--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.X.original 2015-02-13 14:03:44.744441510 +0100 +++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c 2015-02-13 14:03:44.744441510 +0100 @@ -1,3 +1,20 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NXAGENT, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of Medialogic S.p.A. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + /* * $XFree86: xc/programs/Xserver/render/picture.c,v 1.29 2002/11/23 02:38:15 keithp Exp $ * @@ -40,7 +57,21 @@ #include "dixstruct.h" #include "gcstruct.h" #include "servermd.h" -#include "picturestr.h" +#include "NXpicturestr.h" + +#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); int PictureScreenPrivateIndex = -1; int PictureWindowPrivateIndex; @@ -50,6 +81,13 @@ 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; @@ -189,11 +227,6 @@ return 0; } -typedef struct _formatInit { - CARD32 format; - CARD8 depth; -} FormatInitRec, *FormatInitPtr; - static int addFormat (FormatInitRec formats[256], int nformat, @@ -207,6 +240,11 @@ 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; } @@ -215,10 +253,13 @@ PictFormatPtr PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp) { - int nformats, f; + int nformats, f; PictFormatPtr pFormats; FormatInitRec formats[1024]; CARD32 format; + +#ifndef NXAGENT_SERVER + CARD8 depth; VisualPtr pVisual; int v; @@ -228,7 +269,16 @@ 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; @@ -254,6 +304,7 @@ if (!depth) continue; bpp = BitsPerPixel (depth); + switch (pVisual->class) { case DirectColor: case TrueColor: @@ -296,6 +347,7 @@ break; } } + /* * Walk supported depths and add useful Direct formats */ @@ -304,16 +356,18 @@ 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) { @@ -325,18 +379,18 @@ /* 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: @@ -359,7 +413,8 @@ break; } } - + +#endif pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec)); if (!pFormats) @@ -368,9 +423,9 @@ 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; + pFormats[f].depth = formats[f].depth; + format = formats[f].format; + pFormats[f].format = format; switch (PICT_FORMAT_TYPE(format)) { case PICT_TYPE_ARGB: pFormats[f].type = PictTypeDirect; @@ -427,6 +482,29 @@ pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid; break; } + +#ifdef NXAGENT_SERVER + if (nxagentMatchingFormats(&pFormats[f]) != NULL) + { + #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 + { + #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 + } +#endif } *nformatp = nformats; return pFormats; @@ -795,9 +873,20 @@ else ppriv->ptr = (pointer)NULL; } + + nxagentPicturePriv(pPicture) -> picture = 0; + return pPicture; } +/* + * Let picture always point to the virtual pixmap. + * For sure this is not the best way to deal with + * the virtual frame-buffer. + */ + +#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL + PicturePtr CreatePicture (Picture pid, DrawablePtr pDrawable, @@ -823,6 +912,12 @@ pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24); if (pDrawable->type == DRAWABLE_PIXMAP) { + #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL + + pPicture->pDrawable = nxagentVirtualDrawable(pDrawable); + + #endif + ++((PixmapPtr)pDrawable)->refcnt; pPicture->pNext = 0; } @@ -972,7 +1067,49 @@ static PicturePtr createSourcePicture(void) { PicturePtr pPicture; - pPicture = (PicturePtr) xalloc(sizeof(PictureRec)); + + 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; @@ -1294,6 +1431,12 @@ 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; @@ -1600,6 +1743,10 @@ if (--pPicture->refcnt == 0) { +#ifdef NXAGENT_SERVER + nxagentDestroyPicture(pPicture); +#endif + if (pPicture->transform) xfree (pPicture->transform); if (!pPicture->pDrawable) { @@ -1698,6 +1845,13 @@ ValidatePicture (pSrc); ValidatePicture (pDst); + + #ifdef TEST + fprintf(stderr, "CompositeGlyphs: Going to composite glyphs with " + "source at [%p] and destination at [%p].\n", + (void *) pSrc, (void *) pDst); + #endif + (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs); } @@ -1862,3 +2016,255 @@ vector->vector[2] = xFixed1; return TRUE; } + +#ifndef True +# define True 1 +#endif + +#ifndef False +# define False 0 +#endif + +void nxagentReconnectPictFormat(void*, XID, void*); + +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; + + #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG) + fprintf(stderr, "nxagentReconnectAllPictFormat\n"); + #endif + + formats_old = GetPictureScreen(nxagentDefaultScreen) -> formats; + nformats_old = GetPictureScreen(nxagentDefaultScreen) -> nformats; + + /* + * TODO: We could copy PictureCreateDefaultFormats, + * in order not to waste ID with FakeClientID(). + */ + formats = PictureCreateDefaultFormats (nxagentDefaultScreen, &nformats); + + if (!formats) + return False; + + for (n = 0; n < nformats; n++) + { + if (formats[n].type == PictTypeIndexed) + { + pVisual = nxagentVisualFromID(nxagentDefaultScreen, formats[n].index.vid); + + if ((pVisual->class | DynamicClass) == PseudoColor) + type = PICT_TYPE_COLOR; + else + type = PICT_TYPE_GRAY; + a = r = g = b = 0; + } + else + { + if ((formats[n].direct.redMask| + formats[n].direct.blueMask| + formats[n].direct.greenMask) == 0) + type = PICT_TYPE_A; + else if (formats[n].direct.red > formats[n].direct.blue) + type = PICT_TYPE_ARGB; + else + type = PICT_TYPE_ABGR; + a = Ones (formats[n].direct.alphaMask); + r = Ones (formats[n].direct.redMask); + g = Ones (formats[n].direct.greenMask); + b = Ones (formats[n].direct.blueMask); + } + formats[n].format = PICT_FORMAT(0,type,a,r,g,b); + } + + for (n = 0; n < nformats_old; n++) + { + for (i = 0, matched = False; (!matched) && (i < nformats); i++) + { + if (formats_old[n].format == formats[i].format && + formats_old[n].type == formats[i].type && + formats_old[n].direct.red == formats[i].direct.red && + formats_old[n].direct.green == formats[i].direct.green && + formats_old[n].direct.blue == formats[i].direct.blue && + formats_old[n].direct.redMask == formats[i].direct.redMask && + formats_old[n].direct.greenMask == formats[i].direct.greenMask && + formats_old[n].direct.blueMask == formats[i].direct.blueMask && + formats_old[n].direct.alpha == formats[i].direct.alpha && + formats_old[n].direct.alphaMask == formats[i].direct.alphaMask) + { + /* + * Regard depth 16 and 15 as were the same, if all other values match. + */ + + if ((formats_old[n].depth == formats[i].depth) || + ((formats_old[n].depth == 15 || formats_old[n].depth == 16) && + (formats[i].depth == 15 || formats[i].depth == 16))) + { + matched = True; + } + } + } + + if (!matched) + { + return False; + } + } + + xfree(formats); + + /* TODO: Perhaps do i have to do PictureFinishInit ?. */ + /* TODO: We have to check for new Render protocol version. */ + + for (i = 0; (i < MAXCLIENTS) && (success); i++) + { + if (clients[i]) + { + FindClientResourcesByType(clients[i], PictFormatType, nxagentReconnectPictFormat, &success); + } + } + + return success; +} + +/* + * It seem we don't have nothing + * to do for reconnect PictureFormat. + */ + +void nxagentReconnectPictFormat(void *p0, XID x1, void *p2) +{ + PictFormatPtr pFormat; + Bool *pBool; + + pFormat = (PictFormatPtr)p0; + pBool = (Bool*)p2; + + #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; + } + } +} +