[PATCH 2/3] dix: when attaching a slave device, update the xkb modifier state from master

Peter Hutterer peter.hutterer at who-t.net
Sun Feb 23 21:33:50 PST 2014


Fixes a long-standing issue of the numlock being out-of-sync on a hotplugged
keyboard.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 dix/devices.c    |  7 +++++++
 include/xkbsrv.h |  2 ++
 xkb/xkbActions.c | 38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+)

diff --git a/dix/devices.c b/dix/devices.c
index 1c86d52..f5a16bf 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -416,6 +416,7 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent)
         XISendDeviceHierarchyEvent(flags);
     }
 
+    XkbUpdateKbdModifiersFromMaster(dev);
     RecalculateMasterButtons(dev);
 
     /* initialise an idle timer for this device*/
@@ -2649,6 +2650,12 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
         dev->spriteInfo->paired = master;
         dev->spriteInfo->spriteOwner = FALSE;
 
+        /* AttachDevice is also called during EnableDevice, when the device
+           fd isn't set yet. Trying to write to the device will fail, but
+           the internal state is updated so the LEDs won't light up on the
+           second call at the end of EnableDevice */
+        if (dev->public.on)
+            XkbUpdateKbdModifiersFromMaster(dev);
         RecalculateMasterButtons(master);
     }
 
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 73a7b19..35f7bc4 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -758,6 +758,8 @@ XkbLatchLockState(ClientPtr client,
                   int modLatches,
                   int latchGroup,
                   int groupLatch);
+void
+XkbUpdateKbdModifiersFromMaster(DeviceIntPtr dev);
 
 extern _X_EXPORT void XkbGetRulesDflts(XkbRMLVOSet *    /* rmlvo */
     );
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 1443498..c89baaf 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -79,6 +79,44 @@ XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
     WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
 }
 
+/**
+ * Update keyboard modifiers, and most importantly LEDs from the master
+ * device.
+ */
+void
+XkbUpdateKbdModifiersFromMaster(DeviceIntPtr dev)
+{
+    DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD);
+    XkbStateRec *state;
+
+    if (!master)
+        return;
+    if (!dev->key)
+        return;
+
+    BUG_WARN(!master->key);
+
+    /* FIXME: this is potentially buggy. if the modmap of the slave differs
+     * from the master, we'll update the wrong mods and groups here. We'll
+     * have to live with that for now.
+     * Really what we'd need here is get each mod separately, map it to the
+     * respective mod on the other device, then update that map.
+     */
+    state = &master->key->xkbInfo->state;
+    XkbLatchLockState(NullClient, dev,
+                      state->locked_mods,
+                      state->locked_mods,
+                      state->locked_group,
+                      state->locked_group,
+                      state->latched_mods,
+                      state->latched_mods,
+                      state->latched_group,
+                      state->latched_group);
+
+}
+
+
+
 /***====================================================================***/
 
 static XkbAction
-- 
1.8.4.2



More information about the xorg-devel mailing list