ReactOS 0.4.16-dev-1260-g901af6a
imm.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS IMM32
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Implementing Far-Eastern languages input
5 * COPYRIGHT: Copyright 1998 Patrik Stridvall
6 * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
7 * Copyright 2017 James Tabor <james.tabor@reactos.org>
8 * Copyright 2018 Amine Khaldi <amine.khaldi@reactos.org>
9 * Copyright 2020-2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
10 */
11
12#include "precomp.h"
13#include <ndk/exfuncs.h>
14
16
17HMODULE ghImm32Inst = NULL; /* The IMM32 instance */
20BYTE gfImmInitialized = FALSE; /* Is IMM32 initialized? */
22
24{
27
28 if (hMod)
29 ghImm32Inst = hMod;
30
32 return TRUE;
33
35 if (NT_ERROR(status))
36 {
37 ERR("\n");
38 return FALSE;
39 }
40
41 status = NtQuerySystemInformation(SystemBasicInformation, &SysInfo, sizeof(SysInfo), NULL);
42 if (NT_ERROR(status))
43 {
44 ERR("\n");
45 return FALSE;
46 }
48
50 return TRUE;
51}
52
53/***********************************************************************
54 * ImmRegisterClient(IMM32.@)
55 * ( Undocumented, called from user32.dll )
56 */
60 _In_ HINSTANCE hMod)
61{
64 return ImmInitializeGlobals(hMod);
65}
66
67/***********************************************************************
68 * ImmLoadLayout (IMM32.@)
69 */
72 _In_ HKL hKL,
73 _Inout_ PIMEINFOEX pImeInfoEx)
74{
75 DWORD cbData, dwType;
76 HKEY hKey;
78 WCHAR szLayout[MAX_PATH];
79 LPCWSTR pszSubKey;
80
81 TRACE("(%p, %p)\n", hKL, pImeInfoEx);
82
83 /* Choose a key */
84 if (IS_IME_HKL(hKL) || !IS_CICERO_MODE() || IS_16BIT_MODE()) /* Non-Cicero? */
85 {
86 StringCchPrintfW(szLayout, _countof(szLayout), L"%s\\%08lX",
88 pszSubKey = szLayout;
89 }
90 else /* Cicero */
91 {
92 pszSubKey = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\IMM";
93 }
94
95 /* Open the key */
98 return FALSE;
99
100 /* Load "IME File" value */
101 cbData = sizeof(pImeInfoEx->wszImeFile);
102 error = RegQueryValueExW(hKey, L"IME File", NULL, &dwType,
103 (LPBYTE)pImeInfoEx->wszImeFile, &cbData);
104
105 /* Avoid buffer overrun */
106 pImeInfoEx->wszImeFile[_countof(pImeInfoEx->wszImeFile) - 1] = UNICODE_NULL;
107
109
110 if (error != ERROR_SUCCESS || dwType != REG_SZ)
111 return FALSE; /* Failed */
112
113 pImeInfoEx->hkl = hKL;
114 pImeInfoEx->fLoadFlag = 0;
115 return Imm32LoadImeVerInfo(pImeInfoEx);
116}
117
118/***********************************************************************
119 * ImmFreeLayout (IMM32.@)
120 *
121 * NOTE: HKL_SWITCH_TO_NON_IME and HKL_RELEASE_IME are special values for hKL.
122 */
125{
126 WCHAR szKBD[KL_NAMELENGTH];
127 UINT iKL, cKLs;
128 HKL hOldKL, *pList;
129 PIMEDPI pImeDpi;
131
132 TRACE("(%p)\n", hKL);
133
134 hOldKL = GetKeyboardLayout(0);
135
136 if (hKL == HKL_SWITCH_TO_NON_IME)
137 {
138 if (!IS_IME_HKL(hOldKL))
139 return TRUE;
140
142
143 cKLs = GetKeyboardLayoutList(0, NULL);
144 if (cKLs)
145 {
146 pList = ImmLocalAlloc(0, cKLs * sizeof(HKL));
148 return FALSE;
149
150 cKLs = GetKeyboardLayoutList(cKLs, pList);
151 for (iKL = 0; iKL < cKLs; ++iKL)
152 {
153 if (!IS_IME_HKL(pList[iKL]))
154 {
155 LangID = LOWORD(pList[iKL]);
156 break;
157 }
158 }
159
161 }
162
163 StringCchPrintfW(szKBD, _countof(szKBD), L"%08X", LangID);
165 {
166 WARN("Default to English US\n");
167 LoadKeyboardLayoutW(L"00000409", KLF_ACTIVATE | 0x200);
168 }
169 }
170 else if (hKL == HKL_RELEASE_IME)
171 {
173Retry:
174 for (pImeDpi = gpImeDpiList; pImeDpi; pImeDpi = pImeDpi->pNext)
175 {
176 if (Imm32ReleaseIME(pImeDpi->hKL))
177 goto Retry;
178 }
180 }
181 else
182 {
183 if (IS_IME_HKL(hKL) && hKL != hOldKL)
184 Imm32ReleaseIME(hKL);
185 }
186
187 return TRUE;
188}
189
190static VOID
191Imm32SelectInputContext(HKL hNewKL, HKL hOldKL, HIMC hIMC)
192{
193 PCLIENTIMC pClientImc;
195 LPGUIDELINE pGL;
196 LPCANDIDATEINFO pCI;
198 LOGFONTA LogFontA;
199 LOGFONTW LogFontW;
200 BOOL fOldOpen, bIsNewHKLIme = TRUE, bIsOldHKLIme = TRUE, bClientWide, bNewDpiWide;
201 DWORD cbNewPrivate = 0, cbOldPrivate = 0, dwOldConversion, dwOldSentence, dwSize, dwNewSize;
202 PIMEDPI pNewImeDpi = NULL, pOldImeDpi = NULL;
203 HANDLE hPrivate;
204 PIME_STATE pNewState = NULL, pOldState = NULL;
205
206 pClientImc = ImmLockClientImc(hIMC);
207 if (IS_NULL_UNEXPECTEDLY(pClientImc))
208 return;
209
210 pNewImeDpi = ImmLockImeDpi(hNewKL);
211
212 if (hNewKL != hOldKL)
213 pOldImeDpi = ImmLockImeDpi(hOldKL);
214
215 if (pNewImeDpi)
216 {
217 cbNewPrivate = pNewImeDpi->ImeInfo.dwPrivateDataSize;
218 pClientImc->uCodePage = pNewImeDpi->uCodePage;
219 }
220 else
221 {
222 pClientImc->uCodePage = CP_ACP;
223 }
224
225 if (pOldImeDpi)
226 cbOldPrivate = pOldImeDpi->ImeInfo.dwPrivateDataSize;
227
228 cbNewPrivate = max(cbNewPrivate, sizeof(DWORD));
229 cbOldPrivate = max(cbOldPrivate, sizeof(DWORD));
230
231 if (pClientImc->hKL == hOldKL)
232 {
233 if (pOldImeDpi)
234 {
235 if (IS_IME_HKL(hOldKL))
236 pOldImeDpi->ImeSelect(hIMC, FALSE);
237 else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
238 pOldImeDpi->CtfImeSelectEx(hIMC, FALSE, hOldKL);
239 }
240 pClientImc->hKL = NULL;
241 }
242
244 {
245 bIsNewHKLIme = IS_IME_HKL(hNewKL);
246 bIsOldHKLIme = IS_IME_HKL(hOldKL);
247 }
248
250 if (!pIC)
251 {
252 if (pNewImeDpi)
253 {
254 if (IS_IME_HKL(hNewKL))
255 pNewImeDpi->ImeSelect(hIMC, TRUE);
256 else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
257 pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
258
259 pClientImc->hKL = hNewKL;
260 }
261 }
262 else
263 {
264 dwOldConversion = pIC->fdwConversion;
265 dwOldSentence = pIC->fdwSentence;
266 fOldOpen = pIC->fOpen;
267
268 if (pNewImeDpi)
269 {
270 bClientWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
271 bNewDpiWide = ImeDpi_IsUnicode(pNewImeDpi);
272 if (bClientWide && !bNewDpiWide)
273 {
274 if (pIC->fdwInit & INIT_LOGFONT)
275 {
276 LogFontWideToAnsi(&pIC->lfFont.W, &LogFontA);
277 pIC->lfFont.A = LogFontA;
278 }
279 pClientImc->dwFlags &= ~CLIENTIMC_WIDE;
280 }
281 else if (!bClientWide && bNewDpiWide)
282 {
283 if (pIC->fdwInit & INIT_LOGFONT)
284 {
285 LogFontAnsiToWide(&pIC->lfFont.A, &LogFontW);
286 pIC->lfFont.W = LogFontW;
287 }
288 pClientImc->dwFlags |= CLIENTIMC_WIDE;
289 }
290 }
291
292 if (cbOldPrivate != cbNewPrivate)
293 {
294 hPrivate = ImmReSizeIMCC(pIC->hPrivate, cbNewPrivate);
295 if (!hPrivate)
296 {
297 ImmDestroyIMCC(pIC->hPrivate);
298 hPrivate = ImmCreateIMCC(cbNewPrivate);
299 }
300 pIC->hPrivate = hPrivate;
301 }
302
303#define MAX_IMCC_SIZE 0x1000
304 dwSize = ImmGetIMCCSize(pIC->hMsgBuf);
305 if (ImmGetIMCCLockCount(pIC->hMsgBuf) || dwSize > MAX_IMCC_SIZE)
306 {
307 ImmDestroyIMCC(pIC->hMsgBuf);
308 pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
309 pIC->dwNumMsgBuf = 0;
310 }
311
312 dwSize = ImmGetIMCCSize(pIC->hGuideLine);
313 dwNewSize = sizeof(GUIDELINE);
314 if (ImmGetIMCCLockCount(pIC->hGuideLine) ||
315 dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
316 {
317 ImmDestroyIMCC(pIC->hGuideLine);
318 pIC->hGuideLine = ImmCreateIMCC(dwNewSize);
319 pGL = ImmLockIMCC(pIC->hGuideLine);
320 if (pGL)
321 {
322 pGL->dwSize = dwNewSize;
323 ImmUnlockIMCC(pIC->hGuideLine);
324 }
325 }
326
327 dwSize = ImmGetIMCCSize(pIC->hCandInfo);
328 dwNewSize = sizeof(CANDIDATEINFO);
329 if (ImmGetIMCCLockCount(pIC->hCandInfo) ||
330 dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
331 {
332 ImmDestroyIMCC(pIC->hCandInfo);
333 pIC->hCandInfo = ImmCreateIMCC(dwNewSize);
334 pCI = ImmLockIMCC(pIC->hCandInfo);
335 if (pCI)
336 {
337 pCI->dwSize = dwNewSize;
338 ImmUnlockIMCC(pIC->hCandInfo);
339 }
340 }
341
342 dwSize = ImmGetIMCCSize(pIC->hCompStr);
343 dwNewSize = sizeof(COMPOSITIONSTRING);
344 if (ImmGetIMCCLockCount(pIC->hCompStr) ||
345 dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
346 {
347 ImmDestroyIMCC(pIC->hCompStr);
348 pIC->hCompStr = ImmCreateIMCC(dwNewSize);
349 pCS = ImmLockIMCC(pIC->hCompStr);
350 if (pCS)
351 {
352 pCS->dwSize = dwNewSize;
353 ImmUnlockIMCC(pIC->hCompStr);
354 }
355 }
356#undef MAX_IMCC_SIZE
357
358 if (pOldImeDpi && bIsOldHKLIme)
359 {
360 pOldState = Imm32FetchImeState(pIC, hOldKL);
361 if (pOldState)
362 Imm32SaveImeStateSentence(pIC, pOldState, hOldKL);
363 }
364
365 if (pNewImeDpi && bIsNewHKLIme)
366 pNewState = Imm32FetchImeState(pIC, hNewKL);
367
368 if (pOldState != pNewState)
369 {
370 if (pOldState)
371 {
372 pOldState->fOpen = !!pIC->fOpen;
373 pOldState->dwConversion = pIC->fdwConversion;
374 pOldState->dwConversion &= ~IME_CMODE_EUDC;
375 pOldState->dwSentence = pIC->fdwSentence;
376 pOldState->dwInit = pIC->fdwInit;
377 }
378
379 if (pNewState)
380 {
382 {
383 pIC->dwChange &= ~INPUTCONTEXTDX_CHANGE_FORCE_OPEN;
384 pIC->fOpen = TRUE;
385 }
386 else
387 {
388 pIC->fOpen = pNewState->fOpen;
389 }
390
391 pIC->fdwConversion = pNewState->dwConversion;
392 pIC->fdwConversion &= ~IME_CMODE_EUDC;
393 pIC->fdwSentence = pNewState->dwSentence;
394 pIC->fdwInit = pNewState->dwInit;
395 }
396 }
397
398 if (pNewState)
399 Imm32LoadImeStateSentence(pIC, pNewState, hNewKL);
400
401 if (pNewImeDpi)
402 {
403 if (IS_IME_HKL(hNewKL))
404 pNewImeDpi->ImeSelect(hIMC, TRUE);
405 else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
406 pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
407
408 pClientImc->hKL = hNewKL;
409 }
410
411 pIC->dwChange = 0;
412 if (pIC->fOpen != fOldOpen)
414 if (pIC->fdwConversion != dwOldConversion)
416 if (pIC->fdwSentence != dwOldSentence)
418
419 ImmUnlockIMC(hIMC);
420 }
421
422 ImmUnlockImeDpi(pOldImeDpi);
423 ImmUnlockImeDpi(pNewImeDpi);
424 ImmUnlockClientImc(pClientImc);
425}
426
427typedef struct SELECT_LAYOUT
428{
432
434{
436 Imm32SelectInputContext(pSelect->hNewKL, pSelect->hOldKL, hIMC);
437 return TRUE;
438}
439
441{
443 return TRUE;
444}
445
446/***********************************************************************
447 * ImmActivateLayout (IMM32.@)
448 */
451{
452 PIMEDPI pImeDpi;
453 HKL hOldKL;
455 HWND hwndDefIME = NULL;
456 SELECT_LAYOUT SelectLayout;
457
458 hOldKL = GetKeyboardLayout(0);
459
460 if (hOldKL == hKL && !(GetWin32ClientInfo()->CI_flags & CI_IMMACTIVATE))
461 return TRUE;
462
463 ImmLoadIME(hKL);
464
465 if (hOldKL != hKL)
466 {
467 pImeDpi = ImmLockImeDpi(hOldKL);
468 if (pImeDpi)
469 {
472 else
474 ImmUnlockImeDpi(pImeDpi);
475
477 }
478
479 hwndDefIME = ImmGetDefaultIMEWnd(NULL);
480 if (IsWindow(hwndDefIME))
481 SendMessageW(hwndDefIME, WM_IME_SELECT, FALSE, (LPARAM)hOldKL);
482
483 NtUserSetThreadLayoutHandles(hKL, hOldKL);
484 }
485
486 SelectLayout.hNewKL = hKL;
487 SelectLayout.hOldKL = hOldKL;
489
490 if (IsWindow(hwndDefIME))
491 SendMessageW(hwndDefIME, WM_IME_SELECT, TRUE, (LPARAM)hKL);
492
493 return TRUE;
494}
495
496/***********************************************************************
497 * ImmAssociateContext (IMM32.@)
498 */
501 _In_ HWND hWnd,
502 _In_opt_ HIMC hIMC)
503{
504 PWND pWnd;
505 HWND hwndFocus;
506 DWORD dwValue;
507 HIMC hOldIMC;
508
509 TRACE("(%p, %p)\n", hWnd, hIMC);
510
511 if (!IS_IMM_MODE())
512 {
513 TRACE("\n");
514 return NULL;
515 }
516
517 pWnd = ValidateHwnd(hWnd);
518 if (IS_NULL_UNEXPECTEDLY(pWnd))
519 return NULL;
520
521 if (hIMC && IS_CROSS_THREAD_HIMC(hIMC))
522 return NULL;
523
524 hOldIMC = pWnd->hImc;
525 if (hOldIMC == hIMC)
526 return hIMC;
527
528 dwValue = NtUserAssociateInputContext(hWnd, hIMC, 0);
529 switch (dwValue)
530 {
531 case 0:
532 return hOldIMC;
533
534 case 1:
536 if (hwndFocus == hWnd)
537 {
538 ImmSetActiveContext(hWnd, hOldIMC, FALSE);
540 }
541 return hOldIMC;
542
543 default:
544 return NULL;
545 }
546}
547
548/***********************************************************************
549 * ImmAssociateContextEx (IMM32.@)
550 */
553 _In_ HWND hWnd,
554 _In_opt_ HIMC hIMC,
556{
557 HWND hwndFocus;
559 HIMC hOldIMC = NULL;
560 DWORD dwValue;
561
562 TRACE("(%p, %p, 0x%lX)\n", hWnd, hIMC, dwFlags);
563
564 if (!IS_IMM_MODE())
565 {
566 TRACE("\n");
567 return FALSE;
568 }
569
570 if (hIMC && !(dwFlags & IACE_DEFAULT) && IS_CROSS_THREAD_HIMC(hIMC))
571 return FALSE;
572
574 pFocusWnd = ValidateHwnd(hwndFocus);
575 if (pFocusWnd)
576 hOldIMC = pFocusWnd->hImc;
577
578 dwValue = NtUserAssociateInputContext(hWnd, hIMC, dwFlags);
579 switch (dwValue)
580 {
581 case 0:
582 return TRUE;
583
584 case 1:
585 pFocusWnd = ValidateHwnd(hwndFocus);
586 if (pFocusWnd)
587 {
588 hIMC = pFocusWnd->hImc;
589 if (hIMC != hOldIMC)
590 {
591 ImmSetActiveContext(hwndFocus, hOldIMC, FALSE);
592 ImmSetActiveContext(hwndFocus, hIMC, TRUE);
593 }
594 }
595 return TRUE;
596
597 default:
598 return FALSE;
599 }
600}
601
602/***********************************************************************
603 * ImmCreateContext (IMM32.@)
604 */
607{
608 PCLIENTIMC pClientImc;
609 HIMC hIMC;
610
611 TRACE("()\n");
612
613 if (!IS_IMM_MODE())
614 {
615 TRACE("\n");
616 return NULL;
617 }
618
619 pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
620 if (IS_NULL_UNEXPECTEDLY(pClientImc))
621 return NULL;
622
623 hIMC = NtUserCreateInputContext((ULONG_PTR)pClientImc);
624 if (IS_NULL_UNEXPECTEDLY(hIMC))
625 {
626 ImmLocalFree(pClientImc);
627 return NULL;
628 }
629
630 RtlInitializeCriticalSection(&pClientImc->cs);
631
633
634 return hIMC;
635}
636
637static VOID
639{
640 PIME_STATE pState, pNext;
641 PIME_SUBSTATE pSubState, pSubNext;
642
643 for (pState = pIC->pState; pState; pState = pNext)
644 {
645 pNext = pState->pNext;
646
647 for (pSubState = pState->pSubState; pSubState; pSubState = pSubNext)
648 {
649 pSubNext = pSubState->pNext;
650 ImmLocalFree(pSubState);
651 }
652
653 ImmLocalFree(pState);
654 }
655
656 pIC->pState = NULL;
657}
658
659static BOOL
661{
662 PIMEDPI pImeDpi;
664 PCLIENTIMC pClientImc;
665 PIMC pIMC;
666
667 if (hIMC == NULL)
668 return FALSE;
669
670 if (!IS_IMM_MODE())
671 {
672 TRACE("\n");
673 return FALSE;
674 }
675
676 pIMC = ValidateHandle(hIMC, TYPE_INPUTCONTEXT);
677 if (IS_NULL_UNEXPECTEDLY(pIMC))
678 return FALSE;
679
680 if (pIMC->head.pti != Imm32CurrentPti())
681 {
682 ERR("Thread mismatch\n");
683 return FALSE;
684 }
685
686 pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
687 if (pClientImc == NULL)
688 {
689 TRACE("pClientImc == NULL\n");
690 goto Finish;
691 }
692
693 if ((pClientImc->dwFlags & CLIENTIMC_UNKNOWN2) && !bKeep)
694 {
695 ERR("Can't destroy for CLIENTIMC_UNKNOWN2\n");
696 return FALSE;
697 }
698
699 if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
700 return TRUE;
701
702 InterlockedIncrement(&pClientImc->cLockObj);
703
704 if (IS_NULL_UNEXPECTEDLY(pClientImc->hInputContext))
705 goto Quit;
706
707 pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
708 if (IS_NULL_UNEXPECTEDLY(pIC))
709 {
710 ImmUnlockClientImc(pClientImc);
711 return FALSE;
712 }
713
715
716 if (pClientImc->hKL == hKL)
717 {
718 pImeDpi = ImmLockImeDpi(hKL);
719 if (pImeDpi)
720 {
721 if (IS_IME_HKL(hKL))
722 pImeDpi->ImeSelect(hIMC, FALSE);
723 else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
724 pImeDpi->CtfImeSelectEx(hIMC, FALSE, hKL);
725
726 ImmUnlockImeDpi(pImeDpi);
727 }
728
729 pClientImc->hKL = NULL;
730 }
731
732 ImmDestroyIMCC(pIC->hPrivate);
733 ImmDestroyIMCC(pIC->hMsgBuf);
734 ImmDestroyIMCC(pIC->hGuideLine);
735 ImmDestroyIMCC(pIC->hCandInfo);
736 ImmDestroyIMCC(pIC->hCompStr);
738 ImmUnlockIMC(hIMC);
739
740Quit:
741 pClientImc->dwFlags |= CLIENTIMC_DESTROY;
742 ImmUnlockClientImc(pClientImc);
743
744Finish:
745 if (bKeep)
746 return TRUE;
747 return NtUserDestroyInputContext(hIMC);
748}
749
750// NOTE: Windows does recursive call ImmLockIMC here but we don't do so.
751static BOOL
752Imm32CreateInputContext(HIMC hIMC, LPINPUTCONTEXT pIC, PCLIENTIMC pClientImc, HKL hKL, BOOL fSelect)
753{
754 DWORD dwIndex, cbPrivate;
755 PIMEDPI pImeDpi = NULL;
757 LPCANDIDATEINFO pCI;
758 LPGUIDELINE pGL;
759
760 /* Create IC components */
762 pIC->hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
763 pIC->hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
764 pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
765 if (IS_NULL_UNEXPECTEDLY(pIC->hCompStr) ||
769 {
770 goto Fail;
771 }
772
773 /* Initialize IC components */
774 pCS = ImmLockIMCC(pIC->hCompStr);
775 if (IS_NULL_UNEXPECTEDLY(pCS))
776 goto Fail;
777 pCS->dwSize = sizeof(COMPOSITIONSTRING);
779
780 pCI = ImmLockIMCC(pIC->hCandInfo);
781 if (IS_NULL_UNEXPECTEDLY(pCI))
782 goto Fail;
783 pCI->dwSize = sizeof(CANDIDATEINFO);
785
786 pGL = ImmLockIMCC(pIC->hGuideLine);
787 if (IS_NULL_UNEXPECTEDLY(pGL))
788 goto Fail;
789 pGL->dwSize = sizeof(GUIDELINE);
791
792 pIC->dwNumMsgBuf = 0;
793 pIC->fOpen = FALSE;
794 pIC->fdwConversion = pIC->fdwSentence = 0;
795
796 for (dwIndex = 0; dwIndex < MAX_CANDIDATEFORM; ++dwIndex)
798
799 /* Get private data size */
800 pImeDpi = ImmLockImeDpi(hKL);
801 if (!pImeDpi)
802 {
803 cbPrivate = sizeof(DWORD);
804 }
805 else
806 {
807 /* Update CLIENTIMC */
808 pClientImc->uCodePage = pImeDpi->uCodePage;
809 if (ImeDpi_IsUnicode(pImeDpi))
810 pClientImc->dwFlags |= CLIENTIMC_WIDE;
811
812 cbPrivate = pImeDpi->ImeInfo.dwPrivateDataSize;
813 }
814
815 /* Create private data */
816 pIC->hPrivate = ImmCreateIMCC(cbPrivate);
818 goto Fail;
819
821
822 if (pImeDpi)
823 {
824 /* Select the IME */
825 if (fSelect)
826 {
827 if (IS_IME_HKL(hKL))
828 pImeDpi->ImeSelect(hIMC, TRUE);
829 else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
830 pImeDpi->CtfImeSelectEx(hIMC, TRUE, hKL);
831 }
832
833 /* Set HKL */
834 pClientImc->hKL = hKL;
835
836 ImmUnlockImeDpi(pImeDpi);
837 }
838
839 return TRUE;
840
841Fail:
842 if (pImeDpi)
843 ImmUnlockImeDpi(pImeDpi);
844
845 pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
848 pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
849 return FALSE;
850}
851
853{
854 HANDLE hIC;
855 LPINPUTCONTEXT pIC = NULL;
856 PCLIENTIMC pClientImc;
857 WORD LangID;
859 HKL hOldKL, hNewKL;
860 PIMEDPI pImeDpi = NULL;
861
862 pClientImc = ImmLockClientImc(hIMC);
863 if (!pClientImc)
864 return NULL;
865
866 RtlEnterCriticalSection(&pClientImc->cs);
867
868 if (pClientImc->hInputContext)
869 {
870 pIC = LocalLock(pClientImc->hInputContext);
871 if (IS_NULL_UNEXPECTEDLY(pIC))
872 goto Failure;
873
875 goto Success;
876 }
877
880 {
881 hOldKL = GetKeyboardLayout(0);
882 LangID = LOWORD(hOldKL);
884
885 pImeDpi = Imm32FindOrLoadImeDpi(hNewKL);
886 if (pImeDpi)
887 {
888 CtfImmTIMActivate(hNewKL);
889 }
890 }
891
893 {
894 ERR("No default IME window\n");
895 goto Failure;
896 }
897
898 hIC = LocalAlloc(LHND, sizeof(INPUTCONTEXTDX));
899 pIC = LocalLock(hIC);
900 if (IS_NULL_UNEXPECTEDLY(pIC))
901 {
902 LocalFree(hIC);
903 goto Failure;
904 }
905 pClientImc->hInputContext = hIC;
906
908 if (!Imm32CreateInputContext(hIMC, pIC, pClientImc, hNewKL, fSelect))
909 {
910 LocalUnlock(hIC);
911 pClientImc->hInputContext = LocalFree(hIC);
912 goto Failure;
913 }
914
915Success:
916 RtlLeaveCriticalSection(&pClientImc->cs);
917 InterlockedIncrement(&pClientImc->cLockObj);
918 ImmUnlockClientImc(pClientImc);
919 return pIC;
920
921Failure:
922 RtlLeaveCriticalSection(&pClientImc->cs);
923 ImmUnlockClientImc(pClientImc);
924 return NULL;
925}
926
927/***********************************************************************
928 * ImmDestroyContext (IMM32.@)
929 */
932{
933 HKL hKL;
934
935 TRACE("(%p)\n", hIMC);
936
937 if (!IS_IMM_MODE())
938 {
939 TRACE("\n");
940 return FALSE;
941 }
942
943 if (IS_CROSS_THREAD_HIMC(hIMC))
944 return FALSE;
945
946 hKL = GetKeyboardLayout(0);
947 return Imm32DestroyInputContext(hIMC, hKL, FALSE);
948}
949
950/***********************************************************************
951 * ImmLockClientImc (IMM32.@)
952 */
955{
956 PIMC pIMC;
957 PCLIENTIMC pClientImc;
958
959 TRACE("(%p)\n", hImc);
960
961 if (IS_NULL_UNEXPECTEDLY(hImc))
962 return NULL;
963
964 pIMC = ValidateHandle(hImc, TYPE_INPUTCONTEXT);
965 if (!pIMC || !Imm32CheckImcProcess(pIMC))
966 return NULL;
967
968 pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
969 if (pClientImc)
970 {
971 if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
972 return NULL;
973 goto Finish;
974 }
975
976 pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
977 if (IS_NULL_UNEXPECTEDLY(pClientImc))
978 return NULL;
979
980 RtlInitializeCriticalSection(&pClientImc->cs);
982
984 {
985 ERR("\n");
986 ImmLocalFree(pClientImc);
987 return NULL;
988 }
989
990 pClientImc->dwFlags |= CLIENTIMC_UNKNOWN2;
991
992Finish:
993 InterlockedIncrement(&pClientImc->cLockObj);
994 return pClientImc;
995}
996
997/***********************************************************************
998 * ImmUnlockClientImc (IMM32.@)
999 */
1002{
1003 LONG cLocks;
1004 HANDLE hInputContext;
1005
1006 TRACE("(%p)\n", pClientImc);
1007
1008 cLocks = InterlockedDecrement(&pClientImc->cLockObj);
1009 if (cLocks != 0 || !(pClientImc->dwFlags & CLIENTIMC_DESTROY))
1010 return;
1011
1012 hInputContext = pClientImc->hInputContext;
1013 if (hInputContext)
1014 LocalFree(hInputContext);
1015
1016 RtlDeleteCriticalSection(&pClientImc->cs);
1017 ImmLocalFree(pClientImc);
1018}
1019
1020static HIMC
1023 _In_ DWORD dwContextFlags)
1024{
1025 HIMC hIMC;
1026 PCLIENTIMC pClientImc;
1027 PWND pWnd;
1028
1029 if (!IS_IMM_MODE())
1030 {
1031 TRACE("Not IMM mode.\n");
1032 return NULL;
1033 }
1034
1035 if (!hWnd)
1036 {
1038 goto Quit;
1039 }
1040
1041 pWnd = ValidateHwnd(hWnd);
1043 return NULL;
1044
1045 hIMC = pWnd->hImc;
1046 if (!hIMC && (dwContextFlags & 1))
1048
1049Quit:
1050 pClientImc = ImmLockClientImc(hIMC);
1051 if (IS_NULL_UNEXPECTEDLY(pClientImc))
1052 return NULL;
1053
1054 if ((dwContextFlags & 2) && (pClientImc->dwFlags & CLIENTIMC_DISABLEIME))
1055 hIMC = NULL;
1056
1057 ImmUnlockClientImc(pClientImc);
1058 return hIMC;
1059}
1060
1061/***********************************************************************
1062 * ImmGetContext (IMM32.@)
1063 */
1066{
1067 TRACE("(%p)\n", hWnd);
1069 return NULL;
1070 return ImmGetSaveContext(hWnd, 2);
1071}
1072
1073/***********************************************************************
1074 * ImmLockIMC(IMM32.@)
1075 *
1076 * NOTE: This is not ImmLockIMCC. Don't confuse.
1077 */
1080{
1081 TRACE("(%p)\n", hIMC);
1082 return Imm32InternalLockIMC(hIMC, TRUE);
1083}
1084
1085/***********************************************************************
1086* ImmUnlockIMC(IMM32.@)
1087*/
1090{
1091 PCLIENTIMC pClientImc;
1092
1093 pClientImc = ImmLockClientImc(hIMC);
1094 if (IS_NULL_UNEXPECTEDLY(pClientImc))
1095 return FALSE;
1096
1097 if (pClientImc->hInputContext)
1098 LocalUnlock(pClientImc->hInputContext);
1099
1100 InterlockedDecrement(&pClientImc->cLockObj);
1101 ImmUnlockClientImc(pClientImc);
1102 return TRUE;
1103}
1104
1105/***********************************************************************
1106 * ImmReleaseContext (IMM32.@)
1107 */
1110 _In_ HWND hWnd,
1111 _In_ HIMC hIMC)
1112{
1113 TRACE("(%p, %p)\n", hWnd, hIMC);
1116 return TRUE; // Do nothing. This is correct.
1117}
1118
1119/***********************************************************************
1120 * ImmEnumInputContext(IMM32.@)
1121 */
1125 _In_ IMCENUMPROC lpfn,
1127{
1128 HIMC *phList;
1129 DWORD dwIndex, dwCount;
1130 BOOL ret = TRUE;
1131 HIMC hIMC;
1132
1133 TRACE("(%lu, %p, %p)\n", dwThreadId, lpfn, lParam);
1134
1135 dwCount = Imm32BuildHimcList(dwThreadId, &phList);
1136 if (IS_ZERO_UNEXPECTEDLY(dwCount))
1137 return FALSE;
1138
1139 for (dwIndex = 0; dwIndex < dwCount; ++dwIndex)
1140 {
1141 hIMC = phList[dwIndex];
1142 ret = (*lpfn)(hIMC, lParam);
1143 if (!ret)
1144 break;
1145 }
1146
1147 ImmLocalFree(phList);
1148 return ret;
1149}
1150
1151/***********************************************************************
1152 * ImmSetActiveContext(IMM32.@)
1153 */
1156 _In_ HWND hWnd,
1157 _In_opt_ HIMC hIMC,
1158 _In_ BOOL fActive)
1159{
1160 PCLIENTIMC pClientImc;
1161 LPINPUTCONTEXTDX pIC;
1162 PIMEDPI pImeDpi;
1163 HIMC hOldIMC;
1164 HKL hKL;
1165 BOOL fOpen = FALSE;
1166 DWORD dwConversion = 0, dwShowFlags = ISC_SHOWUIALL;
1167 HWND hwndDefIME;
1168
1169 TRACE("(%p, %p, %d)\n", hWnd, hIMC, fActive);
1170
1171 if (!IS_IMM_MODE())
1172 {
1173 TRACE("\n");
1174 return FALSE;
1175 }
1176
1177 pClientImc = ImmLockClientImc(hIMC);
1178
1179 if (!fActive)
1180 {
1181 if (pClientImc)
1182 pClientImc->dwFlags &= ~CLIENTIMC_ACTIVE;
1183 }
1184 else if (hIMC)
1185 {
1186 if (IS_NULL_UNEXPECTEDLY(pClientImc))
1187 return FALSE;
1188
1189 pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
1190 if (IS_NULL_UNEXPECTEDLY(pIC))
1191 {
1192 ImmUnlockClientImc(pClientImc);
1193 return FALSE;
1194 }
1195
1196 pIC->hWnd = hWnd;
1197 pClientImc->dwFlags |= CLIENTIMC_ACTIVE;
1198
1199 if (pIC->dwUIFlags & 2)
1201
1202 fOpen = pIC->fOpen;
1203 dwConversion = pIC->fdwConversion;
1204
1205 ImmUnlockIMC(hIMC);
1206 }
1207 else
1208 {
1209 hOldIMC = ImmGetSaveContext(hWnd, 1);
1210 pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hOldIMC);
1211 if (pIC)
1212 {
1213 pIC->hWnd = hWnd;
1214 ImmUnlockIMC(hOldIMC);
1215 }
1216 }
1217
1218 hKL = GetKeyboardLayout(0);
1219 if (IS_CICERO_MODE() && !IS_16BIT_MODE())
1220 {
1221 CtfImeSetActiveContextAlways(hIMC, fActive, hWnd, hKL);
1222 hKL = GetKeyboardLayout(0);
1223 }
1224
1225 pImeDpi = ImmLockImeDpi(hKL);
1226 if (pImeDpi)
1227 {
1228 if (IS_IME_HKL(hKL))
1229 pImeDpi->ImeSetActiveContext(hIMC, fActive);
1230 ImmUnlockImeDpi(pImeDpi);
1231 }
1232
1233 if (IsWindow(hWnd))
1234 {
1235 SendMessageW(hWnd, WM_IME_SETCONTEXT, fActive, dwShowFlags);
1236 if (fActive)
1237 NtUserNotifyIMEStatus(hWnd, fOpen, dwConversion);
1238 }
1239 else if (!fActive)
1240 {
1241 hwndDefIME = ImmGetDefaultIMEWnd(NULL);
1242 if (hwndDefIME)
1243 SendMessageW(hwndDefIME, WM_IME_SETCONTEXT, 0, dwShowFlags);
1244 }
1245
1246 if (pClientImc)
1247 ImmUnlockClientImc(pClientImc);
1248
1249 return TRUE;
1250}
1251
1252/***********************************************************************
1253 * ImmWINNLSGetEnableStatus (IMM32.@)
1254 */
1257{
1259 {
1261 return FALSE;
1262 }
1263
1264 return !!ImmGetSaveContext(hWnd, 2);
1265}
1266
1267/***********************************************************************
1268 * ImmSetActiveContextConsoleIME(IMM32.@)
1269 */
1272 _In_ HWND hwnd,
1273 _In_ BOOL fFlag)
1274{
1275 HIMC hIMC;
1276 TRACE("(%p, %d)\n", hwnd, fFlag);
1277
1278 hIMC = ImmGetContext(hwnd);
1279 if (IS_NULL_UNEXPECTEDLY(hIMC))
1280 return FALSE;
1281 return ImmSetActiveContext(hwnd, hIMC, fFlag);
1282}
1283
1284/***********************************************************************
1285 * GetKeyboardLayoutCP (IMM32.@)
1286 */
1288{
1289 WCHAR szText[8];
1290 static LANGID s_wKeyboardLangIdCache = 0;
1291 static UINT s_uKeyboardLayoutCPCache = 0;
1292
1293 TRACE("(%u)\n", wLangId);
1294
1295 if (wLangId == s_wKeyboardLangIdCache)
1296 return s_uKeyboardLayoutCPCache;
1297
1298 if (!GetLocaleInfoW(wLangId, LOCALE_IDEFAULTANSICODEPAGE, szText, _countof(szText)))
1299 return 0;
1300
1301 s_wKeyboardLangIdCache = wLangId;
1302 szText[_countof(szText) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
1303 s_uKeyboardLayoutCPCache = wcstol(szText, NULL, 10);
1304 return s_uKeyboardLayoutCPCache;
1305}
1306
1307#ifndef NDEBUG
1309{
1310 if (0)
1311 {
1312 DWORD dwValue;
1313 WCHAR szText[64];
1314
1315 Imm32StrToUInt(L"123", &dwValue, 10);
1316 ASSERT(dwValue == 123);
1317 Imm32StrToUInt(L"100", &dwValue, 16);
1318 ASSERT(dwValue == 0x100);
1319
1320 Imm32UIntToStr(123, 10, szText, _countof(szText));
1321 ASSERT(lstrcmpW(szText, L"123") == 0);
1322 Imm32UIntToStr(0x100, 16, szText, _countof(szText));
1323 ASSERT(lstrcmpW(szText, L"100") == 0);
1324 }
1325}
1326#endif
1327
1328BOOL
1329WINAPI
1331 _In_ HINSTANCE hDll,
1333 _In_opt_ PVOID pReserved)
1334{
1335 HKL hKL;
1336 HIMC hIMC;
1337
1338 TRACE("(%p, 0x%X, %p)\n", hDll, dwReason, pReserved);
1339
1340 switch (dwReason)
1341 {
1342 case DLL_PROCESS_ATTACH:
1343 if (!ImmInitializeGlobals(hDll))
1344 {
1345 ERR("ImmInitializeGlobals failed\n");
1346 return FALSE;
1347 }
1349 {
1350 ERR("User32InitializeImmEntryTable failed\n");
1351 return FALSE;
1352 }
1353#ifndef NDEBUG
1354 Imm32UnitTest();
1355#endif
1356 break;
1357
1358 case DLL_THREAD_ATTACH:
1359 break;
1360
1361 case DLL_THREAD_DETACH:
1362 if (!IS_IMM_MODE() || NtCurrentTeb()->Win32ThreadInfo == NULL)
1363 return TRUE;
1364
1365 hKL = GetKeyboardLayout(0);
1367 Imm32DestroyInputContext(hIMC, hKL, TRUE);
1368 break;
1369
1370 case DLL_PROCESS_DETACH:
1372 TRACE("imm32.dll is unloaded\n");
1373 break;
1374 }
1375
1376 return TRUE;
1377}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
DWORD dwReason
Definition: misc.cpp:135
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define HandleToUlong(h)
Definition: basetsd.h:79
#define RegCloseKey(hKey)
Definition: registry.h:49
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:312
LPARAM lParam
Definition: combotst.c:139
HRESULT CtfImmTIMCreateInputContext(_In_ HIMC hIMC)
Definition: ctf.c:939
HRESULT CtfImmTIMDestroyInputContext(_In_ HIMC hIMC)
Definition: ctf.c:929
#define ERROR_SUCCESS
Definition: deptool.c:10
DWORD HIMC
Definition: dimm.idl:75
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define DLL_THREAD_DETACH
Definition: compat.h:133
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
HANDLE HWND
Definition: compat.h:19
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
#define DLL_THREAD_ATTACH
Definition: compat.h:132
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4243
LCID WINAPI GetSystemDefaultLCID(void)
Definition: locale.c:1230
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1666
PTHEME_CLASS ValidateHandle(HTHEME hTheme)
Definition: system.c:732
LPFN_SELECT pSelect
Definition: handle.c:32
int Fail
Definition: ehthrow.cxx:24
@ Success
Definition: eventcreate.c:712
DWORD dwThreadId
Definition: fdebug.c:31
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
@ SystemBasicInformation
Definition: ntddk_ex.h:11
unsigned short WORD
Definition: ntddk_ex.h:93
FxChildList * pList
FxAutoRegKey hKey
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
LPVOID NTAPI LocalLock(HLOCAL hMem)
Definition: heapmem.c:1616
BOOL NTAPI LocalUnlock(HLOCAL hMem)
Definition: heapmem.c:1805
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
RTL_CRITICAL_SECTION gcsImeDpi
Definition: ime.c:16
PIMEDPI gpImeDpiList
Definition: ime.c:17
BOOL Imm32ReleaseIME(_In_ HKL hKL)
Definition: ime.c:378
PIMEDPI Imm32FindOrLoadImeDpi(HKL hKL)
Definition: ime.c:350
HIMC WINAPI ImmAssociateContext(_In_ HWND hWnd, _In_opt_ HIMC hIMC)
Definition: imm.c:500
BOOL WINAPI ImmFreeLayout(_In_ HKL hKL)
Definition: imm.c:124
UINT WINAPI GetKeyboardLayoutCP(_In_ LANGID wLangId)
Definition: imm.c:1287
LPINPUTCONTEXT Imm32InternalLockIMC(HIMC hIMC, BOOL fSelect)
Definition: imm.c:852
LPINPUTCONTEXT WINAPI ImmLockIMC(_In_ HIMC hIMC)
Definition: imm.c:1079
BOOL WINAPI ImmActivateLayout(_In_ HKL hKL)
Definition: imm.c:450
static BOOL CALLBACK Imm32SelectContextProc(HIMC hIMC, LPARAM lParam)
Definition: imm.c:433
#define MAX_IMCC_SIZE
BOOL WINAPI ImmRegisterClient(_Inout_ PSHAREDINFO ptr, _In_ HINSTANCE hMod)
Definition: imm.c:58
static BOOL Imm32CreateInputContext(HIMC hIMC, LPINPUTCONTEXT pIC, PCLIENTIMC pClientImc, HKL hKL, BOOL fSelect)
Definition: imm.c:752
PCLIENTIMC WINAPI ImmLockClientImc(_In_ HIMC hImc)
Definition: imm.c:954
HMODULE ghImm32Inst
Definition: imm.c:17
HIMC WINAPI ImmGetContext(_In_ HWND hWnd)
Definition: imm.c:1065
BOOL WINAPI ImmEnumInputContext(_In_ DWORD dwThreadId, _In_ IMCENUMPROC lpfn, _In_ LPARAM lParam)
Definition: imm.c:1123
BOOL WINAPI ImmWINNLSGetEnableStatus(_In_opt_ HWND hWnd)
Definition: imm.c:1256
BOOL WINAPI ImmSetActiveContextConsoleIME(_In_ HWND hwnd, _In_ BOOL fFlag)
Definition: imm.c:1271
static VOID Imm32SelectInputContext(HKL hNewKL, HKL hOldKL, HIMC hIMC)
Definition: imm.c:191
BOOL WINAPI ImmDllInitialize(_In_ HINSTANCE hDll, _In_ ULONG dwReason, _In_opt_ PVOID pReserved)
Definition: imm.c:1330
static BOOL Imm32DestroyInputContext(HIMC hIMC, HKL hKL, BOOL bKeep)
Definition: imm.c:660
static HIMC ImmGetSaveContext(_In_opt_ HWND hWnd, _In_ DWORD dwContextFlags)
Definition: imm.c:1021
static VOID Imm32DestroyImeModeSaver(LPINPUTCONTEXTDX pIC)
Definition: imm.c:638
static BOOL CALLBACK Imm32NotifyIMEProc(HIMC hIMC, LPARAM lParam)
Definition: imm.c:440
HIMC WINAPI ImmCreateContext(VOID)
Definition: imm.c:606
struct SELECT_LAYOUT * LPSELECT_LAYOUT
BOOL WINAPI ImmReleaseContext(_In_ HWND hWnd, _In_ HIMC hIMC)
Definition: imm.c:1109
SHAREDINFO gSharedInfo
Definition: imm.c:19
BOOL WINAPI ImmAssociateContextEx(_In_ HWND hWnd, _In_opt_ HIMC hIMC, _In_ DWORD dwFlags)
Definition: imm.c:552
BOOL WINAPI ImmUnlockIMC(_In_ HIMC hIMC)
Definition: imm.c:1089
BYTE gfImmInitialized
Definition: imm.c:20
PSERVERINFO gpsi
Definition: imm.c:18
VOID Imm32UnitTest(VOID)
Definition: imm.c:1308
BOOL WINAPI ImmDestroyContext(_In_ HIMC hIMC)
Definition: imm.c:931
BOOL WINAPI ImmSetActiveContext(_In_ HWND hWnd, _In_opt_ HIMC hIMC, _In_ BOOL fActive)
Definition: imm.c:1155
ULONG_PTR gHighestUserAddress
Definition: imm.c:21
static BOOL ImmInitializeGlobals(HMODULE hMod)
Definition: imm.c:23
VOID WINAPI ImmUnlockClientImc(_Inout_ PCLIENTIMC pClientImc)
Definition: imm.c:1001
BOOL WINAPI ImmLoadLayout(_In_ HKL hKL, _Inout_ PIMEINFOEX pImeInfoEx)
Definition: imm.c:71
struct tagCLIENTIMC * PCLIENTIMC
#define HKL_SWITCH_TO_NON_IME
Definition: imm32_undoc.h:29
BOOL WINAPI ImmLoadIME(_In_ HKL hKL)
Definition: ime.c:611
#define CLIENTIMC_DESTROY
Definition: imm32_undoc.h:172
HRESULT WINAPI CtfImmTIMActivate(_In_ HKL hKL)
Definition: ctf.c:1123
#define CLIENTIMC_DISABLEIME
Definition: imm32_undoc.h:173
struct INPUTCONTEXTDX * LPINPUTCONTEXTDX
#define IS_IME_HKL(hKL)
Definition: imm32_undoc.h:21
BOOL WINAPI CtfImmIsTextFrameServiceDisabled(VOID)
Definition: ctf.c:1079
#define CLIENTIMC_UNKNOWN2
Definition: imm32_undoc.h:174
PIMEDPI WINAPI ImmLockImeDpi(_In_ HKL hKL)
Definition: ime.c:531
#define CLIENTIMC_ACTIVE
Definition: imm32_undoc.h:170
VOID WINAPI ImmUnlockImeDpi(_Inout_opt_ PIMEDPI pImeDpi)
Definition: ime.c:561
#define HKL_RELEASE_IME
Definition: imm32_undoc.h:30
#define CLIENTIMC_WIDE
Definition: imm32_undoc.h:169
#define CPS_CANCEL
Definition: imm.h:181
#define ISC_SHOWUIGUIDELINE
Definition: imm.h:173
#define ISC_SHOWUIALLCANDIDATEWINDOW
Definition: imm.h:174
#define CPS_COMPLETE
Definition: imm.h:178
HWND WINAPI ImmGetDefaultIMEWnd(_In_opt_ HWND hWnd)
Definition: ime.c:440
#define ISC_SHOWUIALL
Definition: imm.h:175
#define IME_PROP_COMPLETE_ON_UNSELECT
Definition: imm.h:250
BOOL WINAPI ImmNotifyIME(_In_ HIMC hIMC, _In_ DWORD dwAction, _In_ DWORD dwIndex, _In_ DWORD_PTR dwValue)
Definition: ime.c:458
DWORD WINAPI ImmGetIMCCSize(_In_ HIMCC imcc)
Definition: utils.c:648
struct tagGUIDELINE GUIDELINE
BOOL WINAPI ImmUnlockIMCC(_In_ HIMCC imcc)
Definition: utils.c:615
#define INPUTCONTEXTDX_CHANGE_OPEN
Definition: immdev.h:160
#define INPUTCONTEXTDX_CHANGE_SENTENCE
Definition: immdev.h:162
HIMCC WINAPI ImmReSizeIMCC(_In_ HIMCC imcc, _In_ DWORD size)
Definition: utils.c:635
#define INIT_LOGFONT
Definition: immdev.h:154
HIMCC WINAPI ImmDestroyIMCC(_In_ HIMCC block)
Definition: utils.c:593
#define NI_COMPOSITIONSTR
Definition: immdev.h:381
DWORD WINAPI ImmGetIMCCLockCount(_In_ HIMCC imcc)
Definition: utils.c:626
struct tagCANDIDATEINFO CANDIDATEINFO
#define INPUTCONTEXTDX_CHANGE_FORCE_OPEN
Definition: immdev.h:163
#define INPUTCONTEXTDX_CHANGE_CONVERSION
Definition: immdev.h:161
HIMCC WINAPI ImmCreateIMCC(_In_ DWORD size)
Definition: utils.c:582
struct tagCOMPOSITIONSTRING COMPOSITIONSTRING
LPVOID WINAPI ImmLockIMCC(_In_ HIMCC imcc)
Definition: utils.c:604
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define QUERY_WINDOW_DEFAULT_ICONTEXT
Definition: ntuser.h:2851
#define QUERY_WINDOW_FOCUS
Definition: ntuser.h:2846
DWORD NTAPI NtUserNotifyIMEStatus(_In_ HWND hwnd, _In_ BOOL fOpen, _In_ DWORD dwConversion)
Definition: ime.c:848
BOOL NTAPI NtUserDestroyInputContext(_In_ HIMC hIMC)
Definition: ime.c:1612
DWORD NTAPI NtUserSetThreadLayoutHandles(_In_ HKL hNewKL, _In_ HKL hOldKL)
Definition: ime.c:535
@ THREADSTATE_DEFAULTINPUTCONTEXT
Definition: ntuser.h:2489
@ THREADSTATE_IMECOMPATFLAGS
Definition: ntuser.h:2498
#define CI_IMMACTIVATE
Definition: ntuser.h:306
#define IS_IMM_MODE()
Definition: ntuser.h:1212
DWORD NTAPI NtUserAssociateInputContext(_In_ HWND hWnd, _In_opt_ HIMC hIMC, _In_ DWORD dwFlags)
Definition: ime.c:1779
DWORD_PTR NTAPI NtUserQueryInputContext(HIMC hIMC, DWORD dwType)
Definition: ime.c:1878
@ TYPE_INPUTCONTEXT
Definition: ntuser.h:57
#define IS_16BIT_MODE()
Definition: ntuser.h:1214
DWORD_PTR NTAPI NtUserQueryWindow(HWND hWnd, DWORD Index)
Definition: window.c:4207
#define IS_CICERO_MODE()
Definition: ntuser.h:1213
HIMC NTAPI NtUserCreateInputContext(_In_ ULONG_PTR dwClientImcData)
Definition: ime.c:1683
BOOL NTAPI NtUserUpdateInputContext(HIMC hIMC, DWORD dwType, DWORD_PTR dwValue)
Definition: ime.c:1846
#define GetWin32ClientInfo()
Definition: ntuser.h:352
DWORD_PTR NTAPI NtUserGetThreadState(DWORD Routine)
Definition: misc.c:240
#define NtCurrentTeb
#define REG_SZ
Definition: layer.c:22
USHORT LANGID
Definition: mui.h:9
if(dx< 0)
Definition: linetemp.h:194
HWND pFocusWnd
Definition: magnifier.c:66
#define error(str)
Definition: mkdosfs.c:1605
#define ASSERT(a)
Definition: mode.c:44
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static PVOID ptr
Definition: dispmode.c:27
static LONG cLocks
Definition: compobj.c:119
UINT_PTR HKL
Definition: msctf.idl:125
EXTERN_C HRESULT WINAPI CtfImeSetActiveContextAlways(_In_ HIMC hIMC, _In_ BOOL fActive, _In_ HWND hWnd, _In_ HKL hKL)
Definition: msctfime.cpp:775
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define KEY_READ
Definition: nt_native.h:1023
#define DWORD
Definition: nt_native.h:44
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define L(x)
Definition: ntvdm.h:50
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
#define LANGIDFROMLCID(l)
Definition: nls.h:18
#define _countof(array)
Definition: sndvol32.h:70
#define TRACE(s)
Definition: solgame.cpp:4
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
DWORD dwIndex
Definition: dimm.idl:79
IMEINFO ImeInfo
Definition: imm32_undoc.h:94
HKL hKL
Definition: imm32_undoc.h:93
struct IMEDPI * pNext
Definition: imm32_undoc.h:91
UINT uCodePage
Definition: imm32_undoc.h:95
DWORD dwConversion
Definition: imm32_undoc.h:216
WORD fOpen
Definition: imm32_undoc.h:215
PIME_SUBSTATE pSubState
Definition: imm32_undoc.h:219
DWORD dwInit
Definition: imm32_undoc.h:218
DWORD dwSentence
Definition: imm32_undoc.h:217
struct IME_STATE * pNext
Definition: imm32_undoc.h:213
struct IME_SUBSTATE * pNext
Definition: imm32_undoc.h:202
struct IME_STATE * pState
Definition: imm32_undoc.h:195
HKL hNewKL
Definition: imm.c:429
HKL hOldKL
Definition: imm.c:430
PSERVERINFO psi
Definition: ntuser.h:1130
Definition: ntuser.h:694
HIMC hImc
Definition: ntuser.h:740
DWORD fdwProperty
Definition: immdev.h:22
DWORD dwPrivateDataSize
Definition: immdev.h:21
HIMCC hPrivate
Definition: immdev.h:122
CANDIDATEFORM cfCandForm[4]
Definition: immdev.h:118
HIMCC hMsgBuf
Definition: immdev.h:124
HIMCC hCompStr
Definition: immdev.h:119
DWORD fdwConversion
Definition: immdev.h:111
HIMCC hCandInfo
Definition: immdev.h:120
HIMCC hGuideLine
Definition: immdev.h:121
DWORD fdwSentence
Definition: immdev.h:112
DWORD dwNumMsgBuf
Definition: immdev.h:123
Definition: ps.c:97
DWORD dwSize
Definition: immdev.h:31
RTL_CRITICAL_SECTION cs
Definition: imm32_undoc.h:151
DWORD dwCompatFlags
Definition: imm32_undoc.h:150
HANDLE hInputContext
Definition: imm32_undoc.h:147
DWORD dwSize
Definition: immdev.h:76
Definition: ntuser.h:199
THRDESKHEAD head
Definition: ntuser.h:200
ULONG_PTR dwClientImcData
Definition: ntuser.h:202
#define max(a, b)
Definition: svc.c:63
uint32_t DWORD_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249
uint32_t ULONG
Definition: typedefs.h:59
#define NT_ERROR(Status)
Definition: umtypes.h:106
BOOL WINAPI User32InitializeImmEntryTable(_In_ DWORD)
@ UIC_CLIENTIMCDATA
Definition: undocuser.h:314
@ QIC_DEFAULTWINDOWIME
Definition: undocuser.h:405
@ QIC_INPUTTHREADID
Definition: undocuser.h:404
int ret
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR _In_opt_ USHORT LangID
Definition: wdfusb.h:1083
BOOL Imm32LoadImeVerInfo(_Inout_ PIMEINFOEX pImeInfoEx)
Definition: install.c:418
DWORD Imm32BuildHimcList(DWORD dwThreadId, HIMC **pphList)
Definition: utils.c:338
#define IS_ZERO_UNEXPECTEDLY(p)
Definition: precomp.h:67
BOOL Imm32LoadImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL)
Definition: utils.c:420
#define ValidateHwnd(hwnd)
Definition: precomp.h:101
#define ImmLocalFree(lpData)
Definition: precomp.h:105
#define IS_CROSS_THREAD_HIMC(hIMC)
Definition: precomp.h:72
#define IMM_INVALID_CANDFORM
Definition: precomp.h:76
PTHREADINFO FASTCALL Imm32CurrentPti(VOID)
Definition: utils.c:18
#define IMM_INIT_MAGIC
Definition: precomp.h:75
#define REGKEY_KEYBOARD_LAYOUTS
Definition: precomp.h:85
#define IS_ERROR_UNEXPECTEDLY(x)
Definition: precomp.h:69
VOID LogFontAnsiToWide(const LOGFONTA *plfA, LPLOGFONTW plfW)
Definition: utils.c:164
HRESULT Imm32UIntToStr(_In_ DWORD dwValue, _In_ ULONG nBase, _Out_ PWSTR pszBuff, _In_ USHORT cchBuff)
Definition: utils.c:56
#define IS_NULL_UNEXPECTEDLY(p)
Definition: precomp.h:66
BOOL Imm32SaveImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL)
Definition: utils.c:431
#define MAX_CANDIDATEFORM
Definition: precomp.h:78
#define IS_CROSS_PROCESS_HWND(hWnd)
Definition: precomp.h:73
BOOL Imm32IsSystemJapaneseOrKorean(VOID)
Definition: utils.c:72
PIME_STATE Imm32FetchImeState(LPINPUTCONTEXTDX pIC, HKL hKL)
Definition: utils.c:378
LPVOID ImmLocalAlloc(_In_ DWORD dwFlags, _In_ DWORD dwBytes)
Definition: utils.c:275
VOID LogFontWideToAnsi(const LOGFONTW *plfW, LPLOGFONTA plfA)
Definition: utils.c:176
#define ImeDpi_IsUnicode(pImeDpi)
Definition: precomp.h:120
HRESULT Imm32StrToUInt(_In_ PCWSTR pszText, _Out_ PDWORD pdwValue, _In_ ULONG nBase)
Definition: utils.c:40
BOOL Imm32CheckImcProcess(PIMC pIMC)
Definition: utils.c:252
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define LHND
Definition: winbase.h:415
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
#define WINAPI
Definition: msvc.h:6
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:45
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
BOOL WINAPI IsWindow(_In_opt_ HWND)
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
#define KL_NAMELENGTH
Definition: winuser.h:122
#define KLF_ACTIVATE
Definition: winuser.h:111
#define WM_IME_SETCONTEXT
Definition: winuser.h:1848
HKL WINAPI LoadKeyboardLayoutW(_In_ LPCWSTR, _In_ UINT)
UINT WINAPI GetKeyboardLayoutList(_In_ int nBuff, _Out_writes_to_opt_(nBuff, return) HKL FAR *lpList)
#define WM_IME_SELECT
Definition: winuser.h:1852
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193