2 * X11DRV clipping functions
4 * Copyright 1998 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(x11drv
);
34 /***********************************************************************
35 * X11DRV_SetDeviceClipping
36 * Copy RECT32s to a temporary buffer of XRectangles and call
37 * TSXSetClipRectangles().
39 * Could write using GetRegionData but this would be slower.
41 void X11DRV_SetDeviceClipping( X11DRV_PDEVICE
*physDev
, HRGN hrgn
)
45 RGNOBJ
*obj
= (RGNOBJ
*) GDI_GetObjPtr(hrgn
, REGION_MAGIC
);
48 ERR("Rgn is 0. Please report this.\n");
52 if (obj
->rgn
->numRects
> 0)
55 RECT
*pRect
= obj
->rgn
->rects
;
56 RECT
*pEndRect
= obj
->rgn
->rects
+ obj
->rgn
->numRects
;
58 pXrect
= HeapAlloc( GetProcessHeap(), 0,
59 sizeof(*pXrect
) * obj
->rgn
->numRects
);
62 WARN("Can't alloc buffer\n");
63 GDI_ReleaseObj( hrgn
);
67 for(pXr
= pXrect
; pRect
< pEndRect
; pRect
++, pXr
++)
71 pXr
->width
= pRect
->right
- pRect
->left
;
72 pXr
->height
= pRect
->bottom
- pRect
->top
;
78 TSXSetClipRectangles( gdi_display
, physDev
->gc
, 0, 0,
79 pXrect
, obj
->rgn
->numRects
, YXBanded
);
82 HeapFree( GetProcessHeap(), 0, pXrect
);
84 GDI_ReleaseObj( hrgn
);
88 /***********************************************************************
91 * Set the drawable, clipping mode and origin for a DC.
93 void X11DRV_SetDrawable( HDC hdc
, Drawable drawable
, int mode
, int org_x
, int org_y
)
95 DC
*dc
= DC_GetDCPtr( hdc
);
98 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
100 * This function change the coordinate system (DCOrgX,DCOrgY)
101 * values. When it moves the origin, other data like the current clipping
102 * region will not be moved to that new origin. In the case of DCs that are class
103 * or window DCs that clipping region might be a valid value from a previous use
104 * of the DC and changing the origin of the DC without moving the clip region
105 * results in a clip region that is not placed properly in the DC.
106 * This code will save the dc origin, let the SetDrawable
107 * modify the origin and reset the clipping. When the clipping is set,
108 * it is moved according to the new DC origin.
110 if (dc
->hClipRgn
) OffsetRgn( dc
->hClipRgn
, org_x
- dc
->DCOrgX
, org_y
- dc
->DCOrgY
);
113 physDev
->drawable
= drawable
;
114 TSXSetSubwindowMode( gdi_display
, physDev
->gc
, mode
);
116 X11DRV_XRender_UpdateDrawable( physDev
);
117 GDI_ReleaseObj( hdc
);
122 /***********************************************************************
123 * X11DRV_StartGraphicsExposures
125 * Set the DC in graphics exposures mode
127 void X11DRV_StartGraphicsExposures( HDC hdc
)
129 DC
*dc
= DC_GetDCPtr( hdc
);
132 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
133 TSXSetGraphicsExposures( gdi_display
, physDev
->gc
, True
);
134 physDev
->exposures
= 0;
135 GDI_ReleaseObj( hdc
);
140 /***********************************************************************
141 * X11DRV_EndGraphicsExposures
143 * End the graphics exposures mode and process the events
145 void X11DRV_EndGraphicsExposures( HDC hdc
, HRGN hrgn
)
148 DC
*dc
= DC_GetDCPtr( hdc
);
153 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
155 SetRectRgn( hrgn
, 0, 0, 0, 0 );
157 XSetGraphicsExposures( gdi_display
, physDev
->gc
, False
);
158 if (physDev
->exposures
)
160 XSync( gdi_display
, False
);
163 XWindowEvent( gdi_display
, physDev
->drawable
, ~0, &event
);
164 if (event
.type
== NoExpose
) break;
165 if (event
.type
== GraphicsExpose
)
167 int x
= event
.xgraphicsexpose
.x
- dc
->DCOrgX
;
168 int y
= event
.xgraphicsexpose
.y
- dc
->DCOrgY
;
170 TRACE( "got %d,%d %dx%d count %d\n",
171 x
, y
, event
.xgraphicsexpose
.width
, event
.xgraphicsexpose
.height
,
172 event
.xgraphicsexpose
.count
);
174 if (!tmp
) tmp
= CreateRectRgn( 0, 0, 0, 0 );
175 SetRectRgn( tmp
, x
, y
,
176 x
+ event
.xgraphicsexpose
.width
,
177 y
+ event
.xgraphicsexpose
.height
);
178 CombineRgn( hrgn
, hrgn
, tmp
, RGN_OR
);
179 if (!event
.xgraphicsexpose
.count
) break;
183 ERR( "got unexpected event %d\n", event
.type
);
186 if (tmp
) DeleteObject( tmp
);
190 GDI_ReleaseObj( hdc
);