ReactOS  0.4.15-dev-5126-g3bb451b
ime.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Win32k subsystem
4  * PURPOSE: Input Method Editor and Input Method Manager support
5  * FILE: win32ss/user/ntuser/ime.c
6  * PROGRAMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
8  */
9 
10 #include <win32k.h>
11 DBG_DEFAULT_CHANNEL(UserMisc);
12 
13 #define INVALID_THREAD_ID ((ULONG)-1)
14 #define INVALID_HOTKEY ((UINT)-1)
15 #define MOD_KEYS (MOD_CONTROL | MOD_SHIFT | MOD_ALT | MOD_WIN)
16 #define MOD_LEFT_RIGHT (MOD_LEFT | MOD_RIGHT)
17 
18 #define LANGID_CHINESE_SIMPLIFIED MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
19 #define LANGID_JAPANESE MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)
20 #define LANGID_KOREAN MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN)
21 #define LANGID_CHINESE_TRADITIONAL MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)
22 #define LANGID_NEUTRAL MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
23 
24 // The special virtual keys for Japanese: Used for key states.
25 // https://www.kthree.co.jp/kihelp/index.html?page=app/vkey&type=html
26 #define VK_DBE_ALPHANUMERIC 0xF0
27 #define VK_DBE_KATAKANA 0xF1
28 #define VK_DBE_HIRAGANA 0xF2
29 #define VK_DBE_SBCSCHAR 0xF3
30 #define VK_DBE_DBCSCHAR 0xF4
31 #define VK_DBE_ROMAN 0xF5
32 #define VK_DBE_NOROMAN 0xF6
33 #define VK_DBE_ENTERWORDREGISTERMODE 0xF7
34 #define VK_DBE_ENTERCONFIGMODE 0xF8
35 #define VK_DBE_FLUSHSTRING 0xF9
36 #define VK_DBE_CODEINPUT 0xFA
37 #define VK_DBE_NOCODEINPUT 0xFB
38 #define VK_DBE_DETERINESTRING 0xFC
39 #define VK_DBE_ENTERDLGCONVERSIONMODE 0xFD
40 
45 
46 typedef struct tagIMEHOTKEY
47 {
54 
55 PIMEHOTKEY gpImeHotKeyList = NULL; // Win: gpImeHotKeyListHeader
56 LCID glcidSystem = 0; // Win: glcidSystem
57 
58 // Win: GetAppImeCompatFlags
60 {
61  if (!pti)
63 
64  return pti->ppi->dwImeCompatFlags;
65 }
66 
67 // Win: GetLangIdMatchLevel
69 {
70  LCID lcid;
71 
72  if (HotKeyLangId == LANGID_NEUTRAL || HotKeyLangId == LOWORD(hKL))
73  return 3;
74 
75  _SEH2_TRY
76  {
77  lcid = NtCurrentTeb()->CurrentLocale;
78  }
80  {
82  }
83  _SEH2_END;
84 
85  if (HotKeyLangId == LANGIDFROMLCID(lcid))
86  return 2;
87 
88  if (glcidSystem == 0)
90 
91  if (HotKeyLangId == LANGIDFROMLCID(glcidSystem))
92  return 1;
93 
94  return 0;
95 }
96 
97 // Win: GetActiveHKL
99 {
100  PTHREADINFO pti;
101 
103  {
104  pti = gpqForeground->spwndActive->head.pti;
105  if (pti && pti->KeyboardLayout)
106  return pti->KeyboardLayout->hkl;
107  }
108 
109  return UserGetKeyboardLayout(0);
110 }
111 
112 // Win: GetHotKeyLangID
114 {
115 #define IME_CHOTKEY 0x10
116 #define IME_JHOTKEY 0x30
117 #define IME_KHOTKEY 0x50
118 #define IME_THOTKEY 0x70
119 #define IME_XHOTKEY 0x90
120  static const LANGID s_array[] =
121  {
122  /* 0x00 */ (WORD)-1,
123  /* 0x10 */ LANGID_CHINESE_SIMPLIFIED,
124  /* 0x20 */ LANGID_CHINESE_SIMPLIFIED,
125  /* 0x30 */ LANGID_JAPANESE,
126  /* 0x40 */ LANGID_JAPANESE,
127  /* 0x50 */ LANGID_KOREAN,
128  /* 0x60 */ LANGID_KOREAN,
129  /* 0x70 */ LANGID_CHINESE_TRADITIONAL,
130  /* 0x80 */ LANGID_CHINESE_TRADITIONAL
131  };
132 
134  return s_array[(dwHotKeyId & 0xF0) >> 4];
135  return LANGID_NEUTRAL;
136 }
137 
138 // Win: AddImeHotKey
140 {
141  PIMEHOTKEY pNode;
142 
143  if (!*ppList)
144  {
145  *ppList = pHotKey;
146  return;
147  }
148 
149  for (pNode = *ppList; pNode; pNode = pNode->pNext)
150  {
151  if (!pNode->pNext)
152  {
153  pNode->pNext = pHotKey;
154  return;
155  }
156  }
157 }
158 
159 // Win: FindImeHotKeyByID
161 {
162  PIMEHOTKEY pNode;
163  for (pNode = pList; pNode; pNode = pNode->pNext)
164  {
165  if (pNode->dwHotKeyId == dwHotKeyId)
166  return pNode;
167  }
168  return NULL;
169 }
170 
171 // Win: FindImeHotKeyByKeyWithLang
172 static PIMEHOTKEY APIENTRY
174  UINT uVirtualKey, LANGID TargetLangId)
175 {
176  PIMEHOTKEY pNode;
177  LANGID LangID;
179 
180  for (pNode = pList; pNode; pNode = pNode->pNext)
181  {
182  if (pNode->uVirtualKey != uVirtualKey)
183  continue;
184 
186  if (LangID != TargetLangId)
187  continue;
188 
189  uModifiers = pNode->uModifiers;
191  return pNode;
192 
193  if ((uModifiers & MOD_KEYS) != uModKeys)
194  continue;
195 
196  if ((uModifiers & uLeftRight) || (uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
197  return pNode;
198  }
199 
200  return NULL;
201 }
202 
203 // Win: DeleteImeHotKey
205 {
206  PIMEHOTKEY pNode;
207 
208  if (*ppList == pHotKey)
209  {
210  *ppList = pHotKey->pNext;
212  return;
213  }
214 
215  for (pNode = *ppList; pNode; pNode = pNode->pNext)
216  {
217  if (pNode->pNext == pHotKey)
218  {
219  pNode->pNext = pHotKey->pNext;
221  return;
222  }
223  }
224 }
225 
226 // Win: FindImeHotKeyByKey
229 {
230  PIMEHOTKEY pNode, ret = NULL;
232  LANGID LangId;
234  BOOL fKorean = (PRIMARYLANGID(LOWORD(hKL)) == LANG_KOREAN);
235  UINT nScore, nMaxScore = 0;
236 
237  for (pNode = pList; pNode; pNode = pNode->pNext)
238  {
239  if (pNode->uVirtualKey != uVirtualKey)
240  continue;
241 
242  if ((pNode->uModifiers & MOD_IGNORE_ALL_MODIFIER))
243  {
244  ;
245  }
246  else if ((pNode->uModifiers & MOD_KEYS) != uModKeys)
247  {
248  continue;
249  }
250  else if ((pNode->uModifiers & uLeftRight) ||
251  (pNode->uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
252  {
253  ;
254  }
255  else
256  {
257  continue;
258  }
259 
260  LangId = IntGetImeHotKeyLangId(pNode->dwHotKeyId);
261  nScore = IntGetImeHotKeyLanguageScore(hKL, LangId);
262  if (nScore >= 3)
263  return pNode;
264 
265  if (fKorean)
266  continue;
267 
268  if (nScore == 0)
269  {
272  {
273  if (LOWORD(pti->hklPrev) == LangId)
274  return pNode;
275  }
276  }
277 
278  if (nMaxScore < nScore)
279  {
280  nMaxScore = nScore;
281  ret = pNode;
282  }
283  }
284 
285  return ret;
286 }
287 
288 // Win: CheckImeHotKey
290 {
291  PIMEHOTKEY pHotKey;
293  BOOL bKeyUp = (lParam & 0x80000000);
294  const BYTE *KeyState = MessageQueue->afKeyState;
295  static UINT s_uKeyUpVKey = 0;
296 
297  if (bKeyUp)
298  {
299  if (s_uKeyUpVKey != uVirtualKey)
300  {
301  s_uKeyUpVKey = 0;
302  return NULL;
303  }
304 
305  s_uKeyUpVKey = 0;
306  }
307 
308  uModifiers = 0;
309  if (IS_KEY_DOWN(KeyState, VK_LSHIFT)) uModifiers |= (MOD_SHIFT | MOD_LEFT);
310  if (IS_KEY_DOWN(KeyState, VK_RSHIFT)) uModifiers |= (MOD_SHIFT | MOD_RIGHT);
311  if (IS_KEY_DOWN(KeyState, VK_LCONTROL)) uModifiers |= (MOD_CONTROL | MOD_LEFT);
312  if (IS_KEY_DOWN(KeyState, VK_RCONTROL)) uModifiers |= (MOD_CONTROL | MOD_RIGHT);
313  if (IS_KEY_DOWN(KeyState, VK_LMENU)) uModifiers |= (MOD_ALT | MOD_LEFT);
314  if (IS_KEY_DOWN(KeyState, VK_RMENU)) uModifiers |= (MOD_ALT | MOD_RIGHT);
315 
317  (uModifiers & MOD_KEYS),
319  uVirtualKey);
320  if (pHotKey)
321  {
322  if (bKeyUp)
323  {
324  if (pHotKey->uModifiers & MOD_ON_KEYUP)
325  return pHotKey;
326  }
327  else
328  {
329  if (pHotKey->uModifiers & MOD_ON_KEYUP)
330  s_uKeyUpVKey = uVirtualKey;
331  else
332  return pHotKey;
333  }
334  }
335 
336  return NULL;
337 }
338 
339 // Win: FreeImeHotKeys
341 {
342  PIMEHOTKEY pNode, pNext;
343  for (pNode = gpImeHotKeyList; pNode; pNode = pNext)
344  {
345  pNext = pNode->pNext;
347  }
349 }
350 
351 // Win: SetImeHotKey
352 static BOOL APIENTRY
354 {
355  PIMEHOTKEY pNode;
356  LANGID LangId;
357 
358  switch (dwAction)
359  {
360  case SETIMEHOTKEY_DELETE:
362  if (!pNode)
363  {
364  ERR("dwHotKeyId: 0x%lX\n", dwHotKeyId);
365  return FALSE;
366  }
367 
369  return TRUE;
370 
371  case SETIMEHOTKEY_ADD:
372  if (uVirtualKey == VK_PACKET)
373  return FALSE;
374 
376  if (LangId == LANGID_KOREAN)
377  return FALSE;
378 
380  (uModifiers & MOD_KEYS),
382  uVirtualKey, LangId);
383  if (!pNode)
385 
386  if (pNode)
387  {
388  pNode->uModifiers = uModifiers;
389  pNode->uVirtualKey = uVirtualKey;
390  pNode->hKL = hKL;
391  return TRUE;
392  }
393 
395  if (!pNode)
396  return FALSE;
397 
398  pNode->pNext = NULL;
399  pNode->dwHotKeyId = dwHotKeyId;
400  pNode->uModifiers = uModifiers;
401  pNode->uVirtualKey = uVirtualKey;
402  pNode->hKL = hKL;
404  return TRUE;
405 
408  return TRUE;
409 
410  default:
411  return FALSE;
412  }
413 }
414 
415 BOOL NTAPI
416 NtUserGetImeHotKey(DWORD dwHotKeyId, LPUINT lpuModifiers, LPUINT lpuVirtualKey, LPHKL lphKL)
417 {
418  PIMEHOTKEY pNode = NULL;
419 
421 
422  _SEH2_TRY
423  {
424  ProbeForWrite(lpuModifiers, sizeof(UINT), 1);
425  ProbeForWrite(lpuVirtualKey, sizeof(UINT), 1);
426  if (lphKL)
427  ProbeForWrite(lphKL, sizeof(HKL), 1);
428  }
430  {
431  goto Quit;
432  }
433  _SEH2_END;
434 
436  if (!pNode)
437  goto Quit;
438 
439  _SEH2_TRY
440  {
441  *lpuModifiers = pNode->uModifiers;
442  *lpuVirtualKey = pNode->uVirtualKey;
443  if (lphKL)
444  *lphKL = pNode->hKL;
445  }
447  {
448  pNode = NULL;
449  }
450  _SEH2_END;
451 
452 Quit:
453  UserLeave();
454  return !!pNode;
455 }
456 
457 BOOL
458 NTAPI
463  HKL hKL,
464  DWORD dwAction)
465 {
466  BOOL ret;
469  UserLeave();
470  return ret;
471 }
472 
473 DWORD
474 NTAPI
476 {
477  PIMEHOTKEY pNode;
479 
481 
482  if (!gpqForeground || !IS_IMM_MODE())
483  goto Quit;
484 
486  if (pNode)
487  ret = pNode->dwHotKeyId;
488 
489 Quit:
490  UserLeave();
491  return ret;
492 }
493 
494 // Win: GetTopLevelWindow
496 {
497  if (!pwnd)
498  return NULL;
499 
500  while (pwnd->style & WS_CHILD)
501  pwnd = pwnd->spwndParent;
502 
503  return pwnd;
504 }
505 
506 // Win: AssociateInputContext
508 {
509  HIMC hOldImc = pWnd->hImc;
510  pWnd->hImc = (pImc ? UserHMGetHandle(pImc) : NULL);
511  return hOldImc;
512 }
513 
514 DWORD
515 NTAPI
517 {
518  PTHREADINFO pti;
519  PKL pOldKL, pNewKL;
520 
522 
523  pti = GetW32ThreadInfo();
524  pOldKL = pti->KeyboardLayout;
525  if (pOldKL && pOldKL->hkl != hOldKL)
526  goto Quit;
527 
528  pNewKL = UserHklToKbl(hNewKL);
529  if (!pNewKL)
530  goto Quit;
531 
532  if (IS_IME_HKL(hNewKL) != IS_IME_HKL(hOldKL))
533  pti->hklPrev = hOldKL;
534 
535  UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pNewKL);
536  pti->pClientInfo->hKL = pNewKL->hkl;
537 
538 Quit:
539  UserLeave();
540  return 0;
541 }
542 
543 // Win: BuildHimcList
545 {
546  PIMC pIMC;
547  DWORD dwRealCount = 0;
548 
549  if (pti)
550  {
551  for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
552  {
553  if (dwRealCount < dwCount)
554  phList[dwRealCount] = UserHMGetHandle(pIMC);
555 
556  ++dwRealCount;
557  }
558  }
559  else
560  {
561  for (pti = GetW32ThreadInfo()->ppi->ptiList; pti; pti = pti->ptiSibling)
562  {
563  for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
564  {
565  if (dwRealCount < dwCount)
566  phList[dwRealCount] = UserHMGetHandle(pIMC);
567 
568  ++dwRealCount;
569  }
570  }
571  }
572 
573  return dwRealCount;
574 }
575 
576 // Win: xxxImmProcessKey
580 {
581  UINT uVirtualKey, ret = 0;
583  PKL pKL;
584  PIMC pIMC = NULL;
585  PIMEHOTKEY pImeHotKey;
586  HKL hKL;
587  HWND hWnd;
588 
589  ASSERT_REFS_CO(pWnd);
590 
591  switch (uMsg)
592  {
593  case WM_KEYDOWN:
594  case WM_KEYUP:
595  case WM_SYSKEYDOWN:
596  case WM_SYSKEYUP:
597  break;
598 
599  default:
600  return 0;
601  }
602 
603  hWnd = UserHMGetHandle(pWnd);
604  pKL = pWnd->head.pti->KeyboardLayout;
605  if (!pKL)
606  return 0;
607 
609  pImeHotKey = IntCheckImeHotKey(MessageQueue, uVirtualKey, lParam);
610  if (pImeHotKey)
611  {
612  dwHotKeyId = pImeHotKey->dwHotKeyId;
613  hKL = pImeHotKey->hKL;
614  }
615  else
616  {
618  hKL = NULL;
619  }
620 
622  {
623  if (pKL->hkl != hKL)
624  {
625  UserPostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST,
626  ((pKL->dwFontSigs & gSystemFS) ? INPUTLANGCHANGE_SYSCHARSET : 0),
627  (LPARAM)hKL);
628  }
629 
630  if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000)
631  return 0;
632 
633  return IPHK_HOTKEY;
634  }
635 
636  if (!IS_IMM_MODE())
637  return 0;
638 
639  if (dwHotKeyId == INVALID_HOTKEY)
640  {
641  if (!pKL->piiex)
642  return 0;
643 
644  if (pWnd->hImc)
646  if (!pIMC)
647  return 0;
648 
649  if ((lParam & 0x80000000) &&
651  {
652  return 0;
653  }
654 
655  switch (uVirtualKey)
656  {
657  case VK_DBE_CODEINPUT:
660  case VK_DBE_HIRAGANA:
661  case VK_DBE_KATAKANA:
662  case VK_DBE_NOCODEINPUT:
663  case VK_DBE_NOROMAN:
664  case VK_DBE_ROMAN:
665  break;
666 
667  default:
668  {
669  if (uMsg == WM_SYSKEYDOWN || uMsg == WM_SYSKEYUP)
670  {
671  if (uVirtualKey != VK_MENU && uVirtualKey != VK_F10)
672  return 0;
673  }
674 
676  {
677  if (uVirtualKey == VK_MENU || (lParam & 0x20000000))
678  return 0;
679  }
680  break;
681  }
682  }
683  }
684 
685  if (LOBYTE(uVirtualKey) == VK_PACKET)
686  uVirtualKey = MAKELONG(wParam, GetW32ThreadInfo()->wchInjected);
687 
689 
690  if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000)
691  ret &= ~IPHK_HOTKEY;
692 
693  return ret;
694 }
695 
696 NTSTATUS
697 NTAPI
698 NtUserBuildHimcList(DWORD dwThreadId, DWORD dwCount, HIMC *phList, LPDWORD pdwCount)
699 {
701  DWORD dwRealCount;
702  PTHREADINFO pti;
703 
705 
706  if (!IS_IMM_MODE())
707  {
708  ERR("!IS_IMM_MODE()\n");
710  goto Quit;
711  }
712 
713  if (dwThreadId == 0)
714  {
715  pti = GetW32ThreadInfo();
716  }
717  else if (dwThreadId == INVALID_THREAD_ID)
718  {
719  pti = NULL;
720  }
721  else
722  {
724  if (!pti || !pti->rpdesk)
725  goto Quit;
726  }
727 
728  _SEH2_TRY
729  {
730  ProbeForWrite(phList, dwCount * sizeof(HIMC), 1);
731  ProbeForWrite(pdwCount, sizeof(DWORD), 1);
732  *pdwCount = dwRealCount = UserBuildHimcList(pti, dwCount, phList);
733  }
735  {
736  goto Quit;
737  }
738  _SEH2_END;
739 
740  if (dwCount < dwRealCount)
742  else
744 
745 Quit:
746  UserLeave();
747  return ret;
748 }
749 
750 // Win: SetConvMode
752 {
753  HKL hKL;
754  LANGID LangID;
755  LPBYTE KeyState;
756  BOOL bAlphaNumeric, bKatakana, bHiragana, bFullShape, bRoman, bCharCode;
757 
758  if (!pti->KeyboardLayout)
759  return;
760 
761  hKL = pti->KeyboardLayout->hkl;
762  LangID = LOWORD(hKL);
763  KeyState = pti->MessageQueue->afKeyState;
764 
765  switch (PRIMARYLANGID(LangID))
766  {
767  case LANG_JAPANESE:
768  bAlphaNumeric = !(dwConversion & IME_CMODE_NATIVE);
769  bKatakana = !bAlphaNumeric && (dwConversion & IME_CMODE_KATAKANA);
770  bHiragana = !bAlphaNumeric && !(dwConversion & IME_CMODE_KATAKANA);
771  SET_KEY_DOWN(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
772  SET_KEY_LOCKED(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
773  SET_KEY_DOWN(KeyState, VK_DBE_HIRAGANA, bHiragana);
774  SET_KEY_LOCKED(KeyState, VK_DBE_HIRAGANA, bHiragana);
775  SET_KEY_DOWN(KeyState, VK_DBE_KATAKANA, bKatakana);
776  SET_KEY_LOCKED(KeyState, VK_DBE_KATAKANA, bKatakana);
777 
778  bFullShape = (dwConversion & IME_CMODE_FULLSHAPE);
779  SET_KEY_DOWN(KeyState, VK_DBE_DBCSCHAR, bFullShape);
780  SET_KEY_LOCKED(KeyState, VK_DBE_DBCSCHAR, bFullShape);
781  SET_KEY_DOWN(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
782  SET_KEY_LOCKED(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
783 
784  bRoman = (dwConversion & IME_CMODE_ROMAN);
785  SET_KEY_DOWN(KeyState, VK_DBE_ROMAN, bRoman);
786  SET_KEY_LOCKED(KeyState, VK_DBE_ROMAN, bRoman);
787  SET_KEY_DOWN(KeyState, VK_DBE_NOROMAN, !bRoman);
788  SET_KEY_LOCKED(KeyState, VK_DBE_NOROMAN, !bRoman);
789 
790  bCharCode = (dwConversion & IME_CMODE_CHARCODE);
791  SET_KEY_DOWN(KeyState, VK_DBE_CODEINPUT, bCharCode);
792  SET_KEY_LOCKED(KeyState, VK_DBE_CODEINPUT, bCharCode);
793  SET_KEY_DOWN(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
794  SET_KEY_LOCKED(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
795  break;
796 
797  case LANG_KOREAN:
798  SET_KEY_LOCKED(KeyState, VK_HANGUL, (dwConversion & IME_CMODE_NATIVE));
799  SET_KEY_LOCKED(KeyState, VK_JUNJA, (dwConversion & IME_CMODE_FULLSHAPE));
800  SET_KEY_LOCKED(KeyState, VK_HANJA, (dwConversion & IME_CMODE_HANJACONVERT));
801  break;
802 
803  default:
804  break;
805  }
806 }
807 
808 DWORD
809 NTAPI
810 NtUserNotifyIMEStatus(HWND hwnd, BOOL fOpen, DWORD dwConversion)
811 {
812  PWND pwnd;
813  PTHREADINFO pti;
814  HKL hKL;
815 
817 
818  if (!IS_IMM_MODE())
819  {
820  ERR("!IS_IMM_MODE()\n");
821  goto Quit;
822  }
823 
824  pwnd = ValidateHwndNoErr(hwnd);
825  if (!pwnd)
826  goto Quit;
827 
828  pti = pwnd->head.pti;
829  if (!pti || !gptiForeground)
830  goto Quit;
832  goto Quit;
833  if (ghIMC == pwnd->hImc && gfImeOpen == !!fOpen && gdwImeConversion == dwConversion)
834  goto Quit;
835 
836  ghIMC = pwnd->hImc;
837  if (ghIMC)
838  {
839  gfImeOpen = !!fOpen;
840  gdwImeConversion = dwConversion;
841  UserSetImeConversionKeyState(pti, (fOpen ? dwConversion : IME_CMODE_ALPHANUMERIC));
842  }
843 
844  if (ISITHOOKED(WH_SHELL))
845  {
846  hKL = (pti->KeyboardLayout ? pti->KeyboardLayout->hkl : NULL);
847  co_HOOK_CallHooks(WH_SHELL, HSHELL_LANGUAGE, (WPARAM)hwnd, (LPARAM)hKL);
848  }
849 
850  // TODO:
851 
852 Quit:
853  UserLeave();
854  return 0;
855 }
856 
857 BOOL
858 NTAPI
860  DWORD dwThreadID)
861 {
862  PTHREADINFO pti, ptiCurrent;
863  PPROCESSINFO ppi;
864  BOOL ret = FALSE;
865 
867 
868  if (!IS_IMM_MODE())
869  {
870  ERR("!IS_IMM_MODE()\n");
872  goto Quit;
873  }
874 
875  ptiCurrent = GetW32ThreadInfo();
876 
877  if (dwThreadID == INVALID_THREAD_ID)
878  {
879  ppi = ptiCurrent->ppi;
880  ppi->W32PF_flags |= W32PF_DISABLEIME;
881 
882 Retry:
883  for (pti = ppi->ptiList; pti; pti = pti->ptiSibling)
884  {
885  pti->TIF_flags |= TIF_DISABLEIME;
886 
887  if (pti->spwndDefaultIme)
888  {
890  pti->spwndDefaultIme = NULL;
891  goto Retry; /* The contents of ppi->ptiList may be changed. */
892  }
893  }
894  }
895  else
896  {
897  if (dwThreadID == 0)
898  {
899  pti = ptiCurrent;
900  }
901  else
902  {
903  pti = IntTID2PTI(UlongToHandle(dwThreadID));
904 
905  /* The thread needs to reside in the current process. */
906  if (!pti || pti->ppi != ptiCurrent->ppi)
907  goto Quit;
908  }
909 
910  pti->TIF_flags |= TIF_DISABLEIME;
911 
912  if (pti->spwndDefaultIme)
913  {
915  pti->spwndDefaultIme = NULL;
916  }
917  }
918 
919  ret = TRUE;
920 
921 Quit:
922  UserLeave();
923  return ret;
924 }
925 
926 DWORD
927 NTAPI
929 {
930  DWORD ret = 0;
931  PWND pWnd;
932  PTHREADINFO pti;
933 
934  UserEnterShared();
935 
936  pWnd = ValidateHwndNoErr(hWnd);
937  if (!pWnd)
938  goto Quit;
939 
940  if (!IS_IMM_MODE())
941  {
942  ERR("!IS_IMM_MODE()\n");
944  goto Quit;
945  }
946 
948  if (pWnd->head.pti->ppi == pti->ppi)
950 
951 Quit:
952  UserLeave();
953  return ret;
954 }
955 
956 // Win: GetImeInfoEx
959  _Inout_ PWINSTATION_OBJECT pWinSta,
960  _Inout_ PIMEINFOEX pInfoEx,
961  _In_ IMEINFOEXCLASS SearchType)
962 {
963  PKL pkl, pklHead;
964 
965  if (!pWinSta || !gspklBaseLayout)
966  return FALSE;
967 
968  pkl = pklHead = gspklBaseLayout;
969 
970  /* Find the matching entry from the list and get info */
971  if (SearchType == ImeInfoExKeyboardLayout)
972  {
973  do
974  {
975  if (pInfoEx->hkl == pkl->hkl)
976  {
977  if (!pkl->piiex)
978  {
979  ERR("!pkl->piiex at %p\n", pkl->hkl);
980  break;
981  }
982 
983  *pInfoEx = *pkl->piiex;
984  return TRUE;
985  }
986 
987  pkl = pkl->pklNext;
988  } while (pkl != pklHead);
989  }
990  else if (SearchType == ImeInfoExImeFileName)
991  {
992  do
993  {
994  if (pkl->piiex &&
995  _wcsnicmp(pkl->piiex->wszImeFile, pInfoEx->wszImeFile,
996  RTL_NUMBER_OF(pkl->piiex->wszImeFile)) == 0)
997  {
998  *pInfoEx = *pkl->piiex;
999  return TRUE;
1000  }
1001 
1002  pkl = pkl->pklNext;
1003  } while (pkl != pklHead);
1004  }
1005  else
1006  {
1007  ERR("SearchType: %d\n", SearchType);
1008  }
1009 
1010  return FALSE;
1011 }
1012 
1013 BOOL
1014 NTAPI
1016  PIMEINFOEX pImeInfoEx,
1017  IMEINFOEXCLASS SearchType)
1018 {
1019  IMEINFOEX ImeInfoEx;
1020  BOOL ret = FALSE;
1021  PWINSTATION_OBJECT pWinSta;
1022 
1023  UserEnterShared();
1024 
1025  if (!IS_IMM_MODE())
1026  {
1027  ERR("!IS_IMM_MODE()\n");
1028  goto Quit;
1029  }
1030 
1031  _SEH2_TRY
1032  {
1033  ProbeForWrite(pImeInfoEx, sizeof(*pImeInfoEx), 1);
1034  ImeInfoEx = *pImeInfoEx;
1035  }
1037  {
1038  goto Quit;
1039  }
1040  _SEH2_END;
1041 
1042  pWinSta = IntGetProcessWindowStation(NULL);
1043  ret = UserGetImeInfoEx(pWinSta, &ImeInfoEx, SearchType);
1044  if (!ret)
1045  goto Quit;
1046 
1047  _SEH2_TRY
1048  {
1049  *pImeInfoEx = ImeInfoEx;
1050  }
1052  {
1053  ret = FALSE;
1054  }
1055  _SEH2_END;
1056 
1057 Quit:
1058  UserLeave();
1059  return ret;
1060 }
1061 
1062 BOOL
1063 NTAPI
1065 {
1066  BOOL ret = FALSE;
1067  PWND pWnd;
1068  PTHREADINFO pti;
1069 
1071 
1072  if (!IS_IMM_MODE())
1073  {
1074  ERR("!IS_IMM_MODE()\n");
1076  goto Quit;
1077  }
1078 
1079  pWnd = ValidateHwndNoErr(hWnd);
1080  if (!pWnd)
1081  goto Quit;
1082 
1084  if (pWnd->head.pti->ppi == pti->ppi)
1085  ret = UserSetProp(pWnd, AtomImeLevel, (HANDLE)(ULONG_PTR)dwLevel, TRUE);
1086 
1087 Quit:
1088  UserLeave();
1089  return ret;
1090 }
1091 
1092 // Win: SetImeInfoEx
1093 BOOL FASTCALL
1095  _Inout_ PWINSTATION_OBJECT pWinSta,
1096  _Inout_ PIMEINFOEX pImeInfoEx)
1097 {
1098  PKL pklHead, pkl;
1099 
1100  if (!pWinSta || !gspklBaseLayout)
1101  return FALSE;
1102 
1103  pkl = pklHead = gspklBaseLayout;
1104 
1105  do
1106  {
1107  if (pkl->hkl != pImeInfoEx->hkl)
1108  {
1109  pkl = pkl->pklNext;
1110  continue;
1111  }
1112 
1113  if (!pkl->piiex)
1114  {
1115  ERR("!pkl->piiex at %p\n", pkl->hkl);
1116  return FALSE;
1117  }
1118 
1119  if (!pkl->piiex->fLoadFlag)
1120  *pkl->piiex = *pImeInfoEx;
1121 
1122  return TRUE;
1123  } while (pkl != pklHead);
1124 
1125  return FALSE;
1126 }
1127 
1128 BOOL
1129 NTAPI
1131 {
1132  BOOL ret = FALSE;
1133  IMEINFOEX ImeInfoEx;
1134  PWINSTATION_OBJECT pWinSta;
1135 
1137 
1138  if (!IS_IMM_MODE())
1139  {
1140  ERR("!IS_IMM_MODE()\n");
1141  goto Quit;
1142  }
1143 
1144  _SEH2_TRY
1145  {
1146  ProbeForRead(pImeInfoEx, sizeof(*pImeInfoEx), 1);
1147  ImeInfoEx = *pImeInfoEx;
1148  }
1150  {
1151  goto Quit;
1152  }
1153  _SEH2_END;
1154 
1155  pWinSta = IntGetProcessWindowStation(NULL);
1156  ret = UserSetImeInfoEx(pWinSta, &ImeInfoEx);
1157 
1158 Quit:
1159  UserLeave();
1160  return ret;
1161 }
1162 
1163 // Choose the preferred owner of the IME window.
1164 // Win: ImeSetFutureOwner
1166 {
1167  PWND pwndNode, pwndNextOwner, pwndParent, pwndSibling;
1168  PTHREADINFO pti = pImeWnd->head.pti;
1169 
1170  if (!pwndOwner || (pwndOwner->style & WS_CHILD)) // invalid owner
1171  return;
1172 
1173  // Get the top-level owner of the same thread
1174  for (pwndNode = pwndOwner; ; pwndNode = pwndNextOwner)
1175  {
1176  pwndNextOwner = pwndNode->spwndOwner;
1177  if (!pwndNextOwner || pwndNextOwner->head.pti != pti)
1178  break;
1179  }
1180 
1181  // Don't choose the IME-like windows and the bottom-most windows unless necessary.
1182  if (IS_WND_IMELIKE(pwndNode) ||
1183  ((pwndNode->state2 & WNDS2_BOTTOMMOST) && !(pwndOwner->state2 & WNDS2_BOTTOMMOST)))
1184  {
1185  pwndNode = pwndOwner;
1186  }
1187 
1188  pwndParent = pwndNode->spwndParent;
1189  if (!pwndParent || pwndOwner != pwndNode)
1190  {
1191  pImeWnd->spwndOwner = pwndNode;
1192  return;
1193  }
1194 
1195  for (pwndSibling = pwndParent->spwndChild; pwndSibling; pwndSibling = pwndSibling->spwndNext)
1196  {
1197  if (pwndNode->head.pti != pwndSibling->head.pti)
1198  continue;
1199 
1200  if (IS_WND_MENU(pwndSibling) || IS_WND_IMELIKE(pwndSibling))
1201  continue;
1202 
1203  if (pwndSibling->state2 & WNDS2_INDESTROY)
1204  continue;
1205 
1206  if (pwndNode == pwndSibling || (pwndSibling->style & WS_CHILD))
1207  continue;
1208 
1209  if (pwndSibling->spwndOwner == NULL ||
1210  pwndSibling->head.pti != pwndSibling->spwndOwner->head.pti)
1211  {
1212  pwndNode = pwndSibling;
1213  break;
1214  }
1215  }
1216 
1217  pImeWnd->spwndOwner = pwndNode;
1218 }
1219 
1220 // Get the last non-IME-like top-most window on the desktop.
1221 // Win: GetLastTopMostWindowNoIME
1223 {
1224  PWND pwndNode, pwndOwner, pwndLastTopMost = NULL;
1225  BOOL bFound;
1226 
1227  pwndNode = UserGetDesktopWindow();
1228  if (!pwndNode || pwndNode->spwndChild == NULL)
1229  return NULL;
1230 
1231  for (pwndNode = pwndNode->spwndChild;
1232  pwndNode && (pwndNode->ExStyle & WS_EX_TOPMOST);
1233  pwndNode = pwndNode->spwndNext)
1234  {
1235  bFound = FALSE;
1236 
1237  if (IS_WND_IMELIKE(pwndNode)) // An IME-like window
1238  {
1239  // Search the IME window from owners
1240  for (pwndOwner = pwndNode; pwndOwner; pwndOwner = pwndOwner->spwndOwner)
1241  {
1242  if (pImeWnd == pwndOwner)
1243  {
1244  bFound = TRUE;
1245  break;
1246  }
1247  }
1248  }
1249 
1250  if (!bFound)
1251  pwndLastTopMost = pwndNode;
1252  }
1253 
1254  return pwndLastTopMost;
1255 }
1256 
1257 // Adjust the ordering of the windows around the IME window.
1258 // Win: ImeSetTopMost
1259 VOID FASTCALL IntImeSetTopMost(PWND pImeWnd, BOOL bTopMost, PWND pwndInsertBefore)
1260 {
1261  PWND pwndParent, pwndChild, pwndNode, pwndNext, pwndInsertAfter = NULL;
1262  PWND pwndInsertAfterSave;
1263 
1264  pwndParent = pImeWnd->spwndParent;
1265  if (!pwndParent)
1266  return;
1267 
1268  pwndChild = pwndParent->spwndChild;
1269 
1270  if (!bTopMost)
1271  {
1272  // Calculate pwndInsertAfter
1273  pwndInsertAfter = IntGetLastTopMostWindowNoIME(pImeWnd);
1274  if (pwndInsertBefore)
1275  {
1276  for (pwndNode = pwndInsertAfter; pwndNode; pwndNode = pwndNode->spwndNext)
1277  {
1278  if (pwndNode->spwndNext == pwndInsertBefore)
1279  break;
1280 
1281  if (pwndNode == pImeWnd)
1282  return;
1283  }
1284 
1285  if (!pwndNode)
1286  return;
1287 
1288  pwndInsertAfter = pwndNode;
1289  }
1290 
1291  // Adjust pwndInsertAfter if the owner is bottom-most
1292  if (pImeWnd->spwndOwner->state2 & WNDS2_BOTTOMMOST)
1293  {
1294  for (pwndNode = pwndInsertAfter; pwndNode; pwndNode = pwndNode->spwndNext)
1295  {
1296  if (pwndNode == pImeWnd->spwndOwner)
1297  break;
1298 
1299  if (!IS_WND_IMELIKE(pwndNode))
1300  pwndInsertAfter = pwndNode;
1301  }
1302  }
1303  }
1304 
1305  pwndInsertAfterSave = pwndInsertAfter;
1306 
1307  while (pwndChild)
1308  {
1309  pwndNext = pwndChild->spwndNext;
1310 
1311  // If pwndChild is a good IME-like window, ...
1312  if (IS_WND_IMELIKE(pwndChild) && pwndChild != pwndInsertAfter &&
1313  pwndChild->head.pti == pImeWnd->head.pti)
1314  {
1315  // Find pImeWnd from the owners
1316  for (pwndNode = pwndChild; pwndNode; pwndNode = pwndNode->spwndOwner)
1317  {
1318  if (pwndNode != pImeWnd)
1319  continue;
1320 
1321  // Adjust the ordering and the linking
1322  IntUnlinkWindow(pwndChild);
1323 
1324  if (bTopMost)
1325  pwndChild->ExStyle |= WS_EX_TOPMOST;
1326  else
1327  pwndChild->ExStyle &= ~WS_EX_TOPMOST;
1328 
1329  if (!pwndInsertAfter)
1330  IntLinkHwnd(pwndChild, HWND_TOP);
1331  else
1332  IntLinkHwnd(pwndChild, UserHMGetHandle(pwndInsertAfter));
1333 
1334  // Update the preferred position
1335  pwndInsertAfter = pwndChild;
1336  break;
1337  }
1338  }
1339 
1340  // Get the next child, with ignoring pwndInsertAfterSave
1341  pwndChild = pwndNext;
1342  if (pwndChild && pwndChild == pwndInsertAfterSave && pwndInsertAfter)
1343  pwndChild = pwndInsertAfter->spwndNext;
1344  }
1345 }
1346 
1347 // Make the IME window top-most if necessary.
1348 // Win: ImeCheckTopmost
1350 {
1351  BOOL bTopMost;
1352  PWND pwndOwner = pImeWnd->spwndOwner, pwndInsertBefore = NULL;
1353 
1354  if (!pwndOwner)
1355  return;
1356 
1357  if (pImeWnd->head.pti != gptiForeground)
1358  pwndInsertBefore = pwndOwner;
1359 
1360  bTopMost = !!(pwndOwner->ExStyle & WS_EX_TOPMOST);
1361  IntImeSetTopMost(pImeWnd, bTopMost, pwndInsertBefore);
1362 }
1363 
1364 BOOL NTAPI
1365 NtUserSetImeOwnerWindow(HWND hImeWnd, HWND hwndFocus)
1366 {
1367  BOOL ret = FALSE;
1368  PWND pImeWnd, pwndFocus, pwndTopLevel, pwndNode, pwndActive;
1369  PTHREADINFO ptiIme;
1370 
1372 
1373  if (!IS_IMM_MODE())
1374  {
1375  ERR("!IS_IMM_MODE()\n");
1376  goto Quit;
1377  }
1378 
1379  pImeWnd = ValidateHwndNoErr(hImeWnd);
1380  if (!pImeWnd || pImeWnd->fnid != FNID_IME)
1381  goto Quit;
1382 
1383  pwndFocus = ValidateHwndNoErr(hwndFocus);
1384  if (pwndFocus)
1385  {
1386  if (IS_WND_IMELIKE(pwndFocus))
1387  goto Quit;
1388 
1389  pwndTopLevel = IntGetTopLevelWindow(pwndFocus);
1390 
1391  for (pwndNode = pwndTopLevel; pwndNode; pwndNode = pwndNode->spwndOwner)
1392  {
1393  if (pwndNode->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME])
1394  {
1395  pwndTopLevel = NULL;
1396  break;
1397  }
1398  }
1399 
1400  pImeWnd->spwndOwner = pwndTopLevel;
1401  IntImeCheckTopmost(pImeWnd);
1402  }
1403  else
1404  {
1405  ptiIme = pImeWnd->head.pti;
1406  pwndActive = ptiIme->MessageQueue->spwndActive;
1407 
1408  if (!pwndActive || pwndActive != pImeWnd->spwndOwner)
1409  {
1410  if (pwndActive && ptiIme == pwndActive->head.pti && !IS_WND_IMELIKE(pwndActive))
1411  {
1412  pImeWnd->spwndOwner = pwndActive;
1413  }
1414  else
1415  {
1416  IntImeSetFutureOwner(pImeWnd, pImeWnd->spwndOwner);
1417  }
1418 
1419  IntImeCheckTopmost(pImeWnd);
1420  }
1421  }
1422 
1423  ret = TRUE;
1424 
1425 Quit:
1426  UserLeave();
1427  return ret;
1428 }
1429 
1430 PVOID
1432  PTHREADINFO pti,
1433  SIZE_T Size,
1434  PVOID* HandleOwner)
1435 {
1436  PTHRDESKHEAD ObjHead;
1437 
1438  ASSERT(Size > sizeof(*ObjHead));
1439  ASSERT(pti != NULL);
1440 
1441  if (!pDesk)
1442  pDesk = pti->rpdesk;
1443 
1444  ObjHead = DesktopHeapAlloc(pDesk, Size);
1445  if (!ObjHead)
1446  return NULL;
1447 
1448  RtlZeroMemory(ObjHead, Size);
1449 
1450  ObjHead->pSelf = ObjHead;
1451  ObjHead->rpdesk = pDesk;
1452  ObjHead->pti = pti;
1454  *HandleOwner = pti;
1455  pti->ppi->UserHandleCount++;
1456 
1457  return ObjHead;
1458 }
1459 
1461 {
1462  PTHRDESKHEAD ObjHead = Object;
1463  PDESKTOP pDesk = ObjHead->rpdesk;
1464  PIMC pNode, pIMC = Object;
1465  PTHREADINFO pti;
1466 
1467  if (!pIMC)
1468  return;
1469 
1470  // Remove pIMC from the list except spDefaultImc
1471  pti = pIMC->head.pti;
1472  for (pNode = pti->spDefaultImc; pNode; pNode = pNode->pImcNext)
1473  {
1474  if (pNode->pImcNext == pIMC)
1475  {
1476  pNode->pImcNext = pIMC->pImcNext;
1477  break;
1478  }
1479  }
1480 
1481  DesktopHeapFree(pDesk, Object);
1482 
1483  pti->ppi->UserHandleCount--;
1485 }
1486 
1488 {
1489  PIMC pIMC = Object;
1490  if (!pIMC)
1491  return TRUE;
1492 
1493  UserMarkObjectDestroy(pIMC);
1495  return TRUE;
1496 }
1497 
1498 // Win: DestroyInputContext
1500 {
1501  HIMC hIMC = UserHMGetHandle(pIMC);
1502  PTHREADINFO pti = pIMC->head.pti;
1503  PWND pwndChild;
1504  PWINDOWLIST pwl;
1505  HWND *phwnd;
1506  PWND pWnd;
1507 
1508  if (pti != gptiCurrent)
1509  {
1511  return FALSE;
1512  }
1513 
1514  if (pIMC == pti->spDefaultImc)
1515  {
1517  return FALSE;
1518  }
1519 
1520  pwndChild = pti->rpdesk->pDeskInfo->spwnd->spwndChild;
1521  pwl = IntBuildHwndList(pwndChild, IACE_LIST | IACE_CHILDREN, pti);
1522  if (pwl)
1523  {
1524  for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
1525  {
1526  pWnd = UserGetObjectNoErr(gHandleTable, *phwnd, TYPE_WINDOW);
1527  if (pWnd && pWnd->hImc == hIMC)
1529  }
1530 
1531  IntFreeHwndList(pwl);
1532  }
1533 
1535  return TRUE;
1536 }
1537 
1539 {
1540  BOOL ret = FALSE;
1541  PIMC pIMC;
1542 
1544 
1545  if (!IS_IMM_MODE())
1546  {
1548  goto Quit;
1549  }
1550 
1552  if (pIMC)
1553  ret = IntDestroyInputContext(pIMC);
1554 
1555 Quit:
1556  UserLeave();
1557  return ret;
1558 }
1559 
1560 // Win: CreateInputContext
1562 {
1563  PIMC pIMC;
1565  PDESKTOP pdesk = pti->rpdesk;
1566 
1567  if (!IS_IMM_MODE() || (pti->TIF_flags & TIF_DISABLEIME)) // Disabled?
1568  {
1569  ERR("IME is disabled\n");
1570  return NULL;
1571  }
1572 
1573  if (!pdesk) // No desktop?
1574  return NULL;
1575 
1576  // pti->spDefaultImc should be already set if non-first time.
1577  if (dwClientImcData && !pti->spDefaultImc)
1578  return NULL;
1579 
1580  // Create an input context user object.
1581  pIMC = UserCreateObject(gHandleTable, pdesk, pti, NULL, TYPE_INPUTCONTEXT, sizeof(IMC));
1582  if (!pIMC)
1583  return NULL;
1584 
1585  // Release the extra reference (UserCreateObject added 2 references).
1586  UserDereferenceObject(pIMC);
1587  ASSERT(pIMC->head.cLockObj == 1);
1588 
1589  if (dwClientImcData) // Non-first time.
1590  {
1591  // Insert pIMC to the second position (non-default) of the list.
1592  pIMC->pImcNext = pti->spDefaultImc->pImcNext;
1593  pti->spDefaultImc->pImcNext = pIMC;
1594  }
1595  else // First time. It's the default IMC.
1596  {
1597  // Add the first one (default) to the list.
1598  UserAssignmentLock((PVOID*)&pti->spDefaultImc, pIMC);
1599  pIMC->pImcNext = NULL;
1600  ASSERT(pIMC->head.cLockObj == 2); // UserAssignmentUnlock'ed at ExitThreadCallback
1601  }
1602 
1603  pIMC->dwClientImcData = dwClientImcData; // Set it.
1604  return pIMC;
1605 }
1606 
1607 HIMC
1608 NTAPI
1610 {
1611  PIMC pIMC;
1612  HIMC ret = NULL;
1613 
1615 
1616  if (!IS_IMM_MODE())
1617  {
1618  ERR("!IS_IMM_MODE()\n");
1620  goto Quit;
1621  }
1622 
1623  if (!dwClientImcData)
1624  {
1626  goto Quit;
1627  }
1628 
1629  pIMC = UserCreateInputContext(dwClientImcData);
1630  if (pIMC)
1631  ret = UserHMGetHandle(pIMC);
1632 
1633 Quit:
1634  UserLeave();
1635  return ret;
1636 }
1637 
1638 // Win: AssociateInputContextEx
1640 {
1641  DWORD ret = 0;
1642  PWINDOWLIST pwl;
1643  BOOL bIgnoreNullImc = (dwFlags & IACE_IGNORENOCONTEXT);
1644  PTHREADINFO pti = pWnd->head.pti;
1645  PWND pwndTarget, pwndFocus = pti->MessageQueue->spwndFocus;
1646  HWND *phwnd;
1647  HIMC hIMC;
1648 
1649  if (dwFlags & IACE_DEFAULT)
1650  {
1651  pIMC = pti->spDefaultImc;
1652  }
1653  else
1654  {
1655  if (pIMC && pti != pIMC->head.pti)
1656  return 2;
1657  }
1658 
1659  if (pWnd->head.pti->ppi != GetW32ThreadInfo()->ppi ||
1660  (pIMC && pIMC->head.rpdesk != pWnd->head.rpdesk))
1661  {
1662  return 2;
1663  }
1664 
1665  if ((dwFlags & IACE_CHILDREN) && pWnd->spwndChild)
1666  {
1667  pwl = IntBuildHwndList(pWnd->spwndChild, IACE_CHILDREN | IACE_LIST, pti);
1668  if (pwl)
1669  {
1670  for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
1671  {
1672  pwndTarget = ValidateHwndNoErr(*phwnd);
1673  if (!pwndTarget)
1674  continue;
1675 
1676  hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1677  if (pwndTarget->hImc == hIMC || (bIgnoreNullImc && !pwndTarget->hImc))
1678  continue;
1679 
1680  IntAssociateInputContext(pwndTarget, pIMC);
1681  if (pwndTarget == pwndFocus)
1682  ret = 1;
1683  }
1684 
1685  IntFreeHwndList(pwl);
1686  }
1687  }
1688 
1689  if (!bIgnoreNullImc || pWnd->hImc)
1690  {
1691  hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1692  if (pWnd->hImc != hIMC)
1693  {
1694  IntAssociateInputContext(pWnd, pIMC);
1695  if (pWnd == pwndFocus)
1696  ret = 1;
1697  }
1698  }
1699 
1700  return ret;
1701 }
1702 
1703 DWORD
1704 NTAPI
1706 {
1707  DWORD ret = 2;
1708  PWND pWnd;
1709  PIMC pIMC;
1710 
1712 
1713  if (!IS_IMM_MODE())
1714  {
1715  ERR("!IS_IMM_MODE()\n");
1716  goto Quit;
1717  }
1718 
1719  pWnd = ValidateHwndNoErr(hWnd);
1720  if (!pWnd)
1721  goto Quit;
1722 
1723  pIMC = (hIMC ? UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT) : NULL);
1724  ret = IntAssociateInputContextEx(pWnd, pIMC, dwFlags);
1725 
1726 Quit:
1727  UserLeave();
1728  return ret;
1729 }
1730 
1731 // Win: UpdateInputContext
1733 {
1734  PTHREADINFO pti = GetW32ThreadInfo();
1735  PTHREADINFO ptiIMC = pIMC->head.pti;
1736 
1737  if (pti->ppi != ptiIMC->ppi) // Different process?
1738  return FALSE;
1739 
1740  switch (dwType)
1741  {
1742  case UIC_CLIENTIMCDATA:
1743  if (pIMC->dwClientImcData)
1744  return FALSE; // Already set
1745 
1746  pIMC->dwClientImcData = dwValue;
1747  break;
1748 
1749  case UIC_IMEWINDOW:
1750  if (!ValidateHwndNoErr((HWND)dwValue))
1751  return FALSE; // Invalid HWND
1752 
1753  pIMC->hImeWnd = (HWND)dwValue;
1754  break;
1755 
1756  default:
1757  return FALSE;
1758  }
1759 
1760  return TRUE;
1761 }
1762 
1763 BOOL
1764 NTAPI
1766  HIMC hIMC,
1767  DWORD dwType,
1768  DWORD_PTR dwValue)
1769 {
1770  PIMC pIMC;
1771  BOOL ret = FALSE;
1772 
1774 
1775  if (!IS_IMM_MODE())
1776  {
1777  ERR("!IS_IMM_MODE()\n");
1778  goto Quit;
1779  }
1780 
1782  if (!pIMC)
1783  goto Quit;
1784 
1785  ret = UserUpdateInputContext(pIMC, dwType, dwValue);
1786 
1787 Quit:
1788  UserLeave();
1789  return ret;
1790 }
1791 
1792 DWORD_PTR
1793 NTAPI
1795 {
1796  PIMC pIMC;
1797  PTHREADINFO ptiIMC;
1798  DWORD_PTR ret = 0;
1799 
1801 
1802  if (!IS_IMM_MODE())
1803  {
1804  ERR("!IS_IMM_MODE()\n");
1805  goto Quit;
1806  }
1807 
1809  if (!pIMC)
1810  goto Quit;
1811 
1812  ptiIMC = pIMC->head.pti;
1813 
1814  switch (dwType)
1815  {
1816  case QIC_INPUTPROCESSID:
1817  ret = (DWORD_PTR)PsGetThreadProcessId(ptiIMC->pEThread);
1818  break;
1819 
1820  case QIC_INPUTTHREADID:
1821  ret = (DWORD_PTR)PsGetThreadId(ptiIMC->pEThread);
1822  break;
1823 
1824  case QIC_DEFAULTWINDOWIME:
1825  if (ptiIMC->spwndDefaultIme)
1827  break;
1828 
1829  case QIC_DEFAULTIMC:
1830  if (ptiIMC->spDefaultImc)
1832  break;
1833  }
1834 
1835 Quit:
1836  UserLeave();
1837  return ret;
1838 }
1839 
1840 // Searchs a non-IME-related window of the same thread of pwndTarget,
1841 // other than pwndTarget, around pwndParent. Returns TRUE if found.
1842 //
1843 // Win: IsChildSameThread
1845 {
1846  PWND pwnd, pwndOwner, pwndNode;
1847  PTHREADINFO ptiTarget = pwndTarget->head.pti;
1848 
1849  // For all the children of pwndParent, ...
1850  for (pwnd = pwndParent->spwndChild; pwnd; pwnd = pwnd->spwndNext)
1851  {
1852  if (pwnd == pwndTarget || pwnd->head.pti != ptiTarget || IS_WND_MENU(pwnd))
1853  continue;
1854 
1855  if (!IS_WND_CHILD(pwnd))
1856  {
1857  // Check if any IME-like owner.
1858  BOOL bFound1 = FALSE;
1859  for (pwndOwner = pwnd; pwndOwner; pwndOwner = pwndOwner->spwndOwner)
1860  {
1861  if (IS_WND_IMELIKE(pwndOwner))
1862  {
1863  bFound1 = TRUE;
1864  break;
1865  }
1866  }
1867  if (bFound1)
1868  continue; // Skip if any IME-like owner.
1869  }
1870 
1871  pwndNode = pwnd;
1872 
1873  if (IS_WND_CHILD(pwndNode))
1874  {
1875  // Check if any same-thread IME-like ancestor.
1876  BOOL bFound2 = FALSE;
1877  for (; IS_WND_CHILD(pwndNode); pwndNode = pwndNode->spwndParent)
1878  {
1879  if (pwndNode->head.pti != ptiTarget)
1880  break;
1881 
1882  if (IS_WND_IMELIKE(pwndNode))
1883  {
1884  bFound2 = TRUE;
1885  break;
1886  }
1887  }
1888  if (bFound2)
1889  continue;
1890  // Now, pwndNode is non-child or non-same-thread window.
1891  }
1892 
1893  if (!IS_WND_CHILD(pwndNode)) // pwndNode is non-child
1894  {
1895  // Check if any same-thread IME-like owner.
1896  BOOL bFound3 = FALSE;
1897  for (; pwndNode; pwndNode = pwndNode->spwndOwner)
1898  {
1899  if (pwndNode->head.pti != ptiTarget)
1900  break;
1901 
1902  if (IS_WND_IMELIKE(pwndNode))
1903  {
1904  bFound3 = TRUE;
1905  break;
1906  }
1907  }
1908  if (bFound3)
1909  continue;
1910  }
1911 
1912  return TRUE;
1913  }
1914 
1915  return FALSE;
1916 }
1917 
1918 // Determines whether the target window needs the IME window.
1919 // Win: WantImeWindow(pwndParent, pwndTarget)
1921 {
1922  PDESKTOP rpdesk;
1923  PWINSTATION_OBJECT rpwinstaParent;
1924  PWND pwndNode, pwndParent = pwndTarget->spwndParent;
1925 
1927  return FALSE;
1928 
1929  if (IS_WND_IMELIKE(pwndTarget))
1930  return FALSE;
1931 
1932  if (pwndTarget->fnid == FNID_DESKTOP || pwndTarget->fnid == FNID_MESSAGEWND)
1933  return FALSE;
1934 
1935  if (pwndTarget->state & WNDS_SERVERSIDEWINDOWPROC)
1936  return FALSE;
1937 
1938  rpdesk = pwndTarget->head.rpdesk;
1939  if (!rpdesk)
1940  return FALSE;
1941 
1942  rpwinstaParent = rpdesk->rpwinstaParent;
1943  if (!rpwinstaParent || (rpwinstaParent->Flags & WSS_NOIO))
1944  return FALSE;
1945 
1946  for (pwndNode = pwndParent; pwndNode; pwndNode = pwndNode->spwndParent)
1947  {
1948  if (rpdesk != pwndNode->head.rpdesk)
1949  break;
1950 
1951  if (pwndNode == rpdesk->spwndMessage)
1952  return FALSE;
1953  }
1954 
1955  return TRUE;
1956 }
1957 
1958 // Create the default IME window for the target window.
1959 // Win: xxxCreateDefaultImeWindow(pwndTarget, ATOM, hInst)
1961 {
1962  LARGE_UNICODE_STRING WindowName;
1963  UNICODE_STRING ClassName;
1964  PWND pImeWnd;
1965  PIMEUI pimeui;
1966  CREATESTRUCTW Cs;
1969  HANDLE pid = PsGetThreadProcessId(pti->pEThread);
1970 
1971  if (!(pti->spDefaultImc) && pid == gpidLogon)
1973 
1974  if (!(pti->spDefaultImc) || IS_WND_IMELIKE(pwndTarget) || !(pti->rpdesk->pheapDesktop))
1975  return NULL;
1976 
1977  if (IS_WND_CHILD(pwndTarget) && !(pwndTarget->style & WS_VISIBLE) &&
1978  pwndTarget->spwndParent->head.pti->ppi != pti->ppi)
1979  {
1980  return NULL;
1981  }
1982 
1983  RtlInitLargeUnicodeString(&WindowName, L"Default IME", 0);
1984 
1985  ClassName.Buffer = (PWCH)(ULONG_PTR)gpsi->atomSysClass[ICLS_IME];
1986  ClassName.Length = 0;
1987  ClassName.MaximumLength = 0;
1988 
1989  UserRefObjectCo(pwndTarget, &Ref);
1990 
1991  RtlZeroMemory(&Cs, sizeof(Cs));
1992  Cs.style = WS_POPUP | WS_DISABLED;
1993  Cs.hInstance = hInst;
1994  Cs.hwndParent = UserHMGetHandle(pwndTarget);
1995  Cs.lpszName = WindowName.Buffer;
1996  Cs.lpszClass = ClassName.Buffer;
1997 
1998  // NOTE: LARGE_UNICODE_STRING is compatible to LARGE_STRING.
1999  pImeWnd = co_UserCreateWindowEx(&Cs, &ClassName, (PLARGE_STRING)&WindowName, NULL, WINVER);
2000  if (pImeWnd)
2001  {
2002  pimeui = ((PIMEWND)pImeWnd)->pimeui;
2003  _SEH2_TRY
2004  {
2005  ProbeForWrite(pimeui, sizeof(IMEUI), 1);
2006  pimeui->fDefault = TRUE;
2007  if (IS_WND_CHILD(pwndTarget) && pwndTarget->spwndParent->head.pti != pti)
2008  pimeui->fChildThreadDef = TRUE;
2009  }
2011  {
2012  NOTHING;
2013  }
2014  _SEH2_END;
2015  }
2016 
2017  UserDerefObjectCo(pwndTarget);
2018  return pImeWnd;
2019 }
2020 
2021 // Determines whether the system can destroy the default IME window for the target child window.
2022 // Win: ImeCanDestroyDefIMEforChild
2024 {
2025  PWND pwndNode;
2026  PIMEUI pimeui;
2027  IMEUI SafeImeUI;
2028 
2029  pimeui = ((PIMEWND)pImeWnd)->pimeui;
2030  if (!pimeui || (LONG_PTR)pimeui == (LONG_PTR)-1)
2031  return FALSE;
2032 
2033  // Check IMEUI.fChildThreadDef
2034  _SEH2_TRY
2035  {
2036  ProbeForRead(pimeui, sizeof(IMEUI), 1);
2037  SafeImeUI = *pimeui;
2038  if (!SafeImeUI.fChildThreadDef)
2039  return FALSE;
2040  }
2042  {
2043  NOTHING;
2044  }
2045  _SEH2_END;
2046 
2047  // The parent of pwndTarget is NULL or of the same thread of pwndTarget?
2048  if (pwndTarget->spwndParent == NULL ||
2049  pwndTarget->head.pti == pwndTarget->spwndParent->head.pti)
2050  {
2051  return FALSE;
2052  }
2053 
2054  for (pwndNode = pwndTarget; pwndNode; pwndNode = pwndNode->spwndParent)
2055  {
2056  if (pwndNode == pwndNode->head.rpdesk->pDeskInfo->spwnd)
2057  break;
2058 
2059  if (IntFindNonImeRelatedWndOfSameThread(pwndNode->spwndParent, pwndTarget))
2060  return FALSE;
2061  }
2062 
2063  return TRUE;
2064 }
2065 
2066 // Determines whether the system can destroy the default IME window for the non-child target window.
2067 // Win: ImeCanDestroyDefIME
2069 {
2070  PWND pwndNode;
2071  PIMEUI pimeui;
2072  IMEUI SafeImeUI;
2073 
2074  pimeui = ((PIMEWND)pImeWnd)->pimeui;
2075  if (!pimeui || (LONG_PTR)pimeui == (LONG_PTR)-1)
2076  return FALSE;
2077 
2078  // Check IMEUI.fDestroy
2079  _SEH2_TRY
2080  {
2081  ProbeForRead(pimeui, sizeof(IMEUI), 1);
2082  SafeImeUI = *pimeui;
2083  if (SafeImeUI.fDestroy)
2084  return FALSE;
2085  }
2087  {
2088  NOTHING;
2089  }
2090  _SEH2_END;
2091 
2092  // Any ancestor of pImeWnd is pwndTarget?
2093  if (pImeWnd->spwndOwner)
2094  {
2095  for (pwndNode = pImeWnd->spwndOwner; pwndNode; pwndNode = pwndNode->spwndOwner)
2096  {
2097  if (pwndNode == pwndTarget)
2098  break;
2099  }
2100 
2101  if (!pwndNode)
2102  return FALSE;
2103  }
2104 
2105  // Any ancestor of pwndTarget is IME-like?
2106  for (pwndNode = pwndTarget; pwndNode; pwndNode = pwndNode->spwndOwner)
2107  {
2108  if (IS_WND_IMELIKE(pwndNode))
2109  return FALSE;
2110  }
2111 
2112  // Adjust the ordering and top-mode status
2113  IntImeSetFutureOwner(pImeWnd, pwndTarget);
2114  for (pwndNode = pImeWnd->spwndOwner; pwndNode; pwndNode = pwndNode->spwndNext)
2115  {
2116  if (pwndNode == pImeWnd)
2117  break;
2118  }
2119  if (pwndNode == pImeWnd)
2120  IntImeCheckTopmost(pImeWnd);
2121 
2122  // Is the owner of pImeWnd NULL or pwndTarget?
2123  if (pImeWnd->spwndOwner && pwndTarget != pImeWnd->spwndOwner)
2124  return FALSE;
2125 
2126  pImeWnd->spwndOwner = NULL;
2127  return TRUE;
2128 }
2129 
2130 // Update IMEUI.fShowStatus flags and Send the WM_IME_NOTIFY messages.
2131 // Win: xxxCheckImeShowStatus
2133 {
2134  BOOL ret = FALSE, bDifferent;
2135  PWINDOWLIST pwl;
2136  HWND *phwnd;
2137  PWND pwndNode, pwndIMC;
2138  PTHREADINFO ptiCurrent = GetW32ThreadInfo();
2139  PIMEUI pimeui;
2140  IMEUI SafeImeUI;
2141 
2142  if (pwndIme->state2 & WNDS2_INDESTROY)
2143  return FALSE;
2144 
2145  // Build a window list
2146  pwl = IntBuildHwndList(pwndIme->spwndParent->spwndChild, IACE_LIST, NULL);
2147  if (!pwl)
2148  return FALSE;
2149 
2150  ret = TRUE;
2151  for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
2152  {
2153  pwndNode = ValidateHwndNoErr(*phwnd);
2154 
2155  if (!pwndNode || pwndIme == pwndNode)
2156  continue;
2157 
2158  if (pwndNode->pcls->atomClassName != gpsi->atomSysClass[ICLS_IME] ||
2159  (pwndNode->state2 & WNDS2_INDESTROY))
2160  {
2161  continue;
2162  }
2163 
2164  pimeui = ((PIMEWND)pwndNode)->pimeui;
2165  if (!pimeui || pimeui == (PIMEUI)-1)
2166  continue;
2167 
2168  if (pti && pti != pwndNode->head.pti)
2169  continue;
2170 
2171  // Attach to the process if necessary
2172  bDifferent = FALSE;
2173  if (pwndNode->head.pti->ppi != ptiCurrent->ppi)
2174  {
2175  KeAttachProcess(&(pwndNode->head.pti->ppi->peProcess->Pcb));
2176  bDifferent = TRUE;
2177  }
2178 
2179  // Get pwndIMC and update IMEUI.fShowStatus flag
2180  _SEH2_TRY
2181  {
2182  ProbeForWrite(pimeui, sizeof(IMEUI), 1);
2183  SafeImeUI = *pimeui;
2184  if (SafeImeUI.fShowStatus)
2185  {
2186  pwndIMC = ValidateHwndNoErr(pimeui->hwndIMC);
2187  if (pwndIMC)
2188  pimeui->fShowStatus = FALSE;
2189  }
2190  else
2191  {
2192  pwndIMC = NULL;
2193  }
2194  }
2196  {
2197  pwndIMC = NULL;
2198  }
2199  _SEH2_END;
2200 
2201  // Detach from the process if necessary
2202  if (bDifferent)
2203  KeDetachProcess();
2204 
2205  // Send the WM_IME_NOTIFY message
2206  if (pwndIMC && pwndIMC->head.pti && !(pwndIMC->head.pti->TIF_flags & TIF_INCLEANUP))
2207  {
2208  HWND hImeWnd;
2210 
2211  UserRefObjectCo(pwndIMC, &Ref);
2212 
2213  hImeWnd = UserHMGetHandle(pwndIMC);
2215 
2216  UserDerefObjectCo(pwndIMC);
2217  }
2218  }
2219 
2220  // Free the window list
2221  IntFreeHwndList(pwl);
2222  return ret;
2223 }
2224 
2225 // Send a UI message.
2226 // Win: xxxSendMessageToUI
2229 {
2230  PWND pwndUI;
2231  LRESULT ret = 0;
2232  IMEUI SafeImeUI;
2233  BOOL bDifferent = FALSE;
2235 
2236  // Attach to the process if necessary
2237  if (ptiIME != GetW32ThreadInfo())
2238  {
2239  bDifferent = TRUE;
2240  KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2241  }
2242 
2243  // Get the pwndUI
2244  _SEH2_TRY
2245  {
2246  ProbeForRead(pimeui, sizeof(IMEUI), 1);
2247  SafeImeUI = *pimeui;
2248  pwndUI = ValidateHwndNoErr(SafeImeUI.hwndUI);
2249  }
2251  {
2252  pwndUI = NULL;
2253  }
2254  _SEH2_END;
2255 
2256  if (!pwndUI)
2257  goto Quit;
2258 
2259  // Increment the recursion count of the IME procedure.
2260  // See also ImeWndProc_common of user32.
2261  _SEH2_TRY
2262  {
2263  ProbeForWrite(&pimeui->nCntInIMEProc, sizeof(LONG), 1);
2265  }
2267  {
2268  goto Quit;
2269  }
2270  _SEH2_END;
2271 
2272  // Detach from the process if necessary
2273  if (bDifferent)
2274  KeDetachProcess();
2275 
2276  UserRefObjectCo(pwndUI, &Ref);
2277  ret = co_IntSendMessage(UserHMGetHandle(pwndUI), uMsg, wParam, lParam);
2278  UserDerefObjectCo(pwndUI);
2279 
2280  // Attach to the process if necessary
2281  if (bDifferent)
2282  KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2283 
2284  // Decrement the recursion count of the IME procedure
2285  _SEH2_TRY
2286  {
2287  ProbeForWrite(&pimeui->nCntInIMEProc, sizeof(LONG), 1);
2289  }
2291  {
2292  goto Quit;
2293  }
2294  _SEH2_END;
2295 
2296 Quit:
2297  // Detach from the process if necessary
2298  if (bDifferent)
2299  KeDetachProcess();
2300 
2301  return ret;
2302 }
2303 
2304 // Send the open status notification.
2305 // Win: xxxSendOpenStatusNotify
2306 VOID FASTCALL
2308 {
2310  PTHREADINFO ptiWnd = pWnd->head.pti;
2312 
2313  if (ptiWnd->dwExpWinVer >= WINVER_WINNT4 && pWnd->hImc)
2314  {
2315  UserRefObjectCo(pWnd, &Ref);
2317  UserDerefObjectCo(pWnd);
2318  }
2319  else
2320  {
2321  IntSendMessageToUI(ptiIME, pimeui, WM_IME_NOTIFY, wParam, 0);
2322  }
2323 }
2324 
2325 // Update the IME status and send a notification.
2326 // Win: xxxNotifyImeShowStatus
2328 {
2329  PIMEUI pimeui;
2330  PWND pWnd;
2331  PTHREADINFO pti, ptiIME;
2332  BOOL bShow, bSendNotify = FALSE;
2333  IMEUI SafeImeUI;
2334 
2335  if (!IS_IMM_MODE() || (pImeWnd->state2 & WNDS2_INDESTROY))
2336  return;
2337 
2339  ptiIME = pImeWnd->head.pti;
2340 
2341  // Attach to the process if necessary
2342  if (pti != ptiIME)
2343  KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2344 
2345  // Get an IMEUI and check whether hwndIMC is valid and update fShowStatus
2346  _SEH2_TRY
2347  {
2348  ProbeForWrite(pImeWnd, sizeof(IMEWND), 1);
2349  pimeui = ((PIMEWND)pImeWnd)->pimeui;
2350  SafeImeUI = *pimeui;
2351 
2352  bShow = (gfIMEShowStatus == TRUE) && SafeImeUI.fCtrlShowStatus;
2353 
2354  pWnd = ValidateHwndNoErr(SafeImeUI.hwndIMC);
2355  if (!pWnd)
2356  pWnd = ptiIME->MessageQueue->spwndFocus;
2357 
2358  if (pWnd)
2359  {
2360  bSendNotify = TRUE;
2361  pimeui->fShowStatus = bShow;
2362  }
2363  }
2365  {
2366  if (pti != ptiIME)
2367  KeDetachProcess();
2368  return;
2369  }
2370  _SEH2_END;
2371 
2372  // Detach from the process if necessary
2373  if (pti != ptiIME)
2374  KeDetachProcess();
2375 
2376  if (bSendNotify)
2377  IntSendOpenStatusNotify(ptiIME, &SafeImeUI, pWnd, bShow);
2378 
2379  if (!(pImeWnd->state2 & WNDS2_INDESTROY))
2380  IntCheckImeShowStatus(pImeWnd, NULL);
2381 }
2382 
2383 // Win: xxxBroadcastImeShowStatusChange
2385 {
2386  if (gfIMEShowStatus == bShow || !IS_IMM_MODE())
2387  return TRUE;
2388 
2389  gfIMEShowStatus = bShow;
2390  IntNotifyImeShowStatus(pImeWnd);
2391  return TRUE;
2392 }
2393 
2394 /* EOF */
_SEH2_TRY
Definition: create.c:4226
#define IME_CMODE_CHARCODE
Definition: imm.h:495
VOID FASTCALL IntNotifyImeShowStatus(PWND pImeWnd)
Definition: ime.c:2327
VOID NTAPI RtlInitLargeUnicodeString(IN OUT PLARGE_UNICODE_STRING, IN PCWSTR, IN INT)
Definition: rtlstr.c:42
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:13
UINT FASTCALL IntImmProcessKey(PUSER_MESSAGE_QUEUE MessageQueue, PWND pWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: ime.c:578
BOOL gfImeOpen
Definition: ime.c:42
#define WS_DISABLED
Definition: pedump.c:621
#define IME_CHOTKEY_IME_NONIME_TOGGLE
Definition: imm.h:331
#define MOD_ALT
Definition: imm.h:319
#define HWND_TERMINATOR
Definition: window.h:82
#define IS_WND_CHILD(pWnd)
Definition: window.h:107
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:242
DWORD FASTCALL IntAssociateInputContextEx(PWND pWnd, PIMC pIMC, DWORD dwFlags)
Definition: ime.c:1639
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
#define WM_IME_NOTIFY
Definition: winuser.h:1820
#define IS_WND_MENU(pWnd)
Definition: window.h:108
#define LONG_PTR
Definition: treelist.c:79
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1346
#define MAKELCID(lgid, srtid)
#define INVALID_THREAD_ID
Definition: ime.c:13
BOOL FASTCALL UserSetImeInfoEx(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PIMEINFOEX pImeInfoEx)
Definition: ime.c:1094
DWORD ExStyle
Definition: ntuser.h:683
PVOID pSelf
Definition: ntuser.h:187
BOOL FASTCALL UserDeleteObject(HANDLE h, HANDLE_TYPE type)
Definition: object.c:717
#define NOTHING
Definition: input_list.c:10
static BOOL APIENTRY IntSetImeHotKey(DWORD dwHotKeyId, UINT uModifiers, UINT uVirtualKey, HKL hKL, DWORD dwAction)
Definition: ime.c:353
#define IMN_CLOSESTATUSWINDOW
Definition: imm.h:521
static PIMEHOTKEY APIENTRY IntGetImeHotKeyByKeyAndLang(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, UINT uVirtualKey, LANGID TargetLangId)
Definition: ime.c:173
struct _DESKTOP * rpdesk
Definition: ntuser.h:186
VOID FASTCALL IntUnlinkWindow(PWND Wnd)
Definition: window.c:1341
struct tagIMC * spDefaultImc
Definition: win32.h:128
#define _Inout_
Definition: ms_sal.h:378
#define IMN_OPENSTATUSWINDOW
Definition: imm.h:522
#define DWORD_PTR
Definition: treelist.c:76
#define LOBYTE(W)
Definition: jmemdos.c:487
PVOID UserGetObjectNoErr(PUSER_HANDLE_TABLE ht, HANDLE handle, HANDLE_TYPE type)
Definition: object.c:481
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define WNDS2_BOTTOMMOST
Definition: ntuser.h:629
PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew)
Definition: object.c:840
DWORD APIENTRY co_IntImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM lParam, DWORD dwHotKeyID)
Definition: callback.c:1253
#define LANGID_KOREAN
Definition: ime.c:20
NTSTATUS NTAPI NtUserBuildHimcList(DWORD dwThreadId, DWORD dwCount, HIMC *phList, LPDWORD pdwCount)
Definition: ime.c:698
#define TRUE
Definition: types.h:120
struct tagIMEHOTKEY IMEHOTKEY
PTHREADINFO ptiSibling
Definition: win32.h:112
#define VK_RMENU
Definition: winuser.h:2277
ULONG_PTR dwClientImcData
Definition: ntuser.h:194
#define IS_IMM_MODE()
Definition: ntuser.h:1204
#define ASSERT_REFS_CO(_obj_)
Definition: userfuncs.h:14
#define VK_LSHIFT
Definition: winuser.h:2272
FLONG TIF_flags
Definition: win32.h:91
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
#define VK_DBE_ENTERWORDREGISTERMODE
Definition: ime.c:33
Definition: ntuser.h:190
LONG NTSTATUS
Definition: precomp.h:26
#define WINVER
Definition: targetver.h:11
PSERVERINFO gpsi
Definition: imm.c:17
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
HWND hWnd
Definition: settings.c:17
PWND FASTCALL IntGetLastTopMostWindowNoIME(PWND pImeWnd)
Definition: ime.c:1222
#define WH_SHELL
Definition: winuser.h:40
#define VK_DBE_SBCSCHAR
Definition: ime.c:29
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:27
HANDLE HWND
Definition: compat.h:19
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
PWINDOWLIST FASTCALL IntBuildHwndList(PWND pwnd, DWORD dwFlags, PTHREADINFO pti)
Definition: window.c:1410
NTSYSAPI NTSTATUS NTAPI ZwQueryDefaultLocale(_In_ BOOLEAN UserProfile, _Out_ PLCID DefaultLocaleId)
#define HWND_TOP
Definition: winuser.h:1197
#define VK_DBE_HIRAGANA
Definition: ime.c:28
uint32_t * LPUINT
Definition: typedefs.h:59
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:644
LONG nCntInIMEProc
Definition: ntuser.h:1214
PIMEINFOEX piiex
Definition: input.h:38
#define LANGID_CHINESE_TRADITIONAL
Definition: ime.c:21
DWORD LCID
Definition: nls.h:13
UINT_PTR WPARAM
Definition: windef.h:207
#define VK_HANGUL
Definition: winuser.h:2199
WORD LANGID
Definition: typedefs.h:81
#define WS_CHILD
Definition: pedump.c:617
#define VK_MENU
Definition: winuser.h:2194
_SEH2_END
Definition: create.c:4400
HIMC hImc
Definition: ntuser.h:719
#define BOOL
Definition: nt_native.h:43
#define FASTCALL
Definition: nt_native.h:50
#define LANGID_NEUTRAL
Definition: ime.c:22
RTL_ATOM atomClassName
Definition: ntuser.h:551
struct _DESKTOP * rpdesk
Definition: win32.h:88
#define MOD_LEFT_RIGHT
Definition: ime.c:16
#define DWORD
Definition: nt_native.h:44
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
WPARAM wParam
Definition: combotst.c:138
#define WINVER_WINNT4
Definition: window.h:56
#define IME_PROP_NEED_ALTKEY
Definition: imm.h:216
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, PDESKTOP pDesktop, PTHREADINFO pti, HANDLE *h, HANDLE_TYPE type, ULONG size)
Definition: object.c:568
PWND FASTCALL co_IntCreateDefaultImeWindow(PWND pwndTarget, HINSTANCE hInst)
Definition: ime.c:1960
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define FNID_MESSAGEWND
Definition: ntuser.h:843
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:801
#define VK_F10
Definition: winuser.h:2254
PPROCESSINFO ppi
Definition: win32.h:84
uint32_t ULONG_PTR
Definition: typedefs.h:65
PTHREADINFO FASTCALL IntTID2PTI(HANDLE id)
Definition: misc.c:42
#define IACE_LIST
Definition: window.h:105
PTHREADINFO gptiForeground
Definition: focus.c:15
DWORD NTAPI NtUserCheckImeHotKey(UINT uVirtualKey, LPARAM lParam)
Definition: ime.c:475
#define LANGID_JAPANESE
Definition: ime.c:19
DWORD dwImeCompatFlags
Definition: win32.h:267
#define L(x)
Definition: ntvdm.h:50
HKL hKL
Definition: ime.c:52
#define VK_DBE_ROMAN
Definition: ime.c:31
BOOL NTAPI NtUserDisableThreadIme(DWORD dwThreadID)
Definition: ime.c:859
unsigned char * LPBYTE
Definition: typedefs.h:53
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes)
Definition: desktop.h:204
VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
Definition: window.c:971
#define LANG_JAPANESE
Definition: nls.h:76
#define FALSE
Definition: types.h:117
UINT uModifiers
Definition: ime.c:51
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define IME_CMODE_NATIVE
Definition: imm.h:485
DWORD fnid
Definition: ntuser.h:688
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
BOOLEAN co_UserDestroyWindow(PVOID Object)
Definition: window.c:2841
#define VK_DBE_KATAKANA
Definition: ime.c:27
HWND hwndUI
Definition: ntuser.h:1213
#define FNID_DESKTOP
Definition: ntuser.h:841
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:40
#define SET_KEY_DOWN(ks, vk, down)
Definition: input.h:101
FxChildList * pList
#define INVALID_HOTKEY
Definition: ime.c:14
#define IACE_CHILDREN
Definition: imm.h:581
struct tagIMEHOTKEY * pNext
Definition: ime.c:48
struct _WND * spwndOwner
Definition: ntuser.h:694
THRDESKHEAD head
Definition: ntuser.h:674
#define WSS_NOIO
Definition: winsta.h:9
Definition: object.h:3
#define IME_HOTKEY_DSWITCH_LAST
Definition: imm.h:349
#define MAKELONG(a, b)
Definition: typedefs.h:249
DWORD gSystemFS
Definition: kbdlayout.c:24
unsigned char BOOLEAN
HKL hklPrev
Definition: win32.h:129
BOOL FASTCALL IntWantImeWindow(PWND pwndTarget)
Definition: ime.c:1920
VOID FASTCALL IntFreeHwndList(PWINDOWLIST pwlTarget)
Definition: window.c:1456
struct _WINSTATION_OBJECT * rpwinstaParent
Definition: desktop.h:11
Definition: input.h:26
HWND ahwnd[ANYSIZE_ARRAY]
Definition: window.h:90
#define _In_
Definition: ms_sal.h:308
BOOL FASTCALL IntBroadcastImeShowStatusChange(PWND pImeWnd, BOOL bShow)
Definition: ime.c:2384
#define WM_KEYDOWN
Definition: winuser.h:1705
LONG_PTR LPARAM
Definition: windef.h:208
#define IME_PROP_IGNORE_UPKEYS
Definition: imm.h:215
struct _WND * spwndDefaultIme
Definition: win32.h:127
#define LANGID_CHINESE_SIMPLIFIED
Definition: ime.c:18
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
UINT fDestroy
Definition: ntuser.h:1218
struct _WND * spwndNext
Definition: ntuser.h:690
DWORD NTAPI NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags)
Definition: ime.c:1705
DWORD HIMC
Definition: dimm.idl:75
BOOL FASTCALL IntImeCanDestroyDefIME(PWND pImeWnd, PWND pwndTarget)
Definition: ime.c:2068
VOID FASTCALL IntImeCheckTopmost(PWND pImeWnd)
Definition: ime.c:1349
VOID UserFreeInputContext(PVOID Object)
Definition: ime.c:1460
#define TIF_DISABLEIME
Definition: ntuser.h:279
BOOL NTAPI NtUserUpdateInputContext(HIMC hIMC, DWORD dwType, DWORD_PTR dwValue)
Definition: ime.c:1765
BOOL FASTCALL IntImeCanDestroyDefIMEforChild(PWND pImeWnd, PWND pwndTarget)
Definition: ime.c:2023
#define MOD_KEYS
Definition: ime.c:15
#define VK_DBE_CODEINPUT
Definition: ime.c:36
DWORD dwExpWinVer
Definition: win32.h:108
#define IntReferenceThreadInfo(pti)
Definition: win32.h:162
#define IME_CHOTKEY
BOOLEAN UserDestroyInputContext(PVOID Object)
Definition: ime.c:1487
HINSTANCE hInstance
Definition: winuser.h:2946
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249
#define UserHMGetHandle(obj)
Definition: ntuser.h:222
#define MOD_LEFT
Definition: imm.h:323
#define MOD_IGNORE_ALL_MODIFIER
Definition: imm.h:327
BOOL NTAPI NtUserSetAppImeLevel(HWND hWnd, DWORD dwLevel)
Definition: ime.c:1064
IMEINFOEXCLASS
Definition: ntuser.h:1195
#define ASSERT(a)
Definition: mode.c:44
#define IME_CMODE_ALPHANUMERIC
Definition: imm.h:484
HKL FASTCALL UserGetKeyboardLayout(DWORD dwThreadId)
Definition: kbdlayout.c:857
#define MOD_SHIFT
Definition: imm.h:321
DBG_DEFAULT_CHANNEL(UserMisc)
#define IME_XHOTKEY
#define SORT_DEFAULT
#define IME_CMODE_FULLSHAPE
Definition: imm.h:493
static VOID FASTCALL IntDeleteImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
Definition: ime.c:204
BOOL NTAPI NtUserGetImeInfoEx(PIMEINFOEX pImeInfoEx, IMEINFOEXCLASS SearchType)
Definition: ime.c:1015
#define IME_THOTKEY_IME_NONIME_TOGGLE
Definition: imm.h:343
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
DWORD fdwProperty
Definition: imm.h:158
#define UlongToHandle(ul)
Definition: basetsd.h:97
BOOL FASTCALL UserUpdateInputContext(PIMC pIMC, DWORD dwType, DWORD_PTR dwValue)
Definition: ime.c:1732
HANDLE NTAPI PsGetThreadProcessId(IN PETHREAD Thread)
Definition: thread.c:745
static VOID FASTCALL IntAddImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
Definition: ime.c:139
#define IME_CMODE_KATAKANA
Definition: imm.h:491
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:84
DWORD FASTCALL UserBuildHimcList(PTHREADINFO pti, DWORD dwCount, HIMC *phList)
Definition: ime.c:544
HKL hkl
Definition: input.h:32
#define ISITHOOKED(HookId)
Definition: hook.h:6
HANDLE FASTCALL UserGetProp(_In_ PWND Window, _In_ ATOM Atom, _In_ BOOLEAN SystemProp)
Definition: prop.c:46
#define WM_KEYUP
Definition: winuser.h:1706
unsigned short WORD
Definition: ntddk_ex.h:93
PWND spwndMessage
Definition: desktop.h:20
unsigned long DWORD
Definition: ntddk_ex.h:95
HWND hImeWnd
Definition: ntuser.h:195
DWORD NTAPI NtUserGetAppImeLevel(HWND hWnd)
Definition: ime.c:928
struct _CLIENTINFO * pClientInfo
Definition: win32.h:90
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
WCHAR * PWCH
Definition: ntbasedef.h:410
LRESULT APIENTRY co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:1103
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
PWND FASTCALL UserGetDesktopWindow(VOID)
Definition: desktop.c:1386
#define VK_DBE_ENTERCONFIGMODE
Definition: ime.c:34
UINT fChildThreadDef
Definition: ntuser.h:1220
int ret
DWORD dwThreadId
Definition: fdebug.c:31
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define ICLS_IME
Definition: ntuser.h:906
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1446
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:310
#define InterlockedDecrement
Definition: armddk.h:52
#define MOD_ON_KEYUP
Definition: imm.h:326
#define VK_RCONTROL
Definition: winuser.h:2275
DWORD NTAPI NtUserSetThreadLayoutHandles(HKL hNewKL, HKL hOldKL)
Definition: ime.c:516
#define VK_LMENU
Definition: winuser.h:2276
DWORD NTAPI NtUserNotifyIMEStatus(HWND hwnd, BOOL fOpen, DWORD dwConversion)
Definition: ime.c:810
#define VK_RSHIFT
Definition: winuser.h:2273
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
LPCWSTR lpszName
Definition: winuser.h:2954
BOOL gfIMEShowStatus
Definition: ime.c:44
BYTE afKeyState[256 *2/8]
Definition: msgqueue.h:84
DWORD dwFontSigs
Definition: input.h:34
DWORD dwHotKeyId
Definition: ime.c:49
PVOID AllocInputContextObject(PDESKTOP pDesk, PTHREADINFO pti, SIZE_T Size, PVOID *HandleOwner)
Definition: ime.c:1431
#define VK_DBE_NOROMAN
Definition: ime.c:32
#define LANGIDFROMLCID(l)
Definition: nls.h:18
#define WS_EX_TOPMOST
Definition: pedump.c:647
ATOM AtomImeLevel
Definition: ntuser.c:28
HANDLE NTAPI PsGetThreadId(IN PETHREAD Thread)
Definition: thread.c:705
UINT_PTR HKL
Definition: msctf.idl:101
LCID glcidSystem
Definition: ime.c:56
#define VK_DBE_ALPHANUMERIC
Definition: ime.c:26
uint32_t DWORD_PTR
Definition: typedefs.h:65
struct tagKL * KeyboardLayout
Definition: win32.h:86
unsigned char BYTE
Definition: xxhash.c:193
#define IME_CMODE_HANJACONVERT
Definition: imm.h:496
struct tagKL * pklNext
Definition: input.h:29
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
struct tagIMEHOTKEY * PIMEHOTKEY
#define ERR(fmt,...)
Definition: debug.h:110
HIMC ghIMC
Definition: ime.c:41
Definition: ntuser.h:672
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:85
WCHAR wszImeFile[80]
Definition: ntuser.h:1187
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:258
ULONG_PTR SIZE_T
Definition: typedefs.h:80
HIMC FASTCALL IntAssociateInputContext(PWND pWnd, PIMC pImc)
Definition: ime.c:507
#define VK_HANJA
Definition: winuser.h:2202
struct _IMEWND * PIMEWND
#define IACE_IGNORENOCONTEXT
Definition: imm.h:583
BOOL IntFindNonImeRelatedWndOfSameThread(PWND pwndParent, PWND pwndTarget)
Definition: ime.c:1844
BOOL IntDestroyInputContext(PIMC pIMC)
Definition: ime.c:1499
HINSTANCE hInst
Definition: dxdiag.c:13
#define IS_IME_HKL(hKL)
Definition: input.h:88
IMEINFO ImeInfo
Definition: ntuser.h:1179
#define InterlockedIncrement
Definition: armddk.h:53
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define IME_HOTKEY_DSWITCH_FIRST
Definition: imm.h:348
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, HANDLE_TYPE type)
Definition: object.c:495
BOOL NTAPI NtUserSetImeHotKey(DWORD dwHotKeyId, UINT uModifiers, UINT uVirtualKey, HKL hKL, DWORD dwAction)
Definition: ime.c:459
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:582
#define WM_SYSKEYUP
Definition: winuser.h:1710
BOOL FASTCALL IntCheckImeShowStatus(PWND pwndIme, PTHREADINFO pti)
Definition: ime.c:2132
#define W32PF_DISABLEIME
Definition: win32.h:28
#define VK_JUNJA
Definition: winuser.h:2200
VOID FASTCALL IntSendOpenStatusNotify(PTHREADINFO ptiIME, PIMEUI pimeui, PWND pWnd, BOOL bOpen)
Definition: ime.c:2307
VOID FASTCALL IntImeSetFutureOwner(PWND pImeWnd, PWND pwndOwner)
Definition: ime.c:1165
DWORD state
Definition: ntuser.h:680
HIMC NTAPI NtUserCreateInputContext(ULONG_PTR dwClientImcData)
Definition: ime.c:1609
#define VK_DBE_NOCODEINPUT
Definition: ime.c:37
#define USERTAG_IMEHOTKEY
Definition: tags.h:239
UINT fDefault
Definition: ntuser.h:1219
#define IME_CMODE_ROMAN
Definition: imm.h:494
THRDESKHEAD head
Definition: ntuser.h:192
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define WS_POPUP
Definition: pedump.c:616
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
INT fLoadFlag
Definition: ntuser.h:1183
PIMEHOTKEY gpImeHotKeyList
Definition: ime.c:55
UINT uVirtualKey
Definition: ime.c:50
#define MOD_RIGHT
Definition: imm.h:324
UINT fShowStatus
Definition: ntuser.h:1216
static VOID FASTCALL UserSetImeConversionKeyState(PTHREADINFO pti, DWORD dwConversion)
Definition: ime.c:751
#define IPHK_HOTKEY
Definition: undocuser.h:138
DWORD_PTR NTAPI NtUserQueryInputContext(HIMC hIMC, DWORD dwType)
Definition: ime.c:1794
#define IS_WND_IMELIKE(pWnd)
Definition: window.h:113
#define WM_SYSKEYDOWN
Definition: winuser.h:1709
uint32_t * LPDWORD
Definition: typedefs.h:59
struct _WND * spwndParent
Definition: ntuser.h:692
LPCWSTR lpszClass
Definition: winuser.h:2955
static PIMEHOTKEY FASTCALL IntGetImeHotKeyById(PIMEHOTKEY pList, DWORD dwHotKeyId)
Definition: ime.c:160
DWORD state2
Definition: ntuser.h:681
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
struct tagIMC * pImcNext
Definition: ntuser.h:193
BOOL NTAPI NtUserSetImeOwnerWindow(HWND hImeWnd, HWND hwndFocus)
Definition: ime.c:1365
#define IS_KEY_DOWN(ks, vk)
Definition: input.h:99
#define LANG_KOREAN
Definition: nls.h:84
UINT fCtrlShowStatus
Definition: ntuser.h:1221
PTHREADINFO ptiList
Definition: win32.h:247
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
BOOL FASTCALL UserGetImeInfoEx(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PIMEINFOEX pInfoEx, _In_ IMEINFOEXCLASS SearchType)
Definition: ime.c:958
PWND FASTCALL IntGetTopLevelWindow(PWND pwnd)
Definition: ime.c:495
static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem)
Definition: desktop.h:215
#define STATUS_SUCCESS
Definition: shellext.h:65
HWND hwndIMC
Definition: ntuser.h:1211
DWORD gdwImeConversion
Definition: ime.c:43
LONG_PTR LRESULT
Definition: windef.h:209
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
#define VK_LCONTROL
Definition: winuser.h:2274
_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:1075
#define MOD_CONTROL
Definition: imm.h:320
struct _WND * spwndChild
Definition: ntuser.h:693
PIMEHOTKEY IntCheckImeHotKey(PUSER_MESSAGE_QUEUE MessageQueue, UINT uVirtualKey, LPARAM lParam)
Definition: ime.c:289
#define IACE_DEFAULT
Definition: imm.h:582
#define SET_KEY_LOCKED(ks, vk, down)
Definition: input.h:104
#define WS_VISIBLE
Definition: pedump.c:620
PUSER_HANDLE_TABLE gHandleTable
Definition: object.c:13
PWINSTATION_OBJECT FASTCALL IntGetProcessWindowStation(HWINSTA *phWinSta OPTIONAL)
Definition: winsta.c:400
BOOL NTAPI NtUserGetImeHotKey(DWORD dwHotKeyId, LPUINT lpuModifiers, LPUINT lpuVirtualKey, LPHKL lphKL)
Definition: ime.c:416
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define IntDereferenceThreadInfo(pti)
Definition: win32.h:167
#define WNDS_SERVERSIDEWINDOWPROC
Definition: ntuser.h:606
VOID FASTCALL IntImeSetTopMost(PWND pImeWnd, BOOL bTopMost, PWND pwndInsertBefore)
Definition: ime.c:1259
VOID FASTCALL IntFreeImeHotKeys(VOID)
Definition: ime.c:340
LPARAM lParam
Definition: combotst.c:139
PIMC FASTCALL UserCreateInputContext(ULONG_PTR dwClientImcData)
Definition: ime.c:1561
#define LOWORD(l)
Definition: pedump.c:82
#define TIF_INCLEANUP
Definition: ntuser.h:254
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:28
HANDLE gpidLogon
Definition: simplecall.c:15
PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW *Cs, PUNICODE_STRING ClassName, PLARGE_STRING WindowName, PVOID acbiBuffer, DWORD dwVer)
Definition: window.c:2185
#define APIENTRY
Definition: api.h:79
PKL gspklBaseLayout
Definition: kbdlayout.c:22
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:541
#define WNDS2_INDESTROY
Definition: ntuser.h:631
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1031
PIMEHOTKEY IntGetImeHotKeyByKey(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, UINT uVirtualKey)
Definition: ime.c:228
DWORD FASTCALL IntGetImeCompatFlags(PTHREADINFO pti)
Definition: ime.c:59
#define FNID_IME
Definition: ntuser.h:853
HKL FASTCALL IntGetActiveKeyboardLayout(VOID)
Definition: ime.c:98
LRESULT FASTCALL IntSendMessageToUI(PTHREADINFO ptiIME, PIMEUI pimeui, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: ime.c:2228
BOOL NTAPI NtUserSetImeInfoEx(PIMEINFOEX pImeInfoEx)
Definition: ime.c:1130
#define PRIMARYLANGID(l)
Definition: nls.h:16
BOOL NTAPI NtUserDestroyInputContext(HIMC hIMC)
Definition: ime.c:1538
PCLS pcls
Definition: ntuser.h:699
static LANGID FASTCALL IntGetImeHotKeyLangId(DWORD dwHotKeyId)
Definition: ime.c:113
DWORD style
Definition: ntuser.h:685
UINT FASTCALL IntGetImeHotKeyLanguageScore(HKL hKL, LANGID HotKeyLangId)
Definition: ime.c:68
#define VK_DBE_DBCSCHAR
Definition: ime.c:30
BOOL FASTCALL UserMarkObjectDestroy(PVOID Object)
Definition: object.c:621