[caribou] xadapter: use level3 shift if possible



commit 0e34f29f73c80034882db6547f99313f6a29ad65
Author: Daiki Ueno <ueno unixuser org>
Date:   Sun Oct 28 10:45:31 2012 +0900

    xadapter: use level3 shift if possible
    
    Some international keyboards (such as Czech) assign more than two
    keysyms to each key.  Use level 3 shift modifier (so called AltGr) to
    designate those keysyms and avoid needless keysym remapping.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=687018

 libcaribou/external-libs.vapi |    5 +++--
 libcaribou/xadapter.vala      |   32 ++++++++++++++++++++++++++++----
 2 files changed, 31 insertions(+), 6 deletions(-)
---
diff --git a/libcaribou/external-libs.vapi b/libcaribou/external-libs.vapi
index 930e582..1489216 100644
--- a/libcaribou/external-libs.vapi
+++ b/libcaribou/external-libs.vapi
@@ -78,8 +78,8 @@ namespace Xkb {
         public X.Display dpy;
         public ushort flags;
         public ushort device_spec;
-        public char min_key_code;
-        public char max_key_code;
+        public uchar min_key_code;
+        public uchar max_key_code;
         public Controls          ctrls;
         public ServerMap         server;
         public ClientMap         map;
@@ -149,6 +149,7 @@ namespace Xkb {
         [CCode (array_length = false, array_null_terminated = true)]
         public SymMap[]         key_sym_map;
 
+        [CCode (array_length = false, array_null_terminated = true)]
         public uchar[]          modmap;
     }
 
diff --git a/libcaribou/xadapter.vala b/libcaribou/xadapter.vala
index 8319313..38e9c8e 100644
--- a/libcaribou/xadapter.vala
+++ b/libcaribou/xadapter.vala
@@ -21,6 +21,7 @@ namespace Caribou {
         uchar reserved_keycode;
         uchar modifiers;
         uchar group;
+        uint[] level_switch_modifiers;
 
         public delegate void KeyButtonCallback (uint keybuttoncode, bool pressed);
 
@@ -57,6 +58,16 @@ namespace Caribou {
 
             this.reserved_keycode = 0;
 
+            this.level_switch_modifiers = {
+                0,
+                Gdk.ModifierType.SHIFT_MASK
+            };
+            var lv3_mod = keysym_to_modifier (Gdk.Key.ISO_Level3_Shift);
+            if (lv3_mod != 0) {
+                level_switch_modifiers += lv3_mod;
+                level_switch_modifiers += Gdk.ModifierType.SHIFT_MASK | lv3_mod;
+            }
+
             button_funcs = new HashTable<uint, KeyButtonHandler> (direct_hash,
                                                                   direct_equal);
 
@@ -122,6 +133,18 @@ namespace Caribou {
 			self.group_changed (self.group, group_name, variant_name);
 		}
 
+        private uchar keysym_to_modifier (uint keyval) {
+            for (var i = xkbdesc.min_key_code; i <= xkbdesc.max_key_code; i++) {
+                unowned Xkb.SymMap symmap = xkbdesc.map.key_sym_map[i];
+                for (var j = 0;
+                     j < symmap.width * (symmap.group_info & 0x0f);
+                     j++)
+                    if (xkbdesc.map.syms[symmap.offset + j] == keyval)
+                        return xkbdesc.map.modmap[i];
+            }
+            return 0;
+        }
+
         private uchar get_reserved_keycode () {
             uchar i;
             unowned Xkb.Desc xkbdesc = this.xkbdesc;
@@ -196,16 +219,17 @@ namespace Caribou {
             Gdk.KeymapKey? best_match = null;
 
             foreach (KeymapKey km in kmk)
-               if (km.group == this.group && km.level <= 1)
+               if (km.group == this.group &&
+                   km.level < this.level_switch_modifiers.length)
                    best_match = km;
 
             if (best_match == null)
                 return false;
 
-               keycode = (uchar) best_match.keycode;
-               modmask = (best_match.level == 1) ? Gdk.ModifierType.SHIFT_MASK : 0;
+            keycode = (uchar) best_match.keycode;
+            modmask = this.level_switch_modifiers[best_match.level];
 
-               return true;
+            return true;
         }
 
         private uchar keycode_for_keyval (uint keyval, out uint modmask) {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]