mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +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);
|
INIT_FUNCTION NTSTATUS NTAPI InitHotkeyImpl(VOID);
|
||||||
|
|
||||||
BOOL FASTCALL
|
PHOT_KEY_ITEM FASTCALL IsHotKey(UINT fsModifiers, WORD wVk);
|
||||||
GetHotKey (UINT fsModifiers,
|
|
||||||
UINT vk,
|
|
||||||
struct _ETHREAD **Thread,
|
|
||||||
HWND *hWnd,
|
|
||||||
int *id);
|
|
||||||
|
|
||||||
VOID FASTCALL UnregisterWindowHotKeys(PWND Window);
|
VOID FASTCALL UnregisterWindowHotKeys(PWND Window);
|
||||||
VOID FASTCALL UnregisterThreadHotKeys(struct _ETHREAD *Thread);
|
VOID FASTCALL UnregisterThreadHotKeys(struct _ETHREAD *Thread);
|
||||||
|
BOOL NTAPI xxxDoHotKeyStuff(WORD wVk, BOOL bIsDown);
|
||||||
UINT FASTCALL DefWndGetHotKey(HWND hwnd);
|
UINT FASTCALL DefWndGetHotKey(HWND hwnd);
|
||||||
INT FASTCALL DefWndSetHotKey( PWND pWnd, WPARAM wParam);
|
INT FASTCALL DefWndSetHotKey(PWND pWnd, WPARAM wParam);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -51,9 +51,21 @@ BOOL UserInitDefaultKeyboardLayout(VOID);
|
||||||
PKBL UserHklToKbl(HKL hKl);
|
PKBL UserHklToKbl(HKL hKl);
|
||||||
BOOL FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL);
|
BOOL FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL);
|
||||||
VOID FASTCALL DoTheScreenSaver(VOID);
|
VOID FASTCALL DoTheScreenSaver(VOID);
|
||||||
#define ThreadHasInputAccess(W32Thread) \
|
#define ThreadHasInputAccess(W32Thread) (TRUE)
|
||||||
(TRUE)
|
|
||||||
|
|
||||||
extern HANDLE ghKeyboardDevice;
|
extern HANDLE ghKeyboardDevice;
|
||||||
extern PTHREADINFO ptiRawInput;
|
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;
|
LPARAM ExtraInfo;
|
||||||
|
|
||||||
/* state of each key */
|
/* 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) */
|
/* showing cursor counter (value>=0 - cursor visible, value<0 - cursor hidden) */
|
||||||
INT ShowingCursor;
|
INT ShowingCursor;
|
||||||
|
@ -220,7 +221,6 @@ co_MsqSendMessageAsync(PTHREADINFO ptiReceiver,
|
||||||
|
|
||||||
LRESULT FASTCALL IntDispatchMessage(MSG* Msg);
|
LRESULT FASTCALL IntDispatchMessage(MSG* Msg);
|
||||||
BOOL FASTCALL IntTranslateKbdMessage(LPMSG lpMsg, UINT flags);
|
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 MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||||
VOID FASTCALL co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook);
|
VOID FASTCALL co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook);
|
||||||
BOOL FASTCALL MsqIsClkLck(LPMSG Msg, BOOL Remove);
|
BOOL FASTCALL MsqIsClkLck(LPMSG Msg, BOOL Remove);
|
||||||
|
|
|
@ -42,34 +42,31 @@ CleanupHotKeys(VOID)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BOOL FASTCALL
|
/*
|
||||||
GetHotKey (UINT fsModifiers,
|
* IntGetModifiers
|
||||||
UINT vk,
|
*
|
||||||
struct _ETHREAD **Thread,
|
* Returns a value that indicates if the key is a modifier key, and
|
||||||
HWND *hWnd,
|
* which one.
|
||||||
int *id)
|
*/
|
||||||
|
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 (IS_KEY_DOWN(pKeyState, VK_CONTROL))
|
||||||
{
|
fModifiers |= MOD_CONTROL;
|
||||||
if (HotKeyItem->fsModifiers == fsModifiers &&
|
|
||||||
HotKeyItem->vk == vk)
|
|
||||||
{
|
|
||||||
if (Thread != NULL)
|
|
||||||
*Thread = HotKeyItem->Thread;
|
|
||||||
|
|
||||||
if (hWnd != NULL)
|
if (IS_KEY_DOWN(pKeyState, VK_MENU))
|
||||||
*hWnd = HotKeyItem->hWnd;
|
fModifiers |= MOD_ALT;
|
||||||
|
|
||||||
if (id != NULL)
|
if (IS_KEY_DOWN(pKeyState, VK_LWIN) || IS_KEY_DOWN(pKeyState, VK_RWIN))
|
||||||
*id = HotKeyItem->id;
|
fModifiers |= MOD_WIN;
|
||||||
|
|
||||||
return TRUE;
|
return fModifiers;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
|
@ -85,7 +82,6 @@ UnregisterWindowHotKeys(PWND Window)
|
||||||
ExFreePool (HotKeyItem);
|
ExFreePool (HotKeyItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
|
@ -104,23 +100,79 @@ UnregisterThreadHotKeys(struct _ETHREAD *Thread)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
PHOT_KEY_ITEM FASTCALL
|
||||||
BOOL FASTCALL
|
IsHotKey(UINT fsModifiers, WORD wVk)
|
||||||
IsHotKey (UINT fsModifiers, UINT vk)
|
|
||||||
{
|
{
|
||||||
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.
|
// Get/SetHotKey message support.
|
||||||
//
|
//
|
||||||
|
@ -258,12 +310,12 @@ NtUserRegisterHotKey(HWND hWnd,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for existing hotkey */
|
/* Check for existing hotkey */
|
||||||
if (IsHotKey (fsModifiers, vk))
|
if (IsHotKey(fsModifiers, vk))
|
||||||
{
|
{
|
||||||
RETURN( FALSE);
|
RETURN( FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
HotKeyItem = ExAllocatePoolWithTag (PagedPool, sizeof(HOT_KEY_ITEM), USERTAG_HOTKEY);
|
HotKeyItem = ExAllocatePoolWithTag(PagedPool, sizeof(HOT_KEY_ITEM), USERTAG_HOTKEY);
|
||||||
if (HotKeyItem == NULL)
|
if (HotKeyItem == NULL)
|
||||||
{
|
{
|
||||||
RETURN( FALSE);
|
RETURN( FALSE);
|
||||||
|
|
|
@ -683,12 +683,12 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
||||||
Msg.lParam = MAKELPARAM(MousePos.x, MousePos.y);
|
Msg.lParam = MAKELPARAM(MousePos.x, MousePos.y);
|
||||||
Msg.pt = MousePos;
|
Msg.pt = MousePos;
|
||||||
|
|
||||||
if (gafAsyncKeyState[VK_SHIFT] & KS_DOWN_BIT)
|
if (IS_KEY_DOWN(gafAsyncKeyState, VK_SHIFT))
|
||||||
{
|
{
|
||||||
Msg.wParam |= MK_SHIFT;
|
Msg.wParam |= MK_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gafAsyncKeyState[VK_CONTROL] & KS_DOWN_BIT)
|
if (IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL))
|
||||||
{
|
{
|
||||||
Msg.wParam |= MK_CONTROL;
|
Msg.wParam |= MK_CONTROL;
|
||||||
}
|
}
|
||||||
|
@ -699,7 +699,7 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
||||||
}
|
}
|
||||||
if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
|
if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
|
||||||
{
|
{
|
||||||
gafAsyncKeyState[VK_LBUTTON] |= KS_DOWN_BIT;
|
SET_KEY_DOWN(gafAsyncKeyState, VK_LBUTTON, TRUE);
|
||||||
Msg.message = SwapBtnMsg[0][SwapButtons];
|
Msg.message = SwapBtnMsg[0][SwapButtons];
|
||||||
CurInfo->ButtonsDown |= SwapBtn[SwapButtons];
|
CurInfo->ButtonsDown |= SwapBtn[SwapButtons];
|
||||||
Msg.wParam |= CurInfo->ButtonsDown;
|
Msg.wParam |= CurInfo->ButtonsDown;
|
||||||
|
@ -707,7 +707,7 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
||||||
}
|
}
|
||||||
else if(mi->dwFlags & MOUSEEVENTF_LEFTUP)
|
else if(mi->dwFlags & MOUSEEVENTF_LEFTUP)
|
||||||
{
|
{
|
||||||
gafAsyncKeyState[VK_LBUTTON] &= ~KS_DOWN_BIT;
|
SET_KEY_DOWN(gafAsyncKeyState, VK_LBUTTON, FALSE);
|
||||||
Msg.message = SwapBtnMsg[1][SwapButtons];
|
Msg.message = SwapBtnMsg[1][SwapButtons];
|
||||||
CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons];
|
CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons];
|
||||||
Msg.wParam |= CurInfo->ButtonsDown;
|
Msg.wParam |= CurInfo->ButtonsDown;
|
||||||
|
@ -715,7 +715,7 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
||||||
}
|
}
|
||||||
if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
|
if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
|
||||||
{
|
{
|
||||||
gafAsyncKeyState[VK_MBUTTON] |= KS_DOWN_BIT;
|
SET_KEY_DOWN(gafAsyncKeyState, VK_MBUTTON, TRUE);
|
||||||
Msg.message = WM_MBUTTONDOWN;
|
Msg.message = WM_MBUTTONDOWN;
|
||||||
CurInfo->ButtonsDown |= MK_MBUTTON;
|
CurInfo->ButtonsDown |= MK_MBUTTON;
|
||||||
Msg.wParam |= CurInfo->ButtonsDown;
|
Msg.wParam |= CurInfo->ButtonsDown;
|
||||||
|
@ -723,7 +723,7 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
||||||
}
|
}
|
||||||
else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
|
else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
|
||||||
{
|
{
|
||||||
gafAsyncKeyState[VK_MBUTTON] &= ~KS_DOWN_BIT;
|
SET_KEY_DOWN(gafAsyncKeyState, VK_MBUTTON, FALSE);
|
||||||
Msg.message = WM_MBUTTONUP;
|
Msg.message = WM_MBUTTONUP;
|
||||||
CurInfo->ButtonsDown &= ~MK_MBUTTON;
|
CurInfo->ButtonsDown &= ~MK_MBUTTON;
|
||||||
Msg.wParam |= CurInfo->ButtonsDown;
|
Msg.wParam |= CurInfo->ButtonsDown;
|
||||||
|
@ -731,7 +731,7 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
||||||
}
|
}
|
||||||
if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
|
if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
|
||||||
{
|
{
|
||||||
gafAsyncKeyState[VK_RBUTTON] |= KS_DOWN_BIT;
|
SET_KEY_DOWN(gafAsyncKeyState, VK_RBUTTON, TRUE);
|
||||||
Msg.message = SwapBtnMsg[0][!SwapButtons];
|
Msg.message = SwapBtnMsg[0][!SwapButtons];
|
||||||
CurInfo->ButtonsDown |= SwapBtn[!SwapButtons];
|
CurInfo->ButtonsDown |= SwapBtn[!SwapButtons];
|
||||||
Msg.wParam |= CurInfo->ButtonsDown;
|
Msg.wParam |= CurInfo->ButtonsDown;
|
||||||
|
@ -739,7 +739,7 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
||||||
}
|
}
|
||||||
else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP)
|
else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP)
|
||||||
{
|
{
|
||||||
gafAsyncKeyState[VK_RBUTTON] &= ~KS_DOWN_BIT;
|
SET_KEY_DOWN(gafAsyncKeyState, VK_RBUTTON, FALSE);
|
||||||
Msg.message = SwapBtnMsg[1][!SwapButtons];
|
Msg.message = SwapBtnMsg[1][!SwapButtons];
|
||||||
CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons];
|
CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons];
|
||||||
Msg.wParam |= CurInfo->ButtonsDown;
|
Msg.wParam |= CurInfo->ButtonsDown;
|
||||||
|
@ -758,14 +758,14 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
||||||
Msg.message = WM_XBUTTONDOWN;
|
Msg.message = WM_XBUTTONDOWN;
|
||||||
if(mi->mouseData & XBUTTON1)
|
if(mi->mouseData & XBUTTON1)
|
||||||
{
|
{
|
||||||
gafAsyncKeyState[VK_XBUTTON1] |= KS_DOWN_BIT;
|
SET_KEY_DOWN(gafAsyncKeyState, VK_XBUTTON1, TRUE);
|
||||||
CurInfo->ButtonsDown |= MK_XBUTTON1;
|
CurInfo->ButtonsDown |= MK_XBUTTON1;
|
||||||
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
|
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
|
||||||
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
|
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
|
||||||
}
|
}
|
||||||
if(mi->mouseData & XBUTTON2)
|
if(mi->mouseData & XBUTTON2)
|
||||||
{
|
{
|
||||||
gafAsyncKeyState[VK_XBUTTON2] |= KS_DOWN_BIT;
|
SET_KEY_DOWN(gafAsyncKeyState, VK_XBUTTON2, TRUE);
|
||||||
CurInfo->ButtonsDown |= MK_XBUTTON2;
|
CurInfo->ButtonsDown |= MK_XBUTTON2;
|
||||||
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
|
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
|
||||||
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
|
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
|
||||||
|
@ -776,14 +776,14 @@ IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
|
||||||
Msg.message = WM_XBUTTONUP;
|
Msg.message = WM_XBUTTONUP;
|
||||||
if(mi->mouseData & XBUTTON1)
|
if(mi->mouseData & XBUTTON1)
|
||||||
{
|
{
|
||||||
gafAsyncKeyState[VK_XBUTTON1] &= ~KS_DOWN_BIT;
|
SET_KEY_DOWN(gafAsyncKeyState, VK_XBUTTON1, FALSE);
|
||||||
CurInfo->ButtonsDown &= ~MK_XBUTTON1;
|
CurInfo->ButtonsDown &= ~MK_XBUTTON1;
|
||||||
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
|
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
|
||||||
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
|
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
|
||||||
}
|
}
|
||||||
if(mi->mouseData & XBUTTON2)
|
if(mi->mouseData & XBUTTON2)
|
||||||
{
|
{
|
||||||
gafAsyncKeyState[VK_XBUTTON2] &= ~KS_DOWN_BIT;
|
SET_KEY_DOWN(gafAsyncKeyState, VK_XBUTTON2, FALSE);
|
||||||
CurInfo->ButtonsDown &= ~MK_XBUTTON2;
|
CurInfo->ButtonsDown &= ~MK_XBUTTON2;
|
||||||
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
|
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
|
||||||
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
|
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
#include <win32k.h>
|
#include <win32k.h>
|
||||||
DBG_DEFAULT_CHANNEL(UserKbd);
|
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;
|
static PKEYBOARD_INDICATOR_TRANSLATION gpKeyboardIndicatorTrans = NULL;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
@ -26,6 +27,7 @@ NTAPI
|
||||||
InitKeyboardImpl(VOID)
|
InitKeyboardImpl(VOID)
|
||||||
{
|
{
|
||||||
RtlZeroMemory(&gafAsyncKeyState, sizeof(gafAsyncKeyState));
|
RtlZeroMemory(&gafAsyncKeyState, sizeof(gafAsyncKeyState));
|
||||||
|
RtlZeroMemory(&gafAsyncKeyStateRecentDown, sizeof(gafAsyncKeyStateRecentDown));
|
||||||
return STATUS_SUCCESS;
|
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
|
* IntGetShiftBit
|
||||||
*
|
*
|
||||||
|
@ -295,11 +270,11 @@ IntGetModBits(PKBDTABLES pKbdTbl, PBYTE pKeyState)
|
||||||
/* DumpKeyState( KeyState ); */
|
/* DumpKeyState( KeyState ); */
|
||||||
|
|
||||||
for (i = 0; pKbdTbl->pCharModifiers->pVkToBit[i].Vk; i++)
|
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;
|
dwModBits |= pKbdTbl->pCharModifiers->pVkToBit[i].ModBits;
|
||||||
|
|
||||||
/* Handle Alt+Gr */
|
/* 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 */
|
dwModBits |= IntGetShiftBit(pKbdTbl, VK_CONTROL); /* Don't use KBDCTRL here */
|
||||||
|
|
||||||
TRACE("Current Mod Bits: %lx\n", dwModBits);
|
TRACE("Current Mod Bits: %lx\n", dwModBits);
|
||||||
|
@ -329,7 +304,7 @@ IntTranslateChar(WORD wVirtKey,
|
||||||
WORD wCaplokAttr;
|
WORD wCaplokAttr;
|
||||||
|
|
||||||
dwModBits = pKeyState ? IntGetModBits(pKbdTbl, pKeyState) : 0;
|
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;
|
wCaplokAttr = bAltGr ? CAPLOKALTGR : CAPLOK;
|
||||||
|
|
||||||
TRACE("TryToTranslate: %04x %x\n", wVirtKey, dwModBits);
|
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 CapsLock is enabled for this key and locked, add SHIFT bit */
|
||||||
if ((pVkToVch->Attributes & wCaplokAttr) &&
|
if ((pVkToVch->Attributes & wCaplokAttr) &&
|
||||||
pKeyState &&
|
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 */
|
/* Note: we use special value here instead of getting VK_SHIFT mod bit - it's verified */
|
||||||
dwVkModBits ^= KBDSHIFT;
|
dwVkModBits ^= KBDSHIFT;
|
||||||
|
@ -407,8 +382,8 @@ IntTranslateChar(WORD wVirtKey,
|
||||||
/* If nothing has been found in layout, check if this is ASCII control character.
|
/* 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 */
|
Note: we could add it to layout table, but windows does not have it there */
|
||||||
if (wVirtKey >= 'A' && wVirtKey <= 'Z' &&
|
if (wVirtKey >= 'A' && wVirtKey <= 'Z' &&
|
||||||
(pKeyState[VK_CONTROL] & KS_DOWN_BIT) &&
|
IS_KEY_DOWN(pKeyState, VK_CONTROL) &&
|
||||||
!(pKeyState[VK_MENU] & KS_DOWN_BIT))
|
!IS_KEY_DOWN(pKeyState, VK_MENU))
|
||||||
{
|
{
|
||||||
*pwcTranslatedChar = (wVirtKey - 'A') + 1; /* ASCII control character */
|
*pwcTranslatedChar = (wVirtKey - 'A') + 1; /* ASCII control character */
|
||||||
*pbDead = FALSE;
|
*pbDead = FALSE;
|
||||||
|
@ -606,58 +581,35 @@ IntVkToChar(WORD wVk, PKBDTABLES pKbdTbl)
|
||||||
return 0;
|
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
|
SHORT
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserGetAsyncKeyState(INT Key)
|
NtUserGetAsyncKeyState(INT Key)
|
||||||
{
|
{
|
||||||
|
WORD wRet = 0;
|
||||||
DECLARE_RETURN(SHORT);
|
DECLARE_RETURN(SHORT);
|
||||||
|
|
||||||
TRACE("Enter NtUserGetAsyncKeyState\n");
|
TRACE("Enter NtUserGetAsyncKeyState\n");
|
||||||
UserEnterExclusive();
|
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:
|
CLEANUP:
|
||||||
TRACE("Leave NtUserGetAsyncKeyState, ret=%i\n", _ret_);
|
TRACE("Leave NtUserGetAsyncKeyState, ret=%i\n", _ret_);
|
||||||
|
@ -665,33 +617,6 @@ CLEANUP:
|
||||||
END_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
|
* co_IntKeyboardSendAltKeyMsg
|
||||||
*
|
*
|
||||||
|
@ -705,6 +630,51 @@ co_IntKeyboardSendAltKeyMsg()
|
||||||
//co_MsqPostKeyboardMessage(WM_SYSCOMMAND,SC_KEYMENU,0); // This sends everything into a msg loop!
|
//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
|
* UserSendKeyboardInput
|
||||||
*
|
*
|
||||||
|
@ -713,19 +683,16 @@ co_IntKeyboardSendAltKeyMsg()
|
||||||
BOOL NTAPI
|
BOOL NTAPI
|
||||||
UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
|
UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
|
||||||
{
|
{
|
||||||
WORD wScanCode, wVk, wSimpleVk, wVkOtherSide, wSysKey;
|
WORD wScanCode, wVk, wSimpleVk = 0, wVkOtherSide, wSysKey;
|
||||||
PKBL pKbl = NULL;
|
PKBL pKbl = NULL;
|
||||||
PKBDTABLES pKbdTbl;
|
PKBDTABLES pKbdTbl;
|
||||||
PUSER_MESSAGE_QUEUE pFocusQueue;
|
PUSER_MESSAGE_QUEUE pFocusQueue;
|
||||||
struct _ETHREAD *pFocusThread;
|
struct _ETHREAD *pFocusThread;
|
||||||
UINT fModifiers;
|
|
||||||
BYTE PrevKeyState = 0;
|
|
||||||
HWND hWnd;
|
|
||||||
int HotkeyId;
|
|
||||||
struct _ETHREAD *Thread;
|
|
||||||
LARGE_INTEGER LargeTickCount;
|
LARGE_INTEGER LargeTickCount;
|
||||||
BOOL bExt = pKbdInput->dwFlags & KEYEVENTF_EXTENDEDKEY;
|
BOOL bExt = (pKbdInput->dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
|
||||||
BOOL bKeyUp = pKbdInput->dwFlags & KEYEVENTF_KEYUP;
|
BOOL bIsDown = (pKbdInput->dwFlags & KEYEVENTF_KEYUP) ? FALSE : TRUE;
|
||||||
|
BOOL bWasDown = FALSE, bPostMsg = TRUE;
|
||||||
|
MSG Msg;
|
||||||
|
|
||||||
/* Find the target thread whose locale is in effect */
|
/* Find the target thread whose locale is in effect */
|
||||||
pFocusQueue = IntGetFocusMessageQueue();
|
pFocusQueue = IntGetFocusMessageQueue();
|
||||||
|
@ -758,13 +725,10 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bExt)
|
|
||||||
wScanCode |= 0xE000;
|
|
||||||
|
|
||||||
if (pKbdInput->dwFlags & KEYEVENTF_SCANCODE)
|
if (pKbdInput->dwFlags & KEYEVENTF_SCANCODE)
|
||||||
{
|
{
|
||||||
/* Don't ignore invalid scan codes */
|
/* 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 */
|
if (!wVk) /* use 0xFF if vsc is invalid */
|
||||||
wVk = 0xFF;
|
wVk = 0xFF;
|
||||||
}
|
}
|
||||||
|
@ -776,29 +740,72 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
|
||||||
wVk = IntSimplifyVk(wVk);
|
wVk = IntSimplifyVk(wVk);
|
||||||
wVk = IntFixVk(wVk, bExt);
|
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))
|
if (!(pKbdInput->dwFlags & KEYEVENTF_UNICODE))
|
||||||
{
|
{
|
||||||
/* Get virtual key without shifts (VK_(L|R)* -> VK_*) */
|
if (bIsDown)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
/* Update keyboard LEDs */
|
/* Update keyboard LEDs */
|
||||||
if (!gpKeyboardIndicatorTrans)
|
if (!gpKeyboardIndicatorTrans)
|
||||||
|
@ -806,91 +813,34 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
|
||||||
if (gpKeyboardIndicatorTrans)
|
if (gpKeyboardIndicatorTrans)
|
||||||
IntKeyboardUpdateLeds(ghKeyboardDevice,
|
IntKeyboardUpdateLeds(ghKeyboardDevice,
|
||||||
wScanCode,
|
wScanCode,
|
||||||
gafAsyncKeyState[wSimpleVk] & KS_LOCK_BIT,
|
IS_KEY_LOCKED(gafAsyncKeyState, wVk),
|
||||||
gpKeyboardIndicatorTrans);
|
gpKeyboardIndicatorTrans);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Truncate scan code */
|
/* Call hook */
|
||||||
wScanCode &= 0x7F;
|
if (CallLowLevelKeyboardHook(&Msg, bInjected, pKbdInput->dwExtraInfo))
|
||||||
|
|
||||||
/* Support VK_*WIN and VK_*MENU keys */
|
|
||||||
if (bKeyUp)
|
|
||||||
{
|
{
|
||||||
if (wVk == VK_LWIN || wVk == VK_RWIN)
|
ERR("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
|
||||||
IntKeyboardSendWinKeyMsg();
|
Msg.message, Msg.wParam, Msg.lParam);
|
||||||
else if(wSimpleVk == VK_MENU && !(gafAsyncKeyState[VK_CONTROL] & KS_DOWN_BIT))
|
bPostMsg = FALSE;
|
||||||
co_IntKeyboardSendAltKeyMsg();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if it is a hotkey */
|
/* Update async state of not simplified vk here.
|
||||||
fModifiers = IntGetModifiers(gafAsyncKeyState);
|
See user32_apitest:GetKeyState */
|
||||||
if (GetHotKey(fModifiers, wSimpleVk, &Thread, &hWnd, &HotkeyId))
|
UpdateAsyncKeyState(wVk, bIsDown);
|
||||||
{
|
|
||||||
if (!bKeyUp)
|
|
||||||
{
|
|
||||||
TRACE("Hot key pressed (hWnd %lx, id %d)\n", hWnd, HotkeyId);
|
|
||||||
MsqPostHotKeyMessage(Thread,
|
|
||||||
hWnd,
|
|
||||||
(WPARAM)HotkeyId,
|
|
||||||
MAKELPARAM((WORD)fModifiers, wSimpleVk));
|
|
||||||
}
|
|
||||||
|
|
||||||
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 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 */
|
/* Post a keyboard message */
|
||||||
TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
|
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;
|
return TRUE;
|
||||||
|
@ -947,7 +897,7 @@ UserProcessKeyboardInput(
|
||||||
KEYBDINPUT KbdInput;
|
KEYBDINPUT KbdInput;
|
||||||
|
|
||||||
/* Support numlock */
|
/* Support numlock */
|
||||||
if ((wVk & KBDNUMPAD) && (gafAsyncKeyState[VK_NUMLOCK] & KS_LOCK_BIT))
|
if ((wVk & KBDNUMPAD) && IS_KEY_LOCKED(gafAsyncKeyState, VK_NUMLOCK))
|
||||||
{
|
{
|
||||||
wVk = IntTranslateNumpadKey(wVk & 0xFF);
|
wVk = IntTranslateNumpadKey(wVk & 0xFF);
|
||||||
}
|
}
|
||||||
|
@ -1028,7 +978,7 @@ IntTranslateKbdMessage(LPMSG lpMsg,
|
||||||
|
|
||||||
cch = IntToUnicodeEx(lpMsg->wParam,
|
cch = IntToUnicodeEx(lpMsg->wParam,
|
||||||
HIWORD(lpMsg->lParam) & 0xFF,
|
HIWORD(lpMsg->lParam) & 0xFF,
|
||||||
pti->MessageQueue->KeyState,
|
pti->MessageQueue->afKeyState,
|
||||||
wch,
|
wch,
|
||||||
sizeof(wch) / sizeof(wch[0]),
|
sizeof(wch) / sizeof(wch[0]),
|
||||||
0,
|
0,
|
||||||
|
@ -1182,31 +1132,49 @@ NtUserToUnicodeEx(
|
||||||
UINT wScanCode,
|
UINT wScanCode,
|
||||||
PBYTE pKeyStateUnsafe,
|
PBYTE pKeyStateUnsafe,
|
||||||
LPWSTR pwszBuffUnsafe,
|
LPWSTR pwszBuffUnsafe,
|
||||||
int cchBuff,
|
INT cchBuff,
|
||||||
UINT wFlags,
|
UINT wFlags,
|
||||||
HKL dwhkl)
|
HKL dwhkl)
|
||||||
{
|
{
|
||||||
PTHREADINFO pti;
|
PTHREADINFO pti;
|
||||||
BYTE KeyState[0x100];
|
BYTE afKeyState[256 * 2 / 8] = {0};
|
||||||
PWCHAR pwszBuff = NULL;
|
PWCHAR pwszBuff = NULL;
|
||||||
int iRet = 0;
|
INT i, iRet = 0;
|
||||||
PKBL pKbl = NULL;
|
PKBL pKbl = NULL;
|
||||||
DECLARE_RETURN(int);
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
DECLARE_RETURN(INT);
|
||||||
|
|
||||||
TRACE("Enter NtUserSetKeyboardState\n");
|
TRACE("Enter NtUserSetKeyboardState\n");
|
||||||
UserEnterShared();
|
UserEnterShared();
|
||||||
|
|
||||||
/* Key up? */
|
/* Return 0 if SC_KEY_UP bit is set */
|
||||||
if (wScanCode & SC_KEY_UP)
|
if (wScanCode & SC_KEY_UP)
|
||||||
{
|
{
|
||||||
RETURN(0);
|
RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(MmCopyFromCaller(KeyState,
|
_SEH2_TRY
|
||||||
pKeyStateUnsafe,
|
|
||||||
sizeof(KeyState))))
|
|
||||||
{
|
{
|
||||||
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);
|
RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1232,7 +1200,7 @@ NtUserToUnicodeEx(
|
||||||
|
|
||||||
iRet = IntToUnicodeEx(wVirtKey,
|
iRet = IntToUnicodeEx(wVirtKey,
|
||||||
wScanCode,
|
wScanCode,
|
||||||
KeyState,
|
afKeyState,
|
||||||
pwszBuff,
|
pwszBuff,
|
||||||
cchBuff,
|
cchBuff,
|
||||||
wFlags,
|
wFlags,
|
||||||
|
@ -1447,24 +1415,24 @@ Exit:
|
||||||
WORD FASTCALL
|
WORD FASTCALL
|
||||||
UserGetMouseButtonsState(VOID)
|
UserGetMouseButtonsState(VOID)
|
||||||
{
|
{
|
||||||
WORD ret = 0;
|
WORD wRet = 0;
|
||||||
|
|
||||||
if (gpsi->aiSysMet[SM_SWAPBUTTON])
|
if (gpsi->aiSysMet[SM_SWAPBUTTON])
|
||||||
{
|
{
|
||||||
if (gafAsyncKeyState[VK_RBUTTON] & KS_DOWN_BIT) ret |= MK_LBUTTON;
|
if (IS_KEY_DOWN(gafAsyncKeyState, VK_RBUTTON)) wRet |= MK_LBUTTON;
|
||||||
if (gafAsyncKeyState[VK_LBUTTON] & KS_DOWN_BIT) ret |= MK_RBUTTON;
|
if (IS_KEY_DOWN(gafAsyncKeyState, VK_LBUTTON)) wRet |= MK_RBUTTON;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (gafAsyncKeyState[VK_LBUTTON] & KS_DOWN_BIT) ret |= MK_LBUTTON;
|
if (IS_KEY_DOWN(gafAsyncKeyState, VK_LBUTTON)) wRet |= MK_LBUTTON;
|
||||||
if (gafAsyncKeyState[VK_RBUTTON] & KS_DOWN_BIT) ret |= MK_RBUTTON;
|
if (IS_KEY_DOWN(gafAsyncKeyState, VK_RBUTTON)) wRet |= MK_RBUTTON;
|
||||||
}
|
}
|
||||||
if (gafAsyncKeyState[VK_MBUTTON] & KS_DOWN_BIT) ret |= MK_MBUTTON;
|
if (IS_KEY_DOWN(gafAsyncKeyState, VK_MBUTTON)) wRet |= MK_MBUTTON;
|
||||||
if (gafAsyncKeyState[VK_SHIFT] & KS_DOWN_BIT) ret |= MK_SHIFT;
|
if (IS_KEY_DOWN(gafAsyncKeyState, VK_SHIFT)) wRet |= MK_SHIFT;
|
||||||
if (gafAsyncKeyState[VK_CONTROL] & KS_DOWN_BIT) ret |= MK_CONTROL;
|
if (IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL)) wRet |= MK_CONTROL;
|
||||||
if (gafAsyncKeyState[VK_XBUTTON1] & KS_DOWN_BIT) ret |= MK_XBUTTON1;
|
if (IS_KEY_DOWN(gafAsyncKeyState, VK_XBUTTON1)) wRet |= MK_XBUTTON1;
|
||||||
if (gafAsyncKeyState[VK_XBUTTON2] & KS_DOWN_BIT) ret |= MK_XBUTTON2;
|
if (IS_KEY_DOWN(gafAsyncKeyState, VK_XBUTTON2)) wRet |= MK_XBUTTON2;
|
||||||
return ret;
|
return wRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -212,56 +212,57 @@ int UserShowCursor(BOOL bShow)
|
||||||
return MessageQueue->ShowingCursor;
|
return MessageQueue->ShowingCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD FASTCALL UserGetKeyState(DWORD key)
|
DWORD FASTCALL
|
||||||
|
UserGetKeyState(DWORD dwKey)
|
||||||
{
|
{
|
||||||
DWORD ret = 0;
|
DWORD dwRet = 0;
|
||||||
PTHREADINFO pti;
|
PTHREADINFO pti;
|
||||||
PUSER_MESSAGE_QUEUE MessageQueue;
|
PUSER_MESSAGE_QUEUE MessageQueue;
|
||||||
|
|
||||||
pti = PsGetCurrentThreadWin32Thread();
|
pti = PsGetCurrentThreadWin32Thread();
|
||||||
MessageQueue = pti->MessageQueue;
|
MessageQueue = pti->MessageQueue;
|
||||||
|
|
||||||
if (key < 0x100)
|
if (dwKey < 0x100)
|
||||||
{
|
{
|
||||||
ret = (DWORD)MessageQueue->KeyState[key];
|
if (IS_KEY_DOWN(MessageQueue->afKeyState, dwKey))
|
||||||
if (MessageQueue->KeyState[key] & KS_DOWN_BIT)
|
dwRet |= 0xFF80; // If down, windows returns 0xFF80.
|
||||||
ret |= 0xFF80; // If down, windows returns 0xFF80.
|
if (IS_KEY_LOCKED(MessageQueue->afKeyState, dwKey))
|
||||||
if (MessageQueue->KeyState[key] & KS_LOCK_BIT)
|
dwRet |= 0x1;
|
||||||
ret |= 0x1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
}
|
}
|
||||||
return ret;
|
return dwRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* change the input key state for a given key */
|
/* 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))
|
/* If it's first key down event, xor lock bit */
|
||||||
{
|
if (!IS_KEY_DOWN(MessageQueue->afKeyState, wVk))
|
||||||
MessageQueue->KeyState[key] ^= KS_LOCK_BIT;
|
SET_KEY_LOCKED(MessageQueue->afKeyState, wVk, !IS_KEY_LOCKED(MessageQueue->afKeyState, wVk));
|
||||||
}
|
|
||||||
MessageQueue->KeyState[key] |= KS_DOWN_BIT;
|
SET_KEY_DOWN(MessageQueue->afKeyState, wVk, TRUE);
|
||||||
|
MessageQueue->afKeyRecentDown[wVk / 8] |= (1 << (wVk % 8));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
SET_KEY_DOWN(MessageQueue->afKeyState, wVk, FALSE);
|
||||||
MessageQueue->KeyState[key] &= ~KS_DOWN_BIT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update the input key state for a keyboard message */
|
/* 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;
|
UCHAR key;
|
||||||
BOOL down = 0;
|
BOOL down = 0;
|
||||||
|
|
||||||
TRACE("update_input_key_state message:%d\n", msg->message);
|
TRACE("UpdateKeyStateFromMsg message:%d\n", msg->message);
|
||||||
|
|
||||||
switch (msg->message)
|
switch (msg->message)
|
||||||
{
|
{
|
||||||
|
@ -269,28 +270,28 @@ static void update_input_key_state( PUSER_MESSAGE_QUEUE MessageQueue, MSG* msg )
|
||||||
down = 1;
|
down = 1;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case WM_LBUTTONUP:
|
case WM_LBUTTONUP:
|
||||||
set_input_key_state( MessageQueue, VK_LBUTTON, down );
|
UpdateKeyState(MessageQueue, VK_LBUTTON, down);
|
||||||
break;
|
break;
|
||||||
case WM_MBUTTONDOWN:
|
case WM_MBUTTONDOWN:
|
||||||
down = 1;
|
down = 1;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case WM_MBUTTONUP:
|
case WM_MBUTTONUP:
|
||||||
set_input_key_state( MessageQueue, VK_MBUTTON, down );
|
UpdateKeyState(MessageQueue, VK_MBUTTON, down);
|
||||||
break;
|
break;
|
||||||
case WM_RBUTTONDOWN:
|
case WM_RBUTTONDOWN:
|
||||||
down = 1;
|
down = 1;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case WM_RBUTTONUP:
|
case WM_RBUTTONUP:
|
||||||
set_input_key_state( MessageQueue, VK_RBUTTON, down );
|
UpdateKeyState(MessageQueue, VK_RBUTTON, down);
|
||||||
break;
|
break;
|
||||||
case WM_XBUTTONDOWN:
|
case WM_XBUTTONDOWN:
|
||||||
down = 1;
|
down = 1;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case WM_XBUTTONUP:
|
case WM_XBUTTONUP:
|
||||||
if (msg->wParam == XBUTTON1)
|
if (msg->wParam == XBUTTON1)
|
||||||
set_input_key_state( MessageQueue, VK_XBUTTON1, down );
|
UpdateKeyState(MessageQueue, VK_XBUTTON1, down);
|
||||||
else if (msg->wParam == XBUTTON2)
|
else if (msg->wParam == XBUTTON2)
|
||||||
set_input_key_state( MessageQueue, VK_XBUTTON2, down );
|
UpdateKeyState(MessageQueue, VK_XBUTTON2, down);
|
||||||
break;
|
break;
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
case WM_SYSKEYDOWN:
|
case WM_SYSKEYDOWN:
|
||||||
|
@ -299,23 +300,23 @@ static void update_input_key_state( PUSER_MESSAGE_QUEUE MessageQueue, MSG* msg )
|
||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
case WM_SYSKEYUP:
|
case WM_SYSKEYUP:
|
||||||
key = (UCHAR)msg->wParam;
|
key = (UCHAR)msg->wParam;
|
||||||
set_input_key_state( MessageQueue, key, down );
|
UpdateKeyState(MessageQueue, key, down);
|
||||||
switch(key)
|
switch(key)
|
||||||
{
|
{
|
||||||
case VK_LCONTROL:
|
case VK_LCONTROL:
|
||||||
case VK_RCONTROL:
|
case VK_RCONTROL:
|
||||||
down = (MessageQueue->KeyState[VK_LCONTROL] | MessageQueue->KeyState[VK_RCONTROL]) & KS_DOWN_BIT;
|
down = IS_KEY_DOWN(MessageQueue->afKeyState, VK_LCONTROL) || IS_KEY_DOWN(MessageQueue->afKeyState, VK_RCONTROL);
|
||||||
set_input_key_state( MessageQueue, VK_CONTROL, down );
|
UpdateKeyState(MessageQueue, VK_CONTROL, down);
|
||||||
break;
|
break;
|
||||||
case VK_LMENU:
|
case VK_LMENU:
|
||||||
case VK_RMENU:
|
case VK_RMENU:
|
||||||
down = (MessageQueue->KeyState[VK_LMENU] | MessageQueue->KeyState[VK_RMENU]) & KS_DOWN_BIT;
|
down = IS_KEY_DOWN(MessageQueue->afKeyState, VK_LMENU) || IS_KEY_DOWN(MessageQueue->afKeyState, VK_RMENU);
|
||||||
set_input_key_state( MessageQueue, VK_MENU, down );
|
UpdateKeyState(MessageQueue, VK_MENU, down);
|
||||||
break;
|
break;
|
||||||
case VK_LSHIFT:
|
case VK_LSHIFT:
|
||||||
case VK_RSHIFT:
|
case VK_RSHIFT:
|
||||||
down = (MessageQueue->KeyState[VK_LSHIFT] | MessageQueue->KeyState[VK_RSHIFT]) & KS_DOWN_BIT;
|
down = IS_KEY_DOWN(MessageQueue->afKeyState, VK_LSHIFT) || IS_KEY_DOWN(MessageQueue->afKeyState, VK_RSHIFT);
|
||||||
set_input_key_state( MessageQueue, VK_SHIFT, down );
|
UpdateKeyState(MessageQueue, VK_SHIFT, down);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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.
|
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
|
VOID FASTCALL
|
||||||
MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
|
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,
|
InsertTailList(&MessageQueue->HardwareMessagesListHead,
|
||||||
&Message->ListEntry);
|
&Message->ListEntry);
|
||||||
|
|
||||||
update_input_key_state( MessageQueue, Msg );
|
UpdateKeyStateFromMsg( MessageQueue, Msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
Message->QS_Flags = MessageBits;
|
Message->QS_Flags = MessageBits;
|
||||||
|
@ -1801,7 +1724,7 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
||||||
|
|
||||||
if (Remove)
|
if (Remove)
|
||||||
{
|
{
|
||||||
update_input_key_state(MessageQueue, &msg);
|
UpdateKeyStateFromMsg(MessageQueue, &msg);
|
||||||
RemoveEntryList(&CurrentMessage->ListEntry);
|
RemoveEntryList(&CurrentMessage->ListEntry);
|
||||||
ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags);
|
ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags);
|
||||||
MsqDestroyMessage(CurrentMessage);
|
MsqDestroyMessage(CurrentMessage);
|
||||||
|
@ -1930,7 +1853,7 @@ MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQu
|
||||||
MessageQueue->NewMessagesHandle = NULL;
|
MessageQueue->NewMessagesHandle = NULL;
|
||||||
MessageQueue->ShowingCursor = 0;
|
MessageQueue->ShowingCursor = 0;
|
||||||
MessageQueue->CursorObject = NULL;
|
MessageQueue->CursorObject = NULL;
|
||||||
RtlCopyMemory(MessageQueue->KeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState));
|
RtlCopyMemory(MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState));
|
||||||
|
|
||||||
Status = ZwCreateEvent(&MessageQueue->NewMessagesHandle, EVENT_ALL_ACCESS,
|
Status = ZwCreateEvent(&MessageQueue->NewMessagesHandle, EVENT_ALL_ACCESS,
|
||||||
NULL, SynchronizationEvent, FALSE);
|
NULL, SynchronizationEvent, FALSE);
|
||||||
|
@ -2281,7 +2204,7 @@ DWORD
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserGetKeyboardState(LPBYTE lpKeyState)
|
NtUserGetKeyboardState(LPBYTE lpKeyState)
|
||||||
{
|
{
|
||||||
DWORD ret = TRUE;
|
DWORD i, ret = TRUE;
|
||||||
PTHREADINFO pti;
|
PTHREADINFO pti;
|
||||||
PUSER_MESSAGE_QUEUE MessageQueue;
|
PUSER_MESSAGE_QUEUE MessageQueue;
|
||||||
|
|
||||||
|
@ -2292,8 +2215,16 @@ NtUserGetKeyboardState(LPBYTE lpKeyState)
|
||||||
|
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
ProbeForWrite(lpKeyState,sizeof(MessageQueue->KeyState) ,1);
|
/* Probe and copy key state to an array */
|
||||||
RtlCopyMemory(lpKeyState,MessageQueue->KeyState,sizeof(MessageQueue->KeyState));
|
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)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
@ -2309,9 +2240,10 @@ NtUserGetKeyboardState(LPBYTE lpKeyState)
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserSetKeyboardState(LPBYTE lpKeyState)
|
NtUserSetKeyboardState(LPBYTE pKeyState)
|
||||||
{
|
{
|
||||||
DWORD ret = TRUE;
|
UINT i;
|
||||||
|
BOOL bRet = TRUE;
|
||||||
PTHREADINFO pti;
|
PTHREADINFO pti;
|
||||||
PUSER_MESSAGE_QUEUE MessageQueue;
|
PUSER_MESSAGE_QUEUE MessageQueue;
|
||||||
|
|
||||||
|
@ -2322,19 +2254,23 @@ NtUserSetKeyboardState(LPBYTE lpKeyState)
|
||||||
|
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
ProbeForRead(lpKeyState,sizeof(MessageQueue->KeyState) ,1);
|
ProbeForRead(pKeyState, 256 * sizeof(BYTE), 1);
|
||||||
RtlCopyMemory(MessageQueue->KeyState,lpKeyState,sizeof(MessageQueue->KeyState));
|
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)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
SetLastNtError(_SEH2_GetExceptionCode());
|
SetLastNtError(_SEH2_GetExceptionCode());
|
||||||
ret = FALSE;
|
bRet = FALSE;
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
UserLeave();
|
UserLeave();
|
||||||
|
|
||||||
return ret;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue