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