1
0
mirror of https://github.com/wine-mirror/wine synced 2024-06-29 06:14:34 +00:00

win32u: Split WindowPosChanging driver call to a separate CreateWindowSurface.

This commit is contained in:
Rémi Bernon 2024-06-12 09:42:22 +02:00 committed by Alexandre Julliard
parent 2a2637743b
commit 71ff81bc2b
15 changed files with 145 additions and 64 deletions

View File

@ -884,8 +884,12 @@ static LRESULT nulldrv_WindowMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM
return 0;
}
static BOOL nulldrv_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect,
RECT *visible_rect, struct window_surface **surface )
static BOOL nulldrv_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect )
{
return TRUE;
}
static BOOL nulldrv_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface )
{
return FALSE;
}
@ -1293,6 +1297,7 @@ static const struct user_driver_funcs lazy_load_driver =
loaderdrv_UpdateLayeredWindow,
nulldrv_WindowMessage,
nulldrv_WindowPosChanging,
nulldrv_CreateWindowSurface,
nulldrv_WindowPosChanged,
/* system parameters */
nulldrv_SystemParametersInfo,
@ -1380,6 +1385,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(CreateWindowSurface);
SET_USER_FUNC(WindowPosChanged);
SET_USER_FUNC(SystemParametersInfo);
SET_USER_FUNC(VulkanInit);

View File

@ -1790,26 +1790,20 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
{
WND *win;
HWND surface_win = 0, parent = NtUserGetAncestor( hwnd, GA_PARENT );
BOOL ret, needs_update = FALSE;
RECT visible_rect, old_visible_rect, old_window_rect, old_client_rect, extra_rects[3];
BOOL ret, needs_surface, needs_update = FALSE;
RECT visible_rect = *window_rect, old_visible_rect, old_window_rect, old_client_rect, extra_rects[3];
struct window_surface *old_surface, *new_surface = NULL;
needs_surface = user_driver->pWindowPosChanging( hwnd, swp_flags, window_rect, client_rect, &visible_rect );
if (!parent || parent == get_desktop_window())
{
new_surface = &dummy_surface; /* provide a default surface for top-level windows */
window_surface_add_ref( new_surface );
}
visible_rect = *window_rect;
if (!(ret = user_driver->pWindowPosChanging( hwnd, swp_flags, window_rect, client_rect,
&visible_rect, &new_surface )))
{
if (IsRectEmpty( window_rect )) visible_rect = *window_rect;
else
{
visible_rect = get_virtual_screen_rect( get_thread_dpi() );
intersect_rect( &visible_rect, &visible_rect, window_rect );
}
}
if (!needs_surface || IsRectEmpty( &visible_rect )) needs_surface = FALSE; /* use default surface */
else needs_surface = !user_driver->pCreateWindowSurface( hwnd, swp_flags, &visible_rect, &new_surface );
get_window_rects( hwnd, COORDS_SCREEN, &old_window_rect, NULL, get_thread_dpi() );
if (IsRectEmpty( &valid_rects[0] )) valid_rects = NULL;
@ -1821,9 +1815,8 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
}
/* create or update window surface for top-level windows if the driver doesn't implement WindowPosChanging */
if (!ret && new_surface && !IsRectEmpty( &visible_rect ) &&
(!(get_window_long( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED) ||
NtUserGetLayeredWindowAttributes( hwnd, NULL, NULL, NULL )))
if (needs_surface && new_surface && (!(get_window_long( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED) ||
NtUserGetLayeredWindowAttributes( hwnd, NULL, NULL, NULL )))
{
window_surface_release( new_surface );
if ((new_surface = win->surface)) window_surface_add_ref( new_surface );

View File

@ -101,8 +101,8 @@ extern UINT ANDROID_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp );
extern BOOL ANDROID_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COLORREF color_key,
struct window_surface **surface );
extern LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp );
extern BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect,
RECT *visible_rect, struct window_surface **surface );
extern BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect );
extern BOOL ANDROID_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface );
extern void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect,
const RECT *visible_rect, const RECT *valid_rects,

View File

@ -351,6 +351,7 @@ static const struct user_driver_funcs android_drv_funcs =
.pCreateLayeredWindow = ANDROID_CreateLayeredWindow,
.pWindowMessage = ANDROID_WindowMessage,
.pWindowPosChanging = ANDROID_WindowPosChanging,
.pCreateWindowSurface = ANDROID_CreateWindowSurface,
.pWindowPosChanged = ANDROID_WindowPosChanged,
.pwine_get_wgl_driver = ANDROID_wine_get_wgl_driver,
};

View File

@ -1136,25 +1136,46 @@ static inline BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rec
/***********************************************************************
* ANDROID_WindowPosChanging
*/
BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect,
RECT *visible_rect, struct window_surface **surface )
BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect )
{
struct android_win_data *data = get_win_data( hwnd );
RECT surface_rect;
BOOL ret = FALSE;
TRACE( "win %p window %s client %s style %08x flags %08x\n",
hwnd, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect),
(int)NtUserGetWindowLongW( hwnd, GWL_STYLE ), swp_flags );
if (!data && !(data = create_win_data( hwnd, window_rect, client_rect ))) return FALSE; /* use default surface */
if (data->parent) goto done; /* use default surface */
if (swp_flags & SWP_HIDEWINDOW) goto done; /* use default surface */
if (is_argb_surface( data->surface )) goto done; /* use default surface */
if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
ret = TRUE;
done:
release_win_data(data);
return ret;
}
/***********************************************************************
* ANDROID_CreateWindowSurface
*/
BOOL ANDROID_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface )
{
struct android_win_data *data;
RECT surface_rect;
DWORD flags;
COLORREF key;
BYTE alpha;
BOOL layered = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED;
TRACE( "win %p window %s client %s style %08x flags %08x\n",
hwnd, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect),
(int)NtUserGetWindowLongW( hwnd, GWL_STYLE ), swp_flags );
TRACE( "hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect( visible_rect ), surface );
if (!data && !(data = create_win_data( hwnd, window_rect, client_rect ))) return TRUE; /* use default surface */
if (data->parent) goto done; /* use default surface */
if (swp_flags & SWP_HIDEWINDOW) goto done; /* use default surface */
if (is_argb_surface( data->surface )) goto done; /* use default surface */
if (!(data = get_win_data( hwnd ))) return TRUE; /* use default surface */
if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
if (data->surface)

View File

@ -309,6 +309,7 @@ static const struct user_driver_funcs macdrv_funcs =
.pWindowMessage = macdrv_WindowMessage,
.pWindowPosChanged = macdrv_WindowPosChanged,
.pWindowPosChanging = macdrv_WindowPosChanging,
.pCreateWindowSurface = macdrv_CreateWindowSurface,
.pVulkanInit = macdrv_VulkanInit,
.pwine_get_wgl_driver = macdrv_wine_get_wgl_driver,
};

View File

@ -150,8 +150,8 @@ extern BOOL macdrv_CreateLayeredWindow(HWND hwnd, const RECT *window_rect, COLOR
extern void macdrv_UpdateLayeredWindow(HWND hwnd, const RECT *window_rect, COLORREF color_key,
BYTE alpha, UINT flags);
extern LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
extern BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect,
RECT *visible_rect, struct window_surface **surface);
extern BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect);
extern BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface);
extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect,
const RECT *visible_rect, const RECT *valid_rects,

View File

@ -2000,18 +2000,17 @@ static inline RECT get_surface_rect(const RECT *visible_rect)
/***********************************************************************
* WindowPosChanging (MACDRV.@)
*/
BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect,
RECT *visible_rect, struct window_surface **surface)
BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect)
{
struct macdrv_win_data *data = get_win_data(hwnd);
DWORD style = NtUserGetWindowLongW(hwnd, GWL_STYLE);
RECT surface_rect;
BOOL ret = FALSE;
TRACE("%p swp %04x window %s client %s visible %s surface %p\n", hwnd,
TRACE("%p swp %04x window %s client %s visible %s\n", hwnd,
swp_flags, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect),
wine_dbgstr_rect(visible_rect), surface);
wine_dbgstr_rect(visible_rect));
if (!data && !(data = macdrv_create_win_data(hwnd, window_rect, client_rect))) return TRUE; /* use default surface */
if (!data && !(data = macdrv_create_win_data(hwnd, window_rect, client_rect))) return FALSE; /* use default surface */
macdrv_window_to_mac_rect(data, style, visible_rect, window_rect, client_rect);
TRACE("visible_rect %s -> %s\n", wine_dbgstr_rect(window_rect),
@ -2021,6 +2020,27 @@ BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect
if (swp_flags & SWP_HIDEWINDOW) goto done; /* use default surface */
if (data->ulw_layered) goto done; /* use default surface */
ret = TRUE;
done:
release_win_data(data);
return ret;
}
/***********************************************************************
* CreateWindowSurface (MACDRV.@)
*/
BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface)
{
struct macdrv_win_data *data;
DWORD style = NtUserGetWindowLongW(hwnd, GWL_STYLE);
RECT surface_rect;
TRACE("hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(visible_rect), surface);
if (!(data = get_win_data(hwnd))) return TRUE; /* use default surface */
if (*surface) window_surface_release(*surface);
*surface = NULL;

View File

@ -337,8 +337,8 @@ void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect,
const RECT *visible_rect, const RECT *valid_rects,
struct window_surface *surface);
BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect,
RECT *visible_rect, struct window_surface **surface);
BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect);
BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_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);

View File

@ -47,6 +47,7 @@ static const struct user_driver_funcs waylanddrv_funcs =
.pWindowMessage = WAYLAND_WindowMessage,
.pWindowPosChanged = WAYLAND_WindowPosChanged,
.pWindowPosChanging = WAYLAND_WindowPosChanging,
.pCreateWindowSurface = WAYLAND_CreateWindowSurface,
.pVulkanInit = WAYLAND_VulkanInit,
.pwine_get_wgl_driver = WAYLAND_wine_get_wgl_driver,
};

View File

@ -444,34 +444,50 @@ void WAYLAND_DestroyWindow(HWND hwnd)
/***********************************************************************
* WAYLAND_WindowPosChanging
*/
BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect,
RECT *visible_rect, struct window_surface **surface)
BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect)
{
struct wayland_win_data *data = wayland_win_data_get(hwnd);
HWND parent;
BOOL visible;
RECT surface_rect;
BOOL visible, ret = FALSE;
TRACE("hwnd %p window %s client %s visible %s flags %08x\n",
hwnd, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect),
wine_dbgstr_rect(visible_rect), swp_flags);
if (!data && !(data = wayland_win_data_create(hwnd, window_rect, client_rect)))
return TRUE;
/* Release the dummy surface wine provides for toplevels. */
if (*surface) window_surface_release(*surface);
*surface = NULL;
if (!data && !(data = wayland_win_data_create(hwnd, window_rect, client_rect))) return FALSE; /* use default surface */
parent = NtUserGetAncestor(hwnd, GA_PARENT);
visible = ((NtUserGetWindowLongW(hwnd, GWL_STYLE) & WS_VISIBLE) ||
(swp_flags & SWP_SHOWWINDOW)) &&
!(swp_flags & SWP_HIDEWINDOW);
/* Check if we don't want a dedicated window surface. */
if ((parent && parent != NtUserGetDesktopWindow()) || !visible) goto done;
if ((parent && parent != NtUserGetDesktopWindow()) || !visible) goto done; /* use default surface */
surface_rect = *window_rect;
ret = TRUE;
done:
wayland_win_data_release(data);
return ret;
}
/***********************************************************************
* WAYLAND_CreateWindowSurface
*/
BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface)
{
struct wayland_win_data *data;
RECT surface_rect;
TRACE("hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(visible_rect), surface);
if (!(data = wayland_win_data_get(hwnd))) return TRUE; /* use default surface */
/* Release the dummy surface wine provides for toplevels. */
if (*surface) window_surface_release(*surface);
*surface = NULL;
surface_rect = *visible_rect;
OffsetRect(&surface_rect, -surface_rect.left, -surface_rect.top);
/* Check if we can reuse our current window surface. */

View File

@ -423,6 +423,7 @@ static const struct user_driver_funcs x11drv_funcs =
.pCreateLayeredWindow = X11DRV_CreateLayeredWindow,
.pWindowMessage = X11DRV_WindowMessage,
.pWindowPosChanging = X11DRV_WindowPosChanging,
.pCreateWindowSurface = X11DRV_CreateWindowSurface,
.pWindowPosChanged = X11DRV_WindowPosChanged,
.pSystemParametersInfo = X11DRV_SystemParametersInfo,
.pVulkanInit = X11DRV_VulkanInit,

View File

@ -2593,16 +2593,13 @@ static inline BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rec
/***********************************************************************
* WindowPosChanging (X11DRV.@)
*/
BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect,
RECT *visible_rect, struct window_surface **surface )
BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect )
{
struct x11drv_win_data *data = get_win_data( hwnd );
RECT surface_rect;
DWORD flags;
COLORREF key;
BOOL layered = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED;
BOOL ret = FALSE;
if (!data && !(data = X11DRV_create_win_data( hwnd, window_rect, client_rect ))) return TRUE; /* use default surface */
if (!data && !(data = X11DRV_create_win_data( hwnd, window_rect, client_rect ))) return FALSE; /* use default surface */
/* check if we need to switch the window to managed */
if (!data->managed && data->whole_window && is_window_managed( hwnd, swp_flags, window_rect ))
@ -2610,7 +2607,7 @@ BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rec
TRACE( "making win %p/%lx managed\n", hwnd, data->whole_window );
release_win_data( data );
unmap_window( hwnd );
if (!(data = get_win_data( hwnd ))) return TRUE; /* use default surface */
if (!(data = get_win_data( hwnd ))) return FALSE; /* use default surface */
data->managed = TRUE;
}
@ -2621,6 +2618,29 @@ BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rec
if (data->use_alpha) goto done; /* use default surface */
if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
ret = TRUE;
done:
release_win_data( data );
return ret;
}
/***********************************************************************
* CreateWindowSurface (X11DRV.@)
*/
BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface )
{
struct x11drv_win_data *data;
RECT surface_rect;
DWORD flags;
COLORREF key;
BOOL layered = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED;
TRACE( "hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect( visible_rect ), surface );
if (!(data = get_win_data( hwnd ))) return TRUE; /* use default surface */
if (*surface) window_surface_release( *surface );
*surface = NULL; /* indicate that we want to draw directly to the window */
@ -2629,6 +2649,7 @@ BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rec
if (data->client_window) goto done; /* draw directly to the window */
if (!client_side_graphics && !layered) goto done; /* draw directly to the window */
if (!get_surface_rect( visible_rect, &surface_rect )) goto done;
if (data->surface)
{
if (EqualRect( &data->surface->rect, &surface_rect ))

View File

@ -243,8 +243,8 @@ extern void X11DRV_UpdateClipboard(void);
extern BOOL X11DRV_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COLORREF color_key,
struct window_surface **surface );
extern LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp );
extern BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect,
RECT *visible_rect, struct window_surface **surface );
extern BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect );
extern BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface );
extern void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *rectWindow, const RECT *rectClient,
const RECT *visible_rect, const RECT *valid_rects,

View File

@ -337,8 +337,8 @@ struct user_driver_funcs
BOOL (*pCreateLayeredWindow)(HWND,const RECT *,COLORREF,struct window_surface **);
void (*pUpdateLayeredWindow)(HWND,const RECT *,COLORREF,BYTE,UINT);
LRESULT (*pWindowMessage)(HWND,UINT,WPARAM,LPARAM);
BOOL (*pWindowPosChanging)(HWND,UINT,const RECT *,const RECT *,RECT *,
struct window_surface**);
BOOL (*pWindowPosChanging)(HWND,UINT,const RECT *,const RECT *,RECT *);
BOOL (*pCreateWindowSurface)(HWND,UINT,const RECT *,struct window_surface**);
void (*pWindowPosChanged)(HWND,HWND,UINT,const RECT *,const RECT *,const RECT *,
const RECT *,struct window_surface*);
/* system parameters */