Doing this first, instead of https://gitlab.winehq.org/wine/wine/-/merge_requests/5865, this will let us move surface rect computation to win32u and then provide the previous surface as a default, before unifying the surface visibility conditions.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/bitblt.c | 100 ++++++++++++++++++++++++++++++++++++- dlls/winex11.drv/window.c | 102 ++------------------------------------ dlls/winex11.drv/x11drv.h | 2 - 3 files changed, 102 insertions(+), 102 deletions(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 11ba34739c3..4fce6cbd363 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -2054,8 +2054,8 @@ static const struct window_surface_funcs x11drv_surface_funcs = /*********************************************************************** * create_surface */ -struct window_surface *create_surface( HWND hwnd, Window window, const XVisualInfo *vis, const RECT *rect, - COLORREF color_key, BOOL use_alpha ) +static struct window_surface *create_surface( HWND hwnd, Window window, const XVisualInfo *vis, const RECT *rect, + COLORREF color_key, BOOL use_alpha ) { const XPixmapFormatValues *format = pixmap_formats[vis->depth]; char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; @@ -2182,3 +2182,99 @@ HRGN expose_surface( struct window_surface *window_surface, const RECT *rect ) window_surface_unlock( window_surface ); return region; } + + +static BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) +{ + *surface_rect = NtUserGetVirtualScreenRect(); + + if (!intersect_rect( surface_rect, surface_rect, visible_rect )) return FALSE; + OffsetRect( surface_rect, -visible_rect->left, -visible_rect->top ); + surface_rect->left &= ~31; + surface_rect->top &= ~31; + surface_rect->right = max( surface_rect->left + 32, (surface_rect->right + 31) & ~31 ); + surface_rect->bottom = max( surface_rect->top + 32, (surface_rect->bottom + 31) & ~31 ); + return TRUE; +} + + +/*********************************************************************** + * 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 */ + + if (data->embedded) goto done; /* draw directly to the window */ + if (data->whole_window == root_window) goto done; /* draw directly to the window */ + 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 )) + { + /* existing surface is good enough */ + window_surface_add_ref( data->surface ); + *surface = data->surface; + goto done; + } + } + else if (!(swp_flags & SWP_SHOWWINDOW) && !(NtUserGetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)) goto done; + + if (!layered || !NtUserGetLayeredWindowAttributes( hwnd, &key, NULL, &flags ) || !(flags & LWA_COLORKEY)) + key = CLR_INVALID; + + *surface = create_surface( data->hwnd, data->whole_window, &data->vis, &surface_rect, key, FALSE ); + +done: + release_win_data( data ); + return TRUE; +} + + +/***************************************************************************** + * CreateLayeredWindow (X11DRV.@) + */ +BOOL X11DRV_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COLORREF color_key, + struct window_surface **window_surface ) +{ + struct window_surface *surface; + struct x11drv_win_data *data; + RECT rect; + + if (!(data = get_win_data( hwnd ))) return FALSE; + + data->layered = TRUE; + if (!data->embedded && argb_visual.visualid) set_window_visual( data, &argb_visual, TRUE ); + + rect = *window_rect; + OffsetRect( &rect, -window_rect->left, -window_rect->top ); + + surface = data->surface; + if (!surface || !EqualRect( &surface->rect, &rect )) + { + data->surface = create_surface( data->hwnd, data->whole_window, &data->vis, &rect, + color_key, data->use_alpha ); + if (surface) window_surface_release( surface ); + surface = data->surface; + } + else set_surface_color_key( surface, color_key ); + + if ((*window_surface = surface)) window_surface_add_ref( surface ); + release_win_data( data ); + + return TRUE; +} diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 74a9a4f6d68..b8358b1596f 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2576,27 +2576,13 @@ done: }
-static inline BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) -{ - *surface_rect = NtUserGetVirtualScreenRect(); - - if (!intersect_rect( surface_rect, surface_rect, visible_rect )) return FALSE; - OffsetRect( surface_rect, -visible_rect->left, -visible_rect->top ); - surface_rect->left &= ~31; - surface_rect->top &= ~31; - surface_rect->right = max( surface_rect->left + 32, (surface_rect->right + 31) & ~31 ); - surface_rect->bottom = max( surface_rect->top + 32, (surface_rect->bottom + 31) & ~31 ); - return TRUE; -} - - /*********************************************************************** * WindowPosChanging (X11DRV.@) */ 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; + RECT virtual_rect; BOOL ret = FALSE;
if (!data && !(data = X11DRV_create_win_data( hwnd, window_rect, client_rect ))) return FALSE; /* use default surface */ @@ -2616,7 +2602,9 @@ BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rec if (!data->whole_window && !data->embedded) goto done; /* use default surface */ if (swp_flags & SWP_HIDEWINDOW) goto done; /* use default surface */ if (data->use_alpha) goto done; /* use default surface */ - if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */ + + virtual_rect = NtUserGetVirtualScreenRect(); + if (!intersect_rect( &virtual_rect, &virtual_rect, visible_rect )) goto done; /* use default surface */
ret = TRUE;
@@ -2626,53 +2614,6 @@ done: }
-/*********************************************************************** - * 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 */ - - if (data->embedded) goto done; /* draw directly to the window */ - if (data->whole_window == root_window) goto done; /* draw directly to the window */ - 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 )) - { - /* existing surface is good enough */ - window_surface_add_ref( data->surface ); - *surface = data->surface; - goto done; - } - } - else if (!(swp_flags & SWP_SHOWWINDOW) && !(NtUserGetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)) goto done; - - if (!layered || !NtUserGetLayeredWindowAttributes( hwnd, &key, NULL, &flags ) || !(flags & LWA_COLORKEY)) - key = CLR_INVALID; - - *surface = create_surface( data->hwnd, data->whole_window, &data->vis, &surface_rect, key, FALSE ); - -done: - release_win_data( data ); - return TRUE; -} - - /*********************************************************************** * WindowPosChanged (X11DRV.@) */ @@ -2983,41 +2924,6 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO }
-/***************************************************************************** - * CreateLayeredWindow (X11DRV.@) - */ -BOOL X11DRV_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COLORREF color_key, - struct window_surface **window_surface ) -{ - struct window_surface *surface; - struct x11drv_win_data *data; - RECT rect; - - if (!(data = get_win_data( hwnd ))) return FALSE; - - data->layered = TRUE; - if (!data->embedded && argb_visual.visualid) set_window_visual( data, &argb_visual, TRUE ); - - rect = *window_rect; - OffsetRect( &rect, -window_rect->left, -window_rect->top ); - - surface = data->surface; - if (!surface || !EqualRect( &surface->rect, &rect )) - { - data->surface = create_surface( data->hwnd, data->whole_window, &data->vis, &rect, - color_key, data->use_alpha ); - if (surface) window_surface_release( surface ); - surface = data->surface; - } - else set_surface_color_key( surface, color_key ); - - if ((*window_surface = surface)) window_surface_add_ref( surface ); - release_win_data( data ); - - return TRUE; -} - - /*********************************************************************** * UpdateLayeredWindow (X11DRV.@) */ diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 49fb17fc7cd..523cdfc23dc 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -266,8 +266,6 @@ extern Pixmap create_pixmap_from_image( HDC hdc, const XVisualInfo *vis, const B const struct gdi_image_bits *bits, UINT coloruse ); extern DWORD get_pixmap_image( Pixmap pixmap, int width, int height, const XVisualInfo *vis, BITMAPINFO *info, struct gdi_image_bits *bits ); -extern struct window_surface *create_surface( HWND hwnd, Window window, const XVisualInfo *vis, const RECT *rect, - COLORREF color_key, BOOL use_alpha ); extern void set_surface_color_key( struct window_surface *window_surface, COLORREF color_key ); extern HRGN expose_surface( struct window_surface *window_surface, const RECT *rect );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/macdrv.h | 3 -- dlls/winemac.drv/surface.c | 98 ++++++++++++++++++++++++++++++++++++-- dlls/winemac.drv/window.c | 96 ++----------------------------------- 3 files changed, 98 insertions(+), 99 deletions(-)
diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 31835164e71..811947f723c 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -207,10 +207,7 @@ extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_p extern macdrv_window macdrv_get_cocoa_window(HWND hwnd, BOOL require_on_screen); extern RGNDATA *get_region_data(HRGN hrgn, HDC hdc_lptodp); extern void activate_on_following_focus(void); -extern struct window_surface *create_surface(HWND hwnd, macdrv_window window, const RECT *rect, - struct window_surface *old_surface, BOOL use_alpha); extern void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha); -extern void surface_clip_to_visible_rect(struct window_surface *window_surface, const RECT *visible_rect);
extern void macdrv_handle_event(const macdrv_event *event);
diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 37e2c466926..02421904986 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -127,8 +127,8 @@ static struct macdrv_window_surface *get_mac_surface(struct window_surface *surf /*********************************************************************** * create_surface */ -struct window_surface *create_surface(HWND hwnd, macdrv_window window, const RECT *rect, - struct window_surface *old_surface, BOOL use_alpha) +static struct window_surface *create_surface(HWND hwnd, macdrv_window window, const RECT *rect, + struct window_surface *old_surface, BOOL use_alpha) { struct macdrv_window_surface *surface; int width = rect->right - rect->left, height = rect->bottom - rect->top; @@ -265,7 +265,7 @@ done: * Intersect the accumulated drawn region with a new visible rect, * effectively discarding stale drawing in the surface slack area. */ -void surface_clip_to_visible_rect(struct window_surface *window_surface, const RECT *visible_rect) +static void surface_clip_to_visible_rect(struct window_surface *window_surface, const RECT *visible_rect) { struct macdrv_window_surface *surface = get_mac_surface(window_surface); RECT rect = *visible_rect; @@ -277,3 +277,95 @@ void surface_clip_to_visible_rect(struct window_surface *window_surface, const R intersect_rect(&window_surface->bounds, &window_surface->bounds, &rect); window_surface_unlock(window_surface); } + + +static RECT get_surface_rect(const RECT *visible_rect) +{ + RECT rect = *visible_rect; + + OffsetRect(&rect, -visible_rect->left, -visible_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; +} + + +/*********************************************************************** + * 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; + + surface_rect = get_surface_rect(visible_rect); + if (data->surface) + { + if (EqualRect(&data->surface->rect, &surface_rect)) + { + /* existing surface is good enough */ + surface_clip_to_visible_rect(data->surface, visible_rect); + window_surface_add_ref(data->surface); + *surface = data->surface; + goto done; + } + } + else if (!(swp_flags & SWP_SHOWWINDOW) && !(style & WS_VISIBLE)) goto done; + + *surface = create_surface(data->hwnd, data->cocoa_window, &surface_rect, data->surface, FALSE); + +done: + release_win_data(data); + return TRUE; +} + + +/*********************************************************************** + * CreateLayeredWindow (MACDRV.@) + */ +BOOL macdrv_CreateLayeredWindow(HWND hwnd, const RECT *window_rect, COLORREF color_key, + struct window_surface **window_surface) +{ + struct window_surface *surface; + struct macdrv_win_data *data; + RECT rect; + + if (!(data = get_win_data(hwnd))) return FALSE; + + data->layered = TRUE; + data->ulw_layered = TRUE; + + rect = *window_rect; + OffsetRect(&rect, -window_rect->left, -window_rect->top); + + surface = data->surface; + if (!surface || !EqualRect(&surface->rect, &rect)) + { + data->surface = create_surface(data->hwnd, data->cocoa_window, &rect, NULL, TRUE); + macdrv_set_window_surface(data->cocoa_window, data->surface); + if (surface) window_surface_release(surface); + surface = data->surface; + if (data->unminimized_surface) + { + window_surface_release(data->unminimized_surface); + data->unminimized_surface = NULL; + } + } + else set_surface_use_alpha(surface, TRUE); + + if ((*window_surface = surface)) window_surface_add_ref(surface); + + release_win_data(data); + + return TRUE; +} diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 012189249a4..7c40af2ee28 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1890,46 +1890,6 @@ done: }
-/*********************************************************************** - * CreateLayeredWindow (MACDRV.@) - */ -BOOL macdrv_CreateLayeredWindow(HWND hwnd, const RECT *window_rect, COLORREF color_key, - struct window_surface **window_surface) -{ - struct window_surface *surface; - struct macdrv_win_data *data; - RECT rect; - - if (!(data = get_win_data(hwnd))) return FALSE; - - data->layered = TRUE; - data->ulw_layered = TRUE; - - rect = *window_rect; - OffsetRect(&rect, -window_rect->left, -window_rect->top); - - surface = data->surface; - if (!surface || !EqualRect(&surface->rect, &rect)) - { - data->surface = create_surface(data->hwnd, data->cocoa_window, &rect, NULL, TRUE); - macdrv_set_window_surface(data->cocoa_window, data->surface); - if (surface) window_surface_release(surface); - surface = data->surface; - if (data->unminimized_surface) - { - window_surface_release(data->unminimized_surface); - data->unminimized_surface = NULL; - } - } - else set_surface_use_alpha(surface, TRUE); - - if ((*window_surface = surface)) window_surface_add_ref(surface); - - release_win_data(data); - - return TRUE; -} - /*********************************************************************** * UpdateLayeredWindow (MACDRV.@) */ @@ -1940,12 +1900,13 @@ void macdrv_UpdateLayeredWindow(HWND hwnd, const RECT *window_rect, COLORREF col
if ((data = get_win_data(hwnd))) { + /* The ULW flags are a superset of the LWA flags. */ + sync_window_opacity(data, color_key, 255, TRUE, flags); + /* Since layered attributes are now set, can now show the window */ if (data->cocoa_window && !data->on_screen && NtUserGetWindowLongW(hwnd, GWL_STYLE) & WS_VISIBLE) show_window(data);
- /* The ULW flags are a superset of the LWA flags. */ - sync_window_opacity(data, color_key, 255, TRUE, flags); release_win_data(data); } } @@ -1984,19 +1945,6 @@ LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) }
-static inline RECT get_surface_rect(const RECT *visible_rect) -{ - RECT rect = *visible_rect; - - OffsetRect(&rect, -visible_rect->left, -visible_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; -} - - /*********************************************************************** * WindowPosChanging (MACDRV.@) */ @@ -2028,44 +1976,6 @@ done: }
-/*********************************************************************** - * 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; - - surface_rect = get_surface_rect(visible_rect); - if (data->surface) - { - if (EqualRect(&data->surface->rect, &surface_rect)) - { - /* existing surface is good enough */ - surface_clip_to_visible_rect(data->surface, visible_rect); - window_surface_add_ref(data->surface); - *surface = data->surface; - goto done; - } - } - else if (!(swp_flags & SWP_SHOWWINDOW) && !(style & WS_VISIBLE)) goto done; - - *surface = create_surface(data->hwnd, data->cocoa_window, &surface_rect, data->surface, FALSE); - -done: - release_win_data(data); - return TRUE; -} - - /*********************************************************************** * WindowPosChanged (MACDRV.@) */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/waylanddrv.h | 25 +++++++++++- dlls/winewayland.drv/window.c | 57 +-------------------------- dlls/winewayland.drv/window_surface.c | 39 +++++++++++++++++- 3 files changed, 64 insertions(+), 57 deletions(-)
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 4b92c9bf1ba..d0a8977f887 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -272,11 +272,34 @@ void wayland_shm_buffer_unref(struct wayland_shm_buffer *shm_buffer); * Wayland window surface */
-struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect); void wayland_window_surface_update_wayland_surface(struct window_surface *surface, struct wayland_surface *wayland_surface); void wayland_window_flush(HWND hwnd);
+/********************************************************************** + * Wayland Window + */ + +/* private window data */ +struct wayland_win_data +{ + struct rb_entry entry; + /* hwnd that this private data belongs to */ + HWND hwnd; + /* wayland surface (if any) for this window */ + struct wayland_surface *wayland_surface; + /* wine window_surface backing this window */ + struct window_surface *window_surface; + /* USER window rectangle relative to win32 parent window client area */ + RECT window_rect; + /* USER client rectangle relative to win32 parent window client area */ + RECT client_rect; + BOOL managed; +}; + +struct wayland_win_data *wayland_win_data_get(HWND hwnd); +void wayland_win_data_release(struct wayland_win_data *data); + /********************************************************************** * Wayland Keyboard */ diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index c006505bc90..060a25d50c6 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -56,23 +56,6 @@ static BOOL set_window_pos(HWND hwnd, HWND after, INT x, INT y, INT cx, INT cy, }
-/* private window data */ -struct wayland_win_data -{ - struct rb_entry entry; - /* hwnd that this private data belongs to */ - HWND hwnd; - /* wayland surface (if any) for this window */ - struct wayland_surface *wayland_surface; - /* wine window_surface backing this window */ - struct window_surface *window_surface; - /* USER window rectangle relative to win32 parent window client area */ - RECT window_rect; - /* USER client rectangle relative to win32 parent window client area */ - RECT client_rect; - BOOL managed; -}; - static int wayland_win_data_cmp_rb(const void *key, const struct rb_entry *entry) { @@ -153,7 +136,7 @@ static void wayland_win_data_destroy(struct wayland_win_data *data) * * Lock and return the data structure associated with a window. */ -static struct wayland_win_data *wayland_win_data_get(HWND hwnd) +struct wayland_win_data *wayland_win_data_get(HWND hwnd) { struct rb_entry *rb_entry;
@@ -172,7 +155,7 @@ static struct wayland_win_data *wayland_win_data_get(HWND hwnd) * * Release the data returned by wayland_win_data_get. */ -static void wayland_win_data_release(struct wayland_win_data *data) +void wayland_win_data_release(struct wayland_win_data *data) { assert(data); pthread_mutex_unlock(&win_data_mutex); @@ -471,42 +454,6 @@ done: }
-/*********************************************************************** - * 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. */ - if (data->window_surface && - EqualRect(&data->window_surface->rect, &surface_rect)) - { - window_surface_add_ref(data->window_surface); - *surface = data->window_surface; - TRACE("reusing surface %p\n", *surface); - goto done; - } - - *surface = wayland_window_surface_create(data->hwnd, &surface_rect); - -done: - wayland_win_data_release(data); - return TRUE; -} - /*********************************************************************** * WAYLAND_WindowPosChanged */ diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index 888fa74c085..9377b05b4ce 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -449,7 +449,7 @@ static const struct window_surface_funcs wayland_window_surface_funcs = /*********************************************************************** * wayland_window_surface_create */ -struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect) +static struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect) { char buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; BITMAPINFO *info = (BITMAPINFO *)buffer; @@ -516,3 +516,40 @@ void wayland_window_surface_update_wayland_surface(struct window_surface *window
window_surface_unlock(window_surface); } + + +/*********************************************************************** + * 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. */ + if (data->window_surface && + EqualRect(&data->window_surface->rect, &surface_rect)) + { + window_surface_add_ref(data->window_surface); + *surface = data->window_surface; + TRACE("reusing surface %p\n", *surface); + goto done; + } + + *surface = wayland_window_surface_create(data->hwnd, &surface_rect); + +done: + wayland_win_data_release(data); + return TRUE; +}
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/bitblt.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 4fce6cbd363..384ee3f0f2e 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1841,13 +1841,11 @@ static BOOL destroy_shm_image( XImage *image, x11drv_xshm_info_t *shminfo ) return TRUE; }
-static BOOL put_shm_image( XImage *image, x11drv_xshm_info_t *shminfo, Window window, - GC gc, const RECT *rect, const RECT *dirty ) +static BOOL put_shm_image( XImage *image, x11drv_xshm_info_t *shminfo, Window window, GC gc, const RECT *dirty ) { if (shminfo->shmid == -1) return FALSE;
- XShmPutImage( gdi_display, window, gc, image, dirty->left, - dirty->top, rect->left + dirty->left, rect->top + dirty->top, + XShmPutImage( gdi_display, window, gc, image, dirty->left, dirty->top, dirty->left, dirty->top, dirty->right - dirty->left, dirty->bottom - dirty->top, False );
return TRUE; @@ -1866,8 +1864,7 @@ static BOOL destroy_shm_image( XImage *image, x11drv_xshm_info_t *shminfo ) return FALSE; }
-static BOOL put_shm_image( XImage *image, x11drv_xshm_info_t *shminfo, Window window, - GC gc, const RECT *rect, const RECT *dirty ) +static BOOL put_shm_image( XImage *image, x11drv_xshm_info_t *shminfo, Window window, GC gc, const RECT *dirty ) { return FALSE; } @@ -2020,10 +2017,9 @@ static BOOL x11drv_surface_flush( struct window_surface *window_surface, const R ptr[x] |= surface->alpha_bits; }
- if (!put_shm_image( ximage, &surface->image->shminfo, surface->window, surface->gc, rect, dirty )) - XPutImage( gdi_display, surface->window, surface->gc, ximage, dirty->left, - dirty->top, rect->left + dirty->left, rect->top + dirty->top, - dirty->right - dirty->left, dirty->bottom - dirty->top ); + if (!put_shm_image( ximage, &surface->image->shminfo, surface->window, surface->gc, dirty )) + XPutImage( gdi_display, surface->window, surface->gc, ximage, dirty->left, dirty->top, + dirty->left, dirty->top, dirty->right - dirty->left, dirty->bottom - dirty->top );
XFlush( gdi_display );
@@ -2184,17 +2180,13 @@ HRGN expose_surface( struct window_surface *window_surface, const RECT *rect ) }
-static BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) +static RECT get_surface_rect( RECT rect ) { - *surface_rect = NtUserGetVirtualScreenRect(); - - if (!intersect_rect( surface_rect, surface_rect, visible_rect )) return FALSE; - OffsetRect( surface_rect, -visible_rect->left, -visible_rect->top ); - surface_rect->left &= ~31; - surface_rect->top &= ~31; - surface_rect->right = max( surface_rect->left + 32, (surface_rect->right + 31) & ~31 ); - surface_rect->bottom = max( surface_rect->top + 32, (surface_rect->bottom + 31) & ~31 ); - return TRUE; + OffsetRect( &rect, -rect.left, -rect.top ); + /* round surface size to avoid re-creating them on every resize */ + rect.right = max( rect.left + 32, (rect.right + 31) & ~31 ); + rect.bottom = max( rect.top + 32, (rect.bottom + 31) & ~31 ); + return rect; }
@@ -2221,7 +2213,7 @@ BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_ 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; + surface_rect = get_surface_rect( *visible_rect ); if (data->surface) { if (EqualRect( &data->surface->rect, &surface_rect ))
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/wineandroid.drv/window.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 764b202d6e5..8b39852ee08 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -670,8 +670,7 @@ static BOOL android_surface_flush( struct window_surface *window_surface, const locked.bottom = rc.bottom; intersect_rect( &locked, &locked, rect );
- src = (DWORD *)window_surface->color_bits + (locked.top - rect->top) * surface->info.bmiHeader.biWidth + - (locked.left - rect->left); + src = (DWORD *)window_surface->color_bits + locked.top * surface->info.bmiHeader.biWidth + locked.left; dst = (DWORD *)buffer.bits + locked.top * buffer.stride + locked.left; width = min( locked.right - locked.left, buffer.stride );
@@ -1121,15 +1120,13 @@ static struct android_win_data *create_win_data( HWND hwnd, const RECT *window_r }
-static inline BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) +static RECT get_surface_rect( RECT rect ) { - if (!intersect_rect( surface_rect, visible_rect, &virtual_screen_rect )) return FALSE; - OffsetRect( surface_rect, -visible_rect->left, -visible_rect->top ); - surface_rect->left &= ~31; - surface_rect->top &= ~31; - surface_rect->right = max( surface_rect->left + 32, (surface_rect->right + 31) & ~31 ); - surface_rect->bottom = max( surface_rect->top + 32, (surface_rect->bottom + 31) & ~31 ); - return TRUE; + OffsetRect( &rect, -rect.left, -rect.top ); + /* round surface size to avoid re-creating them on every resize */ + rect.right = max( rect.left + 32, (rect.right + 31) & ~31 ); + rect.bottom = max( rect.top + 32, (rect.bottom + 31) & ~31 ); + return rect; }
@@ -1139,7 +1136,7 @@ static inline BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rec 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; + RECT virtual_rect; BOOL ret = FALSE;
TRACE( "win %p window %s client %s style %08x flags %08x\n", @@ -1151,7 +1148,9 @@ BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_re 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 */ + + virtual_rect = NtUserGetVirtualScreenRect(); + if (!intersect_rect( &virtual_rect, &virtual_rect, visible_rect )) goto done; /* use default surface */
ret = TRUE;
@@ -1176,8 +1175,8 @@ BOOL ANDROID_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible 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 (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
+ surface_rect = get_surface_rect( *visible_rect ); if (data->surface) { if (!memcmp( &data->surface->rect, &surface_rect, sizeof(surface_rect) ))
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=146402
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: win: Timeout
We still need a mechanism to limit the size, we can't create a surface for the entire window, some apps create huge windows.
I see, then we should probably instead clip the surfaces for all the drivers.
This merge request was closed by Rémi Bernon.