Re-import imm32 from Wine
authorGé van Geldorp <ge@gse.nl>
Mon, 12 Dec 2005 20:59:55 +0000 (20:59 +0000)
committerGé van Geldorp <ge@gse.nl>
Mon, 12 Dec 2005 20:59:55 +0000 (20:59 +0000)
svn path=/trunk/; revision=20120

reactos/lib/imm32/imm.c [new file with mode: 0644]
reactos/lib/imm32/imm32.spec [new file with mode: 0644]
reactos/lib/imm32/imm32.xml [new file with mode: 0644]
reactos/w32api/include/imm.h

diff --git a/reactos/lib/imm32/imm.c b/reactos/lib/imm32/imm.c
new file mode 100644 (file)
index 0000000..7f85c7f
--- /dev/null
@@ -0,0 +1,1646 @@
+/*
+ * IMM32 library
+ *
+ * Copyright 1998 Patrik Stridvall
+ * Copyright 2002, 2003 CodeWeavers, Aric Stewart
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "imm.h"
+#include "winnls.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(imm);
+
+#define FROM_IME 0xcafe1337
+
+static void (*pX11DRV_ForceXIMReset)(HWND);
+
+typedef struct tagInputContextData
+{
+        LPBYTE          CompositionString;
+        LPBYTE          CompositionReadingString;
+        LPBYTE          ResultString;
+        LPBYTE          ResultReadingString;
+        DWORD           dwCompStringSize;   /* buffer size */
+        DWORD           dwCompStringLength; /* string length (in bytes) */
+        DWORD           dwCompReadStringSize;
+        DWORD           dwResultStringSize;
+        DWORD           dwResultReadStringSize;
+        HWND            hwnd;
+        BOOL            bOpen;
+        BOOL            bInternalState;
+        BOOL            bRead;
+        LOGFONTW        font;
+        HFONT           textfont;
+        COMPOSITIONFORM CompForm;
+} InputContextData;
+
+static InputContextData *root_context = NULL;
+static HWND hwndDefault = NULL;
+static HANDLE hImeInst;
+static const WCHAR WC_IMECLASSNAME[] = {'I','M','E',0};
+
+/* MSIME messages */
+static UINT WM_MSIME_SERVICE;
+static UINT WM_MSIME_RECONVERTOPTIONS;
+static UINT WM_MSIME_MOUSE;
+static UINT WM_MSIME_RECONVERTREQUEST;
+static UINT WM_MSIME_RECONVERT;
+static UINT WM_MSIME_QUERYPOSITION;
+static UINT WM_MSIME_DOCUMENTFEED;
+
+/*
+ * prototypes
+ */
+static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
+                                          LPARAM lParam);
+static void UpdateDataInDefaultIMEWindow(HWND hwnd);
+static void ImmInternalPostIMEMessage(UINT, WPARAM, LPARAM);
+static void ImmInternalSetOpenStatus(BOOL fOpen);
+
+static VOID IMM_PostResult(InputContextData *data)
+{
+    unsigned int i;
+    TRACE("Posting result as IME_CHAR\n");
+
+    for (i = 0; i < data->dwResultStringSize / sizeof (WCHAR); i++)
+        ImmInternalPostIMEMessage (WM_IME_CHAR, ((WCHAR*)data->ResultString)[i],
+                     1);
+
+    /* clear the buffer */
+    if (data->dwResultStringSize)
+        HeapFree(GetProcessHeap(),0,data->ResultString);
+    data->dwResultStringSize = 0;
+    data->ResultString = NULL;
+}
+
+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;
+    RegisterClassW(&wndClass);
+}
+
+static void IMM_Unregister(void)
+{
+    UnregisterClassW(WC_IMECLASSNAME, NULL);
+}
+
+static void IMM_RegisterMessages(void)
+{
+    WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
+    WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
+    WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
+    WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
+    WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
+    WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
+    WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
+}
+
+
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
+{
+    HMODULE x11drv;
+
+    TRACE("%p, %lx, %p\n",hInstDLL,fdwReason,lpReserved);
+    switch (fdwReason)
+    {
+        case DLL_PROCESS_ATTACH:
+            DisableThreadLibraryCalls(hInstDLL);
+            hImeInst = hInstDLL;
+            IMM_RegisterMessages();
+            x11drv = GetModuleHandleA("winex11.drv");
+            if (x11drv) pX11DRV_ForceXIMReset = (void *)GetProcAddress( x11drv, "ForceXIMReset");
+            break;
+        case DLL_PROCESS_DETACH:
+            if (hwndDefault)
+            {
+                DestroyWindow(hwndDefault);
+                hwndDefault = 0;
+            }
+            IMM_Unregister();
+            break;
+    }
+    return TRUE;
+}
+
+/* for posting messages as the IME */
+static void ImmInternalPostIMEMessage(UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    HWND target = GetFocus();
+    if (!target)
+       PostMessageW(root_context->hwnd,msg,wParam,lParam);
+    else 
+       PostMessageW(target, msg, wParam, lParam);
+}
+
+
+static void ImmInternalSetOpenStatus(BOOL fOpen)
+{
+    TRACE("Setting internal state to %s\n",(fOpen)?"OPEN":"CLOSED");
+
+   root_context->bOpen = fOpen;
+   root_context->bInternalState = fOpen;
+
+   if (fOpen == FALSE)
+   {
+        ShowWindow(hwndDefault,SW_HIDE);
+
+        if (root_context->dwCompStringSize)
+            HeapFree(GetProcessHeap(),0,root_context->CompositionString);
+        if (root_context->dwCompReadStringSize)
+            HeapFree(GetProcessHeap(),0,root_context->CompositionReadingString);
+        if (root_context->dwResultStringSize)
+            HeapFree(GetProcessHeap(),0,root_context->ResultString);
+        if (root_context->dwResultReadStringSize)
+            HeapFree(GetProcessHeap(),0,root_context->ResultReadingString);
+        root_context->dwCompStringSize = 0;
+        root_context->dwCompStringLength = 0;
+        root_context->CompositionString = NULL;
+        root_context->dwCompReadStringSize = 0;
+        root_context->CompositionReadingString = NULL;
+        root_context->dwResultStringSize = 0;
+        root_context->ResultString = NULL;
+        root_context->dwResultReadStringSize = 0;
+        root_context->ResultReadingString = NULL;
+    }
+    else
+        ShowWindow(hwndDefault, SW_SHOWNOACTIVATE);
+
+   SendMessageW(root_context->hwnd, WM_IME_NOTIFY, IMN_SETOPENSTATUS, 0);
+}
+
+
+/***********************************************************************
+ *             ImmAssociateContext (IMM32.@)
+ */
+HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
+{
+    InputContextData *data = (InputContextData*)hIMC;
+
+    WARN("(%p, %p): semi-stub\n",hWnd,hIMC);
+
+    if (!data)
+        return FALSE;
+
+    /*
+     * 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
+     */
+    if (data->hwnd == hWnd)
+        return (HIMC)data;
+
+    if (IsWindow(data->hwnd))
+    {
+        /*
+         * Post a message that your context is switching
+         */
+        SendMessageW(data->hwnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
+    }
+
+    data->hwnd = hWnd;
+
+    if (IsWindow(data->hwnd))
+    {
+        /*
+         * Post a message that your context is switching
+         */
+        SendMessageW(data->hwnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
+    }
+
+    /*
+     * TODO: We need to keep track of the old context associated
+     * with a window and return it for now we will return NULL;
+     */
+    return (HIMC)NULL;
+}
+
+/***********************************************************************
+ *              ImmAssociateContextEx (IMM32.@)
+ */
+BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
+{
+    FIXME("(%p, %p, %ld): stub\n", hWnd, hIMC, dwFlags);
+    return FALSE;
+}
+
+/***********************************************************************
+ *             ImmConfigureIMEA (IMM32.@)
+ */
+BOOL WINAPI ImmConfigureIMEA(
+  HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
+{
+  FIXME("(%p, %p, %ld, %p): stub\n",
+    hKL, hWnd, dwMode, lpData
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmConfigureIMEW (IMM32.@)
+ */
+BOOL WINAPI ImmConfigureIMEW(
+  HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
+{
+  FIXME("(%p, %p, %ld, %p): stub\n",
+    hKL, hWnd, dwMode, lpData
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmCreateContext (IMM32.@)
+ */
+HIMC WINAPI ImmCreateContext(void)
+{
+    InputContextData *new_context;
+
+    new_context = HeapAlloc(GetProcessHeap(),0,sizeof(InputContextData));
+    ZeroMemory(new_context,sizeof(InputContextData));
+
+    return (HIMC)new_context;
+}
+
+/***********************************************************************
+ *             ImmDestroyContext (IMM32.@)
+ */
+BOOL WINAPI ImmDestroyContext(HIMC hIMC)
+{
+    InputContextData *data = (InputContextData*)hIMC;
+
+    TRACE("Destroying %p\n",hIMC);
+
+    if (hIMC)
+    {
+        if (data->dwCompStringSize)
+            HeapFree(GetProcessHeap(),0,data->CompositionString);
+        if (data->dwCompReadStringSize)
+            HeapFree(GetProcessHeap(),0,data->CompositionReadingString);
+        if (data->dwResultStringSize)
+            HeapFree(GetProcessHeap(),0,data->ResultString);
+        if (data->dwResultReadStringSize)
+            HeapFree(GetProcessHeap(),0,data->ResultReadingString);
+
+        if (data->textfont)
+        {
+            DeleteObject(data->textfont);
+            data->textfont = NULL;
+        }
+
+        HeapFree(GetProcessHeap(),0,data);
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *             ImmDisableIME (IMM32.@)
+ */
+BOOL WINAPI ImmDisableIME(DWORD idThread)
+{
+    FIXME("(%ld): stub\n", idThread);
+    return TRUE;
+}
+
+/***********************************************************************
+ *             ImmEnumRegisterWordA (IMM32.@)
+ */
+UINT WINAPI ImmEnumRegisterWordA(
+  HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
+  LPCSTR lpszReading, DWORD dwStyle,
+  LPCSTR lpszRegister, LPVOID lpData)
+{
+  FIXME("(%p, %p, %s, %ld, %s, %p): stub\n",
+    hKL, lpfnEnumProc,
+    debugstr_a(lpszReading), dwStyle,
+    debugstr_a(lpszRegister), lpData
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmEnumRegisterWordW (IMM32.@)
+ */
+UINT WINAPI ImmEnumRegisterWordW(
+  HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
+  LPCWSTR lpszReading, DWORD dwStyle,
+  LPCWSTR lpszRegister, LPVOID lpData)
+{
+  FIXME("(%p, %p, %s, %ld, %s, %p): stub\n",
+    hKL, lpfnEnumProc,
+    debugstr_w(lpszReading), dwStyle,
+    debugstr_w(lpszRegister), lpData
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmEscapeA (IMM32.@)
+ */
+LRESULT WINAPI ImmEscapeA(
+  HKL hKL, HIMC hIMC,
+  UINT uEscape, LPVOID lpData)
+{
+  FIXME("(%p, %p, %d, %p): stub\n",
+    hKL, hIMC, uEscape, lpData
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmEscapeW (IMM32.@)
+ */
+LRESULT WINAPI ImmEscapeW(
+  HKL hKL, HIMC hIMC,
+  UINT uEscape, LPVOID lpData)
+{
+  FIXME("(%p, %p, %d, %p): stub\n",
+    hKL, hIMC, uEscape, lpData
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetCandidateListA (IMM32.@)
+ */
+DWORD WINAPI ImmGetCandidateListA(
+  HIMC hIMC, DWORD deIndex,
+  LPCANDIDATELIST lpCandList, DWORD dwBufLen)
+{
+  FIXME("(%p, %ld, %p, %ld): stub\n",
+    hIMC, deIndex,
+    lpCandList, dwBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetCandidateListCountA (IMM32.@)
+ */
+DWORD WINAPI ImmGetCandidateListCountA(
+  HIMC hIMC, LPDWORD lpdwListCount)
+{
+  FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetCandidateListCountW (IMM32.@)
+ */
+DWORD WINAPI ImmGetCandidateListCountW(
+  HIMC hIMC, LPDWORD lpdwListCount)
+{
+  FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetCandidateListW (IMM32.@)
+ */
+DWORD WINAPI ImmGetCandidateListW(
+  HIMC hIMC, DWORD deIndex,
+  LPCANDIDATELIST lpCandList, DWORD dwBufLen)
+{
+  FIXME("(%p, %ld, %p, %ld): stub\n",
+    hIMC, deIndex,
+    lpCandList, dwBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetCandidateWindow (IMM32.@)
+ */
+BOOL WINAPI ImmGetCandidateWindow(
+  HIMC hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
+{
+  FIXME("(%p, %ld, %p): stub\n", hIMC, dwBufLen, lpCandidate);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmGetCompositionFontA (IMM32.@)
+ */
+BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
+{
+  FIXME("(%p, %p): stub\n", hIMC, lplf);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmGetCompositionFontW (IMM32.@)
+ */
+BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
+{
+  FIXME("(%p, %p): stub\n", hIMC, lplf);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmGetCompositionStringA (IMM32.@)
+ */
+LONG WINAPI ImmGetCompositionStringA(
+  HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
+{
+    CHAR *buf;
+    LONG rc = 0;
+    InputContextData *data = (InputContextData*)hIMC;
+
+    TRACE("(%p, 0x%lx, %p, %ld)\n", hIMC, dwIndex, lpBuf, dwBufLen);
+
+    if (!data)
+       return FALSE;
+
+    if (dwIndex == GCS_RESULTSTR)
+    {
+        TRACE("GSC_RESULTSTR %p %li\n",data->ResultString,
+                                    data->dwResultStringSize);
+
+        buf = HeapAlloc( GetProcessHeap(), 0, data->dwResultStringSize * 3 );
+        rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->ResultString,
+                                 data->dwResultStringSize / sizeof(WCHAR), buf,
+                                 data->dwResultStringSize * 3, NULL, NULL);
+        if (dwBufLen >= rc)
+            memcpy(lpBuf,buf,rc);
+
+        data->bRead = TRUE;
+        HeapFree( GetProcessHeap(), 0, buf );
+    }
+    else if (dwIndex == GCS_COMPSTR)
+    {
+         TRACE("GSC_COMPSTR %p %li\n",data->CompositionString,
+                                     data->dwCompStringLength/ sizeof(WCHAR));
+
+        buf = HeapAlloc( GetProcessHeap(), 0, data->dwCompStringLength * 3 );
+        rc = WideCharToMultiByte(CP_ACP, 0,(LPWSTR)data->CompositionString,
+                                 data->dwCompStringLength/ sizeof(WCHAR), buf,
+                                 data->dwCompStringLength* 3, NULL, NULL);
+        if (dwBufLen >= rc)
+            memcpy(lpBuf,buf,rc);
+        HeapFree( GetProcessHeap(), 0, buf );
+    }
+    else if (dwIndex == GCS_COMPATTR)
+    {
+        TRACE("GSC_COMPATTR %p %li\n",data->CompositionString,
+                                    data->dwCompStringLength/ sizeof(WCHAR));
+
+        rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->CompositionString,
+                                 data->dwCompStringLength/ sizeof(WCHAR), NULL,
+                                 0, NULL, NULL);
+        if (dwBufLen >= rc)
+        {
+            int i=0;
+            for (i = 0;  i < rc; i++)
+                ((LPBYTE)lpBuf)[i] = ATTR_INPUT;
+    }
+    }
+    else if (dwIndex == GCS_COMPCLAUSE)
+    {
+        TRACE("GSC_COMPCLAUSE %p %li\n",data->CompositionString,
+                                    data->dwCompStringLength/ sizeof(WCHAR));
+        rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->CompositionString,
+                                 data->dwCompStringLength/ sizeof(WCHAR), NULL,
+                                 0, NULL, NULL);
+
+        if (dwBufLen >= sizeof(DWORD)*2)
+        {
+            ((LPDWORD)lpBuf)[0] = 0;
+            ((LPDWORD)lpBuf)[1] = rc;
+        }
+        rc = sizeof(DWORD)*2;
+    }
+    else
+    {
+        FIXME("Unhandled index 0x%lx\n",dwIndex);
+    }
+
+    return rc;
+}
+
+/***********************************************************************
+ *             ImmGetCompositionStringW (IMM32.@)
+ */
+LONG WINAPI ImmGetCompositionStringW(
+  HIMC hIMC, DWORD dwIndex,
+  LPVOID lpBuf, DWORD dwBufLen)
+{
+  LONG rc = 0;
+  InputContextData *data = (InputContextData*)hIMC;
+
+  TRACE("(%p, 0x%lx, %p, %ld)\n",
+    hIMC, dwIndex, lpBuf, dwBufLen
+  );
+
+    if (!data)
+       return FALSE;
+
+    if (dwIndex == GCS_RESULTSTR)
+    {
+        data->bRead = TRUE;
+
+        if (dwBufLen >= data->dwResultStringSize)
+            memcpy(lpBuf,data->ResultString,data->dwResultStringSize);
+        
+        rc =  data->dwResultStringSize;
+    }
+    else if (dwIndex == GCS_RESULTREADSTR)
+    {
+        if (dwBufLen >= data->dwResultReadStringSize)
+            memcpy(lpBuf,data->ResultReadingString,
+                    data->dwResultReadStringSize);
+        
+        rc = data->dwResultReadStringSize;
+    }   
+    else if (dwIndex == GCS_COMPSTR)
+    {
+        if (dwBufLen >= data->dwCompStringLength)
+            memcpy(lpBuf,data->CompositionString,data->dwCompStringLength);
+
+        rc = data->dwCompStringLength;
+    }
+    else if (dwIndex == GCS_COMPATTR)
+    {
+        unsigned int len = data->dwCompStringLength;
+        
+        if (dwBufLen >= len)
+        {
+            unsigned int i=0;
+            for (i = 0;  i < len; i++)
+                ((LPBYTE)lpBuf)[i] = ATTR_INPUT;
+        }
+
+        rc = len;
+    }
+    else if (dwIndex == GCS_COMPCLAUSE)
+    {
+        if (dwBufLen >= sizeof(DWORD)*2)
+        {
+            ((LPDWORD)lpBuf)[0] = 0;
+            ((LPDWORD)lpBuf)[1] = data->dwCompStringLength/sizeof(WCHAR);
+        }
+        rc = sizeof(DWORD)*2;
+    }
+    else if (dwIndex == GCS_COMPREADSTR)
+    {
+        if (dwBufLen >= data->dwCompReadStringSize)
+            memcpy(lpBuf,data->CompositionReadingString,
+                    data->dwCompReadStringSize);
+        
+        rc = data->dwCompReadStringSize;
+    }   
+    else
+    {
+        FIXME("Unhandled index 0x%lx\n",dwIndex);
+    }   
+
+    return rc;
+}
+
+/***********************************************************************
+ *             ImmGetCompositionWindow (IMM32.@)
+ */
+BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
+{
+    InputContextData *data = (InputContextData*)hIMC;
+
+    TRACE("(%p, %p)\n", hIMC, lpCompForm);
+
+    if (!data)
+        return FALSE;
+
+    memcpy(lpCompForm,&(data->CompForm),sizeof(COMPOSITIONFORM));
+    return 1;
+}
+
+/***********************************************************************
+ *             ImmGetContext (IMM32.@)
+ *
+ */
+HIMC WINAPI ImmGetContext(HWND hWnd)
+{
+    FIXME("(%p): stub\n", hWnd);
+
+    if (!root_context)
+        return NULL;
+
+    root_context->hwnd = hWnd;
+    return (HIMC)root_context;
+}
+
+/***********************************************************************
+ *             ImmGetConversionListA (IMM32.@)
+ */
+DWORD WINAPI ImmGetConversionListA(
+  HKL hKL, HIMC hIMC,
+  LPCSTR pSrc, LPCANDIDATELIST lpDst,
+  DWORD dwBufLen, UINT uFlag)
+{
+  FIXME("(%p, %p, %s, %p, %ld, %d): stub\n",
+    hKL, hIMC, debugstr_a(pSrc), lpDst, dwBufLen, uFlag
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetConversionListW (IMM32.@)
+ */
+DWORD WINAPI ImmGetConversionListW(
+  HKL hKL, HIMC hIMC,
+  LPCWSTR pSrc, LPCANDIDATELIST lpDst,
+  DWORD dwBufLen, UINT uFlag)
+{
+  FIXME("(%p, %p, %s, %p, %ld, %d): stub\n",
+    hKL, hIMC, debugstr_w(pSrc), lpDst, dwBufLen, uFlag
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetConversionStatus (IMM32.@)
+ */
+BOOL WINAPI ImmGetConversionStatus(
+  HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
+{
+    TRACE("(%p, %p, %p): best guess\n", hIMC, lpfdwConversion, lpfdwSentence);
+    if (lpfdwConversion)
+        *lpfdwConversion = IME_CMODE_NATIVE;
+    if (lpfdwSentence)
+        *lpfdwSentence = IME_SMODE_NONE;
+    return TRUE;
+}
+
+/***********************************************************************
+ *             ImmGetDefaultIMEWnd (IMM32.@)
+ */
+HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
+{
+  FIXME("(%p - %p %p ): semi-stub\n", hWnd,hwndDefault, root_context);
+
+  if (hwndDefault == NULL)
+  {
+        static const WCHAR the_name[] = {'I','M','E','\0'};
+
+        IMM_Register();
+        hwndDefault = CreateWindowExW( WS_EX_CLIENTEDGE, WC_IMECLASSNAME,
+                the_name, WS_POPUPWINDOW|WS_CAPTION, 0, 0, 120, 55, 0, 0,
+                hImeInst, 0);
+
+        TRACE("Default created (%p)\n",hwndDefault);
+  }
+
+  return (HWND)hwndDefault;
+}
+
+/***********************************************************************
+ *             ImmGetDescriptionA (IMM32.@)
+ */
+UINT WINAPI ImmGetDescriptionA(
+  HKL hKL, LPSTR lpszDescription, UINT uBufLen)
+{
+  WCHAR *buf;
+  DWORD len;
+
+  TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
+
+  /* find out how many characters in the unicode buffer */
+  len = ImmGetDescriptionW( hKL, NULL, 0 );
+
+  /* allocate a buffer of that size */
+  buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
+  if( !buf )
+  return 0;
+
+  /* fetch the unicode buffer */
+  len = ImmGetDescriptionW( hKL, buf, len + 1 );
+
+  /* convert it back to ASCII */
+  len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
+                             lpszDescription, uBufLen, NULL, NULL );
+
+  HeapFree( GetProcessHeap(), 0, buf );
+
+  return len;
+}
+
+/***********************************************************************
+ *             ImmGetDescriptionW (IMM32.@)
+ */
+UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
+{
+  static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
+
+  FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
+
+  if (!uBufLen) return lstrlenW( name );
+  lstrcpynW( lpszDescription, name, uBufLen );
+  return lstrlenW( lpszDescription );
+}
+
+/***********************************************************************
+ *             ImmGetGuideLineA (IMM32.@)
+ */
+DWORD WINAPI ImmGetGuideLineA(
+  HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
+{
+  FIXME("(%p, %ld, %s, %ld): stub\n",
+    hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetGuideLineW (IMM32.@)
+ */
+DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
+{
+  FIXME("(%p, %ld, %s, %ld): stub\n",
+    hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetIMEFileNameA (IMM32.@)
+ */
+UINT WINAPI ImmGetIMEFileNameA(
+  HKL hKL, LPSTR lpszFileName, UINT uBufLen)
+{
+  FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetIMEFileNameW (IMM32.@)
+ */
+UINT WINAPI ImmGetIMEFileNameW(
+  HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
+{
+  FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetOpenStatus (IMM32.@)
+ */
+BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
+{
+  InputContextData *data = (InputContextData*)hIMC;
+
+    if (!data)
+        return FALSE;
+  FIXME("(%p): semi-stub\n", hIMC);
+
+  return data->bOpen;
+}
+
+/***********************************************************************
+ *             ImmGetProperty (IMM32.@)
+ */
+DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
+{
+    DWORD rc = 0;
+    TRACE("(%p, %ld)\n", hKL, fdwIndex);
+
+    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;
+}
+
+/***********************************************************************
+ *             ImmGetRegisterWordStyleA (IMM32.@)
+ */
+UINT WINAPI ImmGetRegisterWordStyleA(
+  HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
+{
+  FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetRegisterWordStyleW (IMM32.@)
+ */
+UINT WINAPI ImmGetRegisterWordStyleW(
+  HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
+{
+  FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return 0;
+}
+
+/***********************************************************************
+ *             ImmGetStatusWindowPos (IMM32.@)
+ */
+BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
+{
+  FIXME("(%p, %p): stub\n", hIMC, lpptPos);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmGetVirtualKey (IMM32.@)
+ */
+UINT WINAPI ImmGetVirtualKey(HWND hWnd)
+{
+  OSVERSIONINFOA version;
+  FIXME("(%p): stub\n", hWnd);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  GetVersionExA( &version );
+  switch(version.dwPlatformId)
+  {
+  case VER_PLATFORM_WIN32_WINDOWS:
+      return VK_PROCESSKEY;
+  case VER_PLATFORM_WIN32_NT:
+      return 0;
+  default:
+      FIXME("%ld not supported\n",version.dwPlatformId);
+      return VK_PROCESSKEY;
+  }
+}
+
+/***********************************************************************
+ *             ImmInstallIMEA (IMM32.@)
+ */
+HKL WINAPI ImmInstallIMEA(
+  LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
+{
+  FIXME("(%s, %s): stub\n",
+    debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return NULL;
+}
+
+/***********************************************************************
+ *             ImmInstallIMEW (IMM32.@)
+ */
+HKL WINAPI ImmInstallIMEW(
+  LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
+{
+  FIXME("(%s, %s): stub\n",
+    debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return NULL;
+}
+
+/***********************************************************************
+ *             ImmIsIME (IMM32.@)
+ */
+BOOL WINAPI ImmIsIME(HKL hKL)
+{
+  TRACE("(%p): semi-stub\n", hKL);
+  /*
+   * FIXME: Dead key locales will return TRUE here when they should not
+   * There is probably a more proper way to check this.
+   */
+  return (root_context != NULL);
+}
+
+/***********************************************************************
+ *             ImmIsUIMessageA (IMM32.@)
+ */
+BOOL WINAPI ImmIsUIMessageA(
+  HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    BOOL rc = FALSE;
+
+    TRACE("(%p, %x, %d, %ld)\n", hWndIME, msg, wParam, lParam);
+    if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
+        (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
+        (msg == WM_MSIME_SERVICE) ||
+        (msg == WM_MSIME_RECONVERTOPTIONS) ||
+        (msg == WM_MSIME_MOUSE) ||
+        (msg == WM_MSIME_RECONVERTREQUEST) ||
+        (msg == WM_MSIME_RECONVERT) ||
+        (msg == WM_MSIME_QUERYPOSITION) ||
+        (msg == WM_MSIME_DOCUMENTFEED))
+
+    {
+        if (!hwndDefault)
+            ImmGetDefaultIMEWnd(NULL);
+
+        if (hWndIME == NULL)
+            PostMessageA(hwndDefault, msg, wParam, lParam);
+
+        rc = TRUE;
+    }
+    return rc;
+}
+
+/***********************************************************************
+ *             ImmIsUIMessageW (IMM32.@)
+ */
+BOOL WINAPI ImmIsUIMessageW(
+  HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    BOOL rc = FALSE;
+    TRACE("(%p, %d, %d, %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) ||
+        (msg == WM_MSIME_RECONVERTOPTIONS) ||
+        (msg == WM_MSIME_MOUSE) ||
+        (msg == WM_MSIME_RECONVERTREQUEST) ||
+        (msg == WM_MSIME_RECONVERT) ||
+        (msg == WM_MSIME_QUERYPOSITION) ||
+        (msg == WM_MSIME_DOCUMENTFEED))
+        rc = TRUE;
+    return rc;
+}
+
+/***********************************************************************
+ *             ImmNotifyIME (IMM32.@)
+ */
+BOOL WINAPI ImmNotifyIME(
+  HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
+{
+    BOOL rc = FALSE;
+  FIXME("(%p, %ld, %ld, %ld): stub\n",
+        hIMC, dwAction, dwIndex, dwValue);
+
+    if (!root_context)
+        return rc;
+
+    switch(dwAction)
+    {
+        case NI_CHANGECANDIDATELIST:
+            FIXME("%s\n","NI_CHANGECANDIDATELIST");
+            break;
+        case NI_CLOSECANDIDATE:
+            FIXME("%s\n","NI_CLOSECANDIDATE");
+            break;
+        case NI_COMPOSITIONSTR:
+            switch (dwIndex)
+            {
+                case CPS_CANCEL:
+                    TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL");
+                    if (pX11DRV_ForceXIMReset)
+                        pX11DRV_ForceXIMReset(root_context->hwnd);
+                    if (root_context->dwCompStringSize)
+                    {
+                        HeapFree(GetProcessHeap(),0,
+                                 root_context->CompositionString);
+                        root_context->dwCompStringSize = 0;
+                        root_context->dwCompStringLength = 0;
+                        root_context->CompositionString = NULL;
+                        ImmInternalPostIMEMessage(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->hwnd);
+
+                    if (root_context->dwResultStringSize)
+                    {
+                        HeapFree(GetProcessHeap(),0,root_context->ResultString);
+                        root_context->dwResultStringSize = 0;
+                        root_context->ResultString = NULL;
+                    }
+                    if (root_context->dwCompStringLength)
+                    {
+                        root_context->ResultString = HeapAlloc(
+                        GetProcessHeap(), 0, root_context->dwCompStringLength);
+                        root_context->dwResultStringSize =
+                                        root_context->dwCompStringLength;
+
+                        memcpy(root_context->ResultString,
+                               root_context->CompositionString,
+                               root_context->dwCompStringLength);
+
+                        HeapFree(GetProcessHeap(),0,
+                                 root_context->CompositionString);
+
+                        root_context->dwCompStringSize = 0;
+                        root_context->dwCompStringLength = 0;
+                        root_context->CompositionString = NULL;
+                        root_context->bRead = FALSE;
+
+                        ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
+                                                  GCS_COMPSTR);
+
+                        ImmInternalPostIMEMessage(WM_IME_COMPOSITION,
+                                            root_context->ResultString[0],
+                                            GCS_RESULTSTR|GCS_RESULTCLAUSE);
+                    }
+                    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 (%li)\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;
+}
+
+/***********************************************************************
+ *             ImmRegisterWordA (IMM32.@)
+ */
+BOOL WINAPI ImmRegisterWordA(
+  HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
+{
+  FIXME("(%p, %s, %ld, %s): stub\n",
+    hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister)
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmRegisterWordW (IMM32.@)
+ */
+BOOL WINAPI ImmRegisterWordW(
+  HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
+{
+  FIXME("(%p, %s, %ld, %s): stub\n",
+    hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister)
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmReleaseContext (IMM32.@)
+ */
+BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
+{
+  FIXME("(%p, %p): stub\n", hWnd, hIMC);
+
+    return TRUE;
+}
+
+/***********************************************************************
+ *             ImmSetCandidateWindow (IMM32.@)
+ */
+BOOL WINAPI ImmSetCandidateWindow(
+  HIMC hIMC, LPCANDIDATEFORM lpCandidate)
+{
+  FIXME("(%p, %p): stub\n", hIMC, lpCandidate);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmSetCompositionFontA (IMM32.@)
+ */
+BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
+{
+    InputContextData *data = (InputContextData*)hIMC;
+    TRACE("(%p, %p)\n", hIMC, lplf);
+
+    if (!data)
+        return FALSE;
+
+    memcpy(&data->font,lplf,sizeof(LOGFONTA));
+    MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->font.lfFaceName,
+                        LF_FACESIZE);
+
+    SendMessageW(root_context->hwnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONFONT, 0);
+
+    if (data->textfont)
+    {
+        DeleteObject(data->textfont);
+        data->textfont = NULL;
+    }
+
+    data->textfont = CreateFontIndirectW(&data->font); 
+    return TRUE;
+}
+
+/***********************************************************************
+ *             ImmSetCompositionFontW (IMM32.@)
+ */
+BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
+{
+    InputContextData *data = (InputContextData*)hIMC;
+    TRACE("(%p, %p)\n", hIMC, lplf);
+
+    if (!data)
+        return FALSE;
+
+    memcpy(&data->font,lplf,sizeof(LOGFONTW));
+    SendMessageW(root_context->hwnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONFONT, 0);
+
+    if (data->textfont)
+    {
+        DeleteObject(data->textfont);
+        data->textfont = NULL;
+    }
+    data->textfont = CreateFontIndirectW(&data->font); 
+    return TRUE;
+}
+
+/***********************************************************************
+ *             ImmSetCompositionStringA (IMM32.@)
+ */
+BOOL WINAPI ImmSetCompositionStringA(
+  HIMC hIMC, DWORD dwIndex,
+  LPCVOID lpComp, DWORD dwCompLen,
+  LPCVOID lpRead, DWORD dwReadLen)
+{
+    DWORD comp_len;
+    DWORD read_len;
+    WCHAR *CompBuffer = NULL;
+    WCHAR *ReadBuffer = NULL;
+    BOOL rc;
+
+    TRACE("(%p, %ld, %p, %ld, %p, %ld): stub\n",
+            hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
+
+    comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
+    if (comp_len)
+    {
+        CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len * sizeof(WCHAR));
+        MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len);
+    }
+
+    read_len = MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, NULL, 0);
+    if (read_len)
+    {
+        ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len * sizeof(WCHAR));
+        MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len);
+    }
+
+    rc =  ImmSetCompositionStringW(hIMC, dwIndex, CompBuffer, comp_len,
+                                   ReadBuffer, read_len);
+
+    HeapFree(GetProcessHeap(), 0, CompBuffer);
+    HeapFree(GetProcessHeap(), 0, ReadBuffer);
+
+    return rc;
+}
+
+/***********************************************************************
+ *             ImmSetCompositionStringW (IMM32.@)
+ */
+BOOL WINAPI ImmSetCompositionStringW(
+       HIMC hIMC, DWORD dwIndex,
+       LPCVOID lpComp, DWORD dwCompLen,
+       LPCVOID lpRead, DWORD dwReadLen)
+{
+     DWORD flags = 0;
+     WCHAR wParam  = 0;
+
+     TRACE("(%p, %ld, %p, %ld, %p, %ld): 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)
+    {
+         flags = GCS_COMPSTR;
+
+         if (root_context->dwCompStringLength)
+             HeapFree(GetProcessHeap(),0,root_context->CompositionString);
+
+         root_context->dwCompStringLength = dwCompLen;
+         root_context->dwCompStringSize = dwCompLen;
+
+         if (dwCompLen && lpComp)
+         {
+             root_context->CompositionString = HeapAlloc(GetProcessHeap(), 0,
+                                                     dwCompLen);
+             memcpy(root_context->CompositionString,lpComp,dwCompLen);
+
+             wParam = ((const WCHAR*)lpComp)[0];
+             flags |= GCS_COMPCLAUSE | GCS_COMPATTR;
+         }
+         else
+             root_context->CompositionString = NULL;
+
+    }
+
+     UpdateDataInDefaultIMEWindow(hwndDefault);
+
+     ImmInternalPostIMEMessage(WM_IME_COMPOSITION, wParam, flags);
+
+     return TRUE;
+}
+
+/***********************************************************************
+ *             ImmSetCompositionWindow (IMM32.@)
+ */
+BOOL WINAPI ImmSetCompositionWindow(
+  HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
+{
+    BOOL reshow = FALSE;
+    InputContextData *data = (InputContextData*)hIMC;
+
+    TRACE("(%p, %p)\n", hIMC, lpCompForm);
+    TRACE("\t%lx, (%li,%li), (%li,%li - %li,%li)\n",lpCompForm->dwStyle,
+          lpCompForm->ptCurrentPos.x, lpCompForm->ptCurrentPos.y, lpCompForm->rcArea.top,
+          lpCompForm->rcArea.left, lpCompForm->rcArea.bottom, lpCompForm->rcArea.right);
+
+    if (!data)
+        return FALSE;
+
+    memcpy(&data->CompForm,lpCompForm,sizeof(COMPOSITIONFORM));
+
+    if (IsWindowVisible(hwndDefault))
+    {
+        reshow = TRUE;
+        ShowWindow(hwndDefault,SW_HIDE);
+    }
+
+    FIXME("STUB\n");
+
+    if (reshow)
+        ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
+
+    SendMessageW(root_context->hwnd, WM_IME_NOTIFY,IMN_SETCOMPOSITIONWINDOW, 0);
+    return TRUE;
+}
+
+/***********************************************************************
+ *             ImmSetConversionStatus (IMM32.@)
+ */
+BOOL WINAPI ImmSetConversionStatus(
+  HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
+{
+  FIXME("(%p, %ld, %ld): stub\n",
+    hIMC, fdwConversion, fdwSentence
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmSetOpenStatus (IMM32.@)
+ */
+BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
+{
+    InputContextData *data = (InputContextData*)hIMC;
+    FIXME("Semi-Stub\n");
+
+    if (hIMC == (HIMC)FROM_IME)
+    {
+        if (fOpen)
+            ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION, 0, 0);
+
+        ImmInternalSetOpenStatus(fOpen);
+
+        if (!fOpen)
+            ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0);
+
+        return TRUE;
+    }
+
+    if (!data)
+        return FALSE;
+
+    if (fOpen != data->bInternalState)
+    {
+        if (fOpen == FALSE && pX11DRV_ForceXIMReset)
+            pX11DRV_ForceXIMReset(data->hwnd);
+
+        if (fOpen == FALSE)
+            ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
+        else
+            ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
+
+        ImmInternalSetOpenStatus(fOpen);
+        ImmInternalSetOpenStatus(!fOpen);
+
+        if (data->bOpen == FALSE)
+            ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
+        else
+            ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
+
+        return FALSE;
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *             ImmSetStatusWindowPos (IMM32.@)
+ */
+BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
+{
+  FIXME("(%p, %p): stub\n", hIMC, lpptPos);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmSimulateHotKey (IMM32.@)
+ */
+BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
+{
+  FIXME("(%p, %ld): stub\n", hWnd, dwHotKeyID);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmUnregisterWordA (IMM32.@)
+ */
+BOOL WINAPI ImmUnregisterWordA(
+  HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
+{
+  FIXME("(%p, %s, %ld, %s): stub\n",
+    hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister)
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+/***********************************************************************
+ *             ImmUnregisterWordW (IMM32.@)
+ */
+BOOL WINAPI ImmUnregisterWordW(
+  HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
+{
+  FIXME("(%p, %s, %ld, %s): stub\n",
+    hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister)
+  );
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*****
+ * Internal functions to help with IME window management
+ */
+static void PaintDefaultIMEWnd(HWND hwnd)
+{
+    PAINTSTRUCT ps;
+    RECT rect;
+    HDC hdc = BeginPaint(hwnd,&ps);
+    GetClientRect(hwnd,&rect);
+
+    if (root_context->dwCompStringLength && root_context->CompositionString)
+    {
+        SIZE size;
+        POINT pt;
+        HFONT oldfont = NULL;
+
+        if (root_context->textfont)
+            oldfont = SelectObject(hdc,root_context->textfont);
+
+        TextOutW(hdc, 0,0,(LPWSTR)root_context->CompositionString,
+                 root_context->dwCompStringLength / sizeof(WCHAR));
+
+        GetTextExtentPoint32W(hdc, (LPWSTR)root_context->CompositionString,
+                              root_context->dwCompStringLength / sizeof(WCHAR),
+                              &size);
+        pt.x = size.cx;
+        pt.y = size.cy;
+        LPtoDP(hdc,&pt,1);
+        rect.left = pt.x;
+
+        if (oldfont)
+            SelectObject(hdc,oldfont);
+    }
+    FillRect(hdc,&rect, (HBRUSH) (COLOR_WINDOW+1));
+    EndPaint(hwnd,&ps);
+}
+
+static void UpdateDataInDefaultIMEWindow(HWND hwnd)
+{
+    RedrawWindow(hwnd,NULL,NULL,RDW_ERASENOW|RDW_INVALIDATE);
+}
+
+/*
+ * 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) && (!root_context->bRead))
+                    IMM_PostResult(root_context);
+            else
+                 UpdateDataInDefaultIMEWindow(hwnd);
+            break;
+        case WM_IME_STARTCOMPOSITION:
+            TRACE("IME message %s, 0x%x, 0x%x\n",
+                    "WM_IME_STARTCOMPOSITION", (UINT)wParam, (UINT)lParam);
+            root_context->hwnd = GetFocus();
+            ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
+            break;
+        case WM_IME_ENDCOMPOSITION:
+            TRACE("IME message %s, 0x%x, 0x%x\n",
+                    "WM_IME_ENDCOMPOSITION", (UINT)wParam, (UINT)lParam);
+            ShowWindow(hwndDefault,SW_HIDE);
+            break;
+        case WM_IME_SELECT:
+            TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_SELECT",
+                (UINT)wParam, (UINT)lParam);
+            break;
+        case WM_IME_CONTROL:
+            TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_CONTROL",
+                (UINT)wParam, (UINT)lParam);
+            rc = 1; 
+            break;
+        case WM_IME_NOTIFY:
+            TRACE("!! IME NOTIFY\n");
+            break;
+       default:
+            TRACE("Non-standard message 0x%x\n",msg);
+    }
+    /* check the MSIME messages */
+    if (msg == WM_MSIME_SERVICE)
+    {
+            TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_SERVICE",
+                (UINT)wParam, (UINT)lParam);
+            rc = FALSE;
+    }
+    else if (msg == WM_MSIME_RECONVERTOPTIONS)
+    {
+            TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTOPTIONS",
+                (UINT)wParam, (UINT)lParam);
+    }
+    else if (msg == WM_MSIME_MOUSE)
+    {
+            TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_MOUSE",
+                (UINT)wParam, (UINT)lParam);
+    }
+    else if (msg == WM_MSIME_RECONVERTREQUEST)
+    {
+            TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTREQUEST",
+                (UINT)wParam, (UINT)lParam);
+    }
+    else if (msg == WM_MSIME_RECONVERT)
+    {
+            TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERT",
+                (UINT)wParam, (UINT)lParam);
+    }
+    else if (msg == WM_MSIME_QUERYPOSITION)
+    {
+            TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_QUERYPOSITION",
+                (UINT)wParam, (UINT)lParam);
+    }
+    else if (msg == WM_MSIME_DOCUMENTFEED)
+    {
+            TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_DOCUMENTFEED",
+                (UINT)wParam, (UINT)lParam);
+    }
+    /* DefWndProc if not an IME message */
+    else if (!rc && !((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
+                      (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP)))
+        rc = DefWindowProcW(hwnd,msg,wParam,lParam);
+
+    return rc;
+}
diff --git a/reactos/lib/imm32/imm32.spec b/reactos/lib/imm32/imm32.spec
new file mode 100644 (file)
index 0000000..bf8ceaa
--- /dev/null
@@ -0,0 +1,111 @@
+@ stub ImmActivateLayout
+@ stdcall ImmAssociateContext(long long)
+@ stdcall ImmAssociateContextEx(long long long)
+@ stdcall ImmConfigureIMEA(long long long ptr)
+@ stdcall ImmConfigureIMEW(long long long ptr)
+@ stdcall ImmCreateContext()
+@ stub ImmCreateIMCC
+@ stub ImmCreateSoftKeyboard
+@ stdcall ImmDestroyContext(long)
+@ stub ImmDestroyIMCC
+@ stub ImmDestroySoftKeyboard
+@ stdcall ImmDisableIME(long)
+@ stub ImmDisableIme
+@ stub ImmEnumInputContext
+@ stdcall ImmEnumRegisterWordA(long ptr str long str ptr)
+@ stdcall ImmEnumRegisterWordW(long ptr wstr long wstr ptr)
+@ stdcall ImmEscapeA(long long long ptr)
+@ stdcall ImmEscapeW(long long long ptr)
+@ stub ImmFreeLayout
+@ stub ImmGenerateMessage
+@ stdcall ImmGetCandidateListA(long long ptr long)
+@ stdcall ImmGetCandidateListCountA(long ptr)
+@ stdcall ImmGetCandidateListCountW(long ptr)
+@ stdcall ImmGetCandidateListW(long long ptr long)
+@ stdcall ImmGetCandidateWindow(long long ptr)
+@ stdcall ImmGetCompositionFontA(long ptr)
+@ stdcall ImmGetCompositionFontW(long ptr)
+@ stdcall ImmGetCompositionString (long long ptr long) ImmGetCompositionStringA
+@ stdcall ImmGetCompositionStringA (long long ptr long)
+@ stdcall ImmGetCompositionStringW (long long ptr long)
+@ stdcall ImmGetCompositionWindow(long ptr)
+@ stdcall ImmGetContext(long)
+@ stdcall ImmGetConversionListA(long long str ptr long long)
+@ stdcall ImmGetConversionListW(long long wstr ptr long long)
+@ stdcall ImmGetConversionStatus(long ptr ptr)
+@ stdcall ImmGetDefaultIMEWnd(long)
+@ stdcall ImmGetDescriptionA(long ptr long)
+@ stdcall ImmGetDescriptionW(long ptr long)
+@ stdcall ImmGetGuideLineA(long long ptr long)
+@ stdcall ImmGetGuideLineW(long long ptr long)
+@ stub ImmGetHotKey
+@ stub ImmGetIMCCLockCount
+@ stub ImmGetIMCCSize
+@ stub ImmGetIMCLockCount
+@ stdcall ImmGetIMEFileNameA(long ptr long)
+@ stdcall ImmGetIMEFileNameW(long ptr long) 
+@ stub ImmGetImeInfoEx
+@ stub ImmGetImeMenuItemsA
+@ stub ImmGetImeMenuItemsW
+@ stdcall ImmGetOpenStatus(long)
+@ stdcall ImmGetProperty(long long)
+@ stdcall ImmGetRegisterWordStyleA(long long ptr)
+@ stdcall ImmGetRegisterWordStyleW(long long ptr)
+@ stdcall ImmGetStatusWindowPos(long ptr)
+@ stdcall ImmGetVirtualKey(long)
+@ stub ImmIMPGetIMEA
+@ stub ImmIMPGetIMEW
+@ stub ImmIMPQueryIMEA
+@ stub ImmIMPQueryIMEW
+@ stub ImmIMPSetIMEA
+@ stub ImmIMPSetIMEW
+@ stdcall ImmInstallIMEA(str str)
+@ stdcall ImmInstallIMEW(wstr wstr)
+@ stdcall ImmIsIME(long)
+@ stdcall ImmIsUIMessageA(long long long long)
+@ stdcall ImmIsUIMessageW(long long long long)
+@ stub ImmLoadIME
+@ stub ImmLoadLayout
+@ stub ImmLockClientImc
+@ stub ImmLockIMC
+@ stub ImmLockIMCC
+@ stub ImmLockImeDpi
+@ stdcall ImmNotifyIME(long long long long)
+@ stub ImmPenAuxInput
+@ stub ImmProcessKey
+@ stub ImmPutImeMenuItemsIntoMappedFile
+@ stub ImmReSizeIMCC
+@ stub ImmRegisterClient
+@ stdcall ImmRegisterWordA(long str long str)
+@ stdcall ImmRegisterWordW(long wstr long wstr)
+@ stdcall ImmReleaseContext(long long)
+@ stub ImmRequestMessageA
+@ stub ImmRequestMessageW
+@ stub ImmSendIMEMessageExA
+@ stub ImmSendIMEMessageExW
+@ stub ImmSendMessageToActiveDefImeWndW
+@ stub ImmSetActiveContext
+@ stub ImmSetActiveContextConsoleIME
+@ stdcall ImmSetCandidateWindow(long ptr)
+@ stdcall ImmSetCompositionFontA(long ptr)
+@ stdcall ImmSetCompositionFontW(long ptr)
+@ stdcall ImmSetCompositionStringA(long long ptr long ptr long)
+@ stdcall ImmSetCompositionStringW(long long ptr long ptr long)
+@ stdcall ImmSetCompositionWindow(long ptr)
+@ stdcall ImmSetConversionStatus(long long long)
+@ stdcall ImmSetHotKey(long long long ptr) user32.CliImmSetHotKey
+@ stdcall ImmSetOpenStatus(long long)
+@ stdcall ImmSetStatusWindowPos(long ptr)
+@ stub ImmShowSoftKeyboard
+@ stdcall ImmSimulateHotKey(long long)
+@ stub ImmSystemHandler
+@ stub ImmTranslateMessage
+@ stub ImmUnlockClientImc
+@ stub ImmUnlockIMC
+@ stub ImmUnlockIMCC
+@ stub ImmUnlockImeDpi
+@ stdcall ImmUnregisterWordA(long str long str)
+@ stdcall ImmUnregisterWordW(long wstr long wstr)
+@ stub ImmWINNLSEnableIME
+@ stub ImmWINNLSGetEnableStatus
+@ stub ImmWINNLSGetIMEHotkey
diff --git a/reactos/lib/imm32/imm32.xml b/reactos/lib/imm32/imm32.xml
new file mode 100644 (file)
index 0000000..b945840
--- /dev/null
@@ -0,0 +1,13 @@
+<module name="imm32" type="win32dll" baseaddress="${BASEADDRESS_IMM32}" installbase="system32" installname="imm32.dll">
+       <importlibrary definition="imm32.spec.def" />
+       <include base="imm32">.</include>
+       <define name="_DISABLE_TIDENTS" />
+       <define name="__USE_W32API" />
+       <library>wine</library>
+       <library>ntdll</library>
+       <library>kernel32</library>
+       <library>user32</library>
+       <library>gdi32</library>
+       <file>imm.c</file>
+       <file>imm32.spec</file>
+</module>
index 6ae9cab..5736cc2 100644 (file)
@@ -241,8 +241,8 @@ extern "C" {
 #define VK_PROCESSKEY 0x0E5
 #endif
 #define STYLE_DESCRIPTION_SIZE 32
-typedef DWORD HIMC;
-typedef DWORD HIMCC;
+typedef HANDLE HIMC;
+typedef HANDLE HIMCC;
 typedef HKL *LPHKL;
 typedef struct tagCOMPOSITIONFORM {
        DWORD dwStyle;