mirror of
https://github.com/reactos/reactos.git
synced 2024-06-29 01:12:06 +00:00
[WIN32K]
- Use 64 byte bitmap for keystate instead of 256 elements array (like Windows) - Fix GetAsyncKeyState lowest bit meaning. See MSDN - Call low level keyboard hook before setting async key state for keys which distinguish between left and right hand. Fixes user32:GetKeyState apitest failure - Improve IsHotKey and delete GetHotKey function to avoid code duplication - Support WIN key in hotkeys code instead of keyboard.c svn path=/trunk/; revision=54063
This commit is contained in:
parent
0386650c63
commit
2a799f8ad8
|
@ -14,16 +14,11 @@ typedef struct _HOT_KEY_ITEM
|
|||
|
||||
INIT_FUNCTION NTSTATUS NTAPI InitHotkeyImpl(VOID);
|
||||
|
||||
BOOL FASTCALL
|
||||
GetHotKey (UINT fsModifiers,
|
||||
UINT vk,
|
||||
struct _ETHREAD **Thread,
|
||||
HWND *hWnd,
|
||||
int *id);
|
||||
|
||||
PHOT_KEY_ITEM FASTCALL IsHotKey(UINT fsModifiers, WORD wVk);
|
||||
VOID FASTCALL UnregisterWindowHotKeys(PWND Window);
|
||||
VOID FASTCALL UnregisterThreadHotKeys(struct _ETHREAD *Thread);
|
||||
BOOL NTAPI xxxDoHotKeyStuff(WORD wVk, BOOL bIsDown);
|
||||
UINT FASTCALL DefWndGetHotKey(HWND hwnd);
|
||||
INT FASTCALL DefWndSetHotKey( PWND pWnd, WPARAM wParam);
|
||||
INT FASTCALL DefWndSetHotKey(PWND pWnd, WPARAM wParam);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -51,9 +51,21 @@ BOOL UserInitDefaultKeyboardLayout(VOID);
|
|||
PKBL UserHklToKbl(HKL hKl);
|
||||
BOOL FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL);
|
||||
VOID FASTCALL DoTheScreenSaver(VOID);
|
||||
#define ThreadHasInputAccess(W32Thread) \
|
||||
(TRUE)
|
||||
#define ThreadHasInputAccess(W32Thread) (TRUE)
|
||||
|
||||
extern HANDLE ghKeyboardDevice;
|
||||
extern PTHREADINFO ptiRawInput;
|
||||
extern BYTE gafAsyncKeyState[0x100];
|
||||
extern BYTE gafAsyncKeyState[256 * 2 / 8]; // 2 bits per key
|
||||
|
||||
#define GET_KS_BYTE(vk) ((vk) * 2 / 8)
|
||||
#define GET_KS_DOWN_BIT(vk) (1 << (((vk) % 4)*2))
|
||||
#define GET_KS_LOCK_BIT(vk) (1 << (((vk) % 4)*2 + 1))
|
||||
#define IS_KEY_DOWN(ks, vk) (((ks)[GET_KS_BYTE(vk)] & GET_KS_DOWN_BIT(vk)) ? TRUE : FALSE)
|
||||
#define IS_KEY_LOCKED(ks, vk) (((ks)[GET_KS_BYTE(vk)] & GET_KS_LOCK_BIT(vk)) ? TRUE : FALSE)
|
||||
#define SET_KEY_DOWN(ks, vk, down) (ks)[GET_KS_BYTE(vk)] = ((down) ? \
|
||||
((ks)[GET_KS_BYTE(vk)] | GET_KS_DOWN_BIT(vk)) : \
|
||||
((ks)[GET_KS_BYTE(vk)] & ~GET_KS_DOWN_BIT(vk)))
|
||||
#define SET_KEY_LOCKED(ks, vk, down) (ks)[GET_KS_BYTE(vk)] = ((down) ? \
|
||||
((ks)[GET_KS_BYTE(vk)] | GET_KS_LOCK_BIT(vk)) : \
|
||||
((ks)[GET_KS_BYTE(vk)] & ~GET_KS_LOCK_BIT(vk)))
|
||||
|
||||
|
|
|
@ -106,7 +106,8 @@ typedef struct _USER_MESSAGE_QUEUE
|
|||
LPARAM ExtraInfo;
|
||||
|
||||
/* state of each key */
|
||||
UCHAR KeyState[256];
|
||||
BYTE afKeyRecentDown[256 / 8]; // 1 bit per key
|
||||
BYTE afKeyState[256 * 2 / 8]; // 2 bits per key
|
||||
|
||||
/* showing cursor counter (value>=0 - cursor visible, value<0 - cursor hidden) */
|
||||
INT ShowingCursor;
|
||||
|
@ -220,7 +221,6 @@ co_MsqSendMessageAsync(PTHREADINFO ptiReceiver,
|
|||
|
||||
LRESULT FASTCALL IntDispatchMessage(MSG* Msg);
|
||||
BOOL FASTCALL IntTranslateKbdMessage(LPMSG lpMsg, UINT flags);
|
||||
VOID FASTCALL co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bInjected);
|
||||
VOID FASTCALL MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||
VOID FASTCALL co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook);
|
||||
BOOL FASTCALL MsqIsClkLck(LPMSG Msg, BOOL Remove);
|
||||
|
|
|
@ -42,34 +42,31 @@ CleanupHotKeys(VOID)
|
|||
}
|
||||
#endif
|
||||
|
||||
BOOL FASTCALL
|
||||
GetHotKey (UINT fsModifiers,
|
||||
UINT vk,
|
||||
struct _ETHREAD **Thread,
|
||||
HWND *hWnd,
|
||||
int *id)
|
||||
/*
|
||||
* IntGetModifiers
|
||||
*
|
||||
* Returns a value that indicates if the key is a modifier key, and
|
||||
* which one.
|
||||
*/
|
||||
static
|
||||
UINT FASTCALL
|
||||
IntGetModifiers(PBYTE pKeyState)
|
||||
{
|
||||
PHOT_KEY_ITEM HotKeyItem;
|
||||
UINT fModifiers = 0;
|
||||
|
||||
if (IS_KEY_DOWN(pKeyState, VK_SHIFT))
|
||||
fModifiers |= MOD_SHIFT;
|
||||
|
||||
LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
|
||||
{
|
||||
if (HotKeyItem->fsModifiers == fsModifiers &&
|
||||
HotKeyItem->vk == vk)
|
||||
{
|
||||
if (Thread != NULL)
|
||||
*Thread = HotKeyItem->Thread;
|
||||
if (IS_KEY_DOWN(pKeyState, VK_CONTROL))
|
||||
fModifiers |= MOD_CONTROL;
|
||||
|
||||
if (hWnd != NULL)
|
||||
*hWnd = HotKeyItem->hWnd;
|
||||
if (IS_KEY_DOWN(pKeyState, VK_MENU))
|
||||
fModifiers |= MOD_ALT;
|
||||
|
||||
if (id != NULL)
|
||||
*id = HotKeyItem->id;
|
||||
if (IS_KEY_DOWN(pKeyState, VK_LWIN) || IS_KEY_DOWN(pKeyState, VK_RWIN))
|
||||
fModifiers |= MOD_WIN;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return fModifiers;
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
|
@ -85,7 +82,6 @@ UnregisterWindowHotKeys(PWND Window)
|
|||
ExFreePool (HotKeyItem);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
|
@ -104,23 +100,79 @@ UnregisterThreadHotKeys(struct _ETHREAD *Thread)
|
|||
|
||||
}
|
||||
|
||||
static
|
||||
BOOL FASTCALL
|
||||
IsHotKey (UINT fsModifiers, UINT vk)
|
||||
PHOT_KEY_ITEM FASTCALL
|
||||
IsHotKey(UINT fsModifiers, WORD wVk)
|
||||
{
|
||||
PHOT_KEY_ITEM HotKeyItem;
|
||||
PHOT_KEY_ITEM pHotKeyItem;
|
||||
|
||||
LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
|
||||
LIST_FOR_EACH(pHotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
|
||||
{
|
||||
if (HotKeyItem->fsModifiers == fsModifiers && HotKeyItem->vk == vk)
|
||||
if (pHotKeyItem->fsModifiers == fsModifiers && pHotKeyItem->vk == wVk)
|
||||
{
|
||||
return TRUE;
|
||||
return pHotKeyItem;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* IntKeyboardSendWinKeyMsg
|
||||
*
|
||||
* Sends syscommand to shell, when WIN key is pressed
|
||||
*/
|
||||
static
|
||||
VOID NTAPI
|
||||
IntKeyboardSendWinKeyMsg()
|
||||
{
|
||||
PWND pWnd;
|
||||
MSG Msg;
|
||||
|
||||
if (!(pWnd = UserGetWindowObject(InputWindowStation->ShellWindow)))
|
||||
{
|
||||
ERR("Couldn't find window to send Windows key message!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Msg.hwnd = InputWindowStation->ShellWindow;
|
||||
Msg.message = WM_SYSCOMMAND;
|
||||
Msg.wParam = SC_TASKLIST;
|
||||
Msg.lParam = 0;
|
||||
|
||||
/* The QS_HOTKEY is just a guess */
|
||||
MsqPostMessage(pWnd->head.pti->MessageQueue, &Msg, FALSE, QS_HOTKEY);
|
||||
}
|
||||
|
||||
BOOL NTAPI
|
||||
xxxDoHotKeyStuff(WORD wVk, BOOL bIsDown)
|
||||
{
|
||||
UINT fModifiers;
|
||||
PHOT_KEY_ITEM pHotKey;
|
||||
|
||||
/* Check if it is a hotkey */
|
||||
fModifiers = IntGetModifiers(gafAsyncKeyState);
|
||||
pHotKey = IsHotKey(fModifiers, wVk);
|
||||
if (pHotKey)
|
||||
{
|
||||
if (bIsDown)
|
||||
{
|
||||
TRACE("Hot key pressed (hWnd %lx, id %d)\n", pHotKey->hWnd, pHotKey->id);
|
||||
MsqPostHotKeyMessage(pHotKey->Thread,
|
||||
pHotKey->hWnd,
|
||||
(WPARAM)pHotKey->id,
|
||||
MAKELPARAM((WORD)fModifiers, wVk));
|
||||
}
|
||||
|
||||
return TRUE; /* Don't send any message */
|
||||
}
|
||||
|
||||
if ((wVk == VK_LWIN || wVk == VK_RWIN) && fModifiers == 0)
|
||||
IntKeyboardSendWinKeyMsg();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Get/SetHotKey message support.
|
||||
//
|
||||
|
@ -258,12 +310,12 @@ NtUserRegisterHotKey(HWND hWnd,
|
|||
}
|
||||
|
||||
/* Check for existing hotkey */
|
||||
if (IsHotKey (fsModifiers, vk))
|
||||
if (IsHotKey(fsModifiers, vk))
|
||||
{
|
||||
RETURN( FALSE);
|
||||
}
|
||||
|
||||
HotKeyItem = ExAllocatePoolWithTag (PagedPool, sizeof(HOT_KEY_ITEM), USERTAG_HOTKEY);
|
||||
HotKeyItem = ExAllocatePoolWithTag(PagedPool, sizeof(HOT_KEY_ITEM), USERTAG_HOTKEY);
|
||||
if (HotKeyItem == NULL)
|
||||
{
|
||||
RETURN( FALSE);
|
||||
|
|
|
@ -683,12 +683,12 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
|||
Msg.lParam = MAKELPARAM(MousePos.x, MousePos.y);
|
||||
Msg.pt = MousePos;
|
||||
|
||||
if (gafAsyncKeyState[VK_SHIFT] & KS_DOWN_BIT)
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_SHIFT))
|
||||
{
|
||||
Msg.wParam |= MK_SHIFT;
|
||||
}
|
||||
|
||||
if (gafAsyncKeyState[VK_CONTROL] & KS_DOWN_BIT)
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL))
|
||||
{
|
||||
Msg.wParam |= MK_CONTROL;
|
||||
}
|
||||
|
@ -699,7 +699,7 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
|||
}
|
||||
if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
|
||||
{
|
||||
gafAsyncKeyState[VK_LBUTTON] |= KS_DOWN_BIT;
|
||||
SET_KEY_DOWN(gafAsyncKeyState, VK_LBUTTON, TRUE);
|
||||
Msg.message = SwapBtnMsg[0][SwapButtons];
|
||||
CurInfo->ButtonsDown |= SwapBtn[SwapButtons];
|
||||
Msg.wParam |= CurInfo->ButtonsDown;
|
||||
|
@ -707,7 +707,7 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
|||
}
|
||||
else if(mi->dwFlags & MOUSEEVENTF_LEFTUP)
|
||||
{
|
||||
gafAsyncKeyState[VK_LBUTTON] &= ~KS_DOWN_BIT;
|
||||
SET_KEY_DOWN(gafAsyncKeyState, VK_LBUTTON, FALSE);
|
||||
Msg.message = SwapBtnMsg[1][SwapButtons];
|
||||
CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons];
|
||||
Msg.wParam |= CurInfo->ButtonsDown;
|
||||
|
@ -715,7 +715,7 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
|||
}
|
||||
if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
|
||||
{
|
||||
gafAsyncKeyState[VK_MBUTTON] |= KS_DOWN_BIT;
|
||||
SET_KEY_DOWN(gafAsyncKeyState, VK_MBUTTON, TRUE);
|
||||
Msg.message = WM_MBUTTONDOWN;
|
||||
CurInfo->ButtonsDown |= MK_MBUTTON;
|
||||
Msg.wParam |= CurInfo->ButtonsDown;
|
||||
|
@ -723,7 +723,7 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
|||
}
|
||||
else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
|
||||
{
|
||||
gafAsyncKeyState[VK_MBUTTON] &= ~KS_DOWN_BIT;
|
||||
SET_KEY_DOWN(gafAsyncKeyState, VK_MBUTTON, FALSE);
|
||||
Msg.message = WM_MBUTTONUP;
|
||||
CurInfo->ButtonsDown &= ~MK_MBUTTON;
|
||||
Msg.wParam |= CurInfo->ButtonsDown;
|
||||
|
@ -731,7 +731,7 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
|||
}
|
||||
if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
|
||||
{
|
||||
gafAsyncKeyState[VK_RBUTTON] |= KS_DOWN_BIT;
|
||||
SET_KEY_DOWN(gafAsyncKeyState, VK_RBUTTON, TRUE);
|
||||
Msg.message = SwapBtnMsg[0][!SwapButtons];
|
||||
CurInfo->ButtonsDown |= SwapBtn[!SwapButtons];
|
||||
Msg.wParam |= CurInfo->ButtonsDown;
|
||||
|
@ -739,7 +739,7 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
|||
}
|
||||
else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP)
|
||||
{
|
||||
gafAsyncKeyState[VK_RBUTTON] &= ~KS_DOWN_BIT;
|
||||
SET_KEY_DOWN(gafAsyncKeyState, VK_RBUTTON, FALSE);
|
||||
Msg.message = SwapBtnMsg[1][!SwapButtons];
|
||||
CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons];
|
||||
Msg.wParam |= CurInfo->ButtonsDown;
|
||||
|
@ -758,14 +758,14 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
|||
Msg.message = WM_XBUTTONDOWN;
|
||||
if(mi->mouseData & XBUTTON1)
|
||||
{
|
||||
gafAsyncKeyState[VK_XBUTTON1] |= KS_DOWN_BIT;
|
||||
SET_KEY_DOWN(gafAsyncKeyState, VK_XBUTTON1, TRUE);
|
||||
CurInfo->ButtonsDown |= MK_XBUTTON1;
|
||||
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
|
||||
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
|
||||
}
|
||||
if(mi->mouseData & XBUTTON2)
|
||||
{
|
||||
gafAsyncKeyState[VK_XBUTTON2] |= KS_DOWN_BIT;
|
||||
SET_KEY_DOWN(gafAsyncKeyState, VK_XBUTTON2, TRUE);
|
||||
CurInfo->ButtonsDown |= MK_XBUTTON2;
|
||||
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
|
||||
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
|
||||
|
@ -776,14 +776,14 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
|||
Msg.message = WM_XBUTTONUP;
|
||||
if(mi->mouseData & XBUTTON1)
|
||||
{
|
||||
gafAsyncKeyState[VK_XBUTTON1] &= ~KS_DOWN_BIT;
|
||||
SET_KEY_DOWN(gafAsyncKeyState, VK_XBUTTON1, FALSE);
|
||||
CurInfo->ButtonsDown &= ~MK_XBUTTON1;
|
||||
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
|
||||
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
|
||||
}
|
||||
if(mi->mouseData & XBUTTON2)
|
||||
{
|
||||
gafAsyncKeyState[VK_XBUTTON2] &= ~KS_DOWN_BIT;
|
||||
SET_KEY_DOWN(gafAsyncKeyState, VK_XBUTTON2, FALSE);
|
||||
CurInfo->ButtonsDown &= ~MK_XBUTTON2;
|
||||
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
|
||||
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
#include <win32k.h>
|
||||
DBG_DEFAULT_CHANNEL(UserKbd);
|
||||
|
||||
BYTE gafAsyncKeyState[0x100];
|
||||
BYTE gafAsyncKeyState[256 * 2 / 8]; // 2 bits per key
|
||||
BYTE gafAsyncKeyStateRecentDown[256 / 8]; // 1 bit per key
|
||||
static PKEYBOARD_INDICATOR_TRANSLATION gpKeyboardIndicatorTrans = NULL;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
@ -26,6 +27,7 @@ NTAPI
|
|||
InitKeyboardImpl(VOID)
|
||||
{
|
||||
RtlZeroMemory(&gafAsyncKeyState, sizeof(gafAsyncKeyState));
|
||||
RtlZeroMemory(&gafAsyncKeyStateRecentDown, sizeof(gafAsyncKeyStateRecentDown));
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -236,33 +238,6 @@ IntTranslateNumpadKey(WORD wVk)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* IntGetModifiers
|
||||
*
|
||||
* Returns a value that indicates if the key is a modifier key, and
|
||||
* which one.
|
||||
*/
|
||||
static
|
||||
UINT FASTCALL
|
||||
IntGetModifiers(PBYTE pKeyState)
|
||||
{
|
||||
UINT fModifiers = 0;
|
||||
|
||||
if (pKeyState[VK_SHIFT] & KS_DOWN_BIT)
|
||||
fModifiers |= MOD_SHIFT;
|
||||
|
||||
if (pKeyState[VK_CONTROL] & KS_DOWN_BIT)
|
||||
fModifiers |= MOD_CONTROL;
|
||||
|
||||
if (pKeyState[VK_MENU] & KS_DOWN_BIT)
|
||||
fModifiers |= MOD_ALT;
|
||||
|
||||
if ((pKeyState[VK_LWIN] | pKeyState[VK_RWIN]) & KS_DOWN_BIT)
|
||||
fModifiers |= MOD_WIN;
|
||||
|
||||
return fModifiers;
|
||||
}
|
||||
|
||||
/*
|
||||
* IntGetShiftBit
|
||||
*
|
||||
|
@ -295,11 +270,11 @@ IntGetModBits(PKBDTABLES pKbdTbl, PBYTE pKeyState)
|
|||
/* DumpKeyState( KeyState ); */
|
||||
|
||||
for (i = 0; pKbdTbl->pCharModifiers->pVkToBit[i].Vk; i++)
|
||||
if (pKeyState[pKbdTbl->pCharModifiers->pVkToBit[i].Vk] & KS_DOWN_BIT)
|
||||
if (IS_KEY_DOWN(pKeyState, pKbdTbl->pCharModifiers->pVkToBit[i].Vk))
|
||||
dwModBits |= pKbdTbl->pCharModifiers->pVkToBit[i].ModBits;
|
||||
|
||||
/* Handle Alt+Gr */
|
||||
if ((pKbdTbl->fLocaleFlags & KLLF_ALTGR) && (pKeyState[VK_RMENU] & KS_DOWN_BIT))
|
||||
if ((pKbdTbl->fLocaleFlags & KLLF_ALTGR) && IS_KEY_DOWN(pKeyState, VK_RMENU))
|
||||
dwModBits |= IntGetShiftBit(pKbdTbl, VK_CONTROL); /* Don't use KBDCTRL here */
|
||||
|
||||
TRACE("Current Mod Bits: %lx\n", dwModBits);
|
||||
|
@ -329,7 +304,7 @@ IntTranslateChar(WORD wVirtKey,
|
|||
WORD wCaplokAttr;
|
||||
|
||||
dwModBits = pKeyState ? IntGetModBits(pKbdTbl, pKeyState) : 0;
|
||||
bAltGr = pKeyState && (pKbdTbl->fLocaleFlags & KLLF_ALTGR) && (pKeyState[VK_RMENU] & KS_DOWN_BIT);
|
||||
bAltGr = pKeyState && (pKbdTbl->fLocaleFlags & KLLF_ALTGR) && IS_KEY_DOWN(pKeyState, VK_RMENU);
|
||||
wCaplokAttr = bAltGr ? CAPLOKALTGR : CAPLOK;
|
||||
|
||||
TRACE("TryToTranslate: %04x %x\n", wVirtKey, dwModBits);
|
||||
|
@ -353,7 +328,7 @@ IntTranslateChar(WORD wVirtKey,
|
|||
/* If CapsLock is enabled for this key and locked, add SHIFT bit */
|
||||
if ((pVkToVch->Attributes & wCaplokAttr) &&
|
||||
pKeyState &&
|
||||
(pKeyState[VK_CAPITAL] & KS_LOCK_BIT))
|
||||
IS_KEY_LOCKED(pKeyState, VK_CAPITAL))
|
||||
{
|
||||
/* Note: we use special value here instead of getting VK_SHIFT mod bit - it's verified */
|
||||
dwVkModBits ^= KBDSHIFT;
|
||||
|
@ -407,8 +382,8 @@ IntTranslateChar(WORD wVirtKey,
|
|||
/* If nothing has been found in layout, check if this is ASCII control character.
|
||||
Note: we could add it to layout table, but windows does not have it there */
|
||||
if (wVirtKey >= 'A' && wVirtKey <= 'Z' &&
|
||||
(pKeyState[VK_CONTROL] & KS_DOWN_BIT) &&
|
||||
!(pKeyState[VK_MENU] & KS_DOWN_BIT))
|
||||
IS_KEY_DOWN(pKeyState, VK_CONTROL) &&
|
||||
!IS_KEY_DOWN(pKeyState, VK_MENU))
|
||||
{
|
||||
*pwcTranslatedChar = (wVirtKey - 'A') + 1; /* ASCII control character */
|
||||
*pbDead = FALSE;
|
||||
|
@ -606,58 +581,35 @@ IntVkToChar(WORD wVk, PKBDTABLES pKbdTbl)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static
|
||||
VOID
|
||||
DumpKeyState(PBYTE pKeyState)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
DbgPrint("KeyState { ");
|
||||
for (i = 0; i < 0x100; i++)
|
||||
{
|
||||
if (pKeyState[i])
|
||||
DbgPrint("%02x(%02x) ", i, pKeyState[i]);
|
||||
}
|
||||
DbgPrint("};\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IntGetAsyncKeyState
|
||||
* NtUserGetAsyncKeyState
|
||||
*
|
||||
* Gets key state from global table
|
||||
* Gets key state from global bitmap
|
||||
*/
|
||||
static
|
||||
WORD FASTCALL
|
||||
IntGetAsyncKeyState(DWORD dwKey)
|
||||
{
|
||||
WORD dwRet = 0;
|
||||
|
||||
if (dwKey < 0x100)
|
||||
{
|
||||
if (gafAsyncKeyState[dwKey] & KS_DOWN_BIT)
|
||||
dwRet |= 0xFFFF8000; // If down, windows returns 0xFFFF8000.
|
||||
if (gafAsyncKeyState[dwKey] & KS_LOCK_BIT)
|
||||
dwRet |= 0x1;
|
||||
}
|
||||
else
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
return dwRet;
|
||||
}
|
||||
|
||||
SHORT
|
||||
APIENTRY
|
||||
NtUserGetAsyncKeyState(INT Key)
|
||||
{
|
||||
WORD wRet = 0;
|
||||
DECLARE_RETURN(SHORT);
|
||||
|
||||
TRACE("Enter NtUserGetAsyncKeyState\n");
|
||||
UserEnterExclusive();
|
||||
|
||||
RETURN(IntGetAsyncKeyState(Key));
|
||||
if (Key < 0x100)
|
||||
{
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, Key))
|
||||
wRet |= 0x8000; // If down, windows returns 0x8000.
|
||||
if (gafAsyncKeyStateRecentDown[Key / 8] & (1 << (Key % 8)))
|
||||
wRet |= 0x1;
|
||||
gafAsyncKeyStateRecentDown[Key / 8] &= ~(1 << (Key % 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
RETURN(wRet);
|
||||
|
||||
CLEANUP:
|
||||
TRACE("Leave NtUserGetAsyncKeyState, ret=%i\n", _ret_);
|
||||
|
@ -665,33 +617,6 @@ CLEANUP:
|
|||
END_CLEANUP;
|
||||
}
|
||||
|
||||
/*
|
||||
* IntKeyboardSendWinKeyMsg
|
||||
*
|
||||
* Sends syscommand to shell, when WIN key is pressed
|
||||
*/
|
||||
static
|
||||
VOID NTAPI
|
||||
IntKeyboardSendWinKeyMsg()
|
||||
{
|
||||
PWND pWnd;
|
||||
MSG Msg;
|
||||
|
||||
if (!(pWnd = UserGetWindowObject(InputWindowStation->ShellWindow)))
|
||||
{
|
||||
ERR("Couldn't find window to send Windows key message!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Msg.hwnd = InputWindowStation->ShellWindow;
|
||||
Msg.message = WM_SYSCOMMAND;
|
||||
Msg.wParam = SC_TASKLIST;
|
||||
Msg.lParam = 0;
|
||||
|
||||
/* The QS_HOTKEY is just a guess */
|
||||
MsqPostMessage(pWnd->head.pti->MessageQueue, &Msg, FALSE, QS_HOTKEY);
|
||||
}
|
||||
|
||||
/*
|
||||
* co_IntKeyboardSendAltKeyMsg
|
||||
*
|
||||
|
@ -705,6 +630,51 @@ co_IntKeyboardSendAltKeyMsg()
|
|||
//co_MsqPostKeyboardMessage(WM_SYSCOMMAND,SC_KEYMENU,0); // This sends everything into a msg loop!
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* UpdateAsyncKeyState
|
||||
*
|
||||
* Updates gafAsyncKeyState array
|
||||
*/
|
||||
static
|
||||
VOID NTAPI
|
||||
UpdateAsyncKeyState(WORD wVk, BOOL bIsDown)
|
||||
{
|
||||
if (bIsDown)
|
||||
{
|
||||
/* If it's first key down event, xor lock bit */
|
||||
if (!IS_KEY_DOWN(gafAsyncKeyState, wVk))
|
||||
SET_KEY_LOCKED(gafAsyncKeyState, wVk, !IS_KEY_LOCKED(gafAsyncKeyState, wVk));
|
||||
|
||||
SET_KEY_DOWN(gafAsyncKeyState, wVk, TRUE);
|
||||
gafAsyncKeyStateRecentDown[wVk / 8] |= (1 << (wVk % 8));
|
||||
}
|
||||
else
|
||||
SET_KEY_DOWN(gafAsyncKeyState, wVk, FALSE);
|
||||
}
|
||||
|
||||
LRESULT
|
||||
co_CallLowLevelKeyboardHook(CONST MSG *pMsg, BOOL bInjected, DWORD dwExtraInfo)
|
||||
{
|
||||
KBDLLHOOKSTRUCT KbdHookData;
|
||||
|
||||
KbdHookData.vkCode = pMsg->wParam;
|
||||
KbdHookData.scanCode = HIWORD(pMsg->lParam) & 0xFF;
|
||||
KbdHookData.flags = 0;
|
||||
if (pMsg->lParam & LP_EXT_BIT)
|
||||
KbdHookData.flags |= LLKHF_EXTENDED;
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU))
|
||||
KbdHookData.flags |= LLKHF_ALTDOWN;
|
||||
if (pMsg->message == WM_KEYUP || pMsg->message == WM_SYSKEYUP)
|
||||
KbdHookData.flags |= LLKHF_UP;
|
||||
if (bInjected)
|
||||
KbdHookData.flags |= LLKHF_INJECTED;
|
||||
KbdHookData.time = pMsg->time;
|
||||
KbdHookData.dwExtraInfo = dwExtraInfo;
|
||||
|
||||
return co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, pMsg->message, (LPARAM) &KbdHookData);
|
||||
}
|
||||
|
||||
/*
|
||||
* UserSendKeyboardInput
|
||||
*
|
||||
|
@ -713,19 +683,16 @@ co_IntKeyboardSendAltKeyMsg()
|
|||
BOOL NTAPI
|
||||
UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
|
||||
{
|
||||
WORD wScanCode, wVk, wSimpleVk, wVkOtherSide, wSysKey;
|
||||
WORD wScanCode, wVk, wSimpleVk = 0, wVkOtherSide, wSysKey;
|
||||
PKBL pKbl = NULL;
|
||||
PKBDTABLES pKbdTbl;
|
||||
PUSER_MESSAGE_QUEUE pFocusQueue;
|
||||
struct _ETHREAD *pFocusThread;
|
||||
UINT fModifiers;
|
||||
BYTE PrevKeyState = 0;
|
||||
HWND hWnd;
|
||||
int HotkeyId;
|
||||
struct _ETHREAD *Thread;
|
||||
LARGE_INTEGER LargeTickCount;
|
||||
BOOL bExt = pKbdInput->dwFlags & KEYEVENTF_EXTENDEDKEY;
|
||||
BOOL bKeyUp = pKbdInput->dwFlags & KEYEVENTF_KEYUP;
|
||||
BOOL bExt = (pKbdInput->dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
|
||||
BOOL bIsDown = (pKbdInput->dwFlags & KEYEVENTF_KEYUP) ? FALSE : TRUE;
|
||||
BOOL bWasDown = FALSE, bPostMsg = TRUE;
|
||||
MSG Msg;
|
||||
|
||||
/* Find the target thread whose locale is in effect */
|
||||
pFocusQueue = IntGetFocusMessageQueue();
|
||||
|
@ -758,13 +725,10 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (bExt)
|
||||
wScanCode |= 0xE000;
|
||||
|
||||
if (pKbdInput->dwFlags & KEYEVENTF_SCANCODE)
|
||||
{
|
||||
/* Don't ignore invalid scan codes */
|
||||
wVk = IntVscToVk(wScanCode, pKbdTbl);
|
||||
wVk = IntVscToVk(wScanCode | (bExt ? 0xE000 : 0), pKbdTbl);
|
||||
if (!wVk) /* use 0xFF if vsc is invalid */
|
||||
wVk = 0xFF;
|
||||
}
|
||||
|
@ -776,29 +740,72 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
|
|||
wVk = IntSimplifyVk(wVk);
|
||||
wVk = IntFixVk(wVk, bExt);
|
||||
}
|
||||
|
||||
/* Get virtual key without shifts (VK_(L|R)* -> VK_*) */
|
||||
wSimpleVk = IntSimplifyVk(wVk);
|
||||
wVkOtherSide = IntGetVkOtherSide(wVk);
|
||||
bWasDown = IS_KEY_DOWN(gafAsyncKeyState, wSimpleVk);
|
||||
|
||||
if (xxxDoHotKeyStuff(wSimpleVk, bIsDown))
|
||||
bPostMsg = FALSE;
|
||||
|
||||
/* Update key without shifts */
|
||||
UpdateAsyncKeyState(wSimpleVk, bIsDown || IS_KEY_DOWN(gafAsyncKeyState, wVkOtherSide));
|
||||
}
|
||||
|
||||
/* If it is F10 or ALT is down and CTRL is up, it's a system key */
|
||||
wSysKey = (pKbdTbl->fLocaleFlags & KLLF_ALTGR) ? VK_LMENU : VK_MENU;
|
||||
if (wVk == VK_F10 ||
|
||||
//uVkNoShift == VK_MENU || // FIXME: If only LALT is pressed WM_SYSKEYUP is generated instead of WM_KEYUP
|
||||
(IS_KEY_DOWN(gafAsyncKeyState, wSysKey) && // FIXME
|
||||
!IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL)))
|
||||
{
|
||||
if (bIsDown)
|
||||
Msg.message = WM_SYSKEYDOWN;
|
||||
else
|
||||
Msg.message = WM_SYSKEYUP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bIsDown)
|
||||
Msg.message = WM_KEYDOWN;
|
||||
else
|
||||
Msg.message = WM_KEYUP;
|
||||
}
|
||||
|
||||
/* Init hwnd and lParam */
|
||||
Msg.hwnd = pFocusQueue->FocusWindow;
|
||||
Msg.lParam = MAKELPARAM(1, wScanCode);
|
||||
|
||||
/* If it is VK_PACKET, high word of wParam is used for wchar */
|
||||
if (!(pKbdInput->dwFlags & KEYEVENTF_UNICODE))
|
||||
{
|
||||
if (bExt)
|
||||
Msg.lParam |= LP_EXT_BIT;
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU))
|
||||
Msg.lParam |= LP_CONTEXT_BIT;
|
||||
if (bWasDown)
|
||||
Msg.lParam |= LP_PREV_STATE_BIT;
|
||||
if (!bIsDown)
|
||||
Msg.lParam |= LP_TRANSITION_BIT;
|
||||
}
|
||||
|
||||
/* Init wParam and cursor position */
|
||||
Msg.wParam = wVk; // Note: it's simplified by msg queue
|
||||
Msg.pt = gpsi->ptCursor;
|
||||
|
||||
/* If time is given, use it */
|
||||
if (pKbdInput->time)
|
||||
Msg.time = pKbdInput->time;
|
||||
else
|
||||
{
|
||||
KeQueryTickCount(&LargeTickCount);
|
||||
Msg.time = MsqCalculateMessageTime(&LargeTickCount);
|
||||
}
|
||||
|
||||
if (!(pKbdInput->dwFlags & KEYEVENTF_UNICODE))
|
||||
{
|
||||
/* Get virtual key without shifts (VK_(L|R)* -> VK_*) */
|
||||
wSimpleVk = IntSimplifyVk(wVk);
|
||||
wVkOtherSide = IntGetVkOtherSide(wVk);
|
||||
PrevKeyState = gafAsyncKeyState[wSimpleVk];
|
||||
|
||||
/* Update global keyboard state. Begin from lock bit */
|
||||
if (!bKeyUp && !(PrevKeyState & KS_DOWN_BIT))
|
||||
gafAsyncKeyState[wVk] ^= KS_LOCK_BIT;
|
||||
|
||||
/* Update down bit */
|
||||
if (bKeyUp)
|
||||
gafAsyncKeyState[wVk] &= ~KS_DOWN_BIT;
|
||||
else
|
||||
gafAsyncKeyState[wVk] |= KS_DOWN_BIT;
|
||||
|
||||
/* Update key without shifts */
|
||||
gafAsyncKeyState[wSimpleVk] = gafAsyncKeyState[wVk] | gafAsyncKeyState[wVkOtherSide];
|
||||
|
||||
if (!bKeyUp)
|
||||
if (bIsDown)
|
||||
{
|
||||
/* Update keyboard LEDs */
|
||||
if (!gpKeyboardIndicatorTrans)
|
||||
|
@ -806,91 +813,34 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
|
|||
if (gpKeyboardIndicatorTrans)
|
||||
IntKeyboardUpdateLeds(ghKeyboardDevice,
|
||||
wScanCode,
|
||||
gafAsyncKeyState[wSimpleVk] & KS_LOCK_BIT,
|
||||
IS_KEY_LOCKED(gafAsyncKeyState, wVk),
|
||||
gpKeyboardIndicatorTrans);
|
||||
}
|
||||
|
||||
/* Truncate scan code */
|
||||
wScanCode &= 0x7F;
|
||||
|
||||
/* Support VK_*WIN and VK_*MENU keys */
|
||||
if (bKeyUp)
|
||||
/* Call hook */
|
||||
if (CallLowLevelKeyboardHook(&Msg, bInjected, pKbdInput->dwExtraInfo))
|
||||
{
|
||||
if (wVk == VK_LWIN || wVk == VK_RWIN)
|
||||
IntKeyboardSendWinKeyMsg();
|
||||
else if(wSimpleVk == VK_MENU && !(gafAsyncKeyState[VK_CONTROL] & KS_DOWN_BIT))
|
||||
co_IntKeyboardSendAltKeyMsg();
|
||||
ERR("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
|
||||
Msg.message, Msg.wParam, Msg.lParam);
|
||||
bPostMsg = FALSE;
|
||||
}
|
||||
|
||||
/* Check if it is a hotkey */
|
||||
fModifiers = IntGetModifiers(gafAsyncKeyState);
|
||||
if (GetHotKey(fModifiers, wSimpleVk, &Thread, &hWnd, &HotkeyId))
|
||||
{
|
||||
if (!bKeyUp)
|
||||
{
|
||||
TRACE("Hot key pressed (hWnd %lx, id %d)\n", hWnd, HotkeyId);
|
||||
MsqPostHotKeyMessage(Thread,
|
||||
hWnd,
|
||||
(WPARAM)HotkeyId,
|
||||
MAKELPARAM((WORD)fModifiers, wSimpleVk));
|
||||
}
|
||||
/* Update async state of not simplified vk here.
|
||||
See user32_apitest:GetKeyState */
|
||||
UpdateAsyncKeyState(wVk, bIsDown);
|
||||
|
||||
return TRUE; /* Don't send any message */
|
||||
}
|
||||
/* Support VK_*MENU keys */
|
||||
if (!bIsDown && wSimpleVk == VK_MENU && !IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL))
|
||||
co_IntKeyboardSendAltKeyMsg();
|
||||
}
|
||||
|
||||
/* If we have a focus queue, post a keyboard message */
|
||||
if (pFocusQueue)
|
||||
if (pFocusQueue && bPostMsg)
|
||||
{
|
||||
MSG Msg;
|
||||
|
||||
/* If it is F10 or ALT is down and CTRL is up, it's a system key */
|
||||
wSysKey = (pKbdTbl->fLocaleFlags & KLLF_ALTGR) ? VK_LMENU : VK_MENU;
|
||||
if (wVk == VK_F10 ||
|
||||
//uVkNoShift == VK_MENU || // FIXME: If only LALT is pressed WM_SYSKEYUP is generated instead of WM_KEYUP
|
||||
((gafAsyncKeyState[wSysKey] & KS_DOWN_BIT) && // FIXME
|
||||
!(gafAsyncKeyState[VK_CONTROL] & KS_DOWN_BIT)))
|
||||
{
|
||||
if (bKeyUp)
|
||||
Msg.message = WM_SYSKEYUP;
|
||||
else
|
||||
Msg.message = WM_SYSKEYDOWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bKeyUp)
|
||||
Msg.message = WM_KEYUP;
|
||||
else
|
||||
Msg.message = WM_KEYDOWN;
|
||||
}
|
||||
Msg.hwnd = pFocusQueue->FocusWindow;
|
||||
Msg.lParam = MAKELPARAM(1, wScanCode);
|
||||
/* If it is VK_PACKET, high word of wParam is used for wchar */
|
||||
if (!(pKbdInput->dwFlags & KEYEVENTF_UNICODE))
|
||||
{
|
||||
if (bExt)
|
||||
Msg.lParam |= LP_EXT_BIT;
|
||||
if (gafAsyncKeyState[VK_MENU] & KS_DOWN_BIT)
|
||||
Msg.lParam |= LP_CONTEXT_BIT;
|
||||
if (PrevKeyState & KS_DOWN_BIT)
|
||||
Msg.lParam |= LP_PREV_STATE_BIT;
|
||||
if (bKeyUp)
|
||||
Msg.lParam |= LP_TRANSITION_BIT;
|
||||
}
|
||||
|
||||
Msg.wParam = wVk; // its "simplified" later
|
||||
Msg.pt = gpsi->ptCursor;
|
||||
if (pKbdInput->time)
|
||||
Msg.time = pKbdInput->time;
|
||||
else
|
||||
{
|
||||
KeQueryTickCount(&LargeTickCount);
|
||||
Msg.time = MsqCalculateMessageTime(&LargeTickCount);
|
||||
}
|
||||
|
||||
/* Post a keyboard message */
|
||||
TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
|
||||
co_MsqPostKeyboardMessage(Msg.message, Msg.wParam, Msg.lParam, bInjected);
|
||||
//co_MsqPostKeyboardMessage(Msg.message, Msg.wParam, Msg.lParam, bInjected);
|
||||
MsqPostMessage(pFocusQueue, &Msg, TRUE, QS_KEY);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -947,7 +897,7 @@ UserProcessKeyboardInput(
|
|||
KEYBDINPUT KbdInput;
|
||||
|
||||
/* Support numlock */
|
||||
if ((wVk & KBDNUMPAD) && (gafAsyncKeyState[VK_NUMLOCK] & KS_LOCK_BIT))
|
||||
if ((wVk & KBDNUMPAD) && IS_KEY_LOCKED(gafAsyncKeyState, VK_NUMLOCK))
|
||||
{
|
||||
wVk = IntTranslateNumpadKey(wVk & 0xFF);
|
||||
}
|
||||
|
@ -1028,7 +978,7 @@ IntTranslateKbdMessage(LPMSG lpMsg,
|
|||
|
||||
cch = IntToUnicodeEx(lpMsg->wParam,
|
||||
HIWORD(lpMsg->lParam) & 0xFF,
|
||||
pti->MessageQueue->KeyState,
|
||||
pti->MessageQueue->afKeyState,
|
||||
wch,
|
||||
sizeof(wch) / sizeof(wch[0]),
|
||||
0,
|
||||
|
@ -1182,31 +1132,49 @@ NtUserToUnicodeEx(
|
|||
UINT wScanCode,
|
||||
PBYTE pKeyStateUnsafe,
|
||||
LPWSTR pwszBuffUnsafe,
|
||||
int cchBuff,
|
||||
INT cchBuff,
|
||||
UINT wFlags,
|
||||
HKL dwhkl)
|
||||
{
|
||||
PTHREADINFO pti;
|
||||
BYTE KeyState[0x100];
|
||||
BYTE afKeyState[256 * 2 / 8] = {0};
|
||||
PWCHAR pwszBuff = NULL;
|
||||
int iRet = 0;
|
||||
INT i, iRet = 0;
|
||||
PKBL pKbl = NULL;
|
||||
DECLARE_RETURN(int);
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
DECLARE_RETURN(INT);
|
||||
|
||||
TRACE("Enter NtUserSetKeyboardState\n");
|
||||
UserEnterShared();
|
||||
|
||||
/* Key up? */
|
||||
/* Return 0 if SC_KEY_UP bit is set */
|
||||
if (wScanCode & SC_KEY_UP)
|
||||
{
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(MmCopyFromCaller(KeyState,
|
||||
pKeyStateUnsafe,
|
||||
sizeof(KeyState))))
|
||||
_SEH2_TRY
|
||||
{
|
||||
ERR("Couldn't copy key state from caller.\n");
|
||||
/* Probe and copy key state to smaller bitmap */
|
||||
ProbeForRead(pKeyStateUnsafe, 256 * sizeof(BYTE), 1);
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
if (pKeyStateUnsafe[i] & KS_DOWN_BIT)
|
||||
SET_KEY_DOWN(afKeyState, i, TRUE);
|
||||
if (pKeyStateUnsafe[i] & KS_LOCK_BIT)
|
||||
SET_KEY_LOCKED(afKeyState, i, TRUE);
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("Cannot copy key state\n");
|
||||
SetLastNtError(Status);
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -1232,7 +1200,7 @@ NtUserToUnicodeEx(
|
|||
|
||||
iRet = IntToUnicodeEx(wVirtKey,
|
||||
wScanCode,
|
||||
KeyState,
|
||||
afKeyState,
|
||||
pwszBuff,
|
||||
cchBuff,
|
||||
wFlags,
|
||||
|
@ -1447,24 +1415,24 @@ Exit:
|
|||
WORD FASTCALL
|
||||
UserGetMouseButtonsState(VOID)
|
||||
{
|
||||
WORD ret = 0;
|
||||
WORD wRet = 0;
|
||||
|
||||
if (gpsi->aiSysMet[SM_SWAPBUTTON])
|
||||
{
|
||||
if (gafAsyncKeyState[VK_RBUTTON] & KS_DOWN_BIT) ret |= MK_LBUTTON;
|
||||
if (gafAsyncKeyState[VK_LBUTTON] & KS_DOWN_BIT) ret |= MK_RBUTTON;
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_RBUTTON)) wRet |= MK_LBUTTON;
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_LBUTTON)) wRet |= MK_RBUTTON;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gafAsyncKeyState[VK_LBUTTON] & KS_DOWN_BIT) ret |= MK_LBUTTON;
|
||||
if (gafAsyncKeyState[VK_RBUTTON] & KS_DOWN_BIT) ret |= MK_RBUTTON;
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_LBUTTON)) wRet |= MK_LBUTTON;
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_RBUTTON)) wRet |= MK_RBUTTON;
|
||||
}
|
||||
if (gafAsyncKeyState[VK_MBUTTON] & KS_DOWN_BIT) ret |= MK_MBUTTON;
|
||||
if (gafAsyncKeyState[VK_SHIFT] & KS_DOWN_BIT) ret |= MK_SHIFT;
|
||||
if (gafAsyncKeyState[VK_CONTROL] & KS_DOWN_BIT) ret |= MK_CONTROL;
|
||||
if (gafAsyncKeyState[VK_XBUTTON1] & KS_DOWN_BIT) ret |= MK_XBUTTON1;
|
||||
if (gafAsyncKeyState[VK_XBUTTON2] & KS_DOWN_BIT) ret |= MK_XBUTTON2;
|
||||
return ret;
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_MBUTTON)) wRet |= MK_MBUTTON;
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_SHIFT)) wRet |= MK_SHIFT;
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL)) wRet |= MK_CONTROL;
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_XBUTTON1)) wRet |= MK_XBUTTON1;
|
||||
if (IS_KEY_DOWN(gafAsyncKeyState, VK_XBUTTON2)) wRet |= MK_XBUTTON2;
|
||||
return wRet;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -212,56 +212,57 @@ int UserShowCursor(BOOL bShow)
|
|||
return MessageQueue->ShowingCursor;
|
||||
}
|
||||
|
||||
DWORD FASTCALL UserGetKeyState(DWORD key)
|
||||
DWORD FASTCALL
|
||||
UserGetKeyState(DWORD dwKey)
|
||||
{
|
||||
DWORD ret = 0;
|
||||
DWORD dwRet = 0;
|
||||
PTHREADINFO pti;
|
||||
PUSER_MESSAGE_QUEUE MessageQueue;
|
||||
|
||||
pti = PsGetCurrentThreadWin32Thread();
|
||||
MessageQueue = pti->MessageQueue;
|
||||
|
||||
if (key < 0x100)
|
||||
if (dwKey < 0x100)
|
||||
{
|
||||
ret = (DWORD)MessageQueue->KeyState[key];
|
||||
if (MessageQueue->KeyState[key] & KS_DOWN_BIT)
|
||||
ret |= 0xFF80; // If down, windows returns 0xFF80.
|
||||
if (MessageQueue->KeyState[key] & KS_LOCK_BIT)
|
||||
ret |= 0x1;
|
||||
if (IS_KEY_DOWN(MessageQueue->afKeyState, dwKey))
|
||||
dwRet |= 0xFF80; // If down, windows returns 0xFF80.
|
||||
if (IS_KEY_LOCKED(MessageQueue->afKeyState, dwKey))
|
||||
dwRet |= 0x1;
|
||||
}
|
||||
else
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
return ret;
|
||||
return dwRet;
|
||||
}
|
||||
|
||||
/* change the input key state for a given key */
|
||||
static void set_input_key_state( PUSER_MESSAGE_QUEUE MessageQueue, UCHAR key, BOOL down )
|
||||
static VOID
|
||||
UpdateKeyState(PUSER_MESSAGE_QUEUE MessageQueue, WORD wVk, BOOL bIsDown)
|
||||
{
|
||||
TRACE("set_input_key_state key:%d, down:%d\n", key, down);
|
||||
TRACE("UpdateKeyState wVk: %d, bIsDown: %d\n", wVk, bIsDown);
|
||||
|
||||
if (down)
|
||||
if (bIsDown)
|
||||
{
|
||||
if (!(MessageQueue->KeyState[key] & KS_DOWN_BIT))
|
||||
{
|
||||
MessageQueue->KeyState[key] ^= KS_LOCK_BIT;
|
||||
}
|
||||
MessageQueue->KeyState[key] |= KS_DOWN_BIT;
|
||||
/* If it's first key down event, xor lock bit */
|
||||
if (!IS_KEY_DOWN(MessageQueue->afKeyState, wVk))
|
||||
SET_KEY_LOCKED(MessageQueue->afKeyState, wVk, !IS_KEY_LOCKED(MessageQueue->afKeyState, wVk));
|
||||
|
||||
SET_KEY_DOWN(MessageQueue->afKeyState, wVk, TRUE);
|
||||
MessageQueue->afKeyRecentDown[wVk / 8] |= (1 << (wVk % 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageQueue->KeyState[key] &= ~KS_DOWN_BIT;
|
||||
}
|
||||
SET_KEY_DOWN(MessageQueue->afKeyState, wVk, FALSE);
|
||||
}
|
||||
|
||||
/* update the input key state for a keyboard message */
|
||||
static void update_input_key_state( PUSER_MESSAGE_QUEUE MessageQueue, MSG* msg )
|
||||
static VOID
|
||||
UpdateKeyStateFromMsg(PUSER_MESSAGE_QUEUE MessageQueue, MSG* msg)
|
||||
{
|
||||
UCHAR key;
|
||||
BOOL down = 0;
|
||||
|
||||
TRACE("update_input_key_state message:%d\n", msg->message);
|
||||
TRACE("UpdateKeyStateFromMsg message:%d\n", msg->message);
|
||||
|
||||
switch (msg->message)
|
||||
{
|
||||
|
@ -269,28 +270,28 @@ static void update_input_key_state( PUSER_MESSAGE_QUEUE MessageQueue, MSG* msg )
|
|||
down = 1;
|
||||
/* fall through */
|
||||
case WM_LBUTTONUP:
|
||||
set_input_key_state( MessageQueue, VK_LBUTTON, down );
|
||||
UpdateKeyState(MessageQueue, VK_LBUTTON, down);
|
||||
break;
|
||||
case WM_MBUTTONDOWN:
|
||||
down = 1;
|
||||
/* fall through */
|
||||
case WM_MBUTTONUP:
|
||||
set_input_key_state( MessageQueue, VK_MBUTTON, down );
|
||||
UpdateKeyState(MessageQueue, VK_MBUTTON, down);
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
down = 1;
|
||||
/* fall through */
|
||||
case WM_RBUTTONUP:
|
||||
set_input_key_state( MessageQueue, VK_RBUTTON, down );
|
||||
UpdateKeyState(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 );
|
||||
UpdateKeyState(MessageQueue, VK_XBUTTON1, down);
|
||||
else if (msg->wParam == XBUTTON2)
|
||||
set_input_key_state( MessageQueue, VK_XBUTTON2, down );
|
||||
UpdateKeyState(MessageQueue, VK_XBUTTON2, down);
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
|
@ -299,23 +300,23 @@ static void update_input_key_state( PUSER_MESSAGE_QUEUE MessageQueue, MSG* msg )
|
|||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
key = (UCHAR)msg->wParam;
|
||||
set_input_key_state( MessageQueue, key, down );
|
||||
UpdateKeyState(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 );
|
||||
down = IS_KEY_DOWN(MessageQueue->afKeyState, VK_LCONTROL) || IS_KEY_DOWN(MessageQueue->afKeyState, VK_RCONTROL);
|
||||
UpdateKeyState(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 );
|
||||
down = IS_KEY_DOWN(MessageQueue->afKeyState, VK_LMENU) || IS_KEY_DOWN(MessageQueue->afKeyState, VK_RMENU);
|
||||
UpdateKeyState(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 );
|
||||
down = IS_KEY_DOWN(MessageQueue->afKeyState, VK_LSHIFT) || IS_KEY_DOWN(MessageQueue->afKeyState, VK_RSHIFT);
|
||||
UpdateKeyState(MessageQueue, VK_SHIFT, down);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -627,84 +628,6 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
|
|||
gcur_count = 0; // 0 - 63 is 64, FIFO forwards.
|
||||
}
|
||||
|
||||
//
|
||||
// Note: Only called from input.c.
|
||||
//
|
||||
VOID FASTCALL
|
||||
co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bInjected)
|
||||
{
|
||||
PUSER_MESSAGE_QUEUE FocusMessageQueue;
|
||||
MSG Msg;
|
||||
LARGE_INTEGER LargeTickCount;
|
||||
KBDLLHOOKSTRUCT KbdHookData;
|
||||
|
||||
TRACE("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n",
|
||||
uMsg, wParam, lParam);
|
||||
|
||||
// Condition may arise when calling MsqPostMessage and waiting for an event.
|
||||
ASSERT(UserIsEntered());
|
||||
|
||||
FocusMessageQueue = IntGetFocusMessageQueue();
|
||||
|
||||
Msg.hwnd = 0;
|
||||
|
||||
if (FocusMessageQueue && (FocusMessageQueue->FocusWindow != (HWND)0))
|
||||
Msg.hwnd = FocusMessageQueue->FocusWindow;
|
||||
|
||||
Msg.message = uMsg;
|
||||
Msg.wParam = wParam;
|
||||
Msg.lParam = lParam;
|
||||
|
||||
KeQueryTickCount(&LargeTickCount);
|
||||
Msg.time = MsqCalculateMessageTime(&LargeTickCount);
|
||||
|
||||
/* We can't get the Msg.pt point here since we don't know thread
|
||||
(and thus the window station) the message will end up in yet. */
|
||||
|
||||
KbdHookData.vkCode = Msg.wParam;
|
||||
KbdHookData.scanCode = (Msg.lParam >> 16) & 0xff;
|
||||
KbdHookData.flags = 0;
|
||||
if (Msg.lParam & 0x01000000)
|
||||
KbdHookData.flags |= LLKHF_EXTENDED;
|
||||
if (Msg.lParam & 0x20000000)
|
||||
KbdHookData.flags |= LLKHF_ALTDOWN;
|
||||
if (Msg.lParam & 0x80000000)
|
||||
KbdHookData.flags |= LLKHF_UP;
|
||||
if (bInjected)
|
||||
KbdHookData.flags |= LLKHF_INJECTED;
|
||||
KbdHookData.time = Msg.time;
|
||||
KbdHookData.dwExtraInfo = 0;
|
||||
if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData))
|
||||
{
|
||||
ERR("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
|
||||
Msg.message, Msg.wParam, Msg.lParam);
|
||||
return;
|
||||
}
|
||||
|
||||
if (FocusMessageQueue == NULL)
|
||||
{
|
||||
TRACE("No focus message queue\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (FocusMessageQueue->FocusWindow != (HWND)0)
|
||||
{
|
||||
Msg.hwnd = FocusMessageQueue->FocusWindow;
|
||||
TRACE("Msg.hwnd = %x\n", Msg.hwnd);
|
||||
|
||||
FocusMessageQueue->Desktop->pDeskInfo->LastInputWasKbd = TRUE;
|
||||
|
||||
Msg.pt = gpsi->ptCursor;
|
||||
MsqPostMessage(FocusMessageQueue, &Msg, TRUE, QS_KEY);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Invalid focus window handle\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
@ -1293,7 +1216,7 @@ MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessa
|
|||
InsertTailList(&MessageQueue->HardwareMessagesListHead,
|
||||
&Message->ListEntry);
|
||||
|
||||
update_input_key_state( MessageQueue, Msg );
|
||||
UpdateKeyStateFromMsg( MessageQueue, Msg );
|
||||
}
|
||||
|
||||
Message->QS_Flags = MessageBits;
|
||||
|
@ -1801,7 +1724,7 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
|||
|
||||
if (Remove)
|
||||
{
|
||||
update_input_key_state(MessageQueue, &msg);
|
||||
UpdateKeyStateFromMsg(MessageQueue, &msg);
|
||||
RemoveEntryList(&CurrentMessage->ListEntry);
|
||||
ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags);
|
||||
MsqDestroyMessage(CurrentMessage);
|
||||
|
@ -1930,7 +1853,7 @@ MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQu
|
|||
MessageQueue->NewMessagesHandle = NULL;
|
||||
MessageQueue->ShowingCursor = 0;
|
||||
MessageQueue->CursorObject = NULL;
|
||||
RtlCopyMemory(MessageQueue->KeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState));
|
||||
RtlCopyMemory(MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState));
|
||||
|
||||
Status = ZwCreateEvent(&MessageQueue->NewMessagesHandle, EVENT_ALL_ACCESS,
|
||||
NULL, SynchronizationEvent, FALSE);
|
||||
|
@ -2281,7 +2204,7 @@ DWORD
|
|||
APIENTRY
|
||||
NtUserGetKeyboardState(LPBYTE lpKeyState)
|
||||
{
|
||||
DWORD ret = TRUE;
|
||||
DWORD i, ret = TRUE;
|
||||
PTHREADINFO pti;
|
||||
PUSER_MESSAGE_QUEUE MessageQueue;
|
||||
|
||||
|
@ -2292,8 +2215,16 @@ NtUserGetKeyboardState(LPBYTE lpKeyState)
|
|||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForWrite(lpKeyState,sizeof(MessageQueue->KeyState) ,1);
|
||||
RtlCopyMemory(lpKeyState,MessageQueue->KeyState,sizeof(MessageQueue->KeyState));
|
||||
/* Probe and copy key state to an array */
|
||||
ProbeForWrite(lpKeyState, 256 * sizeof(BYTE), 1);
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
lpKeyState[i] = 0;
|
||||
if (IS_KEY_DOWN(MessageQueue->afKeyState, i))
|
||||
lpKeyState[i] |= KS_DOWN_BIT;
|
||||
if (IS_KEY_LOCKED(MessageQueue->afKeyState, i))
|
||||
lpKeyState[i] |= KS_LOCK_BIT;
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
@ -2309,9 +2240,10 @@ NtUserGetKeyboardState(LPBYTE lpKeyState)
|
|||
|
||||
BOOL
|
||||
APIENTRY
|
||||
NtUserSetKeyboardState(LPBYTE lpKeyState)
|
||||
NtUserSetKeyboardState(LPBYTE pKeyState)
|
||||
{
|
||||
DWORD ret = TRUE;
|
||||
UINT i;
|
||||
BOOL bRet = TRUE;
|
||||
PTHREADINFO pti;
|
||||
PUSER_MESSAGE_QUEUE MessageQueue;
|
||||
|
||||
|
@ -2322,19 +2254,23 @@ NtUserSetKeyboardState(LPBYTE lpKeyState)
|
|||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(lpKeyState,sizeof(MessageQueue->KeyState) ,1);
|
||||
RtlCopyMemory(MessageQueue->KeyState,lpKeyState,sizeof(MessageQueue->KeyState));
|
||||
ProbeForRead(pKeyState, 256 * sizeof(BYTE), 1);
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
SET_KEY_DOWN(MessageQueue->afKeyState, i, pKeyState[i] & KS_DOWN_BIT);
|
||||
SET_KEY_LOCKED(MessageQueue->afKeyState, i, pKeyState[i] & KS_LOCK_BIT);
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
SetLastNtError(_SEH2_GetExceptionCode());
|
||||
ret = FALSE;
|
||||
bRet = FALSE;
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
UserLeave();
|
||||
|
||||
return ret;
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue