/*
 * The IME for interfacing with XIM
 *
 * Copyright 2008 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

/*
 * Notes:
 *  The normal flow for IMM/IME Processing is as follows.
 * 1) The Keyboard Driver generates key messages which are first passed to
 *    the IMM and then to IME via ImeProcessKey. If the IME returns 0  then
 *    it does not want the key and the keyboard driver then generates the
 *    WM_KEYUP/WM_KEYDOWN messages.  However if the IME is going to process the
 *    key it returns non-zero.
 * 2) If the IME is going to process the key then the IMM calls ImeToAsciiEx to
 *    process the key.  the IME modifies the HIMC structure to reflect the
 *    current state and generates any messages it needs the IMM to process.
 * 3) IMM checks the messages and send them to the application in question. From
 *    here the IMM level deals with if the application is IME aware or not.
 *
 *  This flow does not work well for the X11 driver and XIM.
 *   (It works fine for Mac)
 *  As such we will have to reroute step 1.  Instead the x11drv driver will
 *  generate an XIM events and call directly into this IME implimenetaion.
 *  As such we will have to use the alternative ImmGenerateMessage path to be
 *  generate the messages that we want the IMM layer to send to the application.
 */

#include "config.h"

#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 "ddk/imm.h"
#include "winnls.h"
#include "x11drv.h"

WINE_DEFAULT_DEBUG_CHANNEL(imm);

#define FROM_X11 ((HIMC)0xcafe1337)

typedef struct _IMEPRIVATE {
    BOOL bInComposition;
    BOOL bInternalState;
    HFONT textfont;
    HWND hwndDefault;
} IMEPRIVATE, *LPIMEPRIVATE;

typedef struct _tagTRANSMSG {
    UINT message;
    WPARAM wParam;
    LPARAM lParam;
} TRANSMSG, *LPTRANSMSG;

static const WCHAR UI_CLASS_NAME[] = {'W','i','n','e','X','1','1','I','M','E',0};

static HIMC *hSelectedFrom = NULL;
static INT  hSelectedCount = 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;

static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
                                          LPARAM lParam);
static void UpdateDataInDefaultIMEWindow(HIMC hHIMC, HWND hwnd, BOOL showable);

static HIMC RealIMC(HIMC hIMC)
{
    if (hIMC == FROM_X11)
    {
        INT i;
        HWND wnd = GetFocus();
        HIMC winHimc = ImmGetContext(wnd);
        for (i = 0; i < hSelectedCount; i++)
            if (winHimc == hSelectedFrom[i])
                return winHimc;
        return NULL;
    }
    else
        return hIMC;
}

static LPINPUTCONTEXT LockRealIMC(HIMC hIMC)
{
    HIMC real_imc = RealIMC(hIMC);
    if (real_imc)
        return (LPINPUTCONTEXT)ImmLockIMC(real_imc);
    else
        return NULL;
}

static BOOL UnlockRealIMC(HIMC hIMC)
{
    HIMC real_imc = RealIMC(hIMC);
    if (real_imc)
        return ImmUnlockIMC(real_imc);
    else
        return FALSE;
}

static void IME_RegisterClasses(void)
{
    static int done;
    WNDCLASSW wndClass;

    if (done) return;
    done = 1;

    ZeroMemory(&wndClass, sizeof(WNDCLASSW));
    wndClass.style = CS_GLOBALCLASS | CS_IME | CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc = IME_WindowProc;
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 2 * sizeof(LONG);
    wndClass.hInstance = x11drv_module;
    wndClass.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
    wndClass.hIcon = LoadIconW(NULL, (LPWSTR)IDI_APPLICATION);
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
    wndClass.lpszMenuName   = 0;
    wndClass.lpszClassName = UI_CLASS_NAME;

    RegisterClassW(&wndClass);

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

void IME_UnregisterClasses(void)
{
    UnregisterClassW(UI_CLASS_NAME, x11drv_module);
}

static HIMCC ImeCreateBlankCompStr(void)
{
    HIMCC rc;
    LPCOMPOSITIONSTRING ptr;
    rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
    ptr = (LPCOMPOSITIONSTRING)ImmLockIMCC(rc);
    memset(ptr,0,sizeof(COMPOSITIONSTRING));
    ptr->dwSize = sizeof(COMPOSITIONSTRING);
    ImmUnlockIMCC(rc);
    return rc;
}

static int updateField(DWORD origLen, DWORD origOffset, DWORD currentOffset,
                       LPBYTE target, LPBYTE source, DWORD* lenParam,
                       DWORD* offsetParam, BOOL wchars )
{
     if (origLen > 0 && origOffset > 0)
     {
        int truelen = origLen;
        if (wchars)
            truelen *= sizeof(WCHAR);

        memcpy(&target[currentOffset], &source[origOffset], truelen);

        *lenParam = origLen;
        *offsetParam = currentOffset;
        currentOffset += truelen;
     }
     return currentOffset;
}

static HIMCC updateCompStr(HIMCC old, LPWSTR compstr, DWORD len)
{
    /* we need to make sure the CompStr, CompClaus and CompAttr fields are all
     * set and correct */
    int needed_size;
    HIMCC   rc;
    LPBYTE newdata = NULL;
    LPBYTE olddata = NULL;
    LPCOMPOSITIONSTRING new_one;
    LPCOMPOSITIONSTRING lpcs = NULL;
    INT current_offset = 0;

    TRACE("%s, %i\n",debugstr_wn(compstr,len),len);

    if (old == NULL && compstr == NULL && len == 0)
        return NULL;

    if (old != NULL)
    {
        olddata = ImmLockIMCC(old);
        lpcs = (LPCOMPOSITIONSTRING)olddata;
    }

    needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
                  len + sizeof(DWORD) * 2;

    if (lpcs != NULL)
    {
        needed_size += lpcs->dwCompReadAttrLen;
        needed_size += lpcs->dwCompReadClauseLen;
        needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
        needed_size += lpcs->dwResultReadClauseLen;
        needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
        needed_size += lpcs->dwResultClauseLen;
        needed_size += lpcs->dwResultStrLen * sizeof(DWORD);
        needed_size += lpcs->dwPrivateSize;
    }
    rc = ImmCreateIMCC(needed_size);
    newdata = ImmLockIMCC(rc);
    new_one = (LPCOMPOSITIONSTRING)newdata;

    new_one->dwSize = needed_size;
    current_offset = sizeof(COMPOSITIONSTRING);
    if (lpcs != NULL)
    {
        current_offset = updateField(lpcs->dwCompReadAttrLen,
                                     lpcs->dwCompReadAttrOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwCompReadAttrLen,
                                     &new_one->dwCompReadAttrOffset, FALSE);

        current_offset = updateField(lpcs->dwCompReadClauseLen,
                                     lpcs->dwCompReadClauseOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwCompReadClauseLen,
                                     &new_one->dwCompReadClauseOffset, FALSE);

        current_offset = updateField(lpcs->dwCompReadStrLen,
                                     lpcs->dwCompReadStrOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwCompReadStrLen,
                                     &new_one->dwCompReadStrOffset, TRUE);

        /* new CompAttr, CompClause, CompStr, dwCursorPos */
        new_one->dwDeltaStart = 0;

        current_offset = updateField(lpcs->dwResultReadClauseLen,
                                     lpcs->dwResultReadClauseOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwResultReadClauseLen,
                                     &new_one->dwResultReadClauseOffset, FALSE);

        current_offset = updateField(lpcs->dwResultReadStrLen,
                                     lpcs->dwResultReadStrOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwResultReadStrLen,
                                     &new_one->dwResultReadStrOffset, TRUE);

        current_offset = updateField(lpcs->dwResultClauseLen,
                                     lpcs->dwResultClauseOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwResultClauseLen,
                                     &new_one->dwResultClauseOffset, FALSE);

        current_offset = updateField(lpcs->dwResultStrLen,
                                     lpcs->dwResultStrOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwResultStrLen,
                                     &new_one->dwResultStrOffset, TRUE);

        current_offset = updateField(lpcs->dwPrivateSize,
                                     lpcs->dwPrivateOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwPrivateSize,
                                     &new_one->dwPrivateOffset, FALSE);
    }

    /* set new data */
    /* CompAttr */
    new_one->dwCompAttrLen = len;
    if (len > 0)
    {
        new_one->dwCompAttrOffset = current_offset;
        memset(&newdata[current_offset],ATTR_INPUT,len);
        current_offset += len;
    }

    /* CompClause */
    if (len > 0)
    {
        new_one->dwCompClauseLen = sizeof(DWORD) * 2;
        new_one->dwCompClauseOffset = current_offset;
        *(DWORD*)(&newdata[current_offset]) = 0;
        current_offset += sizeof(DWORD);
        *(DWORD*)(&newdata[current_offset]) = len;
        current_offset += sizeof(DWORD);
    }

    /* CompStr */
    new_one->dwCompStrLen = len;
    if (len > 0)
    {
        new_one->dwCompStrOffset = current_offset;
        memcpy(&newdata[current_offset],compstr,len*sizeof(WCHAR));
    }

    /* CursorPos */
    new_one->dwCursorPos = len;

    ImmUnlockIMCC(rc);
    if (lpcs)
        ImmUnlockIMCC(old);

    return rc;
}

static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len)
{
    /* we need to make sure the ResultStr and ResultClause fields are all
     * set and correct */
    int needed_size;
    HIMCC   rc;
    LPBYTE newdata = NULL;
    LPBYTE olddata = NULL;
    LPCOMPOSITIONSTRING new_one;
    LPCOMPOSITIONSTRING lpcs = NULL;
    INT current_offset = 0;

    TRACE("%s, %i\n",debugstr_wn(resultstr,len),len);

    if (old == NULL && resultstr == NULL && len == 0)
        return NULL;

    if (old != NULL)
    {
        olddata = ImmLockIMCC(old);
        lpcs = (LPCOMPOSITIONSTRING)olddata;
    }

    needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
                  sizeof(DWORD) * 2;

    if (lpcs != NULL)
    {
        needed_size += lpcs->dwCompReadAttrLen;
        needed_size += lpcs->dwCompReadClauseLen;
        needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
        needed_size += lpcs->dwCompAttrLen;
        needed_size += lpcs->dwCompClauseLen;
        needed_size += lpcs->dwCompStrLen * sizeof(DWORD);
        needed_size += lpcs->dwResultReadClauseLen;
        needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
        needed_size += lpcs->dwPrivateSize;
    }
    rc = ImmCreateIMCC(needed_size);
    newdata = ImmLockIMCC(rc);
    new_one = (LPCOMPOSITIONSTRING)newdata;

    new_one->dwSize = needed_size;
    current_offset = sizeof(COMPOSITIONSTRING);
    if (lpcs != NULL)
    {
        current_offset = updateField(lpcs->dwCompReadAttrLen,
                                     lpcs->dwCompReadAttrOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwCompReadAttrLen,
                                     &new_one->dwCompReadAttrOffset, FALSE);

        current_offset = updateField(lpcs->dwCompReadClauseLen,
                                     lpcs->dwCompReadClauseOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwCompReadClauseLen,
                                     &new_one->dwCompReadClauseOffset, FALSE);

        current_offset = updateField(lpcs->dwCompReadStrLen,
                                     lpcs->dwCompReadStrOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwCompReadStrLen,
                                     &new_one->dwCompReadStrOffset, TRUE);

        current_offset = updateField(lpcs->dwCompAttrLen,
                                     lpcs->dwCompAttrOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwCompAttrLen,
                                     &new_one->dwCompAttrOffset, FALSE);

        current_offset = updateField(lpcs->dwCompClauseLen,
                                     lpcs->dwCompClauseOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwCompClauseLen,
                                     &new_one->dwCompClauseOffset, FALSE);

        current_offset = updateField(lpcs->dwCompStrLen,
                                     lpcs->dwCompStrOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwCompStrLen,
                                     &new_one->dwCompStrOffset, TRUE);

        new_one->dwCursorPos = lpcs->dwCursorPos;
        new_one->dwDeltaStart = 0;

        current_offset = updateField(lpcs->dwResultReadClauseLen,
                                     lpcs->dwResultReadClauseOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwResultReadClauseLen,
                                     &new_one->dwResultReadClauseOffset, FALSE);

        current_offset = updateField(lpcs->dwResultReadStrLen,
                                     lpcs->dwResultReadStrOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwResultReadStrLen,
                                     &new_one->dwResultReadStrOffset, TRUE);

        /* new ResultClause , ResultStr */

        current_offset = updateField(lpcs->dwPrivateSize,
                                     lpcs->dwPrivateOffset,
                                     current_offset, newdata, olddata,
                                     &new_one->dwPrivateSize,
                                     &new_one->dwPrivateOffset, FALSE);
    }

    /* set new data */
    /* ResultClause */
    if (len > 0)
    {
        new_one->dwResultClauseLen = sizeof(DWORD) * 2;
        new_one->dwResultClauseOffset = current_offset;
        *(DWORD*)(&newdata[current_offset]) = 0;
        current_offset += sizeof(DWORD);
        *(DWORD*)(&newdata[current_offset]) = len;
        current_offset += sizeof(DWORD);
    }

    /* ResultStr */
    new_one->dwResultStrLen = len;
    if (len > 0)
    {
        new_one->dwResultStrOffset = current_offset;
        memcpy(&newdata[current_offset],resultstr,len*sizeof(WCHAR));
    }
    ImmUnlockIMCC(rc);
    if (lpcs)
        ImmUnlockIMCC(old);

    return rc;
}

static void GenerateIMEMessage(HIMC hIMC, UINT msg, WPARAM wParam,
                               LPARAM lParam)
{
    LPINPUTCONTEXT lpIMC;
    LPTRANSMSG lpTransMsg;

    lpIMC = LockRealIMC(hIMC);
    if (lpIMC == NULL)
        return;

    lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) *
                                    sizeof(TRANSMSG));
    if (!lpIMC->hMsgBuf)
        return;

    lpTransMsg = (LPTRANSMSG)ImmLockIMCC(lpIMC->hMsgBuf);
    if (!lpTransMsg)
        return;

    lpTransMsg += lpIMC->dwNumMsgBuf;
    lpTransMsg->message = msg;
    lpTransMsg->wParam = wParam;
    lpTransMsg->lParam = lParam;

    ImmUnlockIMCC(lpIMC->hMsgBuf);
    lpIMC->dwNumMsgBuf++;

    ImmGenerateMessage(RealIMC(hIMC));
    UnlockRealIMC(hIMC);
}

static void GenerateIMECHARMessages(HIMC hIMC, LPWSTR String, DWORD length)
{
    LPINPUTCONTEXT lpIMC;
    LPTRANSMSG lpTransMsg;
    INT i;

    if (length <= 0)
        return;

    lpIMC = LockRealIMC(hIMC);
    if (lpIMC == NULL)
        return;

    lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf,
                                  (lpIMC->dwNumMsgBuf + length) *
                                    sizeof(TRANSMSG));
    if (!lpIMC->hMsgBuf)
        return;

    lpTransMsg = (LPTRANSMSG)ImmLockIMCC(lpIMC->hMsgBuf);
    if (!lpTransMsg)
        return;

    lpTransMsg += lpIMC->dwNumMsgBuf;
    for (i = 0; i < length; i++)
    {
        lpTransMsg->message = WM_IME_CHAR;
        lpTransMsg->wParam = String[i];
        lpTransMsg->lParam = 1;
        lpTransMsg ++;
    }

    ImmUnlockIMCC(lpIMC->hMsgBuf);
    lpIMC->dwNumMsgBuf+=length;

    ImmGenerateMessage(RealIMC(hIMC));
    UnlockRealIMC(hIMC);
}

static BOOL IME_RemoveFromSelected(HIMC hIMC)
{
    int i;
    for (i = 0; i < hSelectedCount; i++)
        if (hSelectedFrom[i] == hIMC)
        {
            if (i < hSelectedCount - 1)
                memcpy(&hSelectedFrom[i], &hSelectedFrom[i+1], (hSelectedCount - i - 1)*sizeof(HIMC));
            hSelectedCount --;
            return TRUE;
        }
    return FALSE;
}

static void IME_AddToSelected(HIMC hIMC)
{
    hSelectedCount++;
    if (hSelectedFrom)
        hSelectedFrom = HeapReAlloc(GetProcessHeap(), 0, hSelectedFrom, hSelectedCount*sizeof(HIMC));
    else
        hSelectedFrom = HeapAlloc(GetProcessHeap(), 0, sizeof(HIMC));
    hSelectedFrom[hSelectedCount-1] = hIMC;
}

BOOL WINAPI ImeInquire(LPIMEINFO lpIMEInfo, LPWSTR lpszUIClass,
                       LPCWSTR lpszOption)
{
    TRACE("\n");
    IME_RegisterClasses();
    lpIMEInfo->dwPrivateDataSize = sizeof (IMEPRIVATE);
    lpIMEInfo->fdwProperty = IME_PROP_UNICODE | IME_PROP_AT_CARET;
    lpIMEInfo->fdwConversionCaps = IME_CMODE_NATIVE;
    lpIMEInfo->fdwSentenceCaps = IME_SMODE_AUTOMATIC;
    lpIMEInfo->fdwUICaps = UI_CAP_2700;
    /* Tell App we cannot accept ImeSetCompositionString calls */
    lpIMEInfo->fdwSCSCaps = 0;
    lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION;

    lstrcpyW(lpszUIClass,UI_CLASS_NAME);

    return TRUE;
}

BOOL WINAPI ImeConfigure(HKL hKL,HWND hWnd, DWORD dwMode, LPVOID lpData)
{
    FIXME("(%p, %p, %d, %p): stub\n", hKL, hWnd, dwMode, lpData);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

DWORD WINAPI ImeConversionList(HIMC hIMC, LPCWSTR lpSource,
                LPCANDIDATELIST lpCandList, DWORD dwBufLen, UINT uFlag)

{
    FIXME("(%p, %s, %p, %d, %d): stub\n", hIMC, debugstr_w(lpSource),
                                          lpCandList, dwBufLen, uFlag);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return 0;
}

BOOL WINAPI ImeDestroy(UINT uForce)
{
    TRACE("\n");
    HeapFree(GetProcessHeap(),0,hSelectedFrom);
    hSelectedFrom = NULL;
    hSelectedCount = 0;
    return TRUE;
}

LRESULT WINAPI ImeEscape(HIMC hIMC, UINT uSubFunc, LPVOID lpData)
{
    FIXME("(%p, %d, %p): stub\n", hIMC, uSubFunc, lpData);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return 0;
}

BOOL WINAPI ImeProcessKey(HIMC hIMC, UINT vKey, LPARAM lKeyData,
                             CONST LPBYTE lpbKeyState)
{
    /* See the comment at the head of this file */
    TRACE("We do no processing via this route\n");
    return FALSE;
}

BOOL WINAPI ImeSelect(HIMC hIMC, BOOL fSelect)
{
    LPINPUTCONTEXT lpIMC;
    TRACE("%p %s\n",hIMC,(fSelect)?"TRUE":"FALSE");

    if (hIMC == FROM_X11)
    {
        ERR("ImeSelect should never be called from X11\n");
        return FALSE;
    }

    if (!hIMC)
        return TRUE;

    /* not selected */
    if (!fSelect)
        return IME_RemoveFromSelected(hIMC);

    IME_AddToSelected(hIMC);

    /* Initialize our structures */
    lpIMC = LockRealIMC(hIMC);
    if (lpIMC != NULL)
    {
        LPIMEPRIVATE myPrivate;
        myPrivate = (LPIMEPRIVATE)ImmLockIMCC(lpIMC->hPrivate);
        myPrivate->bInComposition = FALSE;
        myPrivate->bInternalState = FALSE;
        myPrivate->textfont = NULL;
        myPrivate->hwndDefault = NULL;
        ImmUnlockIMCC(lpIMC->hPrivate);
        UnlockRealIMC(hIMC);
    }

    return TRUE;
}

BOOL WINAPI ImeSetActiveContext(HIMC hIMC,BOOL fFlag)
{
    FIXME("Stub");
    return TRUE;
}

UINT WINAPI ImeToAsciiEx (UINT uVKey, UINT uScanCode,
                          CONST LPBYTE lpbKeyState, LPDWORD lpdwTransKey,
                          UINT fuState, HIMC hIMC)
{
    /* See the comment at the head of this file */
    TRACE("We do no processing via this route\n");
    return 0;
}

BOOL WINAPI NotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
{
    BOOL bRet = FALSE;
    LPINPUTCONTEXT lpIMC;

    TRACE("%p %i %i %i\n",hIMC,dwAction,dwIndex,dwValue);

    lpIMC = LockRealIMC(hIMC);
    if (lpIMC == NULL)
        return FALSE;

    switch (dwAction)
    {
        case NI_OPENCANDIDATE: FIXME("NI_OPENCANDIDATE\n"); break;
        case NI_CLOSECANDIDATE: FIXME("NI_CLOSECANDIDATE\n"); break;
        case NI_SELECTCANDIDATESTR: FIXME("NI_SELECTCANDIDATESTR\n"); break;
        case NI_CHANGECANDIDATELIST: FIXME("NI_CHANGECANDIDATELIST\n"); break;
        case NI_SETCANDIDATE_PAGESTART: FIXME("NI_SETCANDIDATE_PAGESTART\n"); break;
        case NI_SETCANDIDATE_PAGESIZE: FIXME("NI_SETCANDIDATE_PAGESIZE\n"); break;
        case NI_CONTEXTUPDATED:
            switch (dwValue)
            {
                case IMC_SETCOMPOSITIONWINDOW: FIXME("IMC_SETCOMPOSITIONWINDOW\n"); break;
                case IMC_SETCONVERSIONMODE: FIXME("IMC_SETCONVERSIONMODE\n"); break;
                case IMC_SETSENTENCEMODE: FIXME("IMC_SETSENTENCEMODE\n"); break;
                case IMC_SETCANDIDATEPOS: FIXME("IMC_SETCANDIDATEPOS\n"); break;
                case IMC_SETCOMPOSITIONFONT:
                    {
                        LPIMEPRIVATE myPrivate;
                        TRACE("IMC_SETCOMPOSITIONFONT\n");

                        myPrivate = (LPIMEPRIVATE)ImmLockIMCC(lpIMC->hPrivate);
                        if (myPrivate->textfont)
                        {
                            DeleteObject(myPrivate->textfont);
                            myPrivate->textfont = NULL;
                        }
                        myPrivate->textfont = CreateFontIndirectW(&lpIMC->lfFont.W);
                        ImmUnlockIMCC(lpIMC->hPrivate);
                    }
                    break;
                case IMC_SETOPENSTATUS:
                {
                    LPIMEPRIVATE myPrivate;
                    TRACE("IMC_SETOPENSTATUS\n");

                    myPrivate = (LPIMEPRIVATE)ImmLockIMCC(lpIMC->hPrivate);
                    if (lpIMC->fOpen != myPrivate->bInternalState &&
                        myPrivate->bInComposition)
                    {
                        if(lpIMC->fOpen == FALSE)
                        {
                            X11DRV_ForceXIMReset(lpIMC->hWnd);
                            GenerateIMEMessage(hIMC,WM_IME_ENDCOMPOSITION,0,0);
                            myPrivate->bInComposition = FALSE;
                        }
                        else
                        {
                            GenerateIMEMessage(hIMC,WM_IME_STARTCOMPOSITION,0,0);
                            GenerateIMEMessage(hIMC, WM_IME_COMPOSITION, 0, 0);
                        }
                    }
                    myPrivate->bInternalState = lpIMC->fOpen;
                    bRet = TRUE;
                }
                break;
                default: FIXME("Unknown\n"); break;
            }
            break;
        case NI_COMPOSITIONSTR:
            switch (dwIndex)
            {
                case CPS_COMPLETE:
                {
                    HIMCC newCompStr;
                    DWORD cplen = 0;
                    LPWSTR cpstr;
                    LPCOMPOSITIONSTRING cs = NULL;
                    LPBYTE cdata = NULL;
                    LPIMEPRIVATE myPrivate;

                    TRACE("CPS_COMPLETE\n");

                    /* clear existing result */
                    newCompStr = updateResultStr(lpIMC->hCompStr, NULL, 0);

                    ImmDestroyIMCC(lpIMC->hCompStr);
                    lpIMC->hCompStr = newCompStr;

                    if (lpIMC->hCompStr)
                    {
                        cdata = ImmLockIMCC(lpIMC->hCompStr);
                        cs = (LPCOMPOSITIONSTRING)cdata;
                        cplen = cs->dwCompStrLen;
                        cpstr = (LPWSTR)&(cdata[cs->dwCompStrOffset]);
                        ImmUnlockIMCC(lpIMC->hCompStr);
                    }
                    if (cplen > 0)
                    {
                        WCHAR param = cpstr[0];

                        newCompStr = updateResultStr(lpIMC->hCompStr, cpstr, cplen);
                        ImmDestroyIMCC(lpIMC->hCompStr);
                        lpIMC->hCompStr = newCompStr;
                        newCompStr = updateCompStr(lpIMC->hCompStr, NULL, 0);
                        ImmDestroyIMCC(lpIMC->hCompStr);
                        lpIMC->hCompStr = newCompStr;

                        GenerateIMEMessage(hIMC, WM_IME_COMPOSITION, 0,
                                                  GCS_COMPSTR);

                        GenerateIMEMessage(hIMC, WM_IME_COMPOSITION, param,
                                            GCS_RESULTSTR|GCS_RESULTCLAUSE);
                    }

                    GenerateIMEMessage(hIMC,WM_IME_ENDCOMPOSITION, 0, 0);

                    myPrivate = (LPIMEPRIVATE)ImmLockIMCC(lpIMC->hPrivate);
                    myPrivate->bInComposition = FALSE;
                    ImmUnlockIMCC(lpIMC->hPrivate);

                    bRet = TRUE;
                }
                break;
                case CPS_CONVERT: FIXME("CPS_CONVERT\n"); break;
                case CPS_REVERT: FIXME("CPS_REVERT\n"); break;
                case CPS_CANCEL:
                {
                    LPIMEPRIVATE myPrivate;

                    TRACE("CPS_CANCEL\n");

                    X11DRV_ForceXIMReset(lpIMC->hWnd);

                    if (lpIMC->hCompStr)
                        ImmDestroyIMCC(lpIMC->hCompStr);
                    lpIMC->hCompStr = ImeCreateBlankCompStr();

                    myPrivate = (LPIMEPRIVATE)ImmLockIMCC(lpIMC->hPrivate);
                    if (myPrivate->bInComposition)
                    {
                        GenerateIMEMessage(hIMC, WM_IME_ENDCOMPOSITION, 0, 0);
                        myPrivate->bInComposition = FALSE;
                    }
                    ImmUnlockIMCC(lpIMC->hPrivate);
                    bRet = TRUE;
                }
                break;
                default: FIXME("Unknown\n"); break;
            }
            break;
        default: FIXME("Unknown Message\n"); break;
    }

    UnlockRealIMC(hIMC);
    return bRet;
}

BOOL WINAPI ImeRegisterWord(LPCWSTR lpszReading, DWORD dwStyle,
                            LPCWSTR lpszRegister)
{
    FIXME("(%s, %d, %s): stub\n", debugstr_w(lpszReading), dwStyle,
                                  debugstr_w(lpszRegister));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

BOOL WINAPI ImeUnregisterWord(LPCWSTR lpszReading, DWORD dwStyle,
                              LPCWSTR lpszUnregister)
{
    FIXME("(%s, %d, %s): stub\n", debugstr_w(lpszReading), dwStyle,
                                  debugstr_w(lpszUnregister));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

UINT WINAPI ImeGetRegisterWordStyle(UINT nItem, LPSTYLEBUFW lpStyleBuf)
{
    FIXME("(%d, %p): stub\n", nItem, lpStyleBuf);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return 0;
}

UINT WINAPI ImeEnumRegisterWord(REGISTERWORDENUMPROCW lpfnEnumProc,
                                LPCWSTR lpszReading, DWORD dwStyle,
                                LPCWSTR lpszRegister, LPVOID lpData)
{
    FIXME("(%p, %s, %d, %s, %p): stub\n", lpfnEnumProc,
            debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister),
            lpData);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return 0;
}

BOOL WINAPI ImeSetCompositionString(HIMC hIMC, DWORD dwIndex, LPCVOID lpComp,
                                    DWORD dwCompLen, LPCVOID lpRead,
                                    DWORD dwReadLen)
{
    LPINPUTCONTEXT lpIMC;
    DWORD flags = 0;
    WCHAR wParam  = 0;
    LPIMEPRIVATE myPrivate;

    TRACE("(%p, %d, %p, %d, %p, %d):\n",
         hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);


    if (hIMC != FROM_X11)
        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");

    lpIMC = LockRealIMC(hIMC);

    if (lpIMC == NULL)
        return FALSE;

    myPrivate = (LPIMEPRIVATE)ImmLockIMCC(lpIMC->hPrivate);

    if (dwIndex == SCS_SETSTR)
    {
        HIMCC newCompStr;

        if (!myPrivate->bInComposition)
        {
            GenerateIMEMessage(hIMC, WM_IME_STARTCOMPOSITION, 0, 0);
            myPrivate->bInComposition = TRUE;
        }

        flags = GCS_COMPSTR;

        if (dwCompLen && lpComp)
        {
            newCompStr = updateCompStr(lpIMC->hCompStr, (LPWSTR)lpComp, dwCompLen / sizeof(WCHAR));
            ImmDestroyIMCC(lpIMC->hCompStr);
            lpIMC->hCompStr = newCompStr;

             wParam = ((const WCHAR*)lpComp)[0];
             flags |= GCS_COMPCLAUSE | GCS_COMPATTR | GCS_DELTASTART;
        }
        else
        {
            newCompStr = updateCompStr(lpIMC->hCompStr, NULL, 0);
            ImmDestroyIMCC(lpIMC->hCompStr);
            lpIMC->hCompStr = newCompStr;
        }
    }

    UpdateDataInDefaultIMEWindow(hIMC, myPrivate->hwndDefault,FALSE);

    GenerateIMEMessage(hIMC, WM_IME_COMPOSITION, wParam, flags);
    ImmUnlockIMCC(lpIMC->hPrivate);
    UnlockRealIMC(hIMC);

    return TRUE;
}

DWORD WINAPI ImeGetImeMenuItems(HIMC hIMC,  DWORD dwFlags,  DWORD dwType,
            LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu,
            DWORD dwSize)
{
    FIXME("(%p, %x %x %p %p %x): stub\n", hIMC, dwFlags, dwType,
                                lpImeParentMenu, lpImeMenu, dwSize);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return 0;
}

/* Interfaces to XIM and other parts of winex11drv */

void IME_SetOpenStatus(BOOL fOpen)
{
    LPINPUTCONTEXT lpIMC;
    LPIMEPRIVATE myPrivate;

    lpIMC = LockRealIMC(FROM_X11);
    if (lpIMC == NULL)
        return;

    myPrivate = (LPIMEPRIVATE)ImmLockIMCC(lpIMC->hPrivate);

    if (myPrivate->bInternalState && fOpen == FALSE)
    {
        ShowWindow(myPrivate->hwndDefault, SW_HIDE);
        ImmDestroyIMCC(lpIMC->hCompStr);
        lpIMC->hCompStr = ImeCreateBlankCompStr();
    }

    ImmUnlockIMCC(lpIMC->hPrivate);
    UnlockRealIMC(FROM_X11);

    if (myPrivate->bInComposition && fOpen == FALSE)
    {
        GenerateIMEMessage(FROM_X11, WM_IME_ENDCOMPOSITION, 0, 0);
        myPrivate->bInComposition = FALSE;
    }

    if (!myPrivate->bInternalState && fOpen == TRUE)
        ImmSetOpenStatus(RealIMC(FROM_X11), fOpen);
}

LRESULT IME_SendMessageToSelectedHWND(UINT msg, WPARAM wParam, LPARAM lParam)
{
    LPINPUTCONTEXT lpIMC;
    LRESULT rc = 0;

    if (!hSelectedFrom)
        return rc;

    lpIMC = LockRealIMC(FROM_X11);
    if (lpIMC)
        rc = SendMessageW(lpIMC->hWnd,msg,wParam,lParam);

    UnlockRealIMC(FROM_X11);
    return rc;
}

INT IME_GetCursorPos(void)
{
    LPINPUTCONTEXT lpIMC;
    INT rc = 0;
    LPCOMPOSITIONSTRING compstr;

    if (!hSelectedFrom)
        return rc;

    lpIMC = LockRealIMC(FROM_X11);
    if (lpIMC)
    {
        compstr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
        rc = compstr->dwCursorPos;
        ImmUnlockIMCC(lpIMC->hCompStr);
    }
    UnlockRealIMC(FROM_X11);
    return rc;
}

void IME_SetCursorPos(DWORD pos)
{
    LPINPUTCONTEXT lpIMC;
    LPCOMPOSITIONSTRING compstr;

    if (!hSelectedFrom)
        return;

    lpIMC = LockRealIMC(FROM_X11);
    if (!lpIMC)
        return;

    compstr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
    if (!compstr)
    {
        UnlockRealIMC(FROM_X11);
        return;
    }

    compstr->dwCursorPos = pos;
    ImmUnlockIMCC(lpIMC->hCompStr);
    UnlockRealIMC(FROM_X11);
    GenerateIMEMessage(FROM_X11, WM_IME_COMPOSITION, pos, GCS_CURSORPOS);
    return;
}

void IME_UpdateAssociation(HWND focus)
{
    ImmGetContext(focus);

    if (!focus || !hSelectedFrom)
        return;

    ImmAssociateContext(focus,RealIMC(FROM_X11));
}


BOOL IME_SetCompositionString(DWORD dwIndex, LPCVOID lpComp, DWORD dwCompLen,
                              LPCVOID lpRead, DWORD dwReadLen)
{
    return ImeSetCompositionString(FROM_X11, dwIndex, lpComp, dwCompLen,
                                    lpRead, dwReadLen);
}

BOOL IME_NotifyIME(DWORD dwAction, DWORD dwIndex, DWORD dwValue)
{
    return NotifyIME(FROM_X11, dwAction, dwIndex, dwValue);
}

/*****
 * Internal functions to help with IME window management
 */
static void PaintDefaultIMEWnd(HIMC hIMC, HWND hwnd)
{
    PAINTSTRUCT ps;
    RECT rect;
    HDC hdc;
    LPCOMPOSITIONSTRING compstr;
    LPBYTE compdata = NULL;
    HMONITOR monitor;
    MONITORINFO mon_info;
    INT offX=0, offY=0;
    LPINPUTCONTEXT lpIMC;

    lpIMC = LockRealIMC(hIMC);
    if (lpIMC == NULL)
        return;

    hdc = BeginPaint(hwnd,&ps);

    GetClientRect(hwnd,&rect);
    FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1));

    compdata = ImmLockIMCC(lpIMC->hCompStr);
    compstr = (LPCOMPOSITIONSTRING)compdata;

    if (compstr->dwCompStrLen && compstr->dwCompStrOffset)
    {
        SIZE size;
        POINT pt;
        HFONT oldfont = NULL;
        LPWSTR CompString;
        LPIMEPRIVATE myPrivate;

        CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
        myPrivate = (LPIMEPRIVATE)ImmLockIMCC(lpIMC->hPrivate);

        if (myPrivate->textfont)
            oldfont = SelectObject(hdc,myPrivate->textfont);

        ImmUnlockIMCC(lpIMC->hPrivate);

        GetTextExtentPoint32W(hdc, CompString, compstr->dwCompStrLen, &size);
        pt.x = size.cx;
        pt.y = size.cy;
        LPtoDP(hdc,&pt,1);

        /*
         * How this works based on tests on windows:
         * CFS_POINT: then we start our window at the point and grow it as large
         *    as it needs to be for the string.
         * CFS_RECT:  we still use the ptCurrentPos as a starting point and our
         *    window is only as large as we need for the string, but we do not
         *    grow such that our window exceeds the given rect.  Wrapping if
         *    needed and possible.   If our ptCurrentPos is outside of our rect
         *    then no window is displayed.
         * CFS_FORCE_POSITION: appears to behave just like CFS_POINT
         *    maybe becase the default MSIME does not do any IME adjusting.
         */
        if (lpIMC->cfCompForm.dwStyle != CFS_DEFAULT)
        {
            POINT cpt = lpIMC->cfCompForm.ptCurrentPos;
            ClientToScreen(lpIMC->hWnd,&cpt);
            rect.left = cpt.x;
            rect.top = cpt.y;
            rect.right = rect.left + pt.x;
            rect.bottom = rect.top + pt.y;
            monitor = MonitorFromPoint(cpt, MONITOR_DEFAULTTOPRIMARY);
        }
        else /* CFS_DEFAULT */
        {
            /* Windows places the default IME window in the bottom left */
            HWND target = lpIMC->hWnd;
            if (!target) target = GetFocus();

            GetWindowRect(target,&rect);
            rect.top = rect.bottom;
            rect.right = rect.left + pt.x + 20;
            rect.bottom = rect.top + pt.y + 20;
            offX=offY=10;
            monitor = MonitorFromWindow(target, MONITOR_DEFAULTTOPRIMARY);
        }

        if (lpIMC->cfCompForm.dwStyle == CFS_RECT)
        {
            RECT client;
            client =lpIMC->cfCompForm.rcArea;
            MapWindowPoints( lpIMC->hWnd, 0, (POINT *)&client, 2 );
            IntersectRect(&rect,&rect,&client);
            /* TODO:  Wrap the input if needed */
        }

        if (lpIMC->cfCompForm.dwStyle == CFS_DEFAULT)
        {
            /* make sure we are on the desktop */
            mon_info.cbSize = sizeof(mon_info);
            GetMonitorInfoW(monitor, &mon_info);

            if (rect.bottom > mon_info.rcWork.bottom)
            {
                int shift = rect.bottom - mon_info.rcWork.bottom;
                rect.top -= shift;
                rect.bottom -= shift;
            }
            if (rect.left < 0)
            {
                rect.right -= rect.left;
                rect.left = 0;
            }
            if (rect.right > mon_info.rcWork.right)
            {
                int shift = rect.right - mon_info.rcWork.right;
                rect.left -= shift;
                rect.right -= shift;
            }
        }

        SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE);

        TextOutW(hdc, offX,offY, CompString, compstr->dwCompStrLen);

        if (oldfont)
            SelectObject(hdc,oldfont);
    }

    ImmUnlockIMCC(lpIMC->hCompStr);

    EndPaint(hwnd,&ps);
    UnlockRealIMC(hIMC);
}

static void UpdateDataInDefaultIMEWindow(HIMC hIMC, HWND hwnd, BOOL showable)
{
    LPCOMPOSITIONSTRING compstr;
    LPINPUTCONTEXT lpIMC;

    lpIMC = LockRealIMC(hIMC);
    if (lpIMC == NULL)
        return;

    if (lpIMC->hCompStr)
        compstr = ImmLockIMCC(lpIMC->hCompStr);
    else
        compstr = NULL;

    if (compstr == NULL || compstr->dwCompStrLen == 0)
        ShowWindow(hwnd,SW_HIDE);
    else if (showable)
        ShowWindow(hwnd,SW_SHOWNOACTIVATE);

    RedrawWindow(hwnd,NULL,NULL,RDW_ERASENOW|RDW_INVALIDATE);

    if (compstr != NULL)
        ImmUnlockIMCC(lpIMC->hCompStr);

    UnlockRealIMC(hIMC);
}

static void DefaultIMEComposition(HIMC hIMC, HWND hwnd, LPARAM lParam)
{
    TRACE("IME message WM_IME_COMPOSITION 0x%lx\n", lParam);
    if (lParam & GCS_RESULTSTR)
    {
        LPCOMPOSITIONSTRING compstr;
        LPBYTE compdata;
        LPWSTR ResultStr;
        HIMCC newCompStr;
        LPINPUTCONTEXT lpIMC;

        lpIMC = LockRealIMC(hIMC);
        if (lpIMC == NULL)
            return;

        TRACE("Posting result as IME_CHAR\n");
        compdata = ImmLockIMCC(lpIMC->hCompStr);
        compstr = (LPCOMPOSITIONSTRING)compdata;
        ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
        GenerateIMECHARMessages(hIMC, ResultStr, compstr->dwResultStrLen);
        ImmUnlockIMCC(lpIMC->hCompStr);

        /* clear the buffer */
        newCompStr = updateResultStr(lpIMC->hCompStr, NULL, 0);
        ImmDestroyIMCC(lpIMC->hCompStr);
        lpIMC->hCompStr = newCompStr;
        UnlockRealIMC(hIMC);
    }
    else
         UpdateDataInDefaultIMEWindow(hIMC,hwnd,TRUE);
}

static void DefaultIMEStartComposition(HIMC hIMC, HWND hwnd )
{
    LPINPUTCONTEXT lpIMC;

    lpIMC = LockRealIMC(hIMC);
    if (lpIMC == NULL)
        return;

    TRACE("IME message WM_IME_STARTCOMPOSITION\n");
    lpIMC->hWnd = GetFocus();
    ShowWindow(hwnd,SW_SHOWNOACTIVATE);
    UnlockRealIMC(hIMC);
}

static LRESULT ImeHandleNotify(HIMC hIMC, HWND hwnd, UINT msg, WPARAM wParam,
                               LPARAM lParam)
{
    switch (wParam)
    {
        case IMN_OPENSTATUSWINDOW:
            FIXME("WM_IME_NOTIFY:IMN_OPENSTATUSWINDOW\n");
            break;
        case IMN_CLOSESTATUSWINDOW:
            FIXME("WM_IME_NOTIFY:IMN_CLOSESTATUSWINDOW\n");
            break;
        case IMN_OPENCANDIDATE:
            FIXME("WM_IME_NOTIFY:IMN_OPENCANDIDATE\n");
            break;
        case IMN_CHANGECANDIDATE:
            FIXME("WM_IME_NOTIFY:IMN_CHANGECANDIDATE\n");
            break;
        case IMN_CLOSECANDIDATE:
            FIXME("WM_IME_NOTIFY:IMN_CLOSECANDIDATE\n");
            break;
        case IMN_SETCONVERSIONMODE:
            FIXME("WM_IME_NOTIFY:IMN_SETCONVERSIONMODE\n");
            break;
        case IMN_SETSENTENCEMODE:
            FIXME("WM_IME_NOTIFY:IMN_SETSENTENCEMODE\n");
            break;
        case IMN_SETOPENSTATUS:
            FIXME("WM_IME_NOTIFY:IMN_SETOPENSTATUS\n");
            break;
        case IMN_SETCANDIDATEPOS:
            FIXME("WM_IME_NOTIFY:IMN_SETCANDIDATEPOS\n");
            break;
        case IMN_SETCOMPOSITIONFONT:
            FIXME("WM_IME_NOTIFY:IMN_SETCOMPOSITIONFONT\n");
            break;
        case IMN_SETCOMPOSITIONWINDOW:
            FIXME("WM_IME_NOTIFY:IMN_SETCOMPOSITIONWINDOW\n");
            break;
        case IMN_GUIDELINE:
            FIXME("WM_IME_NOTIFY:IMN_GUIDELINE\n");
            break;
        case IMN_SETSTATUSWINDOWPOS:
            FIXME("WM_IME_NOTIFY:IMN_SETSTATUSWINDOWPOS\n");
            break;
        default:
            FIXME("WM_IME_NOTIFY:<Unknown 0x%lx>\n",wParam);
            break;
    }
    return 0;
}

static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
                                          LPARAM lParam)
{
    LRESULT rc = 0;
    HIMC    hIMC;

    TRACE("Incoming Message 0x%x  (0x%08lx, 0x%08lx)\n", msg, wParam, lParam);

    /*
     * Each UI window contains the current Input Context.
     * This Input Context can be obtained by calling GetWindowLong
     * with IMMGWL_IMC when the UI window receives a WM_IME_xxx message.
     * The UI window can refer to this Input Context and handles the
     * messages.
     */

    hIMC = (HIMC)GetWindowLongW(hwnd,IMMGWL_IMC);
    if (!hIMC)
        hIMC = RealIMC(FROM_X11);

    /* if we have no hIMC there are many messages we cannot process */
    if (hIMC == NULL)
    {
        switch (msg) {
        case WM_IME_STARTCOMPOSITION:
        case WM_IME_ENDCOMPOSITION:
        case WM_IME_COMPOSITION:
        case WM_IME_NOTIFY:
        case WM_IME_CONTROL:
        case WM_IME_COMPOSITIONFULL:
        case WM_IME_SELECT:
        case WM_IME_CHAR:
            return 0L;
        default:
            break;
        }
    }

    switch(msg)
    {
        case WM_CREATE:
        {
            LPIMEPRIVATE myPrivate;
            LPINPUTCONTEXT lpIMC;

            SetWindowTextA(hwnd,"Wine Ime Active");

            lpIMC = LockRealIMC(hIMC);
            if (lpIMC)
            {
                myPrivate = (LPIMEPRIVATE)ImmLockIMCC(lpIMC->hPrivate);
                myPrivate->hwndDefault = hwnd;
                ImmUnlockIMCC(lpIMC->hPrivate);
            }
            UnlockRealIMC(hIMC);

            return TRUE;
        }
        case WM_PAINT:
            PaintDefaultIMEWnd(hIMC, hwnd);
            return FALSE;

        case WM_NCCREATE:
            return TRUE;

        case WM_SETFOCUS:
            if (wParam)
                SetFocus((HWND)wParam);
            else
                FIXME("Received focus, should never have focus\n");
            break;
        case WM_IME_COMPOSITION:
            DefaultIMEComposition(hIMC, hwnd, lParam);
            break;
        case WM_IME_STARTCOMPOSITION:
            DefaultIMEStartComposition(hIMC, hwnd);
            break;
        case WM_IME_ENDCOMPOSITION:
            TRACE("IME message %s, 0x%lx, 0x%lx\n",
                    "WM_IME_ENDCOMPOSITION", wParam, lParam);
            ShowWindow(hwnd,SW_HIDE);
            break;
        case WM_IME_SELECT:
            TRACE("IME message %s, 0x%lx, 0x%lx\n","WM_IME_SELECT", wParam, lParam);
            break;
        case WM_IME_CONTROL:
            TRACE("IME message %s, 0x%lx, 0x%lx\n","WM_IME_CONTROL", wParam, lParam);
            rc = 1;
            break;
        case WM_IME_NOTIFY:
            rc = ImeHandleNotify(hIMC,hwnd,msg,wParam,lParam);
            break;
       default:
            TRACE("Non-standard message 0x%x\n",msg);
    }
    /* check the MSIME messages */
    if (msg == WM_MSIME_SERVICE)
    {
            TRACE("IME message %s, 0x%lx, 0x%lx\n","WM_MSIME_SERVICE", wParam, lParam);
            rc = FALSE;
    }
    else if (msg == WM_MSIME_RECONVERTOPTIONS)
    {
            TRACE("IME message %s, 0x%lx, 0x%lx\n","WM_MSIME_RECONVERTOPTIONS", wParam, lParam);
    }
    else if (msg == WM_MSIME_MOUSE)
    {
            TRACE("IME message %s, 0x%lx, 0x%lx\n","WM_MSIME_MOUSE", wParam, lParam);
    }
    else if (msg == WM_MSIME_RECONVERTREQUEST)
    {
            TRACE("IME message %s, 0x%lx, 0x%lx\n","WM_MSIME_RECONVERTREQUEST", wParam, lParam);
    }
    else if (msg == WM_MSIME_RECONVERT)
    {
            TRACE("IME message %s, 0x%lx, 0x%lx\n","WM_MSIME_RECONVERT", wParam, lParam);
    }
    else if (msg == WM_MSIME_QUERYPOSITION)
    {
            TRACE("IME message %s, 0x%lx, 0x%lx\n","WM_MSIME_QUERYPOSITION", wParam, lParam);
    }
    else if (msg == WM_MSIME_DOCUMENTFEED)
    {
            TRACE("IME message %s, 0x%lx, 0x%lx\n","WM_MSIME_DOCUMENTFEED", wParam, lParam);
    }
    /* DefWndProc if not an IME message */
    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;
}
