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.
This commit is contained in:
Emmanuele Bassi 2010-07-13 09:15:21 +01:00
parent bf2f8d670d
commit 1ea4c50041
3 changed files with 96 additions and 10 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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