winex11.drv: Detect key modifier masks in run-time.
Dmitry Timoshkov
dmitry at codeweavers.com
Wed Dec 24 04:34:54 CST 2008
I haven't heard back from the reporter of the bug 12939, but I hope that
this should be a move in the right direction.
---
dlls/winex11.drv/keyboard.c | 100 ++++++++++++++++++++++++++++++------------
1 files changed, 71 insertions(+), 29 deletions(-)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 8f839f7..c07d00d 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -66,7 +66,9 @@ static BYTE TrackSysKey = 0; /* determine whether ALT key up will cause a WM_SYS
static int min_keycode, max_keycode, keysyms_per_keycode;
static WORD keyc2vkey[256], keyc2scan[256];
-static int NumLockMask, ScrollLockMask, AltGrMask; /* mask in the XKeyEvent state */
+/* masks in the XKeyEvent state */
+static unsigned num_lock_mask, scroll_lock_mask, alt_gr_mask;
+static unsigned mode_switch_mask, caps_lock_mask, shift_mask, control_mask;
static char KEYBOARD_MapDeadKeysym(KeySym keysym);
@@ -1151,7 +1153,7 @@ static WORD EVENT_event_to_vkey( XIC xic, XKeyEvent *e)
else
XLookupString(e, buf, sizeof(buf), &keysym, NULL);
- if ((e->state & NumLockMask) &&
+ if ((e->state & num_lock_mask) &&
(keysym == XK_KP_Separator || keysym == XK_KP_Decimal ||
(keysym >= XK_KP_0 && keysym <= XK_KP_9)))
/* Only the Keypad keys 0-9 and . send different keysyms
@@ -1419,7 +1421,7 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
Ref: X Keyboard Extension: Library specification (section 14.1.1 and 17.1.1) */
/* Save also all possible modifier states. */
- AltGrMask = event->state & (0x6000 | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
+ alt_gr_mask = event->state & (0x6000 | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
if (TRACE_ON(key)){
const char *ksname;
@@ -1456,7 +1458,7 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
Windows triggers them on key down. */
/* Adjust the CAPSLOCK state if it has been changed outside wine */
- if (!(key_state_table[VK_CAPITAL] & 0x01) != !(event->state & LockMask) &&
+ if (!(key_state_table[VK_CAPITAL] & 0x01) != !(event->state & caps_lock_mask) &&
vkey != VK_CAPITAL)
{
TRACE("Adjusting CapsLock state (%#.2x)\n", key_state_table[VK_CAPITAL]);
@@ -1464,7 +1466,7 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
}
/* Adjust the NUMLOCK state if it has been changed outside wine */
- if (!(key_state_table[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask) &&
+ if (!(key_state_table[VK_NUMLOCK] & 0x01) != !(event->state & num_lock_mask) &&
(vkey & 0xff) != VK_NUMLOCK)
{
TRACE("Adjusting NumLock state (%#.2x)\n", key_state_table[VK_NUMLOCK]);
@@ -1472,7 +1474,7 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
}
/* Adjust the SCROLLLOCK state if it has been changed outside wine */
- if (!(key_state_table[VK_SCROLL] & 0x01) != !(event->state & ScrollLockMask) &&
+ if (!(key_state_table[VK_SCROLL] & 0x01) != !(event->state & scroll_lock_mask) &&
vkey != VK_SCROLL)
{
TRACE("Adjusting ScrLock state (%#.2x)\n", key_state_table[VK_SCROLL]);
@@ -1664,22 +1666,57 @@ void X11DRV_InitKeyboard( Display *display )
int j;
for (j = 0; j < mmp->max_keypermod; j += 1, kcp += 1)
+ {
if (*kcp)
{
int k;
for (k = 0; k < keysyms_per_keycode; k += 1)
- if (XKeycodeToKeysym(display, *kcp, k) == XK_Num_Lock)
- {
- NumLockMask = 1 << i;
- TRACE_(key)("NumLockMask is %x\n", NumLockMask);
- }
- else if (XKeycodeToKeysym(display, *kcp, k) == XK_Scroll_Lock)
- {
- ScrollLockMask = 1 << i;
- TRACE_(key)("ScrollLockMask is %x\n", ScrollLockMask);
- }
+ {
+ KeySym ks = XKeycodeToKeysym(display, *kcp, k);
+ switch (ks)
+ {
+ case 0: /* unused */
+ break;
+ case XK_Num_Lock:
+ num_lock_mask = 1 << i;
+ TRACE_(key)("num_lock_mask is %x\n", num_lock_mask);
+ break;
+ case XK_Scroll_Lock:
+ scroll_lock_mask = 1 << i;
+ TRACE_(key)("scroll_lock_mask is %x\n", scroll_lock_mask);
+ break;
+ case XK_Mode_switch:
+ mode_switch_mask = 1 << i;
+ TRACE_(key)("mode_switch_mask is %x\n", mode_switch_mask);
+ break;
+ case XK_Shift_L:
+ shift_mask = 1 << i;
+ TRACE_(key)("shift_mask(L) is %x\n", shift_mask);
+ break;
+ case XK_Shift_R:
+ shift_mask = 1 << i;
+ TRACE_(key)("shift_mask(R) is %x\n", shift_mask);
+ break;
+ case XK_Caps_Lock:
+ caps_lock_mask = 1 << i;
+ TRACE_(key)("caps_lock_mask is %x\n", caps_lock_mask);
+ break;
+ case XK_Control_L:
+ control_mask = 1 << i;
+ TRACE_(key)("control_mask(L) is %x\n", control_mask);
+ break;
+ case XK_Control_R:
+ control_mask = 1 << i;
+ TRACE_(key)("control_mask(R) is %x\n", control_mask);
+ break;
+ default:
+ WARN_(key)("keysym %04lx mask %x not handled\n", ks, 1 << i);
+ break;
+ }
+ }
}
+ }
}
XFreeModifiermap(mmp);
@@ -2499,28 +2536,33 @@ INT CDECL X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState
if (lpKeyState[VK_SHIFT] & 0x80)
{
- TRACE("ShiftMask = %04x\n", ShiftMask);
- e.state |= ShiftMask;
+ TRACE("shift_mask = %04x\n", shift_mask);
+ e.state |= shift_mask;
}
if (lpKeyState[VK_CAPITAL] & 0x01)
{
- TRACE("LockMask = %04x\n", LockMask);
- e.state |= LockMask;
+ TRACE("caps_lock_mask = %04x\n", caps_lock_mask);
+ e.state |= caps_lock_mask;
}
if (lpKeyState[VK_CONTROL] & 0x80)
{
- TRACE("ControlMask = %04x\n", ControlMask);
- e.state |= ControlMask;
+ TRACE("control_mask = %04x\n", control_mask);
+ e.state |= control_mask;
}
if (lpKeyState[VK_NUMLOCK] & 0x01)
{
- TRACE("NumLockMask = %04x\n", NumLockMask);
- e.state |= NumLockMask;
+ TRACE("num_lock_mask = %04x\n", num_lock_mask);
+ e.state |= num_lock_mask;
+ }
+ if (lpKeyState[VK_SCROLL] & 0x01)
+ {
+ TRACE("scroll_lock_mask = %04x\n", scroll_lock_mask);
+ e.state |= scroll_lock_mask;
}
/* Restore saved AltGr state */
- TRACE("AltGrMask = %04x\n", AltGrMask);
- e.state |= AltGrMask;
+ TRACE("alt_gr_mask = %04x\n", alt_gr_mask);
+ e.state |= alt_gr_mask;
TRACE_(key)("(%04X, %04X) : faked state = 0x%04x\n",
virtKey, scanCode, e.state);
@@ -2663,8 +2705,8 @@ INT CDECL X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState
else { /* ret != 0 */
/* We have a special case to handle : Shift + arrow, shift + home, ...
X returns a char for it, but Windows doesn't. Let's eat it. */
- if (!(e.state & NumLockMask) /* NumLock is off */
- && (e.state & ShiftMask) /* Shift is pressed */
+ if (!(e.state & num_lock_mask) /* NumLock is off */
+ && (e.state & shift_mask) /* Shift is pressed */
&& (keysym>=XK_KP_0) && (keysym<=XK_KP_9))
{
lpChar[0] = 0;
@@ -2673,7 +2715,7 @@ INT CDECL X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState
/* more areas where X returns characters but Windows does not
CTRL + number or CTRL + symbol */
- if (e.state & ControlMask)
+ if (e.state & control_mask)
{
if (((keysym>=33) && (keysym < 'A')) ||
((keysym > 'Z') && (keysym < 'a')))
--
1.6.0.5
More information about the wine-patches
mailing list