reshuffling of dlls
[reactos.git] / reactos / dll / 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("winex11.drv");
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 (%p)\n",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 TRACE("(%p): semi-stub\n", hKL);
984 /*
985 * FIXME: 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 = 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 = 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 HeapFree(GetProcessHeap(), 0, CompBuffer);
1286 HeapFree(GetProcessHeap(), 0, ReadBuffer);
1287
1288 return rc;
1289 }
1290
1291 /***********************************************************************
1292 * ImmSetCompositionStringW (IMM32.@)
1293 */
1294 BOOL WINAPI ImmSetCompositionStringW(
1295 HIMC hIMC, DWORD dwIndex,
1296 LPCVOID lpComp, DWORD dwCompLen,
1297 LPCVOID lpRead, DWORD dwReadLen)
1298 {
1299 DWORD flags = 0;
1300 WCHAR wParam = 0;
1301
1302 TRACE("(%p, %ld, %p, %ld, %p, %ld): stub\n",
1303 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1304
1305
1306 if (hIMC != (HIMC)FROM_IME)
1307 FIXME("PROBLEM: This only sets the wine level string\n");
1308
1309 /*
1310 * Explanation:
1311 * this sets the composition string in the imm32.dll level
1312 * of the composition buffer. we cannot manipulate the xim level
1313 * buffer, which means that once the xim level buffer changes again
1314 * any call to this function from the application will be lost
1315 */
1316
1317 if (lpRead && dwReadLen)
1318 FIXME("Reading string unimplemented\n");
1319
1320 /*
1321 * app operating this api to also receive the message from xim
1322 */
1323
1324 if (dwIndex == SCS_SETSTR)
1325 {
1326 flags = GCS_COMPSTR;
1327
1328 if (root_context->dwCompStringLength)
1329 HeapFree(GetProcessHeap(),0,root_context->CompositionString);
1330
1331 root_context->dwCompStringLength = dwCompLen;
1332 root_context->dwCompStringSize = dwCompLen;
1333
1334 if (dwCompLen && lpComp)
1335 {
1336 root_context->CompositionString = HeapAlloc(GetProcessHeap(), 0,
1337 dwCompLen);
1338 memcpy(root_context->CompositionString,lpComp,dwCompLen);
1339
1340 wParam = ((const WCHAR*)lpComp)[0];
1341 flags |= GCS_COMPCLAUSE | GCS_COMPATTR;
1342 }
1343 else
1344 root_context->CompositionString = NULL;
1345
1346 }
1347
1348 UpdateDataInDefaultIMEWindow(hwndDefault);
1349
1350 ImmInternalPostIMEMessage(WM_IME_COMPOSITION, wParam, flags);
1351
1352 return TRUE;
1353 }
1354
1355 /***********************************************************************
1356 * ImmSetCompositionWindow (IMM32.@)
1357 */
1358 BOOL WINAPI ImmSetCompositionWindow(
1359 HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
1360 {
1361 BOOL reshow = FALSE;
1362 InputContextData *data = (InputContextData*)hIMC;
1363
1364 TRACE("(%p, %p)\n", hIMC, lpCompForm);
1365 TRACE("\t%lx, (%li,%li), (%li,%li - %li,%li)\n",lpCompForm->dwStyle,
1366 lpCompForm->ptCurrentPos.x, lpCompForm->ptCurrentPos.y, lpCompForm->rcArea.top,
1367 lpCompForm->rcArea.left, lpCompForm->rcArea.bottom, lpCompForm->rcArea.right);
1368
1369 if (!data)
1370 return FALSE;
1371
1372 memcpy(&data->CompForm,lpCompForm,sizeof(COMPOSITIONFORM));
1373
1374 if (IsWindowVisible(hwndDefault))
1375 {
1376 reshow = TRUE;
1377 ShowWindow(hwndDefault,SW_HIDE);
1378 }
1379
1380 FIXME("STUB\n");
1381
1382 if (reshow)
1383 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
1384
1385 SendMessageW(root_context->hwnd, WM_IME_NOTIFY,IMN_SETCOMPOSITIONWINDOW, 0);
1386 return TRUE;
1387 }
1388
1389 /***********************************************************************
1390 * ImmSetConversionStatus (IMM32.@)
1391 */
1392 BOOL WINAPI ImmSetConversionStatus(
1393 HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
1394 {
1395 FIXME("(%p, %ld, %ld): stub\n",
1396 hIMC, fdwConversion, fdwSentence
1397 );
1398 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1399 return FALSE;
1400 }
1401
1402 /***********************************************************************
1403 * ImmSetOpenStatus (IMM32.@)
1404 */
1405 BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
1406 {
1407 InputContextData *data = (InputContextData*)hIMC;
1408 FIXME("Semi-Stub\n");
1409
1410 if (hIMC == (HIMC)FROM_IME)
1411 {
1412 if (fOpen)
1413 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION, 0, 0);
1414
1415 ImmInternalSetOpenStatus(fOpen);
1416
1417 if (!fOpen)
1418 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0);
1419
1420 return TRUE;
1421 }
1422
1423 if (!data)
1424 return FALSE;
1425
1426 if (fOpen != data->bInternalState)
1427 {
1428 if (fOpen == FALSE && pX11DRV_ForceXIMReset)
1429 pX11DRV_ForceXIMReset(data->hwnd);
1430
1431 if (fOpen == FALSE)
1432 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
1433 else
1434 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
1435
1436 ImmInternalSetOpenStatus(fOpen);
1437 ImmInternalSetOpenStatus(!fOpen);
1438
1439 if (data->bOpen == FALSE)
1440 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
1441 else
1442 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
1443
1444 return FALSE;
1445 }
1446 return TRUE;
1447 }
1448
1449 /***********************************************************************
1450 * ImmSetStatusWindowPos (IMM32.@)
1451 */
1452 BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1453 {
1454 FIXME("(%p, %p): stub\n", hIMC, lpptPos);
1455 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1456 return FALSE;
1457 }
1458
1459 /***********************************************************************
1460 * ImmSimulateHotKey (IMM32.@)
1461 */
1462 BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
1463 {
1464 FIXME("(%p, %ld): stub\n", hWnd, dwHotKeyID);
1465 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1466 return FALSE;
1467 }
1468
1469 /***********************************************************************
1470 * ImmUnregisterWordA (IMM32.@)
1471 */
1472 BOOL WINAPI ImmUnregisterWordA(
1473 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
1474 {
1475 FIXME("(%p, %s, %ld, %s): stub\n",
1476 hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister)
1477 );
1478 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1479 return FALSE;
1480 }
1481
1482 /***********************************************************************
1483 * ImmUnregisterWordW (IMM32.@)
1484 */
1485 BOOL WINAPI ImmUnregisterWordW(
1486 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
1487 {
1488 FIXME("(%p, %s, %ld, %s): stub\n",
1489 hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister)
1490 );
1491 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1492 return FALSE;
1493 }
1494
1495
1496 /*****
1497 * Internal functions to help with IME window management
1498 */
1499 static void PaintDefaultIMEWnd(HWND hwnd)
1500 {
1501 PAINTSTRUCT ps;
1502 RECT rect;
1503 HDC hdc = BeginPaint(hwnd,&ps);
1504 GetClientRect(hwnd,&rect);
1505
1506 if (root_context->dwCompStringLength && root_context->CompositionString)
1507 {
1508 SIZE size;
1509 POINT pt;
1510 HFONT oldfont = NULL;
1511
1512 if (root_context->textfont)
1513 oldfont = SelectObject(hdc,root_context->textfont);
1514
1515 TextOutW(hdc, 0,0,(LPWSTR)root_context->CompositionString,
1516 root_context->dwCompStringLength / sizeof(WCHAR));
1517
1518 GetTextExtentPoint32W(hdc, (LPWSTR)root_context->CompositionString,
1519 root_context->dwCompStringLength / sizeof(WCHAR),
1520 &size);
1521 pt.x = size.cx;
1522 pt.y = size.cy;
1523 LPtoDP(hdc,&pt,1);
1524 rect.left = pt.x;
1525
1526 if (oldfont)
1527 SelectObject(hdc,oldfont);
1528 }
1529 FillRect(hdc,&rect, (HBRUSH) (COLOR_WINDOW+1));
1530 EndPaint(hwnd,&ps);
1531 }
1532
1533 static void UpdateDataInDefaultIMEWindow(HWND hwnd)
1534 {
1535 RedrawWindow(hwnd,NULL,NULL,RDW_ERASENOW|RDW_INVALIDATE);
1536 }
1537
1538 /*
1539 * The window proc for the default IME window
1540 */
1541 static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
1542 LPARAM lParam)
1543 {
1544 LRESULT rc = 0;
1545
1546 TRACE("Incoming Message 0x%x (0x%08x, 0x%08x)\n", msg, (UINT)wParam,
1547 (UINT)lParam);
1548
1549 switch(msg)
1550 {
1551 case WM_PAINT:
1552 PaintDefaultIMEWnd(hwnd);
1553 return FALSE;
1554
1555 case WM_NCCREATE:
1556 return TRUE;
1557
1558 case WM_CREATE:
1559 SetWindowTextA(hwnd,"Wine Ime Active");
1560 return TRUE;
1561
1562 case WM_SETFOCUS:
1563 if (wParam)
1564 SetFocus((HWND)wParam);
1565 else
1566 FIXME("Received focus, should never have focus\n");
1567 break;
1568 case WM_IME_COMPOSITION:
1569 TRACE("IME message %s, 0x%x, 0x%x (%i)\n",
1570 "WM_IME_COMPOSITION", (UINT)wParam, (UINT)lParam,
1571 root_context->bRead);
1572 if ((lParam & GCS_RESULTSTR) && (!root_context->bRead))
1573 IMM_PostResult(root_context);
1574 else
1575 UpdateDataInDefaultIMEWindow(hwnd);
1576 break;
1577 case WM_IME_STARTCOMPOSITION:
1578 TRACE("IME message %s, 0x%x, 0x%x\n",
1579 "WM_IME_STARTCOMPOSITION", (UINT)wParam, (UINT)lParam);
1580 root_context->hwnd = GetFocus();
1581 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
1582 break;
1583 case WM_IME_ENDCOMPOSITION:
1584 TRACE("IME message %s, 0x%x, 0x%x\n",
1585 "WM_IME_ENDCOMPOSITION", (UINT)wParam, (UINT)lParam);
1586 ShowWindow(hwndDefault,SW_HIDE);
1587 break;
1588 case WM_IME_SELECT:
1589 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_SELECT",
1590 (UINT)wParam, (UINT)lParam);
1591 break;
1592 case WM_IME_CONTROL:
1593 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_CONTROL",
1594 (UINT)wParam, (UINT)lParam);
1595 rc = 1;
1596 break;
1597 case WM_IME_NOTIFY:
1598 TRACE("!! IME NOTIFY\n");
1599 break;
1600 default:
1601 TRACE("Non-standard message 0x%x\n",msg);
1602 }
1603 /* check the MSIME messages */
1604 if (msg == WM_MSIME_SERVICE)
1605 {
1606 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_SERVICE",
1607 (UINT)wParam, (UINT)lParam);
1608 rc = FALSE;
1609 }
1610 else if (msg == WM_MSIME_RECONVERTOPTIONS)
1611 {
1612 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTOPTIONS",
1613 (UINT)wParam, (UINT)lParam);
1614 }
1615 else if (msg == WM_MSIME_MOUSE)
1616 {
1617 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_MOUSE",
1618 (UINT)wParam, (UINT)lParam);
1619 }
1620 else if (msg == WM_MSIME_RECONVERTREQUEST)
1621 {
1622 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTREQUEST",
1623 (UINT)wParam, (UINT)lParam);
1624 }
1625 else if (msg == WM_MSIME_RECONVERT)
1626 {
1627 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERT",
1628 (UINT)wParam, (UINT)lParam);
1629 }
1630 else if (msg == WM_MSIME_QUERYPOSITION)
1631 {
1632 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_QUERYPOSITION",
1633 (UINT)wParam, (UINT)lParam);
1634 }
1635 else if (msg == WM_MSIME_DOCUMENTFEED)
1636 {
1637 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_DOCUMENTFEED",
1638 (UINT)wParam, (UINT)lParam);
1639 }
1640 /* DefWndProc if not an IME message */
1641 else if (!rc && !((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1642 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP)))
1643 rc = DefWindowProcW(hwnd,msg,wParam,lParam);
1644
1645 return rc;
1646 }