https://git.reactos.org/?p=reactos.git;a=commitdiff;h=66ef31494e4a9da8a1bd6…
commit 66ef31494e4a9da8a1bd688a631f4a02f2fcf1da
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Oct 4 07:33:15 2021 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Mon Oct 4 07:33:15 2021 +0900
[IMM32] Implement ImmActivateLayout (#3987)
- Add IME_STATE and IME_SUBSTATE structures.
- Modify INPUTCONTEXTDX structure.
- Implement ImmActivateLayout function.
- Improve ImmDestroyContext function by using newly-defined Imm32FreeImeStates.
- Add Imm32FetchImeState, Imm32FetchImeSubState, Imm32LoadImeStateSentence,
Imm32SaveImeStateSentence, and Imm32SelectLayout helper functions.
- Modify NtUserSetThreadLayoutHandles prototype.
CORE-11700
---
dll/win32/imm32/ime.c | 8 -
dll/win32/imm32/imm.c | 332 ++++++++++++++++++++++++++++++++++++-
dll/win32/imm32/imm32.spec | 2 +-
dll/win32/imm32/precomp.h | 9 +
dll/win32/imm32/utils.c | 74 +++++++++
sdk/include/psdk/imm.h | 2 +
sdk/include/reactos/wine/ddk/imm.h | 40 ++++-
win32ss/include/ntuser.h | 4 +-
win32ss/user/ntuser/ntstubs.c | 4 +-
9 files changed, 453 insertions(+), 22 deletions(-)
diff --git a/dll/win32/imm32/ime.c b/dll/win32/imm32/ime.c
index e831a81fcee..02b47bd1b88 100644
--- a/dll/win32/imm32/ime.c
+++ b/dll/win32/imm32/ime.c
@@ -533,14 +533,6 @@ BOOL WINAPI ImmDisableLegacyIME(void)
return TRUE;
}
-/***********************************************************************
- * CtfImmIsTextFrameServiceDisabled(IMM32.@)
- */
-BOOL WINAPI CtfImmIsTextFrameServiceDisabled(VOID)
-{
- return !!(GetWin32ClientInfo()->CI_flags & CI_TFSDISABLED);
-}
-
/***********************************************************************
* ImmGetImeInfoEx (IMM32.@)
*/
diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c
index f458685e0ec..c840cdf3ee7 100644
--- a/dll/win32/imm32/imm.c
+++ b/dll/win32/imm32/imm.c
@@ -168,6 +168,314 @@ Retry:
return TRUE;
}
+VOID APIENTRY Imm32SelectLayout(HKL hNewKL, HKL hOldKL, HIMC hIMC)
+{
+ PCLIENTIMC pClientImc;
+ LPINPUTCONTEXTDX pIC;
+ LPGUIDELINE pGL;
+ LPCANDIDATEINFO pCI;
+ LPCOMPOSITIONSTRING pCS;
+ LOGFONTA LogFontA;
+ LOGFONTW LogFontW;
+ BOOL fOpen, bIsNewHKLIme = TRUE, bIsOldHKLIme = TRUE, bClientWide, bNewDpiWide;
+ DWORD cbNewPrivate = 0, cbOldPrivate = 0, dwConversion, dwSentence, dwSize,
dwNewSize;
+ PIMEDPI pNewImeDpi = NULL, pOldImeDpi = NULL;
+ HANDLE hPrivate;
+ PIME_STATE pNewState = NULL, pOldState = NULL;
+
+ pClientImc = ImmLockClientImc(hIMC);
+ if (!pClientImc)
+ return;
+
+ pNewImeDpi = ImmLockImeDpi(hNewKL);
+
+ if (hNewKL != hOldKL)
+ pOldImeDpi = ImmLockImeDpi(hOldKL);
+
+ if (pNewImeDpi)
+ {
+ cbNewPrivate = pNewImeDpi->ImeInfo.dwPrivateDataSize;
+ pClientImc->uCodePage = pNewImeDpi->uCodePage;
+ }
+ else
+ {
+ pClientImc->uCodePage = CP_ACP;
+ }
+
+ if (cbNewPrivate < 4)
+ cbNewPrivate = 4;
+
+ if (pOldImeDpi)
+ cbOldPrivate = pOldImeDpi->ImeInfo.dwPrivateDataSize;
+
+ if (cbOldPrivate < 4)
+ cbOldPrivate = 4;
+
+ if (pClientImc->hKL == hOldKL)
+ {
+ if (pOldImeDpi)
+ {
+ if (IS_IME_HKL(hOldKL))
+ pOldImeDpi->ImeSelect(hIMC, FALSE);
+ else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() &&
pOldImeDpi->CtfImeSelectEx)
+ pOldImeDpi->CtfImeSelectEx(hIMC, FALSE, hOldKL);
+ }
+ pClientImc->hKL = NULL;
+ }
+
+ if (CtfImmIsTextFrameServiceDisabled())
+ {
+ if (Imm32IsImmMode() && !Imm32IsCiceroMode())
+ {
+ bIsNewHKLIme = IS_IME_HKL(hNewKL);
+ bIsOldHKLIme = IS_IME_HKL(hOldKL);
+ }
+ }
+
+ pIC = (LPINPUTCONTEXTDX)Imm32LockIMCEx(hIMC, FALSE);
+ if (!pIC)
+ {
+ if (pNewImeDpi)
+ {
+ if (IS_IME_HKL(hNewKL))
+ pNewImeDpi->ImeSelect(hIMC, TRUE);
+ else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() &&
pNewImeDpi->CtfImeSelectEx)
+ pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
+
+ pClientImc->hKL = hNewKL;
+ }
+ }
+ else
+ {
+ dwConversion = pIC->fdwConversion;
+ dwSentence = pIC->fdwSentence;
+ fOpen = pIC->fOpen;
+
+ if (pNewImeDpi)
+ {
+ bClientWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
+ bNewDpiWide = ImeDpi_IsUnicode(pNewImeDpi);
+ if (bClientWide && !bNewDpiWide)
+ {
+ if (pIC->fdwInit & INIT_LOGFONT)
+ {
+ LogFontWideToAnsi(&pIC->lfFont.W, &LogFontA);
+ pIC->lfFont.A = LogFontA;
+ }
+ pClientImc->dwFlags &= ~CLIENTIMC_WIDE;
+ }
+ else if (!bClientWide && bNewDpiWide)
+ {
+ if (pIC->fdwInit & INIT_LOGFONT)
+ {
+ LogFontAnsiToWide(&pIC->lfFont.A, &LogFontW);
+ pIC->lfFont.W = LogFontW;
+ }
+ pClientImc->dwFlags |= CLIENTIMC_WIDE;
+ }
+ }
+
+ if (cbOldPrivate != cbNewPrivate)
+ {
+ hPrivate = ImmReSizeIMCC(pIC->hPrivate, cbNewPrivate);
+ if (!hPrivate)
+ {
+ ImmDestroyIMCC(pIC->hPrivate);
+ hPrivate = ImmCreateIMCC(cbNewPrivate);
+ }
+ pIC->hPrivate = hPrivate;
+ }
+
+#define MAX_IMCC_SIZE 0x1000
+ dwSize = ImmGetIMCCSize(pIC->hMsgBuf);
+ if (ImmGetIMCCLockCount(pIC->hMsgBuf) || dwSize > MAX_IMCC_SIZE)
+ {
+ ImmDestroyIMCC(pIC->hMsgBuf);
+ pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
+ pIC->dwNumMsgBuf = 0;
+ }
+
+ dwSize = ImmGetIMCCSize(pIC->hGuideLine);
+ dwNewSize = sizeof(GUIDELINE);
+ if (ImmGetIMCCLockCount(pIC->hGuideLine) ||
+ dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
+ {
+ ImmDestroyIMCC(pIC->hGuideLine);
+ pIC->hGuideLine = ImmCreateIMCC(dwNewSize);
+ pGL = ImmLockIMCC(pIC->hGuideLine);
+ if (pGL)
+ {
+ pGL->dwSize = dwNewSize;
+ ImmUnlockIMCC(pIC->hGuideLine);
+ }
+ }
+
+ dwSize = ImmGetIMCCSize(pIC->hCandInfo);
+ dwNewSize = sizeof(CANDIDATEINFO);
+ if (ImmGetIMCCLockCount(pIC->hCandInfo) ||
+ dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
+ {
+ ImmDestroyIMCC(pIC->hCandInfo);
+ pIC->hCandInfo = ImmCreateIMCC(dwNewSize);
+ pCI = ImmLockIMCC(pIC->hCandInfo);
+ if (pCI)
+ {
+ pCI->dwSize = dwNewSize;
+ ImmUnlockIMCC(pIC->hCandInfo);
+ }
+ }
+
+ dwSize = ImmGetIMCCSize(pIC->hCompStr);
+ dwNewSize = sizeof(COMPOSITIONSTRING);
+ if (ImmGetIMCCLockCount(pIC->hCompStr) ||
+ dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
+ {
+ ImmDestroyIMCC(pIC->hCompStr);
+ pIC->hCompStr = ImmCreateIMCC(dwNewSize);
+ pCS = ImmLockIMCC(pIC->hCompStr);
+ if (pCS)
+ {
+ pCS->dwSize = dwNewSize;
+ ImmUnlockIMCC(pIC->hCompStr);
+ }
+ }
+#undef MAX_IMCC_SIZE
+
+ if (pOldImeDpi && bIsOldHKLIme)
+ {
+ pOldState = Imm32FetchImeState(pIC, hOldKL);
+ if (pOldState)
+ Imm32SaveImeStateSentence(pIC, pOldState, hOldKL);
+ }
+
+ if (pNewImeDpi && bIsNewHKLIme)
+ pNewState = Imm32FetchImeState(pIC, hNewKL);
+
+ if (pOldState != pNewState)
+ {
+ if (pOldState)
+ {
+ pOldState->fOpen = !!pIC->fOpen;
+ pOldState->dwConversion = (pIC->fdwConversion &
~IME_CMODE_EUDC);
+ pOldState->dwSentence = pIC->fdwSentence;
+ pOldState->dwInit = pIC->fdwInit;
+ }
+
+ if (pNewState)
+ {
+ if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_FORCE_OPEN)
+ {
+ pIC->dwChange &= ~INPUTCONTEXTDX_CHANGE_FORCE_OPEN;
+ pIC->fOpen = TRUE;
+ }
+ else
+ {
+ pIC->fOpen = pNewState->fOpen;
+ }
+
+ pIC->fdwConversion = (pNewState->dwConversion &
~IME_CMODE_EUDC);
+ pIC->fdwSentence = pNewState->dwSentence;
+ pIC->fdwInit = pNewState->dwInit;
+ }
+ }
+
+ if (pNewState)
+ Imm32LoadImeStateSentence(pIC, pNewState, hNewKL);
+
+ if (pNewImeDpi)
+ {
+ if (IS_IME_HKL(hNewKL))
+ pNewImeDpi->ImeSelect(hIMC, TRUE);
+ else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() &&
pNewImeDpi->CtfImeSelectEx)
+ pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
+
+ pClientImc->hKL = hNewKL;
+ }
+
+ pIC->dwChange = 0;
+ if (pIC->fOpen != fOpen)
+ pIC->dwChange |= INPUTCONTEXTDX_CHANGE_OPEN;
+ if (pIC->fdwConversion != dwConversion)
+ pIC->dwChange |= INPUTCONTEXTDX_CHANGE_CONVERSION;
+ if (pIC->fdwSentence != dwSentence)
+ pIC->dwChange |= INPUTCONTEXTDX_CHANGE_SENTENCE;
+
+ ImmUnlockIMC(hIMC);
+ }
+
+ ImmUnlockImeDpi(pOldImeDpi);
+ ImmUnlockImeDpi(pNewImeDpi);
+ ImmUnlockClientImc(pClientImc);
+}
+
+typedef struct SELECT_LAYOUT
+{
+ HKL hNewKL;
+ HKL hOldKL;
+} SELECT_LAYOUT, *LPSELECT_LAYOUT;
+
+static BOOL CALLBACK Imm32SelectLayoutProc(HIMC hIMC, LPARAM lParam)
+{
+ LPSELECT_LAYOUT pSelect = (LPSELECT_LAYOUT)lParam;
+ Imm32SelectLayout(pSelect->hNewKL, pSelect->hOldKL, hIMC);
+ return TRUE;
+}
+
+static BOOL CALLBACK Imm32NotifyCompStrProc(HIMC hIMC, LPARAM lParam)
+{
+ ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, (DWORD)lParam, 0);
+ return TRUE;
+}
+
+/***********************************************************************
+ * ImmActivateLayout (IMM32.@)
+ */
+BOOL WINAPI ImmActivateLayout(HKL hKL)
+{
+ PIMEDPI pImeDpi;
+ HKL hOldKL;
+ LPARAM lParam;
+ HWND hwndDefIME = NULL;
+ SELECT_LAYOUT SelectLayout;
+
+ hOldKL = GetKeyboardLayout(0);
+
+ if (hOldKL == hKL && !(GetWin32ClientInfo()->CI_flags &
CI_IMMACTIVATE))
+ return TRUE;
+
+ ImmLoadIME(hKL);
+
+ if (hOldKL != hKL)
+ {
+ pImeDpi = ImmLockImeDpi(hOldKL);
+ if (pImeDpi)
+ {
+ if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT)
+ lParam = CPS_COMPLETE;
+ else
+ lParam = CPS_CANCEL;
+ ImmUnlockImeDpi(pImeDpi);
+
+ ImmEnumInputContext(0, Imm32NotifyCompStrProc, lParam);
+ }
+
+ hwndDefIME = ImmGetDefaultIMEWnd(NULL);
+ if (IsWindow(hwndDefIME))
+ SendMessageW(hwndDefIME, WM_IME_SELECT, FALSE, (LPARAM)hOldKL);
+
+ NtUserSetThreadLayoutHandles(hKL, hOldKL);
+ }
+
+ SelectLayout.hNewKL = hKL;
+ SelectLayout.hOldKL = hOldKL;
+ ImmEnumInputContext(0, Imm32SelectLayoutProc, (LPARAM)&SelectLayout);
+
+ if (IsWindow(hwndDefIME))
+ SendMessageW(hwndDefIME, WM_IME_SELECT, TRUE, (LPARAM)hKL);
+
+ return TRUE;
+}
+
typedef struct _tagImmHkl
{
struct list entry;
@@ -362,15 +670,29 @@ HIMC WINAPI ImmCreateContext(void)
return hIMC;
}
-static VOID APIENTRY Imm32CleanupContextExtra(LPINPUTCONTEXT pIC)
+static VOID APIENTRY Imm32FreeImeStates(LPINPUTCONTEXTDX pIC)
{
- FIXME("We have to do something do here");
+ PIME_STATE pState, pStateNext;
+ PIME_SUBSTATE pSubState, pSubStateNext;
+
+ pState = pIC->pState;
+ pIC->pState = NULL;
+ for (; pState; pState = pStateNext)
+ {
+ pStateNext = pState->pNext;
+ for (pSubState = pState->pSubState; pSubState; pSubState = pSubStateNext)
+ {
+ pSubStateNext = pSubState->pNext;
+ Imm32HeapFree(pSubState);
+ }
+ Imm32HeapFree(pState);
+ }
}
BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
{
PIMEDPI pImeDpi;
- LPINPUTCONTEXT pIC;
+ LPINPUTCONTEXTDX pIC;
PCLIENTIMC pClientImc;
PIMC pIMC;
@@ -394,7 +716,7 @@ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
return TRUE;
}
- pIC = ImmLockIMC(hIMC);
+ pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
if (pIC == NULL)
{
ImmUnlockClientImc(pClientImc);
@@ -427,7 +749,7 @@ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
- Imm32CleanupContextExtra(pIC);
+ Imm32FreeImeStates(pIC);
ImmUnlockIMC(hIMC);
diff --git a/dll/win32/imm32/imm32.spec b/dll/win32/imm32/imm32.spec
index 221c8a85e80..162d3d0c4ff 100644
--- a/dll/win32/imm32/imm32.spec
+++ b/dll/win32/imm32/imm32.spec
@@ -4,7 +4,7 @@
@ stdcall -stub CtfImmRestoreToolbarWnd(long)
@ stdcall -stub CtfImmHideToolbarWnd()
@ stdcall -stub CtfImmDispatchDefImeMessage(ptr long ptr ptr)
-@ stdcall -stub ImmActivateLayout(long)
+@ stdcall ImmActivateLayout(ptr)
@ stdcall ImmAssociateContext(ptr ptr)
@ stdcall ImmAssociateContextEx(ptr ptr long)
@ stdcall ImmConfigureIMEA(ptr ptr long ptr)
diff --git a/dll/win32/imm32/precomp.h b/dll/win32/imm32/precomp.h
index c5522127cc3..caaf30c1c09 100644
--- a/dll/win32/imm32/precomp.h
+++ b/dll/win32/imm32/precomp.h
@@ -81,6 +81,7 @@ LPVOID APIENTRY Imm32HeapAlloc(DWORD dwFlags, DWORD dwBytes);
LPWSTR APIENTRY Imm32WideFromAnsi(LPCSTR pszA);
LPSTR APIENTRY Imm32AnsiFromWide(LPCWSTR pszW);
PIMEDPI APIENTRY ImmLockOrLoadImeDpi(HKL hKL);
+LPINPUTCONTEXT APIENTRY Imm32LockIMCEx(HIMC hIMC, BOOL fSelect);
BOOL APIENTRY Imm32ReleaseIME(HKL hKL);
static inline BOOL Imm32IsCrossThreadAccess(HIMC hIMC)
@@ -122,3 +123,11 @@ Imm32ImeMenuAnsiToWide(const IMEMENUITEMINFOA *pItemA,
LPIMEMENUITEMINFOW pItemW
INT APIENTRY
Imm32ImeMenuWideToAnsi(const IMEMENUITEMINFOW *pItemW, LPIMEMENUITEMINFOA pItemA,
UINT uCodePage);
+
+PIME_STATE APIENTRY Imm32FetchImeState(LPINPUTCONTEXTDX pIC, HKL hKL);
+PIME_SUBSTATE APIENTRY Imm32FetchImeSubState(PIME_STATE pState, HKL hKL);
+
+BOOL APIENTRY
+Imm32LoadImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL);
+BOOL APIENTRY
+Imm32SaveImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL);
diff --git a/dll/win32/imm32/utils.c b/dll/win32/imm32/utils.c
index 40512338d22..5be74913595 100644
--- a/dll/win32/imm32/utils.c
+++ b/dll/win32/imm32/utils.c
@@ -262,6 +262,80 @@ Imm32ImeMenuWideToAnsi(const IMEMENUITEMINFOW *pItemW,
LPIMEMENUITEMINFOA pItemA
return ret;
}
+PIME_STATE APIENTRY
+Imm32FetchImeState(LPINPUTCONTEXTDX pIC, HKL hKL)
+{
+ PIME_STATE pState;
+ WORD Lang = PRIMARYLANGID(LOWORD(hKL));
+ for (pState = pIC->pState; pState; pState = pState->pNext)
+ {
+ if (pState->wLang == Lang)
+ break;
+ }
+ if (!pState)
+ {
+ pState = Imm32HeapAlloc(HEAP_ZERO_MEMORY, sizeof(IME_STATE));
+ if (pState)
+ {
+ pState->wLang = Lang;
+ pState->pNext = pIC->pState;
+ pIC->pState = pState;
+ }
+ }
+ return pState;
+}
+
+PIME_SUBSTATE APIENTRY
+Imm32FetchImeSubState(PIME_STATE pState, HKL hKL)
+{
+ PIME_SUBSTATE pSubState;
+ for (pSubState = pState->pSubState; pSubState; pSubState = pSubState->pNext)
+ {
+ if (pSubState->hKL == hKL)
+ return pSubState;
+ }
+ pSubState = Imm32HeapAlloc(0, sizeof(IME_SUBSTATE));
+ if (!pSubState)
+ return NULL;
+ pSubState->dwValue = 0;
+ pSubState->hKL = hKL;
+ pSubState->pNext = pState->pSubState;
+ pState->pSubState = pSubState;
+ return pSubState;
+}
+
+BOOL APIENTRY
+Imm32LoadImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL)
+{
+ PIME_SUBSTATE pSubState = Imm32FetchImeSubState(pState, hKL);
+ if (pSubState)
+ {
+ pIC->fdwSentence |= pSubState->dwValue;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL APIENTRY
+Imm32SaveImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL)
+{
+ PIME_SUBSTATE pSubState = Imm32FetchImeSubState(pState, hKL);
+ if (pSubState)
+ {
+ pSubState->dwValue = (pIC->fdwSentence & 0xffff0000);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ * CtfImmIsTextFrameServiceDisabled(IMM32.@)
+ */
+BOOL WINAPI CtfImmIsTextFrameServiceDisabled(VOID)
+{
+ return !!(GetWin32ClientInfo()->CI_flags & CI_TFSDISABLED);
+}
+
/***********************************************************************
* ImmCreateIMCC(IMM32.@)
*/
diff --git a/sdk/include/psdk/imm.h b/sdk/include/psdk/imm.h
index 14458e26203..fb7032181a7 100644
--- a/sdk/include/psdk/imm.h
+++ b/sdk/include/psdk/imm.h
@@ -635,6 +635,8 @@ BOOL WINAPI ImmSetActiveContext(HWND hwnd, HIMC hIMC, BOOL fFlag);
BOOL WINAPI ImmDestroyContext(_In_ HIMC hIMC);
BOOL WINAPI ImmDisableIME(_In_ DWORD idThread);
BOOL WINAPI ImmEnumInputContext(_In_ DWORD, _In_ IMCENUMPROC, _In_ LPARAM);
+BOOL WINAPI ImmLoadIME(HKL hKL);
+BOOL WINAPI CtfImmIsTextFrameServiceDisabled(VOID);
UINT
WINAPI
diff --git a/sdk/include/reactos/wine/ddk/imm.h b/sdk/include/reactos/wine/ddk/imm.h
index 842c7cac015..33ed8e49a82 100644
--- a/sdk/include/reactos/wine/ddk/imm.h
+++ b/sdk/include/reactos/wine/ddk/imm.h
@@ -87,6 +87,8 @@ C_ASSERT(offsetof(INPUTCONTEXT, dwReserve) == 0x134);
C_ASSERT(sizeof(INPUTCONTEXT) == 0x140);
#endif
+struct IME_STATE;
+
typedef struct INPUTCONTEXTDX /* unconfirmed */
{
INPUTCONTEXT;
@@ -95,8 +97,8 @@ typedef struct INPUTCONTEXTDX /* unconfirmed */
DWORD dwUnknown1;
DWORD dwUIFlags;
DWORD dwUnknown2;
- void *pUnknown3;
- DWORD dwUnknown4;
+ struct IME_STATE *pState;
+ DWORD dwChange;
DWORD dwUnknown5;
} INPUTCONTEXTDX, *LPINPUTCONTEXTDX;
@@ -104,6 +106,8 @@ typedef struct INPUTCONTEXTDX /* unconfirmed */
C_ASSERT(offsetof(INPUTCONTEXTDX, nVKey) == 0x140);
C_ASSERT(offsetof(INPUTCONTEXTDX, bNeedsTrans) == 0x144);
C_ASSERT(offsetof(INPUTCONTEXTDX, dwUIFlags) == 0x14c);
+C_ASSERT(offsetof(INPUTCONTEXTDX, pState) == 0x154);
+C_ASSERT(offsetof(INPUTCONTEXTDX, dwChange) == 0x158);
C_ASSERT(sizeof(INPUTCONTEXTDX) == 0x160);
#endif
@@ -115,6 +119,12 @@ C_ASSERT(sizeof(INPUTCONTEXTDX) == 0x160);
#define INIT_COMPFORM 0x00000010
#define INIT_SOFTKBDPOS 0x00000020
+// bits for INPUTCONTEXTDX.dwChange
+#define INPUTCONTEXTDX_CHANGE_OPEN 0x1
+#define INPUTCONTEXTDX_CHANGE_CONVERSION 0x2
+#define INPUTCONTEXTDX_CHANGE_SENTENCE 0x4
+#define INPUTCONTEXTDX_CHANGE_FORCE_OPEN 0x100
+
#ifndef WM_IME_REPORT
#define WM_IME_REPORT 0x280
#endif
@@ -154,4 +164,30 @@ typedef struct tagUNDETERMINESTRUCT
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC);
+typedef struct IME_SUBSTATE
+{
+ struct IME_SUBSTATE *pNext;
+ HKL hKL;
+ DWORD dwValue;
+} IME_SUBSTATE, *PIME_SUBSTATE;
+
+#ifndef _WIN64
+C_ASSERT(sizeof(IME_SUBSTATE) == 0xc);
+#endif
+
+typedef struct IME_STATE
+{
+ struct IME_STATE *pNext;
+ WORD wLang;
+ WORD fOpen;
+ DWORD dwConversion;
+ DWORD dwSentence;
+ DWORD dwInit;
+ PIME_SUBSTATE pSubState;
+} IME_STATE, *PIME_STATE;
+
+#ifndef _WIN64
+C_ASSERT(sizeof(IME_STATE) == 0x18);
+#endif
+
#endif /* _WINE_IMM_H_ */
diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h
index a6a45af167b..eb5fb285a79 100644
--- a/win32ss/include/ntuser.h
+++ b/win32ss/include/ntuser.h
@@ -3314,9 +3314,7 @@ NtUserSetSystemTimer(
DWORD
NTAPI
-NtUserSetThreadLayoutHandles(
- DWORD dwUnknown1,
- DWORD dwUnknown2);
+NtUserSetThreadLayoutHandles(HKL hNewKL, HKL hOldKL);
UINT_PTR
NTAPI
diff --git a/win32ss/user/ntuser/ntstubs.c b/win32ss/user/ntuser/ntstubs.c
index 6a1b3c4673e..e3de96b1d51 100644
--- a/win32ss/user/ntuser/ntstubs.c
+++ b/win32ss/user/ntuser/ntstubs.c
@@ -894,9 +894,7 @@ Quit:
DWORD
APIENTRY
-NtUserSetThreadLayoutHandles(
- DWORD dwUnknown1,
- DWORD dwUnknown2)
+NtUserSetThreadLayoutHandles(HKL hNewKL, HKL hOldKL)
{
STUB;
return 0;