From 3b205de8964cbecf259f82668e5c3804500279f7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 20:34:14 -0500 Subject: [PATCH] wayland: Port over missing xkb functionality from X11 backend --- gdk/wayland/gdkkeys-wayland.c | 90 ++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/gdk/wayland/gdkkeys-wayland.c b/gdk/wayland/gdkkeys-wayland.c index 833624236..139e54824 100644 --- a/gdk/wayland/gdkkeys-wayland.c +++ b/gdk/wayland/gdkkeys-wayland.c @@ -49,6 +49,7 @@ typedef struct _GdkWaylandKeymapClass GdkWaylandKeymapClass; struct _GdkWaylandKeymap { GdkKeymap parent_instance; + GdkModifierType modmap[8]; struct xkb_desc *xkb; }; @@ -466,17 +467,103 @@ gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap, } +static void +update_modmap (GdkWaylandKeymap *wayland_keymap) +{ + static struct { + const gchar *name; + uint32_t atom; + GdkModifierType mask; + } vmods[] = { + { "Meta", 0, GDK_META_MASK }, + { "Super", 0, GDK_SUPER_MASK }, + { "Hyper", 0, GDK_HYPER_MASK }, + { NULL, 0, 0 } + }; + + gint i, j, k; + + if (!vmods[0].atom) + for (i = 0; vmods[i].name; i++) + vmods[i].atom = xkb_intern_atom(vmods[i].name); + + for (i = 0; i < 8; i++) + wayland_keymap->modmap[i] = 1 << i; + + for (i = 0; i < XkbNumVirtualMods; i++) + { + for (j = 0; vmods[j].atom; j++) + { + if (wayland_keymap->xkb->names->vmods[i] == vmods[j].atom) + { + for (k = 0; k < 8; k++) + { + if (wayland_keymap->xkb->server->vmods[i] & (1 << k)) + wayland_keymap->modmap[k] |= vmods[j].mask; + } + } + } + } +} + static void gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap *keymap, GdkModifierType *state) { + GdkWaylandKeymap *wayland_keymap; + int i; + + wayland_keymap = GDK_WAYLAND_KEYMAP (keymap); + + for (i = 3; i < 8; i++) + { + if ((1 << i) & *state) + { + if (wayland_keymap->modmap[i] & GDK_MOD1_MASK) + *state |= GDK_MOD1_MASK; + if (wayland_keymap->modmap[i] & GDK_SUPER_MASK) + *state |= GDK_SUPER_MASK; + if (wayland_keymap->modmap[i] & GDK_HYPER_MASK) + *state |= GDK_HYPER_MASK; + if (wayland_keymap->modmap[i] & GDK_META_MASK) + *state |= GDK_META_MASK; + } + } } static gboolean gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap, GdkModifierType *state) { - return FALSE; + const guint vmods[] = { + GDK_SUPER_MASK, GDK_HYPER_MASK, GDK_META_MASK + }; + int i, j; + gboolean retval; + GdkWaylandKeymap *wayland_keymap; + struct xkb_desc *xkb; + + wayland_keymap = GDK_WAYLAND_KEYMAP (keymap); + xkb = wayland_keymap->xkb; + + for (j = 0; j < 3; j++) + { + if (*state & vmods[j]) + { + for (i = 3; i < 8; i++) + { + if (wayland_keymap->modmap[i] & vmods[j]) + { + if (*state & (1 << i)) + retval = FALSE; + else + *state |= 1 << i; + } + } + } + } + + return TRUE; } static void @@ -519,6 +606,7 @@ _gdk_wayland_keymap_new (GdkDisplay *display) names.variant = ""; names.options = ""; keymap->xkb = xkb_compile_keymap_from_rules(&names); + update_modmap (keymap); return GDK_KEYMAP (keymap); } -- 2.43.2