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