diff options
Diffstat (limited to 'xorg-server/render')
-rw-r--r-- | xorg-server/render/mitrap.c | 158 | ||||
-rw-r--r-- | xorg-server/render/picture.c | 3560 | ||||
-rw-r--r-- | xorg-server/render/picturestr.h | 1296 | ||||
-rw-r--r-- | xorg-server/render/render.c | 6768 |
4 files changed, 5891 insertions, 5891 deletions
diff --git a/xorg-server/render/mitrap.c b/xorg-server/render/mitrap.c index 37d917451..445f23630 100644 --- a/xorg-server/render/mitrap.c +++ b/xorg-server/render/mitrap.c @@ -1,79 +1,79 @@ -/*
- *
- * Copyright © 2002 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD 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.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "servermd.h"
-#include "mi.h"
-#include "picturestr.h"
-#include "mipict.h"
-
-static xFixed
-miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
-{
- xFixed dx = l->p2.x - l->p1.x;
- xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
- xFixed dy = l->p2.y - l->p1.y;
- if (ceil)
- ex += (dy - 1);
- return l->p1.x + (xFixed) (ex / dy);
-}
-
-void
-miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
-{
- box->y1 = MAXSHORT;
- box->y2 = MINSHORT;
- box->x1 = MAXSHORT;
- box->x2 = MINSHORT;
- for (; ntrap; ntrap--, traps++)
- {
- INT16 x1, y1, x2, y2;
-
- if (!xTrapezoidValid(traps))
- continue;
- y1 = xFixedToInt (traps->top);
- if (y1 < box->y1)
- box->y1 = y1;
-
- y2 = xFixedToInt (xFixedCeil (traps->bottom));
- if (y2 > box->y2)
- box->y2 = y2;
-
- x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE),
- miLineFixedX (&traps->left, traps->bottom, FALSE)));
- if (x1 < box->x1)
- box->x1 = x1;
-
- x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE),
- miLineFixedX (&traps->right, traps->bottom, TRUE))));
- if (x2 > box->x2)
- box->x2 = x2;
- }
-}
+/* + * + * Copyright © 2002 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "servermd.h" +#include "mi.h" +#include "picturestr.h" +#include "mipict.h" + +static xFixed +miLineFixedX (xLineFixed *l, xFixed y, Bool ceil) +{ + xFixed dx = l->p2.x - l->p1.x; + xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx; + xFixed dy = l->p2.y - l->p1.y; + if (ceil) + ex += (dy - 1); + return l->p1.x + (xFixed) (ex / dy); +} + +void +miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box) +{ + box->y1 = MAXSHORT; + box->y2 = MINSHORT; + box->x1 = MAXSHORT; + box->x2 = MINSHORT; + for (; ntrap; ntrap--, traps++) + { + INT16 x1, y1, x2, y2; + + if (!xTrapezoidValid(traps)) + continue; + y1 = xFixedToInt (traps->top); + if (y1 < box->y1) + box->y1 = y1; + + y2 = xFixedToInt (xFixedCeil (traps->bottom)); + if (y2 > box->y2) + box->y2 = y2; + + x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE), + miLineFixedX (&traps->left, traps->bottom, FALSE))); + if (x1 < box->x1) + box->x1 = x1; + + x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE), + miLineFixedX (&traps->right, traps->bottom, TRUE)))); + if (x2 > box->x2) + box->x2 = x2; + } +} diff --git a/xorg-server/render/picture.c b/xorg-server/render/picture.c index e93f08abf..5640c4d96 100644 --- a/xorg-server/render/picture.c +++ b/xorg-server/render/picture.c @@ -1,1780 +1,1780 @@ -/*
- *
- * 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.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "misc.h"
-#include "scrnintstr.h"
-#include "os.h"
-#include "regionstr.h"
-#include "validate.h"
-#include "windowstr.h"
-#include "input.h"
-#include "resource.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "dixstruct.h"
-#include "gcstruct.h"
-#include "servermd.h"
-#include "picturestr.h"
-#include "xace.h"
-
-DevPrivateKeyRec PictureScreenPrivateKeyRec;
-DevPrivateKeyRec PictureWindowPrivateKeyRec;
-static int PictureGeneration;
-RESTYPE PictureType;
-RESTYPE PictFormatType;
-RESTYPE GlyphSetType;
-int PictureCmapPolicy = PictureCmapPolicyDefault;
-
-Bool
-PictureDestroyWindow (WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- PicturePtr pPicture;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- Bool ret;
-
- while ((pPicture = GetPictureWindow(pWindow)))
- {
- SetPictureWindow(pWindow, pPicture->pNext);
- if (pPicture->id)
- FreeResource (pPicture->id, PictureType);
- FreePicture ((pointer) pPicture, pPicture->id);
- }
- pScreen->DestroyWindow = ps->DestroyWindow;
- ret = (*pScreen->DestroyWindow) (pWindow);
- ps->DestroyWindow = pScreen->DestroyWindow;
- pScreen->DestroyWindow = PictureDestroyWindow;
- return ret;
-}
-
-Bool
-PictureCloseScreen (int index, ScreenPtr pScreen)
-{
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- Bool ret;
- int n;
-
- pScreen->CloseScreen = ps->CloseScreen;
- ret = (*pScreen->CloseScreen) (index, pScreen);
- PictureResetFilters (pScreen);
- for (n = 0; n < ps->nformats; n++)
- if (ps->formats[n].type == PictTypeIndexed)
- (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
- GlyphUninit (pScreen);
- SetPictureScreen(pScreen, 0);
- free(ps->formats);
- free(ps);
- return ret;
-}
-
-void
-PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
-{
- ScreenPtr pScreen = pColormap->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
-
- pScreen->StoreColors = ps->StoreColors;
- (*pScreen->StoreColors) (pColormap, ndef, pdef);
- ps->StoreColors = pScreen->StoreColors;
- pScreen->StoreColors = PictureStoreColors;
-
- if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
- {
- PictFormatPtr format = ps->formats;
- int nformats = ps->nformats;
-
- while (nformats--)
- {
- if (format->type == PictTypeIndexed &&
- format->index.pColormap == pColormap)
- {
- (*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
- break;
- }
- format++;
- }
- }
-}
-
-static int
-visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
-{
- int d, v;
- DepthPtr pDepth;
-
- for (d = 0; d < pScreen->numDepths; d++)
- {
- pDepth = &pScreen->allowedDepths[d];
- for (v = 0; v < pDepth->numVids; v++)
- if (pDepth->vids[v] == pVisual->vid)
- return pDepth->depth;
- }
- return 0;
-}
-
-typedef struct _formatInit {
- CARD32 format;
- CARD8 depth;
-} FormatInitRec, *FormatInitPtr;
-
-static int
-addFormat (FormatInitRec formats[256],
- int nformat,
- CARD32 format,
- CARD8 depth)
-{
- int n;
-
- for (n = 0; n < nformat; n++)
- if (formats[n].format == format && formats[n].depth == depth)
- return nformat;
- formats[nformat].format = format;
- formats[nformat].depth = depth;
- return ++nformat;
-}
-
-#define Mask(n) ((1 << (n)) - 1)
-
-PictFormatPtr
-PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
-{
- int nformats, f;
- PictFormatPtr pFormats;
- FormatInitRec formats[1024];
- CARD32 format;
- CARD8 depth;
- VisualPtr pVisual;
- int v;
- int bpp;
- int type;
- int r, g, b;
- int d;
- DepthPtr pDepth;
-
- nformats = 0;
- /* formats required by protocol */
- formats[nformats].format = PICT_a1;
- formats[nformats].depth = 1;
- nformats++;
- formats[nformats].format = PICT_FORMAT(BitsPerPixel(8),
- PICT_TYPE_A,
- 8, 0, 0, 0);
- formats[nformats].depth = 8;
- nformats++;
- formats[nformats].format = PICT_FORMAT(BitsPerPixel(4),
- PICT_TYPE_A,
- 4, 0, 0, 0);
- formats[nformats].depth = 4;
- nformats++;
- formats[nformats].format = PICT_a8r8g8b8;
- formats[nformats].depth = 32;
- nformats++;
- formats[nformats].format = PICT_x8r8g8b8;
- formats[nformats].depth = 32;
- nformats++;
- formats[nformats].format = PICT_b8g8r8a8;
- formats[nformats].depth = 32;
- nformats++;
- formats[nformats].format = PICT_b8g8r8x8;
- formats[nformats].depth = 32;
- nformats++;
-
- /* 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);
- type = PICT_TYPE_OTHER;
- /*
- * Current rendering code supports only three direct formats,
- * fields must be packed together at the bottom of the pixel
- */
- if (pVisual->offsetBlue == 0 &&
- pVisual->offsetGreen == b &&
- pVisual->offsetRed == b + g)
- {
- type = PICT_TYPE_ARGB;
- }
- else if (pVisual->offsetRed == 0 &&
- pVisual->offsetGreen == r &&
- pVisual->offsetBlue == r + g)
- {
- type = PICT_TYPE_ABGR;
- }
- else if (pVisual->offsetRed == pVisual->offsetGreen - r &&
- pVisual->offsetGreen == pVisual->offsetBlue - g &&
- pVisual->offsetBlue == bpp - b)
- {
- type = PICT_TYPE_BGRA;
- }
- if (type != PICT_TYPE_OTHER)
- {
- format = PICT_FORMAT(bpp, type, 0, r, g, b);
- nformats = addFormat (formats, nformats, format, depth);
- }
- break;
- case StaticColor:
- case PseudoColor:
- format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v);
- nformats = addFormat (formats, nformats, format, depth);
- break;
- case StaticGray:
- case GrayScale:
- format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v);
- nformats = addFormat (formats, nformats, format, depth);
- break;
- }
- }
- /*
- * Walk supported depths and add useful Direct formats
- */
- for (d = 0; d < pScreen->numDepths; d++)
- {
- 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);
- }
- /* depth 15 formats */
- if (pDepth->depth >= 15)
- {
- nformats = addFormat (formats, nformats,
- PICT_x1r5g5b5, pDepth->depth);
- nformats = addFormat (formats, nformats,
- PICT_x1b5g5r5, pDepth->depth);
- }
- /* 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_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);
- }
- break;
- case 24:
- if (pDepth->depth >= 24)
- {
- nformats = addFormat (formats, nformats,
- PICT_r8g8b8, pDepth->depth);
- nformats = addFormat (formats, nformats,
- PICT_b8g8r8, pDepth->depth);
- }
- break;
- case 32:
- if (pDepth->depth >= 24)
- {
- nformats = addFormat (formats, nformats,
- PICT_x8r8g8b8, pDepth->depth);
- nformats = addFormat (formats, nformats,
- PICT_x8b8g8r8, pDepth->depth);
- }
- if (pDepth->depth >= 30)
- {
- nformats = addFormat (formats, nformats,
- PICT_a2r10g10b10, pDepth->depth);
- nformats = addFormat (formats, nformats,
- PICT_x2r10g10b10, pDepth->depth);
- nformats = addFormat (formats, nformats,
- PICT_a2b10g10r10, pDepth->depth);
- nformats = addFormat (formats, nformats,
- PICT_x2b10g10r10, pDepth->depth);
- }
- break;
- }
- }
-
-
- pFormats = 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_BGRA:
- pFormats[f].type = PictTypeDirect;
-
- pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
- pFormats[f].direct.blue = (PICT_FORMAT_BPP(format) - PICT_FORMAT_B(format));
-
- pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
- pFormats[f].direct.green = (PICT_FORMAT_BPP(format) - PICT_FORMAT_B(format) -
- PICT_FORMAT_G(format));
-
- pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
- pFormats[f].direct.red = (PICT_FORMAT_BPP(format) - PICT_FORMAT_B(format) -
- PICT_FORMAT_G(format) - PICT_FORMAT_R(format));
-
- pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
- pFormats[f].direct.alpha = 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;
- }
- }
- *nformatp = nformats;
- 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
-PictureInitIndexedFormat(ScreenPtr pScreen, PictFormatPtr format)
-{
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
-
- if (format->type != PictTypeIndexed || format->index.pColormap)
- return TRUE;
-
- if (format->index.vid == pScreen->rootVisual) {
- dixLookupResourceByType((pointer *)&format->index.pColormap,
- pScreen->defColormap, RT_COLORMAP,
- serverClient, DixGetAttrAccess);
- } else {
- VisualPtr pVisual = PictureFindVisual(pScreen, format->index.vid);
- if (CreateColormap(FakeClientID (0), pScreen, pVisual,
- &format->index.pColormap, AllocNone, 0)
- != Success)
- return FALSE;
- }
- if (!ps->InitIndexed(pScreen, format))
- return FALSE;
- return TRUE;
-}
-
-static Bool
-PictureInitIndexedFormats (ScreenPtr pScreen)
-{
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
- PictFormatPtr format;
- int nformat;
-
- if (!ps)
- return FALSE;
- format = ps->formats;
- nformat = ps->nformats;
- while (nformat--)
- if (!PictureInitIndexedFormat(pScreen, format++))
- return FALSE;
- return TRUE;
-}
-
-Bool
-PictureFinishInit (void)
-{
- int s;
-
- for (s = 0; s < screenInfo.numScreens; s++)
- {
- if (!PictureInitIndexedFormats (screenInfo.screens[s]))
- return FALSE;
- (void) AnimCurInit (screenInfo.screens[s]);
- }
-
- return TRUE;
-}
-
-Bool
-PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel)
-{
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
-
- if (!ps)
- return FALSE;
- ps->subpixel = subpixel;
- return TRUE;
-
-}
-
-int
-PictureGetSubpixelOrder (ScreenPtr pScreen)
-{
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
-
- if (!ps)
- return SubPixelUnknown;
- return ps->subpixel;
-}
-
-PictFormatPtr
-PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
-{
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
- PictFormatPtr format;
- int nformat;
- int type;
-
- if (!ps)
- return 0;
- format = ps->formats;
- nformat = ps->nformats;
- switch (pVisual->class) {
- case StaticGray:
- case GrayScale:
- case StaticColor:
- case PseudoColor:
- type = PictTypeIndexed;
- break;
- case TrueColor:
- case DirectColor:
- type = PictTypeDirect;
- break;
- default:
- return 0;
- }
- while (nformat--)
- {
- if (format->depth == depth && format->type == type)
- {
- if (type == PictTypeIndexed)
- {
- if (format->index.vid == pVisual->vid)
- return format;
- }
- else
- {
- if (format->direct.redMask << format->direct.red ==
- pVisual->redMask &&
- format->direct.greenMask << format->direct.green ==
- pVisual->greenMask &&
- format->direct.blueMask << format->direct.blue ==
- pVisual->blueMask)
- {
- return format;
- }
- }
- }
- format++;
- }
- return 0;
-}
-
-PictFormatPtr
-PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f)
-{
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
- PictFormatPtr format;
- int nformat;
-
- if (!ps)
- return 0;
- format = ps->formats;
- nformat = ps->nformats;
- while (nformat--)
- {
- if (format->depth == depth && format->format == (f & 0xffffff))
- return format;
- format++;
- }
- return 0;
-}
-
-int
-PictureParseCmapPolicy (const char *name)
-{
- if ( strcmp (name, "default" ) == 0)
- return PictureCmapPolicyDefault;
- else if ( strcmp (name, "mono" ) == 0)
- return PictureCmapPolicyMono;
- else if ( strcmp (name, "gray" ) == 0)
- return PictureCmapPolicyGray;
- else if ( strcmp (name, "color" ) == 0)
- return PictureCmapPolicyColor;
- else if ( strcmp (name, "all" ) == 0)
- return PictureCmapPolicyAll;
- else
- return PictureCmapPolicyInvalid;
-}
-
-Bool
-PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
-{
- PictureScreenPtr ps;
- int n;
- CARD32 type, a, r, g, b;
-
- if (PictureGeneration != serverGeneration)
- {
- PictureType = CreateNewResourceType (FreePicture, "PICTURE");
- if (!PictureType)
- return FALSE;
- PictFormatType = CreateNewResourceType (FreePictFormat, "PICTFORMAT");
- if (!PictFormatType)
- return FALSE;
- GlyphSetType = CreateNewResourceType (FreeGlyphSet, "GLYPHSET");
- if (!GlyphSetType)
- return FALSE;
- PictureGeneration = serverGeneration;
- }
- if (!dixRegisterPrivateKey(&PictureScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
-
- if (!dixRegisterPrivateKey(&PictureWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
- return FALSE;
-
- if (!formats)
- {
- formats = PictureCreateDefaultFormats (pScreen, &nformats);
- if (!formats)
- return FALSE;
- }
- for (n = 0; n < nformats; n++)
- {
- if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n)))
- {
- free(formats);
- return FALSE;
- }
- if (formats[n].type == PictTypeIndexed)
- {
- VisualPtr pVisual = PictureFindVisual (pScreen, 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 if (formats[n].direct.red == 0)
- type = PICT_TYPE_ABGR;
- else
- type = PICT_TYPE_BGRA;
- 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);
- }
- ps = (PictureScreenPtr) malloc(sizeof (PictureScreenRec));
- if (!ps)
- {
- free(formats);
- return FALSE;
- }
- SetPictureScreen(pScreen, ps);
-
- ps->formats = formats;
- ps->fallback = formats;
- ps->nformats = nformats;
-
- ps->filters = 0;
- ps->nfilters = 0;
- ps->filterAliases = 0;
- ps->nfilterAliases = 0;
-
- ps->subpixel = SubPixelUnknown;
-
- ps->CloseScreen = pScreen->CloseScreen;
- ps->DestroyWindow = pScreen->DestroyWindow;
- ps->StoreColors = pScreen->StoreColors;
- pScreen->DestroyWindow = PictureDestroyWindow;
- pScreen->CloseScreen = PictureCloseScreen;
- pScreen->StoreColors = PictureStoreColors;
-
- if (!PictureSetDefaultFilters (pScreen))
- {
- PictureResetFilters (pScreen);
- SetPictureScreen(pScreen, 0);
- free(formats);
- free(ps);
- return FALSE;
- }
-
- return TRUE;
-}
-
-void
-SetPictureToDefaults (PicturePtr pPicture)
-{
- pPicture->refcnt = 1;
- pPicture->repeat = 0;
- pPicture->graphicsExposures = FALSE;
- pPicture->subWindowMode = ClipByChildren;
- pPicture->polyEdge = PolyEdgeSharp;
- pPicture->polyMode = PolyModePrecise;
- pPicture->freeCompClip = FALSE;
- pPicture->clientClipType = CT_NONE;
- pPicture->componentAlpha = FALSE;
- pPicture->repeatType = RepeatNone;
-
- pPicture->alphaMap = 0;
- pPicture->alphaOrigin.x = 0;
- pPicture->alphaOrigin.y = 0;
-
- pPicture->clipOrigin.x = 0;
- pPicture->clipOrigin.y = 0;
- pPicture->clientClip = 0;
-
- pPicture->transform = 0;
-
- pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE);
- pPicture->filter_params = 0;
- pPicture->filter_nparams = 0;
-
- pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
- pPicture->stateChanges = -1;
- pPicture->pSourcePict = 0;
-}
-
-PicturePtr
-CreatePicture (Picture pid,
- DrawablePtr pDrawable,
- PictFormatPtr pFormat,
- Mask vmask,
- XID *vlist,
- ClientPtr client,
- int *error)
-{
- PicturePtr pPicture;
- PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen);
-
- pPicture = dixAllocateObjectWithPrivates(PictureRec, PRIVATE_PICTURE);
- if (!pPicture)
- {
- *error = BadAlloc;
- return 0;
- }
-
- pPicture->id = pid;
- pPicture->pDrawable = pDrawable;
- pPicture->pFormat = pFormat;
- pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
-
- /* security creation/labeling check */
- *error = XaceHook(XACE_RESOURCE_ACCESS, client, pid, PictureType, pPicture,
- RT_PIXMAP, pDrawable, DixCreateAccess|DixSetAttrAccess);
- if (*error != Success)
- goto out;
-
- if (pDrawable->type == DRAWABLE_PIXMAP)
- {
- ++((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);
-out:
- if (*error != Success)
- {
- FreePicture (pPicture, (XID) 0);
- pPicture = 0;
- }
- return pPicture;
-}
-
-static CARD32 xRenderColorToCard32(xRenderColor c)
-{
- return
- (c.alpha >> 8 << 24) |
- (c.red >> 8 << 16) |
- (c.green & 0xff00) |
- (c.blue >> 8);
-}
-
-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->gradient.stops = malloc(stopCount*sizeof(PictGradientStop));
- if (!pGradient->gradient.stops) {
- *error = BadAlloc;
- return;
- }
-
- pGradient->gradient.nstops = stopCount;
-
- for (i = 0; i < stopCount; ++i) {
- pGradient->gradient.stops[i].x = stopPoints[i];
- pGradient->gradient.stops[i].color = stopColors[i];
- }
-}
-
-static PicturePtr createSourcePicture(void)
-{
- PicturePtr pPicture;
- pPicture = dixAllocateObjectWithPrivates(PictureRec, PRIVATE_PICTURE);
- pPicture->pDrawable = 0;
- pPicture->pFormat = 0;
- pPicture->pNext = 0;
- pPicture->format = PICT_a8r8g8b8;
-
- 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) malloc(sizeof(PictSolidFill));
- if (!pPicture->pSourcePict) {
- *error = BadAlloc;
- free(pPicture);
- return 0;
- }
- pPicture->pSourcePict->type = SourcePictTypeSolidFill;
- pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
- return pPicture;
-}
-
-PicturePtr
-CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
- int nStops, xFixed *stops, xRenderColor *colors, int *error)
-{
- PicturePtr pPicture;
-
- if (nStops < 2) {
- *error = BadValue;
- return 0;
- }
-
- pPicture = createSourcePicture();
- if (!pPicture) {
- *error = BadAlloc;
- return 0;
- }
-
- pPicture->id = pid;
- pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictLinearGradient));
- if (!pPicture->pSourcePict) {
- *error = BadAlloc;
- free(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) {
- free(pPicture);
- return 0;
- }
- return pPicture;
-}
-
-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;
- }
-
- pPicture->id = pid;
- pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictRadialGradient));
- if (!pPicture->pSourcePict) {
- *error = BadAlloc;
- free(pPicture);
- return 0;
- }
- radial = &pPicture->pSourcePict->radial;
-
- radial->type = SourcePictTypeRadial;
- radial->c1.x = inner->x;
- radial->c1.y = inner->y;
- radial->c1.radius = innerRadius;
- radial->c2.x = outer->x;
- radial->c2.y = outer->y;
- radial->c2.radius = outerRadius;
-
- initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
- if (*error) {
- free(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) malloc(sizeof(PictConicalGradient));
- if (!pPicture->pSourcePict) {
- *error = BadAlloc;
- free(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) {
- free(pPicture);
- return 0;
- }
- return pPicture;
-}
-
-#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
-
-#define NEXT_PTR(_type) ((_type) ulist++->ptr)
-
-int
-ChangePicture (PicturePtr pPicture,
- Mask vmask,
- XID *vlist,
- DevUnion *ulist,
- ClientPtr client)
-{
- ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
- PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0;
- BITS32 index2;
- int error = 0;
- BITS32 maskQ;
-
- pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
- maskQ = vmask;
- while (vmask && !error)
- {
- index2 = (BITS32) lowbit (vmask);
- vmask &= ~index2;
- pPicture->stateChanges |= index2;
- switch (index2)
- {
- case CPRepeat:
- {
- unsigned int newr;
- newr = NEXT_VAL(unsigned int);
- if (newr <= RepeatReflect)
- {
- pPicture->repeat = (newr != RepeatNone);
- pPicture->repeatType = newr;
- }
- else
- {
- client->errorValue = newr;
- error = BadValue;
- }
- }
- break;
- case CPAlphaMap:
- {
- PicturePtr pAlpha;
-
- if (vlist)
- {
- Picture pid = NEXT_VAL(Picture);
-
- if (pid == None)
- pAlpha = 0;
- else
- {
- error = dixLookupResourceByType((pointer *)&pAlpha, pid,
- PictureType, client,
- DixReadAccess);
- if (error != Success)
- {
- client->errorValue = pid;
- break;
- }
- if (pAlpha->pDrawable == NULL ||
- pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
- {
- client->errorValue = pid;
- error = BadMatch;
- break;
- }
- }
- }
- else
- pAlpha = NEXT_PTR(PicturePtr);
- if (!error)
- {
- if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
- pAlpha->refcnt++;
- if (pPicture->alphaMap)
- FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
- pPicture->alphaMap = pAlpha;
- }
- }
- break;
- case CPAlphaXOrigin:
- pPicture->alphaOrigin.x = NEXT_VAL(INT16);
- break;
- case CPAlphaYOrigin:
- pPicture->alphaOrigin.y = NEXT_VAL(INT16);
- break;
- case CPClipXOrigin:
- pPicture->clipOrigin.x = NEXT_VAL(INT16);
- break;
- case CPClipYOrigin:
- pPicture->clipOrigin.y = NEXT_VAL(INT16);
- break;
- case CPClipMask:
- {
- Pixmap pid;
- PixmapPtr pPixmap;
- int clipType;
- if (!pScreen)
- return BadDrawable;
-
- if (vlist)
- {
- pid = NEXT_VAL(Pixmap);
- if (pid == None)
- {
- clipType = CT_NONE;
- pPixmap = NullPixmap;
- }
- else
- {
- clipType = CT_PIXMAP;
- error = dixLookupResourceByType((pointer *)&pPixmap, pid,
- RT_PIXMAP, client,
- DixReadAccess);
- if (error != Success)
- {
- client->errorValue = pid;
- break;
- }
- }
- }
- else
- {
- pPixmap = NEXT_PTR(PixmapPtr);
- if (pPixmap)
- clipType = CT_PIXMAP;
- else
- clipType = CT_NONE;
- }
-
- if (pPixmap)
- {
- if ((pPixmap->drawable.depth != 1) ||
- (pPixmap->drawable.pScreen != pScreen))
- {
- error = BadMatch;
- break;
- }
- else
- {
- clipType = CT_PIXMAP;
- pPixmap->refcnt++;
- }
- }
- error = (*ps->ChangePictureClip)(pPicture, clipType,
- (pointer)pPixmap, 0);
- break;
- }
- case CPGraphicsExposure:
- {
- unsigned int newe;
- newe = NEXT_VAL(unsigned int);
- if (newe <= xTrue)
- pPicture->graphicsExposures = newe;
- else
- {
- client->errorValue = newe;
- error = BadValue;
- }
- }
- break;
- case CPSubwindowMode:
- {
- unsigned int news;
- news = NEXT_VAL(unsigned int);
- if (news == ClipByChildren || news == IncludeInferiors)
- pPicture->subWindowMode = news;
- else
- {
- client->errorValue = news;
- error = BadValue;
- }
- }
- break;
- case CPPolyEdge:
- {
- unsigned int newe;
- newe = NEXT_VAL(unsigned int);
- if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth)
- pPicture->polyEdge = newe;
- else
- {
- client->errorValue = newe;
- error = BadValue;
- }
- }
- break;
- case CPPolyMode:
- {
- unsigned int newm;
- newm = NEXT_VAL(unsigned int);
- if (newm == PolyModePrecise || newm == PolyModeImprecise)
- pPicture->polyMode = newm;
- else
- {
- client->errorValue = newm;
- error = BadValue;
- }
- }
- break;
- case CPDither:
- (void) NEXT_VAL(Atom); /* unimplemented */
- break;
- case CPComponentAlpha:
- {
- unsigned int newca;
-
- newca = NEXT_VAL (unsigned int);
- if (newca <= xTrue)
- pPicture->componentAlpha = newca;
- else
- {
- client->errorValue = newca;
- error = BadValue;
- }
- }
- break;
- default:
- client->errorValue = maskQ;
- error = BadValue;
- break;
- }
- }
- if (ps)
- (*ps->ChangePicture) (pPicture, maskQ);
- return error;
-}
-
-int
-SetPictureClipRects (PicturePtr pPicture,
- int xOrigin,
- int yOrigin,
- int nRect,
- xRectangle *rects)
-{
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- RegionPtr clientClip;
- int result;
-
- clientClip = RegionFromRects(nRect, rects, CT_UNSORTED);
- if (!clientClip)
- return BadAlloc;
- result =(*ps->ChangePictureClip) (pPicture, CT_REGION,
- (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
-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 = RegionCreate(RegionExtents(pRegion),
- RegionNumRects(pRegion));
- if (!clientClip)
- return BadAlloc;
- if (!RegionCopy(clientClip, pRegion))
- {
- RegionDestroy(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;
-}
-
-static Bool
-transformIsIdentity(PictTransform *t)
-{
- return ((t->matrix[0][0] == t->matrix[1][1]) &&
- (t->matrix[0][0] == t->matrix[2][2]) &&
- (t->matrix[0][0] != 0) &&
- (t->matrix[0][1] == 0) &&
- (t->matrix[0][2] == 0) &&
- (t->matrix[1][0] == 0) &&
- (t->matrix[1][2] == 0) &&
- (t->matrix[2][0] == 0) &&
- (t->matrix[2][1] == 0));
-}
-
-int
-SetPictureTransform (PicturePtr pPicture,
- PictTransform *transform)
-{
- if (transform && transformIsIdentity (transform))
- transform = 0;
-
- if (transform)
- {
- if (!pPicture->transform)
- {
- pPicture->transform = (PictTransform *) malloc(sizeof (PictTransform));
- if (!pPicture->transform)
- return BadAlloc;
- }
- *pPicture->transform = *transform;
- }
- else
- {
- free(pPicture->transform);
- pPicture->transform = NULL;
- }
- pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
-
- if (pPicture->pDrawable != NULL) {
- int result;
- PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
-
- result = (*ps->ChangePictureTransform) (pPicture, transform);
-
- return result;
- }
-
- 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 = RegionCreate(
- RegionExtents(srcClientClip),
- RegionNumRects(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:
- break;
- case CPComponentAlpha:
- pDst->componentAlpha = pSrc->componentAlpha;
- break;
- }
- mask &= ~bit;
- }
-
- (*ps->ChangePicture)(pDst, origMask);
-}
-
-static void
-ValidateOnePicture (PicturePtr pPicture)
-{
- if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber)
- {
- PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
-
- (*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
- pPicture->stateChanges = 0;
- pPicture->serialNumber = pPicture->pDrawable->serialNumber;
- }
-}
-
-void
-ValidatePicture(PicturePtr pPicture)
-{
- ValidateOnePicture (pPicture);
- if (pPicture->alphaMap)
- ValidateOnePicture (pPicture->alphaMap);
-}
-
-int
-FreePicture (pointer value,
- XID pid)
-{
- PicturePtr pPicture = (PicturePtr) value;
-
- if (--pPicture->refcnt == 0)
- {
- free(pPicture->transform);
-
- if (pPicture->pSourcePict)
- {
- if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
- free(pPicture->pSourcePict->linear.stops);
-
- free(pPicture->pSourcePict);
- }
-
- if (pPicture->pDrawable)
- {
- 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 *)dixLookupPrivateAddr
- (&pWindow->devPrivates, PictureWindowPrivateKey);
- *pPrev;
- pPrev = &(*pPrev)->pNext)
- {
- if (*pPrev == pPicture)
- {
- *pPrev = pPicture->pNext;
- break;
- }
- }
- }
- else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
- {
- (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
- }
- }
- dixFreeObjectWithPrivates(pPicture, PRIVATE_PICTURE);
- }
- return Success;
-}
-
-int
-FreePictFormat (pointer pPictFormat,
- XID pid)
-{
- return Success;
-}
-
-/**
- * ReduceCompositeOp is used to choose simpler ops for cases where alpha
- * channels are always one and so math on the alpha channel per pixel becomes
- * unnecessary. It may also avoid destination reads sometimes if apps aren't
- * being careful to avoid these cases.
- */
-static CARD8
-ReduceCompositeOp (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
- INT16 xSrc, INT16 ySrc, CARD16 width, CARD16 height)
-{
- Bool no_src_alpha, no_dst_alpha;
-
- /* Sampling off the edge of a RepeatNone picture introduces alpha
- * even if the picture itself doesn't have alpha. We don't try to
- * detect every case where we don't sample off the edge, just the
- * simplest case where there is no transform on the source
- * picture.
- */
- no_src_alpha = PICT_FORMAT_COLOR(pSrc->format) &&
- PICT_FORMAT_A(pSrc->format) == 0 &&
- (pSrc->repeatType != RepeatNone ||
- (!pSrc->transform &&
- xSrc >= 0 && ySrc >= 0 &&
- xSrc + width <= pSrc->pDrawable->width &&
- ySrc + height <= pSrc->pDrawable->height)) &&
- pSrc->alphaMap == NULL &&
- pMask == NULL;
- no_dst_alpha = PICT_FORMAT_COLOR(pDst->format) &&
- PICT_FORMAT_A(pDst->format) == 0 &&
- pDst->alphaMap == NULL;
-
- /* TODO, maybe: Conjoint and Disjoint op reductions? */
-
- /* Deal with simplifications where the source alpha is always 1. */
- if (no_src_alpha)
- {
- switch (op) {
- case PictOpOver:
- op = PictOpSrc;
- break;
- case PictOpInReverse:
- op = PictOpDst;
- break;
- case PictOpOutReverse:
- op = PictOpClear;
- break;
- case PictOpAtop:
- op = PictOpIn;
- break;
- case PictOpAtopReverse:
- op = PictOpOverReverse;
- break;
- case PictOpXor:
- op = PictOpOut;
- break;
- default:
- break;
- }
- }
-
- /* Deal with simplifications when the destination alpha is always 1 */
- if (no_dst_alpha)
- {
- switch (op) {
- case PictOpOverReverse:
- op = PictOpDst;
- break;
- case PictOpIn:
- op = PictOpSrc;
- break;
- case PictOpOut:
- op = PictOpClear;
- break;
- case PictOpAtop:
- op = PictOpOver;
- break;
- case PictOpXor:
- op = PictOpOutReverse;
- break;
- default:
- break;
- }
- }
-
- /* Reduce some con/disjoint ops to the basic names. */
- switch (op) {
- case PictOpDisjointClear:
- case PictOpConjointClear:
- op = PictOpClear;
- break;
- case PictOpDisjointSrc:
- case PictOpConjointSrc:
- op = PictOpSrc;
- break;
- case PictOpDisjointDst:
- case PictOpConjointDst:
- op = PictOpDst;
- break;
- default:
- break;
- }
-
- return op;
-}
-
-void
-CompositePicture (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
-{
- PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
-
- ValidatePicture (pSrc);
- if (pMask)
- ValidatePicture (pMask);
- ValidatePicture (pDst);
-
- op = ReduceCompositeOp (op, pSrc, pMask, pDst, xSrc, ySrc, width, height);
- if (op == PictOpDst)
- return;
-
- (*ps->Composite) (op,
- pSrc,
- pMask,
- pDst,
- xSrc,
- ySrc,
- xMask,
- yMask,
- xDst,
- yDst,
- width,
- height);
-}
-
-void
-CompositeRects (CARD8 op,
- PicturePtr pDst,
- xRenderColor *color,
- int nRect,
- xRectangle *rects)
-{
- PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
-
- ValidatePicture (pDst);
- (*ps->CompositeRects) (op, pDst, color, nRect, rects);
-}
-
-void
-CompositeTrapezoids (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int ntrap,
- xTrapezoid *traps)
-{
- PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
-
- ValidatePicture (pSrc);
- ValidatePicture (pDst);
- (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
-}
-
-void
-CompositeTriangles (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int ntriangles,
- xTriangle *triangles)
-{
- PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
-
- ValidatePicture (pSrc);
- ValidatePicture (pDst);
- (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles);
-}
-
-void
-CompositeTriStrip (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int npoints,
- xPointFixed *points)
-{
- xTriangle *tris, *tri;
- int ntri;
-
- if (npoints < 3)
- return;
- ntri = npoints - 2;
- tris = malloc(ntri * sizeof (xTriangle));
- if (!tris)
- return;
- for (tri = tris; npoints >= 3; npoints--, points++, tri++)
- {
- tri->p1 = points[0];
- tri->p2 = points[1];
- tri->p3 = points[2];
- }
- CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
- free(tris);
-}
-
-void
-CompositeTriFan (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int npoints,
- xPointFixed *points)
-{
- xTriangle *tris, *tri;
- xPointFixed *first;
- int ntri;
-
- if (npoints < 3)
- return;
- ntri = npoints - 2;
- tris = malloc(ntri * sizeof (xTriangle));
- if (!tris)
- return;
- first = points++;
- for (tri = tris; npoints >= 3; npoints--, points++, tri++)
- {
- tri->p1 = *first;
- tri->p2 = points[0];
- tri->p3 = points[1];
- }
- CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
- free(tris);
-}
-
-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);
-}
-
+/* + * + * 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "misc.h" +#include "scrnintstr.h" +#include "os.h" +#include "regionstr.h" +#include "validate.h" +#include "windowstr.h" +#include "input.h" +#include "resource.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "dixstruct.h" +#include "gcstruct.h" +#include "servermd.h" +#include "picturestr.h" +#include "xace.h" + +DevPrivateKeyRec PictureScreenPrivateKeyRec; +DevPrivateKeyRec PictureWindowPrivateKeyRec; +static int PictureGeneration; +RESTYPE PictureType; +RESTYPE PictFormatType; +RESTYPE GlyphSetType; +int PictureCmapPolicy = PictureCmapPolicyDefault; + +Bool +PictureDestroyWindow (WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + PicturePtr pPicture; + PictureScreenPtr ps = GetPictureScreen(pScreen); + Bool ret; + + while ((pPicture = GetPictureWindow(pWindow))) + { + SetPictureWindow(pWindow, pPicture->pNext); + if (pPicture->id) + FreeResource (pPicture->id, PictureType); + FreePicture ((pointer) pPicture, pPicture->id); + } + pScreen->DestroyWindow = ps->DestroyWindow; + ret = (*pScreen->DestroyWindow) (pWindow); + ps->DestroyWindow = pScreen->DestroyWindow; + pScreen->DestroyWindow = PictureDestroyWindow; + return ret; +} + +Bool +PictureCloseScreen (int index, ScreenPtr pScreen) +{ + PictureScreenPtr ps = GetPictureScreen(pScreen); + Bool ret; + int n; + + pScreen->CloseScreen = ps->CloseScreen; + ret = (*pScreen->CloseScreen) (index, pScreen); + PictureResetFilters (pScreen); + for (n = 0; n < ps->nformats; n++) + if (ps->formats[n].type == PictTypeIndexed) + (*ps->CloseIndexed) (pScreen, &ps->formats[n]); + GlyphUninit (pScreen); + SetPictureScreen(pScreen, 0); + free(ps->formats); + free(ps); + return ret; +} + +void +PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef) +{ + ScreenPtr pScreen = pColormap->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + + pScreen->StoreColors = ps->StoreColors; + (*pScreen->StoreColors) (pColormap, ndef, pdef); + ps->StoreColors = pScreen->StoreColors; + pScreen->StoreColors = PictureStoreColors; + + if (pColormap->class == PseudoColor || pColormap->class == GrayScale) + { + PictFormatPtr format = ps->formats; + int nformats = ps->nformats; + + while (nformats--) + { + if (format->type == PictTypeIndexed && + format->index.pColormap == pColormap) + { + (*ps->UpdateIndexed) (pScreen, format, ndef, pdef); + break; + } + format++; + } + } +} + +static int +visualDepth (ScreenPtr pScreen, VisualPtr pVisual) +{ + int d, v; + DepthPtr pDepth; + + for (d = 0; d < pScreen->numDepths; d++) + { + pDepth = &pScreen->allowedDepths[d]; + for (v = 0; v < pDepth->numVids; v++) + if (pDepth->vids[v] == pVisual->vid) + return pDepth->depth; + } + return 0; +} + +typedef struct _formatInit { + CARD32 format; + CARD8 depth; +} FormatInitRec, *FormatInitPtr; + +static int +addFormat (FormatInitRec formats[256], + int nformat, + CARD32 format, + CARD8 depth) +{ + int n; + + for (n = 0; n < nformat; n++) + if (formats[n].format == format && formats[n].depth == depth) + return nformat; + formats[nformat].format = format; + formats[nformat].depth = depth; + return ++nformat; +} + +#define Mask(n) ((1 << (n)) - 1) + +PictFormatPtr +PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp) +{ + int nformats, f; + PictFormatPtr pFormats; + FormatInitRec formats[1024]; + CARD32 format; + CARD8 depth; + VisualPtr pVisual; + int v; + int bpp; + int type; + int r, g, b; + int d; + DepthPtr pDepth; + + nformats = 0; + /* formats required by protocol */ + formats[nformats].format = PICT_a1; + formats[nformats].depth = 1; + nformats++; + formats[nformats].format = PICT_FORMAT(BitsPerPixel(8), + PICT_TYPE_A, + 8, 0, 0, 0); + formats[nformats].depth = 8; + nformats++; + formats[nformats].format = PICT_FORMAT(BitsPerPixel(4), + PICT_TYPE_A, + 4, 0, 0, 0); + formats[nformats].depth = 4; + nformats++; + formats[nformats].format = PICT_a8r8g8b8; + formats[nformats].depth = 32; + nformats++; + formats[nformats].format = PICT_x8r8g8b8; + formats[nformats].depth = 32; + nformats++; + formats[nformats].format = PICT_b8g8r8a8; + formats[nformats].depth = 32; + nformats++; + formats[nformats].format = PICT_b8g8r8x8; + formats[nformats].depth = 32; + nformats++; + + /* 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); + type = PICT_TYPE_OTHER; + /* + * Current rendering code supports only three direct formats, + * fields must be packed together at the bottom of the pixel + */ + if (pVisual->offsetBlue == 0 && + pVisual->offsetGreen == b && + pVisual->offsetRed == b + g) + { + type = PICT_TYPE_ARGB; + } + else if (pVisual->offsetRed == 0 && + pVisual->offsetGreen == r && + pVisual->offsetBlue == r + g) + { + type = PICT_TYPE_ABGR; + } + else if (pVisual->offsetRed == pVisual->offsetGreen - r && + pVisual->offsetGreen == pVisual->offsetBlue - g && + pVisual->offsetBlue == bpp - b) + { + type = PICT_TYPE_BGRA; + } + if (type != PICT_TYPE_OTHER) + { + format = PICT_FORMAT(bpp, type, 0, r, g, b); + nformats = addFormat (formats, nformats, format, depth); + } + break; + case StaticColor: + case PseudoColor: + format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v); + nformats = addFormat (formats, nformats, format, depth); + break; + case StaticGray: + case GrayScale: + format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v); + nformats = addFormat (formats, nformats, format, depth); + break; + } + } + /* + * Walk supported depths and add useful Direct formats + */ + for (d = 0; d < pScreen->numDepths; d++) + { + 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); + } + /* depth 15 formats */ + if (pDepth->depth >= 15) + { + nformats = addFormat (formats, nformats, + PICT_x1r5g5b5, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_x1b5g5r5, pDepth->depth); + } + /* 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_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); + } + break; + case 24: + if (pDepth->depth >= 24) + { + nformats = addFormat (formats, nformats, + PICT_r8g8b8, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_b8g8r8, pDepth->depth); + } + break; + case 32: + if (pDepth->depth >= 24) + { + nformats = addFormat (formats, nformats, + PICT_x8r8g8b8, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_x8b8g8r8, pDepth->depth); + } + if (pDepth->depth >= 30) + { + nformats = addFormat (formats, nformats, + PICT_a2r10g10b10, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_x2r10g10b10, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_a2b10g10r10, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_x2b10g10r10, pDepth->depth); + } + break; + } + } + + + pFormats = 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_BGRA: + pFormats[f].type = PictTypeDirect; + + pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format)); + pFormats[f].direct.blue = (PICT_FORMAT_BPP(format) - PICT_FORMAT_B(format)); + + pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format)); + pFormats[f].direct.green = (PICT_FORMAT_BPP(format) - PICT_FORMAT_B(format) - + PICT_FORMAT_G(format)); + + pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format)); + pFormats[f].direct.red = (PICT_FORMAT_BPP(format) - PICT_FORMAT_B(format) - + PICT_FORMAT_G(format) - PICT_FORMAT_R(format)); + + pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format)); + pFormats[f].direct.alpha = 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; + } + } + *nformatp = nformats; + 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 +PictureInitIndexedFormat(ScreenPtr pScreen, PictFormatPtr format) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + + if (format->type != PictTypeIndexed || format->index.pColormap) + return TRUE; + + if (format->index.vid == pScreen->rootVisual) { + dixLookupResourceByType((pointer *)&format->index.pColormap, + pScreen->defColormap, RT_COLORMAP, + serverClient, DixGetAttrAccess); + } else { + VisualPtr pVisual = PictureFindVisual(pScreen, format->index.vid); + if (CreateColormap(FakeClientID (0), pScreen, pVisual, + &format->index.pColormap, AllocNone, 0) + != Success) + return FALSE; + } + if (!ps->InitIndexed(pScreen, format)) + return FALSE; + return TRUE; +} + +static Bool +PictureInitIndexedFormats (ScreenPtr pScreen) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + PictFormatPtr format; + int nformat; + + if (!ps) + return FALSE; + format = ps->formats; + nformat = ps->nformats; + while (nformat--) + if (!PictureInitIndexedFormat(pScreen, format++)) + return FALSE; + return TRUE; +} + +Bool +PictureFinishInit (void) +{ + int s; + + for (s = 0; s < screenInfo.numScreens; s++) + { + if (!PictureInitIndexedFormats (screenInfo.screens[s])) + return FALSE; + (void) AnimCurInit (screenInfo.screens[s]); + } + + return TRUE; +} + +Bool +PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + + if (!ps) + return FALSE; + ps->subpixel = subpixel; + return TRUE; + +} + +int +PictureGetSubpixelOrder (ScreenPtr pScreen) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + + if (!ps) + return SubPixelUnknown; + return ps->subpixel; +} + +PictFormatPtr +PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + PictFormatPtr format; + int nformat; + int type; + + if (!ps) + return 0; + format = ps->formats; + nformat = ps->nformats; + switch (pVisual->class) { + case StaticGray: + case GrayScale: + case StaticColor: + case PseudoColor: + type = PictTypeIndexed; + break; + case TrueColor: + case DirectColor: + type = PictTypeDirect; + break; + default: + return 0; + } + while (nformat--) + { + if (format->depth == depth && format->type == type) + { + if (type == PictTypeIndexed) + { + if (format->index.vid == pVisual->vid) + return format; + } + else + { + if (format->direct.redMask << format->direct.red == + pVisual->redMask && + format->direct.greenMask << format->direct.green == + pVisual->greenMask && + format->direct.blueMask << format->direct.blue == + pVisual->blueMask) + { + return format; + } + } + } + format++; + } + return 0; +} + +PictFormatPtr +PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + PictFormatPtr format; + int nformat; + + if (!ps) + return 0; + format = ps->formats; + nformat = ps->nformats; + while (nformat--) + { + if (format->depth == depth && format->format == (f & 0xffffff)) + return format; + format++; + } + return 0; +} + +int +PictureParseCmapPolicy (const char *name) +{ + if ( strcmp (name, "default" ) == 0) + return PictureCmapPolicyDefault; + else if ( strcmp (name, "mono" ) == 0) + return PictureCmapPolicyMono; + else if ( strcmp (name, "gray" ) == 0) + return PictureCmapPolicyGray; + else if ( strcmp (name, "color" ) == 0) + return PictureCmapPolicyColor; + else if ( strcmp (name, "all" ) == 0) + return PictureCmapPolicyAll; + else + return PictureCmapPolicyInvalid; +} + +Bool +PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) +{ + PictureScreenPtr ps; + int n; + CARD32 type, a, r, g, b; + + if (PictureGeneration != serverGeneration) + { + PictureType = CreateNewResourceType (FreePicture, "PICTURE"); + if (!PictureType) + return FALSE; + PictFormatType = CreateNewResourceType (FreePictFormat, "PICTFORMAT"); + if (!PictFormatType) + return FALSE; + GlyphSetType = CreateNewResourceType (FreeGlyphSet, "GLYPHSET"); + if (!GlyphSetType) + return FALSE; + PictureGeneration = serverGeneration; + } + if (!dixRegisterPrivateKey(&PictureScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + if (!dixRegisterPrivateKey(&PictureWindowPrivateKeyRec, PRIVATE_WINDOW, 0)) + return FALSE; + + if (!formats) + { + formats = PictureCreateDefaultFormats (pScreen, &nformats); + if (!formats) + return FALSE; + } + for (n = 0; n < nformats; n++) + { + if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n))) + { + free(formats); + return FALSE; + } + if (formats[n].type == PictTypeIndexed) + { + VisualPtr pVisual = PictureFindVisual (pScreen, 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 if (formats[n].direct.red == 0) + type = PICT_TYPE_ABGR; + else + type = PICT_TYPE_BGRA; + 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); + } + ps = (PictureScreenPtr) malloc(sizeof (PictureScreenRec)); + if (!ps) + { + free(formats); + return FALSE; + } + SetPictureScreen(pScreen, ps); + + ps->formats = formats; + ps->fallback = formats; + ps->nformats = nformats; + + ps->filters = 0; + ps->nfilters = 0; + ps->filterAliases = 0; + ps->nfilterAliases = 0; + + ps->subpixel = SubPixelUnknown; + + ps->CloseScreen = pScreen->CloseScreen; + ps->DestroyWindow = pScreen->DestroyWindow; + ps->StoreColors = pScreen->StoreColors; + pScreen->DestroyWindow = PictureDestroyWindow; + pScreen->CloseScreen = PictureCloseScreen; + pScreen->StoreColors = PictureStoreColors; + + if (!PictureSetDefaultFilters (pScreen)) + { + PictureResetFilters (pScreen); + SetPictureScreen(pScreen, 0); + free(formats); + free(ps); + return FALSE; + } + + return TRUE; +} + +void +SetPictureToDefaults (PicturePtr pPicture) +{ + pPicture->refcnt = 1; + pPicture->repeat = 0; + pPicture->graphicsExposures = FALSE; + pPicture->subWindowMode = ClipByChildren; + pPicture->polyEdge = PolyEdgeSharp; + pPicture->polyMode = PolyModePrecise; + pPicture->freeCompClip = FALSE; + pPicture->clientClipType = CT_NONE; + pPicture->componentAlpha = FALSE; + pPicture->repeatType = RepeatNone; + + pPicture->alphaMap = 0; + pPicture->alphaOrigin.x = 0; + pPicture->alphaOrigin.y = 0; + + pPicture->clipOrigin.x = 0; + pPicture->clipOrigin.y = 0; + pPicture->clientClip = 0; + + pPicture->transform = 0; + + pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE); + pPicture->filter_params = 0; + pPicture->filter_nparams = 0; + + pPicture->serialNumber = GC_CHANGE_SERIAL_BIT; + pPicture->stateChanges = -1; + pPicture->pSourcePict = 0; +} + +PicturePtr +CreatePicture (Picture pid, + DrawablePtr pDrawable, + PictFormatPtr pFormat, + Mask vmask, + XID *vlist, + ClientPtr client, + int *error) +{ + PicturePtr pPicture; + PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen); + + pPicture = dixAllocateObjectWithPrivates(PictureRec, PRIVATE_PICTURE); + if (!pPicture) + { + *error = BadAlloc; + return 0; + } + + pPicture->id = pid; + pPicture->pDrawable = pDrawable; + pPicture->pFormat = pFormat; + pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24); + + /* security creation/labeling check */ + *error = XaceHook(XACE_RESOURCE_ACCESS, client, pid, PictureType, pPicture, + RT_PIXMAP, pDrawable, DixCreateAccess|DixSetAttrAccess); + if (*error != Success) + goto out; + + if (pDrawable->type == DRAWABLE_PIXMAP) + { + ++((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); +out: + if (*error != Success) + { + FreePicture (pPicture, (XID) 0); + pPicture = 0; + } + return pPicture; +} + +static CARD32 xRenderColorToCard32(xRenderColor c) +{ + return + (c.alpha >> 8 << 24) | + (c.red >> 8 << 16) | + (c.green & 0xff00) | + (c.blue >> 8); +} + +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->gradient.stops = malloc(stopCount*sizeof(PictGradientStop)); + if (!pGradient->gradient.stops) { + *error = BadAlloc; + return; + } + + pGradient->gradient.nstops = stopCount; + + for (i = 0; i < stopCount; ++i) { + pGradient->gradient.stops[i].x = stopPoints[i]; + pGradient->gradient.stops[i].color = stopColors[i]; + } +} + +static PicturePtr createSourcePicture(void) +{ + PicturePtr pPicture; + pPicture = dixAllocateObjectWithPrivates(PictureRec, PRIVATE_PICTURE); + pPicture->pDrawable = 0; + pPicture->pFormat = 0; + pPicture->pNext = 0; + pPicture->format = PICT_a8r8g8b8; + + 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) malloc(sizeof(PictSolidFill)); + if (!pPicture->pSourcePict) { + *error = BadAlloc; + free(pPicture); + return 0; + } + pPicture->pSourcePict->type = SourcePictTypeSolidFill; + pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color); + return pPicture; +} + +PicturePtr +CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2, + int nStops, xFixed *stops, xRenderColor *colors, int *error) +{ + PicturePtr pPicture; + + if (nStops < 2) { + *error = BadValue; + return 0; + } + + pPicture = createSourcePicture(); + if (!pPicture) { + *error = BadAlloc; + return 0; + } + + pPicture->id = pid; + pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictLinearGradient)); + if (!pPicture->pSourcePict) { + *error = BadAlloc; + free(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) { + free(pPicture); + return 0; + } + return pPicture; +} + +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; + } + + pPicture->id = pid; + pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictRadialGradient)); + if (!pPicture->pSourcePict) { + *error = BadAlloc; + free(pPicture); + return 0; + } + radial = &pPicture->pSourcePict->radial; + + radial->type = SourcePictTypeRadial; + radial->c1.x = inner->x; + radial->c1.y = inner->y; + radial->c1.radius = innerRadius; + radial->c2.x = outer->x; + radial->c2.y = outer->y; + radial->c2.radius = outerRadius; + + initGradient(pPicture->pSourcePict, nStops, stops, colors, error); + if (*error) { + free(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) malloc(sizeof(PictConicalGradient)); + if (!pPicture->pSourcePict) { + *error = BadAlloc; + free(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) { + free(pPicture); + return 0; + } + return pPicture; +} + +#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val) + +#define NEXT_PTR(_type) ((_type) ulist++->ptr) + +int +ChangePicture (PicturePtr pPicture, + Mask vmask, + XID *vlist, + DevUnion *ulist, + ClientPtr client) +{ + ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0; + PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0; + BITS32 index2; + int error = 0; + BITS32 maskQ; + + pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT; + maskQ = vmask; + while (vmask && !error) + { + index2 = (BITS32) lowbit (vmask); + vmask &= ~index2; + pPicture->stateChanges |= index2; + switch (index2) + { + case CPRepeat: + { + unsigned int newr; + newr = NEXT_VAL(unsigned int); + if (newr <= RepeatReflect) + { + pPicture->repeat = (newr != RepeatNone); + pPicture->repeatType = newr; + } + else + { + client->errorValue = newr; + error = BadValue; + } + } + break; + case CPAlphaMap: + { + PicturePtr pAlpha; + + if (vlist) + { + Picture pid = NEXT_VAL(Picture); + + if (pid == None) + pAlpha = 0; + else + { + error = dixLookupResourceByType((pointer *)&pAlpha, pid, + PictureType, client, + DixReadAccess); + if (error != Success) + { + client->errorValue = pid; + break; + } + if (pAlpha->pDrawable == NULL || + pAlpha->pDrawable->type != DRAWABLE_PIXMAP) + { + client->errorValue = pid; + error = BadMatch; + break; + } + } + } + else + pAlpha = NEXT_PTR(PicturePtr); + if (!error) + { + if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP) + pAlpha->refcnt++; + if (pPicture->alphaMap) + FreePicture ((pointer) pPicture->alphaMap, (XID) 0); + pPicture->alphaMap = pAlpha; + } + } + break; + case CPAlphaXOrigin: + pPicture->alphaOrigin.x = NEXT_VAL(INT16); + break; + case CPAlphaYOrigin: + pPicture->alphaOrigin.y = NEXT_VAL(INT16); + break; + case CPClipXOrigin: + pPicture->clipOrigin.x = NEXT_VAL(INT16); + break; + case CPClipYOrigin: + pPicture->clipOrigin.y = NEXT_VAL(INT16); + break; + case CPClipMask: + { + Pixmap pid; + PixmapPtr pPixmap; + int clipType; + if (!pScreen) + return BadDrawable; + + if (vlist) + { + pid = NEXT_VAL(Pixmap); + if (pid == None) + { + clipType = CT_NONE; + pPixmap = NullPixmap; + } + else + { + clipType = CT_PIXMAP; + error = dixLookupResourceByType((pointer *)&pPixmap, pid, + RT_PIXMAP, client, + DixReadAccess); + if (error != Success) + { + client->errorValue = pid; + break; + } + } + } + else + { + pPixmap = NEXT_PTR(PixmapPtr); + if (pPixmap) + clipType = CT_PIXMAP; + else + clipType = CT_NONE; + } + + if (pPixmap) + { + if ((pPixmap->drawable.depth != 1) || + (pPixmap->drawable.pScreen != pScreen)) + { + error = BadMatch; + break; + } + else + { + clipType = CT_PIXMAP; + pPixmap->refcnt++; + } + } + error = (*ps->ChangePictureClip)(pPicture, clipType, + (pointer)pPixmap, 0); + break; + } + case CPGraphicsExposure: + { + unsigned int newe; + newe = NEXT_VAL(unsigned int); + if (newe <= xTrue) + pPicture->graphicsExposures = newe; + else + { + client->errorValue = newe; + error = BadValue; + } + } + break; + case CPSubwindowMode: + { + unsigned int news; + news = NEXT_VAL(unsigned int); + if (news == ClipByChildren || news == IncludeInferiors) + pPicture->subWindowMode = news; + else + { + client->errorValue = news; + error = BadValue; + } + } + break; + case CPPolyEdge: + { + unsigned int newe; + newe = NEXT_VAL(unsigned int); + if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth) + pPicture->polyEdge = newe; + else + { + client->errorValue = newe; + error = BadValue; + } + } + break; + case CPPolyMode: + { + unsigned int newm; + newm = NEXT_VAL(unsigned int); + if (newm == PolyModePrecise || newm == PolyModeImprecise) + pPicture->polyMode = newm; + else + { + client->errorValue = newm; + error = BadValue; + } + } + break; + case CPDither: + (void) NEXT_VAL(Atom); /* unimplemented */ + break; + case CPComponentAlpha: + { + unsigned int newca; + + newca = NEXT_VAL (unsigned int); + if (newca <= xTrue) + pPicture->componentAlpha = newca; + else + { + client->errorValue = newca; + error = BadValue; + } + } + break; + default: + client->errorValue = maskQ; + error = BadValue; + break; + } + } + if (ps) + (*ps->ChangePicture) (pPicture, maskQ); + return error; +} + +int +SetPictureClipRects (PicturePtr pPicture, + int xOrigin, + int yOrigin, + int nRect, + xRectangle *rects) +{ + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + RegionPtr clientClip; + int result; + + clientClip = RegionFromRects(nRect, rects, CT_UNSORTED); + if (!clientClip) + return BadAlloc; + result =(*ps->ChangePictureClip) (pPicture, CT_REGION, + (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 +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 = RegionCreate(RegionExtents(pRegion), + RegionNumRects(pRegion)); + if (!clientClip) + return BadAlloc; + if (!RegionCopy(clientClip, pRegion)) + { + RegionDestroy(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; +} + +static Bool +transformIsIdentity(PictTransform *t) +{ + return ((t->matrix[0][0] == t->matrix[1][1]) && + (t->matrix[0][0] == t->matrix[2][2]) && + (t->matrix[0][0] != 0) && + (t->matrix[0][1] == 0) && + (t->matrix[0][2] == 0) && + (t->matrix[1][0] == 0) && + (t->matrix[1][2] == 0) && + (t->matrix[2][0] == 0) && + (t->matrix[2][1] == 0)); +} + +int +SetPictureTransform (PicturePtr pPicture, + PictTransform *transform) +{ + if (transform && transformIsIdentity (transform)) + transform = 0; + + if (transform) + { + if (!pPicture->transform) + { + pPicture->transform = (PictTransform *) malloc(sizeof (PictTransform)); + if (!pPicture->transform) + return BadAlloc; + } + *pPicture->transform = *transform; + } + else + { + free(pPicture->transform); + pPicture->transform = NULL; + } + pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT; + + if (pPicture->pDrawable != NULL) { + int result; + PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen); + + result = (*ps->ChangePictureTransform) (pPicture, transform); + + return result; + } + + 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 = RegionCreate( + RegionExtents(srcClientClip), + RegionNumRects(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: + break; + case CPComponentAlpha: + pDst->componentAlpha = pSrc->componentAlpha; + break; + } + mask &= ~bit; + } + + (*ps->ChangePicture)(pDst, origMask); +} + +static void +ValidateOnePicture (PicturePtr pPicture) +{ + if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber) + { + PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen); + + (*ps->ValidatePicture) (pPicture, pPicture->stateChanges); + pPicture->stateChanges = 0; + pPicture->serialNumber = pPicture->pDrawable->serialNumber; + } +} + +void +ValidatePicture(PicturePtr pPicture) +{ + ValidateOnePicture (pPicture); + if (pPicture->alphaMap) + ValidateOnePicture (pPicture->alphaMap); +} + +int +FreePicture (pointer value, + XID pid) +{ + PicturePtr pPicture = (PicturePtr) value; + + if (--pPicture->refcnt == 0) + { + free(pPicture->transform); + + if (pPicture->pSourcePict) + { + if (pPicture->pSourcePict->type != SourcePictTypeSolidFill) + free(pPicture->pSourcePict->linear.stops); + + free(pPicture->pSourcePict); + } + + if (pPicture->pDrawable) + { + 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 *)dixLookupPrivateAddr + (&pWindow->devPrivates, PictureWindowPrivateKey); + *pPrev; + pPrev = &(*pPrev)->pNext) + { + if (*pPrev == pPicture) + { + *pPrev = pPicture->pNext; + break; + } + } + } + else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP) + { + (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable); + } + } + dixFreeObjectWithPrivates(pPicture, PRIVATE_PICTURE); + } + return Success; +} + +int +FreePictFormat (pointer pPictFormat, + XID pid) +{ + return Success; +} + +/** + * ReduceCompositeOp is used to choose simpler ops for cases where alpha + * channels are always one and so math on the alpha channel per pixel becomes + * unnecessary. It may also avoid destination reads sometimes if apps aren't + * being careful to avoid these cases. + */ +static CARD8 +ReduceCompositeOp (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, + INT16 xSrc, INT16 ySrc, CARD16 width, CARD16 height) +{ + Bool no_src_alpha, no_dst_alpha; + + /* Sampling off the edge of a RepeatNone picture introduces alpha + * even if the picture itself doesn't have alpha. We don't try to + * detect every case where we don't sample off the edge, just the + * simplest case where there is no transform on the source + * picture. + */ + no_src_alpha = PICT_FORMAT_COLOR(pSrc->format) && + PICT_FORMAT_A(pSrc->format) == 0 && + (pSrc->repeatType != RepeatNone || + (!pSrc->transform && + xSrc >= 0 && ySrc >= 0 && + xSrc + width <= pSrc->pDrawable->width && + ySrc + height <= pSrc->pDrawable->height)) && + pSrc->alphaMap == NULL && + pMask == NULL; + no_dst_alpha = PICT_FORMAT_COLOR(pDst->format) && + PICT_FORMAT_A(pDst->format) == 0 && + pDst->alphaMap == NULL; + + /* TODO, maybe: Conjoint and Disjoint op reductions? */ + + /* Deal with simplifications where the source alpha is always 1. */ + if (no_src_alpha) + { + switch (op) { + case PictOpOver: + op = PictOpSrc; + break; + case PictOpInReverse: + op = PictOpDst; + break; + case PictOpOutReverse: + op = PictOpClear; + break; + case PictOpAtop: + op = PictOpIn; + break; + case PictOpAtopReverse: + op = PictOpOverReverse; + break; + case PictOpXor: + op = PictOpOut; + break; + default: + break; + } + } + + /* Deal with simplifications when the destination alpha is always 1 */ + if (no_dst_alpha) + { + switch (op) { + case PictOpOverReverse: + op = PictOpDst; + break; + case PictOpIn: + op = PictOpSrc; + break; + case PictOpOut: + op = PictOpClear; + break; + case PictOpAtop: + op = PictOpOver; + break; + case PictOpXor: + op = PictOpOutReverse; + break; + default: + break; + } + } + + /* Reduce some con/disjoint ops to the basic names. */ + switch (op) { + case PictOpDisjointClear: + case PictOpConjointClear: + op = PictOpClear; + break; + case PictOpDisjointSrc: + case PictOpConjointSrc: + op = PictOpSrc; + break; + case PictOpDisjointDst: + case PictOpConjointDst: + op = PictOpDst; + break; + default: + break; + } + + return op; +} + +void +CompositePicture (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + + ValidatePicture (pSrc); + if (pMask) + ValidatePicture (pMask); + ValidatePicture (pDst); + + op = ReduceCompositeOp (op, pSrc, pMask, pDst, xSrc, ySrc, width, height); + if (op == PictOpDst) + return; + + (*ps->Composite) (op, + pSrc, + pMask, + pDst, + xSrc, + ySrc, + xMask, + yMask, + xDst, + yDst, + width, + height); +} + +void +CompositeRects (CARD8 op, + PicturePtr pDst, + xRenderColor *color, + int nRect, + xRectangle *rects) +{ + PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + + ValidatePicture (pDst); + (*ps->CompositeRects) (op, pDst, color, nRect, rects); +} + +void +CompositeTrapezoids (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntrap, + xTrapezoid *traps) +{ + PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + + ValidatePicture (pSrc); + ValidatePicture (pDst); + (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps); +} + +void +CompositeTriangles (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntriangles, + xTriangle *triangles) +{ + PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + + ValidatePicture (pSrc); + ValidatePicture (pDst); + (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles); +} + +void +CompositeTriStrip (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoints, + xPointFixed *points) +{ + xTriangle *tris, *tri; + int ntri; + + if (npoints < 3) + return; + ntri = npoints - 2; + tris = malloc(ntri * sizeof (xTriangle)); + if (!tris) + return; + for (tri = tris; npoints >= 3; npoints--, points++, tri++) + { + tri->p1 = points[0]; + tri->p2 = points[1]; + tri->p3 = points[2]; + } + CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); + free(tris); +} + +void +CompositeTriFan (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoints, + xPointFixed *points) +{ + xTriangle *tris, *tri; + xPointFixed *first; + int ntri; + + if (npoints < 3) + return; + ntri = npoints - 2; + tris = malloc(ntri * sizeof (xTriangle)); + if (!tris) + return; + first = points++; + for (tri = tris; npoints >= 3; npoints--, points++, tri++) + { + tri->p1 = *first; + tri->p2 = points[0]; + tri->p3 = points[1]; + } + CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); + free(tris); +} + +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); +} + diff --git a/xorg-server/render/picturestr.h b/xorg-server/render/picturestr.h index 5b9df988b..7b7f9112d 100644 --- a/xorg-server/render/picturestr.h +++ b/xorg-server/render/picturestr.h @@ -1,648 +1,648 @@ -/*
- * 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.
- */
-
-#ifndef _PICTURESTR_H_
-#define _PICTURESTR_H_
-
-#include "scrnintstr.h"
-#include "glyphstr.h"
-#include "resource.h"
-#include "privates.h"
-
-typedef struct _DirectFormat {
- CARD16 red, redMask;
- CARD16 green, greenMask;
- CARD16 blue, blueMask;
- CARD16 alpha, alphaMask;
-} DirectFormatRec;
-
-typedef struct _IndexFormat {
- VisualID vid;
- ColormapPtr pColormap;
- int nvalues;
- xIndexValue *pValues;
- void *devPrivate;
-} IndexFormatRec;
-
-typedef struct _PictFormat {
- CARD32 id;
- CARD32 format; /* except bpp */
- unsigned char type;
- unsigned char depth;
- DirectFormatRec direct;
- IndexFormatRec index;
-} PictFormatRec;
-
-typedef struct pixman_vector PictVector, *PictVectorPtr;
-typedef struct pixman_transform PictTransform, *PictTransformPtr;
-
-#define pict_f_vector pixman_f_vector
-#define pict_f_transform pixman_f_transform
-
-#define PICT_GRADIENT_STOPTABLE_SIZE 1024
-#define SourcePictTypeSolidFill 0
-#define SourcePictTypeLinear 1
-#define SourcePictTypeRadial 2
-#define SourcePictTypeConical 3
-
-typedef struct _PictSolidFill {
- unsigned int type;
- CARD32 color;
-} PictSolidFill, *PictSolidFillPtr;
-
-typedef struct _PictGradientStop {
- xFixed x;
- xRenderColor color;
-} PictGradientStop, *PictGradientStopPtr;
-
-typedef struct _PictGradient {
- unsigned int type;
- int nstops;
- PictGradientStopPtr stops;
-} PictGradient, *PictGradientPtr;
-
-typedef struct _PictLinearGradient {
- unsigned int type;
- int nstops;
- PictGradientStopPtr stops;
- xPointFixed p1;
- xPointFixed p2;
-} PictLinearGradient, *PictLinearGradientPtr;
-
-typedef struct _PictCircle {
- xFixed x;
- xFixed y;
- xFixed radius;
-} PictCircle, *PictCirclePtr;
-
-typedef struct _PictRadialGradient {
- unsigned int type;
- int nstops;
- PictGradientStopPtr stops;
- PictCircle c1;
- PictCircle c2;
-} PictRadialGradient, *PictRadialGradientPtr;
-
-typedef struct _PictConicalGradient {
- unsigned int type;
- int nstops;
- PictGradientStopPtr stops;
- xPointFixed center;
- xFixed angle;
-} PictConicalGradient, *PictConicalGradientPtr;
-
-typedef union _SourcePict {
- unsigned int type;
- PictSolidFill solidFill;
- PictGradient gradient;
- PictLinearGradient linear;
- PictRadialGradient radial;
- PictConicalGradient conical;
-} SourcePict, *SourcePictPtr;
-
-typedef struct _Picture {
- DrawablePtr pDrawable;
- PictFormatPtr pFormat;
- PictFormatShort format; /* PICT_FORMAT */
- int refcnt;
- CARD32 id;
- unsigned int repeat : 1;
- unsigned int graphicsExposures : 1;
- unsigned int subWindowMode : 1;
- unsigned int polyEdge : 1;
- unsigned int polyMode : 1;
- unsigned int freeCompClip : 1;
- unsigned int clientClipType : 2;
- unsigned int componentAlpha : 1;
- unsigned int repeatType : 2;
- unsigned int filter : 3;
- unsigned int stateChanges : CPLastBit;
- unsigned int unused : 18 - CPLastBit;
-
- PicturePtr pNext; /* chain on same drawable */
-
- PicturePtr alphaMap;
- DDXPointRec alphaOrigin;
-
- DDXPointRec clipOrigin;
- pointer clientClip;
-
- unsigned long serialNumber;
-
- RegionPtr pCompositeClip;
-
- PrivateRec *devPrivates;
-
- PictTransform *transform;
-
- SourcePictPtr pSourcePict;
- xFixed *filter_params;
- int filter_nparams;
-} PictureRec;
-
-typedef Bool (*PictFilterValidateParamsProcPtr) (ScreenPtr pScreen, int id,
- xFixed *params, int nparams,
- int *width, int *height);
-typedef struct {
- char *name;
- int id;
- PictFilterValidateParamsProcPtr ValidateParams;
- int width, height;
-} PictFilterRec, *PictFilterPtr;
-
-#define PictFilterNearest 0
-#define PictFilterBilinear 1
-
-#define PictFilterFast 2
-#define PictFilterGood 3
-#define PictFilterBest 4
-
-#define PictFilterConvolution 5
-/* if you add an 8th filter, expand the filter bitfield above */
-
-typedef struct {
- char *alias;
- int alias_id;
- int filter_id;
-} PictFilterAliasRec, *PictFilterAliasPtr;
-
-typedef int (*CreatePictureProcPtr) (PicturePtr pPicture);
-typedef void (*DestroyPictureProcPtr) (PicturePtr pPicture);
-typedef int (*ChangePictureClipProcPtr) (PicturePtr pPicture,
- int clipType,
- pointer value,
- int n);
-typedef void (*DestroyPictureClipProcPtr)(PicturePtr pPicture);
-
-typedef int (*ChangePictureTransformProcPtr) (PicturePtr pPicture,
- PictTransform *transform);
-
-typedef int (*ChangePictureFilterProcPtr) (PicturePtr pPicture,
- int filter,
- xFixed *params,
- int nparams);
-
-typedef void (*DestroyPictureFilterProcPtr) (PicturePtr pPicture);
-
-typedef void (*ChangePictureProcPtr) (PicturePtr pPicture,
- Mask mask);
-typedef void (*ValidatePictureProcPtr) (PicturePtr pPicture,
- Mask mask);
-typedef void (*CompositeProcPtr) (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height);
-
-typedef void (*GlyphsProcPtr) (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlists,
- GlyphListPtr lists,
- GlyphPtr *glyphs);
-
-typedef void (*CompositeRectsProcPtr) (CARD8 op,
- PicturePtr pDst,
- xRenderColor *color,
- int nRect,
- xRectangle *rects);
-
-typedef void (*RasterizeTrapezoidProcPtr)(PicturePtr pMask,
- xTrapezoid *trap,
- int x_off,
- int y_off);
-
-typedef void (*TrapezoidsProcPtr) (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int ntrap,
- xTrapezoid *traps);
-
-typedef void (*TrianglesProcPtr) (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int ntri,
- xTriangle *tris);
-
-typedef Bool (*InitIndexedProcPtr) (ScreenPtr pScreen,
- PictFormatPtr pFormat);
-
-typedef void (*CloseIndexedProcPtr) (ScreenPtr pScreen,
- PictFormatPtr pFormat);
-
-typedef void (*UpdateIndexedProcPtr) (ScreenPtr pScreen,
- PictFormatPtr pFormat,
- int ndef,
- xColorItem *pdef);
-
-typedef void (*AddTrapsProcPtr) (PicturePtr pPicture,
- INT16 xOff,
- INT16 yOff,
- int ntrap,
- xTrap *traps);
-
-typedef void (*AddTrianglesProcPtr) (PicturePtr pPicture,
- INT16 xOff,
- INT16 yOff,
- int ntri,
- xTriangle *tris);
-
-typedef Bool (*RealizeGlyphProcPtr) (ScreenPtr pScreen,
- GlyphPtr glyph);
-
-typedef void (*UnrealizeGlyphProcPtr) (ScreenPtr pScreen,
- GlyphPtr glyph);
-
-typedef struct _PictureScreen {
- PictFormatPtr formats;
- PictFormatPtr fallback;
- int nformats;
-
- CreatePictureProcPtr CreatePicture;
- DestroyPictureProcPtr DestroyPicture;
- ChangePictureClipProcPtr ChangePictureClip;
- DestroyPictureClipProcPtr DestroyPictureClip;
-
- ChangePictureProcPtr ChangePicture;
- ValidatePictureProcPtr ValidatePicture;
-
- CompositeProcPtr Composite;
- GlyphsProcPtr Glyphs; /* unused */
- CompositeRectsProcPtr CompositeRects;
-
- DestroyWindowProcPtr DestroyWindow;
- CloseScreenProcPtr CloseScreen;
-
- StoreColorsProcPtr StoreColors;
-
- InitIndexedProcPtr InitIndexed;
- CloseIndexedProcPtr CloseIndexed;
- UpdateIndexedProcPtr UpdateIndexed;
-
- int subpixel;
-
- PictFilterPtr filters;
- int nfilters;
- PictFilterAliasPtr filterAliases;
- int nfilterAliases;
-
- /**
- * Called immediately after a picture's transform is changed through the
- * SetPictureTransform request. Not called for source-only pictures.
- */
- ChangePictureTransformProcPtr ChangePictureTransform;
-
- /**
- * Called immediately after a picture's transform is changed through the
- * SetPictureFilter request. Not called for source-only pictures.
- */
- ChangePictureFilterProcPtr ChangePictureFilter;
-
- DestroyPictureFilterProcPtr DestroyPictureFilter;
-
- TrapezoidsProcPtr Trapezoids;
- TrianglesProcPtr Triangles;
-
- RasterizeTrapezoidProcPtr RasterizeTrapezoid;
-
- AddTrianglesProcPtr AddTriangles;
-
- AddTrapsProcPtr AddTraps;
-
- RealizeGlyphProcPtr RealizeGlyph;
- UnrealizeGlyphProcPtr UnrealizeGlyph;
-
-} PictureScreenRec, *PictureScreenPtr;
-
-extern _X_EXPORT DevPrivateKeyRec PictureScreenPrivateKeyRec;
-#define PictureScreenPrivateKey (&PictureScreenPrivateKeyRec)
-
-extern _X_EXPORT DevPrivateKeyRec PictureWindowPrivateKeyRec;
-#define PictureWindowPrivateKey (&PictureWindowPrivateKeyRec)
-
-extern _X_EXPORT RESTYPE PictureType;
-extern _X_EXPORT RESTYPE PictFormatType;
-extern _X_EXPORT RESTYPE GlyphSetType;
-
-#define GetPictureScreen(s) ((PictureScreenPtr)dixLookupPrivate(&(s)->devPrivates, PictureScreenPrivateKey))
-#define GetPictureScreenIfSet(s) (dixPrivateKeyRegistered(PictureScreenPrivateKey) ? GetPictureScreen(s) : NULL)
-#define SetPictureScreen(s,p) dixSetPrivate(&(s)->devPrivates, PictureScreenPrivateKey, p)
-#define GetPictureWindow(w) ((PicturePtr)dixLookupPrivate(&(w)->devPrivates, PictureWindowPrivateKey))
-#define SetPictureWindow(w,p) dixSetPrivate(&(w)->devPrivates, PictureWindowPrivateKey, p)
-
-#define VERIFY_PICTURE(pPicture, pid, client, mode) {\
- int rc = dixLookupResourceByType((pointer)&(pPicture), pid,\
- PictureType, client, mode);\
- if (rc != Success)\
- return rc;\
-}
-
-#define VERIFY_ALPHA(pPicture, pid, client, mode) {\
- if (pid == None) \
- pPicture = 0; \
- else { \
- VERIFY_PICTURE(pPicture, pid, client, mode); \
- } \
-} \
-
-extern _X_EXPORT Bool
-PictureDestroyWindow (WindowPtr pWindow);
-
-extern _X_EXPORT Bool
-PictureCloseScreen (int Index, ScreenPtr pScreen);
-
-extern _X_EXPORT void
-PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef);
-
-extern _X_EXPORT Bool
-PictureInitIndexedFormat (ScreenPtr pScreen, PictFormatPtr format);
-
-extern _X_EXPORT Bool
-PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel);
-
-extern _X_EXPORT int
-PictureGetSubpixelOrder (ScreenPtr pScreen);
-
-extern _X_EXPORT PictFormatPtr
-PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
-
-extern _X_EXPORT PictFormatPtr
-PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual);
-
-extern _X_EXPORT PictFormatPtr
-PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format);
-
-extern _X_EXPORT Bool
-PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
-
-extern _X_EXPORT int
-PictureGetFilterId (char *filter, int len, Bool makeit);
-
-extern _X_EXPORT char *
-PictureGetFilterName (int id);
-
-extern _X_EXPORT int
-PictureAddFilter (ScreenPtr pScreen,
- char *filter,
- PictFilterValidateParamsProcPtr ValidateParams,
- int width,
- int height);
-
-extern _X_EXPORT Bool
-PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias);
-
-extern _X_EXPORT Bool
-PictureSetDefaultFilters (ScreenPtr pScreen);
-
-extern _X_EXPORT void
-PictureResetFilters (ScreenPtr pScreen);
-
-extern _X_EXPORT PictFilterPtr
-PictureFindFilter (ScreenPtr pScreen, char *name, int len);
-
-extern _X_EXPORT int
-SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter,
- xFixed *params, int nparams);
-
-extern _X_EXPORT int
-SetPictureFilter (PicturePtr pPicture, char *name, int len,
- xFixed *params, int nparams);
-
-extern _X_EXPORT Bool
-PictureFinishInit (void);
-
-extern _X_EXPORT void
-SetPictureToDefaults (PicturePtr pPicture);
-
-extern _X_EXPORT PicturePtr
-CreatePicture (Picture pid,
- DrawablePtr pDrawable,
- PictFormatPtr pFormat,
- Mask mask,
- XID *list,
- ClientPtr client,
- int *error);
-
-extern _X_EXPORT int
-ChangePicture (PicturePtr pPicture,
- Mask vmask,
- XID *vlist,
- DevUnion *ulist,
- ClientPtr client);
-
-extern _X_EXPORT int
-SetPictureClipRects (PicturePtr pPicture,
- int xOrigin,
- int yOrigin,
- int nRect,
- xRectangle *rects);
-
-extern _X_EXPORT int
-SetPictureClipRegion (PicturePtr pPicture,
- int xOrigin,
- int yOrigin,
- RegionPtr pRegion);
-
-extern _X_EXPORT int
-SetPictureTransform (PicturePtr pPicture,
- PictTransform *transform);
-
-extern _X_EXPORT void
-CopyPicture (PicturePtr pSrc,
- Mask mask,
- PicturePtr pDst);
-
-extern _X_EXPORT void
-ValidatePicture(PicturePtr pPicture);
-
-extern _X_EXPORT int
-FreePicture (pointer pPicture,
- XID pid);
-
-extern _X_EXPORT int
-FreePictFormat (pointer pPictFormat,
- XID pid);
-
-extern _X_EXPORT void
-CompositePicture (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height);
-
-extern _X_EXPORT void
-CompositeGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr lists,
- GlyphPtr *glyphs);
-
-extern _X_EXPORT void
-CompositeRects (CARD8 op,
- PicturePtr pDst,
- xRenderColor *color,
- int nRect,
- xRectangle *rects);
-
-extern _X_EXPORT void
-CompositeTrapezoids (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int ntrap,
- xTrapezoid *traps);
-
-extern _X_EXPORT void
-CompositeTriangles (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int ntriangles,
- xTriangle *triangles);
-
-extern _X_EXPORT void
-CompositeTriStrip (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int npoints,
- xPointFixed *points);
-
-extern _X_EXPORT void
-CompositeTriFan (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int npoints,
- xPointFixed *points);
-
-extern _X_EXPORT void RenderExtensionInit (void);
-
-Bool
-AnimCurInit (ScreenPtr pScreen);
-
-int
-AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor, ClientPtr client, XID cid);
-
-extern _X_EXPORT void
-AddTraps (PicturePtr pPicture,
- INT16 xOff,
- INT16 yOff,
- int ntraps,
- xTrap *traps);
-
-extern _X_EXPORT PicturePtr
-CreateSolidPicture (Picture pid,
- xRenderColor *color,
- int *error);
-
-extern _X_EXPORT PicturePtr
-CreateLinearGradientPicture (Picture pid,
- xPointFixed *p1,
- xPointFixed *p2,
- int nStops,
- xFixed *stops,
- xRenderColor *colors,
- int *error);
-
-extern _X_EXPORT PicturePtr
-CreateRadialGradientPicture (Picture pid,
- xPointFixed *inner,
- xPointFixed *outer,
- xFixed innerRadius,
- xFixed outerRadius,
- int nStops,
- xFixed *stops,
- xRenderColor *colors,
- int *error);
-
-extern _X_EXPORT PicturePtr
-CreateConicalGradientPicture (Picture pid,
- xPointFixed *center,
- xFixed angle,
- int nStops,
- xFixed *stops,
- xRenderColor *colors,
- int *error);
-
-#ifdef PANORAMIX
-extern _X_EXPORT void PanoramiXRenderInit (void);
-extern _X_EXPORT void PanoramiXRenderReset (void);
-#endif
-
-/*
- * matrix.c
- */
-
-extern _X_EXPORT void
-PictTransform_from_xRenderTransform (PictTransformPtr pict,
- xRenderTransform *render);
-
-extern _X_EXPORT void
-xRenderTransform_from_PictTransform (xRenderTransform *render,
- PictTransformPtr pict);
-
-extern _X_EXPORT Bool
-PictureTransformPoint (PictTransformPtr transform,
- PictVectorPtr vector);
-
-extern _X_EXPORT Bool
-PictureTransformPoint3d (PictTransformPtr transform,
- PictVectorPtr vector);
-
-#endif /* _PICTURESTR_H_ */
+/* + * 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. + */ + +#ifndef _PICTURESTR_H_ +#define _PICTURESTR_H_ + +#include "scrnintstr.h" +#include "glyphstr.h" +#include "resource.h" +#include "privates.h" + +typedef struct _DirectFormat { + CARD16 red, redMask; + CARD16 green, greenMask; + CARD16 blue, blueMask; + CARD16 alpha, alphaMask; +} DirectFormatRec; + +typedef struct _IndexFormat { + VisualID vid; + ColormapPtr pColormap; + int nvalues; + xIndexValue *pValues; + void *devPrivate; +} IndexFormatRec; + +typedef struct _PictFormat { + CARD32 id; + CARD32 format; /* except bpp */ + unsigned char type; + unsigned char depth; + DirectFormatRec direct; + IndexFormatRec index; +} PictFormatRec; + +typedef struct pixman_vector PictVector, *PictVectorPtr; +typedef struct pixman_transform PictTransform, *PictTransformPtr; + +#define pict_f_vector pixman_f_vector +#define pict_f_transform pixman_f_transform + +#define PICT_GRADIENT_STOPTABLE_SIZE 1024 +#define SourcePictTypeSolidFill 0 +#define SourcePictTypeLinear 1 +#define SourcePictTypeRadial 2 +#define SourcePictTypeConical 3 + +typedef struct _PictSolidFill { + unsigned int type; + CARD32 color; +} PictSolidFill, *PictSolidFillPtr; + +typedef struct _PictGradientStop { + xFixed x; + xRenderColor color; +} PictGradientStop, *PictGradientStopPtr; + +typedef struct _PictGradient { + unsigned int type; + int nstops; + PictGradientStopPtr stops; +} PictGradient, *PictGradientPtr; + +typedef struct _PictLinearGradient { + unsigned int type; + int nstops; + PictGradientStopPtr stops; + xPointFixed p1; + xPointFixed p2; +} PictLinearGradient, *PictLinearGradientPtr; + +typedef struct _PictCircle { + xFixed x; + xFixed y; + xFixed radius; +} PictCircle, *PictCirclePtr; + +typedef struct _PictRadialGradient { + unsigned int type; + int nstops; + PictGradientStopPtr stops; + PictCircle c1; + PictCircle c2; +} PictRadialGradient, *PictRadialGradientPtr; + +typedef struct _PictConicalGradient { + unsigned int type; + int nstops; + PictGradientStopPtr stops; + xPointFixed center; + xFixed angle; +} PictConicalGradient, *PictConicalGradientPtr; + +typedef union _SourcePict { + unsigned int type; + PictSolidFill solidFill; + PictGradient gradient; + PictLinearGradient linear; + PictRadialGradient radial; + PictConicalGradient conical; +} SourcePict, *SourcePictPtr; + +typedef struct _Picture { + DrawablePtr pDrawable; + PictFormatPtr pFormat; + PictFormatShort format; /* PICT_FORMAT */ + int refcnt; + CARD32 id; + unsigned int repeat : 1; + unsigned int graphicsExposures : 1; + unsigned int subWindowMode : 1; + unsigned int polyEdge : 1; + unsigned int polyMode : 1; + unsigned int freeCompClip : 1; + unsigned int clientClipType : 2; + unsigned int componentAlpha : 1; + unsigned int repeatType : 2; + unsigned int filter : 3; + unsigned int stateChanges : CPLastBit; + unsigned int unused : 18 - CPLastBit; + + PicturePtr pNext; /* chain on same drawable */ + + PicturePtr alphaMap; + DDXPointRec alphaOrigin; + + DDXPointRec clipOrigin; + pointer clientClip; + + unsigned long serialNumber; + + RegionPtr pCompositeClip; + + PrivateRec *devPrivates; + + PictTransform *transform; + + SourcePictPtr pSourcePict; + xFixed *filter_params; + int filter_nparams; +} PictureRec; + +typedef Bool (*PictFilterValidateParamsProcPtr) (ScreenPtr pScreen, int id, + xFixed *params, int nparams, + int *width, int *height); +typedef struct { + char *name; + int id; + PictFilterValidateParamsProcPtr ValidateParams; + int width, height; +} PictFilterRec, *PictFilterPtr; + +#define PictFilterNearest 0 +#define PictFilterBilinear 1 + +#define PictFilterFast 2 +#define PictFilterGood 3 +#define PictFilterBest 4 + +#define PictFilterConvolution 5 +/* if you add an 8th filter, expand the filter bitfield above */ + +typedef struct { + char *alias; + int alias_id; + int filter_id; +} PictFilterAliasRec, *PictFilterAliasPtr; + +typedef int (*CreatePictureProcPtr) (PicturePtr pPicture); +typedef void (*DestroyPictureProcPtr) (PicturePtr pPicture); +typedef int (*ChangePictureClipProcPtr) (PicturePtr pPicture, + int clipType, + pointer value, + int n); +typedef void (*DestroyPictureClipProcPtr)(PicturePtr pPicture); + +typedef int (*ChangePictureTransformProcPtr) (PicturePtr pPicture, + PictTransform *transform); + +typedef int (*ChangePictureFilterProcPtr) (PicturePtr pPicture, + int filter, + xFixed *params, + int nparams); + +typedef void (*DestroyPictureFilterProcPtr) (PicturePtr pPicture); + +typedef void (*ChangePictureProcPtr) (PicturePtr pPicture, + Mask mask); +typedef void (*ValidatePictureProcPtr) (PicturePtr pPicture, + Mask mask); +typedef void (*CompositeProcPtr) (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +typedef void (*GlyphsProcPtr) (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlists, + GlyphListPtr lists, + GlyphPtr *glyphs); + +typedef void (*CompositeRectsProcPtr) (CARD8 op, + PicturePtr pDst, + xRenderColor *color, + int nRect, + xRectangle *rects); + +typedef void (*RasterizeTrapezoidProcPtr)(PicturePtr pMask, + xTrapezoid *trap, + int x_off, + int y_off); + +typedef void (*TrapezoidsProcPtr) (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntrap, + xTrapezoid *traps); + +typedef void (*TrianglesProcPtr) (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntri, + xTriangle *tris); + +typedef Bool (*InitIndexedProcPtr) (ScreenPtr pScreen, + PictFormatPtr pFormat); + +typedef void (*CloseIndexedProcPtr) (ScreenPtr pScreen, + PictFormatPtr pFormat); + +typedef void (*UpdateIndexedProcPtr) (ScreenPtr pScreen, + PictFormatPtr pFormat, + int ndef, + xColorItem *pdef); + +typedef void (*AddTrapsProcPtr) (PicturePtr pPicture, + INT16 xOff, + INT16 yOff, + int ntrap, + xTrap *traps); + +typedef void (*AddTrianglesProcPtr) (PicturePtr pPicture, + INT16 xOff, + INT16 yOff, + int ntri, + xTriangle *tris); + +typedef Bool (*RealizeGlyphProcPtr) (ScreenPtr pScreen, + GlyphPtr glyph); + +typedef void (*UnrealizeGlyphProcPtr) (ScreenPtr pScreen, + GlyphPtr glyph); + +typedef struct _PictureScreen { + PictFormatPtr formats; + PictFormatPtr fallback; + int nformats; + + CreatePictureProcPtr CreatePicture; + DestroyPictureProcPtr DestroyPicture; + ChangePictureClipProcPtr ChangePictureClip; + DestroyPictureClipProcPtr DestroyPictureClip; + + ChangePictureProcPtr ChangePicture; + ValidatePictureProcPtr ValidatePicture; + + CompositeProcPtr Composite; + GlyphsProcPtr Glyphs; /* unused */ + CompositeRectsProcPtr CompositeRects; + + DestroyWindowProcPtr DestroyWindow; + CloseScreenProcPtr CloseScreen; + + StoreColorsProcPtr StoreColors; + + InitIndexedProcPtr InitIndexed; + CloseIndexedProcPtr CloseIndexed; + UpdateIndexedProcPtr UpdateIndexed; + + int subpixel; + + PictFilterPtr filters; + int nfilters; + PictFilterAliasPtr filterAliases; + int nfilterAliases; + + /** + * Called immediately after a picture's transform is changed through the + * SetPictureTransform request. Not called for source-only pictures. + */ + ChangePictureTransformProcPtr ChangePictureTransform; + + /** + * Called immediately after a picture's transform is changed through the + * SetPictureFilter request. Not called for source-only pictures. + */ + ChangePictureFilterProcPtr ChangePictureFilter; + + DestroyPictureFilterProcPtr DestroyPictureFilter; + + TrapezoidsProcPtr Trapezoids; + TrianglesProcPtr Triangles; + + RasterizeTrapezoidProcPtr RasterizeTrapezoid; + + AddTrianglesProcPtr AddTriangles; + + AddTrapsProcPtr AddTraps; + + RealizeGlyphProcPtr RealizeGlyph; + UnrealizeGlyphProcPtr UnrealizeGlyph; + +} PictureScreenRec, *PictureScreenPtr; + +extern _X_EXPORT DevPrivateKeyRec PictureScreenPrivateKeyRec; +#define PictureScreenPrivateKey (&PictureScreenPrivateKeyRec) + +extern _X_EXPORT DevPrivateKeyRec PictureWindowPrivateKeyRec; +#define PictureWindowPrivateKey (&PictureWindowPrivateKeyRec) + +extern _X_EXPORT RESTYPE PictureType; +extern _X_EXPORT RESTYPE PictFormatType; +extern _X_EXPORT RESTYPE GlyphSetType; + +#define GetPictureScreen(s) ((PictureScreenPtr)dixLookupPrivate(&(s)->devPrivates, PictureScreenPrivateKey)) +#define GetPictureScreenIfSet(s) (dixPrivateKeyRegistered(PictureScreenPrivateKey) ? GetPictureScreen(s) : NULL) +#define SetPictureScreen(s,p) dixSetPrivate(&(s)->devPrivates, PictureScreenPrivateKey, p) +#define GetPictureWindow(w) ((PicturePtr)dixLookupPrivate(&(w)->devPrivates, PictureWindowPrivateKey)) +#define SetPictureWindow(w,p) dixSetPrivate(&(w)->devPrivates, PictureWindowPrivateKey, p) + +#define VERIFY_PICTURE(pPicture, pid, client, mode) {\ + int rc = dixLookupResourceByType((pointer)&(pPicture), pid,\ + PictureType, client, mode);\ + if (rc != Success)\ + return rc;\ +} + +#define VERIFY_ALPHA(pPicture, pid, client, mode) {\ + if (pid == None) \ + pPicture = 0; \ + else { \ + VERIFY_PICTURE(pPicture, pid, client, mode); \ + } \ +} \ + +extern _X_EXPORT Bool +PictureDestroyWindow (WindowPtr pWindow); + +extern _X_EXPORT Bool +PictureCloseScreen (int Index, ScreenPtr pScreen); + +extern _X_EXPORT void +PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef); + +extern _X_EXPORT Bool +PictureInitIndexedFormat (ScreenPtr pScreen, PictFormatPtr format); + +extern _X_EXPORT Bool +PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel); + +extern _X_EXPORT int +PictureGetSubpixelOrder (ScreenPtr pScreen); + +extern _X_EXPORT PictFormatPtr +PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp); + +extern _X_EXPORT PictFormatPtr +PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual); + +extern _X_EXPORT PictFormatPtr +PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format); + +extern _X_EXPORT Bool +PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats); + +extern _X_EXPORT int +PictureGetFilterId (char *filter, int len, Bool makeit); + +extern _X_EXPORT char * +PictureGetFilterName (int id); + +extern _X_EXPORT int +PictureAddFilter (ScreenPtr pScreen, + char *filter, + PictFilterValidateParamsProcPtr ValidateParams, + int width, + int height); + +extern _X_EXPORT Bool +PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias); + +extern _X_EXPORT Bool +PictureSetDefaultFilters (ScreenPtr pScreen); + +extern _X_EXPORT void +PictureResetFilters (ScreenPtr pScreen); + +extern _X_EXPORT PictFilterPtr +PictureFindFilter (ScreenPtr pScreen, char *name, int len); + +extern _X_EXPORT int +SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter, + xFixed *params, int nparams); + +extern _X_EXPORT int +SetPictureFilter (PicturePtr pPicture, char *name, int len, + xFixed *params, int nparams); + +extern _X_EXPORT Bool +PictureFinishInit (void); + +extern _X_EXPORT void +SetPictureToDefaults (PicturePtr pPicture); + +extern _X_EXPORT PicturePtr +CreatePicture (Picture pid, + DrawablePtr pDrawable, + PictFormatPtr pFormat, + Mask mask, + XID *list, + ClientPtr client, + int *error); + +extern _X_EXPORT int +ChangePicture (PicturePtr pPicture, + Mask vmask, + XID *vlist, + DevUnion *ulist, + ClientPtr client); + +extern _X_EXPORT int +SetPictureClipRects (PicturePtr pPicture, + int xOrigin, + int yOrigin, + int nRect, + xRectangle *rects); + +extern _X_EXPORT int +SetPictureClipRegion (PicturePtr pPicture, + int xOrigin, + int yOrigin, + RegionPtr pRegion); + +extern _X_EXPORT int +SetPictureTransform (PicturePtr pPicture, + PictTransform *transform); + +extern _X_EXPORT void +CopyPicture (PicturePtr pSrc, + Mask mask, + PicturePtr pDst); + +extern _X_EXPORT void +ValidatePicture(PicturePtr pPicture); + +extern _X_EXPORT int +FreePicture (pointer pPicture, + XID pid); + +extern _X_EXPORT int +FreePictFormat (pointer pPictFormat, + XID pid); + +extern _X_EXPORT void +CompositePicture (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +extern _X_EXPORT void +CompositeGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr lists, + GlyphPtr *glyphs); + +extern _X_EXPORT void +CompositeRects (CARD8 op, + PicturePtr pDst, + xRenderColor *color, + int nRect, + xRectangle *rects); + +extern _X_EXPORT void +CompositeTrapezoids (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntrap, + xTrapezoid *traps); + +extern _X_EXPORT void +CompositeTriangles (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntriangles, + xTriangle *triangles); + +extern _X_EXPORT void +CompositeTriStrip (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoints, + xPointFixed *points); + +extern _X_EXPORT void +CompositeTriFan (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoints, + xPointFixed *points); + +extern _X_EXPORT void RenderExtensionInit (void); + +Bool +AnimCurInit (ScreenPtr pScreen); + +int +AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor, ClientPtr client, XID cid); + +extern _X_EXPORT void +AddTraps (PicturePtr pPicture, + INT16 xOff, + INT16 yOff, + int ntraps, + xTrap *traps); + +extern _X_EXPORT PicturePtr +CreateSolidPicture (Picture pid, + xRenderColor *color, + int *error); + +extern _X_EXPORT PicturePtr +CreateLinearGradientPicture (Picture pid, + xPointFixed *p1, + xPointFixed *p2, + int nStops, + xFixed *stops, + xRenderColor *colors, + int *error); + +extern _X_EXPORT PicturePtr +CreateRadialGradientPicture (Picture pid, + xPointFixed *inner, + xPointFixed *outer, + xFixed innerRadius, + xFixed outerRadius, + int nStops, + xFixed *stops, + xRenderColor *colors, + int *error); + +extern _X_EXPORT PicturePtr +CreateConicalGradientPicture (Picture pid, + xPointFixed *center, + xFixed angle, + int nStops, + xFixed *stops, + xRenderColor *colors, + int *error); + +#ifdef PANORAMIX +extern _X_EXPORT void PanoramiXRenderInit (void); +extern _X_EXPORT void PanoramiXRenderReset (void); +#endif + +/* + * matrix.c + */ + +extern _X_EXPORT void +PictTransform_from_xRenderTransform (PictTransformPtr pict, + xRenderTransform *render); + +extern _X_EXPORT void +xRenderTransform_from_PictTransform (xRenderTransform *render, + PictTransformPtr pict); + +extern _X_EXPORT Bool +PictureTransformPoint (PictTransformPtr transform, + PictVectorPtr vector); + +extern _X_EXPORT Bool +PictureTransformPoint3d (PictTransformPtr transform, + PictVectorPtr vector); + +#endif /* _PICTURESTR_H_ */ diff --git a/xorg-server/render/render.c b/xorg-server/render/render.c index 33fcc1562..ebb1d630a 100644 --- a/xorg-server/render/render.c +++ b/xorg-server/render/render.c @@ -1,3384 +1,3384 @@ -/*
- *
- * 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.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "os.h"
-#include "dixstruct.h"
-#include "resource.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "colormapst.h"
-#include "extnsionst.h"
-#include "servermd.h"
-#include <X11/extensions/render.h>
-#include <X11/extensions/renderproto.h>
-#include "picturestr.h"
-#include "glyphstr.h"
-#include <X11/Xfuncproto.h>
-#include "cursorstr.h"
-#include "xace.h"
-#include "protocol-versions.h"
-
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#endif
-
-#if HAVE_STDINT_H
-#include <stdint.h>
-#elif !defined(UINT32_MAX)
-#define UINT32_MAX 0xffffffffU
-#endif
-
-static int ProcRenderQueryVersion (ClientPtr pClient);
-static int ProcRenderQueryPictFormats (ClientPtr pClient);
-static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
-static int ProcRenderQueryDithers (ClientPtr pClient);
-static int ProcRenderCreatePicture (ClientPtr pClient);
-static int ProcRenderChangePicture (ClientPtr pClient);
-static int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
-static int ProcRenderFreePicture (ClientPtr pClient);
-static int ProcRenderComposite (ClientPtr pClient);
-static int ProcRenderScale (ClientPtr pClient);
-static int ProcRenderTrapezoids (ClientPtr pClient);
-static int ProcRenderTriangles (ClientPtr pClient);
-static int ProcRenderTriStrip (ClientPtr pClient);
-static int ProcRenderTriFan (ClientPtr pClient);
-static int ProcRenderColorTrapezoids (ClientPtr pClient);
-static int ProcRenderColorTriangles (ClientPtr pClient);
-static int ProcRenderTransform (ClientPtr pClient);
-static int ProcRenderCreateGlyphSet (ClientPtr pClient);
-static int ProcRenderReferenceGlyphSet (ClientPtr pClient);
-static int ProcRenderFreeGlyphSet (ClientPtr pClient);
-static int ProcRenderAddGlyphs (ClientPtr pClient);
-static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
-static int ProcRenderFreeGlyphs (ClientPtr pClient);
-static int ProcRenderCompositeGlyphs (ClientPtr pClient);
-static int ProcRenderFillRectangles (ClientPtr pClient);
-static int ProcRenderCreateCursor (ClientPtr pClient);
-static int ProcRenderSetPictureTransform (ClientPtr pClient);
-static int ProcRenderQueryFilters (ClientPtr pClient);
-static int ProcRenderSetPictureFilter (ClientPtr pClient);
-static int ProcRenderCreateAnimCursor (ClientPtr pClient);
-static int ProcRenderAddTraps (ClientPtr pClient);
-static int ProcRenderCreateSolidFill (ClientPtr pClient);
-static int ProcRenderCreateLinearGradient (ClientPtr pClient);
-static int ProcRenderCreateRadialGradient (ClientPtr pClient);
-static int ProcRenderCreateConicalGradient (ClientPtr pClient);
-
-static int ProcRenderDispatch (ClientPtr pClient);
-
-static int SProcRenderQueryVersion (ClientPtr pClient);
-static int SProcRenderQueryPictFormats (ClientPtr pClient);
-static int SProcRenderQueryPictIndexValues (ClientPtr pClient);
-static int SProcRenderQueryDithers (ClientPtr pClient);
-static int SProcRenderCreatePicture (ClientPtr pClient);
-static int SProcRenderChangePicture (ClientPtr pClient);
-static int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
-static int SProcRenderFreePicture (ClientPtr pClient);
-static int SProcRenderComposite (ClientPtr pClient);
-static int SProcRenderScale (ClientPtr pClient);
-static int SProcRenderTrapezoids (ClientPtr pClient);
-static int SProcRenderTriangles (ClientPtr pClient);
-static int SProcRenderTriStrip (ClientPtr pClient);
-static int SProcRenderTriFan (ClientPtr pClient);
-static int SProcRenderColorTrapezoids (ClientPtr pClient);
-static int SProcRenderColorTriangles (ClientPtr pClient);
-static int SProcRenderTransform (ClientPtr pClient);
-static int SProcRenderCreateGlyphSet (ClientPtr pClient);
-static int SProcRenderReferenceGlyphSet (ClientPtr pClient);
-static int SProcRenderFreeGlyphSet (ClientPtr pClient);
-static int SProcRenderAddGlyphs (ClientPtr pClient);
-static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
-static int SProcRenderFreeGlyphs (ClientPtr pClient);
-static int SProcRenderCompositeGlyphs (ClientPtr pClient);
-static int SProcRenderFillRectangles (ClientPtr pClient);
-static int SProcRenderCreateCursor (ClientPtr pClient);
-static int SProcRenderSetPictureTransform (ClientPtr pClient);
-static int SProcRenderQueryFilters (ClientPtr pClient);
-static int SProcRenderSetPictureFilter (ClientPtr pClient);
-static int SProcRenderCreateAnimCursor (ClientPtr pClient);
-static int SProcRenderAddTraps (ClientPtr pClient);
-static int SProcRenderCreateSolidFill (ClientPtr pClient);
-static int SProcRenderCreateLinearGradient (ClientPtr pClient);
-static int SProcRenderCreateRadialGradient (ClientPtr pClient);
-static int SProcRenderCreateConicalGradient (ClientPtr pClient);
-
-static int SProcRenderDispatch (ClientPtr pClient);
-
-int (*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
- ProcRenderQueryVersion,
- ProcRenderQueryPictFormats,
- ProcRenderQueryPictIndexValues,
- ProcRenderQueryDithers,
- ProcRenderCreatePicture,
- ProcRenderChangePicture,
- ProcRenderSetPictureClipRectangles,
- ProcRenderFreePicture,
- ProcRenderComposite,
- ProcRenderScale,
- ProcRenderTrapezoids,
- ProcRenderTriangles,
- ProcRenderTriStrip,
- ProcRenderTriFan,
- ProcRenderColorTrapezoids,
- ProcRenderColorTriangles,
- ProcRenderTransform,
- ProcRenderCreateGlyphSet,
- ProcRenderReferenceGlyphSet,
- ProcRenderFreeGlyphSet,
- ProcRenderAddGlyphs,
- ProcRenderAddGlyphsFromPicture,
- ProcRenderFreeGlyphs,
- ProcRenderCompositeGlyphs,
- ProcRenderCompositeGlyphs,
- ProcRenderCompositeGlyphs,
- ProcRenderFillRectangles,
- ProcRenderCreateCursor,
- ProcRenderSetPictureTransform,
- ProcRenderQueryFilters,
- ProcRenderSetPictureFilter,
- ProcRenderCreateAnimCursor,
- ProcRenderAddTraps,
- ProcRenderCreateSolidFill,
- ProcRenderCreateLinearGradient,
- ProcRenderCreateRadialGradient,
- ProcRenderCreateConicalGradient
-};
-
-int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
- SProcRenderQueryVersion,
- SProcRenderQueryPictFormats,
- SProcRenderQueryPictIndexValues,
- SProcRenderQueryDithers,
- SProcRenderCreatePicture,
- SProcRenderChangePicture,
- SProcRenderSetPictureClipRectangles,
- SProcRenderFreePicture,
- SProcRenderComposite,
- SProcRenderScale,
- SProcRenderTrapezoids,
- SProcRenderTriangles,
- SProcRenderTriStrip,
- SProcRenderTriFan,
- SProcRenderColorTrapezoids,
- SProcRenderColorTriangles,
- SProcRenderTransform,
- SProcRenderCreateGlyphSet,
- SProcRenderReferenceGlyphSet,
- SProcRenderFreeGlyphSet,
- SProcRenderAddGlyphs,
- SProcRenderAddGlyphsFromPicture,
- SProcRenderFreeGlyphs,
- SProcRenderCompositeGlyphs,
- SProcRenderCompositeGlyphs,
- SProcRenderCompositeGlyphs,
- SProcRenderFillRectangles,
- SProcRenderCreateCursor,
- SProcRenderSetPictureTransform,
- SProcRenderQueryFilters,
- SProcRenderSetPictureFilter,
- SProcRenderCreateAnimCursor,
- SProcRenderAddTraps,
- SProcRenderCreateSolidFill,
- SProcRenderCreateLinearGradient,
- SProcRenderCreateRadialGradient,
- SProcRenderCreateConicalGradient
-};
-
-int RenderErrBase;
-static DevPrivateKeyRec RenderClientPrivateKeyRec;
-#define RenderClientPrivateKey (&RenderClientPrivateKeyRec )
-
-typedef struct _RenderClient {
- int major_version;
- int minor_version;
-} RenderClientRec, *RenderClientPtr;
-
-#define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey))
-
-static void
-RenderClientCallback (CallbackListPtr *list,
- pointer closure,
- pointer data)
-{
- NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
- ClientPtr pClient = clientinfo->client;
- RenderClientPtr pRenderClient = GetRenderClient (pClient);
-
- pRenderClient->major_version = 0;
- pRenderClient->minor_version = 0;
-}
-
-#ifdef PANORAMIX
-RESTYPE XRT_PICTURE;
-#endif
-
-void
-RenderExtensionInit (void)
-{
- ExtensionEntry *extEntry;
-
- if (!PictureType)
- return;
- if (!PictureFinishInit ())
- return;
- if (!dixRegisterPrivateKey(&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec)))
- return;
- if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
- return;
-
- extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
- ProcRenderDispatch, SProcRenderDispatch,
- NULL, StandardMinorOpcode);
- if (!extEntry)
- return;
- RenderErrBase = extEntry->errorBase;
-#ifdef PANORAMIX
- if (XRT_PICTURE)
- SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
-#endif
- SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture);
- SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat);
- SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet);
-}
-
-static int
-ProcRenderQueryVersion (ClientPtr client)
-{
- RenderClientPtr pRenderClient = GetRenderClient (client);
- xRenderQueryVersionReply rep;
- register int n;
- REQUEST(xRenderQueryVersionReq);
-
- pRenderClient->major_version = stuff->majorVersion;
- pRenderClient->minor_version = stuff->minorVersion;
-
- REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
- memset(&rep, 0, sizeof(xRenderQueryVersionReply));
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if ((stuff->majorVersion * 1000 + stuff->minorVersion) <
- (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION))
- {
- rep.majorVersion = stuff->majorVersion;
- rep.minorVersion = stuff->minorVersion;
- } else
- {
- rep.majorVersion = SERVER_RENDER_MAJOR_VERSION;
- rep.minorVersion = SERVER_RENDER_MINOR_VERSION;
- }
-
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.majorVersion, n);
- swapl(&rep.minorVersion, n);
- }
- WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
- return Success;
-}
-
-static VisualPtr
-findVisual (ScreenPtr pScreen, VisualID vid)
-{
- VisualPtr pVisual;
- int v;
-
- for (v = 0; v < pScreen->numVisuals; v++)
- {
- pVisual = pScreen->visuals + v;
- if (pVisual->vid == vid)
- return pVisual;
- }
- return 0;
-}
-
-static int
-ProcRenderQueryPictFormats (ClientPtr client)
-{
- RenderClientPtr pRenderClient = GetRenderClient (client);
- xRenderQueryPictFormatsReply *reply;
- xPictScreen *pictScreen;
- xPictDepth *pictDepth;
- xPictVisual *pictVisual;
- xPictFormInfo *pictForm;
- CARD32 *pictSubpixel;
- ScreenPtr pScreen;
- VisualPtr pVisual;
- DepthPtr pDepth;
- int v, d;
- PictureScreenPtr ps;
- PictFormatPtr pFormat;
- int nformat;
- int ndepth;
- int nvisual;
- int rlength;
- int s;
- int n;
- int numScreens;
- int numSubpixel;
-/* REQUEST(xRenderQueryPictFormatsReq); */
-
- REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
-
-#ifdef PANORAMIX
- if (noPanoramiXExtension)
- numScreens = screenInfo.numScreens;
- else
- numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
-#else
- numScreens = screenInfo.numScreens;
-#endif
- ndepth = nformat = nvisual = 0;
- for (s = 0; s < numScreens; s++)
- {
- pScreen = screenInfo.screens[s];
- for (d = 0; d < pScreen->numDepths; d++)
- {
- pDepth = pScreen->allowedDepths + d;
- ++ndepth;
-
- for (v = 0; v < pDepth->numVids; v++)
- {
- pVisual = findVisual (pScreen, pDepth->vids[v]);
- if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
- ++nvisual;
- }
- }
- ps = GetPictureScreenIfSet(pScreen);
- if (ps)
- nformat += ps->nformats;
- }
- if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
- numSubpixel = 0;
- else
- numSubpixel = numScreens;
-
- rlength = (sizeof (xRenderQueryPictFormatsReply) +
- nformat * sizeof (xPictFormInfo) +
- numScreens * sizeof (xPictScreen) +
- ndepth * sizeof (xPictDepth) +
- nvisual * sizeof (xPictVisual) +
- numSubpixel * sizeof (CARD32));
- reply = (xRenderQueryPictFormatsReply *) calloc(1, rlength);
- if (!reply)
- return BadAlloc;
- reply->type = X_Reply;
- reply->sequenceNumber = client->sequence;
- reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
- reply->numFormats = nformat;
- reply->numScreens = numScreens;
- reply->numDepths = ndepth;
- reply->numVisuals = nvisual;
- reply->numSubpixel = numSubpixel;
-
- pictForm = (xPictFormInfo *) (reply + 1);
-
- for (s = 0; s < numScreens; s++)
- {
- pScreen = screenInfo.screens[s];
- ps = GetPictureScreenIfSet(pScreen);
- if (ps)
- {
- for (nformat = 0, pFormat = ps->formats;
- nformat < ps->nformats;
- nformat++, pFormat++)
- {
- pictForm->id = pFormat->id;
- pictForm->type = pFormat->type;
- pictForm->depth = pFormat->depth;
- pictForm->direct.red = pFormat->direct.red;
- pictForm->direct.redMask = pFormat->direct.redMask;
- pictForm->direct.green = pFormat->direct.green;
- pictForm->direct.greenMask = pFormat->direct.greenMask;
- pictForm->direct.blue = pFormat->direct.blue;
- pictForm->direct.blueMask = pFormat->direct.blueMask;
- pictForm->direct.alpha = pFormat->direct.alpha;
- pictForm->direct.alphaMask = pFormat->direct.alphaMask;
- if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
- pictForm->colormap = pFormat->index.pColormap->mid;
- else
- pictForm->colormap = None;
- if (client->swapped)
- {
- swapl (&pictForm->id, n);
- swaps (&pictForm->direct.red, n);
- swaps (&pictForm->direct.redMask, n);
- swaps (&pictForm->direct.green, n);
- swaps (&pictForm->direct.greenMask, n);
- swaps (&pictForm->direct.blue, n);
- swaps (&pictForm->direct.blueMask, n);
- swaps (&pictForm->direct.alpha, n);
- swaps (&pictForm->direct.alphaMask, n);
- swapl (&pictForm->colormap, n);
- }
- pictForm++;
- }
- }
- }
-
- pictScreen = (xPictScreen *) pictForm;
- for (s = 0; s < numScreens; s++)
- {
- pScreen = screenInfo.screens[s];
- pictDepth = (xPictDepth *) (pictScreen + 1);
- ndepth = 0;
- for (d = 0; d < pScreen->numDepths; d++)
- {
- pictVisual = (xPictVisual *) (pictDepth + 1);
- pDepth = pScreen->allowedDepths + d;
-
- nvisual = 0;
- for (v = 0; v < pDepth->numVids; v++)
- {
- pVisual = findVisual (pScreen, pDepth->vids[v]);
- if (pVisual && (pFormat = PictureMatchVisual (pScreen,
- pDepth->depth,
- pVisual)))
- {
- pictVisual->visual = pVisual->vid;
- pictVisual->format = pFormat->id;
- if (client->swapped)
- {
- swapl (&pictVisual->visual, n);
- swapl (&pictVisual->format, n);
- }
- pictVisual++;
- nvisual++;
- }
- }
- pictDepth->depth = pDepth->depth;
- pictDepth->nPictVisuals = nvisual;
- if (client->swapped)
- {
- swaps (&pictDepth->nPictVisuals, n);
- }
- ndepth++;
- pictDepth = (xPictDepth *) pictVisual;
- }
- pictScreen->nDepth = ndepth;
- ps = GetPictureScreenIfSet(pScreen);
- if (ps)
- pictScreen->fallback = ps->fallback->id;
- else
- pictScreen->fallback = 0;
- if (client->swapped)
- {
- swapl (&pictScreen->nDepth, n);
- swapl (&pictScreen->fallback, n);
- }
- pictScreen = (xPictScreen *) pictDepth;
- }
- pictSubpixel = (CARD32 *) pictScreen;
-
- for (s = 0; s < numSubpixel; s++)
- {
- pScreen = screenInfo.screens[s];
- ps = GetPictureScreenIfSet(pScreen);
- if (ps)
- *pictSubpixel = ps->subpixel;
- else
- *pictSubpixel = SubPixelUnknown;
- if (client->swapped)
- {
- swapl (pictSubpixel, n);
- }
- ++pictSubpixel;
- }
-
- if (client->swapped)
- {
- swaps (&reply->sequenceNumber, n);
- swapl (&reply->length, n);
- swapl (&reply->numFormats, n);
- swapl (&reply->numScreens, n);
- swapl (&reply->numDepths, n);
- swapl (&reply->numVisuals, n);
- swapl (&reply->numSubpixel, n);
- }
- WriteToClient(client, rlength, (char *) reply);
- free(reply);
- return Success;
-}
-
-static int
-ProcRenderQueryPictIndexValues (ClientPtr client)
-{
- PictFormatPtr pFormat;
- int rc, num;
- int rlength;
- int i, n;
- REQUEST(xRenderQueryPictIndexValuesReq);
- xRenderQueryPictIndexValuesReply *reply;
- xIndexValue *values;
-
- REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
-
- rc = dixLookupResourceByType((pointer *)&pFormat, stuff->format,
- PictFormatType, client, DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (pFormat->type != PictTypeIndexed)
- {
- client->errorValue = stuff->format;
- return BadMatch;
- }
- num = pFormat->index.nvalues;
- rlength = (sizeof (xRenderQueryPictIndexValuesReply) +
- num * sizeof(xIndexValue));
- reply = (xRenderQueryPictIndexValuesReply *) malloc(rlength);
- if (!reply)
- return BadAlloc;
-
- reply->type = X_Reply;
- reply->sequenceNumber = client->sequence;
- reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
- reply->numIndexValues = num;
-
- values = (xIndexValue *) (reply + 1);
-
- memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
-
- if (client->swapped)
- {
- for (i = 0; i < num; i++)
- {
- swapl (&values[i].pixel, n);
- swaps (&values[i].red, n);
- swaps (&values[i].green, n);
- swaps (&values[i].blue, n);
- swaps (&values[i].alpha, n);
- }
- swaps (&reply->sequenceNumber, n);
- swapl (&reply->length, n);
- swapl (&reply->numIndexValues, n);
- }
-
- WriteToClient(client, rlength, (char *) reply);
- free(reply);
- return Success;
-}
-
-static int
-ProcRenderQueryDithers (ClientPtr client)
-{
- return BadImplementation;
-}
-
-static int
-ProcRenderCreatePicture (ClientPtr client)
-{
- PicturePtr pPicture;
- DrawablePtr pDrawable;
- PictFormatPtr pFormat;
- int len, error, rc;
- REQUEST(xRenderCreatePictureReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
-
- LEGAL_NEW_RESOURCE(stuff->pid, client);
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess|DixAddAccess);
- if (rc != Success)
- return rc;
-
- rc = dixLookupResourceByType((pointer *)&pFormat, stuff->format,
- PictFormatType, client, DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (pFormat->depth != pDrawable->depth)
- return BadMatch;
- len = client->req_len - bytes_to_int32(sizeof(xRenderCreatePictureReq));
- if (Ones(stuff->mask) != len)
- return BadLength;
-
- pPicture = CreatePicture (stuff->pid,
- pDrawable,
- pFormat,
- stuff->mask,
- (XID *) (stuff + 1),
- client,
- &error);
- if (!pPicture)
- return error;
- if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
- return BadAlloc;
- return Success;
-}
-
-static int
-ProcRenderChangePicture (ClientPtr client)
-{
- PicturePtr pPicture;
- REQUEST(xRenderChangePictureReq);
- int len;
-
- REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
- VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess);
-
- len = client->req_len - bytes_to_int32(sizeof(xRenderChangePictureReq));
- if (Ones(stuff->mask) != len)
- return BadLength;
-
- return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
- (DevUnion *) 0, client);
-}
-
-static int
-ProcRenderSetPictureClipRectangles (ClientPtr client)
-{
- REQUEST(xRenderSetPictureClipRectanglesReq);
- PicturePtr pPicture;
- int nr;
-
- REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
- VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess);
- if (!pPicture->pDrawable)
- return BadDrawable;
-
- nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
- if (nr & 4)
- return BadLength;
- nr >>= 3;
- return SetPictureClipRects (pPicture,
- stuff->xOrigin, stuff->yOrigin,
- nr, (xRectangle *) &stuff[1]);
-}
-
-static int
-ProcRenderFreePicture (ClientPtr client)
-{
- PicturePtr pPicture;
- REQUEST(xRenderFreePictureReq);
-
- REQUEST_SIZE_MATCH(xRenderFreePictureReq);
-
- VERIFY_PICTURE (pPicture, stuff->picture, client, DixDestroyAccess);
- FreeResource (stuff->picture, RT_NONE);
- return Success;
-}
-
-static Bool
-PictOpValid (CARD8 op)
-{
- if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
- return TRUE;
- if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
- return TRUE;
- if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
- return TRUE;
- if (PictOpBlendMinimum <= op && op <= PictOpBlendMaximum)
- return TRUE;
- return FALSE;
-}
-
-static int
-ProcRenderComposite (ClientPtr client)
-{
- PicturePtr pSrc, pMask, pDst;
- REQUEST(xRenderCompositeReq);
-
- REQUEST_SIZE_MATCH(xRenderCompositeReq);
- if (!PictOpValid (stuff->op))
- {
- client->errorValue = stuff->op;
- return BadValue;
- }
- VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
- if (!pDst->pDrawable)
- return BadDrawable;
- VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
- VERIFY_ALPHA (pMask, stuff->mask, client, DixReadAccess);
- if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
- (pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen))
- return BadMatch;
- CompositePicture (stuff->op,
- pSrc,
- pMask,
- pDst,
- stuff->xSrc,
- stuff->ySrc,
- stuff->xMask,
- stuff->yMask,
- stuff->xDst,
- stuff->yDst,
- stuff->width,
- stuff->height);
- return Success;
-}
-
-static int
-ProcRenderScale (ClientPtr client)
-{
- return BadImplementation;
-}
-
-static int
-ProcRenderTrapezoids (ClientPtr client)
-{
- int rc, ntraps;
- PicturePtr pSrc, pDst;
- PictFormatPtr pFormat;
- REQUEST(xRenderTrapezoidsReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
- if (!PictOpValid (stuff->op))
- {
- client->errorValue = stuff->op;
- return BadValue;
- }
- VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
- VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
- if (!pDst->pDrawable)
- return BadDrawable;
- if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
- return BadMatch;
- if (stuff->maskFormat)
- {
- rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
- PictFormatType, client, DixReadAccess);
- if (rc != Success)
- return rc;
- }
- else
- pFormat = 0;
- ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
- if (ntraps % sizeof (xTrapezoid))
- return BadLength;
- ntraps /= sizeof (xTrapezoid);
- if (ntraps)
- CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
- stuff->xSrc, stuff->ySrc,
- ntraps, (xTrapezoid *) &stuff[1]);
- return Success;
-}
-
-static int
-ProcRenderTriangles (ClientPtr client)
-{
- int rc, ntris;
- PicturePtr pSrc, pDst;
- PictFormatPtr pFormat;
- REQUEST(xRenderTrianglesReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
- if (!PictOpValid (stuff->op))
- {
- client->errorValue = stuff->op;
- return BadValue;
- }
- VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
- VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
- if (!pDst->pDrawable)
- return BadDrawable;
- if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
- return BadMatch;
- if (stuff->maskFormat)
- {
- rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
- PictFormatType, client, DixReadAccess);
- if (rc != Success)
- return rc;
- }
- else
- pFormat = 0;
- ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
- if (ntris % sizeof (xTriangle))
- return BadLength;
- ntris /= sizeof (xTriangle);
- if (ntris)
- CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
- stuff->xSrc, stuff->ySrc,
- ntris, (xTriangle *) &stuff[1]);
- return Success;
-}
-
-static int
-ProcRenderTriStrip (ClientPtr client)
-{
- int rc, npoints;
- PicturePtr pSrc, pDst;
- PictFormatPtr pFormat;
- REQUEST(xRenderTrianglesReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
- if (!PictOpValid (stuff->op))
- {
- client->errorValue = stuff->op;
- return BadValue;
- }
- VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
- VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
- if (!pDst->pDrawable)
- return BadDrawable;
- if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
- return BadMatch;
- if (stuff->maskFormat)
- {
- rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
- PictFormatType, client, DixReadAccess);
- if (rc != Success)
- return rc;
- }
- else
- pFormat = 0;
- npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
- if (npoints & 4)
- return BadLength;
- npoints >>= 3;
- if (npoints >= 3)
- CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
- stuff->xSrc, stuff->ySrc,
- npoints, (xPointFixed *) &stuff[1]);
- return Success;
-}
-
-static int
-ProcRenderTriFan (ClientPtr client)
-{
- int rc, npoints;
- PicturePtr pSrc, pDst;
- PictFormatPtr pFormat;
- REQUEST(xRenderTrianglesReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
- if (!PictOpValid (stuff->op))
- {
- client->errorValue = stuff->op;
- return BadValue;
- }
- VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
- VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
- if (!pDst->pDrawable)
- return BadDrawable;
- if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
- return BadMatch;
- if (stuff->maskFormat)
- {
- rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
- PictFormatType, client, DixReadAccess);
- if (rc != Success)
- return rc;
- }
- else
- pFormat = 0;
- npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
- if (npoints & 4)
- return BadLength;
- npoints >>= 3;
- if (npoints >= 3)
- CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
- stuff->xSrc, stuff->ySrc,
- npoints, (xPointFixed *) &stuff[1]);
- return Success;
-}
-
-static int
-ProcRenderColorTrapezoids (ClientPtr client)
-{
- return BadImplementation;
-}
-
-static int
-ProcRenderColorTriangles (ClientPtr client)
-{
- return BadImplementation;
-}
-
-static int
-ProcRenderTransform (ClientPtr client)
-{
- return BadImplementation;
-}
-
-static int
-ProcRenderCreateGlyphSet (ClientPtr client)
-{
- GlyphSetPtr glyphSet;
- PictFormatPtr format;
- int rc, f;
- REQUEST(xRenderCreateGlyphSetReq);
-
- REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
-
- LEGAL_NEW_RESOURCE(stuff->gsid, client);
- rc = dixLookupResourceByType((pointer *)&format, stuff->format,
- PictFormatType, client, DixReadAccess);
- if (rc != Success)
- return rc;
-
- switch (format->depth) {
- case 1:
- f = GlyphFormat1;
- break;
- case 4:
- f = GlyphFormat4;
- break;
- case 8:
- f = GlyphFormat8;
- break;
- case 16:
- f = GlyphFormat16;
- break;
- case 32:
- f = GlyphFormat32;
- break;
- default:
- return BadMatch;
- }
- if (format->type != PictTypeDirect)
- return BadMatch;
- glyphSet = AllocateGlyphSet (f, format);
- if (!glyphSet)
- return BadAlloc;
- /* security creation/labeling check */
- rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType,
- glyphSet, RT_NONE, NULL, DixCreateAccess);
- if (rc != Success)
- return rc;
- if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
- return BadAlloc;
- return Success;
-}
-
-static int
-ProcRenderReferenceGlyphSet (ClientPtr client)
-{
- GlyphSetPtr glyphSet;
- int rc;
- REQUEST(xRenderReferenceGlyphSetReq);
-
- REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
-
- LEGAL_NEW_RESOURCE(stuff->gsid, client);
-
- rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->existing, GlyphSetType,
- client, DixGetAttrAccess);
- if (rc != Success)
- {
- client->errorValue = stuff->existing;
- return rc;
- }
- glyphSet->refcnt++;
- if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
- return BadAlloc;
- return Success;
-}
-
-#define NLOCALDELTA 64
-#define NLOCALGLYPH 256
-
-static int
-ProcRenderFreeGlyphSet (ClientPtr client)
-{
- GlyphSetPtr glyphSet;
- int rc;
- REQUEST(xRenderFreeGlyphSetReq);
-
- REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
- rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType,
- client, DixDestroyAccess);
- if (rc != Success)
- {
- client->errorValue = stuff->glyphset;
- return rc;
- }
- FreeResource (stuff->glyphset, RT_NONE);
- return Success;
-}
-
-typedef struct _GlyphNew {
- Glyph id;
- GlyphPtr glyph;
- Bool found;
- unsigned char sha1[20];
-} GlyphNewRec, *GlyphNewPtr;
-
-#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
-
-static int
-ProcRenderAddGlyphs (ClientPtr client)
-{
- GlyphSetPtr glyphSet;
- REQUEST(xRenderAddGlyphsReq);
- GlyphNewRec glyphsLocal[NLOCALGLYPH];
- GlyphNewPtr glyphsBase, glyphs, glyph_new;
- int remain, nglyphs;
- CARD32 *gids;
- xGlyphInfo *gi;
- CARD8 *bits;
- unsigned int size;
- int err;
- int i, screen;
- PicturePtr pSrc = NULL, pDst = NULL;
- PixmapPtr pSrcPix = NULL, pDstPix = NULL;
- CARD32 component_alpha;
-
- REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
- err = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType,
- client, DixAddAccess);
- if (err != Success)
- {
- client->errorValue = stuff->glyphset;
- return err;
- }
-
- err = BadAlloc;
- nglyphs = stuff->nglyphs;
- if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
- return BadAlloc;
-
- component_alpha = NeedsComponent (glyphSet->format->format);
-
- if (nglyphs <= NLOCALGLYPH) {
- memset (glyphsLocal, 0, sizeof (glyphsLocal));
- glyphsBase = glyphsLocal;
- }
- else
- {
- glyphsBase = (GlyphNewPtr)calloc(nglyphs, sizeof (GlyphNewRec));
- if (!glyphsBase)
- return BadAlloc;
- }
-
- remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
-
- glyphs = glyphsBase;
-
- gids = (CARD32 *) (stuff + 1);
- gi = (xGlyphInfo *) (gids + nglyphs);
- bits = (CARD8 *) (gi + nglyphs);
- remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
-
- /* protect against bad nglyphs */
- if (gi < ((xGlyphInfo *)stuff) ||
- gi > ((xGlyphInfo *)((CARD32 *)stuff + client->req_len)) ||
- bits < ((CARD8 *)stuff) ||
- bits > ((CARD8 *)((CARD32 *)stuff + client->req_len))) {
- err = BadLength;
- goto bail;
- }
-
- for (i = 0; i < nglyphs; i++)
- {
- size_t padded_width;
- glyph_new = &glyphs[i];
-
- padded_width = PixmapBytePad (gi[i].width,
- glyphSet->format->depth);
-
- if (gi[i].height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi[i].height)
- break;
-
- size = gi[i].height * padded_width;
- if (remain < size)
- break;
-
- err = HashGlyph (&gi[i], bits, size, glyph_new->sha1);
- if (err)
- goto bail;
-
- glyph_new->glyph = FindGlyphByHash (glyph_new->sha1,
- glyphSet->fdepth);
-
- if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph)
- {
- glyph_new->found = TRUE;
- }
- else
- {
- GlyphPtr glyph;
-
- glyph_new->found = FALSE;
- glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth);
- if (! glyph)
- {
- err = BadAlloc;
- goto bail;
- }
-
- for (screen = 0; screen < screenInfo.numScreens; screen++)
- {
- int width = gi[i].width;
- int height = gi[i].height;
- int depth = glyphSet->format->depth;
- ScreenPtr pScreen;
- int error;
-
- /* Skip work if it's invisibly small anyway */
- if (!width || !height)
- break;
-
- pScreen = screenInfo.screens[screen];
- pSrcPix = GetScratchPixmapHeader (pScreen,
- width, height,
- depth, depth,
- -1, bits);
- if (! pSrcPix)
- {
- err = BadAlloc;
- goto bail;
- }
-
- pSrc = CreatePicture (0, &pSrcPix->drawable,
- glyphSet->format, 0, NULL,
- serverClient, &error);
- if (! pSrc)
- {
- err = BadAlloc;
- goto bail;
- }
-
- pDstPix = (pScreen->CreatePixmap) (pScreen,
- width, height, depth,
- CREATE_PIXMAP_USAGE_GLYPH_PICTURE);
-
- if (!pDstPix)
- {
- err = BadAlloc;
- goto bail;
- }
-
- GlyphPicture (glyph)[screen] = pDst =
- CreatePicture (0, &pDstPix->drawable,
- glyphSet->format,
- CPComponentAlpha, &component_alpha,
- serverClient, &error);
-
- /* The picture takes a reference to the pixmap, so we
- drop ours. */
- (pScreen->DestroyPixmap) (pDstPix);
- pDstPix = NULL;
-
- if (! pDst)
- {
- err = BadAlloc;
- goto bail;
- }
-
- CompositePicture (PictOpSrc,
- pSrc,
- None,
- pDst,
- 0, 0,
- 0, 0,
- 0, 0,
- width, height);
-
- FreePicture ((pointer) pSrc, 0);
- pSrc = NULL;
- FreeScratchPixmapHeader (pSrcPix);
- pSrcPix = NULL;
- }
-
- memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20);
- }
-
- glyph_new->id = gids[i];
-
- if (size & 3)
- size += 4 - (size & 3);
- bits += size;
- remain -= size;
- }
- if (remain || i < nglyphs)
- {
- err = BadLength;
- goto bail;
- }
- if (!ResizeGlyphSet (glyphSet, nglyphs))
- {
- err = BadAlloc;
- goto bail;
- }
- for (i = 0; i < nglyphs; i++)
- AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id);
-
- if (glyphsBase != glyphsLocal)
- free(glyphsBase);
- return Success;
-bail:
- if (pSrc)
- FreePicture ((pointer) pSrc, 0);
- if (pSrcPix)
- FreeScratchPixmapHeader (pSrcPix);
- for (i = 0; i < nglyphs; i++)
- if (glyphs[i].glyph && ! glyphs[i].found)
- free(glyphs[i].glyph);
- if (glyphsBase != glyphsLocal)
- free(glyphsBase);
- return err;
-}
-
-static int
-ProcRenderAddGlyphsFromPicture (ClientPtr client)
-{
- return BadImplementation;
-}
-
-static int
-ProcRenderFreeGlyphs (ClientPtr client)
-{
- REQUEST(xRenderFreeGlyphsReq);
- GlyphSetPtr glyphSet;
- int rc, nglyph;
- CARD32 *gids;
- CARD32 glyph;
-
- REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
- rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType,
- client, DixRemoveAccess);
- if (rc != Success)
- {
- client->errorValue = stuff->glyphset;
- return rc;
- }
- nglyph = bytes_to_int32((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq));
- gids = (CARD32 *) (stuff + 1);
- while (nglyph-- > 0)
- {
- glyph = *gids++;
- if (!DeleteGlyph (glyphSet, glyph))
- {
- client->errorValue = glyph;
- return RenderErrBase + BadGlyph;
- }
- }
- return Success;
-}
-
-static int
-ProcRenderCompositeGlyphs (ClientPtr client)
-{
- GlyphSetPtr glyphSet;
- GlyphSet gs;
- PicturePtr pSrc, pDst;
- PictFormatPtr pFormat;
- GlyphListRec listsLocal[NLOCALDELTA];
- GlyphListPtr lists, listsBase;
- GlyphPtr glyphsLocal[NLOCALGLYPH];
- Glyph glyph;
- GlyphPtr *glyphs, *glyphsBase;
- xGlyphElt *elt;
- CARD8 *buffer, *end;
- int nglyph;
- int nlist;
- int space;
- int size;
- int rc, n;
-
- REQUEST(xRenderCompositeGlyphsReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
-
- switch (stuff->renderReqType) {
- default: size = 1; break;
- case X_RenderCompositeGlyphs16: size = 2; break;
- case X_RenderCompositeGlyphs32: size = 4; break;
- }
-
- if (!PictOpValid (stuff->op))
- {
- client->errorValue = stuff->op;
- return BadValue;
- }
- VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
- VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
- if (!pDst->pDrawable)
- return BadDrawable;
- if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
- return BadMatch;
- if (stuff->maskFormat)
- {
- rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
- PictFormatType, client, DixReadAccess);
- if (rc != Success)
- return rc;
- }
- else
- pFormat = 0;
-
- rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset,
- GlyphSetType, client, DixUseAccess);
- if (rc != Success)
- return rc;
-
- buffer = (CARD8 *) (stuff + 1);
- end = (CARD8 *) stuff + (client->req_len << 2);
- nglyph = 0;
- nlist = 0;
- while (buffer + sizeof (xGlyphElt) < end)
- {
- elt = (xGlyphElt *) buffer;
- buffer += sizeof (xGlyphElt);
-
- if (elt->len == 0xff)
- {
- buffer += 4;
- }
- else
- {
- nlist++;
- nglyph += elt->len;
- space = size * elt->len;
- if (space & 3)
- space += 4 - (space & 3);
- buffer += space;
- }
- }
- if (nglyph <= NLOCALGLYPH)
- glyphsBase = glyphsLocal;
- else
- {
- glyphsBase = (GlyphPtr *) malloc(nglyph * sizeof (GlyphPtr));
- if (!glyphsBase)
- return BadAlloc;
- }
- if (nlist <= NLOCALDELTA)
- listsBase = listsLocal;
- else
- {
- listsBase = (GlyphListPtr) malloc(nlist * sizeof (GlyphListRec));
- if (!listsBase) {
- rc = BadAlloc;
- goto bail;
- }
- }
- buffer = (CARD8 *) (stuff + 1);
- glyphs = glyphsBase;
- lists = listsBase;
- while (buffer + sizeof (xGlyphElt) < end)
- {
- elt = (xGlyphElt *) buffer;
- buffer += sizeof (xGlyphElt);
-
- if (elt->len == 0xff)
- {
- if (buffer + sizeof (GlyphSet) < end)
- {
- memcpy(&gs, buffer, sizeof(GlyphSet));
- rc = dixLookupResourceByType((pointer *)&glyphSet, gs,
- GlyphSetType, client,
- DixUseAccess);
- if (rc != Success)
- goto bail;
- }
- buffer += 4;
- }
- else
- {
- lists->xOff = elt->deltax;
- lists->yOff = elt->deltay;
- lists->format = glyphSet->format;
- lists->len = 0;
- n = elt->len;
- while (n--)
- {
- if (buffer + size <= end)
- {
- switch (size) {
- case 1:
- glyph = *((CARD8 *)buffer); break;
- case 2:
- glyph = *((CARD16 *)buffer); break;
- case 4:
- default:
- glyph = *((CARD32 *)buffer); break;
- }
- if ((*glyphs = FindGlyph (glyphSet, glyph)))
- {
- lists->len++;
- glyphs++;
- }
- }
- buffer += size;
- }
- space = size * elt->len;
- if (space & 3)
- buffer += 4 - (space & 3);
- lists++;
- }
- }
- if (buffer > end) {
- rc = BadLength;
- goto bail;
- }
-
- CompositeGlyphs (stuff->op,
- pSrc,
- pDst,
- pFormat,
- stuff->xSrc,
- stuff->ySrc,
- nlist,
- listsBase,
- glyphsBase);
- rc = Success;
-
-bail:
- if (glyphsBase != glyphsLocal)
- free(glyphsBase);
- if (listsBase != listsLocal)
- free(listsBase);
- return rc;
-}
-
-static int
-ProcRenderFillRectangles (ClientPtr client)
-{
- PicturePtr pDst;
- int things;
- REQUEST(xRenderFillRectanglesReq);
-
- REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
- if (!PictOpValid (stuff->op))
- {
- client->errorValue = stuff->op;
- return BadValue;
- }
- VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
- if (!pDst->pDrawable)
- return BadDrawable;
-
- things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
- if (things & 4)
- return BadLength;
- things >>= 3;
-
- CompositeRects (stuff->op,
- pDst,
- &stuff->color,
- things,
- (xRectangle *) &stuff[1]);
-
- return Success;
-}
-
-static void
-RenderSetBit (unsigned char *line, int x, int bit)
-{
- unsigned char mask;
-
- if (screenInfo.bitmapBitOrder == LSBFirst)
- mask = (1 << (x & 7));
- else
- mask = (0x80 >> (x & 7));
- /* XXX assumes byte order is host byte order */
- line += (x >> 3);
- if (bit)
- *line |= mask;
- else
- *line &= ~mask;
-}
-
-#define DITHER_DIM 2
-
-static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
- { 1, 3, },
- { 4, 2, },
-};
-
-#define DITHER_SIZE ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
-
-static int
-ProcRenderCreateCursor (ClientPtr client)
-{
- REQUEST(xRenderCreateCursorReq);
- PicturePtr pSrc;
- ScreenPtr pScreen;
- unsigned short width, height;
- CARD32 *argbbits, *argb;
- unsigned char *srcbits, *srcline;
- unsigned char *mskbits, *mskline;
- int stride;
- int x, y;
- int nbytes_mono;
- CursorMetricRec cm;
- CursorPtr pCursor;
- CARD32 twocolor[3];
- int rc, ncolor;
-
- REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
- LEGAL_NEW_RESOURCE(stuff->cid, client);
-
- VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
- if (!pSrc->pDrawable)
- return BadDrawable;
- pScreen = pSrc->pDrawable->pScreen;
- width = pSrc->pDrawable->width;
- height = pSrc->pDrawable->height;
- if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
- return BadAlloc;
- if ( stuff->x > width
- || stuff->y > height )
- return BadMatch;
- argbbits = malloc(width * height * sizeof (CARD32));
- if (!argbbits)
- return BadAlloc;
-
- stride = BitmapBytePad(width);
- nbytes_mono = stride*height;
- srcbits = calloc(1, nbytes_mono);
- if (!srcbits)
- {
- free(argbbits);
- return BadAlloc;
- }
- mskbits = calloc(1, nbytes_mono);
- if (!mskbits)
- {
- free(argbbits);
- free(srcbits);
- return BadAlloc;
- }
-
- if (pSrc->format == PICT_a8r8g8b8)
- {
- (*pScreen->GetImage) (pSrc->pDrawable,
- 0, 0, width, height, ZPixmap,
- 0xffffffff, (pointer) argbbits);
- }
- else
- {
- PixmapPtr pPixmap;
- PicturePtr pPicture;
- PictFormatPtr pFormat;
- int error;
-
- pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
- if (!pFormat)
- {
- free(argbbits);
- free(srcbits);
- free(mskbits);
- return BadImplementation;
- }
- pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32,
- CREATE_PIXMAP_USAGE_SCRATCH);
- if (!pPixmap)
- {
- free(argbbits);
- free(srcbits);
- free(mskbits);
- return BadAlloc;
- }
- pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0,
- client, &error);
- if (!pPicture)
- {
- free(argbbits);
- free(srcbits);
- free(mskbits);
- return error;
- }
- (*pScreen->DestroyPixmap) (pPixmap);
- CompositePicture (PictOpSrc,
- pSrc, 0, pPicture,
- 0, 0, 0, 0, 0, 0, width, height);
- (*pScreen->GetImage) (pPicture->pDrawable,
- 0, 0, width, height, ZPixmap,
- 0xffffffff, (pointer) argbbits);
- FreePicture (pPicture, 0);
- }
- /*
- * Check whether the cursor can be directly supported by
- * the core cursor code
- */
- ncolor = 0;
- argb = argbbits;
- for (y = 0; ncolor <= 2 && y < height; y++)
- {
- for (x = 0; ncolor <= 2 && x < width; x++)
- {
- CARD32 p = *argb++;
- CARD32 a = (p >> 24);
-
- if (a == 0) /* transparent */
- continue;
- if (a == 0xff) /* opaque */
- {
- int n;
- for (n = 0; n < ncolor; n++)
- if (p == twocolor[n])
- break;
- if (n == ncolor)
- twocolor[ncolor++] = p;
- }
- else
- ncolor = 3;
- }
- }
-
- /*
- * Convert argb image to two plane cursor
- */
- srcline = srcbits;
- mskline = mskbits;
- argb = argbbits;
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- CARD32 p = *argb++;
-
- if (ncolor <= 2)
- {
- CARD32 a = ((p >> 24));
-
- RenderSetBit (mskline, x, a != 0);
- RenderSetBit (srcline, x, a != 0 && p == twocolor[0]);
- }
- else
- {
- CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255;
- CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
- CARD32 d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
- /* Set mask from dithered alpha value */
- RenderSetBit(mskline, x, a > d);
- /* Set src from dithered intensity value */
- RenderSetBit(srcline, x, a > d && i <= d);
- }
- }
- srcline += stride;
- mskline += stride;
- }
- /*
- * Dither to white and black if the cursor has more than two colors
- */
- if (ncolor > 2)
- {
- twocolor[0] = 0xff000000;
- twocolor[1] = 0xffffffff;
- }
- else
- {
- free(argbbits);
- argbbits = 0;
- }
-
-#define GetByte(p,s) (((p) >> (s)) & 0xff)
-#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8))
-
- cm.width = width;
- cm.height = height;
- cm.xhot = stuff->x;
- cm.yhot = stuff->y;
- rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm,
- GetColor(twocolor[0], 16),
- GetColor(twocolor[0], 8),
- GetColor(twocolor[0], 0),
- GetColor(twocolor[1], 16),
- GetColor(twocolor[1], 8),
- GetColor(twocolor[1], 0),
- &pCursor, client, stuff->cid);
- if (rc != Success)
- goto bail;
- if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) {
- rc = BadAlloc;
- goto bail;
- }
-
- return Success;
-bail:
- free(srcbits);
- free(mskbits);
- return rc;
-}
-
-static int
-ProcRenderSetPictureTransform (ClientPtr client)
-{
- REQUEST(xRenderSetPictureTransformReq);
- PicturePtr pPicture;
-
- REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
- VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess);
- return SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
-}
-
-static int
-ProcRenderQueryFilters (ClientPtr client)
-{
- REQUEST (xRenderQueryFiltersReq);
- DrawablePtr pDrawable;
- xRenderQueryFiltersReply *reply;
- int nbytesName;
- int nnames;
- ScreenPtr pScreen;
- PictureScreenPtr ps;
- int i, j, len, total_bytes, rc;
- INT16 *aliases;
- char *names;
-
- REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- pScreen = pDrawable->pScreen;
- nbytesName = 0;
- nnames = 0;
- ps = GetPictureScreenIfSet(pScreen);
- if (ps)
- {
- for (i = 0; i < ps->nfilters; i++)
- nbytesName += 1 + strlen (ps->filters[i].name);
- for (i = 0; i < ps->nfilterAliases; i++)
- nbytesName += 1 + strlen (ps->filterAliases[i].alias);
- nnames = ps->nfilters + ps->nfilterAliases;
- }
- len = ((nnames + 1) >> 1) + bytes_to_int32(nbytesName);
- total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
- reply = (xRenderQueryFiltersReply *) malloc(total_bytes);
- if (!reply)
- return BadAlloc;
- aliases = (INT16 *) (reply + 1);
- names = (char *) (aliases + ((nnames + 1) & ~1));
-
- reply->type = X_Reply;
- reply->sequenceNumber = client->sequence;
- reply->length = len;
- reply->numAliases = nnames;
- reply->numFilters = nnames;
- if (ps)
- {
-
- /* fill in alias values */
- for (i = 0; i < ps->nfilters; i++)
- aliases[i] = FilterAliasNone;
- for (i = 0; i < ps->nfilterAliases; i++)
- {
- for (j = 0; j < ps->nfilters; j++)
- if (ps->filterAliases[i].filter_id == ps->filters[j].id)
- break;
- if (j == ps->nfilters)
- {
- for (j = 0; j < ps->nfilterAliases; j++)
- if (ps->filterAliases[i].filter_id ==
- ps->filterAliases[j].alias_id)
- {
- break;
- }
- if (j == ps->nfilterAliases)
- j = FilterAliasNone;
- else
- j = j + ps->nfilters;
- }
- aliases[i + ps->nfilters] = j;
- }
-
- /* fill in filter names */
- for (i = 0; i < ps->nfilters; i++)
- {
- j = strlen (ps->filters[i].name);
- *names++ = j;
- strncpy (names, ps->filters[i].name, j);
- names += j;
- }
-
- /* fill in filter alias names */
- for (i = 0; i < ps->nfilterAliases; i++)
- {
- j = strlen (ps->filterAliases[i].alias);
- *names++ = j;
- strncpy (names, ps->filterAliases[i].alias, j);
- names += j;
- }
- }
-
- if (client->swapped)
- {
- register int n;
-
- for (i = 0; i < reply->numAliases; i++)
- {
- swaps (&aliases[i], n);
- }
- swaps(&reply->sequenceNumber, n);
- swapl(&reply->length, n);
- swapl(&reply->numAliases, n);
- swapl(&reply->numFilters, n);
- }
- WriteToClient(client, total_bytes, (char *) reply);
- free(reply);
-
- return Success;
-}
-
-static int
-ProcRenderSetPictureFilter (ClientPtr client)
-{
- REQUEST (xRenderSetPictureFilterReq);
- PicturePtr pPicture;
- int result;
- xFixed *params;
- int nparams;
- char *name;
-
- REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
- VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess);
- name = (char *) (stuff + 1);
- params = (xFixed *) (name + pad_to_int32(stuff->nbytes));
- nparams = ((xFixed *) stuff + client->req_len) - params;
- result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
- return result;
-}
-
-static int
-ProcRenderCreateAnimCursor (ClientPtr client)
-{
- REQUEST(xRenderCreateAnimCursorReq);
- CursorPtr *cursors;
- CARD32 *deltas;
- CursorPtr pCursor;
- int ncursor;
- xAnimCursorElt *elt;
- int i;
- int ret;
-
- REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
- LEGAL_NEW_RESOURCE(stuff->cid, client);
- if (client->req_len & 1)
- return BadLength;
- ncursor = (client->req_len - (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1;
- cursors = malloc(ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
- if (!cursors)
- return BadAlloc;
- deltas = (CARD32 *) (cursors + ncursor);
- elt = (xAnimCursorElt *) (stuff + 1);
- for (i = 0; i < ncursor; i++)
- {
- ret = dixLookupResourceByType((pointer *)(cursors + i), elt->cursor,
- RT_CURSOR, client, DixReadAccess);
- if (ret != Success)
- {
- free(cursors);
- return ret;
- }
- deltas[i] = elt->delay;
- elt++;
- }
- ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor, client,
- stuff->cid);
- free(cursors);
- if (ret != Success)
- return ret;
-
- if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
- return Success;
- return BadAlloc;
-}
-
-static int
-ProcRenderAddTraps (ClientPtr client)
-{
- int ntraps;
- PicturePtr pPicture;
- REQUEST(xRenderAddTrapsReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
- VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess);
- if (!pPicture->pDrawable)
- return BadDrawable;
- ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
- if (ntraps % sizeof (xTrap))
- return BadLength;
- ntraps /= sizeof (xTrap);
- if (ntraps)
- AddTraps (pPicture,
- stuff->xOff, stuff->yOff,
- ntraps, (xTrap *) &stuff[1]);
- return Success;
-}
-
-static int ProcRenderCreateSolidFill(ClientPtr client)
-{
- PicturePtr pPicture;
- int error = 0;
- REQUEST(xRenderCreateSolidFillReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
-
- LEGAL_NEW_RESOURCE(stuff->pid, client);
-
- pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
- if (!pPicture)
- return error;
- /* security creation/labeling check */
- error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
- pPicture, RT_NONE, NULL, DixCreateAccess);
- if (error != Success)
- return error;
- if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
- return BadAlloc;
- return Success;
-}
-
-static int ProcRenderCreateLinearGradient (ClientPtr client)
-{
- PicturePtr pPicture;
- int len;
- int error = 0;
- xFixed *stops;
- xRenderColor *colors;
- REQUEST(xRenderCreateLinearGradientReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
-
- LEGAL_NEW_RESOURCE(stuff->pid, client);
-
- len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
- if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
- return BadLength;
- if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
- return BadLength;
-
- stops = (xFixed *)(stuff + 1);
- colors = (xRenderColor *)(stops + stuff->nStops);
-
- pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
- stuff->nStops, stops, colors, &error);
- if (!pPicture)
- return error;
- /* security creation/labeling check */
- error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
- pPicture, RT_NONE, NULL, DixCreateAccess);
- if (error != Success)
- return error;
- if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
- return BadAlloc;
- return Success;
-}
-
-static int ProcRenderCreateRadialGradient (ClientPtr client)
-{
- PicturePtr pPicture;
- int len;
- int error = 0;
- xFixed *stops;
- xRenderColor *colors;
- REQUEST(xRenderCreateRadialGradientReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
-
- LEGAL_NEW_RESOURCE(stuff->pid, client);
-
- len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
- if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
- return BadLength;
-
- stops = (xFixed *)(stuff + 1);
- colors = (xRenderColor *)(stops + stuff->nStops);
-
- pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
- stuff->inner_radius, stuff->outer_radius,
- stuff->nStops, stops, colors, &error);
- if (!pPicture)
- return error;
- /* security creation/labeling check */
- error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
- pPicture, RT_NONE, NULL, DixCreateAccess);
- if (error != Success)
- return error;
- if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
- return BadAlloc;
- return Success;
-}
-
-static int ProcRenderCreateConicalGradient (ClientPtr client)
-{
- PicturePtr pPicture;
- int len;
- int error = 0;
- xFixed *stops;
- xRenderColor *colors;
- REQUEST(xRenderCreateConicalGradientReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
-
- LEGAL_NEW_RESOURCE(stuff->pid, client);
-
- len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
- if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
- return BadLength;
-
- stops = (xFixed *)(stuff + 1);
- colors = (xRenderColor *)(stops + stuff->nStops);
-
- pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
- stuff->nStops, stops, colors, &error);
- if (!pPicture)
- return error;
- /* security creation/labeling check */
- error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
- pPicture, RT_NONE, NULL, DixCreateAccess);
- if (error != Success)
- return error;
- if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
- return BadAlloc;
- return Success;
-}
-
-
-static int
-ProcRenderDispatch (ClientPtr client)
-{
- REQUEST(xReq);
-
- if (stuff->data < RenderNumberRequests)
- return (*ProcRenderVector[stuff->data]) (client);
- else
- return BadRequest;
-}
-
-static int
-SProcRenderQueryVersion (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderQueryVersionReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->majorVersion, n);
- swapl(&stuff->minorVersion, n);
- return (*ProcRenderVector[stuff->renderReqType])(client);
-}
-
-static int
-SProcRenderQueryPictFormats (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderQueryPictFormatsReq);
- swaps(&stuff->length, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderQueryPictIndexValues (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderQueryPictIndexValuesReq);
- swaps(&stuff->length, n);
- swapl(&stuff->format, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderQueryDithers (ClientPtr client)
-{
- return BadImplementation;
-}
-
-static int
-SProcRenderCreatePicture (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderCreatePictureReq);
- swaps(&stuff->length, n);
- swapl(&stuff->pid, n);
- swapl(&stuff->drawable, n);
- swapl(&stuff->format, n);
- swapl(&stuff->mask, n);
- SwapRestL(stuff);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderChangePicture (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderChangePictureReq);
- swaps(&stuff->length, n);
- swapl(&stuff->picture, n);
- swapl(&stuff->mask, n);
- SwapRestL(stuff);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderSetPictureClipRectangles (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderSetPictureClipRectanglesReq);
- swaps(&stuff->length, n);
- swapl(&stuff->picture, n);
- swaps(&stuff->xOrigin, n);
- swaps(&stuff->yOrigin, n);
- SwapRestS(stuff);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderFreePicture (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderFreePictureReq);
- swaps(&stuff->length, n);
- swapl(&stuff->picture, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderComposite (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderCompositeReq);
- swaps(&stuff->length, n);
- swapl(&stuff->src, n);
- swapl(&stuff->mask, n);
- swapl(&stuff->dst, n);
- swaps(&stuff->xSrc, n);
- swaps(&stuff->ySrc, n);
- swaps(&stuff->xMask, n);
- swaps(&stuff->yMask, n);
- swaps(&stuff->xDst, n);
- swaps(&stuff->yDst, n);
- swaps(&stuff->width, n);
- swaps(&stuff->height, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderScale (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderScaleReq);
- swaps(&stuff->length, n);
- swapl(&stuff->src, n);
- swapl(&stuff->dst, n);
- swapl(&stuff->colorScale, n);
- swapl(&stuff->alphaScale, n);
- swaps(&stuff->xSrc, n);
- swaps(&stuff->ySrc, n);
- swaps(&stuff->xDst, n);
- swaps(&stuff->yDst, n);
- swaps(&stuff->width, n);
- swaps(&stuff->height, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderTrapezoids (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderTrapezoidsReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
- swaps (&stuff->length, n);
- swapl (&stuff->src, n);
- swapl (&stuff->dst, n);
- swapl (&stuff->maskFormat, n);
- swaps (&stuff->xSrc, n);
- swaps (&stuff->ySrc, n);
- SwapRestL(stuff);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderTriangles (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderTrianglesReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
- swaps (&stuff->length, n);
- swapl (&stuff->src, n);
- swapl (&stuff->dst, n);
- swapl (&stuff->maskFormat, n);
- swaps (&stuff->xSrc, n);
- swaps (&stuff->ySrc, n);
- SwapRestL(stuff);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderTriStrip (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderTriStripReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
- swaps (&stuff->length, n);
- swapl (&stuff->src, n);
- swapl (&stuff->dst, n);
- swapl (&stuff->maskFormat, n);
- swaps (&stuff->xSrc, n);
- swaps (&stuff->ySrc, n);
- SwapRestL(stuff);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderTriFan (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderTriFanReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
- swaps (&stuff->length, n);
- swapl (&stuff->src, n);
- swapl (&stuff->dst, n);
- swapl (&stuff->maskFormat, n);
- swaps (&stuff->xSrc, n);
- swaps (&stuff->ySrc, n);
- SwapRestL(stuff);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderColorTrapezoids (ClientPtr client)
-{
- return BadImplementation;
-}
-
-static int
-SProcRenderColorTriangles (ClientPtr client)
-{
- return BadImplementation;
-}
-
-static int
-SProcRenderTransform (ClientPtr client)
-{
- return BadImplementation;
-}
-
-static int
-SProcRenderCreateGlyphSet (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderCreateGlyphSetReq);
- swaps(&stuff->length, n);
- swapl(&stuff->gsid, n);
- swapl(&stuff->format, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderReferenceGlyphSet (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderReferenceGlyphSetReq);
- swaps(&stuff->length, n);
- swapl(&stuff->gsid, n);
- swapl(&stuff->existing, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderFreeGlyphSet (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderFreeGlyphSetReq);
- swaps(&stuff->length, n);
- swapl(&stuff->glyphset, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderAddGlyphs (ClientPtr client)
-{
- register int n;
- register int i;
- CARD32 *gids;
- void *end;
- xGlyphInfo *gi;
- REQUEST(xRenderAddGlyphsReq);
- swaps(&stuff->length, n);
- swapl(&stuff->glyphset, n);
- swapl(&stuff->nglyphs, n);
- if (stuff->nglyphs & 0xe0000000)
- return BadLength;
- end = (CARD8 *) stuff + (client->req_len << 2);
- gids = (CARD32 *) (stuff + 1);
- gi = (xGlyphInfo *) (gids + stuff->nglyphs);
- if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
- return BadLength;
- if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
- return BadLength;
- for (i = 0; i < stuff->nglyphs; i++)
- {
- swapl (&gids[i], n);
- swaps (&gi[i].width, n);
- swaps (&gi[i].height, n);
- swaps (&gi[i].x, n);
- swaps (&gi[i].y, n);
- swaps (&gi[i].xOff, n);
- swaps (&gi[i].yOff, n);
- }
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderAddGlyphsFromPicture (ClientPtr client)
-{
- return BadImplementation;
-}
-
-static int
-SProcRenderFreeGlyphs (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderFreeGlyphsReq);
- swaps(&stuff->length, n);
- swapl(&stuff->glyphset, n);
- SwapRestL(stuff);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderCompositeGlyphs (ClientPtr client)
-{
- register int n;
- xGlyphElt *elt;
- CARD8 *buffer;
- CARD8 *end;
- int space;
- int i;
- int size;
-
- REQUEST(xRenderCompositeGlyphsReq);
-
- switch (stuff->renderReqType) {
- default: size = 1; break;
- case X_RenderCompositeGlyphs16: size = 2; break;
- case X_RenderCompositeGlyphs32: size = 4; break;
- }
-
- swaps(&stuff->length, n);
- swapl(&stuff->src, n);
- swapl(&stuff->dst, n);
- swapl(&stuff->maskFormat, n);
- swapl(&stuff->glyphset, n);
- swaps(&stuff->xSrc, n);
- swaps(&stuff->ySrc, n);
- buffer = (CARD8 *) (stuff + 1);
- end = (CARD8 *) stuff + (client->req_len << 2);
- while (buffer + sizeof (xGlyphElt) < end)
- {
- elt = (xGlyphElt *) buffer;
- buffer += sizeof (xGlyphElt);
-
- swaps (&elt->deltax, n);
- swaps (&elt->deltay, n);
-
- i = elt->len;
- if (i == 0xff)
- {
- swapl (buffer, n);
- buffer += 4;
- }
- else
- {
- space = size * i;
- switch (size) {
- case 1:
- buffer += i;
- break;
- case 2:
- while (i--)
- {
- swaps (buffer, n);
- buffer += 2;
- }
- break;
- case 4:
- while (i--)
- {
- swapl (buffer, n);
- buffer += 4;
- }
- break;
- }
- if (space & 3)
- buffer += 4 - (space & 3);
- }
- }
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderFillRectangles (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderFillRectanglesReq);
-
- REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
- swaps(&stuff->length, n);
- swapl(&stuff->dst, n);
- swaps(&stuff->color.red, n);
- swaps(&stuff->color.green, n);
- swaps(&stuff->color.blue, n);
- swaps(&stuff->color.alpha, n);
- SwapRestS(stuff);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderCreateCursor (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderCreateCursorReq);
- REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->cid, n);
- swapl(&stuff->src, n);
- swaps(&stuff->x, n);
- swaps(&stuff->y, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderSetPictureTransform (ClientPtr client)
-{
- register int n;
- REQUEST(xRenderSetPictureTransformReq);
- REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->picture, n);
- swapl(&stuff->transform.matrix11, n);
- swapl(&stuff->transform.matrix12, n);
- swapl(&stuff->transform.matrix13, n);
- swapl(&stuff->transform.matrix21, n);
- swapl(&stuff->transform.matrix22, n);
- swapl(&stuff->transform.matrix23, n);
- swapl(&stuff->transform.matrix31, n);
- swapl(&stuff->transform.matrix32, n);
- swapl(&stuff->transform.matrix33, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderQueryFilters (ClientPtr client)
-{
- register int n;
- REQUEST (xRenderQueryFiltersReq);
- REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->drawable, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderSetPictureFilter (ClientPtr client)
-{
- register int n;
- REQUEST (xRenderSetPictureFilterReq);
- REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->picture, n);
- swaps(&stuff->nbytes, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderCreateAnimCursor (ClientPtr client)
-{
- register int n;
- REQUEST (xRenderCreateAnimCursorReq);
- REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->cid, n);
- SwapRestL(stuff);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderAddTraps (ClientPtr client)
-{
- register int n;
- REQUEST (xRenderAddTrapsReq);
- REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->picture, n);
- swaps(&stuff->xOff, n);
- swaps(&stuff->yOff, n);
- SwapRestL(stuff);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderCreateSolidFill(ClientPtr client)
-{
- register int n;
- REQUEST (xRenderCreateSolidFillReq);
- REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->pid, n);
- swaps(&stuff->color.alpha, n);
- swaps(&stuff->color.red, n);
- swaps(&stuff->color.green, n);
- swaps(&stuff->color.blue, n);
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static void swapStops(void *stuff, int num)
-{
- int i, n;
- CARD32 *stops;
- CARD16 *colors;
- stops = (CARD32 *)(stuff);
- for (i = 0; i < num; ++i) {
- swapl(stops, n);
- ++stops;
- }
- colors = (CARD16 *)(stops);
- for (i = 0; i < 4*num; ++i) {
- swaps(colors, n);
- ++colors;
- }
-}
-
-static int
-SProcRenderCreateLinearGradient (ClientPtr client)
-{
- register int n;
- int len;
- REQUEST (xRenderCreateLinearGradientReq);
- REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->pid, n);
- swapl(&stuff->p1.x, n);
- swapl(&stuff->p1.y, n);
- swapl(&stuff->p2.x, n);
- swapl(&stuff->p2.y, n);
- swapl(&stuff->nStops, n);
-
- len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
- if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
- return BadLength;
- if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
- return BadLength;
-
- swapStops(stuff+1, stuff->nStops);
-
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderCreateRadialGradient (ClientPtr client)
-{
- register int n;
- int len;
- REQUEST (xRenderCreateRadialGradientReq);
- REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->pid, n);
- swapl(&stuff->inner.x, n);
- swapl(&stuff->inner.y, n);
- swapl(&stuff->outer.x, n);
- swapl(&stuff->outer.y, n);
- swapl(&stuff->inner_radius, n);
- swapl(&stuff->outer_radius, n);
- swapl(&stuff->nStops, n);
-
- len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
- if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
- return BadLength;
- if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
- return BadLength;
-
- swapStops(stuff+1, stuff->nStops);
-
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderCreateConicalGradient (ClientPtr client)
-{
- register int n;
- int len;
- REQUEST (xRenderCreateConicalGradientReq);
- REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->pid, n);
- swapl(&stuff->center.x, n);
- swapl(&stuff->center.y, n);
- swapl(&stuff->angle, n);
- swapl(&stuff->nStops, n);
-
- len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
- if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
- return BadLength;
- if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
- return BadLength;
-
- swapStops(stuff+1, stuff->nStops);
-
- return (*ProcRenderVector[stuff->renderReqType]) (client);
-}
-
-static int
-SProcRenderDispatch (ClientPtr client)
-{
- REQUEST(xReq);
-
- if (stuff->data < RenderNumberRequests)
- return (*SProcRenderVector[stuff->data]) (client);
- else
- return BadRequest;
-}
-
-#ifdef PANORAMIX
-#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\
- int rc = dixLookupResourceByType((pointer *)&(pPicture), pid,\
- XRT_PICTURE, client, mode);\
- if (rc != Success)\
- return rc;\
-}
-
-#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\
- if (pid == None) \
- pPicture = 0; \
- else { \
- VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \
- } \
-} \
-
-int (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
-
-static int
-PanoramiXRenderCreatePicture (ClientPtr client)
-{
- REQUEST(xRenderCreatePictureReq);
- PanoramiXRes *refDraw, *newPict;
- int result, j;
-
- REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
- result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable,
- XRC_DRAWABLE, client, DixWriteAccess);
- if (result != Success)
- return (result == BadValue) ? BadDrawable : result;
- if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
- newPict->type = XRT_PICTURE;
- panoramix_setup_ids(newPict, client, stuff->pid);
-
- if (refDraw->type == XRT_WINDOW &&
- stuff->drawable == screenInfo.screens[0]->root->drawable.id)
- {
- newPict->u.pict.root = TRUE;
- }
- else
- newPict->u.pict.root = FALSE;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->pid = newPict->info[j].id;
- stuff->drawable = refDraw->info[j].id;
- result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
- else
- free(newPict);
-
- return result;
-}
-
-static int
-PanoramiXRenderChangePicture (ClientPtr client)
-{
- PanoramiXRes *pict;
- int result = Success, j;
- REQUEST(xRenderChangePictureReq);
-
- REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
-
- VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->picture = pict->info[j].id;
- result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-static int
-PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
-{
- REQUEST(xRenderSetPictureClipRectanglesReq);
- int result = Success, j;
- PanoramiXRes *pict;
-
- REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
-
- VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->picture = pict->info[j].id;
- result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-static int
-PanoramiXRenderSetPictureTransform (ClientPtr client)
-{
- REQUEST(xRenderSetPictureTransformReq);
- int result = Success, j;
- PanoramiXRes *pict;
-
- REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
-
- VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->picture = pict->info[j].id;
- result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-static int
-PanoramiXRenderSetPictureFilter (ClientPtr client)
-{
- REQUEST(xRenderSetPictureFilterReq);
- int result = Success, j;
- PanoramiXRes *pict;
-
- REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
-
- VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->picture = pict->info[j].id;
- result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-static int
-PanoramiXRenderFreePicture (ClientPtr client)
-{
- PanoramiXRes *pict;
- int result = Success, j;
- REQUEST(xRenderFreePictureReq);
-
- REQUEST_SIZE_MATCH(xRenderFreePictureReq);
-
- client->errorValue = stuff->picture;
-
- VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess);
-
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->picture = pict->info[j].id;
- result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
- if(result != Success) break;
- }
-
- /* Since ProcRenderFreePicture is using FreeResource, it will free
- our resource for us on the last pass through the loop above */
-
- return result;
-}
-
-static int
-PanoramiXRenderComposite (ClientPtr client)
-{
- PanoramiXRes *src, *msk, *dst;
- int result = Success, j;
- xRenderCompositeReq orig;
- REQUEST(xRenderCompositeReq);
-
- REQUEST_SIZE_MATCH(xRenderCompositeReq);
-
- VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
- VERIFY_XIN_ALPHA (msk, stuff->mask, client, DixReadAccess);
- VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
-
- orig = *stuff;
-
- FOR_NSCREENS_FORWARD(j) {
- stuff->src = src->info[j].id;
- if (src->u.pict.root)
- {
- stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x;
- stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y;
- }
- stuff->dst = dst->info[j].id;
- if (dst->u.pict.root)
- {
- stuff->xDst = orig.xDst - screenInfo.screens[j]->x;
- stuff->yDst = orig.yDst - screenInfo.screens[j]->y;
- }
- if (msk)
- {
- stuff->mask = msk->info[j].id;
- if (msk->u.pict.root)
- {
- stuff->xMask = orig.xMask - screenInfo.screens[j]->x;
- stuff->yMask = orig.yMask - screenInfo.screens[j]->y;
- }
- }
- result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
- if(result != Success) break;
- }
-
- return result;
-}
-
-static int
-PanoramiXRenderCompositeGlyphs (ClientPtr client)
-{
- PanoramiXRes *src, *dst;
- int result = Success, j;
- REQUEST(xRenderCompositeGlyphsReq);
- xGlyphElt origElt, *elt;
- INT16 xSrc, ySrc;
-
- REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
- VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
- VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
-
- if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
- sizeof (xGlyphElt)))
- {
- elt = (xGlyphElt *) (stuff + 1);
- origElt = *elt;
- xSrc = stuff->xSrc;
- ySrc = stuff->ySrc;
- FOR_NSCREENS_FORWARD(j) {
- stuff->src = src->info[j].id;
- if (src->u.pict.root)
- {
- stuff->xSrc = xSrc - screenInfo.screens[j]->x;
- stuff->ySrc = ySrc - screenInfo.screens[j]->y;
- }
- stuff->dst = dst->info[j].id;
- if (dst->u.pict.root)
- {
- elt->deltax = origElt.deltax - screenInfo.screens[j]->x;
- elt->deltay = origElt.deltay - screenInfo.screens[j]->y;
- }
- result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
- if(result != Success) break;
- }
- }
-
- return result;
-}
-
-static int
-PanoramiXRenderFillRectangles (ClientPtr client)
-{
- PanoramiXRes *dst;
- int result = Success, j;
- REQUEST(xRenderFillRectanglesReq);
- char *extra;
- int extra_len;
-
- REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
- VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
- extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
- if (extra_len &&
- (extra = (char *) malloc(extra_len)))
- {
- memcpy (extra, stuff + 1, extra_len);
- FOR_NSCREENS_FORWARD(j) {
- if (j) memcpy (stuff + 1, extra, extra_len);
- if (dst->u.pict.root)
- {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xRectangle *rects = (xRectangle *) (stuff + 1);
- int i = extra_len / sizeof (xRectangle);
-
- while (i--)
- {
- rects->x -= x_off;
- rects->y -= y_off;
- rects++;
- }
- }
- }
- stuff->dst = dst->info[j].id;
- result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
- if(result != Success) break;
- }
- free(extra);
- }
-
- return result;
-}
-
-static int
-PanoramiXRenderTrapezoids(ClientPtr client)
-{
- PanoramiXRes *src, *dst;
- int result = Success, j;
- REQUEST(xRenderTrapezoidsReq);
- char *extra;
- int extra_len;
-
- REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
-
- VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
- VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
-
- extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
-
- if (extra_len &&
- (extra = (char *) malloc(extra_len))) {
- memcpy (extra, stuff + 1, extra_len);
-
- FOR_NSCREENS_FORWARD(j) {
- if (j) memcpy (stuff + 1, extra, extra_len);
- if (dst->u.pict.root) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xTrapezoid *trap = (xTrapezoid *) (stuff + 1);
- int i = extra_len / sizeof (xTrapezoid);
-
- while (i--) {
- trap->top -= y_off;
- trap->bottom -= y_off;
- trap->left.p1.x -= x_off;
- trap->left.p1.y -= y_off;
- trap->left.p2.x -= x_off;
- trap->left.p2.y -= y_off;
- trap->right.p1.x -= x_off;
- trap->right.p1.y -= y_off;
- trap->right.p2.x -= x_off;
- trap->right.p2.y -= y_off;
- trap++;
- }
- }
- }
-
- stuff->src = src->info[j].id;
- stuff->dst = dst->info[j].id;
- result =
- (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
-
- if(result != Success) break;
- }
-
- free(extra);
- }
-
- return result;
-}
-
-static int
-PanoramiXRenderTriangles(ClientPtr client)
-{
- PanoramiXRes *src, *dst;
- int result = Success, j;
- REQUEST(xRenderTrianglesReq);
- char *extra;
- int extra_len;
-
- REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
-
- VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
- VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
-
- extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
-
- if (extra_len &&
- (extra = (char *) malloc(extra_len))) {
- memcpy (extra, stuff + 1, extra_len);
-
- FOR_NSCREENS_FORWARD(j) {
- if (j) memcpy (stuff + 1, extra, extra_len);
- if (dst->u.pict.root) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xTriangle *tri = (xTriangle *) (stuff + 1);
- int i = extra_len / sizeof (xTriangle);
-
- while (i--) {
- tri->p1.x -= x_off;
- tri->p1.y -= y_off;
- tri->p2.x -= x_off;
- tri->p2.y -= y_off;
- tri->p3.x -= x_off;
- tri->p3.y -= y_off;
- tri++;
- }
- }
- }
-
- stuff->src = src->info[j].id;
- stuff->dst = dst->info[j].id;
- result =
- (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
-
- if(result != Success) break;
- }
-
- free(extra);
- }
-
- return result;
-}
-
-static int
-PanoramiXRenderTriStrip(ClientPtr client)
-{
- PanoramiXRes *src, *dst;
- int result = Success, j;
- REQUEST(xRenderTriStripReq);
- char *extra;
- int extra_len;
-
- REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
-
- VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
- VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
-
- extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
-
- if (extra_len &&
- (extra = (char *) malloc(extra_len))) {
- memcpy (extra, stuff + 1, extra_len);
-
- FOR_NSCREENS_FORWARD(j) {
- if (j) memcpy (stuff + 1, extra, extra_len);
- if (dst->u.pict.root) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xPointFixed *fixed = (xPointFixed *) (stuff + 1);
- int i = extra_len / sizeof (xPointFixed);
-
- while (i--) {
- fixed->x -= x_off;
- fixed->y -= y_off;
- fixed++;
- }
- }
- }
-
- stuff->src = src->info[j].id;
- stuff->dst = dst->info[j].id;
- result =
- (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
-
- if(result != Success) break;
- }
-
- free(extra);
- }
-
- return result;
-}
-
-static int
-PanoramiXRenderTriFan(ClientPtr client)
-{
- PanoramiXRes *src, *dst;
- int result = Success, j;
- REQUEST(xRenderTriFanReq);
- char *extra;
- int extra_len;
-
- REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
-
- VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
- VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
-
- extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
-
- if (extra_len &&
- (extra = (char *) malloc(extra_len))) {
- memcpy (extra, stuff + 1, extra_len);
-
- FOR_NSCREENS_FORWARD(j) {
- if (j) memcpy (stuff + 1, extra, extra_len);
- if (dst->u.pict.root) {
- int x_off = screenInfo.screens[j]->x;
- int y_off = screenInfo.screens[j]->y;
-
- if(x_off || y_off) {
- xPointFixed *fixed = (xPointFixed *) (stuff + 1);
- int i = extra_len / sizeof (xPointFixed);
-
- while (i--) {
- fixed->x -= x_off;
- fixed->y -= y_off;
- fixed++;
- }
- }
- }
-
- stuff->src = src->info[j].id;
- stuff->dst = dst->info[j].id;
- result =
- (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
-
- if(result != Success) break;
- }
-
- free(extra);
- }
-
- return result;
-}
-
-static int
-PanoramiXRenderAddTraps (ClientPtr client)
-{
- PanoramiXRes *picture;
- int result = Success, j;
- REQUEST(xRenderAddTrapsReq);
- char *extra;
- int extra_len;
- INT16 x_off, y_off;
-
- REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
- VERIFY_XIN_PICTURE (picture, stuff->picture, client, DixWriteAccess);
- extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
- if (extra_len &&
- (extra = (char *) malloc(extra_len)))
- {
- memcpy (extra, stuff + 1, extra_len);
- x_off = stuff->xOff;
- y_off = stuff->yOff;
- FOR_NSCREENS_FORWARD(j) {
- if (j) memcpy (stuff + 1, extra, extra_len);
- stuff->picture = picture->info[j].id;
-
- if (picture->u.pict.root)
- {
- stuff->xOff = x_off + screenInfo.screens[j]->x;
- stuff->yOff = y_off + screenInfo.screens[j]->y;
- }
- result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
- if(result != Success) break;
- }
- free(extra);
- }
-
- return result;
-}
-
-static int
-PanoramiXRenderCreateSolidFill (ClientPtr client)
-{
- REQUEST(xRenderCreateSolidFillReq);
- PanoramiXRes *newPict;
- int result = Success, j;
-
- REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
-
- if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newPict->type = XRT_PICTURE;
- panoramix_setup_ids(newPict, client, stuff->pid);
- newPict->u.pict.root = FALSE;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->pid = newPict->info[j].id;
- result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
- else
- free(newPict);
-
- return result;
-}
-
-static int
-PanoramiXRenderCreateLinearGradient (ClientPtr client)
-{
- REQUEST(xRenderCreateLinearGradientReq);
- PanoramiXRes *newPict;
- int result = Success, j;
-
- REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
-
- if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newPict->type = XRT_PICTURE;
- panoramix_setup_ids(newPict, client, stuff->pid);
- newPict->u.pict.root = FALSE;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->pid = newPict->info[j].id;
- result = (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
- else
- free(newPict);
-
- return result;
-}
-
-static int
-PanoramiXRenderCreateRadialGradient (ClientPtr client)
-{
- REQUEST(xRenderCreateRadialGradientReq);
- PanoramiXRes *newPict;
- int result = Success, j;
-
- REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
-
- if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newPict->type = XRT_PICTURE;
- panoramix_setup_ids(newPict, client, stuff->pid);
- newPict->u.pict.root = FALSE;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->pid = newPict->info[j].id;
- result = (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
- else
- free(newPict);
-
- return result;
-}
-
-static int
-PanoramiXRenderCreateConicalGradient (ClientPtr client)
-{
- REQUEST(xRenderCreateConicalGradientReq);
- PanoramiXRes *newPict;
- int result = Success, j;
-
- REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
-
- if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
- return BadAlloc;
-
- newPict->type = XRT_PICTURE;
- panoramix_setup_ids(newPict, client, stuff->pid);
- newPict->u.pict.root = FALSE;
-
- FOR_NSCREENS_BACKWARD(j) {
- stuff->pid = newPict->info[j].id;
- result = (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient]) (client);
- if(result != Success) break;
- }
-
- if (result == Success)
- AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
- else
- free(newPict);
-
- return result;
-}
-
-void
-PanoramiXRenderInit (void)
-{
- int i;
-
- XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource,
- "XineramaPicture");
- if (RenderErrBase)
- SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
- for (i = 0; i < RenderNumberRequests; i++)
- PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
- /*
- * Stuff in Xinerama aware request processing hooks
- */
- ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
- ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
- ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
- ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
- ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
- ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
- ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
- ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
- ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
- ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
- ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
-
- ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
- ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
- ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
- ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
- ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
-
- ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill;
- ProcRenderVector[X_RenderCreateLinearGradient] = PanoramiXRenderCreateLinearGradient;
- ProcRenderVector[X_RenderCreateRadialGradient] = PanoramiXRenderCreateRadialGradient;
- ProcRenderVector[X_RenderCreateConicalGradient] = PanoramiXRenderCreateConicalGradient;
-}
-
-void
-PanoramiXRenderReset (void)
-{
- int i;
- for (i = 0; i < RenderNumberRequests; i++)
- ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
- RenderErrBase = 0;
-}
-
-#endif /* PANORAMIX */
+/* + * + * 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "os.h" +#include "dixstruct.h" +#include "resource.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "colormapst.h" +#include "extnsionst.h" +#include "servermd.h" +#include <X11/extensions/render.h> +#include <X11/extensions/renderproto.h> +#include "picturestr.h" +#include "glyphstr.h" +#include <X11/Xfuncproto.h> +#include "cursorstr.h" +#include "xace.h" +#include "protocol-versions.h" + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" +#endif + +#if HAVE_STDINT_H +#include <stdint.h> +#elif !defined(UINT32_MAX) +#define UINT32_MAX 0xffffffffU +#endif + +static int ProcRenderQueryVersion (ClientPtr pClient); +static int ProcRenderQueryPictFormats (ClientPtr pClient); +static int ProcRenderQueryPictIndexValues (ClientPtr pClient); +static int ProcRenderQueryDithers (ClientPtr pClient); +static int ProcRenderCreatePicture (ClientPtr pClient); +static int ProcRenderChangePicture (ClientPtr pClient); +static int ProcRenderSetPictureClipRectangles (ClientPtr pClient); +static int ProcRenderFreePicture (ClientPtr pClient); +static int ProcRenderComposite (ClientPtr pClient); +static int ProcRenderScale (ClientPtr pClient); +static int ProcRenderTrapezoids (ClientPtr pClient); +static int ProcRenderTriangles (ClientPtr pClient); +static int ProcRenderTriStrip (ClientPtr pClient); +static int ProcRenderTriFan (ClientPtr pClient); +static int ProcRenderColorTrapezoids (ClientPtr pClient); +static int ProcRenderColorTriangles (ClientPtr pClient); +static int ProcRenderTransform (ClientPtr pClient); +static int ProcRenderCreateGlyphSet (ClientPtr pClient); +static int ProcRenderReferenceGlyphSet (ClientPtr pClient); +static int ProcRenderFreeGlyphSet (ClientPtr pClient); +static int ProcRenderAddGlyphs (ClientPtr pClient); +static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient); +static int ProcRenderFreeGlyphs (ClientPtr pClient); +static int ProcRenderCompositeGlyphs (ClientPtr pClient); +static int ProcRenderFillRectangles (ClientPtr pClient); +static int ProcRenderCreateCursor (ClientPtr pClient); +static int ProcRenderSetPictureTransform (ClientPtr pClient); +static int ProcRenderQueryFilters (ClientPtr pClient); +static int ProcRenderSetPictureFilter (ClientPtr pClient); +static int ProcRenderCreateAnimCursor (ClientPtr pClient); +static int ProcRenderAddTraps (ClientPtr pClient); +static int ProcRenderCreateSolidFill (ClientPtr pClient); +static int ProcRenderCreateLinearGradient (ClientPtr pClient); +static int ProcRenderCreateRadialGradient (ClientPtr pClient); +static int ProcRenderCreateConicalGradient (ClientPtr pClient); + +static int ProcRenderDispatch (ClientPtr pClient); + +static int SProcRenderQueryVersion (ClientPtr pClient); +static int SProcRenderQueryPictFormats (ClientPtr pClient); +static int SProcRenderQueryPictIndexValues (ClientPtr pClient); +static int SProcRenderQueryDithers (ClientPtr pClient); +static int SProcRenderCreatePicture (ClientPtr pClient); +static int SProcRenderChangePicture (ClientPtr pClient); +static int SProcRenderSetPictureClipRectangles (ClientPtr pClient); +static int SProcRenderFreePicture (ClientPtr pClient); +static int SProcRenderComposite (ClientPtr pClient); +static int SProcRenderScale (ClientPtr pClient); +static int SProcRenderTrapezoids (ClientPtr pClient); +static int SProcRenderTriangles (ClientPtr pClient); +static int SProcRenderTriStrip (ClientPtr pClient); +static int SProcRenderTriFan (ClientPtr pClient); +static int SProcRenderColorTrapezoids (ClientPtr pClient); +static int SProcRenderColorTriangles (ClientPtr pClient); +static int SProcRenderTransform (ClientPtr pClient); +static int SProcRenderCreateGlyphSet (ClientPtr pClient); +static int SProcRenderReferenceGlyphSet (ClientPtr pClient); +static int SProcRenderFreeGlyphSet (ClientPtr pClient); +static int SProcRenderAddGlyphs (ClientPtr pClient); +static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient); +static int SProcRenderFreeGlyphs (ClientPtr pClient); +static int SProcRenderCompositeGlyphs (ClientPtr pClient); +static int SProcRenderFillRectangles (ClientPtr pClient); +static int SProcRenderCreateCursor (ClientPtr pClient); +static int SProcRenderSetPictureTransform (ClientPtr pClient); +static int SProcRenderQueryFilters (ClientPtr pClient); +static int SProcRenderSetPictureFilter (ClientPtr pClient); +static int SProcRenderCreateAnimCursor (ClientPtr pClient); +static int SProcRenderAddTraps (ClientPtr pClient); +static int SProcRenderCreateSolidFill (ClientPtr pClient); +static int SProcRenderCreateLinearGradient (ClientPtr pClient); +static int SProcRenderCreateRadialGradient (ClientPtr pClient); +static int SProcRenderCreateConicalGradient (ClientPtr pClient); + +static int SProcRenderDispatch (ClientPtr pClient); + +int (*ProcRenderVector[RenderNumberRequests])(ClientPtr) = { + ProcRenderQueryVersion, + ProcRenderQueryPictFormats, + ProcRenderQueryPictIndexValues, + ProcRenderQueryDithers, + ProcRenderCreatePicture, + ProcRenderChangePicture, + ProcRenderSetPictureClipRectangles, + ProcRenderFreePicture, + ProcRenderComposite, + ProcRenderScale, + ProcRenderTrapezoids, + ProcRenderTriangles, + ProcRenderTriStrip, + ProcRenderTriFan, + ProcRenderColorTrapezoids, + ProcRenderColorTriangles, + ProcRenderTransform, + ProcRenderCreateGlyphSet, + ProcRenderReferenceGlyphSet, + ProcRenderFreeGlyphSet, + ProcRenderAddGlyphs, + ProcRenderAddGlyphsFromPicture, + ProcRenderFreeGlyphs, + ProcRenderCompositeGlyphs, + ProcRenderCompositeGlyphs, + ProcRenderCompositeGlyphs, + ProcRenderFillRectangles, + ProcRenderCreateCursor, + ProcRenderSetPictureTransform, + ProcRenderQueryFilters, + ProcRenderSetPictureFilter, + ProcRenderCreateAnimCursor, + ProcRenderAddTraps, + ProcRenderCreateSolidFill, + ProcRenderCreateLinearGradient, + ProcRenderCreateRadialGradient, + ProcRenderCreateConicalGradient +}; + +int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = { + SProcRenderQueryVersion, + SProcRenderQueryPictFormats, + SProcRenderQueryPictIndexValues, + SProcRenderQueryDithers, + SProcRenderCreatePicture, + SProcRenderChangePicture, + SProcRenderSetPictureClipRectangles, + SProcRenderFreePicture, + SProcRenderComposite, + SProcRenderScale, + SProcRenderTrapezoids, + SProcRenderTriangles, + SProcRenderTriStrip, + SProcRenderTriFan, + SProcRenderColorTrapezoids, + SProcRenderColorTriangles, + SProcRenderTransform, + SProcRenderCreateGlyphSet, + SProcRenderReferenceGlyphSet, + SProcRenderFreeGlyphSet, + SProcRenderAddGlyphs, + SProcRenderAddGlyphsFromPicture, + SProcRenderFreeGlyphs, + SProcRenderCompositeGlyphs, + SProcRenderCompositeGlyphs, + SProcRenderCompositeGlyphs, + SProcRenderFillRectangles, + SProcRenderCreateCursor, + SProcRenderSetPictureTransform, + SProcRenderQueryFilters, + SProcRenderSetPictureFilter, + SProcRenderCreateAnimCursor, + SProcRenderAddTraps, + SProcRenderCreateSolidFill, + SProcRenderCreateLinearGradient, + SProcRenderCreateRadialGradient, + SProcRenderCreateConicalGradient +}; + +int RenderErrBase; +static DevPrivateKeyRec RenderClientPrivateKeyRec; +#define RenderClientPrivateKey (&RenderClientPrivateKeyRec ) + +typedef struct _RenderClient { + int major_version; + int minor_version; +} RenderClientRec, *RenderClientPtr; + +#define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey)) + +static void +RenderClientCallback (CallbackListPtr *list, + pointer closure, + pointer data) +{ + NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; + ClientPtr pClient = clientinfo->client; + RenderClientPtr pRenderClient = GetRenderClient (pClient); + + pRenderClient->major_version = 0; + pRenderClient->minor_version = 0; +} + +#ifdef PANORAMIX +RESTYPE XRT_PICTURE; +#endif + +void +RenderExtensionInit (void) +{ + ExtensionEntry *extEntry; + + if (!PictureType) + return; + if (!PictureFinishInit ()) + return; + if (!dixRegisterPrivateKey(&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec))) + return; + if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0)) + return; + + extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors, + ProcRenderDispatch, SProcRenderDispatch, + NULL, StandardMinorOpcode); + if (!extEntry) + return; + RenderErrBase = extEntry->errorBase; +#ifdef PANORAMIX + if (XRT_PICTURE) + SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture); +#endif + SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture); + SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat); + SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet); +} + +static int +ProcRenderQueryVersion (ClientPtr client) +{ + RenderClientPtr pRenderClient = GetRenderClient (client); + xRenderQueryVersionReply rep; + register int n; + REQUEST(xRenderQueryVersionReq); + + pRenderClient->major_version = stuff->majorVersion; + pRenderClient->minor_version = stuff->minorVersion; + + REQUEST_SIZE_MATCH(xRenderQueryVersionReq); + memset(&rep, 0, sizeof(xRenderQueryVersionReply)); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if ((stuff->majorVersion * 1000 + stuff->minorVersion) < + (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) + { + rep.majorVersion = stuff->majorVersion; + rep.minorVersion = stuff->minorVersion; + } else + { + rep.majorVersion = SERVER_RENDER_MAJOR_VERSION; + rep.minorVersion = SERVER_RENDER_MINOR_VERSION; + } + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep); + return Success; +} + +static VisualPtr +findVisual (ScreenPtr pScreen, VisualID vid) +{ + VisualPtr pVisual; + int v; + + for (v = 0; v < pScreen->numVisuals; v++) + { + pVisual = pScreen->visuals + v; + if (pVisual->vid == vid) + return pVisual; + } + return 0; +} + +static int +ProcRenderQueryPictFormats (ClientPtr client) +{ + RenderClientPtr pRenderClient = GetRenderClient (client); + xRenderQueryPictFormatsReply *reply; + xPictScreen *pictScreen; + xPictDepth *pictDepth; + xPictVisual *pictVisual; + xPictFormInfo *pictForm; + CARD32 *pictSubpixel; + ScreenPtr pScreen; + VisualPtr pVisual; + DepthPtr pDepth; + int v, d; + PictureScreenPtr ps; + PictFormatPtr pFormat; + int nformat; + int ndepth; + int nvisual; + int rlength; + int s; + int n; + int numScreens; + int numSubpixel; +/* REQUEST(xRenderQueryPictFormatsReq); */ + + REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq); + +#ifdef PANORAMIX + if (noPanoramiXExtension) + numScreens = screenInfo.numScreens; + else + numScreens = ((xConnSetup *)ConnectionInfo)->numRoots; +#else + numScreens = screenInfo.numScreens; +#endif + ndepth = nformat = nvisual = 0; + for (s = 0; s < numScreens; s++) + { + pScreen = screenInfo.screens[s]; + for (d = 0; d < pScreen->numDepths; d++) + { + pDepth = pScreen->allowedDepths + d; + ++ndepth; + + for (v = 0; v < pDepth->numVids; v++) + { + pVisual = findVisual (pScreen, pDepth->vids[v]); + if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual)) + ++nvisual; + } + } + ps = GetPictureScreenIfSet(pScreen); + if (ps) + nformat += ps->nformats; + } + if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6) + numSubpixel = 0; + else + numSubpixel = numScreens; + + rlength = (sizeof (xRenderQueryPictFormatsReply) + + nformat * sizeof (xPictFormInfo) + + numScreens * sizeof (xPictScreen) + + ndepth * sizeof (xPictDepth) + + nvisual * sizeof (xPictVisual) + + numSubpixel * sizeof (CARD32)); + reply = (xRenderQueryPictFormatsReply *) calloc(1, rlength); + if (!reply) + return BadAlloc; + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); + reply->numFormats = nformat; + reply->numScreens = numScreens; + reply->numDepths = ndepth; + reply->numVisuals = nvisual; + reply->numSubpixel = numSubpixel; + + pictForm = (xPictFormInfo *) (reply + 1); + + for (s = 0; s < numScreens; s++) + { + pScreen = screenInfo.screens[s]; + ps = GetPictureScreenIfSet(pScreen); + if (ps) + { + for (nformat = 0, pFormat = ps->formats; + nformat < ps->nformats; + nformat++, pFormat++) + { + pictForm->id = pFormat->id; + pictForm->type = pFormat->type; + pictForm->depth = pFormat->depth; + pictForm->direct.red = pFormat->direct.red; + pictForm->direct.redMask = pFormat->direct.redMask; + pictForm->direct.green = pFormat->direct.green; + pictForm->direct.greenMask = pFormat->direct.greenMask; + pictForm->direct.blue = pFormat->direct.blue; + pictForm->direct.blueMask = pFormat->direct.blueMask; + pictForm->direct.alpha = pFormat->direct.alpha; + pictForm->direct.alphaMask = pFormat->direct.alphaMask; + if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap) + pictForm->colormap = pFormat->index.pColormap->mid; + else + pictForm->colormap = None; + if (client->swapped) + { + swapl (&pictForm->id, n); + swaps (&pictForm->direct.red, n); + swaps (&pictForm->direct.redMask, n); + swaps (&pictForm->direct.green, n); + swaps (&pictForm->direct.greenMask, n); + swaps (&pictForm->direct.blue, n); + swaps (&pictForm->direct.blueMask, n); + swaps (&pictForm->direct.alpha, n); + swaps (&pictForm->direct.alphaMask, n); + swapl (&pictForm->colormap, n); + } + pictForm++; + } + } + } + + pictScreen = (xPictScreen *) pictForm; + for (s = 0; s < numScreens; s++) + { + pScreen = screenInfo.screens[s]; + pictDepth = (xPictDepth *) (pictScreen + 1); + ndepth = 0; + for (d = 0; d < pScreen->numDepths; d++) + { + pictVisual = (xPictVisual *) (pictDepth + 1); + pDepth = pScreen->allowedDepths + d; + + nvisual = 0; + for (v = 0; v < pDepth->numVids; v++) + { + pVisual = findVisual (pScreen, pDepth->vids[v]); + if (pVisual && (pFormat = PictureMatchVisual (pScreen, + pDepth->depth, + pVisual))) + { + pictVisual->visual = pVisual->vid; + pictVisual->format = pFormat->id; + if (client->swapped) + { + swapl (&pictVisual->visual, n); + swapl (&pictVisual->format, n); + } + pictVisual++; + nvisual++; + } + } + pictDepth->depth = pDepth->depth; + pictDepth->nPictVisuals = nvisual; + if (client->swapped) + { + swaps (&pictDepth->nPictVisuals, n); + } + ndepth++; + pictDepth = (xPictDepth *) pictVisual; + } + pictScreen->nDepth = ndepth; + ps = GetPictureScreenIfSet(pScreen); + if (ps) + pictScreen->fallback = ps->fallback->id; + else + pictScreen->fallback = 0; + if (client->swapped) + { + swapl (&pictScreen->nDepth, n); + swapl (&pictScreen->fallback, n); + } + pictScreen = (xPictScreen *) pictDepth; + } + pictSubpixel = (CARD32 *) pictScreen; + + for (s = 0; s < numSubpixel; s++) + { + pScreen = screenInfo.screens[s]; + ps = GetPictureScreenIfSet(pScreen); + if (ps) + *pictSubpixel = ps->subpixel; + else + *pictSubpixel = SubPixelUnknown; + if (client->swapped) + { + swapl (pictSubpixel, n); + } + ++pictSubpixel; + } + + if (client->swapped) + { + swaps (&reply->sequenceNumber, n); + swapl (&reply->length, n); + swapl (&reply->numFormats, n); + swapl (&reply->numScreens, n); + swapl (&reply->numDepths, n); + swapl (&reply->numVisuals, n); + swapl (&reply->numSubpixel, n); + } + WriteToClient(client, rlength, (char *) reply); + free(reply); + return Success; +} + +static int +ProcRenderQueryPictIndexValues (ClientPtr client) +{ + PictFormatPtr pFormat; + int rc, num; + int rlength; + int i, n; + REQUEST(xRenderQueryPictIndexValuesReq); + xRenderQueryPictIndexValuesReply *reply; + xIndexValue *values; + + REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq); + + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->format, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + + if (pFormat->type != PictTypeIndexed) + { + client->errorValue = stuff->format; + return BadMatch; + } + num = pFormat->index.nvalues; + rlength = (sizeof (xRenderQueryPictIndexValuesReply) + + num * sizeof(xIndexValue)); + reply = (xRenderQueryPictIndexValuesReply *) malloc(rlength); + if (!reply) + return BadAlloc; + + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); + reply->numIndexValues = num; + + values = (xIndexValue *) (reply + 1); + + memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue)); + + if (client->swapped) + { + for (i = 0; i < num; i++) + { + swapl (&values[i].pixel, n); + swaps (&values[i].red, n); + swaps (&values[i].green, n); + swaps (&values[i].blue, n); + swaps (&values[i].alpha, n); + } + swaps (&reply->sequenceNumber, n); + swapl (&reply->length, n); + swapl (&reply->numIndexValues, n); + } + + WriteToClient(client, rlength, (char *) reply); + free(reply); + return Success; +} + +static int +ProcRenderQueryDithers (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderCreatePicture (ClientPtr client) +{ + PicturePtr pPicture; + DrawablePtr pDrawable; + PictFormatPtr pFormat; + int len, error, rc; + REQUEST(xRenderCreatePictureReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixReadAccess|DixAddAccess); + if (rc != Success) + return rc; + + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->format, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + + if (pFormat->depth != pDrawable->depth) + return BadMatch; + len = client->req_len - bytes_to_int32(sizeof(xRenderCreatePictureReq)); + if (Ones(stuff->mask) != len) + return BadLength; + + pPicture = CreatePicture (stuff->pid, + pDrawable, + pFormat, + stuff->mask, + (XID *) (stuff + 1), + client, + &error); + if (!pPicture) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + +static int +ProcRenderChangePicture (ClientPtr client) +{ + PicturePtr pPicture; + REQUEST(xRenderChangePictureReq); + int len; + + REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess); + + len = client->req_len - bytes_to_int32(sizeof(xRenderChangePictureReq)); + if (Ones(stuff->mask) != len) + return BadLength; + + return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1), + (DevUnion *) 0, client); +} + +static int +ProcRenderSetPictureClipRectangles (ClientPtr client) +{ + REQUEST(xRenderSetPictureClipRectanglesReq); + PicturePtr pPicture; + int nr; + + REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess); + if (!pPicture->pDrawable) + return BadDrawable; + + nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq); + if (nr & 4) + return BadLength; + nr >>= 3; + return SetPictureClipRects (pPicture, + stuff->xOrigin, stuff->yOrigin, + nr, (xRectangle *) &stuff[1]); +} + +static int +ProcRenderFreePicture (ClientPtr client) +{ + PicturePtr pPicture; + REQUEST(xRenderFreePictureReq); + + REQUEST_SIZE_MATCH(xRenderFreePictureReq); + + VERIFY_PICTURE (pPicture, stuff->picture, client, DixDestroyAccess); + FreeResource (stuff->picture, RT_NONE); + return Success; +} + +static Bool +PictOpValid (CARD8 op) +{ + if (/*PictOpMinimum <= op && */ op <= PictOpMaximum) + return TRUE; + if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum) + return TRUE; + if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum) + return TRUE; + if (PictOpBlendMinimum <= op && op <= PictOpBlendMaximum) + return TRUE; + return FALSE; +} + +static int +ProcRenderComposite (ClientPtr client) +{ + PicturePtr pSrc, pMask, pDst; + REQUEST(xRenderCompositeReq); + + REQUEST_SIZE_MATCH(xRenderCompositeReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + VERIFY_ALPHA (pMask, stuff->mask, client, DixReadAccess); + if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) || + (pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen)) + return BadMatch; + CompositePicture (stuff->op, + pSrc, + pMask, + pDst, + stuff->xSrc, + stuff->ySrc, + stuff->xMask, + stuff->yMask, + stuff->xDst, + stuff->yDst, + stuff->width, + stuff->height); + return Success; +} + +static int +ProcRenderScale (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderTrapezoids (ClientPtr client) +{ + int rc, ntraps; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + REQUEST(xRenderTrapezoidsReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + } + else + pFormat = 0; + ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq); + if (ntraps % sizeof (xTrapezoid)) + return BadLength; + ntraps /= sizeof (xTrapezoid); + if (ntraps) + CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat, + stuff->xSrc, stuff->ySrc, + ntraps, (xTrapezoid *) &stuff[1]); + return Success; +} + +static int +ProcRenderTriangles (ClientPtr client) +{ + int rc, ntris; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + REQUEST(xRenderTrianglesReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + } + else + pFormat = 0; + ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq); + if (ntris % sizeof (xTriangle)) + return BadLength; + ntris /= sizeof (xTriangle); + if (ntris) + CompositeTriangles (stuff->op, pSrc, pDst, pFormat, + stuff->xSrc, stuff->ySrc, + ntris, (xTriangle *) &stuff[1]); + return Success; +} + +static int +ProcRenderTriStrip (ClientPtr client) +{ + int rc, npoints; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + REQUEST(xRenderTrianglesReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + } + else + pFormat = 0; + npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq)); + if (npoints & 4) + return BadLength; + npoints >>= 3; + if (npoints >= 3) + CompositeTriStrip (stuff->op, pSrc, pDst, pFormat, + stuff->xSrc, stuff->ySrc, + npoints, (xPointFixed *) &stuff[1]); + return Success; +} + +static int +ProcRenderTriFan (ClientPtr client) +{ + int rc, npoints; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + REQUEST(xRenderTrianglesReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + } + else + pFormat = 0; + npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq)); + if (npoints & 4) + return BadLength; + npoints >>= 3; + if (npoints >= 3) + CompositeTriFan (stuff->op, pSrc, pDst, pFormat, + stuff->xSrc, stuff->ySrc, + npoints, (xPointFixed *) &stuff[1]); + return Success; +} + +static int +ProcRenderColorTrapezoids (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderColorTriangles (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderTransform (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderCreateGlyphSet (ClientPtr client) +{ + GlyphSetPtr glyphSet; + PictFormatPtr format; + int rc, f; + REQUEST(xRenderCreateGlyphSetReq); + + REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq); + + LEGAL_NEW_RESOURCE(stuff->gsid, client); + rc = dixLookupResourceByType((pointer *)&format, stuff->format, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + + switch (format->depth) { + case 1: + f = GlyphFormat1; + break; + case 4: + f = GlyphFormat4; + break; + case 8: + f = GlyphFormat8; + break; + case 16: + f = GlyphFormat16; + break; + case 32: + f = GlyphFormat32; + break; + default: + return BadMatch; + } + if (format->type != PictTypeDirect) + return BadMatch; + glyphSet = AllocateGlyphSet (f, format); + if (!glyphSet) + return BadAlloc; + /* security creation/labeling check */ + rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType, + glyphSet, RT_NONE, NULL, DixCreateAccess); + if (rc != Success) + return rc; + if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet)) + return BadAlloc; + return Success; +} + +static int +ProcRenderReferenceGlyphSet (ClientPtr client) +{ + GlyphSetPtr glyphSet; + int rc; + REQUEST(xRenderReferenceGlyphSetReq); + + REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq); + + LEGAL_NEW_RESOURCE(stuff->gsid, client); + + rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->existing, GlyphSetType, + client, DixGetAttrAccess); + if (rc != Success) + { + client->errorValue = stuff->existing; + return rc; + } + glyphSet->refcnt++; + if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet)) + return BadAlloc; + return Success; +} + +#define NLOCALDELTA 64 +#define NLOCALGLYPH 256 + +static int +ProcRenderFreeGlyphSet (ClientPtr client) +{ + GlyphSetPtr glyphSet; + int rc; + REQUEST(xRenderFreeGlyphSetReq); + + REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq); + rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, + client, DixDestroyAccess); + if (rc != Success) + { + client->errorValue = stuff->glyphset; + return rc; + } + FreeResource (stuff->glyphset, RT_NONE); + return Success; +} + +typedef struct _GlyphNew { + Glyph id; + GlyphPtr glyph; + Bool found; + unsigned char sha1[20]; +} GlyphNewRec, *GlyphNewPtr; + +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + +static int +ProcRenderAddGlyphs (ClientPtr client) +{ + GlyphSetPtr glyphSet; + REQUEST(xRenderAddGlyphsReq); + GlyphNewRec glyphsLocal[NLOCALGLYPH]; + GlyphNewPtr glyphsBase, glyphs, glyph_new; + int remain, nglyphs; + CARD32 *gids; + xGlyphInfo *gi; + CARD8 *bits; + unsigned int size; + int err; + int i, screen; + PicturePtr pSrc = NULL, pDst = NULL; + PixmapPtr pSrcPix = NULL, pDstPix = NULL; + CARD32 component_alpha; + + REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); + err = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, + client, DixAddAccess); + if (err != Success) + { + client->errorValue = stuff->glyphset; + return err; + } + + err = BadAlloc; + nglyphs = stuff->nglyphs; + if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) + return BadAlloc; + + component_alpha = NeedsComponent (glyphSet->format->format); + + if (nglyphs <= NLOCALGLYPH) { + memset (glyphsLocal, 0, sizeof (glyphsLocal)); + glyphsBase = glyphsLocal; + } + else + { + glyphsBase = (GlyphNewPtr)calloc(nglyphs, sizeof (GlyphNewRec)); + if (!glyphsBase) + return BadAlloc; + } + + remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq); + + glyphs = glyphsBase; + + gids = (CARD32 *) (stuff + 1); + gi = (xGlyphInfo *) (gids + nglyphs); + bits = (CARD8 *) (gi + nglyphs); + remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; + + /* protect against bad nglyphs */ + if (gi < ((xGlyphInfo *)stuff) || + gi > ((xGlyphInfo *)((CARD32 *)stuff + client->req_len)) || + bits < ((CARD8 *)stuff) || + bits > ((CARD8 *)((CARD32 *)stuff + client->req_len))) { + err = BadLength; + goto bail; + } + + for (i = 0; i < nglyphs; i++) + { + size_t padded_width; + glyph_new = &glyphs[i]; + + padded_width = PixmapBytePad (gi[i].width, + glyphSet->format->depth); + + if (gi[i].height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi[i].height) + break; + + size = gi[i].height * padded_width; + if (remain < size) + break; + + err = HashGlyph (&gi[i], bits, size, glyph_new->sha1); + if (err) + goto bail; + + glyph_new->glyph = FindGlyphByHash (glyph_new->sha1, + glyphSet->fdepth); + + if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) + { + glyph_new->found = TRUE; + } + else + { + GlyphPtr glyph; + + glyph_new->found = FALSE; + glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth); + if (! glyph) + { + err = BadAlloc; + goto bail; + } + + for (screen = 0; screen < screenInfo.numScreens; screen++) + { + int width = gi[i].width; + int height = gi[i].height; + int depth = glyphSet->format->depth; + ScreenPtr pScreen; + int error; + + /* Skip work if it's invisibly small anyway */ + if (!width || !height) + break; + + pScreen = screenInfo.screens[screen]; + pSrcPix = GetScratchPixmapHeader (pScreen, + width, height, + depth, depth, + -1, bits); + if (! pSrcPix) + { + err = BadAlloc; + goto bail; + } + + pSrc = CreatePicture (0, &pSrcPix->drawable, + glyphSet->format, 0, NULL, + serverClient, &error); + if (! pSrc) + { + err = BadAlloc; + goto bail; + } + + pDstPix = (pScreen->CreatePixmap) (pScreen, + width, height, depth, + CREATE_PIXMAP_USAGE_GLYPH_PICTURE); + + if (!pDstPix) + { + err = BadAlloc; + goto bail; + } + + GlyphPicture (glyph)[screen] = pDst = + CreatePicture (0, &pDstPix->drawable, + glyphSet->format, + CPComponentAlpha, &component_alpha, + serverClient, &error); + + /* The picture takes a reference to the pixmap, so we + drop ours. */ + (pScreen->DestroyPixmap) (pDstPix); + pDstPix = NULL; + + if (! pDst) + { + err = BadAlloc; + goto bail; + } + + CompositePicture (PictOpSrc, + pSrc, + None, + pDst, + 0, 0, + 0, 0, + 0, 0, + width, height); + + FreePicture ((pointer) pSrc, 0); + pSrc = NULL; + FreeScratchPixmapHeader (pSrcPix); + pSrcPix = NULL; + } + + memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20); + } + + glyph_new->id = gids[i]; + + if (size & 3) + size += 4 - (size & 3); + bits += size; + remain -= size; + } + if (remain || i < nglyphs) + { + err = BadLength; + goto bail; + } + if (!ResizeGlyphSet (glyphSet, nglyphs)) + { + err = BadAlloc; + goto bail; + } + for (i = 0; i < nglyphs; i++) + AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id); + + if (glyphsBase != glyphsLocal) + free(glyphsBase); + return Success; +bail: + if (pSrc) + FreePicture ((pointer) pSrc, 0); + if (pSrcPix) + FreeScratchPixmapHeader (pSrcPix); + for (i = 0; i < nglyphs; i++) + if (glyphs[i].glyph && ! glyphs[i].found) + free(glyphs[i].glyph); + if (glyphsBase != glyphsLocal) + free(glyphsBase); + return err; +} + +static int +ProcRenderAddGlyphsFromPicture (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderFreeGlyphs (ClientPtr client) +{ + REQUEST(xRenderFreeGlyphsReq); + GlyphSetPtr glyphSet; + int rc, nglyph; + CARD32 *gids; + CARD32 glyph; + + REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq); + rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, + client, DixRemoveAccess); + if (rc != Success) + { + client->errorValue = stuff->glyphset; + return rc; + } + nglyph = bytes_to_int32((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)); + gids = (CARD32 *) (stuff + 1); + while (nglyph-- > 0) + { + glyph = *gids++; + if (!DeleteGlyph (glyphSet, glyph)) + { + client->errorValue = glyph; + return RenderErrBase + BadGlyph; + } + } + return Success; +} + +static int +ProcRenderCompositeGlyphs (ClientPtr client) +{ + GlyphSetPtr glyphSet; + GlyphSet gs; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + GlyphListRec listsLocal[NLOCALDELTA]; + GlyphListPtr lists, listsBase; + GlyphPtr glyphsLocal[NLOCALGLYPH]; + Glyph glyph; + GlyphPtr *glyphs, *glyphsBase; + xGlyphElt *elt; + CARD8 *buffer, *end; + int nglyph; + int nlist; + int space; + int size; + int rc, n; + + REQUEST(xRenderCompositeGlyphsReq); + + REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); + + switch (stuff->renderReqType) { + default: size = 1; break; + case X_RenderCompositeGlyphs16: size = 2; break; + case X_RenderCompositeGlyphs32: size = 4; break; + } + + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + } + else + pFormat = 0; + + rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, + GlyphSetType, client, DixUseAccess); + if (rc != Success) + return rc; + + buffer = (CARD8 *) (stuff + 1); + end = (CARD8 *) stuff + (client->req_len << 2); + nglyph = 0; + nlist = 0; + while (buffer + sizeof (xGlyphElt) < end) + { + elt = (xGlyphElt *) buffer; + buffer += sizeof (xGlyphElt); + + if (elt->len == 0xff) + { + buffer += 4; + } + else + { + nlist++; + nglyph += elt->len; + space = size * elt->len; + if (space & 3) + space += 4 - (space & 3); + buffer += space; + } + } + if (nglyph <= NLOCALGLYPH) + glyphsBase = glyphsLocal; + else + { + glyphsBase = (GlyphPtr *) malloc(nglyph * sizeof (GlyphPtr)); + if (!glyphsBase) + return BadAlloc; + } + if (nlist <= NLOCALDELTA) + listsBase = listsLocal; + else + { + listsBase = (GlyphListPtr) malloc(nlist * sizeof (GlyphListRec)); + if (!listsBase) { + rc = BadAlloc; + goto bail; + } + } + buffer = (CARD8 *) (stuff + 1); + glyphs = glyphsBase; + lists = listsBase; + while (buffer + sizeof (xGlyphElt) < end) + { + elt = (xGlyphElt *) buffer; + buffer += sizeof (xGlyphElt); + + if (elt->len == 0xff) + { + if (buffer + sizeof (GlyphSet) < end) + { + memcpy(&gs, buffer, sizeof(GlyphSet)); + rc = dixLookupResourceByType((pointer *)&glyphSet, gs, + GlyphSetType, client, + DixUseAccess); + if (rc != Success) + goto bail; + } + buffer += 4; + } + else + { + lists->xOff = elt->deltax; + lists->yOff = elt->deltay; + lists->format = glyphSet->format; + lists->len = 0; + n = elt->len; + while (n--) + { + if (buffer + size <= end) + { + switch (size) { + case 1: + glyph = *((CARD8 *)buffer); break; + case 2: + glyph = *((CARD16 *)buffer); break; + case 4: + default: + glyph = *((CARD32 *)buffer); break; + } + if ((*glyphs = FindGlyph (glyphSet, glyph))) + { + lists->len++; + glyphs++; + } + } + buffer += size; + } + space = size * elt->len; + if (space & 3) + buffer += 4 - (space & 3); + lists++; + } + } + if (buffer > end) { + rc = BadLength; + goto bail; + } + + CompositeGlyphs (stuff->op, + pSrc, + pDst, + pFormat, + stuff->xSrc, + stuff->ySrc, + nlist, + listsBase, + glyphsBase); + rc = Success; + +bail: + if (glyphsBase != glyphsLocal) + free(glyphsBase); + if (listsBase != listsLocal) + free(listsBase); + return rc; +} + +static int +ProcRenderFillRectangles (ClientPtr client) +{ + PicturePtr pDst; + int things; + REQUEST(xRenderFillRectanglesReq); + + REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + + things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq); + if (things & 4) + return BadLength; + things >>= 3; + + CompositeRects (stuff->op, + pDst, + &stuff->color, + things, + (xRectangle *) &stuff[1]); + + return Success; +} + +static void +RenderSetBit (unsigned char *line, int x, int bit) +{ + unsigned char mask; + + if (screenInfo.bitmapBitOrder == LSBFirst) + mask = (1 << (x & 7)); + else + mask = (0x80 >> (x & 7)); + /* XXX assumes byte order is host byte order */ + line += (x >> 3); + if (bit) + *line |= mask; + else + *line &= ~mask; +} + +#define DITHER_DIM 2 + +static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = { + { 1, 3, }, + { 4, 2, }, +}; + +#define DITHER_SIZE ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1) + +static int +ProcRenderCreateCursor (ClientPtr client) +{ + REQUEST(xRenderCreateCursorReq); + PicturePtr pSrc; + ScreenPtr pScreen; + unsigned short width, height; + CARD32 *argbbits, *argb; + unsigned char *srcbits, *srcline; + unsigned char *mskbits, *mskline; + int stride; + int x, y; + int nbytes_mono; + CursorMetricRec cm; + CursorPtr pCursor; + CARD32 twocolor[3]; + int rc, ncolor; + + REQUEST_SIZE_MATCH (xRenderCreateCursorReq); + LEGAL_NEW_RESOURCE(stuff->cid, client); + + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + if (!pSrc->pDrawable) + return BadDrawable; + pScreen = pSrc->pDrawable->pScreen; + width = pSrc->pDrawable->width; + height = pSrc->pDrawable->height; + if (height && width > UINT32_MAX/(height*sizeof(CARD32))) + return BadAlloc; + if ( stuff->x > width + || stuff->y > height ) + return BadMatch; + argbbits = malloc(width * height * sizeof (CARD32)); + if (!argbbits) + return BadAlloc; + + stride = BitmapBytePad(width); + nbytes_mono = stride*height; + srcbits = calloc(1, nbytes_mono); + if (!srcbits) + { + free(argbbits); + return BadAlloc; + } + mskbits = calloc(1, nbytes_mono); + if (!mskbits) + { + free(argbbits); + free(srcbits); + return BadAlloc; + } + + if (pSrc->format == PICT_a8r8g8b8) + { + (*pScreen->GetImage) (pSrc->pDrawable, + 0, 0, width, height, ZPixmap, + 0xffffffff, (pointer) argbbits); + } + else + { + PixmapPtr pPixmap; + PicturePtr pPicture; + PictFormatPtr pFormat; + int error; + + pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8); + if (!pFormat) + { + free(argbbits); + free(srcbits); + free(mskbits); + return BadImplementation; + } + pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pPixmap) + { + free(argbbits); + free(srcbits); + free(mskbits); + return BadAlloc; + } + pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0, + client, &error); + if (!pPicture) + { + free(argbbits); + free(srcbits); + free(mskbits); + return error; + } + (*pScreen->DestroyPixmap) (pPixmap); + CompositePicture (PictOpSrc, + pSrc, 0, pPicture, + 0, 0, 0, 0, 0, 0, width, height); + (*pScreen->GetImage) (pPicture->pDrawable, + 0, 0, width, height, ZPixmap, + 0xffffffff, (pointer) argbbits); + FreePicture (pPicture, 0); + } + /* + * Check whether the cursor can be directly supported by + * the core cursor code + */ + ncolor = 0; + argb = argbbits; + for (y = 0; ncolor <= 2 && y < height; y++) + { + for (x = 0; ncolor <= 2 && x < width; x++) + { + CARD32 p = *argb++; + CARD32 a = (p >> 24); + + if (a == 0) /* transparent */ + continue; + if (a == 0xff) /* opaque */ + { + int n; + for (n = 0; n < ncolor; n++) + if (p == twocolor[n]) + break; + if (n == ncolor) + twocolor[ncolor++] = p; + } + else + ncolor = 3; + } + } + + /* + * Convert argb image to two plane cursor + */ + srcline = srcbits; + mskline = mskbits; + argb = argbbits; + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + CARD32 p = *argb++; + + if (ncolor <= 2) + { + CARD32 a = ((p >> 24)); + + RenderSetBit (mskline, x, a != 0); + RenderSetBit (srcline, x, a != 0 && p == twocolor[0]); + } + else + { + CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255; + CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255; + CARD32 d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)]; + /* Set mask from dithered alpha value */ + RenderSetBit(mskline, x, a > d); + /* Set src from dithered intensity value */ + RenderSetBit(srcline, x, a > d && i <= d); + } + } + srcline += stride; + mskline += stride; + } + /* + * Dither to white and black if the cursor has more than two colors + */ + if (ncolor > 2) + { + twocolor[0] = 0xff000000; + twocolor[1] = 0xffffffff; + } + else + { + free(argbbits); + argbbits = 0; + } + +#define GetByte(p,s) (((p) >> (s)) & 0xff) +#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8)) + + cm.width = width; + cm.height = height; + cm.xhot = stuff->x; + cm.yhot = stuff->y; + rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm, + GetColor(twocolor[0], 16), + GetColor(twocolor[0], 8), + GetColor(twocolor[0], 0), + GetColor(twocolor[1], 16), + GetColor(twocolor[1], 8), + GetColor(twocolor[1], 0), + &pCursor, client, stuff->cid); + if (rc != Success) + goto bail; + if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) { + rc = BadAlloc; + goto bail; + } + + return Success; +bail: + free(srcbits); + free(mskbits); + return rc; +} + +static int +ProcRenderSetPictureTransform (ClientPtr client) +{ + REQUEST(xRenderSetPictureTransformReq); + PicturePtr pPicture; + + REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess); + return SetPictureTransform (pPicture, (PictTransform *) &stuff->transform); +} + +static int +ProcRenderQueryFilters (ClientPtr client) +{ + REQUEST (xRenderQueryFiltersReq); + DrawablePtr pDrawable; + xRenderQueryFiltersReply *reply; + int nbytesName; + int nnames; + ScreenPtr pScreen; + PictureScreenPtr ps; + int i, j, len, total_bytes, rc; + INT16 *aliases; + char *names; + + REQUEST_SIZE_MATCH(xRenderQueryFiltersReq); + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixGetAttrAccess); + if (rc != Success) + return rc; + + pScreen = pDrawable->pScreen; + nbytesName = 0; + nnames = 0; + ps = GetPictureScreenIfSet(pScreen); + if (ps) + { + for (i = 0; i < ps->nfilters; i++) + nbytesName += 1 + strlen (ps->filters[i].name); + for (i = 0; i < ps->nfilterAliases; i++) + nbytesName += 1 + strlen (ps->filterAliases[i].alias); + nnames = ps->nfilters + ps->nfilterAliases; + } + len = ((nnames + 1) >> 1) + bytes_to_int32(nbytesName); + total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2); + reply = (xRenderQueryFiltersReply *) malloc(total_bytes); + if (!reply) + return BadAlloc; + aliases = (INT16 *) (reply + 1); + names = (char *) (aliases + ((nnames + 1) & ~1)); + + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = len; + reply->numAliases = nnames; + reply->numFilters = nnames; + if (ps) + { + + /* fill in alias values */ + for (i = 0; i < ps->nfilters; i++) + aliases[i] = FilterAliasNone; + for (i = 0; i < ps->nfilterAliases; i++) + { + for (j = 0; j < ps->nfilters; j++) + if (ps->filterAliases[i].filter_id == ps->filters[j].id) + break; + if (j == ps->nfilters) + { + for (j = 0; j < ps->nfilterAliases; j++) + if (ps->filterAliases[i].filter_id == + ps->filterAliases[j].alias_id) + { + break; + } + if (j == ps->nfilterAliases) + j = FilterAliasNone; + else + j = j + ps->nfilters; + } + aliases[i + ps->nfilters] = j; + } + + /* fill in filter names */ + for (i = 0; i < ps->nfilters; i++) + { + j = strlen (ps->filters[i].name); + *names++ = j; + strncpy (names, ps->filters[i].name, j); + names += j; + } + + /* fill in filter alias names */ + for (i = 0; i < ps->nfilterAliases; i++) + { + j = strlen (ps->filterAliases[i].alias); + *names++ = j; + strncpy (names, ps->filterAliases[i].alias, j); + names += j; + } + } + + if (client->swapped) + { + register int n; + + for (i = 0; i < reply->numAliases; i++) + { + swaps (&aliases[i], n); + } + swaps(&reply->sequenceNumber, n); + swapl(&reply->length, n); + swapl(&reply->numAliases, n); + swapl(&reply->numFilters, n); + } + WriteToClient(client, total_bytes, (char *) reply); + free(reply); + + return Success; +} + +static int +ProcRenderSetPictureFilter (ClientPtr client) +{ + REQUEST (xRenderSetPictureFilterReq); + PicturePtr pPicture; + int result; + xFixed *params; + int nparams; + char *name; + + REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess); + name = (char *) (stuff + 1); + params = (xFixed *) (name + pad_to_int32(stuff->nbytes)); + nparams = ((xFixed *) stuff + client->req_len) - params; + result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams); + return result; +} + +static int +ProcRenderCreateAnimCursor (ClientPtr client) +{ + REQUEST(xRenderCreateAnimCursorReq); + CursorPtr *cursors; + CARD32 *deltas; + CursorPtr pCursor; + int ncursor; + xAnimCursorElt *elt; + int i; + int ret; + + REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq); + LEGAL_NEW_RESOURCE(stuff->cid, client); + if (client->req_len & 1) + return BadLength; + ncursor = (client->req_len - (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1; + cursors = malloc(ncursor * (sizeof (CursorPtr) + sizeof (CARD32))); + if (!cursors) + return BadAlloc; + deltas = (CARD32 *) (cursors + ncursor); + elt = (xAnimCursorElt *) (stuff + 1); + for (i = 0; i < ncursor; i++) + { + ret = dixLookupResourceByType((pointer *)(cursors + i), elt->cursor, + RT_CURSOR, client, DixReadAccess); + if (ret != Success) + { + free(cursors); + return ret; + } + deltas[i] = elt->delay; + elt++; + } + ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor, client, + stuff->cid); + free(cursors); + if (ret != Success) + return ret; + + if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor)) + return Success; + return BadAlloc; +} + +static int +ProcRenderAddTraps (ClientPtr client) +{ + int ntraps; + PicturePtr pPicture; + REQUEST(xRenderAddTrapsReq); + + REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess); + if (!pPicture->pDrawable) + return BadDrawable; + ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq); + if (ntraps % sizeof (xTrap)) + return BadLength; + ntraps /= sizeof (xTrap); + if (ntraps) + AddTraps (pPicture, + stuff->xOff, stuff->yOff, + ntraps, (xTrap *) &stuff[1]); + return Success; +} + +static int ProcRenderCreateSolidFill(ClientPtr client) +{ + PicturePtr pPicture; + int error = 0; + REQUEST(xRenderCreateSolidFillReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + + pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error); + if (!pPicture) + return error; + /* security creation/labeling check */ + error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, + pPicture, RT_NONE, NULL, DixCreateAccess); + if (error != Success) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + +static int ProcRenderCreateLinearGradient (ClientPtr client) +{ + PicturePtr pPicture; + int len; + int error = 0; + xFixed *stops; + xRenderColor *colors; + REQUEST(xRenderCreateLinearGradientReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + + len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + stops = (xFixed *)(stuff + 1); + colors = (xRenderColor *)(stops + stuff->nStops); + + pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2, + stuff->nStops, stops, colors, &error); + if (!pPicture) + return error; + /* security creation/labeling check */ + error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, + pPicture, RT_NONE, NULL, DixCreateAccess); + if (error != Success) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + +static int ProcRenderCreateRadialGradient (ClientPtr client) +{ + PicturePtr pPicture; + int len; + int error = 0; + xFixed *stops; + xRenderColor *colors; + REQUEST(xRenderCreateRadialGradientReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + + len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + stops = (xFixed *)(stuff + 1); + colors = (xRenderColor *)(stops + stuff->nStops); + + pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer, + stuff->inner_radius, stuff->outer_radius, + stuff->nStops, stops, colors, &error); + if (!pPicture) + return error; + /* security creation/labeling check */ + error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, + pPicture, RT_NONE, NULL, DixCreateAccess); + if (error != Success) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + +static int ProcRenderCreateConicalGradient (ClientPtr client) +{ + PicturePtr pPicture; + int len; + int error = 0; + xFixed *stops; + xRenderColor *colors; + REQUEST(xRenderCreateConicalGradientReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + + len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + stops = (xFixed *)(stuff + 1); + colors = (xRenderColor *)(stops + stuff->nStops); + + pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle, + stuff->nStops, stops, colors, &error); + if (!pPicture) + return error; + /* security creation/labeling check */ + error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, + pPicture, RT_NONE, NULL, DixCreateAccess); + if (error != Success) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + + +static int +ProcRenderDispatch (ClientPtr client) +{ + REQUEST(xReq); + + if (stuff->data < RenderNumberRequests) + return (*ProcRenderVector[stuff->data]) (client); + else + return BadRequest; +} + +static int +SProcRenderQueryVersion (ClientPtr client) +{ + register int n; + REQUEST(xRenderQueryVersionReq); + + swaps(&stuff->length, n); + swapl(&stuff->majorVersion, n); + swapl(&stuff->minorVersion, n); + return (*ProcRenderVector[stuff->renderReqType])(client); +} + +static int +SProcRenderQueryPictFormats (ClientPtr client) +{ + register int n; + REQUEST(xRenderQueryPictFormatsReq); + swaps(&stuff->length, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderQueryPictIndexValues (ClientPtr client) +{ + register int n; + REQUEST(xRenderQueryPictIndexValuesReq); + swaps(&stuff->length, n); + swapl(&stuff->format, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderQueryDithers (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderCreatePicture (ClientPtr client) +{ + register int n; + REQUEST(xRenderCreatePictureReq); + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->drawable, n); + swapl(&stuff->format, n); + swapl(&stuff->mask, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderChangePicture (ClientPtr client) +{ + register int n; + REQUEST(xRenderChangePictureReq); + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swapl(&stuff->mask, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderSetPictureClipRectangles (ClientPtr client) +{ + register int n; + REQUEST(xRenderSetPictureClipRectanglesReq); + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swaps(&stuff->xOrigin, n); + swaps(&stuff->yOrigin, n); + SwapRestS(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderFreePicture (ClientPtr client) +{ + register int n; + REQUEST(xRenderFreePictureReq); + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderComposite (ClientPtr client) +{ + register int n; + REQUEST(xRenderCompositeReq); + swaps(&stuff->length, n); + swapl(&stuff->src, n); + swapl(&stuff->mask, n); + swapl(&stuff->dst, n); + swaps(&stuff->xSrc, n); + swaps(&stuff->ySrc, n); + swaps(&stuff->xMask, n); + swaps(&stuff->yMask, n); + swaps(&stuff->xDst, n); + swaps(&stuff->yDst, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderScale (ClientPtr client) +{ + register int n; + REQUEST(xRenderScaleReq); + swaps(&stuff->length, n); + swapl(&stuff->src, n); + swapl(&stuff->dst, n); + swapl(&stuff->colorScale, n); + swapl(&stuff->alphaScale, n); + swaps(&stuff->xSrc, n); + swaps(&stuff->ySrc, n); + swaps(&stuff->xDst, n); + swaps(&stuff->yDst, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderTrapezoids (ClientPtr client) +{ + register int n; + REQUEST(xRenderTrapezoidsReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); + swaps (&stuff->length, n); + swapl (&stuff->src, n); + swapl (&stuff->dst, n); + swapl (&stuff->maskFormat, n); + swaps (&stuff->xSrc, n); + swaps (&stuff->ySrc, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderTriangles (ClientPtr client) +{ + register int n; + REQUEST(xRenderTrianglesReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); + swaps (&stuff->length, n); + swapl (&stuff->src, n); + swapl (&stuff->dst, n); + swapl (&stuff->maskFormat, n); + swaps (&stuff->xSrc, n); + swaps (&stuff->ySrc, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderTriStrip (ClientPtr client) +{ + register int n; + REQUEST(xRenderTriStripReq); + + REQUEST_AT_LEAST_SIZE(xRenderTriStripReq); + swaps (&stuff->length, n); + swapl (&stuff->src, n); + swapl (&stuff->dst, n); + swapl (&stuff->maskFormat, n); + swaps (&stuff->xSrc, n); + swaps (&stuff->ySrc, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderTriFan (ClientPtr client) +{ + register int n; + REQUEST(xRenderTriFanReq); + + REQUEST_AT_LEAST_SIZE(xRenderTriFanReq); + swaps (&stuff->length, n); + swapl (&stuff->src, n); + swapl (&stuff->dst, n); + swapl (&stuff->maskFormat, n); + swaps (&stuff->xSrc, n); + swaps (&stuff->ySrc, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderColorTrapezoids (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderColorTriangles (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderTransform (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderCreateGlyphSet (ClientPtr client) +{ + register int n; + REQUEST(xRenderCreateGlyphSetReq); + swaps(&stuff->length, n); + swapl(&stuff->gsid, n); + swapl(&stuff->format, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderReferenceGlyphSet (ClientPtr client) +{ + register int n; + REQUEST(xRenderReferenceGlyphSetReq); + swaps(&stuff->length, n); + swapl(&stuff->gsid, n); + swapl(&stuff->existing, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderFreeGlyphSet (ClientPtr client) +{ + register int n; + REQUEST(xRenderFreeGlyphSetReq); + swaps(&stuff->length, n); + swapl(&stuff->glyphset, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderAddGlyphs (ClientPtr client) +{ + register int n; + register int i; + CARD32 *gids; + void *end; + xGlyphInfo *gi; + REQUEST(xRenderAddGlyphsReq); + swaps(&stuff->length, n); + swapl(&stuff->glyphset, n); + swapl(&stuff->nglyphs, n); + if (stuff->nglyphs & 0xe0000000) + return BadLength; + end = (CARD8 *) stuff + (client->req_len << 2); + gids = (CARD32 *) (stuff + 1); + gi = (xGlyphInfo *) (gids + stuff->nglyphs); + if ((char *) end - (char *) (gids + stuff->nglyphs) < 0) + return BadLength; + if ((char *) end - (char *) (gi + stuff->nglyphs) < 0) + return BadLength; + for (i = 0; i < stuff->nglyphs; i++) + { + swapl (&gids[i], n); + swaps (&gi[i].width, n); + swaps (&gi[i].height, n); + swaps (&gi[i].x, n); + swaps (&gi[i].y, n); + swaps (&gi[i].xOff, n); + swaps (&gi[i].yOff, n); + } + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderAddGlyphsFromPicture (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderFreeGlyphs (ClientPtr client) +{ + register int n; + REQUEST(xRenderFreeGlyphsReq); + swaps(&stuff->length, n); + swapl(&stuff->glyphset, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCompositeGlyphs (ClientPtr client) +{ + register int n; + xGlyphElt *elt; + CARD8 *buffer; + CARD8 *end; + int space; + int i; + int size; + + REQUEST(xRenderCompositeGlyphsReq); + + switch (stuff->renderReqType) { + default: size = 1; break; + case X_RenderCompositeGlyphs16: size = 2; break; + case X_RenderCompositeGlyphs32: size = 4; break; + } + + swaps(&stuff->length, n); + swapl(&stuff->src, n); + swapl(&stuff->dst, n); + swapl(&stuff->maskFormat, n); + swapl(&stuff->glyphset, n); + swaps(&stuff->xSrc, n); + swaps(&stuff->ySrc, n); + buffer = (CARD8 *) (stuff + 1); + end = (CARD8 *) stuff + (client->req_len << 2); + while (buffer + sizeof (xGlyphElt) < end) + { + elt = (xGlyphElt *) buffer; + buffer += sizeof (xGlyphElt); + + swaps (&elt->deltax, n); + swaps (&elt->deltay, n); + + i = elt->len; + if (i == 0xff) + { + swapl (buffer, n); + buffer += 4; + } + else + { + space = size * i; + switch (size) { + case 1: + buffer += i; + break; + case 2: + while (i--) + { + swaps (buffer, n); + buffer += 2; + } + break; + case 4: + while (i--) + { + swapl (buffer, n); + buffer += 4; + } + break; + } + if (space & 3) + buffer += 4 - (space & 3); + } + } + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderFillRectangles (ClientPtr client) +{ + register int n; + REQUEST(xRenderFillRectanglesReq); + + REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq); + swaps(&stuff->length, n); + swapl(&stuff->dst, n); + swaps(&stuff->color.red, n); + swaps(&stuff->color.green, n); + swaps(&stuff->color.blue, n); + swaps(&stuff->color.alpha, n); + SwapRestS(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateCursor (ClientPtr client) +{ + register int n; + REQUEST(xRenderCreateCursorReq); + REQUEST_SIZE_MATCH (xRenderCreateCursorReq); + + swaps(&stuff->length, n); + swapl(&stuff->cid, n); + swapl(&stuff->src, n); + swaps(&stuff->x, n); + swaps(&stuff->y, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderSetPictureTransform (ClientPtr client) +{ + register int n; + REQUEST(xRenderSetPictureTransformReq); + REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); + + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swapl(&stuff->transform.matrix11, n); + swapl(&stuff->transform.matrix12, n); + swapl(&stuff->transform.matrix13, n); + swapl(&stuff->transform.matrix21, n); + swapl(&stuff->transform.matrix22, n); + swapl(&stuff->transform.matrix23, n); + swapl(&stuff->transform.matrix31, n); + swapl(&stuff->transform.matrix32, n); + swapl(&stuff->transform.matrix33, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderQueryFilters (ClientPtr client) +{ + register int n; + REQUEST (xRenderQueryFiltersReq); + REQUEST_SIZE_MATCH (xRenderQueryFiltersReq); + + swaps(&stuff->length, n); + swapl(&stuff->drawable, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderSetPictureFilter (ClientPtr client) +{ + register int n; + REQUEST (xRenderSetPictureFilterReq); + REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq); + + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swaps(&stuff->nbytes, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateAnimCursor (ClientPtr client) +{ + register int n; + REQUEST (xRenderCreateAnimCursorReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq); + + swaps(&stuff->length, n); + swapl(&stuff->cid, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderAddTraps (ClientPtr client) +{ + register int n; + REQUEST (xRenderAddTrapsReq); + REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq); + + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swaps(&stuff->xOff, n); + swaps(&stuff->yOff, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateSolidFill(ClientPtr client) +{ + register int n; + REQUEST (xRenderCreateSolidFillReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq); + + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swaps(&stuff->color.alpha, n); + swaps(&stuff->color.red, n); + swaps(&stuff->color.green, n); + swaps(&stuff->color.blue, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static void swapStops(void *stuff, int num) +{ + int i, n; + CARD32 *stops; + CARD16 *colors; + stops = (CARD32 *)(stuff); + for (i = 0; i < num; ++i) { + swapl(stops, n); + ++stops; + } + colors = (CARD16 *)(stops); + for (i = 0; i < 4*num; ++i) { + swaps(colors, n); + ++colors; + } +} + +static int +SProcRenderCreateLinearGradient (ClientPtr client) +{ + register int n; + int len; + REQUEST (xRenderCreateLinearGradientReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq); + + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->p1.x, n); + swapl(&stuff->p1.y, n); + swapl(&stuff->p2.x, n); + swapl(&stuff->p2.y, n); + swapl(&stuff->nStops, n); + + len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + swapStops(stuff+1, stuff->nStops); + + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateRadialGradient (ClientPtr client) +{ + register int n; + int len; + REQUEST (xRenderCreateRadialGradientReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq); + + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->inner.x, n); + swapl(&stuff->inner.y, n); + swapl(&stuff->outer.x, n); + swapl(&stuff->outer.y, n); + swapl(&stuff->inner_radius, n); + swapl(&stuff->outer_radius, n); + swapl(&stuff->nStops, n); + + len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + swapStops(stuff+1, stuff->nStops); + + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateConicalGradient (ClientPtr client) +{ + register int n; + int len; + REQUEST (xRenderCreateConicalGradientReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq); + + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->center.x, n); + swapl(&stuff->center.y, n); + swapl(&stuff->angle, n); + swapl(&stuff->nStops, n); + + len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + swapStops(stuff+1, stuff->nStops); + + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderDispatch (ClientPtr client) +{ + REQUEST(xReq); + + if (stuff->data < RenderNumberRequests) + return (*SProcRenderVector[stuff->data]) (client); + else + return BadRequest; +} + +#ifdef PANORAMIX +#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\ + int rc = dixLookupResourceByType((pointer *)&(pPicture), pid,\ + XRT_PICTURE, client, mode);\ + if (rc != Success)\ + return rc;\ +} + +#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\ + if (pid == None) \ + pPicture = 0; \ + else { \ + VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \ + } \ +} \ + +int (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr); + +static int +PanoramiXRenderCreatePicture (ClientPtr client) +{ + REQUEST(xRenderCreatePictureReq); + PanoramiXRes *refDraw, *newPict; + int result, j; + + REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); + result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + newPict->type = XRT_PICTURE; + panoramix_setup_ids(newPict, client, stuff->pid); + + if (refDraw->type == XRT_WINDOW && + stuff->drawable == screenInfo.screens[0]->root->drawable.id) + { + newPict->u.pict.root = TRUE; + } + else + newPict->u.pict.root = FALSE; + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPict->info[j].id; + stuff->drawable = refDraw->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPict->info[0].id, XRT_PICTURE, newPict); + else + free(newPict); + + return result; +} + +static int +PanoramiXRenderChangePicture (ClientPtr client) +{ + PanoramiXRes *pict; + int result = Success, j; + REQUEST(xRenderChangePictureReq); + + REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client); + if(result != Success) break; + } + + return result; +} + +static int +PanoramiXRenderSetPictureClipRectangles (ClientPtr client) +{ + REQUEST(xRenderSetPictureClipRectanglesReq); + int result = Success, j; + PanoramiXRes *pict; + + REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client); + if(result != Success) break; + } + + return result; +} + +static int +PanoramiXRenderSetPictureTransform (ClientPtr client) +{ + REQUEST(xRenderSetPictureTransformReq); + int result = Success, j; + PanoramiXRes *pict; + + REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq); + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client); + if(result != Success) break; + } + + return result; +} + +static int +PanoramiXRenderSetPictureFilter (ClientPtr client) +{ + REQUEST(xRenderSetPictureFilterReq); + int result = Success, j; + PanoramiXRes *pict; + + REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client); + if(result != Success) break; + } + + return result; +} + +static int +PanoramiXRenderFreePicture (ClientPtr client) +{ + PanoramiXRes *pict; + int result = Success, j; + REQUEST(xRenderFreePictureReq); + + REQUEST_SIZE_MATCH(xRenderFreePictureReq); + + client->errorValue = stuff->picture; + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess); + + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client); + if(result != Success) break; + } + + /* Since ProcRenderFreePicture is using FreeResource, it will free + our resource for us on the last pass through the loop above */ + + return result; +} + +static int +PanoramiXRenderComposite (ClientPtr client) +{ + PanoramiXRes *src, *msk, *dst; + int result = Success, j; + xRenderCompositeReq orig; + REQUEST(xRenderCompositeReq); + + REQUEST_SIZE_MATCH(xRenderCompositeReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); + VERIFY_XIN_ALPHA (msk, stuff->mask, client, DixReadAccess); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + + orig = *stuff; + + FOR_NSCREENS_FORWARD(j) { + stuff->src = src->info[j].id; + if (src->u.pict.root) + { + stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x; + stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y; + } + stuff->dst = dst->info[j].id; + if (dst->u.pict.root) + { + stuff->xDst = orig.xDst - screenInfo.screens[j]->x; + stuff->yDst = orig.yDst - screenInfo.screens[j]->y; + } + if (msk) + { + stuff->mask = msk->info[j].id; + if (msk->u.pict.root) + { + stuff->xMask = orig.xMask - screenInfo.screens[j]->x; + stuff->yMask = orig.yMask - screenInfo.screens[j]->y; + } + } + result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client); + if(result != Success) break; + } + + return result; +} + +static int +PanoramiXRenderCompositeGlyphs (ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderCompositeGlyphsReq); + xGlyphElt origElt, *elt; + INT16 xSrc, ySrc; + + REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + + if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) + + sizeof (xGlyphElt))) + { + elt = (xGlyphElt *) (stuff + 1); + origElt = *elt; + xSrc = stuff->xSrc; + ySrc = stuff->ySrc; + FOR_NSCREENS_FORWARD(j) { + stuff->src = src->info[j].id; + if (src->u.pict.root) + { + stuff->xSrc = xSrc - screenInfo.screens[j]->x; + stuff->ySrc = ySrc - screenInfo.screens[j]->y; + } + stuff->dst = dst->info[j].id; + if (dst->u.pict.root) + { + elt->deltax = origElt.deltax - screenInfo.screens[j]->x; + elt->deltay = origElt.deltay - screenInfo.screens[j]->y; + } + result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client); + if(result != Success) break; + } + } + + return result; +} + +static int +PanoramiXRenderFillRectangles (ClientPtr client) +{ + PanoramiXRes *dst; + int result = Success, j; + REQUEST(xRenderFillRectanglesReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq); + if (extra_len && + (extra = (char *) malloc(extra_len))) + { + memcpy (extra, stuff + 1, extra_len); + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) + { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xRectangle *rects = (xRectangle *) (stuff + 1); + int i = extra_len / sizeof (xRectangle); + + while (i--) + { + rects->x -= x_off; + rects->y -= y_off; + rects++; + } + } + } + stuff->dst = dst->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client); + if(result != Success) break; + } + free(extra); + } + + return result; +} + +static int +PanoramiXRenderTrapezoids(ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderTrapezoidsReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + + extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq); + + if (extra_len && + (extra = (char *) malloc(extra_len))) { + memcpy (extra, stuff + 1, extra_len); + + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xTrapezoid *trap = (xTrapezoid *) (stuff + 1); + int i = extra_len / sizeof (xTrapezoid); + + while (i--) { + trap->top -= y_off; + trap->bottom -= y_off; + trap->left.p1.x -= x_off; + trap->left.p1.y -= y_off; + trap->left.p2.x -= x_off; + trap->left.p2.y -= y_off; + trap->right.p1.x -= x_off; + trap->right.p1.y -= y_off; + trap->right.p2.x -= x_off; + trap->right.p2.y -= y_off; + trap++; + } + } + } + + stuff->src = src->info[j].id; + stuff->dst = dst->info[j].id; + result = + (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client); + + if(result != Success) break; + } + + free(extra); + } + + return result; +} + +static int +PanoramiXRenderTriangles(ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderTrianglesReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + + extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq); + + if (extra_len && + (extra = (char *) malloc(extra_len))) { + memcpy (extra, stuff + 1, extra_len); + + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xTriangle *tri = (xTriangle *) (stuff + 1); + int i = extra_len / sizeof (xTriangle); + + while (i--) { + tri->p1.x -= x_off; + tri->p1.y -= y_off; + tri->p2.x -= x_off; + tri->p2.y -= y_off; + tri->p3.x -= x_off; + tri->p3.y -= y_off; + tri++; + } + } + } + + stuff->src = src->info[j].id; + stuff->dst = dst->info[j].id; + result = + (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client); + + if(result != Success) break; + } + + free(extra); + } + + return result; +} + +static int +PanoramiXRenderTriStrip(ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderTriStripReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderTriStripReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + + extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq); + + if (extra_len && + (extra = (char *) malloc(extra_len))) { + memcpy (extra, stuff + 1, extra_len); + + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xPointFixed *fixed = (xPointFixed *) (stuff + 1); + int i = extra_len / sizeof (xPointFixed); + + while (i--) { + fixed->x -= x_off; + fixed->y -= y_off; + fixed++; + } + } + } + + stuff->src = src->info[j].id; + stuff->dst = dst->info[j].id; + result = + (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client); + + if(result != Success) break; + } + + free(extra); + } + + return result; +} + +static int +PanoramiXRenderTriFan(ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderTriFanReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderTriFanReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + + extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq); + + if (extra_len && + (extra = (char *) malloc(extra_len))) { + memcpy (extra, stuff + 1, extra_len); + + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xPointFixed *fixed = (xPointFixed *) (stuff + 1); + int i = extra_len / sizeof (xPointFixed); + + while (i--) { + fixed->x -= x_off; + fixed->y -= y_off; + fixed++; + } + } + } + + stuff->src = src->info[j].id; + stuff->dst = dst->info[j].id; + result = + (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client); + + if(result != Success) break; + } + + free(extra); + } + + return result; +} + +static int +PanoramiXRenderAddTraps (ClientPtr client) +{ + PanoramiXRes *picture; + int result = Success, j; + REQUEST(xRenderAddTrapsReq); + char *extra; + int extra_len; + INT16 x_off, y_off; + + REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq); + VERIFY_XIN_PICTURE (picture, stuff->picture, client, DixWriteAccess); + extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq); + if (extra_len && + (extra = (char *) malloc(extra_len))) + { + memcpy (extra, stuff + 1, extra_len); + x_off = stuff->xOff; + y_off = stuff->yOff; + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + stuff->picture = picture->info[j].id; + + if (picture->u.pict.root) + { + stuff->xOff = x_off + screenInfo.screens[j]->x; + stuff->yOff = y_off + screenInfo.screens[j]->y; + } + result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client); + if(result != Success) break; + } + free(extra); + } + + return result; +} + +static int +PanoramiXRenderCreateSolidFill (ClientPtr client) +{ + REQUEST(xRenderCreateSolidFillReq); + PanoramiXRes *newPict; + int result = Success, j; + + REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); + + if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPict->type = XRT_PICTURE; + panoramix_setup_ids(newPict, client, stuff->pid); + newPict->u.pict.root = FALSE; + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPict->info[0].id, XRT_PICTURE, newPict); + else + free(newPict); + + return result; +} + +static int +PanoramiXRenderCreateLinearGradient (ClientPtr client) +{ + REQUEST(xRenderCreateLinearGradientReq); + PanoramiXRes *newPict; + int result = Success, j; + + REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); + + if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPict->type = XRT_PICTURE; + panoramix_setup_ids(newPict, client, stuff->pid); + newPict->u.pict.root = FALSE; + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPict->info[0].id, XRT_PICTURE, newPict); + else + free(newPict); + + return result; +} + +static int +PanoramiXRenderCreateRadialGradient (ClientPtr client) +{ + REQUEST(xRenderCreateRadialGradientReq); + PanoramiXRes *newPict; + int result = Success, j; + + REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); + + if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPict->type = XRT_PICTURE; + panoramix_setup_ids(newPict, client, stuff->pid); + newPict->u.pict.root = FALSE; + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPict->info[0].id, XRT_PICTURE, newPict); + else + free(newPict); + + return result; +} + +static int +PanoramiXRenderCreateConicalGradient (ClientPtr client) +{ + REQUEST(xRenderCreateConicalGradientReq); + PanoramiXRes *newPict; + int result = Success, j; + + REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); + + if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPict->type = XRT_PICTURE; + panoramix_setup_ids(newPict, client, stuff->pid); + newPict->u.pict.root = FALSE; + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient]) (client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPict->info[0].id, XRT_PICTURE, newPict); + else + free(newPict); + + return result; +} + +void +PanoramiXRenderInit (void) +{ + int i; + + XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource, + "XineramaPicture"); + if (RenderErrBase) + SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture); + for (i = 0; i < RenderNumberRequests; i++) + PanoramiXSaveRenderVector[i] = ProcRenderVector[i]; + /* + * Stuff in Xinerama aware request processing hooks + */ + ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture; + ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture; + ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform; + ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter; + ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles; + ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture; + ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite; + ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs; + ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs; + ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs; + ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles; + + ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids; + ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles; + ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip; + ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan; + ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps; + + ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill; + ProcRenderVector[X_RenderCreateLinearGradient] = PanoramiXRenderCreateLinearGradient; + ProcRenderVector[X_RenderCreateRadialGradient] = PanoramiXRenderCreateRadialGradient; + ProcRenderVector[X_RenderCreateConicalGradient] = PanoramiXRenderCreateConicalGradient; +} + +void +PanoramiXRenderReset (void) +{ + int i; + for (i = 0; i < RenderNumberRequests; i++) + ProcRenderVector[i] = PanoramiXSaveRenderVector[i]; + RenderErrBase = 0; +} + +#endif /* PANORAMIX */ |