push 649ef288af5d6e2bc91d3ec4d104a0c9bf084d22
[wine/hacks.git] / dlls / imm32 / imm.c
blobde217d13c3d7d038ee7480e5392cfae292341cf4
1 /*
2 * IMM32 library
4 * Copyright 1998 Patrik Stridvall
5 * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
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 "ddk/imm.h"
32 #include "winnls.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(imm);
36 #define FROM_IME 0xcafe1337
38 static void (*pX11DRV_ForceXIMReset)(HWND);
40 typedef struct tagIMCCInternal
42 DWORD dwLock;
43 DWORD dwSize;
44 } IMCCInternal;
46 typedef struct tagInputContextData
48 BOOL bInternalState;
49 BOOL bRead;
50 BOOL bInComposition;
51 HFONT textfont;
53 DWORD dwLock;
54 INPUTCONTEXT IMC;
55 } InputContextData;
57 typedef struct _tagTRANSMSG {
58 UINT message;
59 WPARAM wParam;
60 LPARAM lParam;
61 } TRANSMSG, *LPTRANSMSG;
63 static InputContextData *root_context = NULL;
64 static HWND hwndDefault = NULL;
65 static HANDLE hImeInst;
66 static const WCHAR WC_IMECLASSNAME[] = {'I','M','E',0};
67 static ATOM atIMEClass = 0;
69 /* MSIME messages */
70 static UINT WM_MSIME_SERVICE;
71 static UINT WM_MSIME_RECONVERTOPTIONS;
72 static UINT WM_MSIME_MOUSE;
73 static UINT WM_MSIME_RECONVERTREQUEST;
74 static UINT WM_MSIME_RECONVERT;
75 static UINT WM_MSIME_QUERYPOSITION;
76 static UINT WM_MSIME_DOCUMENTFEED;
79 * prototypes
81 static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
82 LPARAM lParam);
83 static void UpdateDataInDefaultIMEWindow(HWND hwnd, BOOL showable);
84 static void ImmInternalPostIMEMessage(UINT, WPARAM, LPARAM);
85 static void ImmInternalSetOpenStatus(BOOL fOpen);
86 static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len);
88 static VOID IMM_PostResult(InputContextData *data)
90 unsigned int i;
91 LPCOMPOSITIONSTRING compstr;
92 LPBYTE compdata;
93 LPWSTR ResultStr;
94 HIMCC newCompStr;
96 TRACE("Posting result as IME_CHAR\n");
97 compdata = ImmLockIMCC(root_context->IMC.hCompStr);
98 compstr = (LPCOMPOSITIONSTRING)compdata;
99 ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
101 for (i = 0; i < compstr->dwResultStrLen; i++)
102 ImmInternalPostIMEMessage (WM_IME_CHAR, ResultStr[i], 1);
104 ImmUnlockIMCC(root_context->IMC.hCompStr);
106 /* clear the buffer */
107 newCompStr = updateResultStr(root_context->IMC.hCompStr, NULL, 0);
108 ImmDestroyIMCC(root_context->IMC.hCompStr);
109 root_context->IMC.hCompStr = newCompStr;
112 static void IMM_Register(void)
114 WNDCLASSW wndClass;
115 ZeroMemory(&wndClass, sizeof(WNDCLASSW));
116 wndClass.style = CS_GLOBALCLASS | CS_IME | CS_HREDRAW | CS_VREDRAW;
117 wndClass.lpfnWndProc = (WNDPROC) IME_WindowProc;
118 wndClass.cbClsExtra = 0;
119 wndClass.cbWndExtra = 0;
120 wndClass.hInstance = hImeInst;
121 wndClass.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
122 wndClass.hIcon = NULL;
123 wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
124 wndClass.lpszMenuName = 0;
125 wndClass.lpszClassName = WC_IMECLASSNAME;
126 atIMEClass = RegisterClassW(&wndClass);
129 static void IMM_Unregister(void)
131 if (atIMEClass) {
132 UnregisterClassW(WC_IMECLASSNAME, NULL);
136 static void IMM_RegisterMessages(void)
138 WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
139 WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
140 WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
141 WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
142 WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
143 WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
144 WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
148 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
150 HMODULE x11drv;
152 TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
153 switch (fdwReason)
155 case DLL_PROCESS_ATTACH:
156 DisableThreadLibraryCalls(hInstDLL);
157 hImeInst = hInstDLL;
158 IMM_RegisterMessages();
159 x11drv = GetModuleHandleA("winex11.drv");
160 if (x11drv) pX11DRV_ForceXIMReset = (void *)GetProcAddress( x11drv, "ForceXIMReset");
161 break;
162 case DLL_PROCESS_DETACH:
163 if (hwndDefault)
165 DestroyWindow(hwndDefault);
166 hwndDefault = 0;
168 IMM_Unregister();
169 break;
171 return TRUE;
174 /* for posting messages as the IME */
175 static void ImmInternalPostIMEMessage(UINT msg, WPARAM wParam, LPARAM lParam)
177 HWND target = GetFocus();
178 if (!target)
179 PostMessageW(root_context->IMC.hWnd,msg,wParam,lParam);
180 else
181 PostMessageW(target, msg, wParam, lParam);
184 static LRESULT ImmInternalSendIMENotify(WPARAM notify, LPARAM lParam)
186 HWND target;
188 target = root_context->IMC.hWnd;
189 if (!target) target = GetFocus();
191 if (target)
192 return SendMessageW(target, WM_IME_NOTIFY, notify, lParam);
194 return 0;
197 static HIMCC ImmCreateBlankCompStr(void)
199 HIMCC rc;
200 LPCOMPOSITIONSTRING ptr;
201 rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
202 ptr = (LPCOMPOSITIONSTRING)ImmLockIMCC(rc);
203 memset(ptr,0,sizeof(COMPOSITIONSTRING));
204 ptr->dwSize = sizeof(COMPOSITIONSTRING);
205 ImmUnlockIMCC(rc);
206 return rc;
209 static void ImmInternalSetOpenStatus(BOOL fOpen)
211 TRACE("Setting internal state to %s\n",(fOpen)?"OPEN":"CLOSED");
213 if (root_context->IMC.fOpen && fOpen == FALSE)
215 ShowWindow(hwndDefault,SW_HIDE);
216 ImmDestroyIMCC(root_context->IMC.hCompStr);
217 root_context->IMC.hCompStr = ImmCreateBlankCompStr();
220 root_context->IMC.fOpen = fOpen;
221 root_context->bInternalState = fOpen;
223 ImmInternalSendIMENotify(IMN_SETOPENSTATUS, 0);
226 static int updateField(DWORD origLen, DWORD origOffset, DWORD currentOffset,
227 LPBYTE target, LPBYTE source, DWORD* lenParam,
228 DWORD* offsetParam, BOOL wchars )
230 if (origLen > 0 && origOffset > 0)
232 int truelen = origLen;
233 if (wchars)
234 truelen *= sizeof(WCHAR);
236 memcpy(&target[currentOffset], &source[origOffset], truelen);
238 *lenParam = origLen;
239 *offsetParam = currentOffset;
240 currentOffset += truelen;
242 return currentOffset;
245 static HIMCC updateCompStr(HIMCC old, LPWSTR compstr, DWORD len)
247 /* we need to make sure the CompStr, CompClaus and CompAttr fields are all
248 * set and correct */
249 int needed_size;
250 HIMCC rc;
251 LPBYTE newdata = NULL;
252 LPBYTE olddata = NULL;
253 LPCOMPOSITIONSTRING new_one;
254 LPCOMPOSITIONSTRING lpcs = NULL;
255 INT current_offset = 0;
257 TRACE("%s, %i\n",debugstr_wn(compstr,len),len);
259 if (old == NULL && compstr == NULL && len == 0)
260 return NULL;
262 if (old != NULL)
264 olddata = ImmLockIMCC(old);
265 lpcs = (LPCOMPOSITIONSTRING)olddata;
268 needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
269 len + sizeof(DWORD) * 2;
271 if (lpcs != NULL)
273 needed_size += lpcs->dwCompReadAttrLen;
274 needed_size += lpcs->dwCompReadClauseLen;
275 needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
276 needed_size += lpcs->dwResultReadClauseLen;
277 needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
278 needed_size += lpcs->dwResultClauseLen;
279 needed_size += lpcs->dwResultStrLen * sizeof(DWORD);
280 needed_size += lpcs->dwPrivateSize;
282 rc = ImmCreateIMCC(needed_size);
283 newdata = ImmLockIMCC(rc);
284 new_one = (LPCOMPOSITIONSTRING)newdata;
286 new_one->dwSize = needed_size;
287 current_offset = sizeof(COMPOSITIONSTRING);
288 if (lpcs != NULL)
290 current_offset = updateField(lpcs->dwCompReadAttrLen,
291 lpcs->dwCompReadAttrOffset,
292 current_offset, newdata, olddata,
293 &new_one->dwCompReadAttrLen,
294 &new_one->dwCompReadAttrOffset, FALSE);
296 current_offset = updateField(lpcs->dwCompReadClauseLen,
297 lpcs->dwCompReadClauseOffset,
298 current_offset, newdata, olddata,
299 &new_one->dwCompReadClauseLen,
300 &new_one->dwCompReadClauseOffset, FALSE);
302 current_offset = updateField(lpcs->dwCompReadStrLen,
303 lpcs->dwCompReadStrOffset,
304 current_offset, newdata, olddata,
305 &new_one->dwCompReadStrLen,
306 &new_one->dwCompReadStrOffset, TRUE);
308 /* new CompAttr, CompClause, CompStr, dwCursorPos */
309 new_one->dwDeltaStart = 0;
311 current_offset = updateField(lpcs->dwResultReadClauseLen,
312 lpcs->dwResultReadClauseOffset,
313 current_offset, newdata, olddata,
314 &new_one->dwResultReadClauseLen,
315 &new_one->dwResultReadClauseOffset, FALSE);
317 current_offset = updateField(lpcs->dwResultReadStrLen,
318 lpcs->dwResultReadStrOffset,
319 current_offset, newdata, olddata,
320 &new_one->dwResultReadStrLen,
321 &new_one->dwResultReadStrOffset, TRUE);
323 current_offset = updateField(lpcs->dwResultClauseLen,
324 lpcs->dwResultClauseOffset,
325 current_offset, newdata, olddata,
326 &new_one->dwResultClauseLen,
327 &new_one->dwResultClauseOffset, FALSE);
329 current_offset = updateField(lpcs->dwResultStrLen,
330 lpcs->dwResultStrOffset,
331 current_offset, newdata, olddata,
332 &new_one->dwResultStrLen,
333 &new_one->dwResultStrOffset, TRUE);
335 current_offset = updateField(lpcs->dwPrivateSize,
336 lpcs->dwPrivateOffset,
337 current_offset, newdata, olddata,
338 &new_one->dwPrivateSize,
339 &new_one->dwPrivateOffset, FALSE);
342 /* set new data */
343 /* CompAttr */
344 new_one->dwCompAttrLen = len;
345 if (len > 0)
347 new_one->dwCompAttrOffset = current_offset;
348 memset(&newdata[current_offset],ATTR_INPUT,len);
349 current_offset += len;
352 /* CompClause */
353 if (len > 0)
355 new_one->dwCompClauseLen = sizeof(DWORD) * 2;
356 new_one->dwCompClauseOffset = current_offset;
357 *(DWORD*)(&newdata[current_offset]) = 0;
358 current_offset += sizeof(DWORD);
359 *(DWORD*)(&newdata[current_offset]) = len;
360 current_offset += sizeof(DWORD);
363 /* CompStr */
364 new_one->dwCompStrLen = len;
365 if (len > 0)
367 new_one->dwCompStrOffset = current_offset;
368 memcpy(&newdata[current_offset],compstr,len*sizeof(WCHAR));
371 /* CursorPos */
372 new_one->dwCursorPos = len;
374 ImmUnlockIMCC(rc);
375 if (lpcs)
376 ImmUnlockIMCC(old);
378 return rc;
381 static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len)
383 /* we need to make sure the ResultStr and ResultClause fields are all
384 * set and correct */
385 int needed_size;
386 HIMCC rc;
387 LPBYTE newdata = NULL;
388 LPBYTE olddata = NULL;
389 LPCOMPOSITIONSTRING new_one;
390 LPCOMPOSITIONSTRING lpcs = NULL;
391 INT current_offset = 0;
393 TRACE("%s, %i\n",debugstr_wn(resultstr,len),len);
395 if (old == NULL && resultstr == NULL && len == 0)
396 return NULL;
398 if (old != NULL)
400 olddata = ImmLockIMCC(old);
401 lpcs = (LPCOMPOSITIONSTRING)olddata;
404 needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
405 sizeof(DWORD) * 2;
407 if (lpcs != NULL)
409 needed_size += lpcs->dwCompReadAttrLen;
410 needed_size += lpcs->dwCompReadClauseLen;
411 needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
412 needed_size += lpcs->dwCompAttrLen;
413 needed_size += lpcs->dwCompClauseLen;
414 needed_size += lpcs->dwCompStrLen * sizeof(DWORD);
415 needed_size += lpcs->dwResultReadClauseLen;
416 needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
417 needed_size += lpcs->dwPrivateSize;
419 rc = ImmCreateIMCC(needed_size);
420 newdata = ImmLockIMCC(rc);
421 new_one = (LPCOMPOSITIONSTRING)newdata;
423 new_one->dwSize = needed_size;
424 current_offset = sizeof(COMPOSITIONSTRING);
425 if (lpcs != NULL)
427 current_offset = updateField(lpcs->dwCompReadAttrLen,
428 lpcs->dwCompReadAttrOffset,
429 current_offset, newdata, olddata,
430 &new_one->dwCompReadAttrLen,
431 &new_one->dwCompReadAttrOffset, FALSE);
433 current_offset = updateField(lpcs->dwCompReadClauseLen,
434 lpcs->dwCompReadClauseOffset,
435 current_offset, newdata, olddata,
436 &new_one->dwCompReadClauseLen,
437 &new_one->dwCompReadClauseOffset, FALSE);
439 current_offset = updateField(lpcs->dwCompReadStrLen,
440 lpcs->dwCompReadStrOffset,
441 current_offset, newdata, olddata,
442 &new_one->dwCompReadStrLen,
443 &new_one->dwCompReadStrOffset, TRUE);
445 current_offset = updateField(lpcs->dwCompAttrLen,
446 lpcs->dwCompAttrOffset,
447 current_offset, newdata, olddata,
448 &new_one->dwCompAttrLen,
449 &new_one->dwCompAttrOffset, FALSE);
451 current_offset = updateField(lpcs->dwCompClauseLen,
452 lpcs->dwCompClauseOffset,
453 current_offset, newdata, olddata,
454 &new_one->dwCompClauseLen,
455 &new_one->dwCompClauseOffset, FALSE);
457 current_offset = updateField(lpcs->dwCompStrLen,
458 lpcs->dwCompStrOffset,
459 current_offset, newdata, olddata,
460 &new_one->dwCompStrLen,
461 &new_one->dwCompStrOffset, TRUE);
463 new_one->dwCursorPos = lpcs->dwCursorPos;
464 new_one->dwDeltaStart = 0;
466 current_offset = updateField(lpcs->dwResultReadClauseLen,
467 lpcs->dwResultReadClauseOffset,
468 current_offset, newdata, olddata,
469 &new_one->dwResultReadClauseLen,
470 &new_one->dwResultReadClauseOffset, FALSE);
472 current_offset = updateField(lpcs->dwResultReadStrLen,
473 lpcs->dwResultReadStrOffset,
474 current_offset, newdata, olddata,
475 &new_one->dwResultReadStrLen,
476 &new_one->dwResultReadStrOffset, TRUE);
478 /* new ResultClause , ResultStr */
480 current_offset = updateField(lpcs->dwPrivateSize,
481 lpcs->dwPrivateOffset,
482 current_offset, newdata, olddata,
483 &new_one->dwPrivateSize,
484 &new_one->dwPrivateOffset, FALSE);
487 /* set new data */
488 /* ResultClause */
489 if (len > 0)
491 new_one->dwResultClauseLen = sizeof(DWORD) * 2;
492 new_one->dwResultClauseOffset = current_offset;
493 *(DWORD*)(&newdata[current_offset]) = 0;
494 current_offset += sizeof(DWORD);
495 *(DWORD*)(&newdata[current_offset]) = len;
496 current_offset += sizeof(DWORD);
499 /* ResultStr */
500 new_one->dwResultStrLen = len;
501 if (len > 0)
503 new_one->dwResultStrOffset = current_offset;
504 memcpy(&newdata[current_offset],resultstr,len*sizeof(WCHAR));
506 ImmUnlockIMCC(rc);
507 if (lpcs)
508 ImmUnlockIMCC(old);
510 return rc;
515 /***********************************************************************
516 * ImmAssociateContext (IMM32.@)
518 HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
520 InputContextData *data = (InputContextData*)hIMC;
522 WARN("(%p, %p): semi-stub\n", hWnd, hIMC);
524 if (!hIMC)
525 return NULL;
528 * WINE SPECIFIC! MAY CONFLICT
529 * associate the root context we have an XIM created
531 if (hWnd == 0x000)
533 root_context = (InputContextData*)hIMC;
537 * If already associated just return
539 if (data->IMC.hWnd == hWnd)
540 return hIMC;
542 if (IsWindow(data->IMC.hWnd))
545 * Post a message that your context is switching
547 SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
550 data->IMC.hWnd = hWnd;
552 if (IsWindow(data->IMC.hWnd))
555 * Post a message that your context is switching
557 SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
561 * TODO: We need to keep track of the old context associated
562 * with a window and return it for now we will return NULL;
564 return NULL;
567 /***********************************************************************
568 * ImmAssociateContextEx (IMM32.@)
570 BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
572 FIXME("(%p, %p, %d): stub\n", hWnd, hIMC, dwFlags);
573 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
574 return FALSE;
577 /***********************************************************************
578 * ImmConfigureIMEA (IMM32.@)
580 BOOL WINAPI ImmConfigureIMEA(
581 HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
583 FIXME("(%p, %p, %d, %p): stub\n",
584 hKL, hWnd, dwMode, lpData
586 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
587 return FALSE;
590 /***********************************************************************
591 * ImmConfigureIMEW (IMM32.@)
593 BOOL WINAPI ImmConfigureIMEW(
594 HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
596 FIXME("(%p, %p, %d, %p): stub\n",
597 hKL, hWnd, dwMode, lpData
599 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
600 return FALSE;
603 /***********************************************************************
604 * ImmCreateContext (IMM32.@)
606 HIMC WINAPI ImmCreateContext(void)
608 InputContextData *new_context;
610 new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
612 /* hCompStr is never NULL */
613 new_context->IMC.hCompStr = ImmCreateBlankCompStr();
614 new_context->IMC.hMsgBuf = ImmCreateIMCC(1);
616 return (HIMC)new_context;
619 /***********************************************************************
620 * ImmDestroyContext (IMM32.@)
622 BOOL WINAPI ImmDestroyContext(HIMC hIMC)
624 InputContextData *data = (InputContextData*)hIMC;
626 TRACE("Destroying %p\n",hIMC);
628 if (hIMC)
630 ImmDestroyIMCC(data->IMC.hCompStr);
631 ImmDestroyIMCC(data->IMC.hCandInfo);
632 ImmDestroyIMCC(data->IMC.hGuideLine);
633 ImmDestroyIMCC(data->IMC.hPrivate);
634 ImmDestroyIMCC(data->IMC.hMsgBuf);
636 if (data->textfont)
638 DeleteObject(data->textfont);
639 data->textfont = NULL;
642 HeapFree(GetProcessHeap(),0,data);
644 return TRUE;
647 /***********************************************************************
648 * ImmDisableIME (IMM32.@)
650 BOOL WINAPI ImmDisableIME(DWORD idThread)
652 FIXME("(%d): stub\n", idThread);
653 return TRUE;
656 /***********************************************************************
657 * ImmEnumRegisterWordA (IMM32.@)
659 UINT WINAPI ImmEnumRegisterWordA(
660 HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
661 LPCSTR lpszReading, DWORD dwStyle,
662 LPCSTR lpszRegister, LPVOID lpData)
664 FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
665 hKL, lpfnEnumProc,
666 debugstr_a(lpszReading), dwStyle,
667 debugstr_a(lpszRegister), lpData
669 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
670 return 0;
673 /***********************************************************************
674 * ImmEnumRegisterWordW (IMM32.@)
676 UINT WINAPI ImmEnumRegisterWordW(
677 HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
678 LPCWSTR lpszReading, DWORD dwStyle,
679 LPCWSTR lpszRegister, LPVOID lpData)
681 FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
682 hKL, lpfnEnumProc,
683 debugstr_w(lpszReading), dwStyle,
684 debugstr_w(lpszRegister), lpData
686 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
687 return 0;
690 /***********************************************************************
691 * ImmEscapeA (IMM32.@)
693 LRESULT WINAPI ImmEscapeA(
694 HKL hKL, HIMC hIMC,
695 UINT uEscape, LPVOID lpData)
697 FIXME("(%p, %p, %d, %p): stub\n",
698 hKL, hIMC, uEscape, lpData
700 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
701 return 0;
704 /***********************************************************************
705 * ImmEscapeW (IMM32.@)
707 LRESULT WINAPI ImmEscapeW(
708 HKL hKL, HIMC hIMC,
709 UINT uEscape, LPVOID lpData)
711 FIXME("(%p, %p, %d, %p): stub\n",
712 hKL, hIMC, uEscape, lpData
714 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
715 return 0;
718 /***********************************************************************
719 * ImmGetCandidateListA (IMM32.@)
721 DWORD WINAPI ImmGetCandidateListA(
722 HIMC hIMC, DWORD deIndex,
723 LPCANDIDATELIST lpCandList, DWORD dwBufLen)
725 FIXME("(%p, %d, %p, %d): stub\n",
726 hIMC, deIndex,
727 lpCandList, dwBufLen
729 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
730 return 0;
733 /***********************************************************************
734 * ImmGetCandidateListCountA (IMM32.@)
736 DWORD WINAPI ImmGetCandidateListCountA(
737 HIMC hIMC, LPDWORD lpdwListCount)
739 FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
740 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
741 return 0;
744 /***********************************************************************
745 * ImmGetCandidateListCountW (IMM32.@)
747 DWORD WINAPI ImmGetCandidateListCountW(
748 HIMC hIMC, LPDWORD lpdwListCount)
750 FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
751 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
752 return 0;
755 /***********************************************************************
756 * ImmGetCandidateListW (IMM32.@)
758 DWORD WINAPI ImmGetCandidateListW(
759 HIMC hIMC, DWORD deIndex,
760 LPCANDIDATELIST lpCandList, DWORD dwBufLen)
762 FIXME("(%p, %d, %p, %d): stub\n",
763 hIMC, deIndex,
764 lpCandList, dwBufLen
766 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
767 return 0;
770 /***********************************************************************
771 * ImmGetCandidateWindow (IMM32.@)
773 BOOL WINAPI ImmGetCandidateWindow(
774 HIMC hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
776 FIXME("(%p, %d, %p): stub\n", hIMC, dwBufLen, lpCandidate);
777 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
778 return FALSE;
781 /***********************************************************************
782 * ImmGetCompositionFontA (IMM32.@)
784 BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
786 FIXME("(%p, %p): stub\n", hIMC, lplf);
787 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
788 return FALSE;
791 /***********************************************************************
792 * ImmGetCompositionFontW (IMM32.@)
794 BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
796 FIXME("(%p, %p): stub\n", hIMC, lplf);
797 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
798 return FALSE;
801 /***********************************************************************
802 * ImmGetCompositionStringA (IMM32.@)
804 LONG WINAPI ImmGetCompositionStringA(
805 HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
807 CHAR *buf;
808 LONG rc = 0;
809 InputContextData *data = (InputContextData*)hIMC;
810 LPCOMPOSITIONSTRING compstr;
811 LPBYTE compdata;
813 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
815 if (!data)
816 return FALSE;
818 if (!data->IMC.hCompStr)
819 return FALSE;
821 compdata = ImmLockIMCC(data->IMC.hCompStr);
822 compstr = (LPCOMPOSITIONSTRING)compdata;
824 if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
825 compstr->dwResultStrOffset > 0)
827 LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
829 TRACE("GSC_RESULTSTR %p %i\n",ResultStr,
830 compstr->dwResultStrLen);
832 buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwResultStrLen * 3 );
833 rc = WideCharToMultiByte(CP_ACP, 0, ResultStr,
834 compstr->dwResultStrLen , buf,
835 compstr->dwResultStrLen * 3, NULL, NULL);
836 if (dwBufLen >= rc)
837 memcpy(lpBuf,buf,rc);
839 data->bRead = TRUE;
840 HeapFree( GetProcessHeap(), 0, buf );
842 else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
843 compstr->dwCompStrOffset > 0)
845 LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
847 TRACE("GSC_COMPSTR %p %i\n", CompString, compstr->dwCompStrLen);
849 buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwCompStrLen * 3 );
850 rc = WideCharToMultiByte(CP_ACP, 0, CompString,
851 compstr->dwCompStrLen, buf,
852 compstr->dwCompStrLen * 3, NULL, NULL);
853 if (dwBufLen >= rc)
854 memcpy(lpBuf,buf,rc);
855 HeapFree( GetProcessHeap(), 0, buf );
857 else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
858 compstr->dwCompAttrOffset > 0)
860 LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
861 TRACE("GSC_COMPATTR %p %i\n", Compattr , compstr->dwCompAttrLen);
863 rc = compstr->dwCompAttrLen;
864 if (dwBufLen >= rc)
865 memcpy(lpBuf,Compattr,rc);
867 else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
868 compstr->dwCompClauseOffset > 0)
870 LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
871 TRACE("GSC_COMPCLAUSE %p %i\n", Compclause, compstr->dwCompClauseLen);
873 rc = compstr->dwCompClauseLen;
874 if (dwBufLen >= compstr->dwCompClauseLen)
875 memcpy(lpBuf,Compclause,rc);
877 else if (dwIndex == GCS_RESULTCLAUSE && compstr->dwResultClauseLen > 0 &&
878 compstr->dwResultClauseOffset > 0)
880 LPWSTR Resultclause = (LPWSTR)(compdata + compstr->dwResultClauseOffset);
881 TRACE("GSC_RESULTCLAUSE %p %i\n", Resultclause, compstr->dwResultClauseLen);
883 rc = compstr->dwResultClauseLen;
884 if (dwBufLen >= compstr->dwResultClauseLen)
885 memcpy(lpBuf,Resultclause,rc);
887 else if (dwIndex == GCS_CURSORPOS)
889 TRACE("GSC_CURSORPOS\n");
890 rc = compstr->dwCursorPos;
892 else if (dwIndex == GCS_DELTASTART)
894 TRACE("GCS_DELTASTART\n");
895 rc = compstr->dwDeltaStart;
897 else
899 FIXME("Unhandled index 0x%x\n",dwIndex);
902 ImmUnlockIMCC(data->IMC.hCompStr);
904 return rc;
907 /***********************************************************************
908 * ImmGetCompositionStringW (IMM32.@)
910 LONG WINAPI ImmGetCompositionStringW(
911 HIMC hIMC, DWORD dwIndex,
912 LPVOID lpBuf, DWORD dwBufLen)
914 LONG rc = 0;
915 InputContextData *data = (InputContextData*)hIMC;
916 LPCOMPOSITIONSTRING compstr;
917 LPBYTE compdata;
919 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
921 if (!data)
922 return FALSE;
924 if (!data->IMC.hCompStr)
925 return FALSE;
927 compdata = ImmLockIMCC(data->IMC.hCompStr);
928 compstr = (LPCOMPOSITIONSTRING)compdata;
930 if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
931 compstr->dwResultStrOffset > 0)
933 LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
934 data->bRead = TRUE;
935 rc = compstr->dwResultStrLen * sizeof(WCHAR);
937 if (dwBufLen >= rc)
938 memcpy(lpBuf,ResultStr,rc);
940 else if (dwIndex == GCS_RESULTREADSTR && compstr->dwResultReadStrLen > 0 &&
941 compstr->dwResultReadStrOffset > 0)
943 LPWSTR ResultReadString = (LPWSTR)(compdata + compstr->dwResultReadStrOffset);
945 rc = compstr->dwResultReadStrLen * sizeof(WCHAR);
946 if (dwBufLen >= rc)
947 memcpy(lpBuf,ResultReadString,rc);
949 else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
950 compstr->dwCompStrOffset > 0)
952 LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
953 rc = compstr->dwCompStrLen * sizeof(WCHAR);
954 if (dwBufLen >= rc)
955 memcpy(lpBuf,CompString,rc);
957 else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
958 compstr->dwCompAttrOffset > 0)
961 LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
963 rc = compstr->dwCompAttrLen;
964 if (dwBufLen >= rc)
965 memcpy(lpBuf,Compattr,rc);
967 else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
968 compstr->dwCompClauseOffset > 0)
970 LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
972 rc = compstr->dwCompClauseLen;
973 if (dwBufLen >= compstr->dwCompClauseLen)
974 memcpy(lpBuf,Compclause,rc);
976 else if (dwIndex == GCS_COMPREADSTR && compstr->dwCompReadStrLen > 0 &&
977 compstr->dwCompReadStrOffset > 0)
979 LPWSTR CompReadString = (LPWSTR)(compdata + compstr->dwCompReadStrOffset);
981 rc = compstr->dwCompReadStrLen * sizeof(WCHAR);
983 if (dwBufLen >= rc)
984 memcpy(lpBuf,CompReadString,rc);
986 else if (dwIndex == GCS_CURSORPOS)
988 TRACE("GSC_CURSORPOS\n");
989 rc = compstr->dwCursorPos;
991 else if (dwIndex == GCS_DELTASTART)
993 TRACE("GCS_DELTASTART\n");
994 rc = compstr->dwDeltaStart;
996 else
998 FIXME("Unhandled index 0x%x\n",dwIndex);
1001 ImmUnlockIMCC(data->IMC.hCompStr);
1003 return rc;
1006 /***********************************************************************
1007 * ImmGetCompositionWindow (IMM32.@)
1009 BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
1011 InputContextData *data = (InputContextData*)hIMC;
1013 TRACE("(%p, %p)\n", hIMC, lpCompForm);
1015 if (!data)
1016 return FALSE;
1018 *lpCompForm = data->IMC.cfCompForm;
1019 return 1;
1022 /***********************************************************************
1023 * ImmGetContext (IMM32.@)
1026 HIMC WINAPI ImmGetContext(HWND hWnd)
1028 TRACE("%p\n", hWnd);
1030 if (!root_context)
1031 return NULL;
1033 root_context->IMC.hWnd = hWnd;
1034 return (HIMC)root_context;
1037 /***********************************************************************
1038 * ImmGetConversionListA (IMM32.@)
1040 DWORD WINAPI ImmGetConversionListA(
1041 HKL hKL, HIMC hIMC,
1042 LPCSTR pSrc, LPCANDIDATELIST lpDst,
1043 DWORD dwBufLen, UINT uFlag)
1045 FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
1046 hKL, hIMC, debugstr_a(pSrc), lpDst, dwBufLen, uFlag
1048 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1049 return 0;
1052 /***********************************************************************
1053 * ImmGetConversionListW (IMM32.@)
1055 DWORD WINAPI ImmGetConversionListW(
1056 HKL hKL, HIMC hIMC,
1057 LPCWSTR pSrc, LPCANDIDATELIST lpDst,
1058 DWORD dwBufLen, UINT uFlag)
1060 FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
1061 hKL, hIMC, debugstr_w(pSrc), lpDst, dwBufLen, uFlag
1063 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1064 return 0;
1067 /***********************************************************************
1068 * ImmGetConversionStatus (IMM32.@)
1070 BOOL WINAPI ImmGetConversionStatus(
1071 HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
1073 TRACE("(%p, %p, %p): best guess\n", hIMC, lpfdwConversion, lpfdwSentence);
1074 if (lpfdwConversion)
1075 *lpfdwConversion = IME_CMODE_NATIVE;
1076 if (lpfdwSentence)
1077 *lpfdwSentence = IME_SMODE_NONE;
1078 return TRUE;
1081 /***********************************************************************
1082 * ImmGetDefaultIMEWnd (IMM32.@)
1084 HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
1086 static int shown = 0;
1088 if (!shown) {
1089 FIXME("(%p - %p %p ): semi-stub\n", hWnd,hwndDefault, root_context);
1090 shown = 1;
1093 if (hwndDefault == NULL)
1095 static const WCHAR the_name[] = {'I','M','E','\0'};
1097 IMM_Register();
1098 hwndDefault = CreateWindowExW( WS_EX_TOOLWINDOW, WC_IMECLASSNAME,
1099 the_name, WS_POPUP, 0, 0, 1, 1, 0, 0,
1100 hImeInst, 0);
1102 TRACE("Default created (%p)\n",hwndDefault);
1105 return hwndDefault;
1108 /***********************************************************************
1109 * ImmGetDescriptionA (IMM32.@)
1111 UINT WINAPI ImmGetDescriptionA(
1112 HKL hKL, LPSTR lpszDescription, UINT uBufLen)
1114 WCHAR *buf;
1115 DWORD len;
1117 TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
1119 /* find out how many characters in the unicode buffer */
1120 len = ImmGetDescriptionW( hKL, NULL, 0 );
1122 /* allocate a buffer of that size */
1123 buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
1124 if( !buf )
1125 return 0;
1127 /* fetch the unicode buffer */
1128 len = ImmGetDescriptionW( hKL, buf, len + 1 );
1130 /* convert it back to ASCII */
1131 len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
1132 lpszDescription, uBufLen, NULL, NULL );
1134 HeapFree( GetProcessHeap(), 0, buf );
1136 return len;
1139 /***********************************************************************
1140 * ImmGetDescriptionW (IMM32.@)
1142 UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
1144 static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
1146 FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
1148 if (!uBufLen) return lstrlenW( name );
1149 lstrcpynW( lpszDescription, name, uBufLen );
1150 return lstrlenW( lpszDescription );
1153 /***********************************************************************
1154 * ImmGetGuideLineA (IMM32.@)
1156 DWORD WINAPI ImmGetGuideLineA(
1157 HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
1159 FIXME("(%p, %d, %s, %d): stub\n",
1160 hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
1162 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1163 return 0;
1166 /***********************************************************************
1167 * ImmGetGuideLineW (IMM32.@)
1169 DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
1171 FIXME("(%p, %d, %s, %d): stub\n",
1172 hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
1174 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1175 return 0;
1178 /***********************************************************************
1179 * ImmGetIMEFileNameA (IMM32.@)
1181 UINT WINAPI ImmGetIMEFileNameA(
1182 HKL hKL, LPSTR lpszFileName, UINT uBufLen)
1184 FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
1185 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1186 return 0;
1189 /***********************************************************************
1190 * ImmGetIMEFileNameW (IMM32.@)
1192 UINT WINAPI ImmGetIMEFileNameW(
1193 HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
1195 FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
1196 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1197 return 0;
1200 /***********************************************************************
1201 * ImmGetOpenStatus (IMM32.@)
1203 BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
1205 InputContextData *data = (InputContextData*)hIMC;
1207 if (!data)
1208 return FALSE;
1209 FIXME("(%p): semi-stub\n", hIMC);
1211 return data->IMC.fOpen;
1214 /***********************************************************************
1215 * ImmGetProperty (IMM32.@)
1217 DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
1219 DWORD rc = 0;
1220 TRACE("(%p, %d)\n", hKL, fdwIndex);
1222 switch (fdwIndex)
1224 case IGP_PROPERTY:
1225 TRACE("(%s)\n", "IGP_PROPERTY");
1226 rc = IME_PROP_UNICODE | IME_PROP_AT_CARET;
1227 break;
1228 case IGP_CONVERSION:
1229 FIXME("(%s)\n", "IGP_CONVERSION");
1230 rc = IME_CMODE_NATIVE;
1231 break;
1232 case IGP_SENTENCE:
1233 FIXME("%s)\n", "IGP_SENTENCE");
1234 rc = IME_SMODE_AUTOMATIC;
1235 break;
1236 case IGP_SETCOMPSTR:
1237 TRACE("(%s)\n", "IGP_SETCOMPSTR");
1238 rc = 0;
1239 break;
1240 case IGP_SELECT:
1241 TRACE("(%s)\n", "IGP_SELECT");
1242 rc = SELECT_CAP_CONVERSION | SELECT_CAP_SENTENCE;
1243 break;
1244 case IGP_GETIMEVERSION:
1245 TRACE("(%s)\n", "IGP_GETIMEVERSION");
1246 rc = IMEVER_0400;
1247 break;
1248 case IGP_UI:
1249 TRACE("(%s)\n", "IGP_UI");
1250 rc = 0;
1251 break;
1252 default:
1253 rc = 0;
1255 return rc;
1258 /***********************************************************************
1259 * ImmGetRegisterWordStyleA (IMM32.@)
1261 UINT WINAPI ImmGetRegisterWordStyleA(
1262 HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
1264 FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
1265 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1266 return 0;
1269 /***********************************************************************
1270 * ImmGetRegisterWordStyleW (IMM32.@)
1272 UINT WINAPI ImmGetRegisterWordStyleW(
1273 HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
1275 FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
1276 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1277 return 0;
1280 /***********************************************************************
1281 * ImmGetStatusWindowPos (IMM32.@)
1283 BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1285 FIXME("(%p, %p): stub\n", hIMC, lpptPos);
1286 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1287 return FALSE;
1290 /***********************************************************************
1291 * ImmGetVirtualKey (IMM32.@)
1293 UINT WINAPI ImmGetVirtualKey(HWND hWnd)
1295 OSVERSIONINFOA version;
1296 FIXME("(%p): stub\n", hWnd);
1297 GetVersionExA( &version );
1298 switch(version.dwPlatformId)
1300 case VER_PLATFORM_WIN32_WINDOWS:
1301 return VK_PROCESSKEY;
1302 case VER_PLATFORM_WIN32_NT:
1303 return 0;
1304 default:
1305 FIXME("%d not supported\n",version.dwPlatformId);
1306 return VK_PROCESSKEY;
1310 /***********************************************************************
1311 * ImmInstallIMEA (IMM32.@)
1313 HKL WINAPI ImmInstallIMEA(
1314 LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
1316 FIXME("(%s, %s): stub\n",
1317 debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
1319 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1320 return NULL;
1323 /***********************************************************************
1324 * ImmInstallIMEW (IMM32.@)
1326 HKL WINAPI ImmInstallIMEW(
1327 LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
1329 FIXME("(%s, %s): stub\n",
1330 debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
1332 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1333 return NULL;
1336 /***********************************************************************
1337 * ImmIsIME (IMM32.@)
1339 BOOL WINAPI ImmIsIME(HKL hKL)
1341 TRACE("(%p): semi-stub\n", hKL);
1343 * FIXME: Dead key locales will return TRUE here when they should not
1344 * There is probably a more proper way to check this.
1346 return (root_context != NULL);
1349 /***********************************************************************
1350 * ImmIsUIMessageA (IMM32.@)
1352 BOOL WINAPI ImmIsUIMessageA(
1353 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1355 BOOL rc = FALSE;
1357 TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
1358 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1359 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1360 (msg == WM_MSIME_SERVICE) ||
1361 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1362 (msg == WM_MSIME_MOUSE) ||
1363 (msg == WM_MSIME_RECONVERTREQUEST) ||
1364 (msg == WM_MSIME_RECONVERT) ||
1365 (msg == WM_MSIME_QUERYPOSITION) ||
1366 (msg == WM_MSIME_DOCUMENTFEED))
1369 if (!hwndDefault)
1370 ImmGetDefaultIMEWnd(NULL);
1372 if (hWndIME == NULL)
1373 PostMessageA(hwndDefault, msg, wParam, lParam);
1375 rc = TRUE;
1377 return rc;
1380 /***********************************************************************
1381 * ImmIsUIMessageW (IMM32.@)
1383 BOOL WINAPI ImmIsUIMessageW(
1384 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1386 BOOL rc = FALSE;
1387 TRACE("(%p, %d, %ld, %ld): stub\n", hWndIME, msg, wParam, lParam);
1388 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1389 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1390 (msg == WM_MSIME_SERVICE) ||
1391 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1392 (msg == WM_MSIME_MOUSE) ||
1393 (msg == WM_MSIME_RECONVERTREQUEST) ||
1394 (msg == WM_MSIME_RECONVERT) ||
1395 (msg == WM_MSIME_QUERYPOSITION) ||
1396 (msg == WM_MSIME_DOCUMENTFEED))
1397 rc = TRUE;
1398 return rc;
1401 /***********************************************************************
1402 * ImmNotifyIME (IMM32.@)
1404 BOOL WINAPI ImmNotifyIME(
1405 HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
1407 BOOL rc = FALSE;
1409 TRACE("(%p, %d, %d, %d)\n",
1410 hIMC, dwAction, dwIndex, dwValue);
1412 if (!root_context)
1413 return rc;
1415 switch(dwAction)
1417 case NI_CHANGECANDIDATELIST:
1418 FIXME("%s\n","NI_CHANGECANDIDATELIST");
1419 break;
1420 case NI_CLOSECANDIDATE:
1421 FIXME("%s\n","NI_CLOSECANDIDATE");
1422 break;
1423 case NI_COMPOSITIONSTR:
1424 switch (dwIndex)
1426 case CPS_CANCEL:
1427 TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL");
1429 BOOL send;
1430 LPCOMPOSITIONSTRING lpCompStr;
1432 if (pX11DRV_ForceXIMReset)
1433 pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
1435 lpCompStr = ImmLockIMCC(root_context->IMC.hCompStr);
1436 send = (lpCompStr->dwCompStrLen != 0);
1437 ImmUnlockIMCC(root_context->IMC.hCompStr);
1439 ImmDestroyIMCC(root_context->IMC.hCompStr);
1440 root_context->IMC.hCompStr = ImmCreateBlankCompStr();
1442 if (send)
1443 ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
1444 GCS_COMPSTR);
1445 rc = TRUE;
1447 break;
1448 case CPS_COMPLETE:
1449 TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_COMPLETE");
1450 if (hIMC != (HIMC)FROM_IME && pX11DRV_ForceXIMReset)
1451 pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
1453 HIMCC newCompStr;
1454 DWORD cplen = 0;
1455 LPWSTR cpstr;
1456 LPCOMPOSITIONSTRING cs = NULL;
1457 LPBYTE cdata = NULL;
1459 /* clear existing result */
1460 newCompStr = updateResultStr(root_context->IMC.hCompStr, NULL, 0);
1461 ImmDestroyIMCC(root_context->IMC.hCompStr);
1462 root_context->IMC.hCompStr = newCompStr;
1464 if (root_context->IMC.hCompStr)
1466 cdata = ImmLockIMCC(root_context->IMC.hCompStr);
1467 cs = (LPCOMPOSITIONSTRING)cdata;
1468 cplen = cs->dwCompStrLen;
1469 cpstr = (LPWSTR)&(cdata[cs->dwCompStrOffset]);
1470 ImmUnlockIMCC(root_context->IMC.hCompStr);
1472 if (cplen > 0)
1474 WCHAR param = cpstr[0];
1475 newCompStr = updateResultStr(root_context->IMC.hCompStr, cpstr, cplen);
1476 ImmDestroyIMCC(root_context->IMC.hCompStr);
1477 root_context->IMC.hCompStr = newCompStr;
1478 newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
1479 ImmDestroyIMCC(root_context->IMC.hCompStr);
1480 root_context->IMC.hCompStr = newCompStr;
1482 root_context->bRead = FALSE;
1484 ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
1485 GCS_COMPSTR);
1487 ImmInternalPostIMEMessage(WM_IME_COMPOSITION,
1488 param,
1489 GCS_RESULTSTR|GCS_RESULTCLAUSE);
1492 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0);
1493 root_context->bInComposition = FALSE;
1495 break;
1496 case CPS_CONVERT:
1497 FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_CONVERT");
1498 break;
1499 case CPS_REVERT:
1500 FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_REVERT");
1501 break;
1502 default:
1503 ERR("%s - %s (%i)\n","NI_COMPOSITIONSTR","UNKNOWN",dwIndex);
1504 break;
1506 break;
1507 case NI_IMEMENUSELECTED:
1508 FIXME("%s\n", "NI_IMEMENUSELECTED");
1509 break;
1510 case NI_OPENCANDIDATE:
1511 FIXME("%s\n", "NI_OPENCANDIDATE");
1512 break;
1513 case NI_SELECTCANDIDATESTR:
1514 FIXME("%s\n", "NI_SELECTCANDIDATESTR");
1515 break;
1516 case NI_SETCANDIDATE_PAGESIZE:
1517 FIXME("%s\n", "NI_SETCANDIDATE_PAGESIZE");
1518 break;
1519 case NI_SETCANDIDATE_PAGESTART:
1520 FIXME("%s\n", "NI_SETCANDIDATE_PAGESTART");
1521 break;
1522 default:
1523 ERR("Unknown\n");
1526 return rc;
1529 /***********************************************************************
1530 * ImmRegisterWordA (IMM32.@)
1532 BOOL WINAPI ImmRegisterWordA(
1533 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
1535 FIXME("(%p, %s, %d, %s): stub\n",
1536 hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister)
1538 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1539 return FALSE;
1542 /***********************************************************************
1543 * ImmRegisterWordW (IMM32.@)
1545 BOOL WINAPI ImmRegisterWordW(
1546 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
1548 FIXME("(%p, %s, %d, %s): stub\n",
1549 hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister)
1551 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1552 return FALSE;
1555 /***********************************************************************
1556 * ImmReleaseContext (IMM32.@)
1558 BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1560 static int shown = 0;
1562 if (!shown) {
1563 FIXME("(%p, %p): stub\n", hWnd, hIMC);
1564 shown = 1;
1566 return TRUE;
1569 /***********************************************************************
1570 * ImmSetCandidateWindow (IMM32.@)
1572 BOOL WINAPI ImmSetCandidateWindow(
1573 HIMC hIMC, LPCANDIDATEFORM lpCandidate)
1575 FIXME("(%p, %p): stub\n", hIMC, lpCandidate);
1576 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1577 return FALSE;
1580 /***********************************************************************
1581 * ImmSetCompositionFontA (IMM32.@)
1583 BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
1585 InputContextData *data = (InputContextData*)hIMC;
1586 TRACE("(%p, %p)\n", hIMC, lplf);
1588 if (!data)
1589 return FALSE;
1591 memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
1592 MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
1593 LF_FACESIZE);
1595 ImmInternalSendIMENotify(IMN_SETCOMPOSITIONFONT, 0);
1597 if (data->textfont)
1599 DeleteObject(data->textfont);
1600 data->textfont = NULL;
1603 data->textfont = CreateFontIndirectW(&data->IMC.lfFont.W);
1604 return TRUE;
1607 /***********************************************************************
1608 * ImmSetCompositionFontW (IMM32.@)
1610 BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
1612 InputContextData *data = (InputContextData*)hIMC;
1613 TRACE("(%p, %p)\n", hIMC, lplf);
1615 if (!data)
1616 return FALSE;
1618 data->IMC.lfFont.W = *lplf;
1619 ImmInternalSendIMENotify(IMN_SETCOMPOSITIONFONT, 0);
1621 if (data->textfont)
1623 DeleteObject(data->textfont);
1624 data->textfont = NULL;
1626 data->textfont = CreateFontIndirectW(&data->IMC.lfFont.W);
1627 return TRUE;
1630 /***********************************************************************
1631 * ImmSetCompositionStringA (IMM32.@)
1633 BOOL WINAPI ImmSetCompositionStringA(
1634 HIMC hIMC, DWORD dwIndex,
1635 LPCVOID lpComp, DWORD dwCompLen,
1636 LPCVOID lpRead, DWORD dwReadLen)
1638 DWORD comp_len;
1639 DWORD read_len;
1640 WCHAR *CompBuffer = NULL;
1641 WCHAR *ReadBuffer = NULL;
1642 BOOL rc;
1644 TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
1645 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1647 comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
1648 if (comp_len)
1650 CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len * sizeof(WCHAR));
1651 MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len);
1654 read_len = MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, NULL, 0);
1655 if (read_len)
1657 ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len * sizeof(WCHAR));
1658 MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len);
1661 rc = ImmSetCompositionStringW(hIMC, dwIndex, CompBuffer, comp_len,
1662 ReadBuffer, read_len);
1664 HeapFree(GetProcessHeap(), 0, CompBuffer);
1665 HeapFree(GetProcessHeap(), 0, ReadBuffer);
1667 return rc;
1670 /***********************************************************************
1671 * ImmSetCompositionStringW (IMM32.@)
1673 BOOL WINAPI ImmSetCompositionStringW(
1674 HIMC hIMC, DWORD dwIndex,
1675 LPCVOID lpComp, DWORD dwCompLen,
1676 LPCVOID lpRead, DWORD dwReadLen)
1678 DWORD flags = 0;
1679 WCHAR wParam = 0;
1681 TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
1682 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1685 if (hIMC != (HIMC)FROM_IME)
1686 FIXME("PROBLEM: This only sets the wine level string\n");
1689 * Explanation:
1690 * this sets the composition string in the imm32.dll level
1691 * of the composition buffer. we cannot manipulate the xim level
1692 * buffer, which means that once the xim level buffer changes again
1693 * any call to this function from the application will be lost
1696 if (lpRead && dwReadLen)
1697 FIXME("Reading string unimplemented\n");
1700 * app operating this api to also receive the message from xim
1703 if (dwIndex == SCS_SETSTR)
1705 HIMCC newCompStr;
1706 if (!root_context->bInComposition)
1708 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION, 0, 0);
1709 root_context->bInComposition = TRUE;
1712 flags = GCS_COMPSTR;
1714 if (dwCompLen && lpComp)
1716 newCompStr = updateCompStr(root_context->IMC.hCompStr, (LPWSTR)lpComp, dwCompLen / sizeof(WCHAR));
1717 ImmDestroyIMCC(root_context->IMC.hCompStr);
1718 root_context->IMC.hCompStr = newCompStr;
1720 wParam = ((const WCHAR*)lpComp)[0];
1721 flags |= GCS_COMPCLAUSE | GCS_COMPATTR | GCS_DELTASTART;
1723 else
1725 newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
1726 ImmDestroyIMCC(root_context->IMC.hCompStr);
1727 root_context->IMC.hCompStr = newCompStr;
1731 UpdateDataInDefaultIMEWindow(hwndDefault,FALSE);
1733 ImmInternalPostIMEMessage(WM_IME_COMPOSITION, wParam, flags);
1735 return TRUE;
1738 /***********************************************************************
1739 * ImmSetCompositionWindow (IMM32.@)
1741 BOOL WINAPI ImmSetCompositionWindow(
1742 HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
1744 BOOL reshow = FALSE;
1745 InputContextData *data = (InputContextData*)hIMC;
1747 TRACE("(%p, %p)\n", hIMC, lpCompForm);
1748 TRACE("\t%x, (%i,%i), (%i,%i - %i,%i)\n",lpCompForm->dwStyle,
1749 lpCompForm->ptCurrentPos.x, lpCompForm->ptCurrentPos.y, lpCompForm->rcArea.top,
1750 lpCompForm->rcArea.left, lpCompForm->rcArea.bottom, lpCompForm->rcArea.right);
1752 if (!data)
1753 return FALSE;
1755 data->IMC.cfCompForm = *lpCompForm;
1757 if (IsWindowVisible(hwndDefault))
1759 reshow = TRUE;
1760 ShowWindow(hwndDefault,SW_HIDE);
1763 /* FIXME: this is a partial stub */
1765 if (reshow)
1766 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
1768 ImmInternalSendIMENotify(IMN_SETCOMPOSITIONWINDOW, 0);
1769 return TRUE;
1772 /***********************************************************************
1773 * ImmSetConversionStatus (IMM32.@)
1775 BOOL WINAPI ImmSetConversionStatus(
1776 HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
1778 static int shown = 0;
1780 if (!shown) {
1781 FIXME("(%p, %d, %d): stub\n",
1782 hIMC, fdwConversion, fdwSentence
1784 shown = 1;
1786 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1787 return FALSE;
1790 /***********************************************************************
1791 * ImmSetOpenStatus (IMM32.@)
1793 BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
1795 InputContextData *data = (InputContextData*)hIMC;
1797 TRACE("%p %d\n", hIMC, fOpen);
1799 if (hIMC == (HIMC)FROM_IME)
1801 ImmInternalSetOpenStatus(fOpen);
1802 ImmInternalSendIMENotify(IMN_SETOPENSTATUS, 0);
1803 return TRUE;
1806 if (!data)
1807 return FALSE;
1809 if (fOpen != data->bInternalState)
1811 if (fOpen == FALSE && pX11DRV_ForceXIMReset)
1812 pX11DRV_ForceXIMReset(data->IMC.hWnd);
1814 if (fOpen == FALSE)
1815 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
1816 else
1817 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
1819 ImmInternalSetOpenStatus(fOpen);
1820 ImmInternalSetOpenStatus(!fOpen);
1822 if (data->IMC.fOpen == FALSE)
1823 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
1824 else
1825 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
1827 return FALSE;
1829 return TRUE;
1832 /***********************************************************************
1833 * ImmSetStatusWindowPos (IMM32.@)
1835 BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1837 FIXME("(%p, %p): stub\n", hIMC, lpptPos);
1838 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1839 return FALSE;
1842 /***********************************************************************
1843 * ImmSimulateHotKey (IMM32.@)
1845 BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
1847 FIXME("(%p, %d): stub\n", hWnd, dwHotKeyID);
1848 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1849 return FALSE;
1852 /***********************************************************************
1853 * ImmUnregisterWordA (IMM32.@)
1855 BOOL WINAPI ImmUnregisterWordA(
1856 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
1858 FIXME("(%p, %s, %d, %s): stub\n",
1859 hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister)
1861 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1862 return FALSE;
1865 /***********************************************************************
1866 * ImmUnregisterWordW (IMM32.@)
1868 BOOL WINAPI ImmUnregisterWordW(
1869 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
1871 FIXME("(%p, %s, %d, %s): stub\n",
1872 hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister)
1874 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1875 return FALSE;
1878 /***********************************************************************
1879 * ImmGetImeMenuItemsA (IMM32.@)
1881 DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType,
1882 LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
1883 DWORD dwSize)
1885 FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType,
1886 lpImeParentMenu, lpImeMenu, dwSize);
1887 return 0;
1890 /***********************************************************************
1891 * ImmGetImeMenuItemsW (IMM32.@)
1893 DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType,
1894 LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
1895 DWORD dwSize)
1897 FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType,
1898 lpImeParentMenu, lpImeMenu, dwSize);
1899 return 0;
1902 /***********************************************************************
1903 * ImmLockIMC(IMM32.@)
1905 LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
1907 InputContextData *data = (InputContextData*)hIMC;
1909 if (!data)
1910 return NULL;
1911 data->dwLock++;
1912 return &data->IMC;
1915 /***********************************************************************
1916 * ImmUnlockIMC(IMM32.@)
1918 BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
1920 InputContextData *data = (InputContextData*)hIMC;
1921 data->dwLock--;
1922 return (data->dwLock!=0);
1925 /***********************************************************************
1926 * ImmGetIMCLockCount(IMM32.@)
1928 DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
1930 InputContextData *data = (InputContextData*)hIMC;
1931 return data->dwLock;
1934 /***********************************************************************
1935 * ImmCreateIMCC(IMM32.@)
1937 HIMCC WINAPI ImmCreateIMCC(DWORD size)
1939 IMCCInternal *internal;
1940 int real_size = size + sizeof(IMCCInternal);
1942 internal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, real_size);
1943 if (internal == NULL)
1944 return NULL;
1946 internal->dwSize = size;
1947 return (HIMCC)internal;
1950 /***********************************************************************
1951 * ImmDestroyIMCC(IMM32.@)
1953 HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
1955 HeapFree(GetProcessHeap(),0,block);
1956 return NULL;
1959 /***********************************************************************
1960 * ImmLockIMCC(IMM32.@)
1962 LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
1964 IMCCInternal *internal;
1965 internal = (IMCCInternal*) imcc;
1967 internal->dwLock ++;
1968 return internal + 1;
1971 /***********************************************************************
1972 * ImmUnlockIMCC(IMM32.@)
1974 BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
1976 IMCCInternal *internal;
1977 internal = (IMCCInternal*) imcc;
1979 internal->dwLock --;
1980 return (internal->dwLock!=0);
1983 /***********************************************************************
1984 * ImmGetIMCCLockCount(IMM32.@)
1986 DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
1988 IMCCInternal *internal;
1989 internal = (IMCCInternal*) imcc;
1991 return internal->dwLock;
1994 /***********************************************************************
1995 * ImmReSizeIMCC(IMM32.@)
1997 HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
1999 IMCCInternal *internal,*newone;
2000 int real_size = size + sizeof(IMCCInternal);
2002 internal = (IMCCInternal*) imcc;
2004 newone = HeapReAlloc(GetProcessHeap(), 0, internal, real_size);
2005 newone->dwSize = size;
2007 return newone;
2010 /***********************************************************************
2011 * ImmGetIMCCSize(IMM32.@)
2013 DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
2015 IMCCInternal *internal;
2016 internal = (IMCCInternal*) imcc;
2018 return internal->dwSize;
2021 /***********************************************************************
2022 * ImmGenerateMessage(IMM32.@)
2024 BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
2026 InputContextData *data = (InputContextData*)hIMC;
2028 TRACE("%i messages queued\n",data->IMC.dwNumMsgBuf);
2029 if (data->IMC.dwNumMsgBuf > 0)
2031 LPTRANSMSG lpTransMsg;
2032 INT i;
2034 lpTransMsg = (LPTRANSMSG)ImmLockIMCC(data->IMC.hMsgBuf);
2035 for (i = 0; i < data->IMC.dwNumMsgBuf; i++)
2036 ImmInternalPostIMEMessage(lpTransMsg[i].message, lpTransMsg[i].wParam, lpTransMsg[i].lParam);
2038 ImmUnlockIMCC(data->IMC.hMsgBuf);
2040 data->IMC.dwNumMsgBuf = 0;
2043 return TRUE;
2046 /*****
2047 * Internal functions to help with IME window management
2049 static void PaintDefaultIMEWnd(HWND hwnd)
2051 PAINTSTRUCT ps;
2052 RECT rect;
2053 HDC hdc = BeginPaint(hwnd,&ps);
2054 LPCOMPOSITIONSTRING compstr;
2055 LPBYTE compdata = NULL;
2056 HMONITOR monitor;
2057 MONITORINFO mon_info;
2058 INT offX=0, offY=0;
2060 GetClientRect(hwnd,&rect);
2061 FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1));
2063 compdata = ImmLockIMCC(root_context->IMC.hCompStr);
2064 compstr = (LPCOMPOSITIONSTRING)compdata;
2066 if (compstr->dwCompStrLen && compstr->dwCompStrOffset)
2068 SIZE size;
2069 POINT pt;
2070 HFONT oldfont = NULL;
2071 LPWSTR CompString;
2073 CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
2074 if (root_context->textfont)
2075 oldfont = SelectObject(hdc,root_context->textfont);
2078 GetTextExtentPoint32W(hdc, CompString, compstr->dwCompStrLen, &size);
2079 pt.x = size.cx;
2080 pt.y = size.cy;
2081 LPtoDP(hdc,&pt,1);
2084 * How this works based on tests on windows:
2085 * CFS_POINT: then we start our window at the point and grow it as large
2086 * as it needs to be for the string.
2087 * CFS_RECT: we still use the ptCurrentPos as a starting point and our
2088 * window is only as large as we need for the string, but we do not
2089 * grow such that our window exceeds the given rect. Wrapping if
2090 * needed and possible. If our ptCurrentPos is outside of our rect
2091 * then no window is displayed.
2092 * CFS_FORCE_POSITION: appears to behave just like CFS_POINT
2093 * maybe becase the default MSIME does not do any IME adjusting.
2095 if (root_context->IMC.cfCompForm.dwStyle != CFS_DEFAULT)
2097 POINT cpt = root_context->IMC.cfCompForm.ptCurrentPos;
2098 ClientToScreen(root_context->IMC.hWnd,&cpt);
2099 rect.left = cpt.x;
2100 rect.top = cpt.y;
2101 rect.right = rect.left + pt.x;
2102 rect.bottom = rect.top + pt.y;
2103 monitor = MonitorFromPoint(cpt, MONITOR_DEFAULTTOPRIMARY);
2105 else /* CFS_DEFAULT */
2107 /* Windows places the default IME window in the bottom left */
2108 HWND target = root_context->IMC.hWnd;
2109 if (!target) target = GetFocus();
2111 GetWindowRect(target,&rect);
2112 rect.top = rect.bottom;
2113 rect.right = rect.left + pt.x + 20;
2114 rect.bottom = rect.top + pt.y + 20;
2115 offX=offY=10;
2116 monitor = MonitorFromWindow(target, MONITOR_DEFAULTTOPRIMARY);
2119 if (root_context->IMC.cfCompForm.dwStyle == CFS_RECT)
2121 RECT client;
2122 client =root_context->IMC.cfCompForm.rcArea;
2123 MapWindowPoints( root_context->IMC.hWnd, 0, (POINT *)&client, 2 );
2124 IntersectRect(&rect,&rect,&client);
2125 /* TODO: Wrap the input if needed */
2128 if (root_context->IMC.cfCompForm.dwStyle == CFS_DEFAULT)
2130 /* make sure we are on the desktop */
2131 mon_info.cbSize = sizeof(mon_info);
2132 GetMonitorInfoW(monitor, &mon_info);
2134 if (rect.bottom > mon_info.rcWork.bottom)
2136 int shift = rect.bottom - mon_info.rcWork.bottom;
2137 rect.top -= shift;
2138 rect.bottom -= shift;
2140 if (rect.left < 0)
2142 rect.right -= rect.left;
2143 rect.left = 0;
2145 if (rect.right > mon_info.rcWork.right)
2147 int shift = rect.right - mon_info.rcWork.right;
2148 rect.left -= shift;
2149 rect.right -= shift;
2153 SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE);
2155 TextOutW(hdc, offX,offY, CompString, compstr->dwCompStrLen);
2157 if (oldfont)
2158 SelectObject(hdc,oldfont);
2161 ImmUnlockIMCC(root_context->IMC.hCompStr);
2163 EndPaint(hwnd,&ps);
2166 static void UpdateDataInDefaultIMEWindow(HWND hwnd, BOOL showable)
2168 LPCOMPOSITIONSTRING compstr;
2170 if (root_context->IMC.hCompStr)
2171 compstr = ImmLockIMCC(root_context->IMC.hCompStr);
2172 else
2173 compstr = NULL;
2175 if (compstr == NULL || compstr->dwCompStrLen == 0)
2176 ShowWindow(hwndDefault,SW_HIDE);
2177 else if (showable)
2178 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
2180 RedrawWindow(hwnd,NULL,NULL,RDW_ERASENOW|RDW_INVALIDATE);
2182 if (compstr != NULL)
2183 ImmUnlockIMCC(root_context->IMC.hCompStr);
2187 * The window proc for the default IME window
2189 static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
2190 LPARAM lParam)
2192 LRESULT rc = 0;
2194 TRACE("Incoming Message 0x%x (0x%08x, 0x%08x)\n", msg, (UINT)wParam,
2195 (UINT)lParam);
2197 switch(msg)
2199 case WM_PAINT:
2200 PaintDefaultIMEWnd(hwnd);
2201 return FALSE;
2203 case WM_NCCREATE:
2204 return TRUE;
2206 case WM_CREATE:
2207 SetWindowTextA(hwnd,"Wine Ime Active");
2208 return TRUE;
2210 case WM_SETFOCUS:
2211 if (wParam)
2212 SetFocus((HWND)wParam);
2213 else
2214 FIXME("Received focus, should never have focus\n");
2215 break;
2216 case WM_IME_COMPOSITION:
2217 TRACE("IME message %s, 0x%x, 0x%x (%i)\n",
2218 "WM_IME_COMPOSITION", (UINT)wParam, (UINT)lParam,
2219 root_context->bRead);
2220 if (lParam & GCS_RESULTSTR)
2221 IMM_PostResult(root_context);
2222 else
2223 UpdateDataInDefaultIMEWindow(hwnd,TRUE);
2224 break;
2225 case WM_IME_STARTCOMPOSITION:
2226 TRACE("IME message %s, 0x%x, 0x%x\n",
2227 "WM_IME_STARTCOMPOSITION", (UINT)wParam, (UINT)lParam);
2228 root_context->IMC.hWnd = GetFocus();
2229 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
2230 break;
2231 case WM_IME_ENDCOMPOSITION:
2232 TRACE("IME message %s, 0x%x, 0x%x\n",
2233 "WM_IME_ENDCOMPOSITION", (UINT)wParam, (UINT)lParam);
2234 ShowWindow(hwndDefault,SW_HIDE);
2235 break;
2236 case WM_IME_SELECT:
2237 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_SELECT",
2238 (UINT)wParam, (UINT)lParam);
2239 break;
2240 case WM_IME_CONTROL:
2241 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_CONTROL",
2242 (UINT)wParam, (UINT)lParam);
2243 rc = 1;
2244 break;
2245 case WM_IME_NOTIFY:
2246 TRACE("!! IME NOTIFY\n");
2247 break;
2248 default:
2249 TRACE("Non-standard message 0x%x\n",msg);
2251 /* check the MSIME messages */
2252 if (msg == WM_MSIME_SERVICE)
2254 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_SERVICE",
2255 (UINT)wParam, (UINT)lParam);
2256 rc = FALSE;
2258 else if (msg == WM_MSIME_RECONVERTOPTIONS)
2260 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTOPTIONS",
2261 (UINT)wParam, (UINT)lParam);
2263 else if (msg == WM_MSIME_MOUSE)
2265 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_MOUSE",
2266 (UINT)wParam, (UINT)lParam);
2268 else if (msg == WM_MSIME_RECONVERTREQUEST)
2270 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTREQUEST",
2271 (UINT)wParam, (UINT)lParam);
2273 else if (msg == WM_MSIME_RECONVERT)
2275 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERT",
2276 (UINT)wParam, (UINT)lParam);
2278 else if (msg == WM_MSIME_QUERYPOSITION)
2280 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_QUERYPOSITION",
2281 (UINT)wParam, (UINT)lParam);
2283 else if (msg == WM_MSIME_DOCUMENTFEED)
2285 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_DOCUMENTFEED",
2286 (UINT)wParam, (UINT)lParam);
2288 /* DefWndProc if not an IME message */
2289 else if (!rc && !((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
2290 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP)))
2291 rc = DefWindowProcW(hwnd,msg,wParam,lParam);
2293 return rc;