xref: /reactos/dll/win32/imm32/imm.c (revision 72c56c2f)
1c2c66affSColin Finck /*
2f4bc74edSKatayama Hirofumi MZ  * PROJECT:     ReactOS IMM32
3f4bc74edSKatayama Hirofumi MZ  * LICENSE:     LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4f4bc74edSKatayama Hirofumi MZ  * PURPOSE:     Implementing Far-Eastern languages input
5f4bc74edSKatayama Hirofumi MZ  * COPYRIGHT:   Copyright 1998 Patrik Stridvall
6c2c66affSColin Finck  *              Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
7f4bc74edSKatayama Hirofumi MZ  *              Copyright 2017 James Tabor <james.tabor@reactos.org>
8f4bc74edSKatayama Hirofumi MZ  *              Copyright 2018 Amine Khaldi <amine.khaldi@reactos.org>
9a40f55bfSKatayama Hirofumi MZ  *              Copyright 2020-2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
10c2c66affSColin Finck  */
11c2c66affSColin Finck 
12b4557a60SKatayama Hirofumi MZ #include "precomp.h"
13c2c66affSColin Finck 
14c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(imm);
15c2c66affSColin Finck 
16bc8a4ac3SKatayama Hirofumi MZ HMODULE ghImm32Inst = NULL; // Win: ghInst
17bc8a4ac3SKatayama Hirofumi MZ PSERVERINFO gpsi = NULL; // Win: gpsi
18bc8a4ac3SKatayama Hirofumi MZ SHAREDINFO gSharedInfo = { NULL }; // Win: gSharedInfo
19bc8a4ac3SKatayama Hirofumi MZ BYTE gfImmInitialized = FALSE; // Win: gfInitialized
20a8d2cd4bSKatayama Hirofumi MZ 
21a40f55bfSKatayama Hirofumi MZ // Win: ImmInitializeGlobals
22a40f55bfSKatayama Hirofumi MZ static BOOL APIENTRY ImmInitializeGlobals(HMODULE hMod)
23692a30a8SKatayama Hirofumi MZ {
24692a30a8SKatayama Hirofumi MZ     NTSTATUS status;
25692a30a8SKatayama Hirofumi MZ 
26692a30a8SKatayama Hirofumi MZ     if (hMod)
27bc8a4ac3SKatayama Hirofumi MZ         ghImm32Inst = hMod;
28692a30a8SKatayama Hirofumi MZ 
29bc8a4ac3SKatayama Hirofumi MZ     if (gfImmInitialized)
30692a30a8SKatayama Hirofumi MZ         return TRUE;
31692a30a8SKatayama Hirofumi MZ 
32895909e6SKatayama Hirofumi MZ     status = RtlInitializeCriticalSection(&gcsImeDpi);
33692a30a8SKatayama Hirofumi MZ     if (NT_ERROR(status))
34692a30a8SKatayama Hirofumi MZ         return FALSE;
35692a30a8SKatayama Hirofumi MZ 
36bc8a4ac3SKatayama Hirofumi MZ     gfImmInitialized = TRUE;
37692a30a8SKatayama Hirofumi MZ     return TRUE;
38692a30a8SKatayama Hirofumi MZ }
39692a30a8SKatayama Hirofumi MZ 
401da5d7a3SKatayama Hirofumi MZ /***********************************************************************
41b4557a60SKatayama Hirofumi MZ  *		ImmRegisterClient(IMM32.@)
42b4557a60SKatayama Hirofumi MZ  *       ( Undocumented, called from user32.dll )
431da5d7a3SKatayama Hirofumi MZ  */
44b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmRegisterClient(PSHAREDINFO ptr, HINSTANCE hMod)
45692a30a8SKatayama Hirofumi MZ {
466dfe0321SKatayama Hirofumi MZ     gSharedInfo = *ptr;
476dfe0321SKatayama Hirofumi MZ     gpsi = gSharedInfo.psi;
48a40f55bfSKatayama Hirofumi MZ     return ImmInitializeGlobals(hMod);
491e62771cSKatayama Hirofumi MZ }
501e62771cSKatayama Hirofumi MZ 
511da5d7a3SKatayama Hirofumi MZ /***********************************************************************
521da5d7a3SKatayama Hirofumi MZ  *		ImmLoadLayout (IMM32.@)
531da5d7a3SKatayama Hirofumi MZ  */
54a37d9a4eSKatayama Hirofumi MZ BOOL WINAPI ImmLoadLayout(HKL hKL, PIMEINFOEX pImeInfoEx)
558e1dea0cSKatayama Hirofumi MZ {
5685e292d5SKatayama Hirofumi MZ     DWORD cbData, dwType;
5785e292d5SKatayama Hirofumi MZ     HKEY hLayoutKey;
588e1dea0cSKatayama Hirofumi MZ     LONG error;
598e1dea0cSKatayama Hirofumi MZ     WCHAR szLayout[MAX_PATH];
608e1dea0cSKatayama Hirofumi MZ 
611d9542d2SKatayama Hirofumi MZ     TRACE("(%p, %p)\n", hKL, pImeInfoEx);
628e1dea0cSKatayama Hirofumi MZ 
6385e292d5SKatayama Hirofumi MZ     ZeroMemory(pImeInfoEx, sizeof(IMEINFOEX));
6485e292d5SKatayama Hirofumi MZ 
658ba378c9SKatayama Hirofumi MZ     if (IS_IME_HKL(hKL) || !IS_CICERO_MODE() || IS_16BIT_MODE())
668e1dea0cSKatayama Hirofumi MZ     {
6785e292d5SKatayama Hirofumi MZ         StringCchPrintfW(szLayout, _countof(szLayout), L"%s\\%08lX",
6885e292d5SKatayama Hirofumi MZ                          REGKEY_KEYBOARD_LAYOUTS, HandleToUlong(hKL));
698e1dea0cSKatayama Hirofumi MZ 
7085e292d5SKatayama Hirofumi MZ         error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szLayout, 0, KEY_READ, &hLayoutKey);
718e1dea0cSKatayama Hirofumi MZ         if (error)
72a37d9a4eSKatayama Hirofumi MZ         {
7385e292d5SKatayama Hirofumi MZ             ERR("RegOpenKeyExW: 0x%08lX\n", error);
74a37d9a4eSKatayama Hirofumi MZ             return FALSE;
75a37d9a4eSKatayama Hirofumi MZ         }
768e1dea0cSKatayama Hirofumi MZ     }
778e1dea0cSKatayama Hirofumi MZ     else
788e1dea0cSKatayama Hirofumi MZ     {
7985e292d5SKatayama Hirofumi MZ         error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, REGKEY_IMM, 0, KEY_READ, &hLayoutKey);
808e1dea0cSKatayama Hirofumi MZ         if (error)
818e1dea0cSKatayama Hirofumi MZ         {
8285e292d5SKatayama Hirofumi MZ             ERR("RegOpenKeyExW: 0x%08lX\n", error);
83a37d9a4eSKatayama Hirofumi MZ             return FALSE;
848e1dea0cSKatayama Hirofumi MZ         }
85a37d9a4eSKatayama Hirofumi MZ     }
86a37d9a4eSKatayama Hirofumi MZ 
878e1dea0cSKatayama Hirofumi MZ     cbData = sizeof(pImeInfoEx->wszImeFile);
8885e292d5SKatayama Hirofumi MZ     error = RegQueryValueExW(hLayoutKey, L"Ime File", NULL, &dwType,
898e1dea0cSKatayama Hirofumi MZ                              (LPBYTE)pImeInfoEx->wszImeFile, &cbData);
9085e292d5SKatayama Hirofumi MZ     pImeInfoEx->wszImeFile[_countof(pImeInfoEx->wszImeFile) - 1] = UNICODE_NULL;
918e1dea0cSKatayama Hirofumi MZ 
928e1dea0cSKatayama Hirofumi MZ     RegCloseKey(hLayoutKey);
93a37d9a4eSKatayama Hirofumi MZ 
94a37d9a4eSKatayama Hirofumi MZ     pImeInfoEx->fLoadFlag = 0;
95a37d9a4eSKatayama Hirofumi MZ 
9685e292d5SKatayama Hirofumi MZ     if (error != ERROR_SUCCESS || dwType != REG_SZ)
97a37d9a4eSKatayama Hirofumi MZ     {
9885e292d5SKatayama Hirofumi MZ         ERR("RegQueryValueExW: 0x%lX, 0x%lX\n", error, dwType);
99a37d9a4eSKatayama Hirofumi MZ         return FALSE;
100a37d9a4eSKatayama Hirofumi MZ     }
101a37d9a4eSKatayama Hirofumi MZ 
102a37d9a4eSKatayama Hirofumi MZ     pImeInfoEx->hkl = hKL;
103a37d9a4eSKatayama Hirofumi MZ     return Imm32LoadImeVerInfo(pImeInfoEx);
1048e1dea0cSKatayama Hirofumi MZ }
1058e1dea0cSKatayama Hirofumi MZ 
106e6a51b54SKatayama Hirofumi MZ /***********************************************************************
107e6a51b54SKatayama Hirofumi MZ  *		ImmFreeLayout (IMM32.@)
108e6a51b54SKatayama Hirofumi MZ  */
109e6a51b54SKatayama Hirofumi MZ BOOL WINAPI ImmFreeLayout(DWORD dwUnknown)
110e6a51b54SKatayama Hirofumi MZ {
11185e292d5SKatayama Hirofumi MZ     WCHAR szKBD[KL_NAMELENGTH];
112e6a51b54SKatayama Hirofumi MZ     UINT iKL, cKLs;
113e6a51b54SKatayama Hirofumi MZ     HKL hOldKL, hNewKL, *pList;
114e6a51b54SKatayama Hirofumi MZ     PIMEDPI pImeDpi;
115e6a51b54SKatayama Hirofumi MZ     LANGID LangID;
116e6a51b54SKatayama Hirofumi MZ 
117e6a51b54SKatayama Hirofumi MZ     TRACE("(0x%lX)\n", dwUnknown);
118e6a51b54SKatayama Hirofumi MZ 
119e6a51b54SKatayama Hirofumi MZ     hOldKL = GetKeyboardLayout(0);
120e6a51b54SKatayama Hirofumi MZ 
121e6a51b54SKatayama Hirofumi MZ     if (dwUnknown == 1)
122e6a51b54SKatayama Hirofumi MZ     {
123e6a51b54SKatayama Hirofumi MZ         if (!IS_IME_HKL(hOldKL))
124e6a51b54SKatayama Hirofumi MZ             return TRUE;
125e6a51b54SKatayama Hirofumi MZ 
126e6a51b54SKatayama Hirofumi MZ         LangID = LANGIDFROMLCID(GetSystemDefaultLCID());
127e6a51b54SKatayama Hirofumi MZ 
128e6a51b54SKatayama Hirofumi MZ         cKLs = GetKeyboardLayoutList(0, NULL);
129e6a51b54SKatayama Hirofumi MZ         if (cKLs)
130e6a51b54SKatayama Hirofumi MZ         {
13146518ad6SKatayama Hirofumi MZ             pList = ImmLocalAlloc(0, cKLs * sizeof(HKL));
132e6a51b54SKatayama Hirofumi MZ             if (pList == NULL)
133e6a51b54SKatayama Hirofumi MZ                 return FALSE;
134e6a51b54SKatayama Hirofumi MZ 
135e6a51b54SKatayama Hirofumi MZ             cKLs = GetKeyboardLayoutList(cKLs, pList);
136e6a51b54SKatayama Hirofumi MZ             for (iKL = 0; iKL < cKLs; ++iKL)
137e6a51b54SKatayama Hirofumi MZ             {
138e6a51b54SKatayama Hirofumi MZ                 if (!IS_IME_HKL(pList[iKL]))
139e6a51b54SKatayama Hirofumi MZ                 {
140e6a51b54SKatayama Hirofumi MZ                     LangID = LOWORD(pList[iKL]);
141e6a51b54SKatayama Hirofumi MZ                     break;
142e6a51b54SKatayama Hirofumi MZ                 }
143e6a51b54SKatayama Hirofumi MZ             }
144e6a51b54SKatayama Hirofumi MZ 
14546518ad6SKatayama Hirofumi MZ             ImmLocalFree(pList);
146e6a51b54SKatayama Hirofumi MZ         }
147e6a51b54SKatayama Hirofumi MZ 
148e6a51b54SKatayama Hirofumi MZ         StringCchPrintfW(szKBD, _countof(szKBD), L"%08X", LangID);
149e6a51b54SKatayama Hirofumi MZ         if (!LoadKeyboardLayoutW(szKBD, KLF_ACTIVATE))
150e6a51b54SKatayama Hirofumi MZ             LoadKeyboardLayoutW(L"00000409", KLF_ACTIVATE | 0x200);
151e6a51b54SKatayama Hirofumi MZ     }
152e6a51b54SKatayama Hirofumi MZ     else if (dwUnknown == 2)
153e6a51b54SKatayama Hirofumi MZ     {
154895909e6SKatayama Hirofumi MZ         RtlEnterCriticalSection(&gcsImeDpi);
155e6a51b54SKatayama Hirofumi MZ Retry:
1563c169714SKatayama Hirofumi MZ         for (pImeDpi = gpImeDpiList; pImeDpi; pImeDpi = pImeDpi->pNext)
157e6a51b54SKatayama Hirofumi MZ         {
158e6a51b54SKatayama Hirofumi MZ             if (Imm32ReleaseIME(pImeDpi->hKL))
159e6a51b54SKatayama Hirofumi MZ                 goto Retry;
160e6a51b54SKatayama Hirofumi MZ         }
161895909e6SKatayama Hirofumi MZ         RtlLeaveCriticalSection(&gcsImeDpi);
162e6a51b54SKatayama Hirofumi MZ     }
163e6a51b54SKatayama Hirofumi MZ     else
164e6a51b54SKatayama Hirofumi MZ     {
165e6a51b54SKatayama Hirofumi MZ         hNewKL = (HKL)(DWORD_PTR)dwUnknown;
166e6a51b54SKatayama Hirofumi MZ         if (IS_IME_HKL(hNewKL) && hNewKL != hOldKL)
167e6a51b54SKatayama Hirofumi MZ             Imm32ReleaseIME(hNewKL);
168e6a51b54SKatayama Hirofumi MZ     }
169e6a51b54SKatayama Hirofumi MZ 
170e6a51b54SKatayama Hirofumi MZ     return TRUE;
171e6a51b54SKatayama Hirofumi MZ }
172e6a51b54SKatayama Hirofumi MZ 
173bc8a4ac3SKatayama Hirofumi MZ // Win: SelectInputContext
174bc8a4ac3SKatayama Hirofumi MZ VOID APIENTRY Imm32SelectInputContext(HKL hNewKL, HKL hOldKL, HIMC hIMC)
17566ef3149SKatayama Hirofumi MZ {
17666ef3149SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
17766ef3149SKatayama Hirofumi MZ     LPINPUTCONTEXTDX pIC;
17866ef3149SKatayama Hirofumi MZ     LPGUIDELINE pGL;
17966ef3149SKatayama Hirofumi MZ     LPCANDIDATEINFO pCI;
18066ef3149SKatayama Hirofumi MZ     LPCOMPOSITIONSTRING pCS;
18166ef3149SKatayama Hirofumi MZ     LOGFONTA LogFontA;
18266ef3149SKatayama Hirofumi MZ     LOGFONTW LogFontW;
18366ef3149SKatayama Hirofumi MZ     BOOL fOpen, bIsNewHKLIme = TRUE, bIsOldHKLIme = TRUE, bClientWide, bNewDpiWide;
18466ef3149SKatayama Hirofumi MZ     DWORD cbNewPrivate = 0, cbOldPrivate = 0, dwConversion, dwSentence, dwSize, dwNewSize;
18566ef3149SKatayama Hirofumi MZ     PIMEDPI pNewImeDpi = NULL, pOldImeDpi = NULL;
18666ef3149SKatayama Hirofumi MZ     HANDLE hPrivate;
18766ef3149SKatayama Hirofumi MZ     PIME_STATE pNewState = NULL, pOldState = NULL;
18866ef3149SKatayama Hirofumi MZ 
18966ef3149SKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
19066ef3149SKatayama Hirofumi MZ     if (!pClientImc)
19166ef3149SKatayama Hirofumi MZ         return;
19266ef3149SKatayama Hirofumi MZ 
19366ef3149SKatayama Hirofumi MZ     pNewImeDpi = ImmLockImeDpi(hNewKL);
19466ef3149SKatayama Hirofumi MZ 
19566ef3149SKatayama Hirofumi MZ     if (hNewKL != hOldKL)
19666ef3149SKatayama Hirofumi MZ         pOldImeDpi = ImmLockImeDpi(hOldKL);
19766ef3149SKatayama Hirofumi MZ 
19866ef3149SKatayama Hirofumi MZ     if (pNewImeDpi)
19966ef3149SKatayama Hirofumi MZ     {
20066ef3149SKatayama Hirofumi MZ         cbNewPrivate = pNewImeDpi->ImeInfo.dwPrivateDataSize;
20166ef3149SKatayama Hirofumi MZ         pClientImc->uCodePage = pNewImeDpi->uCodePage;
20266ef3149SKatayama Hirofumi MZ     }
20366ef3149SKatayama Hirofumi MZ     else
20466ef3149SKatayama Hirofumi MZ     {
20566ef3149SKatayama Hirofumi MZ         pClientImc->uCodePage = CP_ACP;
20666ef3149SKatayama Hirofumi MZ     }
20766ef3149SKatayama Hirofumi MZ 
208b0d66e68SKatayama Hirofumi MZ     if (cbNewPrivate < sizeof(DWORD))
209b0d66e68SKatayama Hirofumi MZ         cbNewPrivate = sizeof(DWORD);
21066ef3149SKatayama Hirofumi MZ 
21166ef3149SKatayama Hirofumi MZ     if (pOldImeDpi)
21266ef3149SKatayama Hirofumi MZ         cbOldPrivate = pOldImeDpi->ImeInfo.dwPrivateDataSize;
21366ef3149SKatayama Hirofumi MZ 
214b0d66e68SKatayama Hirofumi MZ     if (cbOldPrivate < sizeof(DWORD))
215b0d66e68SKatayama Hirofumi MZ         cbOldPrivate = sizeof(DWORD);
21666ef3149SKatayama Hirofumi MZ 
21766ef3149SKatayama Hirofumi MZ     if (pClientImc->hKL == hOldKL)
21866ef3149SKatayama Hirofumi MZ     {
21966ef3149SKatayama Hirofumi MZ         if (pOldImeDpi)
22066ef3149SKatayama Hirofumi MZ         {
22166ef3149SKatayama Hirofumi MZ             if (IS_IME_HKL(hOldKL))
22266ef3149SKatayama Hirofumi MZ                 pOldImeDpi->ImeSelect(hIMC, FALSE);
223020d7d58SKatayama Hirofumi MZ             else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
22466ef3149SKatayama Hirofumi MZ                 pOldImeDpi->CtfImeSelectEx(hIMC, FALSE, hOldKL);
22566ef3149SKatayama Hirofumi MZ         }
22666ef3149SKatayama Hirofumi MZ         pClientImc->hKL = NULL;
22766ef3149SKatayama Hirofumi MZ     }
22866ef3149SKatayama Hirofumi MZ 
22966ef3149SKatayama Hirofumi MZ     if (CtfImmIsTextFrameServiceDisabled())
23066ef3149SKatayama Hirofumi MZ     {
2315b87c95eSKatayama Hirofumi MZ         if (IS_IMM_MODE() && !IS_CICERO_MODE())
23266ef3149SKatayama Hirofumi MZ         {
23366ef3149SKatayama Hirofumi MZ             bIsNewHKLIme = IS_IME_HKL(hNewKL);
23466ef3149SKatayama Hirofumi MZ             bIsOldHKLIme = IS_IME_HKL(hOldKL);
23566ef3149SKatayama Hirofumi MZ         }
23666ef3149SKatayama Hirofumi MZ     }
23766ef3149SKatayama Hirofumi MZ 
2388de74398SKatayama Hirofumi MZ     pIC = (LPINPUTCONTEXTDX)Imm32InternalLockIMC(hIMC, FALSE);
23966ef3149SKatayama Hirofumi MZ     if (!pIC)
24066ef3149SKatayama Hirofumi MZ     {
24166ef3149SKatayama Hirofumi MZ         if (pNewImeDpi)
24266ef3149SKatayama Hirofumi MZ         {
24366ef3149SKatayama Hirofumi MZ             if (IS_IME_HKL(hNewKL))
24466ef3149SKatayama Hirofumi MZ                 pNewImeDpi->ImeSelect(hIMC, TRUE);
245020d7d58SKatayama Hirofumi MZ             else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
24666ef3149SKatayama Hirofumi MZ                 pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
24766ef3149SKatayama Hirofumi MZ 
24866ef3149SKatayama Hirofumi MZ             pClientImc->hKL = hNewKL;
24966ef3149SKatayama Hirofumi MZ         }
25066ef3149SKatayama Hirofumi MZ     }
25166ef3149SKatayama Hirofumi MZ     else
25266ef3149SKatayama Hirofumi MZ     {
25366ef3149SKatayama Hirofumi MZ         dwConversion = pIC->fdwConversion;
25466ef3149SKatayama Hirofumi MZ         dwSentence = pIC->fdwSentence;
25566ef3149SKatayama Hirofumi MZ         fOpen = pIC->fOpen;
25666ef3149SKatayama Hirofumi MZ 
25766ef3149SKatayama Hirofumi MZ         if (pNewImeDpi)
25866ef3149SKatayama Hirofumi MZ         {
25966ef3149SKatayama Hirofumi MZ             bClientWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
26066ef3149SKatayama Hirofumi MZ             bNewDpiWide = ImeDpi_IsUnicode(pNewImeDpi);
26166ef3149SKatayama Hirofumi MZ             if (bClientWide && !bNewDpiWide)
26266ef3149SKatayama Hirofumi MZ             {
26366ef3149SKatayama Hirofumi MZ                 if (pIC->fdwInit & INIT_LOGFONT)
26466ef3149SKatayama Hirofumi MZ                 {
26566ef3149SKatayama Hirofumi MZ                     LogFontWideToAnsi(&pIC->lfFont.W, &LogFontA);
26666ef3149SKatayama Hirofumi MZ                     pIC->lfFont.A = LogFontA;
26766ef3149SKatayama Hirofumi MZ                 }
26866ef3149SKatayama Hirofumi MZ                 pClientImc->dwFlags &= ~CLIENTIMC_WIDE;
26966ef3149SKatayama Hirofumi MZ             }
27066ef3149SKatayama Hirofumi MZ             else if (!bClientWide && bNewDpiWide)
27166ef3149SKatayama Hirofumi MZ             {
27266ef3149SKatayama Hirofumi MZ                 if (pIC->fdwInit & INIT_LOGFONT)
27366ef3149SKatayama Hirofumi MZ                 {
27466ef3149SKatayama Hirofumi MZ                     LogFontAnsiToWide(&pIC->lfFont.A, &LogFontW);
27566ef3149SKatayama Hirofumi MZ                     pIC->lfFont.W = LogFontW;
27666ef3149SKatayama Hirofumi MZ                 }
27766ef3149SKatayama Hirofumi MZ                 pClientImc->dwFlags |= CLIENTIMC_WIDE;
27866ef3149SKatayama Hirofumi MZ             }
27966ef3149SKatayama Hirofumi MZ         }
28066ef3149SKatayama Hirofumi MZ 
28166ef3149SKatayama Hirofumi MZ         if (cbOldPrivate != cbNewPrivate)
28266ef3149SKatayama Hirofumi MZ         {
28366ef3149SKatayama Hirofumi MZ             hPrivate = ImmReSizeIMCC(pIC->hPrivate, cbNewPrivate);
28466ef3149SKatayama Hirofumi MZ             if (!hPrivate)
28566ef3149SKatayama Hirofumi MZ             {
28666ef3149SKatayama Hirofumi MZ                 ImmDestroyIMCC(pIC->hPrivate);
28766ef3149SKatayama Hirofumi MZ                 hPrivate = ImmCreateIMCC(cbNewPrivate);
28866ef3149SKatayama Hirofumi MZ             }
28966ef3149SKatayama Hirofumi MZ             pIC->hPrivate = hPrivate;
29066ef3149SKatayama Hirofumi MZ         }
29166ef3149SKatayama Hirofumi MZ 
29266ef3149SKatayama Hirofumi MZ #define MAX_IMCC_SIZE 0x1000
29366ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hMsgBuf);
29466ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hMsgBuf) || dwSize > MAX_IMCC_SIZE)
29566ef3149SKatayama Hirofumi MZ         {
29666ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hMsgBuf);
29766ef3149SKatayama Hirofumi MZ             pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
29866ef3149SKatayama Hirofumi MZ             pIC->dwNumMsgBuf = 0;
29966ef3149SKatayama Hirofumi MZ         }
30066ef3149SKatayama Hirofumi MZ 
30166ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hGuideLine);
30266ef3149SKatayama Hirofumi MZ         dwNewSize = sizeof(GUIDELINE);
30366ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hGuideLine) ||
30466ef3149SKatayama Hirofumi MZ             dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
30566ef3149SKatayama Hirofumi MZ         {
30666ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hGuideLine);
30766ef3149SKatayama Hirofumi MZ             pIC->hGuideLine = ImmCreateIMCC(dwNewSize);
30866ef3149SKatayama Hirofumi MZ             pGL = ImmLockIMCC(pIC->hGuideLine);
30966ef3149SKatayama Hirofumi MZ             if (pGL)
31066ef3149SKatayama Hirofumi MZ             {
31166ef3149SKatayama Hirofumi MZ                 pGL->dwSize = dwNewSize;
31266ef3149SKatayama Hirofumi MZ                 ImmUnlockIMCC(pIC->hGuideLine);
31366ef3149SKatayama Hirofumi MZ             }
31466ef3149SKatayama Hirofumi MZ         }
31566ef3149SKatayama Hirofumi MZ 
31666ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hCandInfo);
31766ef3149SKatayama Hirofumi MZ         dwNewSize = sizeof(CANDIDATEINFO);
31866ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hCandInfo) ||
31966ef3149SKatayama Hirofumi MZ             dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
32066ef3149SKatayama Hirofumi MZ         {
32166ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hCandInfo);
32266ef3149SKatayama Hirofumi MZ             pIC->hCandInfo = ImmCreateIMCC(dwNewSize);
32366ef3149SKatayama Hirofumi MZ             pCI = ImmLockIMCC(pIC->hCandInfo);
32466ef3149SKatayama Hirofumi MZ             if (pCI)
32566ef3149SKatayama Hirofumi MZ             {
32666ef3149SKatayama Hirofumi MZ                 pCI->dwSize = dwNewSize;
32766ef3149SKatayama Hirofumi MZ                 ImmUnlockIMCC(pIC->hCandInfo);
32866ef3149SKatayama Hirofumi MZ             }
32966ef3149SKatayama Hirofumi MZ         }
33066ef3149SKatayama Hirofumi MZ 
33166ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hCompStr);
33266ef3149SKatayama Hirofumi MZ         dwNewSize = sizeof(COMPOSITIONSTRING);
33366ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hCompStr) ||
33466ef3149SKatayama Hirofumi MZ             dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
33566ef3149SKatayama Hirofumi MZ         {
33666ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hCompStr);
33766ef3149SKatayama Hirofumi MZ             pIC->hCompStr = ImmCreateIMCC(dwNewSize);
33866ef3149SKatayama Hirofumi MZ             pCS = ImmLockIMCC(pIC->hCompStr);
33966ef3149SKatayama Hirofumi MZ             if (pCS)
34066ef3149SKatayama Hirofumi MZ             {
34166ef3149SKatayama Hirofumi MZ                 pCS->dwSize = dwNewSize;
34266ef3149SKatayama Hirofumi MZ                 ImmUnlockIMCC(pIC->hCompStr);
34366ef3149SKatayama Hirofumi MZ             }
34466ef3149SKatayama Hirofumi MZ         }
34566ef3149SKatayama Hirofumi MZ #undef MAX_IMCC_SIZE
34666ef3149SKatayama Hirofumi MZ 
34766ef3149SKatayama Hirofumi MZ         if (pOldImeDpi && bIsOldHKLIme)
34866ef3149SKatayama Hirofumi MZ         {
34966ef3149SKatayama Hirofumi MZ             pOldState = Imm32FetchImeState(pIC, hOldKL);
35066ef3149SKatayama Hirofumi MZ             if (pOldState)
35166ef3149SKatayama Hirofumi MZ                 Imm32SaveImeStateSentence(pIC, pOldState, hOldKL);
35266ef3149SKatayama Hirofumi MZ         }
35366ef3149SKatayama Hirofumi MZ 
35466ef3149SKatayama Hirofumi MZ         if (pNewImeDpi && bIsNewHKLIme)
35566ef3149SKatayama Hirofumi MZ             pNewState = Imm32FetchImeState(pIC, hNewKL);
35666ef3149SKatayama Hirofumi MZ 
35766ef3149SKatayama Hirofumi MZ         if (pOldState != pNewState)
35866ef3149SKatayama Hirofumi MZ         {
35966ef3149SKatayama Hirofumi MZ             if (pOldState)
36066ef3149SKatayama Hirofumi MZ             {
36166ef3149SKatayama Hirofumi MZ                 pOldState->fOpen = !!pIC->fOpen;
36266ef3149SKatayama Hirofumi MZ                 pOldState->dwConversion = (pIC->fdwConversion & ~IME_CMODE_EUDC);
36366ef3149SKatayama Hirofumi MZ                 pOldState->dwSentence = pIC->fdwSentence;
36466ef3149SKatayama Hirofumi MZ                 pOldState->dwInit = pIC->fdwInit;
36566ef3149SKatayama Hirofumi MZ             }
36666ef3149SKatayama Hirofumi MZ 
36766ef3149SKatayama Hirofumi MZ             if (pNewState)
36866ef3149SKatayama Hirofumi MZ             {
36966ef3149SKatayama Hirofumi MZ                 if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_FORCE_OPEN)
37066ef3149SKatayama Hirofumi MZ                 {
37166ef3149SKatayama Hirofumi MZ                     pIC->dwChange &= ~INPUTCONTEXTDX_CHANGE_FORCE_OPEN;
37266ef3149SKatayama Hirofumi MZ                     pIC->fOpen = TRUE;
37366ef3149SKatayama Hirofumi MZ                 }
37466ef3149SKatayama Hirofumi MZ                 else
37566ef3149SKatayama Hirofumi MZ                 {
37666ef3149SKatayama Hirofumi MZ                     pIC->fOpen = pNewState->fOpen;
37766ef3149SKatayama Hirofumi MZ                 }
37866ef3149SKatayama Hirofumi MZ 
37966ef3149SKatayama Hirofumi MZ                 pIC->fdwConversion = (pNewState->dwConversion & ~IME_CMODE_EUDC);
38066ef3149SKatayama Hirofumi MZ                 pIC->fdwSentence = pNewState->dwSentence;
38166ef3149SKatayama Hirofumi MZ                 pIC->fdwInit = pNewState->dwInit;
38266ef3149SKatayama Hirofumi MZ             }
38366ef3149SKatayama Hirofumi MZ         }
38466ef3149SKatayama Hirofumi MZ 
38566ef3149SKatayama Hirofumi MZ         if (pNewState)
38666ef3149SKatayama Hirofumi MZ             Imm32LoadImeStateSentence(pIC, pNewState, hNewKL);
38766ef3149SKatayama Hirofumi MZ 
38866ef3149SKatayama Hirofumi MZ         if (pNewImeDpi)
38966ef3149SKatayama Hirofumi MZ         {
39066ef3149SKatayama Hirofumi MZ             if (IS_IME_HKL(hNewKL))
39166ef3149SKatayama Hirofumi MZ                 pNewImeDpi->ImeSelect(hIMC, TRUE);
392020d7d58SKatayama Hirofumi MZ             else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
39366ef3149SKatayama Hirofumi MZ                 pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
39466ef3149SKatayama Hirofumi MZ 
39566ef3149SKatayama Hirofumi MZ             pClientImc->hKL = hNewKL;
39666ef3149SKatayama Hirofumi MZ         }
39766ef3149SKatayama Hirofumi MZ 
39866ef3149SKatayama Hirofumi MZ         pIC->dwChange = 0;
39966ef3149SKatayama Hirofumi MZ         if (pIC->fOpen != fOpen)
40066ef3149SKatayama Hirofumi MZ             pIC->dwChange |= INPUTCONTEXTDX_CHANGE_OPEN;
40166ef3149SKatayama Hirofumi MZ         if (pIC->fdwConversion != dwConversion)
40266ef3149SKatayama Hirofumi MZ             pIC->dwChange |= INPUTCONTEXTDX_CHANGE_CONVERSION;
40366ef3149SKatayama Hirofumi MZ         if (pIC->fdwSentence != dwSentence)
40466ef3149SKatayama Hirofumi MZ             pIC->dwChange |= INPUTCONTEXTDX_CHANGE_SENTENCE;
40566ef3149SKatayama Hirofumi MZ 
40666ef3149SKatayama Hirofumi MZ         ImmUnlockIMC(hIMC);
40766ef3149SKatayama Hirofumi MZ     }
40866ef3149SKatayama Hirofumi MZ 
40966ef3149SKatayama Hirofumi MZ     ImmUnlockImeDpi(pOldImeDpi);
41066ef3149SKatayama Hirofumi MZ     ImmUnlockImeDpi(pNewImeDpi);
41166ef3149SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
41266ef3149SKatayama Hirofumi MZ }
41366ef3149SKatayama Hirofumi MZ 
41466ef3149SKatayama Hirofumi MZ typedef struct SELECT_LAYOUT
41566ef3149SKatayama Hirofumi MZ {
41666ef3149SKatayama Hirofumi MZ     HKL hNewKL;
41766ef3149SKatayama Hirofumi MZ     HKL hOldKL;
41866ef3149SKatayama Hirofumi MZ } SELECT_LAYOUT, *LPSELECT_LAYOUT;
41966ef3149SKatayama Hirofumi MZ 
420bc8a4ac3SKatayama Hirofumi MZ // Win: SelectContextProc
421bc8a4ac3SKatayama Hirofumi MZ static BOOL CALLBACK Imm32SelectContextProc(HIMC hIMC, LPARAM lParam)
42266ef3149SKatayama Hirofumi MZ {
42366ef3149SKatayama Hirofumi MZ     LPSELECT_LAYOUT pSelect = (LPSELECT_LAYOUT)lParam;
424bc8a4ac3SKatayama Hirofumi MZ     Imm32SelectInputContext(pSelect->hNewKL, pSelect->hOldKL, hIMC);
42566ef3149SKatayama Hirofumi MZ     return TRUE;
42666ef3149SKatayama Hirofumi MZ }
42766ef3149SKatayama Hirofumi MZ 
428bc8a4ac3SKatayama Hirofumi MZ // Win: NotifyIMEProc
429bc8a4ac3SKatayama Hirofumi MZ static BOOL CALLBACK Imm32NotifyIMEProc(HIMC hIMC, LPARAM lParam)
43066ef3149SKatayama Hirofumi MZ {
43166ef3149SKatayama Hirofumi MZ     ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, (DWORD)lParam, 0);
43266ef3149SKatayama Hirofumi MZ     return TRUE;
43366ef3149SKatayama Hirofumi MZ }
43466ef3149SKatayama Hirofumi MZ 
43566ef3149SKatayama Hirofumi MZ /***********************************************************************
43666ef3149SKatayama Hirofumi MZ  *		ImmActivateLayout (IMM32.@)
43766ef3149SKatayama Hirofumi MZ  */
43866ef3149SKatayama Hirofumi MZ BOOL WINAPI ImmActivateLayout(HKL hKL)
43966ef3149SKatayama Hirofumi MZ {
44066ef3149SKatayama Hirofumi MZ     PIMEDPI pImeDpi;
44166ef3149SKatayama Hirofumi MZ     HKL hOldKL;
44266ef3149SKatayama Hirofumi MZ     LPARAM lParam;
44366ef3149SKatayama Hirofumi MZ     HWND hwndDefIME = NULL;
44466ef3149SKatayama Hirofumi MZ     SELECT_LAYOUT SelectLayout;
44566ef3149SKatayama Hirofumi MZ 
44666ef3149SKatayama Hirofumi MZ     hOldKL = GetKeyboardLayout(0);
44766ef3149SKatayama Hirofumi MZ 
44866ef3149SKatayama Hirofumi MZ     if (hOldKL == hKL && !(GetWin32ClientInfo()->CI_flags & CI_IMMACTIVATE))
44966ef3149SKatayama Hirofumi MZ         return TRUE;
45066ef3149SKatayama Hirofumi MZ 
45166ef3149SKatayama Hirofumi MZ     ImmLoadIME(hKL);
45266ef3149SKatayama Hirofumi MZ 
45366ef3149SKatayama Hirofumi MZ     if (hOldKL != hKL)
45466ef3149SKatayama Hirofumi MZ     {
45566ef3149SKatayama Hirofumi MZ         pImeDpi = ImmLockImeDpi(hOldKL);
45666ef3149SKatayama Hirofumi MZ         if (pImeDpi)
45766ef3149SKatayama Hirofumi MZ         {
45866ef3149SKatayama Hirofumi MZ             if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT)
45966ef3149SKatayama Hirofumi MZ                 lParam = CPS_COMPLETE;
46066ef3149SKatayama Hirofumi MZ             else
46166ef3149SKatayama Hirofumi MZ                 lParam = CPS_CANCEL;
46266ef3149SKatayama Hirofumi MZ             ImmUnlockImeDpi(pImeDpi);
46366ef3149SKatayama Hirofumi MZ 
464bc8a4ac3SKatayama Hirofumi MZ             ImmEnumInputContext(0, Imm32NotifyIMEProc, lParam);
46566ef3149SKatayama Hirofumi MZ         }
46666ef3149SKatayama Hirofumi MZ 
46766ef3149SKatayama Hirofumi MZ         hwndDefIME = ImmGetDefaultIMEWnd(NULL);
46866ef3149SKatayama Hirofumi MZ         if (IsWindow(hwndDefIME))
46966ef3149SKatayama Hirofumi MZ             SendMessageW(hwndDefIME, WM_IME_SELECT, FALSE, (LPARAM)hOldKL);
47066ef3149SKatayama Hirofumi MZ 
47166ef3149SKatayama Hirofumi MZ         NtUserSetThreadLayoutHandles(hKL, hOldKL);
47266ef3149SKatayama Hirofumi MZ     }
47366ef3149SKatayama Hirofumi MZ 
47466ef3149SKatayama Hirofumi MZ     SelectLayout.hNewKL = hKL;
47566ef3149SKatayama Hirofumi MZ     SelectLayout.hOldKL = hOldKL;
476bc8a4ac3SKatayama Hirofumi MZ     ImmEnumInputContext(0, Imm32SelectContextProc, (LPARAM)&SelectLayout);
47766ef3149SKatayama Hirofumi MZ 
47866ef3149SKatayama Hirofumi MZ     if (IsWindow(hwndDefIME))
47966ef3149SKatayama Hirofumi MZ         SendMessageW(hwndDefIME, WM_IME_SELECT, TRUE, (LPARAM)hKL);
48066ef3149SKatayama Hirofumi MZ 
48166ef3149SKatayama Hirofumi MZ     return TRUE;
48266ef3149SKatayama Hirofumi MZ }
48366ef3149SKatayama Hirofumi MZ 
4849adc538cSKatayama Hirofumi MZ static VOID APIENTRY Imm32CiceroSetActiveContext(HIMC hIMC, BOOL fActive, HWND hWnd, HKL hKL)
4859adc538cSKatayama Hirofumi MZ {
486081ffbebSGeorge Bișoc     TRACE("We have to do something\n");
4879adc538cSKatayama Hirofumi MZ }
4889adc538cSKatayama Hirofumi MZ 
489c2c66affSColin Finck /***********************************************************************
490c2c66affSColin Finck  *		ImmAssociateContext (IMM32.@)
491c2c66affSColin Finck  */
492c2c66affSColin Finck HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
493c2c66affSColin Finck {
494ef003fa4SKatayama Hirofumi MZ     PWND pWnd;
495ef003fa4SKatayama Hirofumi MZ     HWND hwndFocus;
496ef003fa4SKatayama Hirofumi MZ     DWORD dwValue;
497ef003fa4SKatayama Hirofumi MZ     HIMC hOldIMC;
498c2c66affSColin Finck 
499ef003fa4SKatayama Hirofumi MZ     TRACE("(%p, %p)\n", hWnd, hIMC);
500c2c66affSColin Finck 
501356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
502c2c66affSColin Finck         return NULL;
503c2c66affSColin Finck 
504b0b925d2SKatayama Hirofumi MZ     pWnd = ValidateHwnd(hWnd);
505ef003fa4SKatayama Hirofumi MZ     if (!pWnd)
506ef003fa4SKatayama Hirofumi MZ         return NULL;
507ef003fa4SKatayama Hirofumi MZ 
508ef003fa4SKatayama Hirofumi MZ     if (hIMC && Imm32IsCrossThreadAccess(hIMC))
509ef003fa4SKatayama Hirofumi MZ         return NULL;
510ef003fa4SKatayama Hirofumi MZ 
511ef003fa4SKatayama Hirofumi MZ     hOldIMC = pWnd->hImc;
512ef003fa4SKatayama Hirofumi MZ     if (hOldIMC == hIMC)
513c2c66affSColin Finck         return hIMC;
514c2c66affSColin Finck 
515ef003fa4SKatayama Hirofumi MZ     dwValue = NtUserAssociateInputContext(hWnd, hIMC, 0);
516*72c56c2fSKatayama Hirofumi MZ     switch (dwValue)
517*72c56c2fSKatayama Hirofumi MZ     {
518*72c56c2fSKatayama Hirofumi MZ         case 0:
519ef003fa4SKatayama Hirofumi MZ             return hOldIMC;
520c45a6e15SJames Tabor 
521*72c56c2fSKatayama Hirofumi MZ         case 1:
522ef003fa4SKatayama Hirofumi MZ             hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS);
523ef003fa4SKatayama Hirofumi MZ             if (hwndFocus == hWnd)
524c2c66affSColin Finck             {
525ef003fa4SKatayama Hirofumi MZ                 ImmSetActiveContext(hWnd, hOldIMC, FALSE);
526ef003fa4SKatayama Hirofumi MZ                 ImmSetActiveContext(hWnd, hIMC, TRUE);
527c2c66affSColin Finck             }
528ef003fa4SKatayama Hirofumi MZ             return hOldIMC;
529*72c56c2fSKatayama Hirofumi MZ 
530*72c56c2fSKatayama Hirofumi MZ         default:
531*72c56c2fSKatayama Hirofumi MZ             return NULL;
532*72c56c2fSKatayama Hirofumi MZ     }
533c2c66affSColin Finck }
534c2c66affSColin Finck 
535c2c66affSColin Finck /***********************************************************************
536c2c66affSColin Finck  *              ImmAssociateContextEx (IMM32.@)
537c2c66affSColin Finck  */
538c2c66affSColin Finck BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
539c2c66affSColin Finck {
540df6fff78SKatayama Hirofumi MZ     HWND hwndFocus;
541df6fff78SKatayama Hirofumi MZ     PWND pFocusWnd;
542df6fff78SKatayama Hirofumi MZ     HIMC hOldIMC = NULL;
543df6fff78SKatayama Hirofumi MZ     DWORD dwValue;
544c2c66affSColin Finck 
545df6fff78SKatayama Hirofumi MZ     TRACE("(%p, %p, 0x%lX)\n", hWnd, hIMC, dwFlags);
546df6fff78SKatayama Hirofumi MZ 
547356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
548c45a6e15SJames Tabor         return FALSE;
549c2c66affSColin Finck 
550df6fff78SKatayama Hirofumi MZ     if (hIMC && !(dwFlags & IACE_DEFAULT) && Imm32IsCrossThreadAccess(hIMC))
551df6fff78SKatayama Hirofumi MZ         return FALSE;
552df6fff78SKatayama Hirofumi MZ 
553df6fff78SKatayama Hirofumi MZ     hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS);
554b0b925d2SKatayama Hirofumi MZ     pFocusWnd = ValidateHwnd(hwndFocus);
555df6fff78SKatayama Hirofumi MZ     if (pFocusWnd)
556df6fff78SKatayama Hirofumi MZ         hOldIMC = pFocusWnd->hImc;
557df6fff78SKatayama Hirofumi MZ 
558df6fff78SKatayama Hirofumi MZ     dwValue = NtUserAssociateInputContext(hWnd, hIMC, dwFlags);
559df6fff78SKatayama Hirofumi MZ     switch (dwValue)
560c2c66affSColin Finck     {
561c2c66affSColin Finck         case 0:
562c2c66affSColin Finck             return TRUE;
563df6fff78SKatayama Hirofumi MZ 
564df6fff78SKatayama Hirofumi MZ         case 1:
565b0b925d2SKatayama Hirofumi MZ             pFocusWnd = ValidateHwnd(hwndFocus);
566df6fff78SKatayama Hirofumi MZ             if (pFocusWnd)
567c45a6e15SJames Tabor             {
568df6fff78SKatayama Hirofumi MZ                 hIMC = pFocusWnd->hImc;
569df6fff78SKatayama Hirofumi MZ                 if (hIMC != hOldIMC)
570df6fff78SKatayama Hirofumi MZ                 {
571df6fff78SKatayama Hirofumi MZ                     ImmSetActiveContext(hwndFocus, hOldIMC, FALSE);
572df6fff78SKatayama Hirofumi MZ                     ImmSetActiveContext(hwndFocus, hIMC, TRUE);
573c45a6e15SJames Tabor                 }
574df6fff78SKatayama Hirofumi MZ             }
575c2c66affSColin Finck             return TRUE;
576df6fff78SKatayama Hirofumi MZ 
577c2c66affSColin Finck         default:
578c2c66affSColin Finck             return FALSE;
579c2c66affSColin Finck     }
580c2c66affSColin Finck }
581c2c66affSColin Finck 
582c2c66affSColin Finck /***********************************************************************
583c2c66affSColin Finck  *		ImmCreateContext (IMM32.@)
584c2c66affSColin Finck  */
585c2c66affSColin Finck HIMC WINAPI ImmCreateContext(void)
586c2c66affSColin Finck {
587692a30a8SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
588692a30a8SKatayama Hirofumi MZ     HIMC hIMC;
589c2c66affSColin Finck 
5901d9542d2SKatayama Hirofumi MZ     TRACE("()\n");
591c2c66affSColin Finck 
592356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
593692a30a8SKatayama Hirofumi MZ         return NULL;
594c2c66affSColin Finck 
59546518ad6SKatayama Hirofumi MZ     pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
596692a30a8SKatayama Hirofumi MZ     if (pClientImc == NULL)
597692a30a8SKatayama Hirofumi MZ         return NULL;
598692a30a8SKatayama Hirofumi MZ 
599d5deacd9SKatayama Hirofumi MZ     hIMC = NtUserCreateInputContext((ULONG_PTR)pClientImc);
600692a30a8SKatayama Hirofumi MZ     if (hIMC == NULL)
601c2c66affSColin Finck     {
60246518ad6SKatayama Hirofumi MZ         ImmLocalFree(pClientImc);
603692a30a8SKatayama Hirofumi MZ         return NULL;
604c2c66affSColin Finck     }
605c2c66affSColin Finck 
606692a30a8SKatayama Hirofumi MZ     RtlInitializeCriticalSection(&pClientImc->cs);
607f4bc74edSKatayama Hirofumi MZ 
60841b87158SKatayama Hirofumi MZ     pClientImc->dwCompatFlags = (DWORD)NtUserGetThreadState(THREADSTATE_IMECOMPATFLAGS);
609f4bc74edSKatayama Hirofumi MZ 
610692a30a8SKatayama Hirofumi MZ     return hIMC;
611c2c66affSColin Finck }
612c2c66affSColin Finck 
6134342b84cSKatayama Hirofumi MZ // Win: DestroyImeModeSaver
6144342b84cSKatayama Hirofumi MZ static VOID APIENTRY Imm32DestroyImeModeSaver(LPINPUTCONTEXTDX pIC)
615c2c66affSColin Finck {
6164342b84cSKatayama Hirofumi MZ     PIME_STATE pState, pNext;
6174342b84cSKatayama Hirofumi MZ     PIME_SUBSTATE pSubState, pSubNext;
61866ef3149SKatayama Hirofumi MZ 
6194342b84cSKatayama Hirofumi MZ     for (pState = pIC->pState; pState; pState = pNext)
62066ef3149SKatayama Hirofumi MZ     {
6214342b84cSKatayama Hirofumi MZ         pNext = pState->pNext;
6224342b84cSKatayama Hirofumi MZ 
6234342b84cSKatayama Hirofumi MZ         for (pSubState = pState->pSubState; pSubState; pSubState = pSubNext)
62466ef3149SKatayama Hirofumi MZ         {
6254342b84cSKatayama Hirofumi MZ             pSubNext = pSubState->pNext;
62646518ad6SKatayama Hirofumi MZ             ImmLocalFree(pSubState);
62766ef3149SKatayama Hirofumi MZ         }
6284342b84cSKatayama Hirofumi MZ 
62946518ad6SKatayama Hirofumi MZ         ImmLocalFree(pState);
63066ef3149SKatayama Hirofumi MZ     }
6314342b84cSKatayama Hirofumi MZ 
6324342b84cSKatayama Hirofumi MZ     pIC->pState = NULL;
633692a30a8SKatayama Hirofumi MZ }
634c2c66affSColin Finck 
635a40f55bfSKatayama Hirofumi MZ // Win: DestroyInputContext
636f8902dc3SKatayama Hirofumi MZ BOOL APIENTRY Imm32DestroyInputContext(HIMC hIMC, HKL hKL, BOOL bKeep)
637692a30a8SKatayama Hirofumi MZ {
638692a30a8SKatayama Hirofumi MZ     PIMEDPI pImeDpi;
63966ef3149SKatayama Hirofumi MZ     LPINPUTCONTEXTDX pIC;
640692a30a8SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
641be9a788fSKatayama Hirofumi MZ     PIMC pIMC;
642692a30a8SKatayama Hirofumi MZ 
6434342b84cSKatayama Hirofumi MZ     if (!hIMC || !IS_IMM_MODE())
644c2c66affSColin Finck         return FALSE;
645c2c66affSColin Finck 
646b0b925d2SKatayama Hirofumi MZ     pIMC = ValidateHandle(hIMC, TYPE_INPUTCONTEXT);
64745a4e53fSKatayama Hirofumi MZ     if (!pIMC || pIMC->head.pti != Imm32CurrentPti())
64845a4e53fSKatayama Hirofumi MZ     {
64945a4e53fSKatayama Hirofumi MZ         ERR("invalid pIMC: %p\n", pIMC);
650be9a788fSKatayama Hirofumi MZ         return FALSE;
65145a4e53fSKatayama Hirofumi MZ     }
652be9a788fSKatayama Hirofumi MZ 
653be9a788fSKatayama Hirofumi MZ     pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
654692a30a8SKatayama Hirofumi MZ     if (!pClientImc)
65545a4e53fSKatayama Hirofumi MZ         goto Finish;
656c2c66affSColin Finck 
65745a4e53fSKatayama Hirofumi MZ     if ((pClientImc->dwFlags & CLIENTIMC_UNKNOWN2) && !bKeep)
658692a30a8SKatayama Hirofumi MZ     {
65945a4e53fSKatayama Hirofumi MZ         ERR("CLIENTIMC_UNKNOWN2\n");
66045a4e53fSKatayama Hirofumi MZ         return FALSE;
661692a30a8SKatayama Hirofumi MZ     }
662c2c66affSColin Finck 
6636ba810c0SKatayama Hirofumi MZ     if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
66445a4e53fSKatayama Hirofumi MZ         return TRUE;
66545a4e53fSKatayama Hirofumi MZ 
66645a4e53fSKatayama Hirofumi MZ     InterlockedIncrement(&pClientImc->cLockObj);
66745a4e53fSKatayama Hirofumi MZ 
66845a4e53fSKatayama Hirofumi MZ     if (!pClientImc->hInputContext)
66945a4e53fSKatayama Hirofumi MZ         goto Quit;
67045a4e53fSKatayama Hirofumi MZ 
67166ef3149SKatayama Hirofumi MZ     pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
67245a4e53fSKatayama Hirofumi MZ     if (!pIC)
673692a30a8SKatayama Hirofumi MZ     {
674692a30a8SKatayama Hirofumi MZ         ImmUnlockClientImc(pClientImc);
67545a4e53fSKatayama Hirofumi MZ         ERR("!pIC\n");
676692a30a8SKatayama Hirofumi MZ         return FALSE;
677692a30a8SKatayama Hirofumi MZ     }
678692a30a8SKatayama Hirofumi MZ 
6794342b84cSKatayama Hirofumi MZ     CtfImmTIMDestroyInputContext(hIMC);
6804342b84cSKatayama Hirofumi MZ 
6814342b84cSKatayama Hirofumi MZ     if (pClientImc->hKL == hKL)
6824342b84cSKatayama Hirofumi MZ     {
683692a30a8SKatayama Hirofumi MZ         pImeDpi = ImmLockImeDpi(hKL);
68445a4e53fSKatayama Hirofumi MZ         if (pImeDpi)
685692a30a8SKatayama Hirofumi MZ         {
6864342b84cSKatayama Hirofumi MZ             if (IS_IME_HKL(hKL))
687692a30a8SKatayama Hirofumi MZ                 pImeDpi->ImeSelect(hIMC, FALSE);
6888ba378c9SKatayama Hirofumi MZ             else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
6894342b84cSKatayama Hirofumi MZ                 pImeDpi->CtfImeSelectEx(hIMC, FALSE, hKL);
6904342b84cSKatayama Hirofumi MZ 
691692a30a8SKatayama Hirofumi MZ             ImmUnlockImeDpi(pImeDpi);
692692a30a8SKatayama Hirofumi MZ         }
693692a30a8SKatayama Hirofumi MZ 
6944342b84cSKatayama Hirofumi MZ         pClientImc->hKL = NULL;
6954342b84cSKatayama Hirofumi MZ     }
6964342b84cSKatayama Hirofumi MZ 
6974342b84cSKatayama Hirofumi MZ     ImmDestroyIMCC(pIC->hPrivate);
6984342b84cSKatayama Hirofumi MZ     ImmDestroyIMCC(pIC->hMsgBuf);
6994342b84cSKatayama Hirofumi MZ     ImmDestroyIMCC(pIC->hGuideLine);
7004342b84cSKatayama Hirofumi MZ     ImmDestroyIMCC(pIC->hCandInfo);
7014342b84cSKatayama Hirofumi MZ     ImmDestroyIMCC(pIC->hCompStr);
7024342b84cSKatayama Hirofumi MZ     Imm32DestroyImeModeSaver(pIC);
703692a30a8SKatayama Hirofumi MZ     ImmUnlockIMC(hIMC);
704692a30a8SKatayama Hirofumi MZ 
70545a4e53fSKatayama Hirofumi MZ Quit:
7066ba810c0SKatayama Hirofumi MZ     pClientImc->dwFlags |= CLIENTIMC_DESTROY;
707692a30a8SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
708692a30a8SKatayama Hirofumi MZ 
70945a4e53fSKatayama Hirofumi MZ Finish:
71045a4e53fSKatayama Hirofumi MZ     if (bKeep)
711c2c66affSColin Finck         return TRUE;
71245a4e53fSKatayama Hirofumi MZ     return NtUserDestroyInputContext(hIMC);
713c2c66affSColin Finck }
714c2c66affSColin Finck 
7158de74398SKatayama Hirofumi MZ // NOTE: Windows does recursive call ImmLockIMC here but we don't do so.
7168de74398SKatayama Hirofumi MZ // Win: BOOL CreateInputContext(HIMC hIMC, HKL hKL, BOOL fSelect)
717b3382d8dSKatayama Hirofumi MZ BOOL APIENTRY
7188de74398SKatayama Hirofumi MZ Imm32CreateInputContext(HIMC hIMC, LPINPUTCONTEXT pIC, PCLIENTIMC pClientImc, HKL hKL, BOOL fSelect)
719b3382d8dSKatayama Hirofumi MZ {
720b3382d8dSKatayama Hirofumi MZ     DWORD dwIndex, cbPrivate;
721b3382d8dSKatayama Hirofumi MZ     PIMEDPI pImeDpi = NULL;
722b3382d8dSKatayama Hirofumi MZ     LPCOMPOSITIONSTRING pCS;
723b3382d8dSKatayama Hirofumi MZ     LPCANDIDATEINFO pCI;
724b3382d8dSKatayama Hirofumi MZ     LPGUIDELINE pGL;
725b3382d8dSKatayama Hirofumi MZ 
726b3382d8dSKatayama Hirofumi MZ     /* Create IC components */
727b3382d8dSKatayama Hirofumi MZ     pIC->hCompStr = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
728b3382d8dSKatayama Hirofumi MZ     pIC->hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
729b3382d8dSKatayama Hirofumi MZ     pIC->hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
730b3382d8dSKatayama Hirofumi MZ     pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
731b3382d8dSKatayama Hirofumi MZ     if (!pIC->hCompStr || !pIC->hCandInfo || !pIC->hGuideLine || !pIC->hMsgBuf)
732b3382d8dSKatayama Hirofumi MZ         goto Fail;
733b3382d8dSKatayama Hirofumi MZ 
734b3382d8dSKatayama Hirofumi MZ     /* Initialize IC components */
735b3382d8dSKatayama Hirofumi MZ     pCS = ImmLockIMCC(pIC->hCompStr);
736b3382d8dSKatayama Hirofumi MZ     if (!pCS)
737b3382d8dSKatayama Hirofumi MZ         goto Fail;
738b3382d8dSKatayama Hirofumi MZ     pCS->dwSize = sizeof(COMPOSITIONSTRING);
739b3382d8dSKatayama Hirofumi MZ     ImmUnlockIMCC(pIC->hCompStr);
740b3382d8dSKatayama Hirofumi MZ 
741b3382d8dSKatayama Hirofumi MZ     pCI = ImmLockIMCC(pIC->hCandInfo);
742b3382d8dSKatayama Hirofumi MZ     if (!pCI)
743b3382d8dSKatayama Hirofumi MZ         goto Fail;
744b3382d8dSKatayama Hirofumi MZ     pCI->dwSize = sizeof(CANDIDATEINFO);
745b3382d8dSKatayama Hirofumi MZ     ImmUnlockIMCC(pIC->hCandInfo);
746b3382d8dSKatayama Hirofumi MZ 
747b3382d8dSKatayama Hirofumi MZ     pGL = ImmLockIMCC(pIC->hGuideLine);
748b3382d8dSKatayama Hirofumi MZ     if (!pGL)
749b3382d8dSKatayama Hirofumi MZ         goto Fail;
750b3382d8dSKatayama Hirofumi MZ     pGL->dwSize = sizeof(GUIDELINE);
751b3382d8dSKatayama Hirofumi MZ     ImmUnlockIMCC(pIC->hGuideLine);
752b3382d8dSKatayama Hirofumi MZ 
753b3382d8dSKatayama Hirofumi MZ     pIC->dwNumMsgBuf = 0;
754b3382d8dSKatayama Hirofumi MZ     pIC->fOpen = FALSE;
755b3382d8dSKatayama Hirofumi MZ     pIC->fdwConversion = pIC->fdwSentence = 0;
756b3382d8dSKatayama Hirofumi MZ 
757b3382d8dSKatayama Hirofumi MZ     for (dwIndex = 0; dwIndex < MAX_CANDIDATEFORM; ++dwIndex)
758b3382d8dSKatayama Hirofumi MZ         pIC->cfCandForm[dwIndex].dwIndex = IMM_INVALID_CANDFORM;
759b3382d8dSKatayama Hirofumi MZ 
760b3382d8dSKatayama Hirofumi MZ     /* Get private data size */
761b3382d8dSKatayama Hirofumi MZ     pImeDpi = ImmLockImeDpi(hKL);
762b3382d8dSKatayama Hirofumi MZ     if (!pImeDpi)
763b3382d8dSKatayama Hirofumi MZ     {
764b3382d8dSKatayama Hirofumi MZ         cbPrivate = sizeof(DWORD);
765b3382d8dSKatayama Hirofumi MZ     }
766b3382d8dSKatayama Hirofumi MZ     else
767b3382d8dSKatayama Hirofumi MZ     {
768b3382d8dSKatayama Hirofumi MZ         /* Update CLIENTIMC */
769b3382d8dSKatayama Hirofumi MZ         pClientImc->uCodePage = pImeDpi->uCodePage;
770b3382d8dSKatayama Hirofumi MZ         if (ImeDpi_IsUnicode(pImeDpi))
771b3382d8dSKatayama Hirofumi MZ             pClientImc->dwFlags |= CLIENTIMC_WIDE;
772b3382d8dSKatayama Hirofumi MZ 
773b3382d8dSKatayama Hirofumi MZ         cbPrivate = pImeDpi->ImeInfo.dwPrivateDataSize;
774b3382d8dSKatayama Hirofumi MZ     }
775b3382d8dSKatayama Hirofumi MZ 
776b3382d8dSKatayama Hirofumi MZ     /* Create private data */
777b3382d8dSKatayama Hirofumi MZ     pIC->hPrivate = ImmCreateIMCC(cbPrivate);
778b3382d8dSKatayama Hirofumi MZ     if (!pIC->hPrivate)
779b3382d8dSKatayama Hirofumi MZ         goto Fail;
780b3382d8dSKatayama Hirofumi MZ 
781b3382d8dSKatayama Hirofumi MZ     if (pImeDpi)
782b3382d8dSKatayama Hirofumi MZ     {
783b3382d8dSKatayama Hirofumi MZ         /* Select the IME */
784b3382d8dSKatayama Hirofumi MZ         if (fSelect)
785b3382d8dSKatayama Hirofumi MZ         {
786b3382d8dSKatayama Hirofumi MZ             if (IS_IME_HKL(hKL))
787b3382d8dSKatayama Hirofumi MZ                 pImeDpi->ImeSelect(hIMC, TRUE);
788020d7d58SKatayama Hirofumi MZ             else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
789b3382d8dSKatayama Hirofumi MZ                 pImeDpi->CtfImeSelectEx(hIMC, TRUE, hKL);
790b3382d8dSKatayama Hirofumi MZ         }
791b3382d8dSKatayama Hirofumi MZ 
792b3382d8dSKatayama Hirofumi MZ         /* Set HKL */
793b3382d8dSKatayama Hirofumi MZ         pClientImc->hKL = hKL;
794b3382d8dSKatayama Hirofumi MZ 
795b3382d8dSKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
796b3382d8dSKatayama Hirofumi MZ     }
797b3382d8dSKatayama Hirofumi MZ 
798b3382d8dSKatayama Hirofumi MZ     return TRUE;
799b3382d8dSKatayama Hirofumi MZ 
800b3382d8dSKatayama Hirofumi MZ Fail:
801b3382d8dSKatayama Hirofumi MZ     if (pImeDpi)
802b3382d8dSKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
803b3382d8dSKatayama Hirofumi MZ 
804b3382d8dSKatayama Hirofumi MZ     pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
805b3382d8dSKatayama Hirofumi MZ     pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
806b3382d8dSKatayama Hirofumi MZ     pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
807b3382d8dSKatayama Hirofumi MZ     pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
808b3382d8dSKatayama Hirofumi MZ     return FALSE;
809b3382d8dSKatayama Hirofumi MZ }
810b3382d8dSKatayama Hirofumi MZ 
811a40f55bfSKatayama Hirofumi MZ // Win: InternalImmLockIMC
8128de74398SKatayama Hirofumi MZ LPINPUTCONTEXT APIENTRY Imm32InternalLockIMC(HIMC hIMC, BOOL fSelect)
813b3382d8dSKatayama Hirofumi MZ {
814b3382d8dSKatayama Hirofumi MZ     HANDLE hIC;
815b3382d8dSKatayama Hirofumi MZ     LPINPUTCONTEXT pIC = NULL;
816b3382d8dSKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
8178de74398SKatayama Hirofumi MZ     WORD LangID;
818b3382d8dSKatayama Hirofumi MZ     DWORD dwThreadId;
8198de74398SKatayama Hirofumi MZ     HKL hOldKL, hNewKL;
820b3382d8dSKatayama Hirofumi MZ     PIMEDPI pImeDpi = NULL;
821b3382d8dSKatayama Hirofumi MZ 
822b3382d8dSKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
823b3382d8dSKatayama Hirofumi MZ     if (!pClientImc)
824b3382d8dSKatayama Hirofumi MZ         return NULL;
825b3382d8dSKatayama Hirofumi MZ 
826b3382d8dSKatayama Hirofumi MZ     RtlEnterCriticalSection(&pClientImc->cs);
827b3382d8dSKatayama Hirofumi MZ 
8288de74398SKatayama Hirofumi MZ     if (pClientImc->hInputContext)
8298f719cb9SKatayama Hirofumi MZ     {
8308f719cb9SKatayama Hirofumi MZ         pIC = LocalLock(pClientImc->hInputContext);
8318f719cb9SKatayama Hirofumi MZ         if (pIC)
8328f719cb9SKatayama Hirofumi MZ             goto Success;
8338f719cb9SKatayama Hirofumi MZ         else
8348f719cb9SKatayama Hirofumi MZ             goto Failure;
8358f719cb9SKatayama Hirofumi MZ     }
836b3382d8dSKatayama Hirofumi MZ 
8378de74398SKatayama Hirofumi MZ     dwThreadId = (DWORD)NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID);
8388ba378c9SKatayama Hirofumi MZ     if (dwThreadId == GetCurrentThreadId() && IS_CICERO_MODE() && !IS_16BIT_MODE())
839b3382d8dSKatayama Hirofumi MZ     {
8408de74398SKatayama Hirofumi MZ         hOldKL = GetKeyboardLayout(0);
8418de74398SKatayama Hirofumi MZ         LangID = LOWORD(hOldKL);
8428de74398SKatayama Hirofumi MZ         hNewKL = (HKL)(DWORD_PTR)MAKELONG(LangID, LangID);
843b3382d8dSKatayama Hirofumi MZ 
84497f4c3c3SKatayama Hirofumi MZ         pImeDpi = Imm32FindOrLoadImeDpi(hNewKL);
845b3382d8dSKatayama Hirofumi MZ         if (pImeDpi)
846b3382d8dSKatayama Hirofumi MZ         {
8478de74398SKatayama Hirofumi MZ             CtfImmTIMActivate(hNewKL);
848b3382d8dSKatayama Hirofumi MZ         }
849b3382d8dSKatayama Hirofumi MZ     }
850b3382d8dSKatayama Hirofumi MZ 
851cdf3b5e8SKatayama Hirofumi MZ     if (!NtUserQueryInputContext(hIMC, QIC_DEFAULTWINDOWIME))
8528f719cb9SKatayama Hirofumi MZ         goto Failure;
853b3382d8dSKatayama Hirofumi MZ 
854b3382d8dSKatayama Hirofumi MZ     hIC = LocalAlloc(LHND, sizeof(INPUTCONTEXTDX));
8558de74398SKatayama Hirofumi MZ     pIC = LocalLock(hIC);
8568de74398SKatayama Hirofumi MZ     if (!pIC)
857b3382d8dSKatayama Hirofumi MZ     {
8588de74398SKatayama Hirofumi MZ         LocalFree(hIC);
8598f719cb9SKatayama Hirofumi MZ         goto Failure;
860b3382d8dSKatayama Hirofumi MZ     }
861b3382d8dSKatayama Hirofumi MZ     pClientImc->hInputContext = hIC;
862b3382d8dSKatayama Hirofumi MZ 
8638de74398SKatayama Hirofumi MZ     hNewKL = GetKeyboardLayout(dwThreadId);
8648de74398SKatayama Hirofumi MZ     if (!Imm32CreateInputContext(hIMC, pIC, pClientImc, hNewKL, fSelect))
865b3382d8dSKatayama Hirofumi MZ     {
866b3382d8dSKatayama Hirofumi MZ         pClientImc->hInputContext = LocalFree(pClientImc->hInputContext);
8678f719cb9SKatayama Hirofumi MZ         goto Failure;
868b3382d8dSKatayama Hirofumi MZ     }
869b3382d8dSKatayama Hirofumi MZ 
8708f719cb9SKatayama Hirofumi MZ Success:
8718de74398SKatayama Hirofumi MZ     CtfImmTIMCreateInputContext(hIMC);
872b3382d8dSKatayama Hirofumi MZ     RtlLeaveCriticalSection(&pClientImc->cs);
873b3382d8dSKatayama Hirofumi MZ     InterlockedIncrement(&pClientImc->cLockObj);
874b3382d8dSKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
875b3382d8dSKatayama Hirofumi MZ     return pIC;
8768de74398SKatayama Hirofumi MZ 
8778f719cb9SKatayama Hirofumi MZ Failure:
8788de74398SKatayama Hirofumi MZ     RtlLeaveCriticalSection(&pClientImc->cs);
8798de74398SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
8808de74398SKatayama Hirofumi MZ     return NULL;
881b3382d8dSKatayama Hirofumi MZ }
882b3382d8dSKatayama Hirofumi MZ 
883c2c66affSColin Finck /***********************************************************************
884c2c66affSColin Finck  *		ImmDestroyContext (IMM32.@)
885c2c66affSColin Finck  */
886c2c66affSColin Finck BOOL WINAPI ImmDestroyContext(HIMC hIMC)
887c2c66affSColin Finck {
888692a30a8SKatayama Hirofumi MZ     HKL hKL;
889692a30a8SKatayama Hirofumi MZ 
8901d9542d2SKatayama Hirofumi MZ     TRACE("(%p)\n", hIMC);
891692a30a8SKatayama Hirofumi MZ 
892356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
893c2c66affSColin Finck         return FALSE;
894692a30a8SKatayama Hirofumi MZ 
8951da5d7a3SKatayama Hirofumi MZ     if (Imm32IsCrossThreadAccess(hIMC))
896692a30a8SKatayama Hirofumi MZ         return FALSE;
897692a30a8SKatayama Hirofumi MZ 
898692a30a8SKatayama Hirofumi MZ     hKL = GetKeyboardLayout(0);
899f8902dc3SKatayama Hirofumi MZ     return Imm32DestroyInputContext(hIMC, hKL, FALSE);
900c2c66affSColin Finck }
901c2c66affSColin Finck 
9021da5d7a3SKatayama Hirofumi MZ /***********************************************************************
9031da5d7a3SKatayama Hirofumi MZ  *		ImmLockClientImc (IMM32.@)
9041da5d7a3SKatayama Hirofumi MZ  */
90592393a75SKatayama Hirofumi MZ PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
90692393a75SKatayama Hirofumi MZ {
907be9a788fSKatayama Hirofumi MZ     PIMC pIMC;
90892393a75SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
90992393a75SKatayama Hirofumi MZ 
9101d9542d2SKatayama Hirofumi MZ     TRACE("(%p)\n", hImc);
91192393a75SKatayama Hirofumi MZ 
912f848343bSKatayama Hirofumi MZ     if (!hImc)
91392393a75SKatayama Hirofumi MZ         return NULL;
91492393a75SKatayama Hirofumi MZ 
915b0b925d2SKatayama Hirofumi MZ     pIMC = ValidateHandle(hImc, TYPE_INPUTCONTEXT);
916f848343bSKatayama Hirofumi MZ     if (!pIMC || !Imm32CheckImcProcess(pIMC))
917be9a788fSKatayama Hirofumi MZ         return NULL;
918be9a788fSKatayama Hirofumi MZ 
919be9a788fSKatayama Hirofumi MZ     pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
920f848343bSKatayama Hirofumi MZ     if (pClientImc)
92192393a75SKatayama Hirofumi MZ     {
922f848343bSKatayama Hirofumi MZ         if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
923f848343bSKatayama Hirofumi MZ             return NULL;
924f848343bSKatayama Hirofumi MZ         goto Finish;
925f848343bSKatayama Hirofumi MZ     }
926f848343bSKatayama Hirofumi MZ 
92746518ad6SKatayama Hirofumi MZ     pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
92892393a75SKatayama Hirofumi MZ     if (!pClientImc)
92992393a75SKatayama Hirofumi MZ         return NULL;
93092393a75SKatayama Hirofumi MZ 
93192393a75SKatayama Hirofumi MZ     RtlInitializeCriticalSection(&pClientImc->cs);
93241b87158SKatayama Hirofumi MZ     pClientImc->dwCompatFlags = (DWORD)NtUserGetThreadState(THREADSTATE_IMECOMPATFLAGS);
93392393a75SKatayama Hirofumi MZ 
934ba3affe5SKatayama Hirofumi MZ     if (!NtUserUpdateInputContext(hImc, UIC_CLIENTIMCDATA, (DWORD_PTR)pClientImc))
93592393a75SKatayama Hirofumi MZ     {
93646518ad6SKatayama Hirofumi MZ         ImmLocalFree(pClientImc);
93792393a75SKatayama Hirofumi MZ         return NULL;
93892393a75SKatayama Hirofumi MZ     }
93992393a75SKatayama Hirofumi MZ 
94092393a75SKatayama Hirofumi MZ     pClientImc->dwFlags |= CLIENTIMC_UNKNOWN2;
94192393a75SKatayama Hirofumi MZ 
942f848343bSKatayama Hirofumi MZ Finish:
94392393a75SKatayama Hirofumi MZ     InterlockedIncrement(&pClientImc->cLockObj);
94492393a75SKatayama Hirofumi MZ     return pClientImc;
94592393a75SKatayama Hirofumi MZ }
94692393a75SKatayama Hirofumi MZ 
9471da5d7a3SKatayama Hirofumi MZ /***********************************************************************
9481da5d7a3SKatayama Hirofumi MZ  *		ImmUnlockClientImc (IMM32.@)
9491da5d7a3SKatayama Hirofumi MZ  */
95092393a75SKatayama Hirofumi MZ VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
95192393a75SKatayama Hirofumi MZ {
95292393a75SKatayama Hirofumi MZ     LONG cLocks;
953b3382d8dSKatayama Hirofumi MZ     HANDLE hInputContext;
95492393a75SKatayama Hirofumi MZ 
9551d9542d2SKatayama Hirofumi MZ     TRACE("(%p)\n", pClientImc);
95692393a75SKatayama Hirofumi MZ 
95792393a75SKatayama Hirofumi MZ     cLocks = InterlockedDecrement(&pClientImc->cLockObj);
9586ba810c0SKatayama Hirofumi MZ     if (cLocks != 0 || !(pClientImc->dwFlags & CLIENTIMC_DESTROY))
95992393a75SKatayama Hirofumi MZ         return;
96092393a75SKatayama Hirofumi MZ 
961b3382d8dSKatayama Hirofumi MZ     hInputContext = pClientImc->hInputContext;
962b3382d8dSKatayama Hirofumi MZ     if (hInputContext)
963b3382d8dSKatayama Hirofumi MZ         LocalFree(hInputContext);
96492393a75SKatayama Hirofumi MZ 
96592393a75SKatayama Hirofumi MZ     RtlDeleteCriticalSection(&pClientImc->cs);
96646518ad6SKatayama Hirofumi MZ     ImmLocalFree(pClientImc);
96792393a75SKatayama Hirofumi MZ }
96892393a75SKatayama Hirofumi MZ 
969a40f55bfSKatayama Hirofumi MZ // Win: ImmGetSaveContext
970720da3b9SKatayama Hirofumi MZ static HIMC APIENTRY ImmGetSaveContext(HWND hWnd, DWORD dwContextFlags)
971a8d2cd4bSKatayama Hirofumi MZ {
972a8d2cd4bSKatayama Hirofumi MZ     HIMC hIMC;
973a8d2cd4bSKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
974a8d2cd4bSKatayama Hirofumi MZ     PWND pWnd;
975a8d2cd4bSKatayama Hirofumi MZ 
976356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
977a8d2cd4bSKatayama Hirofumi MZ         return NULL;
978a8d2cd4bSKatayama Hirofumi MZ 
979a8d2cd4bSKatayama Hirofumi MZ     if (!hWnd)
980a8d2cd4bSKatayama Hirofumi MZ     {
98141b87158SKatayama Hirofumi MZ         hIMC = (HIMC)NtUserGetThreadState(THREADSTATE_DEFAULTINPUTCONTEXT);
982a8d2cd4bSKatayama Hirofumi MZ         goto Quit;
983a8d2cd4bSKatayama Hirofumi MZ     }
984a8d2cd4bSKatayama Hirofumi MZ 
985b0b925d2SKatayama Hirofumi MZ     pWnd = ValidateHwnd(hWnd);
986a8d2cd4bSKatayama Hirofumi MZ     if (!pWnd || Imm32IsCrossProcessAccess(hWnd))
987a8d2cd4bSKatayama Hirofumi MZ         return NULL;
988a8d2cd4bSKatayama Hirofumi MZ 
989a8d2cd4bSKatayama Hirofumi MZ     hIMC = pWnd->hImc;
990a8d2cd4bSKatayama Hirofumi MZ     if (!hIMC && (dwContextFlags & 1))
991a8d2cd4bSKatayama Hirofumi MZ         hIMC = (HIMC)NtUserQueryWindow(hWnd, QUERY_WINDOW_DEFAULT_ICONTEXT);
992a8d2cd4bSKatayama Hirofumi MZ 
993a8d2cd4bSKatayama Hirofumi MZ Quit:
994a8d2cd4bSKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
995a8d2cd4bSKatayama Hirofumi MZ     if (pClientImc == NULL)
996a8d2cd4bSKatayama Hirofumi MZ         return NULL;
997934e5212SKatayama Hirofumi MZ     if ((dwContextFlags & 2) && (pClientImc->dwFlags & CLIENTIMC_DISABLEIME))
998a8d2cd4bSKatayama Hirofumi MZ         hIMC = NULL;
999a8d2cd4bSKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
1000a8d2cd4bSKatayama Hirofumi MZ     return hIMC;
1001a8d2cd4bSKatayama Hirofumi MZ }
1002a8d2cd4bSKatayama Hirofumi MZ 
1003c2c66affSColin Finck /***********************************************************************
1004c2c66affSColin Finck  *		ImmGetContext (IMM32.@)
1005c2c66affSColin Finck  */
1006c2c66affSColin Finck HIMC WINAPI ImmGetContext(HWND hWnd)
1007c2c66affSColin Finck {
1008a8d2cd4bSKatayama Hirofumi MZ     TRACE("(%p)\n", hWnd);
1009a8d2cd4bSKatayama Hirofumi MZ     if (hWnd == NULL)
1010c2c66affSColin Finck         return NULL;
1011720da3b9SKatayama Hirofumi MZ     return ImmGetSaveContext(hWnd, 2);
1012c2c66affSColin Finck }
1013c2c66affSColin Finck 
1014c2c66affSColin Finck /***********************************************************************
1015b4557a60SKatayama Hirofumi MZ  *		ImmLockIMC(IMM32.@)
1016b3382d8dSKatayama Hirofumi MZ  *
1017b3382d8dSKatayama Hirofumi MZ  * NOTE: This is not ImmLockIMCC. Don't confuse.
1018c2c66affSColin Finck  */
1019b4557a60SKatayama Hirofumi MZ LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
1020c2c66affSColin Finck {
1021b3382d8dSKatayama Hirofumi MZ     TRACE("(%p)\n", hIMC);
10228de74398SKatayama Hirofumi MZ     return Imm32InternalLockIMC(hIMC, TRUE);
1023c2c66affSColin Finck }
1024c2c66affSColin Finck 
1025b4557a60SKatayama Hirofumi MZ /***********************************************************************
1026b4557a60SKatayama Hirofumi MZ *		ImmUnlockIMC(IMM32.@)
1027b4557a60SKatayama Hirofumi MZ */
1028b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
102977911014SKatayama Hirofumi MZ {
1030b4557a60SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
1031b4557a60SKatayama Hirofumi MZ 
1032b4557a60SKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
1033b4557a60SKatayama Hirofumi MZ     if (pClientImc == NULL)
103477911014SKatayama Hirofumi MZ         return FALSE;
103577911014SKatayama Hirofumi MZ 
1036b3382d8dSKatayama Hirofumi MZ     if (pClientImc->hInputContext)
1037b3382d8dSKatayama Hirofumi MZ         LocalUnlock(pClientImc->hInputContext);
1038b4557a60SKatayama Hirofumi MZ 
1039b4557a60SKatayama Hirofumi MZ     InterlockedDecrement(&pClientImc->cLockObj);
1040b4557a60SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
104177911014SKatayama Hirofumi MZ     return TRUE;
1042c2c66affSColin Finck }
1043c2c66affSColin Finck 
1044c2c66affSColin Finck /***********************************************************************
1045b4557a60SKatayama Hirofumi MZ  *		ImmReleaseContext (IMM32.@)
1046c2c66affSColin Finck  */
1047b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1048c2c66affSColin Finck {
1049b4557a60SKatayama Hirofumi MZ     TRACE("(%p, %p)\n", hWnd, hIMC);
1050b4557a60SKatayama Hirofumi MZ     UNREFERENCED_PARAMETER(hWnd);
1051b4557a60SKatayama Hirofumi MZ     UNREFERENCED_PARAMETER(hIMC);
1052b4557a60SKatayama Hirofumi MZ     return TRUE; // Do nothing. This is correct.
1053c2c66affSColin Finck }
1054c2c66affSColin Finck 
1055c2c66affSColin Finck /***********************************************************************
1056c2c66affSColin Finck  *              ImmCreateSoftKeyboard(IMM32.@)
1057c2c66affSColin Finck  */
1058c2c66affSColin Finck HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y)
1059c2c66affSColin Finck {
1060c2c66affSColin Finck     FIXME("(%d, %d, %d, %d): stub\n", uType, hOwner, x, y);
1061c2c66affSColin Finck     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1062c2c66affSColin Finck     return 0;
1063c2c66affSColin Finck }
1064c2c66affSColin Finck 
1065c2c66affSColin Finck /***********************************************************************
1066c2c66affSColin Finck  *              ImmDestroySoftKeyboard(IMM32.@)
1067c2c66affSColin Finck  */
1068c2c66affSColin Finck BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
1069c2c66affSColin Finck {
10702705abfbSKatayama Hirofumi MZ     TRACE("(%p)\n", hSoftWnd);
10712705abfbSKatayama Hirofumi MZ     return DestroyWindow(hSoftWnd);
1072c2c66affSColin Finck }
1073c2c66affSColin Finck 
1074c2c66affSColin Finck /***********************************************************************
1075c2c66affSColin Finck  *              ImmShowSoftKeyboard(IMM32.@)
1076c2c66affSColin Finck  */
1077c2c66affSColin Finck BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
1078c2c66affSColin Finck {
10792705abfbSKatayama Hirofumi MZ     TRACE("(%p, %d)\n", hSoftWnd, nCmdShow);
10802705abfbSKatayama Hirofumi MZ     if (hSoftWnd)
10812705abfbSKatayama Hirofumi MZ         return ShowWindow(hSoftWnd, nCmdShow);
1082c2c66affSColin Finck     return FALSE;
1083c2c66affSColin Finck }
1084c2c66affSColin Finck 
1085c2c66affSColin Finck /***********************************************************************
1086b4557a60SKatayama Hirofumi MZ *		ImmDisableTextFrameService(IMM32.@)
1087c2c66affSColin Finck */
1088b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmDisableTextFrameService(DWORD dwThreadId)
1089b4557a60SKatayama Hirofumi MZ {
1090b4557a60SKatayama Hirofumi MZ     FIXME("Stub\n");
1091b4557a60SKatayama Hirofumi MZ     return FALSE;
1092b4557a60SKatayama Hirofumi MZ }
1093b4557a60SKatayama Hirofumi MZ 
1094b4557a60SKatayama Hirofumi MZ /***********************************************************************
1095b4557a60SKatayama Hirofumi MZ  *              ImmEnumInputContext(IMM32.@)
1096b4557a60SKatayama Hirofumi MZ  */
1097b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmEnumInputContext(DWORD dwThreadId, IMCENUMPROC lpfn, LPARAM lParam)
1098b4557a60SKatayama Hirofumi MZ {
1099b4557a60SKatayama Hirofumi MZ     HIMC *phList;
1100b4557a60SKatayama Hirofumi MZ     DWORD dwIndex, dwCount;
1101b4557a60SKatayama Hirofumi MZ     BOOL ret = TRUE;
1102b4557a60SKatayama Hirofumi MZ     HIMC hIMC;
1103b4557a60SKatayama Hirofumi MZ 
1104b4557a60SKatayama Hirofumi MZ     TRACE("(%lu, %p, %p)\n", dwThreadId, lpfn, lParam);
1105b4557a60SKatayama Hirofumi MZ 
1106bc8a4ac3SKatayama Hirofumi MZ     dwCount = Imm32BuildHimcList(dwThreadId, &phList);
1107b4557a60SKatayama Hirofumi MZ     if (!dwCount)
1108b4557a60SKatayama Hirofumi MZ         return FALSE;
1109b4557a60SKatayama Hirofumi MZ 
1110b4557a60SKatayama Hirofumi MZ     for (dwIndex = 0; dwIndex < dwCount; ++dwIndex)
1111b4557a60SKatayama Hirofumi MZ     {
1112b4557a60SKatayama Hirofumi MZ         hIMC = phList[dwIndex];
1113b4557a60SKatayama Hirofumi MZ         ret = (*lpfn)(hIMC, lParam);
1114b4557a60SKatayama Hirofumi MZ         if (!ret)
1115b4557a60SKatayama Hirofumi MZ             break;
1116b4557a60SKatayama Hirofumi MZ     }
1117b4557a60SKatayama Hirofumi MZ 
111846518ad6SKatayama Hirofumi MZ     ImmLocalFree(phList);
1119b4557a60SKatayama Hirofumi MZ     return ret;
1120b4557a60SKatayama Hirofumi MZ }
1121b4557a60SKatayama Hirofumi MZ 
1122b4557a60SKatayama Hirofumi MZ /***********************************************************************
1123b4557a60SKatayama Hirofumi MZ  *              ImmSetActiveContext(IMM32.@)
1124b4557a60SKatayama Hirofumi MZ  */
11259adc538cSKatayama Hirofumi MZ BOOL WINAPI ImmSetActiveContext(HWND hWnd, HIMC hIMC, BOOL fActive)
1126b4557a60SKatayama Hirofumi MZ {
11279adc538cSKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
11289adc538cSKatayama Hirofumi MZ     LPINPUTCONTEXTDX pIC;
11299adc538cSKatayama Hirofumi MZ     PIMEDPI pImeDpi;
11309adc538cSKatayama Hirofumi MZ     HKL hKL;
11319adc538cSKatayama Hirofumi MZ     BOOL fOpen = FALSE;
11329adc538cSKatayama Hirofumi MZ     DWORD dwConversion = 0, iShow = ISC_SHOWUIALL;
11339adc538cSKatayama Hirofumi MZ     HWND hwndDefIME;
11349adc538cSKatayama Hirofumi MZ 
11359adc538cSKatayama Hirofumi MZ     TRACE("(%p, %p, %d)\n", hWnd, hIMC, fActive);
11369adc538cSKatayama Hirofumi MZ 
1137356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1138b4557a60SKatayama Hirofumi MZ         return FALSE;
11399adc538cSKatayama Hirofumi MZ 
11409adc538cSKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
11419adc538cSKatayama Hirofumi MZ 
11429adc538cSKatayama Hirofumi MZ     if (!fActive)
11439adc538cSKatayama Hirofumi MZ     {
11449adc538cSKatayama Hirofumi MZ         if (pClientImc)
11459adc538cSKatayama Hirofumi MZ             pClientImc->dwFlags &= ~CLIENTIMC_UNKNOWN4;
11469adc538cSKatayama Hirofumi MZ     }
11479adc538cSKatayama Hirofumi MZ     else if (hIMC)
11489adc538cSKatayama Hirofumi MZ     {
11499adc538cSKatayama Hirofumi MZ         if (!pClientImc)
11509adc538cSKatayama Hirofumi MZ             return FALSE;
11519adc538cSKatayama Hirofumi MZ 
11529adc538cSKatayama Hirofumi MZ         pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
11539adc538cSKatayama Hirofumi MZ         if (!pIC)
11549adc538cSKatayama Hirofumi MZ         {
11559adc538cSKatayama Hirofumi MZ             ImmUnlockClientImc(pClientImc);
11569adc538cSKatayama Hirofumi MZ             return FALSE;
11579adc538cSKatayama Hirofumi MZ         }
11589adc538cSKatayama Hirofumi MZ 
11599adc538cSKatayama Hirofumi MZ         pIC->hWnd = hWnd;
11609adc538cSKatayama Hirofumi MZ         pClientImc->dwFlags |= CLIENTIMC_UNKNOWN5;
11619adc538cSKatayama Hirofumi MZ 
11629adc538cSKatayama Hirofumi MZ         if (pIC->dwUIFlags & 2)
11639adc538cSKatayama Hirofumi MZ             iShow = (ISC_SHOWUIGUIDELINE | ISC_SHOWUIALLCANDIDATEWINDOW);
11649adc538cSKatayama Hirofumi MZ 
11659adc538cSKatayama Hirofumi MZ         fOpen = pIC->fOpen;
11669adc538cSKatayama Hirofumi MZ         dwConversion = pIC->fdwConversion;
11679adc538cSKatayama Hirofumi MZ 
11689adc538cSKatayama Hirofumi MZ         ImmUnlockIMC(hIMC);
11699adc538cSKatayama Hirofumi MZ     }
11709adc538cSKatayama Hirofumi MZ     else
11719adc538cSKatayama Hirofumi MZ     {
1172720da3b9SKatayama Hirofumi MZ         hIMC = ImmGetSaveContext(hWnd, 1);
11739adc538cSKatayama Hirofumi MZ         pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
11749adc538cSKatayama Hirofumi MZ         if (pIC)
11759adc538cSKatayama Hirofumi MZ         {
11769adc538cSKatayama Hirofumi MZ             pIC->hWnd = hWnd;
11779adc538cSKatayama Hirofumi MZ             ImmUnlockIMC(hIMC);
11789adc538cSKatayama Hirofumi MZ         }
11799adc538cSKatayama Hirofumi MZ         hIMC = NULL;
11809adc538cSKatayama Hirofumi MZ     }
11819adc538cSKatayama Hirofumi MZ 
11829adc538cSKatayama Hirofumi MZ     hKL = GetKeyboardLayout(0);
11839adc538cSKatayama Hirofumi MZ 
11848ba378c9SKatayama Hirofumi MZ     if (IS_CICERO_MODE() && !IS_16BIT_MODE())
11859adc538cSKatayama Hirofumi MZ     {
11869adc538cSKatayama Hirofumi MZ         Imm32CiceroSetActiveContext(hIMC, fActive, hWnd, hKL);
11879adc538cSKatayama Hirofumi MZ         hKL = GetKeyboardLayout(0);
11889adc538cSKatayama Hirofumi MZ     }
11899adc538cSKatayama Hirofumi MZ 
11909adc538cSKatayama Hirofumi MZ     pImeDpi = ImmLockImeDpi(hKL);
11919adc538cSKatayama Hirofumi MZ     if (pImeDpi)
11929adc538cSKatayama Hirofumi MZ     {
11939adc538cSKatayama Hirofumi MZ         if (IS_IME_HKL(hKL))
11949adc538cSKatayama Hirofumi MZ             pImeDpi->ImeSetActiveContext(hIMC, fActive);
11959adc538cSKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
11969adc538cSKatayama Hirofumi MZ     }
11979adc538cSKatayama Hirofumi MZ 
11989adc538cSKatayama Hirofumi MZ     if (IsWindow(hWnd))
11999adc538cSKatayama Hirofumi MZ     {
12009adc538cSKatayama Hirofumi MZ         SendMessageW(hWnd, WM_IME_SETCONTEXT, fActive, iShow);
12019adc538cSKatayama Hirofumi MZ         if (fActive)
12029adc538cSKatayama Hirofumi MZ             NtUserNotifyIMEStatus(hWnd, fOpen, dwConversion);
12039adc538cSKatayama Hirofumi MZ     }
12049adc538cSKatayama Hirofumi MZ     else if (!fActive)
12059adc538cSKatayama Hirofumi MZ     {
12069adc538cSKatayama Hirofumi MZ         hwndDefIME = ImmGetDefaultIMEWnd(NULL);
12079adc538cSKatayama Hirofumi MZ         if (hwndDefIME)
12089adc538cSKatayama Hirofumi MZ             SendMessageW(hwndDefIME, WM_IME_SETCONTEXT, 0, iShow);
12099adc538cSKatayama Hirofumi MZ     }
12109adc538cSKatayama Hirofumi MZ 
12119adc538cSKatayama Hirofumi MZ     if (pClientImc)
12129adc538cSKatayama Hirofumi MZ         ImmUnlockClientImc(pClientImc);
12139adc538cSKatayama Hirofumi MZ 
12149adc538cSKatayama Hirofumi MZ     return TRUE;
1215b4557a60SKatayama Hirofumi MZ }
1216b4557a60SKatayama Hirofumi MZ 
1217b4557a60SKatayama Hirofumi MZ /***********************************************************************
12188cdfc245SKatayama Hirofumi MZ  *              ImmWINNLSGetEnableStatus (IMM32.@)
12198cdfc245SKatayama Hirofumi MZ  */
12208cdfc245SKatayama Hirofumi MZ 
12218cdfc245SKatayama Hirofumi MZ BOOL WINAPI ImmWINNLSGetEnableStatus(HWND hWnd)
12228cdfc245SKatayama Hirofumi MZ {
12238cdfc245SKatayama Hirofumi MZ     if (!Imm32IsSystemJapaneseOrKorean())
12248cdfc245SKatayama Hirofumi MZ     {
12258cdfc245SKatayama Hirofumi MZ         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
12268cdfc245SKatayama Hirofumi MZ         return FALSE;
12278cdfc245SKatayama Hirofumi MZ     }
12288cdfc245SKatayama Hirofumi MZ 
1229720da3b9SKatayama Hirofumi MZ     return !!ImmGetSaveContext(hWnd, 2);
12308cdfc245SKatayama Hirofumi MZ }
12318cdfc245SKatayama Hirofumi MZ 
12328cdfc245SKatayama Hirofumi MZ /***********************************************************************
1233b4557a60SKatayama Hirofumi MZ  *              ImmSetActiveContextConsoleIME(IMM32.@)
1234b4557a60SKatayama Hirofumi MZ  */
1235b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmSetActiveContextConsoleIME(HWND hwnd, BOOL fFlag)
1236c2c66affSColin Finck {
1237d7f13aa6SKatayama Hirofumi MZ     HIMC hIMC;
1238b4557a60SKatayama Hirofumi MZ     TRACE("(%p, %d)\n", hwnd, fFlag);
1239d7f13aa6SKatayama Hirofumi MZ 
1240b4557a60SKatayama Hirofumi MZ     hIMC = ImmGetContext(hwnd);
1241b4557a60SKatayama Hirofumi MZ     if (hIMC)
1242b4557a60SKatayama Hirofumi MZ         return ImmSetActiveContext(hwnd, hIMC, fFlag);
1243c2c66affSColin Finck     return FALSE;
1244c2c66affSColin Finck }
1245c2c66affSColin Finck 
1246692a30a8SKatayama Hirofumi MZ BOOL WINAPI User32InitializeImmEntryTable(DWORD);
1247692a30a8SKatayama Hirofumi MZ 
12482c244eafSHermès Bélusca-Maïto BOOL
12492c244eafSHermès Bélusca-Maïto WINAPI
12502c244eafSHermès Bélusca-Maïto ImmDllInitialize(
12512c244eafSHermès Bélusca-Maïto     _In_ HANDLE hDll,
12522c244eafSHermès Bélusca-Maïto     _In_ ULONG dwReason,
12532c244eafSHermès Bélusca-Maïto     _In_opt_ PVOID pReserved)
1254692a30a8SKatayama Hirofumi MZ {
1255692a30a8SKatayama Hirofumi MZ     HKL hKL;
125677911014SKatayama Hirofumi MZ     HIMC hIMC;
1257692a30a8SKatayama Hirofumi MZ 
12582c244eafSHermès Bélusca-Maïto     TRACE("(%p, 0x%X, %p)\n", hDll, dwReason, pReserved);
1259692a30a8SKatayama Hirofumi MZ 
12602c244eafSHermès Bélusca-Maïto     switch (dwReason)
1261692a30a8SKatayama Hirofumi MZ     {
1262692a30a8SKatayama Hirofumi MZ         case DLL_PROCESS_ATTACH:
12632c244eafSHermès Bélusca-Maïto             if (!ImmInitializeGlobals(hDll))
1264692a30a8SKatayama Hirofumi MZ             {
1265a40f55bfSKatayama Hirofumi MZ                 ERR("ImmInitializeGlobals failed\n");
1266692a30a8SKatayama Hirofumi MZ                 return FALSE;
1267692a30a8SKatayama Hirofumi MZ             }
1268692a30a8SKatayama Hirofumi MZ             if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC))
1269692a30a8SKatayama Hirofumi MZ             {
1270692a30a8SKatayama Hirofumi MZ                 ERR("User32InitializeImmEntryTable failed\n");
1271692a30a8SKatayama Hirofumi MZ                 return FALSE;
1272692a30a8SKatayama Hirofumi MZ             }
1273692a30a8SKatayama Hirofumi MZ             break;
1274692a30a8SKatayama Hirofumi MZ 
1275692a30a8SKatayama Hirofumi MZ         case DLL_THREAD_ATTACH:
1276692a30a8SKatayama Hirofumi MZ             break;
1277692a30a8SKatayama Hirofumi MZ 
1278692a30a8SKatayama Hirofumi MZ         case DLL_THREAD_DETACH:
127945a4e53fSKatayama Hirofumi MZ             if (!IS_IMM_MODE() || NtCurrentTeb()->Win32ThreadInfo == NULL)
1280692a30a8SKatayama Hirofumi MZ                 return TRUE;
1281692a30a8SKatayama Hirofumi MZ 
1282692a30a8SKatayama Hirofumi MZ             hKL = GetKeyboardLayout(0);
128341b87158SKatayama Hirofumi MZ             hIMC = (HIMC)NtUserGetThreadState(THREADSTATE_DEFAULTINPUTCONTEXT);
1284f8902dc3SKatayama Hirofumi MZ             Imm32DestroyInputContext(hIMC, hKL, TRUE);
1285692a30a8SKatayama Hirofumi MZ             break;
1286692a30a8SKatayama Hirofumi MZ 
1287692a30a8SKatayama Hirofumi MZ         case DLL_PROCESS_DETACH:
1288895909e6SKatayama Hirofumi MZ             RtlDeleteCriticalSection(&gcsImeDpi);
12892ab858c1SKatayama Hirofumi MZ             TRACE("imm32.dll is unloaded\n");
1290692a30a8SKatayama Hirofumi MZ             break;
1291692a30a8SKatayama Hirofumi MZ     }
1292692a30a8SKatayama Hirofumi MZ 
1293692a30a8SKatayama Hirofumi MZ     return TRUE;
1294692a30a8SKatayama Hirofumi MZ }
1295