Author: rharabien
Date: Thu Oct 13 13:23:57 2011
New Revision: 54107
URL:
http://svn.reactos.org/svn/reactos?rev=54107&view=rev
Log:
[WIN32K]
- Right ALT on some keyboard sends LCONTROL and RALT key events
- Shift has never extended bit in key messages
- Fixes about 32 user32:input winetest
- Don't allow to register hotkeys with special keys combinations (eg. WIN key)
- Set last error in RegisterHotKey if hotkey is already registered
Modified:
trunk/reactos/subsystems/win32/win32k/include/hotkey.h
trunk/reactos/subsystems/win32/win32k/include/input.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] Thu Oct 13
13:23:57 2011
@@ -1,22 +1,25 @@
#pragma once
-typedef struct _HOT_KEY_ITEM
+typedef struct _HOT_KEY
{
- LIST_ENTRY ListEntry;
- struct _ETHREAD *Thread;
- HWND hWnd;
- int id;
- UINT fsModifiers;
- UINT vk;
-} HOT_KEY_ITEM, *PHOT_KEY_ITEM;
+ struct _ETHREAD *pThread;
+ HWND hWnd;
+ UINT fsModifiers;
+ UINT vk;
+ INT id;
+ struct _HOT_KEY *pNext;
+} HOT_KEY, *PHOT_KEY;
-#define IDHOT_REACTOS (-9)
+/* Special Hot Keys */
+#define IDHK_F12 -5
+#define IDHK_SHIFTF12 -6
+#define IDHK_WINKEY -7
+#define IDHK_REACTOS -8
INIT_FUNCTION NTSTATUS NTAPI InitHotkeyImpl(VOID);
-PHOT_KEY_ITEM FASTCALL IsHotKey(UINT fsModifiers, WORD wVk);
VOID FASTCALL UnregisterWindowHotKeys(PWND Window);
-VOID FASTCALL UnregisterThreadHotKeys(struct _ETHREAD *Thread);
+VOID FASTCALL UnregisterThreadHotKeys(struct _ETHREAD *pThread);
BOOL NTAPI co_UserProcessHotKeys(WORD wVk, BOOL bIsDown);
UINT FASTCALL DefWndGetHotKey(HWND hwnd);
INT FASTCALL DefWndSetHotKey(PWND pWnd, WPARAM wParam);
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] Thu Oct 13 13:23:57
2011
@@ -33,17 +33,12 @@
/* Scan Codes */
#define SC_KEY_UP 0x8000
/* lParam bits */
-#define LP_EXT_BIT (KF_EXTENDED<<16)
#define LP_DO_NOT_CARE_BIT (1<<25) // for GetKeyNameText
-#define LP_DLGMODE (KF_DLGMODE<<16)
-#define LP_MENUMODE (KF_MENUMODE<<16)
-#define LP_CONTEXT_BIT (KF_ALTDOWN<<16)
-#define LP_PREV_STATE_BIT (KF_REPEAT<<16)
-#define LP_TRANSITION_BIT (KF_UP<<16)
INIT_FUNCTION NTSTATUS NTAPI InitInputImpl(VOID);
INIT_FUNCTION NTSTATUS NTAPI InitKeyboardImpl(VOID);
+VOID NTAPI UserInitKeyboard(HANDLE hKeyboardDevice);
PKBL W32kGetDefaultKeyLayout(VOID);
VOID NTAPI UserProcessKeyboardInput(PKEYBOARD_INPUT_DATA pKeyInput);
BOOL NTAPI UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected);
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] Thu Oct 13 13:23:57
2011
@@ -19,7 +19,13 @@
/* GLOBALS *******************************************************************/
-LIST_ENTRY gHotkeyList;
+/* Hardcoded hotkeys. See
http://ivanlef0u.fr/repo/windoz/VI20051005.html */
+/* thread hwnd modifiers vk id next */
+HOT_KEY hkF12 = {NULL, NULL, 0, VK_F12, IDHK_F12, NULL};
+HOT_KEY hkShiftF12 = {NULL, NULL, MOD_SHIFT, VK_F12, IDHK_SHIFTF12, &hkF12};
+HOT_KEY hkWinKey = {NULL, NULL, MOD_WIN, 0, IDHK_WINKEY, &hkShiftF12};
+
+PHOT_KEY gphkFirst = &hkWinKey;
/* FUNCTIONS *****************************************************************/
@@ -28,19 +34,14 @@
NTAPI
InitHotkeyImpl(VOID)
{
- InitializeListHead(&gHotkeyList);
-
return STATUS_SUCCESS;
}
-#if 0 //not used
-NTSTATUS FASTCALL
+/*NTSTATUS FASTCALL
CleanupHotKeys(VOID)
{
-
return STATUS_SUCCESS;
-}
-#endif
+}*/
/*
* IntGetModifiers
@@ -69,151 +70,235 @@
return fModifiers;
}
+/*
+ * UnregisterWindowHotKeys
+ *
+ * Removes hotkeys registered by specified window on its cleanup
+ */
VOID FASTCALL
-UnregisterWindowHotKeys(PWND Window)
-{
- PHOT_KEY_ITEM HotKeyItem, tmp;
-
- LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
- {
- if (HotKeyItem->hWnd == Window->head.h)
- {
- RemoveEntryList(&HotKeyItem->ListEntry);
- ExFreePool(HotKeyItem);
- }
- }
-}
-
+UnregisterWindowHotKeys(PWND pWnd)
+{
+ PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
+ HWND hWnd = pWnd->head.h;
+
+ while (pHotKey)
+ {
+ /* Save next ptr for later use */
+ phkNext = pHotKey->pNext;
+
+ /* Should we delete this hotkey? */
+ if (pHotKey->hWnd == hWnd)
+ {
+ /* Update next ptr for previous hotkey and free memory */
+ *pLink = phkNext;
+ ExFreePoolWithTag(pHotKey, USERTAG_HOTKEY);
+ }
+ else /* This hotkey will stay, use its next ptr */
+ pLink = &pHotKey->pNext;
+
+ /* Move to the next entry */
+ pHotKey = phkNext;
+ }
+}
+
+/*
+ * UnregisterThreadHotKeys
+ *
+ * Removes hotkeys registered by specified thread on its cleanup
+ */
VOID FASTCALL
-UnregisterThreadHotKeys(struct _ETHREAD *Thread)
-{
- PHOT_KEY_ITEM HotKeyItem, tmp;
-
- LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
- {
- if (HotKeyItem->Thread == Thread)
- {
- RemoveEntryList(&HotKeyItem->ListEntry);
- ExFreePool(HotKeyItem);
- }
- }
-
-}
-
-PHOT_KEY_ITEM FASTCALL
+UnregisterThreadHotKeys(struct _ETHREAD *pThread)
+{
+ PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
+
+ while (pHotKey)
+ {
+ /* Save next ptr for later use */
+ phkNext = pHotKey->pNext;
+
+ /* Should we delete this hotkey? */
+ if (pHotKey->pThread == pThread)
+ {
+ /* Update next ptr for previous hotkey and free memory */
+ *pLink = phkNext;
+ ExFreePoolWithTag(pHotKey, USERTAG_HOTKEY);
+ }
+ else /* This hotkey will stay, use its next ptr */
+ pLink = &pHotKey->pNext;
+
+ /* Move to the next entry */
+ pHotKey = phkNext;
+ }
+}
+
+/*
+ * IsHotKey
+ *
+ * Checks if given key and modificators have corresponding hotkey
+ */
+static PHOT_KEY 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;
- }
+ PHOT_KEY pHotKey = gphkFirst;
+
+ while (pHotKey)
+ {
+ if (pHotKey->fsModifiers == fsModifiers &&
+ pHotKey->vk == wVk)
+ {
+ /* We have found it */
+ return pHotKey;
+ }
+
+ /* Move to the next entry */
+ pHotKey = pHotKey->pNext;
}
return NULL;
}
/*
- * IntKeyboardSendWinKeyMsg
- *
- * Sends syscommand to shell, when WIN key is pressed
+ * SendSysCmdMsg
+ *
+ * Sends syscommand to specified window
*/
static
VOID NTAPI
-IntKeyboardSendWinKeyMsg()
+SendSysCmdMsg(HWND hWnd, WPARAM Cmd, LPARAM lParam)
{
PWND pWnd;
MSG Msg;
-
- if (!(pWnd = UserGetWindowObject(InputWindowStation->ShellWindow)))
- {
- ERR("Couldn't find window to send Windows key message!\n");
+ LARGE_INTEGER LargeTickCount;
+
+ /* Get ptr to given window */
+ pWnd = UserGetWindowObject(hWnd);
+ if (!pWnd)
+ {
+ WARN("Invalid window!\n");
return;
}
- Msg.hwnd = InputWindowStation->ShellWindow;
+ /* Prepare WM_SYSCOMMAND message */
+ Msg.hwnd = hWnd;
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);
-}
-
+ Msg.wParam = Cmd;
+ Msg.lParam = lParam;
+ KeQueryTickCount(&LargeTickCount);
+ Msg.time = MsqCalculateMessageTime(&LargeTickCount);
+ Msg.pt = gpsi->ptCursor;
+
+ /* Post message to window */
+ MsqPostMessage(pWnd->head.pti->MessageQueue, &Msg, FALSE, QS_POSTMESSAGE);
+}
+
+/*
+ * co_UserProcessHotKeys
+ *
+ * Sends WM_HOTKEY message if given keys are hotkey
+ */
BOOL NTAPI
co_UserProcessHotKeys(WORD wVk, BOOL bIsDown)
{
UINT fModifiers;
- PHOT_KEY_ITEM pHotKey;
+ PHOT_KEY pHotKey;
+
+ if (wVk == VK_SHIFT || wVk == VK_CONTROL || wVk == VK_MENU ||
+ wVk == VK_LWIN || wVk == VK_RWIN)
+ {
+ /* Those keys are specified by modifiers */
+ wVk = 0;
+ }
/* 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));
+ /* Process hotkey if it is key up event */
+ if (!bIsDown)
+ {
+ TRACE("Hot key pressed (hWnd %p, id %d)\n", pHotKey->hWnd,
pHotKey->id);
+
+ /* WIN and F12 keys are hardcoded here. See:
http://ivanlef0u.fr/repo/windoz/VI20051005.html */
+ if (pHotKey == &hkWinKey)
+ SendSysCmdMsg(InputWindowStation->ShellWindow, SC_TASKLIST, 0);
+ else if (pHotKey == &hkF12 || pHotKey == &hkShiftF12)
+ {
+ //co_ActivateDebugger(); // FIXME
+ }
+ else if (pHotKey->id == IDHK_REACTOS && !pHotKey->pThread) //
FIXME: those hotkeys doesn't depend on RegisterHotKey
+ {
+ SendSysCmdMsg(pHotKey->hWnd, SC_HOTKEY, (LPARAM)pHotKey->hWnd);
+ }
+ else
+ {
+ MsqPostHotKeyMessage(pHotKey->pThread,
+ 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.
-//
+/*
+ * DefWndGetHotKey
+ *
+ * GetHotKey message support
+ */
UINT FASTCALL
-DefWndGetHotKey(HWND hwnd)
-{
- PHOT_KEY_ITEM HotKeyItem;
-
- ERR("DefWndGetHotKey\n");
-
- if (IsListEmpty(&gHotkeyList)) return 0;
-
- LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
- {
- if (HotKeyItem->hWnd == hwnd &&
- HotKeyItem->id == IDHOT_REACTOS)
- {
- return MAKELONG(HotKeyItem->vk, HotKeyItem->fsModifiers);
- }
- }
+DefWndGetHotKey(HWND hWnd)
+{
+ PHOT_KEY pHotKey = gphkFirst;
+
+ WARN("DefWndGetHotKey\n");
+
+ while (pHotKey)
+ {
+ if (pHotKey->hWnd == hWnd && pHotKey->id == IDHK_REACTOS)
+ {
+ /* We have found it */
+ return MAKELONG(pHotKey->vk, pHotKey->fsModifiers);
+ }
+
+ /* Move to the next entry */
+ pHotKey = pHotKey->pNext;
+ }
+
return 0;
}
+/*
+ * DefWndSetHotKey
+ *
+ * SetHotKey message support
+ */
INT FASTCALL
DefWndSetHotKey(PWND pWnd, WPARAM wParam)
{
UINT fsModifiers, vk;
- PHOT_KEY_ITEM HotKeyItem;
+ PHOT_KEY pHotKey, *pLink;
HWND hWnd;
- BOOL HaveSameWnd = FALSE;
- INT Ret = 1;
-
- ERR("DefWndSetHotKey wParam 0x%x\n", wParam);
+ INT iRet = 1;
+
+ WARN("DefWndSetHotKey wParam 0x%x\n", wParam);
// A hot key cannot be associated with a child window.
- if (pWnd->style & WS_CHILD) return 0;
+ if (pWnd->style & WS_CHILD)
+ return 0;
// VK_ESCAPE, VK_SPACE, and VK_TAB are invalid hot keys.
if (LOWORD(wParam) == VK_ESCAPE ||
LOWORD(wParam) == VK_SPACE ||
- LOWORD(wParam) == VK_TAB) return -1;
+ LOWORD(wParam) == VK_TAB)
+ {
+ return -1;
+ }
vk = LOWORD(wParam);
fsModifiers = HIWORD(wParam);
@@ -221,62 +306,68 @@
if (wParam)
{
- LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
- {
- if (HotKeyItem->fsModifiers == fsModifiers &&
- HotKeyItem->vk == vk &&
- HotKeyItem->id == IDHOT_REACTOS)
+ pHotKey = gphkFirst;
+ while (pHotKey)
+ {
+ if (pHotKey->fsModifiers == fsModifiers &&
+ pHotKey->vk == vk &&
+ pHotKey->id == IDHK_REACTOS)
{
- if (HotKeyItem->hWnd != hWnd)
- Ret = 2; // Another window already has the same hot key.
+ if (pHotKey->hWnd != hWnd)
+ iRet = 2; // Another window already has the same hot key.
break;
}
- }
- }
-
- LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
- {
- if (HotKeyItem->hWnd == hWnd &&
- HotKeyItem->id == IDHOT_REACTOS)
- {
- HaveSameWnd = TRUE;
+
+ /* Move to the next entry */
+ pHotKey = pHotKey->pNext;
+ }
+ }
+
+ pHotKey = gphkFirst;
+ pLink = &gphkFirst;
+ while (pHotKey)
+ {
+ if (pHotKey->hWnd == hWnd &&
+ pHotKey->id == IDHK_REACTOS)
+ {
+ /* This window has already hotkey registered */
break;
}
- }
-
- if (HaveSameWnd)
- {
- if (wParam == 0)
- { // Setting wParam to NULL removes the hot key associated with a window.
- UnregisterWindowHotKeys(pWnd);
- }
- else
- { /* A window can only have one hot key. If the window already has a hot key
- associated with it, the new hot key replaces the old one. */
- HotKeyItem->fsModifiers = fsModifiers;
- HotKeyItem->vk = vk;
- }
- }
- else //
- {
- if (wParam == 0)
- return 1; // Do nothing, exit.
-
- HotKeyItem = ExAllocatePoolWithTag(PagedPool, sizeof(HOT_KEY_ITEM),
USERTAG_HOTKEY);
- if (HotKeyItem == NULL)
- {
- return 0;
- }
-
- HotKeyItem->Thread = pWnd->head.pti->pEThread;
- HotKeyItem->hWnd = hWnd;
- HotKeyItem->id = IDHOT_REACTOS; // Don't care, these hot keys are
unrelated to the hot keys set by RegisterHotKey.
- HotKeyItem->fsModifiers = fsModifiers;
- HotKeyItem->vk = vk;
-
- InsertHeadList(&gHotkeyList, &HotKeyItem->ListEntry);
- }
- return Ret;
+
+ /* Move to the next entry */
+ pLink = &pHotKey->pNext;
+ pHotKey = pHotKey->pNext;
+ }
+
+ if (wParam)
+ {
+ if (!pHotKey)
+ {
+ /* Create new hotkey */
+ pHotKey = ExAllocatePoolWithTag(PagedPool, sizeof(HOT_KEY), USERTAG_HOTKEY);
+ if (pHotKey == NULL)
+ return 0;
+
+ pHotKey->hWnd = hWnd;
+ pHotKey->id = IDHK_REACTOS; // Don't care, these hot keys are
unrelated to the hot keys set by RegisterHotKey
+ pHotKey->pNext = gphkFirst;
+ gphkFirst = pHotKey;
+ }
+
+ /* A window can only have one hot key. If the window already has a
+ hot key associated with it, the new hot key replaces the old one. */
+ pHotKey->pThread = NULL;
+ pHotKey->fsModifiers = fsModifiers;
+ pHotKey->vk = vk;
+ }
+ else if (pHotKey)
+ {
+ /* Remove hotkey */
+ *pLink = pHotKey->pNext;
+ ExFreePoolWithTag(pHotKey, USERTAG_HOTKEY);
+ }
+
+ return iRet;
}
/* SYSCALLS *****************************************************************/
@@ -288,88 +379,110 @@
UINT fsModifiers,
UINT vk)
{
- PHOT_KEY_ITEM HotKeyItem;
- PWND Window;
- PETHREAD HotKeyThread;
- DECLARE_RETURN(BOOL);
+ PHOT_KEY pHotKey;
+ PWND pWnd;
+ PETHREAD pHotKeyThread;
+ BOOL bRet = FALSE;
TRACE("Enter NtUserRegisterHotKey\n");
+
+ if (fsModifiers & ~(MOD_ALT|MOD_CONTROL|MOD_SHIFT|MOD_WIN)) //FIXME: does win2k3
supports MOD_NOREPEAT?
+ {
+ WARN("Invalid modifiers: %x\n", fsModifiers);
+ EngSetLastError(ERROR_INVALID_FLAGS);
+ return 0;
+ }
+
UserEnterExclusive();
+ /* Find hotkey thread */
if (hWnd == NULL)
{
- HotKeyThread = PsGetCurrentThread();
+ pHotKeyThread = PsGetCurrentThread();
}
else
{
- if(!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN( FALSE);
- }
- HotKeyThread = Window->head.pti->pEThread;
+ pWnd = UserGetWindowObject(hWnd);
+ if (!pWnd)
+ goto cleanup;
+
+ pHotKeyThread = pWnd->head.pti->pEThread;
}
/* Check for existing hotkey */
if (IsHotKey(fsModifiers, vk))
{
- RETURN( FALSE);
- }
-
- HotKeyItem = ExAllocatePoolWithTag(PagedPool, sizeof(HOT_KEY_ITEM), USERTAG_HOTKEY);
- if (HotKeyItem == NULL)
- {
- RETURN( FALSE);
- }
-
- HotKeyItem->Thread = HotKeyThread;
- HotKeyItem->hWnd = hWnd;
- HotKeyItem->id = id;
- HotKeyItem->fsModifiers = fsModifiers;
- HotKeyItem->vk = vk;
-
- InsertHeadList(&gHotkeyList, &HotKeyItem->ListEntry);
-
- RETURN( TRUE);
-
-CLEANUP:
- TRACE("Leave NtUserRegisterHotKey, ret=%i\n", _ret_);
+ EngSetLastError(ERROR_HOTKEY_ALREADY_REGISTERED);
+ WARN("Hotkey already exists\n");
+ goto cleanup;
+ }
+
+ /* Create new hotkey */
+ pHotKey = ExAllocatePoolWithTag(PagedPool, sizeof(HOT_KEY), USERTAG_HOTKEY);
+ if (pHotKey == NULL)
+ {
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+
+ pHotKey->pThread = pHotKeyThread;
+ pHotKey->hWnd = hWnd;
+ pHotKey->fsModifiers = fsModifiers;
+ pHotKey->vk = vk;
+ pHotKey->id = id;
+
+ /* Insert hotkey to the global list */
+ pHotKey->pNext = gphkFirst;
+ gphkFirst = pHotKey;
+
+ bRet = TRUE;
+
+cleanup:
+ TRACE("Leave NtUserRegisterHotKey, ret=%i\n", bRet);
UserLeave();
- END_CLEANUP;
+ return bRet;
}
BOOL APIENTRY
NtUserUnregisterHotKey(HWND hWnd, int id)
{
- PHOT_KEY_ITEM HotKeyItem;
- PWND Window;
- DECLARE_RETURN(BOOL);
+ PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
+ PWND pWnd;
+ BOOL bRet = FALSE;
TRACE("Enter NtUserUnregisterHotKey\n");
UserEnterExclusive();
- if(!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN( FALSE);
- }
-
- LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
- {
- if (HotKeyItem->hWnd == hWnd && HotKeyItem->id == id)
- {
- RemoveEntryList(&HotKeyItem->ListEntry);
- ExFreePoolWithTag(HotKeyItem, USERTAG_HOTKEY);
-
- RETURN( TRUE);
- }
- }
-
- RETURN( FALSE);
-
-CLEANUP:
- TRACE("Leave NtUserUnregisterHotKey, ret=%i\n", _ret_);
+ pWnd = UserGetWindowObject(hWnd);
+ if (!pWnd)
+ goto cleanup;
+
+ while (pHotKey)
+ {
+ /* Save next ptr for later use */
+ phkNext = pHotKey->pNext;
+
+ /* Should we delete this hotkey? */
+ if (pHotKey->hWnd == hWnd && pHotKey->id == id)
+ {
+ /* Update next ptr for previous hotkey and free memory */
+ *pLink = phkNext;
+ ExFreePoolWithTag(pHotKey, USERTAG_HOTKEY);
+
+ bRet = TRUE;
+ }
+ else /* This hotkey will stay, use its next ptr */
+ pLink = &pHotKey->pNext;
+
+ /* Move to the next entry */
+ pHotKey = phkNext;
+ }
+
+cleanup:
+ TRACE("Leave NtUserUnregisterHotKey, ret=%i\n", bRet);
UserLeave();
- END_CLEANUP;
+ return bRet;
}
/* EOF */
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] Thu Oct 13 13:23:57
2011
@@ -332,6 +332,8 @@
FILE_SYNCHRONOUS_IO_ALERT);
} while (!NT_SUCCESS(Status));
+ UserInitKeyboard(ghKeyboardDevice);
+
/* Not sure if converting this thread to a win32 thread is such
a great idea. Since we're posting keyboard messages to the focus
window message queue, we'll be (indirectly) doing sendmessage
@@ -355,22 +357,19 @@
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
LOW_REALTIME_PRIORITY + 3);
- //IntKeyboardGetIndicatorTrans(ghKeyboardDevice,
- // &IndicatorTrans);
-
for (;;)
{
/*
* Wait to start input.
*/
- TRACE( "Keyboard Input Thread Waiting for start event\n" );
+ TRACE("Keyboard Input Thread Waiting for start event\n");
Status = KeWaitForSingleObject(&InputThreadsStart,
0,
KernelMode,
TRUE,
NULL);
- TRACE( "Keyboard Input Thread Starting...\n" );
+ TRACE("Keyboard Input Thread Starting...\n");
/*
* Receive and process keyboard input.
*/
@@ -390,16 +389,16 @@
NULL,
NULL);
- if(Status == STATUS_ALERTED && !InputThreadsRunning)
+ if (Status == STATUS_ALERTED && !InputThreadsRunning)
{
break;
}
- if(Status == STATUS_PENDING)
+ if (Status == STATUS_PENDING)
{
NtWaitForSingleObject(ghKeyboardDevice, FALSE, NULL);
Status = Iosb.Status;
}
- if(!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
ERR("Win32K: Failed to read from keyboard.\n");
return; //(Status);
@@ -427,7 +426,7 @@
UserLeave();
}
- TRACE( "KeyboardInput Thread Stopped...\n" );
+ TRACE("KeyboardInput Thread Stopped...\n");
}
}
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] Thu Oct 13
13:23:57 2011
@@ -11,8 +11,9 @@
DBG_DEFAULT_CHANNEL(UserKbd);
BYTE gafAsyncKeyState[256 * 2 / 8]; // 2 bits per key
-BYTE gafAsyncKeyStateRecentDown[256 / 8]; // 1 bit per key
+static BYTE gafAsyncKeyStateRecentDown[256 / 8]; // 1 bit per key
static PKEYBOARD_INDICATOR_TRANSLATION gpKeyboardIndicatorTrans = NULL;
+static KEYBOARD_INDICATOR_PARAMETERS gIndicators = {0, 0};
/* FUNCTIONS *****************************************************************/
@@ -97,42 +98,85 @@
static
NTSTATUS APIENTRY
IntKeyboardUpdateLeds(HANDLE hKeyboardDevice,
+ WORD wVk,
WORD wScanCode,
- BOOL bEnabled,
- PKEYBOARD_INDICATOR_TRANSLATION pIndicatorTrans)
+ BOOL bEnabled)
{
NTSTATUS Status;
UINT i;
- static KEYBOARD_INDICATOR_PARAMETERS Indicators;
+ USHORT LedFlag = 0;
IO_STATUS_BLOCK Block;
- if (!pIndicatorTrans)
+ if (!gpKeyboardIndicatorTrans)
return STATUS_NOT_SUPPORTED;
- for (i = 0; i < pIndicatorTrans->NumberOfIndicatorKeys; i++)
- {
- if (pIndicatorTrans->IndicatorList[i].MakeCode == wScanCode)
- {
- if (bEnabled)
- Indicators.LedFlags |=
pIndicatorTrans->IndicatorList[i].IndicatorFlags;
- else
- Indicators.LedFlags =
~pIndicatorTrans->IndicatorList[i].IndicatorFlags;
-
- /* Update the lights on the hardware */
- Status = NtDeviceIoControlFile(hKeyboardDevice,
- NULL,
- NULL,
- NULL,
- &Block,
- IOCTL_KEYBOARD_SET_INDICATORS,
- &Indicators, sizeof(Indicators),
- NULL, 0);
-
- return Status;
- }
+ switch (wVk)
+ {
+ case VK_CAPITAL: LedFlag = KEYBOARD_CAPS_LOCK_ON; break;
+ case VK_NUMLOCK: LedFlag = KEYBOARD_NUM_LOCK_ON; break;
+ case VK_SCROLL: LedFlag = KEYBOARD_SCROLL_LOCK_ON; break;
+ default:
+ for (i = 0; i < gpKeyboardIndicatorTrans->NumberOfIndicatorKeys; i++)
+ {
+ if (gpKeyboardIndicatorTrans->IndicatorList[i].MakeCode == wScanCode)
+ {
+ LedFlag =
gpKeyboardIndicatorTrans->IndicatorList[i].IndicatorFlags;
+ break;
+ }
+ }
+ }
+
+ if (LedFlag)
+ {
+ if (bEnabled)
+ gIndicators.LedFlags |= LedFlag;
+ else
+ gIndicators.LedFlags = ~LedFlag;
+
+ /* Update the lights on the hardware */
+ Status = NtDeviceIoControlFile(hKeyboardDevice,
+ NULL,
+ NULL,
+ NULL,
+ &Block,
+ IOCTL_KEYBOARD_SET_INDICATORS,
+ &gIndicators, sizeof(gIndicators),
+ NULL, 0);
+
+ return Status;
}
return STATUS_SUCCESS;
+}
+
+/*
+ * UserInitKeyboard
+ *
+ * Initializes keyboard indicators translation and their state
+ */
+VOID NTAPI
+UserInitKeyboard(HANDLE hKeyboardDevice)
+{
+ NTSTATUS Status;
+ IO_STATUS_BLOCK Block;
+
+ IntKeyboardGetIndicatorTrans(hKeyboardDevice, &gpKeyboardIndicatorTrans);
+
+ Status = NtDeviceIoControlFile(hKeyboardDevice,
+ NULL,
+ NULL,
+ NULL,
+ &Block,
+ IOCTL_KEYBOARD_QUERY_INDICATORS,
+ NULL, 0,
+ &gIndicators, sizeof(gIndicators));
+
+ SET_KEY_LOCKED(gafAsyncKeyState, VK_CAPITAL,
+ gIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON);
+ SET_KEY_LOCKED(gafAsyncKeyState, VK_NUMLOCK,
+ gIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON);
+ SET_KEY_LOCKED(gafAsyncKeyState, VK_SCROLL,
+ gIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON);
}
/*
@@ -185,30 +229,6 @@
default:
return wVk;
- }
-}
-
-/*
- * IntGetVkOtherSide
- *
- * Gets other side of vk: right -> left, left -> right
- */
-static
-WORD
-IntGetVkOtherSide(WORD wVk)
-{
- switch (wVk)
- {
- case VK_LSHIFT: return VK_RSHIFT;
- case VK_RSHIFT: return VK_LSHIFT;
-
- case VK_LCONTROL: return VK_RCONTROL;
- case VK_RCONTROL: return VK_LCONTROL;
-
- case VK_LMENU: return VK_RMENU;
- case VK_RMENU: return VK_LMENU;
-
- default: return wVk;
}
}
@@ -239,24 +259,6 @@
}
/*
- * IntGetShiftBit
- *
- * Search the keyboard layout modifiers table for the shift bit
- */
-static
-DWORD FASTCALL
-IntGetShiftBit(PKBDTABLES pKbdTbl, WORD wVk)
-{
- unsigned i;
-
- for (i = 0; pKbdTbl->pCharModifiers->pVkToBit[i].Vk; i++)
- if (pKbdTbl->pCharModifiers->pVkToBit[i].Vk == wVk)
- return pKbdTbl->pCharModifiers->pVkToBit[i].ModBits;
-
- return 0;
-}
-
-/*
* IntGetModBits
*
* Gets layout specific modification bits, for example KBDSHIFT, KBDCTRL, KBDALT
@@ -272,10 +274,6 @@
for (i = 0; pKbdTbl->pCharModifiers->pVkToBit[i].Vk; i++)
if (IS_KEY_DOWN(pKeyState, pKbdTbl->pCharModifiers->pVkToBit[i].Vk))
dwModBits |= pKbdTbl->pCharModifiers->pVkToBit[i].ModBits;
-
- /* Handle Alt+Gr */
- 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);
@@ -616,20 +614,6 @@
}
/*
- * co_IntKeyboardSendAltKeyMsg
- *
- * Sends syscommand enabling window menu
- */
-static
-VOID NTAPI
-co_IntKeyboardSendAltKeyMsg()
-{
- FIXME("co_IntKeyboardSendAltKeyMsg\n");
- //co_MsqPostKeyboardMessage(WM_SYSCOMMAND,SC_KEYMENU,0); // This sends everything
into a msg loop!
-}
-
-
-/*
* UpdateAsyncKeyState
*
* Updates gafAsyncKeyState array
@@ -651,26 +635,40 @@
SET_KEY_DOWN(gafAsyncKeyState, wVk, FALSE);
}
-LRESULT
-co_CallLowLevelKeyboardHook(CONST MSG *pMsg, BOOL bInjected, DWORD dwExtraInfo)
+/*
+ * co_CallLowLevelKeyboardHook
+ *
+ * Calls WH_KEYBOARD_LL hook
+ */
+static LRESULT
+co_CallLowLevelKeyboardHook(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected,
DWORD dwTime, DWORD dwExtraInfo)
{
KBDLLHOOKSTRUCT KbdHookData;
-
- KbdHookData.vkCode = pMsg->wParam;
- KbdHookData.scanCode = HIWORD(pMsg->lParam) & 0xFF;
+ UINT uMsg;
+
+ KbdHookData.vkCode = wVk;
+ KbdHookData.scanCode = wScanCode;
KbdHookData.flags = 0;
- if (pMsg->lParam & LP_EXT_BIT)
+ if (dwFlags & KEYEVENTF_EXTENDEDKEY)
KbdHookData.flags |= LLKHF_EXTENDED;
if (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU))
KbdHookData.flags |= LLKHF_ALTDOWN;
- if (pMsg->message == WM_KEYUP || pMsg->message == WM_SYSKEYUP)
+ if (dwFlags & KEYEVENTF_KEYUP)
KbdHookData.flags |= LLKHF_UP;
if (bInjected)
KbdHookData.flags |= LLKHF_INJECTED;
- KbdHookData.time = pMsg->time;
+ KbdHookData.time = dwTime;
KbdHookData.dwExtraInfo = dwExtraInfo;
- return co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, pMsg->message, (LPARAM)
&KbdHookData);
+ /* Note: it doesnt support WM_SYSKEYUP */
+ if (dwFlags & KEYEVENTF_KEYUP)
+ uMsg = WM_KEYUP;
+ else if (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU) &&
!IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL))
+ uMsg = WM_SYSKEYDOWN;
+ else
+ uMsg = WM_KEYDOWN;
+
+ return co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, uMsg, (LPARAM)&KbdHookData);
}
/*
@@ -678,19 +676,141 @@
*
* Process keyboard input from input devices and SendInput API
*/
+BOOL NTAPI
+ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime,
DWORD dwExtraInfo)
+{
+ WORD wSimpleVk = 0, wFixedVk, wVk2;
+ PUSER_MESSAGE_QUEUE pFocusQueue;
+ BOOL bExt = (dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
+ BOOL bIsDown = (dwFlags & KEYEVENTF_KEYUP) ? FALSE : TRUE;
+ BOOL bPacket = (dwFlags & KEYEVENTF_UNICODE) ? TRUE : FALSE;
+ BOOL bWasSimpleDown = FALSE, bPostMsg = TRUE, bIsSimpleDown;
+ MSG Msg;
+ static BOOL bMenuDownRecently = FALSE;
+
+ /* Get virtual key without shifts (VK_(L|R)* -> VK_*) */
+ wSimpleVk = IntSimplifyVk(wVk);
+ bWasSimpleDown = IS_KEY_DOWN(gafAsyncKeyState, wSimpleVk);
+
+ /* Update key without shifts */
+ wVk2 = IntFixVk(wSimpleVk, !bExt);
+ bIsSimpleDown = bIsDown || IS_KEY_DOWN(gafAsyncKeyState, wVk2);
+ UpdateAsyncKeyState(wSimpleVk, bIsSimpleDown);
+
+ if (bIsDown)
+ {
+ /* Update keyboard LEDs */
+ IntKeyboardUpdateLeds(ghKeyboardDevice,
+ wSimpleVk,
+ wScanCode,
+ IS_KEY_LOCKED(gafAsyncKeyState, wSimpleVk));
+ }
+
+ /* Call WH_KEYBOARD_LL hook */
+ if (co_CallLowLevelKeyboardHook(wVk, wScanCode, dwFlags, bInjected, dwTime,
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;
+ }
+
+ /* Check if this is a hotkey */
+ if (co_UserProcessHotKeys(wSimpleVk, bIsDown))
+ bPostMsg = FALSE;
+
+ wFixedVk = IntFixVk(wSimpleVk, bExt); /* LSHIFT + EXT = RSHIFT */
+ if (wSimpleVk == VK_SHIFT) /* shift can't be extended */
+ bExt = FALSE;
+
+ /* If it is F10 or ALT is down and CTRL is up, it's a system key */
+ if (wVk == VK_F10 ||
+ (wSimpleVk == VK_MENU && bMenuDownRecently) ||
+ (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU) &&
+ !IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL)))
+ {
+ bMenuDownRecently = FALSE; // reset
+ if (bIsDown)
+ {
+ Msg.message = WM_SYSKEYDOWN;
+ if (wSimpleVk == VK_MENU)
+ {
+ // Note: If only LALT is pressed WM_SYSKEYUP is generated instead of
WM_KEYUP
+ bMenuDownRecently = TRUE;
+ }
+ }
+ else
+ Msg.message = WM_SYSKEYUP;
+ }
+ else
+ {
+ bMenuDownRecently = FALSE;
+ if (bIsDown)
+ Msg.message = WM_KEYDOWN;
+ else
+ Msg.message = WM_KEYUP;
+ }
+
+ /* Update async state of not simplified vk here.
+ See user32_apitest:GetKeyState */
+ UpdateAsyncKeyState(wFixedVk, bIsDown);
+
+ /* Alt-Tab/Esc Check. Use FocusQueue or RIT Queue */
+ if (bIsSimpleDown && !bWasSimpleDown &&
+ IS_KEY_DOWN(gafAsyncKeyState, VK_MENU) &&
+ !IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL) &&
+ (wVk == VK_ESCAPE || wVk == VK_TAB))
+ {
+ TRACE("Alt-Tab/Esc Pressed wParam %x\n",Msg.wParam);
+ }
+
+ /* If we have a focus queue, post a keyboard message */
+ pFocusQueue = IntGetFocusMessageQueue();
+ if (pFocusQueue && bPostMsg)
+ {
+ /* Init message */
+ Msg.hwnd = pFocusQueue->FocusWindow;
+ Msg.wParam = wFixedVk & 0xFF; /* Note: it's simplified by msg queue */
+ Msg.lParam = MAKELPARAM(1, wScanCode);
+ Msg.time = dwTime;
+ Msg.pt = gpsi->ptCursor;
+
+ /* If it is VK_PACKET, high word of wParam is used for wchar */
+ if (!bPacket)
+ {
+ if (bExt)
+ Msg.lParam |= KF_EXTENDED << 16;
+ if (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU))
+ Msg.lParam |= KF_ALTDOWN << 16;
+ if (bWasSimpleDown)
+ Msg.lParam |= KF_REPEAT << 16;
+ if (!bIsDown)
+ Msg.lParam |= KF_UP << 16;
+ /* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
+ if (pFocusQueue->QF_flags & QF_DIALOGACTIVE)
+ Msg.lParam |= KF_DLGMODE << 16;
+ if (pFocusQueue->MenuOwner)//pFocusQueue->MenuState) // MenuState needs
a start flag...
+ Msg.lParam |= KF_MENUMODE << 16;
+ }
+
+ /* Post a keyboard message */
+ TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message,
Msg.wParam, Msg.lParam);
+ MsqPostMessage(pFocusQueue, &Msg, TRUE, QS_KEY);
+ }
+
+ return TRUE;
+}
+
BOOL NTAPI
UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
{
- WORD wScanCode, wVk, wSimpleVk = 0, wVkOtherSide, wSysKey;
+ WORD wScanCode, wVk;
PKBL pKbl = NULL;
PKBDTABLES pKbdTbl;
PUSER_MESSAGE_QUEUE pFocusQueue;
struct _ETHREAD *pFocusThread;
LARGE_INTEGER LargeTickCount;
+ DWORD dwTime;
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();
@@ -713,7 +833,7 @@
pKbdTbl = pKbl->KBTables;
/* Note: wScan field is always used */
- wScanCode = pKbdInput->wScan & 0x7F;
+ wScanCode = pKbdInput->wScan;
if (pKbdInput->dwFlags & KEYEVENTF_UNICODE)
{
@@ -723,6 +843,7 @@
}
else
{
+ wScanCode &= 0x7F;
if (pKbdInput->dwFlags & KEYEVENTF_SCANCODE)
{
/* Don't ignore invalid scan codes */
@@ -733,129 +854,26 @@
else
{
wVk = pKbdInput->wVk & 0xFF;
-
- /* LSHIFT + EXT = RSHIFT */
- wVk = IntSimplifyVk(wVk);
- wVk = IntFixVk(wVk, bExt);
- }
-
- /* Get virtual key without shifts (VK_(L|R)* -> VK_*) */
- wSimpleVk = IntSimplifyVk(wVk);
- wVkOtherSide = IntGetVkOtherSide(wVk);
- bWasDown = IS_KEY_DOWN(gafAsyncKeyState, wSimpleVk);
-
- if (co_UserProcessHotKeys(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;
- }
-
- /* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
- if ( pFocusQueue && pFocusQueue->QF_flags & QF_DIALOGACTIVE )
- Msg.lParam |= LP_DLGMODE;
- if ( pFocusQueue && pFocusQueue->MenuOwner )//pFocusQueue->MenuState )
// MenuState needs a start flag...
- Msg.lParam |= LP_MENUMODE;
-
- /* 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;
+ dwTime = pKbdInput->time;
else
{
KeQueryTickCount(&LargeTickCount);
- Msg.time = MsqCalculateMessageTime(&LargeTickCount);
- }
-
- if (!(pKbdInput->dwFlags & KEYEVENTF_UNICODE))
- {
- if (bIsDown)
- {
- /* Update keyboard LEDs */
- if (!gpKeyboardIndicatorTrans)
- IntKeyboardGetIndicatorTrans(ghKeyboardDevice,
&gpKeyboardIndicatorTrans);
- if (gpKeyboardIndicatorTrans)
- IntKeyboardUpdateLeds(ghKeyboardDevice,
- wScanCode,
- IS_KEY_LOCKED(gafAsyncKeyState, wVk),
- gpKeyboardIndicatorTrans);
- }
-
- /* Call hook */
- if (co_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();
- }
-
- /* Alt-Tab/Esc Check. Use FocusQueue or RIT Queue */
- if (!(pKbdInput->dwFlags & KEYEVENTF_KEYUP) &&
- HIWORD(Msg.lParam) & KF_ALTDOWN &&
- ( Msg.wParam == VK_ESCAPE || Msg.wParam == VK_TAB ) )
- {
- TRACE("Alt-Tab/Esc Pressed wParam %x\n",Msg.wParam);
- }
-
- /* If we have a focus queue, post a keyboard message */
- 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);
- MsqPostMessage(pFocusQueue, &Msg, TRUE, QS_KEY);
- }
-
- return TRUE;
+ dwTime = MsqCalculateMessageTime(&LargeTickCount);
+ }
+
+ if (wVk == VK_RMENU && (pKbdTbl->fLocaleFlags & KLLF_ALTGR))
+ {
+ /* For AltGr keyboards RALT generates CTRL events */
+ ProcessKeyEvent(VK_LCONTROL, 0, pKbdInput->dwFlags & KEYEVENTF_KEYUP,
bInjected, dwTime, 0);
+ }
+
+ /* Finally process this key */
+ return ProcessKeyEvent(wVk, wScanCode, pKbdInput->dwFlags, bInjected, dwTime,
pKbdInput->dwExtraInfo);
}
/*
@@ -1102,7 +1120,7 @@
UINT ret = 0;
TRACE("Enter NtUserMapVirtualKeyEx\n");
- UserEnterExclusive();
+ UserEnterShared();
if (!dwhkl)
{
@@ -1188,7 +1206,7 @@
}
RtlZeroMemory(pwszBuff, sizeof(WCHAR) * cchBuff);
- UserEnterShared();
+ UserEnterExclusive(); // Note: we modify wchDead static variable
if (dwhkl)
pKbl = UserHklToKbl(dwhkl);
@@ -1227,7 +1245,7 @@
PTHREADINFO pti;
DWORD i, cchKeyName, dwRet = 0;
WORD wScanCode = (lParam >> 16) & 0xFF;
- BOOL bExtKey = (lParam & LP_EXT_BIT) ? TRUE : FALSE;
+ BOOL bExtKey = (HIWORD(lParam) & KF_EXTENDED) ? TRUE : FALSE;
PKBDTABLES pKbdTbl;
VSC_LPWSTR *pKeyNames = NULL;
CONST WCHAR *pKeyName = NULL;
@@ -1235,6 +1253,8 @@
TRACE("Enter NtUserGetKeyNameText\n");
+ UserEnterShared();
+
/* Get current keyboard layout */
pti = PsGetCurrentThreadWin32Thread();
pKbdTbl = pti ? pti->KeyboardLayout->KBTables : 0;
@@ -1242,10 +1262,8 @@
if (!pKbdTbl || cchSize < 1)
{
ERR("Invalid parameter\n");
- return 0;
- }
-
- UserEnterShared();
+ goto cleanup;
+ }
/* "Do not care" flag */
if(lParam & LP_DO_NOT_CARE_BIT)
@@ -1309,6 +1327,7 @@
EngSetLastError(ERROR_INVALID_PARAMETER);
}
+cleanup:
UserLeave();
TRACE("Leave NtUserGetKeyNameText, ret=%i\n", dwRet);
return dwRet;
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] Thu Oct 13
13:23:57 2011
@@ -663,10 +663,10 @@
id = wParam; // Check for hot keys unrelated to the hot keys set by RegisterHotKey.
Mesg.hwnd = hWnd;
- Mesg.message = id != IDHOT_REACTOS ? WM_HOTKEY : WM_SYSCOMMAND;
- Mesg.wParam = id != IDHOT_REACTOS ? wParam : SC_HOTKEY;
- Mesg.lParam = id != IDHOT_REACTOS ? lParam : (LPARAM)hWnd;
- Type = id != IDHOT_REACTOS ? QS_HOTKEY : QS_POSTMESSAGE;
+ Mesg.message = id != IDHK_REACTOS ? WM_HOTKEY : WM_SYSCOMMAND;
+ Mesg.wParam = id != IDHK_REACTOS ? wParam : SC_HOTKEY;
+ Mesg.lParam = id != IDHK_REACTOS ? lParam : (LPARAM)hWnd;
+ Type = id != IDHK_REACTOS ? QS_HOTKEY : QS_POSTMESSAGE;
KeQueryTickCount(&LargeTickCount);
Mesg.time = MsqCalculateMessageTime(&LargeTickCount);
Mesg.pt = gpsi->ptCursor;