xref: /reactos/win32ss/user/ntuser/ime.c (revision 0f1e19a7)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * COPYRIGHT:        See COPYING in the top level directory
3c2c66affSColin Finck  * PROJECT:          ReactOS Win32k subsystem
4c2c66affSColin Finck  * PURPOSE:          Input Method Editor and Input Method Manager support
5c2c66affSColin Finck  * FILE:             win32ss/user/ntuser/ime.c
63d78601fSKatayama Hirofumi MZ  * PROGRAMERS:       Casper S. Hornstrup (chorns@users.sourceforge.net)
73d78601fSKatayama Hirofumi MZ  *                   Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
8c2c66affSColin Finck  */
9c2c66affSColin Finck 
10c2c66affSColin Finck #include <win32k.h>
11c2c66affSColin Finck DBG_DEFAULT_CHANNEL(UserMisc);
12c2c66affSColin Finck 
13fcc222c2SKatayama Hirofumi MZ #define INVALID_THREAD_ID  ((ULONG)-1)
14bbe5fd52SKatayama Hirofumi MZ #define INVALID_HOTKEY     ((UINT)-1)
155d5cc578SKatayama Hirofumi MZ #define MOD_KEYS           (MOD_CONTROL | MOD_SHIFT | MOD_ALT | MOD_WIN)
165d5cc578SKatayama Hirofumi MZ #define MOD_LEFT_RIGHT     (MOD_LEFT | MOD_RIGHT)
175d5cc578SKatayama Hirofumi MZ 
185d5cc578SKatayama Hirofumi MZ #define LANGID_CHINESE_SIMPLIFIED   MAKELANGID(LANG_CHINESE,  SUBLANG_CHINESE_SIMPLIFIED)
195d5cc578SKatayama Hirofumi MZ #define LANGID_JAPANESE             MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)
205d5cc578SKatayama Hirofumi MZ #define LANGID_KOREAN               MAKELANGID(LANG_KOREAN,   SUBLANG_KOREAN)
215d5cc578SKatayama Hirofumi MZ #define LANGID_CHINESE_TRADITIONAL  MAKELANGID(LANG_CHINESE,  SUBLANG_CHINESE_TRADITIONAL)
225d5cc578SKatayama Hirofumi MZ #define LANGID_NEUTRAL              MAKELANGID(LANG_NEUTRAL,  SUBLANG_NEUTRAL)
23c2c66affSColin Finck 
240519ae0aSKatayama Hirofumi MZ #define IS_WND_IMELIKE(pwnd) \
250519ae0aSKatayama Hirofumi MZ     (((pwnd)->pcls->style & CS_IME) || \
260519ae0aSKatayama Hirofumi MZ      ((pwnd)->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME]))
270519ae0aSKatayama Hirofumi MZ 
289db44371SKatayama Hirofumi MZ // The special virtual keys for Japanese: Used for key states.
299db44371SKatayama Hirofumi MZ // https://www.kthree.co.jp/kihelp/index.html?page=app/vkey&type=html
309db44371SKatayama Hirofumi MZ #define VK_DBE_ALPHANUMERIC 0xF0
319db44371SKatayama Hirofumi MZ #define VK_DBE_KATAKANA 0xF1
329db44371SKatayama Hirofumi MZ #define VK_DBE_HIRAGANA 0xF2
339db44371SKatayama Hirofumi MZ #define VK_DBE_SBCSCHAR 0xF3
349db44371SKatayama Hirofumi MZ #define VK_DBE_DBCSCHAR 0xF4
359db44371SKatayama Hirofumi MZ #define VK_DBE_ROMAN 0xF5
369db44371SKatayama Hirofumi MZ #define VK_DBE_NOROMAN 0xF6
379db44371SKatayama Hirofumi MZ #define VK_DBE_ENTERWORDREGISTERMODE 0xF7
389db44371SKatayama Hirofumi MZ #define VK_DBE_ENTERCONFIGMODE 0xF8
399db44371SKatayama Hirofumi MZ #define VK_DBE_FLUSHSTRING 0xF9
409db44371SKatayama Hirofumi MZ #define VK_DBE_CODEINPUT 0xFA
419db44371SKatayama Hirofumi MZ #define VK_DBE_NOCODEINPUT 0xFB
429db44371SKatayama Hirofumi MZ #define VK_DBE_DETERINESTRING 0xFC
439db44371SKatayama Hirofumi MZ #define VK_DBE_ENTERDLGCONVERSIONMODE 0xFD
449db44371SKatayama Hirofumi MZ 
459db44371SKatayama Hirofumi MZ HIMC ghIMC = NULL;
469db44371SKatayama Hirofumi MZ BOOL gfImeOpen = (BOOL)-1;
479db44371SKatayama Hirofumi MZ DWORD gdwImeConversion = (DWORD)-1;
489db44371SKatayama Hirofumi MZ 
495d5cc578SKatayama Hirofumi MZ typedef struct tagIMEHOTKEY
505d5cc578SKatayama Hirofumi MZ {
515d5cc578SKatayama Hirofumi MZ     struct tagIMEHOTKEY *pNext;
525d5cc578SKatayama Hirofumi MZ     DWORD  dwHotKeyId;
535d5cc578SKatayama Hirofumi MZ     UINT   uVirtualKey;
545d5cc578SKatayama Hirofumi MZ     UINT   uModifiers;
555d5cc578SKatayama Hirofumi MZ     HKL    hKL;
565d5cc578SKatayama Hirofumi MZ } IMEHOTKEY, *PIMEHOTKEY;
575d5cc578SKatayama Hirofumi MZ 
585d5cc578SKatayama Hirofumi MZ PIMEHOTKEY gpImeHotKeyList = NULL;
59bbe5fd52SKatayama Hirofumi MZ LCID glcid = 0;
60bbe5fd52SKatayama Hirofumi MZ 
61b5c9d532SKatayama Hirofumi MZ DWORD FASTCALL IntGetImeCompatFlags(PTHREADINFO pti)
62b5c9d532SKatayama Hirofumi MZ {
63b5c9d532SKatayama Hirofumi MZ     if (!pti)
64b5c9d532SKatayama Hirofumi MZ         pti = PsGetCurrentThreadWin32Thread();
65b5c9d532SKatayama Hirofumi MZ 
66b5c9d532SKatayama Hirofumi MZ     return pti->ppi->dwImeCompatFlags;
67b5c9d532SKatayama Hirofumi MZ }
68b5c9d532SKatayama Hirofumi MZ 
69bbe5fd52SKatayama Hirofumi MZ UINT FASTCALL IntGetImeHotKeyLanguageScore(HKL hKL, LANGID HotKeyLangId)
70bbe5fd52SKatayama Hirofumi MZ {
71bbe5fd52SKatayama Hirofumi MZ     LCID lcid;
72bbe5fd52SKatayama Hirofumi MZ 
73bbe5fd52SKatayama Hirofumi MZ     if (HotKeyLangId == LANGID_NEUTRAL || HotKeyLangId == LOWORD(hKL))
74bbe5fd52SKatayama Hirofumi MZ         return 3;
75bbe5fd52SKatayama Hirofumi MZ 
76bbe5fd52SKatayama Hirofumi MZ     _SEH2_TRY
77bbe5fd52SKatayama Hirofumi MZ     {
78bbe5fd52SKatayama Hirofumi MZ         lcid = NtCurrentTeb()->CurrentLocale;
79bbe5fd52SKatayama Hirofumi MZ     }
80bbe5fd52SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
81bbe5fd52SKatayama Hirofumi MZ     {
82bbe5fd52SKatayama Hirofumi MZ         lcid = MAKELCID(LANGID_NEUTRAL, SORT_DEFAULT);
83bbe5fd52SKatayama Hirofumi MZ     }
84bbe5fd52SKatayama Hirofumi MZ     _SEH2_END;
85bbe5fd52SKatayama Hirofumi MZ 
86bbe5fd52SKatayama Hirofumi MZ     if (HotKeyLangId == LANGIDFROMLCID(lcid))
87bbe5fd52SKatayama Hirofumi MZ         return 2;
88bbe5fd52SKatayama Hirofumi MZ 
89bbe5fd52SKatayama Hirofumi MZ     if (glcid == 0)
90bbe5fd52SKatayama Hirofumi MZ         ZwQueryDefaultLocale(FALSE, &glcid);
91bbe5fd52SKatayama Hirofumi MZ 
92bbe5fd52SKatayama Hirofumi MZ     if (HotKeyLangId == LANGIDFROMLCID(glcid))
93bbe5fd52SKatayama Hirofumi MZ         return 1;
94bbe5fd52SKatayama Hirofumi MZ 
95bbe5fd52SKatayama Hirofumi MZ     return 0;
96bbe5fd52SKatayama Hirofumi MZ }
97bbe5fd52SKatayama Hirofumi MZ 
98bbe5fd52SKatayama Hirofumi MZ HKL FASTCALL IntGetActiveKeyboardLayout(VOID)
99bbe5fd52SKatayama Hirofumi MZ {
100bbe5fd52SKatayama Hirofumi MZ     PTHREADINFO pti;
101bbe5fd52SKatayama Hirofumi MZ 
102bbe5fd52SKatayama Hirofumi MZ     if (gpqForeground && gpqForeground->spwndActive)
103bbe5fd52SKatayama Hirofumi MZ     {
104bbe5fd52SKatayama Hirofumi MZ         pti = gpqForeground->spwndActive->head.pti;
105bbe5fd52SKatayama Hirofumi MZ         if (pti && pti->KeyboardLayout)
106bbe5fd52SKatayama Hirofumi MZ             return pti->KeyboardLayout->hkl;
107bbe5fd52SKatayama Hirofumi MZ     }
108bbe5fd52SKatayama Hirofumi MZ 
109bbe5fd52SKatayama Hirofumi MZ     return UserGetKeyboardLayout(0);
110bbe5fd52SKatayama Hirofumi MZ }
1115d5cc578SKatayama Hirofumi MZ 
1125d5cc578SKatayama Hirofumi MZ static LANGID FASTCALL IntGetImeHotKeyLangId(DWORD dwHotKeyId)
1135d5cc578SKatayama Hirofumi MZ {
1145d5cc578SKatayama Hirofumi MZ #define IME_CHOTKEY 0x10
1155d5cc578SKatayama Hirofumi MZ #define IME_JHOTKEY 0x30
1165d5cc578SKatayama Hirofumi MZ #define IME_KHOTKEY 0x50
1175d5cc578SKatayama Hirofumi MZ #define IME_THOTKEY 0x70
1185d5cc578SKatayama Hirofumi MZ #define IME_XHOTKEY 0x90
1195d5cc578SKatayama Hirofumi MZ     static const LANGID s_array[] =
1205d5cc578SKatayama Hirofumi MZ     {
1215d5cc578SKatayama Hirofumi MZ         /* 0x00 */ (WORD)-1,
1225d5cc578SKatayama Hirofumi MZ         /* 0x10 */ LANGID_CHINESE_SIMPLIFIED,
1235d5cc578SKatayama Hirofumi MZ         /* 0x20 */ LANGID_CHINESE_SIMPLIFIED,
1245d5cc578SKatayama Hirofumi MZ         /* 0x30 */ LANGID_JAPANESE,
1255d5cc578SKatayama Hirofumi MZ         /* 0x40 */ LANGID_JAPANESE,
1265d5cc578SKatayama Hirofumi MZ         /* 0x50 */ LANGID_KOREAN,
1275d5cc578SKatayama Hirofumi MZ         /* 0x60 */ LANGID_KOREAN,
1285d5cc578SKatayama Hirofumi MZ         /* 0x70 */ LANGID_CHINESE_TRADITIONAL,
1295d5cc578SKatayama Hirofumi MZ         /* 0x80 */ LANGID_CHINESE_TRADITIONAL
1305d5cc578SKatayama Hirofumi MZ     };
1315d5cc578SKatayama Hirofumi MZ 
1325d5cc578SKatayama Hirofumi MZ     if (IME_CHOTKEY <= dwHotKeyId && dwHotKeyId < IME_XHOTKEY)
1335d5cc578SKatayama Hirofumi MZ         return s_array[(dwHotKeyId & 0xF0) >> 4];
1345d5cc578SKatayama Hirofumi MZ     return LANGID_NEUTRAL;
1355d5cc578SKatayama Hirofumi MZ }
1365d5cc578SKatayama Hirofumi MZ 
1372f7775c6SKatayama Hirofumi MZ // Win: AddImeHotKey
1385d5cc578SKatayama Hirofumi MZ static VOID FASTCALL IntAddImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
1395d5cc578SKatayama Hirofumi MZ {
1405d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
1415d5cc578SKatayama Hirofumi MZ 
1425d5cc578SKatayama Hirofumi MZ     if (!*ppList)
1435d5cc578SKatayama Hirofumi MZ     {
1445d5cc578SKatayama Hirofumi MZ         *ppList = pHotKey;
1455d5cc578SKatayama Hirofumi MZ         return;
1465d5cc578SKatayama Hirofumi MZ     }
1475d5cc578SKatayama Hirofumi MZ 
1485d5cc578SKatayama Hirofumi MZ     for (pNode = *ppList; pNode; pNode = pNode->pNext)
1495d5cc578SKatayama Hirofumi MZ     {
1505d5cc578SKatayama Hirofumi MZ         if (!pNode->pNext)
1515d5cc578SKatayama Hirofumi MZ         {
1525d5cc578SKatayama Hirofumi MZ             pNode->pNext = pHotKey;
1535d5cc578SKatayama Hirofumi MZ             return;
1545d5cc578SKatayama Hirofumi MZ         }
1555d5cc578SKatayama Hirofumi MZ     }
1565d5cc578SKatayama Hirofumi MZ }
1575d5cc578SKatayama Hirofumi MZ 
1585d5cc578SKatayama Hirofumi MZ static PIMEHOTKEY FASTCALL IntGetImeHotKeyById(PIMEHOTKEY pList, DWORD dwHotKeyId)
1595d5cc578SKatayama Hirofumi MZ {
1605d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
1615d5cc578SKatayama Hirofumi MZ     for (pNode = pList; pNode; pNode = pNode->pNext)
1625d5cc578SKatayama Hirofumi MZ     {
1635d5cc578SKatayama Hirofumi MZ         if (pNode->dwHotKeyId == dwHotKeyId)
1645d5cc578SKatayama Hirofumi MZ             return pNode;
1655d5cc578SKatayama Hirofumi MZ     }
1665d5cc578SKatayama Hirofumi MZ     return NULL;
1675d5cc578SKatayama Hirofumi MZ }
1685d5cc578SKatayama Hirofumi MZ 
1695d5cc578SKatayama Hirofumi MZ static PIMEHOTKEY APIENTRY
1705d5cc578SKatayama Hirofumi MZ IntGetImeHotKeyByKeyAndLang(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight,
1715d5cc578SKatayama Hirofumi MZ                             UINT uVirtualKey, LANGID TargetLangId)
1725d5cc578SKatayama Hirofumi MZ {
1735d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
1745d5cc578SKatayama Hirofumi MZ     LANGID LangID;
1755d5cc578SKatayama Hirofumi MZ     UINT uModifiers;
1765d5cc578SKatayama Hirofumi MZ 
1775d5cc578SKatayama Hirofumi MZ     for (pNode = pList; pNode; pNode = pNode->pNext)
1785d5cc578SKatayama Hirofumi MZ     {
1795d5cc578SKatayama Hirofumi MZ         if (pNode->uVirtualKey != uVirtualKey)
1805d5cc578SKatayama Hirofumi MZ             continue;
1815d5cc578SKatayama Hirofumi MZ 
1825d5cc578SKatayama Hirofumi MZ         LangID = IntGetImeHotKeyLangId(pNode->dwHotKeyId);
1835d5cc578SKatayama Hirofumi MZ         if (LangID != TargetLangId)
1845d5cc578SKatayama Hirofumi MZ             continue;
1855d5cc578SKatayama Hirofumi MZ 
1865d5cc578SKatayama Hirofumi MZ         uModifiers = pNode->uModifiers;
1875d5cc578SKatayama Hirofumi MZ         if (uModifiers & MOD_IGNORE_ALL_MODIFIER)
1885d5cc578SKatayama Hirofumi MZ             return pNode;
1895d5cc578SKatayama Hirofumi MZ 
1905d5cc578SKatayama Hirofumi MZ         if ((uModifiers & MOD_KEYS) != uModKeys)
1915d5cc578SKatayama Hirofumi MZ             continue;
1925d5cc578SKatayama Hirofumi MZ 
1935d5cc578SKatayama Hirofumi MZ         if ((uModifiers & uLeftRight) || (uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
1945d5cc578SKatayama Hirofumi MZ             return pNode;
1955d5cc578SKatayama Hirofumi MZ     }
1965d5cc578SKatayama Hirofumi MZ 
1975d5cc578SKatayama Hirofumi MZ     return NULL;
1985d5cc578SKatayama Hirofumi MZ }
1995d5cc578SKatayama Hirofumi MZ 
2005d5cc578SKatayama Hirofumi MZ static VOID FASTCALL IntDeleteImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
2015d5cc578SKatayama Hirofumi MZ {
2025d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
2035d5cc578SKatayama Hirofumi MZ 
2045d5cc578SKatayama Hirofumi MZ     if (*ppList == pHotKey)
2055d5cc578SKatayama Hirofumi MZ     {
2065d5cc578SKatayama Hirofumi MZ         *ppList = pHotKey->pNext;
2075d5cc578SKatayama Hirofumi MZ         ExFreePoolWithTag(pHotKey, USERTAG_IMEHOTKEY);
2085d5cc578SKatayama Hirofumi MZ         return;
2095d5cc578SKatayama Hirofumi MZ     }
2105d5cc578SKatayama Hirofumi MZ 
2115d5cc578SKatayama Hirofumi MZ     for (pNode = *ppList; pNode; pNode = pNode->pNext)
2125d5cc578SKatayama Hirofumi MZ     {
2135d5cc578SKatayama Hirofumi MZ         if (pNode->pNext == pHotKey)
2145d5cc578SKatayama Hirofumi MZ         {
2155d5cc578SKatayama Hirofumi MZ             pNode->pNext = pHotKey->pNext;
2165d5cc578SKatayama Hirofumi MZ             ExFreePoolWithTag(pHotKey, USERTAG_IMEHOTKEY);
2175d5cc578SKatayama Hirofumi MZ             return;
2185d5cc578SKatayama Hirofumi MZ         }
2195d5cc578SKatayama Hirofumi MZ     }
2205d5cc578SKatayama Hirofumi MZ }
2215d5cc578SKatayama Hirofumi MZ 
222bbe5fd52SKatayama Hirofumi MZ PIMEHOTKEY
223bbe5fd52SKatayama Hirofumi MZ IntGetImeHotKeyByKey(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, UINT uVirtualKey)
224bbe5fd52SKatayama Hirofumi MZ {
225bbe5fd52SKatayama Hirofumi MZ     PIMEHOTKEY pNode, ret = NULL;
226bbe5fd52SKatayama Hirofumi MZ     PTHREADINFO pti = GetW32ThreadInfo();
227bbe5fd52SKatayama Hirofumi MZ     LANGID LangId;
228bbe5fd52SKatayama Hirofumi MZ     HKL hKL = IntGetActiveKeyboardLayout();
229bbe5fd52SKatayama Hirofumi MZ     BOOL fKorean = (PRIMARYLANGID(LOWORD(hKL)) == LANG_KOREAN);
230bbe5fd52SKatayama Hirofumi MZ     UINT nScore, nMaxScore = 0;
231bbe5fd52SKatayama Hirofumi MZ 
232bbe5fd52SKatayama Hirofumi MZ     for (pNode = pList; pNode; pNode = pNode->pNext)
233bbe5fd52SKatayama Hirofumi MZ     {
234bbe5fd52SKatayama Hirofumi MZ         if (pNode->uVirtualKey != uVirtualKey)
235bbe5fd52SKatayama Hirofumi MZ             continue;
236bbe5fd52SKatayama Hirofumi MZ 
237bbe5fd52SKatayama Hirofumi MZ         if ((pNode->uModifiers & MOD_IGNORE_ALL_MODIFIER))
238bbe5fd52SKatayama Hirofumi MZ         {
239bbe5fd52SKatayama Hirofumi MZ             ;
240bbe5fd52SKatayama Hirofumi MZ         }
241bbe5fd52SKatayama Hirofumi MZ         else if ((pNode->uModifiers & MOD_KEYS) != uModKeys)
242bbe5fd52SKatayama Hirofumi MZ         {
243bbe5fd52SKatayama Hirofumi MZ             continue;
244bbe5fd52SKatayama Hirofumi MZ         }
245bbe5fd52SKatayama Hirofumi MZ         else if ((pNode->uModifiers & uLeftRight) ||
246bbe5fd52SKatayama Hirofumi MZ                  (pNode->uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
247bbe5fd52SKatayama Hirofumi MZ         {
248bbe5fd52SKatayama Hirofumi MZ             ;
249bbe5fd52SKatayama Hirofumi MZ         }
250bbe5fd52SKatayama Hirofumi MZ         else
251bbe5fd52SKatayama Hirofumi MZ         {
252bbe5fd52SKatayama Hirofumi MZ             continue;
253bbe5fd52SKatayama Hirofumi MZ         }
254bbe5fd52SKatayama Hirofumi MZ 
255bbe5fd52SKatayama Hirofumi MZ         LangId = IntGetImeHotKeyLangId(pNode->dwHotKeyId);
256bbe5fd52SKatayama Hirofumi MZ         nScore = IntGetImeHotKeyLanguageScore(hKL, LangId);
257bbe5fd52SKatayama Hirofumi MZ         if (nScore >= 3)
258bbe5fd52SKatayama Hirofumi MZ             return pNode;
259bbe5fd52SKatayama Hirofumi MZ 
260bbe5fd52SKatayama Hirofumi MZ         if (fKorean)
261bbe5fd52SKatayama Hirofumi MZ             continue;
262bbe5fd52SKatayama Hirofumi MZ 
263bbe5fd52SKatayama Hirofumi MZ         if (nScore == 0)
264bbe5fd52SKatayama Hirofumi MZ         {
265bbe5fd52SKatayama Hirofumi MZ             if (pNode->dwHotKeyId == IME_CHOTKEY_IME_NONIME_TOGGLE ||
266bbe5fd52SKatayama Hirofumi MZ                 pNode->dwHotKeyId == IME_THOTKEY_IME_NONIME_TOGGLE)
267bbe5fd52SKatayama Hirofumi MZ             {
268bbe5fd52SKatayama Hirofumi MZ                 if (LOWORD(pti->hklPrev) == LangId)
269bbe5fd52SKatayama Hirofumi MZ                     return pNode;
270bbe5fd52SKatayama Hirofumi MZ             }
271bbe5fd52SKatayama Hirofumi MZ         }
272bbe5fd52SKatayama Hirofumi MZ 
273bbe5fd52SKatayama Hirofumi MZ         if (nMaxScore < nScore)
274bbe5fd52SKatayama Hirofumi MZ         {
275bbe5fd52SKatayama Hirofumi MZ             nMaxScore = nScore;
276bbe5fd52SKatayama Hirofumi MZ             ret = pNode;
277bbe5fd52SKatayama Hirofumi MZ         }
278bbe5fd52SKatayama Hirofumi MZ     }
279bbe5fd52SKatayama Hirofumi MZ 
280bbe5fd52SKatayama Hirofumi MZ     return ret;
281bbe5fd52SKatayama Hirofumi MZ }
282bbe5fd52SKatayama Hirofumi MZ 
2832f7775c6SKatayama Hirofumi MZ // Win: CheckImeHotKey
284bbe5fd52SKatayama Hirofumi MZ PIMEHOTKEY IntCheckImeHotKey(PUSER_MESSAGE_QUEUE MessageQueue, UINT uVirtualKey, LPARAM lParam)
285bbe5fd52SKatayama Hirofumi MZ {
286bbe5fd52SKatayama Hirofumi MZ     PIMEHOTKEY pHotKey;
287bbe5fd52SKatayama Hirofumi MZ     UINT uModifiers;
288bbe5fd52SKatayama Hirofumi MZ     BOOL bKeyUp = (lParam & 0x80000000);
289bbe5fd52SKatayama Hirofumi MZ     const BYTE *KeyState = MessageQueue->afKeyState;
290bbe5fd52SKatayama Hirofumi MZ     static UINT s_uKeyUpVKey = 0;
291bbe5fd52SKatayama Hirofumi MZ 
292bbe5fd52SKatayama Hirofumi MZ     if (bKeyUp)
293bbe5fd52SKatayama Hirofumi MZ     {
294bbe5fd52SKatayama Hirofumi MZ         if (s_uKeyUpVKey != uVirtualKey)
295bbe5fd52SKatayama Hirofumi MZ         {
296bbe5fd52SKatayama Hirofumi MZ             s_uKeyUpVKey = 0;
297bbe5fd52SKatayama Hirofumi MZ             return NULL;
298bbe5fd52SKatayama Hirofumi MZ         }
299bbe5fd52SKatayama Hirofumi MZ 
300bbe5fd52SKatayama Hirofumi MZ         s_uKeyUpVKey = 0;
301bbe5fd52SKatayama Hirofumi MZ     }
302bbe5fd52SKatayama Hirofumi MZ 
303bbe5fd52SKatayama Hirofumi MZ     uModifiers = 0;
304bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_LSHIFT))   uModifiers |= (MOD_SHIFT | MOD_LEFT);
305bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_RSHIFT))   uModifiers |= (MOD_SHIFT | MOD_RIGHT);
306bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_LCONTROL)) uModifiers |= (MOD_CONTROL | MOD_LEFT);
307bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_RCONTROL)) uModifiers |= (MOD_CONTROL | MOD_RIGHT);
308bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_LMENU))    uModifiers |= (MOD_ALT | MOD_LEFT);
309bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_RMENU))    uModifiers |= (MOD_ALT | MOD_RIGHT);
310bbe5fd52SKatayama Hirofumi MZ 
311bbe5fd52SKatayama Hirofumi MZ     pHotKey = IntGetImeHotKeyByKey(gpImeHotKeyList,
312bbe5fd52SKatayama Hirofumi MZ                                    (uModifiers & MOD_KEYS),
313bbe5fd52SKatayama Hirofumi MZ                                    (uModifiers & MOD_LEFT_RIGHT),
314bbe5fd52SKatayama Hirofumi MZ                                    uVirtualKey);
315bbe5fd52SKatayama Hirofumi MZ     if (pHotKey)
316bbe5fd52SKatayama Hirofumi MZ     {
317bbe5fd52SKatayama Hirofumi MZ         if (bKeyUp)
318bbe5fd52SKatayama Hirofumi MZ         {
319bbe5fd52SKatayama Hirofumi MZ             if (pHotKey->uModifiers & MOD_ON_KEYUP)
320bbe5fd52SKatayama Hirofumi MZ                 return pHotKey;
321bbe5fd52SKatayama Hirofumi MZ         }
322bbe5fd52SKatayama Hirofumi MZ         else
323bbe5fd52SKatayama Hirofumi MZ         {
324bbe5fd52SKatayama Hirofumi MZ             if (pHotKey->uModifiers & MOD_ON_KEYUP)
325bbe5fd52SKatayama Hirofumi MZ                 s_uKeyUpVKey = uVirtualKey;
326bbe5fd52SKatayama Hirofumi MZ             else
327bbe5fd52SKatayama Hirofumi MZ                 return pHotKey;
328bbe5fd52SKatayama Hirofumi MZ         }
329bbe5fd52SKatayama Hirofumi MZ     }
330bbe5fd52SKatayama Hirofumi MZ 
331bbe5fd52SKatayama Hirofumi MZ     return NULL;
332bbe5fd52SKatayama Hirofumi MZ }
333bbe5fd52SKatayama Hirofumi MZ 
3342f7775c6SKatayama Hirofumi MZ // Win: FreeImeHotKeys
3355d5cc578SKatayama Hirofumi MZ VOID FASTCALL IntFreeImeHotKeys(VOID)
3365d5cc578SKatayama Hirofumi MZ {
3375d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode, pNext;
3385d5cc578SKatayama Hirofumi MZ     for (pNode = gpImeHotKeyList; pNode; pNode = pNext)
3395d5cc578SKatayama Hirofumi MZ     {
3405d5cc578SKatayama Hirofumi MZ         pNext = pNode->pNext;
3415d5cc578SKatayama Hirofumi MZ         ExFreePoolWithTag(pNode, USERTAG_IMEHOTKEY);
3425d5cc578SKatayama Hirofumi MZ     }
3435d5cc578SKatayama Hirofumi MZ     gpImeHotKeyList = NULL;
3445d5cc578SKatayama Hirofumi MZ }
3455d5cc578SKatayama Hirofumi MZ 
3462f7775c6SKatayama Hirofumi MZ // Win: SetImeHotKey
3475d5cc578SKatayama Hirofumi MZ static BOOL APIENTRY
3485d5cc578SKatayama Hirofumi MZ IntSetImeHotKey(DWORD dwHotKeyId, UINT uModifiers, UINT uVirtualKey, HKL hKL, DWORD dwAction)
3495d5cc578SKatayama Hirofumi MZ {
3505d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
3515d5cc578SKatayama Hirofumi MZ     LANGID LangId;
3525d5cc578SKatayama Hirofumi MZ 
3535d5cc578SKatayama Hirofumi MZ     switch (dwAction)
3545d5cc578SKatayama Hirofumi MZ     {
3555d5cc578SKatayama Hirofumi MZ         case SETIMEHOTKEY_DELETE:
3565d5cc578SKatayama Hirofumi MZ             pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId);
3575d5cc578SKatayama Hirofumi MZ             if (!pNode)
358b5c9d532SKatayama Hirofumi MZ             {
359b5c9d532SKatayama Hirofumi MZ                 ERR("dwHotKeyId: 0x%lX\n", dwHotKeyId);
3605d5cc578SKatayama Hirofumi MZ                 return FALSE;
361b5c9d532SKatayama Hirofumi MZ             }
3625d5cc578SKatayama Hirofumi MZ 
3635d5cc578SKatayama Hirofumi MZ             IntDeleteImeHotKey(&gpImeHotKeyList, pNode);
3645d5cc578SKatayama Hirofumi MZ             return TRUE;
3655d5cc578SKatayama Hirofumi MZ 
3665d5cc578SKatayama Hirofumi MZ         case SETIMEHOTKEY_ADD:
3675d5cc578SKatayama Hirofumi MZ             if (uVirtualKey == VK_PACKET)
3685d5cc578SKatayama Hirofumi MZ                 return FALSE;
3695d5cc578SKatayama Hirofumi MZ 
3705d5cc578SKatayama Hirofumi MZ             LangId = IntGetImeHotKeyLangId(dwHotKeyId);
3715d5cc578SKatayama Hirofumi MZ             if (LangId == LANGID_KOREAN)
3725d5cc578SKatayama Hirofumi MZ                 return FALSE;
3735d5cc578SKatayama Hirofumi MZ 
3745d5cc578SKatayama Hirofumi MZ             pNode = IntGetImeHotKeyByKeyAndLang(gpImeHotKeyList,
3755d5cc578SKatayama Hirofumi MZ                                                 (uModifiers & MOD_KEYS),
3765d5cc578SKatayama Hirofumi MZ                                                 (uModifiers & MOD_LEFT_RIGHT),
3775d5cc578SKatayama Hirofumi MZ                                                 uVirtualKey, LangId);
3785d5cc578SKatayama Hirofumi MZ             if (!pNode)
3795d5cc578SKatayama Hirofumi MZ                 pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId);
3805d5cc578SKatayama Hirofumi MZ 
3815d5cc578SKatayama Hirofumi MZ             if (pNode)
3825d5cc578SKatayama Hirofumi MZ             {
3835d5cc578SKatayama Hirofumi MZ                 pNode->uModifiers = uModifiers;
3845d5cc578SKatayama Hirofumi MZ                 pNode->uVirtualKey = uVirtualKey;
3855d5cc578SKatayama Hirofumi MZ                 pNode->hKL = hKL;
3865d5cc578SKatayama Hirofumi MZ                 return TRUE;
3875d5cc578SKatayama Hirofumi MZ             }
3885d5cc578SKatayama Hirofumi MZ 
3895d5cc578SKatayama Hirofumi MZ             pNode = ExAllocatePoolWithTag(PagedPool, sizeof(IMEHOTKEY), USERTAG_IMEHOTKEY);
3905d5cc578SKatayama Hirofumi MZ             if (!pNode)
3915d5cc578SKatayama Hirofumi MZ                 return FALSE;
3925d5cc578SKatayama Hirofumi MZ 
3935d5cc578SKatayama Hirofumi MZ             pNode->pNext = NULL;
3945d5cc578SKatayama Hirofumi MZ             pNode->dwHotKeyId = dwHotKeyId;
3955d5cc578SKatayama Hirofumi MZ             pNode->uModifiers = uModifiers;
3965d5cc578SKatayama Hirofumi MZ             pNode->uVirtualKey = uVirtualKey;
3975d5cc578SKatayama Hirofumi MZ             pNode->hKL = hKL;
3985d5cc578SKatayama Hirofumi MZ             IntAddImeHotKey(&gpImeHotKeyList, pNode);
3995d5cc578SKatayama Hirofumi MZ             return TRUE;
4005d5cc578SKatayama Hirofumi MZ 
4015d5cc578SKatayama Hirofumi MZ         case SETIMEHOTKEY_DELETEALL:
4025d5cc578SKatayama Hirofumi MZ             IntFreeImeHotKeys();
4035d5cc578SKatayama Hirofumi MZ             return TRUE;
4045d5cc578SKatayama Hirofumi MZ 
4055d5cc578SKatayama Hirofumi MZ         default:
4065d5cc578SKatayama Hirofumi MZ             return FALSE;
4075d5cc578SKatayama Hirofumi MZ     }
4085d5cc578SKatayama Hirofumi MZ }
4095d5cc578SKatayama Hirofumi MZ 
4105d5cc578SKatayama Hirofumi MZ BOOL NTAPI
4115d5cc578SKatayama Hirofumi MZ NtUserGetImeHotKey(DWORD dwHotKeyId, LPUINT lpuModifiers, LPUINT lpuVirtualKey, LPHKL lphKL)
4125d5cc578SKatayama Hirofumi MZ {
4135d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode = NULL;
4145d5cc578SKatayama Hirofumi MZ 
4155d5cc578SKatayama Hirofumi MZ     UserEnterExclusive();
4165d5cc578SKatayama Hirofumi MZ 
4175d5cc578SKatayama Hirofumi MZ     _SEH2_TRY
4185d5cc578SKatayama Hirofumi MZ     {
4195d5cc578SKatayama Hirofumi MZ         ProbeForWrite(lpuModifiers, sizeof(UINT), 1);
4205d5cc578SKatayama Hirofumi MZ         ProbeForWrite(lpuVirtualKey, sizeof(UINT), 1);
4215d5cc578SKatayama Hirofumi MZ         if (lphKL)
4225d5cc578SKatayama Hirofumi MZ             ProbeForWrite(lphKL, sizeof(HKL), 1);
4235d5cc578SKatayama Hirofumi MZ     }
4245d5cc578SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
4255d5cc578SKatayama Hirofumi MZ     {
4265d5cc578SKatayama Hirofumi MZ         goto Quit;
4275d5cc578SKatayama Hirofumi MZ     }
4285d5cc578SKatayama Hirofumi MZ     _SEH2_END;
4295d5cc578SKatayama Hirofumi MZ 
4305d5cc578SKatayama Hirofumi MZ     pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId);
4315d5cc578SKatayama Hirofumi MZ     if (!pNode)
4325d5cc578SKatayama Hirofumi MZ         goto Quit;
4335d5cc578SKatayama Hirofumi MZ 
4345d5cc578SKatayama Hirofumi MZ     _SEH2_TRY
4355d5cc578SKatayama Hirofumi MZ     {
4365d5cc578SKatayama Hirofumi MZ         *lpuModifiers = pNode->uModifiers;
4375d5cc578SKatayama Hirofumi MZ         *lpuVirtualKey = pNode->uVirtualKey;
4385d5cc578SKatayama Hirofumi MZ         if (lphKL)
4395d5cc578SKatayama Hirofumi MZ             *lphKL = pNode->hKL;
4405d5cc578SKatayama Hirofumi MZ     }
4415d5cc578SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
4425d5cc578SKatayama Hirofumi MZ     {
4435d5cc578SKatayama Hirofumi MZ         pNode = NULL;
4445d5cc578SKatayama Hirofumi MZ     }
4455d5cc578SKatayama Hirofumi MZ     _SEH2_END;
4465d5cc578SKatayama Hirofumi MZ 
4475d5cc578SKatayama Hirofumi MZ Quit:
4485d5cc578SKatayama Hirofumi MZ     UserLeave();
4495d5cc578SKatayama Hirofumi MZ     return !!pNode;
4505d5cc578SKatayama Hirofumi MZ }
4515d5cc578SKatayama Hirofumi MZ 
4525d5cc578SKatayama Hirofumi MZ BOOL
4535d5cc578SKatayama Hirofumi MZ NTAPI
4545d5cc578SKatayama Hirofumi MZ NtUserSetImeHotKey(
4555d5cc578SKatayama Hirofumi MZ     DWORD  dwHotKeyId,
4565d5cc578SKatayama Hirofumi MZ     UINT   uModifiers,
4575d5cc578SKatayama Hirofumi MZ     UINT   uVirtualKey,
4585d5cc578SKatayama Hirofumi MZ     HKL    hKL,
4595d5cc578SKatayama Hirofumi MZ     DWORD  dwAction)
4605d5cc578SKatayama Hirofumi MZ {
4615d5cc578SKatayama Hirofumi MZ     BOOL ret;
4625d5cc578SKatayama Hirofumi MZ     UserEnterExclusive();
4635d5cc578SKatayama Hirofumi MZ     ret = IntSetImeHotKey(dwHotKeyId, uModifiers, uVirtualKey, hKL, dwAction);
4645d5cc578SKatayama Hirofumi MZ     UserLeave();
4655d5cc578SKatayama Hirofumi MZ     return ret;
4665d5cc578SKatayama Hirofumi MZ }
4675d5cc578SKatayama Hirofumi MZ 
468bbe5fd52SKatayama Hirofumi MZ DWORD
469bbe5fd52SKatayama Hirofumi MZ NTAPI
470bbe5fd52SKatayama Hirofumi MZ NtUserCheckImeHotKey(UINT uVirtualKey, LPARAM lParam)
471bbe5fd52SKatayama Hirofumi MZ {
472bbe5fd52SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
473bbe5fd52SKatayama Hirofumi MZ     DWORD ret = INVALID_HOTKEY;
474bbe5fd52SKatayama Hirofumi MZ 
475bbe5fd52SKatayama Hirofumi MZ     UserEnterExclusive();
476bbe5fd52SKatayama Hirofumi MZ 
477bbe5fd52SKatayama Hirofumi MZ     if (!gpqForeground || !IS_IMM_MODE())
478bbe5fd52SKatayama Hirofumi MZ         goto Quit;
479bbe5fd52SKatayama Hirofumi MZ 
480bbe5fd52SKatayama Hirofumi MZ     pNode = IntCheckImeHotKey(gpqForeground, uVirtualKey, lParam);
481bbe5fd52SKatayama Hirofumi MZ     if (pNode)
482bbe5fd52SKatayama Hirofumi MZ         ret = pNode->dwHotKeyId;
483bbe5fd52SKatayama Hirofumi MZ 
484bbe5fd52SKatayama Hirofumi MZ Quit:
485bbe5fd52SKatayama Hirofumi MZ     UserLeave();
486bbe5fd52SKatayama Hirofumi MZ     return ret;
487bbe5fd52SKatayama Hirofumi MZ }
488bbe5fd52SKatayama Hirofumi MZ 
4890519ae0aSKatayama Hirofumi MZ PWND FASTCALL IntGetTopLevelWindow(PWND pwnd)
4900519ae0aSKatayama Hirofumi MZ {
4910519ae0aSKatayama Hirofumi MZ     if (!pwnd)
4920519ae0aSKatayama Hirofumi MZ         return NULL;
4930519ae0aSKatayama Hirofumi MZ 
4940519ae0aSKatayama Hirofumi MZ     while (pwnd->style & WS_CHILD)
4950519ae0aSKatayama Hirofumi MZ         pwnd = pwnd->spwndParent;
4960519ae0aSKatayama Hirofumi MZ 
4970519ae0aSKatayama Hirofumi MZ     return pwnd;
4980519ae0aSKatayama Hirofumi MZ }
4990519ae0aSKatayama Hirofumi MZ 
5002f7775c6SKatayama Hirofumi MZ // Win: AssociateInputContext
5011bc9dda5SKatayama Hirofumi MZ HIMC FASTCALL IntAssociateInputContext(PWND pWnd, PIMC pImc)
5021bc9dda5SKatayama Hirofumi MZ {
5031bc9dda5SKatayama Hirofumi MZ     HIMC hOldImc = pWnd->hImc;
5041bc9dda5SKatayama Hirofumi MZ     pWnd->hImc = (pImc ? UserHMGetHandle(pImc) : NULL);
5051bc9dda5SKatayama Hirofumi MZ     return hOldImc;
5061bc9dda5SKatayama Hirofumi MZ }
5071bc9dda5SKatayama Hirofumi MZ 
508470aa276SKatayama Hirofumi MZ DWORD
509e52ce89bSKatayama Hirofumi MZ NTAPI
510470aa276SKatayama Hirofumi MZ NtUserSetThreadLayoutHandles(HKL hNewKL, HKL hOldKL)
511470aa276SKatayama Hirofumi MZ {
512470aa276SKatayama Hirofumi MZ     PTHREADINFO pti;
513470aa276SKatayama Hirofumi MZ     PKL pOldKL, pNewKL;
514470aa276SKatayama Hirofumi MZ 
515470aa276SKatayama Hirofumi MZ     UserEnterExclusive();
516470aa276SKatayama Hirofumi MZ 
517470aa276SKatayama Hirofumi MZ     pti = GetW32ThreadInfo();
518470aa276SKatayama Hirofumi MZ     pOldKL = pti->KeyboardLayout;
519470aa276SKatayama Hirofumi MZ     if (pOldKL && pOldKL->hkl != hOldKL)
520470aa276SKatayama Hirofumi MZ         goto Quit;
521470aa276SKatayama Hirofumi MZ 
522470aa276SKatayama Hirofumi MZ     pNewKL = UserHklToKbl(hNewKL);
523470aa276SKatayama Hirofumi MZ     if (!pNewKL)
524470aa276SKatayama Hirofumi MZ         goto Quit;
525470aa276SKatayama Hirofumi MZ 
526470aa276SKatayama Hirofumi MZ     if (IS_IME_HKL(hNewKL) != IS_IME_HKL(hOldKL))
527470aa276SKatayama Hirofumi MZ         pti->hklPrev = hOldKL;
528470aa276SKatayama Hirofumi MZ 
529470aa276SKatayama Hirofumi MZ     pti->KeyboardLayout = pNewKL;
530470aa276SKatayama Hirofumi MZ 
531470aa276SKatayama Hirofumi MZ Quit:
532470aa276SKatayama Hirofumi MZ     UserLeave();
533470aa276SKatayama Hirofumi MZ     return 0;
534470aa276SKatayama Hirofumi MZ }
535470aa276SKatayama Hirofumi MZ 
5362f7775c6SKatayama Hirofumi MZ // Win: BuildHimcList
537ce6da820SKatayama Hirofumi MZ DWORD FASTCALL UserBuildHimcList(PTHREADINFO pti, DWORD dwCount, HIMC *phList)
538ce6da820SKatayama Hirofumi MZ {
539ce6da820SKatayama Hirofumi MZ     PIMC pIMC;
540ce6da820SKatayama Hirofumi MZ     DWORD dwRealCount = 0;
541ce6da820SKatayama Hirofumi MZ 
542ce6da820SKatayama Hirofumi MZ     if (pti)
543ce6da820SKatayama Hirofumi MZ     {
544ce6da820SKatayama Hirofumi MZ         for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
545ce6da820SKatayama Hirofumi MZ         {
546ce6da820SKatayama Hirofumi MZ             if (dwRealCount < dwCount)
547ce6da820SKatayama Hirofumi MZ                 phList[dwRealCount] = UserHMGetHandle(pIMC);
548ce6da820SKatayama Hirofumi MZ 
549ce6da820SKatayama Hirofumi MZ             ++dwRealCount;
550ce6da820SKatayama Hirofumi MZ         }
551ce6da820SKatayama Hirofumi MZ     }
552ce6da820SKatayama Hirofumi MZ     else
553ce6da820SKatayama Hirofumi MZ     {
554ce6da820SKatayama Hirofumi MZ         for (pti = GetW32ThreadInfo()->ppi->ptiList; pti; pti = pti->ptiSibling)
555ce6da820SKatayama Hirofumi MZ         {
556ce6da820SKatayama Hirofumi MZ             for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
557ce6da820SKatayama Hirofumi MZ             {
558ce6da820SKatayama Hirofumi MZ                 if (dwRealCount < dwCount)
559ce6da820SKatayama Hirofumi MZ                     phList[dwRealCount] = UserHMGetHandle(pIMC);
560ce6da820SKatayama Hirofumi MZ 
561ce6da820SKatayama Hirofumi MZ                 ++dwRealCount;
562ce6da820SKatayama Hirofumi MZ             }
563ce6da820SKatayama Hirofumi MZ         }
564ce6da820SKatayama Hirofumi MZ     }
565ce6da820SKatayama Hirofumi MZ 
566ce6da820SKatayama Hirofumi MZ     return dwRealCount;
567ce6da820SKatayama Hirofumi MZ }
568ce6da820SKatayama Hirofumi MZ 
569c2c66affSColin Finck UINT FASTCALL
570b5c9d532SKatayama Hirofumi MZ IntImmProcessKey(PUSER_MESSAGE_QUEUE MessageQueue, PWND pWnd, UINT uMsg,
571b5c9d532SKatayama Hirofumi MZ                  WPARAM wParam, LPARAM lParam)
572c2c66affSColin Finck {
573b5c9d532SKatayama Hirofumi MZ     UINT uVirtualKey, ret = 0;
574b5c9d532SKatayama Hirofumi MZ     DWORD dwHotKeyId;
575b5c9d532SKatayama Hirofumi MZ     PKL pKL;
576b5c9d532SKatayama Hirofumi MZ     PIMC pIMC = NULL;
577b5c9d532SKatayama Hirofumi MZ     PIMEHOTKEY pImeHotKey;
578b5c9d532SKatayama Hirofumi MZ     HKL hKL;
579b5c9d532SKatayama Hirofumi MZ     HWND hWnd;
580c2c66affSColin Finck 
581c2c66affSColin Finck     ASSERT_REFS_CO(pWnd);
582c2c66affSColin Finck 
583b5c9d532SKatayama Hirofumi MZ     switch (uMsg)
584c2c66affSColin Finck     {
585b5c9d532SKatayama Hirofumi MZ         case WM_KEYDOWN:
586b5c9d532SKatayama Hirofumi MZ         case WM_KEYUP:
587b5c9d532SKatayama Hirofumi MZ         case WM_SYSKEYDOWN:
588b5c9d532SKatayama Hirofumi MZ         case WM_SYSKEYUP:
589b5c9d532SKatayama Hirofumi MZ             break;
590b5c9d532SKatayama Hirofumi MZ 
591b5c9d532SKatayama Hirofumi MZ         default:
592c2c66affSColin Finck             return 0;
593c2c66affSColin Finck     }
594c2c66affSColin Finck 
595b5c9d532SKatayama Hirofumi MZ     hWnd = UserHMGetHandle(pWnd);
596b5c9d532SKatayama Hirofumi MZ     pKL = pWnd->head.pti->KeyboardLayout;
597b5c9d532SKatayama Hirofumi MZ     if (!pKL)
598b5c9d532SKatayama Hirofumi MZ         return 0;
599b5c9d532SKatayama Hirofumi MZ 
600b5c9d532SKatayama Hirofumi MZ     uVirtualKey = LOBYTE(wParam);
601b5c9d532SKatayama Hirofumi MZ     pImeHotKey = IntCheckImeHotKey(MessageQueue, uVirtualKey, lParam);
602b5c9d532SKatayama Hirofumi MZ     if (pImeHotKey)
603b5c9d532SKatayama Hirofumi MZ     {
604b5c9d532SKatayama Hirofumi MZ         dwHotKeyId = pImeHotKey->dwHotKeyId;
605b5c9d532SKatayama Hirofumi MZ         hKL = pImeHotKey->hKL;
606b5c9d532SKatayama Hirofumi MZ     }
607b5c9d532SKatayama Hirofumi MZ     else
608b5c9d532SKatayama Hirofumi MZ     {
609b5c9d532SKatayama Hirofumi MZ         dwHotKeyId = INVALID_HOTKEY;
610b5c9d532SKatayama Hirofumi MZ         hKL = NULL;
611b5c9d532SKatayama Hirofumi MZ     }
612b5c9d532SKatayama Hirofumi MZ 
613b5c9d532SKatayama Hirofumi MZ     if (IME_HOTKEY_DSWITCH_FIRST <= dwHotKeyId && dwHotKeyId <= IME_HOTKEY_DSWITCH_LAST)
614b5c9d532SKatayama Hirofumi MZ     {
615b5c9d532SKatayama Hirofumi MZ         if (pKL->hkl != hKL)
616b5c9d532SKatayama Hirofumi MZ         {
617b5c9d532SKatayama Hirofumi MZ             UserPostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST,
618b5c9d532SKatayama Hirofumi MZ                             ((pKL->dwFontSigs & gSystemFS) ? INPUTLANGCHANGE_SYSCHARSET : 0),
619b5c9d532SKatayama Hirofumi MZ                             (LPARAM)hKL);
620b5c9d532SKatayama Hirofumi MZ         }
621b5c9d532SKatayama Hirofumi MZ 
622b5c9d532SKatayama Hirofumi MZ         if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000)
623b5c9d532SKatayama Hirofumi MZ             return 0;
624b5c9d532SKatayama Hirofumi MZ 
625b5c9d532SKatayama Hirofumi MZ         return IPHK_HOTKEY;
626b5c9d532SKatayama Hirofumi MZ     }
627b5c9d532SKatayama Hirofumi MZ 
628b5c9d532SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
629b5c9d532SKatayama Hirofumi MZ         return 0;
630b5c9d532SKatayama Hirofumi MZ 
631b5c9d532SKatayama Hirofumi MZ     if (dwHotKeyId == INVALID_HOTKEY)
632b5c9d532SKatayama Hirofumi MZ     {
633b5c9d532SKatayama Hirofumi MZ         if (!pKL->piiex)
634b5c9d532SKatayama Hirofumi MZ             return 0;
635b5c9d532SKatayama Hirofumi MZ 
636b5c9d532SKatayama Hirofumi MZ         if (pWnd->hImc)
637b5c9d532SKatayama Hirofumi MZ             pIMC = UserGetObject(gHandleTable, pWnd->hImc, TYPE_INPUTCONTEXT);
638b5c9d532SKatayama Hirofumi MZ         if (!pIMC)
639b5c9d532SKatayama Hirofumi MZ             return 0;
640b5c9d532SKatayama Hirofumi MZ 
641b5c9d532SKatayama Hirofumi MZ         if ((lParam & 0x80000000) &&
642b5c9d532SKatayama Hirofumi MZ             (pKL->piiex->ImeInfo.fdwProperty & IME_PROP_IGNORE_UPKEYS))
643b5c9d532SKatayama Hirofumi MZ         {
644b5c9d532SKatayama Hirofumi MZ             return 0;
645b5c9d532SKatayama Hirofumi MZ         }
646b5c9d532SKatayama Hirofumi MZ 
647b5c9d532SKatayama Hirofumi MZ         switch (uVirtualKey)
648b5c9d532SKatayama Hirofumi MZ         {
649b5c9d532SKatayama Hirofumi MZ             case VK_DBE_CODEINPUT:
650b5c9d532SKatayama Hirofumi MZ             case VK_DBE_ENTERCONFIGMODE:
651b5c9d532SKatayama Hirofumi MZ             case VK_DBE_ENTERWORDREGISTERMODE:
652b5c9d532SKatayama Hirofumi MZ             case VK_DBE_HIRAGANA:
653b5c9d532SKatayama Hirofumi MZ             case VK_DBE_KATAKANA:
654b5c9d532SKatayama Hirofumi MZ             case VK_DBE_NOCODEINPUT:
655b5c9d532SKatayama Hirofumi MZ             case VK_DBE_NOROMAN:
656b5c9d532SKatayama Hirofumi MZ             case VK_DBE_ROMAN:
657b5c9d532SKatayama Hirofumi MZ                 break;
658b5c9d532SKatayama Hirofumi MZ 
659b5c9d532SKatayama Hirofumi MZ             default:
660b5c9d532SKatayama Hirofumi MZ             {
661b5c9d532SKatayama Hirofumi MZ                 if (uMsg == WM_SYSKEYDOWN || uMsg == WM_SYSKEYUP)
662b5c9d532SKatayama Hirofumi MZ                 {
663b5c9d532SKatayama Hirofumi MZ                     if (uVirtualKey != VK_MENU && uVirtualKey != VK_F10)
664b5c9d532SKatayama Hirofumi MZ                         return 0;
665b5c9d532SKatayama Hirofumi MZ                 }
666b5c9d532SKatayama Hirofumi MZ 
667b5c9d532SKatayama Hirofumi MZ                 if (!(pKL->piiex->ImeInfo.fdwProperty & IME_PROP_NEED_ALTKEY))
668b5c9d532SKatayama Hirofumi MZ                 {
669b5c9d532SKatayama Hirofumi MZ                     if (uVirtualKey == VK_MENU || (lParam & 0x20000000))
670b5c9d532SKatayama Hirofumi MZ                         return 0;
671b5c9d532SKatayama Hirofumi MZ                 }
672b5c9d532SKatayama Hirofumi MZ                 break;
673b5c9d532SKatayama Hirofumi MZ             }
674b5c9d532SKatayama Hirofumi MZ         }
675b5c9d532SKatayama Hirofumi MZ     }
676b5c9d532SKatayama Hirofumi MZ 
677b5c9d532SKatayama Hirofumi MZ     if (LOBYTE(uVirtualKey) == VK_PACKET)
678b5c9d532SKatayama Hirofumi MZ         uVirtualKey = MAKELONG(wParam, GetW32ThreadInfo()->wchInjected);
679b5c9d532SKatayama Hirofumi MZ 
680b5c9d532SKatayama Hirofumi MZ     ret = co_IntImmProcessKey(hWnd, pKL->hkl, uVirtualKey, lParam, dwHotKeyId);
681b5c9d532SKatayama Hirofumi MZ 
682b5c9d532SKatayama Hirofumi MZ     if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000)
683b5c9d532SKatayama Hirofumi MZ         ret &= ~IPHK_HOTKEY;
684b5c9d532SKatayama Hirofumi MZ 
685b5c9d532SKatayama Hirofumi MZ     return ret;
686b5c9d532SKatayama Hirofumi MZ }
687b5c9d532SKatayama Hirofumi MZ 
688ce6da820SKatayama Hirofumi MZ NTSTATUS
689e52ce89bSKatayama Hirofumi MZ NTAPI
690ce6da820SKatayama Hirofumi MZ NtUserBuildHimcList(DWORD dwThreadId, DWORD dwCount, HIMC *phList, LPDWORD pdwCount)
691ce6da820SKatayama Hirofumi MZ {
692ce6da820SKatayama Hirofumi MZ     NTSTATUS ret = STATUS_UNSUCCESSFUL;
693ce6da820SKatayama Hirofumi MZ     DWORD dwRealCount;
694ce6da820SKatayama Hirofumi MZ     PTHREADINFO pti;
695ce6da820SKatayama Hirofumi MZ 
696ce6da820SKatayama Hirofumi MZ     UserEnterExclusive();
697ce6da820SKatayama Hirofumi MZ 
698ce6da820SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
699ce6da820SKatayama Hirofumi MZ     {
700b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
701ce6da820SKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
702ce6da820SKatayama Hirofumi MZ         goto Quit;
703ce6da820SKatayama Hirofumi MZ     }
704ce6da820SKatayama Hirofumi MZ 
705ce6da820SKatayama Hirofumi MZ     if (dwThreadId == 0)
706ce6da820SKatayama Hirofumi MZ     {
707ce6da820SKatayama Hirofumi MZ         pti = GetW32ThreadInfo();
708ce6da820SKatayama Hirofumi MZ     }
709ce6da820SKatayama Hirofumi MZ     else if (dwThreadId == INVALID_THREAD_ID)
710ce6da820SKatayama Hirofumi MZ     {
711ce6da820SKatayama Hirofumi MZ         pti = NULL;
712ce6da820SKatayama Hirofumi MZ     }
713ce6da820SKatayama Hirofumi MZ     else
714ce6da820SKatayama Hirofumi MZ     {
715ce6da820SKatayama Hirofumi MZ         pti = IntTID2PTI(UlongToHandle(dwThreadId));
716ce6da820SKatayama Hirofumi MZ         if (!pti || !pti->rpdesk)
717ce6da820SKatayama Hirofumi MZ             goto Quit;
718ce6da820SKatayama Hirofumi MZ     }
719ce6da820SKatayama Hirofumi MZ 
720ce6da820SKatayama Hirofumi MZ     _SEH2_TRY
721ce6da820SKatayama Hirofumi MZ     {
722ce6da820SKatayama Hirofumi MZ         ProbeForWrite(phList, dwCount * sizeof(HIMC), 1);
723ce6da820SKatayama Hirofumi MZ         ProbeForWrite(pdwCount, sizeof(DWORD), 1);
724ce6da820SKatayama Hirofumi MZ         *pdwCount = dwRealCount = UserBuildHimcList(pti, dwCount, phList);
725ce6da820SKatayama Hirofumi MZ     }
726ce6da820SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
727ce6da820SKatayama Hirofumi MZ     {
728ce6da820SKatayama Hirofumi MZ         goto Quit;
729ce6da820SKatayama Hirofumi MZ     }
730ce6da820SKatayama Hirofumi MZ     _SEH2_END;
731ce6da820SKatayama Hirofumi MZ 
732ce6da820SKatayama Hirofumi MZ     if (dwCount < dwRealCount)
733ce6da820SKatayama Hirofumi MZ         ret = STATUS_BUFFER_TOO_SMALL;
734ce6da820SKatayama Hirofumi MZ     else
735ce6da820SKatayama Hirofumi MZ         ret = STATUS_SUCCESS;
736ce6da820SKatayama Hirofumi MZ 
737ce6da820SKatayama Hirofumi MZ Quit:
738ce6da820SKatayama Hirofumi MZ     UserLeave();
739ce6da820SKatayama Hirofumi MZ     return ret;
740ce6da820SKatayama Hirofumi MZ }
741ce6da820SKatayama Hirofumi MZ 
7429db44371SKatayama Hirofumi MZ static VOID FASTCALL UserSetImeConversionKeyState(PTHREADINFO pti, DWORD dwConversion)
7439db44371SKatayama Hirofumi MZ {
7449db44371SKatayama Hirofumi MZ     HKL hKL;
7459db44371SKatayama Hirofumi MZ     LANGID LangID;
7469db44371SKatayama Hirofumi MZ     LPBYTE KeyState;
7479db44371SKatayama Hirofumi MZ     BOOL bAlphaNumeric, bKatakana, bHiragana, bFullShape, bRoman, bCharCode;
7489db44371SKatayama Hirofumi MZ 
7499db44371SKatayama Hirofumi MZ     if (!pti->KeyboardLayout)
7509db44371SKatayama Hirofumi MZ         return;
7519db44371SKatayama Hirofumi MZ 
7529db44371SKatayama Hirofumi MZ     hKL = pti->KeyboardLayout->hkl;
7539db44371SKatayama Hirofumi MZ     LangID = LOWORD(hKL);
7549db44371SKatayama Hirofumi MZ     KeyState = pti->MessageQueue->afKeyState;
7559db44371SKatayama Hirofumi MZ 
7569db44371SKatayama Hirofumi MZ     switch (PRIMARYLANGID(LangID))
7579db44371SKatayama Hirofumi MZ     {
7589db44371SKatayama Hirofumi MZ         case LANG_JAPANESE:
7599db44371SKatayama Hirofumi MZ             bAlphaNumeric = !(dwConversion & IME_CMODE_NATIVE);
7609db44371SKatayama Hirofumi MZ             bKatakana = !bAlphaNumeric && (dwConversion & IME_CMODE_KATAKANA);
7619db44371SKatayama Hirofumi MZ             bHiragana = !bAlphaNumeric && !(dwConversion & IME_CMODE_KATAKANA);
7629db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
7639db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
7649db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_HIRAGANA, bHiragana);
7659db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_HIRAGANA, bHiragana);
7669db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_KATAKANA, bKatakana);
7679db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_KATAKANA, bKatakana);
7689db44371SKatayama Hirofumi MZ 
7699db44371SKatayama Hirofumi MZ             bFullShape = (dwConversion & IME_CMODE_FULLSHAPE);
7709db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_DBCSCHAR, bFullShape);
7719db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_DBCSCHAR, bFullShape);
7729db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
7739db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
7749db44371SKatayama Hirofumi MZ 
7759db44371SKatayama Hirofumi MZ             bRoman = (dwConversion & IME_CMODE_ROMAN);
7769db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_ROMAN, bRoman);
7779db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_ROMAN, bRoman);
7789db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_NOROMAN, !bRoman);
7799db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_NOROMAN, !bRoman);
7809db44371SKatayama Hirofumi MZ 
7819db44371SKatayama Hirofumi MZ             bCharCode = (dwConversion & IME_CMODE_CHARCODE);
7829db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_CODEINPUT, bCharCode);
7839db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_CODEINPUT, bCharCode);
7849db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
7859db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
7869db44371SKatayama Hirofumi MZ             break;
7879db44371SKatayama Hirofumi MZ 
7889db44371SKatayama Hirofumi MZ         case LANG_KOREAN:
7899db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_HANGUL, (dwConversion & IME_CMODE_NATIVE));
7909db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_JUNJA, (dwConversion & IME_CMODE_FULLSHAPE));
7919db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_HANJA, (dwConversion & IME_CMODE_HANJACONVERT));
7929db44371SKatayama Hirofumi MZ             break;
7939db44371SKatayama Hirofumi MZ 
7949db44371SKatayama Hirofumi MZ         default:
7959db44371SKatayama Hirofumi MZ             break;
7969db44371SKatayama Hirofumi MZ     }
7979db44371SKatayama Hirofumi MZ }
7989db44371SKatayama Hirofumi MZ 
799c2c66affSColin Finck DWORD
800e52ce89bSKatayama Hirofumi MZ NTAPI
8019adc538cSKatayama Hirofumi MZ NtUserNotifyIMEStatus(HWND hwnd, BOOL fOpen, DWORD dwConversion)
802c2c66affSColin Finck {
8039db44371SKatayama Hirofumi MZ     PWND pwnd;
8049db44371SKatayama Hirofumi MZ     PTHREADINFO pti;
8059db44371SKatayama Hirofumi MZ     HKL hKL;
8069db44371SKatayama Hirofumi MZ 
8079db44371SKatayama Hirofumi MZ     UserEnterExclusive();
8089db44371SKatayama Hirofumi MZ 
809b5c9d532SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
810b5c9d532SKatayama Hirofumi MZ     {
811b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
812b5c9d532SKatayama Hirofumi MZ         goto Quit;
813b5c9d532SKatayama Hirofumi MZ     }
814b5c9d532SKatayama Hirofumi MZ 
8159db44371SKatayama Hirofumi MZ     pwnd = ValidateHwndNoErr(hwnd);
816b5c9d532SKatayama Hirofumi MZ     if (!pwnd)
8179db44371SKatayama Hirofumi MZ         goto Quit;
8189db44371SKatayama Hirofumi MZ 
8199db44371SKatayama Hirofumi MZ     pti = pwnd->head.pti;
8209db44371SKatayama Hirofumi MZ     if (!pti || !gptiForeground)
8219db44371SKatayama Hirofumi MZ         goto Quit;
8229db44371SKatayama Hirofumi MZ     if (pti != gptiForeground && pti->MessageQueue != gptiForeground->MessageQueue)
8239db44371SKatayama Hirofumi MZ         goto Quit;
8249db44371SKatayama Hirofumi MZ     if (ghIMC == pwnd->hImc && gfImeOpen == !!fOpen && gdwImeConversion == dwConversion)
8259db44371SKatayama Hirofumi MZ         goto Quit;
8269db44371SKatayama Hirofumi MZ 
8279db44371SKatayama Hirofumi MZ     ghIMC = pwnd->hImc;
8289db44371SKatayama Hirofumi MZ     if (ghIMC)
8299db44371SKatayama Hirofumi MZ     {
8309db44371SKatayama Hirofumi MZ         gfImeOpen = !!fOpen;
8319db44371SKatayama Hirofumi MZ         gdwImeConversion = dwConversion;
8329db44371SKatayama Hirofumi MZ         UserSetImeConversionKeyState(pti, (fOpen ? dwConversion : IME_CMODE_ALPHANUMERIC));
8339db44371SKatayama Hirofumi MZ     }
8349db44371SKatayama Hirofumi MZ 
8359db44371SKatayama Hirofumi MZ     if (ISITHOOKED(WH_SHELL))
8369db44371SKatayama Hirofumi MZ     {
8379db44371SKatayama Hirofumi MZ         hKL = (pti->KeyboardLayout ? pti->KeyboardLayout->hkl : NULL);
8389db44371SKatayama Hirofumi MZ         co_HOOK_CallHooks(WH_SHELL, HSHELL_LANGUAGE, (WPARAM)hwnd, (LPARAM)hKL);
8399db44371SKatayama Hirofumi MZ     }
8409db44371SKatayama Hirofumi MZ 
8419db44371SKatayama Hirofumi MZ     // TODO:
8429db44371SKatayama Hirofumi MZ 
8439db44371SKatayama Hirofumi MZ Quit:
8449db44371SKatayama Hirofumi MZ     UserLeave();
845c2c66affSColin Finck     return 0;
846c2c66affSColin Finck }
847c2c66affSColin Finck 
848fcc222c2SKatayama Hirofumi MZ BOOL
849e52ce89bSKatayama Hirofumi MZ NTAPI
850c2c66affSColin Finck NtUserDisableThreadIme(
851fcc222c2SKatayama Hirofumi MZ     DWORD dwThreadID)
852c2c66affSColin Finck {
853fcc222c2SKatayama Hirofumi MZ     PTHREADINFO pti, ptiCurrent;
854fcc222c2SKatayama Hirofumi MZ     PPROCESSINFO ppi;
855fcc222c2SKatayama Hirofumi MZ     BOOL ret = FALSE;
856fcc222c2SKatayama Hirofumi MZ 
857fcc222c2SKatayama Hirofumi MZ     UserEnterExclusive();
858fcc222c2SKatayama Hirofumi MZ 
859fcc222c2SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
860fcc222c2SKatayama Hirofumi MZ     {
861b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
862fcc222c2SKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
863fcc222c2SKatayama Hirofumi MZ         goto Quit;
864fcc222c2SKatayama Hirofumi MZ     }
865fcc222c2SKatayama Hirofumi MZ 
866fcc222c2SKatayama Hirofumi MZ     ptiCurrent = GetW32ThreadInfo();
867fcc222c2SKatayama Hirofumi MZ 
868fcc222c2SKatayama Hirofumi MZ     if (dwThreadID == INVALID_THREAD_ID)
869fcc222c2SKatayama Hirofumi MZ     {
870fcc222c2SKatayama Hirofumi MZ         ppi = ptiCurrent->ppi;
871fcc222c2SKatayama Hirofumi MZ         ppi->W32PF_flags |= W32PF_DISABLEIME;
872fcc222c2SKatayama Hirofumi MZ 
873fcc222c2SKatayama Hirofumi MZ Retry:
874fcc222c2SKatayama Hirofumi MZ         for (pti = ppi->ptiList; pti; pti = pti->ptiSibling)
875fcc222c2SKatayama Hirofumi MZ         {
876fcc222c2SKatayama Hirofumi MZ             pti->TIF_flags |= TIF_DISABLEIME;
877fcc222c2SKatayama Hirofumi MZ 
878fcc222c2SKatayama Hirofumi MZ             if (pti->spwndDefaultIme)
879fcc222c2SKatayama Hirofumi MZ             {
880fcc222c2SKatayama Hirofumi MZ                 co_UserDestroyWindow(pti->spwndDefaultIme);
881fcc222c2SKatayama Hirofumi MZ                 pti->spwndDefaultIme = NULL;
882fcc222c2SKatayama Hirofumi MZ                 goto Retry; /* The contents of ppi->ptiList may be changed. */
883fcc222c2SKatayama Hirofumi MZ             }
884fcc222c2SKatayama Hirofumi MZ         }
885fcc222c2SKatayama Hirofumi MZ     }
886fcc222c2SKatayama Hirofumi MZ     else
887fcc222c2SKatayama Hirofumi MZ     {
888fcc222c2SKatayama Hirofumi MZ         if (dwThreadID == 0)
889fcc222c2SKatayama Hirofumi MZ         {
890fcc222c2SKatayama Hirofumi MZ             pti = ptiCurrent;
891fcc222c2SKatayama Hirofumi MZ         }
892fcc222c2SKatayama Hirofumi MZ         else
893fcc222c2SKatayama Hirofumi MZ         {
894fcc222c2SKatayama Hirofumi MZ             pti = IntTID2PTI(UlongToHandle(dwThreadID));
895fcc222c2SKatayama Hirofumi MZ 
896fcc222c2SKatayama Hirofumi MZ             /* The thread needs to reside in the current process. */
897fcc222c2SKatayama Hirofumi MZ             if (!pti || pti->ppi != ptiCurrent->ppi)
898fcc222c2SKatayama Hirofumi MZ                 goto Quit;
899fcc222c2SKatayama Hirofumi MZ         }
900fcc222c2SKatayama Hirofumi MZ 
901fcc222c2SKatayama Hirofumi MZ         pti->TIF_flags |= TIF_DISABLEIME;
902fcc222c2SKatayama Hirofumi MZ 
903fcc222c2SKatayama Hirofumi MZ         if (pti->spwndDefaultIme)
904fcc222c2SKatayama Hirofumi MZ         {
905fcc222c2SKatayama Hirofumi MZ             co_UserDestroyWindow(pti->spwndDefaultIme);
906fcc222c2SKatayama Hirofumi MZ             pti->spwndDefaultIme = NULL;
907fcc222c2SKatayama Hirofumi MZ         }
908fcc222c2SKatayama Hirofumi MZ     }
909fcc222c2SKatayama Hirofumi MZ 
910fcc222c2SKatayama Hirofumi MZ     ret = TRUE;
911fcc222c2SKatayama Hirofumi MZ 
912fcc222c2SKatayama Hirofumi MZ Quit:
913fcc222c2SKatayama Hirofumi MZ     UserLeave();
914fcc222c2SKatayama Hirofumi MZ     return ret;
915c2c66affSColin Finck }
916c2c66affSColin Finck 
917c2c66affSColin Finck DWORD
918e52ce89bSKatayama Hirofumi MZ NTAPI
919f4bc74edSKatayama Hirofumi MZ NtUserGetAppImeLevel(HWND hWnd)
920c2c66affSColin Finck {
9219c8167e9SKatayama Hirofumi MZ     DWORD ret = 0;
9229c8167e9SKatayama Hirofumi MZ     PWND pWnd;
9239c8167e9SKatayama Hirofumi MZ     PTHREADINFO pti;
9249c8167e9SKatayama Hirofumi MZ 
9259c8167e9SKatayama Hirofumi MZ     UserEnterShared();
9269c8167e9SKatayama Hirofumi MZ 
9279c8167e9SKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
9289c8167e9SKatayama Hirofumi MZ     if (!pWnd)
9299c8167e9SKatayama Hirofumi MZ         goto Quit;
9309c8167e9SKatayama Hirofumi MZ 
9319c8167e9SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
9329c8167e9SKatayama Hirofumi MZ     {
933b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
9349c8167e9SKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
9359c8167e9SKatayama Hirofumi MZ         goto Quit;
9369c8167e9SKatayama Hirofumi MZ     }
9379c8167e9SKatayama Hirofumi MZ 
9389c8167e9SKatayama Hirofumi MZ     pti = PsGetCurrentThreadWin32Thread();
9399c8167e9SKatayama Hirofumi MZ     if (pWnd->head.pti->ppi == pti->ppi)
9409c8167e9SKatayama Hirofumi MZ         ret = (DWORD)(ULONG_PTR)UserGetProp(pWnd, AtomImeLevel, TRUE);
9419c8167e9SKatayama Hirofumi MZ 
9429c8167e9SKatayama Hirofumi MZ Quit:
9439c8167e9SKatayama Hirofumi MZ     UserLeave();
9449c8167e9SKatayama Hirofumi MZ     return ret;
945c2c66affSColin Finck }
946c2c66affSColin Finck 
9472f7775c6SKatayama Hirofumi MZ // Win: GetImeInfoEx
94836740ca9SKatayama Hirofumi MZ BOOL FASTCALL UserGetImeInfoEx(LPVOID pUnknown, PIMEINFOEX pInfoEx, IMEINFOEXCLASS SearchType)
94936740ca9SKatayama Hirofumi MZ {
95036740ca9SKatayama Hirofumi MZ     PKL pkl, pklHead;
95136740ca9SKatayama Hirofumi MZ 
95236740ca9SKatayama Hirofumi MZ     if (!gspklBaseLayout)
95336740ca9SKatayama Hirofumi MZ         return FALSE;
95436740ca9SKatayama Hirofumi MZ 
95536740ca9SKatayama Hirofumi MZ     pkl = pklHead = gspklBaseLayout;
95636740ca9SKatayama Hirofumi MZ 
95736740ca9SKatayama Hirofumi MZ     /* Find the matching entry from the list and get info */
95836740ca9SKatayama Hirofumi MZ     if (SearchType == ImeInfoExKeyboardLayout)
95936740ca9SKatayama Hirofumi MZ     {
96036740ca9SKatayama Hirofumi MZ         do
96136740ca9SKatayama Hirofumi MZ         {
96228959a2dSKatayama Hirofumi MZ             if (pInfoEx->hkl == pkl->hkl)
96336740ca9SKatayama Hirofumi MZ             {
96436740ca9SKatayama Hirofumi MZ                 if (!pkl->piiex)
96536740ca9SKatayama Hirofumi MZ                     break;
96636740ca9SKatayama Hirofumi MZ 
96728959a2dSKatayama Hirofumi MZ                 *pInfoEx = *pkl->piiex;
96828959a2dSKatayama Hirofumi MZ                 return TRUE;
96936740ca9SKatayama Hirofumi MZ             }
97036740ca9SKatayama Hirofumi MZ 
97136740ca9SKatayama Hirofumi MZ             pkl = pkl->pklNext;
97236740ca9SKatayama Hirofumi MZ         } while (pkl != pklHead);
97336740ca9SKatayama Hirofumi MZ     }
97436740ca9SKatayama Hirofumi MZ     else if (SearchType == ImeInfoExImeFileName)
97536740ca9SKatayama Hirofumi MZ     {
97636740ca9SKatayama Hirofumi MZ         do
97736740ca9SKatayama Hirofumi MZ         {
97836740ca9SKatayama Hirofumi MZ             if (pkl->piiex &&
97936740ca9SKatayama Hirofumi MZ                 _wcsnicmp(pkl->piiex->wszImeFile, pInfoEx->wszImeFile,
98028959a2dSKatayama Hirofumi MZ                           RTL_NUMBER_OF(pkl->piiex->wszImeFile)) == 0)
98136740ca9SKatayama Hirofumi MZ             {
98228959a2dSKatayama Hirofumi MZ                 *pInfoEx = *pkl->piiex;
98328959a2dSKatayama Hirofumi MZ                 return TRUE;
98436740ca9SKatayama Hirofumi MZ             }
98536740ca9SKatayama Hirofumi MZ 
98636740ca9SKatayama Hirofumi MZ             pkl = pkl->pklNext;
98736740ca9SKatayama Hirofumi MZ         } while (pkl != pklHead);
98836740ca9SKatayama Hirofumi MZ     }
98936740ca9SKatayama Hirofumi MZ     else
99036740ca9SKatayama Hirofumi MZ     {
99136740ca9SKatayama Hirofumi MZ         /* Do nothing */
99236740ca9SKatayama Hirofumi MZ     }
99336740ca9SKatayama Hirofumi MZ 
99428959a2dSKatayama Hirofumi MZ     return FALSE;
99536740ca9SKatayama Hirofumi MZ }
99636740ca9SKatayama Hirofumi MZ 
9974b038ec8SKatayama Hirofumi MZ BOOL
998e52ce89bSKatayama Hirofumi MZ NTAPI
999c2c66affSColin Finck NtUserGetImeInfoEx(
1000c2c66affSColin Finck     PIMEINFOEX pImeInfoEx,
10014b038ec8SKatayama Hirofumi MZ     IMEINFOEXCLASS SearchType)
1002c2c66affSColin Finck {
100336740ca9SKatayama Hirofumi MZ     IMEINFOEX ImeInfoEx;
100436740ca9SKatayama Hirofumi MZ     BOOL ret = FALSE;
100536740ca9SKatayama Hirofumi MZ 
100636740ca9SKatayama Hirofumi MZ     UserEnterShared();
100736740ca9SKatayama Hirofumi MZ 
100836740ca9SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1009b5c9d532SKatayama Hirofumi MZ     {
1010b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
101136740ca9SKatayama Hirofumi MZ         goto Quit;
1012b5c9d532SKatayama Hirofumi MZ     }
101336740ca9SKatayama Hirofumi MZ 
101436740ca9SKatayama Hirofumi MZ     _SEH2_TRY
101536740ca9SKatayama Hirofumi MZ     {
101636740ca9SKatayama Hirofumi MZ         ProbeForWrite(pImeInfoEx, sizeof(*pImeInfoEx), 1);
101736740ca9SKatayama Hirofumi MZ         ImeInfoEx = *pImeInfoEx;
101836740ca9SKatayama Hirofumi MZ     }
101936740ca9SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
102036740ca9SKatayama Hirofumi MZ     {
102136740ca9SKatayama Hirofumi MZ         goto Quit;
102236740ca9SKatayama Hirofumi MZ     }
102336740ca9SKatayama Hirofumi MZ     _SEH2_END;
102436740ca9SKatayama Hirofumi MZ 
102536740ca9SKatayama Hirofumi MZ     ret = UserGetImeInfoEx(NULL, &ImeInfoEx, SearchType);
1026e52ce89bSKatayama Hirofumi MZ     if (!ret)
1027e52ce89bSKatayama Hirofumi MZ         goto Quit;
1028e52ce89bSKatayama Hirofumi MZ 
102936740ca9SKatayama Hirofumi MZ     _SEH2_TRY
103036740ca9SKatayama Hirofumi MZ     {
103136740ca9SKatayama Hirofumi MZ         *pImeInfoEx = ImeInfoEx;
103236740ca9SKatayama Hirofumi MZ     }
103336740ca9SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
103436740ca9SKatayama Hirofumi MZ     {
103536740ca9SKatayama Hirofumi MZ         ret = FALSE;
103636740ca9SKatayama Hirofumi MZ     }
103736740ca9SKatayama Hirofumi MZ     _SEH2_END;
1038c2c66affSColin Finck 
103936740ca9SKatayama Hirofumi MZ Quit:
104036740ca9SKatayama Hirofumi MZ     UserLeave();
104136740ca9SKatayama Hirofumi MZ     return ret;
104236740ca9SKatayama Hirofumi MZ }
1043c2c66affSColin Finck 
10449c8167e9SKatayama Hirofumi MZ BOOL
1045e52ce89bSKatayama Hirofumi MZ NTAPI
10469c8167e9SKatayama Hirofumi MZ NtUserSetAppImeLevel(HWND hWnd, DWORD dwLevel)
1047c2c66affSColin Finck {
10489c8167e9SKatayama Hirofumi MZ     BOOL ret = FALSE;
10499c8167e9SKatayama Hirofumi MZ     PWND pWnd;
10509c8167e9SKatayama Hirofumi MZ     PTHREADINFO pti;
10519c8167e9SKatayama Hirofumi MZ 
10529c8167e9SKatayama Hirofumi MZ     UserEnterExclusive();
10539c8167e9SKatayama Hirofumi MZ 
10549c8167e9SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
10559c8167e9SKatayama Hirofumi MZ     {
1056b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
10579c8167e9SKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
10589c8167e9SKatayama Hirofumi MZ         goto Quit;
10599c8167e9SKatayama Hirofumi MZ     }
10609c8167e9SKatayama Hirofumi MZ 
1061b5c9d532SKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
1062b5c9d532SKatayama Hirofumi MZ     if (!pWnd)
1063b5c9d532SKatayama Hirofumi MZ         goto Quit;
1064b5c9d532SKatayama Hirofumi MZ 
10659c8167e9SKatayama Hirofumi MZ     pti = PsGetCurrentThreadWin32Thread();
10669c8167e9SKatayama Hirofumi MZ     if (pWnd->head.pti->ppi == pti->ppi)
10679c8167e9SKatayama Hirofumi MZ         ret = UserSetProp(pWnd, AtomImeLevel, (HANDLE)(ULONG_PTR)dwLevel, TRUE);
10689c8167e9SKatayama Hirofumi MZ 
10699c8167e9SKatayama Hirofumi MZ Quit:
10709c8167e9SKatayama Hirofumi MZ     UserLeave();
10719c8167e9SKatayama Hirofumi MZ     return ret;
1072c2c66affSColin Finck }
1073c2c66affSColin Finck 
10742f7775c6SKatayama Hirofumi MZ // Win: SetImeInfoEx
10751f446936SKatayama Hirofumi MZ BOOL FASTCALL UserSetImeInfoEx(LPVOID pUnknown, PIMEINFOEX pImeInfoEx)
1076c2c66affSColin Finck {
10771f446936SKatayama Hirofumi MZ     PKL pklHead, pkl;
10781f446936SKatayama Hirofumi MZ 
10791f446936SKatayama Hirofumi MZ     pkl = pklHead = gspklBaseLayout;
10801f446936SKatayama Hirofumi MZ 
10811f446936SKatayama Hirofumi MZ     do
10821f446936SKatayama Hirofumi MZ     {
10831f446936SKatayama Hirofumi MZ         if (pkl->hkl != pImeInfoEx->hkl)
10841f446936SKatayama Hirofumi MZ         {
10851f446936SKatayama Hirofumi MZ             pkl = pkl->pklNext;
10861f446936SKatayama Hirofumi MZ             continue;
10871f446936SKatayama Hirofumi MZ         }
10881f446936SKatayama Hirofumi MZ 
10891f446936SKatayama Hirofumi MZ         if (!pkl->piiex)
10901f446936SKatayama Hirofumi MZ             return FALSE;
10911f446936SKatayama Hirofumi MZ 
10921f446936SKatayama Hirofumi MZ         if (!pkl->piiex->fLoadFlag)
10931f446936SKatayama Hirofumi MZ             *pkl->piiex = *pImeInfoEx;
10941f446936SKatayama Hirofumi MZ 
10951f446936SKatayama Hirofumi MZ         return TRUE;
10961f446936SKatayama Hirofumi MZ     } while (pkl != pklHead);
10971f446936SKatayama Hirofumi MZ 
10981f446936SKatayama Hirofumi MZ     return FALSE;
10991f446936SKatayama Hirofumi MZ }
11001f446936SKatayama Hirofumi MZ 
11011f446936SKatayama Hirofumi MZ BOOL
1102e52ce89bSKatayama Hirofumi MZ NTAPI
11031f446936SKatayama Hirofumi MZ NtUserSetImeInfoEx(PIMEINFOEX pImeInfoEx)
11041f446936SKatayama Hirofumi MZ {
11051f446936SKatayama Hirofumi MZ     BOOL ret = FALSE;
11061f446936SKatayama Hirofumi MZ     IMEINFOEX ImeInfoEx;
11071f446936SKatayama Hirofumi MZ 
11081f446936SKatayama Hirofumi MZ     UserEnterExclusive();
11091f446936SKatayama Hirofumi MZ 
11101f446936SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1111b5c9d532SKatayama Hirofumi MZ     {
1112b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
11131f446936SKatayama Hirofumi MZ         goto Quit;
1114b5c9d532SKatayama Hirofumi MZ     }
11151f446936SKatayama Hirofumi MZ 
11161f446936SKatayama Hirofumi MZ     _SEH2_TRY
11171f446936SKatayama Hirofumi MZ     {
11181f446936SKatayama Hirofumi MZ         ProbeForRead(pImeInfoEx, sizeof(*pImeInfoEx), 1);
11191f446936SKatayama Hirofumi MZ         ImeInfoEx = *pImeInfoEx;
11201f446936SKatayama Hirofumi MZ     }
11211f446936SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
11221f446936SKatayama Hirofumi MZ     {
11231f446936SKatayama Hirofumi MZ         goto Quit;
11241f446936SKatayama Hirofumi MZ     }
11251f446936SKatayama Hirofumi MZ     _SEH2_END;
11261f446936SKatayama Hirofumi MZ 
11271f446936SKatayama Hirofumi MZ     ret = UserSetImeInfoEx(NULL, &ImeInfoEx);
11281f446936SKatayama Hirofumi MZ 
11291f446936SKatayama Hirofumi MZ Quit:
11301f446936SKatayama Hirofumi MZ     UserLeave();
11311f446936SKatayama Hirofumi MZ     return ret;
1132c2c66affSColin Finck }
1133c2c66affSColin Finck 
1134e52ce89bSKatayama Hirofumi MZ BOOL NTAPI
11358c6dcdcfSKatayama Hirofumi MZ NtUserSetImeOwnerWindow(HWND hImeWnd, HWND hwndFocus)
1136c2c66affSColin Finck {
11370519ae0aSKatayama Hirofumi MZ     BOOL ret = FALSE;
11380519ae0aSKatayama Hirofumi MZ     PWND pImeWnd, pwndFocus, pwndTopLevel, pwnd, pwndActive;
11390519ae0aSKatayama Hirofumi MZ     PTHREADINFO ptiIme;
11400519ae0aSKatayama Hirofumi MZ 
11410519ae0aSKatayama Hirofumi MZ     UserEnterExclusive();
11420519ae0aSKatayama Hirofumi MZ 
1143b5c9d532SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1144b5c9d532SKatayama Hirofumi MZ     {
1145b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1146b5c9d532SKatayama Hirofumi MZ         goto Quit;
1147b5c9d532SKatayama Hirofumi MZ     }
1148b5c9d532SKatayama Hirofumi MZ 
11490519ae0aSKatayama Hirofumi MZ     pImeWnd = ValidateHwndNoErr(hImeWnd);
1150b5c9d532SKatayama Hirofumi MZ     if (!pImeWnd || pImeWnd->fnid != FNID_IME)
11510519ae0aSKatayama Hirofumi MZ         goto Quit;
11520519ae0aSKatayama Hirofumi MZ 
11530519ae0aSKatayama Hirofumi MZ     pwndFocus = ValidateHwndNoErr(hwndFocus);
11540519ae0aSKatayama Hirofumi MZ     if (pwndFocus)
11550519ae0aSKatayama Hirofumi MZ     {
11560519ae0aSKatayama Hirofumi MZ         if (IS_WND_IMELIKE(pwndFocus))
11570519ae0aSKatayama Hirofumi MZ             goto Quit;
11580519ae0aSKatayama Hirofumi MZ 
11590519ae0aSKatayama Hirofumi MZ         pwndTopLevel = IntGetTopLevelWindow(pwndFocus);
11600519ae0aSKatayama Hirofumi MZ 
11610519ae0aSKatayama Hirofumi MZ         for (pwnd = pwndTopLevel; pwnd; pwnd = pwnd->spwndOwner)
11620519ae0aSKatayama Hirofumi MZ         {
11630519ae0aSKatayama Hirofumi MZ             if (pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME])
11640519ae0aSKatayama Hirofumi MZ             {
11650519ae0aSKatayama Hirofumi MZ                 pwndTopLevel = NULL;
11660519ae0aSKatayama Hirofumi MZ                 break;
11670519ae0aSKatayama Hirofumi MZ             }
11680519ae0aSKatayama Hirofumi MZ         }
11690519ae0aSKatayama Hirofumi MZ 
11700519ae0aSKatayama Hirofumi MZ         pImeWnd->spwndOwner = pwndTopLevel;
11710519ae0aSKatayama Hirofumi MZ         // TODO:
11720519ae0aSKatayama Hirofumi MZ     }
11730519ae0aSKatayama Hirofumi MZ     else
11740519ae0aSKatayama Hirofumi MZ     {
11750519ae0aSKatayama Hirofumi MZ         ptiIme = pImeWnd->head.pti;
11760519ae0aSKatayama Hirofumi MZ         pwndActive = ptiIme->MessageQueue->spwndActive;
11770519ae0aSKatayama Hirofumi MZ 
11780519ae0aSKatayama Hirofumi MZ         if (!pwndActive || pwndActive != pImeWnd->spwndOwner)
11790519ae0aSKatayama Hirofumi MZ         {
11800519ae0aSKatayama Hirofumi MZ             if (pwndActive && ptiIme == pwndActive->head.pti && !IS_WND_IMELIKE(pwndActive))
11810519ae0aSKatayama Hirofumi MZ             {
11820519ae0aSKatayama Hirofumi MZ                 pImeWnd->spwndOwner = pwndActive;
11830519ae0aSKatayama Hirofumi MZ             }
11840519ae0aSKatayama Hirofumi MZ             else
11850519ae0aSKatayama Hirofumi MZ             {
11860519ae0aSKatayama Hirofumi MZ                 // TODO:
11870519ae0aSKatayama Hirofumi MZ             }
11880519ae0aSKatayama Hirofumi MZ 
11890519ae0aSKatayama Hirofumi MZ             // TODO:
11900519ae0aSKatayama Hirofumi MZ         }
11910519ae0aSKatayama Hirofumi MZ     }
11920519ae0aSKatayama Hirofumi MZ 
11930519ae0aSKatayama Hirofumi MZ     ret = TRUE;
11940519ae0aSKatayama Hirofumi MZ 
11950519ae0aSKatayama Hirofumi MZ Quit:
11960519ae0aSKatayama Hirofumi MZ     UserLeave();
11970519ae0aSKatayama Hirofumi MZ     return ret;
1198c2c66affSColin Finck }
1199c2c66affSColin Finck 
12003d78601fSKatayama Hirofumi MZ PVOID
12013d78601fSKatayama Hirofumi MZ AllocInputContextObject(PDESKTOP pDesk,
12023d78601fSKatayama Hirofumi MZ                         PTHREADINFO pti,
12033d78601fSKatayama Hirofumi MZ                         SIZE_T Size,
12043d78601fSKatayama Hirofumi MZ                         PVOID* HandleOwner)
12053d78601fSKatayama Hirofumi MZ {
12063d78601fSKatayama Hirofumi MZ     PTHRDESKHEAD ObjHead;
12073d78601fSKatayama Hirofumi MZ 
12083d78601fSKatayama Hirofumi MZ     ASSERT(Size > sizeof(*ObjHead));
12093d78601fSKatayama Hirofumi MZ     ASSERT(pti != NULL);
12103d78601fSKatayama Hirofumi MZ 
1211cfeb498eSKatayama Hirofumi MZ     if (!pDesk)
1212cfeb498eSKatayama Hirofumi MZ         pDesk = pti->rpdesk;
1213cfeb498eSKatayama Hirofumi MZ 
1214cfeb498eSKatayama Hirofumi MZ     ObjHead = DesktopHeapAlloc(pDesk, Size);
12153d78601fSKatayama Hirofumi MZ     if (!ObjHead)
12163d78601fSKatayama Hirofumi MZ         return NULL;
12173d78601fSKatayama Hirofumi MZ 
12183d78601fSKatayama Hirofumi MZ     RtlZeroMemory(ObjHead, Size);
12193d78601fSKatayama Hirofumi MZ 
12203d78601fSKatayama Hirofumi MZ     ObjHead->pSelf = ObjHead;
12213d78601fSKatayama Hirofumi MZ     ObjHead->rpdesk = pDesk;
12223d78601fSKatayama Hirofumi MZ     ObjHead->pti = pti;
12233d78601fSKatayama Hirofumi MZ     IntReferenceThreadInfo(pti);
12243d78601fSKatayama Hirofumi MZ     *HandleOwner = pti;
12253d78601fSKatayama Hirofumi MZ     pti->ppi->UserHandleCount++;
12263d78601fSKatayama Hirofumi MZ 
12273d78601fSKatayama Hirofumi MZ     return ObjHead;
12283d78601fSKatayama Hirofumi MZ }
12293d78601fSKatayama Hirofumi MZ 
12303d78601fSKatayama Hirofumi MZ VOID UserFreeInputContext(PVOID Object)
12313d78601fSKatayama Hirofumi MZ {
1232cfeb498eSKatayama Hirofumi MZ     PTHRDESKHEAD ObjHead = Object;
1233cfeb498eSKatayama Hirofumi MZ     PDESKTOP pDesk = ObjHead->rpdesk;
1234eb902e5bSKatayama Hirofumi MZ     PIMC pNode, pIMC = Object;
1235757bed81SKatayama Hirofumi MZ     PTHREADINFO pti;
12363d78601fSKatayama Hirofumi MZ 
1237757bed81SKatayama Hirofumi MZ     if (!pIMC)
1238757bed81SKatayama Hirofumi MZ         return;
12393d78601fSKatayama Hirofumi MZ 
1240eb902e5bSKatayama Hirofumi MZ     // Remove pIMC from the list except spDefaultImc
1241757bed81SKatayama Hirofumi MZ     pti = pIMC->head.pti;
1242eb902e5bSKatayama Hirofumi MZ     for (pNode = pti->spDefaultImc; pNode; pNode = pNode->pImcNext)
12432b2366abSKatayama Hirofumi MZ     {
1244eb902e5bSKatayama Hirofumi MZ         if (pNode->pImcNext == pIMC)
12452b2366abSKatayama Hirofumi MZ         {
1246eb902e5bSKatayama Hirofumi MZ             pNode->pImcNext = pIMC->pImcNext;
12472b2366abSKatayama Hirofumi MZ             break;
12482b2366abSKatayama Hirofumi MZ         }
12492b2366abSKatayama Hirofumi MZ     }
1250757bed81SKatayama Hirofumi MZ 
1251cfeb498eSKatayama Hirofumi MZ     DesktopHeapFree(pDesk, Object);
125245a4e53fSKatayama Hirofumi MZ 
125345a4e53fSKatayama Hirofumi MZ     pti->ppi->UserHandleCount--;
125445a4e53fSKatayama Hirofumi MZ     IntDereferenceThreadInfo(pti);
125545a4e53fSKatayama Hirofumi MZ }
125645a4e53fSKatayama Hirofumi MZ 
125745a4e53fSKatayama Hirofumi MZ BOOLEAN UserDestroyInputContext(PVOID Object)
125845a4e53fSKatayama Hirofumi MZ {
12592b2366abSKatayama Hirofumi MZ     PIMC pIMC = Object;
1260eb902e5bSKatayama Hirofumi MZ     if (!pIMC || !UserMarkObjectDestroy(pIMC))
126145a4e53fSKatayama Hirofumi MZ         return TRUE;
126245a4e53fSKatayama Hirofumi MZ 
1263cfeb498eSKatayama Hirofumi MZ     return UserDeleteObject(UserHMGetHandle(pIMC), TYPE_INPUTCONTEXT);
12643d78601fSKatayama Hirofumi MZ }
12653d78601fSKatayama Hirofumi MZ 
1266eb902e5bSKatayama Hirofumi MZ // Win: DestroyInputContext
1267*0f1e19a7SKatayama Hirofumi MZ BOOL IntDestroyInputContext(PIMC pIMC)
12683d78601fSKatayama Hirofumi MZ {
1269*0f1e19a7SKatayama Hirofumi MZ     HIMC hIMC = UserHMGetHandle(pIMC);
1270eb902e5bSKatayama Hirofumi MZ     PTHREADINFO pti = pIMC->head.pti;
1271eb902e5bSKatayama Hirofumi MZ     PWND pwndChild;
1272eb902e5bSKatayama Hirofumi MZ     PWINDOWLIST pwl;
12731bc9dda5SKatayama Hirofumi MZ     HWND *phwnd;
12741bc9dda5SKatayama Hirofumi MZ     PWND pWnd;
12753d78601fSKatayama Hirofumi MZ 
1276*0f1e19a7SKatayama Hirofumi MZ     if (pti != gptiCurrent)
12773d78601fSKatayama Hirofumi MZ     {
1278eb902e5bSKatayama Hirofumi MZ         EngSetLastError(ERROR_ACCESS_DENIED);
1279eb902e5bSKatayama Hirofumi MZ         return FALSE;
12803d78601fSKatayama Hirofumi MZ     }
12813d78601fSKatayama Hirofumi MZ 
1282eb902e5bSKatayama Hirofumi MZ     if (pIMC == pti->spDefaultImc)
1283eb902e5bSKatayama Hirofumi MZ     {
1284eb902e5bSKatayama Hirofumi MZ         EngSetLastError(ERROR_INVALID_PARAMETER);
1285eb902e5bSKatayama Hirofumi MZ         return FALSE;
1286eb902e5bSKatayama Hirofumi MZ     }
12873d78601fSKatayama Hirofumi MZ 
1288eb902e5bSKatayama Hirofumi MZ     pwndChild = pti->rpdesk->pDeskInfo->spwnd->spwndChild;
1289eb902e5bSKatayama Hirofumi MZ     pwl = IntBuildHwndList(pwndChild, IACE_LIST | IACE_CHILDREN, pti);
12901bc9dda5SKatayama Hirofumi MZ     if (pwl)
12911bc9dda5SKatayama Hirofumi MZ     {
12921bc9dda5SKatayama Hirofumi MZ         for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
12931bc9dda5SKatayama Hirofumi MZ         {
1294eb902e5bSKatayama Hirofumi MZ             pWnd = UserGetObjectNoErr(gHandleTable, *phwnd, TYPE_WINDOW);
1295eb902e5bSKatayama Hirofumi MZ             if (pWnd && pWnd->hImc == hIMC)
12961bc9dda5SKatayama Hirofumi MZ                 IntAssociateInputContext(pWnd, pti->spDefaultImc);
12971bc9dda5SKatayama Hirofumi MZ         }
12981bc9dda5SKatayama Hirofumi MZ 
12991bc9dda5SKatayama Hirofumi MZ         IntFreeHwndList(pwl);
13001bc9dda5SKatayama Hirofumi MZ     }
13011bc9dda5SKatayama Hirofumi MZ 
1302eb902e5bSKatayama Hirofumi MZ     UserDeleteObject(hIMC, TYPE_INPUTCONTEXT);
1303eb902e5bSKatayama Hirofumi MZ     return TRUE;
1304eb902e5bSKatayama Hirofumi MZ }
1305eb902e5bSKatayama Hirofumi MZ 
1306eb902e5bSKatayama Hirofumi MZ BOOL NTAPI NtUserDestroyInputContext(HIMC hIMC)
1307eb902e5bSKatayama Hirofumi MZ {
1308eb902e5bSKatayama Hirofumi MZ     BOOL ret = FALSE;
1309eb902e5bSKatayama Hirofumi MZ     PIMC pIMC;
1310eb902e5bSKatayama Hirofumi MZ 
1311eb902e5bSKatayama Hirofumi MZ     UserEnterExclusive();
1312eb902e5bSKatayama Hirofumi MZ 
1313eb902e5bSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1314eb902e5bSKatayama Hirofumi MZ     {
1315eb902e5bSKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1316eb902e5bSKatayama Hirofumi MZ         goto Quit;
1317eb902e5bSKatayama Hirofumi MZ     }
1318eb902e5bSKatayama Hirofumi MZ 
1319eb902e5bSKatayama Hirofumi MZ     pIMC = UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT);
1320eb902e5bSKatayama Hirofumi MZ     if (pIMC)
1321eb902e5bSKatayama Hirofumi MZ         ret = IntDestroyInputContext(pIMC);
13221bc9dda5SKatayama Hirofumi MZ 
13231bc9dda5SKatayama Hirofumi MZ Quit:
13243d78601fSKatayama Hirofumi MZ     UserLeave();
13253d78601fSKatayama Hirofumi MZ     return ret;
13263d78601fSKatayama Hirofumi MZ }
1327c2c66affSColin Finck 
13282f7775c6SKatayama Hirofumi MZ // Win: CreateInputContext
1329470aa276SKatayama Hirofumi MZ PIMC FASTCALL UserCreateInputContext(ULONG_PTR dwClientImcData)
1330470aa276SKatayama Hirofumi MZ {
1331470aa276SKatayama Hirofumi MZ     PIMC pIMC;
1332470aa276SKatayama Hirofumi MZ     PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
1333470aa276SKatayama Hirofumi MZ     PDESKTOP pdesk = pti->rpdesk;
1334470aa276SKatayama Hirofumi MZ 
1335470aa276SKatayama Hirofumi MZ     if (!IS_IMM_MODE() || (pti->TIF_flags & TIF_DISABLEIME)) // Disabled?
1336b5c9d532SKatayama Hirofumi MZ     {
1337b5c9d532SKatayama Hirofumi MZ         ERR("IME is disabled\n");
1338470aa276SKatayama Hirofumi MZ         return NULL;
1339b5c9d532SKatayama Hirofumi MZ     }
1340470aa276SKatayama Hirofumi MZ 
1341470aa276SKatayama Hirofumi MZ     if (!pdesk) // No desktop?
1342470aa276SKatayama Hirofumi MZ         return NULL;
1343470aa276SKatayama Hirofumi MZ 
1344470aa276SKatayama Hirofumi MZ     // pti->spDefaultImc should be already set if non-first time.
1345470aa276SKatayama Hirofumi MZ     if (dwClientImcData && !pti->spDefaultImc)
1346470aa276SKatayama Hirofumi MZ         return NULL;
1347470aa276SKatayama Hirofumi MZ 
1348470aa276SKatayama Hirofumi MZ     // Create an input context user object.
1349470aa276SKatayama Hirofumi MZ     pIMC = UserCreateObject(gHandleTable, pdesk, pti, NULL, TYPE_INPUTCONTEXT, sizeof(IMC));
1350470aa276SKatayama Hirofumi MZ     if (!pIMC)
1351470aa276SKatayama Hirofumi MZ         return NULL;
1352470aa276SKatayama Hirofumi MZ 
1353470aa276SKatayama Hirofumi MZ     // Release the extra reference (UserCreateObject added 2 references).
1354470aa276SKatayama Hirofumi MZ     UserDereferenceObject(pIMC);
1355470aa276SKatayama Hirofumi MZ 
1356470aa276SKatayama Hirofumi MZ     if (dwClientImcData) // Non-first time.
1357470aa276SKatayama Hirofumi MZ     {
1358470aa276SKatayama Hirofumi MZ         // Insert pIMC to the second position (non-default) of the list.
1359470aa276SKatayama Hirofumi MZ         pIMC->pImcNext = pti->spDefaultImc->pImcNext;
1360470aa276SKatayama Hirofumi MZ         pti->spDefaultImc->pImcNext = pIMC;
1361470aa276SKatayama Hirofumi MZ     }
1362470aa276SKatayama Hirofumi MZ     else // First time. It's the default IMC.
1363470aa276SKatayama Hirofumi MZ     {
1364470aa276SKatayama Hirofumi MZ         // Add the first one (default) to the list.
1365470aa276SKatayama Hirofumi MZ         pti->spDefaultImc = pIMC;
1366470aa276SKatayama Hirofumi MZ         pIMC->pImcNext = NULL;
1367470aa276SKatayama Hirofumi MZ     }
1368470aa276SKatayama Hirofumi MZ 
1369470aa276SKatayama Hirofumi MZ     pIMC->dwClientImcData = dwClientImcData; // Set it.
1370470aa276SKatayama Hirofumi MZ     return pIMC;
1371470aa276SKatayama Hirofumi MZ }
1372470aa276SKatayama Hirofumi MZ 
1373470aa276SKatayama Hirofumi MZ HIMC
1374e52ce89bSKatayama Hirofumi MZ NTAPI
1375470aa276SKatayama Hirofumi MZ NtUserCreateInputContext(ULONG_PTR dwClientImcData)
1376470aa276SKatayama Hirofumi MZ {
1377470aa276SKatayama Hirofumi MZ     PIMC pIMC;
1378470aa276SKatayama Hirofumi MZ     HIMC ret = NULL;
1379470aa276SKatayama Hirofumi MZ 
1380470aa276SKatayama Hirofumi MZ     if (!dwClientImcData)
1381470aa276SKatayama Hirofumi MZ         return NULL;
1382470aa276SKatayama Hirofumi MZ 
1383470aa276SKatayama Hirofumi MZ     UserEnterExclusive();
1384470aa276SKatayama Hirofumi MZ 
1385470aa276SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1386b5c9d532SKatayama Hirofumi MZ     {
1387b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1388470aa276SKatayama Hirofumi MZ         goto Quit;
1389b5c9d532SKatayama Hirofumi MZ     }
1390470aa276SKatayama Hirofumi MZ 
1391470aa276SKatayama Hirofumi MZ     pIMC = UserCreateInputContext(dwClientImcData);
1392470aa276SKatayama Hirofumi MZ     if (pIMC)
1393470aa276SKatayama Hirofumi MZ         ret = UserHMGetHandle(pIMC);
1394470aa276SKatayama Hirofumi MZ 
1395470aa276SKatayama Hirofumi MZ Quit:
1396470aa276SKatayama Hirofumi MZ     UserLeave();
1397470aa276SKatayama Hirofumi MZ     return ret;
1398470aa276SKatayama Hirofumi MZ }
1399470aa276SKatayama Hirofumi MZ 
14002f7775c6SKatayama Hirofumi MZ // Win: AssociateInputContextEx
1401f2c3167dSKatayama Hirofumi MZ DWORD FASTCALL IntAssociateInputContextEx(PWND pWnd, PIMC pIMC, DWORD dwFlags)
1402f2c3167dSKatayama Hirofumi MZ {
1403f2c3167dSKatayama Hirofumi MZ     DWORD ret = 0;
1404f2c3167dSKatayama Hirofumi MZ     PWINDOWLIST pwl;
1405f2c3167dSKatayama Hirofumi MZ     BOOL bIgnoreNullImc = (dwFlags & IACE_IGNORENOCONTEXT);
1406f2c3167dSKatayama Hirofumi MZ     PTHREADINFO pti = pWnd->head.pti;
1407f2c3167dSKatayama Hirofumi MZ     PWND pwndTarget, pwndFocus = pti->MessageQueue->spwndFocus;
1408f2c3167dSKatayama Hirofumi MZ     HWND *phwnd;
1409f2c3167dSKatayama Hirofumi MZ     HIMC hIMC;
1410f2c3167dSKatayama Hirofumi MZ 
1411f2c3167dSKatayama Hirofumi MZ     if (dwFlags & IACE_DEFAULT)
1412f2c3167dSKatayama Hirofumi MZ     {
1413f2c3167dSKatayama Hirofumi MZ         pIMC = pti->spDefaultImc;
1414f2c3167dSKatayama Hirofumi MZ     }
1415f2c3167dSKatayama Hirofumi MZ     else
1416f2c3167dSKatayama Hirofumi MZ     {
1417f2c3167dSKatayama Hirofumi MZ         if (pIMC && pti != pIMC->head.pti)
1418f2c3167dSKatayama Hirofumi MZ             return 2;
1419f2c3167dSKatayama Hirofumi MZ     }
1420f2c3167dSKatayama Hirofumi MZ 
1421f2c3167dSKatayama Hirofumi MZ     if (pWnd->head.pti->ppi != GetW32ThreadInfo()->ppi ||
1422f2c3167dSKatayama Hirofumi MZ         (pIMC && pIMC->head.rpdesk != pWnd->head.rpdesk))
1423f2c3167dSKatayama Hirofumi MZ     {
1424f2c3167dSKatayama Hirofumi MZ         return 2;
1425f2c3167dSKatayama Hirofumi MZ     }
1426f2c3167dSKatayama Hirofumi MZ 
1427f2c3167dSKatayama Hirofumi MZ     if ((dwFlags & IACE_CHILDREN) && pWnd->spwndChild)
1428f2c3167dSKatayama Hirofumi MZ     {
1429f2c3167dSKatayama Hirofumi MZ         pwl = IntBuildHwndList(pWnd->spwndChild, IACE_CHILDREN | IACE_LIST, pti);
1430f2c3167dSKatayama Hirofumi MZ         if (pwl)
1431f2c3167dSKatayama Hirofumi MZ         {
1432f2c3167dSKatayama Hirofumi MZ             for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
1433f2c3167dSKatayama Hirofumi MZ             {
1434f2c3167dSKatayama Hirofumi MZ                 pwndTarget = ValidateHwndNoErr(*phwnd);
1435f2c3167dSKatayama Hirofumi MZ                 if (!pwndTarget)
1436f2c3167dSKatayama Hirofumi MZ                     continue;
1437f2c3167dSKatayama Hirofumi MZ 
1438f2c3167dSKatayama Hirofumi MZ                 hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1439f2c3167dSKatayama Hirofumi MZ                 if (pwndTarget->hImc == hIMC || (bIgnoreNullImc && !pwndTarget->hImc))
1440f2c3167dSKatayama Hirofumi MZ                     continue;
1441f2c3167dSKatayama Hirofumi MZ 
1442f2c3167dSKatayama Hirofumi MZ                 IntAssociateInputContext(pwndTarget, pIMC);
1443f2c3167dSKatayama Hirofumi MZ                 if (pwndTarget == pwndFocus)
1444f2c3167dSKatayama Hirofumi MZ                     ret = 1;
1445f2c3167dSKatayama Hirofumi MZ             }
1446f2c3167dSKatayama Hirofumi MZ 
1447f2c3167dSKatayama Hirofumi MZ             IntFreeHwndList(pwl);
1448f2c3167dSKatayama Hirofumi MZ         }
1449f2c3167dSKatayama Hirofumi MZ     }
1450f2c3167dSKatayama Hirofumi MZ 
1451f2c3167dSKatayama Hirofumi MZ     if (!bIgnoreNullImc || pWnd->hImc)
1452f2c3167dSKatayama Hirofumi MZ     {
1453f2c3167dSKatayama Hirofumi MZ         hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1454f2c3167dSKatayama Hirofumi MZ         if (pWnd->hImc != hIMC)
1455f2c3167dSKatayama Hirofumi MZ         {
1456f2c3167dSKatayama Hirofumi MZ             IntAssociateInputContext(pWnd, pIMC);
1457f2c3167dSKatayama Hirofumi MZ             if (pWnd == pwndFocus)
1458f2c3167dSKatayama Hirofumi MZ                 ret = 1;
1459f2c3167dSKatayama Hirofumi MZ         }
1460f2c3167dSKatayama Hirofumi MZ     }
1461f2c3167dSKatayama Hirofumi MZ 
1462f2c3167dSKatayama Hirofumi MZ     return ret;
1463f2c3167dSKatayama Hirofumi MZ }
1464f2c3167dSKatayama Hirofumi MZ 
1465470aa276SKatayama Hirofumi MZ DWORD
1466e52ce89bSKatayama Hirofumi MZ NTAPI
1467470aa276SKatayama Hirofumi MZ NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags)
1468470aa276SKatayama Hirofumi MZ {
1469f2c3167dSKatayama Hirofumi MZ     DWORD ret = 2;
1470f2c3167dSKatayama Hirofumi MZ     PWND pWnd;
1471f2c3167dSKatayama Hirofumi MZ     PIMC pIMC;
1472f2c3167dSKatayama Hirofumi MZ 
1473f2c3167dSKatayama Hirofumi MZ     UserEnterExclusive();
1474f2c3167dSKatayama Hirofumi MZ 
1475b5c9d532SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1476b5c9d532SKatayama Hirofumi MZ     {
1477b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1478b5c9d532SKatayama Hirofumi MZ         goto Quit;
1479b5c9d532SKatayama Hirofumi MZ     }
1480b5c9d532SKatayama Hirofumi MZ 
1481f2c3167dSKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
1482b5c9d532SKatayama Hirofumi MZ     if (!pWnd)
1483f2c3167dSKatayama Hirofumi MZ         goto Quit;
1484f2c3167dSKatayama Hirofumi MZ 
1485f2c3167dSKatayama Hirofumi MZ     pIMC = (hIMC ? UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT) : NULL);
1486f2c3167dSKatayama Hirofumi MZ     ret = IntAssociateInputContextEx(pWnd, pIMC, dwFlags);
1487f2c3167dSKatayama Hirofumi MZ 
1488f2c3167dSKatayama Hirofumi MZ Quit:
1489f2c3167dSKatayama Hirofumi MZ     UserLeave();
1490f2c3167dSKatayama Hirofumi MZ     return ret;
1491470aa276SKatayama Hirofumi MZ }
1492470aa276SKatayama Hirofumi MZ 
1493470aa276SKatayama Hirofumi MZ BOOL FASTCALL UserUpdateInputContext(PIMC pIMC, DWORD dwType, DWORD_PTR dwValue)
1494470aa276SKatayama Hirofumi MZ {
1495470aa276SKatayama Hirofumi MZ     PTHREADINFO pti = GetW32ThreadInfo();
1496470aa276SKatayama Hirofumi MZ     PTHREADINFO ptiIMC = pIMC->head.pti;
1497470aa276SKatayama Hirofumi MZ 
1498470aa276SKatayama Hirofumi MZ     if (pti->ppi != ptiIMC->ppi) // Different process?
1499470aa276SKatayama Hirofumi MZ         return FALSE;
1500470aa276SKatayama Hirofumi MZ 
1501470aa276SKatayama Hirofumi MZ     switch (dwType)
1502470aa276SKatayama Hirofumi MZ     {
1503470aa276SKatayama Hirofumi MZ         case UIC_CLIENTIMCDATA:
1504470aa276SKatayama Hirofumi MZ             if (pIMC->dwClientImcData)
1505470aa276SKatayama Hirofumi MZ                 return FALSE; // Already set
1506470aa276SKatayama Hirofumi MZ 
1507470aa276SKatayama Hirofumi MZ             pIMC->dwClientImcData = dwValue;
1508470aa276SKatayama Hirofumi MZ             break;
1509470aa276SKatayama Hirofumi MZ 
1510470aa276SKatayama Hirofumi MZ         case UIC_IMEWINDOW:
1511470aa276SKatayama Hirofumi MZ             if (!ValidateHwndNoErr((HWND)dwValue))
1512470aa276SKatayama Hirofumi MZ                 return FALSE; // Invalid HWND
1513470aa276SKatayama Hirofumi MZ 
1514470aa276SKatayama Hirofumi MZ             pIMC->hImeWnd = (HWND)dwValue;
1515470aa276SKatayama Hirofumi MZ             break;
1516470aa276SKatayama Hirofumi MZ 
1517470aa276SKatayama Hirofumi MZ         default:
1518470aa276SKatayama Hirofumi MZ             return FALSE;
1519470aa276SKatayama Hirofumi MZ     }
1520470aa276SKatayama Hirofumi MZ 
1521470aa276SKatayama Hirofumi MZ     return TRUE;
1522470aa276SKatayama Hirofumi MZ }
1523470aa276SKatayama Hirofumi MZ 
1524470aa276SKatayama Hirofumi MZ BOOL
1525e52ce89bSKatayama Hirofumi MZ NTAPI
1526470aa276SKatayama Hirofumi MZ NtUserUpdateInputContext(
1527470aa276SKatayama Hirofumi MZ     HIMC hIMC,
1528470aa276SKatayama Hirofumi MZ     DWORD dwType,
1529470aa276SKatayama Hirofumi MZ     DWORD_PTR dwValue)
1530470aa276SKatayama Hirofumi MZ {
1531470aa276SKatayama Hirofumi MZ     PIMC pIMC;
1532470aa276SKatayama Hirofumi MZ     BOOL ret = FALSE;
1533470aa276SKatayama Hirofumi MZ 
1534470aa276SKatayama Hirofumi MZ     UserEnterExclusive();
1535470aa276SKatayama Hirofumi MZ 
1536470aa276SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1537b5c9d532SKatayama Hirofumi MZ     {
1538b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1539470aa276SKatayama Hirofumi MZ         goto Quit;
1540b5c9d532SKatayama Hirofumi MZ     }
1541470aa276SKatayama Hirofumi MZ 
1542470aa276SKatayama Hirofumi MZ     pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT);
1543470aa276SKatayama Hirofumi MZ     if (!pIMC)
1544470aa276SKatayama Hirofumi MZ         goto Quit;
1545470aa276SKatayama Hirofumi MZ 
1546470aa276SKatayama Hirofumi MZ     ret = UserUpdateInputContext(pIMC, dwType, dwValue);
1547470aa276SKatayama Hirofumi MZ 
1548470aa276SKatayama Hirofumi MZ Quit:
1549470aa276SKatayama Hirofumi MZ     UserLeave();
1550470aa276SKatayama Hirofumi MZ     return ret;
1551470aa276SKatayama Hirofumi MZ }
1552470aa276SKatayama Hirofumi MZ 
1553470aa276SKatayama Hirofumi MZ DWORD_PTR
1554e52ce89bSKatayama Hirofumi MZ NTAPI
1555470aa276SKatayama Hirofumi MZ NtUserQueryInputContext(HIMC hIMC, DWORD dwType)
1556470aa276SKatayama Hirofumi MZ {
1557470aa276SKatayama Hirofumi MZ     PIMC pIMC;
1558470aa276SKatayama Hirofumi MZ     PTHREADINFO ptiIMC;
1559470aa276SKatayama Hirofumi MZ     DWORD_PTR ret = 0;
1560470aa276SKatayama Hirofumi MZ 
1561470aa276SKatayama Hirofumi MZ     UserEnterExclusive();
1562470aa276SKatayama Hirofumi MZ 
1563470aa276SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1564b5c9d532SKatayama Hirofumi MZ     {
1565b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1566470aa276SKatayama Hirofumi MZ         goto Quit;
1567b5c9d532SKatayama Hirofumi MZ     }
1568470aa276SKatayama Hirofumi MZ 
1569470aa276SKatayama Hirofumi MZ     pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT);
1570470aa276SKatayama Hirofumi MZ     if (!pIMC)
1571470aa276SKatayama Hirofumi MZ         goto Quit;
1572470aa276SKatayama Hirofumi MZ 
1573470aa276SKatayama Hirofumi MZ     ptiIMC = pIMC->head.pti;
1574470aa276SKatayama Hirofumi MZ 
1575470aa276SKatayama Hirofumi MZ     switch (dwType)
1576470aa276SKatayama Hirofumi MZ     {
1577470aa276SKatayama Hirofumi MZ         case QIC_INPUTPROCESSID:
1578470aa276SKatayama Hirofumi MZ             ret = (DWORD_PTR)PsGetThreadProcessId(ptiIMC->pEThread);
1579470aa276SKatayama Hirofumi MZ             break;
1580470aa276SKatayama Hirofumi MZ 
1581470aa276SKatayama Hirofumi MZ         case QIC_INPUTTHREADID:
1582470aa276SKatayama Hirofumi MZ             ret = (DWORD_PTR)PsGetThreadId(ptiIMC->pEThread);
1583470aa276SKatayama Hirofumi MZ             break;
1584470aa276SKatayama Hirofumi MZ 
1585470aa276SKatayama Hirofumi MZ         case QIC_DEFAULTWINDOWIME:
1586470aa276SKatayama Hirofumi MZ             if (ptiIMC->spwndDefaultIme)
1587470aa276SKatayama Hirofumi MZ                 ret = (DWORD_PTR)UserHMGetHandle(ptiIMC->spwndDefaultIme);
1588470aa276SKatayama Hirofumi MZ             break;
1589470aa276SKatayama Hirofumi MZ 
1590470aa276SKatayama Hirofumi MZ         case QIC_DEFAULTIMC:
1591470aa276SKatayama Hirofumi MZ             if (ptiIMC->spDefaultImc)
1592470aa276SKatayama Hirofumi MZ                 ret = (DWORD_PTR)UserHMGetHandle(ptiIMC->spDefaultImc);
1593470aa276SKatayama Hirofumi MZ             break;
1594470aa276SKatayama Hirofumi MZ     }
1595470aa276SKatayama Hirofumi MZ 
1596470aa276SKatayama Hirofumi MZ Quit:
1597470aa276SKatayama Hirofumi MZ     UserLeave();
1598470aa276SKatayama Hirofumi MZ     return ret;
1599470aa276SKatayama Hirofumi MZ }
1600470aa276SKatayama Hirofumi MZ 
1601c2c66affSColin Finck /* EOF */
1602