xref: /reactos/dll/win32/imm32/imm.c (revision dcf0788f)
1c2c66affSColin Finck /*
2f4bc74edSKatayama Hirofumi MZ  * PROJECT:     ReactOS IMM32
3f4bc74edSKatayama Hirofumi MZ  * LICENSE:     LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4f4bc74edSKatayama Hirofumi MZ  * PURPOSE:     Implementing Far-Eastern languages input
5f4bc74edSKatayama Hirofumi MZ  * COPYRIGHT:   Copyright 1998 Patrik Stridvall
6c2c66affSColin Finck  *              Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
7f4bc74edSKatayama Hirofumi MZ  *              Copyright 2017 James Tabor <james.tabor@reactos.org>
8f4bc74edSKatayama Hirofumi MZ  *              Copyright 2018 Amine Khaldi <amine.khaldi@reactos.org>
9a40f55bfSKatayama Hirofumi MZ  *              Copyright 2020-2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
10c2c66affSColin Finck  */
11c2c66affSColin Finck 
12b4557a60SKatayama Hirofumi MZ #include "precomp.h"
133d298831SKatayama Hirofumi MZ #include <ndk/exfuncs.h>
14c2c66affSColin Finck 
15c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(imm);
16c2c66affSColin Finck 
17d795021aSKatayama Hirofumi MZ HMODULE ghImm32Inst = NULL; /* The IMM32 instance */
18d795021aSKatayama Hirofumi MZ PSERVERINFO gpsi = NULL;
19d795021aSKatayama Hirofumi MZ SHAREDINFO gSharedInfo = { NULL };
20d795021aSKatayama Hirofumi MZ BYTE gfImmInitialized = FALSE; /* Is IMM32 initialized? */
213d298831SKatayama Hirofumi MZ ULONG_PTR gHighestUserAddress = 0;
22a8d2cd4bSKatayama Hirofumi MZ 
ImmInitializeGlobals(HMODULE hMod)23a40f55bfSKatayama Hirofumi MZ static BOOL APIENTRY ImmInitializeGlobals(HMODULE hMod)
24692a30a8SKatayama Hirofumi MZ {
25692a30a8SKatayama Hirofumi MZ     NTSTATUS status;
263d298831SKatayama Hirofumi MZ     SYSTEM_BASIC_INFORMATION SysInfo;
27692a30a8SKatayama Hirofumi MZ 
28692a30a8SKatayama Hirofumi MZ     if (hMod)
29bc8a4ac3SKatayama Hirofumi MZ         ghImm32Inst = hMod;
30692a30a8SKatayama Hirofumi MZ 
31bc8a4ac3SKatayama Hirofumi MZ     if (gfImmInitialized)
32692a30a8SKatayama Hirofumi MZ         return TRUE;
33692a30a8SKatayama Hirofumi MZ 
34895909e6SKatayama Hirofumi MZ     status = RtlInitializeCriticalSection(&gcsImeDpi);
35692a30a8SKatayama Hirofumi MZ     if (NT_ERROR(status))
36c2a94365SKatayama Hirofumi MZ     {
37c2a94365SKatayama Hirofumi MZ         ERR("\n");
38692a30a8SKatayama Hirofumi MZ         return FALSE;
39c2a94365SKatayama Hirofumi MZ     }
40692a30a8SKatayama Hirofumi MZ 
413d298831SKatayama Hirofumi MZ     status = NtQuerySystemInformation(SystemBasicInformation, &SysInfo, sizeof(SysInfo), NULL);
423d298831SKatayama Hirofumi MZ     if (NT_ERROR(status))
433d298831SKatayama Hirofumi MZ     {
443d298831SKatayama Hirofumi MZ         ERR("\n");
453d298831SKatayama Hirofumi MZ         return FALSE;
463d298831SKatayama Hirofumi MZ     }
473d298831SKatayama Hirofumi MZ     gHighestUserAddress = SysInfo.MaximumUserModeAddress;
483d298831SKatayama Hirofumi MZ 
49bc8a4ac3SKatayama Hirofumi MZ     gfImmInitialized = TRUE;
50692a30a8SKatayama Hirofumi MZ     return TRUE;
51692a30a8SKatayama Hirofumi MZ }
52692a30a8SKatayama Hirofumi MZ 
531da5d7a3SKatayama Hirofumi MZ /***********************************************************************
54b4557a60SKatayama Hirofumi MZ  *		ImmRegisterClient(IMM32.@)
55b4557a60SKatayama Hirofumi MZ  *       ( Undocumented, called from user32.dll )
561da5d7a3SKatayama Hirofumi MZ  */
ImmRegisterClient(PSHAREDINFO ptr,HINSTANCE hMod)57b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmRegisterClient(PSHAREDINFO ptr, HINSTANCE hMod)
58692a30a8SKatayama Hirofumi MZ {
596dfe0321SKatayama Hirofumi MZ     gSharedInfo = *ptr;
606dfe0321SKatayama Hirofumi MZ     gpsi = gSharedInfo.psi;
61a40f55bfSKatayama Hirofumi MZ     return ImmInitializeGlobals(hMod);
621e62771cSKatayama Hirofumi MZ }
631e62771cSKatayama Hirofumi MZ 
641da5d7a3SKatayama Hirofumi MZ /***********************************************************************
651da5d7a3SKatayama Hirofumi MZ  *		ImmLoadLayout (IMM32.@)
661da5d7a3SKatayama Hirofumi MZ  */
ImmLoadLayout(HKL hKL,PIMEINFOEX pImeInfoEx)67a37d9a4eSKatayama Hirofumi MZ BOOL WINAPI ImmLoadLayout(HKL hKL, PIMEINFOEX pImeInfoEx)
688e1dea0cSKatayama Hirofumi MZ {
6985e292d5SKatayama Hirofumi MZ     DWORD cbData, dwType;
70b7dcc102SKatayama Hirofumi MZ     HKEY hKey;
71b7dcc102SKatayama Hirofumi MZ     LSTATUS error;
728e1dea0cSKatayama Hirofumi MZ     WCHAR szLayout[MAX_PATH];
73b7dcc102SKatayama Hirofumi MZ     LPCWSTR pszSubKey;
748e1dea0cSKatayama Hirofumi MZ 
751d9542d2SKatayama Hirofumi MZ     TRACE("(%p, %p)\n", hKL, pImeInfoEx);
768e1dea0cSKatayama Hirofumi MZ 
77b7dcc102SKatayama Hirofumi MZ     /* Choose a key */
78b7dcc102SKatayama Hirofumi MZ     if (IS_IME_HKL(hKL) || !IS_CICERO_MODE() || IS_16BIT_MODE()) /* Non-Cicero? */
798e1dea0cSKatayama Hirofumi MZ     {
8085e292d5SKatayama Hirofumi MZ         StringCchPrintfW(szLayout, _countof(szLayout), L"%s\\%08lX",
8185e292d5SKatayama Hirofumi MZ                          REGKEY_KEYBOARD_LAYOUTS, HandleToUlong(hKL));
82b7dcc102SKatayama Hirofumi MZ         pszSubKey = szLayout;
83a37d9a4eSKatayama Hirofumi MZ     }
84b7dcc102SKatayama Hirofumi MZ     else /* Cicero */
858e1dea0cSKatayama Hirofumi MZ     {
86b7dcc102SKatayama Hirofumi MZ         pszSubKey = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\IMM";
878e1dea0cSKatayama Hirofumi MZ     }
88a37d9a4eSKatayama Hirofumi MZ 
89b7dcc102SKatayama Hirofumi MZ     /* Open the key */
90b7dcc102SKatayama Hirofumi MZ     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, pszSubKey, 0, KEY_READ, &hKey);
91b7dcc102SKatayama Hirofumi MZ     if (IS_ERROR_UNEXPECTEDLY(error))
92b7dcc102SKatayama Hirofumi MZ         return FALSE;
93b7dcc102SKatayama Hirofumi MZ 
94b7dcc102SKatayama Hirofumi MZ     /* Load "IME File" value */
958e1dea0cSKatayama Hirofumi MZ     cbData = sizeof(pImeInfoEx->wszImeFile);
96b7dcc102SKatayama Hirofumi MZ     error = RegQueryValueExW(hKey, L"IME File", NULL, &dwType,
978e1dea0cSKatayama Hirofumi MZ                              (LPBYTE)pImeInfoEx->wszImeFile, &cbData);
98b7dcc102SKatayama Hirofumi MZ 
99b7dcc102SKatayama Hirofumi MZ     /* Avoid buffer overrun */
10085e292d5SKatayama Hirofumi MZ     pImeInfoEx->wszImeFile[_countof(pImeInfoEx->wszImeFile) - 1] = UNICODE_NULL;
1018e1dea0cSKatayama Hirofumi MZ 
102b7dcc102SKatayama Hirofumi MZ     RegCloseKey(hKey);
103a37d9a4eSKatayama Hirofumi MZ 
104b7dcc102SKatayama Hirofumi MZ     if (error != ERROR_SUCCESS || dwType != REG_SZ)
105b7dcc102SKatayama Hirofumi MZ         return FALSE; /* Failed */
106a37d9a4eSKatayama Hirofumi MZ 
107a37d9a4eSKatayama Hirofumi MZ     pImeInfoEx->hkl = hKL;
108b7dcc102SKatayama Hirofumi MZ     pImeInfoEx->fLoadFlag = 0;
109a37d9a4eSKatayama Hirofumi MZ     return Imm32LoadImeVerInfo(pImeInfoEx);
1108e1dea0cSKatayama Hirofumi MZ }
1118e1dea0cSKatayama Hirofumi MZ 
112e6a51b54SKatayama Hirofumi MZ /***********************************************************************
113e6a51b54SKatayama Hirofumi MZ  *		ImmFreeLayout (IMM32.@)
114*dcf0788fSKatayama Hirofumi MZ  *
115*dcf0788fSKatayama Hirofumi MZ  * NOTE: HKL_SWITCH_TO_NON_IME and HKL_RELEASE_IME are special values for hKL.
116e6a51b54SKatayama Hirofumi MZ  */
ImmFreeLayout(HKL hKL)117*dcf0788fSKatayama Hirofumi MZ BOOL WINAPI ImmFreeLayout(HKL hKL)
118e6a51b54SKatayama Hirofumi MZ {
11985e292d5SKatayama Hirofumi MZ     WCHAR szKBD[KL_NAMELENGTH];
120e6a51b54SKatayama Hirofumi MZ     UINT iKL, cKLs;
121*dcf0788fSKatayama Hirofumi MZ     HKL hOldKL, *pList;
122e6a51b54SKatayama Hirofumi MZ     PIMEDPI pImeDpi;
123e6a51b54SKatayama Hirofumi MZ     LANGID LangID;
124e6a51b54SKatayama Hirofumi MZ 
125*dcf0788fSKatayama Hirofumi MZ     TRACE("(%p)\n", hKL);
126e6a51b54SKatayama Hirofumi MZ 
127e6a51b54SKatayama Hirofumi MZ     hOldKL = GetKeyboardLayout(0);
128e6a51b54SKatayama Hirofumi MZ 
129*dcf0788fSKatayama Hirofumi MZ     if (hKL == HKL_SWITCH_TO_NON_IME)
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));
140c2a94365SKatayama Hirofumi MZ             if (IS_NULL_UNEXPECTEDLY(pList))
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))
158c2a94365SKatayama Hirofumi MZ         {
159e1df4f2dSKatayama Hirofumi MZ             WARN("Default to English US\n");
160e6a51b54SKatayama Hirofumi MZ             LoadKeyboardLayoutW(L"00000409", KLF_ACTIVATE | 0x200);
161e6a51b54SKatayama Hirofumi MZ         }
162c2a94365SKatayama Hirofumi MZ     }
163*dcf0788fSKatayama Hirofumi MZ     else if (hKL == HKL_RELEASE_IME)
164e6a51b54SKatayama Hirofumi MZ     {
165895909e6SKatayama Hirofumi MZ         RtlEnterCriticalSection(&gcsImeDpi);
166e6a51b54SKatayama Hirofumi MZ Retry:
1673c169714SKatayama Hirofumi MZ         for (pImeDpi = gpImeDpiList; pImeDpi; pImeDpi = pImeDpi->pNext)
168e6a51b54SKatayama Hirofumi MZ         {
169e6a51b54SKatayama Hirofumi MZ             if (Imm32ReleaseIME(pImeDpi->hKL))
170e6a51b54SKatayama Hirofumi MZ                 goto Retry;
171e6a51b54SKatayama Hirofumi MZ         }
172895909e6SKatayama Hirofumi MZ         RtlLeaveCriticalSection(&gcsImeDpi);
173e6a51b54SKatayama Hirofumi MZ     }
174e6a51b54SKatayama Hirofumi MZ     else
175e6a51b54SKatayama Hirofumi MZ     {
176*dcf0788fSKatayama Hirofumi MZ         if (IS_IME_HKL(hKL) && hKL != hOldKL)
177*dcf0788fSKatayama Hirofumi MZ             Imm32ReleaseIME(hKL);
178e6a51b54SKatayama Hirofumi MZ     }
179e6a51b54SKatayama Hirofumi MZ 
180e6a51b54SKatayama Hirofumi MZ     return TRUE;
181e6a51b54SKatayama Hirofumi MZ }
182e6a51b54SKatayama Hirofumi MZ 
Imm32SelectInputContext(HKL hNewKL,HKL hOldKL,HIMC hIMC)183bc8a4ac3SKatayama Hirofumi MZ VOID APIENTRY Imm32SelectInputContext(HKL hNewKL, HKL hOldKL, HIMC hIMC)
18466ef3149SKatayama Hirofumi MZ {
18566ef3149SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
18666ef3149SKatayama Hirofumi MZ     LPINPUTCONTEXTDX pIC;
18766ef3149SKatayama Hirofumi MZ     LPGUIDELINE pGL;
18866ef3149SKatayama Hirofumi MZ     LPCANDIDATEINFO pCI;
18966ef3149SKatayama Hirofumi MZ     LPCOMPOSITIONSTRING pCS;
19066ef3149SKatayama Hirofumi MZ     LOGFONTA LogFontA;
19166ef3149SKatayama Hirofumi MZ     LOGFONTW LogFontW;
192b086f910SKatayama Hirofumi MZ     BOOL fOldOpen, bIsNewHKLIme = TRUE, bIsOldHKLIme = TRUE, bClientWide, bNewDpiWide;
193b086f910SKatayama Hirofumi MZ     DWORD cbNewPrivate = 0, cbOldPrivate = 0, dwOldConversion, dwOldSentence, dwSize, dwNewSize;
19466ef3149SKatayama Hirofumi MZ     PIMEDPI pNewImeDpi = NULL, pOldImeDpi = NULL;
19566ef3149SKatayama Hirofumi MZ     HANDLE hPrivate;
19666ef3149SKatayama Hirofumi MZ     PIME_STATE pNewState = NULL, pOldState = NULL;
19766ef3149SKatayama Hirofumi MZ 
19866ef3149SKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
199c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pClientImc))
20066ef3149SKatayama Hirofumi MZ         return;
20166ef3149SKatayama Hirofumi MZ 
20266ef3149SKatayama Hirofumi MZ     pNewImeDpi = ImmLockImeDpi(hNewKL);
20366ef3149SKatayama Hirofumi MZ 
20466ef3149SKatayama Hirofumi MZ     if (hNewKL != hOldKL)
20566ef3149SKatayama Hirofumi MZ         pOldImeDpi = ImmLockImeDpi(hOldKL);
20666ef3149SKatayama Hirofumi MZ 
20766ef3149SKatayama Hirofumi MZ     if (pNewImeDpi)
20866ef3149SKatayama Hirofumi MZ     {
20966ef3149SKatayama Hirofumi MZ         cbNewPrivate = pNewImeDpi->ImeInfo.dwPrivateDataSize;
21066ef3149SKatayama Hirofumi MZ         pClientImc->uCodePage = pNewImeDpi->uCodePage;
21166ef3149SKatayama Hirofumi MZ     }
21266ef3149SKatayama Hirofumi MZ     else
21366ef3149SKatayama Hirofumi MZ     {
21466ef3149SKatayama Hirofumi MZ         pClientImc->uCodePage = CP_ACP;
21566ef3149SKatayama Hirofumi MZ     }
21666ef3149SKatayama Hirofumi MZ 
21766ef3149SKatayama Hirofumi MZ     if (pOldImeDpi)
21866ef3149SKatayama Hirofumi MZ         cbOldPrivate = pOldImeDpi->ImeInfo.dwPrivateDataSize;
21966ef3149SKatayama Hirofumi MZ 
220b086f910SKatayama Hirofumi MZ     cbNewPrivate = max(cbNewPrivate, sizeof(DWORD));
221b086f910SKatayama Hirofumi MZ     cbOldPrivate = max(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);
229020d7d58SKatayama Hirofumi MZ             else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
23066ef3149SKatayama Hirofumi MZ                 pOldImeDpi->CtfImeSelectEx(hIMC, FALSE, hOldKL);
23166ef3149SKatayama Hirofumi MZ         }
23266ef3149SKatayama Hirofumi MZ         pClientImc->hKL = NULL;
23366ef3149SKatayama Hirofumi MZ     }
23466ef3149SKatayama Hirofumi MZ 
235b086f910SKatayama Hirofumi MZ     if (CtfImmIsTextFrameServiceDisabled() && IS_CICERO_MODE() && !IS_16BIT_MODE())
23666ef3149SKatayama Hirofumi MZ     {
23766ef3149SKatayama Hirofumi MZ         bIsNewHKLIme = IS_IME_HKL(hNewKL);
23866ef3149SKatayama Hirofumi MZ         bIsOldHKLIme = IS_IME_HKL(hOldKL);
23966ef3149SKatayama Hirofumi MZ     }
24066ef3149SKatayama Hirofumi MZ 
2418de74398SKatayama Hirofumi MZ     pIC = (LPINPUTCONTEXTDX)Imm32InternalLockIMC(hIMC, FALSE);
24266ef3149SKatayama Hirofumi MZ     if (!pIC)
24366ef3149SKatayama Hirofumi MZ     {
24466ef3149SKatayama Hirofumi MZ         if (pNewImeDpi)
24566ef3149SKatayama Hirofumi MZ         {
24666ef3149SKatayama Hirofumi MZ             if (IS_IME_HKL(hNewKL))
24766ef3149SKatayama Hirofumi MZ                 pNewImeDpi->ImeSelect(hIMC, TRUE);
248020d7d58SKatayama Hirofumi MZ             else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
24966ef3149SKatayama Hirofumi MZ                 pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
25066ef3149SKatayama Hirofumi MZ 
25166ef3149SKatayama Hirofumi MZ             pClientImc->hKL = hNewKL;
25266ef3149SKatayama Hirofumi MZ         }
25366ef3149SKatayama Hirofumi MZ     }
25466ef3149SKatayama Hirofumi MZ     else
25566ef3149SKatayama Hirofumi MZ     {
256b086f910SKatayama Hirofumi MZ         dwOldConversion = pIC->fdwConversion;
257b086f910SKatayama Hirofumi MZ         dwOldSentence = pIC->fdwSentence;
258b086f910SKatayama Hirofumi MZ         fOldOpen = pIC->fOpen;
25966ef3149SKatayama Hirofumi MZ 
26066ef3149SKatayama Hirofumi MZ         if (pNewImeDpi)
26166ef3149SKatayama Hirofumi MZ         {
26266ef3149SKatayama Hirofumi MZ             bClientWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
26366ef3149SKatayama Hirofumi MZ             bNewDpiWide = ImeDpi_IsUnicode(pNewImeDpi);
26466ef3149SKatayama Hirofumi MZ             if (bClientWide && !bNewDpiWide)
26566ef3149SKatayama Hirofumi MZ             {
26666ef3149SKatayama Hirofumi MZ                 if (pIC->fdwInit & INIT_LOGFONT)
26766ef3149SKatayama Hirofumi MZ                 {
26866ef3149SKatayama Hirofumi MZ                     LogFontWideToAnsi(&pIC->lfFont.W, &LogFontA);
26966ef3149SKatayama Hirofumi MZ                     pIC->lfFont.A = LogFontA;
27066ef3149SKatayama Hirofumi MZ                 }
27166ef3149SKatayama Hirofumi MZ                 pClientImc->dwFlags &= ~CLIENTIMC_WIDE;
27266ef3149SKatayama Hirofumi MZ             }
27366ef3149SKatayama Hirofumi MZ             else if (!bClientWide && bNewDpiWide)
27466ef3149SKatayama Hirofumi MZ             {
27566ef3149SKatayama Hirofumi MZ                 if (pIC->fdwInit & INIT_LOGFONT)
27666ef3149SKatayama Hirofumi MZ                 {
27766ef3149SKatayama Hirofumi MZ                     LogFontAnsiToWide(&pIC->lfFont.A, &LogFontW);
27866ef3149SKatayama Hirofumi MZ                     pIC->lfFont.W = LogFontW;
27966ef3149SKatayama Hirofumi MZ                 }
28066ef3149SKatayama Hirofumi MZ                 pClientImc->dwFlags |= CLIENTIMC_WIDE;
28166ef3149SKatayama Hirofumi MZ             }
28266ef3149SKatayama Hirofumi MZ         }
28366ef3149SKatayama Hirofumi MZ 
28466ef3149SKatayama Hirofumi MZ         if (cbOldPrivate != cbNewPrivate)
28566ef3149SKatayama Hirofumi MZ         {
28666ef3149SKatayama Hirofumi MZ             hPrivate = ImmReSizeIMCC(pIC->hPrivate, cbNewPrivate);
28766ef3149SKatayama Hirofumi MZ             if (!hPrivate)
28866ef3149SKatayama Hirofumi MZ             {
28966ef3149SKatayama Hirofumi MZ                 ImmDestroyIMCC(pIC->hPrivate);
29066ef3149SKatayama Hirofumi MZ                 hPrivate = ImmCreateIMCC(cbNewPrivate);
29166ef3149SKatayama Hirofumi MZ             }
29266ef3149SKatayama Hirofumi MZ             pIC->hPrivate = hPrivate;
29366ef3149SKatayama Hirofumi MZ         }
29466ef3149SKatayama Hirofumi MZ 
29566ef3149SKatayama Hirofumi MZ #define MAX_IMCC_SIZE 0x1000
29666ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hMsgBuf);
29766ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hMsgBuf) || dwSize > MAX_IMCC_SIZE)
29866ef3149SKatayama Hirofumi MZ         {
29966ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hMsgBuf);
30066ef3149SKatayama Hirofumi MZ             pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
30166ef3149SKatayama Hirofumi MZ             pIC->dwNumMsgBuf = 0;
30266ef3149SKatayama Hirofumi MZ         }
30366ef3149SKatayama Hirofumi MZ 
30466ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hGuideLine);
30566ef3149SKatayama Hirofumi MZ         dwNewSize = sizeof(GUIDELINE);
30666ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hGuideLine) ||
30766ef3149SKatayama Hirofumi MZ             dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
30866ef3149SKatayama Hirofumi MZ         {
30966ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hGuideLine);
31066ef3149SKatayama Hirofumi MZ             pIC->hGuideLine = ImmCreateIMCC(dwNewSize);
31166ef3149SKatayama Hirofumi MZ             pGL = ImmLockIMCC(pIC->hGuideLine);
31266ef3149SKatayama Hirofumi MZ             if (pGL)
31366ef3149SKatayama Hirofumi MZ             {
31466ef3149SKatayama Hirofumi MZ                 pGL->dwSize = dwNewSize;
31566ef3149SKatayama Hirofumi MZ                 ImmUnlockIMCC(pIC->hGuideLine);
31666ef3149SKatayama Hirofumi MZ             }
31766ef3149SKatayama Hirofumi MZ         }
31866ef3149SKatayama Hirofumi MZ 
31966ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hCandInfo);
32066ef3149SKatayama Hirofumi MZ         dwNewSize = sizeof(CANDIDATEINFO);
32166ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hCandInfo) ||
32266ef3149SKatayama Hirofumi MZ             dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
32366ef3149SKatayama Hirofumi MZ         {
32466ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hCandInfo);
32566ef3149SKatayama Hirofumi MZ             pIC->hCandInfo = ImmCreateIMCC(dwNewSize);
32666ef3149SKatayama Hirofumi MZ             pCI = ImmLockIMCC(pIC->hCandInfo);
32766ef3149SKatayama Hirofumi MZ             if (pCI)
32866ef3149SKatayama Hirofumi MZ             {
32966ef3149SKatayama Hirofumi MZ                 pCI->dwSize = dwNewSize;
33066ef3149SKatayama Hirofumi MZ                 ImmUnlockIMCC(pIC->hCandInfo);
33166ef3149SKatayama Hirofumi MZ             }
33266ef3149SKatayama Hirofumi MZ         }
33366ef3149SKatayama Hirofumi MZ 
33466ef3149SKatayama Hirofumi MZ         dwSize = ImmGetIMCCSize(pIC->hCompStr);
33566ef3149SKatayama Hirofumi MZ         dwNewSize = sizeof(COMPOSITIONSTRING);
33666ef3149SKatayama Hirofumi MZ         if (ImmGetIMCCLockCount(pIC->hCompStr) ||
33766ef3149SKatayama Hirofumi MZ             dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
33866ef3149SKatayama Hirofumi MZ         {
33966ef3149SKatayama Hirofumi MZ             ImmDestroyIMCC(pIC->hCompStr);
34066ef3149SKatayama Hirofumi MZ             pIC->hCompStr = ImmCreateIMCC(dwNewSize);
34166ef3149SKatayama Hirofumi MZ             pCS = ImmLockIMCC(pIC->hCompStr);
34266ef3149SKatayama Hirofumi MZ             if (pCS)
34366ef3149SKatayama Hirofumi MZ             {
34466ef3149SKatayama Hirofumi MZ                 pCS->dwSize = dwNewSize;
34566ef3149SKatayama Hirofumi MZ                 ImmUnlockIMCC(pIC->hCompStr);
34666ef3149SKatayama Hirofumi MZ             }
34766ef3149SKatayama Hirofumi MZ         }
34866ef3149SKatayama Hirofumi MZ #undef MAX_IMCC_SIZE
34966ef3149SKatayama Hirofumi MZ 
35066ef3149SKatayama Hirofumi MZ         if (pOldImeDpi && bIsOldHKLIme)
35166ef3149SKatayama Hirofumi MZ         {
35266ef3149SKatayama Hirofumi MZ             pOldState = Imm32FetchImeState(pIC, hOldKL);
35366ef3149SKatayama Hirofumi MZ             if (pOldState)
35466ef3149SKatayama Hirofumi MZ                 Imm32SaveImeStateSentence(pIC, pOldState, hOldKL);
35566ef3149SKatayama Hirofumi MZ         }
35666ef3149SKatayama Hirofumi MZ 
35766ef3149SKatayama Hirofumi MZ         if (pNewImeDpi && bIsNewHKLIme)
35866ef3149SKatayama Hirofumi MZ             pNewState = Imm32FetchImeState(pIC, hNewKL);
35966ef3149SKatayama Hirofumi MZ 
36066ef3149SKatayama Hirofumi MZ         if (pOldState != pNewState)
36166ef3149SKatayama Hirofumi MZ         {
36266ef3149SKatayama Hirofumi MZ             if (pOldState)
36366ef3149SKatayama Hirofumi MZ             {
36466ef3149SKatayama Hirofumi MZ                 pOldState->fOpen = !!pIC->fOpen;
365b086f910SKatayama Hirofumi MZ                 pOldState->dwConversion = pIC->fdwConversion;
366b086f910SKatayama Hirofumi MZ                 pOldState->dwConversion &= ~IME_CMODE_EUDC;
36766ef3149SKatayama Hirofumi MZ                 pOldState->dwSentence = pIC->fdwSentence;
36866ef3149SKatayama Hirofumi MZ                 pOldState->dwInit = pIC->fdwInit;
36966ef3149SKatayama Hirofumi MZ             }
37066ef3149SKatayama Hirofumi MZ 
37166ef3149SKatayama Hirofumi MZ             if (pNewState)
37266ef3149SKatayama Hirofumi MZ             {
37366ef3149SKatayama Hirofumi MZ                 if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_FORCE_OPEN)
37466ef3149SKatayama Hirofumi MZ                 {
37566ef3149SKatayama Hirofumi MZ                     pIC->dwChange &= ~INPUTCONTEXTDX_CHANGE_FORCE_OPEN;
37666ef3149SKatayama Hirofumi MZ                     pIC->fOpen = TRUE;
37766ef3149SKatayama Hirofumi MZ                 }
37866ef3149SKatayama Hirofumi MZ                 else
37966ef3149SKatayama Hirofumi MZ                 {
38066ef3149SKatayama Hirofumi MZ                     pIC->fOpen = pNewState->fOpen;
38166ef3149SKatayama Hirofumi MZ                 }
38266ef3149SKatayama Hirofumi MZ 
383b086f910SKatayama Hirofumi MZ                 pIC->fdwConversion = pNewState->dwConversion;
384b086f910SKatayama Hirofumi MZ                 pIC->fdwConversion &= ~IME_CMODE_EUDC;
38566ef3149SKatayama Hirofumi MZ                 pIC->fdwSentence = pNewState->dwSentence;
38666ef3149SKatayama Hirofumi MZ                 pIC->fdwInit = pNewState->dwInit;
38766ef3149SKatayama Hirofumi MZ             }
38866ef3149SKatayama Hirofumi MZ         }
38966ef3149SKatayama Hirofumi MZ 
39066ef3149SKatayama Hirofumi MZ         if (pNewState)
39166ef3149SKatayama Hirofumi MZ             Imm32LoadImeStateSentence(pIC, pNewState, hNewKL);
39266ef3149SKatayama Hirofumi MZ 
39366ef3149SKatayama Hirofumi MZ         if (pNewImeDpi)
39466ef3149SKatayama Hirofumi MZ         {
39566ef3149SKatayama Hirofumi MZ             if (IS_IME_HKL(hNewKL))
39666ef3149SKatayama Hirofumi MZ                 pNewImeDpi->ImeSelect(hIMC, TRUE);
397020d7d58SKatayama Hirofumi MZ             else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
39866ef3149SKatayama Hirofumi MZ                 pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
39966ef3149SKatayama Hirofumi MZ 
40066ef3149SKatayama Hirofumi MZ             pClientImc->hKL = hNewKL;
40166ef3149SKatayama Hirofumi MZ         }
40266ef3149SKatayama Hirofumi MZ 
40366ef3149SKatayama Hirofumi MZ         pIC->dwChange = 0;
404b086f910SKatayama Hirofumi MZ         if (pIC->fOpen != fOldOpen)
40566ef3149SKatayama Hirofumi MZ             pIC->dwChange |= INPUTCONTEXTDX_CHANGE_OPEN;
406b086f910SKatayama Hirofumi MZ         if (pIC->fdwConversion != dwOldConversion)
40766ef3149SKatayama Hirofumi MZ             pIC->dwChange |= INPUTCONTEXTDX_CHANGE_CONVERSION;
408b086f910SKatayama Hirofumi MZ         if (pIC->fdwSentence != dwOldSentence)
40966ef3149SKatayama Hirofumi MZ             pIC->dwChange |= INPUTCONTEXTDX_CHANGE_SENTENCE;
41066ef3149SKatayama Hirofumi MZ 
41166ef3149SKatayama Hirofumi MZ         ImmUnlockIMC(hIMC);
41266ef3149SKatayama Hirofumi MZ     }
41366ef3149SKatayama Hirofumi MZ 
41466ef3149SKatayama Hirofumi MZ     ImmUnlockImeDpi(pOldImeDpi);
41566ef3149SKatayama Hirofumi MZ     ImmUnlockImeDpi(pNewImeDpi);
41666ef3149SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
41766ef3149SKatayama Hirofumi MZ }
41866ef3149SKatayama Hirofumi MZ 
41966ef3149SKatayama Hirofumi MZ typedef struct SELECT_LAYOUT
42066ef3149SKatayama Hirofumi MZ {
42166ef3149SKatayama Hirofumi MZ     HKL hNewKL;
42266ef3149SKatayama Hirofumi MZ     HKL hOldKL;
42366ef3149SKatayama Hirofumi MZ } SELECT_LAYOUT, *LPSELECT_LAYOUT;
42466ef3149SKatayama Hirofumi MZ 
425bc8a4ac3SKatayama Hirofumi MZ // Win: SelectContextProc
Imm32SelectContextProc(HIMC hIMC,LPARAM lParam)426bc8a4ac3SKatayama Hirofumi MZ static BOOL CALLBACK Imm32SelectContextProc(HIMC hIMC, LPARAM lParam)
42766ef3149SKatayama Hirofumi MZ {
42866ef3149SKatayama Hirofumi MZ     LPSELECT_LAYOUT pSelect = (LPSELECT_LAYOUT)lParam;
429bc8a4ac3SKatayama Hirofumi MZ     Imm32SelectInputContext(pSelect->hNewKL, pSelect->hOldKL, hIMC);
43066ef3149SKatayama Hirofumi MZ     return TRUE;
43166ef3149SKatayama Hirofumi MZ }
43266ef3149SKatayama Hirofumi MZ 
433bc8a4ac3SKatayama Hirofumi MZ // Win: NotifyIMEProc
Imm32NotifyIMEProc(HIMC hIMC,LPARAM lParam)434bc8a4ac3SKatayama Hirofumi MZ static BOOL CALLBACK Imm32NotifyIMEProc(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  */
ImmActivateLayout(HKL hKL)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 
469bc8a4ac3SKatayama Hirofumi MZ             ImmEnumInputContext(0, Imm32NotifyIMEProc, 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;
481bc8a4ac3SKatayama Hirofumi MZ     ImmEnumInputContext(0, Imm32SelectContextProc, (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 
489c2c66affSColin Finck /***********************************************************************
490c2c66affSColin Finck  *		ImmAssociateContext (IMM32.@)
491c2c66affSColin Finck  */
ImmAssociateContext(HWND hWnd,HIMC hIMC)492c2c66affSColin Finck HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
493c2c66affSColin Finck {
494ef003fa4SKatayama Hirofumi MZ     PWND pWnd;
495ef003fa4SKatayama Hirofumi MZ     HWND hwndFocus;
496ef003fa4SKatayama Hirofumi MZ     DWORD dwValue;
497ef003fa4SKatayama Hirofumi MZ     HIMC hOldIMC;
498c2c66affSColin Finck 
499ef003fa4SKatayama Hirofumi MZ     TRACE("(%p, %p)\n", hWnd, hIMC);
500c2c66affSColin Finck 
501356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
502c2a94365SKatayama Hirofumi MZ     {
503e1df4f2dSKatayama Hirofumi MZ         TRACE("\n");
504c2c66affSColin Finck         return NULL;
505c2a94365SKatayama Hirofumi MZ     }
506c2c66affSColin Finck 
507b0b925d2SKatayama Hirofumi MZ     pWnd = ValidateHwnd(hWnd);
508c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pWnd))
509ef003fa4SKatayama Hirofumi MZ         return NULL;
510ef003fa4SKatayama Hirofumi MZ 
511c2a94365SKatayama Hirofumi MZ     if (hIMC && IS_CROSS_THREAD_HIMC(hIMC))
512ef003fa4SKatayama Hirofumi MZ         return NULL;
513ef003fa4SKatayama Hirofumi MZ 
514ef003fa4SKatayama Hirofumi MZ     hOldIMC = pWnd->hImc;
515ef003fa4SKatayama Hirofumi MZ     if (hOldIMC == hIMC)
516c2c66affSColin Finck         return hIMC;
517c2c66affSColin Finck 
518ef003fa4SKatayama Hirofumi MZ     dwValue = NtUserAssociateInputContext(hWnd, hIMC, 0);
51972c56c2fSKatayama Hirofumi MZ     switch (dwValue)
52072c56c2fSKatayama Hirofumi MZ     {
52172c56c2fSKatayama Hirofumi MZ         case 0:
522ef003fa4SKatayama Hirofumi MZ             return hOldIMC;
523c45a6e15SJames Tabor 
52472c56c2fSKatayama Hirofumi MZ         case 1:
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             }
531ef003fa4SKatayama Hirofumi MZ             return hOldIMC;
53272c56c2fSKatayama Hirofumi MZ 
53372c56c2fSKatayama Hirofumi MZ         default:
53472c56c2fSKatayama Hirofumi MZ             return NULL;
53572c56c2fSKatayama Hirofumi MZ     }
536c2c66affSColin Finck }
537c2c66affSColin Finck 
538c2c66affSColin Finck /***********************************************************************
539c2c66affSColin Finck  *              ImmAssociateContextEx (IMM32.@)
540c2c66affSColin Finck  */
ImmAssociateContextEx(HWND hWnd,HIMC hIMC,DWORD dwFlags)541c2c66affSColin Finck BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
542c2c66affSColin Finck {
543df6fff78SKatayama Hirofumi MZ     HWND hwndFocus;
544df6fff78SKatayama Hirofumi MZ     PWND pFocusWnd;
545df6fff78SKatayama Hirofumi MZ     HIMC hOldIMC = NULL;
546df6fff78SKatayama Hirofumi MZ     DWORD dwValue;
547c2c66affSColin Finck 
548df6fff78SKatayama Hirofumi MZ     TRACE("(%p, %p, 0x%lX)\n", hWnd, hIMC, dwFlags);
549df6fff78SKatayama Hirofumi MZ 
550356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
551c2a94365SKatayama Hirofumi MZ     {
552e1df4f2dSKatayama Hirofumi MZ         TRACE("\n");
553c45a6e15SJames Tabor         return FALSE;
554c2a94365SKatayama Hirofumi MZ     }
555c2c66affSColin Finck 
556c2a94365SKatayama Hirofumi MZ     if (hIMC && !(dwFlags & IACE_DEFAULT) && IS_CROSS_THREAD_HIMC(hIMC))
557df6fff78SKatayama Hirofumi MZ         return FALSE;
558df6fff78SKatayama Hirofumi MZ 
559df6fff78SKatayama Hirofumi MZ     hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS);
560b0b925d2SKatayama Hirofumi MZ     pFocusWnd = ValidateHwnd(hwndFocus);
561df6fff78SKatayama Hirofumi MZ     if (pFocusWnd)
562df6fff78SKatayama Hirofumi MZ         hOldIMC = pFocusWnd->hImc;
563df6fff78SKatayama Hirofumi MZ 
564df6fff78SKatayama Hirofumi MZ     dwValue = NtUserAssociateInputContext(hWnd, hIMC, dwFlags);
565df6fff78SKatayama Hirofumi MZ     switch (dwValue)
566c2c66affSColin Finck     {
567c2c66affSColin Finck         case 0:
568c2c66affSColin Finck             return TRUE;
569df6fff78SKatayama Hirofumi MZ 
570df6fff78SKatayama Hirofumi MZ         case 1:
571b0b925d2SKatayama Hirofumi MZ             pFocusWnd = ValidateHwnd(hwndFocus);
572df6fff78SKatayama Hirofumi MZ             if (pFocusWnd)
573c45a6e15SJames Tabor             {
574df6fff78SKatayama Hirofumi MZ                 hIMC = pFocusWnd->hImc;
575df6fff78SKatayama Hirofumi MZ                 if (hIMC != hOldIMC)
576df6fff78SKatayama Hirofumi MZ                 {
577df6fff78SKatayama Hirofumi MZ                     ImmSetActiveContext(hwndFocus, hOldIMC, FALSE);
578df6fff78SKatayama Hirofumi MZ                     ImmSetActiveContext(hwndFocus, hIMC, TRUE);
579c45a6e15SJames Tabor                 }
580df6fff78SKatayama Hirofumi MZ             }
581c2c66affSColin Finck             return TRUE;
582df6fff78SKatayama Hirofumi MZ 
583c2c66affSColin Finck         default:
584c2c66affSColin Finck             return FALSE;
585c2c66affSColin Finck     }
586c2c66affSColin Finck }
587c2c66affSColin Finck 
588c2c66affSColin Finck /***********************************************************************
589c2c66affSColin Finck  *		ImmCreateContext (IMM32.@)
590c2c66affSColin Finck  */
ImmCreateContext(void)591c2c66affSColin Finck HIMC WINAPI ImmCreateContext(void)
592c2c66affSColin Finck {
593692a30a8SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
594692a30a8SKatayama Hirofumi MZ     HIMC hIMC;
595c2c66affSColin Finck 
5961d9542d2SKatayama Hirofumi MZ     TRACE("()\n");
597c2c66affSColin Finck 
598356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
599c2a94365SKatayama Hirofumi MZ     {
600e1df4f2dSKatayama Hirofumi MZ         TRACE("\n");
601692a30a8SKatayama Hirofumi MZ         return NULL;
602c2a94365SKatayama Hirofumi MZ     }
603c2c66affSColin Finck 
60446518ad6SKatayama Hirofumi MZ     pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
605c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pClientImc))
606692a30a8SKatayama Hirofumi MZ         return NULL;
607692a30a8SKatayama Hirofumi MZ 
608d5deacd9SKatayama Hirofumi MZ     hIMC = NtUserCreateInputContext((ULONG_PTR)pClientImc);
609c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(hIMC))
610c2c66affSColin Finck     {
61146518ad6SKatayama Hirofumi MZ         ImmLocalFree(pClientImc);
612692a30a8SKatayama Hirofumi MZ         return NULL;
613c2c66affSColin Finck     }
614c2c66affSColin Finck 
615692a30a8SKatayama Hirofumi MZ     RtlInitializeCriticalSection(&pClientImc->cs);
616f4bc74edSKatayama Hirofumi MZ 
61741b87158SKatayama Hirofumi MZ     pClientImc->dwCompatFlags = (DWORD)NtUserGetThreadState(THREADSTATE_IMECOMPATFLAGS);
618f4bc74edSKatayama Hirofumi MZ 
619692a30a8SKatayama Hirofumi MZ     return hIMC;
620c2c66affSColin Finck }
621c2c66affSColin Finck 
6224342b84cSKatayama Hirofumi MZ // Win: DestroyImeModeSaver
Imm32DestroyImeModeSaver(LPINPUTCONTEXTDX pIC)6234342b84cSKatayama Hirofumi MZ static VOID APIENTRY Imm32DestroyImeModeSaver(LPINPUTCONTEXTDX pIC)
624c2c66affSColin Finck {
6254342b84cSKatayama Hirofumi MZ     PIME_STATE pState, pNext;
6264342b84cSKatayama Hirofumi MZ     PIME_SUBSTATE pSubState, pSubNext;
62766ef3149SKatayama Hirofumi MZ 
6284342b84cSKatayama Hirofumi MZ     for (pState = pIC->pState; pState; pState = pNext)
62966ef3149SKatayama Hirofumi MZ     {
6304342b84cSKatayama Hirofumi MZ         pNext = pState->pNext;
6314342b84cSKatayama Hirofumi MZ 
6324342b84cSKatayama Hirofumi MZ         for (pSubState = pState->pSubState; pSubState; pSubState = pSubNext)
63366ef3149SKatayama Hirofumi MZ         {
6344342b84cSKatayama Hirofumi MZ             pSubNext = pSubState->pNext;
63546518ad6SKatayama Hirofumi MZ             ImmLocalFree(pSubState);
63666ef3149SKatayama Hirofumi MZ         }
6374342b84cSKatayama Hirofumi MZ 
63846518ad6SKatayama Hirofumi MZ         ImmLocalFree(pState);
63966ef3149SKatayama Hirofumi MZ     }
6404342b84cSKatayama Hirofumi MZ 
6414342b84cSKatayama Hirofumi MZ     pIC->pState = NULL;
642692a30a8SKatayama Hirofumi MZ }
643c2c66affSColin Finck 
644a40f55bfSKatayama Hirofumi MZ // Win: DestroyInputContext
Imm32DestroyInputContext(HIMC hIMC,HKL hKL,BOOL bKeep)645f8902dc3SKatayama Hirofumi MZ BOOL APIENTRY Imm32DestroyInputContext(HIMC hIMC, HKL hKL, BOOL bKeep)
646692a30a8SKatayama Hirofumi MZ {
647692a30a8SKatayama Hirofumi MZ     PIMEDPI pImeDpi;
64866ef3149SKatayama Hirofumi MZ     LPINPUTCONTEXTDX pIC;
649692a30a8SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
650be9a788fSKatayama Hirofumi MZ     PIMC pIMC;
651692a30a8SKatayama Hirofumi MZ 
652c2a94365SKatayama Hirofumi MZ     if (hIMC == NULL)
653c2c66affSColin Finck         return FALSE;
654c2c66affSColin Finck 
655c2a94365SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
65645a4e53fSKatayama Hirofumi MZ     {
657e1df4f2dSKatayama Hirofumi MZ         TRACE("\n");
658c2a94365SKatayama Hirofumi MZ         return FALSE;
659c2a94365SKatayama Hirofumi MZ     }
660c2a94365SKatayama Hirofumi MZ 
661c2a94365SKatayama Hirofumi MZ     pIMC = ValidateHandle(hIMC, TYPE_INPUTCONTEXT);
662c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pIMC))
663c2a94365SKatayama Hirofumi MZ         return FALSE;
664c2a94365SKatayama Hirofumi MZ 
665c2a94365SKatayama Hirofumi MZ     if (pIMC->head.pti != Imm32CurrentPti())
666c2a94365SKatayama Hirofumi MZ     {
667e1df4f2dSKatayama Hirofumi MZ         ERR("Thread mismatch\n");
668be9a788fSKatayama Hirofumi MZ         return FALSE;
66945a4e53fSKatayama Hirofumi MZ     }
670be9a788fSKatayama Hirofumi MZ 
671be9a788fSKatayama Hirofumi MZ     pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
672c2a94365SKatayama Hirofumi MZ     if (pClientImc == NULL)
673c2a94365SKatayama Hirofumi MZ     {
674c2a94365SKatayama Hirofumi MZ         TRACE("pClientImc == NULL\n");
67545a4e53fSKatayama Hirofumi MZ         goto Finish;
676c2a94365SKatayama Hirofumi MZ     }
677c2c66affSColin Finck 
67845a4e53fSKatayama Hirofumi MZ     if ((pClientImc->dwFlags & CLIENTIMC_UNKNOWN2) && !bKeep)
679692a30a8SKatayama Hirofumi MZ     {
680e1df4f2dSKatayama Hirofumi MZ         ERR("Can't destroy for CLIENTIMC_UNKNOWN2\n");
68145a4e53fSKatayama Hirofumi MZ         return FALSE;
682692a30a8SKatayama Hirofumi MZ     }
683c2c66affSColin Finck 
6846ba810c0SKatayama Hirofumi MZ     if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
68545a4e53fSKatayama Hirofumi MZ         return TRUE;
68645a4e53fSKatayama Hirofumi MZ 
68745a4e53fSKatayama Hirofumi MZ     InterlockedIncrement(&pClientImc->cLockObj);
68845a4e53fSKatayama Hirofumi MZ 
689c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pClientImc->hInputContext))
69045a4e53fSKatayama Hirofumi MZ         goto Quit;
69145a4e53fSKatayama Hirofumi MZ 
69266ef3149SKatayama Hirofumi MZ     pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
693c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pIC))
694692a30a8SKatayama Hirofumi MZ     {
695692a30a8SKatayama Hirofumi MZ         ImmUnlockClientImc(pClientImc);
696692a30a8SKatayama Hirofumi MZ         return FALSE;
697692a30a8SKatayama Hirofumi MZ     }
698692a30a8SKatayama Hirofumi MZ 
6994342b84cSKatayama Hirofumi MZ     CtfImmTIMDestroyInputContext(hIMC);
7004342b84cSKatayama Hirofumi MZ 
7014342b84cSKatayama Hirofumi MZ     if (pClientImc->hKL == hKL)
7024342b84cSKatayama Hirofumi MZ     {
703692a30a8SKatayama Hirofumi MZ         pImeDpi = ImmLockImeDpi(hKL);
70445a4e53fSKatayama Hirofumi MZ         if (pImeDpi)
705692a30a8SKatayama Hirofumi MZ         {
7064342b84cSKatayama Hirofumi MZ             if (IS_IME_HKL(hKL))
707692a30a8SKatayama Hirofumi MZ                 pImeDpi->ImeSelect(hIMC, FALSE);
7088ba378c9SKatayama Hirofumi MZ             else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
7094342b84cSKatayama Hirofumi MZ                 pImeDpi->CtfImeSelectEx(hIMC, FALSE, hKL);
7104342b84cSKatayama Hirofumi MZ 
711692a30a8SKatayama Hirofumi MZ             ImmUnlockImeDpi(pImeDpi);
712692a30a8SKatayama Hirofumi MZ         }
713692a30a8SKatayama Hirofumi MZ 
7144342b84cSKatayama Hirofumi MZ         pClientImc->hKL = NULL;
7154342b84cSKatayama Hirofumi MZ     }
7164342b84cSKatayama Hirofumi MZ 
7174342b84cSKatayama Hirofumi MZ     ImmDestroyIMCC(pIC->hPrivate);
7184342b84cSKatayama Hirofumi MZ     ImmDestroyIMCC(pIC->hMsgBuf);
7194342b84cSKatayama Hirofumi MZ     ImmDestroyIMCC(pIC->hGuideLine);
7204342b84cSKatayama Hirofumi MZ     ImmDestroyIMCC(pIC->hCandInfo);
7214342b84cSKatayama Hirofumi MZ     ImmDestroyIMCC(pIC->hCompStr);
7224342b84cSKatayama Hirofumi MZ     Imm32DestroyImeModeSaver(pIC);
723692a30a8SKatayama Hirofumi MZ     ImmUnlockIMC(hIMC);
724692a30a8SKatayama Hirofumi MZ 
72545a4e53fSKatayama Hirofumi MZ Quit:
7266ba810c0SKatayama Hirofumi MZ     pClientImc->dwFlags |= CLIENTIMC_DESTROY;
727692a30a8SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
728692a30a8SKatayama Hirofumi MZ 
72945a4e53fSKatayama Hirofumi MZ Finish:
73045a4e53fSKatayama Hirofumi MZ     if (bKeep)
731c2c66affSColin Finck         return TRUE;
73245a4e53fSKatayama Hirofumi MZ     return NtUserDestroyInputContext(hIMC);
733c2c66affSColin Finck }
734c2c66affSColin Finck 
7358de74398SKatayama Hirofumi MZ // NOTE: Windows does recursive call ImmLockIMC here but we don't do so.
7368de74398SKatayama Hirofumi MZ // Win: BOOL CreateInputContext(HIMC hIMC, HKL hKL, BOOL fSelect)
737b3382d8dSKatayama Hirofumi MZ BOOL APIENTRY
Imm32CreateInputContext(HIMC hIMC,LPINPUTCONTEXT pIC,PCLIENTIMC pClientImc,HKL hKL,BOOL fSelect)7388de74398SKatayama Hirofumi MZ Imm32CreateInputContext(HIMC hIMC, LPINPUTCONTEXT pIC, PCLIENTIMC pClientImc, HKL hKL, BOOL fSelect)
739b3382d8dSKatayama Hirofumi MZ {
740b3382d8dSKatayama Hirofumi MZ     DWORD dwIndex, cbPrivate;
741b3382d8dSKatayama Hirofumi MZ     PIMEDPI pImeDpi = NULL;
742b3382d8dSKatayama Hirofumi MZ     LPCOMPOSITIONSTRING pCS;
743b3382d8dSKatayama Hirofumi MZ     LPCANDIDATEINFO pCI;
744b3382d8dSKatayama Hirofumi MZ     LPGUIDELINE pGL;
745b3382d8dSKatayama Hirofumi MZ 
746b3382d8dSKatayama Hirofumi MZ     /* Create IC components */
747b3382d8dSKatayama Hirofumi MZ     pIC->hCompStr = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
748b3382d8dSKatayama Hirofumi MZ     pIC->hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
749b3382d8dSKatayama Hirofumi MZ     pIC->hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
750b3382d8dSKatayama Hirofumi MZ     pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
751c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pIC->hCompStr) ||
752c2a94365SKatayama Hirofumi MZ         IS_NULL_UNEXPECTEDLY(pIC->hCandInfo) ||
753c2a94365SKatayama Hirofumi MZ         IS_NULL_UNEXPECTEDLY(pIC->hGuideLine) ||
754c2a94365SKatayama Hirofumi MZ         IS_NULL_UNEXPECTEDLY(pIC->hMsgBuf))
755c2a94365SKatayama Hirofumi MZ     {
756b3382d8dSKatayama Hirofumi MZ         goto Fail;
757c2a94365SKatayama Hirofumi MZ     }
758b3382d8dSKatayama Hirofumi MZ 
759b3382d8dSKatayama Hirofumi MZ     /* Initialize IC components */
760b3382d8dSKatayama Hirofumi MZ     pCS = ImmLockIMCC(pIC->hCompStr);
761c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pCS))
762b3382d8dSKatayama Hirofumi MZ         goto Fail;
763b3382d8dSKatayama Hirofumi MZ     pCS->dwSize = sizeof(COMPOSITIONSTRING);
764b3382d8dSKatayama Hirofumi MZ     ImmUnlockIMCC(pIC->hCompStr);
765b3382d8dSKatayama Hirofumi MZ 
766b3382d8dSKatayama Hirofumi MZ     pCI = ImmLockIMCC(pIC->hCandInfo);
767c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pCI))
768b3382d8dSKatayama Hirofumi MZ         goto Fail;
769b3382d8dSKatayama Hirofumi MZ     pCI->dwSize = sizeof(CANDIDATEINFO);
770b3382d8dSKatayama Hirofumi MZ     ImmUnlockIMCC(pIC->hCandInfo);
771b3382d8dSKatayama Hirofumi MZ 
772b3382d8dSKatayama Hirofumi MZ     pGL = ImmLockIMCC(pIC->hGuideLine);
773c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pGL))
774b3382d8dSKatayama Hirofumi MZ         goto Fail;
775b3382d8dSKatayama Hirofumi MZ     pGL->dwSize = sizeof(GUIDELINE);
776b3382d8dSKatayama Hirofumi MZ     ImmUnlockIMCC(pIC->hGuideLine);
777b3382d8dSKatayama Hirofumi MZ 
778b3382d8dSKatayama Hirofumi MZ     pIC->dwNumMsgBuf = 0;
779b3382d8dSKatayama Hirofumi MZ     pIC->fOpen = FALSE;
780b3382d8dSKatayama Hirofumi MZ     pIC->fdwConversion = pIC->fdwSentence = 0;
781b3382d8dSKatayama Hirofumi MZ 
782b3382d8dSKatayama Hirofumi MZ     for (dwIndex = 0; dwIndex < MAX_CANDIDATEFORM; ++dwIndex)
783b3382d8dSKatayama Hirofumi MZ         pIC->cfCandForm[dwIndex].dwIndex = IMM_INVALID_CANDFORM;
784b3382d8dSKatayama Hirofumi MZ 
785b3382d8dSKatayama Hirofumi MZ     /* Get private data size */
786b3382d8dSKatayama Hirofumi MZ     pImeDpi = ImmLockImeDpi(hKL);
787b3382d8dSKatayama Hirofumi MZ     if (!pImeDpi)
788b3382d8dSKatayama Hirofumi MZ     {
789b3382d8dSKatayama Hirofumi MZ         cbPrivate = sizeof(DWORD);
790b3382d8dSKatayama Hirofumi MZ     }
791b3382d8dSKatayama Hirofumi MZ     else
792b3382d8dSKatayama Hirofumi MZ     {
793b3382d8dSKatayama Hirofumi MZ         /* Update CLIENTIMC */
794b3382d8dSKatayama Hirofumi MZ         pClientImc->uCodePage = pImeDpi->uCodePage;
795b3382d8dSKatayama Hirofumi MZ         if (ImeDpi_IsUnicode(pImeDpi))
796b3382d8dSKatayama Hirofumi MZ             pClientImc->dwFlags |= CLIENTIMC_WIDE;
797b3382d8dSKatayama Hirofumi MZ 
798b3382d8dSKatayama Hirofumi MZ         cbPrivate = pImeDpi->ImeInfo.dwPrivateDataSize;
799b3382d8dSKatayama Hirofumi MZ     }
800b3382d8dSKatayama Hirofumi MZ 
801b3382d8dSKatayama Hirofumi MZ     /* Create private data */
802b3382d8dSKatayama Hirofumi MZ     pIC->hPrivate = ImmCreateIMCC(cbPrivate);
803c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pIC->hPrivate))
804b3382d8dSKatayama Hirofumi MZ         goto Fail;
805b3382d8dSKatayama Hirofumi MZ 
806edbeaa3cSKatayama Hirofumi MZ     CtfImmTIMCreateInputContext(hIMC);
807edbeaa3cSKatayama Hirofumi MZ 
808b3382d8dSKatayama Hirofumi MZ     if (pImeDpi)
809b3382d8dSKatayama Hirofumi MZ     {
810b3382d8dSKatayama Hirofumi MZ         /* Select the IME */
811b3382d8dSKatayama Hirofumi MZ         if (fSelect)
812b3382d8dSKatayama Hirofumi MZ         {
813b3382d8dSKatayama Hirofumi MZ             if (IS_IME_HKL(hKL))
814b3382d8dSKatayama Hirofumi MZ                 pImeDpi->ImeSelect(hIMC, TRUE);
815020d7d58SKatayama Hirofumi MZ             else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
816b3382d8dSKatayama Hirofumi MZ                 pImeDpi->CtfImeSelectEx(hIMC, TRUE, hKL);
817b3382d8dSKatayama Hirofumi MZ         }
818b3382d8dSKatayama Hirofumi MZ 
819b3382d8dSKatayama Hirofumi MZ         /* Set HKL */
820b3382d8dSKatayama Hirofumi MZ         pClientImc->hKL = hKL;
821b3382d8dSKatayama Hirofumi MZ 
822b3382d8dSKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
823b3382d8dSKatayama Hirofumi MZ     }
824b3382d8dSKatayama Hirofumi MZ 
825b3382d8dSKatayama Hirofumi MZ     return TRUE;
826b3382d8dSKatayama Hirofumi MZ 
827b3382d8dSKatayama Hirofumi MZ Fail:
828b3382d8dSKatayama Hirofumi MZ     if (pImeDpi)
829b3382d8dSKatayama Hirofumi MZ         ImmUnlockImeDpi(pImeDpi);
830b3382d8dSKatayama Hirofumi MZ 
831b3382d8dSKatayama Hirofumi MZ     pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
832b3382d8dSKatayama Hirofumi MZ     pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
833b3382d8dSKatayama Hirofumi MZ     pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
834b3382d8dSKatayama Hirofumi MZ     pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
835b3382d8dSKatayama Hirofumi MZ     return FALSE;
836b3382d8dSKatayama Hirofumi MZ }
837b3382d8dSKatayama Hirofumi MZ 
Imm32InternalLockIMC(HIMC hIMC,BOOL fSelect)8388de74398SKatayama Hirofumi MZ LPINPUTCONTEXT APIENTRY Imm32InternalLockIMC(HIMC hIMC, BOOL fSelect)
839b3382d8dSKatayama Hirofumi MZ {
840b3382d8dSKatayama Hirofumi MZ     HANDLE hIC;
841b3382d8dSKatayama Hirofumi MZ     LPINPUTCONTEXT pIC = NULL;
842b3382d8dSKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
8438de74398SKatayama Hirofumi MZ     WORD LangID;
844b3382d8dSKatayama Hirofumi MZ     DWORD dwThreadId;
8458de74398SKatayama Hirofumi MZ     HKL hOldKL, hNewKL;
846b3382d8dSKatayama Hirofumi MZ     PIMEDPI pImeDpi = NULL;
847b3382d8dSKatayama Hirofumi MZ 
848b3382d8dSKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
8498e01ab83SKatayama Hirofumi MZ     if (!pClientImc)
850b3382d8dSKatayama Hirofumi MZ         return NULL;
851b3382d8dSKatayama Hirofumi MZ 
852b3382d8dSKatayama Hirofumi MZ     RtlEnterCriticalSection(&pClientImc->cs);
853b3382d8dSKatayama Hirofumi MZ 
8548de74398SKatayama Hirofumi MZ     if (pClientImc->hInputContext)
8558f719cb9SKatayama Hirofumi MZ     {
8568f719cb9SKatayama Hirofumi MZ         pIC = LocalLock(pClientImc->hInputContext);
857c2a94365SKatayama Hirofumi MZ         if (IS_NULL_UNEXPECTEDLY(pIC))
858c2a94365SKatayama Hirofumi MZ             goto Failure;
859c2a94365SKatayama Hirofumi MZ 
860edbeaa3cSKatayama Hirofumi MZ         CtfImmTIMCreateInputContext(hIMC);
8618f719cb9SKatayama Hirofumi MZ         goto Success;
862edbeaa3cSKatayama Hirofumi MZ     }
863b3382d8dSKatayama Hirofumi MZ 
8648de74398SKatayama Hirofumi MZ     dwThreadId = (DWORD)NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID);
8658ba378c9SKatayama Hirofumi MZ     if (dwThreadId == GetCurrentThreadId() && IS_CICERO_MODE() && !IS_16BIT_MODE())
866b3382d8dSKatayama Hirofumi MZ     {
8678de74398SKatayama Hirofumi MZ         hOldKL = GetKeyboardLayout(0);
8688de74398SKatayama Hirofumi MZ         LangID = LOWORD(hOldKL);
869ec24b547SKatayama Hirofumi MZ         hNewKL = UlongToHandle(MAKELONG(LangID, LangID));
870b3382d8dSKatayama Hirofumi MZ 
87197f4c3c3SKatayama Hirofumi MZ         pImeDpi = Imm32FindOrLoadImeDpi(hNewKL);
872b3382d8dSKatayama Hirofumi MZ         if (pImeDpi)
873b3382d8dSKatayama Hirofumi MZ         {
8748de74398SKatayama Hirofumi MZ             CtfImmTIMActivate(hNewKL);
875b3382d8dSKatayama Hirofumi MZ         }
876b3382d8dSKatayama Hirofumi MZ     }
877b3382d8dSKatayama Hirofumi MZ 
878cdf3b5e8SKatayama Hirofumi MZ     if (!NtUserQueryInputContext(hIMC, QIC_DEFAULTWINDOWIME))
879c2a94365SKatayama Hirofumi MZ     {
880e1df4f2dSKatayama Hirofumi MZ         ERR("No default IME window\n");
8818f719cb9SKatayama Hirofumi MZ         goto Failure;
882c2a94365SKatayama Hirofumi MZ     }
883b3382d8dSKatayama Hirofumi MZ 
884b3382d8dSKatayama Hirofumi MZ     hIC = LocalAlloc(LHND, sizeof(INPUTCONTEXTDX));
8858de74398SKatayama Hirofumi MZ     pIC = LocalLock(hIC);
886c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pIC))
887b3382d8dSKatayama Hirofumi MZ     {
8888de74398SKatayama Hirofumi MZ         LocalFree(hIC);
8898f719cb9SKatayama Hirofumi MZ         goto Failure;
890b3382d8dSKatayama Hirofumi MZ     }
891b3382d8dSKatayama Hirofumi MZ     pClientImc->hInputContext = hIC;
892b3382d8dSKatayama Hirofumi MZ 
8938de74398SKatayama Hirofumi MZ     hNewKL = GetKeyboardLayout(dwThreadId);
8948de74398SKatayama Hirofumi MZ     if (!Imm32CreateInputContext(hIMC, pIC, pClientImc, hNewKL, fSelect))
895b3382d8dSKatayama Hirofumi MZ     {
8965462d4adSKatayama Hirofumi MZ         LocalUnlock(hIC);
8975462d4adSKatayama Hirofumi MZ         pClientImc->hInputContext = LocalFree(hIC);
8988f719cb9SKatayama Hirofumi MZ         goto Failure;
899b3382d8dSKatayama Hirofumi MZ     }
900b3382d8dSKatayama Hirofumi MZ 
9018f719cb9SKatayama Hirofumi MZ Success:
902b3382d8dSKatayama Hirofumi MZ     RtlLeaveCriticalSection(&pClientImc->cs);
903b3382d8dSKatayama Hirofumi MZ     InterlockedIncrement(&pClientImc->cLockObj);
904b3382d8dSKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
905b3382d8dSKatayama Hirofumi MZ     return pIC;
9068de74398SKatayama Hirofumi MZ 
9078f719cb9SKatayama Hirofumi MZ Failure:
9088de74398SKatayama Hirofumi MZ     RtlLeaveCriticalSection(&pClientImc->cs);
9098de74398SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
9108de74398SKatayama Hirofumi MZ     return NULL;
911b3382d8dSKatayama Hirofumi MZ }
912b3382d8dSKatayama Hirofumi MZ 
913c2c66affSColin Finck /***********************************************************************
914c2c66affSColin Finck  *		ImmDestroyContext (IMM32.@)
915c2c66affSColin Finck  */
ImmDestroyContext(HIMC hIMC)916c2c66affSColin Finck BOOL WINAPI ImmDestroyContext(HIMC hIMC)
917c2c66affSColin Finck {
918692a30a8SKatayama Hirofumi MZ     HKL hKL;
919692a30a8SKatayama Hirofumi MZ 
9201d9542d2SKatayama Hirofumi MZ     TRACE("(%p)\n", hIMC);
921692a30a8SKatayama Hirofumi MZ 
922356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
923c2a94365SKatayama Hirofumi MZ     {
924e1df4f2dSKatayama Hirofumi MZ         TRACE("\n");
925c2c66affSColin Finck         return FALSE;
926c2a94365SKatayama Hirofumi MZ     }
927692a30a8SKatayama Hirofumi MZ 
928c2a94365SKatayama Hirofumi MZ     if (IS_CROSS_THREAD_HIMC(hIMC))
929692a30a8SKatayama Hirofumi MZ         return FALSE;
930692a30a8SKatayama Hirofumi MZ 
931692a30a8SKatayama Hirofumi MZ     hKL = GetKeyboardLayout(0);
932f8902dc3SKatayama Hirofumi MZ     return Imm32DestroyInputContext(hIMC, hKL, FALSE);
933c2c66affSColin Finck }
934c2c66affSColin Finck 
9351da5d7a3SKatayama Hirofumi MZ /***********************************************************************
9361da5d7a3SKatayama Hirofumi MZ  *		ImmLockClientImc (IMM32.@)
9371da5d7a3SKatayama Hirofumi MZ  */
ImmLockClientImc(HIMC hImc)93892393a75SKatayama Hirofumi MZ PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
93992393a75SKatayama Hirofumi MZ {
940be9a788fSKatayama Hirofumi MZ     PIMC pIMC;
94192393a75SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
94292393a75SKatayama Hirofumi MZ 
9431d9542d2SKatayama Hirofumi MZ     TRACE("(%p)\n", hImc);
94492393a75SKatayama Hirofumi MZ 
945c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(hImc))
94692393a75SKatayama Hirofumi MZ         return NULL;
94792393a75SKatayama Hirofumi MZ 
948b0b925d2SKatayama Hirofumi MZ     pIMC = ValidateHandle(hImc, TYPE_INPUTCONTEXT);
9498e01ab83SKatayama Hirofumi MZ     if (!pIMC || !Imm32CheckImcProcess(pIMC))
950be9a788fSKatayama Hirofumi MZ         return NULL;
951be9a788fSKatayama Hirofumi MZ 
952be9a788fSKatayama Hirofumi MZ     pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
953f848343bSKatayama Hirofumi MZ     if (pClientImc)
95492393a75SKatayama Hirofumi MZ     {
955f848343bSKatayama Hirofumi MZ         if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
956f848343bSKatayama Hirofumi MZ             return NULL;
957f848343bSKatayama Hirofumi MZ         goto Finish;
958f848343bSKatayama Hirofumi MZ     }
959f848343bSKatayama Hirofumi MZ 
96046518ad6SKatayama Hirofumi MZ     pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
961c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pClientImc))
96292393a75SKatayama Hirofumi MZ         return NULL;
96392393a75SKatayama Hirofumi MZ 
96492393a75SKatayama Hirofumi MZ     RtlInitializeCriticalSection(&pClientImc->cs);
96541b87158SKatayama Hirofumi MZ     pClientImc->dwCompatFlags = (DWORD)NtUserGetThreadState(THREADSTATE_IMECOMPATFLAGS);
96692393a75SKatayama Hirofumi MZ 
967ba3affe5SKatayama Hirofumi MZ     if (!NtUserUpdateInputContext(hImc, UIC_CLIENTIMCDATA, (DWORD_PTR)pClientImc))
96892393a75SKatayama Hirofumi MZ     {
969c2a94365SKatayama Hirofumi MZ         ERR("\n");
97046518ad6SKatayama Hirofumi MZ         ImmLocalFree(pClientImc);
97192393a75SKatayama Hirofumi MZ         return NULL;
97292393a75SKatayama Hirofumi MZ     }
97392393a75SKatayama Hirofumi MZ 
97492393a75SKatayama Hirofumi MZ     pClientImc->dwFlags |= CLIENTIMC_UNKNOWN2;
97592393a75SKatayama Hirofumi MZ 
976f848343bSKatayama Hirofumi MZ Finish:
97792393a75SKatayama Hirofumi MZ     InterlockedIncrement(&pClientImc->cLockObj);
97892393a75SKatayama Hirofumi MZ     return pClientImc;
97992393a75SKatayama Hirofumi MZ }
98092393a75SKatayama Hirofumi MZ 
9811da5d7a3SKatayama Hirofumi MZ /***********************************************************************
9821da5d7a3SKatayama Hirofumi MZ  *		ImmUnlockClientImc (IMM32.@)
9831da5d7a3SKatayama Hirofumi MZ  */
ImmUnlockClientImc(PCLIENTIMC pClientImc)98492393a75SKatayama Hirofumi MZ VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
98592393a75SKatayama Hirofumi MZ {
98692393a75SKatayama Hirofumi MZ     LONG cLocks;
987b3382d8dSKatayama Hirofumi MZ     HANDLE hInputContext;
98892393a75SKatayama Hirofumi MZ 
9891d9542d2SKatayama Hirofumi MZ     TRACE("(%p)\n", pClientImc);
99092393a75SKatayama Hirofumi MZ 
99192393a75SKatayama Hirofumi MZ     cLocks = InterlockedDecrement(&pClientImc->cLockObj);
9926ba810c0SKatayama Hirofumi MZ     if (cLocks != 0 || !(pClientImc->dwFlags & CLIENTIMC_DESTROY))
99392393a75SKatayama Hirofumi MZ         return;
99492393a75SKatayama Hirofumi MZ 
995b3382d8dSKatayama Hirofumi MZ     hInputContext = pClientImc->hInputContext;
996b3382d8dSKatayama Hirofumi MZ     if (hInputContext)
997b3382d8dSKatayama Hirofumi MZ         LocalFree(hInputContext);
99892393a75SKatayama Hirofumi MZ 
99992393a75SKatayama Hirofumi MZ     RtlDeleteCriticalSection(&pClientImc->cs);
100046518ad6SKatayama Hirofumi MZ     ImmLocalFree(pClientImc);
100192393a75SKatayama Hirofumi MZ }
100292393a75SKatayama Hirofumi MZ 
1003a40f55bfSKatayama Hirofumi MZ // Win: ImmGetSaveContext
ImmGetSaveContext(HWND hWnd,DWORD dwContextFlags)1004720da3b9SKatayama Hirofumi MZ static HIMC APIENTRY ImmGetSaveContext(HWND hWnd, DWORD dwContextFlags)
1005a8d2cd4bSKatayama Hirofumi MZ {
1006a8d2cd4bSKatayama Hirofumi MZ     HIMC hIMC;
1007a8d2cd4bSKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
1008a8d2cd4bSKatayama Hirofumi MZ     PWND pWnd;
1009a8d2cd4bSKatayama Hirofumi MZ 
1010356babcaSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1011c2a94365SKatayama Hirofumi MZ     {
1012c2a94365SKatayama Hirofumi MZ         TRACE("Not IMM mode.\n");
1013a8d2cd4bSKatayama Hirofumi MZ         return NULL;
1014c2a94365SKatayama Hirofumi MZ     }
1015a8d2cd4bSKatayama Hirofumi MZ 
1016a8d2cd4bSKatayama Hirofumi MZ     if (!hWnd)
1017a8d2cd4bSKatayama Hirofumi MZ     {
101841b87158SKatayama Hirofumi MZ         hIMC = (HIMC)NtUserGetThreadState(THREADSTATE_DEFAULTINPUTCONTEXT);
1019a8d2cd4bSKatayama Hirofumi MZ         goto Quit;
1020a8d2cd4bSKatayama Hirofumi MZ     }
1021a8d2cd4bSKatayama Hirofumi MZ 
1022b0b925d2SKatayama Hirofumi MZ     pWnd = ValidateHwnd(hWnd);
1023c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pWnd) || IS_CROSS_PROCESS_HWND(hWnd))
1024a8d2cd4bSKatayama Hirofumi MZ         return NULL;
1025a8d2cd4bSKatayama Hirofumi MZ 
1026a8d2cd4bSKatayama Hirofumi MZ     hIMC = pWnd->hImc;
1027a8d2cd4bSKatayama Hirofumi MZ     if (!hIMC && (dwContextFlags & 1))
1028a8d2cd4bSKatayama Hirofumi MZ         hIMC = (HIMC)NtUserQueryWindow(hWnd, QUERY_WINDOW_DEFAULT_ICONTEXT);
1029a8d2cd4bSKatayama Hirofumi MZ 
1030a8d2cd4bSKatayama Hirofumi MZ Quit:
1031a8d2cd4bSKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
1032c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pClientImc))
1033a8d2cd4bSKatayama Hirofumi MZ         return NULL;
1034c2a94365SKatayama Hirofumi MZ 
1035934e5212SKatayama Hirofumi MZ     if ((dwContextFlags & 2) && (pClientImc->dwFlags & CLIENTIMC_DISABLEIME))
1036a8d2cd4bSKatayama Hirofumi MZ         hIMC = NULL;
1037c2a94365SKatayama Hirofumi MZ 
1038a8d2cd4bSKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
1039a8d2cd4bSKatayama Hirofumi MZ     return hIMC;
1040a8d2cd4bSKatayama Hirofumi MZ }
1041a8d2cd4bSKatayama Hirofumi MZ 
1042c2c66affSColin Finck /***********************************************************************
1043c2c66affSColin Finck  *		ImmGetContext (IMM32.@)
1044c2c66affSColin Finck  */
ImmGetContext(HWND hWnd)1045c2c66affSColin Finck HIMC WINAPI ImmGetContext(HWND hWnd)
1046c2c66affSColin Finck {
1047a8d2cd4bSKatayama Hirofumi MZ     TRACE("(%p)\n", hWnd);
1048c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(hWnd))
1049c2c66affSColin Finck         return NULL;
1050720da3b9SKatayama Hirofumi MZ     return ImmGetSaveContext(hWnd, 2);
1051c2c66affSColin Finck }
1052c2c66affSColin Finck 
1053c2c66affSColin Finck /***********************************************************************
1054b4557a60SKatayama Hirofumi MZ  *		ImmLockIMC(IMM32.@)
1055b3382d8dSKatayama Hirofumi MZ  *
1056b3382d8dSKatayama Hirofumi MZ  * NOTE: This is not ImmLockIMCC. Don't confuse.
1057c2c66affSColin Finck  */
ImmLockIMC(HIMC hIMC)1058b4557a60SKatayama Hirofumi MZ LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
1059c2c66affSColin Finck {
1060b3382d8dSKatayama Hirofumi MZ     TRACE("(%p)\n", hIMC);
10618de74398SKatayama Hirofumi MZ     return Imm32InternalLockIMC(hIMC, TRUE);
1062c2c66affSColin Finck }
1063c2c66affSColin Finck 
1064b4557a60SKatayama Hirofumi MZ /***********************************************************************
1065b4557a60SKatayama Hirofumi MZ *		ImmUnlockIMC(IMM32.@)
1066b4557a60SKatayama Hirofumi MZ */
ImmUnlockIMC(HIMC hIMC)1067b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
106877911014SKatayama Hirofumi MZ {
1069b4557a60SKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
1070b4557a60SKatayama Hirofumi MZ 
1071b4557a60SKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
1072c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(pClientImc))
107377911014SKatayama Hirofumi MZ         return FALSE;
107477911014SKatayama Hirofumi MZ 
1075b3382d8dSKatayama Hirofumi MZ     if (pClientImc->hInputContext)
1076b3382d8dSKatayama Hirofumi MZ         LocalUnlock(pClientImc->hInputContext);
1077b4557a60SKatayama Hirofumi MZ 
1078b4557a60SKatayama Hirofumi MZ     InterlockedDecrement(&pClientImc->cLockObj);
1079b4557a60SKatayama Hirofumi MZ     ImmUnlockClientImc(pClientImc);
108077911014SKatayama Hirofumi MZ     return TRUE;
1081c2c66affSColin Finck }
1082c2c66affSColin Finck 
1083c2c66affSColin Finck /***********************************************************************
1084b4557a60SKatayama Hirofumi MZ  *		ImmReleaseContext (IMM32.@)
1085c2c66affSColin Finck  */
ImmReleaseContext(HWND hWnd,HIMC hIMC)1086b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1087c2c66affSColin Finck {
1088b4557a60SKatayama Hirofumi MZ     TRACE("(%p, %p)\n", hWnd, hIMC);
1089b4557a60SKatayama Hirofumi MZ     UNREFERENCED_PARAMETER(hWnd);
1090b4557a60SKatayama Hirofumi MZ     UNREFERENCED_PARAMETER(hIMC);
1091b4557a60SKatayama Hirofumi MZ     return TRUE; // Do nothing. This is correct.
1092c2c66affSColin Finck }
1093c2c66affSColin Finck 
1094c2c66affSColin Finck /***********************************************************************
1095b4557a60SKatayama Hirofumi MZ  *              ImmEnumInputContext(IMM32.@)
1096b4557a60SKatayama Hirofumi MZ  */
ImmEnumInputContext(DWORD dwThreadId,IMCENUMPROC lpfn,LPARAM lParam)1097b4557a60SKatayama Hirofumi MZ BOOL WINAPI ImmEnumInputContext(DWORD dwThreadId, IMCENUMPROC lpfn, LPARAM lParam)
1098b4557a60SKatayama Hirofumi MZ {
1099b4557a60SKatayama Hirofumi MZ     HIMC *phList;
1100b4557a60SKatayama Hirofumi MZ     DWORD dwIndex, dwCount;
1101b4557a60SKatayama Hirofumi MZ     BOOL ret = TRUE;
1102b4557a60SKatayama Hirofumi MZ     HIMC hIMC;
1103b4557a60SKatayama Hirofumi MZ 
1104b4557a60SKatayama Hirofumi MZ     TRACE("(%lu, %p, %p)\n", dwThreadId, lpfn, lParam);
1105b4557a60SKatayama Hirofumi MZ 
1106bc8a4ac3SKatayama Hirofumi MZ     dwCount = Imm32BuildHimcList(dwThreadId, &phList);
1107c2a94365SKatayama Hirofumi MZ     if (IS_ZERO_UNEXPECTEDLY(dwCount))
1108b4557a60SKatayama Hirofumi MZ         return FALSE;
1109b4557a60SKatayama Hirofumi MZ 
1110b4557a60SKatayama Hirofumi MZ     for (dwIndex = 0; dwIndex < dwCount; ++dwIndex)
1111b4557a60SKatayama Hirofumi MZ     {
1112b4557a60SKatayama Hirofumi MZ         hIMC = phList[dwIndex];
1113b4557a60SKatayama Hirofumi MZ         ret = (*lpfn)(hIMC, lParam);
1114b4557a60SKatayama Hirofumi MZ         if (!ret)
1115b4557a60SKatayama Hirofumi MZ             break;
1116b4557a60SKatayama Hirofumi MZ     }
1117b4557a60SKatayama Hirofumi MZ 
111846518ad6SKatayama Hirofumi MZ     ImmLocalFree(phList);
1119b4557a60SKatayama Hirofumi MZ     return ret;
1120b4557a60SKatayama Hirofumi MZ }
1121b4557a60SKatayama Hirofumi MZ 
1122b4557a60SKatayama Hirofumi MZ /***********************************************************************
1123b4557a60SKatayama Hirofumi MZ  *              ImmSetActiveContext(IMM32.@)
1124b4557a60SKatayama Hirofumi MZ  */
ImmSetActiveContext(HWND hWnd,HIMC hIMC,BOOL fActive)11259adc538cSKatayama Hirofumi MZ BOOL WINAPI ImmSetActiveContext(HWND hWnd, HIMC hIMC, BOOL fActive)
1126b4557a60SKatayama Hirofumi MZ {
11279adc538cSKatayama Hirofumi MZ     PCLIENTIMC pClientImc;
11289adc538cSKatayama Hirofumi MZ     LPINPUTCONTEXTDX pIC;
11299adc538cSKatayama Hirofumi MZ     PIMEDPI pImeDpi;
1130962c4557SKatayama Hirofumi MZ     HIMC hOldIMC;
11319adc538cSKatayama Hirofumi MZ     HKL hKL;
11329adc538cSKatayama Hirofumi MZ     BOOL fOpen = FALSE;
1133962c4557SKatayama Hirofumi MZ     DWORD dwConversion = 0, dwShowFlags = 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())
1139c2a94365SKatayama Hirofumi MZ     {
1140e1df4f2dSKatayama Hirofumi MZ         TRACE("\n");
1141b4557a60SKatayama Hirofumi MZ         return FALSE;
1142c2a94365SKatayama Hirofumi MZ     }
11439adc538cSKatayama Hirofumi MZ 
11449adc538cSKatayama Hirofumi MZ     pClientImc = ImmLockClientImc(hIMC);
11459adc538cSKatayama Hirofumi MZ 
11469adc538cSKatayama Hirofumi MZ     if (!fActive)
11479adc538cSKatayama Hirofumi MZ     {
11489adc538cSKatayama Hirofumi MZ         if (pClientImc)
1149633ed86aSKatayama Hirofumi MZ             pClientImc->dwFlags &= ~CLIENTIMC_ACTIVE;
11509adc538cSKatayama Hirofumi MZ     }
11519adc538cSKatayama Hirofumi MZ     else if (hIMC)
11529adc538cSKatayama Hirofumi MZ     {
1153c2a94365SKatayama Hirofumi MZ         if (IS_NULL_UNEXPECTEDLY(pClientImc))
11549adc538cSKatayama Hirofumi MZ             return FALSE;
11559adc538cSKatayama Hirofumi MZ 
11569adc538cSKatayama Hirofumi MZ         pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
1157c2a94365SKatayama Hirofumi MZ         if (IS_NULL_UNEXPECTEDLY(pIC))
11589adc538cSKatayama Hirofumi MZ         {
11599adc538cSKatayama Hirofumi MZ             ImmUnlockClientImc(pClientImc);
11609adc538cSKatayama Hirofumi MZ             return FALSE;
11619adc538cSKatayama Hirofumi MZ         }
11629adc538cSKatayama Hirofumi MZ 
11639adc538cSKatayama Hirofumi MZ         pIC->hWnd = hWnd;
1164633ed86aSKatayama Hirofumi MZ         pClientImc->dwFlags |= CLIENTIMC_ACTIVE;
11659adc538cSKatayama Hirofumi MZ 
11669adc538cSKatayama Hirofumi MZ         if (pIC->dwUIFlags & 2)
1167962c4557SKatayama Hirofumi MZ             dwShowFlags = (ISC_SHOWUIGUIDELINE | ISC_SHOWUIALLCANDIDATEWINDOW);
11689adc538cSKatayama Hirofumi MZ 
11699adc538cSKatayama Hirofumi MZ         fOpen = pIC->fOpen;
11709adc538cSKatayama Hirofumi MZ         dwConversion = pIC->fdwConversion;
11719adc538cSKatayama Hirofumi MZ 
11729adc538cSKatayama Hirofumi MZ         ImmUnlockIMC(hIMC);
11739adc538cSKatayama Hirofumi MZ     }
11749adc538cSKatayama Hirofumi MZ     else
11759adc538cSKatayama Hirofumi MZ     {
1176962c4557SKatayama Hirofumi MZ         hOldIMC = ImmGetSaveContext(hWnd, 1);
1177962c4557SKatayama Hirofumi MZ         pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hOldIMC);
11789adc538cSKatayama Hirofumi MZ         if (pIC)
11799adc538cSKatayama Hirofumi MZ         {
11809adc538cSKatayama Hirofumi MZ             pIC->hWnd = hWnd;
1181962c4557SKatayama Hirofumi MZ             ImmUnlockIMC(hOldIMC);
11829adc538cSKatayama Hirofumi MZ         }
11839adc538cSKatayama Hirofumi MZ     }
11849adc538cSKatayama Hirofumi MZ 
11859adc538cSKatayama Hirofumi MZ     hKL = GetKeyboardLayout(0);
11868ba378c9SKatayama Hirofumi MZ     if (IS_CICERO_MODE() && !IS_16BIT_MODE())
11879adc538cSKatayama Hirofumi MZ     {
118875cf6920SKatayama Hirofumi MZ         CtfImeSetActiveContextAlways(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     {
1202962c4557SKatayama Hirofumi MZ         SendMessageW(hWnd, WM_IME_SETCONTEXT, fActive, dwShowFlags);
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)
1210962c4557SKatayama Hirofumi MZ             SendMessageW(hwndDefIME, WM_IME_SETCONTEXT, 0, dwShowFlags);
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 
ImmWINNLSGetEnableStatus(HWND hWnd)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 
1231720da3b9SKatayama Hirofumi MZ     return !!ImmGetSaveContext(hWnd, 2);
12328cdfc245SKatayama Hirofumi MZ }
12338cdfc245SKatayama Hirofumi MZ 
12348cdfc245SKatayama Hirofumi MZ /***********************************************************************
1235b4557a60SKatayama Hirofumi MZ  *              ImmSetActiveContextConsoleIME(IMM32.@)
1236b4557a60SKatayama Hirofumi MZ  */
ImmSetActiveContextConsoleIME(HWND hwnd,BOOL fFlag)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);
1243c2a94365SKatayama Hirofumi MZ     if (IS_NULL_UNEXPECTEDLY(hIMC))
1244c2c66affSColin Finck         return FALSE;
1245c2a94365SKatayama Hirofumi MZ     return ImmSetActiveContext(hwnd, hIMC, fFlag);
1246c2c66affSColin Finck }
1247c2c66affSColin Finck 
1248d795021aSKatayama Hirofumi MZ /***********************************************************************
1249d795021aSKatayama Hirofumi MZ  *              GetKeyboardLayoutCP (IMM32.@)
1250d795021aSKatayama Hirofumi MZ  */
GetKeyboardLayoutCP(_In_ LANGID wLangId)1251d795021aSKatayama Hirofumi MZ UINT WINAPI GetKeyboardLayoutCP(_In_ LANGID wLangId)
1252d795021aSKatayama Hirofumi MZ {
1253d795021aSKatayama Hirofumi MZ     WCHAR szText[8];
1254d795021aSKatayama Hirofumi MZ     static LANGID s_wKeyboardLangIdCache = 0;
1255d795021aSKatayama Hirofumi MZ     static UINT s_uKeyboardLayoutCPCache = 0;
1256d795021aSKatayama Hirofumi MZ 
1257d795021aSKatayama Hirofumi MZ     TRACE("(%u)\n", wLangId);
1258d795021aSKatayama Hirofumi MZ 
1259d795021aSKatayama Hirofumi MZ     if (wLangId == s_wKeyboardLangIdCache)
1260d795021aSKatayama Hirofumi MZ         return s_uKeyboardLayoutCPCache;
1261d795021aSKatayama Hirofumi MZ 
1262d795021aSKatayama Hirofumi MZ     if (!GetLocaleInfoW(wLangId, LOCALE_IDEFAULTANSICODEPAGE, szText, _countof(szText)))
1263d795021aSKatayama Hirofumi MZ         return 0;
1264d795021aSKatayama Hirofumi MZ 
1265d795021aSKatayama Hirofumi MZ     s_wKeyboardLangIdCache = wLangId;
1266d795021aSKatayama Hirofumi MZ     szText[_countof(szText) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
1267d795021aSKatayama Hirofumi MZ     s_uKeyboardLayoutCPCache = wcstol(szText, NULL, 10);
1268d795021aSKatayama Hirofumi MZ     return s_uKeyboardLayoutCPCache;
1269d795021aSKatayama Hirofumi MZ }
1270d795021aSKatayama Hirofumi MZ 
1271c2a94365SKatayama Hirofumi MZ #ifndef NDEBUG
Imm32UnitTest(VOID)1272c2a94365SKatayama Hirofumi MZ VOID APIENTRY Imm32UnitTest(VOID)
1273c2a94365SKatayama Hirofumi MZ {
1274c2a94365SKatayama Hirofumi MZ     if (0)
1275c2a94365SKatayama Hirofumi MZ     {
1276c2a94365SKatayama Hirofumi MZ         DWORD dwValue;
1277c2a94365SKatayama Hirofumi MZ         WCHAR szText[64];
1278c2a94365SKatayama Hirofumi MZ 
1279c2a94365SKatayama Hirofumi MZ         Imm32StrToUInt(L"123", &dwValue, 10);
1280c2a94365SKatayama Hirofumi MZ         ASSERT(dwValue == 123);
1281c2a94365SKatayama Hirofumi MZ         Imm32StrToUInt(L"100", &dwValue, 16);
1282c2a94365SKatayama Hirofumi MZ         ASSERT(dwValue == 0x100);
1283c2a94365SKatayama Hirofumi MZ 
1284c2a94365SKatayama Hirofumi MZ         Imm32UIntToStr(123, 10, szText, _countof(szText));
1285c2a94365SKatayama Hirofumi MZ         ASSERT(lstrcmpW(szText, L"123") == 0);
1286c2a94365SKatayama Hirofumi MZ         Imm32UIntToStr(0x100, 16, szText, _countof(szText));
1287c2a94365SKatayama Hirofumi MZ         ASSERT(lstrcmpW(szText, L"100") == 0);
1288c2a94365SKatayama Hirofumi MZ     }
1289c2a94365SKatayama Hirofumi MZ }
1290c2a94365SKatayama Hirofumi MZ #endif
1291c2a94365SKatayama Hirofumi MZ 
1292692a30a8SKatayama Hirofumi MZ BOOL WINAPI User32InitializeImmEntryTable(DWORD);
1293692a30a8SKatayama Hirofumi MZ 
12942c244eafSHermès Bélusca-Maïto BOOL
12952c244eafSHermès Bélusca-Maïto WINAPI
ImmDllInitialize(_In_ HINSTANCE hDll,_In_ ULONG dwReason,_In_opt_ PVOID pReserved)12962c244eafSHermès Bélusca-Maïto ImmDllInitialize(
1297f73a4d6bSKatayama Hirofumi MZ     _In_ HINSTANCE hDll,
12982c244eafSHermès Bélusca-Maïto     _In_ ULONG dwReason,
12992c244eafSHermès Bélusca-Maïto     _In_opt_ PVOID pReserved)
1300692a30a8SKatayama Hirofumi MZ {
1301692a30a8SKatayama Hirofumi MZ     HKL hKL;
130277911014SKatayama Hirofumi MZ     HIMC hIMC;
1303692a30a8SKatayama Hirofumi MZ 
13042c244eafSHermès Bélusca-Maïto     TRACE("(%p, 0x%X, %p)\n", hDll, dwReason, pReserved);
1305692a30a8SKatayama Hirofumi MZ 
13062c244eafSHermès Bélusca-Maïto     switch (dwReason)
1307692a30a8SKatayama Hirofumi MZ     {
1308692a30a8SKatayama Hirofumi MZ         case DLL_PROCESS_ATTACH:
13092c244eafSHermès Bélusca-Maïto             if (!ImmInitializeGlobals(hDll))
1310692a30a8SKatayama Hirofumi MZ             {
1311a40f55bfSKatayama Hirofumi MZ                 ERR("ImmInitializeGlobals failed\n");
1312692a30a8SKatayama Hirofumi MZ                 return FALSE;
1313692a30a8SKatayama Hirofumi MZ             }
1314692a30a8SKatayama Hirofumi MZ             if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC))
1315692a30a8SKatayama Hirofumi MZ             {
1316692a30a8SKatayama Hirofumi MZ                 ERR("User32InitializeImmEntryTable failed\n");
1317692a30a8SKatayama Hirofumi MZ                 return FALSE;
1318692a30a8SKatayama Hirofumi MZ             }
1319c2a94365SKatayama Hirofumi MZ #ifndef NDEBUG
1320c2a94365SKatayama Hirofumi MZ             Imm32UnitTest();
1321c2a94365SKatayama Hirofumi MZ #endif
1322692a30a8SKatayama Hirofumi MZ             break;
1323692a30a8SKatayama Hirofumi MZ 
1324692a30a8SKatayama Hirofumi MZ         case DLL_THREAD_ATTACH:
1325692a30a8SKatayama Hirofumi MZ             break;
1326692a30a8SKatayama Hirofumi MZ 
1327692a30a8SKatayama Hirofumi MZ         case DLL_THREAD_DETACH:
132845a4e53fSKatayama Hirofumi MZ             if (!IS_IMM_MODE() || NtCurrentTeb()->Win32ThreadInfo == NULL)
1329692a30a8SKatayama Hirofumi MZ                 return TRUE;
1330692a30a8SKatayama Hirofumi MZ 
1331692a30a8SKatayama Hirofumi MZ             hKL = GetKeyboardLayout(0);
133241b87158SKatayama Hirofumi MZ             hIMC = (HIMC)NtUserGetThreadState(THREADSTATE_DEFAULTINPUTCONTEXT);
1333f8902dc3SKatayama Hirofumi MZ             Imm32DestroyInputContext(hIMC, hKL, TRUE);
1334692a30a8SKatayama Hirofumi MZ             break;
1335692a30a8SKatayama Hirofumi MZ 
1336692a30a8SKatayama Hirofumi MZ         case DLL_PROCESS_DETACH:
1337895909e6SKatayama Hirofumi MZ             RtlDeleteCriticalSection(&gcsImeDpi);
13382ab858c1SKatayama Hirofumi MZ             TRACE("imm32.dll is unloaded\n");
1339692a30a8SKatayama Hirofumi MZ             break;
1340692a30a8SKatayama Hirofumi MZ     }
1341692a30a8SKatayama Hirofumi MZ 
1342692a30a8SKatayama Hirofumi MZ     return TRUE;
1343692a30a8SKatayama Hirofumi MZ }
1344