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