Module: wine Branch: master Commit: 731f5b0b7b608b9b70683721ad297fdb60432701 URL: http://source.winehq.org/git/wine.git/?a=commit;h=731f5b0b7b608b9b70683721ad...
Author: Alexandre Julliard julliard@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);