render.c revision f7df2e56
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
19f7df2e56Smrg * 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"
40f7df2e56Smrg#include "extinit.h"
4105b261ecSmrg#include "servermd.h"
4205b261ecSmrg#include <X11/extensions/render.h>
4305b261ecSmrg#include <X11/extensions/renderproto.h>
4405b261ecSmrg#include "picturestr.h"
4505b261ecSmrg#include "glyphstr.h"
4605b261ecSmrg#include <X11/Xfuncproto.h>
4705b261ecSmrg#include "cursorstr.h"
484642e01fSmrg#include "xace.h"
496747b715Smrg#include "protocol-versions.h"
5005b261ecSmrg
519ace9065Smrg#ifdef PANORAMIX
529ace9065Smrg#include "panoramiX.h"
539ace9065Smrg#include "panoramiXsrv.h"
549ace9065Smrg#endif
559ace9065Smrg
5605b261ecSmrg#include <stdint.h>
5705b261ecSmrg
58f7df2e56Smrgstatic int ProcRenderQueryVersion(ClientPtr pClient);
59f7df2e56Smrgstatic int ProcRenderQueryPictFormats(ClientPtr pClient);
60f7df2e56Smrgstatic int ProcRenderQueryPictIndexValues(ClientPtr pClient);
61f7df2e56Smrgstatic int ProcRenderQueryDithers(ClientPtr pClient);
62f7df2e56Smrgstatic int ProcRenderCreatePicture(ClientPtr pClient);
63f7df2e56Smrgstatic int ProcRenderChangePicture(ClientPtr pClient);
64f7df2e56Smrgstatic int ProcRenderSetPictureClipRectangles(ClientPtr pClient);
65f7df2e56Smrgstatic int ProcRenderFreePicture(ClientPtr pClient);
66f7df2e56Smrgstatic int ProcRenderComposite(ClientPtr pClient);
67f7df2e56Smrgstatic int ProcRenderScale(ClientPtr pClient);
68f7df2e56Smrgstatic int ProcRenderTrapezoids(ClientPtr pClient);
69f7df2e56Smrgstatic int ProcRenderTriangles(ClientPtr pClient);
70f7df2e56Smrgstatic int ProcRenderTriStrip(ClientPtr pClient);
71f7df2e56Smrgstatic int ProcRenderTriFan(ClientPtr pClient);
72f7df2e56Smrgstatic int ProcRenderColorTrapezoids(ClientPtr pClient);
73f7df2e56Smrgstatic int ProcRenderColorTriangles(ClientPtr pClient);
74f7df2e56Smrgstatic int ProcRenderTransform(ClientPtr pClient);
75f7df2e56Smrgstatic int ProcRenderCreateGlyphSet(ClientPtr pClient);
76f7df2e56Smrgstatic int ProcRenderReferenceGlyphSet(ClientPtr pClient);
77f7df2e56Smrgstatic int ProcRenderFreeGlyphSet(ClientPtr pClient);
78f7df2e56Smrgstatic int ProcRenderAddGlyphs(ClientPtr pClient);
79f7df2e56Smrgstatic int ProcRenderAddGlyphsFromPicture(ClientPtr pClient);
80f7df2e56Smrgstatic int ProcRenderFreeGlyphs(ClientPtr pClient);
81f7df2e56Smrgstatic int ProcRenderCompositeGlyphs(ClientPtr pClient);
82f7df2e56Smrgstatic int ProcRenderFillRectangles(ClientPtr pClient);
83f7df2e56Smrgstatic int ProcRenderCreateCursor(ClientPtr pClient);
84f7df2e56Smrgstatic int ProcRenderSetPictureTransform(ClientPtr pClient);
85f7df2e56Smrgstatic int ProcRenderQueryFilters(ClientPtr pClient);
86f7df2e56Smrgstatic int ProcRenderSetPictureFilter(ClientPtr pClient);
87f7df2e56Smrgstatic int ProcRenderCreateAnimCursor(ClientPtr pClient);
88f7df2e56Smrgstatic int ProcRenderAddTraps(ClientPtr pClient);
89f7df2e56Smrgstatic int ProcRenderCreateSolidFill(ClientPtr pClient);
90f7df2e56Smrgstatic int ProcRenderCreateLinearGradient(ClientPtr pClient);
91f7df2e56Smrgstatic int ProcRenderCreateRadialGradient(ClientPtr pClient);
92f7df2e56Smrgstatic int ProcRenderCreateConicalGradient(ClientPtr pClient);
93f7df2e56Smrg
94f7df2e56Smrgstatic int ProcRenderDispatch(ClientPtr pClient);
95f7df2e56Smrg
96f7df2e56Smrgstatic int SProcRenderQueryVersion(ClientPtr pClient);
97f7df2e56Smrgstatic int SProcRenderQueryPictFormats(ClientPtr pClient);
98f7df2e56Smrgstatic int SProcRenderQueryPictIndexValues(ClientPtr pClient);
99f7df2e56Smrgstatic int SProcRenderQueryDithers(ClientPtr pClient);
100f7df2e56Smrgstatic int SProcRenderCreatePicture(ClientPtr pClient);
101f7df2e56Smrgstatic int SProcRenderChangePicture(ClientPtr pClient);
102f7df2e56Smrgstatic int SProcRenderSetPictureClipRectangles(ClientPtr pClient);
103f7df2e56Smrgstatic int SProcRenderFreePicture(ClientPtr pClient);
104f7df2e56Smrgstatic int SProcRenderComposite(ClientPtr pClient);
105f7df2e56Smrgstatic int SProcRenderScale(ClientPtr pClient);
106f7df2e56Smrgstatic int SProcRenderTrapezoids(ClientPtr pClient);
107f7df2e56Smrgstatic int SProcRenderTriangles(ClientPtr pClient);
108f7df2e56Smrgstatic int SProcRenderTriStrip(ClientPtr pClient);
109f7df2e56Smrgstatic int SProcRenderTriFan(ClientPtr pClient);
110f7df2e56Smrgstatic int SProcRenderColorTrapezoids(ClientPtr pClient);
111f7df2e56Smrgstatic int SProcRenderColorTriangles(ClientPtr pClient);
112f7df2e56Smrgstatic int SProcRenderTransform(ClientPtr pClient);
113f7df2e56Smrgstatic int SProcRenderCreateGlyphSet(ClientPtr pClient);
114f7df2e56Smrgstatic int SProcRenderReferenceGlyphSet(ClientPtr pClient);
115f7df2e56Smrgstatic int SProcRenderFreeGlyphSet(ClientPtr pClient);
116f7df2e56Smrgstatic int SProcRenderAddGlyphs(ClientPtr pClient);
117f7df2e56Smrgstatic int SProcRenderAddGlyphsFromPicture(ClientPtr pClient);
118f7df2e56Smrgstatic int SProcRenderFreeGlyphs(ClientPtr pClient);
119f7df2e56Smrgstatic int SProcRenderCompositeGlyphs(ClientPtr pClient);
120f7df2e56Smrgstatic int SProcRenderFillRectangles(ClientPtr pClient);
121f7df2e56Smrgstatic int SProcRenderCreateCursor(ClientPtr pClient);
122f7df2e56Smrgstatic int SProcRenderSetPictureTransform(ClientPtr pClient);
123f7df2e56Smrgstatic int SProcRenderQueryFilters(ClientPtr pClient);
124f7df2e56Smrgstatic int SProcRenderSetPictureFilter(ClientPtr pClient);
125f7df2e56Smrgstatic int SProcRenderCreateAnimCursor(ClientPtr pClient);
126f7df2e56Smrgstatic int SProcRenderAddTraps(ClientPtr pClient);
127f7df2e56Smrgstatic int SProcRenderCreateSolidFill(ClientPtr pClient);
128f7df2e56Smrgstatic int SProcRenderCreateLinearGradient(ClientPtr pClient);
129f7df2e56Smrgstatic int SProcRenderCreateRadialGradient(ClientPtr pClient);
130f7df2e56Smrgstatic int SProcRenderCreateConicalGradient(ClientPtr pClient);
131f7df2e56Smrg
132f7df2e56Smrgstatic int SProcRenderDispatch(ClientPtr pClient);
133f7df2e56Smrg
134f7df2e56Smrgint (*ProcRenderVector[RenderNumberRequests]) (ClientPtr) = {
135f7df2e56SmrgProcRenderQueryVersion,
136f7df2e56Smrg        ProcRenderQueryPictFormats,
137f7df2e56Smrg        ProcRenderQueryPictIndexValues,
138f7df2e56Smrg        ProcRenderQueryDithers,
139f7df2e56Smrg        ProcRenderCreatePicture,
140f7df2e56Smrg        ProcRenderChangePicture,
141f7df2e56Smrg        ProcRenderSetPictureClipRectangles,
142f7df2e56Smrg        ProcRenderFreePicture,
143f7df2e56Smrg        ProcRenderComposite,
144f7df2e56Smrg        ProcRenderScale,
145f7df2e56Smrg        ProcRenderTrapezoids,
146f7df2e56Smrg        ProcRenderTriangles,
147f7df2e56Smrg        ProcRenderTriStrip,
148f7df2e56Smrg        ProcRenderTriFan,
149f7df2e56Smrg        ProcRenderColorTrapezoids,
150f7df2e56Smrg        ProcRenderColorTriangles,
151f7df2e56Smrg        ProcRenderTransform,
152f7df2e56Smrg        ProcRenderCreateGlyphSet,
153f7df2e56Smrg        ProcRenderReferenceGlyphSet,
154f7df2e56Smrg        ProcRenderFreeGlyphSet,
155f7df2e56Smrg        ProcRenderAddGlyphs,
156f7df2e56Smrg        ProcRenderAddGlyphsFromPicture,
157f7df2e56Smrg        ProcRenderFreeGlyphs,
158f7df2e56Smrg        ProcRenderCompositeGlyphs,
159f7df2e56Smrg        ProcRenderCompositeGlyphs,
160f7df2e56Smrg        ProcRenderCompositeGlyphs,
161f7df2e56Smrg        ProcRenderFillRectangles,
162f7df2e56Smrg        ProcRenderCreateCursor,
163f7df2e56Smrg        ProcRenderSetPictureTransform,
164f7df2e56Smrg        ProcRenderQueryFilters,
165f7df2e56Smrg        ProcRenderSetPictureFilter,
166f7df2e56Smrg        ProcRenderCreateAnimCursor,
167f7df2e56Smrg        ProcRenderAddTraps,
168f7df2e56Smrg        ProcRenderCreateSolidFill,
169f7df2e56Smrg        ProcRenderCreateLinearGradient,
170f7df2e56Smrg        ProcRenderCreateRadialGradient, ProcRenderCreateConicalGradient};
171f7df2e56Smrg
172f7df2e56Smrgint (*SProcRenderVector[RenderNumberRequests]) (ClientPtr) = {
173f7df2e56SmrgSProcRenderQueryVersion,
174f7df2e56Smrg        SProcRenderQueryPictFormats,
175f7df2e56Smrg        SProcRenderQueryPictIndexValues,
176f7df2e56Smrg        SProcRenderQueryDithers,
177f7df2e56Smrg        SProcRenderCreatePicture,
178f7df2e56Smrg        SProcRenderChangePicture,
179f7df2e56Smrg        SProcRenderSetPictureClipRectangles,
180f7df2e56Smrg        SProcRenderFreePicture,
181f7df2e56Smrg        SProcRenderComposite,
182f7df2e56Smrg        SProcRenderScale,
183f7df2e56Smrg        SProcRenderTrapezoids,
184f7df2e56Smrg        SProcRenderTriangles,
185f7df2e56Smrg        SProcRenderTriStrip,
186f7df2e56Smrg        SProcRenderTriFan,
187f7df2e56Smrg        SProcRenderColorTrapezoids,
188f7df2e56Smrg        SProcRenderColorTriangles,
189f7df2e56Smrg        SProcRenderTransform,
190f7df2e56Smrg        SProcRenderCreateGlyphSet,
191f7df2e56Smrg        SProcRenderReferenceGlyphSet,
192f7df2e56Smrg        SProcRenderFreeGlyphSet,
193f7df2e56Smrg        SProcRenderAddGlyphs,
194f7df2e56Smrg        SProcRenderAddGlyphsFromPicture,
195f7df2e56Smrg        SProcRenderFreeGlyphs,
196f7df2e56Smrg        SProcRenderCompositeGlyphs,
197f7df2e56Smrg        SProcRenderCompositeGlyphs,
198f7df2e56Smrg        SProcRenderCompositeGlyphs,
199f7df2e56Smrg        SProcRenderFillRectangles,
200f7df2e56Smrg        SProcRenderCreateCursor,
201f7df2e56Smrg        SProcRenderSetPictureTransform,
202f7df2e56Smrg        SProcRenderQueryFilters,
203f7df2e56Smrg        SProcRenderSetPictureFilter,
204f7df2e56Smrg        SProcRenderCreateAnimCursor,
205f7df2e56Smrg        SProcRenderAddTraps,
206f7df2e56Smrg        SProcRenderCreateSolidFill,
207f7df2e56Smrg        SProcRenderCreateLinearGradient,
208f7df2e56Smrg        SProcRenderCreateRadialGradient, SProcRenderCreateConicalGradient};
209f7df2e56Smrg
210f7df2e56Smrgint RenderErrBase;
2116747b715Smrgstatic DevPrivateKeyRec RenderClientPrivateKeyRec;
212f7df2e56Smrg
2136747b715Smrg#define RenderClientPrivateKey (&RenderClientPrivateKeyRec )
21405b261ecSmrg
21505b261ecSmrgtypedef struct _RenderClient {
216f7df2e56Smrg    int major_version;
217f7df2e56Smrg    int minor_version;
21805b261ecSmrg} RenderClientRec, *RenderClientPtr;
21905b261ecSmrg
2204642e01fSmrg#define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey))
22105b261ecSmrg
22205b261ecSmrgstatic void
223f7df2e56SmrgRenderClientCallback(CallbackListPtr *list, void *closure, void *data)
22405b261ecSmrg{
225f7df2e56Smrg    NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
226f7df2e56Smrg    ClientPtr pClient = clientinfo->client;
227f7df2e56Smrg    RenderClientPtr pRenderClient = GetRenderClient(pClient);
22805b261ecSmrg
22905b261ecSmrg    pRenderClient->major_version = 0;
23005b261ecSmrg    pRenderClient->minor_version = 0;
23105b261ecSmrg}
23205b261ecSmrg
2336747b715Smrg#ifdef PANORAMIX
234f7df2e56SmrgRESTYPE XRT_PICTURE;
2356747b715Smrg#endif
2366747b715Smrg
23705b261ecSmrgvoid
238f7df2e56SmrgRenderExtensionInit(void)
23905b261ecSmrg{
24005b261ecSmrg    ExtensionEntry *extEntry;
24105b261ecSmrg
24205b261ecSmrg    if (!PictureType)
243f7df2e56Smrg        return;
244f7df2e56Smrg    if (!PictureFinishInit())
245f7df2e56Smrg        return;
246f7df2e56Smrg    if (!dixRegisterPrivateKey
247f7df2e56Smrg        (&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec)))
248f7df2e56Smrg        return;
249f7df2e56Smrg    if (!AddCallback(&ClientStateCallback, RenderClientCallback, 0))
250f7df2e56Smrg        return;
251f7df2e56Smrg
252f7df2e56Smrg    extEntry = AddExtension(RENDER_NAME, 0, RenderNumberErrors,
253f7df2e56Smrg                            ProcRenderDispatch, SProcRenderDispatch,
254f7df2e56Smrg                            NULL, StandardMinorOpcode);
25505b261ecSmrg    if (!extEntry)
256f7df2e56Smrg        return;
25705b261ecSmrg    RenderErrBase = extEntry->errorBase;
2586747b715Smrg#ifdef PANORAMIX
2596747b715Smrg    if (XRT_PICTURE)
260f7df2e56Smrg        SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
2616747b715Smrg#endif
2626747b715Smrg    SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture);
2636747b715Smrg    SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat);
2646747b715Smrg    SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet);
26505b261ecSmrg}
26605b261ecSmrg
26705b261ecSmrgstatic int
268f7df2e56SmrgProcRenderQueryVersion(ClientPtr client)
26905b261ecSmrg{
270f7df2e56Smrg    RenderClientPtr pRenderClient = GetRenderClient(client);
271f7df2e56Smrg    xRenderQueryVersionReply rep = {
272f7df2e56Smrg        .type = X_Reply,
273f7df2e56Smrg        .sequenceNumber = client->sequence,
274f7df2e56Smrg        .length = 0
275f7df2e56Smrg    };
276f7df2e56Smrg
27705b261ecSmrg    REQUEST(xRenderQueryVersionReq);
2780b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
27905b261ecSmrg
280f7df2e56Smrg    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
281f7df2e56Smrg
28205b261ecSmrg    pRenderClient->major_version = stuff->majorVersion;
28305b261ecSmrg    pRenderClient->minor_version = stuff->minorVersion;
28405b261ecSmrg
2856747b715Smrg    if ((stuff->majorVersion * 1000 + stuff->minorVersion) <
286f7df2e56Smrg        (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) {
287f7df2e56Smrg        rep.majorVersion = stuff->majorVersion;
288f7df2e56Smrg        rep.minorVersion = stuff->minorVersion;
289f7df2e56Smrg    }
290f7df2e56Smrg    else {
291f7df2e56Smrg        rep.majorVersion = SERVER_RENDER_MAJOR_VERSION;
292f7df2e56Smrg        rep.minorVersion = SERVER_RENDER_MINOR_VERSION;
2936747b715Smrg    }
2946747b715Smrg
29505b261ecSmrg    if (client->swapped) {
296f7df2e56Smrg        swaps(&rep.sequenceNumber);
297f7df2e56Smrg        swapl(&rep.length);
298f7df2e56Smrg        swapl(&rep.majorVersion);
299f7df2e56Smrg        swapl(&rep.minorVersion);
30005b261ecSmrg    }
301f7df2e56Smrg    WriteToClient(client, sizeof(xRenderQueryVersionReply), &rep);
3026747b715Smrg    return Success;
30305b261ecSmrg}
30405b261ecSmrg
30505b261ecSmrgstatic VisualPtr
306f7df2e56SmrgfindVisual(ScreenPtr pScreen, VisualID vid)
30705b261ecSmrg{
308f7df2e56Smrg    VisualPtr pVisual;
309f7df2e56Smrg    int v;
31005b261ecSmrg
311f7df2e56Smrg    for (v = 0; v < pScreen->numVisuals; v++) {
312f7df2e56Smrg        pVisual = pScreen->visuals + v;
313f7df2e56Smrg        if (pVisual->vid == vid)
314f7df2e56Smrg            return pVisual;
31505b261ecSmrg    }
31605b261ecSmrg    return 0;
31705b261ecSmrg}
31805b261ecSmrg
31905b261ecSmrgstatic int
320f7df2e56SmrgProcRenderQueryPictFormats(ClientPtr client)
321f7df2e56Smrg{
322f7df2e56Smrg    RenderClientPtr pRenderClient = GetRenderClient(client);
323f7df2e56Smrg    xRenderQueryPictFormatsReply *reply;
324f7df2e56Smrg    xPictScreen *pictScreen;
325f7df2e56Smrg    xPictDepth *pictDepth;
326f7df2e56Smrg    xPictVisual *pictVisual;
327f7df2e56Smrg    xPictFormInfo *pictForm;
328f7df2e56Smrg    CARD32 *pictSubpixel;
329f7df2e56Smrg    ScreenPtr pScreen;
330f7df2e56Smrg    VisualPtr pVisual;
331f7df2e56Smrg    DepthPtr pDepth;
332f7df2e56Smrg    int v, d;
333f7df2e56Smrg    PictureScreenPtr ps;
334f7df2e56Smrg    PictFormatPtr pFormat;
335f7df2e56Smrg    int nformat;
336f7df2e56Smrg    int ndepth;
337f7df2e56Smrg    int nvisual;
338f7df2e56Smrg    int rlength;
339f7df2e56Smrg    int s;
340f7df2e56Smrg    int numScreens;
341f7df2e56Smrg    int numSubpixel;
342f7df2e56Smrg
34305b261ecSmrg/*    REQUEST(xRenderQueryPictFormatsReq); */
34405b261ecSmrg
34505b261ecSmrg    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
34605b261ecSmrg
34705b261ecSmrg#ifdef PANORAMIX
34805b261ecSmrg    if (noPanoramiXExtension)
349f7df2e56Smrg        numScreens = screenInfo.numScreens;
350f7df2e56Smrg    else
351f7df2e56Smrg        numScreens = ((xConnSetup *) ConnectionInfo)->numRoots;
35205b261ecSmrg#else
35305b261ecSmrg    numScreens = screenInfo.numScreens;
35405b261ecSmrg#endif
35505b261ecSmrg    ndepth = nformat = nvisual = 0;
356f7df2e56Smrg    for (s = 0; s < numScreens; s++) {
357f7df2e56Smrg        pScreen = screenInfo.screens[s];
358f7df2e56Smrg        for (d = 0; d < pScreen->numDepths; d++) {
359f7df2e56Smrg            pDepth = pScreen->allowedDepths + d;
360f7df2e56Smrg            ++ndepth;
361f7df2e56Smrg
362f7df2e56Smrg            for (v = 0; v < pDepth->numVids; v++) {
363f7df2e56Smrg                pVisual = findVisual(pScreen, pDepth->vids[v]);
364f7df2e56Smrg                if (pVisual &&
365f7df2e56Smrg                    PictureMatchVisual(pScreen, pDepth->depth, pVisual))
366f7df2e56Smrg                    ++nvisual;
367f7df2e56Smrg            }
368f7df2e56Smrg        }
369f7df2e56Smrg        ps = GetPictureScreenIfSet(pScreen);
370f7df2e56Smrg        if (ps)
371f7df2e56Smrg            nformat += ps->nformats;
37205b261ecSmrg    }
37305b261ecSmrg    if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
374f7df2e56Smrg        numSubpixel = 0;
37505b261ecSmrg    else
376f7df2e56Smrg        numSubpixel = numScreens;
377f7df2e56Smrg
378f7df2e56Smrg    rlength = (sizeof(xRenderQueryPictFormatsReply) +
379f7df2e56Smrg               nformat * sizeof(xPictFormInfo) +
380f7df2e56Smrg               numScreens * sizeof(xPictScreen) +
381f7df2e56Smrg               ndepth * sizeof(xPictDepth) +
382f7df2e56Smrg               nvisual * sizeof(xPictVisual) + numSubpixel * sizeof(CARD32));
3836747b715Smrg    reply = (xRenderQueryPictFormatsReply *) calloc(1, rlength);
38405b261ecSmrg    if (!reply)
385f7df2e56Smrg        return BadAlloc;
38605b261ecSmrg    reply->type = X_Reply;
38705b261ecSmrg    reply->sequenceNumber = client->sequence;
3886747b715Smrg    reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
38905b261ecSmrg    reply->numFormats = nformat;
39005b261ecSmrg    reply->numScreens = numScreens;
39105b261ecSmrg    reply->numDepths = ndepth;
39205b261ecSmrg    reply->numVisuals = nvisual;
39305b261ecSmrg    reply->numSubpixel = numSubpixel;
394f7df2e56Smrg
39505b261ecSmrg    pictForm = (xPictFormInfo *) (reply + 1);
396f7df2e56Smrg
397f7df2e56Smrg    for (s = 0; s < numScreens; s++) {
398f7df2e56Smrg        pScreen = screenInfo.screens[s];
399f7df2e56Smrg        ps = GetPictureScreenIfSet(pScreen);
400f7df2e56Smrg        if (ps) {
401f7df2e56Smrg            for (nformat = 0, pFormat = ps->formats;
402f7df2e56Smrg                 nformat < ps->nformats; nformat++, pFormat++) {
403f7df2e56Smrg                pictForm->id = pFormat->id;
404f7df2e56Smrg                pictForm->type = pFormat->type;
405f7df2e56Smrg                pictForm->depth = pFormat->depth;
406f7df2e56Smrg                pictForm->direct.red = pFormat->direct.red;
407f7df2e56Smrg                pictForm->direct.redMask = pFormat->direct.redMask;
408f7df2e56Smrg                pictForm->direct.green = pFormat->direct.green;
409f7df2e56Smrg                pictForm->direct.greenMask = pFormat->direct.greenMask;
410f7df2e56Smrg                pictForm->direct.blue = pFormat->direct.blue;
411f7df2e56Smrg                pictForm->direct.blueMask = pFormat->direct.blueMask;
412f7df2e56Smrg                pictForm->direct.alpha = pFormat->direct.alpha;
413f7df2e56Smrg                pictForm->direct.alphaMask = pFormat->direct.alphaMask;
414f7df2e56Smrg                if (pFormat->type == PictTypeIndexed &&
415f7df2e56Smrg                    pFormat->index.pColormap)
416f7df2e56Smrg                    pictForm->colormap = pFormat->index.pColormap->mid;
417f7df2e56Smrg                else
418f7df2e56Smrg                    pictForm->colormap = None;
419f7df2e56Smrg                if (client->swapped) {
420f7df2e56Smrg                    swapl(&pictForm->id);
421f7df2e56Smrg                    swaps(&pictForm->direct.red);
422f7df2e56Smrg                    swaps(&pictForm->direct.redMask);
423f7df2e56Smrg                    swaps(&pictForm->direct.green);
424f7df2e56Smrg                    swaps(&pictForm->direct.greenMask);
425f7df2e56Smrg                    swaps(&pictForm->direct.blue);
426f7df2e56Smrg                    swaps(&pictForm->direct.blueMask);
427f7df2e56Smrg                    swaps(&pictForm->direct.alpha);
428f7df2e56Smrg                    swaps(&pictForm->direct.alphaMask);
429f7df2e56Smrg                    swapl(&pictForm->colormap);
430f7df2e56Smrg                }
431f7df2e56Smrg                pictForm++;
432f7df2e56Smrg            }
433f7df2e56Smrg        }
434f7df2e56Smrg    }
435f7df2e56Smrg
43605b261ecSmrg    pictScreen = (xPictScreen *) pictForm;
437f7df2e56Smrg    for (s = 0; s < numScreens; s++) {
438f7df2e56Smrg        pScreen = screenInfo.screens[s];
439f7df2e56Smrg        pictDepth = (xPictDepth *) (pictScreen + 1);
440f7df2e56Smrg        ndepth = 0;
441f7df2e56Smrg        for (d = 0; d < pScreen->numDepths; d++) {
442f7df2e56Smrg            pictVisual = (xPictVisual *) (pictDepth + 1);
443f7df2e56Smrg            pDepth = pScreen->allowedDepths + d;
444f7df2e56Smrg
445f7df2e56Smrg            nvisual = 0;
446f7df2e56Smrg            for (v = 0; v < pDepth->numVids; v++) {
447f7df2e56Smrg                pVisual = findVisual(pScreen, pDepth->vids[v]);
448f7df2e56Smrg                if (pVisual && (pFormat = PictureMatchVisual(pScreen,
449f7df2e56Smrg                                                             pDepth->depth,
450f7df2e56Smrg                                                             pVisual))) {
451f7df2e56Smrg                    pictVisual->visual = pVisual->vid;
452f7df2e56Smrg                    pictVisual->format = pFormat->id;
453f7df2e56Smrg                    if (client->swapped) {
454f7df2e56Smrg                        swapl(&pictVisual->visual);
455f7df2e56Smrg                        swapl(&pictVisual->format);
456f7df2e56Smrg                    }
457f7df2e56Smrg                    pictVisual++;
458f7df2e56Smrg                    nvisual++;
459f7df2e56Smrg                }
460f7df2e56Smrg            }
461f7df2e56Smrg            pictDepth->depth = pDepth->depth;
462f7df2e56Smrg            pictDepth->nPictVisuals = nvisual;
463f7df2e56Smrg            if (client->swapped) {
464f7df2e56Smrg                swaps(&pictDepth->nPictVisuals);
465f7df2e56Smrg            }
466f7df2e56Smrg            ndepth++;
467f7df2e56Smrg            pictDepth = (xPictDepth *) pictVisual;
468f7df2e56Smrg        }
469f7df2e56Smrg        pictScreen->nDepth = ndepth;
470f7df2e56Smrg        ps = GetPictureScreenIfSet(pScreen);
471f7df2e56Smrg        if (ps)
472f7df2e56Smrg            pictScreen->fallback = ps->fallback->id;
473f7df2e56Smrg        else
474f7df2e56Smrg            pictScreen->fallback = 0;
475f7df2e56Smrg        if (client->swapped) {
476f7df2e56Smrg            swapl(&pictScreen->nDepth);
477f7df2e56Smrg            swapl(&pictScreen->fallback);
478f7df2e56Smrg        }
479f7df2e56Smrg        pictScreen = (xPictScreen *) pictDepth;
48005b261ecSmrg    }
48105b261ecSmrg    pictSubpixel = (CARD32 *) pictScreen;
482f7df2e56Smrg
483f7df2e56Smrg    for (s = 0; s < numSubpixel; s++) {
484f7df2e56Smrg        pScreen = screenInfo.screens[s];
485f7df2e56Smrg        ps = GetPictureScreenIfSet(pScreen);
486f7df2e56Smrg        if (ps)
487f7df2e56Smrg            *pictSubpixel = ps->subpixel;
488f7df2e56Smrg        else
489f7df2e56Smrg            *pictSubpixel = SubPixelUnknown;
490f7df2e56Smrg        if (client->swapped) {
491f7df2e56Smrg            swapl(pictSubpixel);
492f7df2e56Smrg        }
493f7df2e56Smrg        ++pictSubpixel;
494f7df2e56Smrg    }
495f7df2e56Smrg
496f7df2e56Smrg    if (client->swapped) {
497f7df2e56Smrg        swaps(&reply->sequenceNumber);
498f7df2e56Smrg        swapl(&reply->length);
499f7df2e56Smrg        swapl(&reply->numFormats);
500f7df2e56Smrg        swapl(&reply->numScreens);
501f7df2e56Smrg        swapl(&reply->numDepths);
502f7df2e56Smrg        swapl(&reply->numVisuals);
503f7df2e56Smrg        swapl(&reply->numSubpixel);
504f7df2e56Smrg    }
505f7df2e56Smrg    WriteToClient(client, rlength, reply);
5066747b715Smrg    free(reply);
5076747b715Smrg    return Success;
50805b261ecSmrg}
50905b261ecSmrg
51005b261ecSmrgstatic int
511f7df2e56SmrgProcRenderQueryPictIndexValues(ClientPtr client)
51205b261ecSmrg{
513f7df2e56Smrg    PictFormatPtr pFormat;
514f7df2e56Smrg    int rc, num;
515f7df2e56Smrg    int rlength;
516f7df2e56Smrg    int i;
517f7df2e56Smrg
51805b261ecSmrg    REQUEST(xRenderQueryPictIndexValuesReq);
51905b261ecSmrg    xRenderQueryPictIndexValuesReply *reply;
520f7df2e56Smrg    xIndexValue *values;
52105b261ecSmrg
52205b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
52305b261ecSmrg
524f7df2e56Smrg    rc = dixLookupResourceByType((void **) &pFormat, stuff->format,
525f7df2e56Smrg                                 PictFormatType, client, DixReadAccess);
5266747b715Smrg    if (rc != Success)
527f7df2e56Smrg        return rc;
52805b261ecSmrg
529f7df2e56Smrg    if (pFormat->type != PictTypeIndexed) {
530f7df2e56Smrg        client->errorValue = stuff->format;
531f7df2e56Smrg        return BadMatch;
53205b261ecSmrg    }
53305b261ecSmrg    num = pFormat->index.nvalues;
534f7df2e56Smrg    rlength = (sizeof(xRenderQueryPictIndexValuesReply) +
535f7df2e56Smrg               num * sizeof(xIndexValue));
536f7df2e56Smrg    reply = (xRenderQueryPictIndexValuesReply *) calloc(1, rlength);
53705b261ecSmrg    if (!reply)
538f7df2e56Smrg        return BadAlloc;
53905b261ecSmrg
54005b261ecSmrg    reply->type = X_Reply;
54105b261ecSmrg    reply->sequenceNumber = client->sequence;
5426747b715Smrg    reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
54305b261ecSmrg    reply->numIndexValues = num;
54405b261ecSmrg
54505b261ecSmrg    values = (xIndexValue *) (reply + 1);
546f7df2e56Smrg
547f7df2e56Smrg    memcpy(reply + 1, pFormat->index.pValues, num * sizeof(xIndexValue));
548f7df2e56Smrg
549f7df2e56Smrg    if (client->swapped) {
550f7df2e56Smrg        for (i = 0; i < num; i++) {
551f7df2e56Smrg            swapl(&values[i].pixel);
552f7df2e56Smrg            swaps(&values[i].red);
553f7df2e56Smrg            swaps(&values[i].green);
554f7df2e56Smrg            swaps(&values[i].blue);
555f7df2e56Smrg            swaps(&values[i].alpha);
556f7df2e56Smrg        }
557f7df2e56Smrg        swaps(&reply->sequenceNumber);
558f7df2e56Smrg        swapl(&reply->length);
559f7df2e56Smrg        swapl(&reply->numIndexValues);
560f7df2e56Smrg    }
561f7df2e56Smrg
562f7df2e56Smrg    WriteToClient(client, rlength, reply);
5636747b715Smrg    free(reply);
5646747b715Smrg    return Success;
56505b261ecSmrg}
56605b261ecSmrg
56705b261ecSmrgstatic int
568f7df2e56SmrgProcRenderQueryDithers(ClientPtr client)
56905b261ecSmrg{
57005b261ecSmrg    return BadImplementation;
57105b261ecSmrg}
57205b261ecSmrg
57305b261ecSmrgstatic int
574f7df2e56SmrgProcRenderCreatePicture(ClientPtr client)
57505b261ecSmrg{
576f7df2e56Smrg    PicturePtr pPicture;
577f7df2e56Smrg    DrawablePtr pDrawable;
578f7df2e56Smrg    PictFormatPtr pFormat;
579f7df2e56Smrg    int len, error, rc;
580f7df2e56Smrg
58105b261ecSmrg    REQUEST(xRenderCreatePictureReq);
58205b261ecSmrg
58305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
58405b261ecSmrg
58505b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
58605b261ecSmrg    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
587f7df2e56Smrg                           DixReadAccess | DixAddAccess);
58805b261ecSmrg    if (rc != Success)
589f7df2e56Smrg        return rc;
59005b261ecSmrg
591f7df2e56Smrg    rc = dixLookupResourceByType((void **) &pFormat, stuff->format,
592f7df2e56Smrg                                 PictFormatType, client, DixReadAccess);
5936747b715Smrg    if (rc != Success)
594f7df2e56Smrg        return rc;
5956747b715Smrg
59605b261ecSmrg    if (pFormat->depth != pDrawable->depth)
597f7df2e56Smrg        return BadMatch;
5986747b715Smrg    len = client->req_len - bytes_to_int32(sizeof(xRenderCreatePictureReq));
59905b261ecSmrg    if (Ones(stuff->mask) != len)
600f7df2e56Smrg        return BadLength;
601f7df2e56Smrg
602f7df2e56Smrg    pPicture = CreatePicture(stuff->pid,
603f7df2e56Smrg                             pDrawable,
604f7df2e56Smrg                             pFormat,
605f7df2e56Smrg                             stuff->mask, (XID *) (stuff + 1), client, &error);
60605b261ecSmrg    if (!pPicture)
607f7df2e56Smrg        return error;
608f7df2e56Smrg    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
609f7df2e56Smrg        return BadAlloc;
61005b261ecSmrg    return Success;
61105b261ecSmrg}
61205b261ecSmrg
61305b261ecSmrgstatic int
614f7df2e56SmrgProcRenderChangePicture(ClientPtr client)
61505b261ecSmrg{
616f7df2e56Smrg    PicturePtr pPicture;
617f7df2e56Smrg
61805b261ecSmrg    REQUEST(xRenderChangePictureReq);
61905b261ecSmrg    int len;
62005b261ecSmrg
62105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
622f7df2e56Smrg    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
62305b261ecSmrg
6246747b715Smrg    len = client->req_len - bytes_to_int32(sizeof(xRenderChangePictureReq));
62505b261ecSmrg    if (Ones(stuff->mask) != len)
626f7df2e56Smrg        return BadLength;
627f7df2e56Smrg
628f7df2e56Smrg    return ChangePicture(pPicture, stuff->mask, (XID *) (stuff + 1),
629f7df2e56Smrg                         (DevUnion *) 0, client);
63005b261ecSmrg}
63105b261ecSmrg
63205b261ecSmrgstatic int
633f7df2e56SmrgProcRenderSetPictureClipRectangles(ClientPtr client)
63405b261ecSmrg{
63505b261ecSmrg    REQUEST(xRenderSetPictureClipRectanglesReq);
636f7df2e56Smrg    PicturePtr pPicture;
637f7df2e56Smrg    int nr;
63805b261ecSmrg
63905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
640f7df2e56Smrg    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
64105b261ecSmrg    if (!pPicture->pDrawable)
642f7df2e56Smrg        return RenderErrBase + BadPicture;
64305b261ecSmrg
6446747b715Smrg    nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
64505b261ecSmrg    if (nr & 4)
646f7df2e56Smrg        return BadLength;
64705b261ecSmrg    nr >>= 3;
648f7df2e56Smrg    return SetPictureClipRects(pPicture,
649f7df2e56Smrg                               stuff->xOrigin, stuff->yOrigin,
650f7df2e56Smrg                               nr, (xRectangle *) &stuff[1]);
65105b261ecSmrg}
65205b261ecSmrg
65305b261ecSmrgstatic int
654f7df2e56SmrgProcRenderFreePicture(ClientPtr client)
65505b261ecSmrg{
656f7df2e56Smrg    PicturePtr pPicture;
657f7df2e56Smrg
65805b261ecSmrg    REQUEST(xRenderFreePictureReq);
65905b261ecSmrg
66005b261ecSmrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
66105b261ecSmrg
662f7df2e56Smrg    VERIFY_PICTURE(pPicture, stuff->picture, client, DixDestroyAccess);
663f7df2e56Smrg    FreeResource(stuff->picture, RT_NONE);
6646747b715Smrg    return Success;
66505b261ecSmrg}
66605b261ecSmrg
66705b261ecSmrgstatic Bool
668f7df2e56SmrgPictOpValid(CARD8 op)
66905b261ecSmrg{
670f7df2e56Smrg    if ( /*PictOpMinimum <= op && */ op <= PictOpMaximum)
671f7df2e56Smrg        return TRUE;
67205b261ecSmrg    if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
673f7df2e56Smrg        return TRUE;
67405b261ecSmrg    if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
675f7df2e56Smrg        return TRUE;
6766747b715Smrg    if (PictOpBlendMinimum <= op && op <= PictOpBlendMaximum)
677f7df2e56Smrg        return TRUE;
67805b261ecSmrg    return FALSE;
67905b261ecSmrg}
68005b261ecSmrg
68105b261ecSmrgstatic int
682f7df2e56SmrgProcRenderComposite(ClientPtr client)
68305b261ecSmrg{
684f7df2e56Smrg    PicturePtr pSrc, pMask, pDst;
685f7df2e56Smrg
68605b261ecSmrg    REQUEST(xRenderCompositeReq);
68705b261ecSmrg
68805b261ecSmrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
689f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
690f7df2e56Smrg        client->errorValue = stuff->op;
691f7df2e56Smrg        return BadValue;
69205b261ecSmrg    }
693f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
69405b261ecSmrg    if (!pDst->pDrawable)
69505b261ecSmrg        return BadDrawable;
696f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
697f7df2e56Smrg    VERIFY_ALPHA(pMask, stuff->mask, client, DixReadAccess);
698f7df2e56Smrg    if ((pSrc->pDrawable &&
699f7df2e56Smrg         pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) || (pMask &&
700f7df2e56Smrg                                                                   pMask->
701f7df2e56Smrg                                                                   pDrawable &&
702f7df2e56Smrg                                                                   pDst->
703f7df2e56Smrg                                                                   pDrawable->
704f7df2e56Smrg                                                                   pScreen !=
705f7df2e56Smrg                                                                   pMask->
706f7df2e56Smrg                                                                   pDrawable->
707f7df2e56Smrg                                                                   pScreen))
708f7df2e56Smrg        return BadMatch;
709f7df2e56Smrg    CompositePicture(stuff->op,
710f7df2e56Smrg                     pSrc,
711f7df2e56Smrg                     pMask,
712f7df2e56Smrg                     pDst,
713f7df2e56Smrg                     stuff->xSrc,
714f7df2e56Smrg                     stuff->ySrc,
715f7df2e56Smrg                     stuff->xMask,
716f7df2e56Smrg                     stuff->yMask,
717f7df2e56Smrg                     stuff->xDst, stuff->yDst, stuff->width, stuff->height);
71805b261ecSmrg    return Success;
71905b261ecSmrg}
72005b261ecSmrg
72105b261ecSmrgstatic int
722f7df2e56SmrgProcRenderScale(ClientPtr client)
72305b261ecSmrg{
72405b261ecSmrg    return BadImplementation;
72505b261ecSmrg}
72605b261ecSmrg
72705b261ecSmrgstatic int
728f7df2e56SmrgProcRenderTrapezoids(ClientPtr client)
72905b261ecSmrg{
730f7df2e56Smrg    int rc, ntraps;
731f7df2e56Smrg    PicturePtr pSrc, pDst;
732f7df2e56Smrg    PictFormatPtr pFormat;
733f7df2e56Smrg
73405b261ecSmrg    REQUEST(xRenderTrapezoidsReq);
73505b261ecSmrg
73605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
737f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
738f7df2e56Smrg        client->errorValue = stuff->op;
739f7df2e56Smrg        return BadValue;
74005b261ecSmrg    }
741f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
742f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
74305b261ecSmrg    if (!pDst->pDrawable)
74405b261ecSmrg        return BadDrawable;
74505b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
746f7df2e56Smrg        return BadMatch;
747f7df2e56Smrg    if (stuff->maskFormat) {
748f7df2e56Smrg        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
749f7df2e56Smrg                                     PictFormatType, client, DixReadAccess);
750f7df2e56Smrg        if (rc != Success)
751f7df2e56Smrg            return rc;
75205b261ecSmrg    }
75305b261ecSmrg    else
754f7df2e56Smrg        pFormat = 0;
755f7df2e56Smrg    ntraps = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq);
756f7df2e56Smrg    if (ntraps % sizeof(xTrapezoid))
757f7df2e56Smrg        return BadLength;
758f7df2e56Smrg    ntraps /= sizeof(xTrapezoid);
75905b261ecSmrg    if (ntraps)
760f7df2e56Smrg        CompositeTrapezoids(stuff->op, pSrc, pDst, pFormat,
761f7df2e56Smrg                            stuff->xSrc, stuff->ySrc,
762f7df2e56Smrg                            ntraps, (xTrapezoid *) &stuff[1]);
7636747b715Smrg    return Success;
76405b261ecSmrg}
76505b261ecSmrg
76605b261ecSmrgstatic int
767f7df2e56SmrgProcRenderTriangles(ClientPtr client)
76805b261ecSmrg{
769f7df2e56Smrg    int rc, ntris;
770f7df2e56Smrg    PicturePtr pSrc, pDst;
771f7df2e56Smrg    PictFormatPtr pFormat;
772f7df2e56Smrg
77305b261ecSmrg    REQUEST(xRenderTrianglesReq);
77405b261ecSmrg
77505b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
776f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
777f7df2e56Smrg        client->errorValue = stuff->op;
778f7df2e56Smrg        return BadValue;
77905b261ecSmrg    }
780f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
781f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
78205b261ecSmrg    if (!pDst->pDrawable)
78305b261ecSmrg        return BadDrawable;
78405b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
785f7df2e56Smrg        return BadMatch;
786f7df2e56Smrg    if (stuff->maskFormat) {
787f7df2e56Smrg        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
788f7df2e56Smrg                                     PictFormatType, client, DixReadAccess);
789f7df2e56Smrg        if (rc != Success)
790f7df2e56Smrg            return rc;
79105b261ecSmrg    }
79205b261ecSmrg    else
793f7df2e56Smrg        pFormat = 0;
794f7df2e56Smrg    ntris = (client->req_len << 2) - sizeof(xRenderTrianglesReq);
795f7df2e56Smrg    if (ntris % sizeof(xTriangle))
796f7df2e56Smrg        return BadLength;
797f7df2e56Smrg    ntris /= sizeof(xTriangle);
79805b261ecSmrg    if (ntris)
799f7df2e56Smrg        CompositeTriangles(stuff->op, pSrc, pDst, pFormat,
800f7df2e56Smrg                           stuff->xSrc, stuff->ySrc,
801f7df2e56Smrg                           ntris, (xTriangle *) &stuff[1]);
8026747b715Smrg    return Success;
80305b261ecSmrg}
80405b261ecSmrg
80505b261ecSmrgstatic int
806f7df2e56SmrgProcRenderTriStrip(ClientPtr client)
80705b261ecSmrg{
808f7df2e56Smrg    int rc, npoints;
809f7df2e56Smrg    PicturePtr pSrc, pDst;
810f7df2e56Smrg    PictFormatPtr pFormat;
811f7df2e56Smrg
81205b261ecSmrg    REQUEST(xRenderTrianglesReq);
81305b261ecSmrg
81405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
815f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
816f7df2e56Smrg        client->errorValue = stuff->op;
817f7df2e56Smrg        return BadValue;
81805b261ecSmrg    }
819f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
820f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
82105b261ecSmrg    if (!pDst->pDrawable)
82205b261ecSmrg        return BadDrawable;
82305b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
824f7df2e56Smrg        return BadMatch;
825f7df2e56Smrg    if (stuff->maskFormat) {
826f7df2e56Smrg        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
827f7df2e56Smrg                                     PictFormatType, client, DixReadAccess);
828f7df2e56Smrg        if (rc != Success)
829f7df2e56Smrg            return rc;
83005b261ecSmrg    }
83105b261ecSmrg    else
832f7df2e56Smrg        pFormat = 0;
833f7df2e56Smrg    npoints = ((client->req_len << 2) - sizeof(xRenderTriStripReq));
83405b261ecSmrg    if (npoints & 4)
835f7df2e56Smrg        return BadLength;
83605b261ecSmrg    npoints >>= 3;
83705b261ecSmrg    if (npoints >= 3)
838f7df2e56Smrg        CompositeTriStrip(stuff->op, pSrc, pDst, pFormat,
839f7df2e56Smrg                          stuff->xSrc, stuff->ySrc,
840f7df2e56Smrg                          npoints, (xPointFixed *) &stuff[1]);
8416747b715Smrg    return Success;
84205b261ecSmrg}
84305b261ecSmrg
84405b261ecSmrgstatic int
845f7df2e56SmrgProcRenderTriFan(ClientPtr client)
84605b261ecSmrg{
847f7df2e56Smrg    int rc, npoints;
848f7df2e56Smrg    PicturePtr pSrc, pDst;
849f7df2e56Smrg    PictFormatPtr pFormat;
850f7df2e56Smrg
85105b261ecSmrg    REQUEST(xRenderTrianglesReq);
85205b261ecSmrg
85305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
854f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
855f7df2e56Smrg        client->errorValue = stuff->op;
856f7df2e56Smrg        return BadValue;
85705b261ecSmrg    }
858f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
859f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
86005b261ecSmrg    if (!pDst->pDrawable)
86105b261ecSmrg        return BadDrawable;
86205b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
863f7df2e56Smrg        return BadMatch;
864f7df2e56Smrg    if (stuff->maskFormat) {
865f7df2e56Smrg        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
866f7df2e56Smrg                                     PictFormatType, client, DixReadAccess);
867f7df2e56Smrg        if (rc != Success)
868f7df2e56Smrg            return rc;
86905b261ecSmrg    }
87005b261ecSmrg    else
871f7df2e56Smrg        pFormat = 0;
872f7df2e56Smrg    npoints = ((client->req_len << 2) - sizeof(xRenderTriStripReq));
87305b261ecSmrg    if (npoints & 4)
874f7df2e56Smrg        return BadLength;
87505b261ecSmrg    npoints >>= 3;
87605b261ecSmrg    if (npoints >= 3)
877f7df2e56Smrg        CompositeTriFan(stuff->op, pSrc, pDst, pFormat,
878f7df2e56Smrg                        stuff->xSrc, stuff->ySrc,
879f7df2e56Smrg                        npoints, (xPointFixed *) &stuff[1]);
8806747b715Smrg    return Success;
88105b261ecSmrg}
88205b261ecSmrg
88305b261ecSmrgstatic int
884f7df2e56SmrgProcRenderColorTrapezoids(ClientPtr client)
88505b261ecSmrg{
88605b261ecSmrg    return BadImplementation;
88705b261ecSmrg}
88805b261ecSmrg
88905b261ecSmrgstatic int
890f7df2e56SmrgProcRenderColorTriangles(ClientPtr client)
89105b261ecSmrg{
89205b261ecSmrg    return BadImplementation;
89305b261ecSmrg}
89405b261ecSmrg
89505b261ecSmrgstatic int
896f7df2e56SmrgProcRenderTransform(ClientPtr client)
89705b261ecSmrg{
89805b261ecSmrg    return BadImplementation;
89905b261ecSmrg}
90005b261ecSmrg
90105b261ecSmrgstatic int
902f7df2e56SmrgProcRenderCreateGlyphSet(ClientPtr client)
90305b261ecSmrg{
904f7df2e56Smrg    GlyphSetPtr glyphSet;
905f7df2e56Smrg    PictFormatPtr format;
906f7df2e56Smrg    int rc, f;
907f7df2e56Smrg
90805b261ecSmrg    REQUEST(xRenderCreateGlyphSetReq);
90905b261ecSmrg
91005b261ecSmrg    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
91105b261ecSmrg
91205b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->gsid, client);
913f7df2e56Smrg    rc = dixLookupResourceByType((void **) &format, stuff->format,
914f7df2e56Smrg                                 PictFormatType, client, DixReadAccess);
9156747b715Smrg    if (rc != Success)
916f7df2e56Smrg        return rc;
9176747b715Smrg
91805b261ecSmrg    switch (format->depth) {
91905b261ecSmrg    case 1:
920f7df2e56Smrg        f = GlyphFormat1;
921f7df2e56Smrg        break;
92205b261ecSmrg    case 4:
923f7df2e56Smrg        f = GlyphFormat4;
924f7df2e56Smrg        break;
92505b261ecSmrg    case 8:
926f7df2e56Smrg        f = GlyphFormat8;
927f7df2e56Smrg        break;
92805b261ecSmrg    case 16:
929f7df2e56Smrg        f = GlyphFormat16;
930f7df2e56Smrg        break;
93105b261ecSmrg    case 32:
932f7df2e56Smrg        f = GlyphFormat32;
933f7df2e56Smrg        break;
93405b261ecSmrg    default:
935f7df2e56Smrg        return BadMatch;
93605b261ecSmrg    }
93705b261ecSmrg    if (format->type != PictTypeDirect)
938f7df2e56Smrg        return BadMatch;
939f7df2e56Smrg    glyphSet = AllocateGlyphSet(f, format);
94005b261ecSmrg    if (!glyphSet)
941f7df2e56Smrg        return BadAlloc;
9424642e01fSmrg    /* security creation/labeling check */
9434642e01fSmrg    rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType,
944f7df2e56Smrg                  glyphSet, RT_NONE, NULL, DixCreateAccess);
9454642e01fSmrg    if (rc != Success)
946f7df2e56Smrg        return rc;
947f7df2e56Smrg    if (!AddResource(stuff->gsid, GlyphSetType, (void *) glyphSet))
948f7df2e56Smrg        return BadAlloc;
94905b261ecSmrg    return Success;
95005b261ecSmrg}
95105b261ecSmrg
95205b261ecSmrgstatic int
953f7df2e56SmrgProcRenderReferenceGlyphSet(ClientPtr client)
95405b261ecSmrg{
955f7df2e56Smrg    GlyphSetPtr glyphSet;
9564642e01fSmrg    int rc;
957f7df2e56Smrg
95805b261ecSmrg    REQUEST(xRenderReferenceGlyphSetReq);
95905b261ecSmrg
96005b261ecSmrg    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
96105b261ecSmrg
96205b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->gsid, client);
96305b261ecSmrg
964f7df2e56Smrg    rc = dixLookupResourceByType((void **) &glyphSet, stuff->existing,
965f7df2e56Smrg                                 GlyphSetType, client, DixGetAttrAccess);
966f7df2e56Smrg    if (rc != Success) {
967f7df2e56Smrg        client->errorValue = stuff->existing;
968f7df2e56Smrg        return rc;
96905b261ecSmrg    }
97005b261ecSmrg    glyphSet->refcnt++;
971f7df2e56Smrg    if (!AddResource(stuff->gsid, GlyphSetType, (void *) glyphSet))
972f7df2e56Smrg        return BadAlloc;
9736747b715Smrg    return Success;
97405b261ecSmrg}
97505b261ecSmrg
97605b261ecSmrg#define NLOCALDELTA	64
97705b261ecSmrg#define NLOCALGLYPH	256
97805b261ecSmrg
97905b261ecSmrgstatic int
980f7df2e56SmrgProcRenderFreeGlyphSet(ClientPtr client)
98105b261ecSmrg{
982f7df2e56Smrg    GlyphSetPtr glyphSet;
9834642e01fSmrg    int rc;
984f7df2e56Smrg
98505b261ecSmrg    REQUEST(xRenderFreeGlyphSetReq);
98605b261ecSmrg
98705b261ecSmrg    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
988f7df2e56Smrg    rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
989f7df2e56Smrg                                 GlyphSetType, client, DixDestroyAccess);
990f7df2e56Smrg    if (rc != Success) {
991f7df2e56Smrg        client->errorValue = stuff->glyphset;
992f7df2e56Smrg        return rc;
99305b261ecSmrg    }
994f7df2e56Smrg    FreeResource(stuff->glyphset, RT_NONE);
9956747b715Smrg    return Success;
99605b261ecSmrg}
99705b261ecSmrg
99805b261ecSmrgtypedef struct _GlyphNew {
999f7df2e56Smrg    Glyph id;
1000f7df2e56Smrg    GlyphPtr glyph;
1001f7df2e56Smrg    Bool found;
1002f7df2e56Smrg    unsigned char sha1[20];
100305b261ecSmrg} GlyphNewRec, *GlyphNewPtr;
100405b261ecSmrg
10054642e01fSmrg#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
10064642e01fSmrg
100705b261ecSmrgstatic int
1008f7df2e56SmrgProcRenderAddGlyphs(ClientPtr client)
100905b261ecSmrg{
1010f7df2e56Smrg    GlyphSetPtr glyphSet;
1011f7df2e56Smrg
101205b261ecSmrg    REQUEST(xRenderAddGlyphsReq);
1013f7df2e56Smrg    GlyphNewRec glyphsLocal[NLOCALGLYPH];
1014f7df2e56Smrg    GlyphNewPtr glyphsBase, glyphs, glyph_new;
1015f7df2e56Smrg    int remain, nglyphs;
1016f7df2e56Smrg    CARD32 *gids;
1017f7df2e56Smrg    xGlyphInfo *gi;
1018f7df2e56Smrg    CARD8 *bits;
1019f7df2e56Smrg    unsigned int size;
1020f7df2e56Smrg    int err;
1021f7df2e56Smrg    int i, screen;
1022f7df2e56Smrg    PicturePtr pSrc = NULL, pDst = NULL;
1023f7df2e56Smrg    PixmapPtr pSrcPix = NULL, pDstPix = NULL;
1024f7df2e56Smrg    CARD32 component_alpha;
102505b261ecSmrg
102605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
1027f7df2e56Smrg    err =
1028f7df2e56Smrg        dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
1029f7df2e56Smrg                                GlyphSetType, client, DixAddAccess);
1030f7df2e56Smrg    if (err != Success) {
1031f7df2e56Smrg        client->errorValue = stuff->glyphset;
1032f7df2e56Smrg        return err;
103305b261ecSmrg    }
103405b261ecSmrg
10354642e01fSmrg    err = BadAlloc;
103605b261ecSmrg    nglyphs = stuff->nglyphs;
103705b261ecSmrg    if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
1038f7df2e56Smrg        return BadAlloc;
103905b261ecSmrg
1040f7df2e56Smrg    component_alpha = NeedsComponent(glyphSet->format->format);
10414642e01fSmrg
10424642e01fSmrg    if (nglyphs <= NLOCALGLYPH) {
1043f7df2e56Smrg        memset(glyphsLocal, 0, sizeof(glyphsLocal));
1044f7df2e56Smrg        glyphsBase = glyphsLocal;
10454642e01fSmrg    }
1046f7df2e56Smrg    else {
1047f7df2e56Smrg        glyphsBase = (GlyphNewPtr) calloc(nglyphs, sizeof(GlyphNewRec));
1048f7df2e56Smrg        if (!glyphsBase)
1049f7df2e56Smrg            return BadAlloc;
105005b261ecSmrg    }
105105b261ecSmrg
1052f7df2e56Smrg    remain = (client->req_len << 2) - sizeof(xRenderAddGlyphsReq);
105305b261ecSmrg
105405b261ecSmrg    glyphs = glyphsBase;
105505b261ecSmrg
105605b261ecSmrg    gids = (CARD32 *) (stuff + 1);
105705b261ecSmrg    gi = (xGlyphInfo *) (gids + nglyphs);
105805b261ecSmrg    bits = (CARD8 *) (gi + nglyphs);
1059f7df2e56Smrg    remain -= (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs;
10606747b715Smrg
10616747b715Smrg    /* protect against bad nglyphs */
1062f7df2e56Smrg    if (gi < ((xGlyphInfo *) stuff) ||
1063f7df2e56Smrg        gi > ((xGlyphInfo *) ((CARD32 *) stuff + client->req_len)) ||
1064f7df2e56Smrg        bits < ((CARD8 *) stuff) ||
1065f7df2e56Smrg        bits > ((CARD8 *) ((CARD32 *) stuff + client->req_len))) {
10666747b715Smrg        err = BadLength;
10676747b715Smrg        goto bail;
10686747b715Smrg    }
10696747b715Smrg
1070f7df2e56Smrg    for (i = 0; i < nglyphs; i++) {
1071f7df2e56Smrg        size_t padded_width;
1072f7df2e56Smrg
1073f7df2e56Smrg        glyph_new = &glyphs[i];
1074f7df2e56Smrg
1075f7df2e56Smrg        padded_width = PixmapBytePad(gi[i].width, glyphSet->format->depth);
1076f7df2e56Smrg
1077f7df2e56Smrg        if (gi[i].height &&
1078f7df2e56Smrg            padded_width > (UINT32_MAX - sizeof(GlyphRec)) / gi[i].height)
1079f7df2e56Smrg            break;
1080f7df2e56Smrg
1081f7df2e56Smrg        size = gi[i].height * padded_width;
1082f7df2e56Smrg        if (remain < size)
1083f7df2e56Smrg            break;
1084f7df2e56Smrg
1085f7df2e56Smrg        err = HashGlyph(&gi[i], bits, size, glyph_new->sha1);
1086f7df2e56Smrg        if (err)
1087f7df2e56Smrg            goto bail;
1088f7df2e56Smrg
1089f7df2e56Smrg        glyph_new->glyph = FindGlyphByHash(glyph_new->sha1, glyphSet->fdepth);
1090f7df2e56Smrg
1091f7df2e56Smrg        if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) {
1092f7df2e56Smrg            glyph_new->found = TRUE;
1093f7df2e56Smrg        }
1094f7df2e56Smrg        else {
1095f7df2e56Smrg            GlyphPtr glyph;
1096f7df2e56Smrg
1097f7df2e56Smrg            glyph_new->found = FALSE;
1098f7df2e56Smrg            glyph_new->glyph = glyph = AllocateGlyph(&gi[i], glyphSet->fdepth);
1099f7df2e56Smrg            if (!glyph) {
1100f7df2e56Smrg                err = BadAlloc;
1101f7df2e56Smrg                goto bail;
1102f7df2e56Smrg            }
1103f7df2e56Smrg
1104f7df2e56Smrg            for (screen = 0; screen < screenInfo.numScreens; screen++) {
1105f7df2e56Smrg                int width = gi[i].width;
1106f7df2e56Smrg                int height = gi[i].height;
1107f7df2e56Smrg                int depth = glyphSet->format->depth;
1108f7df2e56Smrg                ScreenPtr pScreen;
1109f7df2e56Smrg                int error;
1110f7df2e56Smrg
1111f7df2e56Smrg                /* Skip work if it's invisibly small anyway */
1112f7df2e56Smrg                if (!width || !height)
1113f7df2e56Smrg                    break;
1114f7df2e56Smrg
1115f7df2e56Smrg                pScreen = screenInfo.screens[screen];
1116f7df2e56Smrg                pSrcPix = GetScratchPixmapHeader(pScreen,
1117f7df2e56Smrg                                                 width, height,
1118f7df2e56Smrg                                                 depth, depth, -1, bits);
1119f7df2e56Smrg                if (!pSrcPix) {
1120f7df2e56Smrg                    err = BadAlloc;
1121f7df2e56Smrg                    goto bail;
1122f7df2e56Smrg                }
1123f7df2e56Smrg
1124f7df2e56Smrg                pSrc = CreatePicture(0, &pSrcPix->drawable,
1125f7df2e56Smrg                                     glyphSet->format, 0, NULL,
1126f7df2e56Smrg                                     serverClient, &error);
1127f7df2e56Smrg                if (!pSrc) {
1128f7df2e56Smrg                    err = BadAlloc;
1129f7df2e56Smrg                    goto bail;
1130f7df2e56Smrg                }
1131f7df2e56Smrg
1132f7df2e56Smrg                pDstPix = (pScreen->CreatePixmap) (pScreen,
1133f7df2e56Smrg                                                   width, height, depth,
1134f7df2e56Smrg                                                   CREATE_PIXMAP_USAGE_GLYPH_PICTURE);
1135f7df2e56Smrg
1136f7df2e56Smrg                if (!pDstPix) {
1137f7df2e56Smrg                    err = BadAlloc;
1138f7df2e56Smrg                    goto bail;
1139f7df2e56Smrg                }
1140f7df2e56Smrg
1141f7df2e56Smrg                pDst = CreatePicture(0, &pDstPix->drawable,
1142f7df2e56Smrg                                  glyphSet->format,
1143f7df2e56Smrg                                  CPComponentAlpha, &component_alpha,
1144f7df2e56Smrg                                  serverClient, &error);
1145f7df2e56Smrg                SetGlyphPicture(glyph, pScreen, pDst);
1146f7df2e56Smrg
1147f7df2e56Smrg                /* The picture takes a reference to the pixmap, so we
1148f7df2e56Smrg                   drop ours. */
1149f7df2e56Smrg                (pScreen->DestroyPixmap) (pDstPix);
1150f7df2e56Smrg                pDstPix = NULL;
1151f7df2e56Smrg
1152f7df2e56Smrg                if (!pDst) {
1153f7df2e56Smrg                    err = BadAlloc;
1154f7df2e56Smrg                    goto bail;
1155f7df2e56Smrg                }
1156f7df2e56Smrg
1157f7df2e56Smrg                CompositePicture(PictOpSrc,
1158f7df2e56Smrg                                 pSrc,
1159f7df2e56Smrg                                 None, pDst, 0, 0, 0, 0, 0, 0, width, height);
1160f7df2e56Smrg
1161f7df2e56Smrg                FreePicture((void *) pSrc, 0);
1162f7df2e56Smrg                pSrc = NULL;
1163f7df2e56Smrg                FreeScratchPixmapHeader(pSrcPix);
1164f7df2e56Smrg                pSrcPix = NULL;
1165f7df2e56Smrg            }
1166f7df2e56Smrg
1167f7df2e56Smrg            memcpy(glyph_new->glyph->sha1, glyph_new->sha1, 20);
1168f7df2e56Smrg        }
1169f7df2e56Smrg
1170f7df2e56Smrg        glyph_new->id = gids[i];
1171f7df2e56Smrg
1172f7df2e56Smrg        if (size & 3)
1173f7df2e56Smrg            size += 4 - (size & 3);
1174f7df2e56Smrg        bits += size;
1175f7df2e56Smrg        remain -= size;
1176f7df2e56Smrg    }
1177f7df2e56Smrg    if (remain || i < nglyphs) {
1178f7df2e56Smrg        err = BadLength;
1179f7df2e56Smrg        goto bail;
1180f7df2e56Smrg    }
1181f7df2e56Smrg    if (!ResizeGlyphSet(glyphSet, nglyphs)) {
1182f7df2e56Smrg        err = BadAlloc;
1183f7df2e56Smrg        goto bail;
118405b261ecSmrg    }
11854642e01fSmrg    for (i = 0; i < nglyphs; i++)
1186f7df2e56Smrg        AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id);
118705b261ecSmrg
118805b261ecSmrg    if (glyphsBase != glyphsLocal)
1189f7df2e56Smrg        free(glyphsBase);
11906747b715Smrg    return Success;
1191f7df2e56Smrg bail:
11924642e01fSmrg    if (pSrc)
1193f7df2e56Smrg        FreePicture((void *) pSrc, 0);
11944642e01fSmrg    if (pSrcPix)
1195f7df2e56Smrg        FreeScratchPixmapHeader(pSrcPix);
11964642e01fSmrg    for (i = 0; i < nglyphs; i++)
1197f7df2e56Smrg        if (glyphs[i].glyph && !glyphs[i].found)
1198f7df2e56Smrg            free(glyphs[i].glyph);
119905b261ecSmrg    if (glyphsBase != glyphsLocal)
1200f7df2e56Smrg        free(glyphsBase);
120105b261ecSmrg    return err;
120205b261ecSmrg}
120305b261ecSmrg
120405b261ecSmrgstatic int
1205f7df2e56SmrgProcRenderAddGlyphsFromPicture(ClientPtr client)
120605b261ecSmrg{
120705b261ecSmrg    return BadImplementation;
120805b261ecSmrg}
120905b261ecSmrg
121005b261ecSmrgstatic int
1211f7df2e56SmrgProcRenderFreeGlyphs(ClientPtr client)
121205b261ecSmrg{
121305b261ecSmrg    REQUEST(xRenderFreeGlyphsReq);
1214f7df2e56Smrg    GlyphSetPtr glyphSet;
1215f7df2e56Smrg    int rc, nglyph;
1216f7df2e56Smrg    CARD32 *gids;
1217f7df2e56Smrg    CARD32 glyph;
121805b261ecSmrg
121905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
1220f7df2e56Smrg    rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
1221f7df2e56Smrg                                 GlyphSetType, client, DixRemoveAccess);
1222f7df2e56Smrg    if (rc != Success) {
1223f7df2e56Smrg        client->errorValue = stuff->glyphset;
1224f7df2e56Smrg        return rc;
1225f7df2e56Smrg    }
1226f7df2e56Smrg    nglyph =
1227f7df2e56Smrg        bytes_to_int32((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq));
122805b261ecSmrg    gids = (CARD32 *) (stuff + 1);
1229f7df2e56Smrg    while (nglyph-- > 0) {
1230f7df2e56Smrg        glyph = *gids++;
1231f7df2e56Smrg        if (!DeleteGlyph(glyphSet, glyph)) {
1232f7df2e56Smrg            client->errorValue = glyph;
1233f7df2e56Smrg            return RenderErrBase + BadGlyph;
1234f7df2e56Smrg        }
123505b261ecSmrg    }
12366747b715Smrg    return Success;
123705b261ecSmrg}
123805b261ecSmrg
123905b261ecSmrgstatic int
1240f7df2e56SmrgProcRenderCompositeGlyphs(ClientPtr client)
1241f7df2e56Smrg{
1242f7df2e56Smrg    GlyphSetPtr glyphSet;
1243f7df2e56Smrg    GlyphSet gs;
1244f7df2e56Smrg    PicturePtr pSrc, pDst;
1245f7df2e56Smrg    PictFormatPtr pFormat;
1246f7df2e56Smrg    GlyphListRec listsLocal[NLOCALDELTA];
1247f7df2e56Smrg    GlyphListPtr lists, listsBase;
1248f7df2e56Smrg    GlyphPtr glyphsLocal[NLOCALGLYPH];
1249f7df2e56Smrg    Glyph glyph;
1250f7df2e56Smrg    GlyphPtr *glyphs, *glyphsBase;
1251f7df2e56Smrg    xGlyphElt *elt;
1252f7df2e56Smrg    CARD8 *buffer, *end;
1253f7df2e56Smrg    int nglyph;
1254f7df2e56Smrg    int nlist;
1255f7df2e56Smrg    int space;
1256f7df2e56Smrg    int size;
1257f7df2e56Smrg    int rc, n;
1258f7df2e56Smrg
125905b261ecSmrg    REQUEST(xRenderCompositeGlyphsReq);
126005b261ecSmrg
126105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
126205b261ecSmrg
126305b261ecSmrg    switch (stuff->renderReqType) {
1264f7df2e56Smrg    default:
1265f7df2e56Smrg        size = 1;
1266f7df2e56Smrg        break;
1267f7df2e56Smrg    case X_RenderCompositeGlyphs16:
1268f7df2e56Smrg        size = 2;
1269f7df2e56Smrg        break;
1270f7df2e56Smrg    case X_RenderCompositeGlyphs32:
1271f7df2e56Smrg        size = 4;
1272f7df2e56Smrg        break;
1273f7df2e56Smrg    }
1274f7df2e56Smrg
1275f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
1276f7df2e56Smrg        client->errorValue = stuff->op;
1277f7df2e56Smrg        return BadValue;
1278f7df2e56Smrg    }
1279f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
1280f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
128105b261ecSmrg    if (!pDst->pDrawable)
128205b261ecSmrg        return BadDrawable;
128305b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
1284f7df2e56Smrg        return BadMatch;
1285f7df2e56Smrg    if (stuff->maskFormat) {
1286f7df2e56Smrg        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
1287f7df2e56Smrg                                     PictFormatType, client, DixReadAccess);
1288f7df2e56Smrg        if (rc != Success)
1289f7df2e56Smrg            return rc;
129005b261ecSmrg    }
129105b261ecSmrg    else
1292f7df2e56Smrg        pFormat = 0;
129305b261ecSmrg
1294f7df2e56Smrg    rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
1295f7df2e56Smrg                                 GlyphSetType, client, DixUseAccess);
12966747b715Smrg    if (rc != Success)
1297f7df2e56Smrg        return rc;
129805b261ecSmrg
129905b261ecSmrg    buffer = (CARD8 *) (stuff + 1);
130005b261ecSmrg    end = (CARD8 *) stuff + (client->req_len << 2);
130105b261ecSmrg    nglyph = 0;
130205b261ecSmrg    nlist = 0;
1303f7df2e56Smrg    while (buffer + sizeof(xGlyphElt) < end) {
1304f7df2e56Smrg        elt = (xGlyphElt *) buffer;
1305f7df2e56Smrg        buffer += sizeof(xGlyphElt);
1306f7df2e56Smrg
1307f7df2e56Smrg        if (elt->len == 0xff) {
1308f7df2e56Smrg            buffer += 4;
1309f7df2e56Smrg        }
1310f7df2e56Smrg        else {
1311f7df2e56Smrg            nlist++;
1312f7df2e56Smrg            nglyph += elt->len;
1313f7df2e56Smrg            space = size * elt->len;
1314f7df2e56Smrg            if (space & 3)
1315f7df2e56Smrg                space += 4 - (space & 3);
1316f7df2e56Smrg            buffer += space;
1317f7df2e56Smrg        }
131805b261ecSmrg    }
131905b261ecSmrg    if (nglyph <= NLOCALGLYPH)
1320f7df2e56Smrg        glyphsBase = glyphsLocal;
1321f7df2e56Smrg    else {
1322f7df2e56Smrg        glyphsBase = xallocarray(nglyph, sizeof(GlyphPtr));
1323f7df2e56Smrg        if (!glyphsBase)
1324f7df2e56Smrg            return BadAlloc;
132505b261ecSmrg    }
132605b261ecSmrg    if (nlist <= NLOCALDELTA)
1327f7df2e56Smrg        listsBase = listsLocal;
1328f7df2e56Smrg    else {
1329f7df2e56Smrg        listsBase = xallocarray(nlist, sizeof(GlyphListRec));
1330f7df2e56Smrg        if (!listsBase) {
1331f7df2e56Smrg            rc = BadAlloc;
1332f7df2e56Smrg            goto bail;
1333f7df2e56Smrg        }
133405b261ecSmrg    }
133505b261ecSmrg    buffer = (CARD8 *) (stuff + 1);
133605b261ecSmrg    glyphs = glyphsBase;
133705b261ecSmrg    lists = listsBase;
1338f7df2e56Smrg    while (buffer + sizeof(xGlyphElt) < end) {
1339f7df2e56Smrg        elt = (xGlyphElt *) buffer;
1340f7df2e56Smrg        buffer += sizeof(xGlyphElt);
1341f7df2e56Smrg
1342f7df2e56Smrg        if (elt->len == 0xff) {
1343f7df2e56Smrg            if (buffer + sizeof(GlyphSet) < end) {
134405b261ecSmrg                memcpy(&gs, buffer, sizeof(GlyphSet));
1345f7df2e56Smrg                rc = dixLookupResourceByType((void **) &glyphSet, gs,
1346f7df2e56Smrg                                             GlyphSetType, client,
1347f7df2e56Smrg                                             DixUseAccess);
1348f7df2e56Smrg                if (rc != Success)
1349f7df2e56Smrg                    goto bail;
1350f7df2e56Smrg            }
1351f7df2e56Smrg            buffer += 4;
1352f7df2e56Smrg        }
1353f7df2e56Smrg        else {
1354f7df2e56Smrg            lists->xOff = elt->deltax;
1355f7df2e56Smrg            lists->yOff = elt->deltay;
1356f7df2e56Smrg            lists->format = glyphSet->format;
1357f7df2e56Smrg            lists->len = 0;
1358f7df2e56Smrg            n = elt->len;
1359f7df2e56Smrg            while (n--) {
1360f7df2e56Smrg                if (buffer + size <= end) {
1361f7df2e56Smrg                    switch (size) {
1362f7df2e56Smrg                    case 1:
1363f7df2e56Smrg                        glyph = *((CARD8 *) buffer);
1364f7df2e56Smrg                        break;
1365f7df2e56Smrg                    case 2:
1366f7df2e56Smrg                        glyph = *((CARD16 *) buffer);
1367f7df2e56Smrg                        break;
1368f7df2e56Smrg                    case 4:
1369f7df2e56Smrg                    default:
1370f7df2e56Smrg                        glyph = *((CARD32 *) buffer);
1371f7df2e56Smrg                        break;
1372f7df2e56Smrg                    }
1373f7df2e56Smrg                    if ((*glyphs = FindGlyph(glyphSet, glyph))) {
1374f7df2e56Smrg                        lists->len++;
1375f7df2e56Smrg                        glyphs++;
1376f7df2e56Smrg                    }
1377f7df2e56Smrg                }
1378f7df2e56Smrg                buffer += size;
1379f7df2e56Smrg            }
1380f7df2e56Smrg            space = size * elt->len;
1381f7df2e56Smrg            if (space & 3)
1382f7df2e56Smrg                buffer += 4 - (space & 3);
1383f7df2e56Smrg            lists++;
1384f7df2e56Smrg        }
138505b261ecSmrg    }
13869ace9065Smrg    if (buffer > end) {
1387f7df2e56Smrg        rc = BadLength;
1388f7df2e56Smrg        goto bail;
1389f7df2e56Smrg    }
1390f7df2e56Smrg
1391f7df2e56Smrg    CompositeGlyphs(stuff->op,
1392f7df2e56Smrg                    pSrc,
1393f7df2e56Smrg                    pDst,
1394f7df2e56Smrg                    pFormat,
1395f7df2e56Smrg                    stuff->xSrc, stuff->ySrc, nlist, listsBase, glyphsBase);
13969ace9065Smrg    rc = Success;
139705b261ecSmrg
1398f7df2e56Smrg bail:
139905b261ecSmrg    if (glyphsBase != glyphsLocal)
1400f7df2e56Smrg        free(glyphsBase);
140105b261ecSmrg    if (listsBase != listsLocal)
1402f7df2e56Smrg        free(listsBase);
14039ace9065Smrg    return rc;
140405b261ecSmrg}
140505b261ecSmrg
140605b261ecSmrgstatic int
1407f7df2e56SmrgProcRenderFillRectangles(ClientPtr client)
140805b261ecSmrg{
1409f7df2e56Smrg    PicturePtr pDst;
1410f7df2e56Smrg    int things;
1411f7df2e56Smrg
141205b261ecSmrg    REQUEST(xRenderFillRectanglesReq);
1413f7df2e56Smrg
1414f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
1415f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
1416f7df2e56Smrg        client->errorValue = stuff->op;
1417f7df2e56Smrg        return BadValue;
1418f7df2e56Smrg    }
1419f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
142005b261ecSmrg    if (!pDst->pDrawable)
142105b261ecSmrg        return BadDrawable;
1422f7df2e56Smrg
142305b261ecSmrg    things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
142405b261ecSmrg    if (things & 4)
1425f7df2e56Smrg        return BadLength;
142605b261ecSmrg    things >>= 3;
1427f7df2e56Smrg
1428f7df2e56Smrg    CompositeRects(stuff->op,
1429f7df2e56Smrg                   pDst, &stuff->color, things, (xRectangle *) &stuff[1]);
1430f7df2e56Smrg
14316747b715Smrg    return Success;
143205b261ecSmrg}
143305b261ecSmrg
143405b261ecSmrgstatic void
1435f7df2e56SmrgRenderSetBit(unsigned char *line, int x, int bit)
143605b261ecSmrg{
1437f7df2e56Smrg    unsigned char mask;
1438f7df2e56Smrg
143905b261ecSmrg    if (screenInfo.bitmapBitOrder == LSBFirst)
1440f7df2e56Smrg        mask = (1 << (x & 7));
144105b261ecSmrg    else
1442f7df2e56Smrg        mask = (0x80 >> (x & 7));
144305b261ecSmrg    /* XXX assumes byte order is host byte order */
144405b261ecSmrg    line += (x >> 3);
144505b261ecSmrg    if (bit)
1446f7df2e56Smrg        *line |= mask;
144705b261ecSmrg    else
1448f7df2e56Smrg        *line &= ~mask;
144905b261ecSmrg}
145005b261ecSmrg
145105b261ecSmrg#define DITHER_DIM 2
145205b261ecSmrg
145305b261ecSmrgstatic CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
1454f7df2e56Smrg    {1, 3,},
1455f7df2e56Smrg    {4, 2,},
145605b261ecSmrg};
145705b261ecSmrg
145805b261ecSmrg#define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
145905b261ecSmrg
146005b261ecSmrgstatic int
1461f7df2e56SmrgProcRenderCreateCursor(ClientPtr client)
146205b261ecSmrg{
146305b261ecSmrg    REQUEST(xRenderCreateCursorReq);
1464f7df2e56Smrg    PicturePtr pSrc;
1465f7df2e56Smrg    ScreenPtr pScreen;
1466f7df2e56Smrg    unsigned short width, height;
1467f7df2e56Smrg    CARD32 *argbbits, *argb;
1468f7df2e56Smrg    unsigned char *srcbits, *srcline;
1469f7df2e56Smrg    unsigned char *mskbits, *mskline;
1470f7df2e56Smrg    int stride;
1471f7df2e56Smrg    int x, y;
1472f7df2e56Smrg    int nbytes_mono;
147305b261ecSmrg    CursorMetricRec cm;
1474f7df2e56Smrg    CursorPtr pCursor;
1475f7df2e56Smrg    CARD32 twocolor[3];
1476f7df2e56Smrg    int rc, ncolor;
147705b261ecSmrg
1478f7df2e56Smrg    REQUEST_SIZE_MATCH(xRenderCreateCursorReq);
147905b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
1480f7df2e56Smrg
1481f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
148205b261ecSmrg    if (!pSrc->pDrawable)
148305b261ecSmrg        return BadDrawable;
148405b261ecSmrg    pScreen = pSrc->pDrawable->pScreen;
148505b261ecSmrg    width = pSrc->pDrawable->width;
148605b261ecSmrg    height = pSrc->pDrawable->height;
1487f7df2e56Smrg    if (height && width > UINT32_MAX / (height * sizeof(CARD32)))
1488f7df2e56Smrg        return BadAlloc;
1489f7df2e56Smrg    if (stuff->x > width || stuff->y > height)
1490f7df2e56Smrg        return BadMatch;
1491f7df2e56Smrg    argbbits = malloc(width * height * sizeof(CARD32));
149205b261ecSmrg    if (!argbbits)
1493f7df2e56Smrg        return BadAlloc;
1494f7df2e56Smrg
149505b261ecSmrg    stride = BitmapBytePad(width);
1496f7df2e56Smrg    nbytes_mono = stride * height;
14976747b715Smrg    srcbits = calloc(1, nbytes_mono);
1498f7df2e56Smrg    if (!srcbits) {
1499f7df2e56Smrg        free(argbbits);
1500f7df2e56Smrg        return BadAlloc;
150105b261ecSmrg    }
15026747b715Smrg    mskbits = calloc(1, nbytes_mono);
1503f7df2e56Smrg    if (!mskbits) {
1504f7df2e56Smrg        free(argbbits);
1505f7df2e56Smrg        free(srcbits);
1506f7df2e56Smrg        return BadAlloc;
1507f7df2e56Smrg    }
1508f7df2e56Smrg
1509f7df2e56Smrg    if (pSrc->format == PICT_a8r8g8b8) {
1510f7df2e56Smrg        (*pScreen->GetImage) (pSrc->pDrawable,
1511f7df2e56Smrg                              0, 0, width, height, ZPixmap,
1512f7df2e56Smrg                              0xffffffff, (void *) argbbits);
1513f7df2e56Smrg    }
1514f7df2e56Smrg    else {
1515f7df2e56Smrg        PixmapPtr pPixmap;
1516f7df2e56Smrg        PicturePtr pPicture;
1517f7df2e56Smrg        PictFormatPtr pFormat;
1518f7df2e56Smrg        int error;
1519f7df2e56Smrg
1520f7df2e56Smrg        pFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8);
1521f7df2e56Smrg        if (!pFormat) {
1522f7df2e56Smrg            free(argbbits);
1523f7df2e56Smrg            free(srcbits);
1524f7df2e56Smrg            free(mskbits);
1525f7df2e56Smrg            return BadImplementation;
1526f7df2e56Smrg        }
1527f7df2e56Smrg        pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32,
1528f7df2e56Smrg                                            CREATE_PIXMAP_USAGE_SCRATCH);
1529f7df2e56Smrg        if (!pPixmap) {
1530f7df2e56Smrg            free(argbbits);
1531f7df2e56Smrg            free(srcbits);
1532f7df2e56Smrg            free(mskbits);
1533f7df2e56Smrg            return BadAlloc;
1534f7df2e56Smrg        }
1535f7df2e56Smrg        pPicture = CreatePicture(0, &pPixmap->drawable, pFormat, 0, 0,
1536f7df2e56Smrg                                 client, &error);
1537f7df2e56Smrg        if (!pPicture) {
1538f7df2e56Smrg            free(argbbits);
1539f7df2e56Smrg            free(srcbits);
1540f7df2e56Smrg            free(mskbits);
1541f7df2e56Smrg            return error;
1542f7df2e56Smrg        }
1543f7df2e56Smrg        (*pScreen->DestroyPixmap) (pPixmap);
1544f7df2e56Smrg        CompositePicture(PictOpSrc,
1545f7df2e56Smrg                         pSrc, 0, pPicture, 0, 0, 0, 0, 0, 0, width, height);
1546f7df2e56Smrg        (*pScreen->GetImage) (pPicture->pDrawable,
1547f7df2e56Smrg                              0, 0, width, height, ZPixmap,
1548f7df2e56Smrg                              0xffffffff, (void *) argbbits);
1549f7df2e56Smrg        FreePicture(pPicture, 0);
155005b261ecSmrg    }
155105b261ecSmrg    /*
1552f7df2e56Smrg     * Check whether the cursor can be directly supported by
155305b261ecSmrg     * the core cursor code
155405b261ecSmrg     */
155505b261ecSmrg    ncolor = 0;
155605b261ecSmrg    argb = argbbits;
1557f7df2e56Smrg    for (y = 0; ncolor <= 2 && y < height; y++) {
1558f7df2e56Smrg        for (x = 0; ncolor <= 2 && x < width; x++) {
1559f7df2e56Smrg            CARD32 p = *argb++;
1560f7df2e56Smrg            CARD32 a = (p >> 24);
1561f7df2e56Smrg
1562f7df2e56Smrg            if (a == 0)         /* transparent */
1563f7df2e56Smrg                continue;
1564f7df2e56Smrg            if (a == 0xff) {    /* opaque */
1565f7df2e56Smrg                int n;
1566f7df2e56Smrg
1567f7df2e56Smrg                for (n = 0; n < ncolor; n++)
1568f7df2e56Smrg                    if (p == twocolor[n])
1569f7df2e56Smrg                        break;
1570f7df2e56Smrg                if (n == ncolor)
1571f7df2e56Smrg                    twocolor[ncolor++] = p;
1572f7df2e56Smrg            }
1573f7df2e56Smrg            else
1574f7df2e56Smrg                ncolor = 3;
1575f7df2e56Smrg        }
1576f7df2e56Smrg    }
1577f7df2e56Smrg
157805b261ecSmrg    /*
157905b261ecSmrg     * Convert argb image to two plane cursor
158005b261ecSmrg     */
158105b261ecSmrg    srcline = srcbits;
158205b261ecSmrg    mskline = mskbits;
158305b261ecSmrg    argb = argbbits;
1584f7df2e56Smrg    for (y = 0; y < height; y++) {
1585f7df2e56Smrg        for (x = 0; x < width; x++) {
1586f7df2e56Smrg            CARD32 p = *argb++;
1587f7df2e56Smrg
1588f7df2e56Smrg            if (ncolor <= 2) {
1589f7df2e56Smrg                CARD32 a = ((p >> 24));
1590f7df2e56Smrg
1591f7df2e56Smrg                RenderSetBit(mskline, x, a != 0);
1592f7df2e56Smrg                RenderSetBit(srcline, x, a != 0 && p == twocolor[0]);
1593f7df2e56Smrg            }
1594f7df2e56Smrg            else {
1595f7df2e56Smrg                CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255;
1596f7df2e56Smrg                CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
1597f7df2e56Smrg                CARD32 d =
1598f7df2e56Smrg                    orderedDither[y & (DITHER_DIM - 1)][x & (DITHER_DIM - 1)];
1599f7df2e56Smrg                /* Set mask from dithered alpha value */
1600f7df2e56Smrg                RenderSetBit(mskline, x, a > d);
1601f7df2e56Smrg                /* Set src from dithered intensity value */
1602f7df2e56Smrg                RenderSetBit(srcline, x, a > d && i <= d);
1603f7df2e56Smrg            }
1604f7df2e56Smrg        }
1605f7df2e56Smrg        srcline += stride;
1606f7df2e56Smrg        mskline += stride;
160705b261ecSmrg    }
160805b261ecSmrg    /*
160905b261ecSmrg     * Dither to white and black if the cursor has more than two colors
161005b261ecSmrg     */
1611f7df2e56Smrg    if (ncolor > 2) {
1612f7df2e56Smrg        twocolor[0] = 0xff000000;
1613f7df2e56Smrg        twocolor[1] = 0xffffffff;
161405b261ecSmrg    }
1615f7df2e56Smrg    else {
1616f7df2e56Smrg        free(argbbits);
1617f7df2e56Smrg        argbbits = 0;
161805b261ecSmrg    }
1619f7df2e56Smrg
162005b261ecSmrg#define GetByte(p,s)	(((p) >> (s)) & 0xff)
162105b261ecSmrg#define GetColor(p,s)	(GetByte(p,s) | (GetByte(p,s) << 8))
1622f7df2e56Smrg
162305b261ecSmrg    cm.width = width;
162405b261ecSmrg    cm.height = height;
162505b261ecSmrg    cm.xhot = stuff->x;
162605b261ecSmrg    cm.yhot = stuff->y;
16274642e01fSmrg    rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm,
1628f7df2e56Smrg                         GetColor(twocolor[0], 16),
1629f7df2e56Smrg                         GetColor(twocolor[0], 8),
1630f7df2e56Smrg                         GetColor(twocolor[0], 0),
1631f7df2e56Smrg                         GetColor(twocolor[1], 16),
1632f7df2e56Smrg                         GetColor(twocolor[1], 8),
1633f7df2e56Smrg                         GetColor(twocolor[1], 0),
1634f7df2e56Smrg                         &pCursor, client, stuff->cid);
16354642e01fSmrg    if (rc != Success)
1636f7df2e56Smrg        goto bail;
1637f7df2e56Smrg    if (!AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) {
1638f7df2e56Smrg        rc = BadAlloc;
1639f7df2e56Smrg        goto bail;
1640f7df2e56Smrg    }
16414642e01fSmrg
16426747b715Smrg    return Success;
1643f7df2e56Smrg bail:
1644f7df2e56Smrg    free(srcbits);
1645f7df2e56Smrg    free(mskbits);
1646f7df2e56Smrg    return rc;
164705b261ecSmrg}
164805b261ecSmrg
164905b261ecSmrgstatic int
1650f7df2e56SmrgProcRenderSetPictureTransform(ClientPtr client)
165105b261ecSmrg{
165205b261ecSmrg    REQUEST(xRenderSetPictureTransformReq);
1653f7df2e56Smrg    PicturePtr pPicture;
165405b261ecSmrg
165505b261ecSmrg    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
1656f7df2e56Smrg    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
1657f7df2e56Smrg    return SetPictureTransform(pPicture, (PictTransform *) &stuff->transform);
165805b261ecSmrg}
165905b261ecSmrg
166005b261ecSmrgstatic int
1661f7df2e56SmrgProcRenderQueryFilters(ClientPtr client)
166205b261ecSmrg{
1663f7df2e56Smrg    REQUEST(xRenderQueryFiltersReq);
1664f7df2e56Smrg    DrawablePtr pDrawable;
1665f7df2e56Smrg    xRenderQueryFiltersReply *reply;
1666f7df2e56Smrg    int nbytesName;
1667f7df2e56Smrg    int nnames;
1668f7df2e56Smrg    ScreenPtr pScreen;
1669f7df2e56Smrg    PictureScreenPtr ps;
1670f7df2e56Smrg    int i, j, len, total_bytes, rc;
1671f7df2e56Smrg    INT16 *aliases;
1672f7df2e56Smrg    char *names;
167305b261ecSmrg
167405b261ecSmrg    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
167505b261ecSmrg    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
1676f7df2e56Smrg                           DixGetAttrAccess);
167705b261ecSmrg    if (rc != Success)
1678f7df2e56Smrg        return rc;
1679f7df2e56Smrg
168005b261ecSmrg    pScreen = pDrawable->pScreen;
168105b261ecSmrg    nbytesName = 0;
168205b261ecSmrg    nnames = 0;
168305b261ecSmrg    ps = GetPictureScreenIfSet(pScreen);
1684f7df2e56Smrg    if (ps) {
1685f7df2e56Smrg        for (i = 0; i < ps->nfilters; i++)
1686f7df2e56Smrg            nbytesName += 1 + strlen(ps->filters[i].name);
1687f7df2e56Smrg        for (i = 0; i < ps->nfilterAliases; i++)
1688f7df2e56Smrg            nbytesName += 1 + strlen(ps->filterAliases[i].alias);
1689f7df2e56Smrg        nnames = ps->nfilters + ps->nfilterAliases;
169005b261ecSmrg    }
16916747b715Smrg    len = ((nnames + 1) >> 1) + bytes_to_int32(nbytesName);
1692f7df2e56Smrg    total_bytes = sizeof(xRenderQueryFiltersReply) + (len << 2);
1693f7df2e56Smrg    reply = (xRenderQueryFiltersReply *) calloc(1, total_bytes);
169405b261ecSmrg    if (!reply)
1695f7df2e56Smrg        return BadAlloc;
169605b261ecSmrg    aliases = (INT16 *) (reply + 1);
169705b261ecSmrg    names = (char *) (aliases + ((nnames + 1) & ~1));
1698f7df2e56Smrg
169905b261ecSmrg    reply->type = X_Reply;
170005b261ecSmrg    reply->sequenceNumber = client->sequence;
170105b261ecSmrg    reply->length = len;
170205b261ecSmrg    reply->numAliases = nnames;
170305b261ecSmrg    reply->numFilters = nnames;
1704f7df2e56Smrg    if (ps) {
1705f7df2e56Smrg
1706f7df2e56Smrg        /* fill in alias values */
1707f7df2e56Smrg        for (i = 0; i < ps->nfilters; i++)
1708f7df2e56Smrg            aliases[i] = FilterAliasNone;
1709f7df2e56Smrg        for (i = 0; i < ps->nfilterAliases; i++) {
1710f7df2e56Smrg            for (j = 0; j < ps->nfilters; j++)
1711f7df2e56Smrg                if (ps->filterAliases[i].filter_id == ps->filters[j].id)
1712f7df2e56Smrg                    break;
1713f7df2e56Smrg            if (j == ps->nfilters) {
1714f7df2e56Smrg                for (j = 0; j < ps->nfilterAliases; j++)
1715f7df2e56Smrg                    if (ps->filterAliases[i].filter_id ==
1716f7df2e56Smrg                        ps->filterAliases[j].alias_id) {
1717f7df2e56Smrg                        break;
1718f7df2e56Smrg                    }
1719f7df2e56Smrg                if (j == ps->nfilterAliases)
1720f7df2e56Smrg                    j = FilterAliasNone;
1721f7df2e56Smrg                else
1722f7df2e56Smrg                    j = j + ps->nfilters;
1723f7df2e56Smrg            }
1724f7df2e56Smrg            aliases[i + ps->nfilters] = j;
1725f7df2e56Smrg        }
1726f7df2e56Smrg
1727f7df2e56Smrg        /* fill in filter names */
1728f7df2e56Smrg        for (i = 0; i < ps->nfilters; i++) {
1729f7df2e56Smrg            j = strlen(ps->filters[i].name);
1730f7df2e56Smrg            *names++ = j;
1731f7df2e56Smrg            memcpy(names, ps->filters[i].name, j);
1732f7df2e56Smrg            names += j;
1733f7df2e56Smrg        }
1734f7df2e56Smrg
1735f7df2e56Smrg        /* fill in filter alias names */
1736f7df2e56Smrg        for (i = 0; i < ps->nfilterAliases; i++) {
1737f7df2e56Smrg            j = strlen(ps->filterAliases[i].alias);
1738f7df2e56Smrg            *names++ = j;
1739f7df2e56Smrg            memcpy(names, ps->filterAliases[i].alias, j);
1740f7df2e56Smrg            names += j;
1741f7df2e56Smrg        }
1742f7df2e56Smrg    }
1743f7df2e56Smrg
1744f7df2e56Smrg    if (client->swapped) {
1745f7df2e56Smrg        for (i = 0; i < reply->numAliases; i++) {
1746f7df2e56Smrg            swaps(&aliases[i]);
1747f7df2e56Smrg        }
1748f7df2e56Smrg        swaps(&reply->sequenceNumber);
1749f7df2e56Smrg        swapl(&reply->length);
1750f7df2e56Smrg        swapl(&reply->numAliases);
1751f7df2e56Smrg        swapl(&reply->numFilters);
1752f7df2e56Smrg    }
1753f7df2e56Smrg    WriteToClient(client, total_bytes, reply);
17546747b715Smrg    free(reply);
1755f7df2e56Smrg
17566747b715Smrg    return Success;
175705b261ecSmrg}
175805b261ecSmrg
175905b261ecSmrgstatic int
1760f7df2e56SmrgProcRenderSetPictureFilter(ClientPtr client)
176105b261ecSmrg{
1762f7df2e56Smrg    REQUEST(xRenderSetPictureFilterReq);
1763f7df2e56Smrg    PicturePtr pPicture;
1764f7df2e56Smrg    int result;
1765f7df2e56Smrg    xFixed *params;
1766f7df2e56Smrg    int nparams;
1767f7df2e56Smrg    char *name;
1768f7df2e56Smrg
1769f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
1770f7df2e56Smrg    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
177105b261ecSmrg    name = (char *) (stuff + 1);
17726747b715Smrg    params = (xFixed *) (name + pad_to_int32(stuff->nbytes));
177305b261ecSmrg    nparams = ((xFixed *) stuff + client->req_len) - params;
1774f7df2e56Smrg    result = SetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
177505b261ecSmrg    return result;
177605b261ecSmrg}
177705b261ecSmrg
177805b261ecSmrgstatic int
1779f7df2e56SmrgProcRenderCreateAnimCursor(ClientPtr client)
178005b261ecSmrg{
178105b261ecSmrg    REQUEST(xRenderCreateAnimCursorReq);
1782f7df2e56Smrg    CursorPtr *cursors;
1783f7df2e56Smrg    CARD32 *deltas;
1784f7df2e56Smrg    CursorPtr pCursor;
1785f7df2e56Smrg    int ncursor;
1786f7df2e56Smrg    xAnimCursorElt *elt;
1787f7df2e56Smrg    int i;
1788f7df2e56Smrg    int ret;
178905b261ecSmrg
179005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
179105b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
179205b261ecSmrg    if (client->req_len & 1)
1793f7df2e56Smrg        return BadLength;
1794f7df2e56Smrg    ncursor =
1795f7df2e56Smrg        (client->req_len -
1796f7df2e56Smrg         (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1;
1797f7df2e56Smrg    cursors = xallocarray(ncursor, sizeof(CursorPtr) + sizeof(CARD32));
179805b261ecSmrg    if (!cursors)
1799f7df2e56Smrg        return BadAlloc;
180005b261ecSmrg    deltas = (CARD32 *) (cursors + ncursor);
180105b261ecSmrg    elt = (xAnimCursorElt *) (stuff + 1);
1802f7df2e56Smrg    for (i = 0; i < ncursor; i++) {
1803f7df2e56Smrg        ret = dixLookupResourceByType((void **) (cursors + i), elt->cursor,
1804f7df2e56Smrg                                      RT_CURSOR, client, DixReadAccess);
1805f7df2e56Smrg        if (ret != Success) {
1806f7df2e56Smrg            free(cursors);
1807f7df2e56Smrg            return ret;
1808f7df2e56Smrg        }
1809f7df2e56Smrg        deltas[i] = elt->delay;
1810f7df2e56Smrg        elt++;
1811f7df2e56Smrg    }
1812f7df2e56Smrg    ret = AnimCursorCreate(cursors, deltas, ncursor, &pCursor, client,
1813f7df2e56Smrg                           stuff->cid);
18146747b715Smrg    free(cursors);
181505b261ecSmrg    if (ret != Success)
1816f7df2e56Smrg        return ret;
1817f7df2e56Smrg
1818f7df2e56Smrg    if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor))
1819f7df2e56Smrg        return Success;
182005b261ecSmrg    return BadAlloc;
182105b261ecSmrg}
182205b261ecSmrg
182305b261ecSmrgstatic int
1824f7df2e56SmrgProcRenderAddTraps(ClientPtr client)
182505b261ecSmrg{
1826f7df2e56Smrg    int ntraps;
1827f7df2e56Smrg    PicturePtr pPicture;
1828f7df2e56Smrg
182905b261ecSmrg    REQUEST(xRenderAddTrapsReq);
183005b261ecSmrg
183105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
1832f7df2e56Smrg    VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess);
183305b261ecSmrg    if (!pPicture->pDrawable)
183405b261ecSmrg        return BadDrawable;
1835f7df2e56Smrg    ntraps = (client->req_len << 2) - sizeof(xRenderAddTrapsReq);
1836f7df2e56Smrg    if (ntraps % sizeof(xTrap))
1837f7df2e56Smrg        return BadLength;
1838f7df2e56Smrg    ntraps /= sizeof(xTrap);
183905b261ecSmrg    if (ntraps)
1840f7df2e56Smrg        AddTraps(pPicture,
1841f7df2e56Smrg                 stuff->xOff, stuff->yOff, ntraps, (xTrap *) &stuff[1]);
18426747b715Smrg    return Success;
184305b261ecSmrg}
184405b261ecSmrg
1845f7df2e56Smrgstatic int
1846f7df2e56SmrgProcRenderCreateSolidFill(ClientPtr client)
184705b261ecSmrg{
1848f7df2e56Smrg    PicturePtr pPicture;
1849f7df2e56Smrg    int error = 0;
1850f7df2e56Smrg
185105b261ecSmrg    REQUEST(xRenderCreateSolidFillReq);
185205b261ecSmrg
185305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
185405b261ecSmrg
185505b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
185605b261ecSmrg
185705b261ecSmrg    pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
185805b261ecSmrg    if (!pPicture)
1859f7df2e56Smrg        return error;
18604642e01fSmrg    /* security creation/labeling check */
18614642e01fSmrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1862f7df2e56Smrg                     pPicture, RT_NONE, NULL, DixCreateAccess);
18634642e01fSmrg    if (error != Success)
1864f7df2e56Smrg        return error;
1865f7df2e56Smrg    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
1866f7df2e56Smrg        return BadAlloc;
186705b261ecSmrg    return Success;
186805b261ecSmrg}
186905b261ecSmrg
1870f7df2e56Smrgstatic int
1871f7df2e56SmrgProcRenderCreateLinearGradient(ClientPtr client)
187205b261ecSmrg{
1873f7df2e56Smrg    PicturePtr pPicture;
1874f7df2e56Smrg    int len;
1875f7df2e56Smrg    int error = 0;
1876f7df2e56Smrg    xFixed *stops;
1877f7df2e56Smrg    xRenderColor *colors;
1878f7df2e56Smrg
187905b261ecSmrg    REQUEST(xRenderCreateLinearGradientReq);
188005b261ecSmrg
188105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
188205b261ecSmrg
188305b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
188405b261ecSmrg
188505b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
1886f7df2e56Smrg    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
1887f7df2e56Smrg        return BadLength;
1888f7df2e56Smrg    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
188905b261ecSmrg        return BadLength;
189005b261ecSmrg
1891f7df2e56Smrg    stops = (xFixed *) (stuff + 1);
1892f7df2e56Smrg    colors = (xRenderColor *) (stops + stuff->nStops);
189305b261ecSmrg
1894f7df2e56Smrg    pPicture = CreateLinearGradientPicture(stuff->pid, &stuff->p1, &stuff->p2,
1895f7df2e56Smrg                                           stuff->nStops, stops, colors,
1896f7df2e56Smrg                                           &error);
189705b261ecSmrg    if (!pPicture)
1898f7df2e56Smrg        return error;
18994642e01fSmrg    /* security creation/labeling check */
19004642e01fSmrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1901f7df2e56Smrg                     pPicture, RT_NONE, NULL, DixCreateAccess);
19024642e01fSmrg    if (error != Success)
1903f7df2e56Smrg        return error;
1904f7df2e56Smrg    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
1905f7df2e56Smrg        return BadAlloc;
190605b261ecSmrg    return Success;
190705b261ecSmrg}
190805b261ecSmrg
1909f7df2e56Smrgstatic int
1910f7df2e56SmrgProcRenderCreateRadialGradient(ClientPtr client)
191105b261ecSmrg{
1912f7df2e56Smrg    PicturePtr pPicture;
1913f7df2e56Smrg    int len;
1914f7df2e56Smrg    int error = 0;
1915f7df2e56Smrg    xFixed *stops;
1916f7df2e56Smrg    xRenderColor *colors;
1917f7df2e56Smrg
191805b261ecSmrg    REQUEST(xRenderCreateRadialGradientReq);
191905b261ecSmrg
192005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
192105b261ecSmrg
192205b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
192305b261ecSmrg
192405b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
1925f7df2e56Smrg    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
192605b261ecSmrg        return BadLength;
192705b261ecSmrg
1928f7df2e56Smrg    stops = (xFixed *) (stuff + 1);
1929f7df2e56Smrg    colors = (xRenderColor *) (stops + stuff->nStops);
193005b261ecSmrg
1931f7df2e56Smrg    pPicture =
1932f7df2e56Smrg        CreateRadialGradientPicture(stuff->pid, &stuff->inner, &stuff->outer,
1933f7df2e56Smrg                                    stuff->inner_radius, stuff->outer_radius,
1934f7df2e56Smrg                                    stuff->nStops, stops, colors, &error);
193505b261ecSmrg    if (!pPicture)
1936f7df2e56Smrg        return error;
19374642e01fSmrg    /* security creation/labeling check */
19384642e01fSmrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1939f7df2e56Smrg                     pPicture, RT_NONE, NULL, DixCreateAccess);
19404642e01fSmrg    if (error != Success)
1941f7df2e56Smrg        return error;
1942f7df2e56Smrg    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
1943f7df2e56Smrg        return BadAlloc;
194405b261ecSmrg    return Success;
194505b261ecSmrg}
194605b261ecSmrg
1947f7df2e56Smrgstatic int
1948f7df2e56SmrgProcRenderCreateConicalGradient(ClientPtr client)
194905b261ecSmrg{
1950f7df2e56Smrg    PicturePtr pPicture;
1951f7df2e56Smrg    int len;
1952f7df2e56Smrg    int error = 0;
1953f7df2e56Smrg    xFixed *stops;
1954f7df2e56Smrg    xRenderColor *colors;
1955f7df2e56Smrg
195605b261ecSmrg    REQUEST(xRenderCreateConicalGradientReq);
195705b261ecSmrg
195805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
195905b261ecSmrg
196005b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
196105b261ecSmrg
196205b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
1963f7df2e56Smrg    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
196405b261ecSmrg        return BadLength;
196505b261ecSmrg
1966f7df2e56Smrg    stops = (xFixed *) (stuff + 1);
1967f7df2e56Smrg    colors = (xRenderColor *) (stops + stuff->nStops);
196805b261ecSmrg
1969f7df2e56Smrg    pPicture =
1970f7df2e56Smrg        CreateConicalGradientPicture(stuff->pid, &stuff->center, stuff->angle,
1971f7df2e56Smrg                                     stuff->nStops, stops, colors, &error);
197205b261ecSmrg    if (!pPicture)
1973f7df2e56Smrg        return error;
19744642e01fSmrg    /* security creation/labeling check */
19754642e01fSmrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1976f7df2e56Smrg                     pPicture, RT_NONE, NULL, DixCreateAccess);
19774642e01fSmrg    if (error != Success)
1978f7df2e56Smrg        return error;
1979f7df2e56Smrg    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
1980f7df2e56Smrg        return BadAlloc;
198105b261ecSmrg    return Success;
198205b261ecSmrg}
198305b261ecSmrg
198405b261ecSmrgstatic int
1985f7df2e56SmrgProcRenderDispatch(ClientPtr client)
198605b261ecSmrg{
198705b261ecSmrg    REQUEST(xReq);
1988f7df2e56Smrg
198905b261ecSmrg    if (stuff->data < RenderNumberRequests)
1990f7df2e56Smrg        return (*ProcRenderVector[stuff->data]) (client);
199105b261ecSmrg    else
1992f7df2e56Smrg        return BadRequest;
199305b261ecSmrg}
199405b261ecSmrg
199505b261ecSmrgstatic int
1996f7df2e56SmrgSProcRenderQueryVersion(ClientPtr client)
199705b261ecSmrg{
199805b261ecSmrg    REQUEST(xRenderQueryVersionReq);
19990b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
2000f7df2e56Smrg    swaps(&stuff->length);
2001f7df2e56Smrg    swapl(&stuff->majorVersion);
2002f7df2e56Smrg    swapl(&stuff->minorVersion);
2003f7df2e56Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
200405b261ecSmrg}
200505b261ecSmrg
200605b261ecSmrgstatic int
2007f7df2e56SmrgSProcRenderQueryPictFormats(ClientPtr client)
200805b261ecSmrg{
200905b261ecSmrg    REQUEST(xRenderQueryPictFormatsReq);
20100b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
2011f7df2e56Smrg    swaps(&stuff->length);
201205b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
201305b261ecSmrg}
201405b261ecSmrg
201505b261ecSmrgstatic int
2016f7df2e56SmrgSProcRenderQueryPictIndexValues(ClientPtr client)
201705b261ecSmrg{
201805b261ecSmrg    REQUEST(xRenderQueryPictIndexValuesReq);
20190b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
2020f7df2e56Smrg    swaps(&stuff->length);
2021f7df2e56Smrg    swapl(&stuff->format);
202205b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
202305b261ecSmrg}
202405b261ecSmrg
202505b261ecSmrgstatic int
2026f7df2e56SmrgSProcRenderQueryDithers(ClientPtr client)
202705b261ecSmrg{
202805b261ecSmrg    return BadImplementation;
202905b261ecSmrg}
203005b261ecSmrg
203105b261ecSmrgstatic int
2032f7df2e56SmrgSProcRenderCreatePicture(ClientPtr client)
203305b261ecSmrg{
203405b261ecSmrg    REQUEST(xRenderCreatePictureReq);
20350b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2036f7df2e56Smrg    swaps(&stuff->length);
2037f7df2e56Smrg    swapl(&stuff->pid);
2038f7df2e56Smrg    swapl(&stuff->drawable);
2039f7df2e56Smrg    swapl(&stuff->format);
2040f7df2e56Smrg    swapl(&stuff->mask);
204105b261ecSmrg    SwapRestL(stuff);
204205b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
204305b261ecSmrg}
204405b261ecSmrg
204505b261ecSmrgstatic int
2046f7df2e56SmrgSProcRenderChangePicture(ClientPtr client)
204705b261ecSmrg{
204805b261ecSmrg    REQUEST(xRenderChangePictureReq);
20490b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
2050f7df2e56Smrg    swaps(&stuff->length);
2051f7df2e56Smrg    swapl(&stuff->picture);
2052f7df2e56Smrg    swapl(&stuff->mask);
205305b261ecSmrg    SwapRestL(stuff);
205405b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
205505b261ecSmrg}
205605b261ecSmrg
205705b261ecSmrgstatic int
2058f7df2e56SmrgSProcRenderSetPictureClipRectangles(ClientPtr client)
205905b261ecSmrg{
206005b261ecSmrg    REQUEST(xRenderSetPictureClipRectanglesReq);
20610b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
2062f7df2e56Smrg    swaps(&stuff->length);
2063f7df2e56Smrg    swapl(&stuff->picture);
2064f7df2e56Smrg    swaps(&stuff->xOrigin);
2065f7df2e56Smrg    swaps(&stuff->yOrigin);
206605b261ecSmrg    SwapRestS(stuff);
206705b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
206805b261ecSmrg}
206905b261ecSmrg
207005b261ecSmrgstatic int
2071f7df2e56SmrgSProcRenderFreePicture(ClientPtr client)
207205b261ecSmrg{
207305b261ecSmrg    REQUEST(xRenderFreePictureReq);
20740b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
2075f7df2e56Smrg    swaps(&stuff->length);
2076f7df2e56Smrg    swapl(&stuff->picture);
207705b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
207805b261ecSmrg}
207905b261ecSmrg
208005b261ecSmrgstatic int
2081f7df2e56SmrgSProcRenderComposite(ClientPtr client)
208205b261ecSmrg{
208305b261ecSmrg    REQUEST(xRenderCompositeReq);
20840b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
2085f7df2e56Smrg    swaps(&stuff->length);
2086f7df2e56Smrg    swapl(&stuff->src);
2087f7df2e56Smrg    swapl(&stuff->mask);
2088f7df2e56Smrg    swapl(&stuff->dst);
2089f7df2e56Smrg    swaps(&stuff->xSrc);
2090f7df2e56Smrg    swaps(&stuff->ySrc);
2091f7df2e56Smrg    swaps(&stuff->xMask);
2092f7df2e56Smrg    swaps(&stuff->yMask);
2093f7df2e56Smrg    swaps(&stuff->xDst);
2094f7df2e56Smrg    swaps(&stuff->yDst);
2095f7df2e56Smrg    swaps(&stuff->width);
2096f7df2e56Smrg    swaps(&stuff->height);
209705b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
209805b261ecSmrg}
209905b261ecSmrg
210005b261ecSmrgstatic int
2101f7df2e56SmrgSProcRenderScale(ClientPtr client)
210205b261ecSmrg{
2103f7df2e56Smrg    return BadImplementation;
210405b261ecSmrg}
210505b261ecSmrg
210605b261ecSmrgstatic int
2107f7df2e56SmrgSProcRenderTrapezoids(ClientPtr client)
210805b261ecSmrg{
210905b261ecSmrg    REQUEST(xRenderTrapezoidsReq);
211005b261ecSmrg
211105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
2112f7df2e56Smrg    swaps(&stuff->length);
2113f7df2e56Smrg    swapl(&stuff->src);
2114f7df2e56Smrg    swapl(&stuff->dst);
2115f7df2e56Smrg    swapl(&stuff->maskFormat);
2116f7df2e56Smrg    swaps(&stuff->xSrc);
2117f7df2e56Smrg    swaps(&stuff->ySrc);
211805b261ecSmrg    SwapRestL(stuff);
211905b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
212005b261ecSmrg}
212105b261ecSmrg
212205b261ecSmrgstatic int
2123f7df2e56SmrgSProcRenderTriangles(ClientPtr client)
212405b261ecSmrg{
212505b261ecSmrg    REQUEST(xRenderTrianglesReq);
212605b261ecSmrg
212705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
2128f7df2e56Smrg    swaps(&stuff->length);
2129f7df2e56Smrg    swapl(&stuff->src);
2130f7df2e56Smrg    swapl(&stuff->dst);
2131f7df2e56Smrg    swapl(&stuff->maskFormat);
2132f7df2e56Smrg    swaps(&stuff->xSrc);
2133f7df2e56Smrg    swaps(&stuff->ySrc);
213405b261ecSmrg    SwapRestL(stuff);
213505b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
213605b261ecSmrg}
213705b261ecSmrg
213805b261ecSmrgstatic int
2139f7df2e56SmrgSProcRenderTriStrip(ClientPtr client)
214005b261ecSmrg{
214105b261ecSmrg    REQUEST(xRenderTriStripReq);
214205b261ecSmrg
214305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
2144f7df2e56Smrg    swaps(&stuff->length);
2145f7df2e56Smrg    swapl(&stuff->src);
2146f7df2e56Smrg    swapl(&stuff->dst);
2147f7df2e56Smrg    swapl(&stuff->maskFormat);
2148f7df2e56Smrg    swaps(&stuff->xSrc);
2149f7df2e56Smrg    swaps(&stuff->ySrc);
215005b261ecSmrg    SwapRestL(stuff);
215105b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
215205b261ecSmrg}
215305b261ecSmrg
215405b261ecSmrgstatic int
2155f7df2e56SmrgSProcRenderTriFan(ClientPtr client)
215605b261ecSmrg{
215705b261ecSmrg    REQUEST(xRenderTriFanReq);
215805b261ecSmrg
215905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
2160f7df2e56Smrg    swaps(&stuff->length);
2161f7df2e56Smrg    swapl(&stuff->src);
2162f7df2e56Smrg    swapl(&stuff->dst);
2163f7df2e56Smrg    swapl(&stuff->maskFormat);
2164f7df2e56Smrg    swaps(&stuff->xSrc);
2165f7df2e56Smrg    swaps(&stuff->ySrc);
216605b261ecSmrg    SwapRestL(stuff);
216705b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
216805b261ecSmrg}
216905b261ecSmrg
217005b261ecSmrgstatic int
2171f7df2e56SmrgSProcRenderColorTrapezoids(ClientPtr client)
217205b261ecSmrg{
217305b261ecSmrg    return BadImplementation;
217405b261ecSmrg}
217505b261ecSmrg
217605b261ecSmrgstatic int
2177f7df2e56SmrgSProcRenderColorTriangles(ClientPtr client)
217805b261ecSmrg{
217905b261ecSmrg    return BadImplementation;
218005b261ecSmrg}
218105b261ecSmrg
218205b261ecSmrgstatic int
2183f7df2e56SmrgSProcRenderTransform(ClientPtr client)
218405b261ecSmrg{
218505b261ecSmrg    return BadImplementation;
218605b261ecSmrg}
218705b261ecSmrg
218805b261ecSmrgstatic int
2189f7df2e56SmrgSProcRenderCreateGlyphSet(ClientPtr client)
219005b261ecSmrg{
219105b261ecSmrg    REQUEST(xRenderCreateGlyphSetReq);
21920b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
2193f7df2e56Smrg    swaps(&stuff->length);
2194f7df2e56Smrg    swapl(&stuff->gsid);
2195f7df2e56Smrg    swapl(&stuff->format);
219605b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
219705b261ecSmrg}
219805b261ecSmrg
219905b261ecSmrgstatic int
2200f7df2e56SmrgSProcRenderReferenceGlyphSet(ClientPtr client)
220105b261ecSmrg{
220205b261ecSmrg    REQUEST(xRenderReferenceGlyphSetReq);
22030b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
2204f7df2e56Smrg    swaps(&stuff->length);
2205f7df2e56Smrg    swapl(&stuff->gsid);
2206f7df2e56Smrg    swapl(&stuff->existing);
2207f7df2e56Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
220805b261ecSmrg}
220905b261ecSmrg
221005b261ecSmrgstatic int
2211f7df2e56SmrgSProcRenderFreeGlyphSet(ClientPtr client)
221205b261ecSmrg{
221305b261ecSmrg    REQUEST(xRenderFreeGlyphSetReq);
22140b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
2215f7df2e56Smrg    swaps(&stuff->length);
2216f7df2e56Smrg    swapl(&stuff->glyphset);
221705b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
221805b261ecSmrg}
221905b261ecSmrg
222005b261ecSmrgstatic int
2221f7df2e56SmrgSProcRenderAddGlyphs(ClientPtr client)
222205b261ecSmrg{
222305b261ecSmrg    register int i;
2224f7df2e56Smrg    CARD32 *gids;
2225f7df2e56Smrg    void *end;
222605b261ecSmrg    xGlyphInfo *gi;
2227f7df2e56Smrg
222805b261ecSmrg    REQUEST(xRenderAddGlyphsReq);
22290b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
2230f7df2e56Smrg    swaps(&stuff->length);
2231f7df2e56Smrg    swapl(&stuff->glyphset);
2232f7df2e56Smrg    swapl(&stuff->nglyphs);
223305b261ecSmrg    if (stuff->nglyphs & 0xe0000000)
2234f7df2e56Smrg        return BadLength;
223505b261ecSmrg    end = (CARD8 *) stuff + (client->req_len << 2);
223605b261ecSmrg    gids = (CARD32 *) (stuff + 1);
223705b261ecSmrg    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
223805b261ecSmrg    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
2239f7df2e56Smrg        return BadLength;
224005b261ecSmrg    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
2241f7df2e56Smrg        return BadLength;
2242f7df2e56Smrg    for (i = 0; i < stuff->nglyphs; i++) {
2243f7df2e56Smrg        swapl(&gids[i]);
2244f7df2e56Smrg        swaps(&gi[i].width);
2245f7df2e56Smrg        swaps(&gi[i].height);
2246f7df2e56Smrg        swaps(&gi[i].x);
2247f7df2e56Smrg        swaps(&gi[i].y);
2248f7df2e56Smrg        swaps(&gi[i].xOff);
2249f7df2e56Smrg        swaps(&gi[i].yOff);
225005b261ecSmrg    }
225105b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
225205b261ecSmrg}
225305b261ecSmrg
225405b261ecSmrgstatic int
2255f7df2e56SmrgSProcRenderAddGlyphsFromPicture(ClientPtr client)
225605b261ecSmrg{
225705b261ecSmrg    return BadImplementation;
225805b261ecSmrg}
225905b261ecSmrg
226005b261ecSmrgstatic int
2261f7df2e56SmrgSProcRenderFreeGlyphs(ClientPtr client)
226205b261ecSmrg{
226305b261ecSmrg    REQUEST(xRenderFreeGlyphsReq);
22640b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
2265f7df2e56Smrg    swaps(&stuff->length);
2266f7df2e56Smrg    swapl(&stuff->glyphset);
226705b261ecSmrg    SwapRestL(stuff);
226805b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
226905b261ecSmrg}
227005b261ecSmrg
227105b261ecSmrgstatic int
2272f7df2e56SmrgSProcRenderCompositeGlyphs(ClientPtr client)
227305b261ecSmrg{
2274f7df2e56Smrg    xGlyphElt *elt;
2275f7df2e56Smrg    CARD8 *buffer;
2276f7df2e56Smrg    CARD8 *end;
2277f7df2e56Smrg    int space;
2278f7df2e56Smrg    int i;
2279f7df2e56Smrg    int size;
2280f7df2e56Smrg
228105b261ecSmrg    REQUEST(xRenderCompositeGlyphsReq);
22820b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
2283f7df2e56Smrg
228405b261ecSmrg    switch (stuff->renderReqType) {
2285f7df2e56Smrg    default:
2286f7df2e56Smrg        size = 1;
2287f7df2e56Smrg        break;
2288f7df2e56Smrg    case X_RenderCompositeGlyphs16:
2289f7df2e56Smrg        size = 2;
2290f7df2e56Smrg        break;
2291f7df2e56Smrg    case X_RenderCompositeGlyphs32:
2292f7df2e56Smrg        size = 4;
2293f7df2e56Smrg        break;
2294f7df2e56Smrg    }
2295f7df2e56Smrg
2296f7df2e56Smrg    swaps(&stuff->length);
2297f7df2e56Smrg    swapl(&stuff->src);
2298f7df2e56Smrg    swapl(&stuff->dst);
2299f7df2e56Smrg    swapl(&stuff->maskFormat);
2300f7df2e56Smrg    swapl(&stuff->glyphset);
2301f7df2e56Smrg    swaps(&stuff->xSrc);
2302f7df2e56Smrg    swaps(&stuff->ySrc);
230305b261ecSmrg    buffer = (CARD8 *) (stuff + 1);
230405b261ecSmrg    end = (CARD8 *) stuff + (client->req_len << 2);
2305f7df2e56Smrg    while (buffer + sizeof(xGlyphElt) < end) {
2306f7df2e56Smrg        elt = (xGlyphElt *) buffer;
2307f7df2e56Smrg        buffer += sizeof(xGlyphElt);
2308f7df2e56Smrg
2309f7df2e56Smrg        swaps(&elt->deltax);
2310f7df2e56Smrg        swaps(&elt->deltay);
2311f7df2e56Smrg
2312f7df2e56Smrg        i = elt->len;
2313f7df2e56Smrg        if (i == 0xff) {
2314f7df2e56Smrg            swapl((int *) buffer);
2315f7df2e56Smrg            buffer += 4;
2316f7df2e56Smrg        }
2317f7df2e56Smrg        else {
2318f7df2e56Smrg            space = size * i;
2319f7df2e56Smrg            switch (size) {
2320f7df2e56Smrg            case 1:
2321f7df2e56Smrg                buffer += i;
2322f7df2e56Smrg                break;
2323f7df2e56Smrg            case 2:
2324f7df2e56Smrg                while (i--) {
2325f7df2e56Smrg                    swaps((short *) buffer);
2326f7df2e56Smrg                    buffer += 2;
2327f7df2e56Smrg                }
2328f7df2e56Smrg                break;
2329f7df2e56Smrg            case 4:
2330f7df2e56Smrg                while (i--) {
2331f7df2e56Smrg                    swapl((int *) buffer);
2332f7df2e56Smrg                    buffer += 4;
2333f7df2e56Smrg                }
2334f7df2e56Smrg                break;
2335f7df2e56Smrg            }
2336f7df2e56Smrg            if (space & 3)
2337f7df2e56Smrg                buffer += 4 - (space & 3);
2338f7df2e56Smrg        }
233905b261ecSmrg    }
234005b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
234105b261ecSmrg}
234205b261ecSmrg
234305b261ecSmrgstatic int
2344f7df2e56SmrgSProcRenderFillRectangles(ClientPtr client)
234505b261ecSmrg{
234605b261ecSmrg    REQUEST(xRenderFillRectanglesReq);
234705b261ecSmrg
2348f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
2349f7df2e56Smrg    swaps(&stuff->length);
2350f7df2e56Smrg    swapl(&stuff->dst);
2351f7df2e56Smrg    swaps(&stuff->color.red);
2352f7df2e56Smrg    swaps(&stuff->color.green);
2353f7df2e56Smrg    swaps(&stuff->color.blue);
2354f7df2e56Smrg    swaps(&stuff->color.alpha);
235505b261ecSmrg    SwapRestS(stuff);
235605b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
235705b261ecSmrg}
2358f7df2e56Smrg
235905b261ecSmrgstatic int
2360f7df2e56SmrgSProcRenderCreateCursor(ClientPtr client)
236105b261ecSmrg{
236205b261ecSmrg    REQUEST(xRenderCreateCursorReq);
2363f7df2e56Smrg    REQUEST_SIZE_MATCH(xRenderCreateCursorReq);
2364f7df2e56Smrg
2365f7df2e56Smrg    swaps(&stuff->length);
2366f7df2e56Smrg    swapl(&stuff->cid);
2367f7df2e56Smrg    swapl(&stuff->src);
2368f7df2e56Smrg    swaps(&stuff->x);
2369f7df2e56Smrg    swaps(&stuff->y);
237005b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
237105b261ecSmrg}
2372f7df2e56Smrg
237305b261ecSmrgstatic int
2374f7df2e56SmrgSProcRenderSetPictureTransform(ClientPtr client)
237505b261ecSmrg{
237605b261ecSmrg    REQUEST(xRenderSetPictureTransformReq);
237705b261ecSmrg    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
237805b261ecSmrg
2379f7df2e56Smrg    swaps(&stuff->length);
2380f7df2e56Smrg    swapl(&stuff->picture);
2381f7df2e56Smrg    swapl(&stuff->transform.matrix11);
2382f7df2e56Smrg    swapl(&stuff->transform.matrix12);
2383f7df2e56Smrg    swapl(&stuff->transform.matrix13);
2384f7df2e56Smrg    swapl(&stuff->transform.matrix21);
2385f7df2e56Smrg    swapl(&stuff->transform.matrix22);
2386f7df2e56Smrg    swapl(&stuff->transform.matrix23);
2387f7df2e56Smrg    swapl(&stuff->transform.matrix31);
2388f7df2e56Smrg    swapl(&stuff->transform.matrix32);
2389f7df2e56Smrg    swapl(&stuff->transform.matrix33);
239005b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
239105b261ecSmrg}
239205b261ecSmrg
239305b261ecSmrgstatic int
2394f7df2e56SmrgSProcRenderQueryFilters(ClientPtr client)
239505b261ecSmrg{
2396f7df2e56Smrg    REQUEST(xRenderQueryFiltersReq);
2397f7df2e56Smrg    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
239805b261ecSmrg
2399f7df2e56Smrg    swaps(&stuff->length);
2400f7df2e56Smrg    swapl(&stuff->drawable);
240105b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
240205b261ecSmrg}
2403f7df2e56Smrg
240405b261ecSmrgstatic int
2405f7df2e56SmrgSProcRenderSetPictureFilter(ClientPtr client)
240605b261ecSmrg{
2407f7df2e56Smrg    REQUEST(xRenderSetPictureFilterReq);
2408f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
240905b261ecSmrg
2410f7df2e56Smrg    swaps(&stuff->length);
2411f7df2e56Smrg    swapl(&stuff->picture);
2412f7df2e56Smrg    swaps(&stuff->nbytes);
241305b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
241405b261ecSmrg}
2415f7df2e56Smrg
241605b261ecSmrgstatic int
2417f7df2e56SmrgSProcRenderCreateAnimCursor(ClientPtr client)
241805b261ecSmrg{
2419f7df2e56Smrg    REQUEST(xRenderCreateAnimCursorReq);
2420f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
242105b261ecSmrg
2422f7df2e56Smrg    swaps(&stuff->length);
2423f7df2e56Smrg    swapl(&stuff->cid);
242405b261ecSmrg    SwapRestL(stuff);
242505b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
242605b261ecSmrg}
242705b261ecSmrg
242805b261ecSmrgstatic int
2429f7df2e56SmrgSProcRenderAddTraps(ClientPtr client)
243005b261ecSmrg{
2431f7df2e56Smrg    REQUEST(xRenderAddTrapsReq);
2432f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
243305b261ecSmrg
2434f7df2e56Smrg    swaps(&stuff->length);
2435f7df2e56Smrg    swapl(&stuff->picture);
2436f7df2e56Smrg    swaps(&stuff->xOff);
2437f7df2e56Smrg    swaps(&stuff->yOff);
243805b261ecSmrg    SwapRestL(stuff);
243905b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
244005b261ecSmrg}
244105b261ecSmrg
244205b261ecSmrgstatic int
244305b261ecSmrgSProcRenderCreateSolidFill(ClientPtr client)
244405b261ecSmrg{
2445f7df2e56Smrg    REQUEST(xRenderCreateSolidFillReq);
2446f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
244705b261ecSmrg
2448f7df2e56Smrg    swaps(&stuff->length);
2449f7df2e56Smrg    swapl(&stuff->pid);
2450f7df2e56Smrg    swaps(&stuff->color.alpha);
2451f7df2e56Smrg    swaps(&stuff->color.red);
2452f7df2e56Smrg    swaps(&stuff->color.green);
2453f7df2e56Smrg    swaps(&stuff->color.blue);
245405b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
245505b261ecSmrg}
245605b261ecSmrg
2457f7df2e56Smrgstatic void
2458f7df2e56SmrgswapStops(void *stuff, int num)
245905b261ecSmrg{
2460f7df2e56Smrg    int i;
246105b261ecSmrg    CARD32 *stops;
246205b261ecSmrg    CARD16 *colors;
2463f7df2e56Smrg
2464f7df2e56Smrg    stops = (CARD32 *) (stuff);
246505b261ecSmrg    for (i = 0; i < num; ++i) {
2466f7df2e56Smrg        swapl(stops);
246705b261ecSmrg        ++stops;
246805b261ecSmrg    }
2469f7df2e56Smrg    colors = (CARD16 *) (stops);
2470f7df2e56Smrg    for (i = 0; i < 4 * num; ++i) {
2471f7df2e56Smrg        swaps(colors);
24728223e2f2Smrg        ++colors;
247305b261ecSmrg    }
247405b261ecSmrg}
247505b261ecSmrg
247605b261ecSmrgstatic int
2477f7df2e56SmrgSProcRenderCreateLinearGradient(ClientPtr client)
247805b261ecSmrg{
247905b261ecSmrg    int len;
248005b261ecSmrg
2481f7df2e56Smrg    REQUEST(xRenderCreateLinearGradientReq);
2482f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
2483f7df2e56Smrg
2484f7df2e56Smrg    swaps(&stuff->length);
2485f7df2e56Smrg    swapl(&stuff->pid);
2486f7df2e56Smrg    swapl(&stuff->p1.x);
2487f7df2e56Smrg    swapl(&stuff->p1.y);
2488f7df2e56Smrg    swapl(&stuff->p2.x);
2489f7df2e56Smrg    swapl(&stuff->p2.y);
2490f7df2e56Smrg    swapl(&stuff->nStops);
249105b261ecSmrg
249205b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
2493f7df2e56Smrg    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
2494f7df2e56Smrg        return BadLength;
2495f7df2e56Smrg    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
249605b261ecSmrg        return BadLength;
249705b261ecSmrg
2498f7df2e56Smrg    swapStops(stuff + 1, stuff->nStops);
249905b261ecSmrg
250005b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
250105b261ecSmrg}
250205b261ecSmrg
250305b261ecSmrgstatic int
2504f7df2e56SmrgSProcRenderCreateRadialGradient(ClientPtr client)
250505b261ecSmrg{
250605b261ecSmrg    int len;
2507f7df2e56Smrg
2508f7df2e56Smrg    REQUEST(xRenderCreateRadialGradientReq);
2509f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
2510f7df2e56Smrg
2511f7df2e56Smrg    swaps(&stuff->length);
2512f7df2e56Smrg    swapl(&stuff->pid);
2513f7df2e56Smrg    swapl(&stuff->inner.x);
2514f7df2e56Smrg    swapl(&stuff->inner.y);
2515f7df2e56Smrg    swapl(&stuff->outer.x);
2516f7df2e56Smrg    swapl(&stuff->outer.y);
2517f7df2e56Smrg    swapl(&stuff->inner_radius);
2518f7df2e56Smrg    swapl(&stuff->outer_radius);
2519f7df2e56Smrg    swapl(&stuff->nStops);
252005b261ecSmrg
252105b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
2522f7df2e56Smrg    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
2523f7df2e56Smrg        return BadLength;
2524f7df2e56Smrg    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
252505b261ecSmrg        return BadLength;
252605b261ecSmrg
2527f7df2e56Smrg    swapStops(stuff + 1, stuff->nStops);
252805b261ecSmrg
252905b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
253005b261ecSmrg}
253105b261ecSmrg
253205b261ecSmrgstatic int
2533f7df2e56SmrgSProcRenderCreateConicalGradient(ClientPtr client)
253405b261ecSmrg{
253505b261ecSmrg    int len;
253605b261ecSmrg
2537f7df2e56Smrg    REQUEST(xRenderCreateConicalGradientReq);
2538f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
2539f7df2e56Smrg
2540f7df2e56Smrg    swaps(&stuff->length);
2541f7df2e56Smrg    swapl(&stuff->pid);
2542f7df2e56Smrg    swapl(&stuff->center.x);
2543f7df2e56Smrg    swapl(&stuff->center.y);
2544f7df2e56Smrg    swapl(&stuff->angle);
2545f7df2e56Smrg    swapl(&stuff->nStops);
254605b261ecSmrg
254705b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
2548f7df2e56Smrg    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
2549f7df2e56Smrg        return BadLength;
2550f7df2e56Smrg    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
255105b261ecSmrg        return BadLength;
255205b261ecSmrg
2553f7df2e56Smrg    swapStops(stuff + 1, stuff->nStops);
255405b261ecSmrg
255505b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
255605b261ecSmrg}
255705b261ecSmrg
255805b261ecSmrgstatic int
2559f7df2e56SmrgSProcRenderDispatch(ClientPtr client)
256005b261ecSmrg{
256105b261ecSmrg    REQUEST(xReq);
2562f7df2e56Smrg
256305b261ecSmrg    if (stuff->data < RenderNumberRequests)
2564f7df2e56Smrg        return (*SProcRenderVector[stuff->data]) (client);
256505b261ecSmrg    else
2566f7df2e56Smrg        return BadRequest;
256705b261ecSmrg}
256805b261ecSmrg
256905b261ecSmrg#ifdef PANORAMIX
25706747b715Smrg#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\
2571f7df2e56Smrg    int rc = dixLookupResourceByType((void **)&(pPicture), pid,\
25726747b715Smrg                                     XRT_PICTURE, client, mode);\
25736747b715Smrg    if (rc != Success)\
25746747b715Smrg	return rc;\
257505b261ecSmrg}
257605b261ecSmrg
25776747b715Smrg#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\
257805b261ecSmrg    if (pid == None) \
257905b261ecSmrg	pPicture = 0; \
258005b261ecSmrg    else { \
25816747b715Smrg	VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \
258205b261ecSmrg    } \
258305b261ecSmrg} \
258405b261ecSmrg
2585f7df2e56Smrgint (*PanoramiXSaveRenderVector[RenderNumberRequests]) (ClientPtr);
258605b261ecSmrg
258705b261ecSmrgstatic int
2588f7df2e56SmrgPanoramiXRenderCreatePicture(ClientPtr client)
258905b261ecSmrg{
259005b261ecSmrg    REQUEST(xRenderCreatePictureReq);
2591f7df2e56Smrg    PanoramiXRes *refDraw, *newPict;
2592f7df2e56Smrg    int result, j;
259305b261ecSmrg
259405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2595f7df2e56Smrg    result = dixLookupResourceByClass((void **) &refDraw, stuff->drawable,
2596f7df2e56Smrg                                      XRC_DRAWABLE, client, DixWriteAccess);
25976747b715Smrg    if (result != Success)
2598f7df2e56Smrg        return (result == BadValue) ? BadDrawable : result;
2599f7df2e56Smrg    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
2600f7df2e56Smrg        return BadAlloc;
260105b261ecSmrg    newPict->type = XRT_PICTURE;
2602f7df2e56Smrg    panoramix_setup_ids(newPict, client, stuff->pid);
2603f7df2e56Smrg
260405b261ecSmrg    if (refDraw->type == XRT_WINDOW &&
2605f7df2e56Smrg        stuff->drawable == screenInfo.screens[0]->root->drawable.id) {
2606f7df2e56Smrg        newPict->u.pict.root = TRUE;
260705b261ecSmrg    }
260805b261ecSmrg    else
2609f7df2e56Smrg        newPict->u.pict.root = FALSE;
261005b261ecSmrg
261105b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
2612f7df2e56Smrg        stuff->pid = newPict->info[j].id;
2613f7df2e56Smrg        stuff->drawable = refDraw->info[j].id;
2614f7df2e56Smrg        result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
2615f7df2e56Smrg        if (result != Success)
2616f7df2e56Smrg            break;
261705b261ecSmrg    }
261805b261ecSmrg
261905b261ecSmrg    if (result == Success)
2620f7df2e56Smrg        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
2621f7df2e56Smrg    else
2622f7df2e56Smrg        free(newPict);
262305b261ecSmrg
26246747b715Smrg    return result;
262505b261ecSmrg}
262605b261ecSmrg
262705b261ecSmrgstatic int
2628f7df2e56SmrgPanoramiXRenderChangePicture(ClientPtr client)
262905b261ecSmrg{
2630f7df2e56Smrg    PanoramiXRes *pict;
2631f7df2e56Smrg    int result = Success, j;
2632f7df2e56Smrg
263305b261ecSmrg    REQUEST(xRenderChangePictureReq);
263405b261ecSmrg
26356747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
2636f7df2e56Smrg
26376747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2638f7df2e56Smrg
263905b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
264005b261ecSmrg        stuff->picture = pict->info[j].id;
264105b261ecSmrg        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
2642f7df2e56Smrg        if (result != Success)
2643f7df2e56Smrg            break;
264405b261ecSmrg    }
264505b261ecSmrg
26466747b715Smrg    return result;
264705b261ecSmrg}
264805b261ecSmrg
264905b261ecSmrgstatic int
2650f7df2e56SmrgPanoramiXRenderSetPictureClipRectangles(ClientPtr client)
265105b261ecSmrg{
265205b261ecSmrg    REQUEST(xRenderSetPictureClipRectanglesReq);
2653f7df2e56Smrg    int result = Success, j;
2654f7df2e56Smrg    PanoramiXRes *pict;
265505b261ecSmrg
265605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
2657f7df2e56Smrg
26586747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2659f7df2e56Smrg
266005b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
266105b261ecSmrg        stuff->picture = pict->info[j].id;
2662f7df2e56Smrg        result =
2663f7df2e56Smrg            (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles])
2664f7df2e56Smrg            (client);
2665f7df2e56Smrg        if (result != Success)
2666f7df2e56Smrg            break;
266705b261ecSmrg    }
266805b261ecSmrg
26696747b715Smrg    return result;
267005b261ecSmrg}
267105b261ecSmrg
267205b261ecSmrgstatic int
2673f7df2e56SmrgPanoramiXRenderSetPictureTransform(ClientPtr client)
267405b261ecSmrg{
267505b261ecSmrg    REQUEST(xRenderSetPictureTransformReq);
2676f7df2e56Smrg    int result = Success, j;
2677f7df2e56Smrg    PanoramiXRes *pict;
267805b261ecSmrg
267905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
2680f7df2e56Smrg
26816747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2682f7df2e56Smrg
268305b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
268405b261ecSmrg        stuff->picture = pict->info[j].id;
2685f7df2e56Smrg        result =
2686f7df2e56Smrg            (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
2687f7df2e56Smrg        if (result != Success)
2688f7df2e56Smrg            break;
268905b261ecSmrg    }
269005b261ecSmrg
26916747b715Smrg    return result;
269205b261ecSmrg}
269305b261ecSmrg
269405b261ecSmrgstatic int
2695f7df2e56SmrgPanoramiXRenderSetPictureFilter(ClientPtr client)
269605b261ecSmrg{
269705b261ecSmrg    REQUEST(xRenderSetPictureFilterReq);
2698f7df2e56Smrg    int result = Success, j;
2699f7df2e56Smrg    PanoramiXRes *pict;
270005b261ecSmrg
270105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
2702f7df2e56Smrg
27036747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2704f7df2e56Smrg
270505b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
270605b261ecSmrg        stuff->picture = pict->info[j].id;
2707f7df2e56Smrg        result =
2708f7df2e56Smrg            (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
2709f7df2e56Smrg        if (result != Success)
2710f7df2e56Smrg            break;
271105b261ecSmrg    }
271205b261ecSmrg
27136747b715Smrg    return result;
271405b261ecSmrg}
271505b261ecSmrg
271605b261ecSmrgstatic int
2717f7df2e56SmrgPanoramiXRenderFreePicture(ClientPtr client)
271805b261ecSmrg{
271905b261ecSmrg    PanoramiXRes *pict;
2720f7df2e56Smrg    int result = Success, j;
2721f7df2e56Smrg
272205b261ecSmrg    REQUEST(xRenderFreePictureReq);
272305b261ecSmrg
272405b261ecSmrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
272505b261ecSmrg
272605b261ecSmrg    client->errorValue = stuff->picture;
272705b261ecSmrg
27286747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess);
272905b261ecSmrg
273005b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
2731f7df2e56Smrg        stuff->picture = pict->info[j].id;
2732f7df2e56Smrg        result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
2733f7df2e56Smrg        if (result != Success)
2734f7df2e56Smrg            break;
273505b261ecSmrg    }
273605b261ecSmrg
273705b261ecSmrg    /* Since ProcRenderFreePicture is using FreeResource, it will free
2738f7df2e56Smrg       our resource for us on the last pass through the loop above */
2739f7df2e56Smrg
27406747b715Smrg    return result;
274105b261ecSmrg}
274205b261ecSmrg
274305b261ecSmrgstatic int
2744f7df2e56SmrgPanoramiXRenderComposite(ClientPtr client)
274505b261ecSmrg{
2746f7df2e56Smrg    PanoramiXRes *src, *msk, *dst;
2747f7df2e56Smrg    int result = Success, j;
2748f7df2e56Smrg    xRenderCompositeReq orig;
2749f7df2e56Smrg
275005b261ecSmrg    REQUEST(xRenderCompositeReq);
275105b261ecSmrg
275205b261ecSmrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
2753f7df2e56Smrg
2754f7df2e56Smrg    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2755f7df2e56Smrg    VERIFY_XIN_ALPHA(msk, stuff->mask, client, DixReadAccess);
2756f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2757f7df2e56Smrg
275805b261ecSmrg    orig = *stuff;
2759f7df2e56Smrg
276005b261ecSmrg    FOR_NSCREENS_FORWARD(j) {
2761f7df2e56Smrg        stuff->src = src->info[j].id;
2762f7df2e56Smrg        if (src->u.pict.root) {
2763f7df2e56Smrg            stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x;
2764f7df2e56Smrg            stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y;
2765f7df2e56Smrg        }
2766f7df2e56Smrg        stuff->dst = dst->info[j].id;
2767f7df2e56Smrg        if (dst->u.pict.root) {
2768f7df2e56Smrg            stuff->xDst = orig.xDst - screenInfo.screens[j]->x;
2769f7df2e56Smrg            stuff->yDst = orig.yDst - screenInfo.screens[j]->y;
2770f7df2e56Smrg        }
2771f7df2e56Smrg        if (msk) {
2772f7df2e56Smrg            stuff->mask = msk->info[j].id;
2773f7df2e56Smrg            if (msk->u.pict.root) {
2774f7df2e56Smrg                stuff->xMask = orig.xMask - screenInfo.screens[j]->x;
2775f7df2e56Smrg                stuff->yMask = orig.yMask - screenInfo.screens[j]->y;
2776f7df2e56Smrg            }
2777f7df2e56Smrg        }
2778f7df2e56Smrg        result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
2779f7df2e56Smrg        if (result != Success)
2780f7df2e56Smrg            break;
278105b261ecSmrg    }
278205b261ecSmrg
278305b261ecSmrg    return result;
278405b261ecSmrg}
278505b261ecSmrg
278605b261ecSmrgstatic int
2787f7df2e56SmrgPanoramiXRenderCompositeGlyphs(ClientPtr client)
278805b261ecSmrg{
2789f7df2e56Smrg    PanoramiXRes *src, *dst;
2790f7df2e56Smrg    int result = Success, j;
2791f7df2e56Smrg
279205b261ecSmrg    REQUEST(xRenderCompositeGlyphsReq);
2793f7df2e56Smrg    xGlyphElt origElt, *elt;
2794f7df2e56Smrg    INT16 xSrc, ySrc;
279505b261ecSmrg
279605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
2797f7df2e56Smrg    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2798f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2799f7df2e56Smrg
2800f7df2e56Smrg    if (client->req_len << 2 >= (sizeof(xRenderCompositeGlyphsReq) +
2801f7df2e56Smrg                                 sizeof(xGlyphElt))) {
2802f7df2e56Smrg        elt = (xGlyphElt *) (stuff + 1);
2803f7df2e56Smrg        origElt = *elt;
2804f7df2e56Smrg        xSrc = stuff->xSrc;
2805f7df2e56Smrg        ySrc = stuff->ySrc;
2806f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
2807f7df2e56Smrg            stuff->src = src->info[j].id;
2808f7df2e56Smrg            if (src->u.pict.root) {
2809f7df2e56Smrg                stuff->xSrc = xSrc - screenInfo.screens[j]->x;
2810f7df2e56Smrg                stuff->ySrc = ySrc - screenInfo.screens[j]->y;
2811f7df2e56Smrg            }
2812f7df2e56Smrg            stuff->dst = dst->info[j].id;
2813f7df2e56Smrg            if (dst->u.pict.root) {
2814f7df2e56Smrg                elt->deltax = origElt.deltax - screenInfo.screens[j]->x;
2815f7df2e56Smrg                elt->deltay = origElt.deltay - screenInfo.screens[j]->y;
2816f7df2e56Smrg            }
2817f7df2e56Smrg            result =
2818f7df2e56Smrg                (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
2819f7df2e56Smrg            if (result != Success)
2820f7df2e56Smrg                break;
2821f7df2e56Smrg        }
282205b261ecSmrg    }
282305b261ecSmrg
282405b261ecSmrg    return result;
282505b261ecSmrg}
282605b261ecSmrg
282705b261ecSmrgstatic int
2828f7df2e56SmrgPanoramiXRenderFillRectangles(ClientPtr client)
282905b261ecSmrg{
2830f7df2e56Smrg    PanoramiXRes *dst;
2831f7df2e56Smrg    int result = Success, j;
2832f7df2e56Smrg
283305b261ecSmrg    REQUEST(xRenderFillRectanglesReq);
2834f7df2e56Smrg    char *extra;
2835f7df2e56Smrg    int extra_len;
2836f7df2e56Smrg
2837f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
2838f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2839f7df2e56Smrg    extra_len = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
2840f7df2e56Smrg    if (extra_len && (extra = (char *) malloc(extra_len))) {
2841f7df2e56Smrg        memcpy(extra, stuff + 1, extra_len);
2842f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
2843f7df2e56Smrg            if (j)
2844f7df2e56Smrg                memcpy(stuff + 1, extra, extra_len);
2845f7df2e56Smrg            if (dst->u.pict.root) {
2846f7df2e56Smrg                int x_off = screenInfo.screens[j]->x;
2847f7df2e56Smrg                int y_off = screenInfo.screens[j]->y;
2848f7df2e56Smrg
2849f7df2e56Smrg                if (x_off || y_off) {
2850f7df2e56Smrg                    xRectangle *rects = (xRectangle *) (stuff + 1);
2851f7df2e56Smrg                    int i = extra_len / sizeof(xRectangle);
2852f7df2e56Smrg
2853f7df2e56Smrg                    while (i--) {
2854f7df2e56Smrg                        rects->x -= x_off;
2855f7df2e56Smrg                        rects->y -= y_off;
2856f7df2e56Smrg                        rects++;
2857f7df2e56Smrg                    }
2858f7df2e56Smrg                }
2859f7df2e56Smrg            }
2860f7df2e56Smrg            stuff->dst = dst->info[j].id;
2861f7df2e56Smrg            result =
2862f7df2e56Smrg                (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
2863f7df2e56Smrg            if (result != Success)
2864f7df2e56Smrg                break;
2865f7df2e56Smrg        }
2866f7df2e56Smrg        free(extra);
286705b261ecSmrg    }
286805b261ecSmrg
286905b261ecSmrg    return result;
287005b261ecSmrg}
287105b261ecSmrg
287205b261ecSmrgstatic int
287305b261ecSmrgPanoramiXRenderTrapezoids(ClientPtr client)
287405b261ecSmrg{
2875f7df2e56Smrg    PanoramiXRes *src, *dst;
2876f7df2e56Smrg    int result = Success, j;
2877f7df2e56Smrg
287805b261ecSmrg    REQUEST(xRenderTrapezoidsReq);
2879f7df2e56Smrg    char *extra;
2880f7df2e56Smrg    int extra_len;
2881f7df2e56Smrg
2882f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
2883f7df2e56Smrg
2884f7df2e56Smrg    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2885f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2886f7df2e56Smrg
2887f7df2e56Smrg    extra_len = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq);
2888f7df2e56Smrg
2889f7df2e56Smrg    if (extra_len && (extra = (char *) malloc(extra_len))) {
2890f7df2e56Smrg        memcpy(extra, stuff + 1, extra_len);
2891f7df2e56Smrg
2892f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
2893f7df2e56Smrg            if (j)
2894f7df2e56Smrg                memcpy(stuff + 1, extra, extra_len);
2895f7df2e56Smrg            if (dst->u.pict.root) {
2896f7df2e56Smrg                int x_off = screenInfo.screens[j]->x;
2897f7df2e56Smrg                int y_off = screenInfo.screens[j]->y;
2898f7df2e56Smrg
2899f7df2e56Smrg                if (x_off || y_off) {
2900f7df2e56Smrg                    xTrapezoid *trap = (xTrapezoid *) (stuff + 1);
2901f7df2e56Smrg                    int i = extra_len / sizeof(xTrapezoid);
2902f7df2e56Smrg
2903f7df2e56Smrg                    while (i--) {
2904f7df2e56Smrg                        trap->top -= y_off;
2905f7df2e56Smrg                        trap->bottom -= y_off;
2906f7df2e56Smrg                        trap->left.p1.x -= x_off;
2907f7df2e56Smrg                        trap->left.p1.y -= y_off;
2908f7df2e56Smrg                        trap->left.p2.x -= x_off;
2909f7df2e56Smrg                        trap->left.p2.y -= y_off;
2910f7df2e56Smrg                        trap->right.p1.x -= x_off;
2911f7df2e56Smrg                        trap->right.p1.y -= y_off;
2912f7df2e56Smrg                        trap->right.p2.x -= x_off;
2913f7df2e56Smrg                        trap->right.p2.y -= y_off;
2914f7df2e56Smrg                        trap++;
2915f7df2e56Smrg                    }
2916f7df2e56Smrg                }
2917f7df2e56Smrg            }
2918f7df2e56Smrg
291905b261ecSmrg            stuff->src = src->info[j].id;
292005b261ecSmrg            stuff->dst = dst->info[j].id;
2921f7df2e56Smrg            result = (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
2922f7df2e56Smrg
2923f7df2e56Smrg            if (result != Success)
2924f7df2e56Smrg                break;
2925f7df2e56Smrg        }
292605b261ecSmrg
29276747b715Smrg        free(extra);
292805b261ecSmrg    }
292905b261ecSmrg
293005b261ecSmrg    return result;
293105b261ecSmrg}
293205b261ecSmrg
293305b261ecSmrgstatic int
293405b261ecSmrgPanoramiXRenderTriangles(ClientPtr client)
293505b261ecSmrg{
2936f7df2e56Smrg    PanoramiXRes *src, *dst;
2937f7df2e56Smrg    int result = Success, j;
2938f7df2e56Smrg
293905b261ecSmrg    REQUEST(xRenderTrianglesReq);
2940f7df2e56Smrg    char *extra;
2941f7df2e56Smrg    int extra_len;
2942f7df2e56Smrg
2943f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
2944f7df2e56Smrg
2945f7df2e56Smrg    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2946f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2947f7df2e56Smrg
2948f7df2e56Smrg    extra_len = (client->req_len << 2) - sizeof(xRenderTrianglesReq);
2949f7df2e56Smrg
2950f7df2e56Smrg    if (extra_len && (extra = (char *) malloc(extra_len))) {
2951f7df2e56Smrg        memcpy(extra, stuff + 1, extra_len);
2952f7df2e56Smrg
2953f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
2954f7df2e56Smrg            if (j)
2955f7df2e56Smrg                memcpy(stuff + 1, extra, extra_len);
2956f7df2e56Smrg            if (dst->u.pict.root) {
2957f7df2e56Smrg                int x_off = screenInfo.screens[j]->x;
2958f7df2e56Smrg                int y_off = screenInfo.screens[j]->y;
2959f7df2e56Smrg
2960f7df2e56Smrg                if (x_off || y_off) {
2961f7df2e56Smrg                    xTriangle *tri = (xTriangle *) (stuff + 1);
2962f7df2e56Smrg                    int i = extra_len / sizeof(xTriangle);
2963f7df2e56Smrg
2964f7df2e56Smrg                    while (i--) {
2965f7df2e56Smrg                        tri->p1.x -= x_off;
2966f7df2e56Smrg                        tri->p1.y -= y_off;
2967f7df2e56Smrg                        tri->p2.x -= x_off;
2968f7df2e56Smrg                        tri->p2.y -= y_off;
2969f7df2e56Smrg                        tri->p3.x -= x_off;
2970f7df2e56Smrg                        tri->p3.y -= y_off;
2971f7df2e56Smrg                        tri++;
2972f7df2e56Smrg                    }
2973f7df2e56Smrg                }
2974f7df2e56Smrg            }
2975f7df2e56Smrg
297605b261ecSmrg            stuff->src = src->info[j].id;
297705b261ecSmrg            stuff->dst = dst->info[j].id;
2978f7df2e56Smrg            result = (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
2979f7df2e56Smrg
2980f7df2e56Smrg            if (result != Success)
2981f7df2e56Smrg                break;
2982f7df2e56Smrg        }
298305b261ecSmrg
29846747b715Smrg        free(extra);
298505b261ecSmrg    }
298605b261ecSmrg
298705b261ecSmrg    return result;
298805b261ecSmrg}
298905b261ecSmrg
299005b261ecSmrgstatic int
299105b261ecSmrgPanoramiXRenderTriStrip(ClientPtr client)
299205b261ecSmrg{
2993f7df2e56Smrg    PanoramiXRes *src, *dst;
2994f7df2e56Smrg    int result = Success, j;
2995f7df2e56Smrg
299605b261ecSmrg    REQUEST(xRenderTriStripReq);
2997f7df2e56Smrg    char *extra;
2998f7df2e56Smrg    int extra_len;
2999f7df2e56Smrg
3000f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
3001f7df2e56Smrg
3002f7df2e56Smrg    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
3003f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
3004f7df2e56Smrg
3005f7df2e56Smrg    extra_len = (client->req_len << 2) - sizeof(xRenderTriStripReq);
3006f7df2e56Smrg
3007f7df2e56Smrg    if (extra_len && (extra = (char *) malloc(extra_len))) {
3008f7df2e56Smrg        memcpy(extra, stuff + 1, extra_len);
3009f7df2e56Smrg
3010f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
3011f7df2e56Smrg            if (j)
3012f7df2e56Smrg                memcpy(stuff + 1, extra, extra_len);
3013f7df2e56Smrg            if (dst->u.pict.root) {
3014f7df2e56Smrg                int x_off = screenInfo.screens[j]->x;
3015f7df2e56Smrg                int y_off = screenInfo.screens[j]->y;
3016f7df2e56Smrg
3017f7df2e56Smrg                if (x_off || y_off) {
3018f7df2e56Smrg                    xPointFixed *fixed = (xPointFixed *) (stuff + 1);
3019f7df2e56Smrg                    int i = extra_len / sizeof(xPointFixed);
3020f7df2e56Smrg
3021f7df2e56Smrg                    while (i--) {
3022f7df2e56Smrg                        fixed->x -= x_off;
3023f7df2e56Smrg                        fixed->y -= y_off;
3024f7df2e56Smrg                        fixed++;
3025f7df2e56Smrg                    }
3026f7df2e56Smrg                }
3027f7df2e56Smrg            }
3028f7df2e56Smrg
302905b261ecSmrg            stuff->src = src->info[j].id;
303005b261ecSmrg            stuff->dst = dst->info[j].id;
3031f7df2e56Smrg            result = (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
3032f7df2e56Smrg
3033f7df2e56Smrg            if (result != Success)
3034f7df2e56Smrg                break;
3035f7df2e56Smrg        }
303605b261ecSmrg
30376747b715Smrg        free(extra);
303805b261ecSmrg    }
303905b261ecSmrg
304005b261ecSmrg    return result;
304105b261ecSmrg}
304205b261ecSmrg
304305b261ecSmrgstatic int
304405b261ecSmrgPanoramiXRenderTriFan(ClientPtr client)
304505b261ecSmrg{
3046f7df2e56Smrg    PanoramiXRes *src, *dst;
3047f7df2e56Smrg    int result = Success, j;
3048f7df2e56Smrg
304905b261ecSmrg    REQUEST(xRenderTriFanReq);
3050f7df2e56Smrg    char *extra;
3051f7df2e56Smrg    int extra_len;
3052f7df2e56Smrg
3053f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
3054f7df2e56Smrg
3055f7df2e56Smrg    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
3056f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
3057f7df2e56Smrg
3058f7df2e56Smrg    extra_len = (client->req_len << 2) - sizeof(xRenderTriFanReq);
3059f7df2e56Smrg
3060f7df2e56Smrg    if (extra_len && (extra = (char *) malloc(extra_len))) {
3061f7df2e56Smrg        memcpy(extra, stuff + 1, extra_len);
3062f7df2e56Smrg
3063f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
3064f7df2e56Smrg            if (j)
3065f7df2e56Smrg                memcpy(stuff + 1, extra, extra_len);
3066f7df2e56Smrg            if (dst->u.pict.root) {
3067f7df2e56Smrg                int x_off = screenInfo.screens[j]->x;
3068f7df2e56Smrg                int y_off = screenInfo.screens[j]->y;
3069f7df2e56Smrg
3070f7df2e56Smrg                if (x_off || y_off) {
3071f7df2e56Smrg                    xPointFixed *fixed = (xPointFixed *) (stuff + 1);
3072f7df2e56Smrg                    int i = extra_len / sizeof(xPointFixed);
3073f7df2e56Smrg
3074f7df2e56Smrg                    while (i--) {
3075f7df2e56Smrg                        fixed->x -= x_off;
3076f7df2e56Smrg                        fixed->y -= y_off;
3077f7df2e56Smrg                        fixed++;
3078f7df2e56Smrg                    }
3079f7df2e56Smrg                }
3080f7df2e56Smrg            }
3081f7df2e56Smrg
308205b261ecSmrg            stuff->src = src->info[j].id;
308305b261ecSmrg            stuff->dst = dst->info[j].id;
3084f7df2e56Smrg            result = (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
3085f7df2e56Smrg
3086f7df2e56Smrg            if (result != Success)
3087f7df2e56Smrg                break;
3088f7df2e56Smrg        }
308905b261ecSmrg
30906747b715Smrg        free(extra);
309105b261ecSmrg    }
309205b261ecSmrg
309305b261ecSmrg    return result;
309405b261ecSmrg}
309505b261ecSmrg
309605b261ecSmrgstatic int
3097f7df2e56SmrgPanoramiXRenderAddTraps(ClientPtr client)
309805b261ecSmrg{
3099f7df2e56Smrg    PanoramiXRes *picture;
3100f7df2e56Smrg    int result = Success, j;
3101f7df2e56Smrg
310205b261ecSmrg    REQUEST(xRenderAddTrapsReq);
3103f7df2e56Smrg    char *extra;
3104f7df2e56Smrg    int extra_len;
3105f7df2e56Smrg    INT16 x_off, y_off;
3106f7df2e56Smrg
3107f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
3108f7df2e56Smrg    VERIFY_XIN_PICTURE(picture, stuff->picture, client, DixWriteAccess);
3109f7df2e56Smrg    extra_len = (client->req_len << 2) - sizeof(xRenderAddTrapsReq);
3110f7df2e56Smrg    if (extra_len && (extra = (char *) malloc(extra_len))) {
3111f7df2e56Smrg        memcpy(extra, stuff + 1, extra_len);
3112f7df2e56Smrg        x_off = stuff->xOff;
3113f7df2e56Smrg        y_off = stuff->yOff;
3114f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
3115f7df2e56Smrg            if (j)
3116f7df2e56Smrg                memcpy(stuff + 1, extra, extra_len);
3117f7df2e56Smrg            stuff->picture = picture->info[j].id;
3118f7df2e56Smrg
3119f7df2e56Smrg            if (picture->u.pict.root) {
3120f7df2e56Smrg                stuff->xOff = x_off + screenInfo.screens[j]->x;
3121f7df2e56Smrg                stuff->yOff = y_off + screenInfo.screens[j]->y;
3122f7df2e56Smrg            }
3123f7df2e56Smrg            result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
3124f7df2e56Smrg            if (result != Success)
3125f7df2e56Smrg                break;
3126f7df2e56Smrg        }
3127f7df2e56Smrg        free(extra);
31286747b715Smrg    }
31296747b715Smrg
31306747b715Smrg    return result;
31316747b715Smrg}
31326747b715Smrg
31336747b715Smrgstatic int
3134f7df2e56SmrgPanoramiXRenderCreateSolidFill(ClientPtr client)
31356747b715Smrg{
31366747b715Smrg    REQUEST(xRenderCreateSolidFillReq);
3137f7df2e56Smrg    PanoramiXRes *newPict;
3138f7df2e56Smrg    int result = Success, j;
31396747b715Smrg
31406747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
31416747b715Smrg
3142f7df2e56Smrg    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3143f7df2e56Smrg        return BadAlloc;
31446747b715Smrg
31456747b715Smrg    newPict->type = XRT_PICTURE;
3146f7df2e56Smrg    panoramix_setup_ids(newPict, client, stuff->pid);
31476747b715Smrg    newPict->u.pict.root = FALSE;
31486747b715Smrg
31496747b715Smrg    FOR_NSCREENS_BACKWARD(j) {
3150f7df2e56Smrg        stuff->pid = newPict->info[j].id;
3151f7df2e56Smrg        result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client);
3152f7df2e56Smrg        if (result != Success)
3153f7df2e56Smrg            break;
31546747b715Smrg    }
31556747b715Smrg
31566747b715Smrg    if (result == Success)
3157f7df2e56Smrg        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
31586747b715Smrg    else
3159f7df2e56Smrg        free(newPict);
31606747b715Smrg
31616747b715Smrg    return result;
31626747b715Smrg}
31636747b715Smrg
31646747b715Smrgstatic int
3165f7df2e56SmrgPanoramiXRenderCreateLinearGradient(ClientPtr client)
31666747b715Smrg{
31676747b715Smrg    REQUEST(xRenderCreateLinearGradientReq);
3168f7df2e56Smrg    PanoramiXRes *newPict;
3169f7df2e56Smrg    int result = Success, j;
31706747b715Smrg
31716747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
31726747b715Smrg
3173f7df2e56Smrg    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3174f7df2e56Smrg        return BadAlloc;
31756747b715Smrg
31766747b715Smrg    newPict->type = XRT_PICTURE;
3177f7df2e56Smrg    panoramix_setup_ids(newPict, client, stuff->pid);
31786747b715Smrg    newPict->u.pict.root = FALSE;
31796747b715Smrg
31806747b715Smrg    FOR_NSCREENS_BACKWARD(j) {
3181f7df2e56Smrg        stuff->pid = newPict->info[j].id;
3182f7df2e56Smrg        result =
3183f7df2e56Smrg            (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client);
3184f7df2e56Smrg        if (result != Success)
3185f7df2e56Smrg            break;
318605b261ecSmrg    }
318705b261ecSmrg
31886747b715Smrg    if (result == Success)
3189f7df2e56Smrg        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
31906747b715Smrg    else
3191f7df2e56Smrg        free(newPict);
31926747b715Smrg
31936747b715Smrg    return result;
31946747b715Smrg}
31956747b715Smrg
31966747b715Smrgstatic int
3197f7df2e56SmrgPanoramiXRenderCreateRadialGradient(ClientPtr client)
31986747b715Smrg{
31996747b715Smrg    REQUEST(xRenderCreateRadialGradientReq);
3200f7df2e56Smrg    PanoramiXRes *newPict;
3201f7df2e56Smrg    int result = Success, j;
32026747b715Smrg
32036747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
32046747b715Smrg
3205f7df2e56Smrg    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3206f7df2e56Smrg        return BadAlloc;
32076747b715Smrg
32086747b715Smrg    newPict->type = XRT_PICTURE;
3209f7df2e56Smrg    panoramix_setup_ids(newPict, client, stuff->pid);
32106747b715Smrg    newPict->u.pict.root = FALSE;
32116747b715Smrg
32126747b715Smrg    FOR_NSCREENS_BACKWARD(j) {
3213f7df2e56Smrg        stuff->pid = newPict->info[j].id;
3214f7df2e56Smrg        result =
3215f7df2e56Smrg            (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client);
3216f7df2e56Smrg        if (result != Success)
3217f7df2e56Smrg            break;
32186747b715Smrg    }
32196747b715Smrg
32206747b715Smrg    if (result == Success)
3221f7df2e56Smrg        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
32226747b715Smrg    else
3223f7df2e56Smrg        free(newPict);
32246747b715Smrg
32256747b715Smrg    return result;
32266747b715Smrg}
32276747b715Smrg
32286747b715Smrgstatic int
3229f7df2e56SmrgPanoramiXRenderCreateConicalGradient(ClientPtr client)
32306747b715Smrg{
32316747b715Smrg    REQUEST(xRenderCreateConicalGradientReq);
3232f7df2e56Smrg    PanoramiXRes *newPict;
3233f7df2e56Smrg    int result = Success, j;
32346747b715Smrg
32356747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
32366747b715Smrg
3237f7df2e56Smrg    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3238f7df2e56Smrg        return BadAlloc;
32396747b715Smrg
32406747b715Smrg    newPict->type = XRT_PICTURE;
3241f7df2e56Smrg    panoramix_setup_ids(newPict, client, stuff->pid);
32426747b715Smrg    newPict->u.pict.root = FALSE;
32436747b715Smrg
32446747b715Smrg    FOR_NSCREENS_BACKWARD(j) {
3245f7df2e56Smrg        stuff->pid = newPict->info[j].id;
3246f7df2e56Smrg        result =
3247f7df2e56Smrg            (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient])
3248f7df2e56Smrg            (client);
3249f7df2e56Smrg        if (result != Success)
3250f7df2e56Smrg            break;
32516747b715Smrg    }
32526747b715Smrg
32536747b715Smrg    if (result == Success)
3254f7df2e56Smrg        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
32556747b715Smrg    else
3256f7df2e56Smrg        free(newPict);
32576747b715Smrg
325805b261ecSmrg    return result;
325905b261ecSmrg}
326005b261ecSmrg
326105b261ecSmrgvoid
3262f7df2e56SmrgPanoramiXRenderInit(void)
326305b261ecSmrg{
3264f7df2e56Smrg    int i;
3265f7df2e56Smrg
3266f7df2e56Smrg    XRT_PICTURE = CreateNewResourceType(XineramaDeleteResource,
3267f7df2e56Smrg                                        "XineramaPicture");
32686747b715Smrg    if (RenderErrBase)
3269f7df2e56Smrg        SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
327005b261ecSmrg    for (i = 0; i < RenderNumberRequests; i++)
3271f7df2e56Smrg        PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
327205b261ecSmrg    /*
327305b261ecSmrg     * Stuff in Xinerama aware request processing hooks
327405b261ecSmrg     */
327505b261ecSmrg    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
327605b261ecSmrg    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
3277f7df2e56Smrg    ProcRenderVector[X_RenderSetPictureTransform] =
3278f7df2e56Smrg        PanoramiXRenderSetPictureTransform;
3279f7df2e56Smrg    ProcRenderVector[X_RenderSetPictureFilter] =
3280f7df2e56Smrg        PanoramiXRenderSetPictureFilter;
3281f7df2e56Smrg    ProcRenderVector[X_RenderSetPictureClipRectangles] =
3282f7df2e56Smrg        PanoramiXRenderSetPictureClipRectangles;
328305b261ecSmrg    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
328405b261ecSmrg    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
328505b261ecSmrg    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
3286f7df2e56Smrg    ProcRenderVector[X_RenderCompositeGlyphs16] =
3287f7df2e56Smrg        PanoramiXRenderCompositeGlyphs;
3288f7df2e56Smrg    ProcRenderVector[X_RenderCompositeGlyphs32] =
3289f7df2e56Smrg        PanoramiXRenderCompositeGlyphs;
329005b261ecSmrg    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
329105b261ecSmrg
329205b261ecSmrg    ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
329305b261ecSmrg    ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
329405b261ecSmrg    ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
329505b261ecSmrg    ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
329605b261ecSmrg    ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
32976747b715Smrg
32986747b715Smrg    ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill;
3299f7df2e56Smrg    ProcRenderVector[X_RenderCreateLinearGradient] =
3300f7df2e56Smrg        PanoramiXRenderCreateLinearGradient;
3301f7df2e56Smrg    ProcRenderVector[X_RenderCreateRadialGradient] =
3302f7df2e56Smrg        PanoramiXRenderCreateRadialGradient;
3303f7df2e56Smrg    ProcRenderVector[X_RenderCreateConicalGradient] =
3304f7df2e56Smrg        PanoramiXRenderCreateConicalGradient;
330505b261ecSmrg}
330605b261ecSmrg
330705b261ecSmrgvoid
3308f7df2e56SmrgPanoramiXRenderReset(void)
330905b261ecSmrg{
3310f7df2e56Smrg    int i;
3311f7df2e56Smrg
331205b261ecSmrg    for (i = 0; i < RenderNumberRequests; i++)
3313f7df2e56Smrg        ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
33146747b715Smrg    RenderErrBase = 0;
331505b261ecSmrg}
331605b261ecSmrg
3317f7df2e56Smrg#endif                          /* PANORAMIX */
3318