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) 14c2c66affSColin Finck 150519ae0aSKatayama Hirofumi MZ #define IS_WND_IMELIKE(pwnd) \ 160519ae0aSKatayama Hirofumi MZ (((pwnd)->pcls->style & CS_IME) || \ 170519ae0aSKatayama Hirofumi MZ ((pwnd)->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME])) 180519ae0aSKatayama Hirofumi MZ 190519ae0aSKatayama Hirofumi MZ PWND FASTCALL IntGetTopLevelWindow(PWND pwnd) 200519ae0aSKatayama Hirofumi MZ { 210519ae0aSKatayama Hirofumi MZ if (!pwnd) 220519ae0aSKatayama Hirofumi MZ return NULL; 230519ae0aSKatayama Hirofumi MZ 240519ae0aSKatayama Hirofumi MZ while (pwnd->style & WS_CHILD) 250519ae0aSKatayama Hirofumi MZ pwnd = pwnd->spwndParent; 260519ae0aSKatayama Hirofumi MZ 270519ae0aSKatayama Hirofumi MZ return pwnd; 280519ae0aSKatayama Hirofumi MZ } 290519ae0aSKatayama Hirofumi MZ 30470aa276SKatayama Hirofumi MZ DWORD 31470aa276SKatayama Hirofumi MZ APIENTRY 32470aa276SKatayama Hirofumi MZ NtUserSetThreadLayoutHandles(HKL hNewKL, HKL hOldKL) 33470aa276SKatayama Hirofumi MZ { 34470aa276SKatayama Hirofumi MZ PTHREADINFO pti; 35470aa276SKatayama Hirofumi MZ PKL pOldKL, pNewKL; 36470aa276SKatayama Hirofumi MZ 37470aa276SKatayama Hirofumi MZ UserEnterExclusive(); 38470aa276SKatayama Hirofumi MZ 39470aa276SKatayama Hirofumi MZ pti = GetW32ThreadInfo(); 40470aa276SKatayama Hirofumi MZ pOldKL = pti->KeyboardLayout; 41470aa276SKatayama Hirofumi MZ if (pOldKL && pOldKL->hkl != hOldKL) 42470aa276SKatayama Hirofumi MZ goto Quit; 43470aa276SKatayama Hirofumi MZ 44470aa276SKatayama Hirofumi MZ pNewKL = UserHklToKbl(hNewKL); 45470aa276SKatayama Hirofumi MZ if (!pNewKL) 46470aa276SKatayama Hirofumi MZ goto Quit; 47470aa276SKatayama Hirofumi MZ 48470aa276SKatayama Hirofumi MZ if (IS_IME_HKL(hNewKL) != IS_IME_HKL(hOldKL)) 49470aa276SKatayama Hirofumi MZ pti->hklPrev = hOldKL; 50470aa276SKatayama Hirofumi MZ 51470aa276SKatayama Hirofumi MZ pti->KeyboardLayout = pNewKL; 52470aa276SKatayama Hirofumi MZ 53470aa276SKatayama Hirofumi MZ Quit: 54470aa276SKatayama Hirofumi MZ UserLeave(); 55470aa276SKatayama Hirofumi MZ return 0; 56470aa276SKatayama Hirofumi MZ } 57470aa276SKatayama Hirofumi MZ 58ce6da820SKatayama Hirofumi MZ DWORD FASTCALL UserBuildHimcList(PTHREADINFO pti, DWORD dwCount, HIMC *phList) 59ce6da820SKatayama Hirofumi MZ { 60ce6da820SKatayama Hirofumi MZ PIMC pIMC; 61ce6da820SKatayama Hirofumi MZ DWORD dwRealCount = 0; 62ce6da820SKatayama Hirofumi MZ 63ce6da820SKatayama Hirofumi MZ if (pti) 64ce6da820SKatayama Hirofumi MZ { 65ce6da820SKatayama Hirofumi MZ for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext) 66ce6da820SKatayama Hirofumi MZ { 67ce6da820SKatayama Hirofumi MZ if (dwRealCount < dwCount) 68ce6da820SKatayama Hirofumi MZ phList[dwRealCount] = UserHMGetHandle(pIMC); 69ce6da820SKatayama Hirofumi MZ 70ce6da820SKatayama Hirofumi MZ ++dwRealCount; 71ce6da820SKatayama Hirofumi MZ } 72ce6da820SKatayama Hirofumi MZ } 73ce6da820SKatayama Hirofumi MZ else 74ce6da820SKatayama Hirofumi MZ { 75ce6da820SKatayama Hirofumi MZ for (pti = GetW32ThreadInfo()->ppi->ptiList; pti; pti = pti->ptiSibling) 76ce6da820SKatayama Hirofumi MZ { 77ce6da820SKatayama Hirofumi MZ for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext) 78ce6da820SKatayama Hirofumi MZ { 79ce6da820SKatayama Hirofumi MZ if (dwRealCount < dwCount) 80ce6da820SKatayama Hirofumi MZ phList[dwRealCount] = UserHMGetHandle(pIMC); 81ce6da820SKatayama Hirofumi MZ 82ce6da820SKatayama Hirofumi MZ ++dwRealCount; 83ce6da820SKatayama Hirofumi MZ } 84ce6da820SKatayama Hirofumi MZ } 85ce6da820SKatayama Hirofumi MZ } 86ce6da820SKatayama Hirofumi MZ 87ce6da820SKatayama Hirofumi MZ return dwRealCount; 88ce6da820SKatayama Hirofumi MZ } 89ce6da820SKatayama Hirofumi MZ 90c2c66affSColin Finck UINT FASTCALL 91c2c66affSColin Finck IntImmProcessKey(PUSER_MESSAGE_QUEUE MessageQueue, PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam) 92c2c66affSColin Finck { 93c2c66affSColin Finck PKL pKbdLayout; 94c2c66affSColin Finck 95c2c66affSColin Finck ASSERT_REFS_CO(pWnd); 96c2c66affSColin Finck 97c2c66affSColin Finck if ( Msg == WM_KEYDOWN || 98c2c66affSColin Finck Msg == WM_SYSKEYDOWN || 99c2c66affSColin Finck Msg == WM_KEYUP || 100c2c66affSColin Finck Msg == WM_SYSKEYUP ) 101c2c66affSColin Finck { 102c2c66affSColin Finck //Vk = wParam & 0xff; 103c2c66affSColin Finck pKbdLayout = pWnd->head.pti->KeyboardLayout; 104c2c66affSColin Finck if (pKbdLayout == NULL) return 0; 105c2c66affSColin Finck // 106c2c66affSColin Finck if (!(gpsi->dwSRVIFlags & SRVINFO_IMM32)) return 0; 107c2c66affSColin Finck // need ime.h! 108c2c66affSColin Finck } 109c2c66affSColin Finck // Call User32: 110c2c66affSColin Finck // Anything but BOOL! 111c2c66affSColin Finck //ImmRet = co_IntImmProcessKey(UserHMGetHandle(pWnd), pKbdLayout->hkl, Vk, lParam, HotKey); 112c2c66affSColin Finck FIXME(" is UNIMPLEMENTED.\n"); 113c2c66affSColin Finck return 0; 114c2c66affSColin Finck } 115c2c66affSColin Finck 116ce6da820SKatayama Hirofumi MZ NTSTATUS 117ce6da820SKatayama Hirofumi MZ APIENTRY 118ce6da820SKatayama Hirofumi MZ NtUserBuildHimcList(DWORD dwThreadId, DWORD dwCount, HIMC *phList, LPDWORD pdwCount) 119ce6da820SKatayama Hirofumi MZ { 120ce6da820SKatayama Hirofumi MZ NTSTATUS ret = STATUS_UNSUCCESSFUL; 121ce6da820SKatayama Hirofumi MZ DWORD dwRealCount; 122ce6da820SKatayama Hirofumi MZ PTHREADINFO pti; 123ce6da820SKatayama Hirofumi MZ 124ce6da820SKatayama Hirofumi MZ UserEnterExclusive(); 125ce6da820SKatayama Hirofumi MZ 126ce6da820SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 127ce6da820SKatayama Hirofumi MZ { 128ce6da820SKatayama Hirofumi MZ EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); 129ce6da820SKatayama Hirofumi MZ goto Quit; 130ce6da820SKatayama Hirofumi MZ } 131ce6da820SKatayama Hirofumi MZ 132ce6da820SKatayama Hirofumi MZ if (dwThreadId == 0) 133ce6da820SKatayama Hirofumi MZ { 134ce6da820SKatayama Hirofumi MZ pti = GetW32ThreadInfo(); 135ce6da820SKatayama Hirofumi MZ } 136ce6da820SKatayama Hirofumi MZ else if (dwThreadId == INVALID_THREAD_ID) 137ce6da820SKatayama Hirofumi MZ { 138ce6da820SKatayama Hirofumi MZ pti = NULL; 139ce6da820SKatayama Hirofumi MZ } 140ce6da820SKatayama Hirofumi MZ else 141ce6da820SKatayama Hirofumi MZ { 142ce6da820SKatayama Hirofumi MZ pti = IntTID2PTI(UlongToHandle(dwThreadId)); 143ce6da820SKatayama Hirofumi MZ if (!pti || !pti->rpdesk) 144ce6da820SKatayama Hirofumi MZ goto Quit; 145ce6da820SKatayama Hirofumi MZ } 146ce6da820SKatayama Hirofumi MZ 147ce6da820SKatayama Hirofumi MZ _SEH2_TRY 148ce6da820SKatayama Hirofumi MZ { 149ce6da820SKatayama Hirofumi MZ ProbeForWrite(phList, dwCount * sizeof(HIMC), 1); 150ce6da820SKatayama Hirofumi MZ ProbeForWrite(pdwCount, sizeof(DWORD), 1); 151ce6da820SKatayama Hirofumi MZ *pdwCount = dwRealCount = UserBuildHimcList(pti, dwCount, phList); 152ce6da820SKatayama Hirofumi MZ } 153ce6da820SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 154ce6da820SKatayama Hirofumi MZ { 155ce6da820SKatayama Hirofumi MZ goto Quit; 156ce6da820SKatayama Hirofumi MZ } 157ce6da820SKatayama Hirofumi MZ _SEH2_END; 158ce6da820SKatayama Hirofumi MZ 159ce6da820SKatayama Hirofumi MZ if (dwCount < dwRealCount) 160ce6da820SKatayama Hirofumi MZ ret = STATUS_BUFFER_TOO_SMALL; 161ce6da820SKatayama Hirofumi MZ else 162ce6da820SKatayama Hirofumi MZ ret = STATUS_SUCCESS; 163ce6da820SKatayama Hirofumi MZ 164ce6da820SKatayama Hirofumi MZ Quit: 165ce6da820SKatayama Hirofumi MZ UserLeave(); 166ce6da820SKatayama Hirofumi MZ return ret; 167ce6da820SKatayama Hirofumi MZ } 168ce6da820SKatayama Hirofumi MZ 169ec9d277dSKatayama Hirofumi MZ BOOL WINAPI 170ec9d277dSKatayama Hirofumi MZ NtUserGetImeHotKey(IN DWORD dwHotKey, 171ec9d277dSKatayama Hirofumi MZ OUT LPUINT lpuModifiers, 172ec9d277dSKatayama Hirofumi MZ OUT LPUINT lpuVKey, 173ec9d277dSKatayama Hirofumi MZ OUT LPHKL lphKL) 174c2c66affSColin Finck { 175c2c66affSColin Finck STUB 176c2c66affSColin Finck 177ec9d277dSKatayama Hirofumi MZ return FALSE; 178c2c66affSColin Finck } 179c2c66affSColin Finck 180c2c66affSColin Finck DWORD 181c2c66affSColin Finck APIENTRY 1829adc538cSKatayama Hirofumi MZ NtUserNotifyIMEStatus(HWND hwnd, BOOL fOpen, DWORD dwConversion) 183c2c66affSColin Finck { 1849adc538cSKatayama Hirofumi MZ TRACE("NtUserNotifyIMEStatus(%p, %d, 0x%lX)\n", hwnd, fOpen, dwConversion); 185c2c66affSColin Finck return 0; 186c2c66affSColin Finck } 187c2c66affSColin Finck 188c2c66affSColin Finck DWORD 189c2c66affSColin Finck APIENTRY 190c2c66affSColin Finck NtUserSetImeHotKey( 191c2c66affSColin Finck DWORD Unknown0, 192c2c66affSColin Finck DWORD Unknown1, 193c2c66affSColin Finck DWORD Unknown2, 194c2c66affSColin Finck DWORD Unknown3, 195c2c66affSColin Finck DWORD Unknown4) 196c2c66affSColin Finck { 197c2c66affSColin Finck STUB 198c2c66affSColin Finck 199c2c66affSColin Finck return 0; 200c2c66affSColin Finck } 201c2c66affSColin Finck 202c2c66affSColin Finck DWORD 203c2c66affSColin Finck APIENTRY 204c2c66affSColin Finck NtUserCheckImeHotKey( 205c2c66affSColin Finck DWORD VirtualKey, 206c2c66affSColin Finck LPARAM lParam) 207c2c66affSColin Finck { 208c2c66affSColin Finck STUB; 209c2c66affSColin Finck return 0; 210c2c66affSColin Finck } 211c2c66affSColin Finck 212fcc222c2SKatayama Hirofumi MZ BOOL 213c2c66affSColin Finck APIENTRY 214c2c66affSColin Finck NtUserDisableThreadIme( 215fcc222c2SKatayama Hirofumi MZ DWORD dwThreadID) 216c2c66affSColin Finck { 217fcc222c2SKatayama Hirofumi MZ PTHREADINFO pti, ptiCurrent; 218fcc222c2SKatayama Hirofumi MZ PPROCESSINFO ppi; 219fcc222c2SKatayama Hirofumi MZ BOOL ret = FALSE; 220fcc222c2SKatayama Hirofumi MZ 221fcc222c2SKatayama Hirofumi MZ UserEnterExclusive(); 222fcc222c2SKatayama Hirofumi MZ 223fcc222c2SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 224fcc222c2SKatayama Hirofumi MZ { 225fcc222c2SKatayama Hirofumi MZ EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); 226fcc222c2SKatayama Hirofumi MZ goto Quit; 227fcc222c2SKatayama Hirofumi MZ } 228fcc222c2SKatayama Hirofumi MZ 229fcc222c2SKatayama Hirofumi MZ ptiCurrent = GetW32ThreadInfo(); 230fcc222c2SKatayama Hirofumi MZ 231fcc222c2SKatayama Hirofumi MZ if (dwThreadID == INVALID_THREAD_ID) 232fcc222c2SKatayama Hirofumi MZ { 233fcc222c2SKatayama Hirofumi MZ ppi = ptiCurrent->ppi; 234fcc222c2SKatayama Hirofumi MZ ppi->W32PF_flags |= W32PF_DISABLEIME; 235fcc222c2SKatayama Hirofumi MZ 236fcc222c2SKatayama Hirofumi MZ Retry: 237fcc222c2SKatayama Hirofumi MZ for (pti = ppi->ptiList; pti; pti = pti->ptiSibling) 238fcc222c2SKatayama Hirofumi MZ { 239fcc222c2SKatayama Hirofumi MZ pti->TIF_flags |= TIF_DISABLEIME; 240fcc222c2SKatayama Hirofumi MZ 241fcc222c2SKatayama Hirofumi MZ if (pti->spwndDefaultIme) 242fcc222c2SKatayama Hirofumi MZ { 243fcc222c2SKatayama Hirofumi MZ co_UserDestroyWindow(pti->spwndDefaultIme); 244fcc222c2SKatayama Hirofumi MZ pti->spwndDefaultIme = NULL; 245fcc222c2SKatayama Hirofumi MZ goto Retry; /* The contents of ppi->ptiList may be changed. */ 246fcc222c2SKatayama Hirofumi MZ } 247fcc222c2SKatayama Hirofumi MZ } 248fcc222c2SKatayama Hirofumi MZ } 249fcc222c2SKatayama Hirofumi MZ else 250fcc222c2SKatayama Hirofumi MZ { 251fcc222c2SKatayama Hirofumi MZ if (dwThreadID == 0) 252fcc222c2SKatayama Hirofumi MZ { 253fcc222c2SKatayama Hirofumi MZ pti = ptiCurrent; 254fcc222c2SKatayama Hirofumi MZ } 255fcc222c2SKatayama Hirofumi MZ else 256fcc222c2SKatayama Hirofumi MZ { 257fcc222c2SKatayama Hirofumi MZ pti = IntTID2PTI(UlongToHandle(dwThreadID)); 258fcc222c2SKatayama Hirofumi MZ 259fcc222c2SKatayama Hirofumi MZ /* The thread needs to reside in the current process. */ 260fcc222c2SKatayama Hirofumi MZ if (!pti || pti->ppi != ptiCurrent->ppi) 261fcc222c2SKatayama Hirofumi MZ goto Quit; 262fcc222c2SKatayama Hirofumi MZ } 263fcc222c2SKatayama Hirofumi MZ 264fcc222c2SKatayama Hirofumi MZ pti->TIF_flags |= TIF_DISABLEIME; 265fcc222c2SKatayama Hirofumi MZ 266fcc222c2SKatayama Hirofumi MZ if (pti->spwndDefaultIme) 267fcc222c2SKatayama Hirofumi MZ { 268fcc222c2SKatayama Hirofumi MZ co_UserDestroyWindow(pti->spwndDefaultIme); 269fcc222c2SKatayama Hirofumi MZ pti->spwndDefaultIme = NULL; 270fcc222c2SKatayama Hirofumi MZ } 271fcc222c2SKatayama Hirofumi MZ } 272fcc222c2SKatayama Hirofumi MZ 273fcc222c2SKatayama Hirofumi MZ ret = TRUE; 274fcc222c2SKatayama Hirofumi MZ 275fcc222c2SKatayama Hirofumi MZ Quit: 276fcc222c2SKatayama Hirofumi MZ UserLeave(); 277fcc222c2SKatayama Hirofumi MZ return ret; 278c2c66affSColin Finck } 279c2c66affSColin Finck 280c2c66affSColin Finck DWORD 281c2c66affSColin Finck APIENTRY 282f4bc74edSKatayama Hirofumi MZ NtUserGetAppImeLevel(HWND hWnd) 283c2c66affSColin Finck { 2849c8167e9SKatayama Hirofumi MZ DWORD ret = 0; 2859c8167e9SKatayama Hirofumi MZ PWND pWnd; 2869c8167e9SKatayama Hirofumi MZ PTHREADINFO pti; 2879c8167e9SKatayama Hirofumi MZ 2889c8167e9SKatayama Hirofumi MZ UserEnterShared(); 2899c8167e9SKatayama Hirofumi MZ 2909c8167e9SKatayama Hirofumi MZ pWnd = ValidateHwndNoErr(hWnd); 2919c8167e9SKatayama Hirofumi MZ if (!pWnd) 2929c8167e9SKatayama Hirofumi MZ goto Quit; 2939c8167e9SKatayama Hirofumi MZ 2949c8167e9SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 2959c8167e9SKatayama Hirofumi MZ { 2969c8167e9SKatayama Hirofumi MZ EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); 2979c8167e9SKatayama Hirofumi MZ goto Quit; 2989c8167e9SKatayama Hirofumi MZ } 2999c8167e9SKatayama Hirofumi MZ 3009c8167e9SKatayama Hirofumi MZ pti = PsGetCurrentThreadWin32Thread(); 3019c8167e9SKatayama Hirofumi MZ if (pWnd->head.pti->ppi == pti->ppi) 3029c8167e9SKatayama Hirofumi MZ ret = (DWORD)(ULONG_PTR)UserGetProp(pWnd, AtomImeLevel, TRUE); 3039c8167e9SKatayama Hirofumi MZ 3049c8167e9SKatayama Hirofumi MZ Quit: 3059c8167e9SKatayama Hirofumi MZ UserLeave(); 3069c8167e9SKatayama Hirofumi MZ return ret; 307c2c66affSColin Finck } 308c2c66affSColin Finck 30936740ca9SKatayama Hirofumi MZ BOOL FASTCALL UserGetImeInfoEx(LPVOID pUnknown, PIMEINFOEX pInfoEx, IMEINFOEXCLASS SearchType) 31036740ca9SKatayama Hirofumi MZ { 31136740ca9SKatayama Hirofumi MZ PKL pkl, pklHead; 31236740ca9SKatayama Hirofumi MZ 31336740ca9SKatayama Hirofumi MZ if (!gspklBaseLayout) 31436740ca9SKatayama Hirofumi MZ return FALSE; 31536740ca9SKatayama Hirofumi MZ 31636740ca9SKatayama Hirofumi MZ pkl = pklHead = gspklBaseLayout; 31736740ca9SKatayama Hirofumi MZ 31836740ca9SKatayama Hirofumi MZ /* Find the matching entry from the list and get info */ 31936740ca9SKatayama Hirofumi MZ if (SearchType == ImeInfoExKeyboardLayout) 32036740ca9SKatayama Hirofumi MZ { 32136740ca9SKatayama Hirofumi MZ do 32236740ca9SKatayama Hirofumi MZ { 32328959a2dSKatayama Hirofumi MZ if (pInfoEx->hkl == pkl->hkl) 32436740ca9SKatayama Hirofumi MZ { 32536740ca9SKatayama Hirofumi MZ if (!pkl->piiex) 32636740ca9SKatayama Hirofumi MZ break; 32736740ca9SKatayama Hirofumi MZ 32828959a2dSKatayama Hirofumi MZ *pInfoEx = *pkl->piiex; 32928959a2dSKatayama Hirofumi MZ return TRUE; 33036740ca9SKatayama Hirofumi MZ } 33136740ca9SKatayama Hirofumi MZ 33236740ca9SKatayama Hirofumi MZ pkl = pkl->pklNext; 33336740ca9SKatayama Hirofumi MZ } while (pkl != pklHead); 33436740ca9SKatayama Hirofumi MZ } 33536740ca9SKatayama Hirofumi MZ else if (SearchType == ImeInfoExImeFileName) 33636740ca9SKatayama Hirofumi MZ { 33736740ca9SKatayama Hirofumi MZ do 33836740ca9SKatayama Hirofumi MZ { 33936740ca9SKatayama Hirofumi MZ if (pkl->piiex && 34036740ca9SKatayama Hirofumi MZ _wcsnicmp(pkl->piiex->wszImeFile, pInfoEx->wszImeFile, 34128959a2dSKatayama Hirofumi MZ RTL_NUMBER_OF(pkl->piiex->wszImeFile)) == 0) 34236740ca9SKatayama Hirofumi MZ { 34328959a2dSKatayama Hirofumi MZ *pInfoEx = *pkl->piiex; 34428959a2dSKatayama Hirofumi MZ return TRUE; 34536740ca9SKatayama Hirofumi MZ } 34636740ca9SKatayama Hirofumi MZ 34736740ca9SKatayama Hirofumi MZ pkl = pkl->pklNext; 34836740ca9SKatayama Hirofumi MZ } while (pkl != pklHead); 34936740ca9SKatayama Hirofumi MZ } 35036740ca9SKatayama Hirofumi MZ else 35136740ca9SKatayama Hirofumi MZ { 35236740ca9SKatayama Hirofumi MZ /* Do nothing */ 35336740ca9SKatayama Hirofumi MZ } 35436740ca9SKatayama Hirofumi MZ 35528959a2dSKatayama Hirofumi MZ return FALSE; 35636740ca9SKatayama Hirofumi MZ } 35736740ca9SKatayama Hirofumi MZ 3584b038ec8SKatayama Hirofumi MZ BOOL 359c2c66affSColin Finck APIENTRY 360c2c66affSColin Finck NtUserGetImeInfoEx( 361c2c66affSColin Finck PIMEINFOEX pImeInfoEx, 3624b038ec8SKatayama Hirofumi MZ IMEINFOEXCLASS SearchType) 363c2c66affSColin Finck { 36436740ca9SKatayama Hirofumi MZ IMEINFOEX ImeInfoEx; 36536740ca9SKatayama Hirofumi MZ BOOL ret = FALSE; 36636740ca9SKatayama Hirofumi MZ 36736740ca9SKatayama Hirofumi MZ UserEnterShared(); 36836740ca9SKatayama Hirofumi MZ 36936740ca9SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 37036740ca9SKatayama Hirofumi MZ goto Quit; 37136740ca9SKatayama Hirofumi MZ 37236740ca9SKatayama Hirofumi MZ _SEH2_TRY 37336740ca9SKatayama Hirofumi MZ { 37436740ca9SKatayama Hirofumi MZ ProbeForWrite(pImeInfoEx, sizeof(*pImeInfoEx), 1); 37536740ca9SKatayama Hirofumi MZ ImeInfoEx = *pImeInfoEx; 37636740ca9SKatayama Hirofumi MZ } 37736740ca9SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 37836740ca9SKatayama Hirofumi MZ { 37936740ca9SKatayama Hirofumi MZ goto Quit; 38036740ca9SKatayama Hirofumi MZ } 38136740ca9SKatayama Hirofumi MZ _SEH2_END; 38236740ca9SKatayama Hirofumi MZ 38336740ca9SKatayama Hirofumi MZ ret = UserGetImeInfoEx(NULL, &ImeInfoEx, SearchType); 38436740ca9SKatayama Hirofumi MZ if (ret) 38536740ca9SKatayama Hirofumi MZ { 38636740ca9SKatayama Hirofumi MZ _SEH2_TRY 38736740ca9SKatayama Hirofumi MZ { 38836740ca9SKatayama Hirofumi MZ *pImeInfoEx = ImeInfoEx; 38936740ca9SKatayama Hirofumi MZ } 39036740ca9SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 39136740ca9SKatayama Hirofumi MZ { 39236740ca9SKatayama Hirofumi MZ ret = FALSE; 39336740ca9SKatayama Hirofumi MZ } 39436740ca9SKatayama Hirofumi MZ _SEH2_END; 395c2c66affSColin Finck } 396c2c66affSColin Finck 39736740ca9SKatayama Hirofumi MZ Quit: 39836740ca9SKatayama Hirofumi MZ UserLeave(); 39936740ca9SKatayama Hirofumi MZ return ret; 40036740ca9SKatayama Hirofumi MZ } 401c2c66affSColin Finck 4029c8167e9SKatayama Hirofumi MZ BOOL 403c2c66affSColin Finck APIENTRY 4049c8167e9SKatayama Hirofumi MZ NtUserSetAppImeLevel(HWND hWnd, DWORD dwLevel) 405c2c66affSColin Finck { 4069c8167e9SKatayama Hirofumi MZ BOOL ret = FALSE; 4079c8167e9SKatayama Hirofumi MZ PWND pWnd; 4089c8167e9SKatayama Hirofumi MZ PTHREADINFO pti; 4099c8167e9SKatayama Hirofumi MZ 4109c8167e9SKatayama Hirofumi MZ UserEnterExclusive(); 4119c8167e9SKatayama Hirofumi MZ 4129c8167e9SKatayama Hirofumi MZ pWnd = ValidateHwndNoErr(hWnd); 4139c8167e9SKatayama Hirofumi MZ if (!pWnd) 4149c8167e9SKatayama Hirofumi MZ goto Quit; 4159c8167e9SKatayama Hirofumi MZ 4169c8167e9SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 4179c8167e9SKatayama Hirofumi MZ { 4189c8167e9SKatayama Hirofumi MZ EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); 4199c8167e9SKatayama Hirofumi MZ goto Quit; 4209c8167e9SKatayama Hirofumi MZ } 4219c8167e9SKatayama Hirofumi MZ 4229c8167e9SKatayama Hirofumi MZ pti = PsGetCurrentThreadWin32Thread(); 4239c8167e9SKatayama Hirofumi MZ if (pWnd->head.pti->ppi == pti->ppi) 4249c8167e9SKatayama Hirofumi MZ ret = UserSetProp(pWnd, AtomImeLevel, (HANDLE)(ULONG_PTR)dwLevel, TRUE); 4259c8167e9SKatayama Hirofumi MZ 4269c8167e9SKatayama Hirofumi MZ Quit: 4279c8167e9SKatayama Hirofumi MZ UserLeave(); 4289c8167e9SKatayama Hirofumi MZ return ret; 429c2c66affSColin Finck } 430c2c66affSColin Finck 4311f446936SKatayama Hirofumi MZ BOOL FASTCALL UserSetImeInfoEx(LPVOID pUnknown, PIMEINFOEX pImeInfoEx) 432c2c66affSColin Finck { 4331f446936SKatayama Hirofumi MZ PKL pklHead, pkl; 4341f446936SKatayama Hirofumi MZ 4351f446936SKatayama Hirofumi MZ pkl = pklHead = gspklBaseLayout; 4361f446936SKatayama Hirofumi MZ 4371f446936SKatayama Hirofumi MZ do 4381f446936SKatayama Hirofumi MZ { 4391f446936SKatayama Hirofumi MZ if (pkl->hkl != pImeInfoEx->hkl) 4401f446936SKatayama Hirofumi MZ { 4411f446936SKatayama Hirofumi MZ pkl = pkl->pklNext; 4421f446936SKatayama Hirofumi MZ continue; 4431f446936SKatayama Hirofumi MZ } 4441f446936SKatayama Hirofumi MZ 4451f446936SKatayama Hirofumi MZ if (!pkl->piiex) 4461f446936SKatayama Hirofumi MZ return FALSE; 4471f446936SKatayama Hirofumi MZ 4481f446936SKatayama Hirofumi MZ if (!pkl->piiex->fLoadFlag) 4491f446936SKatayama Hirofumi MZ *pkl->piiex = *pImeInfoEx; 4501f446936SKatayama Hirofumi MZ 4511f446936SKatayama Hirofumi MZ return TRUE; 4521f446936SKatayama Hirofumi MZ } while (pkl != pklHead); 4531f446936SKatayama Hirofumi MZ 4541f446936SKatayama Hirofumi MZ return FALSE; 4551f446936SKatayama Hirofumi MZ } 4561f446936SKatayama Hirofumi MZ 4571f446936SKatayama Hirofumi MZ BOOL 4581f446936SKatayama Hirofumi MZ APIENTRY 4591f446936SKatayama Hirofumi MZ NtUserSetImeInfoEx(PIMEINFOEX pImeInfoEx) 4601f446936SKatayama Hirofumi MZ { 4611f446936SKatayama Hirofumi MZ BOOL ret = FALSE; 4621f446936SKatayama Hirofumi MZ IMEINFOEX ImeInfoEx; 4631f446936SKatayama Hirofumi MZ 4641f446936SKatayama Hirofumi MZ UserEnterExclusive(); 4651f446936SKatayama Hirofumi MZ 4661f446936SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 4671f446936SKatayama Hirofumi MZ goto Quit; 4681f446936SKatayama Hirofumi MZ 4691f446936SKatayama Hirofumi MZ _SEH2_TRY 4701f446936SKatayama Hirofumi MZ { 4711f446936SKatayama Hirofumi MZ ProbeForRead(pImeInfoEx, sizeof(*pImeInfoEx), 1); 4721f446936SKatayama Hirofumi MZ ImeInfoEx = *pImeInfoEx; 4731f446936SKatayama Hirofumi MZ } 4741f446936SKatayama Hirofumi MZ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 4751f446936SKatayama Hirofumi MZ { 4761f446936SKatayama Hirofumi MZ goto Quit; 4771f446936SKatayama Hirofumi MZ } 4781f446936SKatayama Hirofumi MZ _SEH2_END; 4791f446936SKatayama Hirofumi MZ 4801f446936SKatayama Hirofumi MZ ret = UserSetImeInfoEx(NULL, &ImeInfoEx); 4811f446936SKatayama Hirofumi MZ 4821f446936SKatayama Hirofumi MZ Quit: 4831f446936SKatayama Hirofumi MZ UserLeave(); 4841f446936SKatayama Hirofumi MZ return ret; 485c2c66affSColin Finck } 486c2c66affSColin Finck 4878c6dcdcfSKatayama Hirofumi MZ BOOL APIENTRY 4888c6dcdcfSKatayama Hirofumi MZ NtUserSetImeOwnerWindow(HWND hImeWnd, HWND hwndFocus) 489c2c66affSColin Finck { 4900519ae0aSKatayama Hirofumi MZ BOOL ret = FALSE; 4910519ae0aSKatayama Hirofumi MZ PWND pImeWnd, pwndFocus, pwndTopLevel, pwnd, pwndActive; 4920519ae0aSKatayama Hirofumi MZ PTHREADINFO ptiIme; 4930519ae0aSKatayama Hirofumi MZ 4940519ae0aSKatayama Hirofumi MZ UserEnterExclusive(); 4950519ae0aSKatayama Hirofumi MZ 4960519ae0aSKatayama Hirofumi MZ pImeWnd = ValidateHwndNoErr(hImeWnd); 4970519ae0aSKatayama Hirofumi MZ if (!IS_IMM_MODE() || !pImeWnd || pImeWnd->fnid != FNID_IME) 4980519ae0aSKatayama Hirofumi MZ goto Quit; 4990519ae0aSKatayama Hirofumi MZ 5000519ae0aSKatayama Hirofumi MZ pwndFocus = ValidateHwndNoErr(hwndFocus); 5010519ae0aSKatayama Hirofumi MZ if (pwndFocus) 5020519ae0aSKatayama Hirofumi MZ { 5030519ae0aSKatayama Hirofumi MZ if (IS_WND_IMELIKE(pwndFocus)) 5040519ae0aSKatayama Hirofumi MZ goto Quit; 5050519ae0aSKatayama Hirofumi MZ 5060519ae0aSKatayama Hirofumi MZ pwndTopLevel = IntGetTopLevelWindow(pwndFocus); 5070519ae0aSKatayama Hirofumi MZ 5080519ae0aSKatayama Hirofumi MZ for (pwnd = pwndTopLevel; pwnd; pwnd = pwnd->spwndOwner) 5090519ae0aSKatayama Hirofumi MZ { 5100519ae0aSKatayama Hirofumi MZ if (pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME]) 5110519ae0aSKatayama Hirofumi MZ { 5120519ae0aSKatayama Hirofumi MZ pwndTopLevel = NULL; 5130519ae0aSKatayama Hirofumi MZ break; 5140519ae0aSKatayama Hirofumi MZ } 5150519ae0aSKatayama Hirofumi MZ } 5160519ae0aSKatayama Hirofumi MZ 5170519ae0aSKatayama Hirofumi MZ pImeWnd->spwndOwner = pwndTopLevel; 5180519ae0aSKatayama Hirofumi MZ // TODO: 5190519ae0aSKatayama Hirofumi MZ } 5200519ae0aSKatayama Hirofumi MZ else 5210519ae0aSKatayama Hirofumi MZ { 5220519ae0aSKatayama Hirofumi MZ ptiIme = pImeWnd->head.pti; 5230519ae0aSKatayama Hirofumi MZ pwndActive = ptiIme->MessageQueue->spwndActive; 5240519ae0aSKatayama Hirofumi MZ 5250519ae0aSKatayama Hirofumi MZ if (!pwndActive || pwndActive != pImeWnd->spwndOwner) 5260519ae0aSKatayama Hirofumi MZ { 5270519ae0aSKatayama Hirofumi MZ if (pwndActive && ptiIme == pwndActive->head.pti && !IS_WND_IMELIKE(pwndActive)) 5280519ae0aSKatayama Hirofumi MZ { 5290519ae0aSKatayama Hirofumi MZ pImeWnd->spwndOwner = pwndActive; 5300519ae0aSKatayama Hirofumi MZ } 5310519ae0aSKatayama Hirofumi MZ else 5320519ae0aSKatayama Hirofumi MZ { 5330519ae0aSKatayama Hirofumi MZ // TODO: 5340519ae0aSKatayama Hirofumi MZ } 5350519ae0aSKatayama Hirofumi MZ 5360519ae0aSKatayama Hirofumi MZ // TODO: 5370519ae0aSKatayama Hirofumi MZ } 5380519ae0aSKatayama Hirofumi MZ } 5390519ae0aSKatayama Hirofumi MZ 5400519ae0aSKatayama Hirofumi MZ ret = TRUE; 5410519ae0aSKatayama Hirofumi MZ 5420519ae0aSKatayama Hirofumi MZ Quit: 5430519ae0aSKatayama Hirofumi MZ UserLeave(); 5440519ae0aSKatayama Hirofumi MZ return ret; 545c2c66affSColin Finck } 546c2c66affSColin Finck 5473d78601fSKatayama Hirofumi MZ PVOID 5483d78601fSKatayama Hirofumi MZ AllocInputContextObject(PDESKTOP pDesk, 5493d78601fSKatayama Hirofumi MZ PTHREADINFO pti, 5503d78601fSKatayama Hirofumi MZ SIZE_T Size, 5513d78601fSKatayama Hirofumi MZ PVOID* HandleOwner) 5523d78601fSKatayama Hirofumi MZ { 5533d78601fSKatayama Hirofumi MZ PTHRDESKHEAD ObjHead; 5543d78601fSKatayama Hirofumi MZ 5553d78601fSKatayama Hirofumi MZ ASSERT(Size > sizeof(*ObjHead)); 5563d78601fSKatayama Hirofumi MZ ASSERT(pti != NULL); 5573d78601fSKatayama Hirofumi MZ 5583d78601fSKatayama Hirofumi MZ ObjHead = UserHeapAlloc(Size); 5593d78601fSKatayama Hirofumi MZ if (!ObjHead) 5603d78601fSKatayama Hirofumi MZ return NULL; 5613d78601fSKatayama Hirofumi MZ 5623d78601fSKatayama Hirofumi MZ RtlZeroMemory(ObjHead, Size); 5633d78601fSKatayama Hirofumi MZ 5643d78601fSKatayama Hirofumi MZ ObjHead->pSelf = ObjHead; 5653d78601fSKatayama Hirofumi MZ ObjHead->rpdesk = pDesk; 5663d78601fSKatayama Hirofumi MZ ObjHead->pti = pti; 5673d78601fSKatayama Hirofumi MZ IntReferenceThreadInfo(pti); 5683d78601fSKatayama Hirofumi MZ *HandleOwner = pti; 5693d78601fSKatayama Hirofumi MZ pti->ppi->UserHandleCount++; 5703d78601fSKatayama Hirofumi MZ 5713d78601fSKatayama Hirofumi MZ return ObjHead; 5723d78601fSKatayama Hirofumi MZ } 5733d78601fSKatayama Hirofumi MZ 5743d78601fSKatayama Hirofumi MZ VOID UserFreeInputContext(PVOID Object) 5753d78601fSKatayama Hirofumi MZ { 5763d78601fSKatayama Hirofumi MZ PIMC pIMC = Object, pImc0; 577757bed81SKatayama Hirofumi MZ PTHREADINFO pti; 5783d78601fSKatayama Hirofumi MZ 579757bed81SKatayama Hirofumi MZ if (!pIMC) 580757bed81SKatayama Hirofumi MZ return; 5813d78601fSKatayama Hirofumi MZ 582757bed81SKatayama Hirofumi MZ pti = pIMC->head.pti; 583757bed81SKatayama Hirofumi MZ 584757bed81SKatayama Hirofumi MZ /* Find the IMC in the list and remove it */ 5853d78601fSKatayama Hirofumi MZ for (pImc0 = pti->spDefaultImc; pImc0; pImc0 = pImc0->pImcNext) 5863d78601fSKatayama Hirofumi MZ { 5873d78601fSKatayama Hirofumi MZ if (pImc0->pImcNext == pIMC) 5883d78601fSKatayama Hirofumi MZ { 5893d78601fSKatayama Hirofumi MZ pImc0->pImcNext = pIMC->pImcNext; 5903d78601fSKatayama Hirofumi MZ break; 5913d78601fSKatayama Hirofumi MZ } 5923d78601fSKatayama Hirofumi MZ } 5933d78601fSKatayama Hirofumi MZ 594757bed81SKatayama Hirofumi MZ UserHeapFree(pIMC); 5953d78601fSKatayama Hirofumi MZ 5963d78601fSKatayama Hirofumi MZ pti->ppi->UserHandleCount--; 5973d78601fSKatayama Hirofumi MZ IntDereferenceThreadInfo(pti); 5983d78601fSKatayama Hirofumi MZ } 5993d78601fSKatayama Hirofumi MZ 6003d78601fSKatayama Hirofumi MZ BOOLEAN UserDestroyInputContext(PVOID Object) 6013d78601fSKatayama Hirofumi MZ { 6023d78601fSKatayama Hirofumi MZ PIMC pIMC = Object; 603757bed81SKatayama Hirofumi MZ if (pIMC) 604757bed81SKatayama Hirofumi MZ { 605757bed81SKatayama Hirofumi MZ UserMarkObjectDestroy(pIMC); 6063d78601fSKatayama Hirofumi MZ UserDeleteObject(pIMC->head.h, TYPE_INPUTCONTEXT); 607757bed81SKatayama Hirofumi MZ } 6083d78601fSKatayama Hirofumi MZ return TRUE; 6093d78601fSKatayama Hirofumi MZ } 6103d78601fSKatayama Hirofumi MZ 6113d78601fSKatayama Hirofumi MZ BOOL APIENTRY NtUserDestroyInputContext(HIMC hIMC) 6123d78601fSKatayama Hirofumi MZ { 6133d78601fSKatayama Hirofumi MZ PIMC pIMC; 6143d78601fSKatayama Hirofumi MZ BOOL ret = FALSE; 6153d78601fSKatayama Hirofumi MZ 6163d78601fSKatayama Hirofumi MZ UserEnterExclusive(); 6173d78601fSKatayama Hirofumi MZ 6183d78601fSKatayama Hirofumi MZ if (!(gpsi->dwSRVIFlags & SRVINFO_IMM32)) 6193d78601fSKatayama Hirofumi MZ { 6203d78601fSKatayama Hirofumi MZ EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); 6213d78601fSKatayama Hirofumi MZ UserLeave(); 6223d78601fSKatayama Hirofumi MZ return FALSE; 6233d78601fSKatayama Hirofumi MZ } 6243d78601fSKatayama Hirofumi MZ 6253d78601fSKatayama Hirofumi MZ pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT); 6263d78601fSKatayama Hirofumi MZ if (pIMC) 6273d78601fSKatayama Hirofumi MZ ret = UserDereferenceObject(pIMC); 6283d78601fSKatayama Hirofumi MZ 6293d78601fSKatayama Hirofumi MZ UserLeave(); 6303d78601fSKatayama Hirofumi MZ return ret; 6313d78601fSKatayama Hirofumi MZ } 632c2c66affSColin Finck 633470aa276SKatayama Hirofumi MZ PIMC FASTCALL UserCreateInputContext(ULONG_PTR dwClientImcData) 634470aa276SKatayama Hirofumi MZ { 635470aa276SKatayama Hirofumi MZ PIMC pIMC; 636470aa276SKatayama Hirofumi MZ PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); 637470aa276SKatayama Hirofumi MZ PDESKTOP pdesk = pti->rpdesk; 638470aa276SKatayama Hirofumi MZ 639470aa276SKatayama Hirofumi MZ if (!IS_IMM_MODE() || (pti->TIF_flags & TIF_DISABLEIME)) // Disabled? 640470aa276SKatayama Hirofumi MZ return NULL; 641470aa276SKatayama Hirofumi MZ 642470aa276SKatayama Hirofumi MZ if (!pdesk) // No desktop? 643470aa276SKatayama Hirofumi MZ return NULL; 644470aa276SKatayama Hirofumi MZ 645470aa276SKatayama Hirofumi MZ // pti->spDefaultImc should be already set if non-first time. 646470aa276SKatayama Hirofumi MZ if (dwClientImcData && !pti->spDefaultImc) 647470aa276SKatayama Hirofumi MZ return NULL; 648470aa276SKatayama Hirofumi MZ 649470aa276SKatayama Hirofumi MZ // Create an input context user object. 650470aa276SKatayama Hirofumi MZ pIMC = UserCreateObject(gHandleTable, pdesk, pti, NULL, TYPE_INPUTCONTEXT, sizeof(IMC)); 651470aa276SKatayama Hirofumi MZ if (!pIMC) 652470aa276SKatayama Hirofumi MZ return NULL; 653470aa276SKatayama Hirofumi MZ 654470aa276SKatayama Hirofumi MZ // Release the extra reference (UserCreateObject added 2 references). 655470aa276SKatayama Hirofumi MZ UserDereferenceObject(pIMC); 656470aa276SKatayama Hirofumi MZ 657470aa276SKatayama Hirofumi MZ if (dwClientImcData) // Non-first time. 658470aa276SKatayama Hirofumi MZ { 659470aa276SKatayama Hirofumi MZ // Insert pIMC to the second position (non-default) of the list. 660470aa276SKatayama Hirofumi MZ pIMC->pImcNext = pti->spDefaultImc->pImcNext; 661470aa276SKatayama Hirofumi MZ pti->spDefaultImc->pImcNext = pIMC; 662470aa276SKatayama Hirofumi MZ } 663470aa276SKatayama Hirofumi MZ else // First time. It's the default IMC. 664470aa276SKatayama Hirofumi MZ { 665470aa276SKatayama Hirofumi MZ // Add the first one (default) to the list. 666470aa276SKatayama Hirofumi MZ pti->spDefaultImc = pIMC; 667470aa276SKatayama Hirofumi MZ pIMC->pImcNext = NULL; 668470aa276SKatayama Hirofumi MZ } 669470aa276SKatayama Hirofumi MZ 670470aa276SKatayama Hirofumi MZ pIMC->dwClientImcData = dwClientImcData; // Set it. 671470aa276SKatayama Hirofumi MZ return pIMC; 672470aa276SKatayama Hirofumi MZ } 673470aa276SKatayama Hirofumi MZ 674470aa276SKatayama Hirofumi MZ HIMC 675470aa276SKatayama Hirofumi MZ APIENTRY 676470aa276SKatayama Hirofumi MZ NtUserCreateInputContext(ULONG_PTR dwClientImcData) 677470aa276SKatayama Hirofumi MZ { 678470aa276SKatayama Hirofumi MZ PIMC pIMC; 679470aa276SKatayama Hirofumi MZ HIMC ret = NULL; 680470aa276SKatayama Hirofumi MZ 681470aa276SKatayama Hirofumi MZ if (!dwClientImcData) 682470aa276SKatayama Hirofumi MZ return NULL; 683470aa276SKatayama Hirofumi MZ 684470aa276SKatayama Hirofumi MZ UserEnterExclusive(); 685470aa276SKatayama Hirofumi MZ 686470aa276SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 687470aa276SKatayama Hirofumi MZ goto Quit; 688470aa276SKatayama Hirofumi MZ 689470aa276SKatayama Hirofumi MZ pIMC = UserCreateInputContext(dwClientImcData); 690470aa276SKatayama Hirofumi MZ if (pIMC) 691470aa276SKatayama Hirofumi MZ ret = UserHMGetHandle(pIMC); 692470aa276SKatayama Hirofumi MZ 693470aa276SKatayama Hirofumi MZ Quit: 694470aa276SKatayama Hirofumi MZ UserLeave(); 695470aa276SKatayama Hirofumi MZ return ret; 696470aa276SKatayama Hirofumi MZ } 697470aa276SKatayama Hirofumi MZ 698*f2c3167dSKatayama Hirofumi MZ HIMC FASTCALL IntAssociateInputContext(PWND pWnd, PIMC pImc) 699*f2c3167dSKatayama Hirofumi MZ { 700*f2c3167dSKatayama Hirofumi MZ HIMC hOldImc = pWnd->hImc; 701*f2c3167dSKatayama Hirofumi MZ pWnd->hImc = (pImc ? UserHMGetHandle(pImc) : NULL); 702*f2c3167dSKatayama Hirofumi MZ return hOldImc; 703*f2c3167dSKatayama Hirofumi MZ } 704*f2c3167dSKatayama Hirofumi MZ 705*f2c3167dSKatayama Hirofumi MZ DWORD FASTCALL IntAssociateInputContextEx(PWND pWnd, PIMC pIMC, DWORD dwFlags) 706*f2c3167dSKatayama Hirofumi MZ { 707*f2c3167dSKatayama Hirofumi MZ DWORD ret = 0; 708*f2c3167dSKatayama Hirofumi MZ PWINDOWLIST pwl; 709*f2c3167dSKatayama Hirofumi MZ BOOL bIgnoreNullImc = (dwFlags & IACE_IGNORENOCONTEXT); 710*f2c3167dSKatayama Hirofumi MZ PTHREADINFO pti = pWnd->head.pti; 711*f2c3167dSKatayama Hirofumi MZ PWND pwndTarget, pwndFocus = pti->MessageQueue->spwndFocus; 712*f2c3167dSKatayama Hirofumi MZ HWND *phwnd; 713*f2c3167dSKatayama Hirofumi MZ HIMC hIMC; 714*f2c3167dSKatayama Hirofumi MZ 715*f2c3167dSKatayama Hirofumi MZ if (dwFlags & IACE_DEFAULT) 716*f2c3167dSKatayama Hirofumi MZ { 717*f2c3167dSKatayama Hirofumi MZ pIMC = pti->spDefaultImc; 718*f2c3167dSKatayama Hirofumi MZ } 719*f2c3167dSKatayama Hirofumi MZ else 720*f2c3167dSKatayama Hirofumi MZ { 721*f2c3167dSKatayama Hirofumi MZ if (pIMC && pti != pIMC->head.pti) 722*f2c3167dSKatayama Hirofumi MZ return 2; 723*f2c3167dSKatayama Hirofumi MZ } 724*f2c3167dSKatayama Hirofumi MZ 725*f2c3167dSKatayama Hirofumi MZ if (pWnd->head.pti->ppi != GetW32ThreadInfo()->ppi || 726*f2c3167dSKatayama Hirofumi MZ (pIMC && pIMC->head.rpdesk != pWnd->head.rpdesk)) 727*f2c3167dSKatayama Hirofumi MZ { 728*f2c3167dSKatayama Hirofumi MZ return 2; 729*f2c3167dSKatayama Hirofumi MZ } 730*f2c3167dSKatayama Hirofumi MZ 731*f2c3167dSKatayama Hirofumi MZ if ((dwFlags & IACE_CHILDREN) && pWnd->spwndChild) 732*f2c3167dSKatayama Hirofumi MZ { 733*f2c3167dSKatayama Hirofumi MZ pwl = IntBuildHwndList(pWnd->spwndChild, IACE_CHILDREN | IACE_LIST, pti); 734*f2c3167dSKatayama Hirofumi MZ if (pwl) 735*f2c3167dSKatayama Hirofumi MZ { 736*f2c3167dSKatayama Hirofumi MZ for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd) 737*f2c3167dSKatayama Hirofumi MZ { 738*f2c3167dSKatayama Hirofumi MZ pwndTarget = ValidateHwndNoErr(*phwnd); 739*f2c3167dSKatayama Hirofumi MZ if (!pwndTarget) 740*f2c3167dSKatayama Hirofumi MZ continue; 741*f2c3167dSKatayama Hirofumi MZ 742*f2c3167dSKatayama Hirofumi MZ hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL); 743*f2c3167dSKatayama Hirofumi MZ if (pwndTarget->hImc == hIMC || (bIgnoreNullImc && !pwndTarget->hImc)) 744*f2c3167dSKatayama Hirofumi MZ continue; 745*f2c3167dSKatayama Hirofumi MZ 746*f2c3167dSKatayama Hirofumi MZ IntAssociateInputContext(pwndTarget, pIMC); 747*f2c3167dSKatayama Hirofumi MZ if (pwndTarget == pwndFocus) 748*f2c3167dSKatayama Hirofumi MZ ret = 1; 749*f2c3167dSKatayama Hirofumi MZ } 750*f2c3167dSKatayama Hirofumi MZ 751*f2c3167dSKatayama Hirofumi MZ IntFreeHwndList(pwl); 752*f2c3167dSKatayama Hirofumi MZ } 753*f2c3167dSKatayama Hirofumi MZ } 754*f2c3167dSKatayama Hirofumi MZ 755*f2c3167dSKatayama Hirofumi MZ if (!bIgnoreNullImc || pWnd->hImc) 756*f2c3167dSKatayama Hirofumi MZ { 757*f2c3167dSKatayama Hirofumi MZ hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL); 758*f2c3167dSKatayama Hirofumi MZ if (pWnd->hImc != hIMC) 759*f2c3167dSKatayama Hirofumi MZ { 760*f2c3167dSKatayama Hirofumi MZ IntAssociateInputContext(pWnd, pIMC); 761*f2c3167dSKatayama Hirofumi MZ if (pWnd == pwndFocus) 762*f2c3167dSKatayama Hirofumi MZ ret = 1; 763*f2c3167dSKatayama Hirofumi MZ } 764*f2c3167dSKatayama Hirofumi MZ } 765*f2c3167dSKatayama Hirofumi MZ 766*f2c3167dSKatayama Hirofumi MZ return ret; 767*f2c3167dSKatayama Hirofumi MZ } 768*f2c3167dSKatayama Hirofumi MZ 769470aa276SKatayama Hirofumi MZ DWORD 770470aa276SKatayama Hirofumi MZ APIENTRY 771470aa276SKatayama Hirofumi MZ NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags) 772470aa276SKatayama Hirofumi MZ { 773*f2c3167dSKatayama Hirofumi MZ DWORD ret = 2; 774*f2c3167dSKatayama Hirofumi MZ PWND pWnd; 775*f2c3167dSKatayama Hirofumi MZ PIMC pIMC; 776*f2c3167dSKatayama Hirofumi MZ 777*f2c3167dSKatayama Hirofumi MZ UserEnterExclusive(); 778*f2c3167dSKatayama Hirofumi MZ 779*f2c3167dSKatayama Hirofumi MZ pWnd = ValidateHwndNoErr(hWnd); 780*f2c3167dSKatayama Hirofumi MZ if (!pWnd || !IS_IMM_MODE()) 781*f2c3167dSKatayama Hirofumi MZ goto Quit; 782*f2c3167dSKatayama Hirofumi MZ 783*f2c3167dSKatayama Hirofumi MZ pIMC = (hIMC ? UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT) : NULL); 784*f2c3167dSKatayama Hirofumi MZ ret = IntAssociateInputContextEx(pWnd, pIMC, dwFlags); 785*f2c3167dSKatayama Hirofumi MZ 786*f2c3167dSKatayama Hirofumi MZ Quit: 787*f2c3167dSKatayama Hirofumi MZ UserLeave(); 788*f2c3167dSKatayama Hirofumi MZ return ret; 789470aa276SKatayama Hirofumi MZ } 790470aa276SKatayama Hirofumi MZ 791470aa276SKatayama Hirofumi MZ BOOL FASTCALL UserUpdateInputContext(PIMC pIMC, DWORD dwType, DWORD_PTR dwValue) 792470aa276SKatayama Hirofumi MZ { 793470aa276SKatayama Hirofumi MZ PTHREADINFO pti = GetW32ThreadInfo(); 794470aa276SKatayama Hirofumi MZ PTHREADINFO ptiIMC = pIMC->head.pti; 795470aa276SKatayama Hirofumi MZ 796470aa276SKatayama Hirofumi MZ if (pti->ppi != ptiIMC->ppi) // Different process? 797470aa276SKatayama Hirofumi MZ return FALSE; 798470aa276SKatayama Hirofumi MZ 799470aa276SKatayama Hirofumi MZ switch (dwType) 800470aa276SKatayama Hirofumi MZ { 801470aa276SKatayama Hirofumi MZ case UIC_CLIENTIMCDATA: 802470aa276SKatayama Hirofumi MZ if (pIMC->dwClientImcData) 803470aa276SKatayama Hirofumi MZ return FALSE; // Already set 804470aa276SKatayama Hirofumi MZ 805470aa276SKatayama Hirofumi MZ pIMC->dwClientImcData = dwValue; 806470aa276SKatayama Hirofumi MZ break; 807470aa276SKatayama Hirofumi MZ 808470aa276SKatayama Hirofumi MZ case UIC_IMEWINDOW: 809470aa276SKatayama Hirofumi MZ if (!ValidateHwndNoErr((HWND)dwValue)) 810470aa276SKatayama Hirofumi MZ return FALSE; // Invalid HWND 811470aa276SKatayama Hirofumi MZ 812470aa276SKatayama Hirofumi MZ pIMC->hImeWnd = (HWND)dwValue; 813470aa276SKatayama Hirofumi MZ break; 814470aa276SKatayama Hirofumi MZ 815470aa276SKatayama Hirofumi MZ default: 816470aa276SKatayama Hirofumi MZ return FALSE; 817470aa276SKatayama Hirofumi MZ } 818470aa276SKatayama Hirofumi MZ 819470aa276SKatayama Hirofumi MZ return TRUE; 820470aa276SKatayama Hirofumi MZ } 821470aa276SKatayama Hirofumi MZ 822470aa276SKatayama Hirofumi MZ BOOL 823470aa276SKatayama Hirofumi MZ APIENTRY 824470aa276SKatayama Hirofumi MZ NtUserUpdateInputContext( 825470aa276SKatayama Hirofumi MZ HIMC hIMC, 826470aa276SKatayama Hirofumi MZ DWORD dwType, 827470aa276SKatayama Hirofumi MZ DWORD_PTR dwValue) 828470aa276SKatayama Hirofumi MZ { 829470aa276SKatayama Hirofumi MZ PIMC pIMC; 830470aa276SKatayama Hirofumi MZ BOOL ret = FALSE; 831470aa276SKatayama Hirofumi MZ 832470aa276SKatayama Hirofumi MZ UserEnterExclusive(); 833470aa276SKatayama Hirofumi MZ 834470aa276SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 835470aa276SKatayama Hirofumi MZ goto Quit; 836470aa276SKatayama Hirofumi MZ 837470aa276SKatayama Hirofumi MZ pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT); 838470aa276SKatayama Hirofumi MZ if (!pIMC) 839470aa276SKatayama Hirofumi MZ goto Quit; 840470aa276SKatayama Hirofumi MZ 841470aa276SKatayama Hirofumi MZ ret = UserUpdateInputContext(pIMC, dwType, dwValue); 842470aa276SKatayama Hirofumi MZ 843470aa276SKatayama Hirofumi MZ Quit: 844470aa276SKatayama Hirofumi MZ UserLeave(); 845470aa276SKatayama Hirofumi MZ return ret; 846470aa276SKatayama Hirofumi MZ } 847470aa276SKatayama Hirofumi MZ 848470aa276SKatayama Hirofumi MZ DWORD_PTR 849470aa276SKatayama Hirofumi MZ APIENTRY 850470aa276SKatayama Hirofumi MZ NtUserQueryInputContext(HIMC hIMC, DWORD dwType) 851470aa276SKatayama Hirofumi MZ { 852470aa276SKatayama Hirofumi MZ PIMC pIMC; 853470aa276SKatayama Hirofumi MZ PTHREADINFO ptiIMC; 854470aa276SKatayama Hirofumi MZ DWORD_PTR ret = 0; 855470aa276SKatayama Hirofumi MZ 856470aa276SKatayama Hirofumi MZ UserEnterExclusive(); 857470aa276SKatayama Hirofumi MZ 858470aa276SKatayama Hirofumi MZ if (!IS_IMM_MODE()) 859470aa276SKatayama Hirofumi MZ goto Quit; 860470aa276SKatayama Hirofumi MZ 861470aa276SKatayama Hirofumi MZ pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT); 862470aa276SKatayama Hirofumi MZ if (!pIMC) 863470aa276SKatayama Hirofumi MZ goto Quit; 864470aa276SKatayama Hirofumi MZ 865470aa276SKatayama Hirofumi MZ ptiIMC = pIMC->head.pti; 866470aa276SKatayama Hirofumi MZ 867470aa276SKatayama Hirofumi MZ switch (dwType) 868470aa276SKatayama Hirofumi MZ { 869470aa276SKatayama Hirofumi MZ case QIC_INPUTPROCESSID: 870470aa276SKatayama Hirofumi MZ ret = (DWORD_PTR)PsGetThreadProcessId(ptiIMC->pEThread); 871470aa276SKatayama Hirofumi MZ break; 872470aa276SKatayama Hirofumi MZ 873470aa276SKatayama Hirofumi MZ case QIC_INPUTTHREADID: 874470aa276SKatayama Hirofumi MZ ret = (DWORD_PTR)PsGetThreadId(ptiIMC->pEThread); 875470aa276SKatayama Hirofumi MZ break; 876470aa276SKatayama Hirofumi MZ 877470aa276SKatayama Hirofumi MZ case QIC_DEFAULTWINDOWIME: 878470aa276SKatayama Hirofumi MZ if (ptiIMC->spwndDefaultIme) 879470aa276SKatayama Hirofumi MZ ret = (DWORD_PTR)UserHMGetHandle(ptiIMC->spwndDefaultIme); 880470aa276SKatayama Hirofumi MZ break; 881470aa276SKatayama Hirofumi MZ 882470aa276SKatayama Hirofumi MZ case QIC_DEFAULTIMC: 883470aa276SKatayama Hirofumi MZ if (ptiIMC->spDefaultImc) 884470aa276SKatayama Hirofumi MZ ret = (DWORD_PTR)UserHMGetHandle(ptiIMC->spDefaultImc); 885470aa276SKatayama Hirofumi MZ break; 886470aa276SKatayama Hirofumi MZ } 887470aa276SKatayama Hirofumi MZ 888470aa276SKatayama Hirofumi MZ Quit: 889470aa276SKatayama Hirofumi MZ UserLeave(); 890470aa276SKatayama Hirofumi MZ return ret; 891470aa276SKatayama Hirofumi MZ } 892470aa276SKatayama Hirofumi MZ 893c2c66affSColin Finck /* EOF */ 894