xref: /reactos/win32ss/user/ntuser/ime.c (revision ec24b547)
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>
114aff6293SKatayama Hirofumi MZ #include <jpnvkeys.h>
124aff6293SKatayama Hirofumi MZ 
13c2c66affSColin Finck DBG_DEFAULT_CHANNEL(UserMisc);
14c2c66affSColin Finck 
15fcc222c2SKatayama Hirofumi MZ #define INVALID_THREAD_ID  ((ULONG)-1)
16bbe5fd52SKatayama Hirofumi MZ #define INVALID_HOTKEY     ((UINT)-1)
175d5cc578SKatayama Hirofumi MZ #define MOD_KEYS           (MOD_CONTROL | MOD_SHIFT | MOD_ALT | MOD_WIN)
185d5cc578SKatayama Hirofumi MZ #define MOD_LEFT_RIGHT     (MOD_LEFT | MOD_RIGHT)
195d5cc578SKatayama Hirofumi MZ 
205d5cc578SKatayama Hirofumi MZ #define LANGID_CHINESE_SIMPLIFIED   MAKELANGID(LANG_CHINESE,  SUBLANG_CHINESE_SIMPLIFIED)
215d5cc578SKatayama Hirofumi MZ #define LANGID_JAPANESE             MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)
225d5cc578SKatayama Hirofumi MZ #define LANGID_KOREAN               MAKELANGID(LANG_KOREAN,   SUBLANG_KOREAN)
235d5cc578SKatayama Hirofumi MZ #define LANGID_CHINESE_TRADITIONAL  MAKELANGID(LANG_CHINESE,  SUBLANG_CHINESE_TRADITIONAL)
245d5cc578SKatayama Hirofumi MZ #define LANGID_NEUTRAL              MAKELANGID(LANG_NEUTRAL,  SUBLANG_NEUTRAL)
25c2c66affSColin Finck 
269db44371SKatayama Hirofumi MZ HIMC ghIMC = NULL;
279db44371SKatayama Hirofumi MZ BOOL gfImeOpen = (BOOL)-1;
289db44371SKatayama Hirofumi MZ DWORD gdwImeConversion = (DWORD)-1;
29242e0b43SKatayama Hirofumi MZ BOOL gfIMEShowStatus = (BOOL)-1;
309db44371SKatayama Hirofumi MZ 
315d5cc578SKatayama Hirofumi MZ typedef struct tagIMEHOTKEY
325d5cc578SKatayama Hirofumi MZ {
335d5cc578SKatayama Hirofumi MZ     struct tagIMEHOTKEY *pNext;
345d5cc578SKatayama Hirofumi MZ     DWORD  dwHotKeyId;
355d5cc578SKatayama Hirofumi MZ     UINT   uVirtualKey;
365d5cc578SKatayama Hirofumi MZ     UINT   uModifiers;
375d5cc578SKatayama Hirofumi MZ     HKL    hKL;
385d5cc578SKatayama Hirofumi MZ } IMEHOTKEY, *PIMEHOTKEY;
395d5cc578SKatayama Hirofumi MZ 
405df5ef2bSKatayama Hirofumi MZ PIMEHOTKEY gpImeHotKeyList = NULL; // Win: gpImeHotKeyListHeader
415df5ef2bSKatayama Hirofumi MZ LCID glcidSystem = 0; // Win: glcidSystem
42bbe5fd52SKatayama Hirofumi MZ 
435df5ef2bSKatayama Hirofumi MZ // Win: GetAppImeCompatFlags
IntGetImeCompatFlags(PTHREADINFO pti)44b5c9d532SKatayama Hirofumi MZ DWORD FASTCALL IntGetImeCompatFlags(PTHREADINFO pti)
45b5c9d532SKatayama Hirofumi MZ {
46b5c9d532SKatayama Hirofumi MZ     if (!pti)
47b5c9d532SKatayama Hirofumi MZ         pti = PsGetCurrentThreadWin32Thread();
48b5c9d532SKatayama Hirofumi MZ 
49b5c9d532SKatayama Hirofumi MZ     return pti->ppi->dwImeCompatFlags;
50b5c9d532SKatayama Hirofumi MZ }
51b5c9d532SKatayama Hirofumi MZ 
525df5ef2bSKatayama Hirofumi MZ // Win: GetLangIdMatchLevel
IntGetImeHotKeyLanguageScore(HKL hKL,LANGID HotKeyLangId)53bbe5fd52SKatayama Hirofumi MZ UINT FASTCALL IntGetImeHotKeyLanguageScore(HKL hKL, LANGID HotKeyLangId)
54bbe5fd52SKatayama Hirofumi MZ {
55bbe5fd52SKatayama Hirofumi MZ     LCID lcid;
56bbe5fd52SKatayama Hirofumi MZ 
57bbe5fd52SKatayama Hirofumi MZ     if (HotKeyLangId == LANGID_NEUTRAL || HotKeyLangId == LOWORD(hKL))
58bbe5fd52SKatayama Hirofumi MZ         return 3;
59bbe5fd52SKatayama Hirofumi MZ 
60bbe5fd52SKatayama Hirofumi MZ     _SEH2_TRY
61bbe5fd52SKatayama Hirofumi MZ     {
62bbe5fd52SKatayama Hirofumi MZ         lcid = NtCurrentTeb()->CurrentLocale;
63bbe5fd52SKatayama Hirofumi MZ     }
64bbe5fd52SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
65bbe5fd52SKatayama Hirofumi MZ     {
661ef98fffSKatayama Hirofumi MZ         ERR("%p\n", NtCurrentTeb());
67bbe5fd52SKatayama Hirofumi MZ         lcid = MAKELCID(LANGID_NEUTRAL, SORT_DEFAULT);
68bbe5fd52SKatayama Hirofumi MZ     }
69bbe5fd52SKatayama Hirofumi MZ     _SEH2_END;
70bbe5fd52SKatayama Hirofumi MZ 
71bbe5fd52SKatayama Hirofumi MZ     if (HotKeyLangId == LANGIDFROMLCID(lcid))
72bbe5fd52SKatayama Hirofumi MZ         return 2;
73bbe5fd52SKatayama Hirofumi MZ 
745df5ef2bSKatayama Hirofumi MZ     if (glcidSystem == 0)
755df5ef2bSKatayama Hirofumi MZ         ZwQueryDefaultLocale(FALSE, &glcidSystem);
76bbe5fd52SKatayama Hirofumi MZ 
775df5ef2bSKatayama Hirofumi MZ     if (HotKeyLangId == LANGIDFROMLCID(glcidSystem))
78bbe5fd52SKatayama Hirofumi MZ         return 1;
79bbe5fd52SKatayama Hirofumi MZ 
80bbe5fd52SKatayama Hirofumi MZ     return 0;
81bbe5fd52SKatayama Hirofumi MZ }
82bbe5fd52SKatayama Hirofumi MZ 
835df5ef2bSKatayama Hirofumi MZ // Win: GetActiveHKL
IntGetActiveKeyboardLayout(VOID)84bbe5fd52SKatayama Hirofumi MZ HKL FASTCALL IntGetActiveKeyboardLayout(VOID)
85bbe5fd52SKatayama Hirofumi MZ {
86bbe5fd52SKatayama Hirofumi MZ     PTHREADINFO pti;
87bbe5fd52SKatayama Hirofumi MZ 
88bbe5fd52SKatayama Hirofumi MZ     if (gpqForeground && gpqForeground->spwndActive)
89bbe5fd52SKatayama Hirofumi MZ     {
90bbe5fd52SKatayama Hirofumi MZ         pti = gpqForeground->spwndActive->head.pti;
91bbe5fd52SKatayama Hirofumi MZ         if (pti && pti->KeyboardLayout)
92bbe5fd52SKatayama Hirofumi MZ             return pti->KeyboardLayout->hkl;
93bbe5fd52SKatayama Hirofumi MZ     }
94bbe5fd52SKatayama Hirofumi MZ 
95bbe5fd52SKatayama Hirofumi MZ     return UserGetKeyboardLayout(0);
96bbe5fd52SKatayama Hirofumi MZ }
975d5cc578SKatayama Hirofumi MZ 
985df5ef2bSKatayama Hirofumi MZ // Win: GetHotKeyLangID
IntGetImeHotKeyLangId(DWORD dwHotKeyId)995d5cc578SKatayama Hirofumi MZ static LANGID FASTCALL IntGetImeHotKeyLangId(DWORD dwHotKeyId)
1005d5cc578SKatayama Hirofumi MZ {
1015d5cc578SKatayama Hirofumi MZ #define IME_CHOTKEY 0x10
1025d5cc578SKatayama Hirofumi MZ #define IME_JHOTKEY 0x30
1035d5cc578SKatayama Hirofumi MZ #define IME_KHOTKEY 0x50
1045d5cc578SKatayama Hirofumi MZ #define IME_THOTKEY 0x70
1055d5cc578SKatayama Hirofumi MZ #define IME_XHOTKEY 0x90
1065d5cc578SKatayama Hirofumi MZ     static const LANGID s_array[] =
1075d5cc578SKatayama Hirofumi MZ     {
1085d5cc578SKatayama Hirofumi MZ         /* 0x00 */ (WORD)-1,
1095d5cc578SKatayama Hirofumi MZ         /* 0x10 */ LANGID_CHINESE_SIMPLIFIED,
1105d5cc578SKatayama Hirofumi MZ         /* 0x20 */ LANGID_CHINESE_SIMPLIFIED,
1115d5cc578SKatayama Hirofumi MZ         /* 0x30 */ LANGID_JAPANESE,
1125d5cc578SKatayama Hirofumi MZ         /* 0x40 */ LANGID_JAPANESE,
1135d5cc578SKatayama Hirofumi MZ         /* 0x50 */ LANGID_KOREAN,
1145d5cc578SKatayama Hirofumi MZ         /* 0x60 */ LANGID_KOREAN,
1155d5cc578SKatayama Hirofumi MZ         /* 0x70 */ LANGID_CHINESE_TRADITIONAL,
1165d5cc578SKatayama Hirofumi MZ         /* 0x80 */ LANGID_CHINESE_TRADITIONAL
1175d5cc578SKatayama Hirofumi MZ     };
1185d5cc578SKatayama Hirofumi MZ 
1195d5cc578SKatayama Hirofumi MZ     if (IME_CHOTKEY <= dwHotKeyId && dwHotKeyId < IME_XHOTKEY)
1205d5cc578SKatayama Hirofumi MZ         return s_array[(dwHotKeyId & 0xF0) >> 4];
1215d5cc578SKatayama Hirofumi MZ     return LANGID_NEUTRAL;
1225d5cc578SKatayama Hirofumi MZ }
1235d5cc578SKatayama Hirofumi MZ 
1242f7775c6SKatayama Hirofumi MZ // Win: AddImeHotKey
IntAddImeHotKey(PIMEHOTKEY * ppList,PIMEHOTKEY pHotKey)1255d5cc578SKatayama Hirofumi MZ static VOID FASTCALL IntAddImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
1265d5cc578SKatayama Hirofumi MZ {
1275d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
1285d5cc578SKatayama Hirofumi MZ 
1295d5cc578SKatayama Hirofumi MZ     if (!*ppList)
1305d5cc578SKatayama Hirofumi MZ     {
1315d5cc578SKatayama Hirofumi MZ         *ppList = pHotKey;
1325d5cc578SKatayama Hirofumi MZ         return;
1335d5cc578SKatayama Hirofumi MZ     }
1345d5cc578SKatayama Hirofumi MZ 
1355d5cc578SKatayama Hirofumi MZ     for (pNode = *ppList; pNode; pNode = pNode->pNext)
1365d5cc578SKatayama Hirofumi MZ     {
1375d5cc578SKatayama Hirofumi MZ         if (!pNode->pNext)
1385d5cc578SKatayama Hirofumi MZ         {
1395d5cc578SKatayama Hirofumi MZ             pNode->pNext = pHotKey;
1405d5cc578SKatayama Hirofumi MZ             return;
1415d5cc578SKatayama Hirofumi MZ         }
1425d5cc578SKatayama Hirofumi MZ     }
1435d5cc578SKatayama Hirofumi MZ }
1445d5cc578SKatayama Hirofumi MZ 
1455df5ef2bSKatayama Hirofumi MZ // Win: FindImeHotKeyByID
IntGetImeHotKeyById(PIMEHOTKEY pList,DWORD dwHotKeyId)1465d5cc578SKatayama Hirofumi MZ static PIMEHOTKEY FASTCALL IntGetImeHotKeyById(PIMEHOTKEY pList, DWORD dwHotKeyId)
1475d5cc578SKatayama Hirofumi MZ {
1485d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
1495d5cc578SKatayama Hirofumi MZ     for (pNode = pList; pNode; pNode = pNode->pNext)
1505d5cc578SKatayama Hirofumi MZ     {
1515d5cc578SKatayama Hirofumi MZ         if (pNode->dwHotKeyId == dwHotKeyId)
1525d5cc578SKatayama Hirofumi MZ             return pNode;
1535d5cc578SKatayama Hirofumi MZ     }
1545d5cc578SKatayama Hirofumi MZ     return NULL;
1555d5cc578SKatayama Hirofumi MZ }
1565d5cc578SKatayama Hirofumi MZ 
1575df5ef2bSKatayama Hirofumi MZ // Win: FindImeHotKeyByKeyWithLang
1585d5cc578SKatayama Hirofumi MZ static PIMEHOTKEY APIENTRY
IntGetImeHotKeyByKeyAndLang(PIMEHOTKEY pList,UINT uModKeys,UINT uLeftRight,UINT uVirtualKey,LANGID TargetLangId)1595d5cc578SKatayama Hirofumi MZ IntGetImeHotKeyByKeyAndLang(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight,
1605d5cc578SKatayama Hirofumi MZ                             UINT uVirtualKey, LANGID TargetLangId)
1615d5cc578SKatayama Hirofumi MZ {
1625d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
1635d5cc578SKatayama Hirofumi MZ     LANGID LangID;
1645d5cc578SKatayama Hirofumi MZ     UINT uModifiers;
1655d5cc578SKatayama Hirofumi MZ 
1665d5cc578SKatayama Hirofumi MZ     for (pNode = pList; pNode; pNode = pNode->pNext)
1675d5cc578SKatayama Hirofumi MZ     {
1685d5cc578SKatayama Hirofumi MZ         if (pNode->uVirtualKey != uVirtualKey)
1695d5cc578SKatayama Hirofumi MZ             continue;
1705d5cc578SKatayama Hirofumi MZ 
1715d5cc578SKatayama Hirofumi MZ         LangID = IntGetImeHotKeyLangId(pNode->dwHotKeyId);
17239fe905eSKatayama Hirofumi MZ         if (LangID != TargetLangId && LangID != 0)
1735d5cc578SKatayama Hirofumi MZ             continue;
1745d5cc578SKatayama Hirofumi MZ 
1755d5cc578SKatayama Hirofumi MZ         uModifiers = pNode->uModifiers;
1765d5cc578SKatayama Hirofumi MZ         if (uModifiers & MOD_IGNORE_ALL_MODIFIER)
1775d5cc578SKatayama Hirofumi MZ             return pNode;
1785d5cc578SKatayama Hirofumi MZ 
1795d5cc578SKatayama Hirofumi MZ         if ((uModifiers & MOD_KEYS) != uModKeys)
1805d5cc578SKatayama Hirofumi MZ             continue;
1815d5cc578SKatayama Hirofumi MZ 
1825d5cc578SKatayama Hirofumi MZ         if ((uModifiers & uLeftRight) || (uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
1835d5cc578SKatayama Hirofumi MZ             return pNode;
1845d5cc578SKatayama Hirofumi MZ     }
1855d5cc578SKatayama Hirofumi MZ 
1865d5cc578SKatayama Hirofumi MZ     return NULL;
1875d5cc578SKatayama Hirofumi MZ }
1885d5cc578SKatayama Hirofumi MZ 
1895df5ef2bSKatayama Hirofumi MZ // Win: DeleteImeHotKey
IntDeleteImeHotKey(PIMEHOTKEY * ppList,PIMEHOTKEY pHotKey)1905d5cc578SKatayama Hirofumi MZ static VOID FASTCALL IntDeleteImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
1915d5cc578SKatayama Hirofumi MZ {
1925d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
1935d5cc578SKatayama Hirofumi MZ 
1945d5cc578SKatayama Hirofumi MZ     if (*ppList == pHotKey)
1955d5cc578SKatayama Hirofumi MZ     {
1965d5cc578SKatayama Hirofumi MZ         *ppList = pHotKey->pNext;
1975d5cc578SKatayama Hirofumi MZ         ExFreePoolWithTag(pHotKey, USERTAG_IMEHOTKEY);
1985d5cc578SKatayama Hirofumi MZ         return;
1995d5cc578SKatayama Hirofumi MZ     }
2005d5cc578SKatayama Hirofumi MZ 
2015d5cc578SKatayama Hirofumi MZ     for (pNode = *ppList; pNode; pNode = pNode->pNext)
2025d5cc578SKatayama Hirofumi MZ     {
2035d5cc578SKatayama Hirofumi MZ         if (pNode->pNext == pHotKey)
2045d5cc578SKatayama Hirofumi MZ         {
2055d5cc578SKatayama Hirofumi MZ             pNode->pNext = pHotKey->pNext;
2065d5cc578SKatayama Hirofumi MZ             ExFreePoolWithTag(pHotKey, USERTAG_IMEHOTKEY);
2075d5cc578SKatayama Hirofumi MZ             return;
2085d5cc578SKatayama Hirofumi MZ         }
2095d5cc578SKatayama Hirofumi MZ     }
2105d5cc578SKatayama Hirofumi MZ }
2115d5cc578SKatayama Hirofumi MZ 
2125df5ef2bSKatayama Hirofumi MZ // Win: FindImeHotKeyByKey
213bbe5fd52SKatayama Hirofumi MZ PIMEHOTKEY
IntGetImeHotKeyByKey(PIMEHOTKEY pList,UINT uModKeys,UINT uLeftRight,UINT uVirtualKey)214bbe5fd52SKatayama Hirofumi MZ IntGetImeHotKeyByKey(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, UINT uVirtualKey)
215bbe5fd52SKatayama Hirofumi MZ {
216bbe5fd52SKatayama Hirofumi MZ     PIMEHOTKEY pNode, ret = NULL;
217bbe5fd52SKatayama Hirofumi MZ     PTHREADINFO pti = GetW32ThreadInfo();
218bbe5fd52SKatayama Hirofumi MZ     LANGID LangId;
219bbe5fd52SKatayama Hirofumi MZ     HKL hKL = IntGetActiveKeyboardLayout();
220bbe5fd52SKatayama Hirofumi MZ     BOOL fKorean = (PRIMARYLANGID(LOWORD(hKL)) == LANG_KOREAN);
221bbe5fd52SKatayama Hirofumi MZ     UINT nScore, nMaxScore = 0;
222bbe5fd52SKatayama Hirofumi MZ 
223bbe5fd52SKatayama Hirofumi MZ     for (pNode = pList; pNode; pNode = pNode->pNext)
224bbe5fd52SKatayama Hirofumi MZ     {
225bbe5fd52SKatayama Hirofumi MZ         if (pNode->uVirtualKey != uVirtualKey)
226bbe5fd52SKatayama Hirofumi MZ             continue;
227bbe5fd52SKatayama Hirofumi MZ 
228bbe5fd52SKatayama Hirofumi MZ         if ((pNode->uModifiers & MOD_IGNORE_ALL_MODIFIER))
229bbe5fd52SKatayama Hirofumi MZ         {
230bbe5fd52SKatayama Hirofumi MZ             ;
231bbe5fd52SKatayama Hirofumi MZ         }
232bbe5fd52SKatayama Hirofumi MZ         else if ((pNode->uModifiers & MOD_KEYS) != uModKeys)
233bbe5fd52SKatayama Hirofumi MZ         {
234bbe5fd52SKatayama Hirofumi MZ             continue;
235bbe5fd52SKatayama Hirofumi MZ         }
236bbe5fd52SKatayama Hirofumi MZ         else if ((pNode->uModifiers & uLeftRight) ||
237bbe5fd52SKatayama Hirofumi MZ                  (pNode->uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
238bbe5fd52SKatayama Hirofumi MZ         {
239bbe5fd52SKatayama Hirofumi MZ             ;
240bbe5fd52SKatayama Hirofumi MZ         }
241bbe5fd52SKatayama Hirofumi MZ         else
242bbe5fd52SKatayama Hirofumi MZ         {
243bbe5fd52SKatayama Hirofumi MZ             continue;
244bbe5fd52SKatayama Hirofumi MZ         }
245bbe5fd52SKatayama Hirofumi MZ 
246bbe5fd52SKatayama Hirofumi MZ         LangId = IntGetImeHotKeyLangId(pNode->dwHotKeyId);
247bbe5fd52SKatayama Hirofumi MZ         nScore = IntGetImeHotKeyLanguageScore(hKL, LangId);
248bbe5fd52SKatayama Hirofumi MZ         if (nScore >= 3)
249bbe5fd52SKatayama Hirofumi MZ             return pNode;
250bbe5fd52SKatayama Hirofumi MZ 
251bbe5fd52SKatayama Hirofumi MZ         if (fKorean)
252bbe5fd52SKatayama Hirofumi MZ             continue;
253bbe5fd52SKatayama Hirofumi MZ 
254bbe5fd52SKatayama Hirofumi MZ         if (nScore == 0)
255bbe5fd52SKatayama Hirofumi MZ         {
256bbe5fd52SKatayama Hirofumi MZ             if (pNode->dwHotKeyId == IME_CHOTKEY_IME_NONIME_TOGGLE ||
257bbe5fd52SKatayama Hirofumi MZ                 pNode->dwHotKeyId == IME_THOTKEY_IME_NONIME_TOGGLE)
258bbe5fd52SKatayama Hirofumi MZ             {
259bbe5fd52SKatayama Hirofumi MZ                 if (LOWORD(pti->hklPrev) == LangId)
260bbe5fd52SKatayama Hirofumi MZ                     return pNode;
261bbe5fd52SKatayama Hirofumi MZ             }
262bbe5fd52SKatayama Hirofumi MZ         }
263bbe5fd52SKatayama Hirofumi MZ 
264bbe5fd52SKatayama Hirofumi MZ         if (nMaxScore < nScore)
265bbe5fd52SKatayama Hirofumi MZ         {
266bbe5fd52SKatayama Hirofumi MZ             nMaxScore = nScore;
267bbe5fd52SKatayama Hirofumi MZ             ret = pNode;
268bbe5fd52SKatayama Hirofumi MZ         }
269bbe5fd52SKatayama Hirofumi MZ     }
270bbe5fd52SKatayama Hirofumi MZ 
271bbe5fd52SKatayama Hirofumi MZ     return ret;
272bbe5fd52SKatayama Hirofumi MZ }
273bbe5fd52SKatayama Hirofumi MZ 
2742f7775c6SKatayama Hirofumi MZ // Win: CheckImeHotKey
IntCheckImeHotKey(PUSER_MESSAGE_QUEUE MessageQueue,UINT uVirtualKey,LPARAM lParam)275bbe5fd52SKatayama Hirofumi MZ PIMEHOTKEY IntCheckImeHotKey(PUSER_MESSAGE_QUEUE MessageQueue, UINT uVirtualKey, LPARAM lParam)
276bbe5fd52SKatayama Hirofumi MZ {
277bbe5fd52SKatayama Hirofumi MZ     PIMEHOTKEY pHotKey;
278bbe5fd52SKatayama Hirofumi MZ     UINT uModifiers;
279bbe5fd52SKatayama Hirofumi MZ     BOOL bKeyUp = (lParam & 0x80000000);
280bbe5fd52SKatayama Hirofumi MZ     const BYTE *KeyState = MessageQueue->afKeyState;
281bbe5fd52SKatayama Hirofumi MZ     static UINT s_uKeyUpVKey = 0;
282bbe5fd52SKatayama Hirofumi MZ 
283bbe5fd52SKatayama Hirofumi MZ     if (bKeyUp)
284bbe5fd52SKatayama Hirofumi MZ     {
285bbe5fd52SKatayama Hirofumi MZ         if (s_uKeyUpVKey != uVirtualKey)
286bbe5fd52SKatayama Hirofumi MZ         {
287bbe5fd52SKatayama Hirofumi MZ             s_uKeyUpVKey = 0;
288bbe5fd52SKatayama Hirofumi MZ             return NULL;
289bbe5fd52SKatayama Hirofumi MZ         }
290bbe5fd52SKatayama Hirofumi MZ 
291bbe5fd52SKatayama Hirofumi MZ         s_uKeyUpVKey = 0;
292bbe5fd52SKatayama Hirofumi MZ     }
293bbe5fd52SKatayama Hirofumi MZ 
294bbe5fd52SKatayama Hirofumi MZ     uModifiers = 0;
295bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_LSHIFT))   uModifiers |= (MOD_SHIFT | MOD_LEFT);
296bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_RSHIFT))   uModifiers |= (MOD_SHIFT | MOD_RIGHT);
297bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_LCONTROL)) uModifiers |= (MOD_CONTROL | MOD_LEFT);
298bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_RCONTROL)) uModifiers |= (MOD_CONTROL | MOD_RIGHT);
299bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_LMENU))    uModifiers |= (MOD_ALT | MOD_LEFT);
300bbe5fd52SKatayama Hirofumi MZ     if (IS_KEY_DOWN(KeyState, VK_RMENU))    uModifiers |= (MOD_ALT | MOD_RIGHT);
301bbe5fd52SKatayama Hirofumi MZ 
302bbe5fd52SKatayama Hirofumi MZ     pHotKey = IntGetImeHotKeyByKey(gpImeHotKeyList,
303bbe5fd52SKatayama Hirofumi MZ                                    (uModifiers & MOD_KEYS),
304bbe5fd52SKatayama Hirofumi MZ                                    (uModifiers & MOD_LEFT_RIGHT),
305bbe5fd52SKatayama Hirofumi MZ                                    uVirtualKey);
306bbe5fd52SKatayama Hirofumi MZ     if (pHotKey)
307bbe5fd52SKatayama Hirofumi MZ     {
308bbe5fd52SKatayama Hirofumi MZ         if (bKeyUp)
309bbe5fd52SKatayama Hirofumi MZ         {
310bbe5fd52SKatayama Hirofumi MZ             if (pHotKey->uModifiers & MOD_ON_KEYUP)
311bbe5fd52SKatayama Hirofumi MZ                 return pHotKey;
312bbe5fd52SKatayama Hirofumi MZ         }
313bbe5fd52SKatayama Hirofumi MZ         else
314bbe5fd52SKatayama Hirofumi MZ         {
315bbe5fd52SKatayama Hirofumi MZ             if (pHotKey->uModifiers & MOD_ON_KEYUP)
316bbe5fd52SKatayama Hirofumi MZ                 s_uKeyUpVKey = uVirtualKey;
317bbe5fd52SKatayama Hirofumi MZ             else
318bbe5fd52SKatayama Hirofumi MZ                 return pHotKey;
319bbe5fd52SKatayama Hirofumi MZ         }
320bbe5fd52SKatayama Hirofumi MZ     }
321bbe5fd52SKatayama Hirofumi MZ 
322bbe5fd52SKatayama Hirofumi MZ     return NULL;
323bbe5fd52SKatayama Hirofumi MZ }
324bbe5fd52SKatayama Hirofumi MZ 
3252f7775c6SKatayama Hirofumi MZ // Win: FreeImeHotKeys
IntFreeImeHotKeys(VOID)3265d5cc578SKatayama Hirofumi MZ VOID FASTCALL IntFreeImeHotKeys(VOID)
3275d5cc578SKatayama Hirofumi MZ {
3285d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode, pNext;
3295d5cc578SKatayama Hirofumi MZ     for (pNode = gpImeHotKeyList; pNode; pNode = pNext)
3305d5cc578SKatayama Hirofumi MZ     {
3315d5cc578SKatayama Hirofumi MZ         pNext = pNode->pNext;
3325d5cc578SKatayama Hirofumi MZ         ExFreePoolWithTag(pNode, USERTAG_IMEHOTKEY);
3335d5cc578SKatayama Hirofumi MZ     }
3345d5cc578SKatayama Hirofumi MZ     gpImeHotKeyList = NULL;
3355d5cc578SKatayama Hirofumi MZ }
3365d5cc578SKatayama Hirofumi MZ 
3372f7775c6SKatayama Hirofumi MZ // Win: SetImeHotKey
3385d5cc578SKatayama Hirofumi MZ static BOOL APIENTRY
IntSetImeHotKey(DWORD dwHotKeyId,UINT uModifiers,UINT uVirtualKey,HKL hKL,DWORD dwAction)3395d5cc578SKatayama Hirofumi MZ IntSetImeHotKey(DWORD dwHotKeyId, UINT uModifiers, UINT uVirtualKey, HKL hKL, DWORD dwAction)
3405d5cc578SKatayama Hirofumi MZ {
3415d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
3425d5cc578SKatayama Hirofumi MZ     LANGID LangId;
3435d5cc578SKatayama Hirofumi MZ 
3445d5cc578SKatayama Hirofumi MZ     switch (dwAction)
3455d5cc578SKatayama Hirofumi MZ     {
3465d5cc578SKatayama Hirofumi MZ         case SETIMEHOTKEY_DELETE:
34739fe905eSKatayama Hirofumi MZ             pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId); /* Find hotkey by ID */
3485d5cc578SKatayama Hirofumi MZ             if (!pNode)
349b5c9d532SKatayama Hirofumi MZ             {
350b5c9d532SKatayama Hirofumi MZ                 ERR("dwHotKeyId: 0x%lX\n", dwHotKeyId);
3515d5cc578SKatayama Hirofumi MZ                 return FALSE;
352b5c9d532SKatayama Hirofumi MZ             }
3535d5cc578SKatayama Hirofumi MZ 
35439fe905eSKatayama Hirofumi MZ             IntDeleteImeHotKey(&gpImeHotKeyList, pNode); /* Delete it */
3555d5cc578SKatayama Hirofumi MZ             return TRUE;
3565d5cc578SKatayama Hirofumi MZ 
3575d5cc578SKatayama Hirofumi MZ         case SETIMEHOTKEY_ADD:
35839fe905eSKatayama Hirofumi MZ             if (LOWORD(uVirtualKey) == VK_PACKET) /* In case of VK_PACKET */
3595d5cc578SKatayama Hirofumi MZ                 return FALSE;
3605d5cc578SKatayama Hirofumi MZ 
3615d5cc578SKatayama Hirofumi MZ             LangId = IntGetImeHotKeyLangId(dwHotKeyId);
3625d5cc578SKatayama Hirofumi MZ             if (LangId == LANGID_KOREAN)
36339fe905eSKatayama Hirofumi MZ                 return FALSE; /* Korean can't add IME hotkeys */
3645d5cc578SKatayama Hirofumi MZ 
36539fe905eSKatayama Hirofumi MZ             /* Find hotkey by key and language */
3665d5cc578SKatayama Hirofumi MZ             pNode = IntGetImeHotKeyByKeyAndLang(gpImeHotKeyList,
3675d5cc578SKatayama Hirofumi MZ                                                 (uModifiers & MOD_KEYS),
3685d5cc578SKatayama Hirofumi MZ                                                 (uModifiers & MOD_LEFT_RIGHT),
3695d5cc578SKatayama Hirofumi MZ                                                 uVirtualKey, LangId);
37039fe905eSKatayama Hirofumi MZ             if (pNode == NULL) /* If not found */
37139fe905eSKatayama Hirofumi MZ                 pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId); /* Find by ID */
3725d5cc578SKatayama Hirofumi MZ 
37339fe905eSKatayama Hirofumi MZ             if (pNode) /* Already exists */
3745d5cc578SKatayama Hirofumi MZ             {
3755d5cc578SKatayama Hirofumi MZ                 pNode->uModifiers = uModifiers;
3765d5cc578SKatayama Hirofumi MZ                 pNode->uVirtualKey = uVirtualKey;
3775d5cc578SKatayama Hirofumi MZ                 pNode->hKL = hKL;
3785d5cc578SKatayama Hirofumi MZ                 return TRUE;
3795d5cc578SKatayama Hirofumi MZ             }
3805d5cc578SKatayama Hirofumi MZ 
38139fe905eSKatayama Hirofumi MZ             /* Allocate new hotkey */
3825d5cc578SKatayama Hirofumi MZ             pNode = ExAllocatePoolWithTag(PagedPool, sizeof(IMEHOTKEY), USERTAG_IMEHOTKEY);
3835d5cc578SKatayama Hirofumi MZ             if (!pNode)
3845d5cc578SKatayama Hirofumi MZ                 return FALSE;
3855d5cc578SKatayama Hirofumi MZ 
38639fe905eSKatayama Hirofumi MZ             /* Populate */
3875d5cc578SKatayama Hirofumi MZ             pNode->pNext = NULL;
3885d5cc578SKatayama Hirofumi MZ             pNode->dwHotKeyId = dwHotKeyId;
3895d5cc578SKatayama Hirofumi MZ             pNode->uModifiers = uModifiers;
3905d5cc578SKatayama Hirofumi MZ             pNode->uVirtualKey = uVirtualKey;
3915d5cc578SKatayama Hirofumi MZ             pNode->hKL = hKL;
39239fe905eSKatayama Hirofumi MZ             IntAddImeHotKey(&gpImeHotKeyList, pNode); /* Add it */
3935d5cc578SKatayama Hirofumi MZ             return TRUE;
3945d5cc578SKatayama Hirofumi MZ 
395dff4579bSKatayama Hirofumi MZ         case SETIMEHOTKEY_INITIALIZE:
39639fe905eSKatayama Hirofumi MZ             IntFreeImeHotKeys(); /* Delete all the IME hotkeys */
3975d5cc578SKatayama Hirofumi MZ             return TRUE;
3985d5cc578SKatayama Hirofumi MZ 
3995d5cc578SKatayama Hirofumi MZ         default:
40039fe905eSKatayama Hirofumi MZ             ERR("0x%lX\n", dwAction);
4015d5cc578SKatayama Hirofumi MZ             return FALSE;
4025d5cc578SKatayama Hirofumi MZ     }
4035d5cc578SKatayama Hirofumi MZ }
4045d5cc578SKatayama Hirofumi MZ 
4055d5cc578SKatayama Hirofumi MZ BOOL NTAPI
NtUserGetImeHotKey(DWORD dwHotKeyId,LPUINT lpuModifiers,LPUINT lpuVirtualKey,LPHKL lphKL)4065d5cc578SKatayama Hirofumi MZ NtUserGetImeHotKey(DWORD dwHotKeyId, LPUINT lpuModifiers, LPUINT lpuVirtualKey, LPHKL lphKL)
4075d5cc578SKatayama Hirofumi MZ {
4085d5cc578SKatayama Hirofumi MZ     PIMEHOTKEY pNode = NULL;
4095d5cc578SKatayama Hirofumi MZ 
4105d5cc578SKatayama Hirofumi MZ     UserEnterExclusive();
4115d5cc578SKatayama Hirofumi MZ 
4125d5cc578SKatayama Hirofumi MZ     _SEH2_TRY
4135d5cc578SKatayama Hirofumi MZ     {
4145d5cc578SKatayama Hirofumi MZ         ProbeForWrite(lpuModifiers, sizeof(UINT), 1);
4155d5cc578SKatayama Hirofumi MZ         ProbeForWrite(lpuVirtualKey, sizeof(UINT), 1);
4165d5cc578SKatayama Hirofumi MZ         if (lphKL)
4175d5cc578SKatayama Hirofumi MZ             ProbeForWrite(lphKL, sizeof(HKL), 1);
4185d5cc578SKatayama Hirofumi MZ     }
4195d5cc578SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
4205d5cc578SKatayama Hirofumi MZ     {
4211ef98fffSKatayama Hirofumi MZ         ERR("%p, %p, %p\n", lpuModifiers, lpuVirtualKey, lphKL);
422b3013335SKatayama Hirofumi MZ         _SEH2_YIELD(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     {
4391ef98fffSKatayama Hirofumi MZ         ERR("%p, %p, %p, %p\n", pNode, lpuModifiers, lpuVirtualKey, lphKL);
4405d5cc578SKatayama Hirofumi MZ         pNode = NULL;
4415d5cc578SKatayama Hirofumi MZ     }
4425d5cc578SKatayama Hirofumi MZ     _SEH2_END;
4435d5cc578SKatayama Hirofumi MZ 
4445d5cc578SKatayama Hirofumi MZ Quit:
4455d5cc578SKatayama Hirofumi MZ     UserLeave();
4465d5cc578SKatayama Hirofumi MZ     return !!pNode;
4475d5cc578SKatayama Hirofumi MZ }
4485d5cc578SKatayama Hirofumi MZ 
4495d5cc578SKatayama Hirofumi MZ BOOL
4505d5cc578SKatayama Hirofumi MZ NTAPI
NtUserSetImeHotKey(DWORD dwHotKeyId,UINT uModifiers,UINT uVirtualKey,HKL hKL,DWORD dwAction)4515d5cc578SKatayama Hirofumi MZ NtUserSetImeHotKey(
4525d5cc578SKatayama Hirofumi MZ     DWORD  dwHotKeyId,
4535d5cc578SKatayama Hirofumi MZ     UINT   uModifiers,
4545d5cc578SKatayama Hirofumi MZ     UINT   uVirtualKey,
4555d5cc578SKatayama Hirofumi MZ     HKL    hKL,
4565d5cc578SKatayama Hirofumi MZ     DWORD  dwAction)
4575d5cc578SKatayama Hirofumi MZ {
4585d5cc578SKatayama Hirofumi MZ     BOOL ret;
4595d5cc578SKatayama Hirofumi MZ     UserEnterExclusive();
4605d5cc578SKatayama Hirofumi MZ     ret = IntSetImeHotKey(dwHotKeyId, uModifiers, uVirtualKey, hKL, dwAction);
4615d5cc578SKatayama Hirofumi MZ     UserLeave();
4625d5cc578SKatayama Hirofumi MZ     return ret;
4635d5cc578SKatayama Hirofumi MZ }
4645d5cc578SKatayama Hirofumi MZ 
465bbe5fd52SKatayama Hirofumi MZ DWORD
466bbe5fd52SKatayama Hirofumi MZ NTAPI
NtUserCheckImeHotKey(UINT uVirtualKey,LPARAM lParam)467bbe5fd52SKatayama Hirofumi MZ NtUserCheckImeHotKey(UINT uVirtualKey, LPARAM lParam)
468bbe5fd52SKatayama Hirofumi MZ {
469bbe5fd52SKatayama Hirofumi MZ     PIMEHOTKEY pNode;
470bbe5fd52SKatayama Hirofumi MZ     DWORD ret = INVALID_HOTKEY;
471bbe5fd52SKatayama Hirofumi MZ 
472bbe5fd52SKatayama Hirofumi MZ     UserEnterExclusive();
473bbe5fd52SKatayama Hirofumi MZ 
474bbe5fd52SKatayama Hirofumi MZ     if (!gpqForeground || !IS_IMM_MODE())
475bbe5fd52SKatayama Hirofumi MZ         goto Quit;
476bbe5fd52SKatayama Hirofumi MZ 
477bbe5fd52SKatayama Hirofumi MZ     pNode = IntCheckImeHotKey(gpqForeground, uVirtualKey, lParam);
478bbe5fd52SKatayama Hirofumi MZ     if (pNode)
479bbe5fd52SKatayama Hirofumi MZ         ret = pNode->dwHotKeyId;
480bbe5fd52SKatayama Hirofumi MZ 
481bbe5fd52SKatayama Hirofumi MZ Quit:
482bbe5fd52SKatayama Hirofumi MZ     UserLeave();
483bbe5fd52SKatayama Hirofumi MZ     return ret;
484bbe5fd52SKatayama Hirofumi MZ }
485bbe5fd52SKatayama Hirofumi MZ 
4865df5ef2bSKatayama Hirofumi MZ // Win: GetTopLevelWindow
IntGetTopLevelWindow(PWND pwnd)4870519ae0aSKatayama Hirofumi MZ PWND FASTCALL IntGetTopLevelWindow(PWND pwnd)
4880519ae0aSKatayama Hirofumi MZ {
4890519ae0aSKatayama Hirofumi MZ     if (!pwnd)
4900519ae0aSKatayama Hirofumi MZ         return NULL;
4910519ae0aSKatayama Hirofumi MZ 
4920519ae0aSKatayama Hirofumi MZ     while (pwnd->style & WS_CHILD)
4930519ae0aSKatayama Hirofumi MZ         pwnd = pwnd->spwndParent;
4940519ae0aSKatayama Hirofumi MZ 
4950519ae0aSKatayama Hirofumi MZ     return pwnd;
4960519ae0aSKatayama Hirofumi MZ }
4970519ae0aSKatayama Hirofumi MZ 
4982f7775c6SKatayama Hirofumi MZ // Win: AssociateInputContext
IntAssociateInputContext(PWND pWnd,PIMC pImc)4991bc9dda5SKatayama Hirofumi MZ HIMC FASTCALL IntAssociateInputContext(PWND pWnd, PIMC pImc)
5001bc9dda5SKatayama Hirofumi MZ {
5011bc9dda5SKatayama Hirofumi MZ     HIMC hOldImc = pWnd->hImc;
5021bc9dda5SKatayama Hirofumi MZ     pWnd->hImc = (pImc ? UserHMGetHandle(pImc) : NULL);
5031bc9dda5SKatayama Hirofumi MZ     return hOldImc;
5041bc9dda5SKatayama Hirofumi MZ }
5051bc9dda5SKatayama Hirofumi MZ 
506470aa276SKatayama Hirofumi MZ DWORD
507e52ce89bSKatayama Hirofumi MZ NTAPI
NtUserSetThreadLayoutHandles(HKL hNewKL,HKL hOldKL)508470aa276SKatayama Hirofumi MZ NtUserSetThreadLayoutHandles(HKL hNewKL, HKL hOldKL)
509470aa276SKatayama Hirofumi MZ {
510470aa276SKatayama Hirofumi MZ     PTHREADINFO pti;
511470aa276SKatayama Hirofumi MZ     PKL pOldKL, pNewKL;
512470aa276SKatayama Hirofumi MZ 
513470aa276SKatayama Hirofumi MZ     UserEnterExclusive();
514470aa276SKatayama Hirofumi MZ 
515470aa276SKatayama Hirofumi MZ     pti = GetW32ThreadInfo();
516470aa276SKatayama Hirofumi MZ     pOldKL = pti->KeyboardLayout;
517470aa276SKatayama Hirofumi MZ     if (pOldKL && pOldKL->hkl != hOldKL)
518470aa276SKatayama Hirofumi MZ         goto Quit;
519470aa276SKatayama Hirofumi MZ 
520470aa276SKatayama Hirofumi MZ     pNewKL = UserHklToKbl(hNewKL);
521470aa276SKatayama Hirofumi MZ     if (!pNewKL)
522470aa276SKatayama Hirofumi MZ         goto Quit;
523470aa276SKatayama Hirofumi MZ 
524470aa276SKatayama Hirofumi MZ     if (IS_IME_HKL(hNewKL) != IS_IME_HKL(hOldKL))
525470aa276SKatayama Hirofumi MZ         pti->hklPrev = hOldKL;
526470aa276SKatayama Hirofumi MZ 
5275df5ef2bSKatayama Hirofumi MZ     UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pNewKL);
528f34b8460SKatayama Hirofumi MZ     pti->pClientInfo->hKL = pNewKL->hkl;
529470aa276SKatayama Hirofumi MZ 
530470aa276SKatayama Hirofumi MZ Quit:
531470aa276SKatayama Hirofumi MZ     UserLeave();
532470aa276SKatayama Hirofumi MZ     return 0;
533470aa276SKatayama Hirofumi MZ }
534470aa276SKatayama Hirofumi MZ 
5352f7775c6SKatayama Hirofumi MZ // Win: BuildHimcList
UserBuildHimcList(PTHREADINFO pti,DWORD dwCount,HIMC * phList)536ce6da820SKatayama Hirofumi MZ DWORD FASTCALL UserBuildHimcList(PTHREADINFO pti, DWORD dwCount, HIMC *phList)
537ce6da820SKatayama Hirofumi MZ {
538ce6da820SKatayama Hirofumi MZ     PIMC pIMC;
539ce6da820SKatayama Hirofumi MZ     DWORD dwRealCount = 0;
540ce6da820SKatayama Hirofumi MZ 
541ce6da820SKatayama Hirofumi MZ     if (pti)
542ce6da820SKatayama Hirofumi MZ     {
543ce6da820SKatayama Hirofumi MZ         for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
544ce6da820SKatayama Hirofumi MZ         {
545ce6da820SKatayama Hirofumi MZ             if (dwRealCount < dwCount)
546ce6da820SKatayama Hirofumi MZ                 phList[dwRealCount] = UserHMGetHandle(pIMC);
547ce6da820SKatayama Hirofumi MZ 
548ce6da820SKatayama Hirofumi MZ             ++dwRealCount;
549ce6da820SKatayama Hirofumi MZ         }
550ce6da820SKatayama Hirofumi MZ     }
551ce6da820SKatayama Hirofumi MZ     else
552ce6da820SKatayama Hirofumi MZ     {
553a2c6af0dSKatayama Hirofumi MZ         for (pti = gptiCurrent->ppi->ptiList; pti; pti = pti->ptiSibling)
554ce6da820SKatayama Hirofumi MZ         {
555ce6da820SKatayama Hirofumi MZ             for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
556ce6da820SKatayama Hirofumi MZ             {
557ce6da820SKatayama Hirofumi MZ                 if (dwRealCount < dwCount)
558ce6da820SKatayama Hirofumi MZ                     phList[dwRealCount] = UserHMGetHandle(pIMC);
559ce6da820SKatayama Hirofumi MZ 
560ce6da820SKatayama Hirofumi MZ                 ++dwRealCount;
561ce6da820SKatayama Hirofumi MZ             }
562ce6da820SKatayama Hirofumi MZ         }
563ce6da820SKatayama Hirofumi MZ     }
564ce6da820SKatayama Hirofumi MZ 
565ce6da820SKatayama Hirofumi MZ     return dwRealCount;
566ce6da820SKatayama Hirofumi MZ }
567ce6da820SKatayama Hirofumi MZ 
568c2c66affSColin Finck UINT FASTCALL
IntImmProcessKey(PUSER_MESSAGE_QUEUE MessageQueue,PWND pWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)569b5c9d532SKatayama Hirofumi MZ IntImmProcessKey(PUSER_MESSAGE_QUEUE MessageQueue, PWND pWnd, UINT uMsg,
570b5c9d532SKatayama Hirofumi MZ                  WPARAM wParam, LPARAM lParam)
571c2c66affSColin Finck {
572398201dcSKatayama Hirofumi MZ     UINT uVirtualKey, ret;
573b5c9d532SKatayama Hirofumi MZ     DWORD dwHotKeyId;
574b5c9d532SKatayama Hirofumi MZ     PKL pKL;
575398201dcSKatayama Hirofumi MZ     PIMC pIMC;
576b5c9d532SKatayama Hirofumi MZ     PIMEHOTKEY pImeHotKey;
577b5c9d532SKatayama Hirofumi MZ     HKL hKL;
578b5c9d532SKatayama Hirofumi MZ     HWND hWnd;
579c2c66affSColin Finck 
580c2c66affSColin Finck     ASSERT_REFS_CO(pWnd);
581c2c66affSColin Finck 
582b5c9d532SKatayama Hirofumi MZ     switch (uMsg)
583c2c66affSColin Finck     {
584b5c9d532SKatayama Hirofumi MZ         case WM_KEYDOWN:
585b5c9d532SKatayama Hirofumi MZ         case WM_KEYUP:
586b5c9d532SKatayama Hirofumi MZ         case WM_SYSKEYDOWN:
587b5c9d532SKatayama Hirofumi MZ         case WM_SYSKEYUP:
588b5c9d532SKatayama Hirofumi MZ             break;
589b5c9d532SKatayama Hirofumi MZ 
590b5c9d532SKatayama Hirofumi MZ         default:
591c2c66affSColin Finck             return 0;
592c2c66affSColin Finck     }
593c2c66affSColin Finck 
594398201dcSKatayama Hirofumi MZ     pIMC = NULL;
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 
641398201dcSKatayama Hirofumi MZ         if ((lParam & (KF_UP << 16)) &&
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
NtUserBuildHimcList(DWORD dwThreadId,DWORD dwCount,HIMC * phList,LPDWORD pdwCount)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     {
707a2c6af0dSKatayama Hirofumi MZ         pti = gptiCurrent;
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     {
7281ef98fffSKatayama Hirofumi MZ         ERR("%p, %p\n", phList, pdwCount);
729ef20cc08SKatayama Hirofumi MZ         _SEH2_YIELD(goto Quit);
730ce6da820SKatayama Hirofumi MZ     }
731ce6da820SKatayama Hirofumi MZ     _SEH2_END;
732ce6da820SKatayama Hirofumi MZ 
733ce6da820SKatayama Hirofumi MZ     if (dwCount < dwRealCount)
734ce6da820SKatayama Hirofumi MZ         ret = STATUS_BUFFER_TOO_SMALL;
735ce6da820SKatayama Hirofumi MZ     else
736ce6da820SKatayama Hirofumi MZ         ret = STATUS_SUCCESS;
737ce6da820SKatayama Hirofumi MZ 
738ce6da820SKatayama Hirofumi MZ Quit:
739ce6da820SKatayama Hirofumi MZ     UserLeave();
740ce6da820SKatayama Hirofumi MZ     return ret;
741ce6da820SKatayama Hirofumi MZ }
742ce6da820SKatayama Hirofumi MZ 
7435df5ef2bSKatayama Hirofumi MZ // Win: SetConvMode
UserSetImeConversionKeyState(PTHREADINFO pti,DWORD dwConversion)7449db44371SKatayama Hirofumi MZ static VOID FASTCALL UserSetImeConversionKeyState(PTHREADINFO pti, DWORD dwConversion)
7459db44371SKatayama Hirofumi MZ {
7469db44371SKatayama Hirofumi MZ     HKL hKL;
7479db44371SKatayama Hirofumi MZ     LANGID LangID;
7489db44371SKatayama Hirofumi MZ     LPBYTE KeyState;
7499db44371SKatayama Hirofumi MZ     BOOL bAlphaNumeric, bKatakana, bHiragana, bFullShape, bRoman, bCharCode;
7509db44371SKatayama Hirofumi MZ 
7519db44371SKatayama Hirofumi MZ     if (!pti->KeyboardLayout)
7529db44371SKatayama Hirofumi MZ         return;
7539db44371SKatayama Hirofumi MZ 
7549db44371SKatayama Hirofumi MZ     hKL = pti->KeyboardLayout->hkl;
7559db44371SKatayama Hirofumi MZ     LangID = LOWORD(hKL);
7569db44371SKatayama Hirofumi MZ     KeyState = pti->MessageQueue->afKeyState;
7579db44371SKatayama Hirofumi MZ 
7589db44371SKatayama Hirofumi MZ     switch (PRIMARYLANGID(LangID))
7599db44371SKatayama Hirofumi MZ     {
7609db44371SKatayama Hirofumi MZ         case LANG_JAPANESE:
7619db44371SKatayama Hirofumi MZ             bAlphaNumeric = !(dwConversion & IME_CMODE_NATIVE);
7629db44371SKatayama Hirofumi MZ             bKatakana = !bAlphaNumeric && (dwConversion & IME_CMODE_KATAKANA);
7639db44371SKatayama Hirofumi MZ             bHiragana = !bAlphaNumeric && !(dwConversion & IME_CMODE_KATAKANA);
7649db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
7659db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
7669db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_HIRAGANA, bHiragana);
7679db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_HIRAGANA, bHiragana);
7689db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_KATAKANA, bKatakana);
7699db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_KATAKANA, bKatakana);
7709db44371SKatayama Hirofumi MZ 
7719db44371SKatayama Hirofumi MZ             bFullShape = (dwConversion & IME_CMODE_FULLSHAPE);
7729db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_DBCSCHAR, bFullShape);
7739db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_DBCSCHAR, bFullShape);
7749db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
7759db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
7769db44371SKatayama Hirofumi MZ 
7779db44371SKatayama Hirofumi MZ             bRoman = (dwConversion & IME_CMODE_ROMAN);
7789db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_ROMAN, bRoman);
7799db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_ROMAN, bRoman);
7809db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_NOROMAN, !bRoman);
7819db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_NOROMAN, !bRoman);
7829db44371SKatayama Hirofumi MZ 
7839db44371SKatayama Hirofumi MZ             bCharCode = (dwConversion & IME_CMODE_CHARCODE);
7849db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_CODEINPUT, bCharCode);
7859db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_CODEINPUT, bCharCode);
7869db44371SKatayama Hirofumi MZ             SET_KEY_DOWN(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
7879db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
7889db44371SKatayama Hirofumi MZ             break;
7899db44371SKatayama Hirofumi MZ 
7909db44371SKatayama Hirofumi MZ         case LANG_KOREAN:
7919db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_HANGUL, (dwConversion & IME_CMODE_NATIVE));
7929db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_JUNJA, (dwConversion & IME_CMODE_FULLSHAPE));
7939db44371SKatayama Hirofumi MZ             SET_KEY_LOCKED(KeyState, VK_HANJA, (dwConversion & IME_CMODE_HANJACONVERT));
7949db44371SKatayama Hirofumi MZ             break;
7959db44371SKatayama Hirofumi MZ 
7969db44371SKatayama Hirofumi MZ         default:
7979db44371SKatayama Hirofumi MZ             break;
7989db44371SKatayama Hirofumi MZ     }
7999db44371SKatayama Hirofumi MZ }
8009db44371SKatayama Hirofumi MZ 
801c2c66affSColin Finck DWORD
802e52ce89bSKatayama Hirofumi MZ NTAPI
NtUserNotifyIMEStatus(HWND hwnd,BOOL fOpen,DWORD dwConversion)8039adc538cSKatayama Hirofumi MZ NtUserNotifyIMEStatus(HWND hwnd, BOOL fOpen, DWORD dwConversion)
804c2c66affSColin Finck {
8059db44371SKatayama Hirofumi MZ     PWND pwnd;
8069db44371SKatayama Hirofumi MZ     PTHREADINFO pti;
8079db44371SKatayama Hirofumi MZ     HKL hKL;
8089db44371SKatayama Hirofumi MZ 
8099db44371SKatayama Hirofumi MZ     UserEnterExclusive();
8109db44371SKatayama Hirofumi MZ 
811b5c9d532SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
812b5c9d532SKatayama Hirofumi MZ     {
813b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
814b5c9d532SKatayama Hirofumi MZ         goto Quit;
815b5c9d532SKatayama Hirofumi MZ     }
816b5c9d532SKatayama Hirofumi MZ 
8179db44371SKatayama Hirofumi MZ     pwnd = ValidateHwndNoErr(hwnd);
818b5c9d532SKatayama Hirofumi MZ     if (!pwnd)
8199db44371SKatayama Hirofumi MZ         goto Quit;
8209db44371SKatayama Hirofumi MZ 
8219db44371SKatayama Hirofumi MZ     pti = pwnd->head.pti;
8229db44371SKatayama Hirofumi MZ     if (!pti || !gptiForeground)
8239db44371SKatayama Hirofumi MZ         goto Quit;
8249db44371SKatayama Hirofumi MZ     if (pti != gptiForeground && pti->MessageQueue != gptiForeground->MessageQueue)
8259db44371SKatayama Hirofumi MZ         goto Quit;
8269db44371SKatayama Hirofumi MZ     if (ghIMC == pwnd->hImc && gfImeOpen == !!fOpen && gdwImeConversion == dwConversion)
8279db44371SKatayama Hirofumi MZ         goto Quit;
8289db44371SKatayama Hirofumi MZ 
8299db44371SKatayama Hirofumi MZ     ghIMC = pwnd->hImc;
8309db44371SKatayama Hirofumi MZ     if (ghIMC)
8319db44371SKatayama Hirofumi MZ     {
8329db44371SKatayama Hirofumi MZ         gfImeOpen = !!fOpen;
8339db44371SKatayama Hirofumi MZ         gdwImeConversion = dwConversion;
8349db44371SKatayama Hirofumi MZ         UserSetImeConversionKeyState(pti, (fOpen ? dwConversion : IME_CMODE_ALPHANUMERIC));
8359db44371SKatayama Hirofumi MZ     }
8369db44371SKatayama Hirofumi MZ 
8379db44371SKatayama Hirofumi MZ     if (ISITHOOKED(WH_SHELL))
8389db44371SKatayama Hirofumi MZ     {
8399db44371SKatayama Hirofumi MZ         hKL = (pti->KeyboardLayout ? pti->KeyboardLayout->hkl : NULL);
8409db44371SKatayama Hirofumi MZ         co_HOOK_CallHooks(WH_SHELL, HSHELL_LANGUAGE, (WPARAM)hwnd, (LPARAM)hKL);
8419db44371SKatayama Hirofumi MZ     }
8429db44371SKatayama Hirofumi MZ 
8439db44371SKatayama Hirofumi MZ     // TODO:
8449db44371SKatayama Hirofumi MZ 
8459db44371SKatayama Hirofumi MZ Quit:
8469db44371SKatayama Hirofumi MZ     UserLeave();
847c2c66affSColin Finck     return 0;
848c2c66affSColin Finck }
849c2c66affSColin Finck 
850fcc222c2SKatayama Hirofumi MZ BOOL
851e52ce89bSKatayama Hirofumi MZ NTAPI
NtUserDisableThreadIme(DWORD dwThreadID)852c2c66affSColin Finck NtUserDisableThreadIme(
853fcc222c2SKatayama Hirofumi MZ     DWORD dwThreadID)
854c2c66affSColin Finck {
855fcc222c2SKatayama Hirofumi MZ     PTHREADINFO pti, ptiCurrent;
856fcc222c2SKatayama Hirofumi MZ     PPROCESSINFO ppi;
857fcc222c2SKatayama Hirofumi MZ     BOOL ret = FALSE;
858fcc222c2SKatayama Hirofumi MZ 
859fcc222c2SKatayama Hirofumi MZ     UserEnterExclusive();
860fcc222c2SKatayama Hirofumi MZ 
861fcc222c2SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
862fcc222c2SKatayama Hirofumi MZ     {
863b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
864fcc222c2SKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
865fcc222c2SKatayama Hirofumi MZ         goto Quit;
866fcc222c2SKatayama Hirofumi MZ     }
867fcc222c2SKatayama Hirofumi MZ 
868fcc222c2SKatayama Hirofumi MZ     ptiCurrent = GetW32ThreadInfo();
869fcc222c2SKatayama Hirofumi MZ 
870fcc222c2SKatayama Hirofumi MZ     if (dwThreadID == INVALID_THREAD_ID)
871fcc222c2SKatayama Hirofumi MZ     {
872fcc222c2SKatayama Hirofumi MZ         ppi = ptiCurrent->ppi;
873fcc222c2SKatayama Hirofumi MZ         ppi->W32PF_flags |= W32PF_DISABLEIME;
874fcc222c2SKatayama Hirofumi MZ 
875fcc222c2SKatayama Hirofumi MZ Retry:
876fcc222c2SKatayama Hirofumi MZ         for (pti = ppi->ptiList; pti; pti = pti->ptiSibling)
877fcc222c2SKatayama Hirofumi MZ         {
878fcc222c2SKatayama Hirofumi MZ             pti->TIF_flags |= TIF_DISABLEIME;
879fcc222c2SKatayama Hirofumi MZ 
880fcc222c2SKatayama Hirofumi MZ             if (pti->spwndDefaultIme)
881fcc222c2SKatayama Hirofumi MZ             {
882fcc222c2SKatayama Hirofumi MZ                 co_UserDestroyWindow(pti->spwndDefaultIme);
883fcc222c2SKatayama Hirofumi MZ                 pti->spwndDefaultIme = NULL;
884fcc222c2SKatayama Hirofumi MZ                 goto Retry; /* The contents of ppi->ptiList may be changed. */
885fcc222c2SKatayama Hirofumi MZ             }
886fcc222c2SKatayama Hirofumi MZ         }
887fcc222c2SKatayama Hirofumi MZ     }
888fcc222c2SKatayama Hirofumi MZ     else
889fcc222c2SKatayama Hirofumi MZ     {
890fcc222c2SKatayama Hirofumi MZ         if (dwThreadID == 0)
891fcc222c2SKatayama Hirofumi MZ         {
892fcc222c2SKatayama Hirofumi MZ             pti = ptiCurrent;
893fcc222c2SKatayama Hirofumi MZ         }
894fcc222c2SKatayama Hirofumi MZ         else
895fcc222c2SKatayama Hirofumi MZ         {
896fcc222c2SKatayama Hirofumi MZ             pti = IntTID2PTI(UlongToHandle(dwThreadID));
897fcc222c2SKatayama Hirofumi MZ 
898fcc222c2SKatayama Hirofumi MZ             /* The thread needs to reside in the current process. */
899fcc222c2SKatayama Hirofumi MZ             if (!pti || pti->ppi != ptiCurrent->ppi)
900fcc222c2SKatayama Hirofumi MZ                 goto Quit;
901fcc222c2SKatayama Hirofumi MZ         }
902fcc222c2SKatayama Hirofumi MZ 
903fcc222c2SKatayama Hirofumi MZ         pti->TIF_flags |= TIF_DISABLEIME;
904fcc222c2SKatayama Hirofumi MZ 
905fcc222c2SKatayama Hirofumi MZ         if (pti->spwndDefaultIme)
906fcc222c2SKatayama Hirofumi MZ         {
907fcc222c2SKatayama Hirofumi MZ             co_UserDestroyWindow(pti->spwndDefaultIme);
908fcc222c2SKatayama Hirofumi MZ             pti->spwndDefaultIme = NULL;
909fcc222c2SKatayama Hirofumi MZ         }
910fcc222c2SKatayama Hirofumi MZ     }
911fcc222c2SKatayama Hirofumi MZ 
912fcc222c2SKatayama Hirofumi MZ     ret = TRUE;
913fcc222c2SKatayama Hirofumi MZ 
914fcc222c2SKatayama Hirofumi MZ Quit:
915fcc222c2SKatayama Hirofumi MZ     UserLeave();
916fcc222c2SKatayama Hirofumi MZ     return ret;
917c2c66affSColin Finck }
918c2c66affSColin Finck 
919c2c66affSColin Finck DWORD
920e52ce89bSKatayama Hirofumi MZ NTAPI
NtUserGetAppImeLevel(HWND hWnd)921f4bc74edSKatayama Hirofumi MZ NtUserGetAppImeLevel(HWND hWnd)
922c2c66affSColin Finck {
9239c8167e9SKatayama Hirofumi MZ     DWORD ret = 0;
9249c8167e9SKatayama Hirofumi MZ     PWND pWnd;
9259c8167e9SKatayama Hirofumi MZ     PTHREADINFO pti;
9269c8167e9SKatayama Hirofumi MZ 
9279c8167e9SKatayama Hirofumi MZ     UserEnterShared();
9289c8167e9SKatayama Hirofumi MZ 
9299c8167e9SKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
9309c8167e9SKatayama Hirofumi MZ     if (!pWnd)
9319c8167e9SKatayama Hirofumi MZ         goto Quit;
9329c8167e9SKatayama Hirofumi MZ 
9339c8167e9SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
9349c8167e9SKatayama Hirofumi MZ     {
935b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
9369c8167e9SKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
9379c8167e9SKatayama Hirofumi MZ         goto Quit;
9389c8167e9SKatayama Hirofumi MZ     }
9399c8167e9SKatayama Hirofumi MZ 
9409c8167e9SKatayama Hirofumi MZ     pti = PsGetCurrentThreadWin32Thread();
9419c8167e9SKatayama Hirofumi MZ     if (pWnd->head.pti->ppi == pti->ppi)
942*ec24b547SKatayama Hirofumi MZ         ret = HandleToUlong(UserGetProp(pWnd, AtomImeLevel, TRUE));
9439c8167e9SKatayama Hirofumi MZ 
9449c8167e9SKatayama Hirofumi MZ Quit:
9459c8167e9SKatayama Hirofumi MZ     UserLeave();
9469c8167e9SKatayama Hirofumi MZ     return ret;
947c2c66affSColin Finck }
948c2c66affSColin Finck 
9492f7775c6SKatayama Hirofumi MZ // Win: GetImeInfoEx
9509e7c2ba4SKatayama Hirofumi MZ BOOL FASTCALL
UserGetImeInfoEx(_Inout_ PWINSTATION_OBJECT pWinSta,_Inout_ PIMEINFOEX pInfoEx,_In_ IMEINFOEXCLASS SearchType)9519e7c2ba4SKatayama Hirofumi MZ UserGetImeInfoEx(
9529e7c2ba4SKatayama Hirofumi MZ     _Inout_ PWINSTATION_OBJECT pWinSta,
9539e7c2ba4SKatayama Hirofumi MZ     _Inout_ PIMEINFOEX pInfoEx,
9549e7c2ba4SKatayama Hirofumi MZ     _In_ IMEINFOEXCLASS SearchType)
95536740ca9SKatayama Hirofumi MZ {
95636740ca9SKatayama Hirofumi MZ     PKL pkl, pklHead;
95736740ca9SKatayama Hirofumi MZ 
9589e7c2ba4SKatayama Hirofumi MZ     if (!pWinSta || !gspklBaseLayout)
95936740ca9SKatayama Hirofumi MZ         return FALSE;
96036740ca9SKatayama Hirofumi MZ 
96136740ca9SKatayama Hirofumi MZ     pkl = pklHead = gspklBaseLayout;
96236740ca9SKatayama Hirofumi MZ 
96336740ca9SKatayama Hirofumi MZ     /* Find the matching entry from the list and get info */
96436740ca9SKatayama Hirofumi MZ     if (SearchType == ImeInfoExKeyboardLayout)
96536740ca9SKatayama Hirofumi MZ     {
96636740ca9SKatayama Hirofumi MZ         do
96736740ca9SKatayama Hirofumi MZ         {
96828959a2dSKatayama Hirofumi MZ             if (pInfoEx->hkl == pkl->hkl)
96936740ca9SKatayama Hirofumi MZ             {
97036740ca9SKatayama Hirofumi MZ                 if (!pkl->piiex)
9719e7c2ba4SKatayama Hirofumi MZ                 {
9729e7c2ba4SKatayama Hirofumi MZ                     ERR("!pkl->piiex at %p\n", pkl->hkl);
97336740ca9SKatayama Hirofumi MZ                     break;
9749e7c2ba4SKatayama Hirofumi MZ                 }
97536740ca9SKatayama Hirofumi MZ 
97628959a2dSKatayama Hirofumi MZ                 *pInfoEx = *pkl->piiex;
97728959a2dSKatayama Hirofumi MZ                 return TRUE;
97836740ca9SKatayama Hirofumi MZ             }
97936740ca9SKatayama Hirofumi MZ 
98036740ca9SKatayama Hirofumi MZ             pkl = pkl->pklNext;
98136740ca9SKatayama Hirofumi MZ         } while (pkl != pklHead);
98236740ca9SKatayama Hirofumi MZ     }
98336740ca9SKatayama Hirofumi MZ     else if (SearchType == ImeInfoExImeFileName)
98436740ca9SKatayama Hirofumi MZ     {
98536740ca9SKatayama Hirofumi MZ         do
98636740ca9SKatayama Hirofumi MZ         {
987c7ba53e3SKatayama Hirofumi MZ             if (pkl->piiex &&
988c7ba53e3SKatayama Hirofumi MZ                 _wcsnicmp(pkl->piiex->wszImeFile, pInfoEx->wszImeFile,
98928959a2dSKatayama Hirofumi MZ                           RTL_NUMBER_OF(pkl->piiex->wszImeFile)) == 0)
99036740ca9SKatayama Hirofumi MZ             {
99128959a2dSKatayama Hirofumi MZ                 *pInfoEx = *pkl->piiex;
99228959a2dSKatayama Hirofumi MZ                 return TRUE;
99336740ca9SKatayama Hirofumi MZ             }
99436740ca9SKatayama Hirofumi MZ 
99536740ca9SKatayama Hirofumi MZ             pkl = pkl->pklNext;
99636740ca9SKatayama Hirofumi MZ         } while (pkl != pklHead);
99736740ca9SKatayama Hirofumi MZ     }
99836740ca9SKatayama Hirofumi MZ     else
99936740ca9SKatayama Hirofumi MZ     {
1000c7ba53e3SKatayama Hirofumi MZ         ERR("SearchType: %d\n", SearchType);
100136740ca9SKatayama Hirofumi MZ     }
100236740ca9SKatayama Hirofumi MZ 
100328959a2dSKatayama Hirofumi MZ     return FALSE;
100436740ca9SKatayama Hirofumi MZ }
100536740ca9SKatayama Hirofumi MZ 
10064b038ec8SKatayama Hirofumi MZ BOOL
1007e52ce89bSKatayama Hirofumi MZ NTAPI
NtUserGetImeInfoEx(PIMEINFOEX pImeInfoEx,IMEINFOEXCLASS SearchType)1008c2c66affSColin Finck NtUserGetImeInfoEx(
1009c2c66affSColin Finck     PIMEINFOEX pImeInfoEx,
10104b038ec8SKatayama Hirofumi MZ     IMEINFOEXCLASS SearchType)
1011c2c66affSColin Finck {
101236740ca9SKatayama Hirofumi MZ     IMEINFOEX ImeInfoEx;
101336740ca9SKatayama Hirofumi MZ     BOOL ret = FALSE;
10149e7c2ba4SKatayama Hirofumi MZ     PWINSTATION_OBJECT pWinSta;
101536740ca9SKatayama Hirofumi MZ 
101636740ca9SKatayama Hirofumi MZ     UserEnterShared();
101736740ca9SKatayama Hirofumi MZ 
101836740ca9SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1019b5c9d532SKatayama Hirofumi MZ     {
1020b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
102136740ca9SKatayama Hirofumi MZ         goto Quit;
1022b5c9d532SKatayama Hirofumi MZ     }
102336740ca9SKatayama Hirofumi MZ 
102436740ca9SKatayama Hirofumi MZ     _SEH2_TRY
102536740ca9SKatayama Hirofumi MZ     {
10261ef98fffSKatayama Hirofumi MZ         ProbeForRead(pImeInfoEx, sizeof(*pImeInfoEx), 1);
102736740ca9SKatayama Hirofumi MZ         ImeInfoEx = *pImeInfoEx;
102836740ca9SKatayama Hirofumi MZ     }
102936740ca9SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
103036740ca9SKatayama Hirofumi MZ     {
10311ef98fffSKatayama Hirofumi MZ         ERR("%p\n", pImeInfoEx);
1032ed5098b2SKatayama Hirofumi MZ         _SEH2_YIELD(goto Quit);
103336740ca9SKatayama Hirofumi MZ     }
103436740ca9SKatayama Hirofumi MZ     _SEH2_END;
103536740ca9SKatayama Hirofumi MZ 
10369e7c2ba4SKatayama Hirofumi MZ     pWinSta = IntGetProcessWindowStation(NULL);
10379e7c2ba4SKatayama Hirofumi MZ     ret = UserGetImeInfoEx(pWinSta, &ImeInfoEx, SearchType);
1038e52ce89bSKatayama Hirofumi MZ     if (!ret)
1039e52ce89bSKatayama Hirofumi MZ         goto Quit;
1040e52ce89bSKatayama Hirofumi MZ 
104136740ca9SKatayama Hirofumi MZ     _SEH2_TRY
104236740ca9SKatayama Hirofumi MZ     {
10431ef98fffSKatayama Hirofumi MZ         ProbeForWrite(pImeInfoEx, sizeof(*pImeInfoEx), 1);
104436740ca9SKatayama Hirofumi MZ         *pImeInfoEx = ImeInfoEx;
104536740ca9SKatayama Hirofumi MZ     }
104636740ca9SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
104736740ca9SKatayama Hirofumi MZ     {
10481ef98fffSKatayama Hirofumi MZ         ERR("%p\n", pImeInfoEx);
104936740ca9SKatayama Hirofumi MZ         ret = FALSE;
105036740ca9SKatayama Hirofumi MZ     }
105136740ca9SKatayama Hirofumi MZ     _SEH2_END;
1052c2c66affSColin Finck 
105336740ca9SKatayama Hirofumi MZ Quit:
105436740ca9SKatayama Hirofumi MZ     UserLeave();
105536740ca9SKatayama Hirofumi MZ     return ret;
105636740ca9SKatayama Hirofumi MZ }
1057c2c66affSColin Finck 
10589c8167e9SKatayama Hirofumi MZ BOOL
1059e52ce89bSKatayama Hirofumi MZ NTAPI
NtUserSetAppImeLevel(HWND hWnd,DWORD dwLevel)10609c8167e9SKatayama Hirofumi MZ NtUserSetAppImeLevel(HWND hWnd, DWORD dwLevel)
1061c2c66affSColin Finck {
10629c8167e9SKatayama Hirofumi MZ     BOOL ret = FALSE;
10639c8167e9SKatayama Hirofumi MZ     PWND pWnd;
10649c8167e9SKatayama Hirofumi MZ     PTHREADINFO pti;
10659c8167e9SKatayama Hirofumi MZ 
10669c8167e9SKatayama Hirofumi MZ     UserEnterExclusive();
10679c8167e9SKatayama Hirofumi MZ 
10689c8167e9SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
10699c8167e9SKatayama Hirofumi MZ     {
1070b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
10719c8167e9SKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
10729c8167e9SKatayama Hirofumi MZ         goto Quit;
10739c8167e9SKatayama Hirofumi MZ     }
10749c8167e9SKatayama Hirofumi MZ 
1075b5c9d532SKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
1076b5c9d532SKatayama Hirofumi MZ     if (!pWnd)
1077b5c9d532SKatayama Hirofumi MZ         goto Quit;
1078b5c9d532SKatayama Hirofumi MZ 
10799c8167e9SKatayama Hirofumi MZ     pti = PsGetCurrentThreadWin32Thread();
10809c8167e9SKatayama Hirofumi MZ     if (pWnd->head.pti->ppi == pti->ppi)
1081*ec24b547SKatayama Hirofumi MZ         ret = UserSetProp(pWnd, AtomImeLevel, UlongToHandle(dwLevel), TRUE);
10829c8167e9SKatayama Hirofumi MZ 
10839c8167e9SKatayama Hirofumi MZ Quit:
10849c8167e9SKatayama Hirofumi MZ     UserLeave();
10859c8167e9SKatayama Hirofumi MZ     return ret;
1086c2c66affSColin Finck }
1087c2c66affSColin Finck 
10882f7775c6SKatayama Hirofumi MZ // Win: SetImeInfoEx
10899e7c2ba4SKatayama Hirofumi MZ BOOL FASTCALL
UserSetImeInfoEx(_Inout_ PWINSTATION_OBJECT pWinSta,_Inout_ PIMEINFOEX pImeInfoEx)10909e7c2ba4SKatayama Hirofumi MZ UserSetImeInfoEx(
10919e7c2ba4SKatayama Hirofumi MZ     _Inout_ PWINSTATION_OBJECT pWinSta,
10929e7c2ba4SKatayama Hirofumi MZ     _Inout_ PIMEINFOEX pImeInfoEx)
1093c2c66affSColin Finck {
10941f446936SKatayama Hirofumi MZ     PKL pklHead, pkl;
10951f446936SKatayama Hirofumi MZ 
10969e7c2ba4SKatayama Hirofumi MZ     if (!pWinSta || !gspklBaseLayout)
10979e7c2ba4SKatayama Hirofumi MZ         return FALSE;
10989e7c2ba4SKatayama Hirofumi MZ 
10991f446936SKatayama Hirofumi MZ     pkl = pklHead = gspklBaseLayout;
11001f446936SKatayama Hirofumi MZ 
11011f446936SKatayama Hirofumi MZ     do
11021f446936SKatayama Hirofumi MZ     {
11031f446936SKatayama Hirofumi MZ         if (pkl->hkl != pImeInfoEx->hkl)
11041f446936SKatayama Hirofumi MZ         {
11051f446936SKatayama Hirofumi MZ             pkl = pkl->pklNext;
11061f446936SKatayama Hirofumi MZ             continue;
11071f446936SKatayama Hirofumi MZ         }
11081f446936SKatayama Hirofumi MZ 
11091f446936SKatayama Hirofumi MZ         if (!pkl->piiex)
11109e7c2ba4SKatayama Hirofumi MZ         {
11119e7c2ba4SKatayama Hirofumi MZ             ERR("!pkl->piiex at %p\n", pkl->hkl);
11121f446936SKatayama Hirofumi MZ             return FALSE;
11139e7c2ba4SKatayama Hirofumi MZ         }
11141f446936SKatayama Hirofumi MZ 
11151f446936SKatayama Hirofumi MZ         if (!pkl->piiex->fLoadFlag)
11161f446936SKatayama Hirofumi MZ             *pkl->piiex = *pImeInfoEx;
11171f446936SKatayama Hirofumi MZ 
11181f446936SKatayama Hirofumi MZ         return TRUE;
11191f446936SKatayama Hirofumi MZ     } while (pkl != pklHead);
11201f446936SKatayama Hirofumi MZ 
11211f446936SKatayama Hirofumi MZ     return FALSE;
11221f446936SKatayama Hirofumi MZ }
11231f446936SKatayama Hirofumi MZ 
11241f446936SKatayama Hirofumi MZ BOOL
1125e52ce89bSKatayama Hirofumi MZ NTAPI
NtUserSetImeInfoEx(PIMEINFOEX pImeInfoEx)11261f446936SKatayama Hirofumi MZ NtUserSetImeInfoEx(PIMEINFOEX pImeInfoEx)
11271f446936SKatayama Hirofumi MZ {
11281f446936SKatayama Hirofumi MZ     BOOL ret = FALSE;
11291f446936SKatayama Hirofumi MZ     IMEINFOEX ImeInfoEx;
11309e7c2ba4SKatayama Hirofumi MZ     PWINSTATION_OBJECT pWinSta;
11311f446936SKatayama Hirofumi MZ 
11321f446936SKatayama Hirofumi MZ     UserEnterExclusive();
11331f446936SKatayama Hirofumi MZ 
11341f446936SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1135b5c9d532SKatayama Hirofumi MZ     {
1136b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
11371f446936SKatayama Hirofumi MZ         goto Quit;
1138b5c9d532SKatayama Hirofumi MZ     }
11391f446936SKatayama Hirofumi MZ 
11401f446936SKatayama Hirofumi MZ     _SEH2_TRY
11411f446936SKatayama Hirofumi MZ     {
11421f446936SKatayama Hirofumi MZ         ProbeForRead(pImeInfoEx, sizeof(*pImeInfoEx), 1);
11431f446936SKatayama Hirofumi MZ         ImeInfoEx = *pImeInfoEx;
11441f446936SKatayama Hirofumi MZ     }
11451f446936SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
11461f446936SKatayama Hirofumi MZ     {
11471ef98fffSKatayama Hirofumi MZ         ERR("%p\n", pImeInfoEx);
11480694b559SKatayama Hirofumi MZ         _SEH2_YIELD(goto Quit);
11491f446936SKatayama Hirofumi MZ     }
11501f446936SKatayama Hirofumi MZ     _SEH2_END;
11511f446936SKatayama Hirofumi MZ 
11529e7c2ba4SKatayama Hirofumi MZ     pWinSta = IntGetProcessWindowStation(NULL);
11539e7c2ba4SKatayama Hirofumi MZ     ret = UserSetImeInfoEx(pWinSta, &ImeInfoEx);
11541f446936SKatayama Hirofumi MZ 
11551f446936SKatayama Hirofumi MZ Quit:
11561f446936SKatayama Hirofumi MZ     UserLeave();
11571f446936SKatayama Hirofumi MZ     return ret;
1158c2c66affSColin Finck }
1159c2c66affSColin Finck 
1160291a94cdSKatayama Hirofumi MZ // Choose the preferred owner of the IME window.
1161291a94cdSKatayama Hirofumi MZ // Win: ImeSetFutureOwner
IntImeSetFutureOwner(PWND pImeWnd,PWND pwndOwner)1162291a94cdSKatayama Hirofumi MZ VOID FASTCALL IntImeSetFutureOwner(PWND pImeWnd, PWND pwndOwner)
1163291a94cdSKatayama Hirofumi MZ {
1164291a94cdSKatayama Hirofumi MZ     PWND pwndNode, pwndNextOwner, pwndParent, pwndSibling;
1165291a94cdSKatayama Hirofumi MZ     PTHREADINFO pti = pImeWnd->head.pti;
1166291a94cdSKatayama Hirofumi MZ 
1167291a94cdSKatayama Hirofumi MZ     if (!pwndOwner || (pwndOwner->style & WS_CHILD)) // invalid owner
1168291a94cdSKatayama Hirofumi MZ         return;
1169291a94cdSKatayama Hirofumi MZ 
1170291a94cdSKatayama Hirofumi MZ     // Get the top-level owner of the same thread
1171291a94cdSKatayama Hirofumi MZ     for (pwndNode = pwndOwner; ; pwndNode = pwndNextOwner)
1172291a94cdSKatayama Hirofumi MZ     {
1173291a94cdSKatayama Hirofumi MZ         pwndNextOwner = pwndNode->spwndOwner;
1174291a94cdSKatayama Hirofumi MZ         if (!pwndNextOwner || pwndNextOwner->head.pti != pti)
1175291a94cdSKatayama Hirofumi MZ             break;
1176291a94cdSKatayama Hirofumi MZ     }
1177291a94cdSKatayama Hirofumi MZ 
1178291a94cdSKatayama Hirofumi MZ     // Don't choose the IME-like windows and the bottom-most windows unless necessary.
1179291a94cdSKatayama Hirofumi MZ     if (IS_WND_IMELIKE(pwndNode) ||
1180291a94cdSKatayama Hirofumi MZ         ((pwndNode->state2 & WNDS2_BOTTOMMOST) && !(pwndOwner->state2 & WNDS2_BOTTOMMOST)))
1181291a94cdSKatayama Hirofumi MZ     {
1182291a94cdSKatayama Hirofumi MZ         pwndNode = pwndOwner;
1183291a94cdSKatayama Hirofumi MZ     }
1184291a94cdSKatayama Hirofumi MZ 
1185291a94cdSKatayama Hirofumi MZ     pwndParent = pwndNode->spwndParent;
1186291a94cdSKatayama Hirofumi MZ     if (!pwndParent || pwndOwner != pwndNode)
1187291a94cdSKatayama Hirofumi MZ     {
1188e56da485STimo Kreuzer         WndSetOwner(pImeWnd, pwndNode);
1189291a94cdSKatayama Hirofumi MZ         return;
1190291a94cdSKatayama Hirofumi MZ     }
1191291a94cdSKatayama Hirofumi MZ 
1192291a94cdSKatayama Hirofumi MZ     for (pwndSibling = pwndParent->spwndChild; pwndSibling; pwndSibling = pwndSibling->spwndNext)
1193291a94cdSKatayama Hirofumi MZ     {
1194291a94cdSKatayama Hirofumi MZ         if (pwndNode->head.pti != pwndSibling->head.pti)
1195291a94cdSKatayama Hirofumi MZ             continue;
1196291a94cdSKatayama Hirofumi MZ 
1197291a94cdSKatayama Hirofumi MZ         if (IS_WND_MENU(pwndSibling) || IS_WND_IMELIKE(pwndSibling))
1198291a94cdSKatayama Hirofumi MZ             continue;
1199291a94cdSKatayama Hirofumi MZ 
1200291a94cdSKatayama Hirofumi MZ         if (pwndSibling->state2 & WNDS2_INDESTROY)
1201291a94cdSKatayama Hirofumi MZ             continue;
1202291a94cdSKatayama Hirofumi MZ 
1203291a94cdSKatayama Hirofumi MZ         if (pwndNode == pwndSibling || (pwndSibling->style & WS_CHILD))
1204291a94cdSKatayama Hirofumi MZ             continue;
1205291a94cdSKatayama Hirofumi MZ 
1206291a94cdSKatayama Hirofumi MZ         if (pwndSibling->spwndOwner == NULL ||
1207291a94cdSKatayama Hirofumi MZ             pwndSibling->head.pti != pwndSibling->spwndOwner->head.pti)
1208291a94cdSKatayama Hirofumi MZ         {
1209291a94cdSKatayama Hirofumi MZ             pwndNode = pwndSibling;
1210291a94cdSKatayama Hirofumi MZ             break;
1211291a94cdSKatayama Hirofumi MZ         }
1212291a94cdSKatayama Hirofumi MZ     }
1213291a94cdSKatayama Hirofumi MZ 
1214e56da485STimo Kreuzer     WndSetOwner(pImeWnd, pwndNode);
1215291a94cdSKatayama Hirofumi MZ }
1216291a94cdSKatayama Hirofumi MZ 
1217291a94cdSKatayama Hirofumi MZ // Get the last non-IME-like top-most window on the desktop.
1218291a94cdSKatayama Hirofumi MZ // Win: GetLastTopMostWindowNoIME
IntGetLastTopMostWindowNoIME(PWND pImeWnd)1219291a94cdSKatayama Hirofumi MZ PWND FASTCALL IntGetLastTopMostWindowNoIME(PWND pImeWnd)
1220291a94cdSKatayama Hirofumi MZ {
1221291a94cdSKatayama Hirofumi MZ     PWND pwndNode, pwndOwner, pwndLastTopMost = NULL;
1222291a94cdSKatayama Hirofumi MZ     BOOL bFound;
1223291a94cdSKatayama Hirofumi MZ 
1224291a94cdSKatayama Hirofumi MZ     pwndNode = UserGetDesktopWindow();
1225291a94cdSKatayama Hirofumi MZ     if (!pwndNode || pwndNode->spwndChild == NULL)
1226291a94cdSKatayama Hirofumi MZ         return NULL;
1227291a94cdSKatayama Hirofumi MZ 
1228291a94cdSKatayama Hirofumi MZ     for (pwndNode = pwndNode->spwndChild;
1229291a94cdSKatayama Hirofumi MZ          pwndNode && (pwndNode->ExStyle & WS_EX_TOPMOST);
1230291a94cdSKatayama Hirofumi MZ          pwndNode = pwndNode->spwndNext)
1231291a94cdSKatayama Hirofumi MZ     {
1232291a94cdSKatayama Hirofumi MZ         bFound = FALSE;
1233291a94cdSKatayama Hirofumi MZ 
1234291a94cdSKatayama Hirofumi MZ         if (IS_WND_IMELIKE(pwndNode)) // An IME-like window
1235291a94cdSKatayama Hirofumi MZ         {
1236291a94cdSKatayama Hirofumi MZ             // Search the IME window from owners
1237291a94cdSKatayama Hirofumi MZ             for (pwndOwner = pwndNode; pwndOwner; pwndOwner = pwndOwner->spwndOwner)
1238291a94cdSKatayama Hirofumi MZ             {
1239291a94cdSKatayama Hirofumi MZ                 if (pImeWnd == pwndOwner)
1240291a94cdSKatayama Hirofumi MZ                 {
1241291a94cdSKatayama Hirofumi MZ                     bFound = TRUE;
1242291a94cdSKatayama Hirofumi MZ                     break;
1243291a94cdSKatayama Hirofumi MZ                 }
1244291a94cdSKatayama Hirofumi MZ             }
1245291a94cdSKatayama Hirofumi MZ         }
1246291a94cdSKatayama Hirofumi MZ 
1247291a94cdSKatayama Hirofumi MZ         if (!bFound)
1248291a94cdSKatayama Hirofumi MZ             pwndLastTopMost = pwndNode;
1249291a94cdSKatayama Hirofumi MZ     }
1250291a94cdSKatayama Hirofumi MZ 
1251291a94cdSKatayama Hirofumi MZ     return pwndLastTopMost;
1252291a94cdSKatayama Hirofumi MZ }
1253291a94cdSKatayama Hirofumi MZ 
1254291a94cdSKatayama Hirofumi MZ // Adjust the ordering of the windows around the IME window.
1255291a94cdSKatayama Hirofumi MZ // Win: ImeSetTopMost
IntImeSetTopMost(PWND pImeWnd,BOOL bTopMost,PWND pwndInsertBefore)1256291a94cdSKatayama Hirofumi MZ VOID FASTCALL IntImeSetTopMost(PWND pImeWnd, BOOL bTopMost, PWND pwndInsertBefore)
1257291a94cdSKatayama Hirofumi MZ {
1258291a94cdSKatayama Hirofumi MZ     PWND pwndParent, pwndChild, pwndNode, pwndNext, pwndInsertAfter = NULL;
1259291a94cdSKatayama Hirofumi MZ     PWND pwndInsertAfterSave;
1260291a94cdSKatayama Hirofumi MZ 
1261291a94cdSKatayama Hirofumi MZ     pwndParent = pImeWnd->spwndParent;
1262291a94cdSKatayama Hirofumi MZ     if (!pwndParent)
1263291a94cdSKatayama Hirofumi MZ         return;
1264291a94cdSKatayama Hirofumi MZ 
1265291a94cdSKatayama Hirofumi MZ     pwndChild = pwndParent->spwndChild;
1266291a94cdSKatayama Hirofumi MZ 
1267291a94cdSKatayama Hirofumi MZ     if (!bTopMost)
1268291a94cdSKatayama Hirofumi MZ     {
1269291a94cdSKatayama Hirofumi MZ         // Calculate pwndInsertAfter
1270291a94cdSKatayama Hirofumi MZ         pwndInsertAfter = IntGetLastTopMostWindowNoIME(pImeWnd);
1271291a94cdSKatayama Hirofumi MZ         if (pwndInsertBefore)
1272291a94cdSKatayama Hirofumi MZ         {
1273291a94cdSKatayama Hirofumi MZ             for (pwndNode = pwndInsertAfter; pwndNode; pwndNode = pwndNode->spwndNext)
1274291a94cdSKatayama Hirofumi MZ             {
1275291a94cdSKatayama Hirofumi MZ                 if (pwndNode->spwndNext == pwndInsertBefore)
1276291a94cdSKatayama Hirofumi MZ                     break;
1277291a94cdSKatayama Hirofumi MZ 
1278291a94cdSKatayama Hirofumi MZ                 if (pwndNode == pImeWnd)
1279291a94cdSKatayama Hirofumi MZ                     return;
1280291a94cdSKatayama Hirofumi MZ             }
1281291a94cdSKatayama Hirofumi MZ 
1282291a94cdSKatayama Hirofumi MZ             if (!pwndNode)
1283291a94cdSKatayama Hirofumi MZ                 return;
1284291a94cdSKatayama Hirofumi MZ 
1285291a94cdSKatayama Hirofumi MZ             pwndInsertAfter = pwndNode;
1286291a94cdSKatayama Hirofumi MZ         }
1287291a94cdSKatayama Hirofumi MZ 
1288291a94cdSKatayama Hirofumi MZ         // Adjust pwndInsertAfter if the owner is bottom-most
1289291a94cdSKatayama Hirofumi MZ         if (pImeWnd->spwndOwner->state2 & WNDS2_BOTTOMMOST)
1290291a94cdSKatayama Hirofumi MZ         {
1291291a94cdSKatayama Hirofumi MZ             for (pwndNode = pwndInsertAfter; pwndNode; pwndNode = pwndNode->spwndNext)
1292291a94cdSKatayama Hirofumi MZ             {
1293291a94cdSKatayama Hirofumi MZ                 if (pwndNode == pImeWnd->spwndOwner)
1294291a94cdSKatayama Hirofumi MZ                     break;
1295291a94cdSKatayama Hirofumi MZ 
1296291a94cdSKatayama Hirofumi MZ                 if (!IS_WND_IMELIKE(pwndNode))
1297291a94cdSKatayama Hirofumi MZ                     pwndInsertAfter = pwndNode;
1298291a94cdSKatayama Hirofumi MZ             }
1299291a94cdSKatayama Hirofumi MZ         }
1300291a94cdSKatayama Hirofumi MZ     }
1301291a94cdSKatayama Hirofumi MZ 
1302291a94cdSKatayama Hirofumi MZ     pwndInsertAfterSave = pwndInsertAfter;
1303291a94cdSKatayama Hirofumi MZ 
1304291a94cdSKatayama Hirofumi MZ     while (pwndChild)
1305291a94cdSKatayama Hirofumi MZ     {
1306291a94cdSKatayama Hirofumi MZ         pwndNext = pwndChild->spwndNext;
1307291a94cdSKatayama Hirofumi MZ 
1308291a94cdSKatayama Hirofumi MZ         // If pwndChild is a good IME-like window, ...
1309291a94cdSKatayama Hirofumi MZ         if (IS_WND_IMELIKE(pwndChild) && pwndChild != pwndInsertAfter &&
1310291a94cdSKatayama Hirofumi MZ             pwndChild->head.pti == pImeWnd->head.pti)
1311291a94cdSKatayama Hirofumi MZ         {
1312291a94cdSKatayama Hirofumi MZ             // Find pImeWnd from the owners
1313291a94cdSKatayama Hirofumi MZ             for (pwndNode = pwndChild; pwndNode; pwndNode = pwndNode->spwndOwner)
1314291a94cdSKatayama Hirofumi MZ             {
1315291a94cdSKatayama Hirofumi MZ                 if (pwndNode != pImeWnd)
1316291a94cdSKatayama Hirofumi MZ                     continue;
1317291a94cdSKatayama Hirofumi MZ 
1318291a94cdSKatayama Hirofumi MZ                 // Adjust the ordering and the linking
1319291a94cdSKatayama Hirofumi MZ                 IntUnlinkWindow(pwndChild);
1320291a94cdSKatayama Hirofumi MZ 
1321291a94cdSKatayama Hirofumi MZ                 if (bTopMost)
1322291a94cdSKatayama Hirofumi MZ                     pwndChild->ExStyle |= WS_EX_TOPMOST;
1323291a94cdSKatayama Hirofumi MZ                 else
1324291a94cdSKatayama Hirofumi MZ                     pwndChild->ExStyle &= ~WS_EX_TOPMOST;
1325291a94cdSKatayama Hirofumi MZ 
1326291a94cdSKatayama Hirofumi MZ                 if (!pwndInsertAfter)
1327291a94cdSKatayama Hirofumi MZ                     IntLinkHwnd(pwndChild, HWND_TOP);
1328291a94cdSKatayama Hirofumi MZ                 else
1329291a94cdSKatayama Hirofumi MZ                     IntLinkHwnd(pwndChild, UserHMGetHandle(pwndInsertAfter));
1330291a94cdSKatayama Hirofumi MZ 
1331291a94cdSKatayama Hirofumi MZ                 // Update the preferred position
1332291a94cdSKatayama Hirofumi MZ                 pwndInsertAfter = pwndChild;
1333291a94cdSKatayama Hirofumi MZ                 break;
1334291a94cdSKatayama Hirofumi MZ             }
1335291a94cdSKatayama Hirofumi MZ         }
1336291a94cdSKatayama Hirofumi MZ 
1337291a94cdSKatayama Hirofumi MZ         // Get the next child, with ignoring pwndInsertAfterSave
1338291a94cdSKatayama Hirofumi MZ         pwndChild = pwndNext;
1339291a94cdSKatayama Hirofumi MZ         if (pwndChild && pwndChild == pwndInsertAfterSave && pwndInsertAfter)
1340291a94cdSKatayama Hirofumi MZ             pwndChild = pwndInsertAfter->spwndNext;
1341291a94cdSKatayama Hirofumi MZ     }
1342291a94cdSKatayama Hirofumi MZ }
1343291a94cdSKatayama Hirofumi MZ 
1344291a94cdSKatayama Hirofumi MZ // Make the IME window top-most if necessary.
1345291a94cdSKatayama Hirofumi MZ // Win: ImeCheckTopmost
IntImeCheckTopmost(PWND pImeWnd)1346291a94cdSKatayama Hirofumi MZ VOID FASTCALL IntImeCheckTopmost(PWND pImeWnd)
1347291a94cdSKatayama Hirofumi MZ {
1348291a94cdSKatayama Hirofumi MZ     BOOL bTopMost;
1349291a94cdSKatayama Hirofumi MZ     PWND pwndOwner = pImeWnd->spwndOwner, pwndInsertBefore = NULL;
1350291a94cdSKatayama Hirofumi MZ 
1351291a94cdSKatayama Hirofumi MZ     if (!pwndOwner)
1352291a94cdSKatayama Hirofumi MZ         return;
1353291a94cdSKatayama Hirofumi MZ 
1354291a94cdSKatayama Hirofumi MZ     if (pImeWnd->head.pti != gptiForeground)
1355291a94cdSKatayama Hirofumi MZ         pwndInsertBefore = pwndOwner;
1356291a94cdSKatayama Hirofumi MZ 
1357291a94cdSKatayama Hirofumi MZ     bTopMost = !!(pwndOwner->ExStyle & WS_EX_TOPMOST);
1358291a94cdSKatayama Hirofumi MZ     IntImeSetTopMost(pImeWnd, bTopMost, pwndInsertBefore);
1359291a94cdSKatayama Hirofumi MZ }
1360291a94cdSKatayama Hirofumi MZ 
1361e52ce89bSKatayama Hirofumi MZ BOOL NTAPI
NtUserSetImeOwnerWindow(HWND hImeWnd,HWND hwndFocus)13628c6dcdcfSKatayama Hirofumi MZ NtUserSetImeOwnerWindow(HWND hImeWnd, HWND hwndFocus)
1363c2c66affSColin Finck {
13640519ae0aSKatayama Hirofumi MZ     BOOL ret = FALSE;
1365291a94cdSKatayama Hirofumi MZ     PWND pImeWnd, pwndFocus, pwndTopLevel, pwndNode, pwndActive;
13660519ae0aSKatayama Hirofumi MZ     PTHREADINFO ptiIme;
13670519ae0aSKatayama Hirofumi MZ 
13680519ae0aSKatayama Hirofumi MZ     UserEnterExclusive();
13690519ae0aSKatayama Hirofumi MZ 
1370b5c9d532SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1371b5c9d532SKatayama Hirofumi MZ     {
1372b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1373b5c9d532SKatayama Hirofumi MZ         goto Quit;
1374b5c9d532SKatayama Hirofumi MZ     }
1375b5c9d532SKatayama Hirofumi MZ 
13760519ae0aSKatayama Hirofumi MZ     pImeWnd = ValidateHwndNoErr(hImeWnd);
1377b5c9d532SKatayama Hirofumi MZ     if (!pImeWnd || pImeWnd->fnid != FNID_IME)
13780519ae0aSKatayama Hirofumi MZ         goto Quit;
13790519ae0aSKatayama Hirofumi MZ 
13800519ae0aSKatayama Hirofumi MZ     pwndFocus = ValidateHwndNoErr(hwndFocus);
13810519ae0aSKatayama Hirofumi MZ     if (pwndFocus)
13820519ae0aSKatayama Hirofumi MZ     {
13830519ae0aSKatayama Hirofumi MZ         if (IS_WND_IMELIKE(pwndFocus))
13840519ae0aSKatayama Hirofumi MZ             goto Quit;
13850519ae0aSKatayama Hirofumi MZ 
13860519ae0aSKatayama Hirofumi MZ         pwndTopLevel = IntGetTopLevelWindow(pwndFocus);
13870519ae0aSKatayama Hirofumi MZ 
1388291a94cdSKatayama Hirofumi MZ         for (pwndNode = pwndTopLevel; pwndNode; pwndNode = pwndNode->spwndOwner)
13890519ae0aSKatayama Hirofumi MZ         {
1390291a94cdSKatayama Hirofumi MZ             if (pwndNode->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME])
13910519ae0aSKatayama Hirofumi MZ             {
13920519ae0aSKatayama Hirofumi MZ                 pwndTopLevel = NULL;
13930519ae0aSKatayama Hirofumi MZ                 break;
13940519ae0aSKatayama Hirofumi MZ             }
13950519ae0aSKatayama Hirofumi MZ         }
13960519ae0aSKatayama Hirofumi MZ 
1397e56da485STimo Kreuzer         WndSetOwner(pImeWnd, pwndTopLevel);
1398291a94cdSKatayama Hirofumi MZ         IntImeCheckTopmost(pImeWnd);
13990519ae0aSKatayama Hirofumi MZ     }
14000519ae0aSKatayama Hirofumi MZ     else
14010519ae0aSKatayama Hirofumi MZ     {
14020519ae0aSKatayama Hirofumi MZ         ptiIme = pImeWnd->head.pti;
14030519ae0aSKatayama Hirofumi MZ         pwndActive = ptiIme->MessageQueue->spwndActive;
14040519ae0aSKatayama Hirofumi MZ 
14050519ae0aSKatayama Hirofumi MZ         if (!pwndActive || pwndActive != pImeWnd->spwndOwner)
14060519ae0aSKatayama Hirofumi MZ         {
14070519ae0aSKatayama Hirofumi MZ             if (pwndActive && ptiIme == pwndActive->head.pti && !IS_WND_IMELIKE(pwndActive))
14080519ae0aSKatayama Hirofumi MZ             {
1409e56da485STimo Kreuzer                 WndSetOwner(pImeWnd, pwndActive);
14100519ae0aSKatayama Hirofumi MZ             }
14110519ae0aSKatayama Hirofumi MZ             else
14120519ae0aSKatayama Hirofumi MZ             {
1413291a94cdSKatayama Hirofumi MZ                 IntImeSetFutureOwner(pImeWnd, pImeWnd->spwndOwner);
14140519ae0aSKatayama Hirofumi MZ             }
14150519ae0aSKatayama Hirofumi MZ 
1416291a94cdSKatayama Hirofumi MZ             IntImeCheckTopmost(pImeWnd);
14170519ae0aSKatayama Hirofumi MZ         }
14180519ae0aSKatayama Hirofumi MZ     }
14190519ae0aSKatayama Hirofumi MZ 
14200519ae0aSKatayama Hirofumi MZ     ret = TRUE;
14210519ae0aSKatayama Hirofumi MZ 
14220519ae0aSKatayama Hirofumi MZ Quit:
14230519ae0aSKatayama Hirofumi MZ     UserLeave();
14240519ae0aSKatayama Hirofumi MZ     return ret;
1425c2c66affSColin Finck }
1426c2c66affSColin Finck 
14273d78601fSKatayama Hirofumi MZ PVOID
AllocInputContextObject(PDESKTOP pDesk,PTHREADINFO pti,SIZE_T Size,PVOID * HandleOwner)14283d78601fSKatayama Hirofumi MZ AllocInputContextObject(PDESKTOP pDesk,
14293d78601fSKatayama Hirofumi MZ                         PTHREADINFO pti,
14303d78601fSKatayama Hirofumi MZ                         SIZE_T Size,
14313d78601fSKatayama Hirofumi MZ                         PVOID* HandleOwner)
14323d78601fSKatayama Hirofumi MZ {
14333d78601fSKatayama Hirofumi MZ     PTHRDESKHEAD ObjHead;
14343d78601fSKatayama Hirofumi MZ 
14353d78601fSKatayama Hirofumi MZ     ASSERT(Size > sizeof(*ObjHead));
14363d78601fSKatayama Hirofumi MZ     ASSERT(pti != NULL);
14373d78601fSKatayama Hirofumi MZ 
1438cfeb498eSKatayama Hirofumi MZ     if (!pDesk)
1439cfeb498eSKatayama Hirofumi MZ         pDesk = pti->rpdesk;
1440cfeb498eSKatayama Hirofumi MZ 
1441cfeb498eSKatayama Hirofumi MZ     ObjHead = DesktopHeapAlloc(pDesk, Size);
14423d78601fSKatayama Hirofumi MZ     if (!ObjHead)
14433d78601fSKatayama Hirofumi MZ         return NULL;
14443d78601fSKatayama Hirofumi MZ 
14453d78601fSKatayama Hirofumi MZ     RtlZeroMemory(ObjHead, Size);
14463d78601fSKatayama Hirofumi MZ 
14473d78601fSKatayama Hirofumi MZ     ObjHead->pSelf = ObjHead;
14483d78601fSKatayama Hirofumi MZ     ObjHead->rpdesk = pDesk;
14493d78601fSKatayama Hirofumi MZ     ObjHead->pti = pti;
14503d78601fSKatayama Hirofumi MZ     IntReferenceThreadInfo(pti);
14513d78601fSKatayama Hirofumi MZ     *HandleOwner = pti;
14523d78601fSKatayama Hirofumi MZ     pti->ppi->UserHandleCount++;
14533d78601fSKatayama Hirofumi MZ 
14543d78601fSKatayama Hirofumi MZ     return ObjHead;
14553d78601fSKatayama Hirofumi MZ }
14563d78601fSKatayama Hirofumi MZ 
UserFreeInputContext(PVOID Object)14573d78601fSKatayama Hirofumi MZ VOID UserFreeInputContext(PVOID Object)
14583d78601fSKatayama Hirofumi MZ {
1459cfeb498eSKatayama Hirofumi MZ     PTHRDESKHEAD ObjHead = Object;
1460cfeb498eSKatayama Hirofumi MZ     PDESKTOP pDesk = ObjHead->rpdesk;
1461eb902e5bSKatayama Hirofumi MZ     PIMC pNode, pIMC = Object;
1462757bed81SKatayama Hirofumi MZ     PTHREADINFO pti;
14633d78601fSKatayama Hirofumi MZ 
1464757bed81SKatayama Hirofumi MZ     if (!pIMC)
1465757bed81SKatayama Hirofumi MZ         return;
14663d78601fSKatayama Hirofumi MZ 
1467eb902e5bSKatayama Hirofumi MZ     // Remove pIMC from the list except spDefaultImc
1468757bed81SKatayama Hirofumi MZ     pti = pIMC->head.pti;
1469eb902e5bSKatayama Hirofumi MZ     for (pNode = pti->spDefaultImc; pNode; pNode = pNode->pImcNext)
14702b2366abSKatayama Hirofumi MZ     {
1471eb902e5bSKatayama Hirofumi MZ         if (pNode->pImcNext == pIMC)
14722b2366abSKatayama Hirofumi MZ         {
1473eb902e5bSKatayama Hirofumi MZ             pNode->pImcNext = pIMC->pImcNext;
14742b2366abSKatayama Hirofumi MZ             break;
14752b2366abSKatayama Hirofumi MZ         }
14762b2366abSKatayama Hirofumi MZ     }
1477757bed81SKatayama Hirofumi MZ 
1478cfeb498eSKatayama Hirofumi MZ     DesktopHeapFree(pDesk, Object);
147945a4e53fSKatayama Hirofumi MZ 
148045a4e53fSKatayama Hirofumi MZ     pti->ppi->UserHandleCount--;
148145a4e53fSKatayama Hirofumi MZ     IntDereferenceThreadInfo(pti);
148245a4e53fSKatayama Hirofumi MZ }
148345a4e53fSKatayama Hirofumi MZ 
UserDestroyInputContext(PVOID Object)148445a4e53fSKatayama Hirofumi MZ BOOLEAN UserDestroyInputContext(PVOID Object)
148545a4e53fSKatayama Hirofumi MZ {
14862b2366abSKatayama Hirofumi MZ     PIMC pIMC = Object;
14874a748a3aSKatayama Hirofumi MZ     if (!pIMC)
148845a4e53fSKatayama Hirofumi MZ         return TRUE;
148945a4e53fSKatayama Hirofumi MZ 
14902ef605d4SKatayama Hirofumi MZ     UserMarkObjectDestroy(pIMC);
14914a748a3aSKatayama Hirofumi MZ     UserDeleteObject(UserHMGetHandle(pIMC), TYPE_INPUTCONTEXT);
14924a748a3aSKatayama Hirofumi MZ     return TRUE;
14933d78601fSKatayama Hirofumi MZ }
14943d78601fSKatayama Hirofumi MZ 
1495eb902e5bSKatayama Hirofumi MZ // Win: DestroyInputContext
IntDestroyInputContext(PIMC pIMC)14960f1e19a7SKatayama Hirofumi MZ BOOL IntDestroyInputContext(PIMC pIMC)
14973d78601fSKatayama Hirofumi MZ {
14980f1e19a7SKatayama Hirofumi MZ     HIMC hIMC = UserHMGetHandle(pIMC);
1499eb902e5bSKatayama Hirofumi MZ     PTHREADINFO pti = pIMC->head.pti;
1500eb902e5bSKatayama Hirofumi MZ     PWND pwndChild;
1501eb902e5bSKatayama Hirofumi MZ     PWINDOWLIST pwl;
15021bc9dda5SKatayama Hirofumi MZ     HWND *phwnd;
15031bc9dda5SKatayama Hirofumi MZ     PWND pWnd;
15043d78601fSKatayama Hirofumi MZ 
15050f1e19a7SKatayama Hirofumi MZ     if (pti != gptiCurrent)
15063d78601fSKatayama Hirofumi MZ     {
1507eb902e5bSKatayama Hirofumi MZ         EngSetLastError(ERROR_ACCESS_DENIED);
1508eb902e5bSKatayama Hirofumi MZ         return FALSE;
15093d78601fSKatayama Hirofumi MZ     }
15103d78601fSKatayama Hirofumi MZ 
1511eb902e5bSKatayama Hirofumi MZ     if (pIMC == pti->spDefaultImc)
1512eb902e5bSKatayama Hirofumi MZ     {
1513eb902e5bSKatayama Hirofumi MZ         EngSetLastError(ERROR_INVALID_PARAMETER);
1514eb902e5bSKatayama Hirofumi MZ         return FALSE;
1515eb902e5bSKatayama Hirofumi MZ     }
15163d78601fSKatayama Hirofumi MZ 
1517eb902e5bSKatayama Hirofumi MZ     pwndChild = pti->rpdesk->pDeskInfo->spwnd->spwndChild;
1518eb902e5bSKatayama Hirofumi MZ     pwl = IntBuildHwndList(pwndChild, IACE_LIST | IACE_CHILDREN, pti);
15191bc9dda5SKatayama Hirofumi MZ     if (pwl)
15201bc9dda5SKatayama Hirofumi MZ     {
15211bc9dda5SKatayama Hirofumi MZ         for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
15221bc9dda5SKatayama Hirofumi MZ         {
1523eb902e5bSKatayama Hirofumi MZ             pWnd = UserGetObjectNoErr(gHandleTable, *phwnd, TYPE_WINDOW);
1524eb902e5bSKatayama Hirofumi MZ             if (pWnd && pWnd->hImc == hIMC)
15251bc9dda5SKatayama Hirofumi MZ                 IntAssociateInputContext(pWnd, pti->spDefaultImc);
15261bc9dda5SKatayama Hirofumi MZ         }
15271bc9dda5SKatayama Hirofumi MZ 
15281bc9dda5SKatayama Hirofumi MZ         IntFreeHwndList(pwl);
15291bc9dda5SKatayama Hirofumi MZ     }
15301bc9dda5SKatayama Hirofumi MZ 
1531eb902e5bSKatayama Hirofumi MZ     UserDeleteObject(hIMC, TYPE_INPUTCONTEXT);
1532eb902e5bSKatayama Hirofumi MZ     return TRUE;
1533eb902e5bSKatayama Hirofumi MZ }
1534eb902e5bSKatayama Hirofumi MZ 
NtUserDestroyInputContext(HIMC hIMC)1535eb902e5bSKatayama Hirofumi MZ BOOL NTAPI NtUserDestroyInputContext(HIMC hIMC)
1536eb902e5bSKatayama Hirofumi MZ {
1537eb902e5bSKatayama Hirofumi MZ     BOOL ret = FALSE;
1538eb902e5bSKatayama Hirofumi MZ     PIMC pIMC;
1539eb902e5bSKatayama Hirofumi MZ 
1540eb902e5bSKatayama Hirofumi MZ     UserEnterExclusive();
1541eb902e5bSKatayama Hirofumi MZ 
1542eb902e5bSKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1543eb902e5bSKatayama Hirofumi MZ     {
1544eb902e5bSKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1545eb902e5bSKatayama Hirofumi MZ         goto Quit;
1546eb902e5bSKatayama Hirofumi MZ     }
1547eb902e5bSKatayama Hirofumi MZ 
1548eb902e5bSKatayama Hirofumi MZ     pIMC = UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT);
1549eb902e5bSKatayama Hirofumi MZ     if (pIMC)
1550eb902e5bSKatayama Hirofumi MZ         ret = IntDestroyInputContext(pIMC);
15511bc9dda5SKatayama Hirofumi MZ 
15521bc9dda5SKatayama Hirofumi MZ Quit:
15533d78601fSKatayama Hirofumi MZ     UserLeave();
15543d78601fSKatayama Hirofumi MZ     return ret;
15553d78601fSKatayama Hirofumi MZ }
1556c2c66affSColin Finck 
15572f7775c6SKatayama Hirofumi MZ // Win: CreateInputContext
UserCreateInputContext(ULONG_PTR dwClientImcData)1558470aa276SKatayama Hirofumi MZ PIMC FASTCALL UserCreateInputContext(ULONG_PTR dwClientImcData)
1559470aa276SKatayama Hirofumi MZ {
1560470aa276SKatayama Hirofumi MZ     PIMC pIMC;
1561470aa276SKatayama Hirofumi MZ     PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
1562470aa276SKatayama Hirofumi MZ     PDESKTOP pdesk = pti->rpdesk;
1563470aa276SKatayama Hirofumi MZ 
1564470aa276SKatayama Hirofumi MZ     if (!IS_IMM_MODE() || (pti->TIF_flags & TIF_DISABLEIME)) // Disabled?
1565b5c9d532SKatayama Hirofumi MZ     {
1566b5c9d532SKatayama Hirofumi MZ         ERR("IME is disabled\n");
1567470aa276SKatayama Hirofumi MZ         return NULL;
1568b5c9d532SKatayama Hirofumi MZ     }
1569470aa276SKatayama Hirofumi MZ 
1570470aa276SKatayama Hirofumi MZ     if (!pdesk) // No desktop?
1571470aa276SKatayama Hirofumi MZ         return NULL;
1572470aa276SKatayama Hirofumi MZ 
1573470aa276SKatayama Hirofumi MZ     // pti->spDefaultImc should be already set if non-first time.
1574470aa276SKatayama Hirofumi MZ     if (dwClientImcData && !pti->spDefaultImc)
1575470aa276SKatayama Hirofumi MZ         return NULL;
1576470aa276SKatayama Hirofumi MZ 
1577470aa276SKatayama Hirofumi MZ     // Create an input context user object.
1578470aa276SKatayama Hirofumi MZ     pIMC = UserCreateObject(gHandleTable, pdesk, pti, NULL, TYPE_INPUTCONTEXT, sizeof(IMC));
1579470aa276SKatayama Hirofumi MZ     if (!pIMC)
1580470aa276SKatayama Hirofumi MZ         return NULL;
1581470aa276SKatayama Hirofumi MZ 
1582470aa276SKatayama Hirofumi MZ     // Release the extra reference (UserCreateObject added 2 references).
1583470aa276SKatayama Hirofumi MZ     UserDereferenceObject(pIMC);
15844a748a3aSKatayama Hirofumi MZ     ASSERT(pIMC->head.cLockObj == 1);
1585470aa276SKatayama Hirofumi MZ 
1586470aa276SKatayama Hirofumi MZ     if (dwClientImcData) // Non-first time.
1587470aa276SKatayama Hirofumi MZ     {
1588470aa276SKatayama Hirofumi MZ         // Insert pIMC to the second position (non-default) of the list.
1589470aa276SKatayama Hirofumi MZ         pIMC->pImcNext = pti->spDefaultImc->pImcNext;
1590470aa276SKatayama Hirofumi MZ         pti->spDefaultImc->pImcNext = pIMC;
1591470aa276SKatayama Hirofumi MZ     }
1592470aa276SKatayama Hirofumi MZ     else // First time. It's the default IMC.
1593470aa276SKatayama Hirofumi MZ     {
1594470aa276SKatayama Hirofumi MZ         // Add the first one (default) to the list.
15957e138837SKatayama Hirofumi MZ         UserAssignmentLock((PVOID*)&pti->spDefaultImc, pIMC);
1596470aa276SKatayama Hirofumi MZ         pIMC->pImcNext = NULL;
15974a748a3aSKatayama Hirofumi MZ         ASSERT(pIMC->head.cLockObj == 2); // UserAssignmentUnlock'ed at ExitThreadCallback
1598470aa276SKatayama Hirofumi MZ     }
1599470aa276SKatayama Hirofumi MZ 
1600470aa276SKatayama Hirofumi MZ     pIMC->dwClientImcData = dwClientImcData; // Set it.
1601470aa276SKatayama Hirofumi MZ     return pIMC;
1602470aa276SKatayama Hirofumi MZ }
1603470aa276SKatayama Hirofumi MZ 
1604470aa276SKatayama Hirofumi MZ HIMC
1605e52ce89bSKatayama Hirofumi MZ NTAPI
NtUserCreateInputContext(ULONG_PTR dwClientImcData)1606470aa276SKatayama Hirofumi MZ NtUserCreateInputContext(ULONG_PTR dwClientImcData)
1607470aa276SKatayama Hirofumi MZ {
1608470aa276SKatayama Hirofumi MZ     PIMC pIMC;
1609470aa276SKatayama Hirofumi MZ     HIMC ret = NULL;
1610470aa276SKatayama Hirofumi MZ 
1611470aa276SKatayama Hirofumi MZ     UserEnterExclusive();
1612470aa276SKatayama Hirofumi MZ 
1613470aa276SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1614b5c9d532SKatayama Hirofumi MZ     {
1615b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
161688c1d8c7SKatayama Hirofumi MZ         EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
161788c1d8c7SKatayama Hirofumi MZ         goto Quit;
161888c1d8c7SKatayama Hirofumi MZ     }
161988c1d8c7SKatayama Hirofumi MZ 
162088c1d8c7SKatayama Hirofumi MZ     if (!dwClientImcData)
162188c1d8c7SKatayama Hirofumi MZ     {
162288c1d8c7SKatayama Hirofumi MZ         EngSetLastError(ERROR_INVALID_PARAMETER);
1623470aa276SKatayama Hirofumi MZ         goto Quit;
1624b5c9d532SKatayama Hirofumi MZ     }
1625470aa276SKatayama Hirofumi MZ 
1626470aa276SKatayama Hirofumi MZ     pIMC = UserCreateInputContext(dwClientImcData);
1627470aa276SKatayama Hirofumi MZ     if (pIMC)
1628470aa276SKatayama Hirofumi MZ         ret = UserHMGetHandle(pIMC);
1629470aa276SKatayama Hirofumi MZ 
1630470aa276SKatayama Hirofumi MZ Quit:
1631470aa276SKatayama Hirofumi MZ     UserLeave();
1632470aa276SKatayama Hirofumi MZ     return ret;
1633470aa276SKatayama Hirofumi MZ }
1634470aa276SKatayama Hirofumi MZ 
16352f7775c6SKatayama Hirofumi MZ // Win: AssociateInputContextEx
IntAssociateInputContextEx(PWND pWnd,PIMC pIMC,DWORD dwFlags)1636f2c3167dSKatayama Hirofumi MZ DWORD FASTCALL IntAssociateInputContextEx(PWND pWnd, PIMC pIMC, DWORD dwFlags)
1637f2c3167dSKatayama Hirofumi MZ {
1638f2c3167dSKatayama Hirofumi MZ     DWORD ret = 0;
1639f2c3167dSKatayama Hirofumi MZ     PWINDOWLIST pwl;
1640f2c3167dSKatayama Hirofumi MZ     BOOL bIgnoreNullImc = (dwFlags & IACE_IGNORENOCONTEXT);
1641f2c3167dSKatayama Hirofumi MZ     PTHREADINFO pti = pWnd->head.pti;
1642f2c3167dSKatayama Hirofumi MZ     PWND pwndTarget, pwndFocus = pti->MessageQueue->spwndFocus;
1643f2c3167dSKatayama Hirofumi MZ     HWND *phwnd;
1644f2c3167dSKatayama Hirofumi MZ     HIMC hIMC;
1645f2c3167dSKatayama Hirofumi MZ 
1646f2c3167dSKatayama Hirofumi MZ     if (dwFlags & IACE_DEFAULT)
1647f2c3167dSKatayama Hirofumi MZ     {
1648f2c3167dSKatayama Hirofumi MZ         pIMC = pti->spDefaultImc;
1649f2c3167dSKatayama Hirofumi MZ     }
1650f2c3167dSKatayama Hirofumi MZ     else
1651f2c3167dSKatayama Hirofumi MZ     {
1652f2c3167dSKatayama Hirofumi MZ         if (pIMC && pti != pIMC->head.pti)
1653f2c3167dSKatayama Hirofumi MZ             return 2;
1654f2c3167dSKatayama Hirofumi MZ     }
1655f2c3167dSKatayama Hirofumi MZ 
1656f2c3167dSKatayama Hirofumi MZ     if (pWnd->head.pti->ppi != GetW32ThreadInfo()->ppi ||
1657f2c3167dSKatayama Hirofumi MZ         (pIMC && pIMC->head.rpdesk != pWnd->head.rpdesk))
1658f2c3167dSKatayama Hirofumi MZ     {
1659f2c3167dSKatayama Hirofumi MZ         return 2;
1660f2c3167dSKatayama Hirofumi MZ     }
1661f2c3167dSKatayama Hirofumi MZ 
1662f2c3167dSKatayama Hirofumi MZ     if ((dwFlags & IACE_CHILDREN) && pWnd->spwndChild)
1663f2c3167dSKatayama Hirofumi MZ     {
1664f2c3167dSKatayama Hirofumi MZ         pwl = IntBuildHwndList(pWnd->spwndChild, IACE_CHILDREN | IACE_LIST, pti);
1665f2c3167dSKatayama Hirofumi MZ         if (pwl)
1666f2c3167dSKatayama Hirofumi MZ         {
1667f2c3167dSKatayama Hirofumi MZ             for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
1668f2c3167dSKatayama Hirofumi MZ             {
1669f2c3167dSKatayama Hirofumi MZ                 pwndTarget = ValidateHwndNoErr(*phwnd);
1670f2c3167dSKatayama Hirofumi MZ                 if (!pwndTarget)
1671f2c3167dSKatayama Hirofumi MZ                     continue;
1672f2c3167dSKatayama Hirofumi MZ 
1673f2c3167dSKatayama Hirofumi MZ                 hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1674f2c3167dSKatayama Hirofumi MZ                 if (pwndTarget->hImc == hIMC || (bIgnoreNullImc && !pwndTarget->hImc))
1675f2c3167dSKatayama Hirofumi MZ                     continue;
1676f2c3167dSKatayama Hirofumi MZ 
1677f2c3167dSKatayama Hirofumi MZ                 IntAssociateInputContext(pwndTarget, pIMC);
1678f2c3167dSKatayama Hirofumi MZ                 if (pwndTarget == pwndFocus)
1679f2c3167dSKatayama Hirofumi MZ                     ret = 1;
1680f2c3167dSKatayama Hirofumi MZ             }
1681f2c3167dSKatayama Hirofumi MZ 
1682f2c3167dSKatayama Hirofumi MZ             IntFreeHwndList(pwl);
1683f2c3167dSKatayama Hirofumi MZ         }
1684f2c3167dSKatayama Hirofumi MZ     }
1685f2c3167dSKatayama Hirofumi MZ 
1686f2c3167dSKatayama Hirofumi MZ     if (!bIgnoreNullImc || pWnd->hImc)
1687f2c3167dSKatayama Hirofumi MZ     {
1688f2c3167dSKatayama Hirofumi MZ         hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1689f2c3167dSKatayama Hirofumi MZ         if (pWnd->hImc != hIMC)
1690f2c3167dSKatayama Hirofumi MZ         {
1691f2c3167dSKatayama Hirofumi MZ             IntAssociateInputContext(pWnd, pIMC);
1692f2c3167dSKatayama Hirofumi MZ             if (pWnd == pwndFocus)
1693f2c3167dSKatayama Hirofumi MZ                 ret = 1;
1694f2c3167dSKatayama Hirofumi MZ         }
1695f2c3167dSKatayama Hirofumi MZ     }
1696f2c3167dSKatayama Hirofumi MZ 
1697f2c3167dSKatayama Hirofumi MZ     return ret;
1698f2c3167dSKatayama Hirofumi MZ }
1699f2c3167dSKatayama Hirofumi MZ 
1700470aa276SKatayama Hirofumi MZ DWORD
1701e52ce89bSKatayama Hirofumi MZ NTAPI
NtUserAssociateInputContext(HWND hWnd,HIMC hIMC,DWORD dwFlags)1702470aa276SKatayama Hirofumi MZ NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags)
1703470aa276SKatayama Hirofumi MZ {
1704f2c3167dSKatayama Hirofumi MZ     DWORD ret = 2;
1705f2c3167dSKatayama Hirofumi MZ     PWND pWnd;
1706f2c3167dSKatayama Hirofumi MZ     PIMC pIMC;
1707f2c3167dSKatayama Hirofumi MZ 
1708f2c3167dSKatayama Hirofumi MZ     UserEnterExclusive();
1709f2c3167dSKatayama Hirofumi MZ 
1710b5c9d532SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1711b5c9d532SKatayama Hirofumi MZ     {
1712b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1713b5c9d532SKatayama Hirofumi MZ         goto Quit;
1714b5c9d532SKatayama Hirofumi MZ     }
1715b5c9d532SKatayama Hirofumi MZ 
1716f2c3167dSKatayama Hirofumi MZ     pWnd = ValidateHwndNoErr(hWnd);
1717b5c9d532SKatayama Hirofumi MZ     if (!pWnd)
1718f2c3167dSKatayama Hirofumi MZ         goto Quit;
1719f2c3167dSKatayama Hirofumi MZ 
1720f2c3167dSKatayama Hirofumi MZ     pIMC = (hIMC ? UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT) : NULL);
1721f2c3167dSKatayama Hirofumi MZ     ret = IntAssociateInputContextEx(pWnd, pIMC, dwFlags);
1722f2c3167dSKatayama Hirofumi MZ 
1723f2c3167dSKatayama Hirofumi MZ Quit:
1724f2c3167dSKatayama Hirofumi MZ     UserLeave();
1725f2c3167dSKatayama Hirofumi MZ     return ret;
1726470aa276SKatayama Hirofumi MZ }
1727470aa276SKatayama Hirofumi MZ 
17285df5ef2bSKatayama Hirofumi MZ // Win: UpdateInputContext
UserUpdateInputContext(PIMC pIMC,DWORD dwType,DWORD_PTR dwValue)1729470aa276SKatayama Hirofumi MZ BOOL FASTCALL UserUpdateInputContext(PIMC pIMC, DWORD dwType, DWORD_PTR dwValue)
1730470aa276SKatayama Hirofumi MZ {
1731470aa276SKatayama Hirofumi MZ     PTHREADINFO pti = GetW32ThreadInfo();
1732470aa276SKatayama Hirofumi MZ     PTHREADINFO ptiIMC = pIMC->head.pti;
1733470aa276SKatayama Hirofumi MZ 
1734470aa276SKatayama Hirofumi MZ     if (pti->ppi != ptiIMC->ppi) // Different process?
1735470aa276SKatayama Hirofumi MZ         return FALSE;
1736470aa276SKatayama Hirofumi MZ 
1737470aa276SKatayama Hirofumi MZ     switch (dwType)
1738470aa276SKatayama Hirofumi MZ     {
1739470aa276SKatayama Hirofumi MZ         case UIC_CLIENTIMCDATA:
1740470aa276SKatayama Hirofumi MZ             if (pIMC->dwClientImcData)
1741470aa276SKatayama Hirofumi MZ                 return FALSE; // Already set
1742470aa276SKatayama Hirofumi MZ 
1743470aa276SKatayama Hirofumi MZ             pIMC->dwClientImcData = dwValue;
1744470aa276SKatayama Hirofumi MZ             break;
1745470aa276SKatayama Hirofumi MZ 
1746470aa276SKatayama Hirofumi MZ         case UIC_IMEWINDOW:
1747470aa276SKatayama Hirofumi MZ             if (!ValidateHwndNoErr((HWND)dwValue))
1748470aa276SKatayama Hirofumi MZ                 return FALSE; // Invalid HWND
1749470aa276SKatayama Hirofumi MZ 
1750470aa276SKatayama Hirofumi MZ             pIMC->hImeWnd = (HWND)dwValue;
1751470aa276SKatayama Hirofumi MZ             break;
1752470aa276SKatayama Hirofumi MZ 
1753470aa276SKatayama Hirofumi MZ         default:
1754470aa276SKatayama Hirofumi MZ             return FALSE;
1755470aa276SKatayama Hirofumi MZ     }
1756470aa276SKatayama Hirofumi MZ 
1757470aa276SKatayama Hirofumi MZ     return TRUE;
1758470aa276SKatayama Hirofumi MZ }
1759470aa276SKatayama Hirofumi MZ 
1760470aa276SKatayama Hirofumi MZ BOOL
1761e52ce89bSKatayama Hirofumi MZ NTAPI
NtUserUpdateInputContext(HIMC hIMC,DWORD dwType,DWORD_PTR dwValue)1762470aa276SKatayama Hirofumi MZ NtUserUpdateInputContext(
1763470aa276SKatayama Hirofumi MZ     HIMC hIMC,
1764470aa276SKatayama Hirofumi MZ     DWORD dwType,
1765470aa276SKatayama Hirofumi MZ     DWORD_PTR dwValue)
1766470aa276SKatayama Hirofumi MZ {
1767470aa276SKatayama Hirofumi MZ     PIMC pIMC;
1768470aa276SKatayama Hirofumi MZ     BOOL ret = FALSE;
1769470aa276SKatayama Hirofumi MZ 
1770470aa276SKatayama Hirofumi MZ     UserEnterExclusive();
1771470aa276SKatayama Hirofumi MZ 
1772470aa276SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1773b5c9d532SKatayama Hirofumi MZ     {
1774b5c9d532SKatayama Hirofumi MZ         ERR("!IS_IMM_MODE()\n");
1775470aa276SKatayama Hirofumi MZ         goto Quit;
1776b5c9d532SKatayama Hirofumi MZ     }
1777470aa276SKatayama Hirofumi MZ 
1778470aa276SKatayama Hirofumi MZ     pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT);
1779470aa276SKatayama Hirofumi MZ     if (!pIMC)
1780470aa276SKatayama Hirofumi MZ         goto Quit;
1781470aa276SKatayama Hirofumi MZ 
1782470aa276SKatayama Hirofumi MZ     ret = UserUpdateInputContext(pIMC, dwType, dwValue);
1783470aa276SKatayama Hirofumi MZ 
1784470aa276SKatayama Hirofumi MZ Quit:
1785470aa276SKatayama Hirofumi MZ     UserLeave();
1786470aa276SKatayama Hirofumi MZ     return ret;
1787470aa276SKatayama Hirofumi MZ }
1788470aa276SKatayama Hirofumi MZ 
1789470aa276SKatayama Hirofumi MZ DWORD_PTR
1790e52ce89bSKatayama Hirofumi MZ NTAPI
NtUserQueryInputContext(HIMC hIMC,DWORD dwType)1791470aa276SKatayama Hirofumi MZ NtUserQueryInputContext(HIMC hIMC, DWORD dwType)
1792470aa276SKatayama Hirofumi MZ {
1793470aa276SKatayama Hirofumi MZ     PIMC pIMC;
1794470aa276SKatayama Hirofumi MZ     PTHREADINFO ptiIMC;
1795470aa276SKatayama Hirofumi MZ     DWORD_PTR ret = 0;
1796470aa276SKatayama Hirofumi MZ 
1797470aa276SKatayama Hirofumi MZ     UserEnterExclusive();
1798470aa276SKatayama Hirofumi MZ 
1799470aa276SKatayama Hirofumi MZ     if (!IS_IMM_MODE())
1800470aa276SKatayama Hirofumi MZ         goto Quit;
1801470aa276SKatayama Hirofumi MZ 
1802470aa276SKatayama Hirofumi MZ     pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT);
1803470aa276SKatayama Hirofumi MZ     if (!pIMC)
1804470aa276SKatayama Hirofumi MZ         goto Quit;
1805470aa276SKatayama Hirofumi MZ 
1806470aa276SKatayama Hirofumi MZ     ptiIMC = pIMC->head.pti;
1807470aa276SKatayama Hirofumi MZ 
1808470aa276SKatayama Hirofumi MZ     switch (dwType)
1809470aa276SKatayama Hirofumi MZ     {
1810470aa276SKatayama Hirofumi MZ         case QIC_INPUTPROCESSID:
1811470aa276SKatayama Hirofumi MZ             ret = (DWORD_PTR)PsGetThreadProcessId(ptiIMC->pEThread);
1812470aa276SKatayama Hirofumi MZ             break;
1813470aa276SKatayama Hirofumi MZ 
1814470aa276SKatayama Hirofumi MZ         case QIC_INPUTTHREADID:
1815470aa276SKatayama Hirofumi MZ             ret = (DWORD_PTR)PsGetThreadId(ptiIMC->pEThread);
1816470aa276SKatayama Hirofumi MZ             break;
1817470aa276SKatayama Hirofumi MZ 
1818470aa276SKatayama Hirofumi MZ         case QIC_DEFAULTWINDOWIME:
1819470aa276SKatayama Hirofumi MZ             if (ptiIMC->spwndDefaultIme)
1820470aa276SKatayama Hirofumi MZ                 ret = (DWORD_PTR)UserHMGetHandle(ptiIMC->spwndDefaultIme);
1821470aa276SKatayama Hirofumi MZ             break;
1822470aa276SKatayama Hirofumi MZ 
1823470aa276SKatayama Hirofumi MZ         case QIC_DEFAULTIMC:
1824470aa276SKatayama Hirofumi MZ             if (ptiIMC->spDefaultImc)
1825470aa276SKatayama Hirofumi MZ                 ret = (DWORD_PTR)UserHMGetHandle(ptiIMC->spDefaultImc);
1826470aa276SKatayama Hirofumi MZ             break;
1827470aa276SKatayama Hirofumi MZ     }
1828470aa276SKatayama Hirofumi MZ 
1829470aa276SKatayama Hirofumi MZ Quit:
1830470aa276SKatayama Hirofumi MZ     UserLeave();
1831470aa276SKatayama Hirofumi MZ     return ret;
1832470aa276SKatayama Hirofumi MZ }
1833470aa276SKatayama Hirofumi MZ 
18344bcf23d1SKatayama Hirofumi MZ // Searchs a non-IME-related window of the same thread of pwndTarget,
18354bcf23d1SKatayama Hirofumi MZ // other than pwndTarget, around pwndParent. Returns TRUE if found.
18364bcf23d1SKatayama Hirofumi MZ //
18374bcf23d1SKatayama Hirofumi MZ // Win: IsChildSameThread
IntFindNonImeRelatedWndOfSameThread(PWND pwndParent,PWND pwndTarget)18384bcf23d1SKatayama Hirofumi MZ BOOL IntFindNonImeRelatedWndOfSameThread(PWND pwndParent, PWND pwndTarget)
18394bcf23d1SKatayama Hirofumi MZ {
18404bcf23d1SKatayama Hirofumi MZ     PWND pwnd, pwndOwner, pwndNode;
18414bcf23d1SKatayama Hirofumi MZ     PTHREADINFO ptiTarget = pwndTarget->head.pti;
18424bcf23d1SKatayama Hirofumi MZ 
18434bcf23d1SKatayama Hirofumi MZ     // For all the children of pwndParent, ...
18444bcf23d1SKatayama Hirofumi MZ     for (pwnd = pwndParent->spwndChild; pwnd; pwnd = pwnd->spwndNext)
18454bcf23d1SKatayama Hirofumi MZ     {
18464bcf23d1SKatayama Hirofumi MZ         if (pwnd == pwndTarget || pwnd->head.pti != ptiTarget || IS_WND_MENU(pwnd))
18474bcf23d1SKatayama Hirofumi MZ             continue;
18484bcf23d1SKatayama Hirofumi MZ 
18494bcf23d1SKatayama Hirofumi MZ         if (!IS_WND_CHILD(pwnd))
18504bcf23d1SKatayama Hirofumi MZ         {
18514bcf23d1SKatayama Hirofumi MZ             // Check if any IME-like owner.
18524bcf23d1SKatayama Hirofumi MZ             BOOL bFound1 = FALSE;
18534bcf23d1SKatayama Hirofumi MZ             for (pwndOwner = pwnd; pwndOwner; pwndOwner = pwndOwner->spwndOwner)
18544bcf23d1SKatayama Hirofumi MZ             {
18554bcf23d1SKatayama Hirofumi MZ                 if (IS_WND_IMELIKE(pwndOwner))
18564bcf23d1SKatayama Hirofumi MZ                 {
18574bcf23d1SKatayama Hirofumi MZ                     bFound1 = TRUE;
18584bcf23d1SKatayama Hirofumi MZ                     break;
18594bcf23d1SKatayama Hirofumi MZ                 }
18604bcf23d1SKatayama Hirofumi MZ             }
18614bcf23d1SKatayama Hirofumi MZ             if (bFound1)
18624bcf23d1SKatayama Hirofumi MZ                 continue; // Skip if any IME-like owner.
18634bcf23d1SKatayama Hirofumi MZ         }
18644bcf23d1SKatayama Hirofumi MZ 
18654bcf23d1SKatayama Hirofumi MZ         pwndNode = pwnd;
18664bcf23d1SKatayama Hirofumi MZ 
18674bcf23d1SKatayama Hirofumi MZ         if (IS_WND_CHILD(pwndNode))
18684bcf23d1SKatayama Hirofumi MZ         {
18694bcf23d1SKatayama Hirofumi MZ             // Check if any same-thread IME-like ancestor.
18704bcf23d1SKatayama Hirofumi MZ             BOOL bFound2 = FALSE;
18714bcf23d1SKatayama Hirofumi MZ             for (; IS_WND_CHILD(pwndNode); pwndNode = pwndNode->spwndParent)
18724bcf23d1SKatayama Hirofumi MZ             {
18734bcf23d1SKatayama Hirofumi MZ                 if (pwndNode->head.pti != ptiTarget)
18744bcf23d1SKatayama Hirofumi MZ                     break;
18754bcf23d1SKatayama Hirofumi MZ 
18764bcf23d1SKatayama Hirofumi MZ                 if (IS_WND_IMELIKE(pwndNode))
18774bcf23d1SKatayama Hirofumi MZ                 {
18784bcf23d1SKatayama Hirofumi MZ                     bFound2 = TRUE;
18794bcf23d1SKatayama Hirofumi MZ                     break;
18804bcf23d1SKatayama Hirofumi MZ                 }
18814bcf23d1SKatayama Hirofumi MZ             }
18824bcf23d1SKatayama Hirofumi MZ             if (bFound2)
18834bcf23d1SKatayama Hirofumi MZ                 continue;
18844bcf23d1SKatayama Hirofumi MZ             // Now, pwndNode is non-child or non-same-thread window.
18854bcf23d1SKatayama Hirofumi MZ         }
18864bcf23d1SKatayama Hirofumi MZ 
18874bcf23d1SKatayama Hirofumi MZ         if (!IS_WND_CHILD(pwndNode)) // pwndNode is non-child
18884bcf23d1SKatayama Hirofumi MZ         {
18894bcf23d1SKatayama Hirofumi MZ             // Check if any same-thread IME-like owner.
18904bcf23d1SKatayama Hirofumi MZ             BOOL bFound3 = FALSE;
18914bcf23d1SKatayama Hirofumi MZ             for (; pwndNode; pwndNode = pwndNode->spwndOwner)
18924bcf23d1SKatayama Hirofumi MZ             {
18934bcf23d1SKatayama Hirofumi MZ                 if (pwndNode->head.pti != ptiTarget)
18944bcf23d1SKatayama Hirofumi MZ                     break;
18954bcf23d1SKatayama Hirofumi MZ 
18964bcf23d1SKatayama Hirofumi MZ                 if (IS_WND_IMELIKE(pwndNode))
18974bcf23d1SKatayama Hirofumi MZ                 {
18984bcf23d1SKatayama Hirofumi MZ                     bFound3 = TRUE;
18994bcf23d1SKatayama Hirofumi MZ                     break;
19004bcf23d1SKatayama Hirofumi MZ                 }
19014bcf23d1SKatayama Hirofumi MZ             }
19024bcf23d1SKatayama Hirofumi MZ             if (bFound3)
19034bcf23d1SKatayama Hirofumi MZ                 continue;
19044bcf23d1SKatayama Hirofumi MZ         }
19054bcf23d1SKatayama Hirofumi MZ 
19064bcf23d1SKatayama Hirofumi MZ         return TRUE;
19074bcf23d1SKatayama Hirofumi MZ     }
19084bcf23d1SKatayama Hirofumi MZ 
19094bcf23d1SKatayama Hirofumi MZ     return FALSE;
19104bcf23d1SKatayama Hirofumi MZ }
19114bcf23d1SKatayama Hirofumi MZ 
19128f719cb9SKatayama Hirofumi MZ // Determines whether the target window needs the IME window.
19138f719cb9SKatayama Hirofumi MZ // Win: WantImeWindow(pwndParent, pwndTarget)
IntWantImeWindow(PWND pwndTarget)19148f719cb9SKatayama Hirofumi MZ BOOL FASTCALL IntWantImeWindow(PWND pwndTarget)
19158f719cb9SKatayama Hirofumi MZ {
19168f719cb9SKatayama Hirofumi MZ     PDESKTOP rpdesk;
19178f719cb9SKatayama Hirofumi MZ     PWINSTATION_OBJECT rpwinstaParent;
19188f719cb9SKatayama Hirofumi MZ     PWND pwndNode, pwndParent = pwndTarget->spwndParent;
19198f719cb9SKatayama Hirofumi MZ 
19208f719cb9SKatayama Hirofumi MZ     if (gptiCurrent->TIF_flags & TIF_DISABLEIME)
19218f719cb9SKatayama Hirofumi MZ         return FALSE;
19228f719cb9SKatayama Hirofumi MZ 
19238f719cb9SKatayama Hirofumi MZ     if (IS_WND_IMELIKE(pwndTarget))
19248f719cb9SKatayama Hirofumi MZ         return FALSE;
19258f719cb9SKatayama Hirofumi MZ 
19268f719cb9SKatayama Hirofumi MZ     if (pwndTarget->fnid == FNID_DESKTOP || pwndTarget->fnid == FNID_MESSAGEWND)
19278f719cb9SKatayama Hirofumi MZ         return FALSE;
19288f719cb9SKatayama Hirofumi MZ 
19298f719cb9SKatayama Hirofumi MZ     if (pwndTarget->state & WNDS_SERVERSIDEWINDOWPROC)
19308f719cb9SKatayama Hirofumi MZ         return FALSE;
19318f719cb9SKatayama Hirofumi MZ 
19328f719cb9SKatayama Hirofumi MZ     rpdesk = pwndTarget->head.rpdesk;
19338f719cb9SKatayama Hirofumi MZ     if (!rpdesk)
19348f719cb9SKatayama Hirofumi MZ         return FALSE;
19358f719cb9SKatayama Hirofumi MZ 
19368f719cb9SKatayama Hirofumi MZ     rpwinstaParent = rpdesk->rpwinstaParent;
19378f719cb9SKatayama Hirofumi MZ     if (!rpwinstaParent || (rpwinstaParent->Flags & WSS_NOIO))
19388f719cb9SKatayama Hirofumi MZ         return FALSE;
19398f719cb9SKatayama Hirofumi MZ 
19408f719cb9SKatayama Hirofumi MZ     for (pwndNode = pwndParent; pwndNode; pwndNode = pwndNode->spwndParent)
19418f719cb9SKatayama Hirofumi MZ     {
19428f719cb9SKatayama Hirofumi MZ         if (rpdesk != pwndNode->head.rpdesk)
19438f719cb9SKatayama Hirofumi MZ             break;
19448f719cb9SKatayama Hirofumi MZ 
19458f719cb9SKatayama Hirofumi MZ         if (pwndNode == rpdesk->spwndMessage)
19468f719cb9SKatayama Hirofumi MZ             return FALSE;
19478f719cb9SKatayama Hirofumi MZ     }
19488f719cb9SKatayama Hirofumi MZ 
19498f719cb9SKatayama Hirofumi MZ     return TRUE;
19508f719cb9SKatayama Hirofumi MZ }
19518f719cb9SKatayama Hirofumi MZ 
19528f719cb9SKatayama Hirofumi MZ // Create the default IME window for the target window.
19538f719cb9SKatayama Hirofumi MZ // Win: xxxCreateDefaultImeWindow(pwndTarget, ATOM, hInst)
co_IntCreateDefaultImeWindow(PWND pwndTarget,HINSTANCE hInst)19548f719cb9SKatayama Hirofumi MZ PWND FASTCALL co_IntCreateDefaultImeWindow(PWND pwndTarget, HINSTANCE hInst)
19558f719cb9SKatayama Hirofumi MZ {
19568f719cb9SKatayama Hirofumi MZ     LARGE_UNICODE_STRING WindowName;
19578f719cb9SKatayama Hirofumi MZ     UNICODE_STRING ClassName;
19588f719cb9SKatayama Hirofumi MZ     PWND pImeWnd;
19598f719cb9SKatayama Hirofumi MZ     PIMEUI pimeui;
19608f719cb9SKatayama Hirofumi MZ     CREATESTRUCTW Cs;
19618f719cb9SKatayama Hirofumi MZ     USER_REFERENCE_ENTRY Ref;
19628f719cb9SKatayama Hirofumi MZ     PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
19638f719cb9SKatayama Hirofumi MZ     HANDLE pid = PsGetThreadProcessId(pti->pEThread);
19648f719cb9SKatayama Hirofumi MZ 
19658f719cb9SKatayama Hirofumi MZ     if (!(pti->spDefaultImc) && pid == gpidLogon)
19668f719cb9SKatayama Hirofumi MZ         UserCreateInputContext(0);
19678f719cb9SKatayama Hirofumi MZ 
19688f719cb9SKatayama Hirofumi MZ     if (!(pti->spDefaultImc) || IS_WND_IMELIKE(pwndTarget) || !(pti->rpdesk->pheapDesktop))
19698f719cb9SKatayama Hirofumi MZ         return NULL;
19708f719cb9SKatayama Hirofumi MZ 
19718f719cb9SKatayama Hirofumi MZ     if (IS_WND_CHILD(pwndTarget) && !(pwndTarget->style & WS_VISIBLE) &&
19728f719cb9SKatayama Hirofumi MZ         pwndTarget->spwndParent->head.pti->ppi != pti->ppi)
19738f719cb9SKatayama Hirofumi MZ     {
19748f719cb9SKatayama Hirofumi MZ         return NULL;
19758f719cb9SKatayama Hirofumi MZ     }
19768f719cb9SKatayama Hirofumi MZ 
19778f719cb9SKatayama Hirofumi MZ     RtlInitLargeUnicodeString(&WindowName, L"Default IME", 0);
19788f719cb9SKatayama Hirofumi MZ 
1979*ec24b547SKatayama Hirofumi MZ     ClassName.Buffer = UlongToPtr(gpsi->atomSysClass[ICLS_IME]);
19808f719cb9SKatayama Hirofumi MZ     ClassName.Length = 0;
19818f719cb9SKatayama Hirofumi MZ     ClassName.MaximumLength = 0;
19828f719cb9SKatayama Hirofumi MZ 
19838f719cb9SKatayama Hirofumi MZ     UserRefObjectCo(pwndTarget, &Ref);
19848f719cb9SKatayama Hirofumi MZ 
19858f719cb9SKatayama Hirofumi MZ     RtlZeroMemory(&Cs, sizeof(Cs));
19868f719cb9SKatayama Hirofumi MZ     Cs.style = WS_POPUP | WS_DISABLED;
19878f719cb9SKatayama Hirofumi MZ     Cs.hInstance = hInst;
19888f719cb9SKatayama Hirofumi MZ     Cs.hwndParent = UserHMGetHandle(pwndTarget);
19898f719cb9SKatayama Hirofumi MZ     Cs.lpszName = WindowName.Buffer;
19908f719cb9SKatayama Hirofumi MZ     Cs.lpszClass = ClassName.Buffer;
19918f719cb9SKatayama Hirofumi MZ 
19928f719cb9SKatayama Hirofumi MZ     // NOTE: LARGE_UNICODE_STRING is compatible to LARGE_STRING.
19938f719cb9SKatayama Hirofumi MZ     pImeWnd = co_UserCreateWindowEx(&Cs, &ClassName, (PLARGE_STRING)&WindowName, NULL, WINVER);
19948f719cb9SKatayama Hirofumi MZ     if (pImeWnd)
19958f719cb9SKatayama Hirofumi MZ     {
19968f719cb9SKatayama Hirofumi MZ         pimeui = ((PIMEWND)pImeWnd)->pimeui;
19978f719cb9SKatayama Hirofumi MZ         _SEH2_TRY
19988f719cb9SKatayama Hirofumi MZ         {
19998f719cb9SKatayama Hirofumi MZ             ProbeForWrite(pimeui, sizeof(IMEUI), 1);
20008f719cb9SKatayama Hirofumi MZ             pimeui->fDefault = TRUE;
20018f719cb9SKatayama Hirofumi MZ             if (IS_WND_CHILD(pwndTarget) && pwndTarget->spwndParent->head.pti != pti)
20028f719cb9SKatayama Hirofumi MZ                 pimeui->fChildThreadDef = TRUE;
20038f719cb9SKatayama Hirofumi MZ         }
20048f719cb9SKatayama Hirofumi MZ         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
20058f719cb9SKatayama Hirofumi MZ         {
20061ef98fffSKatayama Hirofumi MZ             ERR("%p\n", pimeui);
20078f719cb9SKatayama Hirofumi MZ         }
20088f719cb9SKatayama Hirofumi MZ         _SEH2_END;
20098f719cb9SKatayama Hirofumi MZ     }
20108f719cb9SKatayama Hirofumi MZ 
20118f719cb9SKatayama Hirofumi MZ     UserDerefObjectCo(pwndTarget);
20128f719cb9SKatayama Hirofumi MZ     return pImeWnd;
20138f719cb9SKatayama Hirofumi MZ }
20148f719cb9SKatayama Hirofumi MZ 
20158f719cb9SKatayama Hirofumi MZ // Determines whether the system can destroy the default IME window for the target child window.
20164bcf23d1SKatayama Hirofumi MZ // Win: ImeCanDestroyDefIMEforChild
IntImeCanDestroyDefIMEforChild(PWND pImeWnd,PWND pwndTarget)20174bcf23d1SKatayama Hirofumi MZ BOOL FASTCALL IntImeCanDestroyDefIMEforChild(PWND pImeWnd, PWND pwndTarget)
20184bcf23d1SKatayama Hirofumi MZ {
20194bcf23d1SKatayama Hirofumi MZ     PWND pwndNode;
20204bcf23d1SKatayama Hirofumi MZ     PIMEUI pimeui;
20214bcf23d1SKatayama Hirofumi MZ     IMEUI SafeImeUI;
20224bcf23d1SKatayama Hirofumi MZ 
20234bcf23d1SKatayama Hirofumi MZ     pimeui = ((PIMEWND)pImeWnd)->pimeui;
20244bcf23d1SKatayama Hirofumi MZ     if (!pimeui || (LONG_PTR)pimeui == (LONG_PTR)-1)
20254bcf23d1SKatayama Hirofumi MZ         return FALSE;
20264bcf23d1SKatayama Hirofumi MZ 
20274bcf23d1SKatayama Hirofumi MZ     // Check IMEUI.fChildThreadDef
20284bcf23d1SKatayama Hirofumi MZ     _SEH2_TRY
20294bcf23d1SKatayama Hirofumi MZ     {
20304bcf23d1SKatayama Hirofumi MZ         ProbeForRead(pimeui, sizeof(IMEUI), 1);
20314bcf23d1SKatayama Hirofumi MZ         SafeImeUI = *pimeui;
20324bcf23d1SKatayama Hirofumi MZ         if (!SafeImeUI.fChildThreadDef)
20334bcf23d1SKatayama Hirofumi MZ             return FALSE;
20344bcf23d1SKatayama Hirofumi MZ     }
20354bcf23d1SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
20364bcf23d1SKatayama Hirofumi MZ     {
20371ef98fffSKatayama Hirofumi MZ         ERR("%p\n", pimeui);
20384bcf23d1SKatayama Hirofumi MZ     }
20394bcf23d1SKatayama Hirofumi MZ     _SEH2_END;
20404bcf23d1SKatayama Hirofumi MZ 
20414bcf23d1SKatayama Hirofumi MZ     // The parent of pwndTarget is NULL or of the same thread of pwndTarget?
20424bcf23d1SKatayama Hirofumi MZ     if (pwndTarget->spwndParent == NULL ||
20434bcf23d1SKatayama Hirofumi MZ         pwndTarget->head.pti == pwndTarget->spwndParent->head.pti)
20444bcf23d1SKatayama Hirofumi MZ     {
20454bcf23d1SKatayama Hirofumi MZ         return FALSE;
20464bcf23d1SKatayama Hirofumi MZ     }
20474bcf23d1SKatayama Hirofumi MZ 
20484bcf23d1SKatayama Hirofumi MZ     for (pwndNode = pwndTarget; pwndNode; pwndNode = pwndNode->spwndParent)
20494bcf23d1SKatayama Hirofumi MZ     {
20504bcf23d1SKatayama Hirofumi MZ         if (pwndNode == pwndNode->head.rpdesk->pDeskInfo->spwnd)
20514bcf23d1SKatayama Hirofumi MZ             break;
20524bcf23d1SKatayama Hirofumi MZ 
20534bcf23d1SKatayama Hirofumi MZ         if (IntFindNonImeRelatedWndOfSameThread(pwndNode->spwndParent, pwndTarget))
20544bcf23d1SKatayama Hirofumi MZ             return FALSE;
20554bcf23d1SKatayama Hirofumi MZ     }
20564bcf23d1SKatayama Hirofumi MZ 
20574bcf23d1SKatayama Hirofumi MZ     return TRUE;
20584bcf23d1SKatayama Hirofumi MZ }
20594bcf23d1SKatayama Hirofumi MZ 
20608f719cb9SKatayama Hirofumi MZ // Determines whether the system can destroy the default IME window for the non-child target window.
20614bcf23d1SKatayama Hirofumi MZ // Win: ImeCanDestroyDefIME
IntImeCanDestroyDefIME(PWND pImeWnd,PWND pwndTarget)20624bcf23d1SKatayama Hirofumi MZ BOOL FASTCALL IntImeCanDestroyDefIME(PWND pImeWnd, PWND pwndTarget)
20634bcf23d1SKatayama Hirofumi MZ {
20644bcf23d1SKatayama Hirofumi MZ     PWND pwndNode;
20654bcf23d1SKatayama Hirofumi MZ     PIMEUI pimeui;
20664bcf23d1SKatayama Hirofumi MZ     IMEUI SafeImeUI;
20674bcf23d1SKatayama Hirofumi MZ 
20684bcf23d1SKatayama Hirofumi MZ     pimeui = ((PIMEWND)pImeWnd)->pimeui;
20694bcf23d1SKatayama Hirofumi MZ     if (!pimeui || (LONG_PTR)pimeui == (LONG_PTR)-1)
20704bcf23d1SKatayama Hirofumi MZ         return FALSE;
20714bcf23d1SKatayama Hirofumi MZ 
20724bcf23d1SKatayama Hirofumi MZ     // Check IMEUI.fDestroy
20734bcf23d1SKatayama Hirofumi MZ     _SEH2_TRY
20744bcf23d1SKatayama Hirofumi MZ     {
20754bcf23d1SKatayama Hirofumi MZ         ProbeForRead(pimeui, sizeof(IMEUI), 1);
20764bcf23d1SKatayama Hirofumi MZ         SafeImeUI = *pimeui;
20774bcf23d1SKatayama Hirofumi MZ         if (SafeImeUI.fDestroy)
20784bcf23d1SKatayama Hirofumi MZ             return FALSE;
20794bcf23d1SKatayama Hirofumi MZ     }
20804bcf23d1SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
20814bcf23d1SKatayama Hirofumi MZ     {
20821ef98fffSKatayama Hirofumi MZ         ERR("%p\n", pimeui);
20834bcf23d1SKatayama Hirofumi MZ     }
20844bcf23d1SKatayama Hirofumi MZ     _SEH2_END;
20854bcf23d1SKatayama Hirofumi MZ 
20864bcf23d1SKatayama Hirofumi MZ     // Any ancestor of pImeWnd is pwndTarget?
20874bcf23d1SKatayama Hirofumi MZ     if (pImeWnd->spwndOwner)
20884bcf23d1SKatayama Hirofumi MZ     {
20894bcf23d1SKatayama Hirofumi MZ         for (pwndNode = pImeWnd->spwndOwner; pwndNode; pwndNode = pwndNode->spwndOwner)
20904bcf23d1SKatayama Hirofumi MZ         {
20914bcf23d1SKatayama Hirofumi MZ             if (pwndNode == pwndTarget)
20924bcf23d1SKatayama Hirofumi MZ                 break;
20934bcf23d1SKatayama Hirofumi MZ         }
20944bcf23d1SKatayama Hirofumi MZ 
20954bcf23d1SKatayama Hirofumi MZ         if (!pwndNode)
20964bcf23d1SKatayama Hirofumi MZ             return FALSE;
20974bcf23d1SKatayama Hirofumi MZ     }
20984bcf23d1SKatayama Hirofumi MZ 
20994bcf23d1SKatayama Hirofumi MZ     // Any ancestor of pwndTarget is IME-like?
21004bcf23d1SKatayama Hirofumi MZ     for (pwndNode = pwndTarget; pwndNode; pwndNode = pwndNode->spwndOwner)
21014bcf23d1SKatayama Hirofumi MZ     {
21024bcf23d1SKatayama Hirofumi MZ         if (IS_WND_IMELIKE(pwndNode))
21034bcf23d1SKatayama Hirofumi MZ             return FALSE;
21044bcf23d1SKatayama Hirofumi MZ     }
21054bcf23d1SKatayama Hirofumi MZ 
21064bcf23d1SKatayama Hirofumi MZ     // Adjust the ordering and top-mode status
21074bcf23d1SKatayama Hirofumi MZ     IntImeSetFutureOwner(pImeWnd, pwndTarget);
21084bcf23d1SKatayama Hirofumi MZ     for (pwndNode = pImeWnd->spwndOwner; pwndNode; pwndNode = pwndNode->spwndNext)
21094bcf23d1SKatayama Hirofumi MZ     {
21104bcf23d1SKatayama Hirofumi MZ         if (pwndNode == pImeWnd)
21114bcf23d1SKatayama Hirofumi MZ             break;
21124bcf23d1SKatayama Hirofumi MZ     }
21134bcf23d1SKatayama Hirofumi MZ     if (pwndNode == pImeWnd)
21144bcf23d1SKatayama Hirofumi MZ         IntImeCheckTopmost(pImeWnd);
21154bcf23d1SKatayama Hirofumi MZ 
21164bcf23d1SKatayama Hirofumi MZ     // Is the owner of pImeWnd NULL or pwndTarget?
21174bcf23d1SKatayama Hirofumi MZ     if (pImeWnd->spwndOwner && pwndTarget != pImeWnd->spwndOwner)
21184bcf23d1SKatayama Hirofumi MZ         return FALSE;
21194bcf23d1SKatayama Hirofumi MZ 
2120e56da485STimo Kreuzer     WndSetOwner(pImeWnd, NULL);
21214bcf23d1SKatayama Hirofumi MZ     return TRUE;
21224bcf23d1SKatayama Hirofumi MZ }
21234bcf23d1SKatayama Hirofumi MZ 
2124242e0b43SKatayama Hirofumi MZ // Update IMEUI.fShowStatus flags and Send the WM_IME_NOTIFY messages.
2125242e0b43SKatayama Hirofumi MZ // Win: xxxCheckImeShowStatus
IntCheckImeShowStatus(PWND pwndIme,PTHREADINFO pti)2126242e0b43SKatayama Hirofumi MZ BOOL FASTCALL IntCheckImeShowStatus(PWND pwndIme, PTHREADINFO pti)
2127242e0b43SKatayama Hirofumi MZ {
2128242e0b43SKatayama Hirofumi MZ     BOOL ret = FALSE, bDifferent;
2129242e0b43SKatayama Hirofumi MZ     PWINDOWLIST pwl;
2130242e0b43SKatayama Hirofumi MZ     HWND *phwnd;
2131242e0b43SKatayama Hirofumi MZ     PWND pwndNode, pwndIMC;
2132242e0b43SKatayama Hirofumi MZ     PTHREADINFO ptiCurrent = GetW32ThreadInfo();
2133242e0b43SKatayama Hirofumi MZ     PIMEUI pimeui;
2134242e0b43SKatayama Hirofumi MZ     IMEUI SafeImeUI;
2135242e0b43SKatayama Hirofumi MZ 
2136242e0b43SKatayama Hirofumi MZ     if (pwndIme->state2 & WNDS2_INDESTROY)
2137242e0b43SKatayama Hirofumi MZ         return FALSE;
2138242e0b43SKatayama Hirofumi MZ 
2139242e0b43SKatayama Hirofumi MZ     // Build a window list
2140242e0b43SKatayama Hirofumi MZ     pwl = IntBuildHwndList(pwndIme->spwndParent->spwndChild, IACE_LIST, NULL);
2141242e0b43SKatayama Hirofumi MZ     if (!pwl)
2142242e0b43SKatayama Hirofumi MZ         return FALSE;
2143242e0b43SKatayama Hirofumi MZ 
2144242e0b43SKatayama Hirofumi MZ     ret = TRUE;
2145242e0b43SKatayama Hirofumi MZ     for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
2146242e0b43SKatayama Hirofumi MZ     {
2147242e0b43SKatayama Hirofumi MZ         pwndNode = ValidateHwndNoErr(*phwnd);
2148242e0b43SKatayama Hirofumi MZ 
2149242e0b43SKatayama Hirofumi MZ         if (!pwndNode || pwndIme == pwndNode)
2150242e0b43SKatayama Hirofumi MZ             continue;
2151242e0b43SKatayama Hirofumi MZ 
2152242e0b43SKatayama Hirofumi MZ         if (pwndNode->pcls->atomClassName != gpsi->atomSysClass[ICLS_IME] ||
2153242e0b43SKatayama Hirofumi MZ             (pwndNode->state2 & WNDS2_INDESTROY))
2154242e0b43SKatayama Hirofumi MZ         {
2155242e0b43SKatayama Hirofumi MZ             continue;
2156242e0b43SKatayama Hirofumi MZ         }
2157242e0b43SKatayama Hirofumi MZ 
2158242e0b43SKatayama Hirofumi MZ         pimeui = ((PIMEWND)pwndNode)->pimeui;
2159242e0b43SKatayama Hirofumi MZ         if (!pimeui || pimeui == (PIMEUI)-1)
2160242e0b43SKatayama Hirofumi MZ             continue;
2161242e0b43SKatayama Hirofumi MZ 
2162242e0b43SKatayama Hirofumi MZ         if (pti && pti != pwndNode->head.pti)
2163242e0b43SKatayama Hirofumi MZ             continue;
2164242e0b43SKatayama Hirofumi MZ 
2165242e0b43SKatayama Hirofumi MZ         // Attach to the process if necessary
2166242e0b43SKatayama Hirofumi MZ         bDifferent = FALSE;
2167242e0b43SKatayama Hirofumi MZ         if (pwndNode->head.pti->ppi != ptiCurrent->ppi)
2168242e0b43SKatayama Hirofumi MZ         {
2169242e0b43SKatayama Hirofumi MZ             KeAttachProcess(&(pwndNode->head.pti->ppi->peProcess->Pcb));
2170242e0b43SKatayama Hirofumi MZ             bDifferent = TRUE;
2171242e0b43SKatayama Hirofumi MZ         }
2172242e0b43SKatayama Hirofumi MZ 
2173242e0b43SKatayama Hirofumi MZ         // Get pwndIMC and update IMEUI.fShowStatus flag
2174242e0b43SKatayama Hirofumi MZ         _SEH2_TRY
2175242e0b43SKatayama Hirofumi MZ         {
2176242e0b43SKatayama Hirofumi MZ             ProbeForWrite(pimeui, sizeof(IMEUI), 1);
2177242e0b43SKatayama Hirofumi MZ             SafeImeUI = *pimeui;
2178242e0b43SKatayama Hirofumi MZ             if (SafeImeUI.fShowStatus)
2179242e0b43SKatayama Hirofumi MZ             {
2180242e0b43SKatayama Hirofumi MZ                 pwndIMC = ValidateHwndNoErr(pimeui->hwndIMC);
2181242e0b43SKatayama Hirofumi MZ                 if (pwndIMC)
2182242e0b43SKatayama Hirofumi MZ                     pimeui->fShowStatus = FALSE;
2183242e0b43SKatayama Hirofumi MZ             }
2184242e0b43SKatayama Hirofumi MZ             else
2185242e0b43SKatayama Hirofumi MZ             {
2186242e0b43SKatayama Hirofumi MZ                 pwndIMC = NULL;
2187242e0b43SKatayama Hirofumi MZ             }
2188242e0b43SKatayama Hirofumi MZ         }
2189242e0b43SKatayama Hirofumi MZ         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2190242e0b43SKatayama Hirofumi MZ         {
21911ef98fffSKatayama Hirofumi MZ             ERR("%p\n", pimeui);
2192242e0b43SKatayama Hirofumi MZ             pwndIMC = NULL;
2193242e0b43SKatayama Hirofumi MZ         }
2194242e0b43SKatayama Hirofumi MZ         _SEH2_END;
2195242e0b43SKatayama Hirofumi MZ 
2196242e0b43SKatayama Hirofumi MZ         // Detach from the process if necessary
2197242e0b43SKatayama Hirofumi MZ         if (bDifferent)
2198242e0b43SKatayama Hirofumi MZ             KeDetachProcess();
2199242e0b43SKatayama Hirofumi MZ 
2200242e0b43SKatayama Hirofumi MZ         // Send the WM_IME_NOTIFY message
2201242e0b43SKatayama Hirofumi MZ         if (pwndIMC && pwndIMC->head.pti && !(pwndIMC->head.pti->TIF_flags & TIF_INCLEANUP))
2202242e0b43SKatayama Hirofumi MZ         {
2203242e0b43SKatayama Hirofumi MZ             HWND hImeWnd;
2204242e0b43SKatayama Hirofumi MZ             USER_REFERENCE_ENTRY Ref;
2205242e0b43SKatayama Hirofumi MZ 
2206242e0b43SKatayama Hirofumi MZ             UserRefObjectCo(pwndIMC, &Ref);
2207242e0b43SKatayama Hirofumi MZ 
2208242e0b43SKatayama Hirofumi MZ             hImeWnd = UserHMGetHandle(pwndIMC);
2209242e0b43SKatayama Hirofumi MZ             co_IntSendMessage(hImeWnd, WM_IME_NOTIFY, IMN_CLOSESTATUSWINDOW, 0);
2210242e0b43SKatayama Hirofumi MZ 
2211242e0b43SKatayama Hirofumi MZ             UserDerefObjectCo(pwndIMC);
2212242e0b43SKatayama Hirofumi MZ         }
2213242e0b43SKatayama Hirofumi MZ     }
2214242e0b43SKatayama Hirofumi MZ 
2215242e0b43SKatayama Hirofumi MZ     // Free the window list
2216242e0b43SKatayama Hirofumi MZ     IntFreeHwndList(pwl);
2217242e0b43SKatayama Hirofumi MZ     return ret;
2218242e0b43SKatayama Hirofumi MZ }
2219242e0b43SKatayama Hirofumi MZ 
2220242e0b43SKatayama Hirofumi MZ // Send a UI message.
2221242e0b43SKatayama Hirofumi MZ LRESULT FASTCALL
IntSendMessageToUI(PTHREADINFO ptiIME,PIMEUI pimeui,UINT uMsg,WPARAM wParam,LPARAM lParam)2222242e0b43SKatayama Hirofumi MZ IntSendMessageToUI(PTHREADINFO ptiIME, PIMEUI pimeui, UINT uMsg, WPARAM wParam, LPARAM lParam)
2223242e0b43SKatayama Hirofumi MZ {
2224242e0b43SKatayama Hirofumi MZ     PWND pwndUI;
2225242e0b43SKatayama Hirofumi MZ     LRESULT ret = 0;
2226242e0b43SKatayama Hirofumi MZ     IMEUI SafeImeUI;
2227242e0b43SKatayama Hirofumi MZ     BOOL bDifferent = FALSE;
2228242e0b43SKatayama Hirofumi MZ     USER_REFERENCE_ENTRY Ref;
2229242e0b43SKatayama Hirofumi MZ 
2230242e0b43SKatayama Hirofumi MZ     // Attach to the process if necessary
2231242e0b43SKatayama Hirofumi MZ     if (ptiIME != GetW32ThreadInfo())
2232242e0b43SKatayama Hirofumi MZ     {
2233242e0b43SKatayama Hirofumi MZ         bDifferent = TRUE;
2234242e0b43SKatayama Hirofumi MZ         KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2235242e0b43SKatayama Hirofumi MZ     }
2236242e0b43SKatayama Hirofumi MZ 
2237242e0b43SKatayama Hirofumi MZ     // Get the pwndUI
2238242e0b43SKatayama Hirofumi MZ     _SEH2_TRY
2239242e0b43SKatayama Hirofumi MZ     {
2240242e0b43SKatayama Hirofumi MZ         ProbeForRead(pimeui, sizeof(IMEUI), 1);
2241242e0b43SKatayama Hirofumi MZ         SafeImeUI = *pimeui;
2242242e0b43SKatayama Hirofumi MZ         pwndUI = ValidateHwndNoErr(SafeImeUI.hwndUI);
2243242e0b43SKatayama Hirofumi MZ     }
2244242e0b43SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2245242e0b43SKatayama Hirofumi MZ     {
22461ef98fffSKatayama Hirofumi MZ         ERR("%p\n", pimeui);
2247242e0b43SKatayama Hirofumi MZ         pwndUI = NULL;
2248242e0b43SKatayama Hirofumi MZ     }
2249242e0b43SKatayama Hirofumi MZ     _SEH2_END;
2250242e0b43SKatayama Hirofumi MZ 
2251242e0b43SKatayama Hirofumi MZ     if (!pwndUI)
2252242e0b43SKatayama Hirofumi MZ         goto Quit;
2253242e0b43SKatayama Hirofumi MZ 
2254242e0b43SKatayama Hirofumi MZ     // Increment the recursion count of the IME procedure.
2255242e0b43SKatayama Hirofumi MZ     // See also ImeWndProc_common of user32.
2256242e0b43SKatayama Hirofumi MZ     _SEH2_TRY
2257242e0b43SKatayama Hirofumi MZ     {
2258242e0b43SKatayama Hirofumi MZ         ProbeForWrite(&pimeui->nCntInIMEProc, sizeof(LONG), 1);
2259242e0b43SKatayama Hirofumi MZ         InterlockedIncrement(&pimeui->nCntInIMEProc);
2260242e0b43SKatayama Hirofumi MZ     }
2261242e0b43SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2262242e0b43SKatayama Hirofumi MZ     {
22631ef98fffSKatayama Hirofumi MZ         ERR("%p\n", pimeui);
22649751d03cSKatayama Hirofumi MZ         _SEH2_YIELD(goto Quit);
2265242e0b43SKatayama Hirofumi MZ     }
2266242e0b43SKatayama Hirofumi MZ     _SEH2_END;
2267242e0b43SKatayama Hirofumi MZ 
2268242e0b43SKatayama Hirofumi MZ     // Detach from the process if necessary
2269242e0b43SKatayama Hirofumi MZ     if (bDifferent)
2270242e0b43SKatayama Hirofumi MZ         KeDetachProcess();
2271242e0b43SKatayama Hirofumi MZ 
2272242e0b43SKatayama Hirofumi MZ     UserRefObjectCo(pwndUI, &Ref);
2273242e0b43SKatayama Hirofumi MZ     ret = co_IntSendMessage(UserHMGetHandle(pwndUI), uMsg, wParam, lParam);
2274242e0b43SKatayama Hirofumi MZ     UserDerefObjectCo(pwndUI);
2275242e0b43SKatayama Hirofumi MZ 
2276242e0b43SKatayama Hirofumi MZ     // Attach to the process if necessary
2277242e0b43SKatayama Hirofumi MZ     if (bDifferent)
2278242e0b43SKatayama Hirofumi MZ         KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2279242e0b43SKatayama Hirofumi MZ 
2280242e0b43SKatayama Hirofumi MZ     // Decrement the recursion count of the IME procedure
2281242e0b43SKatayama Hirofumi MZ     _SEH2_TRY
2282242e0b43SKatayama Hirofumi MZ     {
2283242e0b43SKatayama Hirofumi MZ         ProbeForWrite(&pimeui->nCntInIMEProc, sizeof(LONG), 1);
2284242e0b43SKatayama Hirofumi MZ         InterlockedDecrement(&pimeui->nCntInIMEProc);
2285242e0b43SKatayama Hirofumi MZ     }
2286242e0b43SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2287242e0b43SKatayama Hirofumi MZ     {
22881ef98fffSKatayama Hirofumi MZ         ERR("%p\n", pimeui);
22899751d03cSKatayama Hirofumi MZ         _SEH2_YIELD(goto Quit);
2290242e0b43SKatayama Hirofumi MZ     }
2291242e0b43SKatayama Hirofumi MZ     _SEH2_END;
2292242e0b43SKatayama Hirofumi MZ 
2293242e0b43SKatayama Hirofumi MZ Quit:
2294242e0b43SKatayama Hirofumi MZ     // Detach from the process if necessary
2295242e0b43SKatayama Hirofumi MZ     if (bDifferent)
2296242e0b43SKatayama Hirofumi MZ         KeDetachProcess();
2297242e0b43SKatayama Hirofumi MZ 
2298242e0b43SKatayama Hirofumi MZ     return ret;
2299242e0b43SKatayama Hirofumi MZ }
2300242e0b43SKatayama Hirofumi MZ 
2301242e0b43SKatayama Hirofumi MZ // Send the open status notification.
2302242e0b43SKatayama Hirofumi MZ // Win: xxxSendOpenStatusNotify
2303242e0b43SKatayama Hirofumi MZ VOID FASTCALL
IntSendOpenStatusNotify(PTHREADINFO ptiIME,PIMEUI pimeui,PWND pWnd,BOOL bOpen)2304242e0b43SKatayama Hirofumi MZ IntSendOpenStatusNotify(PTHREADINFO ptiIME, PIMEUI pimeui, PWND pWnd, BOOL bOpen)
2305242e0b43SKatayama Hirofumi MZ {
2306242e0b43SKatayama Hirofumi MZ     WPARAM wParam = (bOpen ? IMN_OPENSTATUSWINDOW : IMN_CLOSESTATUSWINDOW);
2307242e0b43SKatayama Hirofumi MZ     PTHREADINFO ptiWnd = pWnd->head.pti;
2308242e0b43SKatayama Hirofumi MZ     USER_REFERENCE_ENTRY Ref;
2309242e0b43SKatayama Hirofumi MZ 
2310242e0b43SKatayama Hirofumi MZ     if (ptiWnd->dwExpWinVer >= WINVER_WINNT4 && pWnd->hImc)
2311242e0b43SKatayama Hirofumi MZ     {
2312242e0b43SKatayama Hirofumi MZ         UserRefObjectCo(pWnd, &Ref);
2313242e0b43SKatayama Hirofumi MZ         co_IntSendMessage(UserHMGetHandle(pWnd), WM_IME_NOTIFY, wParam, 0);
2314242e0b43SKatayama Hirofumi MZ         UserDerefObjectCo(pWnd);
2315242e0b43SKatayama Hirofumi MZ     }
2316242e0b43SKatayama Hirofumi MZ     else
2317242e0b43SKatayama Hirofumi MZ     {
2318242e0b43SKatayama Hirofumi MZ         IntSendMessageToUI(ptiIME, pimeui, WM_IME_NOTIFY, wParam, 0);
2319242e0b43SKatayama Hirofumi MZ     }
2320242e0b43SKatayama Hirofumi MZ }
2321242e0b43SKatayama Hirofumi MZ 
2322242e0b43SKatayama Hirofumi MZ // Update the IME status and send a notification.
IntNotifyImeShowStatus(PWND pImeWnd)2323242e0b43SKatayama Hirofumi MZ VOID FASTCALL IntNotifyImeShowStatus(PWND pImeWnd)
2324242e0b43SKatayama Hirofumi MZ {
2325242e0b43SKatayama Hirofumi MZ     PIMEUI pimeui;
2326242e0b43SKatayama Hirofumi MZ     PWND pWnd;
2327242e0b43SKatayama Hirofumi MZ     PTHREADINFO pti, ptiIME;
2328242e0b43SKatayama Hirofumi MZ     BOOL bShow, bSendNotify = FALSE;
2329242e0b43SKatayama Hirofumi MZ     IMEUI SafeImeUI;
2330242e0b43SKatayama Hirofumi MZ 
2331242e0b43SKatayama Hirofumi MZ     if (!IS_IMM_MODE() || (pImeWnd->state2 & WNDS2_INDESTROY))
2332242e0b43SKatayama Hirofumi MZ         return;
2333242e0b43SKatayama Hirofumi MZ 
2334242e0b43SKatayama Hirofumi MZ     pti = PsGetCurrentThreadWin32Thread();
2335242e0b43SKatayama Hirofumi MZ     ptiIME = pImeWnd->head.pti;
2336242e0b43SKatayama Hirofumi MZ 
2337242e0b43SKatayama Hirofumi MZ     // Attach to the process if necessary
2338242e0b43SKatayama Hirofumi MZ     if (pti != ptiIME)
2339242e0b43SKatayama Hirofumi MZ         KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2340242e0b43SKatayama Hirofumi MZ 
2341242e0b43SKatayama Hirofumi MZ     // Get an IMEUI and check whether hwndIMC is valid and update fShowStatus
2342242e0b43SKatayama Hirofumi MZ     _SEH2_TRY
2343242e0b43SKatayama Hirofumi MZ     {
2344242e0b43SKatayama Hirofumi MZ         ProbeForWrite(pImeWnd, sizeof(IMEWND), 1);
2345242e0b43SKatayama Hirofumi MZ         pimeui = ((PIMEWND)pImeWnd)->pimeui;
2346242e0b43SKatayama Hirofumi MZ         SafeImeUI = *pimeui;
2347242e0b43SKatayama Hirofumi MZ 
2348242e0b43SKatayama Hirofumi MZ         bShow = (gfIMEShowStatus == TRUE) && SafeImeUI.fCtrlShowStatus;
2349242e0b43SKatayama Hirofumi MZ 
2350242e0b43SKatayama Hirofumi MZ         pWnd = ValidateHwndNoErr(SafeImeUI.hwndIMC);
2351242e0b43SKatayama Hirofumi MZ         if (!pWnd)
2352242e0b43SKatayama Hirofumi MZ             pWnd = ptiIME->MessageQueue->spwndFocus;
2353242e0b43SKatayama Hirofumi MZ 
2354242e0b43SKatayama Hirofumi MZ         if (pWnd)
2355242e0b43SKatayama Hirofumi MZ         {
2356242e0b43SKatayama Hirofumi MZ             bSendNotify = TRUE;
2357242e0b43SKatayama Hirofumi MZ             pimeui->fShowStatus = bShow;
2358242e0b43SKatayama Hirofumi MZ         }
2359242e0b43SKatayama Hirofumi MZ     }
2360242e0b43SKatayama Hirofumi MZ     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2361242e0b43SKatayama Hirofumi MZ     {
23621ef98fffSKatayama Hirofumi MZ         ERR("%p, %p\n", pImeWnd, pimeui);
23634ab7c93bSKatayama Hirofumi MZ 
2364242e0b43SKatayama Hirofumi MZ         if (pti != ptiIME)
2365242e0b43SKatayama Hirofumi MZ             KeDetachProcess();
23664ab7c93bSKatayama Hirofumi MZ 
23674ab7c93bSKatayama Hirofumi MZ         _SEH2_YIELD(return);
2368242e0b43SKatayama Hirofumi MZ     }
2369242e0b43SKatayama Hirofumi MZ     _SEH2_END;
2370242e0b43SKatayama Hirofumi MZ 
2371242e0b43SKatayama Hirofumi MZ     // Detach from the process if necessary
2372242e0b43SKatayama Hirofumi MZ     if (pti != ptiIME)
2373242e0b43SKatayama Hirofumi MZ         KeDetachProcess();
2374242e0b43SKatayama Hirofumi MZ 
2375242e0b43SKatayama Hirofumi MZ     if (bSendNotify)
2376242e0b43SKatayama Hirofumi MZ         IntSendOpenStatusNotify(ptiIME, &SafeImeUI, pWnd, bShow);
2377242e0b43SKatayama Hirofumi MZ 
2378242e0b43SKatayama Hirofumi MZ     if (!(pImeWnd->state2 & WNDS2_INDESTROY))
2379242e0b43SKatayama Hirofumi MZ         IntCheckImeShowStatus(pImeWnd, NULL);
2380242e0b43SKatayama Hirofumi MZ }
2381242e0b43SKatayama Hirofumi MZ 
2382242e0b43SKatayama Hirofumi MZ // Win: xxxBroadcastImeShowStatusChange
IntBroadcastImeShowStatusChange(PWND pImeWnd,BOOL bShow)2383242e0b43SKatayama Hirofumi MZ BOOL FASTCALL IntBroadcastImeShowStatusChange(PWND pImeWnd, BOOL bShow)
2384242e0b43SKatayama Hirofumi MZ {
2385242e0b43SKatayama Hirofumi MZ     if (gfIMEShowStatus == bShow || !IS_IMM_MODE())
2386242e0b43SKatayama Hirofumi MZ         return TRUE;
2387242e0b43SKatayama Hirofumi MZ 
2388242e0b43SKatayama Hirofumi MZ     gfIMEShowStatus = bShow;
2389242e0b43SKatayama Hirofumi MZ     IntNotifyImeShowStatus(pImeWnd);
2390242e0b43SKatayama Hirofumi MZ     return TRUE;
2391242e0b43SKatayama Hirofumi MZ }
2392242e0b43SKatayama Hirofumi MZ 
23937cc89e52SKatayama Hirofumi MZ /* Win: xxxCheckImeShowStatusInThread */
IntCheckImeShowStatusInThread(PWND pImeWnd)23947cc89e52SKatayama Hirofumi MZ VOID FASTCALL IntCheckImeShowStatusInThread(PWND pImeWnd)
23957cc89e52SKatayama Hirofumi MZ {
23967cc89e52SKatayama Hirofumi MZ     if (IS_IMM_MODE() && !(pImeWnd->state2 & WNDS2_INDESTROY))
23977cc89e52SKatayama Hirofumi MZ         IntCheckImeShowStatus(pImeWnd, pImeWnd->head.pti);
23987cc89e52SKatayama Hirofumi MZ }
23997cc89e52SKatayama Hirofumi MZ 
2400c2c66affSColin Finck /* EOF */
2401