mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[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 svn path=/trunk/; revision=51295
This commit is contained in:
parent
4041e16e6f
commit
893a0bfccb
4 changed files with 135 additions and 54 deletions
|
@ -27,6 +27,22 @@ extern PATTACHINFO gpai;
|
||||||
#define KBL_PRELOAD 2
|
#define KBL_PRELOAD 2
|
||||||
#define KBL_RESET 4
|
#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
|
INIT_FUNCTION
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
|
@ -108,6 +108,9 @@ typedef struct _USER_MESSAGE_QUEUE
|
||||||
/* extra message information */
|
/* extra message information */
|
||||||
LPARAM ExtraInfo;
|
LPARAM ExtraInfo;
|
||||||
|
|
||||||
|
/* state of each key */
|
||||||
|
UCHAR KeyState[256];
|
||||||
|
|
||||||
/* messages that are currently dispatched by other threads */
|
/* messages that are currently dispatched by other threads */
|
||||||
LIST_ENTRY DispatchingMessagesHead;
|
LIST_ENTRY DispatchingMessagesHead;
|
||||||
/* messages that are currently dispatched by this message queue, required for cleanup */
|
/* messages that are currently dispatched by this message queue, required for cleanup */
|
||||||
|
|
|
@ -33,28 +33,8 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#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];
|
BYTE gQueueKeyStateTable[256];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
/* Initialization -- Right now, just zero the key state and init the lock */
|
/* 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 FASTCALL UserGetAsyncKeyState(DWORD key)
|
||||||
{
|
{
|
||||||
DWORD ret = 0;
|
DWORD ret = 0;
|
||||||
|
|
|
@ -41,6 +41,106 @@ MsqInitializeImpl(VOID)
|
||||||
return(STATUS_SUCCESS);
|
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
|
HANDLE FASTCALL
|
||||||
IntMsqSetWakeMask(DWORD WakeMask)
|
IntMsqSetWakeMask(DWORD WakeMask)
|
||||||
{
|
{
|
||||||
|
@ -1294,6 +1394,7 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
||||||
|
|
||||||
if (Remove)
|
if (Remove)
|
||||||
{
|
{
|
||||||
|
update_input_key_state(MessageQueue, pMsg);
|
||||||
RemoveEntryList(&CurrentMessage->ListEntry);
|
RemoveEntryList(&CurrentMessage->ListEntry);
|
||||||
ClearMsgBitsMask(MessageQueue, QS_INPUT);
|
ClearMsgBitsMask(MessageQueue, QS_INPUT);
|
||||||
MsqDestroyMessage(CurrentMessage);
|
MsqDestroyMessage(CurrentMessage);
|
||||||
|
@ -1714,4 +1815,19 @@ MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHORT
|
||||||
|
APIENTRY
|
||||||
|
NtUserGetKeyState(INT key)
|
||||||
|
{
|
||||||
|
DWORD Ret;
|
||||||
|
|
||||||
|
UserEnterExclusive();
|
||||||
|
|
||||||
|
Ret = UserGetKeyState(key);
|
||||||
|
|
||||||
|
UserLeave();
|
||||||
|
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue