[ros-diffs] [dchapyshev] 33367: - Revert r33314

dchapyshev at svn.reactos.org dchapyshev at svn.reactos.org
Thu May 8 18:03:10 CEST 2008


Author: dchapyshev
Date: Thu May  8 11:03:10 2008
New Revision: 33367

URL: http://svn.reactos.org/svn/reactos?rev=33367&view=rev
Log:
- Revert r33314

Modified:
    trunk/reactos/dll/win32/imm32/imm.c
    trunk/reactos/dll/win32/imm32/imm32.spec

Modified: trunk/reactos/dll/win32/imm32/imm.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/imm32/imm.c?rev=33367&r1=33366&r2=33367&view=diff
==============================================================================
--- trunk/reactos/dll/win32/imm32/imm.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/imm32/imm.c [iso-8859-1] Thu May  8 11:03:10 2008
@@ -20,7 +20,6 @@
  */
 
 #include <stdarg.h>
-#include <stdio.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -35,6 +34,10 @@
 #include "wine/list.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(imm);
+
+#define FROM_IME 0xcafe1337
+
+static void (*pX11DRV_ForceXIMReset)(HWND);
 
 typedef struct tagIMCCInternal
 {
@@ -73,12 +76,15 @@
 
 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 @@
     LPARAM lParam;
 } TRANSMSG, *LPTRANSMSG;
 
-typedef struct _tagIMMThreadData {
-    HIMC defaultContext;
-    HWND hwndDefault;
-} IMMThreadData;
-
-static DWORD tlsIndex = 0;
+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 struct list ImmHklList = LIST_INIT(ImmHklList);
 
 /* MSIME messages */
@@ -105,167 +111,15 @@
 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 @@
 
     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_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 @@
     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 @@
     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 @@
 
     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 @@
         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 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 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 @@
 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 @@
     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 @@
     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,20 +783,15 @@
         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;
 }
 
 /***********************************************************************
@@ -672,31 +811,13 @@
   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 @@
   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 @@
   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 @@
   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 @@
 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 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)
-{
-    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;
+  HIMC hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
+{
+  FIXME("(%p, %d, %p): stub\n", hIMC, dwBufLen, lpCandidate);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 /***********************************************************************
@@ -959,13 +939,13 @@
     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 @@
 
     TRACE("(%p, %p):\n", hIMC, lplf);
 
-    if (!data || !lplf)
+    if (!data)
         return FALSE;
 
     *lplf = data->IMC.lfFont.W;
@@ -1013,7 +993,7 @@
     {
         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 @@
         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 @@
     {
         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 @@
              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 @@
              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 @@
              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 @@
     }
     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 @@
         compstr->dwResultStrOffset > 0)
     {
         LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
+        data->bRead = TRUE;
         rc =  compstr->dwResultStrLen * sizeof(WCHAR);
 
         if (dwBufLen >= rc)
@@ -1170,7 +1152,7 @@
     }
     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 @@
     else
     {
         FIXME("Unhandled index 0x%x\n",dwIndex);
-    }
+    }   
 
     ImmUnlockIMCC(data->IMC.hCompStr);
 
@@ -1213,14 +1195,12 @@
     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 @@
   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 @@
   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 @@
 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 @@
  */
 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 @@
 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)
-        {
-            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;
-        }
+
+    switch (fdwIndex)
+    {
+        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 @@
 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 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 @@
  */
 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 @@
 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 @@
  */
 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 @@
         (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 @@
   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 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;
-
-    return data->immKbd->pNotifyIME(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");
+    }
+
+    return rc;
 }
 
 /***********************************************************************
@@ -1742,28 +1770,11 @@
 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 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;
 }
 
 /***********************************************************************
@@ -1811,62 +1805,14 @@
 }
 
 /***********************************************************************
-*              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 @@
     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 @@
     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,17 +1878,9 @@
     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 @@
 	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;
-
-    TRACE("(%p, %d, %p, %d, %p, %d):\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 = WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, NULL, 0, NULL,
-                                   NULL);
-    if (comp_len)
-    {
-        CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len);
-        WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len,
-                            NULL, NULL);
-    }
-
-    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);
-    }
-
-    rc =  ImmSetCompositionStringA(hIMC, dwIndex, CompBuffer, comp_len,
-                                   ReadBuffer, read_len);
-
-    HeapFree(GetProcessHeap(), 0, CompBuffer);
-    HeapFree(GetProcessHeap(), 0, ReadBuffer);
-
-    return rc;
+     DWORD flags = 0;
+     WCHAR wParam  = 0;
+
+     TRACE("(%p, %d, %p, %d, %p, %d): stub\n",
+             hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
+
+
+     if (hIMC != (HIMC)FROM_IME)
+         FIXME("PROBLEM: This only sets the wine level string\n");
+
+     /*
+      * 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)
+    {
+        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;
+        }
+    }
+
+     UpdateDataInDefaultIMEWindow(hwndDefault,FALSE);
+
+     ImmInternalPostIMEMessage(root_context, WM_IME_COMPOSITION, wParam, flags);
+
+     return TRUE;
 }
 
 /***********************************************************************
@@ -2026,16 +1992,16 @@
 
     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,113 +2013,68 @@
 BOOL WINAPI ImmSetConversionStatus(
   HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
 {
-    DWORD oldConversion, oldSentence;
+  static int shown = 0;
+
+  if (!shown) {
+      FIXME("(%p, %d, %d): stub\n",
+          hIMC, fdwConversion, fdwSentence
+      );
+      shown = 1;
+  }
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *		ImmSetOpenStatus (IMM32.@)
+ */
+BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
+{
     InputContextData *data = (InputContextData*)hIMC;
 
-    TRACE("%p %d %d\n", hIMC, fdwConversion, fdwSentence);
+    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 ( 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);
-    }
-
+    if (fOpen != data->bInternalState)
+    {
+        if (fOpen == FALSE && pX11DRV_ForceXIMReset)
+            pX11DRV_ForceXIMReset(data->IMC.hWnd);
+
+        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;
 }
 
 /***********************************************************************
- *		ImmSetOpenStatus (IMM32.@)
- */
-BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
-{
-    InputContextData *data = (InputContextData*)hIMC;
-
-    TRACE("%p %d\n", hIMC, fOpen);
-
-    if (!data)
-        return FALSE;
-
-    if (data->imeWnd == NULL)
-    {
-        /* 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 != !data->IMC.fOpen)
-    {
-        data->IMC.fOpen = fOpen;
-        ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS);
-        ImmInternalSendIMENotify(data, IMN_SETOPENSTATUS, 0);
-    }
-
-    return TRUE;
-}
-
-/***********************************************************************
  *		ImmSetStatusWindowPos (IMM32.@)
  */
 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 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 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 @@
    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 @@
    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 @@
     return TRUE;
 }
 
-/***********************************************************************
-*       ImmTranslateMessage(IMM32.@)
-*       ( Undocumented, call internally and from user32.dll )
-*/
-BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyData)
-{
-    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;
-
-    TRACE("%p %x %x %x\n",hwnd, msg, (UINT)wParam, (UINT)lKeyData);
-
-    if (imc)
-        data = (InputContextData*)imc;
+/*****
+ * Internal functions to help with IME window management
+ */
+static void PaintDefaultIMEWnd(HWND hwnd)
+{
+    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);
+
+
+        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);
+    }
+
+    ImmUnlockIMCC(root_context->IMC.hCompStr);
+
+    EndPaint(hwnd,&ps);
+}
+
+static void UpdateDataInDefaultIMEWindow(HWND hwnd, BOOL showable)
+{
+    LPCOMPOSITIONSTRING compstr;
+
+    if (root_context->IMC.hCompStr)
+        compstr = ImmLockIMCC(root_context->IMC.hCompStr);
     else
-        return FALSE;
-
-    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)
-    {
-        WCHAR chr;
-
-        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;
-
-    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));
-
-        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);
-}
-
-/***********************************************************************
-*		ImmProcessKey(IMM32.@)
-*       ( Undocumented, called from user32.dll )
-*/
-BOOL WINAPI ImmProcessKey(HWND hwnd, HKL hKL, UINT vKey, LPARAM lKeyData, DWORD unknown)
-{
-    InputContextData *data;
-    HIMC imc = ImmGetContext(hwnd);
-    BYTE state[256];
-
-    TRACE("%p %p %x %x %x\n",hwnd, hKL, vKey, (UINT)lKeyData, unknown);
-
-    if (imc)
-        data = (InputContextData*)imc;
-    else
-        return FALSE;
-
-    if (!data->immKbd->hIME || !data->immKbd->pImeProcessKey)
-        return FALSE;
-
-    GetKeyboardState(state);
-    if (data->immKbd->pImeProcessKey(imc, vKey, lKeyData, state))
-    {
-        data->lastVK = vKey;
-        return TRUE;
-    }
-
-    data->lastVK = VK_PROCESSKEY;
-    return FALSE;
-}
+        compstr = NULL;
+
+    if (compstr == NULL || compstr->dwCompStrLen == 0)
+        ShowWindow(hwndDefault,SW_HIDE);
+    else if (showable)
+        ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
+
+    RedrawWindow(hwnd,NULL,NULL,RDW_ERASENOW|RDW_INVALIDATE);
+
+    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;
+}

Modified: trunk/reactos/dll/win32/imm32/imm32.spec
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/imm32/imm32.spec?rev=33367&r1=33366&r2=33367&view=diff
==============================================================================
--- trunk/reactos/dll/win32/imm32/imm32.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/imm32/imm32.spec [iso-8859-1] Thu May  8 11:03:10 2008
@@ -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)



More information about the Ros-diffs mailing list