Right now this should not do anything because all windows are per-monitor DPI aware. When this is changed this will automatically fall back to window surface scaling through `NtGdiStretchBlt` in win32u.
This has the disadvantage that `NtGdiStretchBlt` is doing an absolutely terrible job at upscaling. This then adds a way for drivers to opt-in and do their own surface scaling before falling back to win32u. Alternatively and perhaps better, we could pull libcairo and use it to scale the surface contents with high quality filtering instead of using GDI.
-- v2: win32u: Implement DPI scaled window surface. win32u: Move window_surface creation helper to dce.c. win32u: Map window rects DPI before calling into the drivers. win32u: Map window region DPI before calling into the drivers. winex11: Use the driver rects to convert from host visible to window rect. winex11: Keep a window_rects struct in the driver window data. win32u: Move visible rect computation out of the drivers. win32u: Keep SetIMECompositionWindowPos with other IME entries.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 20 ++++++++++++-------- dlls/winex11.drv/init.c | 2 +- dlls/winex11.drv/x11drv.h | 2 +- include/wine/gdi_driver.h | 5 ++--- 4 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 87b2971216d..c56bf89d069 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -686,6 +686,11 @@ static void nulldrv_NotifyIMEStatus( HWND hwnd, UINT status ) { }
+static BOOL nulldrv_SetIMECompositionWindowPos( HWND hwnd, const POINT *point ) +{ + return FALSE; +} + static LRESULT nulldrv_DesktopWindowProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { return default_window_proc( hwnd, msg, wparam, lparam, FALSE ); @@ -914,11 +919,6 @@ static void nulldrv_ThreadDetach( void ) { }
-static BOOL nulldrv_SetIMECompositionWindowPos( HWND hwnd, const POINT *point ) -{ - return FALSE; -} - static const WCHAR guid_key_prefixW[] = { '\','R','e','g','i','s','t','r','y', @@ -1099,6 +1099,11 @@ static void loaderdrv_NotifyIMEStatus( HWND hwnd, UINT status ) return load_driver()->pNotifyIMEStatus( hwnd, status ); }
+static BOOL loaderdrv_SetIMECompositionWindowPos( HWND hwnd, const POINT *point ) +{ + return load_driver()->pSetIMECompositionWindowPos( hwnd, point ); +} + static LONG loaderdrv_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd, DWORD flags, LPVOID lparam ) { @@ -1243,6 +1248,7 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_ReleaseKbdTables, loaderdrv_ImeProcessKey, loaderdrv_NotifyIMEStatus, + loaderdrv_SetIMECompositionWindowPos, /* cursor/icon functions */ nulldrv_DestroyCursorIcon, loaderdrv_SetCursor, @@ -1299,8 +1305,6 @@ static const struct user_driver_funcs lazy_load_driver = nulldrv_wine_get_wgl_driver, /* thread management */ nulldrv_ThreadDetach, - /* IME support */ - nulldrv_SetIMECompositionWindowPos, };
const struct user_driver_funcs *user_driver = &lazy_load_driver; @@ -1338,6 +1342,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(DestroyCursorIcon); SET_USER_FUNC(SetCursor); SET_USER_FUNC(GetCursorPos); @@ -1385,7 +1390,6 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(VulkanInit); SET_USER_FUNC(wine_get_wgl_driver); SET_USER_FUNC(ThreadDetach); - SET_USER_FUNC(SetIMECompositionWindowPos); #undef SET_USER_FUNC
prev = InterlockedCompareExchangePointer( (void **)&user_driver, driver, (void *)&lazy_load_driver ); diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 3b919335624..1fa07d38e13 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -385,6 +385,7 @@ static const struct user_driver_funcs x11drv_funcs = .pToUnicodeEx = X11DRV_ToUnicodeEx, .pVkKeyScanEx = X11DRV_VkKeyScanEx, .pNotifyIMEStatus = X11DRV_NotifyIMEStatus, + .pSetIMECompositionWindowPos = X11DRV_SetIMECompositionWindowPos, .pDestroyCursorIcon = X11DRV_DestroyCursorIcon, .pSetCursor = X11DRV_SetCursor, .pGetCursorPos = X11DRV_GetCursorPos, @@ -430,7 +431,6 @@ static const struct user_driver_funcs x11drv_funcs = .pVulkanInit = X11DRV_VulkanInit, .pwine_get_wgl_driver = X11DRV_wine_get_wgl_driver, .pThreadDetach = X11DRV_ThreadDetach, - .pSetIMECompositionWindowPos = X11DRV_SetIMECompositionWindowPos, };
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 72527c7b92d..e75e3d7c70a 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -205,6 +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 void X11DRV_DestroyCursorIcon( HCURSOR handle ); extern void X11DRV_SetCursor( HWND hwnd, HCURSOR handle ); extern BOOL X11DRV_SetCursorPos( INT x, INT y ); @@ -250,7 +251,6 @@ extern void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flag extern BOOL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, UINT flags ); extern void X11DRV_ThreadDetach(void); -extern BOOL X11DRV_SetIMECompositionWindowPos( HWND hwnd, const POINT *point );
/* X11 driver internal functions */
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 7fe492f4776..a2497a39d7b 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 94 +#define WINE_GDI_DRIVER_VERSION 95
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -340,6 +340,7 @@ struct user_driver_funcs /* IME functions */ UINT (*pImeProcessKey)(HIMC,UINT,UINT,const BYTE*); void (*pNotifyIMEStatus)(HWND,UINT); + BOOL (*pSetIMECompositionWindowPos)(HWND, const POINT *); /* cursor/icon functions */ void (*pDestroyCursorIcon)(HCURSOR); void (*pSetCursor)(HWND,HCURSOR); @@ -396,8 +397,6 @@ struct user_driver_funcs struct opengl_funcs * (*pwine_get_wgl_driver)(UINT); /* thread management */ void (*pThreadDetach)(void); - /* IME support */ - BOOL (*pSetIMECompositionWindowPos)(HWND, const POINT *); };
W32KAPI void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version );
From: Rémi Bernon rbernon@codeweavers.com
Using a new GetWindowStyleMasks driver entry to get the style masks to be used to mask out non-client decorations which are hidden by the host decorations. --- dlls/win32u/driver.c | 9 +++- dlls/win32u/window.c | 34 ++++++++++++- dlls/wineandroid.drv/android.h | 2 +- dlls/wineandroid.drv/window.c | 2 +- dlls/winemac.drv/gdi.c | 1 + dlls/winemac.drv/macdrv.h | 3 +- dlls/winemac.drv/window.c | 77 ++++++++++++++++++++---------- dlls/winewayland.drv/waylanddrv.h | 2 +- dlls/winewayland.drv/window.c | 2 +- dlls/winex11.drv/init.c | 1 + dlls/winex11.drv/window.c | 79 ++++++++++++++++++------------- dlls/winex11.drv/x11drv.h | 3 +- include/wine/gdi_driver.h | 5 +- 13 files changed, 151 insertions(+), 69 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index c56bf89d069..3e094264d15 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -881,11 +881,16 @@ static LRESULT nulldrv_WindowMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM return 0; }
-static BOOL nulldrv_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects ) +static BOOL nulldrv_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ) { return TRUE; }
+extern BOOL nulldrv_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask ) +{ + return FALSE; +} + static BOOL nulldrv_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ) { return FALSE; @@ -1294,6 +1299,7 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_UpdateLayeredWindow, nulldrv_WindowMessage, nulldrv_WindowPosChanging, + nulldrv_GetWindowStyleMasks, nulldrv_CreateWindowSurface, nulldrv_MoveWindowBits, nulldrv_WindowPosChanged, @@ -1383,6 +1389,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(UpdateLayeredWindow); SET_USER_FUNC(WindowMessage); SET_USER_FUNC(WindowPosChanging); + SET_USER_FUNC(GetWindowStyleMasks); SET_USER_FUNC(CreateWindowSurface); SET_USER_FUNC(MoveWindowBits); SET_USER_FUNC(WindowPosChanged); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 7ad3e1d50ff..f17e45231ad 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1818,6 +1818,28 @@ done: }
+static RECT get_visible_rect( HWND hwnd, UINT style, UINT ex_style, RECT window_rect, UINT dpi ) +{ + RECT visible_rect = window_rect; + UINT style_mask, ex_style_mask; + RECT rect = {0}; + + if (!user_driver->pGetWindowStyleMasks( hwnd, style, ex_style, &style_mask, &ex_style_mask )) return visible_rect; + NtUserAdjustWindowRect( &rect, style & style_mask, FALSE, ex_style & ex_style_mask, dpi ? dpi : get_system_dpi() ); + + visible_rect.left -= rect.left; + visible_rect.right -= rect.right; + visible_rect.top -= rect.top; + visible_rect.bottom -= rect.bottom; + if (visible_rect.top >= visible_rect.bottom) visible_rect.bottom = visible_rect.top + 1; + if (visible_rect.left >= visible_rect.right) visible_rect.right = visible_rect.left + 1; + + TRACE( "hwnd %p, window_rect %s, style %#x, ex_style %#x -> visible_rect %s\n", hwnd, + wine_dbgstr_rect( &window_rect ), style, ex_style, wine_dbgstr_rect( &visible_rect ) ); + return visible_rect; +} + + static BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) { RECT virtual_rect = NtUserGetVirtualScreenRect(); @@ -1874,18 +1896,26 @@ static struct window_surface *create_window_surface( HWND hwnd, UINT swp_flags, BOOL shaped, needs_surface, create_opaque, is_layered; HWND parent = NtUserGetAncestor( hwnd, GA_PARENT ); struct window_surface *new_surface; + UINT style, ex_style; RECT dummy; HRGN shape;
+ style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); + ex_style = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ); + if (get_window_region( hwnd, FALSE, &shape, &dummy )) shaped = FALSE; else if ((shaped = !!shape)) NtGdiDeleteObjectApp( shape );
- rects->visible = rects->window; if (!user_driver->pWindowPosChanging( hwnd, swp_flags, shaped, rects )) needs_surface = FALSE; else if (parent && parent != NtUserGetDesktopWindow()) needs_surface = FALSE; else if (swp_flags & SWP_HIDEWINDOW) needs_surface = FALSE; else if (swp_flags & SWP_SHOWWINDOW) needs_surface = TRUE; - else needs_surface = !!(NtUserGetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE); + else needs_surface = !!(style & WS_VISIBLE); + + if (IsRectEmpty( &rects->window )) rects->visible = rects->window; + else if (EqualRect( &rects->window, &rects->client )) rects->visible = rects->window; + else if (shaped) rects->visible = rects->window; + else rects->visible = get_visible_rect( hwnd, style, ex_style, rects->window, get_thread_dpi() );
if (!get_surface_rect( &rects->visible, surface_rect )) needs_surface = FALSE; if (!get_default_window_surface( hwnd, surface_rect, &new_surface )) return NULL; diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index f438deb714e..850b235f3a1 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -95,7 +95,7 @@ extern void ANDROID_SetParent( HWND hwnd, HWND parent, HWND old_parent ); extern void ANDROID_SetCapture( HWND hwnd, UINT flags ); extern UINT ANDROID_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ); extern LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); -extern BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects ); +extern BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ); extern BOOL ANDROID_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ); extern void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface ); diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 8018ee1a567..537aae456e7 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1023,7 +1023,7 @@ static struct android_win_data *create_win_data( HWND hwnd, const struct window_ /*********************************************************************** * ANDROID_WindowPosChanging */ -BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects ) +BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ) { struct android_win_data *data = get_win_data( hwnd );
diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 0505938a822..8492b0030c0 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -309,6 +309,7 @@ static const struct user_driver_funcs macdrv_funcs = .pMoveWindowBits = macdrv_MoveWindowBits, .pWindowPosChanged = macdrv_WindowPosChanged, .pWindowPosChanging = macdrv_WindowPosChanging, + .pGetWindowStyleMasks = macdrv_GetWindowStyleMasks, .pCreateWindowSurface = macdrv_CreateWindowSurface, .pVulkanInit = macdrv_VulkanInit, .pwine_get_wgl_driver = macdrv_wine_get_wgl_driver, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index b417c0e2344..6e506514164 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -147,7 +147,8 @@ extern void macdrv_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alph extern LRESULT macdrv_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam); extern void macdrv_UpdateLayeredWindow(HWND hwnd, UINT flags); extern LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); -extern BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects); +extern BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects); +extern BOOL macdrv_GetWindowStyleMasks(HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask); extern BOOL macdrv_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); extern void macdrv_MoveWindowBits(HWND hwnd, const struct window_rects *new_rects, const RECT *valid_rects); extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index d3959a005f8..bb11ae12ffa 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -74,6 +74,35 @@ static void set_internal_window_pos(HWND hwnd, UINT cmd, RECT *rect, POINT *pt) }
+static struct macdrv_window_features get_window_features_for_style(DWORD style, DWORD ex_style, BOOL shaped) +{ + struct macdrv_window_features wf = {0}; + + if (ex_style & WS_EX_NOACTIVATE) wf.prevents_app_activation = TRUE; + + if ((style & WS_CAPTION) == WS_CAPTION && !(ex_style & WS_EX_LAYERED)) + { + wf.shadow = TRUE; + if (!shaped) + { + wf.title_bar = TRUE; + if (style & WS_SYSMENU) wf.close_button = TRUE; + if (style & WS_MINIMIZEBOX) wf.minimize_button = TRUE; + if (style & WS_MAXIMIZEBOX) wf.maximize_button = TRUE; + if (ex_style & WS_EX_TOOLWINDOW) wf.utility = TRUE; + } + } + if (style & WS_THICKFRAME) + { + wf.shadow = TRUE; + if (!shaped) wf.resizable = TRUE; + } + else if (ex_style & WS_EX_DLGMODALFRAME) wf.shadow = TRUE; + else if ((style & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME) wf.shadow = TRUE; + + return wf; +} + /*********************************************************************** * get_cocoa_window_features */ @@ -91,25 +120,7 @@ static void get_cocoa_window_features(struct macdrv_win_data *data, if (IsRectEmpty(window_rect)) return; if (EqualRect(window_rect, client_rect)) return;
- if ((style & WS_CAPTION) == WS_CAPTION && !(ex_style & WS_EX_LAYERED)) - { - wf->shadow = TRUE; - if (!data->shaped) - { - wf->title_bar = TRUE; - if (style & WS_SYSMENU) wf->close_button = TRUE; - if (style & WS_MINIMIZEBOX) wf->minimize_button = TRUE; - if (style & WS_MAXIMIZEBOX) wf->maximize_button = TRUE; - if (ex_style & WS_EX_TOOLWINDOW) wf->utility = TRUE; - } - } - if (style & WS_THICKFRAME) - { - wf->shadow = TRUE; - if (!data->shaped) wf->resizable = TRUE; - } - else if (ex_style & WS_EX_DLGMODALFRAME) wf->shadow = TRUE; - else if ((style & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME) wf->shadow = TRUE; + *wf = get_window_features_for_style(style, ex_style, data->shaped); }
@@ -1804,10 +1815,9 @@ LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) /*********************************************************************** * WindowPosChanging (MACDRV.@) */ -BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects) +BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects) { struct macdrv_win_data *data = get_win_data(hwnd); - DWORD style = NtUserGetWindowLongW(hwnd, GWL_STYLE); BOOL ret = FALSE;
TRACE("hwnd %p, swp_flags %04x, shaped %u, rects %s\n", hwnd, swp_flags, shaped, debugstr_window_rects(rects)); @@ -1815,9 +1825,6 @@ BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, struct win if (!data && !(data = macdrv_create_win_data(hwnd, rects))) return FALSE; /* use default surface */ data->shaped = shaped;
- macdrv_window_to_mac_rect(data, style, &rects->visible, &rects->window, &rects->client); - TRACE("-> %s\n", debugstr_window_rects(rects)); - ret = !!data->cocoa_window; /* use default surface if we don't have a window */ release_win_data(data);
@@ -1854,6 +1861,28 @@ void macdrv_MoveWindowBits(HWND hwnd, const struct window_rects *new_rects, cons } }
+/*********************************************************************** + * GetWindowStyleMasks (X11DRV.@) + */ +BOOL macdrv_GetWindowStyleMasks(HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask) +{ + struct macdrv_window_features wf = get_window_features_for_style(style, ex_style, FALSE); + + if (wf.title_bar) + { + *style_mask |= WS_CAPTION; + *ex_style_mask |= WS_EX_TOOLWINDOW; + } + if (wf.shadow) + { + *style_mask |= WS_DLGFRAME | WS_THICKFRAME; + *ex_style_mask |= WS_EX_DLGMODALFRAME; + } + + return TRUE; +} + + /*********************************************************************** * WindowPosChanged (MACDRV.@) */ diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 4e3841d8cf9..40f86526cd2 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -355,7 +355,7 @@ UINT WAYLAND_UpdateDisplayDevices(const struct gdi_device_manager *device_manage LRESULT WAYLAND_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface); -BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects); +BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects); BOOL WAYLAND_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs); struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version); diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 355894f6137..73a8de37f77 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -425,7 +425,7 @@ void WAYLAND_DestroyWindow(HWND hwnd) /*********************************************************************** * WAYLAND_WindowPosChanging */ -BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects) +BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects) { struct wayland_win_data *data = wayland_win_data_get(hwnd);
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 1fa07d38e13..fa477a4de6b 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -424,6 +424,7 @@ static const struct user_driver_funcs x11drv_funcs = .pUpdateLayeredWindow = X11DRV_UpdateLayeredWindow, .pWindowMessage = X11DRV_WindowMessage, .pWindowPosChanging = X11DRV_WindowPosChanging, + .pGetWindowStyleMasks = X11DRV_GetWindowStyleMasks, .pCreateWindowSurface = X11DRV_CreateWindowSurface, .pMoveWindowBits = X11DRV_MoveWindowBits, .pWindowPosChanged = X11DRV_WindowPosChanged, diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 6e834457620..c7c785d2510 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -303,19 +303,12 @@ static inline BOOL is_window_resizable( struct x11drv_win_data *data, DWORD styl /*********************************************************************** * get_mwm_decorations */ -static unsigned long get_mwm_decorations( struct x11drv_win_data *data, - DWORD style, DWORD ex_style, - const RECT *window_rect, - const RECT *client_rect ) +static unsigned long get_mwm_decorations_for_style( DWORD style, DWORD ex_style ) { unsigned long ret = 0;
if (!decorated_mode) return 0;
- if (EqualRect( window_rect, client_rect )) return 0; - if (IsRectEmpty( window_rect )) return 0; - if (data->shaped) return 0; - if (ex_style & WS_EX_TOOLWINDOW) return 0; if (ex_style & WS_EX_LAYERED) return 0;
@@ -333,6 +326,24 @@ static unsigned long get_mwm_decorations( struct x11drv_win_data *data, }
+/*********************************************************************** + * get_mwm_decorations + */ +static unsigned long get_mwm_decorations( struct x11drv_win_data *data, + DWORD style, DWORD ex_style, + const RECT *window_rect, + const RECT *client_rect ) +{ + if (!decorated_mode) return 0; + + if (EqualRect( window_rect, client_rect )) return 0; + if (IsRectEmpty( window_rect )) return 0; + if (data->shaped) return 0; + + return get_mwm_decorations_for_style( style, ex_style ); +} + + /*********************************************************************** * get_window_attributes * @@ -1337,28 +1348,6 @@ static void get_decoration_rect( struct x11drv_win_data *data, RECT *rect, }
-/*********************************************************************** - * X11DRV_window_to_X_rect - * - * Convert a rect from client to X window coordinates - */ -static void X11DRV_window_to_X_rect( struct x11drv_win_data *data, RECT *rect, - const RECT *window_rect, const RECT *client_rect ) -{ - RECT rc; - - if (IsRectEmpty( rect )) return; - - get_decoration_rect( data, &rc, window_rect, client_rect ); - rect->left -= rc.left; - rect->right -= rc.right; - rect->top -= rc.top; - rect->bottom -= rc.bottom; - if (rect->top >= rect->bottom) rect->bottom = rect->top + 1; - if (rect->left >= rect->right) rect->right = rect->left + 1; -} - - /*********************************************************************** * X11DRV_X_to_window_rect * @@ -2569,7 +2558,7 @@ done: /*********************************************************************** * WindowPosChanging (X11DRV.@) */ -BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects ) +BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ) { struct x11drv_win_data *data = get_win_data( hwnd ); BOOL ret = FALSE; @@ -2589,9 +2578,6 @@ BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct wi data->managed = TRUE; }
- X11DRV_window_to_X_rect( data, &rects->visible, &rects->window, &rects->client ); - TRACE( "-> %s\n", debugstr_window_rects(rects) ); - ret = !!data->whole_window; /* use default surface if we don't have a window */ release_win_data( data );
@@ -2628,6 +2614,31 @@ void X11DRV_MoveWindowBits( HWND hwnd, const struct window_rects *new_rects, con } }
+/*********************************************************************** + * GetWindowStyleMasks (X11DRV.@) + */ +BOOL X11DRV_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask ) +{ + unsigned long decor = get_mwm_decorations_for_style( style, ex_style ); + struct x11drv_win_data *data; + + if ((data = get_win_data( hwnd ))) + { + if (!data->managed) decor = 0; + release_win_data( data ); + } + + if (decor & MWM_DECOR_TITLE) *style_mask |= WS_CAPTION; + if (decor & MWM_DECOR_BORDER) + { + *style_mask |= WS_DLGFRAME | WS_THICKFRAME; + *ex_style_mask |= WS_EX_DLGMODALFRAME; + } + + return TRUE; +} + + /*********************************************************************** * WindowPosChanged (X11DRV.@) */ diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index e75e3d7c70a..c0cf020067e 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -243,7 +243,8 @@ extern LRESULT X11DRV_ClipboardWindowProc( HWND hwnd, UINT msg, WPARAM wp, LPARA extern void X11DRV_UpdateClipboard(void); extern void X11DRV_UpdateLayeredWindow( HWND hwnd, UINT flags ); extern LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); -extern BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, struct window_rects *rects ); +extern BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ); +extern BOOL X11DRV_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask ); extern BOOL X11DRV_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ); extern void X11DRV_MoveWindowBits( HWND hwnd, const struct window_rects *new_rects, const RECT *valid_rects ); extern void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index a2497a39d7b..fee065af71b 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 95 +#define WINE_GDI_DRIVER_VERSION 96
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -385,7 +385,8 @@ struct user_driver_funcs LRESULT (*pSysCommand)(HWND,WPARAM,LPARAM); void (*pUpdateLayeredWindow)(HWND,UINT); LRESULT (*pWindowMessage)(HWND,UINT,WPARAM,LPARAM); - BOOL (*pWindowPosChanging)(HWND,UINT,BOOL,struct window_rects *); + BOOL (*pWindowPosChanging)(HWND,UINT,BOOL,const struct window_rects *); + BOOL (*pGetWindowStyleMasks)(HWND,UINT,UINT,UINT*,UINT*); BOOL (*pCreateWindowSurface)(HWND,BOOL,const RECT *,struct window_surface**); void (*pMoveWindowBits)(HWND,const struct window_rects *,const RECT *); void (*pWindowPosChanged)(HWND,HWND,UINT,const struct window_rects*,struct window_surface*);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 40 +++++----- dlls/winex11.drv/mouse.c | 6 +- dlls/winex11.drv/window.c | 157 ++++++++++++++++++-------------------- dlls/winex11.drv/x11drv.h | 4 +- dlls/winex11.drv/xim.c | 6 +- 5 files changed, 101 insertions(+), 112 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 635025aff97..ca9ab4b8aed 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -896,13 +896,13 @@ static BOOL X11DRV_Expose( HWND hwnd, XEvent *xev ) rect.bottom = pos.y + event->height;
if (event->window != data->client_window) - OffsetRect( &rect, data->whole_rect.left - data->client_rect.left, - data->whole_rect.top - data->client_rect.top ); + OffsetRect( &rect, data->rects.visible.left - data->rects.client.left, + data->rects.visible.top - data->rects.client.top );
if (event->window != root_window) { if (NtUserGetWindowLongW( data->hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) - mirror_rect( &data->client_rect, &rect ); + mirror_rect( &data->rects.client, &rect ); abs_rect = rect; NtUserMapWindowPoints( hwnd, 0, (POINT *)&abs_rect, 2, 0 /* per-monitor DPI */ );
@@ -1091,22 +1091,22 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
if (!data->whole_window) flags |= SWP_NOCOPYBITS; /* we can't copy bits of foreign windows */
- if (data->window_rect.left == x && data->window_rect.top == y) flags |= SWP_NOMOVE; + if (data->rects.window.left == x && data->rects.window.top == y) flags |= SWP_NOMOVE; else TRACE( "%p moving from (%d,%d) to (%d,%d)\n", - hwnd, (int)data->window_rect.left, (int)data->window_rect.top, x, y ); + hwnd, (int)data->rects.window.left, (int)data->rects.window.top, x, y );
- if ((data->window_rect.right - data->window_rect.left == cx && - data->window_rect.bottom - data->window_rect.top == cy) || - IsRectEmpty( &data->window_rect )) + if ((data->rects.window.right - data->rects.window.left == cx && + data->rects.window.bottom - data->rects.window.top == cy) || + IsRectEmpty( &data->rects.window )) flags |= SWP_NOSIZE; else TRACE( "%p resizing from (%dx%d) to (%dx%d)\n", - hwnd, (int)(data->window_rect.right - data->window_rect.left), - (int)(data->window_rect.bottom - data->window_rect.top), cx, cy ); + hwnd, (int)(data->rects.window.right - data->rects.window.left), + (int)(data->rects.window.bottom - data->rects.window.top), cx, cy );
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); - if ((style & WS_CAPTION) == WS_CAPTION || !NtUserIsWindowRectFullScreen( &data->whole_rect, dpi )) + if ((style & WS_CAPTION) == WS_CAPTION || !NtUserIsWindowRectFullScreen( &data->rects.visible, dpi )) { read_net_wm_states( event->display, data ); if ((data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED))) @@ -1159,13 +1159,13 @@ static BOOL X11DRV_GravityNotify( HWND hwnd, XEvent *xev ) return FALSE; }
- x = event->x + data->window_rect.left - data->whole_rect.left; - y = event->y + data->window_rect.top - data->whole_rect.top; + x = event->x + data->rects.window.left - data->rects.visible.left; + y = event->y + data->rects.window.top - data->rects.visible.top;
TRACE( "win %p/%lx new X pos %d,%d (event %d,%d)\n", hwnd, data->whole_window, x, y, event->x, event->y );
- window_rect = data->window_rect; + window_rect = data->rects.window; release_win_data( data );
if (window_rect.left != x || window_rect.top != y) @@ -1448,8 +1448,8 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event ) Window win, w_aux_root, w_aux_child;
if (!(data = get_win_data( hWnd ))) return; - cx = data->whole_rect.right - data->whole_rect.left; - cy = data->whole_rect.bottom - data->whole_rect.top; + cx = data->rects.visible.right - data->rects.visible.left; + cy = data->rects.visible.bottom - data->rects.visible.top; win = data->whole_window; release_win_data( data );
@@ -1537,10 +1537,10 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) if ((win_data = get_win_data( hWnd ))) { drop->fNC = - (drop->pt.x < (win_data->client_rect.left - win_data->whole_rect.left) || - drop->pt.y < (win_data->client_rect.top - win_data->whole_rect.top) || - drop->pt.x > (win_data->client_rect.right - win_data->whole_rect.left) || - drop->pt.y > (win_data->client_rect.bottom - win_data->whole_rect.top) ); + (drop->pt.x < (win_data->rects.client.left - win_data->rects.visible.left) || + drop->pt.y < (win_data->rects.client.top - win_data->rects.visible.top) || + drop->pt.x > (win_data->rects.client.right - win_data->rects.visible.left) || + drop->pt.y > (win_data->rects.client.bottom - win_data->rects.visible.top) ); release_win_data( win_data ); }
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 30444de0cdf..ee0191630f7 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -513,12 +513,12 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x { if (window == data->whole_window) { - pt.x += data->whole_rect.left - data->client_rect.left; - pt.y += data->whole_rect.top - data->client_rect.top; + pt.x += data->rects.visible.left - data->rects.client.left; + pt.y += data->rects.visible.top - data->rects.client.top; }
if (NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) - pt.x = data->client_rect.right - data->client_rect.left - 1 - pt.x; + pt.x = data->rects.client.right - data->rects.client.left - 1 - pt.x; NtUserMapWindowPoints( hwnd, 0, &pt, 1, 0 /* per-monitor DPI */ ); } release_win_data( data ); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index c7c785d2510..6b0329418cf 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -297,7 +297,7 @@ static inline BOOL is_window_resizable( struct x11drv_win_data *data, DWORD styl { if (style & WS_THICKFRAME) return TRUE; /* Metacity needs the window to be resizable to make it fullscreen */ - return NtUserIsWindowRectFullScreen( &data->whole_rect, get_win_monitor_dpi( data->hwnd ) ); + return NtUserIsWindowRectFullScreen( &data->rects.visible, get_win_monitor_dpi( data->hwnd ) ); }
/*********************************************************************** @@ -388,7 +388,7 @@ static void sync_window_style( struct x11drv_win_data *data ) static void sync_empty_window_shape( struct x11drv_win_data *data, struct window_surface *surface ) { #ifdef HAVE_LIBXSHAPE - if (IsRectEmpty( &data->window_rect )) /* set an empty shape */ + if (IsRectEmpty( &data->rects.window )) /* set an empty shape */ { static XRectangle empty_rect; XShapeCombineRectangles( data->display, data->whole_window, ShapeBounding, 0, 0, @@ -440,8 +440,8 @@ static void sync_window_region( struct x11drv_win_data *data, HRGN win_region ) if ((pRegionData = X11DRV_GetRegionData( hrgn, 0 ))) { XShapeCombineRectangles( data->display, data->whole_window, ShapeBounding, - data->window_rect.left - data->whole_rect.left, - data->window_rect.top - data->whole_rect.top, + data->rects.window.left - data->rects.visible.left, + data->rects.window.top - data->rects.visible.top, (XRectangle *)pRegionData->Buffer, pRegionData->rdh.nCount, ShapeSet, YXBanded ); free( pRegionData ); @@ -745,7 +745,7 @@ static void set_size_hints( struct x11drv_win_data *data, DWORD style ) { if (data->hwnd != NtUserGetDesktopWindow()) /* don't force position of desktop */ { - POINT pt = virtual_screen_to_root( data->whole_rect.left, data->whole_rect.top ); + POINT pt = virtual_screen_to_root( data->rects.visible.left, data->rects.visible.top ); size_hints->x = pt.x; size_hints->y = pt.y; size_hints->flags |= PPosition; @@ -754,8 +754,8 @@ static void set_size_hints( struct x11drv_win_data *data, DWORD style )
if (!is_window_resizable( data, style )) { - size_hints->max_width = data->whole_rect.right - data->whole_rect.left; - size_hints->max_height = data->whole_rect.bottom - data->whole_rect.top; + size_hints->max_width = data->rects.visible.right - data->rects.visible.left; + size_hints->max_height = data->rects.visible.bottom - data->rects.visible.top; if (size_hints->max_width <= 0 ||size_hints->max_height <= 0) size_hints->max_width = size_hints->max_height = 1; size_hints->min_width = size_hints->max_width; @@ -787,7 +787,7 @@ static void set_mwm_hints( struct x11drv_win_data *data, UINT style, UINT ex_sty } else { - mwm_hints.decorations = get_mwm_decorations( data, style, ex_style, &data->window_rect, &data->client_rect ); + mwm_hints.decorations = get_mwm_decorations( data, style, ex_style, &data->rects.window, &data->rects.client ); mwm_hints.functions = MWM_FUNC_MOVE; if (is_window_resizable( data, style )) mwm_hints.functions |= MWM_FUNC_RESIZE; if (!(style & WS_DISABLED)) @@ -1053,7 +1053,7 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data ) if (!X11DRV_DisplayDevices_SupportEventHandlers()) return;
- if (!xinerama_get_fullscreen_monitors( &data->whole_rect, monitors )) + if (!xinerama_get_fullscreen_monitors( &data->rects.visible, monitors )) return;
/* If _NET_WM_FULLSCREEN_MONITORS is not set and the fullscreen monitors are spanning only one @@ -1109,7 +1109,7 @@ void update_net_wm_states( struct x11drv_win_data *data ) style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); if (style & WS_MINIMIZE) new_state |= data->net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED)); - if (NtUserIsWindowRectFullScreen( &data->whole_rect, get_win_monitor_dpi( data->hwnd ) )) + if (NtUserIsWindowRectFullScreen( &data->rects.visible, get_win_monitor_dpi( data->hwnd ) )) { if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION) new_state |= (1 << NET_WM_STATE_MAXIMIZED); @@ -1357,14 +1357,14 @@ void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect, int x, i { RECT rc;
- get_decoration_rect( data, &rc, &data->window_rect, &data->client_rect ); + get_decoration_rect( data, &rc, &data->rects.window, &data->rects.client );
- x += min( data->window_rect.left - data->whole_rect.left, rc.left ); - y += min( data->window_rect.top - data->whole_rect.top, rc.top ); - cx += max( (data->window_rect.right - data->window_rect.left) - - (data->whole_rect.right - data->whole_rect.left), rc.right - rc.left ); - cy += max( (data->window_rect.bottom - data->window_rect.top) - - (data->whole_rect.bottom - data->whole_rect.top), rc.bottom - rc.top ); + x += min( data->rects.window.left - data->rects.visible.left, rc.left ); + y += min( data->rects.window.top - data->rects.visible.top, rc.top ); + cx += max( (data->rects.window.right - data->rects.window.left) - + (data->rects.visible.right - data->rects.visible.left), rc.right - rc.left ); + cy += max( (data->rects.window.bottom - data->rects.window.top) - + (data->rects.visible.bottom - data->rects.visible.top), rc.bottom - rc.top ); SetRect( rect, x, y, x + cx, y + cy ); }
@@ -1374,9 +1374,7 @@ void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect, int x, i * * Synchronize the X window position with the Windows one */ -static void sync_window_position( struct x11drv_win_data *data, - UINT swp_flags, const RECT *old_window_rect, - const RECT *old_whole_rect, const RECT *old_client_rect ) +static void sync_window_position( struct x11drv_win_data *data, UINT swp_flags ) { DWORD style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); DWORD ex_style = NtUserGetWindowLongW( data->hwnd, GWL_EXSTYLE ); @@ -1388,8 +1386,8 @@ static void sync_window_position( struct x11drv_win_data *data, /* resizing a managed maximized window is not allowed */ if (!(style & WS_MAXIMIZE) || !data->managed) { - changes.width = data->whole_rect.right - data->whole_rect.left; - changes.height = data->whole_rect.bottom - data->whole_rect.top; + changes.width = data->rects.visible.right - data->rects.visible.left; + changes.height = data->rects.visible.bottom - data->rects.visible.top; /* if window rect is empty force size to 1x1 */ if (changes.width <= 0 || changes.height <= 0) changes.width = changes.height = 1; if (changes.width > 65535) changes.width = 65535; @@ -1400,7 +1398,7 @@ static void sync_window_position( struct x11drv_win_data *data, /* only the size is allowed to change for the desktop window or systray docked windows */ if (data->whole_window != root_window && !data->embedded) { - POINT pt = virtual_screen_to_root( data->whole_rect.left, data->whole_rect.top ); + POINT pt = virtual_screen_to_root( data->rects.visible.left, data->rects.visible.top ); changes.x = pt.x; changes.y = pt.y; mask |= CWX | CWY; @@ -1428,9 +1426,9 @@ static void sync_window_position( struct x11drv_win_data *data, XReconfigureWMWindow( data->display, data->whole_window, data->vis.screen, mask, &changes );
TRACE( "win %p/%lx pos %d,%d,%dx%d after %lx changes=%x serial=%lu\n", - data->hwnd, data->whole_window, (int)data->whole_rect.left, (int)data->whole_rect.top, - (int)(data->whole_rect.right - data->whole_rect.left), - (int)(data->whole_rect.bottom - data->whole_rect.top), + data->hwnd, data->whole_window, (int)data->rects.visible.left, (int)data->rects.visible.top, + (int)(data->rects.visible.right - data->rects.visible.left), + (int)(data->rects.visible.bottom - data->rects.visible.top), changes.sibling, mask, data->configure_serial ); }
@@ -1440,23 +1438,22 @@ static void sync_window_position( struct x11drv_win_data *data, * * Synchronize the X client window position with the Windows one */ -static void sync_client_position( struct x11drv_win_data *data, - const RECT *old_client_rect, const RECT *old_whole_rect ) +static void sync_client_position( struct x11drv_win_data *data, const struct window_rects *old_rects ) { int mask = 0; XWindowChanges changes;
if (!data->client_window) return;
- changes.x = data->client_rect.left - data->whole_rect.left; - changes.y = data->client_rect.top - data->whole_rect.top; - changes.width = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 ); - changes.height = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 ); + changes.x = data->rects.client.left - data->rects.visible.left; + changes.y = data->rects.client.top - data->rects.visible.top; + changes.width = min( max( 1, data->rects.client.right - data->rects.client.left ), 65535 ); + changes.height = min( max( 1, data->rects.client.bottom - data->rects.client.top ), 65535 );
- if (changes.x != old_client_rect->left - old_whole_rect->left) mask |= CWX; - if (changes.y != old_client_rect->top - old_whole_rect->top) mask |= CWY; - if (changes.width != old_client_rect->right - old_client_rect->left) mask |= CWWidth; - if (changes.height != old_client_rect->bottom - old_client_rect->top) mask |= CWHeight; + if (changes.x != old_rects->client.left - old_rects->visible.left) mask |= CWX; + if (changes.y != old_rects->client.top - old_rects->visible.top) mask |= CWY; + if (changes.width != old_rects->client.right - old_rects->client.left) mask |= CWWidth; + if (changes.height != old_rects->client.bottom - old_rects->client.top) mask |= CWHeight;
if (mask) { @@ -1625,8 +1622,8 @@ static void attach_client_window( struct x11drv_win_data *data, Window client_wi if (data->whole_window) { client_window_events_enable( data, client_window ); - XReparentWindow( gdi_display, client_window, data->whole_window, data->client_rect.left - data->whole_rect.left, - data->client_rect.top - data->whole_rect.top ); + XReparentWindow( gdi_display, client_window, data->whole_window, data->rects.client.left - data->rects.visible.left, + data->rects.client.top - data->rects.visible.top ); }
data->client_window = client_window; @@ -1673,8 +1670,8 @@ Window create_client_window( HWND hwnd, const XVisualInfo *visual, Colormap colo HWND parent = NtUserGetAncestor( hwnd, GA_PARENT ); if (parent == NtUserGetDesktopWindow() || NtUserGetAncestor( parent, GA_PARENT )) return 0; if (!(data = alloc_win_data( thread_init_display(), hwnd ))) return 0; - NtUserGetClientRect( hwnd, &data->client_rect, get_win_monitor_dpi( hwnd ) ); - data->window_rect = data->whole_rect = data->client_rect; + NtUserGetClientRect( hwnd, &data->rects.client, get_win_monitor_dpi( hwnd ) ); + data->rects.window = data->rects.visible = data->rects.client; }
detach_client_window( data, data->client_window ); @@ -1685,10 +1682,10 @@ Window create_client_window( HWND hwnd, const XVisualInfo *visual, Colormap colo attr.backing_store = NotUseful; attr.border_pixel = 0;
- x = data->client_rect.left - data->whole_rect.left; - y = data->client_rect.top - data->whole_rect.top; - cx = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 ); - cy = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 ); + x = data->rects.client.left - data->rects.visible.left; + y = data->rects.client.top - data->rects.visible.top; + cx = min( max( 1, data->rects.client.right - data->rects.client.left ), 65535 ); + cy = min( max( 1, data->rects.client.bottom - data->rects.client.top ), 65535 );
XSync( gdi_display, False ); /* make sure whole_window is known from gdi_display */ ret = data->client_window = XCreateWindow( gdi_display, @@ -1727,7 +1724,7 @@ static void create_whole_window( struct x11drv_win_data *data ) HRGN win_rgn; POINT pos;
- if (!data->managed && is_window_managed( data->hwnd, SWP_NOACTIVATE, &data->window_rect )) + if (!data->managed && is_window_managed( data->hwnd, SWP_NOACTIVATE, &data->rects.window )) { TRACE( "making win %p/%lx managed\n", data->hwnd, data->whole_window ); data->managed = TRUE; @@ -1746,12 +1743,12 @@ static void create_whole_window( struct x11drv_win_data *data )
mask = get_window_attributes( data, &attr );
- if (!(cx = data->whole_rect.right - data->whole_rect.left)) cx = 1; + if (!(cx = data->rects.visible.right - data->rects.visible.left)) cx = 1; else if (cx > 65535) cx = 65535; - if (!(cy = data->whole_rect.bottom - data->whole_rect.top)) cy = 1; + if (!(cy = data->rects.visible.bottom - data->rects.visible.top)) cy = 1; else if (cy > 65535) cy = 65535;
- pos = virtual_screen_to_root( data->whole_rect.left, data->whole_rect.top ); + pos = virtual_screen_to_root( data->rects.visible.left, data->rects.visible.top ); data->whole_window = XCreateWindow( data->display, root_window, pos.x, pos.y, cx, cy, 0, data->vis.depth, InputOutput, data->vis.visual, mask, &attr ); @@ -1769,7 +1766,7 @@ static void create_whole_window( struct x11drv_win_data *data ) sync_window_text( data->display, data->whole_window, text );
/* set the window region */ - if (IsRectEmpty( &data->window_rect )) sync_empty_window_shape( data, NULL ); + if (IsRectEmpty( &data->rects.window )) sync_empty_window_shape( data, NULL ); else if (win_rgn) sync_window_region( data, win_rgn );
/* set the window opacity */ @@ -2108,8 +2105,7 @@ void release_win_data( struct x11drv_win_data *data ) * * Create an X11 data window structure for an existing window. */ -static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const RECT *window_rect, - const RECT *client_rect ) +static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const struct window_rects *rects ) { Display *display; struct x11drv_win_data *data; @@ -2131,15 +2127,14 @@ static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const RECT *wi init_clip_window(); /* make sure the clip window is initialized in this thread */
if (!(data = alloc_win_data( display, hwnd ))) return NULL; + data->rects = *rects;
- data->whole_rect = data->window_rect = *window_rect; - data->client_rect = *client_rect; if (parent == NtUserGetDesktopWindow()) { create_whole_window( data ); TRACE( "win %p/%lx window %s whole %s client %s\n", - hwnd, data->whole_window, wine_dbgstr_rect( &data->window_rect ), - wine_dbgstr_rect( &data->whole_rect ), wine_dbgstr_rect( &data->client_rect )); + hwnd, data->whole_window, wine_dbgstr_rect( &data->rects.window ), + wine_dbgstr_rect( &data->rects.visible ), wine_dbgstr_rect( &data->rects.client )); } return data; } @@ -2223,7 +2218,7 @@ HWND create_foreign_window( Display *display, Window xwin ) XSaveContext( display, xwin, winContext, (char *)data->hwnd );
TRACE( "win %lx parent %p style %08x %s -> hwnd %p\n", - xwin, parent, style, wine_dbgstr_rect(&data->window_rect), hwnd ); + xwin, parent, style, wine_dbgstr_rect(&data->rects.window), hwnd );
release_win_data( data );
@@ -2565,7 +2560,7 @@ BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const str
TRACE( "hwnd %p, swp_flags %#x, shaped %u, rects %s\n", hwnd, swp_flags, shaped, debugstr_window_rects( rects ) );
- if (!data && !(data = X11DRV_create_win_data( hwnd, &rects->window, &rects->client ))) return FALSE; /* use default surface */ + if (!data && !(data = X11DRV_create_win_data( hwnd, rects ))) return FALSE; /* use default surface */ data->shaped = shaped;
/* check if we need to switch the window to managed */ @@ -2594,8 +2589,8 @@ void X11DRV_MoveWindowBits( HWND hwnd, const struct window_rects *new_rects, con Window window;
if (!(data = get_win_data( hwnd ))) return; - old_visible_rect = data->whole_rect; - old_client_rect = data->client_rect; + old_visible_rect = data->rects.visible; + old_client_rect = data->rects.client; window = data->whole_window; release_win_data( data );
@@ -2648,34 +2643,30 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, cons struct x11drv_thread_data *thread_data; struct x11drv_win_data *data; UINT new_style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); - RECT old_window_rect, old_whole_rect, old_client_rect; + struct window_rects old_rects; int event_type;
if (!(data = get_win_data( hwnd ))) return;
thread_data = x11drv_thread_data();
- old_window_rect = data->window_rect; - old_whole_rect = data->whole_rect; - old_client_rect = data->client_rect; - data->window_rect = new_rects->window; - data->whole_rect = new_rects->visible; - data->client_rect = new_rects->client; + old_rects = data->rects; + data->rects = *new_rects;
TRACE( "win %p/%lx new_rects %s style %08x flags %08x\n", hwnd, data->whole_window, debugstr_window_rects(new_rects), new_style, swp_flags );
XFlush( gdi_display ); /* make sure painting is done before we move the window */
- sync_client_position( data, &old_client_rect, &old_whole_rect ); + sync_client_position( data, &old_rects );
if (!data->whole_window) { BOOL needs_resize = (!data->client_window && - (data->client_rect.right - data->client_rect.left != - old_client_rect.right - old_client_rect.left || - data->client_rect.bottom - data->client_rect.top != - old_client_rect.bottom - old_client_rect.top)); + (data->rects.client.right - data->rects.client.left != + old_rects.client.right - old_rects.client.left || + data->rects.client.bottom - data->rects.client.top != + old_rects.client.bottom - old_rects.client.top)); release_win_data( data ); if (needs_resize) sync_gl_drawable( hwnd, FALSE ); return; @@ -2697,11 +2688,11 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, cons { if (((swp_flags & SWP_HIDEWINDOW) && !(new_style & WS_VISIBLE)) || (!event_type && !(new_style & WS_MINIMIZE) && - !is_window_rect_mapped( &new_rects->window ) && is_window_rect_mapped( &old_window_rect ))) + !is_window_rect_mapped( &new_rects->window ) && is_window_rect_mapped( &old_rects.window ))) { release_win_data( data ); unmap_window( hwnd ); - if (NtUserIsWindowRectFullScreen( &old_window_rect, get_win_monitor_dpi( hwnd ) )) + if (NtUserIsWindowRectFullScreen( &old_rects.window, get_win_monitor_dpi( hwnd ) )) NtUserClipCursor( NULL ); if (!(data = get_win_data( hwnd ))) return; } @@ -2711,16 +2702,16 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, cons if (!event_type && !(data->managed && (swp_flags & SWP_STATECHANGED) && (new_style & (WS_MINIMIZE|WS_MAXIMIZE)))) { - sync_window_position( data, swp_flags, &old_window_rect, &old_whole_rect, &old_client_rect ); + sync_window_position( data, swp_flags ); #ifdef HAVE_LIBXSHAPE - if (IsRectEmpty( &old_window_rect ) != IsRectEmpty( &data->window_rect )) + if (IsRectEmpty( &old_rects.window ) != IsRectEmpty( &new_rects->window )) sync_empty_window_shape( data, surface ); if (data->shaped) { - int old_x_offset = old_window_rect.left - old_whole_rect.left; - int old_y_offset = old_window_rect.top - old_whole_rect.top; - int new_x_offset = data->window_rect.left - data->whole_rect.left; - int new_y_offset = data->window_rect.top - data->whole_rect.top; + int old_x_offset = old_rects.window.left - old_rects.visible.left; + int old_y_offset = old_rects.window.top - old_rects.visible.top; + int new_x_offset = new_rects->window.left - new_rects->visible.left; + int new_y_offset = new_rects->window.top - new_rects->visible.top; if (old_x_offset != new_x_offset || old_y_offset != new_y_offset) XShapeOffsetShape( data->display, data->whole_window, ShapeBounding, new_x_offset - old_x_offset, new_y_offset - old_y_offset ); @@ -2896,7 +2887,7 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO DWORD style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
if ((style & WS_VISIBLE) && - ((style & WS_MINIMIZE) || is_window_rect_mapped( &data->window_rect ))) + ((style & WS_MINIMIZE) || is_window_rect_mapped( &data->rects.window ))) { release_win_data( data ); map_window( hwnd, style ); @@ -2935,7 +2926,7 @@ void X11DRV_UpdateLayeredWindow( HWND hwnd, UINT flags ) { DWORD style = NtUserGetWindowLongW( hwnd, GWL_STYLE );
- if ((style & WS_VISIBLE) && ((style & WS_MINIMIZE) || is_window_rect_mapped( &data->window_rect ))) + if ((style & WS_VISIBLE) && ((style & WS_MINIMIZE) || is_window_rect_mapped( &data->rects.window ))) map_window( hwnd, style ); } } @@ -3002,8 +2993,8 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) if (data->whole_window) { /* sync window position with the new virtual screen rect */ - POINT old_pos = {.x = data->whole_rect.left - wp, .y = data->whole_rect.top - lp}; - POINT pos = virtual_screen_to_root( data->whole_rect.left, data->whole_rect.top ); + POINT old_pos = {.x = data->rects.visible.left - wp, .y = data->rects.visible.top - lp}; + POINT pos = virtual_screen_to_root( data->rects.visible.left, data->rects.visible.top ); XWindowChanges changes = {.x = pos.x, .y = pos.y}; UINT mask = 0;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index c0cf020067e..947eb1a10e3 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -600,9 +600,7 @@ struct x11drv_win_data HWND hwnd; /* hwnd that this private data belongs to */ Window whole_window; /* X window for the complete window */ Window client_window; /* X window for the client area */ - RECT window_rect; /* USER window rectangle relative to win32 parent window client area */ - RECT whole_rect; /* X window rectangle for the whole window relative to win32 parent window client area */ - RECT client_rect; /* client area relative to win32 parent window client area */ + struct window_rects rects; /* window rects in monitor DPI, relative to parent client area */ XIC xic; /* X input context */ UINT managed : 1; /* is window managed? */ UINT mapped : 1; /* is window mapped? (in either normal or iconic state) */ diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 1bb20c845f3..732a55a978a 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -507,10 +507,10 @@ BOOL X11DRV_SetIMECompositionWindowPos( HWND hwnd, const POINT *point )
pt = *point; if (NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) - pt.x = data->client_rect.right - data->client_rect.left - 1 - pt.x; + pt.x = data->rects.client.right - data->rects.client.left - 1 - pt.x;
- xpoint.x = pt.x + data->client_rect.left - data->whole_rect.left; - xpoint.y = pt.y + data->client_rect.top - data->whole_rect.top; + xpoint.x = pt.x + data->rects.client.left - data->rects.visible.left; + xpoint.y = pt.y + data->rects.client.top - data->rects.visible.top; attr = XVaCreateNestedList( 0, XNSpotLocation, &xpoint, NULL ); if (attr) {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 3 ++- dlls/winex11.drv/window.c | 53 ++------------------------------------- dlls/winex11.drv/x11drv.h | 1 - 3 files changed, 4 insertions(+), 53 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index ca9ab4b8aed..e7cc3855c2d 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1073,7 +1073,8 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) } else pos = root_to_virtual_screen( x, y );
- X11DRV_X_to_window_rect( data, &rect, pos.x, pos.y, event->width, event->height ); + SetRect( &rect, pos.x, pos.y, pos.x + event->width, pos.y + event->height ); + rect = window_rect_from_visible( &data->rects, rect ); if (root_coords) NtUserMapWindowPoints( 0, parent, (POINT *)&rect, 2, 0 /* per-monitor DPI */ );
TRACE( "win %p/%lx new X rect %d,%d,%dx%d (event %d,%d,%dx%d)\n", diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 6b0329418cf..82c6a372530 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1319,56 +1319,6 @@ void make_window_embedded( struct x11drv_win_data *data ) }
-/*********************************************************************** - * get_decoration_rect - */ -static void get_decoration_rect( struct x11drv_win_data *data, RECT *rect, - const RECT *window_rect, const RECT *client_rect ) -{ - DWORD style, ex_style, style_mask = 0, ex_style_mask = 0; - unsigned long decor; - UINT dpi; - - SetRectEmpty( rect ); - if (!data->managed) return; - - dpi = get_win_monitor_dpi( data->hwnd ); - style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); - ex_style = NtUserGetWindowLongW( data->hwnd, GWL_EXSTYLE ); - decor = get_mwm_decorations( data, style, ex_style, window_rect, client_rect ); - - if (decor & MWM_DECOR_TITLE) style_mask |= WS_CAPTION; - if (decor & MWM_DECOR_BORDER) - { - style_mask |= WS_DLGFRAME | WS_THICKFRAME; - ex_style_mask |= WS_EX_DLGMODALFRAME; - } - - NtUserAdjustWindowRect( rect, style & style_mask, FALSE, ex_style & ex_style_mask, dpi ); -} - - -/*********************************************************************** - * X11DRV_X_to_window_rect - * - * Opposite of X11DRV_window_to_X_rect - */ -void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect, int x, int y, int cx, int cy ) -{ - RECT rc; - - get_decoration_rect( data, &rc, &data->rects.window, &data->rects.client ); - - x += min( data->rects.window.left - data->rects.visible.left, rc.left ); - y += min( data->rects.window.top - data->rects.visible.top, rc.top ); - cx += max( (data->rects.window.right - data->rects.window.left) - - (data->rects.visible.right - data->rects.visible.left), rc.right - rc.left ); - cy += max( (data->rects.window.bottom - data->rects.window.top) - - (data->rects.visible.bottom - data->rects.visible.top), rc.bottom - rc.top ); - SetRect( rect, x, y, x + cx, y + cy ); -} - - /*********************************************************************** * sync_window_position * @@ -2810,7 +2760,8 @@ UINT X11DRV_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ) &root, &x, &y, &width, &height, &border, &depth ); XTranslateCoordinates( thread_data->display, data->whole_window, root, 0, 0, &x, &y, &top ); pos = root_to_virtual_screen( x, y ); - X11DRV_X_to_window_rect( data, rect, pos.x, pos.y, width, height ); + SetRect( rect, pos.x, pos.y, pos.x + width, pos.y + height ); + *rect = window_rect_from_visible( &data->rects, *rect ); swp &= ~(SWP_NOMOVE | SWP_NOCLIENTMOVE | SWP_NOSIZE | SWP_NOCLIENTSIZE);
done: diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 947eb1a10e3..b87d6a87932 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -678,7 +678,6 @@ typedef int (*x11drv_error_callback)( Display *display, XErrorEvent *event, void
extern void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg ); extern int X11DRV_check_error(void); -extern void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect, int x, int y, int cx, int cy ); extern POINT virtual_screen_to_root( INT x, INT y ); extern POINT root_to_virtual_screen( INT x, INT y ); extern RECT get_host_primary_monitor_rect(void);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 23 +++++++++++++++++++++++ dlls/win32u/win32u_private.h | 1 + dlls/win32u/window.c | 8 +++++++- 3 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index a5e6a244264..2522ade91e4 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2248,6 +2248,29 @@ RECT map_dpi_rect( RECT rect, UINT dpi_from, UINT dpi_to ) return rect; }
+/********************************************************************** + * map_dpi_region + */ +HRGN map_dpi_region( HRGN hrgn, UINT dpi_from, UINT dpi_to ) +{ + RGNDATA *data; + UINT i, size; + + if (!(size = NtGdiGetRegionData( hrgn, 0, NULL ))) return 0; + if (!(data = malloc( size ))) return 0; + NtGdiGetRegionData( hrgn, size, data ); + + if (dpi_from && dpi_to && dpi_from != dpi_to) + { + RECT *rects = (RECT *)data->Buffer; + for (i = 0; i < data->rdh.nCount; i++) rects[i] = map_dpi_rect( rects[i], dpi_from, dpi_to ); + } + + hrgn = NtGdiExtCreateRegion( NULL, data->rdh.dwSize + data->rdh.nRgnSize, data ); + free( data ); + return hrgn; +} + /********************************************************************** * map_dpi_point */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 47b50c87f14..0fce687cb18 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -182,6 +182,7 @@ extern RECT get_virtual_screen_rect( UINT dpi ); extern BOOL is_exiting_thread( DWORD tid ); extern POINT map_dpi_point( POINT pt, UINT dpi_from, UINT dpi_to ); extern RECT map_dpi_rect( RECT rect, UINT dpi_from, UINT dpi_to ); +extern HRGN map_dpi_region( HRGN region, UINT dpi_from, UINT dpi_to ); extern BOOL message_beep( UINT i ); extern POINT point_phys_to_win_dpi( HWND hwnd, POINT pt ); extern POINT point_thread_to_win_dpi( HWND hwnd, POINT pt ); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index f17e45231ad..f80cb64f204 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2233,8 +2233,14 @@ int WINAPI NtUserSetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw ) { UINT swp_flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE; + HRGN monitor_hrgn; + if (!redraw) swp_flags |= SWP_NOREDRAW; - user_driver->pSetWindowRgn( hwnd, hrgn, redraw ); + + monitor_hrgn = map_dpi_region( hrgn, get_thread_dpi(), get_win_monitor_dpi( hwnd ) ); + user_driver->pSetWindowRgn( hwnd, monitor_hrgn, redraw ); + if (monitor_hrgn) NtGdiDeleteObjectApp( monitor_hrgn ); + NtUserSetWindowPos( hwnd, 0, 0, 0, 0, 0, swp_flags ); if (hrgn) NtGdiDeleteObjectApp( hrgn ); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 11 +++++++++++ dlls/win32u/win32u_private.h | 1 + dlls/win32u/window.c | 26 ++++++++++++++++++++++---- 3 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 2522ade91e4..c5924609401 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2271,6 +2271,17 @@ HRGN map_dpi_region( HRGN hrgn, UINT dpi_from, UINT dpi_to ) return hrgn; }
+/********************************************************************** + * map_dpi_window_rects + */ +struct window_rects map_dpi_window_rects( struct window_rects rects, UINT dpi_from, UINT dpi_to ) +{ + rects.window = map_dpi_rect( rects.window, dpi_from, dpi_to ); + rects.client = map_dpi_rect( rects.client, dpi_from, dpi_to ); + rects.visible = map_dpi_rect( rects.visible, dpi_from, dpi_to ); + return rects; +} + /********************************************************************** * map_dpi_point */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 0fce687cb18..3155ebab984 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -183,6 +183,7 @@ extern BOOL is_exiting_thread( DWORD tid ); extern POINT map_dpi_point( POINT pt, UINT dpi_from, UINT dpi_to ); extern RECT map_dpi_rect( RECT rect, UINT dpi_from, UINT dpi_to ); extern HRGN map_dpi_region( HRGN region, UINT dpi_from, UINT dpi_to ); +extern struct window_rects map_dpi_window_rects( struct window_rects rects, UINT dpi_from, UINT dpi_to ); extern BOOL message_beep( UINT i ); extern POINT point_phys_to_win_dpi( HWND hwnd, POINT pt ); extern POINT point_thread_to_win_dpi( HWND hwnd, POINT pt ); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index f80cb64f204..ca36d9bb56d 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1896,17 +1896,23 @@ static struct window_surface *create_window_surface( HWND hwnd, UINT swp_flags, BOOL shaped, needs_surface, create_opaque, is_layered; HWND parent = NtUserGetAncestor( hwnd, GA_PARENT ); struct window_surface *new_surface; - UINT style, ex_style; + struct window_rects monitor_rects; + UINT monitor_dpi, style, ex_style; + HMONITOR monitor; RECT dummy; HRGN shape;
+ monitor = monitor_from_rect( &rects->window, MONITOR_DEFAULTTONEAREST, get_thread_dpi() ); + monitor_dpi = get_monitor_dpi( monitor ); + style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); ex_style = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE );
if (get_window_region( hwnd, FALSE, &shape, &dummy )) shaped = FALSE; else if ((shaped = !!shape)) NtGdiDeleteObjectApp( shape );
- if (!user_driver->pWindowPosChanging( hwnd, swp_flags, shaped, rects )) needs_surface = FALSE; + monitor_rects = map_dpi_window_rects( *rects, get_thread_dpi(), monitor_dpi ); + if (!user_driver->pWindowPosChanging( hwnd, swp_flags, shaped, &monitor_rects )) needs_surface = FALSE; else if (parent && parent != NtUserGetDesktopWindow()) needs_surface = FALSE; else if (swp_flags & SWP_HIDEWINDOW) needs_surface = FALSE; else if (swp_flags & SWP_SHOWWINDOW) needs_surface = TRUE; @@ -1969,12 +1975,15 @@ static struct window_surface *create_window_surface( HWND hwnd, UINT swp_flags, static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, struct window_surface *new_surface, const struct window_rects *new_rects, const RECT *valid_rects ) { + struct window_rects monitor_rects; WND *win; HWND surface_win = 0; BOOL ret, is_layered, needs_update = FALSE; struct window_rects old_rects; RECT extra_rects[3]; struct window_surface *old_surface; + HMONITOR monitor; + UINT monitor_dpi;
is_layered = new_surface && new_surface->alpha_mask;
@@ -1994,6 +2003,11 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru valid_rects = NULL; }
+ monitor = monitor_from_rect( &new_rects->window, MONITOR_DEFAULTTONEAREST, get_thread_dpi() ); + monitor_dpi = get_monitor_dpi( monitor ); + + monitor_rects = map_dpi_window_rects( *new_rects, get_thread_dpi(), monitor_dpi ); + SERVER_START_REQ( set_window_pos ) { req->handle = wine_server_user_handle( hwnd ); @@ -2091,10 +2105,14 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru if (surface_win && surface_win != hwnd) move_window_bits( hwnd, &new_rects->visible, &new_rects->visible, &new_rects->window, valid_rects ); else - user_driver->pMoveWindowBits( hwnd, new_rects, valid_rects ); + { + rects[0] = map_dpi_rect( valid_rects[0], get_thread_dpi(), monitor_dpi ); + rects[1] = map_dpi_rect( valid_rects[1], get_thread_dpi(), monitor_dpi ); + user_driver->pMoveWindowBits( hwnd, &monitor_rects, rects ); + } }
- user_driver->pWindowPosChanged( hwnd, insert_after, swp_flags, new_rects, new_surface ); + user_driver->pWindowPosChanged( hwnd, insert_after, swp_flags, &monitor_rects, new_surface ); }
return ret;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 16 +++++++++++++++- dlls/win32u/win32u_private.h | 4 ++-- dlls/win32u/window.c | 24 ++++++++++-------------- 3 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 6749e2b1725..8bad1949ebd 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -115,7 +115,7 @@ static const struct window_surface_funcs offscreen_window_surface_funcs = offscreen_window_surface_destroy };
-void create_offscreen_window_surface( HWND hwnd, const RECT *surface_rect, struct window_surface **window_surface ) +static void create_offscreen_window_surface( HWND hwnd, const RECT *surface_rect, struct window_surface **window_surface ) { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; struct window_surface *surface, *previous; @@ -138,6 +138,20 @@ void create_offscreen_window_surface( HWND hwnd, const RECT *surface_rect, struc *window_surface = window_surface_create( sizeof(*surface), &offscreen_window_surface_funcs, hwnd, surface_rect, info, 0 ); }
+void create_window_surface( HWND hwnd, BOOL create_layered, const RECT *surface_rect, + struct window_surface **window_surface ) +{ + if (!user_driver->pCreateWindowSurface( hwnd, create_layered, surface_rect, window_surface )) + { + if (*window_surface) + { + window_surface_release( *window_surface ); + /* create an offscreen window surface if the driver doesn't implement CreateWindowSurface */ + create_offscreen_window_surface( hwnd, surface_rect, window_surface ); + } + } +} + /* window surface common helpers */
static UINT get_color_component( UINT color, UINT mask ) diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 3155ebab984..c8b2eb4c529 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -45,8 +45,8 @@ extern ULONG_PTR set_icon_param( HICON handle, ULONG_PTR param );
/* dce.c */ extern struct window_surface dummy_surface; -extern void create_offscreen_window_surface( HWND hwnd, const RECT *surface_rect, - struct window_surface **surface ); +extern void create_window_surface( HWND hwnd, BOOL create_layered, const RECT *surface_rect, + struct window_surface **window_surface ); extern void erase_now( HWND hwnd, UINT rdw_flags ); extern void flush_window_surfaces( BOOL idle ); extern void move_window_bits( HWND hwnd, const RECT *visible_rect, const RECT *old_visible_rect, diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index ca36d9bb56d..1835bfa3f47 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1890,8 +1890,8 @@ static BOOL get_default_window_surface( HWND hwnd, const RECT *surface_rect, str return TRUE; }
-static struct window_surface *create_window_surface( HWND hwnd, UINT swp_flags, BOOL create_layered, - struct window_rects *rects, RECT *surface_rect ) +static struct window_surface *get_window_surface( HWND hwnd, UINT swp_flags, BOOL create_layered, + struct window_rects *rects, RECT *surface_rect ) { BOOL shaped, needs_surface, create_opaque, is_layered; HWND parent = NtUserGetAncestor( hwnd, GA_PARENT ); @@ -1940,17 +1940,13 @@ static struct window_surface *create_window_surface( HWND hwnd, UINT swp_flags, if (IsRectEmpty( surface_rect )) needs_surface = FALSE; else if (create_layered || is_layered) needs_surface = TRUE;
- if (!needs_surface && new_surface && new_surface != &dummy_surface) + if (needs_surface) + create_window_surface( hwnd, create_layered, surface_rect, &new_surface ); + else if (new_surface && new_surface != &dummy_surface) { window_surface_release( new_surface ); window_surface_add_ref( (new_surface = &dummy_surface) ); } - else if (needs_surface && !user_driver->pCreateWindowSurface( hwnd, create_layered, surface_rect, &new_surface ) && new_surface) - { - /* create or update window surface for top-level windows if the driver doesn't implement CreateWindowSurface */ - window_surface_release( new_surface ); - create_offscreen_window_surface( hwnd, surface_rect, &new_surface ); - }
if (new_surface && !is_layered) { @@ -2384,7 +2380,7 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_
TRACE( "window %p new_rects %s\n", hwnd, debugstr_window_rects( &new_rects ) );
- surface = create_window_surface( hwnd, swp_flags, TRUE, &new_rects, &surface_rect ); + surface = get_window_surface( hwnd, swp_flags, TRUE, &new_rects, &surface_rect ); apply_window_pos( hwnd, 0, swp_flags, surface, &new_rects, NULL ); if (!surface) return FALSE;
@@ -3699,7 +3695,7 @@ BOOL set_window_pos( WINDOWPOS *winpos, int parent_x, int parent_y )
calc_ncsize( winpos, &old_rects, &new_rects, valid_rects, parent_x, parent_y );
- surface = create_window_surface( winpos->hwnd, winpos->flags, FALSE, &new_rects, &surface_rect ); + surface = get_window_surface( winpos->hwnd, winpos->flags, FALSE, &new_rects, &surface_rect ); if (!apply_window_pos( winpos->hwnd, winpos->hwndInsertAfter, winpos->flags, surface, &new_rects, valid_rects )) { @@ -4498,7 +4494,7 @@ void update_window_state( HWND hwnd ) get_window_rects( hwnd, COORDS_PARENT, &new_rects, get_thread_dpi() ); valid_rects[0] = valid_rects[1] = new_rects.client;
- surface = create_window_surface( hwnd, swp_flags, FALSE, &new_rects, &surface_rect ); + surface = get_window_surface( hwnd, swp_flags, FALSE, &new_rects, &surface_rect ); apply_window_pos( hwnd, 0, swp_flags, surface, &new_rects, valid_rects ); if (surface) window_surface_release( surface );
@@ -5552,7 +5548,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, if (cs.y > 0x7fffffff - cy) new_rects.window.bottom = 0x7fffffff; new_rects.client = new_rects.window;
- surface = create_window_surface( hwnd, SWP_NOZORDER | SWP_NOACTIVATE, FALSE, &new_rects, &surface_rect ); + surface = get_window_surface( hwnd, SWP_NOZORDER | SWP_NOACTIVATE, FALSE, &new_rects, &surface_rect ); if (!apply_window_pos( hwnd, 0, SWP_NOZORDER | SWP_NOACTIVATE, surface, &new_rects, NULL )) { if (surface) window_surface_release( surface ); @@ -5591,7 +5587,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, send_message( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&new_rects.client ); map_window_points( 0, parent, (POINT *)&new_rects.client, 2, win_dpi );
- surface = create_window_surface( hwnd, SWP_NOACTIVATE, FALSE, &new_rects, &surface_rect ); + surface = get_window_surface( hwnd, SWP_NOACTIVATE, FALSE, &new_rects, &surface_rect ); apply_window_pos( hwnd, insert_after, SWP_NOACTIVATE, surface, &new_rects, NULL ); if (surface) window_surface_release( surface ); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 170 +++++++++++++++++++++++++- dlls/win32u/driver.c | 3 +- dlls/win32u/win32u_private.h | 3 +- dlls/win32u/window.c | 4 +- dlls/wineandroid.drv/android.h | 3 +- dlls/wineandroid.drv/window.c | 4 +- dlls/winemac.drv/macdrv.h | 3 +- dlls/winemac.drv/surface.c | 4 +- dlls/winewayland.drv/waylanddrv.h | 3 +- dlls/winewayland.drv/window_surface.c | 4 +- dlls/winex11.drv/bitblt.c | 4 +- dlls/winex11.drv/x11drv.h | 3 +- include/wine/gdi_driver.h | 4 +- 13 files changed, 196 insertions(+), 16 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 8bad1949ebd..e0684c8f86f 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -138,18 +138,184 @@ static void create_offscreen_window_surface( HWND hwnd, const RECT *surface_rect *window_surface = window_surface_create( sizeof(*surface), &offscreen_window_surface_funcs, hwnd, surface_rect, info, 0 ); }
-void create_window_surface( HWND hwnd, BOOL create_layered, const RECT *surface_rect, +struct scaled_surface +{ + struct window_surface header; + struct window_surface *target_surface; + UINT dpi_from; + UINT dpi_to; +}; + +static struct scaled_surface *get_scaled_surface( struct window_surface *window_surface ) +{ + return CONTAINING_RECORD( window_surface, struct scaled_surface, header ); +} + +static void scaled_surface_set_clip( struct window_surface *window_surface, const RECT *rects, UINT count ) +{ + struct scaled_surface *surface = get_scaled_surface( window_surface ); + HRGN hrgn = map_dpi_region( window_surface->clip_region, surface->dpi_from, surface->dpi_to ); + window_surface_set_clip( surface->target_surface, hrgn ); + if (hrgn) NtGdiDeleteObjectApp( hrgn ); +} + +static BOOL scaled_surface_flush( struct window_surface *window_surface, const RECT *rect, const RECT *dirty, + const BITMAPINFO *color_info, const void *color_bits, BOOL shape_changed, + const BITMAPINFO *shape_info, const void *shape_bits ) +{ + struct scaled_surface *surface = get_scaled_surface( window_surface ); + RECT src = *dirty, dst; + HDC hdc_dst, hdc_src; + HBITMAP bitmap = 0; + + src.left &= ~7; + src.top &= ~7; + src.right = (src.right + 7) & ~7; + src.bottom = (src.bottom + 7) & ~7; + + dst = map_dpi_rect( src, surface->dpi_from, surface->dpi_to ); + + hdc_dst = NtGdiCreateCompatibleDC( 0 ); + hdc_src = NtGdiCreateCompatibleDC( 0 ); + + NtGdiSelectBitmap( hdc_src, window_surface->color_bitmap ); + NtGdiSelectBitmap( hdc_dst, surface->target_surface->color_bitmap ); + + NtGdiStretchBlt( hdc_dst, dst.left, dst.top, dst.right - dst.left, dst.bottom - dst.top, + hdc_src, src.left, src.top, src.right - src.left, src.bottom - src.top, + SRCCOPY, 0 ); + + NtGdiDeleteObjectApp( hdc_dst ); + NtGdiDeleteObjectApp( hdc_src ); + if (bitmap) NtGdiDeleteObjectApp( bitmap ); + + window_surface_lock( surface->target_surface ); + add_bounds_rect( &surface->target_surface->bounds, &dst ); + window_surface_unlock( surface->target_surface ); + + if (shape_changed) + { + HRGN hrgn = map_dpi_region( window_surface->shape_region, surface->dpi_from, surface->dpi_to ); + window_surface_set_shape( surface->target_surface, hrgn ); + if (hrgn) NtGdiDeleteObjectApp( hrgn ); + + window_surface_set_layered( surface->target_surface, window_surface->color_key, + window_surface->alpha_bits, window_surface->alpha_mask ); + } + + window_surface_flush( surface->target_surface ); + return TRUE; +} + +static void scaled_surface_destroy( struct window_surface *window_surface ) +{ + struct scaled_surface *surface = get_scaled_surface( window_surface ); + window_surface_release( surface->target_surface ); +} + +static const struct window_surface_funcs scaled_surface_funcs = +{ + scaled_surface_set_clip, + scaled_surface_flush, + scaled_surface_destroy +}; + +static struct window_surface *scaled_surface_create( HWND hwnd, const RECT *surface_rect, UINT dpi_from, UINT dpi_to, + struct window_surface *target_surface ) +{ + char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + BITMAPINFO *info = (BITMAPINFO *)buffer; + struct window_surface *window_surface; + struct scaled_surface *surface; + + memset( info, 0, sizeof(*info) ); + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biWidth = surface_rect->right; + info->bmiHeader.biHeight = -surface_rect->bottom; /* top-down */ + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = 32; + info->bmiHeader.biSizeImage = get_dib_image_size( info ); + info->bmiHeader.biCompression = BI_RGB; + + if ((window_surface = window_surface_create( sizeof(*surface), &scaled_surface_funcs, hwnd, surface_rect, info, 0 ))) + { + surface = get_scaled_surface( window_surface ); + surface->target_surface = target_surface; + surface->dpi_from = dpi_from; + surface->dpi_to = dpi_to; + } + + return window_surface; +} + +static RECT get_surface_rect( RECT rect ) +{ + OffsetRect( &rect, -rect.left, -rect.top ); + + rect.left &= ~127; + rect.top &= ~127; + rect.right = max( rect.left + 128, (rect.right + 127) & ~127 ); + rect.bottom = max( rect.top + 128, (rect.bottom + 127) & ~127 ); + + return rect; +} + +void create_window_surface( HWND hwnd, BOOL create_layered, const RECT *surface_rect, UINT monitor_dpi, struct window_surface **window_surface ) { - if (!user_driver->pCreateWindowSurface( hwnd, create_layered, surface_rect, window_surface )) + struct window_surface *previous, *driver_surface; + UINT dpi = get_thread_dpi(); + RECT monitor_rect; + + window_surface_add_ref( (driver_surface = get_driver_window_surface( *window_surface, monitor_dpi )) ); + + /* check if the driver supports scaling window surfaces directly */ + if (user_driver->pCreateWindowSurface( hwnd, create_layered, dpi, monitor_dpi, surface_rect, &driver_surface )) { + if (*window_surface) window_surface_release( *window_surface ); + *window_surface = driver_surface; + return; + } + + monitor_rect = get_surface_rect( map_dpi_rect( *surface_rect, dpi, monitor_dpi ) ); + if (!user_driver->pCreateWindowSurface( hwnd, create_layered, monitor_dpi, monitor_dpi, &monitor_rect, &driver_surface )) + { + if (driver_surface) window_surface_release( driver_surface ); if (*window_surface) { window_surface_release( *window_surface ); /* create an offscreen window surface if the driver doesn't implement CreateWindowSurface */ create_offscreen_window_surface( hwnd, surface_rect, window_surface ); } + return; } + + if (!driver_surface) + { + if (*window_surface) window_surface_release( *window_surface ); + *window_surface = NULL; + return; + } + + /* reuse previous scaling surface, update its target to the driver surface */ + if ((previous = *window_surface) && previous->funcs == &scaled_surface_funcs) + { + struct scaled_surface *surface = get_scaled_surface( previous ); + window_surface_release( surface->target_surface ); + surface->target_surface = driver_surface; + return; + } + if (previous) window_surface_release( previous ); + + *window_surface = scaled_surface_create( hwnd, surface_rect, dpi, monitor_dpi, driver_surface ); +} + +struct window_surface *get_driver_window_surface( struct window_surface *surface, UINT monitor_dpi ) +{ + if (!surface || surface == &dummy_surface) return surface; + if (surface->funcs != &scaled_surface_funcs) return surface; + if (get_scaled_surface( surface )->dpi_to != monitor_dpi) return &dummy_surface; + return get_scaled_surface( surface )->target_surface; }
/* window surface common helpers */ diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 3e094264d15..db4a94542a1 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -891,7 +891,8 @@ extern BOOL nulldrv_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, U return FALSE; }
-static BOOL nulldrv_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ) +static BOOL nulldrv_CreateWindowSurface( HWND hwnd, BOOL layered, UINT dpi_from, UINT dpi_to, + const RECT *surface_rect, struct window_surface **surface ) { return FALSE; } diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index c8b2eb4c529..1dbae4fe94d 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -45,8 +45,9 @@ extern ULONG_PTR set_icon_param( HICON handle, ULONG_PTR param );
/* dce.c */ extern struct window_surface dummy_surface; -extern void create_window_surface( HWND hwnd, BOOL create_layered, const RECT *surface_rect, +extern void create_window_surface( HWND hwnd, BOOL create_layered, const RECT *surface_rect, UINT monitor_dpi, struct window_surface **window_surface ); +extern struct window_surface *get_driver_window_surface( struct window_surface *surface, UINT monitor_dpi ); extern void erase_now( HWND hwnd, UINT rdw_flags ); extern void flush_window_surfaces( BOOL idle ); extern void move_window_bits( HWND hwnd, const RECT *visible_rect, const RECT *old_visible_rect, diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 1835bfa3f47..12b71b6de82 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1941,7 +1941,7 @@ static struct window_surface *get_window_surface( HWND hwnd, UINT swp_flags, BOO else if (create_layered || is_layered) needs_surface = TRUE;
if (needs_surface) - create_window_surface( hwnd, create_layered, surface_rect, &new_surface ); + create_window_surface( hwnd, create_layered, surface_rect, monitor_dpi, &new_surface ); else if (new_surface && new_surface != &dummy_surface) { window_surface_release( new_surface ); @@ -2108,7 +2108,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru } }
- user_driver->pWindowPosChanged( hwnd, insert_after, swp_flags, &monitor_rects, new_surface ); + user_driver->pWindowPosChanged( hwnd, insert_after, swp_flags, &monitor_rects, get_driver_window_surface( new_surface, monitor_dpi ) ); }
return ret; diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index 850b235f3a1..ade6eae1aa3 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -96,7 +96,8 @@ extern void ANDROID_SetCapture( HWND hwnd, UINT flags ); extern UINT ANDROID_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ); extern LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ); -extern BOOL ANDROID_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ); +extern BOOL ANDROID_CreateWindowSurface( HWND hwnd, BOOL layered, UINT dpi_from, UINT dpi_to, + const RECT *surface_rect, struct window_surface **surface ); extern void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface );
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 537aae456e7..dcb4d1e1212 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1039,13 +1039,15 @@ BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const st /*********************************************************************** * ANDROID_CreateWindowSurface */ -BOOL ANDROID_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ) +BOOL ANDROID_CreateWindowSurface( HWND hwnd, BOOL layered, UINT dpi_from, UINT dpi_to, + const RECT *surface_rect, struct window_surface **surface ) { struct window_surface *previous; struct android_win_data *data;
TRACE( "hwnd %p, layered %u, surface_rect %s, surface %p\n", hwnd, layered, wine_dbgstr_rect( surface_rect ), surface );
+ if (dpi_from != dpi_to) return FALSE; /* use default implementation */ if ((previous = *surface) && previous->funcs == &android_surface_funcs) return TRUE; if (!(data = get_win_data( hwnd ))) return TRUE; /* use default surface */ if (previous) window_surface_release( previous ); diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 6e506514164..b80162e522b 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -149,7 +149,8 @@ extern void macdrv_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alph extern LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); extern BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects); extern BOOL macdrv_GetWindowStyleMasks(HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask); -extern BOOL macdrv_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); +extern BOOL macdrv_CreateWindowSurface(HWND hwnd, BOOL layered, UINT dpi_from, UINT dpi_to, + const RECT *surface_rect, struct window_surface **surface); extern void macdrv_MoveWindowBits(HWND hwnd, const struct window_rects *new_rects, const RECT *valid_rects); extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface); diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index a849918dfa7..85170777c59 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -211,13 +211,15 @@ static struct window_surface *create_surface(HWND hwnd, macdrv_window window, co /*********************************************************************** * CreateWindowSurface (MACDRV.@) */ -BOOL macdrv_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface) +BOOL macdrv_CreateWindowSurface(HWND hwnd, BOOL layered, UINT dpi_from, UINT dpi_to, + const RECT *surface_rect, struct window_surface **surface) { struct window_surface *previous; struct macdrv_win_data *data;
TRACE("hwnd %p, layered %u, surface_rect %s, surface %p\n", hwnd, layered, wine_dbgstr_rect(surface_rect), surface);
+ if (dpi_from != dpi_to) return FALSE; /* use default implementation */ if ((previous = *surface) && previous->funcs == &macdrv_surface_funcs) return TRUE; if (!(data = get_win_data(hwnd))) return TRUE; /* use default surface */ if (previous) window_surface_release(previous); diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 40f86526cd2..b0a7890b7b8 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -356,7 +356,8 @@ LRESULT WAYLAND_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface); BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects); -BOOL WAYLAND_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); +BOOL WAYLAND_CreateWindowSurface(HWND hwnd, BOOL layered, UINT dpi_from, UINT dpi_to, + const RECT *surface_rect, struct window_surface **surface); UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs); struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version);
diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index 570c186861b..bd2fae6bad0 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -499,13 +499,15 @@ void wayland_window_surface_update_wayland_surface(struct window_surface *window /*********************************************************************** * WAYLAND_CreateWindowSurface */ -BOOL WAYLAND_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface) +BOOL WAYLAND_CreateWindowSurface(HWND hwnd, BOOL layered, UINT dpi_from, UINT dpi_to, + const RECT *surface_rect, struct window_surface **surface) { struct window_surface *previous; struct wayland_win_data *data;
TRACE("hwnd %p, layered %u, surface_rect %s, surface %p\n", hwnd, layered, wine_dbgstr_rect(surface_rect), surface);
+ if (dpi_from != dpi_to) return FALSE; /* use default implementation */ if ((previous = *surface) && previous->funcs == &wayland_window_surface_funcs) return TRUE; if (!(data = wayland_win_data_get(hwnd))) return TRUE; /* use default surface */ if (previous) window_surface_release(previous); diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 757386595f0..ef635ca4d24 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1964,13 +1964,15 @@ static BOOL enable_direct_drawing( struct x11drv_win_data *data, BOOL layered ) /*********************************************************************** * CreateWindowSurface (X11DRV.@) */ -BOOL X11DRV_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ) +BOOL X11DRV_CreateWindowSurface( HWND hwnd, BOOL layered, UINT dpi_from, UINT dpi_to, + const RECT *surface_rect, struct window_surface **surface ) { struct window_surface *previous; struct x11drv_win_data *data;
TRACE( "hwnd %p, layered %u, surface_rect %s, surface %p\n", hwnd, layered, wine_dbgstr_rect( surface_rect ), surface );
+ if (dpi_from != dpi_to) return FALSE; /* use default implementation */ if (!(data = get_win_data( hwnd ))) return TRUE; /* use default surface */ if ((previous = *surface) && previous->funcs == &x11drv_surface_funcs) { diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index b87d6a87932..b5d92c9bff5 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -245,7 +245,8 @@ extern void X11DRV_UpdateLayeredWindow( HWND hwnd, UINT flags ); extern LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ); extern BOOL X11DRV_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask ); -extern BOOL X11DRV_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ); +extern BOOL X11DRV_CreateWindowSurface( HWND hwnd, BOOL layered, UINT dpi_from, UINT dpi_to, + const RECT *surface_rect, struct window_surface **surface ); extern void X11DRV_MoveWindowBits( HWND hwnd, const struct window_rects *new_rects, const RECT *valid_rects ); extern void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface ); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index fee065af71b..e1da4711846 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 96 +#define WINE_GDI_DRIVER_VERSION 97
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -387,7 +387,7 @@ struct user_driver_funcs LRESULT (*pWindowMessage)(HWND,UINT,WPARAM,LPARAM); BOOL (*pWindowPosChanging)(HWND,UINT,BOOL,const struct window_rects *); BOOL (*pGetWindowStyleMasks)(HWND,UINT,UINT,UINT*,UINT*); - BOOL (*pCreateWindowSurface)(HWND,BOOL,const RECT *,struct window_surface**); + BOOL (*pCreateWindowSurface)(HWND,BOOL,UINT,UINT,const RECT *,struct window_surface**); void (*pMoveWindowBits)(HWND,const struct window_rects *,const RECT *); void (*pWindowPosChanged)(HWND,HWND,UINT,const struct window_rects*,struct window_surface*); /* system parameters */
v2: Fix a typo in X11DRV_GetWindowStyleMasks.
Looks like I messed this up somehow, will make some changes.