/*
 * 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 implementation.
 *  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 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 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_PTR);
    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");
}

static HIMCC ImeCreateBlankCompStr(void)
{
    HIMCC rc;
    LPCOMPOSITIONSTRING ptr;
    rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
    ptr = 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, LPCWSTR 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 (compstr == NULL && len != 0)
    {
        ERR("compstr is NULL however we have a len!  Please report\n");
        len = 0;
    }

    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 (resultstr == NULL && len != 0)
    {
        ERR("resultstr is NULL however we have a len!  Please report\n");
        len = 0;
    }

    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 = 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;
    DWORD 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 = 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)
                memmove(&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 = 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("(%p, %x): stub\n", hIMC, fFlag);
    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 = 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:
                    TRACE("IMC_SETOPENSTATUS\n");

                    bRet = TRUE;
                    X11DRV_SetPreeditState(lpIMC->hWnd, lpIMC->fOpen);
                    if (!lpIMC->fOpen)
                    {
                        LPIMEPRIVATE myPrivate;

                        myPrivate = ImmLockIMCC(lpIMC->hPrivate);
                        if (myPrivate->bInComposition)
                        {
                            X11DRV_ForceXIMReset(lpIMC->hWnd);
                            GenerateIMEMessage(hIMC, WM_IME_ENDCOMPOSITION, 0, 0);
                            myPrivate->bInComposition = FALSE;
                        }
                        ImmUnlockIMCC(lpIMC->hPrivate);
                    }

                    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 = 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 = 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 = 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, (LPCWSTR)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;
        }
    }

    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)
{
    HIMC imc;

    imc = RealIMC(FROM_X11);
    ImmSetOpenStatus(imc, fOpen);
}

void IME_SetCompositionStatus(BOOL fOpen)
{
    HIMC imc;
    LPINPUTCONTEXT lpIMC;
    LPIMEPRIVATE myPrivate;

    imc = RealIMC(FROM_X11);
    lpIMC = ImmLockIMC(imc);
    if (lpIMC == NULL)
        return;

    myPrivate = ImmLockIMCC(lpIMC->hPrivate);

    if (fOpen && !myPrivate->bInComposition)
    {
        GenerateIMEMessage(imc, WM_IME_STARTCOMPOSITION, 0, 0);
    }
    else if (!fOpen && myPrivate->bInComposition)
    {
        ShowWindow(myPrivate->hwndDefault, SW_HIDE);
        ImmDestroyIMCC(lpIMC->hCompStr);
        lpIMC->hCompStr = ImeCreateBlankCompStr();
        GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0);
    }
    myPrivate->bInComposition = fOpen;

    ImmUnlockIMCC(lpIMC->hPrivate);
    ImmUnlockIMC(imc);
}

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

    if (!hSelectedFrom)
        return rc;

    lpIMC = LockRealIMC(FROM_X11);
    if (lpIMC)
    {
        compstr = 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 = 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);
}

void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen)
{
    HIMC imc;
    LPINPUTCONTEXT lpIMC;
    HIMCC newCompStr;
    LPIMEPRIVATE myPrivate;

    imc = RealIMC(FROM_X11);
    lpIMC = ImmLockIMC(imc);
    if (lpIMC == NULL)
        return;

    newCompStr = updateResultStr(lpIMC->hCompStr, lpResult, dwResultLen);
    ImmDestroyIMCC(lpIMC->hCompStr);
    lpIMC->hCompStr = newCompStr;

    myPrivate = ImmLockIMCC(lpIMC->hPrivate);
    if (!myPrivate->bInComposition)
        GenerateIMEMessage(imc, WM_IME_STARTCOMPOSITION, 0, 0);
    GenerateIMEMessage(imc, WM_IME_COMPOSITION, 0, GCS_RESULTSTR);
    if (!myPrivate->bInComposition)
        GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0);
    ImmUnlockIMCC(lpIMC->hPrivate);

    ImmUnlockIMC(imc);
}

/*****
 * 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 = 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 because 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 UpdateDefaultIMEWindow(HIMC hIMC, HWND hwnd)
{
    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
    {
        ShowWindow(hwnd,SW_SHOWNOACTIVATE);
        RedrawWindow(hwnd, NULL, NULL, RDW_ERASENOW | RDW_INVALIDATE);
    }

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

    lpIMC->hWnd = GetFocus();
    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
        UpdateDefaultIMEWindow(hIMC, hwnd);
}

static void DefaultIMEStartComposition(HIMC hIMC, HWND hwnd )
{
    TRACE("IME message WM_IME_STARTCOMPOSITION\n");
    UpdateDefaultIMEWindow(hIMC, hwnd);
}

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:
            TRACE("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)GetWindowLongPtrW(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 = 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;
}
