From e39364ba5a8930ade20af80ad30aba69ea9398cd Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Thu, 25 Oct 2012 15:23:52 +0900 Subject: 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 (); -- cgit v1.2.1