mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 05:53:45 +00:00
win32u: Use a helper to set the window surface clipping, within the lock.
This commit is contained in:
parent
39f79d73fa
commit
8d587a47eb
|
@ -74,7 +74,7 @@ static void *dummy_surface_get_bitmap_info( struct window_surface *window_surfac
|
|||
return &dummy_data;
|
||||
}
|
||||
|
||||
static void dummy_surface_set_region( struct window_surface *window_surface, HRGN region )
|
||||
static void dummy_surface_set_clip( struct window_surface *window_surface, const RECT *rects, UINT count )
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ static void dummy_surface_destroy( struct window_surface *window_surface )
|
|||
static const struct window_surface_funcs dummy_surface_funcs =
|
||||
{
|
||||
dummy_surface_get_bitmap_info,
|
||||
dummy_surface_set_region,
|
||||
dummy_surface_set_clip,
|
||||
dummy_surface_flush,
|
||||
dummy_surface_destroy
|
||||
};
|
||||
|
@ -132,7 +132,7 @@ static void *offscreen_window_surface_get_bitmap_info( struct window_surface *ba
|
|||
return impl->bits;
|
||||
}
|
||||
|
||||
static void offscreen_window_surface_set_region( struct window_surface *base, HRGN region )
|
||||
static void offscreen_window_surface_set_clip( struct window_surface *base, const RECT *rects, UINT count )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ static void offscreen_window_surface_destroy( struct window_surface *base )
|
|||
static const struct window_surface_funcs offscreen_window_surface_funcs =
|
||||
{
|
||||
offscreen_window_surface_get_bitmap_info,
|
||||
offscreen_window_surface_set_region,
|
||||
offscreen_window_surface_set_clip,
|
||||
offscreen_window_surface_flush,
|
||||
offscreen_window_surface_destroy
|
||||
};
|
||||
|
@ -219,6 +219,7 @@ W32KAPI void window_surface_release( struct window_surface *surface )
|
|||
if (!ret)
|
||||
{
|
||||
if (surface != &dummy_surface) pthread_mutex_destroy( &surface->mutex );
|
||||
if (surface->clip_region) NtGdiDeleteObjectApp( surface->clip_region );
|
||||
surface->funcs->destroy( surface );
|
||||
}
|
||||
}
|
||||
|
@ -251,6 +252,39 @@ W32KAPI void window_surface_flush( struct window_surface *surface )
|
|||
window_surface_unlock( surface );
|
||||
}
|
||||
|
||||
W32KAPI void window_surface_set_clip( struct window_surface *surface, HRGN clip_region )
|
||||
{
|
||||
window_surface_lock( surface );
|
||||
|
||||
if (!clip_region && surface->clip_region)
|
||||
{
|
||||
TRACE( "hwnd %p, surface %p %s, clearing clip region\n", surface->hwnd, surface,
|
||||
wine_dbgstr_rect( &surface->rect ) );
|
||||
|
||||
NtGdiDeleteObjectApp( surface->clip_region );
|
||||
surface->clip_region = 0;
|
||||
surface->funcs->set_clip( surface, NULL, 0 );
|
||||
}
|
||||
else if (clip_region && !NtGdiEqualRgn( clip_region, surface->clip_region ))
|
||||
{
|
||||
WINEREGION *data;
|
||||
|
||||
TRACE( "hwnd %p, surface %p %s, setting clip region %p\n", surface->hwnd, surface,
|
||||
wine_dbgstr_rect( &surface->rect ), clip_region );
|
||||
|
||||
if (!surface->clip_region) surface->clip_region = NtGdiCreateRectRgn( 0, 0, 0, 0 );
|
||||
NtGdiCombineRgn( surface->clip_region, clip_region, 0, RGN_COPY );
|
||||
|
||||
if ((data = GDI_GetObjPtr( clip_region, NTGDI_OBJ_REGION )))
|
||||
{
|
||||
surface->funcs->set_clip( surface, data->rects, data->numRects );
|
||||
GDI_ReleaseObj( clip_region );
|
||||
}
|
||||
}
|
||||
|
||||
window_surface_unlock( surface );
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* register_window_surface
|
||||
*
|
||||
|
|
|
@ -1781,12 +1781,12 @@ static void update_surface_region( HWND hwnd )
|
|||
}
|
||||
|
||||
if (get_window_region( hwnd, TRUE, ®ion, &visible )) goto done;
|
||||
if (!region) win->surface->funcs->set_region( win->surface, shape );
|
||||
if (!region) window_surface_set_clip( win->surface, shape );
|
||||
else
|
||||
{
|
||||
NtGdiOffsetRgn( region, -visible.left, -visible.top );
|
||||
if (shape) NtGdiCombineRgn( region, region, shape, RGN_AND );
|
||||
win->surface->funcs->set_region( win->surface, region );
|
||||
window_surface_set_clip( win->surface, region );
|
||||
NtGdiDeleteObjectApp( region );
|
||||
}
|
||||
|
||||
|
|
|
@ -571,8 +571,8 @@ struct android_window_surface
|
|||
struct window_surface header;
|
||||
ANativeWindow *window;
|
||||
BOOL byteswap;
|
||||
RGNDATA *region_data;
|
||||
HRGN region;
|
||||
UINT clip_count;
|
||||
RECT *clip_rects;
|
||||
BYTE alpha;
|
||||
COLORREF color_key;
|
||||
void *bits;
|
||||
|
@ -647,40 +647,18 @@ static void *android_surface_get_bitmap_info( struct window_surface *window_surf
|
|||
}
|
||||
|
||||
/***********************************************************************
|
||||
* android_surface_set_region
|
||||
* android_surface_set_clip
|
||||
*/
|
||||
static void android_surface_set_region( struct window_surface *window_surface, HRGN region )
|
||||
static void android_surface_set_clip( struct window_surface *window_surface, const RECT *rects, UINT count )
|
||||
{
|
||||
struct android_window_surface *surface = get_android_surface( window_surface );
|
||||
RGNDATA *data;
|
||||
UINT size;
|
||||
|
||||
TRACE( "updating surface %p hwnd %p with %p\n", surface, window_surface->hwnd, region );
|
||||
free( surface->clip_rects );
|
||||
surface->clip_rects = NULL;
|
||||
|
||||
window_surface_lock( window_surface );
|
||||
if (!region)
|
||||
{
|
||||
if (surface->region) NtGdiDeleteObjectApp( surface->region );
|
||||
surface->region = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!surface->region) surface->region = NtGdiCreateRectRgn( 0, 0, 0, 0 );
|
||||
NtGdiCombineRgn( surface->region, region, 0, RGN_COPY );
|
||||
}
|
||||
|
||||
if (!(size = NtGdiGetRegionData( region, 0, NULL ))) goto done;
|
||||
if (!(data = malloc( size ))) goto done;
|
||||
if (!NtGdiGetRegionData( region, size, data ))
|
||||
{
|
||||
free( data );
|
||||
data = NULL;
|
||||
}
|
||||
free( surface->region_data );
|
||||
surface->region_data = data;
|
||||
|
||||
done:
|
||||
window_surface_unlock( window_surface );
|
||||
if (!count || !(surface->clip_rects = malloc( count * sizeof(*rects) ))) return;
|
||||
memcpy( surface->clip_rects, rects, count * sizeof(*rects) );
|
||||
surface->clip_count = count;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -699,7 +677,7 @@ static BOOL android_surface_flush( struct window_surface *window_surface, const
|
|||
|
||||
if (!surface->window->perform( surface->window, NATIVE_WINDOW_LOCK, &buffer, &rc ))
|
||||
{
|
||||
const RECT *rgn_rect = NULL, *end = NULL;
|
||||
const RECT *rgn_rect = surface->clip_rects, *end = surface->clip_rects + surface->clip_count;
|
||||
DWORD *src, *dst;
|
||||
int x, y, width;
|
||||
RECT locked;
|
||||
|
@ -710,11 +688,6 @@ static BOOL android_surface_flush( struct window_surface *window_surface, const
|
|||
locked.bottom = rc.bottom;
|
||||
intersect_rect( &locked, &locked, rect );
|
||||
|
||||
if (surface->region_data)
|
||||
{
|
||||
rgn_rect = (RECT *)surface->region_data->Buffer;
|
||||
end = rgn_rect + surface->region_data->rdh.nCount;
|
||||
}
|
||||
src = (DWORD *)surface->bits + (locked.top - rect->top) * surface->info.bmiHeader.biWidth +
|
||||
(locked.left - rect->left);
|
||||
dst = (DWORD *)buffer.bits + locked.top * buffer.stride + locked.left;
|
||||
|
@ -762,8 +735,7 @@ static void android_surface_destroy( struct window_surface *window_surface )
|
|||
|
||||
TRACE( "freeing %p bits %p\n", surface, surface->bits );
|
||||
|
||||
free( surface->region_data );
|
||||
if (surface->region) NtGdiDeleteObjectApp( surface->region );
|
||||
free( surface->clip_rects );
|
||||
release_ioctl_window( surface->window );
|
||||
free( surface->bits );
|
||||
free( surface );
|
||||
|
@ -772,7 +744,7 @@ static void android_surface_destroy( struct window_surface *window_surface )
|
|||
static const struct window_surface_funcs android_surface_funcs =
|
||||
{
|
||||
android_surface_get_bitmap_info,
|
||||
android_surface_set_region,
|
||||
android_surface_set_clip,
|
||||
android_surface_flush,
|
||||
android_surface_destroy
|
||||
};
|
||||
|
|
|
@ -64,7 +64,6 @@ struct macdrv_window_surface
|
|||
{
|
||||
struct window_surface header;
|
||||
macdrv_window window;
|
||||
HRGN region;
|
||||
BOOL use_alpha;
|
||||
BYTE *bits;
|
||||
BITMAPINFO info; /* variable size, must be last */
|
||||
|
@ -85,28 +84,10 @@ static void *macdrv_surface_get_bitmap_info(struct window_surface *window_surfac
|
|||
}
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_surface_set_region
|
||||
* macdrv_surface_set_clip
|
||||
*/
|
||||
static void macdrv_surface_set_region(struct window_surface *window_surface, HRGN region)
|
||||
static void macdrv_surface_set_clip(struct window_surface *window_surface, const RECT *rects, UINT count)
|
||||
{
|
||||
struct macdrv_window_surface *surface = get_mac_surface(window_surface);
|
||||
|
||||
TRACE("updating surface %p with %p\n", surface, region);
|
||||
|
||||
window_surface_lock(window_surface);
|
||||
|
||||
if (region)
|
||||
{
|
||||
if (!surface->region) surface->region = NtGdiCreateRectRgn(0, 0, 0, 0);
|
||||
NtGdiCombineRgn(surface->region, region, 0, RGN_COPY);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (surface->region) NtGdiDeleteObjectApp(surface->region);
|
||||
surface->region = 0;
|
||||
}
|
||||
|
||||
window_surface_unlock(window_surface);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -127,7 +108,6 @@ static void macdrv_surface_destroy(struct window_surface *window_surface)
|
|||
struct macdrv_window_surface *surface = get_mac_surface(window_surface);
|
||||
|
||||
TRACE("freeing %p bits %p\n", surface, surface->bits);
|
||||
if (surface->region) NtGdiDeleteObjectApp(surface->region);
|
||||
free(surface->bits);
|
||||
free(surface);
|
||||
}
|
||||
|
@ -135,7 +115,7 @@ static void macdrv_surface_destroy(struct window_surface *window_surface)
|
|||
static const struct window_surface_funcs macdrv_surface_funcs =
|
||||
{
|
||||
macdrv_surface_get_bitmap_info,
|
||||
macdrv_surface_set_region,
|
||||
macdrv_surface_set_clip,
|
||||
macdrv_surface_flush,
|
||||
macdrv_surface_destroy,
|
||||
};
|
||||
|
|
|
@ -224,10 +224,10 @@ static void *wayland_window_surface_get_bitmap_info(struct window_surface *windo
|
|||
}
|
||||
|
||||
/***********************************************************************
|
||||
* wayland_window_surface_set_region
|
||||
* wayland_window_surface_set_clip
|
||||
*/
|
||||
static void wayland_window_surface_set_region(struct window_surface *window_surface,
|
||||
HRGN region)
|
||||
static void wayland_window_surface_set_clip(struct window_surface *window_surface,
|
||||
const RECT *rects, UINT count)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
@ -444,7 +444,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_get_bitmap_info,
|
||||
wayland_window_surface_set_region,
|
||||
wayland_window_surface_set_clip,
|
||||
wayland_window_surface_flush,
|
||||
wayland_window_surface_destroy
|
||||
};
|
||||
|
|
|
@ -1581,7 +1581,6 @@ struct x11drv_window_surface
|
|||
BOOL is_argb;
|
||||
DWORD alpha_bits;
|
||||
COLORREF color_key;
|
||||
HRGN region;
|
||||
void *bits;
|
||||
#ifdef HAVE_LIBXXSHM
|
||||
XShmSegmentInfo shminfo;
|
||||
|
@ -1837,35 +1836,41 @@ static void *x11drv_surface_get_bitmap_info( struct window_surface *window_surfa
|
|||
return surface->bits;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* x11drv_surface_set_region
|
||||
*/
|
||||
static void x11drv_surface_set_region( struct window_surface *window_surface, HRGN region )
|
||||
static XRectangle *xrectangles_from_rects( const RECT *rects, UINT count )
|
||||
{
|
||||
XRectangle *xrects;
|
||||
if (!(xrects = malloc( count * sizeof(*xrects) ))) return NULL;
|
||||
while (count--)
|
||||
{
|
||||
if (rects[count].left > SHRT_MAX) continue;
|
||||
if (rects[count].top > SHRT_MAX) continue;
|
||||
if (rects[count].right < SHRT_MIN) continue;
|
||||
if (rects[count].bottom < SHRT_MIN) continue;
|
||||
xrects[count].x = max( min( rects[count].left, SHRT_MAX), SHRT_MIN);
|
||||
xrects[count].y = max( min( rects[count].top, SHRT_MAX), SHRT_MIN);
|
||||
xrects[count].width = max( min( rects[count].right, SHRT_MAX ) - xrects[count].x, 0);
|
||||
xrects[count].height = max( min( rects[count].bottom, SHRT_MAX ) - xrects[count].y, 0);
|
||||
}
|
||||
return xrects;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* x11drv_surface_set_clip
|
||||
*/
|
||||
static void x11drv_surface_set_clip( struct window_surface *window_surface, const RECT *rects, UINT count )
|
||||
{
|
||||
RGNDATA *data;
|
||||
struct x11drv_window_surface *surface = get_x11_surface( window_surface );
|
||||
XRectangle *xrects;
|
||||
|
||||
TRACE( "updating surface %p with %p\n", surface, region );
|
||||
TRACE( "surface %p, rects %p, count %u\n", surface, rects, count );
|
||||
|
||||
window_surface_lock( window_surface );
|
||||
if (!region)
|
||||
{
|
||||
if (surface->region) NtGdiDeleteObjectApp( surface->region );
|
||||
surface->region = 0;
|
||||
if (!count)
|
||||
XSetClipMask( gdi_display, surface->gc, None );
|
||||
}
|
||||
else
|
||||
else if ((xrects = xrectangles_from_rects( rects, count )))
|
||||
{
|
||||
if (!surface->region) surface->region = NtGdiCreateRectRgn( 0, 0, 0, 0 );
|
||||
NtGdiCombineRgn( surface->region, region, 0, RGN_COPY );
|
||||
if ((data = X11DRV_GetRegionData( surface->region, 0 )))
|
||||
{
|
||||
XSetClipRectangles( gdi_display, surface->gc, 0, 0,
|
||||
(XRectangle *)data->Buffer, data->rdh.nCount, YXBanded );
|
||||
free( data );
|
||||
}
|
||||
XSetClipRectangles( gdi_display, surface->gc, 0, 0, xrects, count, YXBanded );
|
||||
free( xrects );
|
||||
}
|
||||
window_surface_unlock( window_surface );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1938,7 +1943,6 @@ static void x11drv_surface_destroy( struct window_surface *window_surface )
|
|||
surface->image->data = NULL;
|
||||
XDestroyImage( surface->image );
|
||||
}
|
||||
if (surface->region) NtGdiDeleteObjectApp( surface->region );
|
||||
|
||||
free( surface );
|
||||
}
|
||||
|
@ -1946,7 +1950,7 @@ static void x11drv_surface_destroy( struct window_surface *window_surface )
|
|||
static const struct window_surface_funcs x11drv_surface_funcs =
|
||||
{
|
||||
x11drv_surface_get_bitmap_info,
|
||||
x11drv_surface_set_region,
|
||||
x11drv_surface_set_clip,
|
||||
x11drv_surface_flush,
|
||||
x11drv_surface_destroy
|
||||
};
|
||||
|
@ -2038,7 +2042,6 @@ void set_surface_color_key( struct window_surface *window_surface, COLORREF colo
|
|||
*/
|
||||
HRGN expose_surface( struct window_surface *window_surface, const RECT *rect )
|
||||
{
|
||||
struct x11drv_window_surface *surface = get_x11_surface( window_surface );
|
||||
HRGN region = 0;
|
||||
RECT rc = *rect;
|
||||
|
||||
|
@ -2047,10 +2050,10 @@ HRGN expose_surface( struct window_surface *window_surface, const RECT *rect )
|
|||
window_surface_lock( window_surface );
|
||||
OffsetRect( &rc, -window_surface->rect.left, -window_surface->rect.top );
|
||||
add_bounds_rect( &window_surface->bounds, &rc );
|
||||
if (surface->region)
|
||||
if (window_surface->clip_region)
|
||||
{
|
||||
region = NtGdiCreateRectRgn( rect->left, rect->top, rect->right, rect->bottom );
|
||||
if (NtGdiCombineRgn( region, region, surface->region, RGN_DIFF ) <= NULLREGION)
|
||||
if (NtGdiCombineRgn( region, region, window_surface->clip_region, RGN_DIFF ) <= NULLREGION)
|
||||
{
|
||||
NtGdiDeleteObjectApp( region );
|
||||
region = 0;
|
||||
|
|
|
@ -212,7 +212,7 @@ struct window_surface;
|
|||
struct window_surface_funcs
|
||||
{
|
||||
void* (*get_info)( struct window_surface *surface, BITMAPINFO *info );
|
||||
void (*set_region)( struct window_surface *surface, HRGN region );
|
||||
void (*set_clip)( struct window_surface *surface, const RECT *rects, UINT count );
|
||||
BOOL (*flush)( struct window_surface *surface, const RECT *rect, const RECT *dirty );
|
||||
void (*destroy)( struct window_surface *surface );
|
||||
};
|
||||
|
@ -227,6 +227,7 @@ struct window_surface
|
|||
|
||||
pthread_mutex_t mutex;
|
||||
RECT bounds; /* dirty area rect, requires locking */
|
||||
HRGN clip_region; /* visible region of the surface, fully visible if 0 */
|
||||
DWORD draw_start_ticks; /* start ticks of fresh draw */
|
||||
/* driver-specific fields here */
|
||||
};
|
||||
|
@ -237,6 +238,7 @@ W32KAPI void window_surface_release( struct window_surface *surface );
|
|||
W32KAPI void window_surface_lock( struct window_surface *surface );
|
||||
W32KAPI void window_surface_unlock( struct window_surface *surface );
|
||||
W32KAPI void window_surface_flush( struct window_surface *surface );
|
||||
W32KAPI void window_surface_set_clip( struct window_surface *surface, HRGN clip_region );
|
||||
|
||||
/* display manager interface, used to initialize display device registry data */
|
||||
|
||||
|
|
Loading…
Reference in a new issue