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