예제 #1
0
파일: dmxpict.c 프로젝트: Agnesa/xserver
/** Create \a glyphSet on the backend screen number \a idx. */
int
dmxBECreateGlyphSet(int idx, GlyphSetPtr glyphSet)
{
    XRenderPictFormat *pFormat;
    DMXScreenInfo *dmxScreen = &dmxScreens[idx];
    dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
    PictFormatPtr pFmt = glyphSet->format;
    int (*oldErrorHandler) (Display *, XErrorEvent *);

    pFormat = dmxFindFormat(dmxScreen, pFmt);
    if (!pFormat) {
        return BadMatch;
    }

    dmxGlyphLastError = 0;
    oldErrorHandler = XSetErrorHandler(dmxGlyphErrorHandler);

    /* Catch when this fails */
    glyphPriv->glyphSets[idx]
        = XRenderCreateGlyphSet(dmxScreen->beDisplay, pFormat);

    XSetErrorHandler(oldErrorHandler);

    if (dmxGlyphLastError) {
        return dmxGlyphLastError;
    }

    return Success;
}
예제 #2
0
파일: dmxpict.c 프로젝트: Agnesa/xserver
/** Create a picture on the appropriate screen.  This is the actual
 *  function that creates the picture.  However, if the associated
 *  window has not yet been created due to lazy window creation, then
 *  delay the picture creation until the window is mapped. */
static Picture
dmxDoCreatePicture(PicturePtr pPicture)
{
    DrawablePtr pDraw = pPicture->pDrawable;
    ScreenPtr pScreen = pDraw->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    XRenderPictFormat *pFormat;
    Drawable draw;

    if (pPicture->pDrawable->type == DRAWABLE_WINDOW) {
        dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV((WindowPtr) (pDraw));

        if (!(draw = pWinPriv->window)) {
            /* Window has not been created yet due to the window
             * optimization.  Delay picture creation until window is
             * mapped.
             */
            pWinPriv->hasPict = TRUE;
            return 0;
        }
    }
    else {
        dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV((PixmapPtr) (pDraw));

        if (!(draw = pPixPriv->pixmap)) {
            /* FIXME: Zero width/height pixmap?? */
            return 0;
        }
    }

    /* This should not be reached if the back-end display has been
     * detached because the pWinPriv->window or the pPixPriv->pixmap
     * will be NULL; however, we add it here for completeness
     */
    if (!dmxScreen->beDisplay)
        return 0;

    pFormat = dmxFindFormat(dmxScreen, pPicture->pFormat);

    return XRenderCreatePicture(dmxScreen->beDisplay, draw, pFormat, 0, 0);
}
예제 #3
0
/** Composite a triangle fan on the appropriate screen.  For a complete
 *  description see the protocol document of the RENDER library. */
void dmxTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
	       PictFormatPtr maskFormat,
	       INT16 xSrc, INT16 ySrc,
	       int npoint, xPointFixed *points)
{
    ScreenPtr         pScreen   = pDst->pDrawable->pScreen;
    DMXScreenInfo    *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr  ps        = GetPictureScreen(pScreen);
    dmxPictPrivPtr    pSrcPriv  = DMX_GET_PICT_PRIV(pSrc);
    dmxPictPrivPtr    pDstPriv  = DMX_GET_PICT_PRIV(pDst);

    DMX_UNWRAP(TriFan, dmxScreen, ps);
#if 0
    if (ps->TriFan)
	ps->TriFan(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points);
#endif

    /* Draw trapezoids on back-end server */
    if (pDstPriv->pict) {
	XRenderPictFormat *pFormat;

	pFormat = dmxFindFormat(dmxScreen, maskFormat);
	if (!pFormat) {
	    /* FIXME: Error! */
	}

	XRenderCompositeTriFan(dmxScreen->beDisplay,
			       op,
			       pSrcPriv->pict,
			       pDstPriv->pict,
			       pFormat,
			       xSrc, ySrc,
			       (XPointFixed *)points,
			       npoint);
	dmxSync(dmxScreen, FALSE);
    }

    DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps);
}
예제 #4
0
파일: dmxpict.c 프로젝트: Agnesa/xserver
/** 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((pointer *) &pSrc,
                                stuff->src, PictureType, client, DixReadAccess);

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

        dixLookupResourceByType((pointer *) &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((pointer *) &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((pointer *) &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((pointer *) &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;
}
예제 #5
0
/** Create a Glyph Set on each screen.  Save the glyphset ID from each
 *  screen in the Glyph Set's private structure.  Fail if the format
 *  requested is not available or if the Glyph Set cannot be created on
 *  the screen. */
static int dmxProcRenderCreateGlyphSet(ClientPtr client)
{
    int  ret;
    REQUEST(xRenderCreateGlyphSetReq);

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

    if (ret == Success) {
	int              (*oldErrorHandler)(Display *, XErrorEvent *);
	GlyphSetPtr        glyphSet;
	dmxGlyphPrivPtr    glyphPriv;
	int                i;
	PictFormatPtr      pFmt;
	XRenderPictFormat *pFormat;

	/* Look up glyphSet that was just created ???? */
	/* Store glyphsets from backends in glyphSet->devPrivate ????? */
	/* Make sure we handle all errors here!! */
	
	glyphSet = SecurityLookupIDByType(client, stuff->gsid, GlyphSetType,
					  SecurityDestroyAccess);
	glyphPriv = xalloc(sizeof(dmxGlyphPrivRec));
	if (!glyphPriv) return BadAlloc;
        glyphPriv->glyphSets = NULL;
        MAXSCREENSALLOC_RETURN(glyphPriv->glyphSets, BadAlloc);
	DMX_SET_GLYPH_PRIV(glyphSet, glyphPriv);

	pFmt = SecurityLookupIDByType(client, stuff->format, PictFormatType,
				      SecurityReadAccess);

	oldErrorHandler = XSetErrorHandler(dmxGlyphErrorHandler);

	for (i = 0; i < dmxNumScreens; i++) {
	    DMXScreenInfo *dmxScreen = &dmxScreens[i];

	    if (!dmxScreen->beDisplay) {
		glyphPriv->glyphSets[i] = 0;
		continue;
	    }

	    pFormat = dmxFindFormat(dmxScreen, pFmt);
	    if (!pFormat) {
		int  j;

		/* Free the glyph sets we've allocated thus far */
		for (j = 0; j < i; j++)
		    dmxBEFreeGlyphSet(screenInfo.screens[j], glyphSet);

		/* Free the resource created by render */
		FreeResource(stuff->gsid, RT_NONE);

		ret = BadMatch;
		break;
	    }

	    /* Catch when this fails */
	    glyphPriv->glyphSets[i]
		= XRenderCreateGlyphSet(dmxScreen->beDisplay, pFormat);

	    if (dmxGlyphLastError) {
		int  j;

		/* Free the glyph sets we've allocated thus far */
		for (j = 0; j < i; j++)
		    dmxBEFreeGlyphSet(screenInfo.screens[j], glyphSet);

		/* Free the resource created by render */
		FreeResource(stuff->gsid, RT_NONE);

		ret = dmxGlyphLastError;
		break;
	    }
	}

	XSetErrorHandler(oldErrorHandler);
    }

    return ret;
}