]> Pileus Git - ~andy/gtk/commitdiff
Add support for extra virtual modifiers: (#85780, Owen Taylor)
authorMatthias Clasen <mclasen@redhat.com>
Tue, 6 Sep 2005 17:56:01 +0000 (17:56 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Tue, 6 Sep 2005 17:56:01 +0000 (17:56 +0000)
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.

ChangeLog
ChangeLog.pre-2-10
gdk/gdktypes.h
gdk/x11/gdkevents-x11.c
gdk/x11/gdkkeys-x11.c
gdk/x11/gdkprivate-x11.h

index b7feeca281f9bb44f3b33f6692afd9cb0850281b..cdbca2bd1e81bd3de28ee2fbe975ddc7a4de814f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+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
index b7feeca281f9bb44f3b33f6692afd9cb0850281b..cdbca2bd1e81bd3de28ee2fbe975ddc7a4de814f 100644 (file)
@@ -1,3 +1,25 @@
+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
index 5472ca9d1a8f20d19f23b055982f95ae6b768ab2..3998e5586cb9daf4ed1ec0286e729af6adf0a579 100644 (file)
@@ -119,6 +119,7 @@ typedef enum
   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,
@@ -128,12 +129,18 @@ typedef enum
   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
index 0a273a4b6bf9385545aa8de381ab8b9b926d76c3..d1505b2ae1a89657c0a5ced6a526659d46fcde1a 100644 (file)
@@ -610,6 +610,8 @@ translate_key_event (GdkDisplay *display,
                                       &event->key.keyval,
                                       NULL, NULL, NULL);
 
+  _gdk_keymap_add_virtual_modifiers (keymap, &event->key.state);
+
   /* Fill in event->string crudely, since various programs
    * depend on it.
    */
index 6539e79fffc8c6f8b2d16d693c7dc6d1bb1d12da..531aa17383d66eace04869e39940f9353bec6a08 100644 (file)
@@ -80,6 +80,7 @@ struct _GdkKeymapX11
   guint lock_keysym;
   GdkModifierType group_switch_mask;
   GdkModifierType num_lock_mask;
+  GdkModifierType modmap[8];
   gboolean sun_keypad;
   PangoDirection current_direction;
   gboolean have_direction;
@@ -168,6 +169,43 @@ update_keyrange (GdkKeymapX11 *keymap_x11)
 
 #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)
 {
@@ -178,17 +216,21 @@ 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;
@@ -324,7 +366,7 @@ update_keymaps (GdkKeymapX11 *keymap_x11)
       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.
        */
@@ -344,6 +386,22 @@ update_keymaps (GdkKeymapX11 *keymap_x11)
 
           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.
            */
@@ -1299,7 +1357,7 @@ gdk_keymap_translate_keyboard_state (GdkKeymap       *keymap,
   if (hardware_keycode < keymap_x11->min_keycode ||
       hardware_keycode > keymap_x11->max_keycode)
     return FALSE;
-  
+
 #ifdef HAVE_XKB
   if (KEYMAP_USE_XKB (keymap))
     {
@@ -1447,5 +1505,30 @@ _gdk_x11_get_group_for_state (GdkDisplay      *display,
     }
 }
 
+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"
index 5e9e2cba617be8c5068609af26b1d0be1a971cad..cc310cf82086c01d0982b67844fe15311e3234af 100644 (file)
@@ -143,6 +143,8 @@ void _gdk_keymap_state_changed    (GdkDisplay      *display);
 void _gdk_keymap_keys_changed     (GdkDisplay      *display);
 gint _gdk_x11_get_group_for_state (GdkDisplay      *display,
                                   GdkModifierType  state);
+void _gdk_keymap_add_virtual_modifiers (GdkKeymap       *keymap,
+                                       GdkModifierType *modifiers);
 
 GC _gdk_x11_gc_flush (GdkGC *gc);