From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/window.c | 67 ++++++++++++++++++++++++++ dlls/wineandroid.drv/window.c | 14 +----- dlls/winewayland.drv/wayland_surface.c | 5 +- dlls/winewayland.drv/waylanddrv.h | 1 - dlls/winewayland.drv/window.c | 17 ------- dlls/winex11.drv/bitblt.c | 32 ------------ dlls/winex11.drv/event.c | 16 +----- dlls/winex11.drv/x11drv.h | 1 - include/ntuser.h | 16 ++++++ 9 files changed, 90 insertions(+), 79 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 1762e2c8228..a5499019176 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2068,6 +2068,67 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru return ret; }
+static HRGN expose_window_surface_rect( struct window_surface *surface, UINT flags, RECT dirty ) +{ + HRGN region, clipped; + + intersect_rect( &dirty, &dirty, &surface->rect ); + add_bounds_rect( &surface->bounds, &dirty ); + + if (!surface->clip_region || !flags) return 0; + + clipped = NtGdiCreateRectRgn( surface->rect.left, surface->rect.top, + surface->rect.right, surface->rect.bottom ); + NtGdiCombineRgn( clipped, clipped, surface->clip_region, RGN_DIFF ); + + region = NtGdiCreateRectRgn( dirty.left, dirty.top, dirty.right, dirty.bottom ); + if (NtGdiCombineRgn( region, region, clipped, RGN_DIFF ) <= NULLREGION) + { + NtGdiDeleteObjectApp( region ); + region = 0; + } + + NtGdiDeleteObjectApp( clipped ); + return region; +} + +static BOOL expose_window_surface( HWND hwnd, UINT flags, const RECT *rect, UINT dpi ) +{ + struct window_surface *surface; + struct window_rects rects; + HRGN region = 0; + WND *win; + + if (!(win = get_win_ptr( hwnd )) || win == WND_DESKTOP || win == WND_OTHER_PROCESS) return FALSE; + if ((surface = win->surface)) window_surface_add_ref( surface ); + rects = win->rects; + release_win_ptr( win ); + + if (surface) + { + window_surface_lock( surface ); + + if (!rect) add_bounds_rect( &surface->bounds, rect ); + else + { + RECT dirty = *rect; + OffsetRect( &dirty, rects.client.left - rects.visible.left, rects.client.top - rects.visible.top ); + if (!(region = expose_window_surface_rect( surface, flags, dirty ))) flags = 0; + else NtGdiOffsetRgn( region, rects.client.left - rects.visible.left, rects.client.top - rects.visible.top ); + } + + window_surface_unlock( surface ); + if (surface->alpha_mask) window_surface_flush( surface ); + + window_surface_release( surface ); + } + + if (flags) NtUserRedrawWindow( hwnd, rect, region, flags ); + if (region) NtGdiDeleteObjectApp( region ); + return TRUE; +} + + /******************************************************************* * NtUserGetWindowRgnEx (win32u.@) */ @@ -5778,6 +5839,12 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code ) return send_hardware_message( hwnd, params->flags, params->input, params->lparam ); }
+ case NtUserCallHwndParam_ExposeWindowSurface: + { + struct expose_window_surface_params *params = (void *)param; + return expose_window_surface( hwnd, params->flags, params->whole ? NULL : ¶ms->rect, params->dpi ); + } + /* temporary exports */ case NtUserSetWindowStyle: { diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 7eb37f05202..f0b94938f68 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1237,8 +1237,6 @@ void ANDROID_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style ) */ LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) { - struct android_win_data *data; - switch (msg) { case WM_ANDROID_REFRESH: @@ -1246,17 +1244,9 @@ LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) { update_gl_drawable( hwnd ); } - else if ((data = get_win_data( hwnd ))) + else { - struct window_surface *surface = data->surface; - if (surface) - { - window_surface_lock( surface ); - surface->bounds = surface->rect; - window_surface_unlock( surface ); - if (is_argb_surface( surface )) window_surface_flush( surface ); - } - release_win_data( data ); + NtUserExposeWindowSurface( hwnd, 0, NULL, 0 ); } return 0; default: diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 39c3976cdfd..a2699d66e51 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -64,7 +64,10 @@ static void xdg_surface_handle_configure(void *data, struct xdg_surface *xdg_sur
/* Flush the window surface in case there is content that we weren't * able to flush before due to the lack of the initial configure. */ - if (initial_configure) wayland_window_flush(hwnd); + if (initial_configure) + { + NtUserExposeWindowSurface(hwnd, 0, NULL, 0); + } }
static const struct xdg_surface_listener xdg_surface_listener = diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 5bde94a0ac9..1a2eeeecb93 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -274,7 +274,6 @@ void wayland_shm_buffer_unref(struct wayland_shm_buffer *shm_buffer);
void wayland_window_surface_update_wayland_surface(struct window_surface *surface, const RECT *visible_rect, struct wayland_surface *wayland_surface); -void wayland_window_flush(HWND hwnd);
/********************************************************************** * Wayland Window diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 233ca0e5a62..e8d6b770496 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -696,23 +696,6 @@ LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam) return ret; }
-/********************************************************************** - * wayland_window_flush - * - * Flush the window_surface associated with a HWND. - */ -void wayland_window_flush(HWND hwnd) -{ - struct wayland_win_data *data = wayland_win_data_get(hwnd); - - if (!data) return; - - if (data->window_surface) - window_surface_flush(data->window_surface); - - wayland_win_data_release(data); -} - /********************************************************************** * wayland_surface_lock_hwnd */ diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 5963bf98f3d..be1ae962334 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1956,38 +1956,6 @@ failed: return NULL; }
-/*********************************************************************** - * expose_surface - */ -HRGN expose_surface( struct window_surface *window_surface, const RECT *rect ) -{ - HRGN region = 0; - RECT rc = *rect; - - if (window_surface->funcs != &x11drv_surface_funcs) return 0; /* we may get the null surface */ - - window_surface_lock( window_surface ); - OffsetRect( &rc, -window_surface->rect.left, -window_surface->rect.top ); - add_bounds_rect( &window_surface->bounds, &rc ); - if (window_surface->clip_region) - { - HRGN clipped = NtGdiCreateRectRgn( window_surface->rect.left, window_surface->rect.top, - window_surface->rect.right, window_surface->rect.bottom ); - NtGdiCombineRgn( clipped, clipped, window_surface->clip_region, RGN_DIFF ); - - region = NtGdiCreateRectRgn( rect->left, rect->top, rect->right, rect->bottom ); - if (NtGdiCombineRgn( region, region, clipped, RGN_DIFF ) <= NULLREGION) - { - NtGdiDeleteObjectApp( region ); - region = 0; - } - - NtGdiDeleteObjectApp( clipped ); - } - window_surface_unlock( window_surface ); - return region; -} -
/*********************************************************************** * CreateWindowSurface (X11DRV.@) diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index c377bbc9984..635025aff97 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -876,7 +876,6 @@ static BOOL X11DRV_Expose( HWND hwnd, XEvent *xev ) RECT rect, abs_rect; POINT pos; struct x11drv_win_data *data; - HRGN surface_region = 0; UINT flags = RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN;
TRACE( "win %p (%lx) %d,%d %dx%d\n", @@ -897,20 +896,8 @@ static BOOL X11DRV_Expose( HWND hwnd, XEvent *xev ) rect.bottom = pos.y + event->height;
if (event->window != data->client_window) - { - if (data->surface) - { - surface_region = expose_surface( data->surface, &rect ); - if (!surface_region) flags = 0; - else NtGdiOffsetRgn( surface_region, data->whole_rect.left - data->client_rect.left, - data->whole_rect.top - data->client_rect.top ); - - if (data->vis.visualid != default_visual.visualid) - window_surface_flush( data->surface ); - } OffsetRect( &rect, data->whole_rect.left - data->client_rect.left, data->whole_rect.top - data->client_rect.top ); - }
if (event->window != root_window) { @@ -931,8 +918,7 @@ static BOOL X11DRV_Expose( HWND hwnd, XEvent *xev )
release_win_data( data );
- if (flags) redraw_window( hwnd, &rect, surface_region, flags ); - if (surface_region) NtGdiDeleteObjectApp( surface_region ); + NtUserExposeWindowSurface( hwnd, flags, &rect, get_win_monitor_dpi( hwnd ) ); return TRUE; }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 83e7889fb59..9d9c9a109b7 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -262,7 +262,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 HRGN expose_surface( struct window_surface *window_surface, const RECT *rect );
extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ); extern BOOL add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn ); diff --git a/include/ntuser.h b/include/ntuser.h index 4148c8cf0b6..61dfd7697c2 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -1289,6 +1289,7 @@ enum NtUserCallHwndParam_SetWindowContextHelpId, NtUserCallHwndParam_ShowOwnedPopups, NtUserCallHwndParam_SendHardwareInput, + NtUserCallHwndParam_ExposeWindowSurface, /* temporary exports */ NtUserSetWindowStyle, }; @@ -1499,4 +1500,19 @@ static inline BOOL NtUserSendHardwareInput( HWND hwnd, UINT flags, const INPUT * return NtUserCallHwndParam( hwnd, (UINT_PTR)¶ms, NtUserCallHwndParam_SendHardwareInput ); }
+struct expose_window_surface_params +{ + UINT flags; + BOOL whole; + RECT rect; + UINT dpi; +}; + +static inline BOOL NtUserExposeWindowSurface( HWND hwnd, UINT flags, const RECT *rect, UINT dpi ) +{ + struct expose_window_surface_params params = {.flags = flags, .whole = !rect, .dpi = dpi}; + if (rect) params.rect = *rect; + return NtUserCallHwndParam( hwnd, (UINT_PTR)¶ms, NtUserCallHwndParam_ExposeWindowSurface ); +} + #endif /* _NTUSER_ */