Removed some direct accesses to the DC structure.
[wine/multimedia.git] / graphics / x11drv / clipping.c
blobedd0987c7fcc01a8dfff4137272829101ea31f7b
1 /*
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
21 #include "config.h"
23 #include "ts_xlib.h"
25 #include <stdio.h>
27 #include "gdi.h"
28 #include "x11drv.h"
29 #include "region.h"
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 )
43 XRectangle *pXrect;
45 RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(hrgn, REGION_MAGIC);
46 if (!obj)
48 ERR("Rgn is 0. Please report this.\n");
49 return;
52 if (obj->rgn->numRects > 0)
54 XRectangle *pXr;
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 );
60 if(!pXrect)
62 WARN("Can't alloc buffer\n");
63 GDI_ReleaseObj( hrgn );
64 return;
67 for(pXr = pXrect; pRect < pEndRect; pRect++, pXr++)
69 pXr->x = pRect->left;
70 pXr->y = pRect->top;
71 pXr->width = pRect->right - pRect->left;
72 pXr->height = pRect->bottom - pRect->top;
75 else
76 pXrect = NULL;
78 TSXSetClipRectangles( gdi_display, physDev->gc, 0, 0,
79 pXrect, obj->rgn->numRects, YXBanded );
81 if(pXrect)
82 HeapFree( GetProcessHeap(), 0, pXrect );
84 GDI_ReleaseObj( hrgn );
88 /***********************************************************************
89 * X11DRV_SetDrawable
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 );
96 if (dc)
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 );
111 dc->DCOrgX = org_x;
112 dc->DCOrgY = org_y;
113 physDev->drawable = drawable;
114 TSXSetSubwindowMode( gdi_display, physDev->gc, mode );
115 if(physDev->xrender)
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 );
130 if (dc)
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 )
147 HRGN tmp = 0;
148 DC *dc = DC_GetDCPtr( hdc );
150 if (dc)
152 XEvent event;
153 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
155 SetRectRgn( hrgn, 0, 0, 0, 0 );
156 wine_tsx11_lock();
157 XSetGraphicsExposures( gdi_display, physDev->gc, False );
158 if (physDev->exposures)
160 XSync( gdi_display, False );
161 for (;;)
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;
181 else
183 ERR( "got unexpected event %d\n", event.type );
184 break;
186 if (tmp) DeleteObject( tmp );
189 wine_tsx11_unlock();
190 GDI_ReleaseObj( hdc );