mshtml: Added IHTMLWindow2::clearInterval implementation.
[wine/hacks.git] / dlls / imm32 / imm.c
blob94b775201f7ce2182bf392c1b3b12f95d1e439e8
1 /*
2 * IMM32 library
4 * Copyright 1998 Patrik Stridvall
5 * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <stdio.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "winerror.h"
30 #include "wine/debug.h"
31 #include "imm.h"
32 #include "ddk/imm.h"
33 #include "winnls.h"
34 #include "winreg.h"
35 #include "wine/list.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(imm);
39 typedef struct tagIMCCInternal
41 DWORD dwLock;
42 DWORD dwSize;
43 } IMCCInternal;
45 #define MAKE_FUNCPTR(f) typeof(f) * p##f
46 typedef struct _tagImmHkl{
47 struct list entry;
48 HKL hkl;
49 HMODULE hIME;
50 IMEINFO imeInfo;
51 WCHAR imeClassName[17]; /* 16 character max */
52 ULONG uSelected;
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);
71 } ImmHkl;
72 #undef MAKE_FUNCPTR
74 typedef struct tagInputContextData
76 DWORD dwLock;
77 INPUTCONTEXT IMC;
79 ImmHkl *immKbd;
80 HWND imeWnd;
81 UINT lastVK;
82 } InputContextData;
84 typedef struct _tagTRANSMSG {
85 UINT message;
86 WPARAM wParam;
87 LPARAM lParam;
88 } TRANSMSG, *LPTRANSMSG;
90 typedef struct _tagIMMThreadData {
91 HIMC defaultContext;
92 HWND hwndDefault;
93 } IMMThreadData;
95 static DWORD tlsIndex = 0;
96 static struct list ImmHklList = LIST_INIT(ImmHklList);
98 /* MSIME messages */
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 )
116 WCHAR *ret = NULL;
117 if (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 );
123 return ret;
126 static inline CHAR *strdupWtoA( const WCHAR *str )
128 CHAR *ret = NULL;
129 if (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 );
135 return ret;
138 static DWORD convert_candidatelist_WtoA(
139 LPCANDIDATELIST lpSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen)
141 DWORD ret, i, len;
143 ret = FIELD_OFFSET( CANDIDATELIST, dwOffset[lpSrc->dwCount] );
144 if ( lpDst && dwBufLen > 0 )
146 *lpDst = *lpSrc;
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);
165 else
166 len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, NULL, 0, NULL, NULL);
168 ret += len * sizeof(char);
171 if ( lpDst )
172 lpDst->dwSize = ret;
174 return ret;
177 static DWORD convert_candidatelist_AtoW(
178 LPCANDIDATELIST lpSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen)
180 DWORD ret, i, len;
182 ret = FIELD_OFFSET( CANDIDATELIST, dwOffset[lpSrc->dwCount] );
183 if ( lpDst && dwBufLen > 0 )
185 *lpDst = *lpSrc;
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);
204 else
205 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1, NULL, 0);
207 ret += len * sizeof(WCHAR);
210 if ( lpDst )
211 lpDst->dwSize = ret;
213 return ret;
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;
242 HMODULE module = 0;
243 HKEY hkey;
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 );
253 RegCloseKey( hkey );
256 name = buffer;
257 while (name)
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;
264 name = next;
267 return module;
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)
274 ImmHkl *ptr;
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)
281 if (ptr->hkl == hkl)
282 return ptr;
284 /* not found... create it */
286 ptr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ImmHkl));
288 ptr->hkl = hkl;
289 if (ImmGetIMEFileNameW(hkl, filename, MAX_PATH)) ptr->hIME = LoadLibraryW(filename);
290 if (!ptr->hIME)
291 ptr->hIME = LoadDefaultWineIME();
292 if (ptr->hIME)
294 LOAD_FUNCPTR(ImeInquire);
295 if (!ptr->pImeInquire || !ptr->pImeInquire(&ptr->imeInfo, ptr->imeClassName, NULL))
297 FreeLibrary(ptr->hIME);
298 ptr->hIME = NULL;
300 else
302 LOAD_FUNCPTR(ImeDestroy);
303 LOAD_FUNCPTR(ImeSelect);
304 if (!ptr->pImeSelect || !ptr->pImeDestroy)
306 FreeLibrary(ptr->hIME);
307 ptr->hIME = NULL;
309 else
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))
327 WCHAR bufW[17];
328 MultiByteToWideChar(CP_ACP, 0, (LPSTR)ptr->imeClassName,
329 -1, bufW, 17);
330 lstrcpyW(ptr->imeClassName, bufW);
335 list_add_head(&ImmHklList,&ptr->entry);
337 return ptr;
339 #undef LOAD_FUNCPTR
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);
348 if (ptr->hIME)
350 ptr->pImeDestroy(1);
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);
371 switch (fdwReason)
373 case DLL_PROCESS_ATTACH:
374 IMM_RegisterMessages();
375 tlsIndex = TlsAlloc();
376 IMM_InitThreadData();
377 break;
378 case DLL_THREAD_ATTACH:
379 IMM_InitThreadData();
380 break;
381 case DLL_THREAD_DETACH:
382 IMM_FreeThreadData();
383 break;
384 case DLL_PROCESS_DETACH:
385 IMM_FreeThreadData();
386 IMM_FreeAllImmHkl();
387 TlsFree(tlsIndex);
388 break;
390 return TRUE;
393 /* for posting messages as the IME */
394 static void ImmInternalPostIMEMessage(InputContextData *data, UINT msg, WPARAM wParam, LPARAM lParam)
396 HWND target = GetFocus();
397 if (!target)
398 PostMessageW(data->IMC.hWnd,msg,wParam,lParam);
399 else
400 PostMessageW(target, msg, wParam, lParam);
403 static LRESULT ImmInternalSendIMENotify(InputContextData *data, WPARAM notify, LPARAM lParam)
405 HWND target;
407 target = data->IMC.hWnd;
408 if (!target) target = GetFocus();
410 if (target)
411 return SendMessageW(target, WM_IME_NOTIFY, notify, lParam);
413 return 0;
416 static HIMCC ImmCreateBlankCompStr(void)
418 HIMCC rc;
419 LPCOMPOSITIONSTRING ptr;
420 rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
421 ptr = (LPCOMPOSITIONSTRING)ImmLockIMCC(rc);
422 memset(ptr,0,sizeof(COMPOSITIONSTRING));
423 ptr->dwSize = sizeof(COMPOSITIONSTRING);
424 ImmUnlockIMCC(rc);
425 return rc;
428 /***********************************************************************
429 * ImmAssociateContext (IMM32.@)
431 HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
433 HIMC old = NULL;
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)
445 return hIMC;
447 if (hWnd)
449 old = (HIMC)RemovePropW(hWnd,szwWineIMCProperty);
451 if (old == NULL)
452 old = IMM_GetThreadData()->defaultContext;
453 else if (old == (HIMC)-1)
454 old = NULL;
456 if (hIMC != IMM_GetThreadData()->defaultContext)
458 if (hIMC == NULL) /* Meaning disable imm for that window*/
459 SetPropW(hWnd,szwWineIMCProperty,(HANDLE)-1);
460 else
461 SetPropW(hWnd,szwWineIMCProperty,(HANDLE)hIMC);
464 if (old)
466 InputContextData *old_data = (InputContextData*)old;
467 if (old_data->IMC.hWnd == hWnd)
468 old_data->IMC.hWnd = NULL;
472 if (!hIMC)
473 return old;
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);
493 return old;
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);
503 return FALSE;
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);
520 else
522 REGISTERWORDW rww;
523 REGISTERWORDA *rwa = (REGISTERWORDA*)lpData;
524 BOOL rc;
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);
531 return rc;
534 else
535 return FALSE;
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);
552 else
554 REGISTERWORDW *rww = (REGISTERWORDW*)lpData;
555 REGISTERWORDA rwa;
556 BOOL rc;
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);
563 return rc;
566 else
567 return FALSE;
570 /***********************************************************************
571 * ImmCreateContext (IMM32.@)
573 HIMC WINAPI ImmCreateContext(void)
575 InputContextData *new_context;
576 LPGUIDELINE gl;
577 LPCANDIDATEINFO ci;
579 new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
581 /* Load the IME */
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);
588 return 0;
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);
612 return 0;
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);
627 if (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);
644 return TRUE;
647 /***********************************************************************
648 * ImmDestroyContext (IMM32.@)
650 BOOL WINAPI ImmDestroyContext(HIMC hIMC)
652 if (hIMC != IMM_GetThreadData()->defaultContext)
653 return IMM_DestroyContext(hIMC);
654 else
655 return FALSE;
658 /***********************************************************************
659 * ImmDisableIME (IMM32.@)
661 BOOL WINAPI ImmDisableIME(DWORD idThread)
663 FIXME("(%d): stub\n", idThread);
664 return TRUE;
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);
683 else
685 LPWSTR lpszwReading = strdupAtoW(lpszReading);
686 LPWSTR lpszwRegister = strdupAtoW(lpszRegister);
687 BOOL rc;
689 rc = immHkl->pImeEnumRegisterWord((REGISTERWORDENUMPROCW)lpfnEnumProc,
690 lpszwReading, dwStyle, lpszwRegister,
691 lpData);
693 HeapFree(GetProcessHeap(),0,lpszwReading);
694 HeapFree(GetProcessHeap(),0,lpszwRegister);
695 return rc;
698 else
699 return 0;
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);
718 else
720 LPSTR lpszaReading = strdupWtoA(lpszReading);
721 LPSTR lpszaRegister = strdupWtoA(lpszRegister);
722 BOOL rc;
724 rc = immHkl->pImeEnumRegisterWord(lpfnEnumProc, (LPCWSTR)lpszaReading,
725 dwStyle, (LPCWSTR)lpszaRegister, lpData);
727 HeapFree(GetProcessHeap(),0,lpszaReading);
728 HeapFree(GetProcessHeap(),0,lpszaRegister);
729 return rc;
732 else
733 return 0;
736 /***********************************************************************
737 * ImmEscapeA (IMM32.@)
739 LRESULT WINAPI ImmEscapeA(
740 HKL hKL, HIMC hIMC,
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);
750 else
752 FIXME("A procedure called with W ime back end\n");
753 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
754 return 0;
757 else
758 return 0;
761 /***********************************************************************
762 * ImmEscapeW (IMM32.@)
764 LRESULT WINAPI ImmEscapeW(
765 HKL hKL, HIMC hIMC,
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);
775 else
777 FIXME("W procedure called with A ime back end\n");
778 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
779 return 0;
782 else
783 return 0;
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;
796 DWORD ret = 0;
798 TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
800 if (!data || !data->IMC.hCandInfo)
801 return 0;
803 candinfo = ImmLockIMCC(data->IMC.hCandInfo);
804 if ( dwIndex >= candinfo->dwCount ||
805 dwIndex >= (sizeof(candinfo->dwOffset) / sizeof(DWORD)) )
806 goto done;
808 candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + candinfo->dwOffset[dwIndex]);
809 if ( !candlist->dwSize || !candlist->dwCount )
810 goto done;
812 if ( !is_himc_ime_unicode(data) )
814 ret = candlist->dwSize;
815 if ( lpCandList && dwBufLen >= ret )
816 memcpy(lpCandList, candlist, ret);
818 else
819 ret = convert_candidatelist_WtoA( candlist, lpCandList, dwBufLen);
821 done:
822 ImmUnlockIMCC(data->IMC.hCandInfo);
823 return ret;
826 /***********************************************************************
827 * ImmGetCandidateListCountA (IMM32.@)
829 DWORD WINAPI ImmGetCandidateListCountA(
830 HIMC hIMC, LPDWORD lpdwListCount)
832 InputContextData *data = (InputContextData *)hIMC;
833 LPCANDIDATEINFO candinfo;
834 DWORD ret, count;
836 TRACE("%p, %p\n", hIMC, lpdwListCount);
838 if (!data || !lpdwListCount || !data->IMC.hCandInfo)
839 return 0;
841 candinfo = ImmLockIMCC(data->IMC.hCandInfo);
843 *lpdwListCount = count = candinfo->dwCount;
845 if ( !is_himc_ime_unicode(data) )
846 ret = candinfo->dwSize;
847 else
849 ret = sizeof(CANDIDATEINFO);
850 while ( count-- )
851 ret += ImmGetCandidateListA(hIMC, count, NULL, 0);
854 ImmUnlockIMCC(data->IMC.hCandInfo);
855 return ret;
858 /***********************************************************************
859 * ImmGetCandidateListCountW (IMM32.@)
861 DWORD WINAPI ImmGetCandidateListCountW(
862 HIMC hIMC, LPDWORD lpdwListCount)
864 InputContextData *data = (InputContextData *)hIMC;
865 LPCANDIDATEINFO candinfo;
866 DWORD ret, count;
868 TRACE("%p, %p\n", hIMC, lpdwListCount);
870 if (!data || !lpdwListCount || !data->IMC.hCandInfo)
871 return 0;
873 candinfo = ImmLockIMCC(data->IMC.hCandInfo);
875 *lpdwListCount = count = candinfo->dwCount;
877 if ( is_himc_ime_unicode(data) )
878 ret = candinfo->dwSize;
879 else
881 ret = sizeof(CANDIDATEINFO);
882 while ( count-- )
883 ret += ImmGetCandidateListW(hIMC, count, NULL, 0);
886 ImmUnlockIMCC(data->IMC.hCandInfo);
887 return ret;
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;
900 DWORD ret = 0;
902 TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
904 if (!data || !data->IMC.hCandInfo)
905 return 0;
907 candinfo = ImmLockIMCC(data->IMC.hCandInfo);
908 if ( dwIndex >= candinfo->dwCount ||
909 dwIndex >= (sizeof(candinfo->dwOffset) / sizeof(DWORD)) )
910 goto done;
912 candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + candinfo->dwOffset[dwIndex]);
913 if ( !candlist->dwSize || !candlist->dwCount )
914 goto done;
916 if ( is_himc_ime_unicode(data) )
918 ret = candlist->dwSize;
919 if ( lpCandList && dwBufLen >= ret )
920 memcpy(lpCandList, candlist, ret);
922 else
923 ret = convert_candidatelist_AtoW( candlist, lpCandList, dwBufLen);
925 done:
926 ImmUnlockIMCC(data->IMC.hCandInfo);
927 return ret;
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)
941 return FALSE;
943 if ( dwIndex >= (sizeof(data->IMC.cfCandForm) / sizeof(CANDIDATEFORM)) )
944 return FALSE;
946 *lpCandidate = data->IMC.cfCandForm[dwIndex];
948 return TRUE;
951 /***********************************************************************
952 * ImmGetCompositionFontA (IMM32.@)
954 BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
956 LOGFONTW lfW;
957 BOOL rc;
959 TRACE("(%p, %p):\n", hIMC, lplf);
961 rc = ImmGetCompositionFontW(hIMC,&lfW);
962 if (!rc || !lplf)
963 return FALSE;
965 memcpy(lplf,&lfW,sizeof(LOGFONTA));
966 WideCharToMultiByte(CP_ACP, 0, lfW.lfFaceName, -1, lplf->lfFaceName,
967 LF_FACESIZE, NULL, NULL);
968 return TRUE;
971 /***********************************************************************
972 * ImmGetCompositionFontW (IMM32.@)
974 BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
976 InputContextData *data = (InputContextData*)hIMC;
978 TRACE("(%p, %p):\n", hIMC, lplf);
980 if (!data || !lplf)
981 return FALSE;
983 *lplf = data->IMC.lfFont.W;
985 return TRUE;
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;
996 CHAR *buf = NULL;
997 LONG rc = 0;
998 InputContextData *data = (InputContextData*)hIMC;
999 LPCOMPOSITIONSTRING compstr;
1000 LPBYTE compdata;
1002 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
1004 if (!data)
1005 return FALSE;
1007 if (!data->IMC.hCompStr)
1008 return FALSE;
1010 compdata = ImmLockIMCC(data->IMC.hCompStr);
1011 compstr = (LPCOMPOSITIONSTRING)compdata;
1013 switch (dwIndex)
1015 case GCS_RESULTSTR:
1016 if (compstr->dwResultStrLen > 0 && compstr->dwResultStrOffset > 0)
1018 isString = TRUE;
1019 buffer = compdata + compstr->dwResultStrOffset;
1020 rc = compstr->dwResultStrLen;
1021 TRACE("GCS_RESULTSTR %p %i\n", buffer, rc);
1023 break;
1024 case GCS_COMPSTR:
1025 if (compstr->dwCompStrLen > 0 && compstr->dwCompStrOffset > 0)
1027 isString = TRUE;
1028 buffer = compdata + compstr->dwCompStrOffset;
1029 rc = compstr->dwCompStrLen;
1030 TRACE("GCS_COMPSTR %p %i\n", buffer, rc);
1032 break;
1033 case GCS_COMPATTR:
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);
1040 break;
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);
1048 break;
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);
1056 break;
1057 case GCS_RESULTREADSTR:
1058 if (compstr->dwResultReadStrLen > 0 && compstr->dwResultReadStrOffset > 0)
1060 isString = TRUE;
1061 buffer = compdata + compstr->dwResultReadStrOffset;
1062 rc = compstr->dwResultReadStrLen;
1063 TRACE("GCS_RESULTREADSTR %p %i\n",buffer, rc);
1065 break;
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);
1073 break;
1074 case GCS_COMPREADSTR:
1075 if (compstr->dwCompReadStrLen > 0 && compstr->dwCompReadStrOffset > 0)
1077 isString = TRUE;
1078 buffer = compdata + compstr->dwCompReadStrOffset;
1079 rc = compstr->dwCompReadStrLen;
1080 TRACE("GCS_COMPREADSTR %p %i\n", buffer, rc);
1082 break;
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);
1090 break;
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);
1098 break;
1099 case GCS_CURSORPOS:
1100 TRACE("GCS_CURSORPOS\n");
1101 rc = compstr->dwCursorPos;
1102 break;
1103 case GCS_DELTASTART:
1104 TRACE("GCS_DELTASTART\n");
1105 rc = compstr->dwDeltaStart;
1106 break;
1107 default:
1108 FIXME("Unhandled index 0x%x\n",dwIndex);
1109 break;
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 );
1116 if ( buf )
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);
1127 return rc;
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;
1139 WCHAR *buf = NULL;
1140 LONG rc = 0;
1141 InputContextData *data = (InputContextData*)hIMC;
1142 LPCOMPOSITIONSTRING compstr;
1143 LPBYTE compdata;
1145 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
1147 if (!data)
1148 return FALSE;
1150 if (!data->IMC.hCompStr)
1151 return FALSE;
1153 compdata = ImmLockIMCC(data->IMC.hCompStr);
1154 compstr = (LPCOMPOSITIONSTRING)compdata;
1156 switch (dwIndex)
1158 case GCS_RESULTSTR:
1159 if (compstr->dwResultStrLen > 0 && compstr->dwResultStrOffset > 0)
1161 isString = TRUE;
1162 buffer = compdata + compstr->dwResultStrOffset;
1163 rc = compstr->dwResultStrLen;
1164 TRACE("GCS_RESULTSTR %p %i\n", buffer, rc);
1166 break;
1167 case GCS_RESULTREADSTR:
1168 if (compstr->dwResultReadStrLen > 0 && compstr->dwResultReadStrOffset > 0)
1170 isString = TRUE;
1171 buffer = compdata + compstr->dwResultReadStrOffset;
1172 rc = compstr->dwResultReadStrLen;
1173 TRACE("GCS_RESULTREADSTR %p %i\n",buffer, rc);
1175 break;
1176 case GCS_COMPSTR:
1177 if (compstr->dwCompStrLen > 0 && compstr->dwCompStrOffset > 0)
1179 isString = TRUE;
1180 buffer = compdata + compstr->dwCompStrOffset;
1181 rc = compstr->dwCompStrLen;
1182 TRACE("GCS_COMPSTR %p %i\n", buffer, rc);
1184 break;
1185 case GCS_COMPATTR:
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);
1192 break;
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);
1200 break;
1201 case GCS_COMPREADSTR:
1202 if (compstr->dwCompReadStrLen > 0 && compstr->dwCompReadStrOffset > 0)
1204 isString = TRUE;
1205 buffer = compdata + compstr->dwCompReadStrOffset;
1206 rc = compstr->dwCompReadStrLen;
1207 TRACE("GCS_COMPREADSTR %p %i\n", buffer, rc);
1209 break;
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);
1217 break;
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);
1225 break;
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);
1233 break;
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);
1241 break;
1242 case GCS_CURSORPOS:
1243 TRACE("GCS_CURSORPOS\n");
1244 rc = compstr->dwCursorPos;
1245 break;
1246 case GCS_DELTASTART:
1247 TRACE("GCS_DELTASTART\n");
1248 rc = compstr->dwDeltaStart;
1249 break;
1250 default:
1251 FIXME("Unhandled index 0x%x\n",dwIndex);
1252 break;
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) );
1261 if ( buf )
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);
1274 return rc;
1277 /***********************************************************************
1278 * ImmGetCompositionWindow (IMM32.@)
1280 BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
1282 InputContextData *data = (InputContextData*)hIMC;
1284 TRACE("(%p, %p)\n", hIMC, lpCompForm);
1286 if (!data)
1287 return FALSE;
1289 *lpCompForm = data->IMC.cfCompForm;
1290 return 1;
1293 /***********************************************************************
1294 * ImmGetContext (IMM32.@)
1297 HIMC WINAPI ImmGetContext(HWND hWnd)
1299 HIMC rc = NULL;
1301 TRACE("%p\n", hWnd);
1302 if (!IMM_GetThreadData()->defaultContext)
1303 IMM_GetThreadData()->defaultContext = ImmCreateContext();
1305 rc = (HIMC)GetPropW(hWnd,szwWineIMCProperty);
1306 if (rc == (HIMC)-1)
1307 rc = NULL;
1308 else if (rc == NULL)
1309 rc = IMM_GetThreadData()->defaultContext;
1311 if (rc)
1313 InputContextData *data = (InputContextData*)rc;
1314 data->IMC.hWnd = hWnd;
1316 TRACE("returning %p\n", rc);
1318 return rc;
1321 /***********************************************************************
1322 * ImmGetConversionListA (IMM32.@)
1324 DWORD WINAPI ImmGetConversionListA(
1325 HKL hKL, HIMC hIMC,
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,
1331 dwBufLen, uFlag);
1332 if (immHkl->hIME && immHkl->pImeConversionList)
1334 if (!is_kbd_ime_unicode(immHkl))
1335 return immHkl->pImeConversionList(hIMC,(LPCWSTR)pSrc,lpDst,dwBufLen,uFlag);
1336 else
1338 LPCANDIDATELIST lpwDst;
1339 DWORD ret = 0, len;
1340 LPWSTR pwSrc = strdupAtoW(pSrc);
1342 len = immHkl->pImeConversionList(hIMC, pwSrc, NULL, 0, uFlag);
1343 lpwDst = HeapAlloc(GetProcessHeap(), 0, len);
1344 if ( lpwDst )
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);
1352 return ret;
1355 else
1356 return 0;
1359 /***********************************************************************
1360 * ImmGetConversionListW (IMM32.@)
1362 DWORD WINAPI ImmGetConversionListW(
1363 HKL hKL, HIMC hIMC,
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,
1369 dwBufLen, uFlag);
1370 if (immHkl->hIME && immHkl->pImeConversionList)
1372 if (is_kbd_ime_unicode(immHkl))
1373 return immHkl->pImeConversionList(hIMC,pSrc,lpDst,dwBufLen,uFlag);
1374 else
1376 LPCANDIDATELIST lpaDst;
1377 DWORD ret = 0, len;
1378 LPSTR paSrc = strdupWtoA(pSrc);
1380 len = immHkl->pImeConversionList(hIMC, (LPCWSTR)paSrc, NULL, 0, uFlag);
1381 lpaDst = HeapAlloc(GetProcessHeap(), 0, len);
1382 if ( lpaDst )
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);
1390 return ret;
1393 else
1394 return 0;
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);
1407 if (!data)
1408 return FALSE;
1410 if (lpfdwConversion)
1411 *lpfdwConversion = data->IMC.fdwConversion;
1412 if (lpfdwSentence)
1413 *lpfdwSentence = data->IMC.fdwSentence;
1415 return TRUE;
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)
1433 WCHAR *buf;
1434 DWORD len;
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) );
1443 if( !buf )
1444 return 0;
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 );
1455 return len;
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);
1482 return 0;
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);
1494 return 0;
1497 /***********************************************************************
1498 * ImmGetIMEFileNameA (IMM32.@)
1500 UINT WINAPI ImmGetIMEFileNameA( HKL hKL, LPSTR lpszFileName, UINT uBufLen)
1502 LPWSTR bufW = NULL;
1503 UINT wBufLen = uBufLen;
1504 UINT rc;
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));
1511 wBufLen = MAX_PATH;
1514 rc = ImmGetIMEFileNameW(hKL,bufW,wBufLen);
1516 if (rc > 0)
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,
1523 NULL);
1526 HeapFree(GetProcessHeap(),0,bufW);
1527 return rc;
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};
1538 HKEY hkey;
1539 DWORD length;
1540 DWORD rc;
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)
1547 SetLastError(rc);
1548 return 0;
1551 length = 0;
1552 rc = RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, NULL, &length);
1554 if (rc != ERROR_SUCCESS)
1556 RegCloseKey(hkey);
1557 SetLastError(rc);
1558 return 0;
1560 if (length > uBufLen * sizeof(WCHAR) || !lpszFileName)
1562 RegCloseKey(hkey);
1563 if (lpszFileName)
1565 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1566 return 0;
1568 else
1569 return length / sizeof(WCHAR);
1572 RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, lpszFileName, &length);
1574 RegCloseKey(hkey);
1576 return length / sizeof(WCHAR);
1579 /***********************************************************************
1580 * ImmGetOpenStatus (IMM32.@)
1582 BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
1584 InputContextData *data = (InputContextData*)hIMC;
1586 if (!data)
1587 return FALSE;
1588 FIXME("(%p): semi-stub\n", hIMC);
1590 return data->IMC.fOpen;
1593 /***********************************************************************
1594 * ImmGetProperty (IMM32.@)
1596 DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
1598 DWORD rc = 0;
1599 ImmHkl *kbd;
1601 TRACE("(%p, %d)\n", hKL, fdwIndex);
1602 kbd = IMM_GetImmHkl(hKL);
1604 if (kbd && kbd->hIME)
1606 switch (fdwIndex)
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;
1615 default: rc = 0;
1618 return rc;
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);
1633 else
1635 STYLEBUFW sbw;
1636 UINT rc;
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;
1642 return rc;
1645 else
1646 return 0;
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);
1661 else
1663 STYLEBUFA sba;
1664 UINT rc;
1666 rc = immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)&sba);
1667 MultiByteToWideChar(CP_ACP, 0, sba.szDescription, -1,
1668 lpStyleBuf->szDescription, 32);
1669 lpStyleBuf->dwStyle = sba.dwStyle;
1670 return rc;
1673 else
1674 return 0;
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)
1687 return FALSE;
1689 *lpptPos = data->IMC.ptStatusWndPos;
1691 return TRUE;
1694 /***********************************************************************
1695 * ImmGetVirtualKey (IMM32.@)
1697 UINT WINAPI ImmGetVirtualKey(HWND hWnd)
1699 OSVERSIONINFOA version;
1700 InputContextData *data = (InputContextData *)ImmGetContext( hWnd );
1701 TRACE("%p\n", hWnd);
1703 if ( data )
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:
1712 return 0;
1713 default:
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);
1729 return NULL;
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);
1742 return NULL;
1745 /***********************************************************************
1746 * ImmIsIME (IMM32.@)
1748 BOOL WINAPI ImmIsIME(HKL hKL)
1750 ImmHkl *ptr;
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)
1762 BOOL rc = FALSE;
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);
1782 rc = TRUE;
1784 return rc;
1787 /***********************************************************************
1788 * ImmIsUIMessageW (IMM32.@)
1790 BOOL WINAPI ImmIsUIMessageW(
1791 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1793 BOOL rc = FALSE;
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))
1804 rc = TRUE;
1805 return rc;
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)
1820 return FALSE;
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);
1839 else
1841 LPWSTR lpszwReading = strdupAtoW(lpszReading);
1842 LPWSTR lpszwRegister = strdupAtoW(lpszRegister);
1843 BOOL rc;
1845 rc = immHkl->pImeRegisterWord(lpszwReading,dwStyle,lpszwRegister);
1846 HeapFree(GetProcessHeap(),0,lpszwReading);
1847 HeapFree(GetProcessHeap(),0,lpszwRegister);
1848 return rc;
1851 else
1852 return FALSE;
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);
1868 else
1870 LPSTR lpszaReading = strdupWtoA(lpszReading);
1871 LPSTR lpszaRegister = strdupWtoA(lpszRegister);
1872 BOOL rc;
1874 rc = immHkl->pImeRegisterWord((LPCWSTR)lpszaReading,dwStyle,
1875 (LPCWSTR)lpszaRegister);
1876 HeapFree(GetProcessHeap(),0,lpszaReading);
1877 HeapFree(GetProcessHeap(),0,lpszaRegister);
1878 return rc;
1881 else
1882 return FALSE;
1885 /***********************************************************************
1886 * ImmReleaseContext (IMM32.@)
1888 BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1890 static int shown = 0;
1892 if (!shown) {
1893 FIXME("(%p, %p): stub\n", hWnd, hIMC);
1894 shown = 1;
1896 return TRUE;
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);
1911 return 0;
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);
1926 return 0;
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)
1940 return FALSE;
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)) )
1949 return FALSE;
1951 data->IMC.cfCandForm[lpCandidate->dwIndex] = *lpCandidate;
1952 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS);
1953 ImmInternalSendIMENotify(data, IMN_SETCANDIDATEPOS, 1 << lpCandidate->dwIndex);
1955 return TRUE;
1958 /***********************************************************************
1959 * ImmSetCompositionFontA (IMM32.@)
1961 BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
1963 InputContextData *data = (InputContextData*)hIMC;
1964 TRACE("(%p, %p)\n", hIMC, lplf);
1966 if (!data || !lplf)
1967 return FALSE;
1969 memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
1970 MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
1971 LF_FACESIZE);
1972 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
1973 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
1975 return TRUE;
1978 /***********************************************************************
1979 * ImmSetCompositionFontW (IMM32.@)
1981 BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
1983 InputContextData *data = (InputContextData*)hIMC;
1984 TRACE("(%p, %p)\n", hIMC, lplf);
1986 if (!data || !lplf)
1987 return FALSE;
1989 data->IMC.lfFont.W = *lplf;
1990 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
1991 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
1993 return TRUE;
1996 /***********************************************************************
1997 * ImmSetCompositionStringA (IMM32.@)
1999 BOOL WINAPI ImmSetCompositionStringA(
2000 HIMC hIMC, DWORD dwIndex,
2001 LPCVOID lpComp, DWORD dwCompLen,
2002 LPCVOID lpRead, DWORD dwReadLen)
2004 DWORD comp_len;
2005 DWORD read_len;
2006 WCHAR *CompBuffer = NULL;
2007 WCHAR *ReadBuffer = NULL;
2008 BOOL rc;
2009 InputContextData *data = (InputContextData*)hIMC;
2011 TRACE("(%p, %d, %p, %d, %p, %d):\n",
2012 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
2014 if (!data)
2015 return FALSE;
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);
2022 if (comp_len)
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);
2029 if (read_len)
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);
2041 return rc;
2044 /***********************************************************************
2045 * ImmSetCompositionStringW (IMM32.@)
2047 BOOL WINAPI ImmSetCompositionStringW(
2048 HIMC hIMC, DWORD dwIndex,
2049 LPCVOID lpComp, DWORD dwCompLen,
2050 LPCVOID lpRead, DWORD dwReadLen)
2052 DWORD comp_len;
2053 DWORD read_len;
2054 CHAR *CompBuffer = NULL;
2055 CHAR *ReadBuffer = NULL;
2056 BOOL rc;
2057 InputContextData *data = (InputContextData*)hIMC;
2059 TRACE("(%p, %d, %p, %d, %p, %d):\n",
2060 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
2062 if (!data)
2063 return FALSE;
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,
2070 NULL);
2071 if (comp_len)
2073 CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len);
2074 WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len,
2075 NULL, NULL);
2078 read_len = WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, NULL, 0, NULL,
2079 NULL);
2080 if (read_len)
2082 ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len);
2083 WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len,
2084 NULL, NULL);
2087 rc = ImmSetCompositionStringA(hIMC, dwIndex, CompBuffer, comp_len,
2088 ReadBuffer, read_len);
2090 HeapFree(GetProcessHeap(), 0, CompBuffer);
2091 HeapFree(GetProcessHeap(), 0, ReadBuffer);
2093 return rc;
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);
2110 if (!data)
2111 return FALSE;
2113 data->IMC.cfCompForm = *lpCompForm;
2115 if (IsWindowVisible(IMM_GetThreadData()->hwndDefault))
2117 reshow = TRUE;
2118 ShowWindow(IMM_GetThreadData()->hwndDefault,SW_HIDE);
2121 /* FIXME: this is a partial stub */
2123 if (reshow)
2124 ShowWindow(IMM_GetThreadData()->hwndDefault,SW_SHOWNOACTIVATE);
2126 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0);
2127 return TRUE;
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);
2141 if (!data)
2142 return FALSE;
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);
2159 return TRUE;
2162 /***********************************************************************
2163 * ImmSetOpenStatus (IMM32.@)
2165 BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
2167 InputContextData *data = (InputContextData*)hIMC;
2169 TRACE("%p %d\n", hIMC, fOpen);
2171 if (!data)
2172 return FALSE;
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);
2191 return TRUE;
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)
2204 return FALSE;
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);
2212 return TRUE;
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);
2222 return 0;
2225 /***********************************************************************
2226 * ImmDestroySoftKeyboard(IMM32.@)
2228 BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
2230 FIXME("(%p): stub\n", hSoftWnd);
2231 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2232 return FALSE;
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);
2242 return FALSE;
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);
2252 return FALSE;
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);
2269 else
2271 LPWSTR lpszwReading = strdupAtoW(lpszReading);
2272 LPWSTR lpszwUnregister = strdupAtoW(lpszUnregister);
2273 BOOL rc;
2275 rc = immHkl->pImeUnregisterWord(lpszwReading,dwStyle,lpszwUnregister);
2276 HeapFree(GetProcessHeap(),0,lpszwReading);
2277 HeapFree(GetProcessHeap(),0,lpszwUnregister);
2278 return rc;
2281 else
2282 return FALSE;
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);
2298 else
2300 LPSTR lpszaReading = strdupWtoA(lpszReading);
2301 LPSTR lpszaUnregister = strdupWtoA(lpszUnregister);
2302 BOOL rc;
2304 rc = immHkl->pImeUnregisterWord((LPCWSTR)lpszaReading,dwStyle,
2305 (LPCWSTR)lpszaUnregister);
2306 HeapFree(GetProcessHeap(),0,lpszaReading);
2307 HeapFree(GetProcessHeap(),0,lpszaUnregister);
2308 return rc;
2311 else
2312 return FALSE;
2315 /***********************************************************************
2316 * ImmGetImeMenuItemsA (IMM32.@)
2318 DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType,
2319 LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
2320 DWORD dwSize)
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);
2331 else
2333 IMEMENUITEMINFOW lpImeParentMenuW;
2334 IMEMENUITEMINFOW *lpImeMenuW, *parent = NULL;
2335 DWORD rc;
2337 if (lpImeParentMenu)
2338 parent = &lpImeParentMenuW;
2339 if (lpImeMenu)
2341 int count = dwSize / sizeof(LPIMEMENUITEMINFOA);
2342 dwSize = count * sizeof(IMEMENUITEMINFOW);
2343 lpImeMenuW = HeapAlloc(GetProcessHeap(), 0, dwSize);
2345 else
2346 lpImeMenuW = NULL;
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,
2357 NULL, NULL);
2359 if (lpImeMenu && rc)
2361 int i;
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,
2368 NULL, NULL);
2371 HeapFree(GetProcessHeap(),0,lpImeMenuW);
2372 return rc;
2375 else
2376 return 0;
2379 /***********************************************************************
2380 * ImmGetImeMenuItemsW (IMM32.@)
2382 DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType,
2383 LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
2384 DWORD dwSize)
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);
2394 else
2396 IMEMENUITEMINFOA lpImeParentMenuA;
2397 IMEMENUITEMINFOA *lpImeMenuA, *parent = NULL;
2398 DWORD rc;
2400 if (lpImeParentMenu)
2401 parent = &lpImeParentMenuA;
2402 if (lpImeMenu)
2404 int count = dwSize / sizeof(LPIMEMENUITEMINFOW);
2405 dwSize = count * sizeof(IMEMENUITEMINFOA);
2406 lpImeMenuA = HeapAlloc(GetProcessHeap(), 0, dwSize);
2408 else
2409 lpImeMenuA = NULL;
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)
2424 int i;
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);
2434 return rc;
2437 else
2438 return 0;
2441 /***********************************************************************
2442 * ImmLockIMC(IMM32.@)
2444 LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
2446 InputContextData *data = (InputContextData*)hIMC;
2448 if (!data)
2449 return NULL;
2450 data->dwLock++;
2451 return &data->IMC;
2454 /***********************************************************************
2455 * ImmUnlockIMC(IMM32.@)
2457 BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
2459 InputContextData *data = (InputContextData*)hIMC;
2460 data->dwLock--;
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)
2483 return NULL;
2485 internal->dwSize = size;
2486 return (HIMCC)internal;
2489 /***********************************************************************
2490 * ImmDestroyIMCC(IMM32.@)
2492 HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
2494 HeapFree(GetProcessHeap(),0,block);
2495 return NULL;
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;
2546 return newone;
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;
2571 INT i;
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;
2582 return TRUE;
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);
2593 BYTE state[256];
2594 UINT scancode;
2595 LPVOID list = 0;
2596 UINT msg_count;
2597 UINT uVirtKey;
2598 static const int list_count = 10;
2600 TRACE("%p %x %x %x\n",hwnd, msg, (UINT)wParam, (UINT)lKeyData);
2602 if (imc)
2603 data = (InputContextData*)imc;
2604 else
2605 return FALSE;
2607 if (!data->immKbd->hIME || !data->immKbd->pImeToAsciiEx)
2608 return FALSE;
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)
2618 WCHAR chr;
2620 if (!is_himc_ime_unicode(data))
2621 ToAscii(data->lastVK, scancode, state, &chr, 0);
2622 else
2623 ToUnicodeEx(data->lastVK, scancode, state, &chr, 1, 0, GetKeyboardLayout(0));
2624 uVirtKey = MAKELONG(data->lastVK,chr);
2626 else
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)
2633 int i;
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);
2657 BYTE state[256];
2659 TRACE("%p %p %x %x %x\n",hwnd, hKL, vKey, (UINT)lKeyData, unknown);
2661 if (imc)
2662 data = (InputContextData*)imc;
2663 else
2664 return FALSE;
2666 if (!data->immKbd->hIME || !data->immKbd->pImeProcessKey)
2667 return FALSE;
2669 GetKeyboardState(state);
2670 if (data->immKbd->pImeProcessKey(imc, vKey, lKeyData, state))
2672 data->lastVK = vKey;
2673 return TRUE;
2676 data->lastVK = VK_PROCESSKEY;
2677 return FALSE;