summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@nwnk.net>2005-06-25 21:28:48 +0000
committerAdam Jackson <ajax@nwnk.net>2005-06-25 21:28:48 +0000
commitaa7fb99bc76e62036c73ff50f58337558859b814 (patch)
treeb2e26112b997cca8c4a91f9af2811840fcffcb70
parent8562f800b879ae461317da9640961f753e107250 (diff)
Bug #3030: Fix Xnest keyboard state handling. (Mark McLoughlin)
-rw-r--r--hw/xnest/Events.c23
-rw-r--r--hw/xnest/Events.h1
-rw-r--r--hw/xnest/Init.c12
-rw-r--r--hw/xnest/Keyboard.c49
-rw-r--r--hw/xnest/Keyboard.h3
-rw-r--r--hw/xnest/Pointer.c2
-rw-r--r--hw/xnest/Pointer.h2
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;
@@ -96,6 +97,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()
{
XEvent X;
@@ -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 <X11/extensions/XKB.h>
@@ -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);