Exemplo n.º 1
0
/* This input filter will handle zaurus-specific keyboard events, like
 * powering off and adjusting the frontlight.
 */
void infilter_zaurus_handler(struct infilter *self, u32 trigger, union trigparam *param) {
  static u32 last_cancel_press = 0;
  u32 now;
  union trigparam newtrig;

  switch (param->kbd.key) {

    /* Detect double-press of the cancel button as suspend */
  case PGKEY_ESCAPE:
    now = os_getticks();
    if (now < last_cancel_press + 250)
      drivermessage(PGDM_POWER, PG_POWER_SLEEP, NULL);
    else
      last_cancel_press = now;
    break;

    /* Seems to be F6 is what happens when you press Fn-C, map that to CTRL-C */
  case PGKEY_F6:
    newtrig = *param;
    newtrig.kbd.key = PGKEY_c;
    newtrig.kbd.mods = PGMOD_CTRL;
    infilter_send(self,PG_TRIGGER_KEY,&newtrig);
    break;

  }
}
Exemplo n.º 2
0
void infilter_magic_handler(struct infilter *self, u32 trigger, union trigparam *param) {

  /* If a CTRL-ALT key was pressed, the keydown event triggers magic_button. 
   * Otherwise, pass on the key.
   */

  if ((param->kbd.mods & PGMOD_CTRL) && (param->kbd.mods & PGMOD_ALT)) {
    if (trigger==PG_TRIGGER_KEYDOWN)
      magic_button(param->kbd.key);
  }
  else
    infilter_send(self,trigger,param);
}
Exemplo n.º 3
0
void infilter_hotspot_handler(struct infilter *self, u32 trigger, union trigparam *param) {
  int consume = 0;

  /* Traverse the hotspot graph using keys defined in the theme
   */

  if (!(param->kbd.mods & ~(PGMOD_CAPS|PGMOD_NUM))) {
    /* Key down, no modifiers */
    
    if (param->kbd.key == hotkey_next) {
      consume = 1;
      if (trigger==PG_TRIGGER_KEYDOWN)
	hotspot_traverse(HOTSPOT_NEXT);
    }
    else if (param->kbd.key == hotkey_up) {
      consume = 1;
      if (trigger==PG_TRIGGER_KEYDOWN)
	hotspot_traverse(HOTSPOT_UP);
    }
    else if (param->kbd.key == hotkey_down) {
      consume = 1;
      if (trigger==PG_TRIGGER_KEYDOWN)
	hotspot_traverse(HOTSPOT_DOWN);
    }
    else if (param->kbd.key == hotkey_left) {
      consume = 1;
      if (trigger==PG_TRIGGER_KEYDOWN)
	hotspot_traverse(HOTSPOT_LEFT);
    } 
    else if (param->kbd.key == hotkey_right) {
      consume = 1;
      if (trigger==PG_TRIGGER_KEYDOWN)
	hotspot_traverse(HOTSPOT_RIGHT);    
    }
  }
  
  else if (!(param->kbd.mods & ~(PGMOD_CAPS|PGMOD_NUM|PGMOD_SHIFT))) {
    /* Key down with shift */
    
    if (param->kbd.key == hotkey_next) {
      consume = 1;
      if (trigger==PG_TRIGGER_KEYDOWN)
	hotspot_traverse(HOTSPOT_PREV);
    }
  }
    
  /* Pass it on if we didn't use it */
  if (!consume)
    infilter_send(self,trigger,param);
}
Exemplo n.º 4
0
/* Given a pg_client_trigger in network byte order this will reconstruct
 * the trigparam union from it, and dispatch it to the proper input filter.
 */
g_error infilter_client_send(union pg_client_trigger *client_trig) {
  union trigparam tp;
  int i;
  struct infilter *from;
  g_error e;
  memset(&tp,0,sizeof(tp));

  /* Convert it all to host byte order 
   */
  for (i=0;i<(sizeof(client_trig->array)/sizeof(client_trig->array[0]));i++)
    client_trig->array[i] = ntohl(client_trig->array[i]);

  /* Reconstruct the trigparam union, depending on trigger type 
   */
  if (client_trig->content.type & PG_TRIGGERS_KEY) {
    tp.kbd.key     = client_trig->content.u.kbd.key;
    tp.kbd.mods    = client_trig->content.u.kbd.mods;
    tp.kbd.flags   = client_trig->content.u.kbd.flags;
    tp.kbd.consume = client_trig->content.u.kbd.consume;
    tp.kbd.divtree = client_trig->content.u.kbd.divtree;
  }
  else if (client_trig->content.type & PG_TRIGGERS_MOUSE) {
    tp.mouse.x          = client_trig->content.u.mouse.x;
    tp.mouse.y          = client_trig->content.u.mouse.y;
    tp.mouse.btn        = client_trig->content.u.mouse.btn;
    tp.mouse.chbtn      = client_trig->content.u.mouse.chbtn;
    tp.mouse.pressure   = client_trig->content.u.mouse.pressure;
    tp.mouse.is_logical = client_trig->content.u.mouse.is_logical;
    tp.mouse.divtree    = client_trig->content.u.mouse.divtree;
    e = rdhandle((void**)&tp.mouse.cursor, PG_TYPE_CURSOR, -1,
		 client_trig->content.u.mouse.cursor_handle);
    tp.mouse.ts_calibration = client_trig->content.u.mouse.ts_calibration;
    errorcheck;
  }
  else if (client_trig->content.type & PG_TRIGGER_MOTIONTRACKER) {
    memcpy(&tp.motion, &client_trig->content.u.motion, sizeof(tp.motion));
  }

  /* Get the source infilter */
  e = rdhandle((void**)&from,PG_TYPE_INFILTER,-1,client_trig->content.infilter_from);
  errorcheck;

  /* Send it out */
  infilter_send(from, client_trig->content.type, &tp);

  return success;
} 
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
void infilter_pntr_normalize_handler(struct infilter *self, u32 trigger, union trigparam *param) {
  int x,y, oldbtn, newbtn;
  static struct cursor *cursor_global_invisible;

  /* If we have pointer events with no cursor, assign them our invisible global
   * cursor so that it can collect context information that we'll need for dispatch.
   */
  if (!param->mouse.cursor) {
    if (!cursor_global_invisible) {
      if (iserror(cursor_new(&cursor_global_invisible,NULL,-1)))
	return;
      cursor_global_invisible->sprite->visible = 0;
    }
    param->mouse.cursor = cursor_global_invisible;
  }

  if (trigger != PG_TRIGGER_SCROLLWHEEL) {
    
    /* Get physical cursor position for use later */
    cursor_getposition(param->mouse.cursor, &x, &y,NULL);
    if (!param->mouse.is_logical) {
      /* Normal rotation handling */
      VID(coord_physicalize)(&x,&y);
    }
    
    /* Convert relative motion to absolute motion.
     * We have to be careful about which coordinate system the input is in.
     */
    if (trigger==PG_TRIGGER_PNTR_RELATIVE) {
      trigger = PG_TRIGGER_PNTR_STATUS;
      param->mouse.x += x;
      param->mouse.y += y;
      if (param->mouse.is_logical)
	VID(coord_physicalize)(&x,&y);
      param->mouse.is_logical = 0;
    }
    
    /* Convert absolute motion to individual events
     */
    if (trigger==PG_TRIGGER_PNTR_STATUS) {
      /* Save the old/new button state too, since it may be modified by other
       * input filters when we do infilter_send. Remember that this is all working
       * with the same trigparam structure, and just repassing it after changing
       * the type :)
       */
      newbtn = param->mouse.btn;
      oldbtn = param->mouse.cursor->prev_buttons;
      
      if (newbtn & ~oldbtn)
	trigger = PG_TRIGGER_DOWN;
      else if (oldbtn & ~newbtn)
	trigger = PG_TRIGGER_UP;
      else
	trigger = PG_TRIGGER_MOVE;
    }
    
    /* If we're moving the cursor and this isn't a MOVE event, generate one
     */
    if ((param->mouse.x != x || param->mouse.y != y) && trigger!=PG_TRIGGER_MOVE) {
      union trigparam moveparam = *param;
      moveparam.mouse.btn = param->mouse.cursor->prev_buttons;
      infilter_send(self,PG_TRIGGER_MOVE,&moveparam);
    }
  }    

  /* Detect changes in buttons, and store that along with the event
   */
  param->mouse.chbtn = param->mouse.btn ^ param->mouse.cursor->prev_buttons;
  param->mouse.cursor->prev_buttons = param->mouse.btn;

  /* Resend it (we might have changed the trigger type) */
  infilter_send(self,trigger,param);
}