diff options
author | Mihai Moldovan <ionic@ionic.de> | 2015-04-16 18:03:18 +0200 |
---|---|---|
committer | Mihai Moldovan <ionic@ionic.de> | 2015-04-16 18:03:18 +0200 |
commit | cfc0202b42ad307391202ca776937b28ea7d2b03 (patch) | |
tree | 03acc5d7d7bb0d35152bfc597eb788b938f09647 /nx-X11/programs/Xserver/hw/nxagent/NXpicture.c | |
parent | fad840cfe558601a8ec02414f1235824bc9f3168 (diff) | |
parent | a5f71f084e9f32e947a04da69edb7aae96d61697 (diff) | |
download | nx-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.c | 944 |
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 */ |