/** Free the previously allocated Glyph Sets for each screen. */ static int dmxProcRenderFreeGlyphSet(ClientPtr client) { GlyphSetPtr glyphSet; REQUEST(xRenderFreeGlyphSetReq); REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq); dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset, GlyphSetType, client, DixDestroyAccess); if (glyphSet && glyphSet->refcnt == 1) { dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); int i; for (i = 0; i < dmxNumScreens; i++) { DMXScreenInfo *dmxScreen = &dmxScreens[i]; if (dmxScreen->beDisplay) { if (dmxBEFreeGlyphSet(screenInfo.screens[i], glyphSet)) dmxSync(dmxScreen, FALSE); } } MAXSCREENSFREE(glyphPriv->glyphSets); free(glyphPriv); DMX_SET_GLYPH_PRIV(glyphSet, NULL); } return dmxSaveRenderVector[stuff->renderReqType] (client); }
/** 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; }
/** Add glyphs to the Glyph Set on each screen. */ static int dmxProcRenderAddGlyphs(ClientPtr client) { int ret; REQUEST(xRenderAddGlyphsReq); ret = dmxSaveRenderVector[stuff->renderReqType] (client); if (ret == Success) { GlyphSetPtr glyphSet; dmxGlyphPrivPtr glyphPriv; int i; int nglyphs; CARD32 *gids; Glyph *gidsCopy; xGlyphInfo *gi; CARD8 *bits; int nbytes; dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset, GlyphSetType, client, DixReadAccess); glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); nglyphs = stuff->nglyphs; gids = (CARD32 *) (stuff + 1); gi = (xGlyphInfo *) (gids + nglyphs); bits = (CARD8 *) (gi + nglyphs); nbytes = ((stuff->length << 2) - sizeof(xRenderAddGlyphsReq) - (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs); gidsCopy = malloc(sizeof(*gidsCopy) * nglyphs); for (i = 0; i < nglyphs; i++) gidsCopy[i] = gids[i]; /* FIXME: Will this ever fail? */ for (i = 0; i < dmxNumScreens; i++) { DMXScreenInfo *dmxScreen = &dmxScreens[i]; if (dmxScreen->beDisplay) { XRenderAddGlyphs(dmxScreen->beDisplay, glyphPriv->glyphSets[i], gidsCopy, (XGlyphInfo *) gi, nglyphs, (char *) bits, nbytes); dmxSync(dmxScreen, FALSE); } } free(gidsCopy); } return ret; }
/** Free \a glyphSet on back-end screen number \a idx. */ Bool dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet) { dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); int idx = pScreen->myNum; DMXScreenInfo *dmxScreen = &dmxScreens[idx]; if (glyphPriv->glyphSets[idx]) { XRenderFreeGlyphSet(dmxScreen->beDisplay, glyphPriv->glyphSets[idx]); glyphPriv->glyphSets[idx] = (GlyphSet)0; return TRUE; } return FALSE; }
/** Free glyphs from the Glyph Set for each screen. */ static int dmxProcRenderFreeGlyphs(ClientPtr client) { GlyphSetPtr glyphSet; REQUEST(xRenderFreeGlyphsReq); REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq); dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset, GlyphSetType, client, DixWriteAccess); if (glyphSet) { dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet); int i; int nglyphs; Glyph *gids; nglyphs = ((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq)) >> 2; if (nglyphs) { gids = malloc(sizeof(*gids) * nglyphs); for (i = 0; i < nglyphs; i++) gids[i] = ((CARD32 *) (stuff + 1))[i]; for (i = 0; i < dmxNumScreens; i++) { DMXScreenInfo *dmxScreen = &dmxScreens[i]; if (dmxScreen->beDisplay) { XRenderFreeGlyphs(dmxScreen->beDisplay, glyphPriv->glyphSets[i], gids, nglyphs); dmxSync(dmxScreen, FALSE); } } free(gids); } } return dmxSaveRenderVector[stuff->renderReqType] (client); }
/** 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; }