Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xnest / GC.c
CommitLineData
a09e091a
JB
1/*
2
3Copyright 1993 by Davor Matic
4
5Permission to use, copy, modify, distribute, and sell this software
6and its documentation for any purpose is hereby granted without fee,
7provided that the above copyright notice appear in all copies and that
8both that copyright notice and this permission notice appear in
9supporting documentation. Davor Matic makes no representations about
10the suitability of this software for any purpose. It is provided "as
11is" without express or implied warranty.
12
13*/
14
15#ifdef HAVE_XNEST_CONFIG_H
16#include <xnest-config.h>
17#endif
18
19#include <X11/X.h>
20#include <X11/Xproto.h>
21#include "gcstruct.h"
22#include "windowstr.h"
23#include "pixmapstr.h"
24#include "scrnintstr.h"
25#include <X11/fonts/fontstruct.h>
26#include "mistruct.h"
27#include "region.h"
28
29#include "Xnest.h"
30
31#include "Display.h"
32#include "XNGC.h"
33#include "GCOps.h"
34#include "Drawable.h"
35#include "XNFont.h"
36#include "Color.h"
37
38DevPrivateKeyRec xnestGCPrivateKeyRec;
39
40static GCFuncs xnestFuncs = {
41 xnestValidateGC,
42 xnestChangeGC,
43 xnestCopyGC,
44 xnestDestroyGC,
45 xnestChangeClip,
46 xnestDestroyClip,
47 xnestCopyClip,
48};
49
50static GCOps xnestOps = {
51 xnestFillSpans,
52 xnestSetSpans,
53 xnestPutImage,
54 xnestCopyArea,
55 xnestCopyPlane,
56 xnestPolyPoint,
57 xnestPolylines,
58 xnestPolySegment,
59 xnestPolyRectangle,
60 xnestPolyArc,
61 xnestFillPolygon,
62 xnestPolyFillRect,
63 xnestPolyFillArc,
64 xnestPolyText8,
65 xnestPolyText16,
66 xnestImageText8,
67 xnestImageText16,
68 xnestImageGlyphBlt,
69 xnestPolyGlyphBlt,
70 xnestPushPixels
71};
72
73Bool
74xnestCreateGC(GCPtr pGC)
75{
76 pGC->funcs = &xnestFuncs;
77 pGC->ops = &xnestOps;
78
79 pGC->miTranslate = 1;
80
81 xnestGCPriv(pGC)->gc = XCreateGC(xnestDisplay,
82 xnestDefaultDrawables[pGC->depth],
83 0L, NULL);
84
85 return True;
86}
87
88void
89xnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
90{
91}
92
93void
94xnestChangeGC(GCPtr pGC, unsigned long mask)
95{
96 XGCValues values;
97
98 if (mask & GCFunction)
99 values.function = pGC->alu;
100
101 if (mask & GCPlaneMask)
102 values.plane_mask = pGC->planemask;
103
104 if (mask & GCForeground)
105 values.foreground = xnestPixel(pGC->fgPixel);
106
107 if (mask & GCBackground)
108 values.background = xnestPixel(pGC->bgPixel);
109
110 if (mask & GCLineWidth)
111 values.line_width = pGC->lineWidth;
112
113 if (mask & GCLineStyle)
114 values.line_style = pGC->lineStyle;
115
116 if (mask & GCCapStyle)
117 values.cap_style = pGC->capStyle;
118
119 if (mask & GCJoinStyle)
120 values.join_style = pGC->joinStyle;
121
122 if (mask & GCFillStyle)
123 values.fill_style = pGC->fillStyle;
124
125 if (mask & GCFillRule)
126 values.fill_rule = pGC->fillRule;
127
128 if (mask & GCTile) {
129 if (pGC->tileIsPixel)
130 mask &= ~GCTile;
131 else
132 values.tile = xnestPixmap(pGC->tile.pixmap);
133 }
134
135 if (mask & GCStipple)
136 values.stipple = xnestPixmap(pGC->stipple);
137
138 if (mask & GCTileStipXOrigin)
139 values.ts_x_origin = pGC->patOrg.x;
140
141 if (mask & GCTileStipYOrigin)
142 values.ts_y_origin = pGC->patOrg.y;
143
144 if (mask & GCFont)
145 values.font = xnestFont(pGC->font);
146
147 if (mask & GCSubwindowMode)
148 values.subwindow_mode = pGC->subWindowMode;
149
150 if (mask & GCGraphicsExposures)
151 values.graphics_exposures = pGC->graphicsExposures;
152
153 if (mask & GCClipXOrigin)
154 values.clip_x_origin = pGC->clipOrg.x;
155
156 if (mask & GCClipYOrigin)
157 values.clip_y_origin = pGC->clipOrg.y;
158
159 if (mask & GCClipMask) /* this is handled in change clip */
160 mask &= ~GCClipMask;
161
162 if (mask & GCDashOffset)
163 values.dash_offset = pGC->dashOffset;
164
165 if (mask & GCDashList) {
166 mask &= ~GCDashList;
167 XSetDashes(xnestDisplay, xnestGC(pGC),
168 pGC->dashOffset, (char *) pGC->dash, pGC->numInDashList);
169 }
170
171 if (mask & GCArcMode)
172 values.arc_mode = pGC->arcMode;
173
174 if (mask)
175 XChangeGC(xnestDisplay, xnestGC(pGC), mask, &values);
176}
177
178void
179xnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
180{
181 XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst));
182}
183
184void
185xnestDestroyGC(GCPtr pGC)
186{
187 XFreeGC(xnestDisplay, xnestGC(pGC));
188}
189
190void
191xnestChangeClip(GCPtr pGC, int type, pointer pValue, int nRects)
192{
193 int i, size;
194 BoxPtr pBox;
195 XRectangle *pRects;
196
197 xnestDestroyClipHelper(pGC);
198
199 switch (type) {
200 case CT_NONE:
201 XSetClipMask(xnestDisplay, xnestGC(pGC), None);
202 break;
203
204 case CT_REGION:
205 nRects = RegionNumRects((RegionPtr) pValue);
206 size = nRects * sizeof(*pRects);
207 pRects = (XRectangle *) malloc(size);
208 pBox = RegionRects((RegionPtr) pValue);
209 for (i = nRects; i-- > 0;) {
210 pRects[i].x = pBox[i].x1;
211 pRects[i].y = pBox[i].y1;
212 pRects[i].width = pBox[i].x2 - pBox[i].x1;
213 pRects[i].height = pBox[i].y2 - pBox[i].y1;
214 }
215 XSetClipRectangles(xnestDisplay, xnestGC(pGC), 0, 0,
216 pRects, nRects, Unsorted);
217 free((char *) pRects);
218 break;
219
220 case CT_PIXMAP:
221 XSetClipMask(xnestDisplay, xnestGC(pGC),
222 xnestPixmap((PixmapPtr) pValue));
223 /*
224 * Need to change into region, so subsequent uses are with
225 * current pixmap contents.
226 */
227 pGC->clientClip =
228 (pointer) (*pGC->pScreen->BitmapToRegion) ((PixmapPtr) pValue);
229 (*pGC->pScreen->DestroyPixmap) ((PixmapPtr) pValue);
230 pValue = pGC->clientClip;
231 type = CT_REGION;
232 break;
233
234 case CT_UNSORTED:
235 XSetClipRectangles(xnestDisplay, xnestGC(pGC),
236 pGC->clipOrg.x, pGC->clipOrg.y,
237 (XRectangle *) pValue, nRects, Unsorted);
238 break;
239
240 case CT_YSORTED:
241 XSetClipRectangles(xnestDisplay, xnestGC(pGC),
242 pGC->clipOrg.x, pGC->clipOrg.y,
243 (XRectangle *) pValue, nRects, YSorted);
244 break;
245
246 case CT_YXSORTED:
247 XSetClipRectangles(xnestDisplay, xnestGC(pGC),
248 pGC->clipOrg.x, pGC->clipOrg.y,
249 (XRectangle *) pValue, nRects, YXSorted);
250 break;
251
252 case CT_YXBANDED:
253 XSetClipRectangles(xnestDisplay, xnestGC(pGC),
254 pGC->clipOrg.x, pGC->clipOrg.y,
255 (XRectangle *) pValue, nRects, YXBanded);
256 break;
257 }
258
259 switch (type) {
260 default:
261 break;
262
263 case CT_UNSORTED:
264 case CT_YSORTED:
265 case CT_YXSORTED:
266 case CT_YXBANDED:
267
268 /*
269 * other parts of server can only deal with CT_NONE,
270 * CT_PIXMAP and CT_REGION client clips.
271 */
272 pGC->clientClip = (pointer) RegionFromRects(nRects,
273 (xRectangle *) pValue,
274 type);
275 free(pValue);
276 pValue = pGC->clientClip;
277 type = CT_REGION;
278
279 break;
280 }
281
282 pGC->clientClipType = type;
283 pGC->clientClip = pValue;
284}
285
286void
287xnestDestroyClip(GCPtr pGC)
288{
289 xnestDestroyClipHelper(pGC);
290
291 XSetClipMask(xnestDisplay, xnestGC(pGC), None);
292
293 pGC->clientClipType = CT_NONE;
294 pGC->clientClip = NULL;
295}
296
297void
298xnestDestroyClipHelper(GCPtr pGC)
299{
300 switch (pGC->clientClipType) {
301 default:
302 case CT_NONE:
303 break;
304
305 case CT_REGION:
306 RegionDestroy(pGC->clientClip);
307 break;
308 }
309}
310
311void
312xnestCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
313{
314 RegionPtr pRgn;
315
316 switch (pGCSrc->clientClipType) {
317 default:
318 case CT_NONE:
319 xnestDestroyClip(pGCDst);
320 break;
321
322 case CT_REGION:
323 pRgn = RegionCreate(NULL, 1);
324 RegionCopy(pRgn, pGCSrc->clientClip);
325 xnestChangeClip(pGCDst, CT_REGION, pRgn, 0);
326 break;
327 }
328}