From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 38 +++++++++++++++++++++++++++ dlls/win32u/window.c | 1 + dlls/wineandroid.drv/window.c | 8 ++++++ dlls/winemac.drv/surface.c | 9 +++++++ dlls/winewayland.drv/window_surface.c | 9 +++++++ dlls/winex11.drv/bitblt.c | 24 +++++++++++++++++ dlls/winex11.drv/window.c | 5 +++- include/wine/gdi_driver.h | 5 ++++ 8 files changed, 98 insertions(+), 1 deletion(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 91bcb02a6a8..c7199e6b64a 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -61,6 +61,11 @@ static void dummy_surface_set_clip( struct window_surface *window_surface, const /* nothing to do */ }
+static void dummy_surface_set_shape( struct window_surface *window_surface, const RECT *rects, UINT count ) +{ + /* nothing to do */ +} + static BOOL dummy_surface_flush( struct window_surface *window_surface, const RECT *rect, const RECT *dirty, const BITMAPINFO *color_info, const void *color_bits ) { @@ -76,6 +81,7 @@ static void dummy_surface_destroy( struct window_surface *window_surface ) static const struct window_surface_funcs dummy_surface_funcs = { dummy_surface_set_clip, + dummy_surface_set_shape, dummy_surface_flush, dummy_surface_destroy }; @@ -96,6 +102,10 @@ static void offscreen_window_surface_set_clip( struct window_surface *surface, c { }
+static void offscreen_window_surface_set_shape( struct window_surface *surface, const RECT *rects, UINT count ) +{ +} + static BOOL offscreen_window_surface_flush( struct window_surface *surface, const RECT *rect, const RECT *dirty, const BITMAPINFO *color_info, const void *color_bits ) { @@ -110,6 +120,7 @@ static void offscreen_window_surface_destroy( struct window_surface *surface ) static const struct window_surface_funcs offscreen_window_surface_funcs = { offscreen_window_surface_set_clip, + offscreen_window_surface_set_shape, offscreen_window_surface_flush, offscreen_window_surface_destroy }; @@ -328,6 +339,33 @@ W32KAPI void window_surface_set_clip( struct window_surface *surface, HRGN clip_ window_surface_unlock( surface ); }
+W32KAPI void window_surface_set_shape( struct window_surface *surface, HRGN shape_region ) +{ + window_surface_lock( surface ); + + if (!shape_region && surface->shape_region) + { + NtGdiDeleteObjectApp( surface->shape_region ); + surface->shape_region = 0; + surface->funcs->set_shape( surface, NULL, 0 ); + } + else if (shape_region && !NtGdiEqualRgn( shape_region, surface->shape_region )) + { + WINEREGION *data; + + if (!surface->shape_region) surface->shape_region = NtGdiCreateRectRgn( 0, 0, 0, 0 ); + NtGdiCombineRgn( surface->shape_region, shape_region, 0, RGN_COPY ); + + if ((data = GDI_GetObjPtr( shape_region, NTGDI_OBJ_REGION ))) + { + surface->funcs->set_shape( surface, data->rects, data->numRects ); + GDI_ReleaseObj( shape_region ); + } + } + + window_surface_unlock( surface ); +} + /******************************************************************* * register_window_surface * diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index f065fd7309e..ad4d49ca034 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1764,6 +1764,7 @@ static void update_surface_region( HWND hwnd ) if (win->dwExStyle & WS_EX_LAYOUTRTL) NtUserMirrorRgn( hwnd, shape ); NtGdiDeleteObjectApp( region ); } + window_surface_set_shape( win->surface, shape );
if (get_window_region( hwnd, TRUE, ®ion, &visible )) goto done; if (!region) window_surface_set_clip( win->surface, shape ); diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 5da40b4a2f1..550d98e5c85 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -618,6 +618,13 @@ static void android_surface_set_clip( struct window_surface *window_surface, con surface->clip_count = count; }
+/*********************************************************************** + * android_surface_set_shape + */ +static void android_surface_set_shape( struct window_surface *window_surface, const RECT *rects, UINT count ) +{ +} + /*********************************************************************** * android_surface_flush */ @@ -704,6 +711,7 @@ static void android_surface_destroy( struct window_surface *window_surface ) static const struct window_surface_funcs android_surface_funcs = { android_surface_set_clip, + android_surface_set_shape, android_surface_flush, android_surface_destroy }; diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index d8a49674a5b..6961baf0d2e 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -74,6 +74,14 @@ static void macdrv_surface_set_clip(struct window_surface *window_surface, const { }
+/*********************************************************************** + * macdrv_surface_set_shape + */ +static void macdrv_surface_set_shape(struct window_surface *window_surface, const RECT *rects, UINT count) +{ + /* TODO */ +} + /*********************************************************************** * macdrv_surface_flush */ @@ -112,6 +120,7 @@ static void macdrv_surface_destroy(struct window_surface *window_surface) static const struct window_surface_funcs macdrv_surface_funcs = { macdrv_surface_set_clip, + macdrv_surface_set_shape, macdrv_surface_flush, macdrv_surface_destroy, }; diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index 084f987df6c..ed11323ea51 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -217,6 +217,14 @@ static void wayland_window_surface_set_clip(struct window_surface *window_surfac /* TODO */ }
+/*********************************************************************** + * wayland_window_surface_set_shape + */ +static void wayland_window_surface_set_shape(struct window_surface *window_surface, const RECT *rects, UINT count) +{ + /* TODO */ +} + /********************************************************************** * get_region_data */ @@ -430,6 +438,7 @@ static void wayland_window_surface_destroy(struct window_surface *window_surface static const struct window_surface_funcs wayland_window_surface_funcs = { wayland_window_surface_set_clip, + wayland_window_surface_set_shape, wayland_window_surface_flush, wayland_window_surface_destroy }; diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 28723425029..68d7f528601 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1941,6 +1941,29 @@ static void x11drv_surface_set_clip( struct window_surface *window_surface, cons } }
+/*********************************************************************** + * x11drv_surface_set_shape + */ +static void x11drv_surface_set_shape( struct window_surface *window_surface, const RECT *rects, UINT count ) +{ +#ifdef HAVE_LIBXSHAPE + struct x11drv_window_surface *surface = get_x11_surface( window_surface ); + XRectangle *xrects; + + TRACE( "surface %p, rects %p, count %u\n", surface, rects, count ); + + if (!count) + XShapeCombineMask( gdi_display, surface->window, ShapeBounding, 0, 0, None, ShapeSet ); + else if ((xrects = xrectangles_from_rects( rects, count ))) + { + XShapeCombineRectangles( gdi_display, surface->window, ShapeBounding, 0, 0, + xrects, count, ShapeSet, YXBanded ); + free( xrects ); + } + XFlush( gdi_display ); +#endif /* HAVE_LIBXSHAPE */ +} + /*********************************************************************** * x11drv_surface_flush */ @@ -2013,6 +2036,7 @@ static void x11drv_surface_destroy( struct window_surface *window_surface ) static const struct window_surface_funcs x11drv_surface_funcs = { x11drv_surface_set_clip, + x11drv_surface_set_shape, x11drv_surface_flush, x11drv_surface_destroy }; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 5c949525598..9e51d76e5ab 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -386,16 +386,19 @@ static void sync_window_region( struct x11drv_win_data *data, HRGN win_region ) HRGN hrgn = win_region;
if (!data->whole_window) return; - data->shaped = FALSE;
if (IsRectEmpty( &data->window_rect )) /* set an empty shape */ { static XRectangle empty_rect; + data->shaped = FALSE; XShapeCombineRectangles( data->display, data->whole_window, ShapeBounding, 0, 0, &empty_rect, 1, ShapeSet, YXBanded ); return; }
+ if (data->surface) return; /* use surface shape instead */ + data->shaped = FALSE; + if (hrgn == (HRGN)1) /* hack: win_region == 1 means retrieve region from server */ { if (!(hrgn = NtGdiCreateRectRgn( 0, 0, 0, 0 ))) return; diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index ef2d284cfe1..0ce908e5cad 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -212,6 +212,7 @@ struct window_surface; struct window_surface_funcs { void (*set_clip)( struct window_surface *surface, const RECT *rects, UINT count ); + void (*set_shape)( struct window_surface *surface, const RECT *rects, UINT count ); BOOL (*flush)( struct window_surface *surface, const RECT *rect, const RECT *dirty, const BITMAPINFO *color_info, const void *color_bits ); void (*destroy)( struct window_surface *surface ); @@ -232,6 +233,8 @@ struct window_surface COLORREF color_key; /* layered window surface color key, invalid if CLR_INVALID */ UINT alpha_bits; /* layered window global alpha bits, invalid if -1 */ UINT alpha_mask; /* layered window per-pixel alpha mask, invalid if 0 */ + HRGN shape_region; /* shape of the window surface, unshaped if 0 */ + HBITMAP shape_bitmap; /* bitmap for the surface shape (1bpp) */ HBITMAP color_bitmap; /* bitmap for the surface colors */ /* driver-specific fields here */ }; @@ -245,6 +248,8 @@ W32KAPI void window_surface_unlock( struct window_surface *surface ); W32KAPI void window_surface_set_layered( struct window_surface *surface, COLORREF color_key, UINT alpha_bits, UINT alpha_mask ); W32KAPI void window_surface_flush( struct window_surface *surface ); W32KAPI void window_surface_set_clip( struct window_surface *surface, HRGN clip_region ); +W32KAPI void window_surface_set_shape( struct window_surface *surface, HRGN shape_region ); +W32KAPI void window_surface_set_layered( struct window_surface *surface, COLORREF color_key, UINT alpha_bits, UINT alpha_mask );
/* display manager interface, used to initialize display device registry data */