Example #1
0
/** Render string of 16-bit \a chars (foreground only) in \a pDrawable
 *  on the back-end server associated with \a pDrawable's screen.  If
 *  the offscreen optimization is enabled, only draw when \a pDrawable
 *  is at least partially visible. */
int dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC,
		  int x, int y, int count, unsigned short *chars)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
    unsigned long  n, i;
    int            w;
    CharInfoPtr    charinfo[255];
    Drawable       draw;

    GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
	      (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
	      &n, charinfo);

    /* Calculate text width */
    w = 0;
    for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;

    if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
	DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);

	XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
		      x, y, (XChar2b *)chars, count);
	dmxSync(dmxScreen, FALSE);
    }

    return x+w;
}
Example #2
0
/** Create a graphics context on the back-end server associated /a pGC's
 *  screen. */
Bool
dmxCreateGC(GCPtr pGC)
{
    ScreenPtr pScreen = pGC->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
    Bool ret;

    DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
    if ((ret = pScreen->CreateGC(pGC))) {
        /* Save the old funcs */
        pGCPriv->funcs = pGC->funcs;
        pGCPriv->ops = NULL;

        pGC->funcs = &dmxGCFuncs;

        if (dmxScreen->beDisplay) {
            dmxBECreateGC(pScreen, pGC);
        }
        else {
            pGCPriv->gc = NULL;
        }

        /* Check for "magic special case"
         * 1. see CreateGC in dix/gc.c for more info
         * 2. see dmxChangeGC for more info
         */
        pGCPriv->msc = (!pGC->tileIsPixel && !pGC->tile.pixmap);
    }
    DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);

    return ret;
}
Example #3
0
/** Copy \a pGCSrc to \a pGCDst on the back-end server associated with
 *  \a pGCSrc's screen. */
void
dmxCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst)
{
    ScreenPtr pScreen = pGCSrc->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    dmxGCPrivPtr pGCSrcPriv = DMX_GET_GC_PRIV(pGCSrc);
    dmxGCPrivPtr pGCDstPriv = DMX_GET_GC_PRIV(pGCDst);

    DMX_GC_FUNC_PROLOGUE(pGCDst);
    pGCDst->funcs->CopyGC(pGCSrc, changes, pGCDst);

    /* Copy the GC on the back-end server */
    if (dmxScreen->beDisplay)
        XCopyGC(dmxScreen->beDisplay, pGCSrcPriv->gc, changes, pGCDstPriv->gc);

    DMX_GC_FUNC_EPILOGUE(pGCDst);
}
Example #4
0
/** Render list of disjoint segments, \a pSegs in \a pDrawable on the
 *  back-end server associated with \a pDrawable's screen.  If the
 *  offscreen optimization is enabled, only draw when \a pDrawable is at
 *  least partially visible. */
void dmxPolySegment(DrawablePtr pDrawable, GCPtr pGC,
		    int nseg, xSegment *pSegs)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
    Drawable       draw;

    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;

    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);

    XDrawSegments(dmxScreen->beDisplay, draw, pGCPriv->gc,
		  (XSegment *)pSegs, nseg);
    dmxSync(dmxScreen, FALSE);
}
Example #5
0
/** Render list of connected lines, \a pptInit in \a pDrawable on the
 *  back-end server associated with \a pDrawable's screen.  If the
 *  offscreen optimization is enabled, only draw when \a pDrawable is at
 *  least partially visible. */
void dmxPolylines(DrawablePtr pDrawable, GCPtr pGC,
		  int mode, int npt, DDXPointPtr pptInit)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
    Drawable       draw;

    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;

    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);

    XDrawLines(dmxScreen->beDisplay, draw, pGCPriv->gc,
	       (XPoint *)pptInit, npt, mode);
    dmxSync(dmxScreen, FALSE);
}
Example #6
0
/** Render list of filled rectangles, \a prectInit in \a pDrawable on
 *  the back-end server associated with \a pDrawable's screen.  If the
 *  offscreen optimization is enabled, only draw when \a pDrawable is at
 *  least partially visible. */
void dmxPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
		     int nrectFill, xRectangle *prectInit)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
    Drawable       draw;

    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;

    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);

    XFillRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
		    (XRectangle *)prectInit, nrectFill);
    dmxSync(dmxScreen, FALSE);
}
Example #7
0
/** Render list of filled arcs, \a parcs in \a pDrawable on the back-end
 *  server associated with \a pDrawable's screen.  If the offscreen
 *  optimization is enabled, only draw when \a pDrawable is at least
 *  partially visible. */
void dmxPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
		    int narcs, xArc *parcs)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
    Drawable       draw;

    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;

    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);

    XFillArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
	      (XArc *)parcs, narcs);
    dmxSync(dmxScreen, FALSE);
}
Example #8
0
/** Free the \a pGC on the back-end server. */
Bool
dmxBEFreeGC(GCPtr pGC)
{
    ScreenPtr pScreen = pGC->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);

    if (pGCPriv->gc) {
        XFreeGC(dmxScreen->beDisplay, pGCPriv->gc);
        pGCPriv->gc = NULL;
        return TRUE;
    }

    return FALSE;
}
Example #9
0
/** Render string of 16-bit \a chars (both foreground and background) in
 *  \a pDrawable on the back-end server associated with \a pDrawable's
 *  screen.  If the offscreen optimization is enabled, only draw when \a
 *  pDrawable is at least partially visible. */
void dmxImageText16(DrawablePtr pDrawable, GCPtr pGC,
		    int x, int y, int count, unsigned short *chars)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
    Drawable       draw;

    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;

    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);

    XDrawImageString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
		       x, y, (XChar2b *)chars, count);
    dmxSync(dmxScreen, FALSE);
}
Example #10
0
/** Render a filled polygons in \a pDrawable on the back-end server
 *  associated with \a pDrawable's screen.  If the offscreen
 *  optimization is enabled, only draw when \a pDrawable is at least
 *  partially visible. */
void dmxFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
		    int shape, int mode, int count, DDXPointPtr pPts)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
    Drawable       draw;

    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;

    DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);

    XFillPolygon(dmxScreen->beDisplay, draw, pGCPriv->gc,
		 (XPoint *)pPts, count, shape, mode);
    dmxSync(dmxScreen, FALSE);
}
Example #11
0
/** Destroy a GC's clip rects. */
void
dmxDestroyClip(GCPtr pGC)
{
    ScreenPtr pScreen = pGC->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);

    DMX_GC_FUNC_PROLOGUE(pGC);
    pGC->funcs->DestroyClip(pGC);

    /* Set the client clip on the back-end server to None */
    if (dmxScreen->beDisplay)
        XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);

    DMX_GC_FUNC_EPILOGUE(pGC);
}
Example #12
0
/** Copy area from \a pSrc drawable to \a pDst drawable on the back-end
 *  server associated with \a pSrc drawable's screen.  If the offscreen
 *  optimization is enabled, only copy when both \a pSrc and \a pDst are
 *  at least partially visible. */
RegionPtr dmxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
		      int srcx, int srcy, int w, int h, int dstx, int dsty)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pSrc->pScreen->myNum];
    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
    Drawable       srcDraw, dstDraw;

    if (DMX_GCOPS_OFFSCREEN(pSrc) || DMX_GCOPS_OFFSCREEN(pDst))
	return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
				 dstx, dsty, 0L);

    DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
    DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);

    XCopyArea(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
	      srcx, srcy, w, h, dstx, dsty);
    dmxSync(dmxScreen, FALSE);

    return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
			     dstx, dsty, 0L);
}
Example #13
0
/** Change the clip rects for a GC. */
void
dmxChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
{
    ScreenPtr pScreen = pGC->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
    XRectangle *pRects;
    BoxPtr pBox;
    int i, nRects;

    DMX_GC_FUNC_PROLOGUE(pGC);
    pGC->funcs->ChangeClip(pGC, type, pvalue, nrects);

    /* Set the client clip on the back-end server */
    if (!pGC->clientClip) {
        if (dmxScreen->beDisplay)
            XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
    } else {
        if (dmxScreen->beDisplay) {
            nRects = RegionNumRects((RegionPtr) pGC->clientClip);
            pRects = malloc(nRects * sizeof(*pRects));
            pBox = RegionRects((RegionPtr) pGC->clientClip);

            for (i = 0; i < nRects; i++) {
                pRects[i].x = pBox[i].x1;
                pRects[i].y = pBox[i].y1;
                pRects[i].width = pBox[i].x2 - pBox[i].x1;
                pRects[i].height = pBox[i].y2 - pBox[i].y1;
            }

            XSetClipRectangles(dmxScreen->beDisplay, pGCPriv->gc,
                               pGC->clipOrg.x, pGC->clipOrg.y,
                               pRects, nRects, Unsorted);

            free(pRects);
        }
    }

    DMX_GC_FUNC_EPILOGUE(pGC);
}
Example #14
0
/** Create the GC on the back-end server. */
void
dmxBECreateGC(ScreenPtr pScreen, GCPtr pGC)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
    int i;

    for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
        if (pGC->depth == dmxScreen->bePixmapFormats[i].depth) {
            unsigned long mask;
            XGCValues gcvals;

            mask = GCGraphicsExposures;
            gcvals.graphics_exposures = FALSE;

            /* Create GC in the back-end servers */
            pGCPriv->gc = XCreateGC(dmxScreen->beDisplay,
                                    dmxScreen->scrnDefDrawables[i],
                                    mask, &gcvals);
            break;
        }
    }
}
Example #15
0
/** Validate a graphics context, \a pGC, locally in the DMX server and
 *  recompute the composite clip, if necessary. */
void
dmxValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
{
    dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);

    DMX_GC_FUNC_PROLOGUE(pGC);
#if 0
    pGC->funcs->ValidateGC(pGC, changes, pDrawable);
#endif

    if (pDrawable->type == DRAWABLE_WINDOW ||
            pDrawable->type == DRAWABLE_PIXMAP) {
        /* Save the old ops, since we're about to change the ops in the
         * epilogue.
         */
        pGCPriv->ops = pGC->ops;
    }
    else {
        pGCPriv->ops = NULL;
    }

    /* If the client clip is different or moved OR the subwindowMode has
     * changed OR the window's clip has changed since the last
     * validation, then we need to recompute the composite clip.
     */
    if ((changes & (GCClipXOrigin |
                    GCClipYOrigin |
                    GCClipMask |
                    GCSubwindowMode)) ||
            (pDrawable->serialNumber !=
             (pGC->serialNumber & DRAWABLE_SERIAL_BITS))) {
        miComputeCompositeClip(pGC, pDrawable);
    }

    DMX_GC_FUNC_EPILOGUE(pGC);
}
Example #16
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! */
    }
}
Example #17
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);
}