void cursor_move(struct cursor *cursor, enum movement movement) { switch (movement) { case LEFT: if (cursor->x > CURSOR_BEGIN_X) { cursor->x = cursor->x - 8; if (cursor->y > CURSOR_BEGIN_Y) { cursor_move(cursor, UP); cursor_move(cursor, DOWN); } } break; case DOWN: if (cursor->y == CURSOR_BEGIN_Y) { switch (cursor->x - 3) { case MANEUVRE_0_BEGIN_X: cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[0]); break; case MANEUVRE_1_BEGIN_X: cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[1]); break; case MANEUVRE_2_BEGIN_X: cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[2]); break; case MANEUVRE_3_BEGIN_X: cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[3]); break; case MANEUVRE_4_BEGIN_X: cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[4]); break; case MANEUVRE_5_BEGIN_X: cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[5]); break; case MANEUVRE_6_BEGIN_X: cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[6]); break; } } break; case RIGHT: if (cursor->x < 49) { cursor->x = cursor->x + 8; if (cursor->y > CURSOR_BEGIN_Y) { cursor_move(cursor, UP); cursor_move(cursor, DOWN); } } break; case UP: if (cursor->y > CURSOR_BEGIN_Y) { cursor->y = CURSOR_BEGIN_Y; } break; } }
static void om_console_do_work(struct work_struct *work) { unsigned int output = 0; unsigned long flags = 0; unsigned int head_snap; do { spin_lock_irqsave(&buffer_lock, flags); tail = cursor_move(tail, output); if (tail == head){ /*no buffer to output, leave the task*/ spin_unlock_irqrestore(&buffer_lock, flags); break; } head_snap = head; spin_unlock_irqrestore(&buffer_lock, flags); /*calc the size to output this round*/ if (head_snap < tail){ output = CONSOLE_BUFF_LEN - tail; }else{ output = head_snap - tail; } /*send to OM, update the tail cursor*/ BSP_MNTN_OmDrvTraceSend(0, 0, buffer + tail, output); } while (1); return; }
/* A widget has requested focus... Send out the ACTIVATE and DEACTIVATE triggers, and update necessary vars */ void request_focus(struct widget *self) { handle hself = hlookup(self,NULL); struct widget *kbdfocus; /* Already focused? */ if (dts->top->focus==hself) return; kbdfocus = NULL; rdhandle((void**)&kbdfocus,PG_TYPE_WIDGET,-1,dts->top->focus); /* Deactivate the old widget, activate the new */ send_trigger(kbdfocus,PG_TRIGGER_DEACTIVATE,NULL); dts->top->focus = hself; appmgr_focus(appmgr_findapp(self)); send_trigger(self,PG_TRIGGER_ACTIVATE,NULL); /* Scroll in */ scroll_to_divnode(self->in->div); /* If there's an active hotspot cursor, move it to this widget */ if (dts->top->hotspot_cursor) { int x,y; divnode_hotspot_position(self->in->div, &x, &y); cursor_move(dts->top->hotspot_cursor,x,y,dts->top); } }
///////////////////////////////////////////////////////////////// // checkUserInputAndPerformActions // scans the keyboard and checks whether the user has pressed // any action key or not. When the user presses an action key, // the corresponding action is performed. // void checkUserInputAndPerformActions() { // Scan the keyboard for user keypresses cpct_scanKeyboard(); // Perform checks only when the user has // pressed at least one key if(cpct_isAnyKeyPressed()) { // Get current (x,y) coordinates of the cursor u8 x = cursor_getX(); u8 y = cursor_getY(); // Check if the key pressed is one of the valid keys and // if sanity conditions are met // CURSOR_UP or CURSOR_DOWN (Only one at a time) // Perform required action, if the cursor is not at the // edge of the map already. if (cpct_isKeyPressed(Key_CursorUp) && y > 0) cursor_move(DIR_UP); else if (cpct_isKeyPressed(Key_CursorDown) && y < MAP_HEIGHT-1) cursor_move(DIR_DOWN); // CURSOR_LEFT or CURSOR_RIGHT (Only one at a time) // Perform required action, if the cursor is not at the // edge of the map already. if (cpct_isKeyPressed(Key_CursorLeft) && x > 0) cursor_move(DIR_LEFT); else if (cpct_isKeyPressed(Key_CursorRight) && x < MAP_WIDTH-1) cursor_move(DIR_RIGHT); // SPACE (change tile) or ESCAPE (clear map) // Perform one of these actions if corresponding key is pressed if (cpct_isKeyPressed(Key_Space)) map_changeTile(x, y); else if (cpct_isKeyPressed(Key_Esc)) map_clear(); // Always redraw the cursor after any of the above actions cursor_draw(); } }
/* This is the 'high level' hotspot function that will usually be called * by the widget code. * * It rebuilds the hotspot graph from the current divtree if necessary, finds * the hotspot closest to the mouse pointer, traverses the hotspot graph in * the indicated direction, and finds the new mouse pointer position. * * The direction is a HOTSPOT_* constant */ void hotspot_traverse(short direction) { struct hotspot *p; int x,y; struct divtree *dt; /* rebuild the graph */ if (!hotspotlist) { hotspot_build(dts->top->head,NULL); if (popup_toolbar_passthrough()) hotspot_build(dts->root->head,appmgr_nontoolbar_area()); hotspot_graph(); } /* Create the hotspotnav cursor if it doesn't exist */ if (!dts->top->hotspot_cursor) if (iserror(cursor_new(&dts->top->hotspot_cursor,NULL,-1))) return; /* Find the current node */ cursor_getposition(dts->top->hotspot_cursor,&x,&y,&dt); p = hotspot_closest(x,y); if (!p) return; /* If the closest node isn't really that close, just warp to * that closest node. Otherwise, traverse. * * NOTE: We used to test whether the hotspot cursor was within * the same divnode as the hotspot, but now that the hotspot cursor * is separate from all driver-controlled cursors we can do an * exact match. */ if (x==p->x && y==p->y) { /* traverse */ p = p->graph[direction]; if (!p) return; } /* Make sure the divnode is scrolled in and focused now */ if (p->div) request_focus(p->div->owner); /* Warp the hotspot cursor to the new hotspot location */ cursor_move(dts->top->hotspot_cursor,p->x,p->y,dt); }
/***************************************************************************** Description : console output write to OM History 1.Date: 2012/9/13 Author : x00138766 Modification : Created function *****************************************************************************/ static void write_msg(struct console *con, const char *msg, unsigned int len) { unsigned long flags = 0; unsigned int free = 0; unsigned int output = 0; unsigned int left = 0; unsigned int trigger = 0; /*in hard/soft irq context*/ if (unlikely(in_interrupt())){ spin_lock_irqsave(&buffer_lock, flags); free = (tail + CONSOLE_BUFF_LEN - head - 1)%CONSOLE_BUFF_LEN; /*free buffer space*/ output = min(free, len); /*output bytes*/ /*copy data to ring buffer */ left = CONSOLE_BUFF_LEN - head; if (output > left){ memcpy(buffer + head, msg, left); memcpy(buffer, msg + left, output - left); }else{ memcpy(buffer + head, msg, output); } if (head == tail){ trigger = 1; } head = cursor_move(head, output); spin_unlock_irqrestore(&buffer_lock, flags); if (1 == trigger){ queue_work_on(0, om_console_work_queue, &om_console_work); } }else{ output = len; /*in other context, output to OM directly*/ BSP_MNTN_OmDrvTraceSend(0, 0, (BSP_U8 *)msg, output); } atomic_add(output, &om_console_output_bytes); atomic_add(len - output, &om_console_omit_bytes); return; }
void infilter_pntr_dispatch_handler(struct infilter *self, u32 trigger, union trigparam *param) { struct widget *under; int release_captured = 0; int accepted = 0; /* In order to dispatch a pointing event, it must have an associated cursor. * The normalize filter should have given us a cursor whether the driver had * one or not, but in case an event was inserted into the pipe with no cursor, * pass it on. This will usually just run the event off the end of the * filter chain, but this makes it theoretically possible for a client to pick * up the cursorless events. */ if (!param->mouse.cursor) { infilter_send(self, trigger, param); return; } /* Move the cursor */ if (trigger==PG_TRIGGER_MOVE) { int cx,cy; struct divtree *new_dt, *old_dt; /* Default to the topmost divtree, but allow the event to override */ if (iserror(rdhandle((void**)&new_dt, PG_TYPE_DIVTREE, -1, param->mouse.divtree)) || !new_dt) new_dt = dts->top; /* If the cursor is already at the destination, throw away this event */ cursor_getposition(param->mouse.cursor,&cx,&cy,&old_dt); if (cx == param->mouse.x && cy == param->mouse.y && new_dt == old_dt) return; cursor_move(param->mouse.cursor,param->mouse.x,param->mouse.y,new_dt); } inactivity_reset(); /* Read which widget is under the cursor */ under = NULL; rdhandle((void**)&under, PG_TYPE_WIDGET, -1, param->mouse.cursor->ctx.widget_under); /* If the capture_btn is released, release the capture */ if ((!(param->mouse.btn & param->mouse.cursor->ctx.capture_btn)) && param->mouse.cursor->ctx.widget_capture && param->mouse.cursor->ctx.widget_capture != param->mouse.cursor->ctx.widget_under) { struct widget *capture; if ((!iserror(rdhandle((void**)&capture, PG_TYPE_WIDGET, -1, param->mouse.cursor->ctx.widget_capture))) && capture) release_captured = send_trigger(capture,PG_TRIGGER_RELEASE,param); accepted++; param->mouse.cursor->ctx.widget_capture = 0; param->mouse.cursor->ctx.capture_btn = 0; } if (under) { /* There's an interactive widget under the cursor */ /* Keep track of the most recently clicked widget */ if (trigger==PG_TRIGGER_DOWN) { param->mouse.cursor->ctx.widget_last_clicked = param->mouse.cursor->ctx.widget_under; /* Also, allow clicks to focus applications */ appmgr_focus(appmgr_findapp(under)); } /* First send the 'raw' event, then handle the cooked ones. */ if (!release_captured) accepted += send_propagating_trigger(under,trigger,param); /* If the mouse is clicked in a widget, it 'captures' future MOVE and RELEASE events * until this button is released. */ if (trigger==PG_TRIGGER_DOWN && !param->mouse.cursor->ctx.widget_capture) { param->mouse.cursor->ctx.widget_capture = param->mouse.cursor->ctx.widget_under; param->mouse.cursor->ctx.capture_btn = param->mouse.chbtn; } } /* If a captured widget accepts PG_TRIGGER_DRAG, send it even when the * mouse is outside its divnodes. */ if (trigger==PG_TRIGGER_MOVE && param->mouse.cursor->ctx.widget_capture) { struct widget *capture; if ((!iserror(rdhandle((void**)&capture, PG_TYPE_WIDGET, -1, param->mouse.cursor->ctx.widget_capture))) && capture) accepted += send_trigger(capture,PG_TRIGGER_DRAG,param); } /* If nothing has accepted the event so far, pass it on */ if (!accepted) infilter_send(self,trigger,param); }
g_error cursor_set_theme(struct cursor *crsr, int thobj) { hwrbitmap *bitmap,*mask; s16 w,h; bool redisplay; g_error e; crsr->thobj = thobj; /* Read the cursor bitmap and bitmask. Note that if the cursor is rectangular * or it uses an alpha channel the mask will be NULL. */ e = rdhandlep((void***)&bitmap,PG_TYPE_BITMAP,-1,theme_lookup(thobj,PGTH_P_CURSORBITMAP)); errorcheck; mask = NULL; e = rdhandlep((void***)&mask,PG_TYPE_BITMAP,-1,theme_lookup(thobj,PGTH_P_CURSORBITMASK)); errorcheck; if (crsr->sprite && bitmap==crsr->sprite->bitmap && mask==crsr->sprite->mask) return success; /* If there's no bitmap yet, it's early in init and the default cursor * hasn't been created yet. Skip this all. */ if (!bitmap) return success; VID(bitmap_getsize) (*bitmap,&w,&h); /* Insert the new bitmaps, resize/create the sprite if necessary */ redisplay = crsr->sprite && crsr->sprite->onscreen; if (redisplay) VID(sprite_hide) (crsr->sprite); /* Update the hotspot before cursor_move */ crsr->hotspot_x = theme_lookup(thobj,PGTH_P_CRSRHOTSPOT_X); crsr->hotspot_y = theme_lookup(thobj,PGTH_P_CRSRHOTSPOT_Y); if (!crsr->sprite) { int x,y; struct divtree *dt; /* Get the default position */ cursor_getposition(crsr,&x,&y,&dt); /* Create a new sprite (default hidden, as per description in input.h) */ e = new_sprite(&crsr->sprite,dt,w,h); errorcheck; crsr->sprite->visible = 0; /* Set the bitmap up, and move it */ crsr->sprite->bitmap = bitmap; crsr->sprite->mask = mask; cursor_move(crsr, x,y, dt); } else { /* Since we're not creating a new sprite, we might need to move the hotspot */ crsr->sprite->x = crsr->x - crsr->hotspot_x; crsr->sprite->y = crsr->y - crsr->hotspot_y; if ( (w!=crsr->sprite->w) || (h!=crsr->sprite->h) ) { /* Resize an existing sprite */ VID(bitmap_free) (crsr->sprite->backbuffer); e = VID(bitmap_new) (&crsr->sprite->backbuffer,w,h,vid->bpp); errorcheck; crsr->sprite->w = w; crsr->sprite->h = h; } crsr->sprite->bitmap = bitmap; crsr->sprite->mask = mask; } /* If the cursor has an alpha channel, set the LGOP accordingly */ if (w && h && (VID(getpixel)(*bitmap,0,0) & PGCF_ALPHA)) crsr->sprite->lgop = PG_LGOP_ALPHA; else crsr->sprite->lgop = PG_LGOP_NONE; if (redisplay) VID(sprite_show)(crsr->sprite); /* Whether it was onscreen or not, show it at the next convenient opportunity */ crsr->sprite->visible = 1; return success; }