2 * X11DRV clipping functions
4 * Copyright 1998 Huw Davies
16 #include "debugtools.h"
19 DEFAULT_DEBUG_CHANNEL(x11drv);
21 /***********************************************************************
22 * X11DRV_SetDeviceClipping
23 * Copy RECT32s to a temporary buffer of XRectangles and call
24 * TSXSetClipRectangles().
26 * Could write using GetRegionData but this would be slower.
28 void X11DRV_SetDeviceClipping( DC * dc )
31 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
33 RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(dc->hGCClipRgn, REGION_MAGIC);
36 ERR("Rgn is 0. Please report this.\n");
40 if (obj->rgn->numRects > 0)
43 RECT *pRect = obj->rgn->rects;
44 RECT *pEndRect = obj->rgn->rects + obj->rgn->numRects;
46 pXrect = HeapAlloc( GetProcessHeap(), 0,
47 sizeof(*pXrect) * obj->rgn->numRects );
50 WARN("Can't alloc buffer\n");
51 GDI_ReleaseObj( dc->hGCClipRgn );
55 for(pXr = pXrect; pRect < pEndRect; pRect++, pXr++)
59 pXr->width = pRect->right - pRect->left;
60 pXr->height = pRect->bottom - pRect->top;
66 TSXSetClipRectangles( gdi_display, physDev->gc, 0, 0,
67 pXrect, obj->rgn->numRects, YXBanded );
70 HeapFree( GetProcessHeap(), 0, pXrect );
72 GDI_ReleaseObj( dc->hGCClipRgn );
76 /***********************************************************************
79 * Set the drawable, clipping mode and origin for a DC.
81 void X11DRV_SetDrawable( HDC hdc, Drawable drawable, int mode, int org_x, int org_y )
83 DC *dc = DC_GetDCPtr( hdc );
86 X11DRV_PDEVICE *physDev = dc->physDev;
88 * This function change the coordinate system (DCOrgX,DCOrgY)
89 * values. When it moves the origin, other data like the current clipping
90 * region will not be moved to that new origin. In the case of DCs that are class
91 * or window DCs that clipping region might be a valid value from a previous use
92 * of the DC and changing the origin of the DC without moving the clip region
93 * results in a clip region that is not placed properly in the DC.
94 * This code will save the dc origin, let the SetDrawable
95 * modify the origin and reset the clipping. When the clipping is set,
96 * it is moved according to the new DC origin.
98 if (dc->hClipRgn) OffsetRgn( dc->hClipRgn, org_x - dc->DCOrgX, org_y - dc->DCOrgY );
101 physDev->drawable = drawable;
102 TSXSetSubwindowMode( gdi_display, physDev->gc, mode );
103 GDI_ReleaseObj( hdc );
108 /***********************************************************************
109 * X11DRV_StartGraphicsExposures
111 * Set the DC in graphics exposures mode
113 void X11DRV_StartGraphicsExposures( HDC hdc )
115 DC *dc = DC_GetDCPtr( hdc );
118 X11DRV_PDEVICE *physDev = dc->physDev;
119 TSXSetGraphicsExposures( gdi_display, physDev->gc, True );
120 physDev->exposures = 0;
121 GDI_ReleaseObj( hdc );
126 /***********************************************************************
127 * X11DRV_EndGraphicsExposures
129 * End the graphics exposures mode and process the events
131 void X11DRV_EndGraphicsExposures( HDC hdc, HRGN hrgn )
134 DC *dc = DC_GetDCPtr( hdc );
139 X11DRV_PDEVICE *physDev = dc->physDev;
141 SetRectRgn( hrgn, 0, 0, 0, 0 );
143 XSetGraphicsExposures( gdi_display, physDev->gc, False );
144 if (physDev->exposures)
146 XSync( gdi_display, False );
149 XWindowEvent( gdi_display, physDev->drawable, ~0, &event );
150 if (event.type == NoExpose) break;
151 if (event.type == GraphicsExpose)
153 int x = event.xgraphicsexpose.x - dc->DCOrgX;
154 int y = event.xgraphicsexpose.y - dc->DCOrgY;
156 TRACE( "got %d,%d %dx%d count %d\n",
157 x, y, event.xgraphicsexpose.width, event.xgraphicsexpose.height,
158 event.xgraphicsexpose.count );
160 if (!tmp) tmp = CreateRectRgn( 0, 0, 0, 0 );
161 SetRectRgn( tmp, x, y,
162 x + event.xgraphicsexpose.width,
163 y + event.xgraphicsexpose.height );
164 CombineRgn( hrgn, hrgn, tmp, RGN_OR );
165 if (!event.xgraphicsexpose.count) break;
169 ERR( "got unexpected event %d\n", event.type );
172 if (tmp) DeleteObject( tmp );
176 GDI_ReleaseObj( hdc );