https://git.reactos.org/?p=reactos.git;a=commitdiff;h=379188acfeb55efc0dbbc7b5c7f3e7ecf57bbd0b

commit 379188acfeb55efc0dbbc7b5c7f3e7ecf57bbd0b
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Mon Aug 15 08:25:06 2022 +0900
Commit:     GitHub <[email protected]>
CommitDate: Mon Aug 15 08:25:06 2022 +0900

    [NTUSER] Refactor NtUserUnloadKeyboardLayout (#4605)
    
    - Add IntHKLtoPKL, co_UserActivateKeyboardLayout, 
IntReorderKeyboardLayouts, and co_IntActivateKeyboardLayout helper functions.
    - Rewrite NtUserUnloadKeyboardLayout by using helper functions.
    CORE-11700
---
 win32ss/include/ntuser.h        |   2 +-
 win32ss/user/ntuser/kbdlayout.c | 183 +++++++++++++++++++++++++++++-----------
 2 files changed, 135 insertions(+), 50 deletions(-)

diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h
index 924a0bef195..3f0449d2ee6 100644
--- a/win32ss/include/ntuser.h
+++ b/win32ss/include/ntuser.h
@@ -1515,7 +1515,7 @@ NtUserTrackPopupMenuEx(
 HKL
 NTAPI
 NtUserActivateKeyboardLayout(
-    HKL hKl,
+    HKL hKL,
     ULONG Flags);
 
 DWORD
diff --git a/win32ss/user/ntuser/kbdlayout.c b/win32ss/user/ntuser/kbdlayout.c
index 09e0f677f38..c4d97267101 100644
--- a/win32ss/user/ntuser/kbdlayout.c
+++ b/win32ss/user/ntuser/kbdlayout.c
@@ -27,7 +27,71 @@ typedef PVOID (*PFN_KBDLAYERDESCRIPTOR)(VOID);
 
 /* PRIVATE FUNCTIONS ******************************************************/
 
-// Win: _GetKeyboardLayoutList
+/*
+ * Retrieves a PKL by an input locale identifier (HKL).
+ * @implemented
+ * Win: HKLtoPKL
+ */
+PKL FASTCALL IntHKLtoPKL(_Inout_ PTHREADINFO pti, _In_ HKL hKL)
+{
+    PKL pFirstKL, pKL;
+
+    pFirstKL = pti->KeyboardLayout;
+    if (!pFirstKL)
+        return NULL;
+
+    pKL = pFirstKL;
+
+    /* hKL can have special value HKL_NEXT or HKL_PREV */
+    if (hKL == (HKL)(ULONG_PTR)HKL_NEXT) /* Looking forward */
+    {
+        do
+        {
+            pKL = pKL->pklNext;
+            if (!(pKL->dwKL_Flags & KLF_UNLOAD))
+                return pKL;
+        } while (pKL != pFirstKL);
+    }
+    else if (hKL == (HKL)(ULONG_PTR)HKL_PREV) /* Looking backward */
+    {
+        do
+        {
+            pKL = pKL->pklPrev;
+            if (!(pKL->dwKL_Flags & KLF_UNLOAD))
+                return pKL;
+        } while (pKL != pFirstKL);
+    }
+    else if (HIWORD(hKL)) /* hKL is a full input locale identifier */
+    {
+        /* No KLF_UNLOAD check */
+        do
+        {
+            if (pKL->hkl == hKL)
+                return pKL;
+
+            pKL = pKL->pklNext;
+        } while (pKL != pFirstKL);
+    }
+    else  /* Language only specified */
+    {
+        /* No KLF_UNLOAD check */
+        do
+        {
+            if (LOWORD(pKL->hkl) == LOWORD(hKL)) /* Low word is language ID */
+                return pKL;
+
+            pKL = pKL->pklNext;
+        } while (pKL != pFirstKL);
+    }
+
+    return NULL;
+}
+
+/*
+ * A helper function for NtUserGetKeyboardLayoutList.
+ * @implemented
+ * Win: _GetKeyboardLayoutList
+ */
 static UINT APIENTRY
 IntGetKeyboardLayoutList(
     _Inout_ PWINSTATION_OBJECT pWinSta,
@@ -543,6 +607,66 @@ co_UserActivateKbl(PTHREADINFO pti, PKL pKl, UINT Flags)
     return pklPrev;
 }
 
+/* Win: xxxInternalActivateKeyboardLayout */
+HKL APIENTRY
+co_UserActivateKeyboardLayout(
+    _Inout_ PKL     pKL,
+    _In_    ULONG   uFlags,
+    _Inout_ PWND    pWnd)
+{
+    HKL hKL = pKL->hkl;
+    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+
+    if (pKL != pti->KeyboardLayout)
+    {
+        /* Activate layout for current thread */
+        co_UserActivateKbl(pti, pKL, uFlags);
+
+        /* Send shell message */
+        if (!(uFlags & KLF_NOTELLSHELL))
+            co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hKL);
+    }
+
+    /* FIXME: KLF_RESET
+              KLF_SHIFTLOCK */
+
+    return hKL;
+}
+
+// Win: ReorderKeyboardLayouts
+VOID FASTCALL
+IntReorderKeyboardLayouts(
+    _Inout_ PWINSTATION_OBJECT pWinSta,
+    _Inout_ PKL pKL)
+{
+    /* FIXME */
+    gspklBaseLayout = pKL;
+}
+
+/* Win: xxxActivateKeyboardLayout */
+HKL APIENTRY
+co_IntActivateKeyboardLayout(
+    _Inout_ PWINSTATION_OBJECT pWinSta,
+    _In_ HKL hKL,
+    _In_ ULONG uFlags,
+    _Inout_ PWND pWnd)
+{
+    PKL pKL;
+    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+
+    pKL = IntHKLtoPKL(pti, hKL);
+    if (!pKL)
+    {
+        ERR("Invalid HKL %p!\n", hKL);
+        return NULL;
+    }
+
+    if (uFlags & KLF_REORDER)
+        IntReorderKeyboardLayouts(pWinSta, pKL);
+
+    return co_UserActivateKeyboardLayout(pKL, uFlags, pWnd);
+}
+
 /* EXPORTS *******************************************************************/
 
 /*
@@ -821,62 +945,23 @@ cleanup:
  * Activates specified layout for thread or process
  */
 HKL
-APIENTRY
+NTAPI
 NtUserActivateKeyboardLayout(
-    HKL hKl,
+    HKL hKL,
     ULONG Flags)
 {
-    PKL pKl = NULL;
-    HKL hkl = NULL;
-    PTHREADINFO pti;
+    PWINSTATION_OBJECT pWinSta;
+    HKL hOldKL;
 
     UserEnterExclusive();
 
-    pti = PsGetCurrentThreadWin32Thread();
+    /* FIXME */
 
-    /* hKl can have special value HKL_NEXT or HKL_PREV */
-    if (hKl == (HKL)HKL_NEXT)
-    {
-        /* Get next keyboard layout starting with current */
-        if (pti->KeyboardLayout)
-            pKl = pti->KeyboardLayout->pklNext;
-    }
-    else if (hKl == (HKL)HKL_PREV)
-    {
-        /* Get previous keyboard layout starting with current */
-        if (pti->KeyboardLayout)
-            pKl = pti->KeyboardLayout->pklPrev;
-    }
-    else
-        pKl = UserHklToKbl(hKl);
-
-    if (!pKl)
-    {
-        ERR("Invalid HKL %p!\n", hKl);
-        goto cleanup;
-    }
-
-    hkl = pKl->hkl;
-
-    /* FIXME: KLF_RESET
-              KLF_SHIFTLOCK */
-
-    if (Flags & KLF_REORDER)
-        gspklBaseLayout = pKl;
-
-    if (pKl != pti->KeyboardLayout)
-    {
-        /* Activate layout for current thread */
-        pKl = co_UserActivateKbl(pti, pKl, Flags);
-
-        /* Send shell message */
-        if (!(Flags & KLF_NOTELLSHELL))
-            co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hkl);
-    }
-
-cleanup:
+    pWinSta = IntGetProcessWindowStation(NULL);
+    hOldKL = co_IntActivateKeyboardLayout(pWinSta, hKL, Flags, NULL);
     UserLeave();
-    return hkl;
+
+    return hOldKL;
 }
 
 /*

Reply via email to