From 1ea4c50041b3193a83e0336e9a39a91b57bdb7ed Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 13 Jul 2010 09:15:21 +0100 Subject: [PATCH] x11: Use XKB to track the Locks state For Caps Lock and Num Lock. Store the state of both in the platform-specific per-event data structure. No accessors, yet. --- clutter/x11/clutter-event-x11.c | 17 +++++-- clutter/x11/clutter-keymap-x11.c | 83 ++++++++++++++++++++++++++++++-- clutter/x11/clutter-keymap-x11.h | 6 ++- 3 files changed, 96 insertions(+), 10 deletions(-) diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index 42f6034c9..267aa52b8 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -94,6 +94,9 @@ struct _ClutterEventX11 { /* additional fields for Key events */ gint key_group; + + guint num_lock_set : 1; + guint caps_lock_set : 1; }; ClutterEventX11 * @@ -328,7 +331,7 @@ convert_xdevicekey_to_xkey (XDeviceKeyEvent *xkev, } #endif /* HAVE_XINPUT */ -static void +static inline void translate_key_event (ClutterBackendX11 *backend_x11, ClutterEvent *event, XEvent *xevent) @@ -336,9 +339,6 @@ translate_key_event (ClutterBackendX11 *backend_x11, ClutterEventX11 *event_x11; char buffer[256 + 1]; int n; - - CLUTTER_NOTE (EVENT, "Translating key %s event", - xevent->xany.type == KeyPress ? "press" : "release"); /* KeyEvents have platform specific data associated to them */ event_x11 = _clutter_event_x11_new (); @@ -357,6 +357,10 @@ translate_key_event (ClutterBackendX11 *backend_x11, event_x11->key_group = _clutter_keymap_x11_get_key_group (backend_x11->keymap, event->key.modifier_state); + event_x11->num_lock_set = + _clutter_keymap_x11_get_num_lock_state (backend_x11->keymap); + event_x11->caps_lock_set = + _clutter_keymap_x11_get_caps_lock_state (backend_x11->keymap); /* unicode_value is the printable representation */ n = XLookupString (&xevent->xkey, buffer, sizeof (buffer) - 1, NULL, NULL); @@ -366,10 +370,13 @@ translate_key_event (ClutterBackendX11 *backend_x11, event->key.unicode_value = g_utf8_get_char_validated (buffer, n); if ((event->key.unicode_value != -1) && (event->key.unicode_value != -2)) - return; + goto out; } else event->key.unicode_value = (gunichar)'\0'; + +out: + return; } static gboolean diff --git a/clutter/x11/clutter-keymap-x11.c b/clutter/x11/clutter-keymap-x11.c index fcf0f388f..9957e8a7c 100644 --- a/clutter/x11/clutter-keymap-x11.c +++ b/clutter/x11/clutter-keymap-x11.c @@ -59,6 +59,9 @@ struct _ClutterKeymapX11 #ifdef HAVE_XKB XkbDescPtr xkb_desc; #endif + + guint caps_lock_state : 1; + guint num_lock_state : 1; }; struct _ClutterKeymapX11Class @@ -156,6 +159,65 @@ get_xkb (ClutterKeymapX11 *keymap_x11) } #endif /* HAVE_XKB */ +#ifdef HAVE_XKB +static void +update_locked_mods (ClutterKeymapX11 *keymap_x11, + gint locked_mods) +{ + gboolean old_caps_lock_state, old_num_lock_state; + + old_caps_lock_state = keymap_x11->caps_lock_state; + old_num_lock_state = keymap_x11->num_lock_state; + + keymap_x11->caps_lock_state = (locked_mods & CLUTTER_LOCK_MASK) != 0; + keymap_x11->num_lock_state = (locked_mods & keymap_x11->num_lock_mask) != 0; + + 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) || + (keymap_x11->num_lock_state != old_num_lock_state)) + g_signal_emit_by_name (keymap_x11->backend, "key-lock-changed"); +#endif +} + +static ClutterX11FilterReturn +xkb_filter (XEvent *xevent, + ClutterEvent *event, + gpointer data) +{ + ClutterBackendX11 *backend_x11 = data; + ClutterKeymapX11 *keymap_x11 = backend_x11->keymap; + + g_assert (keymap_x11 != NULL); + + if (!backend_x11->use_xkb) + return CLUTTER_X11_FILTER_CONTINUE; + + if (xevent->type == backend_x11->xkb_event_base) + { + XkbEvent *xkb_event = (XkbEvent *) xevent; + + CLUTTER_NOTE (BACKEND, "Received XKB event [%d]", + xkb_event->any.xkb_type); + + switch (xkb_event->any.xkb_type) + { + case XkbStateNotify: + update_locked_mods (keymap_x11, xkb_event->state.locked_mods); + break; + + default: + break; + } + } + + return CLUTTER_X11_FILTER_CONTINUE; +} +#endif /* HAVE_XKB */ + static void clutter_keymap_x11_constructed (GObject *gobject) { @@ -183,8 +245,6 @@ clutter_keymap_x11_constructed (GObject *gobject) backend_x11->use_xkb = TRUE; -#if 0 - /* XXX - enable when we handle keymap-related events */ XkbSelectEvents (backend_x11->xdpy, XkbUseCoreKbd, XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask, @@ -194,7 +254,8 @@ clutter_keymap_x11_constructed (GObject *gobject) XkbUseCoreKbd, XkbStateNotify, XkbAllStateComponentsMask, XkbGroupLockMask|XkbModifierLockMask); -#endif + + clutter_x11_add_filter (xkb_filter, backend_x11); /* enable XKB autorepeat */ XkbSetDetectableAutoRepeat (backend_x11->xdpy, @@ -274,3 +335,19 @@ _clutter_keymap_x11_get_key_group (ClutterKeymapX11 *keymap, return 0; #endif /* HAVE_XKB */ } + +gboolean +_clutter_keymap_x11_get_num_lock_state (ClutterKeymapX11 *keymap) +{ + g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), FALSE); + + return keymap->num_lock_state; +} + +gboolean +_clutter_keymap_x11_get_caps_lock_state (ClutterKeymapX11 *keymap) +{ + g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), FALSE); + + return keymap->caps_lock_state; +} diff --git a/clutter/x11/clutter-keymap-x11.h b/clutter/x11/clutter-keymap-x11.h index e0d0fb6aa..f228c6f10 100644 --- a/clutter/x11/clutter-keymap-x11.h +++ b/clutter/x11/clutter-keymap-x11.h @@ -37,8 +37,10 @@ typedef struct _ClutterKeymapX11 ClutterKeymapX11; GType clutter_keymap_x11_get_type (void) G_GNUC_CONST; -gint _clutter_keymap_x11_get_key_group (ClutterKeymapX11 *keymap, - ClutterModifierType state); +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); G_END_DECLS