wined3d: Handle texture coordinates the same way we handle other vertex attributes.
[wine/wine64.git] / dlls / imm32 / imm.c
blobabcff551a1b21be9ebe50d52d83ba9684615d645
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;
989 /* Helpers for the GetCompositionString functions */
991 static INT CopyCompStringIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE target, INT tlen,
992 BOOL unicode )
994 INT rc;
996 if (is_himc_ime_unicode(data) && !unicode)
997 rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)source, slen, (LPSTR)target, tlen, NULL, NULL);
998 else if (!is_himc_ime_unicode(data) && unicode)
999 rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)source, slen, (LPWSTR)target, tlen) * sizeof(WCHAR);
1000 else
1002 int dlen = (unicode)?sizeof(WCHAR):sizeof(CHAR);
1003 memcpy( target, source, min(slen,tlen)*dlen);
1004 rc = slen*dlen;
1007 return rc;
1010 static INT CopyCompAttrIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, INT sslen,
1011 LPBYTE target, INT tlen, BOOL unicode )
1013 INT rc;
1015 if (is_himc_ime_unicode(data) && !unicode)
1017 rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, sslen, NULL, 0, NULL, NULL);
1018 if (tlen)
1020 const BYTE *src = source;
1021 LPBYTE dst = target;
1022 int i, j = 0, k = 0;
1024 if (rc < tlen)
1025 tlen = rc;
1026 for (i = 0; i < sslen; ++i)
1028 int len;
1030 len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)ssource + i, 1,
1031 NULL, 0, NULL, NULL);
1032 for (; len > 0; --len)
1034 dst[j++] = src[k];
1036 if (j >= tlen)
1037 goto end;
1039 ++k;
1041 end:
1042 rc = j;
1045 else if (!is_himc_ime_unicode(data) && unicode)
1047 rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, sslen, NULL, 0);
1048 if (tlen)
1050 const BYTE *src = source;
1051 LPBYTE dst = target;
1052 int i, j = 0;
1054 if (rc < tlen)
1055 tlen = rc;
1056 for (i = 0; i < sslen; ++i)
1058 if (IsDBCSLeadByte(((LPSTR)ssource)[i]))
1059 continue;
1061 dst[j++] = src[i];
1063 if (j >= tlen)
1064 break;
1066 rc = j;
1069 else
1071 memcpy( target, source, min(slen,tlen));
1072 rc = slen;
1075 return rc;
1078 static INT CopyCompClauseIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, INT sslen,
1079 LPBYTE target, INT tlen, BOOL unicode )
1081 INT rc;
1083 if (is_himc_ime_unicode(data) && !unicode)
1085 if (tlen)
1087 int i;
1089 if (slen < tlen)
1090 tlen = slen;
1091 tlen /= sizeof (DWORD);
1092 for (i = 0; i < tlen; ++i)
1094 ((DWORD *)target)[i] = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource,
1095 ((DWORD *)source)[i],
1096 NULL, 0,
1097 NULL, NULL);
1099 rc = sizeof (DWORD) * i;
1101 else
1102 rc = slen;
1104 else if (!is_himc_ime_unicode(data) && unicode)
1106 if (tlen)
1108 int i;
1110 if (slen < tlen)
1111 tlen = slen;
1112 tlen /= sizeof (DWORD);
1113 for (i = 0; i < tlen; ++i)
1115 ((DWORD *)target)[i] = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource,
1116 ((DWORD *)source)[i],
1117 NULL, 0);
1119 rc = sizeof (DWORD) * i;
1121 else
1122 rc = slen;
1124 else
1126 memcpy( target, source, min(slen,tlen));
1127 rc = slen;
1130 return rc;
1133 static INT CopyCompOffsetIMEtoClient(InputContextData *data, DWORD offset, LPBYTE ssource, BOOL unicode)
1135 int rc;
1137 if (is_himc_ime_unicode(data) && !unicode)
1139 rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, offset, NULL, 0, NULL, NULL);
1141 else if (!is_himc_ime_unicode(data) && unicode)
1143 rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, offset, NULL, 0);
1145 else
1146 rc = offset;
1148 return rc;
1151 static LONG ImmGetCompositionStringT( HIMC hIMC, DWORD dwIndex, LPVOID lpBuf,
1152 DWORD dwBufLen, BOOL unicode)
1154 LONG rc = 0;
1155 InputContextData *data = (InputContextData*)hIMC;
1156 LPCOMPOSITIONSTRING compstr;
1157 LPBYTE compdata;
1159 TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
1161 if (!data)
1162 return FALSE;
1164 if (!data->IMC.hCompStr)
1165 return FALSE;
1167 compdata = ImmLockIMCC(data->IMC.hCompStr);
1168 compstr = (LPCOMPOSITIONSTRING)compdata;
1170 switch (dwIndex)
1172 case GCS_RESULTSTR:
1173 TRACE("GCS_RESULTSTR\n");
1174 rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwResultStrOffset, compstr->dwResultStrLen, lpBuf, dwBufLen, unicode);
1175 break;
1176 case GCS_COMPSTR:
1177 TRACE("GCS_COMPSTR\n");
1178 rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen, lpBuf, dwBufLen, unicode);
1179 break;
1180 case GCS_COMPATTR:
1181 TRACE("GCS_COMPATTR\n");
1182 rc = CopyCompAttrIMEtoClient(data, compdata + compstr->dwCompAttrOffset, compstr->dwCompAttrLen,
1183 compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen,
1184 lpBuf, dwBufLen, unicode);
1185 break;
1186 case GCS_COMPCLAUSE:
1187 TRACE("GCS_COMPCLAUSE\n");
1188 rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwCompClauseOffset,compstr->dwCompClauseLen,
1189 compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen,
1190 lpBuf, dwBufLen, unicode);
1191 break;
1192 case GCS_RESULTCLAUSE:
1193 TRACE("GCS_RESULTCLAUSE\n");
1194 rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultClauseOffset,compstr->dwResultClauseLen,
1195 compdata + compstr->dwResultStrOffset, compstr->dwResultStrLen,
1196 lpBuf, dwBufLen, unicode);
1197 break;
1198 case GCS_RESULTREADSTR:
1199 TRACE("GCS_RESULTREADSTR\n");
1200 rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwResultReadStrOffset, compstr->dwResultReadStrLen, lpBuf, dwBufLen, unicode);
1201 break;
1202 case GCS_RESULTREADCLAUSE:
1203 TRACE("GCS_RESULTREADCLAUSE\n");
1204 rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultReadClauseOffset,compstr->dwResultReadClauseLen,
1205 compdata + compstr->dwResultStrOffset, compstr->dwResultStrLen,
1206 lpBuf, dwBufLen, unicode);
1207 break;
1208 case GCS_COMPREADSTR:
1209 TRACE("GCS_COMPREADSTR\n");
1210 rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwCompReadStrOffset, compstr->dwCompReadStrLen, lpBuf, dwBufLen, unicode);
1211 break;
1212 case GCS_COMPREADATTR:
1213 TRACE("GCS_COMPREADATTR\n");
1214 rc = CopyCompAttrIMEtoClient(data, compdata + compstr->dwCompReadAttrOffset, compstr->dwCompReadAttrLen,
1215 compdata + compstr->dwCompReadStrOffset, compstr->dwCompReadStrLen,
1216 lpBuf, dwBufLen, unicode);
1217 break;
1218 case GCS_COMPREADCLAUSE:
1219 TRACE("GCS_COMPREADCLAUSE\n");
1220 rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwCompReadClauseOffset,compstr->dwCompReadClauseLen,
1221 compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen,
1222 lpBuf, dwBufLen, unicode);
1223 break;
1224 case GCS_CURSORPOS:
1225 TRACE("GCS_CURSORPOS\n");
1226 rc = CopyCompOffsetIMEtoClient(data, compstr->dwCursorPos, compdata + compstr->dwCompStrOffset, unicode);
1227 break;
1228 case GCS_DELTASTART:
1229 TRACE("GCS_DELTASTART\n");
1230 rc = CopyCompOffsetIMEtoClient(data, compstr->dwDeltaStart, compdata + compstr->dwCompStrOffset, unicode);
1231 break;
1232 default:
1233 FIXME("Unhandled index 0x%x\n",dwIndex);
1234 break;
1237 ImmUnlockIMCC(data->IMC.hCompStr);
1239 return rc;
1242 /***********************************************************************
1243 * ImmGetCompositionStringA (IMM32.@)
1245 LONG WINAPI ImmGetCompositionStringA(
1246 HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
1248 return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, FALSE);
1252 /***********************************************************************
1253 * ImmGetCompositionStringW (IMM32.@)
1255 LONG WINAPI ImmGetCompositionStringW(
1256 HIMC hIMC, DWORD dwIndex,
1257 LPVOID lpBuf, DWORD dwBufLen)
1259 return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, TRUE);
1262 /***********************************************************************
1263 * ImmGetCompositionWindow (IMM32.@)
1265 BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
1267 InputContextData *data = (InputContextData*)hIMC;
1269 TRACE("(%p, %p)\n", hIMC, lpCompForm);
1271 if (!data)
1272 return FALSE;
1274 *lpCompForm = data->IMC.cfCompForm;
1275 return 1;
1278 /***********************************************************************
1279 * ImmGetContext (IMM32.@)
1282 HIMC WINAPI ImmGetContext(HWND hWnd)
1284 HIMC rc = NULL;
1286 TRACE("%p\n", hWnd);
1287 if (!IMM_GetThreadData()->defaultContext)
1288 IMM_GetThreadData()->defaultContext = ImmCreateContext();
1290 rc = (HIMC)GetPropW(hWnd,szwWineIMCProperty);
1291 if (rc == (HIMC)-1)
1292 rc = NULL;
1293 else if (rc == NULL)
1294 rc = IMM_GetThreadData()->defaultContext;
1296 if (rc)
1298 InputContextData *data = (InputContextData*)rc;
1299 data->IMC.hWnd = hWnd;
1301 TRACE("returning %p\n", rc);
1303 return rc;
1306 /***********************************************************************
1307 * ImmGetConversionListA (IMM32.@)
1309 DWORD WINAPI ImmGetConversionListA(
1310 HKL hKL, HIMC hIMC,
1311 LPCSTR pSrc, LPCANDIDATELIST lpDst,
1312 DWORD dwBufLen, UINT uFlag)
1314 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1315 TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL, hIMC, debugstr_a(pSrc), lpDst,
1316 dwBufLen, uFlag);
1317 if (immHkl->hIME && immHkl->pImeConversionList)
1319 if (!is_kbd_ime_unicode(immHkl))
1320 return immHkl->pImeConversionList(hIMC,(LPCWSTR)pSrc,lpDst,dwBufLen,uFlag);
1321 else
1323 LPCANDIDATELIST lpwDst;
1324 DWORD ret = 0, len;
1325 LPWSTR pwSrc = strdupAtoW(pSrc);
1327 len = immHkl->pImeConversionList(hIMC, pwSrc, NULL, 0, uFlag);
1328 lpwDst = HeapAlloc(GetProcessHeap(), 0, len);
1329 if ( lpwDst )
1331 immHkl->pImeConversionList(hIMC, pwSrc, lpwDst, len, uFlag);
1332 ret = convert_candidatelist_WtoA( lpwDst, lpDst, dwBufLen);
1333 HeapFree(GetProcessHeap(), 0, lpwDst);
1335 HeapFree(GetProcessHeap(), 0, pwSrc);
1337 return ret;
1340 else
1341 return 0;
1344 /***********************************************************************
1345 * ImmGetConversionListW (IMM32.@)
1347 DWORD WINAPI ImmGetConversionListW(
1348 HKL hKL, HIMC hIMC,
1349 LPCWSTR pSrc, LPCANDIDATELIST lpDst,
1350 DWORD dwBufLen, UINT uFlag)
1352 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1353 TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL, hIMC, debugstr_w(pSrc), lpDst,
1354 dwBufLen, uFlag);
1355 if (immHkl->hIME && immHkl->pImeConversionList)
1357 if (is_kbd_ime_unicode(immHkl))
1358 return immHkl->pImeConversionList(hIMC,pSrc,lpDst,dwBufLen,uFlag);
1359 else
1361 LPCANDIDATELIST lpaDst;
1362 DWORD ret = 0, len;
1363 LPSTR paSrc = strdupWtoA(pSrc);
1365 len = immHkl->pImeConversionList(hIMC, (LPCWSTR)paSrc, NULL, 0, uFlag);
1366 lpaDst = HeapAlloc(GetProcessHeap(), 0, len);
1367 if ( lpaDst )
1369 immHkl->pImeConversionList(hIMC, (LPCWSTR)paSrc, lpaDst, len, uFlag);
1370 ret = convert_candidatelist_AtoW( lpaDst, lpDst, dwBufLen);
1371 HeapFree(GetProcessHeap(), 0, lpaDst);
1373 HeapFree(GetProcessHeap(), 0, paSrc);
1375 return ret;
1378 else
1379 return 0;
1382 /***********************************************************************
1383 * ImmGetConversionStatus (IMM32.@)
1385 BOOL WINAPI ImmGetConversionStatus(
1386 HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
1388 InputContextData *data = (InputContextData*)hIMC;
1390 TRACE("%p %p %p\n", hIMC, lpfdwConversion, lpfdwSentence);
1392 if (!data)
1393 return FALSE;
1395 if (lpfdwConversion)
1396 *lpfdwConversion = data->IMC.fdwConversion;
1397 if (lpfdwSentence)
1398 *lpfdwSentence = data->IMC.fdwSentence;
1400 return TRUE;
1403 /***********************************************************************
1404 * ImmGetDefaultIMEWnd (IMM32.@)
1406 HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
1408 TRACE("Default is %x\n",(unsigned)IMM_GetThreadData()->hwndDefault);
1409 return IMM_GetThreadData()->hwndDefault;
1412 /***********************************************************************
1413 * ImmGetDescriptionA (IMM32.@)
1415 UINT WINAPI ImmGetDescriptionA(
1416 HKL hKL, LPSTR lpszDescription, UINT uBufLen)
1418 WCHAR *buf;
1419 DWORD len;
1421 TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
1423 /* find out how many characters in the unicode buffer */
1424 len = ImmGetDescriptionW( hKL, NULL, 0 );
1426 /* allocate a buffer of that size */
1427 buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
1428 if( !buf )
1429 return 0;
1431 /* fetch the unicode buffer */
1432 len = ImmGetDescriptionW( hKL, buf, len + 1 );
1434 /* convert it back to ASCII */
1435 len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
1436 lpszDescription, uBufLen, NULL, NULL );
1438 HeapFree( GetProcessHeap(), 0, buf );
1440 return len;
1443 /***********************************************************************
1444 * ImmGetDescriptionW (IMM32.@)
1446 UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
1448 static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
1450 FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
1452 if (!uBufLen) return lstrlenW( name );
1453 lstrcpynW( lpszDescription, name, uBufLen );
1454 return lstrlenW( lpszDescription );
1457 /***********************************************************************
1458 * ImmGetGuideLineA (IMM32.@)
1460 DWORD WINAPI ImmGetGuideLineA(
1461 HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
1463 FIXME("(%p, %d, %s, %d): stub\n",
1464 hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
1466 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1467 return 0;
1470 /***********************************************************************
1471 * ImmGetGuideLineW (IMM32.@)
1473 DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
1475 FIXME("(%p, %d, %s, %d): stub\n",
1476 hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
1478 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1479 return 0;
1482 /***********************************************************************
1483 * ImmGetIMEFileNameA (IMM32.@)
1485 UINT WINAPI ImmGetIMEFileNameA( HKL hKL, LPSTR lpszFileName, UINT uBufLen)
1487 LPWSTR bufW = NULL;
1488 UINT wBufLen = uBufLen;
1489 UINT rc;
1491 if (uBufLen && lpszFileName)
1492 bufW = HeapAlloc(GetProcessHeap(),0,uBufLen * sizeof(WCHAR));
1493 else /* We need this to get the number of byte required */
1495 bufW = HeapAlloc(GetProcessHeap(),0,MAX_PATH * sizeof(WCHAR));
1496 wBufLen = MAX_PATH;
1499 rc = ImmGetIMEFileNameW(hKL,bufW,wBufLen);
1501 if (rc > 0)
1503 if (uBufLen && lpszFileName)
1504 rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, lpszFileName,
1505 uBufLen, NULL, NULL);
1506 else /* get the length */
1507 rc = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL,
1508 NULL);
1511 HeapFree(GetProcessHeap(),0,bufW);
1512 return rc;
1515 /***********************************************************************
1516 * ImmGetIMEFileNameW (IMM32.@)
1518 UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
1520 static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0};
1521 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};
1523 HKEY hkey;
1524 DWORD length;
1525 DWORD rc;
1526 WCHAR regKey[sizeof(fmt)/sizeof(WCHAR)+8];
1528 wsprintfW( regKey, fmt, (unsigned)hKL );
1529 rc = RegOpenKeyW( HKEY_LOCAL_MACHINE, regKey, &hkey);
1530 if (rc != ERROR_SUCCESS)
1532 SetLastError(rc);
1533 return 0;
1536 length = 0;
1537 rc = RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, NULL, &length);
1539 if (rc != ERROR_SUCCESS)
1541 RegCloseKey(hkey);
1542 SetLastError(rc);
1543 return 0;
1545 if (length > uBufLen * sizeof(WCHAR) || !lpszFileName)
1547 RegCloseKey(hkey);
1548 if (lpszFileName)
1550 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1551 return 0;
1553 else
1554 return length / sizeof(WCHAR);
1557 RegGetValueW(hkey, NULL, szImeFileW, RRF_RT_REG_SZ, NULL, lpszFileName, &length);
1559 RegCloseKey(hkey);
1561 return length / sizeof(WCHAR);
1564 /***********************************************************************
1565 * ImmGetOpenStatus (IMM32.@)
1567 BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
1569 InputContextData *data = (InputContextData*)hIMC;
1571 if (!data)
1572 return FALSE;
1573 FIXME("(%p): semi-stub\n", hIMC);
1575 return data->IMC.fOpen;
1578 /***********************************************************************
1579 * ImmGetProperty (IMM32.@)
1581 DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
1583 DWORD rc = 0;
1584 ImmHkl *kbd;
1586 TRACE("(%p, %d)\n", hKL, fdwIndex);
1587 kbd = IMM_GetImmHkl(hKL);
1589 if (kbd && kbd->hIME)
1591 switch (fdwIndex)
1593 case IGP_PROPERTY: rc = kbd->imeInfo.fdwProperty; break;
1594 case IGP_CONVERSION: rc = kbd->imeInfo.fdwConversionCaps; break;
1595 case IGP_SENTENCE: rc = kbd->imeInfo.fdwSentenceCaps; break;
1596 case IGP_SETCOMPSTR: rc = kbd->imeInfo.fdwSCSCaps; break;
1597 case IGP_SELECT: rc = kbd->imeInfo.fdwSelectCaps; break;
1598 case IGP_GETIMEVERSION: rc = IMEVER_0400; break;
1599 case IGP_UI: rc = 0; break;
1600 default: rc = 0;
1603 return rc;
1606 /***********************************************************************
1607 * ImmGetRegisterWordStyleA (IMM32.@)
1609 UINT WINAPI ImmGetRegisterWordStyleA(
1610 HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
1612 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1613 TRACE("(%p, %d, %p):\n", hKL, nItem, lpStyleBuf);
1614 if (immHkl->hIME && immHkl->pImeGetRegisterWordStyle)
1616 if (!is_kbd_ime_unicode(immHkl))
1617 return immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)lpStyleBuf);
1618 else
1620 STYLEBUFW sbw;
1621 UINT rc;
1623 rc = immHkl->pImeGetRegisterWordStyle(nItem,&sbw);
1624 WideCharToMultiByte(CP_ACP, 0, sbw.szDescription, -1,
1625 lpStyleBuf->szDescription, 32, NULL, NULL);
1626 lpStyleBuf->dwStyle = sbw.dwStyle;
1627 return rc;
1630 else
1631 return 0;
1634 /***********************************************************************
1635 * ImmGetRegisterWordStyleW (IMM32.@)
1637 UINT WINAPI ImmGetRegisterWordStyleW(
1638 HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
1640 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1641 TRACE("(%p, %d, %p):\n", hKL, nItem, lpStyleBuf);
1642 if (immHkl->hIME && immHkl->pImeGetRegisterWordStyle)
1644 if (is_kbd_ime_unicode(immHkl))
1645 return immHkl->pImeGetRegisterWordStyle(nItem,lpStyleBuf);
1646 else
1648 STYLEBUFA sba;
1649 UINT rc;
1651 rc = immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)&sba);
1652 MultiByteToWideChar(CP_ACP, 0, sba.szDescription, -1,
1653 lpStyleBuf->szDescription, 32);
1654 lpStyleBuf->dwStyle = sba.dwStyle;
1655 return rc;
1658 else
1659 return 0;
1662 /***********************************************************************
1663 * ImmGetStatusWindowPos (IMM32.@)
1665 BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
1667 InputContextData *data = (InputContextData*)hIMC;
1669 TRACE("(%p, %p)\n", hIMC, lpptPos);
1671 if (!data || !lpptPos)
1672 return FALSE;
1674 *lpptPos = data->IMC.ptStatusWndPos;
1676 return TRUE;
1679 /***********************************************************************
1680 * ImmGetVirtualKey (IMM32.@)
1682 UINT WINAPI ImmGetVirtualKey(HWND hWnd)
1684 OSVERSIONINFOA version;
1685 InputContextData *data = (InputContextData *)ImmGetContext( hWnd );
1686 TRACE("%p\n", hWnd);
1688 if ( data )
1689 return data->lastVK;
1691 GetVersionExA( &version );
1692 switch(version.dwPlatformId)
1694 case VER_PLATFORM_WIN32_WINDOWS:
1695 return VK_PROCESSKEY;
1696 case VER_PLATFORM_WIN32_NT:
1697 return 0;
1698 default:
1699 FIXME("%d not supported\n",version.dwPlatformId);
1700 return VK_PROCESSKEY;
1704 /***********************************************************************
1705 * ImmInstallIMEA (IMM32.@)
1707 HKL WINAPI ImmInstallIMEA(
1708 LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
1710 FIXME("(%s, %s): stub\n",
1711 debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
1713 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1714 return NULL;
1717 /***********************************************************************
1718 * ImmInstallIMEW (IMM32.@)
1720 HKL WINAPI ImmInstallIMEW(
1721 LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
1723 FIXME("(%s, %s): stub\n",
1724 debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
1726 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1727 return NULL;
1730 /***********************************************************************
1731 * ImmIsIME (IMM32.@)
1733 BOOL WINAPI ImmIsIME(HKL hKL)
1735 ImmHkl *ptr;
1736 TRACE("(%p):\n", hKL);
1737 ptr = IMM_GetImmHkl(hKL);
1738 return (ptr && ptr->hIME);
1741 /***********************************************************************
1742 * ImmIsUIMessageA (IMM32.@)
1744 BOOL WINAPI ImmIsUIMessageA(
1745 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1747 BOOL rc = FALSE;
1749 TRACE("(%p, %x, %ld, %ld)\n", hWndIME, msg, wParam, lParam);
1750 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1751 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1752 (msg == WM_MSIME_SERVICE) ||
1753 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1754 (msg == WM_MSIME_MOUSE) ||
1755 (msg == WM_MSIME_RECONVERTREQUEST) ||
1756 (msg == WM_MSIME_RECONVERT) ||
1757 (msg == WM_MSIME_QUERYPOSITION) ||
1758 (msg == WM_MSIME_DOCUMENTFEED))
1761 if (!IMM_GetThreadData()->hwndDefault)
1762 ImmGetDefaultIMEWnd(NULL);
1764 if (hWndIME == NULL)
1765 PostMessageA(IMM_GetThreadData()->hwndDefault, msg, wParam, lParam);
1767 rc = TRUE;
1769 return rc;
1772 /***********************************************************************
1773 * ImmIsUIMessageW (IMM32.@)
1775 BOOL WINAPI ImmIsUIMessageW(
1776 HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1778 BOOL rc = FALSE;
1779 TRACE("(%p, %d, %ld, %ld):\n", hWndIME, msg, wParam, lParam);
1780 if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
1781 (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
1782 (msg == WM_MSIME_SERVICE) ||
1783 (msg == WM_MSIME_RECONVERTOPTIONS) ||
1784 (msg == WM_MSIME_MOUSE) ||
1785 (msg == WM_MSIME_RECONVERTREQUEST) ||
1786 (msg == WM_MSIME_RECONVERT) ||
1787 (msg == WM_MSIME_QUERYPOSITION) ||
1788 (msg == WM_MSIME_DOCUMENTFEED))
1789 rc = TRUE;
1790 return rc;
1793 /***********************************************************************
1794 * ImmNotifyIME (IMM32.@)
1796 BOOL WINAPI ImmNotifyIME(
1797 HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
1799 InputContextData *data = (InputContextData*)hIMC;
1801 TRACE("(%p, %d, %d, %d)\n",
1802 hIMC, dwAction, dwIndex, dwValue);
1804 if (!data || ! data->immKbd->pNotifyIME)
1805 return FALSE;
1807 return data->immKbd->pNotifyIME(hIMC,dwAction,dwIndex,dwValue);
1810 /***********************************************************************
1811 * ImmRegisterWordA (IMM32.@)
1813 BOOL WINAPI ImmRegisterWordA(
1814 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
1816 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1817 TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_a(lpszReading), dwStyle,
1818 debugstr_a(lpszRegister));
1819 if (immHkl->hIME && immHkl->pImeRegisterWord)
1821 if (!is_kbd_ime_unicode(immHkl))
1822 return immHkl->pImeRegisterWord((LPCWSTR)lpszReading,dwStyle,
1823 (LPCWSTR)lpszRegister);
1824 else
1826 LPWSTR lpszwReading = strdupAtoW(lpszReading);
1827 LPWSTR lpszwRegister = strdupAtoW(lpszRegister);
1828 BOOL rc;
1830 rc = immHkl->pImeRegisterWord(lpszwReading,dwStyle,lpszwRegister);
1831 HeapFree(GetProcessHeap(),0,lpszwReading);
1832 HeapFree(GetProcessHeap(),0,lpszwRegister);
1833 return rc;
1836 else
1837 return FALSE;
1840 /***********************************************************************
1841 * ImmRegisterWordW (IMM32.@)
1843 BOOL WINAPI ImmRegisterWordW(
1844 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
1846 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
1847 TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_w(lpszReading), dwStyle,
1848 debugstr_w(lpszRegister));
1849 if (immHkl->hIME && immHkl->pImeRegisterWord)
1851 if (is_kbd_ime_unicode(immHkl))
1852 return immHkl->pImeRegisterWord(lpszReading,dwStyle,lpszRegister);
1853 else
1855 LPSTR lpszaReading = strdupWtoA(lpszReading);
1856 LPSTR lpszaRegister = strdupWtoA(lpszRegister);
1857 BOOL rc;
1859 rc = immHkl->pImeRegisterWord((LPCWSTR)lpszaReading,dwStyle,
1860 (LPCWSTR)lpszaRegister);
1861 HeapFree(GetProcessHeap(),0,lpszaReading);
1862 HeapFree(GetProcessHeap(),0,lpszaRegister);
1863 return rc;
1866 else
1867 return FALSE;
1870 /***********************************************************************
1871 * ImmReleaseContext (IMM32.@)
1873 BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
1875 static int shown = 0;
1877 if (!shown) {
1878 FIXME("(%p, %p): stub\n", hWnd, hIMC);
1879 shown = 1;
1881 return TRUE;
1884 /***********************************************************************
1885 * ImmRequestMessageA(IMM32.@)
1887 LRESULT WINAPI ImmRequestMessageA(HIMC hIMC, WPARAM wParam, LPARAM lParam)
1889 InputContextData *data = (InputContextData*)hIMC;
1891 TRACE("%p %ld %ld\n", hIMC, wParam, wParam);
1893 if (data && IsWindow(data->IMC.hWnd))
1894 return SendMessageA(data->IMC.hWnd, WM_IME_REQUEST, wParam, lParam);
1896 return 0;
1899 /***********************************************************************
1900 * ImmRequestMessageW(IMM32.@)
1902 LRESULT WINAPI ImmRequestMessageW(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 SendMessageW(data->IMC.hWnd, WM_IME_REQUEST, wParam, lParam);
1911 return 0;
1914 /***********************************************************************
1915 * ImmSetCandidateWindow (IMM32.@)
1917 BOOL WINAPI ImmSetCandidateWindow(
1918 HIMC hIMC, LPCANDIDATEFORM lpCandidate)
1920 InputContextData *data = (InputContextData*)hIMC;
1922 TRACE("(%p, %p)\n", hIMC, lpCandidate);
1924 if (!data || !lpCandidate)
1925 return FALSE;
1927 TRACE("\t%x, %x, (%i,%i), (%i,%i - %i,%i)\n",
1928 lpCandidate->dwIndex, lpCandidate->dwStyle,
1929 lpCandidate->ptCurrentPos.x, lpCandidate->ptCurrentPos.y,
1930 lpCandidate->rcArea.top, lpCandidate->rcArea.left,
1931 lpCandidate->rcArea.bottom, lpCandidate->rcArea.right);
1933 if ( lpCandidate->dwIndex >= (sizeof(data->IMC.cfCandForm) / sizeof(CANDIDATEFORM)) )
1934 return FALSE;
1936 data->IMC.cfCandForm[lpCandidate->dwIndex] = *lpCandidate;
1937 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS);
1938 ImmInternalSendIMENotify(data, IMN_SETCANDIDATEPOS, 1 << lpCandidate->dwIndex);
1940 return TRUE;
1943 /***********************************************************************
1944 * ImmSetCompositionFontA (IMM32.@)
1946 BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
1948 InputContextData *data = (InputContextData*)hIMC;
1949 TRACE("(%p, %p)\n", hIMC, lplf);
1951 if (!data || !lplf)
1952 return FALSE;
1954 memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
1955 MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
1956 LF_FACESIZE);
1957 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
1958 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
1960 return TRUE;
1963 /***********************************************************************
1964 * ImmSetCompositionFontW (IMM32.@)
1966 BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
1968 InputContextData *data = (InputContextData*)hIMC;
1969 TRACE("(%p, %p)\n", hIMC, lplf);
1971 if (!data || !lplf)
1972 return FALSE;
1974 data->IMC.lfFont.W = *lplf;
1975 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
1976 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
1978 return TRUE;
1981 /***********************************************************************
1982 * ImmSetCompositionStringA (IMM32.@)
1984 BOOL WINAPI ImmSetCompositionStringA(
1985 HIMC hIMC, DWORD dwIndex,
1986 LPCVOID lpComp, DWORD dwCompLen,
1987 LPCVOID lpRead, DWORD dwReadLen)
1989 DWORD comp_len;
1990 DWORD read_len;
1991 WCHAR *CompBuffer = NULL;
1992 WCHAR *ReadBuffer = NULL;
1993 BOOL rc;
1994 InputContextData *data = (InputContextData*)hIMC;
1996 TRACE("(%p, %d, %p, %d, %p, %d):\n",
1997 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
1999 if (!data)
2000 return FALSE;
2002 if (!is_himc_ime_unicode(data))
2003 return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
2004 dwCompLen, lpRead, dwReadLen);
2006 comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
2007 if (comp_len)
2009 CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len * sizeof(WCHAR));
2010 MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len);
2013 read_len = MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, NULL, 0);
2014 if (read_len)
2016 ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len * sizeof(WCHAR));
2017 MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len);
2020 rc = ImmSetCompositionStringW(hIMC, dwIndex, CompBuffer, comp_len,
2021 ReadBuffer, read_len);
2023 HeapFree(GetProcessHeap(), 0, CompBuffer);
2024 HeapFree(GetProcessHeap(), 0, ReadBuffer);
2026 return rc;
2029 /***********************************************************************
2030 * ImmSetCompositionStringW (IMM32.@)
2032 BOOL WINAPI ImmSetCompositionStringW(
2033 HIMC hIMC, DWORD dwIndex,
2034 LPCVOID lpComp, DWORD dwCompLen,
2035 LPCVOID lpRead, DWORD dwReadLen)
2037 DWORD comp_len;
2038 DWORD read_len;
2039 CHAR *CompBuffer = NULL;
2040 CHAR *ReadBuffer = NULL;
2041 BOOL rc;
2042 InputContextData *data = (InputContextData*)hIMC;
2044 TRACE("(%p, %d, %p, %d, %p, %d):\n",
2045 hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
2047 if (!data)
2048 return FALSE;
2050 if (is_himc_ime_unicode(data))
2051 return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
2052 dwCompLen, lpRead, dwReadLen);
2054 comp_len = WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, NULL, 0, NULL,
2055 NULL);
2056 if (comp_len)
2058 CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len);
2059 WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len,
2060 NULL, NULL);
2063 read_len = WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, NULL, 0, NULL,
2064 NULL);
2065 if (read_len)
2067 ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len);
2068 WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len,
2069 NULL, NULL);
2072 rc = ImmSetCompositionStringA(hIMC, dwIndex, CompBuffer, comp_len,
2073 ReadBuffer, read_len);
2075 HeapFree(GetProcessHeap(), 0, CompBuffer);
2076 HeapFree(GetProcessHeap(), 0, ReadBuffer);
2078 return rc;
2081 /***********************************************************************
2082 * ImmSetCompositionWindow (IMM32.@)
2084 BOOL WINAPI ImmSetCompositionWindow(
2085 HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
2087 BOOL reshow = FALSE;
2088 InputContextData *data = (InputContextData*)hIMC;
2090 TRACE("(%p, %p)\n", hIMC, lpCompForm);
2091 TRACE("\t%x, (%i,%i), (%i,%i - %i,%i)\n",lpCompForm->dwStyle,
2092 lpCompForm->ptCurrentPos.x, lpCompForm->ptCurrentPos.y, lpCompForm->rcArea.top,
2093 lpCompForm->rcArea.left, lpCompForm->rcArea.bottom, lpCompForm->rcArea.right);
2095 if (!data)
2096 return FALSE;
2098 data->IMC.cfCompForm = *lpCompForm;
2100 if (IsWindowVisible(IMM_GetThreadData()->hwndDefault))
2102 reshow = TRUE;
2103 ShowWindow(IMM_GetThreadData()->hwndDefault,SW_HIDE);
2106 /* FIXME: this is a partial stub */
2108 if (reshow)
2109 ShowWindow(IMM_GetThreadData()->hwndDefault,SW_SHOWNOACTIVATE);
2111 ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0);
2112 return TRUE;
2115 /***********************************************************************
2116 * ImmSetConversionStatus (IMM32.@)
2118 BOOL WINAPI ImmSetConversionStatus(
2119 HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
2121 DWORD oldConversion, oldSentence;
2122 InputContextData *data = (InputContextData*)hIMC;
2124 TRACE("%p %d %d\n", hIMC, fdwConversion, fdwSentence);
2126 if (!data)
2127 return FALSE;
2129 if ( fdwConversion != data->IMC.fdwConversion )
2131 oldConversion = data->IMC.fdwConversion;
2132 data->IMC.fdwConversion = fdwConversion;
2133 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, oldConversion, IMC_SETCONVERSIONMODE);
2134 ImmInternalSendIMENotify(data, IMN_SETCONVERSIONMODE, 0);
2136 if ( fdwSentence != data->IMC.fdwSentence )
2138 oldSentence = data->IMC.fdwSentence;
2139 data->IMC.fdwSentence = fdwSentence;
2140 ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, oldSentence, IMC_SETSENTENCEMODE);
2141 ImmInternalSendIMENotify(data, IMN_SETSENTENCEMODE, 0);
2144 return TRUE;
2147 /***********************************************************************
2148 * ImmSetOpenStatus (IMM32.@)
2150 BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
2152 InputContextData *data = (InputContextData*)hIMC;
2154 TRACE("%p %d\n", hIMC, fOpen);
2156 if (!data)
2157 return FALSE;
2159 if (data->imeWnd == NULL)
2161 /* create the ime window */
2162 data->imeWnd = CreateWindowExW( WS_EX_TOOLWINDOW,
2163 data->immKbd->imeClassName, NULL, WS_POPUP, 0, 0, 1, 1, 0,
2164 0, data->immKbd->hIME, 0);
2165 SetWindowLongW(data->imeWnd, IMMGWL_IMC, (LONG)data);
2166 IMM_GetThreadData()->hwndDefault = data->imeWnd;
2169 if (!fOpen != !data->IMC.fOpen)
2171 data->IMC.fOpen = fOpen;
2172 ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS);
2173 ImmInternalSendIMENotify(data, IMN_SETOPENSTATUS, 0);
2176 return TRUE;
2179 /***********************************************************************
2180 * ImmSetStatusWindowPos (IMM32.@)
2182 BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
2184 InputContextData *data = (InputContextData*)hIMC;
2186 TRACE("(%p, %p)\n", hIMC, lpptPos);
2188 if (!data || !lpptPos)
2189 return FALSE;
2191 TRACE("\t(%i,%i)\n", lpptPos->x, lpptPos->y);
2193 data->IMC.ptStatusWndPos = *lpptPos;
2194 ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETSTATUSWINDOWPOS);
2195 ImmInternalSendIMENotify(data, IMN_SETSTATUSWINDOWPOS, 0);
2197 return TRUE;
2200 /***********************************************************************
2201 * ImmCreateSoftKeyboard(IMM32.@)
2203 HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y)
2205 FIXME("(%d, %d, %d, %d): stub\n", uType, hOwner, x, y);
2206 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2207 return 0;
2210 /***********************************************************************
2211 * ImmDestroySoftKeyboard(IMM32.@)
2213 BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
2215 FIXME("(%p): stub\n", hSoftWnd);
2216 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2217 return FALSE;
2220 /***********************************************************************
2221 * ImmShowSoftKeyboard(IMM32.@)
2223 BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
2225 FIXME("(%p, %d): stub\n", hSoftWnd, nCmdShow);
2226 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2227 return FALSE;
2230 /***********************************************************************
2231 * ImmSimulateHotKey (IMM32.@)
2233 BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
2235 FIXME("(%p, %d): stub\n", hWnd, dwHotKeyID);
2236 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2237 return FALSE;
2240 /***********************************************************************
2241 * ImmUnregisterWordA (IMM32.@)
2243 BOOL WINAPI ImmUnregisterWordA(
2244 HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
2246 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
2247 TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_a(lpszReading), dwStyle,
2248 debugstr_a(lpszUnregister));
2249 if (immHkl->hIME && immHkl->pImeUnregisterWord)
2251 if (!is_kbd_ime_unicode(immHkl))
2252 return immHkl->pImeUnregisterWord((LPCWSTR)lpszReading,dwStyle,
2253 (LPCWSTR)lpszUnregister);
2254 else
2256 LPWSTR lpszwReading = strdupAtoW(lpszReading);
2257 LPWSTR lpszwUnregister = strdupAtoW(lpszUnregister);
2258 BOOL rc;
2260 rc = immHkl->pImeUnregisterWord(lpszwReading,dwStyle,lpszwUnregister);
2261 HeapFree(GetProcessHeap(),0,lpszwReading);
2262 HeapFree(GetProcessHeap(),0,lpszwUnregister);
2263 return rc;
2266 else
2267 return FALSE;
2270 /***********************************************************************
2271 * ImmUnregisterWordW (IMM32.@)
2273 BOOL WINAPI ImmUnregisterWordW(
2274 HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
2276 ImmHkl *immHkl = IMM_GetImmHkl(hKL);
2277 TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_w(lpszReading), dwStyle,
2278 debugstr_w(lpszUnregister));
2279 if (immHkl->hIME && immHkl->pImeUnregisterWord)
2281 if (is_kbd_ime_unicode(immHkl))
2282 return immHkl->pImeUnregisterWord(lpszReading,dwStyle,lpszUnregister);
2283 else
2285 LPSTR lpszaReading = strdupWtoA(lpszReading);
2286 LPSTR lpszaUnregister = strdupWtoA(lpszUnregister);
2287 BOOL rc;
2289 rc = immHkl->pImeUnregisterWord((LPCWSTR)lpszaReading,dwStyle,
2290 (LPCWSTR)lpszaUnregister);
2291 HeapFree(GetProcessHeap(),0,lpszaReading);
2292 HeapFree(GetProcessHeap(),0,lpszaUnregister);
2293 return rc;
2296 else
2297 return FALSE;
2300 /***********************************************************************
2301 * ImmGetImeMenuItemsA (IMM32.@)
2303 DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType,
2304 LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
2305 DWORD dwSize)
2307 InputContextData *data = (InputContextData*)hIMC;
2308 TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
2309 lpImeParentMenu, lpImeMenu, dwSize);
2310 if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
2312 if (!is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
2313 return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
2314 (IMEMENUITEMINFOW*)lpImeParentMenu,
2315 (IMEMENUITEMINFOW*)lpImeMenu, dwSize);
2316 else
2318 IMEMENUITEMINFOW lpImeParentMenuW;
2319 IMEMENUITEMINFOW *lpImeMenuW, *parent = NULL;
2320 DWORD rc;
2322 if (lpImeParentMenu)
2323 parent = &lpImeParentMenuW;
2324 if (lpImeMenu)
2326 int count = dwSize / sizeof(LPIMEMENUITEMINFOA);
2327 dwSize = count * sizeof(IMEMENUITEMINFOW);
2328 lpImeMenuW = HeapAlloc(GetProcessHeap(), 0, dwSize);
2330 else
2331 lpImeMenuW = NULL;
2333 rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
2334 parent, lpImeMenuW, dwSize);
2336 if (lpImeParentMenu)
2338 memcpy(lpImeParentMenu,&lpImeParentMenuW,sizeof(IMEMENUITEMINFOA));
2339 lpImeParentMenu->hbmpItem = lpImeParentMenuW.hbmpItem;
2340 WideCharToMultiByte(CP_ACP, 0, lpImeParentMenuW.szString,
2341 -1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE,
2342 NULL, NULL);
2344 if (lpImeMenu && rc)
2346 int i;
2347 for (i = 0; i < rc; i++)
2349 memcpy(&lpImeMenu[i],&lpImeMenuW[1],sizeof(IMEMENUITEMINFOA));
2350 lpImeMenu[i].hbmpItem = lpImeMenuW[i].hbmpItem;
2351 WideCharToMultiByte(CP_ACP, 0, lpImeMenuW[i].szString,
2352 -1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE,
2353 NULL, NULL);
2356 HeapFree(GetProcessHeap(),0,lpImeMenuW);
2357 return rc;
2360 else
2361 return 0;
2364 /***********************************************************************
2365 * ImmGetImeMenuItemsW (IMM32.@)
2367 DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType,
2368 LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
2369 DWORD dwSize)
2371 InputContextData *data = (InputContextData*)hIMC;
2372 TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
2373 lpImeParentMenu, lpImeMenu, dwSize);
2374 if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
2376 if (is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
2377 return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
2378 lpImeParentMenu, lpImeMenu, dwSize);
2379 else
2381 IMEMENUITEMINFOA lpImeParentMenuA;
2382 IMEMENUITEMINFOA *lpImeMenuA, *parent = NULL;
2383 DWORD rc;
2385 if (lpImeParentMenu)
2386 parent = &lpImeParentMenuA;
2387 if (lpImeMenu)
2389 int count = dwSize / sizeof(LPIMEMENUITEMINFOW);
2390 dwSize = count * sizeof(IMEMENUITEMINFOA);
2391 lpImeMenuA = HeapAlloc(GetProcessHeap(), 0, dwSize);
2393 else
2394 lpImeMenuA = NULL;
2396 rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
2397 (IMEMENUITEMINFOW*)parent,
2398 (IMEMENUITEMINFOW*)lpImeMenuA, dwSize);
2400 if (lpImeParentMenu)
2402 memcpy(lpImeParentMenu,&lpImeParentMenuA,sizeof(IMEMENUITEMINFOA));
2403 lpImeParentMenu->hbmpItem = lpImeParentMenuA.hbmpItem;
2404 MultiByteToWideChar(CP_ACP, 0, lpImeParentMenuA.szString,
2405 -1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE);
2407 if (lpImeMenu && rc)
2409 int i;
2410 for (i = 0; i < rc; i++)
2412 memcpy(&lpImeMenu[i],&lpImeMenuA[1],sizeof(IMEMENUITEMINFOA));
2413 lpImeMenu[i].hbmpItem = lpImeMenuA[i].hbmpItem;
2414 MultiByteToWideChar(CP_ACP, 0, lpImeMenuA[i].szString,
2415 -1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE);
2418 HeapFree(GetProcessHeap(),0,lpImeMenuA);
2419 return rc;
2422 else
2423 return 0;
2426 /***********************************************************************
2427 * ImmLockIMC(IMM32.@)
2429 LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
2431 InputContextData *data = (InputContextData*)hIMC;
2433 if (!data)
2434 return NULL;
2435 data->dwLock++;
2436 return &data->IMC;
2439 /***********************************************************************
2440 * ImmUnlockIMC(IMM32.@)
2442 BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
2444 InputContextData *data = (InputContextData*)hIMC;
2445 data->dwLock--;
2446 return (data->dwLock!=0);
2449 /***********************************************************************
2450 * ImmGetIMCLockCount(IMM32.@)
2452 DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
2454 InputContextData *data = (InputContextData*)hIMC;
2455 return data->dwLock;
2458 /***********************************************************************
2459 * ImmCreateIMCC(IMM32.@)
2461 HIMCC WINAPI ImmCreateIMCC(DWORD size)
2463 IMCCInternal *internal;
2464 int real_size = size + sizeof(IMCCInternal);
2466 internal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, real_size);
2467 if (internal == NULL)
2468 return NULL;
2470 internal->dwSize = size;
2471 return (HIMCC)internal;
2474 /***********************************************************************
2475 * ImmDestroyIMCC(IMM32.@)
2477 HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
2479 HeapFree(GetProcessHeap(),0,block);
2480 return NULL;
2483 /***********************************************************************
2484 * ImmLockIMCC(IMM32.@)
2486 LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
2488 IMCCInternal *internal;
2489 internal = (IMCCInternal*) imcc;
2491 internal->dwLock ++;
2492 return internal + 1;
2495 /***********************************************************************
2496 * ImmUnlockIMCC(IMM32.@)
2498 BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
2500 IMCCInternal *internal;
2501 internal = (IMCCInternal*) imcc;
2503 internal->dwLock --;
2504 return (internal->dwLock!=0);
2507 /***********************************************************************
2508 * ImmGetIMCCLockCount(IMM32.@)
2510 DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
2512 IMCCInternal *internal;
2513 internal = (IMCCInternal*) imcc;
2515 return internal->dwLock;
2518 /***********************************************************************
2519 * ImmReSizeIMCC(IMM32.@)
2521 HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
2523 IMCCInternal *internal,*newone;
2524 int real_size = size + sizeof(IMCCInternal);
2526 internal = (IMCCInternal*) imcc;
2528 newone = HeapReAlloc(GetProcessHeap(), 0, internal, real_size);
2529 newone->dwSize = size;
2531 return newone;
2534 /***********************************************************************
2535 * ImmGetIMCCSize(IMM32.@)
2537 DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
2539 IMCCInternal *internal;
2540 internal = (IMCCInternal*) imcc;
2542 return internal->dwSize;
2545 /***********************************************************************
2546 * ImmGenerateMessage(IMM32.@)
2548 BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
2550 InputContextData *data = (InputContextData*)hIMC;
2552 TRACE("%i messages queued\n",data->IMC.dwNumMsgBuf);
2553 if (data->IMC.dwNumMsgBuf > 0)
2555 LPTRANSMSG lpTransMsg;
2556 INT i;
2558 lpTransMsg = (LPTRANSMSG)ImmLockIMCC(data->IMC.hMsgBuf);
2559 for (i = 0; i < data->IMC.dwNumMsgBuf; i++)
2560 ImmInternalPostIMEMessage(data, lpTransMsg[i].message, lpTransMsg[i].wParam, lpTransMsg[i].lParam);
2562 ImmUnlockIMCC(data->IMC.hMsgBuf);
2564 data->IMC.dwNumMsgBuf = 0;
2567 return TRUE;
2570 /***********************************************************************
2571 * ImmTranslateMessage(IMM32.@)
2572 * ( Undocumented, call internally and from user32.dll )
2574 BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyData)
2576 InputContextData *data;
2577 HIMC imc = ImmGetContext(hwnd);
2578 BYTE state[256];
2579 UINT scancode;
2580 LPVOID list = 0;
2581 UINT msg_count;
2582 UINT uVirtKey;
2583 static const int list_count = 10;
2585 TRACE("%p %x %x %x\n",hwnd, msg, (UINT)wParam, (UINT)lKeyData);
2587 if (imc)
2588 data = (InputContextData*)imc;
2589 else
2590 return FALSE;
2592 if (!data->immKbd->hIME || !data->immKbd->pImeToAsciiEx)
2593 return FALSE;
2595 GetKeyboardState(state);
2596 scancode = lKeyData >> 0x10 & 0xff;
2598 list = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, list_count * sizeof(TRANSMSG) + sizeof(DWORD));
2599 ((DWORD*)list)[0] = list_count;
2601 if (data->immKbd->imeInfo.fdwProperty & IME_PROP_KBD_CHAR_FIRST)
2603 WCHAR chr;
2605 if (!is_himc_ime_unicode(data))
2606 ToAscii(data->lastVK, scancode, state, &chr, 0);
2607 else
2608 ToUnicodeEx(data->lastVK, scancode, state, &chr, 1, 0, GetKeyboardLayout(0));
2609 uVirtKey = MAKELONG(data->lastVK,chr);
2611 else
2612 uVirtKey = data->lastVK;
2614 msg_count = data->immKbd->pImeToAsciiEx(uVirtKey, scancode, state, list, 0, imc);
2615 TRACE("%i messages generated\n",msg_count);
2616 if (msg_count && msg_count <= list_count)
2618 int i;
2619 LPTRANSMSG msgs = (LPTRANSMSG)((LPBYTE)list + sizeof(DWORD));
2621 for (i = 0; i < msg_count; i++)
2622 ImmInternalPostIMEMessage(data, msgs[i].message, msgs[i].wParam, msgs[i].lParam);
2624 else if (msg_count > list_count)
2625 ImmGenerateMessage(imc);
2627 HeapFree(GetProcessHeap(),0,list);
2629 data->lastVK = VK_PROCESSKEY;
2631 return (msg_count > 0);
2634 /***********************************************************************
2635 * ImmProcessKey(IMM32.@)
2636 * ( Undocumented, called from user32.dll )
2638 BOOL WINAPI ImmProcessKey(HWND hwnd, HKL hKL, UINT vKey, LPARAM lKeyData, DWORD unknown)
2640 InputContextData *data;
2641 HIMC imc = ImmGetContext(hwnd);
2642 BYTE state[256];
2644 TRACE("%p %p %x %x %x\n",hwnd, hKL, vKey, (UINT)lKeyData, unknown);
2646 if (imc)
2647 data = (InputContextData*)imc;
2648 else
2649 return FALSE;
2651 if (!data->immKbd->hIME || !data->immKbd->pImeProcessKey)
2652 return FALSE;
2654 GetKeyboardState(state);
2655 if (data->immKbd->pImeProcessKey(imc, vKey, lKeyData, state))
2657 data->lastVK = vKey;
2658 return TRUE;
2661 data->lastVK = VK_PROCESSKEY;
2662 return FALSE;