xref: /reactos/win32ss/user/user32/misc/imm.c (revision 7b1049c8)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS user32.dll
4  * FILE:            win32ss/user/user32/misc/imm.c
5  * PURPOSE:         User32.dll Imm functions
6  * PROGRAMMERS:     Dmitry Chapyshev (dmitry@reactos.org)
7  *                  Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
8  * UPDATE HISTORY:
9  *      01/27/2009  Created
10  */
11 
12 #include <user32.h>
13 #include <strsafe.h>
14 
15 WINE_DEFAULT_DEBUG_CHANNEL(user32);
16 
17 #define IMM_INIT_MAGIC 0x19650412
18 
19 HINSTANCE ghImm32 = NULL;
20 BOOL bImmInitializing = FALSE;
21 
22 /* define stub functions */
23 #undef DEFINE_IMM_ENTRY
24 #define DEFINE_IMM_ENTRY(type, name, params, retval, retkind) \
25     static type WINAPI IMMSTUB_##name params { IMM_RETURN_##retkind((type)retval); }
26 #include "immtable.h"
27 
28 Imm32ApiTable gImmApiEntries = {
29 /* initialize by stubs */
30 #undef DEFINE_IMM_ENTRY
31 #define DEFINE_IMM_ENTRY(type, name, params, retval, retkind) \
32     IMMSTUB_##name,
33 #include "immtable.h"
34 };
35 
36 HRESULT WINAPI GetImmFileName(PWSTR lpBuffer, UINT uSize)
37 {
38   UINT length;
39   STRSAFE_LPWSTR Safe = lpBuffer;
40 
41   length = GetSystemDirectoryW(lpBuffer, uSize);
42   if ( length && length < uSize )
43   {
44     StringCchCatW(Safe, uSize, L"\\");
45     return StringCchCatW(Safe, uSize, L"imm32.dll");
46   }
47   return StringCchCopyW(Safe, uSize, L"imm32.dll");
48 }
49 
50 /*
51  * @unimplemented
52  */
53 BOOL WINAPI IntInitializeImmEntryTable(VOID)
54 {
55     WCHAR ImmFile[MAX_PATH];
56     HMODULE imm32 = ghImm32;
57 
58     GetImmFileName(ImmFile, sizeof(ImmFile));
59     TRACE("File %ws\n",ImmFile);
60 
61     if (imm32 == NULL)
62     {
63        imm32 = GetModuleHandleW(ImmFile);
64     }
65 
66     if (imm32 == NULL)
67     {
68         imm32 = ghImm32 = LoadLibraryW(ImmFile);
69         if (imm32 == NULL)
70         {
71            ERR("Did not load!\n");
72            return FALSE;
73         }
74         return TRUE;
75     }
76 
77 /* load imm procedures */
78 #undef DEFINE_IMM_ENTRY
79 #define DEFINE_IMM_ENTRY(type, name, params, retval, retkind) \
80     do { \
81         FN_##name proc = (FN_##name)GetProcAddress(imm32, #name); \
82         if (proc) { \
83             IMM_FN(name) = proc; \
84         } \
85     } while (0);
86 #include "immtable.h"
87 
88     return TRUE;
89 }
90 
91 BOOL WINAPI InitializeImmEntryTable(VOID)
92 {
93   bImmInitializing = TRUE;
94   return IntInitializeImmEntryTable();
95 }
96 
97 BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
98 {
99     TRACE("Imm (%x)\n", magic);
100 
101     if (magic != IMM_INIT_MAGIC)
102         return FALSE;
103 
104     if (IMM_FN(ImmIsIME) != IMMSTUB_ImmIsIME)
105         return TRUE;
106 
107     IntInitializeImmEntryTable();
108 
109     if (ghImm32 == NULL && !bImmInitializing)
110     {
111        WCHAR ImmFile[MAX_PATH];
112        GetImmFileName(ImmFile, sizeof(ImmFile));
113        ghImm32 = LoadLibraryW(ImmFile);
114        if (ghImm32 == NULL)
115        {
116           ERR("Did not load! 2\n");
117           return FALSE;
118        }
119     }
120 
121     return TRUE;
122 }
123 
124 LRESULT WINAPI ImeWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode ) // ReactOS
125 {
126     PWND pWnd;
127     PIMEUI pimeui;
128 
129     pWnd = ValidateHwnd(hwnd);
130     if (pWnd)
131     {
132        if (!pWnd->fnid)
133        {
134           if (msg != WM_NCCREATE)
135           {
136              if (unicode)
137                 return DefWindowProcW(hwnd, msg, wParam, lParam);
138              return DefWindowProcA(hwnd, msg, wParam, lParam);
139           }
140           NtUserSetWindowFNID(hwnd, FNID_IME);
141           pimeui = HeapAlloc( GetProcessHeap(), 0, sizeof(IMEUI) );
142           SetWindowLongPtrW(hwnd, 0, (LONG_PTR)pimeui);
143        }
144        else
145        {
146           if (pWnd->fnid != FNID_IME)
147           {
148              ERR("Wrong window class for Ime! fnId 0x%x\n",pWnd->fnid);
149              return 0;
150           }
151           pimeui = ((PIMEWND)pWnd)->pimeui;
152           if (pimeui == NULL)
153           {
154              ERR("Window is not set to IME!\n");
155              return 0;
156           }
157        }
158     }
159 
160     if (msg==WM_CREATE || msg==WM_NCCREATE)
161         return TRUE;
162 
163     if (msg==WM_NCDESTROY)
164     {
165         HeapFree( GetProcessHeap(), 0, pimeui );
166         SetWindowLongPtrW(hwnd, 0, 0);
167         NtUserSetWindowFNID(hwnd, FNID_DESTROY);
168     }
169 
170     if (unicode)
171        return DefWindowProcW(hwnd, msg, wParam, lParam);
172     return DefWindowProcA(hwnd, msg, wParam, lParam);
173 }
174 
175 LRESULT WINAPI ImeWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
176 {
177     return ImeWndProc_common(hwnd, msg, wParam, lParam, FALSE);
178 }
179 
180 LRESULT WINAPI ImeWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
181 {
182     return ImeWndProc_common(hwnd, msg, wParam, lParam, TRUE);
183 }
184 
185 BOOL
186 WINAPI
187 UpdatePerUserImmEnabling(VOID)
188 {
189   BOOL Ret = NtUserCallNoParam(NOPARAM_ROUTINE_UPDATEPERUSERIMMENABLING);
190   if ( Ret )
191   {
192     if ( gpsi->dwSRVIFlags & SRVINFO_IMM32 )
193     {
194       HMODULE imm32 = GetModuleHandleW(L"imm32.dll");
195       if ( !imm32 )
196       {
197         imm32 = LoadLibraryW(L"imm32.dll");
198         if (!imm32)
199         {
200            ERR("UPUIE: Imm32 not installed!\n");
201            Ret = FALSE;
202         }
203       }
204     }
205   }
206   return Ret;
207 }
208 
209 static const WCHAR imeW[] = {'I','M','E',0};
210 
211 BOOL
212 WINAPI
213 RegisterIMEClass(VOID)
214 {
215     WNDCLASSEXW WndClass;
216     ATOM atom;
217 
218     ZeroMemory(&WndClass, sizeof(WndClass));
219 
220     WndClass.cbSize = sizeof(WndClass);
221     WndClass.lpszClassName = imeW;
222     WndClass.style = CS_GLOBALCLASS;
223     WndClass.lpfnWndProc = ImeWndProcW;
224     WndClass.cbWndExtra = sizeof(LONG_PTR);
225     WndClass.hCursor = LoadCursorW(NULL, IDC_ARROW);
226 
227     atom = RegisterClassExWOWW( &WndClass,
228                                  0,
229                                  FNID_IME,
230                                  0,
231                                  FALSE);
232     if (atom)
233     {
234        RegisterDefaultClasses |= ICLASS_TO_MASK(ICLS_IME);
235        TRACE("Register IME Class!\n");
236        return TRUE;
237     }
238     ERR("Failed to register IME Class!\n");
239     return FALSE;
240 }
241 
242 /*
243  * @unimplemented
244  */
245 BOOL WINAPI CliImmSetHotKey(DWORD dwID, UINT uModifiers, UINT uVirtualKey, HKL hKl)
246 {
247   UNIMPLEMENTED;
248   return FALSE;
249 }
250 
251 /*
252  * @implemented
253  */
254 BOOL
255 WINAPI
256 IMPSetIMEW(HWND hwnd, LPIMEPROW ime)
257 {
258     return IMM_FN(ImmIMPSetIMEW)(hwnd, ime);
259 }
260 
261 /*
262  * @implemented
263  */
264 BOOL
265 WINAPI
266 IMPQueryIMEW(LPIMEPROW ime)
267 {
268     return IMM_FN(ImmIMPQueryIMEW)(ime);
269 }
270 
271 /*
272  * @implemented
273  */
274 BOOL
275 WINAPI
276 IMPGetIMEW(HWND hwnd, LPIMEPROW ime)
277 {
278     return IMM_FN(ImmIMPGetIMEW)(hwnd, ime);
279 }
280 
281 /*
282  * @implemented
283  */
284 BOOL
285 WINAPI
286 IMPSetIMEA(HWND hwnd, LPIMEPROA ime)
287 {
288     return IMM_FN(ImmIMPSetIMEA)(hwnd, ime);
289 }
290 
291 /*
292  * @implemented
293  */
294 BOOL
295 WINAPI
296 IMPQueryIMEA(LPIMEPROA ime)
297 {
298     return IMM_FN(ImmIMPQueryIMEA)(ime);
299 }
300 
301 /*
302  * @implemented
303  */
304 BOOL
305 WINAPI
306 IMPGetIMEA(HWND hwnd, LPIMEPROA ime)
307 {
308     return IMM_FN(ImmIMPGetIMEA)(hwnd, ime);
309 }
310 
311 /*
312  * @implemented
313  */
314 LRESULT
315 WINAPI
316 SendIMEMessageExW(HWND hwnd, LPARAM lParam)
317 {
318     return IMM_FN(ImmSendIMEMessageExW)(hwnd, lParam);
319 }
320 
321 /*
322  * @implemented
323  */
324 LRESULT
325 WINAPI
326 SendIMEMessageExA(HWND hwnd, LPARAM lParam)
327 {
328     return IMM_FN(ImmSendIMEMessageExA)(hwnd, lParam);
329 }
330 
331 /*
332  * @implemented
333  */
334 BOOL
335 WINAPI
336 WINNLSEnableIME(HWND hwnd, BOOL enable)
337 {
338     return IMM_FN(ImmWINNLSEnableIME)(hwnd, enable);
339 }
340 
341 /*
342  * @implemented
343  */
344 BOOL
345 WINAPI
346 WINNLSGetEnableStatus(HWND hwnd)
347 {
348     return IMM_FN(ImmWINNLSGetEnableStatus)(hwnd);
349 }
350 
351 /*
352  * @implemented
353  */
354 UINT
355 WINAPI
356 WINNLSGetIMEHotkey(HWND hwnd)
357 {
358     return FALSE;
359 }
360