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