Removed W->A from DEFWND_ImmIsUIMessageW.
[wine] / dlls / imm32 / imm.c
1 /*
2  * IMM32 library
3  *
4  * Copyright 1998 Patrik Stridvall
5  * Copyright 2002, 2003 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 #define FROM_IME 0xcafe1337
36
37 static void (*pX11DRV_ForceXIMReset)(HWND);
38
39 typedef struct tagInputContextData
40 {
41         LPBYTE          CompositionString;
42         LPBYTE          CompositionReadingString;
43         LPBYTE          ResultString;
44         LPBYTE          ResultReadingString;
45         DWORD           dwCompStringSize;   /* buffer size */
46         DWORD           dwCompStringLength; /* string length (in bytes) */
47         DWORD           dwCompReadStringSize;
48         DWORD           dwResultStringSize;
49         DWORD           dwResultReadStringSize;
50         HWND            hwnd;
51         BOOL            bOpen;
52         BOOL            bInternalState;
53         BOOL            bRead;
54         LOGFONTW        font;
55         HFONT           textfont;
56         COMPOSITIONFORM CompForm;
57 } InputContextData;
58
59 static InputContextData *root_context = NULL;
60 static HWND hwndDefault = NULL;
61 static HANDLE hImeInst;
62 static const WCHAR WC_IMECLASSNAME[] = {'I','M','E',0};
63
64 /* MSIME messages */
65 static UINT WM_MSIME_SERVICE;
66 static UINT WM_MSIME_RECONVERTOPTIONS;
67 static UINT WM_MSIME_MOUSE;
68 static UINT WM_MSIME_RECONVERTREQUEST;
69 static UINT WM_MSIME_RECONVERT;
70 static UINT WM_MSIME_QUERYPOSITION;
71 static UINT WM_MSIME_DOCUMENTFEED;
72
73 /*
74  * prototypes
75  */
76 static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
77                                           LPARAM lParam);
78 static void UpdateDataInDefaultIMEWindow(HWND hwnd);
79 static void ImmInternalPostIMEMessage(UINT, WPARAM, LPARAM);
80 static void ImmInternalSetOpenStatus(BOOL fOpen);
81
82 static VOID IMM_PostResult(InputContextData *data)
83 {
84     unsigned int i;
85     TRACE("Posting result as IME_CHAR\n");
86
87     for (i = 0; i < data->dwResultStringSize / sizeof (WCHAR); i++)
88         ImmInternalPostIMEMessage (WM_IME_CHAR, ((WCHAR*)data->ResultString)[i],
89                      1);
90
91     /* clear the buffer */
92     if (data->dwResultStringSize)
93         HeapFree(GetProcessHeap(),0,data->ResultString);
94     data->dwResultStringSize = 0;
95     data->ResultString = NULL;
96 }
97
98 static void IMM_Register(void)
99 {
100     WNDCLASSW wndClass;
101     ZeroMemory(&wndClass, sizeof(WNDCLASSW));
102     wndClass.style = CS_GLOBALCLASS | CS_IME | CS_HREDRAW | CS_VREDRAW;
103     wndClass.lpfnWndProc = (WNDPROC) IME_WindowProc;
104     wndClass.cbClsExtra = 0;
105     wndClass.cbWndExtra = 0;
106     wndClass.hInstance = hImeInst;
107     wndClass.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
108     wndClass.hIcon = NULL;
109     wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
110     wndClass.lpszMenuName   = 0;
111     wndClass.lpszClassName = WC_IMECLASSNAME;
112     RegisterClassW(&wndClass);
113 }
114
115 static void IMM_Unregister(void)
116 {
117     UnregisterClassW(WC_IMECLASSNAME, NULL);
118 }
119
120 static void IMM_RegisterMessages(void)
121 {
122     WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
123     WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
124     WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
125     WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
126     WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
127     WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
128     WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
129 }
130
131
132 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
133 {
134     HMODULE x11drv;
135
136     TRACE("%p, %lx, %p\n",hInstDLL,fdwReason,lpReserved);
137     switch (fdwReason)
138     {
139         case DLL_PROCESS_ATTACH:
140             DisableThreadLibraryCalls(hInstDLL);
141             hImeInst = hInstDLL;
142             IMM_RegisterMessages();
143             x11drv = GetModuleHandleA("x11drv.dll");
144             if (x11drv) pX11DRV_ForceXIMReset = (void *)GetProcAddress( x11drv, "ForceXIMReset");
145             break;
146         case DLL_PROCESS_DETACH:
147             if (hwndDefault)
148             {
149                 DestroyWindow(hwndDefault);
150                 hwndDefault = 0;
151             }
152             IMM_Unregister();
153             break;
154     }
155     return TRUE;
156 }
157
158 /* for posting messages as the IME */
159 static void ImmInternalPostIMEMessage(UINT msg, WPARAM wParam, LPARAM lParam)
160 {
161     HWND target = GetFocus();
162     if (!target)
163        PostMessageW(root_context->hwnd,msg,wParam,lParam);
164     else 
165        PostMessageW(target, msg, wParam, lParam);
166 }
167
168
169 static void ImmInternalSetOpenStatus(BOOL fOpen)
170 {
171     TRACE("Setting internal state to %s\n",(fOpen)?"OPEN":"CLOSED");
172
173    root_context->bOpen = fOpen;
174    root_context->bInternalState = fOpen;
175
176    if (fOpen == FALSE)
177    {
178         ShowWindow(hwndDefault,SW_HIDE);
179
180         if (root_context->dwCompStringSize)
181             HeapFree(GetProcessHeap(),0,root_context->CompositionString);
182         if (root_context->dwCompReadStringSize)
183             HeapFree(GetProcessHeap(),0,root_context->CompositionReadingString);
184         if (root_context->dwResultStringSize)
185             HeapFree(GetProcessHeap(),0,root_context->ResultString);
186         if (root_context->dwResultReadStringSize)
187             HeapFree(GetProcessHeap(),0,root_context->ResultReadingString);
188         root_context->dwCompStringSize = 0;
189         root_context->dwCompStringLength = 0;
190         root_context->CompositionString = NULL;
191         root_context->dwCompReadStringSize = 0;
192         root_context->CompositionReadingString = NULL;
193         root_context->dwResultStringSize = 0;
194         root_context->ResultString = NULL;
195         root_context->dwResultReadStringSize = 0;
196         root_context->ResultReadingString = NULL;
197     }
198     else
199         ShowWindow(hwndDefault, SW_SHOWNOACTIVATE);
200
201    SendMessageW(root_context->hwnd, WM_IME_NOTIFY, IMN_SETOPENSTATUS, 0);
202 }
203
204
205 /***********************************************************************
206  *              ImmAssociateContext (IMM32.@)
207  */
208 HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
209 {
210     InputContextData *data = (InputContextData*)hIMC;
211
212     WARN("(%p, %p): semi-stub\n",hWnd,hIMC);
213
214     if (!data)
215         return FALSE;
216
217     /*
218      * WINE SPECIFIC! MAY CONFLICT
219      * associate the root context we have an XIM created
220      */
221     if (hWnd == 0x000)
222     {
223         root_context = (InputContextData*)hIMC;
224     }
225
226     /*
227      * If already associated just return
228      */
229     if (data->hwnd == hWnd)
230         return (HIMC)data;
231
232     if (IsWindow(data->hwnd))
233     {
234         /*
235          * Post a message that your context is switching
236          */
237         SendMessageW(data->hwnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
238     }
239
240     data->hwnd = hWnd;
241
242     if (IsWindow(data->hwnd))
243     {
244         /*
245          * Post a message that your context is switching
246          */
247         SendMessageW(data->hwnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
248     }
249
250     /*
251      * TODO: We need to keep track of the old context associated
252      * with a window and return it for now we will return NULL;
253      */
254     return (HIMC)NULL;
255 }
256
257 /***********************************************************************
258  *              ImmAssociateContextEx (IMM32.@)
259  */
260 BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
261 {
262     FIXME("(%p, %p, %ld): stub\n", hWnd, hIMC, dwFlags);
263     return FALSE;
264 }
265
266 /***********************************************************************
267  *              ImmConfigureIMEA (IMM32.@)
268  */
269 BOOL WINAPI ImmConfigureIMEA(
270   HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
271 {
272   FIXME("(%p, %p, %ld, %p): stub\n",
273     hKL, hWnd, dwMode, lpData
274   );
275   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
276   return FALSE;
277 }
278
279 /***********************************************************************
280  *              ImmConfigureIMEW (IMM32.@)
281  */
282 BOOL WINAPI ImmConfigureIMEW(
283   HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
284 {
285   FIXME("(%p, %p, %ld, %p): stub\n",
286     hKL, hWnd, dwMode, lpData
287   );
288   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
289   return FALSE;
290 }
291
292 /***********************************************************************
293  *              ImmCreateContext (IMM32.@)
294  */
295 HIMC WINAPI ImmCreateContext(void)
296 {
297     InputContextData *new_context;
298
299     new_context = HeapAlloc(GetProcessHeap(),0,sizeof(InputContextData));
300     ZeroMemory(new_context,sizeof(InputContextData));
301
302     return (HIMC)new_context;
303 }
304
305 /***********************************************************************
306  *              ImmDestroyContext (IMM32.@)
307  */
308 BOOL WINAPI ImmDestroyContext(HIMC hIMC)
309 {
310     InputContextData *data = (InputContextData*)hIMC;
311
312     TRACE("Destroying %p\n",hIMC);
313
314     if (hIMC)
315     {
316         if (data->dwCompStringSize)
317             HeapFree(GetProcessHeap(),0,data->CompositionString);
318         if (data->dwCompReadStringSize)
319             HeapFree(GetProcessHeap(),0,data->CompositionReadingString);
320         if (data->dwResultStringSize)
321             HeapFree(GetProcessHeap(),0,data->ResultString);
322         if (data->dwResultReadStringSize)
323             HeapFree(GetProcessHeap(),0,data->ResultReadingString);
324
325         if (data->textfont)
326         {
327             DeleteObject(data->textfont);
328             data->textfont = NULL;
329         }
330
331         HeapFree(GetProcessHeap(),0,data);
332     }
333     return TRUE;
334 }
335
336 /***********************************************************************
337  *              ImmDisableIME (IMM32.@)
338  */
339 BOOL WINAPI ImmDisableIME(DWORD idThread)
340 {
341     FIXME("(%ld): stub\n", idThread);
342     return TRUE;
343 }
344
345 /***********************************************************************
346  *              ImmEnumRegisterWordA (IMM32.@)
347  */
348 UINT WINAPI ImmEnumRegisterWordA(
349   HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
350   LPCSTR lpszReading, DWORD dwStyle,
351   LPCSTR lpszRegister, LPVOID lpData)
352 {
353   FIXME("(%p, %p, %s, %ld, %s, %p): stub\n",
354     hKL, lpfnEnumProc,
355     debugstr_a(lpszReading), dwStyle,
356     debugstr_a(lpszRegister), lpData
357   );
358   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
359   return 0;
360 }
361
362 /***********************************************************************
363  *              ImmEnumRegisterWordW (IMM32.@)
364  */
365 UINT WINAPI ImmEnumRegisterWordW(
366   HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
367   LPCWSTR lpszReading, DWORD dwStyle,
368   LPCWSTR lpszRegister, LPVOID lpData)
369 {
370   FIXME("(%p, %p, %s, %ld, %s, %p): stub\n",
371     hKL, lpfnEnumProc,
372     debugstr_w(lpszReading), dwStyle,
373     debugstr_w(lpszRegister), lpData
374   );
375   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
376   return 0;
377 }
378
379 /***********************************************************************
380  *              ImmEscapeA (IMM32.@)
381  */
382 LRESULT WINAPI ImmEscapeA(
383   HKL hKL, HIMC hIMC,
384   UINT uEscape, LPVOID lpData)
385 {
386   FIXME("(%p, %p, %d, %p): stub\n",
387     hKL, hIMC, uEscape, lpData
388   );
389   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
390   return 0;
391 }
392
393 /***********************************************************************
394  *              ImmEscapeW (IMM32.@)
395  */
396 LRESULT WINAPI ImmEscapeW(
397   HKL hKL, HIMC hIMC,
398   UINT uEscape, LPVOID lpData)
399 {
400   FIXME("(%p, %p, %d, %p): stub\n",
401     hKL, hIMC, uEscape, lpData
402   );
403   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
404   return 0;
405 }
406
407 /***********************************************************************
408  *              ImmGetCandidateListA (IMM32.@)
409  */
410 DWORD WINAPI ImmGetCandidateListA(
411   HIMC hIMC, DWORD deIndex,
412   LPCANDIDATELIST lpCandList, DWORD dwBufLen)
413 {
414   FIXME("(%p, %ld, %p, %ld): stub\n",
415     hIMC, deIndex,
416     lpCandList, dwBufLen
417   );
418   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
419   return 0;
420 }
421
422 /***********************************************************************
423  *              ImmGetCandidateListCountA (IMM32.@)
424  */
425 DWORD WINAPI ImmGetCandidateListCountA(
426   HIMC hIMC, LPDWORD lpdwListCount)
427 {
428   FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
429   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
430   return 0;
431 }
432
433 /***********************************************************************
434  *              ImmGetCandidateListCountW (IMM32.@)
435  */
436 DWORD WINAPI ImmGetCandidateListCountW(
437   HIMC hIMC, LPDWORD lpdwListCount)
438 {
439   FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
440   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
441   return 0;
442 }
443
444 /***********************************************************************
445  *              ImmGetCandidateListW (IMM32.@)
446  */
447 DWORD WINAPI ImmGetCandidateListW(
448   HIMC hIMC, DWORD deIndex,
449   LPCANDIDATELIST lpCandList, DWORD dwBufLen)
450 {
451   FIXME("(%p, %ld, %p, %ld): stub\n",
452     hIMC, deIndex,
453     lpCandList, dwBufLen
454   );
455   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
456   return 0;
457 }
458
459 /***********************************************************************
460  *              ImmGetCandidateWindow (IMM32.@)
461  */
462 BOOL WINAPI ImmGetCandidateWindow(
463   HIMC hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
464 {
465   FIXME("(%p, %ld, %p): stub\n", hIMC, dwBufLen, lpCandidate);
466   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
467   return FALSE;
468 }
469
470 /***********************************************************************
471  *              ImmGetCompositionFontA (IMM32.@)
472  */
473 BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
474 {
475   FIXME("(%p, %p): stub\n", hIMC, lplf);
476   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
477   return FALSE;
478 }
479
480 /***********************************************************************
481  *              ImmGetCompositionFontW (IMM32.@)
482  */
483 BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
484 {
485   FIXME("(%p, %p): stub\n", hIMC, lplf);
486   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
487   return FALSE;
488 }
489
490 /***********************************************************************
491  *              ImmGetCompositionStringA (IMM32.@)
492  */
493 LONG WINAPI ImmGetCompositionStringA(
494   HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
495 {
496     CHAR *buf;
497     LONG rc = 0;
498     InputContextData *data = (InputContextData*)hIMC;
499
500     TRACE("(%p, 0x%lx, %p, %ld)\n", hIMC, dwIndex, lpBuf, dwBufLen);
501
502     if (!data)
503        return FALSE;
504
505     if (dwIndex == GCS_RESULTSTR)
506     {
507         TRACE("GSC_RESULTSTR %p %li\n",data->ResultString,
508                                     data->dwResultStringSize);
509
510         buf = HeapAlloc( GetProcessHeap(), 0, data->dwResultStringSize * 3 );
511         rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->ResultString,
512                                  data->dwResultStringSize / sizeof(WCHAR), buf,
513                                  data->dwResultStringSize * 3, NULL, NULL);
514         if (dwBufLen >= rc)
515             memcpy(lpBuf,buf,rc);
516
517         data->bRead = TRUE;
518         HeapFree( GetProcessHeap(), 0, buf );
519     }
520     else if (dwIndex == GCS_COMPSTR)
521     {
522          TRACE("GSC_COMPSTR %p %li\n",data->CompositionString,
523                                      data->dwCompStringLength/ sizeof(WCHAR));
524
525         buf = HeapAlloc( GetProcessHeap(), 0, data->dwCompStringLength * 3 );
526         rc = WideCharToMultiByte(CP_ACP, 0,(LPWSTR)data->CompositionString,
527                                  data->dwCompStringLength/ sizeof(WCHAR), buf,
528                                  data->dwCompStringLength* 3, NULL, NULL);
529         if (dwBufLen >= rc)
530             memcpy(lpBuf,buf,rc);
531         HeapFree( GetProcessHeap(), 0, buf );
532     }
533     else if (dwIndex == GCS_COMPATTR)
534     {
535         TRACE("GSC_COMPATTR %p %li\n",data->CompositionString,
536                                     data->dwCompStringLength/ sizeof(WCHAR));
537
538         rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->CompositionString,
539                                  data->dwCompStringLength/ sizeof(WCHAR), NULL,
540                                  0, NULL, NULL);
541  
542         if (dwBufLen >= rc)
543         {
544             int i=0;
545             for (i = 0;  i < rc; i++)
546                 ((LPBYTE)lpBuf)[i] = ATTR_INPUT;
547     }
548     }
549     else if (dwIndex == GCS_COMPCLAUSE)
550     {
551         TRACE("GSC_COMPCLAUSE %p %li\n",data->CompositionString,
552                                     data->dwCompStringLength/ sizeof(WCHAR));
553  
554         rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->CompositionString,
555                                  data->dwCompStringLength/ sizeof(WCHAR), NULL,
556                                  0, NULL, NULL);
557
558         if (dwBufLen >= sizeof(DWORD)*2)
559         {
560             ((LPDWORD)lpBuf)[0] = 0;
561             ((LPDWORD)lpBuf)[1] = rc;
562         }
563         rc = sizeof(DWORD)*2;
564     }
565     else
566     {
567         FIXME("Unhandled index 0x%lx\n",dwIndex);
568     }
569
570     return rc;
571 }
572
573 /***********************************************************************
574  *              ImmGetCompositionStringW (IMM32.@)
575  */
576 LONG WINAPI ImmGetCompositionStringW(
577   HIMC hIMC, DWORD dwIndex,
578   LPVOID lpBuf, DWORD dwBufLen)
579 {
580   LONG rc = 0;
581   InputContextData *data = (InputContextData*)hIMC;
582
583   TRACE("(%p, 0x%lx, %p, %ld)\n",
584     hIMC, dwIndex, lpBuf, dwBufLen
585   );
586
587     if (!data)
588        return FALSE;
589
590     if (dwIndex == GCS_RESULTSTR)
591     {
592         data->bRead = TRUE;
593
594         if (dwBufLen >= data->dwResultStringSize)
595             memcpy(lpBuf,data->ResultString,data->dwResultStringSize);
596         
597         rc =  data->dwResultStringSize;
598     }
599     else if (dwIndex == GCS_RESULTREADSTR)
600     {
601         if (dwBufLen >= data->dwResultReadStringSize)
602             memcpy(lpBuf,data->ResultReadingString,
603                     data->dwResultReadStringSize);
604         
605         rc = data->dwResultReadStringSize;
606     }   
607     else if (dwIndex == GCS_COMPSTR)
608     {
609         if (dwBufLen >= data->dwCompStringLength)
610             memcpy(lpBuf,data->CompositionString,data->dwCompStringLength);
611
612         rc = data->dwCompStringLength;
613     }
614     else if (dwIndex == GCS_COMPATTR)
615     {
616         unsigned int len = data->dwCompStringLength;
617         
618         if (dwBufLen >= len)
619         {
620             unsigned int i=0;
621             for (i = 0;  i < len; i++)
622                 ((LPBYTE)lpBuf)[i] = ATTR_INPUT;
623         }
624
625         rc = len;
626     }
627     else if (dwIndex == GCS_COMPCLAUSE)
628     {
629         if (dwBufLen >= sizeof(DWORD)*2)
630         {
631             ((LPDWORD)lpBuf)[0] = 0;
632             ((LPDWORD)lpBuf)[1] = data->dwCompStringLength/sizeof(WCHAR);
633         }
634         rc = sizeof(DWORD)*2;
635     }
636     else if (dwIndex == GCS_COMPREADSTR)
637     {
638         if (dwBufLen >= data->dwCompReadStringSize)
639             memcpy(lpBuf,data->CompositionReadingString,
640                     data->dwCompReadStringSize);
641         
642         rc = data->dwCompReadStringSize;
643     }   
644     else
645     {
646         FIXME("Unhandled index 0x%lx\n",dwIndex);
647     }   
648
649     return rc;
650 }
651
652 /***********************************************************************
653  *              ImmGetCompositionWindow (IMM32.@)
654  */
655 BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
656 {
657     InputContextData *data = (InputContextData*)hIMC;
658
659     TRACE("(%p, %p)\n", hIMC, lpCompForm);
660
661     if (!data)
662         return FALSE;
663
664     memcpy(lpCompForm,&(data->CompForm),sizeof(COMPOSITIONFORM));
665     return 1;
666 }
667
668 /***********************************************************************
669  *              ImmGetContext (IMM32.@)
670  *
671  */
672 HIMC WINAPI ImmGetContext(HWND hWnd)
673 {
674     FIXME("(%p): stub\n", hWnd);
675
676     if (!root_context)
677         return NULL;
678
679     root_context->hwnd = hWnd;
680     return (HIMC)root_context;
681 }
682
683 /***********************************************************************
684  *              ImmGetConversionListA (IMM32.@)
685  */
686 DWORD WINAPI ImmGetConversionListA(
687   HKL hKL, HIMC hIMC,
688   LPCSTR pSrc, LPCANDIDATELIST lpDst,
689   DWORD dwBufLen, UINT uFlag)
690 {
691   FIXME("(%p, %p, %s, %p, %ld, %d): stub\n",
692     hKL, hIMC, debugstr_a(pSrc), lpDst, dwBufLen, uFlag
693   );
694   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
695   return 0;
696 }
697
698 /***********************************************************************
699  *              ImmGetConversionListW (IMM32.@)
700  */
701 DWORD WINAPI ImmGetConversionListW(
702   HKL hKL, HIMC hIMC,
703   LPCWSTR pSrc, LPCANDIDATELIST lpDst,
704   DWORD dwBufLen, UINT uFlag)
705 {
706   FIXME("(%p, %p, %s, %p, %ld, %d): stub\n",
707     hKL, hIMC, debugstr_w(pSrc), lpDst, dwBufLen, uFlag
708   );
709   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
710   return 0;
711 }
712
713 /***********************************************************************
714  *              ImmGetConversionStatus (IMM32.@)
715  */
716 BOOL WINAPI ImmGetConversionStatus(
717   HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
718 {
719     TRACE("(%p, %p, %p): best guess\n", hIMC, lpfdwConversion, lpfdwSentence);
720     if (lpfdwConversion)
721         *lpfdwConversion = IME_CMODE_NATIVE;
722     if (lpfdwSentence)
723         *lpfdwSentence = IME_SMODE_NONE;
724     return TRUE;
725 }
726
727 /***********************************************************************
728  *              ImmGetDefaultIMEWnd (IMM32.@)
729  */
730 HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
731 {
732   FIXME("(%p - %p %p ): semi-stub\n", hWnd,hwndDefault, root_context);
733
734   if (hwndDefault == NULL)
735   {
736         static const WCHAR the_name[] = {'I','M','E','\0'};
737
738         IMM_Register();
739         hwndDefault = CreateWindowExW( WS_EX_CLIENTEDGE, WC_IMECLASSNAME,
740                 the_name, WS_POPUPWINDOW|WS_CAPTION, 0, 0, 120, 55, 0, 0,
741                 hImeInst, 0);
742
743         TRACE("Default created (0x%x)\n",(INT)hwndDefault);
744   }
745
746   return (HWND)hwndDefault;
747 }
748
749 /***********************************************************************
750  *              ImmGetDescriptionA (IMM32.@)
751  */
752 UINT WINAPI ImmGetDescriptionA(
753   HKL hKL, LPSTR lpszDescription, UINT uBufLen)
754 {
755   WCHAR *buf;
756   DWORD len;
757
758   TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
759
760   /* find out how many characters in the unicode buffer */
761   len = ImmGetDescriptionW( hKL, NULL, 0 );
762
763   /* allocate a buffer of that size */
764   buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
765   if( !buf )
766   return 0;
767
768   /* fetch the unicode buffer */
769   len = ImmGetDescriptionW( hKL, buf, len + 1 );
770
771   /* convert it back to ASCII */
772   len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
773                              lpszDescription, uBufLen, NULL, NULL );
774
775   HeapFree( GetProcessHeap(), 0, buf );
776
777   return len;
778 }
779
780 /***********************************************************************
781  *              ImmGetDescriptionW (IMM32.@)
782  */
783 UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
784 {
785   static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
786
787   FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
788
789   if (!uBufLen) return lstrlenW( name );
790   lstrcpynW( lpszDescription, name, uBufLen );
791   return lstrlenW( lpszDescription );
792 }
793
794 /***********************************************************************
795  *              ImmGetGuideLineA (IMM32.@)
796  */
797 DWORD WINAPI ImmGetGuideLineA(
798   HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
799 {
800   FIXME("(%p, %ld, %s, %ld): stub\n",
801     hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
802   );
803   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
804   return 0;
805 }
806
807 /***********************************************************************
808  *              ImmGetGuideLineW (IMM32.@)
809  */
810 DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
811 {
812   FIXME("(%p, %ld, %s, %ld): stub\n",
813     hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
814   );
815   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
816   return 0;
817 }
818
819 /***********************************************************************
820  *              ImmGetIMEFileNameA (IMM32.@)
821  */
822 UINT WINAPI ImmGetIMEFileNameA(
823   HKL hKL, LPSTR lpszFileName, UINT uBufLen)
824 {
825   FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
826   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
827   return 0;
828 }
829
830 /***********************************************************************
831  *              ImmGetIMEFileNameW (IMM32.@)
832  */
833 UINT WINAPI ImmGetIMEFileNameW(
834   HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
835 {
836   FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
837   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
838   return 0;
839 }
840
841 /***********************************************************************
842  *              ImmGetOpenStatus (IMM32.@)
843  */
844 BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
845 {
846   InputContextData *data = (InputContextData*)hIMC;
847
848     if (!data)
849         return FALSE;
850   FIXME("(%p): semi-stub\n", hIMC);
851
852   return data->bOpen;
853 }
854
855 /***********************************************************************
856  *              ImmGetProperty (IMM32.@)
857  */
858 DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
859 {
860     DWORD rc = 0;
861     TRACE("(%p, %ld)\n", hKL, fdwIndex);
862
863     switch (fdwIndex)
864     {
865         case IGP_PROPERTY:
866             TRACE("(%s)\n", "IGP_PROPERTY");
867             rc = IME_PROP_UNICODE | IME_PROP_AT_CARET;
868             break;
869         case IGP_CONVERSION:
870             FIXME("(%s)\n", "IGP_CONVERSION");
871             rc = IME_CMODE_NATIVE;
872             break;
873         case IGP_SENTENCE:
874             FIXME("%s)\n", "IGP_SENTENCE");
875             rc = IME_SMODE_AUTOMATIC;
876             break;
877         case IGP_SETCOMPSTR:
878             TRACE("(%s)\n", "IGP_SETCOMPSTR");
879             rc = 0;
880             break;
881         case IGP_SELECT:
882             TRACE("(%s)\n", "IGP_SELECT");
883             rc = SELECT_CAP_CONVERSION | SELECT_CAP_SENTENCE;
884             break;
885         case IGP_GETIMEVERSION:
886             TRACE("(%s)\n", "IGP_GETIMEVERSION");
887             rc = IMEVER_0400;
888             break;
889         case IGP_UI:
890             TRACE("(%s)\n", "IGP_UI");
891             rc = 0;
892             break;
893         default:
894             rc = 0;
895     }
896     return rc;
897 }
898
899 /***********************************************************************
900  *              ImmGetRegisterWordStyleA (IMM32.@)
901  */
902 UINT WINAPI ImmGetRegisterWordStyleA(
903   HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
904 {
905   FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
906   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
907   return 0;
908 }
909
910 /***********************************************************************
911  *              ImmGetRegisterWordStyleW (IMM32.@)
912  */
913 UINT WINAPI ImmGetRegisterWordStyleW(
914   HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
915 {
916   FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
917   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
918   return 0;
919 }
920
921 /***********************************************************************
922  *              ImmGetStatusWindowPos (IMM32.@)
923  */
924 BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
925 {
926   FIXME("(%p, %p): stub\n", hIMC, lpptPos);
927   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
928   return FALSE;
929 }
930
931 /***********************************************************************
932  *              ImmGetVirtualKey (IMM32.@)
933  */
934 UINT WINAPI ImmGetVirtualKey(HWND hWnd)
935 {
936   OSVERSIONINFOA version;
937   FIXME("(%p): stub\n", hWnd);
938   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
939   GetVersionExA( &version );
940   switch(version.dwPlatformId)
941   {
942   case VER_PLATFORM_WIN32_WINDOWS:
943       return VK_PROCESSKEY;
944   case VER_PLATFORM_WIN32_NT:
945       return 0;
946   default:
947       FIXME("%ld not supported\n",version.dwPlatformId);
948       return VK_PROCESSKEY;
949   }
950 }
951
952 /***********************************************************************
953  *              ImmInstallIMEA (IMM32.@)
954  */
955 HKL WINAPI ImmInstallIMEA(
956   LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
957 {
958   FIXME("(%s, %s): stub\n",
959     debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
960   );
961   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
962   return NULL;
963 }
964
965 /***********************************************************************
966  *              ImmInstallIMEW (IMM32.@)
967  */
968 HKL WINAPI ImmInstallIMEW(
969   LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
970 {
971   FIXME("(%s, %s): stub\n",
972     debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
973   );
974   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
975   return NULL;
976 }
977
978 /***********************************************************************
979  *              ImmIsIME (IMM32.@)
980  */
981 BOOL WINAPI ImmIsIME(HKL hKL)
982 {
983   FIXME("(%p): semi-stub\n", hKL);
984   /*
985    * Dead key locales will return TRUE here when they should not
986    * There is probably a more proper way to check this.
987    */
988   return (root_context != NULL);
989 }
990
991 /***********************************************************************
992  *              ImmIsUIMessageA (IMM32.@)
993  */
994 BOOL WINAPI ImmIsUIMessageA(
995   HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
996 {
997     BOOL rc = FALSE;
998
999     TRACE("(%p, %x, %d, %ld)\n", hWndIME, msg, wParam, lParam);
1000     if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1001         (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1002         (msg == WM_MSIME_SERVICE) ||
1003         (msg == WM_MSIME_RECONVERTOPTIONS) ||
1004         (msg == WM_MSIME_MOUSE) ||
1005         (msg == WM_MSIME_RECONVERTREQUEST) ||
1006         (msg == WM_MSIME_RECONVERT) ||
1007         (msg == WM_MSIME_QUERYPOSITION) ||
1008         (msg == WM_MSIME_DOCUMENTFEED))
1009
1010     {
1011         if (!hwndDefault)
1012             ImmGetDefaultIMEWnd(NULL);
1013
1014         if (hWndIME == NULL)
1015             PostMessageA(hwndDefault, msg, wParam, lParam);
1016
1017         rc = TRUE;
1018     }
1019     return rc;
1020 }
1021
1022 /***********************************************************************
1023  *              ImmIsUIMessageW (IMM32.@)
1024  */
1025 BOOL WINAPI ImmIsUIMessageW(
1026   HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1027 {
1028     BOOL rc = FALSE;
1029     TRACE("(%p, %d, %d, %ld): stub\n", hWndIME, msg, wParam, lParam);
1030     if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1031         (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1032         (msg == WM_MSIME_SERVICE) ||
1033         (msg == WM_MSIME_RECONVERTOPTIONS) ||
1034         (msg == WM_MSIME_MOUSE) ||
1035         (msg == WM_MSIME_RECONVERTREQUEST) ||
1036         (msg == WM_MSIME_RECONVERT) ||
1037         (msg == WM_MSIME_QUERYPOSITION) ||
1038         (msg == WM_MSIME_DOCUMENTFEED))
1039         rc = TRUE;
1040     return rc;
1041 }
1042
1043 /***********************************************************************
1044  *              ImmNotifyIME (IMM32.@)
1045  */
1046 BOOL WINAPI ImmNotifyIME(
1047   HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
1048 {
1049     BOOL rc = FALSE;
1050   FIXME("(%p, %ld, %ld, %ld): stub\n",
1051         hIMC, dwAction, dwIndex, dwValue);
1052
1053     if (!root_context)
1054         return rc;
1055
1056     switch(dwAction)
1057     {
1058         case NI_CHANGECANDIDATELIST:
1059             FIXME("%s\n","NI_CHANGECANDIDATELIST");
1060             break;
1061         case NI_CLOSECANDIDATE:
1062             FIXME("%s\n","NI_CLOSECANDIDATE");
1063             break;
1064         case NI_COMPOSITIONSTR:
1065             switch (dwIndex)
1066             {
1067                 case CPS_CANCEL:
1068                     TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL");
1069                     if (pX11DRV_ForceXIMReset)
1070                         pX11DRV_ForceXIMReset(root_context->hwnd);
1071                     if (root_context->dwCompStringSize)
1072                     {
1073                         HeapFree(GetProcessHeap(),0,
1074                                  root_context->CompositionString);
1075                         root_context->dwCompStringSize = 0;
1076                         root_context->dwCompStringLength = 0;
1077                         root_context->CompositionString = NULL;
1078                         ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
1079                                                   GCS_COMPSTR);
1080                     }
1081                     rc = TRUE;
1082                     break;
1083                 case CPS_COMPLETE:
1084                     TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_COMPLETE");
1085                     if (hIMC != (HIMC)FROM_IME && pX11DRV_ForceXIMReset)
1086                         pX11DRV_ForceXIMReset(root_context->hwnd);
1087
1088                     if (root_context->dwResultStringSize)
1089                     {
1090                         HeapFree(GetProcessHeap(),0,root_context->ResultString);
1091                         root_context->dwResultStringSize = 0;
1092                         root_context->ResultString = NULL;
1093                     }
1094                     if (root_context->dwCompStringLength)
1095                     {
1096                         root_context->ResultString = HeapAlloc(
1097                         GetProcessHeap(), 0, root_context->dwCompStringLength);
1098                         root_context->dwResultStringSize =
1099                                         root_context->dwCompStringLength;
1100
1101                         memcpy(root_context->ResultString,
1102                                root_context->CompositionString,
1103                                root_context->dwCompStringLength);
1104
1105                         HeapFree(GetProcessHeap(),0,
1106                                  root_context->CompositionString);
1107
1108                         root_context->dwCompStringSize = 0;
1109                         root_context->dwCompStringLength = 0;
1110                         root_context->CompositionString = NULL;
1111                         root_context->bRead = FALSE;
1112
1113                         ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
1114                                                   GCS_COMPSTR);
1115
1116                         ImmInternalPostIMEMessage(WM_IME_COMPOSITION,
1117                                             root_context->ResultString[0],
1118                                             GCS_RESULTSTR|GCS_RESULTCLAUSE);
1119                     }
1120                     break;
1121                 case CPS_CONVERT:
1122                     FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_CONVERT");
1123                     break;
1124                 case CPS_REVERT:
1125                     FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_REVERT");
1126                     break;
1127                 default:
1128                     ERR("%s - %s (%li)\n","NI_COMPOSITIONSTR","UNKNOWN",dwIndex);
1129                     break;
1130             }
1131             break;
1132         case NI_IMEMENUSELECTED:
1133             FIXME("%s\n", "NI_IMEMENUSELECTED");
1134             break;
1135         case NI_OPENCANDIDATE:
1136             FIXME("%s\n", "NI_OPENCANDIDATE");
1137             break;
1138         case NI_SELECTCANDIDATESTR:
1139             FIXME("%s\n", "NI_SELECTCANDIDATESTR");
1140             break;
1141         case NI_SETCANDIDATE_PAGESIZE:
1142             FIXME("%s\n", "NI_SETCANDIDATE_PAGESIZE");
1143             break;
1144         case NI_SETCANDIDATE_PAGESTART:
1145             FIXME("%s\n", "NI_SETCANDIDATE_PAGESTART");
1146             break;
1147         default:
1148             ERR("Unknown\n");
1149     }
1150   
1151     return rc;
1152 }
1153
1154 /***********************************************************************
1155  *              ImmRegisterWordA (IMM32.@)
1156  */
1157 BOOL WINAPI ImmRegisterWordA(
1158   HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
1159 {
1160   FIXME("(%p, %s, %ld, %s): stub\n",
1161     hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister)
1162   );
1163   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1164   return FALSE;
1165 }
1166
1167 /***********************************************************************
1168  *              ImmRegisterWordW (IMM32.@)
1169  */
1170 BOOL WINAPI ImmRegisterWordW(
1171   HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
1172 {
1173   FIXME("(%p, %s, %ld, %s): stub\n",
1174     hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister)
1175   );
1176   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1177   return FALSE;
1178 }
1179
1180 /***********************************************************************
1181  *              ImmReleaseContext (IMM32.@)
1182  */
1183 BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1184 {
1185   FIXME("(%p, %p): stub\n", hWnd, hIMC);
1186
1187     return TRUE;
1188 }
1189
1190 /***********************************************************************
1191  *              ImmSetCandidateWindow (IMM32.@)
1192  */
1193 BOOL WINAPI ImmSetCandidateWindow(
1194   HIMC hIMC, LPCANDIDATEFORM lpCandidate)
1195 {
1196   FIXME("(%p, %p): stub\n", hIMC, lpCandidate);
1197   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1198   return FALSE;
1199 }
1200
1201 /***********************************************************************
1202  *              ImmSetCompositionFontA (IMM32.@)
1203  */
1204 BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
1205 {
1206     InputContextData *data = (InputContextData*)hIMC;
1207     TRACE("(%p, %p)\n", hIMC, lplf);
1208
1209     if (!data)
1210         return FALSE;
1211
1212     memcpy(&data->font,lplf,sizeof(LOGFONTA));
1213     MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->font.lfFaceName,
1214                         LF_FACESIZE);
1215
1216     SendMessageW(root_context->hwnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONFONT, 0);
1217
1218     if (data->textfont)
1219     {
1220         DeleteObject(data->textfont);
1221         data->textfont = NULL;
1222     }
1223
1224     data->textfont = CreateFontIndirectW(&data->font); 
1225     return TRUE;
1226 }
1227
1228 /***********************************************************************
1229  *              ImmSetCompositionFontW (IMM32.@)
1230  */
1231 BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
1232 {
1233     InputContextData *data = (InputContextData*)hIMC;
1234     TRACE("(%p, %p)\n", hIMC, lplf);
1235
1236     if (!data)
1237         return FALSE;
1238
1239     memcpy(&data->font,lplf,sizeof(LOGFONTW));
1240     SendMessageW(root_context->hwnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONFONT, 0);
1241
1242     if (data->textfont)
1243     {
1244         DeleteObject(data->textfont);
1245         data->textfont = NULL;
1246     }
1247     data->textfont = CreateFontIndirectW(&data->font); 
1248     return TRUE;
1249 }
1250
1251 /***********************************************************************
1252  *              ImmSetCompositionStringA (IMM32.@)
1253  */
1254 BOOL WINAPI ImmSetCompositionStringA(
1255   HIMC hIMC, DWORD dwIndex,
1256   LPCVOID lpComp, DWORD dwCompLen,
1257   LPCVOID lpRead, DWORD dwReadLen)
1258 {
1259     DWORD comp_len;
1260     DWORD read_len;
1261     WCHAR *CompBuffer = NULL;
1262     WCHAR *ReadBuffer = NULL;
1263     BOOL rc;
1264
1265     TRACE("(%p, %ld, %p, %ld, %p, %ld): stub\n",
1266             hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1267
1268     comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
1269     if (comp_len)
1270     {
1271         CompBuffer = (WCHAR*)HeapAlloc(GetProcessHeap(),0,comp_len * sizeof(WCHAR));
1272         MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len);
1273     }
1274
1275     read_len = MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, NULL, 0);
1276     if (read_len)
1277     {
1278         ReadBuffer = (WCHAR*)HeapAlloc(GetProcessHeap(),0,read_len * sizeof(WCHAR));
1279         MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len);
1280     }
1281
1282     rc =  ImmSetCompositionStringW(hIMC, dwIndex, CompBuffer, comp_len,
1283                                    ReadBuffer, read_len);
1284
1285     if (CompBuffer)
1286         HeapFree(GetProcessHeap(), 0, CompBuffer);
1287
1288     if (ReadBuffer)
1289         HeapFree(GetProcessHeap(), 0, ReadBuffer);
1290
1291     return rc;
1292 }
1293
1294 /***********************************************************************
1295  *              ImmSetCompositionStringW (IMM32.@)
1296  */
1297 BOOL WINAPI ImmSetCompositionStringW(
1298         HIMC hIMC, DWORD dwIndex,
1299         LPCVOID lpComp, DWORD dwCompLen,
1300         LPCVOID lpRead, DWORD dwReadLen)
1301 {
1302      DWORD flags = 0;
1303      WCHAR wParam  = 0;
1304
1305      TRACE("(%p, %ld, %p, %ld, %p, %ld): stub\n",
1306              hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1307
1308
1309      if (hIMC != (HIMC)FROM_IME)
1310          FIXME("PROBLEM: This only sets the wine level string\n");
1311
1312      /*
1313       * Explanation:
1314       *  this sets the composition string in the imm32.dll level
1315       *  of the composition buffer. we cannot manipulate the xim level
1316       *  buffer, which means that once the xim level buffer changes again
1317       *  any call to this function from the application will be lost
1318       */
1319
1320      if (lpRead && dwReadLen)
1321          FIXME("Reading string unimplemented\n");
1322
1323      /*
1324       * app operating this api to also receive the message from xim
1325       */
1326
1327     if (dwIndex == SCS_SETSTR)
1328     {
1329          flags = GCS_COMPSTR;
1330
1331          if (root_context->dwCompStringLength)
1332              HeapFree(GetProcessHeap(),0,root_context->CompositionString);
1333
1334          root_context->dwCompStringLength = dwCompLen;
1335          root_context->dwCompStringSize = dwCompLen;
1336
1337          if (dwCompLen && lpComp)
1338          {
1339              root_context->CompositionString = HeapAlloc(GetProcessHeap(), 0,
1340                                                      dwCompLen);
1341              memcpy(root_context->CompositionString,lpComp,dwCompLen);
1342
1343              wParam = ((WCHAR*)lpComp)[0];
1344              flags |= GCS_COMPCLAUSE | GCS_COMPATTR;
1345          }
1346          else
1347              root_context->CompositionString = NULL;
1348
1349     }
1350
1351      UpdateDataInDefaultIMEWindow(hwndDefault);
1352
1353      ImmInternalPostIMEMessage(WM_IME_COMPOSITION, wParam, flags);
1354
1355      return TRUE;
1356 }
1357
1358 /***********************************************************************
1359  *              ImmSetCompositionWindow (IMM32.@)
1360  */
1361 BOOL WINAPI ImmSetCompositionWindow(
1362   HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
1363 {
1364     BOOL reshow = FALSE;
1365     InputContextData *data = (InputContextData*)hIMC;
1366
1367     TRACE("(%p, %p)\n", hIMC, lpCompForm);
1368     TRACE("\t%lx, (%li,%li), (%li,%li - %li,%li)\n",lpCompForm->dwStyle,
1369           lpCompForm->ptCurrentPos.x, lpCompForm->ptCurrentPos.y, lpCompForm->rcArea.top,
1370           lpCompForm->rcArea.left, lpCompForm->rcArea.bottom, lpCompForm->rcArea.right);
1371
1372     if (!data)
1373         return FALSE;
1374
1375     memcpy(&data->CompForm,lpCompForm,sizeof(COMPOSITIONFORM));
1376
1377     if (IsWindowVisible(hwndDefault))
1378     {
1379         reshow = TRUE;
1380         ShowWindow(hwndDefault,SW_HIDE);
1381     }
1382
1383     FIXME("STUB\n");
1384
1385     if (reshow)
1386         ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
1387
1388     SendMessageW(root_context->hwnd, WM_IME_NOTIFY,IMN_SETCOMPOSITIONWINDOW, 0);
1389     return TRUE;
1390 }
1391
1392 /***********************************************************************
1393  *              ImmSetConversionStatus (IMM32.@)
1394  */
1395 BOOL WINAPI ImmSetConversionStatus(
1396   HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
1397 {
1398   FIXME("(%p, %ld, %ld): stub\n",
1399     hIMC, fdwConversion, fdwSentence
1400   );
1401   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1402   return FALSE;
1403 }
1404
1405 /***********************************************************************
1406  *              ImmSetOpenStatus (IMM32.@)
1407  */
1408 BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
1409 {
1410     InputContextData *data = (InputContextData*)hIMC;
1411     FIXME("Semi-Stub\n");
1412
1413     if (hIMC == (HIMC)FROM_IME)
1414     {
1415         if (fOpen)
1416             ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION, 0, 0);
1417
1418         ImmInternalSetOpenStatus(fOpen);
1419
1420         if (!fOpen)
1421             ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0);
1422
1423         return TRUE;
1424     }
1425
1426     if (!data)
1427         return FALSE;
1428
1429     if (fOpen != data->bInternalState)
1430     {
1431         if (fOpen == FALSE && pX11DRV_ForceXIMReset)
1432             pX11DRV_ForceXIMReset(data->hwnd);
1433
1434         if (fOpen == FALSE)
1435             ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
1436         else
1437             ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
1438
1439         ImmInternalSetOpenStatus(fOpen);
1440         ImmInternalSetOpenStatus(!fOpen);
1441
1442         if (data->bOpen == FALSE)
1443             ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
1444         else
1445             ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
1446
1447         return FALSE;
1448     }
1449     return TRUE;
1450 }
1451
1452 /***********************************************************************
1453  *              ImmSetStatusWindowPos (IMM32.@)
1454  */
1455 BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1456 {
1457   FIXME("(%p, %p): stub\n", hIMC, lpptPos);
1458   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1459   return FALSE;
1460 }
1461
1462 /***********************************************************************
1463  *              ImmSimulateHotKey (IMM32.@)
1464  */
1465 BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
1466 {
1467   FIXME("(%p, %ld): stub\n", hWnd, dwHotKeyID);
1468   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1469   return FALSE;
1470 }
1471
1472 /***********************************************************************
1473  *              ImmUnregisterWordA (IMM32.@)
1474  */
1475 BOOL WINAPI ImmUnregisterWordA(
1476   HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
1477 {
1478   FIXME("(%p, %s, %ld, %s): stub\n",
1479     hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister)
1480   );
1481   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1482   return FALSE;
1483 }
1484
1485 /***********************************************************************
1486  *              ImmUnregisterWordW (IMM32.@)
1487  */
1488 BOOL WINAPI ImmUnregisterWordW(
1489   HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
1490 {
1491   FIXME("(%p, %s, %ld, %s): stub\n",
1492     hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister)
1493   );
1494   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1495   return FALSE;
1496 }
1497
1498
1499 /*****
1500  * Internal functions to help with IME window management
1501  */
1502 static void PaintDefaultIMEWnd(HWND hwnd)
1503 {
1504     PAINTSTRUCT ps;
1505     RECT rect;
1506     HDC hdc = BeginPaint(hwnd,&ps);
1507     GetClientRect(hwnd,&rect);
1508
1509     if (root_context->dwCompStringLength && root_context->CompositionString)
1510     {
1511         SIZE size;
1512         POINT pt;
1513         HFONT oldfont = NULL;
1514
1515         if (root_context->textfont)
1516             oldfont = SelectObject(hdc,root_context->textfont);
1517
1518         TextOutW(hdc, 0,0,(LPWSTR)root_context->CompositionString,
1519                  root_context->dwCompStringLength / sizeof(WCHAR));
1520
1521         GetTextExtentPoint32W(hdc, (LPWSTR)root_context->CompositionString,
1522                               root_context->dwCompStringLength / sizeof(WCHAR),
1523                               &size);
1524         pt.x = size.cx;
1525         pt.y = size.cy;
1526         LPtoDP(hdc,&pt,1);
1527         rect.left = pt.x;
1528
1529         if (oldfont)
1530             SelectObject(hdc,oldfont);
1531     }
1532     FillRect(hdc,&rect, (HBRUSH) (COLOR_WINDOW+1));
1533     EndPaint(hwnd,&ps);
1534 }
1535
1536 static void UpdateDataInDefaultIMEWindow(HWND hwnd)
1537 {
1538     RedrawWindow(hwnd,NULL,NULL,RDW_ERASENOW|RDW_INVALIDATE);
1539 }
1540
1541 /*
1542  * The window proc for the default IME window
1543  */
1544 static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
1545                                           LPARAM lParam)
1546 {
1547     LRESULT rc = 0;
1548
1549     TRACE("Incoming Message 0x%x  (0x%08x, 0x%08x)\n", msg, (UINT)wParam,
1550            (UINT)lParam);
1551
1552     switch(msg)
1553     {
1554         case WM_PAINT:
1555             PaintDefaultIMEWnd(hwnd);
1556             return FALSE;
1557
1558         case WM_NCCREATE:
1559             return TRUE;
1560
1561         case WM_CREATE:
1562             SetWindowTextA(hwnd,"Wine Ime Active");
1563             return TRUE;
1564
1565         case WM_SETFOCUS:
1566             if (wParam)
1567                 SetFocus((HWND)wParam);
1568             else
1569                 FIXME("Received focus, should never have focus\n");
1570             break;
1571         case WM_IME_COMPOSITION:
1572             TRACE("IME message %s, 0x%x, 0x%x (%i)\n",
1573                     "WM_IME_COMPOSITION", (UINT)wParam, (UINT)lParam,
1574                      root_context->bRead);
1575             if ((lParam & GCS_RESULTSTR) && (!root_context->bRead))
1576                     IMM_PostResult(root_context);
1577             else
1578                  UpdateDataInDefaultIMEWindow(hwnd);
1579             break;
1580         case WM_IME_STARTCOMPOSITION:
1581             TRACE("IME message %s, 0x%x, 0x%x\n",
1582                     "WM_IME_STARTCOMPOSITION", (UINT)wParam, (UINT)lParam);
1583             root_context->hwnd = GetFocus();
1584             ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
1585             break;
1586         case WM_IME_ENDCOMPOSITION:
1587             TRACE("IME message %s, 0x%x, 0x%x\n",
1588                     "WM_IME_ENDCOMPOSITION", (UINT)wParam, (UINT)lParam);
1589             ShowWindow(hwndDefault,SW_HIDE);
1590             break;
1591         case WM_IME_SELECT:
1592             TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_SELECT",
1593                 (UINT)wParam, (UINT)lParam);
1594             break;
1595         case WM_IME_CONTROL:
1596             TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_CONTROL",
1597                 (UINT)wParam, (UINT)lParam);
1598             rc = 1; 
1599             break;
1600         case WM_IME_NOTIFY:
1601             TRACE("!! IME NOTIFY\n");
1602             break;
1603        default:
1604             TRACE("Non-standard message 0x%x\n",msg);
1605     }
1606     /* check the MSIME messages */
1607     if (msg == WM_MSIME_SERVICE)
1608     {
1609             TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_SERVICE",
1610                 (UINT)wParam, (UINT)lParam);
1611             rc = FALSE;
1612     }
1613     else if (msg == WM_MSIME_RECONVERTOPTIONS)
1614     {
1615             TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTOPTIONS",
1616                 (UINT)wParam, (UINT)lParam);
1617     }
1618     else if (msg == WM_MSIME_MOUSE)
1619     {
1620             TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_MOUSE",
1621                 (UINT)wParam, (UINT)lParam);
1622     }
1623     else if (msg == WM_MSIME_RECONVERTREQUEST)
1624     {
1625             TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTREQUEST",
1626                 (UINT)wParam, (UINT)lParam);
1627     }
1628     else if (msg == WM_MSIME_RECONVERT)
1629     {
1630             TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERT",
1631                 (UINT)wParam, (UINT)lParam);
1632     }
1633     else if (msg == WM_MSIME_QUERYPOSITION)
1634     {
1635             TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_QUERYPOSITION",
1636                 (UINT)wParam, (UINT)lParam);
1637     }
1638     else if (msg == WM_MSIME_DOCUMENTFEED)
1639     {
1640             TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_DOCUMENTFEED",
1641                 (UINT)wParam, (UINT)lParam);
1642     }
1643     /* DefWndProc if not an IME message */
1644     else if (!rc && !((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1645                       (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP)))
1646         rc = DefWindowProcW(hwnd,msg,wParam,lParam);
1647
1648     return rc;
1649 }