From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 62 +++++++++++++-------------- dlls/wineandroid.drv/window.c | 12 +----- dlls/winemac.drv/surface.c | 13 +----- dlls/winewayland.drv/window_surface.c | 13 +----- dlls/winex11.drv/bitblt.c | 49 +++++++++------------ include/wine/gdi_driver.h | 5 +-- 6 files changed, 59 insertions(+), 95 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 1f8d1e4c3e2..aa6836e3440 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -61,14 +61,9 @@ 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 BITMAPINFO *shape_info, const void *shape_bits ) -{ - /* 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 ) + const BITMAPINFO *color_info, const void *color_bits, BOOL shape_changed, + const BITMAPINFO *shape_info, const void *shape_bits ) { /* nothing to do */ return TRUE; @@ -82,7 +77,6 @@ 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 }; @@ -103,13 +97,9 @@ static void offscreen_window_surface_set_clip( struct window_surface *surface, c { }
-static void offscreen_window_surface_set_shape( struct window_surface *surface, - const BITMAPINFO *shape_info, const void *shape_bits ) -{ -} - static BOOL offscreen_window_surface_flush( struct window_surface *surface, const RECT *rect, const RECT *dirty, - const BITMAPINFO *color_info, const void *color_bits ) + const BITMAPINFO *color_info, const void *color_bits, BOOL shape_changed, + const BITMAPINFO *shape_info, const void *shape_bits ) { return TRUE; } @@ -122,7 +112,6 @@ 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 }; @@ -242,23 +231,27 @@ static BYTE shape_from_color_key_32( UINT32 *bits, UINT32 color_mask, UINT32 col return ~mask; }
-static void set_surface_shape( struct window_surface *surface, const RECT *rect, const RECT *dirty, +static BOOL set_surface_shape( struct window_surface *surface, const RECT *rect, const RECT *dirty, const BITMAPINFO *color_info, void *color_bits ) { UINT width, height, x, y, shape_stride, color_stride, alpha_mask = surface->alpha_mask; char shape_buf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *shape_info = (BITMAPINFO *)shape_buf; COLORREF color_key = surface->color_key; + void *shape_bits, *old_shape; RECT *shape_rect, tmp_rect; WINEREGION *data; - void *shape_bits; + BOOL ret;
width = color_info->bmiHeader.biWidth; height = abs( color_info->bmiHeader.biHeight ); assert( !(width & 7) ); /* expect 1bpp bitmap to be aligned on bytes */
if (!surface->shape_bitmap) surface->shape_bitmap = NtGdiCreateBitmap( width, height, 1, 1, NULL ); - if (!(shape_bits = window_surface_get_shape( surface, shape_info ))) return; + if (!(shape_bits = window_surface_get_shape( surface, shape_info ))) return FALSE; + + old_shape = malloc( shape_info->bmiHeader.biSizeImage ); + memcpy( old_shape, shape_bits, shape_info->bmiHeader.biSizeImage );
color_stride = color_info->bmiHeader.biSizeImage / height; shape_stride = shape_info->bmiHeader.biSizeImage / abs( shape_info->bmiHeader.biHeight ); @@ -328,28 +321,28 @@ static void set_surface_shape( struct window_surface *surface, const RECT *rect, } }
- surface->funcs->set_shape( surface, shape_info, shape_bits ); + ret = memcmp( old_shape, shape_bits, shape_info->bmiHeader.biSizeImage ); + free( old_shape ); + return ret; }
-static void clear_surface_shape( struct window_surface *surface ) +static BOOL clear_surface_shape( struct window_surface *surface ) { - if (surface->shape_bitmap) - { - NtGdiDeleteObjectApp( surface->shape_bitmap ); - surface->shape_bitmap = 0; - surface->funcs->set_shape( surface, NULL, NULL ); - } + if (!surface->shape_bitmap) return FALSE; + NtGdiDeleteObjectApp( surface->shape_bitmap ); + surface->shape_bitmap = 0; + return TRUE; }
-static void update_surface_shape( struct window_surface *surface, const RECT *rect, const RECT *dirty, +static BOOL update_surface_shape( struct window_surface *surface, const RECT *rect, const RECT *dirty, const BITMAPINFO *color_info, void *color_bits ) { - if (surface == &dummy_surface) return; + if (surface == &dummy_surface) return FALSE;
if (surface->shape_region || surface->alpha_mask || surface->color_key != CLR_INVALID) - set_surface_shape( surface, rect, dirty, color_info, color_bits ); + return set_surface_shape( surface, rect, dirty, color_info, color_bits ); else - clear_surface_shape( surface ); + return clear_surface_shape( surface ); }
W32KAPI BOOL window_surface_init( struct window_surface *surface, const struct window_surface_funcs *funcs, @@ -427,7 +420,9 @@ void *window_surface_get_color( struct window_surface *surface, BITMAPINFO *info W32KAPI void window_surface_flush( struct window_surface *surface ) { char color_buf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + char shape_buf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *color_info = (BITMAPINFO *)color_buf; + BITMAPINFO *shape_info = (BITMAPINFO *)shape_buf; RECT dirty = surface->rect, bounds; void *color_bits;
@@ -443,12 +438,15 @@ W32KAPI void window_surface_flush( struct window_surface *surface )
if (intersect_rect( &dirty, &dirty, &bounds ) && (color_bits = window_surface_get_color( surface, color_info ))) { - update_surface_shape( surface, &surface->rect, &dirty, color_info, color_bits ); + BOOL shape_changed = update_surface_shape( surface, &surface->rect, &dirty, color_info, color_bits ); + void *shape_bits = window_surface_get_shape( surface, shape_info );
TRACE( "Flushing hwnd %p, surface %p %s, bounds %s, dirty %s\n", surface->hwnd, surface, wine_dbgstr_rect( &surface->rect ), wine_dbgstr_rect( &surface->bounds ), wine_dbgstr_rect( &dirty ) );
- if (surface->funcs->flush( surface, &surface->rect, &dirty, color_info, color_bits )) reset_bounds( &surface->bounds ); + if (surface->funcs->flush( surface, &surface->rect, &dirty, color_info, color_bits, + shape_changed, shape_info, shape_bits )) + reset_bounds( &surface->bounds ); }
window_surface_unlock( surface ); diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 498cb744a64..0f8cedfbd0b 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -618,19 +618,12 @@ 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 BITMAPINFO *shape_info, const void *shape_bits ) -{ -} - /*********************************************************************** * android_surface_flush */ static BOOL android_surface_flush( struct window_surface *window_surface, const RECT *rect, const RECT *dirty, - const BITMAPINFO *color_info, const void *color_bits ) + const BITMAPINFO *color_info, const void *color_bits, BOOL shape_changed, + const BITMAPINFO *shape_info, const void *shape_bits ) { struct android_window_surface *surface = get_android_surface( window_surface ); ANativeWindow_Buffer buffer; @@ -712,7 +705,6 @@ 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 a4103b1818b..fa34a5122ab 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -74,20 +74,12 @@ 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 BITMAPINFO *shape_info, const void *shape_bits) -{ - /* TODO */ -} - /*********************************************************************** * macdrv_surface_flush */ static BOOL macdrv_surface_flush(struct window_surface *window_surface, const RECT *rect, const RECT *dirty, - const BITMAPINFO *color_info, const void *color_bits) + const BITMAPINFO *color_info, const void *color_bits, BOOL shape_changed, + const BITMAPINFO *shape_info, const void *shape_bits) { struct macdrv_window_surface *surface = get_mac_surface(window_surface); CGImageAlphaInfo alpha_info = (window_surface->alpha_mask ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst); @@ -121,7 +113,6 @@ 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 b29f7faf781..e9eb74b17ca 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -217,15 +217,6 @@ 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 BITMAPINFO *shape_info, const void *shape_bits) -{ - /* TODO */ -} - /********************************************************************** * get_region_data */ @@ -328,7 +319,8 @@ static void wayland_shm_buffer_copy(struct wayland_shm_buffer *src, * wayland_window_surface_flush */ static BOOL wayland_window_surface_flush(struct window_surface *window_surface, const RECT *rect, const RECT *dirty, - const BITMAPINFO *color_info, const void *color_bits) + const BITMAPINFO *color_info, const void *color_bits, BOOL shape_changed, + const BITMAPINFO *shape_info, const void *shape_bits) { RECT surface_rect = {.right = color_info->bmiHeader.biWidth, .bottom = abs(color_info->bmiHeader.biHeight)}; struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface); @@ -439,7 +431,6 @@ 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 649f301827f..de233bfb679 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1785,37 +1785,12 @@ 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 BITMAPINFO *shape_info, const void *shape_bits ) -{ -#ifdef HAVE_LIBXSHAPE - struct x11drv_window_surface *surface = get_x11_surface( window_surface ); - - if (!shape_bits) - XShapeCombineMask( gdi_display, surface->window, ShapeBounding, 0, 0, None, ShapeSet ); - else - { - struct gdi_image_bits bits = {.ptr = (void *)shape_bits}; - XVisualInfo vis = default_visual; - Pixmap shape; - - vis.depth = 1; - shape = create_pixmap_from_image( 0, &vis, shape_info, &bits, DIB_RGB_COLORS ); - XShapeCombineMask( gdi_display, surface->window, ShapeBounding, 0, 0, shape, ShapeSet ); - XFreePixmap( gdi_display, shape ); - } - XFlush( gdi_display ); -#endif /* HAVE_LIBXSHAPE */ -} - /*********************************************************************** * x11drv_surface_flush */ static BOOL x11drv_surface_flush( struct window_surface *window_surface, const RECT *rect, const RECT *dirty, - const BITMAPINFO *color_info, const void *color_bits ) + const BITMAPINFO *color_info, const void *color_bits, BOOL shape_changed, + const BITMAPINFO *shape_info, const void *shape_bits ) { UINT alpha_mask = window_surface->alpha_mask, alpha_bits = window_surface->alpha_bits; struct x11drv_window_surface *surface = get_x11_surface( window_surface ); @@ -1859,6 +1834,25 @@ static BOOL x11drv_surface_flush( struct window_surface *window_surface, const R dirty->top, rect->left + dirty->left, rect->top + dirty->top, dirty->right - dirty->left, dirty->bottom - dirty->top );
+ if (shape_changed) + { +#ifdef HAVE_LIBXSHAPE + if (!shape_bits) + XShapeCombineMask( gdi_display, surface->window, ShapeBounding, 0, 0, None, ShapeSet ); + else + { + struct gdi_image_bits bits = {.ptr = (void *)shape_bits}; + XVisualInfo vis = default_visual; + Pixmap shape; + + vis.depth = 1; + shape = create_pixmap_from_image( 0, &vis, shape_info, &bits, DIB_RGB_COLORS ); + XShapeCombineMask( gdi_display, surface->window, ShapeBounding, 0, 0, shape, ShapeSet ); + XFreePixmap( gdi_display, shape ); + } +#endif /* HAVE_LIBXSHAPE */ + } + XFlush( gdi_display );
return TRUE; @@ -1880,7 +1874,6 @@ 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/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index a8f4eb97cfa..774211fea15 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -212,10 +212,9 @@ 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 BITMAPINFO *shape_info, - const void *shape_bits ); BOOL (*flush)( struct window_surface *surface, const RECT *rect, const RECT *dirty, - const BITMAPINFO *color_info, const void *color_bits ); + const BITMAPINFO *color_info, const void *color_bits, BOOL shape_changed, + const BITMAPINFO *shape_info, const void *shape_bits ); void (*destroy)( struct window_surface *surface ); };