1c2c66affSColin Finck /* 2c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory 3c2c66affSColin Finck * PROJECT: ReactOS Win32k subsystem 4c2c66affSColin Finck * PURPOSE: Input Method Editor and Input Method Manager support 5c2c66affSColin Finck * FILE: win32ss/user/ntuser/ime.c 63d78601fSKatayama Hirofumi MZ * PROGRAMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 73d78601fSKatayama Hirofumi MZ * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 8c2c66affSColin Finck */ 9c2c66affSColin Finck 10c2c66affSColin Finck #include <win32k.h> 11c2c66affSColin Finck DBG_DEFAULT_CHANNEL(UserMisc); 12c2c66affSColin Finck 13fcc222c2SKatayama Hirofumi MZ #define INVALID_THREAD_ID ((ULONG)-1) 14bbe5fd52SKatayama Hirofumi MZ #define INVALID_HOTKEY ((UINT)-1) 155d5cc578SKatayama Hirofumi MZ #define MOD_KEYS (MOD_CONTROL | MOD_SHIFT | MOD_ALT | MOD_WIN) 165d5cc578SKatayama Hirofumi MZ #define MOD_LEFT_RIGHT (MOD_LEFT | MOD_RIGHT) 175d5cc578SKatayama Hirofumi MZ 185d5cc578SKatayama Hirofumi MZ #define LANGID_CHINESE_SIMPLIFIED MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) 195d5cc578SKatayama Hirofumi MZ #define LANGID_JAPANESE MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT) 205d5cc578SKatayama Hirofumi MZ #define LANGID_KOREAN MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN) 215d5cc578SKatayama Hirofumi MZ #define LANGID_CHINESE_TRADITIONAL MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL) 225d5cc578SKatayama Hirofumi MZ #define LANGID_NEUTRAL MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) 23c2c66affSColin Finck 249db44371SKatayama Hirofumi MZ // The special virtual keys for Japanese: Used for key states. 259db44371SKatayama Hirofumi MZ // https://www.kthree.co.jp/kihelp/index.html?page=app/vkey&type=html 269db44371SKatayama Hirofumi MZ #define VK_DBE_ALPHANUMERIC 0xF0 279db44371SKatayama Hirofumi MZ #define VK_DBE_KATAKANA 0xF1 289db44371SKatayama Hirofumi MZ #define VK_DBE_HIRAGANA 0xF2 299db44371SKatayama Hirofumi MZ #define VK_DBE_SBCSCHAR 0xF3 309db44371SKatayama Hirofumi MZ #define VK_DBE_DBCSCHAR 0xF4 319db44371SKatayama Hirofumi MZ #define VK_DBE_ROMAN 0xF5 329db44371SKatayama Hirofumi MZ #define VK_DBE_NOROMAN 0xF6 339db44371SKatayama Hirofumi MZ #define VK_DBE_ENTERWORDREGISTERMODE 0xF7 349db44371SKatayama Hirofumi MZ #define VK_DBE_ENTERCONFIGMODE 0xF8 359db44371SKatayama Hirofumi MZ #define VK_DBE_FLUSHSTRING 0xF9 369db44371SKatayama Hirofumi MZ #define VK_DBE_CODEINPUT 0xFA 379db44371SKatayama Hirofumi MZ #define VK_DBE_NOCODEINPUT 0xFB 389db44371SKatayama Hirofumi MZ #define VK_DBE_DETERINESTRING 0xFC 399db44371SKatayama Hirofumi MZ #define VK_DBE_ENTERDLGCONVERSIONMODE 0xFD 409db44371SKatayama Hirofumi MZ 419db44371SKatayama Hirofumi MZ HIMC ghIMC = NULL; 429db44371SKatayama Hirofumi MZ BOOL gfImeOpen = (BOOL)-1; 439db44371SKatayama Hirofumi MZ DWORD gdwImeConversion = (DWORD)-1; 44242e0b43SKatayama Hirofumi MZ BOOL gfIMEShowStatus = (BOOL)-1; 459db44371SKatayama Hirofumi MZ 465d5cc578SKatayama Hirofumi MZ typedef struct tagIMEHOTKEY 475d5cc578SKatayama Hirofumi MZ { 485d5cc578SKatayama Hirofumi MZ struct tagIMEHOTKEY *pNext; 495d5cc578SKatayama Hirofumi MZ DWORD dwHotKeyId; 505d5cc578SKatayama Hirofumi MZ UINT uVirtualKey; 515d5cc578SKatayama Hirofumi MZ UINT uModifiers; 525d5cc578SKatayama Hirofumi MZ HKL hKL; 535d5cc578SKatayama Hirofumi MZ } IMEHOTKEY, *PIMEHOTKEY; 545d5cc578SKatayama Hirofumi MZ 555df5ef2bSKatayama Hirofumi MZ PIMEHOTKEY gpImeHotKeyList = NULL; // Win: gpImeHotKeyListHeader 565df5ef2bSKatayama Hirofumi MZ LCID glcidSystem = 0; // Win: glcidSystem 57bbe5fd52SKatayama Hirofumi MZ 585df5ef2bSKatayama Hirofumi MZ // Win: GetAppImeCompatFlags 59b5c9d532SKatayama Hirofumi MZ DWORD FASTCALL IntGetImeCompatFlags(PTHREADINFO pti) 60b5c9d532SKatayama Hirofumi MZ { 61b5c9d532SKatayama Hirofumi MZ if (!pti) 62b5c9d532SKatayama Hirofumi MZ pti = PsGetCurrentThreadWin32Thread(); 63b5c9d532SKatayama Hirofumi MZ 64b5c9d532SKatayama Hirofumi MZ return pti->ppi->dwImeCompatFlags; 65b5c9d532SKatayama Hirofumi MZ } 66b5c9d532SKatayama Hirofumi MZ 675df5ef2bSKatayama Hirofumi MZ // Win: GetLangIdMatchLevel 68bbe5fd52SKatayama Hirofumi MZ UINT FASTCALL IntGetImeHotKeyLanguageScore(HKL hKL, LANGID HotKeyLangId) 69bbe5fd52SKatayama Hirofumi MZ { 70bbe5fd52SKatayama Hirofumi MZ LCID lcid; 71bbe5fd52SKatayama Hirofumi MZ 72bbe5fd52SKatayama Hirofumi MZ if (HotKeyLangId == LANGID_NEUTRAL || HotKeyLangId == LOWORD(hKL)) 73bbe5fd52SKatayama Hirofumi MZ return 3; 74bbe5fd52SKatayama Hirofumi MZ 75bbe5fd52SKatayama Hirofumi MZ _SEH2_TRY 76bbe5fd52SKatayama Hirofumi MZ { 77bbe5fd52SKatayama Hirofumi MZ lcid = NtCurrentTeb()->CurrentLocale; 78bbe5fd52SKatayama Hirofumi MZ } 79bbe5fd52SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 80bbe5fd52SKatayama Hirofumi MZ { 81bbe5fd52SKatayama Hirofumi MZ lcid = MAKELCID(LANGID_NEUTRAL, SORT_DEFAULT); 82bbe5fd52SKatayama Hirofumi MZ } 83bbe5fd52SKatayama Hirofumi MZ _SEH2_END; 84bbe5fd52SKatayama Hirofumi MZ 85bbe5fd52SKatayama Hirofumi MZ if (HotKeyLangId == LANGIDFROMLCID(lcid)) 86bbe5fd52SKatayama Hirofumi MZ return 2; 87bbe5fd52SKatayama Hirofumi MZ 885df5ef2bSKatayama Hirofumi MZ if (glcidSystem == 0) 895df5ef2bSKatayama Hirofumi MZ ZwQueryDefaultLocale(FALSE, &glcidSystem); 90bbe5fd52SKatayama Hirofumi MZ 915df5ef2bSKatayama Hirofumi MZ if (HotKeyLangId == LANGIDFROMLCID(glcidSystem)) 92bbe5fd52SKatayama Hirofumi MZ return 1; 93bbe5fd52SKatayama Hirofumi MZ 94bbe5fd52SKatayama Hirofumi MZ return 0; 95bbe5fd52SKatayama Hirofumi MZ } 96bbe5fd52SKatayama Hirofumi MZ 975df5ef2bSKatayama Hirofumi MZ // Win: GetActiveHKL 98bbe5fd52SKatayama Hirofumi MZ HKL FASTCALL IntGetActiveKeyboardLayout(VOID) 99bbe5fd52SKatayama Hirofumi MZ { 100bbe5fd52SKatayama Hirofumi MZ PTHREADINFO pti; 101bbe5fd52SKatayama Hirofumi MZ 102bbe5fd52SKatayama Hirofumi MZ if (gpqForeground && gpqForeground->spwndActive) 103bbe5fd52SKatayama Hirofumi MZ { 104bbe5fd52SKatayama Hirofumi MZ pti = gpqForeground->spwndActive->head.pti; 105bbe5fd52SKatayama Hirofumi MZ if (pti && pti->KeyboardLayout) 106bbe5fd52SKatayama Hirofumi MZ return pti->KeyboardLayout->hkl; 107bbe5fd52SKatayama Hirofumi MZ } 108bbe5fd52SKatayama Hirofumi MZ 109bbe5fd52SKatayama Hirofumi MZ return UserGetKeyboardLayout(0); 110bbe5fd52SKatayama Hirofumi MZ } 1115d5cc578SKatayama Hirofumi MZ 1125df5ef2bSKatayama Hirofumi MZ // Win: GetHotKeyLangID 1135d5cc578SKatayama Hirofumi MZ static LANGID FASTCALL IntGetImeHotKeyLangId(DWORD dwHotKeyId) 1145d5cc578SKatayama Hirofumi MZ { 1155d5cc578SKatayama Hirofumi MZ #define IME_CHOTKEY 0x10 1165d5cc578SKatayama Hirofumi MZ #define IME_JHOTKEY 0x30 1175d5cc578SKatayama Hirofumi MZ #define IME_KHOTKEY 0x50 1185d5cc578SKatayama Hirofumi MZ #define IME_THOTKEY 0x70 1195d5cc578SKatayama Hirofumi MZ #define IME_XHOTKEY 0x90 1205d5cc578SKatayama Hirofumi MZ static const LANGID s_array[] = 1215d5cc578SKatayama Hirofumi MZ { 1225d5cc578SKatayama Hirofumi MZ /* 0x00 */ (WORD)-1, 1235d5cc578SKatayama Hirofumi MZ /* 0x10 */ LANGID_CHINESE_SIMPLIFIED, 1245d5cc578SKatayama Hirofumi MZ /* 0x20 */ LANGID_CHINESE_SIMPLIFIED, 1255d5cc578SKatayama Hirofumi MZ /* 0x30 */ LANGID_JAPANESE, 1265d5cc578SKatayama Hirofumi MZ /* 0x40 */ LANGID_JAPANESE, 1275d5cc578SKatayama Hirofumi MZ /* 0x50 */ LANGID_KOREAN, 1285d5cc578SKatayama Hirofumi MZ /* 0x60 */ LANGID_KOREAN, 1295d5cc578SKatayama Hirofumi MZ /* 0x70 */ LANGID_CHINESE_TRADITIONAL, 1305d5cc578SKatayama Hirofumi MZ /* 0x80 */ LANGID_CHINESE_TRADITIONAL 1315d5cc578SKatayama Hirofumi MZ }; 1325d5cc578SKatayama Hirofumi MZ 1335d5cc578SKatayama Hirofumi MZ if (IME_CHOTKEY <= dwHotKeyId && dwHotKeyId < IME_XHOTKEY) 1345d5cc578SKatayama Hirofumi MZ return s_array[(dwHotKeyId & 0xF0) >> 4]; 1355d5cc578SKatayama Hirofumi MZ return LANGID_NEUTRAL; 1365d5cc578SKatayama Hirofumi MZ } 1375d5cc578SKatayama Hirofumi MZ 1382f7775c6SKatayama Hirofumi MZ // Win: AddImeHotKey 1395d5cc578SKatayama Hirofumi MZ static VOID FASTCALL IntAddImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey) 1405d5cc578SKatayama Hirofumi MZ { 1415d5cc578SKatayama Hirofumi MZ PIMEHOTKEY pNode; 1425d5cc578SKatayama Hirofumi MZ 1435d5cc578SKatayama Hirofumi MZ if (!*ppList) 1445d5cc578SKatayama Hirofumi MZ { 1455d5cc578SKatayama Hirofumi MZ *ppList = pHotKey; 1465d5cc578SKatayama Hirofumi MZ return; 1475d5cc578SKatayama Hirofumi MZ } 1485d5cc578SKatayama Hirofumi MZ 1495d5cc578SKatayama Hirofumi MZ for (pNode = *ppList; pNode; pNode = pNode->pNext) 1505d5cc578SKatayama Hirofumi MZ { 1515d5cc578SKatayama Hirofumi MZ if (!pNode->pNext) 1525d5cc578SKatayama Hirofumi MZ { 1535d5cc578SKatayama Hirofumi MZ pNode->pNext = pHotKey; 1545d5cc578SKatayama Hirofumi MZ return; 1555d5cc578SKatayama Hirofumi MZ } 1565d5cc578SKatayama Hirofumi MZ } 1575d5cc578SKatayama Hirofumi MZ } 1585d5cc578SKatayama Hirofumi MZ 1595df5ef2bSKatayama Hirofumi MZ // Win: FindImeHotKeyByID 1605d5cc578SKatayama Hirofumi MZ static PIMEHOTKEY FASTCALL IntGetImeHotKeyById(PIMEHOTKEY pList, DWORD dwHotKeyId) 1615d5cc578SKatayama Hirofumi MZ { 1625d5cc578SKatayama Hirofumi MZ PIMEHOTKEY pNode; 1635d5cc578SKatayama Hirofumi MZ for (pNode = pList; pNode; pNode = pNode->pNext) 1645d5cc578SKatayama Hirofumi MZ { 1655d5cc578SKatayama Hirofumi MZ if (pNode->dwHotKeyId == dwHotKeyId) 1665d5cc578SKatayama Hirofumi MZ return pNode; 1675d5cc578SKatayama Hirofumi MZ } 1685d5cc578SKatayama Hirofumi MZ return NULL; 1695d5cc578SKatayama Hirofumi MZ } 1705d5cc578SKatayama Hirofumi MZ 1715df5ef2bSKatayama Hirofumi MZ // Win: FindImeHotKeyByKeyWithLang 1725d5cc578SKatayama Hirofumi MZ static PIMEHOTKEY APIENTRY 1735d5cc578SKatayama Hirofumi MZ IntGetImeHotKeyByKeyAndLang(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, 1745d5cc578SKatayama Hirofumi MZ UINT uVirtualKey, LANGID TargetLangId) 1755d5cc578SKatayama Hirofumi MZ { 1765d5cc578SKatayama Hirofumi MZ PIMEHOTKEY pNode; 1775d5cc578SKatayama Hirofumi MZ LANGID LangID; 1785d5cc578SKatayama Hirofumi MZ UINT uModifiers; 1795d5cc578SKatayama Hirofumi MZ 1805d5cc578SKatayama Hirofumi MZ for (pNode = pList; pNode; pNode = pNode->pNext) 1815d5cc578SKatayama Hirofumi MZ { 1825d5cc578SKatayama Hirofumi MZ if (pNode->uVirtualKey != uVirtualKey) 1835d5cc578SKatayama Hirofumi MZ continue; 1845d5cc578SKatayama Hirofumi MZ 1855d5cc578SKatayama Hirofumi MZ LangID = IntGetImeHotKeyLangId(pNode->dwHotKeyId); 18639fe905eSKatayama Hirofumi MZ if (LangID != TargetLangId && LangID != 0) 1875d5cc578SKatayama Hirofumi MZ continue; 1885d5cc578SKatayama Hirofumi MZ 1895d5cc578SKatayama Hirofumi MZ uModifiers = pNode->uModifiers; 1905d5cc578SKatayama Hirofumi MZ if (uModifiers & MOD_IGNORE_ALL_MODIFIER) 1915d5cc578SKatayama Hirofumi MZ return pNode; 1925d5cc578SKatayama Hirofumi MZ 1935d5cc578SKatayama Hirofumi MZ if ((uModifiers & MOD_KEYS) != uModKeys) 1945d5cc578SKatayama Hirofumi MZ continue; 1955d5cc578SKatayama Hirofumi MZ 1965d5cc578SKatayama Hirofumi MZ if ((uModifiers & uLeftRight) || (uModifiers & MOD_LEFT_RIGHT) == uLeftRight) 1975d5cc578SKatayama Hirofumi MZ return pNode; 1985d5cc578SKatayama Hirofumi MZ } 1995d5cc578SKatayama Hirofumi MZ 2005d5cc578SKatayama Hirofumi MZ return NULL; 2015d5cc578SKatayama Hirofumi MZ } 2025d5cc578SKatayama Hirofumi MZ 2035df5ef2bSKatayama Hirofumi MZ // Win: DeleteImeHotKey 2045d5cc578SKatayama Hirofumi MZ static VOID FASTCALL IntDeleteImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey) 2055d5cc578SKatayama Hirofumi MZ { 2065d5cc578SKatayama Hirofumi MZ PIMEHOTKEY pNode; 2075d5cc578SKatayama Hirofumi MZ 2085d5cc578SKatayama Hirofumi MZ if (*ppList == pHotKey) 2095d5cc578SKatayama Hirofumi MZ { 2105d5cc578SKatayama Hirofumi MZ *ppList = pHotKey->pNext; 2115d5cc578SKatayama Hirofumi MZ ExFreePoolWithTag(pHotKey, USERTAG_IMEHOTKEY); 2125d5cc578SKatayama Hirofumi MZ return; 2135d5cc578SKatayama Hirofumi MZ } 2145d5cc578SKatayama Hirofumi MZ 2155d5cc578SKatayama Hirofumi MZ for (pNode = *ppList; pNode; pNode = pNode->pNext) 2165d5cc578SKatayama Hirofumi MZ { 2175d5cc578SKatayama Hirofumi MZ if (pNode->pNext == pHotKey) 2185d5cc578SKatayama Hirofumi MZ { 2195d5cc578SKatayama Hirofumi MZ pNode->pNext = pHotKey->pNext; 2205d5cc578SKatayama Hirofumi MZ ExFreePoolWithTag(pHotKey, USERTAG_IMEHOTKEY); 2215d5cc578SKatayama Hirofumi MZ return; 2225d5cc578SKatayama Hirofumi MZ } 2235d5cc578SKatayama Hirofumi MZ } 2245d5cc578SKatayama Hirofumi MZ } 2255d5cc578SKatayama Hirofumi MZ 2265df5ef2bSKatayama Hirofumi MZ // Win: FindImeHotKeyByKey 227bbe5fd52SKatayama Hirofumi MZ PIMEHOTKEY 228bbe5fd52SKatayama Hirofumi MZ IntGetImeHotKeyByKey(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, UINT uVirtualKey) 229bbe5fd52SKatayama Hirofumi MZ { 230bbe5fd52SKatayama Hirofumi MZ PIMEHOTKEY pNode, ret = NULL; 231bbe5fd52SKatayama Hirofumi MZ PTHREADINFO pti = GetW32ThreadInfo(); 232bbe5fd52SKatayama Hirofumi MZ LANGID LangId; 233bbe5fd52SKatayama Hirofumi MZ HKL hKL = IntGetActiveKeyboardLayout(); 234bbe5fd52SKatayama Hirofumi MZ BOOL fKorean = (PRIMARYLANGID(LOWORD(hKL)) == LANG_KOREAN); 235bbe5fd52SKatayama Hirofumi MZ UINT nScore, nMaxScore = 0; 236bbe5fd52SKatayama Hirofumi MZ 237bbe5fd52SKatayama Hirofumi MZ for (pNode = pList; pNode; pNode = pNode->pNext) 238bbe5fd52SKatayama Hirofumi MZ { 239bbe5fd52SKatayama Hirofumi MZ if (pNode->uVirtualKey != uVirtualKey) 240bbe5fd52SKatayama Hirofumi MZ continue; 241bbe5fd52SKatayama Hirofumi MZ 242bbe5fd52SKatayama Hirofumi MZ if ((pNode->uModifiers & MOD_IGNORE_ALL_MODIFIER)) 243bbe5fd52SKatayama Hirofumi MZ { 244bbe5fd52SKatayama Hirofumi MZ ; 245bbe5fd52SKatayama Hirofumi MZ } 246bbe5fd52SKatayama Hirofumi MZ else if ((pNode->uModifiers & MOD_KEYS) != uModKeys) 247bbe5fd52SKatayama Hirofumi MZ { 248bbe5fd52SKatayama Hirofumi MZ continue; 249bbe5fd52SKatayama Hirofumi MZ } 250bbe5fd52SKatayama Hirofumi MZ else if ((pNode->uModifiers & uLeftRight) || 251bbe5fd52SKatayama Hirofumi MZ (pNode->uModifiers & MOD_LEFT_RIGHT) == uLeftRight) 252bbe5fd52SKatayama Hirofumi MZ { 253bbe5fd52SKatayama Hirofumi MZ ; 254bbe5fd52SKatayama Hirofumi MZ } 255bbe5fd52SKatayama Hirofumi MZ else 256bbe5fd52SKatayama Hirofumi MZ { 257bbe5fd52SKatayama Hirofumi MZ continue; 258bbe5fd52SKatayama Hirofumi MZ } 259bbe5fd52SKatayama Hirofumi MZ 260bbe5fd52SKatayama Hirofumi MZ LangId = IntGetImeHotKeyLangId(pNode->dwHotKeyId); 261bbe5fd52SKatayama Hirofumi MZ nScore = IntGetImeHotKeyLanguageScore(hKL, LangId); 262bbe5fd52SKatayama Hirofumi MZ if (nScore >= 3) 263bbe5fd52SKatayama Hirofumi MZ return pNode; 264bbe5fd52SKatayama Hirofumi MZ 265bbe5fd52SKatayama Hirofumi MZ if (fKorean) 266bbe5fd52SKatayama Hirofumi MZ continue; 267bbe5fd52SKatayama Hirofumi MZ 268bbe5fd52SKatayama Hirofumi MZ if (nScore == 0) 269bbe5fd52SKatayama Hirofumi MZ { 270bbe5fd52SKatayama Hirofumi MZ if (pNode->dwHotKeyId == IME_CHOTKEY_IME_NONIME_TOGGLE || 271bbe5fd52SKatayama Hirofumi MZ pNode->dwHotKeyId == IME_THOTKEY_IME_NONIME_TOGGLE) 272bbe5fd52SKatayama Hirofumi MZ { 273bbe5fd52SKatayama Hirofumi MZ if (LOWORD(pti->hklPrev) == LangId) 274bbe5fd52SKatayama Hirofumi MZ return pNode; 275bbe5fd52SKatayama Hirofumi MZ } 276bbe5fd52SKatayama Hirofumi MZ } 277bbe5fd52SKatayama Hirofumi MZ 278bbe5fd52SKatayama Hirofumi MZ if (nMaxScore < nScore) 279bbe5fd52SKatayama Hirofumi MZ { 280bbe5fd52SKatayama Hirofumi MZ nMaxScore = nScore; 281bbe5fd52SKatayama Hirofumi MZ ret = pNode; 282bbe5fd52SKatayama Hirofumi MZ } 283bbe5fd52SKatayama Hirofumi MZ } 284bbe5fd52SKatayama Hirofumi MZ 285bbe5fd52SKatayama Hirofumi MZ return ret; 286bbe5fd52SKatayama Hirofumi MZ } 287bbe5fd52SKatayama Hirofumi MZ 2882f7775c6SKatayama Hirofumi MZ // Win: CheckImeHotKey 289bbe5fd52SKatayama Hirofumi MZ PIMEHOTKEY IntCheckImeHotKey(PUSER_MESSAGE_QUEUE MessageQueue, UINT uVirtualKey, LPARAM lParam) 290bbe5fd52SKatayama Hirofumi MZ { 291bbe5fd52SKatayama Hirofumi MZ PIMEHOTKEY pHotKey; 292bbe5fd52SKatayama Hirofumi MZ UINT uModifiers; 293bbe5fd52SKatayama Hirofumi MZ BOOL bKeyUp = (lParam & 0x80000000); 294bbe5fd52SKatayama Hirofumi MZ const BYTE *KeyState = MessageQueue->afKeyState; 295bbe5fd52SKatayama Hirofumi MZ static UINT s_uKeyUpVKey = 0; 296bbe5fd52SKatayama Hirofumi MZ 297bbe5fd52SKatayama Hirofumi MZ if (bKeyUp) 298bbe5fd52SKatayama Hirofumi MZ { 299bbe5fd52SKatayama Hirofumi MZ if (s_uKeyUpVKey != uVirtualKey) 300bbe5fd52SKatayama Hirofumi MZ { 301bbe5fd52SKatayama Hirofumi MZ s_uKeyUpVKey = 0; 302bbe5fd52SKatayama Hirofumi MZ return NULL; 303bbe5fd52SKatayama Hirofumi MZ } 304bbe5fd52SKatayama Hirofumi MZ 305bbe5fd52SKatayama Hirofumi MZ s_uKeyUpVKey = 0; 306bbe5fd52SKatayama Hirofumi MZ } 307bbe5fd52SKatayama Hirofumi MZ 308bbe5fd52SKatayama Hirofumi MZ uModifiers = 0; 309bbe5fd52SKatayama Hirofumi MZ if (IS_KEY_DOWN(KeyState, VK_LSHIFT)) uModifiers |= (MOD_SHIFT | MOD_LEFT); 310bbe5fd52SKatayama Hirofumi MZ if (IS_KEY_DOWN(KeyState, VK_RSHIFT)) uModifiers |= (MOD_SHIFT | MOD_RIGHT); 311bbe5fd52SKatayama Hirofumi MZ if (IS_KEY_DOWN(KeyState, VK_LCONTROL)) uModifiers |= (MOD_CONTROL | MOD_LEFT); 312bbe5fd52SKatayama Hirofumi MZ if (IS_KEY_DOWN(KeyState, VK_RCONTROL)) uModifiers |= (MOD_CONTROL | MOD_RIGHT); 313bbe5fd52SKatayama Hirofumi MZ if (IS_KEY_DOWN(KeyState, VK_LMENU)) uModifiers |= (MOD_ALT | MOD_LEFT); 314bbe5fd52SKatayama Hirofumi MZ if (IS_KEY_DOWN(KeyState, VK_RMENU)) uModifiers |= (MOD_ALT | MOD_RIGHT); 315bbe5fd52SKatayama Hirofumi MZ 316bbe5fd52SKatayama Hirofumi MZ pHotKey = IntGetImeHotKeyByKey(gpImeHotKeyList, 317bbe5fd52SKatayama Hirofumi MZ (uModifiers & MOD_KEYS), 318bbe5fd52SKatayama Hirofumi MZ (uModifiers & MOD_LEFT_RIGHT), 319bbe5fd52SKatayama Hirofumi MZ uVirtualKey); 320bbe5fd52SKatayama Hirofumi MZ if (pHotKey) 321bbe5fd52SKatayama Hirofumi MZ { 322bbe5fd52SKatayama Hirofumi MZ if (bKeyUp) 323bbe5fd52SKatayama Hirofumi MZ { 324bbe5fd52SKatayama Hirofumi MZ if (pHotKey->uModifiers & MOD_ON_KEYUP) 325bbe5fd52SKatayama Hirofumi MZ return pHotKey; 326bbe5fd52SKatayama Hirofumi MZ } 327bbe5fd52SKatayama Hirofumi MZ else 328bbe5fd52SKatayama Hirofumi MZ { 329bbe5fd52SKatayama Hirofumi MZ if (pHotKey->uModifiers & MOD_ON_KEYUP) 330bbe5fd52SKatayama Hirofumi MZ s_uKeyUpVKey = uVirtualKey; 331bbe5fd52SKatayama Hirofumi MZ else 332bbe5fd52SKatayama Hirofumi MZ return pHotKey; 333bbe5fd52SKatayama Hirofumi MZ } 334bbe5fd52SKatayama Hirofumi MZ } 335bbe5fd52SKatayama Hirofumi MZ 336bbe5fd52SKatayama Hirofumi MZ return NULL; 337bbe5fd52SKatayama Hirofumi MZ } 338bbe5fd52SKatayama Hirofumi MZ 3392f7775c6SKatayama Hirofumi MZ // Win: FreeImeHotKeys 3405d5cc578SKatayama Hirofumi MZ VOID FASTCALL IntFreeImeHotKeys(VOID) 3415d5cc578SKatayama Hirofumi MZ { 3425d5cc578SKatayama Hirofumi MZ PIMEHOTKEY pNode, pNext; 3435d5cc578SKatayama Hirofumi MZ for (pNode = gpImeHotKeyList; pNode; pNode = pNext) 3445d5cc578SKatayama Hirofumi MZ { 3455d5cc578SKatayama Hirofumi MZ pNext = pNode->pNext; 3465d5cc578SKatayama Hirofumi MZ ExFreePoolWithTag(pNode, USERTAG_IMEHOTKEY); 3475d5cc578SKatayama Hirofumi MZ } 3485d5cc578SKatayama Hirofumi MZ gpImeHotKeyList = NULL; 3495d5cc578SKatayama Hirofumi MZ } 3505d5cc578SKatayama Hirofumi MZ 3512f7775c6SKatayama Hirofumi MZ // Win: SetImeHotKey 3525d5cc578SKatayama Hirofumi MZ static BOOL APIENTRY 3535d5cc578SKatayama Hirofumi MZ IntSetImeHotKey(DWORD dwHotKeyId, UINT uModifiers, UINT uVirtualKey, HKL hKL, DWORD dwAction) 3545d5cc578SKatayama Hirofumi MZ { 3555d5cc578SKatayama Hirofumi MZ PIMEHOTKEY pNode; 3565d5cc578SKatayama Hirofumi MZ LANGID LangId; 3575d5cc578SKatayama Hirofumi MZ 3585d5cc578SKatayama Hirofumi MZ switch (dwAction) 3595d5cc578SKatayama Hirofumi MZ { 3605d5cc578SKatayama Hirofumi MZ case SETIMEHOTKEY_DELETE: 36139fe905eSKatayama Hirofumi MZ pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId); /* Find hotkey by ID */ 3625d5cc578SKatayama Hirofumi MZ if (!pNode) 363b5c9d532SKatayama Hirofumi MZ { 364b5c9d532SKatayama Hirofumi MZ ERR("dwHotKeyId: 0x%lX\n", dwHotKeyId); 3655d5cc578SKatayama Hirofumi MZ return FALSE; 366b5c9d532SKatayama Hirofumi MZ } 3675d5cc578SKatayama Hirofumi MZ 36839fe905eSKatayama Hirofumi MZ IntDeleteImeHotKey(&gpImeHotKeyList, pNode); /* Delete it */ 3695d5cc578SKatayama Hirofumi MZ return TRUE; 3705d5cc578SKatayama Hirofumi MZ 3715d5cc578SKatayama Hirofumi MZ case SETIMEHOTKEY_ADD: 37239fe905eSKatayama Hirofumi MZ if (LOWORD(uVirtualKey) == VK_PACKET) /* In case of VK_PACKET */ 3735d5cc578SKatayama Hirofumi MZ return FALSE; 3745d5cc578SKatayama Hirofumi MZ 3755d5cc578SKatayama Hirofumi MZ LangId = IntGetImeHotKeyLangId(dwHotKeyId); 3765d5cc578SKatayama Hirofumi MZ if (LangId == LANGID_KOREAN) 37739fe905eSKatayama Hirofumi MZ return FALSE; /* Korean can't add IME hotkeys */ 3785d5cc578SKatayama Hirofumi MZ 37939fe905eSKatayama Hirofumi MZ /* Find hotkey by key and language */ 3805d5cc578SKatayama Hirofumi MZ pNode = IntGetImeHotKeyByKeyAndLang(gpImeHotKeyList, 3815d5cc578SKatayama Hirofumi MZ (uModifiers & MOD_KEYS), 3825d5cc578SKatayama Hirofumi MZ (uModifiers & MOD_LEFT_RIGHT), 3835d5cc578SKatayama Hirofumi MZ uVirtualKey, LangId); 38439fe905eSKatayama Hirofumi MZ if (pNode == NULL) /* If not found */ 38539fe905eSKatayama Hirofumi MZ pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId); /* Find by ID */ 3865d5cc578SKatayama Hirofumi MZ 38739fe905eSKatayama Hirofumi MZ if (pNode) /* Already exists */ 3885d5cc578SKatayama Hirofumi MZ { 3895d5cc578SKatayama Hirofumi MZ pNode->uModifiers = uModifiers; 3905d5cc578SKatayama Hirofumi MZ pNode->uVirtualKey = uVirtualKey; 3915d5cc578SKatayama Hirofumi MZ pNode->hKL = hKL; 3925d5cc578SKatayama Hirofumi MZ return TRUE; 3935d5cc578SKatayama Hirofumi MZ } 3945d5cc578SKatayama Hirofumi MZ 39539fe905eSKatayama Hirofumi MZ /* Allocate new hotkey */ 3965d5cc578SKatayama Hirofumi MZ pNode = ExAllocatePoolWithTag(PagedPool, sizeof(IMEHOTKEY), USERTAG_IMEHOTKEY); 3975d5cc578SKatayama Hirofumi MZ if (!pNode) 3985d5cc578SKatayama Hirofumi MZ return FALSE; 3995d5cc578SKatayama Hirofumi MZ 40039fe905eSKatayama Hirofumi MZ /* Populate */ 4015d5cc578SKatayama Hirofumi MZ pNode->pNext = NULL; 4025d5cc578SKatayama Hirofumi MZ pNode->dwHotKeyId = dwHotKeyId; 4035d5cc578SKatayama Hirofumi MZ pNode->uModifiers = uModifiers; 4045d5cc578SKatayama Hirofumi MZ pNode->uVirtualKey = uVirtualKey; 4055d5cc578SKatayama Hirofumi MZ pNode->hKL = hKL; 40639fe905eSKatayama Hirofumi MZ IntAddImeHotKey(&gpImeHotKeyList, pNode); /* Add it */ 4075d5cc578SKatayama Hirofumi MZ return TRUE; 4085d5cc578SKatayama Hirofumi MZ 409dff4579bSKatayama Hirofumi MZ case SETIMEHOTKEY_INITIALIZE: 41039fe905eSKatayama Hirofumi MZ IntFreeImeHotKeys(); /* Delete all the IME hotkeys */ 4115d5cc578SKatayama Hirofumi MZ return TRUE; 4125d5cc578SKatayama Hirofumi MZ 4135d5cc578SKatayama Hirofumi MZ default: 41439fe905eSKatayama Hirofumi MZ ERR("0x%lX\n", dwAction); 4155d5cc578SKatayama Hirofumi MZ return FALSE; 4165d5cc578SKatayama Hirofumi MZ } 4175d5cc578SKatayama Hirofumi MZ } 4185d5cc578SKatayama Hirofumi MZ 4195d5cc578SKatayama Hirofumi MZ BOOL NTAPI 4205d5cc578SKatayama Hirofumi MZ NtUserGetImeHotKey(DWORD dwHotKeyId, LPUINT lpuModifiers, LPUINT lpuVirtualKey, LPHKL lphKL) 4215d5cc578SKatayama Hirofumi MZ { 4225d5cc578SKatayama Hirofumi MZ PIMEHOTKEY pNode = NULL; 4235d5cc578SKatayama Hirofumi MZ 4245d5cc578SKatayama Hirofumi MZ UserEnterExclusive(); 4255d5cc578SKatayama Hirofumi MZ 4265d5cc578SKatayama Hirofumi MZ _SEH2_TRY 4275d5cc578SKatayama Hirofumi MZ { 4285d5cc578SKatayama Hirofumi MZ ProbeForWrite(lpuModifiers, sizeof(UINT), 1); 4295d5cc578SKatayama Hirofumi MZ ProbeForWrite(lpuVirtualKey, sizeof(UINT), 1); 4305d5cc578SKatayama Hirofumi MZ if (lphKL) 4315d5cc578SKatayama Hirofumi MZ ProbeForWrite(lphKL, sizeof(HKL), 1); 4325d5cc578SKatayama Hirofumi MZ } 4335d5cc578SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 4345d5cc578SKatayama Hirofumi MZ { 4355d5cc578SKatayama Hirofumi MZ goto Quit; 4365d5cc578SKatayama Hirofumi MZ } 4375d5cc578SKatayama Hirofumi MZ _SEH2_END; 4385d5cc578SKatayama Hirofumi MZ 4395d5cc578SKatayama Hirofumi MZ pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId); 4405d5cc578SKatayama Hirofumi MZ if (!pNode) 4415d5cc578SKatayama Hirofumi MZ goto Quit; 4425d5cc578SKatayama Hirofumi MZ 4435d5cc578SKatayama Hirofumi MZ _SEH2_TRY 4445d5cc578SKatayama Hirofumi MZ { 4455d5cc578SKatayama Hirofumi MZ *lpuModifiers = pNode->uModifiers; 4465d5cc578SKatayama Hirofumi MZ *lpuVirtualKey = pNode->uVirtualKey; 4475d5cc578SKatayama Hirofumi MZ if (lphKL) 4485d5cc578SKatayama Hirofumi MZ *lphKL = pNode->hKL; 4495d5cc578SKatayama Hirofumi MZ } 4505d5cc578SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 4515d5cc578SKatayama Hirofumi MZ { 4525d5cc578SKatayama Hirofumi MZ pNode = NULL; 4535d5cc578SKatayama Hirofumi MZ } 4545d5cc578SKatayama Hirofumi MZ _SEH2_END; 4555d5cc578SKatayama Hirofumi MZ 4565d5cc578SKatayama Hirofumi MZ Quit: 4575d5cc578SKatayama Hirofumi MZ UserLeave(); 4585d5cc578SKatayama Hirofumi MZ return !!pNode; 4595d5cc578SKatayama Hirofumi MZ } 4605d5cc578SKatayama Hirofumi MZ 4615d5cc578SKatayama Hirofumi MZ BOOL 4625d5cc578SKatayama Hirofumi MZ NTAPI 4635d5cc578SKatayama Hirofumi MZ NtUserSetImeHotKey( 4645d5cc578SKatayama Hirofumi MZ DWORD dwHotKeyId, 4655d5cc578SKatayama Hirofumi MZ UINT uModifiers, 4665d5cc578SKatayama Hirofumi MZ UINT uVirtualKey, 4675d5cc578SKatayama Hirofumi MZ HKL hKL, 4685d5cc578SKatayama Hirofumi MZ DWORD dwAction) 4695d5cc578SKatayama Hirofumi MZ { 4705d5cc578SKatayama Hirofumi MZ BOOL ret; 4715d5cc578SKatayama Hirofumi MZ UserEnterExclusive(); 4725d5cc578SKatayama Hirofumi MZ ret = IntSetImeHotKey(dwHotKeyId, uModifiers, uVirtualKey, hKL, dwAction); 4735d5cc578SKatayama Hirofumi MZ UserLeave(); 4745d5cc578SKatayama Hirofumi MZ return ret; 4755d5cc578SKatayama Hirofumi MZ } 4765d5cc578SKatayama Hirofumi MZ 477bbe5fd52SKatayama Hirofumi MZ DWORD 478bbe5fd52SKatayama Hirofumi MZ NTAPI 479bbe5fd52SKatayama Hirofumi MZ NtUserCheckImeHotKey(UINT uVirtualKey, LPARAM lParam) 480bbe5fd52SKatayama Hirofumi MZ { 481bbe5fd52SKatayama Hirofumi MZ PIMEHOTKEY pNode; 482bbe5fd52SKatayama Hirofumi MZ DWORD ret = INVALID_HOTKEY; 483bbe5fd52SKatayama Hirofumi MZ 484bbe5fd52SKatayama Hirofumi MZ UserEnterExclusive(); 485bbe5fd52SKatayama Hirofumi MZ 486bbe5fd52SKatayama Hirofumi MZ if (!gpqForeground || !IS_IMM_MODE()) 487bbe5fd52SKatayama Hirofumi MZ goto Quit; 488bbe5fd52SKatayama Hirofumi MZ 489bbe5fd52SKatayama Hirofumi MZ pNode = IntCheckImeHotKey(gpqForeground, uVirtualKey, lParam); 490bbe5fd52SKatayama Hirofumi MZ if (pNode) 491bbe5fd52SKatayama Hirofumi MZ ret = pNode->dwHotKeyId; 492bbe5fd52SKatayama Hirofumi MZ 493bbe5fd52SKatayama Hirofumi MZ Quit: 494bbe5fd52SKatayama Hirofumi MZ UserLeave(); 495bbe5fd52SKatayama Hirofumi MZ return ret; 496bbe5fd52SKatayama Hirofumi MZ } 497bbe5fd52SKatayama Hirofumi MZ 4985df5ef2bSKatayama Hirofumi MZ // Win: GetTopLevelWindow 4990519ae0aSKatayama Hirofumi MZ PWND FASTCALL IntGetTopLevelWindow(PWND pwnd) 5000519ae0aSKatayama Hirofumi MZ { 5010519ae0aSKatayama Hirofumi MZ if (!pwnd) 5020519ae0aSKatayama Hirofumi MZ return NULL; 5030519ae0aSKatayama Hirofumi MZ 5040519ae0aSKatayama Hirofumi MZ while (pwnd->style & WS_CHILD) 5050519ae0aSKatayama Hirofumi MZ pwnd = pwnd->spwndParent; 5060519ae0aSKatayama Hirofumi MZ 5070519ae0aSKatayama Hirofumi MZ return pwnd; 5080519ae0aSKatayama Hirofumi MZ } 5090519ae0aSKatayama Hirofumi MZ 5102f7775c6SKatayama Hirofumi MZ // Win: AssociateInputContext 5111bc9dda5SKatayama Hirofumi MZ HIMC FASTCALL IntAssociateInputContext(PWND pWnd, PIMC pImc) 5121bc9dda5SKatayama Hirofumi MZ { 5131bc9dda5SKatayama Hirofumi MZ HIMC hOldImc = pWnd->hImc; 5141bc9dda5SKatayama Hirofumi MZ pWnd->hImc = (pImc ? UserHMGetHandle(pImc) : NULL); 5151bc9dda5SKatayama Hirofumi MZ return hOldImc; 5161bc9dda5SKatayama Hirofumi MZ } 5171bc9dda5SKatayama Hirofumi MZ 518470aa276SKatayama Hirofumi MZ DWORD 519e52ce89bSKatayama Hirofumi MZ NTAPI 520470aa276SKatayama Hirofumi MZ NtUserSetThreadLayoutHandles(HKL hNewKL, HKL hOldKL) 521470aa276SKatayama Hirofumi MZ { 522470aa276SKatayama Hirofumi MZ PTHREADINFO pti; 523470aa276SKatayama Hirofumi MZ PKL pOldKL, pNewKL; 524470aa276SKatayama Hirofumi MZ 525470aa276SKatayama Hirofumi MZ UserEnterExclusive(); 526470aa276SKatayama Hirofumi MZ 527470aa276SKatayama Hirofumi MZ pti = GetW32ThreadInfo(); 528470aa276SKatayama Hirofumi MZ pOldKL = pti->KeyboardLayout; 529470aa276SKatayama Hirofumi MZ if (pOldKL && pOldKL->hkl != hOldKL) 530470aa276SKatayama Hirofumi MZ goto Quit; 531470aa276SKatayama Hirofumi MZ 532470aa276SKatayama Hirofumi MZ pNewKL = UserHklToKbl(hNewKL); 533470aa276SKatayama Hirofumi MZ if (!pNewKL) 534470aa276SKatayama Hirofumi MZ goto Quit; 535470aa276SKatayama Hirofumi MZ 536470aa276SKatayama Hirofumi MZ if (IS_IME_HKL(hNewKL) != IS_IME_HKL(hOldKL)) 537470aa276SKatayama Hirofumi MZ pti->hklPrev = hOldKL; 538470aa276SKatayama Hirofumi MZ 5395df5ef2bSKatayama Hirofumi MZ UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pNewKL); 540f34b8460SKatayama Hirofumi MZ pti->pClientInfo->hKL = pNewKL->hkl; 541470aa276SKatayama Hirofumi MZ 542470aa276SKatayama Hirofumi MZ Quit: 543470aa276SKatayama Hirofumi MZ UserLeave(); 544470aa276SKatayama Hirofumi MZ return 0; 545470aa276SKatayama Hirofumi MZ } 546470aa276SKatayama Hirofumi MZ 5472f7775c6SKatayama Hirofumi MZ // Win: BuildHimcList 548ce6da820SKatayama Hirofumi MZ DWORD FASTCALL UserBuildHimcList(PTHREADINFO pti, DWORD dwCount, HIMC *phList) 549ce6da820SKatayama Hirofumi MZ { 550ce6da820SKatayama Hirofumi MZ PIMC pIMC; 551ce6da820SKatayama Hirofumi MZ DWORD dwRealCount = 0; 552ce6da820SKatayama Hirofumi MZ 553ce6da820SKatayama Hirofumi MZ if (pti) 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 else 564ce6da820SKatayama Hirofumi MZ { 565a2c6af0dSKatayama Hirofumi MZ for (pti = gptiCurrent->ppi->ptiList; pti; pti = pti->ptiSibling) 566ce6da820SKatayama Hirofumi MZ { 567ce6da820SKatayama Hirofumi MZ for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext) 568ce6da820SKatayama Hirofumi MZ { 569ce6da820SKatayama Hirofumi MZ if (dwRealCount < dwCount) 570ce6da820SKatayama Hirofumi MZ phList[dwRealCount] = UserHMGetHandle(pIMC); 571ce6da820SKatayama Hirofumi MZ 572ce6da820SKatayama Hirofumi MZ ++dwRealCount; 573ce6da820SKatayama Hirofumi MZ } 574ce6da820SKatayama Hirofumi MZ } 575ce6da820SKatayama Hirofumi MZ } 576ce6da820SKatayama Hirofumi MZ 577ce6da820SKatayama Hirofumi MZ return dwRealCount; 578ce6da820SKatayama Hirofumi MZ } 579ce6da820SKatayama Hirofumi MZ 5805df5ef2bSKatayama Hirofumi MZ // Win: xxxImmProcessKey 581c2c66affSColin Finck UINT FASTCALL 582b5c9d532SKatayama Hirofumi MZ IntImmProcessKey(PUSER_MESSAGE_QUEUE MessageQueue, PWND pWnd, UINT uMsg, 583b5c9d532SKatayama Hirofumi MZ WPARAM wParam, LPARAM lParam) 584c2c66affSColin Finck { 585b5c9d532SKatayama Hirofumi MZ UINT uVirtualKey, ret = 0; 586b5c9d532SKatayama Hirofumi MZ DWORD dwHotKeyId; 587b5c9d532SKatayama Hirofumi MZ PKL pKL; 588b5c9d532SKatayama Hirofumi MZ PIMC pIMC = NULL; 589b5c9d532SKatayama Hirofumi MZ PIMEHOTKEY pImeHotKey; 590b5c9d532SKatayama Hirofumi MZ HKL hKL; 591b5c9d532SKatayama Hirofumi MZ HWND hWnd; 592c2c66affSColin Finck 593c2c66affSColin Finck ASSERT_REFS_CO(pWnd); 594c2c66affSColin Finck 595b5c9d532SKatayama Hirofumi MZ switch (uMsg) 596c2c66affSColin Finck { 597b5c9d532SKatayama Hirofumi MZ case WM_KEYDOWN: 598b5c9d532SKatayama Hirofumi MZ case WM_KEYUP: 599b5c9d532SKatayama Hirofumi MZ case WM_SYSKEYDOWN: 600b5c9d532SKatayama Hirofumi MZ case WM_SYSKEYUP: 601b5c9d532SKatayama Hirofumi MZ break; 602b5c9d532SKatayama Hirofumi MZ 603b5c9d532SKatayama Hirofumi MZ default: 604c2c66affSColin Finck return 0; 605c2c66affSColin Finck } 606c2c66affSColin Finck 607b5c9d532SKatayama Hirofumi MZ hWnd = UserHMGetHandle(pWnd); 608b5c9d532SKatayama Hirofumi MZ pKL = pWnd->head.pti->KeyboardLayout; 609b5c9d532SKatayama Hirofumi MZ if (!pKL) 610b5c9d532SKatayama Hirofumi MZ return 0; 611b5c9d532SKatayama Hirofumi MZ 612b5c9d532SKatayama Hirofumi MZ uVirtualKey = LOBYTE(wParam); 613b5c9d532SKatayama Hirofumi MZ pImeHotKey = IntCheckImeHotKey(MessageQueue, uVirtualKey, lParam); 614b5c9d532SKatayama Hirofumi MZ if (pImeHotKey) 615b5c9d532SKatayama Hirofumi MZ { 616b5c9d532SKatayama Hirofumi MZ dwHotKeyId = pImeHotKey->dwHotKeyId; 617b5c9d532SKatayama Hirofumi MZ hKL = pImeHotKey->hKL; 618b5c9d532SKatayama Hirofumi MZ } 619b5c9d532SKatayama Hirofumi MZ else 620b5c9d532SKatayama Hirofumi MZ { 621b5c9d532SKatayama Hirofumi MZ dwHotKeyId = INVALID_HOTKEY; 622b5c9d532SKatayama Hirofumi MZ hKL = NULL; 623b5c9d532SKatayama Hirofumi MZ } 624b5c9d532SKatayama Hirofumi MZ 625b5c9d532SKatayama Hirofumi MZ if (IME_HOTKEY_DSWITCH_FIRST <= dwHotKeyId && dwHotKeyId <= IME_HOTKEY_DSWITCH_LAST) 626b5c9d532SKatayama Hirofumi MZ { 627b5c9d532SKatayama Hirofumi MZ if (pKL->hkl != hKL) 628b5c9d532SKatayama Hirofumi MZ { 629b5c9d532SKatayama Hirofumi MZ UserPostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 630b5c9d532SKatayama Hirofumi MZ ((pKL->dwFontSigs & gSystemFS) ? INPUTLANGCHANGE_SYSCHARSET : 0), 631b5c9d532SKatayama Hirofumi MZ (LPARAM)hKL); 632b5c9d532SKatayama Hirofumi MZ } 633b5c9d532SKatayama Hirofumi MZ 634b5c9d532SKatayama Hirofumi MZ if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000) 635b5c9d532SKatayama Hirofumi MZ return 0; 636b5c9d532SKatayama Hirofumi MZ 637b5c9d532SKatayama Hirofumi MZ return IPHK_HOTKEY; 638b5c9d532SKatayama Hirofumi MZ } 639b5c9d532SKatayama Hirofumi MZ 640b5c9d532SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 641b5c9d532SKatayama Hirofumi MZ return 0; 642b5c9d532SKatayama Hirofumi MZ 643b5c9d532SKatayama Hirofumi MZ if (dwHotKeyId == INVALID_HOTKEY) 644b5c9d532SKatayama Hirofumi MZ { 645b5c9d532SKatayama Hirofumi MZ if (!pKL->piiex) 646b5c9d532SKatayama Hirofumi MZ return 0; 647b5c9d532SKatayama Hirofumi MZ 648b5c9d532SKatayama Hirofumi MZ if (pWnd->hImc) 649b5c9d532SKatayama Hirofumi MZ pIMC = UserGetObject(gHandleTable, pWnd->hImc, TYPE_INPUTCONTEXT); 650b5c9d532SKatayama Hirofumi MZ if (!pIMC) 651b5c9d532SKatayama Hirofumi MZ return 0; 652b5c9d532SKatayama Hirofumi MZ 653b5c9d532SKatayama Hirofumi MZ if ((lParam & 0x80000000) && 654b5c9d532SKatayama Hirofumi MZ (pKL->piiex->ImeInfo.fdwProperty & IME_PROP_IGNORE_UPKEYS)) 655b5c9d532SKatayama Hirofumi MZ { 656b5c9d532SKatayama Hirofumi MZ return 0; 657b5c9d532SKatayama Hirofumi MZ } 658b5c9d532SKatayama Hirofumi MZ 659b5c9d532SKatayama Hirofumi MZ switch (uVirtualKey) 660b5c9d532SKatayama Hirofumi MZ { 661b5c9d532SKatayama Hirofumi MZ case VK_DBE_CODEINPUT: 662b5c9d532SKatayama Hirofumi MZ case VK_DBE_ENTERCONFIGMODE: 663b5c9d532SKatayama Hirofumi MZ case VK_DBE_ENTERWORDREGISTERMODE: 664b5c9d532SKatayama Hirofumi MZ case VK_DBE_HIRAGANA: 665b5c9d532SKatayama Hirofumi MZ case VK_DBE_KATAKANA: 666b5c9d532SKatayama Hirofumi MZ case VK_DBE_NOCODEINPUT: 667b5c9d532SKatayama Hirofumi MZ case VK_DBE_NOROMAN: 668b5c9d532SKatayama Hirofumi MZ case VK_DBE_ROMAN: 669b5c9d532SKatayama Hirofumi MZ break; 670b5c9d532SKatayama Hirofumi MZ 671b5c9d532SKatayama Hirofumi MZ default: 672b5c9d532SKatayama Hirofumi MZ { 673b5c9d532SKatayama Hirofumi MZ if (uMsg == WM_SYSKEYDOWN || uMsg == WM_SYSKEYUP) 674b5c9d532SKatayama Hirofumi MZ { 675b5c9d532SKatayama Hirofumi MZ if (uVirtualKey != VK_MENU && uVirtualKey != VK_F10) 676b5c9d532SKatayama Hirofumi MZ return 0; 677b5c9d532SKatayama Hirofumi MZ } 678b5c9d532SKatayama Hirofumi MZ 679b5c9d532SKatayama Hirofumi MZ if (!(pKL->piiex->ImeInfo.fdwProperty & IME_PROP_NEED_ALTKEY)) 680b5c9d532SKatayama Hirofumi MZ { 681b5c9d532SKatayama Hirofumi MZ if (uVirtualKey == VK_MENU || (lParam & 0x20000000)) 682b5c9d532SKatayama Hirofumi MZ return 0; 683b5c9d532SKatayama Hirofumi MZ } 684b5c9d532SKatayama Hirofumi MZ break; 685b5c9d532SKatayama Hirofumi MZ } 686b5c9d532SKatayama Hirofumi MZ } 687b5c9d532SKatayama Hirofumi MZ } 688b5c9d532SKatayama Hirofumi MZ 689b5c9d532SKatayama Hirofumi MZ if (LOBYTE(uVirtualKey) == VK_PACKET) 690b5c9d532SKatayama Hirofumi MZ uVirtualKey = MAKELONG(wParam, GetW32ThreadInfo()->wchInjected); 691b5c9d532SKatayama Hirofumi MZ 692b5c9d532SKatayama Hirofumi MZ ret = co_IntImmProcessKey(hWnd, pKL->hkl, uVirtualKey, lParam, dwHotKeyId); 693b5c9d532SKatayama Hirofumi MZ 694b5c9d532SKatayama Hirofumi MZ if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000) 695b5c9d532SKatayama Hirofumi MZ ret &= ~IPHK_HOTKEY; 696b5c9d532SKatayama Hirofumi MZ 697b5c9d532SKatayama Hirofumi MZ return ret; 698b5c9d532SKatayama Hirofumi MZ } 699b5c9d532SKatayama Hirofumi MZ 700ce6da820SKatayama Hirofumi MZ NTSTATUS 701e52ce89bSKatayama Hirofumi MZ NTAPI 702ce6da820SKatayama Hirofumi MZ NtUserBuildHimcList(DWORD dwThreadId, DWORD dwCount, HIMC *phList, LPDWORD pdwCount) 703ce6da820SKatayama Hirofumi MZ { 704ce6da820SKatayama Hirofumi MZ NTSTATUS ret = STATUS_UNSUCCESSFUL; 705ce6da820SKatayama Hirofumi MZ DWORD dwRealCount; 706ce6da820SKatayama Hirofumi MZ PTHREADINFO pti; 707ce6da820SKatayama Hirofumi MZ 708ce6da820SKatayama Hirofumi MZ UserEnterExclusive(); 709ce6da820SKatayama Hirofumi MZ 710ce6da820SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 711ce6da820SKatayama Hirofumi MZ { 712b5c9d532SKatayama Hirofumi MZ ERR("!IS_IMM_MODE()\n"); 713ce6da820SKatayama Hirofumi MZ EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); 714ce6da820SKatayama Hirofumi MZ goto Quit; 715ce6da820SKatayama Hirofumi MZ } 716ce6da820SKatayama Hirofumi MZ 717ce6da820SKatayama Hirofumi MZ if (dwThreadId == 0) 718ce6da820SKatayama Hirofumi MZ { 719a2c6af0dSKatayama Hirofumi MZ pti = gptiCurrent; 720ce6da820SKatayama Hirofumi MZ } 721ce6da820SKatayama Hirofumi MZ else if (dwThreadId == INVALID_THREAD_ID) 722ce6da820SKatayama Hirofumi MZ { 723ce6da820SKatayama Hirofumi MZ pti = NULL; 724ce6da820SKatayama Hirofumi MZ } 725ce6da820SKatayama Hirofumi MZ else 726ce6da820SKatayama Hirofumi MZ { 727ce6da820SKatayama Hirofumi MZ pti = IntTID2PTI(UlongToHandle(dwThreadId)); 728ce6da820SKatayama Hirofumi MZ if (!pti || !pti->rpdesk) 729ce6da820SKatayama Hirofumi MZ goto Quit; 730ce6da820SKatayama Hirofumi MZ } 731ce6da820SKatayama Hirofumi MZ 732ce6da820SKatayama Hirofumi MZ _SEH2_TRY 733ce6da820SKatayama Hirofumi MZ { 734ce6da820SKatayama Hirofumi MZ ProbeForWrite(phList, dwCount * sizeof(HIMC), 1); 735ce6da820SKatayama Hirofumi MZ ProbeForWrite(pdwCount, sizeof(DWORD), 1); 736ce6da820SKatayama Hirofumi MZ *pdwCount = dwRealCount = UserBuildHimcList(pti, dwCount, phList); 737ce6da820SKatayama Hirofumi MZ } 738ce6da820SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 739ce6da820SKatayama Hirofumi MZ { 740ce6da820SKatayama Hirofumi MZ goto Quit; 741ce6da820SKatayama Hirofumi MZ } 742ce6da820SKatayama Hirofumi MZ _SEH2_END; 743ce6da820SKatayama Hirofumi MZ 744ce6da820SKatayama Hirofumi MZ if (dwCount < dwRealCount) 745ce6da820SKatayama Hirofumi MZ ret = STATUS_BUFFER_TOO_SMALL; 746ce6da820SKatayama Hirofumi MZ else 747ce6da820SKatayama Hirofumi MZ ret = STATUS_SUCCESS; 748ce6da820SKatayama Hirofumi MZ 749ce6da820SKatayama Hirofumi MZ Quit: 750ce6da820SKatayama Hirofumi MZ UserLeave(); 751ce6da820SKatayama Hirofumi MZ return ret; 752ce6da820SKatayama Hirofumi MZ } 753ce6da820SKatayama Hirofumi MZ 7545df5ef2bSKatayama Hirofumi MZ // Win: SetConvMode 7559db44371SKatayama Hirofumi MZ static VOID FASTCALL UserSetImeConversionKeyState(PTHREADINFO pti, DWORD dwConversion) 7569db44371SKatayama Hirofumi MZ { 7579db44371SKatayama Hirofumi MZ HKL hKL; 7589db44371SKatayama Hirofumi MZ LANGID LangID; 7599db44371SKatayama Hirofumi MZ LPBYTE KeyState; 7609db44371SKatayama Hirofumi MZ BOOL bAlphaNumeric, bKatakana, bHiragana, bFullShape, bRoman, bCharCode; 7619db44371SKatayama Hirofumi MZ 7629db44371SKatayama Hirofumi MZ if (!pti->KeyboardLayout) 7639db44371SKatayama Hirofumi MZ return; 7649db44371SKatayama Hirofumi MZ 7659db44371SKatayama Hirofumi MZ hKL = pti->KeyboardLayout->hkl; 7669db44371SKatayama Hirofumi MZ LangID = LOWORD(hKL); 7679db44371SKatayama Hirofumi MZ KeyState = pti->MessageQueue->afKeyState; 7689db44371SKatayama Hirofumi MZ 7699db44371SKatayama Hirofumi MZ switch (PRIMARYLANGID(LangID)) 7709db44371SKatayama Hirofumi MZ { 7719db44371SKatayama Hirofumi MZ case LANG_JAPANESE: 7729db44371SKatayama Hirofumi MZ bAlphaNumeric = !(dwConversion & IME_CMODE_NATIVE); 7739db44371SKatayama Hirofumi MZ bKatakana = !bAlphaNumeric && (dwConversion & IME_CMODE_KATAKANA); 7749db44371SKatayama Hirofumi MZ bHiragana = !bAlphaNumeric && !(dwConversion & IME_CMODE_KATAKANA); 7759db44371SKatayama Hirofumi MZ SET_KEY_DOWN(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric); 7769db44371SKatayama Hirofumi MZ SET_KEY_LOCKED(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric); 7779db44371SKatayama Hirofumi MZ SET_KEY_DOWN(KeyState, VK_DBE_HIRAGANA, bHiragana); 7789db44371SKatayama Hirofumi MZ SET_KEY_LOCKED(KeyState, VK_DBE_HIRAGANA, bHiragana); 7799db44371SKatayama Hirofumi MZ SET_KEY_DOWN(KeyState, VK_DBE_KATAKANA, bKatakana); 7809db44371SKatayama Hirofumi MZ SET_KEY_LOCKED(KeyState, VK_DBE_KATAKANA, bKatakana); 7819db44371SKatayama Hirofumi MZ 7829db44371SKatayama Hirofumi MZ bFullShape = (dwConversion & IME_CMODE_FULLSHAPE); 7839db44371SKatayama Hirofumi MZ SET_KEY_DOWN(KeyState, VK_DBE_DBCSCHAR, bFullShape); 7849db44371SKatayama Hirofumi MZ SET_KEY_LOCKED(KeyState, VK_DBE_DBCSCHAR, bFullShape); 7859db44371SKatayama Hirofumi MZ SET_KEY_DOWN(KeyState, VK_DBE_SBCSCHAR, !bFullShape); 7869db44371SKatayama Hirofumi MZ SET_KEY_LOCKED(KeyState, VK_DBE_SBCSCHAR, !bFullShape); 7879db44371SKatayama Hirofumi MZ 7889db44371SKatayama Hirofumi MZ bRoman = (dwConversion & IME_CMODE_ROMAN); 7899db44371SKatayama Hirofumi MZ SET_KEY_DOWN(KeyState, VK_DBE_ROMAN, bRoman); 7909db44371SKatayama Hirofumi MZ SET_KEY_LOCKED(KeyState, VK_DBE_ROMAN, bRoman); 7919db44371SKatayama Hirofumi MZ SET_KEY_DOWN(KeyState, VK_DBE_NOROMAN, !bRoman); 7929db44371SKatayama Hirofumi MZ SET_KEY_LOCKED(KeyState, VK_DBE_NOROMAN, !bRoman); 7939db44371SKatayama Hirofumi MZ 7949db44371SKatayama Hirofumi MZ bCharCode = (dwConversion & IME_CMODE_CHARCODE); 7959db44371SKatayama Hirofumi MZ SET_KEY_DOWN(KeyState, VK_DBE_CODEINPUT, bCharCode); 7969db44371SKatayama Hirofumi MZ SET_KEY_LOCKED(KeyState, VK_DBE_CODEINPUT, bCharCode); 7979db44371SKatayama Hirofumi MZ SET_KEY_DOWN(KeyState, VK_DBE_NOCODEINPUT, !bCharCode); 7989db44371SKatayama Hirofumi MZ SET_KEY_LOCKED(KeyState, VK_DBE_NOCODEINPUT, !bCharCode); 7999db44371SKatayama Hirofumi MZ break; 8009db44371SKatayama Hirofumi MZ 8019db44371SKatayama Hirofumi MZ case LANG_KOREAN: 8029db44371SKatayama Hirofumi MZ SET_KEY_LOCKED(KeyState, VK_HANGUL, (dwConversion & IME_CMODE_NATIVE)); 8039db44371SKatayama Hirofumi MZ SET_KEY_LOCKED(KeyState, VK_JUNJA, (dwConversion & IME_CMODE_FULLSHAPE)); 8049db44371SKatayama Hirofumi MZ SET_KEY_LOCKED(KeyState, VK_HANJA, (dwConversion & IME_CMODE_HANJACONVERT)); 8059db44371SKatayama Hirofumi MZ break; 8069db44371SKatayama Hirofumi MZ 8079db44371SKatayama Hirofumi MZ default: 8089db44371SKatayama Hirofumi MZ break; 8099db44371SKatayama Hirofumi MZ } 8109db44371SKatayama Hirofumi MZ } 8119db44371SKatayama Hirofumi MZ 812c2c66affSColin Finck DWORD 813e52ce89bSKatayama Hirofumi MZ NTAPI 8149adc538cSKatayama Hirofumi MZ NtUserNotifyIMEStatus(HWND hwnd, BOOL fOpen, DWORD dwConversion) 815c2c66affSColin Finck { 8169db44371SKatayama Hirofumi MZ PWND pwnd; 8179db44371SKatayama Hirofumi MZ PTHREADINFO pti; 8189db44371SKatayama Hirofumi MZ HKL hKL; 8199db44371SKatayama Hirofumi MZ 8209db44371SKatayama Hirofumi MZ UserEnterExclusive(); 8219db44371SKatayama Hirofumi MZ 822b5c9d532SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 823b5c9d532SKatayama Hirofumi MZ { 824b5c9d532SKatayama Hirofumi MZ ERR("!IS_IMM_MODE()\n"); 825b5c9d532SKatayama Hirofumi MZ goto Quit; 826b5c9d532SKatayama Hirofumi MZ } 827b5c9d532SKatayama Hirofumi MZ 8289db44371SKatayama Hirofumi MZ pwnd = ValidateHwndNoErr(hwnd); 829b5c9d532SKatayama Hirofumi MZ if (!pwnd) 8309db44371SKatayama Hirofumi MZ goto Quit; 8319db44371SKatayama Hirofumi MZ 8329db44371SKatayama Hirofumi MZ pti = pwnd->head.pti; 8339db44371SKatayama Hirofumi MZ if (!pti || !gptiForeground) 8349db44371SKatayama Hirofumi MZ goto Quit; 8359db44371SKatayama Hirofumi MZ if (pti != gptiForeground && pti->MessageQueue != gptiForeground->MessageQueue) 8369db44371SKatayama Hirofumi MZ goto Quit; 8379db44371SKatayama Hirofumi MZ if (ghIMC == pwnd->hImc && gfImeOpen == !!fOpen && gdwImeConversion == dwConversion) 8389db44371SKatayama Hirofumi MZ goto Quit; 8399db44371SKatayama Hirofumi MZ 8409db44371SKatayama Hirofumi MZ ghIMC = pwnd->hImc; 8419db44371SKatayama Hirofumi MZ if (ghIMC) 8429db44371SKatayama Hirofumi MZ { 8439db44371SKatayama Hirofumi MZ gfImeOpen = !!fOpen; 8449db44371SKatayama Hirofumi MZ gdwImeConversion = dwConversion; 8459db44371SKatayama Hirofumi MZ UserSetImeConversionKeyState(pti, (fOpen ? dwConversion : IME_CMODE_ALPHANUMERIC)); 8469db44371SKatayama Hirofumi MZ } 8479db44371SKatayama Hirofumi MZ 8489db44371SKatayama Hirofumi MZ if (ISITHOOKED(WH_SHELL)) 8499db44371SKatayama Hirofumi MZ { 8509db44371SKatayama Hirofumi MZ hKL = (pti->KeyboardLayout ? pti->KeyboardLayout->hkl : NULL); 8519db44371SKatayama Hirofumi MZ co_HOOK_CallHooks(WH_SHELL, HSHELL_LANGUAGE, (WPARAM)hwnd, (LPARAM)hKL); 8529db44371SKatayama Hirofumi MZ } 8539db44371SKatayama Hirofumi MZ 8549db44371SKatayama Hirofumi MZ // TODO: 8559db44371SKatayama Hirofumi MZ 8569db44371SKatayama Hirofumi MZ Quit: 8579db44371SKatayama Hirofumi MZ UserLeave(); 858c2c66affSColin Finck return 0; 859c2c66affSColin Finck } 860c2c66affSColin Finck 861fcc222c2SKatayama Hirofumi MZ BOOL 862e52ce89bSKatayama Hirofumi MZ NTAPI 863c2c66affSColin Finck NtUserDisableThreadIme( 864fcc222c2SKatayama Hirofumi MZ DWORD dwThreadID) 865c2c66affSColin Finck { 866fcc222c2SKatayama Hirofumi MZ PTHREADINFO pti, ptiCurrent; 867fcc222c2SKatayama Hirofumi MZ PPROCESSINFO ppi; 868fcc222c2SKatayama Hirofumi MZ BOOL ret = FALSE; 869fcc222c2SKatayama Hirofumi MZ 870fcc222c2SKatayama Hirofumi MZ UserEnterExclusive(); 871fcc222c2SKatayama Hirofumi MZ 872fcc222c2SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 873fcc222c2SKatayama Hirofumi MZ { 874b5c9d532SKatayama Hirofumi MZ ERR("!IS_IMM_MODE()\n"); 875fcc222c2SKatayama Hirofumi MZ EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); 876fcc222c2SKatayama Hirofumi MZ goto Quit; 877fcc222c2SKatayama Hirofumi MZ } 878fcc222c2SKatayama Hirofumi MZ 879fcc222c2SKatayama Hirofumi MZ ptiCurrent = GetW32ThreadInfo(); 880fcc222c2SKatayama Hirofumi MZ 881fcc222c2SKatayama Hirofumi MZ if (dwThreadID == INVALID_THREAD_ID) 882fcc222c2SKatayama Hirofumi MZ { 883fcc222c2SKatayama Hirofumi MZ ppi = ptiCurrent->ppi; 884fcc222c2SKatayama Hirofumi MZ ppi->W32PF_flags |= W32PF_DISABLEIME; 885fcc222c2SKatayama Hirofumi MZ 886fcc222c2SKatayama Hirofumi MZ Retry: 887fcc222c2SKatayama Hirofumi MZ for (pti = ppi->ptiList; pti; pti = pti->ptiSibling) 888fcc222c2SKatayama Hirofumi MZ { 889fcc222c2SKatayama Hirofumi MZ pti->TIF_flags |= TIF_DISABLEIME; 890fcc222c2SKatayama Hirofumi MZ 891fcc222c2SKatayama Hirofumi MZ if (pti->spwndDefaultIme) 892fcc222c2SKatayama Hirofumi MZ { 893fcc222c2SKatayama Hirofumi MZ co_UserDestroyWindow(pti->spwndDefaultIme); 894fcc222c2SKatayama Hirofumi MZ pti->spwndDefaultIme = NULL; 895fcc222c2SKatayama Hirofumi MZ goto Retry; /* The contents of ppi->ptiList may be changed. */ 896fcc222c2SKatayama Hirofumi MZ } 897fcc222c2SKatayama Hirofumi MZ } 898fcc222c2SKatayama Hirofumi MZ } 899fcc222c2SKatayama Hirofumi MZ else 900fcc222c2SKatayama Hirofumi MZ { 901fcc222c2SKatayama Hirofumi MZ if (dwThreadID == 0) 902fcc222c2SKatayama Hirofumi MZ { 903fcc222c2SKatayama Hirofumi MZ pti = ptiCurrent; 904fcc222c2SKatayama Hirofumi MZ } 905fcc222c2SKatayama Hirofumi MZ else 906fcc222c2SKatayama Hirofumi MZ { 907fcc222c2SKatayama Hirofumi MZ pti = IntTID2PTI(UlongToHandle(dwThreadID)); 908fcc222c2SKatayama Hirofumi MZ 909fcc222c2SKatayama Hirofumi MZ /* The thread needs to reside in the current process. */ 910fcc222c2SKatayama Hirofumi MZ if (!pti || pti->ppi != ptiCurrent->ppi) 911fcc222c2SKatayama Hirofumi MZ goto Quit; 912fcc222c2SKatayama Hirofumi MZ } 913fcc222c2SKatayama Hirofumi MZ 914fcc222c2SKatayama Hirofumi MZ pti->TIF_flags |= TIF_DISABLEIME; 915fcc222c2SKatayama Hirofumi MZ 916fcc222c2SKatayama Hirofumi MZ if (pti->spwndDefaultIme) 917fcc222c2SKatayama Hirofumi MZ { 918fcc222c2SKatayama Hirofumi MZ co_UserDestroyWindow(pti->spwndDefaultIme); 919fcc222c2SKatayama Hirofumi MZ pti->spwndDefaultIme = NULL; 920fcc222c2SKatayama Hirofumi MZ } 921fcc222c2SKatayama Hirofumi MZ } 922fcc222c2SKatayama Hirofumi MZ 923fcc222c2SKatayama Hirofumi MZ ret = TRUE; 924fcc222c2SKatayama Hirofumi MZ 925fcc222c2SKatayama Hirofumi MZ Quit: 926fcc222c2SKatayama Hirofumi MZ UserLeave(); 927fcc222c2SKatayama Hirofumi MZ return ret; 928c2c66affSColin Finck } 929c2c66affSColin Finck 930c2c66affSColin Finck DWORD 931e52ce89bSKatayama Hirofumi MZ NTAPI 932f4bc74edSKatayama Hirofumi MZ NtUserGetAppImeLevel(HWND hWnd) 933c2c66affSColin Finck { 9349c8167e9SKatayama Hirofumi MZ DWORD ret = 0; 9359c8167e9SKatayama Hirofumi MZ PWND pWnd; 9369c8167e9SKatayama Hirofumi MZ PTHREADINFO pti; 9379c8167e9SKatayama Hirofumi MZ 9389c8167e9SKatayama Hirofumi MZ UserEnterShared(); 9399c8167e9SKatayama Hirofumi MZ 9409c8167e9SKatayama Hirofumi MZ pWnd = ValidateHwndNoErr(hWnd); 9419c8167e9SKatayama Hirofumi MZ if (!pWnd) 9429c8167e9SKatayama Hirofumi MZ goto Quit; 9439c8167e9SKatayama Hirofumi MZ 9449c8167e9SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 9459c8167e9SKatayama Hirofumi MZ { 946b5c9d532SKatayama Hirofumi MZ ERR("!IS_IMM_MODE()\n"); 9479c8167e9SKatayama Hirofumi MZ EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); 9489c8167e9SKatayama Hirofumi MZ goto Quit; 9499c8167e9SKatayama Hirofumi MZ } 9509c8167e9SKatayama Hirofumi MZ 9519c8167e9SKatayama Hirofumi MZ pti = PsGetCurrentThreadWin32Thread(); 9529c8167e9SKatayama Hirofumi MZ if (pWnd->head.pti->ppi == pti->ppi) 9539c8167e9SKatayama Hirofumi MZ ret = (DWORD)(ULONG_PTR)UserGetProp(pWnd, AtomImeLevel, TRUE); 9549c8167e9SKatayama Hirofumi MZ 9559c8167e9SKatayama Hirofumi MZ Quit: 9569c8167e9SKatayama Hirofumi MZ UserLeave(); 9579c8167e9SKatayama Hirofumi MZ return ret; 958c2c66affSColin Finck } 959c2c66affSColin Finck 9602f7775c6SKatayama Hirofumi MZ // Win: GetImeInfoEx 9619e7c2ba4SKatayama Hirofumi MZ BOOL FASTCALL 9629e7c2ba4SKatayama Hirofumi MZ UserGetImeInfoEx( 9639e7c2ba4SKatayama Hirofumi MZ _Inout_ PWINSTATION_OBJECT pWinSta, 9649e7c2ba4SKatayama Hirofumi MZ _Inout_ PIMEINFOEX pInfoEx, 9659e7c2ba4SKatayama Hirofumi MZ _In_ IMEINFOEXCLASS SearchType) 96636740ca9SKatayama Hirofumi MZ { 96736740ca9SKatayama Hirofumi MZ PKL pkl, pklHead; 96836740ca9SKatayama Hirofumi MZ 9699e7c2ba4SKatayama Hirofumi MZ if (!pWinSta || !gspklBaseLayout) 97036740ca9SKatayama Hirofumi MZ return FALSE; 97136740ca9SKatayama Hirofumi MZ 97236740ca9SKatayama Hirofumi MZ pkl = pklHead = gspklBaseLayout; 97336740ca9SKatayama Hirofumi MZ 97436740ca9SKatayama Hirofumi MZ /* Find the matching entry from the list and get info */ 97536740ca9SKatayama Hirofumi MZ if (SearchType == ImeInfoExKeyboardLayout) 97636740ca9SKatayama Hirofumi MZ { 97736740ca9SKatayama Hirofumi MZ do 97836740ca9SKatayama Hirofumi MZ { 97928959a2dSKatayama Hirofumi MZ if (pInfoEx->hkl == pkl->hkl) 98036740ca9SKatayama Hirofumi MZ { 98136740ca9SKatayama Hirofumi MZ if (!pkl->piiex) 9829e7c2ba4SKatayama Hirofumi MZ { 9839e7c2ba4SKatayama Hirofumi MZ ERR("!pkl->piiex at %p\n", pkl->hkl); 98436740ca9SKatayama Hirofumi MZ break; 9859e7c2ba4SKatayama Hirofumi MZ } 98636740ca9SKatayama Hirofumi MZ 98728959a2dSKatayama Hirofumi MZ *pInfoEx = *pkl->piiex; 98828959a2dSKatayama Hirofumi MZ return TRUE; 98936740ca9SKatayama Hirofumi MZ } 99036740ca9SKatayama Hirofumi MZ 99136740ca9SKatayama Hirofumi MZ pkl = pkl->pklNext; 99236740ca9SKatayama Hirofumi MZ } while (pkl != pklHead); 99336740ca9SKatayama Hirofumi MZ } 99436740ca9SKatayama Hirofumi MZ else if (SearchType == ImeInfoExImeFileName) 99536740ca9SKatayama Hirofumi MZ { 99636740ca9SKatayama Hirofumi MZ do 99736740ca9SKatayama Hirofumi MZ { 998c7ba53e3SKatayama Hirofumi MZ if (pkl->piiex && 999c7ba53e3SKatayama Hirofumi MZ _wcsnicmp(pkl->piiex->wszImeFile, pInfoEx->wszImeFile, 100028959a2dSKatayama Hirofumi MZ RTL_NUMBER_OF(pkl->piiex->wszImeFile)) == 0) 100136740ca9SKatayama Hirofumi MZ { 100228959a2dSKatayama Hirofumi MZ *pInfoEx = *pkl->piiex; 100328959a2dSKatayama Hirofumi MZ return TRUE; 100436740ca9SKatayama Hirofumi MZ } 100536740ca9SKatayama Hirofumi MZ 100636740ca9SKatayama Hirofumi MZ pkl = pkl->pklNext; 100736740ca9SKatayama Hirofumi MZ } while (pkl != pklHead); 100836740ca9SKatayama Hirofumi MZ } 100936740ca9SKatayama Hirofumi MZ else 101036740ca9SKatayama Hirofumi MZ { 1011c7ba53e3SKatayama Hirofumi MZ ERR("SearchType: %d\n", SearchType); 101236740ca9SKatayama Hirofumi MZ } 101336740ca9SKatayama Hirofumi MZ 101428959a2dSKatayama Hirofumi MZ return FALSE; 101536740ca9SKatayama Hirofumi MZ } 101636740ca9SKatayama Hirofumi MZ 10174b038ec8SKatayama Hirofumi MZ BOOL 1018e52ce89bSKatayama Hirofumi MZ NTAPI 1019c2c66affSColin Finck NtUserGetImeInfoEx( 1020c2c66affSColin Finck PIMEINFOEX pImeInfoEx, 10214b038ec8SKatayama Hirofumi MZ IMEINFOEXCLASS SearchType) 1022c2c66affSColin Finck { 102336740ca9SKatayama Hirofumi MZ IMEINFOEX ImeInfoEx; 102436740ca9SKatayama Hirofumi MZ BOOL ret = FALSE; 10259e7c2ba4SKatayama Hirofumi MZ PWINSTATION_OBJECT pWinSta; 102636740ca9SKatayama Hirofumi MZ 102736740ca9SKatayama Hirofumi MZ UserEnterShared(); 102836740ca9SKatayama Hirofumi MZ 102936740ca9SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 1030b5c9d532SKatayama Hirofumi MZ { 1031b5c9d532SKatayama Hirofumi MZ ERR("!IS_IMM_MODE()\n"); 103236740ca9SKatayama Hirofumi MZ goto Quit; 1033b5c9d532SKatayama Hirofumi MZ } 103436740ca9SKatayama Hirofumi MZ 103536740ca9SKatayama Hirofumi MZ _SEH2_TRY 103636740ca9SKatayama Hirofumi MZ { 103736740ca9SKatayama Hirofumi MZ ProbeForWrite(pImeInfoEx, sizeof(*pImeInfoEx), 1); 103836740ca9SKatayama Hirofumi MZ ImeInfoEx = *pImeInfoEx; 103936740ca9SKatayama Hirofumi MZ } 104036740ca9SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 104136740ca9SKatayama Hirofumi MZ { 104236740ca9SKatayama Hirofumi MZ goto Quit; 104336740ca9SKatayama Hirofumi MZ } 104436740ca9SKatayama Hirofumi MZ _SEH2_END; 104536740ca9SKatayama Hirofumi MZ 10469e7c2ba4SKatayama Hirofumi MZ pWinSta = IntGetProcessWindowStation(NULL); 10479e7c2ba4SKatayama Hirofumi MZ ret = UserGetImeInfoEx(pWinSta, &ImeInfoEx, SearchType); 1048e52ce89bSKatayama Hirofumi MZ if (!ret) 1049e52ce89bSKatayama Hirofumi MZ goto Quit; 1050e52ce89bSKatayama Hirofumi MZ 105136740ca9SKatayama Hirofumi MZ _SEH2_TRY 105236740ca9SKatayama Hirofumi MZ { 105336740ca9SKatayama Hirofumi MZ *pImeInfoEx = ImeInfoEx; 105436740ca9SKatayama Hirofumi MZ } 105536740ca9SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 105636740ca9SKatayama Hirofumi MZ { 105736740ca9SKatayama Hirofumi MZ ret = FALSE; 105836740ca9SKatayama Hirofumi MZ } 105936740ca9SKatayama Hirofumi MZ _SEH2_END; 1060c2c66affSColin Finck 106136740ca9SKatayama Hirofumi MZ Quit: 106236740ca9SKatayama Hirofumi MZ UserLeave(); 106336740ca9SKatayama Hirofumi MZ return ret; 106436740ca9SKatayama Hirofumi MZ } 1065c2c66affSColin Finck 10669c8167e9SKatayama Hirofumi MZ BOOL 1067e52ce89bSKatayama Hirofumi MZ NTAPI 10689c8167e9SKatayama Hirofumi MZ NtUserSetAppImeLevel(HWND hWnd, DWORD dwLevel) 1069c2c66affSColin Finck { 10709c8167e9SKatayama Hirofumi MZ BOOL ret = FALSE; 10719c8167e9SKatayama Hirofumi MZ PWND pWnd; 10729c8167e9SKatayama Hirofumi MZ PTHREADINFO pti; 10739c8167e9SKatayama Hirofumi MZ 10749c8167e9SKatayama Hirofumi MZ UserEnterExclusive(); 10759c8167e9SKatayama Hirofumi MZ 10769c8167e9SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 10779c8167e9SKatayama Hirofumi MZ { 1078b5c9d532SKatayama Hirofumi MZ ERR("!IS_IMM_MODE()\n"); 10799c8167e9SKatayama Hirofumi MZ EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); 10809c8167e9SKatayama Hirofumi MZ goto Quit; 10819c8167e9SKatayama Hirofumi MZ } 10829c8167e9SKatayama Hirofumi MZ 1083b5c9d532SKatayama Hirofumi MZ pWnd = ValidateHwndNoErr(hWnd); 1084b5c9d532SKatayama Hirofumi MZ if (!pWnd) 1085b5c9d532SKatayama Hirofumi MZ goto Quit; 1086b5c9d532SKatayama Hirofumi MZ 10879c8167e9SKatayama Hirofumi MZ pti = PsGetCurrentThreadWin32Thread(); 10889c8167e9SKatayama Hirofumi MZ if (pWnd->head.pti->ppi == pti->ppi) 10899c8167e9SKatayama Hirofumi MZ ret = UserSetProp(pWnd, AtomImeLevel, (HANDLE)(ULONG_PTR)dwLevel, TRUE); 10909c8167e9SKatayama Hirofumi MZ 10919c8167e9SKatayama Hirofumi MZ Quit: 10929c8167e9SKatayama Hirofumi MZ UserLeave(); 10939c8167e9SKatayama Hirofumi MZ return ret; 1094c2c66affSColin Finck } 1095c2c66affSColin Finck 10962f7775c6SKatayama Hirofumi MZ // Win: SetImeInfoEx 10979e7c2ba4SKatayama Hirofumi MZ BOOL FASTCALL 10989e7c2ba4SKatayama Hirofumi MZ UserSetImeInfoEx( 10999e7c2ba4SKatayama Hirofumi MZ _Inout_ PWINSTATION_OBJECT pWinSta, 11009e7c2ba4SKatayama Hirofumi MZ _Inout_ PIMEINFOEX pImeInfoEx) 1101c2c66affSColin Finck { 11021f446936SKatayama Hirofumi MZ PKL pklHead, pkl; 11031f446936SKatayama Hirofumi MZ 11049e7c2ba4SKatayama Hirofumi MZ if (!pWinSta || !gspklBaseLayout) 11059e7c2ba4SKatayama Hirofumi MZ return FALSE; 11069e7c2ba4SKatayama Hirofumi MZ 11071f446936SKatayama Hirofumi MZ pkl = pklHead = gspklBaseLayout; 11081f446936SKatayama Hirofumi MZ 11091f446936SKatayama Hirofumi MZ do 11101f446936SKatayama Hirofumi MZ { 11111f446936SKatayama Hirofumi MZ if (pkl->hkl != pImeInfoEx->hkl) 11121f446936SKatayama Hirofumi MZ { 11131f446936SKatayama Hirofumi MZ pkl = pkl->pklNext; 11141f446936SKatayama Hirofumi MZ continue; 11151f446936SKatayama Hirofumi MZ } 11161f446936SKatayama Hirofumi MZ 11171f446936SKatayama Hirofumi MZ if (!pkl->piiex) 11189e7c2ba4SKatayama Hirofumi MZ { 11199e7c2ba4SKatayama Hirofumi MZ ERR("!pkl->piiex at %p\n", pkl->hkl); 11201f446936SKatayama Hirofumi MZ return FALSE; 11219e7c2ba4SKatayama Hirofumi MZ } 11221f446936SKatayama Hirofumi MZ 11231f446936SKatayama Hirofumi MZ if (!pkl->piiex->fLoadFlag) 11241f446936SKatayama Hirofumi MZ *pkl->piiex = *pImeInfoEx; 11251f446936SKatayama Hirofumi MZ 11261f446936SKatayama Hirofumi MZ return TRUE; 11271f446936SKatayama Hirofumi MZ } while (pkl != pklHead); 11281f446936SKatayama Hirofumi MZ 11291f446936SKatayama Hirofumi MZ return FALSE; 11301f446936SKatayama Hirofumi MZ } 11311f446936SKatayama Hirofumi MZ 11321f446936SKatayama Hirofumi MZ BOOL 1133e52ce89bSKatayama Hirofumi MZ NTAPI 11341f446936SKatayama Hirofumi MZ NtUserSetImeInfoEx(PIMEINFOEX pImeInfoEx) 11351f446936SKatayama Hirofumi MZ { 11361f446936SKatayama Hirofumi MZ BOOL ret = FALSE; 11371f446936SKatayama Hirofumi MZ IMEINFOEX ImeInfoEx; 11389e7c2ba4SKatayama Hirofumi MZ PWINSTATION_OBJECT pWinSta; 11391f446936SKatayama Hirofumi MZ 11401f446936SKatayama Hirofumi MZ UserEnterExclusive(); 11411f446936SKatayama Hirofumi MZ 11421f446936SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 1143b5c9d532SKatayama Hirofumi MZ { 1144b5c9d532SKatayama Hirofumi MZ ERR("!IS_IMM_MODE()\n"); 11451f446936SKatayama Hirofumi MZ goto Quit; 1146b5c9d532SKatayama Hirofumi MZ } 11471f446936SKatayama Hirofumi MZ 11481f446936SKatayama Hirofumi MZ _SEH2_TRY 11491f446936SKatayama Hirofumi MZ { 11501f446936SKatayama Hirofumi MZ ProbeForRead(pImeInfoEx, sizeof(*pImeInfoEx), 1); 11511f446936SKatayama Hirofumi MZ ImeInfoEx = *pImeInfoEx; 11521f446936SKatayama Hirofumi MZ } 11531f446936SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 11541f446936SKatayama Hirofumi MZ { 11551f446936SKatayama Hirofumi MZ goto Quit; 11561f446936SKatayama Hirofumi MZ } 11571f446936SKatayama Hirofumi MZ _SEH2_END; 11581f446936SKatayama Hirofumi MZ 11599e7c2ba4SKatayama Hirofumi MZ pWinSta = IntGetProcessWindowStation(NULL); 11609e7c2ba4SKatayama Hirofumi MZ ret = UserSetImeInfoEx(pWinSta, &ImeInfoEx); 11611f446936SKatayama Hirofumi MZ 11621f446936SKatayama Hirofumi MZ Quit: 11631f446936SKatayama Hirofumi MZ UserLeave(); 11641f446936SKatayama Hirofumi MZ return ret; 1165c2c66affSColin Finck } 1166c2c66affSColin Finck 1167291a94cdSKatayama Hirofumi MZ // Choose the preferred owner of the IME window. 1168291a94cdSKatayama Hirofumi MZ // Win: ImeSetFutureOwner 1169291a94cdSKatayama Hirofumi MZ VOID FASTCALL IntImeSetFutureOwner(PWND pImeWnd, PWND pwndOwner) 1170291a94cdSKatayama Hirofumi MZ { 1171291a94cdSKatayama Hirofumi MZ PWND pwndNode, pwndNextOwner, pwndParent, pwndSibling; 1172291a94cdSKatayama Hirofumi MZ PTHREADINFO pti = pImeWnd->head.pti; 1173291a94cdSKatayama Hirofumi MZ 1174291a94cdSKatayama Hirofumi MZ if (!pwndOwner || (pwndOwner->style & WS_CHILD)) // invalid owner 1175291a94cdSKatayama Hirofumi MZ return; 1176291a94cdSKatayama Hirofumi MZ 1177291a94cdSKatayama Hirofumi MZ // Get the top-level owner of the same thread 1178291a94cdSKatayama Hirofumi MZ for (pwndNode = pwndOwner; ; pwndNode = pwndNextOwner) 1179291a94cdSKatayama Hirofumi MZ { 1180291a94cdSKatayama Hirofumi MZ pwndNextOwner = pwndNode->spwndOwner; 1181291a94cdSKatayama Hirofumi MZ if (!pwndNextOwner || pwndNextOwner->head.pti != pti) 1182291a94cdSKatayama Hirofumi MZ break; 1183291a94cdSKatayama Hirofumi MZ } 1184291a94cdSKatayama Hirofumi MZ 1185291a94cdSKatayama Hirofumi MZ // Don't choose the IME-like windows and the bottom-most windows unless necessary. 1186291a94cdSKatayama Hirofumi MZ if (IS_WND_IMELIKE(pwndNode) || 1187291a94cdSKatayama Hirofumi MZ ((pwndNode->state2 & WNDS2_BOTTOMMOST) && !(pwndOwner->state2 & WNDS2_BOTTOMMOST))) 1188291a94cdSKatayama Hirofumi MZ { 1189291a94cdSKatayama Hirofumi MZ pwndNode = pwndOwner; 1190291a94cdSKatayama Hirofumi MZ } 1191291a94cdSKatayama Hirofumi MZ 1192291a94cdSKatayama Hirofumi MZ pwndParent = pwndNode->spwndParent; 1193291a94cdSKatayama Hirofumi MZ if (!pwndParent || pwndOwner != pwndNode) 1194291a94cdSKatayama Hirofumi MZ { 1195*e56da485STimo Kreuzer WndSetOwner(pImeWnd, pwndNode); 1196291a94cdSKatayama Hirofumi MZ return; 1197291a94cdSKatayama Hirofumi MZ } 1198291a94cdSKatayama Hirofumi MZ 1199291a94cdSKatayama Hirofumi MZ for (pwndSibling = pwndParent->spwndChild; pwndSibling; pwndSibling = pwndSibling->spwndNext) 1200291a94cdSKatayama Hirofumi MZ { 1201291a94cdSKatayama Hirofumi MZ if (pwndNode->head.pti != pwndSibling->head.pti) 1202291a94cdSKatayama Hirofumi MZ continue; 1203291a94cdSKatayama Hirofumi MZ 1204291a94cdSKatayama Hirofumi MZ if (IS_WND_MENU(pwndSibling) || IS_WND_IMELIKE(pwndSibling)) 1205291a94cdSKatayama Hirofumi MZ continue; 1206291a94cdSKatayama Hirofumi MZ 1207291a94cdSKatayama Hirofumi MZ if (pwndSibling->state2 & WNDS2_INDESTROY) 1208291a94cdSKatayama Hirofumi MZ continue; 1209291a94cdSKatayama Hirofumi MZ 1210291a94cdSKatayama Hirofumi MZ if (pwndNode == pwndSibling || (pwndSibling->style & WS_CHILD)) 1211291a94cdSKatayama Hirofumi MZ continue; 1212291a94cdSKatayama Hirofumi MZ 1213291a94cdSKatayama Hirofumi MZ if (pwndSibling->spwndOwner == NULL || 1214291a94cdSKatayama Hirofumi MZ pwndSibling->head.pti != pwndSibling->spwndOwner->head.pti) 1215291a94cdSKatayama Hirofumi MZ { 1216291a94cdSKatayama Hirofumi MZ pwndNode = pwndSibling; 1217291a94cdSKatayama Hirofumi MZ break; 1218291a94cdSKatayama Hirofumi MZ } 1219291a94cdSKatayama Hirofumi MZ } 1220291a94cdSKatayama Hirofumi MZ 1221*e56da485STimo Kreuzer WndSetOwner(pImeWnd, pwndNode); 1222291a94cdSKatayama Hirofumi MZ } 1223291a94cdSKatayama Hirofumi MZ 1224291a94cdSKatayama Hirofumi MZ // Get the last non-IME-like top-most window on the desktop. 1225291a94cdSKatayama Hirofumi MZ // Win: GetLastTopMostWindowNoIME 1226291a94cdSKatayama Hirofumi MZ PWND FASTCALL IntGetLastTopMostWindowNoIME(PWND pImeWnd) 1227291a94cdSKatayama Hirofumi MZ { 1228291a94cdSKatayama Hirofumi MZ PWND pwndNode, pwndOwner, pwndLastTopMost = NULL; 1229291a94cdSKatayama Hirofumi MZ BOOL bFound; 1230291a94cdSKatayama Hirofumi MZ 1231291a94cdSKatayama Hirofumi MZ pwndNode = UserGetDesktopWindow(); 1232291a94cdSKatayama Hirofumi MZ if (!pwndNode || pwndNode->spwndChild == NULL) 1233291a94cdSKatayama Hirofumi MZ return NULL; 1234291a94cdSKatayama Hirofumi MZ 1235291a94cdSKatayama Hirofumi MZ for (pwndNode = pwndNode->spwndChild; 1236291a94cdSKatayama Hirofumi MZ pwndNode && (pwndNode->ExStyle & WS_EX_TOPMOST); 1237291a94cdSKatayama Hirofumi MZ pwndNode = pwndNode->spwndNext) 1238291a94cdSKatayama Hirofumi MZ { 1239291a94cdSKatayama Hirofumi MZ bFound = FALSE; 1240291a94cdSKatayama Hirofumi MZ 1241291a94cdSKatayama Hirofumi MZ if (IS_WND_IMELIKE(pwndNode)) // An IME-like window 1242291a94cdSKatayama Hirofumi MZ { 1243291a94cdSKatayama Hirofumi MZ // Search the IME window from owners 1244291a94cdSKatayama Hirofumi MZ for (pwndOwner = pwndNode; pwndOwner; pwndOwner = pwndOwner->spwndOwner) 1245291a94cdSKatayama Hirofumi MZ { 1246291a94cdSKatayama Hirofumi MZ if (pImeWnd == pwndOwner) 1247291a94cdSKatayama Hirofumi MZ { 1248291a94cdSKatayama Hirofumi MZ bFound = TRUE; 1249291a94cdSKatayama Hirofumi MZ break; 1250291a94cdSKatayama Hirofumi MZ } 1251291a94cdSKatayama Hirofumi MZ } 1252291a94cdSKatayama Hirofumi MZ } 1253291a94cdSKatayama Hirofumi MZ 1254291a94cdSKatayama Hirofumi MZ if (!bFound) 1255291a94cdSKatayama Hirofumi MZ pwndLastTopMost = pwndNode; 1256291a94cdSKatayama Hirofumi MZ } 1257291a94cdSKatayama Hirofumi MZ 1258291a94cdSKatayama Hirofumi MZ return pwndLastTopMost; 1259291a94cdSKatayama Hirofumi MZ } 1260291a94cdSKatayama Hirofumi MZ 1261291a94cdSKatayama Hirofumi MZ // Adjust the ordering of the windows around the IME window. 1262291a94cdSKatayama Hirofumi MZ // Win: ImeSetTopMost 1263291a94cdSKatayama Hirofumi MZ VOID FASTCALL IntImeSetTopMost(PWND pImeWnd, BOOL bTopMost, PWND pwndInsertBefore) 1264291a94cdSKatayama Hirofumi MZ { 1265291a94cdSKatayama Hirofumi MZ PWND pwndParent, pwndChild, pwndNode, pwndNext, pwndInsertAfter = NULL; 1266291a94cdSKatayama Hirofumi MZ PWND pwndInsertAfterSave; 1267291a94cdSKatayama Hirofumi MZ 1268291a94cdSKatayama Hirofumi MZ pwndParent = pImeWnd->spwndParent; 1269291a94cdSKatayama Hirofumi MZ if (!pwndParent) 1270291a94cdSKatayama Hirofumi MZ return; 1271291a94cdSKatayama Hirofumi MZ 1272291a94cdSKatayama Hirofumi MZ pwndChild = pwndParent->spwndChild; 1273291a94cdSKatayama Hirofumi MZ 1274291a94cdSKatayama Hirofumi MZ if (!bTopMost) 1275291a94cdSKatayama Hirofumi MZ { 1276291a94cdSKatayama Hirofumi MZ // Calculate pwndInsertAfter 1277291a94cdSKatayama Hirofumi MZ pwndInsertAfter = IntGetLastTopMostWindowNoIME(pImeWnd); 1278291a94cdSKatayama Hirofumi MZ if (pwndInsertBefore) 1279291a94cdSKatayama Hirofumi MZ { 1280291a94cdSKatayama Hirofumi MZ for (pwndNode = pwndInsertAfter; pwndNode; pwndNode = pwndNode->spwndNext) 1281291a94cdSKatayama Hirofumi MZ { 1282291a94cdSKatayama Hirofumi MZ if (pwndNode->spwndNext == pwndInsertBefore) 1283291a94cdSKatayama Hirofumi MZ break; 1284291a94cdSKatayama Hirofumi MZ 1285291a94cdSKatayama Hirofumi MZ if (pwndNode == pImeWnd) 1286291a94cdSKatayama Hirofumi MZ return; 1287291a94cdSKatayama Hirofumi MZ } 1288291a94cdSKatayama Hirofumi MZ 1289291a94cdSKatayama Hirofumi MZ if (!pwndNode) 1290291a94cdSKatayama Hirofumi MZ return; 1291291a94cdSKatayama Hirofumi MZ 1292291a94cdSKatayama Hirofumi MZ pwndInsertAfter = pwndNode; 1293291a94cdSKatayama Hirofumi MZ } 1294291a94cdSKatayama Hirofumi MZ 1295291a94cdSKatayama Hirofumi MZ // Adjust pwndInsertAfter if the owner is bottom-most 1296291a94cdSKatayama Hirofumi MZ if (pImeWnd->spwndOwner->state2 & WNDS2_BOTTOMMOST) 1297291a94cdSKatayama Hirofumi MZ { 1298291a94cdSKatayama Hirofumi MZ for (pwndNode = pwndInsertAfter; pwndNode; pwndNode = pwndNode->spwndNext) 1299291a94cdSKatayama Hirofumi MZ { 1300291a94cdSKatayama Hirofumi MZ if (pwndNode == pImeWnd->spwndOwner) 1301291a94cdSKatayama Hirofumi MZ break; 1302291a94cdSKatayama Hirofumi MZ 1303291a94cdSKatayama Hirofumi MZ if (!IS_WND_IMELIKE(pwndNode)) 1304291a94cdSKatayama Hirofumi MZ pwndInsertAfter = pwndNode; 1305291a94cdSKatayama Hirofumi MZ } 1306291a94cdSKatayama Hirofumi MZ } 1307291a94cdSKatayama Hirofumi MZ } 1308291a94cdSKatayama Hirofumi MZ 1309291a94cdSKatayama Hirofumi MZ pwndInsertAfterSave = pwndInsertAfter; 1310291a94cdSKatayama Hirofumi MZ 1311291a94cdSKatayama Hirofumi MZ while (pwndChild) 1312291a94cdSKatayama Hirofumi MZ { 1313291a94cdSKatayama Hirofumi MZ pwndNext = pwndChild->spwndNext; 1314291a94cdSKatayama Hirofumi MZ 1315291a94cdSKatayama Hirofumi MZ // If pwndChild is a good IME-like window, ... 1316291a94cdSKatayama Hirofumi MZ if (IS_WND_IMELIKE(pwndChild) && pwndChild != pwndInsertAfter && 1317291a94cdSKatayama Hirofumi MZ pwndChild->head.pti == pImeWnd->head.pti) 1318291a94cdSKatayama Hirofumi MZ { 1319291a94cdSKatayama Hirofumi MZ // Find pImeWnd from the owners 1320291a94cdSKatayama Hirofumi MZ for (pwndNode = pwndChild; pwndNode; pwndNode = pwndNode->spwndOwner) 1321291a94cdSKatayama Hirofumi MZ { 1322291a94cdSKatayama Hirofumi MZ if (pwndNode != pImeWnd) 1323291a94cdSKatayama Hirofumi MZ continue; 1324291a94cdSKatayama Hirofumi MZ 1325291a94cdSKatayama Hirofumi MZ // Adjust the ordering and the linking 1326291a94cdSKatayama Hirofumi MZ IntUnlinkWindow(pwndChild); 1327291a94cdSKatayama Hirofumi MZ 1328291a94cdSKatayama Hirofumi MZ if (bTopMost) 1329291a94cdSKatayama Hirofumi MZ pwndChild->ExStyle |= WS_EX_TOPMOST; 1330291a94cdSKatayama Hirofumi MZ else 1331291a94cdSKatayama Hirofumi MZ pwndChild->ExStyle &= ~WS_EX_TOPMOST; 1332291a94cdSKatayama Hirofumi MZ 1333291a94cdSKatayama Hirofumi MZ if (!pwndInsertAfter) 1334291a94cdSKatayama Hirofumi MZ IntLinkHwnd(pwndChild, HWND_TOP); 1335291a94cdSKatayama Hirofumi MZ else 1336291a94cdSKatayama Hirofumi MZ IntLinkHwnd(pwndChild, UserHMGetHandle(pwndInsertAfter)); 1337291a94cdSKatayama Hirofumi MZ 1338291a94cdSKatayama Hirofumi MZ // Update the preferred position 1339291a94cdSKatayama Hirofumi MZ pwndInsertAfter = pwndChild; 1340291a94cdSKatayama Hirofumi MZ break; 1341291a94cdSKatayama Hirofumi MZ } 1342291a94cdSKatayama Hirofumi MZ } 1343291a94cdSKatayama Hirofumi MZ 1344291a94cdSKatayama Hirofumi MZ // Get the next child, with ignoring pwndInsertAfterSave 1345291a94cdSKatayama Hirofumi MZ pwndChild = pwndNext; 1346291a94cdSKatayama Hirofumi MZ if (pwndChild && pwndChild == pwndInsertAfterSave && pwndInsertAfter) 1347291a94cdSKatayama Hirofumi MZ pwndChild = pwndInsertAfter->spwndNext; 1348291a94cdSKatayama Hirofumi MZ } 1349291a94cdSKatayama Hirofumi MZ } 1350291a94cdSKatayama Hirofumi MZ 1351291a94cdSKatayama Hirofumi MZ // Make the IME window top-most if necessary. 1352291a94cdSKatayama Hirofumi MZ // Win: ImeCheckTopmost 1353291a94cdSKatayama Hirofumi MZ VOID FASTCALL IntImeCheckTopmost(PWND pImeWnd) 1354291a94cdSKatayama Hirofumi MZ { 1355291a94cdSKatayama Hirofumi MZ BOOL bTopMost; 1356291a94cdSKatayama Hirofumi MZ PWND pwndOwner = pImeWnd->spwndOwner, pwndInsertBefore = NULL; 1357291a94cdSKatayama Hirofumi MZ 1358291a94cdSKatayama Hirofumi MZ if (!pwndOwner) 1359291a94cdSKatayama Hirofumi MZ return; 1360291a94cdSKatayama Hirofumi MZ 1361291a94cdSKatayama Hirofumi MZ if (pImeWnd->head.pti != gptiForeground) 1362291a94cdSKatayama Hirofumi MZ pwndInsertBefore = pwndOwner; 1363291a94cdSKatayama Hirofumi MZ 1364291a94cdSKatayama Hirofumi MZ bTopMost = !!(pwndOwner->ExStyle & WS_EX_TOPMOST); 1365291a94cdSKatayama Hirofumi MZ IntImeSetTopMost(pImeWnd, bTopMost, pwndInsertBefore); 1366291a94cdSKatayama Hirofumi MZ } 1367291a94cdSKatayama Hirofumi MZ 1368e52ce89bSKatayama Hirofumi MZ BOOL NTAPI 13698c6dcdcfSKatayama Hirofumi MZ NtUserSetImeOwnerWindow(HWND hImeWnd, HWND hwndFocus) 1370c2c66affSColin Finck { 13710519ae0aSKatayama Hirofumi MZ BOOL ret = FALSE; 1372291a94cdSKatayama Hirofumi MZ PWND pImeWnd, pwndFocus, pwndTopLevel, pwndNode, pwndActive; 13730519ae0aSKatayama Hirofumi MZ PTHREADINFO ptiIme; 13740519ae0aSKatayama Hirofumi MZ 13750519ae0aSKatayama Hirofumi MZ UserEnterExclusive(); 13760519ae0aSKatayama Hirofumi MZ 1377b5c9d532SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 1378b5c9d532SKatayama Hirofumi MZ { 1379b5c9d532SKatayama Hirofumi MZ ERR("!IS_IMM_MODE()\n"); 1380b5c9d532SKatayama Hirofumi MZ goto Quit; 1381b5c9d532SKatayama Hirofumi MZ } 1382b5c9d532SKatayama Hirofumi MZ 13830519ae0aSKatayama Hirofumi MZ pImeWnd = ValidateHwndNoErr(hImeWnd); 1384b5c9d532SKatayama Hirofumi MZ if (!pImeWnd || pImeWnd->fnid != FNID_IME) 13850519ae0aSKatayama Hirofumi MZ goto Quit; 13860519ae0aSKatayama Hirofumi MZ 13870519ae0aSKatayama Hirofumi MZ pwndFocus = ValidateHwndNoErr(hwndFocus); 13880519ae0aSKatayama Hirofumi MZ if (pwndFocus) 13890519ae0aSKatayama Hirofumi MZ { 13900519ae0aSKatayama Hirofumi MZ if (IS_WND_IMELIKE(pwndFocus)) 13910519ae0aSKatayama Hirofumi MZ goto Quit; 13920519ae0aSKatayama Hirofumi MZ 13930519ae0aSKatayama Hirofumi MZ pwndTopLevel = IntGetTopLevelWindow(pwndFocus); 13940519ae0aSKatayama Hirofumi MZ 1395291a94cdSKatayama Hirofumi MZ for (pwndNode = pwndTopLevel; pwndNode; pwndNode = pwndNode->spwndOwner) 13960519ae0aSKatayama Hirofumi MZ { 1397291a94cdSKatayama Hirofumi MZ if (pwndNode->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME]) 13980519ae0aSKatayama Hirofumi MZ { 13990519ae0aSKatayama Hirofumi MZ pwndTopLevel = NULL; 14000519ae0aSKatayama Hirofumi MZ break; 14010519ae0aSKatayama Hirofumi MZ } 14020519ae0aSKatayama Hirofumi MZ } 14030519ae0aSKatayama Hirofumi MZ 1404*e56da485STimo Kreuzer WndSetOwner(pImeWnd, pwndTopLevel); 1405291a94cdSKatayama Hirofumi MZ IntImeCheckTopmost(pImeWnd); 14060519ae0aSKatayama Hirofumi MZ } 14070519ae0aSKatayama Hirofumi MZ else 14080519ae0aSKatayama Hirofumi MZ { 14090519ae0aSKatayama Hirofumi MZ ptiIme = pImeWnd->head.pti; 14100519ae0aSKatayama Hirofumi MZ pwndActive = ptiIme->MessageQueue->spwndActive; 14110519ae0aSKatayama Hirofumi MZ 14120519ae0aSKatayama Hirofumi MZ if (!pwndActive || pwndActive != pImeWnd->spwndOwner) 14130519ae0aSKatayama Hirofumi MZ { 14140519ae0aSKatayama Hirofumi MZ if (pwndActive && ptiIme == pwndActive->head.pti && !IS_WND_IMELIKE(pwndActive)) 14150519ae0aSKatayama Hirofumi MZ { 1416*e56da485STimo Kreuzer WndSetOwner(pImeWnd, pwndActive); 14170519ae0aSKatayama Hirofumi MZ } 14180519ae0aSKatayama Hirofumi MZ else 14190519ae0aSKatayama Hirofumi MZ { 1420291a94cdSKatayama Hirofumi MZ IntImeSetFutureOwner(pImeWnd, pImeWnd->spwndOwner); 14210519ae0aSKatayama Hirofumi MZ } 14220519ae0aSKatayama Hirofumi MZ 1423291a94cdSKatayama Hirofumi MZ IntImeCheckTopmost(pImeWnd); 14240519ae0aSKatayama Hirofumi MZ } 14250519ae0aSKatayama Hirofumi MZ } 14260519ae0aSKatayama Hirofumi MZ 14270519ae0aSKatayama Hirofumi MZ ret = TRUE; 14280519ae0aSKatayama Hirofumi MZ 14290519ae0aSKatayama Hirofumi MZ Quit: 14300519ae0aSKatayama Hirofumi MZ UserLeave(); 14310519ae0aSKatayama Hirofumi MZ return ret; 1432c2c66affSColin Finck } 1433c2c66affSColin Finck 14343d78601fSKatayama Hirofumi MZ PVOID 14353d78601fSKatayama Hirofumi MZ AllocInputContextObject(PDESKTOP pDesk, 14363d78601fSKatayama Hirofumi MZ PTHREADINFO pti, 14373d78601fSKatayama Hirofumi MZ SIZE_T Size, 14383d78601fSKatayama Hirofumi MZ PVOID* HandleOwner) 14393d78601fSKatayama Hirofumi MZ { 14403d78601fSKatayama Hirofumi MZ PTHRDESKHEAD ObjHead; 14413d78601fSKatayama Hirofumi MZ 14423d78601fSKatayama Hirofumi MZ ASSERT(Size > sizeof(*ObjHead)); 14433d78601fSKatayama Hirofumi MZ ASSERT(pti != NULL); 14443d78601fSKatayama Hirofumi MZ 1445cfeb498eSKatayama Hirofumi MZ if (!pDesk) 1446cfeb498eSKatayama Hirofumi MZ pDesk = pti->rpdesk; 1447cfeb498eSKatayama Hirofumi MZ 1448cfeb498eSKatayama Hirofumi MZ ObjHead = DesktopHeapAlloc(pDesk, Size); 14493d78601fSKatayama Hirofumi MZ if (!ObjHead) 14503d78601fSKatayama Hirofumi MZ return NULL; 14513d78601fSKatayama Hirofumi MZ 14523d78601fSKatayama Hirofumi MZ RtlZeroMemory(ObjHead, Size); 14533d78601fSKatayama Hirofumi MZ 14543d78601fSKatayama Hirofumi MZ ObjHead->pSelf = ObjHead; 14553d78601fSKatayama Hirofumi MZ ObjHead->rpdesk = pDesk; 14563d78601fSKatayama Hirofumi MZ ObjHead->pti = pti; 14573d78601fSKatayama Hirofumi MZ IntReferenceThreadInfo(pti); 14583d78601fSKatayama Hirofumi MZ *HandleOwner = pti; 14593d78601fSKatayama Hirofumi MZ pti->ppi->UserHandleCount++; 14603d78601fSKatayama Hirofumi MZ 14613d78601fSKatayama Hirofumi MZ return ObjHead; 14623d78601fSKatayama Hirofumi MZ } 14633d78601fSKatayama Hirofumi MZ 14643d78601fSKatayama Hirofumi MZ VOID UserFreeInputContext(PVOID Object) 14653d78601fSKatayama Hirofumi MZ { 1466cfeb498eSKatayama Hirofumi MZ PTHRDESKHEAD ObjHead = Object; 1467cfeb498eSKatayama Hirofumi MZ PDESKTOP pDesk = ObjHead->rpdesk; 1468eb902e5bSKatayama Hirofumi MZ PIMC pNode, pIMC = Object; 1469757bed81SKatayama Hirofumi MZ PTHREADINFO pti; 14703d78601fSKatayama Hirofumi MZ 1471757bed81SKatayama Hirofumi MZ if (!pIMC) 1472757bed81SKatayama Hirofumi MZ return; 14733d78601fSKatayama Hirofumi MZ 1474eb902e5bSKatayama Hirofumi MZ // Remove pIMC from the list except spDefaultImc 1475757bed81SKatayama Hirofumi MZ pti = pIMC->head.pti; 1476eb902e5bSKatayama Hirofumi MZ for (pNode = pti->spDefaultImc; pNode; pNode = pNode->pImcNext) 14772b2366abSKatayama Hirofumi MZ { 1478eb902e5bSKatayama Hirofumi MZ if (pNode->pImcNext == pIMC) 14792b2366abSKatayama Hirofumi MZ { 1480eb902e5bSKatayama Hirofumi MZ pNode->pImcNext = pIMC->pImcNext; 14812b2366abSKatayama Hirofumi MZ break; 14822b2366abSKatayama Hirofumi MZ } 14832b2366abSKatayama Hirofumi MZ } 1484757bed81SKatayama Hirofumi MZ 1485cfeb498eSKatayama Hirofumi MZ DesktopHeapFree(pDesk, Object); 148645a4e53fSKatayama Hirofumi MZ 148745a4e53fSKatayama Hirofumi MZ pti->ppi->UserHandleCount--; 148845a4e53fSKatayama Hirofumi MZ IntDereferenceThreadInfo(pti); 148945a4e53fSKatayama Hirofumi MZ } 149045a4e53fSKatayama Hirofumi MZ 149145a4e53fSKatayama Hirofumi MZ BOOLEAN UserDestroyInputContext(PVOID Object) 149245a4e53fSKatayama Hirofumi MZ { 14932b2366abSKatayama Hirofumi MZ PIMC pIMC = Object; 14944a748a3aSKatayama Hirofumi MZ if (!pIMC) 149545a4e53fSKatayama Hirofumi MZ return TRUE; 149645a4e53fSKatayama Hirofumi MZ 14972ef605d4SKatayama Hirofumi MZ UserMarkObjectDestroy(pIMC); 14984a748a3aSKatayama Hirofumi MZ UserDeleteObject(UserHMGetHandle(pIMC), TYPE_INPUTCONTEXT); 14994a748a3aSKatayama Hirofumi MZ return TRUE; 15003d78601fSKatayama Hirofumi MZ } 15013d78601fSKatayama Hirofumi MZ 1502eb902e5bSKatayama Hirofumi MZ // Win: DestroyInputContext 15030f1e19a7SKatayama Hirofumi MZ BOOL IntDestroyInputContext(PIMC pIMC) 15043d78601fSKatayama Hirofumi MZ { 15050f1e19a7SKatayama Hirofumi MZ HIMC hIMC = UserHMGetHandle(pIMC); 1506eb902e5bSKatayama Hirofumi MZ PTHREADINFO pti = pIMC->head.pti; 1507eb902e5bSKatayama Hirofumi MZ PWND pwndChild; 1508eb902e5bSKatayama Hirofumi MZ PWINDOWLIST pwl; 15091bc9dda5SKatayama Hirofumi MZ HWND *phwnd; 15101bc9dda5SKatayama Hirofumi MZ PWND pWnd; 15113d78601fSKatayama Hirofumi MZ 15120f1e19a7SKatayama Hirofumi MZ if (pti != gptiCurrent) 15133d78601fSKatayama Hirofumi MZ { 1514eb902e5bSKatayama Hirofumi MZ EngSetLastError(ERROR_ACCESS_DENIED); 1515eb902e5bSKatayama Hirofumi MZ return FALSE; 15163d78601fSKatayama Hirofumi MZ } 15173d78601fSKatayama Hirofumi MZ 1518eb902e5bSKatayama Hirofumi MZ if (pIMC == pti->spDefaultImc) 1519eb902e5bSKatayama Hirofumi MZ { 1520eb902e5bSKatayama Hirofumi MZ EngSetLastError(ERROR_INVALID_PARAMETER); 1521eb902e5bSKatayama Hirofumi MZ return FALSE; 1522eb902e5bSKatayama Hirofumi MZ } 15233d78601fSKatayama Hirofumi MZ 1524eb902e5bSKatayama Hirofumi MZ pwndChild = pti->rpdesk->pDeskInfo->spwnd->spwndChild; 1525eb902e5bSKatayama Hirofumi MZ pwl = IntBuildHwndList(pwndChild, IACE_LIST | IACE_CHILDREN, pti); 15261bc9dda5SKatayama Hirofumi MZ if (pwl) 15271bc9dda5SKatayama Hirofumi MZ { 15281bc9dda5SKatayama Hirofumi MZ for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd) 15291bc9dda5SKatayama Hirofumi MZ { 1530eb902e5bSKatayama Hirofumi MZ pWnd = UserGetObjectNoErr(gHandleTable, *phwnd, TYPE_WINDOW); 1531eb902e5bSKatayama Hirofumi MZ if (pWnd && pWnd->hImc == hIMC) 15321bc9dda5SKatayama Hirofumi MZ IntAssociateInputContext(pWnd, pti->spDefaultImc); 15331bc9dda5SKatayama Hirofumi MZ } 15341bc9dda5SKatayama Hirofumi MZ 15351bc9dda5SKatayama Hirofumi MZ IntFreeHwndList(pwl); 15361bc9dda5SKatayama Hirofumi MZ } 15371bc9dda5SKatayama Hirofumi MZ 1538eb902e5bSKatayama Hirofumi MZ UserDeleteObject(hIMC, TYPE_INPUTCONTEXT); 1539eb902e5bSKatayama Hirofumi MZ return TRUE; 1540eb902e5bSKatayama Hirofumi MZ } 1541eb902e5bSKatayama Hirofumi MZ 1542eb902e5bSKatayama Hirofumi MZ BOOL NTAPI NtUserDestroyInputContext(HIMC hIMC) 1543eb902e5bSKatayama Hirofumi MZ { 1544eb902e5bSKatayama Hirofumi MZ BOOL ret = FALSE; 1545eb902e5bSKatayama Hirofumi MZ PIMC pIMC; 1546eb902e5bSKatayama Hirofumi MZ 1547eb902e5bSKatayama Hirofumi MZ UserEnterExclusive(); 1548eb902e5bSKatayama Hirofumi MZ 1549eb902e5bSKatayama Hirofumi MZ if (!IS_IMM_MODE()) 1550eb902e5bSKatayama Hirofumi MZ { 1551eb902e5bSKatayama Hirofumi MZ EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); 1552eb902e5bSKatayama Hirofumi MZ goto Quit; 1553eb902e5bSKatayama Hirofumi MZ } 1554eb902e5bSKatayama Hirofumi MZ 1555eb902e5bSKatayama Hirofumi MZ pIMC = UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT); 1556eb902e5bSKatayama Hirofumi MZ if (pIMC) 1557eb902e5bSKatayama Hirofumi MZ ret = IntDestroyInputContext(pIMC); 15581bc9dda5SKatayama Hirofumi MZ 15591bc9dda5SKatayama Hirofumi MZ Quit: 15603d78601fSKatayama Hirofumi MZ UserLeave(); 15613d78601fSKatayama Hirofumi MZ return ret; 15623d78601fSKatayama Hirofumi MZ } 1563c2c66affSColin Finck 15642f7775c6SKatayama Hirofumi MZ // Win: CreateInputContext 1565470aa276SKatayama Hirofumi MZ PIMC FASTCALL UserCreateInputContext(ULONG_PTR dwClientImcData) 1566470aa276SKatayama Hirofumi MZ { 1567470aa276SKatayama Hirofumi MZ PIMC pIMC; 1568470aa276SKatayama Hirofumi MZ PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); 1569470aa276SKatayama Hirofumi MZ PDESKTOP pdesk = pti->rpdesk; 1570470aa276SKatayama Hirofumi MZ 1571470aa276SKatayama Hirofumi MZ if (!IS_IMM_MODE() || (pti->TIF_flags & TIF_DISABLEIME)) // Disabled? 1572b5c9d532SKatayama Hirofumi MZ { 1573b5c9d532SKatayama Hirofumi MZ ERR("IME is disabled\n"); 1574470aa276SKatayama Hirofumi MZ return NULL; 1575b5c9d532SKatayama Hirofumi MZ } 1576470aa276SKatayama Hirofumi MZ 1577470aa276SKatayama Hirofumi MZ if (!pdesk) // No desktop? 1578470aa276SKatayama Hirofumi MZ return NULL; 1579470aa276SKatayama Hirofumi MZ 1580470aa276SKatayama Hirofumi MZ // pti->spDefaultImc should be already set if non-first time. 1581470aa276SKatayama Hirofumi MZ if (dwClientImcData && !pti->spDefaultImc) 1582470aa276SKatayama Hirofumi MZ return NULL; 1583470aa276SKatayama Hirofumi MZ 1584470aa276SKatayama Hirofumi MZ // Create an input context user object. 1585470aa276SKatayama Hirofumi MZ pIMC = UserCreateObject(gHandleTable, pdesk, pti, NULL, TYPE_INPUTCONTEXT, sizeof(IMC)); 1586470aa276SKatayama Hirofumi MZ if (!pIMC) 1587470aa276SKatayama Hirofumi MZ return NULL; 1588470aa276SKatayama Hirofumi MZ 1589470aa276SKatayama Hirofumi MZ // Release the extra reference (UserCreateObject added 2 references). 1590470aa276SKatayama Hirofumi MZ UserDereferenceObject(pIMC); 15914a748a3aSKatayama Hirofumi MZ ASSERT(pIMC->head.cLockObj == 1); 1592470aa276SKatayama Hirofumi MZ 1593470aa276SKatayama Hirofumi MZ if (dwClientImcData) // Non-first time. 1594470aa276SKatayama Hirofumi MZ { 1595470aa276SKatayama Hirofumi MZ // Insert pIMC to the second position (non-default) of the list. 1596470aa276SKatayama Hirofumi MZ pIMC->pImcNext = pti->spDefaultImc->pImcNext; 1597470aa276SKatayama Hirofumi MZ pti->spDefaultImc->pImcNext = pIMC; 1598470aa276SKatayama Hirofumi MZ } 1599470aa276SKatayama Hirofumi MZ else // First time. It's the default IMC. 1600470aa276SKatayama Hirofumi MZ { 1601470aa276SKatayama Hirofumi MZ // Add the first one (default) to the list. 16027e138837SKatayama Hirofumi MZ UserAssignmentLock((PVOID*)&pti->spDefaultImc, pIMC); 1603470aa276SKatayama Hirofumi MZ pIMC->pImcNext = NULL; 16044a748a3aSKatayama Hirofumi MZ ASSERT(pIMC->head.cLockObj == 2); // UserAssignmentUnlock'ed at ExitThreadCallback 1605470aa276SKatayama Hirofumi MZ } 1606470aa276SKatayama Hirofumi MZ 1607470aa276SKatayama Hirofumi MZ pIMC->dwClientImcData = dwClientImcData; // Set it. 1608470aa276SKatayama Hirofumi MZ return pIMC; 1609470aa276SKatayama Hirofumi MZ } 1610470aa276SKatayama Hirofumi MZ 1611470aa276SKatayama Hirofumi MZ HIMC 1612e52ce89bSKatayama Hirofumi MZ NTAPI 1613470aa276SKatayama Hirofumi MZ NtUserCreateInputContext(ULONG_PTR dwClientImcData) 1614470aa276SKatayama Hirofumi MZ { 1615470aa276SKatayama Hirofumi MZ PIMC pIMC; 1616470aa276SKatayama Hirofumi MZ HIMC ret = NULL; 1617470aa276SKatayama Hirofumi MZ 1618470aa276SKatayama Hirofumi MZ UserEnterExclusive(); 1619470aa276SKatayama Hirofumi MZ 1620470aa276SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 1621b5c9d532SKatayama Hirofumi MZ { 1622b5c9d532SKatayama Hirofumi MZ ERR("!IS_IMM_MODE()\n"); 162388c1d8c7SKatayama Hirofumi MZ EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); 162488c1d8c7SKatayama Hirofumi MZ goto Quit; 162588c1d8c7SKatayama Hirofumi MZ } 162688c1d8c7SKatayama Hirofumi MZ 162788c1d8c7SKatayama Hirofumi MZ if (!dwClientImcData) 162888c1d8c7SKatayama Hirofumi MZ { 162988c1d8c7SKatayama Hirofumi MZ EngSetLastError(ERROR_INVALID_PARAMETER); 1630470aa276SKatayama Hirofumi MZ goto Quit; 1631b5c9d532SKatayama Hirofumi MZ } 1632470aa276SKatayama Hirofumi MZ 1633470aa276SKatayama Hirofumi MZ pIMC = UserCreateInputContext(dwClientImcData); 1634470aa276SKatayama Hirofumi MZ if (pIMC) 1635470aa276SKatayama Hirofumi MZ ret = UserHMGetHandle(pIMC); 1636470aa276SKatayama Hirofumi MZ 1637470aa276SKatayama Hirofumi MZ Quit: 1638470aa276SKatayama Hirofumi MZ UserLeave(); 1639470aa276SKatayama Hirofumi MZ return ret; 1640470aa276SKatayama Hirofumi MZ } 1641470aa276SKatayama Hirofumi MZ 16422f7775c6SKatayama Hirofumi MZ // Win: AssociateInputContextEx 1643f2c3167dSKatayama Hirofumi MZ DWORD FASTCALL IntAssociateInputContextEx(PWND pWnd, PIMC pIMC, DWORD dwFlags) 1644f2c3167dSKatayama Hirofumi MZ { 1645f2c3167dSKatayama Hirofumi MZ DWORD ret = 0; 1646f2c3167dSKatayama Hirofumi MZ PWINDOWLIST pwl; 1647f2c3167dSKatayama Hirofumi MZ BOOL bIgnoreNullImc = (dwFlags & IACE_IGNORENOCONTEXT); 1648f2c3167dSKatayama Hirofumi MZ PTHREADINFO pti = pWnd->head.pti; 1649f2c3167dSKatayama Hirofumi MZ PWND pwndTarget, pwndFocus = pti->MessageQueue->spwndFocus; 1650f2c3167dSKatayama Hirofumi MZ HWND *phwnd; 1651f2c3167dSKatayama Hirofumi MZ HIMC hIMC; 1652f2c3167dSKatayama Hirofumi MZ 1653f2c3167dSKatayama Hirofumi MZ if (dwFlags & IACE_DEFAULT) 1654f2c3167dSKatayama Hirofumi MZ { 1655f2c3167dSKatayama Hirofumi MZ pIMC = pti->spDefaultImc; 1656f2c3167dSKatayama Hirofumi MZ } 1657f2c3167dSKatayama Hirofumi MZ else 1658f2c3167dSKatayama Hirofumi MZ { 1659f2c3167dSKatayama Hirofumi MZ if (pIMC && pti != pIMC->head.pti) 1660f2c3167dSKatayama Hirofumi MZ return 2; 1661f2c3167dSKatayama Hirofumi MZ } 1662f2c3167dSKatayama Hirofumi MZ 1663f2c3167dSKatayama Hirofumi MZ if (pWnd->head.pti->ppi != GetW32ThreadInfo()->ppi || 1664f2c3167dSKatayama Hirofumi MZ (pIMC && pIMC->head.rpdesk != pWnd->head.rpdesk)) 1665f2c3167dSKatayama Hirofumi MZ { 1666f2c3167dSKatayama Hirofumi MZ return 2; 1667f2c3167dSKatayama Hirofumi MZ } 1668f2c3167dSKatayama Hirofumi MZ 1669f2c3167dSKatayama Hirofumi MZ if ((dwFlags & IACE_CHILDREN) && pWnd->spwndChild) 1670f2c3167dSKatayama Hirofumi MZ { 1671f2c3167dSKatayama Hirofumi MZ pwl = IntBuildHwndList(pWnd->spwndChild, IACE_CHILDREN | IACE_LIST, pti); 1672f2c3167dSKatayama Hirofumi MZ if (pwl) 1673f2c3167dSKatayama Hirofumi MZ { 1674f2c3167dSKatayama Hirofumi MZ for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd) 1675f2c3167dSKatayama Hirofumi MZ { 1676f2c3167dSKatayama Hirofumi MZ pwndTarget = ValidateHwndNoErr(*phwnd); 1677f2c3167dSKatayama Hirofumi MZ if (!pwndTarget) 1678f2c3167dSKatayama Hirofumi MZ continue; 1679f2c3167dSKatayama Hirofumi MZ 1680f2c3167dSKatayama Hirofumi MZ hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL); 1681f2c3167dSKatayama Hirofumi MZ if (pwndTarget->hImc == hIMC || (bIgnoreNullImc && !pwndTarget->hImc)) 1682f2c3167dSKatayama Hirofumi MZ continue; 1683f2c3167dSKatayama Hirofumi MZ 1684f2c3167dSKatayama Hirofumi MZ IntAssociateInputContext(pwndTarget, pIMC); 1685f2c3167dSKatayama Hirofumi MZ if (pwndTarget == pwndFocus) 1686f2c3167dSKatayama Hirofumi MZ ret = 1; 1687f2c3167dSKatayama Hirofumi MZ } 1688f2c3167dSKatayama Hirofumi MZ 1689f2c3167dSKatayama Hirofumi MZ IntFreeHwndList(pwl); 1690f2c3167dSKatayama Hirofumi MZ } 1691f2c3167dSKatayama Hirofumi MZ } 1692f2c3167dSKatayama Hirofumi MZ 1693f2c3167dSKatayama Hirofumi MZ if (!bIgnoreNullImc || pWnd->hImc) 1694f2c3167dSKatayama Hirofumi MZ { 1695f2c3167dSKatayama Hirofumi MZ hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL); 1696f2c3167dSKatayama Hirofumi MZ if (pWnd->hImc != hIMC) 1697f2c3167dSKatayama Hirofumi MZ { 1698f2c3167dSKatayama Hirofumi MZ IntAssociateInputContext(pWnd, pIMC); 1699f2c3167dSKatayama Hirofumi MZ if (pWnd == pwndFocus) 1700f2c3167dSKatayama Hirofumi MZ ret = 1; 1701f2c3167dSKatayama Hirofumi MZ } 1702f2c3167dSKatayama Hirofumi MZ } 1703f2c3167dSKatayama Hirofumi MZ 1704f2c3167dSKatayama Hirofumi MZ return ret; 1705f2c3167dSKatayama Hirofumi MZ } 1706f2c3167dSKatayama Hirofumi MZ 1707470aa276SKatayama Hirofumi MZ DWORD 1708e52ce89bSKatayama Hirofumi MZ NTAPI 1709470aa276SKatayama Hirofumi MZ NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags) 1710470aa276SKatayama Hirofumi MZ { 1711f2c3167dSKatayama Hirofumi MZ DWORD ret = 2; 1712f2c3167dSKatayama Hirofumi MZ PWND pWnd; 1713f2c3167dSKatayama Hirofumi MZ PIMC pIMC; 1714f2c3167dSKatayama Hirofumi MZ 1715f2c3167dSKatayama Hirofumi MZ UserEnterExclusive(); 1716f2c3167dSKatayama Hirofumi MZ 1717b5c9d532SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 1718b5c9d532SKatayama Hirofumi MZ { 1719b5c9d532SKatayama Hirofumi MZ ERR("!IS_IMM_MODE()\n"); 1720b5c9d532SKatayama Hirofumi MZ goto Quit; 1721b5c9d532SKatayama Hirofumi MZ } 1722b5c9d532SKatayama Hirofumi MZ 1723f2c3167dSKatayama Hirofumi MZ pWnd = ValidateHwndNoErr(hWnd); 1724b5c9d532SKatayama Hirofumi MZ if (!pWnd) 1725f2c3167dSKatayama Hirofumi MZ goto Quit; 1726f2c3167dSKatayama Hirofumi MZ 1727f2c3167dSKatayama Hirofumi MZ pIMC = (hIMC ? UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT) : NULL); 1728f2c3167dSKatayama Hirofumi MZ ret = IntAssociateInputContextEx(pWnd, pIMC, dwFlags); 1729f2c3167dSKatayama Hirofumi MZ 1730f2c3167dSKatayama Hirofumi MZ Quit: 1731f2c3167dSKatayama Hirofumi MZ UserLeave(); 1732f2c3167dSKatayama Hirofumi MZ return ret; 1733470aa276SKatayama Hirofumi MZ } 1734470aa276SKatayama Hirofumi MZ 17355df5ef2bSKatayama Hirofumi MZ // Win: UpdateInputContext 1736470aa276SKatayama Hirofumi MZ BOOL FASTCALL UserUpdateInputContext(PIMC pIMC, DWORD dwType, DWORD_PTR dwValue) 1737470aa276SKatayama Hirofumi MZ { 1738470aa276SKatayama Hirofumi MZ PTHREADINFO pti = GetW32ThreadInfo(); 1739470aa276SKatayama Hirofumi MZ PTHREADINFO ptiIMC = pIMC->head.pti; 1740470aa276SKatayama Hirofumi MZ 1741470aa276SKatayama Hirofumi MZ if (pti->ppi != ptiIMC->ppi) // Different process? 1742470aa276SKatayama Hirofumi MZ return FALSE; 1743470aa276SKatayama Hirofumi MZ 1744470aa276SKatayama Hirofumi MZ switch (dwType) 1745470aa276SKatayama Hirofumi MZ { 1746470aa276SKatayama Hirofumi MZ case UIC_CLIENTIMCDATA: 1747470aa276SKatayama Hirofumi MZ if (pIMC->dwClientImcData) 1748470aa276SKatayama Hirofumi MZ return FALSE; // Already set 1749470aa276SKatayama Hirofumi MZ 1750470aa276SKatayama Hirofumi MZ pIMC->dwClientImcData = dwValue; 1751470aa276SKatayama Hirofumi MZ break; 1752470aa276SKatayama Hirofumi MZ 1753470aa276SKatayama Hirofumi MZ case UIC_IMEWINDOW: 1754470aa276SKatayama Hirofumi MZ if (!ValidateHwndNoErr((HWND)dwValue)) 1755470aa276SKatayama Hirofumi MZ return FALSE; // Invalid HWND 1756470aa276SKatayama Hirofumi MZ 1757470aa276SKatayama Hirofumi MZ pIMC->hImeWnd = (HWND)dwValue; 1758470aa276SKatayama Hirofumi MZ break; 1759470aa276SKatayama Hirofumi MZ 1760470aa276SKatayama Hirofumi MZ default: 1761470aa276SKatayama Hirofumi MZ return FALSE; 1762470aa276SKatayama Hirofumi MZ } 1763470aa276SKatayama Hirofumi MZ 1764470aa276SKatayama Hirofumi MZ return TRUE; 1765470aa276SKatayama Hirofumi MZ } 1766470aa276SKatayama Hirofumi MZ 1767470aa276SKatayama Hirofumi MZ BOOL 1768e52ce89bSKatayama Hirofumi MZ NTAPI 1769470aa276SKatayama Hirofumi MZ NtUserUpdateInputContext( 1770470aa276SKatayama Hirofumi MZ HIMC hIMC, 1771470aa276SKatayama Hirofumi MZ DWORD dwType, 1772470aa276SKatayama Hirofumi MZ DWORD_PTR dwValue) 1773470aa276SKatayama Hirofumi MZ { 1774470aa276SKatayama Hirofumi MZ PIMC pIMC; 1775470aa276SKatayama Hirofumi MZ BOOL ret = FALSE; 1776470aa276SKatayama Hirofumi MZ 1777470aa276SKatayama Hirofumi MZ UserEnterExclusive(); 1778470aa276SKatayama Hirofumi MZ 1779470aa276SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 1780b5c9d532SKatayama Hirofumi MZ { 1781b5c9d532SKatayama Hirofumi MZ ERR("!IS_IMM_MODE()\n"); 1782470aa276SKatayama Hirofumi MZ goto Quit; 1783b5c9d532SKatayama Hirofumi MZ } 1784470aa276SKatayama Hirofumi MZ 1785470aa276SKatayama Hirofumi MZ pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT); 1786470aa276SKatayama Hirofumi MZ if (!pIMC) 1787470aa276SKatayama Hirofumi MZ goto Quit; 1788470aa276SKatayama Hirofumi MZ 1789470aa276SKatayama Hirofumi MZ ret = UserUpdateInputContext(pIMC, dwType, dwValue); 1790470aa276SKatayama Hirofumi MZ 1791470aa276SKatayama Hirofumi MZ Quit: 1792470aa276SKatayama Hirofumi MZ UserLeave(); 1793470aa276SKatayama Hirofumi MZ return ret; 1794470aa276SKatayama Hirofumi MZ } 1795470aa276SKatayama Hirofumi MZ 1796470aa276SKatayama Hirofumi MZ DWORD_PTR 1797e52ce89bSKatayama Hirofumi MZ NTAPI 1798470aa276SKatayama Hirofumi MZ NtUserQueryInputContext(HIMC hIMC, DWORD dwType) 1799470aa276SKatayama Hirofumi MZ { 1800470aa276SKatayama Hirofumi MZ PIMC pIMC; 1801470aa276SKatayama Hirofumi MZ PTHREADINFO ptiIMC; 1802470aa276SKatayama Hirofumi MZ DWORD_PTR ret = 0; 1803470aa276SKatayama Hirofumi MZ 1804470aa276SKatayama Hirofumi MZ UserEnterExclusive(); 1805470aa276SKatayama Hirofumi MZ 1806470aa276SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 1807b5c9d532SKatayama Hirofumi MZ { 1808b5c9d532SKatayama Hirofumi MZ ERR("!IS_IMM_MODE()\n"); 1809470aa276SKatayama Hirofumi MZ goto Quit; 1810b5c9d532SKatayama Hirofumi MZ } 1811470aa276SKatayama Hirofumi MZ 1812470aa276SKatayama Hirofumi MZ pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT); 1813470aa276SKatayama Hirofumi MZ if (!pIMC) 1814470aa276SKatayama Hirofumi MZ goto Quit; 1815470aa276SKatayama Hirofumi MZ 1816470aa276SKatayama Hirofumi MZ ptiIMC = pIMC->head.pti; 1817470aa276SKatayama Hirofumi MZ 1818470aa276SKatayama Hirofumi MZ switch (dwType) 1819470aa276SKatayama Hirofumi MZ { 1820470aa276SKatayama Hirofumi MZ case QIC_INPUTPROCESSID: 1821470aa276SKatayama Hirofumi MZ ret = (DWORD_PTR)PsGetThreadProcessId(ptiIMC->pEThread); 1822470aa276SKatayama Hirofumi MZ break; 1823470aa276SKatayama Hirofumi MZ 1824470aa276SKatayama Hirofumi MZ case QIC_INPUTTHREADID: 1825470aa276SKatayama Hirofumi MZ ret = (DWORD_PTR)PsGetThreadId(ptiIMC->pEThread); 1826470aa276SKatayama Hirofumi MZ break; 1827470aa276SKatayama Hirofumi MZ 1828470aa276SKatayama Hirofumi MZ case QIC_DEFAULTWINDOWIME: 1829470aa276SKatayama Hirofumi MZ if (ptiIMC->spwndDefaultIme) 1830470aa276SKatayama Hirofumi MZ ret = (DWORD_PTR)UserHMGetHandle(ptiIMC->spwndDefaultIme); 1831470aa276SKatayama Hirofumi MZ break; 1832470aa276SKatayama Hirofumi MZ 1833470aa276SKatayama Hirofumi MZ case QIC_DEFAULTIMC: 1834470aa276SKatayama Hirofumi MZ if (ptiIMC->spDefaultImc) 1835470aa276SKatayama Hirofumi MZ ret = (DWORD_PTR)UserHMGetHandle(ptiIMC->spDefaultImc); 1836470aa276SKatayama Hirofumi MZ break; 1837470aa276SKatayama Hirofumi MZ } 1838470aa276SKatayama Hirofumi MZ 1839470aa276SKatayama Hirofumi MZ Quit: 1840470aa276SKatayama Hirofumi MZ UserLeave(); 1841470aa276SKatayama Hirofumi MZ return ret; 1842470aa276SKatayama Hirofumi MZ } 1843470aa276SKatayama Hirofumi MZ 18444bcf23d1SKatayama Hirofumi MZ // Searchs a non-IME-related window of the same thread of pwndTarget, 18454bcf23d1SKatayama Hirofumi MZ // other than pwndTarget, around pwndParent. Returns TRUE if found. 18464bcf23d1SKatayama Hirofumi MZ // 18474bcf23d1SKatayama Hirofumi MZ // Win: IsChildSameThread 18484bcf23d1SKatayama Hirofumi MZ BOOL IntFindNonImeRelatedWndOfSameThread(PWND pwndParent, PWND pwndTarget) 18494bcf23d1SKatayama Hirofumi MZ { 18504bcf23d1SKatayama Hirofumi MZ PWND pwnd, pwndOwner, pwndNode; 18514bcf23d1SKatayama Hirofumi MZ PTHREADINFO ptiTarget = pwndTarget->head.pti; 18524bcf23d1SKatayama Hirofumi MZ 18534bcf23d1SKatayama Hirofumi MZ // For all the children of pwndParent, ... 18544bcf23d1SKatayama Hirofumi MZ for (pwnd = pwndParent->spwndChild; pwnd; pwnd = pwnd->spwndNext) 18554bcf23d1SKatayama Hirofumi MZ { 18564bcf23d1SKatayama Hirofumi MZ if (pwnd == pwndTarget || pwnd->head.pti != ptiTarget || IS_WND_MENU(pwnd)) 18574bcf23d1SKatayama Hirofumi MZ continue; 18584bcf23d1SKatayama Hirofumi MZ 18594bcf23d1SKatayama Hirofumi MZ if (!IS_WND_CHILD(pwnd)) 18604bcf23d1SKatayama Hirofumi MZ { 18614bcf23d1SKatayama Hirofumi MZ // Check if any IME-like owner. 18624bcf23d1SKatayama Hirofumi MZ BOOL bFound1 = FALSE; 18634bcf23d1SKatayama Hirofumi MZ for (pwndOwner = pwnd; pwndOwner; pwndOwner = pwndOwner->spwndOwner) 18644bcf23d1SKatayama Hirofumi MZ { 18654bcf23d1SKatayama Hirofumi MZ if (IS_WND_IMELIKE(pwndOwner)) 18664bcf23d1SKatayama Hirofumi MZ { 18674bcf23d1SKatayama Hirofumi MZ bFound1 = TRUE; 18684bcf23d1SKatayama Hirofumi MZ break; 18694bcf23d1SKatayama Hirofumi MZ } 18704bcf23d1SKatayama Hirofumi MZ } 18714bcf23d1SKatayama Hirofumi MZ if (bFound1) 18724bcf23d1SKatayama Hirofumi MZ continue; // Skip if any IME-like owner. 18734bcf23d1SKatayama Hirofumi MZ } 18744bcf23d1SKatayama Hirofumi MZ 18754bcf23d1SKatayama Hirofumi MZ pwndNode = pwnd; 18764bcf23d1SKatayama Hirofumi MZ 18774bcf23d1SKatayama Hirofumi MZ if (IS_WND_CHILD(pwndNode)) 18784bcf23d1SKatayama Hirofumi MZ { 18794bcf23d1SKatayama Hirofumi MZ // Check if any same-thread IME-like ancestor. 18804bcf23d1SKatayama Hirofumi MZ BOOL bFound2 = FALSE; 18814bcf23d1SKatayama Hirofumi MZ for (; IS_WND_CHILD(pwndNode); pwndNode = pwndNode->spwndParent) 18824bcf23d1SKatayama Hirofumi MZ { 18834bcf23d1SKatayama Hirofumi MZ if (pwndNode->head.pti != ptiTarget) 18844bcf23d1SKatayama Hirofumi MZ break; 18854bcf23d1SKatayama Hirofumi MZ 18864bcf23d1SKatayama Hirofumi MZ if (IS_WND_IMELIKE(pwndNode)) 18874bcf23d1SKatayama Hirofumi MZ { 18884bcf23d1SKatayama Hirofumi MZ bFound2 = TRUE; 18894bcf23d1SKatayama Hirofumi MZ break; 18904bcf23d1SKatayama Hirofumi MZ } 18914bcf23d1SKatayama Hirofumi MZ } 18924bcf23d1SKatayama Hirofumi MZ if (bFound2) 18934bcf23d1SKatayama Hirofumi MZ continue; 18944bcf23d1SKatayama Hirofumi MZ // Now, pwndNode is non-child or non-same-thread window. 18954bcf23d1SKatayama Hirofumi MZ } 18964bcf23d1SKatayama Hirofumi MZ 18974bcf23d1SKatayama Hirofumi MZ if (!IS_WND_CHILD(pwndNode)) // pwndNode is non-child 18984bcf23d1SKatayama Hirofumi MZ { 18994bcf23d1SKatayama Hirofumi MZ // Check if any same-thread IME-like owner. 19004bcf23d1SKatayama Hirofumi MZ BOOL bFound3 = FALSE; 19014bcf23d1SKatayama Hirofumi MZ for (; pwndNode; pwndNode = pwndNode->spwndOwner) 19024bcf23d1SKatayama Hirofumi MZ { 19034bcf23d1SKatayama Hirofumi MZ if (pwndNode->head.pti != ptiTarget) 19044bcf23d1SKatayama Hirofumi MZ break; 19054bcf23d1SKatayama Hirofumi MZ 19064bcf23d1SKatayama Hirofumi MZ if (IS_WND_IMELIKE(pwndNode)) 19074bcf23d1SKatayama Hirofumi MZ { 19084bcf23d1SKatayama Hirofumi MZ bFound3 = TRUE; 19094bcf23d1SKatayama Hirofumi MZ break; 19104bcf23d1SKatayama Hirofumi MZ } 19114bcf23d1SKatayama Hirofumi MZ } 19124bcf23d1SKatayama Hirofumi MZ if (bFound3) 19134bcf23d1SKatayama Hirofumi MZ continue; 19144bcf23d1SKatayama Hirofumi MZ } 19154bcf23d1SKatayama Hirofumi MZ 19164bcf23d1SKatayama Hirofumi MZ return TRUE; 19174bcf23d1SKatayama Hirofumi MZ } 19184bcf23d1SKatayama Hirofumi MZ 19194bcf23d1SKatayama Hirofumi MZ return FALSE; 19204bcf23d1SKatayama Hirofumi MZ } 19214bcf23d1SKatayama Hirofumi MZ 19228f719cb9SKatayama Hirofumi MZ // Determines whether the target window needs the IME window. 19238f719cb9SKatayama Hirofumi MZ // Win: WantImeWindow(pwndParent, pwndTarget) 19248f719cb9SKatayama Hirofumi MZ BOOL FASTCALL IntWantImeWindow(PWND pwndTarget) 19258f719cb9SKatayama Hirofumi MZ { 19268f719cb9SKatayama Hirofumi MZ PDESKTOP rpdesk; 19278f719cb9SKatayama Hirofumi MZ PWINSTATION_OBJECT rpwinstaParent; 19288f719cb9SKatayama Hirofumi MZ PWND pwndNode, pwndParent = pwndTarget->spwndParent; 19298f719cb9SKatayama Hirofumi MZ 19308f719cb9SKatayama Hirofumi MZ if (gptiCurrent->TIF_flags & TIF_DISABLEIME) 19318f719cb9SKatayama Hirofumi MZ return FALSE; 19328f719cb9SKatayama Hirofumi MZ 19338f719cb9SKatayama Hirofumi MZ if (IS_WND_IMELIKE(pwndTarget)) 19348f719cb9SKatayama Hirofumi MZ return FALSE; 19358f719cb9SKatayama Hirofumi MZ 19368f719cb9SKatayama Hirofumi MZ if (pwndTarget->fnid == FNID_DESKTOP || pwndTarget->fnid == FNID_MESSAGEWND) 19378f719cb9SKatayama Hirofumi MZ return FALSE; 19388f719cb9SKatayama Hirofumi MZ 19398f719cb9SKatayama Hirofumi MZ if (pwndTarget->state & WNDS_SERVERSIDEWINDOWPROC) 19408f719cb9SKatayama Hirofumi MZ return FALSE; 19418f719cb9SKatayama Hirofumi MZ 19428f719cb9SKatayama Hirofumi MZ rpdesk = pwndTarget->head.rpdesk; 19438f719cb9SKatayama Hirofumi MZ if (!rpdesk) 19448f719cb9SKatayama Hirofumi MZ return FALSE; 19458f719cb9SKatayama Hirofumi MZ 19468f719cb9SKatayama Hirofumi MZ rpwinstaParent = rpdesk->rpwinstaParent; 19478f719cb9SKatayama Hirofumi MZ if (!rpwinstaParent || (rpwinstaParent->Flags & WSS_NOIO)) 19488f719cb9SKatayama Hirofumi MZ return FALSE; 19498f719cb9SKatayama Hirofumi MZ 19508f719cb9SKatayama Hirofumi MZ for (pwndNode = pwndParent; pwndNode; pwndNode = pwndNode->spwndParent) 19518f719cb9SKatayama Hirofumi MZ { 19528f719cb9SKatayama Hirofumi MZ if (rpdesk != pwndNode->head.rpdesk) 19538f719cb9SKatayama Hirofumi MZ break; 19548f719cb9SKatayama Hirofumi MZ 19558f719cb9SKatayama Hirofumi MZ if (pwndNode == rpdesk->spwndMessage) 19568f719cb9SKatayama Hirofumi MZ return FALSE; 19578f719cb9SKatayama Hirofumi MZ } 19588f719cb9SKatayama Hirofumi MZ 19598f719cb9SKatayama Hirofumi MZ return TRUE; 19608f719cb9SKatayama Hirofumi MZ } 19618f719cb9SKatayama Hirofumi MZ 19628f719cb9SKatayama Hirofumi MZ // Create the default IME window for the target window. 19638f719cb9SKatayama Hirofumi MZ // Win: xxxCreateDefaultImeWindow(pwndTarget, ATOM, hInst) 19648f719cb9SKatayama Hirofumi MZ PWND FASTCALL co_IntCreateDefaultImeWindow(PWND pwndTarget, HINSTANCE hInst) 19658f719cb9SKatayama Hirofumi MZ { 19668f719cb9SKatayama Hirofumi MZ LARGE_UNICODE_STRING WindowName; 19678f719cb9SKatayama Hirofumi MZ UNICODE_STRING ClassName; 19688f719cb9SKatayama Hirofumi MZ PWND pImeWnd; 19698f719cb9SKatayama Hirofumi MZ PIMEUI pimeui; 19708f719cb9SKatayama Hirofumi MZ CREATESTRUCTW Cs; 19718f719cb9SKatayama Hirofumi MZ USER_REFERENCE_ENTRY Ref; 19728f719cb9SKatayama Hirofumi MZ PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); 19738f719cb9SKatayama Hirofumi MZ HANDLE pid = PsGetThreadProcessId(pti->pEThread); 19748f719cb9SKatayama Hirofumi MZ 19758f719cb9SKatayama Hirofumi MZ if (!(pti->spDefaultImc) && pid == gpidLogon) 19768f719cb9SKatayama Hirofumi MZ UserCreateInputContext(0); 19778f719cb9SKatayama Hirofumi MZ 19788f719cb9SKatayama Hirofumi MZ if (!(pti->spDefaultImc) || IS_WND_IMELIKE(pwndTarget) || !(pti->rpdesk->pheapDesktop)) 19798f719cb9SKatayama Hirofumi MZ return NULL; 19808f719cb9SKatayama Hirofumi MZ 19818f719cb9SKatayama Hirofumi MZ if (IS_WND_CHILD(pwndTarget) && !(pwndTarget->style & WS_VISIBLE) && 19828f719cb9SKatayama Hirofumi MZ pwndTarget->spwndParent->head.pti->ppi != pti->ppi) 19838f719cb9SKatayama Hirofumi MZ { 19848f719cb9SKatayama Hirofumi MZ return NULL; 19858f719cb9SKatayama Hirofumi MZ } 19868f719cb9SKatayama Hirofumi MZ 19878f719cb9SKatayama Hirofumi MZ RtlInitLargeUnicodeString(&WindowName, L"Default IME", 0); 19888f719cb9SKatayama Hirofumi MZ 19898f719cb9SKatayama Hirofumi MZ ClassName.Buffer = (PWCH)(ULONG_PTR)gpsi->atomSysClass[ICLS_IME]; 19908f719cb9SKatayama Hirofumi MZ ClassName.Length = 0; 19918f719cb9SKatayama Hirofumi MZ ClassName.MaximumLength = 0; 19928f719cb9SKatayama Hirofumi MZ 19938f719cb9SKatayama Hirofumi MZ UserRefObjectCo(pwndTarget, &Ref); 19948f719cb9SKatayama Hirofumi MZ 19958f719cb9SKatayama Hirofumi MZ RtlZeroMemory(&Cs, sizeof(Cs)); 19968f719cb9SKatayama Hirofumi MZ Cs.style = WS_POPUP | WS_DISABLED; 19978f719cb9SKatayama Hirofumi MZ Cs.hInstance = hInst; 19988f719cb9SKatayama Hirofumi MZ Cs.hwndParent = UserHMGetHandle(pwndTarget); 19998f719cb9SKatayama Hirofumi MZ Cs.lpszName = WindowName.Buffer; 20008f719cb9SKatayama Hirofumi MZ Cs.lpszClass = ClassName.Buffer; 20018f719cb9SKatayama Hirofumi MZ 20028f719cb9SKatayama Hirofumi MZ // NOTE: LARGE_UNICODE_STRING is compatible to LARGE_STRING. 20038f719cb9SKatayama Hirofumi MZ pImeWnd = co_UserCreateWindowEx(&Cs, &ClassName, (PLARGE_STRING)&WindowName, NULL, WINVER); 20048f719cb9SKatayama Hirofumi MZ if (pImeWnd) 20058f719cb9SKatayama Hirofumi MZ { 20068f719cb9SKatayama Hirofumi MZ pimeui = ((PIMEWND)pImeWnd)->pimeui; 20078f719cb9SKatayama Hirofumi MZ _SEH2_TRY 20088f719cb9SKatayama Hirofumi MZ { 20098f719cb9SKatayama Hirofumi MZ ProbeForWrite(pimeui, sizeof(IMEUI), 1); 20108f719cb9SKatayama Hirofumi MZ pimeui->fDefault = TRUE; 20118f719cb9SKatayama Hirofumi MZ if (IS_WND_CHILD(pwndTarget) && pwndTarget->spwndParent->head.pti != pti) 20128f719cb9SKatayama Hirofumi MZ pimeui->fChildThreadDef = TRUE; 20138f719cb9SKatayama Hirofumi MZ } 20148f719cb9SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 20158f719cb9SKatayama Hirofumi MZ { 20168f719cb9SKatayama Hirofumi MZ NOTHING; 20178f719cb9SKatayama Hirofumi MZ } 20188f719cb9SKatayama Hirofumi MZ _SEH2_END; 20198f719cb9SKatayama Hirofumi MZ } 20208f719cb9SKatayama Hirofumi MZ 20218f719cb9SKatayama Hirofumi MZ UserDerefObjectCo(pwndTarget); 20228f719cb9SKatayama Hirofumi MZ return pImeWnd; 20238f719cb9SKatayama Hirofumi MZ } 20248f719cb9SKatayama Hirofumi MZ 20258f719cb9SKatayama Hirofumi MZ // Determines whether the system can destroy the default IME window for the target child window. 20264bcf23d1SKatayama Hirofumi MZ // Win: ImeCanDestroyDefIMEforChild 20274bcf23d1SKatayama Hirofumi MZ BOOL FASTCALL IntImeCanDestroyDefIMEforChild(PWND pImeWnd, PWND pwndTarget) 20284bcf23d1SKatayama Hirofumi MZ { 20294bcf23d1SKatayama Hirofumi MZ PWND pwndNode; 20304bcf23d1SKatayama Hirofumi MZ PIMEUI pimeui; 20314bcf23d1SKatayama Hirofumi MZ IMEUI SafeImeUI; 20324bcf23d1SKatayama Hirofumi MZ 20334bcf23d1SKatayama Hirofumi MZ pimeui = ((PIMEWND)pImeWnd)->pimeui; 20344bcf23d1SKatayama Hirofumi MZ if (!pimeui || (LONG_PTR)pimeui == (LONG_PTR)-1) 20354bcf23d1SKatayama Hirofumi MZ return FALSE; 20364bcf23d1SKatayama Hirofumi MZ 20374bcf23d1SKatayama Hirofumi MZ // Check IMEUI.fChildThreadDef 20384bcf23d1SKatayama Hirofumi MZ _SEH2_TRY 20394bcf23d1SKatayama Hirofumi MZ { 20404bcf23d1SKatayama Hirofumi MZ ProbeForRead(pimeui, sizeof(IMEUI), 1); 20414bcf23d1SKatayama Hirofumi MZ SafeImeUI = *pimeui; 20424bcf23d1SKatayama Hirofumi MZ if (!SafeImeUI.fChildThreadDef) 20434bcf23d1SKatayama Hirofumi MZ return FALSE; 20444bcf23d1SKatayama Hirofumi MZ } 20454bcf23d1SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 20464bcf23d1SKatayama Hirofumi MZ { 20478f719cb9SKatayama Hirofumi MZ NOTHING; 20484bcf23d1SKatayama Hirofumi MZ } 20494bcf23d1SKatayama Hirofumi MZ _SEH2_END; 20504bcf23d1SKatayama Hirofumi MZ 20514bcf23d1SKatayama Hirofumi MZ // The parent of pwndTarget is NULL or of the same thread of pwndTarget? 20524bcf23d1SKatayama Hirofumi MZ if (pwndTarget->spwndParent == NULL || 20534bcf23d1SKatayama Hirofumi MZ pwndTarget->head.pti == pwndTarget->spwndParent->head.pti) 20544bcf23d1SKatayama Hirofumi MZ { 20554bcf23d1SKatayama Hirofumi MZ return FALSE; 20564bcf23d1SKatayama Hirofumi MZ } 20574bcf23d1SKatayama Hirofumi MZ 20584bcf23d1SKatayama Hirofumi MZ for (pwndNode = pwndTarget; pwndNode; pwndNode = pwndNode->spwndParent) 20594bcf23d1SKatayama Hirofumi MZ { 20604bcf23d1SKatayama Hirofumi MZ if (pwndNode == pwndNode->head.rpdesk->pDeskInfo->spwnd) 20614bcf23d1SKatayama Hirofumi MZ break; 20624bcf23d1SKatayama Hirofumi MZ 20634bcf23d1SKatayama Hirofumi MZ if (IntFindNonImeRelatedWndOfSameThread(pwndNode->spwndParent, pwndTarget)) 20644bcf23d1SKatayama Hirofumi MZ return FALSE; 20654bcf23d1SKatayama Hirofumi MZ } 20664bcf23d1SKatayama Hirofumi MZ 20674bcf23d1SKatayama Hirofumi MZ return TRUE; 20684bcf23d1SKatayama Hirofumi MZ } 20694bcf23d1SKatayama Hirofumi MZ 20708f719cb9SKatayama Hirofumi MZ // Determines whether the system can destroy the default IME window for the non-child target window. 20714bcf23d1SKatayama Hirofumi MZ // Win: ImeCanDestroyDefIME 20724bcf23d1SKatayama Hirofumi MZ BOOL FASTCALL IntImeCanDestroyDefIME(PWND pImeWnd, PWND pwndTarget) 20734bcf23d1SKatayama Hirofumi MZ { 20744bcf23d1SKatayama Hirofumi MZ PWND pwndNode; 20754bcf23d1SKatayama Hirofumi MZ PIMEUI pimeui; 20764bcf23d1SKatayama Hirofumi MZ IMEUI SafeImeUI; 20774bcf23d1SKatayama Hirofumi MZ 20784bcf23d1SKatayama Hirofumi MZ pimeui = ((PIMEWND)pImeWnd)->pimeui; 20794bcf23d1SKatayama Hirofumi MZ if (!pimeui || (LONG_PTR)pimeui == (LONG_PTR)-1) 20804bcf23d1SKatayama Hirofumi MZ return FALSE; 20814bcf23d1SKatayama Hirofumi MZ 20824bcf23d1SKatayama Hirofumi MZ // Check IMEUI.fDestroy 20834bcf23d1SKatayama Hirofumi MZ _SEH2_TRY 20844bcf23d1SKatayama Hirofumi MZ { 20854bcf23d1SKatayama Hirofumi MZ ProbeForRead(pimeui, sizeof(IMEUI), 1); 20864bcf23d1SKatayama Hirofumi MZ SafeImeUI = *pimeui; 20874bcf23d1SKatayama Hirofumi MZ if (SafeImeUI.fDestroy) 20884bcf23d1SKatayama Hirofumi MZ return FALSE; 20894bcf23d1SKatayama Hirofumi MZ } 20904bcf23d1SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 20914bcf23d1SKatayama Hirofumi MZ { 20928f719cb9SKatayama Hirofumi MZ NOTHING; 20934bcf23d1SKatayama Hirofumi MZ } 20944bcf23d1SKatayama Hirofumi MZ _SEH2_END; 20954bcf23d1SKatayama Hirofumi MZ 20964bcf23d1SKatayama Hirofumi MZ // Any ancestor of pImeWnd is pwndTarget? 20974bcf23d1SKatayama Hirofumi MZ if (pImeWnd->spwndOwner) 20984bcf23d1SKatayama Hirofumi MZ { 20994bcf23d1SKatayama Hirofumi MZ for (pwndNode = pImeWnd->spwndOwner; pwndNode; pwndNode = pwndNode->spwndOwner) 21004bcf23d1SKatayama Hirofumi MZ { 21014bcf23d1SKatayama Hirofumi MZ if (pwndNode == pwndTarget) 21024bcf23d1SKatayama Hirofumi MZ break; 21034bcf23d1SKatayama Hirofumi MZ } 21044bcf23d1SKatayama Hirofumi MZ 21054bcf23d1SKatayama Hirofumi MZ if (!pwndNode) 21064bcf23d1SKatayama Hirofumi MZ return FALSE; 21074bcf23d1SKatayama Hirofumi MZ } 21084bcf23d1SKatayama Hirofumi MZ 21094bcf23d1SKatayama Hirofumi MZ // Any ancestor of pwndTarget is IME-like? 21104bcf23d1SKatayama Hirofumi MZ for (pwndNode = pwndTarget; pwndNode; pwndNode = pwndNode->spwndOwner) 21114bcf23d1SKatayama Hirofumi MZ { 21124bcf23d1SKatayama Hirofumi MZ if (IS_WND_IMELIKE(pwndNode)) 21134bcf23d1SKatayama Hirofumi MZ return FALSE; 21144bcf23d1SKatayama Hirofumi MZ } 21154bcf23d1SKatayama Hirofumi MZ 21164bcf23d1SKatayama Hirofumi MZ // Adjust the ordering and top-mode status 21174bcf23d1SKatayama Hirofumi MZ IntImeSetFutureOwner(pImeWnd, pwndTarget); 21184bcf23d1SKatayama Hirofumi MZ for (pwndNode = pImeWnd->spwndOwner; pwndNode; pwndNode = pwndNode->spwndNext) 21194bcf23d1SKatayama Hirofumi MZ { 21204bcf23d1SKatayama Hirofumi MZ if (pwndNode == pImeWnd) 21214bcf23d1SKatayama Hirofumi MZ break; 21224bcf23d1SKatayama Hirofumi MZ } 21234bcf23d1SKatayama Hirofumi MZ if (pwndNode == pImeWnd) 21244bcf23d1SKatayama Hirofumi MZ IntImeCheckTopmost(pImeWnd); 21254bcf23d1SKatayama Hirofumi MZ 21264bcf23d1SKatayama Hirofumi MZ // Is the owner of pImeWnd NULL or pwndTarget? 21274bcf23d1SKatayama Hirofumi MZ if (pImeWnd->spwndOwner && pwndTarget != pImeWnd->spwndOwner) 21284bcf23d1SKatayama Hirofumi MZ return FALSE; 21294bcf23d1SKatayama Hirofumi MZ 2130*e56da485STimo Kreuzer WndSetOwner(pImeWnd, NULL); 21314bcf23d1SKatayama Hirofumi MZ return TRUE; 21324bcf23d1SKatayama Hirofumi MZ } 21334bcf23d1SKatayama Hirofumi MZ 2134242e0b43SKatayama Hirofumi MZ // Update IMEUI.fShowStatus flags and Send the WM_IME_NOTIFY messages. 2135242e0b43SKatayama Hirofumi MZ // Win: xxxCheckImeShowStatus 2136242e0b43SKatayama Hirofumi MZ BOOL FASTCALL IntCheckImeShowStatus(PWND pwndIme, PTHREADINFO pti) 2137242e0b43SKatayama Hirofumi MZ { 2138242e0b43SKatayama Hirofumi MZ BOOL ret = FALSE, bDifferent; 2139242e0b43SKatayama Hirofumi MZ PWINDOWLIST pwl; 2140242e0b43SKatayama Hirofumi MZ HWND *phwnd; 2141242e0b43SKatayama Hirofumi MZ PWND pwndNode, pwndIMC; 2142242e0b43SKatayama Hirofumi MZ PTHREADINFO ptiCurrent = GetW32ThreadInfo(); 2143242e0b43SKatayama Hirofumi MZ PIMEUI pimeui; 2144242e0b43SKatayama Hirofumi MZ IMEUI SafeImeUI; 2145242e0b43SKatayama Hirofumi MZ 2146242e0b43SKatayama Hirofumi MZ if (pwndIme->state2 & WNDS2_INDESTROY) 2147242e0b43SKatayama Hirofumi MZ return FALSE; 2148242e0b43SKatayama Hirofumi MZ 2149242e0b43SKatayama Hirofumi MZ // Build a window list 2150242e0b43SKatayama Hirofumi MZ pwl = IntBuildHwndList(pwndIme->spwndParent->spwndChild, IACE_LIST, NULL); 2151242e0b43SKatayama Hirofumi MZ if (!pwl) 2152242e0b43SKatayama Hirofumi MZ return FALSE; 2153242e0b43SKatayama Hirofumi MZ 2154242e0b43SKatayama Hirofumi MZ ret = TRUE; 2155242e0b43SKatayama Hirofumi MZ for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd) 2156242e0b43SKatayama Hirofumi MZ { 2157242e0b43SKatayama Hirofumi MZ pwndNode = ValidateHwndNoErr(*phwnd); 2158242e0b43SKatayama Hirofumi MZ 2159242e0b43SKatayama Hirofumi MZ if (!pwndNode || pwndIme == pwndNode) 2160242e0b43SKatayama Hirofumi MZ continue; 2161242e0b43SKatayama Hirofumi MZ 2162242e0b43SKatayama Hirofumi MZ if (pwndNode->pcls->atomClassName != gpsi->atomSysClass[ICLS_IME] || 2163242e0b43SKatayama Hirofumi MZ (pwndNode->state2 & WNDS2_INDESTROY)) 2164242e0b43SKatayama Hirofumi MZ { 2165242e0b43SKatayama Hirofumi MZ continue; 2166242e0b43SKatayama Hirofumi MZ } 2167242e0b43SKatayama Hirofumi MZ 2168242e0b43SKatayama Hirofumi MZ pimeui = ((PIMEWND)pwndNode)->pimeui; 2169242e0b43SKatayama Hirofumi MZ if (!pimeui || pimeui == (PIMEUI)-1) 2170242e0b43SKatayama Hirofumi MZ continue; 2171242e0b43SKatayama Hirofumi MZ 2172242e0b43SKatayama Hirofumi MZ if (pti && pti != pwndNode->head.pti) 2173242e0b43SKatayama Hirofumi MZ continue; 2174242e0b43SKatayama Hirofumi MZ 2175242e0b43SKatayama Hirofumi MZ // Attach to the process if necessary 2176242e0b43SKatayama Hirofumi MZ bDifferent = FALSE; 2177242e0b43SKatayama Hirofumi MZ if (pwndNode->head.pti->ppi != ptiCurrent->ppi) 2178242e0b43SKatayama Hirofumi MZ { 2179242e0b43SKatayama Hirofumi MZ KeAttachProcess(&(pwndNode->head.pti->ppi->peProcess->Pcb)); 2180242e0b43SKatayama Hirofumi MZ bDifferent = TRUE; 2181242e0b43SKatayama Hirofumi MZ } 2182242e0b43SKatayama Hirofumi MZ 2183242e0b43SKatayama Hirofumi MZ // Get pwndIMC and update IMEUI.fShowStatus flag 2184242e0b43SKatayama Hirofumi MZ _SEH2_TRY 2185242e0b43SKatayama Hirofumi MZ { 2186242e0b43SKatayama Hirofumi MZ ProbeForWrite(pimeui, sizeof(IMEUI), 1); 2187242e0b43SKatayama Hirofumi MZ SafeImeUI = *pimeui; 2188242e0b43SKatayama Hirofumi MZ if (SafeImeUI.fShowStatus) 2189242e0b43SKatayama Hirofumi MZ { 2190242e0b43SKatayama Hirofumi MZ pwndIMC = ValidateHwndNoErr(pimeui->hwndIMC); 2191242e0b43SKatayama Hirofumi MZ if (pwndIMC) 2192242e0b43SKatayama Hirofumi MZ pimeui->fShowStatus = FALSE; 2193242e0b43SKatayama Hirofumi MZ } 2194242e0b43SKatayama Hirofumi MZ else 2195242e0b43SKatayama Hirofumi MZ { 2196242e0b43SKatayama Hirofumi MZ pwndIMC = NULL; 2197242e0b43SKatayama Hirofumi MZ } 2198242e0b43SKatayama Hirofumi MZ } 2199242e0b43SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2200242e0b43SKatayama Hirofumi MZ { 2201242e0b43SKatayama Hirofumi MZ pwndIMC = NULL; 2202242e0b43SKatayama Hirofumi MZ } 2203242e0b43SKatayama Hirofumi MZ _SEH2_END; 2204242e0b43SKatayama Hirofumi MZ 2205242e0b43SKatayama Hirofumi MZ // Detach from the process if necessary 2206242e0b43SKatayama Hirofumi MZ if (bDifferent) 2207242e0b43SKatayama Hirofumi MZ KeDetachProcess(); 2208242e0b43SKatayama Hirofumi MZ 2209242e0b43SKatayama Hirofumi MZ // Send the WM_IME_NOTIFY message 2210242e0b43SKatayama Hirofumi MZ if (pwndIMC && pwndIMC->head.pti && !(pwndIMC->head.pti->TIF_flags & TIF_INCLEANUP)) 2211242e0b43SKatayama Hirofumi MZ { 2212242e0b43SKatayama Hirofumi MZ HWND hImeWnd; 2213242e0b43SKatayama Hirofumi MZ USER_REFERENCE_ENTRY Ref; 2214242e0b43SKatayama Hirofumi MZ 2215242e0b43SKatayama Hirofumi MZ UserRefObjectCo(pwndIMC, &Ref); 2216242e0b43SKatayama Hirofumi MZ 2217242e0b43SKatayama Hirofumi MZ hImeWnd = UserHMGetHandle(pwndIMC); 2218242e0b43SKatayama Hirofumi MZ co_IntSendMessage(hImeWnd, WM_IME_NOTIFY, IMN_CLOSESTATUSWINDOW, 0); 2219242e0b43SKatayama Hirofumi MZ 2220242e0b43SKatayama Hirofumi MZ UserDerefObjectCo(pwndIMC); 2221242e0b43SKatayama Hirofumi MZ } 2222242e0b43SKatayama Hirofumi MZ } 2223242e0b43SKatayama Hirofumi MZ 2224242e0b43SKatayama Hirofumi MZ // Free the window list 2225242e0b43SKatayama Hirofumi MZ IntFreeHwndList(pwl); 2226242e0b43SKatayama Hirofumi MZ return ret; 2227242e0b43SKatayama Hirofumi MZ } 2228242e0b43SKatayama Hirofumi MZ 2229242e0b43SKatayama Hirofumi MZ // Send a UI message. 2230242e0b43SKatayama Hirofumi MZ // Win: xxxSendMessageToUI 2231242e0b43SKatayama Hirofumi MZ LRESULT FASTCALL 2232242e0b43SKatayama Hirofumi MZ IntSendMessageToUI(PTHREADINFO ptiIME, PIMEUI pimeui, UINT uMsg, WPARAM wParam, LPARAM lParam) 2233242e0b43SKatayama Hirofumi MZ { 2234242e0b43SKatayama Hirofumi MZ PWND pwndUI; 2235242e0b43SKatayama Hirofumi MZ LRESULT ret = 0; 2236242e0b43SKatayama Hirofumi MZ IMEUI SafeImeUI; 2237242e0b43SKatayama Hirofumi MZ BOOL bDifferent = FALSE; 2238242e0b43SKatayama Hirofumi MZ USER_REFERENCE_ENTRY Ref; 2239242e0b43SKatayama Hirofumi MZ 2240242e0b43SKatayama Hirofumi MZ // Attach to the process if necessary 2241242e0b43SKatayama Hirofumi MZ if (ptiIME != GetW32ThreadInfo()) 2242242e0b43SKatayama Hirofumi MZ { 2243242e0b43SKatayama Hirofumi MZ bDifferent = TRUE; 2244242e0b43SKatayama Hirofumi MZ KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb)); 2245242e0b43SKatayama Hirofumi MZ } 2246242e0b43SKatayama Hirofumi MZ 2247242e0b43SKatayama Hirofumi MZ // Get the pwndUI 2248242e0b43SKatayama Hirofumi MZ _SEH2_TRY 2249242e0b43SKatayama Hirofumi MZ { 2250242e0b43SKatayama Hirofumi MZ ProbeForRead(pimeui, sizeof(IMEUI), 1); 2251242e0b43SKatayama Hirofumi MZ SafeImeUI = *pimeui; 2252242e0b43SKatayama Hirofumi MZ pwndUI = ValidateHwndNoErr(SafeImeUI.hwndUI); 2253242e0b43SKatayama Hirofumi MZ } 2254242e0b43SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2255242e0b43SKatayama Hirofumi MZ { 2256242e0b43SKatayama Hirofumi MZ pwndUI = NULL; 2257242e0b43SKatayama Hirofumi MZ } 2258242e0b43SKatayama Hirofumi MZ _SEH2_END; 2259242e0b43SKatayama Hirofumi MZ 2260242e0b43SKatayama Hirofumi MZ if (!pwndUI) 2261242e0b43SKatayama Hirofumi MZ goto Quit; 2262242e0b43SKatayama Hirofumi MZ 2263242e0b43SKatayama Hirofumi MZ // Increment the recursion count of the IME procedure. 2264242e0b43SKatayama Hirofumi MZ // See also ImeWndProc_common of user32. 2265242e0b43SKatayama Hirofumi MZ _SEH2_TRY 2266242e0b43SKatayama Hirofumi MZ { 2267242e0b43SKatayama Hirofumi MZ ProbeForWrite(&pimeui->nCntInIMEProc, sizeof(LONG), 1); 2268242e0b43SKatayama Hirofumi MZ InterlockedIncrement(&pimeui->nCntInIMEProc); 2269242e0b43SKatayama Hirofumi MZ } 2270242e0b43SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2271242e0b43SKatayama Hirofumi MZ { 2272242e0b43SKatayama Hirofumi MZ goto Quit; 2273242e0b43SKatayama Hirofumi MZ } 2274242e0b43SKatayama Hirofumi MZ _SEH2_END; 2275242e0b43SKatayama Hirofumi MZ 2276242e0b43SKatayama Hirofumi MZ // Detach from the process if necessary 2277242e0b43SKatayama Hirofumi MZ if (bDifferent) 2278242e0b43SKatayama Hirofumi MZ KeDetachProcess(); 2279242e0b43SKatayama Hirofumi MZ 2280242e0b43SKatayama Hirofumi MZ UserRefObjectCo(pwndUI, &Ref); 2281242e0b43SKatayama Hirofumi MZ ret = co_IntSendMessage(UserHMGetHandle(pwndUI), uMsg, wParam, lParam); 2282242e0b43SKatayama Hirofumi MZ UserDerefObjectCo(pwndUI); 2283242e0b43SKatayama Hirofumi MZ 2284242e0b43SKatayama Hirofumi MZ // Attach to the process if necessary 2285242e0b43SKatayama Hirofumi MZ if (bDifferent) 2286242e0b43SKatayama Hirofumi MZ KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb)); 2287242e0b43SKatayama Hirofumi MZ 2288242e0b43SKatayama Hirofumi MZ // Decrement the recursion count of the IME procedure 2289242e0b43SKatayama Hirofumi MZ _SEH2_TRY 2290242e0b43SKatayama Hirofumi MZ { 2291242e0b43SKatayama Hirofumi MZ ProbeForWrite(&pimeui->nCntInIMEProc, sizeof(LONG), 1); 2292242e0b43SKatayama Hirofumi MZ InterlockedDecrement(&pimeui->nCntInIMEProc); 2293242e0b43SKatayama Hirofumi MZ } 2294242e0b43SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2295242e0b43SKatayama Hirofumi MZ { 2296242e0b43SKatayama Hirofumi MZ goto Quit; 2297242e0b43SKatayama Hirofumi MZ } 2298242e0b43SKatayama Hirofumi MZ _SEH2_END; 2299242e0b43SKatayama Hirofumi MZ 2300242e0b43SKatayama Hirofumi MZ Quit: 2301242e0b43SKatayama Hirofumi MZ // Detach from the process if necessary 2302242e0b43SKatayama Hirofumi MZ if (bDifferent) 2303242e0b43SKatayama Hirofumi MZ KeDetachProcess(); 2304242e0b43SKatayama Hirofumi MZ 2305242e0b43SKatayama Hirofumi MZ return ret; 2306242e0b43SKatayama Hirofumi MZ } 2307242e0b43SKatayama Hirofumi MZ 2308242e0b43SKatayama Hirofumi MZ // Send the open status notification. 2309242e0b43SKatayama Hirofumi MZ // Win: xxxSendOpenStatusNotify 2310242e0b43SKatayama Hirofumi MZ VOID FASTCALL 2311242e0b43SKatayama Hirofumi MZ IntSendOpenStatusNotify(PTHREADINFO ptiIME, PIMEUI pimeui, PWND pWnd, BOOL bOpen) 2312242e0b43SKatayama Hirofumi MZ { 2313242e0b43SKatayama Hirofumi MZ WPARAM wParam = (bOpen ? IMN_OPENSTATUSWINDOW : IMN_CLOSESTATUSWINDOW); 2314242e0b43SKatayama Hirofumi MZ PTHREADINFO ptiWnd = pWnd->head.pti; 2315242e0b43SKatayama Hirofumi MZ USER_REFERENCE_ENTRY Ref; 2316242e0b43SKatayama Hirofumi MZ 2317242e0b43SKatayama Hirofumi MZ if (ptiWnd->dwExpWinVer >= WINVER_WINNT4 && pWnd->hImc) 2318242e0b43SKatayama Hirofumi MZ { 2319242e0b43SKatayama Hirofumi MZ UserRefObjectCo(pWnd, &Ref); 2320242e0b43SKatayama Hirofumi MZ co_IntSendMessage(UserHMGetHandle(pWnd), WM_IME_NOTIFY, wParam, 0); 2321242e0b43SKatayama Hirofumi MZ UserDerefObjectCo(pWnd); 2322242e0b43SKatayama Hirofumi MZ } 2323242e0b43SKatayama Hirofumi MZ else 2324242e0b43SKatayama Hirofumi MZ { 2325242e0b43SKatayama Hirofumi MZ IntSendMessageToUI(ptiIME, pimeui, WM_IME_NOTIFY, wParam, 0); 2326242e0b43SKatayama Hirofumi MZ } 2327242e0b43SKatayama Hirofumi MZ } 2328242e0b43SKatayama Hirofumi MZ 2329242e0b43SKatayama Hirofumi MZ // Update the IME status and send a notification. 2330242e0b43SKatayama Hirofumi MZ // Win: xxxNotifyImeShowStatus 2331242e0b43SKatayama Hirofumi MZ VOID FASTCALL IntNotifyImeShowStatus(PWND pImeWnd) 2332242e0b43SKatayama Hirofumi MZ { 2333242e0b43SKatayama Hirofumi MZ PIMEUI pimeui; 2334242e0b43SKatayama Hirofumi MZ PWND pWnd; 2335242e0b43SKatayama Hirofumi MZ PTHREADINFO pti, ptiIME; 2336242e0b43SKatayama Hirofumi MZ BOOL bShow, bSendNotify = FALSE; 2337242e0b43SKatayama Hirofumi MZ IMEUI SafeImeUI; 2338242e0b43SKatayama Hirofumi MZ 2339242e0b43SKatayama Hirofumi MZ if (!IS_IMM_MODE() || (pImeWnd->state2 & WNDS2_INDESTROY)) 2340242e0b43SKatayama Hirofumi MZ return; 2341242e0b43SKatayama Hirofumi MZ 2342242e0b43SKatayama Hirofumi MZ pti = PsGetCurrentThreadWin32Thread(); 2343242e0b43SKatayama Hirofumi MZ ptiIME = pImeWnd->head.pti; 2344242e0b43SKatayama Hirofumi MZ 2345242e0b43SKatayama Hirofumi MZ // Attach to the process if necessary 2346242e0b43SKatayama Hirofumi MZ if (pti != ptiIME) 2347242e0b43SKatayama Hirofumi MZ KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb)); 2348242e0b43SKatayama Hirofumi MZ 2349242e0b43SKatayama Hirofumi MZ // Get an IMEUI and check whether hwndIMC is valid and update fShowStatus 2350242e0b43SKatayama Hirofumi MZ _SEH2_TRY 2351242e0b43SKatayama Hirofumi MZ { 2352242e0b43SKatayama Hirofumi MZ ProbeForWrite(pImeWnd, sizeof(IMEWND), 1); 2353242e0b43SKatayama Hirofumi MZ pimeui = ((PIMEWND)pImeWnd)->pimeui; 2354242e0b43SKatayama Hirofumi MZ SafeImeUI = *pimeui; 2355242e0b43SKatayama Hirofumi MZ 2356242e0b43SKatayama Hirofumi MZ bShow = (gfIMEShowStatus == TRUE) && SafeImeUI.fCtrlShowStatus; 2357242e0b43SKatayama Hirofumi MZ 2358242e0b43SKatayama Hirofumi MZ pWnd = ValidateHwndNoErr(SafeImeUI.hwndIMC); 2359242e0b43SKatayama Hirofumi MZ if (!pWnd) 2360242e0b43SKatayama Hirofumi MZ pWnd = ptiIME->MessageQueue->spwndFocus; 2361242e0b43SKatayama Hirofumi MZ 2362242e0b43SKatayama Hirofumi MZ if (pWnd) 2363242e0b43SKatayama Hirofumi MZ { 2364242e0b43SKatayama Hirofumi MZ bSendNotify = TRUE; 2365242e0b43SKatayama Hirofumi MZ pimeui->fShowStatus = bShow; 2366242e0b43SKatayama Hirofumi MZ } 2367242e0b43SKatayama Hirofumi MZ } 2368242e0b43SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2369242e0b43SKatayama Hirofumi MZ { 2370242e0b43SKatayama Hirofumi MZ if (pti != ptiIME) 2371242e0b43SKatayama Hirofumi MZ KeDetachProcess(); 2372242e0b43SKatayama Hirofumi MZ return; 2373242e0b43SKatayama Hirofumi MZ } 2374242e0b43SKatayama Hirofumi MZ _SEH2_END; 2375242e0b43SKatayama Hirofumi MZ 2376242e0b43SKatayama Hirofumi MZ // Detach from the process if necessary 2377242e0b43SKatayama Hirofumi MZ if (pti != ptiIME) 2378242e0b43SKatayama Hirofumi MZ KeDetachProcess(); 2379242e0b43SKatayama Hirofumi MZ 2380242e0b43SKatayama Hirofumi MZ if (bSendNotify) 2381242e0b43SKatayama Hirofumi MZ IntSendOpenStatusNotify(ptiIME, &SafeImeUI, pWnd, bShow); 2382242e0b43SKatayama Hirofumi MZ 2383242e0b43SKatayama Hirofumi MZ if (!(pImeWnd->state2 & WNDS2_INDESTROY)) 2384242e0b43SKatayama Hirofumi MZ IntCheckImeShowStatus(pImeWnd, NULL); 2385242e0b43SKatayama Hirofumi MZ } 2386242e0b43SKatayama Hirofumi MZ 2387242e0b43SKatayama Hirofumi MZ // Win: xxxBroadcastImeShowStatusChange 2388242e0b43SKatayama Hirofumi MZ BOOL FASTCALL IntBroadcastImeShowStatusChange(PWND pImeWnd, BOOL bShow) 2389242e0b43SKatayama Hirofumi MZ { 2390242e0b43SKatayama Hirofumi MZ if (gfIMEShowStatus == bShow || !IS_IMM_MODE()) 2391242e0b43SKatayama Hirofumi MZ return TRUE; 2392242e0b43SKatayama Hirofumi MZ 2393242e0b43SKatayama Hirofumi MZ gfIMEShowStatus = bShow; 2394242e0b43SKatayama Hirofumi MZ IntNotifyImeShowStatus(pImeWnd); 2395242e0b43SKatayama Hirofumi MZ return TRUE; 2396242e0b43SKatayama Hirofumi MZ } 2397242e0b43SKatayama Hirofumi MZ 23987cc89e52SKatayama Hirofumi MZ /* Win: xxxCheckImeShowStatusInThread */ 23997cc89e52SKatayama Hirofumi MZ VOID FASTCALL IntCheckImeShowStatusInThread(PWND pImeWnd) 24007cc89e52SKatayama Hirofumi MZ { 24017cc89e52SKatayama Hirofumi MZ if (IS_IMM_MODE() && !(pImeWnd->state2 & WNDS2_INDESTROY)) 24027cc89e52SKatayama Hirofumi MZ IntCheckImeShowStatus(pImeWnd, pImeWnd->head.pti); 24037cc89e52SKatayama Hirofumi MZ } 24047cc89e52SKatayama Hirofumi MZ 2405c2c66affSColin Finck /* EOF */ 2406