Added version information.
[wine] / dlls / imm32 / imm.c
1 /*
2  * IMM32 library
3  *
4  * Copyright 1998 Patrik Stridvall
5  * Copyright 2002 Codeweavers, Aric Stewart
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "winbase.h"
23 #include "windef.h"
24 #include "wingdi.h"
25 #include "winuser.h"
26 #include "winerror.h"
27 #include "wine/debug.h"
28 #include "imm.h"
29 #include "winnls.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(imm);
32
33 typedef struct tagInputContextData
34 {
35         LPBYTE  CompositionString;
36         LPBYTE  CompositionReadingString;
37         LPBYTE  ResultString;
38         LPBYTE  ResultReadingString;
39         DWORD   dwCompStringSize;
40         DWORD   dwCompReadStringSize;
41         DWORD   dwResultStringSize;
42         DWORD   dwResultReadStringSize;
43         HWND    hwnd;
44         BOOL    bOpen;
45         BOOL    bRead;
46 } InputContextData; 
47
48 static InputContextData *root_context = NULL;
49 static HWND hwndDefault = (HWND)NULL;
50 static HANDLE hImeInst;
51 static const WCHAR WC_IMECLASSNAME[] = {'W','i','n','e','I','M','E','C','l','a','s','s',0};
52
53 static LRESULT CALLBACK IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
54
55 static VOID IMM_PostResult(InputContextData *data)
56 {
57     int i;
58
59     for (i = 0; i < data->dwResultStringSize / sizeof (WCHAR); i++)
60         SendMessageW(data->hwnd, WM_IME_CHAR, ((WCHAR*)data->ResultString)[i], 1);
61 }
62
63 static void IMM_Register(void)
64 {
65     WNDCLASSW wndClass;
66     ZeroMemory(&wndClass, sizeof(WNDCLASSW));
67     wndClass.style = CS_GLOBALCLASS | CS_IME;
68     wndClass.lpfnWndProc = IME_WindowProc;
69     wndClass.cbClsExtra = 0;
70     wndClass.cbWndExtra = 0;
71     wndClass.hCursor = (HCURSOR)NULL;
72     wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
73     wndClass.lpszClassName = WC_IMECLASSNAME;
74     RegisterClassW(&wndClass);
75 }
76
77 static void IMM_Unregister(void)
78 {
79     UnregisterClassW(WC_IMECLASSNAME, (HINSTANCE)NULL);
80 }
81
82
83 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
84 {
85     TRACE("%p, %lx, %p\n",hInstDLL,fdwReason,lpReserved);
86     switch (fdwReason)
87     {
88         case DLL_PROCESS_ATTACH:
89             hImeInst = hInstDLL;
90             break;
91         case DLL_PROCESS_DETACH:
92             if (hwndDefault)
93             {
94                 DestroyWindow(hwndDefault);
95                 hwndDefault = 0;
96             }
97             IMM_Unregister();
98             break;
99     }
100     return TRUE;
101 }
102
103
104 /***********************************************************************
105  *              ImmAssociateContext (IMM32.@)
106  */
107 HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
108 {
109     InputContextData *data = (InputContextData*)hIMC;
110
111     FIXME("(%p, %p): semi-stub\n",hWnd,hIMC);
112
113     if (!data)
114         return FALSE;
115
116     /*
117      * WINE SPECIFIC! MAY CONFLICT
118      * associate the root context we have an XIM created
119      */
120     if (hWnd == 0x000)
121     {
122         root_context = (InputContextData*)hIMC;
123     }
124
125     /*
126      * If already associated just return
127      */
128     if (data->hwnd == hWnd)
129         return (HIMC)data;
130
131     if (IsWindow(data->hwnd))
132     {
133         /*
134          * Post a message that your context is switching
135          */
136         SendMessageW(data->hwnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
137     }
138
139     data->hwnd = hWnd;
140
141     if (IsWindow(data->hwnd))
142     {
143         /*
144          * Post a message that your context is switching
145          */
146         SendMessageW(data->hwnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
147     }
148
149     /*
150      * TODO: We need to keep track of the old context associated
151      * with a window and return it for now we will return NULL;
152      */
153     return (HIMC)NULL;
154 }
155
156 /***********************************************************************
157  *              ImmConfigureIMEA (IMM32.@)
158  */
159 BOOL WINAPI ImmConfigureIMEA(
160   HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
161 {
162   FIXME("(%p, %p, %ld, %p): stub\n",
163     hKL, hWnd, dwMode, lpData
164   );
165   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
166   return FALSE;
167 }
168
169 /***********************************************************************
170  *              ImmConfigureIMEW (IMM32.@)
171  */
172 BOOL WINAPI ImmConfigureIMEW(
173   HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
174 {
175   FIXME("(%p, %p, %ld, %p): stub\n",
176     hKL, hWnd, dwMode, lpData
177   );
178   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
179   return FALSE;
180 }
181
182 /***********************************************************************
183  *              ImmCreateContext (IMM32.@)
184  */
185 HIMC WINAPI ImmCreateContext(void)
186 {
187     InputContextData *new_context;
188
189     new_context = HeapAlloc(GetProcessHeap(),0,sizeof(InputContextData));
190     ZeroMemory(new_context,sizeof(InputContextData));
191
192     return (HIMC)new_context;
193 }
194
195 /***********************************************************************
196  *              ImmDestroyContext (IMM32.@)
197  */
198 BOOL WINAPI ImmDestroyContext(HIMC hIMC)
199 {
200     InputContextData *data = (InputContextData*)hIMC;
201
202     TRACE("Destroying %p\n",hIMC);
203
204     if (hIMC)
205     {
206         if (data->dwCompStringSize)
207             HeapFree(GetProcessHeap(),0,data->CompositionString);
208         if (data->dwCompReadStringSize)
209             HeapFree(GetProcessHeap(),0,data->CompositionReadingString);
210         if (data->dwResultStringSize)
211             HeapFree(GetProcessHeap(),0,data->ResultString);
212         if (data->dwResultReadStringSize)
213             HeapFree(GetProcessHeap(),0,data->ResultReadingString);
214
215         HeapFree(GetProcessHeap(),0,data);
216     }
217     return TRUE;
218 }
219
220 /***********************************************************************
221  *              ImmEnumRegisterWordA (IMM32.@)
222  */
223 UINT WINAPI ImmEnumRegisterWordA(
224   HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
225   LPCSTR lpszReading, DWORD dwStyle,
226   LPCSTR lpszRegister, LPVOID lpData)
227 {
228   FIXME("(%p, %p, %s, %ld, %s, %p): stub\n",
229     hKL, lpfnEnumProc,
230     debugstr_a(lpszReading), dwStyle,
231     debugstr_a(lpszRegister), lpData
232   );
233   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
234   return 0;
235 }
236
237 /***********************************************************************
238  *              ImmEnumRegisterWordW (IMM32.@)
239  */
240 UINT WINAPI ImmEnumRegisterWordW(
241   HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
242   LPCWSTR lpszReading, DWORD dwStyle,
243   LPCWSTR lpszRegister, LPVOID lpData)
244 {
245   FIXME("(%p, %p, %s, %ld, %s, %p): stub\n",
246     hKL, lpfnEnumProc,
247     debugstr_w(lpszReading), dwStyle,
248     debugstr_w(lpszRegister), lpData
249   );
250   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
251   return 0;
252 }
253
254 /***********************************************************************
255  *              ImmEscapeA (IMM32.@)
256  */
257 LRESULT WINAPI ImmEscapeA(
258   HKL hKL, HIMC hIMC,
259   UINT uEscape, LPVOID lpData)
260 {
261   FIXME("(%p, %p, %d, %p): stub\n",
262     hKL, hIMC, uEscape, lpData
263   );
264   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
265   return 0;
266 }
267
268 /***********************************************************************
269  *              ImmEscapeW (IMM32.@)
270  */
271 LRESULT WINAPI ImmEscapeW(
272   HKL hKL, HIMC hIMC,
273   UINT uEscape, LPVOID lpData)
274 {
275   FIXME("(%p, %p, %d, %p): stub\n",
276     hKL, hIMC, uEscape, lpData
277   );
278   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
279   return 0;
280 }
281
282 /***********************************************************************
283  *              ImmGetCandidateListA (IMM32.@)
284  */
285 DWORD WINAPI ImmGetCandidateListA(
286   HIMC hIMC, DWORD deIndex,
287   LPCANDIDATELIST lpCandList, DWORD dwBufLen)
288 {
289   FIXME("(%p, %ld, %p, %ld): stub\n",
290     hIMC, deIndex,
291     lpCandList, dwBufLen
292   );
293   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
294   return 0;
295 }
296
297 /***********************************************************************
298  *              ImmGetCandidateListCountA (IMM32.@)
299  */
300 DWORD WINAPI ImmGetCandidateListCountA(
301   HIMC hIMC, LPDWORD lpdwListCount)
302 {
303   FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
304   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
305   return 0;
306 }
307
308 /***********************************************************************
309  *              ImmGetCandidateListCountW (IMM32.@)
310  */
311 DWORD WINAPI ImmGetCandidateListCountW(
312   HIMC hIMC, LPDWORD lpdwListCount)
313 {
314   FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
315   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
316   return 0;
317 }
318
319 /***********************************************************************
320  *              ImmGetCandidateListW (IMM32.@)
321  */
322 DWORD WINAPI ImmGetCandidateListW(
323   HIMC hIMC, DWORD deIndex,
324   LPCANDIDATELIST lpCandList, DWORD dwBufLen)
325 {
326   FIXME("(%p, %ld, %p, %ld): stub\n",
327     hIMC, deIndex,
328     lpCandList, dwBufLen
329   );
330   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
331   return 0;
332 }
333
334 /***********************************************************************
335  *              ImmGetCandidateWindow (IMM32.@)
336  */
337 BOOL WINAPI ImmGetCandidateWindow(
338   HIMC hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
339 {
340   FIXME("(%p, %ld, %p): stub\n", hIMC, dwBufLen, lpCandidate);
341   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
342   return FALSE;
343 }
344
345 /***********************************************************************
346  *              ImmGetCompositionFontA (IMM32.@)
347  */
348 BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
349 {
350   FIXME("(%p, %p): stub\n", hIMC, lplf);
351   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
352   return FALSE;
353 }
354
355 /***********************************************************************
356  *              ImmGetCompositionFontW (IMM32.@)
357  */
358 BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
359 {
360   FIXME("(%p, %p): stub\n", hIMC, lplf);
361   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
362   return FALSE;
363 }
364
365 /***********************************************************************
366  *              ImmGetCompositionStringA (IMM32.@)
367  */
368 LONG WINAPI ImmGetCompositionStringA(
369   HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
370 {
371     LONG rc; 
372     LPBYTE wcstring=NULL;
373
374     FIXME("(%p, %ld, %p, %ld): stub\n",
375             hIMC, dwIndex, lpBuf, dwBufLen);
376
377     if (dwBufLen > 0)
378         wcstring = HeapAlloc(GetProcessHeap(),0,dwBufLen * 2); 
379  
380     rc = ImmGetCompositionStringW(hIMC, dwIndex, wcstring, dwBufLen*2 );
381
382     if ((rc > dwBufLen) || (rc == 0))
383     {
384         if (wcstring)
385             HeapFree(GetProcessHeap(),0,wcstring);
386
387         return rc;
388     }
389  
390     rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)wcstring, (rc / sizeof(WCHAR)),
391                              lpBuf, dwBufLen, NULL, NULL);
392
393     HeapFree(GetProcessHeap(),0,wcstring);
394
395     return rc;
396 }
397
398 /***********************************************************************
399  *              ImmGetCompositionStringW (IMM32.@)
400  */
401 LONG WINAPI ImmGetCompositionStringW(
402   HIMC hIMC, DWORD dwIndex,
403   LPVOID lpBuf, DWORD dwBufLen)
404 {
405   InputContextData *data = (InputContextData*)hIMC;
406
407   FIXME("(%p, 0x%lx, %p, %ld): stub\n",
408     hIMC, dwIndex, lpBuf, dwBufLen
409   );
410
411     if (!data)
412        return FALSE;
413
414     if (dwIndex == GCS_RESULTSTR)
415     {
416         data->bRead = TRUE;
417
418         if (dwBufLen >= data->dwResultStringSize)
419             memcpy(lpBuf,data->ResultString,data->dwResultStringSize);
420         
421         return data->dwResultStringSize;
422     }
423
424     if (dwIndex == GCS_RESULTREADSTR)
425     {
426         if (dwBufLen >= data->dwResultReadStringSize)
427             memcpy(lpBuf,data->ResultReadingString,
428                     data->dwResultReadStringSize);
429         
430         return data->dwResultReadStringSize;
431     }   
432
433     if (dwIndex == GCS_COMPSTR)
434     {
435         if (dwBufLen >= data->dwCompStringSize)
436             memcpy(lpBuf,data->CompositionString,data->dwCompStringSize);
437         
438         return data->dwCompStringSize;
439     }
440
441     if (dwIndex == GCS_COMPREADSTR)
442     {
443         if (dwBufLen >= data->dwCompReadStringSize)
444             memcpy(lpBuf,data->CompositionReadingString,
445                     data->dwCompReadStringSize);
446         
447         return data->dwCompReadStringSize;
448     }   
449
450     return 0;
451 }
452
453 /***********************************************************************
454  *              ImmGetCompositionWindow (IMM32.@)
455  */
456 BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
457 {
458   FIXME("(%p, %p): stub\n", hIMC, lpCompForm);
459   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
460   return 0;
461 }
462
463 /***********************************************************************
464  *              ImmGetContext (IMM32.@)
465  */
466 HIMC WINAPI ImmGetContext(HWND hWnd)
467 {
468     FIXME("(%p): stub\n", hWnd);
469     return (HIMC)root_context;
470 }
471
472 /***********************************************************************
473  *              ImmGetConversionListA (IMM32.@)
474  */
475 DWORD WINAPI ImmGetConversionListA(
476   HKL hKL, HIMC hIMC,
477   LPCSTR pSrc, LPCANDIDATELIST lpDst,
478   DWORD dwBufLen, UINT uFlag)
479 {
480   FIXME("(%p, %p, %s, %p, %ld, %d): stub\n",
481     hKL, hIMC, debugstr_a(pSrc), lpDst, dwBufLen, uFlag
482   );
483   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
484   return 0;
485 }
486
487 /***********************************************************************
488  *              ImmGetConversionListW (IMM32.@)
489  */
490 DWORD WINAPI ImmGetConversionListW(
491   HKL hKL, HIMC hIMC,
492   LPCWSTR pSrc, LPCANDIDATELIST lpDst,
493   DWORD dwBufLen, UINT uFlag)
494 {
495   FIXME("(%p, %p, %s, %p, %ld, %d): stub\n",
496     hKL, hIMC, debugstr_w(pSrc), lpDst, dwBufLen, uFlag
497   );
498   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
499   return 0;
500 }
501
502 /***********************************************************************
503  *              ImmGetConversionStatus (IMM32.@)
504  */
505 BOOL WINAPI ImmGetConversionStatus(
506   HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
507 {
508   FIXME("(%p, %p, %p): stub\n",
509     hIMC, lpfdwConversion, lpfdwSentence
510   );
511   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
512   return FALSE;
513 }
514
515 /***********************************************************************
516  *              ImmGetDefaultIMEWnd (IMM32.@)
517  */
518 HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
519 {
520   FIXME("(%p): semi-stub\n", hWnd);
521
522   if ((!hwndDefault) && (root_context))
523   {
524         static const WCHAR name[] = {'I','M','E',0};
525         IMM_Register();
526
527         hwndDefault = CreateWindowW( WC_IMECLASSNAME,
528                        name,WS_POPUPWINDOW,0,0,0,0,0,0,hImeInst,0);
529   }
530
531   return (HWND)hwndDefault;
532 }
533
534 /***********************************************************************
535  *              ImmGetDescriptionA (IMM32.@)
536  */
537 UINT WINAPI ImmGetDescriptionA(
538   HKL hKL, LPSTR lpszDescription, UINT uBufLen)
539 {
540   FIXME("(%p, %s, %d): stub\n",
541     hKL, debugstr_a(lpszDescription), uBufLen
542   );
543   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
544   return 0;
545 }
546
547 /***********************************************************************
548  *              ImmGetDescriptionW (IMM32.@)
549  */
550 UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
551 {
552   FIXME("(%p, %s, %d): stub\n",
553     hKL, debugstr_w(lpszDescription), uBufLen
554   );
555   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
556   return 0;
557 }
558
559 /***********************************************************************
560  *              ImmGetGuideLineA (IMM32.@)
561  */
562 DWORD WINAPI ImmGetGuideLineA(
563   HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
564 {
565   FIXME("(%p, %ld, %s, %ld): stub\n",
566     hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
567   );
568   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
569   return 0;
570 }
571
572 /***********************************************************************
573  *              ImmGetGuideLineW (IMM32.@)
574  */
575 DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
576 {
577   FIXME("(%p, %ld, %s, %ld): stub\n",
578     hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
579   );
580   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
581   return 0;
582 }
583
584 /***********************************************************************
585  *              ImmGetIMEFileNameA (IMM32.@)
586  */
587 UINT WINAPI ImmGetIMEFileNameA(
588   HKL hKL, LPSTR lpszFileName, UINT uBufLen)
589 {
590   FIXME("(%p, %s, %d): stub\n",
591     hKL, debugstr_a(lpszFileName), uBufLen
592   );
593   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
594   return 0;
595 }
596
597 /***********************************************************************
598  *              ImmGetIMEFileNameW (IMM32.@)
599  */
600 UINT WINAPI ImmGetIMEFileNameW(
601   HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
602 {
603   FIXME("(%p, %s, %d): stub\n",
604     hKL, debugstr_w(lpszFileName), uBufLen
605   );
606   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
607   return 0;
608 }
609
610 /***********************************************************************
611  *              ImmGetOpenStatus (IMM32.@)
612  */
613 BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
614 {
615     InputContextData *data = (InputContextData*)hIMC;
616
617   FIXME("(%p): semi-stub\n", hIMC);
618
619   return data->bOpen;
620 }
621
622 /***********************************************************************
623  *              ImmGetProperty (IMM32.@)
624  */
625 DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
626 {
627     DWORD rc = 0;
628     FIXME("(%p, %ld): semi-stub\n", hKL, fdwIndex);
629
630     switch (fdwIndex)
631     {
632         case IGP_PROPERTY:
633             rc = IME_PROP_UNICODE | IME_PROP_SPECIAL_UI;
634             break;
635         case IGP_SETCOMPSTR:
636             rc = SCS_CAP_COMPSTR;
637             break;
638         case IGP_SELECT:
639             rc = SELECT_CAP_CONVERSION | SELECT_CAP_SENTENCE;
640             break;
641         case IGP_GETIMEVERSION:
642             rc = IMEVER_0400;
643             break;
644         case IGP_UI:
645         default:
646             rc = 0;
647     }
648     return rc;
649 }
650
651 /***********************************************************************
652  *              ImmGetRegisterWordStyleA (IMM32.@)
653  */
654 UINT WINAPI ImmGetRegisterWordStyleA(
655   HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
656 {
657   FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
658   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
659   return 0;
660 }
661
662 /***********************************************************************
663  *              ImmGetRegisterWordStyleW (IMM32.@)
664  */
665 UINT WINAPI ImmGetRegisterWordStyleW(
666   HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
667 {
668   FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
669   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
670   return 0;
671 }
672
673 /***********************************************************************
674  *              ImmGetStatusWindowPos (IMM32.@)
675  */
676 BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
677 {
678   FIXME("(%p, %p): stub\n", hIMC, lpptPos);
679   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
680   return FALSE;
681 }
682
683 /***********************************************************************
684  *              ImmGetVirtualKey (IMM32.@)
685  */
686 UINT WINAPI ImmGetVirtualKey(HWND hWnd)
687 {
688   OSVERSIONINFOA version;
689   FIXME("(%p): stub\n", hWnd);
690   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
691   GetVersionExA( &version );
692   switch(version.dwPlatformId)
693   {
694   case VER_PLATFORM_WIN32_WINDOWS:
695       return VK_PROCESSKEY;
696   case VER_PLATFORM_WIN32_NT:
697       return 0;
698   default:
699       FIXME("%ld not supported\n",version.dwPlatformId);
700       return VK_PROCESSKEY;
701   }
702 }
703
704 /***********************************************************************
705  *              ImmInstallIMEA (IMM32.@)
706  */
707 HKL WINAPI ImmInstallIMEA(
708   LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
709 {
710   FIXME("(%s, %s): stub\n",
711     debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
712   );
713   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
714   return NULL;
715 }
716
717 /***********************************************************************
718  *              ImmInstallIMEW (IMM32.@)
719  */
720 HKL WINAPI ImmInstallIMEW(
721   LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
722 {
723   FIXME("(%s, %s): stub\n",
724     debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
725   );
726   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
727   return NULL;
728 }
729
730 /***********************************************************************
731  *              ImmIsIME (IMM32.@)
732  */
733 BOOL WINAPI ImmIsIME(HKL hKL)
734 {
735   FIXME("(%p): semi-stub\n", hKL);
736   /*
737    * Dead key locales will return TRUE here when they should not
738    * There is probibly a more proper way to check this.
739    */
740   return (root_context != NULL);
741 }
742
743 /***********************************************************************
744  *              ImmIsUIMessageA (IMM32.@)
745  */
746 BOOL WINAPI ImmIsUIMessageA(
747   HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
748 {
749   FIXME("(%p, %d, %d, %ld): stub\n",
750     hWndIME, msg, wParam, lParam
751   );
752   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
753   return FALSE;
754 }
755
756 /***********************************************************************
757  *              ImmIsUIMessageW (IMM32.@)
758  */
759 BOOL WINAPI ImmIsUIMessageW(
760   HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
761 {
762   FIXME("(%p, %d, %d, %ld): stub\n",
763     hWndIME, msg, wParam, lParam
764   );
765   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
766   return FALSE;
767 }
768
769 /***********************************************************************
770  *              ImmNotifyIME (IMM32.@)
771  */
772 BOOL WINAPI ImmNotifyIME(
773   HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
774 {
775   FIXME("(%p, %ld, %ld, %ld): stub\n",
776     hIMC, dwAction, dwIndex, dwValue
777   );
778   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
779   return FALSE;
780 }
781
782 /***********************************************************************
783  *              ImmRegisterWordA (IMM32.@)
784  */
785 BOOL WINAPI ImmRegisterWordA(
786   HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
787 {
788   FIXME("(%p, %s, %ld, %s): stub\n",
789     hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister)
790   );
791   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
792   return FALSE;
793 }
794
795 /***********************************************************************
796  *              ImmRegisterWordW (IMM32.@)
797  */
798 BOOL WINAPI ImmRegisterWordW(
799   HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
800 {
801   FIXME("(%p, %s, %ld, %s): stub\n",
802     hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister)
803   );
804   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
805   return FALSE;
806 }
807
808 /***********************************************************************
809  *              ImmReleaseContext (IMM32.@)
810  */
811 BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
812 {
813   FIXME("(%p, %p): stub\n", hWnd, hIMC);
814   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
815   return FALSE;
816 }
817
818 /***********************************************************************
819  *              ImmSetCandidateWindow (IMM32.@)
820  */
821 BOOL WINAPI ImmSetCandidateWindow(
822   HIMC hIMC, LPCANDIDATEFORM lpCandidate)
823 {
824   FIXME("(%p, %p): stub\n", hIMC, lpCandidate);
825   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
826   return FALSE;
827 }
828
829 /***********************************************************************
830  *              ImmSetCompositionFontA (IMM32.@)
831  */
832 BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
833 {
834   FIXME("(%p, %p): stub\n", hIMC, lplf);
835   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
836   return FALSE;
837 }
838
839 /***********************************************************************
840  *              ImmSetCompositionFontW (IMM32.@)
841  */
842 BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
843 {
844   FIXME("(%p, %p): stub\n", hIMC, lplf);
845   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
846   return FALSE;
847 }
848
849 /***********************************************************************
850  *              ImmSetCompositionStringA (IMM32.@)
851  */
852 BOOL WINAPI ImmSetCompositionStringA(
853   HIMC hIMC, DWORD dwIndex,
854   LPCVOID lpComp, DWORD dwCompLen,
855   LPCVOID lpRead, DWORD dwReadLen)
856 {
857   FIXME("(%p, %ld, %p, %ld, %p, %ld): stub\n",
858     hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen
859   );
860   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
861   return FALSE;
862 }
863
864 /***********************************************************************
865  *              ImmSetCompositionStringW (IMM32.@)
866  */
867 BOOL WINAPI ImmSetCompositionStringW(
868         HIMC hIMC, DWORD dwIndex,
869         LPCVOID lpComp, DWORD dwCompLen,
870         LPCVOID lpRead, DWORD dwReadLen)
871 {
872     InputContextData *data = (InputContextData*)hIMC;
873
874     FIXME("(%p, %ld, %p, %ld, %p, %ld): semi-stub\n",
875         hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen
876         );
877
878     if (!data)
879         return FALSE;
880
881     if ((dwIndex == SCS_SETSTR)&&(dwCompLen || dwReadLen))
882         SendMessageW(data->hwnd, WM_IME_STARTCOMPOSITION, 0, 0);
883
884     if (dwIndex == SCS_SETSTR)
885     {
886         INT send_comp = 0;
887
888
889         if (lpComp && dwCompLen)
890         {
891 /*            if (data->dwCompStringSize)
892                 HeapFree(GetProcessHeap(),0,data->CompositionString);
893             data->dwCompStringSize = dwCompLen;
894             data->CompositionString = HeapAlloc(GetProcessHeap(),0,dwCompLen); 
895             memcpy(data->CompositionString,lpComp,dwCompLen);
896             send_comp |= GCS_COMPSTR;
897 */
898             data->bRead = FALSE;
899
900             if (data->dwResultStringSize)
901                 HeapFree(GetProcessHeap(),0,data->ResultString);
902             data->dwResultStringSize= dwCompLen;
903             data->ResultString= HeapAlloc(GetProcessHeap(),0,dwCompLen); 
904             memcpy(data->ResultString,lpComp,dwCompLen);
905             send_comp |= GCS_RESULTSTR;
906         }
907
908         if (lpRead && dwReadLen)
909         {
910             if (data->dwCompReadStringSize)
911                 HeapFree(GetProcessHeap(),0,data->CompositionReadingString);
912             data->dwCompReadStringSize= dwReadLen;
913             data->CompositionReadingString = HeapAlloc(GetProcessHeap(), 0,
914                                                         dwReadLen);
915             memcpy(data->CompositionReadingString,lpRead,dwReadLen);
916             send_comp |= GCS_COMPREADSTR;
917         }
918
919         if (send_comp)
920             SendMessageW(data->hwnd, WM_IME_COMPOSITION, 0, send_comp);
921
922         SendMessageW(data->hwnd, WM_IME_ENDCOMPOSITION, 0, 0);
923
924         return TRUE;
925     }
926     return FALSE;
927 }
928
929 /***********************************************************************
930  *              ImmSetCompositionWindow (IMM32.@)
931  */
932 BOOL WINAPI ImmSetCompositionWindow(
933   HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
934 {
935   FIXME("(%p, %p): stub\n", hIMC, lpCompForm);
936   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
937   return FALSE;
938 }
939
940 /***********************************************************************
941  *              ImmSetConversionStatus (IMM32.@)
942  */
943 BOOL WINAPI ImmSetConversionStatus(
944   HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
945 {
946   FIXME("(%p, %ld, %ld): stub\n",
947     hIMC, fdwConversion, fdwSentence
948   );
949   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
950   return FALSE;
951 }
952
953 /***********************************************************************
954  *              ImmSetOpenStatus (IMM32.@)
955  */
956 BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
957 {
958     InputContextData *data = (InputContextData*)hIMC;
959     FIXME("Semi-Stub\n");
960     if (data)
961     {
962         data->bOpen = fOpen;
963         SendMessageW(data->hwnd, WM_IME_NOTIFY, IMN_SETOPENSTATUS, 0);
964         return TRUE;
965     }
966     else
967         return FALSE;
968 }
969
970 /***********************************************************************
971  *              ImmSetStatusWindowPos (IMM32.@)
972  */
973 BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
974 {
975   FIXME("(%p, %p): stub\n", hIMC, lpptPos);
976   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
977   return FALSE;
978 }
979
980 /***********************************************************************
981  *              ImmSimulateHotKey (IMM32.@)
982  */
983 BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
984 {
985   FIXME("(%p, %ld): stub\n", hWnd, dwHotKeyID);
986   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
987   return FALSE;
988 }
989
990 /***********************************************************************
991  *              ImmUnregisterWordA (IMM32.@)
992  */
993 BOOL WINAPI ImmUnregisterWordA(
994   HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
995 {
996   FIXME("(%p, %s, %ld, %s): stub\n",
997     hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister)
998   );
999   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1000   return FALSE;
1001 }
1002
1003 /***********************************************************************
1004  *              ImmUnregisterWordW (IMM32.@)
1005  */
1006 BOOL WINAPI ImmUnregisterWordW(
1007   HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
1008 {
1009   FIXME("(%p, %s, %ld, %s): stub\n",
1010     hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister)
1011   );
1012   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1013   return FALSE;
1014 }
1015
1016 /*
1017  * The window proc for the default IME window
1018  */
1019 static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
1020                                           LPARAM lParam)
1021 {
1022     TRACE("Incomming Message 0x%x  (0x%08x, 0x%08x)\n", uMsg, (UINT)wParam,
1023            (UINT)lParam);
1024
1025     switch(uMsg)
1026     {
1027         case WM_NCCREATE:
1028             return TRUE;
1029
1030         case WM_IME_COMPOSITION:
1031             TRACE("IME message %s, 0x%x, 0x%x\n",
1032                     "WM_IME_COMPOSITION", (UINT)wParam, (UINT)lParam);
1033             break;
1034         case WM_IME_STARTCOMPOSITION:
1035             TRACE("IME message %s, 0x%x, 0x%x\n",
1036                     "WM_IME_STARTCOMPOSITION", (UINT)wParam, (UINT)lParam);
1037             break;
1038         case WM_IME_ENDCOMPOSITION:
1039             TRACE("IME message %s, 0x%x, 0x%x\n",
1040                     "WM_IME_ENDCOMPOSITION", (UINT)wParam, (UINT)lParam);
1041             /* 
1042              *   if the string has not been read, then send it as
1043              *   WM_IME_CHAR messages
1044              */
1045             if (!root_context->bRead)
1046                 IMM_PostResult(root_context);
1047             break;
1048         case WM_IME_SELECT:
1049             TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_SELECT",
1050                 (UINT)wParam, (UINT)lParam);
1051             break;
1052     }
1053     return 0;
1054 }