mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 20:59:54 +00:00
winex11: Allow the visible region to be zero when not clipping.
This commit is contained in:
parent
649e33de58
commit
8d6354c5b2
@ -1280,9 +1280,8 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info
|
||||
}
|
||||
else
|
||||
{
|
||||
RGNDATA *saved_region = NULL;
|
||||
BOOL restore_region = add_extra_clipping_region( physdev, clip );
|
||||
|
||||
if (clip) saved_region = add_extra_clipping_region( physdev, clip );
|
||||
X11DRV_LockDIBSection( physdev, DIB_Status_GdiMod );
|
||||
|
||||
/* optimization for single-op ROPs */
|
||||
@ -1317,7 +1316,7 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info
|
||||
}
|
||||
|
||||
X11DRV_UnlockDIBSection( physdev, !ret );
|
||||
restore_clipping_region( physdev, saved_region );
|
||||
if (restore_region) restore_clipping_region( physdev );
|
||||
}
|
||||
image->data = NULL;
|
||||
}
|
||||
|
@ -188,12 +188,24 @@ RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp )
|
||||
/***********************************************************************
|
||||
* update_x11_clipping
|
||||
*/
|
||||
static void update_x11_clipping( X11DRV_PDEVICE *physDev, const RGNDATA *data )
|
||||
static void update_x11_clipping( X11DRV_PDEVICE *physDev, HRGN rgn )
|
||||
{
|
||||
wine_tsx11_lock();
|
||||
XSetClipRectangles( gdi_display, physDev->gc, physDev->dc_rect.left, physDev->dc_rect.top,
|
||||
(XRectangle *)data->Buffer, data->rdh.nCount, YXBanded );
|
||||
wine_tsx11_unlock();
|
||||
RGNDATA *data;
|
||||
|
||||
if (!rgn)
|
||||
{
|
||||
wine_tsx11_lock();
|
||||
XSetClipMask( gdi_display, physDev->gc, None );
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
else if ((data = X11DRV_GetRegionData( rgn, 0 )))
|
||||
{
|
||||
wine_tsx11_lock();
|
||||
XSetClipRectangles( gdi_display, physDev->gc, physDev->dc_rect.left, physDev->dc_rect.top,
|
||||
(XRectangle *)data->Buffer, data->rdh.nCount, YXBanded );
|
||||
wine_tsx11_unlock();
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -201,38 +213,31 @@ static void update_x11_clipping( X11DRV_PDEVICE *physDev, const RGNDATA *data )
|
||||
* add_extra_clipping_region
|
||||
*
|
||||
* Temporarily add a region to the current clipping region.
|
||||
* The returned region must be restored with restore_clipping_region.
|
||||
* The region must be restored with restore_clipping_region.
|
||||
*/
|
||||
RGNDATA *add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn )
|
||||
BOOL add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn )
|
||||
{
|
||||
RGNDATA *ret, *data;
|
||||
HRGN clip;
|
||||
|
||||
if (!(ret = X11DRV_GetRegionData( dev->region, 0 ))) return NULL;
|
||||
if (!(clip = CreateRectRgn( 0, 0, 0, 0 )))
|
||||
if (!rgn) return FALSE;
|
||||
if (dev->region)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, ret );
|
||||
return NULL;
|
||||
if (!(clip = CreateRectRgn( 0, 0, 0, 0 ))) return FALSE;
|
||||
CombineRgn( clip, dev->region, rgn, RGN_AND );
|
||||
update_x11_clipping( dev, clip );
|
||||
DeleteObject( clip );
|
||||
}
|
||||
CombineRgn( clip, dev->region, rgn, RGN_AND );
|
||||
if ((data = X11DRV_GetRegionData( clip, 0 )))
|
||||
{
|
||||
update_x11_clipping( dev, data );
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
}
|
||||
DeleteObject( clip );
|
||||
return ret;
|
||||
else update_x11_clipping( dev, rgn );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* restore_clipping_region
|
||||
*/
|
||||
void restore_clipping_region( X11DRV_PDEVICE *dev, RGNDATA *data )
|
||||
void restore_clipping_region( X11DRV_PDEVICE *dev )
|
||||
{
|
||||
if (!data) return;
|
||||
update_x11_clipping( dev, data );
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
update_x11_clipping( dev, dev->region );
|
||||
}
|
||||
|
||||
|
||||
@ -241,13 +246,10 @@ void restore_clipping_region( X11DRV_PDEVICE *dev, RGNDATA *data )
|
||||
*/
|
||||
void X11DRV_SetDeviceClipping( PHYSDEV dev, HRGN rgn )
|
||||
{
|
||||
RGNDATA *data;
|
||||
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
|
||||
|
||||
physDev->region = rgn;
|
||||
|
||||
if ((data = X11DRV_GetRegionData( physDev->region, 0 ))) update_x11_clipping( physDev, data );
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
update_x11_clipping( physDev, rgn );
|
||||
}
|
||||
|
||||
|
||||
@ -1455,8 +1457,24 @@ BOOL X11DRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillTy
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
LPtoDP( dev->hdc, &pt, 1 );
|
||||
if (!PtInRegion( physDev->region, pt.x, pt.y )) return FALSE;
|
||||
GetRgnBox( physDev->region, &rect );
|
||||
|
||||
if (!physDev->region)
|
||||
{
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = physDev->dc_rect.right - physDev->dc_rect.left;
|
||||
rect.bottom = physDev->dc_rect.bottom - physDev->dc_rect.top;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!PtInRegion( physDev->region, pt.x, pt.y )) return FALSE;
|
||||
GetRgnBox( physDev->region, &rect );
|
||||
rect.left = max( rect.left, 0 );
|
||||
rect.top = max( rect.top, 0 );
|
||||
rect.right = min( rect.right, physDev->dc_rect.right - physDev->dc_rect.left );
|
||||
rect.bottom = min( rect.bottom, physDev->dc_rect.bottom - physDev->dc_rect.top );
|
||||
}
|
||||
if (pt.x < rect.left || pt.x >= rect.right || pt.y < rect.top || pt.y >= rect.bottom) return FALSE;
|
||||
|
||||
X11DRV_expect_error( gdi_display, ExtFloodFillXGetImageErrorHandler, NULL );
|
||||
image = XGetImage( gdi_display, physDev->drawable,
|
||||
|
@ -41,7 +41,7 @@ BOOL X11DRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
||||
const RECT *lprect, LPCWSTR wstr, UINT count, const INT *lpDx )
|
||||
{
|
||||
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
|
||||
RGNDATA *saved_region = NULL;
|
||||
BOOL restore_region = FALSE;
|
||||
unsigned int i;
|
||||
fontObject* pfo = XFONT_GetFontObject( physDev->font );
|
||||
XFontStruct* font;
|
||||
@ -88,7 +88,7 @@ BOOL X11DRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
||||
if (flags & ETO_CLIPPED)
|
||||
{
|
||||
HRGN clip_region = CreateRectRgnIndirect( lprect );
|
||||
saved_region = add_extra_clipping_region( physDev, clip_region );
|
||||
restore_region = add_extra_clipping_region( physDev, clip_region );
|
||||
DeleteObject( clip_region );
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ BOOL X11DRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
||||
END:
|
||||
HeapFree( GetProcessHeap(), 0, str2b );
|
||||
if (dibUpdateFlag) X11DRV_UnlockDIBSection( physDev, TRUE );
|
||||
restore_clipping_region( physDev, saved_region );
|
||||
if (restore_region) restore_clipping_region( physDev );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -286,8 +286,8 @@ extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
|
||||
struct bitblt_coords *coords, const int *mapping, unsigned int zeropad_mask ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) DECLSPEC_HIDDEN;
|
||||
extern RGNDATA *add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn ) DECLSPEC_HIDDEN;
|
||||
extern void restore_clipping_region( X11DRV_PDEVICE *dev, RGNDATA *data ) DECLSPEC_HIDDEN;
|
||||
extern BOOL add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn ) DECLSPEC_HIDDEN;
|
||||
extern void restore_clipping_region( X11DRV_PDEVICE *dev ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void execute_rop( X11DRV_PDEVICE *physdev, Pixmap src_pixmap, GC gc, const RECT *visrect, DWORD rop ) DECLSPEC_HIDDEN;
|
||||
|
||||
|
@ -188,6 +188,7 @@ static void *xrender_handle;
|
||||
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f;
|
||||
MAKE_FUNCPTR(XRenderAddGlyphs)
|
||||
MAKE_FUNCPTR(XRenderChangePicture)
|
||||
MAKE_FUNCPTR(XRenderComposite)
|
||||
MAKE_FUNCPTR(XRenderCompositeText16)
|
||||
MAKE_FUNCPTR(XRenderCreateGlyphSet)
|
||||
@ -372,6 +373,7 @@ const struct gdi_dc_funcs *X11DRV_XRender_Init(void)
|
||||
#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(xrender_handle, #f, NULL, 0)) == NULL) return NULL
|
||||
#define LOAD_OPTIONAL_FUNCPTR(f) p##f = wine_dlsym(xrender_handle, #f, NULL, 0)
|
||||
LOAD_FUNCPTR(XRenderAddGlyphs);
|
||||
LOAD_FUNCPTR(XRenderChangePicture);
|
||||
LOAD_FUNCPTR(XRenderComposite);
|
||||
LOAD_FUNCPTR(XRenderCompositeText16);
|
||||
LOAD_FUNCPTR(XRenderCreateGlyphSet);
|
||||
@ -578,6 +580,30 @@ static BOOL use_source_repeat( struct xrender_physdev *dev )
|
||||
dev->x11dev->drawable_rect.bottom - dev->x11dev->drawable_rect.top == 1);
|
||||
}
|
||||
|
||||
static void update_xrender_clipping( struct xrender_physdev *dev, HRGN rgn )
|
||||
{
|
||||
XRenderPictureAttributes pa;
|
||||
RGNDATA *data;
|
||||
|
||||
if (!rgn)
|
||||
{
|
||||
wine_tsx11_lock();
|
||||
pa.clip_mask = None;
|
||||
pXRenderChangePicture( gdi_display, dev->pict, CPClipMask, &pa );
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
else if ((data = X11DRV_GetRegionData( rgn, 0 )))
|
||||
{
|
||||
wine_tsx11_lock();
|
||||
pXRenderSetPictureClipRectangles( gdi_display, dev->pict,
|
||||
dev->x11dev->dc_rect.left, dev->x11dev->dc_rect.top,
|
||||
(XRectangle *)data->Buffer, data->rdh.nCount );
|
||||
wine_tsx11_unlock();
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Picture get_xrender_picture( struct xrender_physdev *dev, HRGN clip_rgn, const RECT *clip_rect )
|
||||
{
|
||||
if (!dev->pict && dev->pict_format)
|
||||
@ -591,38 +617,31 @@ static Picture get_xrender_picture( struct xrender_physdev *dev, HRGN clip_rgn,
|
||||
wine_tsx11_unlock();
|
||||
TRACE( "Allocing pict=%lx dc=%p drawable=%08lx\n",
|
||||
dev->pict, dev->dev.hdc, dev->x11dev->drawable );
|
||||
dev->update_clip = TRUE;
|
||||
dev->update_clip = (dev->x11dev->region != 0);
|
||||
}
|
||||
|
||||
if (dev->update_clip || clip_rect || clip_rgn)
|
||||
if (clip_rect)
|
||||
{
|
||||
RGNDATA *clip_data;
|
||||
HRGN rgn = 0;
|
||||
|
||||
if (clip_rect)
|
||||
{
|
||||
rgn = CreateRectRgnIndirect( clip_rect );
|
||||
if (clip_rgn) CombineRgn( rgn, rgn, clip_rgn, RGN_AND );
|
||||
CombineRgn( rgn, rgn, dev->x11dev->region, RGN_AND );
|
||||
}
|
||||
else if (clip_rgn)
|
||||
{
|
||||
rgn = CreateRectRgn( 0, 0, 0, 0 );
|
||||
CombineRgn( rgn, clip_rgn, dev->x11dev->region, RGN_AND );
|
||||
}
|
||||
|
||||
if ((clip_data = X11DRV_GetRegionData( rgn ? rgn : dev->x11dev->region, 0 )))
|
||||
{
|
||||
wine_tsx11_lock();
|
||||
pXRenderSetPictureClipRectangles( gdi_display, dev->pict,
|
||||
dev->x11dev->dc_rect.left, dev->x11dev->dc_rect.top,
|
||||
(XRectangle *)clip_data->Buffer, clip_data->rdh.nCount );
|
||||
wine_tsx11_unlock();
|
||||
HeapFree( GetProcessHeap(), 0, clip_data );
|
||||
}
|
||||
dev->update_clip = (rgn != 0); /* have to update again if we are using a custom region */
|
||||
if (rgn) DeleteObject( rgn );
|
||||
HRGN rgn = CreateRectRgnIndirect( clip_rect );
|
||||
if (clip_rgn) CombineRgn( rgn, rgn, clip_rgn, RGN_AND );
|
||||
if (dev->x11dev->region) CombineRgn( rgn, rgn, dev->x11dev->region, RGN_AND );
|
||||
update_xrender_clipping( dev, rgn );
|
||||
DeleteObject( rgn );
|
||||
}
|
||||
else if (clip_rgn)
|
||||
{
|
||||
if (dev->x11dev->region)
|
||||
{
|
||||
HRGN rgn = CreateRectRgn( 0, 0, 0, 0 );
|
||||
CombineRgn( rgn, clip_rgn, dev->x11dev->region, RGN_AND );
|
||||
update_xrender_clipping( dev, rgn );
|
||||
DeleteObject( rgn );
|
||||
}
|
||||
else update_xrender_clipping( dev, clip_rgn );
|
||||
}
|
||||
else if (dev->update_clip) update_xrender_clipping( dev, dev->x11dev->region );
|
||||
|
||||
dev->update_clip = (clip_rect || clip_rgn); /* have to update again if we are using a custom region */
|
||||
return dev->pict;
|
||||
}
|
||||
|
||||
@ -2288,7 +2307,7 @@ static DWORD xrenderdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMA
|
||||
|
||||
if (rop != SRCCOPY)
|
||||
{
|
||||
RGNDATA *clip_data = NULL;
|
||||
BOOL restore_region = add_extra_clipping_region( physdev->x11dev, clip );
|
||||
|
||||
/* make coordinates relative to tmp pixmap */
|
||||
tmp = *dst;
|
||||
@ -2296,8 +2315,6 @@ static DWORD xrenderdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMA
|
||||
tmp.y -= tmp.visrect.top;
|
||||
OffsetRect( &tmp.visrect, -tmp.visrect.left, -tmp.visrect.top );
|
||||
|
||||
if (clip) clip_data = add_extra_clipping_region( physdev->x11dev, clip );
|
||||
|
||||
wine_tsx11_lock();
|
||||
gc = XCreateGC( gdi_display, physdev->x11dev->drawable, 0, NULL );
|
||||
XSetSubwindowMode( gdi_display, gc, IncludeInferiors );
|
||||
@ -2315,7 +2332,7 @@ static DWORD xrenderdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMA
|
||||
XFreeGC( gdi_display, gc );
|
||||
wine_tsx11_unlock();
|
||||
|
||||
restore_clipping_region( physdev->x11dev, clip_data );
|
||||
if (restore_region) restore_clipping_region( physdev->x11dev );
|
||||
}
|
||||
else xrender_put_image( src_pixmap, src_pict, mask_pict, clip,
|
||||
physdev->pict_format, physdev, 0, src, dst, use_repeat );
|
||||
|
Loading…
Reference in New Issue
Block a user