From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/imm.c | 35 ++++++++++++++++++++++++++--------- dlls/win32u/imm.c | 10 ++++++++++ include/ntuser.h | 1 + 3 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index d29684f34a2..42a6a568c1a 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -87,8 +87,6 @@ struct imc
struct ime *ime; UINT lastVK; - - HWND ui_hwnd; /* IME UI window, on the default input context */ };
#define WINE_IMC_VALID_MAGIC 0x56434D49 @@ -623,12 +621,25 @@ static INPUTCONTEXT *ime_find_input_context( struct ime *ime, HIMC himc ) return &entry->context; }
+static BOOL CALLBACK enum_set_ui_window( HIMC himc, LPARAM lparam ) +{ + NtUserUpdateInputContext( himc, NtUserInputContextUIHwnd, lparam ); + return TRUE; +} + static void imc_release_ime( struct imc *imc, struct ime *ime ) { + HIMC default_himc = UlongToHandle( NtUserGetThreadInfo()->default_imc ); INPUTCONTEXT *ctx; + HWND hwnd; + + if (imc->handle != default_himc) NtUserUpdateInputContext( imc->handle, NtUserInputContextUIHwnd, 0 ); + else if ((hwnd = (HWND)NtUserQueryInputContext( default_himc, NtUserInputContextUIHwnd ))) + { + DestroyWindow( hwnd ); + ImmEnumInputContext( 0, enum_set_ui_window, 0 ); + }
- if (imc->ui_hwnd) DestroyWindow( imc->ui_hwnd ); - imc->ui_hwnd = NULL; ime->pImeSelect( imc->handle, FALSE );
if ((ctx = ime_find_input_context( ime, imc->handle ))) *ctx = imc->IMC; @@ -651,11 +662,14 @@ static struct ime *imc_select_ime( struct imc *imc ) WARN( "Failed to acquire IME for HKL %p\n", hkl ); else { + HIMC default_himc = UlongToHandle( NtUserGetThreadInfo()->default_imc ); + HWND hwnd = (HWND)NtUserQueryInputContext( default_himc, NtUserInputContextUIHwnd ); INPUTCONTEXT *ctx;
if ((ctx = ime_find_input_context( imc->ime, imc->handle ))) imc->IMC = *ctx; else ime_save_input_context( imc->ime, imc->handle, &imc->IMC );
+ NtUserUpdateInputContext( imc->handle, NtUserInputContextUIHwnd, (LPARAM)hwnd ); imc->ime->pImeSelect( imc->handle, TRUE ); }
@@ -1010,16 +1024,19 @@ static HWND get_ime_ui_window(void) { struct imc *imc = default_input_context(); struct ime *ime; + HWND hwnd;
if (!(ime = imc_select_ime( imc ))) return 0;
- if (!imc->ui_hwnd) + if (!(hwnd = (HWND)NtUserQueryInputContext( imc->handle, NtUserInputContextUIHwnd ))) { - imc->ui_hwnd = CreateWindowExW( WS_EX_TOOLWINDOW, ime->ui_class, NULL, WS_POPUP, 0, 0, 1, 1, - ImmGetDefaultIMEWnd( 0 ), 0, ime->module, 0 ); - SetWindowLongPtrW( imc->ui_hwnd, IMMGWL_IMC, (LONG_PTR)imc->handle ); + hwnd = CreateWindowExW( WS_EX_TOOLWINDOW, ime->ui_class, NULL, WS_POPUP, 0, 0, 1, 1, + ImmGetDefaultIMEWnd( 0 ), 0, ime->module, 0 ); + SetWindowLongPtrW( hwnd, IMMGWL_IMC, (LONG_PTR)imc->handle ); + ImmEnumInputContext( 0, enum_set_ui_window, (LPARAM)hwnd ); } - return imc->ui_hwnd; + + return hwnd; }
/*********************************************************************** diff --git a/dlls/win32u/imm.c b/dlls/win32u/imm.c index 7dee4912e27..7be44306dda 100644 --- a/dlls/win32u/imm.c +++ b/dlls/win32u/imm.c @@ -40,6 +40,7 @@ struct imc struct user_object obj; DWORD thread_id; UINT_PTR client_ptr; + HWND ui_hwnd; };
struct imm_thread_data @@ -80,6 +81,7 @@ HIMC WINAPI NtUserCreateInputContext( UINT_PTR client_ptr ) if (!(imc = malloc( sizeof(*imc) ))) return 0; imc->client_ptr = client_ptr; imc->thread_id = GetCurrentThreadId(); + imc->ui_hwnd = 0; if (!(handle = alloc_user_handle( &imc->obj, NTUSER_OBJ_IMC ))) { free( imc ); @@ -127,6 +129,10 @@ BOOL WINAPI NtUserUpdateInputContext( HIMC handle, UINT attr, UINT_PTR value ) imc->client_ptr = value; break;
+ case NtUserInputContextUIHwnd: + imc->ui_hwnd = (HWND)value; + break; + default: FIXME( "unknown attr %u\n", attr ); ret = FALSE; @@ -156,6 +162,10 @@ UINT_PTR WINAPI NtUserQueryInputContext( HIMC handle, UINT attr ) ret = imc->thread_id; break;
+ case NtUserInputContextUIHwnd: + ret = (UINT_PTR)imc->ui_hwnd; + break; + default: FIXME( "unknown attr %u\n", attr ); ret = 0; diff --git a/include/ntuser.h b/include/ntuser.h index 3d43eb476e4..c398afa95e7 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -455,6 +455,7 @@ enum input_context_attr { NtUserInputContextClientPtr, NtUserInputContextThreadId, + NtUserInputContextUIHwnd, };
/* NtUserAssociateInputContext result */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/ime.c | 3 +++ dlls/imm32/imm_private.h | 1 + dlls/winex11.drv/dllmain.c | 1 - dlls/winex11.drv/ime.c | 9 --------- dlls/winex11.drv/unixlib.h | 1 - dlls/winex11.drv/x11drv_dll.h | 1 - dlls/winex11.drv/xim.c | 25 +++++++++++++++++-------- include/ntuser.h | 3 +++ 8 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/dlls/imm32/ime.c b/dlls/imm32/ime.c index 3c4550c3cd9..35edcfe7f46 100644 --- a/dlls/imm32/ime.c +++ b/dlls/imm32/ime.c @@ -291,6 +291,9 @@ static LRESULT WINAPI ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LP FIXME( "hwnd %p, himc %p, msg %s, wparam %s, lparam %#Ix stub!\n", hwnd, himc, debugstr_wm_ime(msg), debugstr_imc(wparam), lparam ); return 1; + + case WM_WINE_IME_SET_OPEN_STATUS: + return ImmSetOpenStatus( himc, wparam ); }
return DefWindowProcW( hwnd, msg, wparam, lparam ); diff --git a/dlls/imm32/imm_private.h b/dlls/imm32/imm_private.h index 8a957494ce9..eccfd223ac3 100644 --- a/dlls/imm32/imm_private.h +++ b/dlls/imm32/imm_private.h @@ -61,6 +61,7 @@ static const char *debugstr_wm_ime( UINT msg ) case WM_IME_REQUEST: return "WM_IME_REQUEST"; case WM_IME_KEYDOWN: return "WM_IME_KEYDOWN"; case WM_IME_KEYUP: return "WM_IME_KEYUP"; + case WM_WINE_IME_SET_OPEN_STATUS: return "WM_WINE_IME_SET_OPEN_STATUS"; 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 500a4a6bc44..54093d36b6e 100644 --- a/dlls/winex11.drv/dllmain.c +++ b/dlls/winex11.drv/dllmain.c @@ -33,7 +33,6 @@ static const callback_func callback_funcs[] = x11drv_ime_get_cursor_pos, x11drv_ime_set_composition_status, x11drv_ime_set_cursor_pos, - x11drv_ime_set_open_status, x11drv_ime_update_association, };
diff --git a/dlls/winex11.drv/ime.c b/dlls/winex11.drv/ime.c index 55485bfbfcf..72ada45f774 100644 --- a/dlls/winex11.drv/ime.c +++ b/dlls/winex11.drv/ime.c @@ -755,15 +755,6 @@ BOOL WINAPI ImeSetCompositionString(HIMC hIMC, DWORD dwIndex, LPCVOID lpComp,
/* Interfaces to XIM and other parts of winex11drv */
-NTSTATUS x11drv_ime_set_open_status( UINT open ) -{ - HIMC imc; - - imc = RealIMC(FROM_X11); - ImmSetOpenStatus(imc, open); - return 0; -} - NTSTATUS x11drv_ime_set_composition_status( UINT open ) { HIMC imc; diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h index 7dc1d9f0ca7..ed5dbac6535 100644 --- a/dlls/winex11.drv/unixlib.h +++ b/dlls/winex11.drv/unixlib.h @@ -99,7 +99,6 @@ enum client_callback client_ime_get_cursor_pos, client_ime_set_composition_status, client_ime_set_cursor_pos, - client_ime_set_open_status, client_ime_update_association, client_funcs_count }; diff --git a/dlls/winex11.drv/x11drv_dll.h b/dlls/winex11.drv/x11drv_dll.h index 047bb430d39..80fe9ab2a3d 100644 --- a/dlls/winex11.drv/x11drv_dll.h +++ b/dlls/winex11.drv/x11drv_dll.h @@ -39,7 +39,6 @@ extern NTSTATUS x11drv_dnd_leave_event( UINT arg ) DECLSPEC_HIDDEN; extern NTSTATUS x11drv_ime_get_cursor_pos( 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_set_open_status( UINT open ) DECLSPEC_HIDDEN; extern NTSTATUS x11drv_ime_update_association( UINT arg ) DECLSPEC_HIDDEN;
extern LRESULT WINAPI foreign_window_proc( HWND hwnd, UINT msg, WPARAM wparam, diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index b7f5f696ba5..f4c75d653cf 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -72,6 +72,21 @@ static const char *debugstr_xim_style( XIMStyle style ) return wine_dbg_sprintf( "%s", buffer ); }
+/* sends a message to the IME UI window */ +static LRESULT send_ime_ui_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + static const WCHAR WINE_IME_UI_CLASS[] = {'W','i','n','e',' ','I','M','E',0}; + WCHAR buffer[64]; + UNICODE_STRING name = {.Buffer = buffer, .MaximumLength = sizeof(buffer)}; + HIMC himc; + + if (!(himc = NtUserGetWindowInputContext( hwnd ))) return 0; + if (!(hwnd = (HWND)NtUserQueryInputContext( himc, NtUserInputContextUIHwnd ))) return 0; + if (!NtUserGetClassName( hwnd, 0, &name ) || wcscmp( buffer, WINE_IME_UI_CLASS )) return 0; + + return send_message( hwnd, msg, wparam, lparam ); +} + static void X11DRV_ImmSetInternalString(UINT offset, UINT selLength, LPWSTR lpComp, UINT len) { /* Composition strings are edited in chunks */ @@ -130,14 +145,8 @@ static BOOL xic_preedit_state_notify( XIC xic, XPointer user, XPointer arg )
switch (state) { - case XIMPreeditEnable: - x11drv_client_call( client_ime_set_open_status, TRUE ); - break; - case XIMPreeditDisable: - x11drv_client_call( client_ime_set_open_status, FALSE ); - break; - default: - break; + case XIMPreeditEnable: send_ime_ui_message( hwnd, WM_WINE_IME_SET_OPEN_STATUS, TRUE, 0 ); break; + case XIMPreeditDisable: send_ime_ui_message( hwnd, WM_WINE_IME_SET_OPEN_STATUS, FALSE, 0 ); break; }
return TRUE; diff --git a/include/ntuser.h b/include/ntuser.h index c398afa95e7..83349cb1929 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -491,6 +491,9 @@ enum wine_internal_message #define IME_INTERNAL_HKL_ACTIVATE 0x19 #define IME_INTERNAL_HKL_DEACTIVATE 0x20
+/* default IME UI messages */ +#define WM_WINE_IME_SET_OPEN_STATUS (WM_USER + 0) + /* internal IME private */ typedef struct ime_private {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/ime.c | 21 +++++++++++++++++++++ dlls/imm32/imm_private.h | 1 + dlls/winex11.drv/dllmain.c | 1 - dlls/winex11.drv/ime.c | 20 -------------------- dlls/winex11.drv/unixlib.h | 1 - dlls/winex11.drv/x11drv_dll.h | 1 - dlls/winex11.drv/xim.c | 2 +- include/ntuser.h | 1 + 8 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/dlls/imm32/ime.c b/dlls/imm32/ime.c index 35edcfe7f46..86834546a58 100644 --- a/dlls/imm32/ime.c +++ b/dlls/imm32/ime.c @@ -242,6 +242,25 @@ static void ime_ui_start_composition( HIMC himc, HWND hwnd ) ImmUnlockIMC( himc ); }
+static UINT ime_get_cursor_pos( HIMC himc ) +{ + COMPOSITIONSTRING *string; + INPUTCONTEXT *ctx; + UINT pos = 0; + + TRACE( "himc %p\n", himc ); + + if (!(ctx = ImmLockIMC( himc ))) return 0; + if ((string = ImmLockIMCC( ctx->hCompStr ))) + { + pos = string->dwCursorPos; + ImmUnlockIMCC( ctx->hCompStr ); + } + ImmUnlockIMC( himc ); + + return pos; +} + static LRESULT WINAPI ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { HIMC himc = (HIMC)GetWindowLongPtrW( hwnd, IMMGWL_IMC ); @@ -294,6 +313,8 @@ static LRESULT WINAPI ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LP
case WM_WINE_IME_SET_OPEN_STATUS: return ImmSetOpenStatus( himc, wparam ); + case WM_WINE_IME_GET_CURSOR_POS: + return ime_get_cursor_pos( himc ); }
return DefWindowProcW( hwnd, msg, wparam, lparam ); diff --git a/dlls/imm32/imm_private.h b/dlls/imm32/imm_private.h index eccfd223ac3..4a3afce09ba 100644 --- a/dlls/imm32/imm_private.h +++ b/dlls/imm32/imm_private.h @@ -62,6 +62,7 @@ static const char *debugstr_wm_ime( UINT msg ) case WM_IME_KEYDOWN: return "WM_IME_KEYDOWN"; case WM_IME_KEYUP: return "WM_IME_KEYUP"; case WM_WINE_IME_SET_OPEN_STATUS: return "WM_WINE_IME_SET_OPEN_STATUS"; + case WM_WINE_IME_GET_CURSOR_POS: return "WM_WINE_IME_GET_CURSOR_POS"; 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 54093d36b6e..a3375e60957 100644 --- a/dlls/winex11.drv/dllmain.c +++ b/dlls/winex11.drv/dllmain.c @@ -30,7 +30,6 @@ static const callback_func callback_funcs[] = { x11drv_dnd_drop_event, x11drv_dnd_leave_event, - x11drv_ime_get_cursor_pos, x11drv_ime_set_composition_status, x11drv_ime_set_cursor_pos, x11drv_ime_update_association, diff --git a/dlls/winex11.drv/ime.c b/dlls/winex11.drv/ime.c index 72ada45f774..b92c13ff08a 100644 --- a/dlls/winex11.drv/ime.c +++ b/dlls/winex11.drv/ime.c @@ -786,26 +786,6 @@ NTSTATUS x11drv_ime_set_composition_status( UINT open ) return 0; }
-NTSTATUS x11drv_ime_get_cursor_pos( UINT arg ) -{ - LPINPUTCONTEXT lpIMC; - INT rc = 0; - LPCOMPOSITIONSTRING compstr; - - if (!hSelectedFrom) - return rc; - - lpIMC = LockRealIMC(FROM_X11); - if (lpIMC) - { - compstr = ImmLockIMCC(lpIMC->hCompStr); - rc = compstr->dwCursorPos; - ImmUnlockIMCC(lpIMC->hCompStr); - } - UnlockRealIMC(FROM_X11); - return rc; -} - NTSTATUS x11drv_ime_set_cursor_pos( UINT pos ) { LPINPUTCONTEXT lpIMC; diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h index ed5dbac6535..332c4e4b3fa 100644 --- a/dlls/winex11.drv/unixlib.h +++ b/dlls/winex11.drv/unixlib.h @@ -96,7 +96,6 @@ enum client_callback { client_dnd_drop_event, client_dnd_leave_event, - client_ime_get_cursor_pos, client_ime_set_composition_status, client_ime_set_cursor_pos, client_ime_update_association, diff --git a/dlls/winex11.drv/x11drv_dll.h b/dlls/winex11.drv/x11drv_dll.h index 80fe9ab2a3d..2cc27abd362 100644 --- a/dlls/winex11.drv/x11drv_dll.h +++ b/dlls/winex11.drv/x11drv_dll.h @@ -36,7 +36,6 @@ extern NTSTATUS WINAPI x11drv_systray_change_owner( void *params, ULONG size ) D
extern NTSTATUS x11drv_dnd_drop_event( UINT arg ) DECLSPEC_HIDDEN; extern NTSTATUS x11drv_dnd_leave_event( UINT arg ) DECLSPEC_HIDDEN; -extern NTSTATUS x11drv_ime_get_cursor_pos( 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; diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index f4c75d653cf..46ec8680eb8 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -232,7 +232,7 @@ static int xic_preedit_caret( XIC xic, XPointer user, XPointer arg )
if (!params) return 0;
- pos = x11drv_client_call( client_ime_get_cursor_pos, 0 ); + pos = send_ime_ui_message( hwnd, WM_WINE_IME_GET_CURSOR_POS, 0, 0 ); switch (params->direction) { case XIMForwardChar: diff --git a/include/ntuser.h b/include/ntuser.h index 83349cb1929..813f407d46a 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -493,6 +493,7 @@ enum wine_internal_message
/* default IME UI messages */ #define WM_WINE_IME_SET_OPEN_STATUS (WM_USER + 0) +#define WM_WINE_IME_GET_CURSOR_POS (WM_USER + 1)
/* internal IME private */ typedef struct ime_private
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/ime.c | 42 +++++++++++++++++++++++++++++++++++ dlls/imm32/imm_private.h | 1 + dlls/winex11.drv/dllmain.c | 1 - dlls/winex11.drv/ime.c | 26 ---------------------- dlls/winex11.drv/unixlib.h | 1 - dlls/winex11.drv/x11drv_dll.h | 1 - dlls/winex11.drv/xim.c | 5 ++--- include/ntuser.h | 1 + 8 files changed, 46 insertions(+), 32 deletions(-)
diff --git a/dlls/imm32/ime.c b/dlls/imm32/ime.c index 86834546a58..77c485a2e83 100644 --- a/dlls/imm32/ime.c +++ b/dlls/imm32/ime.c @@ -93,6 +93,25 @@ static HFONT input_context_select_ui_font( INPUTCONTEXT *ctx, HDC hdc ) return font; }
+static void ime_send_message( HIMC himc, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + TRANSMSG *messages = NULL, message = {.message = msg, .wParam = wparam, .lParam = lparam}; + INPUTCONTEXT *ctx; + HIMCC tmp; + + TRACE( "himc %p, msg %#x, wparam %#Ix, lparam %#Ix\n", himc, msg, wparam, lparam ); + + if (!(ctx = ImmLockIMC( himc ))) return; + if (!(tmp = ImmReSizeIMCC( ctx->hMsgBuf, (ctx->dwNumMsgBuf + 1) * sizeof(message) ))) goto done; + if (!(messages = ImmLockIMCC( (ctx->hMsgBuf = tmp) ))) goto done; + messages[ctx->dwNumMsgBuf++] = message; + ImmUnlockIMCC( ctx->hMsgBuf ); + +done: + ImmUnlockIMC( himc ); + if (!messages || !ImmGenerateMessage( himc )) WARN( "Failed to generate himc %p messages, error %lu\n", himc, GetLastError() ); +} + static void ime_ui_paint( HIMC himc, HWND hwnd ) { PAINTSTRUCT ps; @@ -261,6 +280,27 @@ static UINT ime_get_cursor_pos( HIMC himc ) return pos; }
+static UINT ime_set_cursor_pos( HIMC himc, UINT new_pos ) +{ + COMPOSITIONSTRING *string; + INPUTCONTEXT *ctx; + UINT pos = 0; + + TRACE( "himc %p, new_pos %u\n", himc, new_pos ); + + if (!(ctx = ImmLockIMC( himc ))) return 0; + if ((string = ImmLockIMCC( ctx->hCompStr ))) + { + pos = string->dwCursorPos; + string->dwCursorPos = new_pos; + ImmUnlockIMCC( ctx->hCompStr ); + } + ImmUnlockIMC( himc ); + + if (pos != new_pos) ime_send_message( himc, WM_IME_COMPOSITION, new_pos, GCS_CURSORPOS ); + return pos; +} + static LRESULT WINAPI ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { HIMC himc = (HIMC)GetWindowLongPtrW( hwnd, IMMGWL_IMC ); @@ -315,6 +355,8 @@ static LRESULT WINAPI ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LP return ImmSetOpenStatus( himc, wparam ); case WM_WINE_IME_GET_CURSOR_POS: return ime_get_cursor_pos( himc ); + case WM_WINE_IME_SET_CURSOR_POS: + return ime_set_cursor_pos( himc, wparam ); }
return DefWindowProcW( hwnd, msg, wparam, lparam ); diff --git a/dlls/imm32/imm_private.h b/dlls/imm32/imm_private.h index 4a3afce09ba..b10d04d77ff 100644 --- a/dlls/imm32/imm_private.h +++ b/dlls/imm32/imm_private.h @@ -63,6 +63,7 @@ static const char *debugstr_wm_ime( UINT msg ) case WM_IME_KEYUP: return "WM_IME_KEYUP"; case WM_WINE_IME_SET_OPEN_STATUS: return "WM_WINE_IME_SET_OPEN_STATUS"; 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"; 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 a3375e60957..71fddfe4449 100644 --- a/dlls/winex11.drv/dllmain.c +++ b/dlls/winex11.drv/dllmain.c @@ -31,7 +31,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, };
diff --git a/dlls/winex11.drv/ime.c b/dlls/winex11.drv/ime.c index b92c13ff08a..cbf9c488f3a 100644 --- a/dlls/winex11.drv/ime.c +++ b/dlls/winex11.drv/ime.c @@ -786,32 +786,6 @@ NTSTATUS x11drv_ime_set_composition_status( UINT 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 ); diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h index 332c4e4b3fa..e48a2c61669 100644 --- a/dlls/winex11.drv/unixlib.h +++ b/dlls/winex11.drv/unixlib.h @@ -97,7 +97,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 }; diff --git a/dlls/winex11.drv/x11drv_dll.h b/dlls/winex11.drv/x11drv_dll.h index 2cc27abd362..5180969eeb7 100644 --- a/dlls/winex11.drv/x11drv_dll.h +++ b/dlls/winex11.drv/x11drv_dll.h @@ -37,7 +37,6 @@ extern NTSTATUS WINAPI x11drv_systray_change_owner( void *params, ULONG size ) D 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, diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 46ec8680eb8..0e8c1d1293a 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -217,8 +217,7 @@ static int xic_preedit_draw( XIC xic, XPointer user, XPointer arg ) if (str != text->string.multi_byte) free( str ); }
- x11drv_client_call( client_ime_set_cursor_pos, params->caret ); - + send_ime_ui_message( hwnd, WM_WINE_IME_SET_CURSOR_POS, params->caret, 0 ); return 0; }
@@ -260,7 +259,7 @@ 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 ); + send_ime_ui_message( hwnd, WM_WINE_IME_SET_CURSOR_POS, pos, 0 ); params->position = pos;
return 0; diff --git a/include/ntuser.h b/include/ntuser.h index 813f407d46a..6b6f3f0024e 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -494,6 +494,7 @@ enum wine_internal_message /* default IME UI messages */ #define WM_WINE_IME_SET_OPEN_STATUS (WM_USER + 0) #define WM_WINE_IME_GET_CURSOR_POS (WM_USER + 1) +#define WM_WINE_IME_SET_CURSOR_POS (WM_USER + 2)
/* internal IME private */ typedef struct ime_private
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/ime.c | 39 +++++++++++++++++++++++++++++++++++ dlls/imm32/imm_private.h | 1 + dlls/winex11.drv/dllmain.c | 1 - dlls/winex11.drv/ime.c | 31 ---------------------------- dlls/winex11.drv/unixlib.h | 1 - dlls/winex11.drv/x11drv_dll.h | 1 - dlls/winex11.drv/xim.c | 5 +++-- include/ntuser.h | 1 + 8 files changed, 44 insertions(+), 36 deletions(-)
diff --git a/dlls/imm32/ime.c b/dlls/imm32/ime.c index 77c485a2e83..762d1e29190 100644 --- a/dlls/imm32/ime.c +++ b/dlls/imm32/ime.c @@ -301,6 +301,43 @@ static UINT ime_set_cursor_pos( HIMC himc, UINT new_pos ) return pos; }
+static BOOL ime_set_composition_status( HIMC himc, HWND hwnd, BOOL new_status ) +{ + COMPOSITIONSTRING *string; + struct ime_private *priv; + BOOL old_status = FALSE; + INPUTCONTEXT *ctx; + HIMCC tmp; + + TRACE( "himc %p, hwnd %p, new_status %u\n", himc, hwnd, new_status ); + + if (!(ctx = ImmLockIMC( himc ))) return 0; + if ((priv = ImmLockIMCC( ctx->hPrivate ))) + { + old_status = priv->bInComposition; + priv->bInComposition = new_status; + ImmUnlockIMCC( ctx->hPrivate ); + } + ImmUnlockIMC( himc ); + + if (new_status == old_status) return old_status; + if (old_status) ShowWindow( hwnd, SW_HIDE ); + + if (!(ctx = ImmLockIMC( himc ))) return old_status; + if (!new_status && (string = ImmLockIMCC( ctx->hCompStr ))) + { + memset( string, 0, sizeof(COMPOSITIONSTRING) ); + string->dwSize = sizeof(COMPOSITIONSTRING); + ImmUnlockIMCC( ctx->hCompStr ); + if ((tmp = ImmReSizeIMCC( ctx->hCompStr, sizeof(COMPOSITIONSTRING) ))) ctx->hCompStr = tmp; + else WARN( "Failed to shrink composition string for himc %p\n", himc ); + } + ImmUnlockIMC( himc ); + + ime_send_message( himc, new_status ? WM_IME_STARTCOMPOSITION : WM_IME_ENDCOMPOSITION, 0, 0 ); + return old_status; +} + static LRESULT WINAPI ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { HIMC himc = (HIMC)GetWindowLongPtrW( hwnd, IMMGWL_IMC ); @@ -357,6 +394,8 @@ static LRESULT WINAPI ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LP return ime_get_cursor_pos( himc ); case WM_WINE_IME_SET_CURSOR_POS: return ime_set_cursor_pos( himc, wparam ); + case WM_WINE_IME_SET_COMP_STATUS: + return ime_set_composition_status( himc, hwnd, wparam ); }
return DefWindowProcW( hwnd, msg, wparam, lparam ); diff --git a/dlls/imm32/imm_private.h b/dlls/imm32/imm_private.h index b10d04d77ff..876d92d4aa2 100644 --- a/dlls/imm32/imm_private.h +++ b/dlls/imm32/imm_private.h @@ -64,6 +64,7 @@ static const char *debugstr_wm_ime( UINT msg ) case WM_WINE_IME_SET_OPEN_STATUS: return "WM_WINE_IME_SET_OPEN_STATUS"; 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"; 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 71fddfe4449..8445c21470e 100644 --- a/dlls/winex11.drv/dllmain.c +++ b/dlls/winex11.drv/dllmain.c @@ -30,7 +30,6 @@ static const callback_func callback_funcs[] = { x11drv_dnd_drop_event, x11drv_dnd_leave_event, - x11drv_ime_set_composition_status, x11drv_ime_update_association, };
diff --git a/dlls/winex11.drv/ime.c b/dlls/winex11.drv/ime.c index cbf9c488f3a..09440140568 100644 --- a/dlls/winex11.drv/ime.c +++ b/dlls/winex11.drv/ime.c @@ -755,37 +755,6 @@ BOOL WINAPI ImeSetCompositionString(HIMC hIMC, DWORD dwIndex, LPCVOID lpComp,
/* Interfaces to XIM and other parts of winex11drv */
-NTSTATUS x11drv_ime_set_composition_status( UINT open ) -{ - HIMC imc; - LPINPUTCONTEXT lpIMC; - LPIMEPRIVATE myPrivate; - - imc = RealIMC(FROM_X11); - lpIMC = ImmLockIMC(imc); - if (lpIMC == NULL) - return 0; - - myPrivate = ImmLockIMCC(lpIMC->hPrivate); - - if (open && !myPrivate->bInComposition) - { - GenerateIMEMessage(imc, WM_IME_STARTCOMPOSITION, 0, 0); - } - else if (!open && myPrivate->bInComposition) - { - ShowWindow(myPrivate->hwndDefault, SW_HIDE); - ImmDestroyIMCC(lpIMC->hCompStr); - lpIMC->hCompStr = ImeCreateBlankCompStr(); - GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0); - } - myPrivate->bInComposition = open; - - ImmUnlockIMCC(lpIMC->hPrivate); - ImmUnlockIMC(imc); - return 0; -} - NTSTATUS x11drv_ime_update_association( UINT arg ) { HWND focus = UlongToHandle( arg ); diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h index e48a2c61669..484ed4e5725 100644 --- a/dlls/winex11.drv/unixlib.h +++ b/dlls/winex11.drv/unixlib.h @@ -96,7 +96,6 @@ enum client_callback { client_dnd_drop_event, client_dnd_leave_event, - client_ime_set_composition_status, client_ime_update_association, client_funcs_count }; diff --git a/dlls/winex11.drv/x11drv_dll.h b/dlls/winex11.drv/x11drv_dll.h index 5180969eeb7..a96e286ae83 100644 --- a/dlls/winex11.drv/x11drv_dll.h +++ b/dlls/winex11.drv/x11drv_dll.h @@ -36,7 +36,6 @@ extern NTSTATUS WINAPI x11drv_systray_change_owner( void *params, ULONG size ) D
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_update_association( UINT arg ) DECLSPEC_HIDDEN;
extern LRESULT WINAPI foreign_window_proc( HWND hwnd, UINT msg, WPARAM wparam, diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 0e8c1d1293a..a7e2a0a2c26 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -158,7 +158,7 @@ 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 ); + send_ime_ui_message( hwnd, WM_WINE_IME_SET_COMP_STATUS, TRUE, 0 ); ximInComposeMode = TRUE; return -1; } @@ -175,7 +175,8 @@ static int xic_preedit_done( XIC xic, XPointer user, XPointer arg ) dwCompStringSize = 0; dwCompStringLength = 0; CompositionString = NULL; - x11drv_client_call( client_ime_set_composition_status, FALSE ); + + send_ime_ui_message( hwnd, WM_WINE_IME_SET_COMP_STATUS, FALSE, 0 ); return 0; }
diff --git a/include/ntuser.h b/include/ntuser.h index 6b6f3f0024e..343c98a9ff7 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -495,6 +495,7 @@ enum wine_internal_message #define WM_WINE_IME_SET_OPEN_STATUS (WM_USER + 0) #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)
/* internal IME private */ typedef struct ime_private
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/xim.c | 54 ++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 31 deletions(-)
diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index a7e2a0a2c26..61998c22ad2 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -44,10 +44,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(xim);
BOOL ximInComposeMode=FALSE;
-/* moved here from imm32 for dll separation */ -static DWORD dwCompStringLength = 0; -static LPBYTE CompositionString = NULL; -static DWORD dwCompStringSize = 0; +static DWORD preedit_len = 0; +static DWORD preedit_max = 0; +static WCHAR *preedit_buf = NULL;
static XIMStyle input_style = 0; static XIMStyle input_style_req = XIMPreeditCallbacks | XIMStatusCallbacks; @@ -87,38 +86,32 @@ static LRESULT send_ime_ui_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l return send_message( hwnd, msg, wparam, lparam ); }
-static void X11DRV_ImmSetInternalString(UINT offset, UINT selLength, LPWSTR lpComp, UINT len) +static void xim_update_preedit_string( UINT offset, UINT old_len, WCHAR *text, UINT new_len ) { - /* Composition strings are edited in chunks */ - unsigned int byte_length = len * sizeof(WCHAR); - unsigned int byte_offset = offset * sizeof(WCHAR); - unsigned int byte_selection = selLength * sizeof(WCHAR); - int byte_expansion = byte_length - byte_selection; - LPBYTE ptr_new; + int diff = new_len - old_len;
- TRACE("( %i, %i, %p, %d):\n", offset, selLength, lpComp, len ); + TRACE( "offset %u, old_len %u, text %s\n", offset, old_len, debugstr_wn(text, new_len) );
- if (byte_expansion + dwCompStringLength >= dwCompStringSize) + if (preedit_len + diff >= preedit_max) { - ptr_new = realloc( CompositionString, dwCompStringSize + byte_expansion ); - if (ptr_new == NULL) + WCHAR *tmp; + + if (!(tmp = realloc( preedit_buf, (preedit_max + diff) * sizeof(WCHAR) ))) { ERR("Couldn't expand composition string buffer\n"); return; }
- CompositionString = ptr_new; - dwCompStringSize += byte_expansion; + preedit_buf = tmp; + preedit_max += diff; }
- ptr_new = CompositionString + byte_offset; - memmove(ptr_new + byte_length, ptr_new + byte_selection, - dwCompStringLength - byte_offset - byte_selection); - if (lpComp) memcpy(ptr_new, lpComp, byte_length); - dwCompStringLength += byte_expansion; + memmove( preedit_buf + offset + new_len, preedit_buf + offset + old_len, + (preedit_len - offset - old_len) * sizeof(WCHAR) ); + if (text) memcpy( preedit_buf + offset, text, new_len * sizeof(WCHAR) ); + preedit_len += diff;
- x11drv_client_func( client_func_ime_set_composition_string, - CompositionString, dwCompStringLength ); + x11drv_client_func( client_func_ime_set_composition_string, preedit_buf, preedit_len * sizeof(WCHAR) ); }
void X11DRV_XIMLookupChars( const char *str, UINT count ) @@ -170,11 +163,10 @@ static int xic_preedit_done( XIC xic, XPointer user, XPointer arg ) TRACE( "xic %p, hwnd %p, arg %p\n", xic, hwnd, arg );
ximInComposeMode = FALSE; - if (dwCompStringSize) - free( CompositionString ); - dwCompStringSize = 0; - dwCompStringLength = 0; - CompositionString = NULL; + free( preedit_buf ); + preedit_max = 0; + preedit_len = 0; + preedit_buf = NULL;
send_ime_ui_message( hwnd, WM_WINE_IME_SET_COMP_STATUS, FALSE, 0 ); return 0; @@ -191,7 +183,7 @@ static int xic_preedit_draw( XIC xic, XPointer user, XPointer arg ) if (!params) return 0;
if (!(text = params->text)) - X11DRV_ImmSetInternalString( params->chg_first, params->chg_length, NULL, 0 ); + xim_update_preedit_string( params->chg_first, params->chg_length, NULL, 0 ); else { size_t text_len; @@ -211,7 +203,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 ); - X11DRV_ImmSetInternalString( params->chg_first, params->chg_length, output, text_len ); + xim_update_preedit_string( params->chg_first, params->chg_length, output, text_len ); free( output ); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/xim.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 61998c22ad2..500d2924d77 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -92,11 +92,11 @@ static void xim_update_preedit_string( UINT offset, UINT old_len, WCHAR *text, U
TRACE( "offset %u, old_len %u, text %s\n", offset, old_len, debugstr_wn(text, new_len) );
- if (preedit_len + diff >= preedit_max) + if (!preedit_buf || preedit_len + diff >= preedit_max) { WCHAR *tmp;
- if (!(tmp = realloc( preedit_buf, (preedit_max + diff) * sizeof(WCHAR) ))) + if (!(tmp = realloc( preedit_buf, (preedit_max + diff + 1) * sizeof(WCHAR) ))) { ERR("Couldn't expand composition string buffer\n"); return; @@ -110,6 +110,7 @@ static void xim_update_preedit_string( UINT offset, UINT old_len, WCHAR *text, U (preedit_len - offset - old_len) * sizeof(WCHAR) ); if (text) memcpy( preedit_buf + offset, text, new_len * sizeof(WCHAR) ); preedit_len += diff; + preedit_buf[preedit_len] = 0;
x11drv_client_func( client_func_ime_set_composition_string, preedit_buf, preedit_len * sizeof(WCHAR) ); } @@ -121,8 +122,9 @@ void X11DRV_XIMLookupChars( const char *str, UINT count )
TRACE("%p %u\n", str, count);
- if (!(output = malloc( count * sizeof(WCHAR) ))) 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) ); free( output );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/ime.c | 111 +++++++++++++++++++++++++++++++++- dlls/imm32/imm_private.h | 1 + dlls/winex11.drv/dllmain.c | 2 - dlls/winex11.drv/ime.c | 54 ----------------- dlls/winex11.drv/keyboard.c | 2 +- dlls/winex11.drv/unixlib.h | 2 - dlls/winex11.drv/x11drv.h | 2 +- dlls/winex11.drv/x11drv_dll.h | 2 - dlls/winex11.drv/xim.c | 17 +++--- include/ntuser.h | 1 + 10 files changed, 122 insertions(+), 72 deletions(-)
diff --git a/dlls/imm32/ime.c b/dlls/imm32/ime.c index 762d1e29190..9c80c05121d 100644 --- a/dlls/imm32/ime.c +++ b/dlls/imm32/ime.c @@ -83,6 +83,86 @@ static WCHAR *input_context_get_comp_str( INPUTCONTEXT *ctx, BOOL result, UINT * return text; }
+static DWORD input_context_set_comp_str( INPUTCONTEXT *ctx, BOOL result, const WCHAR *str, SIZE_T len ) +{ + DWORD flags = result ? GCS_RESULTSTR : GCS_COMPSTR; + UINT new_size = sizeof(COMPOSITIONSTRING); + COMPOSITIONSTRING old, *comp; + BYTE *dst; + + TRACE( "ctx %p, result %u, str %s\n", ctx, result, debugstr_wn(str, len) ); + + new_size += len * sizeof(WCHAR); + if (len) new_size += 2 * sizeof(DWORD); + if (!result) new_size += len; + + if (!(comp = ImmLockIMCC( ctx->hCompStr ))) goto error; + old = *comp; + ImmUnlockIMCC( ctx->hCompStr ); + + if (new_size > old.dwSize && !(ctx->hCompStr = ImmReSizeIMCC( ctx->hCompStr, new_size ))) goto error; + + if (!(comp = ImmLockIMCC( ctx->hCompStr ))) goto error; + memset( comp, 0, sizeof(COMPOSITIONSTRING) ); + comp->dwSize = sizeof(COMPOSITIONSTRING); + + if (!result && len) + { + comp->dwCursorPos = min( len, old.dwCursorPos ); + + comp->dwCompStrLen = len; + comp->dwCompStrOffset = comp->dwSize; + dst = (BYTE *)comp + comp->dwCompStrOffset; + memcpy( dst, str, len * sizeof(WCHAR) ); + comp->dwSize += len * sizeof(WCHAR); + + comp->dwCompClauseLen = 2 * sizeof(DWORD); + comp->dwCompClauseOffset = comp->dwSize; + dst = (BYTE *)comp + comp->dwCompClauseOffset; + *(DWORD *)(dst + 0 * sizeof(DWORD)) = 0; + *(DWORD *)(dst + 1 * sizeof(DWORD)) = len; + comp->dwSize += 2 * sizeof(DWORD); + + comp->dwCompAttrLen = len; + comp->dwCompAttrOffset = comp->dwSize; + dst = (BYTE *)comp + comp->dwCompAttrOffset; + memset( dst, ATTR_INPUT, len ); + comp->dwSize += len; + } + else if (len) + { + comp->dwResultStrLen = len; + comp->dwResultStrOffset = comp->dwSize; + dst = (BYTE *)comp + comp->dwResultStrOffset; + memcpy( dst, str, len * sizeof(WCHAR) ); + comp->dwSize += len * sizeof(WCHAR); + + comp->dwResultClauseLen = 2 * sizeof(DWORD); + comp->dwResultClauseOffset = comp->dwSize; + dst = (BYTE *)comp + comp->dwResultClauseOffset; + *(DWORD *)(dst + 0 * sizeof(DWORD)) = 0; + *(DWORD *)(dst + 1 * sizeof(DWORD)) = len; + comp->dwSize += 2 * sizeof(DWORD); + } + + if (comp->dwCursorPos != old.dwCursorPos) flags |= GCS_CURSORPOS; + if (comp->dwDeltaStart != old.dwDeltaStart) flags |= GCS_DELTASTART; + if (comp->dwCompStrLen != old.dwCompStrLen) flags |= GCS_COMPSTR; + if (comp->dwCompAttrLen != old.dwCompAttrLen) flags |= GCS_COMPATTR; + if (comp->dwCompClauseLen != old.dwCompClauseLen) flags |= GCS_COMPCLAUSE; + if (comp->dwResultStrLen != old.dwResultStrLen) flags |= GCS_RESULTSTR; + if (comp->dwResultClauseLen != old.dwResultClauseLen) flags |= GCS_RESULTCLAUSE; + + ImmUnlockIMCC( ctx->hCompStr ); + + if (new_size < old.dwSize && !(ctx->hCompStr = ImmReSizeIMCC( ctx->hCompStr, new_size ))) goto error; + return flags; + +error: + WARN( "Failed to update result string, error %lu\n", GetLastError() ); + return 0; +} + static HFONT input_context_select_ui_font( INPUTCONTEXT *ctx, HDC hdc ) { struct ime_private *priv; @@ -338,6 +418,33 @@ static BOOL ime_set_composition_status( HIMC himc, HWND hwnd, BOOL new_status ) return old_status; }
+static BOOL ime_set_composition_text( HIMC himc, HWND hwnd, BOOL result, const WCHAR *str, UINT len ) +{ + struct ime_private *priv; + BOOL old_status = FALSE; + INPUTCONTEXT *ctx; + DWORD flags; + + TRACE( "old_status %u, himc %p, result %u, str %s\n", old_status, himc, result, debugstr_wn(str, len) ); + + if (!(ctx = ImmLockIMC( himc ))) return FALSE; + if ((priv = ImmLockIMCC( ctx->hPrivate ))) + { + old_status = priv->bInComposition; + ImmUnlockIMCC( ctx->hPrivate ); + } + flags = input_context_set_comp_str( ctx, result, str, len ); + ImmUnlockIMC( himc ); + + if (!old_status) ImmSetOpenStatus( himc, TRUE ); + if (!result || !old_status) ime_set_composition_status( himc, hwnd, TRUE ); + ime_send_message( himc, WM_IME_COMPOSITION, len ? str[0] : 0, flags ); + if (result || !old_status) ime_set_composition_status( himc, hwnd, FALSE ); + if (!old_status) ImmSetOpenStatus( himc, FALSE ); + + return TRUE; +} + static LRESULT WINAPI ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { HIMC himc = (HIMC)GetWindowLongPtrW( hwnd, IMMGWL_IMC ); @@ -352,8 +459,6 @@ static LRESULT WINAPI ime_ui_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LP { struct ime_private *priv;
- SetWindowTextA( hwnd, "Wine Ime Active" ); - if (!(ctx = ImmLockIMC( himc ))) return TRUE; if ((priv = ImmLockIMCC( ctx->hPrivate ))) { @@ -396,6 +501,8 @@ 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, hwnd, !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/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..d4581e21298 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -823,7 +823,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 500d2924d77..c62fce18c80 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -86,11 +86,11 @@ static LRESULT send_ime_ui_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l return send_message( hwnd, msg, wparam, lparam ); }
-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) { @@ -112,21 +112,22 @@ 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_ime_ui_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 (!(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) ); + send_ime_ui_message( hwnd, WM_WINE_IME_SET_COMP_TEXT, FALSE, (LPARAM)output ); + free( output ); }
@@ -185,7 +186,7 @@ static int xic_preedit_draw( XIC xic, XPointer user, XPointer arg ) if (!params) return 0;
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; @@ -205,7 +206,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 343c98a9ff7..0835606e159 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
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/ime.c | 435 +++++++++-------------------------------- 1 file changed, 90 insertions(+), 345 deletions(-)
diff --git a/dlls/winex11.drv/ime.c b/dlls/winex11.drv/ime.c index a69ad81eff5..f8d4a6a64c3 100644 --- a/dlls/winex11.drv/ime.c +++ b/dlls/winex11.drv/ime.c @@ -73,6 +73,86 @@ static WCHAR *input_context_get_comp_str( INPUTCONTEXT *ctx, BOOL result, UINT * return text; }
+static DWORD input_context_set_comp_str( INPUTCONTEXT *ctx, BOOL result, const WCHAR *str, SIZE_T len ) +{ + DWORD flags = result ? GCS_RESULTSTR : GCS_COMPSTR; + UINT new_size = sizeof(COMPOSITIONSTRING); + COMPOSITIONSTRING old, *comp; + BYTE *dst; + + TRACE( "ctx %p, result %u, str %s\n", ctx, result, debugstr_wn(str, len) ); + + new_size += len * sizeof(WCHAR); + if (len) new_size += 2 * sizeof(DWORD); + if (!result) new_size += len; + + if (!(comp = ImmLockIMCC( ctx->hCompStr ))) goto error; + old = *comp; + ImmUnlockIMCC( ctx->hCompStr ); + + if (new_size > old.dwSize && !(ctx->hCompStr = ImmReSizeIMCC( ctx->hCompStr, new_size ))) goto error; + + if (!(comp = ImmLockIMCC( ctx->hCompStr ))) goto error; + memset( comp, 0, sizeof(COMPOSITIONSTRING) ); + comp->dwSize = sizeof(COMPOSITIONSTRING); + + if (!result && len) + { + comp->dwCursorPos = min( len, old.dwCursorPos ); + + comp->dwCompStrLen = len; + comp->dwCompStrOffset = comp->dwSize; + dst = (BYTE *)comp + comp->dwCompStrOffset; + memcpy( dst, str, len * sizeof(WCHAR) ); + comp->dwSize += len * sizeof(WCHAR); + + comp->dwCompClauseLen = 2 * sizeof(DWORD); + comp->dwCompClauseOffset = comp->dwSize; + dst = (BYTE *)comp + comp->dwCompClauseOffset; + *(DWORD *)(dst + 0 * sizeof(DWORD)) = 0; + *(DWORD *)(dst + 1 * sizeof(DWORD)) = len; + comp->dwSize += 2 * sizeof(DWORD); + + comp->dwCompAttrLen = len; + comp->dwCompAttrOffset = comp->dwSize; + dst = (BYTE *)comp + comp->dwCompAttrOffset; + memset( dst, ATTR_INPUT, len ); + comp->dwSize += len; + } + else if (len) + { + comp->dwResultStrLen = len; + comp->dwResultStrOffset = comp->dwSize; + dst = (BYTE *)comp + comp->dwResultStrOffset; + memcpy( dst, str, len * sizeof(WCHAR) ); + comp->dwSize += len * sizeof(WCHAR); + + comp->dwResultClauseLen = 2 * sizeof(DWORD); + comp->dwResultClauseOffset = comp->dwSize; + dst = (BYTE *)comp + comp->dwResultClauseOffset; + *(DWORD *)(dst + 0 * sizeof(DWORD)) = 0; + *(DWORD *)(dst + 1 * sizeof(DWORD)) = len; + comp->dwSize += 2 * sizeof(DWORD); + } + + if (comp->dwCursorPos != old.dwCursorPos) flags |= GCS_CURSORPOS; + if (comp->dwDeltaStart != old.dwDeltaStart) flags |= GCS_DELTASTART; + if (comp->dwCompStrLen != old.dwCompStrLen) flags |= GCS_COMPSTR; + if (comp->dwCompAttrLen != old.dwCompAttrLen) flags |= GCS_COMPATTR; + if (comp->dwCompClauseLen != old.dwCompClauseLen) flags |= GCS_COMPCLAUSE; + if (comp->dwResultStrLen != old.dwResultStrLen) flags |= GCS_RESULTSTR; + if (comp->dwResultClauseLen != old.dwResultClauseLen) flags |= GCS_RESULTCLAUSE; + + ImmUnlockIMCC( ctx->hCompStr ); + + if (new_size < old.dwSize && !(ctx->hCompStr = ImmReSizeIMCC( ctx->hCompStr, new_size ))) goto error; + return flags; + +error: + WARN( "Failed to update result string, error %lu\n", GetLastError() ); + return 0; +} + static HIMC RealIMC(HIMC hIMC) { if (hIMC == FROM_X11) @@ -119,309 +199,6 @@ static HIMCC ImeCreateBlankCompStr(void) return rc; }
-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) { @@ -601,42 +378,25 @@ BOOL WINAPI NotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue) { case CPS_COMPLETE: { - HIMCC newCompStr; LPIMEPRIVATE myPrivate; WCHAR *str; UINT len;
TRACE("CPS_COMPLETE\n");
- /* clear existing result */ - newCompStr = updateResultStr(lpIMC->hCompStr, NULL, 0); - - ImmDestroyIMCC(lpIMC->hCompStr); - lpIMC->hCompStr = newCompStr; - myPrivate = ImmLockIMCC(lpIMC->hPrivate); if ((str = input_context_get_comp_str( lpIMC, FALSE, &len ))) { - WCHAR param = str[0]; - - newCompStr = updateResultStr( lpIMC->hCompStr, str, len ); - ImmDestroyIMCC(lpIMC->hCompStr); - lpIMC->hCompStr = newCompStr; - newCompStr = updateCompStr(lpIMC->hCompStr, NULL, 0); - ImmDestroyIMCC(lpIMC->hCompStr); - lpIMC->hCompStr = newCompStr; - - GenerateIMEMessage(hIMC, WM_IME_COMPOSITION, 0, - GCS_COMPSTR); - - GenerateIMEMessage(hIMC, WM_IME_COMPOSITION, param, - GCS_RESULTSTR|GCS_RESULTCLAUSE); - + DWORD flags = input_context_set_comp_str( lpIMC, TRUE, str, len ); + GenerateIMEMessage(hIMC, WM_IME_COMPOSITION, str[0], flags ); GenerateIMEMessage(hIMC,WM_IME_ENDCOMPOSITION, 0, 0); free( str ); } - else if (myPrivate->bInComposition) - GenerateIMEMessage(hIMC,WM_IME_ENDCOMPOSITION, 0, 0); + else + { + input_context_set_comp_str( lpIMC, TRUE, NULL, 0 ); + if (myPrivate->bInComposition) GenerateIMEMessage(hIMC,WM_IME_ENDCOMPOSITION, 0, 0); + }
myPrivate->bInComposition = FALSE; ImmUnlockIMCC(lpIMC->hPrivate); @@ -714,35 +474,20 @@ BOOL WINAPI ImeSetCompositionString(HIMC hIMC, DWORD dwIndex, LPCVOID lpComp,
if (dwIndex == SCS_SETSTR) { - HIMCC newCompStr; - if (!myPrivate->bInComposition) { GenerateIMEMessage(hIMC, WM_IME_STARTCOMPOSITION, 0, 0); myPrivate->bInComposition = TRUE; }
- /* clear existing result */ - newCompStr = updateResultStr(lpIMC->hCompStr, NULL, 0); - ImmDestroyIMCC(lpIMC->hCompStr); - lpIMC->hCompStr = newCompStr; - - flags = GCS_COMPSTR; - if (dwCompLen && lpComp) { - newCompStr = updateCompStr(lpIMC->hCompStr, (LPCWSTR)lpComp, dwCompLen / sizeof(WCHAR)); - ImmDestroyIMCC(lpIMC->hCompStr); - lpIMC->hCompStr = newCompStr; - - wParam = ((const WCHAR*)lpComp)[0]; - flags |= GCS_COMPCLAUSE | GCS_COMPATTR | GCS_DELTASTART; + flags = input_context_set_comp_str( lpIMC, FALSE, lpComp, dwCompLen / sizeof(WCHAR) ); + wParam = ((const WCHAR*)lpComp)[0]; } else { - newCompStr = updateCompStr(lpIMC->hCompStr, NULL, 0); - ImmDestroyIMCC(lpIMC->hCompStr); - lpIMC->hCompStr = newCompStr; + flags = input_context_set_comp_str( lpIMC, FALSE, NULL, 0 ); } }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=131814
Your paranoid android.
=== debian11 (32 bit report) ===
win32u: win32u.c:284: Test failed: NtUserUpdateInputContext 2 succeeded win32u.c:306: Test failed: NtUserQueryInputContext 2 returned 0xdeadbeef
=== debian11 (32 bit zh:CN report) ===
win32u: win32u.c:284: Test failed: NtUserUpdateInputContext 2 succeeded win32u.c:306: Test failed: NtUserQueryInputContext 2 returned 0xdeadbeef
=== debian11b (64 bit WoW report) ===
win32u: win32u.c:284: Test failed: NtUserUpdateInputContext 2 succeeded win32u.c:306: Test failed: NtUserQueryInputContext 2 returned 0xdeadbeef