Exemplo n.º 1
0
static unsigned XkbKeyEffectiveGroup(XkbDescPtr xkb, KeyCode key, unsigned int mods)
{
	int nKeyGroups;
	unsigned effectiveGroup;

	nKeyGroups= XkbKeyNumGroups(xkb,key);
	if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0))
		return 0;

	effectiveGroup= XkbGroupForCoreState(mods);
	if ( effectiveGroup>=nKeyGroups ) {
		unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
		switch (XkbOutOfRangeGroupAction(groupInfo)) {
		default:
			effectiveGroup %= nKeyGroups;
			break;
		case XkbClampIntoRange:
			effectiveGroup = nKeyGroups-1;
			break;
		case XkbRedirectIntoRange:
			effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
			if (effectiveGroup>=nKeyGroups)
				effectiveGroup= 0;
			break;
		}
	}

	return effectiveGroup;
}
Exemplo n.º 2
0
gint
_clutter_keymap_x11_get_key_group (ClutterKeymapX11    *keymap,
                                   ClutterModifierType  state)
{
#ifdef HAVE_XKB
  return XkbGroupForCoreState (state);
#else
  return 0;
#endif /* HAVE_XKB */
}
Exemplo n.º 3
0
gboolean
match_xi2_key (Key *key, XIDeviceEvent *event)
{
	guint keyval;
	GdkModifierType consumed;
	gint group;
	guint keycode, state;

	if (key == NULL)
		return FALSE;

	setup_modifiers ();

	state = device_xi2_translate_state (&event->mods, &event->group);

	if (have_xkb (event->display))
		group = XkbGroupForCoreState (state);
	else
		group = (state & GDK_KEY_Mode_switch) ? 1 : 0;

	keycode = event->detail;

	/* Check if we find a keysym that matches our current state */
	if (gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (), keycode,
						 state, group,
						 &keyval, NULL, NULL, &consumed)) {
		guint lower, upper;
		guint mask;

		/* The Key structure contains virtual modifiers, whereas
		 * the XEvent will be using the real modifier, so translate those */
		mask = key->state;
		gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mask);

		gdk_keyval_convert_case (keyval, &lower, &upper);

		/* If we are checking against the lower version of the
		 * keysym, we might need the Shift state for matching,
		 * so remove it from the consumed modifiers */
		if (lower == key->keysym)
			consumed &= ~GDK_SHIFT_MASK;

		return ((lower == key->keysym || upper == key->keysym)
			&& (state & ~consumed & gsd_used_mods) == mask);
	}

	/* The key we passed doesn't have a keysym, so try with just the keycode */
        return (key != NULL
                && key->state == (state & gsd_used_mods)
                && key_uses_keycode (key, keycode));
}
Exemplo n.º 4
0
static XkbAction *XkbKeyActionPtr(XkbDescPtr xkb, KeyCode key, unsigned int mods)
{
	XkbKeyTypeRec *type;
	int col,nKeyGroups;
	unsigned effectiveGroup;
	XkbAction *acts;

	if (!XkbKeyHasActions(xkb, key))
		return NULL;

	nKeyGroups= XkbKeyNumGroups(xkb,key);
	if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0))
		return NULL;

	acts = XkbKeyActionsPtr(xkb,key);

	/* find the offset of the effective group */
	col = 0;
	effectiveGroup= XkbGroupForCoreState(mods);
	if ( effectiveGroup>=nKeyGroups ) {
		unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
		switch (XkbOutOfRangeGroupAction(groupInfo)) {
		default:
			effectiveGroup %= nKeyGroups;
			break;
		case XkbClampIntoRange:
			effectiveGroup = nKeyGroups-1;
			break;
		case XkbRedirectIntoRange:
			effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
			if (effectiveGroup>=nKeyGroups)
				effectiveGroup= 0;
			break;
		}
	}
	col= effectiveGroup*XkbKeyGroupsWidth(xkb,key);
	type = XkbKeyKeyType(xkb,key,effectiveGroup);

	if (type->map) { /* find the column (shift level) within the group */
		register int i;
		register XkbKTMapEntryPtr entry;
		for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
			if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) {
				col+= entry->level;
				break;
			}
		}
	}

	return &acts[col];
}
Exemplo n.º 5
0
static GdkEventKey *
key_event_to_gdk (ClutterKeyEvent *event_clutter)
{
  GdkDisplay *display = gdk_display_get_default ();
  GdkKeymap *keymap = gdk_keymap_get_for_display (display);
  GdkEventKey *event_gdk;
  event_gdk = (GdkEventKey *)gdk_event_new ((event_clutter->type == CLUTTER_KEY_PRESS) ?
                                            GDK_KEY_PRESS : GDK_KEY_RELEASE);

  event_gdk->window = window_for_actor ((ClutterActor *)event_clutter->stage);
  event_gdk->send_event = FALSE;
  event_gdk->time = event_clutter->time;
  /* This depends on ClutterModifierType and GdkModifierType being
   * identical, which they are currently. (They both match the X
   * modifier state in the low 16-bits and have the same extensions.) */
  event_gdk->state = event_clutter->modifier_state;
  event_gdk->keyval = event_clutter->keyval;
  event_gdk->hardware_keycode = event_clutter->hardware_keycode;
  /* For non-proper non-XKB support, we'd need a huge cut-and-paste
   * from gdkkeys-x11.c; this is a macro that just shifts a few bits
   * out of state, so won't make the situation worse if the server
   * doesn't support XKB; we'll just end up with group == 0 */
  event_gdk->group = XkbGroupForCoreState (event_gdk->state);

  gdk_keymap_translate_keyboard_state (keymap, event_gdk->hardware_keycode,
                                       event_gdk->state, event_gdk->group,
                                       &event_gdk->keyval, NULL, NULL, NULL);

  if (event_clutter->unicode_value)
    {
      /* This is not particularly close to what GDK does - event_gdk->string
       * is supposed to be in the locale encoding, and have control keys
       * as control characters, etc. See gdkevents-x11.c:translate_key_event().
       * Hopefully no input method is using event.string.
       */
      char buf[6];

      event_gdk->length = g_unichar_to_utf8 (event_clutter->unicode_value, buf);
      event_gdk->string = g_strndup (buf, event_gdk->length);
    }

  event_gdk->is_modifier = key_is_modifier (event_gdk->keyval);

  return event_gdk;
}
Exemplo n.º 6
0
gboolean
match_key (Key *key, XEvent *event)
{
	guint keyval;
	GdkModifierType consumed;
	gint group;

	if (key == NULL)
		return FALSE;

	setup_modifiers ();

#ifdef HAVE_X11_EXTENSIONS_XKB_H
	if (have_xkb (event->xkey.display))
		group = XkbGroupForCoreState (event->xkey.state);
	else
#endif
		group = (event->xkey.state & GDK_KEY_Mode_switch) ? 1 : 0;

	/* Check if we find a keysym that matches our current state */
	if (gdk_keymap_translate_keyboard_state (NULL, event->xkey.keycode,
					     event->xkey.state, group,
					     &keyval, NULL, NULL, &consumed)) {
		guint lower, upper;

		gdk_keyval_convert_case (keyval, &lower, &upper);

		/* If we are checking against the lower version of the
		 * keysym, we might need the Shift state for matching,
		 * so remove it from the consumed modifiers */
		if (lower == key->keysym)
			consumed &= ~GDK_SHIFT_MASK;

		return ((lower == key->keysym || upper == key->keysym)
			&& (event->xkey.state & ~consumed & msd_used_mods) == key->state);
	}

	/* The key we passed doesn't have a keysym, so try with just the keycode */
        return (key != NULL
                && key->state == (event->xkey.state & msd_used_mods)
                && key_uses_keycode (key, event->xkey.keycode));
}
Exemplo n.º 7
0
static NimfEvent *
translate_xkey_event (XEvent *xevent)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  GdkKeymap *keymap = gdk_keymap_get_default ();
  GdkModifierType consumed, state;

  NimfEvent *nimf_event = nimf_event_new (NIMF_EVENT_NOTHING);

  if (xevent->type == KeyPress)
    nimf_event->key.type = NIMF_EVENT_KEY_PRESS;
  else
    nimf_event->key.type = NIMF_EVENT_KEY_RELEASE;

  nimf_event->key.state = (NimfModifierType) xevent->xkey.state;

#if GTK_CHECK_VERSION (3, 6, 0)
  gint group = gdk_x11_keymap_get_group_for_state (keymap, xevent->xkey.state);
#else
  gint group = XkbGroupForCoreState (xevent->xkey.state);
#endif

  nimf_event->key.hardware_keycode = xevent->xkey.keycode;
  nimf_event->key.keyval = NIMF_KEY_VoidSymbol;

  gdk_keymap_translate_keyboard_state (keymap,
                                       nimf_event->key.hardware_keycode,
                                       nimf_event->key.state,
                                       group,
                                       &nimf_event->key.keyval,
                                       NULL, NULL, &consumed);

  state = nimf_event->key.state & ~consumed;
  gdk_keymap_add_virtual_modifiers (keymap, &state);
  nimf_event->key.state |= (NimfModifierType) state;

  return nimf_event;
}
Exemplo n.º 8
0
void
translate_key_event (GdkDisplay *display,
		     GdkEvent   *event,
		     XEvent     *xevent)
{
  GdkKeymap *keymap = gdk_keymap_get_for_display (display);

  event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
  event->key.time = xevent->xkey.time;

  event->key.state = (GdkModifierType) xevent->xkey.state;

#ifdef HAVE_XKB
  event->key.group = XkbGroupForCoreState (xevent->xkey.state);
#else
  event->key.group = 0;
#endif

  event->key.hardware_keycode = xevent->xkey.keycode;

  event->key.keyval = GDK_VoidSymbol;

  gdk_keymap_translate_keyboard_state (keymap,
				       event->key.hardware_keycode,
				       event->key.state,
				       event->key.group,
				       &event->key.keyval,
				       NULL, NULL, NULL);
  event->key.is_modifier = 0;

  /* Fill in event->string crudely, since various programs
   * depend on it.
   */
  event->key.string = NULL;
  event->key.length = 0;

  return;
}
Exemplo n.º 9
0
/* Stolen from libX11 */
static Bool
XkbTranslateKeyCode(register XkbDescPtr xkb, KeyCode key,
                    register unsigned int mods, unsigned int *mods_rtrn,
                    KeySym *keysym_rtrn)
{
	XkbKeyTypeRec *type;
	int col,nKeyGroups;
	unsigned preserve,effectiveGroup;
	KeySym *syms;

	if (mods_rtrn!=NULL)
		*mods_rtrn = 0;

	nKeyGroups= XkbKeyNumGroups(xkb,key);
	if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) {
		if (keysym_rtrn!=NULL)
			*keysym_rtrn = NoSymbol;
		return False;
	}

	syms = XkbKeySymsPtr(xkb,key);

	/* find the offset of the effective group */
	col = 0;
	effectiveGroup= XkbGroupForCoreState(mods);
	if ( effectiveGroup>=nKeyGroups ) {
		unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
		switch (XkbOutOfRangeGroupAction(groupInfo)) {
		default:
			effectiveGroup %= nKeyGroups;
			break;
		case XkbClampIntoRange:
			effectiveGroup = nKeyGroups-1;
			break;
		case XkbRedirectIntoRange:
			effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
			if (effectiveGroup>=nKeyGroups)
				effectiveGroup= 0;
			break;
		}
	}
	col= effectiveGroup*XkbKeyGroupsWidth(xkb,key);
	type = XkbKeyKeyType(xkb,key,effectiveGroup);

	preserve= 0;
	if (type->map) { /* find the column (shift level) within the group */
		register int i;
		register XkbKTMapEntryPtr entry;
		for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
			if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) {
				col+= entry->level;
				if (type->preserve)
					preserve= type->preserve[i].mask;
				break;
			}
		}
	}

	if (keysym_rtrn!=NULL)
		*keysym_rtrn= syms[col];
	if (mods_rtrn)
		*mods_rtrn= type->mods.mask&(~preserve);

	return (syms[col]!=NoSymbol);
}
Exemplo n.º 10
0
int
XLookupString (	register XKeyEvent *	event,
		char *			buffer,
		int 			nbytes,
		KeySym *		keysym,
		XComposeStatus *	status)
{
    KeySym	dummy;
    int rtrnLen;
    unsigned int new_mods;
    Display *dpy = event->display;

    if (keysym==NULL)
	keysym= &dummy;
    if (!XkbLookupKeySym(dpy,event->keycode,event->state, &new_mods,keysym))
	return 0;
    new_mods= (event->state&(~new_mods));

    /* find the group where a symbol can be converted to control one */
    if (new_mods&ControlMask && *keysym > 0x7F &&
	(dpy->xkb_info->xlib_ctrls & XkbLC_ControlFallback)) {
	XKeyEvent tmp_ev = *event;
	KeySym tmp_keysym;
	unsigned int tmp_new_mods;
	if (_XkbUnavailable(dpy)) {
            tmp_ev.state= event->state ^ dpy->mode_switch;
            if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state,
                                &tmp_new_mods, &tmp_keysym) &&
                tmp_keysym != NoSymbol && tmp_keysym < 0x80 ) {
                *keysym = tmp_keysym;
            }
        } else {
            int n = XkbKeyNumGroups(dpy->xkb_info->desc, tmp_ev.keycode);
            int i;
            for (i = 0; i < n; i++) {
                if (XkbGroupForCoreState(event->state) == i)
                    continue;
                tmp_ev.state= XkbBuildCoreState(tmp_ev.state, i);
                if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state,
                                     &tmp_new_mods, &tmp_keysym) &&
                    tmp_keysym != NoSymbol && tmp_keysym < 0x80 ) {
                    *keysym = tmp_keysym;
                    new_mods= (event->state&(~tmp_new_mods));
                    break;
                }
            }
        }
    }

#ifdef USE_OWN_COMPOSE
    if ( status ) {
	static int been_here= 0;
	if ( !been_here ) {
	    XimCompInitTables();
	    been_here = 1;
	}
	if ( !XimCompLegalStatus(status) ) {
	    status->compose_ptr = NULL;
	    status->chars_matched = 0;
	}
	if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL)) ||
		XimCompIsComposeKey(*keysym,event->keycode,status) ) {
	    XimCompRtrn rtrn;

	    switch (XimCompProcessSym(status,*keysym,&rtrn)) {
		case XIM_COMP_IGNORE:
		    break;
		case XIM_COMP_IN_PROGRESS:
		    if ( keysym!=NULL )
			*keysym = NoSymbol;
#ifndef NO_COMPOSE_LED
		    if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) {
			XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
						True,True,False,NULL);
		    }
#endif
		    return 0;
		case XIM_COMP_FAIL:
		{
		    static Atom _ComposeFail= None;
		    int n = 0, len= 0;
#ifndef NO_COMPOSE_LED
		    if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) {
			XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
						True,False,False,NULL);
		    }
#endif
#ifndef NO_BELL_ON_COMPOSE_FAIL
		    if (dpy->xkb_info->xlib_ctrls&XkbLC_BeepOnComposeFail) {
			if (_ComposeFail==None)
			    _ComposeFail= XInternAtom(dpy,"ComposeFail",0);
			XkbBell(dpy,event->window,0,_ComposeFail);
		    }
#endif
		    for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
			if ( nbytes-len > 0 ) {
			    len+= XkbTranslateKeySym(dpy,&rtrn.sym[n],new_mods,
							buffer+len,nbytes-len,
							NULL);
			}
		    }
		    if ( keysym!=NULL ) {
			if ( n==1 )	*keysym = rtrn.sym[0];
			else		*keysym = NoSymbol;
		    }
		    return len;
		}
		case XIM_COMP_SUCCEED:
		{
		    int len,n = 0;

#ifndef NO_COMPOSE_LED
		    if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) {
			XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
						True,False,False,NULL);
		    }
#endif
		    *keysym = rtrn.matchSym;
		    if ( rtrn.str[0]!='\0' ) {
			strncpy(buffer,rtrn.str,nbytes-1);
			buffer[nbytes-1]= '\0';
			len = (int)strlen(buffer);
		    }
		    else {
			len = XkbTranslateKeySym(dpy,keysym,new_mods,
							buffer,nbytes,
							NULL);
		    }
		    for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
			if ( nbytes-len > 0 ) {
			    len+= XkbTranslateKeySym(dpy,&rtrn.sym[n],
							event->state,
							buffer+len,nbytes-len,
							NULL);
			}
		    }
		    return len;
		}
	    }
	}
    }
#endif

    /* We *should* use the new_mods (which does not contain any modifiers */
    /* that were used to compute the symbol here, but pre-XKB XLookupString */
    /* did not and we have to remain compatible.  Sigh. */
    if (_XkbUnavailable(dpy) ||
	(dpy->xkb_info->xlib_ctrls&XkbLC_ConsumeLookupMods)==0)
	new_mods= event->state;

    rtrnLen= XkbLookupKeyBinding(dpy,*keysym,new_mods,buffer,nbytes,NULL);
    if (rtrnLen>0)
	return rtrnLen;

    return XkbTranslateKeySym(dpy,keysym,new_mods,buffer,nbytes,NULL);
}
Exemplo n.º 11
0
Bool
XkbTranslateKeyCode(	register XkbDescPtr	xkb,
			KeyCode 		key,
			register unsigned int 	mods,
			unsigned int *		mods_rtrn,
			KeySym *		keysym_rtrn)
{
    XkbKeyTypeRec *type;
    int col,nKeyGroups;
    unsigned preserve,effectiveGroup;
    KeySym *syms;

    if (mods_rtrn!=NULL)
	*mods_rtrn = 0;

    nKeyGroups= XkbKeyNumGroups(xkb,key);
    if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) {
	if (keysym_rtrn!=NULL)
	    *keysym_rtrn = NoSymbol;
	return False;
    }

    syms = XkbKeySymsPtr(xkb,key);

    /* find the offset of the effective group */
    col = 0;
    effectiveGroup= XkbGroupForCoreState(mods);
    if ( effectiveGroup>=nKeyGroups ) {
	unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
	switch (XkbOutOfRangeGroupAction(groupInfo)) {
	    default:
		effectiveGroup %= nKeyGroups;
		break;
	    case XkbClampIntoRange:
		effectiveGroup = nKeyGroups-1;
		break;
	    case XkbRedirectIntoRange:
		effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
		if (effectiveGroup>=nKeyGroups)
		    effectiveGroup= 0;
		break;
	}
    }
    col= effectiveGroup*XkbKeyGroupsWidth(xkb,key);
    type = XkbKeyKeyType(xkb,key,effectiveGroup);

    preserve= 0;
    if (type->map) { /* find the column (shift level) within the group */
	register int i;
	register XkbKTMapEntryPtr entry;
	for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
	    if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) {
		col+= entry->level;
		if (type->preserve)
		    preserve= type->preserve[i].mask;
		break;
	    }
	}
    }

    if (keysym_rtrn!=NULL)
	*keysym_rtrn= syms[col];
    if (mods_rtrn) {
	*mods_rtrn= type->mods.mask&(~preserve);
	/* The Motif VTS doesn't get the help callback called if help
	 * is bound to Shift+<whatever>, and it appears as though it
	 * is XkbTranslateKeyCode that is causing the problem.  The
	 * core X version of XTranslateKey always OR's in ShiftMask
	 * and LockMask for mods_rtrn, so this "fix" keeps this behavior
	 * and solves the VTS problem.
	 */
	if ((xkb->dpy)&&(xkb->dpy->xkb_info)&&
	    (xkb->dpy->xkb_info->xlib_ctrls&XkbLC_AlwaysConsumeShiftAndLock)) {
	    *mods_rtrn|= (ShiftMask|LockMask);
	}
    }
    return (syms[col]!=NoSymbol);
}