render.c revision 7e31ba66
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
2226747b715Smrg#ifdef PANORAMIX
223f7df2e56SmrgRESTYPE XRT_PICTURE;
2246747b715Smrg#endif
2256747b715Smrg
22605b261ecSmrgvoid
227f7df2e56SmrgRenderExtensionInit(void)
22805b261ecSmrg{
22905b261ecSmrg    ExtensionEntry *extEntry;
23005b261ecSmrg
23105b261ecSmrg    if (!PictureType)
232f7df2e56Smrg        return;
233f7df2e56Smrg    if (!PictureFinishInit())
234f7df2e56Smrg        return;
235f7df2e56Smrg    if (!dixRegisterPrivateKey
236f7df2e56Smrg        (&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec)))
237f7df2e56Smrg        return;
238f7df2e56Smrg
239f7df2e56Smrg    extEntry = AddExtension(RENDER_NAME, 0, RenderNumberErrors,
240f7df2e56Smrg                            ProcRenderDispatch, SProcRenderDispatch,
241f7df2e56Smrg                            NULL, StandardMinorOpcode);
24205b261ecSmrg    if (!extEntry)
243f7df2e56Smrg        return;
24405b261ecSmrg    RenderErrBase = extEntry->errorBase;
2456747b715Smrg#ifdef PANORAMIX
2466747b715Smrg    if (XRT_PICTURE)
247f7df2e56Smrg        SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
2486747b715Smrg#endif
2496747b715Smrg    SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture);
2506747b715Smrg    SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat);
2516747b715Smrg    SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet);
25205b261ecSmrg}
25305b261ecSmrg
25405b261ecSmrgstatic int
255f7df2e56SmrgProcRenderQueryVersion(ClientPtr client)
25605b261ecSmrg{
257f7df2e56Smrg    RenderClientPtr pRenderClient = GetRenderClient(client);
258f7df2e56Smrg    xRenderQueryVersionReply rep = {
259f7df2e56Smrg        .type = X_Reply,
260f7df2e56Smrg        .sequenceNumber = client->sequence,
261f7df2e56Smrg        .length = 0
262f7df2e56Smrg    };
263f7df2e56Smrg
26405b261ecSmrg    REQUEST(xRenderQueryVersionReq);
2650b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
26605b261ecSmrg
267f7df2e56Smrg    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
268f7df2e56Smrg
26905b261ecSmrg    pRenderClient->major_version = stuff->majorVersion;
27005b261ecSmrg    pRenderClient->minor_version = stuff->minorVersion;
27105b261ecSmrg
2726747b715Smrg    if ((stuff->majorVersion * 1000 + stuff->minorVersion) <
273f7df2e56Smrg        (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) {
274f7df2e56Smrg        rep.majorVersion = stuff->majorVersion;
275f7df2e56Smrg        rep.minorVersion = stuff->minorVersion;
276f7df2e56Smrg    }
277f7df2e56Smrg    else {
278f7df2e56Smrg        rep.majorVersion = SERVER_RENDER_MAJOR_VERSION;
279f7df2e56Smrg        rep.minorVersion = SERVER_RENDER_MINOR_VERSION;
2806747b715Smrg    }
2816747b715Smrg
28205b261ecSmrg    if (client->swapped) {
283f7df2e56Smrg        swaps(&rep.sequenceNumber);
284f7df2e56Smrg        swapl(&rep.length);
285f7df2e56Smrg        swapl(&rep.majorVersion);
286f7df2e56Smrg        swapl(&rep.minorVersion);
28705b261ecSmrg    }
288f7df2e56Smrg    WriteToClient(client, sizeof(xRenderQueryVersionReply), &rep);
2896747b715Smrg    return Success;
29005b261ecSmrg}
29105b261ecSmrg
29205b261ecSmrgstatic VisualPtr
293f7df2e56SmrgfindVisual(ScreenPtr pScreen, VisualID vid)
29405b261ecSmrg{
295f7df2e56Smrg    VisualPtr pVisual;
296f7df2e56Smrg    int v;
29705b261ecSmrg
298f7df2e56Smrg    for (v = 0; v < pScreen->numVisuals; v++) {
299f7df2e56Smrg        pVisual = pScreen->visuals + v;
300f7df2e56Smrg        if (pVisual->vid == vid)
301f7df2e56Smrg            return pVisual;
30205b261ecSmrg    }
30305b261ecSmrg    return 0;
30405b261ecSmrg}
30505b261ecSmrg
30605b261ecSmrgstatic int
307f7df2e56SmrgProcRenderQueryPictFormats(ClientPtr client)
308f7df2e56Smrg{
309f7df2e56Smrg    RenderClientPtr pRenderClient = GetRenderClient(client);
310f7df2e56Smrg    xRenderQueryPictFormatsReply *reply;
311f7df2e56Smrg    xPictScreen *pictScreen;
312f7df2e56Smrg    xPictDepth *pictDepth;
313f7df2e56Smrg    xPictVisual *pictVisual;
314f7df2e56Smrg    xPictFormInfo *pictForm;
315f7df2e56Smrg    CARD32 *pictSubpixel;
316f7df2e56Smrg    ScreenPtr pScreen;
317f7df2e56Smrg    VisualPtr pVisual;
318f7df2e56Smrg    DepthPtr pDepth;
319f7df2e56Smrg    int v, d;
320f7df2e56Smrg    PictureScreenPtr ps;
321f7df2e56Smrg    PictFormatPtr pFormat;
322f7df2e56Smrg    int nformat;
323f7df2e56Smrg    int ndepth;
324f7df2e56Smrg    int nvisual;
325f7df2e56Smrg    int rlength;
326f7df2e56Smrg    int s;
327f7df2e56Smrg    int numScreens;
328f7df2e56Smrg    int numSubpixel;
329f7df2e56Smrg
33005b261ecSmrg/*    REQUEST(xRenderQueryPictFormatsReq); */
33105b261ecSmrg
33205b261ecSmrg    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
33305b261ecSmrg
33405b261ecSmrg#ifdef PANORAMIX
33505b261ecSmrg    if (noPanoramiXExtension)
336f7df2e56Smrg        numScreens = screenInfo.numScreens;
337f7df2e56Smrg    else
338f7df2e56Smrg        numScreens = ((xConnSetup *) ConnectionInfo)->numRoots;
33905b261ecSmrg#else
34005b261ecSmrg    numScreens = screenInfo.numScreens;
34105b261ecSmrg#endif
34205b261ecSmrg    ndepth = nformat = nvisual = 0;
343f7df2e56Smrg    for (s = 0; s < numScreens; s++) {
344f7df2e56Smrg        pScreen = screenInfo.screens[s];
345f7df2e56Smrg        for (d = 0; d < pScreen->numDepths; d++) {
346f7df2e56Smrg            pDepth = pScreen->allowedDepths + d;
347f7df2e56Smrg            ++ndepth;
348f7df2e56Smrg
349f7df2e56Smrg            for (v = 0; v < pDepth->numVids; v++) {
350f7df2e56Smrg                pVisual = findVisual(pScreen, pDepth->vids[v]);
351f7df2e56Smrg                if (pVisual &&
352f7df2e56Smrg                    PictureMatchVisual(pScreen, pDepth->depth, pVisual))
353f7df2e56Smrg                    ++nvisual;
354f7df2e56Smrg            }
355f7df2e56Smrg        }
356f7df2e56Smrg        ps = GetPictureScreenIfSet(pScreen);
357f7df2e56Smrg        if (ps)
358f7df2e56Smrg            nformat += ps->nformats;
35905b261ecSmrg    }
36005b261ecSmrg    if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
361f7df2e56Smrg        numSubpixel = 0;
36205b261ecSmrg    else
363f7df2e56Smrg        numSubpixel = numScreens;
364f7df2e56Smrg
365f7df2e56Smrg    rlength = (sizeof(xRenderQueryPictFormatsReply) +
366f7df2e56Smrg               nformat * sizeof(xPictFormInfo) +
367f7df2e56Smrg               numScreens * sizeof(xPictScreen) +
368f7df2e56Smrg               ndepth * sizeof(xPictDepth) +
369f7df2e56Smrg               nvisual * sizeof(xPictVisual) + numSubpixel * sizeof(CARD32));
3706747b715Smrg    reply = (xRenderQueryPictFormatsReply *) calloc(1, rlength);
37105b261ecSmrg    if (!reply)
372f7df2e56Smrg        return BadAlloc;
37305b261ecSmrg    reply->type = X_Reply;
37405b261ecSmrg    reply->sequenceNumber = client->sequence;
3756747b715Smrg    reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
37605b261ecSmrg    reply->numFormats = nformat;
37705b261ecSmrg    reply->numScreens = numScreens;
37805b261ecSmrg    reply->numDepths = ndepth;
37905b261ecSmrg    reply->numVisuals = nvisual;
38005b261ecSmrg    reply->numSubpixel = numSubpixel;
381f7df2e56Smrg
38205b261ecSmrg    pictForm = (xPictFormInfo *) (reply + 1);
383f7df2e56Smrg
384f7df2e56Smrg    for (s = 0; s < numScreens; s++) {
385f7df2e56Smrg        pScreen = screenInfo.screens[s];
386f7df2e56Smrg        ps = GetPictureScreenIfSet(pScreen);
387f7df2e56Smrg        if (ps) {
388f7df2e56Smrg            for (nformat = 0, pFormat = ps->formats;
389f7df2e56Smrg                 nformat < ps->nformats; nformat++, pFormat++) {
390f7df2e56Smrg                pictForm->id = pFormat->id;
391f7df2e56Smrg                pictForm->type = pFormat->type;
392f7df2e56Smrg                pictForm->depth = pFormat->depth;
393f7df2e56Smrg                pictForm->direct.red = pFormat->direct.red;
394f7df2e56Smrg                pictForm->direct.redMask = pFormat->direct.redMask;
395f7df2e56Smrg                pictForm->direct.green = pFormat->direct.green;
396f7df2e56Smrg                pictForm->direct.greenMask = pFormat->direct.greenMask;
397f7df2e56Smrg                pictForm->direct.blue = pFormat->direct.blue;
398f7df2e56Smrg                pictForm->direct.blueMask = pFormat->direct.blueMask;
399f7df2e56Smrg                pictForm->direct.alpha = pFormat->direct.alpha;
400f7df2e56Smrg                pictForm->direct.alphaMask = pFormat->direct.alphaMask;
401f7df2e56Smrg                if (pFormat->type == PictTypeIndexed &&
402f7df2e56Smrg                    pFormat->index.pColormap)
403f7df2e56Smrg                    pictForm->colormap = pFormat->index.pColormap->mid;
404f7df2e56Smrg                else
405f7df2e56Smrg                    pictForm->colormap = None;
406f7df2e56Smrg                if (client->swapped) {
407f7df2e56Smrg                    swapl(&pictForm->id);
408f7df2e56Smrg                    swaps(&pictForm->direct.red);
409f7df2e56Smrg                    swaps(&pictForm->direct.redMask);
410f7df2e56Smrg                    swaps(&pictForm->direct.green);
411f7df2e56Smrg                    swaps(&pictForm->direct.greenMask);
412f7df2e56Smrg                    swaps(&pictForm->direct.blue);
413f7df2e56Smrg                    swaps(&pictForm->direct.blueMask);
414f7df2e56Smrg                    swaps(&pictForm->direct.alpha);
415f7df2e56Smrg                    swaps(&pictForm->direct.alphaMask);
416f7df2e56Smrg                    swapl(&pictForm->colormap);
417f7df2e56Smrg                }
418f7df2e56Smrg                pictForm++;
419f7df2e56Smrg            }
420f7df2e56Smrg        }
421f7df2e56Smrg    }
422f7df2e56Smrg
42305b261ecSmrg    pictScreen = (xPictScreen *) pictForm;
424f7df2e56Smrg    for (s = 0; s < numScreens; s++) {
425f7df2e56Smrg        pScreen = screenInfo.screens[s];
426f7df2e56Smrg        pictDepth = (xPictDepth *) (pictScreen + 1);
427f7df2e56Smrg        ndepth = 0;
428f7df2e56Smrg        for (d = 0; d < pScreen->numDepths; d++) {
429f7df2e56Smrg            pictVisual = (xPictVisual *) (pictDepth + 1);
430f7df2e56Smrg            pDepth = pScreen->allowedDepths + d;
431f7df2e56Smrg
432f7df2e56Smrg            nvisual = 0;
433f7df2e56Smrg            for (v = 0; v < pDepth->numVids; v++) {
434f7df2e56Smrg                pVisual = findVisual(pScreen, pDepth->vids[v]);
435f7df2e56Smrg                if (pVisual && (pFormat = PictureMatchVisual(pScreen,
436f7df2e56Smrg                                                             pDepth->depth,
437f7df2e56Smrg                                                             pVisual))) {
438f7df2e56Smrg                    pictVisual->visual = pVisual->vid;
439f7df2e56Smrg                    pictVisual->format = pFormat->id;
440f7df2e56Smrg                    if (client->swapped) {
441f7df2e56Smrg                        swapl(&pictVisual->visual);
442f7df2e56Smrg                        swapl(&pictVisual->format);
443f7df2e56Smrg                    }
444f7df2e56Smrg                    pictVisual++;
445f7df2e56Smrg                    nvisual++;
446f7df2e56Smrg                }
447f7df2e56Smrg            }
448f7df2e56Smrg            pictDepth->depth = pDepth->depth;
449f7df2e56Smrg            pictDepth->nPictVisuals = nvisual;
450f7df2e56Smrg            if (client->swapped) {
451f7df2e56Smrg                swaps(&pictDepth->nPictVisuals);
452f7df2e56Smrg            }
453f7df2e56Smrg            ndepth++;
454f7df2e56Smrg            pictDepth = (xPictDepth *) pictVisual;
455f7df2e56Smrg        }
456f7df2e56Smrg        pictScreen->nDepth = ndepth;
457f7df2e56Smrg        ps = GetPictureScreenIfSet(pScreen);
458f7df2e56Smrg        if (ps)
459f7df2e56Smrg            pictScreen->fallback = ps->fallback->id;
460f7df2e56Smrg        else
461f7df2e56Smrg            pictScreen->fallback = 0;
462f7df2e56Smrg        if (client->swapped) {
463f7df2e56Smrg            swapl(&pictScreen->nDepth);
464f7df2e56Smrg            swapl(&pictScreen->fallback);
465f7df2e56Smrg        }
466f7df2e56Smrg        pictScreen = (xPictScreen *) pictDepth;
46705b261ecSmrg    }
46805b261ecSmrg    pictSubpixel = (CARD32 *) pictScreen;
469f7df2e56Smrg
470f7df2e56Smrg    for (s = 0; s < numSubpixel; s++) {
471f7df2e56Smrg        pScreen = screenInfo.screens[s];
472f7df2e56Smrg        ps = GetPictureScreenIfSet(pScreen);
473f7df2e56Smrg        if (ps)
474f7df2e56Smrg            *pictSubpixel = ps->subpixel;
475f7df2e56Smrg        else
476f7df2e56Smrg            *pictSubpixel = SubPixelUnknown;
477f7df2e56Smrg        if (client->swapped) {
478f7df2e56Smrg            swapl(pictSubpixel);
479f7df2e56Smrg        }
480f7df2e56Smrg        ++pictSubpixel;
481f7df2e56Smrg    }
482f7df2e56Smrg
483f7df2e56Smrg    if (client->swapped) {
484f7df2e56Smrg        swaps(&reply->sequenceNumber);
485f7df2e56Smrg        swapl(&reply->length);
486f7df2e56Smrg        swapl(&reply->numFormats);
487f7df2e56Smrg        swapl(&reply->numScreens);
488f7df2e56Smrg        swapl(&reply->numDepths);
489f7df2e56Smrg        swapl(&reply->numVisuals);
490f7df2e56Smrg        swapl(&reply->numSubpixel);
491f7df2e56Smrg    }
492f7df2e56Smrg    WriteToClient(client, rlength, reply);
4936747b715Smrg    free(reply);
4946747b715Smrg    return Success;
49505b261ecSmrg}
49605b261ecSmrg
49705b261ecSmrgstatic int
498f7df2e56SmrgProcRenderQueryPictIndexValues(ClientPtr client)
49905b261ecSmrg{
500f7df2e56Smrg    PictFormatPtr pFormat;
501f7df2e56Smrg    int rc, num;
502f7df2e56Smrg    int rlength;
503f7df2e56Smrg    int i;
504f7df2e56Smrg
50505b261ecSmrg    REQUEST(xRenderQueryPictIndexValuesReq);
50605b261ecSmrg    xRenderQueryPictIndexValuesReply *reply;
507f7df2e56Smrg    xIndexValue *values;
50805b261ecSmrg
50905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
51005b261ecSmrg
511f7df2e56Smrg    rc = dixLookupResourceByType((void **) &pFormat, stuff->format,
512f7df2e56Smrg                                 PictFormatType, client, DixReadAccess);
5136747b715Smrg    if (rc != Success)
514f7df2e56Smrg        return rc;
51505b261ecSmrg
516f7df2e56Smrg    if (pFormat->type != PictTypeIndexed) {
517f7df2e56Smrg        client->errorValue = stuff->format;
518f7df2e56Smrg        return BadMatch;
51905b261ecSmrg    }
52005b261ecSmrg    num = pFormat->index.nvalues;
521f7df2e56Smrg    rlength = (sizeof(xRenderQueryPictIndexValuesReply) +
522f7df2e56Smrg               num * sizeof(xIndexValue));
523f7df2e56Smrg    reply = (xRenderQueryPictIndexValuesReply *) calloc(1, rlength);
52405b261ecSmrg    if (!reply)
525f7df2e56Smrg        return BadAlloc;
52605b261ecSmrg
52705b261ecSmrg    reply->type = X_Reply;
52805b261ecSmrg    reply->sequenceNumber = client->sequence;
5296747b715Smrg    reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
53005b261ecSmrg    reply->numIndexValues = num;
53105b261ecSmrg
53205b261ecSmrg    values = (xIndexValue *) (reply + 1);
533f7df2e56Smrg
534f7df2e56Smrg    memcpy(reply + 1, pFormat->index.pValues, num * sizeof(xIndexValue));
535f7df2e56Smrg
536f7df2e56Smrg    if (client->swapped) {
537f7df2e56Smrg        for (i = 0; i < num; i++) {
538f7df2e56Smrg            swapl(&values[i].pixel);
539f7df2e56Smrg            swaps(&values[i].red);
540f7df2e56Smrg            swaps(&values[i].green);
541f7df2e56Smrg            swaps(&values[i].blue);
542f7df2e56Smrg            swaps(&values[i].alpha);
543f7df2e56Smrg        }
544f7df2e56Smrg        swaps(&reply->sequenceNumber);
545f7df2e56Smrg        swapl(&reply->length);
546f7df2e56Smrg        swapl(&reply->numIndexValues);
547f7df2e56Smrg    }
548f7df2e56Smrg
549f7df2e56Smrg    WriteToClient(client, rlength, reply);
5506747b715Smrg    free(reply);
5516747b715Smrg    return Success;
55205b261ecSmrg}
55305b261ecSmrg
55405b261ecSmrgstatic int
555f7df2e56SmrgProcRenderQueryDithers(ClientPtr client)
55605b261ecSmrg{
55705b261ecSmrg    return BadImplementation;
55805b261ecSmrg}
55905b261ecSmrg
56005b261ecSmrgstatic int
561f7df2e56SmrgProcRenderCreatePicture(ClientPtr client)
56205b261ecSmrg{
563f7df2e56Smrg    PicturePtr pPicture;
564f7df2e56Smrg    DrawablePtr pDrawable;
565f7df2e56Smrg    PictFormatPtr pFormat;
566f7df2e56Smrg    int len, error, rc;
567f7df2e56Smrg
56805b261ecSmrg    REQUEST(xRenderCreatePictureReq);
56905b261ecSmrg
57005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
57105b261ecSmrg
57205b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
57305b261ecSmrg    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
574f7df2e56Smrg                           DixReadAccess | DixAddAccess);
57505b261ecSmrg    if (rc != Success)
576f7df2e56Smrg        return rc;
57705b261ecSmrg
578f7df2e56Smrg    rc = dixLookupResourceByType((void **) &pFormat, stuff->format,
579f7df2e56Smrg                                 PictFormatType, client, DixReadAccess);
5806747b715Smrg    if (rc != Success)
581f7df2e56Smrg        return rc;
5826747b715Smrg
58305b261ecSmrg    if (pFormat->depth != pDrawable->depth)
584f7df2e56Smrg        return BadMatch;
5856747b715Smrg    len = client->req_len - bytes_to_int32(sizeof(xRenderCreatePictureReq));
58605b261ecSmrg    if (Ones(stuff->mask) != len)
587f7df2e56Smrg        return BadLength;
588f7df2e56Smrg
589f7df2e56Smrg    pPicture = CreatePicture(stuff->pid,
590f7df2e56Smrg                             pDrawable,
591f7df2e56Smrg                             pFormat,
592f7df2e56Smrg                             stuff->mask, (XID *) (stuff + 1), client, &error);
59305b261ecSmrg    if (!pPicture)
594f7df2e56Smrg        return error;
595f7df2e56Smrg    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
596f7df2e56Smrg        return BadAlloc;
59705b261ecSmrg    return Success;
59805b261ecSmrg}
59905b261ecSmrg
60005b261ecSmrgstatic int
601f7df2e56SmrgProcRenderChangePicture(ClientPtr client)
60205b261ecSmrg{
603f7df2e56Smrg    PicturePtr pPicture;
604f7df2e56Smrg
60505b261ecSmrg    REQUEST(xRenderChangePictureReq);
60605b261ecSmrg    int len;
60705b261ecSmrg
60805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
609f7df2e56Smrg    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
61005b261ecSmrg
6116747b715Smrg    len = client->req_len - bytes_to_int32(sizeof(xRenderChangePictureReq));
61205b261ecSmrg    if (Ones(stuff->mask) != len)
613f7df2e56Smrg        return BadLength;
614f7df2e56Smrg
615f7df2e56Smrg    return ChangePicture(pPicture, stuff->mask, (XID *) (stuff + 1),
616f7df2e56Smrg                         (DevUnion *) 0, client);
61705b261ecSmrg}
61805b261ecSmrg
61905b261ecSmrgstatic int
620f7df2e56SmrgProcRenderSetPictureClipRectangles(ClientPtr client)
62105b261ecSmrg{
62205b261ecSmrg    REQUEST(xRenderSetPictureClipRectanglesReq);
623f7df2e56Smrg    PicturePtr pPicture;
624f7df2e56Smrg    int nr;
62505b261ecSmrg
62605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
627f7df2e56Smrg    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
62805b261ecSmrg    if (!pPicture->pDrawable)
629f7df2e56Smrg        return RenderErrBase + BadPicture;
63005b261ecSmrg
6316747b715Smrg    nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
63205b261ecSmrg    if (nr & 4)
633f7df2e56Smrg        return BadLength;
63405b261ecSmrg    nr >>= 3;
635f7df2e56Smrg    return SetPictureClipRects(pPicture,
636f7df2e56Smrg                               stuff->xOrigin, stuff->yOrigin,
637f7df2e56Smrg                               nr, (xRectangle *) &stuff[1]);
63805b261ecSmrg}
63905b261ecSmrg
64005b261ecSmrgstatic int
641f7df2e56SmrgProcRenderFreePicture(ClientPtr client)
64205b261ecSmrg{
643f7df2e56Smrg    PicturePtr pPicture;
644f7df2e56Smrg
64505b261ecSmrg    REQUEST(xRenderFreePictureReq);
64605b261ecSmrg
64705b261ecSmrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
64805b261ecSmrg
649f7df2e56Smrg    VERIFY_PICTURE(pPicture, stuff->picture, client, DixDestroyAccess);
650f7df2e56Smrg    FreeResource(stuff->picture, RT_NONE);
6516747b715Smrg    return Success;
65205b261ecSmrg}
65305b261ecSmrg
65405b261ecSmrgstatic Bool
655f7df2e56SmrgPictOpValid(CARD8 op)
65605b261ecSmrg{
657f7df2e56Smrg    if ( /*PictOpMinimum <= op && */ op <= PictOpMaximum)
658f7df2e56Smrg        return TRUE;
65905b261ecSmrg    if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
660f7df2e56Smrg        return TRUE;
66105b261ecSmrg    if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
662f7df2e56Smrg        return TRUE;
6636747b715Smrg    if (PictOpBlendMinimum <= op && op <= PictOpBlendMaximum)
664f7df2e56Smrg        return TRUE;
66505b261ecSmrg    return FALSE;
66605b261ecSmrg}
66705b261ecSmrg
66805b261ecSmrgstatic int
669f7df2e56SmrgProcRenderComposite(ClientPtr client)
67005b261ecSmrg{
671f7df2e56Smrg    PicturePtr pSrc, pMask, pDst;
672f7df2e56Smrg
67305b261ecSmrg    REQUEST(xRenderCompositeReq);
67405b261ecSmrg
67505b261ecSmrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
676f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
677f7df2e56Smrg        client->errorValue = stuff->op;
678f7df2e56Smrg        return BadValue;
67905b261ecSmrg    }
680f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
68105b261ecSmrg    if (!pDst->pDrawable)
68205b261ecSmrg        return BadDrawable;
683f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
684f7df2e56Smrg    VERIFY_ALPHA(pMask, stuff->mask, client, DixReadAccess);
685f7df2e56Smrg    if ((pSrc->pDrawable &&
686f7df2e56Smrg         pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) || (pMask &&
687f7df2e56Smrg                                                                   pMask->
688f7df2e56Smrg                                                                   pDrawable &&
689f7df2e56Smrg                                                                   pDst->
690f7df2e56Smrg                                                                   pDrawable->
691f7df2e56Smrg                                                                   pScreen !=
692f7df2e56Smrg                                                                   pMask->
693f7df2e56Smrg                                                                   pDrawable->
694f7df2e56Smrg                                                                   pScreen))
695f7df2e56Smrg        return BadMatch;
696f7df2e56Smrg    CompositePicture(stuff->op,
697f7df2e56Smrg                     pSrc,
698f7df2e56Smrg                     pMask,
699f7df2e56Smrg                     pDst,
700f7df2e56Smrg                     stuff->xSrc,
701f7df2e56Smrg                     stuff->ySrc,
702f7df2e56Smrg                     stuff->xMask,
703f7df2e56Smrg                     stuff->yMask,
704f7df2e56Smrg                     stuff->xDst, stuff->yDst, stuff->width, stuff->height);
70505b261ecSmrg    return Success;
70605b261ecSmrg}
70705b261ecSmrg
70805b261ecSmrgstatic int
709f7df2e56SmrgProcRenderScale(ClientPtr client)
71005b261ecSmrg{
71105b261ecSmrg    return BadImplementation;
71205b261ecSmrg}
71305b261ecSmrg
71405b261ecSmrgstatic int
715f7df2e56SmrgProcRenderTrapezoids(ClientPtr client)
71605b261ecSmrg{
717f7df2e56Smrg    int rc, ntraps;
718f7df2e56Smrg    PicturePtr pSrc, pDst;
719f7df2e56Smrg    PictFormatPtr pFormat;
720f7df2e56Smrg
72105b261ecSmrg    REQUEST(xRenderTrapezoidsReq);
72205b261ecSmrg
72305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
724f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
725f7df2e56Smrg        client->errorValue = stuff->op;
726f7df2e56Smrg        return BadValue;
72705b261ecSmrg    }
728f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
729f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
73005b261ecSmrg    if (!pDst->pDrawable)
73105b261ecSmrg        return BadDrawable;
73205b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
733f7df2e56Smrg        return BadMatch;
734f7df2e56Smrg    if (stuff->maskFormat) {
735f7df2e56Smrg        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
736f7df2e56Smrg                                     PictFormatType, client, DixReadAccess);
737f7df2e56Smrg        if (rc != Success)
738f7df2e56Smrg            return rc;
73905b261ecSmrg    }
74005b261ecSmrg    else
741f7df2e56Smrg        pFormat = 0;
742f7df2e56Smrg    ntraps = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq);
743f7df2e56Smrg    if (ntraps % sizeof(xTrapezoid))
744f7df2e56Smrg        return BadLength;
745f7df2e56Smrg    ntraps /= sizeof(xTrapezoid);
74605b261ecSmrg    if (ntraps)
747f7df2e56Smrg        CompositeTrapezoids(stuff->op, pSrc, pDst, pFormat,
748f7df2e56Smrg                            stuff->xSrc, stuff->ySrc,
749f7df2e56Smrg                            ntraps, (xTrapezoid *) &stuff[1]);
7506747b715Smrg    return Success;
75105b261ecSmrg}
75205b261ecSmrg
75305b261ecSmrgstatic int
754f7df2e56SmrgProcRenderTriangles(ClientPtr client)
75505b261ecSmrg{
756f7df2e56Smrg    int rc, ntris;
757f7df2e56Smrg    PicturePtr pSrc, pDst;
758f7df2e56Smrg    PictFormatPtr pFormat;
759f7df2e56Smrg
76005b261ecSmrg    REQUEST(xRenderTrianglesReq);
76105b261ecSmrg
76205b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
763f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
764f7df2e56Smrg        client->errorValue = stuff->op;
765f7df2e56Smrg        return BadValue;
76605b261ecSmrg    }
767f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
768f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
76905b261ecSmrg    if (!pDst->pDrawable)
77005b261ecSmrg        return BadDrawable;
77105b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
772f7df2e56Smrg        return BadMatch;
773f7df2e56Smrg    if (stuff->maskFormat) {
774f7df2e56Smrg        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
775f7df2e56Smrg                                     PictFormatType, client, DixReadAccess);
776f7df2e56Smrg        if (rc != Success)
777f7df2e56Smrg            return rc;
77805b261ecSmrg    }
77905b261ecSmrg    else
780f7df2e56Smrg        pFormat = 0;
781f7df2e56Smrg    ntris = (client->req_len << 2) - sizeof(xRenderTrianglesReq);
782f7df2e56Smrg    if (ntris % sizeof(xTriangle))
783f7df2e56Smrg        return BadLength;
784f7df2e56Smrg    ntris /= sizeof(xTriangle);
78505b261ecSmrg    if (ntris)
786f7df2e56Smrg        CompositeTriangles(stuff->op, pSrc, pDst, pFormat,
787f7df2e56Smrg                           stuff->xSrc, stuff->ySrc,
788f7df2e56Smrg                           ntris, (xTriangle *) &stuff[1]);
7896747b715Smrg    return Success;
79005b261ecSmrg}
79105b261ecSmrg
79205b261ecSmrgstatic int
793f7df2e56SmrgProcRenderTriStrip(ClientPtr client)
79405b261ecSmrg{
795f7df2e56Smrg    int rc, npoints;
796f7df2e56Smrg    PicturePtr pSrc, pDst;
797f7df2e56Smrg    PictFormatPtr pFormat;
798f7df2e56Smrg
79905b261ecSmrg    REQUEST(xRenderTrianglesReq);
80005b261ecSmrg
80105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
802f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
803f7df2e56Smrg        client->errorValue = stuff->op;
804f7df2e56Smrg        return BadValue;
80505b261ecSmrg    }
806f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
807f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
80805b261ecSmrg    if (!pDst->pDrawable)
80905b261ecSmrg        return BadDrawable;
81005b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
811f7df2e56Smrg        return BadMatch;
812f7df2e56Smrg    if (stuff->maskFormat) {
813f7df2e56Smrg        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
814f7df2e56Smrg                                     PictFormatType, client, DixReadAccess);
815f7df2e56Smrg        if (rc != Success)
816f7df2e56Smrg            return rc;
81705b261ecSmrg    }
81805b261ecSmrg    else
819f7df2e56Smrg        pFormat = 0;
820f7df2e56Smrg    npoints = ((client->req_len << 2) - sizeof(xRenderTriStripReq));
82105b261ecSmrg    if (npoints & 4)
822f7df2e56Smrg        return BadLength;
82305b261ecSmrg    npoints >>= 3;
82405b261ecSmrg    if (npoints >= 3)
825f7df2e56Smrg        CompositeTriStrip(stuff->op, pSrc, pDst, pFormat,
826f7df2e56Smrg                          stuff->xSrc, stuff->ySrc,
827f7df2e56Smrg                          npoints, (xPointFixed *) &stuff[1]);
8286747b715Smrg    return Success;
82905b261ecSmrg}
83005b261ecSmrg
83105b261ecSmrgstatic int
832f7df2e56SmrgProcRenderTriFan(ClientPtr client)
83305b261ecSmrg{
834f7df2e56Smrg    int rc, npoints;
835f7df2e56Smrg    PicturePtr pSrc, pDst;
836f7df2e56Smrg    PictFormatPtr pFormat;
837f7df2e56Smrg
83805b261ecSmrg    REQUEST(xRenderTrianglesReq);
83905b261ecSmrg
84005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
841f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
842f7df2e56Smrg        client->errorValue = stuff->op;
843f7df2e56Smrg        return BadValue;
84405b261ecSmrg    }
845f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
846f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
84705b261ecSmrg    if (!pDst->pDrawable)
84805b261ecSmrg        return BadDrawable;
84905b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
850f7df2e56Smrg        return BadMatch;
851f7df2e56Smrg    if (stuff->maskFormat) {
852f7df2e56Smrg        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
853f7df2e56Smrg                                     PictFormatType, client, DixReadAccess);
854f7df2e56Smrg        if (rc != Success)
855f7df2e56Smrg            return rc;
85605b261ecSmrg    }
85705b261ecSmrg    else
858f7df2e56Smrg        pFormat = 0;
859f7df2e56Smrg    npoints = ((client->req_len << 2) - sizeof(xRenderTriStripReq));
86005b261ecSmrg    if (npoints & 4)
861f7df2e56Smrg        return BadLength;
86205b261ecSmrg    npoints >>= 3;
86305b261ecSmrg    if (npoints >= 3)
864f7df2e56Smrg        CompositeTriFan(stuff->op, pSrc, pDst, pFormat,
865f7df2e56Smrg                        stuff->xSrc, stuff->ySrc,
866f7df2e56Smrg                        npoints, (xPointFixed *) &stuff[1]);
8676747b715Smrg    return Success;
86805b261ecSmrg}
86905b261ecSmrg
87005b261ecSmrgstatic int
871f7df2e56SmrgProcRenderColorTrapezoids(ClientPtr client)
87205b261ecSmrg{
87305b261ecSmrg    return BadImplementation;
87405b261ecSmrg}
87505b261ecSmrg
87605b261ecSmrgstatic int
877f7df2e56SmrgProcRenderColorTriangles(ClientPtr client)
87805b261ecSmrg{
87905b261ecSmrg    return BadImplementation;
88005b261ecSmrg}
88105b261ecSmrg
88205b261ecSmrgstatic int
883f7df2e56SmrgProcRenderTransform(ClientPtr client)
88405b261ecSmrg{
88505b261ecSmrg    return BadImplementation;
88605b261ecSmrg}
88705b261ecSmrg
88805b261ecSmrgstatic int
889f7df2e56SmrgProcRenderCreateGlyphSet(ClientPtr client)
89005b261ecSmrg{
891f7df2e56Smrg    GlyphSetPtr glyphSet;
892f7df2e56Smrg    PictFormatPtr format;
893f7df2e56Smrg    int rc, f;
894f7df2e56Smrg
89505b261ecSmrg    REQUEST(xRenderCreateGlyphSetReq);
89605b261ecSmrg
89705b261ecSmrg    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
89805b261ecSmrg
89905b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->gsid, client);
900f7df2e56Smrg    rc = dixLookupResourceByType((void **) &format, stuff->format,
901f7df2e56Smrg                                 PictFormatType, client, DixReadAccess);
9026747b715Smrg    if (rc != Success)
903f7df2e56Smrg        return rc;
9046747b715Smrg
90505b261ecSmrg    switch (format->depth) {
90605b261ecSmrg    case 1:
907f7df2e56Smrg        f = GlyphFormat1;
908f7df2e56Smrg        break;
90905b261ecSmrg    case 4:
910f7df2e56Smrg        f = GlyphFormat4;
911f7df2e56Smrg        break;
91205b261ecSmrg    case 8:
913f7df2e56Smrg        f = GlyphFormat8;
914f7df2e56Smrg        break;
91505b261ecSmrg    case 16:
916f7df2e56Smrg        f = GlyphFormat16;
917f7df2e56Smrg        break;
91805b261ecSmrg    case 32:
919f7df2e56Smrg        f = GlyphFormat32;
920f7df2e56Smrg        break;
92105b261ecSmrg    default:
922f7df2e56Smrg        return BadMatch;
92305b261ecSmrg    }
92405b261ecSmrg    if (format->type != PictTypeDirect)
925f7df2e56Smrg        return BadMatch;
926f7df2e56Smrg    glyphSet = AllocateGlyphSet(f, format);
92705b261ecSmrg    if (!glyphSet)
928f7df2e56Smrg        return BadAlloc;
9294642e01fSmrg    /* security creation/labeling check */
9304642e01fSmrg    rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType,
931f7df2e56Smrg                  glyphSet, RT_NONE, NULL, DixCreateAccess);
9324642e01fSmrg    if (rc != Success)
933f7df2e56Smrg        return rc;
934f7df2e56Smrg    if (!AddResource(stuff->gsid, GlyphSetType, (void *) glyphSet))
935f7df2e56Smrg        return BadAlloc;
93605b261ecSmrg    return Success;
93705b261ecSmrg}
93805b261ecSmrg
93905b261ecSmrgstatic int
940f7df2e56SmrgProcRenderReferenceGlyphSet(ClientPtr client)
94105b261ecSmrg{
942f7df2e56Smrg    GlyphSetPtr glyphSet;
9434642e01fSmrg    int rc;
944f7df2e56Smrg
94505b261ecSmrg    REQUEST(xRenderReferenceGlyphSetReq);
94605b261ecSmrg
94705b261ecSmrg    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
94805b261ecSmrg
94905b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->gsid, client);
95005b261ecSmrg
951f7df2e56Smrg    rc = dixLookupResourceByType((void **) &glyphSet, stuff->existing,
952f7df2e56Smrg                                 GlyphSetType, client, DixGetAttrAccess);
953f7df2e56Smrg    if (rc != Success) {
954f7df2e56Smrg        client->errorValue = stuff->existing;
955f7df2e56Smrg        return rc;
95605b261ecSmrg    }
95705b261ecSmrg    glyphSet->refcnt++;
958f7df2e56Smrg    if (!AddResource(stuff->gsid, GlyphSetType, (void *) glyphSet))
959f7df2e56Smrg        return BadAlloc;
9606747b715Smrg    return Success;
96105b261ecSmrg}
96205b261ecSmrg
96305b261ecSmrg#define NLOCALDELTA	64
96405b261ecSmrg#define NLOCALGLYPH	256
96505b261ecSmrg
96605b261ecSmrgstatic int
967f7df2e56SmrgProcRenderFreeGlyphSet(ClientPtr client)
96805b261ecSmrg{
969f7df2e56Smrg    GlyphSetPtr glyphSet;
9704642e01fSmrg    int rc;
971f7df2e56Smrg
97205b261ecSmrg    REQUEST(xRenderFreeGlyphSetReq);
97305b261ecSmrg
97405b261ecSmrg    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
975f7df2e56Smrg    rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
976f7df2e56Smrg                                 GlyphSetType, client, DixDestroyAccess);
977f7df2e56Smrg    if (rc != Success) {
978f7df2e56Smrg        client->errorValue = stuff->glyphset;
979f7df2e56Smrg        return rc;
98005b261ecSmrg    }
981f7df2e56Smrg    FreeResource(stuff->glyphset, RT_NONE);
9826747b715Smrg    return Success;
98305b261ecSmrg}
98405b261ecSmrg
98505b261ecSmrgtypedef struct _GlyphNew {
986f7df2e56Smrg    Glyph id;
987f7df2e56Smrg    GlyphPtr glyph;
988f7df2e56Smrg    Bool found;
989f7df2e56Smrg    unsigned char sha1[20];
99005b261ecSmrg} GlyphNewRec, *GlyphNewPtr;
99105b261ecSmrg
9924642e01fSmrg#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
9934642e01fSmrg
99405b261ecSmrgstatic int
995f7df2e56SmrgProcRenderAddGlyphs(ClientPtr client)
99605b261ecSmrg{
997f7df2e56Smrg    GlyphSetPtr glyphSet;
998f7df2e56Smrg
99905b261ecSmrg    REQUEST(xRenderAddGlyphsReq);
1000f7df2e56Smrg    GlyphNewRec glyphsLocal[NLOCALGLYPH];
1001f7df2e56Smrg    GlyphNewPtr glyphsBase, glyphs, glyph_new;
1002f7df2e56Smrg    int remain, nglyphs;
1003f7df2e56Smrg    CARD32 *gids;
1004f7df2e56Smrg    xGlyphInfo *gi;
1005f7df2e56Smrg    CARD8 *bits;
1006f7df2e56Smrg    unsigned int size;
1007f7df2e56Smrg    int err;
1008f7df2e56Smrg    int i, screen;
1009f7df2e56Smrg    PicturePtr pSrc = NULL, pDst = NULL;
1010f7df2e56Smrg    PixmapPtr pSrcPix = NULL, pDstPix = NULL;
1011f7df2e56Smrg    CARD32 component_alpha;
101205b261ecSmrg
101305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
1014f7df2e56Smrg    err =
1015f7df2e56Smrg        dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
1016f7df2e56Smrg                                GlyphSetType, client, DixAddAccess);
1017f7df2e56Smrg    if (err != Success) {
1018f7df2e56Smrg        client->errorValue = stuff->glyphset;
1019f7df2e56Smrg        return err;
102005b261ecSmrg    }
102105b261ecSmrg
10224642e01fSmrg    err = BadAlloc;
102305b261ecSmrg    nglyphs = stuff->nglyphs;
102405b261ecSmrg    if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
1025f7df2e56Smrg        return BadAlloc;
102605b261ecSmrg
1027f7df2e56Smrg    component_alpha = NeedsComponent(glyphSet->format->format);
10284642e01fSmrg
10294642e01fSmrg    if (nglyphs <= NLOCALGLYPH) {
1030f7df2e56Smrg        memset(glyphsLocal, 0, sizeof(glyphsLocal));
1031f7df2e56Smrg        glyphsBase = glyphsLocal;
10324642e01fSmrg    }
1033f7df2e56Smrg    else {
1034f7df2e56Smrg        glyphsBase = (GlyphNewPtr) calloc(nglyphs, sizeof(GlyphNewRec));
1035f7df2e56Smrg        if (!glyphsBase)
1036f7df2e56Smrg            return BadAlloc;
103705b261ecSmrg    }
103805b261ecSmrg
1039f7df2e56Smrg    remain = (client->req_len << 2) - sizeof(xRenderAddGlyphsReq);
104005b261ecSmrg
104105b261ecSmrg    glyphs = glyphsBase;
104205b261ecSmrg
104305b261ecSmrg    gids = (CARD32 *) (stuff + 1);
104405b261ecSmrg    gi = (xGlyphInfo *) (gids + nglyphs);
104505b261ecSmrg    bits = (CARD8 *) (gi + nglyphs);
1046f7df2e56Smrg    remain -= (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs;
10476747b715Smrg
10486747b715Smrg    /* protect against bad nglyphs */
1049f7df2e56Smrg    if (gi < ((xGlyphInfo *) stuff) ||
1050f7df2e56Smrg        gi > ((xGlyphInfo *) ((CARD32 *) stuff + client->req_len)) ||
1051f7df2e56Smrg        bits < ((CARD8 *) stuff) ||
1052f7df2e56Smrg        bits > ((CARD8 *) ((CARD32 *) stuff + client->req_len))) {
10536747b715Smrg        err = BadLength;
10546747b715Smrg        goto bail;
10556747b715Smrg    }
10566747b715Smrg
1057f7df2e56Smrg    for (i = 0; i < nglyphs; i++) {
1058f7df2e56Smrg        size_t padded_width;
1059f7df2e56Smrg
1060f7df2e56Smrg        glyph_new = &glyphs[i];
1061f7df2e56Smrg
1062f7df2e56Smrg        padded_width = PixmapBytePad(gi[i].width, glyphSet->format->depth);
1063f7df2e56Smrg
1064f7df2e56Smrg        if (gi[i].height &&
1065f7df2e56Smrg            padded_width > (UINT32_MAX - sizeof(GlyphRec)) / gi[i].height)
1066f7df2e56Smrg            break;
1067f7df2e56Smrg
1068f7df2e56Smrg        size = gi[i].height * padded_width;
1069f7df2e56Smrg        if (remain < size)
1070f7df2e56Smrg            break;
1071f7df2e56Smrg
1072f7df2e56Smrg        err = HashGlyph(&gi[i], bits, size, glyph_new->sha1);
1073f7df2e56Smrg        if (err)
1074f7df2e56Smrg            goto bail;
1075f7df2e56Smrg
1076f7df2e56Smrg        glyph_new->glyph = FindGlyphByHash(glyph_new->sha1, glyphSet->fdepth);
1077f7df2e56Smrg
1078f7df2e56Smrg        if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) {
1079f7df2e56Smrg            glyph_new->found = TRUE;
1080f7df2e56Smrg        }
1081f7df2e56Smrg        else {
1082f7df2e56Smrg            GlyphPtr glyph;
1083f7df2e56Smrg
1084f7df2e56Smrg            glyph_new->found = FALSE;
1085f7df2e56Smrg            glyph_new->glyph = glyph = AllocateGlyph(&gi[i], glyphSet->fdepth);
1086f7df2e56Smrg            if (!glyph) {
1087f7df2e56Smrg                err = BadAlloc;
1088f7df2e56Smrg                goto bail;
1089f7df2e56Smrg            }
1090f7df2e56Smrg
1091f7df2e56Smrg            for (screen = 0; screen < screenInfo.numScreens; screen++) {
1092f7df2e56Smrg                int width = gi[i].width;
1093f7df2e56Smrg                int height = gi[i].height;
1094f7df2e56Smrg                int depth = glyphSet->format->depth;
1095f7df2e56Smrg                ScreenPtr pScreen;
1096f7df2e56Smrg                int error;
1097f7df2e56Smrg
1098f7df2e56Smrg                /* Skip work if it's invisibly small anyway */
1099f7df2e56Smrg                if (!width || !height)
1100f7df2e56Smrg                    break;
1101f7df2e56Smrg
1102f7df2e56Smrg                pScreen = screenInfo.screens[screen];
1103f7df2e56Smrg                pSrcPix = GetScratchPixmapHeader(pScreen,
1104f7df2e56Smrg                                                 width, height,
1105f7df2e56Smrg                                                 depth, depth, -1, bits);
1106f7df2e56Smrg                if (!pSrcPix) {
1107f7df2e56Smrg                    err = BadAlloc;
1108f7df2e56Smrg                    goto bail;
1109f7df2e56Smrg                }
1110f7df2e56Smrg
1111f7df2e56Smrg                pSrc = CreatePicture(0, &pSrcPix->drawable,
1112f7df2e56Smrg                                     glyphSet->format, 0, NULL,
1113f7df2e56Smrg                                     serverClient, &error);
1114f7df2e56Smrg                if (!pSrc) {
1115f7df2e56Smrg                    err = BadAlloc;
1116f7df2e56Smrg                    goto bail;
1117f7df2e56Smrg                }
1118f7df2e56Smrg
1119f7df2e56Smrg                pDstPix = (pScreen->CreatePixmap) (pScreen,
1120f7df2e56Smrg                                                   width, height, depth,
1121f7df2e56Smrg                                                   CREATE_PIXMAP_USAGE_GLYPH_PICTURE);
1122f7df2e56Smrg
1123f7df2e56Smrg                if (!pDstPix) {
1124f7df2e56Smrg                    err = BadAlloc;
1125f7df2e56Smrg                    goto bail;
1126f7df2e56Smrg                }
1127f7df2e56Smrg
1128f7df2e56Smrg                pDst = CreatePicture(0, &pDstPix->drawable,
1129f7df2e56Smrg                                  glyphSet->format,
1130f7df2e56Smrg                                  CPComponentAlpha, &component_alpha,
1131f7df2e56Smrg                                  serverClient, &error);
1132f7df2e56Smrg                SetGlyphPicture(glyph, pScreen, pDst);
1133f7df2e56Smrg
1134f7df2e56Smrg                /* The picture takes a reference to the pixmap, so we
1135f7df2e56Smrg                   drop ours. */
1136f7df2e56Smrg                (pScreen->DestroyPixmap) (pDstPix);
1137f7df2e56Smrg                pDstPix = NULL;
1138f7df2e56Smrg
1139f7df2e56Smrg                if (!pDst) {
1140f7df2e56Smrg                    err = BadAlloc;
1141f7df2e56Smrg                    goto bail;
1142f7df2e56Smrg                }
1143f7df2e56Smrg
1144f7df2e56Smrg                CompositePicture(PictOpSrc,
1145f7df2e56Smrg                                 pSrc,
1146f7df2e56Smrg                                 None, pDst, 0, 0, 0, 0, 0, 0, width, height);
1147f7df2e56Smrg
1148f7df2e56Smrg                FreePicture((void *) pSrc, 0);
1149f7df2e56Smrg                pSrc = NULL;
1150f7df2e56Smrg                FreeScratchPixmapHeader(pSrcPix);
1151f7df2e56Smrg                pSrcPix = NULL;
1152f7df2e56Smrg            }
1153f7df2e56Smrg
1154f7df2e56Smrg            memcpy(glyph_new->glyph->sha1, glyph_new->sha1, 20);
1155f7df2e56Smrg        }
1156f7df2e56Smrg
1157f7df2e56Smrg        glyph_new->id = gids[i];
1158f7df2e56Smrg
1159f7df2e56Smrg        if (size & 3)
1160f7df2e56Smrg            size += 4 - (size & 3);
1161f7df2e56Smrg        bits += size;
1162f7df2e56Smrg        remain -= size;
1163f7df2e56Smrg    }
1164f7df2e56Smrg    if (remain || i < nglyphs) {
1165f7df2e56Smrg        err = BadLength;
1166f7df2e56Smrg        goto bail;
1167f7df2e56Smrg    }
1168f7df2e56Smrg    if (!ResizeGlyphSet(glyphSet, nglyphs)) {
1169f7df2e56Smrg        err = BadAlloc;
1170f7df2e56Smrg        goto bail;
117105b261ecSmrg    }
11724642e01fSmrg    for (i = 0; i < nglyphs; i++)
1173f7df2e56Smrg        AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id);
117405b261ecSmrg
117505b261ecSmrg    if (glyphsBase != glyphsLocal)
1176f7df2e56Smrg        free(glyphsBase);
11776747b715Smrg    return Success;
1178f7df2e56Smrg bail:
11794642e01fSmrg    if (pSrc)
1180f7df2e56Smrg        FreePicture((void *) pSrc, 0);
11814642e01fSmrg    if (pSrcPix)
1182f7df2e56Smrg        FreeScratchPixmapHeader(pSrcPix);
11834642e01fSmrg    for (i = 0; i < nglyphs; i++)
1184f7df2e56Smrg        if (glyphs[i].glyph && !glyphs[i].found)
1185f7df2e56Smrg            free(glyphs[i].glyph);
118605b261ecSmrg    if (glyphsBase != glyphsLocal)
1187f7df2e56Smrg        free(glyphsBase);
118805b261ecSmrg    return err;
118905b261ecSmrg}
119005b261ecSmrg
119105b261ecSmrgstatic int
1192f7df2e56SmrgProcRenderAddGlyphsFromPicture(ClientPtr client)
119305b261ecSmrg{
119405b261ecSmrg    return BadImplementation;
119505b261ecSmrg}
119605b261ecSmrg
119705b261ecSmrgstatic int
1198f7df2e56SmrgProcRenderFreeGlyphs(ClientPtr client)
119905b261ecSmrg{
120005b261ecSmrg    REQUEST(xRenderFreeGlyphsReq);
1201f7df2e56Smrg    GlyphSetPtr glyphSet;
1202f7df2e56Smrg    int rc, nglyph;
1203f7df2e56Smrg    CARD32 *gids;
1204f7df2e56Smrg    CARD32 glyph;
120505b261ecSmrg
120605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
1207f7df2e56Smrg    rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
1208f7df2e56Smrg                                 GlyphSetType, client, DixRemoveAccess);
1209f7df2e56Smrg    if (rc != Success) {
1210f7df2e56Smrg        client->errorValue = stuff->glyphset;
1211f7df2e56Smrg        return rc;
1212f7df2e56Smrg    }
1213f7df2e56Smrg    nglyph =
1214f7df2e56Smrg        bytes_to_int32((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq));
121505b261ecSmrg    gids = (CARD32 *) (stuff + 1);
1216f7df2e56Smrg    while (nglyph-- > 0) {
1217f7df2e56Smrg        glyph = *gids++;
1218f7df2e56Smrg        if (!DeleteGlyph(glyphSet, glyph)) {
1219f7df2e56Smrg            client->errorValue = glyph;
1220f7df2e56Smrg            return RenderErrBase + BadGlyph;
1221f7df2e56Smrg        }
122205b261ecSmrg    }
12236747b715Smrg    return Success;
122405b261ecSmrg}
122505b261ecSmrg
122605b261ecSmrgstatic int
1227f7df2e56SmrgProcRenderCompositeGlyphs(ClientPtr client)
1228f7df2e56Smrg{
1229f7df2e56Smrg    GlyphSetPtr glyphSet;
1230f7df2e56Smrg    GlyphSet gs;
1231f7df2e56Smrg    PicturePtr pSrc, pDst;
1232f7df2e56Smrg    PictFormatPtr pFormat;
1233f7df2e56Smrg    GlyphListRec listsLocal[NLOCALDELTA];
1234f7df2e56Smrg    GlyphListPtr lists, listsBase;
1235f7df2e56Smrg    GlyphPtr glyphsLocal[NLOCALGLYPH];
1236f7df2e56Smrg    Glyph glyph;
1237f7df2e56Smrg    GlyphPtr *glyphs, *glyphsBase;
1238f7df2e56Smrg    xGlyphElt *elt;
1239f7df2e56Smrg    CARD8 *buffer, *end;
1240f7df2e56Smrg    int nglyph;
1241f7df2e56Smrg    int nlist;
1242f7df2e56Smrg    int space;
1243f7df2e56Smrg    int size;
1244f7df2e56Smrg    int rc, n;
1245f7df2e56Smrg
124605b261ecSmrg    REQUEST(xRenderCompositeGlyphsReq);
124705b261ecSmrg
124805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
124905b261ecSmrg
125005b261ecSmrg    switch (stuff->renderReqType) {
1251f7df2e56Smrg    default:
1252f7df2e56Smrg        size = 1;
1253f7df2e56Smrg        break;
1254f7df2e56Smrg    case X_RenderCompositeGlyphs16:
1255f7df2e56Smrg        size = 2;
1256f7df2e56Smrg        break;
1257f7df2e56Smrg    case X_RenderCompositeGlyphs32:
1258f7df2e56Smrg        size = 4;
1259f7df2e56Smrg        break;
1260f7df2e56Smrg    }
1261f7df2e56Smrg
1262f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
1263f7df2e56Smrg        client->errorValue = stuff->op;
1264f7df2e56Smrg        return BadValue;
1265f7df2e56Smrg    }
1266f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
1267f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
126805b261ecSmrg    if (!pDst->pDrawable)
126905b261ecSmrg        return BadDrawable;
127005b261ecSmrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
1271f7df2e56Smrg        return BadMatch;
1272f7df2e56Smrg    if (stuff->maskFormat) {
1273f7df2e56Smrg        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
1274f7df2e56Smrg                                     PictFormatType, client, DixReadAccess);
1275f7df2e56Smrg        if (rc != Success)
1276f7df2e56Smrg            return rc;
127705b261ecSmrg    }
127805b261ecSmrg    else
1279f7df2e56Smrg        pFormat = 0;
128005b261ecSmrg
1281f7df2e56Smrg    rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
1282f7df2e56Smrg                                 GlyphSetType, client, DixUseAccess);
12836747b715Smrg    if (rc != Success)
1284f7df2e56Smrg        return rc;
128505b261ecSmrg
128605b261ecSmrg    buffer = (CARD8 *) (stuff + 1);
128705b261ecSmrg    end = (CARD8 *) stuff + (client->req_len << 2);
128805b261ecSmrg    nglyph = 0;
128905b261ecSmrg    nlist = 0;
1290f7df2e56Smrg    while (buffer + sizeof(xGlyphElt) < end) {
1291f7df2e56Smrg        elt = (xGlyphElt *) buffer;
1292f7df2e56Smrg        buffer += sizeof(xGlyphElt);
1293f7df2e56Smrg
1294f7df2e56Smrg        if (elt->len == 0xff) {
1295f7df2e56Smrg            buffer += 4;
1296f7df2e56Smrg        }
1297f7df2e56Smrg        else {
1298f7df2e56Smrg            nlist++;
1299f7df2e56Smrg            nglyph += elt->len;
1300f7df2e56Smrg            space = size * elt->len;
1301f7df2e56Smrg            if (space & 3)
1302f7df2e56Smrg                space += 4 - (space & 3);
1303f7df2e56Smrg            buffer += space;
1304f7df2e56Smrg        }
130505b261ecSmrg    }
130605b261ecSmrg    if (nglyph <= NLOCALGLYPH)
1307f7df2e56Smrg        glyphsBase = glyphsLocal;
1308f7df2e56Smrg    else {
1309f7df2e56Smrg        glyphsBase = xallocarray(nglyph, sizeof(GlyphPtr));
1310f7df2e56Smrg        if (!glyphsBase)
1311f7df2e56Smrg            return BadAlloc;
131205b261ecSmrg    }
131305b261ecSmrg    if (nlist <= NLOCALDELTA)
1314f7df2e56Smrg        listsBase = listsLocal;
1315f7df2e56Smrg    else {
1316f7df2e56Smrg        listsBase = xallocarray(nlist, sizeof(GlyphListRec));
1317f7df2e56Smrg        if (!listsBase) {
1318f7df2e56Smrg            rc = BadAlloc;
1319f7df2e56Smrg            goto bail;
1320f7df2e56Smrg        }
132105b261ecSmrg    }
132205b261ecSmrg    buffer = (CARD8 *) (stuff + 1);
132305b261ecSmrg    glyphs = glyphsBase;
132405b261ecSmrg    lists = listsBase;
1325f7df2e56Smrg    while (buffer + sizeof(xGlyphElt) < end) {
1326f7df2e56Smrg        elt = (xGlyphElt *) buffer;
1327f7df2e56Smrg        buffer += sizeof(xGlyphElt);
1328f7df2e56Smrg
1329f7df2e56Smrg        if (elt->len == 0xff) {
1330f7df2e56Smrg            if (buffer + sizeof(GlyphSet) < end) {
133105b261ecSmrg                memcpy(&gs, buffer, sizeof(GlyphSet));
1332f7df2e56Smrg                rc = dixLookupResourceByType((void **) &glyphSet, gs,
1333f7df2e56Smrg                                             GlyphSetType, client,
1334f7df2e56Smrg                                             DixUseAccess);
1335f7df2e56Smrg                if (rc != Success)
1336f7df2e56Smrg                    goto bail;
1337f7df2e56Smrg            }
1338f7df2e56Smrg            buffer += 4;
1339f7df2e56Smrg        }
1340f7df2e56Smrg        else {
1341f7df2e56Smrg            lists->xOff = elt->deltax;
1342f7df2e56Smrg            lists->yOff = elt->deltay;
1343f7df2e56Smrg            lists->format = glyphSet->format;
1344f7df2e56Smrg            lists->len = 0;
1345f7df2e56Smrg            n = elt->len;
1346f7df2e56Smrg            while (n--) {
1347f7df2e56Smrg                if (buffer + size <= end) {
1348f7df2e56Smrg                    switch (size) {
1349f7df2e56Smrg                    case 1:
1350f7df2e56Smrg                        glyph = *((CARD8 *) buffer);
1351f7df2e56Smrg                        break;
1352f7df2e56Smrg                    case 2:
1353f7df2e56Smrg                        glyph = *((CARD16 *) buffer);
1354f7df2e56Smrg                        break;
1355f7df2e56Smrg                    case 4:
1356f7df2e56Smrg                    default:
1357f7df2e56Smrg                        glyph = *((CARD32 *) buffer);
1358f7df2e56Smrg                        break;
1359f7df2e56Smrg                    }
1360f7df2e56Smrg                    if ((*glyphs = FindGlyph(glyphSet, glyph))) {
1361f7df2e56Smrg                        lists->len++;
1362f7df2e56Smrg                        glyphs++;
1363f7df2e56Smrg                    }
1364f7df2e56Smrg                }
1365f7df2e56Smrg                buffer += size;
1366f7df2e56Smrg            }
1367f7df2e56Smrg            space = size * elt->len;
1368f7df2e56Smrg            if (space & 3)
1369f7df2e56Smrg                buffer += 4 - (space & 3);
1370f7df2e56Smrg            lists++;
1371f7df2e56Smrg        }
137205b261ecSmrg    }
13739ace9065Smrg    if (buffer > end) {
1374f7df2e56Smrg        rc = BadLength;
1375f7df2e56Smrg        goto bail;
1376f7df2e56Smrg    }
1377f7df2e56Smrg
1378f7df2e56Smrg    CompositeGlyphs(stuff->op,
1379f7df2e56Smrg                    pSrc,
1380f7df2e56Smrg                    pDst,
1381f7df2e56Smrg                    pFormat,
1382f7df2e56Smrg                    stuff->xSrc, stuff->ySrc, nlist, listsBase, glyphsBase);
13839ace9065Smrg    rc = Success;
138405b261ecSmrg
1385f7df2e56Smrg bail:
138605b261ecSmrg    if (glyphsBase != glyphsLocal)
1387f7df2e56Smrg        free(glyphsBase);
138805b261ecSmrg    if (listsBase != listsLocal)
1389f7df2e56Smrg        free(listsBase);
13909ace9065Smrg    return rc;
139105b261ecSmrg}
139205b261ecSmrg
139305b261ecSmrgstatic int
1394f7df2e56SmrgProcRenderFillRectangles(ClientPtr client)
139505b261ecSmrg{
1396f7df2e56Smrg    PicturePtr pDst;
1397f7df2e56Smrg    int things;
1398f7df2e56Smrg
139905b261ecSmrg    REQUEST(xRenderFillRectanglesReq);
1400f7df2e56Smrg
1401f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
1402f7df2e56Smrg    if (!PictOpValid(stuff->op)) {
1403f7df2e56Smrg        client->errorValue = stuff->op;
1404f7df2e56Smrg        return BadValue;
1405f7df2e56Smrg    }
1406f7df2e56Smrg    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
140705b261ecSmrg    if (!pDst->pDrawable)
140805b261ecSmrg        return BadDrawable;
1409f7df2e56Smrg
141005b261ecSmrg    things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
141105b261ecSmrg    if (things & 4)
1412f7df2e56Smrg        return BadLength;
141305b261ecSmrg    things >>= 3;
1414f7df2e56Smrg
1415f7df2e56Smrg    CompositeRects(stuff->op,
1416f7df2e56Smrg                   pDst, &stuff->color, things, (xRectangle *) &stuff[1]);
1417f7df2e56Smrg
14186747b715Smrg    return Success;
141905b261ecSmrg}
142005b261ecSmrg
142105b261ecSmrgstatic void
1422f7df2e56SmrgRenderSetBit(unsigned char *line, int x, int bit)
142305b261ecSmrg{
1424f7df2e56Smrg    unsigned char mask;
1425f7df2e56Smrg
142605b261ecSmrg    if (screenInfo.bitmapBitOrder == LSBFirst)
1427f7df2e56Smrg        mask = (1 << (x & 7));
142805b261ecSmrg    else
1429f7df2e56Smrg        mask = (0x80 >> (x & 7));
143005b261ecSmrg    /* XXX assumes byte order is host byte order */
143105b261ecSmrg    line += (x >> 3);
143205b261ecSmrg    if (bit)
1433f7df2e56Smrg        *line |= mask;
143405b261ecSmrg    else
1435f7df2e56Smrg        *line &= ~mask;
143605b261ecSmrg}
143705b261ecSmrg
143805b261ecSmrg#define DITHER_DIM 2
143905b261ecSmrg
144005b261ecSmrgstatic CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
1441f7df2e56Smrg    {1, 3,},
1442f7df2e56Smrg    {4, 2,},
144305b261ecSmrg};
144405b261ecSmrg
144505b261ecSmrg#define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
144605b261ecSmrg
144705b261ecSmrgstatic int
1448f7df2e56SmrgProcRenderCreateCursor(ClientPtr client)
144905b261ecSmrg{
145005b261ecSmrg    REQUEST(xRenderCreateCursorReq);
1451f7df2e56Smrg    PicturePtr pSrc;
1452f7df2e56Smrg    ScreenPtr pScreen;
1453f7df2e56Smrg    unsigned short width, height;
1454f7df2e56Smrg    CARD32 *argbbits, *argb;
1455f7df2e56Smrg    unsigned char *srcbits, *srcline;
1456f7df2e56Smrg    unsigned char *mskbits, *mskline;
1457f7df2e56Smrg    int stride;
1458f7df2e56Smrg    int x, y;
1459f7df2e56Smrg    int nbytes_mono;
146005b261ecSmrg    CursorMetricRec cm;
1461f7df2e56Smrg    CursorPtr pCursor;
1462f7df2e56Smrg    CARD32 twocolor[3];
1463f7df2e56Smrg    int rc, ncolor;
146405b261ecSmrg
1465f7df2e56Smrg    REQUEST_SIZE_MATCH(xRenderCreateCursorReq);
146605b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
1467f7df2e56Smrg
1468f7df2e56Smrg    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
146905b261ecSmrg    if (!pSrc->pDrawable)
147005b261ecSmrg        return BadDrawable;
147105b261ecSmrg    pScreen = pSrc->pDrawable->pScreen;
147205b261ecSmrg    width = pSrc->pDrawable->width;
147305b261ecSmrg    height = pSrc->pDrawable->height;
1474f7df2e56Smrg    if (height && width > UINT32_MAX / (height * sizeof(CARD32)))
1475f7df2e56Smrg        return BadAlloc;
1476f7df2e56Smrg    if (stuff->x > width || stuff->y > height)
1477f7df2e56Smrg        return BadMatch;
1478f7df2e56Smrg    argbbits = malloc(width * height * sizeof(CARD32));
147905b261ecSmrg    if (!argbbits)
1480f7df2e56Smrg        return BadAlloc;
1481f7df2e56Smrg
148205b261ecSmrg    stride = BitmapBytePad(width);
1483f7df2e56Smrg    nbytes_mono = stride * height;
14846747b715Smrg    srcbits = calloc(1, nbytes_mono);
1485f7df2e56Smrg    if (!srcbits) {
1486f7df2e56Smrg        free(argbbits);
1487f7df2e56Smrg        return BadAlloc;
148805b261ecSmrg    }
14896747b715Smrg    mskbits = calloc(1, nbytes_mono);
1490f7df2e56Smrg    if (!mskbits) {
1491f7df2e56Smrg        free(argbbits);
1492f7df2e56Smrg        free(srcbits);
1493f7df2e56Smrg        return BadAlloc;
1494f7df2e56Smrg    }
1495f7df2e56Smrg
1496f7df2e56Smrg    if (pSrc->format == PICT_a8r8g8b8) {
1497f7df2e56Smrg        (*pScreen->GetImage) (pSrc->pDrawable,
1498f7df2e56Smrg                              0, 0, width, height, ZPixmap,
1499f7df2e56Smrg                              0xffffffff, (void *) argbbits);
1500f7df2e56Smrg    }
1501f7df2e56Smrg    else {
1502f7df2e56Smrg        PixmapPtr pPixmap;
1503f7df2e56Smrg        PicturePtr pPicture;
1504f7df2e56Smrg        PictFormatPtr pFormat;
1505f7df2e56Smrg        int error;
1506f7df2e56Smrg
1507f7df2e56Smrg        pFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8);
1508f7df2e56Smrg        if (!pFormat) {
1509f7df2e56Smrg            free(argbbits);
1510f7df2e56Smrg            free(srcbits);
1511f7df2e56Smrg            free(mskbits);
1512f7df2e56Smrg            return BadImplementation;
1513f7df2e56Smrg        }
1514f7df2e56Smrg        pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32,
1515f7df2e56Smrg                                            CREATE_PIXMAP_USAGE_SCRATCH);
1516f7df2e56Smrg        if (!pPixmap) {
1517f7df2e56Smrg            free(argbbits);
1518f7df2e56Smrg            free(srcbits);
1519f7df2e56Smrg            free(mskbits);
1520f7df2e56Smrg            return BadAlloc;
1521f7df2e56Smrg        }
1522f7df2e56Smrg        pPicture = CreatePicture(0, &pPixmap->drawable, pFormat, 0, 0,
1523f7df2e56Smrg                                 client, &error);
1524f7df2e56Smrg        if (!pPicture) {
1525f7df2e56Smrg            free(argbbits);
1526f7df2e56Smrg            free(srcbits);
1527f7df2e56Smrg            free(mskbits);
1528f7df2e56Smrg            return error;
1529f7df2e56Smrg        }
1530f7df2e56Smrg        (*pScreen->DestroyPixmap) (pPixmap);
1531f7df2e56Smrg        CompositePicture(PictOpSrc,
1532f7df2e56Smrg                         pSrc, 0, pPicture, 0, 0, 0, 0, 0, 0, width, height);
1533f7df2e56Smrg        (*pScreen->GetImage) (pPicture->pDrawable,
1534f7df2e56Smrg                              0, 0, width, height, ZPixmap,
1535f7df2e56Smrg                              0xffffffff, (void *) argbbits);
1536f7df2e56Smrg        FreePicture(pPicture, 0);
153705b261ecSmrg    }
153805b261ecSmrg    /*
1539f7df2e56Smrg     * Check whether the cursor can be directly supported by
154005b261ecSmrg     * the core cursor code
154105b261ecSmrg     */
154205b261ecSmrg    ncolor = 0;
154305b261ecSmrg    argb = argbbits;
1544f7df2e56Smrg    for (y = 0; ncolor <= 2 && y < height; y++) {
1545f7df2e56Smrg        for (x = 0; ncolor <= 2 && x < width; x++) {
1546f7df2e56Smrg            CARD32 p = *argb++;
1547f7df2e56Smrg            CARD32 a = (p >> 24);
1548f7df2e56Smrg
1549f7df2e56Smrg            if (a == 0)         /* transparent */
1550f7df2e56Smrg                continue;
1551f7df2e56Smrg            if (a == 0xff) {    /* opaque */
1552f7df2e56Smrg                int n;
1553f7df2e56Smrg
1554f7df2e56Smrg                for (n = 0; n < ncolor; n++)
1555f7df2e56Smrg                    if (p == twocolor[n])
1556f7df2e56Smrg                        break;
1557f7df2e56Smrg                if (n == ncolor)
1558f7df2e56Smrg                    twocolor[ncolor++] = p;
1559f7df2e56Smrg            }
1560f7df2e56Smrg            else
1561f7df2e56Smrg                ncolor = 3;
1562f7df2e56Smrg        }
1563f7df2e56Smrg    }
1564f7df2e56Smrg
156505b261ecSmrg    /*
156605b261ecSmrg     * Convert argb image to two plane cursor
156705b261ecSmrg     */
156805b261ecSmrg    srcline = srcbits;
156905b261ecSmrg    mskline = mskbits;
157005b261ecSmrg    argb = argbbits;
1571f7df2e56Smrg    for (y = 0; y < height; y++) {
1572f7df2e56Smrg        for (x = 0; x < width; x++) {
1573f7df2e56Smrg            CARD32 p = *argb++;
1574f7df2e56Smrg
1575f7df2e56Smrg            if (ncolor <= 2) {
1576f7df2e56Smrg                CARD32 a = ((p >> 24));
1577f7df2e56Smrg
1578f7df2e56Smrg                RenderSetBit(mskline, x, a != 0);
1579f7df2e56Smrg                RenderSetBit(srcline, x, a != 0 && p == twocolor[0]);
1580f7df2e56Smrg            }
1581f7df2e56Smrg            else {
1582f7df2e56Smrg                CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255;
1583f7df2e56Smrg                CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
1584f7df2e56Smrg                CARD32 d =
1585f7df2e56Smrg                    orderedDither[y & (DITHER_DIM - 1)][x & (DITHER_DIM - 1)];
1586f7df2e56Smrg                /* Set mask from dithered alpha value */
1587f7df2e56Smrg                RenderSetBit(mskline, x, a > d);
1588f7df2e56Smrg                /* Set src from dithered intensity value */
1589f7df2e56Smrg                RenderSetBit(srcline, x, a > d && i <= d);
1590f7df2e56Smrg            }
1591f7df2e56Smrg        }
1592f7df2e56Smrg        srcline += stride;
1593f7df2e56Smrg        mskline += stride;
159405b261ecSmrg    }
159505b261ecSmrg    /*
159605b261ecSmrg     * Dither to white and black if the cursor has more than two colors
159705b261ecSmrg     */
1598f7df2e56Smrg    if (ncolor > 2) {
1599f7df2e56Smrg        twocolor[0] = 0xff000000;
1600f7df2e56Smrg        twocolor[1] = 0xffffffff;
160105b261ecSmrg    }
1602f7df2e56Smrg    else {
1603f7df2e56Smrg        free(argbbits);
1604f7df2e56Smrg        argbbits = 0;
160505b261ecSmrg    }
1606f7df2e56Smrg
160705b261ecSmrg#define GetByte(p,s)	(((p) >> (s)) & 0xff)
160805b261ecSmrg#define GetColor(p,s)	(GetByte(p,s) | (GetByte(p,s) << 8))
1609f7df2e56Smrg
161005b261ecSmrg    cm.width = width;
161105b261ecSmrg    cm.height = height;
161205b261ecSmrg    cm.xhot = stuff->x;
161305b261ecSmrg    cm.yhot = stuff->y;
16144642e01fSmrg    rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm,
1615f7df2e56Smrg                         GetColor(twocolor[0], 16),
1616f7df2e56Smrg                         GetColor(twocolor[0], 8),
1617f7df2e56Smrg                         GetColor(twocolor[0], 0),
1618f7df2e56Smrg                         GetColor(twocolor[1], 16),
1619f7df2e56Smrg                         GetColor(twocolor[1], 8),
1620f7df2e56Smrg                         GetColor(twocolor[1], 0),
1621f7df2e56Smrg                         &pCursor, client, stuff->cid);
16224642e01fSmrg    if (rc != Success)
1623f7df2e56Smrg        goto bail;
1624f7df2e56Smrg    if (!AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) {
1625f7df2e56Smrg        rc = BadAlloc;
1626f7df2e56Smrg        goto bail;
1627f7df2e56Smrg    }
16284642e01fSmrg
16296747b715Smrg    return Success;
1630f7df2e56Smrg bail:
1631f7df2e56Smrg    free(srcbits);
1632f7df2e56Smrg    free(mskbits);
1633f7df2e56Smrg    return rc;
163405b261ecSmrg}
163505b261ecSmrg
163605b261ecSmrgstatic int
1637f7df2e56SmrgProcRenderSetPictureTransform(ClientPtr client)
163805b261ecSmrg{
163905b261ecSmrg    REQUEST(xRenderSetPictureTransformReq);
1640f7df2e56Smrg    PicturePtr pPicture;
164105b261ecSmrg
164205b261ecSmrg    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
1643f7df2e56Smrg    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
1644f7df2e56Smrg    return SetPictureTransform(pPicture, (PictTransform *) &stuff->transform);
164505b261ecSmrg}
164605b261ecSmrg
164705b261ecSmrgstatic int
1648f7df2e56SmrgProcRenderQueryFilters(ClientPtr client)
164905b261ecSmrg{
1650f7df2e56Smrg    REQUEST(xRenderQueryFiltersReq);
1651f7df2e56Smrg    DrawablePtr pDrawable;
1652f7df2e56Smrg    xRenderQueryFiltersReply *reply;
1653f7df2e56Smrg    int nbytesName;
1654f7df2e56Smrg    int nnames;
1655f7df2e56Smrg    ScreenPtr pScreen;
1656f7df2e56Smrg    PictureScreenPtr ps;
1657f7df2e56Smrg    int i, j, len, total_bytes, rc;
1658f7df2e56Smrg    INT16 *aliases;
1659f7df2e56Smrg    char *names;
166005b261ecSmrg
166105b261ecSmrg    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
166205b261ecSmrg    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
1663f7df2e56Smrg                           DixGetAttrAccess);
166405b261ecSmrg    if (rc != Success)
1665f7df2e56Smrg        return rc;
1666f7df2e56Smrg
166705b261ecSmrg    pScreen = pDrawable->pScreen;
166805b261ecSmrg    nbytesName = 0;
166905b261ecSmrg    nnames = 0;
167005b261ecSmrg    ps = GetPictureScreenIfSet(pScreen);
1671f7df2e56Smrg    if (ps) {
1672f7df2e56Smrg        for (i = 0; i < ps->nfilters; i++)
1673f7df2e56Smrg            nbytesName += 1 + strlen(ps->filters[i].name);
1674f7df2e56Smrg        for (i = 0; i < ps->nfilterAliases; i++)
1675f7df2e56Smrg            nbytesName += 1 + strlen(ps->filterAliases[i].alias);
1676f7df2e56Smrg        nnames = ps->nfilters + ps->nfilterAliases;
167705b261ecSmrg    }
16786747b715Smrg    len = ((nnames + 1) >> 1) + bytes_to_int32(nbytesName);
1679f7df2e56Smrg    total_bytes = sizeof(xRenderQueryFiltersReply) + (len << 2);
1680f7df2e56Smrg    reply = (xRenderQueryFiltersReply *) calloc(1, total_bytes);
168105b261ecSmrg    if (!reply)
1682f7df2e56Smrg        return BadAlloc;
168305b261ecSmrg    aliases = (INT16 *) (reply + 1);
168405b261ecSmrg    names = (char *) (aliases + ((nnames + 1) & ~1));
1685f7df2e56Smrg
168605b261ecSmrg    reply->type = X_Reply;
168705b261ecSmrg    reply->sequenceNumber = client->sequence;
168805b261ecSmrg    reply->length = len;
168905b261ecSmrg    reply->numAliases = nnames;
169005b261ecSmrg    reply->numFilters = nnames;
1691f7df2e56Smrg    if (ps) {
1692f7df2e56Smrg
1693f7df2e56Smrg        /* fill in alias values */
1694f7df2e56Smrg        for (i = 0; i < ps->nfilters; i++)
1695f7df2e56Smrg            aliases[i] = FilterAliasNone;
1696f7df2e56Smrg        for (i = 0; i < ps->nfilterAliases; i++) {
1697f7df2e56Smrg            for (j = 0; j < ps->nfilters; j++)
1698f7df2e56Smrg                if (ps->filterAliases[i].filter_id == ps->filters[j].id)
1699f7df2e56Smrg                    break;
1700f7df2e56Smrg            if (j == ps->nfilters) {
1701f7df2e56Smrg                for (j = 0; j < ps->nfilterAliases; j++)
1702f7df2e56Smrg                    if (ps->filterAliases[i].filter_id ==
1703f7df2e56Smrg                        ps->filterAliases[j].alias_id) {
1704f7df2e56Smrg                        break;
1705f7df2e56Smrg                    }
1706f7df2e56Smrg                if (j == ps->nfilterAliases)
1707f7df2e56Smrg                    j = FilterAliasNone;
1708f7df2e56Smrg                else
1709f7df2e56Smrg                    j = j + ps->nfilters;
1710f7df2e56Smrg            }
1711f7df2e56Smrg            aliases[i + ps->nfilters] = j;
1712f7df2e56Smrg        }
1713f7df2e56Smrg
1714f7df2e56Smrg        /* fill in filter names */
1715f7df2e56Smrg        for (i = 0; i < ps->nfilters; i++) {
1716f7df2e56Smrg            j = strlen(ps->filters[i].name);
1717f7df2e56Smrg            *names++ = j;
1718f7df2e56Smrg            memcpy(names, ps->filters[i].name, j);
1719f7df2e56Smrg            names += j;
1720f7df2e56Smrg        }
1721f7df2e56Smrg
1722f7df2e56Smrg        /* fill in filter alias names */
1723f7df2e56Smrg        for (i = 0; i < ps->nfilterAliases; i++) {
1724f7df2e56Smrg            j = strlen(ps->filterAliases[i].alias);
1725f7df2e56Smrg            *names++ = j;
1726f7df2e56Smrg            memcpy(names, ps->filterAliases[i].alias, j);
1727f7df2e56Smrg            names += j;
1728f7df2e56Smrg        }
1729f7df2e56Smrg    }
1730f7df2e56Smrg
1731f7df2e56Smrg    if (client->swapped) {
1732f7df2e56Smrg        for (i = 0; i < reply->numAliases; i++) {
1733f7df2e56Smrg            swaps(&aliases[i]);
1734f7df2e56Smrg        }
1735f7df2e56Smrg        swaps(&reply->sequenceNumber);
1736f7df2e56Smrg        swapl(&reply->length);
1737f7df2e56Smrg        swapl(&reply->numAliases);
1738f7df2e56Smrg        swapl(&reply->numFilters);
1739f7df2e56Smrg    }
1740f7df2e56Smrg    WriteToClient(client, total_bytes, reply);
17416747b715Smrg    free(reply);
1742f7df2e56Smrg
17436747b715Smrg    return Success;
174405b261ecSmrg}
174505b261ecSmrg
174605b261ecSmrgstatic int
1747f7df2e56SmrgProcRenderSetPictureFilter(ClientPtr client)
174805b261ecSmrg{
1749f7df2e56Smrg    REQUEST(xRenderSetPictureFilterReq);
1750f7df2e56Smrg    PicturePtr pPicture;
1751f7df2e56Smrg    int result;
1752f7df2e56Smrg    xFixed *params;
1753f7df2e56Smrg    int nparams;
1754f7df2e56Smrg    char *name;
1755f7df2e56Smrg
1756f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
1757f7df2e56Smrg    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
175805b261ecSmrg    name = (char *) (stuff + 1);
17596747b715Smrg    params = (xFixed *) (name + pad_to_int32(stuff->nbytes));
176005b261ecSmrg    nparams = ((xFixed *) stuff + client->req_len) - params;
17616e78d31fSmrg    if (nparams < 0)
17626e78d31fSmrg	return BadLength;
17636e78d31fSmrg
1764f7df2e56Smrg    result = SetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
176505b261ecSmrg    return result;
176605b261ecSmrg}
176705b261ecSmrg
176805b261ecSmrgstatic int
1769f7df2e56SmrgProcRenderCreateAnimCursor(ClientPtr client)
177005b261ecSmrg{
177105b261ecSmrg    REQUEST(xRenderCreateAnimCursorReq);
1772f7df2e56Smrg    CursorPtr *cursors;
1773f7df2e56Smrg    CARD32 *deltas;
1774f7df2e56Smrg    CursorPtr pCursor;
1775f7df2e56Smrg    int ncursor;
1776f7df2e56Smrg    xAnimCursorElt *elt;
1777f7df2e56Smrg    int i;
1778f7df2e56Smrg    int ret;
177905b261ecSmrg
178005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
178105b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
178205b261ecSmrg    if (client->req_len & 1)
1783f7df2e56Smrg        return BadLength;
1784f7df2e56Smrg    ncursor =
1785f7df2e56Smrg        (client->req_len -
1786f7df2e56Smrg         (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1;
1787f7df2e56Smrg    cursors = xallocarray(ncursor, sizeof(CursorPtr) + sizeof(CARD32));
178805b261ecSmrg    if (!cursors)
1789f7df2e56Smrg        return BadAlloc;
179005b261ecSmrg    deltas = (CARD32 *) (cursors + ncursor);
179105b261ecSmrg    elt = (xAnimCursorElt *) (stuff + 1);
1792f7df2e56Smrg    for (i = 0; i < ncursor; i++) {
1793f7df2e56Smrg        ret = dixLookupResourceByType((void **) (cursors + i), elt->cursor,
1794f7df2e56Smrg                                      RT_CURSOR, client, DixReadAccess);
1795f7df2e56Smrg        if (ret != Success) {
1796f7df2e56Smrg            free(cursors);
1797f7df2e56Smrg            return ret;
1798f7df2e56Smrg        }
1799f7df2e56Smrg        deltas[i] = elt->delay;
1800f7df2e56Smrg        elt++;
1801f7df2e56Smrg    }
1802f7df2e56Smrg    ret = AnimCursorCreate(cursors, deltas, ncursor, &pCursor, client,
1803f7df2e56Smrg                           stuff->cid);
18046747b715Smrg    free(cursors);
180505b261ecSmrg    if (ret != Success)
1806f7df2e56Smrg        return ret;
1807f7df2e56Smrg
1808f7df2e56Smrg    if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor))
1809f7df2e56Smrg        return Success;
181005b261ecSmrg    return BadAlloc;
181105b261ecSmrg}
181205b261ecSmrg
181305b261ecSmrgstatic int
1814f7df2e56SmrgProcRenderAddTraps(ClientPtr client)
181505b261ecSmrg{
1816f7df2e56Smrg    int ntraps;
1817f7df2e56Smrg    PicturePtr pPicture;
1818f7df2e56Smrg
181905b261ecSmrg    REQUEST(xRenderAddTrapsReq);
182005b261ecSmrg
182105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
1822f7df2e56Smrg    VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess);
182305b261ecSmrg    if (!pPicture->pDrawable)
182405b261ecSmrg        return BadDrawable;
1825f7df2e56Smrg    ntraps = (client->req_len << 2) - sizeof(xRenderAddTrapsReq);
1826f7df2e56Smrg    if (ntraps % sizeof(xTrap))
1827f7df2e56Smrg        return BadLength;
1828f7df2e56Smrg    ntraps /= sizeof(xTrap);
182905b261ecSmrg    if (ntraps)
1830f7df2e56Smrg        AddTraps(pPicture,
1831f7df2e56Smrg                 stuff->xOff, stuff->yOff, ntraps, (xTrap *) &stuff[1]);
18326747b715Smrg    return Success;
183305b261ecSmrg}
183405b261ecSmrg
1835f7df2e56Smrgstatic int
1836f7df2e56SmrgProcRenderCreateSolidFill(ClientPtr client)
183705b261ecSmrg{
1838f7df2e56Smrg    PicturePtr pPicture;
1839f7df2e56Smrg    int error = 0;
1840f7df2e56Smrg
184105b261ecSmrg    REQUEST(xRenderCreateSolidFillReq);
184205b261ecSmrg
184305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
184405b261ecSmrg
184505b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
184605b261ecSmrg
184705b261ecSmrg    pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
184805b261ecSmrg    if (!pPicture)
1849f7df2e56Smrg        return error;
18504642e01fSmrg    /* security creation/labeling check */
18514642e01fSmrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1852f7df2e56Smrg                     pPicture, RT_NONE, NULL, DixCreateAccess);
18534642e01fSmrg    if (error != Success)
1854f7df2e56Smrg        return error;
1855f7df2e56Smrg    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
1856f7df2e56Smrg        return BadAlloc;
185705b261ecSmrg    return Success;
185805b261ecSmrg}
185905b261ecSmrg
1860f7df2e56Smrgstatic int
1861f7df2e56SmrgProcRenderCreateLinearGradient(ClientPtr client)
186205b261ecSmrg{
1863f7df2e56Smrg    PicturePtr pPicture;
1864f7df2e56Smrg    int len;
1865f7df2e56Smrg    int error = 0;
1866f7df2e56Smrg    xFixed *stops;
1867f7df2e56Smrg    xRenderColor *colors;
1868f7df2e56Smrg
186905b261ecSmrg    REQUEST(xRenderCreateLinearGradientReq);
187005b261ecSmrg
187105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
187205b261ecSmrg
187305b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
187405b261ecSmrg
187505b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
1876f7df2e56Smrg    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
1877f7df2e56Smrg        return BadLength;
1878f7df2e56Smrg    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
187905b261ecSmrg        return BadLength;
188005b261ecSmrg
1881f7df2e56Smrg    stops = (xFixed *) (stuff + 1);
1882f7df2e56Smrg    colors = (xRenderColor *) (stops + stuff->nStops);
188305b261ecSmrg
1884f7df2e56Smrg    pPicture = CreateLinearGradientPicture(stuff->pid, &stuff->p1, &stuff->p2,
1885f7df2e56Smrg                                           stuff->nStops, stops, colors,
1886f7df2e56Smrg                                           &error);
188705b261ecSmrg    if (!pPicture)
1888f7df2e56Smrg        return error;
18894642e01fSmrg    /* security creation/labeling check */
18904642e01fSmrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1891f7df2e56Smrg                     pPicture, RT_NONE, NULL, DixCreateAccess);
18924642e01fSmrg    if (error != Success)
1893f7df2e56Smrg        return error;
1894f7df2e56Smrg    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
1895f7df2e56Smrg        return BadAlloc;
189605b261ecSmrg    return Success;
189705b261ecSmrg}
189805b261ecSmrg
1899f7df2e56Smrgstatic int
1900f7df2e56SmrgProcRenderCreateRadialGradient(ClientPtr client)
190105b261ecSmrg{
1902f7df2e56Smrg    PicturePtr pPicture;
1903f7df2e56Smrg    int len;
1904f7df2e56Smrg    int error = 0;
1905f7df2e56Smrg    xFixed *stops;
1906f7df2e56Smrg    xRenderColor *colors;
1907f7df2e56Smrg
190805b261ecSmrg    REQUEST(xRenderCreateRadialGradientReq);
190905b261ecSmrg
191005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
191105b261ecSmrg
191205b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
191305b261ecSmrg
191405b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
19157e31ba66Smrg    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
19167e31ba66Smrg        return BadLength;
1917f7df2e56Smrg    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
191805b261ecSmrg        return BadLength;
191905b261ecSmrg
1920f7df2e56Smrg    stops = (xFixed *) (stuff + 1);
1921f7df2e56Smrg    colors = (xRenderColor *) (stops + stuff->nStops);
192205b261ecSmrg
1923f7df2e56Smrg    pPicture =
1924f7df2e56Smrg        CreateRadialGradientPicture(stuff->pid, &stuff->inner, &stuff->outer,
1925f7df2e56Smrg                                    stuff->inner_radius, stuff->outer_radius,
1926f7df2e56Smrg                                    stuff->nStops, stops, colors, &error);
192705b261ecSmrg    if (!pPicture)
1928f7df2e56Smrg        return error;
19294642e01fSmrg    /* security creation/labeling check */
19304642e01fSmrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1931f7df2e56Smrg                     pPicture, RT_NONE, NULL, DixCreateAccess);
19324642e01fSmrg    if (error != Success)
1933f7df2e56Smrg        return error;
1934f7df2e56Smrg    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
1935f7df2e56Smrg        return BadAlloc;
193605b261ecSmrg    return Success;
193705b261ecSmrg}
193805b261ecSmrg
1939f7df2e56Smrgstatic int
1940f7df2e56SmrgProcRenderCreateConicalGradient(ClientPtr client)
194105b261ecSmrg{
1942f7df2e56Smrg    PicturePtr pPicture;
1943f7df2e56Smrg    int len;
1944f7df2e56Smrg    int error = 0;
1945f7df2e56Smrg    xFixed *stops;
1946f7df2e56Smrg    xRenderColor *colors;
1947f7df2e56Smrg
194805b261ecSmrg    REQUEST(xRenderCreateConicalGradientReq);
194905b261ecSmrg
195005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
195105b261ecSmrg
195205b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
195305b261ecSmrg
195405b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
19557e31ba66Smrg    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
19567e31ba66Smrg        return BadLength;
1957f7df2e56Smrg    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
195805b261ecSmrg        return BadLength;
195905b261ecSmrg
1960f7df2e56Smrg    stops = (xFixed *) (stuff + 1);
1961f7df2e56Smrg    colors = (xRenderColor *) (stops + stuff->nStops);
196205b261ecSmrg
1963f7df2e56Smrg    pPicture =
1964f7df2e56Smrg        CreateConicalGradientPicture(stuff->pid, &stuff->center, stuff->angle,
1965f7df2e56Smrg                                     stuff->nStops, stops, colors, &error);
196605b261ecSmrg    if (!pPicture)
1967f7df2e56Smrg        return error;
19684642e01fSmrg    /* security creation/labeling check */
19694642e01fSmrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1970f7df2e56Smrg                     pPicture, RT_NONE, NULL, DixCreateAccess);
19714642e01fSmrg    if (error != Success)
1972f7df2e56Smrg        return error;
1973f7df2e56Smrg    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
1974f7df2e56Smrg        return BadAlloc;
197505b261ecSmrg    return Success;
197605b261ecSmrg}
197705b261ecSmrg
197805b261ecSmrgstatic int
1979f7df2e56SmrgProcRenderDispatch(ClientPtr client)
198005b261ecSmrg{
198105b261ecSmrg    REQUEST(xReq);
1982f7df2e56Smrg
198305b261ecSmrg    if (stuff->data < RenderNumberRequests)
1984f7df2e56Smrg        return (*ProcRenderVector[stuff->data]) (client);
198505b261ecSmrg    else
1986f7df2e56Smrg        return BadRequest;
198705b261ecSmrg}
198805b261ecSmrg
19897e31ba66Smrgstatic int _X_COLD
1990f7df2e56SmrgSProcRenderQueryVersion(ClientPtr client)
199105b261ecSmrg{
199205b261ecSmrg    REQUEST(xRenderQueryVersionReq);
19930b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
1994f7df2e56Smrg    swaps(&stuff->length);
1995f7df2e56Smrg    swapl(&stuff->majorVersion);
1996f7df2e56Smrg    swapl(&stuff->minorVersion);
1997f7df2e56Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
199805b261ecSmrg}
199905b261ecSmrg
20007e31ba66Smrgstatic int _X_COLD
2001f7df2e56SmrgSProcRenderQueryPictFormats(ClientPtr client)
200205b261ecSmrg{
200305b261ecSmrg    REQUEST(xRenderQueryPictFormatsReq);
20040b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
2005f7df2e56Smrg    swaps(&stuff->length);
200605b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
200705b261ecSmrg}
200805b261ecSmrg
20097e31ba66Smrgstatic int _X_COLD
2010f7df2e56SmrgSProcRenderQueryPictIndexValues(ClientPtr client)
201105b261ecSmrg{
201205b261ecSmrg    REQUEST(xRenderQueryPictIndexValuesReq);
20130b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
2014f7df2e56Smrg    swaps(&stuff->length);
2015f7df2e56Smrg    swapl(&stuff->format);
201605b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
201705b261ecSmrg}
201805b261ecSmrg
20197e31ba66Smrgstatic int _X_COLD
2020f7df2e56SmrgSProcRenderQueryDithers(ClientPtr client)
202105b261ecSmrg{
202205b261ecSmrg    return BadImplementation;
202305b261ecSmrg}
202405b261ecSmrg
20257e31ba66Smrgstatic int _X_COLD
2026f7df2e56SmrgSProcRenderCreatePicture(ClientPtr client)
202705b261ecSmrg{
202805b261ecSmrg    REQUEST(xRenderCreatePictureReq);
20290b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2030f7df2e56Smrg    swaps(&stuff->length);
2031f7df2e56Smrg    swapl(&stuff->pid);
2032f7df2e56Smrg    swapl(&stuff->drawable);
2033f7df2e56Smrg    swapl(&stuff->format);
2034f7df2e56Smrg    swapl(&stuff->mask);
203505b261ecSmrg    SwapRestL(stuff);
203605b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
203705b261ecSmrg}
203805b261ecSmrg
20397e31ba66Smrgstatic int _X_COLD
2040f7df2e56SmrgSProcRenderChangePicture(ClientPtr client)
204105b261ecSmrg{
204205b261ecSmrg    REQUEST(xRenderChangePictureReq);
20430b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
2044f7df2e56Smrg    swaps(&stuff->length);
2045f7df2e56Smrg    swapl(&stuff->picture);
2046f7df2e56Smrg    swapl(&stuff->mask);
204705b261ecSmrg    SwapRestL(stuff);
204805b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
204905b261ecSmrg}
205005b261ecSmrg
20517e31ba66Smrgstatic int _X_COLD
2052f7df2e56SmrgSProcRenderSetPictureClipRectangles(ClientPtr client)
205305b261ecSmrg{
205405b261ecSmrg    REQUEST(xRenderSetPictureClipRectanglesReq);
20550b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
2056f7df2e56Smrg    swaps(&stuff->length);
2057f7df2e56Smrg    swapl(&stuff->picture);
2058f7df2e56Smrg    swaps(&stuff->xOrigin);
2059f7df2e56Smrg    swaps(&stuff->yOrigin);
206005b261ecSmrg    SwapRestS(stuff);
206105b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
206205b261ecSmrg}
206305b261ecSmrg
20647e31ba66Smrgstatic int _X_COLD
2065f7df2e56SmrgSProcRenderFreePicture(ClientPtr client)
206605b261ecSmrg{
206705b261ecSmrg    REQUEST(xRenderFreePictureReq);
20680b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
2069f7df2e56Smrg    swaps(&stuff->length);
2070f7df2e56Smrg    swapl(&stuff->picture);
207105b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
207205b261ecSmrg}
207305b261ecSmrg
20747e31ba66Smrgstatic int _X_COLD
2075f7df2e56SmrgSProcRenderComposite(ClientPtr client)
207605b261ecSmrg{
207705b261ecSmrg    REQUEST(xRenderCompositeReq);
20780b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
2079f7df2e56Smrg    swaps(&stuff->length);
2080f7df2e56Smrg    swapl(&stuff->src);
2081f7df2e56Smrg    swapl(&stuff->mask);
2082f7df2e56Smrg    swapl(&stuff->dst);
2083f7df2e56Smrg    swaps(&stuff->xSrc);
2084f7df2e56Smrg    swaps(&stuff->ySrc);
2085f7df2e56Smrg    swaps(&stuff->xMask);
2086f7df2e56Smrg    swaps(&stuff->yMask);
2087f7df2e56Smrg    swaps(&stuff->xDst);
2088f7df2e56Smrg    swaps(&stuff->yDst);
2089f7df2e56Smrg    swaps(&stuff->width);
2090f7df2e56Smrg    swaps(&stuff->height);
209105b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
209205b261ecSmrg}
209305b261ecSmrg
20947e31ba66Smrgstatic int _X_COLD
2095f7df2e56SmrgSProcRenderScale(ClientPtr client)
209605b261ecSmrg{
2097f7df2e56Smrg    return BadImplementation;
209805b261ecSmrg}
209905b261ecSmrg
21007e31ba66Smrgstatic int _X_COLD
2101f7df2e56SmrgSProcRenderTrapezoids(ClientPtr client)
210205b261ecSmrg{
210305b261ecSmrg    REQUEST(xRenderTrapezoidsReq);
210405b261ecSmrg
210505b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
2106f7df2e56Smrg    swaps(&stuff->length);
2107f7df2e56Smrg    swapl(&stuff->src);
2108f7df2e56Smrg    swapl(&stuff->dst);
2109f7df2e56Smrg    swapl(&stuff->maskFormat);
2110f7df2e56Smrg    swaps(&stuff->xSrc);
2111f7df2e56Smrg    swaps(&stuff->ySrc);
211205b261ecSmrg    SwapRestL(stuff);
211305b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
211405b261ecSmrg}
211505b261ecSmrg
21167e31ba66Smrgstatic int _X_COLD
2117f7df2e56SmrgSProcRenderTriangles(ClientPtr client)
211805b261ecSmrg{
211905b261ecSmrg    REQUEST(xRenderTrianglesReq);
212005b261ecSmrg
212105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
2122f7df2e56Smrg    swaps(&stuff->length);
2123f7df2e56Smrg    swapl(&stuff->src);
2124f7df2e56Smrg    swapl(&stuff->dst);
2125f7df2e56Smrg    swapl(&stuff->maskFormat);
2126f7df2e56Smrg    swaps(&stuff->xSrc);
2127f7df2e56Smrg    swaps(&stuff->ySrc);
212805b261ecSmrg    SwapRestL(stuff);
212905b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
213005b261ecSmrg}
213105b261ecSmrg
21327e31ba66Smrgstatic int _X_COLD
2133f7df2e56SmrgSProcRenderTriStrip(ClientPtr client)
213405b261ecSmrg{
213505b261ecSmrg    REQUEST(xRenderTriStripReq);
213605b261ecSmrg
213705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
2138f7df2e56Smrg    swaps(&stuff->length);
2139f7df2e56Smrg    swapl(&stuff->src);
2140f7df2e56Smrg    swapl(&stuff->dst);
2141f7df2e56Smrg    swapl(&stuff->maskFormat);
2142f7df2e56Smrg    swaps(&stuff->xSrc);
2143f7df2e56Smrg    swaps(&stuff->ySrc);
214405b261ecSmrg    SwapRestL(stuff);
214505b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
214605b261ecSmrg}
214705b261ecSmrg
21487e31ba66Smrgstatic int _X_COLD
2149f7df2e56SmrgSProcRenderTriFan(ClientPtr client)
215005b261ecSmrg{
215105b261ecSmrg    REQUEST(xRenderTriFanReq);
215205b261ecSmrg
215305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
2154f7df2e56Smrg    swaps(&stuff->length);
2155f7df2e56Smrg    swapl(&stuff->src);
2156f7df2e56Smrg    swapl(&stuff->dst);
2157f7df2e56Smrg    swapl(&stuff->maskFormat);
2158f7df2e56Smrg    swaps(&stuff->xSrc);
2159f7df2e56Smrg    swaps(&stuff->ySrc);
216005b261ecSmrg    SwapRestL(stuff);
216105b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
216205b261ecSmrg}
216305b261ecSmrg
21647e31ba66Smrgstatic int _X_COLD
2165f7df2e56SmrgSProcRenderColorTrapezoids(ClientPtr client)
216605b261ecSmrg{
216705b261ecSmrg    return BadImplementation;
216805b261ecSmrg}
216905b261ecSmrg
21707e31ba66Smrgstatic int _X_COLD
2171f7df2e56SmrgSProcRenderColorTriangles(ClientPtr client)
217205b261ecSmrg{
217305b261ecSmrg    return BadImplementation;
217405b261ecSmrg}
217505b261ecSmrg
21767e31ba66Smrgstatic int _X_COLD
2177f7df2e56SmrgSProcRenderTransform(ClientPtr client)
217805b261ecSmrg{
217905b261ecSmrg    return BadImplementation;
218005b261ecSmrg}
218105b261ecSmrg
21827e31ba66Smrgstatic int _X_COLD
2183f7df2e56SmrgSProcRenderCreateGlyphSet(ClientPtr client)
218405b261ecSmrg{
218505b261ecSmrg    REQUEST(xRenderCreateGlyphSetReq);
21860b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
2187f7df2e56Smrg    swaps(&stuff->length);
2188f7df2e56Smrg    swapl(&stuff->gsid);
2189f7df2e56Smrg    swapl(&stuff->format);
219005b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
219105b261ecSmrg}
219205b261ecSmrg
21937e31ba66Smrgstatic int _X_COLD
2194f7df2e56SmrgSProcRenderReferenceGlyphSet(ClientPtr client)
219505b261ecSmrg{
219605b261ecSmrg    REQUEST(xRenderReferenceGlyphSetReq);
21970b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
2198f7df2e56Smrg    swaps(&stuff->length);
2199f7df2e56Smrg    swapl(&stuff->gsid);
2200f7df2e56Smrg    swapl(&stuff->existing);
2201f7df2e56Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
220205b261ecSmrg}
220305b261ecSmrg
22047e31ba66Smrgstatic int _X_COLD
2205f7df2e56SmrgSProcRenderFreeGlyphSet(ClientPtr client)
220605b261ecSmrg{
220705b261ecSmrg    REQUEST(xRenderFreeGlyphSetReq);
22080b0d8713Smrg    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
2209f7df2e56Smrg    swaps(&stuff->length);
2210f7df2e56Smrg    swapl(&stuff->glyphset);
221105b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
221205b261ecSmrg}
221305b261ecSmrg
22147e31ba66Smrgstatic int _X_COLD
2215f7df2e56SmrgSProcRenderAddGlyphs(ClientPtr client)
221605b261ecSmrg{
221705b261ecSmrg    register int i;
2218f7df2e56Smrg    CARD32 *gids;
2219f7df2e56Smrg    void *end;
222005b261ecSmrg    xGlyphInfo *gi;
2221f7df2e56Smrg
222205b261ecSmrg    REQUEST(xRenderAddGlyphsReq);
22230b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
2224f7df2e56Smrg    swaps(&stuff->length);
2225f7df2e56Smrg    swapl(&stuff->glyphset);
2226f7df2e56Smrg    swapl(&stuff->nglyphs);
222705b261ecSmrg    if (stuff->nglyphs & 0xe0000000)
2228f7df2e56Smrg        return BadLength;
222905b261ecSmrg    end = (CARD8 *) stuff + (client->req_len << 2);
223005b261ecSmrg    gids = (CARD32 *) (stuff + 1);
223105b261ecSmrg    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
223205b261ecSmrg    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
2233f7df2e56Smrg        return BadLength;
223405b261ecSmrg    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
2235f7df2e56Smrg        return BadLength;
2236f7df2e56Smrg    for (i = 0; i < stuff->nglyphs; i++) {
2237f7df2e56Smrg        swapl(&gids[i]);
2238f7df2e56Smrg        swaps(&gi[i].width);
2239f7df2e56Smrg        swaps(&gi[i].height);
2240f7df2e56Smrg        swaps(&gi[i].x);
2241f7df2e56Smrg        swaps(&gi[i].y);
2242f7df2e56Smrg        swaps(&gi[i].xOff);
2243f7df2e56Smrg        swaps(&gi[i].yOff);
224405b261ecSmrg    }
224505b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
224605b261ecSmrg}
224705b261ecSmrg
22487e31ba66Smrgstatic int _X_COLD
2249f7df2e56SmrgSProcRenderAddGlyphsFromPicture(ClientPtr client)
225005b261ecSmrg{
225105b261ecSmrg    return BadImplementation;
225205b261ecSmrg}
225305b261ecSmrg
22547e31ba66Smrgstatic int _X_COLD
2255f7df2e56SmrgSProcRenderFreeGlyphs(ClientPtr client)
225605b261ecSmrg{
225705b261ecSmrg    REQUEST(xRenderFreeGlyphsReq);
22580b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
2259f7df2e56Smrg    swaps(&stuff->length);
2260f7df2e56Smrg    swapl(&stuff->glyphset);
226105b261ecSmrg    SwapRestL(stuff);
226205b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
226305b261ecSmrg}
226405b261ecSmrg
22657e31ba66Smrgstatic int _X_COLD
2266f7df2e56SmrgSProcRenderCompositeGlyphs(ClientPtr client)
226705b261ecSmrg{
2268f7df2e56Smrg    xGlyphElt *elt;
2269f7df2e56Smrg    CARD8 *buffer;
2270f7df2e56Smrg    CARD8 *end;
2271f7df2e56Smrg    int space;
2272f7df2e56Smrg    int i;
2273f7df2e56Smrg    int size;
2274f7df2e56Smrg
227505b261ecSmrg    REQUEST(xRenderCompositeGlyphsReq);
22760b0d8713Smrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
2277f7df2e56Smrg
227805b261ecSmrg    switch (stuff->renderReqType) {
2279f7df2e56Smrg    default:
2280f7df2e56Smrg        size = 1;
2281f7df2e56Smrg        break;
2282f7df2e56Smrg    case X_RenderCompositeGlyphs16:
2283f7df2e56Smrg        size = 2;
2284f7df2e56Smrg        break;
2285f7df2e56Smrg    case X_RenderCompositeGlyphs32:
2286f7df2e56Smrg        size = 4;
2287f7df2e56Smrg        break;
2288f7df2e56Smrg    }
2289f7df2e56Smrg
2290f7df2e56Smrg    swaps(&stuff->length);
2291f7df2e56Smrg    swapl(&stuff->src);
2292f7df2e56Smrg    swapl(&stuff->dst);
2293f7df2e56Smrg    swapl(&stuff->maskFormat);
2294f7df2e56Smrg    swapl(&stuff->glyphset);
2295f7df2e56Smrg    swaps(&stuff->xSrc);
2296f7df2e56Smrg    swaps(&stuff->ySrc);
229705b261ecSmrg    buffer = (CARD8 *) (stuff + 1);
229805b261ecSmrg    end = (CARD8 *) stuff + (client->req_len << 2);
2299f7df2e56Smrg    while (buffer + sizeof(xGlyphElt) < end) {
2300f7df2e56Smrg        elt = (xGlyphElt *) buffer;
2301f7df2e56Smrg        buffer += sizeof(xGlyphElt);
2302f7df2e56Smrg
2303f7df2e56Smrg        swaps(&elt->deltax);
2304f7df2e56Smrg        swaps(&elt->deltay);
2305f7df2e56Smrg
2306f7df2e56Smrg        i = elt->len;
2307f7df2e56Smrg        if (i == 0xff) {
2308f7df2e56Smrg            swapl((int *) buffer);
2309f7df2e56Smrg            buffer += 4;
2310f7df2e56Smrg        }
2311f7df2e56Smrg        else {
2312f7df2e56Smrg            space = size * i;
2313f7df2e56Smrg            switch (size) {
2314f7df2e56Smrg            case 1:
2315f7df2e56Smrg                buffer += i;
2316f7df2e56Smrg                break;
2317f7df2e56Smrg            case 2:
2318f7df2e56Smrg                while (i--) {
2319f7df2e56Smrg                    swaps((short *) buffer);
2320f7df2e56Smrg                    buffer += 2;
2321f7df2e56Smrg                }
2322f7df2e56Smrg                break;
2323f7df2e56Smrg            case 4:
2324f7df2e56Smrg                while (i--) {
2325f7df2e56Smrg                    swapl((int *) buffer);
2326f7df2e56Smrg                    buffer += 4;
2327f7df2e56Smrg                }
2328f7df2e56Smrg                break;
2329f7df2e56Smrg            }
2330f7df2e56Smrg            if (space & 3)
2331f7df2e56Smrg                buffer += 4 - (space & 3);
2332f7df2e56Smrg        }
233305b261ecSmrg    }
233405b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
233505b261ecSmrg}
233605b261ecSmrg
23377e31ba66Smrgstatic int _X_COLD
2338f7df2e56SmrgSProcRenderFillRectangles(ClientPtr client)
233905b261ecSmrg{
234005b261ecSmrg    REQUEST(xRenderFillRectanglesReq);
234105b261ecSmrg
2342f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
2343f7df2e56Smrg    swaps(&stuff->length);
2344f7df2e56Smrg    swapl(&stuff->dst);
2345f7df2e56Smrg    swaps(&stuff->color.red);
2346f7df2e56Smrg    swaps(&stuff->color.green);
2347f7df2e56Smrg    swaps(&stuff->color.blue);
2348f7df2e56Smrg    swaps(&stuff->color.alpha);
234905b261ecSmrg    SwapRestS(stuff);
235005b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
235105b261ecSmrg}
2352f7df2e56Smrg
23537e31ba66Smrgstatic int _X_COLD
2354f7df2e56SmrgSProcRenderCreateCursor(ClientPtr client)
235505b261ecSmrg{
235605b261ecSmrg    REQUEST(xRenderCreateCursorReq);
2357f7df2e56Smrg    REQUEST_SIZE_MATCH(xRenderCreateCursorReq);
2358f7df2e56Smrg
2359f7df2e56Smrg    swaps(&stuff->length);
2360f7df2e56Smrg    swapl(&stuff->cid);
2361f7df2e56Smrg    swapl(&stuff->src);
2362f7df2e56Smrg    swaps(&stuff->x);
2363f7df2e56Smrg    swaps(&stuff->y);
236405b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
236505b261ecSmrg}
2366f7df2e56Smrg
23677e31ba66Smrgstatic int _X_COLD
2368f7df2e56SmrgSProcRenderSetPictureTransform(ClientPtr client)
236905b261ecSmrg{
237005b261ecSmrg    REQUEST(xRenderSetPictureTransformReq);
237105b261ecSmrg    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
237205b261ecSmrg
2373f7df2e56Smrg    swaps(&stuff->length);
2374f7df2e56Smrg    swapl(&stuff->picture);
2375f7df2e56Smrg    swapl(&stuff->transform.matrix11);
2376f7df2e56Smrg    swapl(&stuff->transform.matrix12);
2377f7df2e56Smrg    swapl(&stuff->transform.matrix13);
2378f7df2e56Smrg    swapl(&stuff->transform.matrix21);
2379f7df2e56Smrg    swapl(&stuff->transform.matrix22);
2380f7df2e56Smrg    swapl(&stuff->transform.matrix23);
2381f7df2e56Smrg    swapl(&stuff->transform.matrix31);
2382f7df2e56Smrg    swapl(&stuff->transform.matrix32);
2383f7df2e56Smrg    swapl(&stuff->transform.matrix33);
238405b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
238505b261ecSmrg}
238605b261ecSmrg
23877e31ba66Smrgstatic int _X_COLD
2388f7df2e56SmrgSProcRenderQueryFilters(ClientPtr client)
238905b261ecSmrg{
2390f7df2e56Smrg    REQUEST(xRenderQueryFiltersReq);
2391f7df2e56Smrg    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
239205b261ecSmrg
2393f7df2e56Smrg    swaps(&stuff->length);
2394f7df2e56Smrg    swapl(&stuff->drawable);
239505b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
239605b261ecSmrg}
2397f7df2e56Smrg
23987e31ba66Smrgstatic int _X_COLD
2399f7df2e56SmrgSProcRenderSetPictureFilter(ClientPtr client)
240005b261ecSmrg{
2401f7df2e56Smrg    REQUEST(xRenderSetPictureFilterReq);
2402f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
240305b261ecSmrg
2404f7df2e56Smrg    swaps(&stuff->length);
2405f7df2e56Smrg    swapl(&stuff->picture);
2406f7df2e56Smrg    swaps(&stuff->nbytes);
240705b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
240805b261ecSmrg}
2409f7df2e56Smrg
24107e31ba66Smrgstatic int _X_COLD
2411f7df2e56SmrgSProcRenderCreateAnimCursor(ClientPtr client)
241205b261ecSmrg{
2413f7df2e56Smrg    REQUEST(xRenderCreateAnimCursorReq);
2414f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
241505b261ecSmrg
2416f7df2e56Smrg    swaps(&stuff->length);
2417f7df2e56Smrg    swapl(&stuff->cid);
241805b261ecSmrg    SwapRestL(stuff);
241905b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
242005b261ecSmrg}
242105b261ecSmrg
24227e31ba66Smrgstatic int _X_COLD
2423f7df2e56SmrgSProcRenderAddTraps(ClientPtr client)
242405b261ecSmrg{
2425f7df2e56Smrg    REQUEST(xRenderAddTrapsReq);
2426f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
242705b261ecSmrg
2428f7df2e56Smrg    swaps(&stuff->length);
2429f7df2e56Smrg    swapl(&stuff->picture);
2430f7df2e56Smrg    swaps(&stuff->xOff);
2431f7df2e56Smrg    swaps(&stuff->yOff);
243205b261ecSmrg    SwapRestL(stuff);
243305b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
243405b261ecSmrg}
243505b261ecSmrg
24367e31ba66Smrgstatic int _X_COLD
243705b261ecSmrgSProcRenderCreateSolidFill(ClientPtr client)
243805b261ecSmrg{
2439f7df2e56Smrg    REQUEST(xRenderCreateSolidFillReq);
2440f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
244105b261ecSmrg
2442f7df2e56Smrg    swaps(&stuff->length);
2443f7df2e56Smrg    swapl(&stuff->pid);
2444f7df2e56Smrg    swaps(&stuff->color.alpha);
2445f7df2e56Smrg    swaps(&stuff->color.red);
2446f7df2e56Smrg    swaps(&stuff->color.green);
2447f7df2e56Smrg    swaps(&stuff->color.blue);
244805b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
244905b261ecSmrg}
245005b261ecSmrg
24517e31ba66Smrgstatic void _X_COLD
2452f7df2e56SmrgswapStops(void *stuff, int num)
245305b261ecSmrg{
2454f7df2e56Smrg    int i;
245505b261ecSmrg    CARD32 *stops;
245605b261ecSmrg    CARD16 *colors;
2457f7df2e56Smrg
2458f7df2e56Smrg    stops = (CARD32 *) (stuff);
245905b261ecSmrg    for (i = 0; i < num; ++i) {
2460f7df2e56Smrg        swapl(stops);
246105b261ecSmrg        ++stops;
246205b261ecSmrg    }
2463f7df2e56Smrg    colors = (CARD16 *) (stops);
2464f7df2e56Smrg    for (i = 0; i < 4 * num; ++i) {
2465f7df2e56Smrg        swaps(colors);
24668223e2f2Smrg        ++colors;
246705b261ecSmrg    }
246805b261ecSmrg}
246905b261ecSmrg
24707e31ba66Smrgstatic int _X_COLD
2471f7df2e56SmrgSProcRenderCreateLinearGradient(ClientPtr client)
247205b261ecSmrg{
247305b261ecSmrg    int len;
247405b261ecSmrg
2475f7df2e56Smrg    REQUEST(xRenderCreateLinearGradientReq);
2476f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
2477f7df2e56Smrg
2478f7df2e56Smrg    swaps(&stuff->length);
2479f7df2e56Smrg    swapl(&stuff->pid);
2480f7df2e56Smrg    swapl(&stuff->p1.x);
2481f7df2e56Smrg    swapl(&stuff->p1.y);
2482f7df2e56Smrg    swapl(&stuff->p2.x);
2483f7df2e56Smrg    swapl(&stuff->p2.y);
2484f7df2e56Smrg    swapl(&stuff->nStops);
248505b261ecSmrg
248605b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
2487f7df2e56Smrg    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
2488f7df2e56Smrg        return BadLength;
2489f7df2e56Smrg    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
249005b261ecSmrg        return BadLength;
249105b261ecSmrg
2492f7df2e56Smrg    swapStops(stuff + 1, stuff->nStops);
249305b261ecSmrg
249405b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
249505b261ecSmrg}
249605b261ecSmrg
24977e31ba66Smrgstatic int _X_COLD
2498f7df2e56SmrgSProcRenderCreateRadialGradient(ClientPtr client)
249905b261ecSmrg{
250005b261ecSmrg    int len;
2501f7df2e56Smrg
2502f7df2e56Smrg    REQUEST(xRenderCreateRadialGradientReq);
2503f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
2504f7df2e56Smrg
2505f7df2e56Smrg    swaps(&stuff->length);
2506f7df2e56Smrg    swapl(&stuff->pid);
2507f7df2e56Smrg    swapl(&stuff->inner.x);
2508f7df2e56Smrg    swapl(&stuff->inner.y);
2509f7df2e56Smrg    swapl(&stuff->outer.x);
2510f7df2e56Smrg    swapl(&stuff->outer.y);
2511f7df2e56Smrg    swapl(&stuff->inner_radius);
2512f7df2e56Smrg    swapl(&stuff->outer_radius);
2513f7df2e56Smrg    swapl(&stuff->nStops);
251405b261ecSmrg
251505b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
2516f7df2e56Smrg    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
2517f7df2e56Smrg        return BadLength;
2518f7df2e56Smrg    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
251905b261ecSmrg        return BadLength;
252005b261ecSmrg
2521f7df2e56Smrg    swapStops(stuff + 1, stuff->nStops);
252205b261ecSmrg
252305b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
252405b261ecSmrg}
252505b261ecSmrg
25267e31ba66Smrgstatic int _X_COLD
2527f7df2e56SmrgSProcRenderCreateConicalGradient(ClientPtr client)
252805b261ecSmrg{
252905b261ecSmrg    int len;
253005b261ecSmrg
2531f7df2e56Smrg    REQUEST(xRenderCreateConicalGradientReq);
2532f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
2533f7df2e56Smrg
2534f7df2e56Smrg    swaps(&stuff->length);
2535f7df2e56Smrg    swapl(&stuff->pid);
2536f7df2e56Smrg    swapl(&stuff->center.x);
2537f7df2e56Smrg    swapl(&stuff->center.y);
2538f7df2e56Smrg    swapl(&stuff->angle);
2539f7df2e56Smrg    swapl(&stuff->nStops);
254005b261ecSmrg
254105b261ecSmrg    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
2542f7df2e56Smrg    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
2543f7df2e56Smrg        return BadLength;
2544f7df2e56Smrg    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
254505b261ecSmrg        return BadLength;
254605b261ecSmrg
2547f7df2e56Smrg    swapStops(stuff + 1, stuff->nStops);
254805b261ecSmrg
254905b261ecSmrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
255005b261ecSmrg}
255105b261ecSmrg
25527e31ba66Smrgstatic int _X_COLD
2553f7df2e56SmrgSProcRenderDispatch(ClientPtr client)
255405b261ecSmrg{
255505b261ecSmrg    REQUEST(xReq);
2556f7df2e56Smrg
255705b261ecSmrg    if (stuff->data < RenderNumberRequests)
2558f7df2e56Smrg        return (*SProcRenderVector[stuff->data]) (client);
255905b261ecSmrg    else
2560f7df2e56Smrg        return BadRequest;
256105b261ecSmrg}
256205b261ecSmrg
256305b261ecSmrg#ifdef PANORAMIX
25646747b715Smrg#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\
2565f7df2e56Smrg    int rc = dixLookupResourceByType((void **)&(pPicture), pid,\
25666747b715Smrg                                     XRT_PICTURE, client, mode);\
25676747b715Smrg    if (rc != Success)\
25686747b715Smrg	return rc;\
256905b261ecSmrg}
257005b261ecSmrg
25716747b715Smrg#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\
257205b261ecSmrg    if (pid == None) \
257305b261ecSmrg	pPicture = 0; \
257405b261ecSmrg    else { \
25756747b715Smrg	VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \
257605b261ecSmrg    } \
257705b261ecSmrg} \
257805b261ecSmrg
2579f7df2e56Smrgint (*PanoramiXSaveRenderVector[RenderNumberRequests]) (ClientPtr);
258005b261ecSmrg
258105b261ecSmrgstatic int
2582f7df2e56SmrgPanoramiXRenderCreatePicture(ClientPtr client)
258305b261ecSmrg{
258405b261ecSmrg    REQUEST(xRenderCreatePictureReq);
2585f7df2e56Smrg    PanoramiXRes *refDraw, *newPict;
2586f7df2e56Smrg    int result, j;
258705b261ecSmrg
258805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2589f7df2e56Smrg    result = dixLookupResourceByClass((void **) &refDraw, stuff->drawable,
2590f7df2e56Smrg                                      XRC_DRAWABLE, client, DixWriteAccess);
25916747b715Smrg    if (result != Success)
2592f7df2e56Smrg        return (result == BadValue) ? BadDrawable : result;
2593f7df2e56Smrg    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
2594f7df2e56Smrg        return BadAlloc;
259505b261ecSmrg    newPict->type = XRT_PICTURE;
2596f7df2e56Smrg    panoramix_setup_ids(newPict, client, stuff->pid);
2597f7df2e56Smrg
259805b261ecSmrg    if (refDraw->type == XRT_WINDOW &&
2599f7df2e56Smrg        stuff->drawable == screenInfo.screens[0]->root->drawable.id) {
2600f7df2e56Smrg        newPict->u.pict.root = TRUE;
260105b261ecSmrg    }
260205b261ecSmrg    else
2603f7df2e56Smrg        newPict->u.pict.root = FALSE;
260405b261ecSmrg
260505b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
2606f7df2e56Smrg        stuff->pid = newPict->info[j].id;
2607f7df2e56Smrg        stuff->drawable = refDraw->info[j].id;
2608f7df2e56Smrg        result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
2609f7df2e56Smrg        if (result != Success)
2610f7df2e56Smrg            break;
261105b261ecSmrg    }
261205b261ecSmrg
261305b261ecSmrg    if (result == Success)
2614f7df2e56Smrg        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
2615f7df2e56Smrg    else
2616f7df2e56Smrg        free(newPict);
261705b261ecSmrg
26186747b715Smrg    return result;
261905b261ecSmrg}
262005b261ecSmrg
262105b261ecSmrgstatic int
2622f7df2e56SmrgPanoramiXRenderChangePicture(ClientPtr client)
262305b261ecSmrg{
2624f7df2e56Smrg    PanoramiXRes *pict;
2625f7df2e56Smrg    int result = Success, j;
2626f7df2e56Smrg
262705b261ecSmrg    REQUEST(xRenderChangePictureReq);
262805b261ecSmrg
26296747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
2630f7df2e56Smrg
26316747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2632f7df2e56Smrg
263305b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
263405b261ecSmrg        stuff->picture = pict->info[j].id;
263505b261ecSmrg        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
2636f7df2e56Smrg        if (result != Success)
2637f7df2e56Smrg            break;
263805b261ecSmrg    }
263905b261ecSmrg
26406747b715Smrg    return result;
264105b261ecSmrg}
264205b261ecSmrg
264305b261ecSmrgstatic int
2644f7df2e56SmrgPanoramiXRenderSetPictureClipRectangles(ClientPtr client)
264505b261ecSmrg{
264605b261ecSmrg    REQUEST(xRenderSetPictureClipRectanglesReq);
2647f7df2e56Smrg    int result = Success, j;
2648f7df2e56Smrg    PanoramiXRes *pict;
264905b261ecSmrg
265005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
2651f7df2e56Smrg
26526747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2653f7df2e56Smrg
265405b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
265505b261ecSmrg        stuff->picture = pict->info[j].id;
2656f7df2e56Smrg        result =
2657f7df2e56Smrg            (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles])
2658f7df2e56Smrg            (client);
2659f7df2e56Smrg        if (result != Success)
2660f7df2e56Smrg            break;
266105b261ecSmrg    }
266205b261ecSmrg
26636747b715Smrg    return result;
266405b261ecSmrg}
266505b261ecSmrg
266605b261ecSmrgstatic int
2667f7df2e56SmrgPanoramiXRenderSetPictureTransform(ClientPtr client)
266805b261ecSmrg{
266905b261ecSmrg    REQUEST(xRenderSetPictureTransformReq);
2670f7df2e56Smrg    int result = Success, j;
2671f7df2e56Smrg    PanoramiXRes *pict;
267205b261ecSmrg
267305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
2674f7df2e56Smrg
26756747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2676f7df2e56Smrg
267705b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
267805b261ecSmrg        stuff->picture = pict->info[j].id;
2679f7df2e56Smrg        result =
2680f7df2e56Smrg            (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
2681f7df2e56Smrg        if (result != Success)
2682f7df2e56Smrg            break;
268305b261ecSmrg    }
268405b261ecSmrg
26856747b715Smrg    return result;
268605b261ecSmrg}
268705b261ecSmrg
268805b261ecSmrgstatic int
2689f7df2e56SmrgPanoramiXRenderSetPictureFilter(ClientPtr client)
269005b261ecSmrg{
269105b261ecSmrg    REQUEST(xRenderSetPictureFilterReq);
2692f7df2e56Smrg    int result = Success, j;
2693f7df2e56Smrg    PanoramiXRes *pict;
269405b261ecSmrg
269505b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
2696f7df2e56Smrg
26976747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2698f7df2e56Smrg
269905b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
270005b261ecSmrg        stuff->picture = pict->info[j].id;
2701f7df2e56Smrg        result =
2702f7df2e56Smrg            (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
2703f7df2e56Smrg        if (result != Success)
2704f7df2e56Smrg            break;
270505b261ecSmrg    }
270605b261ecSmrg
27076747b715Smrg    return result;
270805b261ecSmrg}
270905b261ecSmrg
271005b261ecSmrgstatic int
2711f7df2e56SmrgPanoramiXRenderFreePicture(ClientPtr client)
271205b261ecSmrg{
271305b261ecSmrg    PanoramiXRes *pict;
2714f7df2e56Smrg    int result = Success, j;
2715f7df2e56Smrg
271605b261ecSmrg    REQUEST(xRenderFreePictureReq);
271705b261ecSmrg
271805b261ecSmrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
271905b261ecSmrg
272005b261ecSmrg    client->errorValue = stuff->picture;
272105b261ecSmrg
27226747b715Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess);
272305b261ecSmrg
272405b261ecSmrg    FOR_NSCREENS_BACKWARD(j) {
2725f7df2e56Smrg        stuff->picture = pict->info[j].id;
2726f7df2e56Smrg        result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
2727f7df2e56Smrg        if (result != Success)
2728f7df2e56Smrg            break;
272905b261ecSmrg    }
273005b261ecSmrg
273105b261ecSmrg    /* Since ProcRenderFreePicture is using FreeResource, it will free
2732f7df2e56Smrg       our resource for us on the last pass through the loop above */
2733f7df2e56Smrg
27346747b715Smrg    return result;
273505b261ecSmrg}
273605b261ecSmrg
273705b261ecSmrgstatic int
2738f7df2e56SmrgPanoramiXRenderComposite(ClientPtr client)
273905b261ecSmrg{
2740f7df2e56Smrg    PanoramiXRes *src, *msk, *dst;
2741f7df2e56Smrg    int result = Success, j;
2742f7df2e56Smrg    xRenderCompositeReq orig;
2743f7df2e56Smrg
274405b261ecSmrg    REQUEST(xRenderCompositeReq);
274505b261ecSmrg
274605b261ecSmrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
2747f7df2e56Smrg
2748f7df2e56Smrg    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2749f7df2e56Smrg    VERIFY_XIN_ALPHA(msk, stuff->mask, client, DixReadAccess);
2750f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2751f7df2e56Smrg
275205b261ecSmrg    orig = *stuff;
2753f7df2e56Smrg
275405b261ecSmrg    FOR_NSCREENS_FORWARD(j) {
2755f7df2e56Smrg        stuff->src = src->info[j].id;
2756f7df2e56Smrg        if (src->u.pict.root) {
2757f7df2e56Smrg            stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x;
2758f7df2e56Smrg            stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y;
2759f7df2e56Smrg        }
2760f7df2e56Smrg        stuff->dst = dst->info[j].id;
2761f7df2e56Smrg        if (dst->u.pict.root) {
2762f7df2e56Smrg            stuff->xDst = orig.xDst - screenInfo.screens[j]->x;
2763f7df2e56Smrg            stuff->yDst = orig.yDst - screenInfo.screens[j]->y;
2764f7df2e56Smrg        }
2765f7df2e56Smrg        if (msk) {
2766f7df2e56Smrg            stuff->mask = msk->info[j].id;
2767f7df2e56Smrg            if (msk->u.pict.root) {
2768f7df2e56Smrg                stuff->xMask = orig.xMask - screenInfo.screens[j]->x;
2769f7df2e56Smrg                stuff->yMask = orig.yMask - screenInfo.screens[j]->y;
2770f7df2e56Smrg            }
2771f7df2e56Smrg        }
2772f7df2e56Smrg        result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
2773f7df2e56Smrg        if (result != Success)
2774f7df2e56Smrg            break;
277505b261ecSmrg    }
277605b261ecSmrg
277705b261ecSmrg    return result;
277805b261ecSmrg}
277905b261ecSmrg
278005b261ecSmrgstatic int
2781f7df2e56SmrgPanoramiXRenderCompositeGlyphs(ClientPtr client)
278205b261ecSmrg{
2783f7df2e56Smrg    PanoramiXRes *src, *dst;
2784f7df2e56Smrg    int result = Success, j;
2785f7df2e56Smrg
278605b261ecSmrg    REQUEST(xRenderCompositeGlyphsReq);
2787f7df2e56Smrg    xGlyphElt origElt, *elt;
2788f7df2e56Smrg    INT16 xSrc, ySrc;
278905b261ecSmrg
279005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
2791f7df2e56Smrg    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2792f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2793f7df2e56Smrg
2794f7df2e56Smrg    if (client->req_len << 2 >= (sizeof(xRenderCompositeGlyphsReq) +
2795f7df2e56Smrg                                 sizeof(xGlyphElt))) {
2796f7df2e56Smrg        elt = (xGlyphElt *) (stuff + 1);
2797f7df2e56Smrg        origElt = *elt;
2798f7df2e56Smrg        xSrc = stuff->xSrc;
2799f7df2e56Smrg        ySrc = stuff->ySrc;
2800f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
2801f7df2e56Smrg            stuff->src = src->info[j].id;
2802f7df2e56Smrg            if (src->u.pict.root) {
2803f7df2e56Smrg                stuff->xSrc = xSrc - screenInfo.screens[j]->x;
2804f7df2e56Smrg                stuff->ySrc = ySrc - screenInfo.screens[j]->y;
2805f7df2e56Smrg            }
2806f7df2e56Smrg            stuff->dst = dst->info[j].id;
2807f7df2e56Smrg            if (dst->u.pict.root) {
2808f7df2e56Smrg                elt->deltax = origElt.deltax - screenInfo.screens[j]->x;
2809f7df2e56Smrg                elt->deltay = origElt.deltay - screenInfo.screens[j]->y;
2810f7df2e56Smrg            }
2811f7df2e56Smrg            result =
2812f7df2e56Smrg                (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
2813f7df2e56Smrg            if (result != Success)
2814f7df2e56Smrg                break;
2815f7df2e56Smrg        }
281605b261ecSmrg    }
281705b261ecSmrg
281805b261ecSmrg    return result;
281905b261ecSmrg}
282005b261ecSmrg
282105b261ecSmrgstatic int
2822f7df2e56SmrgPanoramiXRenderFillRectangles(ClientPtr client)
282305b261ecSmrg{
2824f7df2e56Smrg    PanoramiXRes *dst;
2825f7df2e56Smrg    int result = Success, j;
2826f7df2e56Smrg
282705b261ecSmrg    REQUEST(xRenderFillRectanglesReq);
2828f7df2e56Smrg    char *extra;
2829f7df2e56Smrg    int extra_len;
2830f7df2e56Smrg
2831f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
2832f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2833f7df2e56Smrg    extra_len = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
2834f7df2e56Smrg    if (extra_len && (extra = (char *) malloc(extra_len))) {
2835f7df2e56Smrg        memcpy(extra, stuff + 1, extra_len);
2836f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
2837f7df2e56Smrg            if (j)
2838f7df2e56Smrg                memcpy(stuff + 1, extra, extra_len);
2839f7df2e56Smrg            if (dst->u.pict.root) {
2840f7df2e56Smrg                int x_off = screenInfo.screens[j]->x;
2841f7df2e56Smrg                int y_off = screenInfo.screens[j]->y;
2842f7df2e56Smrg
2843f7df2e56Smrg                if (x_off || y_off) {
2844f7df2e56Smrg                    xRectangle *rects = (xRectangle *) (stuff + 1);
2845f7df2e56Smrg                    int i = extra_len / sizeof(xRectangle);
2846f7df2e56Smrg
2847f7df2e56Smrg                    while (i--) {
2848f7df2e56Smrg                        rects->x -= x_off;
2849f7df2e56Smrg                        rects->y -= y_off;
2850f7df2e56Smrg                        rects++;
2851f7df2e56Smrg                    }
2852f7df2e56Smrg                }
2853f7df2e56Smrg            }
2854f7df2e56Smrg            stuff->dst = dst->info[j].id;
2855f7df2e56Smrg            result =
2856f7df2e56Smrg                (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
2857f7df2e56Smrg            if (result != Success)
2858f7df2e56Smrg                break;
2859f7df2e56Smrg        }
2860f7df2e56Smrg        free(extra);
286105b261ecSmrg    }
286205b261ecSmrg
286305b261ecSmrg    return result;
286405b261ecSmrg}
286505b261ecSmrg
286605b261ecSmrgstatic int
286705b261ecSmrgPanoramiXRenderTrapezoids(ClientPtr client)
286805b261ecSmrg{
2869f7df2e56Smrg    PanoramiXRes *src, *dst;
2870f7df2e56Smrg    int result = Success, j;
2871f7df2e56Smrg
287205b261ecSmrg    REQUEST(xRenderTrapezoidsReq);
2873f7df2e56Smrg    char *extra;
2874f7df2e56Smrg    int extra_len;
2875f7df2e56Smrg
2876f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
2877f7df2e56Smrg
2878f7df2e56Smrg    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2879f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2880f7df2e56Smrg
2881f7df2e56Smrg    extra_len = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq);
2882f7df2e56Smrg
2883f7df2e56Smrg    if (extra_len && (extra = (char *) malloc(extra_len))) {
2884f7df2e56Smrg        memcpy(extra, stuff + 1, extra_len);
2885f7df2e56Smrg
2886f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
2887f7df2e56Smrg            if (j)
2888f7df2e56Smrg                memcpy(stuff + 1, extra, extra_len);
2889f7df2e56Smrg            if (dst->u.pict.root) {
2890f7df2e56Smrg                int x_off = screenInfo.screens[j]->x;
2891f7df2e56Smrg                int y_off = screenInfo.screens[j]->y;
2892f7df2e56Smrg
2893f7df2e56Smrg                if (x_off || y_off) {
2894f7df2e56Smrg                    xTrapezoid *trap = (xTrapezoid *) (stuff + 1);
2895f7df2e56Smrg                    int i = extra_len / sizeof(xTrapezoid);
2896f7df2e56Smrg
2897f7df2e56Smrg                    while (i--) {
2898f7df2e56Smrg                        trap->top -= y_off;
2899f7df2e56Smrg                        trap->bottom -= y_off;
2900f7df2e56Smrg                        trap->left.p1.x -= x_off;
2901f7df2e56Smrg                        trap->left.p1.y -= y_off;
2902f7df2e56Smrg                        trap->left.p2.x -= x_off;
2903f7df2e56Smrg                        trap->left.p2.y -= y_off;
2904f7df2e56Smrg                        trap->right.p1.x -= x_off;
2905f7df2e56Smrg                        trap->right.p1.y -= y_off;
2906f7df2e56Smrg                        trap->right.p2.x -= x_off;
2907f7df2e56Smrg                        trap->right.p2.y -= y_off;
2908f7df2e56Smrg                        trap++;
2909f7df2e56Smrg                    }
2910f7df2e56Smrg                }
2911f7df2e56Smrg            }
2912f7df2e56Smrg
291305b261ecSmrg            stuff->src = src->info[j].id;
291405b261ecSmrg            stuff->dst = dst->info[j].id;
2915f7df2e56Smrg            result = (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
2916f7df2e56Smrg
2917f7df2e56Smrg            if (result != Success)
2918f7df2e56Smrg                break;
2919f7df2e56Smrg        }
292005b261ecSmrg
29216747b715Smrg        free(extra);
292205b261ecSmrg    }
292305b261ecSmrg
292405b261ecSmrg    return result;
292505b261ecSmrg}
292605b261ecSmrg
292705b261ecSmrgstatic int
292805b261ecSmrgPanoramiXRenderTriangles(ClientPtr client)
292905b261ecSmrg{
2930f7df2e56Smrg    PanoramiXRes *src, *dst;
2931f7df2e56Smrg    int result = Success, j;
2932f7df2e56Smrg
293305b261ecSmrg    REQUEST(xRenderTrianglesReq);
2934f7df2e56Smrg    char *extra;
2935f7df2e56Smrg    int extra_len;
2936f7df2e56Smrg
2937f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
2938f7df2e56Smrg
2939f7df2e56Smrg    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2940f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2941f7df2e56Smrg
2942f7df2e56Smrg    extra_len = (client->req_len << 2) - sizeof(xRenderTrianglesReq);
2943f7df2e56Smrg
2944f7df2e56Smrg    if (extra_len && (extra = (char *) malloc(extra_len))) {
2945f7df2e56Smrg        memcpy(extra, stuff + 1, extra_len);
2946f7df2e56Smrg
2947f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
2948f7df2e56Smrg            if (j)
2949f7df2e56Smrg                memcpy(stuff + 1, extra, extra_len);
2950f7df2e56Smrg            if (dst->u.pict.root) {
2951f7df2e56Smrg                int x_off = screenInfo.screens[j]->x;
2952f7df2e56Smrg                int y_off = screenInfo.screens[j]->y;
2953f7df2e56Smrg
2954f7df2e56Smrg                if (x_off || y_off) {
2955f7df2e56Smrg                    xTriangle *tri = (xTriangle *) (stuff + 1);
2956f7df2e56Smrg                    int i = extra_len / sizeof(xTriangle);
2957f7df2e56Smrg
2958f7df2e56Smrg                    while (i--) {
2959f7df2e56Smrg                        tri->p1.x -= x_off;
2960f7df2e56Smrg                        tri->p1.y -= y_off;
2961f7df2e56Smrg                        tri->p2.x -= x_off;
2962f7df2e56Smrg                        tri->p2.y -= y_off;
2963f7df2e56Smrg                        tri->p3.x -= x_off;
2964f7df2e56Smrg                        tri->p3.y -= y_off;
2965f7df2e56Smrg                        tri++;
2966f7df2e56Smrg                    }
2967f7df2e56Smrg                }
2968f7df2e56Smrg            }
2969f7df2e56Smrg
297005b261ecSmrg            stuff->src = src->info[j].id;
297105b261ecSmrg            stuff->dst = dst->info[j].id;
2972f7df2e56Smrg            result = (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
2973f7df2e56Smrg
2974f7df2e56Smrg            if (result != Success)
2975f7df2e56Smrg                break;
2976f7df2e56Smrg        }
297705b261ecSmrg
29786747b715Smrg        free(extra);
297905b261ecSmrg    }
298005b261ecSmrg
298105b261ecSmrg    return result;
298205b261ecSmrg}
298305b261ecSmrg
298405b261ecSmrgstatic int
298505b261ecSmrgPanoramiXRenderTriStrip(ClientPtr client)
298605b261ecSmrg{
2987f7df2e56Smrg    PanoramiXRes *src, *dst;
2988f7df2e56Smrg    int result = Success, j;
2989f7df2e56Smrg
299005b261ecSmrg    REQUEST(xRenderTriStripReq);
2991f7df2e56Smrg    char *extra;
2992f7df2e56Smrg    int extra_len;
2993f7df2e56Smrg
2994f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
2995f7df2e56Smrg
2996f7df2e56Smrg    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2997f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2998f7df2e56Smrg
2999f7df2e56Smrg    extra_len = (client->req_len << 2) - sizeof(xRenderTriStripReq);
3000f7df2e56Smrg
3001f7df2e56Smrg    if (extra_len && (extra = (char *) malloc(extra_len))) {
3002f7df2e56Smrg        memcpy(extra, stuff + 1, extra_len);
3003f7df2e56Smrg
3004f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
3005f7df2e56Smrg            if (j)
3006f7df2e56Smrg                memcpy(stuff + 1, extra, extra_len);
3007f7df2e56Smrg            if (dst->u.pict.root) {
3008f7df2e56Smrg                int x_off = screenInfo.screens[j]->x;
3009f7df2e56Smrg                int y_off = screenInfo.screens[j]->y;
3010f7df2e56Smrg
3011f7df2e56Smrg                if (x_off || y_off) {
3012f7df2e56Smrg                    xPointFixed *fixed = (xPointFixed *) (stuff + 1);
3013f7df2e56Smrg                    int i = extra_len / sizeof(xPointFixed);
3014f7df2e56Smrg
3015f7df2e56Smrg                    while (i--) {
3016f7df2e56Smrg                        fixed->x -= x_off;
3017f7df2e56Smrg                        fixed->y -= y_off;
3018f7df2e56Smrg                        fixed++;
3019f7df2e56Smrg                    }
3020f7df2e56Smrg                }
3021f7df2e56Smrg            }
3022f7df2e56Smrg
302305b261ecSmrg            stuff->src = src->info[j].id;
302405b261ecSmrg            stuff->dst = dst->info[j].id;
3025f7df2e56Smrg            result = (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
3026f7df2e56Smrg
3027f7df2e56Smrg            if (result != Success)
3028f7df2e56Smrg                break;
3029f7df2e56Smrg        }
303005b261ecSmrg
30316747b715Smrg        free(extra);
303205b261ecSmrg    }
303305b261ecSmrg
303405b261ecSmrg    return result;
303505b261ecSmrg}
303605b261ecSmrg
303705b261ecSmrgstatic int
303805b261ecSmrgPanoramiXRenderTriFan(ClientPtr client)
303905b261ecSmrg{
3040f7df2e56Smrg    PanoramiXRes *src, *dst;
3041f7df2e56Smrg    int result = Success, j;
3042f7df2e56Smrg
304305b261ecSmrg    REQUEST(xRenderTriFanReq);
3044f7df2e56Smrg    char *extra;
3045f7df2e56Smrg    int extra_len;
3046f7df2e56Smrg
3047f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
3048f7df2e56Smrg
3049f7df2e56Smrg    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
3050f7df2e56Smrg    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
3051f7df2e56Smrg
3052f7df2e56Smrg    extra_len = (client->req_len << 2) - sizeof(xRenderTriFanReq);
3053f7df2e56Smrg
3054f7df2e56Smrg    if (extra_len && (extra = (char *) malloc(extra_len))) {
3055f7df2e56Smrg        memcpy(extra, stuff + 1, extra_len);
3056f7df2e56Smrg
3057f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
3058f7df2e56Smrg            if (j)
3059f7df2e56Smrg                memcpy(stuff + 1, extra, extra_len);
3060f7df2e56Smrg            if (dst->u.pict.root) {
3061f7df2e56Smrg                int x_off = screenInfo.screens[j]->x;
3062f7df2e56Smrg                int y_off = screenInfo.screens[j]->y;
3063f7df2e56Smrg
3064f7df2e56Smrg                if (x_off || y_off) {
3065f7df2e56Smrg                    xPointFixed *fixed = (xPointFixed *) (stuff + 1);
3066f7df2e56Smrg                    int i = extra_len / sizeof(xPointFixed);
3067f7df2e56Smrg
3068f7df2e56Smrg                    while (i--) {
3069f7df2e56Smrg                        fixed->x -= x_off;
3070f7df2e56Smrg                        fixed->y -= y_off;
3071f7df2e56Smrg                        fixed++;
3072f7df2e56Smrg                    }
3073f7df2e56Smrg                }
3074f7df2e56Smrg            }
3075f7df2e56Smrg
307605b261ecSmrg            stuff->src = src->info[j].id;
307705b261ecSmrg            stuff->dst = dst->info[j].id;
3078f7df2e56Smrg            result = (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
3079f7df2e56Smrg
3080f7df2e56Smrg            if (result != Success)
3081f7df2e56Smrg                break;
3082f7df2e56Smrg        }
308305b261ecSmrg
30846747b715Smrg        free(extra);
308505b261ecSmrg    }
308605b261ecSmrg
308705b261ecSmrg    return result;
308805b261ecSmrg}
308905b261ecSmrg
309005b261ecSmrgstatic int
3091f7df2e56SmrgPanoramiXRenderAddTraps(ClientPtr client)
309205b261ecSmrg{
3093f7df2e56Smrg    PanoramiXRes *picture;
3094f7df2e56Smrg    int result = Success, j;
3095f7df2e56Smrg
309605b261ecSmrg    REQUEST(xRenderAddTrapsReq);
3097f7df2e56Smrg    char *extra;
3098f7df2e56Smrg    int extra_len;
3099f7df2e56Smrg    INT16 x_off, y_off;
3100f7df2e56Smrg
3101f7df2e56Smrg    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
3102f7df2e56Smrg    VERIFY_XIN_PICTURE(picture, stuff->picture, client, DixWriteAccess);
3103f7df2e56Smrg    extra_len = (client->req_len << 2) - sizeof(xRenderAddTrapsReq);
3104f7df2e56Smrg    if (extra_len && (extra = (char *) malloc(extra_len))) {
3105f7df2e56Smrg        memcpy(extra, stuff + 1, extra_len);
3106f7df2e56Smrg        x_off = stuff->xOff;
3107f7df2e56Smrg        y_off = stuff->yOff;
3108f7df2e56Smrg        FOR_NSCREENS_FORWARD(j) {
3109f7df2e56Smrg            if (j)
3110f7df2e56Smrg                memcpy(stuff + 1, extra, extra_len);
3111f7df2e56Smrg            stuff->picture = picture->info[j].id;
3112f7df2e56Smrg
3113f7df2e56Smrg            if (picture->u.pict.root) {
3114f7df2e56Smrg                stuff->xOff = x_off + screenInfo.screens[j]->x;
3115f7df2e56Smrg                stuff->yOff = y_off + screenInfo.screens[j]->y;
3116f7df2e56Smrg            }
3117f7df2e56Smrg            result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
3118f7df2e56Smrg            if (result != Success)
3119f7df2e56Smrg                break;
3120f7df2e56Smrg        }
3121f7df2e56Smrg        free(extra);
31226747b715Smrg    }
31236747b715Smrg
31246747b715Smrg    return result;
31256747b715Smrg}
31266747b715Smrg
31276747b715Smrgstatic int
3128f7df2e56SmrgPanoramiXRenderCreateSolidFill(ClientPtr client)
31296747b715Smrg{
31306747b715Smrg    REQUEST(xRenderCreateSolidFillReq);
3131f7df2e56Smrg    PanoramiXRes *newPict;
3132f7df2e56Smrg    int result = Success, j;
31336747b715Smrg
31346747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
31356747b715Smrg
3136f7df2e56Smrg    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3137f7df2e56Smrg        return BadAlloc;
31386747b715Smrg
31396747b715Smrg    newPict->type = XRT_PICTURE;
3140f7df2e56Smrg    panoramix_setup_ids(newPict, client, stuff->pid);
31416747b715Smrg    newPict->u.pict.root = FALSE;
31426747b715Smrg
31436747b715Smrg    FOR_NSCREENS_BACKWARD(j) {
3144f7df2e56Smrg        stuff->pid = newPict->info[j].id;
3145f7df2e56Smrg        result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client);
3146f7df2e56Smrg        if (result != Success)
3147f7df2e56Smrg            break;
31486747b715Smrg    }
31496747b715Smrg
31506747b715Smrg    if (result == Success)
3151f7df2e56Smrg        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
31526747b715Smrg    else
3153f7df2e56Smrg        free(newPict);
31546747b715Smrg
31556747b715Smrg    return result;
31566747b715Smrg}
31576747b715Smrg
31586747b715Smrgstatic int
3159f7df2e56SmrgPanoramiXRenderCreateLinearGradient(ClientPtr client)
31606747b715Smrg{
31616747b715Smrg    REQUEST(xRenderCreateLinearGradientReq);
3162f7df2e56Smrg    PanoramiXRes *newPict;
3163f7df2e56Smrg    int result = Success, j;
31646747b715Smrg
31656747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
31666747b715Smrg
3167f7df2e56Smrg    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3168f7df2e56Smrg        return BadAlloc;
31696747b715Smrg
31706747b715Smrg    newPict->type = XRT_PICTURE;
3171f7df2e56Smrg    panoramix_setup_ids(newPict, client, stuff->pid);
31726747b715Smrg    newPict->u.pict.root = FALSE;
31736747b715Smrg
31746747b715Smrg    FOR_NSCREENS_BACKWARD(j) {
3175f7df2e56Smrg        stuff->pid = newPict->info[j].id;
3176f7df2e56Smrg        result =
3177f7df2e56Smrg            (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client);
3178f7df2e56Smrg        if (result != Success)
3179f7df2e56Smrg            break;
318005b261ecSmrg    }
318105b261ecSmrg
31826747b715Smrg    if (result == Success)
3183f7df2e56Smrg        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
31846747b715Smrg    else
3185f7df2e56Smrg        free(newPict);
31866747b715Smrg
31876747b715Smrg    return result;
31886747b715Smrg}
31896747b715Smrg
31906747b715Smrgstatic int
3191f7df2e56SmrgPanoramiXRenderCreateRadialGradient(ClientPtr client)
31926747b715Smrg{
31936747b715Smrg    REQUEST(xRenderCreateRadialGradientReq);
3194f7df2e56Smrg    PanoramiXRes *newPict;
3195f7df2e56Smrg    int result = Success, j;
31966747b715Smrg
31976747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
31986747b715Smrg
3199f7df2e56Smrg    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3200f7df2e56Smrg        return BadAlloc;
32016747b715Smrg
32026747b715Smrg    newPict->type = XRT_PICTURE;
3203f7df2e56Smrg    panoramix_setup_ids(newPict, client, stuff->pid);
32046747b715Smrg    newPict->u.pict.root = FALSE;
32056747b715Smrg
32066747b715Smrg    FOR_NSCREENS_BACKWARD(j) {
3207f7df2e56Smrg        stuff->pid = newPict->info[j].id;
3208f7df2e56Smrg        result =
3209f7df2e56Smrg            (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client);
3210f7df2e56Smrg        if (result != Success)
3211f7df2e56Smrg            break;
32126747b715Smrg    }
32136747b715Smrg
32146747b715Smrg    if (result == Success)
3215f7df2e56Smrg        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
32166747b715Smrg    else
3217f7df2e56Smrg        free(newPict);
32186747b715Smrg
32196747b715Smrg    return result;
32206747b715Smrg}
32216747b715Smrg
32226747b715Smrgstatic int
3223f7df2e56SmrgPanoramiXRenderCreateConicalGradient(ClientPtr client)
32246747b715Smrg{
32256747b715Smrg    REQUEST(xRenderCreateConicalGradientReq);
3226f7df2e56Smrg    PanoramiXRes *newPict;
3227f7df2e56Smrg    int result = Success, j;
32286747b715Smrg
32296747b715Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
32306747b715Smrg
3231f7df2e56Smrg    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3232f7df2e56Smrg        return BadAlloc;
32336747b715Smrg
32346747b715Smrg    newPict->type = XRT_PICTURE;
3235f7df2e56Smrg    panoramix_setup_ids(newPict, client, stuff->pid);
32366747b715Smrg    newPict->u.pict.root = FALSE;
32376747b715Smrg
32386747b715Smrg    FOR_NSCREENS_BACKWARD(j) {
3239f7df2e56Smrg        stuff->pid = newPict->info[j].id;
3240f7df2e56Smrg        result =
3241f7df2e56Smrg            (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient])
3242f7df2e56Smrg            (client);
3243f7df2e56Smrg        if (result != Success)
3244f7df2e56Smrg            break;
32456747b715Smrg    }
32466747b715Smrg
32476747b715Smrg    if (result == Success)
3248f7df2e56Smrg        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
32496747b715Smrg    else
3250f7df2e56Smrg        free(newPict);
32516747b715Smrg
325205b261ecSmrg    return result;
325305b261ecSmrg}
325405b261ecSmrg
325505b261ecSmrgvoid
3256f7df2e56SmrgPanoramiXRenderInit(void)
325705b261ecSmrg{
3258f7df2e56Smrg    int i;
3259f7df2e56Smrg
3260f7df2e56Smrg    XRT_PICTURE = CreateNewResourceType(XineramaDeleteResource,
3261f7df2e56Smrg                                        "XineramaPicture");
32626747b715Smrg    if (RenderErrBase)
3263f7df2e56Smrg        SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
326405b261ecSmrg    for (i = 0; i < RenderNumberRequests; i++)
3265f7df2e56Smrg        PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
326605b261ecSmrg    /*
326705b261ecSmrg     * Stuff in Xinerama aware request processing hooks
326805b261ecSmrg     */
326905b261ecSmrg    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
327005b261ecSmrg    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
3271f7df2e56Smrg    ProcRenderVector[X_RenderSetPictureTransform] =
3272f7df2e56Smrg        PanoramiXRenderSetPictureTransform;
3273f7df2e56Smrg    ProcRenderVector[X_RenderSetPictureFilter] =
3274f7df2e56Smrg        PanoramiXRenderSetPictureFilter;
3275f7df2e56Smrg    ProcRenderVector[X_RenderSetPictureClipRectangles] =
3276f7df2e56Smrg        PanoramiXRenderSetPictureClipRectangles;
327705b261ecSmrg    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
327805b261ecSmrg    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
327905b261ecSmrg    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
3280f7df2e56Smrg    ProcRenderVector[X_RenderCompositeGlyphs16] =
3281f7df2e56Smrg        PanoramiXRenderCompositeGlyphs;
3282f7df2e56Smrg    ProcRenderVector[X_RenderCompositeGlyphs32] =
3283f7df2e56Smrg        PanoramiXRenderCompositeGlyphs;
328405b261ecSmrg    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
328505b261ecSmrg
328605b261ecSmrg    ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
328705b261ecSmrg    ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
328805b261ecSmrg    ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
328905b261ecSmrg    ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
329005b261ecSmrg    ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
32916747b715Smrg
32926747b715Smrg    ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill;
3293f7df2e56Smrg    ProcRenderVector[X_RenderCreateLinearGradient] =
3294f7df2e56Smrg        PanoramiXRenderCreateLinearGradient;
3295f7df2e56Smrg    ProcRenderVector[X_RenderCreateRadialGradient] =
3296f7df2e56Smrg        PanoramiXRenderCreateRadialGradient;
3297f7df2e56Smrg    ProcRenderVector[X_RenderCreateConicalGradient] =
3298f7df2e56Smrg        PanoramiXRenderCreateConicalGradient;
329905b261ecSmrg}
330005b261ecSmrg
330105b261ecSmrgvoid
3302f7df2e56SmrgPanoramiXRenderReset(void)
330305b261ecSmrg{
3304f7df2e56Smrg    int i;
3305f7df2e56Smrg
330605b261ecSmrg    for (i = 0; i < RenderNumberRequests; i++)
3307f7df2e56Smrg        ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
33086747b715Smrg    RenderErrBase = 0;
330905b261ecSmrg}
331005b261ecSmrg
3311f7df2e56Smrg#endif                          /* PANORAMIX */
3312