Author: gadamopoulos Date: Sat Apr 9 12:44:45 2011 New Revision: 51295
URL: http://svn.reactos.org/svn/reactos?rev=51295&view=rev Log: [win32k] - Rewrite GetKeyState based on wine. Now it's results are based on whether or nor the message queue has processed a keyboard message and not the actual state of the keyboard.c - TODO: ensure it works corectly and use this implementation in most other places in win32k when we need to check the state of a key. To ensure nothing breaks, this change affects only GetKeyState
Modified: trunk/reactos/subsystems/win32/win32k/include/input.h trunk/reactos/subsystems/win32/win32k/include/msgqueue.h trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
Modified: trunk/reactos/subsystems/win32/win32k/include/input.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/input.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/input.h [iso-8859-1] Sat Apr 9 12:44:45 2011 @@ -27,6 +27,22 @@ #define KBL_PRELOAD 2 #define KBL_RESET 4
+/* Key States */ +#define KS_DOWN_MASK 0xc0 +#define KS_DOWN_BIT 0x80 +#define KS_LOCK_BIT 0x01 +/* Lock modifiers */ +#define CAPITAL_BIT 0x80000000 +#define NUMLOCK_BIT 0x40000000 +#define MOD_BITS_MASK 0x3fffffff +#define MOD_KCTRL 0x02 +/* Scan Codes */ +#define SC_KEY_UP 0x8000 +/* lParam bits */ +#define LP_EXT_BIT (1<<24) +/* From kbdxx.c -- Key changes with numlock */ +#define KNUMP 0x400 + INIT_FUNCTION NTSTATUS NTAPI
Modified: trunk/reactos/subsystems/win32/win32k/include/msgqueue.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] Sat Apr 9 12:44:45 2011 @@ -108,6 +108,9 @@ /* extra message information */ LPARAM ExtraInfo;
+ /* state of each key */ + UCHAR KeyState[256]; + /* messages that are currently dispatched by other threads */ LIST_ENTRY DispatchingMessagesHead; /* messages that are currently dispatched by this message queue, required for cleanup */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] Sat Apr 9 12:44:45 2011 @@ -33,27 +33,7 @@ #define NDEBUG #include <debug.h>
- -/* Lock modifiers */ -#define CAPITAL_BIT 0x80000000 -#define NUMLOCK_BIT 0x40000000 -#define MOD_BITS_MASK 0x3fffffff -#define MOD_KCTRL 0x02 -/* Key States */ -#define KS_DOWN_MASK 0xc0 -#define KS_DOWN_BIT 0x80 -#define KS_LOCK_BIT 0x01 -/* Scan Codes */ -#define SC_KEY_UP 0x8000 -/* lParam bits */ -#define LP_EXT_BIT (1<<24) -/* From kbdxx.c -- Key changes with numlock */ -#define KNUMP 0x400 - - BYTE gQueueKeyStateTable[256]; - -
/* FUNCTIONS *****************************************************************/
@@ -351,40 +331,6 @@
return 0; } - - -DWORD FASTCALL UserGetKeyState(DWORD key) -{ - DWORD ret = 0; - - if( key < 0x100 ) - { - ret = ((DWORD)(gQueueKeyStateTable[key] & KS_DOWN_BIT) << 8 ) | - (gQueueKeyStateTable[key] & KS_LOCK_BIT); - } - - return ret; -} - - -SHORT -APIENTRY -NtUserGetKeyState( - INT key) -{ - DECLARE_RETURN(DWORD); - - DPRINT("Enter NtUserGetKeyState\n"); - UserEnterExclusive(); - - RETURN(UserGetKeyState(key)); - -CLEANUP: - DPRINT("Leave NtUserGetKeyState, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} -
DWORD FASTCALL UserGetAsyncKeyState(DWORD key)
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] Sat Apr 9 12:44:45 2011 @@ -39,6 +39,106 @@ 256);
return(STATUS_SUCCESS); +} + +DWORD FASTCALL UserGetKeyState(DWORD key) +{ + DWORD ret = 0; + PTHREADINFO pti; + PUSER_MESSAGE_QUEUE MessageQueue; + + pti = PsGetCurrentThreadWin32Thread(); + MessageQueue = pti->MessageQueue; + + if( key < 0x100 ) + { + ret = ((DWORD)(MessageQueue->KeyState[key] & KS_DOWN_BIT) << 8 ) | + (MessageQueue->KeyState[key] & KS_LOCK_BIT); + } + + return ret; +} + +/* change the input key state for a given key */ +static void set_input_key_state( PUSER_MESSAGE_QUEUE MessageQueue, UCHAR key, BOOL down ) +{ + if (down) + { + if (!(MessageQueue->KeyState[key] & KS_DOWN_BIT)) + { + MessageQueue->KeyState[key] ^= KS_LOCK_BIT; + } + MessageQueue->KeyState[key] |= KS_DOWN_BIT; + } + else + { + MessageQueue->KeyState[key] &= ~KS_DOWN_BIT; + } +} + +/* update the input key state for a keyboard message */ +static void update_input_key_state( PUSER_MESSAGE_QUEUE MessageQueue, MSG* msg ) +{ + UCHAR key; + BOOL down = 0; + + switch (msg->message) + { + case WM_LBUTTONDOWN: + down = 1; + /* fall through */ + case WM_LBUTTONUP: + set_input_key_state( MessageQueue, VK_LBUTTON, down ); + break; + case WM_MBUTTONDOWN: + down = 1; + /* fall through */ + case WM_MBUTTONUP: + set_input_key_state( MessageQueue, VK_MBUTTON, down ); + break; + case WM_RBUTTONDOWN: + down = 1; + /* fall through */ + case WM_RBUTTONUP: + set_input_key_state( MessageQueue, VK_RBUTTON, down ); + break; + case WM_XBUTTONDOWN: + down = 1; + /* fall through */ + case WM_XBUTTONUP: + if (msg->wParam == XBUTTON1) + set_input_key_state( MessageQueue, VK_XBUTTON1, down ); + else if (msg->wParam == XBUTTON2) + set_input_key_state( MessageQueue, VK_XBUTTON2, down ); + break; + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + down = 1; + /* fall through */ + case WM_KEYUP: + case WM_SYSKEYUP: + key = (UCHAR)msg->wParam; + set_input_key_state( MessageQueue, key, down ); + switch(key) + { + case VK_LCONTROL: + case VK_RCONTROL: + down = (MessageQueue->KeyState[VK_LCONTROL] | MessageQueue->KeyState[VK_RCONTROL]) & KS_DOWN_BIT; + set_input_key_state( MessageQueue, VK_CONTROL, down ); + break; + case VK_LMENU: + case VK_RMENU: + down = (MessageQueue->KeyState[VK_LMENU] | MessageQueue->KeyState[VK_RMENU]) & KS_DOWN_BIT; + set_input_key_state( MessageQueue, VK_MENU, down ); + break; + case VK_LSHIFT: + case VK_RSHIFT: + down = (MessageQueue->KeyState[VK_LSHIFT] | MessageQueue->KeyState[VK_RSHIFT]) & KS_DOWN_BIT; + set_input_key_state( MessageQueue, VK_SHIFT, down ); + break; + } + break; + } }
HANDLE FASTCALL @@ -1294,6 +1394,7 @@
if (Remove) { + update_input_key_state(MessageQueue, pMsg); RemoveEntryList(&CurrentMessage->ListEntry); ClearMsgBitsMask(MessageQueue, QS_INPUT); MsqDestroyMessage(CurrentMessage); @@ -1714,4 +1815,19 @@ return NULL; }
+SHORT +APIENTRY +NtUserGetKeyState(INT key) +{ + DWORD Ret; + + UserEnterExclusive(); + + Ret = UserGetKeyState(key); + + UserLeave(); + + return Ret; +} + /* EOF */