xref: /reactos/win32ss/user/ntuser/ime.c (revision f2c3167d)
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