From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/ime.c | 59 +++++++++++++++++++++++++++++++++++ dlls/imm32/imm_private.h | 1 + dlls/winex11.drv/dllmain.c | 2 -- dlls/winex11.drv/event.c | 4 +-- dlls/winex11.drv/ime.c | 54 -------------------------------- dlls/winex11.drv/keyboard.c | 2 +- dlls/winex11.drv/unixlib.h | 2 -- dlls/winex11.drv/x11drv.h | 3 +- dlls/winex11.drv/x11drv_dll.h | 2 -- dlls/winex11.drv/xim.c | 39 ++++++++++++++++------- include/ntuser.h | 1 + 11 files changed, 93 insertions(+), 76 deletions(-)
diff --git a/dlls/imm32/ime.c b/dlls/imm32/ime.c index e4e3c65aee4..464b5bdc2bf 100644 --- a/dlls/imm32/ime.c +++ b/dlls/imm32/ime.c @@ -88,6 +88,7 @@ static void input_context_set_comp_str( INPUTCONTEXT *ctx, BOOL result, const WC UINT new_size = sizeof(COMPOSITIONSTRING); COMPOSITIONSTRING old, *string; HIMCC tmp; + BYTE *dst;
TRACE( "ctx %p, result %u, str %s\n", ctx, result, debugstr_wn(str, len) );
@@ -108,6 +109,46 @@ static void input_context_set_comp_str( INPUTCONTEXT *ctx, BOOL result, const WC if (!(string = ImmLockIMCC( ctx->hCompStr ))) return; memset( string, 0, sizeof(COMPOSITIONSTRING) ); string->dwSize = sizeof(COMPOSITIONSTRING); + + if (!result && len) + { + string->dwCursorPos = min( len, old.dwCursorPos ); + + string->dwCompStrLen = len; + string->dwCompStrOffset = string->dwSize; + dst = (BYTE *)string + string->dwCompStrOffset; + memcpy( dst, str, len * sizeof(WCHAR) ); + string->dwSize += len * sizeof(WCHAR); + + string->dwCompClauseLen = 2 * sizeof(DWORD); + string->dwCompClauseOffset = string->dwSize; + dst = (BYTE *)string + string->dwCompClauseOffset; + *(DWORD *)(dst + 0 * sizeof(DWORD)) = 0; + *(DWORD *)(dst + 1 * sizeof(DWORD)) = len; + string->dwSize += 2 * sizeof(DWORD); + + string->dwCompAttrLen = len; + string->dwCompAttrOffset = string->dwSize; + dst = (BYTE *)string + string->dwCompAttrOffset; + memset( dst, ATTR_INPUT, len ); + string->dwSize += len; + } + else if (len) + { + string->dwResultStrLen = len; + string->dwResultStrOffset = string->dwSize; + dst = (BYTE *)string + string->dwResultStrOffset; + memcpy( dst, str, len * sizeof(WCHAR) ); + string->dwSize += len * sizeof(WCHAR); + + string->dwResultClauseLen = 2 * sizeof(DWORD); + string->dwResultClauseOffset = string->dwSize; + dst = (BYTE *)string + string->dwResultClauseOffset; + *(DWORD *)(dst + 0 * sizeof(DWORD)) = 0; + *(DWORD *)(dst + 1 * sizeof(DWORD)) = len; + string->dwSize += 2 * sizeof(DWORD); + } + ImmUnlockIMCC( ctx->hCompStr );
if (new_size < old.dwSize) @@ -364,6 +405,21 @@ static BOOL ime_set_composition_status( HIMC himc, HWND hwnd, BOOL new_status ) return old_status; }
+static BOOL ime_set_composition_text( HIMC himc, BOOL result, const WCHAR *str, UINT len ) +{ + DWORD flags = result ? GCS_RESULT : GCS_COMP | GCS_CURSORPOS | GCS_DELTASTART; + INPUTCONTEXT *ctx; + + TRACE( "himc %p, result %u, str %s\n", himc, result, debugstr_wn(str, len) ); + + if (!(ctx = ImmLockIMC( himc ))) return FALSE; + input_context_set_comp_str( ctx, result, str, len ); + ImmUnlockIMC( himc ); + + ime_send_message( himc, WM_IME_COMPOSITION, len ? str[0] : 0, flags ); + return TRUE; +} + static LRESULT WINAPI ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { HIMC himc = (HIMC)GetWindowLongPtrW( hwnd, IMMGWL_IMC ); @@ -422,6 +478,9 @@ static LRESULT WINAPI ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LP return ime_set_cursor_pos( himc, wparam ); case WM_WINE_IME_SET_COMP_STATUS: return ime_set_composition_status( himc, hwnd, wparam ); + case WM_WINE_IME_SET_COMP_TEXT: + return ime_set_composition_text( himc, !wparam, (const WCHAR *)lparam, + wcslen( (const WCHAR *)lparam ) ); }
return DefWindowProcW( hwnd, msg, wparam, lparam ); diff --git a/dlls/imm32/imm_private.h b/dlls/imm32/imm_private.h index 876d92d4aa2..8ea40e1fb27 100644 --- a/dlls/imm32/imm_private.h +++ b/dlls/imm32/imm_private.h @@ -65,6 +65,7 @@ static const char *debugstr_wm_ime( UINT msg ) case WM_WINE_IME_GET_CURSOR_POS: return "WM_WINE_IME_GET_CURSOR_POS"; case WM_WINE_IME_SET_CURSOR_POS: return "WM_WINE_IME_SET_CURSOR_POS"; case WM_WINE_IME_SET_COMP_STATUS: return "WM_WINE_IME_SET_COMP_STATUS"; + case WM_WINE_IME_SET_COMP_TEXT: return "WM_WINE_IME_SET_COMP_TEXT"; default: if (msg == WM_MSIME_SERVICE) return "WM_MSIME_SERVICE"; else if (msg == WM_MSIME_RECONVERTOPTIONS) return "WM_MSIME_RECONVERTOPTIONS"; diff --git a/dlls/winex11.drv/dllmain.c b/dlls/winex11.drv/dllmain.c index 8445c21470e..7c463d4e401 100644 --- a/dlls/winex11.drv/dllmain.c +++ b/dlls/winex11.drv/dllmain.c @@ -48,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, };
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 1ae39eb9edf..4ec37185751 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -49,8 +49,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(event); WINE_DECLARE_DEBUG_CHANNEL(xdnd);
-extern BOOL ximInComposeMode; - #define DndNotDnd -1 /* OffiX drag&drop */ #define DndUnknown 0 #define DndRawData 1 @@ -810,7 +808,7 @@ static void focus_out( Display *display , HWND hwnd ) int revert; XIC xic;
- if (ximInComposeMode) return; + if (xim_in_compose_mode) return;
x11drv_thread_data()->last_focus = hwnd; if ((xic = X11DRV_get_ic( hwnd ))) XUnsetICFocus( xic ); diff --git a/dlls/winex11.drv/ime.c b/dlls/winex11.drv/ime.c index 09440140568..a69ad81eff5 100644 --- a/dlls/winex11.drv/ime.c +++ b/dlls/winex11.drv/ime.c @@ -765,57 +765,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 ImeSetCompositionString(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; -} diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index b1c47d5258e..195cc65eddb 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1347,7 +1347,7 @@ BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
if (status == XLookupChars) { - X11DRV_XIMLookupChars( Str, ascii_chars ); + xim_set_result_string( hwnd, Str, ascii_chars ); if (buf != Str) free( Str ); return TRUE; diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h index 484ed4e5725..de044a9416c 100644 --- a/dlls/winex11.drv/unixlib.h +++ b/dlls/winex11.drv/unixlib.h @@ -83,8 +83,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 }; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 9efaae3465b..e007f07066a 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -453,6 +453,7 @@ extern int xrender_error_base DECLSPEC_HIDDEN; extern char *process_name DECLSPEC_HIDDEN; extern Display *clipboard_display DECLSPEC_HIDDEN; extern WNDPROC client_foreign_window_proc DECLSPEC_HIDDEN; +extern BOOL xim_in_compose_mode DECLSPEC_HIDDEN;
/* atoms */
@@ -823,7 +824,7 @@ extern struct x11drv_display_device_handler desktop_handler DECLSPEC_HIDDEN; /* XIM support */ extern BOOL xim_init( const WCHAR *input_style ) DECLSPEC_HIDDEN; extern void xim_thread_attach( struct x11drv_thread_data *data ) DECLSPEC_HIDDEN; -extern void X11DRV_XIMLookupChars( const char *str, UINT count ) DECLSPEC_HIDDEN; +extern void xim_set_result_string( HWND hwnd, const char *str, UINT count ) DECLSPEC_HIDDEN; extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN;
#define XEMBED_MAPPED (1 << 0) diff --git a/dlls/winex11.drv/x11drv_dll.h b/dlls/winex11.drv/x11drv_dll.h index a96e286ae83..fbd2a3e74b2 100644 --- a/dlls/winex11.drv/x11drv_dll.h +++ b/dlls/winex11.drv/x11drv_dll.h @@ -30,8 +30,6 @@ 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; diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index cba737c333f..25ddb9ea940 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -42,7 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(xim); #define XICProc XIMProc #endif
-BOOL ximInComposeMode=FALSE; +BOOL xim_in_compose_mode = FALSE;
static DWORD preedit_len = 0; static DWORD preedit_max = 0; @@ -79,11 +79,11 @@ static HWND get_builtin_ime_ui( HWND hwnd ) return (HWND)NtUserQueryInputContext( himc, NtUserInputContextBuiltinUI ); }
-static void xim_update_preedit_string( UINT offset, UINT old_len, WCHAR *text, UINT new_len ) +static void xim_update_preedit_string( HWND hwnd, UINT offset, UINT old_len, WCHAR *text, UINT new_len ) { int diff = new_len - old_len;
- TRACE( "offset %u, old_len %u, text %s\n", offset, old_len, debugstr_wn(text, new_len) ); + TRACE( "hwnd %p, offset %u, old_len %u, text %s\n", hwnd, offset, old_len, debugstr_wn(text, new_len) );
if (!preedit_buf || preedit_len + diff >= preedit_max) { @@ -105,21 +105,38 @@ static void xim_update_preedit_string( UINT offset, UINT old_len, WCHAR *text, U preedit_len += diff; preedit_buf[preedit_len] = 0;
- x11drv_client_func( client_func_ime_set_composition_string, preedit_buf, preedit_len * sizeof(WCHAR) ); + send_message( hwnd, WM_WINE_IME_SET_COMP_TEXT, TRUE, (LPARAM)preedit_buf ); }
-void X11DRV_XIMLookupChars( const char *str, UINT count ) +void xim_set_result_string( HWND hwnd, const char *str, UINT count ) { WCHAR *output; DWORD len;
- TRACE("%p %u\n", str, count); + TRACE( "hwnd %p, str %s\n", hwnd, debugstr_an(str, count) ); + + if (!(hwnd = get_builtin_ime_ui( hwnd ))) + { + WARN( "No builtin IME UI, ignoring event.\n" ); + return; + }
if (!(output = malloc( (count + 1) * sizeof(WCHAR) ))) return; len = ntdll_umbstowcs( str, count, output, count ); output[len] = 0;
- x11drv_client_func( client_func_ime_set_result, output, len * sizeof(WCHAR) ); + if (!xim_in_compose_mode) + { + send_message( hwnd, WM_WINE_IME_SET_OPEN_STATUS, TRUE, 0 ); + send_message( hwnd, WM_WINE_IME_SET_COMP_STATUS, TRUE, 0 ); + } + send_message( hwnd, WM_WINE_IME_SET_COMP_TEXT, FALSE, (LPARAM)output ); + if (!xim_in_compose_mode) + { + send_message( hwnd, WM_WINE_IME_SET_COMP_STATUS, FALSE, 0 ); + send_message( hwnd, WM_WINE_IME_SET_OPEN_STATUS, FALSE, 0 ); + } + free( output ); }
@@ -152,7 +169,7 @@ static int xic_preedit_start( XIC xic, XPointer user, XPointer arg )
TRACE( "xic %p, hwnd %p, arg %p\n", xic, hwnd, arg );
- ximInComposeMode = TRUE; + xim_in_compose_mode = TRUE;
if (!(hwnd = get_builtin_ime_ui( hwnd ))) WARN( "No builtin IME UI, ignoring event.\n" ); else send_message( hwnd, WM_WINE_IME_SET_COMP_STATUS, TRUE, 0 ); @@ -166,7 +183,7 @@ static int xic_preedit_done( XIC xic, XPointer user, XPointer arg )
TRACE( "xic %p, hwnd %p, arg %p\n", xic, hwnd, arg );
- ximInComposeMode = FALSE; + xim_in_compose_mode = FALSE; free( preedit_buf ); preedit_max = 0; preedit_len = 0; @@ -194,7 +211,7 @@ static int xic_preedit_draw( XIC xic, XPointer user, XPointer arg ) }
if (!(text = params->text)) - xim_update_preedit_string( params->chg_first, params->chg_length, NULL, 0 ); + xim_update_preedit_string( hwnd, params->chg_first, params->chg_length, NULL, 0 ); else { size_t text_len; @@ -214,7 +231,7 @@ static int xic_preedit_draw( XIC xic, XPointer user, XPointer arg ) if ((output = malloc( text_len * sizeof(WCHAR) ))) { text_len = ntdll_umbstowcs( str, text_len, output, text_len ); - xim_update_preedit_string( params->chg_first, params->chg_length, output, text_len ); + xim_update_preedit_string( hwnd, params->chg_first, params->chg_length, output, text_len ); free( output ); }
diff --git a/include/ntuser.h b/include/ntuser.h index e00bfaee44b..331b2b6b4a5 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -496,6 +496,7 @@ enum wine_internal_message #define WM_WINE_IME_GET_CURSOR_POS (WM_USER + 1) #define WM_WINE_IME_SET_CURSOR_POS (WM_USER + 2) #define WM_WINE_IME_SET_COMP_STATUS (WM_USER + 3) +#define WM_WINE_IME_SET_COMP_TEXT EM_REPLACESEL
/* internal IME private */ typedef struct ime_private