x11: Use XKB to translate keycodes into key symbols
authorEmmanuele Bassi <ebassi@linux.intel.com>
Tue, 13 Jul 2010 10:54:44 +0000 (11:54 +0100)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Tue, 13 Jul 2010 10:54:44 +0000 (11:54 +0100)
And fall back to XKeycodeToKeysym() if XKB is not available.

clutter/x11/clutter-event-x11.c
clutter/x11/clutter-keymap-x11.c
clutter/x11/clutter-keymap-x11.h

index 267aa52..acddb38 100644 (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 =
index 9957e8a..abd2cb5 100644 (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;
+}
index f228c6f..34abf39 100644 (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