From aa7fb99bc76e62036c73ff50f58337558859b814 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Sat, 25 Jun 2005 21:28:48 +0000 Subject: Bug #3030: Fix Xnest keyboard state handling. (Mark McLoughlin) --- hw/xnest/Events.c | 23 +++++++++++++++-------- hw/xnest/Events.h | 1 + hw/xnest/Init.c | 12 +++++------- hw/xnest/Keyboard.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ hw/xnest/Keyboard.h | 3 +++ hw/xnest/Pointer.c | 2 ++ hw/xnest/Pointer.h | 2 ++ 7 files changed, 77 insertions(+), 15 deletions(-) diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c index 482c5fda8..604499f89 100644 --- a/hw/xnest/Events.c +++ b/hw/xnest/Events.c @@ -34,6 +34,7 @@ is" without express or implied warranty. #include "Screen.h" #include "XNWindow.h" #include "Events.h" +#include "Keyboard.h" #include "mipointer.h" CARD32 lastEventTime = 0; @@ -95,6 +96,16 @@ xnestCollectExposures() } } +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() { @@ -105,17 +116,13 @@ xnestCollectEvents() 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: diff --git a/hw/xnest/Events.h b/hw/xnest/Events.h index 9ed211cb8..c61b26c0d 100644 --- a/hw/xnest/Events.h +++ b/hw/xnest/Events.h @@ -26,5 +26,6 @@ extern CARD32 lastEventTime; void SetTimeSinceLastInputEvent(void); void xnestCollectExposures(void); void xnestCollectEvents(void); +void xnestQueueKeyEvent(int type, unsigned int keycode); #endif /* XNESTEVENTS_H */ diff --git a/hw/xnest/Init.c b/hw/xnest/Init.c index 3fac15e63..ba209b732 100644 --- a/hw/xnest/Init.c +++ b/hw/xnest/Init.c @@ -87,15 +87,13 @@ InitOutput(ScreenInfo *screenInfo, int argc, char *argv[]) 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)); diff --git a/hw/xnest/Keyboard.c b/hw/xnest/Keyboard.c index f786819a5..a65b0ffcd 100644 --- a/hw/xnest/Keyboard.c +++ b/hw/xnest/Keyboard.c @@ -31,6 +31,7 @@ is" without express or implied warranty. #include "Screen.h" #include "Keyboard.h" #include "Args.h" +#include "Events.h" #ifdef XKB #include @@ -83,6 +84,8 @@ extern Status XkbGetControls( #endif +DeviceIntPtr xnestKeyboardDevice = NULL; + void xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls) { @@ -282,3 +285,49 @@ LegalModifier(unsigned int key, DevicePtr pDev) { return TRUE; } + +void +xnestUpdateModifierState(unsigned int state) +{ + DeviceIntPtr pDev = xnestKeyboardDevice; + KeyClassPtr keyc = pDev->key; + int i; + CARD8 mask; + + 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; + } + } +} diff --git a/hw/xnest/Keyboard.h b/hw/xnest/Keyboard.h index 480231860..8237dac14 100644 --- a/hw/xnest/Keyboard.h +++ b/hw/xnest/Keyboard.h @@ -20,8 +20,11 @@ is" without express or implied warranty. #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 */ diff --git a/hw/xnest/Pointer.c b/hw/xnest/Pointer.c index abd258d6c..7613122be 100644 --- a/hw/xnest/Pointer.c +++ b/hw/xnest/Pointer.c @@ -31,6 +31,8 @@ is" without express or implied warranty. #include "Pointer.h" #include "Args.h" +DeviceIntPtr xnestPointerDevice = NULL; + void xnestChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl) { diff --git a/hw/xnest/Pointer.h b/hw/xnest/Pointer.h index 27a2011b8..872dfb8ee 100644 --- a/hw/xnest/Pointer.h +++ b/hw/xnest/Pointer.h @@ -23,6 +23,8 @@ is" without express or implied warranty. (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \ EnterWindowMask | LeaveWindowMask) +extern DeviceIntPtr xnestPointerDevice; + void xnestChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl); int xnestPointerProc(DeviceIntPtr pDev, int onoff); -- cgit v1.2.3