Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xnest / GC.c
1 /*
2
3 Copyright 1993 by Davor Matic
4
5 Permission to use, copy, modify, distribute, and sell this software
6 and its documentation for any purpose is hereby granted without fee,
7 provided that the above copyright notice appear in all copies and that
8 both that copyright notice and this permission notice appear in
9 supporting documentation. Davor Matic makes no representations about
10 the suitability of this software for any purpose. It is provided "as
11 is" 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
38 DevPrivateKeyRec xnestGCPrivateKeyRec;
39
40 static GCFuncs xnestFuncs = {
41 xnestValidateGC,
42 xnestChangeGC,
43 xnestCopyGC,
44 xnestDestroyGC,
45 xnestChangeClip,
46 xnestDestroyClip,
47 xnestCopyClip,
48 };
49
50 static 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
73 Bool
74 xnestCreateGC(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
88 void
89 xnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
90 {
91 }
92
93 void
94 xnestChangeGC(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
178 void
179 xnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
180 {
181 XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst));
182 }
183
184 void
185 xnestDestroyGC(GCPtr pGC)
186 {
187 XFreeGC(xnestDisplay, xnestGC(pGC));
188 }
189
190 void
191 xnestChangeClip(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
286 void
287 xnestDestroyClip(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
297 void
298 xnestDestroyClipHelper(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
311 void
312 xnestCopyClip(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 }