diff options
Diffstat (limited to 'xorg-server/render')
-rw-r--r-- | xorg-server/render/picture.c | 3618 | ||||
-rw-r--r-- | xorg-server/render/picturestr.h | 1344 |
2 files changed, 2428 insertions, 2534 deletions
diff --git a/xorg-server/render/picture.c b/xorg-server/render/picture.c index ee0f8dee5..5640c4d96 100644 --- a/xorg-server/render/picture.c +++ b/xorg-server/render/picture.c @@ -1,1838 +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) ((n) == 32 ? 0xffffffff : ((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 unsigned int premultiply(unsigned int x)
-{
- unsigned int a = x >> 24;
- unsigned int t = (x & 0xff00ff) * a + 0x800080;
- t = (t + ((t >> 8) & 0xff00ff)) >> 8;
- t &= 0xff00ff;
-
- x = ((x >> 8) & 0xff) * a + 0x80;
- x = (x + ((x >> 8) & 0xff));
- x &= 0xff00;
- x |= t | (a << 24);
- return x;
-}
-
-static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
- unsigned int y, unsigned int b)
-{
- CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
- t >>= 8;
- t &= 0xff00ff;
-
- x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
- x &= 0xff00ff00;
- x |= t;
- return x;
-}
-
-CARD32
-PictureGradientColor (PictGradientStopPtr stop1,
- PictGradientStopPtr stop2,
- CARD32 x)
-{
- CARD32 current_color, next_color;
- int dist, idist;
-
- current_color = xRenderColorToCard32 (stop1->color);
- next_color = xRenderColorToCard32 (stop2->color);
-
- dist = (int) (256 * (x - stop1->x) / (stop2->x - stop1->x));
- idist = 256 - dist;
-
- return premultiply (INTERPOLATE_PIXEL_256 (current_color, idist,
- next_color, dist));
-}
-
-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];
- }
-
- pGradient->gradient.class = SourcePictClassUnknown;
- pGradient->gradient.stopRange = 0xffff;
- pGradient->gradient.colorTable = NULL;
- pGradient->gradient.colorTableSize = 0;
-}
-
-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;
-}
-
-#define FixedToDouble(x) ((x)/65536.)
-
-PicturePtr
-CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer,
- xFixed innerRadius, xFixed outerRadius,
- int nStops, xFixed *stops, xRenderColor *colors, int *error)
-{
- PicturePtr pPicture;
- PictRadialGradient *radial;
-
- if (nStops < 2) {
- *error = BadValue;
- return 0;
- }
-
- pPicture = createSourcePicture();
- if (!pPicture) {
- *error = BadAlloc;
- return 0;
- }
-
- 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;
- radial->cdx = (radial->c2.x - radial->c1.x) / 65536.;
- radial->cdy = (radial->c2.y - radial->c1.y) / 65536.;
- radial->dr = (radial->c2.radius - radial->c1.radius) / 65536.;
- radial->A = ( radial->cdx * radial->cdx
- + radial->cdy * radial->cdy
- - radial->dr * radial->dr);
-
- 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 f642bf0df..7b7f9112d 100644 --- a/xorg-server/render/picturestr.h +++ b/xorg-server/render/picturestr.h @@ -1,696 +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
-
-#define SourcePictClassUnknown 0
-#define SourcePictClassHorizontal 1
-#define SourcePictClassVertical 2
-
-typedef struct _PictSolidFill {
- unsigned int type;
- unsigned int class;
- CARD32 color;
-} PictSolidFill, *PictSolidFillPtr;
-
-typedef struct _PictGradientStop {
- xFixed x;
- xRenderColor color;
-} PictGradientStop, *PictGradientStopPtr;
-
-typedef struct _PictGradient {
- unsigned int type;
- unsigned int class;
- int nstops;
- PictGradientStopPtr stops;
- int stopRange;
- CARD32 *colorTable;
- int colorTableSize;
-} PictGradient, *PictGradientPtr;
-
-typedef struct _PictLinearGradient {
- unsigned int type;
- unsigned int class;
- int nstops;
- PictGradientStopPtr stops;
- int stopRange;
- CARD32 *colorTable;
- int colorTableSize;
- xPointFixed p1;
- xPointFixed p2;
-} PictLinearGradient, *PictLinearGradientPtr;
-
-typedef struct _PictCircle {
- xFixed x;
- xFixed y;
- xFixed radius;
-} PictCircle, *PictCirclePtr;
-
-typedef struct _PictRadialGradient {
- unsigned int type;
- unsigned int class;
- int nstops;
- PictGradientStopPtr stops;
- int stopRange;
- CARD32 *colorTable;
- int colorTableSize;
- PictCircle c1;
- PictCircle c2;
- double cdx;
- double cdy;
- double dr;
- double A;
-} PictRadialGradient, *PictRadialGradientPtr;
-
-typedef struct _PictConicalGradient {
- unsigned int type;
- unsigned int class;
- int nstops;
- PictGradientStopPtr stops;
- int stopRange;
- CARD32 *colorTable;
- int colorTableSize;
- 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 void (*TriStripProcPtr) (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int npoint,
- xPointFixed *points);
-
-typedef void (*TriFanProcPtr) (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int npoint,
- xPointFixed *points);
-
-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 CARD32
-PictureGradientColor (PictGradientStopPtr stop1,
- PictGradientStopPtr stop2,
- CARD32 x);
-
-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_ */ |