From 0dc710cadaa10557ead0a154f69df94201b941cc Mon Sep 17 00:00:00 2001 From: Dmitry Chapyshev Date: Thu, 8 May 2008 16:03:10 +0000 Subject: [PATCH] - Revert r33314 svn path=/trunk/; revision=33367 --- reactos/dll/win32/imm32/imm.c | 2214 ++++++++++++++-------------- reactos/dll/win32/imm32/imm32.spec | 14 +- 2 files changed, 1084 insertions(+), 1144 deletions(-) diff --git a/reactos/dll/win32/imm32/imm.c b/reactos/dll/win32/imm32/imm.c index ce28f481d02..4ba1d631313 100644 --- a/reactos/dll/win32/imm32/imm.c +++ b/reactos/dll/win32/imm32/imm.c @@ -20,7 +20,6 @@ */ #include -#include #include "windef.h" #include "winbase.h" @@ -36,6 +35,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm); +#define FROM_IME 0xcafe1337 + +static void (*pX11DRV_ForceXIMReset)(HWND); + typedef struct tagIMCCInternal { DWORD dwLock; @@ -73,12 +76,15 @@ typedef struct _tagImmHkl{ 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 { @@ -87,12 +93,12 @@ typedef struct _tagTRANSMSG { LPARAM lParam; } TRANSMSG, *LPTRANSMSG; -typedef struct _tagIMMThreadData { - HIMC defaultContext; - HWND hwndDefault; -} IMMThreadData; +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; -static DWORD tlsIndex = 0; static struct list ImmHklList = LIST_INIT(ImmHklList); /* MSIME messages */ @@ -105,167 +111,15 @@ static UINT WM_MSIME_QUERYPOSITION; 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}; - -#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) -{ - return (IMMThreadData*)TlsGetValue(tlsIndex); -} - -static void IMM_InitThreadData(void) -{ - IMMThreadData* data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(IMMThreadData)); - TlsSetValue(tlsIndex,data); - - TRACE("Thread Data Created\n"); -} - -static void IMM_FreeThreadData(void) -{ - IMMThreadData* data = TlsGetValue(tlsIndex); - 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; -} +/* + * 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); /* 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);} @@ -287,49 +141,32 @@ static ImmHkl *IMM_GetImmHkl(HKL hkl) 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); - if (!ptr->pImeInquire || !ptr->pImeInquire(&ptr->imeInfo, ptr->imeClassName, NULL)) + LOAD_FUNCPTR(ImeDestroy); + LOAD_FUNCPTR(ImeSelect); + if (!ptr->pImeInquire || !ptr->pImeDestroy || !ptr->pImeSelect) { FreeLibrary(ptr->hIME); ptr->hIME = NULL; } else { - 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); - } - } + 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); } } list_add_head(&ImmHklList,&ptr->entry); @@ -354,6 +191,54 @@ static void IMM_FreeAllImmHkl(void) } } +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"); @@ -365,26 +250,29 @@ static void IMM_RegisterMessages(void) 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(); - tlsIndex = TlsAlloc(); - IMM_InitThreadData(); - break; - case DLL_THREAD_ATTACH: - IMM_InitThreadData(); - break; - case DLL_THREAD_DETACH: - IMM_FreeThreadData(); + x11drv = GetModuleHandleA("winex11.drv"); + if (x11drv) pX11DRV_ForceXIMReset = (void *)GetProcAddress( x11drv, "ForceXIMReset"); break; case DLL_PROCESS_DETACH: - IMM_FreeThreadData(); + if (hwndDefault) + { + DestroyWindow(hwndDefault); + hwndDefault = 0; + } + IMM_Unregister(); IMM_FreeAllImmHkl(); - TlsFree(tlsIndex); break; } return TRUE; @@ -425,6 +313,312 @@ static HIMCC ImmCreateBlankCompStr(void) 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.@) */ @@ -435,8 +629,14 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC) TRACE("(%p, %p):\n", hWnd, hIMC); - if (!IMM_GetThreadData()->defaultContext) - IMM_GetThreadData()->defaultContext = ImmCreateContext(); + /* + * WINE SPECIFIC! MAY CONFLICT + * associate the root context we have an XIM created + */ + if (hWnd == 0x000) + { + root_context = (InputContextData*)hIMC; + } /* * If already associated just return @@ -449,24 +649,17 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC) old = (HIMC)RemovePropW(hWnd,szwWineIMCProperty); if (old == NULL) - old = IMM_GetThreadData()->defaultContext; + old = (HIMC)root_context; else if (old == (HIMC)-1) old = NULL; - if (hIMC != IMM_GetThreadData()->defaultContext) + if (hIMC != (HIMC)root_context) { if (hIMC == NULL) /* Meaning disable imm for that window*/ SetPropW(hWnd,szwWineIMCProperty,(HANDLE)-1); else SetPropW(hWnd,szwWineIMCProperty,(HANDLE)hIMC); } - - if (old) - { - InputContextData *old_data = (InputContextData*)old; - if (old_data->IMC.hWnd == hWnd) - old_data->IMC.hWnd = NULL; - } } if (!hIMC) @@ -509,30 +702,11 @@ BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags) BOOL WINAPI ImmConfigureIMEA( HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData) { - ImmHkl *immHkl = IMM_GetImmHkl(hKL); - - TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData); - - 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 = (REGISTERWORDA*)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; + FIXME("(%p, %p, %d, %p): stub\n", + hKL, hWnd, dwMode, lpData + ); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /*********************************************************************** @@ -541,30 +715,11 @@ BOOL WINAPI ImmConfigureIMEA( BOOL WINAPI ImmConfigureIMEW( HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData) { - ImmHkl *immHkl = IMM_GetImmHkl(hKL); - - TRACE("(%p, %p, %d, %p):\n", hKL, hWnd, dwMode, lpData); - - 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 = (REGISTERWORDW*)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; + FIXME("(%p, %p, %d, %p): stub\n", + hKL, hWnd, dwMode, lpData + ); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /*********************************************************************** @@ -573,42 +728,31 @@ BOOL WINAPI ImmConfigureIMEW( 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; - } - /* the HIMCCs are never NULL */ + /* hCompStr is never NULL */ new_context->IMC.hCompStr = ImmCreateBlankCompStr(); - 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); + new_context->IMC.hMsgBuf = ImmCreateIMCC(1); /* Initialize the IME Private */ new_context->IMC.hPrivate = ImmCreateIMCC(new_context->immKbd->imeInfo.dwPrivateDataSize); - if (!new_context->immKbd->pImeSelect(new_context, TRUE)) + if (new_context->immKbd->hIME && + !new_context->immKbd->pImeSelect(new_context, TRUE)) { TRACE("Selection of IME failed\n"); - IMM_DestroyContext(new_context); + ImmDestroyContext(new_context); return 0; } @@ -618,7 +762,10 @@ HIMC WINAPI ImmCreateContext(void) return (HIMC)new_context; } -static BOOL IMM_DestroyContext(HIMC hIMC) +/*********************************************************************** + * ImmDestroyContext (IMM32.@) + */ +BOOL WINAPI ImmDestroyContext(HIMC hIMC) { InputContextData *data = (InputContextData*)hIMC; @@ -627,11 +774,8 @@ static BOOL IMM_DestroyContext(HIMC hIMC) if (hIMC) { data->immKbd->uSelected --; - data->immKbd->pImeSelect(hIMC, FALSE); - - if (IMM_GetThreadData()->hwndDefault == data->imeWnd) - IMM_GetThreadData()->hwndDefault = NULL; - DestroyWindow(data->imeWnd); + if (data->immKbd->hIME) + data->immKbd->pImeSelect(hIMC, FALSE); ImmDestroyIMCC(data->IMC.hCompStr); ImmDestroyIMCC(data->IMC.hCandInfo); @@ -639,22 +783,17 @@ static BOOL IMM_DestroyContext(HIMC hIMC) 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.@) */ @@ -672,31 +811,13 @@ UINT WINAPI ImmEnumRegisterWordA( LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister, LPVOID lpData) { - 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; + 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; } /*********************************************************************** @@ -707,30 +828,13 @@ UINT WINAPI ImmEnumRegisterWordW( LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister, LPVOID lpData) { - 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; + 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; } /*********************************************************************** @@ -740,22 +844,11 @@ LRESULT WINAPI ImmEscapeA( HKL hKL, HIMC hIMC, UINT uEscape, LPVOID lpData) { - ImmHkl *immHkl = IMM_GetImmHkl(hKL); - TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData); - - if (immHkl->hIME && immHkl->pImeEscape) - { - if (!is_kbd_ime_unicode(immHkl)) - return immHkl->pImeEscape(hIMC,uEscape,lpData); - else - { - FIXME("A procedure called with W ime back end\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; - } - } - else - return 0; + FIXME("(%p, %p, %d, %p): stub\n", + hKL, hIMC, uEscape, lpData + ); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } /*********************************************************************** @@ -765,62 +858,26 @@ LRESULT WINAPI ImmEscapeW( HKL hKL, HIMC hIMC, UINT uEscape, LPVOID lpData) { - ImmHkl *immHkl = IMM_GetImmHkl(hKL); - TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData); - - if (immHkl->hIME && immHkl->pImeEscape) - { - if (is_kbd_ime_unicode(immHkl)) - return immHkl->pImeEscape(hIMC,uEscape,lpData); - else - { - FIXME("W procedure called with A ime back end\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; - } - } - else - return 0; + FIXME("(%p, %p, %d, %p): stub\n", + hKL, hIMC, uEscape, lpData + ); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } /*********************************************************************** * ImmGetCandidateListA (IMM32.@) */ DWORD WINAPI ImmGetCandidateListA( - HIMC hIMC, DWORD dwIndex, + HIMC hIMC, DWORD deIndex, LPCANDIDATELIST lpCandList, DWORD dwBufLen) { - InputContextData *data = (InputContextData *)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; + FIXME("(%p, %d, %p, %d): stub\n", + hIMC, deIndex, + lpCandList, dwBufLen + ); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } /*********************************************************************** @@ -829,30 +886,9 @@ done: DWORD WINAPI ImmGetCandidateListCountA( HIMC hIMC, LPDWORD lpdwListCount) { - InputContextData *data = (InputContextData *)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; + FIXME("(%p, %p): stub\n", hIMC, lpdwListCount); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } /*********************************************************************** @@ -861,91 +897,35 @@ DWORD WINAPI ImmGetCandidateListCountA( DWORD WINAPI ImmGetCandidateListCountW( HIMC hIMC, LPDWORD lpdwListCount) { - InputContextData *data = (InputContextData *)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; + FIXME("(%p, %p): stub\n", hIMC, lpdwListCount); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } /*********************************************************************** * ImmGetCandidateListW (IMM32.@) */ DWORD WINAPI ImmGetCandidateListW( - HIMC hIMC, DWORD dwIndex, + HIMC hIMC, DWORD deIndex, LPCANDIDATELIST lpCandList, DWORD dwBufLen) { - InputContextData *data = (InputContextData *)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; + FIXME("(%p, %d, %p, %d): stub\n", + hIMC, deIndex, + lpCandList, dwBufLen + ); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } /*********************************************************************** * ImmGetCandidateWindow (IMM32.@) */ BOOL WINAPI ImmGetCandidateWindow( - HIMC hIMC, DWORD dwIndex, LPCANDIDATEFORM lpCandidate) + HIMC hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate) { - InputContextData *data = (InputContextData*)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; + FIXME("(%p, %d, %p): stub\n", hIMC, dwBufLen, lpCandidate); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /*********************************************************************** @@ -959,13 +939,13 @@ BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf) TRACE("(%p, %p):\n", hIMC, lplf); rc = ImmGetCompositionFontW(hIMC,&lfW); - if (!rc || !lplf) - return FALSE; - - memcpy(lplf,&lfW,sizeof(LOGFONTA)); - WideCharToMultiByte(CP_ACP, 0, lfW.lfFaceName, -1, lplf->lfFaceName, + if (rc) + { + memcpy(lplf,&lfW,sizeof(LOGFONTA)); + WideCharToMultiByte(CP_ACP, 0, lfW.lfFaceName, -1, lplf->lfFaceName, LF_FACESIZE, NULL, NULL); - return TRUE; + } + return rc; } /*********************************************************************** @@ -977,7 +957,7 @@ BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf) TRACE("(%p, %p):\n", hIMC, lplf); - if (!data || !lplf) + if (!data) return FALSE; *lplf = data->IMC.lfFont.W; @@ -1013,7 +993,7 @@ LONG WINAPI ImmGetCompositionStringA( { LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset); - TRACE("GCS_RESULTSTR %p %i\n",ResultStr, + TRACE("GSC_RESULTSTR %p %i\n",ResultStr, compstr->dwResultStrLen); buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwResultStrLen * 3 ); @@ -1023,6 +1003,7 @@ LONG WINAPI ImmGetCompositionStringA( if (dwBufLen >= rc) memcpy(lpBuf,buf,rc); + data->bRead = TRUE; HeapFree( GetProcessHeap(), 0, buf ); } else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 && @@ -1030,7 +1011,7 @@ LONG WINAPI ImmGetCompositionStringA( { LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset); - TRACE("GCS_COMPSTR %p %i\n", CompString, compstr->dwCompStrLen); + TRACE("GSC_COMPSTR %p %i\n", CompString, compstr->dwCompStrLen); buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwCompStrLen * 3 ); rc = WideCharToMultiByte(CP_ACP, 0, CompString, @@ -1044,7 +1025,7 @@ LONG WINAPI ImmGetCompositionStringA( compstr->dwCompAttrOffset > 0) { LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset); - TRACE("GCS_COMPATTR %p %i\n", Compattr , compstr->dwCompAttrLen); + TRACE("GSC_COMPATTR %p %i\n", Compattr , compstr->dwCompAttrLen); rc = compstr->dwCompAttrLen; if (dwBufLen >= rc) @@ -1054,7 +1035,7 @@ LONG WINAPI ImmGetCompositionStringA( compstr->dwCompClauseOffset > 0) { LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset); - TRACE("GCS_COMPCLAUSE %p %i\n", Compclause, compstr->dwCompClauseLen); + TRACE("GSC_COMPCLAUSE %p %i\n", Compclause, compstr->dwCompClauseLen); rc = compstr->dwCompClauseLen; if (dwBufLen >= compstr->dwCompClauseLen) @@ -1064,7 +1045,7 @@ LONG WINAPI ImmGetCompositionStringA( compstr->dwResultClauseOffset > 0) { LPWSTR Resultclause = (LPWSTR)(compdata + compstr->dwResultClauseOffset); - TRACE("GCS_RESULTCLAUSE %p %i\n", Resultclause, compstr->dwResultClauseLen); + TRACE("GSC_RESULTCLAUSE %p %i\n", Resultclause, compstr->dwResultClauseLen); rc = compstr->dwResultClauseLen; if (dwBufLen >= compstr->dwResultClauseLen) @@ -1072,7 +1053,7 @@ LONG WINAPI ImmGetCompositionStringA( } else if (dwIndex == GCS_CURSORPOS) { - TRACE("GCS_CURSORPOS\n"); + TRACE("GSC_CURSORPOS\n"); rc = compstr->dwCursorPos; } else if (dwIndex == GCS_DELTASTART) @@ -1117,6 +1098,7 @@ LONG WINAPI ImmGetCompositionStringW( compstr->dwResultStrOffset > 0) { LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset); + data->bRead = TRUE; rc = compstr->dwResultStrLen * sizeof(WCHAR); if (dwBufLen >= rc) @@ -1170,7 +1152,7 @@ LONG WINAPI ImmGetCompositionStringW( } else if (dwIndex == GCS_CURSORPOS) { - TRACE("GCS_CURSORPOS\n"); + TRACE("GSC_CURSORPOS\n"); rc = compstr->dwCursorPos; } else if (dwIndex == GCS_DELTASTART) @@ -1181,7 +1163,7 @@ LONG WINAPI ImmGetCompositionStringW( else { FIXME("Unhandled index 0x%x\n",dwIndex); - } + } ImmUnlockIMCC(data->IMC.hCompStr); @@ -1213,14 +1195,12 @@ HIMC WINAPI ImmGetContext(HWND hWnd) HIMC rc = NULL; TRACE("%p\n", hWnd); - if (!IMM_GetThreadData()->defaultContext) - IMM_GetThreadData()->defaultContext = ImmCreateContext(); rc = (HIMC)GetPropW(hWnd,szwWineIMCProperty); if (rc == (HIMC)-1) rc = NULL; else if (rc == NULL) - rc = IMM_GetThreadData()->defaultContext; + rc = (HIMC)root_context; if (rc) { @@ -1240,34 +1220,11 @@ DWORD WINAPI ImmGetConversionListA( LPCSTR pSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen, UINT uFlag) { - 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; + FIXME("(%p, %p, %s, %p, %d, %d): stub\n", + hKL, hIMC, debugstr_a(pSrc), lpDst, dwBufLen, uFlag + ); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } /*********************************************************************** @@ -1278,34 +1235,11 @@ DWORD WINAPI ImmGetConversionListW( LPCWSTR pSrc, LPCANDIDATELIST lpDst, DWORD dwBufLen, UINT uFlag) { - 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; + FIXME("(%p, %p, %s, %p, %d, %d): stub\n", + hKL, hIMC, debugstr_w(pSrc), lpDst, dwBufLen, uFlag + ); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } /*********************************************************************** @@ -1314,18 +1248,11 @@ DWORD WINAPI ImmGetConversionListW( BOOL WINAPI ImmGetConversionStatus( HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence) { - InputContextData *data = (InputContextData*)hIMC; - - TRACE("%p %p %p\n", hIMC, lpfdwConversion, lpfdwSentence); - - if (!data) - return FALSE; - + TRACE("(%p, %p, %p): best guess\n", hIMC, lpfdwConversion, lpfdwSentence); if (lpfdwConversion) - *lpfdwConversion = data->IMC.fdwConversion; + *lpfdwConversion = IME_CMODE_NATIVE; if (lpfdwSentence) - *lpfdwSentence = data->IMC.fdwSentence; - + *lpfdwSentence = IME_SMODE_NONE; return TRUE; } @@ -1334,8 +1261,26 @@ BOOL WINAPI ImmGetConversionStatus( */ HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd) { - TRACE("Default is %x\n",(unsigned)IMM_GetThreadData()->hwndDefault); - return IMM_GetThreadData()->hwndDefault; + 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; } /*********************************************************************** @@ -1510,24 +1455,40 @@ BOOL WINAPI ImmGetOpenStatus(HIMC hIMC) DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex) { DWORD rc = 0; - ImmHkl *kbd; - TRACE("(%p, %d)\n", hKL, fdwIndex); - kbd = IMM_GetImmHkl(hKL); - if (kbd && kbd->hIME) + switch (fdwIndex) { - 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; - } + 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; } return rc; } @@ -1538,26 +1499,9 @@ DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex) UINT WINAPI ImmGetRegisterWordStyleA( HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf) { - 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; + FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } /*********************************************************************** @@ -1566,26 +1510,9 @@ UINT WINAPI ImmGetRegisterWordStyleA( UINT WINAPI ImmGetRegisterWordStyleW( HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf) { - 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; + FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; } /*********************************************************************** @@ -1593,16 +1520,9 @@ UINT WINAPI ImmGetRegisterWordStyleW( */ BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos) { - InputContextData *data = (InputContextData*)hIMC; - - TRACE("(%p, %p)\n", hIMC, lpptPos); - - if (!data || !lpptPos) - return FALSE; - - *lpptPos = data->IMC.ptStatusWndPos; - - return TRUE; + FIXME("(%p, %p): stub\n", hIMC, lpptPos); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /*********************************************************************** @@ -1611,12 +1531,7 @@ BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos) UINT WINAPI ImmGetVirtualKey(HWND hWnd) { OSVERSIONINFOA version; - InputContextData *data = (InputContextData *)ImmGetContext( hWnd ); - TRACE("%p\n", hWnd); - - if ( data ) - return data->lastVK; - + FIXME("(%p): stub\n", hWnd); GetVersionExA( &version ); switch(version.dwPlatformId) { @@ -1661,10 +1576,12 @@ HKL WINAPI ImmInstallIMEW( */ BOOL WINAPI ImmIsIME(HKL hKL) { - ImmHkl *ptr; - TRACE("(%p):\n", hKL); - ptr = IMM_GetImmHkl(hKL); - return (ptr && ptr->hIME); + 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); } /*********************************************************************** @@ -1687,11 +1604,11 @@ BOOL WINAPI ImmIsUIMessageA( (msg == WM_MSIME_DOCUMENTFEED)) { - if (!IMM_GetThreadData()->hwndDefault) + if (!hwndDefault) ImmGetDefaultIMEWnd(NULL); if (hWndIME == NULL) - PostMessageA(IMM_GetThreadData()->hwndDefault, msg, wParam, lParam); + PostMessageA(hwndDefault, msg, wParam, lParam); rc = TRUE; } @@ -1705,7 +1622,7 @@ BOOL WINAPI ImmIsUIMessageW( HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam) { BOOL rc = FALSE; - TRACE("(%p, %d, %ld, %ld):\n", hWndIME, msg, wParam, lParam); + TRACE("(%p, %d, %ld, %ld): stub\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) || @@ -1725,15 +1642,126 @@ BOOL WINAPI ImmIsUIMessageW( BOOL WINAPI ImmNotifyIME( HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue) { - InputContextData *data = (InputContextData*)hIMC; + BOOL rc = FALSE; TRACE("(%p, %d, %d, %d)\n", hIMC, dwAction, dwIndex, dwValue); - if (!data || ! data->immKbd->pNotifyIME) - return FALSE; + if (!root_context) + return rc; - return data->immKbd->pNotifyIME(hIMC,dwAction,dwIndex,dwValue); + 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"); + } + + return rc; } /*********************************************************************** @@ -1742,28 +1770,11 @@ BOOL WINAPI ImmNotifyIME( BOOL WINAPI ImmRegisterWordA( HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister) { - 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; + FIXME("(%p, %s, %d, %s): stub\n", + hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister) + ); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /*********************************************************************** @@ -1772,28 +1783,11 @@ BOOL WINAPI ImmRegisterWordA( BOOL WINAPI ImmRegisterWordW( HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister) { - 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; + FIXME("(%p, %s, %d, %s): stub\n", + hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister) + ); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /*********************************************************************** @@ -1810,63 +1804,15 @@ BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC) return TRUE; } -/*********************************************************************** -* ImmRequestMessageA(IMM32.@) -*/ -LRESULT WINAPI ImmRequestMessageA(HIMC hIMC, WPARAM wParam, LPARAM lParam) -{ - InputContextData *data = (InputContextData*)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 = (InputContextData*)hIMC; - - 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; -} - /*********************************************************************** * ImmSetCandidateWindow (IMM32.@) */ BOOL WINAPI ImmSetCandidateWindow( HIMC hIMC, LPCANDIDATEFORM lpCandidate) { - InputContextData *data = (InputContextData*)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; + FIXME("(%p, %p): stub\n", hIMC, lpCandidate); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /*********************************************************************** @@ -1877,15 +1823,22 @@ BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf) InputContextData *data = (InputContextData*)hIMC; TRACE("(%p, %p)\n", hIMC, lplf); - if (!data || !lplf) + if (!data) 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; } @@ -1897,13 +1850,18 @@ BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf) InputContextData *data = (InputContextData*)hIMC; TRACE("(%p, %p)\n", hIMC, lplf); - if (!data || !lplf) + if (!data) 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; } @@ -1920,18 +1878,10 @@ BOOL WINAPI ImmSetCompositionStringA( WCHAR *CompBuffer = NULL; WCHAR *ReadBuffer = NULL; BOOL rc; - InputContextData *data = (InputContextData*)hIMC; - TRACE("(%p, %d, %p, %d, %p, %d):\n", + TRACE("(%p, %d, %p, %d, %p, %d): stub\n", hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen); - if (!data) - 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) { @@ -1963,48 +1913,64 @@ BOOL WINAPI ImmSetCompositionStringW( LPCVOID lpComp, DWORD dwCompLen, LPCVOID lpRead, DWORD dwReadLen) { - DWORD comp_len; - DWORD read_len; - CHAR *CompBuffer = NULL; - CHAR *ReadBuffer = NULL; - BOOL rc; - InputContextData *data = (InputContextData*)hIMC; + DWORD flags = 0; + WCHAR wParam = 0; - TRACE("(%p, %d, %p, %d, %p, %d):\n", - hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen); + TRACE("(%p, %d, %p, %d, %p, %d): stub\n", + hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen); - if (!data) - return FALSE; - if (is_himc_ime_unicode(data)) - return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp, - dwCompLen, lpRead, dwReadLen); + if (hIMC != (HIMC)FROM_IME) + FIXME("PROBLEM: This only sets the wine level string\n"); - comp_len = WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, NULL, 0, NULL, - NULL); - if (comp_len) + /* + * 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 (lpRead && dwReadLen) + FIXME("Reading string unimplemented\n"); + + /* + * app operating this api to also receive the message from xim + */ + + if (dwIndex == SCS_SETSTR) { - CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len); - WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len, - NULL, NULL); + 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; + + 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 rc; + return TRUE; } /*********************************************************************** @@ -2026,16 +1992,16 @@ BOOL WINAPI ImmSetCompositionWindow( data->IMC.cfCompForm = *lpCompForm; - if (IsWindowVisible(IMM_GetThreadData()->hwndDefault)) + if (IsWindowVisible(hwndDefault)) { reshow = TRUE; - ShowWindow(IMM_GetThreadData()->hwndDefault,SW_HIDE); + ShowWindow(hwndDefault,SW_HIDE); } /* FIXME: this is a partial stub */ if (reshow) - ShowWindow(IMM_GetThreadData()->hwndDefault,SW_SHOWNOACTIVATE); + ShowWindow(hwndDefault,SW_SHOWNOACTIVATE); ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0); return TRUE; @@ -2047,30 +2013,16 @@ BOOL WINAPI ImmSetCompositionWindow( BOOL WINAPI ImmSetConversionStatus( HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence) { - DWORD oldConversion, oldSentence; - InputContextData *data = (InputContextData*)hIMC; + static int shown = 0; - 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; + if (!shown) { + FIXME("(%p, %d, %d): stub\n", + hIMC, fdwConversion, fdwSentence + ); + shown = 1; + } + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /*********************************************************************** @@ -2082,26 +2034,36 @@ BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen) 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 (data->imeWnd == NULL) + if (fOpen != data->bInternalState) { - /* 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); - SetWindowLongW(data->imeWnd, IMMGWL_IMC, (LONG)data); - IMM_GetThreadData()->hwndDefault = data->imeWnd; - } + if (fOpen == FALSE && pX11DRV_ForceXIMReset) + pX11DRV_ForceXIMReset(data->IMC.hWnd); - if (!fOpen != !data->IMC.fOpen) - { - data->IMC.fOpen = fOpen; - ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS); - ImmInternalSendIMENotify(data, IMN_SETOPENSTATUS, 0); - } + if (fOpen == FALSE) + ImmInternalPostIMEMessage(data, WM_IME_ENDCOMPOSITION,0,0); + else + ImmInternalPostIMEMessage(data, WM_IME_STARTCOMPOSITION,0,0); + ImmInternalSetOpenStatus(fOpen); + ImmInternalSetOpenStatus(!fOpen); + + if (data->IMC.fOpen == FALSE) + ImmInternalPostIMEMessage(data, WM_IME_ENDCOMPOSITION,0,0); + else + ImmInternalPostIMEMessage(data, WM_IME_STARTCOMPOSITION,0,0); + + return FALSE; + } return TRUE; } @@ -2110,50 +2072,9 @@ BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen) */ BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos) { - InputContextData *data = (InputContextData*)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; -} - -/*********************************************************************** - * ImmCreateSoftKeyboard(IMM32.@) - */ -HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y) -{ - 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; + FIXME("(%p, %p): stub\n", hIMC, lpptPos); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /*********************************************************************** @@ -2172,28 +2093,11 @@ BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID) BOOL WINAPI ImmUnregisterWordA( HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister) { - 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; + FIXME("(%p, %s, %d, %s): stub\n", + hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister) + ); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /*********************************************************************** @@ -2202,28 +2106,11 @@ BOOL WINAPI ImmUnregisterWordA( BOOL WINAPI ImmUnregisterWordW( HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister) { - 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; + FIXME("(%p, %s, %d, %s): stub\n", + hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister) + ); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /*********************************************************************** @@ -2233,61 +2120,9 @@ DWORD WINAPI ImmGetImeMenuItemsA( HIMC hIMC, DWORD dwFlags, DWORD dwType, LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu, DWORD dwSize) { - InputContextData *data = (InputContextData*)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) - { - 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; + FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType, + lpImeParentMenu, lpImeMenu, dwSize); + return 0; } /*********************************************************************** @@ -2297,59 +2132,9 @@ DWORD WINAPI ImmGetImeMenuItemsW( HIMC hIMC, DWORD dwFlags, DWORD dwType, LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu, DWORD dwSize) { - InputContextData *data = (InputContextData*)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) - { - 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; + FIXME("(%p, %i, %i, %p, %p, %i): stub\n", hIMC, dwFlags, dwType, + lpImeParentMenu, lpImeMenu, dwSize); + return 0; } /*********************************************************************** @@ -2496,97 +2281,252 @@ BOOL WINAPI ImmGenerateMessage(HIMC hIMC) return TRUE; } -/*********************************************************************** -* ImmTranslateMessage(IMM32.@) -* ( Undocumented, call internally and from user32.dll ) -*/ -BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyData) +/***** + * Internal functions to help with IME window management + */ +static void PaintDefaultIMEWnd(HWND hwnd) { - InputContextData *data; - HIMC imc = ImmGetContext(hwnd); - BYTE state[256]; - UINT scancode; - LPVOID list = 0; - UINT msg_count; - UINT uVirtKey; - static const int list_count = 10; + PAINTSTRUCT ps; + RECT rect; + HDC hdc = BeginPaint(hwnd,&ps); + LPCOMPOSITIONSTRING compstr; + LPBYTE compdata = NULL; + HMONITOR monitor; + MONITORINFO mon_info; + INT offX=0, offY=0; - TRACE("%p %x %x %x\n",hwnd, msg, (UINT)wParam, (UINT)lKeyData); + GetClientRect(hwnd,&rect); + FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1)); - if (imc) - data = (InputContextData*)imc; - else - return FALSE; + compdata = ImmLockIMCC(root_context->IMC.hCompStr); + compstr = (LPCOMPOSITIONSTRING)compdata; - if (!data->immKbd->hIME || !data->immKbd->pImeToAsciiEx) - return FALSE; - - GetKeyboardState(state); - scancode = lKeyData >> 0x10 & 0xff; - - list = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, list_count * sizeof(TRANSMSG) + sizeof(DWORD)); - ((DWORD*)list)[0] = list_count; - - if (data->immKbd->imeInfo.fdwProperty & IME_PROP_KBD_CHAR_FIRST) + if (compstr->dwCompStrLen && compstr->dwCompStrOffset) { - WCHAR chr; + SIZE size; + POINT pt; + HFONT oldfont = NULL; + LPWSTR CompString; - 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); + CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset); + if (root_context->textfont) + oldfont = SelectObject(hdc,root_context->textfont); + + + 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 (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 (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; + } + } + + SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE); + + TextOutW(hdc, offX,offY, CompString, compstr->dwCompStrLen); + + if (oldfont) + SelectObject(hdc,oldfont); } - else - uVirtKey = data->lastVK; - 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) - { - int i; - LPTRANSMSG msgs = (LPTRANSMSG)((LPBYTE)list + sizeof(DWORD)); + ImmUnlockIMCC(root_context->IMC.hCompStr); - 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); - - HeapFree(GetProcessHeap(),0,list); - - data->lastVK = VK_PROCESSKEY; - - return (msg_count > 0); + EndPaint(hwnd,&ps); } -/*********************************************************************** -* ImmProcessKey(IMM32.@) -* ( Undocumented, called from user32.dll ) -*/ -BOOL WINAPI ImmProcessKey(HWND hwnd, HKL hKL, UINT vKey, LPARAM lKeyData, DWORD unknown) +static void UpdateDataInDefaultIMEWindow(HWND hwnd, BOOL showable) { - InputContextData *data; - HIMC imc = ImmGetContext(hwnd); - BYTE state[256]; + LPCOMPOSITIONSTRING compstr; - TRACE("%p %p %x %x %x\n",hwnd, hKL, vKey, (UINT)lKeyData, unknown); - - if (imc) - data = (InputContextData*)imc; + if (root_context->IMC.hCompStr) + compstr = ImmLockIMCC(root_context->IMC.hCompStr); else - return FALSE; + compstr = NULL; - if (!data->immKbd->hIME || !data->immKbd->pImeProcessKey) - return FALSE; + if (compstr == NULL || compstr->dwCompStrLen == 0) + ShowWindow(hwndDefault,SW_HIDE); + else if (showable) + ShowWindow(hwndDefault,SW_SHOWNOACTIVATE); - GetKeyboardState(state); - if (data->immKbd->pImeProcessKey(imc, vKey, lKeyData, state)) - { - data->lastVK = vKey; - return TRUE; - } + RedrawWindow(hwnd,NULL,NULL,RDW_ERASENOW|RDW_INVALIDATE); - data->lastVK = VK_PROCESSKEY; - return FALSE; + if (compstr != NULL) + ImmUnlockIMCC(root_context->IMC.hCompStr); +} + +/* + * The window proc for the default IME window + */ +static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, + LPARAM lParam) +{ + LRESULT rc = 0; + + TRACE("Incoming Message 0x%x (0x%08x, 0x%08x)\n", msg, (UINT)wParam, + (UINT)lParam); + + switch(msg) + { + case WM_PAINT: + PaintDefaultIMEWnd(hwnd); + return FALSE; + + case WM_NCCREATE: + return TRUE; + + case WM_CREATE: + SetWindowTextA(hwnd,"Wine Ime Active"); + return TRUE; + + 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) + { + TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_DOCUMENTFEED", + (UINT)wParam, (UINT)lParam); + } + /* 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; } diff --git a/reactos/dll/win32/imm32/imm32.spec b/reactos/dll/win32/imm32/imm32.spec index e0c93859d37..0ecd1f93fa8 100644 --- a/reactos/dll/win32/imm32/imm32.spec +++ b/reactos/dll/win32/imm32/imm32.spec @@ -5,10 +5,10 @@ @ stdcall ImmConfigureIMEW(long long long ptr) @ stdcall ImmCreateContext() @ stdcall ImmCreateIMCC(long) -@ stdcall ImmCreateSoftKeyboard(long long long long) +@ stub ImmCreateSoftKeyboard @ stdcall ImmDestroyContext(long) @ stdcall ImmDestroyIMCC(long) -@ stdcall ImmDestroySoftKeyboard(long) +@ stub ImmDestroySoftKeyboard @ stdcall ImmDisableIME(long) @ stdcall ImmDisableIme(long) ImmDisableIME @ stub ImmEnumInputContext @@ -72,15 +72,15 @@ @ stub ImmLockImeDpi @ stdcall ImmNotifyIME(long long long long) @ stub ImmPenAuxInput -@ stdcall ImmProcessKey(long long long long long) +@ stub ImmProcessKey @ stub ImmPutImeMenuItemsIntoMappedFile @ stdcall ImmReSizeIMCC(long long) @ stub ImmRegisterClient @ stdcall ImmRegisterWordA(long str long str) @ stdcall ImmRegisterWordW(long wstr long wstr) @ stdcall ImmReleaseContext(long long) -@ stdcall ImmRequestMessageA(ptr long long) -@ stdcall ImmRequestMessageW(ptr long long) +@ stub ImmRequestMessageA +@ stub ImmRequestMessageW @ stub ImmSendIMEMessageExA @ stub ImmSendIMEMessageExW @ stub ImmSendMessageToActiveDefImeWndW @@ -96,10 +96,10 @@ #@ stdcall ImmSetHotKey(long long long ptr) user32.CliImmSetHotKey @ stdcall ImmSetOpenStatus(long long) @ stdcall ImmSetStatusWindowPos(long ptr) -@ stdcall ImmShowSoftKeyboard(long long) +@ stub ImmShowSoftKeyboard @ stdcall ImmSimulateHotKey(long long) @ stub ImmSystemHandler -@ stdcall ImmTranslateMessage(long long long long) +@ stub ImmTranslateMessage @ stub ImmUnlockClientImc @ stdcall ImmUnlockIMC(long) @ stdcall ImmUnlockIMCC(long)