GC.c revision 706f2543
1706f2543Smrg/*
2706f2543Smrg
3706f2543SmrgCopyright 1993 by Davor Matic
4706f2543Smrg
5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software
6706f2543Smrgand its documentation for any purpose is hereby granted without fee,
7706f2543Smrgprovided that the above copyright notice appear in all copies and that
8706f2543Smrgboth that copyright notice and this permission notice appear in
9706f2543Smrgsupporting documentation.  Davor Matic makes no representations about
10706f2543Smrgthe suitability of this software for any purpose.  It is provided "as
11706f2543Smrgis" without express or implied warranty.
12706f2543Smrg
13706f2543Smrg*/
14706f2543Smrg
15706f2543Smrg#ifdef HAVE_XNEST_CONFIG_H
16706f2543Smrg#include <xnest-config.h>
17706f2543Smrg#endif
18706f2543Smrg
19706f2543Smrg#include <X11/X.h>
20706f2543Smrg#include <X11/Xproto.h>
21706f2543Smrg#include "gcstruct.h"
22706f2543Smrg#include "windowstr.h"
23706f2543Smrg#include "pixmapstr.h"
24706f2543Smrg#include "scrnintstr.h"
25706f2543Smrg#include <X11/fonts/fontstruct.h>
26706f2543Smrg#include "mistruct.h"
27706f2543Smrg#include "region.h"
28706f2543Smrg
29706f2543Smrg#include "Xnest.h"
30706f2543Smrg
31706f2543Smrg#include "Display.h"
32706f2543Smrg#include "XNGC.h"
33706f2543Smrg#include "GCOps.h"
34706f2543Smrg#include "Drawable.h"
35706f2543Smrg#include "XNFont.h"
36706f2543Smrg#include "Color.h"
37706f2543Smrg
38706f2543SmrgDevPrivateKeyRec xnestGCPrivateKeyRec;
39706f2543Smrg
40706f2543Smrgstatic GCFuncs xnestFuncs = {
41706f2543Smrg  xnestValidateGC,
42706f2543Smrg  xnestChangeGC,
43706f2543Smrg  xnestCopyGC,
44706f2543Smrg  xnestDestroyGC,
45706f2543Smrg  xnestChangeClip,
46706f2543Smrg  xnestDestroyClip,
47706f2543Smrg  xnestCopyClip,
48706f2543Smrg};
49706f2543Smrg
50706f2543Smrgstatic GCOps xnestOps = {
51706f2543Smrg  xnestFillSpans,
52706f2543Smrg  xnestSetSpans,
53706f2543Smrg  xnestPutImage,
54706f2543Smrg  xnestCopyArea,
55706f2543Smrg  xnestCopyPlane,
56706f2543Smrg  xnestPolyPoint,
57706f2543Smrg  xnestPolylines,
58706f2543Smrg  xnestPolySegment,
59706f2543Smrg  xnestPolyRectangle,
60706f2543Smrg  xnestPolyArc,
61706f2543Smrg  xnestFillPolygon,
62706f2543Smrg  xnestPolyFillRect,
63706f2543Smrg  xnestPolyFillArc,
64706f2543Smrg  xnestPolyText8,
65706f2543Smrg  xnestPolyText16,
66706f2543Smrg  xnestImageText8,
67706f2543Smrg  xnestImageText16,
68706f2543Smrg  xnestImageGlyphBlt,
69706f2543Smrg  xnestPolyGlyphBlt,
70706f2543Smrg  xnestPushPixels
71706f2543Smrg};
72706f2543Smrg
73706f2543SmrgBool
74706f2543SmrgxnestCreateGC(GCPtr pGC)
75706f2543Smrg{
76706f2543Smrg  pGC->funcs = &xnestFuncs;
77706f2543Smrg  pGC->ops = &xnestOps;
78706f2543Smrg
79706f2543Smrg  pGC->miTranslate = 1;
80706f2543Smrg
81706f2543Smrg  xnestGCPriv(pGC)->gc = XCreateGC(xnestDisplay,
82706f2543Smrg				   xnestDefaultDrawables[pGC->depth],
83706f2543Smrg				   0L, NULL);
84706f2543Smrg  xnestGCPriv(pGC)->nClipRects = 0;
85706f2543Smrg
86706f2543Smrg  return True;
87706f2543Smrg}
88706f2543Smrg
89706f2543Smrgvoid
90706f2543SmrgxnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
91706f2543Smrg{
92706f2543Smrg}
93706f2543Smrg
94706f2543Smrgvoid
95706f2543SmrgxnestChangeGC(GCPtr pGC, unsigned long mask)
96706f2543Smrg{
97706f2543Smrg  XGCValues values;
98706f2543Smrg
99706f2543Smrg  if (mask & GCFunction)
100706f2543Smrg    values.function = pGC->alu;
101706f2543Smrg
102706f2543Smrg  if (mask & GCPlaneMask)
103706f2543Smrg    values.plane_mask = pGC->planemask;
104706f2543Smrg
105706f2543Smrg  if (mask & GCForeground)
106706f2543Smrg    values.foreground = xnestPixel(pGC->fgPixel);
107706f2543Smrg
108706f2543Smrg  if (mask & GCBackground)
109706f2543Smrg    values.background = xnestPixel(pGC->bgPixel);
110706f2543Smrg
111706f2543Smrg  if (mask & GCLineWidth)
112706f2543Smrg    values.line_width = pGC->lineWidth;
113706f2543Smrg
114706f2543Smrg  if (mask & GCLineStyle)
115706f2543Smrg    values.line_style = pGC->lineStyle;
116706f2543Smrg
117706f2543Smrg  if (mask & GCCapStyle)
118706f2543Smrg    values.cap_style = pGC->capStyle;
119706f2543Smrg
120706f2543Smrg  if (mask & GCJoinStyle)
121706f2543Smrg    values.join_style = pGC->joinStyle;
122706f2543Smrg
123706f2543Smrg  if (mask & GCFillStyle)
124706f2543Smrg    values.fill_style = pGC->fillStyle;
125706f2543Smrg
126706f2543Smrg  if (mask & GCFillRule)
127706f2543Smrg    values.fill_rule = pGC->fillRule;
128706f2543Smrg
129706f2543Smrg  if (mask & GCTile) {
130706f2543Smrg    if (pGC->tileIsPixel)
131706f2543Smrg      mask &= ~GCTile;
132706f2543Smrg    else
133706f2543Smrg      values.tile = xnestPixmap(pGC->tile.pixmap);
134706f2543Smrg  }
135706f2543Smrg
136706f2543Smrg  if (mask & GCStipple)
137706f2543Smrg    values.stipple = xnestPixmap(pGC->stipple);
138706f2543Smrg
139706f2543Smrg  if (mask & GCTileStipXOrigin)
140706f2543Smrg    values.ts_x_origin = pGC->patOrg.x;
141706f2543Smrg
142706f2543Smrg  if (mask & GCTileStipYOrigin)
143706f2543Smrg    values.ts_y_origin = pGC->patOrg.y;
144706f2543Smrg
145706f2543Smrg  if (mask & GCFont)
146706f2543Smrg    values.font = xnestFont(pGC->font);
147706f2543Smrg
148706f2543Smrg  if (mask & GCSubwindowMode)
149706f2543Smrg    values.subwindow_mode = pGC->subWindowMode;
150706f2543Smrg
151706f2543Smrg  if (mask & GCGraphicsExposures)
152706f2543Smrg    values.graphics_exposures = pGC->graphicsExposures;
153706f2543Smrg
154706f2543Smrg  if (mask & GCClipXOrigin)
155706f2543Smrg    values.clip_x_origin = pGC->clipOrg.x;
156706f2543Smrg
157706f2543Smrg  if (mask & GCClipYOrigin)
158706f2543Smrg    values.clip_y_origin = pGC->clipOrg.y;
159706f2543Smrg
160706f2543Smrg  if (mask & GCClipMask) /* this is handled in change clip */
161706f2543Smrg    mask &= ~GCClipMask;
162706f2543Smrg
163706f2543Smrg  if (mask & GCDashOffset)
164706f2543Smrg    values.dash_offset = pGC->dashOffset;
165706f2543Smrg
166706f2543Smrg  if (mask & GCDashList) {
167706f2543Smrg    mask &= ~GCDashList;
168706f2543Smrg    XSetDashes(xnestDisplay, xnestGC(pGC),
169706f2543Smrg	       pGC->dashOffset, (char *)pGC->dash, pGC->numInDashList);
170706f2543Smrg  }
171706f2543Smrg
172706f2543Smrg  if (mask & GCArcMode)
173706f2543Smrg    values.arc_mode = pGC->arcMode;
174706f2543Smrg
175706f2543Smrg  if (mask)
176706f2543Smrg    XChangeGC(xnestDisplay, xnestGC(pGC), mask, &values);
177706f2543Smrg}
178706f2543Smrg
179706f2543Smrgvoid
180706f2543SmrgxnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
181706f2543Smrg{
182706f2543Smrg  XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst));
183706f2543Smrg}
184706f2543Smrg
185706f2543Smrgvoid
186706f2543SmrgxnestDestroyGC(GCPtr pGC)
187706f2543Smrg{
188706f2543Smrg  XFreeGC(xnestDisplay, xnestGC(pGC));
189706f2543Smrg}
190706f2543Smrg
191706f2543Smrgvoid
192706f2543SmrgxnestChangeClip(GCPtr pGC, int type, pointer pValue, int nRects)
193706f2543Smrg{
194706f2543Smrg  int i, size;
195706f2543Smrg  BoxPtr pBox;
196706f2543Smrg  XRectangle *pRects;
197706f2543Smrg
198706f2543Smrg  xnestDestroyClipHelper(pGC);
199706f2543Smrg
200706f2543Smrg  switch(type)
201706f2543Smrg    {
202706f2543Smrg    case CT_NONE:
203706f2543Smrg      XSetClipMask(xnestDisplay, xnestGC(pGC), None);
204706f2543Smrg      break;
205706f2543Smrg
206706f2543Smrg    case CT_REGION:
207706f2543Smrg      nRects = RegionNumRects((RegionPtr)pValue);
208706f2543Smrg      size = nRects * sizeof(*pRects);
209706f2543Smrg      pRects = (XRectangle *) malloc(size);
210706f2543Smrg      pBox = RegionRects((RegionPtr)pValue);
211706f2543Smrg      for (i = nRects; i-- > 0; ) {
212706f2543Smrg	pRects[i].x = pBox[i].x1;
213706f2543Smrg	pRects[i].y = pBox[i].y1;
214706f2543Smrg	pRects[i].width = pBox[i].x2 - pBox[i].x1;
215706f2543Smrg	pRects[i].height = pBox[i].y2 - pBox[i].y1;
216706f2543Smrg      }
217706f2543Smrg      XSetClipRectangles(xnestDisplay, xnestGC(pGC), 0, 0,
218706f2543Smrg			 pRects, nRects, Unsorted);
219706f2543Smrg      free((char *) pRects);
220706f2543Smrg      break;
221706f2543Smrg
222706f2543Smrg    case CT_PIXMAP:
223706f2543Smrg      XSetClipMask(xnestDisplay, xnestGC(pGC),
224706f2543Smrg		   xnestPixmap((PixmapPtr)pValue));
225706f2543Smrg      /*
226706f2543Smrg       * Need to change into region, so subsequent uses are with
227706f2543Smrg       * current pixmap contents.
228706f2543Smrg       */
229706f2543Smrg      pGC->clientClip = (pointer) (*pGC->pScreen->BitmapToRegion)((PixmapPtr)pValue);
230706f2543Smrg      (*pGC->pScreen->DestroyPixmap)((PixmapPtr)pValue);
231706f2543Smrg      pValue = pGC->clientClip;
232706f2543Smrg      type = CT_REGION;
233706f2543Smrg      break;
234706f2543Smrg
235706f2543Smrg    case CT_UNSORTED:
236706f2543Smrg      XSetClipRectangles(xnestDisplay, xnestGC(pGC),
237706f2543Smrg			 pGC->clipOrg.x, pGC->clipOrg.y,
238706f2543Smrg			 (XRectangle *)pValue, nRects, Unsorted);
239706f2543Smrg      break;
240706f2543Smrg
241706f2543Smrg    case CT_YSORTED:
242706f2543Smrg      XSetClipRectangles(xnestDisplay, xnestGC(pGC),
243706f2543Smrg			 pGC->clipOrg.x, pGC->clipOrg.y,
244706f2543Smrg			 (XRectangle *)pValue, nRects, YSorted);
245706f2543Smrg      break;
246706f2543Smrg
247706f2543Smrg    case CT_YXSORTED:
248706f2543Smrg      XSetClipRectangles(xnestDisplay, xnestGC(pGC),
249706f2543Smrg			 pGC->clipOrg.x, pGC->clipOrg.y,
250706f2543Smrg			 (XRectangle *)pValue, nRects, YXSorted);
251706f2543Smrg      break;
252706f2543Smrg
253706f2543Smrg    case CT_YXBANDED:
254706f2543Smrg      XSetClipRectangles(xnestDisplay, xnestGC(pGC),
255706f2543Smrg			 pGC->clipOrg.x, pGC->clipOrg.y,
256706f2543Smrg			 (XRectangle *)pValue, nRects, YXBanded);
257706f2543Smrg      break;
258706f2543Smrg    }
259706f2543Smrg
260706f2543Smrg  switch(type)
261706f2543Smrg    {
262706f2543Smrg    default:
263706f2543Smrg      break;
264706f2543Smrg
265706f2543Smrg    case CT_UNSORTED:
266706f2543Smrg    case CT_YSORTED:
267706f2543Smrg    case CT_YXSORTED:
268706f2543Smrg    case CT_YXBANDED:
269706f2543Smrg
270706f2543Smrg      /*
271706f2543Smrg       * other parts of server can only deal with CT_NONE,
272706f2543Smrg       * CT_PIXMAP and CT_REGION client clips.
273706f2543Smrg       */
274706f2543Smrg      pGC->clientClip = (pointer) RegionFromRects(nRects,
275706f2543Smrg						  (xRectangle *)pValue, type);
276706f2543Smrg      free(pValue);
277706f2543Smrg      pValue = pGC->clientClip;
278706f2543Smrg      type = CT_REGION;
279706f2543Smrg
280706f2543Smrg      break;
281706f2543Smrg    }
282706f2543Smrg
283706f2543Smrg  pGC->clientClipType = type;
284706f2543Smrg  pGC->clientClip = pValue;
285706f2543Smrg  xnestGCPriv(pGC)->nClipRects = nRects;
286706f2543Smrg}
287706f2543Smrg
288706f2543Smrgvoid
289706f2543SmrgxnestDestroyClip(GCPtr pGC)
290706f2543Smrg{
291706f2543Smrg  xnestDestroyClipHelper(pGC);
292706f2543Smrg
293706f2543Smrg  XSetClipMask(xnestDisplay, xnestGC(pGC), None);
294706f2543Smrg
295706f2543Smrg  pGC->clientClipType = CT_NONE;
296706f2543Smrg  pGC->clientClip = NULL;
297706f2543Smrg  xnestGCPriv(pGC)->nClipRects = 0;
298706f2543Smrg}
299706f2543Smrg
300706f2543Smrgvoid
301706f2543SmrgxnestDestroyClipHelper(GCPtr pGC)
302706f2543Smrg{
303706f2543Smrg  switch (pGC->clientClipType)
304706f2543Smrg    {
305706f2543Smrg    default:
306706f2543Smrg    case CT_NONE:
307706f2543Smrg      break;
308706f2543Smrg
309706f2543Smrg    case CT_REGION:
310706f2543Smrg      RegionDestroy(pGC->clientClip);
311706f2543Smrg      break;
312706f2543Smrg    }
313706f2543Smrg}
314706f2543Smrg
315706f2543Smrgvoid
316706f2543SmrgxnestCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
317706f2543Smrg{
318706f2543Smrg  RegionPtr pRgn;
319706f2543Smrg
320706f2543Smrg  switch (pGCSrc->clientClipType)
321706f2543Smrg    {
322706f2543Smrg    default:
323706f2543Smrg    case CT_NONE:
324706f2543Smrg      xnestDestroyClip(pGCDst);
325706f2543Smrg      break;
326706f2543Smrg
327706f2543Smrg    case CT_REGION:
328706f2543Smrg      pRgn = RegionCreate(NULL, 1);
329706f2543Smrg      RegionCopy(pRgn, pGCSrc->clientClip);
330706f2543Smrg      xnestChangeClip(pGCDst, CT_REGION, pRgn, 0);
331706f2543Smrg      break;
332706f2543Smrg    }
333706f2543Smrg}
334