Commit b9bfd74a authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

winex11: Generate IME messages using WM_IME_NOTIFY instead of callbacks.

parent c28f571a
......@@ -350,13 +350,31 @@ static UINT ime_set_comp_string( HIMC himc, LPARAM lparam )
};
TRANSMSGLIST list;
} buffer = {.uMsgCount = ARRAY_SIZE(buffer.TransMsg)};
INPUTCONTEXT *ctx;
TRANSMSG *msgs;
HIMCC himcc;
UINT count;
TRACE( "himc %p\n", himc );
if (!(ctx = ImmLockIMC( himc ))) return 0;
count = ImeToAsciiEx( VK_PROCESSKEY, lparam, NULL, &buffer.list, 0, himc );
if (count >= buffer.uMsgCount)
WARN( "ImeToAsciiEx returned %#x messages\n", count );
else if (!(himcc = ImmReSizeIMCC( ctx->hMsgBuf, (ctx->dwNumMsgBuf + count) * sizeof(*msgs) )))
WARN( "Failed to resize input context message buffer\n" );
else if (!(msgs = ImmLockIMCC( (ctx->hMsgBuf = himcc) )))
WARN( "Failed to lock input context message buffer\n" );
else
{
memcpy( msgs + ctx->dwNumMsgBuf, buffer.TransMsg, count * sizeof(*msgs) );
ImmUnlockIMCC( ctx->hMsgBuf );
ctx->dwNumMsgBuf += count;
}
ImmUnlockIMC( himc );
ImmGenerateMessage( himc );
return count;
}
......
......@@ -30,8 +30,6 @@ static const callback_func callback_funcs[] =
{
x11drv_dnd_drop_event,
x11drv_dnd_leave_event,
x11drv_ime_set_composition_status,
x11drv_ime_set_cursor_pos,
x11drv_ime_update_association,
};
......@@ -50,8 +48,6 @@ static const kernel_callback kernel_callbacks[] =
x11drv_dnd_enter_event,
x11drv_dnd_position_event,
x11drv_dnd_post_drop,
x11drv_ime_set_composition_string,
x11drv_ime_set_result,
x11drv_systray_change_owner,
};
......
......@@ -52,20 +52,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm);
static HIMC *hSelectedFrom = NULL;
static INT hSelectedCount = 0;
static void input_context_reset_comp_str( INPUTCONTEXT *ctx )
{
COMPOSITIONSTRING *compstr;
if (!(compstr = ImmLockIMCC( ctx->hCompStr )))
WARN( "Failed to lock input context composition string\n" );
else
{
memset( compstr, 0, sizeof(*compstr) );
compstr->dwSize = sizeof(*compstr);
ImmUnlockIMCC( ctx->hCompStr );
}
}
static HIMC RealIMC(HIMC hIMC)
{
if (hIMC == FROM_X11)
......@@ -100,359 +86,6 @@ static BOOL UnlockRealIMC(HIMC hIMC)
return FALSE;
}
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, LPCWSTR compstr, DWORD len)
{
/* We need to make sure the CompStr, CompClause 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, %li\n",debugstr_wn(compstr,len),len);
if (old == NULL && compstr == NULL && len == 0)
return NULL;
if (compstr == NULL && len != 0)
{
ERR("compstr is NULL however we have a len! Please report\n");
len = 0;
}
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(WCHAR);
needed_size += lpcs->dwResultReadClauseLen;
needed_size += lpcs->dwResultReadStrLen * sizeof(WCHAR);
needed_size += lpcs->dwResultClauseLen;
needed_size += lpcs->dwResultStrLen * sizeof(WCHAR);
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 */
new_one->dwDeltaStart = 0;
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);
}
else
new_one->dwCompClauseLen = 0;
/* 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, %li\n",debugstr_wn(resultstr,len),len);
if (old == NULL && resultstr == NULL && len == 0)
return NULL;
if (resultstr == NULL && len != 0)
{
ERR("resultstr is NULL however we have a len! Please report\n");
len = 0;
}
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(WCHAR);
needed_size += lpcs->dwCompAttrLen;
needed_size += lpcs->dwCompClauseLen;
needed_size += lpcs->dwCompStrLen * sizeof(WCHAR);
needed_size += lpcs->dwResultReadClauseLen;
needed_size += lpcs->dwResultReadStrLen * sizeof(WCHAR);
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;
new_one->dwDeltaStart = 0;
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);
}
else
new_one->dwResultClauseLen = 0;
/* 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;
}
static void GenerateIMEMessage(HIMC hIMC, UINT msg, WPARAM wParam,
LPARAM lParam)
{
LPINPUTCONTEXT lpIMC;
LPTRANSMSG lpTransMsg;
lpIMC = LockRealIMC(hIMC);
if (lpIMC == NULL)
return;
lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) *
sizeof(TRANSMSG));
if (!lpIMC->hMsgBuf)
return;
lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf);
if (!lpTransMsg)
return;
lpTransMsg += lpIMC->dwNumMsgBuf;
lpTransMsg->message = msg;
lpTransMsg->wParam = wParam;
lpTransMsg->lParam = lParam;
ImmUnlockIMCC(lpIMC->hMsgBuf);
lpIMC->dwNumMsgBuf++;
ImmGenerateMessage(RealIMC(hIMC));
UnlockRealIMC(hIMC);
}
static void ime_set_composition_status( HIMC himc, BOOL composition )
{
struct ime_private *priv;
INPUTCONTEXT *ctx;
UINT msg = 0;
if (!(ctx = ImmLockIMC( himc ))) return;
if ((priv = ImmLockIMCC( ctx->hPrivate )))
{
if (!priv->bInComposition && composition) msg = WM_IME_STARTCOMPOSITION;
else if (priv->bInComposition && !composition) msg = WM_IME_ENDCOMPOSITION;
priv->bInComposition = composition;
ImmUnlockIMCC( ctx->hPrivate );
}
ImmUnlockIMC( himc );
if (msg) GenerateIMEMessage( himc, msg, 0, 0 );
}
static BOOL IME_RemoveFromSelected(HIMC hIMC)
{
int i;
......@@ -516,57 +149,6 @@ BOOL WINAPI ImeSelect(HIMC hIMC, BOOL fSelect)
/* Interfaces to XIM and other parts of winex11drv */
NTSTATUS x11drv_ime_set_composition_status( UINT open )
{
HIMC imc;
LPINPUTCONTEXT lpIMC;
imc = RealIMC(FROM_X11);
lpIMC = ImmLockIMC(imc);
if (lpIMC == NULL)
return 0;
if (!open)
{
struct ime_private *myPrivate = ImmLockIMCC(lpIMC->hPrivate);
ShowWindow(myPrivate->hwndDefault, SW_HIDE);
input_context_reset_comp_str( lpIMC );
ImmUnlockIMCC(lpIMC->hPrivate);
}
ImmUnlockIMC(imc);
ime_set_composition_status( imc, open );
return 0;
}
NTSTATUS x11drv_ime_set_cursor_pos( UINT pos )
{
LPINPUTCONTEXT lpIMC;
LPCOMPOSITIONSTRING compstr;
if (!hSelectedFrom)
return 0;
lpIMC = LockRealIMC(FROM_X11);
if (!lpIMC)
return 0;
compstr = ImmLockIMCC(lpIMC->hCompStr);
if (!compstr)
{
UnlockRealIMC(FROM_X11);
return 0;
}
compstr->dwCursorPos = pos;
ImmUnlockIMCC(lpIMC->hCompStr);
UnlockRealIMC(FROM_X11);
GenerateIMEMessage(FROM_X11, WM_IME_COMPOSITION, pos, GCS_CURSORPOS);
return 0;
}
NTSTATUS x11drv_ime_update_association( UINT arg )
{
HWND focus = UlongToHandle( arg );
......@@ -577,57 +159,3 @@ NTSTATUS x11drv_ime_update_association( UINT arg )
ImmAssociateContext(focus,RealIMC(FROM_X11));
return 0;
}
NTSTATUS WINAPI x11drv_ime_set_composition_string( void *param, ULONG size )
{
return ImmSetCompositionStringW( RealIMC(FROM_X11), SCS_SETSTR, param, size, NULL, 0 );
}
NTSTATUS WINAPI x11drv_ime_set_result( void *params, ULONG len )
{
WCHAR *lpResult = params;
HIMC imc;
LPINPUTCONTEXT lpIMC;
HIMCC newCompStr;
LPIMEPRIVATE myPrivate;
BOOL inComp;
HWND focus;
len /= sizeof(WCHAR);
if ((focus = GetFocus()))
x11drv_ime_update_association( HandleToUlong( focus ));
imc = RealIMC(FROM_X11);
lpIMC = ImmLockIMC(imc);
if (lpIMC == NULL)
return 0;
newCompStr = updateCompStr(lpIMC->hCompStr, NULL, 0);
ImmDestroyIMCC(lpIMC->hCompStr);
lpIMC->hCompStr = newCompStr;
newCompStr = updateResultStr(lpIMC->hCompStr, lpResult, len);
ImmDestroyIMCC(lpIMC->hCompStr);
lpIMC->hCompStr = newCompStr;
myPrivate = ImmLockIMCC(lpIMC->hPrivate);
inComp = myPrivate->bInComposition;
ImmUnlockIMCC(lpIMC->hPrivate);
if (!inComp)
{
ImmSetOpenStatus(imc, TRUE);
GenerateIMEMessage(imc, WM_IME_STARTCOMPOSITION, 0, 0);
}
GenerateIMEMessage(imc, WM_IME_COMPOSITION, 0, GCS_COMPSTR);
GenerateIMEMessage(imc, WM_IME_COMPOSITION, lpResult[0], GCS_RESULTSTR|GCS_RESULTCLAUSE);
GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0);
if (!inComp)
ImmSetOpenStatus(imc, FALSE);
ImmUnlockIMC(imc);
return 0;
}
......@@ -81,8 +81,6 @@ enum x11drv_client_funcs
client_func_dnd_enter_event,
client_func_dnd_position_event,
client_func_dnd_post_drop,
client_func_ime_set_composition_string,
client_func_ime_set_result,
client_func_systray_change_owner,
client_func_last
};
......@@ -94,8 +92,6 @@ enum client_callback
{
client_dnd_drop_event,
client_dnd_leave_event,
client_ime_set_composition_status,
client_ime_set_cursor_pos,
client_ime_update_association,
client_funcs_count
};
......
......@@ -30,14 +30,10 @@
extern NTSTATUS WINAPI x11drv_dnd_enter_event( void *params, ULONG size ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI x11drv_dnd_position_event( void *params, ULONG size ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI x11drv_dnd_post_drop( void *data, ULONG size ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI x11drv_ime_set_composition_string( void *params, ULONG size ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI x11drv_ime_set_result( void *params, ULONG size ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI x11drv_systray_change_owner( void *params, ULONG size ) DECLSPEC_HIDDEN;
extern NTSTATUS x11drv_dnd_drop_event( UINT arg ) DECLSPEC_HIDDEN;
extern NTSTATUS x11drv_dnd_leave_event( UINT arg ) DECLSPEC_HIDDEN;
extern NTSTATUS x11drv_ime_set_composition_status( UINT arg ) DECLSPEC_HIDDEN;
extern NTSTATUS x11drv_ime_set_cursor_pos( UINT pos ) DECLSPEC_HIDDEN;
extern NTSTATUS x11drv_ime_update_association( UINT arg ) DECLSPEC_HIDDEN;
extern LRESULT WINAPI foreign_window_proc( HWND hwnd, UINT msg, WPARAM wparam,
......
......@@ -126,10 +126,7 @@ static void xim_update_comp_string( UINT offset, UINT old_len, const WCHAR *text
ptr = ime_comp_buf + offset;
memmove( ptr + new_len, ptr + old_len, (len - offset - old_len) * sizeof(WCHAR) );
if (text) memcpy( ptr, text, new_len * sizeof(WCHAR) );
len += diff;
ime_comp_buf[len] = 0;
x11drv_client_func( client_func_ime_set_composition_string, ime_comp_buf, len * sizeof(WCHAR) );
ime_comp_buf[len + diff] = 0;
}
void xim_set_result_string( HWND hwnd, const char *str, UINT count )
......@@ -144,7 +141,6 @@ void xim_set_result_string( HWND hwnd, const char *str, UINT count )
output[len] = 0;
post_ime_update( hwnd, 0, ime_comp_buf, output );
x11drv_client_func( client_func_ime_set_result, output, len * sizeof(WCHAR) );
free( output );
}
......@@ -160,10 +156,10 @@ static BOOL xic_preedit_state_notify( XIC xic, XPointer user, XPointer arg )
switch (state)
{
case XIMPreeditEnable:
send_message( hwnd, WM_IME_NOTIFY, IMN_WINE_SET_OPEN_STATUS, TRUE );
NtUserPostMessage( hwnd, WM_IME_NOTIFY, IMN_WINE_SET_OPEN_STATUS, TRUE );
break;
case XIMPreeditDisable:
send_message( hwnd, WM_IME_NOTIFY, IMN_WINE_SET_OPEN_STATUS, FALSE );
NtUserPostMessage( hwnd, WM_IME_NOTIFY, IMN_WINE_SET_OPEN_STATUS, FALSE );
break;
}
......@@ -176,7 +172,6 @@ static int xic_preedit_start( XIC xic, XPointer user, XPointer arg )
TRACE( "xic %p, hwnd %p, arg %p\n", xic, hwnd, arg );
x11drv_client_call( client_ime_set_composition_status, TRUE );
if ((ime_comp_buf = realloc( ime_comp_buf, sizeof(WCHAR) ))) *ime_comp_buf = 0;
else ERR( "Failed to allocate preedit buffer\n" );
......@@ -194,7 +189,6 @@ static int xic_preedit_done( XIC xic, XPointer user, XPointer arg )
free( ime_comp_buf );
ime_comp_buf = NULL;
x11drv_client_call( client_ime_set_composition_status, FALSE );
post_ime_update( hwnd, 0, NULL, NULL );
return 0;
......@@ -234,7 +228,6 @@ static int xic_preedit_draw( XIC xic, XPointer user, XPointer arg )
if (text && str != text->string.multi_byte) free( str );
x11drv_client_call( client_ime_set_cursor_pos, params->caret );
post_ime_update( hwnd, params->caret, ime_comp_buf, NULL );
return 0;
......@@ -279,7 +272,6 @@ static int xic_preedit_caret( XIC xic, XPointer user, XPointer arg )
FIXME( "Not implemented\n" );
break;
}
x11drv_client_call( client_ime_set_cursor_pos, pos );
params->position = xim_caret_pos = pos;
post_ime_update( hwnd, pos, ime_comp_buf, NULL );
......@@ -545,11 +537,16 @@ static struct ime_update *find_ime_update( UINT id )
/***********************************************************************
* ImeToAsciiEx (X11DRV.@)
*
* As XIM filters key events upfront, we don't use ImeProcessKey and ImeToAsciiEx is instead called
* back from the IME UI window procedure when WM_IME_NOTIFY / IMN_WINE_SET_COMP_STRING messages are
* sent to it, to retrieve composition string updates and generate WM_IME messages.
*/
UINT X11DRV_ImeToAsciiEx( UINT vkey, UINT lparam, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc )
{
UINT needed = sizeof(COMPOSITIONSTRING), comp_len, result_len;
struct ime_update *update;
void *dst;
TRACE( "vkey %#x, lparam %#x, state %p, compstr %p, himc %p\n", vkey, lparam, state, compstr, himc );
......@@ -588,6 +585,49 @@ UINT X11DRV_ImeToAsciiEx( UINT vkey, UINT lparam, const BYTE *state, COMPOSITION
list_remove( &update->entry );
pthread_mutex_unlock( &ime_mutex );
memset( compstr, 0, sizeof(*compstr) );
compstr->dwSize = sizeof(*compstr);
if (update->comp_str)
{
compstr->dwCursorPos = update->cursor_pos;
compstr->dwCompStrLen = comp_len;
compstr->dwCompStrOffset = compstr->dwSize;
dst = (BYTE *)compstr + compstr->dwCompStrOffset;
memcpy( dst, update->comp_str, compstr->dwCompStrLen * sizeof(WCHAR) );
compstr->dwSize += compstr->dwCompStrLen * sizeof(WCHAR);
compstr->dwCompClauseLen = 2 * sizeof(DWORD);
compstr->dwCompClauseOffset = compstr->dwSize;
dst = (BYTE *)compstr + compstr->dwCompClauseOffset;
*((DWORD *)dst + 0) = 0;
*((DWORD *)dst + 1) = compstr->dwCompStrLen;
compstr->dwSize += compstr->dwCompClauseLen;
compstr->dwCompAttrLen = compstr->dwCompStrLen;
compstr->dwCompAttrOffset = compstr->dwSize;
dst = (BYTE *)compstr + compstr->dwCompAttrOffset;
memset( dst, ATTR_INPUT, compstr->dwCompAttrLen );
compstr->dwSize += compstr->dwCompAttrLen;
}
if (update->result_str)
{
compstr->dwResultStrLen = result_len;
compstr->dwResultStrOffset = compstr->dwSize;
dst = (BYTE *)compstr + compstr->dwResultStrOffset;
memcpy( dst, update->result_str, compstr->dwResultStrLen * sizeof(WCHAR) );
compstr->dwSize += compstr->dwResultStrLen * sizeof(WCHAR);
compstr->dwResultClauseLen = 2 * sizeof(DWORD);
compstr->dwResultClauseOffset = compstr->dwSize;
dst = (BYTE *)compstr + compstr->dwResultClauseOffset;
*((DWORD *)dst + 0) = 0;
*((DWORD *)dst + 1) = compstr->dwResultStrLen;
compstr->dwSize += compstr->dwResultClauseLen;
}
free( update );
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment