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/include/hotkey.h?rev=54107&r1=54106&r2=54107&view=diff ============================================================================== --- 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/include/input.h?rev=54107&r1=54106&r2=54107&view=diff ============================================================================== --- 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/ntuser/hotkey.c?rev=54107&r1=54106&r2=54107&view=diff ============================================================================== --- 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/ntuser/input.c?rev=54107&r1=54106&r2=54107&view=diff ============================================================================== --- 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/ntuser/keyboard.c?rev=54107&r1=54106&r2=54107&view=diff ============================================================================== --- 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/ntuser/msgqueue.c?rev=54107&r1=54106&r2=54107&view=diff ============================================================================== --- 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;