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

commit a3c841f8e29b507455e4f432338ce0ffe04e94b0
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Tue Sep 28 22:02:30 2021 +0900
Commit:     GitHub <[email protected]>
CommitDate: Tue Sep 28 22:02:30 2021 +0900

    [IMM32] Implement ImmFreeLayout (#3978)
    
    - Implement ImmFreeLayout function.
    - Add Imm32ReleaseIME helper function.
    CORE-11700
---
 dll/win32/imm32/ime.c      | 114 +++++++++++++++++++++++++++++++++++++++++++++
 dll/win32/imm32/imm32.spec |   2 +-
 2 files changed, 115 insertions(+), 1 deletion(-)

diff --git a/dll/win32/imm32/ime.c b/dll/win32/imm32/ime.c
index 99c675dbfce..3eeb7169b22 100644
--- a/dll/win32/imm32/ime.c
+++ b/dll/win32/imm32/ime.c
@@ -283,6 +283,53 @@ ImeDpi_Escape(PIMEDPI pImeDpi, HIMC hIMC, UINT uSubFunc, 
LPVOID lpData, HKL hKL)
     return 0;
 }
 
+BOOL APIENTRY Imm32ReleaseIME(HKL hKL)
+{
+    BOOL ret = TRUE;
+    PIMEDPI pImeDpi0, pImeDpi1;
+
+    RtlEnterCriticalSection(&g_csImeDpi);
+
+    for (pImeDpi0 = g_pImeDpiList; pImeDpi0; pImeDpi0 = pImeDpi0->pNext)
+    {
+        if (pImeDpi0->hKL == hKL)
+            break;
+    }
+
+    if (!pImeDpi0)
+        goto Quit;
+
+    if (pImeDpi0->cLockObj)
+    {
+        pImeDpi0->dwFlags |= IMEDPI_FLAG_UNKNOWN;
+        ret = FALSE;
+        goto Quit;
+    }
+
+    if (g_pImeDpiList == pImeDpi0)
+    {
+        g_pImeDpiList = pImeDpi0->pNext;
+    }
+    else if (g_pImeDpiList)
+    {
+        for (pImeDpi1 = g_pImeDpiList; pImeDpi1; pImeDpi1 = pImeDpi1->pNext)
+        {
+            if (pImeDpi1->pNext == pImeDpi0)
+            {
+                pImeDpi1->pNext = pImeDpi0->pNext;
+                break;
+            }
+        }
+    }
+
+    Imm32FreeImeDpi(pImeDpi0, TRUE);
+    Imm32HeapFree(pImeDpi0);
+
+Quit:
+    RtlLeaveCriticalSection(&g_csImeDpi);
+    return ret;
+}
+
 /***********************************************************************
  *             ImmIsIME (IMM32.@)
  */
@@ -1456,3 +1503,70 @@ Quit:
     ImmUnlockImeDpi(pImeDpi);
     return ret;
 }
+
+/***********************************************************************
+ *             ImmFreeLayout (IMM32.@)
+ */
+BOOL WINAPI ImmFreeLayout(DWORD dwUnknown)
+{
+    WCHAR szKBD[9];
+    UINT iKL, cKLs;
+    HKL hOldKL, hNewKL, *pList;
+    PIMEDPI pImeDpi;
+    LANGID LangID;
+
+    TRACE("(0x%lX)\n", dwUnknown);
+
+    hOldKL = GetKeyboardLayout(0);
+
+    if (dwUnknown == 1)
+    {
+        if (!IS_IME_HKL(hOldKL))
+            return TRUE;
+
+        LangID = LANGIDFROMLCID(GetSystemDefaultLCID());
+
+        cKLs = GetKeyboardLayoutList(0, NULL);
+        if (cKLs)
+        {
+            pList = Imm32HeapAlloc(0, cKLs * sizeof(HKL));
+            if (pList == NULL)
+                return FALSE;
+
+            cKLs = GetKeyboardLayoutList(cKLs, pList);
+            for (iKL = 0; iKL < cKLs; ++iKL)
+            {
+                if (!IS_IME_HKL(pList[iKL]))
+                {
+                    LangID = LOWORD(pList[iKL]);
+                    break;
+                }
+            }
+
+            Imm32HeapFree(pList);
+        }
+
+        StringCchPrintfW(szKBD, _countof(szKBD), L"%08X", LangID);
+        if (!LoadKeyboardLayoutW(szKBD, KLF_ACTIVATE))
+            LoadKeyboardLayoutW(L"00000409", KLF_ACTIVATE | 0x200);
+    }
+    else if (dwUnknown == 2)
+    {
+        RtlEnterCriticalSection(&g_csImeDpi);
+Retry:
+        for (pImeDpi = g_pImeDpiList; pImeDpi; pImeDpi = pImeDpi->pNext)
+        {
+            if (Imm32ReleaseIME(pImeDpi->hKL))
+                goto Retry;
+        }
+        RtlLeaveCriticalSection(&g_csImeDpi);
+    }
+    else
+    {
+        hNewKL = (HKL)(DWORD_PTR)dwUnknown;
+        if (IS_IME_HKL(hNewKL) && hNewKL != hOldKL)
+            Imm32ReleaseIME(hNewKL);
+    }
+
+    return TRUE;
+}
diff --git a/dll/win32/imm32/imm32.spec b/dll/win32/imm32/imm32.spec
index ba038cbcfb2..221c8a85e80 100644
--- a/dll/win32/imm32/imm32.spec
+++ b/dll/win32/imm32/imm32.spec
@@ -24,7 +24,7 @@
 @ stdcall ImmEnumRegisterWordW(long ptr wstr long wstr ptr)
 @ stdcall ImmEscapeA(long ptr long ptr)
 @ stdcall ImmEscapeW(long ptr long ptr)
-@ stdcall -stub ImmFreeLayout(long)
+@ stdcall ImmFreeLayout(long)
 @ stdcall ImmGenerateMessage(ptr)
 @ stdcall ImmGetCandidateListA(long long ptr long)
 @ stdcall ImmGetCandidateListCountA(long ptr)

Reply via email to