1706f2543Smrg/*
2706f2543Smrg * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
3706f2543Smrg *
4706f2543Smrg * All Rights Reserved.
5706f2543Smrg *
6706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining
7706f2543Smrg * a copy of this software and associated documentation files (the
8706f2543Smrg * "Software"), to deal in the Software without restriction, including
9706f2543Smrg * without limitation on the rights to use, copy, modify, merge,
10706f2543Smrg * publish, distribute, sublicense, and/or sell copies of the Software,
11706f2543Smrg * and to permit persons to whom the Software is furnished to do so,
12706f2543Smrg * subject to the following conditions:
13706f2543Smrg *
14706f2543Smrg * The above copyright notice and this permission notice (including the
15706f2543Smrg * next paragraph) shall be included in all copies or substantial
16706f2543Smrg * portions of the Software.
17706f2543Smrg *
18706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19706f2543Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21706f2543Smrg * NON-INFRINGEMENT.  IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22706f2543Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23706f2543Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24706f2543Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25706f2543Smrg * SOFTWARE.
26706f2543Smrg */
27706f2543Smrg
28706f2543Smrg/*
29706f2543Smrg * Authors:
30706f2543Smrg *   Kevin E. Martin <kem@redhat.com>
31706f2543Smrg *
32706f2543Smrg */
33706f2543Smrg
34706f2543Smrg/** \file
35706f2543Smrg * This file provides support for GCs. */
36706f2543Smrg
37706f2543Smrg#ifdef HAVE_DMX_CONFIG_H
38706f2543Smrg#include <dmx-config.h>
39706f2543Smrg#endif
40706f2543Smrg
41706f2543Smrg#include "dmx.h"
42706f2543Smrg#include "dmxsync.h"
43706f2543Smrg#include "dmxgc.h"
44706f2543Smrg#include "dmxgcops.h"
45706f2543Smrg#include "dmxpixmap.h"
46706f2543Smrg#include "dmxfont.h"
47706f2543Smrg
48706f2543Smrg#include "gcstruct.h"
49706f2543Smrg#include "pixmapstr.h"
50706f2543Smrg#include "migc.h"
51706f2543Smrg
52706f2543Smrgstatic GCFuncs dmxGCFuncs = {
53706f2543Smrg    dmxValidateGC,
54706f2543Smrg    dmxChangeGC,
55706f2543Smrg    dmxCopyGC,
56706f2543Smrg    dmxDestroyGC,
57706f2543Smrg    dmxChangeClip,
58706f2543Smrg    dmxDestroyClip,
59706f2543Smrg    dmxCopyClip,
60706f2543Smrg};
61706f2543Smrg
62706f2543Smrgstatic GCOps dmxGCOps = {
63706f2543Smrg    dmxFillSpans,
64706f2543Smrg    dmxSetSpans,
65706f2543Smrg    dmxPutImage,
66706f2543Smrg    dmxCopyArea,
67706f2543Smrg    dmxCopyPlane,
68706f2543Smrg    dmxPolyPoint,
69706f2543Smrg    dmxPolylines,
70706f2543Smrg    dmxPolySegment,
71706f2543Smrg    dmxPolyRectangle,
72706f2543Smrg    dmxPolyArc,
73706f2543Smrg    dmxFillPolygon,
74706f2543Smrg    dmxPolyFillRect,
75706f2543Smrg    dmxPolyFillArc,
76706f2543Smrg    dmxPolyText8,
77706f2543Smrg    dmxPolyText16,
78706f2543Smrg    dmxImageText8,
79706f2543Smrg    dmxImageText16,
80706f2543Smrg    dmxImageGlyphBlt,
81706f2543Smrg    dmxPolyGlyphBlt,
82706f2543Smrg    dmxPushPixels
83706f2543Smrg};
84706f2543Smrg
85706f2543Smrg/** Initialize the GC on \a pScreen */
86706f2543SmrgBool dmxInitGC(ScreenPtr pScreen)
87706f2543Smrg{
88706f2543Smrg    if (!dixRegisterPrivateKey(&dmxGCPrivateKeyRec, PRIVATE_GC, sizeof(dmxGCPrivRec)))
89706f2543Smrg            return FALSE;
90706f2543Smrg    return TRUE;
91706f2543Smrg}
92706f2543Smrg
93706f2543Smrg/** Create the GC on the back-end server. */
94706f2543Smrgvoid dmxBECreateGC(ScreenPtr pScreen, GCPtr pGC)
95706f2543Smrg{
96706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
97706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
98706f2543Smrg    int            i;
99706f2543Smrg
100706f2543Smrg    for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
101706f2543Smrg	if (pGC->depth == dmxScreen->bePixmapFormats[i].depth) {
102706f2543Smrg	    unsigned long  mask;
103706f2543Smrg	    XGCValues      gcvals;
104706f2543Smrg
105706f2543Smrg	    mask = GCGraphicsExposures;
106706f2543Smrg	    gcvals.graphics_exposures = FALSE;
107706f2543Smrg
108706f2543Smrg	    /* Create GC in the back-end servers */
109706f2543Smrg	    pGCPriv->gc = XCreateGC(dmxScreen->beDisplay,
110706f2543Smrg				    dmxScreen->scrnDefDrawables[i],
111706f2543Smrg				    mask, &gcvals);
112706f2543Smrg	    break;
113706f2543Smrg	}
114706f2543Smrg    }
115706f2543Smrg}
116706f2543Smrg
117706f2543Smrg/** Create a graphics context on the back-end server associated /a pGC's
118706f2543Smrg *  screen. */
119706f2543SmrgBool dmxCreateGC(GCPtr pGC)
120706f2543Smrg{
121706f2543Smrg    ScreenPtr      pScreen = pGC->pScreen;
122706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
123706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
124706f2543Smrg    Bool           ret;
125706f2543Smrg
126706f2543Smrg    DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
127706f2543Smrg    if ((ret = pScreen->CreateGC(pGC))) {
128706f2543Smrg	/* Save the old funcs */
129706f2543Smrg	pGCPriv->funcs = pGC->funcs;
130706f2543Smrg	pGCPriv->ops   = NULL;
131706f2543Smrg
132706f2543Smrg	pGC->funcs = &dmxGCFuncs;
133706f2543Smrg
134706f2543Smrg	if (dmxScreen->beDisplay) {
135706f2543Smrg	    dmxBECreateGC(pScreen, pGC);
136706f2543Smrg	} else {
137706f2543Smrg	    pGCPriv->gc = NULL;
138706f2543Smrg	}
139706f2543Smrg
140706f2543Smrg	/* Check for "magic special case"
141706f2543Smrg	 * 1. see CreateGC in dix/gc.c for more info
142706f2543Smrg	 * 2. see dmxChangeGC for more info
143706f2543Smrg	 */
144706f2543Smrg	pGCPriv->msc = (!pGC->tileIsPixel && !pGC->tile.pixmap);
145706f2543Smrg    }
146706f2543Smrg    DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);
147706f2543Smrg
148706f2543Smrg    return ret;
149706f2543Smrg}
150706f2543Smrg
151706f2543Smrg/** Validate a graphics context, \a pGC, locally in the DMX server and
152706f2543Smrg *  recompute the composite clip, if necessary. */
153706f2543Smrgvoid dmxValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
154706f2543Smrg{
155706f2543Smrg    dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
156706f2543Smrg
157706f2543Smrg    DMX_GC_FUNC_PROLOGUE(pGC);
158706f2543Smrg#if 0
159706f2543Smrg    pGC->funcs->ValidateGC(pGC, changes, pDrawable);
160706f2543Smrg#endif
161706f2543Smrg
162706f2543Smrg    if (pDrawable->type == DRAWABLE_WINDOW ||
163706f2543Smrg	pDrawable->type == DRAWABLE_PIXMAP) {
164706f2543Smrg	/* Save the old ops, since we're about to change the ops in the
165706f2543Smrg	 * epilogue.
166706f2543Smrg	 */
167706f2543Smrg	pGCPriv->ops = pGC->ops;
168706f2543Smrg    } else {
169706f2543Smrg	pGCPriv->ops = NULL;
170706f2543Smrg    }
171706f2543Smrg
172706f2543Smrg    /* If the client clip is different or moved OR the subwindowMode has
173706f2543Smrg     * changed OR the window's clip has changed since the last
174706f2543Smrg     * validation, then we need to recompute the composite clip.
175706f2543Smrg     */
176706f2543Smrg    if ((changes & (GCClipXOrigin |
177706f2543Smrg		    GCClipYOrigin |
178706f2543Smrg		    GCClipMask |
179706f2543Smrg		    GCSubwindowMode)) ||
180706f2543Smrg	(pDrawable->serialNumber !=
181706f2543Smrg	 (pGC->serialNumber & DRAWABLE_SERIAL_BITS))) {
182706f2543Smrg	miComputeCompositeClip(pGC, pDrawable);
183706f2543Smrg    }
184706f2543Smrg
185706f2543Smrg    DMX_GC_FUNC_EPILOGUE(pGC);
186706f2543Smrg}
187706f2543Smrg
188706f2543Smrg/** Set the values in the graphics context on the back-end server
189706f2543Smrg *  associated with \a pGC's screen. */
190706f2543Smrgvoid dmxChangeGC(GCPtr pGC, unsigned long mask)
191706f2543Smrg{
192706f2543Smrg    ScreenPtr      pScreen = pGC->pScreen;
193706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
194706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
195706f2543Smrg    XGCValues      v;
196706f2543Smrg
197706f2543Smrg    DMX_GC_FUNC_PROLOGUE(pGC);
198706f2543Smrg#if 0
199706f2543Smrg    pGC->funcs->ChangeGC(pGC, mask);
200706f2543Smrg#endif
201706f2543Smrg
202706f2543Smrg    /* Handle "magic special case" from CreateGC */
203706f2543Smrg    if (pGCPriv->msc) {
204706f2543Smrg	/* The "magic special case" is used to handle the case where a
205706f2543Smrg	 * foreground pixel is set when the GC is created so that a
206706f2543Smrg	 * "pseudo default-tile" can be created and used in case the
207706f2543Smrg	 * fillstyle was set to FillTiled.  This specific case is tested
208706f2543Smrg	 * in xtest (XCreateGC test #3).  What has happened in dix by
209706f2543Smrg	 * the time it reaches here is (1) the pGC->tile.pixel has been
210706f2543Smrg	 * set to pGC->fgPixel and pGC->tileIsPixel is set, (2) if a
211706f2543Smrg	 * tile has also been set, then pGC->tileIsPixel is unset and
212706f2543Smrg	 * pGC->tile.pixmap is initialized; else, the default tile is
213706f2543Smrg	 * created and pGC->tileIsPixel is unset and pGC->tile.pixmap is
214706f2543Smrg	 * initialized to the "pseudo default-tile".  In either case,
215706f2543Smrg	 * pGC->tile.pixmap is set; however, in the "magic special case"
216706f2543Smrg	 * the mask is not updated to allow us to detect that we should
217706f2543Smrg	 * initialize the GCTile in the back-end server.  Thus, we catch
218706f2543Smrg	 * this case in dmxCreateGC and add GCTile to the mask here.
219706f2543Smrg	 * Are there any cases that I've missed?
220706f2543Smrg	 */
221706f2543Smrg
222706f2543Smrg	/* Make sure that the tile.pixmap is set, just in case the user
223706f2543Smrg         * set GCTile in the mask but forgot to set vals.pixmap
224706f2543Smrg	 */
225706f2543Smrg	if (pGC->tile.pixmap) mask |= GCTile;
226706f2543Smrg
227706f2543Smrg	/* This only happens once when the GC is created */
228706f2543Smrg	pGCPriv->msc = FALSE;
229706f2543Smrg    }
230706f2543Smrg
231706f2543Smrg    /* Update back-end server's gc */
232706f2543Smrg    if (mask & GCFunction)          v.function = pGC->alu;
233706f2543Smrg    if (mask & GCPlaneMask)         v.plane_mask = pGC->planemask;
234706f2543Smrg    if (mask & GCForeground)        v.foreground = pGC->fgPixel;
235706f2543Smrg    if (mask & GCBackground)        v.background = pGC->bgPixel;
236706f2543Smrg    if (mask & GCLineWidth)         v.line_width = pGC->lineWidth;
237706f2543Smrg    if (mask & GCLineStyle)         v.line_style = pGC->lineStyle;
238706f2543Smrg    if (mask & GCCapStyle)          v.cap_style = pGC->capStyle;
239706f2543Smrg    if (mask & GCJoinStyle)         v.join_style = pGC->joinStyle;
240706f2543Smrg    if (mask & GCFillStyle)         v.fill_style = pGC->fillStyle;
241706f2543Smrg    if (mask & GCFillRule)          v.fill_rule = pGC->fillRule;
242706f2543Smrg    if (mask & GCTile) {
243706f2543Smrg	if (pGC->tileIsPixel) {
244706f2543Smrg	    mask &= ~GCTile;
245706f2543Smrg	} else {
246706f2543Smrg	    dmxPixPrivPtr  pPixPriv = DMX_GET_PIXMAP_PRIV(pGC->tile.pixmap);
247706f2543Smrg	    v.tile = (Drawable)pPixPriv->pixmap;
248706f2543Smrg	}
249706f2543Smrg    }
250706f2543Smrg    if (mask & GCStipple) {
251706f2543Smrg	dmxPixPrivPtr  pPixPriv = DMX_GET_PIXMAP_PRIV(pGC->stipple);
252706f2543Smrg	v.stipple = (Drawable)pPixPriv->pixmap;
253706f2543Smrg    }
254706f2543Smrg    if (mask & GCTileStipXOrigin)   v.ts_x_origin = pGC->patOrg.x;
255706f2543Smrg    if (mask & GCTileStipYOrigin)   v.ts_y_origin = pGC->patOrg.y;
256706f2543Smrg    if (mask & GCFont) {
257706f2543Smrg	if (dmxScreen->beDisplay) {
258706f2543Smrg	    dmxFontPrivPtr  pFontPriv;
259706f2543Smrg	    pFontPriv = FontGetPrivate(pGC->font, dmxFontPrivateIndex);
260706f2543Smrg	    v.font = pFontPriv->font[pScreen->myNum]->fid;
261706f2543Smrg	} else {
262706f2543Smrg	    mask &= ~GCFont;
263706f2543Smrg	}
264706f2543Smrg    }
265706f2543Smrg    if (mask & GCSubwindowMode)     v.subwindow_mode = pGC->subWindowMode;
266706f2543Smrg
267706f2543Smrg    /* Graphics exposures are not needed on the back-ends since they can
268706f2543Smrg       be generated on the front-end thereby saving bandwidth. */
269706f2543Smrg    if (mask & GCGraphicsExposures) mask &= ~GCGraphicsExposures;
270706f2543Smrg
271706f2543Smrg    if (mask & GCClipXOrigin)       v.clip_x_origin = pGC->clipOrg.x;
272706f2543Smrg    if (mask & GCClipYOrigin)       v.clip_y_origin = pGC->clipOrg.y;
273706f2543Smrg    if (mask & GCClipMask)          mask &= ~GCClipMask; /* See ChangeClip */
274706f2543Smrg    if (mask & GCDashOffset)        v.dash_offset = pGC->dashOffset;
275706f2543Smrg    if (mask & GCDashList) {
276706f2543Smrg	mask &= ~GCDashList;
277706f2543Smrg	if (dmxScreen->beDisplay)
278706f2543Smrg	    XSetDashes(dmxScreen->beDisplay, pGCPriv->gc,
279706f2543Smrg		       pGC->dashOffset, (char *)pGC->dash,
280706f2543Smrg		       pGC->numInDashList);
281706f2543Smrg    }
282706f2543Smrg    if (mask & GCArcMode)           v.arc_mode = pGC->arcMode;
283706f2543Smrg
284706f2543Smrg    if (mask && dmxScreen->beDisplay) {
285706f2543Smrg	XChangeGC(dmxScreen->beDisplay, pGCPriv->gc, mask, &v);
286706f2543Smrg	dmxSync(dmxScreen, FALSE);
287706f2543Smrg    }
288706f2543Smrg
289706f2543Smrg    DMX_GC_FUNC_EPILOGUE(pGC);
290706f2543Smrg}
291706f2543Smrg
292706f2543Smrg/** Copy \a pGCSrc to \a pGCDst on the back-end server associated with
293706f2543Smrg *  \a pGCSrc's screen. */
294706f2543Smrgvoid dmxCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst)
295706f2543Smrg{
296706f2543Smrg    ScreenPtr      pScreen = pGCSrc->pScreen;
297706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
298706f2543Smrg    dmxGCPrivPtr   pGCSrcPriv = DMX_GET_GC_PRIV(pGCSrc);
299706f2543Smrg    dmxGCPrivPtr   pGCDstPriv = DMX_GET_GC_PRIV(pGCDst);
300706f2543Smrg
301706f2543Smrg    DMX_GC_FUNC_PROLOGUE(pGCDst);
302706f2543Smrg    pGCDst->funcs->CopyGC(pGCSrc, changes, pGCDst);
303706f2543Smrg
304706f2543Smrg    /* Copy the GC on the back-end server */
305706f2543Smrg    if (dmxScreen->beDisplay)
306706f2543Smrg	XCopyGC(dmxScreen->beDisplay, pGCSrcPriv->gc, changes, pGCDstPriv->gc);
307706f2543Smrg
308706f2543Smrg    DMX_GC_FUNC_EPILOGUE(pGCDst);
309706f2543Smrg}
310706f2543Smrg
311706f2543Smrg/** Free the \a pGC on the back-end server. */
312706f2543SmrgBool dmxBEFreeGC(GCPtr pGC)
313706f2543Smrg{
314706f2543Smrg    ScreenPtr      pScreen   = pGC->pScreen;
315706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
316706f2543Smrg    dmxGCPrivPtr   pGCPriv   = DMX_GET_GC_PRIV(pGC);
317706f2543Smrg
318706f2543Smrg    if (pGCPriv->gc) {
319706f2543Smrg	XFreeGC(dmxScreen->beDisplay, pGCPriv->gc);
320706f2543Smrg	pGCPriv->gc = NULL;
321706f2543Smrg	return TRUE;
322706f2543Smrg    }
323706f2543Smrg
324706f2543Smrg    return FALSE;
325706f2543Smrg}
326706f2543Smrg
327706f2543Smrg/** Destroy the graphics context, \a pGC and free the corresponding GC
328706f2543Smrg *  on the back-end server. */
329706f2543Smrgvoid dmxDestroyGC(GCPtr pGC)
330706f2543Smrg{
331706f2543Smrg    ScreenPtr      pScreen   = pGC->pScreen;
332706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
333706f2543Smrg
334706f2543Smrg    DMX_GC_FUNC_PROLOGUE(pGC);
335706f2543Smrg
336706f2543Smrg    /* Free the GC on the back-end server */
337706f2543Smrg    if (dmxScreen->beDisplay)
338706f2543Smrg	dmxBEFreeGC(pGC);
339706f2543Smrg
340706f2543Smrg    pGC->funcs->DestroyGC(pGC);
341706f2543Smrg    DMX_GC_FUNC_EPILOGUE(pGC);
342706f2543Smrg}
343706f2543Smrg
344706f2543Smrg/** Change the clip rects for a GC. */
345706f2543Smrgvoid dmxChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
346706f2543Smrg{
347706f2543Smrg    ScreenPtr      pScreen = pGC->pScreen;
348706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
349706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
350706f2543Smrg    XRectangle    *pRects;
351706f2543Smrg    BoxPtr         pBox;
352706f2543Smrg    int            i, nRects;
353706f2543Smrg
354706f2543Smrg    DMX_GC_FUNC_PROLOGUE(pGC);
355706f2543Smrg    pGC->funcs->ChangeClip(pGC, type, pvalue, nrects);
356706f2543Smrg
357706f2543Smrg    /* Set the client clip on the back-end server */
358706f2543Smrg    switch (pGC->clientClipType) {
359706f2543Smrg    case CT_NONE:
360706f2543Smrg	if (dmxScreen->beDisplay)
361706f2543Smrg	    XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
362706f2543Smrg	break;
363706f2543Smrg
364706f2543Smrg    case CT_REGION:
365706f2543Smrg	if (dmxScreen->beDisplay) {
366706f2543Smrg	    nRects = RegionNumRects((RegionPtr)pGC->clientClip);
367706f2543Smrg	    pRects = malloc(nRects * sizeof(*pRects));
368706f2543Smrg	    pBox   = RegionRects((RegionPtr)pGC->clientClip);
369706f2543Smrg
370706f2543Smrg	    for (i = 0; i < nRects; i++) {
371706f2543Smrg		pRects[i].x      = pBox[i].x1;
372706f2543Smrg		pRects[i].y      = pBox[i].y1;
373706f2543Smrg		pRects[i].width  = pBox[i].x2 - pBox[i].x1;
374706f2543Smrg		pRects[i].height = pBox[i].y2 - pBox[i].y1;
375706f2543Smrg	    }
376706f2543Smrg
377706f2543Smrg	    XSetClipRectangles(dmxScreen->beDisplay, pGCPriv->gc,
378706f2543Smrg			       pGC->clipOrg.x, pGC->clipOrg.y,
379706f2543Smrg			       pRects, nRects, Unsorted);
380706f2543Smrg
381706f2543Smrg	    free(pRects);
382706f2543Smrg	}
383706f2543Smrg	break;
384706f2543Smrg
385706f2543Smrg    case CT_PIXMAP:
386706f2543Smrg	/* Condensed down to REGION in the mi code */
387706f2543Smrg	break;
388706f2543Smrg    }
389706f2543Smrg
390706f2543Smrg    DMX_GC_FUNC_EPILOGUE(pGC);
391706f2543Smrg}
392706f2543Smrg
393706f2543Smrg/** Destroy a GC's clip rects. */
394706f2543Smrgvoid dmxDestroyClip(GCPtr pGC)
395706f2543Smrg{
396706f2543Smrg    ScreenPtr      pScreen = pGC->pScreen;
397706f2543Smrg    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
398706f2543Smrg    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
399706f2543Smrg
400706f2543Smrg    DMX_GC_FUNC_PROLOGUE(pGC);
401706f2543Smrg    pGC->funcs->DestroyClip(pGC);
402706f2543Smrg
403706f2543Smrg    /* Set the client clip on the back-end server to None */
404706f2543Smrg    if (dmxScreen->beDisplay)
405706f2543Smrg	XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
406706f2543Smrg
407706f2543Smrg    DMX_GC_FUNC_EPILOGUE(pGC);
408706f2543Smrg}
409706f2543Smrg
410706f2543Smrg/** Copy a GC's clip rects. */
411706f2543Smrgvoid dmxCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
412706f2543Smrg{
413706f2543Smrg    DMX_GC_FUNC_PROLOGUE(pGCDst);
414706f2543Smrg    pGCDst->funcs->CopyClip(pGCDst, pGCSrc);
415706f2543Smrg    DMX_GC_FUNC_EPILOGUE(pGCDst);
416706f2543Smrg}
417