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 typedef struct tagIMCCInternal
45 #define MAKE_FUNCPTR(f) typeof(f) * p##f
46 typedef struct _tagImmHkl{
51 WCHAR imeClassName[17]; /* 16 character max */
54 /* Function Pointers */
55 MAKE_FUNCPTR(ImeInquire);
56 MAKE_FUNCPTR(ImeConfigure);
57 MAKE_FUNCPTR(ImeDestroy);
58 MAKE_FUNCPTR(ImeEscape);
59 MAKE_FUNCPTR(ImeSelect);
60 MAKE_FUNCPTR(ImeSetActiveContext);
61 MAKE_FUNCPTR(ImeToAsciiEx);
62 MAKE_FUNCPTR(NotifyIME);
63 MAKE_FUNCPTR(ImeRegisterWord);
64 MAKE_FUNCPTR(ImeUnregisterWord);
65 MAKE_FUNCPTR(ImeEnumRegisterWord);
66 MAKE_FUNCPTR(ImeSetCompositionString);
67 MAKE_FUNCPTR(ImeConversionList);
68 MAKE_FUNCPTR(ImeProcessKey);
69 MAKE_FUNCPTR(ImeGetRegisterWordStyle);
70 MAKE_FUNCPTR(ImeGetImeMenuItems);
74 typedef struct tagInputContextData
84 typedef struct _tagTRANSMSG {
88 } TRANSMSG, *LPTRANSMSG;
90 typedef struct _tagIMMThreadData {
95 static DWORD tlsIndex = 0;
96 static struct list ImmHklList = LIST_INIT(ImmHklList);
99 static UINT WM_MSIME_SERVICE;
100 static UINT WM_MSIME_RECONVERTOPTIONS;
101 static UINT WM_MSIME_MOUSE;
102 static UINT WM_MSIME_RECONVERTREQUEST;
103 static UINT WM_MSIME_RECONVERT;
104 static UINT WM_MSIME_QUERYPOSITION;
105 static UINT WM_MSIME_DOCUMENTFEED;
107 static const WCHAR szwWineIMCProperty[] = {'W','i','n','e','I','m','m','H','I','M','C','P','r','o','p','e','r','t','y',0};
109 #define is_himc_ime_unicode(p) (p->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE)
110 #define is_kbd_ime_unicode(p) (p->imeInfo.fdwProperty & IME_PROP_UNICODE)
112 static BOOL IMM_DestroyContext(HIMC hIMC);
114 static inline WCHAR *strdupAtoW( const char *str )
119 DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
120 if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
121 MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
126 static inline CHAR *strdupWtoA( const WCHAR *str )
131 DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
132 if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
133 WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
138 static DWORD convert_candidatelist_WtoA(
139 LPCANDIDATELIST lpSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen)
143 ret = FIELD_OFFSET( CANDIDATELIST, dwOffset[lpSrc->dwCount] );
144 if ( lpDst && dwBufLen > 0 )
147 lpDst->dwOffset[0] = ret;
150 for ( i = 0; i < lpSrc->dwCount; i++)
152 LPBYTE src = (LPBYTE)lpSrc + lpSrc->dwOffset[i];
154 if ( lpDst && dwBufLen > 0 )
156 LPBYTE dest = (LPBYTE)lpDst + lpDst->dwOffset[i];
158 len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1,
159 (LPSTR)dest, dwBufLen, NULL, NULL);
161 if ( i + 1 < lpSrc->dwCount )
162 lpDst->dwOffset[i+1] = lpDst->dwOffset[i] + len * sizeof(char);
163 dwBufLen -= len * sizeof(char);
166 len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, NULL, 0, NULL, NULL);
168 ret += len * sizeof(char);
177 static DWORD convert_candidatelist_AtoW(
178 LPCANDIDATELIST lpSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen)
182 ret = FIELD_OFFSET( CANDIDATELIST, dwOffset[lpSrc->dwCount] );
183 if ( lpDst && dwBufLen > 0 )
186 lpDst->dwOffset[0] = ret;
189 for ( i = 0; i < lpSrc->dwCount; i++)
191 LPBYTE src = (LPBYTE)lpSrc + lpSrc->dwOffset[i];
193 if ( lpDst && dwBufLen > 0 )
195 LPBYTE dest = (LPBYTE)lpDst + lpDst->dwOffset[i];
197 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1,
198 (LPWSTR)dest, dwBufLen);
200 if ( i + 1 < lpSrc->dwCount )
201 lpDst->dwOffset[i+1] = lpDst->dwOffset[i] + len * sizeof(WCHAR);
202 dwBufLen -= len * sizeof(WCHAR);
205 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1, NULL, 0);
207 ret += len * sizeof(WCHAR);
216 static IMMThreadData* IMM_GetThreadData(void)
218 return (IMMThreadData*)TlsGetValue(tlsIndex);
221 static void IMM_InitThreadData(void)
223 IMMThreadData* data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
224 sizeof(IMMThreadData));
225 TlsSetValue(tlsIndex,data);
227 TRACE("Thread Data Created\n");
230 static void IMM_FreeThreadData(void)
232 IMMThreadData* data = TlsGetValue(tlsIndex);
233 IMM_DestroyContext(data->defaultContext);
234 DestroyWindow(data->hwndDefault);
235 HeapFree(GetProcessHeap(),0,data);
236 TRACE("Thread Data Destroyed\n");
239 static HMODULE LoadDefaultWineIME(void)
241 char buffer[MAX_PATH], libname[32], *name, *next;
245 TRACE("Attempting to fall back to wine default IME\n");
247 strcpy( buffer, "x11" ); /* default value */
248 /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
249 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey ))
251 DWORD type, count = sizeof(buffer);
252 RegQueryValueExA( hkey, "Ime", 0, &type, (LPBYTE) buffer, &count );
259 next = strchr( name, ',' );
260 if (next) *next++ = 0;
262 snprintf( libname, sizeof(libname), "wine%s.drv", name );
263 if ((module = LoadLibraryA( libname )) != 0) break;
270 /* ImmHkl loading and freeing */
271 #define LOAD_FUNCPTR(f) if((ptr->p##f = (LPVOID)GetProcAddress(ptr->hIME, #f)) == NULL){WARN("Can't find function %s in ime\n", #f);}
272 static ImmHkl *IMM_GetImmHkl(HKL hkl)
275 WCHAR filename[MAX_PATH];
277 TRACE("Seeking ime for keyboard 0x%x\n",(unsigned)hkl);
279 LIST_FOR_EACH_ENTRY(ptr, &ImmHklList, ImmHkl, entry)
284 /* not found... create it */
286 ptr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ImmHkl));
289 if (ImmGetIMEFileNameW(hkl, filename, MAX_PATH)) ptr->hIME = LoadLibraryW(filename);
291 ptr->hIME = LoadDefaultWineIME();
294 LOAD_FUNCPTR(ImeInquire);
295 if (!ptr->pImeInquire || !ptr->pImeInquire(&ptr->imeInfo, ptr->imeClassName, NULL))
297 FreeLibrary(ptr->hIME);
302 LOAD_FUNCPTR(ImeDestroy);
303 LOAD_FUNCPTR(ImeSelect);
304 if (!ptr->pImeSelect || !ptr->pImeDestroy)
306 FreeLibrary(ptr->hIME);
311 LOAD_FUNCPTR(ImeConfigure);
312 LOAD_FUNCPTR(ImeEscape);
313 LOAD_FUNCPTR(ImeSetActiveContext);
314 LOAD_FUNCPTR(ImeToAsciiEx);
315 LOAD_FUNCPTR(NotifyIME);
316 LOAD_FUNCPTR(ImeRegisterWord);
317 LOAD_FUNCPTR(ImeUnregisterWord);
318 LOAD_FUNCPTR(ImeEnumRegisterWord);
319 LOAD_FUNCPTR(ImeSetCompositionString);
320 LOAD_FUNCPTR(ImeConversionList);
321 LOAD_FUNCPTR(ImeProcessKey);
322 LOAD_FUNCPTR(ImeGetRegisterWordStyle);
323 LOAD_FUNCPTR(ImeGetImeMenuItems);
324 /* make sure our classname is WCHAR */
325 if (!is_kbd_ime_unicode(ptr))
328 MultiByteToWideChar(CP_ACP, 0, (LPSTR)ptr->imeClassName,
330 lstrcpyW(ptr->imeClassName, bufW);
335 list_add_head(&ImmHklList,&ptr->entry);
341 static void IMM_FreeAllImmHkl(void)
343 ImmHkl *ptr,*cursor2;
345 LIST_FOR_EACH_ENTRY_SAFE(ptr, cursor2, &ImmHklList, ImmHkl, entry)
347 list_remove(&ptr->entry);
351 FreeLibrary(ptr->hIME);
353 HeapFree(GetProcessHeap(),0,ptr);
357 static void IMM_RegisterMessages(void)
359 WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
360 WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
361 WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
362 WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
363 WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
364 WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
365 WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
368 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
370 TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
373 case DLL_PROCESS_ATTACH:
374 IMM_RegisterMessages();
375 tlsIndex = TlsAlloc();
376 IMM_InitThreadData();
378 case DLL_THREAD_ATTACH:
379 IMM_InitThreadData();
381 case DLL_THREAD_DETACH:
382 IMM_FreeThreadData();
384 case DLL_PROCESS_DETACH:
385 IMM_FreeThreadData();
393 /* for posting messages as the IME */
394 static void ImmInternalPostIMEMessage(InputContextData *data, UINT msg, WPARAM wParam, LPARAM lParam)
396 HWND target = GetFocus();
398 PostMessageW(data->IMC.hWnd,msg,wParam,lParam);
400 PostMessageW(target, msg, wParam, lParam);
403 static LRESULT ImmInternalSendIMENotify(InputContextData *data, WPARAM notify, LPARAM lParam)
407 target = data->IMC.hWnd;
408 if (!target) target = GetFocus();
411 return SendMessageW(target, WM_IME_NOTIFY, notify, lParam);
416 static HIMCC ImmCreateBlankCompStr(void)
419 LPCOMPOSITIONSTRING ptr;
420 rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
421 ptr = (LPCOMPOSITIONSTRING)ImmLockIMCC(rc);
422 memset(ptr,0,sizeof(COMPOSITIONSTRING));
423 ptr->dwSize = sizeof(COMPOSITIONSTRING);
428 /***********************************************************************
429 * ImmAssociateContext (IMM32.@)
431 HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
434 InputContextData *data = (InputContextData*)hIMC;
436 TRACE("(%p, %p):\n", hWnd, hIMC);
438 if (!IMM_GetThreadData()->defaultContext)
439 IMM_GetThreadData()->defaultContext = ImmCreateContext();
442 * If already associated just return
444 if (hIMC && data->IMC.hWnd == hWnd)
449 old = (HIMC)RemovePropW(hWnd,szwWineIMCProperty);
452 old = IMM_GetThreadData()->defaultContext;
453 else if (old == (HIMC)-1)
456 if (hIMC != IMM_GetThreadData()->defaultContext)
458 if (hIMC == NULL) /* Meaning disable imm for that window*/
459 SetPropW(hWnd,szwWineIMCProperty,(HANDLE)-1);
461 SetPropW(hWnd,szwWineIMCProperty,(HANDLE)hIMC);
466 InputContextData *old_data = (InputContextData*)old;
467 if (old_data->IMC.hWnd == hWnd)
468 old_data->IMC.hWnd = NULL;
475 if (IsWindow(data->IMC.hWnd))
478 * Post a message that your context is switching
480 SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
483 data->IMC.hWnd = hWnd;
485 if (IsWindow(data->IMC.hWnd))
488 * Post a message that your context is switching
490 SendMessageW(data->IMC.hWnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
496 /***********************************************************************
497 * ImmAssociateContextEx (IMM32.@)
499 BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
501 FIXME("(%p, %p, %d): stub\n", hWnd, hIMC, dwFlags);
502 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
506 /***********************************************************************
507 * ImmConfigureIMEA (IMM32.@)
509 BOOL WINAPI ImmConfigureIMEA(
510 HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
512 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
514 TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
516 if (immHkl->hIME && immHkl->pImeConfigure)
518 if (dwMode != IME_CONFIG_REGISTERWORD || !is_kbd_ime_unicode(immHkl))
519 return immHkl->pImeConfigure(hKL,hWnd,dwMode,lpData);
523 REGISTERWORDA *rwa = (REGISTERWORDA*)lpData;
526 rww.lpReading = strdupAtoW(rwa->lpReading);
527 rww.lpWord = strdupAtoW(rwa->lpWord);
528 rc = immHkl->pImeConfigure(hKL,hWnd,dwMode,&rww);
529 HeapFree(GetProcessHeap(),0,rww.lpReading);
530 HeapFree(GetProcessHeap(),0,rww.lpWord);
538 /***********************************************************************
539 * ImmConfigureIMEW (IMM32.@)
541 BOOL WINAPI ImmConfigureIMEW(
542 HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
544 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
546 TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
548 if (immHkl->hIME && immHkl->pImeConfigure)
550 if (dwMode != IME_CONFIG_REGISTERWORD || is_kbd_ime_unicode(immHkl))
551 return immHkl->pImeConfigure(hKL,hWnd,dwMode,lpData);
554 REGISTERWORDW *rww = (REGISTERWORDW*)lpData;
558 rwa.lpReading = strdupWtoA(rww->lpReading);
559 rwa.lpWord = strdupWtoA(rww->lpWord);
560 rc = immHkl->pImeConfigure(hKL,hWnd,dwMode,&rwa);
561 HeapFree(GetProcessHeap(),0,rwa.lpReading);
562 HeapFree(GetProcessHeap(),0,rwa.lpWord);
570 /***********************************************************************
571 * ImmCreateContext (IMM32.@)
573 HIMC WINAPI ImmCreateContext(void)
575 InputContextData *new_context;
579 new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
582 new_context->immKbd = IMM_GetImmHkl(GetKeyboardLayout(0));
584 if (!new_context->immKbd->hIME)
586 TRACE("IME dll could not be loaded\n");
587 HeapFree(GetProcessHeap(),0,new_context);
591 /* the HIMCCs are never NULL */
592 new_context->IMC.hCompStr = ImmCreateBlankCompStr();
593 new_context->IMC.hMsgBuf = ImmCreateIMCC(0);
594 new_context->IMC.hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
595 ci = ImmLockIMCC(new_context->IMC.hCandInfo);
596 memset(ci,0,sizeof(CANDIDATEINFO));
597 ci->dwSize = sizeof(CANDIDATEINFO);
598 ImmUnlockIMCC(new_context->IMC.hCandInfo);
599 new_context->IMC.hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
600 gl = ImmLockIMCC(new_context->IMC.hGuideLine);
601 memset(gl,0,sizeof(GUIDELINE));
602 gl->dwSize = sizeof(GUIDELINE);
603 ImmUnlockIMCC(new_context->IMC.hGuideLine);
605 /* Initialize the IME Private */
606 new_context->IMC.hPrivate = ImmCreateIMCC(new_context->immKbd->imeInfo.dwPrivateDataSize);
608 if (!new_context->immKbd->pImeSelect(new_context, TRUE))
610 TRACE("Selection of IME failed\n");
611 IMM_DestroyContext(new_context);
615 new_context->immKbd->uSelected++;
616 TRACE("Created context 0x%x\n",(UINT)new_context);
618 return (HIMC)new_context;
621 static BOOL IMM_DestroyContext(HIMC hIMC)
623 InputContextData *data = (InputContextData*)hIMC;
625 TRACE("Destroying %p\n",hIMC);
629 data->immKbd->uSelected --;
630 data->immKbd->pImeSelect(hIMC, FALSE);
632 if (IMM_GetThreadData()->hwndDefault == data->imeWnd)
633 IMM_GetThreadData()->hwndDefault = NULL;
634 DestroyWindow(data->imeWnd);
636 ImmDestroyIMCC(data->IMC.hCompStr);
637 ImmDestroyIMCC(data->IMC.hCandInfo);
638 ImmDestroyIMCC(data->IMC.hGuideLine);
639 ImmDestroyIMCC(data->IMC.hPrivate);
640 ImmDestroyIMCC(data->IMC.hMsgBuf);
642 HeapFree(GetProcessHeap(),0,data);
647 /***********************************************************************
648 * ImmDestroyContext (IMM32.@)
650 BOOL WINAPI ImmDestroyContext(HIMC hIMC)
652 if (hIMC != IMM_GetThreadData()->defaultContext)
653 return IMM_DestroyContext(hIMC);
658 /***********************************************************************
659 * ImmDisableIME (IMM32.@)
661 BOOL WINAPI ImmDisableIME(DWORD idThread)
663 FIXME("(%d): stub\n", idThread);
667 /***********************************************************************
668 * ImmEnumRegisterWordA (IMM32.@)
670 UINT WINAPI ImmEnumRegisterWordA(
671 HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
672 LPCSTR lpszReading, DWORD dwStyle,
673 LPCSTR lpszRegister, LPVOID lpData)
675 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
676 TRACE("(%p, %p, %s, %d, %s, %p):\n", hKL, lpfnEnumProc,
677 debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister), lpData);
678 if (immHkl->hIME && immHkl->pImeEnumRegisterWord)
680 if (!is_kbd_ime_unicode(immHkl))
681 return immHkl->pImeEnumRegisterWord((REGISTERWORDENUMPROCW)lpfnEnumProc,
682 (LPCWSTR)lpszReading, dwStyle, (LPCWSTR)lpszRegister, lpData);
685 LPWSTR lpszwReading = strdupAtoW(lpszReading);
686 LPWSTR lpszwRegister = strdupAtoW(lpszRegister);
689 rc = immHkl->pImeEnumRegisterWord((REGISTERWORDENUMPROCW)lpfnEnumProc,
690 lpszwReading, dwStyle, lpszwRegister,
693 HeapFree(GetProcessHeap(),0,lpszwReading);
694 HeapFree(GetProcessHeap(),0,lpszwRegister);
702 /***********************************************************************
703 * ImmEnumRegisterWordW (IMM32.@)
705 UINT WINAPI ImmEnumRegisterWordW(
706 HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
707 LPCWSTR lpszReading, DWORD dwStyle,
708 LPCWSTR lpszRegister, LPVOID lpData)
710 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
711 TRACE("(%p, %p, %s, %d, %s, %p):\n", hKL, lpfnEnumProc,
712 debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister), lpData);
713 if (immHkl->hIME && immHkl->pImeEnumRegisterWord)
715 if (is_kbd_ime_unicode(immHkl))
716 return immHkl->pImeEnumRegisterWord(lpfnEnumProc, lpszReading, dwStyle,
717 lpszRegister, lpData);
720 LPSTR lpszaReading = strdupWtoA(lpszReading);
721 LPSTR lpszaRegister = strdupWtoA(lpszRegister);
724 rc = immHkl->pImeEnumRegisterWord(lpfnEnumProc, (LPCWSTR)lpszaReading,
725 dwStyle, (LPCWSTR)lpszaRegister, lpData);
727 HeapFree(GetProcessHeap(),0,lpszaReading);
728 HeapFree(GetProcessHeap(),0,lpszaRegister);
736 /***********************************************************************
737 * ImmEscapeA (IMM32.@)
739 LRESULT WINAPI ImmEscapeA(
741 UINT uEscape, LPVOID lpData)
743 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
744 TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
746 if (immHkl->hIME && immHkl->pImeEscape)
748 if (!is_kbd_ime_unicode(immHkl))
749 return immHkl->pImeEscape(hIMC,uEscape,lpData);
752 FIXME("A procedure called with W ime back end\n");
753 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
761 /***********************************************************************
762 * ImmEscapeW (IMM32.@)
764 LRESULT WINAPI ImmEscapeW(
766 UINT uEscape, LPVOID lpData)
768 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
769 TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
771 if (immHkl->hIME && immHkl->pImeEscape)
773 if (is_kbd_ime_unicode(immHkl))
774 return immHkl->pImeEscape(hIMC,uEscape,lpData);
777 FIXME("W procedure called with A ime back end\n");
778 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
786 /***********************************************************************
787 * ImmGetCandidateListA (IMM32.@)
789 DWORD WINAPI ImmGetCandidateListA(
790 HIMC hIMC, DWORD dwIndex,
791 LPCANDIDATELIST lpCandList, DWORD dwBufLen)
793 InputContextData *data = (InputContextData *)hIMC;
794 LPCANDIDATEINFO candinfo;
795 LPCANDIDATELIST candlist;
798 TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
800 if (!data || !data->IMC.hCandInfo)
803 candinfo = ImmLockIMCC(data->IMC.hCandInfo);
804 if ( dwIndex >= candinfo->dwCount ||
805 dwIndex >= (sizeof(candinfo->dwOffset) / sizeof(DWORD)) )
808 candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + candinfo->dwOffset[dwIndex]);
809 if ( !candlist->dwSize || !candlist->dwCount )
812 if ( !is_himc_ime_unicode(data) )
814 ret = candlist->dwSize;
815 if ( lpCandList && dwBufLen >= ret )
816 memcpy(lpCandList, candlist, ret);
819 ret = convert_candidatelist_WtoA( candlist, lpCandList, dwBufLen);
822 ImmUnlockIMCC(data->IMC.hCandInfo);
826 /***********************************************************************
827 * ImmGetCandidateListCountA (IMM32.@)
829 DWORD WINAPI ImmGetCandidateListCountA(
830 HIMC hIMC, LPDWORD lpdwListCount)
832 InputContextData *data = (InputContextData *)hIMC;
833 LPCANDIDATEINFO candinfo;
836 TRACE("%p, %p\n", hIMC, lpdwListCount);
838 if (!data || !lpdwListCount || !data->IMC.hCandInfo)
841 candinfo = ImmLockIMCC(data->IMC.hCandInfo);
843 *lpdwListCount = count = candinfo->dwCount;
845 if ( !is_himc_ime_unicode(data) )
846 ret = candinfo->dwSize;
849 ret = sizeof(CANDIDATEINFO);
851 ret += ImmGetCandidateListA(hIMC, count, NULL, 0);
854 ImmUnlockIMCC(data->IMC.hCandInfo);
858 /***********************************************************************
859 * ImmGetCandidateListCountW (IMM32.@)
861 DWORD WINAPI ImmGetCandidateListCountW(
862 HIMC hIMC, LPDWORD lpdwListCount)
864 InputContextData *data = (InputContextData *)hIMC;
865 LPCANDIDATEINFO candinfo;
868 TRACE("%p, %p\n", hIMC, lpdwListCount);
870 if (!data || !lpdwListCount || !data->IMC.hCandInfo)
873 candinfo = ImmLockIMCC(data->IMC.hCandInfo);
875 *lpdwListCount = count = candinfo->dwCount;
877 if ( is_himc_ime_unicode(data) )
878 ret = candinfo->dwSize;
881 ret = sizeof(CANDIDATEINFO);
883 ret += ImmGetCandidateListW(hIMC, count, NULL, 0);
886 ImmUnlockIMCC(data->IMC.hCandInfo);
890 /***********************************************************************
891 * ImmGetCandidateListW (IMM32.@)
893 DWORD WINAPI ImmGetCandidateListW(
894 HIMC hIMC, DWORD dwIndex,
895 LPCANDIDATELIST lpCandList, DWORD dwBufLen)
897 InputContextData *data = (InputContextData *)hIMC;
898 LPCANDIDATEINFO candinfo;
899 LPCANDIDATELIST candlist;
902 TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
904 if (!data || !data->IMC.hCandInfo)
907 candinfo = ImmLockIMCC(data->IMC.hCandInfo);
908 if ( dwIndex >= candinfo->dwCount ||
909 dwIndex >= (sizeof(candinfo->dwOffset) / sizeof(DWORD)) )
912 candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + candinfo->dwOffset[dwIndex]);
913 if ( !candlist->dwSize || !candlist->dwCount )
916 if ( is_himc_ime_unicode(data) )
918 ret = candlist->dwSize;
919 if ( lpCandList && dwBufLen >= ret )
920 memcpy(lpCandList, candlist, ret);
923 ret = convert_candidatelist_AtoW( candlist, lpCandList, dwBufLen);
926 ImmUnlockIMCC(data->IMC.hCandInfo);
930 /***********************************************************************
931 * ImmGetCandidateWindow (IMM32.@)
933 BOOL WINAPI ImmGetCandidateWindow(
934 HIMC hIMC, DWORD dwIndex, LPCANDIDATEFORM lpCandidate)
936 InputContextData *data = (InputContextData*)hIMC;
938 TRACE("%p, %d, %p\n", hIMC, dwIndex, lpCandidate);
940 if (!data || !lpCandidate)
943 if ( dwIndex >= (sizeof(data->IMC.cfCandForm) / sizeof(CANDIDATEFORM)) )
946 *lpCandidate = data->IMC.cfCandForm[dwIndex];
951 /***********************************************************************
952 * ImmGetCompositionFontA (IMM32.@)
954 BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
959 TRACE("(%p, %p):\n", hIMC, lplf);
961 rc = ImmGetCompositionFontW(hIMC,&lfW);
965 memcpy(lplf,&lfW,sizeof(LOGFONTA));
966 WideCharToMultiByte(CP_ACP, 0, lfW.lfFaceName, -1, lplf->lfFaceName,
967 LF_FACESIZE, NULL, NULL);
971 /***********************************************************************
972 * ImmGetCompositionFontW (IMM32.@)
974 BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
976 InputContextData *data = (InputContextData*)hIMC;
978 TRACE("(%p, %p):\n", hIMC, lplf);
983 *lplf = data->IMC.lfFont.W;
988 /***********************************************************************
989 * ImmGetCompositionStringA (IMM32.@)
991 LONG WINAPI ImmGetCompositionStringA(
992 HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
994 BOOL isString = FALSE;
995 LPBYTE buffer = NULL;
998 InputContextData *data = (InputContextData*)hIMC;
999 LPCOMPOSITIONSTRING compstr;
1002 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
1007 if (!data->IMC.hCompStr)
1010 compdata = ImmLockIMCC(data->IMC.hCompStr);
1011 compstr = (LPCOMPOSITIONSTRING)compdata;
1016 if (compstr->dwResultStrLen > 0 && compstr->dwResultStrOffset > 0)
1019 buffer = compdata + compstr->dwResultStrOffset;
1020 rc = compstr->dwResultStrLen;
1021 TRACE("GCS_RESULTSTR %p %i\n", buffer, rc);
1025 if (compstr->dwCompStrLen > 0 && compstr->dwCompStrOffset > 0)
1028 buffer = compdata + compstr->dwCompStrOffset;
1029 rc = compstr->dwCompStrLen;
1030 TRACE("GCS_COMPSTR %p %i\n", buffer, rc);
1034 if (compstr->dwCompAttrLen > 0 && compstr->dwCompAttrOffset > 0)
1036 buffer = compdata + compstr->dwCompAttrOffset;
1037 rc = compstr->dwCompAttrLen;
1038 TRACE("GCS_COMPATTR %p %i\n", buffer, rc);
1041 case GCS_COMPCLAUSE:
1042 if (compstr->dwCompClauseLen > 0 && compstr->dwCompClauseOffset > 0)
1044 buffer = compdata + compstr->dwCompClauseOffset;
1045 rc = compstr->dwCompClauseLen;
1046 TRACE("GCS_COMPCLAUSE %p %i\n", buffer, rc);
1049 case GCS_RESULTCLAUSE:
1050 if (compstr->dwResultClauseLen > 0 && compstr->dwResultClauseOffset > 0)
1052 buffer = compdata + compstr->dwResultClauseOffset;
1053 rc = compstr->dwResultClauseLen;
1054 TRACE("GCS_RESULTCLAUSE %p %i\n", buffer, rc);
1057 case GCS_RESULTREADSTR:
1058 if (compstr->dwResultReadStrLen > 0 && compstr->dwResultReadStrOffset > 0)
1061 buffer = compdata + compstr->dwResultReadStrOffset;
1062 rc = compstr->dwResultReadStrLen;
1063 TRACE("GCS_RESULTREADSTR %p %i\n",buffer, rc);
1066 case GCS_RESULTREADCLAUSE:
1067 if (compstr->dwResultReadClauseLen > 0 && compstr->dwResultReadClauseOffset > 0)
1069 buffer = compdata + compstr->dwResultReadClauseOffset;
1070 rc = compstr->dwResultReadClauseLen;
1071 TRACE("GCS_RESULTREADCLAUSE %p %i\n", buffer, rc);
1074 case GCS_COMPREADSTR:
1075 if (compstr->dwCompReadStrLen > 0 && compstr->dwCompReadStrOffset > 0)
1078 buffer = compdata + compstr->dwCompReadStrOffset;
1079 rc = compstr->dwCompReadStrLen;
1080 TRACE("GCS_COMPREADSTR %p %i\n", buffer, rc);
1083 case GCS_COMPREADATTR:
1084 if (compstr->dwCompReadAttrLen > 0 && compstr->dwCompReadAttrOffset > 0)
1086 buffer = compdata + compstr->dwCompReadAttrOffset;
1087 rc = compstr->dwCompReadAttrLen;
1088 TRACE("GCS_COMPREADATTR %p %i\n", buffer, rc);
1091 case GCS_COMPREADCLAUSE:
1092 if (compstr->dwCompReadClauseLen > 0 && compstr->dwCompReadClauseOffset > 0)
1094 buffer = compdata + compstr->dwCompReadClauseOffset;
1095 rc = compstr->dwCompReadClauseLen;
1096 TRACE("GCS_COMPREADCLAUSE %p %i\n", buffer, rc);
1100 TRACE("GCS_CURSORPOS\n");
1101 rc = compstr->dwCursorPos;
1103 case GCS_DELTASTART:
1104 TRACE("GCS_DELTASTART\n");
1105 rc = compstr->dwDeltaStart;
1108 FIXME("Unhandled index 0x%x\n",dwIndex);
1112 if ( isString && buffer && is_himc_ime_unicode(data))
1114 INT len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)buffer, rc, NULL, 0, NULL, NULL);
1115 buf = HeapAlloc( GetProcessHeap(), 0, len );
1117 rc = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)buffer, rc, buf, len, NULL, NULL);
1118 buffer = (LPBYTE)buf;
1121 if ( lpBuf && buffer && dwBufLen >= rc)
1122 memcpy(lpBuf, buffer, rc);
1124 HeapFree( GetProcessHeap(), 0, buf );
1125 ImmUnlockIMCC(data->IMC.hCompStr);
1130 /***********************************************************************
1131 * ImmGetCompositionStringW (IMM32.@)
1133 LONG WINAPI ImmGetCompositionStringW(
1134 HIMC hIMC, DWORD dwIndex,
1135 LPVOID lpBuf, DWORD dwBufLen)
1137 BOOL isString = FALSE;
1138 LPBYTE buffer = NULL;
1141 InputContextData *data = (InputContextData*)hIMC;
1142 LPCOMPOSITIONSTRING compstr;
1145 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
1150 if (!data->IMC.hCompStr)
1153 compdata = ImmLockIMCC(data->IMC.hCompStr);
1154 compstr = (LPCOMPOSITIONSTRING)compdata;
1159 if (compstr->dwResultStrLen > 0 && compstr->dwResultStrOffset > 0)
1162 buffer = compdata + compstr->dwResultStrOffset;
1163 rc = compstr->dwResultStrLen;
1164 TRACE("GCS_RESULTSTR %p %i\n", buffer, rc);
1167 case GCS_RESULTREADSTR:
1168 if (compstr->dwResultReadStrLen > 0 && compstr->dwResultReadStrOffset > 0)
1171 buffer = compdata + compstr->dwResultReadStrOffset;
1172 rc = compstr->dwResultReadStrLen;
1173 TRACE("GCS_RESULTREADSTR %p %i\n",buffer, rc);
1177 if (compstr->dwCompStrLen > 0 && compstr->dwCompStrOffset > 0)
1180 buffer = compdata + compstr->dwCompStrOffset;
1181 rc = compstr->dwCompStrLen;
1182 TRACE("GCS_COMPSTR %p %i\n", buffer, rc);
1186 if (compstr->dwCompAttrLen > 0 && compstr->dwCompAttrOffset > 0)
1188 buffer = compdata + compstr->dwCompAttrOffset;
1189 rc = compstr->dwCompAttrLen;
1190 TRACE("GCS_COMPATTR %p %i\n", buffer, rc);
1193 case GCS_COMPCLAUSE:
1194 if (compstr->dwCompClauseLen > 0 && compstr->dwCompClauseOffset > 0)
1196 buffer = compdata + compstr->dwCompClauseOffset;
1197 rc = compstr->dwCompClauseLen;
1198 TRACE("GCS_COMPCLAUSE %p %i\n", buffer, rc);
1201 case GCS_COMPREADSTR:
1202 if (compstr->dwCompReadStrLen > 0 && compstr->dwCompReadStrOffset > 0)
1205 buffer = compdata + compstr->dwCompReadStrOffset;
1206 rc = compstr->dwCompReadStrLen;
1207 TRACE("GCS_COMPREADSTR %p %i\n", buffer, rc);
1210 case GCS_COMPREADATTR:
1211 if (compstr->dwCompReadAttrLen > 0 && compstr->dwCompReadAttrOffset > 0)
1213 buffer = compdata + compstr->dwCompReadAttrOffset;
1214 rc = compstr->dwCompReadAttrLen;
1215 TRACE("GCS_COMPREADATTR %p %i\n", buffer, rc);
1218 case GCS_COMPREADCLAUSE:
1219 if (compstr->dwCompReadClauseLen > 0 && compstr->dwCompReadClauseOffset > 0)
1221 buffer = compdata + compstr->dwCompReadClauseOffset;
1222 rc = compstr->dwCompReadClauseLen;
1223 TRACE("GCS_COMPREADCLAUSE %p %i\n", buffer, rc);
1226 case GCS_RESULTREADCLAUSE:
1227 if (compstr->dwResultReadClauseLen > 0 && compstr->dwResultReadClauseOffset > 0)
1229 buffer = compdata + compstr->dwResultReadClauseOffset;
1230 rc = compstr->dwResultReadClauseLen;
1231 TRACE("GCS_RESULTREADCLAUSE %p %i\n", buffer, rc);
1234 case GCS_RESULTCLAUSE:
1235 if (compstr->dwResultClauseLen > 0 && compstr->dwResultClauseOffset > 0)
1237 buffer = compdata + compstr->dwResultClauseOffset;
1238 rc = compstr->dwResultClauseLen;
1239 TRACE("GCS_RESULTCLAUSE %p %i\n", buffer, rc);
1243 TRACE("GCS_CURSORPOS\n");
1244 rc = compstr->dwCursorPos;
1246 case GCS_DELTASTART:
1247 TRACE("GCS_DELTASTART\n");
1248 rc = compstr->dwDeltaStart;
1251 FIXME("Unhandled index 0x%x\n",dwIndex);
1255 if ( isString && buffer )
1257 if ( !is_himc_ime_unicode(data) )
1259 INT len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)buffer, rc, NULL, 0 );
1260 buf = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1262 rc = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)buffer, rc, buf, len );
1263 buffer = (LPBYTE)buf;
1265 rc *= sizeof(WCHAR);
1268 if ( lpBuf && buffer && dwBufLen >= rc )
1269 memcpy( lpBuf, buffer, rc );
1271 HeapFree( GetProcessHeap(), 0, buf );
1272 ImmUnlockIMCC(data->IMC.hCompStr);
1277 /***********************************************************************
1278 * ImmGetCompositionWindow (IMM32.@)
1280 BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
1282 InputContextData *data = (InputContextData*)hIMC;
1284 TRACE("(%p, %p)\n", hIMC, lpCompForm);
1289 *lpCompForm = data->IMC.cfCompForm;
1293 /***********************************************************************
1294 * ImmGetContext (IMM32.@)
1297 HIMC WINAPI ImmGetContext(HWND hWnd)
1301 TRACE("%p\n", hWnd);
1302 if (!IMM_GetThreadData()->defaultContext)
1303 IMM_GetThreadData()->defaultContext = ImmCreateContext();
1305 rc = (HIMC)GetPropW(hWnd,szwWineIMCProperty);
1308 else if (rc == NULL)
1309 rc = IMM_GetThreadData()->defaultContext;
1313 InputContextData *data = (InputContextData*)rc;
1314 data->IMC.hWnd = hWnd;
1316 TRACE("returning %p\n", rc);
1321 /***********************************************************************
1322 * ImmGetConversionListA (IMM32.@)
1324 DWORD WINAPI ImmGetConversionListA(
1326 LPCSTR pSrc, LPCANDIDATELIST lpDst,
1327 DWORD dwBufLen, UINT uFlag)
1329 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1330 TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL, hIMC, debugstr_a(pSrc), lpDst,
1332 if (immHkl->hIME && immHkl->pImeConversionList)
1334 if (!is_kbd_ime_unicode(immHkl))
1335 return immHkl->pImeConversionList(hIMC,(LPCWSTR)pSrc,lpDst,dwBufLen,uFlag);
1338 LPCANDIDATELIST lpwDst;
1340 LPWSTR pwSrc = strdupAtoW(pSrc);
1342 len = immHkl->pImeConversionList(hIMC, pwSrc, NULL, 0, uFlag);
1343 lpwDst = HeapAlloc(GetProcessHeap(), 0, len);
1346 immHkl->pImeConversionList(hIMC, pwSrc, lpwDst, len, uFlag);
1347 ret = convert_candidatelist_WtoA( lpwDst, lpDst, dwBufLen);
1348 HeapFree(GetProcessHeap(), 0, lpwDst);
1350 HeapFree(GetProcessHeap(), 0, pwSrc);
1359 /***********************************************************************
1360 * ImmGetConversionListW (IMM32.@)
1362 DWORD WINAPI ImmGetConversionListW(
1364 LPCWSTR pSrc, LPCANDIDATELIST lpDst,
1365 DWORD dwBufLen, UINT uFlag)
1367 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1368 TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL, hIMC, debugstr_w(pSrc), lpDst,
1370 if (immHkl->hIME && immHkl->pImeConversionList)
1372 if (is_kbd_ime_unicode(immHkl))
1373 return immHkl->pImeConversionList(hIMC,pSrc,lpDst,dwBufLen,uFlag);
1376 LPCANDIDATELIST lpaDst;
1378 LPSTR paSrc = strdupWtoA(pSrc);
1380 len = immHkl->pImeConversionList(hIMC, (LPCWSTR)paSrc, NULL, 0, uFlag);
1381 lpaDst = HeapAlloc(GetProcessHeap(), 0, len);
1384 immHkl->pImeConversionList(hIMC, (LPCWSTR)paSrc, lpaDst, len, uFlag);
1385 ret = convert_candidatelist_AtoW( lpaDst, lpDst, dwBufLen);
1386 HeapFree(GetProcessHeap(), 0, lpaDst);
1388 HeapFree(GetProcessHeap(), 0, paSrc);
1397 /***********************************************************************
1398 * ImmGetConversionStatus (IMM32.@)
1400 BOOL WINAPI ImmGetConversionStatus(
1401 HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
1403 InputContextData *data = (InputContextData*)hIMC;
1405 TRACE("%p %p %p\n", hIMC, lpfdwConversion, lpfdwSentence);
1410 if (lpfdwConversion)
1411 *lpfdwConversion = data->IMC.fdwConversion;
1413 *lpfdwSentence = data->IMC.fdwSentence;
1418 /***********************************************************************
1419 * ImmGetDefaultIMEWnd (IMM32.@)
1421 HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
1423 TRACE("Default is %x\n",(unsigned)IMM_GetThreadData()->hwndDefault);
1424 return IMM_GetThreadData()->hwndDefault;
1427 /***********************************************************************
1428 * ImmGetDescriptionA (IMM32.@)
1430 UINT WINAPI ImmGetDescriptionA(
1431 HKL hKL, LPSTR lpszDescription, UINT uBufLen)
1436 TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
1438 /* find out how many characters in the unicode buffer */
1439 len = ImmGetDescriptionW( hKL, NULL, 0 );
1441 /* allocate a buffer of that size */
1442 buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
1446 /* fetch the unicode buffer */
1447 len = ImmGetDescriptionW( hKL, buf, len + 1 );
1449 /* convert it back to ASCII */
1450 len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
1451 lpszDescription, uBufLen, NULL, NULL );
1453 HeapFree( GetProcessHeap(), 0, buf );
1458 /***********************************************************************
1459 * ImmGetDescriptionW (IMM32.@)
1461 UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
1463 static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
1465 FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
1467 if (!uBufLen) return lstrlenW( name );
1468 lstrcpynW( lpszDescription, name, uBufLen );
1469 return lstrlenW( lpszDescription );
1472 /***********************************************************************
1473 * ImmGetGuideLineA (IMM32.@)
1475 DWORD WINAPI ImmGetGuideLineA(
1476 HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
1478 FIXME("(%p, %d, %s, %d): stub\n",
1479 hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
1481 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1485 /***********************************************************************
1486 * ImmGetGuideLineW (IMM32.@)
1488 DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
1490 FIXME("(%p, %d, %s, %d): stub\n",
1491 hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
1493 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1497 /***********************************************************************
1498 * ImmGetIMEFileNameA (IMM32.@)
1500 UINT WINAPI ImmGetIMEFileNameA( HKL hKL, LPSTR lpszFileName, UINT uBufLen)
1503 UINT wBufLen = uBufLen;
1506 if (uBufLen && lpszFileName)
1507 bufW = HeapAlloc(GetProcessHeap(),0,uBufLen * sizeof(WCHAR));
1508 else /* We need this to get the number of byte required */
1510 bufW = HeapAlloc(GetProcessHeap(),0,MAX_PATH * sizeof(WCHAR));
1514 rc = ImmGetIMEFileNameW(hKL,bufW,wBufLen);
1518 if (uBufLen && lpszFileName)
1519 rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, lpszFileName,
1520 uBufLen, NULL, NULL);
1521 else /* get the length */
1522 rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL,
1526 HeapFree(GetProcessHeap(),0,bufW);
1530 /***********************************************************************
1531 * ImmGetIMEFileNameW (IMM32.@)
1533 UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
1535 static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0};
1536 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};
1541 WCHAR regKey[sizeof(fmt)/sizeof(WCHAR)+8];
1543 wsprintfW( regKey, fmt, (unsigned)hKL );
1544 rc = RegOpenKeyW( HKEY_LOCAL_MACHINE, regKey, &hkey);
1545 if (rc != ERROR_SUCCESS)
1552 rc = RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, NULL, &length);
1554 if (rc != ERROR_SUCCESS)
1560 if (length > uBufLen * sizeof(WCHAR) || !lpszFileName)
1565 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1569 return length / sizeof(WCHAR);
1572 RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, lpszFileName, &length);
1576 return length / sizeof(WCHAR);
1579 /***********************************************************************
1580 * ImmGetOpenStatus (IMM32.@)
1582 BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
1584 InputContextData *data = (InputContextData*)hIMC;
1588 FIXME("(%p): semi-stub\n", hIMC);
1590 return data->IMC.fOpen;
1593 /***********************************************************************
1594 * ImmGetProperty (IMM32.@)
1596 DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
1601 TRACE("(%p, %d)\n", hKL, fdwIndex);
1602 kbd = IMM_GetImmHkl(hKL);
1604 if (kbd && kbd->hIME)
1608 case IGP_PROPERTY: rc = kbd->imeInfo.fdwProperty; break;
1609 case IGP_CONVERSION: rc = kbd->imeInfo.fdwConversionCaps; break;
1610 case IGP_SENTENCE: rc = kbd->imeInfo.fdwSentenceCaps; break;
1611 case IGP_SETCOMPSTR: rc = kbd->imeInfo.fdwSCSCaps; break;
1612 case IGP_SELECT: rc = kbd->imeInfo.fdwSelectCaps; break;
1613 case IGP_GETIMEVERSION: rc = IMEVER_0400; break;
1614 case IGP_UI: rc = 0; break;
1621 /***********************************************************************
1622 * ImmGetRegisterWordStyleA (IMM32.@)
1624 UINT WINAPI ImmGetRegisterWordStyleA(
1625 HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
1627 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1628 TRACE("(%p, %d, %p):\n", hKL, nItem, lpStyleBuf);
1629 if (immHkl->hIME && immHkl->pImeGetRegisterWordStyle)
1631 if (!is_kbd_ime_unicode(immHkl))
1632 return immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)lpStyleBuf);
1638 rc = immHkl->pImeGetRegisterWordStyle(nItem,&sbw);
1639 WideCharToMultiByte(CP_ACP, 0, sbw.szDescription, -1,
1640 lpStyleBuf->szDescription, 32, NULL, NULL);
1641 lpStyleBuf->dwStyle = sbw.dwStyle;
1649 /***********************************************************************
1650 * ImmGetRegisterWordStyleW (IMM32.@)
1652 UINT WINAPI ImmGetRegisterWordStyleW(
1653 HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
1655 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1656 TRACE("(%p, %d, %p):\n", hKL, nItem, lpStyleBuf);
1657 if (immHkl->hIME && immHkl->pImeGetRegisterWordStyle)
1659 if (is_kbd_ime_unicode(immHkl))
1660 return immHkl->pImeGetRegisterWordStyle(nItem,lpStyleBuf);
1666 rc = immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)&sba);
1667 MultiByteToWideChar(CP_ACP, 0, sba.szDescription, -1,
1668 lpStyleBuf->szDescription, 32);
1669 lpStyleBuf->dwStyle = sba.dwStyle;
1677 /***********************************************************************
1678 * ImmGetStatusWindowPos (IMM32.@)
1680 BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1682 InputContextData *data = (InputContextData*)hIMC;
1684 TRACE("(%p, %p)\n", hIMC, lpptPos);
1686 if (!data || !lpptPos)
1689 *lpptPos = data->IMC.ptStatusWndPos;
1694 /***********************************************************************
1695 * ImmGetVirtualKey (IMM32.@)
1697 UINT WINAPI ImmGetVirtualKey(HWND hWnd)
1699 OSVERSIONINFOA version;
1700 InputContextData *data = (InputContextData *)ImmGetContext( hWnd );
1701 TRACE("%p\n", hWnd);
1704 return data->lastVK;
1706 GetVersionExA( &version );
1707 switch(version.dwPlatformId)
1709 case VER_PLATFORM_WIN32_WINDOWS:
1710 return VK_PROCESSKEY;
1711 case VER_PLATFORM_WIN32_NT:
1714 FIXME("%d not supported\n",version.dwPlatformId);
1715 return VK_PROCESSKEY;
1719 /***********************************************************************
1720 * ImmInstallIMEA (IMM32.@)
1722 HKL WINAPI ImmInstallIMEA(
1723 LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
1725 FIXME("(%s, %s): stub\n",
1726 debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
1728 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1732 /***********************************************************************
1733 * ImmInstallIMEW (IMM32.@)
1735 HKL WINAPI ImmInstallIMEW(
1736 LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
1738 FIXME("(%s, %s): stub\n",
1739 debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
1741 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1745 /***********************************************************************
1746 * ImmIsIME (IMM32.@)
1748 BOOL WINAPI ImmIsIME(HKL hKL)
1751 TRACE("(%p):\n", hKL);
1752 ptr = IMM_GetImmHkl(hKL);
1753 return (ptr && ptr->hIME);
1756 /***********************************************************************
1757 * ImmIsUIMessageA (IMM32.@)
1759 BOOL WINAPI ImmIsUIMessageA(
1760 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1764 TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
1765 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1766 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1767 (msg == WM_MSIME_SERVICE) ||
1768 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1769 (msg == WM_MSIME_MOUSE) ||
1770 (msg == WM_MSIME_RECONVERTREQUEST) ||
1771 (msg == WM_MSIME_RECONVERT) ||
1772 (msg == WM_MSIME_QUERYPOSITION) ||
1773 (msg == WM_MSIME_DOCUMENTFEED))
1776 if (!IMM_GetThreadData()->hwndDefault)
1777 ImmGetDefaultIMEWnd(NULL);
1779 if (hWndIME == NULL)
1780 PostMessageA(IMM_GetThreadData()->hwndDefault, msg, wParam, lParam);
1787 /***********************************************************************
1788 * ImmIsUIMessageW (IMM32.@)
1790 BOOL WINAPI ImmIsUIMessageW(
1791 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1794 TRACE("(%p, %d, %ld, %ld):\n", hWndIME, msg, wParam, lParam);
1795 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1796 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1797 (msg == WM_MSIME_SERVICE) ||
1798 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1799 (msg == WM_MSIME_MOUSE) ||
1800 (msg == WM_MSIME_RECONVERTREQUEST) ||
1801 (msg == WM_MSIME_RECONVERT) ||
1802 (msg == WM_MSIME_QUERYPOSITION) ||
1803 (msg == WM_MSIME_DOCUMENTFEED))
1808 /***********************************************************************
1809 * ImmNotifyIME (IMM32.@)
1811 BOOL WINAPI ImmNotifyIME(
1812 HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
1814 InputContextData *data = (InputContextData*)hIMC;
1816 TRACE("(%p, %d, %d, %d)\n",
1817 hIMC, dwAction, dwIndex, dwValue);
1819 if (!data || ! data->immKbd->pNotifyIME)
1822 return data->immKbd->pNotifyIME(hIMC,dwAction,dwIndex,dwValue);
1825 /***********************************************************************
1826 * ImmRegisterWordA (IMM32.@)
1828 BOOL WINAPI ImmRegisterWordA(
1829 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
1831 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1832 TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_a(lpszReading), dwStyle,
1833 debugstr_a(lpszRegister));
1834 if (immHkl->hIME && immHkl->pImeRegisterWord)
1836 if (!is_kbd_ime_unicode(immHkl))
1837 return immHkl->pImeRegisterWord((LPCWSTR)lpszReading,dwStyle,
1838 (LPCWSTR)lpszRegister);
1841 LPWSTR lpszwReading = strdupAtoW(lpszReading);
1842 LPWSTR lpszwRegister = strdupAtoW(lpszRegister);
1845 rc = immHkl->pImeRegisterWord(lpszwReading,dwStyle,lpszwRegister);
1846 HeapFree(GetProcessHeap(),0,lpszwReading);
1847 HeapFree(GetProcessHeap(),0,lpszwRegister);
1855 /***********************************************************************
1856 * ImmRegisterWordW (IMM32.@)
1858 BOOL WINAPI ImmRegisterWordW(
1859 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
1861 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1862 TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_w(lpszReading), dwStyle,
1863 debugstr_w(lpszRegister));
1864 if (immHkl->hIME && immHkl->pImeRegisterWord)
1866 if (is_kbd_ime_unicode(immHkl))
1867 return immHkl->pImeRegisterWord(lpszReading,dwStyle,lpszRegister);
1870 LPSTR lpszaReading = strdupWtoA(lpszReading);
1871 LPSTR lpszaRegister = strdupWtoA(lpszRegister);
1874 rc = immHkl->pImeRegisterWord((LPCWSTR)lpszaReading,dwStyle,
1875 (LPCWSTR)lpszaRegister);
1876 HeapFree(GetProcessHeap(),0,lpszaReading);
1877 HeapFree(GetProcessHeap(),0,lpszaRegister);
1885 /***********************************************************************
1886 * ImmReleaseContext (IMM32.@)
1888 BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1890 static int shown = 0;
1893 FIXME("(%p, %p): stub\n", hWnd, hIMC);
1899 /***********************************************************************
1900 * ImmRequestMessageA(IMM32.@)
1902 LRESULT WINAPI ImmRequestMessageA(HIMC hIMC, WPARAM wParam, LPARAM lParam)
1904 InputContextData *data = (InputContextData*)hIMC;
1906 TRACE("%p %ld %ld\n", hIMC, wParam, wParam);
1908 if (data && IsWindow(data->IMC.hWnd))
1909 return SendMessageA(data->IMC.hWnd, WM_IME_REQUEST, wParam, lParam);
1914 /***********************************************************************
1915 * ImmRequestMessageW(IMM32.@)
1917 LRESULT WINAPI ImmRequestMessageW(HIMC hIMC, WPARAM wParam, LPARAM lParam)
1919 InputContextData *data = (InputContextData*)hIMC;
1921 TRACE("%p %ld %ld\n", hIMC, wParam, wParam);
1923 if (data && IsWindow(data->IMC.hWnd))
1924 return SendMessageW(data->IMC.hWnd, WM_IME_REQUEST, wParam, lParam);
1929 /***********************************************************************
1930 * ImmSetCandidateWindow (IMM32.@)
1932 BOOL WINAPI ImmSetCandidateWindow(
1933 HIMC hIMC, LPCANDIDATEFORM lpCandidate)
1935 InputContextData *data = (InputContextData*)hIMC;
1937 TRACE("(%p, %p)\n", hIMC, lpCandidate);
1939 if (!data || !lpCandidate)
1942 TRACE("\t%x, %x, (%i,%i), (%i,%i - %i,%i)\n",
1943 lpCandidate->dwIndex, lpCandidate->dwStyle,
1944 lpCandidate->ptCurrentPos.x, lpCandidate->ptCurrentPos.y,
1945 lpCandidate->rcArea.top, lpCandidate->rcArea.left,
1946 lpCandidate->rcArea.bottom, lpCandidate->rcArea.right);
1948 if ( lpCandidate->dwIndex >= (sizeof(data->IMC.cfCandForm) / sizeof(CANDIDATEFORM)) )
1951 data->IMC.cfCandForm[lpCandidate->dwIndex] = *lpCandidate;
1952 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS);
1953 ImmInternalSendIMENotify(data, IMN_SETCANDIDATEPOS, 1 << lpCandidate->dwIndex);
1958 /***********************************************************************
1959 * ImmSetCompositionFontA (IMM32.@)
1961 BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
1963 InputContextData *data = (InputContextData*)hIMC;
1964 TRACE("(%p, %p)\n", hIMC, lplf);
1969 memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
1970 MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
1972 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
1973 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
1978 /***********************************************************************
1979 * ImmSetCompositionFontW (IMM32.@)
1981 BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
1983 InputContextData *data = (InputContextData*)hIMC;
1984 TRACE("(%p, %p)\n", hIMC, lplf);
1989 data->IMC.lfFont.W = *lplf;
1990 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
1991 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
1996 /***********************************************************************
1997 * ImmSetCompositionStringA (IMM32.@)
1999 BOOL WINAPI ImmSetCompositionStringA(
2000 HIMC hIMC, DWORD dwIndex,
2001 LPCVOID lpComp, DWORD dwCompLen,
2002 LPCVOID lpRead, DWORD dwReadLen)
2006 WCHAR *CompBuffer = NULL;
2007 WCHAR *ReadBuffer = NULL;
2009 InputContextData *data = (InputContextData*)hIMC;
2011 TRACE("(%p, %d, %p, %d, %p, %d):\n",
2012 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
2017 if (!is_himc_ime_unicode(data))
2018 return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
2019 dwCompLen, lpRead, dwReadLen);
2021 comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
2024 CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len * sizeof(WCHAR));
2025 MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len);
2028 read_len = MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, NULL, 0);
2031 ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len * sizeof(WCHAR));
2032 MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len);
2035 rc = ImmSetCompositionStringW(hIMC, dwIndex, CompBuffer, comp_len,
2036 ReadBuffer, read_len);
2038 HeapFree(GetProcessHeap(), 0, CompBuffer);
2039 HeapFree(GetProcessHeap(), 0, ReadBuffer);
2044 /***********************************************************************
2045 * ImmSetCompositionStringW (IMM32.@)
2047 BOOL WINAPI ImmSetCompositionStringW(
2048 HIMC hIMC, DWORD dwIndex,
2049 LPCVOID lpComp, DWORD dwCompLen,
2050 LPCVOID lpRead, DWORD dwReadLen)
2054 CHAR *CompBuffer = NULL;
2055 CHAR *ReadBuffer = NULL;
2057 InputContextData *data = (InputContextData*)hIMC;
2059 TRACE("(%p, %d, %p, %d, %p, %d):\n",
2060 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
2065 if (is_himc_ime_unicode(data))
2066 return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
2067 dwCompLen, lpRead, dwReadLen);
2069 comp_len = WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, NULL, 0, NULL,
2073 CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len);
2074 WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len,
2078 read_len = WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, NULL, 0, NULL,
2082 ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len);
2083 WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len,
2087 rc = ImmSetCompositionStringA(hIMC, dwIndex, CompBuffer, comp_len,
2088 ReadBuffer, read_len);
2090 HeapFree(GetProcessHeap(), 0, CompBuffer);
2091 HeapFree(GetProcessHeap(), 0, ReadBuffer);
2096 /***********************************************************************
2097 * ImmSetCompositionWindow (IMM32.@)
2099 BOOL WINAPI ImmSetCompositionWindow(
2100 HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
2102 BOOL reshow = FALSE;
2103 InputContextData *data = (InputContextData*)hIMC;
2105 TRACE("(%p, %p)\n", hIMC, lpCompForm);
2106 TRACE("\t%x, (%i,%i), (%i,%i - %i,%i)\n",lpCompForm->dwStyle,
2107 lpCompForm->ptCurrentPos.x, lpCompForm->ptCurrentPos.y, lpCompForm->rcArea.top,
2108 lpCompForm->rcArea.left, lpCompForm->rcArea.bottom, lpCompForm->rcArea.right);
2113 data->IMC.cfCompForm = *lpCompForm;
2115 if (IsWindowVisible(IMM_GetThreadData()->hwndDefault))
2118 ShowWindow(IMM_GetThreadData()->hwndDefault,SW_HIDE);
2121 /* FIXME: this is a partial stub */
2124 ShowWindow(IMM_GetThreadData()->hwndDefault,SW_SHOWNOACTIVATE);
2126 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0);
2130 /***********************************************************************
2131 * ImmSetConversionStatus (IMM32.@)
2133 BOOL WINAPI ImmSetConversionStatus(
2134 HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
2136 DWORD oldConversion, oldSentence;
2137 InputContextData *data = (InputContextData*)hIMC;
2139 TRACE("%p %d %d\n", hIMC, fdwConversion, fdwSentence);
2144 if ( fdwConversion != data->IMC.fdwConversion )
2146 oldConversion = data->IMC.fdwConversion;
2147 data->IMC.fdwConversion = fdwConversion;
2148 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, oldConversion, IMC_SETCONVERSIONMODE);
2149 ImmInternalSendIMENotify(data, IMN_SETCONVERSIONMODE, 0);
2151 if ( fdwSentence != data->IMC.fdwSentence )
2153 oldSentence = data->IMC.fdwSentence;
2154 data->IMC.fdwSentence = fdwSentence;
2155 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, oldSentence, IMC_SETSENTENCEMODE);
2156 ImmInternalSendIMENotify(data, IMN_SETSENTENCEMODE, 0);
2162 /***********************************************************************
2163 * ImmSetOpenStatus (IMM32.@)
2165 BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
2167 InputContextData *data = (InputContextData*)hIMC;
2169 TRACE("%p %d\n", hIMC, fOpen);
2174 if (data->imeWnd == NULL)
2176 /* create the ime window */
2177 data->imeWnd = CreateWindowExW( WS_EX_TOOLWINDOW,
2178 data->immKbd->imeClassName, NULL, WS_POPUP, 0, 0, 1, 1, 0,
2179 0, data->immKbd->hIME, 0);
2180 SetWindowLongW(data->imeWnd, IMMGWL_IMC, (LONG)data);
2181 IMM_GetThreadData()->hwndDefault = data->imeWnd;
2184 if (!fOpen != !data->IMC.fOpen)
2186 data->IMC.fOpen = fOpen;
2187 ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS);
2188 ImmInternalSendIMENotify(data, IMN_SETOPENSTATUS, 0);
2194 /***********************************************************************
2195 * ImmSetStatusWindowPos (IMM32.@)
2197 BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
2199 InputContextData *data = (InputContextData*)hIMC;
2201 TRACE("(%p, %p)\n", hIMC, lpptPos);
2203 if (!data || !lpptPos)
2206 TRACE("\t(%i,%i)\n", lpptPos->x, lpptPos->y);
2208 data->IMC.ptStatusWndPos = *lpptPos;
2209 ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETSTATUSWINDOWPOS);
2210 ImmInternalSendIMENotify(data, IMN_SETSTATUSWINDOWPOS, 0);
2215 /***********************************************************************
2216 * ImmCreateSoftKeyboard(IMM32.@)
2218 HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y)
2220 FIXME("(%d, %d, %d, %d): stub\n", uType, hOwner, x, y);
2221 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2225 /***********************************************************************
2226 * ImmDestroySoftKeyboard(IMM32.@)
2228 BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
2230 FIXME("(%p): stub\n", hSoftWnd);
2231 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2235 /***********************************************************************
2236 * ImmShowSoftKeyboard(IMM32.@)
2238 BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
2240 FIXME("(%p, %d): stub\n", hSoftWnd, nCmdShow);
2241 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2245 /***********************************************************************
2246 * ImmSimulateHotKey (IMM32.@)
2248 BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
2250 FIXME("(%p, %d): stub\n", hWnd, dwHotKeyID);
2251 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2255 /***********************************************************************
2256 * ImmUnregisterWordA (IMM32.@)
2258 BOOL WINAPI ImmUnregisterWordA(
2259 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
2261 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
2262 TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_a(lpszReading), dwStyle,
2263 debugstr_a(lpszUnregister));
2264 if (immHkl->hIME && immHkl->pImeUnregisterWord)
2266 if (!is_kbd_ime_unicode(immHkl))
2267 return immHkl->pImeUnregisterWord((LPCWSTR)lpszReading,dwStyle,
2268 (LPCWSTR)lpszUnregister);
2271 LPWSTR lpszwReading = strdupAtoW(lpszReading);
2272 LPWSTR lpszwUnregister = strdupAtoW(lpszUnregister);
2275 rc = immHkl->pImeUnregisterWord(lpszwReading,dwStyle,lpszwUnregister);
2276 HeapFree(GetProcessHeap(),0,lpszwReading);
2277 HeapFree(GetProcessHeap(),0,lpszwUnregister);
2285 /***********************************************************************
2286 * ImmUnregisterWordW (IMM32.@)
2288 BOOL WINAPI ImmUnregisterWordW(
2289 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
2291 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
2292 TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_w(lpszReading), dwStyle,
2293 debugstr_w(lpszUnregister));
2294 if (immHkl->hIME && immHkl->pImeUnregisterWord)
2296 if (is_kbd_ime_unicode(immHkl))
2297 return immHkl->pImeUnregisterWord(lpszReading,dwStyle,lpszUnregister);
2300 LPSTR lpszaReading = strdupWtoA(lpszReading);
2301 LPSTR lpszaUnregister = strdupWtoA(lpszUnregister);
2304 rc = immHkl->pImeUnregisterWord((LPCWSTR)lpszaReading,dwStyle,
2305 (LPCWSTR)lpszaUnregister);
2306 HeapFree(GetProcessHeap(),0,lpszaReading);
2307 HeapFree(GetProcessHeap(),0,lpszaUnregister);
2315 /***********************************************************************
2316 * ImmGetImeMenuItemsA (IMM32.@)
2318 DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType,
2319 LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
2322 InputContextData *data = (InputContextData*)hIMC;
2323 TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
2324 lpImeParentMenu, lpImeMenu, dwSize);
2325 if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
2327 if (!is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
2328 return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
2329 (IMEMENUITEMINFOW*)lpImeParentMenu,
2330 (IMEMENUITEMINFOW*)lpImeMenu, dwSize);
2333 IMEMENUITEMINFOW lpImeParentMenuW;
2334 IMEMENUITEMINFOW *lpImeMenuW, *parent = NULL;
2337 if (lpImeParentMenu)
2338 parent = &lpImeParentMenuW;
2341 int count = dwSize / sizeof(LPIMEMENUITEMINFOA);
2342 dwSize = count * sizeof(IMEMENUITEMINFOW);
2343 lpImeMenuW = HeapAlloc(GetProcessHeap(), 0, dwSize);
2348 rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
2349 parent, lpImeMenuW, dwSize);
2351 if (lpImeParentMenu)
2353 memcpy(lpImeParentMenu,&lpImeParentMenuW,sizeof(IMEMENUITEMINFOA));
2354 lpImeParentMenu->hbmpItem = lpImeParentMenuW.hbmpItem;
2355 WideCharToMultiByte(CP_ACP, 0, lpImeParentMenuW.szString,
2356 -1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE,
2359 if (lpImeMenu && rc)
2362 for (i = 0; i < rc; i++)
2364 memcpy(&lpImeMenu[i],&lpImeMenuW[1],sizeof(IMEMENUITEMINFOA));
2365 lpImeMenu[i].hbmpItem = lpImeMenuW[i].hbmpItem;
2366 WideCharToMultiByte(CP_ACP, 0, lpImeMenuW[i].szString,
2367 -1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE,
2371 HeapFree(GetProcessHeap(),0,lpImeMenuW);
2379 /***********************************************************************
2380 * ImmGetImeMenuItemsW (IMM32.@)
2382 DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType,
2383 LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
2386 InputContextData *data = (InputContextData*)hIMC;
2387 TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
2388 lpImeParentMenu, lpImeMenu, dwSize);
2389 if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
2391 if (is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
2392 return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
2393 lpImeParentMenu, lpImeMenu, dwSize);
2396 IMEMENUITEMINFOA lpImeParentMenuA;
2397 IMEMENUITEMINFOA *lpImeMenuA, *parent = NULL;
2400 if (lpImeParentMenu)
2401 parent = &lpImeParentMenuA;
2404 int count = dwSize / sizeof(LPIMEMENUITEMINFOW);
2405 dwSize = count * sizeof(IMEMENUITEMINFOA);
2406 lpImeMenuA = HeapAlloc(GetProcessHeap(), 0, dwSize);
2411 rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
2412 (IMEMENUITEMINFOW*)parent,
2413 (IMEMENUITEMINFOW*)lpImeMenuA, dwSize);
2415 if (lpImeParentMenu)
2417 memcpy(lpImeParentMenu,&lpImeParentMenuA,sizeof(IMEMENUITEMINFOA));
2418 lpImeParentMenu->hbmpItem = lpImeParentMenuA.hbmpItem;
2419 MultiByteToWideChar(CP_ACP, 0, lpImeParentMenuA.szString,
2420 -1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE);
2422 if (lpImeMenu && rc)
2425 for (i = 0; i < rc; i++)
2427 memcpy(&lpImeMenu[i],&lpImeMenuA[1],sizeof(IMEMENUITEMINFOA));
2428 lpImeMenu[i].hbmpItem = lpImeMenuA[i].hbmpItem;
2429 MultiByteToWideChar(CP_ACP, 0, lpImeMenuA[i].szString,
2430 -1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE);
2433 HeapFree(GetProcessHeap(),0,lpImeMenuA);
2441 /***********************************************************************
2442 * ImmLockIMC(IMM32.@)
2444 LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
2446 InputContextData *data = (InputContextData*)hIMC;
2454 /***********************************************************************
2455 * ImmUnlockIMC(IMM32.@)
2457 BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
2459 InputContextData *data = (InputContextData*)hIMC;
2461 return (data->dwLock!=0);
2464 /***********************************************************************
2465 * ImmGetIMCLockCount(IMM32.@)
2467 DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
2469 InputContextData *data = (InputContextData*)hIMC;
2470 return data->dwLock;
2473 /***********************************************************************
2474 * ImmCreateIMCC(IMM32.@)
2476 HIMCC WINAPI ImmCreateIMCC(DWORD size)
2478 IMCCInternal *internal;
2479 int real_size = size + sizeof(IMCCInternal);
2481 internal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, real_size);
2482 if (internal == NULL)
2485 internal->dwSize = size;
2486 return (HIMCC)internal;
2489 /***********************************************************************
2490 * ImmDestroyIMCC(IMM32.@)
2492 HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
2494 HeapFree(GetProcessHeap(),0,block);
2498 /***********************************************************************
2499 * ImmLockIMCC(IMM32.@)
2501 LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
2503 IMCCInternal *internal;
2504 internal = (IMCCInternal*) imcc;
2506 internal->dwLock ++;
2507 return internal + 1;
2510 /***********************************************************************
2511 * ImmUnlockIMCC(IMM32.@)
2513 BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
2515 IMCCInternal *internal;
2516 internal = (IMCCInternal*) imcc;
2518 internal->dwLock --;
2519 return (internal->dwLock!=0);
2522 /***********************************************************************
2523 * ImmGetIMCCLockCount(IMM32.@)
2525 DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
2527 IMCCInternal *internal;
2528 internal = (IMCCInternal*) imcc;
2530 return internal->dwLock;
2533 /***********************************************************************
2534 * ImmReSizeIMCC(IMM32.@)
2536 HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
2538 IMCCInternal *internal,*newone;
2539 int real_size = size + sizeof(IMCCInternal);
2541 internal = (IMCCInternal*) imcc;
2543 newone = HeapReAlloc(GetProcessHeap(), 0, internal, real_size);
2544 newone->dwSize = size;
2549 /***********************************************************************
2550 * ImmGetIMCCSize(IMM32.@)
2552 DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
2554 IMCCInternal *internal;
2555 internal = (IMCCInternal*) imcc;
2557 return internal->dwSize;
2560 /***********************************************************************
2561 * ImmGenerateMessage(IMM32.@)
2563 BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
2565 InputContextData *data = (InputContextData*)hIMC;
2567 TRACE("%i messages queued\n",data->IMC.dwNumMsgBuf);
2568 if (data->IMC.dwNumMsgBuf > 0)
2570 LPTRANSMSG lpTransMsg;
2573 lpTransMsg = (LPTRANSMSG)ImmLockIMCC(data->IMC.hMsgBuf);
2574 for (i = 0; i < data->IMC.dwNumMsgBuf; i++)
2575 ImmInternalPostIMEMessage(data, lpTransMsg[i].message, lpTransMsg[i].wParam, lpTransMsg[i].lParam);
2577 ImmUnlockIMCC(data->IMC.hMsgBuf);
2579 data->IMC.dwNumMsgBuf = 0;
2585 /***********************************************************************
2586 * ImmTranslateMessage(IMM32.@)
2587 * ( Undocumented, call internally and from user32.dll )
2589 BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyData)
2591 InputContextData *data;
2592 HIMC imc = ImmGetContext(hwnd);
2598 static const int list_count = 10;
2600 TRACE("%p %x %x %x\n",hwnd, msg, (UINT)wParam, (UINT)lKeyData);
2603 data = (InputContextData*)imc;
2607 if (!data->immKbd->hIME || !data->immKbd->pImeToAsciiEx)
2610 GetKeyboardState(state);
2611 scancode = lKeyData >> 0x10 & 0xff;
2613 list = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, list_count * sizeof(TRANSMSG) + sizeof(DWORD));
2614 ((DWORD*)list)[0] = list_count;
2616 if (data->immKbd->imeInfo.fdwProperty & IME_PROP_KBD_CHAR_FIRST)
2620 if (!is_himc_ime_unicode(data))
2621 ToAscii(data->lastVK, scancode, state, &chr, 0);
2623 ToUnicodeEx(data->lastVK, scancode, state, &chr, 1, 0, GetKeyboardLayout(0));
2624 uVirtKey = MAKELONG(data->lastVK,chr);
2627 uVirtKey = data->lastVK;
2629 msg_count = data->immKbd->pImeToAsciiEx(uVirtKey, scancode, state, list, 0, imc);
2630 TRACE("%i messages generated\n",msg_count);
2631 if (msg_count && msg_count <= list_count)
2634 LPTRANSMSG msgs = (LPTRANSMSG)((LPBYTE)list + sizeof(DWORD));
2636 for (i = 0; i < msg_count; i++)
2637 ImmInternalPostIMEMessage(data, msgs[i].message, msgs[i].wParam, msgs[i].lParam);
2639 else if (msg_count > list_count)
2640 ImmGenerateMessage(imc);
2642 HeapFree(GetProcessHeap(),0,list);
2644 data->lastVK = VK_PROCESSKEY;
2646 return (msg_count > 0);
2649 /***********************************************************************
2650 * ImmProcessKey(IMM32.@)
2651 * ( Undocumented, called from user32.dll )
2653 BOOL WINAPI ImmProcessKey(HWND hwnd, HKL hKL, UINT vKey, LPARAM lKeyData, DWORD unknown)
2655 InputContextData *data;
2656 HIMC imc = ImmGetContext(hwnd);
2659 TRACE("%p %p %x %x %x\n",hwnd, hKL, vKey, (UINT)lKeyData, unknown);
2662 data = (InputContextData*)imc;
2666 if (!data->immKbd->hIME || !data->immKbd->pImeProcessKey)
2669 GetKeyboardState(state);
2670 if (data->immKbd->pImeProcessKey(imc, vKey, lKeyData, state))
2672 data->lastVK = vKey;
2676 data->lastVK = VK_PROCESSKEY;