Alexandre Julliard : winex11: Fetch the key state from the server when adjusting state on KeymapNotify and key events .

Alexandre Julliard julliard at winehq.org
Wed Mar 2 12:23:46 CST 2011


Module: wine
Branch: master
Commit: 731f5b0b7b608b9b70683721ad297fdb60432701
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=731f5b0b7b608b9b70683721ad297fdb60432701

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Mar  2 12:24:25 2011 +0100

winex11: Fetch the key state from the server when adjusting state on KeymapNotify and key events.

---

 dlls/winex11.drv/keyboard.c |  115 +++++++++++++++++++++++--------------------
 1 files changed, 62 insertions(+), 53 deletions(-)

diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 190436b..04d7371 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1270,28 +1270,21 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl
 
 
 /***********************************************************************
- *           KEYBOARD_UpdateOneState
- *
- * Updates internal state for <vkey>, depending on key <state> under X
- *
+ *           get_async_key_state
  */
-static inline void KEYBOARD_UpdateOneState ( HWND hwnd, WORD vkey, WORD scan, int state, DWORD time )
+static BOOL get_async_key_state( BYTE state[256] )
 {
-    /* Do something if internal table state != X state for keycode */
-    if (((key_state_table[vkey & 0xff] & 0x80)!=0) != state)
-    {
-        DWORD flags = vkey & 0x100 ? KEYEVENTF_EXTENDEDKEY : 0;
-
-        if (!state) flags |= KEYEVENTF_KEYUP;
-
-        TRACE("Adjusting state for vkey %#.2x. State before %#.2x\n",
-              vkey, key_state_table[vkey & 0xff]);
-
-        /* Fake key being pressed inside wine */
-        X11DRV_send_keyboard_input( hwnd, vkey & 0xff, scan & 0xff, flags, time, 0, 0 );
+    BOOL ret;
 
-        TRACE("State after %#.2x\n", key_state_table[vkey & 0xff]);
+    SERVER_START_REQ( get_key_state )
+    {
+        req->tid = 0;
+        req->key = -1;
+        wine_server_set_reply( req, state, 256 );
+        ret = !wine_server_call( req );
     }
+    SERVER_END_REQ;
+    return ret;
 }
 
 /***********************************************************************
@@ -1307,6 +1300,9 @@ void X11DRV_KeymapNotify( HWND hwnd, XEvent *event )
 {
     int i, j;
     DWORD time = GetCurrentTime();
+    BYTE keystate[256];
+
+    if (!get_async_key_state( keystate )) return;
 
     /* the minimum keycode is always greater or equal to 8, so we can
      * skip the first 8 values, hence start at 1
@@ -1316,8 +1312,6 @@ void X11DRV_KeymapNotify( HWND hwnd, XEvent *event )
         for (j = 0; j < 8; j++)
         {
             WORD vkey = keyc2vkey[(i * 8) + j];
-            WORD scan = keyc2scan[(i * 8) + j];
-            int state = (event->xkeymap.key_vector[i] & (1<<j)) != 0;
 
             switch(vkey & 0xff)
             {
@@ -1327,21 +1321,62 @@ void X11DRV_KeymapNotify( HWND hwnd, XEvent *event )
             case VK_RCONTROL:
             case VK_LSHIFT:
             case VK_RSHIFT:
-                KEYBOARD_UpdateOneState( hwnd, vkey, scan, state, time );
+                if (!(keystate[vkey & 0xff] & 0x80) != !(event->xkeymap.key_vector[i] & (1<<j)))
+                {
+                    WORD scan = keyc2scan[(i * 8) + j];
+                    DWORD flags = vkey & 0x100 ? KEYEVENTF_EXTENDEDKEY : 0;
+                    if (!(event->xkeymap.key_vector[i] & (1<<j))) flags |= KEYEVENTF_KEYUP;
+
+                    TRACE( "Adjusting state for vkey %#.2x. State before %#.2x\n",
+                           vkey, keystate[vkey & 0xff]);
+
+                    /* Fake key being pressed inside wine */
+                    X11DRV_send_keyboard_input( hwnd, vkey & 0xff, scan & 0xff, flags, time, 0, 0 );
+                }
                 break;
             }
         }
     }
 }
 
-static void update_lock_state(HWND hwnd, BYTE vkey, WORD scan, DWORD time)
+static void update_lock_state( HWND hwnd, WORD vkey, UINT state, DWORD time )
 {
-    DWORD flags = vkey == VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0;
+    BYTE keystate[256];
+
+    /* Note: X sets the below states on key down and clears them on key up.
+       Windows triggers them on key down. */
 
-    if (key_state_table[vkey] & 0x80) flags ^= KEYEVENTF_KEYUP;
+    if (!get_async_key_state( keystate )) return;
 
-    X11DRV_send_keyboard_input( hwnd, vkey, scan, flags, time, 0, 0 );
-    X11DRV_send_keyboard_input( hwnd, vkey, scan, flags ^ KEYEVENTF_KEYUP, time, 0, 0 );
+    /* Adjust the CAPSLOCK state if it has been changed outside wine */
+    if (!(keystate[VK_CAPITAL] & 0x01) != !(state & LockMask) && vkey != VK_CAPITAL)
+    {
+        DWORD flags = 0;
+        if (keystate[VK_CAPITAL] & 0x80) flags ^= KEYEVENTF_KEYUP;
+        TRACE("Adjusting CapsLock state (%#.2x)\n", keystate[VK_CAPITAL]);
+        X11DRV_send_keyboard_input( hwnd, VK_CAPITAL, 0x3a, flags, time, 0, 0 );
+        X11DRV_send_keyboard_input( hwnd, VK_CAPITAL, 0x3a, flags ^ KEYEVENTF_KEYUP, time, 0, 0 );
+    }
+
+    /* Adjust the NUMLOCK state if it has been changed outside wine */
+    if (!(keystate[VK_NUMLOCK] & 0x01) != !(state & NumLockMask) && (vkey & 0xff) != VK_NUMLOCK)
+    {
+        DWORD flags = KEYEVENTF_EXTENDEDKEY;
+        if (keystate[VK_NUMLOCK] & 0x80) flags ^= KEYEVENTF_KEYUP;
+        TRACE("Adjusting NumLock state (%#.2x)\n", keystate[VK_NUMLOCK]);
+        X11DRV_send_keyboard_input( hwnd, VK_NUMLOCK, 0x45, flags, time, 0, 0 );
+        X11DRV_send_keyboard_input( hwnd, VK_NUMLOCK, 0x45, flags ^ KEYEVENTF_KEYUP, time, 0, 0 );
+    }
+
+    /* Adjust the SCROLLLOCK state if it has been changed outside wine */
+    if (!(keystate[VK_SCROLL] & 0x01) != !(state & ScrollLockMask) && vkey != VK_SCROLL)
+    {
+        DWORD flags = 0;
+        if (keystate[VK_SCROLL] & 0x80) flags ^= KEYEVENTF_KEYUP;
+        TRACE("Adjusting ScrLock state (%#.2x)\n", keystate[VK_SCROLL]);
+        X11DRV_send_keyboard_input( hwnd, VK_SCROLL, 0x46, flags, time, 0, 0 );
+        X11DRV_send_keyboard_input( hwnd, VK_SCROLL, 0x46, flags ^ KEYEVENTF_KEYUP, time, 0, 0 );
+    }
 }
 
 /***********************************************************************
@@ -1441,33 +1476,7 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
     if ( event->type == KeyRelease ) dwFlags |= KEYEVENTF_KEYUP;
     if ( vkey & 0x100 )              dwFlags |= KEYEVENTF_EXTENDEDKEY;
 
-
-    /* Note: X sets the below states on key down and clears them on key up.
-       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) &&
-        vkey != VK_CAPITAL)
-    {
-        TRACE("Adjusting CapsLock state (%#.2x)\n", key_state_table[VK_CAPITAL]);
-        update_lock_state( hwnd, VK_CAPITAL, 0x3A, event_time );
-    }
-
-    /* Adjust the NUMLOCK state if it has been changed outside wine */
-    if (!(key_state_table[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask) &&
-        (vkey & 0xff) != VK_NUMLOCK)
-    {
-        TRACE("Adjusting NumLock state (%#.2x)\n", key_state_table[VK_NUMLOCK]);
-        update_lock_state( hwnd, VK_NUMLOCK, 0x45, event_time );
-    }
-
-    /* Adjust the SCROLLLOCK state if it has been changed outside wine */
-    if (!(key_state_table[VK_SCROLL] & 0x01) != !(event->state & ScrollLockMask) &&
-        vkey != VK_SCROLL)
-    {
-        TRACE("Adjusting ScrLock state (%#.2x)\n", key_state_table[VK_SCROLL]);
-        update_lock_state( hwnd, VK_SCROLL, 0x46, event_time );
-    }
+    update_lock_state( hwnd, vkey, event->state, event_time );
 
     bScan = keyc2scan[event->keycode] & 0xFF;
     TRACE_(key)("bScan = 0x%02x.\n", bScan);




More information about the wine-cvs mailing list