xref: /reactos/dll/win32/imm32/imm.c (revision 720da3b9)
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 Oleg Dubinskiy <oleg.dubinskij2013@yandex.ua>
10f4bc74edSKatayama Hirofumi MZ  *              Copyright 2020-2021 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
11c2c66affSColin Finck  */
12c2c66affSColin Finck 
13b4557a60SKatayama Hirofumi MZ #include "precomp.h"
14c2c66affSColin Finck 
15c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(imm);
16c2c66affSColin Finck 
17692a30a8SKatayama Hirofumi MZ HMODULE g_hImm32Inst = NULL;
1882fa82d8SKatayama Hirofumi MZ PSERVERINFO gpsi = NULL;
19692a30a8SKatayama Hirofumi MZ SHAREDINFO g_SharedInfo = { NULL };
20692a30a8SKatayama Hirofumi MZ BYTE g_bClientRegd = FALSE;
21a8d2cd4bSKatayama Hirofumi MZ 
22692a30a8SKatayama Hirofumi MZ static BOOL APIENTRY Imm32InitInstance(HMODULE hMod)
23692a30a8SKatayama Hirofumi MZ {
24692a30a8SKatayama Hirofumi MZ     NTSTATUS status;
25692a30a8SKatayama Hirofumi MZ 
26692a30a8SKatayama Hirofumi MZ     if (hMod)
27692a30a8SKatayama Hirofumi MZ         g_hImm32Inst = hMod;
28692a30a8SKatayama Hirofumi MZ 
29692a30a8SKatayama Hirofumi MZ     if (g_bClientRegd)
30692a30a8SKatayama Hirofumi MZ         return TRUE;
31692a30a8SKatayama Hirofumi MZ 
32692a30a8SKatayama Hirofumi MZ     status = RtlInitializeCriticalSection(&g_csImeDpi);
33692a30a8SKatayama Hirofumi MZ     if (NT_ERROR(status))
34692a30a8SKatayama Hirofumi MZ         return FALSE;
35692a30a8SKatayama Hirofumi MZ 
36692a30a8SKatayama Hirofumi MZ     g_bClientRegd = 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 {
46b4557a60SKatayama Hirofumi MZ     g_SharedInfo = *ptr;
4782fa82d8SKatayama Hirofumi MZ     gpsi = g_SharedInfo.psi;
48b4557a60SKatayama Hirofumi MZ     return Imm32InitInstance(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 {
568e1dea0cSKatayama Hirofumi MZ     DWORD cbData;
578e1dea0cSKatayama Hirofumi MZ     HKEY hLayoutKey = NULL, hLayoutsKey = NULL;
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 
63ca3fa719SKatayama Hirofumi MZ     if (IS_IME_HKL(hKL) || !Imm32IsCiceroMode() || Imm32Is16BitMode())
648e1dea0cSKatayama Hirofumi MZ     {
65a37d9a4eSKatayama Hirofumi MZ         Imm32UIntToStr((DWORD)(DWORD_PTR)hKL, 16, szLayout, _countof(szLayout));
668e1dea0cSKatayama Hirofumi MZ 
678e1dea0cSKatayama Hirofumi MZ         error = RegOpenKeyW(HKEY_LOCAL_MACHINE, REGKEY_KEYBOARD_LAYOUTS, &hLayoutsKey);
688e1dea0cSKatayama Hirofumi MZ         if (error)
69a37d9a4eSKatayama Hirofumi MZ         {
70a37d9a4eSKatayama Hirofumi MZ             ERR("RegOpenKeyW: 0x%08lX\n", error);
71a37d9a4eSKatayama Hirofumi MZ             return FALSE;
72a37d9a4eSKatayama Hirofumi MZ         }
738e1dea0cSKatayama Hirofumi MZ 
748e1dea0cSKatayama Hirofumi MZ         error = RegOpenKeyW(hLayoutsKey, szLayout, &hLayoutKey);
75a37d9a4eSKatayama Hirofumi MZ         if (error)
76a37d9a4eSKatayama Hirofumi MZ         {
77a37d9a4eSKatayama Hirofumi MZ             ERR("RegOpenKeyW: 0x%08lX\n", error);
78a37d9a4eSKatayama Hirofumi MZ             RegCloseKey(hLayoutsKey);
79a37d9a4eSKatayama Hirofumi MZ             return FALSE;
80a37d9a4eSKatayama Hirofumi MZ         }
818e1dea0cSKatayama Hirofumi MZ     }
828e1dea0cSKatayama Hirofumi MZ     else
838e1dea0cSKatayama Hirofumi MZ     {
848e1dea0cSKatayama Hirofumi MZ         error = RegOpenKeyW(HKEY_LOCAL_MACHINE, REGKEY_IMM, &hLayoutKey);
858e1dea0cSKatayama Hirofumi MZ         if (error)
868e1dea0cSKatayama Hirofumi MZ         {
87a37d9a4eSKatayama Hirofumi MZ             ERR("RegOpenKeyW: 0x%08lX\n", error);
88a37d9a4eSKatayama Hirofumi MZ             return FALSE;
898e1dea0cSKatayama Hirofumi MZ         }
90a37d9a4eSKatayama Hirofumi MZ     }
91a37d9a4eSKatayama Hirofumi MZ 
928e1dea0cSKatayama Hirofumi MZ     cbData = sizeof(pImeInfoEx->wszImeFile);
938e1dea0cSKatayama Hirofumi MZ     error = RegQueryValueExW(hLayoutKey, L"Ime File", 0, 0,
948e1dea0cSKatayama Hirofumi MZ                              (LPBYTE)pImeInfoEx->wszImeFile, &cbData);
95a37d9a4eSKatayama Hirofumi MZ     pImeInfoEx->wszImeFile[_countof(pImeInfoEx->wszImeFile) - 1] = 0;
968e1dea0cSKatayama Hirofumi MZ 
978e1dea0cSKatayama Hirofumi MZ     RegCloseKey(hLayoutKey);
988e1dea0cSKatayama Hirofumi MZ     if (hLayoutsKey)
998e1dea0cSKatayama Hirofumi MZ         RegCloseKey(hLayoutsKey);
100a37d9a4eSKatayama Hirofumi MZ 
101a37d9a4eSKatayama Hirofumi MZ     pImeInfoEx->fLoadFlag = 0;
102a37d9a4eSKatayama Hirofumi MZ 
103a37d9a4eSKatayama Hirofumi MZ     if (error)
104a37d9a4eSKatayama Hirofumi MZ     {
105a37d9a4eSKatayama Hirofumi MZ         ERR("RegQueryValueExW: 0x%08lX\n", error);
106a37d9a4eSKatayama Hirofumi MZ         pImeInfoEx->hkl = NULL;
107a37d9a4eSKatayama Hirofumi MZ         return FALSE;
108a37d9a4eSKatayama Hirofumi MZ     }
109a37d9a4eSKatayama Hirofumi MZ 
110a37d9a4eSKatayama Hirofumi MZ     pImeInfoEx->hkl = hKL;
111a37d9a4eSKatayama Hirofumi MZ     return Imm32LoadImeVerInfo(pImeInfoEx);
1128e1dea0cSKatayama Hirofumi MZ }
1138e1dea0cSKatayama Hirofumi MZ 
114e6a51b54SKatayama Hirofumi MZ /***********************************************************************
115e6a51b54SKatayama Hirofumi MZ  *		ImmFreeLayout (IMM32.@)
116e6a51b54SKatayama Hirofumi MZ  */
117e6a51b54SKatayama Hirofumi MZ BOOL WINAPI ImmFreeLayout(DWORD dwUnknown)
118e6a51b54SKatayama Hirofumi MZ {
119e6a51b54SKatayama Hirofumi MZ     WCHAR szKBD[9];
120e6a51b54SKatayama Hirofumi MZ     UINT iKL, cKLs;
121e6a51b54SKatayama Hirofumi MZ     HKL hOldKL, hNewKL, *pList;
122e6a51b54SKatayama Hirofumi MZ     PIMEDPI pImeDpi;
123e6a51b54SKatayama Hirofumi MZ     LANGID LangID;
124e6a51b54SKatayama Hirofumi MZ 
125e6a51b54SKatayama Hirofumi MZ     TRACE("(0x%lX)\n", dwUnknown);
126e6a51b54SKatayama Hirofumi MZ 
127e6a51b54SKatayama Hirofumi MZ     hOldKL = GetKeyboardLayout(0);
128e6a51b54SKatayama Hirofumi MZ 
129e6a51b54SKatayama Hirofumi MZ     if (dwUnknown == 1)
130e6a51b54SKatayama Hirofumi MZ     {
131e6a51b54SKatayama Hirofumi MZ         if (!IS_IME_HKL(hOldKL))
132e6a51b54SKatayama Hirofumi MZ             return TRUE;
133e6a51b54SKatayama Hirofumi MZ 
134e6a51b54SKatayama Hirofumi MZ         LangID = LANGIDFROMLCID(GetSystemDefaultLCID());
135e6a51b54SKatayama Hirofumi MZ 
136e6a51b54SKatayama Hirofumi MZ         cKLs = GetKeyboardLayoutList(0, NULL);
137e6a51b54SKatayama Hirofumi MZ         if (cKLs)
138e6a51b54SKatayama Hirofumi MZ         {
13946518ad6SKatayama Hirofumi MZ             pList = ImmLocalAlloc(0, cKLs * sizeof(HKL));
140e6a51b54SKatayama Hirofumi MZ             if (pList == NULL)
141e6a51b54SKatayama Hirofumi MZ                 return FALSE;
142e6a51b54SKatayama Hirofumi MZ 
143e6a51b54SKatayama Hirofumi MZ             cKLs = GetKeyboardLayoutList(cKLs, pList);
144e6a51b54SKatayama Hirofumi MZ             for (iKL = 0; iKL < cKLs; ++iKL)
145e6a51b54SKatayama Hirofumi MZ             {
146e6a51b54SKatayama Hirofumi MZ                 if (!IS_IME_HKL(pList[iKL]))
147e6a51b54SKatayama Hirofumi MZ                 {
148e6a51b54SKatayama Hirofumi MZ                     LangID = LOWORD(pList[iKL]);
149e6a51b54SKatayama Hirofumi MZ                     break;
150e6a51b54SKatayama Hirofumi MZ                 }
151e6a51b54SKatayama Hirofumi MZ             }
152e6a51b54SKatayama Hirofumi MZ 
15346518ad6SKatayama Hirofumi MZ             ImmLocalFree(pList);
154e6a51b54SKatayama Hirofumi MZ         }
155e6a51b54SKatayama Hirofumi MZ 
156e6a51b54SKatayama Hirofumi MZ         StringCchPrintfW(szKBD, _countof(szKBD), L"%08X", LangID);
157e6a51b54SKatayama Hirofumi MZ         if (!LoadKeyboardLayoutW(szKBD, KLF_ACTIVATE))
158e6a51b54SKatayama Hirofumi MZ             LoadKeyboardLayoutW(L"00000409", KLF_ACTIVATE | 0x200);
159e6a51b54SKatayama Hirofumi MZ     }
160e6a51b54SKatayama Hirofumi MZ     else if (dwUnknown == 2)
161e6a51b54SKatayama Hirofumi MZ     {
162e6a51b54SKatayama Hirofumi MZ         RtlEnterCriticalSection(&g_csImeDpi);
163e6a51b54SKatayama Hirofumi MZ Retry:
164e6a51b54SKatayama Hirofumi MZ         for (pImeDpi = g_pImeDpiList; pImeDpi; pImeDpi = pImeDpi->pNext)
165e6a51b54SKatayama Hirofumi MZ         {
166e6a51b54SKatayama Hirofumi MZ             if (Imm32ReleaseIME(pImeDpi->hKL))
167e6a51b54SKatayama Hirofumi MZ                 goto Retry;
168e6a51b54SKatayama Hirofumi MZ         }
169e6a51b54SKatayama Hirofumi MZ         RtlLeaveCriticalSection(&g_csImeDpi);
170e6a51b54SKatayama Hirofumi MZ     }
171e6a51b54SKatayama Hirofumi MZ     else
172e6a51b54SKatayama Hirofumi MZ     {
173e6a51b54SKatayama Hirofumi MZ         hNewKL = (HKL)(DWORD_PTR)dwUnknown;
174e6a51b54SKatayama Hirofumi MZ         if (IS_IME_HKL(hNewKL) && hNewKL != hOldKL)
175e6a51b54SKatayama Hirofumi MZ             Imm32ReleaseIME(hNewKL);
176e6a51b54SKatayama Hirofumi MZ     }
177e6a51b54SKatayama Hirofumi MZ 
178e6a51b54SKatayama Hirofumi MZ     return TRUE;
179e6a51b54SKatayama Hirofumi MZ }
180e6a51b54SKatayama Hirofumi MZ 
18166ef3149SKatayama Hirofumi MZ VOID APIENTRY Imm32SelectLayout(HKL hNewKL, HKL hOldKL, HIMC hIMC)
18266ef3149SKatayama Hirofumi MZ {
18366ef3149SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
18466ef3149SKatayama Hirofumi MZ     LPINPUTCONTEXTDX pIC;
18566ef3149SKatayama Hirofumi MZ     LPGUIDELINE pGL;
18666ef3149SKatayama Hirofumi MZ     LPCANDIDATEINFO pCI;
18766ef3149SKatayama Hirofumi MZ     LPCOMPOSITIONSTRING pCS;
18866ef3149SKatayama Hirofumi MZ     LOGFONTA LogFontA;
18966ef3149SKatayama Hirofumi MZ     LOGFONTW LogFontW;
19066ef3149SKatayama Hirofumi MZ     BOOL fOpen, bIsNewHKLIme = TRUE, bIsOldHKLIme = TRUE, bClientWide, bNewDpiWide;
19166ef3149SKatayama Hirofumi MZ     DWORD cbNewPrivate = 0, cbOldPrivate = 0, dwConversion, dwSentence, dwSize, dwNewSize;
19266ef3149SKatayama Hirofumi MZ     PIMEDPI pNewImeDpi = NULL, pOldImeDpi = NULL;
19366ef3149SKatayama Hirofumi MZ     HANDLE hPrivate;
19466ef3149SKatayama Hirofumi MZ     PIME_STATE pNewState = NULL, pOldState = NULL;
19566ef3149SKatayama Hirofumi MZ 
19666ef3149SKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
19766ef3149SKatayama Hirofumi MZ     if (!pClientImc)
19866ef3149SKatayama Hirofumi MZ         return;
19966ef3149SKatayama Hirofumi MZ 
20066ef3149SKatayama Hirofumi MZ     pNewImeDpi = ImmLockImeDpi(hNewKL);
20166ef3149SKatayama Hirofumi MZ 
20266ef3149SKatayama Hirofumi MZ     if (hNewKL != hOldKL)
20366ef3149SKatayama Hirofumi MZ         pOldImeDpi = ImmLockImeDpi(hOldKL);
20466ef3149SKatayama Hirofumi MZ 
20566ef3149SKatayama Hirofumi MZ     if (pNewImeDpi)
20666ef3149SKatayama Hirofumi MZ     {
20766ef3149SKatayama Hirofumi MZ         cbNewPrivate = pNewImeDpi->ImeInfo.dwPrivateDataSize;
20866ef3149SKatayama Hirofumi MZ         pClientImc->uCodePage = pNewImeDpi->uCodePage;
20966ef3149SKatayama Hirofumi MZ     }
21066ef3149SKatayama Hirofumi MZ     else
21166ef3149SKatayama Hirofumi MZ     {
21266ef3149SKatayama Hirofumi MZ         pClientImc->uCodePage = CP_ACP;
21366ef3149SKatayama Hirofumi MZ     }
21466ef3149SKatayama Hirofumi MZ 
215b0d66e68SKatayama Hirofumi MZ     if (cbNewPrivate < sizeof(DWORD))
216b0d66e68SKatayama Hirofumi MZ         cbNewPrivate = sizeof(DWORD);
21766ef3149SKatayama Hirofumi MZ 
21866ef3149SKatayama Hirofumi MZ     if (pOldImeDpi)
21966ef3149SKatayama Hirofumi MZ         cbOldPrivate = pOldImeDpi->ImeInfo.dwPrivateDataSize;
22066ef3149SKatayama Hirofumi MZ 
221b0d66e68SKatayama Hirofumi MZ     if (cbOldPrivate < sizeof(DWORD))
222b0d66e68SKatayama Hirofumi MZ         cbOldPrivate = sizeof(DWORD);
22366ef3149SKatayama Hirofumi MZ 
22466ef3149SKatayama Hirofumi MZ     if (pClientImc->hKL == hOldKL)
22566ef3149SKatayama Hirofumi MZ     {
22666ef3149SKatayama Hirofumi MZ         if (pOldImeDpi)
22766ef3149SKatayama Hirofumi MZ         {
22866ef3149SKatayama Hirofumi MZ             if (IS_IME_HKL(hOldKL))
22966ef3149SKatayama Hirofumi MZ                 pOldImeDpi->ImeSelect(hIMC, FALSE);
23066ef3149SKatayama Hirofumi MZ             else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pOldImeDpi->CtfImeSelectEx)
23166ef3149SKatayama Hirofumi MZ                 pOldImeDpi->CtfImeSelectEx(hIMC, FALSE, hOldKL);
23266ef3149SKatayama Hirofumi MZ         }
23366ef3149SKatayama Hirofumi MZ         pClientImc->hKL = NULL;
23466ef3149SKatayama Hirofumi MZ     }
23566ef3149SKatayama Hirofumi MZ 
23666ef3149SKatayama Hirofumi MZ     if (CtfImmIsTextFrameServiceDisabled())
23766ef3149SKatayama Hirofumi MZ     {
238356babcaSKatayama Hirofumi MZ         if (IS_IMM_MODE() && !Imm32IsCiceroMode())
23966ef3149SKatayama Hirofumi MZ         {
24066ef3149SKatayama Hirofumi MZ             bIsNewHKLIme = IS_IME_HKL(hNewKL);
24166ef3149SKatayama Hirofumi MZ             bIsOldHKLIme = IS_IME_HKL(hOldKL);
24266ef3149SKatayama Hirofumi MZ         }
24366ef3149SKatayama Hirofumi MZ     }
24466ef3149SKatayama Hirofumi MZ 
24566ef3149SKatayama Hirofumi MZ     pIC = (LPINPUTCONTEXTDX)Imm32LockIMCEx(hIMC, FALSE);
24666ef3149SKatayama Hirofumi MZ     if (!pIC)
24766ef3149SKatayama Hirofumi MZ     {
24866ef3149SKatayama Hirofumi MZ         if (pNewImeDpi)
24966ef3149SKatayama Hirofumi MZ         {
25066ef3149SKatayama Hirofumi MZ             if (IS_IME_HKL(hNewKL))
25166ef3149SKatayama Hirofumi MZ                 pNewImeDpi->ImeSelect(hIMC, TRUE);
25266ef3149SKatayama Hirofumi MZ             else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pNewImeDpi->CtfImeSelectEx)
25366ef3149SKatayama Hirofumi MZ                 pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
25466ef3149SKatayama Hirofumi MZ 
25566ef3149SKatayama Hirofumi MZ             pClientImc->hKL = hNewKL;
25666ef3149SKatayama Hirofumi MZ         }
25766ef3149SKatayama Hirofumi MZ     }
25866ef3149SKatayama Hirofumi MZ     else
25966ef3149SKatayama Hirofumi MZ     {
26066ef3149SKatayama Hirofumi MZ         dwConversion = pIC->fdwConversion;
26166ef3149SKatayama Hirofumi MZ         dwSentence = pIC->fdwSentence;
26266ef3149SKatayama Hirofumi MZ         fOpen = pIC->fOpen;
26366ef3149SKatayama Hirofumi MZ 
26466ef3149SKatayama Hirofumi MZ         if (pNewImeDpi)
26566ef3149SKatayama Hirofumi MZ         {
26666ef3149SKatayama Hirofumi MZ             bClientWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
26766ef3149SKatayama Hirofumi MZ             bNewDpiWide = ImeDpi_IsUnicode(pNewImeDpi);
26866ef3149SKatayama Hirofumi MZ             if (bClientWide && !bNewDpiWide)
26966ef3149SKatayama Hirofumi MZ             {
27066ef3149SKatayama Hirofumi MZ                 if (pIC->fdwInit & INIT_LOGFONT)
27166ef3149SKatayama Hirofumi MZ                 {
27266ef3149SKatayama Hirofumi MZ                     LogFontWideToAnsi(&pIC->lfFont.W, &LogFontA);
27366ef3149SKatayama Hirofumi MZ                     pIC->lfFont.A = LogFontA;
27466ef3149SKatayama Hirofumi MZ                 }
27566ef3149SKatayama Hirofumi MZ                 pClientImc->dwFlags &= ~CLIENTIMC_WIDE;
27666ef3149SKatayama Hirofumi MZ             }
27766ef3149SKatayama Hirofumi MZ             else if (!bClientWide && bNewDpiWide)
27866ef3149SKatayama Hirofumi MZ             {
27966ef3149SKatayama Hirofumi MZ                 if (pIC->fdwInit & INIT_LOGFONT)
28066ef3149SKatayama Hirofumi MZ                 {
28166ef3149SKatayama Hirofumi MZ                     LogFontAnsiToWide(&pIC->lfFont.A, &LogFontW);
28266ef3149SKatayama Hirofumi MZ                     pIC->lfFont.W = LogFontW;
28366ef3149SKatayama Hirofumi MZ                 }
28466ef3149SKatayama Hirofumi MZ                 pClientImc->dwFlags |= CLIENTIMC_WIDE;
28566ef3149SKatayama Hirofumi MZ             }
28666ef3149SKatayama Hirofumi MZ         }
28766ef3149SKatayama Hirofumi MZ 
28866ef3149SKatayama Hirofumi MZ         if (cbOldPrivate != cbNewPrivate)
28966ef3149SKatayama Hirofumi MZ         {
29066ef3149SKatayama Hirofumi MZ             hPrivate = ImmReSizeIMCC(pIC->hPrivate, cbNewPrivate);
29166ef3149SKatayama Hirofumi MZ             if (!hPrivate)
29266ef3149SKatayama Hirofumi MZ             {
29366ef3149SKatayama Hirofumi MZ                 ImmDestroyIMCC(pIC->hPrivate);
29466ef3149SKatayama Hirofumi MZ                 hPrivate = ImmCreateIMCC(cbNewPrivate);
29566ef3149SKatayama Hirofumi MZ             }
29666ef3149SKatayama Hirofumi MZ             pIC->hPrivate = hPrivate;
29766ef3149SKatayama Hirofumi MZ         }
29866ef3149SKatayama Hirofumi MZ 
29966ef3149SKatayama Hirofumi MZ #define MAX_IMCC_SIZE 0x1000
30066ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hMsgBuf);
30166ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hMsgBuf) || dwSize > MAX_IMCC_SIZE)
30266ef3149SKatayama Hirofumi MZ         {
30366ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hMsgBuf);
30466ef3149SKatayama Hirofumi MZ             pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
30566ef3149SKatayama Hirofumi MZ             pIC->dwNumMsgBuf = 0;
30666ef3149SKatayama Hirofumi MZ         }
30766ef3149SKatayama Hirofumi MZ 
30866ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hGuideLine);
30966ef3149SKatayama Hirofumi MZ         dwNewSize = sizeof(GUIDELINE);
31066ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hGuideLine) ||
31166ef3149SKatayama Hirofumi MZ             dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
31266ef3149SKatayama Hirofumi MZ         {
31366ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hGuideLine);
31466ef3149SKatayama Hirofumi MZ             pIC->hGuideLine = ImmCreateIMCC(dwNewSize);
31566ef3149SKatayama Hirofumi MZ             pGL = ImmLockIMCC(pIC->hGuideLine);
31666ef3149SKatayama Hirofumi MZ             if (pGL)
31766ef3149SKatayama Hirofumi MZ             {
31866ef3149SKatayama Hirofumi MZ                 pGL->dwSize = dwNewSize;
31966ef3149SKatayama Hirofumi MZ                 ImmUnlockIMCC(pIC->hGuideLine);
32066ef3149SKatayama Hirofumi MZ             }
32166ef3149SKatayama Hirofumi MZ         }
32266ef3149SKatayama Hirofumi MZ 
32366ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hCandInfo);
32466ef3149SKatayama Hirofumi MZ         dwNewSize = sizeof(CANDIDATEINFO);
32566ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hCandInfo) ||
32666ef3149SKatayama Hirofumi MZ             dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
32766ef3149SKatayama Hirofumi MZ         {
32866ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hCandInfo);
32966ef3149SKatayama Hirofumi MZ             pIC->hCandInfo = ImmCreateIMCC(dwNewSize);
33066ef3149SKatayama Hirofumi MZ             pCI = ImmLockIMCC(pIC->hCandInfo);
33166ef3149SKatayama Hirofumi MZ             if (pCI)
33266ef3149SKatayama Hirofumi MZ             {
33366ef3149SKatayama Hirofumi MZ                 pCI->dwSize = dwNewSize;
33466ef3149SKatayama Hirofumi MZ                 ImmUnlockIMCC(pIC->hCandInfo);
33566ef3149SKatayama Hirofumi MZ             }
33666ef3149SKatayama Hirofumi MZ         }
33766ef3149SKatayama Hirofumi MZ 
33866ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hCompStr);
33966ef3149SKatayama Hirofumi MZ         dwNewSize = sizeof(COMPOSITIONSTRING);
34066ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hCompStr) ||
34166ef3149SKatayama Hirofumi MZ             dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
34266ef3149SKatayama Hirofumi MZ         {
34366ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hCompStr);
34466ef3149SKatayama Hirofumi MZ             pIC->hCompStr = ImmCreateIMCC(dwNewSize);
34566ef3149SKatayama Hirofumi MZ             pCS = ImmLockIMCC(pIC->hCompStr);
34666ef3149SKatayama Hirofumi MZ             if (pCS)
34766ef3149SKatayama Hirofumi MZ             {
34866ef3149SKatayama Hirofumi MZ                 pCS->dwSize = dwNewSize;
34966ef3149SKatayama Hirofumi MZ                 ImmUnlockIMCC(pIC->hCompStr);
35066ef3149SKatayama Hirofumi MZ             }
35166ef3149SKatayama Hirofumi MZ         }
35266ef3149SKatayama Hirofumi MZ #undef MAX_IMCC_SIZE
35366ef3149SKatayama Hirofumi MZ 
35466ef3149SKatayama Hirofumi MZ         if (pOldImeDpi && bIsOldHKLIme)
35566ef3149SKatayama Hirofumi MZ         {
35666ef3149SKatayama Hirofumi MZ             pOldState = Imm32FetchImeState(pIC, hOldKL);
35766ef3149SKatayama Hirofumi MZ             if (pOldState)
35866ef3149SKatayama Hirofumi MZ                 Imm32SaveImeStateSentence(pIC, pOldState, hOldKL);
35966ef3149SKatayama Hirofumi MZ         }
36066ef3149SKatayama Hirofumi MZ 
36166ef3149SKatayama Hirofumi MZ         if (pNewImeDpi && bIsNewHKLIme)
36266ef3149SKatayama Hirofumi MZ             pNewState = Imm32FetchImeState(pIC, hNewKL);
36366ef3149SKatayama Hirofumi MZ 
36466ef3149SKatayama Hirofumi MZ         if (pOldState != pNewState)
36566ef3149SKatayama Hirofumi MZ         {
36666ef3149SKatayama Hirofumi MZ             if (pOldState)
36766ef3149SKatayama Hirofumi MZ             {
36866ef3149SKatayama Hirofumi MZ                 pOldState->fOpen = !!pIC->fOpen;
36966ef3149SKatayama Hirofumi MZ                 pOldState->dwConversion = (pIC->fdwConversion & ~IME_CMODE_EUDC);
37066ef3149SKatayama Hirofumi MZ                 pOldState->dwSentence = pIC->fdwSentence;
37166ef3149SKatayama Hirofumi MZ                 pOldState->dwInit = pIC->fdwInit;
37266ef3149SKatayama Hirofumi MZ             }
37366ef3149SKatayama Hirofumi MZ 
37466ef3149SKatayama Hirofumi MZ             if (pNewState)
37566ef3149SKatayama Hirofumi MZ             {
37666ef3149SKatayama Hirofumi MZ                 if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_FORCE_OPEN)
37766ef3149SKatayama Hirofumi MZ                 {
37866ef3149SKatayama Hirofumi MZ                     pIC->dwChange &= ~INPUTCONTEXTDX_CHANGE_FORCE_OPEN;
37966ef3149SKatayama Hirofumi MZ                     pIC->fOpen = TRUE;
38066ef3149SKatayama Hirofumi MZ                 }
38166ef3149SKatayama Hirofumi MZ                 else
38266ef3149SKatayama Hirofumi MZ                 {
38366ef3149SKatayama Hirofumi MZ                     pIC->fOpen = pNewState->fOpen;
38466ef3149SKatayama Hirofumi MZ                 }
38566ef3149SKatayama Hirofumi MZ 
38666ef3149SKatayama Hirofumi MZ                 pIC->fdwConversion = (pNewState->dwConversion & ~IME_CMODE_EUDC);
38766ef3149SKatayama Hirofumi MZ                 pIC->fdwSentence = pNewState->dwSentence;
38866ef3149SKatayama Hirofumi MZ                 pIC->fdwInit = pNewState->dwInit;
38966ef3149SKatayama Hirofumi MZ             }
39066ef3149SKatayama Hirofumi MZ         }
39166ef3149SKatayama Hirofumi MZ 
39266ef3149SKatayama Hirofumi MZ         if (pNewState)
39366ef3149SKatayama Hirofumi MZ             Imm32LoadImeStateSentence(pIC, pNewState, hNewKL);
39466ef3149SKatayama Hirofumi MZ 
39566ef3149SKatayama Hirofumi MZ         if (pNewImeDpi)
39666ef3149SKatayama Hirofumi MZ         {
39766ef3149SKatayama Hirofumi MZ             if (IS_IME_HKL(hNewKL))
39866ef3149SKatayama Hirofumi MZ                 pNewImeDpi->ImeSelect(hIMC, TRUE);
39966ef3149SKatayama Hirofumi MZ             else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pNewImeDpi->CtfImeSelectEx)
40066ef3149SKatayama Hirofumi MZ                 pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
40166ef3149SKatayama Hirofumi MZ 
40266ef3149SKatayama Hirofumi MZ             pClientImc->hKL = hNewKL;
40366ef3149SKatayama Hirofumi MZ         }
40466ef3149SKatayama Hirofumi MZ 
40566ef3149SKatayama Hirofumi MZ         pIC->dwChange = 0;
40666ef3149SKatayama Hirofumi MZ         if (pIC->fOpen != fOpen)
40766ef3149SKatayama Hirofumi MZ             pIC->dwChange |= INPUTCONTEXTDX_CHANGE_OPEN;
40866ef3149SKatayama Hirofumi MZ         if (pIC->fdwConversion != dwConversion)
40966ef3149SKatayama Hirofumi MZ             pIC->dwChange |= INPUTCONTEXTDX_CHANGE_CONVERSION;
41066ef3149SKatayama Hirofumi MZ         if (pIC->fdwSentence != dwSentence)
41166ef3149SKatayama Hirofumi MZ             pIC->dwChange |= INPUTCONTEXTDX_CHANGE_SENTENCE;
41266ef3149SKatayama Hirofumi MZ 
41366ef3149SKatayama Hirofumi MZ         ImmUnlockIMC(hIMC);
41466ef3149SKatayama Hirofumi MZ     }
41566ef3149SKatayama Hirofumi MZ 
41666ef3149SKatayama Hirofumi MZ     ImmUnlockImeDpi(pOldImeDpi);
41766ef3149SKatayama Hirofumi MZ     ImmUnlockImeDpi(pNewImeDpi);
41866ef3149SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
41966ef3149SKatayama Hirofumi MZ }
42066ef3149SKatayama Hirofumi MZ 
42166ef3149SKatayama Hirofumi MZ typedef struct SELECT_LAYOUT
42266ef3149SKatayama Hirofumi MZ {
42366ef3149SKatayama Hirofumi MZ     HKL hNewKL;
42466ef3149SKatayama Hirofumi MZ     HKL hOldKL;
42566ef3149SKatayama Hirofumi MZ } SELECT_LAYOUT, *LPSELECT_LAYOUT;
42666ef3149SKatayama Hirofumi MZ 
42766ef3149SKatayama Hirofumi MZ static BOOL CALLBACK Imm32SelectLayoutProc(HIMC hIMC, LPARAM lParam)
42866ef3149SKatayama Hirofumi MZ {
42966ef3149SKatayama Hirofumi MZ     LPSELECT_LAYOUT pSelect = (LPSELECT_LAYOUT)lParam;
43066ef3149SKatayama Hirofumi MZ     Imm32SelectLayout(pSelect->hNewKL, pSelect->hOldKL, hIMC);
43166ef3149SKatayama Hirofumi MZ     return TRUE;
43266ef3149SKatayama Hirofumi MZ }
43366ef3149SKatayama Hirofumi MZ 
43466ef3149SKatayama Hirofumi MZ static BOOL CALLBACK Imm32NotifyCompStrProc(HIMC hIMC, LPARAM lParam)
43566ef3149SKatayama Hirofumi MZ {
43666ef3149SKatayama Hirofumi MZ     ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, (DWORD)lParam, 0);
43766ef3149SKatayama Hirofumi MZ     return TRUE;
43866ef3149SKatayama Hirofumi MZ }
43966ef3149SKatayama Hirofumi MZ 
44066ef3149SKatayama Hirofumi MZ /***********************************************************************
44166ef3149SKatayama Hirofumi MZ  *		ImmActivateLayout (IMM32.@)
44266ef3149SKatayama Hirofumi MZ  */
44366ef3149SKatayama Hirofumi MZ BOOL WINAPI ImmActivateLayout(HKL hKL)
44466ef3149SKatayama Hirofumi MZ {
44566ef3149SKatayama Hirofumi MZ     PIMEDPI pImeDpi;
44666ef3149SKatayama Hirofumi MZ     HKL hOldKL;
44766ef3149SKatayama Hirofumi MZ     LPARAM lParam;
44866ef3149SKatayama Hirofumi MZ     HWND hwndDefIME = NULL;
44966ef3149SKatayama Hirofumi MZ     SELECT_LAYOUT SelectLayout;
45066ef3149SKatayama Hirofumi MZ 
45166ef3149SKatayama Hirofumi MZ     hOldKL = GetKeyboardLayout(0);
45266ef3149SKatayama Hirofumi MZ 
45366ef3149SKatayama Hirofumi MZ     if (hOldKL == hKL && !(GetWin32ClientInfo()->CI_flags & CI_IMMACTIVATE))
45466ef3149SKatayama Hirofumi MZ         return TRUE;
45566ef3149SKatayama Hirofumi MZ 
45666ef3149SKatayama Hirofumi MZ     ImmLoadIME(hKL);
45766ef3149SKatayama Hirofumi MZ 
45866ef3149SKatayama Hirofumi MZ     if (hOldKL != hKL)
45966ef3149SKatayama Hirofumi MZ     {
46066ef3149SKatayama Hirofumi MZ         pImeDpi = ImmLockImeDpi(hOldKL);
46166ef3149SKatayama Hirofumi MZ         if (pImeDpi)
46266ef3149SKatayama Hirofumi MZ         {
46366ef3149SKatayama Hirofumi MZ             if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT)
46466ef3149SKatayama Hirofumi MZ                 lParam = CPS_COMPLETE;
46566ef3149SKatayama Hirofumi MZ             else
46666ef3149SKatayama Hirofumi MZ                 lParam = CPS_CANCEL;
46766ef3149SKatayama Hirofumi MZ             ImmUnlockImeDpi(pImeDpi);
46866ef3149SKatayama Hirofumi MZ 
46966ef3149SKatayama Hirofumi MZ             ImmEnumInputContext(0, Imm32NotifyCompStrProc, lParam);
47066ef3149SKatayama Hirofumi MZ         }
47166ef3149SKatayama Hirofumi MZ 
47266ef3149SKatayama Hirofumi MZ         hwndDefIME = ImmGetDefaultIMEWnd(NULL);
47366ef3149SKatayama Hirofumi MZ         if (IsWindow(hwndDefIME))
47466ef3149SKatayama Hirofumi MZ             SendMessageW(hwndDefIME, WM_IME_SELECT, FALSE, (LPARAM)hOldKL);
47566ef3149SKatayama Hirofumi MZ 
47666ef3149SKatayama Hirofumi MZ         NtUserSetThreadLayoutHandles(hKL, hOldKL);
47766ef3149SKatayama Hirofumi MZ     }
47866ef3149SKatayama Hirofumi MZ 
47966ef3149SKatayama Hirofumi MZ     SelectLayout.hNewKL = hKL;
48066ef3149SKatayama Hirofumi MZ     SelectLayout.hOldKL = hOldKL;
48166ef3149SKatayama Hirofumi MZ     ImmEnumInputContext(0, Imm32SelectLayoutProc, (LPARAM)&SelectLayout);
48266ef3149SKatayama Hirofumi MZ 
48366ef3149SKatayama Hirofumi MZ     if (IsWindow(hwndDefIME))
48466ef3149SKatayama Hirofumi MZ         SendMessageW(hwndDefIME, WM_IME_SELECT, TRUE, (LPARAM)hKL);
48566ef3149SKatayama Hirofumi MZ 
48666ef3149SKatayama Hirofumi MZ     return TRUE;
48766ef3149SKatayama Hirofumi MZ }
48866ef3149SKatayama Hirofumi MZ 
4899adc538cSKatayama Hirofumi MZ static VOID APIENTRY Imm32CiceroSetActiveContext(HIMC hIMC, BOOL fActive, HWND hWnd, HKL hKL)
4909adc538cSKatayama Hirofumi MZ {
4919adc538cSKatayama Hirofumi MZ     FIXME("We have to do something\n");
4929adc538cSKatayama Hirofumi MZ }
4939adc538cSKatayama Hirofumi MZ 
494c2c66affSColin Finck /***********************************************************************
495c2c66affSColin Finck  *		ImmAssociateContext (IMM32.@)
496c2c66affSColin Finck  */
497c2c66affSColin Finck HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
498c2c66affSColin Finck {
499ef003fa4SKatayama Hirofumi MZ     PWND pWnd;
500ef003fa4SKatayama Hirofumi MZ     HWND hwndFocus;
501ef003fa4SKatayama Hirofumi MZ     DWORD dwValue;
502ef003fa4SKatayama Hirofumi MZ     HIMC hOldIMC;
503c2c66affSColin Finck 
504ef003fa4SKatayama Hirofumi MZ     TRACE("(%p, %p)\n", hWnd, hIMC);
505c2c66affSColin Finck 
506356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
507c2c66affSColin Finck         return NULL;
508c2c66affSColin Finck 
509ef003fa4SKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
510ef003fa4SKatayama Hirofumi MZ     if (!pWnd)
511ef003fa4SKatayama Hirofumi MZ         return NULL;
512ef003fa4SKatayama Hirofumi MZ 
513ef003fa4SKatayama Hirofumi MZ     if (hIMC && Imm32IsCrossThreadAccess(hIMC))
514ef003fa4SKatayama Hirofumi MZ         return NULL;
515ef003fa4SKatayama Hirofumi MZ 
516ef003fa4SKatayama Hirofumi MZ     hOldIMC = pWnd->hImc;
517ef003fa4SKatayama Hirofumi MZ     if (hOldIMC == hIMC)
518c2c66affSColin Finck         return hIMC;
519c2c66affSColin Finck 
520ef003fa4SKatayama Hirofumi MZ     dwValue = NtUserAssociateInputContext(hWnd, hIMC, 0);
521ef003fa4SKatayama Hirofumi MZ     if (dwValue == 0)
522ef003fa4SKatayama Hirofumi MZ         return hOldIMC;
523ef003fa4SKatayama Hirofumi MZ     if (dwValue != 1)
524c45a6e15SJames Tabor         return NULL;
525c45a6e15SJames Tabor 
526ef003fa4SKatayama Hirofumi MZ     hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS);
527ef003fa4SKatayama Hirofumi MZ     if (hwndFocus == hWnd)
528c2c66affSColin Finck     {
529ef003fa4SKatayama Hirofumi MZ         ImmSetActiveContext(hWnd, hOldIMC, FALSE);
530ef003fa4SKatayama Hirofumi MZ         ImmSetActiveContext(hWnd, hIMC, TRUE);
531c2c66affSColin Finck     }
532c2c66affSColin Finck 
533ef003fa4SKatayama Hirofumi MZ     return hOldIMC;
534c2c66affSColin Finck }
535c2c66affSColin Finck 
536c2c66affSColin Finck /***********************************************************************
537c2c66affSColin Finck  *              ImmAssociateContextEx (IMM32.@)
538c2c66affSColin Finck  */
539c2c66affSColin Finck BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
540c2c66affSColin Finck {
541df6fff78SKatayama Hirofumi MZ     HWND hwndFocus;
542df6fff78SKatayama Hirofumi MZ     PWND pFocusWnd;
543df6fff78SKatayama Hirofumi MZ     HIMC hOldIMC = NULL;
544df6fff78SKatayama Hirofumi MZ     DWORD dwValue;
545c2c66affSColin Finck 
546df6fff78SKatayama Hirofumi MZ     TRACE("(%p, %p, 0x%lX)\n", hWnd, hIMC, dwFlags);
547df6fff78SKatayama Hirofumi MZ 
548356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
549c45a6e15SJames Tabor         return FALSE;
550c2c66affSColin Finck 
551df6fff78SKatayama Hirofumi MZ     if (hIMC && !(dwFlags & IACE_DEFAULT) && Imm32IsCrossThreadAccess(hIMC))
552df6fff78SKatayama Hirofumi MZ         return FALSE;
553df6fff78SKatayama Hirofumi MZ 
554df6fff78SKatayama Hirofumi MZ     hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS);
555df6fff78SKatayama Hirofumi MZ     pFocusWnd = ValidateHwndNoErr(hwndFocus);
556df6fff78SKatayama Hirofumi MZ     if (pFocusWnd)
557df6fff78SKatayama Hirofumi MZ         hOldIMC = pFocusWnd->hImc;
558df6fff78SKatayama Hirofumi MZ 
559df6fff78SKatayama Hirofumi MZ     dwValue = NtUserAssociateInputContext(hWnd, hIMC, dwFlags);
560df6fff78SKatayama Hirofumi MZ     switch (dwValue)
561c2c66affSColin Finck     {
562c2c66affSColin Finck         case 0:
563c2c66affSColin Finck             return TRUE;
564df6fff78SKatayama Hirofumi MZ 
565df6fff78SKatayama Hirofumi MZ         case 1:
566df6fff78SKatayama Hirofumi MZ             pFocusWnd = ValidateHwndNoErr(hwndFocus);
567df6fff78SKatayama Hirofumi MZ             if (pFocusWnd)
568c45a6e15SJames Tabor             {
569df6fff78SKatayama Hirofumi MZ                 hIMC = pFocusWnd->hImc;
570df6fff78SKatayama Hirofumi MZ                 if (hIMC != hOldIMC)
571df6fff78SKatayama Hirofumi MZ                 {
572df6fff78SKatayama Hirofumi MZ                     ImmSetActiveContext(hwndFocus, hOldIMC, FALSE);
573df6fff78SKatayama Hirofumi MZ                     ImmSetActiveContext(hwndFocus, hIMC, TRUE);
574c45a6e15SJames Tabor                 }
575df6fff78SKatayama Hirofumi MZ             }
576c2c66affSColin Finck             return TRUE;
577df6fff78SKatayama Hirofumi MZ 
578c2c66affSColin Finck         default:
579c2c66affSColin Finck             return FALSE;
580c2c66affSColin Finck     }
581c2c66affSColin Finck }
582c2c66affSColin Finck 
583c2c66affSColin Finck /***********************************************************************
584c2c66affSColin Finck  *		ImmCreateContext (IMM32.@)
585c2c66affSColin Finck  */
586c2c66affSColin Finck HIMC WINAPI ImmCreateContext(void)
587c2c66affSColin Finck {
588692a30a8SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
589692a30a8SKatayama Hirofumi MZ     HIMC hIMC;
590c2c66affSColin Finck 
5911d9542d2SKatayama Hirofumi MZ     TRACE("()\n");
592c2c66affSColin Finck 
593356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
594692a30a8SKatayama Hirofumi MZ         return NULL;
595c2c66affSColin Finck 
59646518ad6SKatayama Hirofumi MZ     pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
597692a30a8SKatayama Hirofumi MZ     if (pClientImc == NULL)
598692a30a8SKatayama Hirofumi MZ         return NULL;
599692a30a8SKatayama Hirofumi MZ 
600d5deacd9SKatayama Hirofumi MZ     hIMC = NtUserCreateInputContext((ULONG_PTR)pClientImc);
601692a30a8SKatayama Hirofumi MZ     if (hIMC == NULL)
602c2c66affSColin Finck     {
60346518ad6SKatayama Hirofumi MZ         ImmLocalFree(pClientImc);
604692a30a8SKatayama Hirofumi MZ         return NULL;
605c2c66affSColin Finck     }
606c2c66affSColin Finck 
607692a30a8SKatayama Hirofumi MZ     RtlInitializeCriticalSection(&pClientImc->cs);
608f4bc74edSKatayama Hirofumi MZ 
60941b87158SKatayama Hirofumi MZ     pClientImc->dwCompatFlags = (DWORD)NtUserGetThreadState(THREADSTATE_IMECOMPATFLAGS);
610f4bc74edSKatayama Hirofumi MZ 
611692a30a8SKatayama Hirofumi MZ     return hIMC;
612c2c66affSColin Finck }
613c2c66affSColin Finck 
61466ef3149SKatayama Hirofumi MZ static VOID APIENTRY Imm32FreeImeStates(LPINPUTCONTEXTDX pIC)
615c2c66affSColin Finck {
61666ef3149SKatayama Hirofumi MZ     PIME_STATE pState, pStateNext;
61766ef3149SKatayama Hirofumi MZ     PIME_SUBSTATE pSubState, pSubStateNext;
61866ef3149SKatayama Hirofumi MZ 
61966ef3149SKatayama Hirofumi MZ     pState = pIC->pState;
62066ef3149SKatayama Hirofumi MZ     pIC->pState = NULL;
62166ef3149SKatayama Hirofumi MZ     for (; pState; pState = pStateNext)
62266ef3149SKatayama Hirofumi MZ     {
62366ef3149SKatayama Hirofumi MZ         pStateNext = pState->pNext;
62466ef3149SKatayama Hirofumi MZ         for (pSubState = pState->pSubState; pSubState; pSubState = pSubStateNext)
62566ef3149SKatayama Hirofumi MZ         {
62666ef3149SKatayama Hirofumi MZ             pSubStateNext = pSubState->pNext;
62746518ad6SKatayama Hirofumi MZ             ImmLocalFree(pSubState);
62866ef3149SKatayama Hirofumi MZ         }
62946518ad6SKatayama Hirofumi MZ         ImmLocalFree(pState);
63066ef3149SKatayama Hirofumi MZ     }
631692a30a8SKatayama Hirofumi MZ }
632c2c66affSColin Finck 
633692a30a8SKatayama Hirofumi MZ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
634692a30a8SKatayama Hirofumi MZ {
635692a30a8SKatayama Hirofumi MZ     PIMEDPI pImeDpi;
63666ef3149SKatayama Hirofumi MZ     LPINPUTCONTEXTDX pIC;
637692a30a8SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
638be9a788fSKatayama Hirofumi MZ     PIMC pIMC;
639692a30a8SKatayama Hirofumi MZ 
640356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE() || hIMC == NULL)
641c2c66affSColin Finck         return FALSE;
642c2c66affSColin Finck 
643be9a788fSKatayama Hirofumi MZ     pIMC = ValidateHandleNoErr(hIMC, TYPE_INPUTCONTEXT);
64445a4e53fSKatayama Hirofumi MZ     if (!pIMC || pIMC->head.pti != Imm32CurrentPti())
64545a4e53fSKatayama Hirofumi MZ     {
64645a4e53fSKatayama Hirofumi MZ         ERR("invalid pIMC: %p\n", pIMC);
647be9a788fSKatayama Hirofumi MZ         return FALSE;
64845a4e53fSKatayama Hirofumi MZ     }
649be9a788fSKatayama Hirofumi MZ 
650be9a788fSKatayama Hirofumi MZ     pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
651692a30a8SKatayama Hirofumi MZ     if (!pClientImc)
65245a4e53fSKatayama Hirofumi MZ         goto Finish;
653c2c66affSColin Finck 
65445a4e53fSKatayama Hirofumi MZ     if ((pClientImc->dwFlags & CLIENTIMC_UNKNOWN2) && !bKeep)
655692a30a8SKatayama Hirofumi MZ     {
65645a4e53fSKatayama Hirofumi MZ         ERR("CLIENTIMC_UNKNOWN2\n");
65745a4e53fSKatayama Hirofumi MZ         return FALSE;
658692a30a8SKatayama Hirofumi MZ     }
659c2c66affSColin Finck 
6606ba810c0SKatayama Hirofumi MZ     if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
66145a4e53fSKatayama Hirofumi MZ         return TRUE;
66245a4e53fSKatayama Hirofumi MZ 
66345a4e53fSKatayama Hirofumi MZ     InterlockedIncrement(&pClientImc->cLockObj);
66445a4e53fSKatayama Hirofumi MZ 
66545a4e53fSKatayama Hirofumi MZ     if (!pClientImc->hInputContext)
66645a4e53fSKatayama Hirofumi MZ         goto Quit;
66745a4e53fSKatayama Hirofumi MZ 
66866ef3149SKatayama Hirofumi MZ     pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
66945a4e53fSKatayama Hirofumi MZ     if (!pIC)
670692a30a8SKatayama Hirofumi MZ     {
671692a30a8SKatayama Hirofumi MZ         ImmUnlockClientImc(pClientImc);
67245a4e53fSKatayama Hirofumi MZ         ERR("!pIC\n");
673692a30a8SKatayama Hirofumi MZ         return FALSE;
674692a30a8SKatayama Hirofumi MZ     }
675692a30a8SKatayama Hirofumi MZ 
676692a30a8SKatayama Hirofumi MZ     pImeDpi = ImmLockImeDpi(hKL);
67745a4e53fSKatayama Hirofumi MZ     if (pImeDpi)
678692a30a8SKatayama Hirofumi MZ     {
679692a30a8SKatayama Hirofumi MZ         pImeDpi->ImeSelect(hIMC, FALSE);
680692a30a8SKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
681692a30a8SKatayama Hirofumi MZ     }
682692a30a8SKatayama Hirofumi MZ 
683b3382d8dSKatayama Hirofumi MZ     pIC->hPrivate = ImmDestroyIMCC(pIC->hPrivate);
684b3382d8dSKatayama Hirofumi MZ     pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
685b3382d8dSKatayama Hirofumi MZ     pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
686b3382d8dSKatayama Hirofumi MZ     pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
687b3382d8dSKatayama Hirofumi MZ     pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
68866ef3149SKatayama Hirofumi MZ     Imm32FreeImeStates(pIC);
689692a30a8SKatayama Hirofumi MZ     ImmUnlockIMC(hIMC);
690692a30a8SKatayama Hirofumi MZ 
69145a4e53fSKatayama Hirofumi MZ Quit:
6926ba810c0SKatayama Hirofumi MZ     pClientImc->dwFlags |= CLIENTIMC_DESTROY;
693692a30a8SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
694692a30a8SKatayama Hirofumi MZ 
69545a4e53fSKatayama Hirofumi MZ Finish:
69645a4e53fSKatayama Hirofumi MZ     if (bKeep)
697c2c66affSColin Finck         return TRUE;
69845a4e53fSKatayama Hirofumi MZ     return NtUserDestroyInputContext(hIMC);
699c2c66affSColin Finck }
700c2c66affSColin Finck 
701b3382d8dSKatayama Hirofumi MZ BOOL APIENTRY
702b3382d8dSKatayama Hirofumi MZ Imm32InitContext(HIMC hIMC, LPINPUTCONTEXT pIC, PCLIENTIMC pClientImc, HKL hKL, BOOL fSelect)
703b3382d8dSKatayama Hirofumi MZ {
704b3382d8dSKatayama Hirofumi MZ     DWORD dwIndex, cbPrivate;
705b3382d8dSKatayama Hirofumi MZ     PIMEDPI pImeDpi = NULL;
706b3382d8dSKatayama Hirofumi MZ     LPCOMPOSITIONSTRING pCS;
707b3382d8dSKatayama Hirofumi MZ     LPCANDIDATEINFO pCI;
708b3382d8dSKatayama Hirofumi MZ     LPGUIDELINE pGL;
709b3382d8dSKatayama Hirofumi MZ     /* NOTE: Windows does recursive call ImmLockIMC here but we don't do so. */
710b3382d8dSKatayama Hirofumi MZ 
711b3382d8dSKatayama Hirofumi MZ     /* Create IC components */
712b3382d8dSKatayama Hirofumi MZ     pIC->hCompStr = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
713b3382d8dSKatayama Hirofumi MZ     pIC->hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
714b3382d8dSKatayama Hirofumi MZ     pIC->hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
715b3382d8dSKatayama Hirofumi MZ     pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
716b3382d8dSKatayama Hirofumi MZ     if (!pIC->hCompStr || !pIC->hCandInfo || !pIC->hGuideLine || !pIC->hMsgBuf)
717b3382d8dSKatayama Hirofumi MZ         goto Fail;
718b3382d8dSKatayama Hirofumi MZ 
719b3382d8dSKatayama Hirofumi MZ     /* Initialize IC components */
720b3382d8dSKatayama Hirofumi MZ     pCS = ImmLockIMCC(pIC->hCompStr);
721b3382d8dSKatayama Hirofumi MZ     if (!pCS)
722b3382d8dSKatayama Hirofumi MZ         goto Fail;
723b3382d8dSKatayama Hirofumi MZ     pCS->dwSize = sizeof(COMPOSITIONSTRING);
724b3382d8dSKatayama Hirofumi MZ     ImmUnlockIMCC(pIC->hCompStr);
725b3382d8dSKatayama Hirofumi MZ 
726b3382d8dSKatayama Hirofumi MZ     pCI = ImmLockIMCC(pIC->hCandInfo);
727b3382d8dSKatayama Hirofumi MZ     if (!pCI)
728b3382d8dSKatayama Hirofumi MZ         goto Fail;
729b3382d8dSKatayama Hirofumi MZ     pCI->dwSize = sizeof(CANDIDATEINFO);
730b3382d8dSKatayama Hirofumi MZ     ImmUnlockIMCC(pIC->hCandInfo);
731b3382d8dSKatayama Hirofumi MZ 
732b3382d8dSKatayama Hirofumi MZ     pGL = ImmLockIMCC(pIC->hGuideLine);
733b3382d8dSKatayama Hirofumi MZ     if (!pGL)
734b3382d8dSKatayama Hirofumi MZ         goto Fail;
735b3382d8dSKatayama Hirofumi MZ     pGL->dwSize = sizeof(GUIDELINE);
736b3382d8dSKatayama Hirofumi MZ     ImmUnlockIMCC(pIC->hGuideLine);
737b3382d8dSKatayama Hirofumi MZ 
738b3382d8dSKatayama Hirofumi MZ     pIC->dwNumMsgBuf = 0;
739b3382d8dSKatayama Hirofumi MZ     pIC->fOpen = FALSE;
740b3382d8dSKatayama Hirofumi MZ     pIC->fdwConversion = pIC->fdwSentence = 0;
741b3382d8dSKatayama Hirofumi MZ 
742b3382d8dSKatayama Hirofumi MZ     for (dwIndex = 0; dwIndex < MAX_CANDIDATEFORM; ++dwIndex)
743b3382d8dSKatayama Hirofumi MZ         pIC->cfCandForm[dwIndex].dwIndex = IMM_INVALID_CANDFORM;
744b3382d8dSKatayama Hirofumi MZ 
745b3382d8dSKatayama Hirofumi MZ     /* Get private data size */
746b3382d8dSKatayama Hirofumi MZ     pImeDpi = ImmLockImeDpi(hKL);
747b3382d8dSKatayama Hirofumi MZ     if (!pImeDpi)
748b3382d8dSKatayama Hirofumi MZ     {
749b3382d8dSKatayama Hirofumi MZ         cbPrivate = sizeof(DWORD);
750b3382d8dSKatayama Hirofumi MZ     }
751b3382d8dSKatayama Hirofumi MZ     else
752b3382d8dSKatayama Hirofumi MZ     {
753b3382d8dSKatayama Hirofumi MZ         /* Update CLIENTIMC */
754b3382d8dSKatayama Hirofumi MZ         pClientImc->uCodePage = pImeDpi->uCodePage;
755b3382d8dSKatayama Hirofumi MZ         if (ImeDpi_IsUnicode(pImeDpi))
756b3382d8dSKatayama Hirofumi MZ             pClientImc->dwFlags |= CLIENTIMC_WIDE;
757b3382d8dSKatayama Hirofumi MZ 
758b3382d8dSKatayama Hirofumi MZ         cbPrivate = pImeDpi->ImeInfo.dwPrivateDataSize;
759b3382d8dSKatayama Hirofumi MZ     }
760b3382d8dSKatayama Hirofumi MZ 
761b3382d8dSKatayama Hirofumi MZ     /* Create private data */
762b3382d8dSKatayama Hirofumi MZ     pIC->hPrivate = ImmCreateIMCC(cbPrivate);
763b3382d8dSKatayama Hirofumi MZ     if (!pIC->hPrivate)
764b3382d8dSKatayama Hirofumi MZ         goto Fail;
765b3382d8dSKatayama Hirofumi MZ 
766b3382d8dSKatayama Hirofumi MZ     if (pImeDpi)
767b3382d8dSKatayama Hirofumi MZ     {
768b3382d8dSKatayama Hirofumi MZ         /* Select the IME */
769b3382d8dSKatayama Hirofumi MZ         if (fSelect)
770b3382d8dSKatayama Hirofumi MZ         {
771b3382d8dSKatayama Hirofumi MZ             if (IS_IME_HKL(hKL))
772b3382d8dSKatayama Hirofumi MZ                 pImeDpi->ImeSelect(hIMC, TRUE);
773b3382d8dSKatayama Hirofumi MZ             else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pImeDpi->CtfImeSelectEx)
774b3382d8dSKatayama Hirofumi MZ                 pImeDpi->CtfImeSelectEx(hIMC, TRUE, hKL);
775b3382d8dSKatayama Hirofumi MZ         }
776b3382d8dSKatayama Hirofumi MZ 
777b3382d8dSKatayama Hirofumi MZ         /* Set HKL */
778b3382d8dSKatayama Hirofumi MZ         pClientImc->hKL = hKL;
779b3382d8dSKatayama Hirofumi MZ 
780b3382d8dSKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
781b3382d8dSKatayama Hirofumi MZ     }
782b3382d8dSKatayama Hirofumi MZ 
783b3382d8dSKatayama Hirofumi MZ     return TRUE;
784b3382d8dSKatayama Hirofumi MZ 
785b3382d8dSKatayama Hirofumi MZ Fail:
786b3382d8dSKatayama Hirofumi MZ     if (pImeDpi)
787b3382d8dSKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
788b3382d8dSKatayama Hirofumi MZ 
789b3382d8dSKatayama Hirofumi MZ     pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
790b3382d8dSKatayama Hirofumi MZ     pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
791b3382d8dSKatayama Hirofumi MZ     pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
792b3382d8dSKatayama Hirofumi MZ     pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
793b3382d8dSKatayama Hirofumi MZ     return FALSE;
794b3382d8dSKatayama Hirofumi MZ }
795b3382d8dSKatayama Hirofumi MZ 
796b3382d8dSKatayama Hirofumi MZ LPINPUTCONTEXT APIENTRY Imm32LockIMCEx(HIMC hIMC, BOOL fSelect)
797b3382d8dSKatayama Hirofumi MZ {
798b3382d8dSKatayama Hirofumi MZ     HANDLE hIC;
799b3382d8dSKatayama Hirofumi MZ     LPINPUTCONTEXT pIC = NULL;
800b3382d8dSKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
801b3382d8dSKatayama Hirofumi MZ     WORD Word;
802b3382d8dSKatayama Hirofumi MZ     DWORD dwThreadId;
803b3382d8dSKatayama Hirofumi MZ     HKL hKL, hNewKL;
804b3382d8dSKatayama Hirofumi MZ     PIMEDPI pImeDpi = NULL;
805b3382d8dSKatayama Hirofumi MZ     BOOL bInited;
806b3382d8dSKatayama Hirofumi MZ 
807b3382d8dSKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
808b3382d8dSKatayama Hirofumi MZ     if (!pClientImc)
809b3382d8dSKatayama Hirofumi MZ         return NULL;
810b3382d8dSKatayama Hirofumi MZ 
811b3382d8dSKatayama Hirofumi MZ     RtlEnterCriticalSection(&pClientImc->cs);
812b3382d8dSKatayama Hirofumi MZ 
813b3382d8dSKatayama Hirofumi MZ     if (!pClientImc->hInputContext)
814b3382d8dSKatayama Hirofumi MZ     {
815cdf3b5e8SKatayama Hirofumi MZ         dwThreadId = (DWORD)NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID);
816b3382d8dSKatayama Hirofumi MZ 
817b3382d8dSKatayama Hirofumi MZ         if (dwThreadId == GetCurrentThreadId() && Imm32IsCiceroMode() && !Imm32Is16BitMode())
818b3382d8dSKatayama Hirofumi MZ         {
819b3382d8dSKatayama Hirofumi MZ             hKL = GetKeyboardLayout(0);
820b3382d8dSKatayama Hirofumi MZ             Word = LOWORD(hKL);
821b3382d8dSKatayama Hirofumi MZ             hNewKL = (HKL)(DWORD_PTR)MAKELONG(Word, Word);
822b3382d8dSKatayama Hirofumi MZ 
823b3382d8dSKatayama Hirofumi MZ             pImeDpi = ImmLockOrLoadImeDpi(hNewKL);
824b3382d8dSKatayama Hirofumi MZ             if (pImeDpi)
825b3382d8dSKatayama Hirofumi MZ             {
826b3382d8dSKatayama Hirofumi MZ                 FIXME("We have to do something here\n");
827b3382d8dSKatayama Hirofumi MZ             }
828b3382d8dSKatayama Hirofumi MZ         }
829b3382d8dSKatayama Hirofumi MZ 
830cdf3b5e8SKatayama Hirofumi MZ         if (!NtUserQueryInputContext(hIMC, QIC_DEFAULTWINDOWIME))
831b3382d8dSKatayama Hirofumi MZ         {
832b3382d8dSKatayama Hirofumi MZ             RtlLeaveCriticalSection(&pClientImc->cs);
833b3382d8dSKatayama Hirofumi MZ             goto Quit;
834b3382d8dSKatayama Hirofumi MZ         }
835b3382d8dSKatayama Hirofumi MZ 
836b3382d8dSKatayama Hirofumi MZ         hIC = LocalAlloc(LHND, sizeof(INPUTCONTEXTDX));
837b3382d8dSKatayama Hirofumi MZ         if (!hIC)
838b3382d8dSKatayama Hirofumi MZ         {
839b3382d8dSKatayama Hirofumi MZ             RtlLeaveCriticalSection(&pClientImc->cs);
840b3382d8dSKatayama Hirofumi MZ             goto Quit;
841b3382d8dSKatayama Hirofumi MZ         }
842b3382d8dSKatayama Hirofumi MZ         pClientImc->hInputContext = hIC;
843b3382d8dSKatayama Hirofumi MZ 
844b3382d8dSKatayama Hirofumi MZ         pIC = LocalLock(pClientImc->hInputContext);
845b3382d8dSKatayama Hirofumi MZ         if (!pIC)
846b3382d8dSKatayama Hirofumi MZ         {
847b3382d8dSKatayama Hirofumi MZ             pClientImc->hInputContext = LocalFree(pClientImc->hInputContext);
848b3382d8dSKatayama Hirofumi MZ             RtlLeaveCriticalSection(&pClientImc->cs);
849b3382d8dSKatayama Hirofumi MZ             goto Quit;
850b3382d8dSKatayama Hirofumi MZ         }
851b3382d8dSKatayama Hirofumi MZ 
852b3382d8dSKatayama Hirofumi MZ         hKL = GetKeyboardLayout(dwThreadId);
853b3382d8dSKatayama Hirofumi MZ         // bInited = Imm32InitContext(hIMC, hKL, fSelect);
854b3382d8dSKatayama Hirofumi MZ         bInited = Imm32InitContext(hIMC, pIC, pClientImc, hKL, fSelect);
855b3382d8dSKatayama Hirofumi MZ         LocalUnlock(pClientImc->hInputContext);
856b3382d8dSKatayama Hirofumi MZ 
857b3382d8dSKatayama Hirofumi MZ         if (!bInited)
858b3382d8dSKatayama Hirofumi MZ         {
859b3382d8dSKatayama Hirofumi MZ             pIC = NULL;
860b3382d8dSKatayama Hirofumi MZ             pClientImc->hInputContext = LocalFree(pClientImc->hInputContext);
861b3382d8dSKatayama Hirofumi MZ             RtlLeaveCriticalSection(&pClientImc->cs);
862b3382d8dSKatayama Hirofumi MZ             goto Quit;
863b3382d8dSKatayama Hirofumi MZ         }
864b3382d8dSKatayama Hirofumi MZ     }
865b3382d8dSKatayama Hirofumi MZ 
866b3382d8dSKatayama Hirofumi MZ     FIXME("We have to do something here\n");
867b3382d8dSKatayama Hirofumi MZ 
868b3382d8dSKatayama Hirofumi MZ     RtlLeaveCriticalSection(&pClientImc->cs);
869b3382d8dSKatayama Hirofumi MZ     pIC = LocalLock(pClientImc->hInputContext);
870b3382d8dSKatayama Hirofumi MZ     InterlockedIncrement(&pClientImc->cLockObj);
871b3382d8dSKatayama Hirofumi MZ 
872b3382d8dSKatayama Hirofumi MZ Quit:
873b3382d8dSKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
874b3382d8dSKatayama Hirofumi MZ     return pIC;
875b3382d8dSKatayama Hirofumi MZ }
876b3382d8dSKatayama Hirofumi MZ 
877c2c66affSColin Finck /***********************************************************************
878c2c66affSColin Finck  *		ImmDestroyContext (IMM32.@)
879c2c66affSColin Finck  */
880c2c66affSColin Finck BOOL WINAPI ImmDestroyContext(HIMC hIMC)
881c2c66affSColin Finck {
882692a30a8SKatayama Hirofumi MZ     HKL hKL;
883692a30a8SKatayama Hirofumi MZ 
8841d9542d2SKatayama Hirofumi MZ     TRACE("(%p)\n", hIMC);
885692a30a8SKatayama Hirofumi MZ 
886356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
887c2c66affSColin Finck         return FALSE;
888692a30a8SKatayama Hirofumi MZ 
8891da5d7a3SKatayama Hirofumi MZ     if (Imm32IsCrossThreadAccess(hIMC))
890692a30a8SKatayama Hirofumi MZ         return FALSE;
891692a30a8SKatayama Hirofumi MZ 
892692a30a8SKatayama Hirofumi MZ     hKL = GetKeyboardLayout(0);
893692a30a8SKatayama Hirofumi MZ     return Imm32CleanupContext(hIMC, hKL, FALSE);
894c2c66affSColin Finck }
895c2c66affSColin Finck 
8961da5d7a3SKatayama Hirofumi MZ /***********************************************************************
8971da5d7a3SKatayama Hirofumi MZ  *		ImmLockClientImc (IMM32.@)
8981da5d7a3SKatayama Hirofumi MZ  */
89992393a75SKatayama Hirofumi MZ PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
90092393a75SKatayama Hirofumi MZ {
901be9a788fSKatayama Hirofumi MZ     PIMC pIMC;
90292393a75SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
90392393a75SKatayama Hirofumi MZ 
9041d9542d2SKatayama Hirofumi MZ     TRACE("(%p)\n", hImc);
90592393a75SKatayama Hirofumi MZ 
90692393a75SKatayama Hirofumi MZ     if (hImc == NULL)
90792393a75SKatayama Hirofumi MZ         return NULL;
90892393a75SKatayama Hirofumi MZ 
909be9a788fSKatayama Hirofumi MZ     pIMC = ValidateHandleNoErr(hImc, TYPE_INPUTCONTEXT);
910be9a788fSKatayama Hirofumi MZ     if (pIMC == NULL || !Imm32CheckImcProcess(pIMC))
911be9a788fSKatayama Hirofumi MZ         return NULL;
912be9a788fSKatayama Hirofumi MZ 
913be9a788fSKatayama Hirofumi MZ     pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
91492393a75SKatayama Hirofumi MZ     if (!pClientImc)
91592393a75SKatayama Hirofumi MZ     {
91646518ad6SKatayama Hirofumi MZ         pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
91792393a75SKatayama Hirofumi MZ         if (!pClientImc)
91892393a75SKatayama Hirofumi MZ             return NULL;
91992393a75SKatayama Hirofumi MZ 
92092393a75SKatayama Hirofumi MZ         RtlInitializeCriticalSection(&pClientImc->cs);
921f4bc74edSKatayama Hirofumi MZ 
92241b87158SKatayama Hirofumi MZ         pClientImc->dwCompatFlags = (DWORD)NtUserGetThreadState(THREADSTATE_IMECOMPATFLAGS);
92392393a75SKatayama Hirofumi MZ 
924ba3affe5SKatayama Hirofumi MZ         if (!NtUserUpdateInputContext(hImc, UIC_CLIENTIMCDATA, (DWORD_PTR)pClientImc))
92592393a75SKatayama Hirofumi MZ         {
92646518ad6SKatayama Hirofumi MZ             ImmLocalFree(pClientImc);
92792393a75SKatayama Hirofumi MZ             return NULL;
92892393a75SKatayama Hirofumi MZ         }
92992393a75SKatayama Hirofumi MZ 
93092393a75SKatayama Hirofumi MZ         pClientImc->dwFlags |= CLIENTIMC_UNKNOWN2;
93192393a75SKatayama Hirofumi MZ     }
93292393a75SKatayama Hirofumi MZ     else
93392393a75SKatayama Hirofumi MZ     {
9346ba810c0SKatayama Hirofumi MZ         if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
93592393a75SKatayama Hirofumi MZ             return NULL;
93692393a75SKatayama Hirofumi MZ     }
93792393a75SKatayama Hirofumi MZ 
93892393a75SKatayama Hirofumi MZ     InterlockedIncrement(&pClientImc->cLockObj);
93992393a75SKatayama Hirofumi MZ     return pClientImc;
94092393a75SKatayama Hirofumi MZ }
94192393a75SKatayama Hirofumi MZ 
9421da5d7a3SKatayama Hirofumi MZ /***********************************************************************
9431da5d7a3SKatayama Hirofumi MZ  *		ImmUnlockClientImc (IMM32.@)
9441da5d7a3SKatayama Hirofumi MZ  */
94592393a75SKatayama Hirofumi MZ VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
94692393a75SKatayama Hirofumi MZ {
94792393a75SKatayama Hirofumi MZ     LONG cLocks;
948b3382d8dSKatayama Hirofumi MZ     HANDLE hInputContext;
94992393a75SKatayama Hirofumi MZ 
9501d9542d2SKatayama Hirofumi MZ     TRACE("(%p)\n", pClientImc);
95192393a75SKatayama Hirofumi MZ 
95292393a75SKatayama Hirofumi MZ     cLocks = InterlockedDecrement(&pClientImc->cLockObj);
9536ba810c0SKatayama Hirofumi MZ     if (cLocks != 0 || !(pClientImc->dwFlags & CLIENTIMC_DESTROY))
95492393a75SKatayama Hirofumi MZ         return;
95592393a75SKatayama Hirofumi MZ 
956b3382d8dSKatayama Hirofumi MZ     hInputContext = pClientImc->hInputContext;
957b3382d8dSKatayama Hirofumi MZ     if (hInputContext)
958b3382d8dSKatayama Hirofumi MZ         LocalFree(hInputContext);
95992393a75SKatayama Hirofumi MZ 
96092393a75SKatayama Hirofumi MZ     RtlDeleteCriticalSection(&pClientImc->cs);
96146518ad6SKatayama Hirofumi MZ     ImmLocalFree(pClientImc);
96292393a75SKatayama Hirofumi MZ }
96392393a75SKatayama Hirofumi MZ 
964*720da3b9SKatayama Hirofumi MZ static HIMC APIENTRY ImmGetSaveContext(HWND hWnd, DWORD dwContextFlags)
965a8d2cd4bSKatayama Hirofumi MZ {
966a8d2cd4bSKatayama Hirofumi MZ     HIMC hIMC;
967a8d2cd4bSKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
968a8d2cd4bSKatayama Hirofumi MZ     PWND pWnd;
969a8d2cd4bSKatayama Hirofumi MZ 
970356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
971a8d2cd4bSKatayama Hirofumi MZ         return NULL;
972a8d2cd4bSKatayama Hirofumi MZ 
973a8d2cd4bSKatayama Hirofumi MZ     if (!hWnd)
974a8d2cd4bSKatayama Hirofumi MZ     {
97541b87158SKatayama Hirofumi MZ         hIMC = (HIMC)NtUserGetThreadState(THREADSTATE_DEFAULTINPUTCONTEXT);
976a8d2cd4bSKatayama Hirofumi MZ         goto Quit;
977a8d2cd4bSKatayama Hirofumi MZ     }
978a8d2cd4bSKatayama Hirofumi MZ 
979a8d2cd4bSKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
980a8d2cd4bSKatayama Hirofumi MZ     if (!pWnd || Imm32IsCrossProcessAccess(hWnd))
981a8d2cd4bSKatayama Hirofumi MZ         return NULL;
982a8d2cd4bSKatayama Hirofumi MZ 
983a8d2cd4bSKatayama Hirofumi MZ     hIMC = pWnd->hImc;
984a8d2cd4bSKatayama Hirofumi MZ     if (!hIMC && (dwContextFlags & 1))
985a8d2cd4bSKatayama Hirofumi MZ         hIMC = (HIMC)NtUserQueryWindow(hWnd, QUERY_WINDOW_DEFAULT_ICONTEXT);
986a8d2cd4bSKatayama Hirofumi MZ 
987a8d2cd4bSKatayama Hirofumi MZ Quit:
988a8d2cd4bSKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
989a8d2cd4bSKatayama Hirofumi MZ     if (pClientImc == NULL)
990a8d2cd4bSKatayama Hirofumi MZ         return NULL;
991a8d2cd4bSKatayama Hirofumi MZ     if ((dwContextFlags & 2) && (pClientImc->dwFlags & CLIENTIMC_UNKNOWN3))
992a8d2cd4bSKatayama Hirofumi MZ         hIMC = NULL;
993a8d2cd4bSKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
994a8d2cd4bSKatayama Hirofumi MZ     return hIMC;
995a8d2cd4bSKatayama Hirofumi MZ }
996a8d2cd4bSKatayama Hirofumi MZ 
997c2c66affSColin Finck /***********************************************************************
998c2c66affSColin Finck  *		ImmGetContext (IMM32.@)
999c2c66affSColin Finck  */
1000c2c66affSColin Finck HIMC WINAPI ImmGetContext(HWND hWnd)
1001c2c66affSColin Finck {
1002a8d2cd4bSKatayama Hirofumi MZ     TRACE("(%p)\n", hWnd);
1003a8d2cd4bSKatayama Hirofumi MZ     if (hWnd == NULL)
1004c2c66affSColin Finck         return NULL;
1005*720da3b9SKatayama Hirofumi MZ     return ImmGetSaveContext(hWnd, 2);
1006c2c66affSColin Finck }
1007c2c66affSColin Finck 
1008c2c66affSColin Finck /***********************************************************************
10093714ee26SKatayama Hirofumi MZ  *		CtfImmIsCiceroEnabled (IMM32.@)
10103714ee26SKatayama Hirofumi MZ  */
10113714ee26SKatayama Hirofumi MZ BOOL WINAPI CtfImmIsCiceroEnabled(VOID)
10123714ee26SKatayama Hirofumi MZ {
1013ca3fa719SKatayama Hirofumi MZ     return Imm32IsCiceroMode();
1014c2c66affSColin Finck }
1015c2c66affSColin Finck 
1016c2c66affSColin Finck /***********************************************************************
1017b4557a60SKatayama Hirofumi MZ  *		ImmLockIMC(IMM32.@)
1018b3382d8dSKatayama Hirofumi MZ  *
1019b3382d8dSKatayama Hirofumi MZ  * NOTE: This is not ImmLockIMCC. Don't confuse.
1020c2c66affSColin Finck  */
1021b4557a60SKatayama Hirofumi MZ LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
1022c2c66affSColin Finck {
1023b3382d8dSKatayama Hirofumi MZ     TRACE("(%p)\n", hIMC);
1024b3382d8dSKatayama Hirofumi MZ     return Imm32LockIMCEx(hIMC, TRUE);
1025c2c66affSColin Finck }
1026c2c66affSColin Finck 
1027b4557a60SKatayama Hirofumi MZ /***********************************************************************
1028b4557a60SKatayama Hirofumi MZ *		ImmUnlockIMC(IMM32.@)
1029b4557a60SKatayama Hirofumi MZ */
1030b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
103177911014SKatayama Hirofumi MZ {
1032b4557a60SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
1033b4557a60SKatayama Hirofumi MZ 
1034b4557a60SKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
1035b4557a60SKatayama Hirofumi MZ     if (pClientImc == NULL)
103677911014SKatayama Hirofumi MZ         return FALSE;
103777911014SKatayama Hirofumi MZ 
1038b3382d8dSKatayama Hirofumi MZ     if (pClientImc->hInputContext)
1039b3382d8dSKatayama Hirofumi MZ         LocalUnlock(pClientImc->hInputContext);
1040b4557a60SKatayama Hirofumi MZ 
1041b4557a60SKatayama Hirofumi MZ     InterlockedDecrement(&pClientImc->cLockObj);
1042b4557a60SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
104377911014SKatayama Hirofumi MZ     return TRUE;
1044c2c66affSColin Finck }
1045c2c66affSColin Finck 
1046c2c66affSColin Finck /***********************************************************************
1047b4557a60SKatayama Hirofumi MZ  *		ImmReleaseContext (IMM32.@)
1048c2c66affSColin Finck  */
1049b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1050c2c66affSColin Finck {
1051b4557a60SKatayama Hirofumi MZ     TRACE("(%p, %p)\n", hWnd, hIMC);
1052b4557a60SKatayama Hirofumi MZ     UNREFERENCED_PARAMETER(hWnd);
1053b4557a60SKatayama Hirofumi MZ     UNREFERENCED_PARAMETER(hIMC);
1054b4557a60SKatayama Hirofumi MZ     return TRUE; // Do nothing. This is correct.
1055c2c66affSColin Finck }
1056c2c66affSColin Finck 
1057c2c66affSColin Finck /***********************************************************************
1058c2c66affSColin Finck  *              ImmCreateSoftKeyboard(IMM32.@)
1059c2c66affSColin Finck  */
1060c2c66affSColin Finck HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y)
1061c2c66affSColin Finck {
1062c2c66affSColin Finck     FIXME("(%d, %d, %d, %d): stub\n", uType, hOwner, x, y);
1063c2c66affSColin Finck     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1064c2c66affSColin Finck     return 0;
1065c2c66affSColin Finck }
1066c2c66affSColin Finck 
1067c2c66affSColin Finck /***********************************************************************
1068c2c66affSColin Finck  *              ImmDestroySoftKeyboard(IMM32.@)
1069c2c66affSColin Finck  */
1070c2c66affSColin Finck BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
1071c2c66affSColin Finck {
10722705abfbSKatayama Hirofumi MZ     TRACE("(%p)\n", hSoftWnd);
10732705abfbSKatayama Hirofumi MZ     return DestroyWindow(hSoftWnd);
1074c2c66affSColin Finck }
1075c2c66affSColin Finck 
1076c2c66affSColin Finck /***********************************************************************
1077c2c66affSColin Finck  *              ImmShowSoftKeyboard(IMM32.@)
1078c2c66affSColin Finck  */
1079c2c66affSColin Finck BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
1080c2c66affSColin Finck {
10812705abfbSKatayama Hirofumi MZ     TRACE("(%p, %d)\n", hSoftWnd, nCmdShow);
10822705abfbSKatayama Hirofumi MZ     if (hSoftWnd)
10832705abfbSKatayama Hirofumi MZ         return ShowWindow(hSoftWnd, nCmdShow);
1084c2c66affSColin Finck     return FALSE;
1085c2c66affSColin Finck }
1086c2c66affSColin Finck 
1087c2c66affSColin Finck /***********************************************************************
1088b4557a60SKatayama Hirofumi MZ *		ImmDisableTextFrameService(IMM32.@)
1089c2c66affSColin Finck */
1090b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmDisableTextFrameService(DWORD dwThreadId)
1091b4557a60SKatayama Hirofumi MZ {
1092b4557a60SKatayama Hirofumi MZ     FIXME("Stub\n");
1093b4557a60SKatayama Hirofumi MZ     return FALSE;
1094b4557a60SKatayama Hirofumi MZ }
1095b4557a60SKatayama Hirofumi MZ 
1096b4557a60SKatayama Hirofumi MZ /***********************************************************************
1097b4557a60SKatayama Hirofumi MZ  *              ImmEnumInputContext(IMM32.@)
1098b4557a60SKatayama Hirofumi MZ  */
1099b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmEnumInputContext(DWORD dwThreadId, IMCENUMPROC lpfn, LPARAM lParam)
1100b4557a60SKatayama Hirofumi MZ {
1101b4557a60SKatayama Hirofumi MZ     HIMC *phList;
1102b4557a60SKatayama Hirofumi MZ     DWORD dwIndex, dwCount;
1103b4557a60SKatayama Hirofumi MZ     BOOL ret = TRUE;
1104b4557a60SKatayama Hirofumi MZ     HIMC hIMC;
1105b4557a60SKatayama Hirofumi MZ 
1106b4557a60SKatayama Hirofumi MZ     TRACE("(%lu, %p, %p)\n", dwThreadId, lpfn, lParam);
1107b4557a60SKatayama Hirofumi MZ 
1108b4557a60SKatayama Hirofumi MZ     dwCount = Imm32AllocAndBuildHimcList(dwThreadId, &phList);
1109b4557a60SKatayama Hirofumi MZ     if (!dwCount)
1110b4557a60SKatayama Hirofumi MZ         return FALSE;
1111b4557a60SKatayama Hirofumi MZ 
1112b4557a60SKatayama Hirofumi MZ     for (dwIndex = 0; dwIndex < dwCount; ++dwIndex)
1113b4557a60SKatayama Hirofumi MZ     {
1114b4557a60SKatayama Hirofumi MZ         hIMC = phList[dwIndex];
1115b4557a60SKatayama Hirofumi MZ         ret = (*lpfn)(hIMC, lParam);
1116b4557a60SKatayama Hirofumi MZ         if (!ret)
1117b4557a60SKatayama Hirofumi MZ             break;
1118b4557a60SKatayama Hirofumi MZ     }
1119b4557a60SKatayama Hirofumi MZ 
112046518ad6SKatayama Hirofumi MZ     ImmLocalFree(phList);
1121b4557a60SKatayama Hirofumi MZ     return ret;
1122b4557a60SKatayama Hirofumi MZ }
1123b4557a60SKatayama Hirofumi MZ 
1124b4557a60SKatayama Hirofumi MZ /***********************************************************************
1125b4557a60SKatayama Hirofumi MZ  *              ImmSetActiveContext(IMM32.@)
1126b4557a60SKatayama Hirofumi MZ  */
11279adc538cSKatayama Hirofumi MZ BOOL WINAPI ImmSetActiveContext(HWND hWnd, HIMC hIMC, BOOL fActive)
1128b4557a60SKatayama Hirofumi MZ {
11299adc538cSKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
11309adc538cSKatayama Hirofumi MZ     LPINPUTCONTEXTDX pIC;
11319adc538cSKatayama Hirofumi MZ     PIMEDPI pImeDpi;
11329adc538cSKatayama Hirofumi MZ     HKL hKL;
11339adc538cSKatayama Hirofumi MZ     BOOL fOpen = FALSE;
11349adc538cSKatayama Hirofumi MZ     DWORD dwConversion = 0, iShow = ISC_SHOWUIALL;
11359adc538cSKatayama Hirofumi MZ     HWND hwndDefIME;
11369adc538cSKatayama Hirofumi MZ 
11379adc538cSKatayama Hirofumi MZ     TRACE("(%p, %p, %d)\n", hWnd, hIMC, fActive);
11389adc538cSKatayama Hirofumi MZ 
1139356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1140b4557a60SKatayama Hirofumi MZ         return FALSE;
11419adc538cSKatayama Hirofumi MZ 
11429adc538cSKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
11439adc538cSKatayama Hirofumi MZ 
11449adc538cSKatayama Hirofumi MZ     if (!fActive)
11459adc538cSKatayama Hirofumi MZ     {
11469adc538cSKatayama Hirofumi MZ         if (pClientImc)
11479adc538cSKatayama Hirofumi MZ             pClientImc->dwFlags &= ~CLIENTIMC_UNKNOWN4;
11489adc538cSKatayama Hirofumi MZ     }
11499adc538cSKatayama Hirofumi MZ     else if (hIMC)
11509adc538cSKatayama Hirofumi MZ     {
11519adc538cSKatayama Hirofumi MZ         if (!pClientImc)
11529adc538cSKatayama Hirofumi MZ             return FALSE;
11539adc538cSKatayama Hirofumi MZ 
11549adc538cSKatayama Hirofumi MZ         pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
11559adc538cSKatayama Hirofumi MZ         if (!pIC)
11569adc538cSKatayama Hirofumi MZ         {
11579adc538cSKatayama Hirofumi MZ             ImmUnlockClientImc(pClientImc);
11589adc538cSKatayama Hirofumi MZ             return FALSE;
11599adc538cSKatayama Hirofumi MZ         }
11609adc538cSKatayama Hirofumi MZ 
11619adc538cSKatayama Hirofumi MZ         pIC->hWnd = hWnd;
11629adc538cSKatayama Hirofumi MZ         pClientImc->dwFlags |= CLIENTIMC_UNKNOWN5;
11639adc538cSKatayama Hirofumi MZ 
11649adc538cSKatayama Hirofumi MZ         if (pIC->dwUIFlags & 2)
11659adc538cSKatayama Hirofumi MZ             iShow = (ISC_SHOWUIGUIDELINE | ISC_SHOWUIALLCANDIDATEWINDOW);
11669adc538cSKatayama Hirofumi MZ 
11679adc538cSKatayama Hirofumi MZ         fOpen = pIC->fOpen;
11689adc538cSKatayama Hirofumi MZ         dwConversion = pIC->fdwConversion;
11699adc538cSKatayama Hirofumi MZ 
11709adc538cSKatayama Hirofumi MZ         ImmUnlockIMC(hIMC);
11719adc538cSKatayama Hirofumi MZ     }
11729adc538cSKatayama Hirofumi MZ     else
11739adc538cSKatayama Hirofumi MZ     {
1174*720da3b9SKatayama Hirofumi MZ         hIMC = ImmGetSaveContext(hWnd, 1);
11759adc538cSKatayama Hirofumi MZ         pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
11769adc538cSKatayama Hirofumi MZ         if (pIC)
11779adc538cSKatayama Hirofumi MZ         {
11789adc538cSKatayama Hirofumi MZ             pIC->hWnd = hWnd;
11799adc538cSKatayama Hirofumi MZ             ImmUnlockIMC(hIMC);
11809adc538cSKatayama Hirofumi MZ         }
11819adc538cSKatayama Hirofumi MZ         hIMC = NULL;
11829adc538cSKatayama Hirofumi MZ     }
11839adc538cSKatayama Hirofumi MZ 
11849adc538cSKatayama Hirofumi MZ     hKL = GetKeyboardLayout(0);
11859adc538cSKatayama Hirofumi MZ 
11869adc538cSKatayama Hirofumi MZ     if (Imm32IsCiceroMode() && !Imm32Is16BitMode())
11879adc538cSKatayama Hirofumi MZ     {
11889adc538cSKatayama Hirofumi MZ         Imm32CiceroSetActiveContext(hIMC, fActive, hWnd, hKL);
11899adc538cSKatayama Hirofumi MZ         hKL = GetKeyboardLayout(0);
11909adc538cSKatayama Hirofumi MZ     }
11919adc538cSKatayama Hirofumi MZ 
11929adc538cSKatayama Hirofumi MZ     pImeDpi = ImmLockImeDpi(hKL);
11939adc538cSKatayama Hirofumi MZ     if (pImeDpi)
11949adc538cSKatayama Hirofumi MZ     {
11959adc538cSKatayama Hirofumi MZ         if (IS_IME_HKL(hKL))
11969adc538cSKatayama Hirofumi MZ             pImeDpi->ImeSetActiveContext(hIMC, fActive);
11979adc538cSKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
11989adc538cSKatayama Hirofumi MZ     }
11999adc538cSKatayama Hirofumi MZ 
12009adc538cSKatayama Hirofumi MZ     if (IsWindow(hWnd))
12019adc538cSKatayama Hirofumi MZ     {
12029adc538cSKatayama Hirofumi MZ         SendMessageW(hWnd, WM_IME_SETCONTEXT, fActive, iShow);
12039adc538cSKatayama Hirofumi MZ         if (fActive)
12049adc538cSKatayama Hirofumi MZ             NtUserNotifyIMEStatus(hWnd, fOpen, dwConversion);
12059adc538cSKatayama Hirofumi MZ     }
12069adc538cSKatayama Hirofumi MZ     else if (!fActive)
12079adc538cSKatayama Hirofumi MZ     {
12089adc538cSKatayama Hirofumi MZ         hwndDefIME = ImmGetDefaultIMEWnd(NULL);
12099adc538cSKatayama Hirofumi MZ         if (hwndDefIME)
12109adc538cSKatayama Hirofumi MZ             SendMessageW(hwndDefIME, WM_IME_SETCONTEXT, 0, iShow);
12119adc538cSKatayama Hirofumi MZ     }
12129adc538cSKatayama Hirofumi MZ 
12139adc538cSKatayama Hirofumi MZ     if (pClientImc)
12149adc538cSKatayama Hirofumi MZ         ImmUnlockClientImc(pClientImc);
12159adc538cSKatayama Hirofumi MZ 
12169adc538cSKatayama Hirofumi MZ     return TRUE;
1217b4557a60SKatayama Hirofumi MZ }
1218b4557a60SKatayama Hirofumi MZ 
1219b4557a60SKatayama Hirofumi MZ /***********************************************************************
12208cdfc245SKatayama Hirofumi MZ  *              ImmWINNLSGetEnableStatus (IMM32.@)
12218cdfc245SKatayama Hirofumi MZ  */
12228cdfc245SKatayama Hirofumi MZ 
12238cdfc245SKatayama Hirofumi MZ BOOL WINAPI ImmWINNLSGetEnableStatus(HWND hWnd)
12248cdfc245SKatayama Hirofumi MZ {
12258cdfc245SKatayama Hirofumi MZ     if (!Imm32IsSystemJapaneseOrKorean())
12268cdfc245SKatayama Hirofumi MZ     {
12278cdfc245SKatayama Hirofumi MZ         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
12288cdfc245SKatayama Hirofumi MZ         return FALSE;
12298cdfc245SKatayama Hirofumi MZ     }
12308cdfc245SKatayama Hirofumi MZ 
1231*720da3b9SKatayama Hirofumi MZ     return !!ImmGetSaveContext(hWnd, 2);
12328cdfc245SKatayama Hirofumi MZ }
12338cdfc245SKatayama Hirofumi MZ 
12348cdfc245SKatayama Hirofumi MZ /***********************************************************************
1235b4557a60SKatayama Hirofumi MZ  *              ImmSetActiveContextConsoleIME(IMM32.@)
1236b4557a60SKatayama Hirofumi MZ  */
1237b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmSetActiveContextConsoleIME(HWND hwnd, BOOL fFlag)
1238c2c66affSColin Finck {
1239d7f13aa6SKatayama Hirofumi MZ     HIMC hIMC;
1240b4557a60SKatayama Hirofumi MZ     TRACE("(%p, %d)\n", hwnd, fFlag);
1241d7f13aa6SKatayama Hirofumi MZ 
1242b4557a60SKatayama Hirofumi MZ     hIMC = ImmGetContext(hwnd);
1243b4557a60SKatayama Hirofumi MZ     if (hIMC)
1244b4557a60SKatayama Hirofumi MZ         return ImmSetActiveContext(hwnd, hIMC, fFlag);
1245c2c66affSColin Finck     return FALSE;
1246c2c66affSColin Finck }
1247c2c66affSColin Finck 
1248692a30a8SKatayama Hirofumi MZ BOOL WINAPI User32InitializeImmEntryTable(DWORD);
1249692a30a8SKatayama Hirofumi MZ 
1250692a30a8SKatayama Hirofumi MZ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
1251692a30a8SKatayama Hirofumi MZ {
1252692a30a8SKatayama Hirofumi MZ     HKL hKL;
125377911014SKatayama Hirofumi MZ     HIMC hIMC;
1254692a30a8SKatayama Hirofumi MZ 
12551d9542d2SKatayama Hirofumi MZ     TRACE("(%p, 0x%X, %p)\n", hinstDLL, fdwReason, lpReserved);
1256692a30a8SKatayama Hirofumi MZ 
1257692a30a8SKatayama Hirofumi MZ     switch (fdwReason)
1258692a30a8SKatayama Hirofumi MZ     {
1259692a30a8SKatayama Hirofumi MZ         case DLL_PROCESS_ATTACH:
1260692a30a8SKatayama Hirofumi MZ             if (!Imm32InitInstance(hinstDLL))
1261692a30a8SKatayama Hirofumi MZ             {
1262692a30a8SKatayama Hirofumi MZ                 ERR("Imm32InitInstance failed\n");
1263692a30a8SKatayama Hirofumi MZ                 return FALSE;
1264692a30a8SKatayama Hirofumi MZ             }
1265692a30a8SKatayama Hirofumi MZ             if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC))
1266692a30a8SKatayama Hirofumi MZ             {
1267692a30a8SKatayama Hirofumi MZ                 ERR("User32InitializeImmEntryTable failed\n");
1268692a30a8SKatayama Hirofumi MZ                 return FALSE;
1269692a30a8SKatayama Hirofumi MZ             }
1270692a30a8SKatayama Hirofumi MZ             break;
1271692a30a8SKatayama Hirofumi MZ 
1272692a30a8SKatayama Hirofumi MZ         case DLL_THREAD_ATTACH:
1273692a30a8SKatayama Hirofumi MZ             break;
1274692a30a8SKatayama Hirofumi MZ 
1275692a30a8SKatayama Hirofumi MZ         case DLL_THREAD_DETACH:
127645a4e53fSKatayama Hirofumi MZ             if (!IS_IMM_MODE() || NtCurrentTeb()->Win32ThreadInfo == NULL)
1277692a30a8SKatayama Hirofumi MZ                 return TRUE;
1278692a30a8SKatayama Hirofumi MZ 
1279692a30a8SKatayama Hirofumi MZ             hKL = GetKeyboardLayout(0);
128041b87158SKatayama Hirofumi MZ             hIMC = (HIMC)NtUserGetThreadState(THREADSTATE_DEFAULTINPUTCONTEXT);
128177911014SKatayama Hirofumi MZ             Imm32CleanupContext(hIMC, hKL, TRUE);
1282692a30a8SKatayama Hirofumi MZ             break;
1283692a30a8SKatayama Hirofumi MZ 
1284692a30a8SKatayama Hirofumi MZ         case DLL_PROCESS_DETACH:
1285692a30a8SKatayama Hirofumi MZ             RtlDeleteCriticalSection(&g_csImeDpi);
12862ab858c1SKatayama Hirofumi MZ             TRACE("imm32.dll is unloaded\n");
1287692a30a8SKatayama Hirofumi MZ             break;
1288692a30a8SKatayama Hirofumi MZ     }
1289692a30a8SKatayama Hirofumi MZ 
1290692a30a8SKatayama Hirofumi MZ     return TRUE;
1291692a30a8SKatayama Hirofumi MZ }
1292