Patch submitted to Red Hat bugzilla by Mark McLoughlin to fix the following bugs: Fixes bugs: https://bugs.freedesktop.org/show_bug.cgi?id=3030 https://bugs.freedesktop.org/show_bug.cgi?id=3664 And the first part of bug: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=162246 Mike A. Harris --- xc/programs/Xserver/hw/xnest/Events.h.xnest-update-modifier-state-fdo3030-fdo3664 2004-04-23 20:54:21.000000000 +0100 +++ xc/programs/Xserver/hw/xnest/Events.h 2005-07-01 14:40:14.000000000 +0100 @@ -26,5 +26,6 @@ void SetTimeSinceLastInputEvent(void); void xnestCollectExposures(void); void xnestCollectEvents(void); +void xnestQueueKeyEvent(int type, unsigned int keycode); #endif /* XNESTEVENTS_H */ --- xc/programs/Xserver/hw/xnest/Pointer.h.xnest-update-modifier-state-fdo3030-fdo3664 2004-04-23 20:54:21.000000000 +0100 +++ xc/programs/Xserver/hw/xnest/Pointer.h 2005-07-01 14:40:14.000000000 +0100 @@ -23,6 +23,8 @@ (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \ EnterWindowMask | LeaveWindowMask) +extern DeviceIntPtr xnestPointerDevice; + void xnestChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl); int xnestPointerProc(DeviceIntPtr pDev, int onoff); --- xc/programs/Xserver/hw/xnest/Keyboard.c.xnest-update-modifier-state-fdo3030-fdo3664 2004-04-23 20:54:21.000000000 +0100 +++ xc/programs/Xserver/hw/xnest/Keyboard.c 2005-07-01 14:40:29.000000000 +0100 @@ -31,6 +31,7 @@ #include "Screen.h" #include "Keyboard.h" #include "Args.h" +#include "Events.h" #ifdef XKB #include @@ -83,6 +84,8 @@ #endif +DeviceIntPtr xnestKeyboardDevice = NULL; + void xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls) { @@ -282,3 +285,51 @@ { return TRUE; } + +void +xnestUpdateModifierState(unsigned int state) +{ + DeviceIntPtr pDev = xnestKeyboardDevice; + KeyClassPtr keyc = pDev->key; + int i; + CARD8 mask; + + state = state & 0xff; + + if (keyc->state == state) + return; + + for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { + int key; + + /* Modifier is down, but shouldn't be + */ + if ((keyc->state & mask) && !(state & mask)) { + int count = keyc->modifierKeyCount[i]; + + for (key = 0; key < MAP_LENGTH; key++) + if (keyc->modifierMap[key] & mask) { + int bit; + BYTE *kptr; + + kptr = &keyc->down[key >> 3]; + bit = 1 << (key & 7); + + if (*kptr & bit) + xnestQueueKeyEvent(KeyRelease, key); + + if (--count == 0) + break; + } + } + + /* Modifier shoud be down, but isn't + */ + if (!(keyc->state & mask) && (state & mask)) + for (key = 0; key < MAP_LENGTH; key++) + if (keyc->modifierMap[key] & mask) { + xnestQueueKeyEvent(KeyPress, key); + break; + } + } +} --- xc/programs/Xserver/hw/xnest/Events.c.xnest-update-modifier-state-fdo3030-fdo3664 2004-08-11 23:40:14.000000000 +0100 +++ xc/programs/Xserver/hw/xnest/Events.c 2005-07-01 14:40:29.000000000 +0100 @@ -34,6 +34,7 @@ #include "Screen.h" #include "XNWindow.h" #include "Events.h" +#include "Keyboard.h" #include "mipointer.h" CARD32 lastEventTime = 0; @@ -96,6 +97,16 @@ } void +xnestQueueKeyEvent(int type, unsigned int keycode) +{ + xEvent x; + x.u.u.type = type; + x.u.u.detail = keycode; + x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis(); + mieqEnqueue(&x); +} + +void xnestCollectEvents() { XEvent X; @@ -105,20 +116,17 @@ while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) { switch (X.type) { case KeyPress: - x.u.u.type = KeyPress; - x.u.u.detail = X.xkey.keycode; - x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis(); - mieqEnqueue(&x); + xnestUpdateModifierState(X.xkey.state); + xnestQueueKeyEvent(KeyPress, X.xkey.keycode); break; case KeyRelease: - x.u.u.type = KeyRelease; - x.u.u.detail = X.xkey.keycode; - x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis(); - mieqEnqueue(&x); + xnestUpdateModifierState(X.xkey.state); + xnestQueueKeyEvent(KeyRelease, X.xkey.keycode); break; case ButtonPress: + xnestUpdateModifierState(X.xkey.state); x.u.u.type = ButtonPress; x.u.u.detail = X.xbutton.button; x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis(); @@ -126,6 +134,7 @@ break; case ButtonRelease: + xnestUpdateModifierState(X.xkey.state); x.u.u.type = ButtonRelease; x.u.u.detail = X.xbutton.button; x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis(); --- xc/programs/Xserver/hw/xnest/Keyboard.h.xnest-update-modifier-state-fdo3030-fdo3664 2004-04-23 20:54:21.000000000 +0100 +++ xc/programs/Xserver/hw/xnest/Keyboard.h 2005-07-01 14:40:14.000000000 +0100 @@ -20,8 +20,11 @@ #define XNEST_KEYBOARD_EVENT_MASK \ (KeyPressMask | KeyReleaseMask | FocusChangeMask | KeymapStateMask) +extern DeviceIntPtr xnestKeyboardDevice; + void xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls); void xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl); int xnestKeyboardProc(DeviceIntPtr pDev, int onoff); +void xnestUpdateModifierState(unsigned int state); #endif /* XNESTKEYBOARD_H */ --- xc/programs/Xserver/hw/xnest/Init.c.xnest-update-modifier-state-fdo3030-fdo3664 2004-06-21 14:40:25.000000000 +0100 +++ xc/programs/Xserver/hw/xnest/Init.c 2005-07-01 14:40:14.000000000 +0100 @@ -87,15 +87,13 @@ void InitInput(int argc, char *argv[]) { - pointer ptr, kbd; + xnestPointerDevice = AddInputDevice(xnestPointerProc, TRUE); + xnestKeyboardDevice = AddInputDevice(xnestKeyboardProc, TRUE); - ptr = AddInputDevice(xnestPointerProc, TRUE); - kbd = AddInputDevice(xnestKeyboardProc, TRUE); + RegisterPointerDevice(xnestPointerDevice); + RegisterKeyboardDevice(xnestKeyboardDevice); - RegisterPointerDevice(ptr); - RegisterKeyboardDevice(kbd); - - mieqInit(kbd, ptr); + mieqInit((DevicePtr)xnestKeyboardDevice, (DevicePtr)xnestPointerDevice); AddEnabledDevice(XConnectionNumber(xnestDisplay)); --- xc/programs/Xserver/hw/xnest/Pointer.c.xnest-update-modifier-state-fdo3030-fdo3664 2004-04-23 20:54:21.000000000 +0100 +++ xc/programs/Xserver/hw/xnest/Pointer.c 2005-07-01 14:40:14.000000000 +0100 @@ -31,6 +31,8 @@ #include "Pointer.h" #include "Args.h" +DeviceIntPtr xnestPointerDevice = NULL; + void xnestChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl) {