imm32: Use the COMPOSITIONSTRING in hCompStr.

Stop using our custom structure for the Composition string and instead
use the COMPOSITIONSTRING whose handle is in the IMC structure.
This commit is contained in:
Aric Stewart 2007-07-10 14:19:22 -05:00 committed by Alexandre Julliard
parent dab80a8d9f
commit 5db70db76e
1 changed files with 477 additions and 195 deletions

View File

@ -2,7 +2,7 @@
* IMM32 library * IMM32 library
* *
* Copyright 1998 Patrik Stridvall * Copyright 1998 Patrik Stridvall
* Copyright 2002, 2003 CodeWeavers, Aric Stewart * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -45,15 +45,6 @@ typedef struct tagIMCCInternal
typedef struct tagInputContextData 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;
BOOL bInternalState; BOOL bInternalState;
BOOL bRead; BOOL bRead;
BOOL bInComposition; BOOL bInComposition;
@ -86,21 +77,30 @@ static LRESULT WINAPI IME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
static void UpdateDataInDefaultIMEWindow(HWND hwnd); static void UpdateDataInDefaultIMEWindow(HWND hwnd);
static void ImmInternalPostIMEMessage(UINT, WPARAM, LPARAM); static void ImmInternalPostIMEMessage(UINT, WPARAM, LPARAM);
static void ImmInternalSetOpenStatus(BOOL fOpen); static void ImmInternalSetOpenStatus(BOOL fOpen);
static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len);
static VOID IMM_PostResult(InputContextData *data) static VOID IMM_PostResult(InputContextData *data)
{ {
unsigned int i; unsigned int i;
TRACE("Posting result as IME_CHAR\n"); LPCOMPOSITIONSTRING compstr;
LPBYTE compdata;
LPWSTR ResultStr;
HIMCC newCompStr;
for (i = 0; i < data->dwResultStringSize / sizeof (WCHAR); i++) TRACE("Posting result as IME_CHAR\n");
ImmInternalPostIMEMessage (WM_IME_CHAR, ((WCHAR*)data->ResultString)[i], compdata = ImmLockIMCC(root_context->IMC.hCompStr);
1); compstr = (LPCOMPOSITIONSTRING)compdata;
ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
for (i = 0; i < compstr->dwResultStrLen; i++)
ImmInternalPostIMEMessage (WM_IME_CHAR, ResultStr[i], 1);
ImmUnlockIMCC(root_context->IMC.hCompStr);
/* clear the buffer */ /* clear the buffer */
if (data->dwResultStringSize) newCompStr = updateResultStr(root_context->IMC.hCompStr, NULL, 0);
HeapFree(GetProcessHeap(),0,data->ResultString); ImmDestroyIMCC(root_context->IMC.hCompStr);
data->dwResultStringSize = 0; root_context->IMC.hCompStr = newCompStr;
data->ResultString = NULL;
} }
static void IMM_Register(void) static void IMM_Register(void)
@ -198,24 +198,8 @@ static void ImmInternalSetOpenStatus(BOOL fOpen)
if (fOpen == FALSE) if (fOpen == FALSE)
{ {
ShowWindow(hwndDefault,SW_HIDE); ShowWindow(hwndDefault,SW_HIDE);
ImmDestroyIMCC(root_context->IMC.hCompStr);
if (root_context->dwCompStringSize) root_context->IMC.hCompStr = NULL;
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 else
ShowWindow(hwndDefault, SW_SHOWNOACTIVATE); ShowWindow(hwndDefault, SW_SHOWNOACTIVATE);
@ -223,6 +207,286 @@ static void ImmInternalSetOpenStatus(BOOL fOpen)
ImmInternalSendIMENotify(IMN_SETOPENSTATUS, 0); ImmInternalSendIMENotify(IMN_SETOPENSTATUS, 0);
} }
static int updateField(DWORD origLen, DWORD origOffset, DWORD currentOffset,
LPBYTE target, LPBYTE source, DWORD* lenParam,
DWORD* offsetParam, BOOL wchars )
{
if (origLen > 0 && origOffset > 0)
{
int truelen = origLen;
if (wchars)
truelen *= sizeof(WCHAR);
memcpy(&target[currentOffset], &source[origOffset], truelen);
*lenParam = origLen;
*offsetParam = currentOffset;
currentOffset += truelen;
}
return currentOffset;
}
static HIMCC updateCompStr(HIMCC old, LPWSTR compstr, DWORD len)
{
/* we need to make sure the CompStr, CompClaus and CompAttr fields are all
* set and correct */
int needed_size;
HIMCC rc;
LPBYTE newdata = NULL;
LPBYTE olddata = NULL;
LPCOMPOSITIONSTRING new_one;
LPCOMPOSITIONSTRING lpcs = NULL;
INT current_offset = 0;
TRACE("%s, %i\n",debugstr_wn(compstr,len),len);
if (old != NULL)
{
olddata = ImmLockIMCC(old);
lpcs = (LPCOMPOSITIONSTRING)olddata;
}
needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
len + sizeof(DWORD) * 2;
if (lpcs != NULL)
{
needed_size += lpcs->dwCompReadAttrLen;
needed_size += lpcs->dwCompReadClauseLen;
needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
needed_size += lpcs->dwResultReadClauseLen;
needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
needed_size += lpcs->dwResultClauseLen;
needed_size += lpcs->dwResultStrLen * sizeof(DWORD);
needed_size += lpcs->dwPrivateSize;
}
rc = ImmCreateIMCC(needed_size);
newdata = ImmLockIMCC(rc);
new_one = (LPCOMPOSITIONSTRING)newdata;
new_one->dwSize = needed_size;
current_offset = sizeof(COMPOSITIONSTRING);
if (lpcs != NULL)
{
current_offset = updateField(lpcs->dwCompReadAttrLen,
lpcs->dwCompReadAttrOffset,
current_offset, newdata, olddata,
&new_one->dwCompReadAttrLen,
&new_one->dwCompReadAttrOffset, FALSE);
current_offset = updateField(lpcs->dwCompReadClauseLen,
lpcs->dwCompReadClauseOffset,
current_offset, newdata, olddata,
&new_one->dwCompReadClauseLen,
&new_one->dwCompReadClauseOffset, FALSE);
current_offset = updateField(lpcs->dwCompReadStrLen,
lpcs->dwCompReadStrOffset,
current_offset, newdata, olddata,
&new_one->dwCompReadStrLen,
&new_one->dwCompReadStrOffset, TRUE);
/* new CompAttr, CompClause, CompStr, dwCursorPos */
current_offset = updateField(lpcs->dwResultReadClauseLen,
lpcs->dwResultReadClauseOffset,
current_offset, newdata, olddata,
&new_one->dwResultReadClauseLen,
&new_one->dwResultReadClauseOffset, FALSE);
current_offset = updateField(lpcs->dwResultReadStrLen,
lpcs->dwResultReadStrOffset,
current_offset, newdata, olddata,
&new_one->dwResultReadStrLen,
&new_one->dwResultReadStrOffset, TRUE);
current_offset = updateField(lpcs->dwResultClauseLen,
lpcs->dwResultClauseOffset,
current_offset, newdata, olddata,
&new_one->dwResultClauseLen,
&new_one->dwResultClauseOffset, FALSE);
current_offset = updateField(lpcs->dwResultStrLen,
lpcs->dwResultStrOffset,
current_offset, newdata, olddata,
&new_one->dwResultStrLen,
&new_one->dwResultStrOffset, TRUE);
current_offset = updateField(lpcs->dwPrivateSize,
lpcs->dwPrivateOffset,
current_offset, newdata, olddata,
&new_one->dwPrivateSize,
&new_one->dwPrivateOffset, FALSE);
}
/* set new data */
/* CompAttr */
new_one->dwCompAttrLen = len;
if (len > 0)
{
new_one->dwCompAttrOffset = current_offset;
memset(&newdata[current_offset],ATTR_INPUT,len);
current_offset += len;
}
/* CompClause */
if (len > 0)
{
new_one->dwCompClauseLen = sizeof(DWORD) * 2;
new_one->dwCompClauseOffset = current_offset;
*(DWORD*)(&newdata[current_offset]) = 0;
current_offset += sizeof(DWORD);
*(DWORD*)(&newdata[current_offset]) = len;
current_offset += sizeof(DWORD);
}
/* CompStr */
new_one->dwCompStrLen = len;
if (len > 0)
{
new_one->dwCompStrOffset = current_offset;
memcpy(&newdata[current_offset],compstr,len*sizeof(WCHAR));
}
/* CursorPos */
new_one->dwCursorPos = len;
ImmUnlockIMCC(rc);
if (lpcs)
ImmUnlockIMCC(old);
return rc;
}
static HIMCC updateResultStr(HIMCC old, LPWSTR resultstr, DWORD len)
{
/* we need to make sure the ResultStr and ResultClause fields are all
* set and correct */
int needed_size;
HIMCC rc;
LPBYTE newdata = NULL;
LPBYTE olddata = NULL;
LPCOMPOSITIONSTRING new_one;
LPCOMPOSITIONSTRING lpcs = NULL;
INT current_offset = 0;
TRACE("%s, %i\n",debugstr_wn(resultstr,len),len);
if (old != NULL)
{
olddata = ImmLockIMCC(old);
lpcs = (LPCOMPOSITIONSTRING)olddata;
}
needed_size = sizeof(COMPOSITIONSTRING) + len * sizeof(WCHAR) +
sizeof(DWORD) * 2;
if (lpcs != NULL)
{
needed_size += lpcs->dwCompReadAttrLen;
needed_size += lpcs->dwCompReadClauseLen;
needed_size += lpcs->dwCompReadStrLen * sizeof(DWORD);
needed_size += lpcs->dwCompAttrLen;
needed_size += lpcs->dwCompClauseLen;
needed_size += lpcs->dwCompStrLen * sizeof(DWORD);
needed_size += lpcs->dwResultReadClauseLen;
needed_size += lpcs->dwResultReadStrLen * sizeof(DWORD);
needed_size += lpcs->dwPrivateSize;
}
rc = ImmCreateIMCC(needed_size);
newdata = ImmLockIMCC(rc);
new_one = (LPCOMPOSITIONSTRING)newdata;
new_one->dwSize = needed_size;
current_offset = sizeof(COMPOSITIONSTRING);
if (lpcs != NULL)
{
current_offset = updateField(lpcs->dwCompReadAttrLen,
lpcs->dwCompReadAttrOffset,
current_offset, newdata, olddata,
&new_one->dwCompReadAttrLen,
&new_one->dwCompReadAttrOffset, FALSE);
current_offset = updateField(lpcs->dwCompReadClauseLen,
lpcs->dwCompReadClauseOffset,
current_offset, newdata, olddata,
&new_one->dwCompReadClauseLen,
&new_one->dwCompReadClauseOffset, FALSE);
current_offset = updateField(lpcs->dwCompReadStrLen,
lpcs->dwCompReadStrOffset,
current_offset, newdata, olddata,
&new_one->dwCompReadStrLen,
&new_one->dwCompReadStrOffset, TRUE);
current_offset = updateField(lpcs->dwCompAttrLen,
lpcs->dwCompAttrOffset,
current_offset, newdata, olddata,
&new_one->dwCompAttrLen,
&new_one->dwCompAttrOffset, FALSE);
current_offset = updateField(lpcs->dwCompClauseLen,
lpcs->dwCompClauseOffset,
current_offset, newdata, olddata,
&new_one->dwCompClauseLen,
&new_one->dwCompClauseOffset, FALSE);
current_offset = updateField(lpcs->dwCompStrLen,
lpcs->dwCompStrOffset,
current_offset, newdata, olddata,
&new_one->dwCompStrLen,
&new_one->dwCompStrOffset, TRUE);
new_one->dwCursorPos = lpcs->dwCursorPos;
current_offset = updateField(lpcs->dwResultReadClauseLen,
lpcs->dwResultReadClauseOffset,
current_offset, newdata, olddata,
&new_one->dwResultReadClauseLen,
&new_one->dwResultReadClauseOffset, FALSE);
current_offset = updateField(lpcs->dwResultReadStrLen,
lpcs->dwResultReadStrOffset,
current_offset, newdata, olddata,
&new_one->dwResultReadStrLen,
&new_one->dwResultReadStrOffset, TRUE);
/* new ResultClause , ResultStr */
current_offset = updateField(lpcs->dwPrivateSize,
lpcs->dwPrivateOffset,
current_offset, newdata, olddata,
&new_one->dwPrivateSize,
&new_one->dwPrivateOffset, FALSE);
}
/* set new data */
/* ResultClause */
if (len > 0)
{
new_one->dwResultClauseLen = sizeof(DWORD) * 2;
new_one->dwResultClauseOffset = current_offset;
*(DWORD*)(&newdata[current_offset]) = 0;
current_offset += sizeof(DWORD);
*(DWORD*)(&newdata[current_offset]) = len;
current_offset += sizeof(DWORD);
}
/* ResultStr */
new_one->dwResultStrLen = len;
if (len > 0)
{
new_one->dwResultStrOffset = current_offset;
memcpy(&newdata[current_offset],resultstr,len*sizeof(WCHAR));
}
ImmUnlockIMCC(rc);
if (lpcs)
ImmUnlockIMCC(old);
return rc;
}
/*********************************************************************** /***********************************************************************
* ImmAssociateContext (IMM32.@) * ImmAssociateContext (IMM32.@)
@ -335,14 +599,11 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC)
if (hIMC) if (hIMC)
{ {
if (data->dwCompStringSize) ImmDestroyIMCC(root_context->IMC.hCompStr);
HeapFree(GetProcessHeap(),0,data->CompositionString); ImmDestroyIMCC(root_context->IMC.hCandInfo);
if (data->dwCompReadStringSize) ImmDestroyIMCC(root_context->IMC.hGuideLine);
HeapFree(GetProcessHeap(),0,data->CompositionReadingString); ImmDestroyIMCC(root_context->IMC.hPrivate);
if (data->dwResultStringSize) ImmDestroyIMCC(root_context->IMC.hMsgBuf);
HeapFree(GetProcessHeap(),0,data->ResultString);
if (data->dwResultReadStringSize)
HeapFree(GetProcessHeap(),0,data->ResultReadingString);
if (data->textfont) if (data->textfont)
{ {
@ -518,96 +779,95 @@ LONG WINAPI ImmGetCompositionStringA(
CHAR *buf; CHAR *buf;
LONG rc = 0; LONG rc = 0;
InputContextData *data = (InputContextData*)hIMC; InputContextData *data = (InputContextData*)hIMC;
LPCOMPOSITIONSTRING compstr;
LPBYTE compdata;
TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen); TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
if (!data) if (!data)
return FALSE; return FALSE;
if (dwIndex == GCS_RESULTSTR) if (!data->IMC.hCompStr)
{ return FALSE;
TRACE("GSC_RESULTSTR %p %i\n",data->ResultString,
data->dwResultStringSize);
buf = HeapAlloc( GetProcessHeap(), 0, data->dwResultStringSize * 3 ); compdata = ImmLockIMCC(data->IMC.hCompStr);
rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->ResultString, compstr = (LPCOMPOSITIONSTRING)compdata;
data->dwResultStringSize / sizeof(WCHAR), buf,
data->dwResultStringSize * 3, NULL, NULL); if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
compstr->dwResultStrOffset > 0)
{
LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
TRACE("GSC_RESULTSTR %p %i\n",ResultStr,
compstr->dwResultStrLen);
buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwResultStrLen * 3 );
rc = WideCharToMultiByte(CP_ACP, 0, ResultStr,
compstr->dwResultStrLen , buf,
compstr->dwResultStrLen * 3, NULL, NULL);
if (dwBufLen >= rc) if (dwBufLen >= rc)
memcpy(lpBuf,buf,rc); memcpy(lpBuf,buf,rc);
data->bRead = TRUE; data->bRead = TRUE;
HeapFree( GetProcessHeap(), 0, buf ); HeapFree( GetProcessHeap(), 0, buf );
} }
else if (dwIndex == GCS_COMPSTR) else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
compstr->dwCompStrOffset > 0)
{ {
TRACE("GSC_COMPSTR %p %i\n", data->CompositionString, data->dwCompStringLength); LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
buf = HeapAlloc( GetProcessHeap(), 0, data->dwCompStringLength * 3 ); TRACE("GSC_COMPSTR %p %i\n", CompString, compstr->dwCompStrLen);
rc = WideCharToMultiByte(CP_ACP, 0,(LPWSTR)data->CompositionString,
data->dwCompStringLength/ sizeof(WCHAR), buf, buf = HeapAlloc( GetProcessHeap(), 0, compstr->dwCompStrLen * 3 );
data->dwCompStringLength* 3, NULL, NULL); rc = WideCharToMultiByte(CP_ACP, 0, CompString,
compstr->dwCompStrLen, buf,
compstr->dwCompStrLen * 3, NULL, NULL);
if (dwBufLen >= rc) if (dwBufLen >= rc)
memcpy(lpBuf,buf,rc); memcpy(lpBuf,buf,rc);
HeapFree( GetProcessHeap(), 0, buf ); HeapFree( GetProcessHeap(), 0, buf );
} }
else if (dwIndex == GCS_COMPATTR) else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
compstr->dwCompAttrOffset > 0)
{ {
TRACE("GSC_COMPATTR %p %i\n", data->CompositionString, data->dwCompStringLength); LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
TRACE("GSC_COMPATTR %p %i\n", Compattr , compstr->dwCompAttrLen);
rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->CompositionString,
data->dwCompStringLength/ sizeof(WCHAR), NULL,
0, NULL, NULL);
rc = compstr->dwCompAttrLen;
if (dwBufLen >= rc) if (dwBufLen >= rc)
{ memcpy(lpBuf,Compattr,rc);
int i=0;
for (i = 0; i < rc; i++)
((LPBYTE)lpBuf)[i] = ATTR_INPUT;
} }
} else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
else if (dwIndex == GCS_COMPCLAUSE) compstr->dwCompClauseOffset > 0)
{ {
TRACE("GSC_COMPCLAUSE %p %i\n", data->CompositionString, data->dwCompStringLength); LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
TRACE("GSC_COMPCLAUSE %p %i\n", Compclause, compstr->dwCompClauseLen);
rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->CompositionString, rc = compstr->dwCompClauseLen;
data->dwCompStringLength/ sizeof(WCHAR), NULL, if (dwBufLen >= compstr->dwCompClauseLen)
0, NULL, NULL); memcpy(lpBuf,Compclause,rc);
if (dwBufLen >= sizeof(DWORD)*2)
{
((LPDWORD)lpBuf)[0] = 0;
((LPDWORD)lpBuf)[1] = rc;
}
rc = sizeof(DWORD)*2;
} }
else if (dwIndex == GCS_RESULTCLAUSE) else if (dwIndex == GCS_RESULTCLAUSE && compstr->dwResultClauseLen > 0 &&
compstr->dwResultClauseOffset > 0)
{ {
TRACE("GSC_RESULTCLAUSE %p %i\n", data->ResultString, data->dwResultStringSize); LPWSTR Resultclause = (LPWSTR)(compdata + compstr->dwResultClauseOffset);
TRACE("GSC_RESULTCLAUSE %p %i\n", Resultclause, compstr->dwResultClauseLen);
rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->ResultString, rc = compstr->dwResultClauseLen;
data->dwResultStringSize/ sizeof(WCHAR), NULL, if (dwBufLen >= compstr->dwResultClauseLen)
0, NULL, NULL); memcpy(lpBuf,Resultclause,rc);
if (dwBufLen >= sizeof(DWORD)*2)
{
((LPDWORD)lpBuf)[0] = 0;
((LPDWORD)lpBuf)[1] = rc;
}
rc = sizeof(DWORD)*2;
} }
else if (dwIndex == GCS_CURSORPOS) else if (dwIndex == GCS_CURSORPOS)
{ {
TRACE("GSC_CURSORPOS\n"); TRACE("GSC_CURSORPOS\n");
rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)data->CompositionString, rc = compstr->dwCursorPos;
data->dwCompStringLength/ sizeof(WCHAR), NULL,
0, NULL, NULL);
} }
else else
{ {
FIXME("Unhandled index 0x%x\n",dwIndex); FIXME("Unhandled index 0x%x\n",dwIndex);
} }
ImmUnlockIMCC(data->IMC.hCompStr);
return rc; return rc;
} }
@ -620,76 +880,88 @@ LONG WINAPI ImmGetCompositionStringW(
{ {
LONG rc = 0; LONG rc = 0;
InputContextData *data = (InputContextData*)hIMC; InputContextData *data = (InputContextData*)hIMC;
LPCOMPOSITIONSTRING compstr;
LPBYTE compdata;
TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen); TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
if (!data) if (!data)
return FALSE; return FALSE;
if (dwIndex == GCS_RESULTSTR) if (!data->IMC.hCompStr)
return FALSE;
compdata = ImmLockIMCC(data->IMC.hCompStr);
compstr = (LPCOMPOSITIONSTRING)compdata;
if (dwIndex == GCS_RESULTSTR && compstr->dwResultStrLen > 0 &&
compstr->dwResultStrOffset > 0)
{ {
LPWSTR ResultStr = (LPWSTR)(compdata + compstr->dwResultStrOffset);
data->bRead = TRUE; data->bRead = TRUE;
rc = compstr->dwResultStrLen * sizeof(WCHAR);
if (dwBufLen >= data->dwResultStringSize) if (dwBufLen >= rc)
memcpy(lpBuf,data->ResultString,data->dwResultStringSize); memcpy(lpBuf,ResultStr,rc);
rc = data->dwResultStringSize;
} }
else if (dwIndex == GCS_RESULTREADSTR) else if (dwIndex == GCS_RESULTREADSTR && compstr->dwResultReadStrLen > 0 &&
compstr->dwResultReadStrOffset > 0)
{ {
if (dwBufLen >= data->dwResultReadStringSize) LPWSTR ResultReadString = (LPWSTR)(compdata + compstr->dwResultReadStrOffset);
memcpy(lpBuf,data->ResultReadingString,
data->dwResultReadStringSize);
rc = data->dwResultReadStringSize; rc = compstr->dwResultReadStrLen * sizeof(WCHAR);
if (dwBufLen >= rc)
memcpy(lpBuf,ResultReadString,rc);
} }
else if (dwIndex == GCS_COMPSTR) else if (dwIndex == GCS_COMPSTR && compstr->dwCompStrLen > 0 &&
compstr->dwCompStrOffset > 0)
{
LPWSTR CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
rc = compstr->dwCompStrLen * sizeof(WCHAR);
if (dwBufLen >= rc)
memcpy(lpBuf,CompString,rc);
}
else if (dwIndex == GCS_COMPATTR && compstr->dwCompAttrLen > 0 &&
compstr->dwCompAttrOffset > 0)
{ {
if (dwBufLen >= data->dwCompStringLength)
memcpy(lpBuf,data->CompositionString,data->dwCompStringLength);
rc = data->dwCompStringLength; LPWSTR Compattr = (LPWSTR)(compdata + compstr->dwCompAttrOffset);
}
else if (dwIndex == GCS_COMPATTR)
{
unsigned int len = data->dwCompStringLength;
if (dwBufLen >= len) rc = compstr->dwCompAttrLen;
{ if (dwBufLen >= rc)
unsigned int i=0; memcpy(lpBuf,Compattr,rc);
for (i = 0; i < len; i++) }
((LPBYTE)lpBuf)[i] = ATTR_INPUT; else if (dwIndex == GCS_COMPCLAUSE && compstr->dwCompClauseLen > 0 &&
} compstr->dwCompClauseOffset > 0)
{
LPWSTR Compclause = (LPWSTR)(compdata + compstr->dwCompClauseOffset);
rc = len; rc = compstr->dwCompClauseLen;
if (dwBufLen >= compstr->dwCompClauseLen)
memcpy(lpBuf,Compclause,rc);
} }
else if (dwIndex == GCS_COMPCLAUSE) else if (dwIndex == GCS_COMPREADSTR && compstr->dwCompReadStrLen > 0 &&
compstr->dwCompReadStrOffset > 0)
{ {
if (dwBufLen >= sizeof(DWORD)*2) LPWSTR CompReadString = (LPWSTR)(compdata + compstr->dwCompReadStrOffset);
{
((LPDWORD)lpBuf)[0] = 0; rc = compstr->dwCompReadStrLen * sizeof(WCHAR);
((LPDWORD)lpBuf)[1] = data->dwCompStringLength/sizeof(WCHAR);
} if (dwBufLen >= rc)
rc = sizeof(DWORD)*2; memcpy(lpBuf,CompReadString,rc);
} }
else if (dwIndex == GCS_COMPREADSTR)
{
if (dwBufLen >= data->dwCompReadStringSize)
memcpy(lpBuf,data->CompositionReadingString,
data->dwCompReadStringSize);
rc = data->dwCompReadStringSize;
}
else if (dwIndex == GCS_CURSORPOS) else if (dwIndex == GCS_CURSORPOS)
{ {
TRACE("GSC_CURSORPOS\n"); TRACE("GSC_CURSORPOS\n");
rc = data->dwCompStringLength; rc = compstr->dwCursorPos;
} }
else else
{ {
FIXME("Unhandled index 0x%x\n",dwIndex); FIXME("Unhandled index 0x%x\n",dwIndex);
} }
ImmUnlockIMCC(data->IMC.hCompStr);
return rc; return rc;
} }
@ -1110,56 +1382,60 @@ BOOL WINAPI ImmNotifyIME(
{ {
case CPS_CANCEL: case CPS_CANCEL:
TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL"); TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_CANCEL");
if (pX11DRV_ForceXIMReset)
pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
if (root_context->dwCompStringSize)
{ {
HeapFree(GetProcessHeap(),0, HIMCC newCompStr;
root_context->CompositionString); if (pX11DRV_ForceXIMReset)
root_context->dwCompStringSize = 0; pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
root_context->dwCompStringLength = 0;
root_context->CompositionString = NULL; newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
ImmDestroyIMCC(root_context->IMC.hCompStr);
root_context->IMC.hCompStr = newCompStr;
ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0, ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
GCS_COMPSTR); GCS_COMPSTR);
rc = TRUE;
} }
rc = TRUE;
break; break;
case CPS_COMPLETE: case CPS_COMPLETE:
TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_COMPLETE"); TRACE("%s - %s\n","NI_COMPOSITIONSTR","CPS_COMPLETE");
if (hIMC != (HIMC)FROM_IME && pX11DRV_ForceXIMReset) if (hIMC != (HIMC)FROM_IME && pX11DRV_ForceXIMReset)
pX11DRV_ForceXIMReset(root_context->IMC.hWnd); pX11DRV_ForceXIMReset(root_context->IMC.hWnd);
if (root_context->dwResultStringSize)
{ {
HeapFree(GetProcessHeap(),0,root_context->ResultString); HIMCC newCompStr;
root_context->dwResultStringSize = 0; DWORD cplen;
root_context->ResultString = NULL; LPWSTR cpstr;
} LPCOMPOSITIONSTRING cs = NULL;
if (root_context->dwCompStringLength) LPBYTE cdata = NULL;
{
root_context->ResultString = HeapAlloc(
GetProcessHeap(), 0, root_context->dwCompStringLength);
root_context->dwResultStringSize =
root_context->dwCompStringLength;
memcpy(root_context->ResultString, /* clear existing result */
root_context->CompositionString, newCompStr = updateResultStr(root_context->IMC.hCompStr, NULL, 0);
root_context->dwCompStringLength); ImmDestroyIMCC(root_context->IMC.hCompStr);
root_context->IMC.hCompStr = newCompStr;
HeapFree(GetProcessHeap(),0, cdata = ImmLockIMCC(root_context->IMC.hCompStr);
root_context->CompositionString); cs = (LPCOMPOSITIONSTRING)cdata;
cplen = cs->dwCompStrLen;
cpstr = (LPWSTR)&(cdata[cs->dwCompStrOffset]);
ImmUnlockIMCC(root_context->IMC.hCompStr);
if (cplen > 0)
{
WCHAR param = cpstr[0];
newCompStr = updateResultStr(root_context->IMC.hCompStr, cpstr, cplen);
ImmDestroyIMCC(root_context->IMC.hCompStr);
root_context->IMC.hCompStr = newCompStr;
newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
ImmDestroyIMCC(root_context->IMC.hCompStr);
root_context->IMC.hCompStr = newCompStr;
root_context->dwCompStringSize = 0; root_context->bRead = FALSE;
root_context->dwCompStringLength = 0;
root_context->CompositionString = NULL;
root_context->bRead = FALSE;
ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0, ImmInternalPostIMEMessage(WM_IME_COMPOSITION, 0,
GCS_COMPSTR); GCS_COMPSTR);
ImmInternalPostIMEMessage(WM_IME_COMPOSITION, ImmInternalPostIMEMessage(WM_IME_COMPOSITION,
root_context->ResultString[0], param,
GCS_RESULTSTR|GCS_RESULTCLAUSE); GCS_RESULTSTR|GCS_RESULTCLAUSE);
}
ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0); ImmInternalPostIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0);
root_context->bInComposition = FALSE; root_context->bInComposition = FALSE;
@ -1370,32 +1646,30 @@ BOOL WINAPI ImmSetCompositionStringW(
if (dwIndex == SCS_SETSTR) if (dwIndex == SCS_SETSTR)
{ {
if (!root_context->bInComposition) HIMCC newCompStr;
{ if (!root_context->bInComposition)
{
ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION, 0, 0); ImmInternalPostIMEMessage(WM_IME_STARTCOMPOSITION, 0, 0);
root_context->bInComposition = TRUE; root_context->bInComposition = TRUE;
} }
flags = GCS_COMPSTR; flags = GCS_COMPSTR;
if (root_context->dwCompStringLength) if (dwCompLen && lpComp)
HeapFree(GetProcessHeap(),0,root_context->CompositionString); {
newCompStr = updateCompStr(root_context->IMC.hCompStr, (LPWSTR)lpComp, dwCompLen / sizeof(WCHAR));
root_context->dwCompStringLength = dwCompLen; ImmDestroyIMCC(root_context->IMC.hCompStr);
root_context->dwCompStringSize = dwCompLen; root_context->IMC.hCompStr = newCompStr;
if (dwCompLen && lpComp)
{
root_context->CompositionString = HeapAlloc(GetProcessHeap(), 0,
dwCompLen);
memcpy(root_context->CompositionString,lpComp,dwCompLen);
wParam = ((const WCHAR*)lpComp)[0]; wParam = ((const WCHAR*)lpComp)[0];
flags |= GCS_COMPCLAUSE | GCS_COMPATTR; flags |= GCS_COMPCLAUSE | GCS_COMPATTR;
} }
else else
root_context->CompositionString = NULL; {
newCompStr = updateCompStr(root_context->IMC.hCompStr, NULL, 0);
ImmDestroyIMCC(root_context->IMC.hCompStr);
root_context->IMC.hCompStr = newCompStr;
}
} }
UpdateDataInDefaultIMEWindow(hwndDefault); UpdateDataInDefaultIMEWindow(hwndDefault);
@ -1691,22 +1965,28 @@ static void PaintDefaultIMEWnd(HWND hwnd)
PAINTSTRUCT ps; PAINTSTRUCT ps;
RECT rect; RECT rect;
HDC hdc = BeginPaint(hwnd,&ps); HDC hdc = BeginPaint(hwnd,&ps);
LPCOMPOSITIONSTRING compstr;
LPBYTE compdata = NULL;
GetClientRect(hwnd,&rect); GetClientRect(hwnd,&rect);
FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1)); FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1));
if (root_context->dwCompStringLength && root_context->CompositionString) compdata = ImmLockIMCC(root_context->IMC.hCompStr);
compstr = (LPCOMPOSITIONSTRING)compdata;
if (compstr->dwCompStrLen && compstr->dwCompStrOffset)
{ {
SIZE size; SIZE size;
POINT pt; POINT pt;
HFONT oldfont = NULL; HFONT oldfont = NULL;
LPWSTR CompString;
CompString = (LPWSTR)(compdata + compstr->dwCompStrOffset);
if (root_context->textfont) if (root_context->textfont)
oldfont = SelectObject(hdc,root_context->textfont); oldfont = SelectObject(hdc,root_context->textfont);
GetTextExtentPoint32W(hdc, (LPWSTR)root_context->CompositionString, GetTextExtentPoint32W(hdc, CompString, compstr->dwCompStrLen, &size);
root_context->dwCompStringLength / sizeof(WCHAR),
&size);
pt.x = size.cx; pt.x = size.cx;
pt.y = size.cy; pt.y = size.cy;
LPtoDP(hdc,&pt,1); LPtoDP(hdc,&pt,1);
@ -1742,12 +2022,14 @@ static void PaintDefaultIMEWnd(HWND hwnd)
} }
MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left , MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left ,
rect.bottom - rect.top, FALSE); rect.bottom - rect.top, FALSE);
TextOutW(hdc, 10,10,(LPWSTR)root_context->CompositionString, TextOutW(hdc, 10,10, CompString, compstr->dwCompStrLen);
root_context->dwCompStringLength / sizeof(WCHAR));
if (oldfont) if (oldfont)
SelectObject(hdc,oldfont); SelectObject(hdc,oldfont);
} }
ImmUnlockIMCC(root_context->IMC.hCompStr);
EndPaint(hwnd,&ps); EndPaint(hwnd,&ps);
} }