From: James Tabor Date: Thu, 11 Aug 2016 15:53:05 +0000 (+0000) Subject: [NtUser] X-Git-Tag: backups/sndblst@72664~412 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=4afd02584739b6f80a5fa6c70dd1bb5b524d8090 [NtUser] - Fix up Language Layout Hotkey Toggle support for the new Keyboard switching. Support registry settings. Dedicated to Dmitry Chapyshev. - The registry entry it reads from is the wrong (the short number) one. Someone with registry knowledge please help. Also VK_LSHIFT is passed all the time and not VK_RSHIFT (WIP). Support for Left Alt and Control work including SysParam. - Side Tracks : Fixed CORE-5683. ReactOS can switch from keyboard processing or from DeferWindowProc. svn path=/trunk/; revision=72197 --- diff --git a/reactos/win32ss/user/ntuser/input.h b/reactos/win32ss/user/ntuser/input.h index a85c5876835..715a0b95ee7 100644 --- a/reactos/win32ss/user/ntuser/input.h +++ b/reactos/win32ss/user/ntuser/input.h @@ -75,6 +75,8 @@ VOID NTAPI UserProcessKeyboardInput(PKEYBOARD_INPUT_DATA pKeyInput); BOOL NTAPI UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected); PKL NTAPI UserHklToKbl(HKL hKl); BOOL NTAPI UserSetDefaultInputLang(HKL hKl); +extern int gLanguageToggleKeyState; +extern DWORD gdwLanguageToggleKey; /* Mouse */ WORD FASTCALL UserGetMouseButtonsState(VOID); diff --git a/reactos/win32ss/user/ntuser/keyboard.c b/reactos/win32ss/user/ntuser/keyboard.c index 36461d837d4..18c550af1fe 100644 --- a/reactos/win32ss/user/ntuser/keyboard.c +++ b/reactos/win32ss/user/ntuser/keyboard.c @@ -15,6 +15,8 @@ static BYTE gafAsyncKeyStateRecentDown[256 / 8]; // 1 bit per key static PKEYBOARD_INDICATOR_TRANSLATION gpKeyboardIndicatorTrans = NULL; static KEYBOARD_INDICATOR_PARAMETERS gIndicators = {0, 0}; KEYBOARD_ATTRIBUTES gKeyboardInfo; +int gLanguageToggleKeyState = 0; +DWORD gdwLanguageToggleKey = 0; /* FUNCTIONS *****************************************************************/ @@ -819,7 +821,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d } /* Check if this is a hotkey */ - if (co_UserProcessHotKeys(wSimpleVk, bIsDown)) + if (co_UserProcessHotKeys(wSimpleVk, bIsDown)) //// Check if this is correct, refer to hotkey sequence message tests. { TRACE("HotKey Processed\n"); bPostMsg = FALSE; @@ -922,22 +924,6 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d } } - // TODO: When initializing win32k: Reading from the registry hotkey combination - // to switch the keyboard layout and store it to global variable. - // Using this combination of hotkeys in this function - if (wVk == VK_LSHIFT && IS_KEY_DOWN(gafAsyncKeyState, VK_LMENU)) - { - PKL pkl = pti->KeyboardLayout; - - if (pkl != NULL) - { - UserPostMessage(UserHMGetHandle(Wnd), - WM_INPUTLANGCHANGEREQUEST, - INPUTLANGCHANGE_FORWARD, - (LPARAM)pkl->hkl); - } - } - /* If it is VK_PACKET, high word of wParam is used for wchar */ if (!bPacket) { diff --git a/reactos/win32ss/user/ntuser/main.c b/reactos/win32ss/user/ntuser/main.c index a78441364ec..c2bce2e181a 100644 --- a/reactos/win32ss/user/ntuser/main.c +++ b/reactos/win32ss/user/ntuser/main.c @@ -1004,6 +1004,8 @@ DriverEntry( return Status; } + gdwLanguageToggleKey = UserGetLanguageToggle(); + gusLanguageID = UserGetLanguageID(); return STATUS_SUCCESS; diff --git a/reactos/win32ss/user/ntuser/misc.c b/reactos/win32ss/user/ntuser/misc.c index 519de838c11..74614b9b582 100644 --- a/reactos/win32ss/user/ntuser/misc.c +++ b/reactos/win32ss/user/ntuser/misc.c @@ -51,6 +51,22 @@ IntTID2PTI(HANDLE id) return pti; } +DWORD +FASTCALL +UserGetLanguageToggle(VOID) +{ + NTSTATUS Status; + DWORD dwValue = 0; + + Status = RegReadUserSetting(L"Keyboard Layout\\Toggle", L"Layout Hotkey", REG_SZ, &dwValue, sizeof(dwValue)); + if (NT_SUCCESS(Status)) + { + dwValue = atoi((char *)&dwValue); + ERR("Layout Hotkey %d\n",dwValue); + } + return dwValue; +} + SHORT FASTCALL UserGetLanguageID(VOID) diff --git a/reactos/win32ss/user/ntuser/msgqueue.c b/reactos/win32ss/user/ntuser/msgqueue.c index a2ee419cf47..e17dbd6131b 100644 --- a/reactos/win32ss/user/ntuser/msgqueue.c +++ b/reactos/win32ss/user/ntuser/msgqueue.c @@ -1773,6 +1773,7 @@ BOOL co_IntProcessKeyboardMessage(MSG* Msg, BOOL* RemoveMessages) PWND pWnd; UINT ImmRet; BOOL Ret = TRUE; + WPARAM wParam = Msg->wParam; PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); if (Msg->message == VK_PACKET) @@ -1833,6 +1834,81 @@ BOOL co_IntProcessKeyboardMessage(MSG* Msg, BOOL* RemoveMessages) } } + //// Key Down! + if ( *RemoveMessages && Msg->message == WM_SYSKEYDOWN ) + { + if ( HIWORD(Msg->lParam) & KF_ALTDOWN ) + { + if ( Msg->wParam == VK_ESCAPE || Msg->wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC + { + WPARAM wParamTmp; + + wParamTmp = UserGetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW; + TRACE("Send WM_SYSCOMMAND Alt-Tab/ESC Alt-Shift-Tab/ESC\n"); + co_IntSendMessage( Msg->hwnd, WM_SYSCOMMAND, wParamTmp, Msg->wParam ); + + //// Keep looping. + Ret = FALSE; + //// Skip the rest. + goto Exit; + } + } + } + + if ( *RemoveMessages && (Msg->message == WM_SYSKEYDOWN || Msg->message == WM_KEYDOWN) ) + { + if (gdwLanguageToggleKey < 3) + { + if (IS_KEY_DOWN(gafAsyncKeyState, gdwLanguageToggleKey == 1 ? VK_LMENU : VK_CONTROL)) // L Alt 1 or Ctrl 2 . + { + if ( wParam == VK_LSHIFT ) gLanguageToggleKeyState = INPUTLANGCHANGE_FORWARD; // Left Alt - Left Shift, Next + //// FIXME : It seems to always be VK_LSHIFT. + if ( wParam == VK_RSHIFT ) gLanguageToggleKeyState = INPUTLANGCHANGE_BACKWARD; // Left Alt - Right Shift, Previous + } + } + } + + //// Key Up! Alt Key Ctrl Key + if ( *RemoveMessages && (Msg->message == WM_SYSKEYUP || Msg->message == WM_KEYUP) ) + { + // When initializing win32k: Reading from the registry hotkey combination + // to switch the keyboard layout and store it to global variable. + // Using this combination of hotkeys in this function + + if ( gdwLanguageToggleKey < 3 && + IS_KEY_DOWN(gafAsyncKeyState, gdwLanguageToggleKey == 1 ? VK_LMENU : VK_CONTROL) ) + { + if ( Msg->wParam == VK_SHIFT && !(IS_KEY_DOWN(gafAsyncKeyState, VK_SHIFT))) + { + PKL pkl = pti->KeyboardLayout; + + if (pWnd) UserDerefObjectCo(pWnd); + + //// Seems to override message window. + if (!(pWnd = pti->MessageQueue->spwndFocus)) + { + pWnd = pti->MessageQueue->spwndActive; + } + if (pWnd) UserRefObjectCo(pWnd, &Ref); + + if (pkl != NULL && gLanguageToggleKeyState) + { + TRACE("Posting WM_INPUTLANGCHANGEREQUEST KeyState %d\n", gLanguageToggleKeyState ); + UserPostMessage(UserHMGetHandle(pWnd), + WM_INPUTLANGCHANGEREQUEST, + gLanguageToggleKeyState, + (LPARAM)pkl->hkl); + + gLanguageToggleKeyState = 0; + //// Keep looping. + Ret = FALSE; + //// Skip the rest. + goto Exit; + } + } + } + } + if (co_HOOK_CallHooks( WH_KEYBOARD, *RemoveMessages ? HC_ACTION : HC_NOREMOVE, LOWORD(Msg->wParam), @@ -1865,7 +1941,7 @@ BOOL co_IntProcessKeyboardMessage(MSG* Msg, BOOL* RemoveMessages) } } } - +Exit: if (pWnd) UserDerefObjectCo(pWnd); return Ret; } diff --git a/reactos/win32ss/user/ntuser/ntuser.h b/reactos/win32ss/user/ntuser/ntuser.h index 6856fd4d1a0..79af19d4c01 100644 --- a/reactos/win32ss/user/ntuser/ntuser.h +++ b/reactos/win32ss/user/ntuser/ntuser.h @@ -26,5 +26,6 @@ VOID FASTCALL UserEnterExclusive(VOID); VOID FASTCALL UserLeave(VOID); BOOL FASTCALL UserIsEntered(VOID); BOOL FASTCALL UserIsEnteredExclusive(VOID); +DWORD FASTCALL UserGetLanguageToggle(VOID); /* EOF */ diff --git a/reactos/win32ss/user/ntuser/sysparams.c b/reactos/win32ss/user/ntuser/sysparams.c index 01889129a79..5a193ac9d3c 100644 --- a/reactos/win32ss/user/ntuser/sysparams.c +++ b/reactos/win32ss/user/ntuser/sysparams.c @@ -1209,7 +1209,8 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl) } case SPI_SETLANGTOGGLE: - ERR("SPI_SETLANGTOGGLE is unimplemented\n"); + gdwLanguageToggleKey = UserGetLanguageToggle();; + return gdwLanguageToggleKey; break; case SPI_GETWINDOWSEXTENSION: