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
29 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(imm);
36 #define FROM_IME 0xcafe1337
38 static void (*pX11DRV_ForceXIMReset)(HWND);
40 typedef struct tagIMCCInternal
46 typedef struct tagInputContextData
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;
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;
75 static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
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)
85 LPCOMPOSITIONSTRING compstr;
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)
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)
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)
146 TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
149 case DLL_PROCESS_ATTACH:
150 DisableThreadLibraryCalls(hInstDLL);
152 IMM_RegisterMessages();
153 x11drv = GetModuleHandleA("winex11.drv");
154 if (x11drv) pX11DRV_ForceXIMReset = (void *)GetProcAddress( x11drv, "ForceXIMReset");
156 case DLL_PROCESS_DETACH:
159 DestroyWindow(hwndDefault);
168 /* for posting messages as the IME */
169 static void ImmInternalPostIMEMessage(UINT msg, WPARAM wParam, LPARAM lParam)
171 HWND target = GetFocus();
173 PostMessageW(root_context->IMC.hWnd,msg,wParam,lParam);
175 PostMessageW(target, msg, wParam, lParam);
178 static LRESULT ImmInternalSendIMENotify(WPARAM notify, LPARAM lParam)
182 target = root_context->IMC.hWnd;
183 if (!target) target = GetFocus();
186 return SendMessageW(target, WM_IME_NOTIFY, notify, lParam);
191 static void ImmInternalSetOpenStatus(BOOL fOpen)
193 TRACE("Setting internal state to %s\n",(fOpen)?"OPEN":"CLOSED");
195 if (root_context->IMC.fOpen && fOpen == FALSE)
197 ShowWindow(hwndDefault,SW_HIDE);
198 ImmDestroyIMCC(root_context->IMC.hCompStr);
199 root_context->IMC.hCompStr = NULL;
202 root_context->IMC.fOpen = fOpen;
203 root_context->bInternalState = fOpen;
205 ImmInternalSendIMENotify(IMN_SETOPENSTATUS, 0);
208 static int updateField(DWORD origLen, DWORD origOffset, DWORD currentOffset,
209 LPBYTE target, LPBYTE source, DWORD* lenParam,
210 DWORD* offsetParam, BOOL wchars )
212 if (origLen > 0 && origOffset > 0)
214 int truelen = origLen;
216 truelen *= sizeof(WCHAR);
218 memcpy(&target[currentOffset], &source[origOffset], truelen);
221 *offsetParam = currentOffset;
222 currentOffset += truelen;
224 return currentOffset;
227 static HIMCC updateCompStr(HIMCC old, LPWSTR compstr, DWORD len)
229 /* we need to make sure the CompStr, CompClaus and CompAttr fields are all
233 LPBYTE newdata = NULL;
234 LPBYTE olddata = NULL;
235 LPCOMPOSITIONSTRING new_one;
236 LPCOMPOSITIONSTRING lpcs = NULL;
237 INT current_offset = 0;
239 TRACE("%s, %i\n",debugstr_wn(compstr,len),len);
241 if (old == NULL && compstr == NULL && len == 0)
246 olddata = ImmLockIMCC(old);
247 lpcs = (LPCOMPOSITIONSTRING)olddata;
250 needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
251 len + sizeof(DWORD) * 2;
255 needed_size += lpcs->dwCompReadAttrLen;
256 needed_size += lpcs->dwCompReadClauseLen;
257 needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
258 needed_size += lpcs->dwResultReadClauseLen;
259 needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
260 needed_size += lpcs->dwResultClauseLen;
261 needed_size += lpcs->dwResultStrLen * sizeof(DWORD);
262 needed_size += lpcs->dwPrivateSize;
264 rc = ImmCreateIMCC(needed_size);
265 newdata = ImmLockIMCC(rc);
266 new_one = (LPCOMPOSITIONSTRING)newdata;
268 new_one->dwSize = needed_size;
269 current_offset = sizeof(COMPOSITIONSTRING);
272 current_offset = updateField(lpcs->dwCompReadAttrLen,
273 lpcs->dwCompReadAttrOffset,
274 current_offset, newdata, olddata,
275 &new_one->dwCompReadAttrLen,
276 &new_one->dwCompReadAttrOffset, FALSE);
278 current_offset = updateField(lpcs->dwCompReadClauseLen,
279 lpcs->dwCompReadClauseOffset,
280 current_offset, newdata, olddata,
281 &new_one->dwCompReadClauseLen,
282 &new_one->dwCompReadClauseOffset, FALSE);
284 current_offset = updateField(lpcs->dwCompReadStrLen,
285 lpcs->dwCompReadStrOffset,
286 current_offset, newdata, olddata,
287 &new_one->dwCompReadStrLen,
288 &new_one->dwCompReadStrOffset, TRUE);
290 /* new CompAttr, CompClause, CompStr, dwCursorPos */
291 new_one->dwDeltaStart = 0;
293 current_offset = updateField(lpcs->dwResultReadClauseLen,
294 lpcs->dwResultReadClauseOffset,
295 current_offset, newdata, olddata,
296 &new_one->dwResultReadClauseLen,
297 &new_one->dwResultReadClauseOffset, FALSE);
299 current_offset = updateField(lpcs->dwResultReadStrLen,
300 lpcs->dwResultReadStrOffset,
301 current_offset, newdata, olddata,
302 &new_one->dwResultReadStrLen,
303 &new_one->dwResultReadStrOffset, TRUE);
305 current_offset = updateField(lpcs->dwResultClauseLen,
306 lpcs->dwResultClauseOffset,
307 current_offset, newdata, olddata,
308 &new_one->dwResultClauseLen,
309 &new_one->dwResultClauseOffset, FALSE);
311 current_offset = updateField(lpcs->dwResultStrLen,
312 lpcs->dwResultStrOffset,
313 current_offset, newdata, olddata,
314 &new_one->dwResultStrLen,
315 &new_one->dwResultStrOffset, TRUE);
317 current_offset = updateField(lpcs->dwPrivateSize,
318 lpcs->dwPrivateOffset,
319 current_offset, newdata, olddata,
320 &new_one->dwPrivateSize,
321 &new_one->dwPrivateOffset, FALSE);
326 new_one->dwCompAttrLen = len;
329 new_one->dwCompAttrOffset = current_offset;
330 memset(&newdata[current_offset],ATTR_INPUT,len);
331 current_offset += len;
337 new_one->dwCompClauseLen = sizeof(DWORD) * 2;
338 new_one->dwCompClauseOffset = current_offset;
339 *(DWORD*)(&newdata[current_offset]) = 0;
340 current_offset += sizeof(DWORD);
341 *(DWORD*)(&newdata[current_offset]) = len;
342 current_offset += sizeof(DWORD);
346 new_one->dwCompStrLen = len;
349 new_one->dwCompStrOffset = current_offset;
350 memcpy(&newdata[current_offset],compstr,len*sizeof(WCHAR));
354 new_one->dwCursorPos = len;
363 static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len)
365 /* we need to make sure the ResultStr and ResultClause fields are all
369 LPBYTE newdata = NULL;
370 LPBYTE olddata = NULL;
371 LPCOMPOSITIONSTRING new_one;
372 LPCOMPOSITIONSTRING lpcs = NULL;
373 INT current_offset = 0;
375 TRACE("%s, %i\n",debugstr_wn(resultstr,len),len);
377 if (old == NULL && resultstr == NULL && len == 0)
382 olddata = ImmLockIMCC(old);
383 lpcs = (LPCOMPOSITIONSTRING)olddata;
386 needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
391 needed_size += lpcs->dwCompReadAttrLen;
392 needed_size += lpcs->dwCompReadClauseLen;
393 needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
394 needed_size += lpcs->dwCompAttrLen;
395 needed_size += lpcs->dwCompClauseLen;
396 needed_size += lpcs->dwCompStrLen * sizeof(DWORD);
397 needed_size += lpcs->dwResultReadClauseLen;
398 needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
399 needed_size += lpcs->dwPrivateSize;
401 rc = ImmCreateIMCC(needed_size);
402 newdata = ImmLockIMCC(rc);
403 new_one = (LPCOMPOSITIONSTRING)newdata;
405 new_one->dwSize = needed_size;
406 current_offset = sizeof(COMPOSITIONSTRING);
409 current_offset = updateField(lpcs->dwCompReadAttrLen,
410 lpcs->dwCompReadAttrOffset,
411 current_offset, newdata, olddata,
412 &new_one->dwCompReadAttrLen,
413 &new_one->dwCompReadAttrOffset, FALSE);
415 current_offset = updateField(lpcs->dwCompReadClauseLen,
416 lpcs->dwCompReadClauseOffset,
417 current_offset, newdata, olddata,
418 &new_one->dwCompReadClauseLen,
419 &new_one->dwCompReadClauseOffset, FALSE);
421 current_offset = updateField(lpcs->dwCompReadStrLen,
422 lpcs->dwCompReadStrOffset,
423 current_offset, newdata, olddata,
424 &new_one->dwCompReadStrLen,
425 &new_one->dwCompReadStrOffset, TRUE);
427 current_offset = updateField(lpcs->dwCompAttrLen,
428 lpcs->dwCompAttrOffset,
429 current_offset, newdata, olddata,
430 &new_one->dwCompAttrLen,
431 &new_one->dwCompAttrOffset, FALSE);
433 current_offset = updateField(lpcs->dwCompClauseLen,
434 lpcs->dwCompClauseOffset,
435 current_offset, newdata, olddata,
436 &new_one->dwCompClauseLen,
437 &new_one->dwCompClauseOffset, FALSE);
439 current_offset = updateField(lpcs->dwCompStrLen,
440 lpcs->dwCompStrOffset,
441 current_offset, newdata, olddata,
442 &new_one->dwCompStrLen,
443 &new_one->dwCompStrOffset, TRUE);
445 new_one->dwCursorPos = lpcs->dwCursorPos;
446 new_one->dwDeltaStart = 0;
448 current_offset = updateField(lpcs->dwResultReadClauseLen,
449 lpcs->dwResultReadClauseOffset,
450 current_offset, newdata, olddata,
451 &new_one->dwResultReadClauseLen,
452 &new_one->dwResultReadClauseOffset, FALSE);
454 current_offset = updateField(lpcs->dwResultReadStrLen,
455 lpcs->dwResultReadStrOffset,
456 current_offset, newdata, olddata,
457 &new_one->dwResultReadStrLen,
458 &new_one->dwResultReadStrOffset, TRUE);
460 /* new ResultClause , ResultStr */
462 current_offset = updateField(lpcs->dwPrivateSize,
463 lpcs->dwPrivateOffset,
464 current_offset, newdata, olddata,
465 &new_one->dwPrivateSize,
466 &new_one->dwPrivateOffset, FALSE);
473 new_one->dwResultClauseLen = sizeof(DWORD) * 2;
474 new_one->dwResultClauseOffset = current_offset;
475 *(DWORD*)(&newdata[current_offset]) = 0;
476 current_offset += sizeof(DWORD);
477 *(DWORD*)(&newdata[current_offset]) = len;
478 current_offset += sizeof(DWORD);
482 new_one->dwResultStrLen = len;
485 new_one->dwResultStrOffset = current_offset;
486 memcpy(&newdata[current_offset],resultstr,len*sizeof(WCHAR));
497 /***********************************************************************
498 * ImmAssociateContext (IMM32.@)
500 HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
502 InputContextData *data = (InputContextData*)hIMC;
504 WARN("(%p, %p): semi-stub\n", hWnd, hIMC);
510 * WINE SPECIFIC! MAY CONFLICT
511 * associate the root context we have an XIM created
515 root_context = (InputContextData*)hIMC;
519 * If already associated just return
521 if (data->IMC.hWnd == hWnd)
524 if (IsWindow(data->IMC.hWnd))
527 * Post a message that your context is switching
529 SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
532 data->IMC.hWnd = hWnd;
534 if (IsWindow(data->IMC.hWnd))
537 * Post a message that your context is switching
539 SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
543 * TODO: We need to keep track of the old context associated
544 * with a window and return it for now we will return NULL;
549 /***********************************************************************
550 * ImmAssociateContextEx (IMM32.@)
552 BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
554 FIXME("(%p, %p, %d): stub\n", hWnd, hIMC, dwFlags);
555 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
559 /***********************************************************************
560 * ImmConfigureIMEA (IMM32.@)
562 BOOL WINAPI ImmConfigureIMEA(
563 HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
565 FIXME("(%p, %p, %d, %p): stub\n",
566 hKL, hWnd, dwMode, lpData
568 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
572 /***********************************************************************
573 * ImmConfigureIMEW (IMM32.@)
575 BOOL WINAPI ImmConfigureIMEW(
576 HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
578 FIXME("(%p, %p, %d, %p): stub\n",
579 hKL, hWnd, dwMode, lpData
581 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
585 /***********************************************************************
586 * ImmCreateContext (IMM32.@)
588 HIMC WINAPI ImmCreateContext(void)
590 InputContextData *new_context;
592 new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
594 return (HIMC)new_context;
597 /***********************************************************************
598 * ImmDestroyContext (IMM32.@)
600 BOOL WINAPI ImmDestroyContext(HIMC hIMC)
602 InputContextData *data = (InputContextData*)hIMC;
604 TRACE("Destroying %p\n",hIMC);
608 ImmDestroyIMCC(root_context->IMC.hCompStr);
609 ImmDestroyIMCC(root_context->IMC.hCandInfo);
610 ImmDestroyIMCC(root_context->IMC.hGuideLine);
611 ImmDestroyIMCC(root_context->IMC.hPrivate);
612 ImmDestroyIMCC(root_context->IMC.hMsgBuf);
616 DeleteObject(data->textfont);
617 data->textfont = NULL;
620 HeapFree(GetProcessHeap(),0,data);
625 /***********************************************************************
626 * ImmDisableIME (IMM32.@)
628 BOOL WINAPI ImmDisableIME(DWORD idThread)
630 FIXME("(%d): stub\n", idThread);
634 /***********************************************************************
635 * ImmEnumRegisterWordA (IMM32.@)
637 UINT WINAPI ImmEnumRegisterWordA(
638 HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
639 LPCSTR lpszReading, DWORD dwStyle,
640 LPCSTR lpszRegister, LPVOID lpData)
642 FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
644 debugstr_a(lpszReading), dwStyle,
645 debugstr_a(lpszRegister), lpData
647 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
651 /***********************************************************************
652 * ImmEnumRegisterWordW (IMM32.@)
654 UINT WINAPI ImmEnumRegisterWordW(
655 HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
656 LPCWSTR lpszReading, DWORD dwStyle,
657 LPCWSTR lpszRegister, LPVOID lpData)
659 FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
661 debugstr_w(lpszReading), dwStyle,
662 debugstr_w(lpszRegister), lpData
664 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
668 /***********************************************************************
669 * ImmEscapeA (IMM32.@)
671 LRESULT WINAPI ImmEscapeA(
673 UINT uEscape, LPVOID lpData)
675 FIXME("(%p, %p, %d, %p): stub\n",
676 hKL, hIMC, uEscape, lpData
678 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
682 /***********************************************************************
683 * ImmEscapeW (IMM32.@)
685 LRESULT WINAPI ImmEscapeW(
687 UINT uEscape, LPVOID lpData)
689 FIXME("(%p, %p, %d, %p): stub\n",
690 hKL, hIMC, uEscape, lpData
692 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
696 /***********************************************************************
697 * ImmGetCandidateListA (IMM32.@)
699 DWORD WINAPI ImmGetCandidateListA(
700 HIMC hIMC, DWORD deIndex,
701 LPCANDIDATELIST lpCandList, DWORD dwBufLen)
703 FIXME("(%p, %d, %p, %d): stub\n",
707 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
711 /***********************************************************************
712 * ImmGetCandidateListCountA (IMM32.@)
714 DWORD WINAPI ImmGetCandidateListCountA(
715 HIMC hIMC, LPDWORD lpdwListCount)
717 FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
718 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
722 /***********************************************************************
723 * ImmGetCandidateListCountW (IMM32.@)
725 DWORD WINAPI ImmGetCandidateListCountW(
726 HIMC hIMC, LPDWORD lpdwListCount)
728 FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
729 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
733 /***********************************************************************
734 * ImmGetCandidateListW (IMM32.@)
736 DWORD WINAPI ImmGetCandidateListW(
737 HIMC hIMC, DWORD deIndex,
738 LPCANDIDATELIST lpCandList, DWORD dwBufLen)
740 FIXME("(%p, %d, %p, %d): stub\n",
744 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
748 /***********************************************************************
749 * ImmGetCandidateWindow (IMM32.@)
751 BOOL WINAPI ImmGetCandidateWindow(
752 HIMC hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
754 FIXME("(%p, %d, %p): stub\n", hIMC, dwBufLen, lpCandidate);
755 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
759 /***********************************************************************
760 * ImmGetCompositionFontA (IMM32.@)
762 BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
764 FIXME("(%p, %p): stub\n", hIMC, lplf);
765 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
769 /***********************************************************************
770 * ImmGetCompositionFontW (IMM32.@)
772 BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
774 FIXME("(%p, %p): stub\n", hIMC, lplf);
775 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
779 /***********************************************************************
780 * ImmGetCompositionStringA (IMM32.@)
782 LONG WINAPI ImmGetCompositionStringA(
783 HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
787 InputContextData *data = (InputContextData*)hIMC;
788 LPCOMPOSITIONSTRING compstr;
791 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
796 if (!data->IMC.hCompStr)
799 compdata = ImmLockIMCC(data->IMC.hCompStr);
800 compstr = (LPCOMPOSITIONSTRING)compdata;
802 if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
803 compstr->dwResultStrOffset > 0)
805 LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
807 TRACE("GSC_RESULTSTR %p %i\n",ResultStr,
808 compstr->dwResultStrLen);
810 buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwResultStrLen * 3 );
811 rc = WideCharToMultiByte(CP_ACP, 0, ResultStr,
812 compstr->dwResultStrLen , buf,
813 compstr->dwResultStrLen * 3, NULL, NULL);
815 memcpy(lpBuf,buf,rc);
818 HeapFree( GetProcessHeap(), 0, buf );
820 else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
821 compstr->dwCompStrOffset > 0)
823 LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
825 TRACE("GSC_COMPSTR %p %i\n", CompString, compstr->dwCompStrLen);
827 buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwCompStrLen * 3 );
828 rc = WideCharToMultiByte(CP_ACP, 0, CompString,
829 compstr->dwCompStrLen, buf,
830 compstr->dwCompStrLen * 3, NULL, NULL);
832 memcpy(lpBuf,buf,rc);
833 HeapFree( GetProcessHeap(), 0, buf );
835 else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
836 compstr->dwCompAttrOffset > 0)
838 LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
839 TRACE("GSC_COMPATTR %p %i\n", Compattr , compstr->dwCompAttrLen);
841 rc = compstr->dwCompAttrLen;
843 memcpy(lpBuf,Compattr,rc);
845 else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
846 compstr->dwCompClauseOffset > 0)
848 LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
849 TRACE("GSC_COMPCLAUSE %p %i\n", Compclause, compstr->dwCompClauseLen);
851 rc = compstr->dwCompClauseLen;
852 if (dwBufLen >= compstr->dwCompClauseLen)
853 memcpy(lpBuf,Compclause,rc);
855 else if (dwIndex == GCS_RESULTCLAUSE && compstr->dwResultClauseLen > 0 &&
856 compstr->dwResultClauseOffset > 0)
858 LPWSTR Resultclause = (LPWSTR)(compdata + compstr->dwResultClauseOffset);
859 TRACE("GSC_RESULTCLAUSE %p %i\n", Resultclause, compstr->dwResultClauseLen);
861 rc = compstr->dwResultClauseLen;
862 if (dwBufLen >= compstr->dwResultClauseLen)
863 memcpy(lpBuf,Resultclause,rc);
865 else if (dwIndex == GCS_CURSORPOS)
867 TRACE("GSC_CURSORPOS\n");
868 rc = compstr->dwCursorPos;
870 else if (dwIndex == GCS_DELTASTART)
872 TRACE("GCS_DELTASTART\n");
873 rc = compstr->dwDeltaStart;
877 FIXME("Unhandled index 0x%x\n",dwIndex);
880 ImmUnlockIMCC(data->IMC.hCompStr);
885 /***********************************************************************
886 * ImmGetCompositionStringW (IMM32.@)
888 LONG WINAPI ImmGetCompositionStringW(
889 HIMC hIMC, DWORD dwIndex,
890 LPVOID lpBuf, DWORD dwBufLen)
893 InputContextData *data = (InputContextData*)hIMC;
894 LPCOMPOSITIONSTRING compstr;
897 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
902 if (!data->IMC.hCompStr)
905 compdata = ImmLockIMCC(data->IMC.hCompStr);
906 compstr = (LPCOMPOSITIONSTRING)compdata;
908 if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
909 compstr->dwResultStrOffset > 0)
911 LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
913 rc = compstr->dwResultStrLen * sizeof(WCHAR);
916 memcpy(lpBuf,ResultStr,rc);
918 else if (dwIndex == GCS_RESULTREADSTR && compstr->dwResultReadStrLen > 0 &&
919 compstr->dwResultReadStrOffset > 0)
921 LPWSTR ResultReadString = (LPWSTR)(compdata + compstr->dwResultReadStrOffset);
923 rc = compstr->dwResultReadStrLen * sizeof(WCHAR);
925 memcpy(lpBuf,ResultReadString,rc);
927 else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
928 compstr->dwCompStrOffset > 0)
930 LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
931 rc = compstr->dwCompStrLen * sizeof(WCHAR);
933 memcpy(lpBuf,CompString,rc);
935 else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
936 compstr->dwCompAttrOffset > 0)
939 LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
941 rc = compstr->dwCompAttrLen;
943 memcpy(lpBuf,Compattr,rc);
945 else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
946 compstr->dwCompClauseOffset > 0)
948 LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
950 rc = compstr->dwCompClauseLen;
951 if (dwBufLen >= compstr->dwCompClauseLen)
952 memcpy(lpBuf,Compclause,rc);
954 else if (dwIndex == GCS_COMPREADSTR && compstr->dwCompReadStrLen > 0 &&
955 compstr->dwCompReadStrOffset > 0)
957 LPWSTR CompReadString = (LPWSTR)(compdata + compstr->dwCompReadStrOffset);
959 rc = compstr->dwCompReadStrLen * sizeof(WCHAR);
962 memcpy(lpBuf,CompReadString,rc);
964 else if (dwIndex == GCS_CURSORPOS)
966 TRACE("GSC_CURSORPOS\n");
967 rc = compstr->dwCursorPos;
969 else if (dwIndex == GCS_DELTASTART)
971 TRACE("GCS_DELTASTART\n");
972 rc = compstr->dwDeltaStart;
976 FIXME("Unhandled index 0x%x\n",dwIndex);
979 ImmUnlockIMCC(data->IMC.hCompStr);
984 /***********************************************************************
985 * ImmGetCompositionWindow (IMM32.@)
987 BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
989 InputContextData *data = (InputContextData*)hIMC;
991 TRACE("(%p, %p)\n", hIMC, lpCompForm);
996 memcpy(lpCompForm,&(data->IMC.cfCompForm),sizeof(COMPOSITIONFORM));
1000 /***********************************************************************
1001 * ImmGetContext (IMM32.@)
1004 HIMC WINAPI ImmGetContext(HWND hWnd)
1006 TRACE("%p\n", hWnd);
1011 root_context->IMC.hWnd = hWnd;
1012 return (HIMC)root_context;
1015 /***********************************************************************
1016 * ImmGetConversionListA (IMM32.@)
1018 DWORD WINAPI ImmGetConversionListA(
1020 LPCSTR pSrc, LPCANDIDATELIST lpDst,
1021 DWORD dwBufLen, UINT uFlag)
1023 FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
1024 hKL, hIMC, debugstr_a(pSrc), lpDst, dwBufLen, uFlag
1026 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1030 /***********************************************************************
1031 * ImmGetConversionListW (IMM32.@)
1033 DWORD WINAPI ImmGetConversionListW(
1035 LPCWSTR pSrc, LPCANDIDATELIST lpDst,
1036 DWORD dwBufLen, UINT uFlag)
1038 FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
1039 hKL, hIMC, debugstr_w(pSrc), lpDst, dwBufLen, uFlag
1041 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1045 /***********************************************************************
1046 * ImmGetConversionStatus (IMM32.@)
1048 BOOL WINAPI ImmGetConversionStatus(
1049 HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
1051 TRACE("(%p, %p, %p): best guess\n", hIMC, lpfdwConversion, lpfdwSentence);
1052 if (lpfdwConversion)
1053 *lpfdwConversion = IME_CMODE_NATIVE;
1055 *lpfdwSentence = IME_SMODE_NONE;
1059 /***********************************************************************
1060 * ImmGetDefaultIMEWnd (IMM32.@)
1062 HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
1064 static int shown = 0;
1067 FIXME("(%p - %p %p ): semi-stub\n", hWnd,hwndDefault, root_context);
1071 if (hwndDefault == NULL)
1073 static const WCHAR the_name[] = {'I','M','E','\0'};
1076 hwndDefault = CreateWindowExW( WS_EX_TOOLWINDOW, WC_IMECLASSNAME,
1077 the_name, WS_POPUP, 0, 0, 1, 1, 0, 0,
1080 TRACE("Default created (%p)\n",hwndDefault);
1086 /***********************************************************************
1087 * ImmGetDescriptionA (IMM32.@)
1089 UINT WINAPI ImmGetDescriptionA(
1090 HKL hKL, LPSTR lpszDescription, UINT uBufLen)
1095 TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
1097 /* find out how many characters in the unicode buffer */
1098 len = ImmGetDescriptionW( hKL, NULL, 0 );
1100 /* allocate a buffer of that size */
1101 buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
1105 /* fetch the unicode buffer */
1106 len = ImmGetDescriptionW( hKL, buf, len + 1 );
1108 /* convert it back to ASCII */
1109 len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
1110 lpszDescription, uBufLen, NULL, NULL );
1112 HeapFree( GetProcessHeap(), 0, buf );
1117 /***********************************************************************
1118 * ImmGetDescriptionW (IMM32.@)
1120 UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
1122 static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
1124 FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
1126 if (!uBufLen) return lstrlenW( name );
1127 lstrcpynW( lpszDescription, name, uBufLen );
1128 return lstrlenW( lpszDescription );
1131 /***********************************************************************
1132 * ImmGetGuideLineA (IMM32.@)
1134 DWORD WINAPI ImmGetGuideLineA(
1135 HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
1137 FIXME("(%p, %d, %s, %d): stub\n",
1138 hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
1140 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1144 /***********************************************************************
1145 * ImmGetGuideLineW (IMM32.@)
1147 DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
1149 FIXME("(%p, %d, %s, %d): stub\n",
1150 hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
1152 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1156 /***********************************************************************
1157 * ImmGetIMEFileNameA (IMM32.@)
1159 UINT WINAPI ImmGetIMEFileNameA(
1160 HKL hKL, LPSTR lpszFileName, UINT uBufLen)
1162 FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
1163 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1167 /***********************************************************************
1168 * ImmGetIMEFileNameW (IMM32.@)
1170 UINT WINAPI ImmGetIMEFileNameW(
1171 HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
1173 FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
1174 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1178 /***********************************************************************
1179 * ImmGetOpenStatus (IMM32.@)
1181 BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
1183 InputContextData *data = (InputContextData*)hIMC;
1187 FIXME("(%p): semi-stub\n", hIMC);
1189 return data->IMC.fOpen;
1192 /***********************************************************************
1193 * ImmGetProperty (IMM32.@)
1195 DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
1198 TRACE("(%p, %d)\n", hKL, fdwIndex);
1203 TRACE("(%s)\n", "IGP_PROPERTY");
1204 rc = IME_PROP_UNICODE | IME_PROP_AT_CARET;
1206 case IGP_CONVERSION:
1207 FIXME("(%s)\n", "IGP_CONVERSION");
1208 rc = IME_CMODE_NATIVE;
1211 FIXME("%s)\n", "IGP_SENTENCE");
1212 rc = IME_SMODE_AUTOMATIC;
1214 case IGP_SETCOMPSTR:
1215 TRACE("(%s)\n", "IGP_SETCOMPSTR");
1219 TRACE("(%s)\n", "IGP_SELECT");
1220 rc = SELECT_CAP_CONVERSION | SELECT_CAP_SENTENCE;
1222 case IGP_GETIMEVERSION:
1223 TRACE("(%s)\n", "IGP_GETIMEVERSION");
1227 TRACE("(%s)\n", "IGP_UI");
1236 /***********************************************************************
1237 * ImmGetRegisterWordStyleA (IMM32.@)
1239 UINT WINAPI ImmGetRegisterWordStyleA(
1240 HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
1242 FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
1243 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1247 /***********************************************************************
1248 * ImmGetRegisterWordStyleW (IMM32.@)
1250 UINT WINAPI ImmGetRegisterWordStyleW(
1251 HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
1253 FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
1254 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1258 /***********************************************************************
1259 * ImmGetStatusWindowPos (IMM32.@)
1261 BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1263 FIXME("(%p, %p): stub\n", hIMC, lpptPos);
1264 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1268 /***********************************************************************
1269 * ImmGetVirtualKey (IMM32.@)
1271 UINT WINAPI ImmGetVirtualKey(HWND hWnd)
1273 OSVERSIONINFOA version;
1274 FIXME("(%p): stub\n", hWnd);
1275 GetVersionExA( &version );
1276 switch(version.dwPlatformId)
1278 case VER_PLATFORM_WIN32_WINDOWS:
1279 return VK_PROCESSKEY;
1280 case VER_PLATFORM_WIN32_NT:
1283 FIXME("%d not supported\n",version.dwPlatformId);
1284 return VK_PROCESSKEY;
1288 /***********************************************************************
1289 * ImmInstallIMEA (IMM32.@)
1291 HKL WINAPI ImmInstallIMEA(
1292 LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
1294 FIXME("(%s, %s): stub\n",
1295 debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
1297 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1301 /***********************************************************************
1302 * ImmInstallIMEW (IMM32.@)
1304 HKL WINAPI ImmInstallIMEW(
1305 LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
1307 FIXME("(%s, %s): stub\n",
1308 debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
1310 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1314 /***********************************************************************
1315 * ImmIsIME (IMM32.@)
1317 BOOL WINAPI ImmIsIME(HKL hKL)
1319 TRACE("(%p): semi-stub\n", hKL);
1321 * FIXME: Dead key locales will return TRUE here when they should not
1322 * There is probably a more proper way to check this.
1324 return (root_context != NULL);
1327 /***********************************************************************
1328 * ImmIsUIMessageA (IMM32.@)
1330 BOOL WINAPI ImmIsUIMessageA(
1331 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1335 TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
1336 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1337 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1338 (msg == WM_MSIME_SERVICE) ||
1339 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1340 (msg == WM_MSIME_MOUSE) ||
1341 (msg == WM_MSIME_RECONVERTREQUEST) ||
1342 (msg == WM_MSIME_RECONVERT) ||
1343 (msg == WM_MSIME_QUERYPOSITION) ||
1344 (msg == WM_MSIME_DOCUMENTFEED))
1348 ImmGetDefaultIMEWnd(NULL);
1350 if (hWndIME == NULL)
1351 PostMessageA(hwndDefault, msg, wParam, lParam);
1358 /***********************************************************************
1359 * ImmIsUIMessageW (IMM32.@)
1361 BOOL WINAPI ImmIsUIMessageW(
1362 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1365 TRACE("(%p, %d, %ld, %ld): stub\n", hWndIME, msg, wParam, lParam);
1366 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1367 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1368 (msg == WM_MSIME_SERVICE) ||
1369 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1370 (msg == WM_MSIME_MOUSE) ||
1371 (msg == WM_MSIME_RECONVERTREQUEST) ||
1372 (msg == WM_MSIME_RECONVERT) ||
1373 (msg == WM_MSIME_QUERYPOSITION) ||
1374 (msg == WM_MSIME_DOCUMENTFEED))
1379 /***********************************************************************
1380 * ImmNotifyIME (IMM32.@)
1382 BOOL WINAPI ImmNotifyIME(
1383 HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
1387 TRACE("(%p, %d, %d, %d)\n",
1388 hIMC, dwAction, dwIndex, dwValue);
1395 case NI_CHANGECANDIDATELIST:
1396 FIXME("%s\n","NI_CHANGECANDIDATELIST");
1398 case NI_CLOSECANDIDATE:
1399 FIXME("%s\n","NI_CLOSECANDIDATE");
1401 case NI_COMPOSITIONSTR:
1405 TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL");
1409 if (pX11DRV_ForceXIMReset)
1410 pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
1412 send = (root_context->IMC.hCompStr!=NULL);
1414 ImmDestroyIMCC(root_context->IMC.hCompStr);
1415 root_context->IMC.hCompStr = NULL;
1418 ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
1424 TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_COMPLETE");
1425 if (hIMC != (HIMC)FROM_IME && pX11DRV_ForceXIMReset)
1426 pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
1431 LPCOMPOSITIONSTRING cs = NULL;
1432 LPBYTE cdata = NULL;
1434 /* clear existing result */
1435 newCompStr = updateResultStr(root_context->IMC.hCompStr, NULL, 0);
1436 ImmDestroyIMCC(root_context->IMC.hCompStr);
1437 root_context->IMC.hCompStr = newCompStr;
1439 if (root_context->IMC.hCompStr)
1441 cdata = ImmLockIMCC(root_context->IMC.hCompStr);
1442 cs = (LPCOMPOSITIONSTRING)cdata;
1443 cplen = cs->dwCompStrLen;
1444 cpstr = (LPWSTR)&(cdata[cs->dwCompStrOffset]);
1445 ImmUnlockIMCC(root_context->IMC.hCompStr);
1449 WCHAR param = cpstr[0];
1450 newCompStr = updateResultStr(root_context->IMC.hCompStr, cpstr, cplen);
1451 ImmDestroyIMCC(root_context->IMC.hCompStr);
1452 root_context->IMC.hCompStr = newCompStr;
1453 newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
1454 ImmDestroyIMCC(root_context->IMC.hCompStr);
1455 root_context->IMC.hCompStr = newCompStr;
1457 root_context->bRead = FALSE;
1459 ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
1462 ImmInternalPostIMEMessage(WM_IME_COMPOSITION,
1464 GCS_RESULTSTR|GCS_RESULTCLAUSE);
1467 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0);
1468 root_context->bInComposition = FALSE;
1472 FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_CONVERT");
1475 FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_REVERT");
1478 ERR("%s - %s (%i)\n","NI_COMPOSITIONSTR","UNKNOWN",dwIndex);
1482 case NI_IMEMENUSELECTED:
1483 FIXME("%s\n", "NI_IMEMENUSELECTED");
1485 case NI_OPENCANDIDATE:
1486 FIXME("%s\n", "NI_OPENCANDIDATE");
1488 case NI_SELECTCANDIDATESTR:
1489 FIXME("%s\n", "NI_SELECTCANDIDATESTR");
1491 case NI_SETCANDIDATE_PAGESIZE:
1492 FIXME("%s\n", "NI_SETCANDIDATE_PAGESIZE");
1494 case NI_SETCANDIDATE_PAGESTART:
1495 FIXME("%s\n", "NI_SETCANDIDATE_PAGESTART");
1504 /***********************************************************************
1505 * ImmRegisterWordA (IMM32.@)
1507 BOOL WINAPI ImmRegisterWordA(
1508 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
1510 FIXME("(%p, %s, %d, %s): stub\n",
1511 hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister)
1513 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1517 /***********************************************************************
1518 * ImmRegisterWordW (IMM32.@)
1520 BOOL WINAPI ImmRegisterWordW(
1521 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
1523 FIXME("(%p, %s, %d, %s): stub\n",
1524 hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister)
1526 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1530 /***********************************************************************
1531 * ImmReleaseContext (IMM32.@)
1533 BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1535 static int shown = 0;
1538 FIXME("(%p, %p): stub\n", hWnd, hIMC);
1544 /***********************************************************************
1545 * ImmSetCandidateWindow (IMM32.@)
1547 BOOL WINAPI ImmSetCandidateWindow(
1548 HIMC hIMC, LPCANDIDATEFORM lpCandidate)
1550 FIXME("(%p, %p): stub\n", hIMC, lpCandidate);
1551 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1555 /***********************************************************************
1556 * ImmSetCompositionFontA (IMM32.@)
1558 BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
1560 InputContextData *data = (InputContextData*)hIMC;
1561 TRACE("(%p, %p)\n", hIMC, lplf);
1566 memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
1567 MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
1570 ImmInternalSendIMENotify(IMN_SETCOMPOSITIONFONT, 0);
1574 DeleteObject(data->textfont);
1575 data->textfont = NULL;
1578 data->textfont = CreateFontIndirectW(&data->IMC.lfFont.W);
1582 /***********************************************************************
1583 * ImmSetCompositionFontW (IMM32.@)
1585 BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
1587 InputContextData *data = (InputContextData*)hIMC;
1588 TRACE("(%p, %p)\n", hIMC, lplf);
1593 memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTW));
1594 ImmInternalSendIMENotify(IMN_SETCOMPOSITIONFONT, 0);
1598 DeleteObject(data->textfont);
1599 data->textfont = NULL;
1601 data->textfont = CreateFontIndirectW(&data->IMC.lfFont.W);
1605 /***********************************************************************
1606 * ImmSetCompositionStringA (IMM32.@)
1608 BOOL WINAPI ImmSetCompositionStringA(
1609 HIMC hIMC, DWORD dwIndex,
1610 LPCVOID lpComp, DWORD dwCompLen,
1611 LPCVOID lpRead, DWORD dwReadLen)
1615 WCHAR *CompBuffer = NULL;
1616 WCHAR *ReadBuffer = NULL;
1619 TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
1620 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1622 comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
1625 CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len * sizeof(WCHAR));
1626 MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len);
1629 read_len = MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, NULL, 0);
1632 ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len * sizeof(WCHAR));
1633 MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len);
1636 rc = ImmSetCompositionStringW(hIMC, dwIndex, CompBuffer, comp_len,
1637 ReadBuffer, read_len);
1639 HeapFree(GetProcessHeap(), 0, CompBuffer);
1640 HeapFree(GetProcessHeap(), 0, ReadBuffer);
1645 /***********************************************************************
1646 * ImmSetCompositionStringW (IMM32.@)
1648 BOOL WINAPI ImmSetCompositionStringW(
1649 HIMC hIMC, DWORD dwIndex,
1650 LPCVOID lpComp, DWORD dwCompLen,
1651 LPCVOID lpRead, DWORD dwReadLen)
1656 TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
1657 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1660 if (hIMC != (HIMC)FROM_IME)
1661 FIXME("PROBLEM: This only sets the wine level string\n");
1665 * this sets the composition string in the imm32.dll level
1666 * of the composition buffer. we cannot manipulate the xim level
1667 * buffer, which means that once the xim level buffer changes again
1668 * any call to this function from the application will be lost
1671 if (lpRead && dwReadLen)
1672 FIXME("Reading string unimplemented\n");
1675 * app operating this api to also receive the message from xim
1678 if (dwIndex == SCS_SETSTR)
1681 if (!root_context->bInComposition)
1683 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION, 0, 0);
1684 root_context->bInComposition = TRUE;
1687 flags = GCS_COMPSTR;
1689 if (dwCompLen && lpComp)
1691 newCompStr = updateCompStr(root_context->IMC.hCompStr, (LPWSTR)lpComp, dwCompLen / sizeof(WCHAR));
1692 ImmDestroyIMCC(root_context->IMC.hCompStr);
1693 root_context->IMC.hCompStr = newCompStr;
1695 wParam = ((const WCHAR*)lpComp)[0];
1696 flags |= GCS_COMPCLAUSE | GCS_COMPATTR | GCS_DELTASTART;
1700 newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
1701 ImmDestroyIMCC(root_context->IMC.hCompStr);
1702 root_context->IMC.hCompStr = newCompStr;
1706 UpdateDataInDefaultIMEWindow(hwndDefault,FALSE);
1708 ImmInternalPostIMEMessage(WM_IME_COMPOSITION, wParam, flags);
1713 /***********************************************************************
1714 * ImmSetCompositionWindow (IMM32.@)
1716 BOOL WINAPI ImmSetCompositionWindow(
1717 HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
1719 BOOL reshow = FALSE;
1720 InputContextData *data = (InputContextData*)hIMC;
1722 TRACE("(%p, %p)\n", hIMC, lpCompForm);
1723 TRACE("\t%x, (%i,%i), (%i,%i - %i,%i)\n",lpCompForm->dwStyle,
1724 lpCompForm->ptCurrentPos.x, lpCompForm->ptCurrentPos.y, lpCompForm->rcArea.top,
1725 lpCompForm->rcArea.left, lpCompForm->rcArea.bottom, lpCompForm->rcArea.right);
1730 memcpy(&data->IMC.cfCompForm,lpCompForm,sizeof(COMPOSITIONFORM));
1732 if (IsWindowVisible(hwndDefault))
1735 ShowWindow(hwndDefault,SW_HIDE);
1738 /* FIXME: this is a partial stub */
1741 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
1743 ImmInternalSendIMENotify(IMN_SETCOMPOSITIONWINDOW, 0);
1747 /***********************************************************************
1748 * ImmSetConversionStatus (IMM32.@)
1750 BOOL WINAPI ImmSetConversionStatus(
1751 HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
1753 static int shown = 0;
1756 FIXME("(%p, %d, %d): stub\n",
1757 hIMC, fdwConversion, fdwSentence
1761 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1765 /***********************************************************************
1766 * ImmSetOpenStatus (IMM32.@)
1768 BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
1770 InputContextData *data = (InputContextData*)hIMC;
1772 TRACE("%p %d\n", hIMC, fOpen);
1774 if (hIMC == (HIMC)FROM_IME)
1776 ImmInternalSetOpenStatus(fOpen);
1777 ImmInternalSendIMENotify(IMN_SETOPENSTATUS, 0);
1784 if (fOpen != data->bInternalState)
1786 if (fOpen == FALSE && pX11DRV_ForceXIMReset)
1787 pX11DRV_ForceXIMReset(data->IMC.hWnd);
1790 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
1792 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
1794 ImmInternalSetOpenStatus(fOpen);
1795 ImmInternalSetOpenStatus(!fOpen);
1797 if (data->IMC.fOpen == FALSE)
1798 ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
1800 ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
1807 /***********************************************************************
1808 * ImmSetStatusWindowPos (IMM32.@)
1810 BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1812 FIXME("(%p, %p): stub\n", hIMC, lpptPos);
1813 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1817 /***********************************************************************
1818 * ImmSimulateHotKey (IMM32.@)
1820 BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
1822 FIXME("(%p, %d): stub\n", hWnd, dwHotKeyID);
1823 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1827 /***********************************************************************
1828 * ImmUnregisterWordA (IMM32.@)
1830 BOOL WINAPI ImmUnregisterWordA(
1831 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
1833 FIXME("(%p, %s, %d, %s): stub\n",
1834 hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister)
1836 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1840 /***********************************************************************
1841 * ImmUnregisterWordW (IMM32.@)
1843 BOOL WINAPI ImmUnregisterWordW(
1844 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
1846 FIXME("(%p, %s, %d, %s): stub\n",
1847 hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister)
1849 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1853 /***********************************************************************
1854 * ImmGetImeMenuItemsA (IMM32.@)
1856 DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType,
1857 LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
1860 FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType,
1861 lpImeParentMenu, lpImeMenu, dwSize);
1865 /***********************************************************************
1866 * ImmGetImeMenuItemsW (IMM32.@)
1868 DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType,
1869 LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
1872 FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType,
1873 lpImeParentMenu, lpImeMenu, dwSize);
1877 /***********************************************************************
1878 * ImmLockIMC(IMM32.@)
1880 LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
1882 InputContextData *data = (InputContextData*)hIMC;
1890 /***********************************************************************
1891 * ImmUnlockIMC(IMM32.@)
1893 BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
1895 InputContextData *data = (InputContextData*)hIMC;
1897 return (data->dwLock!=0);
1900 /***********************************************************************
1901 * ImmGetIMCLockCount(IMM32.@)
1903 DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
1905 InputContextData *data = (InputContextData*)hIMC;
1906 return data->dwLock;
1909 /***********************************************************************
1910 * ImmCreateIMCC(IMM32.@)
1912 HIMCC WINAPI ImmCreateIMCC(DWORD size)
1914 IMCCInternal *internal;
1915 int real_size = size + sizeof(IMCCInternal);
1917 internal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, real_size);
1918 if (internal == NULL)
1921 internal->dwSize = size;
1922 return (HIMCC)internal;
1925 /***********************************************************************
1926 * ImmDestroyIMCC(IMM32.@)
1928 HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
1930 HeapFree(GetProcessHeap(),0,block);
1934 /***********************************************************************
1935 * ImmLockIMCC(IMM32.@)
1937 LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
1939 IMCCInternal *internal;
1940 internal = (IMCCInternal*) imcc;
1942 internal->dwLock ++;
1943 return internal + 1;
1946 /***********************************************************************
1947 * ImmUnlockIMCC(IMM32.@)
1949 BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
1951 IMCCInternal *internal;
1952 internal = (IMCCInternal*) imcc;
1954 internal->dwLock --;
1955 return (internal->dwLock!=0);
1958 /***********************************************************************
1959 * ImmGetIMCCLockCount(IMM32.@)
1961 DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
1963 IMCCInternal *internal;
1964 internal = (IMCCInternal*) imcc;
1966 return internal->dwLock;
1969 /***********************************************************************
1970 * ImmReSizeIMCC(IMM32.@)
1972 HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
1974 IMCCInternal *internal,*newone;
1975 int real_size = size + sizeof(IMCCInternal);
1977 internal = (IMCCInternal*) imcc;
1979 newone = HeapReAlloc(GetProcessHeap(), 0, internal, real_size);
1980 newone->dwSize = size;
1985 /***********************************************************************
1986 * ImmGetIMCCSize(IMM32.@)
1988 DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
1990 IMCCInternal *internal;
1991 internal = (IMCCInternal*) imcc;
1993 return internal->dwSize;
1997 * Internal functions to help with IME window management
1999 static void PaintDefaultIMEWnd(HWND hwnd)
2003 HDC hdc = BeginPaint(hwnd,&ps);
2004 LPCOMPOSITIONSTRING compstr;
2005 LPBYTE compdata = NULL;
2007 MONITORINFO mon_info;
2010 GetClientRect(hwnd,&rect);
2011 FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1));
2013 compdata = ImmLockIMCC(root_context->IMC.hCompStr);
2014 compstr = (LPCOMPOSITIONSTRING)compdata;
2016 if (compstr->dwCompStrLen && compstr->dwCompStrOffset)
2020 HFONT oldfont = NULL;
2023 CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
2024 if (root_context->textfont)
2025 oldfont = SelectObject(hdc,root_context->textfont);
2028 GetTextExtentPoint32W(hdc, CompString, compstr->dwCompStrLen, &size);
2034 * How this works based on tests on windows:
2035 * CFS_POINT: then we start our window at the point and grow it as large
2036 * as it needs to be for the string.
2037 * CFS_RECT: we still use the ptCurrentPos as a starting point and our
2038 * window is only as large as we need for the string, but we do not
2039 * grow such that our window exceeds the given rect. Wrapping if
2040 * needed and possible. If our ptCurrentPos is outside of our rect
2041 * then no window is displayed.
2042 * CFS_FORCE_POSITION: appears to behave just like CFS_POINT
2043 * maybe becase the default MSIME does not do any IME adjusting.
2045 if (root_context->IMC.cfCompForm.dwStyle != CFS_DEFAULT)
2047 POINT cpt = root_context->IMC.cfCompForm.ptCurrentPos;
2048 ClientToScreen(root_context->IMC.hWnd,&cpt);
2051 rect.right = rect.left + pt.x;
2052 rect.bottom = rect.top + pt.y;
2054 monitor = MonitorFromPoint(cpt, MONITOR_DEFAULTTOPRIMARY);
2056 else /* CFS_DEFAULT */
2058 /* Windows places the default IME window in the bottom left */
2059 HWND target = root_context->IMC.hWnd;
2060 if (!target) target = GetFocus();
2062 GetWindowRect(target,&rect);
2063 rect.top = rect.bottom;
2064 rect.right = rect.left + pt.x + 20;
2065 rect.bottom = rect.top + pt.y + 20;
2067 monitor = MonitorFromWindow(target, MONITOR_DEFAULTTOPRIMARY);
2070 if (root_context->IMC.cfCompForm.dwStyle == CFS_RECT)
2073 client =root_context->IMC.cfCompForm.rcArea;
2074 MapWindowPoints( root_context->IMC.hWnd, 0, (POINT *)&client, 2 );
2075 IntersectRect(&rect,&rect,&client);
2076 /* TODO: Wrap the input if needed */
2079 if (root_context->IMC.cfCompForm.dwStyle == CFS_DEFAULT)
2081 /* make sure we are on the desktop */
2082 mon_info.cbSize = sizeof(mon_info);
2083 GetMonitorInfoW(monitor, &mon_info);
2085 if (rect.bottom > mon_info.rcWork.bottom)
2087 int shift = rect.bottom - mon_info.rcWork.bottom;
2089 rect.bottom -= shift;
2093 rect.right -= rect.left;
2096 if (rect.right > mon_info.rcWork.right)
2098 int shift = rect.right - mon_info.rcWork.right;
2100 rect.right -= shift;
2104 SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE);
2106 TextOutW(hdc, offX,offY, CompString, compstr->dwCompStrLen);
2109 SelectObject(hdc,oldfont);
2112 ImmUnlockIMCC(root_context->IMC.hCompStr);
2117 static void UpdateDataInDefaultIMEWindow(HWND hwnd, BOOL showable)
2119 LPCOMPOSITIONSTRING compstr;
2121 if (root_context->IMC.hCompStr)
2122 compstr = ImmLockIMCC(root_context->IMC.hCompStr);
2126 if (compstr == NULL || compstr->dwCompStrLen == 0)
2127 ShowWindow(hwndDefault,SW_HIDE);
2129 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
2131 RedrawWindow(hwnd,NULL,NULL,RDW_ERASENOW|RDW_INVALIDATE);
2133 if (compstr != NULL)
2134 ImmUnlockIMCC(root_context->IMC.hCompStr);
2138 * The window proc for the default IME window
2140 static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
2145 TRACE("Incoming Message 0x%x (0x%08x, 0x%08x)\n", msg, (UINT)wParam,
2151 PaintDefaultIMEWnd(hwnd);
2158 SetWindowTextA(hwnd,"Wine Ime Active");
2163 SetFocus((HWND)wParam);
2165 FIXME("Received focus, should never have focus\n");
2167 case WM_IME_COMPOSITION:
2168 TRACE("IME message %s, 0x%x, 0x%x (%i)\n",
2169 "WM_IME_COMPOSITION", (UINT)wParam, (UINT)lParam,
2170 root_context->bRead);
2171 if (lParam & GCS_RESULTSTR)
2172 IMM_PostResult(root_context);
2174 UpdateDataInDefaultIMEWindow(hwnd,TRUE);
2176 case WM_IME_STARTCOMPOSITION:
2177 TRACE("IME message %s, 0x%x, 0x%x\n",
2178 "WM_IME_STARTCOMPOSITION", (UINT)wParam, (UINT)lParam);
2179 root_context->IMC.hWnd = GetFocus();
2180 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
2182 case WM_IME_ENDCOMPOSITION:
2183 TRACE("IME message %s, 0x%x, 0x%x\n",
2184 "WM_IME_ENDCOMPOSITION", (UINT)wParam, (UINT)lParam);
2185 ShowWindow(hwndDefault,SW_HIDE);
2188 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_SELECT",
2189 (UINT)wParam, (UINT)lParam);
2191 case WM_IME_CONTROL:
2192 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_CONTROL",
2193 (UINT)wParam, (UINT)lParam);
2197 TRACE("!! IME NOTIFY\n");
2200 TRACE("Non-standard message 0x%x\n",msg);
2202 /* check the MSIME messages */
2203 if (msg == WM_MSIME_SERVICE)
2205 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_SERVICE",
2206 (UINT)wParam, (UINT)lParam);
2209 else if (msg == WM_MSIME_RECONVERTOPTIONS)
2211 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTOPTIONS",
2212 (UINT)wParam, (UINT)lParam);
2214 else if (msg == WM_MSIME_MOUSE)
2216 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_MOUSE",
2217 (UINT)wParam, (UINT)lParam);
2219 else if (msg == WM_MSIME_RECONVERTREQUEST)
2221 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTREQUEST",
2222 (UINT)wParam, (UINT)lParam);
2224 else if (msg == WM_MSIME_RECONVERT)
2226 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERT",
2227 (UINT)wParam, (UINT)lParam);
2229 else if (msg == WM_MSIME_QUERYPOSITION)
2231 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_QUERYPOSITION",
2232 (UINT)wParam, (UINT)lParam);
2234 else if (msg == WM_MSIME_DOCUMENTFEED)
2236 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_DOCUMENTFEED",
2237 (UINT)wParam, (UINT)lParam);
2239 /* DefWndProc if not an IME message */
2240 else if (!rc && !((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
2241 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP)))
2242 rc = DefWindowProcW(hwnd,msg,wParam,lParam);