Exemplo n.º 1
0
/** Load the font, \a pFont, on the back-end server associated with \a
 *  pScreen.  When a font is loaded, the font path on back-end server is
 *  first initialized to that specified on the command line with the
 *  -fontpath options, and then the font is loaded. */
Bool
dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
    const char *name;
    char **oldFontPath = NULL;
    int nOldPaths;
    Atom name_atom, value_atom;
    int i;

    /* Make sure we have a font private struct to work with */
    if (!pFontPriv)
        return FALSE;

    /* Don't load a font over top of itself */
    if (pFontPriv->font[pScreen->myNum]) {
        return TRUE;            /* Already loaded font */
    }

    /* Save old font path */
    oldFontPath = XGetFontPath(dmxScreen->beDisplay, &nOldPaths);

    /* Set the font path for the font about to be loaded on the back-end */
    if (dmxSetFontPath(dmxScreen)) {
        char **fp;
        int npaths;
        Bool *goodfps;

        /* This could fail only when first starting the X server and
         * loading the default font.  If it fails here, then the default
         * font path is invalid, no default font path will be set, the
         * DMX server will fail to load the default font, and it will
         * exit with an error unless we remove the offending font paths
         * with the -ignorebadfontpaths command line option.
         */

        fp = dmxGetFontPath(&npaths);
        if (!fp) {
            dmxLog(dmxError, "No default font path set.\n");
            dmxLog(dmxError,
                   "Please see the Xdmx man page for information on how to\n");
            dmxLog(dmxError,
                   "initialize the DMX server's default font path.\n");
            XFreeFontPath(oldFontPath);
            return FALSE;
        }

        if (!dmxFontPath)
            dmxLog(dmxWarning, "No default font path is set.\n");

        goodfps = xallocarray(npaths, sizeof(*goodfps));

        dmxLog(dmxError,
               "The DMX server failed to set the following font paths on "
               "screen #%d:\n", pScreen->myNum);

        for (i = 0; i < npaths; i++)
            if (!(goodfps[i] = dmxCheckFontPathElement(dmxScreen, fp[i])))
                dmxLog(dmxError, "    %s\n", fp[i]);

        if (dmxIgnoreBadFontPaths) {
            char *newfp;
            int newnpaths = 0;
            int len = 0;
            int j = 0;

            dmxLog(dmxError,
                   "These font paths will not be used because the "
                   "\"-ignorebadfontpaths\"\n");
            dmxLog(dmxError, "option is set.\n");

            for (i = 0; i < npaths; i++)
                if (goodfps[i]) {
                    len += strlen(fp[i]) + 1;
                    newnpaths++;
                }

            if (!newnpaths) {
                /* No valid font paths were found */
                dmxLog(dmxError,
                       "After removing the font paths above, no valid font "
                       "paths were\n");
                dmxLog(dmxError,
                       "available.  Please check that the font paths set on "
                       "the command\n");
                dmxLog(dmxError,
                       "line or in the configuration file via the "
                       "\"-fontpath\" option\n");
                dmxLog(dmxError,
                       "are valid on all back-end servers.  See the Xdmx man "
                       "page for\n");
                dmxLog(dmxError, "more information on font paths.\n");
                dmxFreeFontPath(fp);
                XFreeFontPath(oldFontPath);
                free(goodfps);
                return FALSE;
            }

            newfp = xallocarray(len, sizeof(*newfp));
            for (i = 0; i < npaths; i++) {
                if (goodfps[i]) {
                    int n = strlen(fp[i]);

                    newfp[j++] = n;
                    strncpy(&newfp[j], fp[i], n);
                    j += n;
                }
            }

            if (SetFontPath(serverClient, newnpaths, (unsigned char *) newfp)) {
                /* Note that this should never happen since all of the
                 * FPEs were previously valid. */
                dmxLog(dmxError, "Cannot reset the default font path.\n");
            }
        }
        else if (dmxFontPath) {
            dmxLog(dmxError,
                   "Please remove these font paths from the command line "
                   "or\n");
            dmxLog(dmxError,
                   "configuration file, or set the \"-ignorebadfontpaths\" "
                   "option to\n");
            dmxLog(dmxError,
                   "ignore them.  For more information on these options, see "
                   "the\n");
            dmxLog(dmxError, "Xdmx man page.\n");
        }
        else {
            dmxLog(dmxError,
                   "Please specify the font paths that are available on all "
                   "back-end\n");
            dmxLog(dmxError,
                   "servers with the \"-fontpath\" option, or use the "
                   "\"-ignorebadfontpaths\"\n");
            dmxLog(dmxError,
                   "to ignore bad defaults.  For more information on "
                   "these and other\n");
            dmxLog(dmxError,
                   "font-path-related options, see the Xdmx man page.\n");
        }

        free(goodfps);
        if (!dmxIgnoreBadFontPaths ||
            (dmxIgnoreBadFontPaths && dmxSetFontPath(dmxScreen))) {
            /* We still have errors so return with error */
            dmxFreeFontPath(fp);
            XFreeFontPath(oldFontPath);
            return FALSE;
        }
    }

    /* Find requested font on back-end server */
    name_atom = MakeAtom("FONT", 4, TRUE);
    value_atom = 0L;

    for (i = 0; i < pFont->info.nprops; i++) {
        if ((Atom) pFont->info.props[i].name == name_atom) {
            value_atom = pFont->info.props[i].value;
            break;
        }
    }
    if (!value_atom)
        return FALSE;

    name = NameForAtom(value_atom);
    if (!name)
        return FALSE;

    pFontPriv->font[pScreen->myNum] =
        XLoadQueryFont(dmxScreen->beDisplay, name);

    /* Restore old font path */
    XSetFontPath(dmxScreen->beDisplay, oldFontPath, nOldPaths);
    XFreeFontPath(oldFontPath);
    dmxSync(dmxScreen, FALSE);

    if (!pFontPriv->font[pScreen->myNum])
        return FALSE;

    return TRUE;
}
Exemplo n.º 2
0
/** Change the picture's list of clip rectangles. */
int
dmxChangePictureClip(PicturePtr pPicture, int clipType, void *value, int n)
{
    ScreenPtr pScreen = pPicture->pDrawable->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);

    DMX_UNWRAP(ChangePictureClip, dmxScreen, ps);
#if 1
    if (ps->ChangePictureClip)
        ps->ChangePictureClip(pPicture, clipType, value, n);
#endif

    /* Change picture clip rects on back-end server */
    if (pPictPriv->pict) {
        /* The clip has already been changed into a region by the mi
         * routine called above.
         */
        if (clipType == CT_NONE) {
            /* Disable clipping, show all */
            XFixesSetPictureClipRegion(dmxScreen->beDisplay,
                                       pPictPriv->pict, 0, 0, None);
        }
        else if (pPicture->clientClip) {
            RegionPtr pClip = pPicture->clientClip;
            BoxPtr pBox = RegionRects(pClip);
            int nBox = RegionNumRects(pClip);
            XRectangle *pRects;
            XRectangle *pRect;
            int nRects;

            nRects = nBox;
            pRects = pRect = malloc(nRects * sizeof(*pRect));

            while (nBox--) {
                pRect->x = pBox->x1;
                pRect->y = pBox->y1;
                pRect->width = pBox->x2 - pBox->x1;
                pRect->height = pBox->y2 - pBox->y1;
                pBox++;
                pRect++;
            }

            XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
                                            pPictPriv->pict,
                                            0, 0, pRects, nRects);
            free(pRects);
        }
        else {
            XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
                                            pPictPriv->pict, 0, 0, NULL, 0);
        }
        dmxSync(dmxScreen, FALSE);
    }
    else {
        /* FIXME: Handle saving clip region when offscreen */
    }

    DMX_WRAP(ChangePictureClip, dmxChangePictureClip, dmxScreen, ps);

    return Success;
}
Exemplo n.º 3
0
/** Composite glyphs on each screen into the requested picture.  If
 *  either the src or dest picture has not been allocated due to lazy
 *  window creation, this request will gracefully return. */
static int
dmxProcRenderCompositeGlyphs(ClientPtr client)
{
    int ret;

    REQUEST(xRenderCompositeGlyphsReq);

    ret = dmxSaveRenderVector[stuff->renderReqType] (client);

    /* For the following to work with PanoramiX, it assumes that Render
     * wraps the ProcRenderVector after dmxRenderInit has been called.
     */
    if (ret == Success) {
        PicturePtr pSrc;
        dmxPictPrivPtr pSrcPriv;
        PicturePtr pDst;
        dmxPictPrivPtr pDstPriv;
        PictFormatPtr pFmt;
        XRenderPictFormat *pFormat;
        int size;

        int scrnNum;
        DMXScreenInfo *dmxScreen;

        CARD8 *buffer;
        CARD8 *end;
        int space;

        int nglyph;
        char *glyphs;
        char *curGlyph;

        xGlyphElt *elt;
        int nelt;
        XGlyphElt8 *elts;
        XGlyphElt8 *curElt;

        GlyphSetPtr glyphSet;
        dmxGlyphPrivPtr glyphPriv;

        dixLookupResourceByType((void **) &pSrc,
                                stuff->src, PictureType, client, DixReadAccess);

        pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
        if (!pSrcPriv->pict)
            return ret;

        dixLookupResourceByType((void **) &pDst,
                                stuff->dst, PictureType,
                                client, DixWriteAccess);

        pDstPriv = DMX_GET_PICT_PRIV(pDst);
        if (!pDstPriv->pict)
            return ret;

        scrnNum = pDst->pDrawable->pScreen->myNum;
        dmxScreen = &dmxScreens[scrnNum];

        /* Note: If the back-end display has been detached, then it
         * should not be possible to reach here since the pSrcPriv->pict
         * and pDstPriv->pict will have already been set to 0.
         */
        if (!dmxScreen->beDisplay)
            return ret;

        if (stuff->maskFormat)
            dixLookupResourceByType((void **) &pFmt,
                                    stuff->maskFormat, PictFormatType,
                                    client, DixReadAccess);
        else
            pFmt = NULL;

        pFormat = dmxFindFormat(dmxScreen, pFmt);

        switch (stuff->renderReqType) {
        case X_RenderCompositeGlyphs8:
            size = sizeof(CARD8);
            break;
        case X_RenderCompositeGlyphs16:
            size = sizeof(CARD16);
            break;
        case X_RenderCompositeGlyphs32:
            size = sizeof(CARD32);
            break;
        default:
            return BadPictOp;   /* Can't happen */
        }

        buffer = (CARD8 *) (stuff + 1);
        end = (CARD8 *) stuff + (stuff->length << 2);
        nelt = 0;
        nglyph = 0;
        while (buffer + sizeof(xGlyphElt) < end) {
            elt = (xGlyphElt *) buffer;
            buffer += sizeof(xGlyphElt);

            if (elt->len == 0xff) {
                buffer += 4;
            }
            else {
                nelt++;
                nglyph += elt->len;
                space = size * elt->len;
                if (space & 3)
                    space += 4 - (space & 3);
                buffer += space;
            }
        }

        /* The following only works for Render version > 0.2 */

        /* All of the XGlyphElt* structure sizes are identical */
        elts = malloc(nelt * sizeof(XGlyphElt8));
        if (!elts)
            return BadAlloc;

        glyphs = malloc(nglyph * size);
        if (!glyphs) {
            free(elts);
            return BadAlloc;
        }

        buffer = (CARD8 *) (stuff + 1);
        end = (CARD8 *) stuff + (stuff->length << 2);
        curGlyph = glyphs;
        curElt = elts;

        dixLookupResourceByType((void **) &glyphSet,
                                stuff->glyphset, GlyphSetType,
                                client, DixReadAccess);
        glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);

        while (buffer + sizeof(xGlyphElt) < end) {
            elt = (xGlyphElt *) buffer;
            buffer += sizeof(xGlyphElt);

            if (elt->len == 0xff) {
                dixLookupResourceByType((void **) &glyphSet,
                                        *((CARD32 *) buffer),
                                        GlyphSetType, client, DixReadAccess);
                glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
                buffer += 4;
            }
            else {
                curElt->glyphset = glyphPriv->glyphSets[scrnNum];
                curElt->xOff = elt->deltax;
                curElt->yOff = elt->deltay;
                curElt->nchars = elt->len;
                curElt->chars = curGlyph;

                memcpy(curGlyph, buffer, size * elt->len);
                curGlyph += size * elt->len;

                curElt++;

                space = size * elt->len;
                if (space & 3)
                    space += 4 - (space & 3);
                buffer += space;
            }
        }

        switch (stuff->renderReqType) {
        case X_RenderCompositeGlyphs8:
            XRenderCompositeText8(dmxScreen->beDisplay, stuff->op,
                                  pSrcPriv->pict, pDstPriv->pict,
                                  pFormat,
                                  stuff->xSrc, stuff->ySrc, 0, 0, elts, nelt);
            break;
        case X_RenderCompositeGlyphs16:
            XRenderCompositeText16(dmxScreen->beDisplay, stuff->op,
                                   pSrcPriv->pict, pDstPriv->pict,
                                   pFormat,
                                   stuff->xSrc, stuff->ySrc,
                                   0, 0, (XGlyphElt16 *) elts, nelt);
            break;
        case X_RenderCompositeGlyphs32:
            XRenderCompositeText32(dmxScreen->beDisplay, stuff->op,
                                   pSrcPriv->pict, pDstPriv->pict,
                                   pFormat,
                                   stuff->xSrc, stuff->ySrc,
                                   0, 0, (XGlyphElt32 *) elts, nelt);
            break;
        }

        dmxSync(dmxScreen, FALSE);

        free(elts);
        free(glyphs);
    }

    return ret;
}
Exemplo n.º 4
0
/** Validate the picture's attributes before rendering to it.  Update
 *  any picture attributes that have been changed by one of the higher
 *  layers. */
void
dmxValidatePicture(PicturePtr pPicture, Mask mask)
{
    ScreenPtr pScreen = pPicture->pDrawable->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);

    DMX_UNWRAP(ValidatePicture, dmxScreen, ps);

    /* Change picture attributes on back-end server */
    if (pPictPriv->pict) {
        XRenderPictureAttributes attribs;

        if (mask & CPRepeat) {
            attribs.repeat = pPicture->repeatType;
        }
        if (mask & CPAlphaMap) {
            if (pPicture->alphaMap) {
                dmxPictPrivPtr pAlphaPriv;

                pAlphaPriv = DMX_GET_PICT_PRIV(pPicture->alphaMap);
                if (pAlphaPriv->pict) {
                    attribs.alpha_map = pAlphaPriv->pict;
                }
                else {
                    /* FIXME: alpha picture drawable has not been created?? */
                    return;     /* or should this be: attribs.alpha_map = None; */
                }
            }
            else {
                attribs.alpha_map = None;
            }
        }
        if (mask & CPAlphaXOrigin)
            attribs.alpha_x_origin = pPicture->alphaOrigin.x;
        if (mask & CPAlphaYOrigin)
            attribs.alpha_y_origin = pPicture->alphaOrigin.y;
        if (mask & CPClipXOrigin)
            attribs.clip_x_origin = pPicture->clipOrigin.x;
        if (mask & CPClipYOrigin)
            attribs.clip_y_origin = pPicture->clipOrigin.y;
        if (mask & CPClipMask)
            mask &= ~CPClipMask;        /* Handled in ChangePictureClip */
        if (mask & CPGraphicsExposure)
            attribs.graphics_exposures = pPicture->graphicsExposures;
        if (mask & CPSubwindowMode)
            attribs.subwindow_mode = pPicture->subWindowMode;
        if (mask & CPPolyEdge)
            attribs.poly_edge = pPicture->polyEdge;
        if (mask & CPPolyMode)
            attribs.poly_mode = pPicture->polyMode;
        if (mask & CPComponentAlpha)
            attribs.component_alpha = pPicture->componentAlpha;

        XRenderChangePicture(dmxScreen->beDisplay, pPictPriv->pict,
                             mask, &attribs);
        dmxSync(dmxScreen, FALSE);
    }
    else {
        pPictPriv->savedMask |= mask;
    }

#if 1
    if (ps->ValidatePicture)
        ps->ValidatePicture(pPicture, mask);
#endif

    DMX_WRAP(ValidatePicture, dmxValidatePicture, dmxScreen, ps);
}
Exemplo n.º 5
0
/** Transfer \a pBits image to back-end server associated with \a
 *  pDrawable's screen.  If primitive subdivision optimization is
 *  enabled, then only transfer the sections of \a pBits that are
 *  visible (i.e., not-clipped) to the back-end server. */
void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC,
		 int depth, int x, int y, int w, int h,
		 int leftPad, int format, char *pBits)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
    XImage        *img;

    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;

    img = XCreateImage(dmxScreen->beDisplay,
		       dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
		       depth, format, leftPad, pBits, w, h,
		       BitmapPad(dmxScreen->beDisplay),
		       (format == ZPixmap) ?
		       PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad));

    if (img) {
	Drawable draw;

	DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);

	if (dmxSubdividePrimitives && pGC->pCompositeClip) {
	    RegionPtr  pSubImages;
	    RegionPtr  pClip;
	    BoxRec     box;
	    BoxPtr     pBox;
	    int        nBox;

	    box.x1 = x;
	    box.y1 = y;
	    box.x2 = x + w;
	    box.y2 = y + h;
	    pSubImages = RegionCreate(&box, 1);

	    pClip = RegionCreate(NullBox, 1);
	    RegionCopy(pClip, pGC->pCompositeClip);
	    RegionTranslate(pClip,
			     -pDrawable->x, -pDrawable->y);
	    RegionIntersect(pSubImages, pSubImages, pClip);

	    nBox = RegionNumRects(pSubImages);
	    pBox = RegionRects(pSubImages);

	    while (nBox--) {
		XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img,
			  pBox->x1 - box.x1,
			  pBox->y1 - box.y1,
			  pBox->x1,
			  pBox->y1,
			  pBox->x2 - pBox->x1,
			  pBox->y2 - pBox->y1);
		pBox++;
	    }
            RegionDestroy(pClip);
            RegionDestroy(pSubImages);
	} else {
	    XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc,
		      img, 0, 0, x, y, w, h);
	}
	XFree(img);             /* Use XFree instead of XDestroyImage
                                 * because pBits is passed in from the
                                 * caller. */

	dmxSync(dmxScreen, FALSE);
    } else {
	/* Error -- this should not happen! */
    }
}
Exemplo n.º 6
0
/** Set the values in the graphics context on the back-end server
 *  associated with \a pGC's screen. */
void
dmxChangeGC(GCPtr pGC, unsigned long mask)
{
    ScreenPtr pScreen = pGC->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
    XGCValues v;

    DMX_GC_FUNC_PROLOGUE(pGC);
#if 0
    pGC->funcs->ChangeGC(pGC, mask);
#endif

    /* Handle "magic special case" from CreateGC */
    if (pGCPriv->msc) {
        /* The "magic special case" is used to handle the case where a
         * foreground pixel is set when the GC is created so that a
         * "pseudo default-tile" can be created and used in case the
         * fillstyle was set to FillTiled.  This specific case is tested
         * in xtest (XCreateGC test #3).  What has happened in dix by
         * the time it reaches here is (1) the pGC->tile.pixel has been
         * set to pGC->fgPixel and pGC->tileIsPixel is set, (2) if a
         * tile has also been set, then pGC->tileIsPixel is unset and
         * pGC->tile.pixmap is initialized; else, the default tile is
         * created and pGC->tileIsPixel is unset and pGC->tile.pixmap is
         * initialized to the "pseudo default-tile".  In either case,
         * pGC->tile.pixmap is set; however, in the "magic special case"
         * the mask is not updated to allow us to detect that we should
         * initialize the GCTile in the back-end server.  Thus, we catch
         * this case in dmxCreateGC and add GCTile to the mask here.
         * Are there any cases that I've missed?
         */

        /* Make sure that the tile.pixmap is set, just in case the user
         * set GCTile in the mask but forgot to set vals.pixmap
         */
        if (pGC->tile.pixmap)
            mask |= GCTile;

        /* This only happens once when the GC is created */
        pGCPriv->msc = FALSE;
    }

    /* Update back-end server's gc */
    if (mask & GCFunction)
        v.function = pGC->alu;
    if (mask & GCPlaneMask)
        v.plane_mask = pGC->planemask;
    if (mask & GCForeground)
        v.foreground = pGC->fgPixel;
    if (mask & GCBackground)
        v.background = pGC->bgPixel;
    if (mask & GCLineWidth)
        v.line_width = pGC->lineWidth;
    if (mask & GCLineStyle)
        v.line_style = pGC->lineStyle;
    if (mask & GCCapStyle)
        v.cap_style = pGC->capStyle;
    if (mask & GCJoinStyle)
        v.join_style = pGC->joinStyle;
    if (mask & GCFillStyle)
        v.fill_style = pGC->fillStyle;
    if (mask & GCFillRule)
        v.fill_rule = pGC->fillRule;
    if (mask & GCTile) {
        if (pGC->tileIsPixel) {
            mask &= ~GCTile;
        }
        else {
            dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pGC->tile.pixmap);

            v.tile = (Drawable) pPixPriv->pixmap;
        }
    }
    if (mask & GCStipple) {
        dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pGC->stipple);

        v.stipple = (Drawable) pPixPriv->pixmap;
    }
    if (mask & GCTileStipXOrigin)
        v.ts_x_origin = pGC->patOrg.x;
    if (mask & GCTileStipYOrigin)
        v.ts_y_origin = pGC->patOrg.y;
    if (mask & GCFont) {
        if (dmxScreen->beDisplay) {
            dmxFontPrivPtr pFontPriv;

            pFontPriv = FontGetPrivate(pGC->font, dmxFontPrivateIndex);
            v.font = pFontPriv->font[pScreen->myNum]->fid;
        }
        else {
            mask &= ~GCFont;
        }
    }
    if (mask & GCSubwindowMode)
        v.subwindow_mode = pGC->subWindowMode;

    /* Graphics exposures are not needed on the back-ends since they can
       be generated on the front-end thereby saving bandwidth. */
    if (mask & GCGraphicsExposures)
        mask &= ~GCGraphicsExposures;

    if (mask & GCClipXOrigin)
        v.clip_x_origin = pGC->clipOrg.x;
    if (mask & GCClipYOrigin)
        v.clip_y_origin = pGC->clipOrg.y;
    if (mask & GCClipMask)
        mask &= ~GCClipMask;    /* See ChangeClip */
    if (mask & GCDashOffset)
        v.dash_offset = pGC->dashOffset;
    if (mask & GCDashList) {
        mask &= ~GCDashList;
        if (dmxScreen->beDisplay)
            XSetDashes(dmxScreen->beDisplay, pGCPriv->gc,
                       pGC->dashOffset, (char *) pGC->dash, pGC->numInDashList);
    }
    if (mask & GCArcMode)
        v.arc_mode = pGC->arcMode;

    if (mask && dmxScreen->beDisplay) {
        XChangeGC(dmxScreen->beDisplay, pGCPriv->gc, mask, &v);
        dmxSync(dmxScreen, FALSE);
    }

    DMX_GC_FUNC_EPILOGUE(pGC);
}