1626 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1626 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 *
 | 
						|
 * Copyright © 2000 SuSE, Inc.
 | 
						|
 *
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
 * documentation for any purpose is hereby granted without fee, provided that
 | 
						|
 * the above copyright notice appear in all copies and that both that
 | 
						|
 * copyright notice and this permission notice appear in supporting
 | 
						|
 * documentation, and that the name of SuSE not be used in advertising or
 | 
						|
 * publicity pertaining to distribution of the software without specific,
 | 
						|
 * written prior permission.  SuSE makes no representations about the
 | 
						|
 * suitability of this software for any purpose.  It is provided "as is"
 | 
						|
 * without express or implied warranty.
 | 
						|
 *
 | 
						|
 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 | 
						|
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
 | 
						|
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
						|
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | 
						|
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
						|
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 *
 | 
						|
 * Author:  Keith Packard, SuSE, Inc.
 | 
						|
 */
 | 
						|
 | 
						|
#include <dix-config.h>
 | 
						|
 | 
						|
#include "dix/colormap_priv.h"
 | 
						|
#include "os/osdep.h"
 | 
						|
 | 
						|
#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_priv.h"
 | 
						|
#include "glyphstr_priv.h"
 | 
						|
#include "xace.h"
 | 
						|
#ifdef PANORAMIX
 | 
						|
#include "panoramiXsrv.h"
 | 
						|
#endif
 | 
						|
 | 
						|
DevPrivateKeyRec PictureScreenPrivateKeyRec;
 | 
						|
DevPrivateKeyRec PictureWindowPrivateKeyRec;
 | 
						|
static int PictureGeneration;
 | 
						|
RESTYPE PictureType;
 | 
						|
RESTYPE PictFormatType;
 | 
						|
RESTYPE GlyphSetType;
 | 
						|
int PictureCmapPolicy = PictureCmapPolicyDefault;
 | 
						|
 | 
						|
PictFormatPtr
 | 
						|
PictureWindowFormat(WindowPtr pWindow)
 | 
						|
{
 | 
						|
    ScreenPtr pScreen = pWindow->drawable.pScreen;
 | 
						|
    return PictureMatchVisual(pScreen, pWindow->drawable.depth,
 | 
						|
                              WindowGetVisual(pWindow));
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
picture_window_destructor(ScreenPtr pScreen, WindowPtr pWindow, void *arg)
 | 
						|
{
 | 
						|
    PicturePtr pPicture;
 | 
						|
 | 
						|
    while ((pPicture = GetPictureWindow(pWindow))) {
 | 
						|
        SetPictureWindow(pWindow, pPicture->pNext);
 | 
						|
        if (pPicture->id)
 | 
						|
            FreeResource(pPicture->id, PictureType);
 | 
						|
        FreePicture((void *) pPicture, pPicture->id);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void PictureScreenClose(ScreenPtr pScreen, void *arg)
 | 
						|
{
 | 
						|
    PictureScreenPtr ps = GetPictureScreen(pScreen);
 | 
						|
    int n;
 | 
						|
 | 
						|
    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);
 | 
						|
}
 | 
						|
 | 
						|
static 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 void
 | 
						|
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;
 | 
						|
    formats[*nformat].format = format;
 | 
						|
    formats[*nformat].depth = depth;
 | 
						|
    ++*nformat;
 | 
						|
}
 | 
						|
 | 
						|
#define Mask(n) ((1 << (n)) - 1)
 | 
						|
 | 
						|
static PictFormatPtr
 | 
						|
PictureCreateDefaultFormats(ScreenPtr pScreen, int *nformatp)
 | 
						|
{
 | 
						|
    int nformats = 0, 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_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);
 | 
						|
                addFormat(formats, &nformats, format, depth);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        case StaticColor:
 | 
						|
        case PseudoColor:
 | 
						|
            format = PICT_VISFORMAT(bpp, PICT_TYPE_COLOR, v);
 | 
						|
            addFormat(formats, &nformats, format, depth);
 | 
						|
            break;
 | 
						|
        case StaticGray:
 | 
						|
        case GrayScale:
 | 
						|
            format = PICT_VISFORMAT(bpp, PICT_TYPE_GRAY, v);
 | 
						|
            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) {
 | 
						|
                addFormat(formats, &nformats, PICT_x4r4g4b4, pDepth->depth);
 | 
						|
                addFormat(formats, &nformats, PICT_x4b4g4r4, pDepth->depth);
 | 
						|
            }
 | 
						|
            /* depth 15 formats */
 | 
						|
            if (pDepth->depth >= 15) {
 | 
						|
                addFormat(formats, &nformats, PICT_x1r5g5b5, pDepth->depth);
 | 
						|
                addFormat(formats, &nformats, PICT_x1b5g5r5, pDepth->depth);
 | 
						|
            }
 | 
						|
            /* depth 16 formats */
 | 
						|
            if (pDepth->depth >= 16) {
 | 
						|
                addFormat(formats, &nformats, PICT_a1r5g5b5, pDepth->depth);
 | 
						|
                addFormat(formats, &nformats, PICT_a1b5g5r5, pDepth->depth);
 | 
						|
                addFormat(formats, &nformats, PICT_r5g6b5, pDepth->depth);
 | 
						|
                addFormat(formats, &nformats, PICT_b5g6r5, pDepth->depth);
 | 
						|
                addFormat(formats, &nformats, PICT_a4r4g4b4, pDepth->depth);
 | 
						|
                addFormat(formats, &nformats, PICT_a4b4g4r4, pDepth->depth);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        case 32:
 | 
						|
            if (pDepth->depth >= 24) {
 | 
						|
                addFormat(formats, &nformats, PICT_x8r8g8b8, pDepth->depth);
 | 
						|
                addFormat(formats, &nformats, PICT_x8b8g8r8, pDepth->depth);
 | 
						|
            }
 | 
						|
            if (pDepth->depth >= 30) {
 | 
						|
                addFormat(formats, &nformats, PICT_a2r10g10b10, pDepth->depth);
 | 
						|
                addFormat(formats, &nformats, PICT_x2r10g10b10, pDepth->depth);
 | 
						|
                addFormat(formats, &nformats, PICT_a2b10g10r10, pDepth->depth);
 | 
						|
                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;
 | 
						|
}
 | 
						|
 | 
						|
static 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((void **) &format->index.pColormap,
 | 
						|
                                pScreen->defColormap, X11_RESTYPE_COLORMAP,
 | 
						|
                                serverClient, DixGetAttrAccess);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        VisualPtr pVisual = PictureFindVisual(pScreen, format->index.vid);
 | 
						|
 | 
						|
        if (pVisual == NULL)
 | 
						|
            return FALSE;
 | 
						|
 | 
						|
        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 ((unsigned long)format->direct.redMask <<
 | 
						|
                        format->direct.red == pVisual->redMask &&
 | 
						|
                    (unsigned long)format->direct.greenMask <<
 | 
						|
                        format->direct.green == pVisual->greenMask &&
 | 
						|
                    (unsigned long)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;
 | 
						|
}
 | 
						|
 | 
						|
/** @see GetDefaultBytes */
 | 
						|
static void
 | 
						|
GetPictureBytes(void *value, XID id, ResourceSizePtr size)
 | 
						|
{
 | 
						|
    PicturePtr picture = value;
 | 
						|
 | 
						|
    /* Currently only pixmap bytes are reported to clients. */
 | 
						|
    size->resourceSize = 0;
 | 
						|
 | 
						|
    size->refCnt = picture->refcnt;
 | 
						|
 | 
						|
    /* Calculate pixmap reference sizes. */
 | 
						|
    size->pixmapRefSize = 0;
 | 
						|
    if (picture->pDrawable && (picture->pDrawable->type == DRAWABLE_PIXMAP))
 | 
						|
    {
 | 
						|
        SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(X11_RESTYPE_PIXMAP);
 | 
						|
        ResourceSizeRec pixmapSize = { 0, 0, 0 };
 | 
						|
        PixmapPtr pixmap = (PixmapPtr)picture->pDrawable;
 | 
						|
        pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize);
 | 
						|
        size->pixmapRefSize += pixmapSize.pixmapRefSize;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
FreePictFormat(void *pPictFormat, XID pid)
 | 
						|
{
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
        SetResourceTypeSizeFunc(PictureType, GetPictureBytes);
 | 
						|
        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, (void *) (formats + n))) {
 | 
						|
            int i;
 | 
						|
            for (i = 0; i < n; i++)
 | 
						|
                FreeResource(formats[i].id, X11_RESTYPE_NONE);
 | 
						|
            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->StoreColors = pScreen->StoreColors;
 | 
						|
    pScreen->StoreColors = PictureStoreColors;
 | 
						|
 | 
						|
    dixScreenHookWindowDestroy(pScreen, picture_window_destructor, NULL);
 | 
						|
    dixScreenHookClose(pScreen, PictureScreenClose, NULL);
 | 
						|
 | 
						|
    if (!PictureSetDefaultFilters(pScreen)) {
 | 
						|
        PictureResetFilters(pScreen);
 | 
						|
        SetPictureScreen(pScreen, 0);
 | 
						|
        free(formats);
 | 
						|
        free(ps);
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static 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->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 = dixAllocateScreenObjectWithPrivates(pDrawable->pScreen,
 | 
						|
                                                   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 = XaceHookResourceAccess(client, pid, PictureType, pPicture,
 | 
						|
                      X11_RESTYPE_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
 | 
						|
        ((unsigned)c.alpha >> 8 << 24) |
 | 
						|
        ((unsigned)c.red >> 8 << 16) |
 | 
						|
        ((unsigned)c.green & 0xff00) |
 | 
						|
        ((unsigned)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 = xallocarray(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 = dixAllocateScreenObjectWithPrivates(NULL, PictureRec,
 | 
						|
                                                   PRIVATE_PICTURE);
 | 
						|
    if (!pPicture)
 | 
						|
	return 0;
 | 
						|
 | 
						|
    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(SourcePict));
 | 
						|
    if (!pPicture->pSourcePict) {
 | 
						|
        *error = BadAlloc;
 | 
						|
        free(pPicture);
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
    pPicture->pSourcePict->type = SourcePictTypeSolidFill;
 | 
						|
    pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
 | 
						|
    memcpy(&pPicture->pSourcePict->solidFill.fullcolor, color, sizeof(*color));
 | 
						|
    return pPicture;
 | 
						|
}
 | 
						|
 | 
						|
PicturePtr
 | 
						|
CreateLinearGradientPicture(Picture pid, xPointFixed * p1, xPointFixed * p2,
 | 
						|
                            int nStops, xFixed * stops, xRenderColor * colors,
 | 
						|
                            int *error)
 | 
						|
{
 | 
						|
    PicturePtr pPicture;
 | 
						|
 | 
						|
    if (nStops < 1) {
 | 
						|
        *error = BadValue;
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    pPicture = createSourcePicture();
 | 
						|
    if (!pPicture) {
 | 
						|
        *error = BadAlloc;
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    pPicture->id = pid;
 | 
						|
    pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(SourcePict));
 | 
						|
    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 < 1) {
 | 
						|
        *error = BadValue;
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    pPicture = createSourcePicture();
 | 
						|
    if (!pPicture) {
 | 
						|
        *error = BadAlloc;
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    pPicture->id = pid;
 | 
						|
    pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(SourcePict));
 | 
						|
    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 < 1) {
 | 
						|
        *error = BadValue;
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    pPicture = createSourcePicture();
 | 
						|
    if (!pPicture) {
 | 
						|
        *error = BadAlloc;
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    pPicture->id = pid;
 | 
						|
    pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(SourcePict));
 | 
						|
    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;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
cpAlphaMap(void **result, XID id, ScreenPtr screen, ClientPtr client, Mask mode)
 | 
						|
{
 | 
						|
#ifdef PANORAMIX
 | 
						|
    if (!noPanoramiXExtension) {
 | 
						|
        PanoramiXRes *res;
 | 
						|
        int err = dixLookupResourceByType((void **)&res, id, XRT_PICTURE,
 | 
						|
                                          client, mode);
 | 
						|
        if (err != Success)
 | 
						|
            return err;
 | 
						|
        id = res->info[screen->myNum].id;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    return dixLookupResourceByType(result, id, PictureType, client, mode);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
cpClipMask(void **result, XID id, ScreenPtr screen, ClientPtr client, Mask mode)
 | 
						|
{
 | 
						|
#ifdef PANORAMIX
 | 
						|
    if (!noPanoramiXExtension) {
 | 
						|
        PanoramiXRes *res;
 | 
						|
        int err = dixLookupResourceByType((void **)&res, id, XRT_PIXMAP,
 | 
						|
                                          client, mode);
 | 
						|
        if (err != Success)
 | 
						|
            return err;
 | 
						|
        id = res->info[screen->myNum].id;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    return dixLookupResourceByType(result, id, X11_RESTYPE_PIXMAP, client, mode);
 | 
						|
}
 | 
						|
 | 
						|
#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 = cpAlphaMap((void **) &pAlpha, pid, pScreen,
 | 
						|
                                       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((void *) 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 = cpClipMask((void **) &pPixmap, pid, pScreen,
 | 
						|
                                       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,
 | 
						|
                                              (void *) 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,
 | 
						|
                                       (void *) 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, (void *) 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;
 | 
						|
}
 | 
						|
 | 
						|
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(void *value, XID pid)
 | 
						|
{
 | 
						|
    PicturePtr pPicture = (PicturePtr) value;
 | 
						|
 | 
						|
    if (--pPicture->refcnt == 0) {
 | 
						|
        free(pPicture->transform);
 | 
						|
        free(pPicture->filter_params);
 | 
						|
 | 
						|
        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((void *) pPicture->alphaMap, (XID) 0);
 | 
						|
            (*ps->DestroyPicture) (pPicture);
 | 
						|
            (*ps->DestroyPictureClip) (pPicture);
 | 
						|
            if (pPicture->pDrawable->type == DRAWABLE_WINDOW) {
 | 
						|
                WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
 | 
						|
                PicturePtr *pPrev;
 | 
						|
 | 
						|
                for (pPrev = (PicturePtr *) dixLookupPrivateAddr
 | 
						|
                     (&pWindow->devPrivates, PictureWindowPrivateKey);
 | 
						|
                     *pPrev; pPrev = &(*pPrev)->pNext) {
 | 
						|
                    if (*pPrev == pPicture) {
 | 
						|
                        *pPrev = pPicture->pNext;
 | 
						|
                        break;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP) {
 | 
						|
                dixDestroyPixmap((PixmapPtr) pPicture->pDrawable, 0);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        dixFreeObjectWithPrivates(pPicture, PRIVATE_PICTURE);
 | 
						|
    }
 | 
						|
    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)
 | 
						|
{
 | 
						|
    PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
 | 
						|
 | 
						|
    if (npoints < 3)
 | 
						|
        return;
 | 
						|
 | 
						|
    ValidatePicture(pSrc);
 | 
						|
    ValidatePicture(pDst);
 | 
						|
    (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
CompositeTriFan(CARD8 op,
 | 
						|
                PicturePtr pSrc,
 | 
						|
                PicturePtr pDst,
 | 
						|
                PictFormatPtr maskFormat,
 | 
						|
                INT16 xSrc, INT16 ySrc, int npoints, xPointFixed * points)
 | 
						|
{
 | 
						|
    PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
 | 
						|
 | 
						|
    if (npoints < 3)
 | 
						|
        return;
 | 
						|
 | 
						|
    ValidatePicture(pSrc);
 | 
						|
    ValidatePicture(pDst);
 | 
						|
    (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
 | 
						|
}
 | 
						|
 | 
						|
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);
 | 
						|
}
 |