/*
 * 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);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    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)
{
    TRACE("%p\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);
  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;

    TRACE("(%p, %ld, %ld, %ld)\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: this is a partial stub */

    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;

    TRACE("%p %d\n", hIMC, fOpen);

    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;
}
