--- xorg-server-1.5.3.orig/hw/kdrive/linux/evdev.c 2009-06-14 12:54:27.000000000 +0400 +++ xorg-server-1.5.3/hw/kdrive/linux/evdev.c 2009-06-15 22:46:41.000000000 +0400 @@ -520,10 +520,16 @@ 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)); @@ -546,7 +552,6 @@ event.code = LED_COMPOSE; event.value = leds & (1 << 3) ? 1 : 0; write(ke->fd, (char *) &event, sizeof(event)); -*/ } static void --- xorg-server-1.5.3.orig/hw/kdrive/src/kinput.c 2008-11-05 19:52:17.000000000 +0300 +++ xorg-server-1.5.3/hw/kdrive/src/kinput.c 2009-06-15 22:13:32.000000000 +0400 @@ -585,6 +585,28 @@ 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) { @@ -2353,6 +2375,7 @@ if (kdSwitchPending) KdProcessSwitch (); KdCheckLock (); + KdCloneCoreLEDs(); } /* FIXME use XSECURITY to work out whether the client should be allowed to