imm32: Implement helper functions for copying CompositionString data out of the IME. Standardize ImmGetCompositionStringA/W to use a common T function.
This commit is contained in:
parent
4b9bc9816b
commit
0739200c75
317
dlls/imm32/imm.c
317
dlls/imm32/imm.c
|
@ -985,15 +985,54 @@ BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* ImmGetCompositionStringA (IMM32.@)
|
/* Helpers for the GetCompositionString functions */
|
||||||
*/
|
|
||||||
LONG WINAPI ImmGetCompositionStringA(
|
static INT CopyCompStringIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE target, INT tlen,
|
||||||
HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
|
BOOL unicode )
|
||||||
|
{
|
||||||
|
INT rc;
|
||||||
|
|
||||||
|
if (is_himc_ime_unicode(data) && !unicode)
|
||||||
|
rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)source, slen, (LPSTR)target, tlen, NULL, NULL);
|
||||||
|
else if (!is_himc_ime_unicode(data) && unicode)
|
||||||
|
rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)source, slen, (LPWSTR)target, tlen) * sizeof(WCHAR);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int dlen = (unicode)?sizeof(WCHAR):sizeof(CHAR);
|
||||||
|
memcpy( target, source, min(slen,tlen)*dlen);
|
||||||
|
rc = slen*dlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT CopyCompAttrIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, INT sslen,
|
||||||
|
LPBYTE target, INT tlen, BOOL unicode )
|
||||||
|
{
|
||||||
|
if ( target && source && tlen >= slen)
|
||||||
|
memcpy( target , source , slen);
|
||||||
|
|
||||||
|
return slen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT CopyCompClauseIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, INT sslen,
|
||||||
|
LPBYTE target, INT tlen, BOOL unicode )
|
||||||
|
{
|
||||||
|
if ( target && source && tlen >= slen)
|
||||||
|
memcpy( target , source , slen);
|
||||||
|
|
||||||
|
return slen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT CopyCompOffsetIMEtoClient(InputContextData *data, DWORD offset, LPBYTE ssource, BOOL unicode)
|
||||||
|
{
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LONG ImmGetCompositionStringT( HIMC hIMC, DWORD dwIndex, LPVOID lpBuf,
|
||||||
|
DWORD dwBufLen, BOOL unicode)
|
||||||
{
|
{
|
||||||
BOOL isString = FALSE;
|
|
||||||
LPBYTE buffer = NULL;
|
|
||||||
CHAR *buf = NULL;
|
|
||||||
LONG rc = 0;
|
LONG rc = 0;
|
||||||
InputContextData *data = (InputContextData*)hIMC;
|
InputContextData *data = (InputContextData*)hIMC;
|
||||||
LPCOMPOSITIONSTRING compstr;
|
LPCOMPOSITIONSTRING compstr;
|
||||||
|
@ -1013,120 +1052,85 @@ LONG WINAPI ImmGetCompositionStringA(
|
||||||
switch (dwIndex)
|
switch (dwIndex)
|
||||||
{
|
{
|
||||||
case GCS_RESULTSTR:
|
case GCS_RESULTSTR:
|
||||||
if (compstr->dwResultStrLen > 0 && compstr->dwResultStrOffset > 0)
|
TRACE("GCS_RESULTSTR\n");
|
||||||
{
|
rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwResultStrOffset, compstr->dwResultStrLen, lpBuf, dwBufLen, unicode);
|
||||||
isString = TRUE;
|
|
||||||
buffer = compdata + compstr->dwResultStrOffset;
|
|
||||||
rc = compstr->dwResultStrLen;
|
|
||||||
TRACE("GCS_RESULTSTR %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GCS_COMPSTR:
|
case GCS_COMPSTR:
|
||||||
if (compstr->dwCompStrLen > 0 && compstr->dwCompStrOffset > 0)
|
TRACE("GCS_COMPSTR\n");
|
||||||
{
|
rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen, lpBuf, dwBufLen, unicode);
|
||||||
isString = TRUE;
|
|
||||||
buffer = compdata + compstr->dwCompStrOffset;
|
|
||||||
rc = compstr->dwCompStrLen;
|
|
||||||
TRACE("GCS_COMPSTR %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GCS_COMPATTR:
|
case GCS_COMPATTR:
|
||||||
if (compstr->dwCompAttrLen > 0 && compstr->dwCompAttrOffset > 0)
|
TRACE("GCS_COMPATTR\n");
|
||||||
{
|
rc = CopyCompAttrIMEtoClient(data, compdata + compstr->dwCompAttrOffset, compstr->dwCompAttrLen,
|
||||||
buffer = compdata + compstr->dwCompAttrOffset;
|
compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen,
|
||||||
rc = compstr->dwCompAttrLen;
|
lpBuf, dwBufLen, unicode);
|
||||||
TRACE("GCS_COMPATTR %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GCS_COMPCLAUSE:
|
case GCS_COMPCLAUSE:
|
||||||
if (compstr->dwCompClauseLen > 0 && compstr->dwCompClauseOffset > 0)
|
TRACE("GCS_COMPCLAUSE\n");
|
||||||
{
|
rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwCompClauseOffset,compstr->dwCompClauseLen,
|
||||||
buffer = compdata + compstr->dwCompClauseOffset;
|
compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen,
|
||||||
rc = compstr->dwCompClauseLen;
|
lpBuf, dwBufLen, unicode);
|
||||||
TRACE("GCS_COMPCLAUSE %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GCS_RESULTCLAUSE:
|
case GCS_RESULTCLAUSE:
|
||||||
if (compstr->dwResultClauseLen > 0 && compstr->dwResultClauseOffset > 0)
|
TRACE("GCS_RESULTCLAUSE\n");
|
||||||
{
|
rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultClauseOffset,compstr->dwResultClauseLen,
|
||||||
buffer = compdata + compstr->dwResultClauseOffset;
|
compdata + compstr->dwResultStrOffset, compstr->dwResultStrLen,
|
||||||
rc = compstr->dwResultClauseLen;
|
lpBuf, dwBufLen, unicode);
|
||||||
TRACE("GCS_RESULTCLAUSE %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GCS_RESULTREADSTR:
|
case GCS_RESULTREADSTR:
|
||||||
if (compstr->dwResultReadStrLen > 0 && compstr->dwResultReadStrOffset > 0)
|
TRACE("GCS_RESULTREADSTR\n");
|
||||||
{
|
rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwResultReadStrOffset, compstr->dwResultReadStrLen, lpBuf, dwBufLen, unicode);
|
||||||
isString = TRUE;
|
|
||||||
buffer = compdata + compstr->dwResultReadStrOffset;
|
|
||||||
rc = compstr->dwResultReadStrLen;
|
|
||||||
TRACE("GCS_RESULTREADSTR %p %i\n",buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GCS_RESULTREADCLAUSE:
|
case GCS_RESULTREADCLAUSE:
|
||||||
if (compstr->dwResultReadClauseLen > 0 && compstr->dwResultReadClauseOffset > 0)
|
TRACE("GCS_RESULTREADCLAUSE\n");
|
||||||
{
|
rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwResultReadClauseOffset,compstr->dwResultReadClauseLen,
|
||||||
buffer = compdata + compstr->dwResultReadClauseOffset;
|
compdata + compstr->dwResultStrOffset, compstr->dwResultStrLen,
|
||||||
rc = compstr->dwResultReadClauseLen;
|
lpBuf, dwBufLen, unicode);
|
||||||
TRACE("GCS_RESULTREADCLAUSE %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GCS_COMPREADSTR:
|
case GCS_COMPREADSTR:
|
||||||
if (compstr->dwCompReadStrLen > 0 && compstr->dwCompReadStrOffset > 0)
|
TRACE("GCS_COMPREADSTR\n");
|
||||||
{
|
rc = CopyCompStringIMEtoClient(data, compdata + compstr->dwCompReadStrOffset, compstr->dwCompReadStrLen, lpBuf, dwBufLen, unicode);
|
||||||
isString = TRUE;
|
|
||||||
buffer = compdata + compstr->dwCompReadStrOffset;
|
|
||||||
rc = compstr->dwCompReadStrLen;
|
|
||||||
TRACE("GCS_COMPREADSTR %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GCS_COMPREADATTR:
|
case GCS_COMPREADATTR:
|
||||||
if (compstr->dwCompReadAttrLen > 0 && compstr->dwCompReadAttrOffset > 0)
|
TRACE("GCS_COMPREADATTR\n");
|
||||||
{
|
rc = CopyCompAttrIMEtoClient(data, compdata + compstr->dwCompReadAttrOffset, compstr->dwCompReadAttrLen,
|
||||||
buffer = compdata + compstr->dwCompReadAttrOffset;
|
compdata + compstr->dwCompReadStrOffset, compstr->dwCompReadStrLen,
|
||||||
rc = compstr->dwCompReadAttrLen;
|
lpBuf, dwBufLen, unicode);
|
||||||
TRACE("GCS_COMPREADATTR %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GCS_COMPREADCLAUSE:
|
case GCS_COMPREADCLAUSE:
|
||||||
if (compstr->dwCompReadClauseLen > 0 && compstr->dwCompReadClauseOffset > 0)
|
TRACE("GCS_COMPREADCLAUSE\n");
|
||||||
{
|
rc = CopyCompClauseIMEtoClient(data, compdata + compstr->dwCompReadClauseOffset,compstr->dwCompReadClauseLen,
|
||||||
buffer = compdata + compstr->dwCompReadClauseOffset;
|
compdata + compstr->dwCompStrOffset, compstr->dwCompStrLen,
|
||||||
rc = compstr->dwCompReadClauseLen;
|
lpBuf, dwBufLen, unicode);
|
||||||
TRACE("GCS_COMPREADCLAUSE %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GCS_CURSORPOS:
|
case GCS_CURSORPOS:
|
||||||
TRACE("GCS_CURSORPOS\n");
|
TRACE("GCS_CURSORPOS\n");
|
||||||
rc = compstr->dwCursorPos;
|
rc = CopyCompOffsetIMEtoClient(data, compstr->dwCursorPos, compdata + compstr->dwCompStrOffset, unicode);
|
||||||
break;
|
break;
|
||||||
case GCS_DELTASTART:
|
case GCS_DELTASTART:
|
||||||
TRACE("GCS_DELTASTART\n");
|
TRACE("GCS_DELTASTART\n");
|
||||||
rc = compstr->dwDeltaStart;
|
rc = CopyCompOffsetIMEtoClient(data, compstr->dwDeltaStart, compdata + compstr->dwCompStrOffset, unicode);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FIXME("Unhandled index 0x%x\n",dwIndex);
|
FIXME("Unhandled index 0x%x\n",dwIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isString && buffer && is_himc_ime_unicode(data))
|
|
||||||
{
|
|
||||||
INT len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)buffer, rc, NULL, 0, NULL, NULL);
|
|
||||||
buf = HeapAlloc( GetProcessHeap(), 0, len );
|
|
||||||
if ( buf )
|
|
||||||
rc = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)buffer, rc, buf, len, NULL, NULL);
|
|
||||||
buffer = (LPBYTE)buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( lpBuf && buffer && dwBufLen >= rc)
|
|
||||||
memcpy(lpBuf, buffer, rc);
|
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, buf );
|
|
||||||
ImmUnlockIMCC(data->IMC.hCompStr);
|
ImmUnlockIMCC(data->IMC.hCompStr);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* ImmGetCompositionStringA (IMM32.@)
|
||||||
|
*/
|
||||||
|
LONG WINAPI ImmGetCompositionStringA(
|
||||||
|
HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
|
||||||
|
{
|
||||||
|
return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* ImmGetCompositionStringW (IMM32.@)
|
* ImmGetCompositionStringW (IMM32.@)
|
||||||
*/
|
*/
|
||||||
|
@ -1134,144 +1138,7 @@ LONG WINAPI ImmGetCompositionStringW(
|
||||||
HIMC hIMC, DWORD dwIndex,
|
HIMC hIMC, DWORD dwIndex,
|
||||||
LPVOID lpBuf, DWORD dwBufLen)
|
LPVOID lpBuf, DWORD dwBufLen)
|
||||||
{
|
{
|
||||||
BOOL isString = FALSE;
|
return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, TRUE);
|
||||||
LPBYTE buffer = NULL;
|
|
||||||
WCHAR *buf = NULL;
|
|
||||||
LONG rc = 0;
|
|
||||||
InputContextData *data = (InputContextData*)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:
|
|
||||||
if (compstr->dwResultStrLen > 0 && compstr->dwResultStrOffset > 0)
|
|
||||||
{
|
|
||||||
isString = TRUE;
|
|
||||||
buffer = compdata + compstr->dwResultStrOffset;
|
|
||||||
rc = compstr->dwResultStrLen;
|
|
||||||
TRACE("GCS_RESULTSTR %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GCS_RESULTREADSTR:
|
|
||||||
if (compstr->dwResultReadStrLen > 0 && compstr->dwResultReadStrOffset > 0)
|
|
||||||
{
|
|
||||||
isString = TRUE;
|
|
||||||
buffer = compdata + compstr->dwResultReadStrOffset;
|
|
||||||
rc = compstr->dwResultReadStrLen;
|
|
||||||
TRACE("GCS_RESULTREADSTR %p %i\n",buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GCS_COMPSTR:
|
|
||||||
if (compstr->dwCompStrLen > 0 && compstr->dwCompStrOffset > 0)
|
|
||||||
{
|
|
||||||
isString = TRUE;
|
|
||||||
buffer = compdata + compstr->dwCompStrOffset;
|
|
||||||
rc = compstr->dwCompStrLen;
|
|
||||||
TRACE("GCS_COMPSTR %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GCS_COMPATTR:
|
|
||||||
if (compstr->dwCompAttrLen > 0 && compstr->dwCompAttrOffset > 0)
|
|
||||||
{
|
|
||||||
buffer = compdata + compstr->dwCompAttrOffset;
|
|
||||||
rc = compstr->dwCompAttrLen;
|
|
||||||
TRACE("GCS_COMPATTR %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GCS_COMPCLAUSE:
|
|
||||||
if (compstr->dwCompClauseLen > 0 && compstr->dwCompClauseOffset > 0)
|
|
||||||
{
|
|
||||||
buffer = compdata + compstr->dwCompClauseOffset;
|
|
||||||
rc = compstr->dwCompClauseLen;
|
|
||||||
TRACE("GCS_COMPCLAUSE %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GCS_COMPREADSTR:
|
|
||||||
if (compstr->dwCompReadStrLen > 0 && compstr->dwCompReadStrOffset > 0)
|
|
||||||
{
|
|
||||||
isString = TRUE;
|
|
||||||
buffer = compdata + compstr->dwCompReadStrOffset;
|
|
||||||
rc = compstr->dwCompReadStrLen;
|
|
||||||
TRACE("GCS_COMPREADSTR %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GCS_COMPREADATTR:
|
|
||||||
if (compstr->dwCompReadAttrLen > 0 && compstr->dwCompReadAttrOffset > 0)
|
|
||||||
{
|
|
||||||
buffer = compdata + compstr->dwCompReadAttrOffset;
|
|
||||||
rc = compstr->dwCompReadAttrLen;
|
|
||||||
TRACE("GCS_COMPREADATTR %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GCS_COMPREADCLAUSE:
|
|
||||||
if (compstr->dwCompReadClauseLen > 0 && compstr->dwCompReadClauseOffset > 0)
|
|
||||||
{
|
|
||||||
buffer = compdata + compstr->dwCompReadClauseOffset;
|
|
||||||
rc = compstr->dwCompReadClauseLen;
|
|
||||||
TRACE("GCS_COMPREADCLAUSE %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GCS_RESULTREADCLAUSE:
|
|
||||||
if (compstr->dwResultReadClauseLen > 0 && compstr->dwResultReadClauseOffset > 0)
|
|
||||||
{
|
|
||||||
buffer = compdata + compstr->dwResultReadClauseOffset;
|
|
||||||
rc = compstr->dwResultReadClauseLen;
|
|
||||||
TRACE("GCS_RESULTREADCLAUSE %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GCS_RESULTCLAUSE:
|
|
||||||
if (compstr->dwResultClauseLen > 0 && compstr->dwResultClauseOffset > 0)
|
|
||||||
{
|
|
||||||
buffer = compdata + compstr->dwResultClauseOffset;
|
|
||||||
rc = compstr->dwResultClauseLen;
|
|
||||||
TRACE("GCS_RESULTCLAUSE %p %i\n", buffer, rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GCS_CURSORPOS:
|
|
||||||
TRACE("GCS_CURSORPOS\n");
|
|
||||||
rc = compstr->dwCursorPos;
|
|
||||||
break;
|
|
||||||
case GCS_DELTASTART:
|
|
||||||
TRACE("GCS_DELTASTART\n");
|
|
||||||
rc = compstr->dwDeltaStart;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FIXME("Unhandled index 0x%x\n",dwIndex);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( isString && buffer )
|
|
||||||
{
|
|
||||||
if ( !is_himc_ime_unicode(data) )
|
|
||||||
{
|
|
||||||
INT len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)buffer, rc, NULL, 0 );
|
|
||||||
buf = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
|
|
||||||
if ( buf )
|
|
||||||
rc = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)buffer, rc, buf, len );
|
|
||||||
buffer = (LPBYTE)buf;
|
|
||||||
}
|
|
||||||
rc *= sizeof(WCHAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( lpBuf && buffer && dwBufLen >= rc )
|
|
||||||
memcpy( lpBuf, buffer, rc );
|
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, buf );
|
|
||||||
ImmUnlockIMCC(data->IMC.hCompStr);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
Loading…
Reference in New Issue