Author: rharabien
Date: Sun Oct 9 20:12:12 2011
New Revision: 54063
URL:
http://svn.reactos.org/svn/reactos?rev=54063&view=rev
Log:
[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
Modified:
trunk/reactos/subsystems/win32/win32k/include/hotkey.h
trunk/reactos/subsystems/win32/win32k/include/input.h
trunk/reactos/subsystems/win32/win32k/include/msgqueue.h
trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c
trunk/reactos/subsystems/win32/win32k/ntuser/input.c
trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c
trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
Modified: trunk/reactos/subsystems/win32/win32k/include/hotkey.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/hotkey.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/hotkey.h [iso-8859-1] Sun Oct 9
20:12:12 2011
@@ -14,16 +14,11 @@
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 */
Modified: trunk/reactos/subsystems/win32/win32k/include/input.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/input.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/input.h [iso-8859-1] Sun Oct 9 20:12:12
2011
@@ -51,9 +51,21 @@
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)))
+
Modified: trunk/reactos/subsystems/win32/win32k/include/msgqueue.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] Sun Oct 9
20:12:12 2011
@@ -106,7 +106,8 @@
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 @@
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);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c [iso-8859-1] Sun Oct 9 20:12:12
2011
@@ -42,34 +42,31 @@
}
#endif
-BOOL FASTCALL
-GetHotKey (UINT fsModifiers,
- UINT vk,
- struct _ETHREAD **Thread,
- HWND *hWnd,
- int *id)
-{
- PHOT_KEY_ITEM HotKeyItem;
-
- LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
- {
- if (HotKeyItem->fsModifiers == fsModifiers &&
- HotKeyItem->vk == vk)
- {
- if (Thread != NULL)
- *Thread = HotKeyItem->Thread;
-
- if (hWnd != NULL)
- *hWnd = HotKeyItem->hWnd;
-
- if (id != NULL)
- *id = HotKeyItem->id;
-
- return TRUE;
- }
- }
-
- return FALSE;
+/*
+ * 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 (IS_KEY_DOWN(pKeyState, VK_SHIFT))
+ fModifiers |= MOD_SHIFT;
+
+ if (IS_KEY_DOWN(pKeyState, VK_CONTROL))
+ fModifiers |= MOD_CONTROL;
+
+ if (IS_KEY_DOWN(pKeyState, VK_MENU))
+ fModifiers |= MOD_ALT;
+
+ if (IS_KEY_DOWN(pKeyState, VK_LWIN) || IS_KEY_DOWN(pKeyState, VK_RWIN))
+ fModifiers |= MOD_WIN;
+
+ return fModifiers;
}
VOID FASTCALL
@@ -85,7 +82,6 @@
ExFreePool (HotKeyItem);
}
}
-
}
VOID FASTCALL
@@ -104,22 +100,78 @@
}
+PHOT_KEY_ITEM FASTCALL
+IsHotKey(UINT fsModifiers, WORD wVk)
+{
+ PHOT_KEY_ITEM pHotKeyItem;
+
+ LIST_FOR_EACH(pHotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
+ {
+ if (pHotKeyItem->fsModifiers == fsModifiers && pHotKeyItem->vk ==
wVk)
+ {
+ return pHotKeyItem;
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * IntKeyboardSendWinKeyMsg
+ *
+ * Sends syscommand to shell, when WIN key is pressed
+ */
static
-BOOL FASTCALL
-IsHotKey (UINT fsModifiers, UINT vk)
-{
- PHOT_KEY_ITEM HotKeyItem;
-
- LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
- {
- if (HotKeyItem->fsModifiers == fsModifiers && HotKeyItem->vk == vk)
- {
- return TRUE;
- }
- }
-
- return FALSE;
-}
+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 @@
}
/* 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);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/input.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] Sun Oct 9 20:12:12
2011
@@ -683,12 +683,12 @@
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 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
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 @@
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);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] Sun Oct 9
20:12:12 2011
@@ -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 @@
InitKeyboardImpl(VOID)
{
RtlZeroMemory(&gafAsyncKeyState, sizeof(gafAsyncKeyState));
+ RtlZeroMemory(&gafAsyncKeyStateRecentDown, sizeof(gafAsyncKeyStateRecentDown));
return STATUS_SUCCESS;
}
@@ -237,33 +239,6 @@
}
/*
- * 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
*
* Search the keyboard layout modifiers table for the shift bit
@@ -295,11 +270,11 @@
/* 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 @@
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 @@
/* 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 @@
/* 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 @@
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
- *
- * Gets key state from global table
- */
-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;
-}
-
+/*
+ * NtUserGetAsyncKeyState
+ *
+ * Gets key state from global bitmap
+ */
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_);
@@ -666,33 +618,6 @@
}
/*
- * 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
*
* Sends syscommand enabling window menu
@@ -705,6 +630,51 @@
//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 @@
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 @@
}
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 @@
wVk = IntSimplifyVk(wVk);
wVk = IntFixVk(wVk, bExt);
}
- }
-
- 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;
+ 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
- gafAsyncKeyState[wVk] |= KS_DOWN_BIT;
-
- /* Update key without shifts */
- gafAsyncKeyState[wSimpleVk] = gafAsyncKeyState[wVk] |
gafAsyncKeyState[wVkOtherSide];
-
- if (!bKeyUp)
+ 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 (bIsDown)
{
/* Update keyboard LEDs */
if (!gpKeyboardIndicatorTrans)
@@ -806,91 +813,34 @@
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)
- {
- if (wVk == VK_LWIN || wVk == VK_RWIN)
- IntKeyboardSendWinKeyMsg();
- else if(wSimpleVk == VK_MENU && !(gafAsyncKeyState[VK_CONTROL] &
KS_DOWN_BIT))
- co_IntKeyboardSendAltKeyMsg();
- }
-
- /* 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));
- }
-
- return TRUE; /* Don't send any message */
- }
+ /* Call hook */
+ if (CallLowLevelKeyboardHook(&Msg, bInjected, pKbdInput->dwExtraInfo))
+ {
+ ERR("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL
hook\n",
+ Msg.message, Msg.wParam, Msg.lParam);
+ bPostMsg = FALSE;
+ }
+
+ /* Update async state of not simplified vk here.
+ See user32_apitest:GetKeyState */
+ UpdateAsyncKeyState(wVk, bIsDown);
+
+ /* 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)
- {
- 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);
- }
-
+ if (pFocusQueue && bPostMsg)
+ {
/* 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 @@
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 @@
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 @@
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))))
- {
- ERR("Couldn't copy key state from caller.\n");
+ _SEH2_TRY
+ {
+ /* 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 @@
iRet = IntToUnicodeEx(wVirtKey,
wScanCode,
- KeyState,
+ afKeyState,
pwszBuff,
cchBuff,
wFlags,
@@ -1447,24 +1415,24 @@
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 (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_LBUTTON)) wRet |= MK_LBUTTON;
+ if (IS_KEY_DOWN(gafAsyncKeyState, VK_RBUTTON)) wRet |= MK_RBUTTON;
+ }
+ 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 */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] Sun Oct 9
20:12:12 2011
@@ -212,56 +212,57 @@
return MessageQueue->ShowingCursor;
}
-DWORD FASTCALL UserGetKeyState(DWORD key)
-{
- DWORD ret = 0;
+DWORD FASTCALL
+UserGetKeyState(DWORD dwKey)
+{
+ DWORD dwRet = 0;
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE MessageQueue;
pti = PsGetCurrentThreadWin32Thread();
MessageQueue = pti->MessageQueue;
- if (key < 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 (dwKey < 0x100)
+ {
+ 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
)
-{
- TRACE("set_input_key_state key:%d, down:%d\n", key, down);
-
- if (down)
- {
- if (!(MessageQueue->KeyState[key] & KS_DOWN_BIT))
- {
- MessageQueue->KeyState[key] ^= KS_LOCK_BIT;
- }
- MessageQueue->KeyState[key] |= KS_DOWN_BIT;
+static VOID
+UpdateKeyState(PUSER_MESSAGE_QUEUE MessageQueue, WORD wVk, BOOL bIsDown)
+{
+ TRACE("UpdateKeyState wVk: %d, bIsDown: %d\n", wVk, bIsDown);
+
+ if (bIsDown)
+ {
+ /* 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 @@
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 @@
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 @@
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 @@
InsertTailList(&MessageQueue->HardwareMessagesListHead,
&Message->ListEntry);
- update_input_key_state( MessageQueue, Msg );
+ UpdateKeyStateFromMsg( MessageQueue, Msg );
}
Message->QS_Flags = MessageBits;
@@ -1801,7 +1724,7 @@
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 @@
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 @@
APIENTRY
NtUserGetKeyboardState(LPBYTE lpKeyState)
{
- DWORD ret = TRUE;
+ DWORD i, ret = TRUE;
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE MessageQueue;
@@ -2292,8 +2215,16 @@
_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 @@
BOOL
APIENTRY
-NtUserSetKeyboardState(LPBYTE lpKeyState)
-{
- DWORD ret = TRUE;
+NtUserSetKeyboardState(LPBYTE pKeyState)
+{
+ UINT i;
+ BOOL bRet = TRUE;
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE MessageQueue;
@@ -2322,19 +2254,23 @@
_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 */