Blob Blame History Raw
From f326e7db9c644e2b7bba0939b5bdd5637b8dbc01 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Wed, 26 Feb 2014 16:20:08 +1000
Subject: [PATCH 3/4] xkb: push locked modifier state down to attached slave
 devices

Whenever the master changes, push the locked modifier state to the attached
slave devices, then update the indicators. This way, when NumLock or CapsLock
are hit on any device, the LED will light up on all devices. Likewise, a new
keyboard attached to a master device will light up with the correct
indicators.

The indicators are handled per-keyboard, depending on the layout, i.e. if one
keyboard has grp_led:num set, the NumLock LED won't light up on that keyboard.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Daniel Stone <daniel@fooishbar.org>
(cherry picked from commit 45fb3a934dc0db51584aba37c2f9d73deff9191d)
---
 dix/devices.c    |  3 +++
 include/xkbsrv.h |  4 ++++
 xkb/xkbActions.c | 20 ++++++++++++++++++++
 3 files changed, 27 insertions(+)

diff --git a/dix/devices.c b/dix/devices.c
index a680ed8..4692251 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -416,6 +416,8 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent)
         XISendDeviceHierarchyEvent(flags);
     }
 
+    if (!IsMaster(dev))
+        XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0);
     RecalculateMasterButtons(dev);
 
     /* initialise an idle timer for this device*/
@@ -2648,6 +2650,7 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
         dev->spriteInfo->paired = master;
         dev->spriteInfo->spriteOwner = FALSE;
 
+        XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0);
         RecalculateMasterButtons(master);
     }
 
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index d5a4eb6..f23f786 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -638,6 +638,10 @@ extern _X_EXPORT void XkbHandleActions(DeviceIntPtr /* dev */ ,
                                        DeviceEvent *    /* event */
     );
 
+extern void XkbPushLockedStateToSlaves(DeviceIntPtr /* master */,
+                                       int /* evtype */,
+                                       int /* key */);
+
 extern _X_EXPORT Bool XkbEnableDisableControls(XkbSrvInfoPtr /* xkbi */ ,
                                                unsigned long /* change */ ,
                                                unsigned long /* newValues */ ,
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 2534c70..ba7368b 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1174,6 +1174,25 @@ _XkbApplyState(DeviceIntPtr dev, Bool genStateNotify, int evtype, int key)
 }
 
 void
+XkbPushLockedStateToSlaves(DeviceIntPtr master, int evtype, int key)
+{
+    DeviceIntPtr dev;
+    Bool genStateNotify;
+
+    nt_list_for_each_entry(dev, inputInfo.devices, next) {
+        if (!dev->key || GetMaster(dev, MASTER_KEYBOARD) != master)
+            continue;
+
+        genStateNotify = _XkbEnsureStateChange(dev->key->xkbInfo);
+
+        dev->key->xkbInfo->state.locked_mods =
+            master->key->xkbInfo->state.locked_mods;
+
+        _XkbApplyState(dev, genStateNotify, evtype, key);
+    }
+}
+
+void
 XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
 {
     int key, bit, i;
@@ -1327,6 +1346,7 @@ XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
     }
 
     _XkbApplyState(dev, genStateNotify, event->type, key);
+    XkbPushLockedStateToSlaves(dev, event->type, key);
 }
 
 int
-- 
1.9.3