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