https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a3c841f8e29b507455e4f…
commit a3c841f8e29b507455e4f432338ce0ffe04e94b0
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Tue Sep 28 22:02:30 2021 +0900
Commit: GitHub <noreply(a)github.com>
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)