#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 "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
static int dmxProcRenderCreateCursor(ClientPtr client);
static int dmxProcRenderCreateAnimCursor(ClientPtr client);
#endif
static int dmxGlyphLastError;
static int dmxGlyphErrorHandler(Display *dpy, XErrorEvent *ev)
{
dmxGlyphLastError = ev->error_code;
return 0;
}
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;
}
void dmxResetRender(void)
{
int i;
for (i = 0; i < RenderNumberRequests; i++)
ProcRenderVector[i] = dmxSaveRenderVector[i];
}
Bool dmxPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
PictureScreenPtr ps;
if (dmxShadowFB) return fbPictureInit(pScreen, formats, nformats);
if (!miPictureInit(pScreen, formats, nformats))
return FALSE;
if (!AllocatePicturePrivate(pScreen, dmxPictPrivateIndex,
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);
DMX_WRAP(TriStrip, dmxTriStrip, dmxScreen, ps);
DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps);
return TRUE;
}
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;
break;
}
return pFormat;
}
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;
}
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);
glyphPriv->glyphSets[idx]
= XRenderCreateGlyphSet(dmxScreen->beDisplay, pFormat);
XSetErrorHandler(oldErrorHandler);
if (dmxGlyphLastError) {
return dmxGlyphLastError;
}
return Success;
}
static int dmxProcRenderCreateGlyphSet(ClientPtr client)
{
int ret;
REQUEST(xRenderCreateGlyphSetReq);
ret = dmxSaveRenderVector[stuff->renderReqType](client);
if (ret == Success) {
GlyphSetPtr glyphSet;
dmxGlyphPrivPtr glyphPriv;
int i;
glyphSet = SecurityLookupIDByType(client, stuff->gsid, GlyphSetType,
DixDestroyAccess);
glyphPriv = xalloc(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;
for (j = 0; j < i; j++)
dmxBEFreeGlyphSet(screenInfo.screens[j], glyphSet);
FreeResource(stuff->gsid, RT_NONE);
return beret;
}
}
}
return ret;
}
static int dmxProcRenderFreeGlyphSet(ClientPtr client)
{
GlyphSetPtr glyphSet;
REQUEST(xRenderFreeGlyphSetReq);
REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
glyphSet = SecurityLookupIDByType(client, stuff->glyphset, GlyphSetType,
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);
xfree(glyphPriv);
DMX_SET_GLYPH_PRIV(glyphSet, NULL);
}
return dmxSaveRenderVector[stuff->renderReqType](client);
}
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;
glyphSet = SecurityLookupIDByType(client, stuff->glyphset,
GlyphSetType, 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 = xalloc(sizeof(*gidsCopy) * nglyphs);
for (i = 0; i < nglyphs; i++) gidsCopy[i] = gids[i];
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);
}
}
xfree(gidsCopy);
}
return ret;
}
static int dmxProcRenderFreeGlyphs(ClientPtr client)
{
GlyphSetPtr glyphSet;
REQUEST(xRenderFreeGlyphsReq);
REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
glyphSet = SecurityLookupIDByType(client, stuff->glyphset, GlyphSetType,
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 = xalloc(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);
}
}
xfree(gids);
}
}
return dmxSaveRenderVector[stuff->renderReqType](client);
}
static int dmxProcRenderCompositeGlyphs(ClientPtr client)
{
int ret;
REQUEST(xRenderCompositeGlyphsReq);
ret = dmxSaveRenderVector[stuff->renderReqType](client);
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;
pSrc = SecurityLookupIDByType(client, stuff->src, PictureType,
DixReadAccess);
pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
if (!pSrcPriv->pict)
return ret;
pDst = SecurityLookupIDByType(client, stuff->dst, PictureType,
DixWriteAccess);
pDstPriv = DMX_GET_PICT_PRIV(pDst);
if (!pDstPriv->pict)
return ret;
scrnNum = pDst->pDrawable->pScreen->myNum;
dmxScreen = &dmxScreens[scrnNum];
if (!dmxScreen->beDisplay)
return ret;
if (stuff->maskFormat)
pFmt = SecurityLookupIDByType(client, stuff->maskFormat,
PictFormatType, 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;
}
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;
}
}
elts = ALLOCATE_LOCAL(nelt * sizeof(XGlyphElt8));
if (!elts)
return BadAlloc;
glyphs = ALLOCATE_LOCAL(nglyph * size);
if (!glyphs) {
DEALLOCATE_LOCAL(elts);
return BadAlloc;
}
buffer = (CARD8 *)(stuff + 1);
end = (CARD8 *)stuff + (stuff->length << 2);
curGlyph = glyphs;
curElt = elts;
glyphSet = SecurityLookupIDByType(client, stuff->glyphset,
GlyphSetType, DixReadAccess);
glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
while (buffer + sizeof(xGlyphElt) < end) {
elt = (xGlyphElt *)buffer;
buffer += sizeof(xGlyphElt);
if (elt->len == 0xff) {
glyphSet = SecurityLookupIDByType(client,
*((CARD32 *)buffer),
GlyphSetType,
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);
DEALLOCATE_LOCAL(elts);
DEALLOCATE_LOCAL(glyphs);
}
return ret;
}
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,
RenderErrBase + BadPicture);
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);
}
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,
RenderErrBase + BadPicture);
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);
}
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)) {
pWinPriv->hasPict = TRUE;
return 0;
}
} else {
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV((PixmapPtr)(pDraw));
if (!(draw = pPixPriv->pixmap)) {
return 0;
}
}
if (!dmxScreen->beDisplay)
return 0;
pFormat = dmxFindFormat(dmxScreen, pPicture->pFormat);
return XRenderCreatePicture(dmxScreen->beDisplay, draw, pFormat, 0, 0);
}
void dmxCreatePictureList(WindowPtr pWindow)
{
PicturePtr pPicture = GetPictureWindow(pWindow);
while (pPicture) {
dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
pPictPriv->pict = dmxDoCreatePicture(pPicture);
pPicture = pPicture->pNext;
}
}
int dmxBECreatePicture(PicturePtr pPicture)
{
dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
pPictPriv->pict = dmxDoCreatePicture(pPicture);
dmxValidatePicture(pPicture, (1 << (CPLastBit+1)) - 1);
return Success;
}
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
pPictPriv->pict = dmxDoCreatePicture(pPicture);
pPictPriv->savedMask = 0;
DMX_WRAP(CreatePicture, dmxCreatePicture, dmxScreen, ps);
return ret;
}
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;
}
Bool dmxDestroyPictureList(WindowPtr pWindow)
{
PicturePtr pPicture = GetPictureWindow(pWindow);
Bool ret = FALSE;
while (pPicture) {
ret |= dmxBEFreePicture(pPicture);
pPicture = pPicture->pNext;
}
return ret;
}
void dmxDestroyPicture(PicturePtr pPicture)
{
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
PictureScreenPtr ps = GetPictureScreen(pScreen);
DMX_UNWRAP(DestroyPicture, dmxScreen, ps);
if (dmxBEFreePicture(pPicture))
dmxSync(dmxScreen, FALSE);
#if 1
if (ps->DestroyPicture)
ps->DestroyPicture(pPicture);
#endif
DMX_WRAP(DestroyPicture, dmxDestroyPicture, dmxScreen, ps);
}
int dmxChangePictureClip(PicturePtr pPicture, int clipType,
pointer 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
if (pPictPriv->pict) {
if (clipType == CT_NONE) {
XFixesSetPictureClipRegion(dmxScreen->beDisplay,
pPictPriv->pict, 0, 0, None);
} else if (pPicture->clientClip) {
RegionPtr pClip = pPicture->clientClip;
BoxPtr pBox = REGION_RECTS(pClip);
int nBox = REGION_NUM_RECTS(pClip);
XRectangle *pRects;
XRectangle *pRect;
int nRects;
nRects = nBox;
pRects = pRect = xalloc(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);
xfree(pRects);
} else {
XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
pPictPriv->pict,
0, 0, NULL, 0);
}
dmxSync(dmxScreen, FALSE);
} else {
}
DMX_WRAP(ChangePictureClip, dmxChangePictureClip, dmxScreen, ps);
return Success;
}
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
if (pPictPriv->pict) {
XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
pPictPriv->pict,
0, 0, NULL, 0);
dmxSync(dmxScreen, FALSE);
} else {
}
DMX_WRAP(DestroyPictureClip, dmxDestroyPictureClip, dmxScreen, ps);
}
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
pPictPriv->savedMask |= mask;
DMX_WRAP(ChangePicture, dmxChangePicture, dmxScreen, ps);
}
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);
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 {
return;
}
} 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;
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 & CPDither)
attribs.dither = pPicture->dither;
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);
}
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
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);
}
void dmxGlyphs(CARD8 op,
PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc,
int nlists, GlyphListPtr lists, GlyphPtr *glyphs)
{
}
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
if (pPictPriv->pict) {
XRenderFillRectangles(dmxScreen->beDisplay,
op,
pPictPriv->pict,
(XRenderColor *)color,
(XRectangle *)rects,
nRect);
dmxSync(dmxScreen, FALSE);
}
DMX_WRAP(CompositeRects, dmxCompositeRects, dmxScreen, ps);
}
Bool dmxInitIndexed(ScreenPtr pScreen, PictFormatPtr pFormat)
{
return TRUE;
}
void dmxCloseIndexed(ScreenPtr pScreen, PictFormatPtr pFormat)
{
}
void dmxUpdateIndexed(ScreenPtr pScreen, PictFormatPtr pFormat,
int ndef, xColorItem *pdef)
{
}
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
if (pDstPriv->pict) {
XRenderPictFormat *pFormat;
pFormat = dmxFindFormat(dmxScreen, maskFormat);
if (!pFormat) {
}
XRenderCompositeTrapezoids(dmxScreen->beDisplay,
op,
pSrcPriv->pict,
pDstPriv->pict,
pFormat,
xSrc, ySrc,
(XTrapezoid *)traps,
ntrap);
dmxSync(dmxScreen, FALSE);
}
DMX_WRAP(Trapezoids, dmxTrapezoids, dmxScreen, ps);
}
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
if (pDstPriv->pict) {
XRenderPictFormat *pFormat;
pFormat = dmxFindFormat(dmxScreen, maskFormat);
if (!pFormat) {
}
XRenderCompositeTriangles(dmxScreen->beDisplay,
op,
pSrcPriv->pict,
pDstPriv->pict,
pFormat,
xSrc, ySrc,
(XTriangle *)tris,
ntri);
dmxSync(dmxScreen, FALSE);
}
DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps);
}
void dmxTriStrip(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(TriStrip, dmxScreen, ps);
#if 0
if (ps->TriStrip)
ps->TriStrip(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points);
#endif
if (pDstPriv->pict) {
XRenderPictFormat *pFormat;
pFormat = dmxFindFormat(dmxScreen, maskFormat);
if (!pFormat) {
}
XRenderCompositeTriStrip(dmxScreen->beDisplay,
op,
pSrcPriv->pict,
pDstPriv->pict,
pFormat,
xSrc, ySrc,
(XPointFixed *)points,
npoint);
dmxSync(dmxScreen, FALSE);
}
DMX_WRAP(TriStrip, dmxTriStrip, dmxScreen, ps);
}
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
if (pDstPriv->pict) {
XRenderPictFormat *pFormat;
pFormat = dmxFindFormat(dmxScreen, maskFormat);
if (!pFormat) {
}
XRenderCompositeTriFan(dmxScreen->beDisplay,
op,
pSrcPriv->pict,
pDstPriv->pict,
pFormat,
xSrc, ySrc,
(XPointFixed *)points,
npoint);
dmxSync(dmxScreen, FALSE);
}
DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps);
}