--- /dev/null
+/*
+ * IMM32 library
+ *
+ * Copyright 1998 Patrik Stridvall
+ * Copyright 2002, 2003 CodeWeavers, Aric Stewart
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "imm.h"
+#include "winnls.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(imm);
+
+#define FROM_IME 0xcafe1337
+
+static void (*pX11DRV_ForceXIMReset)(HWND);
+
+typedef struct tagInputContextData
+{
+ LPBYTE CompositionString;
+ LPBYTE CompositionReadingString;
+ LPBYTE ResultString;
+ LPBYTE ResultReadingString;
+ DWORD dwCompStringSize; /* buffer size */
+ DWORD dwCompStringLength; /* string length (in bytes) */
+ DWORD dwCompReadStringSize;
+ DWORD dwResultStringSize;
+ DWORD dwResultReadStringSize;
+ HWND hwnd;
+ BOOL bOpen;
+ BOOL bInternalState;
+ BOOL bRead;
+ LOGFONTW font;
+ HFONT textfont;
+ COMPOSITIONFORM CompForm;
+} InputContextData;
+
+static InputContextData *root_context = NULL;
+static HWND hwndDefault = NULL;
+static HANDLE hImeInst;
+static const WCHAR WC_IMECLASSNAME[] = {'I','M','E',0};
+
+/* MSIME messages */
+static UINT WM_MSIME_SERVICE;
+static UINT WM_MSIME_RECONVERTOPTIONS;
+static UINT WM_MSIME_MOUSE;
+static UINT WM_MSIME_RECONVERTREQUEST;
+static UINT WM_MSIME_RECONVERT;
+static UINT WM_MSIME_QUERYPOSITION;
+static UINT WM_MSIME_DOCUMENTFEED;
+
+/*
+ * prototypes
+ */
+static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
+ LPARAM lParam);
+static void UpdateDataInDefaultIMEWindow(HWND hwnd);
+static void ImmInternalPostIMEMessage(UINT, WPARAM, LPARAM);
+static void ImmInternalSetOpenStatus(BOOL fOpen);
+
+static VOID IMM_PostResult(InputContextData *data)
+{
+ unsigned int i;
+ TRACE("Posting result as IME_CHAR\n");
+
+ for (i = 0; i < data->dwResultStringSize / sizeof (WCHAR); i++)
+ ImmInternalPostIMEMessage (WM_IME_CHAR, ((WCHAR*)data->ResultString)[i],
+ 1);
+
+ /* clear the buffer */
+ if (data->dwResultStringSize)
+ HeapFree(GetProcessHeap(),0,data->ResultString);
+ data->dwResultStringSize = 0;
+ data->ResultString = NULL;
+}
+
+static void IMM_Register(void)
+{
+ WNDCLASSW wndClass;
+ ZeroMemory(&wndClass, sizeof(WNDCLASSW));
+ wndClass.style = CS_GLOBALCLASS | CS_IME | CS_HREDRAW | CS_VREDRAW;
+ wndClass.lpfnWndProc = (WNDPROC) IME_WindowProc;
+ wndClass.cbClsExtra = 0;
+ wndClass.cbWndExtra = 0;
+ wndClass.hInstance = hImeInst;
+ wndClass.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
+ wndClass.hIcon = NULL;
+ wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
+ wndClass.lpszMenuName = 0;
+ wndClass.lpszClassName = WC_IMECLASSNAME;
+ RegisterClassW(&wndClass);
+}
+
+static void IMM_Unregister(void)
+{
+ UnregisterClassW(WC_IMECLASSNAME, NULL);
+}
+
+static void IMM_RegisterMessages(void)
+{
+ WM_MSIME_SERVICE = RegisterWindowMessageA("MSIMEService");
+ WM_MSIME_RECONVERTOPTIONS = RegisterWindowMessageA("MSIMEReconvertOptions");
+ WM_MSIME_MOUSE = RegisterWindowMessageA("MSIMEMouseOperation");
+ WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageA("MSIMEReconvertRequest");
+ WM_MSIME_RECONVERT = RegisterWindowMessageA("MSIMEReconvert");
+ WM_MSIME_QUERYPOSITION = RegisterWindowMessageA("MSIMEQueryPosition");
+ WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
+}
+
+
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
+{
+ HMODULE x11drv;
+
+ TRACE("%p, %lx, %p\n",hInstDLL,fdwReason,lpReserved);
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hInstDLL);
+ hImeInst = hInstDLL;
+ IMM_RegisterMessages();
+ x11drv = GetModuleHandleA("winex11.drv");
+ if (x11drv) pX11DRV_ForceXIMReset = (void *)GetProcAddress( x11drv, "ForceXIMReset");
+ break;
+ case DLL_PROCESS_DETACH:
+ if (hwndDefault)
+ {
+ DestroyWindow(hwndDefault);
+ hwndDefault = 0;
+ }
+ IMM_Unregister();
+ break;
+ }
+ return TRUE;
+}
+
+/* for posting messages as the IME */
+static void ImmInternalPostIMEMessage(UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ HWND target = GetFocus();
+ if (!target)
+ PostMessageW(root_context->hwnd,msg,wParam,lParam);
+ else
+ PostMessageW(target, msg, wParam, lParam);
+}
+
+
+static void ImmInternalSetOpenStatus(BOOL fOpen)
+{
+ TRACE("Setting internal state to %s\n",(fOpen)?"OPEN":"CLOSED");
+
+ root_context->bOpen = fOpen;
+ root_context->bInternalState = fOpen;
+
+ if (fOpen == FALSE)
+ {
+ ShowWindow(hwndDefault,SW_HIDE);
+
+ if (root_context->dwCompStringSize)
+ HeapFree(GetProcessHeap(),0,root_context->CompositionString);
+ if (root_context->dwCompReadStringSize)
+ HeapFree(GetProcessHeap(),0,root_context->CompositionReadingString);
+ if (root_context->dwResultStringSize)
+ HeapFree(GetProcessHeap(),0,root_context->ResultString);
+ if (root_context->dwResultReadStringSize)
+ HeapFree(GetProcessHeap(),0,root_context->ResultReadingString);
+ root_context->dwCompStringSize = 0;
+ root_context->dwCompStringLength = 0;
+ root_context->CompositionString = NULL;
+ root_context->dwCompReadStringSize = 0;
+ root_context->CompositionReadingString = NULL;
+ root_context->dwResultStringSize = 0;
+ root_context->ResultString = NULL;
+ root_context->dwResultReadStringSize = 0;
+ root_context->ResultReadingString = NULL;
+ }
+ else
+ ShowWindow(hwndDefault, SW_SHOWNOACTIVATE);
+
+ SendMessageW(root_context->hwnd, WM_IME_NOTIFY, IMN_SETOPENSTATUS, 0);
+}
+
+
+/***********************************************************************
+ * ImmAssociateContext (IMM32.@)
+ */
+HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
+{
+ InputContextData *data = (InputContextData*)hIMC;
+
+ WARN("(%p, %p): semi-stub\n",hWnd,hIMC);
+
+ if (!data)
+ return FALSE;
+
+ /*
+ * WINE SPECIFIC! MAY CONFLICT
+ * associate the root context we have an XIM created
+ */
+ if (hWnd == 0x000)
+ {
+ root_context = (InputContextData*)hIMC;
+ }
+
+ /*
+ * If already associated just return
+ */
+ if (data->hwnd == hWnd)
+ return (HIMC)data;
+
+ if (IsWindow(data->hwnd))
+ {
+ /*
+ * Post a message that your context is switching
+ */
+ SendMessageW(data->hwnd, WM_IME_SETCONTEXT, FALSE, ISC_SHOWUIALL);
+ }
+
+ data->hwnd = hWnd;
+
+ if (IsWindow(data->hwnd))
+ {
+ /*
+ * Post a message that your context is switching
+ */
+ SendMessageW(data->hwnd, WM_IME_SETCONTEXT, TRUE, ISC_SHOWUIALL);
+ }
+
+ /*
+ * TODO: We need to keep track of the old context associated
+ * with a window and return it for now we will return NULL;
+ */
+ return (HIMC)NULL;
+}
+
+/***********************************************************************
+ * ImmAssociateContextEx (IMM32.@)
+ */
+BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
+{
+ FIXME("(%p, %p, %ld): stub\n", hWnd, hIMC, dwFlags);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmConfigureIMEA (IMM32.@)
+ */
+BOOL WINAPI ImmConfigureIMEA(
+ HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
+{
+ FIXME("(%p, %p, %ld, %p): stub\n",
+ hKL, hWnd, dwMode, lpData
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmConfigureIMEW (IMM32.@)
+ */
+BOOL WINAPI ImmConfigureIMEW(
+ HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
+{
+ FIXME("(%p, %p, %ld, %p): stub\n",
+ hKL, hWnd, dwMode, lpData
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmCreateContext (IMM32.@)
+ */
+HIMC WINAPI ImmCreateContext(void)
+{
+ InputContextData *new_context;
+
+ new_context = HeapAlloc(GetProcessHeap(),0,sizeof(InputContextData));
+ ZeroMemory(new_context,sizeof(InputContextData));
+
+ return (HIMC)new_context;
+}
+
+/***********************************************************************
+ * ImmDestroyContext (IMM32.@)
+ */
+BOOL WINAPI ImmDestroyContext(HIMC hIMC)
+{
+ InputContextData *data = (InputContextData*)hIMC;
+
+ TRACE("Destroying %p\n",hIMC);
+
+ if (hIMC)
+ {
+ if (data->dwCompStringSize)
+ HeapFree(GetProcessHeap(),0,data->CompositionString);
+ if (data->dwCompReadStringSize)
+ HeapFree(GetProcessHeap(),0,data->CompositionReadingString);
+ if (data->dwResultStringSize)
+ HeapFree(GetProcessHeap(),0,data->ResultString);
+ if (data->dwResultReadStringSize)
+ HeapFree(GetProcessHeap(),0,data->ResultReadingString);
+
+ if (data->textfont)
+ {
+ DeleteObject(data->textfont);
+ data->textfont = NULL;
+ }
+
+ HeapFree(GetProcessHeap(),0,data);
+ }
+ return TRUE;
+}
+
+/***********************************************************************
+ * ImmDisableIME (IMM32.@)
+ */
+BOOL WINAPI ImmDisableIME(DWORD idThread)
+{
+ FIXME("(%ld): stub\n", idThread);
+ return TRUE;
+}
+
+/***********************************************************************
+ * ImmEnumRegisterWordA (IMM32.@)
+ */
+UINT WINAPI ImmEnumRegisterWordA(
+ HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
+ LPCSTR lpszReading, DWORD dwStyle,
+ LPCSTR lpszRegister, LPVOID lpData)
+{
+ FIXME("(%p, %p, %s, %ld, %s, %p): stub\n",
+ hKL, lpfnEnumProc,
+ debugstr_a(lpszReading), dwStyle,
+ debugstr_a(lpszRegister), lpData
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmEnumRegisterWordW (IMM32.@)
+ */
+UINT WINAPI ImmEnumRegisterWordW(
+ HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
+ LPCWSTR lpszReading, DWORD dwStyle,
+ LPCWSTR lpszRegister, LPVOID lpData)
+{
+ FIXME("(%p, %p, %s, %ld, %s, %p): stub\n",
+ hKL, lpfnEnumProc,
+ debugstr_w(lpszReading), dwStyle,
+ debugstr_w(lpszRegister), lpData
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmEscapeA (IMM32.@)
+ */
+LRESULT WINAPI ImmEscapeA(
+ HKL hKL, HIMC hIMC,
+ UINT uEscape, LPVOID lpData)
+{
+ FIXME("(%p, %p, %d, %p): stub\n",
+ hKL, hIMC, uEscape, lpData
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmEscapeW (IMM32.@)
+ */
+LRESULT WINAPI ImmEscapeW(
+ HKL hKL, HIMC hIMC,
+ UINT uEscape, LPVOID lpData)
+{
+ FIXME("(%p, %p, %d, %p): stub\n",
+ hKL, hIMC, uEscape, lpData
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetCandidateListA (IMM32.@)
+ */
+DWORD WINAPI ImmGetCandidateListA(
+ HIMC hIMC, DWORD deIndex,
+ LPCANDIDATELIST lpCandList, DWORD dwBufLen)
+{
+ FIXME("(%p, %ld, %p, %ld): stub\n",
+ hIMC, deIndex,
+ lpCandList, dwBufLen
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetCandidateListCountA (IMM32.@)
+ */
+DWORD WINAPI ImmGetCandidateListCountA(
+ HIMC hIMC, LPDWORD lpdwListCount)
+{
+ FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetCandidateListCountW (IMM32.@)
+ */
+DWORD WINAPI ImmGetCandidateListCountW(
+ HIMC hIMC, LPDWORD lpdwListCount)
+{
+ FIXME("(%p, %p): stub\n", hIMC, lpdwListCount);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetCandidateListW (IMM32.@)
+ */
+DWORD WINAPI ImmGetCandidateListW(
+ HIMC hIMC, DWORD deIndex,
+ LPCANDIDATELIST lpCandList, DWORD dwBufLen)
+{
+ FIXME("(%p, %ld, %p, %ld): stub\n",
+ hIMC, deIndex,
+ lpCandList, dwBufLen
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetCandidateWindow (IMM32.@)
+ */
+BOOL WINAPI ImmGetCandidateWindow(
+ HIMC hIMC, DWORD dwBufLen, LPCANDIDATEFORM lpCandidate)
+{
+ FIXME("(%p, %ld, %p): stub\n", hIMC, dwBufLen, lpCandidate);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmGetCompositionFontA (IMM32.@)
+ */
+BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
+{
+ FIXME("(%p, %p): stub\n", hIMC, lplf);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmGetCompositionFontW (IMM32.@)
+ */
+BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
+{
+ FIXME("(%p, %p): stub\n", hIMC, lplf);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmGetCompositionStringA (IMM32.@)
+ */
+LONG WINAPI ImmGetCompositionStringA(
+ HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
+{
+ CHAR *buf;
+ LONG rc = 0;
+ InputContextData *data = (InputContextData*)hIMC;
+
+ TRACE("(%p, 0x%lx, %p, %ld)\n", hIMC, dwIndex, lpBuf, dwBufLen);
+
+ if (!data)
+ return FALSE;
+
+ if (dwIndex == GCS_RESULTSTR)
+ {
+ TRACE("GSC_RESULTSTR %p %li\n",data->ResultString,
+ data->dwResultStringSize);
+
+ buf = HeapAlloc( GetProcessHeap(), 0, data->dwResultStringSize * 3 );
+ rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->ResultString,
+ data->dwResultStringSize / sizeof(WCHAR), buf,
+ data->dwResultStringSize * 3, NULL, NULL);
+ if (dwBufLen >= rc)
+ memcpy(lpBuf,buf,rc);
+
+ data->bRead = TRUE;
+ HeapFree( GetProcessHeap(), 0, buf );
+ }
+ else if (dwIndex == GCS_COMPSTR)
+ {
+ TRACE("GSC_COMPSTR %p %li\n",data->CompositionString,
+ data->dwCompStringLength/ sizeof(WCHAR));
+
+ buf = HeapAlloc( GetProcessHeap(), 0, data->dwCompStringLength * 3 );
+ rc = WideCharToMultiByte(CP_ACP, 0,(LPWSTR)data->CompositionString,
+ data->dwCompStringLength/ sizeof(WCHAR), buf,
+ data->dwCompStringLength* 3, NULL, NULL);
+ if (dwBufLen >= rc)
+ memcpy(lpBuf,buf,rc);
+ HeapFree( GetProcessHeap(), 0, buf );
+ }
+ else if (dwIndex == GCS_COMPATTR)
+ {
+ TRACE("GSC_COMPATTR %p %li\n",data->CompositionString,
+ data->dwCompStringLength/ sizeof(WCHAR));
+
+ rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->CompositionString,
+ data->dwCompStringLength/ sizeof(WCHAR), NULL,
+ 0, NULL, NULL);
+
+ if (dwBufLen >= rc)
+ {
+ int i=0;
+ for (i = 0; i < rc; i++)
+ ((LPBYTE)lpBuf)[i] = ATTR_INPUT;
+ }
+ }
+ else if (dwIndex == GCS_COMPCLAUSE)
+ {
+ TRACE("GSC_COMPCLAUSE %p %li\n",data->CompositionString,
+ data->dwCompStringLength/ sizeof(WCHAR));
+
+ rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->CompositionString,
+ data->dwCompStringLength/ sizeof(WCHAR), NULL,
+ 0, NULL, NULL);
+
+ if (dwBufLen >= sizeof(DWORD)*2)
+ {
+ ((LPDWORD)lpBuf)[0] = 0;
+ ((LPDWORD)lpBuf)[1] = rc;
+ }
+ rc = sizeof(DWORD)*2;
+ }
+ else
+ {
+ FIXME("Unhandled index 0x%lx\n",dwIndex);
+ }
+
+ return rc;
+}
+
+/***********************************************************************
+ * ImmGetCompositionStringW (IMM32.@)
+ */
+LONG WINAPI ImmGetCompositionStringW(
+ HIMC hIMC, DWORD dwIndex,
+ LPVOID lpBuf, DWORD dwBufLen)
+{
+ LONG rc = 0;
+ InputContextData *data = (InputContextData*)hIMC;
+
+ TRACE("(%p, 0x%lx, %p, %ld)\n",
+ hIMC, dwIndex, lpBuf, dwBufLen
+ );
+
+ if (!data)
+ return FALSE;
+
+ if (dwIndex == GCS_RESULTSTR)
+ {
+ data->bRead = TRUE;
+
+ if (dwBufLen >= data->dwResultStringSize)
+ memcpy(lpBuf,data->ResultString,data->dwResultStringSize);
+
+ rc = data->dwResultStringSize;
+ }
+ else if (dwIndex == GCS_RESULTREADSTR)
+ {
+ if (dwBufLen >= data->dwResultReadStringSize)
+ memcpy(lpBuf,data->ResultReadingString,
+ data->dwResultReadStringSize);
+
+ rc = data->dwResultReadStringSize;
+ }
+ else if (dwIndex == GCS_COMPSTR)
+ {
+ if (dwBufLen >= data->dwCompStringLength)
+ memcpy(lpBuf,data->CompositionString,data->dwCompStringLength);
+
+ rc = data->dwCompStringLength;
+ }
+ else if (dwIndex == GCS_COMPATTR)
+ {
+ unsigned int len = data->dwCompStringLength;
+
+ if (dwBufLen >= len)
+ {
+ unsigned int i=0;
+ for (i = 0; i < len; i++)
+ ((LPBYTE)lpBuf)[i] = ATTR_INPUT;
+ }
+
+ rc = len;
+ }
+ else if (dwIndex == GCS_COMPCLAUSE)
+ {
+ if (dwBufLen >= sizeof(DWORD)*2)
+ {
+ ((LPDWORD)lpBuf)[0] = 0;
+ ((LPDWORD)lpBuf)[1] = data->dwCompStringLength/sizeof(WCHAR);
+ }
+ rc = sizeof(DWORD)*2;
+ }
+ else if (dwIndex == GCS_COMPREADSTR)
+ {
+ if (dwBufLen >= data->dwCompReadStringSize)
+ memcpy(lpBuf,data->CompositionReadingString,
+ data->dwCompReadStringSize);
+
+ rc = data->dwCompReadStringSize;
+ }
+ else
+ {
+ FIXME("Unhandled index 0x%lx\n",dwIndex);
+ }
+
+ return rc;
+}
+
+/***********************************************************************
+ * ImmGetCompositionWindow (IMM32.@)
+ */
+BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
+{
+ InputContextData *data = (InputContextData*)hIMC;
+
+ TRACE("(%p, %p)\n", hIMC, lpCompForm);
+
+ if (!data)
+ return FALSE;
+
+ memcpy(lpCompForm,&(data->CompForm),sizeof(COMPOSITIONFORM));
+ return 1;
+}
+
+/***********************************************************************
+ * ImmGetContext (IMM32.@)
+ *
+ */
+HIMC WINAPI ImmGetContext(HWND hWnd)
+{
+ FIXME("(%p): stub\n", hWnd);
+
+ if (!root_context)
+ return NULL;
+
+ root_context->hwnd = hWnd;
+ return (HIMC)root_context;
+}
+
+/***********************************************************************
+ * ImmGetConversionListA (IMM32.@)
+ */
+DWORD WINAPI ImmGetConversionListA(
+ HKL hKL, HIMC hIMC,
+ LPCSTR pSrc, LPCANDIDATELIST lpDst,
+ DWORD dwBufLen, UINT uFlag)
+{
+ FIXME("(%p, %p, %s, %p, %ld, %d): stub\n",
+ hKL, hIMC, debugstr_a(pSrc), lpDst, dwBufLen, uFlag
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetConversionListW (IMM32.@)
+ */
+DWORD WINAPI ImmGetConversionListW(
+ HKL hKL, HIMC hIMC,
+ LPCWSTR pSrc, LPCANDIDATELIST lpDst,
+ DWORD dwBufLen, UINT uFlag)
+{
+ FIXME("(%p, %p, %s, %p, %ld, %d): stub\n",
+ hKL, hIMC, debugstr_w(pSrc), lpDst, dwBufLen, uFlag
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetConversionStatus (IMM32.@)
+ */
+BOOL WINAPI ImmGetConversionStatus(
+ HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
+{
+ TRACE("(%p, %p, %p): best guess\n", hIMC, lpfdwConversion, lpfdwSentence);
+ if (lpfdwConversion)
+ *lpfdwConversion = IME_CMODE_NATIVE;
+ if (lpfdwSentence)
+ *lpfdwSentence = IME_SMODE_NONE;
+ return TRUE;
+}
+
+/***********************************************************************
+ * ImmGetDefaultIMEWnd (IMM32.@)
+ */
+HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
+{
+ FIXME("(%p - %p %p ): semi-stub\n", hWnd,hwndDefault, root_context);
+
+ if (hwndDefault == NULL)
+ {
+ static const WCHAR the_name[] = {'I','M','E','\0'};
+
+ IMM_Register();
+ hwndDefault = CreateWindowExW( WS_EX_CLIENTEDGE, WC_IMECLASSNAME,
+ the_name, WS_POPUPWINDOW|WS_CAPTION, 0, 0, 120, 55, 0, 0,
+ hImeInst, 0);
+
+ TRACE("Default created (%p)\n",hwndDefault);
+ }
+
+ return (HWND)hwndDefault;
+}
+
+/***********************************************************************
+ * ImmGetDescriptionA (IMM32.@)
+ */
+UINT WINAPI ImmGetDescriptionA(
+ HKL hKL, LPSTR lpszDescription, UINT uBufLen)
+{
+ WCHAR *buf;
+ DWORD len;
+
+ TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
+
+ /* find out how many characters in the unicode buffer */
+ len = ImmGetDescriptionW( hKL, NULL, 0 );
+
+ /* allocate a buffer of that size */
+ buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
+ if( !buf )
+ return 0;
+
+ /* fetch the unicode buffer */
+ len = ImmGetDescriptionW( hKL, buf, len + 1 );
+
+ /* convert it back to ASCII */
+ len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
+ lpszDescription, uBufLen, NULL, NULL );
+
+ HeapFree( GetProcessHeap(), 0, buf );
+
+ return len;
+}
+
+/***********************************************************************
+ * ImmGetDescriptionW (IMM32.@)
+ */
+UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
+{
+ static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
+
+ FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
+
+ if (!uBufLen) return lstrlenW( name );
+ lstrcpynW( lpszDescription, name, uBufLen );
+ return lstrlenW( lpszDescription );
+}
+
+/***********************************************************************
+ * ImmGetGuideLineA (IMM32.@)
+ */
+DWORD WINAPI ImmGetGuideLineA(
+ HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen)
+{
+ FIXME("(%p, %ld, %s, %ld): stub\n",
+ hIMC, dwIndex, debugstr_a(lpBuf), dwBufLen
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetGuideLineW (IMM32.@)
+ */
+DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen)
+{
+ FIXME("(%p, %ld, %s, %ld): stub\n",
+ hIMC, dwIndex, debugstr_w(lpBuf), dwBufLen
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetIMEFileNameA (IMM32.@)
+ */
+UINT WINAPI ImmGetIMEFileNameA(
+ HKL hKL, LPSTR lpszFileName, UINT uBufLen)
+{
+ FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetIMEFileNameW (IMM32.@)
+ */
+UINT WINAPI ImmGetIMEFileNameW(
+ HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
+{
+ FIXME("(%p, %p, %d): stub\n", hKL, lpszFileName, uBufLen);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetOpenStatus (IMM32.@)
+ */
+BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
+{
+ InputContextData *data = (InputContextData*)hIMC;
+
+ if (!data)
+ return FALSE;
+ FIXME("(%p): semi-stub\n", hIMC);
+
+ return data->bOpen;
+}
+
+/***********************************************************************
+ * ImmGetProperty (IMM32.@)
+ */
+DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
+{
+ DWORD rc = 0;
+ TRACE("(%p, %ld)\n", hKL, fdwIndex);
+
+ switch (fdwIndex)
+ {
+ case IGP_PROPERTY:
+ TRACE("(%s)\n", "IGP_PROPERTY");
+ rc = IME_PROP_UNICODE | IME_PROP_AT_CARET;
+ break;
+ case IGP_CONVERSION:
+ FIXME("(%s)\n", "IGP_CONVERSION");
+ rc = IME_CMODE_NATIVE;
+ break;
+ case IGP_SENTENCE:
+ FIXME("%s)\n", "IGP_SENTENCE");
+ rc = IME_SMODE_AUTOMATIC;
+ break;
+ case IGP_SETCOMPSTR:
+ TRACE("(%s)\n", "IGP_SETCOMPSTR");
+ rc = 0;
+ break;
+ case IGP_SELECT:
+ TRACE("(%s)\n", "IGP_SELECT");
+ rc = SELECT_CAP_CONVERSION | SELECT_CAP_SENTENCE;
+ break;
+ case IGP_GETIMEVERSION:
+ TRACE("(%s)\n", "IGP_GETIMEVERSION");
+ rc = IMEVER_0400;
+ break;
+ case IGP_UI:
+ TRACE("(%s)\n", "IGP_UI");
+ rc = 0;
+ break;
+ default:
+ rc = 0;
+ }
+ return rc;
+}
+
+/***********************************************************************
+ * ImmGetRegisterWordStyleA (IMM32.@)
+ */
+UINT WINAPI ImmGetRegisterWordStyleA(
+ HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
+{
+ FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetRegisterWordStyleW (IMM32.@)
+ */
+UINT WINAPI ImmGetRegisterWordStyleW(
+ HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
+{
+ FIXME("(%p, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/***********************************************************************
+ * ImmGetStatusWindowPos (IMM32.@)
+ */
+BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
+{
+ FIXME("(%p, %p): stub\n", hIMC, lpptPos);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmGetVirtualKey (IMM32.@)
+ */
+UINT WINAPI ImmGetVirtualKey(HWND hWnd)
+{
+ OSVERSIONINFOA version;
+ FIXME("(%p): stub\n", hWnd);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ GetVersionExA( &version );
+ switch(version.dwPlatformId)
+ {
+ case VER_PLATFORM_WIN32_WINDOWS:
+ return VK_PROCESSKEY;
+ case VER_PLATFORM_WIN32_NT:
+ return 0;
+ default:
+ FIXME("%ld not supported\n",version.dwPlatformId);
+ return VK_PROCESSKEY;
+ }
+}
+
+/***********************************************************************
+ * ImmInstallIMEA (IMM32.@)
+ */
+HKL WINAPI ImmInstallIMEA(
+ LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
+{
+ FIXME("(%s, %s): stub\n",
+ debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return NULL;
+}
+
+/***********************************************************************
+ * ImmInstallIMEW (IMM32.@)
+ */
+HKL WINAPI ImmInstallIMEW(
+ LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
+{
+ FIXME("(%s, %s): stub\n",
+ debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return NULL;
+}
+
+/***********************************************************************
+ * ImmIsIME (IMM32.@)
+ */
+BOOL WINAPI ImmIsIME(HKL hKL)
+{
+ TRACE("(%p): semi-stub\n", hKL);
+ /*
+ * FIXME: Dead key locales will return TRUE here when they should not
+ * There is probably a more proper way to check this.
+ */
+ return (root_context != NULL);
+}
+
+/***********************************************************************
+ * ImmIsUIMessageA (IMM32.@)
+ */
+BOOL WINAPI ImmIsUIMessageA(
+ HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ BOOL rc = FALSE;
+
+ TRACE("(%p, %x, %d, %ld)\n", hWndIME, msg, wParam, lParam);
+ if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
+ (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
+ (msg == WM_MSIME_SERVICE) ||
+ (msg == WM_MSIME_RECONVERTOPTIONS) ||
+ (msg == WM_MSIME_MOUSE) ||
+ (msg == WM_MSIME_RECONVERTREQUEST) ||
+ (msg == WM_MSIME_RECONVERT) ||
+ (msg == WM_MSIME_QUERYPOSITION) ||
+ (msg == WM_MSIME_DOCUMENTFEED))
+
+ {
+ if (!hwndDefault)
+ ImmGetDefaultIMEWnd(NULL);
+
+ if (hWndIME == NULL)
+ PostMessageA(hwndDefault, msg, wParam, lParam);
+
+ rc = TRUE;
+ }
+ return rc;
+}
+
+/***********************************************************************
+ * ImmIsUIMessageW (IMM32.@)
+ */
+BOOL WINAPI ImmIsUIMessageW(
+ HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ BOOL rc = FALSE;
+ TRACE("(%p, %d, %d, %ld): stub\n", hWndIME, msg, wParam, lParam);
+ if ((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
+ (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP) ||
+ (msg == WM_MSIME_SERVICE) ||
+ (msg == WM_MSIME_RECONVERTOPTIONS) ||
+ (msg == WM_MSIME_MOUSE) ||
+ (msg == WM_MSIME_RECONVERTREQUEST) ||
+ (msg == WM_MSIME_RECONVERT) ||
+ (msg == WM_MSIME_QUERYPOSITION) ||
+ (msg == WM_MSIME_DOCUMENTFEED))
+ rc = TRUE;
+ return rc;
+}
+
+/***********************************************************************
+ * ImmNotifyIME (IMM32.@)
+ */
+BOOL WINAPI ImmNotifyIME(
+ HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
+{
+ BOOL rc = FALSE;
+ FIXME("(%p, %ld, %ld, %ld): stub\n",
+ hIMC, dwAction, dwIndex, dwValue);
+
+ if (!root_context)
+ return rc;
+
+ switch(dwAction)
+ {
+ case NI_CHANGECANDIDATELIST:
+ FIXME("%s\n","NI_CHANGECANDIDATELIST");
+ break;
+ case NI_CLOSECANDIDATE:
+ FIXME("%s\n","NI_CLOSECANDIDATE");
+ break;
+ case NI_COMPOSITIONSTR:
+ switch (dwIndex)
+ {
+ case CPS_CANCEL:
+ TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL");
+ if (pX11DRV_ForceXIMReset)
+ pX11DRV_ForceXIMReset(root_context->hwnd);
+ if (root_context->dwCompStringSize)
+ {
+ HeapFree(GetProcessHeap(),0,
+ root_context->CompositionString);
+ root_context->dwCompStringSize = 0;
+ root_context->dwCompStringLength = 0;
+ root_context->CompositionString = NULL;
+ ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
+ GCS_COMPSTR);
+ }
+ rc = TRUE;
+ break;
+ case CPS_COMPLETE:
+ TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_COMPLETE");
+ if (hIMC != (HIMC)FROM_IME && pX11DRV_ForceXIMReset)
+ pX11DRV_ForceXIMReset(root_context->hwnd);
+
+ if (root_context->dwResultStringSize)
+ {
+ HeapFree(GetProcessHeap(),0,root_context->ResultString);
+ root_context->dwResultStringSize = 0;
+ root_context->ResultString = NULL;
+ }
+ if (root_context->dwCompStringLength)
+ {
+ root_context->ResultString = HeapAlloc(
+ GetProcessHeap(), 0, root_context->dwCompStringLength);
+ root_context->dwResultStringSize =
+ root_context->dwCompStringLength;
+
+ memcpy(root_context->ResultString,
+ root_context->CompositionString,
+ root_context->dwCompStringLength);
+
+ HeapFree(GetProcessHeap(),0,
+ root_context->CompositionString);
+
+ root_context->dwCompStringSize = 0;
+ root_context->dwCompStringLength = 0;
+ root_context->CompositionString = NULL;
+ root_context->bRead = FALSE;
+
+ ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
+ GCS_COMPSTR);
+
+ ImmInternalPostIMEMessage(WM_IME_COMPOSITION,
+ root_context->ResultString[0],
+ GCS_RESULTSTR|GCS_RESULTCLAUSE);
+ }
+ break;
+ case CPS_CONVERT:
+ FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_CONVERT");
+ break;
+ case CPS_REVERT:
+ FIXME("%s - %s\n","NI_COMPOSITIONSTR","CPS_REVERT");
+ break;
+ default:
+ ERR("%s - %s (%li)\n","NI_COMPOSITIONSTR","UNKNOWN",dwIndex);
+ break;
+ }
+ break;
+ case NI_IMEMENUSELECTED:
+ FIXME("%s\n", "NI_IMEMENUSELECTED");
+ break;
+ case NI_OPENCANDIDATE:
+ FIXME("%s\n", "NI_OPENCANDIDATE");
+ break;
+ case NI_SELECTCANDIDATESTR:
+ FIXME("%s\n", "NI_SELECTCANDIDATESTR");
+ break;
+ case NI_SETCANDIDATE_PAGESIZE:
+ FIXME("%s\n", "NI_SETCANDIDATE_PAGESIZE");
+ break;
+ case NI_SETCANDIDATE_PAGESTART:
+ FIXME("%s\n", "NI_SETCANDIDATE_PAGESTART");
+ break;
+ default:
+ ERR("Unknown\n");
+ }
+
+ return rc;
+}
+
+/***********************************************************************
+ * ImmRegisterWordA (IMM32.@)
+ */
+BOOL WINAPI ImmRegisterWordA(
+ HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister)
+{
+ FIXME("(%p, %s, %ld, %s): stub\n",
+ hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszRegister)
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmRegisterWordW (IMM32.@)
+ */
+BOOL WINAPI ImmRegisterWordW(
+ HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister)
+{
+ FIXME("(%p, %s, %ld, %s): stub\n",
+ hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszRegister)
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmReleaseContext (IMM32.@)
+ */
+BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
+{
+ FIXME("(%p, %p): stub\n", hWnd, hIMC);
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * ImmSetCandidateWindow (IMM32.@)
+ */
+BOOL WINAPI ImmSetCandidateWindow(
+ HIMC hIMC, LPCANDIDATEFORM lpCandidate)
+{
+ FIXME("(%p, %p): stub\n", hIMC, lpCandidate);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmSetCompositionFontA (IMM32.@)
+ */
+BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
+{
+ InputContextData *data = (InputContextData*)hIMC;
+ TRACE("(%p, %p)\n", hIMC, lplf);
+
+ if (!data)
+ return FALSE;
+
+ memcpy(&data->font,lplf,sizeof(LOGFONTA));
+ MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->font.lfFaceName,
+ LF_FACESIZE);
+
+ SendMessageW(root_context->hwnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONFONT, 0);
+
+ if (data->textfont)
+ {
+ DeleteObject(data->textfont);
+ data->textfont = NULL;
+ }
+
+ data->textfont = CreateFontIndirectW(&data->font);
+ return TRUE;
+}
+
+/***********************************************************************
+ * ImmSetCompositionFontW (IMM32.@)
+ */
+BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
+{
+ InputContextData *data = (InputContextData*)hIMC;
+ TRACE("(%p, %p)\n", hIMC, lplf);
+
+ if (!data)
+ return FALSE;
+
+ memcpy(&data->font,lplf,sizeof(LOGFONTW));
+ SendMessageW(root_context->hwnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONFONT, 0);
+
+ if (data->textfont)
+ {
+ DeleteObject(data->textfont);
+ data->textfont = NULL;
+ }
+ data->textfont = CreateFontIndirectW(&data->font);
+ return TRUE;
+}
+
+/***********************************************************************
+ * ImmSetCompositionStringA (IMM32.@)
+ */
+BOOL WINAPI ImmSetCompositionStringA(
+ HIMC hIMC, DWORD dwIndex,
+ LPCVOID lpComp, DWORD dwCompLen,
+ LPCVOID lpRead, DWORD dwReadLen)
+{
+ DWORD comp_len;
+ DWORD read_len;
+ WCHAR *CompBuffer = NULL;
+ WCHAR *ReadBuffer = NULL;
+ BOOL rc;
+
+ TRACE("(%p, %ld, %p, %ld, %p, %ld): stub\n",
+ hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
+
+ comp_len = MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, NULL, 0);
+ if (comp_len)
+ {
+ CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len);
+ }
+
+ read_len = MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, NULL, 0);
+ if (read_len)
+ {
+ ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len);
+ }
+
+ rc = ImmSetCompositionStringW(hIMC, dwIndex, CompBuffer, comp_len,
+ ReadBuffer, read_len);
+
+ HeapFree(GetProcessHeap(), 0, CompBuffer);
+ HeapFree(GetProcessHeap(), 0, ReadBuffer);
+
+ return rc;
+}
+
+/***********************************************************************
+ * ImmSetCompositionStringW (IMM32.@)
+ */
+BOOL WINAPI ImmSetCompositionStringW(
+ HIMC hIMC, DWORD dwIndex,
+ LPCVOID lpComp, DWORD dwCompLen,
+ LPCVOID lpRead, DWORD dwReadLen)
+{
+ DWORD flags = 0;
+ WCHAR wParam = 0;
+
+ TRACE("(%p, %ld, %p, %ld, %p, %ld): stub\n",
+ hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
+
+
+ if (hIMC != (HIMC)FROM_IME)
+ FIXME("PROBLEM: This only sets the wine level string\n");
+
+ /*
+ * Explanation:
+ * this sets the composition string in the imm32.dll level
+ * of the composition buffer. we cannot manipulate the xim level
+ * buffer, which means that once the xim level buffer changes again
+ * any call to this function from the application will be lost
+ */
+
+ if (lpRead && dwReadLen)
+ FIXME("Reading string unimplemented\n");
+
+ /*
+ * app operating this api to also receive the message from xim
+ */
+
+ if (dwIndex == SCS_SETSTR)
+ {
+ flags = GCS_COMPSTR;
+
+ if (root_context->dwCompStringLength)
+ HeapFree(GetProcessHeap(),0,root_context->CompositionString);
+
+ root_context->dwCompStringLength = dwCompLen;
+ root_context->dwCompStringSize = dwCompLen;
+
+ if (dwCompLen && lpComp)
+ {
+ root_context->CompositionString = HeapAlloc(GetProcessHeap(), 0,
+ dwCompLen);
+ memcpy(root_context->CompositionString,lpComp,dwCompLen);
+
+ wParam = ((const WCHAR*)lpComp)[0];
+ flags |= GCS_COMPCLAUSE | GCS_COMPATTR;
+ }
+ else
+ root_context->CompositionString = NULL;
+
+ }
+
+ UpdateDataInDefaultIMEWindow(hwndDefault);
+
+ ImmInternalPostIMEMessage(WM_IME_COMPOSITION, wParam, flags);
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * ImmSetCompositionWindow (IMM32.@)
+ */
+BOOL WINAPI ImmSetCompositionWindow(
+ HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
+{
+ BOOL reshow = FALSE;
+ InputContextData *data = (InputContextData*)hIMC;
+
+ TRACE("(%p, %p)\n", hIMC, lpCompForm);
+ TRACE("\t%lx, (%li,%li), (%li,%li - %li,%li)\n",lpCompForm->dwStyle,
+ lpCompForm->ptCurrentPos.x, lpCompForm->ptCurrentPos.y, lpCompForm->rcArea.top,
+ lpCompForm->rcArea.left, lpCompForm->rcArea.bottom, lpCompForm->rcArea.right);
+
+ if (!data)
+ return FALSE;
+
+ memcpy(&data->CompForm,lpCompForm,sizeof(COMPOSITIONFORM));
+
+ if (IsWindowVisible(hwndDefault))
+ {
+ reshow = TRUE;
+ ShowWindow(hwndDefault,SW_HIDE);
+ }
+
+ FIXME("STUB\n");
+
+ if (reshow)
+ ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
+
+ SendMessageW(root_context->hwnd, WM_IME_NOTIFY,IMN_SETCOMPOSITIONWINDOW, 0);
+ return TRUE;
+}
+
+/***********************************************************************
+ * ImmSetConversionStatus (IMM32.@)
+ */
+BOOL WINAPI ImmSetConversionStatus(
+ HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
+{
+ FIXME("(%p, %ld, %ld): stub\n",
+ hIMC, fdwConversion, fdwSentence
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmSetOpenStatus (IMM32.@)
+ */
+BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
+{
+ InputContextData *data = (InputContextData*)hIMC;
+ FIXME("Semi-Stub\n");
+
+ if (hIMC == (HIMC)FROM_IME)
+ {
+ if (fOpen)
+ ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION, 0, 0);
+
+ ImmInternalSetOpenStatus(fOpen);
+
+ if (!fOpen)
+ ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0);
+
+ return TRUE;
+ }
+
+ if (!data)
+ return FALSE;
+
+ if (fOpen != data->bInternalState)
+ {
+ if (fOpen == FALSE && pX11DRV_ForceXIMReset)
+ pX11DRV_ForceXIMReset(data->hwnd);
+
+ if (fOpen == FALSE)
+ ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
+ else
+ ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
+
+ ImmInternalSetOpenStatus(fOpen);
+ ImmInternalSetOpenStatus(!fOpen);
+
+ if (data->bOpen == FALSE)
+ ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION,0,0);
+ else
+ ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION,0,0);
+
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/***********************************************************************
+ * ImmSetStatusWindowPos (IMM32.@)
+ */
+BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos)
+{
+ FIXME("(%p, %p): stub\n", hIMC, lpptPos);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmSimulateHotKey (IMM32.@)
+ */
+BOOL WINAPI ImmSimulateHotKey(HWND hWnd, DWORD dwHotKeyID)
+{
+ FIXME("(%p, %ld): stub\n", hWnd, dwHotKeyID);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmUnregisterWordA (IMM32.@)
+ */
+BOOL WINAPI ImmUnregisterWordA(
+ HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister)
+{
+ FIXME("(%p, %s, %ld, %s): stub\n",
+ hKL, debugstr_a(lpszReading), dwStyle, debugstr_a(lpszUnregister)
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * ImmUnregisterWordW (IMM32.@)
+ */
+BOOL WINAPI ImmUnregisterWordW(
+ HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister)
+{
+ FIXME("(%p, %s, %ld, %s): stub\n",
+ hKL, debugstr_w(lpszReading), dwStyle, debugstr_w(lpszUnregister)
+ );
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+
+/*****
+ * Internal functions to help with IME window management
+ */
+static void PaintDefaultIMEWnd(HWND hwnd)
+{
+ PAINTSTRUCT ps;
+ RECT rect;
+ HDC hdc = BeginPaint(hwnd,&ps);
+ GetClientRect(hwnd,&rect);
+
+ if (root_context->dwCompStringLength && root_context->CompositionString)
+ {
+ SIZE size;
+ POINT pt;
+ HFONT oldfont = NULL;
+
+ if (root_context->textfont)
+ oldfont = SelectObject(hdc,root_context->textfont);
+
+ TextOutW(hdc, 0,0,(LPWSTR)root_context->CompositionString,
+ root_context->dwCompStringLength / sizeof(WCHAR));
+
+ GetTextExtentPoint32W(hdc, (LPWSTR)root_context->CompositionString,
+ root_context->dwCompStringLength / sizeof(WCHAR),
+ &size);
+ pt.x = size.cx;
+ pt.y = size.cy;
+ LPtoDP(hdc,&pt,1);
+ rect.left = pt.x;
+
+ if (oldfont)
+ SelectObject(hdc,oldfont);
+ }
+ FillRect(hdc,&rect, (HBRUSH) (COLOR_WINDOW+1));
+ EndPaint(hwnd,&ps);
+}
+
+static void UpdateDataInDefaultIMEWindow(HWND hwnd)
+{
+ RedrawWindow(hwnd,NULL,NULL,RDW_ERASENOW|RDW_INVALIDATE);
+}
+
+/*
+ * The window proc for the default IME window
+ */
+static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
+ LPARAM lParam)
+{
+ LRESULT rc = 0;
+
+ TRACE("Incoming Message 0x%x (0x%08x, 0x%08x)\n", msg, (UINT)wParam,
+ (UINT)lParam);
+
+ switch(msg)
+ {
+ case WM_PAINT:
+ PaintDefaultIMEWnd(hwnd);
+ return FALSE;
+
+ case WM_NCCREATE:
+ return TRUE;
+
+ case WM_CREATE:
+ SetWindowTextA(hwnd,"Wine Ime Active");
+ return TRUE;
+
+ case WM_SETFOCUS:
+ if (wParam)
+ SetFocus((HWND)wParam);
+ else
+ FIXME("Received focus, should never have focus\n");
+ break;
+ case WM_IME_COMPOSITION:
+ TRACE("IME message %s, 0x%x, 0x%x (%i)\n",
+ "WM_IME_COMPOSITION", (UINT)wParam, (UINT)lParam,
+ root_context->bRead);
+ if ((lParam & GCS_RESULTSTR) && (!root_context->bRead))
+ IMM_PostResult(root_context);
+ else
+ UpdateDataInDefaultIMEWindow(hwnd);
+ break;
+ case WM_IME_STARTCOMPOSITION:
+ TRACE("IME message %s, 0x%x, 0x%x\n",
+ "WM_IME_STARTCOMPOSITION", (UINT)wParam, (UINT)lParam);
+ root_context->hwnd = GetFocus();
+ ShowWindow(hwndDefault,SW_SHOWNOACTIVATE);
+ break;
+ case WM_IME_ENDCOMPOSITION:
+ TRACE("IME message %s, 0x%x, 0x%x\n",
+ "WM_IME_ENDCOMPOSITION", (UINT)wParam, (UINT)lParam);
+ ShowWindow(hwndDefault,SW_HIDE);
+ break;
+ case WM_IME_SELECT:
+ TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_SELECT",
+ (UINT)wParam, (UINT)lParam);
+ break;
+ case WM_IME_CONTROL:
+ TRACE("IME message %s, 0x%x, 0x%x\n","WM_IME_CONTROL",
+ (UINT)wParam, (UINT)lParam);
+ rc = 1;
+ break;
+ case WM_IME_NOTIFY:
+ TRACE("!! IME NOTIFY\n");
+ break;
+ default:
+ TRACE("Non-standard message 0x%x\n",msg);
+ }
+ /* check the MSIME messages */
+ if (msg == WM_MSIME_SERVICE)
+ {
+ TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_SERVICE",
+ (UINT)wParam, (UINT)lParam);
+ rc = FALSE;
+ }
+ else if (msg == WM_MSIME_RECONVERTOPTIONS)
+ {
+ TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTOPTIONS",
+ (UINT)wParam, (UINT)lParam);
+ }
+ else if (msg == WM_MSIME_MOUSE)
+ {
+ TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_MOUSE",
+ (UINT)wParam, (UINT)lParam);
+ }
+ else if (msg == WM_MSIME_RECONVERTREQUEST)
+ {
+ TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERTREQUEST",
+ (UINT)wParam, (UINT)lParam);
+ }
+ else if (msg == WM_MSIME_RECONVERT)
+ {
+ TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_RECONVERT",
+ (UINT)wParam, (UINT)lParam);
+ }
+ else if (msg == WM_MSIME_QUERYPOSITION)
+ {
+ TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_QUERYPOSITION",
+ (UINT)wParam, (UINT)lParam);
+ }
+ else if (msg == WM_MSIME_DOCUMENTFEED)
+ {
+ TRACE("IME message %s, 0x%x, 0x%x\n","WM_MSIME_DOCUMENTFEED",
+ (UINT)wParam, (UINT)lParam);
+ }
+ /* DefWndProc if not an IME message */
+ else if (!rc && !((msg >= WM_IME_STARTCOMPOSITION && msg <= WM_IME_KEYLAST) ||
+ (msg >= WM_IME_SETCONTEXT && msg <= WM_IME_KEYUP)))
+ rc = DefWindowProcW(hwnd,msg,wParam,lParam);
+
+ return rc;
+}