https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b3382d8d24ac7f9e098ed…
commit b3382d8d24ac7f9e098ed77ec1ce1f2f42d167a8
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Sep 27 09:32:24 2021 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Mon Sep 27 09:32:24 2021 +0900
[IMM32] Rewrite ImmLockIMC (#3975)
- Add Imm32InitContext and Imm32LockIMCEx helper functions.
- Re-implement ImmLockIMC function.
- Modify CLIENTIMC and INPUTCONTEXTDX structures.
CORE-11700
---
dll/win32/imm32/imm.c | 216 +++++++++++++++++++++++++---
dll/win32/imm32/utils.c | 8 +-
modules/rostests/apitests/imm32/clientimc.c | 8 +-
sdk/include/reactos/wine/ddk/imm.h | 10 +-
win32ss/include/ntuser.h | 7 +-
5 files changed, 212 insertions(+), 37 deletions(-)
diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c
index 9fecb94c183..383a395f15e 100644
--- a/dll/win32/imm32/imm.c
+++ b/dll/win32/imm32/imm.c
@@ -354,7 +354,7 @@ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
if (!pClientImc)
return FALSE;
- if (pClientImc->hImc == NULL)
+ if (pClientImc->hInputContext == NULL)
{
pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1;
ImmUnlockClientImc(pClientImc);
@@ -390,11 +390,11 @@ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
pClientImc->hKL = NULL;
}
- ImmDestroyIMCC(pIC->hPrivate);
- ImmDestroyIMCC(pIC->hMsgBuf);
- ImmDestroyIMCC(pIC->hGuideLine);
- ImmDestroyIMCC(pIC->hCandInfo);
- ImmDestroyIMCC(pIC->hCompStr);
+ pIC->hPrivate = ImmDestroyIMCC(pIC->hPrivate);
+ pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
+ pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
+ pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
+ pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
Imm32CleanupContextExtra(pIC);
@@ -409,6 +409,182 @@ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
return TRUE;
}
+BOOL APIENTRY
+Imm32InitContext(HIMC hIMC, LPINPUTCONTEXT pIC, PCLIENTIMC pClientImc, HKL hKL, BOOL
fSelect)
+{
+ DWORD dwIndex, cbPrivate;
+ PIMEDPI pImeDpi = NULL;
+ LPCOMPOSITIONSTRING pCS;
+ LPCANDIDATEINFO pCI;
+ LPGUIDELINE pGL;
+ /* NOTE: Windows does recursive call ImmLockIMC here but we don't do so. */
+
+ /* Create IC components */
+ pIC->hCompStr = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
+ pIC->hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
+ pIC->hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
+ pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
+ if (!pIC->hCompStr || !pIC->hCandInfo || !pIC->hGuideLine ||
!pIC->hMsgBuf)
+ goto Fail;
+
+ /* Initialize IC components */
+ pCS = ImmLockIMCC(pIC->hCompStr);
+ if (!pCS)
+ goto Fail;
+ pCS->dwSize = sizeof(COMPOSITIONSTRING);
+ ImmUnlockIMCC(pIC->hCompStr);
+
+ pCI = ImmLockIMCC(pIC->hCandInfo);
+ if (!pCI)
+ goto Fail;
+ pCI->dwSize = sizeof(CANDIDATEINFO);
+ ImmUnlockIMCC(pIC->hCandInfo);
+
+ pGL = ImmLockIMCC(pIC->hGuideLine);
+ if (!pGL)
+ goto Fail;
+ pGL->dwSize = sizeof(GUIDELINE);
+ ImmUnlockIMCC(pIC->hGuideLine);
+
+ pIC->dwNumMsgBuf = 0;
+ pIC->fOpen = FALSE;
+ pIC->fdwConversion = pIC->fdwSentence = 0;
+
+ for (dwIndex = 0; dwIndex < MAX_CANDIDATEFORM; ++dwIndex)
+ pIC->cfCandForm[dwIndex].dwIndex = IMM_INVALID_CANDFORM;
+
+ /* Get private data size */
+ pImeDpi = ImmLockImeDpi(hKL);
+ if (!pImeDpi)
+ {
+ cbPrivate = sizeof(DWORD);
+ }
+ else
+ {
+ /* Update CLIENTIMC */
+ pClientImc->uCodePage = pImeDpi->uCodePage;
+ if (ImeDpi_IsUnicode(pImeDpi))
+ pClientImc->dwFlags |= CLIENTIMC_WIDE;
+
+ cbPrivate = pImeDpi->ImeInfo.dwPrivateDataSize;
+ }
+
+ /* Create private data */
+ pIC->hPrivate = ImmCreateIMCC(cbPrivate);
+ if (!pIC->hPrivate)
+ goto Fail;
+
+ if (pImeDpi)
+ {
+ /* Select the IME */
+ if (fSelect)
+ {
+ if (IS_IME_HKL(hKL))
+ pImeDpi->ImeSelect(hIMC, TRUE);
+ else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() &&
pImeDpi->CtfImeSelectEx)
+ pImeDpi->CtfImeSelectEx(hIMC, TRUE, hKL);
+ }
+
+ /* Set HKL */
+ pClientImc->hKL = hKL;
+
+ ImmUnlockImeDpi(pImeDpi);
+ }
+
+ return TRUE;
+
+Fail:
+ if (pImeDpi)
+ ImmUnlockImeDpi(pImeDpi);
+
+ pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
+ pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
+ pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
+ pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
+ return FALSE;
+}
+
+LPINPUTCONTEXT APIENTRY Imm32LockIMCEx(HIMC hIMC, BOOL fSelect)
+{
+ HANDLE hIC;
+ LPINPUTCONTEXT pIC = NULL;
+ PCLIENTIMC pClientImc;
+ WORD Word;
+ DWORD dwThreadId;
+ HKL hKL, hNewKL;
+ PIMEDPI pImeDpi = NULL;
+ BOOL bInited;
+
+ pClientImc = ImmLockClientImc(hIMC);
+ if (!pClientImc)
+ return NULL;
+
+ RtlEnterCriticalSection(&pClientImc->cs);
+
+ if (!pClientImc->hInputContext)
+ {
+ dwThreadId = (DWORD)NtUserQueryInputContext(hIMC, 1);
+
+ if (dwThreadId == GetCurrentThreadId() && Imm32IsCiceroMode() &&
!Imm32Is16BitMode())
+ {
+ hKL = GetKeyboardLayout(0);
+ Word = LOWORD(hKL);
+ hNewKL = (HKL)(DWORD_PTR)MAKELONG(Word, Word);
+
+ pImeDpi = ImmLockOrLoadImeDpi(hNewKL);
+ if (pImeDpi)
+ {
+ FIXME("We have to do something here\n");
+ }
+ }
+
+ if (!NtUserQueryInputContext(hIMC, 2))
+ {
+ RtlLeaveCriticalSection(&pClientImc->cs);
+ goto Quit;
+ }
+
+ hIC = LocalAlloc(LHND, sizeof(INPUTCONTEXTDX));
+ if (!hIC)
+ {
+ RtlLeaveCriticalSection(&pClientImc->cs);
+ goto Quit;
+ }
+ pClientImc->hInputContext = hIC;
+
+ pIC = LocalLock(pClientImc->hInputContext);
+ if (!pIC)
+ {
+ pClientImc->hInputContext = LocalFree(pClientImc->hInputContext);
+ RtlLeaveCriticalSection(&pClientImc->cs);
+ goto Quit;
+ }
+
+ hKL = GetKeyboardLayout(dwThreadId);
+ // bInited = Imm32InitContext(hIMC, hKL, fSelect);
+ bInited = Imm32InitContext(hIMC, pIC, pClientImc, hKL, fSelect);
+ LocalUnlock(pClientImc->hInputContext);
+
+ if (!bInited)
+ {
+ pIC = NULL;
+ pClientImc->hInputContext = LocalFree(pClientImc->hInputContext);
+ RtlLeaveCriticalSection(&pClientImc->cs);
+ goto Quit;
+ }
+ }
+
+ FIXME("We have to do something here\n");
+
+ RtlLeaveCriticalSection(&pClientImc->cs);
+ pIC = LocalLock(pClientImc->hInputContext);
+ InterlockedIncrement(&pClientImc->cLockObj);
+
+Quit:
+ ImmUnlockClientImc(pClientImc);
+ return pIC;
+}
+
/***********************************************************************
* ImmDestroyContext (IMM32.@)
*/
@@ -481,7 +657,7 @@ PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
{
LONG cLocks;
- HIMC hImc;
+ HANDLE hInputContext;
TRACE("(%p)\n", pClientImc);
@@ -489,9 +665,9 @@ VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
if (cLocks != 0 || !(pClientImc->dwFlags & CLIENTIMC_UNKNOWN1))
return;
- hImc = pClientImc->hImc;
- if (hImc)
- LocalFree(hImc);
+ hInputContext = pClientImc->hInputContext;
+ if (hInputContext)
+ LocalFree(hInputContext);
RtlDeleteCriticalSection(&pClientImc->cs);
Imm32HeapFree(pClientImc);
@@ -925,16 +1101,14 @@ HKL WINAPI ImmInstallIMEW(LPCWSTR lpszIMEFileName, LPCWSTR
lpszLayoutText)
}
/***********************************************************************
-* ImmLockIMC(IMM32.@)
-*/
+ * ImmLockIMC(IMM32.@)
+ *
+ * NOTE: This is not ImmLockIMCC. Don't confuse.
+ */
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
{
- InputContextData *data = get_imc_data(hIMC);
-
- if (!data)
- return NULL;
- data->dwLock++;
- return &data->IMC;
+ TRACE("(%p)\n", hIMC);
+ return Imm32LockIMCEx(hIMC, TRUE);
}
/***********************************************************************
@@ -943,15 +1117,13 @@ LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
{
PCLIENTIMC pClientImc;
- HIMC hClientImc;
pClientImc = ImmLockClientImc(hIMC);
if (pClientImc == NULL)
return FALSE;
- hClientImc = pClientImc->hImc;
- if (hClientImc)
- LocalUnlock(hClientImc);
+ if (pClientImc->hInputContext)
+ LocalUnlock(pClientImc->hInputContext);
InterlockedDecrement(&pClientImc->cLockObj);
ImmUnlockClientImc(pClientImc);
diff --git a/dll/win32/imm32/utils.c b/dll/win32/imm32/utils.c
index 17a7efb5179..64bd3d158be 100644
--- a/dll/win32/imm32/utils.c
+++ b/dll/win32/imm32/utils.c
@@ -276,7 +276,7 @@ DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
{
DWORD ret;
- HIMC hClientImc;
+ HANDLE hInputContext;
PCLIENTIMC pClientImc;
pClientImc = ImmLockClientImc(hIMC);
@@ -284,9 +284,9 @@ DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
return 0;
ret = 0;
- hClientImc = pClientImc->hImc;
- if (hClientImc)
- ret = (LocalFlags(hClientImc) & LMEM_LOCKCOUNT);
+ hInputContext = pClientImc->hInputContext;
+ if (hInputContext)
+ ret = (LocalFlags(hInputContext) & LMEM_LOCKCOUNT);
ImmUnlockClientImc(pClientImc);
return ret;
diff --git a/modules/rostests/apitests/imm32/clientimc.c
b/modules/rostests/apitests/imm32/clientimc.c
index 0f43024efd0..f0080c8112e 100644
--- a/modules/rostests/apitests/imm32/clientimc.c
+++ b/modules/rostests/apitests/imm32/clientimc.c
@@ -24,15 +24,15 @@ START_TEST(clientimc)
DWORD dwCode;
CLIENTIMC *pClientImc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(CLIENTIMC));
- pClientImc->hImc = (HIMC)ImmCreateIMCC(4);
+ pClientImc->hInputContext = (HANDLE)ImmCreateIMCC(4);
pClientImc->cLockObj = 2;
pClientImc->dwFlags = 0x40;
RtlInitializeCriticalSection(&pClientImc->cs);
- ok_long(ImmGetIMCCSize((HIMCC)pClientImc->hImc), 4);
+ ok_long(ImmGetIMCCSize((HIMCC)pClientImc->hInputContext), 4);
ImmUnlockClientImc(pClientImc);
ok_long(pClientImc->cLockObj, 1);
- ok_long(ImmGetIMCCSize((HIMCC)pClientImc->hImc), 4);
+ ok_long(ImmGetIMCCSize((HIMCC)pClientImc->hInputContext), 4);
dwCode = 0;
_SEH2_TRY
@@ -47,7 +47,7 @@ START_TEST(clientimc)
ok_long(dwCode, STATUS_ACCESS_VIOLATION);
ok_long(pClientImc->cLockObj, 0);
- ok_long(ImmGetIMCCSize((HIMCC)pClientImc->hImc), 0);
+ ok_long(ImmGetIMCCSize((HIMCC)pClientImc->hInputContext), 0);
HeapFree(GetProcessHeap(), 0, pClientImc);
}
diff --git a/sdk/include/reactos/wine/ddk/imm.h b/sdk/include/reactos/wine/ddk/imm.h
index f5b45fc6d1a..842c7cac015 100644
--- a/sdk/include/reactos/wine/ddk/imm.h
+++ b/sdk/include/reactos/wine/ddk/imm.h
@@ -92,17 +92,19 @@ typedef struct INPUTCONTEXTDX /* unconfirmed */
INPUTCONTEXT;
UINT nVKey;
BOOL bNeedsTrans;
- DWORD dwUnknownCat;
+ DWORD dwUnknown1;
DWORD dwUIFlags;
- DWORD dwUnknownDog;
- void *pUnknownFox;
- /* ... */
+ DWORD dwUnknown2;
+ void *pUnknown3;
+ DWORD dwUnknown4;
+ DWORD dwUnknown5;
} INPUTCONTEXTDX, *LPINPUTCONTEXTDX;
#ifndef _WIN64
C_ASSERT(offsetof(INPUTCONTEXTDX, nVKey) == 0x140);
C_ASSERT(offsetof(INPUTCONTEXTDX, bNeedsTrans) == 0x144);
C_ASSERT(offsetof(INPUTCONTEXTDX, dwUIFlags) == 0x14c);
+C_ASSERT(sizeof(INPUTCONTEXTDX) == 0x160);
#endif
// bits of fdwInit of INPUTCONTEXT
diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h
index 6d463ddb69a..482ea232926 100644
--- a/win32ss/include/ntuser.h
+++ b/win32ss/include/ntuser.h
@@ -1290,21 +1290,22 @@ C_ASSERT(sizeof(IMEDPI) == 0xa8);
/* unconfirmed */
typedef struct tagCLIENTIMC
{
- HIMC hImc;
+ HANDLE hInputContext; /* LocalAlloc'ed LHND */
LONG cLockObj;
DWORD dwFlags;
DWORD unknown;
RTL_CRITICAL_SECTION cs;
- DWORD unknown2;
+ UINT uCodePage;
HKL hKL;
BOOL bUnknown4;
} CLIENTIMC, *PCLIENTIMC;
#ifndef _WIN64
-C_ASSERT(offsetof(CLIENTIMC, hImc) == 0x0);
+C_ASSERT(offsetof(CLIENTIMC, hInputContext) == 0x0);
C_ASSERT(offsetof(CLIENTIMC, cLockObj) == 0x4);
C_ASSERT(offsetof(CLIENTIMC, dwFlags) == 0x8);
C_ASSERT(offsetof(CLIENTIMC, cs) == 0x10);
+C_ASSERT(offsetof(CLIENTIMC, uCodePage) == 0x28);
C_ASSERT(offsetof(CLIENTIMC, hKL) == 0x2c);
C_ASSERT(sizeof(CLIENTIMC) == 0x34);
#endif