render.c revision 2f76b07d
1/*
2 *
3 * Copyright © 2000 SuSE, Inc.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of SuSE not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission.  SuSE makes no representations about the
12 * suitability of this software for any purpose.  It is provided "as is"
13 * without express or implied warranty.
14 *
15 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
17 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Author:  Keith Packard, SuSE, Inc.
23 */
24
25#ifdef HAVE_DIX_CONFIG_H
26#include <dix-config.h>
27#endif
28
29#include <X11/X.h>
30#include <X11/Xproto.h>
31#include "misc.h"
32#include "os.h"
33#include "dixstruct.h"
34#include "resource.h"
35#include "scrnintstr.h"
36#include "windowstr.h"
37#include "pixmapstr.h"
38#include "colormapst.h"
39#include "extnsionst.h"
40#include "extinit.h"
41#include "servermd.h"
42#include <X11/extensions/render.h>
43#include <X11/extensions/renderproto.h>
44#include "picturestr.h"
45#include "glyphstr.h"
46#include <X11/Xfuncproto.h>
47#include "cursorstr.h"
48#include "xace.h"
49#include "protocol-versions.h"
50
51#ifdef PANORAMIX
52#include "panoramiX.h"
53#include "panoramiXsrv.h"
54#endif
55
56#include <stdint.h>
57
58static int ProcRenderQueryVersion(ClientPtr pClient);
59static int ProcRenderQueryPictFormats(ClientPtr pClient);
60static int ProcRenderQueryPictIndexValues(ClientPtr pClient);
61static int ProcRenderQueryDithers(ClientPtr pClient);
62static int ProcRenderCreatePicture(ClientPtr pClient);
63static int ProcRenderChangePicture(ClientPtr pClient);
64static int ProcRenderSetPictureClipRectangles(ClientPtr pClient);
65static int ProcRenderFreePicture(ClientPtr pClient);
66static int ProcRenderComposite(ClientPtr pClient);
67static int ProcRenderScale(ClientPtr pClient);
68static int ProcRenderTrapezoids(ClientPtr pClient);
69static int ProcRenderTriangles(ClientPtr pClient);
70static int ProcRenderTriStrip(ClientPtr pClient);
71static int ProcRenderTriFan(ClientPtr pClient);
72static int ProcRenderColorTrapezoids(ClientPtr pClient);
73static int ProcRenderColorTriangles(ClientPtr pClient);
74static int ProcRenderTransform(ClientPtr pClient);
75static int ProcRenderCreateGlyphSet(ClientPtr pClient);
76static int ProcRenderReferenceGlyphSet(ClientPtr pClient);
77static int ProcRenderFreeGlyphSet(ClientPtr pClient);
78static int ProcRenderAddGlyphs(ClientPtr pClient);
79static int ProcRenderAddGlyphsFromPicture(ClientPtr pClient);
80static int ProcRenderFreeGlyphs(ClientPtr pClient);
81static int ProcRenderCompositeGlyphs(ClientPtr pClient);
82static int ProcRenderFillRectangles(ClientPtr pClient);
83static int ProcRenderCreateCursor(ClientPtr pClient);
84static int ProcRenderSetPictureTransform(ClientPtr pClient);
85static int ProcRenderQueryFilters(ClientPtr pClient);
86static int ProcRenderSetPictureFilter(ClientPtr pClient);
87static int ProcRenderCreateAnimCursor(ClientPtr pClient);
88static int ProcRenderAddTraps(ClientPtr pClient);
89static int ProcRenderCreateSolidFill(ClientPtr pClient);
90static int ProcRenderCreateLinearGradient(ClientPtr pClient);
91static int ProcRenderCreateRadialGradient(ClientPtr pClient);
92static int ProcRenderCreateConicalGradient(ClientPtr pClient);
93
94static int ProcRenderDispatch(ClientPtr pClient);
95
96static int SProcRenderQueryVersion(ClientPtr pClient);
97static int SProcRenderQueryPictFormats(ClientPtr pClient);
98static int SProcRenderQueryPictIndexValues(ClientPtr pClient);
99static int SProcRenderQueryDithers(ClientPtr pClient);
100static int SProcRenderCreatePicture(ClientPtr pClient);
101static int SProcRenderChangePicture(ClientPtr pClient);
102static int SProcRenderSetPictureClipRectangles(ClientPtr pClient);
103static int SProcRenderFreePicture(ClientPtr pClient);
104static int SProcRenderComposite(ClientPtr pClient);
105static int SProcRenderScale(ClientPtr pClient);
106static int SProcRenderTrapezoids(ClientPtr pClient);
107static int SProcRenderTriangles(ClientPtr pClient);
108static int SProcRenderTriStrip(ClientPtr pClient);
109static int SProcRenderTriFan(ClientPtr pClient);
110static int SProcRenderColorTrapezoids(ClientPtr pClient);
111static int SProcRenderColorTriangles(ClientPtr pClient);
112static int SProcRenderTransform(ClientPtr pClient);
113static int SProcRenderCreateGlyphSet(ClientPtr pClient);
114static int SProcRenderReferenceGlyphSet(ClientPtr pClient);
115static int SProcRenderFreeGlyphSet(ClientPtr pClient);
116static int SProcRenderAddGlyphs(ClientPtr pClient);
117static int SProcRenderAddGlyphsFromPicture(ClientPtr pClient);
118static int SProcRenderFreeGlyphs(ClientPtr pClient);
119static int SProcRenderCompositeGlyphs(ClientPtr pClient);
120static int SProcRenderFillRectangles(ClientPtr pClient);
121static int SProcRenderCreateCursor(ClientPtr pClient);
122static int SProcRenderSetPictureTransform(ClientPtr pClient);
123static int SProcRenderQueryFilters(ClientPtr pClient);
124static int SProcRenderSetPictureFilter(ClientPtr pClient);
125static int SProcRenderCreateAnimCursor(ClientPtr pClient);
126static int SProcRenderAddTraps(ClientPtr pClient);
127static int SProcRenderCreateSolidFill(ClientPtr pClient);
128static int SProcRenderCreateLinearGradient(ClientPtr pClient);
129static int SProcRenderCreateRadialGradient(ClientPtr pClient);
130static int SProcRenderCreateConicalGradient(ClientPtr pClient);
131
132static int SProcRenderDispatch(ClientPtr pClient);
133
134int (*ProcRenderVector[RenderNumberRequests]) (ClientPtr) = {
135ProcRenderQueryVersion,
136        ProcRenderQueryPictFormats,
137        ProcRenderQueryPictIndexValues,
138        ProcRenderQueryDithers,
139        ProcRenderCreatePicture,
140        ProcRenderChangePicture,
141        ProcRenderSetPictureClipRectangles,
142        ProcRenderFreePicture,
143        ProcRenderComposite,
144        ProcRenderScale,
145        ProcRenderTrapezoids,
146        ProcRenderTriangles,
147        ProcRenderTriStrip,
148        ProcRenderTriFan,
149        ProcRenderColorTrapezoids,
150        ProcRenderColorTriangles,
151        ProcRenderTransform,
152        ProcRenderCreateGlyphSet,
153        ProcRenderReferenceGlyphSet,
154        ProcRenderFreeGlyphSet,
155        ProcRenderAddGlyphs,
156        ProcRenderAddGlyphsFromPicture,
157        ProcRenderFreeGlyphs,
158        ProcRenderCompositeGlyphs,
159        ProcRenderCompositeGlyphs,
160        ProcRenderCompositeGlyphs,
161        ProcRenderFillRectangles,
162        ProcRenderCreateCursor,
163        ProcRenderSetPictureTransform,
164        ProcRenderQueryFilters,
165        ProcRenderSetPictureFilter,
166        ProcRenderCreateAnimCursor,
167        ProcRenderAddTraps,
168        ProcRenderCreateSolidFill,
169        ProcRenderCreateLinearGradient,
170        ProcRenderCreateRadialGradient, ProcRenderCreateConicalGradient};
171
172int (*SProcRenderVector[RenderNumberRequests]) (ClientPtr) = {
173SProcRenderQueryVersion,
174        SProcRenderQueryPictFormats,
175        SProcRenderQueryPictIndexValues,
176        SProcRenderQueryDithers,
177        SProcRenderCreatePicture,
178        SProcRenderChangePicture,
179        SProcRenderSetPictureClipRectangles,
180        SProcRenderFreePicture,
181        SProcRenderComposite,
182        SProcRenderScale,
183        SProcRenderTrapezoids,
184        SProcRenderTriangles,
185        SProcRenderTriStrip,
186        SProcRenderTriFan,
187        SProcRenderColorTrapezoids,
188        SProcRenderColorTriangles,
189        SProcRenderTransform,
190        SProcRenderCreateGlyphSet,
191        SProcRenderReferenceGlyphSet,
192        SProcRenderFreeGlyphSet,
193        SProcRenderAddGlyphs,
194        SProcRenderAddGlyphsFromPicture,
195        SProcRenderFreeGlyphs,
196        SProcRenderCompositeGlyphs,
197        SProcRenderCompositeGlyphs,
198        SProcRenderCompositeGlyphs,
199        SProcRenderFillRectangles,
200        SProcRenderCreateCursor,
201        SProcRenderSetPictureTransform,
202        SProcRenderQueryFilters,
203        SProcRenderSetPictureFilter,
204        SProcRenderCreateAnimCursor,
205        SProcRenderAddTraps,
206        SProcRenderCreateSolidFill,
207        SProcRenderCreateLinearGradient,
208        SProcRenderCreateRadialGradient, SProcRenderCreateConicalGradient};
209
210int RenderErrBase;
211static DevPrivateKeyRec RenderClientPrivateKeyRec;
212
213#define RenderClientPrivateKey (&RenderClientPrivateKeyRec )
214
215typedef struct _RenderClient {
216    int major_version;
217    int minor_version;
218} RenderClientRec, *RenderClientPtr;
219
220#define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey))
221
222#ifdef PANORAMIX
223RESTYPE XRT_PICTURE;
224#endif
225
226void
227RenderExtensionInit(void)
228{
229    ExtensionEntry *extEntry;
230
231    if (!PictureType)
232        return;
233    if (!PictureFinishInit())
234        return;
235    if (!dixRegisterPrivateKey
236        (&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec)))
237        return;
238
239    extEntry = AddExtension(RENDER_NAME, 0, RenderNumberErrors,
240                            ProcRenderDispatch, SProcRenderDispatch,
241                            NULL, StandardMinorOpcode);
242    if (!extEntry)
243        return;
244    RenderErrBase = extEntry->errorBase;
245#ifdef PANORAMIX
246    if (XRT_PICTURE)
247        SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
248#endif
249    SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture);
250    SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat);
251    SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet);
252}
253
254static int
255ProcRenderQueryVersion(ClientPtr client)
256{
257    RenderClientPtr pRenderClient = GetRenderClient(client);
258    xRenderQueryVersionReply rep = {
259        .type = X_Reply,
260        .sequenceNumber = client->sequence,
261        .length = 0
262    };
263
264    REQUEST(xRenderQueryVersionReq);
265
266    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
267
268    pRenderClient->major_version = stuff->majorVersion;
269    pRenderClient->minor_version = stuff->minorVersion;
270
271    if ((stuff->majorVersion * 1000 + stuff->minorVersion) <
272        (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) {
273        rep.majorVersion = stuff->majorVersion;
274        rep.minorVersion = stuff->minorVersion;
275    }
276    else {
277        rep.majorVersion = SERVER_RENDER_MAJOR_VERSION;
278        rep.minorVersion = SERVER_RENDER_MINOR_VERSION;
279    }
280
281    if (client->swapped) {
282        swaps(&rep.sequenceNumber);
283        swapl(&rep.length);
284        swapl(&rep.majorVersion);
285        swapl(&rep.minorVersion);
286    }
287    WriteToClient(client, sizeof(xRenderQueryVersionReply), &rep);
288    return Success;
289}
290
291static VisualPtr
292findVisual(ScreenPtr pScreen, VisualID vid)
293{
294    VisualPtr pVisual;
295    int v;
296
297    for (v = 0; v < pScreen->numVisuals; v++) {
298        pVisual = pScreen->visuals + v;
299        if (pVisual->vid == vid)
300            return pVisual;
301    }
302    return 0;
303}
304
305static int
306ProcRenderQueryPictFormats(ClientPtr client)
307{
308    RenderClientPtr pRenderClient = GetRenderClient(client);
309    xRenderQueryPictFormatsReply *reply;
310    xPictScreen *pictScreen;
311    xPictDepth *pictDepth;
312    xPictVisual *pictVisual;
313    xPictFormInfo *pictForm;
314    CARD32 *pictSubpixel;
315    ScreenPtr pScreen;
316    VisualPtr pVisual;
317    DepthPtr pDepth;
318    int v, d;
319    PictureScreenPtr ps;
320    PictFormatPtr pFormat;
321    int nformat;
322    int ndepth;
323    int nvisual;
324    int rlength;
325    int s;
326    int numScreens;
327    int numSubpixel;
328
329/*    REQUEST(xRenderQueryPictFormatsReq); */
330
331    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
332
333#ifdef PANORAMIX
334    if (noPanoramiXExtension)
335        numScreens = screenInfo.numScreens;
336    else
337        numScreens = ((xConnSetup *) ConnectionInfo)->numRoots;
338#else
339    numScreens = screenInfo.numScreens;
340#endif
341    ndepth = nformat = nvisual = 0;
342    for (s = 0; s < numScreens; s++) {
343        pScreen = screenInfo.screens[s];
344        for (d = 0; d < pScreen->numDepths; d++) {
345            pDepth = pScreen->allowedDepths + d;
346            ++ndepth;
347
348            for (v = 0; v < pDepth->numVids; v++) {
349                pVisual = findVisual(pScreen, pDepth->vids[v]);
350                if (pVisual &&
351                    PictureMatchVisual(pScreen, pDepth->depth, pVisual))
352                    ++nvisual;
353            }
354        }
355        ps = GetPictureScreenIfSet(pScreen);
356        if (ps)
357            nformat += ps->nformats;
358    }
359    if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
360        numSubpixel = 0;
361    else
362        numSubpixel = numScreens;
363
364    rlength = (sizeof(xRenderQueryPictFormatsReply) +
365               nformat * sizeof(xPictFormInfo) +
366               numScreens * sizeof(xPictScreen) +
367               ndepth * sizeof(xPictDepth) +
368               nvisual * sizeof(xPictVisual) + numSubpixel * sizeof(CARD32));
369    reply = (xRenderQueryPictFormatsReply *) calloc(1, rlength);
370    if (!reply)
371        return BadAlloc;
372    reply->type = X_Reply;
373    reply->sequenceNumber = client->sequence;
374    reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
375    reply->numFormats = nformat;
376    reply->numScreens = numScreens;
377    reply->numDepths = ndepth;
378    reply->numVisuals = nvisual;
379    reply->numSubpixel = numSubpixel;
380
381    pictForm = (xPictFormInfo *) (reply + 1);
382
383    for (s = 0; s < numScreens; s++) {
384        pScreen = screenInfo.screens[s];
385        ps = GetPictureScreenIfSet(pScreen);
386        if (ps) {
387            for (nformat = 0, pFormat = ps->formats;
388                 nformat < ps->nformats; nformat++, pFormat++) {
389                pictForm->id = pFormat->id;
390                pictForm->type = pFormat->type;
391                pictForm->depth = pFormat->depth;
392                pictForm->direct.red = pFormat->direct.red;
393                pictForm->direct.redMask = pFormat->direct.redMask;
394                pictForm->direct.green = pFormat->direct.green;
395                pictForm->direct.greenMask = pFormat->direct.greenMask;
396                pictForm->direct.blue = pFormat->direct.blue;
397                pictForm->direct.blueMask = pFormat->direct.blueMask;
398                pictForm->direct.alpha = pFormat->direct.alpha;
399                pictForm->direct.alphaMask = pFormat->direct.alphaMask;
400                if (pFormat->type == PictTypeIndexed &&
401                    pFormat->index.pColormap)
402                    pictForm->colormap = pFormat->index.pColormap->mid;
403                else
404                    pictForm->colormap = None;
405                if (client->swapped) {
406                    swapl(&pictForm->id);
407                    swaps(&pictForm->direct.red);
408                    swaps(&pictForm->direct.redMask);
409                    swaps(&pictForm->direct.green);
410                    swaps(&pictForm->direct.greenMask);
411                    swaps(&pictForm->direct.blue);
412                    swaps(&pictForm->direct.blueMask);
413                    swaps(&pictForm->direct.alpha);
414                    swaps(&pictForm->direct.alphaMask);
415                    swapl(&pictForm->colormap);
416                }
417                pictForm++;
418            }
419        }
420    }
421
422    pictScreen = (xPictScreen *) pictForm;
423    for (s = 0; s < numScreens; s++) {
424        pScreen = screenInfo.screens[s];
425        pictDepth = (xPictDepth *) (pictScreen + 1);
426        ndepth = 0;
427        for (d = 0; d < pScreen->numDepths; d++) {
428            pictVisual = (xPictVisual *) (pictDepth + 1);
429            pDepth = pScreen->allowedDepths + d;
430
431            nvisual = 0;
432            for (v = 0; v < pDepth->numVids; v++) {
433                pVisual = findVisual(pScreen, pDepth->vids[v]);
434                if (pVisual && (pFormat = PictureMatchVisual(pScreen,
435                                                             pDepth->depth,
436                                                             pVisual))) {
437                    pictVisual->visual = pVisual->vid;
438                    pictVisual->format = pFormat->id;
439                    if (client->swapped) {
440                        swapl(&pictVisual->visual);
441                        swapl(&pictVisual->format);
442                    }
443                    pictVisual++;
444                    nvisual++;
445                }
446            }
447            pictDepth->depth = pDepth->depth;
448            pictDepth->nPictVisuals = nvisual;
449            if (client->swapped) {
450                swaps(&pictDepth->nPictVisuals);
451            }
452            ndepth++;
453            pictDepth = (xPictDepth *) pictVisual;
454        }
455        pictScreen->nDepth = ndepth;
456        ps = GetPictureScreenIfSet(pScreen);
457        if (ps)
458            pictScreen->fallback = ps->fallback->id;
459        else
460            pictScreen->fallback = 0;
461        if (client->swapped) {
462            swapl(&pictScreen->nDepth);
463            swapl(&pictScreen->fallback);
464        }
465        pictScreen = (xPictScreen *) pictDepth;
466    }
467    pictSubpixel = (CARD32 *) pictScreen;
468
469    for (s = 0; s < numSubpixel; s++) {
470        pScreen = screenInfo.screens[s];
471        ps = GetPictureScreenIfSet(pScreen);
472        if (ps)
473            *pictSubpixel = ps->subpixel;
474        else
475            *pictSubpixel = SubPixelUnknown;
476        if (client->swapped) {
477            swapl(pictSubpixel);
478        }
479        ++pictSubpixel;
480    }
481
482    if (client->swapped) {
483        swaps(&reply->sequenceNumber);
484        swapl(&reply->length);
485        swapl(&reply->numFormats);
486        swapl(&reply->numScreens);
487        swapl(&reply->numDepths);
488        swapl(&reply->numVisuals);
489        swapl(&reply->numSubpixel);
490    }
491    WriteToClient(client, rlength, reply);
492    free(reply);
493    return Success;
494}
495
496static int
497ProcRenderQueryPictIndexValues(ClientPtr client)
498{
499    PictFormatPtr pFormat;
500    int rc, num;
501    int rlength;
502    int i;
503
504    REQUEST(xRenderQueryPictIndexValuesReq);
505    xRenderQueryPictIndexValuesReply *reply;
506    xIndexValue *values;
507
508    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
509
510    rc = dixLookupResourceByType((void **) &pFormat, stuff->format,
511                                 PictFormatType, client, DixReadAccess);
512    if (rc != Success)
513        return rc;
514
515    if (pFormat->type != PictTypeIndexed) {
516        client->errorValue = stuff->format;
517        return BadMatch;
518    }
519    num = pFormat->index.nvalues;
520    rlength = (sizeof(xRenderQueryPictIndexValuesReply) +
521               num * sizeof(xIndexValue));
522    reply = (xRenderQueryPictIndexValuesReply *) calloc(1, rlength);
523    if (!reply)
524        return BadAlloc;
525
526    reply->type = X_Reply;
527    reply->sequenceNumber = client->sequence;
528    reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
529    reply->numIndexValues = num;
530
531    values = (xIndexValue *) (reply + 1);
532
533    memcpy(reply + 1, pFormat->index.pValues, num * sizeof(xIndexValue));
534
535    if (client->swapped) {
536        for (i = 0; i < num; i++) {
537            swapl(&values[i].pixel);
538            swaps(&values[i].red);
539            swaps(&values[i].green);
540            swaps(&values[i].blue);
541            swaps(&values[i].alpha);
542        }
543        swaps(&reply->sequenceNumber);
544        swapl(&reply->length);
545        swapl(&reply->numIndexValues);
546    }
547
548    WriteToClient(client, rlength, reply);
549    free(reply);
550    return Success;
551}
552
553static int
554ProcRenderQueryDithers(ClientPtr client)
555{
556    return BadImplementation;
557}
558
559static int
560ProcRenderCreatePicture(ClientPtr client)
561{
562    PicturePtr pPicture;
563    DrawablePtr pDrawable;
564    PictFormatPtr pFormat;
565    int len, error, rc;
566
567    REQUEST(xRenderCreatePictureReq);
568
569    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
570
571    LEGAL_NEW_RESOURCE(stuff->pid, client);
572    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
573                           DixReadAccess | DixAddAccess);
574    if (rc != Success)
575        return rc;
576
577    rc = dixLookupResourceByType((void **) &pFormat, stuff->format,
578                                 PictFormatType, client, DixReadAccess);
579    if (rc != Success)
580        return rc;
581
582    if (pFormat->depth != pDrawable->depth)
583        return BadMatch;
584    len = client->req_len - bytes_to_int32(sizeof(xRenderCreatePictureReq));
585    if (Ones(stuff->mask) != len)
586        return BadLength;
587
588    pPicture = CreatePicture(stuff->pid,
589                             pDrawable,
590                             pFormat,
591                             stuff->mask, (XID *) (stuff + 1), client, &error);
592    if (!pPicture)
593        return error;
594    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
595        return BadAlloc;
596    return Success;
597}
598
599static int
600ProcRenderChangePicture(ClientPtr client)
601{
602    PicturePtr pPicture;
603
604    REQUEST(xRenderChangePictureReq);
605    int len;
606
607    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
608    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
609
610    len = client->req_len - bytes_to_int32(sizeof(xRenderChangePictureReq));
611    if (Ones(stuff->mask) != len)
612        return BadLength;
613
614    return ChangePicture(pPicture, stuff->mask, (XID *) (stuff + 1),
615                         (DevUnion *) 0, client);
616}
617
618static int
619ProcRenderSetPictureClipRectangles(ClientPtr client)
620{
621    REQUEST(xRenderSetPictureClipRectanglesReq);
622    PicturePtr pPicture;
623    int nr;
624
625    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
626    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
627    if (!pPicture->pDrawable)
628        return RenderErrBase + BadPicture;
629
630    nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
631    if (nr & 4)
632        return BadLength;
633    nr >>= 3;
634    return SetPictureClipRects(pPicture,
635                               stuff->xOrigin, stuff->yOrigin,
636                               nr, (xRectangle *) &stuff[1]);
637}
638
639static int
640ProcRenderFreePicture(ClientPtr client)
641{
642    PicturePtr pPicture;
643
644    REQUEST(xRenderFreePictureReq);
645
646    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
647
648    VERIFY_PICTURE(pPicture, stuff->picture, client, DixDestroyAccess);
649    FreeResource(stuff->picture, RT_NONE);
650    return Success;
651}
652
653static Bool
654PictOpValid(CARD8 op)
655{
656    if ( /*PictOpMinimum <= op && */ op <= PictOpMaximum)
657        return TRUE;
658    if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
659        return TRUE;
660    if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
661        return TRUE;
662    if (PictOpBlendMinimum <= op && op <= PictOpBlendMaximum)
663        return TRUE;
664    return FALSE;
665}
666
667static int
668ProcRenderComposite(ClientPtr client)
669{
670    PicturePtr pSrc, pMask, pDst;
671
672    REQUEST(xRenderCompositeReq);
673
674    REQUEST_SIZE_MATCH(xRenderCompositeReq);
675    if (!PictOpValid(stuff->op)) {
676        client->errorValue = stuff->op;
677        return BadValue;
678    }
679    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
680    if (!pDst->pDrawable)
681        return BadDrawable;
682    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
683    VERIFY_ALPHA(pMask, stuff->mask, client, DixReadAccess);
684    if ((pSrc->pDrawable &&
685         pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) || (pMask &&
686                                                                   pMask->
687                                                                   pDrawable &&
688                                                                   pDst->
689                                                                   pDrawable->
690                                                                   pScreen !=
691                                                                   pMask->
692                                                                   pDrawable->
693                                                                   pScreen))
694        return BadMatch;
695    CompositePicture(stuff->op,
696                     pSrc,
697                     pMask,
698                     pDst,
699                     stuff->xSrc,
700                     stuff->ySrc,
701                     stuff->xMask,
702                     stuff->yMask,
703                     stuff->xDst, stuff->yDst, stuff->width, stuff->height);
704    return Success;
705}
706
707static int
708ProcRenderScale(ClientPtr client)
709{
710    return BadImplementation;
711}
712
713static int
714ProcRenderTrapezoids(ClientPtr client)
715{
716    int rc, ntraps;
717    PicturePtr pSrc, pDst;
718    PictFormatPtr pFormat;
719
720    REQUEST(xRenderTrapezoidsReq);
721
722    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
723    if (!PictOpValid(stuff->op)) {
724        client->errorValue = stuff->op;
725        return BadValue;
726    }
727    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
728    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
729    if (!pDst->pDrawable)
730        return BadDrawable;
731    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
732        return BadMatch;
733    if (stuff->maskFormat) {
734        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
735                                     PictFormatType, client, DixReadAccess);
736        if (rc != Success)
737            return rc;
738    }
739    else
740        pFormat = 0;
741    ntraps = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq);
742    if (ntraps % sizeof(xTrapezoid))
743        return BadLength;
744    ntraps /= sizeof(xTrapezoid);
745    if (ntraps)
746        CompositeTrapezoids(stuff->op, pSrc, pDst, pFormat,
747                            stuff->xSrc, stuff->ySrc,
748                            ntraps, (xTrapezoid *) &stuff[1]);
749    return Success;
750}
751
752static int
753ProcRenderTriangles(ClientPtr client)
754{
755    int rc, ntris;
756    PicturePtr pSrc, pDst;
757    PictFormatPtr pFormat;
758
759    REQUEST(xRenderTrianglesReq);
760
761    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
762    if (!PictOpValid(stuff->op)) {
763        client->errorValue = stuff->op;
764        return BadValue;
765    }
766    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
767    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
768    if (!pDst->pDrawable)
769        return BadDrawable;
770    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
771        return BadMatch;
772    if (stuff->maskFormat) {
773        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
774                                     PictFormatType, client, DixReadAccess);
775        if (rc != Success)
776            return rc;
777    }
778    else
779        pFormat = 0;
780    ntris = (client->req_len << 2) - sizeof(xRenderTrianglesReq);
781    if (ntris % sizeof(xTriangle))
782        return BadLength;
783    ntris /= sizeof(xTriangle);
784    if (ntris)
785        CompositeTriangles(stuff->op, pSrc, pDst, pFormat,
786                           stuff->xSrc, stuff->ySrc,
787                           ntris, (xTriangle *) &stuff[1]);
788    return Success;
789}
790
791static int
792ProcRenderTriStrip(ClientPtr client)
793{
794    int rc, npoints;
795    PicturePtr pSrc, pDst;
796    PictFormatPtr pFormat;
797
798    REQUEST(xRenderTrianglesReq);
799
800    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
801    if (!PictOpValid(stuff->op)) {
802        client->errorValue = stuff->op;
803        return BadValue;
804    }
805    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
806    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
807    if (!pDst->pDrawable)
808        return BadDrawable;
809    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
810        return BadMatch;
811    if (stuff->maskFormat) {
812        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
813                                     PictFormatType, client, DixReadAccess);
814        if (rc != Success)
815            return rc;
816    }
817    else
818        pFormat = 0;
819    npoints = ((client->req_len << 2) - sizeof(xRenderTriStripReq));
820    if (npoints & 4)
821        return BadLength;
822    npoints >>= 3;
823    if (npoints >= 3)
824        CompositeTriStrip(stuff->op, pSrc, pDst, pFormat,
825                          stuff->xSrc, stuff->ySrc,
826                          npoints, (xPointFixed *) &stuff[1]);
827    return Success;
828}
829
830static int
831ProcRenderTriFan(ClientPtr client)
832{
833    int rc, npoints;
834    PicturePtr pSrc, pDst;
835    PictFormatPtr pFormat;
836
837    REQUEST(xRenderTrianglesReq);
838
839    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
840    if (!PictOpValid(stuff->op)) {
841        client->errorValue = stuff->op;
842        return BadValue;
843    }
844    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
845    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
846    if (!pDst->pDrawable)
847        return BadDrawable;
848    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
849        return BadMatch;
850    if (stuff->maskFormat) {
851        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
852                                     PictFormatType, client, DixReadAccess);
853        if (rc != Success)
854            return rc;
855    }
856    else
857        pFormat = 0;
858    npoints = ((client->req_len << 2) - sizeof(xRenderTriStripReq));
859    if (npoints & 4)
860        return BadLength;
861    npoints >>= 3;
862    if (npoints >= 3)
863        CompositeTriFan(stuff->op, pSrc, pDst, pFormat,
864                        stuff->xSrc, stuff->ySrc,
865                        npoints, (xPointFixed *) &stuff[1]);
866    return Success;
867}
868
869static int
870ProcRenderColorTrapezoids(ClientPtr client)
871{
872    return BadImplementation;
873}
874
875static int
876ProcRenderColorTriangles(ClientPtr client)
877{
878    return BadImplementation;
879}
880
881static int
882ProcRenderTransform(ClientPtr client)
883{
884    return BadImplementation;
885}
886
887static int
888ProcRenderCreateGlyphSet(ClientPtr client)
889{
890    GlyphSetPtr glyphSet;
891    PictFormatPtr format;
892    int rc, f;
893
894    REQUEST(xRenderCreateGlyphSetReq);
895
896    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
897
898    LEGAL_NEW_RESOURCE(stuff->gsid, client);
899    rc = dixLookupResourceByType((void **) &format, stuff->format,
900                                 PictFormatType, client, DixReadAccess);
901    if (rc != Success)
902        return rc;
903
904    switch (format->depth) {
905    case 1:
906        f = GlyphFormat1;
907        break;
908    case 4:
909        f = GlyphFormat4;
910        break;
911    case 8:
912        f = GlyphFormat8;
913        break;
914    case 16:
915        f = GlyphFormat16;
916        break;
917    case 32:
918        f = GlyphFormat32;
919        break;
920    default:
921        return BadMatch;
922    }
923    if (format->type != PictTypeDirect)
924        return BadMatch;
925    glyphSet = AllocateGlyphSet(f, format);
926    if (!glyphSet)
927        return BadAlloc;
928    /* security creation/labeling check */
929    rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType,
930                  glyphSet, RT_NONE, NULL, DixCreateAccess);
931    if (rc != Success)
932        return rc;
933    if (!AddResource(stuff->gsid, GlyphSetType, (void *) glyphSet))
934        return BadAlloc;
935    return Success;
936}
937
938static int
939ProcRenderReferenceGlyphSet(ClientPtr client)
940{
941    GlyphSetPtr glyphSet;
942    int rc;
943
944    REQUEST(xRenderReferenceGlyphSetReq);
945
946    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
947
948    LEGAL_NEW_RESOURCE(stuff->gsid, client);
949
950    rc = dixLookupResourceByType((void **) &glyphSet, stuff->existing,
951                                 GlyphSetType, client, DixGetAttrAccess);
952    if (rc != Success) {
953        client->errorValue = stuff->existing;
954        return rc;
955    }
956    glyphSet->refcnt++;
957    if (!AddResource(stuff->gsid, GlyphSetType, (void *) glyphSet))
958        return BadAlloc;
959    return Success;
960}
961
962#define NLOCALDELTA	64
963#define NLOCALGLYPH	256
964
965static int
966ProcRenderFreeGlyphSet(ClientPtr client)
967{
968    GlyphSetPtr glyphSet;
969    int rc;
970
971    REQUEST(xRenderFreeGlyphSetReq);
972
973    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
974    rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
975                                 GlyphSetType, client, DixDestroyAccess);
976    if (rc != Success) {
977        client->errorValue = stuff->glyphset;
978        return rc;
979    }
980    FreeResource(stuff->glyphset, RT_NONE);
981    return Success;
982}
983
984typedef struct _GlyphNew {
985    Glyph id;
986    GlyphPtr glyph;
987    Bool found;
988    unsigned char sha1[20];
989} GlyphNewRec, *GlyphNewPtr;
990
991#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
992
993static int
994ProcRenderAddGlyphs(ClientPtr client)
995{
996    GlyphSetPtr glyphSet;
997
998    REQUEST(xRenderAddGlyphsReq);
999    GlyphNewRec glyphsLocal[NLOCALGLYPH];
1000    GlyphNewPtr glyphsBase, glyphs, glyph_new;
1001    int remain, nglyphs;
1002    CARD32 *gids;
1003    xGlyphInfo *gi;
1004    CARD8 *bits;
1005    unsigned int size;
1006    int err;
1007    int i, screen;
1008    PicturePtr pSrc = NULL, pDst = NULL;
1009    PixmapPtr pSrcPix = NULL, pDstPix = NULL;
1010    CARD32 component_alpha;
1011
1012    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
1013    err =
1014        dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
1015                                GlyphSetType, client, DixAddAccess);
1016    if (err != Success) {
1017        client->errorValue = stuff->glyphset;
1018        return err;
1019    }
1020
1021    err = BadAlloc;
1022    nglyphs = stuff->nglyphs;
1023    if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
1024        return BadAlloc;
1025
1026    component_alpha = NeedsComponent(glyphSet->format->format);
1027
1028    if (nglyphs <= NLOCALGLYPH) {
1029        memset(glyphsLocal, 0, sizeof(glyphsLocal));
1030        glyphsBase = glyphsLocal;
1031    }
1032    else {
1033        glyphsBase = (GlyphNewPtr) calloc(nglyphs, sizeof(GlyphNewRec));
1034        if (!glyphsBase)
1035            return BadAlloc;
1036    }
1037
1038    remain = (client->req_len << 2) - sizeof(xRenderAddGlyphsReq);
1039
1040    glyphs = glyphsBase;
1041
1042    gids = (CARD32 *) (stuff + 1);
1043    gi = (xGlyphInfo *) (gids + nglyphs);
1044    bits = (CARD8 *) (gi + nglyphs);
1045    remain -= (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs;
1046
1047    /* protect against bad nglyphs */
1048    if (gi < ((xGlyphInfo *) stuff) ||
1049        gi > ((xGlyphInfo *) ((CARD32 *) stuff + client->req_len)) ||
1050        bits < ((CARD8 *) stuff) ||
1051        bits > ((CARD8 *) ((CARD32 *) stuff + client->req_len))) {
1052        err = BadLength;
1053        goto bail;
1054    }
1055
1056    for (i = 0; i < nglyphs; i++) {
1057        size_t padded_width;
1058
1059        glyph_new = &glyphs[i];
1060
1061        padded_width = PixmapBytePad(gi[i].width, glyphSet->format->depth);
1062
1063        if (gi[i].height &&
1064            padded_width > (UINT32_MAX - sizeof(GlyphRec)) / gi[i].height)
1065            break;
1066
1067        size = gi[i].height * padded_width;
1068        if (remain < size)
1069            break;
1070
1071        err = HashGlyph(&gi[i], bits, size, glyph_new->sha1);
1072        if (err)
1073            goto bail;
1074
1075        glyph_new->glyph = FindGlyphByHash(glyph_new->sha1, glyphSet->fdepth);
1076
1077        if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) {
1078            glyph_new->found = TRUE;
1079            ++glyph_new->glyph->refcnt;
1080        }
1081        else {
1082            GlyphPtr glyph;
1083
1084            glyph_new->found = FALSE;
1085            glyph_new->glyph = glyph = AllocateGlyph(&gi[i], glyphSet->fdepth);
1086            if (!glyph) {
1087                err = BadAlloc;
1088                goto bail;
1089            }
1090
1091            for (screen = 0; screen < screenInfo.numScreens; screen++) {
1092                int width = gi[i].width;
1093                int height = gi[i].height;
1094                int depth = glyphSet->format->depth;
1095                ScreenPtr pScreen;
1096                int error;
1097
1098                /* Skip work if it's invisibly small anyway */
1099                if (!width || !height)
1100                    break;
1101
1102                pScreen = screenInfo.screens[screen];
1103                pSrcPix = GetScratchPixmapHeader(pScreen,
1104                                                 width, height,
1105                                                 depth, depth, -1, bits);
1106                if (!pSrcPix) {
1107                    err = BadAlloc;
1108                    goto bail;
1109                }
1110
1111                pSrc = CreatePicture(0, &pSrcPix->drawable,
1112                                     glyphSet->format, 0, NULL,
1113                                     serverClient, &error);
1114                if (!pSrc) {
1115                    err = BadAlloc;
1116                    goto bail;
1117                }
1118
1119                pDstPix = (pScreen->CreatePixmap) (pScreen,
1120                                                   width, height, depth,
1121                                                   CREATE_PIXMAP_USAGE_GLYPH_PICTURE);
1122
1123                if (!pDstPix) {
1124                    err = BadAlloc;
1125                    goto bail;
1126                }
1127
1128                pDst = CreatePicture(0, &pDstPix->drawable,
1129                                  glyphSet->format,
1130                                  CPComponentAlpha, &component_alpha,
1131                                  serverClient, &error);
1132                SetGlyphPicture(glyph, pScreen, pDst);
1133
1134                /* The picture takes a reference to the pixmap, so we
1135                   drop ours. */
1136                (pScreen->DestroyPixmap) (pDstPix);
1137                pDstPix = NULL;
1138
1139                if (!pDst) {
1140                    err = BadAlloc;
1141                    goto bail;
1142                }
1143
1144                CompositePicture(PictOpSrc,
1145                                 pSrc,
1146                                 None, pDst, 0, 0, 0, 0, 0, 0, width, height);
1147
1148                FreePicture((void *) pSrc, 0);
1149                pSrc = NULL;
1150                FreeScratchPixmapHeader(pSrcPix);
1151                pSrcPix = NULL;
1152            }
1153
1154            memcpy(glyph_new->glyph->sha1, glyph_new->sha1, 20);
1155        }
1156
1157        glyph_new->id = gids[i];
1158
1159        if (size & 3)
1160            size += 4 - (size & 3);
1161        bits += size;
1162        remain -= size;
1163    }
1164    if (remain || i < nglyphs) {
1165        err = BadLength;
1166        goto bail;
1167    }
1168    if (!ResizeGlyphSet(glyphSet, nglyphs)) {
1169        err = BadAlloc;
1170        goto bail;
1171    }
1172    for (i = 0; i < nglyphs; i++) {
1173        AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id);
1174        FreeGlyph(glyphs[i].glyph, glyphSet->fdepth);
1175    }
1176
1177    if (glyphsBase != glyphsLocal)
1178        free(glyphsBase);
1179    return Success;
1180 bail:
1181    if (pSrc)
1182        FreePicture((void *) pSrc, 0);
1183    if (pSrcPix)
1184        FreeScratchPixmapHeader(pSrcPix);
1185    for (i = 0; i < nglyphs; i++) {
1186        if (glyphs[i].glyph) {
1187            --glyphs[i].glyph->refcnt;
1188            if (!glyphs[i].found)
1189                free(glyphs[i].glyph);
1190        }
1191    }
1192    if (glyphsBase != glyphsLocal)
1193        free(glyphsBase);
1194    return err;
1195}
1196
1197static int
1198ProcRenderAddGlyphsFromPicture(ClientPtr client)
1199{
1200    return BadImplementation;
1201}
1202
1203static int
1204ProcRenderFreeGlyphs(ClientPtr client)
1205{
1206    REQUEST(xRenderFreeGlyphsReq);
1207    GlyphSetPtr glyphSet;
1208    int rc, nglyph;
1209    CARD32 *gids;
1210    CARD32 glyph;
1211
1212    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
1213    rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
1214                                 GlyphSetType, client, DixRemoveAccess);
1215    if (rc != Success) {
1216        client->errorValue = stuff->glyphset;
1217        return rc;
1218    }
1219    nglyph =
1220        bytes_to_int32((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq));
1221    gids = (CARD32 *) (stuff + 1);
1222    while (nglyph-- > 0) {
1223        glyph = *gids++;
1224        if (!DeleteGlyph(glyphSet, glyph)) {
1225            client->errorValue = glyph;
1226            return RenderErrBase + BadGlyph;
1227        }
1228    }
1229    return Success;
1230}
1231
1232static int
1233ProcRenderCompositeGlyphs(ClientPtr client)
1234{
1235    GlyphSetPtr glyphSet;
1236    GlyphSet gs;
1237    PicturePtr pSrc, pDst;
1238    PictFormatPtr pFormat;
1239    GlyphListRec listsLocal[NLOCALDELTA];
1240    GlyphListPtr lists, listsBase;
1241    GlyphPtr glyphsLocal[NLOCALGLYPH];
1242    Glyph glyph;
1243    GlyphPtr *glyphs, *glyphsBase;
1244    xGlyphElt *elt;
1245    CARD8 *buffer, *end;
1246    int nglyph;
1247    int nlist;
1248    int space;
1249    int size;
1250    int rc, n;
1251
1252    REQUEST(xRenderCompositeGlyphsReq);
1253
1254    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
1255
1256    switch (stuff->renderReqType) {
1257    default:
1258        size = 1;
1259        break;
1260    case X_RenderCompositeGlyphs16:
1261        size = 2;
1262        break;
1263    case X_RenderCompositeGlyphs32:
1264        size = 4;
1265        break;
1266    }
1267
1268    if (!PictOpValid(stuff->op)) {
1269        client->errorValue = stuff->op;
1270        return BadValue;
1271    }
1272    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
1273    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
1274    if (!pDst->pDrawable)
1275        return BadDrawable;
1276    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
1277        return BadMatch;
1278    if (stuff->maskFormat) {
1279        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
1280                                     PictFormatType, client, DixReadAccess);
1281        if (rc != Success)
1282            return rc;
1283    }
1284    else
1285        pFormat = 0;
1286
1287    rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
1288                                 GlyphSetType, client, DixUseAccess);
1289    if (rc != Success)
1290        return rc;
1291
1292    buffer = (CARD8 *) (stuff + 1);
1293    end = (CARD8 *) stuff + (client->req_len << 2);
1294    nglyph = 0;
1295    nlist = 0;
1296    while (buffer + sizeof(xGlyphElt) < end) {
1297        elt = (xGlyphElt *) buffer;
1298        buffer += sizeof(xGlyphElt);
1299
1300        if (elt->len == 0xff) {
1301            buffer += 4;
1302        }
1303        else {
1304            nlist++;
1305            nglyph += elt->len;
1306            space = size * elt->len;
1307            if (space & 3)
1308                space += 4 - (space & 3);
1309            buffer += space;
1310        }
1311    }
1312    if (nglyph <= NLOCALGLYPH)
1313        glyphsBase = glyphsLocal;
1314    else {
1315        glyphsBase = xallocarray(nglyph, sizeof(GlyphPtr));
1316        if (!glyphsBase)
1317            return BadAlloc;
1318    }
1319    if (nlist <= NLOCALDELTA)
1320        listsBase = listsLocal;
1321    else {
1322        listsBase = xallocarray(nlist, sizeof(GlyphListRec));
1323        if (!listsBase) {
1324            rc = BadAlloc;
1325            goto bail;
1326        }
1327    }
1328    buffer = (CARD8 *) (stuff + 1);
1329    glyphs = glyphsBase;
1330    lists = listsBase;
1331    while (buffer + sizeof(xGlyphElt) < end) {
1332        elt = (xGlyphElt *) buffer;
1333        buffer += sizeof(xGlyphElt);
1334
1335        if (elt->len == 0xff) {
1336            if (buffer + sizeof(GlyphSet) < end) {
1337                memcpy(&gs, buffer, sizeof(GlyphSet));
1338                rc = dixLookupResourceByType((void **) &glyphSet, gs,
1339                                             GlyphSetType, client,
1340                                             DixUseAccess);
1341                if (rc != Success)
1342                    goto bail;
1343            }
1344            buffer += 4;
1345        }
1346        else {
1347            lists->xOff = elt->deltax;
1348            lists->yOff = elt->deltay;
1349            lists->format = glyphSet->format;
1350            lists->len = 0;
1351            n = elt->len;
1352            while (n--) {
1353                if (buffer + size <= end) {
1354                    switch (size) {
1355                    case 1:
1356                        glyph = *((CARD8 *) buffer);
1357                        break;
1358                    case 2:
1359                        glyph = *((CARD16 *) buffer);
1360                        break;
1361                    case 4:
1362                    default:
1363                        glyph = *((CARD32 *) buffer);
1364                        break;
1365                    }
1366                    if ((*glyphs = FindGlyph(glyphSet, glyph))) {
1367                        lists->len++;
1368                        glyphs++;
1369                    }
1370                }
1371                buffer += size;
1372            }
1373            space = size * elt->len;
1374            if (space & 3)
1375                buffer += 4 - (space & 3);
1376            lists++;
1377        }
1378    }
1379    if (buffer > end) {
1380        rc = BadLength;
1381        goto bail;
1382    }
1383
1384    CompositeGlyphs(stuff->op,
1385                    pSrc,
1386                    pDst,
1387                    pFormat,
1388                    stuff->xSrc, stuff->ySrc, nlist, listsBase, glyphsBase);
1389    rc = Success;
1390
1391 bail:
1392    if (glyphsBase != glyphsLocal)
1393        free(glyphsBase);
1394    if (listsBase != listsLocal)
1395        free(listsBase);
1396    return rc;
1397}
1398
1399static int
1400ProcRenderFillRectangles(ClientPtr client)
1401{
1402    PicturePtr pDst;
1403    int things;
1404
1405    REQUEST(xRenderFillRectanglesReq);
1406
1407    REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
1408    if (!PictOpValid(stuff->op)) {
1409        client->errorValue = stuff->op;
1410        return BadValue;
1411    }
1412    VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
1413    if (!pDst->pDrawable)
1414        return BadDrawable;
1415
1416    things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
1417    if (things & 4)
1418        return BadLength;
1419    things >>= 3;
1420
1421    CompositeRects(stuff->op,
1422                   pDst, &stuff->color, things, (xRectangle *) &stuff[1]);
1423
1424    return Success;
1425}
1426
1427static void
1428RenderSetBit(unsigned char *line, int x, int bit)
1429{
1430    unsigned char mask;
1431
1432    if (screenInfo.bitmapBitOrder == LSBFirst)
1433        mask = (1 << (x & 7));
1434    else
1435        mask = (0x80 >> (x & 7));
1436    /* XXX assumes byte order is host byte order */
1437    line += (x >> 3);
1438    if (bit)
1439        *line |= mask;
1440    else
1441        *line &= ~mask;
1442}
1443
1444#define DITHER_DIM 2
1445
1446static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
1447    {1, 3,},
1448    {4, 2,},
1449};
1450
1451#define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
1452
1453static int
1454ProcRenderCreateCursor(ClientPtr client)
1455{
1456    REQUEST(xRenderCreateCursorReq);
1457    PicturePtr pSrc;
1458    ScreenPtr pScreen;
1459    unsigned short width, height;
1460    CARD32 *argbbits, *argb;
1461    unsigned char *srcbits, *srcline;
1462    unsigned char *mskbits, *mskline;
1463    int stride;
1464    int x, y;
1465    int nbytes_mono;
1466    CursorMetricRec cm;
1467    CursorPtr pCursor;
1468    CARD32 twocolor[3];
1469    int rc, ncolor;
1470
1471    REQUEST_SIZE_MATCH(xRenderCreateCursorReq);
1472    LEGAL_NEW_RESOURCE(stuff->cid, client);
1473
1474    VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
1475    if (!pSrc->pDrawable)
1476        return BadDrawable;
1477    pScreen = pSrc->pDrawable->pScreen;
1478    width = pSrc->pDrawable->width;
1479    height = pSrc->pDrawable->height;
1480    if (height && width > UINT32_MAX / (height * sizeof(CARD32)))
1481        return BadAlloc;
1482    if (stuff->x > width || stuff->y > height)
1483        return BadMatch;
1484    argbbits = malloc(width * height * sizeof(CARD32));
1485    if (!argbbits)
1486        return BadAlloc;
1487
1488    stride = BitmapBytePad(width);
1489    nbytes_mono = stride * height;
1490    srcbits = calloc(1, nbytes_mono);
1491    if (!srcbits) {
1492        free(argbbits);
1493        return BadAlloc;
1494    }
1495    mskbits = calloc(1, nbytes_mono);
1496    if (!mskbits) {
1497        free(argbbits);
1498        free(srcbits);
1499        return BadAlloc;
1500    }
1501
1502    /* what kind of maniac creates a cursor from a window picture though */
1503    if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
1504        pScreen->SourceValidate(pSrc->pDrawable, 0, 0, width, height,
1505                                IncludeInferiors);
1506
1507    if (pSrc->format == PICT_a8r8g8b8) {
1508        (*pScreen->GetImage) (pSrc->pDrawable,
1509                              0, 0, width, height, ZPixmap,
1510                              0xffffffff, (void *) argbbits);
1511    }
1512    else {
1513        PixmapPtr pPixmap;
1514        PicturePtr pPicture;
1515        PictFormatPtr pFormat;
1516        int error;
1517
1518        pFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8);
1519        if (!pFormat) {
1520            free(argbbits);
1521            free(srcbits);
1522            free(mskbits);
1523            return BadImplementation;
1524        }
1525        pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32,
1526                                            CREATE_PIXMAP_USAGE_SCRATCH);
1527        if (!pPixmap) {
1528            free(argbbits);
1529            free(srcbits);
1530            free(mskbits);
1531            return BadAlloc;
1532        }
1533        pPicture = CreatePicture(0, &pPixmap->drawable, pFormat, 0, 0,
1534                                 client, &error);
1535        if (!pPicture) {
1536            free(argbbits);
1537            free(srcbits);
1538            free(mskbits);
1539            return error;
1540        }
1541        (*pScreen->DestroyPixmap) (pPixmap);
1542        CompositePicture(PictOpSrc,
1543                         pSrc, 0, pPicture, 0, 0, 0, 0, 0, 0, width, height);
1544        (*pScreen->GetImage) (pPicture->pDrawable,
1545                              0, 0, width, height, ZPixmap,
1546                              0xffffffff, (void *) argbbits);
1547        FreePicture(pPicture, 0);
1548    }
1549    /*
1550     * Check whether the cursor can be directly supported by
1551     * the core cursor code
1552     */
1553    ncolor = 0;
1554    argb = argbbits;
1555    for (y = 0; ncolor <= 2 && y < height; y++) {
1556        for (x = 0; ncolor <= 2 && x < width; x++) {
1557            CARD32 p = *argb++;
1558            CARD32 a = (p >> 24);
1559
1560            if (a == 0)         /* transparent */
1561                continue;
1562            if (a == 0xff) {    /* opaque */
1563                int n;
1564
1565                for (n = 0; n < ncolor; n++)
1566                    if (p == twocolor[n])
1567                        break;
1568                if (n == ncolor)
1569                    twocolor[ncolor++] = p;
1570            }
1571            else
1572                ncolor = 3;
1573        }
1574    }
1575
1576    /*
1577     * Convert argb image to two plane cursor
1578     */
1579    srcline = srcbits;
1580    mskline = mskbits;
1581    argb = argbbits;
1582    for (y = 0; y < height; y++) {
1583        for (x = 0; x < width; x++) {
1584            CARD32 p = *argb++;
1585
1586            if (ncolor <= 2) {
1587                CARD32 a = ((p >> 24));
1588
1589                RenderSetBit(mskline, x, a != 0);
1590                RenderSetBit(srcline, x, a != 0 && p == twocolor[0]);
1591            }
1592            else {
1593                CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255;
1594                CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
1595                CARD32 d =
1596                    orderedDither[y & (DITHER_DIM - 1)][x & (DITHER_DIM - 1)];
1597                /* Set mask from dithered alpha value */
1598                RenderSetBit(mskline, x, a > d);
1599                /* Set src from dithered intensity value */
1600                RenderSetBit(srcline, x, a > d && i <= d);
1601            }
1602        }
1603        srcline += stride;
1604        mskline += stride;
1605    }
1606    /*
1607     * Dither to white and black if the cursor has more than two colors
1608     */
1609    if (ncolor > 2) {
1610        twocolor[0] = 0xff000000;
1611        twocolor[1] = 0xffffffff;
1612    }
1613    else {
1614        free(argbbits);
1615        argbbits = 0;
1616    }
1617
1618#define GetByte(p,s)	(((p) >> (s)) & 0xff)
1619#define GetColor(p,s)	(GetByte(p,s) | (GetByte(p,s) << 8))
1620
1621    cm.width = width;
1622    cm.height = height;
1623    cm.xhot = stuff->x;
1624    cm.yhot = stuff->y;
1625    rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm,
1626                         GetColor(twocolor[0], 16),
1627                         GetColor(twocolor[0], 8),
1628                         GetColor(twocolor[0], 0),
1629                         GetColor(twocolor[1], 16),
1630                         GetColor(twocolor[1], 8),
1631                         GetColor(twocolor[1], 0),
1632                         &pCursor, client, stuff->cid);
1633    if (rc != Success)
1634        goto bail;
1635    if (!AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) {
1636        rc = BadAlloc;
1637        goto bail;
1638    }
1639
1640    return Success;
1641 bail:
1642    free(srcbits);
1643    free(mskbits);
1644    return rc;
1645}
1646
1647static int
1648ProcRenderSetPictureTransform(ClientPtr client)
1649{
1650    REQUEST(xRenderSetPictureTransformReq);
1651    PicturePtr pPicture;
1652
1653    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
1654    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
1655    return SetPictureTransform(pPicture, (PictTransform *) &stuff->transform);
1656}
1657
1658static int
1659ProcRenderQueryFilters(ClientPtr client)
1660{
1661    REQUEST(xRenderQueryFiltersReq);
1662    DrawablePtr pDrawable;
1663    xRenderQueryFiltersReply *reply;
1664    int nbytesName;
1665    int nnames;
1666    ScreenPtr pScreen;
1667    PictureScreenPtr ps;
1668    int i, j, len, total_bytes, rc;
1669    INT16 *aliases;
1670    char *names;
1671
1672    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
1673    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
1674                           DixGetAttrAccess);
1675    if (rc != Success)
1676        return rc;
1677
1678    pScreen = pDrawable->pScreen;
1679    nbytesName = 0;
1680    nnames = 0;
1681    ps = GetPictureScreenIfSet(pScreen);
1682    if (ps) {
1683        for (i = 0; i < ps->nfilters; i++)
1684            nbytesName += 1 + strlen(ps->filters[i].name);
1685        for (i = 0; i < ps->nfilterAliases; i++)
1686            nbytesName += 1 + strlen(ps->filterAliases[i].alias);
1687        nnames = ps->nfilters + ps->nfilterAliases;
1688    }
1689    len = ((nnames + 1) >> 1) + bytes_to_int32(nbytesName);
1690    total_bytes = sizeof(xRenderQueryFiltersReply) + (len << 2);
1691    reply = (xRenderQueryFiltersReply *) calloc(1, total_bytes);
1692    if (!reply)
1693        return BadAlloc;
1694    aliases = (INT16 *) (reply + 1);
1695    names = (char *) (aliases + ((nnames + 1) & ~1));
1696
1697    reply->type = X_Reply;
1698    reply->sequenceNumber = client->sequence;
1699    reply->length = len;
1700    reply->numAliases = nnames;
1701    reply->numFilters = nnames;
1702    if (ps) {
1703
1704        /* fill in alias values */
1705        for (i = 0; i < ps->nfilters; i++)
1706            aliases[i] = FilterAliasNone;
1707        for (i = 0; i < ps->nfilterAliases; i++) {
1708            for (j = 0; j < ps->nfilters; j++)
1709                if (ps->filterAliases[i].filter_id == ps->filters[j].id)
1710                    break;
1711            if (j == ps->nfilters) {
1712                for (j = 0; j < ps->nfilterAliases; j++)
1713                    if (ps->filterAliases[i].filter_id ==
1714                        ps->filterAliases[j].alias_id) {
1715                        break;
1716                    }
1717                if (j == ps->nfilterAliases)
1718                    j = FilterAliasNone;
1719                else
1720                    j = j + ps->nfilters;
1721            }
1722            aliases[i + ps->nfilters] = j;
1723        }
1724
1725        /* fill in filter names */
1726        for (i = 0; i < ps->nfilters; i++) {
1727            j = strlen(ps->filters[i].name);
1728            *names++ = j;
1729            memcpy(names, ps->filters[i].name, j);
1730            names += j;
1731        }
1732
1733        /* fill in filter alias names */
1734        for (i = 0; i < ps->nfilterAliases; i++) {
1735            j = strlen(ps->filterAliases[i].alias);
1736            *names++ = j;
1737            memcpy(names, ps->filterAliases[i].alias, j);
1738            names += j;
1739        }
1740    }
1741
1742    if (client->swapped) {
1743        for (i = 0; i < reply->numAliases; i++) {
1744            swaps(&aliases[i]);
1745        }
1746        swaps(&reply->sequenceNumber);
1747        swapl(&reply->length);
1748        swapl(&reply->numAliases);
1749        swapl(&reply->numFilters);
1750    }
1751    WriteToClient(client, total_bytes, reply);
1752    free(reply);
1753
1754    return Success;
1755}
1756
1757static int
1758ProcRenderSetPictureFilter(ClientPtr client)
1759{
1760    REQUEST(xRenderSetPictureFilterReq);
1761    PicturePtr pPicture;
1762    int result;
1763    xFixed *params;
1764    int nparams;
1765    char *name;
1766
1767    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
1768    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
1769    name = (char *) (stuff + 1);
1770    params = (xFixed *) (name + pad_to_int32(stuff->nbytes));
1771    nparams = ((xFixed *) stuff + client->req_len) - params;
1772    if (nparams < 0)
1773	return BadLength;
1774
1775    result = SetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
1776    return result;
1777}
1778
1779static int
1780ProcRenderCreateAnimCursor(ClientPtr client)
1781{
1782    REQUEST(xRenderCreateAnimCursorReq);
1783    CursorPtr *cursors;
1784    CARD32 *deltas;
1785    CursorPtr pCursor;
1786    int ncursor;
1787    xAnimCursorElt *elt;
1788    int i;
1789    int ret;
1790
1791    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
1792    LEGAL_NEW_RESOURCE(stuff->cid, client);
1793    if (client->req_len & 1)
1794        return BadLength;
1795    ncursor =
1796        (client->req_len -
1797         (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1;
1798    if (ncursor <= 0)
1799        return BadValue;
1800    cursors = xallocarray(ncursor, sizeof(CursorPtr) + sizeof(CARD32));
1801    if (!cursors)
1802        return BadAlloc;
1803    deltas = (CARD32 *) (cursors + ncursor);
1804    elt = (xAnimCursorElt *) (stuff + 1);
1805    for (i = 0; i < ncursor; i++) {
1806        ret = dixLookupResourceByType((void **) (cursors + i), elt->cursor,
1807                                      RT_CURSOR, client, DixReadAccess);
1808        if (ret != Success) {
1809            free(cursors);
1810            return ret;
1811        }
1812        deltas[i] = elt->delay;
1813        elt++;
1814    }
1815    ret = AnimCursorCreate(cursors, deltas, ncursor, &pCursor, client,
1816                           stuff->cid);
1817    free(cursors);
1818    if (ret != Success)
1819        return ret;
1820
1821    if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor))
1822        return Success;
1823    return BadAlloc;
1824}
1825
1826static int
1827ProcRenderAddTraps(ClientPtr client)
1828{
1829    int ntraps;
1830    PicturePtr pPicture;
1831
1832    REQUEST(xRenderAddTrapsReq);
1833
1834    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
1835    VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess);
1836    if (!pPicture->pDrawable)
1837        return BadDrawable;
1838    ntraps = (client->req_len << 2) - sizeof(xRenderAddTrapsReq);
1839    if (ntraps % sizeof(xTrap))
1840        return BadLength;
1841    ntraps /= sizeof(xTrap);
1842    if (ntraps)
1843        AddTraps(pPicture,
1844                 stuff->xOff, stuff->yOff, ntraps, (xTrap *) &stuff[1]);
1845    return Success;
1846}
1847
1848static int
1849ProcRenderCreateSolidFill(ClientPtr client)
1850{
1851    PicturePtr pPicture;
1852    int error = 0;
1853
1854    REQUEST(xRenderCreateSolidFillReq);
1855
1856    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
1857
1858    LEGAL_NEW_RESOURCE(stuff->pid, client);
1859
1860    pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
1861    if (!pPicture)
1862        return error;
1863    /* security creation/labeling check */
1864    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1865                     pPicture, RT_NONE, NULL, DixCreateAccess);
1866    if (error != Success)
1867        return error;
1868    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
1869        return BadAlloc;
1870    return Success;
1871}
1872
1873static int
1874ProcRenderCreateLinearGradient(ClientPtr client)
1875{
1876    PicturePtr pPicture;
1877    int len;
1878    int error = 0;
1879    xFixed *stops;
1880    xRenderColor *colors;
1881
1882    REQUEST(xRenderCreateLinearGradientReq);
1883
1884    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
1885
1886    LEGAL_NEW_RESOURCE(stuff->pid, client);
1887
1888    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
1889    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
1890        return BadLength;
1891    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
1892        return BadLength;
1893
1894    stops = (xFixed *) (stuff + 1);
1895    colors = (xRenderColor *) (stops + stuff->nStops);
1896
1897    pPicture = CreateLinearGradientPicture(stuff->pid, &stuff->p1, &stuff->p2,
1898                                           stuff->nStops, stops, colors,
1899                                           &error);
1900    if (!pPicture)
1901        return error;
1902    /* security creation/labeling check */
1903    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1904                     pPicture, RT_NONE, NULL, DixCreateAccess);
1905    if (error != Success)
1906        return error;
1907    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
1908        return BadAlloc;
1909    return Success;
1910}
1911
1912static int
1913ProcRenderCreateRadialGradient(ClientPtr client)
1914{
1915    PicturePtr pPicture;
1916    int len;
1917    int error = 0;
1918    xFixed *stops;
1919    xRenderColor *colors;
1920
1921    REQUEST(xRenderCreateRadialGradientReq);
1922
1923    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
1924
1925    LEGAL_NEW_RESOURCE(stuff->pid, client);
1926
1927    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
1928    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
1929        return BadLength;
1930    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
1931        return BadLength;
1932
1933    stops = (xFixed *) (stuff + 1);
1934    colors = (xRenderColor *) (stops + stuff->nStops);
1935
1936    pPicture =
1937        CreateRadialGradientPicture(stuff->pid, &stuff->inner, &stuff->outer,
1938                                    stuff->inner_radius, stuff->outer_radius,
1939                                    stuff->nStops, stops, colors, &error);
1940    if (!pPicture)
1941        return error;
1942    /* security creation/labeling check */
1943    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1944                     pPicture, RT_NONE, NULL, DixCreateAccess);
1945    if (error != Success)
1946        return error;
1947    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
1948        return BadAlloc;
1949    return Success;
1950}
1951
1952static int
1953ProcRenderCreateConicalGradient(ClientPtr client)
1954{
1955    PicturePtr pPicture;
1956    int len;
1957    int error = 0;
1958    xFixed *stops;
1959    xRenderColor *colors;
1960
1961    REQUEST(xRenderCreateConicalGradientReq);
1962
1963    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
1964
1965    LEGAL_NEW_RESOURCE(stuff->pid, client);
1966
1967    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
1968    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
1969        return BadLength;
1970    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
1971        return BadLength;
1972
1973    stops = (xFixed *) (stuff + 1);
1974    colors = (xRenderColor *) (stops + stuff->nStops);
1975
1976    pPicture =
1977        CreateConicalGradientPicture(stuff->pid, &stuff->center, stuff->angle,
1978                                     stuff->nStops, stops, colors, &error);
1979    if (!pPicture)
1980        return error;
1981    /* security creation/labeling check */
1982    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1983                     pPicture, RT_NONE, NULL, DixCreateAccess);
1984    if (error != Success)
1985        return error;
1986    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
1987        return BadAlloc;
1988    return Success;
1989}
1990
1991static int
1992ProcRenderDispatch(ClientPtr client)
1993{
1994    REQUEST(xReq);
1995
1996    if (stuff->data < RenderNumberRequests)
1997        return (*ProcRenderVector[stuff->data]) (client);
1998    else
1999        return BadRequest;
2000}
2001
2002static int _X_COLD
2003SProcRenderQueryVersion(ClientPtr client)
2004{
2005    REQUEST(xRenderQueryVersionReq);
2006    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
2007    swaps(&stuff->length);
2008    swapl(&stuff->majorVersion);
2009    swapl(&stuff->minorVersion);
2010    return (*ProcRenderVector[stuff->renderReqType]) (client);
2011}
2012
2013static int _X_COLD
2014SProcRenderQueryPictFormats(ClientPtr client)
2015{
2016    REQUEST(xRenderQueryPictFormatsReq);
2017    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
2018    swaps(&stuff->length);
2019    return (*ProcRenderVector[stuff->renderReqType]) (client);
2020}
2021
2022static int _X_COLD
2023SProcRenderQueryPictIndexValues(ClientPtr client)
2024{
2025    REQUEST(xRenderQueryPictIndexValuesReq);
2026    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
2027    swaps(&stuff->length);
2028    swapl(&stuff->format);
2029    return (*ProcRenderVector[stuff->renderReqType]) (client);
2030}
2031
2032static int _X_COLD
2033SProcRenderQueryDithers(ClientPtr client)
2034{
2035    return BadImplementation;
2036}
2037
2038static int _X_COLD
2039SProcRenderCreatePicture(ClientPtr client)
2040{
2041    REQUEST(xRenderCreatePictureReq);
2042    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2043    swaps(&stuff->length);
2044    swapl(&stuff->pid);
2045    swapl(&stuff->drawable);
2046    swapl(&stuff->format);
2047    swapl(&stuff->mask);
2048    SwapRestL(stuff);
2049    return (*ProcRenderVector[stuff->renderReqType]) (client);
2050}
2051
2052static int _X_COLD
2053SProcRenderChangePicture(ClientPtr client)
2054{
2055    REQUEST(xRenderChangePictureReq);
2056    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
2057    swaps(&stuff->length);
2058    swapl(&stuff->picture);
2059    swapl(&stuff->mask);
2060    SwapRestL(stuff);
2061    return (*ProcRenderVector[stuff->renderReqType]) (client);
2062}
2063
2064static int _X_COLD
2065SProcRenderSetPictureClipRectangles(ClientPtr client)
2066{
2067    REQUEST(xRenderSetPictureClipRectanglesReq);
2068    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
2069    swaps(&stuff->length);
2070    swapl(&stuff->picture);
2071    swaps(&stuff->xOrigin);
2072    swaps(&stuff->yOrigin);
2073    SwapRestS(stuff);
2074    return (*ProcRenderVector[stuff->renderReqType]) (client);
2075}
2076
2077static int _X_COLD
2078SProcRenderFreePicture(ClientPtr client)
2079{
2080    REQUEST(xRenderFreePictureReq);
2081    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
2082    swaps(&stuff->length);
2083    swapl(&stuff->picture);
2084    return (*ProcRenderVector[stuff->renderReqType]) (client);
2085}
2086
2087static int _X_COLD
2088SProcRenderComposite(ClientPtr client)
2089{
2090    REQUEST(xRenderCompositeReq);
2091    REQUEST_SIZE_MATCH(xRenderCompositeReq);
2092    swaps(&stuff->length);
2093    swapl(&stuff->src);
2094    swapl(&stuff->mask);
2095    swapl(&stuff->dst);
2096    swaps(&stuff->xSrc);
2097    swaps(&stuff->ySrc);
2098    swaps(&stuff->xMask);
2099    swaps(&stuff->yMask);
2100    swaps(&stuff->xDst);
2101    swaps(&stuff->yDst);
2102    swaps(&stuff->width);
2103    swaps(&stuff->height);
2104    return (*ProcRenderVector[stuff->renderReqType]) (client);
2105}
2106
2107static int _X_COLD
2108SProcRenderScale(ClientPtr client)
2109{
2110    return BadImplementation;
2111}
2112
2113static int _X_COLD
2114SProcRenderTrapezoids(ClientPtr client)
2115{
2116    REQUEST(xRenderTrapezoidsReq);
2117
2118    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
2119    swaps(&stuff->length);
2120    swapl(&stuff->src);
2121    swapl(&stuff->dst);
2122    swapl(&stuff->maskFormat);
2123    swaps(&stuff->xSrc);
2124    swaps(&stuff->ySrc);
2125    SwapRestL(stuff);
2126    return (*ProcRenderVector[stuff->renderReqType]) (client);
2127}
2128
2129static int _X_COLD
2130SProcRenderTriangles(ClientPtr client)
2131{
2132    REQUEST(xRenderTrianglesReq);
2133
2134    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
2135    swaps(&stuff->length);
2136    swapl(&stuff->src);
2137    swapl(&stuff->dst);
2138    swapl(&stuff->maskFormat);
2139    swaps(&stuff->xSrc);
2140    swaps(&stuff->ySrc);
2141    SwapRestL(stuff);
2142    return (*ProcRenderVector[stuff->renderReqType]) (client);
2143}
2144
2145static int _X_COLD
2146SProcRenderTriStrip(ClientPtr client)
2147{
2148    REQUEST(xRenderTriStripReq);
2149
2150    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
2151    swaps(&stuff->length);
2152    swapl(&stuff->src);
2153    swapl(&stuff->dst);
2154    swapl(&stuff->maskFormat);
2155    swaps(&stuff->xSrc);
2156    swaps(&stuff->ySrc);
2157    SwapRestL(stuff);
2158    return (*ProcRenderVector[stuff->renderReqType]) (client);
2159}
2160
2161static int _X_COLD
2162SProcRenderTriFan(ClientPtr client)
2163{
2164    REQUEST(xRenderTriFanReq);
2165
2166    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
2167    swaps(&stuff->length);
2168    swapl(&stuff->src);
2169    swapl(&stuff->dst);
2170    swapl(&stuff->maskFormat);
2171    swaps(&stuff->xSrc);
2172    swaps(&stuff->ySrc);
2173    SwapRestL(stuff);
2174    return (*ProcRenderVector[stuff->renderReqType]) (client);
2175}
2176
2177static int _X_COLD
2178SProcRenderColorTrapezoids(ClientPtr client)
2179{
2180    return BadImplementation;
2181}
2182
2183static int _X_COLD
2184SProcRenderColorTriangles(ClientPtr client)
2185{
2186    return BadImplementation;
2187}
2188
2189static int _X_COLD
2190SProcRenderTransform(ClientPtr client)
2191{
2192    return BadImplementation;
2193}
2194
2195static int _X_COLD
2196SProcRenderCreateGlyphSet(ClientPtr client)
2197{
2198    REQUEST(xRenderCreateGlyphSetReq);
2199    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
2200    swaps(&stuff->length);
2201    swapl(&stuff->gsid);
2202    swapl(&stuff->format);
2203    return (*ProcRenderVector[stuff->renderReqType]) (client);
2204}
2205
2206static int _X_COLD
2207SProcRenderReferenceGlyphSet(ClientPtr client)
2208{
2209    REQUEST(xRenderReferenceGlyphSetReq);
2210    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
2211    swaps(&stuff->length);
2212    swapl(&stuff->gsid);
2213    swapl(&stuff->existing);
2214    return (*ProcRenderVector[stuff->renderReqType]) (client);
2215}
2216
2217static int _X_COLD
2218SProcRenderFreeGlyphSet(ClientPtr client)
2219{
2220    REQUEST(xRenderFreeGlyphSetReq);
2221    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
2222    swaps(&stuff->length);
2223    swapl(&stuff->glyphset);
2224    return (*ProcRenderVector[stuff->renderReqType]) (client);
2225}
2226
2227static int _X_COLD
2228SProcRenderAddGlyphs(ClientPtr client)
2229{
2230    register int i;
2231    CARD32 *gids;
2232    void *end;
2233    xGlyphInfo *gi;
2234
2235    REQUEST(xRenderAddGlyphsReq);
2236    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
2237    swaps(&stuff->length);
2238    swapl(&stuff->glyphset);
2239    swapl(&stuff->nglyphs);
2240    if (stuff->nglyphs & 0xe0000000)
2241        return BadLength;
2242    end = (CARD8 *) stuff + (client->req_len << 2);
2243    gids = (CARD32 *) (stuff + 1);
2244    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
2245    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
2246        return BadLength;
2247    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
2248        return BadLength;
2249    for (i = 0; i < stuff->nglyphs; i++) {
2250        swapl(&gids[i]);
2251        swaps(&gi[i].width);
2252        swaps(&gi[i].height);
2253        swaps(&gi[i].x);
2254        swaps(&gi[i].y);
2255        swaps(&gi[i].xOff);
2256        swaps(&gi[i].yOff);
2257    }
2258    return (*ProcRenderVector[stuff->renderReqType]) (client);
2259}
2260
2261static int _X_COLD
2262SProcRenderAddGlyphsFromPicture(ClientPtr client)
2263{
2264    return BadImplementation;
2265}
2266
2267static int _X_COLD
2268SProcRenderFreeGlyphs(ClientPtr client)
2269{
2270    REQUEST(xRenderFreeGlyphsReq);
2271    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
2272    swaps(&stuff->length);
2273    swapl(&stuff->glyphset);
2274    SwapRestL(stuff);
2275    return (*ProcRenderVector[stuff->renderReqType]) (client);
2276}
2277
2278static int _X_COLD
2279SProcRenderCompositeGlyphs(ClientPtr client)
2280{
2281    xGlyphElt *elt;
2282    CARD8 *buffer;
2283    CARD8 *end;
2284    int space;
2285    int i;
2286    int size;
2287
2288    REQUEST(xRenderCompositeGlyphsReq);
2289    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
2290
2291    switch (stuff->renderReqType) {
2292    default:
2293        size = 1;
2294        break;
2295    case X_RenderCompositeGlyphs16:
2296        size = 2;
2297        break;
2298    case X_RenderCompositeGlyphs32:
2299        size = 4;
2300        break;
2301    }
2302
2303    swaps(&stuff->length);
2304    swapl(&stuff->src);
2305    swapl(&stuff->dst);
2306    swapl(&stuff->maskFormat);
2307    swapl(&stuff->glyphset);
2308    swaps(&stuff->xSrc);
2309    swaps(&stuff->ySrc);
2310    buffer = (CARD8 *) (stuff + 1);
2311    end = (CARD8 *) stuff + (client->req_len << 2);
2312    while (buffer + sizeof(xGlyphElt) < end) {
2313        elt = (xGlyphElt *) buffer;
2314        buffer += sizeof(xGlyphElt);
2315
2316        swaps(&elt->deltax);
2317        swaps(&elt->deltay);
2318
2319        i = elt->len;
2320        if (i == 0xff) {
2321            if (buffer + 4 > end) {
2322                return BadLength;
2323            }
2324            swapl((int *) buffer);
2325            buffer += 4;
2326        }
2327        else {
2328            space = size * i;
2329            switch (size) {
2330            case 1:
2331                buffer += i;
2332                break;
2333            case 2:
2334                if (buffer + i * 2 > end) {
2335                    return BadLength;
2336                }
2337                while (i--) {
2338                    swaps((short *) buffer);
2339                    buffer += 2;
2340                }
2341                break;
2342            case 4:
2343                if (buffer + i * 4 > end) {
2344                    return BadLength;
2345                }
2346                while (i--) {
2347                    swapl((int *) buffer);
2348                    buffer += 4;
2349                }
2350                break;
2351            }
2352            if (space & 3)
2353                buffer += 4 - (space & 3);
2354        }
2355    }
2356    return (*ProcRenderVector[stuff->renderReqType]) (client);
2357}
2358
2359static int _X_COLD
2360SProcRenderFillRectangles(ClientPtr client)
2361{
2362    REQUEST(xRenderFillRectanglesReq);
2363
2364    REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
2365    swaps(&stuff->length);
2366    swapl(&stuff->dst);
2367    swaps(&stuff->color.red);
2368    swaps(&stuff->color.green);
2369    swaps(&stuff->color.blue);
2370    swaps(&stuff->color.alpha);
2371    SwapRestS(stuff);
2372    return (*ProcRenderVector[stuff->renderReqType]) (client);
2373}
2374
2375static int _X_COLD
2376SProcRenderCreateCursor(ClientPtr client)
2377{
2378    REQUEST(xRenderCreateCursorReq);
2379    REQUEST_SIZE_MATCH(xRenderCreateCursorReq);
2380
2381    swaps(&stuff->length);
2382    swapl(&stuff->cid);
2383    swapl(&stuff->src);
2384    swaps(&stuff->x);
2385    swaps(&stuff->y);
2386    return (*ProcRenderVector[stuff->renderReqType]) (client);
2387}
2388
2389static int _X_COLD
2390SProcRenderSetPictureTransform(ClientPtr client)
2391{
2392    REQUEST(xRenderSetPictureTransformReq);
2393    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
2394
2395    swaps(&stuff->length);
2396    swapl(&stuff->picture);
2397    swapl(&stuff->transform.matrix11);
2398    swapl(&stuff->transform.matrix12);
2399    swapl(&stuff->transform.matrix13);
2400    swapl(&stuff->transform.matrix21);
2401    swapl(&stuff->transform.matrix22);
2402    swapl(&stuff->transform.matrix23);
2403    swapl(&stuff->transform.matrix31);
2404    swapl(&stuff->transform.matrix32);
2405    swapl(&stuff->transform.matrix33);
2406    return (*ProcRenderVector[stuff->renderReqType]) (client);
2407}
2408
2409static int _X_COLD
2410SProcRenderQueryFilters(ClientPtr client)
2411{
2412    REQUEST(xRenderQueryFiltersReq);
2413    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
2414
2415    swaps(&stuff->length);
2416    swapl(&stuff->drawable);
2417    return (*ProcRenderVector[stuff->renderReqType]) (client);
2418}
2419
2420static int _X_COLD
2421SProcRenderSetPictureFilter(ClientPtr client)
2422{
2423    REQUEST(xRenderSetPictureFilterReq);
2424    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
2425
2426    swaps(&stuff->length);
2427    swapl(&stuff->picture);
2428    swaps(&stuff->nbytes);
2429    return (*ProcRenderVector[stuff->renderReqType]) (client);
2430}
2431
2432static int _X_COLD
2433SProcRenderCreateAnimCursor(ClientPtr client)
2434{
2435    REQUEST(xRenderCreateAnimCursorReq);
2436    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
2437
2438    swaps(&stuff->length);
2439    swapl(&stuff->cid);
2440    SwapRestL(stuff);
2441    return (*ProcRenderVector[stuff->renderReqType]) (client);
2442}
2443
2444static int _X_COLD
2445SProcRenderAddTraps(ClientPtr client)
2446{
2447    REQUEST(xRenderAddTrapsReq);
2448    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
2449
2450    swaps(&stuff->length);
2451    swapl(&stuff->picture);
2452    swaps(&stuff->xOff);
2453    swaps(&stuff->yOff);
2454    SwapRestL(stuff);
2455    return (*ProcRenderVector[stuff->renderReqType]) (client);
2456}
2457
2458static int _X_COLD
2459SProcRenderCreateSolidFill(ClientPtr client)
2460{
2461    REQUEST(xRenderCreateSolidFillReq);
2462    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
2463
2464    swaps(&stuff->length);
2465    swapl(&stuff->pid);
2466    swaps(&stuff->color.alpha);
2467    swaps(&stuff->color.red);
2468    swaps(&stuff->color.green);
2469    swaps(&stuff->color.blue);
2470    return (*ProcRenderVector[stuff->renderReqType]) (client);
2471}
2472
2473static void _X_COLD
2474swapStops(void *stuff, int num)
2475{
2476    int i;
2477    CARD32 *stops;
2478    CARD16 *colors;
2479
2480    stops = (CARD32 *) (stuff);
2481    for (i = 0; i < num; ++i) {
2482        swapl(stops);
2483        ++stops;
2484    }
2485    colors = (CARD16 *) (stops);
2486    for (i = 0; i < 4 * num; ++i) {
2487        swaps(colors);
2488        ++colors;
2489    }
2490}
2491
2492static int _X_COLD
2493SProcRenderCreateLinearGradient(ClientPtr client)
2494{
2495    int len;
2496
2497    REQUEST(xRenderCreateLinearGradientReq);
2498    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
2499
2500    swaps(&stuff->length);
2501    swapl(&stuff->pid);
2502    swapl(&stuff->p1.x);
2503    swapl(&stuff->p1.y);
2504    swapl(&stuff->p2.x);
2505    swapl(&stuff->p2.y);
2506    swapl(&stuff->nStops);
2507
2508    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
2509    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
2510        return BadLength;
2511    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
2512        return BadLength;
2513
2514    swapStops(stuff + 1, stuff->nStops);
2515
2516    return (*ProcRenderVector[stuff->renderReqType]) (client);
2517}
2518
2519static int _X_COLD
2520SProcRenderCreateRadialGradient(ClientPtr client)
2521{
2522    int len;
2523
2524    REQUEST(xRenderCreateRadialGradientReq);
2525    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
2526
2527    swaps(&stuff->length);
2528    swapl(&stuff->pid);
2529    swapl(&stuff->inner.x);
2530    swapl(&stuff->inner.y);
2531    swapl(&stuff->outer.x);
2532    swapl(&stuff->outer.y);
2533    swapl(&stuff->inner_radius);
2534    swapl(&stuff->outer_radius);
2535    swapl(&stuff->nStops);
2536
2537    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
2538    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
2539        return BadLength;
2540    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
2541        return BadLength;
2542
2543    swapStops(stuff + 1, stuff->nStops);
2544
2545    return (*ProcRenderVector[stuff->renderReqType]) (client);
2546}
2547
2548static int _X_COLD
2549SProcRenderCreateConicalGradient(ClientPtr client)
2550{
2551    int len;
2552
2553    REQUEST(xRenderCreateConicalGradientReq);
2554    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
2555
2556    swaps(&stuff->length);
2557    swapl(&stuff->pid);
2558    swapl(&stuff->center.x);
2559    swapl(&stuff->center.y);
2560    swapl(&stuff->angle);
2561    swapl(&stuff->nStops);
2562
2563    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
2564    if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
2565        return BadLength;
2566    if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
2567        return BadLength;
2568
2569    swapStops(stuff + 1, stuff->nStops);
2570
2571    return (*ProcRenderVector[stuff->renderReqType]) (client);
2572}
2573
2574static int _X_COLD
2575SProcRenderDispatch(ClientPtr client)
2576{
2577    REQUEST(xReq);
2578
2579    if (stuff->data < RenderNumberRequests)
2580        return (*SProcRenderVector[stuff->data]) (client);
2581    else
2582        return BadRequest;
2583}
2584
2585#ifdef PANORAMIX
2586#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\
2587    int rc = dixLookupResourceByType((void **)&(pPicture), pid,\
2588                                     XRT_PICTURE, client, mode);\
2589    if (rc != Success)\
2590	return rc;\
2591}
2592
2593#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\
2594    if (pid == None) \
2595	pPicture = 0; \
2596    else { \
2597	VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \
2598    } \
2599} \
2600
2601int (*PanoramiXSaveRenderVector[RenderNumberRequests]) (ClientPtr);
2602
2603static int
2604PanoramiXRenderCreatePicture(ClientPtr client)
2605{
2606    REQUEST(xRenderCreatePictureReq);
2607    PanoramiXRes *refDraw, *newPict;
2608    int result, j;
2609
2610    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2611    result = dixLookupResourceByClass((void **) &refDraw, stuff->drawable,
2612                                      XRC_DRAWABLE, client, DixWriteAccess);
2613    if (result != Success)
2614        return (result == BadValue) ? BadDrawable : result;
2615    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
2616        return BadAlloc;
2617    newPict->type = XRT_PICTURE;
2618    panoramix_setup_ids(newPict, client, stuff->pid);
2619
2620    if (refDraw->type == XRT_WINDOW &&
2621        stuff->drawable == screenInfo.screens[0]->root->drawable.id) {
2622        newPict->u.pict.root = TRUE;
2623    }
2624    else
2625        newPict->u.pict.root = FALSE;
2626
2627    FOR_NSCREENS_BACKWARD(j) {
2628        stuff->pid = newPict->info[j].id;
2629        stuff->drawable = refDraw->info[j].id;
2630        result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
2631        if (result != Success)
2632            break;
2633    }
2634
2635    if (result == Success)
2636        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
2637    else
2638        free(newPict);
2639
2640    return result;
2641}
2642
2643static int
2644PanoramiXRenderChangePicture(ClientPtr client)
2645{
2646    PanoramiXRes *pict;
2647    int result = Success, j;
2648
2649    REQUEST(xRenderChangePictureReq);
2650
2651    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
2652
2653    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2654
2655    FOR_NSCREENS_BACKWARD(j) {
2656        stuff->picture = pict->info[j].id;
2657        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
2658        if (result != Success)
2659            break;
2660    }
2661
2662    return result;
2663}
2664
2665static int
2666PanoramiXRenderSetPictureClipRectangles(ClientPtr client)
2667{
2668    REQUEST(xRenderSetPictureClipRectanglesReq);
2669    int result = Success, j;
2670    PanoramiXRes *pict;
2671
2672    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
2673
2674    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2675
2676    FOR_NSCREENS_BACKWARD(j) {
2677        stuff->picture = pict->info[j].id;
2678        result =
2679            (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles])
2680            (client);
2681        if (result != Success)
2682            break;
2683    }
2684
2685    return result;
2686}
2687
2688static int
2689PanoramiXRenderSetPictureTransform(ClientPtr client)
2690{
2691    REQUEST(xRenderSetPictureTransformReq);
2692    int result = Success, j;
2693    PanoramiXRes *pict;
2694
2695    REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
2696
2697    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2698
2699    FOR_NSCREENS_BACKWARD(j) {
2700        stuff->picture = pict->info[j].id;
2701        result =
2702            (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
2703        if (result != Success)
2704            break;
2705    }
2706
2707    return result;
2708}
2709
2710static int
2711PanoramiXRenderSetPictureFilter(ClientPtr client)
2712{
2713    REQUEST(xRenderSetPictureFilterReq);
2714    int result = Success, j;
2715    PanoramiXRes *pict;
2716
2717    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
2718
2719    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2720
2721    FOR_NSCREENS_BACKWARD(j) {
2722        stuff->picture = pict->info[j].id;
2723        result =
2724            (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
2725        if (result != Success)
2726            break;
2727    }
2728
2729    return result;
2730}
2731
2732static int
2733PanoramiXRenderFreePicture(ClientPtr client)
2734{
2735    PanoramiXRes *pict;
2736    int result = Success, j;
2737
2738    REQUEST(xRenderFreePictureReq);
2739
2740    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
2741
2742    client->errorValue = stuff->picture;
2743
2744    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess);
2745
2746    FOR_NSCREENS_BACKWARD(j) {
2747        stuff->picture = pict->info[j].id;
2748        result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
2749        if (result != Success)
2750            break;
2751    }
2752
2753    /* Since ProcRenderFreePicture is using FreeResource, it will free
2754       our resource for us on the last pass through the loop above */
2755
2756    return result;
2757}
2758
2759static int
2760PanoramiXRenderComposite(ClientPtr client)
2761{
2762    PanoramiXRes *src, *msk, *dst;
2763    int result = Success, j;
2764    xRenderCompositeReq orig;
2765
2766    REQUEST(xRenderCompositeReq);
2767
2768    REQUEST_SIZE_MATCH(xRenderCompositeReq);
2769
2770    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2771    VERIFY_XIN_ALPHA(msk, stuff->mask, client, DixReadAccess);
2772    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2773
2774    orig = *stuff;
2775
2776    FOR_NSCREENS_FORWARD(j) {
2777        stuff->src = src->info[j].id;
2778        if (src->u.pict.root) {
2779            stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x;
2780            stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y;
2781        }
2782        stuff->dst = dst->info[j].id;
2783        if (dst->u.pict.root) {
2784            stuff->xDst = orig.xDst - screenInfo.screens[j]->x;
2785            stuff->yDst = orig.yDst - screenInfo.screens[j]->y;
2786        }
2787        if (msk) {
2788            stuff->mask = msk->info[j].id;
2789            if (msk->u.pict.root) {
2790                stuff->xMask = orig.xMask - screenInfo.screens[j]->x;
2791                stuff->yMask = orig.yMask - screenInfo.screens[j]->y;
2792            }
2793        }
2794        result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
2795        if (result != Success)
2796            break;
2797    }
2798
2799    return result;
2800}
2801
2802static int
2803PanoramiXRenderCompositeGlyphs(ClientPtr client)
2804{
2805    PanoramiXRes *src, *dst;
2806    int result = Success, j;
2807
2808    REQUEST(xRenderCompositeGlyphsReq);
2809    xGlyphElt origElt, *elt;
2810    INT16 xSrc, ySrc;
2811
2812    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
2813    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2814    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2815
2816    if (client->req_len << 2 >= (sizeof(xRenderCompositeGlyphsReq) +
2817                                 sizeof(xGlyphElt))) {
2818        elt = (xGlyphElt *) (stuff + 1);
2819        origElt = *elt;
2820        xSrc = stuff->xSrc;
2821        ySrc = stuff->ySrc;
2822        FOR_NSCREENS_FORWARD(j) {
2823            stuff->src = src->info[j].id;
2824            if (src->u.pict.root) {
2825                stuff->xSrc = xSrc - screenInfo.screens[j]->x;
2826                stuff->ySrc = ySrc - screenInfo.screens[j]->y;
2827            }
2828            stuff->dst = dst->info[j].id;
2829            if (dst->u.pict.root) {
2830                elt->deltax = origElt.deltax - screenInfo.screens[j]->x;
2831                elt->deltay = origElt.deltay - screenInfo.screens[j]->y;
2832            }
2833            result =
2834                (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
2835            if (result != Success)
2836                break;
2837        }
2838    }
2839
2840    return result;
2841}
2842
2843static int
2844PanoramiXRenderFillRectangles(ClientPtr client)
2845{
2846    PanoramiXRes *dst;
2847    int result = Success, j;
2848
2849    REQUEST(xRenderFillRectanglesReq);
2850    char *extra;
2851    int extra_len;
2852
2853    REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
2854    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2855    extra_len = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
2856    if (extra_len && (extra = (char *) malloc(extra_len))) {
2857        memcpy(extra, stuff + 1, extra_len);
2858        FOR_NSCREENS_FORWARD(j) {
2859            if (j)
2860                memcpy(stuff + 1, extra, extra_len);
2861            if (dst->u.pict.root) {
2862                int x_off = screenInfo.screens[j]->x;
2863                int y_off = screenInfo.screens[j]->y;
2864
2865                if (x_off || y_off) {
2866                    xRectangle *rects = (xRectangle *) (stuff + 1);
2867                    int i = extra_len / sizeof(xRectangle);
2868
2869                    while (i--) {
2870                        rects->x -= x_off;
2871                        rects->y -= y_off;
2872                        rects++;
2873                    }
2874                }
2875            }
2876            stuff->dst = dst->info[j].id;
2877            result =
2878                (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
2879            if (result != Success)
2880                break;
2881        }
2882        free(extra);
2883    }
2884
2885    return result;
2886}
2887
2888static int
2889PanoramiXRenderTrapezoids(ClientPtr client)
2890{
2891    PanoramiXRes *src, *dst;
2892    int result = Success, j;
2893
2894    REQUEST(xRenderTrapezoidsReq);
2895    char *extra;
2896    int extra_len;
2897
2898    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
2899
2900    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2901    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2902
2903    extra_len = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq);
2904
2905    if (extra_len && (extra = (char *) malloc(extra_len))) {
2906        memcpy(extra, stuff + 1, extra_len);
2907
2908        FOR_NSCREENS_FORWARD(j) {
2909            if (j)
2910                memcpy(stuff + 1, extra, extra_len);
2911            if (dst->u.pict.root) {
2912                int x_off = screenInfo.screens[j]->x;
2913                int y_off = screenInfo.screens[j]->y;
2914
2915                if (x_off || y_off) {
2916                    xTrapezoid *trap = (xTrapezoid *) (stuff + 1);
2917                    int i = extra_len / sizeof(xTrapezoid);
2918
2919                    while (i--) {
2920                        trap->top -= y_off;
2921                        trap->bottom -= y_off;
2922                        trap->left.p1.x -= x_off;
2923                        trap->left.p1.y -= y_off;
2924                        trap->left.p2.x -= x_off;
2925                        trap->left.p2.y -= y_off;
2926                        trap->right.p1.x -= x_off;
2927                        trap->right.p1.y -= y_off;
2928                        trap->right.p2.x -= x_off;
2929                        trap->right.p2.y -= y_off;
2930                        trap++;
2931                    }
2932                }
2933            }
2934
2935            stuff->src = src->info[j].id;
2936            stuff->dst = dst->info[j].id;
2937            result = (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
2938
2939            if (result != Success)
2940                break;
2941        }
2942
2943        free(extra);
2944    }
2945
2946    return result;
2947}
2948
2949static int
2950PanoramiXRenderTriangles(ClientPtr client)
2951{
2952    PanoramiXRes *src, *dst;
2953    int result = Success, j;
2954
2955    REQUEST(xRenderTrianglesReq);
2956    char *extra;
2957    int extra_len;
2958
2959    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
2960
2961    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
2962    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
2963
2964    extra_len = (client->req_len << 2) - sizeof(xRenderTrianglesReq);
2965
2966    if (extra_len && (extra = (char *) malloc(extra_len))) {
2967        memcpy(extra, stuff + 1, extra_len);
2968
2969        FOR_NSCREENS_FORWARD(j) {
2970            if (j)
2971                memcpy(stuff + 1, extra, extra_len);
2972            if (dst->u.pict.root) {
2973                int x_off = screenInfo.screens[j]->x;
2974                int y_off = screenInfo.screens[j]->y;
2975
2976                if (x_off || y_off) {
2977                    xTriangle *tri = (xTriangle *) (stuff + 1);
2978                    int i = extra_len / sizeof(xTriangle);
2979
2980                    while (i--) {
2981                        tri->p1.x -= x_off;
2982                        tri->p1.y -= y_off;
2983                        tri->p2.x -= x_off;
2984                        tri->p2.y -= y_off;
2985                        tri->p3.x -= x_off;
2986                        tri->p3.y -= y_off;
2987                        tri++;
2988                    }
2989                }
2990            }
2991
2992            stuff->src = src->info[j].id;
2993            stuff->dst = dst->info[j].id;
2994            result = (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
2995
2996            if (result != Success)
2997                break;
2998        }
2999
3000        free(extra);
3001    }
3002
3003    return result;
3004}
3005
3006static int
3007PanoramiXRenderTriStrip(ClientPtr client)
3008{
3009    PanoramiXRes *src, *dst;
3010    int result = Success, j;
3011
3012    REQUEST(xRenderTriStripReq);
3013    char *extra;
3014    int extra_len;
3015
3016    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
3017
3018    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
3019    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
3020
3021    extra_len = (client->req_len << 2) - sizeof(xRenderTriStripReq);
3022
3023    if (extra_len && (extra = (char *) malloc(extra_len))) {
3024        memcpy(extra, stuff + 1, extra_len);
3025
3026        FOR_NSCREENS_FORWARD(j) {
3027            if (j)
3028                memcpy(stuff + 1, extra, extra_len);
3029            if (dst->u.pict.root) {
3030                int x_off = screenInfo.screens[j]->x;
3031                int y_off = screenInfo.screens[j]->y;
3032
3033                if (x_off || y_off) {
3034                    xPointFixed *fixed = (xPointFixed *) (stuff + 1);
3035                    int i = extra_len / sizeof(xPointFixed);
3036
3037                    while (i--) {
3038                        fixed->x -= x_off;
3039                        fixed->y -= y_off;
3040                        fixed++;
3041                    }
3042                }
3043            }
3044
3045            stuff->src = src->info[j].id;
3046            stuff->dst = dst->info[j].id;
3047            result = (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
3048
3049            if (result != Success)
3050                break;
3051        }
3052
3053        free(extra);
3054    }
3055
3056    return result;
3057}
3058
3059static int
3060PanoramiXRenderTriFan(ClientPtr client)
3061{
3062    PanoramiXRes *src, *dst;
3063    int result = Success, j;
3064
3065    REQUEST(xRenderTriFanReq);
3066    char *extra;
3067    int extra_len;
3068
3069    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
3070
3071    VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
3072    VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
3073
3074    extra_len = (client->req_len << 2) - sizeof(xRenderTriFanReq);
3075
3076    if (extra_len && (extra = (char *) malloc(extra_len))) {
3077        memcpy(extra, stuff + 1, extra_len);
3078
3079        FOR_NSCREENS_FORWARD(j) {
3080            if (j)
3081                memcpy(stuff + 1, extra, extra_len);
3082            if (dst->u.pict.root) {
3083                int x_off = screenInfo.screens[j]->x;
3084                int y_off = screenInfo.screens[j]->y;
3085
3086                if (x_off || y_off) {
3087                    xPointFixed *fixed = (xPointFixed *) (stuff + 1);
3088                    int i = extra_len / sizeof(xPointFixed);
3089
3090                    while (i--) {
3091                        fixed->x -= x_off;
3092                        fixed->y -= y_off;
3093                        fixed++;
3094                    }
3095                }
3096            }
3097
3098            stuff->src = src->info[j].id;
3099            stuff->dst = dst->info[j].id;
3100            result = (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
3101
3102            if (result != Success)
3103                break;
3104        }
3105
3106        free(extra);
3107    }
3108
3109    return result;
3110}
3111
3112static int
3113PanoramiXRenderAddTraps(ClientPtr client)
3114{
3115    PanoramiXRes *picture;
3116    int result = Success, j;
3117
3118    REQUEST(xRenderAddTrapsReq);
3119    char *extra;
3120    int extra_len;
3121    INT16 x_off, y_off;
3122
3123    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
3124    VERIFY_XIN_PICTURE(picture, stuff->picture, client, DixWriteAccess);
3125    extra_len = (client->req_len << 2) - sizeof(xRenderAddTrapsReq);
3126    if (extra_len && (extra = (char *) malloc(extra_len))) {
3127        memcpy(extra, stuff + 1, extra_len);
3128        x_off = stuff->xOff;
3129        y_off = stuff->yOff;
3130        FOR_NSCREENS_FORWARD(j) {
3131            if (j)
3132                memcpy(stuff + 1, extra, extra_len);
3133            stuff->picture = picture->info[j].id;
3134
3135            if (picture->u.pict.root) {
3136                stuff->xOff = x_off + screenInfo.screens[j]->x;
3137                stuff->yOff = y_off + screenInfo.screens[j]->y;
3138            }
3139            result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
3140            if (result != Success)
3141                break;
3142        }
3143        free(extra);
3144    }
3145
3146    return result;
3147}
3148
3149static int
3150PanoramiXRenderCreateSolidFill(ClientPtr client)
3151{
3152    REQUEST(xRenderCreateSolidFillReq);
3153    PanoramiXRes *newPict;
3154    int result = Success, j;
3155
3156    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
3157
3158    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3159        return BadAlloc;
3160
3161    newPict->type = XRT_PICTURE;
3162    panoramix_setup_ids(newPict, client, stuff->pid);
3163    newPict->u.pict.root = FALSE;
3164
3165    FOR_NSCREENS_BACKWARD(j) {
3166        stuff->pid = newPict->info[j].id;
3167        result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client);
3168        if (result != Success)
3169            break;
3170    }
3171
3172    if (result == Success)
3173        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3174    else
3175        free(newPict);
3176
3177    return result;
3178}
3179
3180static int
3181PanoramiXRenderCreateLinearGradient(ClientPtr client)
3182{
3183    REQUEST(xRenderCreateLinearGradientReq);
3184    PanoramiXRes *newPict;
3185    int result = Success, j;
3186
3187    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
3188
3189    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3190        return BadAlloc;
3191
3192    newPict->type = XRT_PICTURE;
3193    panoramix_setup_ids(newPict, client, stuff->pid);
3194    newPict->u.pict.root = FALSE;
3195
3196    FOR_NSCREENS_BACKWARD(j) {
3197        stuff->pid = newPict->info[j].id;
3198        result =
3199            (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client);
3200        if (result != Success)
3201            break;
3202    }
3203
3204    if (result == Success)
3205        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3206    else
3207        free(newPict);
3208
3209    return result;
3210}
3211
3212static int
3213PanoramiXRenderCreateRadialGradient(ClientPtr client)
3214{
3215    REQUEST(xRenderCreateRadialGradientReq);
3216    PanoramiXRes *newPict;
3217    int result = Success, j;
3218
3219    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
3220
3221    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3222        return BadAlloc;
3223
3224    newPict->type = XRT_PICTURE;
3225    panoramix_setup_ids(newPict, client, stuff->pid);
3226    newPict->u.pict.root = FALSE;
3227
3228    FOR_NSCREENS_BACKWARD(j) {
3229        stuff->pid = newPict->info[j].id;
3230        result =
3231            (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client);
3232        if (result != Success)
3233            break;
3234    }
3235
3236    if (result == Success)
3237        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3238    else
3239        free(newPict);
3240
3241    return result;
3242}
3243
3244static int
3245PanoramiXRenderCreateConicalGradient(ClientPtr client)
3246{
3247    REQUEST(xRenderCreateConicalGradientReq);
3248    PanoramiXRes *newPict;
3249    int result = Success, j;
3250
3251    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
3252
3253    if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3254        return BadAlloc;
3255
3256    newPict->type = XRT_PICTURE;
3257    panoramix_setup_ids(newPict, client, stuff->pid);
3258    newPict->u.pict.root = FALSE;
3259
3260    FOR_NSCREENS_BACKWARD(j) {
3261        stuff->pid = newPict->info[j].id;
3262        result =
3263            (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient])
3264            (client);
3265        if (result != Success)
3266            break;
3267    }
3268
3269    if (result == Success)
3270        AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3271    else
3272        free(newPict);
3273
3274    return result;
3275}
3276
3277void
3278PanoramiXRenderInit(void)
3279{
3280    int i;
3281
3282    XRT_PICTURE = CreateNewResourceType(XineramaDeleteResource,
3283                                        "XineramaPicture");
3284    if (RenderErrBase)
3285        SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
3286    for (i = 0; i < RenderNumberRequests; i++)
3287        PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
3288    /*
3289     * Stuff in Xinerama aware request processing hooks
3290     */
3291    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
3292    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
3293    ProcRenderVector[X_RenderSetPictureTransform] =
3294        PanoramiXRenderSetPictureTransform;
3295    ProcRenderVector[X_RenderSetPictureFilter] =
3296        PanoramiXRenderSetPictureFilter;
3297    ProcRenderVector[X_RenderSetPictureClipRectangles] =
3298        PanoramiXRenderSetPictureClipRectangles;
3299    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
3300    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
3301    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
3302    ProcRenderVector[X_RenderCompositeGlyphs16] =
3303        PanoramiXRenderCompositeGlyphs;
3304    ProcRenderVector[X_RenderCompositeGlyphs32] =
3305        PanoramiXRenderCompositeGlyphs;
3306    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
3307
3308    ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
3309    ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
3310    ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
3311    ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
3312    ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
3313
3314    ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill;
3315    ProcRenderVector[X_RenderCreateLinearGradient] =
3316        PanoramiXRenderCreateLinearGradient;
3317    ProcRenderVector[X_RenderCreateRadialGradient] =
3318        PanoramiXRenderCreateRadialGradient;
3319    ProcRenderVector[X_RenderCreateConicalGradient] =
3320        PanoramiXRenderCreateConicalGradient;
3321}
3322
3323void
3324PanoramiXRenderReset(void)
3325{
3326    int i;
3327
3328    for (i = 0; i < RenderNumberRequests; i++)
3329        ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
3330    RenderErrBase = 0;
3331}
3332
3333#endif                          /* PANORAMIX */
3334