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