646 lines
20 KiB
C
646 lines
20 KiB
C
/**************************************************************************/
|
|
/* */
|
|
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
|
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
|
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
|
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
|
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
|
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
|
/* */
|
|
/* NXAGENT, NX protocol compression and NX extensions to this software */
|
|
/* are copyright of the aforementioned persons and companies. */
|
|
/* */
|
|
/* Redistribution and use of the present software is allowed according */
|
|
/* to terms specified in the file LICENSE which comes in the source */
|
|
/* distribution. */
|
|
/* */
|
|
/* All rights reserved. */
|
|
/* */
|
|
/* NOTE: This software has received contributions from various other */
|
|
/* contributors, only the core maintainers and supporters are listed as */
|
|
/* copyright holders. Please contact us, if you feel you should be listed */
|
|
/* as copyright holder, as well. */
|
|
/* */
|
|
/**************************************************************************/
|
|
|
|
/*
|
|
* 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
|
|
* the above copyright notice appear in all copies and that both that
|
|
* copyright notice and this permission notice appear in supporting
|
|
* documentation, and that the name of SuSE not be used in advertising or
|
|
* publicity pertaining to distribution of the software without specific,
|
|
* written prior permission. SuSE makes no representations about the
|
|
* suitability of this software for any purpose. It is provided "as is"
|
|
* without express or implied warranty.
|
|
*
|
|
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
|
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
* Author: Keith Packard, SuSE, Inc.
|
|
*/
|
|
|
|
#include "picturestr.h"
|
|
|
|
#include "Screen.h"
|
|
#include "Pixmaps.h"
|
|
#include "Drawable.h"
|
|
#include "Render.h"
|
|
|
|
/* prototypes */
|
|
|
|
PictFormatPtr PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
|
|
PicturePtr AllocatePicture (ScreenPtr pScreen);
|
|
PicturePtr CreatePicture (Picture pid,
|
|
DrawablePtr pDrawable,
|
|
PictFormatPtr pFormat,
|
|
Mask vmask,
|
|
XID *vlist,
|
|
ClientPtr client,
|
|
int *error);
|
|
static PicturePtr createSourcePicture(void);
|
|
int FreePicture (void *value, XID pid);
|
|
|
|
#include "../../render/picture.c"
|
|
|
|
|
|
#define PANIC
|
|
#define WARNING
|
|
#undef TEST
|
|
#undef DEBUG
|
|
|
|
void *nxagentVisualFromID(ScreenPtr pScreen, VisualID visual);
|
|
|
|
void *nxagentMatchingFormats(PictFormatPtr pForm);
|
|
|
|
void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats);
|
|
|
|
extern int nxagentPicturePrivateIndex;
|
|
|
|
PictFormatPtr
|
|
PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
|
|
{
|
|
int nformats, f;
|
|
PictFormatPtr pFormats;
|
|
FormatInitRec formats[1024];
|
|
CARD32 format;
|
|
|
|
nformats = 0;
|
|
|
|
nxagentPictureCreateDefaultFormats(pScreen, formats, &nformats);
|
|
|
|
pFormats = (PictFormatPtr) calloc (nformats, sizeof (PictFormatRec));
|
|
if (!pFormats)
|
|
return 0;
|
|
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;
|
|
switch (PICT_FORMAT_TYPE(format)) {
|
|
case PICT_TYPE_ARGB:
|
|
pFormats[f].type = PictTypeDirect;
|
|
|
|
pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
|
|
if (pFormats[f].direct.alphaMask)
|
|
pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
|
|
PICT_FORMAT_G(format) +
|
|
PICT_FORMAT_B(format));
|
|
|
|
pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
|
|
pFormats[f].direct.red = (PICT_FORMAT_G(format) +
|
|
PICT_FORMAT_B(format));
|
|
|
|
pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
|
|
pFormats[f].direct.green = PICT_FORMAT_B(format);
|
|
|
|
pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
|
|
pFormats[f].direct.blue = 0;
|
|
break;
|
|
|
|
case PICT_TYPE_ABGR:
|
|
pFormats[f].type = PictTypeDirect;
|
|
|
|
pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
|
|
if (pFormats[f].direct.alphaMask)
|
|
pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
|
|
PICT_FORMAT_G(format) +
|
|
PICT_FORMAT_R(format));
|
|
|
|
pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
|
|
pFormats[f].direct.blue = (PICT_FORMAT_G(format) +
|
|
PICT_FORMAT_R(format));
|
|
|
|
pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
|
|
pFormats[f].direct.green = PICT_FORMAT_R(format);
|
|
|
|
pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
|
|
pFormats[f].direct.red = 0;
|
|
break;
|
|
|
|
case PICT_TYPE_A:
|
|
pFormats[f].type = PictTypeDirect;
|
|
|
|
pFormats[f].direct.alpha = 0;
|
|
pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
|
|
|
|
/* remaining fields already set to zero */
|
|
break;
|
|
|
|
case PICT_TYPE_COLOR:
|
|
case PICT_TYPE_GRAY:
|
|
pFormats[f].type = PictTypeIndexed;
|
|
pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
|
|
break;
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
*nformatp = nformats;
|
|
return pFormats;
|
|
}
|
|
|
|
PicturePtr
|
|
AllocatePicture (ScreenPtr pScreen)
|
|
{
|
|
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
|
PicturePtr pPicture;
|
|
char *ptr;
|
|
DevUnion *ppriv;
|
|
unsigned int *sizes;
|
|
unsigned int size;
|
|
int i;
|
|
|
|
pPicture = (PicturePtr) calloc(1, ps->totalPictureSize);
|
|
if (!pPicture)
|
|
return 0;
|
|
ppriv = (DevUnion *)(pPicture + 1);
|
|
pPicture->devPrivates = ppriv;
|
|
sizes = ps->PicturePrivateSizes;
|
|
ptr = (char *)(ppriv + ps->PicturePrivateLen);
|
|
for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
|
|
{
|
|
if ( (size = *sizes) )
|
|
{
|
|
ppriv->ptr = (void *)ptr;
|
|
ptr += size;
|
|
}
|
|
else
|
|
ppriv->ptr = (void *)NULL;
|
|
}
|
|
|
|
#ifdef NXAGENT_SERVER
|
|
nxagentPicturePriv(pPicture) -> picture = 0;
|
|
#endif
|
|
|
|
return pPicture;
|
|
}
|
|
|
|
PicturePtr
|
|
CreatePicture (Picture pid,
|
|
DrawablePtr pDrawable,
|
|
PictFormatPtr pFormat,
|
|
Mask vmask,
|
|
XID *vlist,
|
|
ClientPtr client,
|
|
int *error)
|
|
{
|
|
PicturePtr pPicture;
|
|
PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen);
|
|
|
|
pPicture = AllocatePicture (pDrawable->pScreen);
|
|
if (!pPicture)
|
|
{
|
|
*error = BadAlloc;
|
|
return 0;
|
|
}
|
|
|
|
pPicture->id = pid;
|
|
pPicture->pDrawable = pDrawable;
|
|
pPicture->pFormat = pFormat;
|
|
pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
|
|
if (pDrawable->type == DRAWABLE_PIXMAP)
|
|
{
|
|
#ifdef NXAGENT_SERVER
|
|
/*
|
|
* Let picture always point to the virtual pixmap.
|
|
* For sure this is not the best way to deal with
|
|
* the virtual frame-buffer.
|
|
*/
|
|
pPicture->pDrawable = nxagentVirtualDrawable(pDrawable);
|
|
#endif
|
|
++((PixmapPtr)pDrawable)->refcnt;
|
|
pPicture->pNext = 0;
|
|
}
|
|
else
|
|
{
|
|
pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
|
|
SetPictureWindow(((WindowPtr) pDrawable), pPicture);
|
|
}
|
|
|
|
SetPictureToDefaults (pPicture);
|
|
|
|
if (vmask)
|
|
*error = ChangePicture (pPicture, vmask, vlist, 0, client);
|
|
else
|
|
*error = Success;
|
|
if (*error == Success)
|
|
*error = (*ps->CreatePicture) (pPicture);
|
|
if (*error != Success)
|
|
{
|
|
FreePicture (pPicture, (XID) 0);
|
|
pPicture = 0;
|
|
}
|
|
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) calloc(1, sizeof(PictSolidFill));
|
|
if (!pPicture->pSourcePict) {
|
|
*error = BadAlloc;
|
|
free(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;
|
|
}
|
|
|
|
static PicturePtr createSourcePicture(void)
|
|
{
|
|
/*
|
|
* Compute size of entire PictureRect, plus privates.
|
|
*/
|
|
|
|
unsigned int totalPictureSize = sizeof(PictureRec) +
|
|
picturePrivateCount * sizeof(DevUnion) +
|
|
sizeof(nxagentPrivPictureRec);
|
|
|
|
PicturePtr pPicture = (PicturePtr) calloc(1, totalPictureSize);
|
|
if (!pPicture)
|
|
return 0;
|
|
|
|
DevUnion *ppriv = (DevUnion *) (pPicture + 1);
|
|
|
|
for (int i = 0; i < picturePrivateCount; ++i)
|
|
{
|
|
/*
|
|
* Other privates are inaccessible.
|
|
*/
|
|
|
|
ppriv[i].ptr = NULL;
|
|
}
|
|
|
|
char *privPictureRecAddr = (char *) &ppriv[picturePrivateCount];
|
|
|
|
ppriv[nxagentPicturePrivateIndex].ptr = (void *) privPictureRecAddr;
|
|
|
|
pPicture -> devPrivates = ppriv;
|
|
|
|
nxagentPicturePriv(pPicture) -> picture = 0;
|
|
|
|
pPicture->pDrawable = 0;
|
|
pPicture->pFormat = 0;
|
|
pPicture->pNext = 0;
|
|
|
|
SetPictureToDefaults(pPicture);
|
|
return pPicture;
|
|
}
|
|
|
|
int
|
|
FreePicture (void * value,
|
|
XID pid)
|
|
{
|
|
PicturePtr pPicture = (PicturePtr) value;
|
|
|
|
if (--pPicture->refcnt == 0)
|
|
{
|
|
nxagentDestroyPicture(pPicture);
|
|
|
|
if (pPicture->transform)
|
|
free (pPicture->transform);
|
|
if (!pPicture->pDrawable) {
|
|
if (pPicture->pSourcePict) {
|
|
if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
|
|
free(pPicture->pSourcePict->linear.stops);
|
|
free(pPicture->pSourcePict);
|
|
}
|
|
} else {
|
|
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
|
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
|
|
|
if (pPicture->alphaMap)
|
|
FreePicture ((void *) 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);
|
|
}
|
|
}
|
|
free (pPicture);
|
|
}
|
|
return Success;
|
|
}
|
|
|
|
#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;
|
|
}
|
|
}
|
|
|
|
free(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)
|
|
{
|
|
#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 picture 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;
|
|
}
|
|
}
|
|
}
|
|
|