push 92ef5b88da02911741c0a2f56030fd2e20189321
[wine/hacks.git] / dlls / imm32 / imm.c
blob2bb1a477a4aa64f449c6b815e0638b24afad88ef
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 static InputContextData *root_context = NULL;
58 static HWND hwndDefault = NULL;
59 static HANDLE hImeInst;
60 static const WCHAR WC_IMECLASSNAME[] = {'I','M','E',0};
61 static ATOM atIMEClass = 0;
63 /* MSIME messages */
64 static UINT WM_MSIME_SERVICE;
65 static UINT WM_MSIME_RECONVERTOPTIONS;
66 static UINT WM_MSIME_MOUSE;
67 static UINT WM_MSIME_RECONVERTREQUEST;
68 static UINT WM_MSIME_RECONVERT;
69 static UINT WM_MSIME_QUERYPOSITION;
70 static UINT WM_MSIME_DOCUMENTFEED;
73 * prototypes
75 static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
76 LPARAM lParam);
77 static void UpdateDataInDefaultIMEWindow(HWND hwnd, BOOL showable);
78 static void ImmInternalPostIMEMessage(UINT, WPARAM, LPARAM);
79 static void ImmInternalSetOpenStatus(BOOL fOpen);
80 static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len);
82 static VOID IMM_PostResult(InputContextData *data)
84 unsigned int i;
85 LPCOMPOSITIONSTRING compstr;
86 LPBYTE compdata;
87 LPWSTR ResultStr;
88 HIMCC newCompStr;
90 TRACE("Posting result as IME_CHAR\n");
91 compdata = ImmLockIMCC(root_context->IMC.hCompStr);
92 compstr = (LPCOMPOSITIONSTRING)compdata;
93 ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
95 for (i = 0; i < compstr->dwResultStrLen; i++)
96 ImmInternalPostIMEMessage (WM_IME_CHAR, ResultStr[i], 1);
98 ImmUnlockIMCC(root_context->IMC.hCompStr);
100 /* clear the buffer */
101 newCompStr = updateResultStr(root_context->IMC.hCompStr, NULL, 0);
102 ImmDestroyIMCC(root_context->IMC.hCompStr);
103 root_context->IMC.hCompStr = newCompStr;
106 static void IMM_Register(void)
108 WNDCLASSW wndClass;
109 ZeroMemory(&wndClass, sizeof(WNDCLASSW));
110 wndClass.style = CS_GLOBALCLASS | CS_IME | CS_HREDRAW | CS_VREDRAW;
111 wndClass.lpfnWndProc = (WNDPROC) IME_WindowProc;
112 wndClass.cbClsExtra = 0;
113 wndClass.cbWndExtra = 0;
114 wndClass.hInstance = hImeInst;
115 wndClass.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
116 wndClass.hIcon = NULL;
117 wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
118 wndClass.lpszMenuName = 0;
119 wndClass.lpszClassName = WC_IMECLASSNAME;
120 atIMEClass = RegisterClassW(&wndClass);
123 static void IMM_Unregister(void)
125 if (atIMEClass) {
126 UnregisterClassW(WC_IMECLASSNAME, NULL);
130 static void IMM_RegisterMessages(void)
132 WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
133 WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
134 WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
135 WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
136 WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
137 WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
138 WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
142 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
144 HMODULE x11drv;
146 TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
147 switch (fdwReason)
149 case DLL_PROCESS_ATTACH:
150 DisableThreadLibraryCalls(hInstDLL);
151 hImeInst = hInstDLL;
152 IMM_RegisterMessages();
153 x11drv = GetModuleHandleA("winex11.drv");
154 if (x11drv) pX11DRV_ForceXIMReset = (void *)GetProcAddress( x11drv, "ForceXIMReset");
155 break;
156 case DLL_PROCESS_DETACH:
157 if (hwndDefault)
159 DestroyWindow(hwndDefault);
160 hwndDefault = 0;
162 IMM_Unregister();
163 break;
165 return TRUE;
168 /* for posting messages as the IME */
169 static void ImmInternalPostIMEMessage(UINT msg, WPARAM wParam, LPARAM lParam)
171 HWND target = GetFocus();
172 if (!target)
173 PostMessageW(root_context->IMC.hWnd,msg,wParam,lParam);
174 else
175 PostMessageW(target, msg, wParam, lParam);
178 static LRESULT ImmInternalSendIMENotify(WPARAM notify, LPARAM lParam)
180 HWND target;
182 target = root_context->IMC.hWnd;
183 if (!target) target = GetFocus();
185 if (target)
186 return SendMessageW(target, WM_IME_NOTIFY, notify, lParam);
188 return 0;
191 static void ImmInternalSetOpenStatus(BOOL fOpen)
193 TRACE("Setting internal state to %s\n",(fOpen)?"OPEN":"CLOSED");
195 root_context->IMC.fOpen = fOpen;
196 root_context->bInternalState = fOpen;
198 if (fOpen == FALSE)
200 ShowWindow(hwndDefault,SW_HIDE);
201 ImmDestroyIMCC(root_context->IMC.hCompStr);
202 root_context->IMC.hCompStr = NULL;
204 else
205 ShowWindow(hwndDefault, SW_SHOWNOACTIVATE);
207 ImmInternalSendIMENotify(IMN_SETOPENSTATUS, 0);
210 static int updateField(DWORD origLen, DWORD origOffset, DWORD currentOffset,
211 LPBYTE target, LPBYTE source, DWORD* lenParam,
212 DWORD* offsetParam, BOOL wchars )
214 if (origLen > 0 && origOffset > 0)
216 int truelen = origLen;
217 if (wchars)
218 truelen *= sizeof(WCHAR);
220 memcpy(&target[currentOffset], &source[origOffset], truelen);
222 *lenParam = origLen;
223 *offsetParam = currentOffset;
224 currentOffset += truelen;
226 return currentOffset;
229 static HIMCC updateCompStr(HIMCC old, LPWSTR compstr, DWORD len)
231 /* we need to make sure the CompStr, CompClaus and CompAttr fields are all
232 * set and correct */
233 int needed_size;
234 HIMCC rc;
235 LPBYTE newdata = NULL;
236 LPBYTE olddata = NULL;
237 LPCOMPOSITIONSTRING new_one;
238 LPCOMPOSITIONSTRING lpcs = NULL;
239 INT current_offset = 0;
241 TRACE("%s, %i\n",debugstr_wn(compstr,len),len);
243 if (old != NULL)
245 olddata = ImmLockIMCC(old);
246 lpcs = (LPCOMPOSITIONSTRING)olddata;
249 needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
250 len + sizeof(DWORD) * 2;
252 if (lpcs != NULL)
254 needed_size += lpcs->dwCompReadAttrLen;
255 needed_size += lpcs->dwCompReadClauseLen;
256 needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
257 needed_size += lpcs->dwResultReadClauseLen;
258 needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
259 needed_size += lpcs->dwResultClauseLen;
260 needed_size += lpcs->dwResultStrLen * sizeof(DWORD);
261 needed_size += lpcs->dwPrivateSize;
263 rc = ImmCreateIMCC(needed_size);
264 newdata = ImmLockIMCC(rc);
265 new_one = (LPCOMPOSITIONSTRING)newdata;
267 new_one->dwSize = needed_size;
268 current_offset = sizeof(COMPOSITIONSTRING);
269 if (lpcs != NULL)
271 current_offset = updateField(lpcs->dwCompReadAttrLen,
272 lpcs->dwCompReadAttrOffset,
273 current_offset, newdata, olddata,
274 &new_one->dwCompReadAttrLen,
275 &new_one->dwCompReadAttrOffset, FALSE);
277 current_offset = updateField(lpcs->dwCompReadClauseLen,
278 lpcs->dwCompReadClauseOffset,
279 current_offset, newdata, olddata,
280 &new_one->dwCompReadClauseLen,
281 &new_one->dwCompReadClauseOffset, FALSE);
283 current_offset = updateField(lpcs->dwCompReadStrLen,
284 lpcs->dwCompReadStrOffset,
285 current_offset, newdata, olddata,
286 &new_one->dwCompReadStrLen,
287 &new_one->dwCompReadStrOffset, TRUE);
289 /* new CompAttr, CompClause, CompStr, dwCursorPos */
291 current_offset = updateField(lpcs->dwResultReadClauseLen,
292 lpcs->dwResultReadClauseOffset,
293 current_offset, newdata, olddata,
294 &new_one->dwResultReadClauseLen,
295 &new_one->dwResultReadClauseOffset, FALSE);
297 current_offset = updateField(lpcs->dwResultReadStrLen,
298 lpcs->dwResultReadStrOffset,
299 current_offset, newdata, olddata,
300 &new_one->dwResultReadStrLen,
301 &new_one->dwResultReadStrOffset, TRUE);
303 current_offset = updateField(lpcs->dwResultClauseLen,
304 lpcs->dwResultClauseOffset,
305 current_offset, newdata, olddata,
306 &new_one->dwResultClauseLen,
307 &new_one->dwResultClauseOffset, FALSE);
309 current_offset = updateField(lpcs->dwResultStrLen,
310 lpcs->dwResultStrOffset,
311 current_offset, newdata, olddata,
312 &new_one->dwResultStrLen,
313 &new_one->dwResultStrOffset, TRUE);
315 current_offset = updateField(lpcs->dwPrivateSize,
316 lpcs->dwPrivateOffset,
317 current_offset, newdata, olddata,
318 &new_one->dwPrivateSize,
319 &new_one->dwPrivateOffset, FALSE);
322 /* set new data */
323 /* CompAttr */
324 new_one->dwCompAttrLen = len;
325 if (len > 0)
327 new_one->dwCompAttrOffset = current_offset;
328 memset(&newdata[current_offset],ATTR_INPUT,len);
329 current_offset += len;
332 /* CompClause */
333 if (len > 0)
335 new_one->dwCompClauseLen = sizeof(DWORD) * 2;
336 new_one->dwCompClauseOffset = current_offset;
337 *(DWORD*)(&newdata[current_offset]) = 0;
338 current_offset += sizeof(DWORD);
339 *(DWORD*)(&newdata[current_offset]) = len;
340 current_offset += sizeof(DWORD);
343 /* CompStr */
344 new_one->dwCompStrLen = len;
345 if (len > 0)
347 new_one->dwCompStrOffset = current_offset;
348 memcpy(&newdata[current_offset],compstr,len*sizeof(WCHAR));
351 /* CursorPos */
352 new_one->dwCursorPos = len;
354 ImmUnlockIMCC(rc);
355 if (lpcs)
356 ImmUnlockIMCC(old);
358 return rc;
361 static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len)
363 /* we need to make sure the ResultStr and ResultClause fields are all
364 * set and correct */
365 int needed_size;
366 HIMCC rc;
367 LPBYTE newdata = NULL;
368 LPBYTE olddata = NULL;
369 LPCOMPOSITIONSTRING new_one;
370 LPCOMPOSITIONSTRING lpcs = NULL;
371 INT current_offset = 0;
373 TRACE("%s, %i\n",debugstr_wn(resultstr,len),len);
375 if (old != NULL)
377 olddata = ImmLockIMCC(old);
378 lpcs = (LPCOMPOSITIONSTRING)olddata;
381 needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
382 sizeof(DWORD) * 2;
384 if (lpcs != NULL)
386 needed_size += lpcs->dwCompReadAttrLen;
387 needed_size += lpcs->dwCompReadClauseLen;
388 needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
389 needed_size += lpcs->dwCompAttrLen;
390 needed_size += lpcs->dwCompClauseLen;
391 needed_size += lpcs->dwCompStrLen * sizeof(DWORD);
392 needed_size += lpcs->dwResultReadClauseLen;
393 needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
394 needed_size += lpcs->dwPrivateSize;
396 rc = ImmCreateIMCC(needed_size);
397 newdata = ImmLockIMCC(rc);
398 new_one = (LPCOMPOSITIONSTRING)newdata;
400 new_one->dwSize = needed_size;
401 current_offset = sizeof(COMPOSITIONSTRING);
402 if (lpcs != NULL)
404 current_offset = updateField(lpcs->dwCompReadAttrLen,
405 lpcs->dwCompReadAttrOffset,
406 current_offset, newdata, olddata,
407 &new_one->dwCompReadAttrLen,
408 &new_one->dwCompReadAttrOffset, FALSE);
410 current_offset = updateField(lpcs->dwCompReadClauseLen,
411 lpcs->dwCompReadClauseOffset,
412 current_offset, newdata, olddata,
413 &new_one->dwCompReadClauseLen,
414 &new_one->dwCompReadClauseOffset, FALSE);
416 current_offset = updateField(lpcs->dwCompReadStrLen,
417 lpcs->dwCompReadStrOffset,
418 current_offset, newdata, olddata,
419 &new_one->dwCompReadStrLen,
420 &new_one->dwCompReadStrOffset, TRUE);
422 current_offset = updateField(lpcs->dwCompAttrLen,
423 lpcs->dwCompAttrOffset,
424 current_offset, newdata, olddata,
425 &new_one->dwCompAttrLen,
426 &new_one->dwCompAttrOffset, FALSE);
428 current_offset = updateField(lpcs->dwCompClauseLen,
429 lpcs->dwCompClauseOffset,
430 current_offset, newdata, olddata,
431 &new_one->dwCompClauseLen,
432 &new_one->dwCompClauseOffset, FALSE);
434 current_offset = updateField(lpcs->dwCompStrLen,
435 lpcs->dwCompStrOffset,
436 current_offset, newdata, olddata,
437 &new_one->dwCompStrLen,
438 &new_one->dwCompStrOffset, TRUE);
440 new_one->dwCursorPos = lpcs->dwCursorPos;
442 current_offset = updateField(lpcs->dwResultReadClauseLen,
443 lpcs->dwResultReadClauseOffset,
444 current_offset, newdata, olddata,
445 &new_one->dwResultReadClauseLen,
446 &new_one->dwResultReadClauseOffset, FALSE);
448 current_offset = updateField(lpcs->dwResultReadStrLen,
449 lpcs->dwResultReadStrOffset,
450 current_offset, newdata, olddata,
451 &new_one->dwResultReadStrLen,
452 &new_one->dwResultReadStrOffset, TRUE);
454 /* new ResultClause , ResultStr */
456 current_offset = updateField(lpcs->dwPrivateSize,
457 lpcs->dwPrivateOffset,
458 current_offset, newdata, olddata,
459 &new_one->dwPrivateSize,
460 &new_one->dwPrivateOffset, FALSE);
463 /* set new data */
464 /* ResultClause */
465 if (len > 0)
467 new_one->dwResultClauseLen = sizeof(DWORD) * 2;
468 new_one->dwResultClauseOffset = current_offset;
469 *(DWORD*)(&newdata[current_offset]) = 0;
470 current_offset += sizeof(DWORD);
471 *(DWORD*)(&newdata[current_offset]) = len;
472 current_offset += sizeof(DWORD);
475 /* ResultStr */
476 new_one->dwResultStrLen = len;
477 if (len > 0)
479 new_one->dwResultStrOffset = current_offset;
480 memcpy(&newdata[current_offset],resultstr,len*sizeof(WCHAR));
482 ImmUnlockIMCC(rc);
483 if (lpcs)
484 ImmUnlockIMCC(old);
486 return rc;
491 /***********************************************************************
492 * ImmAssociateContext (IMM32.@)
494 HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
496 InputContextData *data = (InputContextData*)hIMC;
498 WARN("(%p, %p): semi-stub\n", hWnd, hIMC);
500 if (!hIMC)
501 return NULL;
504 * WINE SPECIFIC! MAY CONFLICT
505 * associate the root context we have an XIM created
507 if (hWnd == 0x000)
509 root_context = (InputContextData*)hIMC;
513 * If already associated just return
515 if (data->IMC.hWnd == hWnd)
516 return hIMC;
518 if (IsWindow(data->IMC.hWnd))
521 * Post a message that your context is switching
523 SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
526 data->IMC.hWnd = hWnd;
528 if (IsWindow(data->IMC.hWnd))
531 * Post a message that your context is switching
533 SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
537 * TODO: We need to keep track of the old context associated
538 * with a window and return it for now we will return NULL;
540 return NULL;
543 /***********************************************************************
544 * ImmAssociateContextEx (IMM32.@)
546 BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
548 FIXME("(%p, %p, %d): stub\n", hWnd, hIMC, dwFlags);
549 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
550 return FALSE;
553 /***********************************************************************
554 * ImmConfigureIMEA (IMM32.@)
556 BOOL WINAPI ImmConfigureIMEA(
557 HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
559 FIXME("(%p, %p, %d, %p): stub\n",
560 hKL, hWnd, dwMode, lpData
562 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
563 return FALSE;
566 /***********************************************************************
567 * ImmConfigureIMEW (IMM32.@)
569 BOOL WINAPI ImmConfigureIMEW(
570 HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
572 FIXME("(%p, %p, %d, %p): stub\n",
573 hKL, hWnd, dwMode, lpData
575 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
576 return FALSE;
579 /***********************************************************************
580 * ImmCreateContext (IMM32.@)
582 HIMC WINAPI ImmCreateContext(void)
584 InputContextData *new_context;
586 new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
588 return (HIMC)new_context;
591 /***********************************************************************
592 * ImmDestroyContext (IMM32.@)
594 BOOL WINAPI ImmDestroyContext(HIMC hIMC)
596 InputContextData *data = (InputContextData*)hIMC;
598 TRACE("Destroying %p\n",hIMC);
600 if (hIMC)
602 ImmDestroyIMCC(root_context->IMC.hCompStr);
603 ImmDestroyIMCC(root_context->IMC.hCandInfo);
604 ImmDestroyIMCC(root_context->IMC.hGuideLine);
605 ImmDestroyIMCC(root_context->IMC.hPrivate);
606 ImmDestroyIMCC(root_context->IMC.hMsgBuf);
608 if (data->textfont)
610 DeleteObject(data->textfont);
611 data->textfont = NULL;
614 HeapFree(GetProcessHeap(),0,data);
616 return TRUE;
619 /***********************************************************************
620 * ImmDisableIME (IMM32.@)
622 BOOL WINAPI ImmDisableIME(DWORD idThread)
624 FIXME("(%d): stub\n", idThread);
625 return TRUE;
628 /***********************************************************************
629 * ImmEnumRegisterWordA (IMM32.@)
631 UINT WINAPI ImmEnumRegisterWordA(
632 HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
633 LPCSTR lpszReading, DWORD dwStyle,
634 LPCSTR lpszRegister, LPVOID lpData)
636 FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
637 hKL, lpfnEnumProc,
638 debugstr_a(lpszReading), dwStyle,
639 debugstr_a(lpszRegister), lpData
641 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
642 return 0;
645 /***********************************************************************
646 * ImmEnumRegisterWordW (IMM32.@)
648 UINT WINAPI ImmEnumRegisterWordW(
649 HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
650 LPCWSTR lpszReading, DWORD dwStyle,
651 LPCWSTR lpszRegister, LPVOID lpData)
653 FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
654 hKL, lpfnEnumProc,
655 debugstr_w(lpszReading), dwStyle,
656 debugstr_w(lpszRegister), lpData
658 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
659 return 0;
662 /***********************************************************************
663 * ImmEscapeA (IMM32.@)
665 LRESULT WINAPI ImmEscapeA(
666 HKL hKL, HIMC hIMC,
667 UINT uEscape, LPVOID lpData)
669 FIXME("(%p, %p, %d, %p): stub\n",
670 hKL, hIMC, uEscape, lpData
672 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
673 return 0;
676 /***********************************************************************
677 * ImmEscapeW (IMM32.@)
679 LRESULT WINAPI ImmEscapeW(
680 HKL hKL, HIMC hIMC,
681 UINT uEscape, LPVOID lpData)
683 FIXME("(%p, %p, %d, %p): stub\n",
684 hKL, hIMC, uEscape, lpData
686 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
687 return 0;
690 /***********************************************************************
691 * ImmGetCandidateListA (IMM32.@)
693 DWORD WINAPI ImmGetCandidateListA(
694 HIMC hIMC, DWORD deIndex,
695 LPCANDIDATELIST lpCandList, DWORD dwBufLen)
697 FIXME("(%p, %d, %p, %d): stub\n",
698 hIMC, deIndex,
699 lpCandList, dwBufLen
701 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
702 return 0;
705 /***********************************************************************
706 * ImmGetCandidateListCountA (IMM32.@)
708 DWORD WINAPI ImmGetCandidateListCountA(
709 HIMC hIMC, LPDWORD lpdwListCount)
711 FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
712 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
713 return 0;
716 /***********************************************************************
717 * ImmGetCandidateListCountW (IMM32.@)
719 DWORD WINAPI ImmGetCandidateListCountW(
720 HIMC hIMC, LPDWORD lpdwListCount)
722 FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
723 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
724 return 0;
727 /***********************************************************************
728 * ImmGetCandidateListW (IMM32.@)
730 DWORD WINAPI ImmGetCandidateListW(
731 HIMC hIMC, DWORD deIndex,
732 LPCANDIDATELIST lpCandList, DWORD dwBufLen)
734 FIXME("(%p, %d, %p, %d): stub\n",
735 hIMC, deIndex,
736 lpCandList, dwBufLen
738 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
739 return 0;
742 /***********************************************************************
743 * ImmGetCandidateWindow (IMM32.@)
745 BOOL WINAPI ImmGetCandidateWindow(
746 HIMC hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
748 FIXME("(%p, %d, %p): stub\n", hIMC, dwBufLen, lpCandidate);
749 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
750 return FALSE;
753 /***********************************************************************
754 * ImmGetCompositionFontA (IMM32.@)
756 BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
758 FIXME("(%p, %p): stub\n", hIMC, lplf);
759 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
760 return FALSE;
763 /***********************************************************************
764 * ImmGetCompositionFontW (IMM32.@)
766 BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
768 FIXME("(%p, %p): stub\n", hIMC, lplf);
769 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
770 return FALSE;
773 /***********************************************************************
774 * ImmGetCompositionStringA (IMM32.@)
776 LONG WINAPI ImmGetCompositionStringA(
777 HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
779 CHAR *buf;
780 LONG rc = 0;
781 InputContextData *data = (InputContextData*)hIMC;
782 LPCOMPOSITIONSTRING compstr;
783 LPBYTE compdata;
785 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
787 if (!data)
788 return FALSE;
790 if (!data->IMC.hCompStr)
791 return FALSE;
793 compdata = ImmLockIMCC(data->IMC.hCompStr);
794 compstr = (LPCOMPOSITIONSTRING)compdata;
796 if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
797 compstr->dwResultStrOffset > 0)
799 LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
801 TRACE("GSC_RESULTSTR %p %i\n",ResultStr,
802 compstr->dwResultStrLen);
804 buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwResultStrLen * 3 );
805 rc = WideCharToMultiByte(CP_ACP, 0, ResultStr,
806 compstr->dwResultStrLen , buf,
807 compstr->dwResultStrLen * 3, NULL, NULL);
808 if (dwBufLen >= rc)
809 memcpy(lpBuf,buf,rc);
811 data->bRead = TRUE;
812 HeapFree( GetProcessHeap(), 0, buf );
814 else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
815 compstr->dwCompStrOffset > 0)
817 LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
819 TRACE("GSC_COMPSTR %p %i\n", CompString, compstr->dwCompStrLen);
821 buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwCompStrLen * 3 );
822 rc = WideCharToMultiByte(CP_ACP, 0, CompString,
823 compstr->dwCompStrLen, buf,
824 compstr->dwCompStrLen * 3, NULL, NULL);
825 if (dwBufLen >= rc)
826 memcpy(lpBuf,buf,rc);
827 HeapFree( GetProcessHeap(), 0, buf );
829 else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
830 compstr->dwCompAttrOffset > 0)
832 LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
833 TRACE("GSC_COMPATTR %p %i\n", Compattr , compstr->dwCompAttrLen);
835 rc = compstr->dwCompAttrLen;
836 if (dwBufLen >= rc)
837 memcpy(lpBuf,Compattr,rc);
839 else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
840 compstr->dwCompClauseOffset > 0)
842 LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
843 TRACE("GSC_COMPCLAUSE %p %i\n", Compclause, compstr->dwCompClauseLen);
845 rc = compstr->dwCompClauseLen;
846 if (dwBufLen >= compstr->dwCompClauseLen)
847 memcpy(lpBuf,Compclause,rc);
849 else if (dwIndex == GCS_RESULTCLAUSE && compstr->dwResultClauseLen > 0 &&
850 compstr->dwResultClauseOffset > 0)
852 LPWSTR Resultclause = (LPWSTR)(compdata + compstr->dwResultClauseOffset);
853 TRACE("GSC_RESULTCLAUSE %p %i\n", Resultclause, compstr->dwResultClauseLen);
855 rc = compstr->dwResultClauseLen;
856 if (dwBufLen >= compstr->dwResultClauseLen)
857 memcpy(lpBuf,Resultclause,rc);
859 else if (dwIndex == GCS_CURSORPOS)
861 TRACE("GSC_CURSORPOS\n");
862 rc = compstr->dwCursorPos;
864 else
866 FIXME("Unhandled index 0x%x\n",dwIndex);
869 ImmUnlockIMCC(data->IMC.hCompStr);
871 return rc;
874 /***********************************************************************
875 * ImmGetCompositionStringW (IMM32.@)
877 LONG WINAPI ImmGetCompositionStringW(
878 HIMC hIMC, DWORD dwIndex,
879 LPVOID lpBuf, DWORD dwBufLen)
881 LONG rc = 0;
882 InputContextData *data = (InputContextData*)hIMC;
883 LPCOMPOSITIONSTRING compstr;
884 LPBYTE compdata;
886 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
888 if (!data)
889 return FALSE;
891 if (!data->IMC.hCompStr)
892 return FALSE;
894 compdata = ImmLockIMCC(data->IMC.hCompStr);
895 compstr = (LPCOMPOSITIONSTRING)compdata;
897 if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
898 compstr->dwResultStrOffset > 0)
900 LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
901 data->bRead = TRUE;
902 rc = compstr->dwResultStrLen * sizeof(WCHAR);
904 if (dwBufLen >= rc)
905 memcpy(lpBuf,ResultStr,rc);
907 else if (dwIndex == GCS_RESULTREADSTR && compstr->dwResultReadStrLen > 0 &&
908 compstr->dwResultReadStrOffset > 0)
910 LPWSTR ResultReadString = (LPWSTR)(compdata + compstr->dwResultReadStrOffset);
912 rc = compstr->dwResultReadStrLen * sizeof(WCHAR);
913 if (dwBufLen >= rc)
914 memcpy(lpBuf,ResultReadString,rc);
916 else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
917 compstr->dwCompStrOffset > 0)
919 LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
920 rc = compstr->dwCompStrLen * sizeof(WCHAR);
921 if (dwBufLen >= rc)
922 memcpy(lpBuf,CompString,rc);
924 else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
925 compstr->dwCompAttrOffset > 0)
928 LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
930 rc = compstr->dwCompAttrLen;
931 if (dwBufLen >= rc)
932 memcpy(lpBuf,Compattr,rc);
934 else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
935 compstr->dwCompClauseOffset > 0)
937 LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
939 rc = compstr->dwCompClauseLen;
940 if (dwBufLen >= compstr->dwCompClauseLen)
941 memcpy(lpBuf,Compclause,rc);
943 else if (dwIndex == GCS_COMPREADSTR && compstr->dwCompReadStrLen > 0 &&
944 compstr->dwCompReadStrOffset > 0)
946 LPWSTR CompReadString = (LPWSTR)(compdata + compstr->dwCompReadStrOffset);
948 rc = compstr->dwCompReadStrLen * sizeof(WCHAR);
950 if (dwBufLen >= rc)
951 memcpy(lpBuf,CompReadString,rc);
953 else if (dwIndex == GCS_CURSORPOS)
955 TRACE("GSC_CURSORPOS\n");
956 rc = compstr->dwCursorPos;
958 else
960 FIXME("Unhandled index 0x%x\n",dwIndex);
963 ImmUnlockIMCC(data->IMC.hCompStr);
965 return rc;
968 /***********************************************************************
969 * ImmGetCompositionWindow (IMM32.@)
971 BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
973 InputContextData *data = (InputContextData*)hIMC;
975 TRACE("(%p, %p)\n", hIMC, lpCompForm);
977 if (!data)
978 return FALSE;
980 memcpy(lpCompForm,&(data->IMC.cfCompForm),sizeof(COMPOSITIONFORM));
981 return 1;
984 /***********************************************************************
985 * ImmGetContext (IMM32.@)
988 HIMC WINAPI ImmGetContext(HWND hWnd)
990 TRACE("%p\n", hWnd);
992 if (!root_context)
993 return NULL;
995 root_context->IMC.hWnd = hWnd;
996 return (HIMC)root_context;
999 /***********************************************************************
1000 * ImmGetConversionListA (IMM32.@)
1002 DWORD WINAPI ImmGetConversionListA(
1003 HKL hKL, HIMC hIMC,
1004 LPCSTR pSrc, LPCANDIDATELIST lpDst,
1005 DWORD dwBufLen, UINT uFlag)
1007 FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
1008 hKL, hIMC, debugstr_a(pSrc), lpDst, dwBufLen, uFlag
1010 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1011 return 0;
1014 /***********************************************************************
1015 * ImmGetConversionListW (IMM32.@)
1017 DWORD WINAPI ImmGetConversionListW(
1018 HKL hKL, HIMC hIMC,
1019 LPCWSTR pSrc, LPCANDIDATELIST lpDst,
1020 DWORD dwBufLen, UINT uFlag)
1022 FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
1023 hKL, hIMC, debugstr_w(pSrc), lpDst, dwBufLen, uFlag
1025 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1026 return 0;
1029 /***********************************************************************
1030 * ImmGetConversionStatus (IMM32.@)
1032 BOOL WINAPI ImmGetConversionStatus(
1033 HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
1035 TRACE("(%p, %p, %p): best guess\n", hIMC, lpfdwConversion, lpfdwSentence);
1036 if (lpfdwConversion)
1037 *lpfdwConversion = IME_CMODE_NATIVE;
1038 if (lpfdwSentence)
1039 *lpfdwSentence = IME_SMODE_NONE;
1040 return TRUE;
1043 /***********************************************************************
1044 * ImmGetDefaultIMEWnd (IMM32.@)
1046 HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
1048 FIXME("(%p - %p %p ): semi-stub\n", hWnd,hwndDefault, root_context);
1050 if (hwndDefault == NULL)
1052 static const WCHAR the_name[] = {'I','M','E','\0'};
1054 IMM_Register();
1055 hwndDefault = CreateWindowExW( WS_EX_TOOLWINDOW, WC_IMECLASSNAME,
1056 the_name, WS_POPUP, 0, 0, 1, 1, 0, 0,
1057 hImeInst, 0);
1059 TRACE("Default created (%p)\n",hwndDefault);
1062 return (HWND)hwndDefault;
1065 /***********************************************************************
1066 * ImmGetDescriptionA (IMM32.@)
1068 UINT WINAPI ImmGetDescriptionA(
1069 HKL hKL, LPSTR lpszDescription, UINT uBufLen)
1071 WCHAR *buf;
1072 DWORD len;
1074 TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
1076 /* find out how many characters in the unicode buffer */
1077 len = ImmGetDescriptionW( hKL, NULL, 0 );
1079 /* allocate a buffer of that size */
1080 buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
1081 if( !buf )
1082 return 0;
1084 /* fetch the unicode buffer */
1085 len = ImmGetDescriptionW( hKL, buf, len + 1 );
1087 /* convert it back to ASCII */
1088 len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
1089 lpszDescription, uBufLen, NULL, NULL );
1091 HeapFree( GetProcessHeap(), 0, buf );
1093 return len;
1096 /***********************************************************************
1097 * ImmGetDescriptionW (IMM32.@)
1099 UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
1101 static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
1103 FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
1105 if (!uBufLen) return lstrlenW( name );
1106 lstrcpynW( lpszDescription, name, uBufLen );
1107 return lstrlenW( lpszDescription );
1110 /***********************************************************************
1111 * ImmGetGuideLineA (IMM32.@)
1113 DWORD WINAPI ImmGetGuideLineA(
1114 HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
1116 FIXME("(%p, %d, %s, %d): stub\n",
1117 hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
1119 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1120 return 0;
1123 /***********************************************************************
1124 * ImmGetGuideLineW (IMM32.@)
1126 DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
1128 FIXME("(%p, %d, %s, %d): stub\n",
1129 hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
1131 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1132 return 0;
1135 /***********************************************************************
1136 * ImmGetIMEFileNameA (IMM32.@)
1138 UINT WINAPI ImmGetIMEFileNameA(
1139 HKL hKL, LPSTR lpszFileName, UINT uBufLen)
1141 FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
1142 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1143 return 0;
1146 /***********************************************************************
1147 * ImmGetIMEFileNameW (IMM32.@)
1149 UINT WINAPI ImmGetIMEFileNameW(
1150 HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
1152 FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
1153 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1154 return 0;
1157 /***********************************************************************
1158 * ImmGetOpenStatus (IMM32.@)
1160 BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
1162 InputContextData *data = (InputContextData*)hIMC;
1164 if (!data)
1165 return FALSE;
1166 FIXME("(%p): semi-stub\n", hIMC);
1168 return data->IMC.fOpen;
1171 /***********************************************************************
1172 * ImmGetProperty (IMM32.@)
1174 DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
1176 DWORD rc = 0;
1177 TRACE("(%p, %d)\n", hKL, fdwIndex);
1179 switch (fdwIndex)
1181 case IGP_PROPERTY:
1182 TRACE("(%s)\n", "IGP_PROPERTY");
1183 rc = IME_PROP_UNICODE | IME_PROP_AT_CARET;
1184 break;
1185 case IGP_CONVERSION:
1186 FIXME("(%s)\n", "IGP_CONVERSION");
1187 rc = IME_CMODE_NATIVE;
1188 break;
1189 case IGP_SENTENCE:
1190 FIXME("%s)\n", "IGP_SENTENCE");
1191 rc = IME_SMODE_AUTOMATIC;
1192 break;
1193 case IGP_SETCOMPSTR:
1194 TRACE("(%s)\n", "IGP_SETCOMPSTR");
1195 rc = 0;
1196 break;
1197 case IGP_SELECT:
1198 TRACE("(%s)\n", "IGP_SELECT");
1199 rc = SELECT_CAP_CONVERSION | SELECT_CAP_SENTENCE;
1200 break;
1201 case IGP_GETIMEVERSION:
1202 TRACE("(%s)\n", "IGP_GETIMEVERSION");
1203 rc = IMEVER_0400;
1204 break;
1205 case IGP_UI:
1206 TRACE("(%s)\n", "IGP_UI");
1207 rc = 0;
1208 break;
1209 default:
1210 rc = 0;
1212 return rc;
1215 /***********************************************************************
1216 * ImmGetRegisterWordStyleA (IMM32.@)
1218 UINT WINAPI ImmGetRegisterWordStyleA(
1219 HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
1221 FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
1222 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1223 return 0;
1226 /***********************************************************************
1227 * ImmGetRegisterWordStyleW (IMM32.@)
1229 UINT WINAPI ImmGetRegisterWordStyleW(
1230 HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
1232 FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
1233 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1234 return 0;
1237 /***********************************************************************
1238 * ImmGetStatusWindowPos (IMM32.@)
1240 BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1242 FIXME("(%p, %p): stub\n", hIMC, lpptPos);
1243 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1244 return FALSE;
1247 /***********************************************************************
1248 * ImmGetVirtualKey (IMM32.@)
1250 UINT WINAPI ImmGetVirtualKey(HWND hWnd)
1252 OSVERSIONINFOA version;
1253 FIXME("(%p): stub\n", hWnd);
1254 GetVersionExA( &version );
1255 switch(version.dwPlatformId)
1257 case VER_PLATFORM_WIN32_WINDOWS:
1258 return VK_PROCESSKEY;
1259 case VER_PLATFORM_WIN32_NT:
1260 return 0;
1261 default:
1262 FIXME("%d not supported\n",version.dwPlatformId);
1263 return VK_PROCESSKEY;
1267 /***********************************************************************
1268 * ImmInstallIMEA (IMM32.@)
1270 HKL WINAPI ImmInstallIMEA(
1271 LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
1273 FIXME("(%s, %s): stub\n",
1274 debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
1276 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1277 return NULL;
1280 /***********************************************************************
1281 * ImmInstallIMEW (IMM32.@)
1283 HKL WINAPI ImmInstallIMEW(
1284 LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
1286 FIXME("(%s, %s): stub\n",
1287 debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
1289 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1290 return NULL;
1293 /***********************************************************************
1294 * ImmIsIME (IMM32.@)
1296 BOOL WINAPI ImmIsIME(HKL hKL)
1298 TRACE("(%p): semi-stub\n", hKL);
1300 * FIXME: Dead key locales will return TRUE here when they should not
1301 * There is probably a more proper way to check this.
1303 return (root_context != NULL);
1306 /***********************************************************************
1307 * ImmIsUIMessageA (IMM32.@)
1309 BOOL WINAPI ImmIsUIMessageA(
1310 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1312 BOOL rc = FALSE;
1314 TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
1315 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1316 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1317 (msg == WM_MSIME_SERVICE) ||
1318 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1319 (msg == WM_MSIME_MOUSE) ||
1320 (msg == WM_MSIME_RECONVERTREQUEST) ||
1321 (msg == WM_MSIME_RECONVERT) ||
1322 (msg == WM_MSIME_QUERYPOSITION) ||
1323 (msg == WM_MSIME_DOCUMENTFEED))
1326 if (!hwndDefault)
1327 ImmGetDefaultIMEWnd(NULL);
1329 if (hWndIME == NULL)
1330 PostMessageA(hwndDefault, msg, wParam, lParam);
1332 rc = TRUE;
1334 return rc;
1337 /***********************************************************************
1338 * ImmIsUIMessageW (IMM32.@)
1340 BOOL WINAPI ImmIsUIMessageW(
1341 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1343 BOOL rc = FALSE;
1344 TRACE("(%p, %d, %ld, %ld): stub\n", hWndIME, msg, wParam, lParam);
1345 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1346 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1347 (msg == WM_MSIME_SERVICE) ||
1348 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1349 (msg == WM_MSIME_MOUSE) ||
1350 (msg == WM_MSIME_RECONVERTREQUEST) ||
1351 (msg == WM_MSIME_RECONVERT) ||
1352 (msg == WM_MSIME_QUERYPOSITION) ||
1353 (msg == WM_MSIME_DOCUMENTFEED))
1354 rc = TRUE;
1355 return rc;
1358 /***********************************************************************
1359 * ImmNotifyIME (IMM32.@)
1361 BOOL WINAPI ImmNotifyIME(
1362 HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
1364 BOOL rc = FALSE;
1366 TRACE("(%p, %d, %d, %d)\n",
1367 hIMC, dwAction, dwIndex, dwValue);
1369 if (!root_context)
1370 return rc;
1372 switch(dwAction)
1374 case NI_CHANGECANDIDATELIST:
1375 FIXME("%s\n","NI_CHANGECANDIDATELIST");
1376 break;
1377 case NI_CLOSECANDIDATE:
1378 FIXME("%s\n","NI_CLOSECANDIDATE");
1379 break;
1380 case NI_COMPOSITIONSTR:
1381 switch (dwIndex)
1383 case CPS_CANCEL:
1384 TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL");
1386 HIMCC newCompStr;
1387 if (pX11DRV_ForceXIMReset)
1388 pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
1390 newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
1391 ImmDestroyIMCC(root_context->IMC.hCompStr);
1392 root_context->IMC.hCompStr = newCompStr;
1394 ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
1395 GCS_COMPSTR);
1396 rc = TRUE;
1398 break;
1399 case CPS_COMPLETE:
1400 TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_COMPLETE");
1401 if (hIMC != (HIMC)FROM_IME && pX11DRV_ForceXIMReset)
1402 pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
1404 HIMCC newCompStr;
1405 DWORD cplen;
1406 LPWSTR cpstr;
1407 LPCOMPOSITIONSTRING cs = NULL;
1408 LPBYTE cdata = NULL;
1410 /* clear existing result */
1411 newCompStr = updateResultStr(root_context->IMC.hCompStr, NULL, 0);
1412 ImmDestroyIMCC(root_context->IMC.hCompStr);
1413 root_context->IMC.hCompStr = newCompStr;
1415 cdata = ImmLockIMCC(root_context->IMC.hCompStr);
1416 cs = (LPCOMPOSITIONSTRING)cdata;
1417 cplen = cs->dwCompStrLen;
1418 cpstr = (LPWSTR)&(cdata[cs->dwCompStrOffset]);
1419 ImmUnlockIMCC(root_context->IMC.hCompStr);
1420 if (cplen > 0)
1422 WCHAR param = cpstr[0];
1423 newCompStr = updateResultStr(root_context->IMC.hCompStr, cpstr, cplen);
1424 ImmDestroyIMCC(root_context->IMC.hCompStr);
1425 root_context->IMC.hCompStr = newCompStr;
1426 newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
1427 ImmDestroyIMCC(root_context->IMC.hCompStr);
1428 root_context->IMC.hCompStr = newCompStr;
1430 root_context->bRead = FALSE;
1432 ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
1433 GCS_COMPSTR);
1435 ImmInternalPostIMEMessage(WM_IME_COMPOSITION,
1436 param,
1437 GCS_RESULTSTR|GCS_RESULTCLAUSE);
1440 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0);
1441 root_context->bInComposition = FALSE;
1443 break;
1444 case CPS_CONVERT:
1445 FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_CONVERT");
1446 break;
1447 case CPS_REVERT:
1448 FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_REVERT");
1449 break;
1450 default:
1451 ERR("%s - %s (%i)\n","NI_COMPOSITIONSTR","UNKNOWN",dwIndex);
1452 break;
1454 break;
1455 case NI_IMEMENUSELECTED:
1456 FIXME("%s\n", "NI_IMEMENUSELECTED");
1457 break;
1458 case NI_OPENCANDIDATE:
1459 FIXME("%s\n", "NI_OPENCANDIDATE");
1460 break;
1461 case NI_SELECTCANDIDATESTR:
1462 FIXME("%s\n", "NI_SELECTCANDIDATESTR");
1463 break;
1464 case NI_SETCANDIDATE_PAGESIZE:
1465 FIXME("%s\n", "NI_SETCANDIDATE_PAGESIZE");
1466 break;
1467 case NI_SETCANDIDATE_PAGESTART:
1468 FIXME("%s\n", "NI_SETCANDIDATE_PAGESTART");
1469 break;
1470 default:
1471 ERR("Unknown\n");
1474 return rc;
1477 /***********************************************************************
1478 * ImmRegisterWordA (IMM32.@)
1480 BOOL WINAPI ImmRegisterWordA(
1481 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
1483 FIXME("(%p, %s, %d, %s): stub\n",
1484 hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister)
1486 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1487 return FALSE;
1490 /***********************************************************************
1491 * ImmRegisterWordW (IMM32.@)
1493 BOOL WINAPI ImmRegisterWordW(
1494 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
1496 FIXME("(%p, %s, %d, %s): stub\n",
1497 hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister)
1499 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1500 return FALSE;
1503 /***********************************************************************
1504 * ImmReleaseContext (IMM32.@)
1506 BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1508 FIXME("(%p, %p): stub\n", hWnd, hIMC);
1510 return TRUE;
1513 /***********************************************************************
1514 * ImmSetCandidateWindow (IMM32.@)
1516 BOOL WINAPI ImmSetCandidateWindow(
1517 HIMC hIMC, LPCANDIDATEFORM lpCandidate)
1519 FIXME("(%p, %p): stub\n", hIMC, lpCandidate);
1520 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1521 return FALSE;
1524 /***********************************************************************
1525 * ImmSetCompositionFontA (IMM32.@)
1527 BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
1529 InputContextData *data = (InputContextData*)hIMC;
1530 TRACE("(%p, %p)\n", hIMC, lplf);
1532 if (!data)
1533 return FALSE;
1535 memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
1536 MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
1537 LF_FACESIZE);
1539 ImmInternalSendIMENotify(IMN_SETCOMPOSITIONFONT, 0);
1541 if (data->textfont)
1543 DeleteObject(data->textfont);
1544 data->textfont = NULL;
1547 data->textfont = CreateFontIndirectW(&data->IMC.lfFont.W);
1548 return TRUE;
1551 /***********************************************************************
1552 * ImmSetCompositionFontW (IMM32.@)
1554 BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
1556 InputContextData *data = (InputContextData*)hIMC;
1557 TRACE("(%p, %p)\n", hIMC, lplf);
1559 if (!data)
1560 return FALSE;
1562 memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTW));
1563 ImmInternalSendIMENotify(IMN_SETCOMPOSITIONFONT, 0);
1565 if (data->textfont)
1567 DeleteObject(data->textfont);
1568 data->textfont = NULL;
1570 data->textfont = CreateFontIndirectW(&data->IMC.lfFont.W);
1571 return TRUE;
1574 /***********************************************************************
1575 * ImmSetCompositionStringA (IMM32.@)
1577 BOOL WINAPI ImmSetCompositionStringA(
1578 HIMC hIMC, DWORD dwIndex,
1579 LPCVOID lpComp, DWORD dwCompLen,
1580 LPCVOID lpRead, DWORD dwReadLen)
1582 DWORD comp_len;
1583 DWORD read_len;
1584 WCHAR *CompBuffer = NULL;
1585 WCHAR *ReadBuffer = NULL;
1586 BOOL rc;
1588 TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
1589 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1591 comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
1592 if (comp_len)
1594 CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len * sizeof(WCHAR));
1595 MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len);
1598 read_len = MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, NULL, 0);
1599 if (read_len)
1601 ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len * sizeof(WCHAR));
1602 MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len);
1605 rc = ImmSetCompositionStringW(hIMC, dwIndex, CompBuffer, comp_len,
1606 ReadBuffer, read_len);
1608 HeapFree(GetProcessHeap(), 0, CompBuffer);
1609 HeapFree(GetProcessHeap(), 0, ReadBuffer);
1611 return rc;
1614 /***********************************************************************
1615 * ImmSetCompositionStringW (IMM32.@)
1617 BOOL WINAPI ImmSetCompositionStringW(
1618 HIMC hIMC, DWORD dwIndex,
1619 LPCVOID lpComp, DWORD dwCompLen,
1620 LPCVOID lpRead, DWORD dwReadLen)
1622 DWORD flags = 0;
1623 WCHAR wParam = 0;
1625 TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
1626 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1629 if (hIMC != (HIMC)FROM_IME)
1630 FIXME("PROBLEM: This only sets the wine level string\n");
1633 * Explanation:
1634 * this sets the composition string in the imm32.dll level
1635 * of the composition buffer. we cannot manipulate the xim level
1636 * buffer, which means that once the xim level buffer changes again
1637 * any call to this function from the application will be lost
1640 if (lpRead && dwReadLen)
1641 FIXME("Reading string unimplemented\n");
1644 * app operating this api to also receive the message from xim
1647 if (dwIndex == SCS_SETSTR)
1649 HIMCC newCompStr;
1650 if (!root_context->bInComposition)
1652 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION, 0, 0);
1653 root_context->bInComposition = TRUE;
1656 flags = GCS_COMPSTR;
1658 if (dwCompLen && lpComp)
1660 newCompStr = updateCompStr(root_context->IMC.hCompStr, (LPWSTR)lpComp, dwCompLen / sizeof(WCHAR));
1661 ImmDestroyIMCC(root_context->IMC.hCompStr);
1662 root_context->IMC.hCompStr = newCompStr;
1664 wParam = ((const WCHAR*)lpComp)[0];
1665 flags |= GCS_COMPCLAUSE | GCS_COMPATTR;
1667 else
1669 newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
1670 ImmDestroyIMCC(root_context->IMC.hCompStr);
1671 root_context->IMC.hCompStr = newCompStr;
1675 UpdateDataInDefaultIMEWindow(hwndDefault,FALSE);
1677 ImmInternalPostIMEMessage(WM_IME_COMPOSITION, wParam, flags);
1679 return TRUE;
1682 /***********************************************************************
1683 * ImmSetCompositionWindow (IMM32.@)
1685 BOOL WINAPI ImmSetCompositionWindow(
1686 HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
1688 BOOL reshow = FALSE;
1689 InputContextData *data = (InputContextData*)hIMC;
1691 TRACE("(%p, %p)\n", hIMC, lpCompForm);
1692 TRACE("\t%x, (%i,%i), (%i,%i - %i,%i)\n",lpCompForm->dwStyle,
1693 lpCompForm->ptCurrentPos.x, lpCompForm->ptCurrentPos.y, lpCompForm->rcArea.top,
1694 lpCompForm->rcArea.left, lpCompForm->rcArea.bottom, lpCompForm->rcArea.right);
1696 if (!data)
1697 return FALSE;
1699 memcpy(&data->IMC.cfCompForm,lpCompForm,sizeof(COMPOSITIONFORM));
1701 if (IsWindowVisible(hwndDefault))
1703 reshow = TRUE;
1704 ShowWindow(hwndDefault,SW_HIDE);
1707 /* FIXME: this is a partial stub */
1709 if (reshow)
1710 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
1712 ImmInternalSendIMENotify(IMN_SETCOMPOSITIONWINDOW, 0);
1713 return TRUE;
1716 /***********************************************************************
1717 * ImmSetConversionStatus (IMM32.@)
1719 BOOL WINAPI ImmSetConversionStatus(
1720 HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
1722 FIXME("(%p, %d, %d): stub\n",
1723 hIMC, fdwConversion, fdwSentence
1725 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1726 return FALSE;
1729 /***********************************************************************
1730 * ImmSetOpenStatus (IMM32.@)
1732 BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
1734 InputContextData *data = (InputContextData*)hIMC;
1736 TRACE("%p %d\n", hIMC, fOpen);
1738 if (hIMC == (HIMC)FROM_IME)
1740 ImmInternalSetOpenStatus(fOpen);
1741 ImmInternalSendIMENotify(IMN_SETOPENSTATUS, 0);
1742 return TRUE;
1745 if (!data)
1746 return FALSE;
1748 if (fOpen != data->bInternalState)
1750 if (fOpen == FALSE && pX11DRV_ForceXIMReset)
1751 pX11DRV_ForceXIMReset(data->IMC.hWnd);
1753 if (fOpen == FALSE)
1754 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
1755 else
1756 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
1758 ImmInternalSetOpenStatus(fOpen);
1759 ImmInternalSetOpenStatus(!fOpen);
1761 if (data->IMC.fOpen == FALSE)
1762 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
1763 else
1764 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
1766 return FALSE;
1768 return TRUE;
1771 /***********************************************************************
1772 * ImmSetStatusWindowPos (IMM32.@)
1774 BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1776 FIXME("(%p, %p): stub\n", hIMC, lpptPos);
1777 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1778 return FALSE;
1781 /***********************************************************************
1782 * ImmSimulateHotKey (IMM32.@)
1784 BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
1786 FIXME("(%p, %d): stub\n", hWnd, dwHotKeyID);
1787 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1788 return FALSE;
1791 /***********************************************************************
1792 * ImmUnregisterWordA (IMM32.@)
1794 BOOL WINAPI ImmUnregisterWordA(
1795 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
1797 FIXME("(%p, %s, %d, %s): stub\n",
1798 hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister)
1800 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1801 return FALSE;
1804 /***********************************************************************
1805 * ImmUnregisterWordW (IMM32.@)
1807 BOOL WINAPI ImmUnregisterWordW(
1808 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
1810 FIXME("(%p, %s, %d, %s): stub\n",
1811 hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister)
1813 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1814 return FALSE;
1817 /***********************************************************************
1818 * ImmGetImeMenuItemsA (IMM32.@)
1820 DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType,
1821 LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
1822 DWORD dwSize)
1824 FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType,
1825 lpImeParentMenu, lpImeMenu, dwSize);
1826 return 0;
1829 /***********************************************************************
1830 * ImmGetImeMenuItemsW (IMM32.@)
1832 DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType,
1833 LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
1834 DWORD dwSize)
1836 FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType,
1837 lpImeParentMenu, lpImeMenu, dwSize);
1838 return 0;
1841 /***********************************************************************
1842 * ImmLockIMC(IMM32.@)
1844 LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
1846 InputContextData *data = (InputContextData*)hIMC;
1848 if (!data)
1849 return NULL;
1850 data->dwLock++;
1851 return &data->IMC;
1854 /***********************************************************************
1855 * ImmUnlockIMC(IMM32.@)
1857 BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
1859 InputContextData *data = (InputContextData*)hIMC;
1860 data->dwLock--;
1861 return (data->dwLock!=0);
1864 /***********************************************************************
1865 * ImmGetIMCLockCount(IMM32.@)
1867 DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
1869 InputContextData *data = (InputContextData*)hIMC;
1870 return data->dwLock;
1873 /***********************************************************************
1874 * ImmCreateIMCC(IMM32.@)
1876 HIMCC WINAPI ImmCreateIMCC(DWORD size)
1878 IMCCInternal *internal;
1879 int real_size = size + sizeof(IMCCInternal);
1881 internal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, real_size);
1882 if (internal == NULL)
1883 return NULL;
1885 internal->dwSize = size;
1886 return (HIMCC)internal;
1889 /***********************************************************************
1890 * ImmDestroyIMCC(IMM32.@)
1892 HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
1894 HeapFree(GetProcessHeap(),0,block);
1895 return NULL;
1898 /***********************************************************************
1899 * ImmLockIMCC(IMM32.@)
1901 LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
1903 IMCCInternal *internal;
1904 internal = (IMCCInternal*) imcc;
1906 internal->dwLock ++;
1907 return internal + 1;
1910 /***********************************************************************
1911 * ImmUnlockIMCC(IMM32.@)
1913 BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
1915 IMCCInternal *internal;
1916 internal = (IMCCInternal*) imcc;
1918 internal->dwLock --;
1919 return (internal->dwLock!=0);
1922 /***********************************************************************
1923 * ImmGetIMCCLockCount(IMM32.@)
1925 DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
1927 IMCCInternal *internal;
1928 internal = (IMCCInternal*) imcc;
1930 return internal->dwLock;
1933 /***********************************************************************
1934 * ImmReSizeIMCC(IMM32.@)
1936 HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
1938 IMCCInternal *internal,*newone;
1939 int real_size = size + sizeof(IMCCInternal);
1941 internal = (IMCCInternal*) imcc;
1943 newone = HeapReAlloc(GetProcessHeap(), 0, internal, real_size);
1944 newone->dwSize = size;
1946 return newone;
1949 /***********************************************************************
1950 * ImmGetIMCCSize(IMM32.@)
1952 DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
1954 IMCCInternal *internal;
1955 internal = (IMCCInternal*) imcc;
1957 return internal->dwSize;
1960 /*****
1961 * Internal functions to help with IME window management
1963 static void PaintDefaultIMEWnd(HWND hwnd)
1965 PAINTSTRUCT ps;
1966 RECT rect;
1967 HDC hdc = BeginPaint(hwnd,&ps);
1968 LPCOMPOSITIONSTRING compstr;
1969 LPBYTE compdata = NULL;
1970 HMONITOR monitor;
1971 MONITORINFO mon_info;
1973 GetClientRect(hwnd,&rect);
1974 FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1));
1976 compdata = ImmLockIMCC(root_context->IMC.hCompStr);
1977 compstr = (LPCOMPOSITIONSTRING)compdata;
1979 if (compstr->dwCompStrLen && compstr->dwCompStrOffset)
1981 SIZE size;
1982 POINT pt;
1983 HFONT oldfont = NULL;
1984 LPWSTR CompString;
1986 CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
1987 if (root_context->textfont)
1988 oldfont = SelectObject(hdc,root_context->textfont);
1991 GetTextExtentPoint32W(hdc, CompString, compstr->dwCompStrLen, &size);
1992 pt.x = size.cx;
1993 pt.y = size.cy;
1994 LPtoDP(hdc,&pt,1);
1996 if (root_context->IMC.cfCompForm.dwStyle == CFS_POINT ||
1997 root_context->IMC.cfCompForm.dwStyle == CFS_FORCE_POSITION)
1999 POINT cpt = root_context->IMC.cfCompForm.ptCurrentPos;
2000 ClientToScreen(root_context->IMC.hWnd,&cpt);
2001 rect.left = cpt.x;
2002 rect.top = cpt.y;
2003 rect.right = rect.left + pt.x + 20;
2004 rect.bottom = rect.top + pt.y + 20;
2005 monitor = MonitorFromPoint(cpt, MONITOR_DEFAULTTOPRIMARY);
2007 else if (root_context->IMC.cfCompForm.dwStyle == CFS_RECT)
2009 rect = root_context->IMC.cfCompForm.rcArea;
2010 MapWindowPoints( root_context->IMC.hWnd, 0, (POINT *)&rect, 2 );
2011 monitor = MonitorFromRect(&rect, MONITOR_DEFAULTTOPRIMARY);
2013 else
2015 /* Windows places the default IME window in the bottom left */
2016 HWND target = root_context->IMC.hWnd;
2017 if (!target) target = GetFocus();
2019 GetWindowRect(target,&rect);
2020 rect.top = rect.bottom;
2021 rect.right = rect.left + pt.x + 20;
2022 rect.bottom = rect.top + pt.y + 20;
2023 monitor = MonitorFromWindow(target, MONITOR_DEFAULTTOPRIMARY);
2026 /* make sure we are on the desktop */
2027 mon_info.cbSize = sizeof(mon_info);
2028 GetMonitorInfoW(monitor, &mon_info);
2030 if (rect.bottom > mon_info.rcWork.bottom)
2032 int shift = rect.bottom - mon_info.rcWork.bottom;
2033 rect.top -= shift;
2034 rect.bottom -= shift;
2036 if (rect.left < 0)
2038 rect.right -= rect.left;
2039 rect.left = 0;
2041 if (rect.right > mon_info.rcWork.right)
2043 int shift = rect.right - mon_info.rcWork.right;
2044 rect.left -= shift;
2045 rect.right -= shift;
2048 SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE);
2050 TextOutW(hdc, 10,10, CompString, compstr->dwCompStrLen);
2052 if (oldfont)
2053 SelectObject(hdc,oldfont);
2056 ImmUnlockIMCC(root_context->IMC.hCompStr);
2058 EndPaint(hwnd,&ps);
2061 static void UpdateDataInDefaultIMEWindow(HWND hwnd, BOOL showable)
2063 LPCOMPOSITIONSTRING compstr;
2065 if (root_context->IMC.hCompStr)
2066 compstr = ImmLockIMCC(root_context->IMC.hCompStr);
2067 else
2068 compstr = NULL;
2070 if (compstr == NULL || compstr->dwCompStrLen == 0)
2071 ShowWindow(hwndDefault,SW_HIDE);
2072 else if (showable)
2073 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
2075 RedrawWindow(hwnd,NULL,NULL,RDW_ERASENOW|RDW_INVALIDATE);
2077 if (compstr != NULL)
2078 ImmUnlockIMCC(root_context->IMC.hCompStr);
2082 * The window proc for the default IME window
2084 static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
2085 LPARAM lParam)
2087 LRESULT rc = 0;
2089 TRACE("Incoming Message 0x%x (0x%08x, 0x%08x)\n", msg, (UINT)wParam,
2090 (UINT)lParam);
2092 switch(msg)
2094 case WM_PAINT:
2095 PaintDefaultIMEWnd(hwnd);
2096 return FALSE;
2098 case WM_NCCREATE:
2099 return TRUE;
2101 case WM_CREATE:
2102 SetWindowTextA(hwnd,"Wine Ime Active");
2103 return TRUE;
2105 case WM_SETFOCUS:
2106 if (wParam)
2107 SetFocus((HWND)wParam);
2108 else
2109 FIXME("Received focus, should never have focus\n");
2110 break;
2111 case WM_IME_COMPOSITION:
2112 TRACE("IME message %s, 0x%x, 0x%x (%i)\n",
2113 "WM_IME_COMPOSITION", (UINT)wParam, (UINT)lParam,
2114 root_context->bRead);
2115 if (lParam & GCS_RESULTSTR)
2116 IMM_PostResult(root_context);
2117 else
2118 UpdateDataInDefaultIMEWindow(hwnd,TRUE);
2119 break;
2120 case WM_IME_STARTCOMPOSITION:
2121 TRACE("IME message %s, 0x%x, 0x%x\n",
2122 "WM_IME_STARTCOMPOSITION", (UINT)wParam, (UINT)lParam);
2123 root_context->IMC.hWnd = GetFocus();
2124 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
2125 break;
2126 case WM_IME_ENDCOMPOSITION:
2127 TRACE("IME message %s, 0x%x, 0x%x\n",
2128 "WM_IME_ENDCOMPOSITION", (UINT)wParam, (UINT)lParam);
2129 ShowWindow(hwndDefault,SW_HIDE);
2130 break;
2131 case WM_IME_SELECT:
2132 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_SELECT",
2133 (UINT)wParam, (UINT)lParam);
2134 break;
2135 case WM_IME_CONTROL:
2136 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_CONTROL",
2137 (UINT)wParam, (UINT)lParam);
2138 rc = 1;
2139 break;
2140 case WM_IME_NOTIFY:
2141 TRACE("!! IME NOTIFY\n");
2142 break;
2143 default:
2144 TRACE("Non-standard message 0x%x\n",msg);
2146 /* check the MSIME messages */
2147 if (msg == WM_MSIME_SERVICE)
2149 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_SERVICE",
2150 (UINT)wParam, (UINT)lParam);
2151 rc = FALSE;
2153 else if (msg == WM_MSIME_RECONVERTOPTIONS)
2155 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTOPTIONS",
2156 (UINT)wParam, (UINT)lParam);
2158 else if (msg == WM_MSIME_MOUSE)
2160 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_MOUSE",
2161 (UINT)wParam, (UINT)lParam);
2163 else if (msg == WM_MSIME_RECONVERTREQUEST)
2165 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTREQUEST",
2166 (UINT)wParam, (UINT)lParam);
2168 else if (msg == WM_MSIME_RECONVERT)
2170 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERT",
2171 (UINT)wParam, (UINT)lParam);
2173 else if (msg == WM_MSIME_QUERYPOSITION)
2175 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_QUERYPOSITION",
2176 (UINT)wParam, (UINT)lParam);
2178 else if (msg == WM_MSIME_DOCUMENTFEED)
2180 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_DOCUMENTFEED",
2181 (UINT)wParam, (UINT)lParam);
2183 /* DefWndProc if not an IME message */
2184 else if (!rc && !((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
2185 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP)))
2186 rc = DefWindowProcW(hwnd,msg,wParam,lParam);
2188 return rc;