mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
[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
This commit is contained in:
parent
570cedf176
commit
d14d3dedcb
3 changed files with 229 additions and 469 deletions
|
@ -9,6 +9,7 @@ spec2def(imm32.dll imm32.spec ADD_IMPORTLIB)
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
candidate.c
|
candidate.c
|
||||||
|
compstr.c
|
||||||
guideline.c
|
guideline.c
|
||||||
ime.c
|
ime.c
|
||||||
imm.c
|
imm.c
|
||||||
|
|
228
dll/win32/imm32/compstr.c
Normal file
228
dll/win32/imm32/compstr.c
Normal file
|
@ -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 <katayama.hirofumi.mz@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
|
@ -476,74 +476,10 @@ BOOL WINAPI ImmActivateLayout(HKL hKL)
|
||||||
return TRUE;
|
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 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 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 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)
|
static VOID APIENTRY Imm32CiceroSetActiveContext(HIMC hIMC, BOOL fActive, HWND hWnd, HKL hKL)
|
||||||
{
|
{
|
||||||
FIXME("We have to do something\n");
|
FIXME("We have to do something\n");
|
||||||
|
@ -1060,297 +996,6 @@ Quit:
|
||||||
return hIMC;
|
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.@)
|
* ImmGetContext (IMM32.@)
|
||||||
*/
|
*/
|
||||||
|
@ -1494,120 +1139,6 @@ BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
|
||||||
return TRUE; // Do nothing. This is correct.
|
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.@)
|
* ImmCreateSoftKeyboard(IMM32.@)
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue