[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freedesktop-xorg-devel
Subject:    [PATCH v5 RESEND RFC 05/10] kdrive: update evdev keyboard LEDs (#22302)
From:       Laércio de Sousa <laerciosousa () sme-mogidascruzes ! sp ! gov ! br>
Date:       2015-08-24 12:44:57
Message-ID: 1440420302-6090-6-git-send-email-laerciosousa () sme-mogidascruzes ! sp ! gov ! br
[Download RAW message or body]

From: Mikhail Krivtsov <mikhail.krivtsov@gmail.com>

When one hits {Num,Caps,Scroll}Lock key on a Xephyr's keyboard,
keyboard itself works as expected but LEDs are not updated
and always stay in off.

Currently logical LEDs are propagated to physical keyboard LEDs
for "CoreKeyboard" only. All "kdrive" keyboards are not
"CoreKeyboard" and LEDs of "kdrive" keyboards are always "dead".

One possible solution is cloning "CoreKeyboard" LEDs to all
"kdrive" keyboards.

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=22302

Signed-off-by: Laércio de Sousa <laerciosousa@sme-mogidascruzes.sp.gov.br>
---
 hw/kdrive/linux/evdev.c | 11 ++++++++---
 hw/kdrive/src/kinput.c  | 23 +++++++++++++++++++++++
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/hw/kdrive/linux/evdev.c b/hw/kdrive/linux/evdev.c
index 63e8409..fecbae4 100644
--- a/hw/kdrive/linux/evdev.c
+++ b/hw/kdrive/linux/evdev.c
@@ -440,10 +440,16 @@ EvdevKbdEnable(KdKeyboardInfo * ki)
 static void
 EvdevKbdLeds(KdKeyboardInfo * ki, int leds)
 {
-/*    struct input_event event;
+    struct input_event event;
     Kevdev             *ke;
+    if (!ki) return; // This shouldn't happen but just for safety.
 
-    ki->driverPrivate = ke;
+    ke = ki->driverPrivate;
+    if (!ke) {
+	ErrorF("[%s:%u:%s] can't update LEDs of _disabled_ evdev keyboard\n",
+		__FILE__, __LINE__, __FUNCTION__);
+	return;
+    }
 
     memset(&event, 0, sizeof(event));
 
@@ -466,7 +472,6 @@ EvdevKbdLeds(KdKeyboardInfo * ki, int leds)
     event.code = LED_COMPOSE;
     event.value = leds & (1 << 3) ? 1 : 0;
     write(ke->fd, (char *) &event, sizeof(event));
-*/
 }
 
 static void
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 49c8bb6..1da4537 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -607,6 +607,28 @@ KdSetLed(KdKeyboardInfo * ki, int led, Bool on)
     KdSetLeds(ki, ki->dixdev->kbdfeed->ctrl.leds);
 }
 
+/*
+ * For unknown reason, logical keyboard LEDs are propagated to physical
+ * keyboard LEDs for "CoreKeyboard" only. All "kdrive" keyboards are
+ * not "CoreKeyboard" and LEDs of "kdrive" keyboards are always "dead".
+ * As workaround, the following function will clone "CoreKeyboard" LEDs
+ * to all "kdrive" keyboards.
+ */
+static void
+KdCloneCoreLEDs(void)
+{
+    DeviceIntPtr pCoreKeyboard = inputInfo.keyboard;
+    if (pCoreKeyboard && pCoreKeyboard->kbdfeed) {
+       Leds leds = pCoreKeyboard->kbdfeed->ctrl.leds;
+       KdKeyboardInfo *tmp;
+       for (tmp = kdKeyboards; tmp; tmp = tmp->next) {
+           if (tmp->leds != leds) {
+                KdSetLeds(tmp, tmp->leds = leds);
+           }
+        }
+    }
+}
+
 void
 KdSetPointerMatrix(KdPointerMatrix * matrix)
 {
@@ -2198,6 +2220,7 @@ ProcessInputEvents(void)
     if (kdSwitchPending)
         KdProcessSwitch();
     KdCheckLock();
+    KdCloneCoreLEDs();
 }
 
 /* At the moment, absolute/relative is up to the client. */
-- 
2.5.0

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic