Module: wine Branch: master Commit: bc325ac268ab0b99e1ce6d5012dd329cacb2357c URL: http://source.winehq.org/git/wine.git/?a=commit;h=bc325ac268ab0b99e1ce6d5012...
Author: Vitaliy Margolen wine-patches@kievinfo.com Date: Sat Apr 5 23:36:55 2008 -0600
winex11: Properly report state of the caps-lock and num-lock and scroll-lock keys.
---
dlls/winex11.drv/keyboard.c | 134 +++++++++++++++---------------------------- 1 files changed, 46 insertions(+), 88 deletions(-)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index f11a9ee..4be6336 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1139,8 +1139,6 @@ static WORD EVENT_event_to_vkey( XIC xic, XKeyEvent *e) return keyc2vkey[e->keycode]; }
-static BOOL NumState=FALSE, CapsState=FALSE; -
/*********************************************************************** * X11DRV_send_keyboard_input @@ -1265,53 +1263,6 @@ void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time }
-/********************************************************************** - * KEYBOARD_GenerateMsg - * - * Generate Down+Up messages when NumLock or CapsLock is pressed. - * - * Convention : called with vkey only VK_NUMLOCK or VK_CAPITAL - * - */ -static void KEYBOARD_GenerateMsg( WORD vkey, WORD scan, int Evtype, DWORD event_time ) -{ - BOOL * State = (vkey==VK_NUMLOCK? &NumState : &CapsState); - DWORD up, down; - - if (*State) { - /* The INTERMEDIARY state means : just after a 'press' event, if a 'release' event comes, - don't treat it. It's from the same key press. Then the state goes to ON. - And from there, a 'release' event will switch off the toggle key. */ - *State=FALSE; - TRACE("INTERM : don't treat release of toggle key. key_state_table[%#x] = %#x\n", - vkey,key_state_table[vkey]); - } else - { - down = (vkey==VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0); - up = (vkey==VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0) | KEYEVENTF_KEYUP; - if ( key_state_table[vkey] & 0x1 ) /* it was ON */ - { - if (Evtype!=KeyPress) - { - TRACE("ON + KeyRelease => generating DOWN and UP messages.\n"); - X11DRV_send_keyboard_input( vkey, scan, down, event_time, 0, 0 ); - X11DRV_send_keyboard_input( vkey, scan, up, event_time, 0, 0 ); - *State=FALSE; - key_state_table[vkey] &= ~0x01; /* Toggle state to off. */ - } - } - else /* it was OFF */ - if (Evtype==KeyPress) - { - TRACE("OFF + Keypress => generating DOWN and UP messages.\n"); - X11DRV_send_keyboard_input( vkey, scan, down, event_time, 0, 0 ); - X11DRV_send_keyboard_input( vkey, scan, up, event_time, 0, 0 ); - *State=TRUE; /* Goes to intermediary state before going to ON */ - key_state_table[vkey] |= 0x01; /* Toggle state to on. */ - } - } -} - /*********************************************************************** * KEYBOARD_UpdateOneState * @@ -1370,6 +1321,16 @@ void X11DRV_KeymapNotify( HWND hwnd, XEvent *event ) KEYBOARD_UpdateOneState( VK_SHIFT, shift, time ); }
+static void update_lock_state(BYTE vkey, WORD scan, DWORD time) +{ + DWORD flags = vkey == VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0; + + if (key_state_table[vkey] & 0x80) flags ^= KEYEVENTF_KEYUP; + + X11DRV_send_keyboard_input( vkey, scan, flags, time, 0, 0 ); + X11DRV_send_keyboard_input( vkey, scan, flags ^ KEYEVENTF_KEYUP, time, 0, 0 ); +} + /*********************************************************************** * X11DRV_KeyEvent * @@ -1443,47 +1404,44 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev ) TRACE_(key)("keycode 0x%x converted to vkey 0x%x\n", event->keycode, vkey);
- if (vkey) - { - switch (vkey & 0xff) - { - case VK_NUMLOCK: - KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, event_time ); - break; - case VK_CAPITAL: - TRACE("Caps Lock event. (type %d). State before : %#.2x\n",event->type,key_state_table[vkey]); - KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, event_time ); - TRACE("State after : %#.2x\n",key_state_table[vkey]); - break; - default: - /* Adjust the NUMLOCK state if it has been changed outside wine */ - if (!(key_state_table[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask)) - { - TRACE("Adjusting NumLock state.\n"); - KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, event_time ); - KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyRelease, event_time ); - } - /* Adjust the CAPSLOCK state if it has been changed outside wine */ - if (!(key_state_table[VK_CAPITAL] & 0x01) != !(event->state & LockMask)) - { - TRACE("Adjusting Caps Lock state.\n"); - KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyPress, event_time ); - KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyRelease, event_time ); - } - /* Not Num nor Caps : end of intermediary states for both. */ - NumState = FALSE; - CapsState = FALSE; + if (!vkey) return; + + dwFlags = 0; + if ( event->type == KeyRelease ) dwFlags |= KEYEVENTF_KEYUP; + if ( vkey & 0x100 ) dwFlags |= KEYEVENTF_EXTENDEDKEY; +
- bScan = keyc2scan[event->keycode] & 0xFF; - TRACE_(key)("bScan = 0x%02x.\n", bScan); + /* Note: X sets the below states on key down and clears them on key up. + Windows triggers them on key down. */
- dwFlags = 0; - if ( event->type == KeyRelease ) dwFlags |= KEYEVENTF_KEYUP; - if ( vkey & 0x100 ) dwFlags |= KEYEVENTF_EXTENDEDKEY; + /* 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(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(VK_NUMLOCK, 0x45, event_time); + }
- X11DRV_send_keyboard_input( vkey & 0xff, bScan, dwFlags, event_time, 0, 0 ); + /* 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(VK_SCROLL, 0x46, event_time); } - } + + bScan = keyc2scan[event->keycode] & 0xFF; + TRACE_(key)("bScan = 0x%02x.\n", bScan); + + X11DRV_send_keyboard_input( vkey & 0xff, bScan, dwFlags, event_time, 0, 0 ); }
/**********************************************************************