+2005-09-06 Matthias Clasen <mclasen@redhat.com>
+
+ Add support for extra virtual modifiers: (#85780, Owen Taylor)
+
+ * gdk/x11/gdkkeys-x11.c (struct _GdkKeymapX11): Add a
+ modmap to maintain the information which X modifiers map to
+ virtual modifiers.
+ (get_xkb): Set up the modmap from the XKB tables.
+ (update_keymaps): Set up the modmap from the information returned
+ by XGetModifierMapping in the non-XKB case.
+
+ * gdk/x11/gdkprivate-x11.h:
+ * gdk/x11/gdkkeys-x11.c (_gdk_keymap_add_virtual_modifiers): New
+ function to set the virtual modifiers in the state.
+
+ * gdk/x11/gdkevents-x11.c (translate_key_event): Call
+ _gdk_keymap_add_virtual_modifiers here.
+
+ * gdk/gdktypes.h (GdkModifierType): Add bits for virtual Super,
+ Hyper and Meta modifiers. Also add GDK_ALT_MASK as an alias
+ for GDK_MOD1_MASK.
+
2005-09-05 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkaction.c (connect_proxy): Set the label of a button
+2005-09-06 Matthias Clasen <mclasen@redhat.com>
+
+ Add support for extra virtual modifiers: (#85780, Owen Taylor)
+
+ * gdk/x11/gdkkeys-x11.c (struct _GdkKeymapX11): Add a
+ modmap to maintain the information which X modifiers map to
+ virtual modifiers.
+ (get_xkb): Set up the modmap from the XKB tables.
+ (update_keymaps): Set up the modmap from the information returned
+ by XGetModifierMapping in the non-XKB case.
+
+ * gdk/x11/gdkprivate-x11.h:
+ * gdk/x11/gdkkeys-x11.c (_gdk_keymap_add_virtual_modifiers): New
+ function to set the virtual modifiers in the state.
+
+ * gdk/x11/gdkevents-x11.c (translate_key_event): Call
+ _gdk_keymap_add_virtual_modifiers here.
+
+ * gdk/gdktypes.h (GdkModifierType): Add bits for virtual Super,
+ Hyper and Meta modifiers. Also add GDK_ALT_MASK as an alias
+ for GDK_MOD1_MASK.
+
2005-09-05 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkaction.c (connect_proxy): Set the label of a button
GDK_LOCK_MASK = 1 << 1,
GDK_CONTROL_MASK = 1 << 2,
GDK_MOD1_MASK = 1 << 3,
+ GDK_ALT_MASK = GDK_MOD1_MASK,
GDK_MOD2_MASK = 1 << 4,
GDK_MOD3_MASK = 1 << 5,
GDK_MOD4_MASK = 1 << 6,
GDK_BUTTON3_MASK = 1 << 10,
GDK_BUTTON4_MASK = 1 << 11,
GDK_BUTTON5_MASK = 1 << 12,
+
/* The next few modifiers are used by XKB, so we skip to the end.
- * Bits 16 - 28 are currently unused, but will eventually
- * be used for "virtual modifiers". Bit 29 is used internally.
+ * Bits 15 - 25 are currently unused. Bit 29 is used internally.
*/
+
+ GDK_SUPER_MASK = 1 << 26,
+ GDK_HYPER_MASK = 1 << 27,
+ GDK_META_MASK = 1 << 28,
+
GDK_RELEASE_MASK = 1 << 30,
- GDK_MODIFIER_MASK = GDK_RELEASE_MASK | 0x1fff
+
+ GDK_MODIFIER_MASK = 0x5c001fff
} GdkModifierType;
typedef enum
guint lock_keysym;
GdkModifierType group_switch_mask;
GdkModifierType num_lock_mask;
+ GdkModifierType modmap[8];
gboolean sun_keypad;
PangoDirection current_direction;
gboolean have_direction;
#ifdef HAVE_XKB
+static void
+update_modmap (Display *display,
+ GdkKeymapX11 *keymap_x11)
+{
+ static struct {
+ const gchar *name;
+ Atom 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 = XInternAtom (display, vmods[i].name, FALSE);
+
+ for (i = 0; i < XkbNumVirtualMods; i++)
+ {
+ for (j = 0; vmods[j].atom; j++)
+ {
+ if (keymap_x11->xkb_desc->names->vmods[i] == vmods[j].atom)
+ {
+ for (k = 0; k < 8; k++)
+ {
+ if (keymap_x11->xkb_desc->server->vmods[i] & (1 << k))
+ keymap_x11->modmap[k] |= vmods[j].mask;
+ }
+ }
+ }
+ }
+}
+
static XkbDescPtr
get_xkb (GdkKeymapX11 *keymap_x11)
{
if (keymap_x11->xkb_desc == NULL)
{
- keymap_x11->xkb_desc = XkbGetMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask, XkbUseCoreKbd);
+ keymap_x11->xkb_desc = XkbGetMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask | XkbVirtualModsMask, XkbUseCoreKbd);
if (keymap_x11->xkb_desc == NULL)
g_error ("Failed to get keymap");
- XkbGetNames (xdisplay, XkbGroupNamesMask, keymap_x11->xkb_desc);
+ XkbGetNames (xdisplay, XkbGroupNamesMask | XkbVirtualModNamesMask, keymap_x11->xkb_desc);
+
+ update_modmap (xdisplay, keymap_x11);
}
else if (keymap_x11->current_serial != display_x11->keymap_serial)
{
- XkbGetUpdatedMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask,
+ XkbGetUpdatedMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask | XkbVirtualModsMask,
keymap_x11->xkb_desc);
- XkbGetNames (xdisplay, XkbGroupNamesMask, keymap_x11->xkb_desc);
+ XkbGetNames (xdisplay, XkbGroupNamesMask | XkbVirtualModNamesMask, keymap_x11->xkb_desc);
+
+ update_modmap (xdisplay, keymap_x11);
}
keymap_x11->current_serial = display_x11->keymap_serial;
keymap_x11->lock_keysym = GDK_VoidSymbol;
keymap_x11->group_switch_mask = 0;
keymap_x11->num_lock_mask = 0;
-
+
/* There are 8 sets of modifiers, with each set containing
* max_keypermod keycodes.
*/
syms = keymap_x11->keymap + (keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;
+ mask = 0;
+ for (j = 0; j < keymap_x11->keysyms_per_keycode; j++)
+ {
+ if (syms[j] == GDK_Meta_L ||
+ syms[j] == GDK_Meta_R)
+ mask |= GDK_META_MASK;
+ else if (syms[j] == GDK_Hyper_L ||
+ syms[j] == GDK_Hyper_R)
+ mask |= GDK_HYPER_MASK;
+ else if (syms[j] == GDK_Super_L ||
+ syms[j] == GDK_Super_R)
+ mask |= GDK_SUPER_MASK;
+ }
+
+ keymap_x11->modmap[i/keymap_x11->mod_keymap->max_keypermod] |= mask;
+
/* The fourth modifier, GDK_MOD1_MASK is 1 << 3.
* Each group of max_keypermod entries refers to the same modifier.
*/
if (hardware_keycode < keymap_x11->min_keycode ||
hardware_keycode > keymap_x11->max_keycode)
return FALSE;
-
+
#ifdef HAVE_XKB
if (KEYMAP_USE_XKB (keymap))
{
}
}
+void
+_gdk_keymap_add_virtual_modifiers (GdkKeymap *keymap,
+ GdkModifierType *modifiers)
+{
+ GdkKeymapX11 *keymap_x11;
+ int i;
+
+ keymap = GET_EFFECTIVE_KEYMAP (keymap);
+ keymap_x11 = GDK_KEYMAP_X11 (keymap);
+
+ for (i = 3; i < 8; i++)
+ {
+ if ((1 << i) & *modifiers)
+ {
+ if (keymap_x11->modmap[i] & GDK_SUPER_MASK)
+ *modifiers |= GDK_SUPER_MASK;
+ else if (keymap_x11->modmap[i] & GDK_HYPER_MASK)
+ *modifiers |= GDK_HYPER_MASK;
+ else if (keymap_x11->modmap[i] & GDK_META_MASK)
+ *modifiers |= GDK_META_MASK;
+ }
+ }
+}
+
+
#define __GDK_KEYS_X11_C__
#include "gdkaliasdef.c"