From d14d3dedcbb92496a21c6c55bde0f1ea70ff18a9 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 12 Oct 2021 13:10:01 +0900 Subject: [PATCH] [IMM32] Move Imm(Get|Set)CompositionStringA/W (#4021) - Add new file compstr.c. - Move ImmGetCompositionStringA, ImmGetCompositionStringW, ImmSetCompositionStringA, and ImmSetCompositionStringW functions into compstr.c. - Half-implement ImmGetCompositionStringA/W. CORE-11700 --- dll/win32/imm32/CMakeLists.txt | 1 + dll/win32/imm32/compstr.c | 228 ++++++++++++++++ dll/win32/imm32/imm.c | 469 --------------------------------- 3 files changed, 229 insertions(+), 469 deletions(-) create mode 100644 dll/win32/imm32/compstr.c diff --git a/dll/win32/imm32/CMakeLists.txt b/dll/win32/imm32/CMakeLists.txt index 3597068bdbc..5e67f36f4f5 100644 --- a/dll/win32/imm32/CMakeLists.txt +++ b/dll/win32/imm32/CMakeLists.txt @@ -9,6 +9,7 @@ spec2def(imm32.dll imm32.spec ADD_IMPORTLIB) list(APPEND SOURCE candidate.c + compstr.c guideline.c ime.c imm.c diff --git a/dll/win32/imm32/compstr.c b/dll/win32/imm32/compstr.c new file mode 100644 index 00000000000..4ce157356e3 --- /dev/null +++ b/dll/win32/imm32/compstr.c @@ -0,0 +1,228 @@ +/* + * PROJECT: ReactOS IMM32 + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Implementing composition strings of IMM32 + * COPYRIGHT: Copyright 2020-2021 Katayama Hirofumi MZ + */ + +#include "precomp.h" + +WINE_DEFAULT_DEBUG_CHANNEL(imm); + +LONG APIENTRY +Imm32GetCompStrA(HIMC hIMC, const COMPOSITIONSTRING *pCS, DWORD dwIndex, + LPVOID lpBuf, DWORD dwBufLen, BOOL bAnsiClient, UINT uCodePage) +{ + LONG ret = IMM_ERROR_GENERAL; + + if (bAnsiClient) + { + switch (dwIndex) + { + case GCS_COMPREADSTR: + case GCS_COMPREADATTR: + case GCS_COMPREADCLAUSE: + case GCS_COMPSTR: + case GCS_COMPATTR: + case GCS_COMPCLAUSE: + case GCS_CURSORPOS: + case GCS_DELTASTART: + case GCS_RESULTREADSTR: + case GCS_RESULTREADCLAUSE: + case GCS_RESULTSTR: + case GCS_RESULTCLAUSE: + default: + FIXME("TODO:\n"); + break; + } + } + else /* !bAnsiClient */ + { + switch (dwIndex) + { + case GCS_COMPREADSTR: + case GCS_COMPREADATTR: + case GCS_COMPREADCLAUSE: + case GCS_COMPSTR: + case GCS_COMPATTR: + case GCS_COMPCLAUSE: + case GCS_CURSORPOS: + case GCS_DELTASTART: + case GCS_RESULTREADSTR: + case GCS_RESULTREADCLAUSE: + case GCS_RESULTSTR: + case GCS_RESULTCLAUSE: + default: + FIXME("TODO:\n"); + break; + } + } + + return ret; +} + +LONG APIENTRY +Imm32GetCompStrW(HIMC hIMC, const COMPOSITIONSTRING *pCS, DWORD dwIndex, + LPVOID lpBuf, DWORD dwBufLen, BOOL bAnsiClient, UINT uCodePage) +{ + LONG ret = IMM_ERROR_GENERAL; + + if (bAnsiClient) + { + switch (dwIndex) + { + case GCS_COMPREADSTR: + case GCS_COMPREADATTR: + case GCS_COMPREADCLAUSE: + case GCS_COMPSTR: + case GCS_COMPATTR: + case GCS_COMPCLAUSE: + case GCS_CURSORPOS: + case GCS_DELTASTART: + case GCS_RESULTREADSTR: + case GCS_RESULTREADCLAUSE: + case GCS_RESULTSTR: + case GCS_RESULTCLAUSE: + default: + FIXME("TODO:\n"); + break; + } + } + else /* !bAnsiClient */ + { + switch (dwIndex) + { + case GCS_COMPREADSTR: + case GCS_COMPREADATTR: + case GCS_COMPREADCLAUSE: + case GCS_COMPSTR: + case GCS_COMPATTR: + case GCS_COMPCLAUSE: + case GCS_CURSORPOS: + case GCS_DELTASTART: + case GCS_RESULTREADSTR: + case GCS_RESULTREADCLAUSE: + case GCS_RESULTSTR: + case GCS_RESULTCLAUSE: + default: + FIXME("TODO:\n"); + break; + } + } + + return ret; +} + +BOOL APIENTRY +Imm32SetCompositionStringAW(HIMC hIMC, DWORD dwIndex, LPCVOID lpComp, DWORD dwCompLen, + LPCVOID lpRead, DWORD dwReadLen, BOOL bAnsi) +{ + FIXME("TODO:\n"); + return FALSE; +} + +/*********************************************************************** + * ImmGetCompositionStringA (IMM32.@) + */ +LONG WINAPI ImmGetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen) +{ + LONG ret = 0; + LPINPUTCONTEXT pIC; + PCLIENTIMC pClientImc; + LPCOMPOSITIONSTRING pCS; + BOOL bAnsiClient; + + TRACE("(%p, %lu, %p, %lu)\n", hIMC, dwIndex, lpBuf, dwBufLen); + + if (dwBufLen && !lpBuf) + return 0; + + pClientImc = ImmLockClientImc(hIMC); + if (!pClientImc) + return 0; + + bAnsiClient = !(pClientImc->dwFlags & CLIENTIMC_WIDE); + ImmUnlockClientImc(pClientImc); + + pIC = ImmLockIMC(hIMC); + if (!pIC) + return 0; + + pCS = ImmLockIMCC(pIC->hCompStr); + if (!pCS) + { + ImmUnlockIMC(hIMC); + return 0; + } + + ret = Imm32GetCompStrA(hIMC, pCS, dwIndex, lpBuf, dwBufLen, bAnsiClient, CP_ACP); + ImmUnlockIMCC(pIC->hCompStr); + ImmUnlockIMC(hIMC); + return ret; +} + +/*********************************************************************** + * ImmGetCompositionStringW (IMM32.@) + */ +LONG WINAPI ImmGetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen) +{ + LONG ret = 0; + LPINPUTCONTEXT pIC; + PCLIENTIMC pClientImc; + LPCOMPOSITIONSTRING pCS; + BOOL bAnsiClient; + + TRACE("(%p, %lu, %p, %lu)\n", hIMC, dwIndex, lpBuf, dwBufLen); + + if (dwBufLen && !lpBuf) + return 0; + + pClientImc = ImmLockClientImc(hIMC); + if (!pClientImc) + return 0; + + bAnsiClient = !(pClientImc->dwFlags & CLIENTIMC_WIDE); + ImmUnlockClientImc(pClientImc); + + pIC = ImmLockIMC(hIMC); + if (!pIC) + return 0; + + pCS = ImmLockIMCC(pIC->hCompStr); + if (!pCS) + { + ImmUnlockIMC(hIMC); + return 0; + } + + ret = Imm32GetCompStrW(hIMC, pCS, dwIndex, lpBuf, dwBufLen, bAnsiClient, CP_ACP); + ImmUnlockIMCC(pIC->hCompStr); + ImmUnlockIMC(hIMC); + return ret; +} + +/*********************************************************************** + * ImmSetCompositionStringA (IMM32.@) + */ +BOOL WINAPI +ImmSetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPCVOID lpComp, DWORD dwCompLen, + LPCVOID lpRead, DWORD dwReadLen) +{ + TRACE("(%p, %lu, %p, %lu, %p, %lu)\n", + hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen); + return Imm32SetCompositionStringAW(hIMC, dwIndex, lpComp, dwCompLen, + lpRead, dwReadLen, TRUE); +} + +/*********************************************************************** + * ImmSetCompositionStringW (IMM32.@) + */ +BOOL WINAPI +ImmSetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPCVOID lpComp, DWORD dwCompLen, + LPCVOID lpRead, DWORD dwReadLen) +{ + TRACE("(%p, %lu, %p, %lu, %p, %lu)\n", + hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen); + return Imm32SetCompositionStringAW(hIMC, dwIndex, lpComp, dwCompLen, + lpRead, dwReadLen, FALSE); +} diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c index 69cd4281a55..f4fa021b619 100644 --- a/dll/win32/imm32/imm.c +++ b/dll/win32/imm32/imm.c @@ -476,74 +476,10 @@ BOOL WINAPI ImmActivateLayout(HKL hKL) return TRUE; } -typedef struct _tagImmHkl -{ - struct list entry; - HKL hkl; - HMODULE hIME; - IMEINFO imeInfo; - WCHAR imeClassName[17]; /* 16 character max */ - ULONG uSelected; - HWND UIWnd; - - /* Function Pointers */ - BOOL (WINAPI *pImeInquire)(IMEINFO *, WCHAR *, const WCHAR *); - BOOL (WINAPI *pImeConfigure)(HKL, HWND, DWORD, void *); - BOOL (WINAPI *pImeDestroy)(UINT); - LRESULT (WINAPI *pImeEscape)(HIMC, UINT, void *); - BOOL (WINAPI *pImeSelect)(HIMC, BOOL); - BOOL (WINAPI *pImeSetActiveContext)(HIMC, BOOL); - UINT (WINAPI *pImeToAsciiEx)(UINT, UINT, const BYTE *, DWORD *, UINT, HIMC); - BOOL (WINAPI *pNotifyIME)(HIMC, DWORD, DWORD, DWORD); - BOOL (WINAPI *pImeRegisterWord)(const WCHAR *, DWORD, const WCHAR *); - BOOL (WINAPI *pImeUnregisterWord)(const WCHAR *, DWORD, const WCHAR *); - UINT (WINAPI *pImeEnumRegisterWord)(REGISTERWORDENUMPROCW, const WCHAR *, DWORD, const WCHAR *, void *); - BOOL (WINAPI *pImeSetCompositionString)(HIMC, DWORD, const void *, DWORD, const void *, DWORD); - DWORD (WINAPI *pImeConversionList)(HIMC, const WCHAR *, CANDIDATELIST *, DWORD, UINT); - BOOL (WINAPI *pImeProcessKey)(HIMC, UINT, LPARAM, const BYTE *); - UINT (WINAPI *pImeGetRegisterWordStyle)(UINT, STYLEBUFW *); - DWORD (WINAPI *pImeGetImeMenuItems)(HIMC, DWORD, DWORD, IMEMENUITEMINFOW *, IMEMENUITEMINFOW *, DWORD); -} ImmHkl; - -typedef struct tagInputContextData -{ - DWORD dwLock; - INPUTCONTEXT IMC; - DWORD threadID; - - ImmHkl *immKbd; - UINT lastVK; - BOOL threadDefault; - DWORD magic; -} InputContextData; - -#define WINE_IMC_VALID_MAGIC 0x56434D49 - -static const WCHAR szwWineIMCProperty[] = {'W','i','n','e','I','m','m','H','I','M','C','P','r','o','p','e','r','t','y',0}; static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0}; static const WCHAR szLayoutTextW[] = {'L','a','y','o','u','t',' ','T','e','x','t',0}; static const WCHAR szImeRegFmt[] = {'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','s','\\','%','0','8','l','x',0}; -static inline BOOL is_himc_ime_unicode(const InputContextData *data) -{ - return !!(data->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE); -} - -static InputContextData* get_imc_data(HIMC hIMC) -{ - InputContextData *data = (InputContextData *)hIMC; - - if (hIMC == NULL) - return NULL; - - if(IsBadReadPtr(data, sizeof(InputContextData)) || data->magic != WINE_IMC_VALID_MAGIC) - { - SetLastError(ERROR_INVALID_HANDLE); - return NULL; - } - return data; -} - static VOID APIENTRY Imm32CiceroSetActiveContext(HIMC hIMC, BOOL fActive, HWND hWnd, HKL hKL) { FIXME("We have to do something\n"); @@ -1060,297 +996,6 @@ Quit: return hIMC; } - -/* Helpers for the GetCompositionString functions */ - -/* Source encoding is defined by context, source length is always given in respective characters. Destination buffer - length is always in bytes. */ -static INT -CopyCompStringIMEtoClient(const InputContextData *data, const void *src, INT src_len, void *dst, - INT dst_len, BOOL unicode) -{ - int char_size = unicode ? sizeof(WCHAR) : sizeof(char); - INT ret; - - if (is_himc_ime_unicode(data) ^ unicode) - { - if (unicode) - ret = MultiByteToWideChar(CP_ACP, 0, src, src_len, dst, dst_len / sizeof(WCHAR)); - else - ret = WideCharToMultiByte(CP_ACP, 0, src, src_len, dst, dst_len, NULL, NULL); - ret *= char_size; - } - else - { - if (dst_len) - { - ret = min(src_len * char_size, dst_len); - memcpy(dst, src, ret); - } - else - ret = src_len * char_size; - } - - return ret; -} - -/* Composition string encoding is defined by context, returned attributes correspond to string, converted according to - passed mode. String length is in characters, attributes are in byte arrays. */ -static INT -CopyCompAttrIMEtoClient(const InputContextData *data, const BYTE *src, INT src_len, const void *comp_string, - INT str_len, BYTE *dst, INT dst_len, BOOL unicode) -{ - union - { - const void *str; - const WCHAR *strW; - const char *strA; - } string; - INT rc; - - string.str = comp_string; - - if (is_himc_ime_unicode(data) && !unicode) - { - rc = WideCharToMultiByte(CP_ACP, 0, string.strW, str_len, NULL, 0, NULL, NULL); - if (dst_len) - { - int i, j = 0, k = 0; - - if (rc < dst_len) - dst_len = rc; - for (i = 0; i < str_len; ++i) - { - int len; - - len = WideCharToMultiByte(CP_ACP, 0, string.strW + i, 1, NULL, 0, NULL, NULL); - for (; len > 0; --len) - { - dst[j++] = src[k]; - - if (j >= dst_len) - goto end; - } - ++k; - } - end: - rc = j; - } - } - else if (!is_himc_ime_unicode(data) && unicode) - { - rc = MultiByteToWideChar(CP_ACP, 0, string.strA, str_len, NULL, 0); - if (dst_len) - { - int i, j = 0; - - if (rc < dst_len) - dst_len = rc; - for (i = 0; i < str_len; ++i) - { - if (IsDBCSLeadByte(string.strA[i])) - continue; - - dst[j++] = src[i]; - - if (j >= dst_len) - break; - } - rc = j; - } - } - else - { - memcpy(dst, src, min(src_len, dst_len)); - rc = src_len; - } - - return rc; -} - -static INT -CopyCompClauseIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, - LPBYTE target, INT tlen, BOOL unicode ) -{ - INT rc; - - if (is_himc_ime_unicode(data) && !unicode) - { - if (tlen) - { - int i; - - if (slen < tlen) - tlen = slen; - tlen /= sizeof (DWORD); - for (i = 0; i < tlen; ++i) - { - ((DWORD *)target)[i] = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, - ((DWORD *)source)[i], - NULL, 0, - NULL, NULL); - } - rc = sizeof (DWORD) * i; - } - else - rc = slen; - } - else if (!is_himc_ime_unicode(data) && unicode) - { - if (tlen) - { - int i; - - if (slen < tlen) - tlen = slen; - tlen /= sizeof (DWORD); - for (i = 0; i < tlen; ++i) - { - ((DWORD *)target)[i] = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, - ((DWORD *)source)[i], - NULL, 0); - } - rc = sizeof (DWORD) * i; - } - else - rc = slen; - } - else - { - memcpy( target, source, min(slen,tlen)); - rc = slen; - } - - return rc; -} - -static INT -CopyCompOffsetIMEtoClient(InputContextData *data, DWORD offset, LPBYTE ssource, BOOL unicode) -{ - int rc; - - if (is_himc_ime_unicode(data) && !unicode) - { - rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, offset, NULL, 0, NULL, NULL); - } - else if (!is_himc_ime_unicode(data) && unicode) - { - rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, offset, NULL, 0); - } - else - rc = offset; - - return rc; -} - -static LONG -ImmGetCompositionStringT(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, - DWORD dwBufLen, BOOL unicode) -{ - LONG rc = 0; - InputContextData *data = get_imc_data(hIMC); - LPCOMPOSITIONSTRING compstr; - LPBYTE compdata; - - TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen); - - if (!data) - return FALSE; - - if (!data->IMC.hCompStr) - return FALSE; - - compdata = ImmLockIMCC(data->IMC.hCompStr); - compstr = (LPCOMPOSITIONSTRING)compdata; - - switch (dwIndex) - { - case GCS_RESULTSTR: - TRACE("GCS_RESULTSTR\n"); - rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwResultStrOffset, compstr->dwResultStrLen, lpBuf, dwBufLen, unicode); - break; - case GCS_COMPSTR: - TRACE("GCS_COMPSTR\n"); - rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen, lpBuf, dwBufLen, unicode); - break; - case GCS_COMPATTR: - TRACE("GCS_COMPATTR\n"); - rc = CopyCompAttrIMEtoClient(data, compdata + compstr->dwCompAttrOffset, compstr->dwCompAttrLen, - compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen, - lpBuf, dwBufLen, unicode); - break; - case GCS_COMPCLAUSE: - TRACE("GCS_COMPCLAUSE\n"); - rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwCompClauseOffset,compstr->dwCompClauseLen, - compdata + compstr->dwCompStrOffset, - lpBuf, dwBufLen, unicode); - break; - case GCS_RESULTCLAUSE: - TRACE("GCS_RESULTCLAUSE\n"); - rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultClauseOffset,compstr->dwResultClauseLen, - compdata + compstr->dwResultStrOffset, - lpBuf, dwBufLen, unicode); - break; - case GCS_RESULTREADSTR: - TRACE("GCS_RESULTREADSTR\n"); - rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwResultReadStrOffset, compstr->dwResultReadStrLen, lpBuf, dwBufLen, unicode); - break; - case GCS_RESULTREADCLAUSE: - TRACE("GCS_RESULTREADCLAUSE\n"); - rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultReadClauseOffset,compstr->dwResultReadClauseLen, - compdata + compstr->dwResultStrOffset, - lpBuf, dwBufLen, unicode); - break; - case GCS_COMPREADSTR: - TRACE("GCS_COMPREADSTR\n"); - rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwCompReadStrOffset, compstr->dwCompReadStrLen, lpBuf, dwBufLen, unicode); - break; - case GCS_COMPREADATTR: - TRACE("GCS_COMPREADATTR\n"); - rc = CopyCompAttrIMEtoClient(data, compdata + compstr->dwCompReadAttrOffset, compstr->dwCompReadAttrLen, - compdata + compstr->dwCompReadStrOffset, compstr->dwCompReadStrLen, - lpBuf, dwBufLen, unicode); - break; - case GCS_COMPREADCLAUSE: - TRACE("GCS_COMPREADCLAUSE\n"); - rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwCompReadClauseOffset,compstr->dwCompReadClauseLen, - compdata + compstr->dwCompStrOffset, - lpBuf, dwBufLen, unicode); - break; - case GCS_CURSORPOS: - TRACE("GCS_CURSORPOS\n"); - rc = CopyCompOffsetIMEtoClient(data, compstr->dwCursorPos, compdata + compstr->dwCompStrOffset, unicode); - break; - case GCS_DELTASTART: - TRACE("GCS_DELTASTART\n"); - rc = CopyCompOffsetIMEtoClient(data, compstr->dwDeltaStart, compdata + compstr->dwCompStrOffset, unicode); - break; - default: - FIXME("Unhandled index 0x%x\n",dwIndex); - break; - } - - ImmUnlockIMCC(data->IMC.hCompStr); - - return rc; -} - -/*********************************************************************** - * ImmGetCompositionStringA (IMM32.@) - */ -LONG WINAPI ImmGetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen) -{ - return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, FALSE); -} - -/*********************************************************************** - * ImmGetCompositionStringW (IMM32.@) - */ -LONG WINAPI ImmGetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen) -{ - return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, TRUE); -} - /*********************************************************************** * ImmGetContext (IMM32.@) */ @@ -1494,120 +1139,6 @@ BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC) return TRUE; // Do nothing. This is correct. } -/*********************************************************************** - * 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; - InputContextData *data = get_imc_data(hIMC); - - TRACE("(%p, %d, %p, %d, %p, %d):\n", - hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen); - - if (!data) - return FALSE; - - if (!(dwIndex == SCS_SETSTR || - dwIndex == SCS_CHANGEATTR || - dwIndex == SCS_CHANGECLAUSE || - dwIndex == SCS_SETRECONVERTSTRING || - dwIndex == SCS_QUERYRECONVERTSTRING)) - return FALSE; - - if (!is_himc_ime_unicode(data)) - return data->immKbd->pImeSetCompositionString(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 comp_len; - DWORD read_len; - CHAR *CompBuffer = NULL; - CHAR *ReadBuffer = NULL; - BOOL rc; - InputContextData *data = get_imc_data(hIMC); - - TRACE("(%p, %d, %p, %d, %p, %d):\n", - hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen); - - if (!data) - return FALSE; - - if (!(dwIndex == SCS_SETSTR || - dwIndex == SCS_CHANGEATTR || - dwIndex == SCS_CHANGECLAUSE || - dwIndex == SCS_SETRECONVERTSTRING || - dwIndex == SCS_QUERYRECONVERTSTRING)) - return FALSE; - - if (is_himc_ime_unicode(data)) - return data->immKbd->pImeSetCompositionString(hIMC, dwIndex, lpComp, - dwCompLen, lpRead, dwReadLen); - - comp_len = WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, NULL, 0, NULL, - NULL); - if (comp_len) - { - CompBuffer = HeapAlloc(GetProcessHeap(),0,comp_len); - WideCharToMultiByte(CP_ACP, 0, lpComp, dwCompLen, CompBuffer, comp_len, - NULL, NULL); - } - - read_len = WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, NULL, 0, NULL, - NULL); - if (read_len) - { - ReadBuffer = HeapAlloc(GetProcessHeap(),0,read_len); - WideCharToMultiByte(CP_ACP, 0, lpRead, dwReadLen, ReadBuffer, read_len, - NULL, NULL); - } - - rc = ImmSetCompositionStringA(hIMC, dwIndex, CompBuffer, comp_len, - ReadBuffer, read_len); - - HeapFree(GetProcessHeap(), 0, CompBuffer); - HeapFree(GetProcessHeap(), 0, ReadBuffer); - - return rc; -} - /*********************************************************************** * ImmCreateSoftKeyboard(IMM32.@) */