Passing an absolute rect to the drivers and keeping the DPI mapping to win32u.
From: Rémi Bernon rbernon@codeweavers.com
And rename it to SetIMECompositionRect. --- dlls/imm32/imm.c | 17 +++++------------ dlls/win32u/driver.c | 10 +++++----- dlls/win32u/input.c | 18 +++++------------- dlls/win32u/sysparams.c | 4 ++-- dlls/win32u/win32u_private.h | 2 +- dlls/winex11.drv/init.c | 2 +- dlls/winex11.drv/x11drv.h | 2 +- dlls/winex11.drv/xim.c | 16 ++++++++++------ include/ntuser.h | 2 +- include/wine/gdi_driver.h | 4 ++-- 10 files changed, 33 insertions(+), 44 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 661a08c0d8c..102f6edfe0c 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -2637,7 +2637,7 @@ BOOL WINAPI ImmSetCompositionStringW( BOOL WINAPI ImmSetCompositionWindow( HIMC himc, COMPOSITIONFORM *composition ) { INPUTCONTEXT *ctx; - POINT point; + RECT rect;
TRACE( "himc %p, composition %s\n", himc, debugstr_composition( composition ) );
@@ -2652,17 +2652,10 @@ BOOL WINAPI ImmSetCompositionWindow( HIMC himc, COMPOSITIONFORM *composition )
if (composition->dwStyle & (CFS_RECT | CFS_POINT | CFS_FORCE_POSITION)) { - if (composition->dwStyle & CFS_RECT) - { - point.x = composition->rcArea.left; - point.y = composition->rcArea.top; - } - else - { - point = composition->ptCurrentPos; - } - - NtUserCallTwoParam( (ULONG_PTR)ctx->hWnd, (ULONG_PTR)&point, NtUserCallTwoParam_SetIMECompositionWindowPos ); + if (composition->dwStyle & CFS_RECT) rect = composition->rcArea; + else SetRect( &rect, composition->ptCurrentPos.x, composition->ptCurrentPos.y, + composition->ptCurrentPos.x + 1, composition->ptCurrentPos.y + 1 ); + NtUserCallTwoParam( (ULONG_PTR)ctx->hWnd, (ULONG_PTR)&rect, NtUserCallTwoParam_SetIMECompositionRect ); }
ImmUnlockIMC( himc ); diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 854a2ee7cac..55c07a00572 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -686,7 +686,7 @@ static void nulldrv_NotifyIMEStatus( HWND hwnd, UINT status ) { }
-static BOOL nulldrv_SetIMECompositionWindowPos( HWND hwnd, const POINT *point ) +static BOOL nulldrv_SetIMECompositionRect( HWND hwnd, RECT rect ) { return FALSE; } @@ -1095,9 +1095,9 @@ static void loaderdrv_NotifyIMEStatus( HWND hwnd, UINT status ) return load_driver()->pNotifyIMEStatus( hwnd, status ); }
-static BOOL loaderdrv_SetIMECompositionWindowPos( HWND hwnd, const POINT *point ) +static BOOL loaderdrv_SetIMECompositionRect( HWND hwnd, RECT rect ) { - return load_driver()->pSetIMECompositionWindowPos( hwnd, point ); + return load_driver()->pSetIMECompositionRect( hwnd, rect ); }
static LONG loaderdrv_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd, @@ -1234,7 +1234,7 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_ReleaseKbdTables, loaderdrv_ImeProcessKey, loaderdrv_NotifyIMEStatus, - loaderdrv_SetIMECompositionWindowPos, + loaderdrv_SetIMECompositionRect, /* cursor/icon functions */ nulldrv_DestroyCursorIcon, loaderdrv_SetCursor, @@ -1327,7 +1327,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(ReleaseKbdTables); SET_USER_FUNC(ImeProcessKey); SET_USER_FUNC(NotifyIMEStatus); - SET_USER_FUNC(SetIMECompositionWindowPos); + SET_USER_FUNC(SetIMECompositionRect); SET_USER_FUNC(DestroyCursorIcon); SET_USER_FUNC(SetCursor); SET_USER_FUNC(GetCursorPos); diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 6328698f75f..a5f5ffdb6ef 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2353,19 +2353,17 @@ BOOL WINAPI NtUserGetCaretPos( POINT *pt ) return ret; }
-BOOL set_ime_composition_window_pos( HWND hwnd, const POINT *point ) +BOOL set_ime_composition_rect( HWND hwnd, RECT rect ) { HWND root_hwnd; - POINT pt;
if (!NtUserIsWindow( hwnd )) return FALSE;
root_hwnd = NtUserGetAncestor( hwnd, GA_ROOT ); - pt = *point; - NtUserMapWindowPoints( hwnd, root_hwnd, &pt, 1, 0 /* per-monitor DPI */ ); + NtUserMapWindowPoints( hwnd, root_hwnd, (POINT *)&rect, 2, 0 /* per-monitor DPI */ );
- return user_driver->pSetIMECompositionWindowPos( root_hwnd, &pt ); + return user_driver->pSetIMECompositionRect( root_hwnd, rect ); }
/******************************************************************* @@ -2376,7 +2374,6 @@ BOOL set_caret_pos( int x, int y ) int old_state = 0; int hidden = 0; HWND hwnd = 0; - POINT pt; BOOL ret; RECT r;
@@ -2406,10 +2403,8 @@ BOOL set_caret_pos( int x, int y ) r.bottom += y - r.top; r.left = x; r.top = y; - pt.x = x; - pt.y = y; display_caret( hwnd, &r ); - set_ime_composition_window_pos( hwnd, &pt ); + set_ime_composition_rect( hwnd, r ); NtUserSetSystemTimer( hwnd, SYSTEM_TIMER_CARET, caret.timeout ); } return ret; @@ -2421,7 +2416,6 @@ BOOL set_caret_pos( int x, int y ) BOOL WINAPI NtUserShowCaret( HWND hwnd ) { int hidden = 0; - POINT pt; BOOL ret; RECT r;
@@ -2444,10 +2438,8 @@ BOOL WINAPI NtUserShowCaret( HWND hwnd )
if (ret && hidden == 1) /* hidden was 1 so it's now 0 */ { - pt.x = r.left; - pt.y = r.top; display_caret( hwnd, &r ); - set_ime_composition_window_pos( hwnd, &pt ); + set_ime_composition_rect( hwnd, r ); NtUserSetSystemTimer( hwnd, SYSTEM_TIMER_CARET, caret.timeout ); } return ret; diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 30fe1c1e834..fa0483fb355 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -6742,8 +6742,8 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code case NtUserCallTwoParam_SetIconParam: return set_icon_param( UlongToHandle(arg1), UlongToHandle(arg2) );
- case NtUserCallTwoParam_SetIMECompositionWindowPos: - return set_ime_composition_window_pos( UlongToHandle(arg1), (const POINT *)arg2 ); + case NtUserCallTwoParam_SetIMECompositionRect: + return set_ime_composition_rect( UlongToHandle(arg1), *(const RECT *)arg2 );
case NtUserCallTwoParam_UnhookWindowsHook: return unhook_windows_hook( arg1, (HOOKPROC)arg2 ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 310498f5993..f79052562f1 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -104,7 +104,7 @@ extern BOOL set_caret_blink_time( unsigned int time ); extern BOOL set_caret_pos( int x, int y ); extern BOOL set_foreground_window( HWND hwnd, BOOL mouse ); extern BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus, DWORD new_active_thread_id ); -extern BOOL set_ime_composition_window_pos( HWND hwnd, const POINT *point ); +extern BOOL set_ime_composition_rect( HWND hwnd, RECT rect ); extern void toggle_caret( HWND hwnd ); extern void update_mouse_tracking_info( HWND hwnd ); extern BOOL get_clip_cursor( RECT *rect, UINT dpi ); diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index a8900f9c165..63b47e3769a 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -432,7 +432,7 @@ static const struct user_driver_funcs x11drv_funcs = .pToUnicodeEx = X11DRV_ToUnicodeEx, .pVkKeyScanEx = X11DRV_VkKeyScanEx, .pNotifyIMEStatus = X11DRV_NotifyIMEStatus, - .pSetIMECompositionWindowPos = X11DRV_SetIMECompositionWindowPos, + .pSetIMECompositionRect = X11DRV_SetIMECompositionRect, .pDestroyCursorIcon = X11DRV_DestroyCursorIcon, .pSetCursor = X11DRV_SetCursor, .pGetCursorPos = X11DRV_GetCursorPos, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 622658a6377..2ecf3cb54cd 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -205,7 +205,7 @@ extern INT X11DRV_ToUnicodeEx( UINT virtKey, UINT scanCode, const BYTE *lpKeySta LPWSTR bufW, int bufW_size, UINT flags, HKL hkl ); extern SHORT X11DRV_VkKeyScanEx( WCHAR wChar, HKL hkl ); extern void X11DRV_NotifyIMEStatus( HWND hwnd, UINT status ); -extern BOOL X11DRV_SetIMECompositionWindowPos( HWND hwnd, const POINT *point ); +extern BOOL X11DRV_SetIMECompositionRect( HWND hwnd, RECT rect ); extern void X11DRV_DestroyCursorIcon( HCURSOR handle ); extern void X11DRV_SetCursor( HWND hwnd, HCURSOR handle ); extern BOOL X11DRV_SetCursorPos( INT x, INT y ); diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 3871e4e7617..46b50480c93 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -489,12 +489,14 @@ void xim_set_focus( HWND hwnd, BOOL focus ) else XUnsetICFocus( xic ); }
-BOOL X11DRV_SetIMECompositionWindowPos( HWND hwnd, const POINT *point ) +/*********************************************************************** + * SetIMECompositionRect (X11DRV.@) + */ +BOOL X11DRV_SetIMECompositionRect( HWND hwnd, RECT rect ) { struct x11drv_win_data *data = NULL; XVaNestedList attr; XPoint xpoint; - POINT pt;
if (!(input_style & XIMPreeditPosition)) return FALSE; @@ -505,12 +507,14 @@ BOOL X11DRV_SetIMECompositionWindowPos( HWND hwnd, const POINT *point ) return FALSE; }
- pt = *point; if (NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) - pt.x = data->rects.client.right - data->rects.client.left - 1 - pt.x; + { + rect.left = data->rects.client.right - data->rects.client.left - 1 - rect.left; + rect.right = data->rects.client.right - data->rects.client.left - 1 - rect.right; + }
- xpoint.x = pt.x + data->rects.client.left - data->rects.visible.left; - xpoint.y = pt.y + data->rects.client.top - data->rects.visible.top; + xpoint.x = rect.left + data->rects.client.left - data->rects.visible.left; + xpoint.y = rect.top + data->rects.client.top - data->rects.visible.top; attr = XVaCreateNestedList( 0, XNSpotLocation, &xpoint, NULL ); if (attr) { diff --git a/include/ntuser.h b/include/ntuser.h index cc63b7dd015..69dd1e2f434 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -1072,7 +1072,7 @@ enum NtUserCallTwoParam_MonitorFromRect, NtUserCallTwoParam_SetCaretPos, NtUserCallTwoParam_SetIconParam, - NtUserCallTwoParam_SetIMECompositionWindowPos, + NtUserCallTwoParam_SetIMECompositionRect, NtUserCallTwoParam_UnhookWindowsHook, NtUserCallTwoParam_AdjustWindowRect, NtUserCallTwoParam_GetVirtualScreenRect, diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 66ab52754a0..00b7f5f219e 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -219,7 +219,7 @@ struct gdi_dc_funcs };
/* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 99 +#define WINE_GDI_DRIVER_VERSION 100
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -340,7 +340,7 @@ struct user_driver_funcs /* IME functions */ UINT (*pImeProcessKey)(HIMC,UINT,UINT,const BYTE*); void (*pNotifyIMEStatus)(HWND,UINT); - BOOL (*pSetIMECompositionWindowPos)(HWND, const POINT *); + BOOL (*pSetIMECompositionRect)(HWND,RECT); /* cursor/icon functions */ void (*pDestroyCursorIcon)(HCURSOR); void (*pSetCursor)(HWND,HCURSOR);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/input.c | 12 +++--------- dlls/winex11.drv/xim.c | 10 ++-------- 2 files changed, 5 insertions(+), 17 deletions(-)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index a5f5ffdb6ef..0640b34ac2e 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2355,15 +2355,9 @@ BOOL WINAPI NtUserGetCaretPos( POINT *pt )
BOOL set_ime_composition_rect( HWND hwnd, RECT rect ) { - HWND root_hwnd; - - if (!NtUserIsWindow( hwnd )) - return FALSE; - - root_hwnd = NtUserGetAncestor( hwnd, GA_ROOT ); - NtUserMapWindowPoints( hwnd, root_hwnd, (POINT *)&rect, 2, 0 /* per-monitor DPI */ ); - - return user_driver->pSetIMECompositionRect( root_hwnd, rect ); + if (!NtUserIsWindow( hwnd )) return FALSE; + NtUserMapWindowPoints( hwnd, 0, (POINT *)&rect, 2, 0 /* per-monitor DPI */ ); + return user_driver->pSetIMECompositionRect( NtUserGetAncestor( hwnd, GA_ROOT ), rect ); }
/******************************************************************* diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 46b50480c93..acbe1c3aac1 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -507,14 +507,8 @@ BOOL X11DRV_SetIMECompositionRect( HWND hwnd, RECT rect ) return FALSE; }
- if (NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) - { - rect.left = data->rects.client.right - data->rects.client.left - 1 - rect.left; - rect.right = data->rects.client.right - data->rects.client.left - 1 - rect.right; - } - - xpoint.x = rect.left + data->rects.client.left - data->rects.visible.left; - xpoint.y = rect.top + data->rects.client.top - data->rects.visible.top; + xpoint.x = rect.left - data->rects.visible.left; + xpoint.y = rect.top - data->rects.visible.top; attr = XVaCreateNestedList( 0, XNSpotLocation, &xpoint, NULL ); if (attr) {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/event.c | 37 ++++++++++++++++++++++--------------- dlls/winemac.drv/gdi.c | 1 + dlls/winemac.drv/macdrv.h | 3 ++- 3 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c index 2db0a4fa2bb..4f80f59692e 100644 --- a/dlls/winemac.drv/event.c +++ b/dlls/winemac.drv/event.c @@ -34,6 +34,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(event); WINE_DECLARE_DEBUG_CHANNEL(imm);
+static pthread_mutex_t ime_mutex = PTHREAD_MUTEX_INITIALIZER; +static RECT ime_composition_rect; + /* return the name of an Mac event */ static const char *dbgstr_event(int type) { @@ -307,32 +310,36 @@ BOOL query_ime_char_rect(macdrv_query* query) HWND hwnd = macdrv_get_window_hwnd(query->window); void *himc = query->ime_char_rect.himc; CFRange *range = &query->ime_char_rect.range; - GUITHREADINFO info = {.cbSize = sizeof(info)}; - BOOL ret = FALSE;
TRACE_(imm)("win %p/%p himc %p range %ld-%ld\n", hwnd, query->window, himc, range->location, range->length);
- if (NtUserGetGUIThreadInfo(0, &info)) - { - /* NtUserGetGUIThreadInfo always return client-relative rcCaret in window DPI */ - NtUserMapWindowPoints(info.hwndCaret, 0, (POINT *)&info.rcCaret, 2, NtUserGetDpiForWindow(info.hwndCaret)); - NtUserLogicalToPerMonitorDPIPhysicalPoint(info.hwndCaret, (POINT *)&info.rcCaret.left); - NtUserLogicalToPerMonitorDPIPhysicalPoint(info.hwndCaret, (POINT *)&info.rcCaret.right); - if (range->length && info.rcCaret.left == info.rcCaret.right) info.rcCaret.right++; - query->ime_char_rect.rect = cgrect_from_rect(info.rcCaret); - ret = TRUE; - } + pthread_mutex_lock(&ime_mutex); + query->ime_char_rect.rect = cgrect_from_rect(ime_composition_rect); + pthread_mutex_unlock(&ime_mutex);
- TRACE_(imm)(" -> %s range %ld-%ld rect %s\n", ret ? "TRUE" : "FALSE", range->location, + TRACE_(imm)(" -> range %ld-%ld rect %s\n", range->location, range->length, wine_dbgstr_cgrect(query->ime_char_rect.rect));
- return ret; + return TRUE; +} + + +/*********************************************************************** + * SetIMECompositionRect (MACDRV.@) + */ +BOOL macdrv_SetIMECompositionRect(HWND hwnd, RECT rect) +{ + TRACE("hwnd %p, rect %s\n", hwnd, wine_dbgstr_rect(&rect)); + pthread_mutex_lock(&ime_mutex); + ime_composition_rect = rect; + pthread_mutex_unlock(&ime_mutex); + return TRUE; }
/*********************************************************************** - * NotifyIMEStatus (X11DRV.@) + * NotifyIMEStatus (MACDRV.@) */ void macdrv_NotifyIMEStatus( HWND hwnd, UINT status ) { diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 8592111521c..4921fc2f170 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -303,6 +303,7 @@ static const struct user_driver_funcs macdrv_funcs = .pVkKeyScanEx = macdrv_VkKeyScanEx, .pImeProcessKey = macdrv_ImeProcessKey, .pNotifyIMEStatus = macdrv_NotifyIMEStatus, + .pSetIMECompositionRect = macdrv_SetIMECompositionRect, .pWindowMessage = macdrv_WindowMessage, .pWindowPosChanged = macdrv_WindowPosChanged, .pWindowPosChanging = macdrv_WindowPosChanging, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 91e7a53dba9..76c9be9519f 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -169,7 +169,8 @@ extern INT macdrv_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyStat LPWSTR bufW, int bufW_size, UINT flags, HKL hkl); extern UINT macdrv_GetKeyboardLayoutList(INT size, HKL *list); extern INT macdrv_GetKeyNameText(LONG lparam, LPWSTR buffer, INT size); -extern void macdrv_NotifyIMEStatus( HWND hwnd, UINT status ); +extern void macdrv_NotifyIMEStatus(HWND hwnd, UINT status); +extern BOOL macdrv_SetIMECompositionRect(HWND hwnd, RECT rect); extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_param, UINT flags); extern BOOL macdrv_ProcessEvents(DWORD mask);
This merge request was approved by Huw Davies.