[caribou] xadapter: use XkbChangeMap instead of XkbSetMap



commit e39364ba5a8930ade20af80ad30aba69ea9398cd
Author: Daiki Ueno <ueno unixuser org>
Date:   Thu Oct 25 15:23:52 2012 +0900

    xadapter: use XkbChangeMap instead of XkbSetMap
    
    Optimize keycode replacement logic using XkbChangeMap instead
    of XkbSetMap.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=673547

 libcaribou/external-libs.vapi |   40 ++++++++++++++++++++++++++++++++++++----
 libcaribou/xadapter.vala      |   19 ++++++++++++-------
 2 files changed, 48 insertions(+), 11 deletions(-)
---
diff --git a/libcaribou/external-libs.vapi b/libcaribou/external-libs.vapi
index 209d064..930e582 100644
--- a/libcaribou/external-libs.vapi
+++ b/libcaribou/external-libs.vapi
@@ -9,6 +9,9 @@ namespace Xkb {
     [CCode (cname = "XkbSetMap")]
     public void set_map (X.Display dpy, uint which, Desc xkb);
 
+    [CCode (cname = "XkbChangeMap")]
+    public bool change_map (X.Display dpy, Desc xkb, MapChanges changes);
+
     [CCode (cname = "XkbFreeKeyboard")]
     public void free_keyboard (Desc xkb, uint which, bool free_all);
 
@@ -109,6 +112,29 @@ namespace Xkb {
         ushort   offset;
     }
 
+    [CCode (cname = "XkbMapChangesRec", free_function = "")]
+	public struct MapChanges {
+        ushort changed;
+        char min_key_code;
+        char max_key_code;
+        uchar first_type;
+        uchar num_types;
+        char first_key_sym;
+        uchar num_key_syms;
+        char first_key_act;
+        uchar num_key_acts;
+        char first_key_behavior;
+        uchar num_key_behaviors;
+        char first_key_explicit;
+        uchar num_key_explicit;
+        char first_modmap_key;
+        uchar num_modmap_keys;
+        char first_vmodmap_key;
+        uchar num_vmodmap_keys;
+        uchar pad;
+        ushort vmods;
+	}
+
     [Compact]
     [CCode (cname = "XkbClientMapRec", free_function = "")]
     public class ClientMap {
@@ -212,15 +238,21 @@ namespace Xkb {
     [CCode (cname = "XkbAllEventsMask")]
     public int AllEventsMask;
 
-   [CCode (cname = "XkbStateNotify")]
+    [CCode (cname = "XkbStateNotify")]
     public int StateNotify;
 
-   [CCode (cname = "XkbGroupStateMask")]
+    [CCode (cname = "XkbGroupStateMask")]
     public int GroupStateMask;
 
-   [CCode (cname = "XkbModifierStateMask")]
+    [CCode (cname = "XkbModifierStateMask")]
     public int ModifierStateMask;
 
-  [CCode (cname = "XkbAllMapComponentsMask")]
+    [CCode (cname = "XkbAllMapComponentsMask")]
     public int AllMapComponentsMask;
+
+    [CCode (cname = "XkbKeySymsMask")]
+    public int KeySymsMask;
+
+    [CCode (cname = "XkbKeyTypesMask")]
+    public int KeyTypesMask;
 }
diff --git a/libcaribou/xadapter.vala b/libcaribou/xadapter.vala
index a222f2f..8319313 100644
--- a/libcaribou/xadapter.vala
+++ b/libcaribou/xadapter.vala
@@ -154,16 +154,21 @@ namespace Caribou {
 
             this.xdisplay.flush ();
             uint offset = this.xkbdesc.map.key_sym_map[this.reserved_keycode].offset;
-
             this.xkbdesc.map.syms[offset] = keysym;
             this.xkbdesc.device_spec = (ushort) Xkb.UseCoreKbd;
 
-            Xkb.set_map (this.xdisplay, Xkb.AllMapComponentsMask, this.xkbdesc);
-            /**
-             *  FIXME: the use of XkbChangeMap, and the reuse of the priv->xkb_desc
-             *  structure, would be far preferable. HOWEVER it does not seem to work
-             *  using XFree 4.3.
-             **/
+            Xkb.MapChanges changes = Xkb.MapChanges ();
+
+            // We don't touch key types here but include the
+            // information in XkbSetMap request to the server, because
+            // some X servers need the information to check the sanity
+            // of the keysyms change.
+            changes.changed = (ushort) (Xkb.KeySymsMask | Xkb.KeyTypesMask);
+            changes.first_key_sym = (char) this.reserved_keycode;
+            changes.num_key_syms = this.xkbdesc.map.key_sym_map[this.reserved_keycode].width;
+            changes.first_type = 0;
+            changes.num_types = this.xkbdesc.map.num_types;
+            Xkb.change_map (this.xdisplay, this.xkbdesc, changes);
 
             this.xdisplay.flush ();
 



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