From: Mikhail Krivtsov <mikhail.krivt...@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 <laercioso...@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