[NtUser]
authorJames Tabor <james.tabor@reactos.org>
Thu, 11 Aug 2016 15:53:05 +0000 (15:53 +0000)
committerJames Tabor <james.tabor@reactos.org>
Thu, 11 Aug 2016 15:53:05 +0000 (15:53 +0000)
- 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

reactos/win32ss/user/ntuser/input.h
reactos/win32ss/user/ntuser/keyboard.c
reactos/win32ss/user/ntuser/main.c
reactos/win32ss/user/ntuser/misc.c
reactos/win32ss/user/ntuser/msgqueue.c
reactos/win32ss/user/ntuser/ntuser.h
reactos/win32ss/user/ntuser/sysparams.c

index a85c587..715a0b9 100644 (file)
@@ -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);
index 36461d8..18c550a 100644 (file)
@@ -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)
         {
index a784413..c2bce2e 100644 (file)
@@ -1004,6 +1004,8 @@ DriverEntry(
         return Status;
     }
 
+    gdwLanguageToggleKey = UserGetLanguageToggle();
+
     gusLanguageID = UserGetLanguageID();
 
     return STATUS_SUCCESS;
index 519de83..74614b9 100644 (file)
@@ -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)
index a2ee419..e17dbd6 100644 (file)
@@ -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;
 }
index 6856fd4..79af19d 100644 (file)
@@ -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 */
index 0188912..5a193ac 100644 (file)
@@ -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: