render.c revision 9ace9065
105b261ecSmrg/*
205b261ecSmrg *
305b261ecSmrg * Copyright © 2000 SuSE, Inc.
405b261ecSmrg *
505b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its
605b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that
705b261ecSmrg * the above copyright notice appear in all copies and that both that
805b261ecSmrg * copyright notice and this permission notice appear in supporting
905b261ecSmrg * documentation, and that the name of SuSE not be used in advertising or
1005b261ecSmrg * publicity pertaining to distribution of the software without specific,
1105b261ecSmrg * written prior permission.  SuSE makes no representations about the
1205b261ecSmrg * suitability of this software for any purpose.  It is provided "as is"
1305b261ecSmrg * without express or implied warranty.
1405b261ecSmrg *
1505b261ecSmrg * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
1605b261ecSmrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
1705b261ecSmrg * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1805b261ecSmrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
1905b261ecSmrg * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
2005b261ecSmrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2105b261ecSmrg *
2205b261ecSmrg * Author:  Keith Packard, SuSE, Inc.
2305b261ecSmrg */
2405b261ecSmrg
2505b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
2605b261ecSmrg#include <dix-config.h>
2705b261ecSmrg#endif
2805b261ecSmrg
2905b261ecSmrg#include <X11/X.h>
3005b261ecSmrg#include <X11/Xproto.h>
3105b261ecSmrg#include "misc.h"
3205b261ecSmrg#include "os.h"
3305b261ecSmrg#include "dixstruct.h"
3405b261ecSmrg#include "resource.h"
3505b261ecSmrg#include "scrnintstr.h"
3605b261ecSmrg#include "windowstr.h"
3705b261ecSmrg#include "pixmapstr.h"
3805b261ecSmrg#include "colormapst.h"
3905b261ecSmrg#include "extnsionst.h"
4005b261ecSmrg#include "servermd.h"
4105b261ecSmrg#include <X11/extensions/render.h>
4205b261ecSmrg#include <X11/extensions/renderproto.h>
4305b261ecSmrg#include "picturestr.h"
4405b261ecSmrg#include "glyphstr.h"
4505b261ecSmrg#include <X11/Xfuncproto.h>
4605b261ecSmrg#include "cursorstr.h"
474642e01fSmrg#include "xace.h"
486747b715Smrg#include "protocol-versions.h"
4905b261ecSmrg
509ace9065Smrg#ifdef PANORAMIX
519ace9065Smrg#include "panoramiX.h"
529ace9065Smrg#include "panoramiXsrv.h"
539ace9065Smrg#endif
549ace9065Smrg
5505b261ecSmrg#if HAVE_STDINT_H
5605b261ecSmrg#include <stdint.h>
5705b261ecSmrg#elif !defined(UINT32_MAX)
5805b261ecSmrg#define UINT32_MAX 0xffffffffU
5905b261ecSmrg#endif
6005b261ecSmrg
6105b261ecSmrgstatic int ProcRenderQueryVersion (ClientPtr pClient);
6205b261ecSmrgstatic int ProcRenderQueryPictFormats (ClientPtr pClient);
6305b261ecSmrgstatic int ProcRenderQueryPictIndexValues (ClientPtr pClient);
6405b261ecSmrgstatic int ProcRenderQueryDithers (ClientPtr pClient);
6505b261ecSmrgstatic int ProcRenderCreatePicture (ClientPtr pClient);
6605b261ecSmrgstatic int ProcRenderChangePicture (ClientPtr pClient);
6705b261ecSmrgstatic int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
6805b261ecSmrgstatic int ProcRenderFreePicture (ClientPtr pClient);
6905b261ecSmrgstatic int ProcRenderComposite (ClientPtr pClient);
7005b261ecSmrgstatic int ProcRenderScale (ClientPtr pClient);
7105b261ecSmrgstatic int ProcRenderTrapezoids (ClientPtr pClient);
7205b261ecSmrgstatic int ProcRenderTriangles (ClientPtr pClient);
7305b261ecSmrgstatic int ProcRenderTriStrip (ClientPtr pClient);
7405b261ecSmrgstatic int ProcRenderTriFan (ClientPtr pClient);
7505b261ecSmrgstatic int ProcRenderColorTrapezoids (ClientPtr pClient);
7605b261ecSmrgstatic int ProcRenderColorTriangles (ClientPtr pClient);
7705b261ecSmrgstatic int ProcRenderTransform (ClientPtr pClient);
7805b261ecSmrgstatic int ProcRenderCreateGlyphSet (ClientPtr pClient);
7905b261ecSmrgstatic int ProcRenderReferenceGlyphSet (ClientPtr pClient);
8005b261ecSmrgstatic int ProcRenderFreeGlyphSet (ClientPtr pClient);
8105b261ecSmrgstatic int ProcRenderAddGlyphs (ClientPtr pClient);
8205b261ecSmrgstatic int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
8305b261ecSmrgstatic int ProcRenderFreeGlyphs (ClientPtr pClient);
8405b261ecSmrgstatic int ProcRenderCompositeGlyphs (ClientPtr pClient);
8505b261ecSmrgstatic int ProcRenderFillRectangles (ClientPtr pClient);
8605b261ecSmrgstatic int ProcRenderCreateCursor (ClientPtr pClient);
8705b261ecSmrgstatic int ProcRenderSetPictureTransform (ClientPtr pClient);
8805b261ecSmrgstatic int ProcRenderQueryFilters (ClientPtr pClient);
8905b261ecSmrgstatic int ProcRenderSetPictureFilter (ClientPtr pClient);
9005b261ecSmrgstatic int ProcRenderCreateAnimCursor (ClientPtr pClient);
9105b261ecSmrgstatic int ProcRenderAddTraps (ClientPtr pClient);
9205b261ecSmrgstatic int ProcRenderCreateSolidFill (ClientPtr pClient);
9305b261ecSmrgstatic int ProcRenderCreateLinearGradient (ClientPtr pClient);
9405b261ecSmrgstatic int ProcRenderCreateRadialGradient (ClientPtr pClient);
9505b261ecSmrgstatic int ProcRenderCreateConicalGradient (ClientPtr pClient);
9605b261ecSmrg
9705b261ecSmrgstatic int ProcRenderDispatch (ClientPtr pClient);
9805b261ecSmrg
9905b261ecSmrgstatic int SProcRenderQueryVersion (ClientPtr pClient);
10005b261ecSmrgstatic int SProcRenderQueryPictFormats (ClientPtr pClient);
10105b261ecSmrgstatic int SProcRenderQueryPictIndexValues (ClientPtr pClient);
10205b261ecSmrgstatic int SProcRenderQueryDithers (ClientPtr pClient);
10305b261ecSmrgstatic int SProcRenderCreatePicture (ClientPtr pClient);
10405b261ecSmrgstatic int SProcRenderChangePicture (ClientPtr pClient);
10505b261ecSmrgstatic int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
10605b261ecSmrgstatic int SProcRenderFreePicture (ClientPtr pClient);
10705b261ecSmrgstatic int SProcRenderComposite (ClientPtr pClient);
10805b261ecSmrgstatic int SProcRenderScale (ClientPtr pClient);
10905b261ecSmrgstatic int SProcRenderTrapezoids (ClientPtr pClient);
11005b261ecSmrgstatic int SProcRenderTriangles (ClientPtr pClient);
11105b261ecSmrgstatic int SProcRenderTriStrip (ClientPtr pClient);
11205b261ecSmrgstatic int SProcRenderTriFan (ClientPtr pClient);
11305b261ecSmrgstatic int SProcRenderColorTrapezoids (ClientPtr pClient);
11405b261ecSmrgstatic int SProcRenderColorTriangles (ClientPtr pClient);
11505b261ecSmrgstatic int SProcRenderTransform (ClientPtr pClient);
11605b261ecSmrgstatic int SProcRenderCreateGlyphSet (ClientPtr pClient);
11705b261ecSmrgstatic int SProcRenderReferenceGlyphSet (ClientPtr pClient);
11805b261ecSmrgstatic int SProcRenderFreeGlyphSet (ClientPtr pClient);
11905b261ecSmrgstatic int SProcRenderAddGlyphs (ClientPtr pClient);
12005b261ecSmrgstatic int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
12105b261ecSmrgstatic int SProcRenderFreeGlyphs (ClientPtr pClient);
12205b261ecSmrgstatic int SProcRenderCompositeGlyphs (ClientPtr pClient);
12305b261ecSmrgstatic int SProcRenderFillRectangles (ClientPtr pClient);
12405b261ecSmrgstatic int SProcRenderCreateCursor (ClientPtr pClient);
12505b261ecSmrgstatic int SProcRenderSetPictureTransform (ClientPtr pClient);
12605b261ecSmrgstatic int SProcRenderQueryFilters (ClientPtr pClient);
12705b261ecSmrgstatic int SProcRenderSetPictureFilter (ClientPtr pClient);
12805b261ecSmrgstatic int SProcRenderCreateAnimCursor (ClientPtr pClient);
12905b261ecSmrgstatic int SProcRenderAddTraps (ClientPtr pClient);
13005b261ecSmrgstatic int SProcRenderCreateSolidFill (ClientPtr pClient);
13105b261ecSmrgstatic int SProcRenderCreateLinearGradient (ClientPtr pClient);
13205b261ecSmrgstatic int SProcRenderCreateRadialGradient (ClientPtr pClient);
13305b261ecSmrgstatic int SProcRenderCreateConicalGradient (ClientPtr pClient);
13405b261ecSmrg
13505b261ecSmrgstatic int SProcRenderDispatch (ClientPtr pClient);
13605b261ecSmrg
13705b261ecSmrgint	(*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
13805b261ecSmrg    ProcRenderQueryVersion,
13905b261ecSmrg    ProcRenderQueryPictFormats,
14005b261ecSmrg    ProcRenderQueryPictIndexValues,
14105b261ecSmrg    ProcRenderQueryDithers,
14205b261ecSmrg    ProcRenderCreatePicture,
14305b261ecSmrg    ProcRenderChangePicture,
14405b261ecSmrg    ProcRenderSetPictureClipRectangles,
14505b261ecSmrg    ProcRenderFreePicture,
14605b261ecSmrg    ProcRenderComposite,
14705b261ecSmrg    ProcRenderScale,
14805b261ecSmrg    ProcRenderTrapezoids,
14905b261ecSmrg    ProcRenderTriangles,
15005b261ecSmrg    ProcRenderTriStrip,
15105b261ecSmrg    ProcRenderTriFan,
15205b261ecSmrg    ProcRenderColorTrapezoids,
15305b261ecSmrg    ProcRenderColorTriangles,
15405b261ecSmrg    ProcRenderTransform,
15505b261ecSmrg    ProcRenderCreateGlyphSet,
15605b261ecSmrg    ProcRenderReferenceGlyphSet,
15705b261ecSmrg    ProcRenderFreeGlyphSet,
15805b261ecSmrg    ProcRenderAddGlyphs,
15905b261ecSmrg    ProcRenderAddGlyphsFromPicture,
16005b261ecSmrg    ProcRenderFreeGlyphs,
16105b261ecSmrg    ProcRenderCompositeGlyphs,
16205b261ecSmrg    ProcRenderCompositeGlyphs,
16305b261ecSmrg    ProcRenderCompositeGlyphs,
16405b261ecSmrg    ProcRenderFillRectangles,
16505b261ecSmrg    ProcRenderCreateCursor,
16605b261ecSmrg    ProcRenderSetPictureTransform,
16705b261ecSmrg    ProcRenderQueryFilters,
16805b261ecSmrg    ProcRenderSetPictureFilter,
16905b261ecSmrg    ProcRenderCreateAnimCursor,
17005b261ecSmrg    ProcRenderAddTraps,
17105b261ecSmrg    ProcRenderCreateSolidFill,
17205b261ecSmrg    ProcRenderCreateLinearGradient,
17305b261ecSmrg    ProcRenderCreateRadialGradient,
17405b261ecSmrg    ProcRenderCreateConicalGradient
17505b261ecSmrg};
17605b261ecSmrg
17705b261ecSmrgint	(*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
17805b261ecSmrg    SProcRenderQueryVersion,
17905b261ecSmrg    SProcRenderQueryPictFormats,
18005b261ecSmrg    SProcRenderQueryPictIndexValues,
18105b261ecSmrg    SProcRenderQueryDithers,
18205b261ecSmrg    SProcRenderCreatePicture,
18305b261ecSmrg    SProcRenderChangePicture,
18405b261ecSmrg    SProcRenderSetPictureClipRectangles,
18505b261ecSmrg    SProcRenderFreePicture,
18605b261ecSmrg    SProcRenderComposite,
18705b261ecSmrg    SProcRenderScale,
18805b261ecSmrg    SProcRenderTrapezoids,
18905b261ecSmrg    SProcRenderTriangles,
19005b261ecSmrg    SProcRenderTriStrip,
19105b261ecSmrg    SProcRenderTriFan,
19205b261ecSmrg    SProcRenderColorTrapezoids,
19305b261ecSmrg    SProcRenderColorTriangles,
19405b261ecSmrg    SProcRenderTransform,
19505b261ecSmrg    SProcRenderCreateGlyphSet,
19605b261ecSmrg    SProcRenderReferenceGlyphSet,
19705b261ecSmrg    SProcRenderFreeGlyphSet,
19805b261ecSmrg    SProcRenderAddGlyphs,
19905b261ecSmrg    SProcRenderAddGlyphsFromPicture,
20005b261ecSmrg    SProcRenderFreeGlyphs,
20105b261ecSmrg    SProcRenderCompositeGlyphs,
20205b261ecSmrg    SProcRenderCompositeGlyphs,
20305b261ecSmrg    SProcRenderCompositeGlyphs,
20405b261ecSmrg    SProcRenderFillRectangles,
20505b261ecSmrg    SProcRenderCreateCursor,
20605b261ecSmrg    SProcRenderSetPictureTransform,
20705b261ecSmrg    SProcRenderQueryFilters,
20805b261ecSmrg    SProcRenderSetPictureFilter,
20905b261ecSmrg    SProcRenderCreateAnimCursor,
21005b261ecSmrg    SProcRenderAddTraps,
21105b261ecSmrg    SProcRenderCreateSolidFill,
21205b261ecSmrg    SProcRenderCreateLinearGradient,
21305b261ecSmrg    SProcRenderCreateRadialGradient,
21405b261ecSmrg    SProcRenderCreateConicalGradient
21505b261ecSmrg};
21605b261ecSmrg
21705b261ecSmrgint	RenderErrBase;
2186747b715Smrgstatic DevPrivateKeyRec RenderClientPrivateKeyRec;
2196747b715Smrg#define RenderClientPrivateKey (&RenderClientPrivateKeyRec )
22005b261ecSmrg
22105b261ecSmrgtypedef struct _RenderClient {
22205b261ecSmrg    int	    major_version;
22305b261ecSmrg    int	    minor_version;
22405b261ecSmrg} RenderClientRec, *RenderClientPtr;
22505b261ecSmrg
2264642e01fSmrg#define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey))
22705b261ecSmrg
22805b261ecSmrgstatic void
22905b261ecSmrgRenderClientCallback (CallbackListPtr	*list,
23005b261ecSmrg		      pointer		closure,
23105b261ecSmrg		      pointer		data)
23205b261ecSmrg{
23305b261ecSmrg    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
23405b261ecSmrg    ClientPtr		pClient = clientinfo->client;
23505b261ecSmrg    RenderClientPtr	pRenderClient = GetRenderClient (pClient);
23605b261ecSmrg
23705b261ecSmrg    pRenderClient->major_version = 0;
23805b261ecSmrg    pRenderClient->minor_version = 0;
23905b261ecSmrg}
24005b261ecSmrg
2416747b715Smrg#ifdef PANORAMIX
2426747b715Smrgunsigned long	XRT_PICTURE;
2436747b715Smrg#endif
2446747b715Smrg
24505b261ecSmrgvoid
24605b261ecSmrgRenderExtensionInit (void)
24705b261ecSmrg{
24805b261ecSmrg    ExtensionEntry *extEntry;
24905b261ecSmrg
25005b261ecSmrg    if (!PictureType)
25105b261ecSmrg	return;
25205b261ecSmrg    if (!PictureFinishInit ())
25305b261ecSmrg	return;
2546747b715Smrg    if (!dixRegisterPrivateKey(&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec)))
25505b261ecSmrg	return;
25605b261ecSmrg    if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
25705b261ecSmrg	return;
25805b261ecSmrg
25905b261ecSmrg    extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
26005b261ecSmrg			     ProcRenderDispatch, SProcRenderDispatch,
2614642e01fSmrg			     NULL, StandardMinorOpcode);
26205b261ecSmrg    if (!extEntry)
26305b261ecSmrg	return;
26405b261ecSmrg    RenderErrBase = extEntry->errorBase;
2656747b715Smrg#ifdef PANORAMIX
2666747b715Smrg    if (XRT_PICTURE)
2676747b715Smrg	SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
2686747b715Smrg#endif
2696747b715Smrg    SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture);
2706747b715Smrg    SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat);
2716747b715Smrg    SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet);
27205b261ecSmrg}
27305b261ecSmrg
27405b261ecSmrgstatic int
27505b261ecSmrgProcRenderQueryVersion (ClientPtr client)
27605b261ecSmrg{
27705b261ecSmrg    RenderClientPtr pRenderClient = GetRenderClient (client);
27805b261ecSmrg    xRenderQueryVersionReply rep;
27905b261ecSmrg    register int n;
28005b261ecSmrg    REQUEST(xRenderQueryVersionReq);
28105b261ecSmrg
28205b261ecSmrg    pRenderClient->major_version = stuff->majorVersion;
28305b261ecSmrg    pRenderClient->minor_version = stuff->minorVersion;
28405b261ecSmrg
28505b261ecSmrg    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
2866747b715Smrg    memset(&rep, 0, sizeof(xRenderQueryVersionReply));
28705b261ecSmrg    rep.type = X_Reply;
28805b261ecSmrg    rep.length = 0;
28905b261ecSmrg    rep.sequenceNumber = client->sequence;
2906747b715Smrg
2916747b715Smrg    if ((stuff->majorVersion * 1000 + stuff->minorVersion) <
2926747b715Smrg        (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION))
2936747b715Smrg    {
2946747b715Smrg	rep.majorVersion = stuff->majorVersion;
2956747b715Smrg	rep.minorVersion = stuff->minorVersion;
2966747b715Smrg    } else
2976747b715Smrg    {
2986747b715Smrg	rep.majorVersion = SERVER_RENDER_MAJOR_VERSION;
2996747b715Smrg	rep.minorVersion = SERVER_RENDER_MINOR_VERSION;
3006747b715Smrg    }
3016747b715Smrg
30205b261ecSmrg    if (client->swapped) {
30305b261ecSmrg    	swaps(&rep.sequenceNumber, n);
30405b261ecSmrg    	swapl(&rep.length, n);
30505b261ecSmrg	swapl(&rep.majorVersion, n);
30605b261ecSmrg	swapl(&rep.minorVersion, n);
30705b261ecSmrg    }
30805b261ecSmrg    WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
3096747b715Smrg    return Success;
31005b261ecSmrg}
31105b261ecSmrg
31205b261ecSmrgstatic VisualPtr
31305b261ecSmrgfindVisual (ScreenPtr pScreen, VisualID vid)
31405b261ecSmrg{
31505b261ecSmrg    VisualPtr	pVisual;
31605b261ecSmrg    int		v;
31705b261ecSmrg
31805b261ecSmrg    for (v = 0; v < pScreen->numVisuals; v++)
31905b261ecSmrg    {
32005b261ecSmrg	pVisual = pScreen->visuals + v;
32105b261ecSmrg	if (pVisual->vid == vid)
32205b261ecSmrg	    return pVisual;
32305b261ecSmrg    }
32405b261ecSmrg    return 0;
32505b261ecSmrg}
32605b261ecSmrg
32705b261ecSmrgstatic int
32805b261ecSmrgProcRenderQueryPictFormats (ClientPtr client)
32905b261ecSmrg{
33005b261ecSmrg    RenderClientPtr		    pRenderClient = GetRenderClient (client);
33105b261ecSmrg    xRenderQueryPictFormatsReply    *reply;
33205b261ecSmrg    xPictScreen			    *pictScreen;
33305b261ecSmrg    xPictDepth			    *pictDepth;
33405b261ecSmrg    xPictVisual			    *pictVisual;
33505b261ecSmrg    xPictFormInfo		    *pictForm;
33605b261ecSmrg    CARD32			    *pictSubpixel;
33705b261ecSmrg    ScreenPtr			    pScreen;
33805b261ecSmrg    VisualPtr			    pVisual;
33905b261ecSmrg    DepthPtr			    pDepth;
34005b261ecSmrg    int				    v, d;
34105b261ecSmrg    PictureScreenPtr		    ps;
34205b261ecSmrg    PictFormatPtr		    pFormat;
34305b261ecSmrg    int				    nformat;
34405b261ecSmrg    int				    ndepth;
34505b261ecSmrg    int				    nvisual;
34605b261ecSmrg    int				    rlength;
34705b261ecSmrg    int				    s;
34805b261ecSmrg    int				    n;
34905b261ecSmrg    int				    numScreens;
35005b261ecSmrg    int				    numSubpixel;
35105b261ecSmrg/*    REQUEST(xRenderQueryPictFormatsReq); */
35205b261ecSmrg
35305b261ecSmrg    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
35405b261ecSmrg
35505b261ecSmrg#ifdef PANORAMIX
35605b261ecSmrg    if (noPanoramiXExtension)
35705b261ecSmrg	numScreens = screenInfo.numScreens;
35805b261ecSmrg    else
35905b261ecSmrg        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
36005b261ecSmrg#else
36105b261ecSmrg    numScreens = screenInfo.numScreens;
36205b261ecSmrg#endif
36305b261ecSmrg    ndepth = nformat = nvisual = 0;
36405b261ecSmrg    for (s = 0; s < numScreens; s++)
36505b261ecSmrg    {
36605b261ecSmrg	pScreen = screenInfo.screens[s];
36705b261ecSmrg	for (d = 0; d < pScreen->numDepths; d++)
36805b261ecSmrg	{
36905b261ecSmrg	    pDepth = pScreen->allowedDepths + d;
37005b261ecSmrg	    ++ndepth;
37105b261ecSmrg
37205b261ecSmrg	    for (v = 0; v < pDepth->numVids; v++)
37305b261ecSmrg	    {
37405b261ecSmrg		pVisual = findVisual (pScreen, pDepth->vids[v]);
37505b261ecSmrg		if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
37605b261ecSmrg		    ++nvisual;
37705b261ecSmrg	    }
37805b261ecSmrg	}
37905b261ecSmrg	ps = GetPictureScreenIfSet(pScreen);
38005b261ecSmrg	if (ps)
38105b261ecSmrg	    nformat += ps->nformats;
38205b261ecSmrg    }
38305b261ecSmrg    if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
38405b261ecSmrg	numSubpixel = 0;
38505b261ecSmrg    else
38605b261ecSmrg	numSubpixel = numScreens;
38705b261ecSmrg
38805b261ecSmrg    rlength = (sizeof (xRenderQueryPictFormatsReply) +
38905b261ecSmrg	       nformat * sizeof (xPictFormInfo) +
39005b261ecSmrg	       numScreens * sizeof (xPictScreen) +
39105b261ecSmrg	       ndepth * sizeof (xPictDepth) +
39205b261ecSmrg	       nvisual * sizeof (xPictVisual) +
39305b261ecSmrg	       numSubpixel * sizeof (CARD32));
3946747b715Smrg    reply = (xRenderQueryPictFormatsReply *) calloc(1, rlength);
39505b261ecSmrg    if (!reply)
39605b261ecSmrg	return BadAlloc;
39705b261ecSmrg    reply->type = X_Reply;
39805b261ecSmrg    reply->sequenceNumber = client->sequence;
3996747b715Smrg    reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
40005b261ecSmrg    reply->numFormats = nformat;
40105b261ecSmrg    reply->numScreens = numScreens;
40205b261ecSmrg    reply->numDepths = ndepth;
40305b261ecSmrg    reply->numVisuals = nvisual;
40405b261ecSmrg    reply->numSubpixel = numSubpixel;
40505b261ecSmrg
40605b261ecSmrg    pictForm = (xPictFormInfo *) (reply + 1);
40705b261ecSmrg
40805b261ecSmrg    for (s = 0; s < numScreens; s++)
40905b261ecSmrg    {
41005b261ecSmrg	pScreen = screenInfo.screens[s];
41105b261ecSmrg	ps = GetPictureScreenIfSet(pScreen);
41205b261ecSmrg	if (ps)
41305b261ecSmrg	{
41405b261ecSmrg	    for (nformat = 0, pFormat = ps->formats;
41505b261ecSmrg		 nformat < ps->nformats;
41605b261ecSmrg		 nformat++, pFormat++)
41705b261ecSmrg	    {
41805b261ecSmrg		pictForm->id = pFormat->id;
41905b261ecSmrg		pictForm->type = pFormat->type;
42005b261ecSmrg		pictForm->depth = pFormat->depth;
42105b261ecSmrg		pictForm->direct.red = pFormat->direct.red;
42205b261ecSmrg		pictForm->direct.redMask = pFormat->direct.redMask;
42305b261ecSmrg		pictForm->direct.green = pFormat->direct.green;
42405b261ecSmrg		pictForm->direct.greenMask = pFormat->direct.greenMask;
42505b261ecSmrg		pictForm->direct.blue = pFormat->direct.blue;
42605b261ecSmrg		pictForm->direct.blueMask = pFormat->direct.blueMask;
42705b261ecSmrg		pictForm->direct.alpha = pFormat->direct.alpha;
42805b261ecSmrg		pictForm->direct.alphaMask = pFormat->direct.alphaMask;
42905b261ecSmrg		if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
43005b261ecSmrg		    pictForm->colormap = pFormat->index.pColormap->mid;
43105b261ecSmrg		else
43205b261ecSmrg		    pictForm->colormap = None;
43305b261ecSmrg		if (client->swapped)
43405b261ecSmrg		{
43505b261ecSmrg		    swapl (&pictForm->id, n);
43605b261ecSmrg		    swaps (&pictForm->direct.red, n);
43705b261ecSmrg		    swaps (&pictForm->direct.redMask, n);
43805b261ecSmrg		    swaps (&pictForm->direct.green, n);
43905b261ecSmrg		    swaps (&pictForm->direct.greenMask, n);
44005b261ecSmrg		    swaps (&pictForm->direct.blue, n);
44105b261ecSmrg		    swaps (&pictForm->direct.blueMask, n);
44205b261ecSmrg		    swaps (&pictForm->direct.alpha, n);
44305b261ecSmrg		    swaps (&pictForm->direct.alphaMask, n);
44405b261ecSmrg		    swapl (&pictForm->colormap, n);
44505b261ecSmrg		}
44605b261ecSmrg		pictForm++;
44705b261ecSmrg	    }
44805b261ecSmrg	}
44905b261ecSmrg    }
45005b261ecSmrg
45105b261ecSmrg    pictScreen = (xPictScreen *) pictForm;
45205b261ecSmrg    for (s = 0; s < numScreens; s++)
45305b261ecSmrg    {
45405b261ecSmrg	pScreen = screenInfo.screens[s];
45505b261ecSmrg	pictDepth = (xPictDepth *) (pictScreen + 1);
45605b261ecSmrg	ndepth = 0;
45705b261ecSmrg	for (d = 0; d < pScreen->numDepths; d++)
45805b261ecSmrg	{
45905b261ecSmrg	    pictVisual = (xPictVisual *) (pictDepth + 1);
46005b261ecSmrg	    pDepth = pScreen->allowedDepths + d;
46105b261ecSmrg
46205b261ecSmrg	    nvisual = 0;
46305b261ecSmrg	    for (v = 0; v < pDepth->numVids; v++)
46405b261ecSmrg	    {
46505b261ecSmrg		pVisual = findVisual (pScreen, pDepth->vids[v]);
46605b261ecSmrg		if (pVisual && (pFormat = PictureMatchVisual (pScreen,
46705b261ecSmrg							      pDepth->depth,
46805b261ecSmrg							      pVisual)))
46905b261ecSmrg		{
47005b261ecSmrg		    pictVisual->visual = pVisual->vid;
47105b261ecSmrg		    pictVisual->format = pFormat->id;
47205b261ecSmrg		    if (client->swapped)
47305b261ecSmrg		    {
47405b261ecSmrg			swapl (&pictVisual->visual, n);
47505b261ecSmrg			swapl (&pictVisual->format, n);
47605b261ecSmrg		    }
47705b261ecSmrg		    pictVisual++;
47805b261ecSmrg		    nvisual++;
47905b261ecSmrg		}
48005b261ecSmrg	    }
48105b261ecSmrg	    pictDepth->depth = pDepth->depth;
48205b261ecSmrg	    pictDepth->nPictVisuals = nvisual;
48305b261ecSmrg	    if (client->swapped)
48405b261ecSmrg	    {
48505b261ecSmrg		swaps (&pictDepth->nPictVisuals, n);
48605b261ecSmrg	    }
48705b261ecSmrg	    ndepth++;
48805b261ecSmrg	    pictDepth = (xPictDepth *) pictVisual;
48905b261ecSmrg	}
49005b261ecSmrg	pictScreen->nDepth = ndepth;
49105b261ecSmrg	ps = GetPictureScreenIfSet(pScreen);
49205b261ecSmrg	if (ps)
49305b261ecSmrg	    pictScreen->fallback = ps->fallback->id;
49405b261ecSmrg	else
49505b261ecSmrg	    pictScreen->fallback = 0;
49605b261ecSmrg	if (client->swapped)
49705b261ecSmrg	{
49805b261ecSmrg	    swapl (&pictScreen->nDepth, n);
49905b261ecSmrg	    swapl (&pictScreen->fallback, n);
50005b261ecSmrg	}
50105b261ecSmrg	pictScreen = (xPictScreen *) pictDepth;
50205b261ecSmrg    }
50305b261ecSmrg    pictSubpixel = (CARD32 *) pictScreen;
50405b261ecSmrg
50505b261ecSmrg    for (s = 0; s < numSubpixel; s++)
50605b261ecSmrg    {
50705b261ecSmrg	pScreen = screenInfo.screens[s];
50805b261ecSmrg	ps = GetPictureScreenIfSet(pScreen);
50905b261ecSmrg	if (ps)
51005b261ecSmrg	    *pictSubpixel = ps->subpixel;
51105b261ecSmrg	else
51205b261ecSmrg	    *pictSubpixel = SubPixelUnknown;
51305b261ecSmrg	if (client->swapped)
51405b261ecSmrg	{
51505b261ecSmrg	    swapl (pictSubpixel, n);
51605b261ecSmrg	}
51705b261ecSmrg	++pictSubpixel;
51805b261ecSmrg    }
51905b261ecSmrg
52005b261ecSmrg    if (client->swapped)
52105b261ecSmrg    {
52205b261ecSmrg	swaps (&reply->sequenceNumber, n);
52305b261ecSmrg	swapl (&reply->length, n);
52405b261ecSmrg	swapl (&reply->numFormats, n);
52505b261ecSmrg	swapl (&reply->numScreens, n);
52605b261ecSmrg	swapl (&reply->numDepths, n);
52705b261ecSmrg	swapl (&reply->numVisuals, n);
52805b261ecSmrg	swapl (&reply->numSubpixel, n);
52905b261ecSmrg    }
53005b261ecSmrg    WriteToClient(client, rlength, (char *) reply);
5316747b715Smrg    free(reply);
5326747b715Smrg    return Success;
53305b261ecSmrg}
53405b261ecSmrg
53505b261ecSmrgstatic int
53605b261ecSmrgProcRenderQueryPictIndexValues (ClientPtr client)
53705b261ecSmrg{
53805b261ecSmrg    PictFormatPtr   pFormat;
5396747b715Smrg    int		    rc, num;
54005b261ecSmrg    int		    rlength;
54105b261ecSmrg    int		    i, n;
54205b261ecSmrg    REQUEST(xRenderQueryPictIndexValuesReq);
54305b261ecSmrg    xRenderQueryPictIndexValuesReply *reply;
54405b261ecSmrg    xIndexValue	    *values;
54505b261ecSmrg
54605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
54705b261ecSmrg
5486747b715Smrg    rc = dixLookupResourceByType((pointer *)&pFormat, stuff->format,
5496747b715Smrg				 PictFormatType, client, DixReadAccess);
5506747b715Smrg    if (rc != Success)
5516747b715Smrg	return rc;
55205b261ecSmrg
55305b261ecSmrg    if (pFormat->type != PictTypeIndexed)
55405b261ecSmrg    {
55505b261ecSmrg	client->errorValue = stuff->format;
55605b261ecSmrg	return BadMatch;
55705b261ecSmrg    }
55805b261ecSmrg    num = pFormat->index.nvalues;
55905b261ecSmrg    rlength = (sizeof (xRenderQueryPictIndexValuesReply) +
56005b261ecSmrg	       num * sizeof(xIndexValue));
5616747b715Smrg    reply = (xRenderQueryPictIndexValuesReply *) malloc(rlength);
56205b261ecSmrg    if (!reply)
56305b261ecSmrg	return BadAlloc;
56405b261ecSmrg
56505b261ecSmrg    reply->type = X_Reply;
56605b261ecSmrg    reply->sequenceNumber = client->sequence;
5676747b715Smrg    reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
56805b261ecSmrg    reply->numIndexValues = num;
56905b261ecSmrg
57005b261ecSmrg    values = (xIndexValue *) (reply + 1);
57105b261ecSmrg
57205b261ecSmrg    memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
57305b261ecSmrg
57405b261ecSmrg    if (client->swapped)
57505b261ecSmrg    {
57605b261ecSmrg	for (i = 0; i < num; i++)
57705b261ecSmrg	{
57805b261ecSmrg	    swapl (&values[i].pixel, n);
57905b261ecSmrg	    swaps (&values[i].red, n);
58005b261ecSmrg	    swaps (&values[i].green, n);
58105b261ecSmrg	    swaps (&values[i].blue, n);
58205b261ecSmrg	    swaps (&values[i].alpha, n);
58305b261ecSmrg	}
58405b261ecSmrg	swaps (&reply->sequenceNumber, n);
58505b261ecSmrg	swapl (&reply->length, n);
58605b261ecSmrg	swapl (&reply->numIndexValues, n);
58705b261ecSmrg    }
58805b261ecSmrg
58905b261ecSmrg    WriteToClient(client, rlength, (char *) reply);
5906747b715Smrg    free(reply);
5916747b715Smrg    return Success;
59205b261ecSmrg}
59305b261ecSmrg
59405b261ecSmrgstatic int
59505b261ecSmrgProcRenderQueryDithers (ClientPtr client)
59605b261ecSmrg{
59705b261ecSmrg    return BadImplementation;
59805b261ecSmrg}
59905b261ecSmrg
60005b261ecSmrgstatic int
60105b261ecSmrgProcRenderCreatePicture (ClientPtr client)
60205b261ecSmrg{
60305b261ecSmrg    PicturePtr	    pPicture;
60405b261ecSmrg    DrawablePtr	    pDrawable;
60505b261ecSmrg    PictFormatPtr   pFormat;
60605b261ecSmrg    int		    len, error, rc;
60705b261ecSmrg    REQUEST(xRenderCreatePictureReq);
60805b261ecSmrg
60905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
61005b261ecSmrg
61105b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
61205b261ecSmrg    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
6134642e01fSmrg			   DixReadAccess|DixAddAccess);
61405b261ecSmrg    if (rc != Success)
61505b261ecSmrg	return rc;
61605b261ecSmrg
6176747b715Smrg    rc = dixLookupResourceByType((pointer *)&pFormat, stuff->format,
6186747b715Smrg				 PictFormatType, client, DixReadAccess);
6196747b715Smrg    if (rc != Success)
6206747b715Smrg	return rc;
6216747b715Smrg
62205b261ecSmrg    if (pFormat->depth != pDrawable->depth)
62305b261ecSmrg	return BadMatch;
6246747b715Smrg    len = client->req_len - bytes_to_int32(sizeof(xRenderCreatePictureReq));
62505b261ecSmrg    if (Ones(stuff->mask) != len)
62605b261ecSmrg	return BadLength;
62705b261ecSmrg
62805b261ecSmrg    pPicture = CreatePicture (stuff->pid,
62905b261ecSmrg			      pDrawable,
63005b261ecSmrg			      pFormat,
63105b261ecSmrg			      stuff->mask,
63205b261ecSmrg			      (XID *) (stuff + 1),
63305b261ecSmrg			      client,
63405b261ecSmrg			      &error);
63505b261ecSmrg    if (!pPicture)
63605b261ecSmrg	return error;
63705b261ecSmrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
63805b261ecSmrg	return BadAlloc;
63905b261ecSmrg    return Success;
64005b261ecSmrg}
64105b261ecSmrg
64205b261ecSmrgstatic int
64305b261ecSmrgProcRenderChangePicture (ClientPtr client)
64405b261ecSmrg{
64505b261ecSmrg    PicturePtr	    pPicture;
64605b261ecSmrg    REQUEST(xRenderChangePictureReq);
64705b261ecSmrg    int len;
64805b261ecSmrg
64905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
6506747b715Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess);
65105b261ecSmrg
6526747b715Smrg    len = client->req_len - bytes_to_int32(sizeof(xRenderChangePictureReq));
65305b261ecSmrg    if (Ones(stuff->mask) != len)
65405b261ecSmrg	return BadLength;
65505b261ecSmrg
65605b261ecSmrg    return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
65705b261ecSmrg			  (DevUnion *) 0, client);
65805b261ecSmrg}
65905b261ecSmrg
66005b261ecSmrgstatic int
66105b261ecSmrgProcRenderSetPictureClipRectangles (ClientPtr client)
66205b261ecSmrg{
66305b261ecSmrg    REQUEST(xRenderSetPictureClipRectanglesReq);
66405b261ecSmrg    PicturePtr	    pPicture;
66505b261ecSmrg    int		    nr;
66605b261ecSmrg
66705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
6686747b715Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess);
66905b261ecSmrg    if (!pPicture->pDrawable)
67005b261ecSmrg        return BadDrawable;
67105b261ecSmrg
6726747b715Smrg    nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
67305b261ecSmrg    if (nr & 4)
67405b261ecSmrg	return BadLength;
67505b261ecSmrg    nr >>= 3;
6766747b715Smrg    return SetPictureClipRects (pPicture,
67705b261ecSmrg				  stuff->xOrigin, stuff->yOrigin,
67805b261ecSmrg				  nr, (xRectangle *) &stuff[1]);
67905b261ecSmrg}
68005b261ecSmrg
68105b261ecSmrgstatic int
68205b261ecSmrgProcRenderFreePicture (ClientPtr client)
68305b261ecSmrg{
68405b261ecSmrg    PicturePtr	pPicture;
68505b261ecSmrg    REQUEST(xRenderFreePictureReq);
68605b261ecSmrg
68705b261ecSmrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
68805b261ecSmrg
6896747b715Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixDestroyAccess);
69005b261ecSmrg    FreeResource (stuff->picture, RT_NONE);
6916747b715Smrg    return Success;
69205b261ecSmrg}
69305b261ecSmrg
69405b261ecSmrgstatic Bool
69505b261ecSmrgPictOpValid (CARD8 op)
69605b261ecSmrg{
69705b261ecSmrg    if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
69805b261ecSmrg	return TRUE;
69905b261ecSmrg    if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
70005b261ecSmrg	return TRUE;
70105b261ecSmrg    if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
70205b261ecSmrg	return TRUE;
7036747b715Smrg    if (PictOpBlendMinimum <= op && op <= PictOpBlendMaximum)
7046747b715Smrg	return TRUE;
70505b261ecSmrg    return FALSE;
70605b261ecSmrg}
70705b261ecSmrg
70805b261ecSmrgstatic int
70905b261ecSmrgProcRenderComposite (ClientPtr client)
71005b261ecSmrg{
71105b261ecSmrg    PicturePtr	pSrc, pMask, pDst;
71205b261ecSmrg    REQUEST(xRenderCompositeReq);
71305b261ecSmrg
71405b261ecSmrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
71505b261ecSmrg    if (!PictOpValid (stuff->op))
71605b261ecSmrg    {
71705b261ecSmrg	client->errorValue = stuff->op;
71805b261ecSmrg	return BadValue;
71905b261ecSmrg    }
7206747b715Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
72105b261ecSmrg    if (!pDst->pDrawable)
72205b261ecSmrg        return BadDrawable;
7236747b715Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
7246747b715Smrg    VERIFY_ALPHA (pMask, stuff->mask, client, DixReadAccess);
72505b261ecSmrg    if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
72605b261ecSmrg	(pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen))
72705b261ecSmrg	return BadMatch;
72805b261ecSmrg    CompositePicture (stuff->op,
72905b261ecSmrg		      pSrc,
73005b261ecSmrg		      pMask,
73105b261ecSmrg		      pDst,
73205b261ecSmrg		      stuff->xSrc,
73305b261ecSmrg		      stuff->ySrc,
73405b261ecSmrg		      stuff->xMask,
73505b261ecSmrg		      stuff->yMask,
73605b261ecSmrg		      stuff->xDst,
73705b261ecSmrg		      stuff->yDst,
73805b261ecSmrg		      stuff->width,
73905b261ecSmrg		      stuff->height);
74005b261ecSmrg    return Success;
74105b261ecSmrg}
74205b261ecSmrg
74305b261ecSmrgstatic int
74405b261ecSmrgProcRenderScale (ClientPtr client)
74505b261ecSmrg{
74605b261ecSmrg    return BadImplementation;
74705b261ecSmrg}
74805b261ecSmrg
74905b261ecSmrgstatic int
75005b261ecSmrgProcRenderTrapezoids (ClientPtr client)
75105b261ecSmrg{
7526747b715Smrg    int		rc, ntraps;
75305b261ecSmrg    PicturePtr	pSrc, pDst;
75405b261ecSmrg    PictFormatPtr   pFormat;
75505b261ecSmrg    REQUEST(xRenderTrapezoidsReq);
75605b261ecSmrg
75705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
75805b261ecSmrg    if (!PictOpValid (stuff->op))
75905b261ecSmrg    {
76005b261ecSmrg	client->errorValue = stuff->op;
76105b261ecSmrg	return BadValue;
76205b261ecSmrg    }
7636747b715Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
7646747b715Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
76505b261ecSmrg    if (!pDst->pDrawable)
76605b261ecSmrg        return BadDrawable;
76705b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
76805b261ecSmrg	return BadMatch;
76905b261ecSmrg    if (stuff->maskFormat)
77005b261ecSmrg    {
7716747b715Smrg	rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
7726747b715Smrg				     PictFormatType, client, DixReadAccess);
7736747b715Smrg	if (rc != Success)
7746747b715Smrg	    return rc;
77505b261ecSmrg    }
77605b261ecSmrg    else
77705b261ecSmrg	pFormat = 0;
77805b261ecSmrg    ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
77905b261ecSmrg    if (ntraps % sizeof (xTrapezoid))
78005b261ecSmrg	return BadLength;
78105b261ecSmrg    ntraps /= sizeof (xTrapezoid);
78205b261ecSmrg    if (ntraps)
78305b261ecSmrg	CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
78405b261ecSmrg			     stuff->xSrc, stuff->ySrc,
78505b261ecSmrg			     ntraps, (xTrapezoid *) &stuff[1]);
7866747b715Smrg    return Success;
78705b261ecSmrg}
78805b261ecSmrg
78905b261ecSmrgstatic int
79005b261ecSmrgProcRenderTriangles (ClientPtr client)
79105b261ecSmrg{
7926747b715Smrg    int		rc, ntris;
79305b261ecSmrg    PicturePtr	pSrc, pDst;
79405b261ecSmrg    PictFormatPtr   pFormat;
79505b261ecSmrg    REQUEST(xRenderTrianglesReq);
79605b261ecSmrg
79705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
79805b261ecSmrg    if (!PictOpValid (stuff->op))
79905b261ecSmrg    {
80005b261ecSmrg	client->errorValue = stuff->op;
80105b261ecSmrg	return BadValue;
80205b261ecSmrg    }
8036747b715Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
8046747b715Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
80505b261ecSmrg    if (!pDst->pDrawable)
80605b261ecSmrg        return BadDrawable;
80705b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
80805b261ecSmrg	return BadMatch;
80905b261ecSmrg    if (stuff->maskFormat)
81005b261ecSmrg    {
8116747b715Smrg	rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
8126747b715Smrg				     PictFormatType, client, DixReadAccess);
8136747b715Smrg	if (rc != Success)
8146747b715Smrg	    return rc;
81505b261ecSmrg    }
81605b261ecSmrg    else
81705b261ecSmrg	pFormat = 0;
81805b261ecSmrg    ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
81905b261ecSmrg    if (ntris % sizeof (xTriangle))
82005b261ecSmrg	return BadLength;
82105b261ecSmrg    ntris /= sizeof (xTriangle);
82205b261ecSmrg    if (ntris)
82305b261ecSmrg	CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
82405b261ecSmrg			    stuff->xSrc, stuff->ySrc,
82505b261ecSmrg			    ntris, (xTriangle *) &stuff[1]);
8266747b715Smrg    return Success;
82705b261ecSmrg}
82805b261ecSmrg
82905b261ecSmrgstatic int
83005b261ecSmrgProcRenderTriStrip (ClientPtr client)
83105b261ecSmrg{
8326747b715Smrg    int		rc, npoints;
83305b261ecSmrg    PicturePtr	pSrc, pDst;
83405b261ecSmrg    PictFormatPtr   pFormat;
83505b261ecSmrg    REQUEST(xRenderTrianglesReq);
83605b261ecSmrg
83705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
83805b261ecSmrg    if (!PictOpValid (stuff->op))
83905b261ecSmrg    {
84005b261ecSmrg	client->errorValue = stuff->op;
84105b261ecSmrg	return BadValue;
84205b261ecSmrg    }
8436747b715Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
8446747b715Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
84505b261ecSmrg    if (!pDst->pDrawable)
84605b261ecSmrg        return BadDrawable;
84705b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
84805b261ecSmrg	return BadMatch;
84905b261ecSmrg    if (stuff->maskFormat)
85005b261ecSmrg    {
8516747b715Smrg	rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
8526747b715Smrg				     PictFormatType, client, DixReadAccess);
8536747b715Smrg	if (rc != Success)
8546747b715Smrg	    return rc;
85505b261ecSmrg    }
85605b261ecSmrg    else
85705b261ecSmrg	pFormat = 0;
85805b261ecSmrg    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
85905b261ecSmrg    if (npoints & 4)
8606747b715Smrg	return BadLength;
86105b261ecSmrg    npoints >>= 3;
86205b261ecSmrg    if (npoints >= 3)
86305b261ecSmrg	CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
86405b261ecSmrg			   stuff->xSrc, stuff->ySrc,
86505b261ecSmrg			   npoints, (xPointFixed *) &stuff[1]);
8666747b715Smrg    return Success;
86705b261ecSmrg}
86805b261ecSmrg
86905b261ecSmrgstatic int
87005b261ecSmrgProcRenderTriFan (ClientPtr client)
87105b261ecSmrg{
8726747b715Smrg    int		rc, npoints;
87305b261ecSmrg    PicturePtr	pSrc, pDst;
87405b261ecSmrg    PictFormatPtr   pFormat;
87505b261ecSmrg    REQUEST(xRenderTrianglesReq);
87605b261ecSmrg
87705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
87805b261ecSmrg    if (!PictOpValid (stuff->op))
87905b261ecSmrg    {
88005b261ecSmrg	client->errorValue = stuff->op;
88105b261ecSmrg	return BadValue;
88205b261ecSmrg    }
8836747b715Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
8846747b715Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
88505b261ecSmrg    if (!pDst->pDrawable)
88605b261ecSmrg        return BadDrawable;
88705b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
88805b261ecSmrg	return BadMatch;
88905b261ecSmrg    if (stuff->maskFormat)
89005b261ecSmrg    {
8916747b715Smrg	rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
8926747b715Smrg				     PictFormatType, client, DixReadAccess);
8936747b715Smrg	if (rc != Success)
8946747b715Smrg	    return rc;
89505b261ecSmrg    }
89605b261ecSmrg    else
89705b261ecSmrg	pFormat = 0;
89805b261ecSmrg    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
89905b261ecSmrg    if (npoints & 4)
9006747b715Smrg	return BadLength;
90105b261ecSmrg    npoints >>= 3;
90205b261ecSmrg    if (npoints >= 3)
90305b261ecSmrg	CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
90405b261ecSmrg			 stuff->xSrc, stuff->ySrc,
90505b261ecSmrg			 npoints, (xPointFixed *) &stuff[1]);
9066747b715Smrg    return Success;
90705b261ecSmrg}
90805b261ecSmrg
90905b261ecSmrgstatic int
91005b261ecSmrgProcRenderColorTrapezoids (ClientPtr client)
91105b261ecSmrg{
91205b261ecSmrg    return BadImplementation;
91305b261ecSmrg}
91405b261ecSmrg
91505b261ecSmrgstatic int
91605b261ecSmrgProcRenderColorTriangles (ClientPtr client)
91705b261ecSmrg{
91805b261ecSmrg    return BadImplementation;
91905b261ecSmrg}
92005b261ecSmrg
92105b261ecSmrgstatic int
92205b261ecSmrgProcRenderTransform (ClientPtr client)
92305b261ecSmrg{
92405b261ecSmrg    return BadImplementation;
92505b261ecSmrg}
92605b261ecSmrg
92705b261ecSmrgstatic int
92805b261ecSmrgProcRenderCreateGlyphSet (ClientPtr client)
92905b261ecSmrg{
93005b261ecSmrg    GlyphSetPtr	    glyphSet;
93105b261ecSmrg    PictFormatPtr   format;
9324642e01fSmrg    int		    rc, f;
93305b261ecSmrg    REQUEST(xRenderCreateGlyphSetReq);
93405b261ecSmrg
93505b261ecSmrg    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
93605b261ecSmrg
93705b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->gsid, client);
9386747b715Smrg    rc = dixLookupResourceByType((pointer *)&format, stuff->format,
9396747b715Smrg				 PictFormatType, client, DixReadAccess);
9406747b715Smrg    if (rc != Success)
9416747b715Smrg	return rc;
9426747b715Smrg
94305b261ecSmrg    switch (format->depth) {
94405b261ecSmrg    case 1:
94505b261ecSmrg	f = GlyphFormat1;
94605b261ecSmrg	break;
94705b261ecSmrg    case 4:
94805b261ecSmrg	f = GlyphFormat4;
94905b261ecSmrg	break;
95005b261ecSmrg    case 8:
95105b261ecSmrg	f = GlyphFormat8;
95205b261ecSmrg	break;
95305b261ecSmrg    case 16:
95405b261ecSmrg	f = GlyphFormat16;
95505b261ecSmrg	break;
95605b261ecSmrg    case 32:
95705b261ecSmrg	f = GlyphFormat32;
95805b261ecSmrg	break;
95905b261ecSmrg    default:
96005b261ecSmrg	return BadMatch;
96105b261ecSmrg    }
96205b261ecSmrg    if (format->type != PictTypeDirect)
96305b261ecSmrg	return BadMatch;
96405b261ecSmrg    glyphSet = AllocateGlyphSet (f, format);
96505b261ecSmrg    if (!glyphSet)
96605b261ecSmrg	return BadAlloc;
9674642e01fSmrg    /* security creation/labeling check */
9684642e01fSmrg    rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType,
9694642e01fSmrg		  glyphSet, RT_NONE, NULL, DixCreateAccess);
9704642e01fSmrg    if (rc != Success)
9714642e01fSmrg	return rc;
97205b261ecSmrg    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
97305b261ecSmrg	return BadAlloc;
97405b261ecSmrg    return Success;
97505b261ecSmrg}
97605b261ecSmrg
97705b261ecSmrgstatic int
97805b261ecSmrgProcRenderReferenceGlyphSet (ClientPtr client)
97905b261ecSmrg{
98005b261ecSmrg    GlyphSetPtr     glyphSet;
9814642e01fSmrg    int rc;
98205b261ecSmrg    REQUEST(xRenderReferenceGlyphSetReq);
98305b261ecSmrg
98405b261ecSmrg    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
98505b261ecSmrg
98605b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->gsid, client);
98705b261ecSmrg
988b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->existing, GlyphSetType,
9894642e01fSmrg			   client, DixGetAttrAccess);
9904642e01fSmrg    if (rc != Success)
99105b261ecSmrg    {
99205b261ecSmrg	client->errorValue = stuff->existing;
9936747b715Smrg	return rc;
99405b261ecSmrg    }
99505b261ecSmrg    glyphSet->refcnt++;
99605b261ecSmrg    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
99705b261ecSmrg	return BadAlloc;
9986747b715Smrg    return Success;
99905b261ecSmrg}
100005b261ecSmrg
100105b261ecSmrg#define NLOCALDELTA	64
100205b261ecSmrg#define NLOCALGLYPH	256
100305b261ecSmrg
100405b261ecSmrgstatic int
100505b261ecSmrgProcRenderFreeGlyphSet (ClientPtr client)
100605b261ecSmrg{
100705b261ecSmrg    GlyphSetPtr     glyphSet;
10084642e01fSmrg    int rc;
100905b261ecSmrg    REQUEST(xRenderFreeGlyphSetReq);
101005b261ecSmrg
101105b261ecSmrg    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
1012b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType,
10134642e01fSmrg			   client, DixDestroyAccess);
10144642e01fSmrg    if (rc != Success)
101505b261ecSmrg    {
101605b261ecSmrg	client->errorValue = stuff->glyphset;
10176747b715Smrg	return rc;
101805b261ecSmrg    }
101905b261ecSmrg    FreeResource (stuff->glyphset, RT_NONE);
10206747b715Smrg    return Success;
102105b261ecSmrg}
102205b261ecSmrg
102305b261ecSmrgtypedef struct _GlyphNew {
10244642e01fSmrg    Glyph	    id;
10254642e01fSmrg    GlyphPtr        glyph;
10264642e01fSmrg    Bool	    found;
10274642e01fSmrg    unsigned char   sha1[20];
102805b261ecSmrg} GlyphNewRec, *GlyphNewPtr;
102905b261ecSmrg
10304642e01fSmrg#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
10314642e01fSmrg
103205b261ecSmrgstatic int
103305b261ecSmrgProcRenderAddGlyphs (ClientPtr client)
103405b261ecSmrg{
103505b261ecSmrg    GlyphSetPtr     glyphSet;
103605b261ecSmrg    REQUEST(xRenderAddGlyphsReq);
103705b261ecSmrg    GlyphNewRec	    glyphsLocal[NLOCALGLYPH];
10384642e01fSmrg    GlyphNewPtr	    glyphsBase, glyphs, glyph_new;
103905b261ecSmrg    int		    remain, nglyphs;
104005b261ecSmrg    CARD32	    *gids;
104105b261ecSmrg    xGlyphInfo	    *gi;
104205b261ecSmrg    CARD8	    *bits;
10436747b715Smrg    unsigned int    size;
10444642e01fSmrg    int		    err;
10454642e01fSmrg    int		    i, screen;
10464642e01fSmrg    PicturePtr	    pSrc = NULL, pDst = NULL;
10474642e01fSmrg    PixmapPtr	    pSrcPix = NULL, pDstPix = NULL;
10484642e01fSmrg    CARD32	    component_alpha;
104905b261ecSmrg
105005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
1051b86d567bSmrg    err = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType,
10524642e01fSmrg			    client, DixAddAccess);
10534642e01fSmrg    if (err != Success)
105405b261ecSmrg    {
105505b261ecSmrg	client->errorValue = stuff->glyphset;
10566747b715Smrg	return err;
105705b261ecSmrg    }
105805b261ecSmrg
10594642e01fSmrg    err = BadAlloc;
106005b261ecSmrg    nglyphs = stuff->nglyphs;
106105b261ecSmrg    if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
106205b261ecSmrg	    return BadAlloc;
106305b261ecSmrg
10644642e01fSmrg    component_alpha = NeedsComponent (glyphSet->format->format);
10654642e01fSmrg
10664642e01fSmrg    if (nglyphs <= NLOCALGLYPH) {
10674642e01fSmrg	memset (glyphsLocal, 0, sizeof (glyphsLocal));
106805b261ecSmrg	glyphsBase = glyphsLocal;
10694642e01fSmrg    }
107005b261ecSmrg    else
107105b261ecSmrg    {
10726747b715Smrg	glyphsBase = (GlyphNewPtr)calloc(nglyphs, sizeof (GlyphNewRec));
107305b261ecSmrg	if (!glyphsBase)
107405b261ecSmrg	    return BadAlloc;
107505b261ecSmrg    }
107605b261ecSmrg
107705b261ecSmrg    remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
107805b261ecSmrg
107905b261ecSmrg    glyphs = glyphsBase;
108005b261ecSmrg
108105b261ecSmrg    gids = (CARD32 *) (stuff + 1);
108205b261ecSmrg    gi = (xGlyphInfo *) (gids + nglyphs);
108305b261ecSmrg    bits = (CARD8 *) (gi + nglyphs);
108405b261ecSmrg    remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
10856747b715Smrg
10866747b715Smrg    /* protect against bad nglyphs */
10879ace9065Smrg    if (gi < ((xGlyphInfo *)stuff) ||
10889ace9065Smrg        gi > ((xGlyphInfo *)((CARD32 *)stuff + client->req_len)) ||
10899ace9065Smrg        bits < ((CARD8 *)stuff) ||
10909ace9065Smrg        bits > ((CARD8 *)((CARD32 *)stuff + client->req_len))) {
10916747b715Smrg        err = BadLength;
10926747b715Smrg        goto bail;
10936747b715Smrg    }
10946747b715Smrg
10954642e01fSmrg    for (i = 0; i < nglyphs; i++)
109605b261ecSmrg    {
10974642e01fSmrg	size_t padded_width;
10984642e01fSmrg	glyph_new = &glyphs[i];
10994642e01fSmrg
11004642e01fSmrg	padded_width = PixmapBytePad (gi[i].width,
11014642e01fSmrg				      glyphSet->format->depth);
11024642e01fSmrg
11034642e01fSmrg	if (gi[i].height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi[i].height)
11044642e01fSmrg	    break;
110505b261ecSmrg
11064642e01fSmrg	size = gi[i].height * padded_width;
110705b261ecSmrg	if (remain < size)
110805b261ecSmrg	    break;
11094642e01fSmrg
11104642e01fSmrg	err = HashGlyph (&gi[i], bits, size, glyph_new->sha1);
11114642e01fSmrg	if (err)
11124642e01fSmrg	    goto bail;
11134642e01fSmrg
11144642e01fSmrg	glyph_new->glyph = FindGlyphByHash (glyph_new->sha1,
11154642e01fSmrg					    glyphSet->fdepth);
11164642e01fSmrg
11174642e01fSmrg	if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph)
11184642e01fSmrg	{
11194642e01fSmrg	    glyph_new->found = TRUE;
11204642e01fSmrg	}
11214642e01fSmrg	else
11224642e01fSmrg	{
11234642e01fSmrg	    GlyphPtr glyph;
11244642e01fSmrg
11254642e01fSmrg	    glyph_new->found = FALSE;
11264642e01fSmrg	    glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth);
11274642e01fSmrg	    if (! glyph)
11284642e01fSmrg	    {
11294642e01fSmrg		err = BadAlloc;
11304642e01fSmrg		goto bail;
11314642e01fSmrg	    }
11324642e01fSmrg
11334642e01fSmrg	    for (screen = 0; screen < screenInfo.numScreens; screen++)
11344642e01fSmrg	    {
11354642e01fSmrg		int	    width = gi[i].width;
11364642e01fSmrg		int	    height = gi[i].height;
11374642e01fSmrg		int	    depth = glyphSet->format->depth;
11384642e01fSmrg		ScreenPtr   pScreen;
11394642e01fSmrg		int	    error;
11404642e01fSmrg
11416747b715Smrg		/* Skip work if it's invisibly small anyway */
11426747b715Smrg		if (!width || !height)
11436747b715Smrg		    break;
11446747b715Smrg
11454642e01fSmrg		pScreen = screenInfo.screens[screen];
11464642e01fSmrg		pSrcPix = GetScratchPixmapHeader (pScreen,
11474642e01fSmrg						  width, height,
11484642e01fSmrg						  depth, depth,
11494642e01fSmrg						  -1, bits);
11504642e01fSmrg		if (! pSrcPix)
11514642e01fSmrg		{
11524642e01fSmrg		    err = BadAlloc;
11534642e01fSmrg		    goto bail;
11544642e01fSmrg		}
11554642e01fSmrg
11564642e01fSmrg		pSrc = CreatePicture (0, &pSrcPix->drawable,
11574642e01fSmrg				      glyphSet->format, 0, NULL,
11584642e01fSmrg				      serverClient, &error);
11594642e01fSmrg		if (! pSrc)
11604642e01fSmrg		{
11614642e01fSmrg		    err = BadAlloc;
11624642e01fSmrg		    goto bail;
11634642e01fSmrg		}
11644642e01fSmrg
11654642e01fSmrg		pDstPix = (pScreen->CreatePixmap) (pScreen,
11664642e01fSmrg						   width, height, depth,
11674642e01fSmrg						   CREATE_PIXMAP_USAGE_GLYPH_PICTURE);
11684642e01fSmrg
11696747b715Smrg		if (!pDstPix)
11706747b715Smrg		{
11716747b715Smrg		    err = BadAlloc;
11726747b715Smrg		    goto bail;
11736747b715Smrg		}
11746747b715Smrg
11754642e01fSmrg		GlyphPicture (glyph)[screen] = pDst =
11764642e01fSmrg			CreatePicture (0, &pDstPix->drawable,
11774642e01fSmrg				       glyphSet->format,
11784642e01fSmrg				       CPComponentAlpha, &component_alpha,
11794642e01fSmrg				       serverClient, &error);
11804642e01fSmrg
11814642e01fSmrg		/* The picture takes a reference to the pixmap, so we
11824642e01fSmrg		   drop ours. */
11834642e01fSmrg		(pScreen->DestroyPixmap) (pDstPix);
11846747b715Smrg		pDstPix = NULL;
11854642e01fSmrg
11864642e01fSmrg		if (! pDst)
11874642e01fSmrg		{
11884642e01fSmrg		    err = BadAlloc;
11894642e01fSmrg		    goto bail;
11904642e01fSmrg		}
11914642e01fSmrg
11924642e01fSmrg		CompositePicture (PictOpSrc,
11934642e01fSmrg				  pSrc,
11944642e01fSmrg				  None,
11954642e01fSmrg				  pDst,
11964642e01fSmrg				  0, 0,
11974642e01fSmrg				  0, 0,
11984642e01fSmrg				  0, 0,
11994642e01fSmrg				  width, height);
12004642e01fSmrg
12014642e01fSmrg		FreePicture ((pointer) pSrc, 0);
12024642e01fSmrg		pSrc = NULL;
12034642e01fSmrg		FreeScratchPixmapHeader (pSrcPix);
12044642e01fSmrg		pSrcPix = NULL;
12054642e01fSmrg	    }
12064642e01fSmrg
12074642e01fSmrg	    memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20);
12084642e01fSmrg	}
12094642e01fSmrg
12104642e01fSmrg	glyph_new->id = gids[i];
121105b261ecSmrg
121205b261ecSmrg	if (size & 3)
121305b261ecSmrg	    size += 4 - (size & 3);
121405b261ecSmrg	bits += size;
121505b261ecSmrg	remain -= size;
121605b261ecSmrg    }
12174642e01fSmrg    if (remain || i < nglyphs)
121805b261ecSmrg    {
121905b261ecSmrg	err = BadLength;
122005b261ecSmrg	goto bail;
122105b261ecSmrg    }
122205b261ecSmrg    if (!ResizeGlyphSet (glyphSet, nglyphs))
122305b261ecSmrg    {
122405b261ecSmrg	err = BadAlloc;
122505b261ecSmrg	goto bail;
122605b261ecSmrg    }
12274642e01fSmrg    for (i = 0; i < nglyphs; i++)
12284642e01fSmrg	AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id);
122905b261ecSmrg
123005b261ecSmrg    if (glyphsBase != glyphsLocal)
12316747b715Smrg	free(glyphsBase);
12326747b715Smrg    return Success;
123305b261ecSmrgbail:
12344642e01fSmrg    if (pSrc)
12354642e01fSmrg	FreePicture ((pointer) pSrc, 0);
12364642e01fSmrg    if (pSrcPix)
12374642e01fSmrg	FreeScratchPixmapHeader (pSrcPix);
12384642e01fSmrg    for (i = 0; i < nglyphs; i++)
12394642e01fSmrg	if (glyphs[i].glyph && ! glyphs[i].found)
12406747b715Smrg	    free(glyphs[i].glyph);
124105b261ecSmrg    if (glyphsBase != glyphsLocal)
12426747b715Smrg	free(glyphsBase);
124305b261ecSmrg    return err;
124405b261ecSmrg}
124505b261ecSmrg
124605b261ecSmrgstatic int
124705b261ecSmrgProcRenderAddGlyphsFromPicture (ClientPtr client)
124805b261ecSmrg{
124905b261ecSmrg    return BadImplementation;
125005b261ecSmrg}
125105b261ecSmrg
125205b261ecSmrgstatic int
125305b261ecSmrgProcRenderFreeGlyphs (ClientPtr client)
125405b261ecSmrg{
125505b261ecSmrg    REQUEST(xRenderFreeGlyphsReq);
125605b261ecSmrg    GlyphSetPtr     glyphSet;
12574642e01fSmrg    int		    rc, nglyph;
125805b261ecSmrg    CARD32	    *gids;
125905b261ecSmrg    CARD32	    glyph;
126005b261ecSmrg
126105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
1262b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType,
12634642e01fSmrg			   client, DixRemoveAccess);
12644642e01fSmrg    if (rc != Success)
126505b261ecSmrg    {
126605b261ecSmrg	client->errorValue = stuff->glyphset;
12676747b715Smrg	return rc;
126805b261ecSmrg    }
12696747b715Smrg    nglyph = bytes_to_int32((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq));
127005b261ecSmrg    gids = (CARD32 *) (stuff + 1);
127105b261ecSmrg    while (nglyph-- > 0)
127205b261ecSmrg    {
127305b261ecSmrg	glyph = *gids++;
127405b261ecSmrg	if (!DeleteGlyph (glyphSet, glyph))
127505b261ecSmrg	{
127605b261ecSmrg	    client->errorValue = glyph;
127705b261ecSmrg	    return RenderErrBase + BadGlyph;
127805b261ecSmrg	}
127905b261ecSmrg    }
12806747b715Smrg    return Success;
128105b261ecSmrg}
128205b261ecSmrg
128305b261ecSmrgstatic int
128405b261ecSmrgProcRenderCompositeGlyphs (ClientPtr client)
128505b261ecSmrg{
128605b261ecSmrg    GlyphSetPtr     glyphSet;
128705b261ecSmrg    GlyphSet	    gs;
128805b261ecSmrg    PicturePtr      pSrc, pDst;
128905b261ecSmrg    PictFormatPtr   pFormat;
129005b261ecSmrg    GlyphListRec    listsLocal[NLOCALDELTA];
129105b261ecSmrg    GlyphListPtr    lists, listsBase;
129205b261ecSmrg    GlyphPtr	    glyphsLocal[NLOCALGLYPH];
129305b261ecSmrg    Glyph	    glyph;
129405b261ecSmrg    GlyphPtr	    *glyphs, *glyphsBase;
129505b261ecSmrg    xGlyphElt	    *elt;
129605b261ecSmrg    CARD8	    *buffer, *end;
129705b261ecSmrg    int		    nglyph;
129805b261ecSmrg    int		    nlist;
129905b261ecSmrg    int		    space;
130005b261ecSmrg    int		    size;
13016747b715Smrg    int		    rc, n;
130205b261ecSmrg
130305b261ecSmrg    REQUEST(xRenderCompositeGlyphsReq);
130405b261ecSmrg
130505b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
130605b261ecSmrg
130705b261ecSmrg    switch (stuff->renderReqType) {
130805b261ecSmrg    default:			    size = 1; break;
130905b261ecSmrg    case X_RenderCompositeGlyphs16: size = 2; break;
131005b261ecSmrg    case X_RenderCompositeGlyphs32: size = 4; break;
131105b261ecSmrg    }
131205b261ecSmrg
131305b261ecSmrg    if (!PictOpValid (stuff->op))
131405b261ecSmrg    {
131505b261ecSmrg	client->errorValue = stuff->op;
131605b261ecSmrg	return BadValue;
131705b261ecSmrg    }
13186747b715Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
13196747b715Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
132005b261ecSmrg    if (!pDst->pDrawable)
132105b261ecSmrg        return BadDrawable;
132205b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
132305b261ecSmrg	return BadMatch;
132405b261ecSmrg    if (stuff->maskFormat)
132505b261ecSmrg    {
13266747b715Smrg	rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
13276747b715Smrg				     PictFormatType, client, DixReadAccess);
13286747b715Smrg	if (rc != Success)
13296747b715Smrg	    return rc;
133005b261ecSmrg    }
133105b261ecSmrg    else
133205b261ecSmrg	pFormat = 0;
133305b261ecSmrg
13346747b715Smrg    rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset,
13356747b715Smrg				 GlyphSetType, client, DixUseAccess);
13366747b715Smrg    if (rc != Success)
13376747b715Smrg	return rc;
133805b261ecSmrg
133905b261ecSmrg    buffer = (CARD8 *) (stuff + 1);
134005b261ecSmrg    end = (CARD8 *) stuff + (client->req_len << 2);
134105b261ecSmrg    nglyph = 0;
134205b261ecSmrg    nlist = 0;
134305b261ecSmrg    while (buffer + sizeof (xGlyphElt) < end)
134405b261ecSmrg    {
134505b261ecSmrg	elt = (xGlyphElt *) buffer;
134605b261ecSmrg	buffer += sizeof (xGlyphElt);
134705b261ecSmrg
134805b261ecSmrg	if (elt->len == 0xff)
134905b261ecSmrg	{
135005b261ecSmrg	    buffer += 4;
135105b261ecSmrg	}
135205b261ecSmrg	else
135305b261ecSmrg	{
135405b261ecSmrg	    nlist++;
135505b261ecSmrg	    nglyph += elt->len;
135605b261ecSmrg	    space = size * elt->len;
135705b261ecSmrg	    if (space & 3)
135805b261ecSmrg		space += 4 - (space & 3);
135905b261ecSmrg	    buffer += space;
136005b261ecSmrg	}
136105b261ecSmrg    }
136205b261ecSmrg    if (nglyph <= NLOCALGLYPH)
136305b261ecSmrg	glyphsBase = glyphsLocal;
136405b261ecSmrg    else
136505b261ecSmrg    {
13666747b715Smrg	glyphsBase = (GlyphPtr *) malloc(nglyph * sizeof (GlyphPtr));
136705b261ecSmrg	if (!glyphsBase)
136805b261ecSmrg	    return BadAlloc;
136905b261ecSmrg    }
137005b261ecSmrg    if (nlist <= NLOCALDELTA)
137105b261ecSmrg	listsBase = listsLocal;
137205b261ecSmrg    else
137305b261ecSmrg    {
13746747b715Smrg	listsBase = (GlyphListPtr) malloc(nlist * sizeof (GlyphListRec));
13759ace9065Smrg	if (!listsBase) {
13769ace9065Smrg	    rc = BadAlloc;
13779ace9065Smrg	    goto bail;
13789ace9065Smrg	}
137905b261ecSmrg    }
138005b261ecSmrg    buffer = (CARD8 *) (stuff + 1);
138105b261ecSmrg    glyphs = glyphsBase;
138205b261ecSmrg    lists = listsBase;
138305b261ecSmrg    while (buffer + sizeof (xGlyphElt) < end)
138405b261ecSmrg    {
138505b261ecSmrg	elt = (xGlyphElt *) buffer;
138605b261ecSmrg	buffer += sizeof (xGlyphElt);
138705b261ecSmrg
138805b261ecSmrg	if (elt->len == 0xff)
138905b261ecSmrg	{
139005b261ecSmrg	    if (buffer + sizeof (GlyphSet) < end)
139105b261ecSmrg	    {
139205b261ecSmrg                memcpy(&gs, buffer, sizeof(GlyphSet));
13936747b715Smrg		rc = dixLookupResourceByType((pointer *)&glyphSet, gs,
13946747b715Smrg					     GlyphSetType, client,
13956747b715Smrg					     DixUseAccess);
13966747b715Smrg		if (rc != Success)
13979ace9065Smrg		    goto bail;
139805b261ecSmrg	    }
139905b261ecSmrg	    buffer += 4;
140005b261ecSmrg	}
140105b261ecSmrg	else
140205b261ecSmrg	{
140305b261ecSmrg	    lists->xOff = elt->deltax;
140405b261ecSmrg	    lists->yOff = elt->deltay;
140505b261ecSmrg	    lists->format = glyphSet->format;
140605b261ecSmrg	    lists->len = 0;
140705b261ecSmrg	    n = elt->len;
140805b261ecSmrg	    while (n--)
140905b261ecSmrg	    {
141005b261ecSmrg		if (buffer + size <= end)
141105b261ecSmrg		{
141205b261ecSmrg		    switch (size) {
141305b261ecSmrg		    case 1:
141405b261ecSmrg			glyph = *((CARD8 *)buffer); break;
141505b261ecSmrg		    case 2:
141605b261ecSmrg			glyph = *((CARD16 *)buffer); break;
141705b261ecSmrg		    case 4:
141805b261ecSmrg		    default:
141905b261ecSmrg			glyph = *((CARD32 *)buffer); break;
142005b261ecSmrg		    }
142105b261ecSmrg		    if ((*glyphs = FindGlyph (glyphSet, glyph)))
142205b261ecSmrg		    {
142305b261ecSmrg			lists->len++;
142405b261ecSmrg			glyphs++;
142505b261ecSmrg		    }
142605b261ecSmrg		}
142705b261ecSmrg		buffer += size;
142805b261ecSmrg	    }
142905b261ecSmrg	    space = size * elt->len;
143005b261ecSmrg	    if (space & 3)
143105b261ecSmrg		buffer += 4 - (space & 3);
143205b261ecSmrg	    lists++;
143305b261ecSmrg	}
143405b261ecSmrg    }
14359ace9065Smrg    if (buffer > end) {
14369ace9065Smrg	rc = BadLength;
14379ace9065Smrg	goto bail;
14389ace9065Smrg    }
143905b261ecSmrg
144005b261ecSmrg    CompositeGlyphs (stuff->op,
144105b261ecSmrg		     pSrc,
144205b261ecSmrg		     pDst,
144305b261ecSmrg		     pFormat,
144405b261ecSmrg		     stuff->xSrc,
144505b261ecSmrg		     stuff->ySrc,
144605b261ecSmrg		     nlist,
144705b261ecSmrg		     listsBase,
144805b261ecSmrg		     glyphsBase);
14499ace9065Smrg    rc = Success;
145005b261ecSmrg
14519ace9065Smrgbail:
145205b261ecSmrg    if (glyphsBase != glyphsLocal)
14536747b715Smrg	free(glyphsBase);
145405b261ecSmrg    if (listsBase != listsLocal)
14556747b715Smrg	free(listsBase);
14569ace9065Smrg    return rc;
145705b261ecSmrg}
145805b261ecSmrg
145905b261ecSmrgstatic int
146005b261ecSmrgProcRenderFillRectangles (ClientPtr client)
146105b261ecSmrg{
146205b261ecSmrg    PicturePtr	    pDst;
146305b261ecSmrg    int             things;
146405b261ecSmrg    REQUEST(xRenderFillRectanglesReq);
146505b261ecSmrg
146605b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
146705b261ecSmrg    if (!PictOpValid (stuff->op))
146805b261ecSmrg    {
146905b261ecSmrg	client->errorValue = stuff->op;
147005b261ecSmrg	return BadValue;
147105b261ecSmrg    }
14726747b715Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
147305b261ecSmrg    if (!pDst->pDrawable)
147405b261ecSmrg        return BadDrawable;
147505b261ecSmrg
147605b261ecSmrg    things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
147705b261ecSmrg    if (things & 4)
14786747b715Smrg	return BadLength;
147905b261ecSmrg    things >>= 3;
148005b261ecSmrg
148105b261ecSmrg    CompositeRects (stuff->op,
148205b261ecSmrg		    pDst,
148305b261ecSmrg		    &stuff->color,
148405b261ecSmrg		    things,
148505b261ecSmrg		    (xRectangle *) &stuff[1]);
148605b261ecSmrg
14876747b715Smrg    return Success;
148805b261ecSmrg}
148905b261ecSmrg
149005b261ecSmrgstatic void
14916747b715SmrgRenderSetBit (unsigned char *line, int x, int bit)
149205b261ecSmrg{
149305b261ecSmrg    unsigned char   mask;
149405b261ecSmrg
149505b261ecSmrg    if (screenInfo.bitmapBitOrder == LSBFirst)
149605b261ecSmrg	mask = (1 << (x & 7));
149705b261ecSmrg    else
149805b261ecSmrg	mask = (0x80 >> (x & 7));
149905b261ecSmrg    /* XXX assumes byte order is host byte order */
150005b261ecSmrg    line += (x >> 3);
150105b261ecSmrg    if (bit)
150205b261ecSmrg	*line |= mask;
150305b261ecSmrg    else
150405b261ecSmrg	*line &= ~mask;
150505b261ecSmrg}
150605b261ecSmrg
150705b261ecSmrg#define DITHER_DIM 2
150805b261ecSmrg
150905b261ecSmrgstatic CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
151005b261ecSmrg    {  1,  3,  },
151105b261ecSmrg    {  4,  2,  },
151205b261ecSmrg};
151305b261ecSmrg
151405b261ecSmrg#define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
151505b261ecSmrg
151605b261ecSmrgstatic int
151705b261ecSmrgProcRenderCreateCursor (ClientPtr client)
151805b261ecSmrg{
151905b261ecSmrg    REQUEST(xRenderCreateCursorReq);
152005b261ecSmrg    PicturePtr	    pSrc;
152105b261ecSmrg    ScreenPtr	    pScreen;
152205b261ecSmrg    unsigned short  width, height;
152305b261ecSmrg    CARD32	    *argbbits, *argb;
152405b261ecSmrg    unsigned char   *srcbits, *srcline;
152505b261ecSmrg    unsigned char   *mskbits, *mskline;
152605b261ecSmrg    int		    stride;
152705b261ecSmrg    int		    x, y;
152805b261ecSmrg    int		    nbytes_mono;
152905b261ecSmrg    CursorMetricRec cm;
153005b261ecSmrg    CursorPtr	    pCursor;
153105b261ecSmrg    CARD32	    twocolor[3];
15324642e01fSmrg    int		    rc, ncolor;
153305b261ecSmrg
153405b261ecSmrg    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
153505b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
153605b261ecSmrg
15376747b715Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
153805b261ecSmrg    if (!pSrc->pDrawable)
153905b261ecSmrg        return BadDrawable;
154005b261ecSmrg    pScreen = pSrc->pDrawable->pScreen;
154105b261ecSmrg    width = pSrc->pDrawable->width;
154205b261ecSmrg    height = pSrc->pDrawable->height;
154305b261ecSmrg    if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
154405b261ecSmrg	return BadAlloc;
154505b261ecSmrg    if ( stuff->x > width
154605b261ecSmrg      || stuff->y > height )
15476747b715Smrg	return BadMatch;
15486747b715Smrg    argbbits = malloc(width * height * sizeof (CARD32));
154905b261ecSmrg    if (!argbbits)
15506747b715Smrg	return BadAlloc;
155105b261ecSmrg
155205b261ecSmrg    stride = BitmapBytePad(width);
155305b261ecSmrg    nbytes_mono = stride*height;
15546747b715Smrg    srcbits = calloc(1, nbytes_mono);
155505b261ecSmrg    if (!srcbits)
155605b261ecSmrg    {
15576747b715Smrg	free(argbbits);
15586747b715Smrg	return BadAlloc;
155905b261ecSmrg    }
15606747b715Smrg    mskbits = calloc(1, nbytes_mono);
156105b261ecSmrg    if (!mskbits)
156205b261ecSmrg    {
15636747b715Smrg	free(argbbits);
15646747b715Smrg	free(srcbits);
15656747b715Smrg	return BadAlloc;
156605b261ecSmrg    }
156705b261ecSmrg
156805b261ecSmrg    if (pSrc->format == PICT_a8r8g8b8)
156905b261ecSmrg    {
157005b261ecSmrg	(*pScreen->GetImage) (pSrc->pDrawable,
157105b261ecSmrg			      0, 0, width, height, ZPixmap,
157205b261ecSmrg			      0xffffffff, (pointer) argbbits);
157305b261ecSmrg    }
157405b261ecSmrg    else
157505b261ecSmrg    {
157605b261ecSmrg	PixmapPtr	pPixmap;
157705b261ecSmrg	PicturePtr	pPicture;
157805b261ecSmrg	PictFormatPtr	pFormat;
157905b261ecSmrg	int		error;
158005b261ecSmrg
158105b261ecSmrg	pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
158205b261ecSmrg	if (!pFormat)
158305b261ecSmrg	{
15846747b715Smrg	    free(argbbits);
15856747b715Smrg	    free(srcbits);
15866747b715Smrg	    free(mskbits);
15876747b715Smrg	    return BadImplementation;
158805b261ecSmrg	}
15894642e01fSmrg	pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32,
15904642e01fSmrg					    CREATE_PIXMAP_USAGE_SCRATCH);
159105b261ecSmrg	if (!pPixmap)
159205b261ecSmrg	{
15936747b715Smrg	    free(argbbits);
15946747b715Smrg	    free(srcbits);
15956747b715Smrg	    free(mskbits);
15966747b715Smrg	    return BadAlloc;
159705b261ecSmrg	}
159805b261ecSmrg	pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0,
159905b261ecSmrg				  client, &error);
160005b261ecSmrg	if (!pPicture)
160105b261ecSmrg	{
16026747b715Smrg	    free(argbbits);
16036747b715Smrg	    free(srcbits);
16046747b715Smrg	    free(mskbits);
160505b261ecSmrg	    return error;
160605b261ecSmrg	}
160705b261ecSmrg	(*pScreen->DestroyPixmap) (pPixmap);
160805b261ecSmrg	CompositePicture (PictOpSrc,
160905b261ecSmrg			  pSrc, 0, pPicture,
161005b261ecSmrg			  0, 0, 0, 0, 0, 0, width, height);
161105b261ecSmrg	(*pScreen->GetImage) (pPicture->pDrawable,
161205b261ecSmrg			      0, 0, width, height, ZPixmap,
161305b261ecSmrg			      0xffffffff, (pointer) argbbits);
161405b261ecSmrg	FreePicture (pPicture, 0);
161505b261ecSmrg    }
161605b261ecSmrg    /*
161705b261ecSmrg     * Check whether the cursor can be directly supported by
161805b261ecSmrg     * the core cursor code
161905b261ecSmrg     */
162005b261ecSmrg    ncolor = 0;
162105b261ecSmrg    argb = argbbits;
162205b261ecSmrg    for (y = 0; ncolor <= 2 && y < height; y++)
162305b261ecSmrg    {
162405b261ecSmrg	for (x = 0; ncolor <= 2 && x < width; x++)
162505b261ecSmrg	{
162605b261ecSmrg	    CARD32  p = *argb++;
162705b261ecSmrg	    CARD32  a = (p >> 24);
162805b261ecSmrg
162905b261ecSmrg	    if (a == 0)	    /* transparent */
163005b261ecSmrg		continue;
163105b261ecSmrg	    if (a == 0xff)  /* opaque */
163205b261ecSmrg	    {
163305b261ecSmrg		int n;
163405b261ecSmrg		for (n = 0; n < ncolor; n++)
163505b261ecSmrg		    if (p == twocolor[n])
163605b261ecSmrg			break;
163705b261ecSmrg		if (n == ncolor)
163805b261ecSmrg		    twocolor[ncolor++] = p;
163905b261ecSmrg	    }
164005b261ecSmrg	    else
164105b261ecSmrg		ncolor = 3;
164205b261ecSmrg	}
164305b261ecSmrg    }
164405b261ecSmrg
164505b261ecSmrg    /*
164605b261ecSmrg     * Convert argb image to two plane cursor
164705b261ecSmrg     */
164805b261ecSmrg    srcline = srcbits;
164905b261ecSmrg    mskline = mskbits;
165005b261ecSmrg    argb = argbbits;
165105b261ecSmrg    for (y = 0; y < height; y++)
165205b261ecSmrg    {
165305b261ecSmrg	for (x = 0; x < width; x++)
165405b261ecSmrg	{
165505b261ecSmrg	    CARD32  p = *argb++;
165605b261ecSmrg
165705b261ecSmrg	    if (ncolor <= 2)
165805b261ecSmrg	    {
165905b261ecSmrg		CARD32	a = ((p >> 24));
166005b261ecSmrg
16616747b715Smrg		RenderSetBit (mskline, x, a != 0);
16626747b715Smrg		RenderSetBit (srcline, x, a != 0 && p == twocolor[0]);
166305b261ecSmrg	    }
166405b261ecSmrg	    else
166505b261ecSmrg	    {
166605b261ecSmrg		CARD32	a = ((p >> 24) * DITHER_SIZE + 127) / 255;
166705b261ecSmrg		CARD32	i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
166805b261ecSmrg		CARD32	d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
166905b261ecSmrg		/* Set mask from dithered alpha value */
16706747b715Smrg		RenderSetBit(mskline, x, a > d);
167105b261ecSmrg		/* Set src from dithered intensity value */
16726747b715Smrg		RenderSetBit(srcline, x, a > d && i <= d);
167305b261ecSmrg	    }
167405b261ecSmrg	}
167505b261ecSmrg	srcline += stride;
167605b261ecSmrg	mskline += stride;
167705b261ecSmrg    }
167805b261ecSmrg    /*
167905b261ecSmrg     * Dither to white and black if the cursor has more than two colors
168005b261ecSmrg     */
168105b261ecSmrg    if (ncolor > 2)
168205b261ecSmrg    {
168305b261ecSmrg	twocolor[0] = 0xff000000;
168405b261ecSmrg	twocolor[1] = 0xffffffff;
168505b261ecSmrg    }
168605b261ecSmrg    else
168705b261ecSmrg    {
16886747b715Smrg	free(argbbits);
168905b261ecSmrg	argbbits = 0;
169005b261ecSmrg    }
169105b261ecSmrg
169205b261ecSmrg#define GetByte(p,s)	(((p) >> (s)) & 0xff)
169305b261ecSmrg#define GetColor(p,s)	(GetByte(p,s) | (GetByte(p,s) << 8))
169405b261ecSmrg
169505b261ecSmrg    cm.width = width;
169605b261ecSmrg    cm.height = height;
169705b261ecSmrg    cm.xhot = stuff->x;
169805b261ecSmrg    cm.yhot = stuff->y;
16994642e01fSmrg    rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm,
17004642e01fSmrg			 GetColor(twocolor[0], 16),
17014642e01fSmrg			 GetColor(twocolor[0], 8),
17024642e01fSmrg			 GetColor(twocolor[0], 0),
17034642e01fSmrg			 GetColor(twocolor[1], 16),
17044642e01fSmrg			 GetColor(twocolor[1], 8),
17054642e01fSmrg			 GetColor(twocolor[1], 0),
17064642e01fSmrg			 &pCursor, client, stuff->cid);
17074642e01fSmrg    if (rc != Success)
17084642e01fSmrg	return rc;
17094642e01fSmrg    if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
17104642e01fSmrg	return BadAlloc;
17114642e01fSmrg
17126747b715Smrg    return Success;
171305b261ecSmrg}
171405b261ecSmrg
171505b261ecSmrgstatic int
171605b261ecSmrgProcRenderSetPictureTransform (ClientPtr client)
171705b261ecSmrg{
171805b261ecSmrg    REQUEST(xRenderSetPictureTransformReq);
171905b261ecSmrg    PicturePtr	pPicture;
172005b261ecSmrg
172105b261ecSmrg    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
17226747b715Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess);
17236747b715Smrg    return SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
172405b261ecSmrg}
172505b261ecSmrg
172605b261ecSmrgstatic int
172705b261ecSmrgProcRenderQueryFilters (ClientPtr client)
172805b261ecSmrg{
172905b261ecSmrg    REQUEST (xRenderQueryFiltersReq);
173005b261ecSmrg    DrawablePtr			pDrawable;
173105b261ecSmrg    xRenderQueryFiltersReply	*reply;
173205b261ecSmrg    int				nbytesName;
173305b261ecSmrg    int				nnames;
173405b261ecSmrg    ScreenPtr			pScreen;
173505b261ecSmrg    PictureScreenPtr		ps;
173605b261ecSmrg    int				i, j, len, total_bytes, rc;
173705b261ecSmrg    INT16			*aliases;
173805b261ecSmrg    char			*names;
173905b261ecSmrg
174005b261ecSmrg    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
174105b261ecSmrg    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
17424642e01fSmrg			   DixGetAttrAccess);
174305b261ecSmrg    if (rc != Success)
174405b261ecSmrg	return rc;
174505b261ecSmrg
174605b261ecSmrg    pScreen = pDrawable->pScreen;
174705b261ecSmrg    nbytesName = 0;
174805b261ecSmrg    nnames = 0;
174905b261ecSmrg    ps = GetPictureScreenIfSet(pScreen);
175005b261ecSmrg    if (ps)
175105b261ecSmrg    {
175205b261ecSmrg	for (i = 0; i < ps->nfilters; i++)
175305b261ecSmrg	    nbytesName += 1 + strlen (ps->filters[i].name);
175405b261ecSmrg	for (i = 0; i < ps->nfilterAliases; i++)
175505b261ecSmrg	    nbytesName += 1 + strlen (ps->filterAliases[i].alias);
175605b261ecSmrg	nnames = ps->nfilters + ps->nfilterAliases;
175705b261ecSmrg    }
17586747b715Smrg    len = ((nnames + 1) >> 1) + bytes_to_int32(nbytesName);
175905b261ecSmrg    total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
17606747b715Smrg    reply = (xRenderQueryFiltersReply *) malloc(total_bytes);
176105b261ecSmrg    if (!reply)
176205b261ecSmrg	return BadAlloc;
176305b261ecSmrg    aliases = (INT16 *) (reply + 1);
176405b261ecSmrg    names = (char *) (aliases + ((nnames + 1) & ~1));
176505b261ecSmrg
176605b261ecSmrg    reply->type = X_Reply;
176705b261ecSmrg    reply->sequenceNumber = client->sequence;
176805b261ecSmrg    reply->length = len;
176905b261ecSmrg    reply->numAliases = nnames;
177005b261ecSmrg    reply->numFilters = nnames;
177105b261ecSmrg    if (ps)
177205b261ecSmrg    {
177305b261ecSmrg
177405b261ecSmrg	/* fill in alias values */
177505b261ecSmrg	for (i = 0; i < ps->nfilters; i++)
177605b261ecSmrg	    aliases[i] = FilterAliasNone;
177705b261ecSmrg	for (i = 0; i < ps->nfilterAliases; i++)
177805b261ecSmrg	{
177905b261ecSmrg	    for (j = 0; j < ps->nfilters; j++)
178005b261ecSmrg		if (ps->filterAliases[i].filter_id == ps->filters[j].id)
178105b261ecSmrg		    break;
178205b261ecSmrg	    if (j == ps->nfilters)
178305b261ecSmrg	    {
178405b261ecSmrg		for (j = 0; j < ps->nfilterAliases; j++)
178505b261ecSmrg		    if (ps->filterAliases[i].filter_id ==
178605b261ecSmrg			ps->filterAliases[j].alias_id)
178705b261ecSmrg		    {
178805b261ecSmrg			break;
178905b261ecSmrg		    }
179005b261ecSmrg		if (j == ps->nfilterAliases)
179105b261ecSmrg		    j = FilterAliasNone;
179205b261ecSmrg		else
179305b261ecSmrg		    j = j + ps->nfilters;
179405b261ecSmrg	    }
179505b261ecSmrg	    aliases[i + ps->nfilters] = j;
179605b261ecSmrg	}
179705b261ecSmrg
179805b261ecSmrg	/* fill in filter names */
179905b261ecSmrg	for (i = 0; i < ps->nfilters; i++)
180005b261ecSmrg	{
180105b261ecSmrg	    j = strlen (ps->filters[i].name);
180205b261ecSmrg	    *names++ = j;
180305b261ecSmrg	    strncpy (names, ps->filters[i].name, j);
180405b261ecSmrg	    names += j;
180505b261ecSmrg	}
180605b261ecSmrg
180705b261ecSmrg	/* fill in filter alias names */
180805b261ecSmrg	for (i = 0; i < ps->nfilterAliases; i++)
180905b261ecSmrg	{
181005b261ecSmrg	    j = strlen (ps->filterAliases[i].alias);
181105b261ecSmrg	    *names++ = j;
181205b261ecSmrg	    strncpy (names, ps->filterAliases[i].alias, j);
181305b261ecSmrg	    names += j;
181405b261ecSmrg	}
181505b261ecSmrg    }
181605b261ecSmrg
181705b261ecSmrg    if (client->swapped)
181805b261ecSmrg    {
181905b261ecSmrg	register int n;
182005b261ecSmrg
182105b261ecSmrg	for (i = 0; i < reply->numAliases; i++)
182205b261ecSmrg	{
182305b261ecSmrg	    swaps (&aliases[i], n);
182405b261ecSmrg	}
182505b261ecSmrg    	swaps(&reply->sequenceNumber, n);
182605b261ecSmrg    	swapl(&reply->length, n);
182705b261ecSmrg	swapl(&reply->numAliases, n);
182805b261ecSmrg	swapl(&reply->numFilters, n);
182905b261ecSmrg    }
183005b261ecSmrg    WriteToClient(client, total_bytes, (char *) reply);
18316747b715Smrg    free(reply);
183205b261ecSmrg
18336747b715Smrg    return Success;
183405b261ecSmrg}
183505b261ecSmrg
183605b261ecSmrgstatic int
183705b261ecSmrgProcRenderSetPictureFilter (ClientPtr client)
183805b261ecSmrg{
183905b261ecSmrg    REQUEST (xRenderSetPictureFilterReq);
184005b261ecSmrg    PicturePtr	pPicture;
184105b261ecSmrg    int		result;
184205b261ecSmrg    xFixed	*params;
184305b261ecSmrg    int		nparams;
184405b261ecSmrg    char	*name;
184505b261ecSmrg
184605b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
18476747b715Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess);
184805b261ecSmrg    name = (char *) (stuff + 1);
18496747b715Smrg    params = (xFixed *) (name + pad_to_int32(stuff->nbytes));
185005b261ecSmrg    nparams = ((xFixed *) stuff + client->req_len) - params;
185105b261ecSmrg    result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
185205b261ecSmrg    return result;
185305b261ecSmrg}
185405b261ecSmrg
185505b261ecSmrgstatic int
185605b261ecSmrgProcRenderCreateAnimCursor (ClientPtr client)
185705b261ecSmrg{
185805b261ecSmrg    REQUEST(xRenderCreateAnimCursorReq);
185905b261ecSmrg    CursorPtr	    *cursors;
186005b261ecSmrg    CARD32	    *deltas;
186105b261ecSmrg    CursorPtr	    pCursor;
186205b261ecSmrg    int		    ncursor;
186305b261ecSmrg    xAnimCursorElt  *elt;
186405b261ecSmrg    int		    i;
186505b261ecSmrg    int		    ret;
186605b261ecSmrg
186705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
186805b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
186905b261ecSmrg    if (client->req_len & 1)
187005b261ecSmrg	return BadLength;
18716747b715Smrg    ncursor = (client->req_len - (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1;
18726747b715Smrg    cursors = malloc(ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
187305b261ecSmrg    if (!cursors)
187405b261ecSmrg	return BadAlloc;
187505b261ecSmrg    deltas = (CARD32 *) (cursors + ncursor);
187605b261ecSmrg    elt = (xAnimCursorElt *) (stuff + 1);
187705b261ecSmrg    for (i = 0; i < ncursor; i++)
187805b261ecSmrg    {
18796747b715Smrg	ret = dixLookupResourceByType((pointer *)(cursors + i), elt->cursor,
18806747b715Smrg				      RT_CURSOR, client, DixReadAccess);
18816747b715Smrg	if (ret != Success)
188205b261ecSmrg	{
18836747b715Smrg	    free(cursors);
18846747b715Smrg	    return ret;
188505b261ecSmrg	}
188605b261ecSmrg	deltas[i] = elt->delay;
188705b261ecSmrg	elt++;
188805b261ecSmrg    }
18894642e01fSmrg    ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor, client,
18904642e01fSmrg			    stuff->cid);
18916747b715Smrg    free(cursors);
189205b261ecSmrg    if (ret != Success)
189305b261ecSmrg	return ret;
189405b261ecSmrg
189505b261ecSmrg    if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
18966747b715Smrg	return Success;
189705b261ecSmrg    return BadAlloc;
189805b261ecSmrg}
189905b261ecSmrg
190005b261ecSmrgstatic int
190105b261ecSmrgProcRenderAddTraps (ClientPtr client)
190205b261ecSmrg{
190305b261ecSmrg    int		ntraps;
190405b261ecSmrg    PicturePtr	pPicture;
190505b261ecSmrg    REQUEST(xRenderAddTrapsReq);
190605b261ecSmrg
190705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
19086747b715Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess);
190905b261ecSmrg    if (!pPicture->pDrawable)
191005b261ecSmrg        return BadDrawable;
191105b261ecSmrg    ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
191205b261ecSmrg    if (ntraps % sizeof (xTrap))
191305b261ecSmrg	return BadLength;
191405b261ecSmrg    ntraps /= sizeof (xTrap);
191505b261ecSmrg    if (ntraps)
191605b261ecSmrg	AddTraps (pPicture,
191705b261ecSmrg		  stuff->xOff, stuff->yOff,
191805b261ecSmrg		  ntraps, (xTrap *) &stuff[1]);
19196747b715Smrg    return Success;
192005b261ecSmrg}
192105b261ecSmrg
192205b261ecSmrgstatic int ProcRenderCreateSolidFill(ClientPtr client)
192305b261ecSmrg{
192405b261ecSmrg    PicturePtr	    pPicture;
192505b261ecSmrg    int		    error = 0;
192605b261ecSmrg    REQUEST(xRenderCreateSolidFillReq);
192705b261ecSmrg
192805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
192905b261ecSmrg
193005b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
193105b261ecSmrg
193205b261ecSmrg    pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
193305b261ecSmrg    if (!pPicture)
193405b261ecSmrg	return error;
19354642e01fSmrg    /* security creation/labeling check */
19364642e01fSmrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
19374642e01fSmrg		     pPicture, RT_NONE, NULL, DixCreateAccess);
19384642e01fSmrg    if (error != Success)
19394642e01fSmrg	return error;
194005b261ecSmrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
194105b261ecSmrg	return BadAlloc;
194205b261ecSmrg    return Success;
194305b261ecSmrg}
194405b261ecSmrg
194505b261ecSmrgstatic int ProcRenderCreateLinearGradient (ClientPtr client)
194605b261ecSmrg{
194705b261ecSmrg    PicturePtr	    pPicture;
194805b261ecSmrg    int		    len;
194905b261ecSmrg    int		    error = 0;
195005b261ecSmrg    xFixed          *stops;
195105b261ecSmrg    xRenderColor   *colors;
195205b261ecSmrg    REQUEST(xRenderCreateLinearGradientReq);
195305b261ecSmrg
195405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
195505b261ecSmrg
195605b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
195705b261ecSmrg
195805b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
195905b261ecSmrg    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
196005b261ecSmrg	return BadLength;
196105b261ecSmrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
196205b261ecSmrg        return BadLength;
196305b261ecSmrg
196405b261ecSmrg    stops = (xFixed *)(stuff + 1);
196505b261ecSmrg    colors = (xRenderColor *)(stops + stuff->nStops);
196605b261ecSmrg
196705b261ecSmrg    pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
196805b261ecSmrg                                            stuff->nStops, stops, colors, &error);
196905b261ecSmrg    if (!pPicture)
197005b261ecSmrg	return error;
19714642e01fSmrg    /* security creation/labeling check */
19724642e01fSmrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
19734642e01fSmrg		     pPicture, RT_NONE, NULL, DixCreateAccess);
19744642e01fSmrg    if (error != Success)
19754642e01fSmrg	return error;
197605b261ecSmrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
197705b261ecSmrg	return BadAlloc;
197805b261ecSmrg    return Success;
197905b261ecSmrg}
198005b261ecSmrg
198105b261ecSmrgstatic int ProcRenderCreateRadialGradient (ClientPtr client)
198205b261ecSmrg{
198305b261ecSmrg    PicturePtr	    pPicture;
198405b261ecSmrg    int		    len;
198505b261ecSmrg    int		    error = 0;
198605b261ecSmrg    xFixed          *stops;
198705b261ecSmrg    xRenderColor   *colors;
198805b261ecSmrg    REQUEST(xRenderCreateRadialGradientReq);
198905b261ecSmrg
199005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
199105b261ecSmrg
199205b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
199305b261ecSmrg
199405b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
199505b261ecSmrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
199605b261ecSmrg        return BadLength;
199705b261ecSmrg
199805b261ecSmrg    stops = (xFixed *)(stuff + 1);
199905b261ecSmrg    colors = (xRenderColor *)(stops + stuff->nStops);
200005b261ecSmrg
200105b261ecSmrg    pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
200205b261ecSmrg                                            stuff->inner_radius, stuff->outer_radius,
200305b261ecSmrg                                            stuff->nStops, stops, colors, &error);
200405b261ecSmrg    if (!pPicture)
200505b261ecSmrg	return error;
20064642e01fSmrg    /* security creation/labeling check */
20074642e01fSmrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
20084642e01fSmrg		     pPicture, RT_NONE, NULL, DixCreateAccess);
20094642e01fSmrg    if (error != Success)
20104642e01fSmrg	return error;
201105b261ecSmrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
201205b261ecSmrg	return BadAlloc;
201305b261ecSmrg    return Success;
201405b261ecSmrg}
201505b261ecSmrg
201605b261ecSmrgstatic int ProcRenderCreateConicalGradient (ClientPtr client)
201705b261ecSmrg{
201805b261ecSmrg    PicturePtr	    pPicture;
201905b261ecSmrg    int		    len;
202005b261ecSmrg    int		    error = 0;
202105b261ecSmrg    xFixed          *stops;
202205b261ecSmrg    xRenderColor   *colors;
202305b261ecSmrg    REQUEST(xRenderCreateConicalGradientReq);
202405b261ecSmrg
202505b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
202605b261ecSmrg
202705b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
202805b261ecSmrg
202905b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
203005b261ecSmrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
203105b261ecSmrg        return BadLength;
203205b261ecSmrg
203305b261ecSmrg    stops = (xFixed *)(stuff + 1);
203405b261ecSmrg    colors = (xRenderColor *)(stops + stuff->nStops);
203505b261ecSmrg
203605b261ecSmrg    pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
203705b261ecSmrg                                             stuff->nStops, stops, colors, &error);
203805b261ecSmrg    if (!pPicture)
203905b261ecSmrg	return error;
20404642e01fSmrg    /* security creation/labeling check */
20414642e01fSmrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
20424642e01fSmrg		     pPicture, RT_NONE, NULL, DixCreateAccess);
20434642e01fSmrg    if (error != Success)
20444642e01fSmrg	return error;
204505b261ecSmrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
204605b261ecSmrg	return BadAlloc;
204705b261ecSmrg    return Success;
204805b261ecSmrg}
204905b261ecSmrg
205005b261ecSmrg
205105b261ecSmrgstatic int
205205b261ecSmrgProcRenderDispatch (ClientPtr client)
205305b261ecSmrg{
205405b261ecSmrg    REQUEST(xReq);
205505b261ecSmrg
205605b261ecSmrg    if (stuff->data < RenderNumberRequests)
205705b261ecSmrg	return (*ProcRenderVector[stuff->data]) (client);
205805b261ecSmrg    else
205905b261ecSmrg	return BadRequest;
206005b261ecSmrg}
206105b261ecSmrg
206205b261ecSmrgstatic int
206305b261ecSmrgSProcRenderQueryVersion (ClientPtr client)
206405b261ecSmrg{
206505b261ecSmrg    register int n;
206605b261ecSmrg    REQUEST(xRenderQueryVersionReq);
206705b261ecSmrg
206805b261ecSmrg    swaps(&stuff->length, n);
206905b261ecSmrg    swapl(&stuff->majorVersion, n);
207005b261ecSmrg    swapl(&stuff->minorVersion, n);
207105b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType])(client);
207205b261ecSmrg}
207305b261ecSmrg
207405b261ecSmrgstatic int
207505b261ecSmrgSProcRenderQueryPictFormats (ClientPtr client)
207605b261ecSmrg{
207705b261ecSmrg    register int n;
207805b261ecSmrg    REQUEST(xRenderQueryPictFormatsReq);
207905b261ecSmrg    swaps(&stuff->length, n);
208005b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
208105b261ecSmrg}
208205b261ecSmrg
208305b261ecSmrgstatic int
208405b261ecSmrgSProcRenderQueryPictIndexValues (ClientPtr client)
208505b261ecSmrg{
208605b261ecSmrg    register int n;
208705b261ecSmrg    REQUEST(xRenderQueryPictIndexValuesReq);
208805b261ecSmrg    swaps(&stuff->length, n);
208905b261ecSmrg    swapl(&stuff->format, n);
209005b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
209105b261ecSmrg}
209205b261ecSmrg
209305b261ecSmrgstatic int
209405b261ecSmrgSProcRenderQueryDithers (ClientPtr client)
209505b261ecSmrg{
209605b261ecSmrg    return BadImplementation;
209705b261ecSmrg}
209805b261ecSmrg
209905b261ecSmrgstatic int
210005b261ecSmrgSProcRenderCreatePicture (ClientPtr client)
210105b261ecSmrg{
210205b261ecSmrg    register int n;
210305b261ecSmrg    REQUEST(xRenderCreatePictureReq);
210405b261ecSmrg    swaps(&stuff->length, n);
210505b261ecSmrg    swapl(&stuff->pid, n);
210605b261ecSmrg    swapl(&stuff->drawable, n);
210705b261ecSmrg    swapl(&stuff->format, n);
210805b261ecSmrg    swapl(&stuff->mask, n);
210905b261ecSmrg    SwapRestL(stuff);
211005b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
211105b261ecSmrg}
211205b261ecSmrg
211305b261ecSmrgstatic int
211405b261ecSmrgSProcRenderChangePicture (ClientPtr client)
211505b261ecSmrg{
211605b261ecSmrg    register int n;
211705b261ecSmrg    REQUEST(xRenderChangePictureReq);
211805b261ecSmrg    swaps(&stuff->length, n);
211905b261ecSmrg    swapl(&stuff->picture, n);
212005b261ecSmrg    swapl(&stuff->mask, n);
212105b261ecSmrg    SwapRestL(stuff);
212205b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
212305b261ecSmrg}
212405b261ecSmrg
212505b261ecSmrgstatic int
212605b261ecSmrgSProcRenderSetPictureClipRectangles (ClientPtr client)
212705b261ecSmrg{
212805b261ecSmrg    register int n;
212905b261ecSmrg    REQUEST(xRenderSetPictureClipRectanglesReq);
213005b261ecSmrg    swaps(&stuff->length, n);
213105b261ecSmrg    swapl(&stuff->picture, n);
213205b261ecSmrg    swaps(&stuff->xOrigin, n);
213305b261ecSmrg    swaps(&stuff->yOrigin, n);
213405b261ecSmrg    SwapRestS(stuff);
213505b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
213605b261ecSmrg}
213705b261ecSmrg
213805b261ecSmrgstatic int
213905b261ecSmrgSProcRenderFreePicture (ClientPtr client)
214005b261ecSmrg{
214105b261ecSmrg    register int n;
214205b261ecSmrg    REQUEST(xRenderFreePictureReq);
214305b261ecSmrg    swaps(&stuff->length, n);
214405b261ecSmrg    swapl(&stuff->picture, n);
214505b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
214605b261ecSmrg}
214705b261ecSmrg
214805b261ecSmrgstatic int
214905b261ecSmrgSProcRenderComposite (ClientPtr client)
215005b261ecSmrg{
215105b261ecSmrg    register int n;
215205b261ecSmrg    REQUEST(xRenderCompositeReq);
215305b261ecSmrg    swaps(&stuff->length, n);
215405b261ecSmrg    swapl(&stuff->src, n);
215505b261ecSmrg    swapl(&stuff->mask, n);
215605b261ecSmrg    swapl(&stuff->dst, n);
215705b261ecSmrg    swaps(&stuff->xSrc, n);
215805b261ecSmrg    swaps(&stuff->ySrc, n);
215905b261ecSmrg    swaps(&stuff->xMask, n);
216005b261ecSmrg    swaps(&stuff->yMask, n);
216105b261ecSmrg    swaps(&stuff->xDst, n);
216205b261ecSmrg    swaps(&stuff->yDst, n);
216305b261ecSmrg    swaps(&stuff->width, n);
216405b261ecSmrg    swaps(&stuff->height, n);
216505b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
216605b261ecSmrg}
216705b261ecSmrg
216805b261ecSmrgstatic int
216905b261ecSmrgSProcRenderScale (ClientPtr client)
217005b261ecSmrg{
217105b261ecSmrg    register int n;
217205b261ecSmrg    REQUEST(xRenderScaleReq);
217305b261ecSmrg    swaps(&stuff->length, n);
217405b261ecSmrg    swapl(&stuff->src, n);
217505b261ecSmrg    swapl(&stuff->dst, n);
217605b261ecSmrg    swapl(&stuff->colorScale, n);
217705b261ecSmrg    swapl(&stuff->alphaScale, n);
217805b261ecSmrg    swaps(&stuff->xSrc, n);
217905b261ecSmrg    swaps(&stuff->ySrc, n);
218005b261ecSmrg    swaps(&stuff->xDst, n);
218105b261ecSmrg    swaps(&stuff->yDst, n);
218205b261ecSmrg    swaps(&stuff->width, n);
218305b261ecSmrg    swaps(&stuff->height, n);
218405b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
218505b261ecSmrg}
218605b261ecSmrg
218705b261ecSmrgstatic int
218805b261ecSmrgSProcRenderTrapezoids (ClientPtr client)
218905b261ecSmrg{
219005b261ecSmrg    register int n;
219105b261ecSmrg    REQUEST(xRenderTrapezoidsReq);
219205b261ecSmrg
219305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
219405b261ecSmrg    swaps (&stuff->length, n);
219505b261ecSmrg    swapl (&stuff->src, n);
219605b261ecSmrg    swapl (&stuff->dst, n);
219705b261ecSmrg    swapl (&stuff->maskFormat, n);
219805b261ecSmrg    swaps (&stuff->xSrc, n);
219905b261ecSmrg    swaps (&stuff->ySrc, n);
220005b261ecSmrg    SwapRestL(stuff);
220105b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
220205b261ecSmrg}
220305b261ecSmrg
220405b261ecSmrgstatic int
220505b261ecSmrgSProcRenderTriangles (ClientPtr client)
220605b261ecSmrg{
220705b261ecSmrg    register int n;
220805b261ecSmrg    REQUEST(xRenderTrianglesReq);
220905b261ecSmrg
221005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
221105b261ecSmrg    swaps (&stuff->length, n);
221205b261ecSmrg    swapl (&stuff->src, n);
221305b261ecSmrg    swapl (&stuff->dst, n);
221405b261ecSmrg    swapl (&stuff->maskFormat, n);
221505b261ecSmrg    swaps (&stuff->xSrc, n);
221605b261ecSmrg    swaps (&stuff->ySrc, n);
221705b261ecSmrg    SwapRestL(stuff);
221805b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
221905b261ecSmrg}
222005b261ecSmrg
222105b261ecSmrgstatic int
222205b261ecSmrgSProcRenderTriStrip (ClientPtr client)
222305b261ecSmrg{
222405b261ecSmrg    register int n;
222505b261ecSmrg    REQUEST(xRenderTriStripReq);
222605b261ecSmrg
222705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
222805b261ecSmrg    swaps (&stuff->length, n);
222905b261ecSmrg    swapl (&stuff->src, n);
223005b261ecSmrg    swapl (&stuff->dst, n);
223105b261ecSmrg    swapl (&stuff->maskFormat, n);
223205b261ecSmrg    swaps (&stuff->xSrc, n);
223305b261ecSmrg    swaps (&stuff->ySrc, n);
223405b261ecSmrg    SwapRestL(stuff);
223505b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
223605b261ecSmrg}
223705b261ecSmrg
223805b261ecSmrgstatic int
223905b261ecSmrgSProcRenderTriFan (ClientPtr client)
224005b261ecSmrg{
224105b261ecSmrg    register int n;
224205b261ecSmrg    REQUEST(xRenderTriFanReq);
224305b261ecSmrg
224405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
224505b261ecSmrg    swaps (&stuff->length, n);
224605b261ecSmrg    swapl (&stuff->src, n);
224705b261ecSmrg    swapl (&stuff->dst, n);
224805b261ecSmrg    swapl (&stuff->maskFormat, n);
224905b261ecSmrg    swaps (&stuff->xSrc, n);
225005b261ecSmrg    swaps (&stuff->ySrc, n);
225105b261ecSmrg    SwapRestL(stuff);
225205b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
225305b261ecSmrg}
225405b261ecSmrg
225505b261ecSmrgstatic int
225605b261ecSmrgSProcRenderColorTrapezoids (ClientPtr client)
225705b261ecSmrg{
225805b261ecSmrg    return BadImplementation;
225905b261ecSmrg}
226005b261ecSmrg
226105b261ecSmrgstatic int
226205b261ecSmrgSProcRenderColorTriangles (ClientPtr client)
226305b261ecSmrg{
226405b261ecSmrg    return BadImplementation;
226505b261ecSmrg}
226605b261ecSmrg
226705b261ecSmrgstatic int
226805b261ecSmrgSProcRenderTransform (ClientPtr client)
226905b261ecSmrg{
227005b261ecSmrg    return BadImplementation;
227105b261ecSmrg}
227205b261ecSmrg
227305b261ecSmrgstatic int
227405b261ecSmrgSProcRenderCreateGlyphSet (ClientPtr client)
227505b261ecSmrg{
227605b261ecSmrg    register int n;
227705b261ecSmrg    REQUEST(xRenderCreateGlyphSetReq);
227805b261ecSmrg    swaps(&stuff->length, n);
227905b261ecSmrg    swapl(&stuff->gsid, n);
228005b261ecSmrg    swapl(&stuff->format, n);
228105b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
228205b261ecSmrg}
228305b261ecSmrg
228405b261ecSmrgstatic int
228505b261ecSmrgSProcRenderReferenceGlyphSet (ClientPtr client)
228605b261ecSmrg{
228705b261ecSmrg    register int n;
228805b261ecSmrg    REQUEST(xRenderReferenceGlyphSetReq);
228905b261ecSmrg    swaps(&stuff->length, n);
229005b261ecSmrg    swapl(&stuff->gsid, n);
229105b261ecSmrg    swapl(&stuff->existing, n);
229205b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType])  (client);
229305b261ecSmrg}
229405b261ecSmrg
229505b261ecSmrgstatic int
229605b261ecSmrgSProcRenderFreeGlyphSet (ClientPtr client)
229705b261ecSmrg{
229805b261ecSmrg    register int n;
229905b261ecSmrg    REQUEST(xRenderFreeGlyphSetReq);
230005b261ecSmrg    swaps(&stuff->length, n);
230105b261ecSmrg    swapl(&stuff->glyphset, n);
230205b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
230305b261ecSmrg}
230405b261ecSmrg
230505b261ecSmrgstatic int
230605b261ecSmrgSProcRenderAddGlyphs (ClientPtr client)
230705b261ecSmrg{
230805b261ecSmrg    register int n;
230905b261ecSmrg    register int i;
231005b261ecSmrg    CARD32  *gids;
231105b261ecSmrg    void    *end;
231205b261ecSmrg    xGlyphInfo *gi;
231305b261ecSmrg    REQUEST(xRenderAddGlyphsReq);
231405b261ecSmrg    swaps(&stuff->length, n);
231505b261ecSmrg    swapl(&stuff->glyphset, n);
231605b261ecSmrg    swapl(&stuff->nglyphs, n);
231705b261ecSmrg    if (stuff->nglyphs & 0xe0000000)
231805b261ecSmrg	return BadLength;
231905b261ecSmrg    end = (CARD8 *) stuff + (client->req_len << 2);
232005b261ecSmrg    gids = (CARD32 *) (stuff + 1);
232105b261ecSmrg    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
232205b261ecSmrg    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
232305b261ecSmrg	return BadLength;
232405b261ecSmrg    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
232505b261ecSmrg	return BadLength;
232605b261ecSmrg    for (i = 0; i < stuff->nglyphs; i++)
232705b261ecSmrg    {
232805b261ecSmrg	swapl (&gids[i], n);
232905b261ecSmrg	swaps (&gi[i].width, n);
233005b261ecSmrg	swaps (&gi[i].height, n);
233105b261ecSmrg	swaps (&gi[i].x, n);
233205b261ecSmrg	swaps (&gi[i].y, n);
233305b261ecSmrg	swaps (&gi[i].xOff, n);
233405b261ecSmrg	swaps (&gi[i].yOff, n);
233505b261ecSmrg    }
233605b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
233705b261ecSmrg}
233805b261ecSmrg
233905b261ecSmrgstatic int
234005b261ecSmrgSProcRenderAddGlyphsFromPicture (ClientPtr client)
234105b261ecSmrg{
234205b261ecSmrg    return BadImplementation;
234305b261ecSmrg}
234405b261ecSmrg
234505b261ecSmrgstatic int
234605b261ecSmrgSProcRenderFreeGlyphs (ClientPtr client)
234705b261ecSmrg{
234805b261ecSmrg    register int n;
234905b261ecSmrg    REQUEST(xRenderFreeGlyphsReq);
235005b261ecSmrg    swaps(&stuff->length, n);
235105b261ecSmrg    swapl(&stuff->glyphset, n);
235205b261ecSmrg    SwapRestL(stuff);
235305b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
235405b261ecSmrg}
235505b261ecSmrg
235605b261ecSmrgstatic int
235705b261ecSmrgSProcRenderCompositeGlyphs (ClientPtr client)
235805b261ecSmrg{
235905b261ecSmrg    register int n;
236005b261ecSmrg    xGlyphElt	*elt;
236105b261ecSmrg    CARD8	*buffer;
236205b261ecSmrg    CARD8	*end;
236305b261ecSmrg    int		space;
236405b261ecSmrg    int		i;
236505b261ecSmrg    int		size;
236605b261ecSmrg
236705b261ecSmrg    REQUEST(xRenderCompositeGlyphsReq);
236805b261ecSmrg
236905b261ecSmrg    switch (stuff->renderReqType) {
237005b261ecSmrg    default:			    size = 1; break;
237105b261ecSmrg    case X_RenderCompositeGlyphs16: size = 2; break;
237205b261ecSmrg    case X_RenderCompositeGlyphs32: size = 4; break;
237305b261ecSmrg    }
237405b261ecSmrg
237505b261ecSmrg    swaps(&stuff->length, n);
237605b261ecSmrg    swapl(&stuff->src, n);
237705b261ecSmrg    swapl(&stuff->dst, n);
237805b261ecSmrg    swapl(&stuff->maskFormat, n);
237905b261ecSmrg    swapl(&stuff->glyphset, n);
238005b261ecSmrg    swaps(&stuff->xSrc, n);
238105b261ecSmrg    swaps(&stuff->ySrc, n);
238205b261ecSmrg    buffer = (CARD8 *) (stuff + 1);
238305b261ecSmrg    end = (CARD8 *) stuff + (client->req_len << 2);
238405b261ecSmrg    while (buffer + sizeof (xGlyphElt) < end)
238505b261ecSmrg    {
238605b261ecSmrg	elt = (xGlyphElt *) buffer;
238705b261ecSmrg	buffer += sizeof (xGlyphElt);
238805b261ecSmrg
238905b261ecSmrg	swaps (&elt->deltax, n);
239005b261ecSmrg	swaps (&elt->deltay, n);
239105b261ecSmrg
239205b261ecSmrg	i = elt->len;
239305b261ecSmrg	if (i == 0xff)
239405b261ecSmrg	{
239505b261ecSmrg	    swapl (buffer, n);
239605b261ecSmrg	    buffer += 4;
239705b261ecSmrg	}
239805b261ecSmrg	else
239905b261ecSmrg	{
240005b261ecSmrg	    space = size * i;
240105b261ecSmrg	    switch (size) {
240205b261ecSmrg	    case 1:
240305b261ecSmrg		buffer += i;
240405b261ecSmrg		break;
240505b261ecSmrg	    case 2:
240605b261ecSmrg		while (i--)
240705b261ecSmrg		{
240805b261ecSmrg		    swaps (buffer, n);
240905b261ecSmrg		    buffer += 2;
241005b261ecSmrg		}
241105b261ecSmrg		break;
241205b261ecSmrg	    case 4:
241305b261ecSmrg		while (i--)
241405b261ecSmrg		{
241505b261ecSmrg		    swapl (buffer, n);
241605b261ecSmrg		    buffer += 4;
241705b261ecSmrg		}
241805b261ecSmrg		break;
241905b261ecSmrg	    }
242005b261ecSmrg	    if (space & 3)
242105b261ecSmrg		buffer += 4 - (space & 3);
242205b261ecSmrg	}
242305b261ecSmrg    }
242405b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
242505b261ecSmrg}
242605b261ecSmrg
242705b261ecSmrgstatic int
242805b261ecSmrgSProcRenderFillRectangles (ClientPtr client)
242905b261ecSmrg{
243005b261ecSmrg    register int n;
243105b261ecSmrg    REQUEST(xRenderFillRectanglesReq);
243205b261ecSmrg
243305b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
243405b261ecSmrg    swaps(&stuff->length, n);
243505b261ecSmrg    swapl(&stuff->dst, n);
243605b261ecSmrg    swaps(&stuff->color.red, n);
243705b261ecSmrg    swaps(&stuff->color.green, n);
243805b261ecSmrg    swaps(&stuff->color.blue, n);
243905b261ecSmrg    swaps(&stuff->color.alpha, n);
244005b261ecSmrg    SwapRestS(stuff);
244105b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
244205b261ecSmrg}
244305b261ecSmrg
244405b261ecSmrgstatic int
244505b261ecSmrgSProcRenderCreateCursor (ClientPtr client)
244605b261ecSmrg{
244705b261ecSmrg    register int n;
244805b261ecSmrg    REQUEST(xRenderCreateCursorReq);
244905b261ecSmrg    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
245005b261ecSmrg
245105b261ecSmrg    swaps(&stuff->length, n);
245205b261ecSmrg    swapl(&stuff->cid, n);
245305b261ecSmrg    swapl(&stuff->src, n);
245405b261ecSmrg    swaps(&stuff->x, n);
245505b261ecSmrg    swaps(&stuff->y, n);
245605b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
245705b261ecSmrg}
245805b261ecSmrg
245905b261ecSmrgstatic int
246005b261ecSmrgSProcRenderSetPictureTransform (ClientPtr client)
246105b261ecSmrg{
246205b261ecSmrg    register int n;
246305b261ecSmrg    REQUEST(xRenderSetPictureTransformReq);
246405b261ecSmrg    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
246505b261ecSmrg
246605b261ecSmrg    swaps(&stuff->length, n);
246705b261ecSmrg    swapl(&stuff->picture, n);
246805b261ecSmrg    swapl(&stuff->transform.matrix11, n);
246905b261ecSmrg    swapl(&stuff->transform.matrix12, n);
247005b261ecSmrg    swapl(&stuff->transform.matrix13, n);
247105b261ecSmrg    swapl(&stuff->transform.matrix21, n);
247205b261ecSmrg    swapl(&stuff->transform.matrix22, n);
247305b261ecSmrg    swapl(&stuff->transform.matrix23, n);
247405b261ecSmrg    swapl(&stuff->transform.matrix31, n);
247505b261ecSmrg    swapl(&stuff->transform.matrix32, n);
247605b261ecSmrg    swapl(&stuff->transform.matrix33, n);
247705b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
247805b261ecSmrg}
247905b261ecSmrg
248005b261ecSmrgstatic int
248105b261ecSmrgSProcRenderQueryFilters (ClientPtr client)
248205b261ecSmrg{
248305b261ecSmrg    register int n;
248405b261ecSmrg    REQUEST (xRenderQueryFiltersReq);
248505b261ecSmrg    REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
248605b261ecSmrg
248705b261ecSmrg    swaps(&stuff->length, n);
248805b261ecSmrg    swapl(&stuff->drawable, n);
248905b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
249005b261ecSmrg}
249105b261ecSmrg
249205b261ecSmrgstatic int
249305b261ecSmrgSProcRenderSetPictureFilter (ClientPtr client)
249405b261ecSmrg{
249505b261ecSmrg    register int n;
249605b261ecSmrg    REQUEST (xRenderSetPictureFilterReq);
249705b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
249805b261ecSmrg
249905b261ecSmrg    swaps(&stuff->length, n);
250005b261ecSmrg    swapl(&stuff->picture, n);
250105b261ecSmrg    swaps(&stuff->nbytes, n);
250205b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
250305b261ecSmrg}
250405b261ecSmrg
250505b261ecSmrgstatic int
250605b261ecSmrgSProcRenderCreateAnimCursor (ClientPtr client)
250705b261ecSmrg{
250805b261ecSmrg    register int n;
250905b261ecSmrg    REQUEST (xRenderCreateAnimCursorReq);
251005b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
251105b261ecSmrg
251205b261ecSmrg    swaps(&stuff->length, n);
251305b261ecSmrg    swapl(&stuff->cid, n);
251405b261ecSmrg    SwapRestL(stuff);
251505b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
251605b261ecSmrg}
251705b261ecSmrg
251805b261ecSmrgstatic int
251905b261ecSmrgSProcRenderAddTraps (ClientPtr client)
252005b261ecSmrg{
252105b261ecSmrg    register int n;
252205b261ecSmrg    REQUEST (xRenderAddTrapsReq);
252305b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
252405b261ecSmrg
252505b261ecSmrg    swaps(&stuff->length, n);
252605b261ecSmrg    swapl(&stuff->picture, n);
252705b261ecSmrg    swaps(&stuff->xOff, n);
252805b261ecSmrg    swaps(&stuff->yOff, n);
252905b261ecSmrg    SwapRestL(stuff);
253005b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
253105b261ecSmrg}
253205b261ecSmrg
253305b261ecSmrgstatic int
253405b261ecSmrgSProcRenderCreateSolidFill(ClientPtr client)
253505b261ecSmrg{
253605b261ecSmrg    register int n;
253705b261ecSmrg    REQUEST (xRenderCreateSolidFillReq);
253805b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
253905b261ecSmrg
254005b261ecSmrg    swaps(&stuff->length, n);
254105b261ecSmrg    swapl(&stuff->pid, n);
254205b261ecSmrg    swaps(&stuff->color.alpha, n);
254305b261ecSmrg    swaps(&stuff->color.red, n);
254405b261ecSmrg    swaps(&stuff->color.green, n);
254505b261ecSmrg    swaps(&stuff->color.blue, n);
254605b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
254705b261ecSmrg}
254805b261ecSmrg
254905b261ecSmrgstatic void swapStops(void *stuff, int num)
255005b261ecSmrg{
255105b261ecSmrg    int i, n;
255205b261ecSmrg    CARD32 *stops;
255305b261ecSmrg    CARD16 *colors;
255405b261ecSmrg    stops = (CARD32 *)(stuff);
255505b261ecSmrg    for (i = 0; i < num; ++i) {
255605b261ecSmrg        swapl(stops, n);
255705b261ecSmrg        ++stops;
255805b261ecSmrg    }
255905b261ecSmrg    colors = (CARD16 *)(stops);
256005b261ecSmrg    for (i = 0; i < 4*num; ++i) {
25618223e2f2Smrg        swaps(colors, n);
25628223e2f2Smrg        ++colors;
256305b261ecSmrg    }
256405b261ecSmrg}
256505b261ecSmrg
256605b261ecSmrgstatic int
256705b261ecSmrgSProcRenderCreateLinearGradient (ClientPtr client)
256805b261ecSmrg{
256905b261ecSmrg    register int n;
257005b261ecSmrg    int len;
257105b261ecSmrg    REQUEST (xRenderCreateLinearGradientReq);
257205b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
257305b261ecSmrg
257405b261ecSmrg    swaps(&stuff->length, n);
257505b261ecSmrg    swapl(&stuff->pid, n);
257605b261ecSmrg    swapl(&stuff->p1.x, n);
257705b261ecSmrg    swapl(&stuff->p1.y, n);
257805b261ecSmrg    swapl(&stuff->p2.x, n);
257905b261ecSmrg    swapl(&stuff->p2.y, n);
258005b261ecSmrg    swapl(&stuff->nStops, n);
258105b261ecSmrg
258205b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
258305b261ecSmrg    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
258405b261ecSmrg	return BadLength;
258505b261ecSmrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
258605b261ecSmrg        return BadLength;
258705b261ecSmrg
258805b261ecSmrg    swapStops(stuff+1, stuff->nStops);
258905b261ecSmrg
259005b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
259105b261ecSmrg}
259205b261ecSmrg
259305b261ecSmrgstatic int
259405b261ecSmrgSProcRenderCreateRadialGradient (ClientPtr client)
259505b261ecSmrg{
259605b261ecSmrg    register int n;
259705b261ecSmrg    int len;
259805b261ecSmrg    REQUEST (xRenderCreateRadialGradientReq);
259905b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
260005b261ecSmrg
260105b261ecSmrg    swaps(&stuff->length, n);
260205b261ecSmrg    swapl(&stuff->pid, n);
260305b261ecSmrg    swapl(&stuff->inner.x, n);
260405b261ecSmrg    swapl(&stuff->inner.y, n);
260505b261ecSmrg    swapl(&stuff->outer.x, n);
260605b261ecSmrg    swapl(&stuff->outer.y, n);
260705b261ecSmrg    swapl(&stuff->inner_radius, n);
260805b261ecSmrg    swapl(&stuff->outer_radius, n);
260905b261ecSmrg    swapl(&stuff->nStops, n);
261005b261ecSmrg
261105b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
261205b261ecSmrg    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
261305b261ecSmrg	return BadLength;
261405b261ecSmrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
261505b261ecSmrg        return BadLength;
261605b261ecSmrg
261705b261ecSmrg    swapStops(stuff+1, stuff->nStops);
261805b261ecSmrg
261905b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
262005b261ecSmrg}
262105b261ecSmrg
262205b261ecSmrgstatic int
262305b261ecSmrgSProcRenderCreateConicalGradient (ClientPtr client)
262405b261ecSmrg{
262505b261ecSmrg    register int n;
262605b261ecSmrg    int len;
262705b261ecSmrg    REQUEST (xRenderCreateConicalGradientReq);
262805b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
262905b261ecSmrg
263005b261ecSmrg    swaps(&stuff->length, n);
263105b261ecSmrg    swapl(&stuff->pid, n);
263205b261ecSmrg    swapl(&stuff->center.x, n);
263305b261ecSmrg    swapl(&stuff->center.y, n);
263405b261ecSmrg    swapl(&stuff->angle, n);
263505b261ecSmrg    swapl(&stuff->nStops, n);
263605b261ecSmrg
263705b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
263805b261ecSmrg    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
263905b261ecSmrg	return BadLength;
264005b261ecSmrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
264105b261ecSmrg        return BadLength;
264205b261ecSmrg
264305b261ecSmrg    swapStops(stuff+1, stuff->nStops);
264405b261ecSmrg
264505b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
264605b261ecSmrg}
264705b261ecSmrg
264805b261ecSmrgstatic int
264905b261ecSmrgSProcRenderDispatch (ClientPtr client)
265005b261ecSmrg{
265105b261ecSmrg    REQUEST(xReq);
265205b261ecSmrg
265305b261ecSmrg    if (stuff->data < RenderNumberRequests)
265405b261ecSmrg	return (*SProcRenderVector[stuff->data]) (client);
265505b261ecSmrg    else
265605b261ecSmrg	return BadRequest;
265705b261ecSmrg}
265805b261ecSmrg
265905b261ecSmrg#ifdef PANORAMIX
26606747b715Smrg#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\
26616747b715Smrg    int rc = dixLookupResourceByType((pointer *)&(pPicture), pid,\
26626747b715Smrg                                     XRT_PICTURE, client, mode);\
26636747b715Smrg    if (rc != Success)\
26646747b715Smrg	return rc;\
266505b261ecSmrg}
266605b261ecSmrg
26676747b715Smrg#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\
266805b261ecSmrg    if (pid == None) \
266905b261ecSmrg	pPicture = 0; \
267005b261ecSmrg    else { \
26716747b715Smrg	VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \
267205b261ecSmrg    } \
267305b261ecSmrg} \
267405b261ecSmrg
267505b261ecSmrgint	    (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
267605b261ecSmrg
267705b261ecSmrgstatic int
267805b261ecSmrgPanoramiXRenderCreatePicture (ClientPtr client)
267905b261ecSmrg{
268005b261ecSmrg    REQUEST(xRenderCreatePictureReq);
268105b261ecSmrg    PanoramiXRes    *refDraw, *newPict;
26826747b715Smrg    int		    result, j;
268305b261ecSmrg
268405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
26856747b715Smrg    result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable,
26866747b715Smrg				      XRC_DRAWABLE, client, DixWriteAccess);
26876747b715Smrg    if (result != Success)
26886747b715Smrg	return (result == BadValue) ? BadDrawable : result;
26896747b715Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
269005b261ecSmrg	return BadAlloc;
269105b261ecSmrg    newPict->type = XRT_PICTURE;
269205b261ecSmrg    newPict->info[0].id = stuff->pid;
269305b261ecSmrg
269405b261ecSmrg    if (refDraw->type == XRT_WINDOW &&
26956747b715Smrg	stuff->drawable == screenInfo.screens[0]->root->drawable.id)
269605b261ecSmrg    {
269705b261ecSmrg	newPict->u.pict.root = TRUE;
269805b261ecSmrg    }
269905b261ecSmrg    else
270005b261ecSmrg	newPict->u.pict.root = FALSE;
270105b261ecSmrg
270205b261ecSmrg    for(j = 1; j < PanoramiXNumScreens; j++)
270305b261ecSmrg	newPict->info[j].id = FakeClientID(client->index);
270405b261ecSmrg
270505b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
270605b261ecSmrg	stuff->pid = newPict->info[j].id;
270705b261ecSmrg	stuff->drawable = refDraw->info[j].id;
270805b261ecSmrg	result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
270905b261ecSmrg	if(result != Success) break;
271005b261ecSmrg    }
271105b261ecSmrg
271205b261ecSmrg    if (result == Success)
271305b261ecSmrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
271405b261ecSmrg    else
27156747b715Smrg	free(newPict);
271605b261ecSmrg
27176747b715Smrg    return result;
271805b261ecSmrg}
271905b261ecSmrg
272005b261ecSmrgstatic int
272105b261ecSmrgPanoramiXRenderChangePicture (ClientPtr client)
272205b261ecSmrg{
272305b261ecSmrg    PanoramiXRes    *pict;
272405b261ecSmrg    int		    result = Success, j;
272505b261ecSmrg    REQUEST(xRenderChangePictureReq);
272605b261ecSmrg
27276747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
272805b261ecSmrg
27296747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
273005b261ecSmrg
273105b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
273205b261ecSmrg        stuff->picture = pict->info[j].id;
273305b261ecSmrg        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
273405b261ecSmrg        if(result != Success) break;
273505b261ecSmrg    }
273605b261ecSmrg
27376747b715Smrg    return result;
273805b261ecSmrg}
273905b261ecSmrg
274005b261ecSmrgstatic int
274105b261ecSmrgPanoramiXRenderSetPictureClipRectangles (ClientPtr client)
274205b261ecSmrg{
274305b261ecSmrg    REQUEST(xRenderSetPictureClipRectanglesReq);
274405b261ecSmrg    int		    result = Success, j;
274505b261ecSmrg    PanoramiXRes    *pict;
274605b261ecSmrg
274705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
274805b261ecSmrg
27496747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
275005b261ecSmrg
275105b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
275205b261ecSmrg        stuff->picture = pict->info[j].id;
275305b261ecSmrg        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
275405b261ecSmrg        if(result != Success) break;
275505b261ecSmrg    }
275605b261ecSmrg
27576747b715Smrg    return result;
275805b261ecSmrg}
275905b261ecSmrg
276005b261ecSmrgstatic int
276105b261ecSmrgPanoramiXRenderSetPictureTransform (ClientPtr client)
276205b261ecSmrg{
276305b261ecSmrg    REQUEST(xRenderSetPictureTransformReq);
276405b261ecSmrg    int		    result = Success, j;
276505b261ecSmrg    PanoramiXRes    *pict;
276605b261ecSmrg
276705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
276805b261ecSmrg
27696747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
277005b261ecSmrg
277105b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
277205b261ecSmrg        stuff->picture = pict->info[j].id;
277305b261ecSmrg        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
277405b261ecSmrg        if(result != Success) break;
277505b261ecSmrg    }
277605b261ecSmrg
27776747b715Smrg    return result;
277805b261ecSmrg}
277905b261ecSmrg
278005b261ecSmrgstatic int
278105b261ecSmrgPanoramiXRenderSetPictureFilter (ClientPtr client)
278205b261ecSmrg{
278305b261ecSmrg    REQUEST(xRenderSetPictureFilterReq);
278405b261ecSmrg    int		    result = Success, j;
278505b261ecSmrg    PanoramiXRes    *pict;
278605b261ecSmrg
278705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
278805b261ecSmrg
27896747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
279005b261ecSmrg
279105b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
279205b261ecSmrg        stuff->picture = pict->info[j].id;
279305b261ecSmrg        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
279405b261ecSmrg        if(result != Success) break;
279505b261ecSmrg    }
279605b261ecSmrg
27976747b715Smrg    return result;
279805b261ecSmrg}
279905b261ecSmrg
280005b261ecSmrgstatic int
280105b261ecSmrgPanoramiXRenderFreePicture (ClientPtr client)
280205b261ecSmrg{
280305b261ecSmrg    PanoramiXRes *pict;
280405b261ecSmrg    int         result = Success, j;
280505b261ecSmrg    REQUEST(xRenderFreePictureReq);
280605b261ecSmrg
280705b261ecSmrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
280805b261ecSmrg
280905b261ecSmrg    client->errorValue = stuff->picture;
281005b261ecSmrg
28116747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess);
281205b261ecSmrg
281305b261ecSmrg
281405b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
281505b261ecSmrg	stuff->picture = pict->info[j].id;
281605b261ecSmrg	result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
281705b261ecSmrg	if(result != Success) break;
281805b261ecSmrg    }
281905b261ecSmrg
282005b261ecSmrg    /* Since ProcRenderFreePicture is using FreeResource, it will free
282105b261ecSmrg	our resource for us on the last pass through the loop above */
282205b261ecSmrg
28236747b715Smrg    return result;
282405b261ecSmrg}
282505b261ecSmrg
282605b261ecSmrgstatic int
282705b261ecSmrgPanoramiXRenderComposite (ClientPtr client)
282805b261ecSmrg{
282905b261ecSmrg    PanoramiXRes	*src, *msk, *dst;
283005b261ecSmrg    int			result = Success, j;
283105b261ecSmrg    xRenderCompositeReq	orig;
283205b261ecSmrg    REQUEST(xRenderCompositeReq);
283305b261ecSmrg
283405b261ecSmrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
283505b261ecSmrg
28366747b715Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
28376747b715Smrg    VERIFY_XIN_ALPHA (msk, stuff->mask, client, DixReadAccess);
28386747b715Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
283905b261ecSmrg
284005b261ecSmrg    orig = *stuff;
284105b261ecSmrg
284205b261ecSmrg    FOR_NSCREENS_FORWARD(j) {
284305b261ecSmrg	stuff->src = src->info[j].id;
284405b261ecSmrg	if (src->u.pict.root)
284505b261ecSmrg	{
28466747b715Smrg	    stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x;
28476747b715Smrg	    stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y;
284805b261ecSmrg	}
284905b261ecSmrg	stuff->dst = dst->info[j].id;
285005b261ecSmrg	if (dst->u.pict.root)
285105b261ecSmrg	{
28526747b715Smrg	    stuff->xDst = orig.xDst - screenInfo.screens[j]->x;
28536747b715Smrg	    stuff->yDst = orig.yDst - screenInfo.screens[j]->y;
285405b261ecSmrg	}
285505b261ecSmrg	if (msk)
285605b261ecSmrg	{
285705b261ecSmrg	    stuff->mask = msk->info[j].id;
285805b261ecSmrg	    if (msk->u.pict.root)
285905b261ecSmrg	    {
28606747b715Smrg		stuff->xMask = orig.xMask - screenInfo.screens[j]->x;
28616747b715Smrg		stuff->yMask = orig.yMask - screenInfo.screens[j]->y;
286205b261ecSmrg	    }
286305b261ecSmrg	}
286405b261ecSmrg	result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
286505b261ecSmrg	if(result != Success) break;
286605b261ecSmrg    }
286705b261ecSmrg
286805b261ecSmrg    return result;
286905b261ecSmrg}
287005b261ecSmrg
287105b261ecSmrgstatic int
287205b261ecSmrgPanoramiXRenderCompositeGlyphs (ClientPtr client)
287305b261ecSmrg{
287405b261ecSmrg    PanoramiXRes    *src, *dst;
287505b261ecSmrg    int		    result = Success, j;
287605b261ecSmrg    REQUEST(xRenderCompositeGlyphsReq);
287705b261ecSmrg    xGlyphElt	    origElt, *elt;
287805b261ecSmrg    INT16	    xSrc, ySrc;
287905b261ecSmrg
288005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
28816747b715Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
28826747b715Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
288305b261ecSmrg
288405b261ecSmrg    if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
288505b261ecSmrg				 sizeof (xGlyphElt)))
288605b261ecSmrg    {
288705b261ecSmrg	elt = (xGlyphElt *) (stuff + 1);
288805b261ecSmrg	origElt = *elt;
288905b261ecSmrg	xSrc = stuff->xSrc;
289005b261ecSmrg	ySrc = stuff->ySrc;
289105b261ecSmrg	FOR_NSCREENS_FORWARD(j) {
289205b261ecSmrg	    stuff->src = src->info[j].id;
289305b261ecSmrg	    if (src->u.pict.root)
289405b261ecSmrg	    {
28956747b715Smrg		stuff->xSrc = xSrc - screenInfo.screens[j]->x;
28966747b715Smrg		stuff->ySrc = ySrc - screenInfo.screens[j]->y;
289705b261ecSmrg	    }
289805b261ecSmrg	    stuff->dst = dst->info[j].id;
289905b261ecSmrg	    if (dst->u.pict.root)
290005b261ecSmrg	    {
29016747b715Smrg		elt->deltax = origElt.deltax - screenInfo.screens[j]->x;
29026747b715Smrg		elt->deltay = origElt.deltay - screenInfo.screens[j]->y;
290305b261ecSmrg	    }
290405b261ecSmrg	    result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
290505b261ecSmrg	    if(result != Success) break;
290605b261ecSmrg	}
290705b261ecSmrg    }
290805b261ecSmrg
290905b261ecSmrg    return result;
291005b261ecSmrg}
291105b261ecSmrg
291205b261ecSmrgstatic int
291305b261ecSmrgPanoramiXRenderFillRectangles (ClientPtr client)
291405b261ecSmrg{
291505b261ecSmrg    PanoramiXRes    *dst;
291605b261ecSmrg    int		    result = Success, j;
291705b261ecSmrg    REQUEST(xRenderFillRectanglesReq);
291805b261ecSmrg    char	    *extra;
291905b261ecSmrg    int		    extra_len;
292005b261ecSmrg
292105b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
29226747b715Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
292305b261ecSmrg    extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
292405b261ecSmrg    if (extra_len &&
29256747b715Smrg	(extra = (char *) malloc(extra_len)))
292605b261ecSmrg    {
292705b261ecSmrg	memcpy (extra, stuff + 1, extra_len);
292805b261ecSmrg	FOR_NSCREENS_FORWARD(j) {
292905b261ecSmrg	    if (j) memcpy (stuff + 1, extra, extra_len);
293005b261ecSmrg	    if (dst->u.pict.root)
293105b261ecSmrg	    {
29326747b715Smrg		int x_off = screenInfo.screens[j]->x;
29336747b715Smrg		int y_off = screenInfo.screens[j]->y;
293405b261ecSmrg
293505b261ecSmrg		if(x_off || y_off) {
293605b261ecSmrg		    xRectangle	*rects = (xRectangle *) (stuff + 1);
293705b261ecSmrg		    int		i = extra_len / sizeof (xRectangle);
293805b261ecSmrg
293905b261ecSmrg		    while (i--)
294005b261ecSmrg		    {
294105b261ecSmrg			rects->x -= x_off;
294205b261ecSmrg			rects->y -= y_off;
294305b261ecSmrg			rects++;
294405b261ecSmrg		    }
294505b261ecSmrg		}
294605b261ecSmrg	    }
294705b261ecSmrg	    stuff->dst = dst->info[j].id;
294805b261ecSmrg	    result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
294905b261ecSmrg	    if(result != Success) break;
295005b261ecSmrg	}
29516747b715Smrg	free(extra);
295205b261ecSmrg    }
295305b261ecSmrg
295405b261ecSmrg    return result;
295505b261ecSmrg}
295605b261ecSmrg
295705b261ecSmrgstatic int
295805b261ecSmrgPanoramiXRenderTrapezoids(ClientPtr client)
295905b261ecSmrg{
296005b261ecSmrg    PanoramiXRes        *src, *dst;
296105b261ecSmrg    int                 result = Success, j;
296205b261ecSmrg    REQUEST(xRenderTrapezoidsReq);
296305b261ecSmrg    char		*extra;
296405b261ecSmrg    int			extra_len;
296505b261ecSmrg
296605b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
296705b261ecSmrg
29686747b715Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
29696747b715Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
297005b261ecSmrg
297105b261ecSmrg    extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
297205b261ecSmrg
297305b261ecSmrg    if (extra_len &&
29746747b715Smrg	(extra = (char *) malloc(extra_len))) {
297505b261ecSmrg	memcpy (extra, stuff + 1, extra_len);
297605b261ecSmrg
297705b261ecSmrg	FOR_NSCREENS_FORWARD(j) {
297805b261ecSmrg	    if (j) memcpy (stuff + 1, extra, extra_len);
297905b261ecSmrg	    if (dst->u.pict.root) {
29806747b715Smrg		int x_off = screenInfo.screens[j]->x;
29816747b715Smrg		int y_off = screenInfo.screens[j]->y;
298205b261ecSmrg
298305b261ecSmrg		if(x_off || y_off) {
298405b261ecSmrg                    xTrapezoid  *trap = (xTrapezoid *) (stuff + 1);
298505b261ecSmrg		    int         i = extra_len / sizeof (xTrapezoid);
298605b261ecSmrg
298705b261ecSmrg		    while (i--) {
298805b261ecSmrg			trap->top -= y_off;
298905b261ecSmrg			trap->bottom -= y_off;
299005b261ecSmrg			trap->left.p1.x -= x_off;
299105b261ecSmrg			trap->left.p1.y -= y_off;
299205b261ecSmrg			trap->left.p2.x -= x_off;
299305b261ecSmrg			trap->left.p2.y -= y_off;
299405b261ecSmrg			trap->right.p1.x -= x_off;
299505b261ecSmrg			trap->right.p1.y -= y_off;
299605b261ecSmrg			trap->right.p2.x -= x_off;
299705b261ecSmrg			trap->right.p2.y -= y_off;
299805b261ecSmrg			trap++;
299905b261ecSmrg		    }
300005b261ecSmrg		}
300105b261ecSmrg	    }
300205b261ecSmrg
300305b261ecSmrg            stuff->src = src->info[j].id;
300405b261ecSmrg            stuff->dst = dst->info[j].id;
300505b261ecSmrg	    result =
300605b261ecSmrg		(*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
300705b261ecSmrg
300805b261ecSmrg	    if(result != Success) break;
300905b261ecSmrg	}
301005b261ecSmrg
30116747b715Smrg        free(extra);
301205b261ecSmrg    }
301305b261ecSmrg
301405b261ecSmrg    return result;
301505b261ecSmrg}
301605b261ecSmrg
301705b261ecSmrgstatic int
301805b261ecSmrgPanoramiXRenderTriangles(ClientPtr client)
301905b261ecSmrg{
302005b261ecSmrg    PanoramiXRes        *src, *dst;
302105b261ecSmrg    int                 result = Success, j;
302205b261ecSmrg    REQUEST(xRenderTrianglesReq);
302305b261ecSmrg    char		*extra;
302405b261ecSmrg    int			extra_len;
302505b261ecSmrg
302605b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
302705b261ecSmrg
30286747b715Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
30296747b715Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
303005b261ecSmrg
303105b261ecSmrg    extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
303205b261ecSmrg
303305b261ecSmrg    if (extra_len &&
30346747b715Smrg	(extra = (char *) malloc(extra_len))) {
303505b261ecSmrg	memcpy (extra, stuff + 1, extra_len);
303605b261ecSmrg
303705b261ecSmrg	FOR_NSCREENS_FORWARD(j) {
303805b261ecSmrg	    if (j) memcpy (stuff + 1, extra, extra_len);
303905b261ecSmrg	    if (dst->u.pict.root) {
30406747b715Smrg		int x_off = screenInfo.screens[j]->x;
30416747b715Smrg		int y_off = screenInfo.screens[j]->y;
304205b261ecSmrg
304305b261ecSmrg		if(x_off || y_off) {
304405b261ecSmrg                    xTriangle  *tri = (xTriangle *) (stuff + 1);
304505b261ecSmrg		    int         i = extra_len / sizeof (xTriangle);
304605b261ecSmrg
304705b261ecSmrg		    while (i--) {
304805b261ecSmrg			tri->p1.x -= x_off;
304905b261ecSmrg			tri->p1.y -= y_off;
305005b261ecSmrg			tri->p2.x -= x_off;
305105b261ecSmrg			tri->p2.y -= y_off;
305205b261ecSmrg			tri->p3.x -= x_off;
305305b261ecSmrg			tri->p3.y -= y_off;
305405b261ecSmrg			tri++;
305505b261ecSmrg		    }
305605b261ecSmrg		}
305705b261ecSmrg	    }
305805b261ecSmrg
305905b261ecSmrg            stuff->src = src->info[j].id;
306005b261ecSmrg            stuff->dst = dst->info[j].id;
306105b261ecSmrg	    result =
306205b261ecSmrg		(*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
306305b261ecSmrg
306405b261ecSmrg	    if(result != Success) break;
306505b261ecSmrg	}
306605b261ecSmrg
30676747b715Smrg        free(extra);
306805b261ecSmrg    }
306905b261ecSmrg
307005b261ecSmrg    return result;
307105b261ecSmrg}
307205b261ecSmrg
307305b261ecSmrgstatic int
307405b261ecSmrgPanoramiXRenderTriStrip(ClientPtr client)
307505b261ecSmrg{
307605b261ecSmrg    PanoramiXRes        *src, *dst;
307705b261ecSmrg    int                 result = Success, j;
307805b261ecSmrg    REQUEST(xRenderTriStripReq);
307905b261ecSmrg    char		*extra;
308005b261ecSmrg    int			extra_len;
308105b261ecSmrg
308205b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
308305b261ecSmrg
30846747b715Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
30856747b715Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
308605b261ecSmrg
308705b261ecSmrg    extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
308805b261ecSmrg
308905b261ecSmrg    if (extra_len &&
30906747b715Smrg	(extra = (char *) malloc(extra_len))) {
309105b261ecSmrg	memcpy (extra, stuff + 1, extra_len);
309205b261ecSmrg
309305b261ecSmrg	FOR_NSCREENS_FORWARD(j) {
309405b261ecSmrg	    if (j) memcpy (stuff + 1, extra, extra_len);
309505b261ecSmrg	    if (dst->u.pict.root) {
30966747b715Smrg		int x_off = screenInfo.screens[j]->x;
30976747b715Smrg		int y_off = screenInfo.screens[j]->y;
309805b261ecSmrg
309905b261ecSmrg		if(x_off || y_off) {
310005b261ecSmrg                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
310105b261ecSmrg		    int         i = extra_len / sizeof (xPointFixed);
310205b261ecSmrg
310305b261ecSmrg		    while (i--) {
310405b261ecSmrg			fixed->x -= x_off;
310505b261ecSmrg			fixed->y -= y_off;
310605b261ecSmrg			fixed++;
310705b261ecSmrg		    }
310805b261ecSmrg		}
310905b261ecSmrg	    }
311005b261ecSmrg
311105b261ecSmrg            stuff->src = src->info[j].id;
311205b261ecSmrg            stuff->dst = dst->info[j].id;
311305b261ecSmrg	    result =
311405b261ecSmrg		(*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
311505b261ecSmrg
311605b261ecSmrg	    if(result != Success) break;
311705b261ecSmrg	}
311805b261ecSmrg
31196747b715Smrg        free(extra);
312005b261ecSmrg    }
312105b261ecSmrg
312205b261ecSmrg    return result;
312305b261ecSmrg}
312405b261ecSmrg
312505b261ecSmrgstatic int
312605b261ecSmrgPanoramiXRenderTriFan(ClientPtr client)
312705b261ecSmrg{
312805b261ecSmrg    PanoramiXRes        *src, *dst;
312905b261ecSmrg    int                 result = Success, j;
313005b261ecSmrg    REQUEST(xRenderTriFanReq);
313105b261ecSmrg    char		*extra;
313205b261ecSmrg    int			extra_len;
313305b261ecSmrg
313405b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
313505b261ecSmrg
31366747b715Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
31376747b715Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
313805b261ecSmrg
313905b261ecSmrg    extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
314005b261ecSmrg
314105b261ecSmrg    if (extra_len &&
31426747b715Smrg	(extra = (char *) malloc(extra_len))) {
314305b261ecSmrg	memcpy (extra, stuff + 1, extra_len);
314405b261ecSmrg
314505b261ecSmrg	FOR_NSCREENS_FORWARD(j) {
314605b261ecSmrg	    if (j) memcpy (stuff + 1, extra, extra_len);
314705b261ecSmrg	    if (dst->u.pict.root) {
31486747b715Smrg		int x_off = screenInfo.screens[j]->x;
31496747b715Smrg		int y_off = screenInfo.screens[j]->y;
315005b261ecSmrg
315105b261ecSmrg		if(x_off || y_off) {
315205b261ecSmrg                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
315305b261ecSmrg		    int         i = extra_len / sizeof (xPointFixed);
315405b261ecSmrg
315505b261ecSmrg		    while (i--) {
315605b261ecSmrg			fixed->x -= x_off;
315705b261ecSmrg			fixed->y -= y_off;
315805b261ecSmrg			fixed++;
315905b261ecSmrg		    }
316005b261ecSmrg		}
316105b261ecSmrg	    }
316205b261ecSmrg
316305b261ecSmrg            stuff->src = src->info[j].id;
316405b261ecSmrg            stuff->dst = dst->info[j].id;
316505b261ecSmrg	    result =
316605b261ecSmrg		(*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
316705b261ecSmrg
316805b261ecSmrg	    if(result != Success) break;
316905b261ecSmrg	}
317005b261ecSmrg
31716747b715Smrg        free(extra);
317205b261ecSmrg    }
317305b261ecSmrg
317405b261ecSmrg    return result;
317505b261ecSmrg}
317605b261ecSmrg
317705b261ecSmrgstatic int
317805b261ecSmrgPanoramiXRenderAddTraps (ClientPtr client)
317905b261ecSmrg{
318005b261ecSmrg    PanoramiXRes    *picture;
318105b261ecSmrg    int		    result = Success, j;
318205b261ecSmrg    REQUEST(xRenderAddTrapsReq);
318305b261ecSmrg    char	    *extra;
318405b261ecSmrg    int		    extra_len;
318505b261ecSmrg    INT16    	    x_off, y_off;
318605b261ecSmrg
318705b261ecSmrg    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
31886747b715Smrg    VERIFY_XIN_PICTURE (picture, stuff->picture, client, DixWriteAccess);
318905b261ecSmrg    extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
319005b261ecSmrg    if (extra_len &&
31916747b715Smrg	(extra = (char *) malloc(extra_len)))
319205b261ecSmrg    {
319305b261ecSmrg	memcpy (extra, stuff + 1, extra_len);
319405b261ecSmrg	x_off = stuff->xOff;
319505b261ecSmrg	y_off = stuff->yOff;
319605b261ecSmrg	FOR_NSCREENS_FORWARD(j) {
319705b261ecSmrg	    if (j) memcpy (stuff + 1, extra, extra_len);
319805b261ecSmrg	    stuff->picture = picture->info[j].id;
319905b261ecSmrg
320005b261ecSmrg	    if (picture->u.pict.root)
320105b261ecSmrg	    {
32026747b715Smrg		stuff->xOff = x_off + screenInfo.screens[j]->x;
32036747b715Smrg		stuff->yOff = y_off + screenInfo.screens[j]->y;
320405b261ecSmrg	    }
320505b261ecSmrg	    result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
320605b261ecSmrg	    if(result != Success) break;
320705b261ecSmrg	}
32086747b715Smrg	free(extra);
32096747b715Smrg    }
32106747b715Smrg
32116747b715Smrg    return result;
32126747b715Smrg}
32136747b715Smrg
32146747b715Smrgstatic int
32156747b715SmrgPanoramiXRenderCreateSolidFill (ClientPtr client)
32166747b715Smrg{
32176747b715Smrg    REQUEST(xRenderCreateSolidFillReq);
32186747b715Smrg    PanoramiXRes    *newPict;
32196747b715Smrg    int		    result = Success, j;
32206747b715Smrg
32216747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
32226747b715Smrg
32236747b715Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
32246747b715Smrg	return BadAlloc;
32256747b715Smrg
32266747b715Smrg    newPict->type = XRT_PICTURE;
32276747b715Smrg    newPict->info[0].id = stuff->pid;
32286747b715Smrg    newPict->u.pict.root = FALSE;
32296747b715Smrg
32306747b715Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
32316747b715Smrg	newPict->info[j].id = FakeClientID(client->index);
32326747b715Smrg
32336747b715Smrg    FOR_NSCREENS_BACKWARD(j) {
32346747b715Smrg	stuff->pid = newPict->info[j].id;
32356747b715Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client);
32366747b715Smrg	if(result != Success) break;
32376747b715Smrg    }
32386747b715Smrg
32396747b715Smrg    if (result == Success)
32406747b715Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
32416747b715Smrg    else
32426747b715Smrg	free(newPict);
32436747b715Smrg
32446747b715Smrg    return result;
32456747b715Smrg}
32466747b715Smrg
32476747b715Smrgstatic int
32486747b715SmrgPanoramiXRenderCreateLinearGradient (ClientPtr client)
32496747b715Smrg{
32506747b715Smrg    REQUEST(xRenderCreateLinearGradientReq);
32516747b715Smrg    PanoramiXRes    *newPict;
32526747b715Smrg    int		    result = Success, j;
32536747b715Smrg
32546747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
32556747b715Smrg
32566747b715Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
32576747b715Smrg	return BadAlloc;
32586747b715Smrg
32596747b715Smrg    newPict->type = XRT_PICTURE;
32606747b715Smrg    newPict->info[0].id = stuff->pid;
32616747b715Smrg    newPict->u.pict.root = FALSE;
32626747b715Smrg
32636747b715Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
32646747b715Smrg	newPict->info[j].id = FakeClientID(client->index);
32656747b715Smrg
32666747b715Smrg    FOR_NSCREENS_BACKWARD(j) {
32676747b715Smrg	stuff->pid = newPict->info[j].id;
32686747b715Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client);
32696747b715Smrg	if(result != Success) break;
327005b261ecSmrg    }
327105b261ecSmrg
32726747b715Smrg    if (result == Success)
32736747b715Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
32746747b715Smrg    else
32756747b715Smrg	free(newPict);
32766747b715Smrg
32776747b715Smrg    return result;
32786747b715Smrg}
32796747b715Smrg
32806747b715Smrgstatic int
32816747b715SmrgPanoramiXRenderCreateRadialGradient (ClientPtr client)
32826747b715Smrg{
32836747b715Smrg    REQUEST(xRenderCreateRadialGradientReq);
32846747b715Smrg    PanoramiXRes    *newPict;
32856747b715Smrg    int		    result = Success, j;
32866747b715Smrg
32876747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
32886747b715Smrg
32896747b715Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
32906747b715Smrg	return BadAlloc;
32916747b715Smrg
32926747b715Smrg    newPict->type = XRT_PICTURE;
32936747b715Smrg    newPict->info[0].id = stuff->pid;
32946747b715Smrg    newPict->u.pict.root = FALSE;
32956747b715Smrg
32966747b715Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
32976747b715Smrg	newPict->info[j].id = FakeClientID(client->index);
32986747b715Smrg
32996747b715Smrg    FOR_NSCREENS_BACKWARD(j) {
33006747b715Smrg	stuff->pid = newPict->info[j].id;
33016747b715Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client);
33026747b715Smrg	if(result != Success) break;
33036747b715Smrg    }
33046747b715Smrg
33056747b715Smrg    if (result == Success)
33066747b715Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
33076747b715Smrg    else
33086747b715Smrg	free(newPict);
33096747b715Smrg
33106747b715Smrg    return result;
33116747b715Smrg}
33126747b715Smrg
33136747b715Smrgstatic int
33146747b715SmrgPanoramiXRenderCreateConicalGradient (ClientPtr client)
33156747b715Smrg{
33166747b715Smrg    REQUEST(xRenderCreateConicalGradientReq);
33176747b715Smrg    PanoramiXRes    *newPict;
33186747b715Smrg    int		    result = Success, j;
33196747b715Smrg
33206747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
33216747b715Smrg
33226747b715Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
33236747b715Smrg	return BadAlloc;
33246747b715Smrg
33256747b715Smrg    newPict->type = XRT_PICTURE;
33266747b715Smrg    newPict->info[0].id = stuff->pid;
33276747b715Smrg    newPict->u.pict.root = FALSE;
33286747b715Smrg
33296747b715Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
33306747b715Smrg	newPict->info[j].id = FakeClientID(client->index);
33316747b715Smrg
33326747b715Smrg    FOR_NSCREENS_BACKWARD(j) {
33336747b715Smrg	stuff->pid = newPict->info[j].id;
33346747b715Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient]) (client);
33356747b715Smrg	if(result != Success) break;
33366747b715Smrg    }
33376747b715Smrg
33386747b715Smrg    if (result == Success)
33396747b715Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
33406747b715Smrg    else
33416747b715Smrg	free(newPict);
33426747b715Smrg
334305b261ecSmrg    return result;
334405b261ecSmrg}
334505b261ecSmrg
334605b261ecSmrgvoid
334705b261ecSmrgPanoramiXRenderInit (void)
334805b261ecSmrg{
334905b261ecSmrg    int	    i;
335005b261ecSmrg
33516747b715Smrg    XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource,
33526747b715Smrg					 "XineramaPicture");
33536747b715Smrg    if (RenderErrBase)
33546747b715Smrg	SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
335505b261ecSmrg    for (i = 0; i < RenderNumberRequests; i++)
335605b261ecSmrg	PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
335705b261ecSmrg    /*
335805b261ecSmrg     * Stuff in Xinerama aware request processing hooks
335905b261ecSmrg     */
336005b261ecSmrg    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
336105b261ecSmrg    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
336205b261ecSmrg    ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
336305b261ecSmrg    ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
336405b261ecSmrg    ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
336505b261ecSmrg    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
336605b261ecSmrg    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
336705b261ecSmrg    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
336805b261ecSmrg    ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
336905b261ecSmrg    ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
337005b261ecSmrg    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
337105b261ecSmrg
337205b261ecSmrg    ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
337305b261ecSmrg    ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
337405b261ecSmrg    ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
337505b261ecSmrg    ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
337605b261ecSmrg    ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
33776747b715Smrg
33786747b715Smrg    ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill;
33796747b715Smrg    ProcRenderVector[X_RenderCreateLinearGradient] = PanoramiXRenderCreateLinearGradient;
33806747b715Smrg    ProcRenderVector[X_RenderCreateRadialGradient] = PanoramiXRenderCreateRadialGradient;
33816747b715Smrg    ProcRenderVector[X_RenderCreateConicalGradient] = PanoramiXRenderCreateConicalGradient;
338205b261ecSmrg}
338305b261ecSmrg
338405b261ecSmrgvoid
338505b261ecSmrgPanoramiXRenderReset (void)
338605b261ecSmrg{
338705b261ecSmrg    int	    i;
338805b261ecSmrg    for (i = 0; i < RenderNumberRequests; i++)
338905b261ecSmrg	ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
33906747b715Smrg    RenderErrBase = 0;
339105b261ecSmrg}
339205b261ecSmrg
339305b261ecSmrg#endif	/* PANORAMIX */
3394