*/
#include <stdarg.h>
+#include <stdio.h>
#include "windef.h"
#include "winbase.h"
WINE_DEFAULT_DEBUG_CHANNEL(imm);
-#define FROM_IME 0xcafe1337
-
-static void (*pX11DRV_ForceXIMReset)(HWND);
-
typedef struct tagIMCCInternal
{
DWORD dwLock;
typedef struct tagInputContextData
{
- BOOL bInternalState;
- BOOL bRead;
- BOOL bInComposition;
- HFONT textfont;
-
DWORD dwLock;
INPUTCONTEXT IMC;
ImmHkl *immKbd;
+ HWND imeWnd;
+ UINT lastVK;
} InputContextData;
typedef struct _tagTRANSMSG {
LPARAM lParam;
} TRANSMSG, *LPTRANSMSG;
-static InputContextData *root_context = NULL;
-static HWND hwndDefault = NULL;
-static HANDLE hImeInst;
-static const WCHAR WC_IMECLASSNAME[] = {'I','M','E',0};
-static ATOM atIMEClass = 0;
+typedef struct _tagIMMThreadData {
+ HIMC defaultContext;
+ HWND hwndDefault;
+} IMMThreadData;
+static DWORD tlsIndex = 0;
static struct list ImmHklList = LIST_INIT(ImmHklList);
/* MSIME messages */
static UINT WM_MSIME_DOCUMENTFEED;
static const WCHAR szwWineIMCProperty[] = {'W','i','n','e','I','m','m','H','I','M','C','P','r','o','p','e','r','t','y',0};
-/*
- * prototypes
- */
-static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
- LPARAM lParam);
-static void UpdateDataInDefaultIMEWindow(HWND hwnd, BOOL showable);
-static void ImmInternalPostIMEMessage(InputContextData*, UINT, WPARAM, LPARAM);
-static void ImmInternalSetOpenStatus(BOOL fOpen);
-static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len);
+
+static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0};
+static const WCHAR szLayoutTextW[] = {'L','a','y','o','u','t',' ','T','e','x','t',0};
+static const WCHAR szImeRegFmt[] = {'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','l','x',0};
+
+
+#define is_himc_ime_unicode(p) (p->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE)
+#define is_kbd_ime_unicode(p) (p->imeInfo.fdwProperty & IME_PROP_UNICODE)
+
+static BOOL IMM_DestroyContext(HIMC hIMC);
+
+static inline WCHAR *strdupAtoW( const char *str )
+{
+ WCHAR *ret = NULL;
+ if (str)
+ {
+ DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
+ if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+ MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
+ }
+ return ret;
+}
+
+static inline CHAR *strdupWtoA( const WCHAR *str )
+{
+ CHAR *ret = NULL;
+ if (str)
+ {
+ DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
+ if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
+ WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
+ }
+ return ret;
+}
+
+static DWORD convert_candidatelist_WtoA(
+ LPCANDIDATELIST lpSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen)
+{
+ DWORD ret, i, len;
+
+ ret = FIELD_OFFSET( CANDIDATELIST, dwOffset[lpSrc->dwCount] );
+ if ( lpDst && dwBufLen > 0 )
+ {
+ *lpDst = *lpSrc;
+ lpDst->dwOffset[0] = ret;
+ }
+
+ for ( i = 0; i < lpSrc->dwCount; i++)
+ {
+ LPBYTE src = (LPBYTE)lpSrc + lpSrc->dwOffset[i];
+
+ if ( lpDst && dwBufLen > 0 )
+ {
+ LPBYTE dest = (LPBYTE)lpDst + lpDst->dwOffset[i];
+
+ len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1,
+ (LPSTR)dest, dwBufLen, NULL, NULL);
+
+ if ( i + 1 < lpSrc->dwCount )
+ lpDst->dwOffset[i+1] = lpDst->dwOffset[i] + len * sizeof(char);
+ dwBufLen -= len * sizeof(char);
+ }
+ else
+ len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, NULL, 0, NULL, NULL);
+
+ ret += len * sizeof(char);
+ }
+
+ if ( lpDst )
+ lpDst->dwSize = ret;
+
+ return ret;
+}
+
+static DWORD convert_candidatelist_AtoW(
+ LPCANDIDATELIST lpSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen)
+{
+ DWORD ret, i, len;
+
+ ret = FIELD_OFFSET( CANDIDATELIST, dwOffset[lpSrc->dwCount] );
+ if ( lpDst && dwBufLen > 0 )
+ {
+ *lpDst = *lpSrc;
+ lpDst->dwOffset[0] = ret;
+ }
+
+ for ( i = 0; i < lpSrc->dwCount; i++)
+ {
+ LPBYTE src = (LPBYTE)lpSrc + lpSrc->dwOffset[i];
+
+ if ( lpDst && dwBufLen > 0 )
+ {
+ LPBYTE dest = (LPBYTE)lpDst + lpDst->dwOffset[i];
+
+ len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1,
+ (LPWSTR)dest, dwBufLen);
+
+ if ( i + 1 < lpSrc->dwCount )
+ lpDst->dwOffset[i+1] = lpDst->dwOffset[i] + len * sizeof(WCHAR);
+ dwBufLen -= len * sizeof(WCHAR);
+ }
+ else
+ len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1, NULL, 0);
+
+ ret += len * sizeof(WCHAR);
+ }
+
+ if ( lpDst )
+ lpDst->dwSize = ret;
+
+ return ret;
+}
+
+static IMMThreadData* IMM_GetThreadData(void)
+{
+ IMMThreadData* data = TlsGetValue(tlsIndex);
+ if (!data)
+ {
+ data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(IMMThreadData));
+ TlsSetValue(tlsIndex,data);
+ TRACE("Thread Data Created\n");
+ }
+ return data;
+}
+
+static void IMM_FreeThreadData(void)
+{
+ IMMThreadData* data = TlsGetValue(tlsIndex);
+ if (data)
+ {
+ IMM_DestroyContext(data->defaultContext);
+ DestroyWindow(data->hwndDefault);
+ HeapFree(GetProcessHeap(),0,data);
+ TRACE("Thread Data Destroyed\n");
+ }
+}
+
+static HMODULE LoadDefaultWineIME(void)
+{
+ char buffer[MAX_PATH], libname[32], *name, *next;
+ HMODULE module = 0;
+ HKEY hkey;
+
+ TRACE("Attempting to fall back to wine default IME\n");
+
+ strcpy( buffer, "x11" ); /* default value */
+ /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
+ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey ))
+ {
+ DWORD type, count = sizeof(buffer);
+ RegQueryValueExA( hkey, "Ime", 0, &type, (LPBYTE) buffer, &count );
+ RegCloseKey( hkey );
+ }
+
+ name = buffer;
+ while (name)
+ {
+ next = strchr( name, ',' );
+ if (next) *next++ = 0;
+
+ snprintf( libname, sizeof(libname), "wine%s.drv", name );
+ if ((module = LoadLibraryA( libname )) != 0) break;
+ name = next;
+ }
+
+ return module;
+}
/* ImmHkl loading and freeing */
#define LOAD_FUNCPTR(f) if((ptr->p##f = (LPVOID)GetProcAddress(ptr->hIME, #f)) == NULL){WARN("Can't find function %s in ime\n", #f);}
ImmHkl *ptr;
WCHAR filename[MAX_PATH];
- TRACE("Seeking ime for keyboard 0x%x\n",(unsigned)hkl);
+ TRACE("Seeking ime for keyboard %p\n",hkl);
LIST_FOR_EACH_ENTRY(ptr, &ImmHklList, ImmHkl, entry)
{
ptr->hkl = hkl;
if (ImmGetIMEFileNameW(hkl, filename, MAX_PATH)) ptr->hIME = LoadLibraryW(filename);
+ if (!ptr->hIME)
+ ptr->hIME = LoadDefaultWineIME();
if (ptr->hIME)
{
LOAD_FUNCPTR(ImeInquire);
- LOAD_FUNCPTR(ImeDestroy);
- LOAD_FUNCPTR(ImeSelect);
- if (!ptr->pImeInquire || !ptr->pImeDestroy || !ptr->pImeSelect)
+ if (!ptr->pImeInquire || !ptr->pImeInquire(&ptr->imeInfo, ptr->imeClassName, NULL))
{
FreeLibrary(ptr->hIME);
ptr->hIME = NULL;
}
else
{
- ptr->pImeInquire(&ptr->imeInfo, ptr->imeClassName, NULL);
- LOAD_FUNCPTR(ImeConfigure);
- LOAD_FUNCPTR(ImeEscape);
- LOAD_FUNCPTR(ImeSetActiveContext);
- LOAD_FUNCPTR(ImeToAsciiEx);
- LOAD_FUNCPTR(NotifyIME);
- LOAD_FUNCPTR(ImeRegisterWord);
- LOAD_FUNCPTR(ImeUnregisterWord);
- LOAD_FUNCPTR(ImeEnumRegisterWord);
- LOAD_FUNCPTR(ImeSetCompositionString);
- LOAD_FUNCPTR(ImeConversionList);
- LOAD_FUNCPTR(ImeProcessKey);
- LOAD_FUNCPTR(ImeGetRegisterWordStyle);
- LOAD_FUNCPTR(ImeGetImeMenuItems);
+ LOAD_FUNCPTR(ImeDestroy);
+ LOAD_FUNCPTR(ImeSelect);
+ if (!ptr->pImeSelect || !ptr->pImeDestroy)
+ {
+ FreeLibrary(ptr->hIME);
+ ptr->hIME = NULL;
+ }
+ else
+ {
+ LOAD_FUNCPTR(ImeConfigure);
+ LOAD_FUNCPTR(ImeEscape);
+ LOAD_FUNCPTR(ImeSetActiveContext);
+ LOAD_FUNCPTR(ImeToAsciiEx);
+ LOAD_FUNCPTR(NotifyIME);
+ LOAD_FUNCPTR(ImeRegisterWord);
+ LOAD_FUNCPTR(ImeUnregisterWord);
+ LOAD_FUNCPTR(ImeEnumRegisterWord);
+ LOAD_FUNCPTR(ImeSetCompositionString);
+ LOAD_FUNCPTR(ImeConversionList);
+ LOAD_FUNCPTR(ImeProcessKey);
+ LOAD_FUNCPTR(ImeGetRegisterWordStyle);
+ LOAD_FUNCPTR(ImeGetImeMenuItems);
+ /* make sure our classname is WCHAR */
+ if (!is_kbd_ime_unicode(ptr))
+ {
+ WCHAR bufW[17];
+ MultiByteToWideChar(CP_ACP, 0, (LPSTR)ptr->imeClassName,
+ -1, bufW, 17);
+ lstrcpyW(ptr->imeClassName, bufW);
+ }
+ }
}
}
list_add_head(&ImmHklList,&ptr->entry);
}
}
-static VOID IMM_PostResult(InputContextData *data)
-{
- unsigned int i;
- LPCOMPOSITIONSTRING compstr;
- LPBYTE compdata;
- LPWSTR ResultStr;
- HIMCC newCompStr;
-
- TRACE("Posting result as IME_CHAR\n");
- compdata = ImmLockIMCC(root_context->IMC.hCompStr);
- compstr = (LPCOMPOSITIONSTRING)compdata;
- ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
-
- for (i = 0; i < compstr->dwResultStrLen; i++)
- ImmInternalPostIMEMessage (root_context, WM_IME_CHAR, ResultStr[i], 1);
-
- ImmUnlockIMCC(root_context->IMC.hCompStr);
-
- /* clear the buffer */
- newCompStr = updateResultStr(root_context->IMC.hCompStr, NULL, 0);
- ImmDestroyIMCC(root_context->IMC.hCompStr);
- root_context->IMC.hCompStr = newCompStr;
-}
-
-static void IMM_Register(void)
-{
- WNDCLASSW wndClass;
- ZeroMemory(&wndClass, sizeof(WNDCLASSW));
- wndClass.style = CS_GLOBALCLASS | CS_IME | CS_HREDRAW | CS_VREDRAW;
- wndClass.lpfnWndProc = (WNDPROC) IME_WindowProc;
- wndClass.cbClsExtra = 0;
- wndClass.cbWndExtra = 0;
- wndClass.hInstance = hImeInst;
- wndClass.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
- wndClass.hIcon = NULL;
- wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
- wndClass.lpszMenuName = 0;
- wndClass.lpszClassName = WC_IMECLASSNAME;
- atIMEClass = RegisterClassW(&wndClass);
-}
-
-static void IMM_Unregister(void)
-{
- if (atIMEClass) {
- UnregisterClassW(WC_IMECLASSNAME, NULL);
- }
-}
-
static void IMM_RegisterMessages(void)
{
WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
}
-
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
{
- HMODULE x11drv;
-
TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
- DisableThreadLibraryCalls(hInstDLL);
- hImeInst = hInstDLL;
IMM_RegisterMessages();
- x11drv = GetModuleHandleA("winex11.drv");
- if (x11drv) pX11DRV_ForceXIMReset = (void *)GetProcAddress( x11drv, "ForceXIMReset");
+ tlsIndex = TlsAlloc();
+ if (tlsIndex == TLS_OUT_OF_INDEXES)
+ return FALSE;
+ break;
+ case DLL_THREAD_ATTACH:
+ break;
+ case DLL_THREAD_DETACH:
+ IMM_FreeThreadData();
break;
case DLL_PROCESS_DETACH:
- if (hwndDefault)
- {
- DestroyWindow(hwndDefault);
- hwndDefault = 0;
- }
- IMM_Unregister();
+ IMM_FreeThreadData();
IMM_FreeAllImmHkl();
+ TlsFree(tlsIndex);
break;
}
return TRUE;
HIMCC rc;
LPCOMPOSITIONSTRING ptr;
rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
- ptr = (LPCOMPOSITIONSTRING)ImmLockIMCC(rc);
+ ptr = ImmLockIMCC(rc);
memset(ptr,0,sizeof(COMPOSITIONSTRING));
ptr->dwSize = sizeof(COMPOSITIONSTRING);
ImmUnlockIMCC(rc);
return rc;
}
-static void ImmInternalSetOpenStatus(BOOL fOpen)
-{
- TRACE("Setting internal state to %s\n",(fOpen)?"OPEN":"CLOSED");
-
- if (root_context->IMC.fOpen && fOpen == FALSE)
- {
- ShowWindow(hwndDefault,SW_HIDE);
- ImmDestroyIMCC(root_context->IMC.hCompStr);
- root_context->IMC.hCompStr = ImmCreateBlankCompStr();
- }
-
- root_context->IMC.fOpen = fOpen;
- root_context->bInternalState = fOpen;
-
- ImmInternalSendIMENotify(root_context, IMN_SETOPENSTATUS, 0);
-}
-
-static int updateField(DWORD origLen, DWORD origOffset, DWORD currentOffset,
- LPBYTE target, LPBYTE source, DWORD* lenParam,
- DWORD* offsetParam, BOOL wchars )
-{
- if (origLen > 0 && origOffset > 0)
- {
- int truelen = origLen;
- if (wchars)
- truelen *= sizeof(WCHAR);
-
- memcpy(&target[currentOffset], &source[origOffset], truelen);
-
- *lenParam = origLen;
- *offsetParam = currentOffset;
- currentOffset += truelen;
- }
- return currentOffset;
-}
-
-static HIMCC updateCompStr(HIMCC old, LPWSTR compstr, DWORD len)
-{
- /* we need to make sure the CompStr, CompClaus and CompAttr fields are all
- * set and correct */
- int needed_size;
- HIMCC rc;
- LPBYTE newdata = NULL;
- LPBYTE olddata = NULL;
- LPCOMPOSITIONSTRING new_one;
- LPCOMPOSITIONSTRING lpcs = NULL;
- INT current_offset = 0;
-
- TRACE("%s, %i\n",debugstr_wn(compstr,len),len);
-
- if (old == NULL && compstr == NULL && len == 0)
- return NULL;
-
- if (old != NULL)
- {
- olddata = ImmLockIMCC(old);
- lpcs = (LPCOMPOSITIONSTRING)olddata;
- }
-
- needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
- len + sizeof(DWORD) * 2;
-
- if (lpcs != NULL)
- {
- needed_size += lpcs->dwCompReadAttrLen;
- needed_size += lpcs->dwCompReadClauseLen;
- needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
- needed_size += lpcs->dwResultReadClauseLen;
- needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
- needed_size += lpcs->dwResultClauseLen;
- needed_size += lpcs->dwResultStrLen * sizeof(DWORD);
- needed_size += lpcs->dwPrivateSize;
- }
- rc = ImmCreateIMCC(needed_size);
- newdata = ImmLockIMCC(rc);
- new_one = (LPCOMPOSITIONSTRING)newdata;
-
- new_one->dwSize = needed_size;
- current_offset = sizeof(COMPOSITIONSTRING);
- if (lpcs != NULL)
- {
- current_offset = updateField(lpcs->dwCompReadAttrLen,
- lpcs->dwCompReadAttrOffset,
- current_offset, newdata, olddata,
- &new_one->dwCompReadAttrLen,
- &new_one->dwCompReadAttrOffset, FALSE);
-
- current_offset = updateField(lpcs->dwCompReadClauseLen,
- lpcs->dwCompReadClauseOffset,
- current_offset, newdata, olddata,
- &new_one->dwCompReadClauseLen,
- &new_one->dwCompReadClauseOffset, FALSE);
-
- current_offset = updateField(lpcs->dwCompReadStrLen,
- lpcs->dwCompReadStrOffset,
- current_offset, newdata, olddata,
- &new_one->dwCompReadStrLen,
- &new_one->dwCompReadStrOffset, TRUE);
-
- /* new CompAttr, CompClause, CompStr, dwCursorPos */
- new_one->dwDeltaStart = 0;
-
- current_offset = updateField(lpcs->dwResultReadClauseLen,
- lpcs->dwResultReadClauseOffset,
- current_offset, newdata, olddata,
- &new_one->dwResultReadClauseLen,
- &new_one->dwResultReadClauseOffset, FALSE);
-
- current_offset = updateField(lpcs->dwResultReadStrLen,
- lpcs->dwResultReadStrOffset,
- current_offset, newdata, olddata,
- &new_one->dwResultReadStrLen,
- &new_one->dwResultReadStrOffset, TRUE);
-
- current_offset = updateField(lpcs->dwResultClauseLen,
- lpcs->dwResultClauseOffset,
- current_offset, newdata, olddata,
- &new_one->dwResultClauseLen,
- &new_one->dwResultClauseOffset, FALSE);
-
- current_offset = updateField(lpcs->dwResultStrLen,
- lpcs->dwResultStrOffset,
- current_offset, newdata, olddata,
- &new_one->dwResultStrLen,
- &new_one->dwResultStrOffset, TRUE);
-
- current_offset = updateField(lpcs->dwPrivateSize,
- lpcs->dwPrivateOffset,
- current_offset, newdata, olddata,
- &new_one->dwPrivateSize,
- &new_one->dwPrivateOffset, FALSE);
- }
-
- /* set new data */
- /* CompAttr */
- new_one->dwCompAttrLen = len;
- if (len > 0)
- {
- new_one->dwCompAttrOffset = current_offset;
- memset(&newdata[current_offset],ATTR_INPUT,len);
- current_offset += len;
- }
-
- /* CompClause */
- if (len > 0)
- {
- new_one->dwCompClauseLen = sizeof(DWORD) * 2;
- new_one->dwCompClauseOffset = current_offset;
- *(DWORD*)(&newdata[current_offset]) = 0;
- current_offset += sizeof(DWORD);
- *(DWORD*)(&newdata[current_offset]) = len;
- current_offset += sizeof(DWORD);
- }
-
- /* CompStr */
- new_one->dwCompStrLen = len;
- if (len > 0)
- {
- new_one->dwCompStrOffset = current_offset;
- memcpy(&newdata[current_offset],compstr,len*sizeof(WCHAR));
- }
-
- /* CursorPos */
- new_one->dwCursorPos = len;
-
- ImmUnlockIMCC(rc);
- if (lpcs)
- ImmUnlockIMCC(old);
-
- return rc;
-}
-
-static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len)
-{
- /* we need to make sure the ResultStr and ResultClause fields are all
- * set and correct */
- int needed_size;
- HIMCC rc;
- LPBYTE newdata = NULL;
- LPBYTE olddata = NULL;
- LPCOMPOSITIONSTRING new_one;
- LPCOMPOSITIONSTRING lpcs = NULL;
- INT current_offset = 0;
-
- TRACE("%s, %i\n",debugstr_wn(resultstr,len),len);
-
- if (old == NULL && resultstr == NULL && len == 0)
- return NULL;
-
- if (old != NULL)
- {
- olddata = ImmLockIMCC(old);
- lpcs = (LPCOMPOSITIONSTRING)olddata;
- }
-
- needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
- sizeof(DWORD) * 2;
-
- if (lpcs != NULL)
- {
- needed_size += lpcs->dwCompReadAttrLen;
- needed_size += lpcs->dwCompReadClauseLen;
- needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
- needed_size += lpcs->dwCompAttrLen;
- needed_size += lpcs->dwCompClauseLen;
- needed_size += lpcs->dwCompStrLen * sizeof(DWORD);
- needed_size += lpcs->dwResultReadClauseLen;
- needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
- needed_size += lpcs->dwPrivateSize;
- }
- rc = ImmCreateIMCC(needed_size);
- newdata = ImmLockIMCC(rc);
- new_one = (LPCOMPOSITIONSTRING)newdata;
-
- new_one->dwSize = needed_size;
- current_offset = sizeof(COMPOSITIONSTRING);
- if (lpcs != NULL)
- {
- current_offset = updateField(lpcs->dwCompReadAttrLen,
- lpcs->dwCompReadAttrOffset,
- current_offset, newdata, olddata,
- &new_one->dwCompReadAttrLen,
- &new_one->dwCompReadAttrOffset, FALSE);
-
- current_offset = updateField(lpcs->dwCompReadClauseLen,
- lpcs->dwCompReadClauseOffset,
- current_offset, newdata, olddata,
- &new_one->dwCompReadClauseLen,
- &new_one->dwCompReadClauseOffset, FALSE);
-
- current_offset = updateField(lpcs->dwCompReadStrLen,
- lpcs->dwCompReadStrOffset,
- current_offset, newdata, olddata,
- &new_one->dwCompReadStrLen,
- &new_one->dwCompReadStrOffset, TRUE);
-
- current_offset = updateField(lpcs->dwCompAttrLen,
- lpcs->dwCompAttrOffset,
- current_offset, newdata, olddata,
- &new_one->dwCompAttrLen,
- &new_one->dwCompAttrOffset, FALSE);
-
- current_offset = updateField(lpcs->dwCompClauseLen,
- lpcs->dwCompClauseOffset,
- current_offset, newdata, olddata,
- &new_one->dwCompClauseLen,
- &new_one->dwCompClauseOffset, FALSE);
-
- current_offset = updateField(lpcs->dwCompStrLen,
- lpcs->dwCompStrOffset,
- current_offset, newdata, olddata,
- &new_one->dwCompStrLen,
- &new_one->dwCompStrOffset, TRUE);
-
- new_one->dwCursorPos = lpcs->dwCursorPos;
- new_one->dwDeltaStart = 0;
-
- current_offset = updateField(lpcs->dwResultReadClauseLen,
- lpcs->dwResultReadClauseOffset,
- current_offset, newdata, olddata,
- &new_one->dwResultReadClauseLen,
- &new_one->dwResultReadClauseOffset, FALSE);
-
- current_offset = updateField(lpcs->dwResultReadStrLen,
- lpcs->dwResultReadStrOffset,
- current_offset, newdata, olddata,
- &new_one->dwResultReadStrLen,
- &new_one->dwResultReadStrOffset, TRUE);
-
- /* new ResultClause , ResultStr */
-
- current_offset = updateField(lpcs->dwPrivateSize,
- lpcs->dwPrivateOffset,
- current_offset, newdata, olddata,
- &new_one->dwPrivateSize,
- &new_one->dwPrivateOffset, FALSE);
- }
-
- /* set new data */
- /* ResultClause */
- if (len > 0)
- {
- new_one->dwResultClauseLen = sizeof(DWORD) * 2;
- new_one->dwResultClauseOffset = current_offset;
- *(DWORD*)(&newdata[current_offset]) = 0;
- current_offset += sizeof(DWORD);
- *(DWORD*)(&newdata[current_offset]) = len;
- current_offset += sizeof(DWORD);
- }
-
- /* ResultStr */
- new_one->dwResultStrLen = len;
- if (len > 0)
- {
- new_one->dwResultStrOffset = current_offset;
- memcpy(&newdata[current_offset],resultstr,len*sizeof(WCHAR));
- }
- ImmUnlockIMCC(rc);
- if (lpcs)
- ImmUnlockIMCC(old);
-
- return rc;
-}
-
-
-
/***********************************************************************
* ImmAssociateContext (IMM32.@)
*/
HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
{
HIMC old = NULL;
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
TRACE("(%p, %p):\n", hWnd, hIMC);
- /*
- * WINE SPECIFIC! MAY CONFLICT
- * associate the root context we have an XIM created
- */
- if (hWnd == 0x000)
- {
- root_context = (InputContextData*)hIMC;
- }
+ if (!IMM_GetThreadData()->defaultContext)
+ IMM_GetThreadData()->defaultContext = ImmCreateContext();
/*
* If already associated just return
if (hWnd)
{
- old = (HIMC)RemovePropW(hWnd,szwWineIMCProperty);
+ old = RemovePropW(hWnd,szwWineIMCProperty);
if (old == NULL)
- old = (HIMC)root_context;
+ old = IMM_GetThreadData()->defaultContext;
else if (old == (HIMC)-1)
old = NULL;
- if (hIMC != (HIMC)root_context)
+ if (hIMC != IMM_GetThreadData()->defaultContext)
{
if (hIMC == NULL) /* Meaning disable imm for that window*/
SetPropW(hWnd,szwWineIMCProperty,(HANDLE)-1);
else
- SetPropW(hWnd,szwWineIMCProperty,(HANDLE)hIMC);
+ SetPropW(hWnd,szwWineIMCProperty,hIMC);
+ }
+
+ if (old)
+ {
+ InputContextData *old_data = old;
+ if (old_data->IMC.hWnd == hWnd)
+ old_data->IMC.hWnd = NULL;
}
}
return old;
}
+
+/*
+ * Helper function for ImmAssociateContextEx
+ */
+static BOOL CALLBACK _ImmAssociateContextExEnumProc(HWND hwnd, LPARAM lParam)
+{
+ HIMC hImc = (HIMC)lParam;
+ ImmAssociateContext(hwnd,hImc);
+ return TRUE;
+}
+
/***********************************************************************
* ImmAssociateContextEx (IMM32.@)
*/
BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
{
- FIXME("(%p, %p, %d): stub\n", hWnd, hIMC, dwFlags);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ TRACE("(%p, %p, %d): stub\n", hWnd, hIMC, dwFlags);
+
+ if (!IMM_GetThreadData()->defaultContext)
+ IMM_GetThreadData()->defaultContext = ImmCreateContext();
+
+ if (dwFlags == IACE_DEFAULT)
+ {
+ ImmAssociateContext(hWnd,IMM_GetThreadData()->defaultContext);
+ return TRUE;
+ }
+ else if (dwFlags == IACE_IGNORENOCONTEXT)
+ {
+ if (GetPropW(hWnd,szwWineIMCProperty))
+ ImmAssociateContext(hWnd,hIMC);
+ return TRUE;
+ }
+ else if (dwFlags == IACE_CHILDREN)
+ {
+ EnumChildWindows(hWnd,_ImmAssociateContextExEnumProc,(LPARAM)hIMC);
+ return TRUE;
+ }
+ else
+ {
+ ERR("Unknown dwFlags 0x%x\n",dwFlags);
+ return FALSE;
+ }
}
/***********************************************************************
BOOL WINAPI ImmConfigureIMEA(
HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
{
- FIXME("(%p, %p, %d, %p): stub\n",
- hKL, hWnd, dwMode, lpData
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+
+ TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
+
+ if (dwMode == IME_CONFIG_REGISTERWORD && !lpData)
+ return FALSE;
+
+ if (immHkl->hIME && immHkl->pImeConfigure)
+ {
+ if (dwMode != IME_CONFIG_REGISTERWORD || !is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeConfigure(hKL,hWnd,dwMode,lpData);
+ else
+ {
+ REGISTERWORDW rww;
+ REGISTERWORDA *rwa = lpData;
+ BOOL rc;
+
+ rww.lpReading = strdupAtoW(rwa->lpReading);
+ rww.lpWord = strdupAtoW(rwa->lpWord);
+ rc = immHkl->pImeConfigure(hKL,hWnd,dwMode,&rww);
+ HeapFree(GetProcessHeap(),0,rww.lpReading);
+ HeapFree(GetProcessHeap(),0,rww.lpWord);
+ return rc;
+ }
+ }
+ else
+ return FALSE;
}
/***********************************************************************
BOOL WINAPI ImmConfigureIMEW(
HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
{
- FIXME("(%p, %p, %d, %p): stub\n",
- hKL, hWnd, dwMode, lpData
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+
+ TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData);
+
+ if (dwMode == IME_CONFIG_REGISTERWORD && !lpData)
+ return FALSE;
+
+ if (immHkl->hIME && immHkl->pImeConfigure)
+ {
+ if (dwMode != IME_CONFIG_REGISTERWORD || is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeConfigure(hKL,hWnd,dwMode,lpData);
+ else
+ {
+ REGISTERWORDW *rww = lpData;
+ REGISTERWORDA rwa;
+ BOOL rc;
+
+ rwa.lpReading = strdupWtoA(rww->lpReading);
+ rwa.lpWord = strdupWtoA(rww->lpWord);
+ rc = immHkl->pImeConfigure(hKL,hWnd,dwMode,&rwa);
+ HeapFree(GetProcessHeap(),0,rwa.lpReading);
+ HeapFree(GetProcessHeap(),0,rwa.lpWord);
+ return rc;
+ }
+ }
+ else
+ return FALSE;
}
/***********************************************************************
HIMC WINAPI ImmCreateContext(void)
{
InputContextData *new_context;
+ LPGUIDELINE gl;
+ LPCANDIDATEINFO ci;
new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
/* Load the IME */
new_context->immKbd = IMM_GetImmHkl(GetKeyboardLayout(0));
- /*
- * Once we depend on the IME for all the processing like we should
- * these will become hard errors and result in creation failures
- */
if (!new_context->immKbd->hIME)
+ {
TRACE("IME dll could not be loaded\n");
+ HeapFree(GetProcessHeap(),0,new_context);
+ return 0;
+ }
- /* hCompStr is never NULL */
+ /* the HIMCCs are never NULL */
new_context->IMC.hCompStr = ImmCreateBlankCompStr();
- new_context->IMC.hMsgBuf = ImmCreateIMCC(1);
+ new_context->IMC.hMsgBuf = ImmCreateIMCC(0);
+ new_context->IMC.hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
+ ci = ImmLockIMCC(new_context->IMC.hCandInfo);
+ memset(ci,0,sizeof(CANDIDATEINFO));
+ ci->dwSize = sizeof(CANDIDATEINFO);
+ ImmUnlockIMCC(new_context->IMC.hCandInfo);
+ new_context->IMC.hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
+ gl = ImmLockIMCC(new_context->IMC.hGuideLine);
+ memset(gl,0,sizeof(GUIDELINE));
+ gl->dwSize = sizeof(GUIDELINE);
+ ImmUnlockIMCC(new_context->IMC.hGuideLine);
/* Initialize the IME Private */
new_context->IMC.hPrivate = ImmCreateIMCC(new_context->immKbd->imeInfo.dwPrivateDataSize);
- if (new_context->immKbd->hIME &&
- !new_context->immKbd->pImeSelect(new_context, TRUE))
+ if (!new_context->immKbd->pImeSelect(new_context, TRUE))
{
TRACE("Selection of IME failed\n");
- ImmDestroyContext(new_context);
+ IMM_DestroyContext(new_context);
return 0;
}
+ SendMessageW(GetFocus(), WM_IME_SELECT, TRUE, (LPARAM)GetKeyboardLayout(0));
new_context->immKbd->uSelected++;
- TRACE("Created context 0x%x\n",(UINT)new_context);
+ TRACE("Created context %p\n",new_context);
- return (HIMC)new_context;
+ return new_context;
}
-/***********************************************************************
- * ImmDestroyContext (IMM32.@)
- */
-BOOL WINAPI ImmDestroyContext(HIMC hIMC)
+static BOOL IMM_DestroyContext(HIMC hIMC)
{
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
TRACE("Destroying %p\n",hIMC);
if (hIMC)
{
data->immKbd->uSelected --;
- if (data->immKbd->hIME)
- data->immKbd->pImeSelect(hIMC, FALSE);
+ data->immKbd->pImeSelect(hIMC, FALSE);
+ SendMessageW(data->IMC.hWnd, WM_IME_SELECT, FALSE, (LPARAM)GetKeyboardLayout(0));
+
+ if (IMM_GetThreadData()->hwndDefault == data->imeWnd)
+ IMM_GetThreadData()->hwndDefault = NULL;
+ DestroyWindow(data->imeWnd);
ImmDestroyIMCC(data->IMC.hCompStr);
ImmDestroyIMCC(data->IMC.hCandInfo);
ImmDestroyIMCC(data->IMC.hPrivate);
ImmDestroyIMCC(data->IMC.hMsgBuf);
- if (data->textfont)
- {
- DeleteObject(data->textfont);
- data->textfont = NULL;
- }
-
HeapFree(GetProcessHeap(),0,data);
}
return TRUE;
}
+/***********************************************************************
+ * ImmDestroyContext (IMM32.@)
+ */
+BOOL WINAPI ImmDestroyContext(HIMC hIMC)
+{
+ if (hIMC != IMM_GetThreadData()->defaultContext)
+ return IMM_DestroyContext(hIMC);
+ else
+ return FALSE;
+}
+
/***********************************************************************
* ImmDisableIME (IMM32.@)
*/
LPCSTR lpszReading, DWORD dwStyle,
LPCSTR lpszRegister, LPVOID lpData)
{
- FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
- hKL, lpfnEnumProc,
- debugstr_a(lpszReading), dwStyle,
- debugstr_a(lpszRegister), lpData
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ TRACE("(%p, %p, %s, %d, %s, %p):\n", hKL, lpfnEnumProc,
+ debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister), lpData);
+ if (immHkl->hIME && immHkl->pImeEnumRegisterWord)
+ {
+ if (!is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeEnumRegisterWord((REGISTERWORDENUMPROCW)lpfnEnumProc,
+ (LPCWSTR)lpszReading, dwStyle, (LPCWSTR)lpszRegister, lpData);
+ else
+ {
+ LPWSTR lpszwReading = strdupAtoW(lpszReading);
+ LPWSTR lpszwRegister = strdupAtoW(lpszRegister);
+ BOOL rc;
+
+ rc = immHkl->pImeEnumRegisterWord((REGISTERWORDENUMPROCW)lpfnEnumProc,
+ lpszwReading, dwStyle, lpszwRegister,
+ lpData);
+
+ HeapFree(GetProcessHeap(),0,lpszwReading);
+ HeapFree(GetProcessHeap(),0,lpszwRegister);
+ return rc;
+ }
+ }
+ else
+ return 0;
}
/***********************************************************************
LPCWSTR lpszReading, DWORD dwStyle,
LPCWSTR lpszRegister, LPVOID lpData)
{
- FIXME("(%p, %p, %s, %d, %s, %p): stub\n",
- hKL, lpfnEnumProc,
- debugstr_w(lpszReading), dwStyle,
- debugstr_w(lpszRegister), lpData
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ TRACE("(%p, %p, %s, %d, %s, %p):\n", hKL, lpfnEnumProc,
+ debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister), lpData);
+ if (immHkl->hIME && immHkl->pImeEnumRegisterWord)
+ {
+ if (is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeEnumRegisterWord(lpfnEnumProc, lpszReading, dwStyle,
+ lpszRegister, lpData);
+ else
+ {
+ LPSTR lpszaReading = strdupWtoA(lpszReading);
+ LPSTR lpszaRegister = strdupWtoA(lpszRegister);
+ BOOL rc;
+
+ rc = immHkl->pImeEnumRegisterWord(lpfnEnumProc, (LPCWSTR)lpszaReading,
+ dwStyle, (LPCWSTR)lpszaRegister, lpData);
+
+ HeapFree(GetProcessHeap(),0,lpszaReading);
+ HeapFree(GetProcessHeap(),0,lpszaRegister);
+ return rc;
+ }
+ }
+ else
+ return 0;
+}
+
+static inline BOOL EscapeRequiresWA(UINT uEscape)
+{
+ if (uEscape == IME_ESC_GET_EUDC_DICTIONARY ||
+ uEscape == IME_ESC_SET_EUDC_DICTIONARY ||
+ uEscape == IME_ESC_IME_NAME ||
+ uEscape == IME_ESC_GETHELPFILENAME)
+ return TRUE;
+ return FALSE;
}
/***********************************************************************
HKL hKL, HIMC hIMC,
UINT uEscape, LPVOID lpData)
{
- FIXME("(%p, %p, %d, %p): stub\n",
- hKL, hIMC, uEscape, lpData
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
+
+ if (immHkl->hIME && immHkl->pImeEscape)
+ {
+ if (!EscapeRequiresWA(uEscape) || !is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeEscape(hIMC,uEscape,lpData);
+ else
+ {
+ WCHAR buffer[81]; /* largest required buffer should be 80 */
+ LRESULT rc;
+ if (uEscape == IME_ESC_SET_EUDC_DICTIONARY)
+ {
+ MultiByteToWideChar(CP_ACP,0,lpData,-1,buffer,81);
+ rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
+ }
+ else
+ {
+ rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
+ WideCharToMultiByte(CP_ACP,0,buffer,-1,lpData,80, NULL, NULL);
+ }
+ return rc;
+ }
+ }
+ else
+ return 0;
}
/***********************************************************************
HKL hKL, HIMC hIMC,
UINT uEscape, LPVOID lpData)
{
- FIXME("(%p, %p, %d, %p): stub\n",
- hKL, hIMC, uEscape, lpData
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
+
+ if (immHkl->hIME && immHkl->pImeEscape)
+ {
+ if (!EscapeRequiresWA(uEscape) || is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeEscape(hIMC,uEscape,lpData);
+ else
+ {
+ CHAR buffer[81]; /* largest required buffer should be 80 */
+ LRESULT rc;
+ if (uEscape == IME_ESC_SET_EUDC_DICTIONARY)
+ {
+ WideCharToMultiByte(CP_ACP,0,lpData,-1,buffer,81, NULL, NULL);
+ rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
+ }
+ else
+ {
+ rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
+ MultiByteToWideChar(CP_ACP,0,buffer,-1,lpData,80);
+ }
+ return rc;
+ }
+ }
+ else
+ return 0;
}
/***********************************************************************
* ImmGetCandidateListA (IMM32.@)
*/
DWORD WINAPI ImmGetCandidateListA(
- HIMC hIMC, DWORD deIndex,
+ HIMC hIMC, DWORD dwIndex,
LPCANDIDATELIST lpCandList, DWORD dwBufLen)
{
- FIXME("(%p, %d, %p, %d): stub\n",
- hIMC, deIndex,
- lpCandList, dwBufLen
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ InputContextData *data = hIMC;
+ LPCANDIDATEINFO candinfo;
+ LPCANDIDATELIST candlist;
+ DWORD ret = 0;
+
+ TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
+
+ if (!data || !data->IMC.hCandInfo)
+ return 0;
+
+ candinfo = ImmLockIMCC(data->IMC.hCandInfo);
+ if ( dwIndex >= candinfo->dwCount ||
+ dwIndex >= (sizeof(candinfo->dwOffset) / sizeof(DWORD)) )
+ goto done;
+
+ candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + candinfo->dwOffset[dwIndex]);
+ if ( !candlist->dwSize || !candlist->dwCount )
+ goto done;
+
+ if ( !is_himc_ime_unicode(data) )
+ {
+ ret = candlist->dwSize;
+ if ( lpCandList && dwBufLen >= ret )
+ memcpy(lpCandList, candlist, ret);
+ }
+ else
+ ret = convert_candidatelist_WtoA( candlist, lpCandList, dwBufLen);
+
+done:
+ ImmUnlockIMCC(data->IMC.hCandInfo);
+ return ret;
}
/***********************************************************************
DWORD WINAPI ImmGetCandidateListCountA(
HIMC hIMC, LPDWORD lpdwListCount)
{
- FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ InputContextData *data = hIMC;
+ LPCANDIDATEINFO candinfo;
+ DWORD ret, count;
+
+ TRACE("%p, %p\n", hIMC, lpdwListCount);
+
+ if (!data || !lpdwListCount || !data->IMC.hCandInfo)
+ return 0;
+
+ candinfo = ImmLockIMCC(data->IMC.hCandInfo);
+
+ *lpdwListCount = count = candinfo->dwCount;
+
+ if ( !is_himc_ime_unicode(data) )
+ ret = candinfo->dwSize;
+ else
+ {
+ ret = sizeof(CANDIDATEINFO);
+ while ( count-- )
+ ret += ImmGetCandidateListA(hIMC, count, NULL, 0);
+ }
+
+ ImmUnlockIMCC(data->IMC.hCandInfo);
+ return ret;
}
/***********************************************************************
DWORD WINAPI ImmGetCandidateListCountW(
HIMC hIMC, LPDWORD lpdwListCount)
{
- FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ InputContextData *data = hIMC;
+ LPCANDIDATEINFO candinfo;
+ DWORD ret, count;
+
+ TRACE("%p, %p\n", hIMC, lpdwListCount);
+
+ if (!data || !lpdwListCount || !data->IMC.hCandInfo)
+ return 0;
+
+ candinfo = ImmLockIMCC(data->IMC.hCandInfo);
+
+ *lpdwListCount = count = candinfo->dwCount;
+
+ if ( is_himc_ime_unicode(data) )
+ ret = candinfo->dwSize;
+ else
+ {
+ ret = sizeof(CANDIDATEINFO);
+ while ( count-- )
+ ret += ImmGetCandidateListW(hIMC, count, NULL, 0);
+ }
+
+ ImmUnlockIMCC(data->IMC.hCandInfo);
+ return ret;
}
/***********************************************************************
* ImmGetCandidateListW (IMM32.@)
*/
DWORD WINAPI ImmGetCandidateListW(
- HIMC hIMC, DWORD deIndex,
+ HIMC hIMC, DWORD dwIndex,
LPCANDIDATELIST lpCandList, DWORD dwBufLen)
{
- FIXME("(%p, %d, %p, %d): stub\n",
- hIMC, deIndex,
- lpCandList, dwBufLen
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ InputContextData *data = hIMC;
+ LPCANDIDATEINFO candinfo;
+ LPCANDIDATELIST candlist;
+ DWORD ret = 0;
+
+ TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
+
+ if (!data || !data->IMC.hCandInfo)
+ return 0;
+
+ candinfo = ImmLockIMCC(data->IMC.hCandInfo);
+ if ( dwIndex >= candinfo->dwCount ||
+ dwIndex >= (sizeof(candinfo->dwOffset) / sizeof(DWORD)) )
+ goto done;
+
+ candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + candinfo->dwOffset[dwIndex]);
+ if ( !candlist->dwSize || !candlist->dwCount )
+ goto done;
+
+ if ( is_himc_ime_unicode(data) )
+ {
+ ret = candlist->dwSize;
+ if ( lpCandList && dwBufLen >= ret )
+ memcpy(lpCandList, candlist, ret);
+ }
+ else
+ ret = convert_candidatelist_AtoW( candlist, lpCandList, dwBufLen);
+
+done:
+ ImmUnlockIMCC(data->IMC.hCandInfo);
+ return ret;
}
/***********************************************************************
* ImmGetCandidateWindow (IMM32.@)
*/
BOOL WINAPI ImmGetCandidateWindow(
- HIMC hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
+ HIMC hIMC, DWORD dwIndex, LPCANDIDATEFORM lpCandidate)
{
- FIXME("(%p, %d, %p): stub\n", hIMC, dwBufLen, lpCandidate);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ InputContextData *data = hIMC;
+
+ TRACE("%p, %d, %p\n", hIMC, dwIndex, lpCandidate);
+
+ if (!data || !lpCandidate)
+ return FALSE;
+
+ if ( dwIndex >= (sizeof(data->IMC.cfCandForm) / sizeof(CANDIDATEFORM)) )
+ return FALSE;
+
+ *lpCandidate = data->IMC.cfCandForm[dwIndex];
+
+ return TRUE;
}
/***********************************************************************
TRACE("(%p, %p):\n", hIMC, lplf);
rc = ImmGetCompositionFontW(hIMC,&lfW);
- if (rc)
- {
- memcpy(lplf,&lfW,sizeof(LOGFONTA));
- WideCharToMultiByte(CP_ACP, 0, lfW.lfFaceName, -1, lplf->lfFaceName,
+ if (!rc || !lplf)
+ return FALSE;
+
+ memcpy(lplf,&lfW,sizeof(LOGFONTA));
+ WideCharToMultiByte(CP_ACP, 0, lfW.lfFaceName, -1, lplf->lfFaceName,
LF_FACESIZE, NULL, NULL);
- }
- return rc;
+ return TRUE;
}
/***********************************************************************
*/
BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
{
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
TRACE("(%p, %p):\n", hIMC, lplf);
- if (!data)
+ if (!data || !lplf)
return FALSE;
*lplf = data->IMC.lfFont.W;
return TRUE;
}
-/***********************************************************************
- * ImmGetCompositionStringA (IMM32.@)
- */
-LONG WINAPI ImmGetCompositionStringA(
- HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
+
+/* Helpers for the GetCompositionString functions */
+
+static INT CopyCompStringIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE target, INT tlen,
+ BOOL unicode )
{
- CHAR *buf;
- LONG rc = 0;
- InputContextData *data = (InputContextData*)hIMC;
- LPCOMPOSITIONSTRING compstr;
- LPBYTE compdata;
+ INT rc;
- TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
+ if (is_himc_ime_unicode(data) && !unicode)
+ rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)source, slen, (LPSTR)target, tlen, NULL, NULL);
+ else if (!is_himc_ime_unicode(data) && unicode)
+ rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)source, slen, (LPWSTR)target, tlen) * sizeof(WCHAR);
+ else
+ {
+ int dlen = (unicode)?sizeof(WCHAR):sizeof(CHAR);
+ memcpy( target, source, min(slen,tlen)*dlen);
+ rc = slen*dlen;
+ }
- if (!data)
- return FALSE;
+ return rc;
+}
- if (!data->IMC.hCompStr)
- return FALSE;
+static INT CopyCompAttrIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, INT sslen,
+ LPBYTE target, INT tlen, BOOL unicode )
+{
+ INT rc;
- compdata = ImmLockIMCC(data->IMC.hCompStr);
- compstr = (LPCOMPOSITIONSTRING)compdata;
+ if (is_himc_ime_unicode(data) && !unicode)
+ {
+ rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, sslen, NULL, 0, NULL, NULL);
+ if (tlen)
+ {
+ const BYTE *src = source;
+ LPBYTE dst = target;
+ int i, j = 0, k = 0;
- if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
- compstr->dwResultStrOffset > 0)
+ if (rc < tlen)
+ tlen = rc;
+ for (i = 0; i < sslen; ++i)
+ {
+ int len;
+
+ len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)ssource + i, 1,
+ NULL, 0, NULL, NULL);
+ for (; len > 0; --len)
+ {
+ dst[j++] = src[k];
+
+ if (j >= tlen)
+ goto end;
+ }
+ ++k;
+ }
+ end:
+ rc = j;
+ }
+ }
+ else if (!is_himc_ime_unicode(data) && unicode)
+ {
+ rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, sslen, NULL, 0);
+ if (tlen)
+ {
+ const BYTE *src = source;
+ LPBYTE dst = target;
+ int i, j = 0;
+
+ if (rc < tlen)
+ tlen = rc;
+ for (i = 0; i < sslen; ++i)
+ {
+ if (IsDBCSLeadByte(((LPSTR)ssource)[i]))
+ continue;
+
+ dst[j++] = src[i];
+
+ if (j >= tlen)
+ break;
+ }
+ rc = j;
+ }
+ }
+ else
{
- LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
+ memcpy( target, source, min(slen,tlen));
+ rc = slen;
+ }
- TRACE("GSC_RESULTSTR %p %i\n",ResultStr,
- compstr->dwResultStrLen);
+ return rc;
+}
- buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwResultStrLen * 3 );
- rc = WideCharToMultiByte(CP_ACP, 0, ResultStr,
- compstr->dwResultStrLen , buf,
- compstr->dwResultStrLen * 3, NULL, NULL);
- if (dwBufLen >= rc)
- memcpy(lpBuf,buf,rc);
+static INT CopyCompClauseIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, INT sslen,
+ LPBYTE target, INT tlen, BOOL unicode )
+{
+ INT rc;
- data->bRead = TRUE;
- HeapFree( GetProcessHeap(), 0, buf );
- }
- else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
- compstr->dwCompStrOffset > 0)
+ if (is_himc_ime_unicode(data) && !unicode)
{
- LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
-
- TRACE("GSC_COMPSTR %p %i\n", CompString, compstr->dwCompStrLen);
+ if (tlen)
+ {
+ int i;
- buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwCompStrLen * 3 );
- rc = WideCharToMultiByte(CP_ACP, 0, CompString,
- compstr->dwCompStrLen, buf,
- compstr->dwCompStrLen * 3, NULL, NULL);
- if (dwBufLen >= rc)
- memcpy(lpBuf,buf,rc);
- HeapFree( GetProcessHeap(), 0, buf );
+ if (slen < tlen)
+ tlen = slen;
+ tlen /= sizeof (DWORD);
+ for (i = 0; i < tlen; ++i)
+ {
+ ((DWORD *)target)[i] = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource,
+ ((DWORD *)source)[i],
+ NULL, 0,
+ NULL, NULL);
+ }
+ rc = sizeof (DWORD) * i;
+ }
+ else
+ rc = slen;
}
- else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
- compstr->dwCompAttrOffset > 0)
+ else if (!is_himc_ime_unicode(data) && unicode)
{
- LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
- TRACE("GSC_COMPATTR %p %i\n", Compattr , compstr->dwCompAttrLen);
+ if (tlen)
+ {
+ int i;
- rc = compstr->dwCompAttrLen;
- if (dwBufLen >= rc)
- memcpy(lpBuf,Compattr,rc);
+ if (slen < tlen)
+ tlen = slen;
+ tlen /= sizeof (DWORD);
+ for (i = 0; i < tlen; ++i)
+ {
+ ((DWORD *)target)[i] = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource,
+ ((DWORD *)source)[i],
+ NULL, 0);
+ }
+ rc = sizeof (DWORD) * i;
+ }
+ else
+ rc = slen;
}
- else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
- compstr->dwCompClauseOffset > 0)
+ else
{
- LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
- TRACE("GSC_COMPCLAUSE %p %i\n", Compclause, compstr->dwCompClauseLen);
-
- rc = compstr->dwCompClauseLen;
- if (dwBufLen >= compstr->dwCompClauseLen)
- memcpy(lpBuf,Compclause,rc);
+ memcpy( target, source, min(slen,tlen));
+ rc = slen;
}
- else if (dwIndex == GCS_RESULTCLAUSE && compstr->dwResultClauseLen > 0 &&
- compstr->dwResultClauseOffset > 0)
- {
- LPWSTR Resultclause = (LPWSTR)(compdata + compstr->dwResultClauseOffset);
- TRACE("GSC_RESULTCLAUSE %p %i\n", Resultclause, compstr->dwResultClauseLen);
- rc = compstr->dwResultClauseLen;
- if (dwBufLen >= compstr->dwResultClauseLen)
- memcpy(lpBuf,Resultclause,rc);
- }
- else if (dwIndex == GCS_CURSORPOS)
+ return rc;
+}
+
+static INT CopyCompOffsetIMEtoClient(InputContextData *data, DWORD offset, LPBYTE ssource, BOOL unicode)
+{
+ int rc;
+
+ if (is_himc_ime_unicode(data) && !unicode)
{
- TRACE("GSC_CURSORPOS\n");
- rc = compstr->dwCursorPos;
+ rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, offset, NULL, 0, NULL, NULL);
}
- else if (dwIndex == GCS_DELTASTART)
+ else if (!is_himc_ime_unicode(data) && unicode)
{
- TRACE("GCS_DELTASTART\n");
- rc = compstr->dwDeltaStart;
+ rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, offset, NULL, 0);
}
else
- {
- FIXME("Unhandled index 0x%x\n",dwIndex);
- }
-
- ImmUnlockIMCC(data->IMC.hCompStr);
+ rc = offset;
return rc;
}
-/***********************************************************************
- * ImmGetCompositionStringW (IMM32.@)
- */
-LONG WINAPI ImmGetCompositionStringW(
- HIMC hIMC, DWORD dwIndex,
- LPVOID lpBuf, DWORD dwBufLen)
+static LONG ImmGetCompositionStringT( HIMC hIMC, DWORD dwIndex, LPVOID lpBuf,
+ DWORD dwBufLen, BOOL unicode)
{
LONG rc = 0;
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
LPCOMPOSITIONSTRING compstr;
LPBYTE compdata;
compdata = ImmLockIMCC(data->IMC.hCompStr);
compstr = (LPCOMPOSITIONSTRING)compdata;
- if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
- compstr->dwResultStrOffset > 0)
- {
- LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
- data->bRead = TRUE;
- rc = compstr->dwResultStrLen * sizeof(WCHAR);
-
- if (dwBufLen >= rc)
- memcpy(lpBuf,ResultStr,rc);
- }
- else if (dwIndex == GCS_RESULTREADSTR && compstr->dwResultReadStrLen > 0 &&
- compstr->dwResultReadStrOffset > 0)
- {
- LPWSTR ResultReadString = (LPWSTR)(compdata + compstr->dwResultReadStrOffset);
-
- rc = compstr->dwResultReadStrLen * sizeof(WCHAR);
- if (dwBufLen >= rc)
- memcpy(lpBuf,ResultReadString,rc);
- }
- else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
- compstr->dwCompStrOffset > 0)
- {
- LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
- rc = compstr->dwCompStrLen * sizeof(WCHAR);
- if (dwBufLen >= rc)
- memcpy(lpBuf,CompString,rc);
- }
- else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
- compstr->dwCompAttrOffset > 0)
- {
-
- LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
-
- rc = compstr->dwCompAttrLen;
- if (dwBufLen >= rc)
- memcpy(lpBuf,Compattr,rc);
- }
- else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
- compstr->dwCompClauseOffset > 0)
- {
- LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
-
- rc = compstr->dwCompClauseLen;
- if (dwBufLen >= compstr->dwCompClauseLen)
- memcpy(lpBuf,Compclause,rc);
- }
- else if (dwIndex == GCS_COMPREADSTR && compstr->dwCompReadStrLen > 0 &&
- compstr->dwCompReadStrOffset > 0)
- {
- LPWSTR CompReadString = (LPWSTR)(compdata + compstr->dwCompReadStrOffset);
-
- rc = compstr->dwCompReadStrLen * sizeof(WCHAR);
-
- if (dwBufLen >= rc)
- memcpy(lpBuf,CompReadString,rc);
- }
- else if (dwIndex == GCS_CURSORPOS)
- {
- TRACE("GSC_CURSORPOS\n");
- rc = compstr->dwCursorPos;
- }
- else if (dwIndex == GCS_DELTASTART)
- {
+ switch (dwIndex)
+ {
+ case GCS_RESULTSTR:
+ TRACE("GCS_RESULTSTR\n");
+ rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwResultStrOffset, compstr->dwResultStrLen, lpBuf, dwBufLen, unicode);
+ break;
+ case GCS_COMPSTR:
+ TRACE("GCS_COMPSTR\n");
+ rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen, lpBuf, dwBufLen, unicode);
+ break;
+ case GCS_COMPATTR:
+ TRACE("GCS_COMPATTR\n");
+ rc = CopyCompAttrIMEtoClient(data, compdata + compstr->dwCompAttrOffset, compstr->dwCompAttrLen,
+ compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen,
+ lpBuf, dwBufLen, unicode);
+ break;
+ case GCS_COMPCLAUSE:
+ TRACE("GCS_COMPCLAUSE\n");
+ rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwCompClauseOffset,compstr->dwCompClauseLen,
+ compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen,
+ lpBuf, dwBufLen, unicode);
+ break;
+ case GCS_RESULTCLAUSE:
+ TRACE("GCS_RESULTCLAUSE\n");
+ rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultClauseOffset,compstr->dwResultClauseLen,
+ compdata + compstr->dwResultStrOffset, compstr->dwResultStrLen,
+ lpBuf, dwBufLen, unicode);
+ break;
+ case GCS_RESULTREADSTR:
+ TRACE("GCS_RESULTREADSTR\n");
+ rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwResultReadStrOffset, compstr->dwResultReadStrLen, lpBuf, dwBufLen, unicode);
+ break;
+ case GCS_RESULTREADCLAUSE:
+ TRACE("GCS_RESULTREADCLAUSE\n");
+ rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultReadClauseOffset,compstr->dwResultReadClauseLen,
+ compdata + compstr->dwResultStrOffset, compstr->dwResultStrLen,
+ lpBuf, dwBufLen, unicode);
+ break;
+ case GCS_COMPREADSTR:
+ TRACE("GCS_COMPREADSTR\n");
+ rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwCompReadStrOffset, compstr->dwCompReadStrLen, lpBuf, dwBufLen, unicode);
+ break;
+ case GCS_COMPREADATTR:
+ TRACE("GCS_COMPREADATTR\n");
+ rc = CopyCompAttrIMEtoClient(data, compdata + compstr->dwCompReadAttrOffset, compstr->dwCompReadAttrLen,
+ compdata + compstr->dwCompReadStrOffset, compstr->dwCompReadStrLen,
+ lpBuf, dwBufLen, unicode);
+ break;
+ case GCS_COMPREADCLAUSE:
+ TRACE("GCS_COMPREADCLAUSE\n");
+ rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwCompReadClauseOffset,compstr->dwCompReadClauseLen,
+ compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen,
+ lpBuf, dwBufLen, unicode);
+ break;
+ case GCS_CURSORPOS:
+ TRACE("GCS_CURSORPOS\n");
+ rc = CopyCompOffsetIMEtoClient(data, compstr->dwCursorPos, compdata + compstr->dwCompStrOffset, unicode);
+ break;
+ case GCS_DELTASTART:
TRACE("GCS_DELTASTART\n");
- rc = compstr->dwDeltaStart;
- }
- else
- {
+ rc = CopyCompOffsetIMEtoClient(data, compstr->dwDeltaStart, compdata + compstr->dwCompStrOffset, unicode);
+ break;
+ default:
FIXME("Unhandled index 0x%x\n",dwIndex);
- }
+ break;
+ }
ImmUnlockIMCC(data->IMC.hCompStr);
return rc;
}
+/***********************************************************************
+ * ImmGetCompositionStringA (IMM32.@)
+ */
+LONG WINAPI ImmGetCompositionStringA(
+ HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
+{
+ return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, FALSE);
+}
+
+
+/***********************************************************************
+ * ImmGetCompositionStringW (IMM32.@)
+ */
+LONG WINAPI ImmGetCompositionStringW(
+ HIMC hIMC, DWORD dwIndex,
+ LPVOID lpBuf, DWORD dwBufLen)
+{
+ return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, TRUE);
+}
+
/***********************************************************************
* ImmGetCompositionWindow (IMM32.@)
*/
BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
{
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
TRACE("(%p, %p)\n", hIMC, lpCompForm);
HIMC rc = NULL;
TRACE("%p\n", hWnd);
+ if (!IMM_GetThreadData()->defaultContext)
+ IMM_GetThreadData()->defaultContext = ImmCreateContext();
- rc = (HIMC)GetPropW(hWnd,szwWineIMCProperty);
+ rc = GetPropW(hWnd,szwWineIMCProperty);
if (rc == (HIMC)-1)
rc = NULL;
else if (rc == NULL)
- rc = (HIMC)root_context;
+ rc = IMM_GetThreadData()->defaultContext;
if (rc)
{
- InputContextData *data = (InputContextData*)rc;
+ InputContextData *data = rc;
data->IMC.hWnd = hWnd;
}
TRACE("returning %p\n", rc);
LPCSTR pSrc, LPCANDIDATELIST lpDst,
DWORD dwBufLen, UINT uFlag)
{
- FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
- hKL, hIMC, debugstr_a(pSrc), lpDst, dwBufLen, uFlag
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL, hIMC, debugstr_a(pSrc), lpDst,
+ dwBufLen, uFlag);
+ if (immHkl->hIME && immHkl->pImeConversionList)
+ {
+ if (!is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeConversionList(hIMC,(LPCWSTR)pSrc,lpDst,dwBufLen,uFlag);
+ else
+ {
+ LPCANDIDATELIST lpwDst;
+ DWORD ret = 0, len;
+ LPWSTR pwSrc = strdupAtoW(pSrc);
+
+ len = immHkl->pImeConversionList(hIMC, pwSrc, NULL, 0, uFlag);
+ lpwDst = HeapAlloc(GetProcessHeap(), 0, len);
+ if ( lpwDst )
+ {
+ immHkl->pImeConversionList(hIMC, pwSrc, lpwDst, len, uFlag);
+ ret = convert_candidatelist_WtoA( lpwDst, lpDst, dwBufLen);
+ HeapFree(GetProcessHeap(), 0, lpwDst);
+ }
+ HeapFree(GetProcessHeap(), 0, pwSrc);
+
+ return ret;
+ }
+ }
+ else
+ return 0;
}
/***********************************************************************
LPCWSTR pSrc, LPCANDIDATELIST lpDst,
DWORD dwBufLen, UINT uFlag)
{
- FIXME("(%p, %p, %s, %p, %d, %d): stub\n",
- hKL, hIMC, debugstr_w(pSrc), lpDst, dwBufLen, uFlag
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ TRACE("(%p, %p, %s, %p, %d, %d):\n", hKL, hIMC, debugstr_w(pSrc), lpDst,
+ dwBufLen, uFlag);
+ if (immHkl->hIME && immHkl->pImeConversionList)
+ {
+ if (is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeConversionList(hIMC,pSrc,lpDst,dwBufLen,uFlag);
+ else
+ {
+ LPCANDIDATELIST lpaDst;
+ DWORD ret = 0, len;
+ LPSTR paSrc = strdupWtoA(pSrc);
+
+ len = immHkl->pImeConversionList(hIMC, (LPCWSTR)paSrc, NULL, 0, uFlag);
+ lpaDst = HeapAlloc(GetProcessHeap(), 0, len);
+ if ( lpaDst )
+ {
+ immHkl->pImeConversionList(hIMC, (LPCWSTR)paSrc, lpaDst, len, uFlag);
+ ret = convert_candidatelist_AtoW( lpaDst, lpDst, dwBufLen);
+ HeapFree(GetProcessHeap(), 0, lpaDst);
+ }
+ HeapFree(GetProcessHeap(), 0, paSrc);
+
+ return ret;
+ }
+ }
+ else
+ return 0;
}
/***********************************************************************
BOOL WINAPI ImmGetConversionStatus(
HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
{
- TRACE("(%p, %p, %p): best guess\n", hIMC, lpfdwConversion, lpfdwSentence);
+ InputContextData *data = hIMC;
+
+ TRACE("%p %p %p\n", hIMC, lpfdwConversion, lpfdwSentence);
+
+ if (!data)
+ return FALSE;
+
if (lpfdwConversion)
- *lpfdwConversion = IME_CMODE_NATIVE;
+ *lpfdwConversion = data->IMC.fdwConversion;
if (lpfdwSentence)
- *lpfdwSentence = IME_SMODE_NONE;
+ *lpfdwSentence = data->IMC.fdwSentence;
+
return TRUE;
}
*/
HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
{
- static int shown = 0;
-
- if (!shown) {
- FIXME("(%p - %p %p ): semi-stub\n", hWnd,hwndDefault, root_context);
- shown = 1;
- }
-
- if (hwndDefault == NULL)
- {
- static const WCHAR the_name[] = {'I','M','E','\0'};
-
- IMM_Register();
- hwndDefault = CreateWindowExW( WS_EX_TOOLWINDOW, WC_IMECLASSNAME,
- the_name, WS_POPUP, 0, 0, 1, 1, 0, 0,
- hImeInst, 0);
-
- TRACE("Default created (%p)\n",hwndDefault);
- }
-
- return hwndDefault;
+ TRACE("Default is %p\n",IMM_GetThreadData()->hwndDefault);
+ return IMM_GetThreadData()->hwndDefault;
}
/***********************************************************************
*/
UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
{
- static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0};
- 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};
-
HKEY hkey;
DWORD length;
DWORD rc;
- WCHAR regKey[sizeof(fmt)/sizeof(WCHAR)+8];
+ WCHAR regKey[sizeof(szImeRegFmt)/sizeof(WCHAR)+8];
- wsprintfW( regKey, fmt, (unsigned)hKL );
+ wsprintfW( regKey, szImeRegFmt, (ULONG_PTR)hKL );
rc = RegOpenKeyW( HKEY_LOCAL_MACHINE, regKey, &hkey);
if (rc != ERROR_SUCCESS)
{
*/
BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
{
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
if (!data)
return FALSE;
DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
{
DWORD rc = 0;
+ ImmHkl *kbd;
+
TRACE("(%p, %d)\n", hKL, fdwIndex);
+ kbd = IMM_GetImmHkl(hKL);
- switch (fdwIndex)
+ if (kbd && kbd->hIME)
{
- case IGP_PROPERTY:
- TRACE("(%s)\n", "IGP_PROPERTY");
- rc = IME_PROP_UNICODE | IME_PROP_AT_CARET;
- break;
- case IGP_CONVERSION:
- FIXME("(%s)\n", "IGP_CONVERSION");
- rc = IME_CMODE_NATIVE;
- break;
- case IGP_SENTENCE:
- FIXME("%s)\n", "IGP_SENTENCE");
- rc = IME_SMODE_AUTOMATIC;
- break;
- case IGP_SETCOMPSTR:
- TRACE("(%s)\n", "IGP_SETCOMPSTR");
- rc = 0;
- break;
- case IGP_SELECT:
- TRACE("(%s)\n", "IGP_SELECT");
- rc = SELECT_CAP_CONVERSION | SELECT_CAP_SENTENCE;
- break;
- case IGP_GETIMEVERSION:
- TRACE("(%s)\n", "IGP_GETIMEVERSION");
- rc = IMEVER_0400;
- break;
- case IGP_UI:
- TRACE("(%s)\n", "IGP_UI");
- rc = 0;
- break;
- default:
- rc = 0;
+ switch (fdwIndex)
+ {
+ case IGP_PROPERTY: rc = kbd->imeInfo.fdwProperty; break;
+ case IGP_CONVERSION: rc = kbd->imeInfo.fdwConversionCaps; break;
+ case IGP_SENTENCE: rc = kbd->imeInfo.fdwSentenceCaps; break;
+ case IGP_SETCOMPSTR: rc = kbd->imeInfo.fdwSCSCaps; break;
+ case IGP_SELECT: rc = kbd->imeInfo.fdwSelectCaps; break;
+ case IGP_GETIMEVERSION: rc = IMEVER_0400; break;
+ case IGP_UI: rc = 0; break;
+ default: rc = 0;
+ }
}
return rc;
}
UINT WINAPI ImmGetRegisterWordStyleA(
HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
{
- FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ TRACE("(%p, %d, %p):\n", hKL, nItem, lpStyleBuf);
+ if (immHkl->hIME && immHkl->pImeGetRegisterWordStyle)
+ {
+ if (!is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)lpStyleBuf);
+ else
+ {
+ STYLEBUFW sbw;
+ UINT rc;
+
+ rc = immHkl->pImeGetRegisterWordStyle(nItem,&sbw);
+ WideCharToMultiByte(CP_ACP, 0, sbw.szDescription, -1,
+ lpStyleBuf->szDescription, 32, NULL, NULL);
+ lpStyleBuf->dwStyle = sbw.dwStyle;
+ return rc;
+ }
+ }
+ else
+ return 0;
}
/***********************************************************************
UINT WINAPI ImmGetRegisterWordStyleW(
HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
{
- FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ TRACE("(%p, %d, %p):\n", hKL, nItem, lpStyleBuf);
+ if (immHkl->hIME && immHkl->pImeGetRegisterWordStyle)
+ {
+ if (is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeGetRegisterWordStyle(nItem,lpStyleBuf);
+ else
+ {
+ STYLEBUFA sba;
+ UINT rc;
+
+ rc = immHkl->pImeGetRegisterWordStyle(nItem,(LPSTYLEBUFW)&sba);
+ MultiByteToWideChar(CP_ACP, 0, sba.szDescription, -1,
+ lpStyleBuf->szDescription, 32);
+ lpStyleBuf->dwStyle = sba.dwStyle;
+ return rc;
+ }
+ }
+ else
+ return 0;
}
/***********************************************************************
*/
BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
{
- FIXME("(%p, %p): stub\n", hIMC, lpptPos);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ InputContextData *data = hIMC;
+
+ TRACE("(%p, %p)\n", hIMC, lpptPos);
+
+ if (!data || !lpptPos)
+ return FALSE;
+
+ *lpptPos = data->IMC.ptStatusWndPos;
+
+ return TRUE;
}
/***********************************************************************
UINT WINAPI ImmGetVirtualKey(HWND hWnd)
{
OSVERSIONINFOA version;
- FIXME("(%p): stub\n", hWnd);
+ InputContextData *data = ImmGetContext( hWnd );
+ TRACE("%p\n", hWnd);
+
+ if ( data )
+ return data->lastVK;
+
GetVersionExA( &version );
switch(version.dwPlatformId)
{
HKL WINAPI ImmInstallIMEA(
LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
{
- FIXME("(%s, %s): stub\n",
- debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return NULL;
+ LPWSTR lpszwIMEFileName;
+ LPWSTR lpszwLayoutText;
+ HKL hkl;
+
+ TRACE ("(%s, %s)\n", debugstr_a(lpszIMEFileName),
+ debugstr_a(lpszLayoutText));
+
+ lpszwIMEFileName = strdupAtoW(lpszIMEFileName);
+ lpszwLayoutText = strdupAtoW(lpszLayoutText);
+
+ hkl = ImmInstallIMEW(lpszwIMEFileName, lpszwLayoutText);
+
+ HeapFree(GetProcessHeap(),0,lpszwIMEFileName);
+ HeapFree(GetProcessHeap(),0,lpszwLayoutText);
+ return hkl;
}
/***********************************************************************
HKL WINAPI ImmInstallIMEW(
LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
{
- FIXME("(%s, %s): stub\n",
- debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return NULL;
+ INT lcid = GetUserDefaultLCID();
+ INT count;
+ HKL hkl;
+ DWORD rc;
+ HKEY hkey;
+ WCHAR regKey[sizeof(szImeRegFmt)/sizeof(WCHAR)+8];
+
+ TRACE ("(%s, %s):\n", debugstr_w(lpszIMEFileName),
+ debugstr_w(lpszLayoutText));
+
+ /* Start with 2. e001 will be blank and so default to the wine internal IME */
+ count = 2;
+
+ while (count < 0xfff)
+ {
+ DWORD disposition = 0;
+
+ hkl = (HKL)MAKELPARAM( lcid, 0xe000 | count );
+ wsprintfW( regKey, szImeRegFmt, (ULONG_PTR)hkl);
+
+ rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, regKey, 0, NULL, 0, KEY_WRITE, NULL, &hkey, &disposition);
+ if (rc == ERROR_SUCCESS && disposition == REG_CREATED_NEW_KEY)
+ break;
+ else if (rc == ERROR_SUCCESS)
+ RegCloseKey(hkey);
+
+ count++;
+ }
+
+ if (count == 0xfff)
+ {
+ WARN("Unable to find slot to install IME\n");
+ return 0;
+ }
+
+ if (rc == ERROR_SUCCESS)
+ {
+ rc = RegSetValueExW(hkey, szImeFileW, 0, REG_SZ, (LPBYTE)lpszIMEFileName,
+ (lstrlenW(lpszIMEFileName) + 1) * sizeof(WCHAR));
+ if (rc == ERROR_SUCCESS)
+ rc = RegSetValueExW(hkey, szLayoutTextW, 0, REG_SZ, (LPBYTE)lpszLayoutText,
+ (lstrlenW(lpszLayoutText) + 1) * sizeof(WCHAR));
+ RegCloseKey(hkey);
+ return hkl;
+ }
+ else
+ {
+ WARN("Unable to set IME registry values\n");
+ return 0;
+ }
}
/***********************************************************************
*/
BOOL WINAPI ImmIsIME(HKL hKL)
{
- TRACE("(%p): semi-stub\n", hKL);
- /*
- * FIXME: Dead key locales will return TRUE here when they should not
- * There is probably a more proper way to check this.
- */
- return (root_context != NULL);
+ ImmHkl *ptr;
+ TRACE("(%p):\n", hKL);
+ ptr = IMM_GetImmHkl(hKL);
+ return (ptr && ptr->hIME);
}
/***********************************************************************
(msg == WM_MSIME_DOCUMENTFEED))
{
- if (!hwndDefault)
+ if (!IMM_GetThreadData()->hwndDefault)
ImmGetDefaultIMEWnd(NULL);
if (hWndIME == NULL)
- PostMessageA(hwndDefault, msg, wParam, lParam);
+ PostMessageA(IMM_GetThreadData()->hwndDefault, msg, wParam, lParam);
rc = TRUE;
}
HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
{
BOOL rc = FALSE;
- TRACE("(%p, %d, %ld, %ld): stub\n", hWndIME, msg, wParam, lParam);
+ TRACE("(%p, %d, %ld, %ld):\n", hWndIME, msg, wParam, lParam);
if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
(msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
(msg == WM_MSIME_SERVICE) ||
BOOL WINAPI ImmNotifyIME(
HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
{
- BOOL rc = FALSE;
+ InputContextData *data = hIMC;
TRACE("(%p, %d, %d, %d)\n",
hIMC, dwAction, dwIndex, dwValue);
- if (!root_context)
- return rc;
-
- switch(dwAction)
- {
- case NI_CHANGECANDIDATELIST:
- FIXME("%s\n","NI_CHANGECANDIDATELIST");
- break;
- case NI_CLOSECANDIDATE:
- FIXME("%s\n","NI_CLOSECANDIDATE");
- break;
- case NI_COMPOSITIONSTR:
- switch (dwIndex)
- {
- case CPS_CANCEL:
- TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL");
- {
- BOOL send;
- LPCOMPOSITIONSTRING lpCompStr;
-
- if (pX11DRV_ForceXIMReset)
- pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
-
- lpCompStr = ImmLockIMCC(root_context->IMC.hCompStr);
- send = (lpCompStr->dwCompStrLen != 0);
- ImmUnlockIMCC(root_context->IMC.hCompStr);
-
- ImmDestroyIMCC(root_context->IMC.hCompStr);
- root_context->IMC.hCompStr = ImmCreateBlankCompStr();
-
- if (send)
- ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION, 0,
- GCS_COMPSTR);
- rc = TRUE;
- }
- break;
- case CPS_COMPLETE:
- TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_COMPLETE");
- if (hIMC != (HIMC)FROM_IME && pX11DRV_ForceXIMReset)
- pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
- {
- HIMCC newCompStr;
- DWORD cplen = 0;
- LPWSTR cpstr;
- LPCOMPOSITIONSTRING cs = NULL;
- LPBYTE cdata = NULL;
-
- /* clear existing result */
- newCompStr = updateResultStr(root_context->IMC.hCompStr, NULL, 0);
- ImmDestroyIMCC(root_context->IMC.hCompStr);
- root_context->IMC.hCompStr = newCompStr;
-
- if (root_context->IMC.hCompStr)
- {
- cdata = ImmLockIMCC(root_context->IMC.hCompStr);
- cs = (LPCOMPOSITIONSTRING)cdata;
- cplen = cs->dwCompStrLen;
- cpstr = (LPWSTR)&(cdata[cs->dwCompStrOffset]);
- ImmUnlockIMCC(root_context->IMC.hCompStr);
- }
- if (cplen > 0)
- {
- WCHAR param = cpstr[0];
- newCompStr = updateResultStr(root_context->IMC.hCompStr, cpstr, cplen);
- ImmDestroyIMCC(root_context->IMC.hCompStr);
- root_context->IMC.hCompStr = newCompStr;
- newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
- ImmDestroyIMCC(root_context->IMC.hCompStr);
- root_context->IMC.hCompStr = newCompStr;
-
- root_context->bRead = FALSE;
-
- ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION, 0,
- GCS_COMPSTR);
-
- ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION,
- param,
- GCS_RESULTSTR|GCS_RESULTCLAUSE);
- }
-
- ImmInternalPostIMEMessage(root_context, WM_IME_ENDCOMPOSITION, 0, 0);
- root_context->bInComposition = FALSE;
- }
- break;
- case CPS_CONVERT:
- FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_CONVERT");
- break;
- case CPS_REVERT:
- FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_REVERT");
- break;
- default:
- ERR("%s - %s (%i)\n","NI_COMPOSITIONSTR","UNKNOWN",dwIndex);
- break;
- }
- break;
- case NI_IMEMENUSELECTED:
- FIXME("%s\n", "NI_IMEMENUSELECTED");
- break;
- case NI_OPENCANDIDATE:
- FIXME("%s\n", "NI_OPENCANDIDATE");
- break;
- case NI_SELECTCANDIDATESTR:
- FIXME("%s\n", "NI_SELECTCANDIDATESTR");
- break;
- case NI_SETCANDIDATE_PAGESIZE:
- FIXME("%s\n", "NI_SETCANDIDATE_PAGESIZE");
- break;
- case NI_SETCANDIDATE_PAGESTART:
- FIXME("%s\n", "NI_SETCANDIDATE_PAGESTART");
- break;
- default:
- ERR("Unknown\n");
- }
+ if (!data || ! data->immKbd->pNotifyIME)
+ return FALSE;
- return rc;
+ return data->immKbd->pNotifyIME(hIMC,dwAction,dwIndex,dwValue);
}
/***********************************************************************
BOOL WINAPI ImmRegisterWordA(
HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
{
- FIXME("(%p, %s, %d, %s): stub\n",
- hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister)
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_a(lpszReading), dwStyle,
+ debugstr_a(lpszRegister));
+ if (immHkl->hIME && immHkl->pImeRegisterWord)
+ {
+ if (!is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeRegisterWord((LPCWSTR)lpszReading,dwStyle,
+ (LPCWSTR)lpszRegister);
+ else
+ {
+ LPWSTR lpszwReading = strdupAtoW(lpszReading);
+ LPWSTR lpszwRegister = strdupAtoW(lpszRegister);
+ BOOL rc;
+
+ rc = immHkl->pImeRegisterWord(lpszwReading,dwStyle,lpszwRegister);
+ HeapFree(GetProcessHeap(),0,lpszwReading);
+ HeapFree(GetProcessHeap(),0,lpszwRegister);
+ return rc;
+ }
+ }
+ else
+ return FALSE;
}
/***********************************************************************
BOOL WINAPI ImmRegisterWordW(
HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
{
- FIXME("(%p, %s, %d, %s): stub\n",
- hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister)
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_w(lpszReading), dwStyle,
+ debugstr_w(lpszRegister));
+ if (immHkl->hIME && immHkl->pImeRegisterWord)
+ {
+ if (is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeRegisterWord(lpszReading,dwStyle,lpszRegister);
+ else
+ {
+ LPSTR lpszaReading = strdupWtoA(lpszReading);
+ LPSTR lpszaRegister = strdupWtoA(lpszRegister);
+ BOOL rc;
+
+ rc = immHkl->pImeRegisterWord((LPCWSTR)lpszaReading,dwStyle,
+ (LPCWSTR)lpszaRegister);
+ HeapFree(GetProcessHeap(),0,lpszaReading);
+ HeapFree(GetProcessHeap(),0,lpszaRegister);
+ return rc;
+ }
+ }
+ else
+ return FALSE;
}
/***********************************************************************
*/
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
{
- static int shown = 0;
+ static int shown = 0;
+
+ if (!shown) {
+ FIXME("(%p, %p): stub\n", hWnd, hIMC);
+ shown = 1;
+ }
+ return TRUE;
+}
+
+/***********************************************************************
+* ImmRequestMessageA(IMM32.@)
+*/
+LRESULT WINAPI ImmRequestMessageA(HIMC hIMC, WPARAM wParam, LPARAM lParam)
+{
+ InputContextData *data = hIMC;
+
+ TRACE("%p %ld %ld\n", hIMC, wParam, wParam);
+
+ if (data && IsWindow(data->IMC.hWnd))
+ return SendMessageA(data->IMC.hWnd, WM_IME_REQUEST, wParam, lParam);
+
+ return 0;
+}
+
+/***********************************************************************
+* ImmRequestMessageW(IMM32.@)
+*/
+LRESULT WINAPI ImmRequestMessageW(HIMC hIMC, WPARAM wParam, LPARAM lParam)
+{
+ InputContextData *data = hIMC;
- if (!shown) {
- FIXME("(%p, %p): stub\n", hWnd, hIMC);
- shown = 1;
- }
- return TRUE;
+ TRACE("%p %ld %ld\n", hIMC, wParam, wParam);
+
+ if (data && IsWindow(data->IMC.hWnd))
+ return SendMessageW(data->IMC.hWnd, WM_IME_REQUEST, wParam, lParam);
+
+ return 0;
}
/***********************************************************************
BOOL WINAPI ImmSetCandidateWindow(
HIMC hIMC, LPCANDIDATEFORM lpCandidate)
{
- FIXME("(%p, %p): stub\n", hIMC, lpCandidate);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ InputContextData *data = hIMC;
+
+ TRACE("(%p, %p)\n", hIMC, lpCandidate);
+
+ if (!data || !lpCandidate)
+ return FALSE;
+
+ TRACE("\t%x, %x, (%i,%i), (%i,%i - %i,%i)\n",
+ lpCandidate->dwIndex, lpCandidate->dwStyle,
+ lpCandidate->ptCurrentPos.x, lpCandidate->ptCurrentPos.y,
+ lpCandidate->rcArea.top, lpCandidate->rcArea.left,
+ lpCandidate->rcArea.bottom, lpCandidate->rcArea.right);
+
+ if ( lpCandidate->dwIndex >= (sizeof(data->IMC.cfCandForm) / sizeof(CANDIDATEFORM)) )
+ return FALSE;
+
+ data->IMC.cfCandForm[lpCandidate->dwIndex] = *lpCandidate;
+ ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS);
+ ImmInternalSendIMENotify(data, IMN_SETCANDIDATEPOS, 1 << lpCandidate->dwIndex);
+
+ return TRUE;
}
/***********************************************************************
*/
BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
{
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
TRACE("(%p, %p)\n", hIMC, lplf);
- if (!data)
+ if (!data || !lplf)
return FALSE;
memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
LF_FACESIZE);
-
+ ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
- if (data->textfont)
- {
- DeleteObject(data->textfont);
- data->textfont = NULL;
- }
-
- data->textfont = CreateFontIndirectW(&data->IMC.lfFont.W);
return TRUE;
}
*/
BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
{
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
TRACE("(%p, %p)\n", hIMC, lplf);
- if (!data)
+ if (!data || !lplf)
return FALSE;
data->IMC.lfFont.W = *lplf;
+ ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
- if (data->textfont)
- {
- DeleteObject(data->textfont);
- data->textfont = NULL;
- }
- data->textfont = CreateFontIndirectW(&data->IMC.lfFont.W);
return TRUE;
}
WCHAR *CompBuffer = NULL;
WCHAR *ReadBuffer = NULL;
BOOL rc;
+ InputContextData *data = hIMC;
- TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
+ TRACE("(%p, %d, %p, %d, %p, %d):\n",
hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
+ if (!data)
+ return FALSE;
+
+ if (!(dwIndex == SCS_SETSTR ||
+ dwIndex == SCS_CHANGEATTR ||
+ dwIndex == SCS_CHANGECLAUSE ||
+ dwIndex == SCS_SETRECONVERTSTRING ||
+ dwIndex == SCS_QUERYRECONVERTSTRING))
+ return FALSE;
+
+ if (!is_himc_ime_unicode(data))
+ return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
+ dwCompLen, lpRead, dwReadLen);
+
comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
if (comp_len)
{
LPCVOID lpComp, DWORD dwCompLen,
LPCVOID lpRead, DWORD dwReadLen)
{
- DWORD flags = 0;
- WCHAR wParam = 0;
-
- TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
- hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
-
+ DWORD comp_len;
+ DWORD read_len;
+ CHAR *CompBuffer = NULL;
+ CHAR *ReadBuffer = NULL;
+ BOOL rc;
+ InputContextData *data = hIMC;
- if (hIMC != (HIMC)FROM_IME)
- FIXME("PROBLEM: This only sets the wine level string\n");
+ TRACE("(%p, %d, %p, %d, %p, %d):\n",
+ hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
- /*
- * Explanation:
- * this sets the composition string in the imm32.dll level
- * of the composition buffer. we cannot manipulate the xim level
- * buffer, which means that once the xim level buffer changes again
- * any call to this function from the application will be lost
- */
+ if (!data)
+ return FALSE;
- if (lpRead && dwReadLen)
- FIXME("Reading string unimplemented\n");
+ if (!(dwIndex == SCS_SETSTR ||
+ dwIndex == SCS_CHANGEATTR ||
+ dwIndex == SCS_CHANGECLAUSE ||
+ dwIndex == SCS_SETRECONVERTSTRING ||
+ dwIndex == SCS_QUERYRECONVERTSTRING))
+ return FALSE;
- /*
- * app operating this api to also receive the message from xim
- */
+ if (is_himc_ime_unicode(data))
+ return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp,
+ dwCompLen, lpRead, dwReadLen);
- if (dwIndex == SCS_SETSTR)
+ comp_len = WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, NULL, 0, NULL,
+ NULL);
+ if (comp_len)
{
- HIMCC newCompStr;
- if (!root_context->bInComposition)
- {
- ImmInternalPostIMEMessage(root_context, WM_IME_STARTCOMPOSITION, 0, 0);
- root_context->bInComposition = TRUE;
- }
-
- flags = GCS_COMPSTR;
-
- if (dwCompLen && lpComp)
- {
- newCompStr = updateCompStr(root_context->IMC.hCompStr, (LPWSTR)lpComp, dwCompLen / sizeof(WCHAR));
- ImmDestroyIMCC(root_context->IMC.hCompStr);
- root_context->IMC.hCompStr = newCompStr;
+ CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len);
+ WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len,
+ NULL, NULL);
+ }
- wParam = ((const WCHAR*)lpComp)[0];
- flags |= GCS_COMPCLAUSE | GCS_COMPATTR | GCS_DELTASTART;
- }
- else
- {
- newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
- ImmDestroyIMCC(root_context->IMC.hCompStr);
- root_context->IMC.hCompStr = newCompStr;
- }
+ read_len = WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, NULL, 0, NULL,
+ NULL);
+ if (read_len)
+ {
+ ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len);
+ WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len,
+ NULL, NULL);
}
- UpdateDataInDefaultIMEWindow(hwndDefault,FALSE);
+ rc = ImmSetCompositionStringA(hIMC, dwIndex, CompBuffer, comp_len,
+ ReadBuffer, read_len);
- ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION, wParam, flags);
+ HeapFree(GetProcessHeap(), 0, CompBuffer);
+ HeapFree(GetProcessHeap(), 0, ReadBuffer);
- return TRUE;
+ return rc;
}
/***********************************************************************
HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
{
BOOL reshow = FALSE;
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
TRACE("(%p, %p)\n", hIMC, lpCompForm);
TRACE("\t%x, (%i,%i), (%i,%i - %i,%i)\n",lpCompForm->dwStyle,
data->IMC.cfCompForm = *lpCompForm;
- if (IsWindowVisible(hwndDefault))
+ if (IsWindowVisible(IMM_GetThreadData()->hwndDefault))
{
reshow = TRUE;
- ShowWindow(hwndDefault,SW_HIDE);
+ ShowWindow(IMM_GetThreadData()->hwndDefault,SW_HIDE);
}
/* FIXME: this is a partial stub */
if (reshow)
- ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
+ ShowWindow(IMM_GetThreadData()->hwndDefault,SW_SHOWNOACTIVATE);
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0);
return TRUE;
BOOL WINAPI ImmSetConversionStatus(
HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
{
- static int shown = 0;
+ DWORD oldConversion, oldSentence;
+ InputContextData *data = hIMC;
- if (!shown) {
- FIXME("(%p, %d, %d): stub\n",
- hIMC, fdwConversion, fdwSentence
- );
- shown = 1;
- }
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ TRACE("%p %d %d\n", hIMC, fdwConversion, fdwSentence);
+
+ if (!data)
+ return FALSE;
+
+ if ( fdwConversion != data->IMC.fdwConversion )
+ {
+ oldConversion = data->IMC.fdwConversion;
+ data->IMC.fdwConversion = fdwConversion;
+ ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, oldConversion, IMC_SETCONVERSIONMODE);
+ ImmInternalSendIMENotify(data, IMN_SETCONVERSIONMODE, 0);
+ }
+ if ( fdwSentence != data->IMC.fdwSentence )
+ {
+ oldSentence = data->IMC.fdwSentence;
+ data->IMC.fdwSentence = fdwSentence;
+ ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, oldSentence, IMC_SETSENTENCEMODE);
+ ImmInternalSendIMENotify(data, IMN_SETSENTENCEMODE, 0);
+ }
+
+ return TRUE;
}
/***********************************************************************
*/
BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
{
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
TRACE("%p %d\n", hIMC, fOpen);
- if (hIMC == (HIMC)FROM_IME)
- {
- ImmInternalSetOpenStatus(fOpen);
- ImmInternalSendIMENotify(root_context, IMN_SETOPENSTATUS, 0);
- return TRUE;
- }
-
if (!data)
return FALSE;
- if (fOpen != data->bInternalState)
+ if (data->imeWnd == NULL)
{
- if (fOpen == FALSE && pX11DRV_ForceXIMReset)
- pX11DRV_ForceXIMReset(data->IMC.hWnd);
+ /* create the ime window */
+ data->imeWnd = CreateWindowExW( WS_EX_TOOLWINDOW,
+ data->immKbd->imeClassName, NULL, WS_POPUP, 0, 0, 1, 1, 0,
+ 0, data->immKbd->hIME, 0);
+ SetWindowLongPtrW(data->imeWnd, IMMGWL_IMC, (LONG_PTR)data);
+ IMM_GetThreadData()->hwndDefault = data->imeWnd;
+ }
- if (fOpen == FALSE)
- ImmInternalPostIMEMessage(data, WM_IME_ENDCOMPOSITION,0,0);
- else
- ImmInternalPostIMEMessage(data, WM_IME_STARTCOMPOSITION,0,0);
+ if (!fOpen != !data->IMC.fOpen)
+ {
+ data->IMC.fOpen = fOpen;
+ ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS);
+ ImmInternalSendIMENotify(data, IMN_SETOPENSTATUS, 0);
+ }
- ImmInternalSetOpenStatus(fOpen);
- ImmInternalSetOpenStatus(!fOpen);
+ return TRUE;
+}
- if (data->IMC.fOpen == FALSE)
- ImmInternalPostIMEMessage(data, WM_IME_ENDCOMPOSITION,0,0);
- else
- ImmInternalPostIMEMessage(data, WM_IME_STARTCOMPOSITION,0,0);
+/***********************************************************************
+ * ImmSetStatusWindowPos (IMM32.@)
+ */
+BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
+{
+ InputContextData *data = hIMC;
+
+ TRACE("(%p, %p)\n", hIMC, lpptPos);
+ if (!data || !lpptPos)
return FALSE;
- }
+
+ TRACE("\t(%i,%i)\n", lpptPos->x, lpptPos->y);
+
+ data->IMC.ptStatusWndPos = *lpptPos;
+ ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETSTATUSWINDOWPOS);
+ ImmInternalSendIMENotify(data, IMN_SETSTATUSWINDOWPOS, 0);
+
return TRUE;
}
/***********************************************************************
- * ImmSetStatusWindowPos (IMM32.@)
+ * ImmCreateSoftKeyboard(IMM32.@)
*/
-BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
+HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y)
{
- FIXME("(%p, %p): stub\n", hIMC, lpptPos);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ FIXME("(%d, %d, %d, %d): stub\n", uType, hOwner, x, y);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmDestroySoftKeyboard(IMM32.@)
+ */
+BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
+{
+ FIXME("(%p): stub\n", hSoftWnd);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmShowSoftKeyboard(IMM32.@)
+ */
+BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
+{
+ FIXME("(%p, %d): stub\n", hSoftWnd, nCmdShow);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
/***********************************************************************
BOOL WINAPI ImmUnregisterWordA(
HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
{
- FIXME("(%p, %s, %d, %s): stub\n",
- hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister)
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_a(lpszReading), dwStyle,
+ debugstr_a(lpszUnregister));
+ if (immHkl->hIME && immHkl->pImeUnregisterWord)
+ {
+ if (!is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeUnregisterWord((LPCWSTR)lpszReading,dwStyle,
+ (LPCWSTR)lpszUnregister);
+ else
+ {
+ LPWSTR lpszwReading = strdupAtoW(lpszReading);
+ LPWSTR lpszwUnregister = strdupAtoW(lpszUnregister);
+ BOOL rc;
+
+ rc = immHkl->pImeUnregisterWord(lpszwReading,dwStyle,lpszwUnregister);
+ HeapFree(GetProcessHeap(),0,lpszwReading);
+ HeapFree(GetProcessHeap(),0,lpszwUnregister);
+ return rc;
+ }
+ }
+ else
+ return FALSE;
}
/***********************************************************************
BOOL WINAPI ImmUnregisterWordW(
HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
{
- FIXME("(%p, %s, %d, %s): stub\n",
- hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister)
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ ImmHkl *immHkl = IMM_GetImmHkl(hKL);
+ TRACE("(%p, %s, %d, %s):\n", hKL, debugstr_w(lpszReading), dwStyle,
+ debugstr_w(lpszUnregister));
+ if (immHkl->hIME && immHkl->pImeUnregisterWord)
+ {
+ if (is_kbd_ime_unicode(immHkl))
+ return immHkl->pImeUnregisterWord(lpszReading,dwStyle,lpszUnregister);
+ else
+ {
+ LPSTR lpszaReading = strdupWtoA(lpszReading);
+ LPSTR lpszaUnregister = strdupWtoA(lpszUnregister);
+ BOOL rc;
+
+ rc = immHkl->pImeUnregisterWord((LPCWSTR)lpszaReading,dwStyle,
+ (LPCWSTR)lpszaUnregister);
+ HeapFree(GetProcessHeap(),0,lpszaReading);
+ HeapFree(GetProcessHeap(),0,lpszaUnregister);
+ return rc;
+ }
+ }
+ else
+ return FALSE;
}
/***********************************************************************
LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu,
DWORD dwSize)
{
- FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType,
- lpImeParentMenu, lpImeMenu, dwSize);
- return 0;
+ InputContextData *data = hIMC;
+ TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
+ lpImeParentMenu, lpImeMenu, dwSize);
+ if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
+ {
+ if (!is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
+ return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
+ (IMEMENUITEMINFOW*)lpImeParentMenu,
+ (IMEMENUITEMINFOW*)lpImeMenu, dwSize);
+ else
+ {
+ IMEMENUITEMINFOW lpImeParentMenuW;
+ IMEMENUITEMINFOW *lpImeMenuW, *parent = NULL;
+ DWORD rc;
+
+ if (lpImeParentMenu)
+ parent = &lpImeParentMenuW;
+ if (lpImeMenu)
+ {
+ int count = dwSize / sizeof(LPIMEMENUITEMINFOA);
+ dwSize = count * sizeof(IMEMENUITEMINFOW);
+ lpImeMenuW = HeapAlloc(GetProcessHeap(), 0, dwSize);
+ }
+ else
+ lpImeMenuW = NULL;
+
+ rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
+ parent, lpImeMenuW, dwSize);
+
+ if (lpImeParentMenu)
+ {
+ memcpy(lpImeParentMenu,&lpImeParentMenuW,sizeof(IMEMENUITEMINFOA));
+ lpImeParentMenu->hbmpItem = lpImeParentMenuW.hbmpItem;
+ WideCharToMultiByte(CP_ACP, 0, lpImeParentMenuW.szString,
+ -1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE,
+ NULL, NULL);
+ }
+ if (lpImeMenu && rc)
+ {
+ unsigned int i;
+ for (i = 0; i < rc; i++)
+ {
+ memcpy(&lpImeMenu[i],&lpImeMenuW[1],sizeof(IMEMENUITEMINFOA));
+ lpImeMenu[i].hbmpItem = lpImeMenuW[i].hbmpItem;
+ WideCharToMultiByte(CP_ACP, 0, lpImeMenuW[i].szString,
+ -1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE,
+ NULL, NULL);
+ }
+ }
+ HeapFree(GetProcessHeap(),0,lpImeMenuW);
+ return rc;
+ }
+ }
+ else
+ return 0;
}
/***********************************************************************
LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
DWORD dwSize)
{
- FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType,
- lpImeParentMenu, lpImeMenu, dwSize);
- return 0;
+ InputContextData *data = hIMC;
+ TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
+ lpImeParentMenu, lpImeMenu, dwSize);
+ if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
+ {
+ if (is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
+ return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
+ lpImeParentMenu, lpImeMenu, dwSize);
+ else
+ {
+ IMEMENUITEMINFOA lpImeParentMenuA;
+ IMEMENUITEMINFOA *lpImeMenuA, *parent = NULL;
+ DWORD rc;
+
+ if (lpImeParentMenu)
+ parent = &lpImeParentMenuA;
+ if (lpImeMenu)
+ {
+ int count = dwSize / sizeof(LPIMEMENUITEMINFOW);
+ dwSize = count * sizeof(IMEMENUITEMINFOA);
+ lpImeMenuA = HeapAlloc(GetProcessHeap(), 0, dwSize);
+ }
+ else
+ lpImeMenuA = NULL;
+
+ rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
+ (IMEMENUITEMINFOW*)parent,
+ (IMEMENUITEMINFOW*)lpImeMenuA, dwSize);
+
+ if (lpImeParentMenu)
+ {
+ memcpy(lpImeParentMenu,&lpImeParentMenuA,sizeof(IMEMENUITEMINFOA));
+ lpImeParentMenu->hbmpItem = lpImeParentMenuA.hbmpItem;
+ MultiByteToWideChar(CP_ACP, 0, lpImeParentMenuA.szString,
+ -1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE);
+ }
+ if (lpImeMenu && rc)
+ {
+ unsigned int i;
+ for (i = 0; i < rc; i++)
+ {
+ memcpy(&lpImeMenu[i],&lpImeMenuA[1],sizeof(IMEMENUITEMINFOA));
+ lpImeMenu[i].hbmpItem = lpImeMenuA[i].hbmpItem;
+ MultiByteToWideChar(CP_ACP, 0, lpImeMenuA[i].szString,
+ -1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE);
+ }
+ }
+ HeapFree(GetProcessHeap(),0,lpImeMenuA);
+ return rc;
+ }
+ }
+ else
+ return 0;
}
/***********************************************************************
*/
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
{
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
if (!data)
return NULL;
*/
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
{
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
data->dwLock--;
return (data->dwLock!=0);
}
*/
DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
{
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
return data->dwLock;
}
return NULL;
internal->dwSize = size;
- return (HIMCC)internal;
+ return internal;
}
/***********************************************************************
LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
{
IMCCInternal *internal;
- internal = (IMCCInternal*) imcc;
+ internal = imcc;
internal->dwLock ++;
return internal + 1;
BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
{
IMCCInternal *internal;
- internal = (IMCCInternal*) imcc;
+ internal = imcc;
internal->dwLock --;
return (internal->dwLock!=0);
DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
{
IMCCInternal *internal;
- internal = (IMCCInternal*) imcc;
+ internal = imcc;
return internal->dwLock;
}
IMCCInternal *internal,*newone;
int real_size = size + sizeof(IMCCInternal);
- internal = (IMCCInternal*) imcc;
+ internal = imcc;
newone = HeapReAlloc(GetProcessHeap(), 0, internal, real_size);
newone->dwSize = size;
DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
{
IMCCInternal *internal;
- internal = (IMCCInternal*) imcc;
+ internal = imcc;
return internal->dwSize;
}
*/
BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
{
- InputContextData *data = (InputContextData*)hIMC;
+ InputContextData *data = hIMC;
TRACE("%i messages queued\n",data->IMC.dwNumMsgBuf);
if (data->IMC.dwNumMsgBuf > 0)
{
LPTRANSMSG lpTransMsg;
- INT i;
+ DWORD i;
- lpTransMsg = (LPTRANSMSG)ImmLockIMCC(data->IMC.hMsgBuf);
+ lpTransMsg = ImmLockIMCC(data->IMC.hMsgBuf);
for (i = 0; i < data->IMC.dwNumMsgBuf; i++)
ImmInternalPostIMEMessage(data, lpTransMsg[i].message, lpTransMsg[i].wParam, lpTransMsg[i].lParam);
return TRUE;
}
-/*****
- * Internal functions to help with IME window management
- */
-static void PaintDefaultIMEWnd(HWND hwnd)
+/***********************************************************************
+* ImmTranslateMessage(IMM32.@)
+* ( Undocumented, call internally and from user32.dll )
+*/
+BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyData)
{
- PAINTSTRUCT ps;
- RECT rect;
- HDC hdc = BeginPaint(hwnd,&ps);
- LPCOMPOSITIONSTRING compstr;
- LPBYTE compdata = NULL;
- HMONITOR monitor;
- MONITORINFO mon_info;
- INT offX=0, offY=0;
-
- GetClientRect(hwnd,&rect);
- FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1));
-
- compdata = ImmLockIMCC(root_context->IMC.hCompStr);
- compstr = (LPCOMPOSITIONSTRING)compdata;
-
- if (compstr->dwCompStrLen && compstr->dwCompStrOffset)
- {
- SIZE size;
- POINT pt;
- HFONT oldfont = NULL;
- LPWSTR CompString;
-
- CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
- if (root_context->textfont)
- oldfont = SelectObject(hdc,root_context->textfont);
+ InputContextData *data;
+ HIMC imc = ImmGetContext(hwnd);
+ BYTE state[256];
+ UINT scancode;
+ LPVOID list = 0;
+ UINT msg_count;
+ UINT uVirtKey;
+ static const DWORD list_count = 10;
+ TRACE("%p %x %x %x\n",hwnd, msg, (UINT)wParam, (UINT)lKeyData);
- GetTextExtentPoint32W(hdc, CompString, compstr->dwCompStrLen, &size);
- pt.x = size.cx;
- pt.y = size.cy;
- LPtoDP(hdc,&pt,1);
-
- /*
- * How this works based on tests on windows:
- * CFS_POINT: then we start our window at the point and grow it as large
- * as it needs to be for the string.
- * CFS_RECT: we still use the ptCurrentPos as a starting point and our
- * window is only as large as we need for the string, but we do not
- * grow such that our window exceeds the given rect. Wrapping if
- * needed and possible. If our ptCurrentPos is outside of our rect
- * then no window is displayed.
- * CFS_FORCE_POSITION: appears to behave just like CFS_POINT
- * maybe becase the default MSIME does not do any IME adjusting.
- */
- if (root_context->IMC.cfCompForm.dwStyle != CFS_DEFAULT)
- {
- POINT cpt = root_context->IMC.cfCompForm.ptCurrentPos;
- ClientToScreen(root_context->IMC.hWnd,&cpt);
- rect.left = cpt.x;
- rect.top = cpt.y;
- rect.right = rect.left + pt.x;
- rect.bottom = rect.top + pt.y;
- monitor = MonitorFromPoint(cpt, MONITOR_DEFAULTTOPRIMARY);
- }
- else /* CFS_DEFAULT */
- {
- /* Windows places the default IME window in the bottom left */
- HWND target = root_context->IMC.hWnd;
- if (!target) target = GetFocus();
-
- GetWindowRect(target,&rect);
- rect.top = rect.bottom;
- rect.right = rect.left + pt.x + 20;
- rect.bottom = rect.top + pt.y + 20;
- offX=offY=10;
- monitor = MonitorFromWindow(target, MONITOR_DEFAULTTOPRIMARY);
- }
-
- if (root_context->IMC.cfCompForm.dwStyle == CFS_RECT)
- {
- RECT client;
- client =root_context->IMC.cfCompForm.rcArea;
- MapWindowPoints( root_context->IMC.hWnd, 0, (POINT *)&client, 2 );
- IntersectRect(&rect,&rect,&client);
- /* TODO: Wrap the input if needed */
- }
+ if (imc)
+ data = imc;
+ else
+ return FALSE;
- if (root_context->IMC.cfCompForm.dwStyle == CFS_DEFAULT)
- {
- /* make sure we are on the desktop */
- mon_info.cbSize = sizeof(mon_info);
- GetMonitorInfoW(monitor, &mon_info);
+ if (!data->immKbd->hIME || !data->immKbd->pImeToAsciiEx)
+ return FALSE;
- if (rect.bottom > mon_info.rcWork.bottom)
- {
- int shift = rect.bottom - mon_info.rcWork.bottom;
- rect.top -= shift;
- rect.bottom -= shift;
- }
- if (rect.left < 0)
- {
- rect.right -= rect.left;
- rect.left = 0;
- }
- if (rect.right > mon_info.rcWork.right)
- {
- int shift = rect.right - mon_info.rcWork.right;
- rect.left -= shift;
- rect.right -= shift;
- }
- }
+ GetKeyboardState(state);
+ scancode = lKeyData >> 0x10 & 0xff;
- SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE);
+ list = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, list_count * sizeof(TRANSMSG) + sizeof(DWORD));
+ ((DWORD*)list)[0] = list_count;
- TextOutW(hdc, offX,offY, CompString, compstr->dwCompStrLen);
+ if (data->immKbd->imeInfo.fdwProperty & IME_PROP_KBD_CHAR_FIRST)
+ {
+ WCHAR chr;
- if (oldfont)
- SelectObject(hdc,oldfont);
+ if (!is_himc_ime_unicode(data))
+ ToAscii(data->lastVK, scancode, state, &chr, 0);
+ else
+ ToUnicodeEx(data->lastVK, scancode, state, &chr, 1, 0, GetKeyboardLayout(0));
+ uVirtKey = MAKELONG(data->lastVK,chr);
}
+ else
+ uVirtKey = data->lastVK;
- ImmUnlockIMCC(root_context->IMC.hCompStr);
-
- EndPaint(hwnd,&ps);
-}
-
-static void UpdateDataInDefaultIMEWindow(HWND hwnd, BOOL showable)
-{
- LPCOMPOSITIONSTRING compstr;
+ msg_count = data->immKbd->pImeToAsciiEx(uVirtKey, scancode, state, list, 0, imc);
+ TRACE("%i messages generated\n",msg_count);
+ if (msg_count && msg_count <= list_count)
+ {
+ UINT i;
+ LPTRANSMSG msgs = (LPTRANSMSG)((LPBYTE)list + sizeof(DWORD));
- if (root_context->IMC.hCompStr)
- compstr = ImmLockIMCC(root_context->IMC.hCompStr);
- else
- compstr = NULL;
+ for (i = 0; i < msg_count; i++)
+ ImmInternalPostIMEMessage(data, msgs[i].message, msgs[i].wParam, msgs[i].lParam);
+ }
+ else if (msg_count > list_count)
+ ImmGenerateMessage(imc);
- if (compstr == NULL || compstr->dwCompStrLen == 0)
- ShowWindow(hwndDefault,SW_HIDE);
- else if (showable)
- ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
+ HeapFree(GetProcessHeap(),0,list);
- RedrawWindow(hwnd,NULL,NULL,RDW_ERASENOW|RDW_INVALIDATE);
+ data->lastVK = VK_PROCESSKEY;
- if (compstr != NULL)
- ImmUnlockIMCC(root_context->IMC.hCompStr);
+ return (msg_count > 0);
}
-/*
- * The window proc for the default IME window
- */
-static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
- LPARAM lParam)
+/***********************************************************************
+* ImmProcessKey(IMM32.@)
+* ( Undocumented, called from user32.dll )
+*/
+BOOL WINAPI ImmProcessKey(HWND hwnd, HKL hKL, UINT vKey, LPARAM lKeyData, DWORD unknown)
{
- LRESULT rc = 0;
+ InputContextData *data;
+ HIMC imc = ImmGetContext(hwnd);
+ BYTE state[256];
- TRACE("Incoming Message 0x%x (0x%08x, 0x%08x)\n", msg, (UINT)wParam,
- (UINT)lParam);
+ TRACE("%p %p %x %x %x\n",hwnd, hKL, vKey, (UINT)lKeyData, unknown);
- switch(msg)
- {
- case WM_PAINT:
- PaintDefaultIMEWnd(hwnd);
- return FALSE;
-
- case WM_NCCREATE:
- return TRUE;
+ if (imc)
+ data = imc;
+ else
+ return FALSE;
- case WM_CREATE:
- SetWindowTextA(hwnd,"Wine Ime Active");
- return TRUE;
+ if (!data->immKbd->hIME || !data->immKbd->pImeProcessKey)
+ return FALSE;
- case WM_SETFOCUS:
- if (wParam)
- SetFocus((HWND)wParam);
- else
- FIXME("Received focus, should never have focus\n");
- break;
- case WM_IME_COMPOSITION:
- TRACE("IME message %s, 0x%x, 0x%x (%i)\n",
- "WM_IME_COMPOSITION", (UINT)wParam, (UINT)lParam,
- root_context->bRead);
- if (lParam & GCS_RESULTSTR)
- IMM_PostResult(root_context);
- else
- UpdateDataInDefaultIMEWindow(hwnd,TRUE);
- break;
- case WM_IME_STARTCOMPOSITION:
- TRACE("IME message %s, 0x%x, 0x%x\n",
- "WM_IME_STARTCOMPOSITION", (UINT)wParam, (UINT)lParam);
- root_context->IMC.hWnd = GetFocus();
- ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
- break;
- case WM_IME_ENDCOMPOSITION:
- TRACE("IME message %s, 0x%x, 0x%x\n",
- "WM_IME_ENDCOMPOSITION", (UINT)wParam, (UINT)lParam);
- ShowWindow(hwndDefault,SW_HIDE);
- break;
- case WM_IME_SELECT:
- TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_SELECT",
- (UINT)wParam, (UINT)lParam);
- break;
- case WM_IME_CONTROL:
- TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_CONTROL",
- (UINT)wParam, (UINT)lParam);
- rc = 1;
- break;
- case WM_IME_NOTIFY:
- TRACE("!! IME NOTIFY\n");
- break;
- default:
- TRACE("Non-standard message 0x%x\n",msg);
- }
- /* check the MSIME messages */
- if (msg == WM_MSIME_SERVICE)
- {
- TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_SERVICE",
- (UINT)wParam, (UINT)lParam);
- rc = FALSE;
- }
- else if (msg == WM_MSIME_RECONVERTOPTIONS)
- {
- TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTOPTIONS",
- (UINT)wParam, (UINT)lParam);
- }
- else if (msg == WM_MSIME_MOUSE)
- {
- TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_MOUSE",
- (UINT)wParam, (UINT)lParam);
- }
- else if (msg == WM_MSIME_RECONVERTREQUEST)
- {
- TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTREQUEST",
- (UINT)wParam, (UINT)lParam);
- }
- else if (msg == WM_MSIME_RECONVERT)
- {
- TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERT",
- (UINT)wParam, (UINT)lParam);
- }
- else if (msg == WM_MSIME_QUERYPOSITION)
- {
- TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_QUERYPOSITION",
- (UINT)wParam, (UINT)lParam);
- }
- else if (msg == WM_MSIME_DOCUMENTFEED)
+ GetKeyboardState(state);
+ if (data->immKbd->pImeProcessKey(imc, vKey, lKeyData, state))
{
- TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_DOCUMENTFEED",
- (UINT)wParam, (UINT)lParam);
+ data->lastVK = vKey;
+ return TRUE;
}
- /* DefWndProc if not an IME message */
- else if (!rc && !((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
- (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP)))
- rc = DefWindowProcW(hwnd,msg,wParam,lParam);
- return rc;
+ data->lastVK = VK_PROCESSKEY;
+ return FALSE;
+}
+
+/***********************************************************************
+* ImmDisableTextFrameService(IMM32.@)
+*/
+BOOL WINAPI ImmDisableTextFrameService(DWORD idThread)
+{
+ FIXME("Stub\n");
+ return FALSE;
}