xref: /reactos/dll/win32/imm32/imm.c (revision 97f4c3c3)
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>
9f4bc74edSKatayama Hirofumi MZ  *              Copyright 2020-2021 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 
16692a30a8SKatayama Hirofumi MZ HMODULE g_hImm32Inst = NULL;
1782fa82d8SKatayama Hirofumi MZ PSERVERINFO gpsi = NULL;
186dfe0321SKatayama Hirofumi MZ SHAREDINFO gSharedInfo = { NULL };
19692a30a8SKatayama Hirofumi MZ BYTE g_bClientRegd = FALSE;
20a8d2cd4bSKatayama Hirofumi MZ 
21692a30a8SKatayama Hirofumi MZ static BOOL APIENTRY Imm32InitInstance(HMODULE hMod)
22692a30a8SKatayama Hirofumi MZ {
23692a30a8SKatayama Hirofumi MZ     NTSTATUS status;
24692a30a8SKatayama Hirofumi MZ 
25692a30a8SKatayama Hirofumi MZ     if (hMod)
26692a30a8SKatayama Hirofumi MZ         g_hImm32Inst = hMod;
27692a30a8SKatayama Hirofumi MZ 
28692a30a8SKatayama Hirofumi MZ     if (g_bClientRegd)
29692a30a8SKatayama Hirofumi MZ         return TRUE;
30692a30a8SKatayama Hirofumi MZ 
31692a30a8SKatayama Hirofumi MZ     status = RtlInitializeCriticalSection(&g_csImeDpi);
32692a30a8SKatayama Hirofumi MZ     if (NT_ERROR(status))
33692a30a8SKatayama Hirofumi MZ         return FALSE;
34692a30a8SKatayama Hirofumi MZ 
35692a30a8SKatayama Hirofumi MZ     g_bClientRegd = TRUE;
36692a30a8SKatayama Hirofumi MZ     return TRUE;
37692a30a8SKatayama Hirofumi MZ }
38692a30a8SKatayama Hirofumi MZ 
391da5d7a3SKatayama Hirofumi MZ /***********************************************************************
40b4557a60SKatayama Hirofumi MZ  *		ImmRegisterClient(IMM32.@)
41b4557a60SKatayama Hirofumi MZ  *       ( Undocumented, called from user32.dll )
421da5d7a3SKatayama Hirofumi MZ  */
43b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmRegisterClient(PSHAREDINFO ptr, HINSTANCE hMod)
44692a30a8SKatayama Hirofumi MZ {
456dfe0321SKatayama Hirofumi MZ     gSharedInfo = *ptr;
466dfe0321SKatayama Hirofumi MZ     gpsi = gSharedInfo.psi;
47b4557a60SKatayama Hirofumi MZ     return Imm32InitInstance(hMod);
481e62771cSKatayama Hirofumi MZ }
491e62771cSKatayama Hirofumi MZ 
501da5d7a3SKatayama Hirofumi MZ /***********************************************************************
511da5d7a3SKatayama Hirofumi MZ  *		ImmLoadLayout (IMM32.@)
521da5d7a3SKatayama Hirofumi MZ  */
53a37d9a4eSKatayama Hirofumi MZ BOOL WINAPI ImmLoadLayout(HKL hKL, PIMEINFOEX pImeInfoEx)
548e1dea0cSKatayama Hirofumi MZ {
558e1dea0cSKatayama Hirofumi MZ     DWORD cbData;
568e1dea0cSKatayama Hirofumi MZ     HKEY hLayoutKey = NULL, hLayoutsKey = NULL;
578e1dea0cSKatayama Hirofumi MZ     LONG error;
588e1dea0cSKatayama Hirofumi MZ     WCHAR szLayout[MAX_PATH];
598e1dea0cSKatayama Hirofumi MZ 
601d9542d2SKatayama Hirofumi MZ     TRACE("(%p, %p)\n", hKL, pImeInfoEx);
618e1dea0cSKatayama Hirofumi MZ 
62ca3fa719SKatayama Hirofumi MZ     if (IS_IME_HKL(hKL) || !Imm32IsCiceroMode() || Imm32Is16BitMode())
638e1dea0cSKatayama Hirofumi MZ     {
64a37d9a4eSKatayama Hirofumi MZ         Imm32UIntToStr((DWORD)(DWORD_PTR)hKL, 16, szLayout, _countof(szLayout));
658e1dea0cSKatayama Hirofumi MZ 
668e1dea0cSKatayama Hirofumi MZ         error = RegOpenKeyW(HKEY_LOCAL_MACHINE, REGKEY_KEYBOARD_LAYOUTS, &hLayoutsKey);
678e1dea0cSKatayama Hirofumi MZ         if (error)
68a37d9a4eSKatayama Hirofumi MZ         {
69a37d9a4eSKatayama Hirofumi MZ             ERR("RegOpenKeyW: 0x%08lX\n", error);
70a37d9a4eSKatayama Hirofumi MZ             return FALSE;
71a37d9a4eSKatayama Hirofumi MZ         }
728e1dea0cSKatayama Hirofumi MZ 
738e1dea0cSKatayama Hirofumi MZ         error = RegOpenKeyW(hLayoutsKey, szLayout, &hLayoutKey);
74a37d9a4eSKatayama Hirofumi MZ         if (error)
75a37d9a4eSKatayama Hirofumi MZ         {
76a37d9a4eSKatayama Hirofumi MZ             ERR("RegOpenKeyW: 0x%08lX\n", error);
77a37d9a4eSKatayama Hirofumi MZ             RegCloseKey(hLayoutsKey);
78a37d9a4eSKatayama Hirofumi MZ             return FALSE;
79a37d9a4eSKatayama Hirofumi MZ         }
808e1dea0cSKatayama Hirofumi MZ     }
818e1dea0cSKatayama Hirofumi MZ     else
828e1dea0cSKatayama Hirofumi MZ     {
838e1dea0cSKatayama Hirofumi MZ         error = RegOpenKeyW(HKEY_LOCAL_MACHINE, REGKEY_IMM, &hLayoutKey);
848e1dea0cSKatayama Hirofumi MZ         if (error)
858e1dea0cSKatayama Hirofumi MZ         {
86a37d9a4eSKatayama Hirofumi MZ             ERR("RegOpenKeyW: 0x%08lX\n", error);
87a37d9a4eSKatayama Hirofumi MZ             return FALSE;
888e1dea0cSKatayama Hirofumi MZ         }
89a37d9a4eSKatayama Hirofumi MZ     }
90a37d9a4eSKatayama Hirofumi MZ 
918e1dea0cSKatayama Hirofumi MZ     cbData = sizeof(pImeInfoEx->wszImeFile);
928e1dea0cSKatayama Hirofumi MZ     error = RegQueryValueExW(hLayoutKey, L"Ime File", 0, 0,
938e1dea0cSKatayama Hirofumi MZ                              (LPBYTE)pImeInfoEx->wszImeFile, &cbData);
94a37d9a4eSKatayama Hirofumi MZ     pImeInfoEx->wszImeFile[_countof(pImeInfoEx->wszImeFile) - 1] = 0;
958e1dea0cSKatayama Hirofumi MZ 
968e1dea0cSKatayama Hirofumi MZ     RegCloseKey(hLayoutKey);
978e1dea0cSKatayama Hirofumi MZ     if (hLayoutsKey)
988e1dea0cSKatayama Hirofumi MZ         RegCloseKey(hLayoutsKey);
99a37d9a4eSKatayama Hirofumi MZ 
100a37d9a4eSKatayama Hirofumi MZ     pImeInfoEx->fLoadFlag = 0;
101a37d9a4eSKatayama Hirofumi MZ 
102a37d9a4eSKatayama Hirofumi MZ     if (error)
103a37d9a4eSKatayama Hirofumi MZ     {
104a37d9a4eSKatayama Hirofumi MZ         ERR("RegQueryValueExW: 0x%08lX\n", error);
105a37d9a4eSKatayama Hirofumi MZ         pImeInfoEx->hkl = NULL;
106a37d9a4eSKatayama Hirofumi MZ         return FALSE;
107a37d9a4eSKatayama Hirofumi MZ     }
108a37d9a4eSKatayama Hirofumi MZ 
109a37d9a4eSKatayama Hirofumi MZ     pImeInfoEx->hkl = hKL;
110a37d9a4eSKatayama Hirofumi MZ     return Imm32LoadImeVerInfo(pImeInfoEx);
1118e1dea0cSKatayama Hirofumi MZ }
1128e1dea0cSKatayama Hirofumi MZ 
113e6a51b54SKatayama Hirofumi MZ /***********************************************************************
114e6a51b54SKatayama Hirofumi MZ  *		ImmFreeLayout (IMM32.@)
115e6a51b54SKatayama Hirofumi MZ  */
116e6a51b54SKatayama Hirofumi MZ BOOL WINAPI ImmFreeLayout(DWORD dwUnknown)
117e6a51b54SKatayama Hirofumi MZ {
118e6a51b54SKatayama Hirofumi MZ     WCHAR szKBD[9];
119e6a51b54SKatayama Hirofumi MZ     UINT iKL, cKLs;
120e6a51b54SKatayama Hirofumi MZ     HKL hOldKL, hNewKL, *pList;
121e6a51b54SKatayama Hirofumi MZ     PIMEDPI pImeDpi;
122e6a51b54SKatayama Hirofumi MZ     LANGID LangID;
123e6a51b54SKatayama Hirofumi MZ 
124e6a51b54SKatayama Hirofumi MZ     TRACE("(0x%lX)\n", dwUnknown);
125e6a51b54SKatayama Hirofumi MZ 
126e6a51b54SKatayama Hirofumi MZ     hOldKL = GetKeyboardLayout(0);
127e6a51b54SKatayama Hirofumi MZ 
128e6a51b54SKatayama Hirofumi MZ     if (dwUnknown == 1)
129e6a51b54SKatayama Hirofumi MZ     {
130e6a51b54SKatayama Hirofumi MZ         if (!IS_IME_HKL(hOldKL))
131e6a51b54SKatayama Hirofumi MZ             return TRUE;
132e6a51b54SKatayama Hirofumi MZ 
133e6a51b54SKatayama Hirofumi MZ         LangID = LANGIDFROMLCID(GetSystemDefaultLCID());
134e6a51b54SKatayama Hirofumi MZ 
135e6a51b54SKatayama Hirofumi MZ         cKLs = GetKeyboardLayoutList(0, NULL);
136e6a51b54SKatayama Hirofumi MZ         if (cKLs)
137e6a51b54SKatayama Hirofumi MZ         {
13846518ad6SKatayama Hirofumi MZ             pList = ImmLocalAlloc(0, cKLs * sizeof(HKL));
139e6a51b54SKatayama Hirofumi MZ             if (pList == NULL)
140e6a51b54SKatayama Hirofumi MZ                 return FALSE;
141e6a51b54SKatayama Hirofumi MZ 
142e6a51b54SKatayama Hirofumi MZ             cKLs = GetKeyboardLayoutList(cKLs, pList);
143e6a51b54SKatayama Hirofumi MZ             for (iKL = 0; iKL < cKLs; ++iKL)
144e6a51b54SKatayama Hirofumi MZ             {
145e6a51b54SKatayama Hirofumi MZ                 if (!IS_IME_HKL(pList[iKL]))
146e6a51b54SKatayama Hirofumi MZ                 {
147e6a51b54SKatayama Hirofumi MZ                     LangID = LOWORD(pList[iKL]);
148e6a51b54SKatayama Hirofumi MZ                     break;
149e6a51b54SKatayama Hirofumi MZ                 }
150e6a51b54SKatayama Hirofumi MZ             }
151e6a51b54SKatayama Hirofumi MZ 
15246518ad6SKatayama Hirofumi MZ             ImmLocalFree(pList);
153e6a51b54SKatayama Hirofumi MZ         }
154e6a51b54SKatayama Hirofumi MZ 
155e6a51b54SKatayama Hirofumi MZ         StringCchPrintfW(szKBD, _countof(szKBD), L"%08X", LangID);
156e6a51b54SKatayama Hirofumi MZ         if (!LoadKeyboardLayoutW(szKBD, KLF_ACTIVATE))
157e6a51b54SKatayama Hirofumi MZ             LoadKeyboardLayoutW(L"00000409", KLF_ACTIVATE | 0x200);
158e6a51b54SKatayama Hirofumi MZ     }
159e6a51b54SKatayama Hirofumi MZ     else if (dwUnknown == 2)
160e6a51b54SKatayama Hirofumi MZ     {
161e6a51b54SKatayama Hirofumi MZ         RtlEnterCriticalSection(&g_csImeDpi);
162e6a51b54SKatayama Hirofumi MZ Retry:
163e6a51b54SKatayama Hirofumi MZ         for (pImeDpi = g_pImeDpiList; pImeDpi; pImeDpi = pImeDpi->pNext)
164e6a51b54SKatayama Hirofumi MZ         {
165e6a51b54SKatayama Hirofumi MZ             if (Imm32ReleaseIME(pImeDpi->hKL))
166e6a51b54SKatayama Hirofumi MZ                 goto Retry;
167e6a51b54SKatayama Hirofumi MZ         }
168e6a51b54SKatayama Hirofumi MZ         RtlLeaveCriticalSection(&g_csImeDpi);
169e6a51b54SKatayama Hirofumi MZ     }
170e6a51b54SKatayama Hirofumi MZ     else
171e6a51b54SKatayama Hirofumi MZ     {
172e6a51b54SKatayama Hirofumi MZ         hNewKL = (HKL)(DWORD_PTR)dwUnknown;
173e6a51b54SKatayama Hirofumi MZ         if (IS_IME_HKL(hNewKL) && hNewKL != hOldKL)
174e6a51b54SKatayama Hirofumi MZ             Imm32ReleaseIME(hNewKL);
175e6a51b54SKatayama Hirofumi MZ     }
176e6a51b54SKatayama Hirofumi MZ 
177e6a51b54SKatayama Hirofumi MZ     return TRUE;
178e6a51b54SKatayama Hirofumi MZ }
179e6a51b54SKatayama Hirofumi MZ 
18066ef3149SKatayama Hirofumi MZ VOID APIENTRY Imm32SelectLayout(HKL hNewKL, HKL hOldKL, HIMC hIMC)
18166ef3149SKatayama Hirofumi MZ {
18266ef3149SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
18366ef3149SKatayama Hirofumi MZ     LPINPUTCONTEXTDX pIC;
18466ef3149SKatayama Hirofumi MZ     LPGUIDELINE pGL;
18566ef3149SKatayama Hirofumi MZ     LPCANDIDATEINFO pCI;
18666ef3149SKatayama Hirofumi MZ     LPCOMPOSITIONSTRING pCS;
18766ef3149SKatayama Hirofumi MZ     LOGFONTA LogFontA;
18866ef3149SKatayama Hirofumi MZ     LOGFONTW LogFontW;
18966ef3149SKatayama Hirofumi MZ     BOOL fOpen, bIsNewHKLIme = TRUE, bIsOldHKLIme = TRUE, bClientWide, bNewDpiWide;
19066ef3149SKatayama Hirofumi MZ     DWORD cbNewPrivate = 0, cbOldPrivate = 0, dwConversion, dwSentence, dwSize, dwNewSize;
19166ef3149SKatayama Hirofumi MZ     PIMEDPI pNewImeDpi = NULL, pOldImeDpi = NULL;
19266ef3149SKatayama Hirofumi MZ     HANDLE hPrivate;
19366ef3149SKatayama Hirofumi MZ     PIME_STATE pNewState = NULL, pOldState = NULL;
19466ef3149SKatayama Hirofumi MZ 
19566ef3149SKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
19666ef3149SKatayama Hirofumi MZ     if (!pClientImc)
19766ef3149SKatayama Hirofumi MZ         return;
19866ef3149SKatayama Hirofumi MZ 
19966ef3149SKatayama Hirofumi MZ     pNewImeDpi = ImmLockImeDpi(hNewKL);
20066ef3149SKatayama Hirofumi MZ 
20166ef3149SKatayama Hirofumi MZ     if (hNewKL != hOldKL)
20266ef3149SKatayama Hirofumi MZ         pOldImeDpi = ImmLockImeDpi(hOldKL);
20366ef3149SKatayama Hirofumi MZ 
20466ef3149SKatayama Hirofumi MZ     if (pNewImeDpi)
20566ef3149SKatayama Hirofumi MZ     {
20666ef3149SKatayama Hirofumi MZ         cbNewPrivate = pNewImeDpi->ImeInfo.dwPrivateDataSize;
20766ef3149SKatayama Hirofumi MZ         pClientImc->uCodePage = pNewImeDpi->uCodePage;
20866ef3149SKatayama Hirofumi MZ     }
20966ef3149SKatayama Hirofumi MZ     else
21066ef3149SKatayama Hirofumi MZ     {
21166ef3149SKatayama Hirofumi MZ         pClientImc->uCodePage = CP_ACP;
21266ef3149SKatayama Hirofumi MZ     }
21366ef3149SKatayama Hirofumi MZ 
214b0d66e68SKatayama Hirofumi MZ     if (cbNewPrivate < sizeof(DWORD))
215b0d66e68SKatayama Hirofumi MZ         cbNewPrivate = sizeof(DWORD);
21666ef3149SKatayama Hirofumi MZ 
21766ef3149SKatayama Hirofumi MZ     if (pOldImeDpi)
21866ef3149SKatayama Hirofumi MZ         cbOldPrivate = pOldImeDpi->ImeInfo.dwPrivateDataSize;
21966ef3149SKatayama Hirofumi MZ 
220b0d66e68SKatayama Hirofumi MZ     if (cbOldPrivate < sizeof(DWORD))
221b0d66e68SKatayama Hirofumi MZ         cbOldPrivate = sizeof(DWORD);
22266ef3149SKatayama Hirofumi MZ 
22366ef3149SKatayama Hirofumi MZ     if (pClientImc->hKL == hOldKL)
22466ef3149SKatayama Hirofumi MZ     {
22566ef3149SKatayama Hirofumi MZ         if (pOldImeDpi)
22666ef3149SKatayama Hirofumi MZ         {
22766ef3149SKatayama Hirofumi MZ             if (IS_IME_HKL(hOldKL))
22866ef3149SKatayama Hirofumi MZ                 pOldImeDpi->ImeSelect(hIMC, FALSE);
22966ef3149SKatayama Hirofumi MZ             else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pOldImeDpi->CtfImeSelectEx)
23066ef3149SKatayama Hirofumi MZ                 pOldImeDpi->CtfImeSelectEx(hIMC, FALSE, hOldKL);
23166ef3149SKatayama Hirofumi MZ         }
23266ef3149SKatayama Hirofumi MZ         pClientImc->hKL = NULL;
23366ef3149SKatayama Hirofumi MZ     }
23466ef3149SKatayama Hirofumi MZ 
23566ef3149SKatayama Hirofumi MZ     if (CtfImmIsTextFrameServiceDisabled())
23666ef3149SKatayama Hirofumi MZ     {
237356babcaSKatayama Hirofumi MZ         if (IS_IMM_MODE() && !Imm32IsCiceroMode())
23866ef3149SKatayama Hirofumi MZ         {
23966ef3149SKatayama Hirofumi MZ             bIsNewHKLIme = IS_IME_HKL(hNewKL);
24066ef3149SKatayama Hirofumi MZ             bIsOldHKLIme = IS_IME_HKL(hOldKL);
24166ef3149SKatayama Hirofumi MZ         }
24266ef3149SKatayama Hirofumi MZ     }
24366ef3149SKatayama Hirofumi MZ 
24466ef3149SKatayama Hirofumi MZ     pIC = (LPINPUTCONTEXTDX)Imm32LockIMCEx(hIMC, FALSE);
24566ef3149SKatayama Hirofumi MZ     if (!pIC)
24666ef3149SKatayama Hirofumi MZ     {
24766ef3149SKatayama Hirofumi MZ         if (pNewImeDpi)
24866ef3149SKatayama Hirofumi MZ         {
24966ef3149SKatayama Hirofumi MZ             if (IS_IME_HKL(hNewKL))
25066ef3149SKatayama Hirofumi MZ                 pNewImeDpi->ImeSelect(hIMC, TRUE);
25166ef3149SKatayama Hirofumi MZ             else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pNewImeDpi->CtfImeSelectEx)
25266ef3149SKatayama Hirofumi MZ                 pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
25366ef3149SKatayama Hirofumi MZ 
25466ef3149SKatayama Hirofumi MZ             pClientImc->hKL = hNewKL;
25566ef3149SKatayama Hirofumi MZ         }
25666ef3149SKatayama Hirofumi MZ     }
25766ef3149SKatayama Hirofumi MZ     else
25866ef3149SKatayama Hirofumi MZ     {
25966ef3149SKatayama Hirofumi MZ         dwConversion = pIC->fdwConversion;
26066ef3149SKatayama Hirofumi MZ         dwSentence = pIC->fdwSentence;
26166ef3149SKatayama Hirofumi MZ         fOpen = pIC->fOpen;
26266ef3149SKatayama Hirofumi MZ 
26366ef3149SKatayama Hirofumi MZ         if (pNewImeDpi)
26466ef3149SKatayama Hirofumi MZ         {
26566ef3149SKatayama Hirofumi MZ             bClientWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
26666ef3149SKatayama Hirofumi MZ             bNewDpiWide = ImeDpi_IsUnicode(pNewImeDpi);
26766ef3149SKatayama Hirofumi MZ             if (bClientWide && !bNewDpiWide)
26866ef3149SKatayama Hirofumi MZ             {
26966ef3149SKatayama Hirofumi MZ                 if (pIC->fdwInit & INIT_LOGFONT)
27066ef3149SKatayama Hirofumi MZ                 {
27166ef3149SKatayama Hirofumi MZ                     LogFontWideToAnsi(&pIC->lfFont.W, &LogFontA);
27266ef3149SKatayama Hirofumi MZ                     pIC->lfFont.A = LogFontA;
27366ef3149SKatayama Hirofumi MZ                 }
27466ef3149SKatayama Hirofumi MZ                 pClientImc->dwFlags &= ~CLIENTIMC_WIDE;
27566ef3149SKatayama Hirofumi MZ             }
27666ef3149SKatayama Hirofumi MZ             else if (!bClientWide && bNewDpiWide)
27766ef3149SKatayama Hirofumi MZ             {
27866ef3149SKatayama Hirofumi MZ                 if (pIC->fdwInit & INIT_LOGFONT)
27966ef3149SKatayama Hirofumi MZ                 {
28066ef3149SKatayama Hirofumi MZ                     LogFontAnsiToWide(&pIC->lfFont.A, &LogFontW);
28166ef3149SKatayama Hirofumi MZ                     pIC->lfFont.W = LogFontW;
28266ef3149SKatayama Hirofumi MZ                 }
28366ef3149SKatayama Hirofumi MZ                 pClientImc->dwFlags |= CLIENTIMC_WIDE;
28466ef3149SKatayama Hirofumi MZ             }
28566ef3149SKatayama Hirofumi MZ         }
28666ef3149SKatayama Hirofumi MZ 
28766ef3149SKatayama Hirofumi MZ         if (cbOldPrivate != cbNewPrivate)
28866ef3149SKatayama Hirofumi MZ         {
28966ef3149SKatayama Hirofumi MZ             hPrivate = ImmReSizeIMCC(pIC->hPrivate, cbNewPrivate);
29066ef3149SKatayama Hirofumi MZ             if (!hPrivate)
29166ef3149SKatayama Hirofumi MZ             {
29266ef3149SKatayama Hirofumi MZ                 ImmDestroyIMCC(pIC->hPrivate);
29366ef3149SKatayama Hirofumi MZ                 hPrivate = ImmCreateIMCC(cbNewPrivate);
29466ef3149SKatayama Hirofumi MZ             }
29566ef3149SKatayama Hirofumi MZ             pIC->hPrivate = hPrivate;
29666ef3149SKatayama Hirofumi MZ         }
29766ef3149SKatayama Hirofumi MZ 
29866ef3149SKatayama Hirofumi MZ #define MAX_IMCC_SIZE 0x1000
29966ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hMsgBuf);
30066ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hMsgBuf) || dwSize > MAX_IMCC_SIZE)
30166ef3149SKatayama Hirofumi MZ         {
30266ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hMsgBuf);
30366ef3149SKatayama Hirofumi MZ             pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
30466ef3149SKatayama Hirofumi MZ             pIC->dwNumMsgBuf = 0;
30566ef3149SKatayama Hirofumi MZ         }
30666ef3149SKatayama Hirofumi MZ 
30766ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hGuideLine);
30866ef3149SKatayama Hirofumi MZ         dwNewSize = sizeof(GUIDELINE);
30966ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hGuideLine) ||
31066ef3149SKatayama Hirofumi MZ             dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
31166ef3149SKatayama Hirofumi MZ         {
31266ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hGuideLine);
31366ef3149SKatayama Hirofumi MZ             pIC->hGuideLine = ImmCreateIMCC(dwNewSize);
31466ef3149SKatayama Hirofumi MZ             pGL = ImmLockIMCC(pIC->hGuideLine);
31566ef3149SKatayama Hirofumi MZ             if (pGL)
31666ef3149SKatayama Hirofumi MZ             {
31766ef3149SKatayama Hirofumi MZ                 pGL->dwSize = dwNewSize;
31866ef3149SKatayama Hirofumi MZ                 ImmUnlockIMCC(pIC->hGuideLine);
31966ef3149SKatayama Hirofumi MZ             }
32066ef3149SKatayama Hirofumi MZ         }
32166ef3149SKatayama Hirofumi MZ 
32266ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hCandInfo);
32366ef3149SKatayama Hirofumi MZ         dwNewSize = sizeof(CANDIDATEINFO);
32466ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hCandInfo) ||
32566ef3149SKatayama Hirofumi MZ             dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
32666ef3149SKatayama Hirofumi MZ         {
32766ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hCandInfo);
32866ef3149SKatayama Hirofumi MZ             pIC->hCandInfo = ImmCreateIMCC(dwNewSize);
32966ef3149SKatayama Hirofumi MZ             pCI = ImmLockIMCC(pIC->hCandInfo);
33066ef3149SKatayama Hirofumi MZ             if (pCI)
33166ef3149SKatayama Hirofumi MZ             {
33266ef3149SKatayama Hirofumi MZ                 pCI->dwSize = dwNewSize;
33366ef3149SKatayama Hirofumi MZ                 ImmUnlockIMCC(pIC->hCandInfo);
33466ef3149SKatayama Hirofumi MZ             }
33566ef3149SKatayama Hirofumi MZ         }
33666ef3149SKatayama Hirofumi MZ 
33766ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hCompStr);
33866ef3149SKatayama Hirofumi MZ         dwNewSize = sizeof(COMPOSITIONSTRING);
33966ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hCompStr) ||
34066ef3149SKatayama Hirofumi MZ             dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
34166ef3149SKatayama Hirofumi MZ         {
34266ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hCompStr);
34366ef3149SKatayama Hirofumi MZ             pIC->hCompStr = ImmCreateIMCC(dwNewSize);
34466ef3149SKatayama Hirofumi MZ             pCS = ImmLockIMCC(pIC->hCompStr);
34566ef3149SKatayama Hirofumi MZ             if (pCS)
34666ef3149SKatayama Hirofumi MZ             {
34766ef3149SKatayama Hirofumi MZ                 pCS->dwSize = dwNewSize;
34866ef3149SKatayama Hirofumi MZ                 ImmUnlockIMCC(pIC->hCompStr);
34966ef3149SKatayama Hirofumi MZ             }
35066ef3149SKatayama Hirofumi MZ         }
35166ef3149SKatayama Hirofumi MZ #undef MAX_IMCC_SIZE
35266ef3149SKatayama Hirofumi MZ 
35366ef3149SKatayama Hirofumi MZ         if (pOldImeDpi && bIsOldHKLIme)
35466ef3149SKatayama Hirofumi MZ         {
35566ef3149SKatayama Hirofumi MZ             pOldState = Imm32FetchImeState(pIC, hOldKL);
35666ef3149SKatayama Hirofumi MZ             if (pOldState)
35766ef3149SKatayama Hirofumi MZ                 Imm32SaveImeStateSentence(pIC, pOldState, hOldKL);
35866ef3149SKatayama Hirofumi MZ         }
35966ef3149SKatayama Hirofumi MZ 
36066ef3149SKatayama Hirofumi MZ         if (pNewImeDpi && bIsNewHKLIme)
36166ef3149SKatayama Hirofumi MZ             pNewState = Imm32FetchImeState(pIC, hNewKL);
36266ef3149SKatayama Hirofumi MZ 
36366ef3149SKatayama Hirofumi MZ         if (pOldState != pNewState)
36466ef3149SKatayama Hirofumi MZ         {
36566ef3149SKatayama Hirofumi MZ             if (pOldState)
36666ef3149SKatayama Hirofumi MZ             {
36766ef3149SKatayama Hirofumi MZ                 pOldState->fOpen = !!pIC->fOpen;
36866ef3149SKatayama Hirofumi MZ                 pOldState->dwConversion = (pIC->fdwConversion & ~IME_CMODE_EUDC);
36966ef3149SKatayama Hirofumi MZ                 pOldState->dwSentence = pIC->fdwSentence;
37066ef3149SKatayama Hirofumi MZ                 pOldState->dwInit = pIC->fdwInit;
37166ef3149SKatayama Hirofumi MZ             }
37266ef3149SKatayama Hirofumi MZ 
37366ef3149SKatayama Hirofumi MZ             if (pNewState)
37466ef3149SKatayama Hirofumi MZ             {
37566ef3149SKatayama Hirofumi MZ                 if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_FORCE_OPEN)
37666ef3149SKatayama Hirofumi MZ                 {
37766ef3149SKatayama Hirofumi MZ                     pIC->dwChange &= ~INPUTCONTEXTDX_CHANGE_FORCE_OPEN;
37866ef3149SKatayama Hirofumi MZ                     pIC->fOpen = TRUE;
37966ef3149SKatayama Hirofumi MZ                 }
38066ef3149SKatayama Hirofumi MZ                 else
38166ef3149SKatayama Hirofumi MZ                 {
38266ef3149SKatayama Hirofumi MZ                     pIC->fOpen = pNewState->fOpen;
38366ef3149SKatayama Hirofumi MZ                 }
38466ef3149SKatayama Hirofumi MZ 
38566ef3149SKatayama Hirofumi MZ                 pIC->fdwConversion = (pNewState->dwConversion & ~IME_CMODE_EUDC);
38666ef3149SKatayama Hirofumi MZ                 pIC->fdwSentence = pNewState->dwSentence;
38766ef3149SKatayama Hirofumi MZ                 pIC->fdwInit = pNewState->dwInit;
38866ef3149SKatayama Hirofumi MZ             }
38966ef3149SKatayama Hirofumi MZ         }
39066ef3149SKatayama Hirofumi MZ 
39166ef3149SKatayama Hirofumi MZ         if (pNewState)
39266ef3149SKatayama Hirofumi MZ             Imm32LoadImeStateSentence(pIC, pNewState, hNewKL);
39366ef3149SKatayama Hirofumi MZ 
39466ef3149SKatayama Hirofumi MZ         if (pNewImeDpi)
39566ef3149SKatayama Hirofumi MZ         {
39666ef3149SKatayama Hirofumi MZ             if (IS_IME_HKL(hNewKL))
39766ef3149SKatayama Hirofumi MZ                 pNewImeDpi->ImeSelect(hIMC, TRUE);
39866ef3149SKatayama Hirofumi MZ             else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pNewImeDpi->CtfImeSelectEx)
39966ef3149SKatayama Hirofumi MZ                 pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
40066ef3149SKatayama Hirofumi MZ 
40166ef3149SKatayama Hirofumi MZ             pClientImc->hKL = hNewKL;
40266ef3149SKatayama Hirofumi MZ         }
40366ef3149SKatayama Hirofumi MZ 
40466ef3149SKatayama Hirofumi MZ         pIC->dwChange = 0;
40566ef3149SKatayama Hirofumi MZ         if (pIC->fOpen != fOpen)
40666ef3149SKatayama Hirofumi MZ             pIC->dwChange |= INPUTCONTEXTDX_CHANGE_OPEN;
40766ef3149SKatayama Hirofumi MZ         if (pIC->fdwConversion != dwConversion)
40866ef3149SKatayama Hirofumi MZ             pIC->dwChange |= INPUTCONTEXTDX_CHANGE_CONVERSION;
40966ef3149SKatayama Hirofumi MZ         if (pIC->fdwSentence != dwSentence)
41066ef3149SKatayama Hirofumi MZ             pIC->dwChange |= INPUTCONTEXTDX_CHANGE_SENTENCE;
41166ef3149SKatayama Hirofumi MZ 
41266ef3149SKatayama Hirofumi MZ         ImmUnlockIMC(hIMC);
41366ef3149SKatayama Hirofumi MZ     }
41466ef3149SKatayama Hirofumi MZ 
41566ef3149SKatayama Hirofumi MZ     ImmUnlockImeDpi(pOldImeDpi);
41666ef3149SKatayama Hirofumi MZ     ImmUnlockImeDpi(pNewImeDpi);
41766ef3149SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
41866ef3149SKatayama Hirofumi MZ }
41966ef3149SKatayama Hirofumi MZ 
42066ef3149SKatayama Hirofumi MZ typedef struct SELECT_LAYOUT
42166ef3149SKatayama Hirofumi MZ {
42266ef3149SKatayama Hirofumi MZ     HKL hNewKL;
42366ef3149SKatayama Hirofumi MZ     HKL hOldKL;
42466ef3149SKatayama Hirofumi MZ } SELECT_LAYOUT, *LPSELECT_LAYOUT;
42566ef3149SKatayama Hirofumi MZ 
42666ef3149SKatayama Hirofumi MZ static BOOL CALLBACK Imm32SelectLayoutProc(HIMC hIMC, LPARAM lParam)
42766ef3149SKatayama Hirofumi MZ {
42866ef3149SKatayama Hirofumi MZ     LPSELECT_LAYOUT pSelect = (LPSELECT_LAYOUT)lParam;
42966ef3149SKatayama Hirofumi MZ     Imm32SelectLayout(pSelect->hNewKL, pSelect->hOldKL, hIMC);
43066ef3149SKatayama Hirofumi MZ     return TRUE;
43166ef3149SKatayama Hirofumi MZ }
43266ef3149SKatayama Hirofumi MZ 
43366ef3149SKatayama Hirofumi MZ static BOOL CALLBACK Imm32NotifyCompStrProc(HIMC hIMC, LPARAM lParam)
43466ef3149SKatayama Hirofumi MZ {
43566ef3149SKatayama Hirofumi MZ     ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, (DWORD)lParam, 0);
43666ef3149SKatayama Hirofumi MZ     return TRUE;
43766ef3149SKatayama Hirofumi MZ }
43866ef3149SKatayama Hirofumi MZ 
43966ef3149SKatayama Hirofumi MZ /***********************************************************************
44066ef3149SKatayama Hirofumi MZ  *		ImmActivateLayout (IMM32.@)
44166ef3149SKatayama Hirofumi MZ  */
44266ef3149SKatayama Hirofumi MZ BOOL WINAPI ImmActivateLayout(HKL hKL)
44366ef3149SKatayama Hirofumi MZ {
44466ef3149SKatayama Hirofumi MZ     PIMEDPI pImeDpi;
44566ef3149SKatayama Hirofumi MZ     HKL hOldKL;
44666ef3149SKatayama Hirofumi MZ     LPARAM lParam;
44766ef3149SKatayama Hirofumi MZ     HWND hwndDefIME = NULL;
44866ef3149SKatayama Hirofumi MZ     SELECT_LAYOUT SelectLayout;
44966ef3149SKatayama Hirofumi MZ 
45066ef3149SKatayama Hirofumi MZ     hOldKL = GetKeyboardLayout(0);
45166ef3149SKatayama Hirofumi MZ 
45266ef3149SKatayama Hirofumi MZ     if (hOldKL == hKL && !(GetWin32ClientInfo()->CI_flags & CI_IMMACTIVATE))
45366ef3149SKatayama Hirofumi MZ         return TRUE;
45466ef3149SKatayama Hirofumi MZ 
45566ef3149SKatayama Hirofumi MZ     ImmLoadIME(hKL);
45666ef3149SKatayama Hirofumi MZ 
45766ef3149SKatayama Hirofumi MZ     if (hOldKL != hKL)
45866ef3149SKatayama Hirofumi MZ     {
45966ef3149SKatayama Hirofumi MZ         pImeDpi = ImmLockImeDpi(hOldKL);
46066ef3149SKatayama Hirofumi MZ         if (pImeDpi)
46166ef3149SKatayama Hirofumi MZ         {
46266ef3149SKatayama Hirofumi MZ             if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT)
46366ef3149SKatayama Hirofumi MZ                 lParam = CPS_COMPLETE;
46466ef3149SKatayama Hirofumi MZ             else
46566ef3149SKatayama Hirofumi MZ                 lParam = CPS_CANCEL;
46666ef3149SKatayama Hirofumi MZ             ImmUnlockImeDpi(pImeDpi);
46766ef3149SKatayama Hirofumi MZ 
46866ef3149SKatayama Hirofumi MZ             ImmEnumInputContext(0, Imm32NotifyCompStrProc, lParam);
46966ef3149SKatayama Hirofumi MZ         }
47066ef3149SKatayama Hirofumi MZ 
47166ef3149SKatayama Hirofumi MZ         hwndDefIME = ImmGetDefaultIMEWnd(NULL);
47266ef3149SKatayama Hirofumi MZ         if (IsWindow(hwndDefIME))
47366ef3149SKatayama Hirofumi MZ             SendMessageW(hwndDefIME, WM_IME_SELECT, FALSE, (LPARAM)hOldKL);
47466ef3149SKatayama Hirofumi MZ 
47566ef3149SKatayama Hirofumi MZ         NtUserSetThreadLayoutHandles(hKL, hOldKL);
47666ef3149SKatayama Hirofumi MZ     }
47766ef3149SKatayama Hirofumi MZ 
47866ef3149SKatayama Hirofumi MZ     SelectLayout.hNewKL = hKL;
47966ef3149SKatayama Hirofumi MZ     SelectLayout.hOldKL = hOldKL;
48066ef3149SKatayama Hirofumi MZ     ImmEnumInputContext(0, Imm32SelectLayoutProc, (LPARAM)&SelectLayout);
48166ef3149SKatayama Hirofumi MZ 
48266ef3149SKatayama Hirofumi MZ     if (IsWindow(hwndDefIME))
48366ef3149SKatayama Hirofumi MZ         SendMessageW(hwndDefIME, WM_IME_SELECT, TRUE, (LPARAM)hKL);
48466ef3149SKatayama Hirofumi MZ 
48566ef3149SKatayama Hirofumi MZ     return TRUE;
48666ef3149SKatayama Hirofumi MZ }
48766ef3149SKatayama Hirofumi MZ 
4889adc538cSKatayama Hirofumi MZ static VOID APIENTRY Imm32CiceroSetActiveContext(HIMC hIMC, BOOL fActive, HWND hWnd, HKL hKL)
4899adc538cSKatayama Hirofumi MZ {
4909adc538cSKatayama Hirofumi MZ     FIXME("We have to do something\n");
4919adc538cSKatayama Hirofumi MZ }
4929adc538cSKatayama Hirofumi MZ 
493c2c66affSColin Finck /***********************************************************************
494c2c66affSColin Finck  *		ImmAssociateContext (IMM32.@)
495c2c66affSColin Finck  */
496c2c66affSColin Finck HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
497c2c66affSColin Finck {
498ef003fa4SKatayama Hirofumi MZ     PWND pWnd;
499ef003fa4SKatayama Hirofumi MZ     HWND hwndFocus;
500ef003fa4SKatayama Hirofumi MZ     DWORD dwValue;
501ef003fa4SKatayama Hirofumi MZ     HIMC hOldIMC;
502c2c66affSColin Finck 
503ef003fa4SKatayama Hirofumi MZ     TRACE("(%p, %p)\n", hWnd, hIMC);
504c2c66affSColin Finck 
505356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
506c2c66affSColin Finck         return NULL;
507c2c66affSColin Finck 
508ef003fa4SKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
509ef003fa4SKatayama Hirofumi MZ     if (!pWnd)
510ef003fa4SKatayama Hirofumi MZ         return NULL;
511ef003fa4SKatayama Hirofumi MZ 
512ef003fa4SKatayama Hirofumi MZ     if (hIMC && Imm32IsCrossThreadAccess(hIMC))
513ef003fa4SKatayama Hirofumi MZ         return NULL;
514ef003fa4SKatayama Hirofumi MZ 
515ef003fa4SKatayama Hirofumi MZ     hOldIMC = pWnd->hImc;
516ef003fa4SKatayama Hirofumi MZ     if (hOldIMC == hIMC)
517c2c66affSColin Finck         return hIMC;
518c2c66affSColin Finck 
519ef003fa4SKatayama Hirofumi MZ     dwValue = NtUserAssociateInputContext(hWnd, hIMC, 0);
520ef003fa4SKatayama Hirofumi MZ     if (dwValue == 0)
521ef003fa4SKatayama Hirofumi MZ         return hOldIMC;
522ef003fa4SKatayama Hirofumi MZ     if (dwValue != 1)
523c45a6e15SJames Tabor         return NULL;
524c45a6e15SJames Tabor 
525ef003fa4SKatayama Hirofumi MZ     hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS);
526ef003fa4SKatayama Hirofumi MZ     if (hwndFocus == hWnd)
527c2c66affSColin Finck     {
528ef003fa4SKatayama Hirofumi MZ         ImmSetActiveContext(hWnd, hOldIMC, FALSE);
529ef003fa4SKatayama Hirofumi MZ         ImmSetActiveContext(hWnd, hIMC, TRUE);
530c2c66affSColin Finck     }
531c2c66affSColin Finck 
532ef003fa4SKatayama Hirofumi MZ     return hOldIMC;
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);
554df6fff78SKatayama Hirofumi MZ     pFocusWnd = ValidateHwndNoErr(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:
565df6fff78SKatayama Hirofumi MZ             pFocusWnd = ValidateHwndNoErr(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 
61366ef3149SKatayama Hirofumi MZ static VOID APIENTRY Imm32FreeImeStates(LPINPUTCONTEXTDX pIC)
614c2c66affSColin Finck {
61566ef3149SKatayama Hirofumi MZ     PIME_STATE pState, pStateNext;
61666ef3149SKatayama Hirofumi MZ     PIME_SUBSTATE pSubState, pSubStateNext;
61766ef3149SKatayama Hirofumi MZ 
61866ef3149SKatayama Hirofumi MZ     pState = pIC->pState;
61966ef3149SKatayama Hirofumi MZ     pIC->pState = NULL;
62066ef3149SKatayama Hirofumi MZ     for (; pState; pState = pStateNext)
62166ef3149SKatayama Hirofumi MZ     {
62266ef3149SKatayama Hirofumi MZ         pStateNext = pState->pNext;
62366ef3149SKatayama Hirofumi MZ         for (pSubState = pState->pSubState; pSubState; pSubState = pSubStateNext)
62466ef3149SKatayama Hirofumi MZ         {
62566ef3149SKatayama Hirofumi MZ             pSubStateNext = pSubState->pNext;
62646518ad6SKatayama Hirofumi MZ             ImmLocalFree(pSubState);
62766ef3149SKatayama Hirofumi MZ         }
62846518ad6SKatayama Hirofumi MZ         ImmLocalFree(pState);
62966ef3149SKatayama Hirofumi MZ     }
630692a30a8SKatayama Hirofumi MZ }
631c2c66affSColin Finck 
632f8902dc3SKatayama Hirofumi MZ BOOL APIENTRY Imm32DestroyInputContext(HIMC hIMC, HKL hKL, BOOL bKeep)
633692a30a8SKatayama Hirofumi MZ {
634692a30a8SKatayama Hirofumi MZ     PIMEDPI pImeDpi;
63566ef3149SKatayama Hirofumi MZ     LPINPUTCONTEXTDX pIC;
636692a30a8SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
637be9a788fSKatayama Hirofumi MZ     PIMC pIMC;
638692a30a8SKatayama Hirofumi MZ 
639356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE() || hIMC == NULL)
640c2c66affSColin Finck         return FALSE;
641c2c66affSColin Finck 
642be9a788fSKatayama Hirofumi MZ     pIMC = ValidateHandleNoErr(hIMC, TYPE_INPUTCONTEXT);
64345a4e53fSKatayama Hirofumi MZ     if (!pIMC || pIMC->head.pti != Imm32CurrentPti())
64445a4e53fSKatayama Hirofumi MZ     {
64545a4e53fSKatayama Hirofumi MZ         ERR("invalid pIMC: %p\n", pIMC);
646be9a788fSKatayama Hirofumi MZ         return FALSE;
64745a4e53fSKatayama Hirofumi MZ     }
648be9a788fSKatayama Hirofumi MZ 
649be9a788fSKatayama Hirofumi MZ     pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
650692a30a8SKatayama Hirofumi MZ     if (!pClientImc)
65145a4e53fSKatayama Hirofumi MZ         goto Finish;
652c2c66affSColin Finck 
65345a4e53fSKatayama Hirofumi MZ     if ((pClientImc->dwFlags & CLIENTIMC_UNKNOWN2) && !bKeep)
654692a30a8SKatayama Hirofumi MZ     {
65545a4e53fSKatayama Hirofumi MZ         ERR("CLIENTIMC_UNKNOWN2\n");
65645a4e53fSKatayama Hirofumi MZ         return FALSE;
657692a30a8SKatayama Hirofumi MZ     }
658c2c66affSColin Finck 
6596ba810c0SKatayama Hirofumi MZ     if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
66045a4e53fSKatayama Hirofumi MZ         return TRUE;
66145a4e53fSKatayama Hirofumi MZ 
66245a4e53fSKatayama Hirofumi MZ     InterlockedIncrement(&pClientImc->cLockObj);
66345a4e53fSKatayama Hirofumi MZ 
66445a4e53fSKatayama Hirofumi MZ     if (!pClientImc->hInputContext)
66545a4e53fSKatayama Hirofumi MZ         goto Quit;
66645a4e53fSKatayama Hirofumi MZ 
66766ef3149SKatayama Hirofumi MZ     pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
66845a4e53fSKatayama Hirofumi MZ     if (!pIC)
669692a30a8SKatayama Hirofumi MZ     {
670692a30a8SKatayama Hirofumi MZ         ImmUnlockClientImc(pClientImc);
67145a4e53fSKatayama Hirofumi MZ         ERR("!pIC\n");
672692a30a8SKatayama Hirofumi MZ         return FALSE;
673692a30a8SKatayama Hirofumi MZ     }
674692a30a8SKatayama Hirofumi MZ 
675692a30a8SKatayama Hirofumi MZ     pImeDpi = ImmLockImeDpi(hKL);
67645a4e53fSKatayama Hirofumi MZ     if (pImeDpi)
677692a30a8SKatayama Hirofumi MZ     {
678692a30a8SKatayama Hirofumi MZ         pImeDpi->ImeSelect(hIMC, FALSE);
679692a30a8SKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
680692a30a8SKatayama Hirofumi MZ     }
681692a30a8SKatayama Hirofumi MZ 
682b3382d8dSKatayama Hirofumi MZ     pIC->hPrivate = ImmDestroyIMCC(pIC->hPrivate);
683b3382d8dSKatayama Hirofumi MZ     pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
684b3382d8dSKatayama Hirofumi MZ     pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
685b3382d8dSKatayama Hirofumi MZ     pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
686b3382d8dSKatayama Hirofumi MZ     pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
68766ef3149SKatayama Hirofumi MZ     Imm32FreeImeStates(pIC);
688692a30a8SKatayama Hirofumi MZ     ImmUnlockIMC(hIMC);
689692a30a8SKatayama Hirofumi MZ 
69045a4e53fSKatayama Hirofumi MZ Quit:
6916ba810c0SKatayama Hirofumi MZ     pClientImc->dwFlags |= CLIENTIMC_DESTROY;
692692a30a8SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
693692a30a8SKatayama Hirofumi MZ 
69445a4e53fSKatayama Hirofumi MZ Finish:
69545a4e53fSKatayama Hirofumi MZ     if (bKeep)
696c2c66affSColin Finck         return TRUE;
69745a4e53fSKatayama Hirofumi MZ     return NtUserDestroyInputContext(hIMC);
698c2c66affSColin Finck }
699c2c66affSColin Finck 
700b3382d8dSKatayama Hirofumi MZ BOOL APIENTRY
701b3382d8dSKatayama Hirofumi MZ Imm32InitContext(HIMC hIMC, LPINPUTCONTEXT pIC, PCLIENTIMC pClientImc, HKL hKL, BOOL fSelect)
702b3382d8dSKatayama Hirofumi MZ {
703b3382d8dSKatayama Hirofumi MZ     DWORD dwIndex, cbPrivate;
704b3382d8dSKatayama Hirofumi MZ     PIMEDPI pImeDpi = NULL;
705b3382d8dSKatayama Hirofumi MZ     LPCOMPOSITIONSTRING pCS;
706b3382d8dSKatayama Hirofumi MZ     LPCANDIDATEINFO pCI;
707b3382d8dSKatayama Hirofumi MZ     LPGUIDELINE pGL;
708b3382d8dSKatayama Hirofumi MZ     /* NOTE: Windows does recursive call ImmLockIMC here but we don't do so. */
709b3382d8dSKatayama Hirofumi MZ 
710b3382d8dSKatayama Hirofumi MZ     /* Create IC components */
711b3382d8dSKatayama Hirofumi MZ     pIC->hCompStr = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
712b3382d8dSKatayama Hirofumi MZ     pIC->hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
713b3382d8dSKatayama Hirofumi MZ     pIC->hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
714b3382d8dSKatayama Hirofumi MZ     pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
715b3382d8dSKatayama Hirofumi MZ     if (!pIC->hCompStr || !pIC->hCandInfo || !pIC->hGuideLine || !pIC->hMsgBuf)
716b3382d8dSKatayama Hirofumi MZ         goto Fail;
717b3382d8dSKatayama Hirofumi MZ 
718b3382d8dSKatayama Hirofumi MZ     /* Initialize IC components */
719b3382d8dSKatayama Hirofumi MZ     pCS = ImmLockIMCC(pIC->hCompStr);
720b3382d8dSKatayama Hirofumi MZ     if (!pCS)
721b3382d8dSKatayama Hirofumi MZ         goto Fail;
722b3382d8dSKatayama Hirofumi MZ     pCS->dwSize = sizeof(COMPOSITIONSTRING);
723b3382d8dSKatayama Hirofumi MZ     ImmUnlockIMCC(pIC->hCompStr);
724b3382d8dSKatayama Hirofumi MZ 
725b3382d8dSKatayama Hirofumi MZ     pCI = ImmLockIMCC(pIC->hCandInfo);
726b3382d8dSKatayama Hirofumi MZ     if (!pCI)
727b3382d8dSKatayama Hirofumi MZ         goto Fail;
728b3382d8dSKatayama Hirofumi MZ     pCI->dwSize = sizeof(CANDIDATEINFO);
729b3382d8dSKatayama Hirofumi MZ     ImmUnlockIMCC(pIC->hCandInfo);
730b3382d8dSKatayama Hirofumi MZ 
731b3382d8dSKatayama Hirofumi MZ     pGL = ImmLockIMCC(pIC->hGuideLine);
732b3382d8dSKatayama Hirofumi MZ     if (!pGL)
733b3382d8dSKatayama Hirofumi MZ         goto Fail;
734b3382d8dSKatayama Hirofumi MZ     pGL->dwSize = sizeof(GUIDELINE);
735b3382d8dSKatayama Hirofumi MZ     ImmUnlockIMCC(pIC->hGuideLine);
736b3382d8dSKatayama Hirofumi MZ 
737b3382d8dSKatayama Hirofumi MZ     pIC->dwNumMsgBuf = 0;
738b3382d8dSKatayama Hirofumi MZ     pIC->fOpen = FALSE;
739b3382d8dSKatayama Hirofumi MZ     pIC->fdwConversion = pIC->fdwSentence = 0;
740b3382d8dSKatayama Hirofumi MZ 
741b3382d8dSKatayama Hirofumi MZ     for (dwIndex = 0; dwIndex < MAX_CANDIDATEFORM; ++dwIndex)
742b3382d8dSKatayama Hirofumi MZ         pIC->cfCandForm[dwIndex].dwIndex = IMM_INVALID_CANDFORM;
743b3382d8dSKatayama Hirofumi MZ 
744b3382d8dSKatayama Hirofumi MZ     /* Get private data size */
745b3382d8dSKatayama Hirofumi MZ     pImeDpi = ImmLockImeDpi(hKL);
746b3382d8dSKatayama Hirofumi MZ     if (!pImeDpi)
747b3382d8dSKatayama Hirofumi MZ     {
748b3382d8dSKatayama Hirofumi MZ         cbPrivate = sizeof(DWORD);
749b3382d8dSKatayama Hirofumi MZ     }
750b3382d8dSKatayama Hirofumi MZ     else
751b3382d8dSKatayama Hirofumi MZ     {
752b3382d8dSKatayama Hirofumi MZ         /* Update CLIENTIMC */
753b3382d8dSKatayama Hirofumi MZ         pClientImc->uCodePage = pImeDpi->uCodePage;
754b3382d8dSKatayama Hirofumi MZ         if (ImeDpi_IsUnicode(pImeDpi))
755b3382d8dSKatayama Hirofumi MZ             pClientImc->dwFlags |= CLIENTIMC_WIDE;
756b3382d8dSKatayama Hirofumi MZ 
757b3382d8dSKatayama Hirofumi MZ         cbPrivate = pImeDpi->ImeInfo.dwPrivateDataSize;
758b3382d8dSKatayama Hirofumi MZ     }
759b3382d8dSKatayama Hirofumi MZ 
760b3382d8dSKatayama Hirofumi MZ     /* Create private data */
761b3382d8dSKatayama Hirofumi MZ     pIC->hPrivate = ImmCreateIMCC(cbPrivate);
762b3382d8dSKatayama Hirofumi MZ     if (!pIC->hPrivate)
763b3382d8dSKatayama Hirofumi MZ         goto Fail;
764b3382d8dSKatayama Hirofumi MZ 
765b3382d8dSKatayama Hirofumi MZ     if (pImeDpi)
766b3382d8dSKatayama Hirofumi MZ     {
767b3382d8dSKatayama Hirofumi MZ         /* Select the IME */
768b3382d8dSKatayama Hirofumi MZ         if (fSelect)
769b3382d8dSKatayama Hirofumi MZ         {
770b3382d8dSKatayama Hirofumi MZ             if (IS_IME_HKL(hKL))
771b3382d8dSKatayama Hirofumi MZ                 pImeDpi->ImeSelect(hIMC, TRUE);
772b3382d8dSKatayama Hirofumi MZ             else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pImeDpi->CtfImeSelectEx)
773b3382d8dSKatayama Hirofumi MZ                 pImeDpi->CtfImeSelectEx(hIMC, TRUE, hKL);
774b3382d8dSKatayama Hirofumi MZ         }
775b3382d8dSKatayama Hirofumi MZ 
776b3382d8dSKatayama Hirofumi MZ         /* Set HKL */
777b3382d8dSKatayama Hirofumi MZ         pClientImc->hKL = hKL;
778b3382d8dSKatayama Hirofumi MZ 
779b3382d8dSKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
780b3382d8dSKatayama Hirofumi MZ     }
781b3382d8dSKatayama Hirofumi MZ 
782b3382d8dSKatayama Hirofumi MZ     return TRUE;
783b3382d8dSKatayama Hirofumi MZ 
784b3382d8dSKatayama Hirofumi MZ Fail:
785b3382d8dSKatayama Hirofumi MZ     if (pImeDpi)
786b3382d8dSKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
787b3382d8dSKatayama Hirofumi MZ 
788b3382d8dSKatayama Hirofumi MZ     pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
789b3382d8dSKatayama Hirofumi MZ     pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
790b3382d8dSKatayama Hirofumi MZ     pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
791b3382d8dSKatayama Hirofumi MZ     pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
792b3382d8dSKatayama Hirofumi MZ     return FALSE;
793b3382d8dSKatayama Hirofumi MZ }
794b3382d8dSKatayama Hirofumi MZ 
795b3382d8dSKatayama Hirofumi MZ LPINPUTCONTEXT APIENTRY Imm32LockIMCEx(HIMC hIMC, BOOL fSelect)
796b3382d8dSKatayama Hirofumi MZ {
797b3382d8dSKatayama Hirofumi MZ     HANDLE hIC;
798b3382d8dSKatayama Hirofumi MZ     LPINPUTCONTEXT pIC = NULL;
799b3382d8dSKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
800b3382d8dSKatayama Hirofumi MZ     WORD Word;
801b3382d8dSKatayama Hirofumi MZ     DWORD dwThreadId;
802b3382d8dSKatayama Hirofumi MZ     HKL hKL, hNewKL;
803b3382d8dSKatayama Hirofumi MZ     PIMEDPI pImeDpi = NULL;
804b3382d8dSKatayama Hirofumi MZ     BOOL bInited;
805b3382d8dSKatayama Hirofumi MZ 
806b3382d8dSKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
807b3382d8dSKatayama Hirofumi MZ     if (!pClientImc)
808b3382d8dSKatayama Hirofumi MZ         return NULL;
809b3382d8dSKatayama Hirofumi MZ 
810b3382d8dSKatayama Hirofumi MZ     RtlEnterCriticalSection(&pClientImc->cs);
811b3382d8dSKatayama Hirofumi MZ 
812b3382d8dSKatayama Hirofumi MZ     if (!pClientImc->hInputContext)
813b3382d8dSKatayama Hirofumi MZ     {
814cdf3b5e8SKatayama Hirofumi MZ         dwThreadId = (DWORD)NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID);
815b3382d8dSKatayama Hirofumi MZ 
816b3382d8dSKatayama Hirofumi MZ         if (dwThreadId == GetCurrentThreadId() && Imm32IsCiceroMode() && !Imm32Is16BitMode())
817b3382d8dSKatayama Hirofumi MZ         {
818b3382d8dSKatayama Hirofumi MZ             hKL = GetKeyboardLayout(0);
819b3382d8dSKatayama Hirofumi MZ             Word = LOWORD(hKL);
820b3382d8dSKatayama Hirofumi MZ             hNewKL = (HKL)(DWORD_PTR)MAKELONG(Word, Word);
821b3382d8dSKatayama Hirofumi MZ 
822*97f4c3c3SKatayama Hirofumi MZ             pImeDpi = Imm32FindOrLoadImeDpi(hNewKL);
823b3382d8dSKatayama Hirofumi MZ             if (pImeDpi)
824b3382d8dSKatayama Hirofumi MZ             {
825b3382d8dSKatayama Hirofumi MZ                 FIXME("We have to do something here\n");
826b3382d8dSKatayama Hirofumi MZ             }
827b3382d8dSKatayama Hirofumi MZ         }
828b3382d8dSKatayama Hirofumi MZ 
829cdf3b5e8SKatayama Hirofumi MZ         if (!NtUserQueryInputContext(hIMC, QIC_DEFAULTWINDOWIME))
830b3382d8dSKatayama Hirofumi MZ         {
831b3382d8dSKatayama Hirofumi MZ             RtlLeaveCriticalSection(&pClientImc->cs);
832b3382d8dSKatayama Hirofumi MZ             goto Quit;
833b3382d8dSKatayama Hirofumi MZ         }
834b3382d8dSKatayama Hirofumi MZ 
835b3382d8dSKatayama Hirofumi MZ         hIC = LocalAlloc(LHND, sizeof(INPUTCONTEXTDX));
836b3382d8dSKatayama Hirofumi MZ         if (!hIC)
837b3382d8dSKatayama Hirofumi MZ         {
838b3382d8dSKatayama Hirofumi MZ             RtlLeaveCriticalSection(&pClientImc->cs);
839b3382d8dSKatayama Hirofumi MZ             goto Quit;
840b3382d8dSKatayama Hirofumi MZ         }
841b3382d8dSKatayama Hirofumi MZ         pClientImc->hInputContext = hIC;
842b3382d8dSKatayama Hirofumi MZ 
843b3382d8dSKatayama Hirofumi MZ         pIC = LocalLock(pClientImc->hInputContext);
844b3382d8dSKatayama Hirofumi MZ         if (!pIC)
845b3382d8dSKatayama Hirofumi MZ         {
846b3382d8dSKatayama Hirofumi MZ             pClientImc->hInputContext = LocalFree(pClientImc->hInputContext);
847b3382d8dSKatayama Hirofumi MZ             RtlLeaveCriticalSection(&pClientImc->cs);
848b3382d8dSKatayama Hirofumi MZ             goto Quit;
849b3382d8dSKatayama Hirofumi MZ         }
850b3382d8dSKatayama Hirofumi MZ 
851b3382d8dSKatayama Hirofumi MZ         hKL = GetKeyboardLayout(dwThreadId);
852b3382d8dSKatayama Hirofumi MZ         // bInited = Imm32InitContext(hIMC, hKL, fSelect);
853b3382d8dSKatayama Hirofumi MZ         bInited = Imm32InitContext(hIMC, pIC, pClientImc, hKL, fSelect);
854b3382d8dSKatayama Hirofumi MZ         LocalUnlock(pClientImc->hInputContext);
855b3382d8dSKatayama Hirofumi MZ 
856b3382d8dSKatayama Hirofumi MZ         if (!bInited)
857b3382d8dSKatayama Hirofumi MZ         {
858b3382d8dSKatayama Hirofumi MZ             pIC = NULL;
859b3382d8dSKatayama Hirofumi MZ             pClientImc->hInputContext = LocalFree(pClientImc->hInputContext);
860b3382d8dSKatayama Hirofumi MZ             RtlLeaveCriticalSection(&pClientImc->cs);
861b3382d8dSKatayama Hirofumi MZ             goto Quit;
862b3382d8dSKatayama Hirofumi MZ         }
863b3382d8dSKatayama Hirofumi MZ     }
864b3382d8dSKatayama Hirofumi MZ 
865b3382d8dSKatayama Hirofumi MZ     FIXME("We have to do something here\n");
866b3382d8dSKatayama Hirofumi MZ 
867b3382d8dSKatayama Hirofumi MZ     RtlLeaveCriticalSection(&pClientImc->cs);
868b3382d8dSKatayama Hirofumi MZ     pIC = LocalLock(pClientImc->hInputContext);
869b3382d8dSKatayama Hirofumi MZ     InterlockedIncrement(&pClientImc->cLockObj);
870b3382d8dSKatayama Hirofumi MZ 
871b3382d8dSKatayama Hirofumi MZ Quit:
872b3382d8dSKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
873b3382d8dSKatayama Hirofumi MZ     return pIC;
874b3382d8dSKatayama Hirofumi MZ }
875b3382d8dSKatayama Hirofumi MZ 
876c2c66affSColin Finck /***********************************************************************
877c2c66affSColin Finck  *		ImmDestroyContext (IMM32.@)
878c2c66affSColin Finck  */
879c2c66affSColin Finck BOOL WINAPI ImmDestroyContext(HIMC hIMC)
880c2c66affSColin Finck {
881692a30a8SKatayama Hirofumi MZ     HKL hKL;
882692a30a8SKatayama Hirofumi MZ 
8831d9542d2SKatayama Hirofumi MZ     TRACE("(%p)\n", hIMC);
884692a30a8SKatayama Hirofumi MZ 
885356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
886c2c66affSColin Finck         return FALSE;
887692a30a8SKatayama Hirofumi MZ 
8881da5d7a3SKatayama Hirofumi MZ     if (Imm32IsCrossThreadAccess(hIMC))
889692a30a8SKatayama Hirofumi MZ         return FALSE;
890692a30a8SKatayama Hirofumi MZ 
891692a30a8SKatayama Hirofumi MZ     hKL = GetKeyboardLayout(0);
892f8902dc3SKatayama Hirofumi MZ     return Imm32DestroyInputContext(hIMC, hKL, FALSE);
893c2c66affSColin Finck }
894c2c66affSColin Finck 
8951da5d7a3SKatayama Hirofumi MZ /***********************************************************************
8961da5d7a3SKatayama Hirofumi MZ  *		ImmLockClientImc (IMM32.@)
8971da5d7a3SKatayama Hirofumi MZ  */
89892393a75SKatayama Hirofumi MZ PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
89992393a75SKatayama Hirofumi MZ {
900be9a788fSKatayama Hirofumi MZ     PIMC pIMC;
90192393a75SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
90292393a75SKatayama Hirofumi MZ 
9031d9542d2SKatayama Hirofumi MZ     TRACE("(%p)\n", hImc);
90492393a75SKatayama Hirofumi MZ 
90592393a75SKatayama Hirofumi MZ     if (hImc == NULL)
90692393a75SKatayama Hirofumi MZ         return NULL;
90792393a75SKatayama Hirofumi MZ 
908be9a788fSKatayama Hirofumi MZ     pIMC = ValidateHandleNoErr(hImc, TYPE_INPUTCONTEXT);
909be9a788fSKatayama Hirofumi MZ     if (pIMC == NULL || !Imm32CheckImcProcess(pIMC))
910be9a788fSKatayama Hirofumi MZ         return NULL;
911be9a788fSKatayama Hirofumi MZ 
912be9a788fSKatayama Hirofumi MZ     pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
91392393a75SKatayama Hirofumi MZ     if (!pClientImc)
91492393a75SKatayama Hirofumi MZ     {
91546518ad6SKatayama Hirofumi MZ         pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
91692393a75SKatayama Hirofumi MZ         if (!pClientImc)
91792393a75SKatayama Hirofumi MZ             return NULL;
91892393a75SKatayama Hirofumi MZ 
91992393a75SKatayama Hirofumi MZ         RtlInitializeCriticalSection(&pClientImc->cs);
920f4bc74edSKatayama Hirofumi MZ 
92141b87158SKatayama Hirofumi MZ         pClientImc->dwCompatFlags = (DWORD)NtUserGetThreadState(THREADSTATE_IMECOMPATFLAGS);
92292393a75SKatayama Hirofumi MZ 
923ba3affe5SKatayama Hirofumi MZ         if (!NtUserUpdateInputContext(hImc, UIC_CLIENTIMCDATA, (DWORD_PTR)pClientImc))
92492393a75SKatayama Hirofumi MZ         {
92546518ad6SKatayama Hirofumi MZ             ImmLocalFree(pClientImc);
92692393a75SKatayama Hirofumi MZ             return NULL;
92792393a75SKatayama Hirofumi MZ         }
92892393a75SKatayama Hirofumi MZ 
92992393a75SKatayama Hirofumi MZ         pClientImc->dwFlags |= CLIENTIMC_UNKNOWN2;
93092393a75SKatayama Hirofumi MZ     }
93192393a75SKatayama Hirofumi MZ     else
93292393a75SKatayama Hirofumi MZ     {
9336ba810c0SKatayama Hirofumi MZ         if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
93492393a75SKatayama Hirofumi MZ             return NULL;
93592393a75SKatayama Hirofumi MZ     }
93692393a75SKatayama Hirofumi MZ 
93792393a75SKatayama Hirofumi MZ     InterlockedIncrement(&pClientImc->cLockObj);
93892393a75SKatayama Hirofumi MZ     return pClientImc;
93992393a75SKatayama Hirofumi MZ }
94092393a75SKatayama Hirofumi MZ 
9411da5d7a3SKatayama Hirofumi MZ /***********************************************************************
9421da5d7a3SKatayama Hirofumi MZ  *		ImmUnlockClientImc (IMM32.@)
9431da5d7a3SKatayama Hirofumi MZ  */
94492393a75SKatayama Hirofumi MZ VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
94592393a75SKatayama Hirofumi MZ {
94692393a75SKatayama Hirofumi MZ     LONG cLocks;
947b3382d8dSKatayama Hirofumi MZ     HANDLE hInputContext;
94892393a75SKatayama Hirofumi MZ 
9491d9542d2SKatayama Hirofumi MZ     TRACE("(%p)\n", pClientImc);
95092393a75SKatayama Hirofumi MZ 
95192393a75SKatayama Hirofumi MZ     cLocks = InterlockedDecrement(&pClientImc->cLockObj);
9526ba810c0SKatayama Hirofumi MZ     if (cLocks != 0 || !(pClientImc->dwFlags & CLIENTIMC_DESTROY))
95392393a75SKatayama Hirofumi MZ         return;
95492393a75SKatayama Hirofumi MZ 
955b3382d8dSKatayama Hirofumi MZ     hInputContext = pClientImc->hInputContext;
956b3382d8dSKatayama Hirofumi MZ     if (hInputContext)
957b3382d8dSKatayama Hirofumi MZ         LocalFree(hInputContext);
95892393a75SKatayama Hirofumi MZ 
95992393a75SKatayama Hirofumi MZ     RtlDeleteCriticalSection(&pClientImc->cs);
96046518ad6SKatayama Hirofumi MZ     ImmLocalFree(pClientImc);
96192393a75SKatayama Hirofumi MZ }
96292393a75SKatayama Hirofumi MZ 
963720da3b9SKatayama Hirofumi MZ static HIMC APIENTRY ImmGetSaveContext(HWND hWnd, DWORD dwContextFlags)
964a8d2cd4bSKatayama Hirofumi MZ {
965a8d2cd4bSKatayama Hirofumi MZ     HIMC hIMC;
966a8d2cd4bSKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
967a8d2cd4bSKatayama Hirofumi MZ     PWND pWnd;
968a8d2cd4bSKatayama Hirofumi MZ 
969356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
970a8d2cd4bSKatayama Hirofumi MZ         return NULL;
971a8d2cd4bSKatayama Hirofumi MZ 
972a8d2cd4bSKatayama Hirofumi MZ     if (!hWnd)
973a8d2cd4bSKatayama Hirofumi MZ     {
97441b87158SKatayama Hirofumi MZ         hIMC = (HIMC)NtUserGetThreadState(THREADSTATE_DEFAULTINPUTCONTEXT);
975a8d2cd4bSKatayama Hirofumi MZ         goto Quit;
976a8d2cd4bSKatayama Hirofumi MZ     }
977a8d2cd4bSKatayama Hirofumi MZ 
978a8d2cd4bSKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
979a8d2cd4bSKatayama Hirofumi MZ     if (!pWnd || Imm32IsCrossProcessAccess(hWnd))
980a8d2cd4bSKatayama Hirofumi MZ         return NULL;
981a8d2cd4bSKatayama Hirofumi MZ 
982a8d2cd4bSKatayama Hirofumi MZ     hIMC = pWnd->hImc;
983a8d2cd4bSKatayama Hirofumi MZ     if (!hIMC && (dwContextFlags & 1))
984a8d2cd4bSKatayama Hirofumi MZ         hIMC = (HIMC)NtUserQueryWindow(hWnd, QUERY_WINDOW_DEFAULT_ICONTEXT);
985a8d2cd4bSKatayama Hirofumi MZ 
986a8d2cd4bSKatayama Hirofumi MZ Quit:
987a8d2cd4bSKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
988a8d2cd4bSKatayama Hirofumi MZ     if (pClientImc == NULL)
989a8d2cd4bSKatayama Hirofumi MZ         return NULL;
990a8d2cd4bSKatayama Hirofumi MZ     if ((dwContextFlags & 2) && (pClientImc->dwFlags & CLIENTIMC_UNKNOWN3))
991a8d2cd4bSKatayama Hirofumi MZ         hIMC = NULL;
992a8d2cd4bSKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
993a8d2cd4bSKatayama Hirofumi MZ     return hIMC;
994a8d2cd4bSKatayama Hirofumi MZ }
995a8d2cd4bSKatayama Hirofumi MZ 
996c2c66affSColin Finck /***********************************************************************
997c2c66affSColin Finck  *		ImmGetContext (IMM32.@)
998c2c66affSColin Finck  */
999c2c66affSColin Finck HIMC WINAPI ImmGetContext(HWND hWnd)
1000c2c66affSColin Finck {
1001a8d2cd4bSKatayama Hirofumi MZ     TRACE("(%p)\n", hWnd);
1002a8d2cd4bSKatayama Hirofumi MZ     if (hWnd == NULL)
1003c2c66affSColin Finck         return NULL;
1004720da3b9SKatayama Hirofumi MZ     return ImmGetSaveContext(hWnd, 2);
1005c2c66affSColin Finck }
1006c2c66affSColin Finck 
1007c2c66affSColin Finck /***********************************************************************
10083714ee26SKatayama Hirofumi MZ  *		CtfImmIsCiceroEnabled (IMM32.@)
10093714ee26SKatayama Hirofumi MZ  */
10103714ee26SKatayama Hirofumi MZ BOOL WINAPI CtfImmIsCiceroEnabled(VOID)
10113714ee26SKatayama Hirofumi MZ {
1012ca3fa719SKatayama Hirofumi MZ     return Imm32IsCiceroMode();
1013c2c66affSColin Finck }
1014c2c66affSColin Finck 
1015c2c66affSColin Finck /***********************************************************************
1016b4557a60SKatayama Hirofumi MZ  *		ImmLockIMC(IMM32.@)
1017b3382d8dSKatayama Hirofumi MZ  *
1018b3382d8dSKatayama Hirofumi MZ  * NOTE: This is not ImmLockIMCC. Don't confuse.
1019c2c66affSColin Finck  */
1020b4557a60SKatayama Hirofumi MZ LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
1021c2c66affSColin Finck {
1022b3382d8dSKatayama Hirofumi MZ     TRACE("(%p)\n", hIMC);
1023b3382d8dSKatayama Hirofumi MZ     return Imm32LockIMCEx(hIMC, TRUE);
1024c2c66affSColin Finck }
1025c2c66affSColin Finck 
1026b4557a60SKatayama Hirofumi MZ /***********************************************************************
1027b4557a60SKatayama Hirofumi MZ *		ImmUnlockIMC(IMM32.@)
1028b4557a60SKatayama Hirofumi MZ */
1029b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
103077911014SKatayama Hirofumi MZ {
1031b4557a60SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
1032b4557a60SKatayama Hirofumi MZ 
1033b4557a60SKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
1034b4557a60SKatayama Hirofumi MZ     if (pClientImc == NULL)
103577911014SKatayama Hirofumi MZ         return FALSE;
103677911014SKatayama Hirofumi MZ 
1037b3382d8dSKatayama Hirofumi MZ     if (pClientImc->hInputContext)
1038b3382d8dSKatayama Hirofumi MZ         LocalUnlock(pClientImc->hInputContext);
1039b4557a60SKatayama Hirofumi MZ 
1040b4557a60SKatayama Hirofumi MZ     InterlockedDecrement(&pClientImc->cLockObj);
1041b4557a60SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
104277911014SKatayama Hirofumi MZ     return TRUE;
1043c2c66affSColin Finck }
1044c2c66affSColin Finck 
1045c2c66affSColin Finck /***********************************************************************
1046b4557a60SKatayama Hirofumi MZ  *		ImmReleaseContext (IMM32.@)
1047c2c66affSColin Finck  */
1048b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1049c2c66affSColin Finck {
1050b4557a60SKatayama Hirofumi MZ     TRACE("(%p, %p)\n", hWnd, hIMC);
1051b4557a60SKatayama Hirofumi MZ     UNREFERENCED_PARAMETER(hWnd);
1052b4557a60SKatayama Hirofumi MZ     UNREFERENCED_PARAMETER(hIMC);
1053b4557a60SKatayama Hirofumi MZ     return TRUE; // Do nothing. This is correct.
1054c2c66affSColin Finck }
1055c2c66affSColin Finck 
1056c2c66affSColin Finck /***********************************************************************
1057c2c66affSColin Finck  *              ImmCreateSoftKeyboard(IMM32.@)
1058c2c66affSColin Finck  */
1059c2c66affSColin Finck HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y)
1060c2c66affSColin Finck {
1061c2c66affSColin Finck     FIXME("(%d, %d, %d, %d): stub\n", uType, hOwner, x, y);
1062c2c66affSColin Finck     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1063c2c66affSColin Finck     return 0;
1064c2c66affSColin Finck }
1065c2c66affSColin Finck 
1066c2c66affSColin Finck /***********************************************************************
1067c2c66affSColin Finck  *              ImmDestroySoftKeyboard(IMM32.@)
1068c2c66affSColin Finck  */
1069c2c66affSColin Finck BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
1070c2c66affSColin Finck {
10712705abfbSKatayama Hirofumi MZ     TRACE("(%p)\n", hSoftWnd);
10722705abfbSKatayama Hirofumi MZ     return DestroyWindow(hSoftWnd);
1073c2c66affSColin Finck }
1074c2c66affSColin Finck 
1075c2c66affSColin Finck /***********************************************************************
1076c2c66affSColin Finck  *              ImmShowSoftKeyboard(IMM32.@)
1077c2c66affSColin Finck  */
1078c2c66affSColin Finck BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
1079c2c66affSColin Finck {
10802705abfbSKatayama Hirofumi MZ     TRACE("(%p, %d)\n", hSoftWnd, nCmdShow);
10812705abfbSKatayama Hirofumi MZ     if (hSoftWnd)
10822705abfbSKatayama Hirofumi MZ         return ShowWindow(hSoftWnd, nCmdShow);
1083c2c66affSColin Finck     return FALSE;
1084c2c66affSColin Finck }
1085c2c66affSColin Finck 
1086c2c66affSColin Finck /***********************************************************************
1087b4557a60SKatayama Hirofumi MZ *		ImmDisableTextFrameService(IMM32.@)
1088c2c66affSColin Finck */
1089b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmDisableTextFrameService(DWORD dwThreadId)
1090b4557a60SKatayama Hirofumi MZ {
1091b4557a60SKatayama Hirofumi MZ     FIXME("Stub\n");
1092b4557a60SKatayama Hirofumi MZ     return FALSE;
1093b4557a60SKatayama Hirofumi MZ }
1094b4557a60SKatayama Hirofumi MZ 
1095b4557a60SKatayama Hirofumi MZ /***********************************************************************
1096b4557a60SKatayama Hirofumi MZ  *              ImmEnumInputContext(IMM32.@)
1097b4557a60SKatayama Hirofumi MZ  */
1098b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmEnumInputContext(DWORD dwThreadId, IMCENUMPROC lpfn, LPARAM lParam)
1099b4557a60SKatayama Hirofumi MZ {
1100b4557a60SKatayama Hirofumi MZ     HIMC *phList;
1101b4557a60SKatayama Hirofumi MZ     DWORD dwIndex, dwCount;
1102b4557a60SKatayama Hirofumi MZ     BOOL ret = TRUE;
1103b4557a60SKatayama Hirofumi MZ     HIMC hIMC;
1104b4557a60SKatayama Hirofumi MZ 
1105b4557a60SKatayama Hirofumi MZ     TRACE("(%lu, %p, %p)\n", dwThreadId, lpfn, lParam);
1106b4557a60SKatayama Hirofumi MZ 
1107b4557a60SKatayama Hirofumi MZ     dwCount = Imm32AllocAndBuildHimcList(dwThreadId, &phList);
1108b4557a60SKatayama Hirofumi MZ     if (!dwCount)
1109b4557a60SKatayama Hirofumi MZ         return FALSE;
1110b4557a60SKatayama Hirofumi MZ 
1111b4557a60SKatayama Hirofumi MZ     for (dwIndex = 0; dwIndex < dwCount; ++dwIndex)
1112b4557a60SKatayama Hirofumi MZ     {
1113b4557a60SKatayama Hirofumi MZ         hIMC = phList[dwIndex];
1114b4557a60SKatayama Hirofumi MZ         ret = (*lpfn)(hIMC, lParam);
1115b4557a60SKatayama Hirofumi MZ         if (!ret)
1116b4557a60SKatayama Hirofumi MZ             break;
1117b4557a60SKatayama Hirofumi MZ     }
1118b4557a60SKatayama Hirofumi MZ 
111946518ad6SKatayama Hirofumi MZ     ImmLocalFree(phList);
1120b4557a60SKatayama Hirofumi MZ     return ret;
1121b4557a60SKatayama Hirofumi MZ }
1122b4557a60SKatayama Hirofumi MZ 
1123b4557a60SKatayama Hirofumi MZ /***********************************************************************
1124b4557a60SKatayama Hirofumi MZ  *              ImmSetActiveContext(IMM32.@)
1125b4557a60SKatayama Hirofumi MZ  */
11269adc538cSKatayama Hirofumi MZ BOOL WINAPI ImmSetActiveContext(HWND hWnd, HIMC hIMC, BOOL fActive)
1127b4557a60SKatayama Hirofumi MZ {
11289adc538cSKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
11299adc538cSKatayama Hirofumi MZ     LPINPUTCONTEXTDX pIC;
11309adc538cSKatayama Hirofumi MZ     PIMEDPI pImeDpi;
11319adc538cSKatayama Hirofumi MZ     HKL hKL;
11329adc538cSKatayama Hirofumi MZ     BOOL fOpen = FALSE;
11339adc538cSKatayama Hirofumi MZ     DWORD dwConversion = 0, iShow = ISC_SHOWUIALL;
11349adc538cSKatayama Hirofumi MZ     HWND hwndDefIME;
11359adc538cSKatayama Hirofumi MZ 
11369adc538cSKatayama Hirofumi MZ     TRACE("(%p, %p, %d)\n", hWnd, hIMC, fActive);
11379adc538cSKatayama Hirofumi MZ 
1138356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1139b4557a60SKatayama Hirofumi MZ         return FALSE;
11409adc538cSKatayama Hirofumi MZ 
11419adc538cSKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
11429adc538cSKatayama Hirofumi MZ 
11439adc538cSKatayama Hirofumi MZ     if (!fActive)
11449adc538cSKatayama Hirofumi MZ     {
11459adc538cSKatayama Hirofumi MZ         if (pClientImc)
11469adc538cSKatayama Hirofumi MZ             pClientImc->dwFlags &= ~CLIENTIMC_UNKNOWN4;
11479adc538cSKatayama Hirofumi MZ     }
11489adc538cSKatayama Hirofumi MZ     else if (hIMC)
11499adc538cSKatayama Hirofumi MZ     {
11509adc538cSKatayama Hirofumi MZ         if (!pClientImc)
11519adc538cSKatayama Hirofumi MZ             return FALSE;
11529adc538cSKatayama Hirofumi MZ 
11539adc538cSKatayama Hirofumi MZ         pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
11549adc538cSKatayama Hirofumi MZ         if (!pIC)
11559adc538cSKatayama Hirofumi MZ         {
11569adc538cSKatayama Hirofumi MZ             ImmUnlockClientImc(pClientImc);
11579adc538cSKatayama Hirofumi MZ             return FALSE;
11589adc538cSKatayama Hirofumi MZ         }
11599adc538cSKatayama Hirofumi MZ 
11609adc538cSKatayama Hirofumi MZ         pIC->hWnd = hWnd;
11619adc538cSKatayama Hirofumi MZ         pClientImc->dwFlags |= CLIENTIMC_UNKNOWN5;
11629adc538cSKatayama Hirofumi MZ 
11639adc538cSKatayama Hirofumi MZ         if (pIC->dwUIFlags & 2)
11649adc538cSKatayama Hirofumi MZ             iShow = (ISC_SHOWUIGUIDELINE | ISC_SHOWUIALLCANDIDATEWINDOW);
11659adc538cSKatayama Hirofumi MZ 
11669adc538cSKatayama Hirofumi MZ         fOpen = pIC->fOpen;
11679adc538cSKatayama Hirofumi MZ         dwConversion = pIC->fdwConversion;
11689adc538cSKatayama Hirofumi MZ 
11699adc538cSKatayama Hirofumi MZ         ImmUnlockIMC(hIMC);
11709adc538cSKatayama Hirofumi MZ     }
11719adc538cSKatayama Hirofumi MZ     else
11729adc538cSKatayama Hirofumi MZ     {
1173720da3b9SKatayama Hirofumi MZ         hIMC = ImmGetSaveContext(hWnd, 1);
11749adc538cSKatayama Hirofumi MZ         pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
11759adc538cSKatayama Hirofumi MZ         if (pIC)
11769adc538cSKatayama Hirofumi MZ         {
11779adc538cSKatayama Hirofumi MZ             pIC->hWnd = hWnd;
11789adc538cSKatayama Hirofumi MZ             ImmUnlockIMC(hIMC);
11799adc538cSKatayama Hirofumi MZ         }
11809adc538cSKatayama Hirofumi MZ         hIMC = NULL;
11819adc538cSKatayama Hirofumi MZ     }
11829adc538cSKatayama Hirofumi MZ 
11839adc538cSKatayama Hirofumi MZ     hKL = GetKeyboardLayout(0);
11849adc538cSKatayama Hirofumi MZ 
11859adc538cSKatayama Hirofumi MZ     if (Imm32IsCiceroMode() && !Imm32Is16BitMode())
11869adc538cSKatayama Hirofumi MZ     {
11879adc538cSKatayama Hirofumi MZ         Imm32CiceroSetActiveContext(hIMC, fActive, hWnd, hKL);
11889adc538cSKatayama Hirofumi MZ         hKL = GetKeyboardLayout(0);
11899adc538cSKatayama Hirofumi MZ     }
11909adc538cSKatayama Hirofumi MZ 
11919adc538cSKatayama Hirofumi MZ     pImeDpi = ImmLockImeDpi(hKL);
11929adc538cSKatayama Hirofumi MZ     if (pImeDpi)
11939adc538cSKatayama Hirofumi MZ     {
11949adc538cSKatayama Hirofumi MZ         if (IS_IME_HKL(hKL))
11959adc538cSKatayama Hirofumi MZ             pImeDpi->ImeSetActiveContext(hIMC, fActive);
11969adc538cSKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
11979adc538cSKatayama Hirofumi MZ     }
11989adc538cSKatayama Hirofumi MZ 
11999adc538cSKatayama Hirofumi MZ     if (IsWindow(hWnd))
12009adc538cSKatayama Hirofumi MZ     {
12019adc538cSKatayama Hirofumi MZ         SendMessageW(hWnd, WM_IME_SETCONTEXT, fActive, iShow);
12029adc538cSKatayama Hirofumi MZ         if (fActive)
12039adc538cSKatayama Hirofumi MZ             NtUserNotifyIMEStatus(hWnd, fOpen, dwConversion);
12049adc538cSKatayama Hirofumi MZ     }
12059adc538cSKatayama Hirofumi MZ     else if (!fActive)
12069adc538cSKatayama Hirofumi MZ     {
12079adc538cSKatayama Hirofumi MZ         hwndDefIME = ImmGetDefaultIMEWnd(NULL);
12089adc538cSKatayama Hirofumi MZ         if (hwndDefIME)
12099adc538cSKatayama Hirofumi MZ             SendMessageW(hwndDefIME, WM_IME_SETCONTEXT, 0, iShow);
12109adc538cSKatayama Hirofumi MZ     }
12119adc538cSKatayama Hirofumi MZ 
12129adc538cSKatayama Hirofumi MZ     if (pClientImc)
12139adc538cSKatayama Hirofumi MZ         ImmUnlockClientImc(pClientImc);
12149adc538cSKatayama Hirofumi MZ 
12159adc538cSKatayama Hirofumi MZ     return TRUE;
1216b4557a60SKatayama Hirofumi MZ }
1217b4557a60SKatayama Hirofumi MZ 
1218b4557a60SKatayama Hirofumi MZ /***********************************************************************
12198cdfc245SKatayama Hirofumi MZ  *              ImmWINNLSGetEnableStatus (IMM32.@)
12208cdfc245SKatayama Hirofumi MZ  */
12218cdfc245SKatayama Hirofumi MZ 
12228cdfc245SKatayama Hirofumi MZ BOOL WINAPI ImmWINNLSGetEnableStatus(HWND hWnd)
12238cdfc245SKatayama Hirofumi MZ {
12248cdfc245SKatayama Hirofumi MZ     if (!Imm32IsSystemJapaneseOrKorean())
12258cdfc245SKatayama Hirofumi MZ     {
12268cdfc245SKatayama Hirofumi MZ         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
12278cdfc245SKatayama Hirofumi MZ         return FALSE;
12288cdfc245SKatayama Hirofumi MZ     }
12298cdfc245SKatayama Hirofumi MZ 
1230720da3b9SKatayama Hirofumi MZ     return !!ImmGetSaveContext(hWnd, 2);
12318cdfc245SKatayama Hirofumi MZ }
12328cdfc245SKatayama Hirofumi MZ 
12338cdfc245SKatayama Hirofumi MZ /***********************************************************************
1234b4557a60SKatayama Hirofumi MZ  *              ImmSetActiveContextConsoleIME(IMM32.@)
1235b4557a60SKatayama Hirofumi MZ  */
1236b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmSetActiveContextConsoleIME(HWND hwnd, BOOL fFlag)
1237c2c66affSColin Finck {
1238d7f13aa6SKatayama Hirofumi MZ     HIMC hIMC;
1239b4557a60SKatayama Hirofumi MZ     TRACE("(%p, %d)\n", hwnd, fFlag);
1240d7f13aa6SKatayama Hirofumi MZ 
1241b4557a60SKatayama Hirofumi MZ     hIMC = ImmGetContext(hwnd);
1242b4557a60SKatayama Hirofumi MZ     if (hIMC)
1243b4557a60SKatayama Hirofumi MZ         return ImmSetActiveContext(hwnd, hIMC, fFlag);
1244c2c66affSColin Finck     return FALSE;
1245c2c66affSColin Finck }
1246c2c66affSColin Finck 
1247692a30a8SKatayama Hirofumi MZ BOOL WINAPI User32InitializeImmEntryTable(DWORD);
1248692a30a8SKatayama Hirofumi MZ 
1249692a30a8SKatayama Hirofumi MZ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
1250692a30a8SKatayama Hirofumi MZ {
1251692a30a8SKatayama Hirofumi MZ     HKL hKL;
125277911014SKatayama Hirofumi MZ     HIMC hIMC;
1253692a30a8SKatayama Hirofumi MZ 
12541d9542d2SKatayama Hirofumi MZ     TRACE("(%p, 0x%X, %p)\n", hinstDLL, fdwReason, lpReserved);
1255692a30a8SKatayama Hirofumi MZ 
1256692a30a8SKatayama Hirofumi MZ     switch (fdwReason)
1257692a30a8SKatayama Hirofumi MZ     {
1258692a30a8SKatayama Hirofumi MZ         case DLL_PROCESS_ATTACH:
1259692a30a8SKatayama Hirofumi MZ             if (!Imm32InitInstance(hinstDLL))
1260692a30a8SKatayama Hirofumi MZ             {
1261692a30a8SKatayama Hirofumi MZ                 ERR("Imm32InitInstance failed\n");
1262692a30a8SKatayama Hirofumi MZ                 return FALSE;
1263692a30a8SKatayama Hirofumi MZ             }
1264692a30a8SKatayama Hirofumi MZ             if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC))
1265692a30a8SKatayama Hirofumi MZ             {
1266692a30a8SKatayama Hirofumi MZ                 ERR("User32InitializeImmEntryTable failed\n");
1267692a30a8SKatayama Hirofumi MZ                 return FALSE;
1268692a30a8SKatayama Hirofumi MZ             }
1269692a30a8SKatayama Hirofumi MZ             break;
1270692a30a8SKatayama Hirofumi MZ 
1271692a30a8SKatayama Hirofumi MZ         case DLL_THREAD_ATTACH:
1272692a30a8SKatayama Hirofumi MZ             break;
1273692a30a8SKatayama Hirofumi MZ 
1274692a30a8SKatayama Hirofumi MZ         case DLL_THREAD_DETACH:
127545a4e53fSKatayama Hirofumi MZ             if (!IS_IMM_MODE() || NtCurrentTeb()->Win32ThreadInfo == NULL)
1276692a30a8SKatayama Hirofumi MZ                 return TRUE;
1277692a30a8SKatayama Hirofumi MZ 
1278692a30a8SKatayama Hirofumi MZ             hKL = GetKeyboardLayout(0);
127941b87158SKatayama Hirofumi MZ             hIMC = (HIMC)NtUserGetThreadState(THREADSTATE_DEFAULTINPUTCONTEXT);
1280f8902dc3SKatayama Hirofumi MZ             Imm32DestroyInputContext(hIMC, hKL, TRUE);
1281692a30a8SKatayama Hirofumi MZ             break;
1282692a30a8SKatayama Hirofumi MZ 
1283692a30a8SKatayama Hirofumi MZ         case DLL_PROCESS_DETACH:
1284692a30a8SKatayama Hirofumi MZ             RtlDeleteCriticalSection(&g_csImeDpi);
12852ab858c1SKatayama Hirofumi MZ             TRACE("imm32.dll is unloaded\n");
1286692a30a8SKatayama Hirofumi MZ             break;
1287692a30a8SKatayama Hirofumi MZ     }
1288692a30a8SKatayama Hirofumi MZ 
1289692a30a8SKatayama Hirofumi MZ     return TRUE;
1290692a30a8SKatayama Hirofumi MZ }
1291