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
30 #include "wine/debug.h"
35 #include "wine/list.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(imm);
39 #define FROM_IME 0xcafe1337
41 static void (*pX11DRV_ForceXIMReset)(HWND);
43 typedef struct tagIMCCInternal
49 #define MAKE_FUNCPTR(f) typeof(f) * p##f
50 typedef struct _tagImmHkl{
55 WCHAR imeClassName[17]; /* 16 character max */
58 /* Function Pointers */
59 MAKE_FUNCPTR(ImeInquire);
60 MAKE_FUNCPTR(ImeConfigure);
61 MAKE_FUNCPTR(ImeDestroy);
62 MAKE_FUNCPTR(ImeEscape);
63 MAKE_FUNCPTR(ImeSelect);
64 MAKE_FUNCPTR(ImeSetActiveContext);
65 MAKE_FUNCPTR(ImeToAsciiEx);
66 MAKE_FUNCPTR(NotifyIME);
67 MAKE_FUNCPTR(ImeRegisterWord);
68 MAKE_FUNCPTR(ImeUnregisterWord);
69 MAKE_FUNCPTR(ImeEnumRegisterWord);
70 MAKE_FUNCPTR(ImeSetCompositionString);
71 MAKE_FUNCPTR(ImeConversionList);
72 MAKE_FUNCPTR(ImeProcessKey);
73 MAKE_FUNCPTR(ImeGetRegisterWordStyle);
74 MAKE_FUNCPTR(ImeGetImeMenuItems);
78 typedef struct tagInputContextData
91 typedef struct _tagTRANSMSG {
95 } TRANSMSG, *LPTRANSMSG;
97 static InputContextData *root_context = NULL;
98 static HWND hwndDefault = NULL;
99 static HANDLE hImeInst;
100 static const WCHAR WC_IMECLASSNAME[] = {'I','M','E',0};
101 static ATOM atIMEClass = 0;
103 static struct list ImmHklList = LIST_INIT(ImmHklList);
106 static UINT WM_MSIME_SERVICE;
107 static UINT WM_MSIME_RECONVERTOPTIONS;
108 static UINT WM_MSIME_MOUSE;
109 static UINT WM_MSIME_RECONVERTREQUEST;
110 static UINT WM_MSIME_RECONVERT;
111 static UINT WM_MSIME_QUERYPOSITION;
112 static UINT WM_MSIME_DOCUMENTFEED;
114 static const WCHAR szwWineIMCProperty[] = {'W','i','n','e','I','m','m','H','I','M','C','P','r','o','p','e','r','t','y',0};
118 static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
120 static void UpdateDataInDefaultIMEWindow(HWND hwnd, BOOL showable);
121 static void ImmInternalPostIMEMessage(InputContextData*, UINT, WPARAM, LPARAM);
122 static void ImmInternalSetOpenStatus(BOOL fOpen);
123 static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len);
125 #define is_kbd_ime_unicode(p) (p->imeInfo.fdwProperty & IME_PROP_UNICODE)
127 static inline WCHAR *strdupAtoW( const char *str )
132 DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
133 if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
134 MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
139 static inline CHAR *strdupWtoA( const WCHAR *str )
144 DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
145 if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
146 WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
151 static HMODULE LoadDefaultWineIME(void)
153 char buffer[MAX_PATH], libname[32], *name, *next;
157 TRACE("Attempting to fall back to wine default IME\n");
159 strcpy( buffer, "x11" ); /* default value */
160 /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
161 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey ))
163 DWORD type, count = sizeof(buffer);
164 RegQueryValueExA( hkey, "Ime", 0, &type, (LPBYTE) buffer, &count );
171 next = strchr( name, ',' );
172 if (next) *next++ = 0;
174 snprintf( libname, sizeof(libname), "wine%s.drv", name );
175 if ((module = LoadLibraryA( libname )) != 0) break;
182 /* ImmHkl loading and freeing */
183 #define LOAD_FUNCPTR(f) if((ptr->p##f = (LPVOID)GetProcAddress(ptr->hIME, #f)) == NULL){WARN("Can't find function %s in ime\n", #f);}
184 static ImmHkl *IMM_GetImmHkl(HKL hkl)
187 WCHAR filename[MAX_PATH];
189 TRACE("Seeking ime for keyboard 0x%x\n",(unsigned)hkl);
191 LIST_FOR_EACH_ENTRY(ptr, &ImmHklList, ImmHkl, entry)
196 /* not found... create it */
198 ptr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ImmHkl));
201 if (ImmGetIMEFileNameW(hkl, filename, MAX_PATH)) ptr->hIME = LoadLibraryW(filename);
203 ptr->hIME = LoadDefaultWineIME();
206 LOAD_FUNCPTR(ImeInquire);
207 if (!ptr->pImeInquire || !ptr->pImeInquire(&ptr->imeInfo, ptr->imeClassName, NULL))
209 FreeLibrary(ptr->hIME);
214 LOAD_FUNCPTR(ImeDestroy);
215 LOAD_FUNCPTR(ImeSelect);
216 if (!ptr->pImeSelect || !ptr->pImeDestroy)
218 FreeLibrary(ptr->hIME);
223 LOAD_FUNCPTR(ImeConfigure);
224 LOAD_FUNCPTR(ImeEscape);
225 LOAD_FUNCPTR(ImeSetActiveContext);
226 LOAD_FUNCPTR(ImeToAsciiEx);
227 LOAD_FUNCPTR(NotifyIME);
228 LOAD_FUNCPTR(ImeRegisterWord);
229 LOAD_FUNCPTR(ImeUnregisterWord);
230 LOAD_FUNCPTR(ImeEnumRegisterWord);
231 LOAD_FUNCPTR(ImeSetCompositionString);
232 LOAD_FUNCPTR(ImeConversionList);
233 LOAD_FUNCPTR(ImeProcessKey);
234 LOAD_FUNCPTR(ImeGetRegisterWordStyle);
235 LOAD_FUNCPTR(ImeGetImeMenuItems);
236 /* make sure our classname is WCHAR */
237 if (!is_kbd_ime_unicode(ptr))
240 MultiByteToWideChar(CP_ACP, 0, (LPSTR)ptr->imeClassName,
242 lstrcpyW(ptr->imeClassName, bufW);
247 list_add_head(&ImmHklList,&ptr->entry);
253 static void IMM_FreeAllImmHkl(void)
255 ImmHkl *ptr,*cursor2;
257 LIST_FOR_EACH_ENTRY_SAFE(ptr, cursor2, &ImmHklList, ImmHkl, entry)
259 list_remove(&ptr->entry);
263 FreeLibrary(ptr->hIME);
265 HeapFree(GetProcessHeap(),0,ptr);
269 static VOID IMM_PostResult(InputContextData *data)
272 LPCOMPOSITIONSTRING compstr;
277 TRACE("Posting result as IME_CHAR\n");
278 compdata = ImmLockIMCC(root_context->IMC.hCompStr);
279 compstr = (LPCOMPOSITIONSTRING)compdata;
280 ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
282 for (i = 0; i < compstr->dwResultStrLen; i++)
283 ImmInternalPostIMEMessage (root_context, WM_IME_CHAR, ResultStr[i], 1);
285 ImmUnlockIMCC(root_context->IMC.hCompStr);
287 /* clear the buffer */
288 newCompStr = updateResultStr(root_context->IMC.hCompStr, NULL, 0);
289 ImmDestroyIMCC(root_context->IMC.hCompStr);
290 root_context->IMC.hCompStr = newCompStr;
293 static void IMM_Register(void)
296 ZeroMemory(&wndClass, sizeof(WNDCLASSW));
297 wndClass.style = CS_GLOBALCLASS | CS_IME | CS_HREDRAW | CS_VREDRAW;
298 wndClass.lpfnWndProc = (WNDPROC) IME_WindowProc;
299 wndClass.cbClsExtra = 0;
300 wndClass.cbWndExtra = 0;
301 wndClass.hInstance = hImeInst;
302 wndClass.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
303 wndClass.hIcon = NULL;
304 wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
305 wndClass.lpszMenuName = 0;
306 wndClass.lpszClassName = WC_IMECLASSNAME;
307 atIMEClass = RegisterClassW(&wndClass);
310 static void IMM_Unregister(void)
313 UnregisterClassW(WC_IMECLASSNAME, NULL);
317 static void IMM_RegisterMessages(void)
319 WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
320 WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
321 WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
322 WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
323 WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
324 WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
325 WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
329 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
333 TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
336 case DLL_PROCESS_ATTACH:
337 DisableThreadLibraryCalls(hInstDLL);
339 IMM_RegisterMessages();
340 x11drv = GetModuleHandleA("winex11.drv");
341 if (x11drv) pX11DRV_ForceXIMReset = (void *)GetProcAddress( x11drv, "ForceXIMReset");
343 case DLL_PROCESS_DETACH:
346 DestroyWindow(hwndDefault);
356 /* for posting messages as the IME */
357 static void ImmInternalPostIMEMessage(InputContextData *data, UINT msg, WPARAM wParam, LPARAM lParam)
359 HWND target = GetFocus();
361 PostMessageW(data->IMC.hWnd,msg,wParam,lParam);
363 PostMessageW(target, msg, wParam, lParam);
366 static LRESULT ImmInternalSendIMENotify(InputContextData *data, WPARAM notify, LPARAM lParam)
370 target = data->IMC.hWnd;
371 if (!target) target = GetFocus();
374 return SendMessageW(target, WM_IME_NOTIFY, notify, lParam);
379 static HIMCC ImmCreateBlankCompStr(void)
382 LPCOMPOSITIONSTRING ptr;
383 rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
384 ptr = (LPCOMPOSITIONSTRING)ImmLockIMCC(rc);
385 memset(ptr,0,sizeof(COMPOSITIONSTRING));
386 ptr->dwSize = sizeof(COMPOSITIONSTRING);
391 static void ImmInternalSetOpenStatus(BOOL fOpen)
393 TRACE("Setting internal state to %s\n",(fOpen)?"OPEN":"CLOSED");
395 if (root_context->IMC.fOpen && fOpen == FALSE)
397 ShowWindow(hwndDefault,SW_HIDE);
398 ImmDestroyIMCC(root_context->IMC.hCompStr);
399 root_context->IMC.hCompStr = ImmCreateBlankCompStr();
402 root_context->IMC.fOpen = fOpen;
403 root_context->bInternalState = fOpen;
405 ImmInternalSendIMENotify(root_context, IMN_SETOPENSTATUS, 0);
408 static int updateField(DWORD origLen, DWORD origOffset, DWORD currentOffset,
409 LPBYTE target, LPBYTE source, DWORD* lenParam,
410 DWORD* offsetParam, BOOL wchars )
412 if (origLen > 0 && origOffset > 0)
414 int truelen = origLen;
416 truelen *= sizeof(WCHAR);
418 memcpy(&target[currentOffset], &source[origOffset], truelen);
421 *offsetParam = currentOffset;
422 currentOffset += truelen;
424 return currentOffset;
427 static HIMCC updateCompStr(HIMCC old, LPWSTR compstr, DWORD len)
429 /* we need to make sure the CompStr, CompClaus and CompAttr fields are all
433 LPBYTE newdata = NULL;
434 LPBYTE olddata = NULL;
435 LPCOMPOSITIONSTRING new_one;
436 LPCOMPOSITIONSTRING lpcs = NULL;
437 INT current_offset = 0;
439 TRACE("%s, %i\n",debugstr_wn(compstr,len),len);
441 if (old == NULL && compstr == NULL && len == 0)
446 olddata = ImmLockIMCC(old);
447 lpcs = (LPCOMPOSITIONSTRING)olddata;
450 needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
451 len + sizeof(DWORD) * 2;
455 needed_size += lpcs->dwCompReadAttrLen;
456 needed_size += lpcs->dwCompReadClauseLen;
457 needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
458 needed_size += lpcs->dwResultReadClauseLen;
459 needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
460 needed_size += lpcs->dwResultClauseLen;
461 needed_size += lpcs->dwResultStrLen * sizeof(DWORD);
462 needed_size += lpcs->dwPrivateSize;
464 rc = ImmCreateIMCC(needed_size);
465 newdata = ImmLockIMCC(rc);
466 new_one = (LPCOMPOSITIONSTRING)newdata;
468 new_one->dwSize = needed_size;
469 current_offset = sizeof(COMPOSITIONSTRING);
472 current_offset = updateField(lpcs->dwCompReadAttrLen,
473 lpcs->dwCompReadAttrOffset,
474 current_offset, newdata, olddata,
475 &new_one->dwCompReadAttrLen,
476 &new_one->dwCompReadAttrOffset, FALSE);
478 current_offset = updateField(lpcs->dwCompReadClauseLen,
479 lpcs->dwCompReadClauseOffset,
480 current_offset, newdata, olddata,
481 &new_one->dwCompReadClauseLen,
482 &new_one->dwCompReadClauseOffset, FALSE);
484 current_offset = updateField(lpcs->dwCompReadStrLen,
485 lpcs->dwCompReadStrOffset,
486 current_offset, newdata, olddata,
487 &new_one->dwCompReadStrLen,
488 &new_one->dwCompReadStrOffset, TRUE);
490 /* new CompAttr, CompClause, CompStr, dwCursorPos */
491 new_one->dwDeltaStart = 0;
493 current_offset = updateField(lpcs->dwResultReadClauseLen,
494 lpcs->dwResultReadClauseOffset,
495 current_offset, newdata, olddata,
496 &new_one->dwResultReadClauseLen,
497 &new_one->dwResultReadClauseOffset, FALSE);
499 current_offset = updateField(lpcs->dwResultReadStrLen,
500 lpcs->dwResultReadStrOffset,
501 current_offset, newdata, olddata,
502 &new_one->dwResultReadStrLen,
503 &new_one->dwResultReadStrOffset, TRUE);
505 current_offset = updateField(lpcs->dwResultClauseLen,
506 lpcs->dwResultClauseOffset,
507 current_offset, newdata, olddata,
508 &new_one->dwResultClauseLen,
509 &new_one->dwResultClauseOffset, FALSE);
511 current_offset = updateField(lpcs->dwResultStrLen,
512 lpcs->dwResultStrOffset,
513 current_offset, newdata, olddata,
514 &new_one->dwResultStrLen,
515 &new_one->dwResultStrOffset, TRUE);
517 current_offset = updateField(lpcs->dwPrivateSize,
518 lpcs->dwPrivateOffset,
519 current_offset, newdata, olddata,
520 &new_one->dwPrivateSize,
521 &new_one->dwPrivateOffset, FALSE);
526 new_one->dwCompAttrLen = len;
529 new_one->dwCompAttrOffset = current_offset;
530 memset(&newdata[current_offset],ATTR_INPUT,len);
531 current_offset += len;
537 new_one->dwCompClauseLen = sizeof(DWORD) * 2;
538 new_one->dwCompClauseOffset = current_offset;
539 *(DWORD*)(&newdata[current_offset]) = 0;
540 current_offset += sizeof(DWORD);
541 *(DWORD*)(&newdata[current_offset]) = len;
542 current_offset += sizeof(DWORD);
546 new_one->dwCompStrLen = len;
549 new_one->dwCompStrOffset = current_offset;
550 memcpy(&newdata[current_offset],compstr,len*sizeof(WCHAR));
554 new_one->dwCursorPos = len;
563 static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len)
565 /* we need to make sure the ResultStr and ResultClause fields are all
569 LPBYTE newdata = NULL;
570 LPBYTE olddata = NULL;
571 LPCOMPOSITIONSTRING new_one;
572 LPCOMPOSITIONSTRING lpcs = NULL;
573 INT current_offset = 0;
575 TRACE("%s, %i\n",debugstr_wn(resultstr,len),len);
577 if (old == NULL && resultstr == NULL && len == 0)
582 olddata = ImmLockIMCC(old);
583 lpcs = (LPCOMPOSITIONSTRING)olddata;
586 needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
591 needed_size += lpcs->dwCompReadAttrLen;
592 needed_size += lpcs->dwCompReadClauseLen;
593 needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
594 needed_size += lpcs->dwCompAttrLen;
595 needed_size += lpcs->dwCompClauseLen;
596 needed_size += lpcs->dwCompStrLen * sizeof(DWORD);
597 needed_size += lpcs->dwResultReadClauseLen;
598 needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
599 needed_size += lpcs->dwPrivateSize;
601 rc = ImmCreateIMCC(needed_size);
602 newdata = ImmLockIMCC(rc);
603 new_one = (LPCOMPOSITIONSTRING)newdata;
605 new_one->dwSize = needed_size;
606 current_offset = sizeof(COMPOSITIONSTRING);
609 current_offset = updateField(lpcs->dwCompReadAttrLen,
610 lpcs->dwCompReadAttrOffset,
611 current_offset, newdata, olddata,
612 &new_one->dwCompReadAttrLen,
613 &new_one->dwCompReadAttrOffset, FALSE);
615 current_offset = updateField(lpcs->dwCompReadClauseLen,
616 lpcs->dwCompReadClauseOffset,
617 current_offset, newdata, olddata,
618 &new_one->dwCompReadClauseLen,
619 &new_one->dwCompReadClauseOffset, FALSE);
621 current_offset = updateField(lpcs->dwCompReadStrLen,
622 lpcs->dwCompReadStrOffset,
623 current_offset, newdata, olddata,
624 &new_one->dwCompReadStrLen,
625 &new_one->dwCompReadStrOffset, TRUE);
627 current_offset = updateField(lpcs->dwCompAttrLen,
628 lpcs->dwCompAttrOffset,
629 current_offset, newdata, olddata,
630 &new_one->dwCompAttrLen,
631 &new_one->dwCompAttrOffset, FALSE);
633 current_offset = updateField(lpcs->dwCompClauseLen,
634 lpcs->dwCompClauseOffset,
635 current_offset, newdata, olddata,
636 &new_one->dwCompClauseLen,
637 &new_one->dwCompClauseOffset, FALSE);
639 current_offset = updateField(lpcs->dwCompStrLen,
640 lpcs->dwCompStrOffset,
641 current_offset, newdata, olddata,
642 &new_one->dwCompStrLen,
643 &new_one->dwCompStrOffset, TRUE);
645 new_one->dwCursorPos = lpcs->dwCursorPos;
646 new_one->dwDeltaStart = 0;
648 current_offset = updateField(lpcs->dwResultReadClauseLen,
649 lpcs->dwResultReadClauseOffset,
650 current_offset, newdata, olddata,
651 &new_one->dwResultReadClauseLen,
652 &new_one->dwResultReadClauseOffset, FALSE);
654 current_offset = updateField(lpcs->dwResultReadStrLen,
655 lpcs->dwResultReadStrOffset,
656 current_offset, newdata, olddata,
657 &new_one->dwResultReadStrLen,
658 &new_one->dwResultReadStrOffset, TRUE);
660 /* new ResultClause , ResultStr */
662 current_offset = updateField(lpcs->dwPrivateSize,
663 lpcs->dwPrivateOffset,
664 current_offset, newdata, olddata,
665 &new_one->dwPrivateSize,
666 &new_one->dwPrivateOffset, FALSE);
673 new_one->dwResultClauseLen = sizeof(DWORD) * 2;
674 new_one->dwResultClauseOffset = current_offset;
675 *(DWORD*)(&newdata[current_offset]) = 0;
676 current_offset += sizeof(DWORD);
677 *(DWORD*)(&newdata[current_offset]) = len;
678 current_offset += sizeof(DWORD);
682 new_one->dwResultStrLen = len;
685 new_one->dwResultStrOffset = current_offset;
686 memcpy(&newdata[current_offset],resultstr,len*sizeof(WCHAR));
697 /***********************************************************************
698 * ImmAssociateContext (IMM32.@)
700 HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
703 InputContextData *data = (InputContextData*)hIMC;
705 TRACE("(%p, %p):\n", hWnd, hIMC);
708 * WINE SPECIFIC! MAY CONFLICT
709 * associate the root context we have an XIM created
713 root_context = (InputContextData*)hIMC;
717 * If already associated just return
719 if (hIMC && data->IMC.hWnd == hWnd)
724 old = (HIMC)RemovePropW(hWnd,szwWineIMCProperty);
727 old = (HIMC)root_context;
728 else if (old == (HIMC)-1)
731 if (hIMC != (HIMC)root_context)
733 if (hIMC == NULL) /* Meaning disable imm for that window*/
734 SetPropW(hWnd,szwWineIMCProperty,(HANDLE)-1);
736 SetPropW(hWnd,szwWineIMCProperty,(HANDLE)hIMC);
743 if (IsWindow(data->IMC.hWnd))
746 * Post a message that your context is switching
748 SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
751 data->IMC.hWnd = hWnd;
753 if (IsWindow(data->IMC.hWnd))
756 * Post a message that your context is switching
758 SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
764 /***********************************************************************
765 * ImmAssociateContextEx (IMM32.@)
767 BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
769 FIXME("(%p, %p, %d): stub\n", hWnd, hIMC, dwFlags);
770 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
774 /***********************************************************************
775 * ImmConfigureIMEA (IMM32.@)
777 BOOL WINAPI ImmConfigureIMEA(
778 HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
780 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
782 TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
784 if (immHkl->hIME && immHkl->pImeConfigure)
786 if (dwMode != IME_CONFIG_REGISTERWORD || !is_kbd_ime_unicode(immHkl))
787 return immHkl->pImeConfigure(hKL,hWnd,dwMode,lpData);
791 REGISTERWORDA *rwa = (REGISTERWORDA*)lpData;
794 rww.lpReading = strdupAtoW(rwa->lpReading);
795 rww.lpWord = strdupAtoW(rwa->lpWord);
796 rc = immHkl->pImeConfigure(hKL,hWnd,dwMode,&rww);
797 HeapFree(GetProcessHeap(),0,rww.lpReading);
798 HeapFree(GetProcessHeap(),0,rww.lpWord);
806 /***********************************************************************
807 * ImmConfigureIMEW (IMM32.@)
809 BOOL WINAPI ImmConfigureIMEW(
810 HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
812 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
814 TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
816 if (immHkl->hIME && immHkl->pImeConfigure)
818 if (dwMode != IME_CONFIG_REGISTERWORD || is_kbd_ime_unicode(immHkl))
819 return immHkl->pImeConfigure(hKL,hWnd,dwMode,lpData);
822 REGISTERWORDW *rww = (REGISTERWORDW*)lpData;
826 rwa.lpReading = strdupWtoA(rww->lpReading);
827 rwa.lpWord = strdupWtoA(rww->lpWord);
828 rc = immHkl->pImeConfigure(hKL,hWnd,dwMode,&rwa);
829 HeapFree(GetProcessHeap(),0,rwa.lpReading);
830 HeapFree(GetProcessHeap(),0,rwa.lpWord);
838 /***********************************************************************
839 * ImmCreateContext (IMM32.@)
841 HIMC WINAPI ImmCreateContext(void)
843 InputContextData *new_context;
845 new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
848 new_context->immKbd = IMM_GetImmHkl(GetKeyboardLayout(0));
851 * Once we depend on the IME for all the processing like we should
852 * these will become hard errors and result in creation failures
854 if (!new_context->immKbd->hIME)
855 TRACE("IME dll could not be loaded\n");
857 /* hCompStr is never NULL */
858 new_context->IMC.hCompStr = ImmCreateBlankCompStr();
859 new_context->IMC.hMsgBuf = ImmCreateIMCC(1);
861 /* Initialize the IME Private */
862 new_context->IMC.hPrivate = ImmCreateIMCC(new_context->immKbd->imeInfo.dwPrivateDataSize);
864 if (new_context->immKbd->hIME &&
865 !new_context->immKbd->pImeSelect(new_context, TRUE))
867 TRACE("Selection of IME failed\n");
868 ImmDestroyContext(new_context);
872 new_context->immKbd->uSelected++;
873 TRACE("Created context 0x%x\n",(UINT)new_context);
875 return (HIMC)new_context;
878 /***********************************************************************
879 * ImmDestroyContext (IMM32.@)
881 BOOL WINAPI ImmDestroyContext(HIMC hIMC)
883 InputContextData *data = (InputContextData*)hIMC;
885 TRACE("Destroying %p\n",hIMC);
889 data->immKbd->uSelected --;
890 if (data->immKbd->hIME)
891 data->immKbd->pImeSelect(hIMC, FALSE);
893 ImmDestroyIMCC(data->IMC.hCompStr);
894 ImmDestroyIMCC(data->IMC.hCandInfo);
895 ImmDestroyIMCC(data->IMC.hGuideLine);
896 ImmDestroyIMCC(data->IMC.hPrivate);
897 ImmDestroyIMCC(data->IMC.hMsgBuf);
901 DeleteObject(data->textfont);
902 data->textfont = NULL;
905 HeapFree(GetProcessHeap(),0,data);
910 /***********************************************************************
911 * ImmDisableIME (IMM32.@)
913 BOOL WINAPI ImmDisableIME(DWORD idThread)
915 FIXME("(%d): stub\n", idThread);
919 /***********************************************************************
920 * ImmEnumRegisterWordA (IMM32.@)
922 UINT WINAPI ImmEnumRegisterWordA(
923 HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
924 LPCSTR lpszReading, DWORD dwStyle,
925 LPCSTR lpszRegister, LPVOID lpData)
927 FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
929 debugstr_a(lpszReading), dwStyle,
930 debugstr_a(lpszRegister), lpData
932 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
936 /***********************************************************************
937 * ImmEnumRegisterWordW (IMM32.@)
939 UINT WINAPI ImmEnumRegisterWordW(
940 HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
941 LPCWSTR lpszReading, DWORD dwStyle,
942 LPCWSTR lpszRegister, LPVOID lpData)
944 FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
946 debugstr_w(lpszReading), dwStyle,
947 debugstr_w(lpszRegister), lpData
949 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
953 /***********************************************************************
954 * ImmEscapeA (IMM32.@)
956 LRESULT WINAPI ImmEscapeA(
958 UINT uEscape, LPVOID lpData)
960 FIXME("(%p, %p, %d, %p): stub\n",
961 hKL, hIMC, uEscape, lpData
963 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
967 /***********************************************************************
968 * ImmEscapeW (IMM32.@)
970 LRESULT WINAPI ImmEscapeW(
972 UINT uEscape, LPVOID lpData)
974 FIXME("(%p, %p, %d, %p): stub\n",
975 hKL, hIMC, uEscape, lpData
977 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
981 /***********************************************************************
982 * ImmGetCandidateListA (IMM32.@)
984 DWORD WINAPI ImmGetCandidateListA(
985 HIMC hIMC, DWORD deIndex,
986 LPCANDIDATELIST lpCandList, DWORD dwBufLen)
988 FIXME("(%p, %d, %p, %d): stub\n",
992 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
996 /***********************************************************************
997 * ImmGetCandidateListCountA (IMM32.@)
999 DWORD WINAPI ImmGetCandidateListCountA(
1000 HIMC hIMC, LPDWORD lpdwListCount)
1002 FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
1003 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1007 /***********************************************************************
1008 * ImmGetCandidateListCountW (IMM32.@)
1010 DWORD WINAPI ImmGetCandidateListCountW(
1011 HIMC hIMC, LPDWORD lpdwListCount)
1013 FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
1014 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1018 /***********************************************************************
1019 * ImmGetCandidateListW (IMM32.@)
1021 DWORD WINAPI ImmGetCandidateListW(
1022 HIMC hIMC, DWORD deIndex,
1023 LPCANDIDATELIST lpCandList, DWORD dwBufLen)
1025 FIXME("(%p, %d, %p, %d): stub\n",
1027 lpCandList, dwBufLen
1029 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1033 /***********************************************************************
1034 * ImmGetCandidateWindow (IMM32.@)
1036 BOOL WINAPI ImmGetCandidateWindow(
1037 HIMC hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
1039 FIXME("(%p, %d, %p): stub\n", hIMC, dwBufLen, lpCandidate);
1040 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1044 /***********************************************************************
1045 * ImmGetCompositionFontA (IMM32.@)
1047 BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
1052 TRACE("(%p, %p):\n", hIMC, lplf);
1054 rc = ImmGetCompositionFontW(hIMC,&lfW);
1057 memcpy(lplf,&lfW,sizeof(LOGFONTA));
1058 WideCharToMultiByte(CP_ACP, 0, lfW.lfFaceName, -1, lplf->lfFaceName,
1059 LF_FACESIZE, NULL, NULL);
1064 /***********************************************************************
1065 * ImmGetCompositionFontW (IMM32.@)
1067 BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
1069 InputContextData *data = (InputContextData*)hIMC;
1071 TRACE("(%p, %p):\n", hIMC, lplf);
1076 *lplf = data->IMC.lfFont.W;
1081 /***********************************************************************
1082 * ImmGetCompositionStringA (IMM32.@)
1084 LONG WINAPI ImmGetCompositionStringA(
1085 HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
1089 InputContextData *data = (InputContextData*)hIMC;
1090 LPCOMPOSITIONSTRING compstr;
1093 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
1098 if (!data->IMC.hCompStr)
1101 compdata = ImmLockIMCC(data->IMC.hCompStr);
1102 compstr = (LPCOMPOSITIONSTRING)compdata;
1104 if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
1105 compstr->dwResultStrOffset > 0)
1107 LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
1109 TRACE("GSC_RESULTSTR %p %i\n",ResultStr,
1110 compstr->dwResultStrLen);
1112 buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwResultStrLen * 3 );
1113 rc = WideCharToMultiByte(CP_ACP, 0, ResultStr,
1114 compstr->dwResultStrLen , buf,
1115 compstr->dwResultStrLen * 3, NULL, NULL);
1117 memcpy(lpBuf,buf,rc);
1120 HeapFree( GetProcessHeap(), 0, buf );
1122 else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
1123 compstr->dwCompStrOffset > 0)
1125 LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
1127 TRACE("GSC_COMPSTR %p %i\n", CompString, compstr->dwCompStrLen);
1129 buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwCompStrLen * 3 );
1130 rc = WideCharToMultiByte(CP_ACP, 0, CompString,
1131 compstr->dwCompStrLen, buf,
1132 compstr->dwCompStrLen * 3, NULL, NULL);
1134 memcpy(lpBuf,buf,rc);
1135 HeapFree( GetProcessHeap(), 0, buf );
1137 else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
1138 compstr->dwCompAttrOffset > 0)
1140 LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
1141 TRACE("GSC_COMPATTR %p %i\n", Compattr , compstr->dwCompAttrLen);
1143 rc = compstr->dwCompAttrLen;
1145 memcpy(lpBuf,Compattr,rc);
1147 else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
1148 compstr->dwCompClauseOffset > 0)
1150 LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
1151 TRACE("GSC_COMPCLAUSE %p %i\n", Compclause, compstr->dwCompClauseLen);
1153 rc = compstr->dwCompClauseLen;
1154 if (dwBufLen >= compstr->dwCompClauseLen)
1155 memcpy(lpBuf,Compclause,rc);
1157 else if (dwIndex == GCS_RESULTCLAUSE && compstr->dwResultClauseLen > 0 &&
1158 compstr->dwResultClauseOffset > 0)
1160 LPWSTR Resultclause = (LPWSTR)(compdata + compstr->dwResultClauseOffset);
1161 TRACE("GSC_RESULTCLAUSE %p %i\n", Resultclause, compstr->dwResultClauseLen);
1163 rc = compstr->dwResultClauseLen;
1164 if (dwBufLen >= compstr->dwResultClauseLen)
1165 memcpy(lpBuf,Resultclause,rc);
1167 else if (dwIndex == GCS_CURSORPOS)
1169 TRACE("GSC_CURSORPOS\n");
1170 rc = compstr->dwCursorPos;
1172 else if (dwIndex == GCS_DELTASTART)
1174 TRACE("GCS_DELTASTART\n");
1175 rc = compstr->dwDeltaStart;
1179 FIXME("Unhandled index 0x%x\n",dwIndex);
1182 ImmUnlockIMCC(data->IMC.hCompStr);
1187 /***********************************************************************
1188 * ImmGetCompositionStringW (IMM32.@)
1190 LONG WINAPI ImmGetCompositionStringW(
1191 HIMC hIMC, DWORD dwIndex,
1192 LPVOID lpBuf, DWORD dwBufLen)
1195 InputContextData *data = (InputContextData*)hIMC;
1196 LPCOMPOSITIONSTRING compstr;
1199 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
1204 if (!data->IMC.hCompStr)
1207 compdata = ImmLockIMCC(data->IMC.hCompStr);
1208 compstr = (LPCOMPOSITIONSTRING)compdata;
1210 if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
1211 compstr->dwResultStrOffset > 0)
1213 LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
1215 rc = compstr->dwResultStrLen * sizeof(WCHAR);
1218 memcpy(lpBuf,ResultStr,rc);
1220 else if (dwIndex == GCS_RESULTREADSTR && compstr->dwResultReadStrLen > 0 &&
1221 compstr->dwResultReadStrOffset > 0)
1223 LPWSTR ResultReadString = (LPWSTR)(compdata + compstr->dwResultReadStrOffset);
1225 rc = compstr->dwResultReadStrLen * sizeof(WCHAR);
1227 memcpy(lpBuf,ResultReadString,rc);
1229 else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
1230 compstr->dwCompStrOffset > 0)
1232 LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
1233 rc = compstr->dwCompStrLen * sizeof(WCHAR);
1235 memcpy(lpBuf,CompString,rc);
1237 else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
1238 compstr->dwCompAttrOffset > 0)
1241 LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
1243 rc = compstr->dwCompAttrLen;
1245 memcpy(lpBuf,Compattr,rc);
1247 else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
1248 compstr->dwCompClauseOffset > 0)
1250 LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
1252 rc = compstr->dwCompClauseLen;
1253 if (dwBufLen >= compstr->dwCompClauseLen)
1254 memcpy(lpBuf,Compclause,rc);
1256 else if (dwIndex == GCS_COMPREADSTR && compstr->dwCompReadStrLen > 0 &&
1257 compstr->dwCompReadStrOffset > 0)
1259 LPWSTR CompReadString = (LPWSTR)(compdata + compstr->dwCompReadStrOffset);
1261 rc = compstr->dwCompReadStrLen * sizeof(WCHAR);
1264 memcpy(lpBuf,CompReadString,rc);
1266 else if (dwIndex == GCS_CURSORPOS)
1268 TRACE("GSC_CURSORPOS\n");
1269 rc = compstr->dwCursorPos;
1271 else if (dwIndex == GCS_DELTASTART)
1273 TRACE("GCS_DELTASTART\n");
1274 rc = compstr->dwDeltaStart;
1278 FIXME("Unhandled index 0x%x\n",dwIndex);
1281 ImmUnlockIMCC(data->IMC.hCompStr);
1286 /***********************************************************************
1287 * ImmGetCompositionWindow (IMM32.@)
1289 BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
1291 InputContextData *data = (InputContextData*)hIMC;
1293 TRACE("(%p, %p)\n", hIMC, lpCompForm);
1298 *lpCompForm = data->IMC.cfCompForm;
1302 /***********************************************************************
1303 * ImmGetContext (IMM32.@)
1306 HIMC WINAPI ImmGetContext(HWND hWnd)
1310 TRACE("%p\n", hWnd);
1312 rc = (HIMC)GetPropW(hWnd,szwWineIMCProperty);
1315 else if (rc == NULL)
1316 rc = (HIMC)root_context;
1320 InputContextData *data = (InputContextData*)rc;
1321 data->IMC.hWnd = hWnd;
1323 TRACE("returning %p\n", rc);
1328 /***********************************************************************
1329 * ImmGetConversionListA (IMM32.@)
1331 DWORD WINAPI ImmGetConversionListA(
1333 LPCSTR pSrc, LPCANDIDATELIST lpDst,
1334 DWORD dwBufLen, UINT uFlag)
1336 FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
1337 hKL, hIMC, debugstr_a(pSrc), lpDst, dwBufLen, uFlag
1339 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1343 /***********************************************************************
1344 * ImmGetConversionListW (IMM32.@)
1346 DWORD WINAPI ImmGetConversionListW(
1348 LPCWSTR pSrc, LPCANDIDATELIST lpDst,
1349 DWORD dwBufLen, UINT uFlag)
1351 FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
1352 hKL, hIMC, debugstr_w(pSrc), lpDst, dwBufLen, uFlag
1354 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1358 /***********************************************************************
1359 * ImmGetConversionStatus (IMM32.@)
1361 BOOL WINAPI ImmGetConversionStatus(
1362 HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
1364 TRACE("(%p, %p, %p): best guess\n", hIMC, lpfdwConversion, lpfdwSentence);
1365 if (lpfdwConversion)
1366 *lpfdwConversion = IME_CMODE_NATIVE;
1368 *lpfdwSentence = IME_SMODE_NONE;
1372 /***********************************************************************
1373 * ImmGetDefaultIMEWnd (IMM32.@)
1375 HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
1377 static int shown = 0;
1380 FIXME("(%p - %p %p ): semi-stub\n", hWnd,hwndDefault, root_context);
1384 if (hwndDefault == NULL)
1386 static const WCHAR the_name[] = {'I','M','E','\0'};
1389 hwndDefault = CreateWindowExW( WS_EX_TOOLWINDOW, WC_IMECLASSNAME,
1390 the_name, WS_POPUP, 0, 0, 1, 1, 0, 0,
1393 TRACE("Default created (%p)\n",hwndDefault);
1399 /***********************************************************************
1400 * ImmGetDescriptionA (IMM32.@)
1402 UINT WINAPI ImmGetDescriptionA(
1403 HKL hKL, LPSTR lpszDescription, UINT uBufLen)
1408 TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
1410 /* find out how many characters in the unicode buffer */
1411 len = ImmGetDescriptionW( hKL, NULL, 0 );
1413 /* allocate a buffer of that size */
1414 buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
1418 /* fetch the unicode buffer */
1419 len = ImmGetDescriptionW( hKL, buf, len + 1 );
1421 /* convert it back to ASCII */
1422 len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
1423 lpszDescription, uBufLen, NULL, NULL );
1425 HeapFree( GetProcessHeap(), 0, buf );
1430 /***********************************************************************
1431 * ImmGetDescriptionW (IMM32.@)
1433 UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
1435 static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
1437 FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
1439 if (!uBufLen) return lstrlenW( name );
1440 lstrcpynW( lpszDescription, name, uBufLen );
1441 return lstrlenW( lpszDescription );
1444 /***********************************************************************
1445 * ImmGetGuideLineA (IMM32.@)
1447 DWORD WINAPI ImmGetGuideLineA(
1448 HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
1450 FIXME("(%p, %d, %s, %d): stub\n",
1451 hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
1453 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1457 /***********************************************************************
1458 * ImmGetGuideLineW (IMM32.@)
1460 DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
1462 FIXME("(%p, %d, %s, %d): stub\n",
1463 hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
1465 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1469 /***********************************************************************
1470 * ImmGetIMEFileNameA (IMM32.@)
1472 UINT WINAPI ImmGetIMEFileNameA( HKL hKL, LPSTR lpszFileName, UINT uBufLen)
1475 UINT wBufLen = uBufLen;
1478 if (uBufLen && lpszFileName)
1479 bufW = HeapAlloc(GetProcessHeap(),0,uBufLen * sizeof(WCHAR));
1480 else /* We need this to get the number of byte required */
1482 bufW = HeapAlloc(GetProcessHeap(),0,MAX_PATH * sizeof(WCHAR));
1486 rc = ImmGetIMEFileNameW(hKL,bufW,wBufLen);
1490 if (uBufLen && lpszFileName)
1491 rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, lpszFileName,
1492 uBufLen, NULL, NULL);
1493 else /* get the length */
1494 rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL,
1498 HeapFree(GetProcessHeap(),0,bufW);
1502 /***********************************************************************
1503 * ImmGetIMEFileNameW (IMM32.@)
1505 UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
1507 static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0};
1508 static const WCHAR fmt[] = {'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','s','\\','%','0','8','x',0};
1513 WCHAR regKey[sizeof(fmt)/sizeof(WCHAR)+8];
1515 wsprintfW( regKey, fmt, (unsigned)hKL );
1516 rc = RegOpenKeyW( HKEY_LOCAL_MACHINE, regKey, &hkey);
1517 if (rc != ERROR_SUCCESS)
1524 rc = RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, NULL, &length);
1526 if (rc != ERROR_SUCCESS)
1532 if (length > uBufLen * sizeof(WCHAR) || !lpszFileName)
1537 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1541 return length / sizeof(WCHAR);
1544 RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, lpszFileName, &length);
1548 return length / sizeof(WCHAR);
1551 /***********************************************************************
1552 * ImmGetOpenStatus (IMM32.@)
1554 BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
1556 InputContextData *data = (InputContextData*)hIMC;
1560 FIXME("(%p): semi-stub\n", hIMC);
1562 return data->IMC.fOpen;
1565 /***********************************************************************
1566 * ImmGetProperty (IMM32.@)
1568 DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
1571 TRACE("(%p, %d)\n", hKL, fdwIndex);
1576 TRACE("(%s)\n", "IGP_PROPERTY");
1577 rc = IME_PROP_UNICODE | IME_PROP_AT_CARET;
1579 case IGP_CONVERSION:
1580 FIXME("(%s)\n", "IGP_CONVERSION");
1581 rc = IME_CMODE_NATIVE;
1584 FIXME("%s)\n", "IGP_SENTENCE");
1585 rc = IME_SMODE_AUTOMATIC;
1587 case IGP_SETCOMPSTR:
1588 TRACE("(%s)\n", "IGP_SETCOMPSTR");
1592 TRACE("(%s)\n", "IGP_SELECT");
1593 rc = SELECT_CAP_CONVERSION | SELECT_CAP_SENTENCE;
1595 case IGP_GETIMEVERSION:
1596 TRACE("(%s)\n", "IGP_GETIMEVERSION");
1600 TRACE("(%s)\n", "IGP_UI");
1609 /***********************************************************************
1610 * ImmGetRegisterWordStyleA (IMM32.@)
1612 UINT WINAPI ImmGetRegisterWordStyleA(
1613 HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
1615 FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
1616 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1620 /***********************************************************************
1621 * ImmGetRegisterWordStyleW (IMM32.@)
1623 UINT WINAPI ImmGetRegisterWordStyleW(
1624 HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
1626 FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
1627 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1631 /***********************************************************************
1632 * ImmGetStatusWindowPos (IMM32.@)
1634 BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1636 FIXME("(%p, %p): stub\n", hIMC, lpptPos);
1637 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1641 /***********************************************************************
1642 * ImmGetVirtualKey (IMM32.@)
1644 UINT WINAPI ImmGetVirtualKey(HWND hWnd)
1646 OSVERSIONINFOA version;
1647 FIXME("(%p): stub\n", hWnd);
1648 GetVersionExA( &version );
1649 switch(version.dwPlatformId)
1651 case VER_PLATFORM_WIN32_WINDOWS:
1652 return VK_PROCESSKEY;
1653 case VER_PLATFORM_WIN32_NT:
1656 FIXME("%d not supported\n",version.dwPlatformId);
1657 return VK_PROCESSKEY;
1661 /***********************************************************************
1662 * ImmInstallIMEA (IMM32.@)
1664 HKL WINAPI ImmInstallIMEA(
1665 LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
1667 FIXME("(%s, %s): stub\n",
1668 debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
1670 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1674 /***********************************************************************
1675 * ImmInstallIMEW (IMM32.@)
1677 HKL WINAPI ImmInstallIMEW(
1678 LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
1680 FIXME("(%s, %s): stub\n",
1681 debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
1683 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1687 /***********************************************************************
1688 * ImmIsIME (IMM32.@)
1690 BOOL WINAPI ImmIsIME(HKL hKL)
1692 TRACE("(%p): semi-stub\n", hKL);
1694 * FIXME: Dead key locales will return TRUE here when they should not
1695 * There is probably a more proper way to check this.
1697 return (root_context != NULL);
1700 /***********************************************************************
1701 * ImmIsUIMessageA (IMM32.@)
1703 BOOL WINAPI ImmIsUIMessageA(
1704 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1708 TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
1709 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1710 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1711 (msg == WM_MSIME_SERVICE) ||
1712 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1713 (msg == WM_MSIME_MOUSE) ||
1714 (msg == WM_MSIME_RECONVERTREQUEST) ||
1715 (msg == WM_MSIME_RECONVERT) ||
1716 (msg == WM_MSIME_QUERYPOSITION) ||
1717 (msg == WM_MSIME_DOCUMENTFEED))
1721 ImmGetDefaultIMEWnd(NULL);
1723 if (hWndIME == NULL)
1724 PostMessageA(hwndDefault, msg, wParam, lParam);
1731 /***********************************************************************
1732 * ImmIsUIMessageW (IMM32.@)
1734 BOOL WINAPI ImmIsUIMessageW(
1735 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1738 TRACE("(%p, %d, %ld, %ld): stub\n", hWndIME, msg, wParam, lParam);
1739 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1740 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1741 (msg == WM_MSIME_SERVICE) ||
1742 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1743 (msg == WM_MSIME_MOUSE) ||
1744 (msg == WM_MSIME_RECONVERTREQUEST) ||
1745 (msg == WM_MSIME_RECONVERT) ||
1746 (msg == WM_MSIME_QUERYPOSITION) ||
1747 (msg == WM_MSIME_DOCUMENTFEED))
1752 /***********************************************************************
1753 * ImmNotifyIME (IMM32.@)
1755 BOOL WINAPI ImmNotifyIME(
1756 HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
1760 TRACE("(%p, %d, %d, %d)\n",
1761 hIMC, dwAction, dwIndex, dwValue);
1768 case NI_CHANGECANDIDATELIST:
1769 FIXME("%s\n","NI_CHANGECANDIDATELIST");
1771 case NI_CLOSECANDIDATE:
1772 FIXME("%s\n","NI_CLOSECANDIDATE");
1774 case NI_COMPOSITIONSTR:
1778 TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL");
1781 LPCOMPOSITIONSTRING lpCompStr;
1783 if (pX11DRV_ForceXIMReset)
1784 pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
1786 lpCompStr = ImmLockIMCC(root_context->IMC.hCompStr);
1787 send = (lpCompStr->dwCompStrLen != 0);
1788 ImmUnlockIMCC(root_context->IMC.hCompStr);
1790 ImmDestroyIMCC(root_context->IMC.hCompStr);
1791 root_context->IMC.hCompStr = ImmCreateBlankCompStr();
1794 ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION, 0,
1800 TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_COMPLETE");
1801 if (hIMC != (HIMC)FROM_IME && pX11DRV_ForceXIMReset)
1802 pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
1807 LPCOMPOSITIONSTRING cs = NULL;
1808 LPBYTE cdata = NULL;
1810 /* clear existing result */
1811 newCompStr = updateResultStr(root_context->IMC.hCompStr, NULL, 0);
1812 ImmDestroyIMCC(root_context->IMC.hCompStr);
1813 root_context->IMC.hCompStr = newCompStr;
1815 if (root_context->IMC.hCompStr)
1817 cdata = ImmLockIMCC(root_context->IMC.hCompStr);
1818 cs = (LPCOMPOSITIONSTRING)cdata;
1819 cplen = cs->dwCompStrLen;
1820 cpstr = (LPWSTR)&(cdata[cs->dwCompStrOffset]);
1821 ImmUnlockIMCC(root_context->IMC.hCompStr);
1825 WCHAR param = cpstr[0];
1826 newCompStr = updateResultStr(root_context->IMC.hCompStr, cpstr, cplen);
1827 ImmDestroyIMCC(root_context->IMC.hCompStr);
1828 root_context->IMC.hCompStr = newCompStr;
1829 newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
1830 ImmDestroyIMCC(root_context->IMC.hCompStr);
1831 root_context->IMC.hCompStr = newCompStr;
1833 root_context->bRead = FALSE;
1835 ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION, 0,
1838 ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION,
1840 GCS_RESULTSTR|GCS_RESULTCLAUSE);
1843 ImmInternalPostIMEMessage(root_context, WM_IME_ENDCOMPOSITION, 0, 0);
1844 root_context->bInComposition = FALSE;
1848 FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_CONVERT");
1851 FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_REVERT");
1854 ERR("%s - %s (%i)\n","NI_COMPOSITIONSTR","UNKNOWN",dwIndex);
1858 case NI_IMEMENUSELECTED:
1859 FIXME("%s\n", "NI_IMEMENUSELECTED");
1861 case NI_OPENCANDIDATE:
1862 FIXME("%s\n", "NI_OPENCANDIDATE");
1864 case NI_SELECTCANDIDATESTR:
1865 FIXME("%s\n", "NI_SELECTCANDIDATESTR");
1867 case NI_SETCANDIDATE_PAGESIZE:
1868 FIXME("%s\n", "NI_SETCANDIDATE_PAGESIZE");
1870 case NI_SETCANDIDATE_PAGESTART:
1871 FIXME("%s\n", "NI_SETCANDIDATE_PAGESTART");
1880 /***********************************************************************
1881 * ImmRegisterWordA (IMM32.@)
1883 BOOL WINAPI ImmRegisterWordA(
1884 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
1886 FIXME("(%p, %s, %d, %s): stub\n",
1887 hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister)
1889 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1893 /***********************************************************************
1894 * ImmRegisterWordW (IMM32.@)
1896 BOOL WINAPI ImmRegisterWordW(
1897 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
1899 FIXME("(%p, %s, %d, %s): stub\n",
1900 hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister)
1902 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1906 /***********************************************************************
1907 * ImmReleaseContext (IMM32.@)
1909 BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1911 static int shown = 0;
1914 FIXME("(%p, %p): stub\n", hWnd, hIMC);
1920 /***********************************************************************
1921 * ImmSetCandidateWindow (IMM32.@)
1923 BOOL WINAPI ImmSetCandidateWindow(
1924 HIMC hIMC, LPCANDIDATEFORM lpCandidate)
1926 FIXME("(%p, %p): stub\n", hIMC, lpCandidate);
1927 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1931 /***********************************************************************
1932 * ImmSetCompositionFontA (IMM32.@)
1934 BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
1936 InputContextData *data = (InputContextData*)hIMC;
1937 TRACE("(%p, %p)\n", hIMC, lplf);
1942 memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
1943 MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
1946 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
1950 DeleteObject(data->textfont);
1951 data->textfont = NULL;
1954 data->textfont = CreateFontIndirectW(&data->IMC.lfFont.W);
1958 /***********************************************************************
1959 * ImmSetCompositionFontW (IMM32.@)
1961 BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
1963 InputContextData *data = (InputContextData*)hIMC;
1964 TRACE("(%p, %p)\n", hIMC, lplf);
1969 data->IMC.lfFont.W = *lplf;
1970 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
1974 DeleteObject(data->textfont);
1975 data->textfont = NULL;
1977 data->textfont = CreateFontIndirectW(&data->IMC.lfFont.W);
1981 /***********************************************************************
1982 * ImmSetCompositionStringA (IMM32.@)
1984 BOOL WINAPI ImmSetCompositionStringA(
1985 HIMC hIMC, DWORD dwIndex,
1986 LPCVOID lpComp, DWORD dwCompLen,
1987 LPCVOID lpRead, DWORD dwReadLen)
1991 WCHAR *CompBuffer = NULL;
1992 WCHAR *ReadBuffer = NULL;
1995 TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
1996 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1998 comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
2001 CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len * sizeof(WCHAR));
2002 MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len);
2005 read_len = MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, NULL, 0);
2008 ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len * sizeof(WCHAR));
2009 MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len);
2012 rc = ImmSetCompositionStringW(hIMC, dwIndex, CompBuffer, comp_len,
2013 ReadBuffer, read_len);
2015 HeapFree(GetProcessHeap(), 0, CompBuffer);
2016 HeapFree(GetProcessHeap(), 0, ReadBuffer);
2021 /***********************************************************************
2022 * ImmSetCompositionStringW (IMM32.@)
2024 BOOL WINAPI ImmSetCompositionStringW(
2025 HIMC hIMC, DWORD dwIndex,
2026 LPCVOID lpComp, DWORD dwCompLen,
2027 LPCVOID lpRead, DWORD dwReadLen)
2032 TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
2033 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
2036 if (hIMC != (HIMC)FROM_IME)
2037 FIXME("PROBLEM: This only sets the wine level string\n");
2041 * this sets the composition string in the imm32.dll level
2042 * of the composition buffer. we cannot manipulate the xim level
2043 * buffer, which means that once the xim level buffer changes again
2044 * any call to this function from the application will be lost
2047 if (lpRead && dwReadLen)
2048 FIXME("Reading string unimplemented\n");
2051 * app operating this api to also receive the message from xim
2054 if (dwIndex == SCS_SETSTR)
2057 if (!root_context->bInComposition)
2059 ImmInternalPostIMEMessage(root_context, WM_IME_STARTCOMPOSITION, 0, 0);
2060 root_context->bInComposition = TRUE;
2063 flags = GCS_COMPSTR;
2065 if (dwCompLen && lpComp)
2067 newCompStr = updateCompStr(root_context->IMC.hCompStr, (LPWSTR)lpComp, dwCompLen / sizeof(WCHAR));
2068 ImmDestroyIMCC(root_context->IMC.hCompStr);
2069 root_context->IMC.hCompStr = newCompStr;
2071 wParam = ((const WCHAR*)lpComp)[0];
2072 flags |= GCS_COMPCLAUSE | GCS_COMPATTR | GCS_DELTASTART;
2076 newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
2077 ImmDestroyIMCC(root_context->IMC.hCompStr);
2078 root_context->IMC.hCompStr = newCompStr;
2082 UpdateDataInDefaultIMEWindow(hwndDefault,FALSE);
2084 ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION, wParam, flags);
2089 /***********************************************************************
2090 * ImmSetCompositionWindow (IMM32.@)
2092 BOOL WINAPI ImmSetCompositionWindow(
2093 HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
2095 BOOL reshow = FALSE;
2096 InputContextData *data = (InputContextData*)hIMC;
2098 TRACE("(%p, %p)\n", hIMC, lpCompForm);
2099 TRACE("\t%x, (%i,%i), (%i,%i - %i,%i)\n",lpCompForm->dwStyle,
2100 lpCompForm->ptCurrentPos.x, lpCompForm->ptCurrentPos.y, lpCompForm->rcArea.top,
2101 lpCompForm->rcArea.left, lpCompForm->rcArea.bottom, lpCompForm->rcArea.right);
2106 data->IMC.cfCompForm = *lpCompForm;
2108 if (IsWindowVisible(hwndDefault))
2111 ShowWindow(hwndDefault,SW_HIDE);
2114 /* FIXME: this is a partial stub */
2117 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
2119 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0);
2123 /***********************************************************************
2124 * ImmSetConversionStatus (IMM32.@)
2126 BOOL WINAPI ImmSetConversionStatus(
2127 HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
2129 static int shown = 0;
2132 FIXME("(%p, %d, %d): stub\n",
2133 hIMC, fdwConversion, fdwSentence
2137 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2141 /***********************************************************************
2142 * ImmSetOpenStatus (IMM32.@)
2144 BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
2146 InputContextData *data = (InputContextData*)hIMC;
2148 TRACE("%p %d\n", hIMC, fOpen);
2150 if (hIMC == (HIMC)FROM_IME)
2152 ImmInternalSetOpenStatus(fOpen);
2153 ImmInternalSendIMENotify(root_context, IMN_SETOPENSTATUS, 0);
2160 if (fOpen != data->bInternalState)
2162 if (fOpen == FALSE && pX11DRV_ForceXIMReset)
2163 pX11DRV_ForceXIMReset(data->IMC.hWnd);
2166 ImmInternalPostIMEMessage(data, WM_IME_ENDCOMPOSITION,0,0);
2168 ImmInternalPostIMEMessage(data, WM_IME_STARTCOMPOSITION,0,0);
2170 ImmInternalSetOpenStatus(fOpen);
2171 ImmInternalSetOpenStatus(!fOpen);
2173 if (data->IMC.fOpen == FALSE)
2174 ImmInternalPostIMEMessage(data, WM_IME_ENDCOMPOSITION,0,0);
2176 ImmInternalPostIMEMessage(data, WM_IME_STARTCOMPOSITION,0,0);
2183 /***********************************************************************
2184 * ImmSetStatusWindowPos (IMM32.@)
2186 BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
2188 FIXME("(%p, %p): stub\n", hIMC, lpptPos);
2189 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2193 /***********************************************************************
2194 * ImmSimulateHotKey (IMM32.@)
2196 BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
2198 FIXME("(%p, %d): stub\n", hWnd, dwHotKeyID);
2199 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2203 /***********************************************************************
2204 * ImmUnregisterWordA (IMM32.@)
2206 BOOL WINAPI ImmUnregisterWordA(
2207 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
2209 FIXME("(%p, %s, %d, %s): stub\n",
2210 hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister)
2212 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2216 /***********************************************************************
2217 * ImmUnregisterWordW (IMM32.@)
2219 BOOL WINAPI ImmUnregisterWordW(
2220 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
2222 FIXME("(%p, %s, %d, %s): stub\n",
2223 hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister)
2225 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2229 /***********************************************************************
2230 * ImmGetImeMenuItemsA (IMM32.@)
2232 DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType,
2233 LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
2236 FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType,
2237 lpImeParentMenu, lpImeMenu, dwSize);
2241 /***********************************************************************
2242 * ImmGetImeMenuItemsW (IMM32.@)
2244 DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType,
2245 LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
2248 FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType,
2249 lpImeParentMenu, lpImeMenu, dwSize);
2253 /***********************************************************************
2254 * ImmLockIMC(IMM32.@)
2256 LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
2258 InputContextData *data = (InputContextData*)hIMC;
2266 /***********************************************************************
2267 * ImmUnlockIMC(IMM32.@)
2269 BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
2271 InputContextData *data = (InputContextData*)hIMC;
2273 return (data->dwLock!=0);
2276 /***********************************************************************
2277 * ImmGetIMCLockCount(IMM32.@)
2279 DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
2281 InputContextData *data = (InputContextData*)hIMC;
2282 return data->dwLock;
2285 /***********************************************************************
2286 * ImmCreateIMCC(IMM32.@)
2288 HIMCC WINAPI ImmCreateIMCC(DWORD size)
2290 IMCCInternal *internal;
2291 int real_size = size + sizeof(IMCCInternal);
2293 internal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, real_size);
2294 if (internal == NULL)
2297 internal->dwSize = size;
2298 return (HIMCC)internal;
2301 /***********************************************************************
2302 * ImmDestroyIMCC(IMM32.@)
2304 HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
2306 HeapFree(GetProcessHeap(),0,block);
2310 /***********************************************************************
2311 * ImmLockIMCC(IMM32.@)
2313 LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
2315 IMCCInternal *internal;
2316 internal = (IMCCInternal*) imcc;
2318 internal->dwLock ++;
2319 return internal + 1;
2322 /***********************************************************************
2323 * ImmUnlockIMCC(IMM32.@)
2325 BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
2327 IMCCInternal *internal;
2328 internal = (IMCCInternal*) imcc;
2330 internal->dwLock --;
2331 return (internal->dwLock!=0);
2334 /***********************************************************************
2335 * ImmGetIMCCLockCount(IMM32.@)
2337 DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
2339 IMCCInternal *internal;
2340 internal = (IMCCInternal*) imcc;
2342 return internal->dwLock;
2345 /***********************************************************************
2346 * ImmReSizeIMCC(IMM32.@)
2348 HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
2350 IMCCInternal *internal,*newone;
2351 int real_size = size + sizeof(IMCCInternal);
2353 internal = (IMCCInternal*) imcc;
2355 newone = HeapReAlloc(GetProcessHeap(), 0, internal, real_size);
2356 newone->dwSize = size;
2361 /***********************************************************************
2362 * ImmGetIMCCSize(IMM32.@)
2364 DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
2366 IMCCInternal *internal;
2367 internal = (IMCCInternal*) imcc;
2369 return internal->dwSize;
2372 /***********************************************************************
2373 * ImmGenerateMessage(IMM32.@)
2375 BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
2377 InputContextData *data = (InputContextData*)hIMC;
2379 TRACE("%i messages queued\n",data->IMC.dwNumMsgBuf);
2380 if (data->IMC.dwNumMsgBuf > 0)
2382 LPTRANSMSG lpTransMsg;
2385 lpTransMsg = (LPTRANSMSG)ImmLockIMCC(data->IMC.hMsgBuf);
2386 for (i = 0; i < data->IMC.dwNumMsgBuf; i++)
2387 ImmInternalPostIMEMessage(data, lpTransMsg[i].message, lpTransMsg[i].wParam, lpTransMsg[i].lParam);
2389 ImmUnlockIMCC(data->IMC.hMsgBuf);
2391 data->IMC.dwNumMsgBuf = 0;
2398 * Internal functions to help with IME window management
2400 static void PaintDefaultIMEWnd(HWND hwnd)
2404 HDC hdc = BeginPaint(hwnd,&ps);
2405 LPCOMPOSITIONSTRING compstr;
2406 LPBYTE compdata = NULL;
2408 MONITORINFO mon_info;
2411 GetClientRect(hwnd,&rect);
2412 FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1));
2414 compdata = ImmLockIMCC(root_context->IMC.hCompStr);
2415 compstr = (LPCOMPOSITIONSTRING)compdata;
2417 if (compstr->dwCompStrLen && compstr->dwCompStrOffset)
2421 HFONT oldfont = NULL;
2424 CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
2425 if (root_context->textfont)
2426 oldfont = SelectObject(hdc,root_context->textfont);
2429 GetTextExtentPoint32W(hdc, CompString, compstr->dwCompStrLen, &size);
2435 * How this works based on tests on windows:
2436 * CFS_POINT: then we start our window at the point and grow it as large
2437 * as it needs to be for the string.
2438 * CFS_RECT: we still use the ptCurrentPos as a starting point and our
2439 * window is only as large as we need for the string, but we do not
2440 * grow such that our window exceeds the given rect. Wrapping if
2441 * needed and possible. If our ptCurrentPos is outside of our rect
2442 * then no window is displayed.
2443 * CFS_FORCE_POSITION: appears to behave just like CFS_POINT
2444 * maybe becase the default MSIME does not do any IME adjusting.
2446 if (root_context->IMC.cfCompForm.dwStyle != CFS_DEFAULT)
2448 POINT cpt = root_context->IMC.cfCompForm.ptCurrentPos;
2449 ClientToScreen(root_context->IMC.hWnd,&cpt);
2452 rect.right = rect.left + pt.x;
2453 rect.bottom = rect.top + pt.y;
2454 monitor = MonitorFromPoint(cpt, MONITOR_DEFAULTTOPRIMARY);
2456 else /* CFS_DEFAULT */
2458 /* Windows places the default IME window in the bottom left */
2459 HWND target = root_context->IMC.hWnd;
2460 if (!target) target = GetFocus();
2462 GetWindowRect(target,&rect);
2463 rect.top = rect.bottom;
2464 rect.right = rect.left + pt.x + 20;
2465 rect.bottom = rect.top + pt.y + 20;
2467 monitor = MonitorFromWindow(target, MONITOR_DEFAULTTOPRIMARY);
2470 if (root_context->IMC.cfCompForm.dwStyle == CFS_RECT)
2473 client =root_context->IMC.cfCompForm.rcArea;
2474 MapWindowPoints( root_context->IMC.hWnd, 0, (POINT *)&client, 2 );
2475 IntersectRect(&rect,&rect,&client);
2476 /* TODO: Wrap the input if needed */
2479 if (root_context->IMC.cfCompForm.dwStyle == CFS_DEFAULT)
2481 /* make sure we are on the desktop */
2482 mon_info.cbSize = sizeof(mon_info);
2483 GetMonitorInfoW(monitor, &mon_info);
2485 if (rect.bottom > mon_info.rcWork.bottom)
2487 int shift = rect.bottom - mon_info.rcWork.bottom;
2489 rect.bottom -= shift;
2493 rect.right -= rect.left;
2496 if (rect.right > mon_info.rcWork.right)
2498 int shift = rect.right - mon_info.rcWork.right;
2500 rect.right -= shift;
2504 SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE);
2506 TextOutW(hdc, offX,offY, CompString, compstr->dwCompStrLen);
2509 SelectObject(hdc,oldfont);
2512 ImmUnlockIMCC(root_context->IMC.hCompStr);
2517 static void UpdateDataInDefaultIMEWindow(HWND hwnd, BOOL showable)
2519 LPCOMPOSITIONSTRING compstr;
2521 if (root_context->IMC.hCompStr)
2522 compstr = ImmLockIMCC(root_context->IMC.hCompStr);
2526 if (compstr == NULL || compstr->dwCompStrLen == 0)
2527 ShowWindow(hwndDefault,SW_HIDE);
2529 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
2531 RedrawWindow(hwnd,NULL,NULL,RDW_ERASENOW|RDW_INVALIDATE);
2533 if (compstr != NULL)
2534 ImmUnlockIMCC(root_context->IMC.hCompStr);
2538 * The window proc for the default IME window
2540 static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
2545 TRACE("Incoming Message 0x%x (0x%08x, 0x%08x)\n", msg, (UINT)wParam,
2551 PaintDefaultIMEWnd(hwnd);
2558 SetWindowTextA(hwnd,"Wine Ime Active");
2563 SetFocus((HWND)wParam);
2565 FIXME("Received focus, should never have focus\n");
2567 case WM_IME_COMPOSITION:
2568 TRACE("IME message %s, 0x%x, 0x%x (%i)\n",
2569 "WM_IME_COMPOSITION", (UINT)wParam, (UINT)lParam,
2570 root_context->bRead);
2571 if (lParam & GCS_RESULTSTR)
2572 IMM_PostResult(root_context);
2574 UpdateDataInDefaultIMEWindow(hwnd,TRUE);
2576 case WM_IME_STARTCOMPOSITION:
2577 TRACE("IME message %s, 0x%x, 0x%x\n",
2578 "WM_IME_STARTCOMPOSITION", (UINT)wParam, (UINT)lParam);
2579 root_context->IMC.hWnd = GetFocus();
2580 ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
2582 case WM_IME_ENDCOMPOSITION:
2583 TRACE("IME message %s, 0x%x, 0x%x\n",
2584 "WM_IME_ENDCOMPOSITION", (UINT)wParam, (UINT)lParam);
2585 ShowWindow(hwndDefault,SW_HIDE);
2588 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_SELECT",
2589 (UINT)wParam, (UINT)lParam);
2591 case WM_IME_CONTROL:
2592 TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_CONTROL",
2593 (UINT)wParam, (UINT)lParam);
2597 TRACE("!! IME NOTIFY\n");
2600 TRACE("Non-standard message 0x%x\n",msg);
2602 /* check the MSIME messages */
2603 if (msg == WM_MSIME_SERVICE)
2605 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_SERVICE",
2606 (UINT)wParam, (UINT)lParam);
2609 else if (msg == WM_MSIME_RECONVERTOPTIONS)
2611 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTOPTIONS",
2612 (UINT)wParam, (UINT)lParam);
2614 else if (msg == WM_MSIME_MOUSE)
2616 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_MOUSE",
2617 (UINT)wParam, (UINT)lParam);
2619 else if (msg == WM_MSIME_RECONVERTREQUEST)
2621 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTREQUEST",
2622 (UINT)wParam, (UINT)lParam);
2624 else if (msg == WM_MSIME_RECONVERT)
2626 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERT",
2627 (UINT)wParam, (UINT)lParam);
2629 else if (msg == WM_MSIME_QUERYPOSITION)
2631 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_QUERYPOSITION",
2632 (UINT)wParam, (UINT)lParam);
2634 else if (msg == WM_MSIME_DOCUMENTFEED)
2636 TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_DOCUMENTFEED",
2637 (UINT)wParam, (UINT)lParam);
2639 /* DefWndProc if not an IME message */
2640 else if (!rc && !((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
2641 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP)))
2642 rc = DefWindowProcW(hwnd,msg,wParam,lParam);