From: Rémi Bernon rbernon@codeweavers.com
--- dlls/imm32/ime.c | 70 +++++++++++++++++++++++++++++++++++ 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 | 10 ++++- include/ntuser.h | 1 + 8 files changed, 80 insertions(+), 36 deletions(-)
diff --git a/dlls/imm32/ime.c b/dlls/imm32/ime.c index 77c485a2e83..77a5be5a97c 100644 --- a/dlls/imm32/ime.c +++ b/dlls/imm32/ime.c @@ -83,6 +83,45 @@ 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 ) +{ + UINT new_size = sizeof(COMPOSITIONSTRING); + COMPOSITIONSTRING old, *string; + HIMCC tmp; + + 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 (!(string = ImmLockIMCC( ctx->hCompStr ))) goto error; + old = *string; + ImmUnlockIMCC( ctx->hCompStr ); + + if (new_size > old.dwSize) + { + if (!(tmp = ImmReSizeIMCC( ctx->hCompStr, new_size ))) goto error; + ctx->hCompStr = tmp; + } + + if (!(string = ImmLockIMCC( ctx->hCompStr ))) goto error; + memset( string, 0, sizeof(COMPOSITIONSTRING) ); + string->dwSize = sizeof(COMPOSITIONSTRING); + ImmUnlockIMCC( ctx->hCompStr ); + + if (new_size < old.dwSize) + { + if (!(tmp = ImmReSizeIMCC( ctx->hCompStr, new_size ))) goto error; + ctx->hCompStr = tmp; + } + return 0; + +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; @@ -301,6 +340,35 @@ 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 ) +{ + struct ime_private *priv; + BOOL old_status = FALSE; + INPUTCONTEXT *ctx; + + 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 ); + } + if (new_status != old_status) input_context_set_comp_str( ctx, TRUE, NULL, 0 ); + ImmUnlockIMC( himc ); + + if (old_status < new_status) + ime_send_message( himc, WM_IME_STARTCOMPOSITION, 0, 0 ); + else if (old_status > new_status) + { + ShowWindow( hwnd, SW_HIDE ); + ime_send_message( himc, 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 +425,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 af9846661af..327ab6b5ce2 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -157,8 +157,11 @@ 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 ); ximInComposeMode = 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 ); + return -1; }
@@ -174,7 +177,10 @@ 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 ); + + 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, FALSE, 0 ); + return 0; }
diff --git a/include/ntuser.h b/include/ntuser.h index e7ebf786e25..e00bfaee44b 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