aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
diff options
context:
space:
mode:
authorMihai Moldovan <ionic@ionic.de>2015-04-16 18:03:18 +0200
committerMihai Moldovan <ionic@ionic.de>2015-04-16 18:03:18 +0200
commitcfc0202b42ad307391202ca776937b28ea7d2b03 (patch)
tree03acc5d7d7bb0d35152bfc597eb788b938f09647 /nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
parentfad840cfe558601a8ec02414f1235824bc9f3168 (diff)
parenta5f71f084e9f32e947a04da69edb7aae96d61697 (diff)
downloadnx-libs-cfc0202b42ad307391202ca776937b28ea7d2b03.tar.gz
nx-libs-cfc0202b42ad307391202ca776937b28ea7d2b03.tar.bz2
nx-libs-cfc0202b42ad307391202ca776937b28ea7d2b03.zip
Merge branch 'sunweaver-pr/nxupgradeagent-cleanup' into arctica-3.6.x
Diffstat (limited to 'nx-X11/programs/Xserver/hw/nxagent/NXpicture.c')
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXpicture.c944
1 files changed, 853 insertions, 91 deletions
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
index d32cdb6c4..4b342ebcf 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
@@ -1,9 +1,3 @@
-#ifdef NXAGENT_UPGRADE
-
-#include "X/NXpicture.c"
-
-#else
-
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */
@@ -22,9 +16,9 @@
/**************************************************************************/
/*
- * $XFree86: xc/programs/Xserver/render/picture.c,v 1.30 2003/01/26 16:40:43 eich Exp $
+ * $XFree86: xc/programs/Xserver/render/picture.c,v 1.29 2002/11/23 02:38:15 keithp Exp $
*
- * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2000 SuSE, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -46,6 +40,10 @@
* Author: Keith Packard, SuSE, Inc.
*/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
#include "misc.h"
#include "scrnintstr.h"
#include "os.h"
@@ -64,6 +62,14 @@
#include "Screen.h"
#include "Pixmaps.h"
#include "Drawable.h"
+#include "Render.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+void *nxagentVisualFromID(ScreenPtr pScreen, VisualID visual);
void *nxagentMatchingFormats(PictFormatPtr pForm);
@@ -75,6 +81,64 @@ RESTYPE PictFormatType;
RESTYPE GlyphSetType;
int PictureCmapPolicy = PictureCmapPolicyDefault;
+typedef struct _formatInit {
+ CARD32 format;
+ CARD8 depth;
+} FormatInitRec, *FormatInitPtr;
+
+void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats);
+
+/* Picture Private machinery */
+
+static int picturePrivateCount;
+
+void
+ResetPicturePrivateIndex (void)
+{
+ picturePrivateCount = 0;
+}
+
+int
+AllocatePicturePrivateIndex (void)
+{
+ return picturePrivateCount++;
+}
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ unsigned int oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= ps->PicturePrivateLen)
+ {
+ unsigned int *nsizes;
+
+ nsizes = (unsigned int *)xrealloc(ps->PicturePrivateSizes,
+ (index2 + 1) * sizeof(unsigned int));
+ if (!nsizes)
+ return FALSE;
+ while (ps->PicturePrivateLen <= index2)
+ {
+ nsizes[ps->PicturePrivateLen++] = 0;
+ ps->totalPictureSize += sizeof(DevUnion);
+ }
+ ps->PicturePrivateSizes = nsizes;
+ }
+ oldamount = ps->PicturePrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ ps->PicturePrivateSizes[index2] = amount;
+ ps->totalPictureSize += (amount - oldamount);
+ }
+
+ return TRUE;
+}
+
+
Bool
PictureDestroyWindow (WindowPtr pWindow)
{
@@ -111,6 +175,8 @@ PictureCloseScreen (int index, ScreenPtr pScreen)
if (ps->formats[n].type == PictTypeIndexed)
(*ps->CloseIndexed) (pScreen, &ps->formats[n]);
SetPictureScreen(pScreen, 0);
+ if (ps->PicturePrivateSizes)
+ xfree (ps->PicturePrivateSizes);
xfree (ps->formats);
xfree (ps);
return ret;
@@ -161,11 +227,6 @@ visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
return 0;
}
-typedef struct _formatInit {
- CARD32 format;
- CARD8 depth;
-} FormatInitRec, *FormatInitPtr;
-
static int
addFormat (FormatInitRec formats[256],
int nformat,
@@ -179,6 +240,11 @@ addFormat (FormatInitRec formats[256],
return nformat;
formats[nformat].format = format;
formats[nformat].depth = depth;
+
+ #ifdef DEBUG
+ fprintf(stderr, "addFormat: Added format [%lu] depth [%d].\n", format, depth);
+ #endif
+
return ++nformat;
}
@@ -187,14 +253,13 @@ addFormat (FormatInitRec formats[256],
PictFormatPtr
PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
{
-#ifdef NXAGENT_SERVER
- int nformats, f, n;
-#else
int nformats, f;
-#endif
PictFormatPtr pFormats;
FormatInitRec formats[1024];
CARD32 format;
+
+#ifndef NXAGENT_SERVER
+
CARD8 depth;
VisualPtr pVisual;
int v;
@@ -204,7 +269,16 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
int d;
DepthPtr pDepth;
+#endif
+
nformats = 0;
+
+#ifdef NXAGENT_SERVER
+
+ nxagentPictureCreateDefaultFormats(pScreen, formats, &nformats);
+
+#else
+
/* formats required by protocol */
formats[nformats].format = PICT_a1;
formats[nformats].depth = 1;
@@ -230,6 +304,7 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
if (!depth)
continue;
bpp = BitsPerPixel (depth);
+
switch (pVisual->class) {
case DirectColor:
case TrueColor:
@@ -272,6 +347,7 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
break;
}
}
+
/*
* Walk supported depths and add useful Direct formats
*/
@@ -280,16 +356,18 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
pDepth = &pScreen->allowedDepths[d];
bpp = BitsPerPixel (pDepth->depth);
format = 0;
+
switch (bpp) {
case 16:
/* depth 12 formats */
- if (pDepth->depth >= 12)
- {
- nformats = addFormat (formats, nformats,
- PICT_x4r4g4b4, pDepth->depth);
- nformats = addFormat (formats, nformats,
- PICT_x4b4g4r4, pDepth->depth);
- }
+ if (pDepth->depth >= 12)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x4r4g4b4, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x4b4g4r4, pDepth->depth);
+ }
+
/* depth 15 formats */
if (pDepth->depth >= 15)
{
@@ -301,18 +379,18 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
/* depth 16 formats */
if (pDepth->depth >= 16)
{
- nformats = addFormat (formats, nformats,
- PICT_a1r5g5b5, pDepth->depth);
- nformats = addFormat (formats, nformats,
- PICT_a1b5g5r5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a1r5g5b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a1b5g5r5, pDepth->depth);
nformats = addFormat (formats, nformats,
PICT_r5g6b5, pDepth->depth);
nformats = addFormat (formats, nformats,
PICT_b5g6r5, pDepth->depth);
nformats = addFormat (formats, nformats,
PICT_a4r4g4b4, pDepth->depth);
- nformats = addFormat (formats, nformats,
- PICT_a4b4g4r4, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a4b4g4r4, pDepth->depth);
}
break;
case 24:
@@ -335,27 +413,19 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
break;
}
}
-
+
+#endif
pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
if (!pFormats)
return 0;
memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
-#ifdef NXAGENT_SERVER
- for (f = 0, n = 0; n < nformats; n++)
- {
- pFormats[f].id = FakeClientID (0);
- pFormats[f].depth = formats[n].depth;
- format = formats[n].format;
- pFormats[f].format = format;
-#else
for (f = 0; f < nformats; f++)
{
pFormats[f].id = FakeClientID (0);
pFormats[f].depth = formats[f].depth;
format = formats[f].format;
pFormats[f].format = format;
-#endif
switch (PICT_FORMAT_TYPE(format)) {
case PICT_TYPE_ARGB:
pFormats[f].type = PictTypeDirect;
@@ -409,28 +479,52 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
case PICT_TYPE_COLOR:
case PICT_TYPE_GRAY:
pFormats[f].type = PictTypeIndexed;
- pFormats[f].index.pVisual = &pScreen->visuals[PICT_FORMAT_VIS(format)];
+ pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
break;
}
#ifdef NXAGENT_SERVER
if (nxagentMatchingFormats(&pFormats[f]) != NULL)
{
- f++;
+ #ifdef DEBUG
+ fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
+ "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] matches.\n",
+ pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
+ pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
+ pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
+ #endif
}
else
{
- memset(&pFormats[f], '\0', sizeof(PictFormatRec));
+ #ifdef DEBUG
+ fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
+ "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] doesn't match.\n",
+ pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
+ pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
+ pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
+ #endif
}
- }
- *nformatp = f;
-#else
+#endif
}
*nformatp = nformats;
-#endif
return pFormats;
}
+static VisualPtr
+PictureFindVisual (ScreenPtr pScreen, VisualID visual)
+{
+ int i;
+ VisualPtr pVisual;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid == visual)
+ return pVisual;
+ }
+ return 0;
+}
+
Bool
PictureInitIndexedFormats (ScreenPtr pScreen)
{
@@ -446,13 +540,16 @@ PictureInitIndexedFormats (ScreenPtr pScreen)
{
if (format->type == PictTypeIndexed && !format->index.pColormap)
{
- if (format->index.pVisual->vid == pScreen->rootVisual)
+ if (format->index.vid == pScreen->rootVisual)
format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
RT_COLORMAP);
else
{
+ VisualPtr pVisual;
+
+ pVisual = PictureFindVisual (pScreen, format->index.vid);
if (CreateColormap (FakeClientID (0), pScreen,
- format->index.pVisual,
+ pVisual,
&format->index.pColormap, AllocNone,
0) != Success)
{
@@ -524,9 +621,9 @@ PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
type = PictTypeIndexed;
break;
case TrueColor:
+ case DirectColor:
type = PictTypeDirect;
break;
- case DirectColor:
default:
return 0;
}
@@ -536,7 +633,7 @@ PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
{
if (type == PictTypeIndexed)
{
- if (format->index.pVisual == pVisual)
+ if (format->index.vid == pVisual->vid)
return format;
}
else
@@ -641,7 +738,8 @@ PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
}
if (formats[n].type == PictTypeIndexed)
{
- if ((formats[n].index.pVisual->class | DynamicClass) == PseudoColor)
+ VisualPtr pVisual = PictureFindVisual (pScreen, formats[n].index.vid);
+ if ((pVisual->class | DynamicClass) == PseudoColor)
type = PICT_TYPE_COLOR;
else
type = PICT_TYPE_GRAY;
@@ -725,6 +823,7 @@ SetPictureToDefaults (PicturePtr pPicture)
pPicture->freeCompClip = FALSE;
pPicture->clientClipType = CT_NONE;
pPicture->componentAlpha = FALSE;
+ pPicture->repeatType = RepeatNone;
pPicture->alphaMap = 0;
pPicture->alphaOrigin.x = 0;
@@ -743,6 +842,7 @@ SetPictureToDefaults (PicturePtr pPicture)
pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
+ pPicture->pSourcePict = 0;
}
PicturePtr
@@ -773,6 +873,9 @@ AllocatePicture (ScreenPtr pScreen)
else
ppriv->ptr = (pointer)NULL;
}
+
+ nxagentPicturePriv(pPicture) -> picture = 0;
+
return pPicture;
}
@@ -840,6 +943,348 @@ CreatePicture (Picture pid,
return pPicture;
}
+static CARD32 xRenderColorToCard32(xRenderColor c)
+{
+ return
+ (c.alpha >> 8 << 24) |
+ (c.red >> 8 << 16) |
+ (c.green & 0xff00) |
+ (c.blue >> 8);
+}
+
+static unsigned int premultiply(unsigned int x)
+{
+ unsigned int a = x >> 24;
+ unsigned int 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 unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
+ unsigned int y, unsigned int 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) {
+ unsigned int current_color = xRenderColorToCard32(stops[current_stop].color);
+ unsigned int 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;
+
+ extern int nxagentPicturePrivateIndex;
+
+ unsigned int totalPictureSize;
+
+ DevUnion *ppriv;
+
+ char *privPictureRecAddr;
+
+ int i;
+
+ /*
+ * Compute size of entire PictureRect, plus privates.
+ */
+
+ totalPictureSize = sizeof(PictureRec) +
+ picturePrivateCount * sizeof(DevUnion) +
+ sizeof(nxagentPrivPictureRec);
+
+ pPicture = (PicturePtr) xalloc(totalPictureSize);
+
+ if (pPicture != NULL)
+ {
+ ppriv = (DevUnion *) (pPicture + 1);
+
+ for (i = 0; i < picturePrivateCount; ++i)
+ {
+ /*
+ * Other privates are inaccessible.
+ */
+
+ ppriv[i].ptr = NULL;
+ }
+
+ privPictureRecAddr = (char *) &ppriv[picturePrivateCount];
+
+ ppriv[nxagentPicturePrivateIndex].ptr = (pointer) privPictureRecAddr;
+
+ pPicture -> devPrivates = ppriv;
+
+ nxagentPicturePriv(pPicture) -> picture = 0;
+ }
+
+ 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 = xRenderColorToCard32(*color);
+ pPicture->pSourcePict->solidFill.fullColor.alpha=color->alpha;
+ pPicture->pSourcePict->solidFill.fullColor.red=color->red;
+ pPicture->pSourcePict->solidFill.fullColor.green=color->green;
+ pPicture->pSourcePict->solidFill.fullColor.blue=color->blue;
+ 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)
@@ -851,8 +1296,8 @@ ChangePicture (PicturePtr pPicture,
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;
@@ -870,8 +1315,11 @@ ChangePicture (PicturePtr pPicture,
{
unsigned int newr;
newr = NEXT_VAL(unsigned int);
- if (newr <= xTrue)
- pPicture->repeat = newr;
+ if (newr <= RepeatReflect)
+ {
+ pPicture->repeat = (newr != RepeatNone);
+ pPicture->repeatType = newr;
+ }
else
{
client->errorValue = newr;
@@ -938,6 +1386,8 @@ ChangePicture (PicturePtr pPicture,
Pixmap pid;
PixmapPtr pPixmap;
int clipType;
+ if (!pScreen)
+ return BadDrawable;
if (vlist)
{
@@ -985,6 +1435,12 @@ ChangePicture (PicturePtr pPicture,
pPixmap->refcnt++;
}
}
+
+ #ifdef DEBUG
+ fprintf(stderr, "ChangePicture: Going to call ChangePictureClip with clipType [%d] pPixmap [%p].\n",
+ clipType, (void *) pPixmap);
+ #endif
+
error = (*ps->ChangePictureClip)(pPicture, clipType,
(pointer)pPixmap, 0);
break;
@@ -1064,7 +1520,8 @@ ChangePicture (PicturePtr pPicture,
break;
}
}
- (*ps->ChangePicture) (pPicture, maskQ);
+ if (ps)
+ (*ps->ChangePicture) (pPicture, maskQ);
return error;
}
@@ -1097,6 +1554,51 @@ SetPictureClipRects (PicturePtr pPicture,
}
int
+SetPictureClipRegion (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ RegionPtr pRegion)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ RegionPtr clientClip;
+ int result;
+ int type;
+
+ if (pRegion)
+ {
+ type = CT_REGION;
+ clientClip = REGION_CREATE (pScreen,
+ REGION_EXTENTS(pScreen, pRegion),
+ REGION_NUM_RECTS(pRegion));
+ if (!clientClip)
+ return BadAlloc;
+ if (!REGION_COPY (pSCreen, clientClip, pRegion))
+ {
+ REGION_DESTROY (pScreen, clientClip);
+ return BadAlloc;
+ }
+ }
+ else
+ {
+ type = CT_NONE;
+ clientClip = 0;
+ }
+
+ result =(*ps->ChangePictureClip) (pPicture, type,
+ (pointer) clientClip, 0);
+ if (result == Success)
+ {
+ pPicture->clipOrigin.x = xOrigin;
+ pPicture->clipOrigin.y = yOrigin;
+ pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ }
+ return result;
+}
+
+
+int
SetPictureTransform (PicturePtr pPicture,
PictTransform *transform)
{
@@ -1127,13 +1629,99 @@ SetPictureTransform (PicturePtr pPicture,
pPicture->transform = 0;
}
}
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
return Success;
}
+void
+CopyPicture (PicturePtr pSrc,
+ Mask mask,
+ PicturePtr pDst)
+{
+ PictureScreenPtr ps = GetPictureScreen(pSrc->pDrawable->pScreen);
+ Mask origMask = mask;
+
+ pDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pDst->stateChanges |= mask;
+
+ while (mask) {
+ Mask bit = lowbit(mask);
+
+ switch (bit)
+ {
+ case CPRepeat:
+ pDst->repeat = pSrc->repeat;
+ pDst->repeatType = pSrc->repeatType;
+ break;
+ case CPAlphaMap:
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable->type == DRAWABLE_PIXMAP)
+ pSrc->alphaMap->refcnt++;
+ if (pDst->alphaMap)
+ FreePicture ((pointer) pDst->alphaMap, (XID) 0);
+ pDst->alphaMap = pSrc->alphaMap;
+ break;
+ case CPAlphaXOrigin:
+ pDst->alphaOrigin.x = pSrc->alphaOrigin.x;
+ break;
+ case CPAlphaYOrigin:
+ pDst->alphaOrigin.y = pSrc->alphaOrigin.y;
+ break;
+ case CPClipXOrigin:
+ pDst->clipOrigin.x = pSrc->clipOrigin.x;
+ break;
+ case CPClipYOrigin:
+ pDst->clipOrigin.y = pSrc->clipOrigin.y;
+ break;
+ case CPClipMask:
+ switch (pSrc->clientClipType) {
+ case CT_NONE:
+ (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+ break;
+ case CT_REGION:
+ if (!pSrc->clientClip) {
+ (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+ } else {
+ RegionPtr clientClip;
+ RegionPtr srcClientClip = (RegionPtr)pSrc->clientClip;
+
+ clientClip = REGION_CREATE(pSrc->pDrawable->pScreen,
+ REGION_EXTENTS(pSrc->pDrawable->pScreen, srcClientClip),
+ REGION_NUM_RECTS(srcClientClip));
+ (*ps->ChangePictureClip)(pDst, CT_REGION, clientClip, 0);
+ }
+ break;
+ default:
+ /* XXX: CT_PIXMAP unimplemented */
+ break;
+ }
+ break;
+ case CPGraphicsExposure:
+ pDst->graphicsExposures = pSrc->graphicsExposures;
+ break;
+ case CPPolyEdge:
+ pDst->polyEdge = pSrc->polyEdge;
+ break;
+ case CPPolyMode:
+ pDst->polyMode = pSrc->polyMode;
+ break;
+ case CPDither:
+ pDst->dither = pSrc->dither;
+ break;
+ case CPComponentAlpha:
+ pDst->componentAlpha = pSrc->componentAlpha;
+ break;
+ }
+ mask &= ~bit;
+ }
+
+ (*ps->ChangePicture)(pDst, origMask);
+}
+
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);
@@ -1159,35 +1747,47 @@ FreePicture (pointer value,
if (--pPicture->refcnt == 0)
{
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
-
- if (pPicture->alphaMap)
- FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
- (*ps->DestroyPicture) (pPicture);
- (*ps->DestroyPictureClip) (pPicture);
+#ifdef NXAGENT_SERVER
+ nxagentDestroyPicture(pPicture);
+#endif
+
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);
- }
+ 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->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);
+ }
+ }
xfree (pPicture);
}
return Success;
@@ -1340,12 +1940,52 @@ CompositeTriFan (CARD8 op,
(*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
}
-typedef xFixed_32_32 xFixed_48_16;
+void
+AddTraps (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntrap,
+ xTrap *traps)
+{
+ PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+ ValidatePicture (pPicture);
+ (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
+}
#define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff)
#define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31))
Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+ PictVectorPtr vector)
+{
+ PictVector result;
+ int i, j;
+ xFixed_32_32 partial;
+ xFixed_48_16 v;
+
+ for (j = 0; j < 3; j++)
+ {
+ v = 0;
+ for (i = 0; i < 3; i++)
+ {
+ partial = ((xFixed_48_16) transform->matrix[j][i] *
+ (xFixed_48_16) vector->vector[i]);
+ v += partial >> 16;
+ }
+ if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+ return FALSE;
+ result.vector[j] = (xFixed) v;
+ }
+ if (!result.vector[2])
+ return FALSE;
+ *vector = result;
+ return TRUE;
+}
+
+
+Bool
PictureTransformPoint (PictTransformPtr transform,
PictVectorPtr vector)
{
@@ -1395,12 +2035,13 @@ Bool nxagentReconnectAllPictFormat(void *p)
{
PictFormatPtr formats_old, formats;
int nformats, nformats_old;
+ VisualPtr pVisual;
Bool success = True;
Bool matched;
int i, n;
CARD32 type, a, r, g, b;
- #ifdef DEBUG
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
fprintf(stderr, "nxagentReconnectAllPictFormat\n");
#endif
@@ -1414,13 +2055,15 @@ Bool nxagentReconnectAllPictFormat(void *p)
formats = PictureCreateDefaultFormats (nxagentDefaultScreen, &nformats);
if (!formats)
- return FALSE;
+ return False;
for (n = 0; n < nformats; n++)
{
if (formats[n].type == PictTypeIndexed)
{
- if ((formats[n].index.pVisual->class | DynamicClass) == PseudoColor)
+ pVisual = nxagentVisualFromID(nxagentDefaultScreen, formats[n].index.vid);
+
+ if ((pVisual->class | DynamicClass) == PseudoColor)
type = PICT_TYPE_COLOR;
else
type = PICT_TYPE_GRAY;
@@ -1471,9 +2114,13 @@ Bool nxagentReconnectAllPictFormat(void *p)
}
}
}
+
if (!matched)
+ {
return False;
+ }
}
+
xfree(formats);
/* TODO: Perhaps do i have to do PictureFinishInit ?. */
@@ -1503,10 +2150,125 @@ void nxagentReconnectPictFormat(void *p0, XID x1, void *p2)
pFormat = (PictFormatPtr)p0;
pBool = (Bool*)p2;
- #ifdef DEBUG
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
fprintf(stderr, "nxagentReconnectPictFormat.\n");
#endif
}
+/*
+ * The set of picture formats may change considerably
+ * between different X servers. This poses a problem
+ * while migrating NX sessions, because a requisite to
+ * successfully reconnect the session is that all pic-
+ * ture formats have to be available on the new X server.
+ * To reduce such problems, we use a limited set of
+ * pictures available on the most X servers.
+ */
+
+void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats)
+{
+ DepthPtr pDepth;
+ VisualPtr pVisual;
+
+ CARD32 format;
+ CARD8 depth;
+
+ int r, g, b;
+ int bpp;
+ int d;
+ int v;
+
+
+ formats[*nformats].format = PICT_a1;
+ formats[*nformats].depth = 1;
+ *nformats += 1;
+ formats[*nformats].format = PICT_a4;
+ formats[*nformats].depth = 4;
+ *nformats += 1;
+ formats[*nformats].format = PICT_a8;
+ formats[*nformats].depth = 8;
+ *nformats += 1;
+ formats[*nformats].format = PICT_a8r8g8b8;
+ formats[*nformats].depth = 32;
+ *nformats += 1;
+
+ /*
+ * This format should be required by the
+ * protocol, but it's not used by Xgl.
+ *
+ * formats[*nformats].format = PICT_x8r8g8b8;
+ * formats[*nformats].depth = 32;
+ * *nformats += 1;
+ */
+
+ /* now look through the depths and visuals adding other formats */
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = &pScreen->visuals[v];
+ depth = visualDepth (pScreen, pVisual);
+ if (!depth)
+ continue;
+
+ bpp = BitsPerPixel (depth);
+
+ switch (pVisual->class)
+ {
+ case DirectColor:
+ case TrueColor:
+ r = Ones (pVisual->redMask);
+ g = Ones (pVisual->greenMask);
+ b = Ones (pVisual->blueMask);
+
+ if (pVisual->offsetBlue == 0 &&
+ pVisual->offsetGreen == b &&
+ pVisual->offsetRed == b + g)
+ {
+ format = PICT_FORMAT(bpp, PICT_TYPE_ARGB, 0, r, g, b);
+ *nformats = addFormat (formats, *nformats, format, depth);
+ }
+ break;
+ case StaticColor:
+ case PseudoColor:
+ case StaticGray:
+ case GrayScale:
+ break;
+ }
+ }
+
+ for (d = 0; d < pScreen -> numDepths; d++)
+ {
+ pDepth = &pScreen -> allowedDepths[d];
+ bpp = BitsPerPixel(pDepth -> depth);
+
+ switch (bpp) {
+ case 16:
+ if (pDepth->depth == 15)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_x1r5g5b5, pDepth->depth);
+ }
+
+ if (pDepth->depth == 16)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_r5g6b5, pDepth->depth);
+ }
+ break;
+ case 24:
+ if (pDepth->depth == 24)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_r8g8b8, pDepth->depth);
+ }
+ break;
+ case 32:
+ if (pDepth->depth == 24)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_x8r8g8b8, pDepth->depth);
+ }
+ break;
+ }
+ }
+}
-#endif /* #ifdef NXAGENT_UPGRADE */