12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277 |
- /*
- * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
- /*
- * Authors:
- * Kevin E. Martin <kem@redhat.com>
- *
- */
- /** \file
- * Provide support for the RENDER extension (version 0.8).
- */
- #ifdef HAVE_DMX_CONFIG_H
- #include <dmx-config.h>
- #endif
- #include "dmx.h"
- #include "dmxsync.h"
- #include "dmxpict.h"
- #include "dmxwindow.h"
- #include "dmxpixmap.h"
- #include "fb.h"
- #include "pixmapstr.h"
- #include "dixstruct.h"
- #include <X11/extensions/render.h>
- #include <X11/extensions/renderproto.h>
- #include <X11/extensions/Xfixes.h>
- #include "picture.h"
- #include "picturestr.h"
- #include "mipict.h"
- #include "fbpict.h"
- extern int RenderErrBase;
- extern int (*ProcRenderVector[RenderNumberRequests]) (ClientPtr);
- static int (*dmxSaveRenderVector[RenderNumberRequests]) (ClientPtr);
- static int dmxProcRenderCreateGlyphSet(ClientPtr client);
- static int dmxProcRenderFreeGlyphSet(ClientPtr client);
- static int dmxProcRenderAddGlyphs(ClientPtr client);
- static int dmxProcRenderFreeGlyphs(ClientPtr client);
- static int dmxProcRenderCompositeGlyphs(ClientPtr client);
- static int dmxProcRenderSetPictureTransform(ClientPtr client);
- static int dmxProcRenderSetPictureFilter(ClientPtr client);
- #if 0
- /* FIXME: Not (yet) supported */
- static int dmxProcRenderCreateCursor(ClientPtr client);
- static int dmxProcRenderCreateAnimCursor(ClientPtr client);
- #endif
- /** Catch errors that might occur when allocating Glyph Sets. Errors
- * are saved in dmxGlyphLastError for later handling. */
- static int dmxGlyphLastError;
- static int
- dmxGlyphErrorHandler(Display * dpy, XErrorEvent * ev)
- {
- dmxGlyphLastError = ev->error_code;
- return 0;
- }
- /** Initialize the Proc Vector for the RENDER extension. The functions
- * here cannot be handled by the mi layer RENDER hooks either because
- * the required information is no longer available when it reaches the
- * mi layer or no mi layer hooks exist. This function is called from
- * InitOutput() since it should be initialized only once per server
- * generation. */
- void
- dmxInitRender(void)
- {
- int i;
- for (i = 0; i < RenderNumberRequests; i++)
- dmxSaveRenderVector[i] = ProcRenderVector[i];
- ProcRenderVector[X_RenderCreateGlyphSet]
- = dmxProcRenderCreateGlyphSet;
- ProcRenderVector[X_RenderFreeGlyphSet]
- = dmxProcRenderFreeGlyphSet;
- ProcRenderVector[X_RenderAddGlyphs]
- = dmxProcRenderAddGlyphs;
- ProcRenderVector[X_RenderFreeGlyphs]
- = dmxProcRenderFreeGlyphs;
- ProcRenderVector[X_RenderCompositeGlyphs8]
- = dmxProcRenderCompositeGlyphs;
- ProcRenderVector[X_RenderCompositeGlyphs16]
- = dmxProcRenderCompositeGlyphs;
- ProcRenderVector[X_RenderCompositeGlyphs32]
- = dmxProcRenderCompositeGlyphs;
- ProcRenderVector[X_RenderSetPictureTransform]
- = dmxProcRenderSetPictureTransform;
- ProcRenderVector[X_RenderSetPictureFilter]
- = dmxProcRenderSetPictureFilter;
- }
- /** Reset the Proc Vector for the RENDER extension back to the original
- * functions. This function is called from dmxCloseScreen() during the
- * server reset (only for screen #0). */
- void
- dmxResetRender(void)
- {
- int i;
- for (i = 0; i < RenderNumberRequests; i++)
- ProcRenderVector[i] = dmxSaveRenderVector[i];
- }
- /** Initialize the RENDER extension, allocate the picture privates and
- * wrap mi function hooks. If the shadow frame buffer is used, then
- * call the appropriate fb initialization function. */
- Bool
- dmxPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
- {
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- PictureScreenPtr ps;
- if (!miPictureInit(pScreen, formats, nformats))
- return FALSE;
- if (!dixRegisterPrivateKey
- (&dmxPictPrivateKeyRec, PRIVATE_PICTURE, sizeof(dmxPictPrivRec)))
- return FALSE;
- ps = GetPictureScreen(pScreen);
- DMX_WRAP(CreatePicture, dmxCreatePicture, dmxScreen, ps);
- DMX_WRAP(DestroyPicture, dmxDestroyPicture, dmxScreen, ps);
- DMX_WRAP(ChangePictureClip, dmxChangePictureClip, dmxScreen, ps);
- DMX_WRAP(DestroyPictureClip, dmxDestroyPictureClip, dmxScreen, ps);
- DMX_WRAP(ChangePicture, dmxChangePicture, dmxScreen, ps);
- DMX_WRAP(ValidatePicture, dmxValidatePicture, dmxScreen, ps);
- DMX_WRAP(Composite, dmxComposite, dmxScreen, ps);
- DMX_WRAP(Glyphs, dmxGlyphs, dmxScreen, ps);
- DMX_WRAP(CompositeRects, dmxCompositeRects, dmxScreen, ps);
- DMX_WRAP(Trapezoids, dmxTrapezoids, dmxScreen, ps);
- DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps);
- return TRUE;
- }
- /** Find the appropriate format on the requested screen given the
- * internal format requested. The list of formats is searched
- * sequentially as the XRenderFindFormat() function does not always
- * find the appropriate format when a specific format is requested. */
- static XRenderPictFormat *
- dmxFindFormat(DMXScreenInfo * dmxScreen, PictFormatPtr pFmt)
- {
- XRenderPictFormat *pFormat = NULL;
- int i = 0;
- if (!pFmt || !dmxScreen->beDisplay)
- return pFormat;
- while (1) {
- pFormat = XRenderFindFormat(dmxScreen->beDisplay, 0, 0, i++);
- if (!pFormat)
- break;
- if (pFormat->type != pFmt->type)
- continue;
- if (pFormat->depth != pFmt->depth)
- continue;
- if (pFormat->direct.red != pFmt->direct.red)
- continue;
- if (pFormat->direct.redMask != pFmt->direct.redMask)
- continue;
- if (pFormat->direct.green != pFmt->direct.green)
- continue;
- if (pFormat->direct.greenMask != pFmt->direct.greenMask)
- continue;
- if (pFormat->direct.blue != pFmt->direct.blue)
- continue;
- if (pFormat->direct.blueMask != pFmt->direct.blueMask)
- continue;
- if (pFormat->direct.alpha != pFmt->direct.alpha)
- continue;
- if (pFormat->direct.alphaMask != pFmt->direct.alphaMask)
- continue;
- /* We have a match! */
- break;
- }
- return pFormat;
- }
- /** 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;
- }
- /** 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;
- }
- /** 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) {
- GlyphSetPtr glyphSet;
- dmxGlyphPrivPtr glyphPriv;
- int i;
- /* Look up glyphSet that was just created ???? */
- /* Store glyphsets from backends in glyphSet->devPrivate ????? */
- /* Make sure we handle all errors here!! */
- dixLookupResourceByType((void **) &glyphSet,
- stuff->gsid, GlyphSetType,
- client, DixDestroyAccess);
- glyphPriv = malloc(sizeof(dmxGlyphPrivRec));
- if (!glyphPriv)
- return BadAlloc;
- glyphPriv->glyphSets = NULL;
- MAXSCREENSALLOC_RETURN(glyphPriv->glyphSets, BadAlloc);
- DMX_SET_GLYPH_PRIV(glyphSet, glyphPriv);
- for (i = 0; i < dmxNumScreens; i++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[i];
- int beret;
- if (!dmxScreen->beDisplay) {
- glyphPriv->glyphSets[i] = 0;
- continue;
- }
- if ((beret = dmxBECreateGlyphSet(i, glyphSet)) != Success) {
- 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);
- return beret;
- }
- }
- }
- return ret;
- }
- /** Free the previously allocated Glyph Sets for each screen. */
- static int
- dmxProcRenderFreeGlyphSet(ClientPtr client)
- {
- GlyphSetPtr glyphSet;
- REQUEST(xRenderFreeGlyphSetReq);
- REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
- dixLookupResourceByType((void **) &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);
- }
- /** 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((void **) &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 glyphs from the Glyph Set for each screen. */
- static int
- dmxProcRenderFreeGlyphs(ClientPtr client)
- {
- GlyphSetPtr glyphSet;
- REQUEST(xRenderFreeGlyphsReq);
- REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
- dixLookupResourceByType((void **) &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((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;
- }
- /** Set the picture transform on each screen. */
- static int
- dmxProcRenderSetPictureTransform(ClientPtr client)
- {
- DMXScreenInfo *dmxScreen;
- PicturePtr pPicture;
- dmxPictPrivPtr pPictPriv;
- XTransform xform;
- REQUEST(xRenderSetPictureTransformReq);
- REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
- VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess);
- /* For the following to work with PanoramiX, it assumes that Render
- * wraps the ProcRenderVector after dmxRenderInit has been called.
- */
- dmxScreen = &dmxScreens[pPicture->pDrawable->pScreen->myNum];
- pPictPriv = DMX_GET_PICT_PRIV(pPicture);
- if (pPictPriv->pict) {
- xform.matrix[0][0] = stuff->transform.matrix11;
- xform.matrix[0][1] = stuff->transform.matrix12;
- xform.matrix[0][2] = stuff->transform.matrix13;
- xform.matrix[1][0] = stuff->transform.matrix21;
- xform.matrix[1][1] = stuff->transform.matrix22;
- xform.matrix[1][2] = stuff->transform.matrix23;
- xform.matrix[2][0] = stuff->transform.matrix31;
- xform.matrix[2][1] = stuff->transform.matrix32;
- xform.matrix[2][2] = stuff->transform.matrix33;
- XRenderSetPictureTransform(dmxScreen->beDisplay,
- pPictPriv->pict, &xform);
- dmxSync(dmxScreen, FALSE);
- }
- return dmxSaveRenderVector[stuff->renderReqType] (client);
- }
- /** Set the picture filter on each screen. */
- static int
- dmxProcRenderSetPictureFilter(ClientPtr client)
- {
- DMXScreenInfo *dmxScreen;
- PicturePtr pPicture;
- dmxPictPrivPtr pPictPriv;
- char *filter;
- XFixed *params;
- int nparams;
- REQUEST(xRenderSetPictureFilterReq);
- REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
- VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess);
- /* For the following to work with PanoramiX, it assumes that Render
- * wraps the ProcRenderVector after dmxRenderInit has been called.
- */
- dmxScreen = &dmxScreens[pPicture->pDrawable->pScreen->myNum];
- pPictPriv = DMX_GET_PICT_PRIV(pPicture);
- if (pPictPriv->pict) {
- filter = (char *) (stuff + 1);
- params = (XFixed *) (filter + ((stuff->nbytes + 3) & ~3));
- nparams = ((XFixed *) stuff + client->req_len) - params;
- XRenderSetPictureFilter(dmxScreen->beDisplay,
- pPictPriv->pict, filter, params, nparams);
- dmxSync(dmxScreen, FALSE);
- }
- return dmxSaveRenderVector[stuff->renderReqType] (client);
- }
- /** 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);
- }
- /** Create a list of pictures. This function is called by
- * dmxCreateAndRealizeWindow() during the lazy window creation
- * realization process. It creates the entire list of pictures that
- * are associated with the given window. */
- void
- dmxCreatePictureList(WindowPtr pWindow)
- {
- PicturePtr pPicture = GetPictureWindow(pWindow);
- while (pPicture) {
- dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
- /* Create the picture for this window */
- pPictPriv->pict = dmxDoCreatePicture(pPicture);
- /* ValidatePicture takes care of the state changes */
- pPicture = pPicture->pNext;
- }
- }
- /** Create \a pPicture on the backend. */
- int
- dmxBECreatePicture(PicturePtr pPicture)
- {
- dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
- /* Create picutre on BE */
- pPictPriv->pict = dmxDoCreatePicture(pPicture);
- /* Flush changes to the backend server */
- dmxValidatePicture(pPicture, (1 << (CPLastBit + 1)) - 1);
- return Success;
- }
- /** Create a picture. This function handles the CreatePicture
- * unwrapping/wrapping and calls dmxDoCreatePicture to actually create
- * the picture on the appropriate screen. */
- int
- dmxCreatePicture(PicturePtr pPicture)
- {
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
- int ret = Success;
- DMX_UNWRAP(CreatePicture, dmxScreen, ps);
- #if 1
- if (ps->CreatePicture)
- ret = ps->CreatePicture(pPicture);
- #endif
- /* Create picture on back-end server */
- pPictPriv->pict = dmxDoCreatePicture(pPicture);
- pPictPriv->savedMask = 0;
- DMX_WRAP(CreatePicture, dmxCreatePicture, dmxScreen, ps);
- return ret;
- }
- /** Destroy \a pPicture on the back-end server. */
- Bool
- dmxBEFreePicture(PicturePtr pPicture)
- {
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
- if (pPictPriv->pict) {
- XRenderFreePicture(dmxScreen->beDisplay, pPictPriv->pict);
- pPictPriv->pict = (Picture) 0;
- return TRUE;
- }
- return FALSE;
- }
- /** Destroy a list of pictures that are associated with the window that
- * is being destroyed. This function is called by #dmxDestroyWindow().
- * */
- Bool
- dmxDestroyPictureList(WindowPtr pWindow)
- {
- PicturePtr pPicture = GetPictureWindow(pWindow);
- Bool ret = FALSE;
- while (pPicture) {
- ret |= dmxBEFreePicture(pPicture);
- pPicture = pPicture->pNext;
- }
- return ret;
- }
- /** Destroy a picture. This function calls the wrapped function that
- * frees the resources in the DMX server associated with this
- * picture. */
- void
- dmxDestroyPicture(PicturePtr pPicture)
- {
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- DMX_UNWRAP(DestroyPicture, dmxScreen, ps);
- /* Destroy picture on back-end server */
- if (dmxBEFreePicture(pPicture))
- dmxSync(dmxScreen, FALSE);
- #if 1
- if (ps->DestroyPicture)
- ps->DestroyPicture(pPicture);
- #endif
- DMX_WRAP(DestroyPicture, dmxDestroyPicture, dmxScreen, ps);
- }
- /** 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;
- }
- /** Destroy the picture's list of clip rectangles. */
- void
- dmxDestroyPictureClip(PicturePtr pPicture)
- {
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
- DMX_UNWRAP(DestroyPictureClip, dmxScreen, ps);
- #if 1
- if (ps->DestroyPictureClip)
- ps->DestroyPictureClip(pPicture);
- #endif
- /* Destroy picture clip rects on back-end server */
- if (pPictPriv->pict) {
- XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
- pPictPriv->pict, 0, 0, NULL, 0);
- dmxSync(dmxScreen, FALSE);
- }
- else {
- /* FIXME: Handle destroying clip region when offscreen */
- }
- DMX_WRAP(DestroyPictureClip, dmxDestroyPictureClip, dmxScreen, ps);
- }
- /** Change the attributes of the pictures. If the picture has not yet
- * been created due to lazy window creation, save the mask so that it
- * can be used to appropriately initialize the picture's attributes
- * when it is created later. */
- void
- dmxChangePicture(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(ChangePicture, dmxScreen, ps);
- #if 1
- if (ps->ChangePicture)
- ps->ChangePicture(pPicture, mask);
- #endif
- /* Picture attribute changes are handled in ValidatePicture */
- pPictPriv->savedMask |= mask;
- DMX_WRAP(ChangePicture, dmxChangePicture, dmxScreen, ps);
- }
- /** 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);
- }
- /** Composite a picture on the appropriate screen by combining the
- * specified rectangle of the transformed src and mask operands with
- * the specified rectangle of the dst using op as the compositing
- * operator. For a complete description see the protocol document of
- * the RENDER library. */
- void
- dmxComposite(CARD8 op,
- PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
- INT16 xSrc, INT16 ySrc,
- INT16 xMask, INT16 yMask,
- INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
- {
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
- dmxPictPrivPtr pMaskPriv = NULL;
- dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst);
- if (pMask)
- pMaskPriv = DMX_GET_PICT_PRIV(pMask);
- DMX_UNWRAP(Composite, dmxScreen, ps);
- #if 0
- if (ps->Composite)
- ps->Composite(op, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
- #endif
- /* Composite on back-end server */
- if (pSrcPriv->pict && pDstPriv->pict &&
- ((pMaskPriv && pMaskPriv->pict) || !pMaskPriv)) {
- XRenderComposite(dmxScreen->beDisplay,
- op,
- pSrcPriv->pict,
- pMaskPriv ? pMaskPriv->pict : None,
- pDstPriv->pict,
- xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
- dmxSync(dmxScreen, FALSE);
- }
- DMX_WRAP(Composite, dmxComposite, dmxScreen, ps);
- }
- /** Null function to catch when/if RENDER calls lower level mi hooks.
- * Compositing glyphs is handled by dmxProcRenderCompositeGlyphs().
- * This function should never be called. */
- void
- dmxGlyphs(CARD8 op,
- PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc, INT16 ySrc,
- int nlists, GlyphListPtr lists, GlyphPtr * glyphs)
- {
- /* This won't work, so we need to wrap ProcRenderCompositeGlyphs */
- }
- /** Fill a rectangle on the appropriate screen by combining the color
- * with the dest picture in the area specified by the list of
- * rectangles. For a complete description see the protocol document of
- * the RENDER library. */
- void
- dmxCompositeRects(CARD8 op,
- PicturePtr pDst,
- xRenderColor * color, int nRect, xRectangle *rects)
- {
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pDst);
- DMX_UNWRAP(CompositeRects, dmxScreen, ps);
- #if 0
- if (ps->CompositeRects)
- ps->CompositeRects(op, pDst, color, nRect, rects);
- #endif
- /* CompositeRects on back-end server */
- if (pPictPriv->pict) {
- XRenderFillRectangles(dmxScreen->beDisplay,
- op,
- pPictPriv->pict,
- (XRenderColor *) color,
- (XRectangle *) rects, nRect);
- dmxSync(dmxScreen, FALSE);
- }
- DMX_WRAP(CompositeRects, dmxCompositeRects, dmxScreen, ps);
- }
- /** Indexed color visuals are not yet supported. */
- Bool
- dmxInitIndexed(ScreenPtr pScreen, PictFormatPtr pFormat)
- {
- return TRUE;
- }
- /** Indexed color visuals are not yet supported. */
- void
- dmxCloseIndexed(ScreenPtr pScreen, PictFormatPtr pFormat)
- {
- }
- /** Indexed color visuals are not yet supported. */
- void
- dmxUpdateIndexed(ScreenPtr pScreen, PictFormatPtr pFormat,
- int ndef, xColorItem * pdef)
- {
- }
- /** Composite a list of trapezoids on the appropriate screen. For a
- * complete description see the protocol document of the RENDER
- * library. */
- void
- dmxTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps)
- {
- 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(Trapezoids, dmxScreen, ps);
- #if 0
- if (ps->Trapezoids)
- ps->Trapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, *traps);
- #endif
- /* Draw trapezoids on back-end server */
- if (pDstPriv->pict) {
- XRenderPictFormat *pFormat;
- pFormat = dmxFindFormat(dmxScreen, maskFormat);
- if (!pFormat) {
- /* FIXME: Error! */
- }
- XRenderCompositeTrapezoids(dmxScreen->beDisplay,
- op,
- pSrcPriv->pict,
- pDstPriv->pict,
- pFormat,
- xSrc, ySrc, (XTrapezoid *) traps, ntrap);
- dmxSync(dmxScreen, FALSE);
- }
- DMX_WRAP(Trapezoids, dmxTrapezoids, dmxScreen, ps);
- }
- /** Composite a list of triangles on the appropriate screen. For a
- * complete description see the protocol document of the RENDER
- * library. */
- void
- dmxTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc, INT16 ySrc, int ntri, xTriangle * tris)
- {
- 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(Triangles, dmxScreen, ps);
- #if 0
- if (ps->Triangles)
- ps->Triangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, *tris);
- #endif
- /* Draw trapezoids on back-end server */
- if (pDstPriv->pict) {
- XRenderPictFormat *pFormat;
- pFormat = dmxFindFormat(dmxScreen, maskFormat);
- if (!pFormat) {
- /* FIXME: Error! */
- }
- XRenderCompositeTriangles(dmxScreen->beDisplay,
- op,
- pSrcPriv->pict,
- pDstPriv->pict,
- pFormat,
- xSrc, ySrc, (XTriangle *) tris, ntri);
- dmxSync(dmxScreen, FALSE);
- }
- DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps);
- }
|