diff --git a/reactos/subsystems/win32/win32k/include/input.h b/reactos/subsystems/win32/win32k/include/input.h index ba123366a2a..bcf54013e09 100644 --- a/reactos/subsystems/win32/win32k/include/input.h +++ b/reactos/subsystems/win32/win32k/include/input.h @@ -27,6 +27,22 @@ extern PATTACHINFO gpai; #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 diff --git a/reactos/subsystems/win32/win32k/include/msgqueue.h b/reactos/subsystems/win32/win32k/include/msgqueue.h index e5158574e10..870cf874527 100644 --- a/reactos/subsystems/win32/win32k/include/msgqueue.h +++ b/reactos/subsystems/win32/win32k/include/msgqueue.h @@ -108,6 +108,9 @@ typedef struct _USER_MESSAGE_QUEUE /* 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 */ diff --git a/reactos/subsystems/win32/win32k/ntuser/keyboard.c b/reactos/subsystems/win32/win32k/ntuser/keyboard.c index d0509ad1e7a..c4ef0430555 100644 --- a/reactos/subsystems/win32/win32k/ntuser/keyboard.c +++ b/reactos/subsystems/win32/win32k/ntuser/keyboard.c @@ -33,28 +33,8 @@ #define NDEBUG #include - -/* 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 *****************************************************************/ /* Initialization -- Right now, just zero the key state and init the lock */ @@ -353,40 +333,6 @@ ToUnicodeInner(UINT wVirtKey, } -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) { DWORD ret = 0; diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index 9f57375da83..2fb518dfed3 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -41,6 +41,106 @@ MsqInitializeImpl(VOID) 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 IntMsqSetWakeMask(DWORD WakeMask) { @@ -1294,6 +1394,7 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, if (Remove) { + update_input_key_state(MessageQueue, pMsg); RemoveEntryList(&CurrentMessage->ListEntry); ClearMsgBitsMask(MessageQueue, QS_INPUT); MsqDestroyMessage(CurrentMessage); @@ -1714,4 +1815,19 @@ MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd) return NULL; } +SHORT +APIENTRY +NtUserGetKeyState(INT key) +{ + DWORD Ret; + + UserEnterExclusive(); + + Ret = UserGetKeyState(key); + + UserLeave(); + + return Ret; +} + /* EOF */