2 * X11DRV clipping functions
4 * Copyright 1998 Huw Davies
16 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(x11drv
);
20 /***********************************************************************
21 * X11DRV_SetDeviceClipping
22 * Copy RECT32s to a temporary buffer of XRectangles and call
23 * TSXSetClipRectangles().
25 * Could write using GetRegionData but this would be slower.
27 void X11DRV_SetDeviceClipping( DC
* dc
)
30 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
32 RGNOBJ
*obj
= (RGNOBJ
*) GDI_GetObjPtr(dc
->hGCClipRgn
, REGION_MAGIC
);
35 ERR("Rgn is 0. Please report this.\n");
39 if (obj
->rgn
->numRects
> 0)
42 RECT
*pRect
= obj
->rgn
->rects
;
43 RECT
*pEndRect
= obj
->rgn
->rects
+ obj
->rgn
->numRects
;
45 pXrect
= HeapAlloc( GetProcessHeap(), 0,
46 sizeof(*pXrect
) * obj
->rgn
->numRects
);
49 WARN("Can't alloc buffer\n");
50 GDI_ReleaseObj( dc
->hGCClipRgn
);
54 for(pXr
= pXrect
; pRect
< pEndRect
; pRect
++, pXr
++)
58 pXr
->width
= pRect
->right
- pRect
->left
;
59 pXr
->height
= pRect
->bottom
- pRect
->top
;
65 TSXSetClipRectangles( gdi_display
, physDev
->gc
, 0, 0,
66 pXrect
, obj
->rgn
->numRects
, YXBanded
);
69 HeapFree( GetProcessHeap(), 0, pXrect
);
71 GDI_ReleaseObj( dc
->hGCClipRgn
);
75 /***********************************************************************
78 * Set the drawable, clipping mode and origin for a DC.
80 void X11DRV_SetDrawable( HDC hdc
, Drawable drawable
, int mode
, int org_x
, int org_y
)
82 DC
*dc
= DC_GetDCPtr( hdc
);
85 X11DRV_PDEVICE
*physDev
= dc
->physDev
;
87 * This function change the coordinate system (DCOrgX,DCOrgY)
88 * values. When it moves the origin, other data like the current clipping
89 * region will not be moved to that new origin. In the case of DCs that are class
90 * or window DCs that clipping region might be a valid value from a previous use
91 * of the DC and changing the origin of the DC without moving the clip region
92 * results in a clip region that is not placed properly in the DC.
93 * This code will save the dc origin, let the SetDrawable
94 * modify the origin and reset the clipping. When the clipping is set,
95 * it is moved according to the new DC origin.
97 if (dc
->hClipRgn
) OffsetRgn( dc
->hClipRgn
, org_x
- dc
->DCOrgX
, org_y
- dc
->DCOrgY
);
100 physDev
->drawable
= drawable
;
101 TSXSetSubwindowMode( gdi_display
, physDev
->gc
, mode
);
103 X11DRV_XRender_UpdateDrawable(dc
);
104 GDI_ReleaseObj( hdc
);
109 /***********************************************************************
110 * X11DRV_StartGraphicsExposures
112 * Set the DC in graphics exposures mode
114 void X11DRV_StartGraphicsExposures( HDC hdc
)
116 DC
*dc
= DC_GetDCPtr( hdc
);
119 X11DRV_PDEVICE
*physDev
= dc
->physDev
;
120 TSXSetGraphicsExposures( gdi_display
, physDev
->gc
, True
);
121 physDev
->exposures
= 0;
122 GDI_ReleaseObj( hdc
);
127 /***********************************************************************
128 * X11DRV_EndGraphicsExposures
130 * End the graphics exposures mode and process the events
132 void X11DRV_EndGraphicsExposures( HDC hdc
, HRGN hrgn
)
135 DC
*dc
= DC_GetDCPtr( hdc
);
140 X11DRV_PDEVICE
*physDev
= dc
->physDev
;
142 SetRectRgn( hrgn
, 0, 0, 0, 0 );
144 XSetGraphicsExposures( gdi_display
, physDev
->gc
, False
);
145 if (physDev
->exposures
)
147 XSync( gdi_display
, False
);
150 XWindowEvent( gdi_display
, physDev
->drawable
, ~0, &event
);
151 if (event
.type
== NoExpose
) break;
152 if (event
.type
== GraphicsExpose
)
154 int x
= event
.xgraphicsexpose
.x
- dc
->DCOrgX
;
155 int y
= event
.xgraphicsexpose
.y
- dc
->DCOrgY
;
157 TRACE( "got %d,%d %dx%d count %d\n",
158 x
, y
, event
.xgraphicsexpose
.width
, event
.xgraphicsexpose
.height
,
159 event
.xgraphicsexpose
.count
);
161 if (!tmp
) tmp
= CreateRectRgn( 0, 0, 0, 0 );
162 SetRectRgn( tmp
, x
, y
,
163 x
+ event
.xgraphicsexpose
.width
,
164 y
+ event
.xgraphicsexpose
.height
);
165 CombineRgn( hrgn
, hrgn
, tmp
, RGN_OR
);
166 if (!event
.xgraphicsexpose
.count
) break;
170 ERR( "got unexpected event %d\n", event
.type
);
173 if (tmp
) DeleteObject( tmp
);
177 GDI_ReleaseObj( hdc
);