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