xserver/render mipict.c, 1.25, 1.26 picture.c, 1.41, 1.42 render.c, 1.34, 1.35
Lars Knoll <xserver-commit-u7BhqnqprCWvj1b/[email protected]> Wed, 29 Jun 2005 04:57:21 -0700 (PDT)
| Newsgroups | gmane.comp.freedesktop.xserver.cvs |
|---|---|
| Message-ID | <[email protected]> |
Committed by: lars
Update of /cvs/xserver/xserver/render
In directory gabe:/tmp/cvs-serv16798/render
Modified Files:
mipict.c picture.c render.c
Log Message:
Add support for gradients and solid fills to Render.
Changed the semantics of the Convolution filter a
bit. It now doesn't try to normalize the filter
values but leaves this to the client. This gives
more reasonable behaviour in the limit where the filter
parameters sum up to 0.
Index: mipict.c
===================================================================
RCS file: /cvs/xserver/xserver/render/mipict.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- mipict.c 13 Jun 2005 08:00:59 -0000 1.25
+++ mipict.c 29 Jun 2005 11:57:18 -0000 1.26
@@ -344,7 +344,7 @@
int dy)
{
/* XXX what to do with clipping from transformed pictures? */
- if (pPicture->transform)
+ if (pPicture->transform || !pPicture->pDrawable)
return TRUE;
/* XXX what to do with clipping from pictures with filter that touch
@@ -385,7 +385,12 @@
CARD16 height)
{
DrawablePtr pDrawable = pPicture->pDrawable;
- ScreenPtr pScreen = pDrawable->pScreen;
+ ScreenPtr pScreen;
+
+ if (!pDrawable)
+ return;
+
+ pScreen = pDrawable->pScreen;
if (pScreen->SourceValidate)
{
@@ -590,9 +595,14 @@
Bool
miIsSolidAlpha (PicturePtr pSrc)
{
- ScreenPtr pScreen = pSrc->pDrawable->pScreen;
+ ScreenPtr pScreen;
char line[1];
+ if (!pSrc->pDrawable)
+ return FALSE;
+
+ pScreen = pSrc->pDrawable->pScreen;
+
/* Alpha-only */
if (PICT_FORMAT_TYPE (pSrc->format) != PICT_TYPE_A)
return FALSE;
Index: picture.c
===================================================================
RCS file: /cvs/xserver/xserver/render/picture.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- picture.c 15 Jun 2005 12:13:57 -0000 1.41
+++ picture.c 29 Jun 2005 11:57:18 -0000 1.42
@@ -712,6 +712,7 @@
pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
+ pPicture->pSourcePict = 0;
}
PicturePtr
@@ -795,6 +796,301 @@
return pPicture;
}
+static CARD32 xRenderColorToCard32(xRenderColor c)
+{
+ return
+ (c.alpha >> 8 << 24) |
+ (c.red >> 8 << 16) |
+ (c.green & 0xff00) |
+ (c.blue >> 8);
+}
+
+static uint premultiply(uint x)
+{
+ uint a = x >> 24;
+ uint t = (x & 0xff00ff) * a;
+ t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff) * a;
+ x = (x + ((x >> 8) & 0xff) + 0x80);
+ x &= 0xff00;
+ x |= t | (a << 24);
+ return x;
+}
+
+static uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b)
+{
+ CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
+ t >>= 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
+ x &= 0xff00ff00;
+ x |= t;
+ return x;
+}
+
+static void initGradientColorTable(SourcePictPtr pGradient, int *error)
+{
+ int begin_pos, end_pos;
+ xFixed incr, dpos;
+ int pos, current_stop;
+ PictGradientStopPtr stops = pGradient->linear.stops;
+ int nstops = pGradient->linear.nstops;
+
+ // The position where the gradient begins and ends
+ begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+ end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+
+ pos = 0; // The position in the color table.
+
+ // Up to first point
+ while (pos <= begin_pos) {
+ pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
+ ++pos;
+ }
+
+ incr = (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; // the double increment.
+ dpos = incr * pos; // The position in terms of 0-1.
+
+ current_stop = 0; // We always interpolate between current and current + 1.
+
+ // Gradient area
+ while (pos < end_pos) {
+ uint current_color = xRenderColorToCard32(stops[current_stop].color);
+ uint next_color = xRenderColorToCard32(stops[current_stop + 1].color);
+
+ int dist = (int)(256*(dpos - stops[current_stop].x)
+ / (stops[current_stop+1].x - stops[current_stop].x));
+ int idist = 256 - dist;
+
+ pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+
+ ++pos;
+ dpos += incr;
+
+ if (dpos > stops[current_stop + 1].x)
+ ++current_stop;
+ }
+
+ // After last point
+ while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
+ pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
+ ++pos;
+ }
+}
+
+static void initGradient(SourcePictPtr pGradient, int stopCount,
+ xFixed *stopPoints, xRenderColor *stopColors, int *error)
+{
+ int i;
+ xFixed dpos;
+
+ if (stopCount <= 0) {
+ *error = BadValue;
+ return;
+ }
+
+ dpos = -1;
+ for (i = 0; i < stopCount; ++i) {
+ if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
+ *error = BadValue;
+ return;
+ }
+ dpos = stopPoints[i];
+ }
+
+ pGradient->linear.stops = xalloc(stopCount*sizeof(PictGradientStop));
+ if (!pGradient->linear.stops) {
+ *error = BadAlloc;
+ return;
+ }
+
+ pGradient->linear.nstops = stopCount;
+
+ for (i = 0; i < stopCount; ++i) {
+ pGradient->linear.stops[i].x = stopPoints[i];
+ pGradient->linear.stops[i].color = stopColors[i];
+ }
+ initGradientColorTable(pGradient, error);
+}
+
+static PicturePtr createSourcePicture(void)
+{
+ PicturePtr pPicture;
+ pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
+ pPicture->pDrawable = 0;
+ pPicture->pFormat = 0;
+ pPicture->pNext = 0;
+
+ SetPictureToDefaults(pPicture);
+ return pPicture;
+}
+
+PicturePtr
+CreateSolidPicture (Picture pid, xRenderColor *color, int *error)
+{
+ PicturePtr pPicture;
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictSolidFill));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+ pPicture->pSourcePict->type = SourcePictTypeSolidFill;
+ pPicture->pSourcePict->solidFill.color = premultiply(xRenderColorToCard32(*color));
+ return pPicture;
+}
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+ if (p1->x == p2->x && p1->y == p2->y) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+
+ pPicture->pSourcePict->linear.type = SourcePictTypeLinear;
+ pPicture->pSourcePict->linear.p1 = *p1;
+ pPicture->pSourcePict->linear.p2 = *p2;
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ xfree(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+#define FixedToDouble(x) ((x)/65536.)
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer,
+ xFixed innerRadius, xFixed outerRadius,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+ PictRadialGradient *radial;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+ {
+ double dx = (double)(inner->x - outer->x);
+ double dy = (double)(inner->y - outer->y);
+ if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
+ *error = BadValue;
+ return 0;
+ }
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+ radial = &pPicture->pSourcePict->radial;
+
+ radial->type = SourcePictTypeRadial;
+ {
+ double x = (double)innerRadius / (double)outerRadius;
+ radial->dx = (outer->x - inner->x);
+ radial->dy = (outer->y - inner->y);
+ radial->fx = (inner->x) - x*radial->dx;
+ radial->fy = (inner->y) - x*radial->dy;
+ radial->m = 1./(1+x);
+ radial->b = -x*radial->m;
+ radial->dx /= 65536.;
+ radial->dy /= 65536.;
+ radial->fx /= 65536.;
+ radial->fy /= 65536.;
+ x = outerRadius/65536.;
+ radial->a = x*x - radial->dx*radial->dx - radial->dy*radial->dy;
+ }
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ xfree(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid, xPointFixed *center, xFixed angle,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictConicalGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+
+ pPicture->pSourcePict->conical.type = SourcePictTypeConical;
+ pPicture->pSourcePict->conical.center = *center;
+ pPicture->pSourcePict->conical.angle = angle;
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ xfree(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
#define NEXT_PTR(_type) ((_type) ulist++->ptr)
@@ -806,8 +1102,8 @@
DevUnion *ulist,
ClientPtr client)
{
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
+ ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
+ PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0;
BITS32 index2;
int error = 0;
BITS32 maskQ;
@@ -825,7 +1121,7 @@
{
unsigned int newr;
newr = NEXT_VAL(unsigned int);
- if (newr <= xTrue)
+ if (newr <= RepeatReflect)
pPicture->repeat = newr;
else
{
@@ -893,6 +1189,8 @@
Pixmap pid;
PixmapPtr pPixmap;
int clipType;
+ if (!pScreen)
+ return BadDrawable;
if (vlist)
{
@@ -1019,7 +1317,8 @@
break;
}
}
- (*ps->ChangePicture) (pPicture, maskQ);
+ if (ps)
+ (*ps->ChangePicture) (pPicture, maskQ);
return error;
}
@@ -1103,9 +1402,8 @@
{ 0x00000, xFixed1, 0x00000 },
{ 0x00000, 0x00000, xFixed1 },
} };
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- int result;
+ PictureScreenPtr ps = pPicture->pDrawable ? GetPictureScreen(pPicture->pDrawable->pScreen) : 0;
+ int result = 0;
if (transform && memcmp (transform, &identity, sizeof (PictTransform)) == 0)
transform = 0;
@@ -1129,6 +1427,7 @@
}
}
pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ if (ps)
result = (*ps->ChangePictureTransform) (pPicture, transform);
return result;
}
@@ -1136,7 +1435,7 @@
static void
ValidateOnePicture (PicturePtr pPicture)
{
- if (pPicture->serialNumber != pPicture->pDrawable->serialNumber)
+ if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber)
{
PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
@@ -1162,35 +1461,43 @@
if (--pPicture->refcnt == 0)
{
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
+ if (!pPicture->pDrawable) {
+ if (pPicture->pSourcePict) {
+ if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
+ xfree(pPicture->pSourcePict->linear.stops);
+ xfree(pPicture->pSourcePict);
+ }
+ } else {
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
- if (pPicture->alphaMap)
- FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
- (*ps->DestroyPicture) (pPicture);
- (*ps->DestroyPictureClip) (pPicture);
- if (pPicture->transform)
- xfree (pPicture->transform);
- if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
- {
- WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
- PicturePtr *pPrev;
+ if (pPicture->alphaMap)
+ FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+ (*ps->DestroyPicture) (pPicture);
+ (*ps->DestroyPictureClip) (pPicture);
+ if (pPicture->transform)
+ xfree (pPicture->transform);
+ if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
+ PicturePtr *pPrev;
- for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
- *pPrev;
- pPrev = &(*pPrev)->pNext)
- {
- if (*pPrev == pPicture)
- {
- *pPrev = pPicture->pNext;
- break;
- }
- }
- }
- else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
- {
- (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
- }
+ for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
+ *pPrev;
+ pPrev = &(*pPrev)->pNext)
+ {
+ if (*pPrev == pPicture)
+ {
+ *pPrev = pPicture->pNext;
+ break;
+ }
+ }
+ }
+ else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+ }
+ }
xfree (pPicture);
}
return Success;
Index: render.c
===================================================================
RCS file: /cvs/xserver/xserver/render/render.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- render.c 2 Mar 2005 15:30:04 -0000 1.34
+++ render.c 29 Jun 2005 11:57:18 -0000 1.35
@@ -81,6 +81,10 @@
static int ProcRenderSetPictureFilter (ClientPtr pClient);
static int ProcRenderCreateAnimCursor (ClientPtr pClient);
static int ProcRenderAddTraps (ClientPtr pClient);
+static int ProcRenderCreateSolidFill (ClientPtr pClient);
+static int ProcRenderCreateLinearGradient (ClientPtr pClient);
+static int ProcRenderCreateRadialGradient (ClientPtr pClient);
+static int ProcRenderCreateConicalGradient (ClientPtr pClient);
static int ProcRenderDispatch (ClientPtr pClient);
@@ -115,6 +119,10 @@
static int SProcRenderSetPictureFilter (ClientPtr pClient);
static int SProcRenderCreateAnimCursor (ClientPtr pClient);
static int SProcRenderAddTraps (ClientPtr pClient);
+static int SProcRenderCreateSolidFill (ClientPtr pClient);
+static int SProcRenderCreateLinearGradient (ClientPtr pClient);
+static int SProcRenderCreateRadialGradient (ClientPtr pClient);
+static int SProcRenderCreateConicalGradient (ClientPtr pClient);
static int SProcRenderDispatch (ClientPtr pClient);
@@ -152,6 +160,10 @@
ProcRenderSetPictureFilter,
ProcRenderCreateAnimCursor,
ProcRenderAddTraps,
+ ProcRenderCreateSolidFill,
+ ProcRenderCreateLinearGradient,
+ ProcRenderCreateRadialGradient,
+ ProcRenderCreateConicalGradient
};
int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
@@ -188,6 +200,10 @@
SProcRenderSetPictureFilter,
SProcRenderCreateAnimCursor,
SProcRenderAddTraps,
+ SProcRenderCreateSolidFill,
+ SProcRenderCreateLinearGradient,
+ SProcRenderCreateRadialGradient,
+ SProcRenderCreateConicalGradient
};
static void
@@ -643,6 +659,7 @@
REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
+
len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
if (Ones(stuff->mask) != len)
return BadLength;
@@ -662,6 +679,9 @@
REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
+ if (!pPicture->pDrawable)
+ return BadDrawable;
+
nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
if (nr & 4)
return BadLength;
@@ -713,14 +733,16 @@
client->errorValue = stuff->op;
return BadValue;
}
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
RenderErrBase + BadPicture);
VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess,
RenderErrBase + BadPicture);
- VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
- RenderErrBase + BadPicture);
- if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen ||
- (pMask && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
+ if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+ (pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
return BadMatch;
CompositePicture (stuff->op,
pSrc,
@@ -761,7 +783,9 @@
RenderErrBase + BadPicture);
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
- if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
return BadMatch;
if (stuff->maskFormat)
{
@@ -806,7 +830,9 @@
RenderErrBase + BadPicture);
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
- if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
return BadMatch;
if (stuff->maskFormat)
{
@@ -851,7 +877,9 @@
RenderErrBase + BadPicture);
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
- if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
return BadMatch;
if (stuff->maskFormat)
{
@@ -896,7 +924,9 @@
RenderErrBase + BadPicture);
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
- if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
return BadMatch;
if (stuff->maskFormat)
{
@@ -1223,7 +1253,9 @@
RenderErrBase + BadPicture);
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
- if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
return BadMatch;
if (stuff->maskFormat)
{
@@ -1388,6 +1420,8 @@
}
VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
if (things & 4)
@@ -1452,6 +1486,8 @@
VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
RenderErrBase + BadPicture);
+ if (!pSrc->pDrawable)
+ return BadDrawable;
pScreen = pSrc->pDrawable->pScreen;
width = pSrc->pDrawable->width;
height = pSrc->pDrawable->height;
@@ -1823,6 +1859,8 @@
REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
RenderErrBase + BadPicture);
+ if (!pPicture->pDrawable)
+ return BadDrawable;
ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
if (ntraps % sizeof (xTrap))
return BadLength;
@@ -1834,6 +1872,113 @@
return client->noClientException;
}
+static int ProcRenderCreateSolidFill(ClientPtr client)
+{
+ PicturePtr pPicture;
+ int error = 0;
+ REQUEST(xRenderCreateSolidFillReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateLinearGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateLinearGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateRadialGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateRadialGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
+ stuff->inner_radius, stuff->outer_radius,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateConicalGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateConicalGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+
static int
ProcRenderDispatch (ClientPtr client)
{
@@ -2315,6 +2460,115 @@
}
static int
+SProcRenderCreateSolidFill(ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderCreateSolidFillReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swaps(&stuff->color.alpha, n);
+ swaps(&stuff->color.red, n);
+ swaps(&stuff->color.green, n);
+ swaps(&stuff->color.blue, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static void swapStops(void *stuff, int n)
+{
+ int i;
+ CARD32 *stops;
+ CARD16 *colors;
+ stops = (CARD32 *)(stuff);
+ for (i = 0; i < n; ++i) {
+ swapl(stops, n);
+ ++stops;
+ }
+ colors = (CARD16 *)(stops);
+ for (i = 0; i < 4*n; ++i) {
+ swaps(stops, n);
+ ++stops;
+ }
+}
+
+static int
+SProcRenderCreateLinearGradient (ClientPtr client)
+{
+ register int n;
+ int len;
+ REQUEST (xRenderCreateLinearGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->p1.x, n);
+ swapl(&stuff->p1.y, n);
+ swapl(&stuff->p2.x, n);
+ swapl(&stuff->p2.y, n);
+ swaps(&stuff->nStops, n);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateRadialGradient (ClientPtr client)
+{
+ register int n;
+ int len;
+ REQUEST (xRenderCreateRadialGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->inner.x, n);
+ swapl(&stuff->inner.y, n);
+ swapl(&stuff->outer.x, n);
+ swapl(&stuff->outer.y, n);
+ swapl(&stuff->inner_radius, n);
+ swapl(&stuff->outer_radius, n);
+ swaps(&stuff->nStops, n);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateConicalGradient (ClientPtr client)
+{
+ register int n;
+ int len;
+ REQUEST (xRenderCreateConicalGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->center.x, n);
+ swapl(&stuff->center.y, n);
+ swapl(&stuff->angle, n);
+ swaps(&stuff->nStops, n);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
SProcRenderDispatch (ClientPtr client)
{
REQUEST(xReq);