xref: /reactos/win32ss/user/ntuser/ime.c (revision 45a4e53f)
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 
1375d5cc578SKatayama Hirofumi MZ static VOID FASTCALL IntAddImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
1385d5cc578SKatayama Hirofumi MZ {
1395d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
1405d5cc578SKatayama Hirofumi MZ 
1415d5cc578SKatayama Hirofumi MZ     if (!*ppList)
1425d5cc578SKatayama Hirofumi MZ     {
1435d5cc578SKatayama Hirofumi MZ         *ppList = pHotKey;
1445d5cc578SKatayama Hirofumi MZ         return;
1455d5cc578SKatayama Hirofumi MZ     }
1465d5cc578SKatayama Hirofumi MZ 
1475d5cc578SKatayama Hirofumi MZ     for (pNode = *ppList; pNode; pNode = pNode->pNext)
1485d5cc578SKatayama Hirofumi MZ     {
1495d5cc578SKatayama Hirofumi MZ         if (!pNode->pNext)
1505d5cc578SKatayama Hirofumi MZ         {
1515d5cc578SKatayama Hirofumi MZ             pNode->pNext = pHotKey;
1525d5cc578SKatayama Hirofumi MZ             return;
1535d5cc578SKatayama Hirofumi MZ         }
1545d5cc578SKatayama Hirofumi MZ     }
1555d5cc578SKatayama Hirofumi MZ }
1565d5cc578SKatayama Hirofumi MZ 
1575d5cc578SKatayama Hirofumi MZ static PIMEHOTKEY FASTCALL IntGetImeHotKeyById(PIMEHOTKEY pList, DWORD dwHotKeyId)
1585d5cc578SKatayama Hirofumi MZ {
1595d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
1605d5cc578SKatayama Hirofumi MZ     for (pNode = pList; pNode; pNode = pNode->pNext)
1615d5cc578SKatayama Hirofumi MZ     {
1625d5cc578SKatayama Hirofumi MZ         if (pNode->dwHotKeyId == dwHotKeyId)
1635d5cc578SKatayama Hirofumi MZ             return pNode;
1645d5cc578SKatayama Hirofumi MZ     }
1655d5cc578SKatayama Hirofumi MZ     return NULL;
1665d5cc578SKatayama Hirofumi MZ }
1675d5cc578SKatayama Hirofumi MZ 
1685d5cc578SKatayama Hirofumi MZ static PIMEHOTKEY APIENTRY
1695d5cc578SKatayama Hirofumi MZ IntGetImeHotKeyByKeyAndLang(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight,
1705d5cc578SKatayama Hirofumi MZ                             UINT uVirtualKey, LANGID TargetLangId)
1715d5cc578SKatayama Hirofumi MZ {
1725d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
1735d5cc578SKatayama Hirofumi MZ     LANGID LangID;
1745d5cc578SKatayama Hirofumi MZ     UINT uModifiers;
1755d5cc578SKatayama Hirofumi MZ 
1765d5cc578SKatayama Hirofumi MZ     for (pNode = pList; pNode; pNode = pNode->pNext)
1775d5cc578SKatayama Hirofumi MZ     {
1785d5cc578SKatayama Hirofumi MZ         if (pNode->uVirtualKey != uVirtualKey)
1795d5cc578SKatayama Hirofumi MZ             continue;
1805d5cc578SKatayama Hirofumi MZ 
1815d5cc578SKatayama Hirofumi MZ         LangID = IntGetImeHotKeyLangId(pNode->dwHotKeyId);
1825d5cc578SKatayama Hirofumi MZ         if (LangID != TargetLangId)
1835d5cc578SKatayama Hirofumi MZ             continue;
1845d5cc578SKatayama Hirofumi MZ 
1855d5cc578SKatayama Hirofumi MZ         uModifiers = pNode->uModifiers;
1865d5cc578SKatayama Hirofumi MZ         if (uModifiers & MOD_IGNORE_ALL_MODIFIER)
1875d5cc578SKatayama Hirofumi MZ             return pNode;
1885d5cc578SKatayama Hirofumi MZ 
1895d5cc578SKatayama Hirofumi MZ         if ((uModifiers & MOD_KEYS) != uModKeys)
1905d5cc578SKatayama Hirofumi MZ             continue;
1915d5cc578SKatayama Hirofumi MZ 
1925d5cc578SKatayama Hirofumi MZ         if ((uModifiers & uLeftRight) || (uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
1935d5cc578SKatayama Hirofumi MZ             return pNode;
1945d5cc578SKatayama Hirofumi MZ     }
1955d5cc578SKatayama Hirofumi MZ 
1965d5cc578SKatayama Hirofumi MZ     return NULL;
1975d5cc578SKatayama Hirofumi MZ }
1985d5cc578SKatayama Hirofumi MZ 
1995d5cc578SKatayama Hirofumi MZ static VOID FASTCALL IntDeleteImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
2005d5cc578SKatayama Hirofumi MZ {
2015d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
2025d5cc578SKatayama Hirofumi MZ 
2035d5cc578SKatayama Hirofumi MZ     if (*ppList == pHotKey)
2045d5cc578SKatayama Hirofumi MZ     {
2055d5cc578SKatayama Hirofumi MZ         *ppList = pHotKey->pNext;
2065d5cc578SKatayama Hirofumi MZ         ExFreePoolWithTag(pHotKey, USERTAG_IMEHOTKEY);
2075d5cc578SKatayama Hirofumi MZ         return;
2085d5cc578SKatayama Hirofumi MZ     }
2095d5cc578SKatayama Hirofumi MZ 
2105d5cc578SKatayama Hirofumi MZ     for (pNode = *ppList; pNode; pNode = pNode->pNext)
2115d5cc578SKatayama Hirofumi MZ     {
2125d5cc578SKatayama Hirofumi MZ         if (pNode->pNext == pHotKey)
2135d5cc578SKatayama Hirofumi MZ         {
2145d5cc578SKatayama Hirofumi MZ             pNode->pNext = pHotKey->pNext;
2155d5cc578SKatayama Hirofumi MZ             ExFreePoolWithTag(pHotKey, USERTAG_IMEHOTKEY);
2165d5cc578SKatayama Hirofumi MZ             return;
2175d5cc578SKatayama Hirofumi MZ         }
2185d5cc578SKatayama Hirofumi MZ     }
2195d5cc578SKatayama Hirofumi MZ }
2205d5cc578SKatayama Hirofumi MZ 
221bbe5fd52SKatayama Hirofumi MZ PIMEHOTKEY
222bbe5fd52SKatayama Hirofumi MZ IntGetImeHotKeyByKey(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, UINT uVirtualKey)
223bbe5fd52SKatayama Hirofumi MZ {
224bbe5fd52SKatayama Hirofumi MZ     PIMEHOTKEY pNode, ret = NULL;
225bbe5fd52SKatayama Hirofumi MZ     PTHREADINFO pti = GetW32ThreadInfo();
226bbe5fd52SKatayama Hirofumi MZ     LANGID LangId;
227bbe5fd52SKatayama Hirofumi MZ     HKL hKL = IntGetActiveKeyboardLayout();
228bbe5fd52SKatayama Hirofumi MZ     BOOL fKorean = (PRIMARYLANGID(LOWORD(hKL)) == LANG_KOREAN);
229bbe5fd52SKatayama Hirofumi MZ     UINT nScore, nMaxScore = 0;
230bbe5fd52SKatayama Hirofumi MZ 
231bbe5fd52SKatayama Hirofumi MZ     for (pNode = pList; pNode; pNode = pNode->pNext)
232bbe5fd52SKatayama Hirofumi MZ     {
233bbe5fd52SKatayama Hirofumi MZ         if (pNode->uVirtualKey != uVirtualKey)
234bbe5fd52SKatayama Hirofumi MZ             continue;
235bbe5fd52SKatayama Hirofumi MZ 
236bbe5fd52SKatayama Hirofumi MZ         if ((pNode->uModifiers & MOD_IGNORE_ALL_MODIFIER))
237bbe5fd52SKatayama Hirofumi MZ         {
238bbe5fd52SKatayama Hirofumi MZ             ;
239bbe5fd52SKatayama Hirofumi MZ         }
240bbe5fd52SKatayama Hirofumi MZ         else if ((pNode->uModifiers & MOD_KEYS) != uModKeys)
241bbe5fd52SKatayama Hirofumi MZ         {
242bbe5fd52SKatayama Hirofumi MZ             continue;
243bbe5fd52SKatayama Hirofumi MZ         }
244bbe5fd52SKatayama Hirofumi MZ         else if ((pNode->uModifiers & uLeftRight) ||
245bbe5fd52SKatayama Hirofumi MZ                  (pNode->uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
246bbe5fd52SKatayama Hirofumi MZ         {
247bbe5fd52SKatayama Hirofumi MZ             ;
248bbe5fd52SKatayama Hirofumi MZ         }
249bbe5fd52SKatayama Hirofumi MZ         else
250bbe5fd52SKatayama Hirofumi MZ         {
251bbe5fd52SKatayama Hirofumi MZ             continue;
252bbe5fd52SKatayama Hirofumi MZ         }
253bbe5fd52SKatayama Hirofumi MZ 
254bbe5fd52SKatayama Hirofumi MZ         LangId = IntGetImeHotKeyLangId(pNode->dwHotKeyId);
255bbe5fd52SKatayama Hirofumi MZ         nScore = IntGetImeHotKeyLanguageScore(hKL, LangId);
256bbe5fd52SKatayama Hirofumi MZ         if (nScore >= 3)
257bbe5fd52SKatayama Hirofumi MZ             return pNode;
258bbe5fd52SKatayama Hirofumi MZ 
259bbe5fd52SKatayama Hirofumi MZ         if (fKorean)
260bbe5fd52SKatayama Hirofumi MZ             continue;
261bbe5fd52SKatayama Hirofumi MZ 
262bbe5fd52SKatayama Hirofumi MZ         if (nScore == 0)
263bbe5fd52SKatayama Hirofumi MZ         {
264bbe5fd52SKatayama Hirofumi MZ             if (pNode->dwHotKeyId == IME_CHOTKEY_IME_NONIME_TOGGLE ||
265bbe5fd52SKatayama Hirofumi MZ                 pNode->dwHotKeyId == IME_THOTKEY_IME_NONIME_TOGGLE)
266bbe5fd52SKatayama Hirofumi MZ             {
267bbe5fd52SKatayama Hirofumi MZ                 if (LOWORD(pti->hklPrev) == LangId)
268bbe5fd52SKatayama Hirofumi MZ                     return pNode;
269bbe5fd52SKatayama Hirofumi MZ             }
270bbe5fd52SKatayama Hirofumi MZ         }
271bbe5fd52SKatayama Hirofumi MZ 
272bbe5fd52SKatayama Hirofumi MZ         if (nMaxScore < nScore)
273bbe5fd52SKatayama Hirofumi MZ         {
274bbe5fd52SKatayama Hirofumi MZ             nMaxScore = nScore;
275bbe5fd52SKatayama Hirofumi MZ             ret = pNode;
276bbe5fd52SKatayama Hirofumi MZ         }
277bbe5fd52SKatayama Hirofumi MZ     }
278bbe5fd52SKatayama Hirofumi MZ 
279bbe5fd52SKatayama Hirofumi MZ     return ret;
280bbe5fd52SKatayama Hirofumi MZ }
281bbe5fd52SKatayama Hirofumi MZ 
282bbe5fd52SKatayama Hirofumi MZ PIMEHOTKEY IntCheckImeHotKey(PUSER_MESSAGE_QUEUE MessageQueue, UINT uVirtualKey, LPARAM lParam)
283bbe5fd52SKatayama Hirofumi MZ {
284bbe5fd52SKatayama Hirofumi MZ     PIMEHOTKEY pHotKey;
285bbe5fd52SKatayama Hirofumi MZ     UINT uModifiers;
286bbe5fd52SKatayama Hirofumi MZ     BOOL bKeyUp = (lParam & 0x80000000);
287bbe5fd52SKatayama Hirofumi MZ     const BYTE *KeyState = MessageQueue->afKeyState;
288bbe5fd52SKatayama Hirofumi MZ     static UINT s_uKeyUpVKey = 0;
289bbe5fd52SKatayama Hirofumi MZ 
290bbe5fd52SKatayama Hirofumi MZ     if (bKeyUp)
291bbe5fd52SKatayama Hirofumi MZ     {
292bbe5fd52SKatayama Hirofumi MZ         if (s_uKeyUpVKey != uVirtualKey)
293bbe5fd52SKatayama Hirofumi MZ         {
294bbe5fd52SKatayama Hirofumi MZ             s_uKeyUpVKey = 0;
295bbe5fd52SKatayama Hirofumi MZ             return NULL;
296bbe5fd52SKatayama Hirofumi MZ         }
297bbe5fd52SKatayama Hirofumi MZ 
298bbe5fd52SKatayama Hirofumi MZ         s_uKeyUpVKey = 0;
299bbe5fd52SKatayama Hirofumi MZ     }
300bbe5fd52SKatayama Hirofumi MZ 
301bbe5fd52SKatayama Hirofumi MZ     uModifiers = 0;
302bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_LSHIFT))   uModifiers |= (MOD_SHIFT | MOD_LEFT);
303bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_RSHIFT))   uModifiers |= (MOD_SHIFT | MOD_RIGHT);
304bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_LCONTROL)) uModifiers |= (MOD_CONTROL | MOD_LEFT);
305bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_RCONTROL)) uModifiers |= (MOD_CONTROL | MOD_RIGHT);
306bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_LMENU))    uModifiers |= (MOD_ALT | MOD_LEFT);
307bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_RMENU))    uModifiers |= (MOD_ALT | MOD_RIGHT);
308bbe5fd52SKatayama Hirofumi MZ 
309bbe5fd52SKatayama Hirofumi MZ     pHotKey = IntGetImeHotKeyByKey(gpImeHotKeyList,
310bbe5fd52SKatayama Hirofumi MZ                                    (uModifiers & MOD_KEYS),
311bbe5fd52SKatayama Hirofumi MZ                                    (uModifiers & MOD_LEFT_RIGHT),
312bbe5fd52SKatayama Hirofumi MZ                                    uVirtualKey);
313bbe5fd52SKatayama Hirofumi MZ     if (pHotKey)
314bbe5fd52SKatayama Hirofumi MZ     {
315bbe5fd52SKatayama Hirofumi MZ         if (bKeyUp)
316bbe5fd52SKatayama Hirofumi MZ         {
317bbe5fd52SKatayama Hirofumi MZ             if (pHotKey->uModifiers & MOD_ON_KEYUP)
318bbe5fd52SKatayama Hirofumi MZ                 return pHotKey;
319bbe5fd52SKatayama Hirofumi MZ         }
320bbe5fd52SKatayama Hirofumi MZ         else
321bbe5fd52SKatayama Hirofumi MZ         {
322bbe5fd52SKatayama Hirofumi MZ             if (pHotKey->uModifiers & MOD_ON_KEYUP)
323bbe5fd52SKatayama Hirofumi MZ                 s_uKeyUpVKey = uVirtualKey;
324bbe5fd52SKatayama Hirofumi MZ             else
325bbe5fd52SKatayama Hirofumi MZ                 return pHotKey;
326bbe5fd52SKatayama Hirofumi MZ         }
327bbe5fd52SKatayama Hirofumi MZ     }
328bbe5fd52SKatayama Hirofumi MZ 
329bbe5fd52SKatayama Hirofumi MZ     return NULL;
330bbe5fd52SKatayama Hirofumi MZ }
331bbe5fd52SKatayama Hirofumi MZ 
3325d5cc578SKatayama Hirofumi MZ VOID FASTCALL IntFreeImeHotKeys(VOID)
3335d5cc578SKatayama Hirofumi MZ {
3345d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode, pNext;
3355d5cc578SKatayama Hirofumi MZ     for (pNode = gpImeHotKeyList; pNode; pNode = pNext)
3365d5cc578SKatayama Hirofumi MZ     {
3375d5cc578SKatayama Hirofumi MZ         pNext = pNode->pNext;
3385d5cc578SKatayama Hirofumi MZ         ExFreePoolWithTag(pNode, USERTAG_IMEHOTKEY);
3395d5cc578SKatayama Hirofumi MZ     }
3405d5cc578SKatayama Hirofumi MZ     gpImeHotKeyList = NULL;
3415d5cc578SKatayama Hirofumi MZ }
3425d5cc578SKatayama Hirofumi MZ 
3435d5cc578SKatayama Hirofumi MZ static BOOL APIENTRY
3445d5cc578SKatayama Hirofumi MZ IntSetImeHotKey(DWORD dwHotKeyId, UINT uModifiers, UINT uVirtualKey, HKL hKL, DWORD dwAction)
3455d5cc578SKatayama Hirofumi MZ {
3465d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
3475d5cc578SKatayama Hirofumi MZ     LANGID LangId;
3485d5cc578SKatayama Hirofumi MZ 
3495d5cc578SKatayama Hirofumi MZ     switch (dwAction)
3505d5cc578SKatayama Hirofumi MZ     {
3515d5cc578SKatayama Hirofumi MZ         case SETIMEHOTKEY_DELETE:
3525d5cc578SKatayama Hirofumi MZ             pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId);
3535d5cc578SKatayama Hirofumi MZ             if (!pNode)
354b5c9d532SKatayama Hirofumi MZ             {
355b5c9d532SKatayama Hirofumi MZ                 ERR("dwHotKeyId: 0x%lX\n", dwHotKeyId);
3565d5cc578SKatayama Hirofumi MZ                 return FALSE;
357b5c9d532SKatayama Hirofumi MZ             }
3585d5cc578SKatayama Hirofumi MZ 
3595d5cc578SKatayama Hirofumi MZ             IntDeleteImeHotKey(&gpImeHotKeyList, pNode);
3605d5cc578SKatayama Hirofumi MZ             return TRUE;
3615d5cc578SKatayama Hirofumi MZ 
3625d5cc578SKatayama Hirofumi MZ         case SETIMEHOTKEY_ADD:
3635d5cc578SKatayama Hirofumi MZ             if (uVirtualKey == VK_PACKET)
3645d5cc578SKatayama Hirofumi MZ                 return FALSE;
3655d5cc578SKatayama Hirofumi MZ 
3665d5cc578SKatayama Hirofumi MZ             LangId = IntGetImeHotKeyLangId(dwHotKeyId);
3675d5cc578SKatayama Hirofumi MZ             if (LangId == LANGID_KOREAN)
3685d5cc578SKatayama Hirofumi MZ                 return FALSE;
3695d5cc578SKatayama Hirofumi MZ 
3705d5cc578SKatayama Hirofumi MZ             pNode = IntGetImeHotKeyByKeyAndLang(gpImeHotKeyList,
3715d5cc578SKatayama Hirofumi MZ                                                 (uModifiers & MOD_KEYS),
3725d5cc578SKatayama Hirofumi MZ                                                 (uModifiers & MOD_LEFT_RIGHT),
3735d5cc578SKatayama Hirofumi MZ                                                 uVirtualKey, LangId);
3745d5cc578SKatayama Hirofumi MZ             if (!pNode)
3755d5cc578SKatayama Hirofumi MZ                 pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId);
3765d5cc578SKatayama Hirofumi MZ 
3775d5cc578SKatayama Hirofumi MZ             if (pNode)
3785d5cc578SKatayama Hirofumi MZ             {
3795d5cc578SKatayama Hirofumi MZ                 pNode->uModifiers = uModifiers;
3805d5cc578SKatayama Hirofumi MZ                 pNode->uVirtualKey = uVirtualKey;
3815d5cc578SKatayama Hirofumi MZ                 pNode->hKL = hKL;
3825d5cc578SKatayama Hirofumi MZ                 return TRUE;
3835d5cc578SKatayama Hirofumi MZ             }
3845d5cc578SKatayama Hirofumi MZ 
3855d5cc578SKatayama Hirofumi MZ             pNode = ExAllocatePoolWithTag(PagedPool, sizeof(IMEHOTKEY), USERTAG_IMEHOTKEY);
3865d5cc578SKatayama Hirofumi MZ             if (!pNode)
3875d5cc578SKatayama Hirofumi MZ                 return FALSE;
3885d5cc578SKatayama Hirofumi MZ 
3895d5cc578SKatayama Hirofumi MZ             pNode->pNext = NULL;
3905d5cc578SKatayama Hirofumi MZ             pNode->dwHotKeyId = dwHotKeyId;
3915d5cc578SKatayama Hirofumi MZ             pNode->uModifiers = uModifiers;
3925d5cc578SKatayama Hirofumi MZ             pNode->uVirtualKey = uVirtualKey;
3935d5cc578SKatayama Hirofumi MZ             pNode->hKL = hKL;
3945d5cc578SKatayama Hirofumi MZ             IntAddImeHotKey(&gpImeHotKeyList, pNode);
3955d5cc578SKatayama Hirofumi MZ             return TRUE;
3965d5cc578SKatayama Hirofumi MZ 
3975d5cc578SKatayama Hirofumi MZ         case SETIMEHOTKEY_DELETEALL:
3985d5cc578SKatayama Hirofumi MZ             IntFreeImeHotKeys();
3995d5cc578SKatayama Hirofumi MZ             return TRUE;
4005d5cc578SKatayama Hirofumi MZ 
4015d5cc578SKatayama Hirofumi MZ         default:
4025d5cc578SKatayama Hirofumi MZ             return FALSE;
4035d5cc578SKatayama Hirofumi MZ     }
4045d5cc578SKatayama Hirofumi MZ }
4055d5cc578SKatayama Hirofumi MZ 
4065d5cc578SKatayama Hirofumi MZ BOOL NTAPI
4075d5cc578SKatayama Hirofumi MZ NtUserGetImeHotKey(DWORD dwHotKeyId, LPUINT lpuModifiers, LPUINT lpuVirtualKey, LPHKL lphKL)
4085d5cc578SKatayama Hirofumi MZ {
4095d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode = NULL;
4105d5cc578SKatayama Hirofumi MZ 
4115d5cc578SKatayama Hirofumi MZ     UserEnterExclusive();
4125d5cc578SKatayama Hirofumi MZ 
4135d5cc578SKatayama Hirofumi MZ     _SEH2_TRY
4145d5cc578SKatayama Hirofumi MZ     {
4155d5cc578SKatayama Hirofumi MZ         ProbeForWrite(lpuModifiers, sizeof(UINT), 1);
4165d5cc578SKatayama Hirofumi MZ         ProbeForWrite(lpuVirtualKey, sizeof(UINT), 1);
4175d5cc578SKatayama Hirofumi MZ         if (lphKL)
4185d5cc578SKatayama Hirofumi MZ             ProbeForWrite(lphKL, sizeof(HKL), 1);
4195d5cc578SKatayama Hirofumi MZ     }
4205d5cc578SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
4215d5cc578SKatayama Hirofumi MZ     {
4225d5cc578SKatayama Hirofumi MZ         goto Quit;
4235d5cc578SKatayama Hirofumi MZ     }
4245d5cc578SKatayama Hirofumi MZ     _SEH2_END;
4255d5cc578SKatayama Hirofumi MZ 
4265d5cc578SKatayama Hirofumi MZ     pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId);
4275d5cc578SKatayama Hirofumi MZ     if (!pNode)
4285d5cc578SKatayama Hirofumi MZ         goto Quit;
4295d5cc578SKatayama Hirofumi MZ 
4305d5cc578SKatayama Hirofumi MZ     _SEH2_TRY
4315d5cc578SKatayama Hirofumi MZ     {
4325d5cc578SKatayama Hirofumi MZ         *lpuModifiers = pNode->uModifiers;
4335d5cc578SKatayama Hirofumi MZ         *lpuVirtualKey = pNode->uVirtualKey;
4345d5cc578SKatayama Hirofumi MZ         if (lphKL)
4355d5cc578SKatayama Hirofumi MZ             *lphKL = pNode->hKL;
4365d5cc578SKatayama Hirofumi MZ     }
4375d5cc578SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
4385d5cc578SKatayama Hirofumi MZ     {
4395d5cc578SKatayama Hirofumi MZ         pNode = NULL;
4405d5cc578SKatayama Hirofumi MZ     }
4415d5cc578SKatayama Hirofumi MZ     _SEH2_END;
4425d5cc578SKatayama Hirofumi MZ 
4435d5cc578SKatayama Hirofumi MZ Quit:
4445d5cc578SKatayama Hirofumi MZ     UserLeave();
4455d5cc578SKatayama Hirofumi MZ     return !!pNode;
4465d5cc578SKatayama Hirofumi MZ }
4475d5cc578SKatayama Hirofumi MZ 
4485d5cc578SKatayama Hirofumi MZ BOOL
4495d5cc578SKatayama Hirofumi MZ NTAPI
4505d5cc578SKatayama Hirofumi MZ NtUserSetImeHotKey(
4515d5cc578SKatayama Hirofumi MZ     DWORD  dwHotKeyId,
4525d5cc578SKatayama Hirofumi MZ     UINT   uModifiers,
4535d5cc578SKatayama Hirofumi MZ     UINT   uVirtualKey,
4545d5cc578SKatayama Hirofumi MZ     HKL    hKL,
4555d5cc578SKatayama Hirofumi MZ     DWORD  dwAction)
4565d5cc578SKatayama Hirofumi MZ {
4575d5cc578SKatayama Hirofumi MZ     BOOL ret;
4585d5cc578SKatayama Hirofumi MZ     UserEnterExclusive();
4595d5cc578SKatayama Hirofumi MZ     ret = IntSetImeHotKey(dwHotKeyId, uModifiers, uVirtualKey, hKL, dwAction);
4605d5cc578SKatayama Hirofumi MZ     UserLeave();
4615d5cc578SKatayama Hirofumi MZ     return ret;
4625d5cc578SKatayama Hirofumi MZ }
4635d5cc578SKatayama Hirofumi MZ 
464bbe5fd52SKatayama Hirofumi MZ DWORD
465bbe5fd52SKatayama Hirofumi MZ NTAPI
466bbe5fd52SKatayama Hirofumi MZ NtUserCheckImeHotKey(UINT uVirtualKey, LPARAM lParam)
467bbe5fd52SKatayama Hirofumi MZ {
468bbe5fd52SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
469bbe5fd52SKatayama Hirofumi MZ     DWORD ret = INVALID_HOTKEY;
470bbe5fd52SKatayama Hirofumi MZ 
471bbe5fd52SKatayama Hirofumi MZ     UserEnterExclusive();
472bbe5fd52SKatayama Hirofumi MZ 
473bbe5fd52SKatayama Hirofumi MZ     if (!gpqForeground || !IS_IMM_MODE())
474bbe5fd52SKatayama Hirofumi MZ         goto Quit;
475bbe5fd52SKatayama Hirofumi MZ 
476bbe5fd52SKatayama Hirofumi MZ     pNode = IntCheckImeHotKey(gpqForeground, uVirtualKey, lParam);
477bbe5fd52SKatayama Hirofumi MZ     if (pNode)
478bbe5fd52SKatayama Hirofumi MZ         ret = pNode->dwHotKeyId;
479bbe5fd52SKatayama Hirofumi MZ 
480bbe5fd52SKatayama Hirofumi MZ Quit:
481bbe5fd52SKatayama Hirofumi MZ     UserLeave();
482bbe5fd52SKatayama Hirofumi MZ     return ret;
483bbe5fd52SKatayama Hirofumi MZ }
484bbe5fd52SKatayama Hirofumi MZ 
4850519ae0aSKatayama Hirofumi MZ PWND FASTCALL IntGetTopLevelWindow(PWND pwnd)
4860519ae0aSKatayama Hirofumi MZ {
4870519ae0aSKatayama Hirofumi MZ     if (!pwnd)
4880519ae0aSKatayama Hirofumi MZ         return NULL;
4890519ae0aSKatayama Hirofumi MZ 
4900519ae0aSKatayama Hirofumi MZ     while (pwnd->style & WS_CHILD)
4910519ae0aSKatayama Hirofumi MZ         pwnd = pwnd->spwndParent;
4920519ae0aSKatayama Hirofumi MZ 
4930519ae0aSKatayama Hirofumi MZ     return pwnd;
4940519ae0aSKatayama Hirofumi MZ }
4950519ae0aSKatayama Hirofumi MZ 
4961bc9dda5SKatayama Hirofumi MZ HIMC FASTCALL IntAssociateInputContext(PWND pWnd, PIMC pImc)
4971bc9dda5SKatayama Hirofumi MZ {
4981bc9dda5SKatayama Hirofumi MZ     HIMC hOldImc = pWnd->hImc;
4991bc9dda5SKatayama Hirofumi MZ     pWnd->hImc = (pImc ? UserHMGetHandle(pImc) : NULL);
5001bc9dda5SKatayama Hirofumi MZ     return hOldImc;
5011bc9dda5SKatayama Hirofumi MZ }
5021bc9dda5SKatayama Hirofumi MZ 
503470aa276SKatayama Hirofumi MZ DWORD
504e52ce89bSKatayama Hirofumi MZ NTAPI
505470aa276SKatayama Hirofumi MZ NtUserSetThreadLayoutHandles(HKL hNewKL, HKL hOldKL)
506470aa276SKatayama Hirofumi MZ {
507470aa276SKatayama Hirofumi MZ     PTHREADINFO pti;
508470aa276SKatayama Hirofumi MZ     PKL pOldKL, pNewKL;
509470aa276SKatayama Hirofumi MZ 
510470aa276SKatayama Hirofumi MZ     UserEnterExclusive();
511470aa276SKatayama Hirofumi MZ 
512470aa276SKatayama Hirofumi MZ     pti = GetW32ThreadInfo();
513470aa276SKatayama Hirofumi MZ     pOldKL = pti->KeyboardLayout;
514470aa276SKatayama Hirofumi MZ     if (pOldKL && pOldKL->hkl != hOldKL)
515470aa276SKatayama Hirofumi MZ         goto Quit;
516470aa276SKatayama Hirofumi MZ 
517470aa276SKatayama Hirofumi MZ     pNewKL = UserHklToKbl(hNewKL);
518470aa276SKatayama Hirofumi MZ     if (!pNewKL)
519470aa276SKatayama Hirofumi MZ         goto Quit;
520470aa276SKatayama Hirofumi MZ 
521470aa276SKatayama Hirofumi MZ     if (IS_IME_HKL(hNewKL) != IS_IME_HKL(hOldKL))
522470aa276SKatayama Hirofumi MZ         pti->hklPrev = hOldKL;
523470aa276SKatayama Hirofumi MZ 
524470aa276SKatayama Hirofumi MZ     pti->KeyboardLayout = pNewKL;
525470aa276SKatayama Hirofumi MZ 
526470aa276SKatayama Hirofumi MZ Quit:
527470aa276SKatayama Hirofumi MZ     UserLeave();
528470aa276SKatayama Hirofumi MZ     return 0;
529470aa276SKatayama Hirofumi MZ }
530470aa276SKatayama Hirofumi MZ 
531ce6da820SKatayama Hirofumi MZ DWORD FASTCALL UserBuildHimcList(PTHREADINFO pti, DWORD dwCount, HIMC *phList)
532ce6da820SKatayama Hirofumi MZ {
533ce6da820SKatayama Hirofumi MZ     PIMC pIMC;
534ce6da820SKatayama Hirofumi MZ     DWORD dwRealCount = 0;
535ce6da820SKatayama Hirofumi MZ 
536ce6da820SKatayama Hirofumi MZ     if (pti)
537ce6da820SKatayama Hirofumi MZ     {
538ce6da820SKatayama Hirofumi MZ         for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
539ce6da820SKatayama Hirofumi MZ         {
540ce6da820SKatayama Hirofumi MZ             if (dwRealCount < dwCount)
541ce6da820SKatayama Hirofumi MZ                 phList[dwRealCount] = UserHMGetHandle(pIMC);
542ce6da820SKatayama Hirofumi MZ 
543ce6da820SKatayama Hirofumi MZ             ++dwRealCount;
544ce6da820SKatayama Hirofumi MZ         }
545ce6da820SKatayama Hirofumi MZ     }
546ce6da820SKatayama Hirofumi MZ     else
547ce6da820SKatayama Hirofumi MZ     {
548ce6da820SKatayama Hirofumi MZ         for (pti = GetW32ThreadInfo()->ppi->ptiList; pti; pti = pti->ptiSibling)
549ce6da820SKatayama Hirofumi MZ         {
550ce6da820SKatayama Hirofumi MZ             for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
551ce6da820SKatayama Hirofumi MZ             {
552ce6da820SKatayama Hirofumi MZ                 if (dwRealCount < dwCount)
553ce6da820SKatayama Hirofumi MZ                     phList[dwRealCount] = UserHMGetHandle(pIMC);
554ce6da820SKatayama Hirofumi MZ 
555ce6da820SKatayama Hirofumi MZ                 ++dwRealCount;
556ce6da820SKatayama Hirofumi MZ             }
557ce6da820SKatayama Hirofumi MZ         }
558ce6da820SKatayama Hirofumi MZ     }
559ce6da820SKatayama Hirofumi MZ 
560ce6da820SKatayama Hirofumi MZ     return dwRealCount;
561ce6da820SKatayama Hirofumi MZ }
562ce6da820SKatayama Hirofumi MZ 
563c2c66affSColin Finck UINT FASTCALL
564b5c9d532SKatayama Hirofumi MZ IntImmProcessKey(PUSER_MESSAGE_QUEUE MessageQueue, PWND pWnd, UINT uMsg,
565b5c9d532SKatayama Hirofumi MZ                  WPARAM wParam, LPARAM lParam)
566c2c66affSColin Finck {
567b5c9d532SKatayama Hirofumi MZ     UINT uVirtualKey, ret = 0;
568b5c9d532SKatayama Hirofumi MZ     DWORD dwHotKeyId;
569b5c9d532SKatayama Hirofumi MZ     PKL pKL;
570b5c9d532SKatayama Hirofumi MZ     PIMC pIMC = NULL;
571b5c9d532SKatayama Hirofumi MZ     PIMEHOTKEY pImeHotKey;
572b5c9d532SKatayama Hirofumi MZ     HKL hKL;
573b5c9d532SKatayama Hirofumi MZ     HWND hWnd;
574c2c66affSColin Finck 
575c2c66affSColin Finck     ASSERT_REFS_CO(pWnd);
576c2c66affSColin Finck 
577b5c9d532SKatayama Hirofumi MZ     switch (uMsg)
578c2c66affSColin Finck     {
579b5c9d532SKatayama Hirofumi MZ         case WM_KEYDOWN:
580b5c9d532SKatayama Hirofumi MZ         case WM_KEYUP:
581b5c9d532SKatayama Hirofumi MZ         case WM_SYSKEYDOWN:
582b5c9d532SKatayama Hirofumi MZ         case WM_SYSKEYUP:
583b5c9d532SKatayama Hirofumi MZ             break;
584b5c9d532SKatayama Hirofumi MZ 
585b5c9d532SKatayama Hirofumi MZ         default:
586c2c66affSColin Finck             return 0;
587c2c66affSColin Finck     }
588c2c66affSColin Finck 
589b5c9d532SKatayama Hirofumi MZ     hWnd = UserHMGetHandle(pWnd);
590b5c9d532SKatayama Hirofumi MZ     pKL = pWnd->head.pti->KeyboardLayout;
591b5c9d532SKatayama Hirofumi MZ     if (!pKL)
592b5c9d532SKatayama Hirofumi MZ         return 0;
593b5c9d532SKatayama Hirofumi MZ 
594b5c9d532SKatayama Hirofumi MZ     uVirtualKey = LOBYTE(wParam);
595b5c9d532SKatayama Hirofumi MZ     pImeHotKey = IntCheckImeHotKey(MessageQueue, uVirtualKey, lParam);
596b5c9d532SKatayama Hirofumi MZ     if (pImeHotKey)
597b5c9d532SKatayama Hirofumi MZ     {
598b5c9d532SKatayama Hirofumi MZ         dwHotKeyId = pImeHotKey->dwHotKeyId;
599b5c9d532SKatayama Hirofumi MZ         hKL = pImeHotKey->hKL;
600b5c9d532SKatayama Hirofumi MZ     }
601b5c9d532SKatayama Hirofumi MZ     else
602b5c9d532SKatayama Hirofumi MZ     {
603b5c9d532SKatayama Hirofumi MZ         dwHotKeyId = INVALID_HOTKEY;
604b5c9d532SKatayama Hirofumi MZ         hKL = NULL;
605b5c9d532SKatayama Hirofumi MZ     }
606b5c9d532SKatayama Hirofumi MZ 
607b5c9d532SKatayama Hirofumi MZ     if (IME_HOTKEY_DSWITCH_FIRST <= dwHotKeyId && dwHotKeyId <= IME_HOTKEY_DSWITCH_LAST)
608b5c9d532SKatayama Hirofumi MZ     {
609b5c9d532SKatayama Hirofumi MZ         if (pKL->hkl != hKL)
610b5c9d532SKatayama Hirofumi MZ         {
611b5c9d532SKatayama Hirofumi MZ             UserPostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST,
612b5c9d532SKatayama Hirofumi MZ                             ((pKL->dwFontSigs & gSystemFS) ? INPUTLANGCHANGE_SYSCHARSET : 0),
613b5c9d532SKatayama Hirofumi MZ                             (LPARAM)hKL);
614b5c9d532SKatayama Hirofumi MZ         }
615b5c9d532SKatayama Hirofumi MZ 
616b5c9d532SKatayama Hirofumi MZ         if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000)
617b5c9d532SKatayama Hirofumi MZ             return 0;
618b5c9d532SKatayama Hirofumi MZ 
619b5c9d532SKatayama Hirofumi MZ         return IPHK_HOTKEY;
620b5c9d532SKatayama Hirofumi MZ     }
621b5c9d532SKatayama Hirofumi MZ 
622b5c9d532SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
623b5c9d532SKatayama Hirofumi MZ         return 0;
624b5c9d532SKatayama Hirofumi MZ 
625b5c9d532SKatayama Hirofumi MZ     if (dwHotKeyId == INVALID_HOTKEY)
626b5c9d532SKatayama Hirofumi MZ     {
627b5c9d532SKatayama Hirofumi MZ         if (!pKL->piiex)
628b5c9d532SKatayama Hirofumi MZ             return 0;
629b5c9d532SKatayama Hirofumi MZ 
630b5c9d532SKatayama Hirofumi MZ         if (pWnd->hImc)
631b5c9d532SKatayama Hirofumi MZ             pIMC = UserGetObject(gHandleTable, pWnd->hImc, TYPE_INPUTCONTEXT);
632b5c9d532SKatayama Hirofumi MZ         if (!pIMC)
633b5c9d532SKatayama Hirofumi MZ             return 0;
634b5c9d532SKatayama Hirofumi MZ 
635b5c9d532SKatayama Hirofumi MZ         if ((lParam & 0x80000000) &&
636b5c9d532SKatayama Hirofumi MZ             (pKL->piiex->ImeInfo.fdwProperty & IME_PROP_IGNORE_UPKEYS))
637b5c9d532SKatayama Hirofumi MZ         {
638b5c9d532SKatayama Hirofumi MZ             return 0;
639b5c9d532SKatayama Hirofumi MZ         }
640b5c9d532SKatayama Hirofumi MZ 
641b5c9d532SKatayama Hirofumi MZ         switch (uVirtualKey)
642b5c9d532SKatayama Hirofumi MZ         {
643b5c9d532SKatayama Hirofumi MZ             case VK_DBE_CODEINPUT:
644b5c9d532SKatayama Hirofumi MZ             case VK_DBE_ENTERCONFIGMODE:
645b5c9d532SKatayama Hirofumi MZ             case VK_DBE_ENTERWORDREGISTERMODE:
646b5c9d532SKatayama Hirofumi MZ             case VK_DBE_HIRAGANA:
647b5c9d532SKatayama Hirofumi MZ             case VK_DBE_KATAKANA:
648b5c9d532SKatayama Hirofumi MZ             case VK_DBE_NOCODEINPUT:
649b5c9d532SKatayama Hirofumi MZ             case VK_DBE_NOROMAN:
650b5c9d532SKatayama Hirofumi MZ             case VK_DBE_ROMAN:
651b5c9d532SKatayama Hirofumi MZ                 break;
652b5c9d532SKatayama Hirofumi MZ 
653b5c9d532SKatayama Hirofumi MZ             default:
654b5c9d532SKatayama Hirofumi MZ             {
655b5c9d532SKatayama Hirofumi MZ                 if (uMsg == WM_SYSKEYDOWN || uMsg == WM_SYSKEYUP)
656b5c9d532SKatayama Hirofumi MZ                 {
657b5c9d532SKatayama Hirofumi MZ                     if (uVirtualKey != VK_MENU && uVirtualKey != VK_F10)
658b5c9d532SKatayama Hirofumi MZ                         return 0;
659b5c9d532SKatayama Hirofumi MZ                 }
660b5c9d532SKatayama Hirofumi MZ 
661b5c9d532SKatayama Hirofumi MZ                 if (!(pKL->piiex->ImeInfo.fdwProperty & IME_PROP_NEED_ALTKEY))
662b5c9d532SKatayama Hirofumi MZ                 {
663b5c9d532SKatayama Hirofumi MZ                     if (uVirtualKey == VK_MENU || (lParam & 0x20000000))
664b5c9d532SKatayama Hirofumi MZ                         return 0;
665b5c9d532SKatayama Hirofumi MZ                 }
666b5c9d532SKatayama Hirofumi MZ                 break;
667b5c9d532SKatayama Hirofumi MZ             }
668b5c9d532SKatayama Hirofumi MZ         }
669b5c9d532SKatayama Hirofumi MZ     }
670b5c9d532SKatayama Hirofumi MZ 
671b5c9d532SKatayama Hirofumi MZ     if (LOBYTE(uVirtualKey) == VK_PACKET)
672b5c9d532SKatayama Hirofumi MZ         uVirtualKey = MAKELONG(wParam, GetW32ThreadInfo()->wchInjected);
673b5c9d532SKatayama Hirofumi MZ 
674b5c9d532SKatayama Hirofumi MZ     ret = co_IntImmProcessKey(hWnd, pKL->hkl, uVirtualKey, lParam, dwHotKeyId);
675b5c9d532SKatayama Hirofumi MZ 
676b5c9d532SKatayama Hirofumi MZ     if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000)
677b5c9d532SKatayama Hirofumi MZ         ret &= ~IPHK_HOTKEY;
678b5c9d532SKatayama Hirofumi MZ 
679b5c9d532SKatayama Hirofumi MZ     return ret;
680b5c9d532SKatayama Hirofumi MZ }
681b5c9d532SKatayama Hirofumi MZ 
682ce6da820SKatayama Hirofumi MZ NTSTATUS
683e52ce89bSKatayama Hirofumi MZ NTAPI
684ce6da820SKatayama Hirofumi MZ NtUserBuildHimcList(DWORD dwThreadId, DWORD dwCount, HIMC *phList, LPDWORD pdwCount)
685ce6da820SKatayama Hirofumi MZ {
686ce6da820SKatayama Hirofumi MZ     NTSTATUS ret = STATUS_UNSUCCESSFUL;
687ce6da820SKatayama Hirofumi MZ     DWORD dwRealCount;
688ce6da820SKatayama Hirofumi MZ     PTHREADINFO pti;
689ce6da820SKatayama Hirofumi MZ 
690ce6da820SKatayama Hirofumi MZ     UserEnterExclusive();
691ce6da820SKatayama Hirofumi MZ 
692ce6da820SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
693ce6da820SKatayama Hirofumi MZ     {
694b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
695ce6da820SKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
696ce6da820SKatayama Hirofumi MZ         goto Quit;
697ce6da820SKatayama Hirofumi MZ     }
698ce6da820SKatayama Hirofumi MZ 
699ce6da820SKatayama Hirofumi MZ     if (dwThreadId == 0)
700ce6da820SKatayama Hirofumi MZ     {
701ce6da820SKatayama Hirofumi MZ         pti = GetW32ThreadInfo();
702ce6da820SKatayama Hirofumi MZ     }
703ce6da820SKatayama Hirofumi MZ     else if (dwThreadId == INVALID_THREAD_ID)
704ce6da820SKatayama Hirofumi MZ     {
705ce6da820SKatayama Hirofumi MZ         pti = NULL;
706ce6da820SKatayama Hirofumi MZ     }
707ce6da820SKatayama Hirofumi MZ     else
708ce6da820SKatayama Hirofumi MZ     {
709ce6da820SKatayama Hirofumi MZ         pti = IntTID2PTI(UlongToHandle(dwThreadId));
710ce6da820SKatayama Hirofumi MZ         if (!pti || !pti->rpdesk)
711ce6da820SKatayama Hirofumi MZ             goto Quit;
712ce6da820SKatayama Hirofumi MZ     }
713ce6da820SKatayama Hirofumi MZ 
714ce6da820SKatayama Hirofumi MZ     _SEH2_TRY
715ce6da820SKatayama Hirofumi MZ     {
716ce6da820SKatayama Hirofumi MZ         ProbeForWrite(phList, dwCount * sizeof(HIMC), 1);
717ce6da820SKatayama Hirofumi MZ         ProbeForWrite(pdwCount, sizeof(DWORD), 1);
718ce6da820SKatayama Hirofumi MZ         *pdwCount = dwRealCount = UserBuildHimcList(pti, dwCount, phList);
719ce6da820SKatayama Hirofumi MZ     }
720ce6da820SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
721ce6da820SKatayama Hirofumi MZ     {
722ce6da820SKatayama Hirofumi MZ         goto Quit;
723ce6da820SKatayama Hirofumi MZ     }
724ce6da820SKatayama Hirofumi MZ     _SEH2_END;
725ce6da820SKatayama Hirofumi MZ 
726ce6da820SKatayama Hirofumi MZ     if (dwCount < dwRealCount)
727ce6da820SKatayama Hirofumi MZ         ret = STATUS_BUFFER_TOO_SMALL;
728ce6da820SKatayama Hirofumi MZ     else
729ce6da820SKatayama Hirofumi MZ         ret = STATUS_SUCCESS;
730ce6da820SKatayama Hirofumi MZ 
731ce6da820SKatayama Hirofumi MZ Quit:
732ce6da820SKatayama Hirofumi MZ     UserLeave();
733ce6da820SKatayama Hirofumi MZ     return ret;
734ce6da820SKatayama Hirofumi MZ }
735ce6da820SKatayama Hirofumi MZ 
7369db44371SKatayama Hirofumi MZ static VOID FASTCALL UserSetImeConversionKeyState(PTHREADINFO pti, DWORD dwConversion)
7379db44371SKatayama Hirofumi MZ {
7389db44371SKatayama Hirofumi MZ     HKL hKL;
7399db44371SKatayama Hirofumi MZ     LANGID LangID;
7409db44371SKatayama Hirofumi MZ     LPBYTE KeyState;
7419db44371SKatayama Hirofumi MZ     BOOL bAlphaNumeric, bKatakana, bHiragana, bFullShape, bRoman, bCharCode;
7429db44371SKatayama Hirofumi MZ 
7439db44371SKatayama Hirofumi MZ     if (!pti->KeyboardLayout)
7449db44371SKatayama Hirofumi MZ         return;
7459db44371SKatayama Hirofumi MZ 
7469db44371SKatayama Hirofumi MZ     hKL = pti->KeyboardLayout->hkl;
7479db44371SKatayama Hirofumi MZ     LangID = LOWORD(hKL);
7489db44371SKatayama Hirofumi MZ     KeyState = pti->MessageQueue->afKeyState;
7499db44371SKatayama Hirofumi MZ 
7509db44371SKatayama Hirofumi MZ     switch (PRIMARYLANGID(LangID))
7519db44371SKatayama Hirofumi MZ     {
7529db44371SKatayama Hirofumi MZ         case LANG_JAPANESE:
7539db44371SKatayama Hirofumi MZ             bAlphaNumeric = !(dwConversion & IME_CMODE_NATIVE);
7549db44371SKatayama Hirofumi MZ             bKatakana = !bAlphaNumeric && (dwConversion & IME_CMODE_KATAKANA);
7559db44371SKatayama Hirofumi MZ             bHiragana = !bAlphaNumeric && !(dwConversion & IME_CMODE_KATAKANA);
7569db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
7579db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
7589db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_HIRAGANA, bHiragana);
7599db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_HIRAGANA, bHiragana);
7609db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_KATAKANA, bKatakana);
7619db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_KATAKANA, bKatakana);
7629db44371SKatayama Hirofumi MZ 
7639db44371SKatayama Hirofumi MZ             bFullShape = (dwConversion & IME_CMODE_FULLSHAPE);
7649db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_DBCSCHAR, bFullShape);
7659db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_DBCSCHAR, bFullShape);
7669db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
7679db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
7689db44371SKatayama Hirofumi MZ 
7699db44371SKatayama Hirofumi MZ             bRoman = (dwConversion & IME_CMODE_ROMAN);
7709db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_ROMAN, bRoman);
7719db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_ROMAN, bRoman);
7729db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_NOROMAN, !bRoman);
7739db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_NOROMAN, !bRoman);
7749db44371SKatayama Hirofumi MZ 
7759db44371SKatayama Hirofumi MZ             bCharCode = (dwConversion & IME_CMODE_CHARCODE);
7769db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_CODEINPUT, bCharCode);
7779db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_CODEINPUT, bCharCode);
7789db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
7799db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
7809db44371SKatayama Hirofumi MZ             break;
7819db44371SKatayama Hirofumi MZ 
7829db44371SKatayama Hirofumi MZ         case LANG_KOREAN:
7839db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_HANGUL, (dwConversion & IME_CMODE_NATIVE));
7849db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_JUNJA, (dwConversion & IME_CMODE_FULLSHAPE));
7859db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_HANJA, (dwConversion & IME_CMODE_HANJACONVERT));
7869db44371SKatayama Hirofumi MZ             break;
7879db44371SKatayama Hirofumi MZ 
7889db44371SKatayama Hirofumi MZ         default:
7899db44371SKatayama Hirofumi MZ             break;
7909db44371SKatayama Hirofumi MZ     }
7919db44371SKatayama Hirofumi MZ }
7929db44371SKatayama Hirofumi MZ 
793c2c66affSColin Finck DWORD
794e52ce89bSKatayama Hirofumi MZ NTAPI
7959adc538cSKatayama Hirofumi MZ NtUserNotifyIMEStatus(HWND hwnd, BOOL fOpen, DWORD dwConversion)
796c2c66affSColin Finck {
7979db44371SKatayama Hirofumi MZ     PWND pwnd;
7989db44371SKatayama Hirofumi MZ     PTHREADINFO pti;
7999db44371SKatayama Hirofumi MZ     HKL hKL;
8009db44371SKatayama Hirofumi MZ 
8019db44371SKatayama Hirofumi MZ     UserEnterExclusive();
8029db44371SKatayama Hirofumi MZ 
803b5c9d532SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
804b5c9d532SKatayama Hirofumi MZ     {
805b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
806b5c9d532SKatayama Hirofumi MZ         goto Quit;
807b5c9d532SKatayama Hirofumi MZ     }
808b5c9d532SKatayama Hirofumi MZ 
8099db44371SKatayama Hirofumi MZ     pwnd = ValidateHwndNoErr(hwnd);
810b5c9d532SKatayama Hirofumi MZ     if (!pwnd)
8119db44371SKatayama Hirofumi MZ         goto Quit;
8129db44371SKatayama Hirofumi MZ 
8139db44371SKatayama Hirofumi MZ     pti = pwnd->head.pti;
8149db44371SKatayama Hirofumi MZ     if (!pti || !gptiForeground)
8159db44371SKatayama Hirofumi MZ         goto Quit;
8169db44371SKatayama Hirofumi MZ     if (pti != gptiForeground && pti->MessageQueue != gptiForeground->MessageQueue)
8179db44371SKatayama Hirofumi MZ         goto Quit;
8189db44371SKatayama Hirofumi MZ     if (ghIMC == pwnd->hImc && gfImeOpen == !!fOpen && gdwImeConversion == dwConversion)
8199db44371SKatayama Hirofumi MZ         goto Quit;
8209db44371SKatayama Hirofumi MZ 
8219db44371SKatayama Hirofumi MZ     ghIMC = pwnd->hImc;
8229db44371SKatayama Hirofumi MZ     if (ghIMC)
8239db44371SKatayama Hirofumi MZ     {
8249db44371SKatayama Hirofumi MZ         gfImeOpen = !!fOpen;
8259db44371SKatayama Hirofumi MZ         gdwImeConversion = dwConversion;
8269db44371SKatayama Hirofumi MZ         UserSetImeConversionKeyState(pti, (fOpen ? dwConversion : IME_CMODE_ALPHANUMERIC));
8279db44371SKatayama Hirofumi MZ     }
8289db44371SKatayama Hirofumi MZ 
8299db44371SKatayama Hirofumi MZ     if (ISITHOOKED(WH_SHELL))
8309db44371SKatayama Hirofumi MZ     {
8319db44371SKatayama Hirofumi MZ         hKL = (pti->KeyboardLayout ? pti->KeyboardLayout->hkl : NULL);
8329db44371SKatayama Hirofumi MZ         co_HOOK_CallHooks(WH_SHELL, HSHELL_LANGUAGE, (WPARAM)hwnd, (LPARAM)hKL);
8339db44371SKatayama Hirofumi MZ     }
8349db44371SKatayama Hirofumi MZ 
8359db44371SKatayama Hirofumi MZ     // TODO:
8369db44371SKatayama Hirofumi MZ 
8379db44371SKatayama Hirofumi MZ Quit:
8389db44371SKatayama Hirofumi MZ     UserLeave();
839c2c66affSColin Finck     return 0;
840c2c66affSColin Finck }
841c2c66affSColin Finck 
842fcc222c2SKatayama Hirofumi MZ BOOL
843e52ce89bSKatayama Hirofumi MZ NTAPI
844c2c66affSColin Finck NtUserDisableThreadIme(
845fcc222c2SKatayama Hirofumi MZ     DWORD dwThreadID)
846c2c66affSColin Finck {
847fcc222c2SKatayama Hirofumi MZ     PTHREADINFO pti, ptiCurrent;
848fcc222c2SKatayama Hirofumi MZ     PPROCESSINFO ppi;
849fcc222c2SKatayama Hirofumi MZ     BOOL ret = FALSE;
850fcc222c2SKatayama Hirofumi MZ 
851fcc222c2SKatayama Hirofumi MZ     UserEnterExclusive();
852fcc222c2SKatayama Hirofumi MZ 
853fcc222c2SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
854fcc222c2SKatayama Hirofumi MZ     {
855b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
856fcc222c2SKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
857fcc222c2SKatayama Hirofumi MZ         goto Quit;
858fcc222c2SKatayama Hirofumi MZ     }
859fcc222c2SKatayama Hirofumi MZ 
860fcc222c2SKatayama Hirofumi MZ     ptiCurrent = GetW32ThreadInfo();
861fcc222c2SKatayama Hirofumi MZ 
862fcc222c2SKatayama Hirofumi MZ     if (dwThreadID == INVALID_THREAD_ID)
863fcc222c2SKatayama Hirofumi MZ     {
864fcc222c2SKatayama Hirofumi MZ         ppi = ptiCurrent->ppi;
865fcc222c2SKatayama Hirofumi MZ         ppi->W32PF_flags |= W32PF_DISABLEIME;
866fcc222c2SKatayama Hirofumi MZ 
867fcc222c2SKatayama Hirofumi MZ Retry:
868fcc222c2SKatayama Hirofumi MZ         for (pti = ppi->ptiList; pti; pti = pti->ptiSibling)
869fcc222c2SKatayama Hirofumi MZ         {
870fcc222c2SKatayama Hirofumi MZ             pti->TIF_flags |= TIF_DISABLEIME;
871fcc222c2SKatayama Hirofumi MZ 
872fcc222c2SKatayama Hirofumi MZ             if (pti->spwndDefaultIme)
873fcc222c2SKatayama Hirofumi MZ             {
874fcc222c2SKatayama Hirofumi MZ                 co_UserDestroyWindow(pti->spwndDefaultIme);
875fcc222c2SKatayama Hirofumi MZ                 pti->spwndDefaultIme = NULL;
876fcc222c2SKatayama Hirofumi MZ                 goto Retry; /* The contents of ppi->ptiList may be changed. */
877fcc222c2SKatayama Hirofumi MZ             }
878fcc222c2SKatayama Hirofumi MZ         }
879fcc222c2SKatayama Hirofumi MZ     }
880fcc222c2SKatayama Hirofumi MZ     else
881fcc222c2SKatayama Hirofumi MZ     {
882fcc222c2SKatayama Hirofumi MZ         if (dwThreadID == 0)
883fcc222c2SKatayama Hirofumi MZ         {
884fcc222c2SKatayama Hirofumi MZ             pti = ptiCurrent;
885fcc222c2SKatayama Hirofumi MZ         }
886fcc222c2SKatayama Hirofumi MZ         else
887fcc222c2SKatayama Hirofumi MZ         {
888fcc222c2SKatayama Hirofumi MZ             pti = IntTID2PTI(UlongToHandle(dwThreadID));
889fcc222c2SKatayama Hirofumi MZ 
890fcc222c2SKatayama Hirofumi MZ             /* The thread needs to reside in the current process. */
891fcc222c2SKatayama Hirofumi MZ             if (!pti || pti->ppi != ptiCurrent->ppi)
892fcc222c2SKatayama Hirofumi MZ                 goto Quit;
893fcc222c2SKatayama Hirofumi MZ         }
894fcc222c2SKatayama Hirofumi MZ 
895fcc222c2SKatayama Hirofumi MZ         pti->TIF_flags |= TIF_DISABLEIME;
896fcc222c2SKatayama Hirofumi MZ 
897fcc222c2SKatayama Hirofumi MZ         if (pti->spwndDefaultIme)
898fcc222c2SKatayama Hirofumi MZ         {
899fcc222c2SKatayama Hirofumi MZ             co_UserDestroyWindow(pti->spwndDefaultIme);
900fcc222c2SKatayama Hirofumi MZ             pti->spwndDefaultIme = NULL;
901fcc222c2SKatayama Hirofumi MZ         }
902fcc222c2SKatayama Hirofumi MZ     }
903fcc222c2SKatayama Hirofumi MZ 
904fcc222c2SKatayama Hirofumi MZ     ret = TRUE;
905fcc222c2SKatayama Hirofumi MZ 
906fcc222c2SKatayama Hirofumi MZ Quit:
907fcc222c2SKatayama Hirofumi MZ     UserLeave();
908fcc222c2SKatayama Hirofumi MZ     return ret;
909c2c66affSColin Finck }
910c2c66affSColin Finck 
911c2c66affSColin Finck DWORD
912e52ce89bSKatayama Hirofumi MZ NTAPI
913f4bc74edSKatayama Hirofumi MZ NtUserGetAppImeLevel(HWND hWnd)
914c2c66affSColin Finck {
9159c8167e9SKatayama Hirofumi MZ     DWORD ret = 0;
9169c8167e9SKatayama Hirofumi MZ     PWND pWnd;
9179c8167e9SKatayama Hirofumi MZ     PTHREADINFO pti;
9189c8167e9SKatayama Hirofumi MZ 
9199c8167e9SKatayama Hirofumi MZ     UserEnterShared();
9209c8167e9SKatayama Hirofumi MZ 
9219c8167e9SKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
9229c8167e9SKatayama Hirofumi MZ     if (!pWnd)
9239c8167e9SKatayama Hirofumi MZ         goto Quit;
9249c8167e9SKatayama Hirofumi MZ 
9259c8167e9SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
9269c8167e9SKatayama Hirofumi MZ     {
927b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
9289c8167e9SKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
9299c8167e9SKatayama Hirofumi MZ         goto Quit;
9309c8167e9SKatayama Hirofumi MZ     }
9319c8167e9SKatayama Hirofumi MZ 
9329c8167e9SKatayama Hirofumi MZ     pti = PsGetCurrentThreadWin32Thread();
9339c8167e9SKatayama Hirofumi MZ     if (pWnd->head.pti->ppi == pti->ppi)
9349c8167e9SKatayama Hirofumi MZ         ret = (DWORD)(ULONG_PTR)UserGetProp(pWnd, AtomImeLevel, TRUE);
9359c8167e9SKatayama Hirofumi MZ 
9369c8167e9SKatayama Hirofumi MZ Quit:
9379c8167e9SKatayama Hirofumi MZ     UserLeave();
9389c8167e9SKatayama Hirofumi MZ     return ret;
939c2c66affSColin Finck }
940c2c66affSColin Finck 
94136740ca9SKatayama Hirofumi MZ BOOL FASTCALL UserGetImeInfoEx(LPVOID pUnknown, PIMEINFOEX pInfoEx, IMEINFOEXCLASS SearchType)
94236740ca9SKatayama Hirofumi MZ {
94336740ca9SKatayama Hirofumi MZ     PKL pkl, pklHead;
94436740ca9SKatayama Hirofumi MZ 
94536740ca9SKatayama Hirofumi MZ     if (!gspklBaseLayout)
94636740ca9SKatayama Hirofumi MZ         return FALSE;
94736740ca9SKatayama Hirofumi MZ 
94836740ca9SKatayama Hirofumi MZ     pkl = pklHead = gspklBaseLayout;
94936740ca9SKatayama Hirofumi MZ 
95036740ca9SKatayama Hirofumi MZ     /* Find the matching entry from the list and get info */
95136740ca9SKatayama Hirofumi MZ     if (SearchType == ImeInfoExKeyboardLayout)
95236740ca9SKatayama Hirofumi MZ     {
95336740ca9SKatayama Hirofumi MZ         do
95436740ca9SKatayama Hirofumi MZ         {
95528959a2dSKatayama Hirofumi MZ             if (pInfoEx->hkl == pkl->hkl)
95636740ca9SKatayama Hirofumi MZ             {
95736740ca9SKatayama Hirofumi MZ                 if (!pkl->piiex)
95836740ca9SKatayama Hirofumi MZ                     break;
95936740ca9SKatayama Hirofumi MZ 
96028959a2dSKatayama Hirofumi MZ                 *pInfoEx = *pkl->piiex;
96128959a2dSKatayama Hirofumi MZ                 return TRUE;
96236740ca9SKatayama Hirofumi MZ             }
96336740ca9SKatayama Hirofumi MZ 
96436740ca9SKatayama Hirofumi MZ             pkl = pkl->pklNext;
96536740ca9SKatayama Hirofumi MZ         } while (pkl != pklHead);
96636740ca9SKatayama Hirofumi MZ     }
96736740ca9SKatayama Hirofumi MZ     else if (SearchType == ImeInfoExImeFileName)
96836740ca9SKatayama Hirofumi MZ     {
96936740ca9SKatayama Hirofumi MZ         do
97036740ca9SKatayama Hirofumi MZ         {
97136740ca9SKatayama Hirofumi MZ             if (pkl->piiex &&
97236740ca9SKatayama Hirofumi MZ                 _wcsnicmp(pkl->piiex->wszImeFile, pInfoEx->wszImeFile,
97328959a2dSKatayama Hirofumi MZ                           RTL_NUMBER_OF(pkl->piiex->wszImeFile)) == 0)
97436740ca9SKatayama Hirofumi MZ             {
97528959a2dSKatayama Hirofumi MZ                 *pInfoEx = *pkl->piiex;
97628959a2dSKatayama Hirofumi MZ                 return TRUE;
97736740ca9SKatayama Hirofumi MZ             }
97836740ca9SKatayama Hirofumi MZ 
97936740ca9SKatayama Hirofumi MZ             pkl = pkl->pklNext;
98036740ca9SKatayama Hirofumi MZ         } while (pkl != pklHead);
98136740ca9SKatayama Hirofumi MZ     }
98236740ca9SKatayama Hirofumi MZ     else
98336740ca9SKatayama Hirofumi MZ     {
98436740ca9SKatayama Hirofumi MZ         /* Do nothing */
98536740ca9SKatayama Hirofumi MZ     }
98636740ca9SKatayama Hirofumi MZ 
98728959a2dSKatayama Hirofumi MZ     return FALSE;
98836740ca9SKatayama Hirofumi MZ }
98936740ca9SKatayama Hirofumi MZ 
9904b038ec8SKatayama Hirofumi MZ BOOL
991e52ce89bSKatayama Hirofumi MZ NTAPI
992c2c66affSColin Finck NtUserGetImeInfoEx(
993c2c66affSColin Finck     PIMEINFOEX pImeInfoEx,
9944b038ec8SKatayama Hirofumi MZ     IMEINFOEXCLASS SearchType)
995c2c66affSColin Finck {
99636740ca9SKatayama Hirofumi MZ     IMEINFOEX ImeInfoEx;
99736740ca9SKatayama Hirofumi MZ     BOOL ret = FALSE;
99836740ca9SKatayama Hirofumi MZ 
99936740ca9SKatayama Hirofumi MZ     UserEnterShared();
100036740ca9SKatayama Hirofumi MZ 
100136740ca9SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1002b5c9d532SKatayama Hirofumi MZ     {
1003b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
100436740ca9SKatayama Hirofumi MZ         goto Quit;
1005b5c9d532SKatayama Hirofumi MZ     }
100636740ca9SKatayama Hirofumi MZ 
100736740ca9SKatayama Hirofumi MZ     _SEH2_TRY
100836740ca9SKatayama Hirofumi MZ     {
100936740ca9SKatayama Hirofumi MZ         ProbeForWrite(pImeInfoEx, sizeof(*pImeInfoEx), 1);
101036740ca9SKatayama Hirofumi MZ         ImeInfoEx = *pImeInfoEx;
101136740ca9SKatayama Hirofumi MZ     }
101236740ca9SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
101336740ca9SKatayama Hirofumi MZ     {
101436740ca9SKatayama Hirofumi MZ         goto Quit;
101536740ca9SKatayama Hirofumi MZ     }
101636740ca9SKatayama Hirofumi MZ     _SEH2_END;
101736740ca9SKatayama Hirofumi MZ 
101836740ca9SKatayama Hirofumi MZ     ret = UserGetImeInfoEx(NULL, &ImeInfoEx, SearchType);
1019e52ce89bSKatayama Hirofumi MZ     if (!ret)
1020e52ce89bSKatayama Hirofumi MZ         goto Quit;
1021e52ce89bSKatayama Hirofumi MZ 
102236740ca9SKatayama Hirofumi MZ     _SEH2_TRY
102336740ca9SKatayama Hirofumi MZ     {
102436740ca9SKatayama Hirofumi MZ         *pImeInfoEx = ImeInfoEx;
102536740ca9SKatayama Hirofumi MZ     }
102636740ca9SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
102736740ca9SKatayama Hirofumi MZ     {
102836740ca9SKatayama Hirofumi MZ         ret = FALSE;
102936740ca9SKatayama Hirofumi MZ     }
103036740ca9SKatayama Hirofumi MZ     _SEH2_END;
1031c2c66affSColin Finck 
103236740ca9SKatayama Hirofumi MZ Quit:
103336740ca9SKatayama Hirofumi MZ     UserLeave();
103436740ca9SKatayama Hirofumi MZ     return ret;
103536740ca9SKatayama Hirofumi MZ }
1036c2c66affSColin Finck 
10379c8167e9SKatayama Hirofumi MZ BOOL
1038e52ce89bSKatayama Hirofumi MZ NTAPI
10399c8167e9SKatayama Hirofumi MZ NtUserSetAppImeLevel(HWND hWnd, DWORD dwLevel)
1040c2c66affSColin Finck {
10419c8167e9SKatayama Hirofumi MZ     BOOL ret = FALSE;
10429c8167e9SKatayama Hirofumi MZ     PWND pWnd;
10439c8167e9SKatayama Hirofumi MZ     PTHREADINFO pti;
10449c8167e9SKatayama Hirofumi MZ 
10459c8167e9SKatayama Hirofumi MZ     UserEnterExclusive();
10469c8167e9SKatayama Hirofumi MZ 
10479c8167e9SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
10489c8167e9SKatayama Hirofumi MZ     {
1049b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
10509c8167e9SKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
10519c8167e9SKatayama Hirofumi MZ         goto Quit;
10529c8167e9SKatayama Hirofumi MZ     }
10539c8167e9SKatayama Hirofumi MZ 
1054b5c9d532SKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
1055b5c9d532SKatayama Hirofumi MZ     if (!pWnd)
1056b5c9d532SKatayama Hirofumi MZ         goto Quit;
1057b5c9d532SKatayama Hirofumi MZ 
10589c8167e9SKatayama Hirofumi MZ     pti = PsGetCurrentThreadWin32Thread();
10599c8167e9SKatayama Hirofumi MZ     if (pWnd->head.pti->ppi == pti->ppi)
10609c8167e9SKatayama Hirofumi MZ         ret = UserSetProp(pWnd, AtomImeLevel, (HANDLE)(ULONG_PTR)dwLevel, TRUE);
10619c8167e9SKatayama Hirofumi MZ 
10629c8167e9SKatayama Hirofumi MZ Quit:
10639c8167e9SKatayama Hirofumi MZ     UserLeave();
10649c8167e9SKatayama Hirofumi MZ     return ret;
1065c2c66affSColin Finck }
1066c2c66affSColin Finck 
10671f446936SKatayama Hirofumi MZ BOOL FASTCALL UserSetImeInfoEx(LPVOID pUnknown, PIMEINFOEX pImeInfoEx)
1068c2c66affSColin Finck {
10691f446936SKatayama Hirofumi MZ     PKL pklHead, pkl;
10701f446936SKatayama Hirofumi MZ 
10711f446936SKatayama Hirofumi MZ     pkl = pklHead = gspklBaseLayout;
10721f446936SKatayama Hirofumi MZ 
10731f446936SKatayama Hirofumi MZ     do
10741f446936SKatayama Hirofumi MZ     {
10751f446936SKatayama Hirofumi MZ         if (pkl->hkl != pImeInfoEx->hkl)
10761f446936SKatayama Hirofumi MZ         {
10771f446936SKatayama Hirofumi MZ             pkl = pkl->pklNext;
10781f446936SKatayama Hirofumi MZ             continue;
10791f446936SKatayama Hirofumi MZ         }
10801f446936SKatayama Hirofumi MZ 
10811f446936SKatayama Hirofumi MZ         if (!pkl->piiex)
10821f446936SKatayama Hirofumi MZ             return FALSE;
10831f446936SKatayama Hirofumi MZ 
10841f446936SKatayama Hirofumi MZ         if (!pkl->piiex->fLoadFlag)
10851f446936SKatayama Hirofumi MZ             *pkl->piiex = *pImeInfoEx;
10861f446936SKatayama Hirofumi MZ 
10871f446936SKatayama Hirofumi MZ         return TRUE;
10881f446936SKatayama Hirofumi MZ     } while (pkl != pklHead);
10891f446936SKatayama Hirofumi MZ 
10901f446936SKatayama Hirofumi MZ     return FALSE;
10911f446936SKatayama Hirofumi MZ }
10921f446936SKatayama Hirofumi MZ 
10931f446936SKatayama Hirofumi MZ BOOL
1094e52ce89bSKatayama Hirofumi MZ NTAPI
10951f446936SKatayama Hirofumi MZ NtUserSetImeInfoEx(PIMEINFOEX pImeInfoEx)
10961f446936SKatayama Hirofumi MZ {
10971f446936SKatayama Hirofumi MZ     BOOL ret = FALSE;
10981f446936SKatayama Hirofumi MZ     IMEINFOEX ImeInfoEx;
10991f446936SKatayama Hirofumi MZ 
11001f446936SKatayama Hirofumi MZ     UserEnterExclusive();
11011f446936SKatayama Hirofumi MZ 
11021f446936SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1103b5c9d532SKatayama Hirofumi MZ     {
1104b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
11051f446936SKatayama Hirofumi MZ         goto Quit;
1106b5c9d532SKatayama Hirofumi MZ     }
11071f446936SKatayama Hirofumi MZ 
11081f446936SKatayama Hirofumi MZ     _SEH2_TRY
11091f446936SKatayama Hirofumi MZ     {
11101f446936SKatayama Hirofumi MZ         ProbeForRead(pImeInfoEx, sizeof(*pImeInfoEx), 1);
11111f446936SKatayama Hirofumi MZ         ImeInfoEx = *pImeInfoEx;
11121f446936SKatayama Hirofumi MZ     }
11131f446936SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
11141f446936SKatayama Hirofumi MZ     {
11151f446936SKatayama Hirofumi MZ         goto Quit;
11161f446936SKatayama Hirofumi MZ     }
11171f446936SKatayama Hirofumi MZ     _SEH2_END;
11181f446936SKatayama Hirofumi MZ 
11191f446936SKatayama Hirofumi MZ     ret = UserSetImeInfoEx(NULL, &ImeInfoEx);
11201f446936SKatayama Hirofumi MZ 
11211f446936SKatayama Hirofumi MZ Quit:
11221f446936SKatayama Hirofumi MZ     UserLeave();
11231f446936SKatayama Hirofumi MZ     return ret;
1124c2c66affSColin Finck }
1125c2c66affSColin Finck 
1126e52ce89bSKatayama Hirofumi MZ BOOL NTAPI
11278c6dcdcfSKatayama Hirofumi MZ NtUserSetImeOwnerWindow(HWND hImeWnd, HWND hwndFocus)
1128c2c66affSColin Finck {
11290519ae0aSKatayama Hirofumi MZ     BOOL ret = FALSE;
11300519ae0aSKatayama Hirofumi MZ     PWND pImeWnd, pwndFocus, pwndTopLevel, pwnd, pwndActive;
11310519ae0aSKatayama Hirofumi MZ     PTHREADINFO ptiIme;
11320519ae0aSKatayama Hirofumi MZ 
11330519ae0aSKatayama Hirofumi MZ     UserEnterExclusive();
11340519ae0aSKatayama Hirofumi MZ 
1135b5c9d532SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1136b5c9d532SKatayama Hirofumi MZ     {
1137b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1138b5c9d532SKatayama Hirofumi MZ         goto Quit;
1139b5c9d532SKatayama Hirofumi MZ     }
1140b5c9d532SKatayama Hirofumi MZ 
11410519ae0aSKatayama Hirofumi MZ     pImeWnd = ValidateHwndNoErr(hImeWnd);
1142b5c9d532SKatayama Hirofumi MZ     if (!pImeWnd || pImeWnd->fnid != FNID_IME)
11430519ae0aSKatayama Hirofumi MZ         goto Quit;
11440519ae0aSKatayama Hirofumi MZ 
11450519ae0aSKatayama Hirofumi MZ     pwndFocus = ValidateHwndNoErr(hwndFocus);
11460519ae0aSKatayama Hirofumi MZ     if (pwndFocus)
11470519ae0aSKatayama Hirofumi MZ     {
11480519ae0aSKatayama Hirofumi MZ         if (IS_WND_IMELIKE(pwndFocus))
11490519ae0aSKatayama Hirofumi MZ             goto Quit;
11500519ae0aSKatayama Hirofumi MZ 
11510519ae0aSKatayama Hirofumi MZ         pwndTopLevel = IntGetTopLevelWindow(pwndFocus);
11520519ae0aSKatayama Hirofumi MZ 
11530519ae0aSKatayama Hirofumi MZ         for (pwnd = pwndTopLevel; pwnd; pwnd = pwnd->spwndOwner)
11540519ae0aSKatayama Hirofumi MZ         {
11550519ae0aSKatayama Hirofumi MZ             if (pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME])
11560519ae0aSKatayama Hirofumi MZ             {
11570519ae0aSKatayama Hirofumi MZ                 pwndTopLevel = NULL;
11580519ae0aSKatayama Hirofumi MZ                 break;
11590519ae0aSKatayama Hirofumi MZ             }
11600519ae0aSKatayama Hirofumi MZ         }
11610519ae0aSKatayama Hirofumi MZ 
11620519ae0aSKatayama Hirofumi MZ         pImeWnd->spwndOwner = pwndTopLevel;
11630519ae0aSKatayama Hirofumi MZ         // TODO:
11640519ae0aSKatayama Hirofumi MZ     }
11650519ae0aSKatayama Hirofumi MZ     else
11660519ae0aSKatayama Hirofumi MZ     {
11670519ae0aSKatayama Hirofumi MZ         ptiIme = pImeWnd->head.pti;
11680519ae0aSKatayama Hirofumi MZ         pwndActive = ptiIme->MessageQueue->spwndActive;
11690519ae0aSKatayama Hirofumi MZ 
11700519ae0aSKatayama Hirofumi MZ         if (!pwndActive || pwndActive != pImeWnd->spwndOwner)
11710519ae0aSKatayama Hirofumi MZ         {
11720519ae0aSKatayama Hirofumi MZ             if (pwndActive && ptiIme == pwndActive->head.pti && !IS_WND_IMELIKE(pwndActive))
11730519ae0aSKatayama Hirofumi MZ             {
11740519ae0aSKatayama Hirofumi MZ                 pImeWnd->spwndOwner = pwndActive;
11750519ae0aSKatayama Hirofumi MZ             }
11760519ae0aSKatayama Hirofumi MZ             else
11770519ae0aSKatayama Hirofumi MZ             {
11780519ae0aSKatayama Hirofumi MZ                 // TODO:
11790519ae0aSKatayama Hirofumi MZ             }
11800519ae0aSKatayama Hirofumi MZ 
11810519ae0aSKatayama Hirofumi MZ             // TODO:
11820519ae0aSKatayama Hirofumi MZ         }
11830519ae0aSKatayama Hirofumi MZ     }
11840519ae0aSKatayama Hirofumi MZ 
11850519ae0aSKatayama Hirofumi MZ     ret = TRUE;
11860519ae0aSKatayama Hirofumi MZ 
11870519ae0aSKatayama Hirofumi MZ Quit:
11880519ae0aSKatayama Hirofumi MZ     UserLeave();
11890519ae0aSKatayama Hirofumi MZ     return ret;
1190c2c66affSColin Finck }
1191c2c66affSColin Finck 
11923d78601fSKatayama Hirofumi MZ PVOID
11933d78601fSKatayama Hirofumi MZ AllocInputContextObject(PDESKTOP pDesk,
11943d78601fSKatayama Hirofumi MZ                         PTHREADINFO pti,
11953d78601fSKatayama Hirofumi MZ                         SIZE_T Size,
11963d78601fSKatayama Hirofumi MZ                         PVOID* HandleOwner)
11973d78601fSKatayama Hirofumi MZ {
11983d78601fSKatayama Hirofumi MZ     PTHRDESKHEAD ObjHead;
11993d78601fSKatayama Hirofumi MZ 
12003d78601fSKatayama Hirofumi MZ     ASSERT(Size > sizeof(*ObjHead));
12013d78601fSKatayama Hirofumi MZ     ASSERT(pti != NULL);
12023d78601fSKatayama Hirofumi MZ 
1203*45a4e53fSKatayama Hirofumi MZ     ObjHead = ExAllocatePoolWithTag(PagedPool, Size, USERTAG_IME);
12043d78601fSKatayama Hirofumi MZ     if (!ObjHead)
12053d78601fSKatayama Hirofumi MZ         return NULL;
12063d78601fSKatayama Hirofumi MZ 
12073d78601fSKatayama Hirofumi MZ     RtlZeroMemory(ObjHead, Size);
12083d78601fSKatayama Hirofumi MZ 
12093d78601fSKatayama Hirofumi MZ     ObjHead->pSelf = ObjHead;
12103d78601fSKatayama Hirofumi MZ     ObjHead->rpdesk = pDesk;
12113d78601fSKatayama Hirofumi MZ     ObjHead->pti = pti;
12123d78601fSKatayama Hirofumi MZ     IntReferenceThreadInfo(pti);
12133d78601fSKatayama Hirofumi MZ     *HandleOwner = pti;
12143d78601fSKatayama Hirofumi MZ     pti->ppi->UserHandleCount++;
12153d78601fSKatayama Hirofumi MZ 
12163d78601fSKatayama Hirofumi MZ     return ObjHead;
12173d78601fSKatayama Hirofumi MZ }
12183d78601fSKatayama Hirofumi MZ 
12193d78601fSKatayama Hirofumi MZ VOID UserFreeInputContext(PVOID Object)
12203d78601fSKatayama Hirofumi MZ {
1221*45a4e53fSKatayama Hirofumi MZ     PIMC pIMC = Object;
1222757bed81SKatayama Hirofumi MZ     PTHREADINFO pti;
12233d78601fSKatayama Hirofumi MZ 
1224757bed81SKatayama Hirofumi MZ     if (!pIMC)
1225757bed81SKatayama Hirofumi MZ         return;
12263d78601fSKatayama Hirofumi MZ 
1227757bed81SKatayama Hirofumi MZ     pti = pIMC->head.pti;
1228757bed81SKatayama Hirofumi MZ 
1229*45a4e53fSKatayama Hirofumi MZ     ExFreePoolWithTag(pIMC, USERTAG_IME);
1230*45a4e53fSKatayama Hirofumi MZ 
1231*45a4e53fSKatayama Hirofumi MZ     pti->ppi->UserHandleCount--;
1232*45a4e53fSKatayama Hirofumi MZ     IntDereferenceThreadInfo(pti);
1233*45a4e53fSKatayama Hirofumi MZ }
1234*45a4e53fSKatayama Hirofumi MZ 
1235*45a4e53fSKatayama Hirofumi MZ BOOLEAN UserDestroyInputContext(PVOID Object)
1236*45a4e53fSKatayama Hirofumi MZ {
1237*45a4e53fSKatayama Hirofumi MZ     PIMC pIMC = Object, pImc0;
1238*45a4e53fSKatayama Hirofumi MZ     PTHREADINFO pti;
1239*45a4e53fSKatayama Hirofumi MZ 
1240*45a4e53fSKatayama Hirofumi MZ     if (!pIMC)
1241*45a4e53fSKatayama Hirofumi MZ         return TRUE;
1242*45a4e53fSKatayama Hirofumi MZ 
1243*45a4e53fSKatayama Hirofumi MZ     UserMarkObjectDestroy(pIMC);
1244*45a4e53fSKatayama Hirofumi MZ 
1245757bed81SKatayama Hirofumi MZ     /* Find the IMC in the list and remove it */
1246*45a4e53fSKatayama Hirofumi MZ     pti = pIMC->head.pti;
12473d78601fSKatayama Hirofumi MZ     for (pImc0 = pti->spDefaultImc; pImc0; pImc0 = pImc0->pImcNext)
12483d78601fSKatayama Hirofumi MZ     {
12493d78601fSKatayama Hirofumi MZ         if (pImc0->pImcNext == pIMC)
12503d78601fSKatayama Hirofumi MZ         {
12513d78601fSKatayama Hirofumi MZ             pImc0->pImcNext = pIMC->pImcNext;
12523d78601fSKatayama Hirofumi MZ             break;
12533d78601fSKatayama Hirofumi MZ         }
12543d78601fSKatayama Hirofumi MZ     }
12553d78601fSKatayama Hirofumi MZ 
1256*45a4e53fSKatayama Hirofumi MZ     return UserDeleteObject(pIMC->head.h, TYPE_INPUTCONTEXT);
12573d78601fSKatayama Hirofumi MZ }
12583d78601fSKatayama Hirofumi MZ 
1259e52ce89bSKatayama Hirofumi MZ BOOL NTAPI NtUserDestroyInputContext(HIMC hIMC)
12603d78601fSKatayama Hirofumi MZ {
12613d78601fSKatayama Hirofumi MZ     PIMC pIMC;
12623d78601fSKatayama Hirofumi MZ     BOOL ret = FALSE;
12631bc9dda5SKatayama Hirofumi MZ     HWND *phwnd;
12641bc9dda5SKatayama Hirofumi MZ     PWND pWnd;
12651bc9dda5SKatayama Hirofumi MZ     PWINDOWLIST pwl;
12661bc9dda5SKatayama Hirofumi MZ     PTHREADINFO pti;
12673d78601fSKatayama Hirofumi MZ 
12683d78601fSKatayama Hirofumi MZ     UserEnterExclusive();
12693d78601fSKatayama Hirofumi MZ 
12701bc9dda5SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
12713d78601fSKatayama Hirofumi MZ     {
1272b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
12733d78601fSKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
12741bc9dda5SKatayama Hirofumi MZ         goto Quit;
12753d78601fSKatayama Hirofumi MZ     }
12763d78601fSKatayama Hirofumi MZ 
12771bc9dda5SKatayama Hirofumi MZ     pIMC = UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT);
12781bc9dda5SKatayama Hirofumi MZ     if (!pIMC)
12791bc9dda5SKatayama Hirofumi MZ         goto Quit;
12803d78601fSKatayama Hirofumi MZ 
12811bc9dda5SKatayama Hirofumi MZ     pti = pIMC->head.pti;
12821bc9dda5SKatayama Hirofumi MZ     if (pti != GetW32ThreadInfo() || pIMC == pti->spDefaultImc)
12831bc9dda5SKatayama Hirofumi MZ         goto Quit;
12841bc9dda5SKatayama Hirofumi MZ 
12851bc9dda5SKatayama Hirofumi MZ     UserMarkObjectDestroy(pIMC);
12861bc9dda5SKatayama Hirofumi MZ 
12871bc9dda5SKatayama Hirofumi MZ     pwl = IntBuildHwndList(pti->rpdesk->pDeskInfo->spwnd->spwndChild,
12881bc9dda5SKatayama Hirofumi MZ                            IACE_CHILDREN | IACE_LIST, pti);
12891bc9dda5SKatayama Hirofumi MZ     if (pwl)
12901bc9dda5SKatayama Hirofumi MZ     {
12911bc9dda5SKatayama Hirofumi MZ         for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
12921bc9dda5SKatayama Hirofumi MZ         {
12931bc9dda5SKatayama Hirofumi MZ             pWnd = ValidateHwndNoErr(*phwnd);
12941bc9dda5SKatayama Hirofumi MZ             if (!pWnd)
12951bc9dda5SKatayama Hirofumi MZ                 continue;
12961bc9dda5SKatayama Hirofumi MZ 
12971bc9dda5SKatayama Hirofumi MZ             if (pWnd->hImc == hIMC)
12981bc9dda5SKatayama Hirofumi MZ                 IntAssociateInputContext(pWnd, pti->spDefaultImc);
12991bc9dda5SKatayama Hirofumi MZ         }
13001bc9dda5SKatayama Hirofumi MZ 
13011bc9dda5SKatayama Hirofumi MZ         IntFreeHwndList(pwl);
13021bc9dda5SKatayama Hirofumi MZ     }
13031bc9dda5SKatayama Hirofumi MZ 
13041bc9dda5SKatayama Hirofumi MZ     ret = UserDeleteObject(hIMC, TYPE_INPUTCONTEXT);
13051bc9dda5SKatayama Hirofumi MZ 
13061bc9dda5SKatayama Hirofumi MZ Quit:
13073d78601fSKatayama Hirofumi MZ     UserLeave();
13083d78601fSKatayama Hirofumi MZ     return ret;
13093d78601fSKatayama Hirofumi MZ }
1310c2c66affSColin Finck 
1311470aa276SKatayama Hirofumi MZ PIMC FASTCALL UserCreateInputContext(ULONG_PTR dwClientImcData)
1312470aa276SKatayama Hirofumi MZ {
1313470aa276SKatayama Hirofumi MZ     PIMC pIMC;
1314470aa276SKatayama Hirofumi MZ     PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
1315470aa276SKatayama Hirofumi MZ     PDESKTOP pdesk = pti->rpdesk;
1316470aa276SKatayama Hirofumi MZ 
1317470aa276SKatayama Hirofumi MZ     if (!IS_IMM_MODE() || (pti->TIF_flags & TIF_DISABLEIME)) // Disabled?
1318b5c9d532SKatayama Hirofumi MZ     {
1319b5c9d532SKatayama Hirofumi MZ         ERR("IME is disabled\n");
1320470aa276SKatayama Hirofumi MZ         return NULL;
1321b5c9d532SKatayama Hirofumi MZ     }
1322470aa276SKatayama Hirofumi MZ 
1323470aa276SKatayama Hirofumi MZ     if (!pdesk) // No desktop?
1324470aa276SKatayama Hirofumi MZ         return NULL;
1325470aa276SKatayama Hirofumi MZ 
1326470aa276SKatayama Hirofumi MZ     // pti->spDefaultImc should be already set if non-first time.
1327470aa276SKatayama Hirofumi MZ     if (dwClientImcData && !pti->spDefaultImc)
1328470aa276SKatayama Hirofumi MZ         return NULL;
1329470aa276SKatayama Hirofumi MZ 
1330470aa276SKatayama Hirofumi MZ     // Create an input context user object.
1331470aa276SKatayama Hirofumi MZ     pIMC = UserCreateObject(gHandleTable, pdesk, pti, NULL, TYPE_INPUTCONTEXT, sizeof(IMC));
1332470aa276SKatayama Hirofumi MZ     if (!pIMC)
1333470aa276SKatayama Hirofumi MZ         return NULL;
1334470aa276SKatayama Hirofumi MZ 
1335470aa276SKatayama Hirofumi MZ     // Release the extra reference (UserCreateObject added 2 references).
1336470aa276SKatayama Hirofumi MZ     UserDereferenceObject(pIMC);
1337470aa276SKatayama Hirofumi MZ 
1338470aa276SKatayama Hirofumi MZ     if (dwClientImcData) // Non-first time.
1339470aa276SKatayama Hirofumi MZ     {
1340470aa276SKatayama Hirofumi MZ         // Insert pIMC to the second position (non-default) of the list.
1341470aa276SKatayama Hirofumi MZ         pIMC->pImcNext = pti->spDefaultImc->pImcNext;
1342470aa276SKatayama Hirofumi MZ         pti->spDefaultImc->pImcNext = pIMC;
1343470aa276SKatayama Hirofumi MZ     }
1344470aa276SKatayama Hirofumi MZ     else // First time. It's the default IMC.
1345470aa276SKatayama Hirofumi MZ     {
1346470aa276SKatayama Hirofumi MZ         // Add the first one (default) to the list.
1347470aa276SKatayama Hirofumi MZ         pti->spDefaultImc = pIMC;
1348470aa276SKatayama Hirofumi MZ         pIMC->pImcNext = NULL;
1349470aa276SKatayama Hirofumi MZ     }
1350470aa276SKatayama Hirofumi MZ 
1351470aa276SKatayama Hirofumi MZ     pIMC->dwClientImcData = dwClientImcData; // Set it.
1352470aa276SKatayama Hirofumi MZ     return pIMC;
1353470aa276SKatayama Hirofumi MZ }
1354470aa276SKatayama Hirofumi MZ 
1355470aa276SKatayama Hirofumi MZ HIMC
1356e52ce89bSKatayama Hirofumi MZ NTAPI
1357470aa276SKatayama Hirofumi MZ NtUserCreateInputContext(ULONG_PTR dwClientImcData)
1358470aa276SKatayama Hirofumi MZ {
1359470aa276SKatayama Hirofumi MZ     PIMC pIMC;
1360470aa276SKatayama Hirofumi MZ     HIMC ret = NULL;
1361470aa276SKatayama Hirofumi MZ 
1362470aa276SKatayama Hirofumi MZ     if (!dwClientImcData)
1363470aa276SKatayama Hirofumi MZ         return NULL;
1364470aa276SKatayama Hirofumi MZ 
1365470aa276SKatayama Hirofumi MZ     UserEnterExclusive();
1366470aa276SKatayama Hirofumi MZ 
1367470aa276SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1368b5c9d532SKatayama Hirofumi MZ     {
1369b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1370470aa276SKatayama Hirofumi MZ         goto Quit;
1371b5c9d532SKatayama Hirofumi MZ     }
1372470aa276SKatayama Hirofumi MZ 
1373470aa276SKatayama Hirofumi MZ     pIMC = UserCreateInputContext(dwClientImcData);
1374470aa276SKatayama Hirofumi MZ     if (pIMC)
1375470aa276SKatayama Hirofumi MZ         ret = UserHMGetHandle(pIMC);
1376470aa276SKatayama Hirofumi MZ 
1377470aa276SKatayama Hirofumi MZ Quit:
1378470aa276SKatayama Hirofumi MZ     UserLeave();
1379470aa276SKatayama Hirofumi MZ     return ret;
1380470aa276SKatayama Hirofumi MZ }
1381470aa276SKatayama Hirofumi MZ 
1382f2c3167dSKatayama Hirofumi MZ DWORD FASTCALL IntAssociateInputContextEx(PWND pWnd, PIMC pIMC, DWORD dwFlags)
1383f2c3167dSKatayama Hirofumi MZ {
1384f2c3167dSKatayama Hirofumi MZ     DWORD ret = 0;
1385f2c3167dSKatayama Hirofumi MZ     PWINDOWLIST pwl;
1386f2c3167dSKatayama Hirofumi MZ     BOOL bIgnoreNullImc = (dwFlags & IACE_IGNORENOCONTEXT);
1387f2c3167dSKatayama Hirofumi MZ     PTHREADINFO pti = pWnd->head.pti;
1388f2c3167dSKatayama Hirofumi MZ     PWND pwndTarget, pwndFocus = pti->MessageQueue->spwndFocus;
1389f2c3167dSKatayama Hirofumi MZ     HWND *phwnd;
1390f2c3167dSKatayama Hirofumi MZ     HIMC hIMC;
1391f2c3167dSKatayama Hirofumi MZ 
1392f2c3167dSKatayama Hirofumi MZ     if (dwFlags & IACE_DEFAULT)
1393f2c3167dSKatayama Hirofumi MZ     {
1394f2c3167dSKatayama Hirofumi MZ         pIMC = pti->spDefaultImc;
1395f2c3167dSKatayama Hirofumi MZ     }
1396f2c3167dSKatayama Hirofumi MZ     else
1397f2c3167dSKatayama Hirofumi MZ     {
1398f2c3167dSKatayama Hirofumi MZ         if (pIMC && pti != pIMC->head.pti)
1399f2c3167dSKatayama Hirofumi MZ             return 2;
1400f2c3167dSKatayama Hirofumi MZ     }
1401f2c3167dSKatayama Hirofumi MZ 
1402f2c3167dSKatayama Hirofumi MZ     if (pWnd->head.pti->ppi != GetW32ThreadInfo()->ppi ||
1403f2c3167dSKatayama Hirofumi MZ         (pIMC && pIMC->head.rpdesk != pWnd->head.rpdesk))
1404f2c3167dSKatayama Hirofumi MZ     {
1405f2c3167dSKatayama Hirofumi MZ         return 2;
1406f2c3167dSKatayama Hirofumi MZ     }
1407f2c3167dSKatayama Hirofumi MZ 
1408f2c3167dSKatayama Hirofumi MZ     if ((dwFlags & IACE_CHILDREN) && pWnd->spwndChild)
1409f2c3167dSKatayama Hirofumi MZ     {
1410f2c3167dSKatayama Hirofumi MZ         pwl = IntBuildHwndList(pWnd->spwndChild, IACE_CHILDREN | IACE_LIST, pti);
1411f2c3167dSKatayama Hirofumi MZ         if (pwl)
1412f2c3167dSKatayama Hirofumi MZ         {
1413f2c3167dSKatayama Hirofumi MZ             for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
1414f2c3167dSKatayama Hirofumi MZ             {
1415f2c3167dSKatayama Hirofumi MZ                 pwndTarget = ValidateHwndNoErr(*phwnd);
1416f2c3167dSKatayama Hirofumi MZ                 if (!pwndTarget)
1417f2c3167dSKatayama Hirofumi MZ                     continue;
1418f2c3167dSKatayama Hirofumi MZ 
1419f2c3167dSKatayama Hirofumi MZ                 hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1420f2c3167dSKatayama Hirofumi MZ                 if (pwndTarget->hImc == hIMC || (bIgnoreNullImc && !pwndTarget->hImc))
1421f2c3167dSKatayama Hirofumi MZ                     continue;
1422f2c3167dSKatayama Hirofumi MZ 
1423f2c3167dSKatayama Hirofumi MZ                 IntAssociateInputContext(pwndTarget, pIMC);
1424f2c3167dSKatayama Hirofumi MZ                 if (pwndTarget == pwndFocus)
1425f2c3167dSKatayama Hirofumi MZ                     ret = 1;
1426f2c3167dSKatayama Hirofumi MZ             }
1427f2c3167dSKatayama Hirofumi MZ 
1428f2c3167dSKatayama Hirofumi MZ             IntFreeHwndList(pwl);
1429f2c3167dSKatayama Hirofumi MZ         }
1430f2c3167dSKatayama Hirofumi MZ     }
1431f2c3167dSKatayama Hirofumi MZ 
1432f2c3167dSKatayama Hirofumi MZ     if (!bIgnoreNullImc || pWnd->hImc)
1433f2c3167dSKatayama Hirofumi MZ     {
1434f2c3167dSKatayama Hirofumi MZ         hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1435f2c3167dSKatayama Hirofumi MZ         if (pWnd->hImc != hIMC)
1436f2c3167dSKatayama Hirofumi MZ         {
1437f2c3167dSKatayama Hirofumi MZ             IntAssociateInputContext(pWnd, pIMC);
1438f2c3167dSKatayama Hirofumi MZ             if (pWnd == pwndFocus)
1439f2c3167dSKatayama Hirofumi MZ                 ret = 1;
1440f2c3167dSKatayama Hirofumi MZ         }
1441f2c3167dSKatayama Hirofumi MZ     }
1442f2c3167dSKatayama Hirofumi MZ 
1443f2c3167dSKatayama Hirofumi MZ     return ret;
1444f2c3167dSKatayama Hirofumi MZ }
1445f2c3167dSKatayama Hirofumi MZ 
1446470aa276SKatayama Hirofumi MZ DWORD
1447e52ce89bSKatayama Hirofumi MZ NTAPI
1448470aa276SKatayama Hirofumi MZ NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags)
1449470aa276SKatayama Hirofumi MZ {
1450f2c3167dSKatayama Hirofumi MZ     DWORD ret = 2;
1451f2c3167dSKatayama Hirofumi MZ     PWND pWnd;
1452f2c3167dSKatayama Hirofumi MZ     PIMC pIMC;
1453f2c3167dSKatayama Hirofumi MZ 
1454f2c3167dSKatayama Hirofumi MZ     UserEnterExclusive();
1455f2c3167dSKatayama Hirofumi MZ 
1456b5c9d532SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1457b5c9d532SKatayama Hirofumi MZ     {
1458b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1459b5c9d532SKatayama Hirofumi MZ         goto Quit;
1460b5c9d532SKatayama Hirofumi MZ     }
1461b5c9d532SKatayama Hirofumi MZ 
1462f2c3167dSKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
1463b5c9d532SKatayama Hirofumi MZ     if (!pWnd)
1464f2c3167dSKatayama Hirofumi MZ         goto Quit;
1465f2c3167dSKatayama Hirofumi MZ 
1466f2c3167dSKatayama Hirofumi MZ     pIMC = (hIMC ? UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT) : NULL);
1467f2c3167dSKatayama Hirofumi MZ     ret = IntAssociateInputContextEx(pWnd, pIMC, dwFlags);
1468f2c3167dSKatayama Hirofumi MZ 
1469f2c3167dSKatayama Hirofumi MZ Quit:
1470f2c3167dSKatayama Hirofumi MZ     UserLeave();
1471f2c3167dSKatayama Hirofumi MZ     return ret;
1472470aa276SKatayama Hirofumi MZ }
1473470aa276SKatayama Hirofumi MZ 
1474470aa276SKatayama Hirofumi MZ BOOL FASTCALL UserUpdateInputContext(PIMC pIMC, DWORD dwType, DWORD_PTR dwValue)
1475470aa276SKatayama Hirofumi MZ {
1476470aa276SKatayama Hirofumi MZ     PTHREADINFO pti = GetW32ThreadInfo();
1477470aa276SKatayama Hirofumi MZ     PTHREADINFO ptiIMC = pIMC->head.pti;
1478470aa276SKatayama Hirofumi MZ 
1479470aa276SKatayama Hirofumi MZ     if (pti->ppi != ptiIMC->ppi) // Different process?
1480470aa276SKatayama Hirofumi MZ         return FALSE;
1481470aa276SKatayama Hirofumi MZ 
1482470aa276SKatayama Hirofumi MZ     switch (dwType)
1483470aa276SKatayama Hirofumi MZ     {
1484470aa276SKatayama Hirofumi MZ         case UIC_CLIENTIMCDATA:
1485470aa276SKatayama Hirofumi MZ             if (pIMC->dwClientImcData)
1486470aa276SKatayama Hirofumi MZ                 return FALSE; // Already set
1487470aa276SKatayama Hirofumi MZ 
1488470aa276SKatayama Hirofumi MZ             pIMC->dwClientImcData = dwValue;
1489470aa276SKatayama Hirofumi MZ             break;
1490470aa276SKatayama Hirofumi MZ 
1491470aa276SKatayama Hirofumi MZ         case UIC_IMEWINDOW:
1492470aa276SKatayama Hirofumi MZ             if (!ValidateHwndNoErr((HWND)dwValue))
1493470aa276SKatayama Hirofumi MZ                 return FALSE; // Invalid HWND
1494470aa276SKatayama Hirofumi MZ 
1495470aa276SKatayama Hirofumi MZ             pIMC->hImeWnd = (HWND)dwValue;
1496470aa276SKatayama Hirofumi MZ             break;
1497470aa276SKatayama Hirofumi MZ 
1498470aa276SKatayama Hirofumi MZ         default:
1499470aa276SKatayama Hirofumi MZ             return FALSE;
1500470aa276SKatayama Hirofumi MZ     }
1501470aa276SKatayama Hirofumi MZ 
1502470aa276SKatayama Hirofumi MZ     return TRUE;
1503470aa276SKatayama Hirofumi MZ }
1504470aa276SKatayama Hirofumi MZ 
1505470aa276SKatayama Hirofumi MZ BOOL
1506e52ce89bSKatayama Hirofumi MZ NTAPI
1507470aa276SKatayama Hirofumi MZ NtUserUpdateInputContext(
1508470aa276SKatayama Hirofumi MZ     HIMC hIMC,
1509470aa276SKatayama Hirofumi MZ     DWORD dwType,
1510470aa276SKatayama Hirofumi MZ     DWORD_PTR dwValue)
1511470aa276SKatayama Hirofumi MZ {
1512470aa276SKatayama Hirofumi MZ     PIMC pIMC;
1513470aa276SKatayama Hirofumi MZ     BOOL ret = FALSE;
1514470aa276SKatayama Hirofumi MZ 
1515470aa276SKatayama Hirofumi MZ     UserEnterExclusive();
1516470aa276SKatayama Hirofumi MZ 
1517470aa276SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1518b5c9d532SKatayama Hirofumi MZ     {
1519b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1520470aa276SKatayama Hirofumi MZ         goto Quit;
1521b5c9d532SKatayama Hirofumi MZ     }
1522470aa276SKatayama Hirofumi MZ 
1523470aa276SKatayama Hirofumi MZ     pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT);
1524470aa276SKatayama Hirofumi MZ     if (!pIMC)
1525470aa276SKatayama Hirofumi MZ         goto Quit;
1526470aa276SKatayama Hirofumi MZ 
1527470aa276SKatayama Hirofumi MZ     ret = UserUpdateInputContext(pIMC, dwType, dwValue);
1528470aa276SKatayama Hirofumi MZ 
1529470aa276SKatayama Hirofumi MZ Quit:
1530470aa276SKatayama Hirofumi MZ     UserLeave();
1531470aa276SKatayama Hirofumi MZ     return ret;
1532470aa276SKatayama Hirofumi MZ }
1533470aa276SKatayama Hirofumi MZ 
1534470aa276SKatayama Hirofumi MZ DWORD_PTR
1535e52ce89bSKatayama Hirofumi MZ NTAPI
1536470aa276SKatayama Hirofumi MZ NtUserQueryInputContext(HIMC hIMC, DWORD dwType)
1537470aa276SKatayama Hirofumi MZ {
1538470aa276SKatayama Hirofumi MZ     PIMC pIMC;
1539470aa276SKatayama Hirofumi MZ     PTHREADINFO ptiIMC;
1540470aa276SKatayama Hirofumi MZ     DWORD_PTR ret = 0;
1541470aa276SKatayama Hirofumi MZ 
1542470aa276SKatayama Hirofumi MZ     UserEnterExclusive();
1543470aa276SKatayama Hirofumi MZ 
1544470aa276SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1545b5c9d532SKatayama Hirofumi MZ     {
1546b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1547470aa276SKatayama Hirofumi MZ         goto Quit;
1548b5c9d532SKatayama Hirofumi MZ     }
1549470aa276SKatayama Hirofumi MZ 
1550470aa276SKatayama Hirofumi MZ     pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT);
1551470aa276SKatayama Hirofumi MZ     if (!pIMC)
1552470aa276SKatayama Hirofumi MZ         goto Quit;
1553470aa276SKatayama Hirofumi MZ 
1554470aa276SKatayama Hirofumi MZ     ptiIMC = pIMC->head.pti;
1555470aa276SKatayama Hirofumi MZ 
1556470aa276SKatayama Hirofumi MZ     switch (dwType)
1557470aa276SKatayama Hirofumi MZ     {
1558470aa276SKatayama Hirofumi MZ         case QIC_INPUTPROCESSID:
1559470aa276SKatayama Hirofumi MZ             ret = (DWORD_PTR)PsGetThreadProcessId(ptiIMC->pEThread);
1560470aa276SKatayama Hirofumi MZ             break;
1561470aa276SKatayama Hirofumi MZ 
1562470aa276SKatayama Hirofumi MZ         case QIC_INPUTTHREADID:
1563470aa276SKatayama Hirofumi MZ             ret = (DWORD_PTR)PsGetThreadId(ptiIMC->pEThread);
1564470aa276SKatayama Hirofumi MZ             break;
1565470aa276SKatayama Hirofumi MZ 
1566470aa276SKatayama Hirofumi MZ         case QIC_DEFAULTWINDOWIME:
1567470aa276SKatayama Hirofumi MZ             if (ptiIMC->spwndDefaultIme)
1568470aa276SKatayama Hirofumi MZ                 ret = (DWORD_PTR)UserHMGetHandle(ptiIMC->spwndDefaultIme);
1569470aa276SKatayama Hirofumi MZ             break;
1570470aa276SKatayama Hirofumi MZ 
1571470aa276SKatayama Hirofumi MZ         case QIC_DEFAULTIMC:
1572470aa276SKatayama Hirofumi MZ             if (ptiIMC->spDefaultImc)
1573470aa276SKatayama Hirofumi MZ                 ret = (DWORD_PTR)UserHMGetHandle(ptiIMC->spDefaultImc);
1574470aa276SKatayama Hirofumi MZ             break;
1575470aa276SKatayama Hirofumi MZ     }
1576470aa276SKatayama Hirofumi MZ 
1577470aa276SKatayama Hirofumi MZ Quit:
1578470aa276SKatayama Hirofumi MZ     UserLeave();
1579470aa276SKatayama Hirofumi MZ     return ret;
1580470aa276SKatayama Hirofumi MZ }
1581470aa276SKatayama Hirofumi MZ 
1582c2c66affSColin Finck /* EOF */
1583