render.c revision 706f2543
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    result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
1852    return result;
1853}
1854
1855static int
1856ProcRenderCreateAnimCursor (ClientPtr client)
1857{
1858    REQUEST(xRenderCreateAnimCursorReq);
1859    CursorPtr	    *cursors;
1860    CARD32	    *deltas;
1861    CursorPtr	    pCursor;
1862    int		    ncursor;
1863    xAnimCursorElt  *elt;
1864    int		    i;
1865    int		    ret;
1866
1867    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
1868    LEGAL_NEW_RESOURCE(stuff->cid, client);
1869    if (client->req_len & 1)
1870	return BadLength;
1871    ncursor = (client->req_len - (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1;
1872    cursors = malloc(ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
1873    if (!cursors)
1874	return BadAlloc;
1875    deltas = (CARD32 *) (cursors + ncursor);
1876    elt = (xAnimCursorElt *) (stuff + 1);
1877    for (i = 0; i < ncursor; i++)
1878    {
1879	ret = dixLookupResourceByType((pointer *)(cursors + i), elt->cursor,
1880				      RT_CURSOR, client, DixReadAccess);
1881	if (ret != Success)
1882	{
1883	    free(cursors);
1884	    return ret;
1885	}
1886	deltas[i] = elt->delay;
1887	elt++;
1888    }
1889    ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor, client,
1890			    stuff->cid);
1891    free(cursors);
1892    if (ret != Success)
1893	return ret;
1894
1895    if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
1896	return Success;
1897    return BadAlloc;
1898}
1899
1900static int
1901ProcRenderAddTraps (ClientPtr client)
1902{
1903    int		ntraps;
1904    PicturePtr	pPicture;
1905    REQUEST(xRenderAddTrapsReq);
1906
1907    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
1908    VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess);
1909    if (!pPicture->pDrawable)
1910        return BadDrawable;
1911    ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
1912    if (ntraps % sizeof (xTrap))
1913	return BadLength;
1914    ntraps /= sizeof (xTrap);
1915    if (ntraps)
1916	AddTraps (pPicture,
1917		  stuff->xOff, stuff->yOff,
1918		  ntraps, (xTrap *) &stuff[1]);
1919    return Success;
1920}
1921
1922static int ProcRenderCreateSolidFill(ClientPtr client)
1923{
1924    PicturePtr	    pPicture;
1925    int		    error = 0;
1926    REQUEST(xRenderCreateSolidFillReq);
1927
1928    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
1929
1930    LEGAL_NEW_RESOURCE(stuff->pid, client);
1931
1932    pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
1933    if (!pPicture)
1934	return error;
1935    /* security creation/labeling check */
1936    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1937		     pPicture, RT_NONE, NULL, DixCreateAccess);
1938    if (error != Success)
1939	return error;
1940    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
1941	return BadAlloc;
1942    return Success;
1943}
1944
1945static int ProcRenderCreateLinearGradient (ClientPtr client)
1946{
1947    PicturePtr	    pPicture;
1948    int		    len;
1949    int		    error = 0;
1950    xFixed          *stops;
1951    xRenderColor   *colors;
1952    REQUEST(xRenderCreateLinearGradientReq);
1953
1954    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
1955
1956    LEGAL_NEW_RESOURCE(stuff->pid, client);
1957
1958    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
1959    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
1960	return BadLength;
1961    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
1962        return BadLength;
1963
1964    stops = (xFixed *)(stuff + 1);
1965    colors = (xRenderColor *)(stops + stuff->nStops);
1966
1967    pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
1968                                            stuff->nStops, stops, colors, &error);
1969    if (!pPicture)
1970	return error;
1971    /* security creation/labeling check */
1972    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1973		     pPicture, RT_NONE, NULL, DixCreateAccess);
1974    if (error != Success)
1975	return error;
1976    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
1977	return BadAlloc;
1978    return Success;
1979}
1980
1981static int ProcRenderCreateRadialGradient (ClientPtr client)
1982{
1983    PicturePtr	    pPicture;
1984    int		    len;
1985    int		    error = 0;
1986    xFixed          *stops;
1987    xRenderColor   *colors;
1988    REQUEST(xRenderCreateRadialGradientReq);
1989
1990    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
1991
1992    LEGAL_NEW_RESOURCE(stuff->pid, client);
1993
1994    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
1995    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
1996        return BadLength;
1997
1998    stops = (xFixed *)(stuff + 1);
1999    colors = (xRenderColor *)(stops + stuff->nStops);
2000
2001    pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
2002                                            stuff->inner_radius, stuff->outer_radius,
2003                                            stuff->nStops, stops, colors, &error);
2004    if (!pPicture)
2005	return error;
2006    /* security creation/labeling check */
2007    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
2008		     pPicture, RT_NONE, NULL, DixCreateAccess);
2009    if (error != Success)
2010	return error;
2011    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
2012	return BadAlloc;
2013    return Success;
2014}
2015
2016static int ProcRenderCreateConicalGradient (ClientPtr client)
2017{
2018    PicturePtr	    pPicture;
2019    int		    len;
2020    int		    error = 0;
2021    xFixed          *stops;
2022    xRenderColor   *colors;
2023    REQUEST(xRenderCreateConicalGradientReq);
2024
2025    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
2026
2027    LEGAL_NEW_RESOURCE(stuff->pid, client);
2028
2029    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
2030    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
2031        return BadLength;
2032
2033    stops = (xFixed *)(stuff + 1);
2034    colors = (xRenderColor *)(stops + stuff->nStops);
2035
2036    pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
2037                                             stuff->nStops, stops, colors, &error);
2038    if (!pPicture)
2039	return error;
2040    /* security creation/labeling check */
2041    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
2042		     pPicture, RT_NONE, NULL, DixCreateAccess);
2043    if (error != Success)
2044	return error;
2045    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
2046	return BadAlloc;
2047    return Success;
2048}
2049
2050
2051static int
2052ProcRenderDispatch (ClientPtr client)
2053{
2054    REQUEST(xReq);
2055
2056    if (stuff->data < RenderNumberRequests)
2057	return (*ProcRenderVector[stuff->data]) (client);
2058    else
2059	return BadRequest;
2060}
2061
2062static int
2063SProcRenderQueryVersion (ClientPtr client)
2064{
2065    register int n;
2066    REQUEST(xRenderQueryVersionReq);
2067    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
2068
2069    swaps(&stuff->length, n);
2070    swapl(&stuff->majorVersion, n);
2071    swapl(&stuff->minorVersion, n);
2072    return (*ProcRenderVector[stuff->renderReqType])(client);
2073}
2074
2075static int
2076SProcRenderQueryPictFormats (ClientPtr client)
2077{
2078    register int n;
2079    REQUEST(xRenderQueryPictFormatsReq);
2080    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
2081    swaps(&stuff->length, n);
2082    return (*ProcRenderVector[stuff->renderReqType]) (client);
2083}
2084
2085static int
2086SProcRenderQueryPictIndexValues (ClientPtr client)
2087{
2088    register int n;
2089    REQUEST(xRenderQueryPictIndexValuesReq);
2090    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
2091    swaps(&stuff->length, n);
2092    swapl(&stuff->format, n);
2093    return (*ProcRenderVector[stuff->renderReqType]) (client);
2094}
2095
2096static int
2097SProcRenderQueryDithers (ClientPtr client)
2098{
2099    return BadImplementation;
2100}
2101
2102static int
2103SProcRenderCreatePicture (ClientPtr client)
2104{
2105    register int n;
2106    REQUEST(xRenderCreatePictureReq);
2107    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2108    swaps(&stuff->length, n);
2109    swapl(&stuff->pid, n);
2110    swapl(&stuff->drawable, n);
2111    swapl(&stuff->format, n);
2112    swapl(&stuff->mask, n);
2113    SwapRestL(stuff);
2114    return (*ProcRenderVector[stuff->renderReqType]) (client);
2115}
2116
2117static int
2118SProcRenderChangePicture (ClientPtr client)
2119{
2120    register int n;
2121    REQUEST(xRenderChangePictureReq);
2122    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
2123    swaps(&stuff->length, n);
2124    swapl(&stuff->picture, n);
2125    swapl(&stuff->mask, n);
2126    SwapRestL(stuff);
2127    return (*ProcRenderVector[stuff->renderReqType]) (client);
2128}
2129
2130static int
2131SProcRenderSetPictureClipRectangles (ClientPtr client)
2132{
2133    register int n;
2134    REQUEST(xRenderSetPictureClipRectanglesReq);
2135    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
2136    swaps(&stuff->length, n);
2137    swapl(&stuff->picture, n);
2138    swaps(&stuff->xOrigin, n);
2139    swaps(&stuff->yOrigin, n);
2140    SwapRestS(stuff);
2141    return (*ProcRenderVector[stuff->renderReqType]) (client);
2142}
2143
2144static int
2145SProcRenderFreePicture (ClientPtr client)
2146{
2147    register int n;
2148    REQUEST(xRenderFreePictureReq);
2149    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
2150    swaps(&stuff->length, n);
2151    swapl(&stuff->picture, n);
2152    return (*ProcRenderVector[stuff->renderReqType]) (client);
2153}
2154
2155static int
2156SProcRenderComposite (ClientPtr client)
2157{
2158    register int n;
2159    REQUEST(xRenderCompositeReq);
2160    REQUEST_SIZE_MATCH(xRenderCompositeReq);
2161    swaps(&stuff->length, n);
2162    swapl(&stuff->src, n);
2163    swapl(&stuff->mask, n);
2164    swapl(&stuff->dst, n);
2165    swaps(&stuff->xSrc, n);
2166    swaps(&stuff->ySrc, n);
2167    swaps(&stuff->xMask, n);
2168    swaps(&stuff->yMask, n);
2169    swaps(&stuff->xDst, n);
2170    swaps(&stuff->yDst, n);
2171    swaps(&stuff->width, n);
2172    swaps(&stuff->height, n);
2173    return (*ProcRenderVector[stuff->renderReqType]) (client);
2174}
2175
2176static int
2177SProcRenderScale (ClientPtr client)
2178{
2179    register int n;
2180    REQUEST(xRenderScaleReq);
2181    REQUEST_SIZE_MATCH(xRenderScaleReq);
2182    swaps(&stuff->length, n);
2183    swapl(&stuff->src, n);
2184    swapl(&stuff->dst, n);
2185    swapl(&stuff->colorScale, n);
2186    swapl(&stuff->alphaScale, n);
2187    swaps(&stuff->xSrc, n);
2188    swaps(&stuff->ySrc, n);
2189    swaps(&stuff->xDst, n);
2190    swaps(&stuff->yDst, n);
2191    swaps(&stuff->width, n);
2192    swaps(&stuff->height, n);
2193    return (*ProcRenderVector[stuff->renderReqType]) (client);
2194}
2195
2196static int
2197SProcRenderTrapezoids (ClientPtr client)
2198{
2199    register int n;
2200    REQUEST(xRenderTrapezoidsReq);
2201
2202    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
2203    swaps (&stuff->length, n);
2204    swapl (&stuff->src, n);
2205    swapl (&stuff->dst, n);
2206    swapl (&stuff->maskFormat, n);
2207    swaps (&stuff->xSrc, n);
2208    swaps (&stuff->ySrc, n);
2209    SwapRestL(stuff);
2210    return (*ProcRenderVector[stuff->renderReqType]) (client);
2211}
2212
2213static int
2214SProcRenderTriangles (ClientPtr client)
2215{
2216    register int n;
2217    REQUEST(xRenderTrianglesReq);
2218
2219    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
2220    swaps (&stuff->length, n);
2221    swapl (&stuff->src, n);
2222    swapl (&stuff->dst, n);
2223    swapl (&stuff->maskFormat, n);
2224    swaps (&stuff->xSrc, n);
2225    swaps (&stuff->ySrc, n);
2226    SwapRestL(stuff);
2227    return (*ProcRenderVector[stuff->renderReqType]) (client);
2228}
2229
2230static int
2231SProcRenderTriStrip (ClientPtr client)
2232{
2233    register int n;
2234    REQUEST(xRenderTriStripReq);
2235
2236    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
2237    swaps (&stuff->length, n);
2238    swapl (&stuff->src, n);
2239    swapl (&stuff->dst, n);
2240    swapl (&stuff->maskFormat, n);
2241    swaps (&stuff->xSrc, n);
2242    swaps (&stuff->ySrc, n);
2243    SwapRestL(stuff);
2244    return (*ProcRenderVector[stuff->renderReqType]) (client);
2245}
2246
2247static int
2248SProcRenderTriFan (ClientPtr client)
2249{
2250    register int n;
2251    REQUEST(xRenderTriFanReq);
2252
2253    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
2254    swaps (&stuff->length, n);
2255    swapl (&stuff->src, n);
2256    swapl (&stuff->dst, n);
2257    swapl (&stuff->maskFormat, n);
2258    swaps (&stuff->xSrc, n);
2259    swaps (&stuff->ySrc, n);
2260    SwapRestL(stuff);
2261    return (*ProcRenderVector[stuff->renderReqType]) (client);
2262}
2263
2264static int
2265SProcRenderColorTrapezoids (ClientPtr client)
2266{
2267    return BadImplementation;
2268}
2269
2270static int
2271SProcRenderColorTriangles (ClientPtr client)
2272{
2273    return BadImplementation;
2274}
2275
2276static int
2277SProcRenderTransform (ClientPtr client)
2278{
2279    return BadImplementation;
2280}
2281
2282static int
2283SProcRenderCreateGlyphSet (ClientPtr client)
2284{
2285    register int n;
2286    REQUEST(xRenderCreateGlyphSetReq);
2287    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
2288    swaps(&stuff->length, n);
2289    swapl(&stuff->gsid, n);
2290    swapl(&stuff->format, n);
2291    return (*ProcRenderVector[stuff->renderReqType]) (client);
2292}
2293
2294static int
2295SProcRenderReferenceGlyphSet (ClientPtr client)
2296{
2297    register int n;
2298    REQUEST(xRenderReferenceGlyphSetReq);
2299    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
2300    swaps(&stuff->length, n);
2301    swapl(&stuff->gsid, n);
2302    swapl(&stuff->existing, n);
2303    return (*ProcRenderVector[stuff->renderReqType])  (client);
2304}
2305
2306static int
2307SProcRenderFreeGlyphSet (ClientPtr client)
2308{
2309    register int n;
2310    REQUEST(xRenderFreeGlyphSetReq);
2311    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
2312    swaps(&stuff->length, n);
2313    swapl(&stuff->glyphset, n);
2314    return (*ProcRenderVector[stuff->renderReqType]) (client);
2315}
2316
2317static int
2318SProcRenderAddGlyphs (ClientPtr client)
2319{
2320    register int n;
2321    register int i;
2322    CARD32  *gids;
2323    void    *end;
2324    xGlyphInfo *gi;
2325    REQUEST(xRenderAddGlyphsReq);
2326    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
2327    swaps(&stuff->length, n);
2328    swapl(&stuff->glyphset, n);
2329    swapl(&stuff->nglyphs, n);
2330    if (stuff->nglyphs & 0xe0000000)
2331	return BadLength;
2332    end = (CARD8 *) stuff + (client->req_len << 2);
2333    gids = (CARD32 *) (stuff + 1);
2334    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
2335    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
2336	return BadLength;
2337    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
2338	return BadLength;
2339    for (i = 0; i < stuff->nglyphs; i++)
2340    {
2341	swapl (&gids[i], n);
2342	swaps (&gi[i].width, n);
2343	swaps (&gi[i].height, n);
2344	swaps (&gi[i].x, n);
2345	swaps (&gi[i].y, n);
2346	swaps (&gi[i].xOff, n);
2347	swaps (&gi[i].yOff, n);
2348    }
2349    return (*ProcRenderVector[stuff->renderReqType]) (client);
2350}
2351
2352static int
2353SProcRenderAddGlyphsFromPicture (ClientPtr client)
2354{
2355    return BadImplementation;
2356}
2357
2358static int
2359SProcRenderFreeGlyphs (ClientPtr client)
2360{
2361    register int n;
2362    REQUEST(xRenderFreeGlyphsReq);
2363    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
2364    swaps(&stuff->length, n);
2365    swapl(&stuff->glyphset, n);
2366    SwapRestL(stuff);
2367    return (*ProcRenderVector[stuff->renderReqType]) (client);
2368}
2369
2370static int
2371SProcRenderCompositeGlyphs (ClientPtr client)
2372{
2373    register int n;
2374    xGlyphElt	*elt;
2375    CARD8	*buffer;
2376    CARD8	*end;
2377    int		space;
2378    int		i;
2379    int		size;
2380
2381    REQUEST(xRenderCompositeGlyphsReq);
2382    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
2383
2384    switch (stuff->renderReqType) {
2385    default:			    size = 1; break;
2386    case X_RenderCompositeGlyphs16: size = 2; break;
2387    case X_RenderCompositeGlyphs32: size = 4; break;
2388    }
2389
2390    swaps(&stuff->length, n);
2391    swapl(&stuff->src, n);
2392    swapl(&stuff->dst, n);
2393    swapl(&stuff->maskFormat, n);
2394    swapl(&stuff->glyphset, n);
2395    swaps(&stuff->xSrc, n);
2396    swaps(&stuff->ySrc, n);
2397    buffer = (CARD8 *) (stuff + 1);
2398    end = (CARD8 *) stuff + (client->req_len << 2);
2399    while (buffer + sizeof (xGlyphElt) < end)
2400    {
2401	elt = (xGlyphElt *) buffer;
2402	buffer += sizeof (xGlyphElt);
2403
2404	swaps (&elt->deltax, n);
2405	swaps (&elt->deltay, n);
2406
2407	i = elt->len;
2408	if (i == 0xff)
2409	{
2410	    swapl (buffer, n);
2411	    buffer += 4;
2412	}
2413	else
2414	{
2415	    space = size * i;
2416	    switch (size) {
2417	    case 1:
2418		buffer += i;
2419		break;
2420	    case 2:
2421		while (i--)
2422		{
2423		    swaps (buffer, n);
2424		    buffer += 2;
2425		}
2426		break;
2427	    case 4:
2428		while (i--)
2429		{
2430		    swapl (buffer, n);
2431		    buffer += 4;
2432		}
2433		break;
2434	    }
2435	    if (space & 3)
2436		buffer += 4 - (space & 3);
2437	}
2438    }
2439    return (*ProcRenderVector[stuff->renderReqType]) (client);
2440}
2441
2442static int
2443SProcRenderFillRectangles (ClientPtr client)
2444{
2445    register int n;
2446    REQUEST(xRenderFillRectanglesReq);
2447
2448    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
2449    swaps(&stuff->length, n);
2450    swapl(&stuff->dst, n);
2451    swaps(&stuff->color.red, n);
2452    swaps(&stuff->color.green, n);
2453    swaps(&stuff->color.blue, n);
2454    swaps(&stuff->color.alpha, n);
2455    SwapRestS(stuff);
2456    return (*ProcRenderVector[stuff->renderReqType]) (client);
2457}
2458
2459static int
2460SProcRenderCreateCursor (ClientPtr client)
2461{
2462    register int n;
2463    REQUEST(xRenderCreateCursorReq);
2464    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
2465
2466    swaps(&stuff->length, n);
2467    swapl(&stuff->cid, n);
2468    swapl(&stuff->src, n);
2469    swaps(&stuff->x, n);
2470    swaps(&stuff->y, n);
2471    return (*ProcRenderVector[stuff->renderReqType]) (client);
2472}
2473
2474static int
2475SProcRenderSetPictureTransform (ClientPtr client)
2476{
2477    register int n;
2478    REQUEST(xRenderSetPictureTransformReq);
2479    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
2480
2481    swaps(&stuff->length, n);
2482    swapl(&stuff->picture, n);
2483    swapl(&stuff->transform.matrix11, n);
2484    swapl(&stuff->transform.matrix12, n);
2485    swapl(&stuff->transform.matrix13, n);
2486    swapl(&stuff->transform.matrix21, n);
2487    swapl(&stuff->transform.matrix22, n);
2488    swapl(&stuff->transform.matrix23, n);
2489    swapl(&stuff->transform.matrix31, n);
2490    swapl(&stuff->transform.matrix32, n);
2491    swapl(&stuff->transform.matrix33, n);
2492    return (*ProcRenderVector[stuff->renderReqType]) (client);
2493}
2494
2495static int
2496SProcRenderQueryFilters (ClientPtr client)
2497{
2498    register int n;
2499    REQUEST (xRenderQueryFiltersReq);
2500    REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
2501
2502    swaps(&stuff->length, n);
2503    swapl(&stuff->drawable, n);
2504    return (*ProcRenderVector[stuff->renderReqType]) (client);
2505}
2506
2507static int
2508SProcRenderSetPictureFilter (ClientPtr client)
2509{
2510    register int n;
2511    REQUEST (xRenderSetPictureFilterReq);
2512    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
2513
2514    swaps(&stuff->length, n);
2515    swapl(&stuff->picture, n);
2516    swaps(&stuff->nbytes, n);
2517    return (*ProcRenderVector[stuff->renderReqType]) (client);
2518}
2519
2520static int
2521SProcRenderCreateAnimCursor (ClientPtr client)
2522{
2523    register int n;
2524    REQUEST (xRenderCreateAnimCursorReq);
2525    REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
2526
2527    swaps(&stuff->length, n);
2528    swapl(&stuff->cid, n);
2529    SwapRestL(stuff);
2530    return (*ProcRenderVector[stuff->renderReqType]) (client);
2531}
2532
2533static int
2534SProcRenderAddTraps (ClientPtr client)
2535{
2536    register int n;
2537    REQUEST (xRenderAddTrapsReq);
2538    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
2539
2540    swaps(&stuff->length, n);
2541    swapl(&stuff->picture, n);
2542    swaps(&stuff->xOff, n);
2543    swaps(&stuff->yOff, n);
2544    SwapRestL(stuff);
2545    return (*ProcRenderVector[stuff->renderReqType]) (client);
2546}
2547
2548static int
2549SProcRenderCreateSolidFill(ClientPtr client)
2550{
2551    register int n;
2552    REQUEST (xRenderCreateSolidFillReq);
2553    REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
2554
2555    swaps(&stuff->length, n);
2556    swapl(&stuff->pid, n);
2557    swaps(&stuff->color.alpha, n);
2558    swaps(&stuff->color.red, n);
2559    swaps(&stuff->color.green, n);
2560    swaps(&stuff->color.blue, n);
2561    return (*ProcRenderVector[stuff->renderReqType]) (client);
2562}
2563
2564static void swapStops(void *stuff, int num)
2565{
2566    int i, n;
2567    CARD32 *stops;
2568    CARD16 *colors;
2569    stops = (CARD32 *)(stuff);
2570    for (i = 0; i < num; ++i) {
2571        swapl(stops, n);
2572        ++stops;
2573    }
2574    colors = (CARD16 *)(stops);
2575    for (i = 0; i < 4*num; ++i) {
2576        swaps(colors, n);
2577        ++colors;
2578    }
2579}
2580
2581static int
2582SProcRenderCreateLinearGradient (ClientPtr client)
2583{
2584    register int n;
2585    int len;
2586    REQUEST (xRenderCreateLinearGradientReq);
2587    REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
2588
2589    swaps(&stuff->length, n);
2590    swapl(&stuff->pid, n);
2591    swapl(&stuff->p1.x, n);
2592    swapl(&stuff->p1.y, n);
2593    swapl(&stuff->p2.x, n);
2594    swapl(&stuff->p2.y, n);
2595    swapl(&stuff->nStops, n);
2596
2597    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
2598    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
2599	return BadLength;
2600    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
2601        return BadLength;
2602
2603    swapStops(stuff+1, stuff->nStops);
2604
2605    return (*ProcRenderVector[stuff->renderReqType]) (client);
2606}
2607
2608static int
2609SProcRenderCreateRadialGradient (ClientPtr client)
2610{
2611    register int n;
2612    int len;
2613    REQUEST (xRenderCreateRadialGradientReq);
2614    REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
2615
2616    swaps(&stuff->length, n);
2617    swapl(&stuff->pid, n);
2618    swapl(&stuff->inner.x, n);
2619    swapl(&stuff->inner.y, n);
2620    swapl(&stuff->outer.x, n);
2621    swapl(&stuff->outer.y, n);
2622    swapl(&stuff->inner_radius, n);
2623    swapl(&stuff->outer_radius, n);
2624    swapl(&stuff->nStops, n);
2625
2626    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
2627    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
2628	return BadLength;
2629    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
2630        return BadLength;
2631
2632    swapStops(stuff+1, stuff->nStops);
2633
2634    return (*ProcRenderVector[stuff->renderReqType]) (client);
2635}
2636
2637static int
2638SProcRenderCreateConicalGradient (ClientPtr client)
2639{
2640    register int n;
2641    int len;
2642    REQUEST (xRenderCreateConicalGradientReq);
2643    REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
2644
2645    swaps(&stuff->length, n);
2646    swapl(&stuff->pid, n);
2647    swapl(&stuff->center.x, n);
2648    swapl(&stuff->center.y, n);
2649    swapl(&stuff->angle, n);
2650    swapl(&stuff->nStops, n);
2651
2652    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
2653    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
2654	return BadLength;
2655    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
2656        return BadLength;
2657
2658    swapStops(stuff+1, stuff->nStops);
2659
2660    return (*ProcRenderVector[stuff->renderReqType]) (client);
2661}
2662
2663static int
2664SProcRenderDispatch (ClientPtr client)
2665{
2666    REQUEST(xReq);
2667
2668    if (stuff->data < RenderNumberRequests)
2669	return (*SProcRenderVector[stuff->data]) (client);
2670    else
2671	return BadRequest;
2672}
2673
2674#ifdef PANORAMIX
2675#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\
2676    int rc = dixLookupResourceByType((pointer *)&(pPicture), pid,\
2677                                     XRT_PICTURE, client, mode);\
2678    if (rc != Success)\
2679	return rc;\
2680}
2681
2682#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\
2683    if (pid == None) \
2684	pPicture = 0; \
2685    else { \
2686	VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \
2687    } \
2688} \
2689
2690int	    (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
2691
2692static int
2693PanoramiXRenderCreatePicture (ClientPtr client)
2694{
2695    REQUEST(xRenderCreatePictureReq);
2696    PanoramiXRes    *refDraw, *newPict;
2697    int		    result, j;
2698
2699    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2700    result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable,
2701				      XRC_DRAWABLE, client, DixWriteAccess);
2702    if (result != Success)
2703	return (result == BadValue) ? BadDrawable : result;
2704    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
2705	return BadAlloc;
2706    newPict->type = XRT_PICTURE;
2707    newPict->info[0].id = stuff->pid;
2708
2709    if (refDraw->type == XRT_WINDOW &&
2710	stuff->drawable == screenInfo.screens[0]->root->drawable.id)
2711    {
2712	newPict->u.pict.root = TRUE;
2713    }
2714    else
2715	newPict->u.pict.root = FALSE;
2716
2717    for(j = 1; j < PanoramiXNumScreens; j++)
2718	newPict->info[j].id = FakeClientID(client->index);
2719
2720    FOR_NSCREENS_BACKWARD(j) {
2721	stuff->pid = newPict->info[j].id;
2722	stuff->drawable = refDraw->info[j].id;
2723	result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
2724	if(result != Success) break;
2725    }
2726
2727    if (result == Success)
2728	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
2729    else
2730	free(newPict);
2731
2732    return result;
2733}
2734
2735static int
2736PanoramiXRenderChangePicture (ClientPtr client)
2737{
2738    PanoramiXRes    *pict;
2739    int		    result = Success, j;
2740    REQUEST(xRenderChangePictureReq);
2741
2742    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
2743
2744    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2745
2746    FOR_NSCREENS_BACKWARD(j) {
2747        stuff->picture = pict->info[j].id;
2748        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
2749        if(result != Success) break;
2750    }
2751
2752    return result;
2753}
2754
2755static int
2756PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
2757{
2758    REQUEST(xRenderSetPictureClipRectanglesReq);
2759    int		    result = Success, j;
2760    PanoramiXRes    *pict;
2761
2762    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
2763
2764    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2765
2766    FOR_NSCREENS_BACKWARD(j) {
2767        stuff->picture = pict->info[j].id;
2768        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
2769        if(result != Success) break;
2770    }
2771
2772    return result;
2773}
2774
2775static int
2776PanoramiXRenderSetPictureTransform (ClientPtr client)
2777{
2778    REQUEST(xRenderSetPictureTransformReq);
2779    int		    result = Success, j;
2780    PanoramiXRes    *pict;
2781
2782    REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
2783
2784    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2785
2786    FOR_NSCREENS_BACKWARD(j) {
2787        stuff->picture = pict->info[j].id;
2788        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
2789        if(result != Success) break;
2790    }
2791
2792    return result;
2793}
2794
2795static int
2796PanoramiXRenderSetPictureFilter (ClientPtr client)
2797{
2798    REQUEST(xRenderSetPictureFilterReq);
2799    int		    result = Success, j;
2800    PanoramiXRes    *pict;
2801
2802    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
2803
2804    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2805
2806    FOR_NSCREENS_BACKWARD(j) {
2807        stuff->picture = pict->info[j].id;
2808        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
2809        if(result != Success) break;
2810    }
2811
2812    return result;
2813}
2814
2815static int
2816PanoramiXRenderFreePicture (ClientPtr client)
2817{
2818    PanoramiXRes *pict;
2819    int         result = Success, j;
2820    REQUEST(xRenderFreePictureReq);
2821
2822    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
2823
2824    client->errorValue = stuff->picture;
2825
2826    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess);
2827
2828
2829    FOR_NSCREENS_BACKWARD(j) {
2830	stuff->picture = pict->info[j].id;
2831	result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
2832	if(result != Success) break;
2833    }
2834
2835    /* Since ProcRenderFreePicture is using FreeResource, it will free
2836	our resource for us on the last pass through the loop above */
2837
2838    return result;
2839}
2840
2841static int
2842PanoramiXRenderComposite (ClientPtr client)
2843{
2844    PanoramiXRes	*src, *msk, *dst;
2845    int			result = Success, j;
2846    xRenderCompositeReq	orig;
2847    REQUEST(xRenderCompositeReq);
2848
2849    REQUEST_SIZE_MATCH(xRenderCompositeReq);
2850
2851    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
2852    VERIFY_XIN_ALPHA (msk, stuff->mask, client, DixReadAccess);
2853    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
2854
2855    orig = *stuff;
2856
2857    FOR_NSCREENS_FORWARD(j) {
2858	stuff->src = src->info[j].id;
2859	if (src->u.pict.root)
2860	{
2861	    stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x;
2862	    stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y;
2863	}
2864	stuff->dst = dst->info[j].id;
2865	if (dst->u.pict.root)
2866	{
2867	    stuff->xDst = orig.xDst - screenInfo.screens[j]->x;
2868	    stuff->yDst = orig.yDst - screenInfo.screens[j]->y;
2869	}
2870	if (msk)
2871	{
2872	    stuff->mask = msk->info[j].id;
2873	    if (msk->u.pict.root)
2874	    {
2875		stuff->xMask = orig.xMask - screenInfo.screens[j]->x;
2876		stuff->yMask = orig.yMask - screenInfo.screens[j]->y;
2877	    }
2878	}
2879	result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
2880	if(result != Success) break;
2881    }
2882
2883    return result;
2884}
2885
2886static int
2887PanoramiXRenderCompositeGlyphs (ClientPtr client)
2888{
2889    PanoramiXRes    *src, *dst;
2890    int		    result = Success, j;
2891    REQUEST(xRenderCompositeGlyphsReq);
2892    xGlyphElt	    origElt, *elt;
2893    INT16	    xSrc, ySrc;
2894
2895    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
2896    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
2897    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
2898
2899    if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
2900				 sizeof (xGlyphElt)))
2901    {
2902	elt = (xGlyphElt *) (stuff + 1);
2903	origElt = *elt;
2904	xSrc = stuff->xSrc;
2905	ySrc = stuff->ySrc;
2906	FOR_NSCREENS_FORWARD(j) {
2907	    stuff->src = src->info[j].id;
2908	    if (src->u.pict.root)
2909	    {
2910		stuff->xSrc = xSrc - screenInfo.screens[j]->x;
2911		stuff->ySrc = ySrc - screenInfo.screens[j]->y;
2912	    }
2913	    stuff->dst = dst->info[j].id;
2914	    if (dst->u.pict.root)
2915	    {
2916		elt->deltax = origElt.deltax - screenInfo.screens[j]->x;
2917		elt->deltay = origElt.deltay - screenInfo.screens[j]->y;
2918	    }
2919	    result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
2920	    if(result != Success) break;
2921	}
2922    }
2923
2924    return result;
2925}
2926
2927static int
2928PanoramiXRenderFillRectangles (ClientPtr client)
2929{
2930    PanoramiXRes    *dst;
2931    int		    result = Success, j;
2932    REQUEST(xRenderFillRectanglesReq);
2933    char	    *extra;
2934    int		    extra_len;
2935
2936    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
2937    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
2938    extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
2939    if (extra_len &&
2940	(extra = (char *) malloc(extra_len)))
2941    {
2942	memcpy (extra, stuff + 1, extra_len);
2943	FOR_NSCREENS_FORWARD(j) {
2944	    if (j) memcpy (stuff + 1, extra, extra_len);
2945	    if (dst->u.pict.root)
2946	    {
2947		int x_off = screenInfo.screens[j]->x;
2948		int y_off = screenInfo.screens[j]->y;
2949
2950		if(x_off || y_off) {
2951		    xRectangle	*rects = (xRectangle *) (stuff + 1);
2952		    int		i = extra_len / sizeof (xRectangle);
2953
2954		    while (i--)
2955		    {
2956			rects->x -= x_off;
2957			rects->y -= y_off;
2958			rects++;
2959		    }
2960		}
2961	    }
2962	    stuff->dst = dst->info[j].id;
2963	    result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
2964	    if(result != Success) break;
2965	}
2966	free(extra);
2967    }
2968
2969    return result;
2970}
2971
2972static int
2973PanoramiXRenderTrapezoids(ClientPtr client)
2974{
2975    PanoramiXRes        *src, *dst;
2976    int                 result = Success, j;
2977    REQUEST(xRenderTrapezoidsReq);
2978    char		*extra;
2979    int			extra_len;
2980
2981    REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
2982
2983    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
2984    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
2985
2986    extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
2987
2988    if (extra_len &&
2989	(extra = (char *) malloc(extra_len))) {
2990	memcpy (extra, stuff + 1, extra_len);
2991
2992	FOR_NSCREENS_FORWARD(j) {
2993	    if (j) memcpy (stuff + 1, extra, extra_len);
2994	    if (dst->u.pict.root) {
2995		int x_off = screenInfo.screens[j]->x;
2996		int y_off = screenInfo.screens[j]->y;
2997
2998		if(x_off || y_off) {
2999                    xTrapezoid  *trap = (xTrapezoid *) (stuff + 1);
3000		    int         i = extra_len / sizeof (xTrapezoid);
3001
3002		    while (i--) {
3003			trap->top -= y_off;
3004			trap->bottom -= y_off;
3005			trap->left.p1.x -= x_off;
3006			trap->left.p1.y -= y_off;
3007			trap->left.p2.x -= x_off;
3008			trap->left.p2.y -= y_off;
3009			trap->right.p1.x -= x_off;
3010			trap->right.p1.y -= y_off;
3011			trap->right.p2.x -= x_off;
3012			trap->right.p2.y -= y_off;
3013			trap++;
3014		    }
3015		}
3016	    }
3017
3018            stuff->src = src->info[j].id;
3019            stuff->dst = dst->info[j].id;
3020	    result =
3021		(*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
3022
3023	    if(result != Success) break;
3024	}
3025
3026        free(extra);
3027    }
3028
3029    return result;
3030}
3031
3032static int
3033PanoramiXRenderTriangles(ClientPtr client)
3034{
3035    PanoramiXRes        *src, *dst;
3036    int                 result = Success, j;
3037    REQUEST(xRenderTrianglesReq);
3038    char		*extra;
3039    int			extra_len;
3040
3041    REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
3042
3043    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
3044    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
3045
3046    extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
3047
3048    if (extra_len &&
3049	(extra = (char *) malloc(extra_len))) {
3050	memcpy (extra, stuff + 1, extra_len);
3051
3052	FOR_NSCREENS_FORWARD(j) {
3053	    if (j) memcpy (stuff + 1, extra, extra_len);
3054	    if (dst->u.pict.root) {
3055		int x_off = screenInfo.screens[j]->x;
3056		int y_off = screenInfo.screens[j]->y;
3057
3058		if(x_off || y_off) {
3059                    xTriangle  *tri = (xTriangle *) (stuff + 1);
3060		    int         i = extra_len / sizeof (xTriangle);
3061
3062		    while (i--) {
3063			tri->p1.x -= x_off;
3064			tri->p1.y -= y_off;
3065			tri->p2.x -= x_off;
3066			tri->p2.y -= y_off;
3067			tri->p3.x -= x_off;
3068			tri->p3.y -= y_off;
3069			tri++;
3070		    }
3071		}
3072	    }
3073
3074            stuff->src = src->info[j].id;
3075            stuff->dst = dst->info[j].id;
3076	    result =
3077		(*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
3078
3079	    if(result != Success) break;
3080	}
3081
3082        free(extra);
3083    }
3084
3085    return result;
3086}
3087
3088static int
3089PanoramiXRenderTriStrip(ClientPtr client)
3090{
3091    PanoramiXRes        *src, *dst;
3092    int                 result = Success, j;
3093    REQUEST(xRenderTriStripReq);
3094    char		*extra;
3095    int			extra_len;
3096
3097    REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
3098
3099    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
3100    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
3101
3102    extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
3103
3104    if (extra_len &&
3105	(extra = (char *) malloc(extra_len))) {
3106	memcpy (extra, stuff + 1, extra_len);
3107
3108	FOR_NSCREENS_FORWARD(j) {
3109	    if (j) memcpy (stuff + 1, extra, extra_len);
3110	    if (dst->u.pict.root) {
3111		int x_off = screenInfo.screens[j]->x;
3112		int y_off = screenInfo.screens[j]->y;
3113
3114		if(x_off || y_off) {
3115                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
3116		    int         i = extra_len / sizeof (xPointFixed);
3117
3118		    while (i--) {
3119			fixed->x -= x_off;
3120			fixed->y -= y_off;
3121			fixed++;
3122		    }
3123		}
3124	    }
3125
3126            stuff->src = src->info[j].id;
3127            stuff->dst = dst->info[j].id;
3128	    result =
3129		(*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
3130
3131	    if(result != Success) break;
3132	}
3133
3134        free(extra);
3135    }
3136
3137    return result;
3138}
3139
3140static int
3141PanoramiXRenderTriFan(ClientPtr client)
3142{
3143    PanoramiXRes        *src, *dst;
3144    int                 result = Success, j;
3145    REQUEST(xRenderTriFanReq);
3146    char		*extra;
3147    int			extra_len;
3148
3149    REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
3150
3151    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
3152    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
3153
3154    extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
3155
3156    if (extra_len &&
3157	(extra = (char *) malloc(extra_len))) {
3158	memcpy (extra, stuff + 1, extra_len);
3159
3160	FOR_NSCREENS_FORWARD(j) {
3161	    if (j) memcpy (stuff + 1, extra, extra_len);
3162	    if (dst->u.pict.root) {
3163		int x_off = screenInfo.screens[j]->x;
3164		int y_off = screenInfo.screens[j]->y;
3165
3166		if(x_off || y_off) {
3167                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
3168		    int         i = extra_len / sizeof (xPointFixed);
3169
3170		    while (i--) {
3171			fixed->x -= x_off;
3172			fixed->y -= y_off;
3173			fixed++;
3174		    }
3175		}
3176	    }
3177
3178            stuff->src = src->info[j].id;
3179            stuff->dst = dst->info[j].id;
3180	    result =
3181		(*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
3182
3183	    if(result != Success) break;
3184	}
3185
3186        free(extra);
3187    }
3188
3189    return result;
3190}
3191
3192static int
3193PanoramiXRenderAddTraps (ClientPtr client)
3194{
3195    PanoramiXRes    *picture;
3196    int		    result = Success, j;
3197    REQUEST(xRenderAddTrapsReq);
3198    char	    *extra;
3199    int		    extra_len;
3200    INT16    	    x_off, y_off;
3201
3202    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
3203    VERIFY_XIN_PICTURE (picture, stuff->picture, client, DixWriteAccess);
3204    extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
3205    if (extra_len &&
3206	(extra = (char *) malloc(extra_len)))
3207    {
3208	memcpy (extra, stuff + 1, extra_len);
3209	x_off = stuff->xOff;
3210	y_off = stuff->yOff;
3211	FOR_NSCREENS_FORWARD(j) {
3212	    if (j) memcpy (stuff + 1, extra, extra_len);
3213	    stuff->picture = picture->info[j].id;
3214
3215	    if (picture->u.pict.root)
3216	    {
3217		stuff->xOff = x_off + screenInfo.screens[j]->x;
3218		stuff->yOff = y_off + screenInfo.screens[j]->y;
3219	    }
3220	    result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
3221	    if(result != Success) break;
3222	}
3223	free(extra);
3224    }
3225
3226    return result;
3227}
3228
3229static int
3230PanoramiXRenderCreateSolidFill (ClientPtr client)
3231{
3232    REQUEST(xRenderCreateSolidFillReq);
3233    PanoramiXRes    *newPict;
3234    int		    result = Success, j;
3235
3236    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
3237
3238    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3239	return BadAlloc;
3240
3241    newPict->type = XRT_PICTURE;
3242    newPict->info[0].id = stuff->pid;
3243    newPict->u.pict.root = FALSE;
3244
3245    for(j = 1; j < PanoramiXNumScreens; j++)
3246	newPict->info[j].id = FakeClientID(client->index);
3247
3248    FOR_NSCREENS_BACKWARD(j) {
3249	stuff->pid = newPict->info[j].id;
3250	result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client);
3251	if(result != Success) break;
3252    }
3253
3254    if (result == Success)
3255	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3256    else
3257	free(newPict);
3258
3259    return result;
3260}
3261
3262static int
3263PanoramiXRenderCreateLinearGradient (ClientPtr client)
3264{
3265    REQUEST(xRenderCreateLinearGradientReq);
3266    PanoramiXRes    *newPict;
3267    int		    result = Success, j;
3268
3269    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
3270
3271    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3272	return BadAlloc;
3273
3274    newPict->type = XRT_PICTURE;
3275    newPict->info[0].id = stuff->pid;
3276    newPict->u.pict.root = FALSE;
3277
3278    for(j = 1; j < PanoramiXNumScreens; j++)
3279	newPict->info[j].id = FakeClientID(client->index);
3280
3281    FOR_NSCREENS_BACKWARD(j) {
3282	stuff->pid = newPict->info[j].id;
3283	result = (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client);
3284	if(result != Success) break;
3285    }
3286
3287    if (result == Success)
3288	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3289    else
3290	free(newPict);
3291
3292    return result;
3293}
3294
3295static int
3296PanoramiXRenderCreateRadialGradient (ClientPtr client)
3297{
3298    REQUEST(xRenderCreateRadialGradientReq);
3299    PanoramiXRes    *newPict;
3300    int		    result = Success, j;
3301
3302    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
3303
3304    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3305	return BadAlloc;
3306
3307    newPict->type = XRT_PICTURE;
3308    newPict->info[0].id = stuff->pid;
3309    newPict->u.pict.root = FALSE;
3310
3311    for(j = 1; j < PanoramiXNumScreens; j++)
3312	newPict->info[j].id = FakeClientID(client->index);
3313
3314    FOR_NSCREENS_BACKWARD(j) {
3315	stuff->pid = newPict->info[j].id;
3316	result = (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client);
3317	if(result != Success) break;
3318    }
3319
3320    if (result == Success)
3321	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3322    else
3323	free(newPict);
3324
3325    return result;
3326}
3327
3328static int
3329PanoramiXRenderCreateConicalGradient (ClientPtr client)
3330{
3331    REQUEST(xRenderCreateConicalGradientReq);
3332    PanoramiXRes    *newPict;
3333    int		    result = Success, j;
3334
3335    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
3336
3337    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3338	return BadAlloc;
3339
3340    newPict->type = XRT_PICTURE;
3341    newPict->info[0].id = stuff->pid;
3342    newPict->u.pict.root = FALSE;
3343
3344    for(j = 1; j < PanoramiXNumScreens; j++)
3345	newPict->info[j].id = FakeClientID(client->index);
3346
3347    FOR_NSCREENS_BACKWARD(j) {
3348	stuff->pid = newPict->info[j].id;
3349	result = (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient]) (client);
3350	if(result != Success) break;
3351    }
3352
3353    if (result == Success)
3354	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3355    else
3356	free(newPict);
3357
3358    return result;
3359}
3360
3361void
3362PanoramiXRenderInit (void)
3363{
3364    int	    i;
3365
3366    XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource,
3367					 "XineramaPicture");
3368    if (RenderErrBase)
3369	SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
3370    for (i = 0; i < RenderNumberRequests; i++)
3371	PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
3372    /*
3373     * Stuff in Xinerama aware request processing hooks
3374     */
3375    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
3376    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
3377    ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
3378    ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
3379    ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
3380    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
3381    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
3382    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
3383    ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
3384    ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
3385    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
3386
3387    ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
3388    ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
3389    ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
3390    ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
3391    ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
3392
3393    ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill;
3394    ProcRenderVector[X_RenderCreateLinearGradient] = PanoramiXRenderCreateLinearGradient;
3395    ProcRenderVector[X_RenderCreateRadialGradient] = PanoramiXRenderCreateRadialGradient;
3396    ProcRenderVector[X_RenderCreateConicalGradient] = PanoramiXRenderCreateConicalGradient;
3397}
3398
3399void
3400PanoramiXRenderReset (void)
3401{
3402    int	    i;
3403    for (i = 0; i < RenderNumberRequests; i++)
3404	ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
3405    RenderErrBase = 0;
3406}
3407
3408#endif	/* PANORAMIX */
3409