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