Imported Upstream version 1.15.1
[deb_xorg-server.git] / render / render.c
CommitLineData
a09e091a
JB
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
58static int ProcRenderQueryVersion(ClientPtr pClient);
59static int ProcRenderQueryPictFormats(ClientPtr pClient);
60static int ProcRenderQueryPictIndexValues(ClientPtr pClient);
61static int ProcRenderQueryDithers(ClientPtr pClient);
62static int ProcRenderCreatePicture(ClientPtr pClient);
63static int ProcRenderChangePicture(ClientPtr pClient);
64static int ProcRenderSetPictureClipRectangles(ClientPtr pClient);
65static int ProcRenderFreePicture(ClientPtr pClient);
66static int ProcRenderComposite(ClientPtr pClient);
67static int ProcRenderScale(ClientPtr pClient);
68static int ProcRenderTrapezoids(ClientPtr pClient);
69static int ProcRenderTriangles(ClientPtr pClient);
70static int ProcRenderTriStrip(ClientPtr pClient);
71static int ProcRenderTriFan(ClientPtr pClient);
72static int ProcRenderColorTrapezoids(ClientPtr pClient);
73static int ProcRenderColorTriangles(ClientPtr pClient);
74static int ProcRenderTransform(ClientPtr pClient);
75static int ProcRenderCreateGlyphSet(ClientPtr pClient);
76static int ProcRenderReferenceGlyphSet(ClientPtr pClient);
77static int ProcRenderFreeGlyphSet(ClientPtr pClient);
78static int ProcRenderAddGlyphs(ClientPtr pClient);
79static int ProcRenderAddGlyphsFromPicture(ClientPtr pClient);
80static int ProcRenderFreeGlyphs(ClientPtr pClient);
81static int ProcRenderCompositeGlyphs(ClientPtr pClient);
82static int ProcRenderFillRectangles(ClientPtr pClient);
83static int ProcRenderCreateCursor(ClientPtr pClient);
84static int ProcRenderSetPictureTransform(ClientPtr pClient);
85static int ProcRenderQueryFilters(ClientPtr pClient);
86static int ProcRenderSetPictureFilter(ClientPtr pClient);
87static int ProcRenderCreateAnimCursor(ClientPtr pClient);
88static int ProcRenderAddTraps(ClientPtr pClient);
89static int ProcRenderCreateSolidFill(ClientPtr pClient);
90static int ProcRenderCreateLinearGradient(ClientPtr pClient);
91static int ProcRenderCreateRadialGradient(ClientPtr pClient);
92static int ProcRenderCreateConicalGradient(ClientPtr pClient);
93
94static int ProcRenderDispatch(ClientPtr pClient);
95
96static int SProcRenderQueryVersion(ClientPtr pClient);
97static int SProcRenderQueryPictFormats(ClientPtr pClient);
98static int SProcRenderQueryPictIndexValues(ClientPtr pClient);
99static int SProcRenderQueryDithers(ClientPtr pClient);
100static int SProcRenderCreatePicture(ClientPtr pClient);
101static int SProcRenderChangePicture(ClientPtr pClient);
102static int SProcRenderSetPictureClipRectangles(ClientPtr pClient);
103static int SProcRenderFreePicture(ClientPtr pClient);
104static int SProcRenderComposite(ClientPtr pClient);
105static int SProcRenderScale(ClientPtr pClient);
106static int SProcRenderTrapezoids(ClientPtr pClient);
107static int SProcRenderTriangles(ClientPtr pClient);
108static int SProcRenderTriStrip(ClientPtr pClient);
109static int SProcRenderTriFan(ClientPtr pClient);
110static int SProcRenderColorTrapezoids(ClientPtr pClient);
111static int SProcRenderColorTriangles(ClientPtr pClient);
112static int SProcRenderTransform(ClientPtr pClient);
113static int SProcRenderCreateGlyphSet(ClientPtr pClient);
114static int SProcRenderReferenceGlyphSet(ClientPtr pClient);
115static int SProcRenderFreeGlyphSet(ClientPtr pClient);
116static int SProcRenderAddGlyphs(ClientPtr pClient);
117static int SProcRenderAddGlyphsFromPicture(ClientPtr pClient);
118static int SProcRenderFreeGlyphs(ClientPtr pClient);
119static int SProcRenderCompositeGlyphs(ClientPtr pClient);
120static int SProcRenderFillRectangles(ClientPtr pClient);
121static int SProcRenderCreateCursor(ClientPtr pClient);
122static int SProcRenderSetPictureTransform(ClientPtr pClient);
123static int SProcRenderQueryFilters(ClientPtr pClient);
124static int SProcRenderSetPictureFilter(ClientPtr pClient);
125static int SProcRenderCreateAnimCursor(ClientPtr pClient);
126static int SProcRenderAddTraps(ClientPtr pClient);
127static int SProcRenderCreateSolidFill(ClientPtr pClient);
128static int SProcRenderCreateLinearGradient(ClientPtr pClient);
129static int SProcRenderCreateRadialGradient(ClientPtr pClient);
130static int SProcRenderCreateConicalGradient(ClientPtr pClient);
131
132static int SProcRenderDispatch(ClientPtr pClient);
133
134int (*ProcRenderVector[RenderNumberRequests]) (ClientPtr) = {
135ProcRenderQueryVersion,
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
172int (*SProcRenderVector[RenderNumberRequests]) (ClientPtr) = {
173SProcRenderQueryVersion,
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
210int RenderErrBase;
211static DevPrivateKeyRec RenderClientPrivateKeyRec;
212
213#define RenderClientPrivateKey (&RenderClientPrivateKeyRec )
214
215typedef struct _RenderClient {
216 int major_version;
217 int minor_version;
218} RenderClientRec, *RenderClientPtr;
219
220#define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey))
221
222static void
223RenderClientCallback(CallbackListPtr *list, pointer closure, pointer data)
224{
225 NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
226 ClientPtr pClient = clientinfo->client;
227 RenderClientPtr pRenderClient = GetRenderClient(pClient);
228
229 pRenderClient->major_version = 0;
230 pRenderClient->minor_version = 0;
231}
232
233#ifdef PANORAMIX
234RESTYPE XRT_PICTURE;
235#endif
236
237void
238RenderExtensionInit(void)
239{
240 ExtensionEntry *extEntry;
241
242 if (!PictureType)
243 return;
244 if (!PictureFinishInit())
245 return;
246 if (!dixRegisterPrivateKey
247 (&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec)))
248 return;
249 if (!AddCallback(&ClientStateCallback, RenderClientCallback, 0))
250 return;
251
252 extEntry = AddExtension(RENDER_NAME, 0, RenderNumberErrors,
253 ProcRenderDispatch, SProcRenderDispatch,
254 NULL, StandardMinorOpcode);
255 if (!extEntry)
256 return;
257 RenderErrBase = extEntry->errorBase;
258#ifdef PANORAMIX
259 if (XRT_PICTURE)
260 SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
261#endif
262 SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture);
263 SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat);
264 SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet);
265}
266
267static int
268ProcRenderQueryVersion(ClientPtr client)
269{
270 RenderClientPtr pRenderClient = GetRenderClient(client);
271 xRenderQueryVersionReply rep = {
272 .type = X_Reply,
273 .sequenceNumber = client->sequence,
274 .length = 0
275 };
276
277 REQUEST(xRenderQueryVersionReq);
278
279 pRenderClient->major_version = stuff->majorVersion;
280 pRenderClient->minor_version = stuff->minorVersion;
281
282 REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
283
284 if ((stuff->majorVersion * 1000 + stuff->minorVersion) <
285 (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) {
286 rep.majorVersion = stuff->majorVersion;
287 rep.minorVersion = stuff->minorVersion;
288 }
289 else {
290 rep.majorVersion = SERVER_RENDER_MAJOR_VERSION;
291 rep.minorVersion = SERVER_RENDER_MINOR_VERSION;
292 }
293
294 if (client->swapped) {
295 swaps(&rep.sequenceNumber);
296 swapl(&rep.length);
297 swapl(&rep.majorVersion);
298 swapl(&rep.minorVersion);
299 }
300 WriteToClient(client, sizeof(xRenderQueryVersionReply), &rep);
301 return Success;
302}
303
304static VisualPtr
305findVisual(ScreenPtr pScreen, VisualID vid)
306{
307 VisualPtr pVisual;
308 int v;
309
310 for (v = 0; v < pScreen->numVisuals; v++) {
311 pVisual = pScreen->visuals + v;
312 if (pVisual->vid == vid)
313 return pVisual;
314 }
315 return 0;
316}
317
318static int
319ProcRenderQueryPictFormats(ClientPtr client)
320{
321 RenderClientPtr pRenderClient = GetRenderClient(client);
322 xRenderQueryPictFormatsReply *reply;
323 xPictScreen *pictScreen;
324 xPictDepth *pictDepth;
325 xPictVisual *pictVisual;
326 xPictFormInfo *pictForm;
327 CARD32 *pictSubpixel;
328 ScreenPtr pScreen;
329 VisualPtr pVisual;
330 DepthPtr pDepth;
331 int v, d;
332 PictureScreenPtr ps;
333 PictFormatPtr pFormat;
334 int nformat;
335 int ndepth;
336 int nvisual;
337 int rlength;
338 int s;
339 int numScreens;
340 int numSubpixel;
341
342/* REQUEST(xRenderQueryPictFormatsReq); */
343
344 REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
345
346#ifdef PANORAMIX
347 if (noPanoramiXExtension)
348 numScreens = screenInfo.numScreens;
349 else
350 numScreens = ((xConnSetup *) ConnectionInfo)->numRoots;
351#else
352 numScreens = screenInfo.numScreens;
353#endif
354 ndepth = nformat = nvisual = 0;
355 for (s = 0; s < numScreens; s++) {
356 pScreen = screenInfo.screens[s];
357 for (d = 0; d < pScreen->numDepths; d++) {
358 pDepth = pScreen->allowedDepths + d;
359 ++ndepth;
360
361 for (v = 0; v < pDepth->numVids; v++) {
362 pVisual = findVisual(pScreen, pDepth->vids[v]);
363 if (pVisual &&
364 PictureMatchVisual(pScreen, pDepth->depth, pVisual))
365 ++nvisual;
366 }
367 }
368 ps = GetPictureScreenIfSet(pScreen);
369 if (ps)
370 nformat += ps->nformats;
371 }
372 if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
373 numSubpixel = 0;
374 else
375 numSubpixel = numScreens;
376
377 rlength = (sizeof(xRenderQueryPictFormatsReply) +
378 nformat * sizeof(xPictFormInfo) +
379 numScreens * sizeof(xPictScreen) +
380 ndepth * sizeof(xPictDepth) +
381 nvisual * sizeof(xPictVisual) + numSubpixel * sizeof(CARD32));
382 reply = (xRenderQueryPictFormatsReply *) calloc(1, rlength);
383 if (!reply)
384 return BadAlloc;
385 reply->type = X_Reply;
386 reply->sequenceNumber = client->sequence;
387 reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
388 reply->numFormats = nformat;
389 reply->numScreens = numScreens;
390 reply->numDepths = ndepth;
391 reply->numVisuals = nvisual;
392 reply->numSubpixel = numSubpixel;
393
394 pictForm = (xPictFormInfo *) (reply + 1);
395
396 for (s = 0; s < numScreens; s++) {
397 pScreen = screenInfo.screens[s];
398 ps = GetPictureScreenIfSet(pScreen);
399 if (ps) {
400 for (nformat = 0, pFormat = ps->formats;
401 nformat < ps->nformats; nformat++, pFormat++) {
402 pictForm->id = pFormat->id;
403 pictForm->type = pFormat->type;
404 pictForm->depth = pFormat->depth;
405 pictForm->direct.red = pFormat->direct.red;
406 pictForm->direct.redMask = pFormat->direct.redMask;
407 pictForm->direct.green = pFormat->direct.green;
408 pictForm->direct.greenMask = pFormat->direct.greenMask;
409 pictForm->direct.blue = pFormat->direct.blue;
410 pictForm->direct.blueMask = pFormat->direct.blueMask;
411 pictForm->direct.alpha = pFormat->direct.alpha;
412 pictForm->direct.alphaMask = pFormat->direct.alphaMask;
413 if (pFormat->type == PictTypeIndexed &&
414 pFormat->index.pColormap)
415 pictForm->colormap = pFormat->index.pColormap->mid;
416 else
417 pictForm->colormap = None;
418 if (client->swapped) {
419 swapl(&pictForm->id);
420 swaps(&pictForm->direct.red);
421 swaps(&pictForm->direct.redMask);
422 swaps(&pictForm->direct.green);
423 swaps(&pictForm->direct.greenMask);
424 swaps(&pictForm->direct.blue);
425 swaps(&pictForm->direct.blueMask);
426 swaps(&pictForm->direct.alpha);
427 swaps(&pictForm->direct.alphaMask);
428 swapl(&pictForm->colormap);
429 }
430 pictForm++;
431 }
432 }
433 }
434
435 pictScreen = (xPictScreen *) pictForm;
436 for (s = 0; s < numScreens; s++) {
437 pScreen = screenInfo.screens[s];
438 pictDepth = (xPictDepth *) (pictScreen + 1);
439 ndepth = 0;
440 for (d = 0; d < pScreen->numDepths; d++) {
441 pictVisual = (xPictVisual *) (pictDepth + 1);
442 pDepth = pScreen->allowedDepths + d;
443
444 nvisual = 0;
445 for (v = 0; v < pDepth->numVids; v++) {
446 pVisual = findVisual(pScreen, pDepth->vids[v]);
447 if (pVisual && (pFormat = PictureMatchVisual(pScreen,
448 pDepth->depth,
449 pVisual))) {
450 pictVisual->visual = pVisual->vid;
451 pictVisual->format = pFormat->id;
452 if (client->swapped) {
453 swapl(&pictVisual->visual);
454 swapl(&pictVisual->format);
455 }
456 pictVisual++;
457 nvisual++;
458 }
459 }
460 pictDepth->depth = pDepth->depth;
461 pictDepth->nPictVisuals = nvisual;
462 if (client->swapped) {
463 swaps(&pictDepth->nPictVisuals);
464 }
465 ndepth++;
466 pictDepth = (xPictDepth *) pictVisual;
467 }
468 pictScreen->nDepth = ndepth;
469 ps = GetPictureScreenIfSet(pScreen);
470 if (ps)
471 pictScreen->fallback = ps->fallback->id;
472 else
473 pictScreen->fallback = 0;
474 if (client->swapped) {
475 swapl(&pictScreen->nDepth);
476 swapl(&pictScreen->fallback);
477 }
478 pictScreen = (xPictScreen *) pictDepth;
479 }
480 pictSubpixel = (CARD32 *) pictScreen;
481
482 for (s = 0; s < numSubpixel; s++) {
483 pScreen = screenInfo.screens[s];
484 ps = GetPictureScreenIfSet(pScreen);
485 if (ps)
486 *pictSubpixel = ps->subpixel;
487 else
488 *pictSubpixel = SubPixelUnknown;
489 if (client->swapped) {
490 swapl(pictSubpixel);
491 }
492 ++pictSubpixel;
493 }
494
495 if (client->swapped) {
496 swaps(&reply->sequenceNumber);
497 swapl(&reply->length);
498 swapl(&reply->numFormats);
499 swapl(&reply->numScreens);
500 swapl(&reply->numDepths);
501 swapl(&reply->numVisuals);
502 swapl(&reply->numSubpixel);
503 }
504 WriteToClient(client, rlength, reply);
505 free(reply);
506 return Success;
507}
508
509static int
510ProcRenderQueryPictIndexValues(ClientPtr client)
511{
512 PictFormatPtr pFormat;
513 int rc, num;
514 int rlength;
515 int i;
516
517 REQUEST(xRenderQueryPictIndexValuesReq);
518 xRenderQueryPictIndexValuesReply *reply;
519 xIndexValue *values;
520
521 REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
522
523 rc = dixLookupResourceByType((pointer *) &pFormat, stuff->format,
524 PictFormatType, client, DixReadAccess);
525 if (rc != Success)
526 return rc;
527
528 if (pFormat->type != PictTypeIndexed) {
529 client->errorValue = stuff->format;
530 return BadMatch;
531 }
532 num = pFormat->index.nvalues;
533 rlength = (sizeof(xRenderQueryPictIndexValuesReply) +
534 num * sizeof(xIndexValue));
535 reply = (xRenderQueryPictIndexValuesReply *) calloc(1, rlength);
536 if (!reply)
537 return BadAlloc;
538
539 reply->type = X_Reply;
540 reply->sequenceNumber = client->sequence;
541 reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
542 reply->numIndexValues = num;
543
544 values = (xIndexValue *) (reply + 1);
545
546 memcpy(reply + 1, pFormat->index.pValues, num * sizeof(xIndexValue));
547
548 if (client->swapped) {
549 for (i = 0; i < num; i++) {
550 swapl(&values[i].pixel);
551 swaps(&values[i].red);
552 swaps(&values[i].green);
553 swaps(&values[i].blue);
554 swaps(&values[i].alpha);
555 }
556 swaps(&reply->sequenceNumber);
557 swapl(&reply->length);
558 swapl(&reply->numIndexValues);
559 }
560
561 WriteToClient(client, rlength, reply);
562 free(reply);
563 return Success;
564}
565
566static int
567ProcRenderQueryDithers(ClientPtr client)
568{
569 return BadImplementation;
570}
571
572static int
573ProcRenderCreatePicture(ClientPtr client)
574{
575 PicturePtr pPicture;
576 DrawablePtr pDrawable;
577 PictFormatPtr pFormat;
578 int len, error, rc;
579
580 REQUEST(xRenderCreatePictureReq);
581
582 REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
583
584 LEGAL_NEW_RESOURCE(stuff->pid, client);
585 rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
586 DixReadAccess | DixAddAccess);
587 if (rc != Success)
588 return rc;
589
590 rc = dixLookupResourceByType((pointer *) &pFormat, stuff->format,
591 PictFormatType, client, DixReadAccess);
592 if (rc != Success)
593 return rc;
594
595 if (pFormat->depth != pDrawable->depth)
596 return BadMatch;
597 len = client->req_len - bytes_to_int32(sizeof(xRenderCreatePictureReq));
598 if (Ones(stuff->mask) != len)
599 return BadLength;
600
601 pPicture = CreatePicture(stuff->pid,
602 pDrawable,
603 pFormat,
604 stuff->mask, (XID *) (stuff + 1), client, &error);
605 if (!pPicture)
606 return error;
607 if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
608 return BadAlloc;
609 return Success;
610}
611
612static int
613ProcRenderChangePicture(ClientPtr client)
614{
615 PicturePtr pPicture;
616
617 REQUEST(xRenderChangePictureReq);
618 int len;
619
620 REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
621 VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
622
623 len = client->req_len - bytes_to_int32(sizeof(xRenderChangePictureReq));
624 if (Ones(stuff->mask) != len)
625 return BadLength;
626
627 return ChangePicture(pPicture, stuff->mask, (XID *) (stuff + 1),
628 (DevUnion *) 0, client);
629}
630
631static int
632ProcRenderSetPictureClipRectangles(ClientPtr client)
633{
634 REQUEST(xRenderSetPictureClipRectanglesReq);
635 PicturePtr pPicture;
636 int nr;
637
638 REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
639 VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
640 if (!pPicture->pDrawable)
641 return BadDrawable;
642
643 nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
644 if (nr & 4)
645 return BadLength;
646 nr >>= 3;
647 return SetPictureClipRects(pPicture,
648 stuff->xOrigin, stuff->yOrigin,
649 nr, (xRectangle *) &stuff[1]);
650}
651
652static int
653ProcRenderFreePicture(ClientPtr client)
654{
655 PicturePtr pPicture;
656
657 REQUEST(xRenderFreePictureReq);
658
659 REQUEST_SIZE_MATCH(xRenderFreePictureReq);
660
661 VERIFY_PICTURE(pPicture, stuff->picture, client, DixDestroyAccess);
662 FreeResource(stuff->picture, RT_NONE);
663 return Success;
664}
665
666static Bool
667PictOpValid(CARD8 op)
668{
669 if ( /*PictOpMinimum <= op && */ op <= PictOpMaximum)
670 return TRUE;
671 if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
672 return TRUE;
673 if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
674 return TRUE;
675 if (PictOpBlendMinimum <= op && op <= PictOpBlendMaximum)
676 return TRUE;
677 return FALSE;
678}
679
680static int
681ProcRenderComposite(ClientPtr client)
682{
683 PicturePtr pSrc, pMask, pDst;
684
685 REQUEST(xRenderCompositeReq);
686
687 REQUEST_SIZE_MATCH(xRenderCompositeReq);
688 if (!PictOpValid(stuff->op)) {
689 client->errorValue = stuff->op;
690 return BadValue;
691 }
692 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
693 if (!pDst->pDrawable)
694 return BadDrawable;
695 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
696 VERIFY_ALPHA(pMask, stuff->mask, client, DixReadAccess);
697 if ((pSrc->pDrawable &&
698 pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) || (pMask &&
699 pMask->
700 pDrawable &&
701 pDst->
702 pDrawable->
703 pScreen !=
704 pMask->
705 pDrawable->
706 pScreen))
707 return BadMatch;
708 CompositePicture(stuff->op,
709 pSrc,
710 pMask,
711 pDst,
712 stuff->xSrc,
713 stuff->ySrc,
714 stuff->xMask,
715 stuff->yMask,
716 stuff->xDst, stuff->yDst, stuff->width, stuff->height);
717 return Success;
718}
719
720static int
721ProcRenderScale(ClientPtr client)
722{
723 return BadImplementation;
724}
725
726static int
727ProcRenderTrapezoids(ClientPtr client)
728{
729 int rc, ntraps;
730 PicturePtr pSrc, pDst;
731 PictFormatPtr pFormat;
732
733 REQUEST(xRenderTrapezoidsReq);
734
735 REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
736 if (!PictOpValid(stuff->op)) {
737 client->errorValue = stuff->op;
738 return BadValue;
739 }
740 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
741 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
742 if (!pDst->pDrawable)
743 return BadDrawable;
744 if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
745 return BadMatch;
746 if (stuff->maskFormat) {
747 rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
748 PictFormatType, client, DixReadAccess);
749 if (rc != Success)
750 return rc;
751 }
752 else
753 pFormat = 0;
754 ntraps = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq);
755 if (ntraps % sizeof(xTrapezoid))
756 return BadLength;
757 ntraps /= sizeof(xTrapezoid);
758 if (ntraps)
759 CompositeTrapezoids(stuff->op, pSrc, pDst, pFormat,
760 stuff->xSrc, stuff->ySrc,
761 ntraps, (xTrapezoid *) &stuff[1]);
762 return Success;
763}
764
765static int
766ProcRenderTriangles(ClientPtr client)
767{
768 int rc, ntris;
769 PicturePtr pSrc, pDst;
770 PictFormatPtr pFormat;
771
772 REQUEST(xRenderTrianglesReq);
773
774 REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
775 if (!PictOpValid(stuff->op)) {
776 client->errorValue = stuff->op;
777 return BadValue;
778 }
779 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
780 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
781 if (!pDst->pDrawable)
782 return BadDrawable;
783 if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
784 return BadMatch;
785 if (stuff->maskFormat) {
786 rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
787 PictFormatType, client, DixReadAccess);
788 if (rc != Success)
789 return rc;
790 }
791 else
792 pFormat = 0;
793 ntris = (client->req_len << 2) - sizeof(xRenderTrianglesReq);
794 if (ntris % sizeof(xTriangle))
795 return BadLength;
796 ntris /= sizeof(xTriangle);
797 if (ntris)
798 CompositeTriangles(stuff->op, pSrc, pDst, pFormat,
799 stuff->xSrc, stuff->ySrc,
800 ntris, (xTriangle *) &stuff[1]);
801 return Success;
802}
803
804static int
805ProcRenderTriStrip(ClientPtr client)
806{
807 int rc, npoints;
808 PicturePtr pSrc, pDst;
809 PictFormatPtr pFormat;
810
811 REQUEST(xRenderTrianglesReq);
812
813 REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
814 if (!PictOpValid(stuff->op)) {
815 client->errorValue = stuff->op;
816 return BadValue;
817 }
818 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
819 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
820 if (!pDst->pDrawable)
821 return BadDrawable;
822 if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
823 return BadMatch;
824 if (stuff->maskFormat) {
825 rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
826 PictFormatType, client, DixReadAccess);
827 if (rc != Success)
828 return rc;
829 }
830 else
831 pFormat = 0;
832 npoints = ((client->req_len << 2) - sizeof(xRenderTriStripReq));
833 if (npoints & 4)
834 return BadLength;
835 npoints >>= 3;
836 if (npoints >= 3)
837 CompositeTriStrip(stuff->op, pSrc, pDst, pFormat,
838 stuff->xSrc, stuff->ySrc,
839 npoints, (xPointFixed *) &stuff[1]);
840 return Success;
841}
842
843static int
844ProcRenderTriFan(ClientPtr client)
845{
846 int rc, npoints;
847 PicturePtr pSrc, pDst;
848 PictFormatPtr pFormat;
849
850 REQUEST(xRenderTrianglesReq);
851
852 REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
853 if (!PictOpValid(stuff->op)) {
854 client->errorValue = stuff->op;
855 return BadValue;
856 }
857 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
858 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
859 if (!pDst->pDrawable)
860 return BadDrawable;
861 if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
862 return BadMatch;
863 if (stuff->maskFormat) {
864 rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
865 PictFormatType, client, DixReadAccess);
866 if (rc != Success)
867 return rc;
868 }
869 else
870 pFormat = 0;
871 npoints = ((client->req_len << 2) - sizeof(xRenderTriStripReq));
872 if (npoints & 4)
873 return BadLength;
874 npoints >>= 3;
875 if (npoints >= 3)
876 CompositeTriFan(stuff->op, pSrc, pDst, pFormat,
877 stuff->xSrc, stuff->ySrc,
878 npoints, (xPointFixed *) &stuff[1]);
879 return Success;
880}
881
882static int
883ProcRenderColorTrapezoids(ClientPtr client)
884{
885 return BadImplementation;
886}
887
888static int
889ProcRenderColorTriangles(ClientPtr client)
890{
891 return BadImplementation;
892}
893
894static int
895ProcRenderTransform(ClientPtr client)
896{
897 return BadImplementation;
898}
899
900static int
901ProcRenderCreateGlyphSet(ClientPtr client)
902{
903 GlyphSetPtr glyphSet;
904 PictFormatPtr format;
905 int rc, f;
906
907 REQUEST(xRenderCreateGlyphSetReq);
908
909 REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
910
911 LEGAL_NEW_RESOURCE(stuff->gsid, client);
912 rc = dixLookupResourceByType((pointer *) &format, stuff->format,
913 PictFormatType, client, DixReadAccess);
914 if (rc != Success)
915 return rc;
916
917 switch (format->depth) {
918 case 1:
919 f = GlyphFormat1;
920 break;
921 case 4:
922 f = GlyphFormat4;
923 break;
924 case 8:
925 f = GlyphFormat8;
926 break;
927 case 16:
928 f = GlyphFormat16;
929 break;
930 case 32:
931 f = GlyphFormat32;
932 break;
933 default:
934 return BadMatch;
935 }
936 if (format->type != PictTypeDirect)
937 return BadMatch;
938 glyphSet = AllocateGlyphSet(f, format);
939 if (!glyphSet)
940 return BadAlloc;
941 /* security creation/labeling check */
942 rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType,
943 glyphSet, RT_NONE, NULL, DixCreateAccess);
944 if (rc != Success)
945 return rc;
946 if (!AddResource(stuff->gsid, GlyphSetType, (pointer) glyphSet))
947 return BadAlloc;
948 return Success;
949}
950
951static int
952ProcRenderReferenceGlyphSet(ClientPtr client)
953{
954 GlyphSetPtr glyphSet;
955 int rc;
956
957 REQUEST(xRenderReferenceGlyphSetReq);
958
959 REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
960
961 LEGAL_NEW_RESOURCE(stuff->gsid, client);
962
963 rc = dixLookupResourceByType((pointer *) &glyphSet, stuff->existing,
964 GlyphSetType, client, DixGetAttrAccess);
965 if (rc != Success) {
966 client->errorValue = stuff->existing;
967 return rc;
968 }
969 glyphSet->refcnt++;
970 if (!AddResource(stuff->gsid, GlyphSetType, (pointer) glyphSet))
971 return BadAlloc;
972 return Success;
973}
974
975#define NLOCALDELTA 64
976#define NLOCALGLYPH 256
977
978static int
979ProcRenderFreeGlyphSet(ClientPtr client)
980{
981 GlyphSetPtr glyphSet;
982 int rc;
983
984 REQUEST(xRenderFreeGlyphSetReq);
985
986 REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
987 rc = dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset,
988 GlyphSetType, client, DixDestroyAccess);
989 if (rc != Success) {
990 client->errorValue = stuff->glyphset;
991 return rc;
992 }
993 FreeResource(stuff->glyphset, RT_NONE);
994 return Success;
995}
996
997typedef struct _GlyphNew {
998 Glyph id;
999 GlyphPtr glyph;
1000 Bool found;
1001 unsigned char sha1[20];
1002} GlyphNewRec, *GlyphNewPtr;
1003
1004#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
1005
1006static int
1007ProcRenderAddGlyphs(ClientPtr client)
1008{
1009 GlyphSetPtr glyphSet;
1010
1011 REQUEST(xRenderAddGlyphsReq);
1012 GlyphNewRec glyphsLocal[NLOCALGLYPH];
1013 GlyphNewPtr glyphsBase, glyphs, glyph_new;
1014 int remain, nglyphs;
1015 CARD32 *gids;
1016 xGlyphInfo *gi;
1017 CARD8 *bits;
1018 unsigned int size;
1019 int err;
1020 int i, screen;
1021 PicturePtr pSrc = NULL, pDst = NULL;
1022 PixmapPtr pSrcPix = NULL, pDstPix = NULL;
1023 CARD32 component_alpha;
1024
1025 REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
1026 err =
1027 dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset,
1028 GlyphSetType, client, DixAddAccess);
1029 if (err != Success) {
1030 client->errorValue = stuff->glyphset;
1031 return err;
1032 }
1033
1034 err = BadAlloc;
1035 nglyphs = stuff->nglyphs;
1036 if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
1037 return BadAlloc;
1038
1039 component_alpha = NeedsComponent(glyphSet->format->format);
1040
1041 if (nglyphs <= NLOCALGLYPH) {
1042 memset(glyphsLocal, 0, sizeof(glyphsLocal));
1043 glyphsBase = glyphsLocal;
1044 }
1045 else {
1046 glyphsBase = (GlyphNewPtr) calloc(nglyphs, sizeof(GlyphNewRec));
1047 if (!glyphsBase)
1048 return BadAlloc;
1049 }
1050
1051 remain = (client->req_len << 2) - sizeof(xRenderAddGlyphsReq);
1052
1053 glyphs = glyphsBase;
1054
1055 gids = (CARD32 *) (stuff + 1);
1056 gi = (xGlyphInfo *) (gids + nglyphs);
1057 bits = (CARD8 *) (gi + nglyphs);
1058 remain -= (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs;
1059
1060 /* protect against bad nglyphs */
1061 if (gi < ((xGlyphInfo *) stuff) ||
1062 gi > ((xGlyphInfo *) ((CARD32 *) stuff + client->req_len)) ||
1063 bits < ((CARD8 *) stuff) ||
1064 bits > ((CARD8 *) ((CARD32 *) stuff + client->req_len))) {
1065 err = BadLength;
1066 goto bail;
1067 }
1068
1069 for (i = 0; i < nglyphs; i++) {
1070 size_t padded_width;
1071
1072 glyph_new = &glyphs[i];
1073
1074 padded_width = PixmapBytePad(gi[i].width, glyphSet->format->depth);
1075
1076 if (gi[i].height &&
1077 padded_width > (UINT32_MAX - sizeof(GlyphRec)) / gi[i].height)
1078 break;
1079
1080 size = gi[i].height * padded_width;
1081 if (remain < size)
1082 break;
1083
1084 err = HashGlyph(&gi[i], bits, size, glyph_new->sha1);
1085 if (err)
1086 goto bail;
1087
1088 glyph_new->glyph = FindGlyphByHash(glyph_new->sha1, glyphSet->fdepth);
1089
1090 if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) {
1091 glyph_new->found = TRUE;
1092 }
1093 else {
1094 GlyphPtr glyph;
1095
1096 glyph_new->found = FALSE;
1097 glyph_new->glyph = glyph = AllocateGlyph(&gi[i], glyphSet->fdepth);
1098 if (!glyph) {
1099 err = BadAlloc;
1100 goto bail;
1101 }
1102
1103 for (screen = 0; screen < screenInfo.numScreens; screen++) {
1104 int width = gi[i].width;
1105 int height = gi[i].height;
1106 int depth = glyphSet->format->depth;
1107 ScreenPtr pScreen;
1108 int error;
1109
1110 /* Skip work if it's invisibly small anyway */
1111 if (!width || !height)
1112 break;
1113
1114 pScreen = screenInfo.screens[screen];
1115 pSrcPix = GetScratchPixmapHeader(pScreen,
1116 width, height,
1117 depth, depth, -1, bits);
1118 if (!pSrcPix) {
1119 err = BadAlloc;
1120 goto bail;
1121 }
1122
1123 pSrc = CreatePicture(0, &pSrcPix->drawable,
1124 glyphSet->format, 0, NULL,
1125 serverClient, &error);
1126 if (!pSrc) {
1127 err = BadAlloc;
1128 goto bail;
1129 }
1130
1131 pDstPix = (pScreen->CreatePixmap) (pScreen,
1132 width, height, depth,
1133 CREATE_PIXMAP_USAGE_GLYPH_PICTURE);
1134
1135 if (!pDstPix) {
1136 err = BadAlloc;
1137 goto bail;
1138 }
1139
1140 pDst = CreatePicture(0, &pDstPix->drawable,
1141 glyphSet->format,
1142 CPComponentAlpha, &component_alpha,
1143 serverClient, &error);
1144 SetGlyphPicture(glyph, pScreen, pDst);
1145
1146 /* The picture takes a reference to the pixmap, so we
1147 drop ours. */
1148 (pScreen->DestroyPixmap) (pDstPix);
1149 pDstPix = NULL;
1150
1151 if (!pDst) {
1152 err = BadAlloc;
1153 goto bail;
1154 }
1155
1156 CompositePicture(PictOpSrc,
1157 pSrc,
1158 None, pDst, 0, 0, 0, 0, 0, 0, width, height);
1159
1160 FreePicture((pointer) pSrc, 0);
1161 pSrc = NULL;
1162 FreeScratchPixmapHeader(pSrcPix);
1163 pSrcPix = NULL;
1164 }
1165
1166 memcpy(glyph_new->glyph->sha1, glyph_new->sha1, 20);
1167 }
1168
1169 glyph_new->id = gids[i];
1170
1171 if (size & 3)
1172 size += 4 - (size & 3);
1173 bits += size;
1174 remain -= size;
1175 }
1176 if (remain || i < nglyphs) {
1177 err = BadLength;
1178 goto bail;
1179 }
1180 if (!ResizeGlyphSet(glyphSet, nglyphs)) {
1181 err = BadAlloc;
1182 goto bail;
1183 }
1184 for (i = 0; i < nglyphs; i++)
1185 AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id);
1186
1187 if (glyphsBase != glyphsLocal)
1188 free(glyphsBase);
1189 return Success;
1190 bail:
1191 if (pSrc)
1192 FreePicture((pointer) pSrc, 0);
1193 if (pSrcPix)
1194 FreeScratchPixmapHeader(pSrcPix);
1195 for (i = 0; i < nglyphs; i++)
1196 if (glyphs[i].glyph && !glyphs[i].found)
1197 free(glyphs[i].glyph);
1198 if (glyphsBase != glyphsLocal)
1199 free(glyphsBase);
1200 return err;
1201}
1202
1203static int
1204ProcRenderAddGlyphsFromPicture(ClientPtr client)
1205{
1206 return BadImplementation;
1207}
1208
1209static int
1210ProcRenderFreeGlyphs(ClientPtr client)
1211{
1212 REQUEST(xRenderFreeGlyphsReq);
1213 GlyphSetPtr glyphSet;
1214 int rc, nglyph;
1215 CARD32 *gids;
1216 CARD32 glyph;
1217
1218 REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
1219 rc = dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset,
1220 GlyphSetType, client, DixRemoveAccess);
1221 if (rc != Success) {
1222 client->errorValue = stuff->glyphset;
1223 return rc;
1224 }
1225 nglyph =
1226 bytes_to_int32((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq));
1227 gids = (CARD32 *) (stuff + 1);
1228 while (nglyph-- > 0) {
1229 glyph = *gids++;
1230 if (!DeleteGlyph(glyphSet, glyph)) {
1231 client->errorValue = glyph;
1232 return RenderErrBase + BadGlyph;
1233 }
1234 }
1235 return Success;
1236}
1237
1238static int
1239ProcRenderCompositeGlyphs(ClientPtr client)
1240{
1241 GlyphSetPtr glyphSet;
1242 GlyphSet gs;
1243 PicturePtr pSrc, pDst;
1244 PictFormatPtr pFormat;
1245 GlyphListRec listsLocal[NLOCALDELTA];
1246 GlyphListPtr lists, listsBase;
1247 GlyphPtr glyphsLocal[NLOCALGLYPH];
1248 Glyph glyph;
1249 GlyphPtr *glyphs, *glyphsBase;
1250 xGlyphElt *elt;
1251 CARD8 *buffer, *end;
1252 int nglyph;
1253 int nlist;
1254 int space;
1255 int size;
1256 int rc, n;
1257
1258 REQUEST(xRenderCompositeGlyphsReq);
1259
1260 REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
1261
1262 switch (stuff->renderReqType) {
1263 default:
1264 size = 1;
1265 break;
1266 case X_RenderCompositeGlyphs16:
1267 size = 2;
1268 break;
1269 case X_RenderCompositeGlyphs32:
1270 size = 4;
1271 break;
1272 }
1273
1274 if (!PictOpValid(stuff->op)) {
1275 client->errorValue = stuff->op;
1276 return BadValue;
1277 }
1278 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
1279 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
1280 if (!pDst->pDrawable)
1281 return BadDrawable;
1282 if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
1283 return BadMatch;
1284 if (stuff->maskFormat) {
1285 rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
1286 PictFormatType, client, DixReadAccess);
1287 if (rc != Success)
1288 return rc;
1289 }
1290 else
1291 pFormat = 0;
1292
1293 rc = dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset,
1294 GlyphSetType, client, DixUseAccess);
1295 if (rc != Success)
1296 return rc;
1297
1298 buffer = (CARD8 *) (stuff + 1);
1299 end = (CARD8 *) stuff + (client->req_len << 2);
1300 nglyph = 0;
1301 nlist = 0;
1302 while (buffer + sizeof(xGlyphElt) < end) {
1303 elt = (xGlyphElt *) buffer;
1304 buffer += sizeof(xGlyphElt);
1305
1306 if (elt->len == 0xff) {
1307 buffer += 4;
1308 }
1309 else {
1310 nlist++;
1311 nglyph += elt->len;
1312 space = size * elt->len;
1313 if (space & 3)
1314 space += 4 - (space & 3);
1315 buffer += space;
1316 }
1317 }
1318 if (nglyph <= NLOCALGLYPH)
1319 glyphsBase = glyphsLocal;
1320 else {
1321 glyphsBase = (GlyphPtr *) malloc(nglyph * sizeof(GlyphPtr));
1322 if (!glyphsBase)
1323 return BadAlloc;
1324 }
1325 if (nlist <= NLOCALDELTA)
1326 listsBase = listsLocal;
1327 else {
1328 listsBase = (GlyphListPtr) malloc(nlist * sizeof(GlyphListRec));
1329 if (!listsBase) {
1330 rc = BadAlloc;
1331 goto bail;
1332 }
1333 }
1334 buffer = (CARD8 *) (stuff + 1);
1335 glyphs = glyphsBase;
1336 lists = listsBase;
1337 while (buffer + sizeof(xGlyphElt) < end) {
1338 elt = (xGlyphElt *) buffer;
1339 buffer += sizeof(xGlyphElt);
1340
1341 if (elt->len == 0xff) {
1342 if (buffer + sizeof(GlyphSet) < end) {
1343 memcpy(&gs, buffer, sizeof(GlyphSet));
1344 rc = dixLookupResourceByType((pointer *) &glyphSet, gs,
1345 GlyphSetType, client,
1346 DixUseAccess);
1347 if (rc != Success)
1348 goto bail;
1349 }
1350 buffer += 4;
1351 }
1352 else {
1353 lists->xOff = elt->deltax;
1354 lists->yOff = elt->deltay;
1355 lists->format = glyphSet->format;
1356 lists->len = 0;
1357 n = elt->len;
1358 while (n--) {
1359 if (buffer + size <= end) {
1360 switch (size) {
1361 case 1:
1362 glyph = *((CARD8 *) buffer);
1363 break;
1364 case 2:
1365 glyph = *((CARD16 *) buffer);
1366 break;
1367 case 4:
1368 default:
1369 glyph = *((CARD32 *) buffer);
1370 break;
1371 }
1372 if ((*glyphs = FindGlyph(glyphSet, glyph))) {
1373 lists->len++;
1374 glyphs++;
1375 }
1376 }
1377 buffer += size;
1378 }
1379 space = size * elt->len;
1380 if (space & 3)
1381 buffer += 4 - (space & 3);
1382 lists++;
1383 }
1384 }
1385 if (buffer > end) {
1386 rc = BadLength;
1387 goto bail;
1388 }
1389
1390 CompositeGlyphs(stuff->op,
1391 pSrc,
1392 pDst,
1393 pFormat,
1394 stuff->xSrc, stuff->ySrc, nlist, listsBase, glyphsBase);
1395 rc = Success;
1396
1397 bail:
1398 if (glyphsBase != glyphsLocal)
1399 free(glyphsBase);
1400 if (listsBase != listsLocal)
1401 free(listsBase);
1402 return rc;
1403}
1404
1405static int
1406ProcRenderFillRectangles(ClientPtr client)
1407{
1408 PicturePtr pDst;
1409 int things;
1410
1411 REQUEST(xRenderFillRectanglesReq);
1412
1413 REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
1414 if (!PictOpValid(stuff->op)) {
1415 client->errorValue = stuff->op;
1416 return BadValue;
1417 }
1418 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
1419 if (!pDst->pDrawable)
1420 return BadDrawable;
1421
1422 things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
1423 if (things & 4)
1424 return BadLength;
1425 things >>= 3;
1426
1427 CompositeRects(stuff->op,
1428 pDst, &stuff->color, things, (xRectangle *) &stuff[1]);
1429
1430 return Success;
1431}
1432
1433static void
1434RenderSetBit(unsigned char *line, int x, int bit)
1435{
1436 unsigned char mask;
1437
1438 if (screenInfo.bitmapBitOrder == LSBFirst)
1439 mask = (1 << (x & 7));
1440 else
1441 mask = (0x80 >> (x & 7));
1442 /* XXX assumes byte order is host byte order */
1443 line += (x >> 3);
1444 if (bit)
1445 *line |= mask;
1446 else
1447 *line &= ~mask;
1448}
1449
1450#define DITHER_DIM 2
1451
1452static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
1453 {1, 3,},
1454 {4, 2,},
1455};
1456
1457#define DITHER_SIZE ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
1458
1459static int
1460ProcRenderCreateCursor(ClientPtr client)
1461{
1462 REQUEST(xRenderCreateCursorReq);
1463 PicturePtr pSrc;
1464 ScreenPtr pScreen;
1465 unsigned short width, height;
1466 CARD32 *argbbits, *argb;
1467 unsigned char *srcbits, *srcline;
1468 unsigned char *mskbits, *mskline;
1469 int stride;
1470 int x, y;
1471 int nbytes_mono;
1472 CursorMetricRec cm;
1473 CursorPtr pCursor;
1474 CARD32 twocolor[3];
1475 int rc, ncolor;
1476
1477 REQUEST_SIZE_MATCH(xRenderCreateCursorReq);
1478 LEGAL_NEW_RESOURCE(stuff->cid, client);
1479
1480 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
1481 if (!pSrc->pDrawable)
1482 return BadDrawable;
1483 pScreen = pSrc->pDrawable->pScreen;
1484 width = pSrc->pDrawable->width;
1485 height = pSrc->pDrawable->height;
1486 if (height && width > UINT32_MAX / (height * sizeof(CARD32)))
1487 return BadAlloc;
1488 if (stuff->x > width || stuff->y > height)
1489 return BadMatch;
1490 argbbits = malloc(width * height * sizeof(CARD32));
1491 if (!argbbits)
1492 return BadAlloc;
1493
1494 stride = BitmapBytePad(width);
1495 nbytes_mono = stride * height;
1496 srcbits = calloc(1, nbytes_mono);
1497 if (!srcbits) {
1498 free(argbbits);
1499 return BadAlloc;
1500 }
1501 mskbits = calloc(1, nbytes_mono);
1502 if (!mskbits) {
1503 free(argbbits);
1504 free(srcbits);
1505 return BadAlloc;
1506 }
1507
1508 if (pSrc->format == PICT_a8r8g8b8) {
1509 (*pScreen->GetImage) (pSrc->pDrawable,
1510 0, 0, width, height, ZPixmap,
1511 0xffffffff, (pointer) argbbits);
1512 }
1513 else {
1514 PixmapPtr pPixmap;
1515 PicturePtr pPicture;
1516 PictFormatPtr pFormat;
1517 int error;
1518
1519 pFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8);
1520 if (!pFormat) {
1521 free(argbbits);
1522 free(srcbits);
1523 free(mskbits);
1524 return BadImplementation;
1525 }
1526 pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32,
1527 CREATE_PIXMAP_USAGE_SCRATCH);
1528 if (!pPixmap) {
1529 free(argbbits);
1530 free(srcbits);
1531 free(mskbits);
1532 return BadAlloc;
1533 }
1534 pPicture = CreatePicture(0, &pPixmap->drawable, pFormat, 0, 0,
1535 client, &error);
1536 if (!pPicture) {
1537 free(argbbits);
1538 free(srcbits);
1539 free(mskbits);
1540 return error;
1541 }
1542 (*pScreen->DestroyPixmap) (pPixmap);
1543 CompositePicture(PictOpSrc,
1544 pSrc, 0, pPicture, 0, 0, 0, 0, 0, 0, width, height);
1545 (*pScreen->GetImage) (pPicture->pDrawable,
1546 0, 0, width, height, ZPixmap,
1547 0xffffffff, (pointer) argbbits);
1548 FreePicture(pPicture, 0);
1549 }
1550 /*
1551 * Check whether the cursor can be directly supported by
1552 * the core cursor code
1553 */
1554 ncolor = 0;
1555 argb = argbbits;
1556 for (y = 0; ncolor <= 2 && y < height; y++) {
1557 for (x = 0; ncolor <= 2 && x < width; x++) {
1558 CARD32 p = *argb++;
1559 CARD32 a = (p >> 24);
1560
1561 if (a == 0) /* transparent */
1562 continue;
1563 if (a == 0xff) { /* opaque */
1564 int n;
1565
1566 for (n = 0; n < ncolor; n++)
1567 if (p == twocolor[n])
1568 break;
1569 if (n == ncolor)
1570 twocolor[ncolor++] = p;
1571 }
1572 else
1573 ncolor = 3;
1574 }
1575 }
1576
1577 /*
1578 * Convert argb image to two plane cursor
1579 */
1580 srcline = srcbits;
1581 mskline = mskbits;
1582 argb = argbbits;
1583 for (y = 0; y < height; y++) {
1584 for (x = 0; x < width; x++) {
1585 CARD32 p = *argb++;
1586
1587 if (ncolor <= 2) {
1588 CARD32 a = ((p >> 24));
1589
1590 RenderSetBit(mskline, x, a != 0);
1591 RenderSetBit(srcline, x, a != 0 && p == twocolor[0]);
1592 }
1593 else {
1594 CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255;
1595 CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
1596 CARD32 d =
1597 orderedDither[y & (DITHER_DIM - 1)][x & (DITHER_DIM - 1)];
1598 /* Set mask from dithered alpha value */
1599 RenderSetBit(mskline, x, a > d);
1600 /* Set src from dithered intensity value */
1601 RenderSetBit(srcline, x, a > d && i <= d);
1602 }
1603 }
1604 srcline += stride;
1605 mskline += stride;
1606 }
1607 /*
1608 * Dither to white and black if the cursor has more than two colors
1609 */
1610 if (ncolor > 2) {
1611 twocolor[0] = 0xff000000;
1612 twocolor[1] = 0xffffffff;
1613 }
1614 else {
1615 free(argbbits);
1616 argbbits = 0;
1617 }
1618
1619#define GetByte(p,s) (((p) >> (s)) & 0xff)
1620#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8))
1621
1622 cm.width = width;
1623 cm.height = height;
1624 cm.xhot = stuff->x;
1625 cm.yhot = stuff->y;
1626 rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm,
1627 GetColor(twocolor[0], 16),
1628 GetColor(twocolor[0], 8),
1629 GetColor(twocolor[0], 0),
1630 GetColor(twocolor[1], 16),
1631 GetColor(twocolor[1], 8),
1632 GetColor(twocolor[1], 0),
1633 &pCursor, client, stuff->cid);
1634 if (rc != Success)
1635 goto bail;
1636 if (!AddResource(stuff->cid, RT_CURSOR, (pointer) pCursor)) {
1637 rc = BadAlloc;
1638 goto bail;
1639 }
1640
1641 return Success;
1642 bail:
1643 free(srcbits);
1644 free(mskbits);
1645 return rc;
1646}
1647
1648static int
1649ProcRenderSetPictureTransform(ClientPtr client)
1650{
1651 REQUEST(xRenderSetPictureTransformReq);
1652 PicturePtr pPicture;
1653
1654 REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
1655 VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
1656 return SetPictureTransform(pPicture, (PictTransform *) &stuff->transform);
1657}
1658
1659static int
1660ProcRenderQueryFilters(ClientPtr client)
1661{
1662 REQUEST(xRenderQueryFiltersReq);
1663 DrawablePtr pDrawable;
1664 xRenderQueryFiltersReply *reply;
1665 int nbytesName;
1666 int nnames;
1667 ScreenPtr pScreen;
1668 PictureScreenPtr ps;
1669 int i, j, len, total_bytes, rc;
1670 INT16 *aliases;
1671 char *names;
1672
1673 REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
1674 rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
1675 DixGetAttrAccess);
1676 if (rc != Success)
1677 return rc;
1678
1679 pScreen = pDrawable->pScreen;
1680 nbytesName = 0;
1681 nnames = 0;
1682 ps = GetPictureScreenIfSet(pScreen);
1683 if (ps) {
1684 for (i = 0; i < ps->nfilters; i++)
1685 nbytesName += 1 + strlen(ps->filters[i].name);
1686 for (i = 0; i < ps->nfilterAliases; i++)
1687 nbytesName += 1 + strlen(ps->filterAliases[i].alias);
1688 nnames = ps->nfilters + ps->nfilterAliases;
1689 }
1690 len = ((nnames + 1) >> 1) + bytes_to_int32(nbytesName);
1691 total_bytes = sizeof(xRenderQueryFiltersReply) + (len << 2);
1692 reply = (xRenderQueryFiltersReply *) calloc(1, total_bytes);
1693 if (!reply)
1694 return BadAlloc;
1695 aliases = (INT16 *) (reply + 1);
1696 names = (char *) (aliases + ((nnames + 1) & ~1));
1697
1698 reply->type = X_Reply;
1699 reply->sequenceNumber = client->sequence;
1700 reply->length = len;
1701 reply->numAliases = nnames;
1702 reply->numFilters = nnames;
1703 if (ps) {
1704
1705 /* fill in alias values */
1706 for (i = 0; i < ps->nfilters; i++)
1707 aliases[i] = FilterAliasNone;
1708 for (i = 0; i < ps->nfilterAliases; i++) {
1709 for (j = 0; j < ps->nfilters; j++)
1710 if (ps->filterAliases[i].filter_id == ps->filters[j].id)
1711 break;
1712 if (j == ps->nfilters) {
1713 for (j = 0; j < ps->nfilterAliases; j++)
1714 if (ps->filterAliases[i].filter_id ==
1715 ps->filterAliases[j].alias_id) {
1716 break;
1717 }
1718 if (j == ps->nfilterAliases)
1719 j = FilterAliasNone;
1720 else
1721 j = j + ps->nfilters;
1722 }
1723 aliases[i + ps->nfilters] = j;
1724 }
1725
1726 /* fill in filter names */
1727 for (i = 0; i < ps->nfilters; i++) {
1728 j = strlen(ps->filters[i].name);
1729 *names++ = j;
1730 memcpy(names, ps->filters[i].name, j);
1731 names += j;
1732 }
1733
1734 /* fill in filter alias names */
1735 for (i = 0; i < ps->nfilterAliases; i++) {
1736 j = strlen(ps->filterAliases[i].alias);
1737 *names++ = j;
1738 memcpy(names, ps->filterAliases[i].alias, j);
1739 names += j;
1740 }
1741 }
1742
1743 if (client->swapped) {
1744 for (i = 0; i < reply->numAliases; i++) {
1745 swaps(&aliases[i]);
1746 }
1747 swaps(&reply->sequenceNumber);
1748 swapl(&reply->length);
1749 swapl(&reply->numAliases);
1750 swapl(&reply->numFilters);
1751 }
1752 WriteToClient(client, total_bytes, reply);
1753 free(reply);
1754
1755 return Success;
1756}
1757
1758static int
1759ProcRenderSetPictureFilter(ClientPtr client)
1760{
1761 REQUEST(xRenderSetPictureFilterReq);
1762 PicturePtr pPicture;
1763 int result;
1764 xFixed *params;
1765 int nparams;
1766 char *name;
1767
1768 REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
1769 VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
1770 name = (char *) (stuff + 1);
1771 params = (xFixed *) (name + pad_to_int32(stuff->nbytes));
1772 nparams = ((xFixed *) stuff + client->req_len) - params;
1773 result = SetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
1774 return result;
1775}
1776
1777static int
1778ProcRenderCreateAnimCursor(ClientPtr client)
1779{
1780 REQUEST(xRenderCreateAnimCursorReq);
1781 CursorPtr *cursors;
1782 CARD32 *deltas;
1783 CursorPtr pCursor;
1784 int ncursor;
1785 xAnimCursorElt *elt;
1786 int i;
1787 int ret;
1788
1789 REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
1790 LEGAL_NEW_RESOURCE(stuff->cid, client);
1791 if (client->req_len & 1)
1792 return BadLength;
1793 ncursor =
1794 (client->req_len -
1795 (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1;
1796 cursors = malloc(ncursor * (sizeof(CursorPtr) + sizeof(CARD32)));
1797 if (!cursors)
1798 return BadAlloc;
1799 deltas = (CARD32 *) (cursors + ncursor);
1800 elt = (xAnimCursorElt *) (stuff + 1);
1801 for (i = 0; i < ncursor; i++) {
1802 ret = dixLookupResourceByType((pointer *) (cursors + i), elt->cursor,
1803 RT_CURSOR, client, DixReadAccess);
1804 if (ret != Success) {
1805 free(cursors);
1806 return ret;
1807 }
1808 deltas[i] = elt->delay;
1809 elt++;
1810 }
1811 ret = AnimCursorCreate(cursors, deltas, ncursor, &pCursor, client,
1812 stuff->cid);
1813 free(cursors);
1814 if (ret != Success)
1815 return ret;
1816
1817 if (AddResource(stuff->cid, RT_CURSOR, (pointer) pCursor))
1818 return Success;
1819 return BadAlloc;
1820}
1821
1822static int
1823ProcRenderAddTraps(ClientPtr client)
1824{
1825 int ntraps;
1826 PicturePtr pPicture;
1827
1828 REQUEST(xRenderAddTrapsReq);
1829
1830 REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
1831 VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess);
1832 if (!pPicture->pDrawable)
1833 return BadDrawable;
1834 ntraps = (client->req_len << 2) - sizeof(xRenderAddTrapsReq);
1835 if (ntraps % sizeof(xTrap))
1836 return BadLength;
1837 ntraps /= sizeof(xTrap);
1838 if (ntraps)
1839 AddTraps(pPicture,
1840 stuff->xOff, stuff->yOff, ntraps, (xTrap *) &stuff[1]);
1841 return Success;
1842}
1843
1844static int
1845ProcRenderCreateSolidFill(ClientPtr client)
1846{
1847 PicturePtr pPicture;
1848 int error = 0;
1849
1850 REQUEST(xRenderCreateSolidFillReq);
1851
1852 REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
1853
1854 LEGAL_NEW_RESOURCE(stuff->pid, client);
1855
1856 pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
1857 if (!pPicture)
1858 return error;
1859 /* security creation/labeling check */
1860 error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1861 pPicture, RT_NONE, NULL, DixCreateAccess);
1862 if (error != Success)
1863 return error;
1864 if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
1865 return BadAlloc;
1866 return Success;
1867}
1868
1869static int
1870ProcRenderCreateLinearGradient(ClientPtr client)
1871{
1872 PicturePtr pPicture;
1873 int len;
1874 int error = 0;
1875 xFixed *stops;
1876 xRenderColor *colors;
1877
1878 REQUEST(xRenderCreateLinearGradientReq);
1879
1880 REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
1881
1882 LEGAL_NEW_RESOURCE(stuff->pid, client);
1883
1884 len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
1885 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
1886 return BadLength;
1887 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
1888 return BadLength;
1889
1890 stops = (xFixed *) (stuff + 1);
1891 colors = (xRenderColor *) (stops + stuff->nStops);
1892
1893 pPicture = CreateLinearGradientPicture(stuff->pid, &stuff->p1, &stuff->p2,
1894 stuff->nStops, stops, colors,
1895 &error);
1896 if (!pPicture)
1897 return error;
1898 /* security creation/labeling check */
1899 error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1900 pPicture, RT_NONE, NULL, DixCreateAccess);
1901 if (error != Success)
1902 return error;
1903 if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
1904 return BadAlloc;
1905 return Success;
1906}
1907
1908static int
1909ProcRenderCreateRadialGradient(ClientPtr client)
1910{
1911 PicturePtr pPicture;
1912 int len;
1913 int error = 0;
1914 xFixed *stops;
1915 xRenderColor *colors;
1916
1917 REQUEST(xRenderCreateRadialGradientReq);
1918
1919 REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
1920
1921 LEGAL_NEW_RESOURCE(stuff->pid, client);
1922
1923 len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
1924 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
1925 return BadLength;
1926
1927 stops = (xFixed *) (stuff + 1);
1928 colors = (xRenderColor *) (stops + stuff->nStops);
1929
1930 pPicture =
1931 CreateRadialGradientPicture(stuff->pid, &stuff->inner, &stuff->outer,
1932 stuff->inner_radius, stuff->outer_radius,
1933 stuff->nStops, stops, colors, &error);
1934 if (!pPicture)
1935 return error;
1936 /* security creation/labeling check */
1937 error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1938 pPicture, RT_NONE, NULL, DixCreateAccess);
1939 if (error != Success)
1940 return error;
1941 if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
1942 return BadAlloc;
1943 return Success;
1944}
1945
1946static int
1947ProcRenderCreateConicalGradient(ClientPtr client)
1948{
1949 PicturePtr pPicture;
1950 int len;
1951 int error = 0;
1952 xFixed *stops;
1953 xRenderColor *colors;
1954
1955 REQUEST(xRenderCreateConicalGradientReq);
1956
1957 REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
1958
1959 LEGAL_NEW_RESOURCE(stuff->pid, client);
1960
1961 len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
1962 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
1963 return BadLength;
1964
1965 stops = (xFixed *) (stuff + 1);
1966 colors = (xRenderColor *) (stops + stuff->nStops);
1967
1968 pPicture =
1969 CreateConicalGradientPicture(stuff->pid, &stuff->center, stuff->angle,
1970 stuff->nStops, stops, colors, &error);
1971 if (!pPicture)
1972 return error;
1973 /* security creation/labeling check */
1974 error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1975 pPicture, RT_NONE, NULL, DixCreateAccess);
1976 if (error != Success)
1977 return error;
1978 if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
1979 return BadAlloc;
1980 return Success;
1981}
1982
1983static int
1984ProcRenderDispatch(ClientPtr client)
1985{
1986 REQUEST(xReq);
1987
1988 if (stuff->data < RenderNumberRequests)
1989 return (*ProcRenderVector[stuff->data]) (client);
1990 else
1991 return BadRequest;
1992}
1993
1994static int
1995SProcRenderQueryVersion(ClientPtr client)
1996{
1997 REQUEST(xRenderQueryVersionReq);
1998
1999 swaps(&stuff->length);
2000 swapl(&stuff->majorVersion);
2001 swapl(&stuff->minorVersion);
2002 return (*ProcRenderVector[stuff->renderReqType]) (client);
2003}
2004
2005static int
2006SProcRenderQueryPictFormats(ClientPtr client)
2007{
2008 REQUEST(xRenderQueryPictFormatsReq);
2009 swaps(&stuff->length);
2010 return (*ProcRenderVector[stuff->renderReqType]) (client);
2011}
2012
2013static int
2014SProcRenderQueryPictIndexValues(ClientPtr client)
2015{
2016 REQUEST(xRenderQueryPictIndexValuesReq);
2017 swaps(&stuff->length);
2018 swapl(&stuff->format);
2019 return (*ProcRenderVector[stuff->renderReqType]) (client);
2020}
2021
2022static int
2023SProcRenderQueryDithers(ClientPtr client)
2024{
2025 return BadImplementation;
2026}
2027
2028static int
2029SProcRenderCreatePicture(ClientPtr client)
2030{
2031 REQUEST(xRenderCreatePictureReq);
2032 swaps(&stuff->length);
2033 swapl(&stuff->pid);
2034 swapl(&stuff->drawable);
2035 swapl(&stuff->format);
2036 swapl(&stuff->mask);
2037 SwapRestL(stuff);
2038 return (*ProcRenderVector[stuff->renderReqType]) (client);
2039}
2040
2041static int
2042SProcRenderChangePicture(ClientPtr client)
2043{
2044 REQUEST(xRenderChangePictureReq);
2045 swaps(&stuff->length);
2046 swapl(&stuff->picture);
2047 swapl(&stuff->mask);
2048 SwapRestL(stuff);
2049 return (*ProcRenderVector[stuff->renderReqType]) (client);
2050}
2051
2052static int
2053SProcRenderSetPictureClipRectangles(ClientPtr client)
2054{
2055 REQUEST(xRenderSetPictureClipRectanglesReq);
2056 swaps(&stuff->length);
2057 swapl(&stuff->picture);
2058 swaps(&stuff->xOrigin);
2059 swaps(&stuff->yOrigin);
2060 SwapRestS(stuff);
2061 return (*ProcRenderVector[stuff->renderReqType]) (client);
2062}
2063
2064static int
2065SProcRenderFreePicture(ClientPtr client)
2066{
2067 REQUEST(xRenderFreePictureReq);
2068 swaps(&stuff->length);
2069 swapl(&stuff->picture);
2070 return (*ProcRenderVector[stuff->renderReqType]) (client);
2071}
2072
2073static int
2074SProcRenderComposite(ClientPtr client)
2075{
2076 REQUEST(xRenderCompositeReq);
2077 swaps(&stuff->length);
2078 swapl(&stuff->src);
2079 swapl(&stuff->mask);
2080 swapl(&stuff->dst);
2081 swaps(&stuff->xSrc);
2082 swaps(&stuff->ySrc);
2083 swaps(&stuff->xMask);
2084 swaps(&stuff->yMask);
2085 swaps(&stuff->xDst);
2086 swaps(&stuff->yDst);
2087 swaps(&stuff->width);
2088 swaps(&stuff->height);
2089 return (*ProcRenderVector[stuff->renderReqType]) (client);
2090}
2091
2092static int
2093SProcRenderScale(ClientPtr client)
2094{
2095 REQUEST(xRenderScaleReq);
2096 swaps(&stuff->length);
2097 swapl(&stuff->src);
2098 swapl(&stuff->dst);
2099 swapl(&stuff->colorScale);
2100 swapl(&stuff->alphaScale);
2101 swaps(&stuff->xSrc);
2102 swaps(&stuff->ySrc);
2103 swaps(&stuff->xDst);
2104 swaps(&stuff->yDst);
2105 swaps(&stuff->width);
2106 swaps(&stuff->height);
2107 return (*ProcRenderVector[stuff->renderReqType]) (client);
2108}
2109
2110static int
2111SProcRenderTrapezoids(ClientPtr client)
2112{
2113 REQUEST(xRenderTrapezoidsReq);
2114
2115 REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
2116 swaps(&stuff->length);
2117 swapl(&stuff->src);
2118 swapl(&stuff->dst);
2119 swapl(&stuff->maskFormat);
2120 swaps(&stuff->xSrc);
2121 swaps(&stuff->ySrc);
2122 SwapRestL(stuff);
2123 return (*ProcRenderVector[stuff->renderReqType]) (client);
2124}
2125
2126static int
2127SProcRenderTriangles(ClientPtr client)
2128{
2129 REQUEST(xRenderTrianglesReq);
2130
2131 REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
2132 swaps(&stuff->length);
2133 swapl(&stuff->src);
2134 swapl(&stuff->dst);
2135 swapl(&stuff->maskFormat);
2136 swaps(&stuff->xSrc);
2137 swaps(&stuff->ySrc);
2138 SwapRestL(stuff);
2139 return (*ProcRenderVector[stuff->renderReqType]) (client);
2140}
2141
2142static int
2143SProcRenderTriStrip(ClientPtr client)
2144{
2145 REQUEST(xRenderTriStripReq);
2146
2147 REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
2148 swaps(&stuff->length);
2149 swapl(&stuff->src);
2150 swapl(&stuff->dst);
2151 swapl(&stuff->maskFormat);
2152 swaps(&stuff->xSrc);
2153 swaps(&stuff->ySrc);
2154 SwapRestL(stuff);
2155 return (*ProcRenderVector[stuff->renderReqType]) (client);
2156}
2157
2158static int
2159SProcRenderTriFan(ClientPtr client)
2160{
2161 REQUEST(xRenderTriFanReq);
2162
2163 REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
2164 swaps(&stuff->length);
2165 swapl(&stuff->src);
2166 swapl(&stuff->dst);
2167 swapl(&stuff->maskFormat);
2168 swaps(&stuff->xSrc);
2169 swaps(&stuff->ySrc);
2170 SwapRestL(stuff);
2171 return (*ProcRenderVector[stuff->renderReqType]) (client);
2172}
2173
2174static int
2175SProcRenderColorTrapezoids(ClientPtr client)
2176{
2177 return BadImplementation;
2178}
2179
2180static int
2181SProcRenderColorTriangles(ClientPtr client)
2182{
2183 return BadImplementation;
2184}
2185
2186static int
2187SProcRenderTransform(ClientPtr client)
2188{
2189 return BadImplementation;
2190}
2191
2192static int
2193SProcRenderCreateGlyphSet(ClientPtr client)
2194{
2195 REQUEST(xRenderCreateGlyphSetReq);
2196 swaps(&stuff->length);
2197 swapl(&stuff->gsid);
2198 swapl(&stuff->format);
2199 return (*ProcRenderVector[stuff->renderReqType]) (client);
2200}
2201
2202static int
2203SProcRenderReferenceGlyphSet(ClientPtr client)
2204{
2205 REQUEST(xRenderReferenceGlyphSetReq);
2206 swaps(&stuff->length);
2207 swapl(&stuff->gsid);
2208 swapl(&stuff->existing);
2209 return (*ProcRenderVector[stuff->renderReqType]) (client);
2210}
2211
2212static int
2213SProcRenderFreeGlyphSet(ClientPtr client)
2214{
2215 REQUEST(xRenderFreeGlyphSetReq);
2216 swaps(&stuff->length);
2217 swapl(&stuff->glyphset);
2218 return (*ProcRenderVector[stuff->renderReqType]) (client);
2219}
2220
2221static int
2222SProcRenderAddGlyphs(ClientPtr client)
2223{
2224 register int i;
2225 CARD32 *gids;
2226 void *end;
2227 xGlyphInfo *gi;
2228
2229 REQUEST(xRenderAddGlyphsReq);
2230 swaps(&stuff->length);
2231 swapl(&stuff->glyphset);
2232 swapl(&stuff->nglyphs);
2233 if (stuff->nglyphs & 0xe0000000)
2234 return BadLength;
2235 end = (CARD8 *) stuff + (client->req_len << 2);
2236 gids = (CARD32 *) (stuff + 1);
2237 gi = (xGlyphInfo *) (gids + stuff->nglyphs);
2238 if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
2239 return BadLength;
2240 if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
2241 return BadLength;
2242 for (i = 0; i < stuff->nglyphs; i++) {
2243 swapl(&gids[i]);
2244 swaps(&gi[i].width);
2245 swaps(&gi[i].height);
2246 swaps(&gi[i].x);
2247 swaps(&gi[i].y);
2248 swaps(&gi[i].xOff);
2249 swaps(&gi[i].yOff);
2250 }
2251 return (*ProcRenderVector[stuff->renderReqType]) (client);
2252}
2253
2254static int
2255SProcRenderAddGlyphsFromPicture(ClientPtr client)
2256{
2257 return BadImplementation;
2258}
2259
2260static int
2261SProcRenderFreeGlyphs(ClientPtr client)
2262{
2263 REQUEST(xRenderFreeGlyphsReq);
2264 swaps(&stuff->length);
2265 swapl(&stuff->glyphset);
2266 SwapRestL(stuff);
2267 return (*ProcRenderVector[stuff->renderReqType]) (client);
2268}
2269
2270static int
2271SProcRenderCompositeGlyphs(ClientPtr client)
2272{
2273 xGlyphElt *elt;
2274 CARD8 *buffer;
2275 CARD8 *end;
2276 int space;
2277 int i;
2278 int size;
2279
2280 REQUEST(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
2341static int
2342SProcRenderFillRectangles(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
2357static int
2358SProcRenderCreateCursor(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
2371static int
2372SProcRenderSetPictureTransform(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
2391static int
2392SProcRenderQueryFilters(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
2402static int
2403SProcRenderSetPictureFilter(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
2414static int
2415SProcRenderCreateAnimCursor(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
2426static int
2427SProcRenderAddTraps(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
2440static int
2441SProcRenderCreateSolidFill(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
2455static void
2456swapStops(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
2474static int
2475SProcRenderCreateLinearGradient(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
2501static int
2502SProcRenderCreateRadialGradient(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
2530static int
2531SProcRenderCreateConicalGradient(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
2556static int
2557SProcRenderDispatch(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((pointer *)&(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
2583int (*PanoramiXSaveRenderVector[RenderNumberRequests]) (ClientPtr);
2584
2585static int
2586PanoramiXRenderCreatePicture(ClientPtr client)
2587{
2588 REQUEST(xRenderCreatePictureReq);
2589 PanoramiXRes *refDraw, *newPict;
2590 int result, j;
2591
2592 REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2593 result = dixLookupResourceByClass((pointer *) &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
2625static int
2626PanoramiXRenderChangePicture(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
2647static int
2648PanoramiXRenderSetPictureClipRectangles(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
2670static int
2671PanoramiXRenderSetPictureTransform(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
2692static int
2693PanoramiXRenderSetPictureFilter(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
2714static int
2715PanoramiXRenderFreePicture(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
2741static int
2742PanoramiXRenderComposite(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
2784static int
2785PanoramiXRenderCompositeGlyphs(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
2825static int
2826PanoramiXRenderFillRectangles(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
2870static int
2871PanoramiXRenderTrapezoids(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
2931static int
2932PanoramiXRenderTriangles(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
2988static int
2989PanoramiXRenderTriStrip(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
3041static int
3042PanoramiXRenderTriFan(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
3094static int
3095PanoramiXRenderAddTraps(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
3131static int
3132PanoramiXRenderCreateSolidFill(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
3162static int
3163PanoramiXRenderCreateLinearGradient(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
3194static int
3195PanoramiXRenderCreateRadialGradient(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
3226static int
3227PanoramiXRenderCreateConicalGradient(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
3259void
3260PanoramiXRenderInit(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
3305void
3306PanoramiXRenderReset(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 */