x11: Use XKB to translate keycodes into key symbols

And fall back to XKeycodeToKeysym() if XKB is not available.
This commit is contained in:
Emmanuele Bassi 2010-07-13 11:54:44 +01:00
parent 1ea4c50041
commit 6c913aa55e
3 changed files with 87 additions and 7 deletions

View File

@ -95,8 +95,9 @@ struct _ClutterEventX11
/* additional fields for Key events */
gint key_group;
guint num_lock_set : 1;
guint caps_lock_set : 1;
guint key_is_modifier : 1;
guint num_lock_set : 1;
guint caps_lock_set : 1;
};
ClutterEventX11 *
@ -350,13 +351,17 @@ translate_key_event (ClutterBackendX11 *backend_x11,
/* keyval is the key ignoring all modifiers ('1' vs. '!') */
event->key.keyval =
XKeycodeToKeysym (xevent->xkey.display,
xevent->xkey.keycode,
0);
_clutter_keymap_x11_translate_key_state (backend_x11->keymap,
event->key.hardware_keycode,
event->key.modifier_state,
NULL);
event_x11->key_group =
_clutter_keymap_x11_get_key_group (backend_x11->keymap,
event->key.modifier_state);
event_x11->key_is_modifier =
_clutter_keymap_x11_get_is_modifier (backend_x11->keymap,
event->key.hardware_keycode);
event_x11->num_lock_set =
_clutter_keymap_x11_get_num_lock_state (backend_x11->keymap);
event_x11->caps_lock_set =

View File

@ -175,6 +175,7 @@ update_locked_mods (ClutterKeymapX11 *keymap_x11,
CLUTTER_NOTE (BACKEND, "Locks state changed - Num: %s, Caps: %s",
keymap_x11->num_lock_state ? "set" : "unset",
keymap_x11->caps_lock_state ? "set" : "unset");
#if 0
/* Add signal to ClutterBackend? */
if ((keymap_x11->caps_lock_state != old_caps_lock_state) ||
@ -296,6 +297,15 @@ clutter_keymap_x11_set_property (GObject *gobject,
static void
clutter_keymap_x11_finalize (GObject *gobject)
{
ClutterKeymapX11 *keymap;
keymap = CLUTTER_KEYMAP_X11 (gobject);
#ifdef HAVE_XKB
if (keymap->xkb_desc != NULL)
XkbFreeKeyboard (keymap->xkb_desc, XkbAllComponentsMask, True);
#endif
G_OBJECT_CLASS (clutter_keymap_x11_parent_class)->finalize (gobject);
}
@ -328,8 +338,6 @@ _clutter_keymap_x11_get_key_group (ClutterKeymapX11 *keymap,
ClutterModifierType state)
{
#ifdef HAVE_XKB
(void) get_xkb (keymap);
return XkbGroupForCoreState (state);
#else
return 0;
@ -351,3 +359,64 @@ _clutter_keymap_x11_get_caps_lock_state (ClutterKeymapX11 *keymap)
return keymap->caps_lock_state;
}
gint
_clutter_keymap_x11_translate_key_state (ClutterKeymapX11 *keymap,
guint hardware_keycode,
ClutterModifierType modifier_state,
ClutterModifierType *mods_p)
{
ClutterBackendX11 *backend_x11;
ClutterModifierType unconsumed_modifiers = 0;
gint retval;
g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), 0);
backend_x11 = CLUTTER_BACKEND_X11 (keymap->backend);
#ifdef HAVE_XKB
if (backend_x11->use_xkb)
{
XkbDescRec *xkb = get_xkb (keymap);
KeySym tmp_keysym;
if (XkbTranslateKeyCode (xkb, hardware_keycode, modifier_state,
&unconsumed_modifiers,
&tmp_keysym))
{
retval = tmp_keysym;
}
else
retval = 0;
}
else
#endif /* HAVE_XKB */
retval = XKeycodeToKeysym (backend_x11->xdpy, hardware_keycode, 0);
if (mods_p)
*mods_p = unconsumed_modifiers;
return retval;
}
gboolean
_clutter_keymap_x11_get_is_modifier (ClutterKeymapX11 *keymap,
guint keycode)
{
g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), FALSE);
if (keycode < keymap->min_keycode || keycode > keymap->max_keycode)
return FALSE;
#ifdef HAVE_XKB
if (CLUTTER_BACKEND_X11 (keymap->backend)->use_xkb)
{
XkbDescRec *xkb = get_xkb (keymap);
if (xkb->map->modmap && xkb->map->modmap[keycode] != 0)
return TRUE;
}
#endif /* HAVE_XKB */
return FALSE;
}

View File

@ -41,6 +41,12 @@ gint _clutter_keymap_x11_get_key_group (ClutterKeymapX11 *keymap,
ClutterModifierType state);
gboolean _clutter_keymap_x11_get_num_lock_state (ClutterKeymapX11 *keymap);
gboolean _clutter_keymap_x11_get_caps_lock_state (ClutterKeymapX11 *keymap);
gint _clutter_keymap_x11_translate_key_state (ClutterKeymapX11 *keymap,
guint hardware_keycode,
ClutterModifierType modifier_state,
ClutterModifierType *mods_p);
gboolean _clutter_keymap_x11_get_is_modifier (ClutterKeymapX11 *keymap,
guint keycode);
G_END_DECLS