mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +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_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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -33,28 +33,8 @@
|
|||
#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 *****************************************************************/
|
||||
|
||||
/* 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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue