Bug Summary

File:render/picture.c
Location:line 894, column 45
Description:Result of 'malloc' is converted to a pointer of type 'union _SourcePict', which is incompatible with sizeof operand type 'PictSolidFill'

Annotated Source Code

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_H1
26#include <dix-config.h>
27#endif
28
29#include "misc.h"
30#include "scrnintstr.h"
31#include "os.h"
32#include "regionstr.h"
33#include "validate.h"
34#include "windowstr.h"
35#include "input.h"
36#include "resource.h"
37#include "colormapst.h"
38#include "cursorstr.h"
39#include "dixstruct.h"
40#include "gcstruct.h"
41#include "servermd.h"
42#include "picturestr.h"
43#include "xace.h"
44#ifdef PANORAMIX1
45#include "panoramiXsrv.h"
46#endif
47
48DevPrivateKeyRec PictureScreenPrivateKeyRec;
49DevPrivateKeyRec PictureWindowPrivateKeyRec;
50static int PictureGeneration;
51RESTYPE PictureType;
52RESTYPE PictFormatType;
53RESTYPE GlyphSetType;
54int PictureCmapPolicy = PictureCmapPolicyDefault0;
55
56PictFormatPtr
57PictureWindowFormat(WindowPtr pWindow)
58{
59 ScreenPtr pScreen = pWindow->drawable.pScreen;
60 return PictureMatchVisual(pScreen, pWindow->drawable.depth,
61 WindowGetVisual(pWindow));
62}
63
64static Bool
65PictureDestroyWindow(WindowPtr pWindow)
66{
67 ScreenPtr pScreen = pWindow->drawable.pScreen;
68 PicturePtr pPicture;
69 PictureScreenPtr ps = GetPictureScreen(pScreen)((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec)))
;
70 Bool ret;
71
72 while ((pPicture = GetPictureWindow(pWindow)((PicturePtr)dixLookupPrivate(&(pWindow)->devPrivates,
(&PictureWindowPrivateKeyRec)))
)) {
73 SetPictureWindow(pWindow, pPicture->pNext)dixSetPrivate(&(pWindow)->devPrivates, (&PictureWindowPrivateKeyRec
), pPicture->pNext)
;
74 if (pPicture->id)
75 FreeResource(pPicture->id, PictureType);
76 FreePicture((void *) pPicture, pPicture->id);
77 }
78 pScreen->DestroyWindow = ps->DestroyWindow;
79 ret = (*pScreen->DestroyWindow) (pWindow);
80 ps->DestroyWindow = pScreen->DestroyWindow;
81 pScreen->DestroyWindow = PictureDestroyWindow;
82 return ret;
83}
84
85static Bool
86PictureCloseScreen(ScreenPtr pScreen)
87{
88 PictureScreenPtr ps = GetPictureScreen(pScreen)((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec)))
;
89 Bool ret;
90 int n;
91
92 pScreen->CloseScreen = ps->CloseScreen;
93 ret = (*pScreen->CloseScreen) (pScreen);
94 PictureResetFilters(pScreen);
95 for (n = 0; n < ps->nformats; n++)
96 if (ps->formats[n].type == PictTypeIndexed0)
97 (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
98 GlyphUninit(pScreen);
99 SetPictureScreen(pScreen, 0)dixSetPrivate(&(pScreen)->devPrivates, (&PictureScreenPrivateKeyRec
), 0)
;
100 free(ps->formats);
101 free(ps);
102 return ret;
103}
104
105static void
106PictureStoreColors(ColormapPtr pColormap, int ndef, xColorItem * pdef)
107{
108 ScreenPtr pScreen = pColormap->pScreen;
109 PictureScreenPtr ps = GetPictureScreen(pScreen)((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec)))
;
110
111 pScreen->StoreColors = ps->StoreColors;
112 (*pScreen->StoreColors) (pColormap, ndef, pdef);
113 ps->StoreColors = pScreen->StoreColors;
114 pScreen->StoreColors = PictureStoreColors;
115
116 if (pColormap->class == PseudoColor3 || pColormap->class == GrayScale1) {
117 PictFormatPtr format = ps->formats;
118 int nformats = ps->nformats;
119
120 while (nformats--) {
121 if (format->type == PictTypeIndexed0 &&
122 format->index.pColormap == pColormap) {
123 (*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
124 break;
125 }
126 format++;
127 }
128 }
129}
130
131static int
132visualDepth(ScreenPtr pScreen, VisualPtr pVisual)
133{
134 int d, v;
135 DepthPtr pDepth;
136
137 for (d = 0; d < pScreen->numDepths; d++) {
138 pDepth = &pScreen->allowedDepths[d];
139 for (v = 0; v < pDepth->numVids; v++)
140 if (pDepth->vids[v] == pVisual->vid)
141 return pDepth->depth;
142 }
143 return 0;
144}
145
146typedef struct _formatInit {
147 CARD32 format;
148 CARD8 depth;
149} FormatInitRec, *FormatInitPtr;
150
151static int
152addFormat(FormatInitRec formats[256], int nformat, CARD32 format, CARD8 depth)
153{
154 int n;
155
156 for (n = 0; n < nformat; n++)
157 if (formats[n].format == format && formats[n].depth == depth)
158 return nformat;
159 formats[nformat].format = format;
160 formats[nformat].depth = depth;
161 return ++nformat;
162}
163
164#define Mask(n)((1 << (n)) - 1) ((1 << (n)) - 1)
165
166static PictFormatPtr
167PictureCreateDefaultFormats(ScreenPtr pScreen, int *nformatp)
168{
169 int nformats, f;
170 PictFormatPtr pFormats;
171 FormatInitRec formats[1024];
172 CARD32 format;
173 CARD8 depth;
174 VisualPtr pVisual;
175 int v;
176 int bpp;
177 int type;
178 int r, g, b;
179 int d;
180 DepthPtr pDepth;
181
182 nformats = 0;
183 /* formats required by protocol */
184 formats[nformats].format = PICT_a1;
185 formats[nformats].depth = 1;
186 nformats++;
187 formats[nformats].format = PICT_FORMAT(BitsPerPixel(8),((((PixmapWidthPaddingInfo[8].bitsPerPixel)) << 24) | (
(1) << 16) | ((8) << 12) | ((0) << 8) | ((0
) << 4) | ((0)))
188 PICT_TYPE_A, 8, 0, 0, 0)((((PixmapWidthPaddingInfo[8].bitsPerPixel)) << 24) | (
(1) << 16) | ((8) << 12) | ((0) << 8) | ((0
) << 4) | ((0)))
;
189 formats[nformats].depth = 8;
190 nformats++;
191 formats[nformats].format = PICT_FORMAT(BitsPerPixel(4),((((PixmapWidthPaddingInfo[4].bitsPerPixel)) << 24) | (
(1) << 16) | ((4) << 12) | ((0) << 8) | ((0
) << 4) | ((0)))
192 PICT_TYPE_A, 4, 0, 0, 0)((((PixmapWidthPaddingInfo[4].bitsPerPixel)) << 24) | (
(1) << 16) | ((4) << 12) | ((0) << 8) | ((0
) << 4) | ((0)))
;
193 formats[nformats].depth = 4;
194 nformats++;
195 formats[nformats].format = PICT_a8r8g8b8;
196 formats[nformats].depth = 32;
197 nformats++;
198 formats[nformats].format = PICT_x8r8g8b8;
199 formats[nformats].depth = 32;
200 nformats++;
201 formats[nformats].format = PICT_b8g8r8a8;
202 formats[nformats].depth = 32;
203 nformats++;
204 formats[nformats].format = PICT_b8g8r8x8;
205 formats[nformats].depth = 32;
206 nformats++;
207
208 /* now look through the depths and visuals adding other formats */
209 for (v = 0; v < pScreen->numVisuals; v++) {
210 pVisual = &pScreen->visuals[v];
211 depth = visualDepth(pScreen, pVisual);
212 if (!depth)
213 continue;
214 bpp = BitsPerPixel(depth)(PixmapWidthPaddingInfo[depth].bitsPerPixel);
215 switch (pVisual->class) {
216 case DirectColor5:
217 case TrueColor4:
218 r = Ones(pVisual->redMask);
219 g = Ones(pVisual->greenMask);
220 b = Ones(pVisual->blueMask);
221 type = PICT_TYPE_OTHER0;
222 /*
223 * Current rendering code supports only three direct formats,
224 * fields must be packed together at the bottom of the pixel
225 */
226 if (pVisual->offsetBlue == 0 &&
227 pVisual->offsetGreen == b && pVisual->offsetRed == b + g) {
228 type = PICT_TYPE_ARGB2;
229 }
230 else if (pVisual->offsetRed == 0 &&
231 pVisual->offsetGreen == r &&
232 pVisual->offsetBlue == r + g) {
233 type = PICT_TYPE_ABGR3;
234 }
235 else if (pVisual->offsetRed == pVisual->offsetGreen - r &&
236 pVisual->offsetGreen == pVisual->offsetBlue - g &&
237 pVisual->offsetBlue == bpp - b) {
238 type = PICT_TYPE_BGRA8;
239 }
240 if (type != PICT_TYPE_OTHER0) {
241 format = PICT_FORMAT(bpp, type, 0, r, g, b)(((bpp) << 24) | ((type) << 16) | ((0) << 12
) | ((r) << 8) | ((g) << 4) | ((b)))
;
242 nformats = addFormat(formats, nformats, format, depth);
243 }
244 break;
245 case StaticColor2:
246 case PseudoColor3:
247 format = PICT_VISFORMAT(bpp, PICT_TYPE_COLOR, v)(((bpp) << 24) | ((4) << 16) | ((v)));
248 nformats = addFormat(formats, nformats, format, depth);
249 break;
250 case StaticGray0:
251 case GrayScale1:
252 format = PICT_VISFORMAT(bpp, PICT_TYPE_GRAY, v)(((bpp) << 24) | ((5) << 16) | ((v)));
253 nformats = addFormat(formats, nformats, format, depth);
254 break;
255 }
256 }
257 /*
258 * Walk supported depths and add useful Direct formats
259 */
260 for (d = 0; d < pScreen->numDepths; d++) {
261 pDepth = &pScreen->allowedDepths[d];
262 bpp = BitsPerPixel(pDepth->depth)(PixmapWidthPaddingInfo[pDepth->depth].bitsPerPixel);
263 format = 0;
264 switch (bpp) {
265 case 16:
266 /* depth 12 formats */
267 if (pDepth->depth >= 12) {
268 nformats = addFormat(formats, nformats,
269 PICT_x4r4g4b4, pDepth->depth);
270 nformats = addFormat(formats, nformats,
271 PICT_x4b4g4r4, pDepth->depth);
272 }
273 /* depth 15 formats */
274 if (pDepth->depth >= 15) {
275 nformats = addFormat(formats, nformats,
276 PICT_x1r5g5b5, pDepth->depth);
277 nformats = addFormat(formats, nformats,
278 PICT_x1b5g5r5, pDepth->depth);
279 }
280 /* depth 16 formats */
281 if (pDepth->depth >= 16) {
282 nformats = addFormat(formats, nformats,
283 PICT_a1r5g5b5, pDepth->depth);
284 nformats = addFormat(formats, nformats,
285 PICT_a1b5g5r5, pDepth->depth);
286 nformats = addFormat(formats, nformats,
287 PICT_r5g6b5, pDepth->depth);
288 nformats = addFormat(formats, nformats,
289 PICT_b5g6r5, pDepth->depth);
290 nformats = addFormat(formats, nformats,
291 PICT_a4r4g4b4, pDepth->depth);
292 nformats = addFormat(formats, nformats,
293 PICT_a4b4g4r4, pDepth->depth);
294 }
295 break;
296 case 24:
297 if (pDepth->depth >= 24) {
298 nformats = addFormat(formats, nformats,
299 PICT_r8g8b8, pDepth->depth);
300 nformats = addFormat(formats, nformats,
301 PICT_b8g8r8, pDepth->depth);
302 }
303 break;
304 case 32:
305 if (pDepth->depth >= 24) {
306 nformats = addFormat(formats, nformats,
307 PICT_x8r8g8b8, pDepth->depth);
308 nformats = addFormat(formats, nformats,
309 PICT_x8b8g8r8, pDepth->depth);
310 }
311 if (pDepth->depth >= 30) {
312 nformats = addFormat(formats, nformats,
313 PICT_a2r10g10b10, pDepth->depth);
314 nformats = addFormat(formats, nformats,
315 PICT_x2r10g10b10, pDepth->depth);
316 nformats = addFormat(formats, nformats,
317 PICT_a2b10g10r10, pDepth->depth);
318 nformats = addFormat(formats, nformats,
319 PICT_x2b10g10r10, pDepth->depth);
320 }
321 break;
322 }
323 }
324
325 pFormats = calloc(nformats, sizeof(PictFormatRec));
326 if (!pFormats)
327 return 0;
328 for (f = 0; f < nformats; f++) {
329 pFormats[f].id = FakeClientID(0);
330 pFormats[f].depth = formats[f].depth;
331 format = formats[f].format;
332 pFormats[f].format = format;
333 switch (PICT_FORMAT_TYPE(format)(((format) >> 16) & 0xff)) {
334 case PICT_TYPE_ARGB2:
335 pFormats[f].type = PictTypeDirect1;
336
337 pFormats[f].direct.alphaMask = Mask (PICT_FORMAT_A(format))((1 << ((((format) >> 12) & 0x0f))) - 1);
338
339 if (pFormats[f].direct.alphaMask)
340 pFormats[f].direct.alpha = (PICT_FORMAT_R(format)(((format) >> 8) & 0x0f) +
341 PICT_FORMAT_G(format)(((format) >> 4) & 0x0f) +
342 PICT_FORMAT_B(format)(((format) ) & 0x0f));
343
344 pFormats[f].direct.redMask = Mask (PICT_FORMAT_R(format))((1 << ((((format) >> 8) & 0x0f))) - 1);
345
346 pFormats[f].direct.red = (PICT_FORMAT_G(format)(((format) >> 4) & 0x0f) +
347 PICT_FORMAT_B(format)(((format) ) & 0x0f));
348
349 pFormats[f].direct.greenMask = Mask (PICT_FORMAT_G(format))((1 << ((((format) >> 4) & 0x0f))) - 1);
350
351 pFormats[f].direct.green = PICT_FORMAT_B(format)(((format) ) & 0x0f);
352
353 pFormats[f].direct.blueMask = Mask (PICT_FORMAT_B(format))((1 << ((((format) ) & 0x0f))) - 1);
354
355 pFormats[f].direct.blue = 0;
356 break;
357
358 case PICT_TYPE_ABGR3:
359 pFormats[f].type = PictTypeDirect1;
360
361 pFormats[f].direct.alphaMask = Mask (PICT_FORMAT_A(format))((1 << ((((format) >> 12) & 0x0f))) - 1);
362
363 if (pFormats[f].direct.alphaMask)
364 pFormats[f].direct.alpha = (PICT_FORMAT_B(format)(((format) ) & 0x0f) +
365 PICT_FORMAT_G(format)(((format) >> 4) & 0x0f) +
366 PICT_FORMAT_R(format)(((format) >> 8) & 0x0f));
367
368 pFormats[f].direct.blueMask = Mask (PICT_FORMAT_B(format))((1 << ((((format) ) & 0x0f))) - 1);
369
370 pFormats[f].direct.blue = (PICT_FORMAT_G(format)(((format) >> 4) & 0x0f) +
371 PICT_FORMAT_R(format)(((format) >> 8) & 0x0f));
372
373 pFormats[f].direct.greenMask = Mask (PICT_FORMAT_G(format))((1 << ((((format) >> 4) & 0x0f))) - 1);
374
375 pFormats[f].direct.green = PICT_FORMAT_R(format)(((format) >> 8) & 0x0f);
376
377 pFormats[f].direct.redMask = Mask (PICT_FORMAT_R(format))((1 << ((((format) >> 8) & 0x0f))) - 1);
378
379 pFormats[f].direct.red = 0;
380 break;
381
382 case PICT_TYPE_BGRA8:
383 pFormats[f].type = PictTypeDirect1;
384
385 pFormats[f].direct.blueMask = Mask (PICT_FORMAT_B(format))((1 << ((((format) ) & 0x0f))) - 1);
386
387 pFormats[f].direct.blue =
388 (PICT_FORMAT_BPP(format)(((format) >> 24) ) - PICT_FORMAT_B(format)(((format) ) & 0x0f));
389
390 pFormats[f].direct.greenMask = Mask (PICT_FORMAT_G(format))((1 << ((((format) >> 4) & 0x0f))) - 1);
391
392 pFormats[f].direct.green =
393 (PICT_FORMAT_BPP(format)(((format) >> 24) ) - PICT_FORMAT_B(format)(((format) ) & 0x0f) -
394 PICT_FORMAT_G(format)(((format) >> 4) & 0x0f));
395
396 pFormats[f].direct.redMask = Mask (PICT_FORMAT_R(format))((1 << ((((format) >> 8) & 0x0f))) - 1);
397
398 pFormats[f].direct.red =
399 (PICT_FORMAT_BPP(format)(((format) >> 24) ) - PICT_FORMAT_B(format)(((format) ) & 0x0f) -
400 PICT_FORMAT_G(format)(((format) >> 4) & 0x0f) - PICT_FORMAT_R(format)(((format) >> 8) & 0x0f));
401
402 pFormats[f].direct.alphaMask = Mask (PICT_FORMAT_A(format))((1 << ((((format) >> 12) & 0x0f))) - 1);
403
404 pFormats[f].direct.alpha = 0;
405 break;
406
407 case PICT_TYPE_A1:
408 pFormats[f].type = PictTypeDirect1;
409
410 pFormats[f].direct.alpha = 0;
411 pFormats[f].direct.alphaMask = Mask (PICT_FORMAT_A(format))((1 << ((((format) >> 12) & 0x0f))) - 1);
412
413 /* remaining fields already set to zero */
414 break;
415
416 case PICT_TYPE_COLOR4:
417 case PICT_TYPE_GRAY5:
418 pFormats[f].type = PictTypeIndexed0;
419 pFormats[f].index.vid =
420 pScreen->visuals[PICT_FORMAT_VIS(format)(((format) ) & 0xffff)].vid;
421 break;
422 }
423 }
424 *nformatp = nformats;
425 return pFormats;
426}
427
428static VisualPtr
429PictureFindVisual(ScreenPtr pScreen, VisualID visual)
430{
431 int i;
432 VisualPtr pVisual;
433
434 for (i = 0, pVisual = pScreen->visuals;
435 i < pScreen->numVisuals; i++, pVisual++) {
436 if (pVisual->vid == visual)
437 return pVisual;
438 }
439 return 0;
440}
441
442static Bool
443PictureInitIndexedFormat(ScreenPtr pScreen, PictFormatPtr format)
444{
445 PictureScreenPtr ps = GetPictureScreenIfSet(pScreen)(dixPrivateKeyRegistered((&PictureScreenPrivateKeyRec)) ?
((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec))) : ((void*)0))
;
446
447 if (format->type != PictTypeIndexed0 || format->index.pColormap)
448 return TRUE1;
449
450 if (format->index.vid == pScreen->rootVisual) {
451 dixLookupResourceByType((void **) &format->index.pColormap,
452 pScreen->defColormap, RT_COLORMAP((RESTYPE)6),
453 serverClient, DixGetAttrAccess(1<<4));
454 }
455 else {
456 VisualPtr pVisual = PictureFindVisual(pScreen, format->index.vid);
457
458 if (CreateColormap(FakeClientID(0), pScreen, pVisual,
459 &format->index.pColormap, AllocNone0, 0)
460 != Success0)
461 return FALSE0;
462 }
463 if (!ps->InitIndexed(pScreen, format))
464 return FALSE0;
465 return TRUE1;
466}
467
468static Bool
469PictureInitIndexedFormats(ScreenPtr pScreen)
470{
471 PictureScreenPtr ps = GetPictureScreenIfSet(pScreen)(dixPrivateKeyRegistered((&PictureScreenPrivateKeyRec)) ?
((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec))) : ((void*)0))
;
472 PictFormatPtr format;
473 int nformat;
474
475 if (!ps)
476 return FALSE0;
477 format = ps->formats;
478 nformat = ps->nformats;
479 while (nformat--)
480 if (!PictureInitIndexedFormat(pScreen, format++))
481 return FALSE0;
482 return TRUE1;
483}
484
485Bool
486PictureFinishInit(void)
487{
488 int s;
489
490 for (s = 0; s < screenInfo.numScreens; s++) {
491 if (!PictureInitIndexedFormats(screenInfo.screens[s]))
492 return FALSE0;
493 (void) AnimCurInit(screenInfo.screens[s]);
494 }
495
496 return TRUE1;
497}
498
499Bool
500PictureSetSubpixelOrder(ScreenPtr pScreen, int subpixel)
501{
502 PictureScreenPtr ps = GetPictureScreenIfSet(pScreen)(dixPrivateKeyRegistered((&PictureScreenPrivateKeyRec)) ?
((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec))) : ((void*)0))
;
503
504 if (!ps)
505 return FALSE0;
506 ps->subpixel = subpixel;
507 return TRUE1;
508
509}
510
511int
512PictureGetSubpixelOrder(ScreenPtr pScreen)
513{
514 PictureScreenPtr ps = GetPictureScreenIfSet(pScreen)(dixPrivateKeyRegistered((&PictureScreenPrivateKeyRec)) ?
((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec))) : ((void*)0))
;
515
516 if (!ps)
517 return SubPixelUnknown0;
518 return ps->subpixel;
519}
520
521PictFormatPtr
522PictureMatchVisual(ScreenPtr pScreen, int depth, VisualPtr pVisual)
523{
524 PictureScreenPtr ps = GetPictureScreenIfSet(pScreen)(dixPrivateKeyRegistered((&PictureScreenPrivateKeyRec)) ?
((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec))) : ((void*)0))
;
525 PictFormatPtr format;
526 int nformat;
527 int type;
528
529 if (!ps)
530 return 0;
531 format = ps->formats;
532 nformat = ps->nformats;
533 switch (pVisual->class) {
534 case StaticGray0:
535 case GrayScale1:
536 case StaticColor2:
537 case PseudoColor3:
538 type = PictTypeIndexed0;
539 break;
540 case TrueColor4:
541 case DirectColor5:
542 type = PictTypeDirect1;
543 break;
544 default:
545 return 0;
546 }
547 while (nformat--) {
548 if (format->depth == depth && format->type == type) {
549 if (type == PictTypeIndexed0) {
550 if (format->index.vid == pVisual->vid)
551 return format;
552 }
553 else {
554 if (format->direct.redMask << format->direct.red ==
555 pVisual->redMask &&
556 format->direct.greenMask << format->direct.green ==
557 pVisual->greenMask &&
558 format->direct.blueMask << format->direct.blue ==
559 pVisual->blueMask) {
560 return format;
561 }
562 }
563 }
564 format++;
565 }
566 return 0;
567}
568
569PictFormatPtr
570PictureMatchFormat(ScreenPtr pScreen, int depth, CARD32 f)
571{
572 PictureScreenPtr ps = GetPictureScreenIfSet(pScreen)(dixPrivateKeyRegistered((&PictureScreenPrivateKeyRec)) ?
((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec))) : ((void*)0))
;
573 PictFormatPtr format;
574 int nformat;
575
576 if (!ps)
577 return 0;
578 format = ps->formats;
579 nformat = ps->nformats;
580 while (nformat--) {
581 if (format->depth == depth && format->format == (f & 0xffffff))
582 return format;
583 format++;
584 }
585 return 0;
586}
587
588int
589PictureParseCmapPolicy(const char *name)
590{
591 if (strcmp(name, "default") == 0)
592 return PictureCmapPolicyDefault0;
593 else if (strcmp(name, "mono") == 0)
594 return PictureCmapPolicyMono1;
595 else if (strcmp(name, "gray") == 0)
596 return PictureCmapPolicyGray2;
597 else if (strcmp(name, "color") == 0)
598 return PictureCmapPolicyColor3;
599 else if (strcmp(name, "all") == 0)
600 return PictureCmapPolicyAll4;
601 else
602 return PictureCmapPolicyInvalid-1;
603}
604
605/** @see GetDefaultBytes */
606static void
607GetPictureBytes(void *value, XID id, ResourceSizePtr size)
608{
609 PicturePtr picture = value;
610
611 /* Currently only pixmap bytes are reported to clients. */
612 size->resourceSize = 0;
613
614 size->refCnt = picture->refcnt;
615
616 /* Calculate pixmap reference sizes. */
617 size->pixmapRefSize = 0;
618 if (picture->pDrawable && (picture->pDrawable->type == DRAWABLE_PIXMAP1))
619 {
620 SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)));
621 ResourceSizeRec pixmapSize = { 0, 0, 0 };
622 PixmapPtr pixmap = (PixmapPtr)picture->pDrawable;
623 pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize);
624 size->pixmapRefSize += pixmapSize.pixmapRefSize;
625 }
626}
627
628static int
629FreePictFormat(void *pPictFormat, XID pid)
630{
631 return Success0;
632}
633
634Bool
635PictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
636{
637 PictureScreenPtr ps;
638 int n;
639 CARD32 type, a, r, g, b;
640
641 if (PictureGeneration != serverGeneration) {
642 PictureType = CreateNewResourceType(FreePicture, "PICTURE");
643 if (!PictureType)
644 return FALSE0;
645 SetResourceTypeSizeFunc(PictureType, GetPictureBytes);
646 PictFormatType = CreateNewResourceType(FreePictFormat, "PICTFORMAT");
647 if (!PictFormatType)
648 return FALSE0;
649 GlyphSetType = CreateNewResourceType(FreeGlyphSet, "GLYPHSET");
650 if (!GlyphSetType)
651 return FALSE0;
652 PictureGeneration = serverGeneration;
653 }
654 if (!dixRegisterPrivateKey(&PictureScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
655 return FALSE0;
656
657 if (!dixRegisterPrivateKey(&PictureWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
658 return FALSE0;
659
660 if (!formats) {
661 formats = PictureCreateDefaultFormats(pScreen, &nformats);
662 if (!formats)
663 return FALSE0;
664 }
665 for (n = 0; n < nformats; n++) {
666 if (!AddResourceDarwin_X_AddResource
667 (formats[n].id, PictFormatType, (void *) (formats + n))) {
668 int i;
669 for (i = 0; i < n; i++)
670 FreeResource(formats[i].id, RT_NONE((RESTYPE)0));
671 free(formats);
672 return FALSE0;
673 }
674 if (formats[n].type == PictTypeIndexed0) {
675 VisualPtr pVisual =
676 PictureFindVisual(pScreen, formats[n].index.vid);
677 if ((pVisual->class | DynamicClass1) == PseudoColor3)
678 type = PICT_TYPE_COLOR4;
679 else
680 type = PICT_TYPE_GRAY5;
681 a = r = g = b = 0;
682 }
683 else {
684 if ((formats[n].direct.redMask |
685 formats[n].direct.blueMask | formats[n].direct.greenMask) == 0)
686 type = PICT_TYPE_A1;
687 else if (formats[n].direct.red > formats[n].direct.blue)
688 type = PICT_TYPE_ARGB2;
689 else if (formats[n].direct.red == 0)
690 type = PICT_TYPE_ABGR3;
691 else
692 type = PICT_TYPE_BGRA8;
693 a = Ones(formats[n].direct.alphaMask);
694 r = Ones(formats[n].direct.redMask);
695 g = Ones(formats[n].direct.greenMask);
696 b = Ones(formats[n].direct.blueMask);
697 }
698 formats[n].format = PICT_FORMAT(0, type, a, r, g, b)(((0) << 24) | ((type) << 16) | ((a) << 12)
| ((r) << 8) | ((g) << 4) | ((b)))
;
699 }
700 ps = (PictureScreenPtr) malloc(sizeof(PictureScreenRec));
701 if (!ps) {
702 free(formats);
703 return FALSE0;
704 }
705 SetPictureScreen(pScreen, ps)dixSetPrivate(&(pScreen)->devPrivates, (&PictureScreenPrivateKeyRec
), ps)
;
706
707 ps->formats = formats;
708 ps->fallback = formats;
709 ps->nformats = nformats;
710
711 ps->filters = 0;
712 ps->nfilters = 0;
713 ps->filterAliases = 0;
714 ps->nfilterAliases = 0;
715
716 ps->subpixel = SubPixelUnknown0;
717
718 ps->CloseScreen = pScreen->CloseScreen;
719 ps->DestroyWindow = pScreen->DestroyWindow;
720 ps->StoreColors = pScreen->StoreColors;
721 pScreen->DestroyWindow = PictureDestroyWindow;
722 pScreen->CloseScreen = PictureCloseScreen;
723 pScreen->StoreColors = PictureStoreColors;
724
725 if (!PictureSetDefaultFilters(pScreen)) {
726 PictureResetFilters(pScreen);
727 SetPictureScreen(pScreen, 0)dixSetPrivate(&(pScreen)->devPrivates, (&PictureScreenPrivateKeyRec
), 0)
;
728 free(formats);
729 free(ps);
730 return FALSE0;
731 }
732
733 return TRUE1;
734}
735
736static void
737SetPictureToDefaults(PicturePtr pPicture)
738{
739 pPicture->refcnt = 1;
740 pPicture->repeat = 0;
741 pPicture->graphicsExposures = FALSE0;
742 pPicture->subWindowMode = ClipByChildren0;
743 pPicture->polyEdge = PolyEdgeSharp0;
744 pPicture->polyMode = PolyModePrecise0;
745 pPicture->freeCompClip = FALSE0;
746 pPicture->componentAlpha = FALSE0;
747 pPicture->repeatType = RepeatNone0;
748
749 pPicture->alphaMap = 0;
750 pPicture->alphaOrigin.x = 0;
751 pPicture->alphaOrigin.y = 0;
752
753 pPicture->clipOrigin.x = 0;
754 pPicture->clipOrigin.y = 0;
755 pPicture->clientClip = 0;
756
757 pPicture->transform = 0;
758
759 pPicture->filter = PictureGetFilterId(FilterNearest"nearest", -1, TRUE1);
760 pPicture->filter_params = 0;
761 pPicture->filter_nparams = 0;
762
763 pPicture->serialNumber = GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
764 pPicture->stateChanges = -1;
765 pPicture->pSourcePict = 0;
766}
767
768PicturePtr
769CreatePicture(Picture pid,
770 DrawablePtr pDrawable,
771 PictFormatPtr pFormat,
772 Mask vmask, XID *vlist, ClientPtr client, int *error)
773{
774 PicturePtr pPicture;
775 PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDrawable->pScreen
)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
776
777 pPicture = dixAllocateScreenObjectWithPrivates(pDrawable->pScreen,_dixAllocateScreenObjectWithPrivates(pDrawable->pScreen, sizeof
(PictureRec), sizeof(PictureRec), __builtin_offsetof(PictureRec
, devPrivates), PRIVATE_PICTURE)
778 PictureRec, PRIVATE_PICTURE)_dixAllocateScreenObjectWithPrivates(pDrawable->pScreen, sizeof
(PictureRec), sizeof(PictureRec), __builtin_offsetof(PictureRec
, devPrivates), PRIVATE_PICTURE)
;
779 if (!pPicture) {
780 *error = BadAlloc11;
781 return 0;
782 }
783
784 pPicture->id = pid;
785 pPicture->pDrawable = pDrawable;
786 pPicture->pFormat = pFormat;
787 pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
788
789 /* security creation/labeling check */
790 *error = XaceHook(XACE_RESOURCE_ACCESS2, client, pid, PictureType, pPicture,
791 RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), pDrawable, DixCreateAccess(1<<3) | DixSetAttrAccess(1<<5));
792 if (*error != Success0)
793 goto out;
794
795 if (pDrawable->type == DRAWABLE_PIXMAP1) {
796 ++((PixmapPtr) pDrawable)->refcnt;
797 pPicture->pNext = 0;
798 }
799 else {
800 pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable))((PicturePtr)dixLookupPrivate(&(((WindowPtr) pDrawable))->
devPrivates, (&PictureWindowPrivateKeyRec)))
;
801 SetPictureWindow(((WindowPtr) pDrawable), pPicture)dixSetPrivate(&(((WindowPtr) pDrawable))->devPrivates,
(&PictureWindowPrivateKeyRec), pPicture)
;
802 }
803
804 SetPictureToDefaults(pPicture);
805
806 if (vmask)
807 *error = ChangePicture(pPicture, vmask, vlist, 0, client);
808 else
809 *error = Success0;
810 if (*error == Success0)
811 *error = (*ps->CreatePicture) (pPicture);
812 out:
813 if (*error != Success0) {
814 FreePicture(pPicture, (XID) 0);
815 pPicture = 0;
816 }
817 return pPicture;
818}
819
820static CARD32
821xRenderColorToCard32(xRenderColor c)
822{
823 return
824 (c.alpha >> 8 << 24) |
825 (c.red >> 8 << 16) | (c.green & 0xff00) | (c.blue >> 8);
826}
827
828static void
829initGradient(SourcePictPtr pGradient, int stopCount,
830 xFixed * stopPoints, xRenderColor * stopColors, int *error)
831{
832 int i;
833 xFixed dpos;
834
835 if (stopCount <= 0) {
836 *error = BadValue2;
837 return;
838 }
839
840 dpos = -1;
841 for (i = 0; i < stopCount; ++i) {
842 if (stopPoints[i] < dpos || stopPoints[i] > (1 << 16)) {
843 *error = BadValue2;
844 return;
845 }
846 dpos = stopPoints[i];
847 }
848
849 pGradient->gradient.stops = xallocarray(stopCount, sizeof(PictGradientStop))xreallocarray(((void*)0), (stopCount), (sizeof(PictGradientStop
)))
;
850 if (!pGradient->gradient.stops) {
851 *error = BadAlloc11;
852 return;
853 }
854
855 pGradient->gradient.nstops = stopCount;
856
857 for (i = 0; i < stopCount; ++i) {
858 pGradient->gradient.stops[i].x = stopPoints[i];
859 pGradient->gradient.stops[i].color = stopColors[i];
860 }
861}
862
863static PicturePtr
864createSourcePicture(void)
865{
866 PicturePtr pPicture;
867
868 pPicture = dixAllocateScreenObjectWithPrivates(NULL, PictureRec,_dixAllocateScreenObjectWithPrivates(((void*)0), sizeof(PictureRec
), sizeof(PictureRec), __builtin_offsetof(PictureRec, devPrivates
), PRIVATE_PICTURE)
869 PRIVATE_PICTURE)_dixAllocateScreenObjectWithPrivates(((void*)0), sizeof(PictureRec
), sizeof(PictureRec), __builtin_offsetof(PictureRec, devPrivates
), PRIVATE_PICTURE)
;
870 if (!pPicture)
871 return 0;
872
873 pPicture->pDrawable = 0;
874 pPicture->pFormat = 0;
875 pPicture->pNext = 0;
876 pPicture->format = PICT_a8r8g8b8;
877
878 SetPictureToDefaults(pPicture);
879 return pPicture;
880}
881
882PicturePtr
883CreateSolidPicture(Picture pid, xRenderColor * color, int *error)
884{
885 PicturePtr pPicture;
886
887 pPicture = createSourcePicture();
888 if (!pPicture) {
889 *error = BadAlloc11;
890 return 0;
891 }
892
893 pPicture->id = pid;
894 pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictSolidFill));
Result of 'malloc' is converted to a pointer of type 'union _SourcePict', which is incompatible with sizeof operand type 'PictSolidFill'
895 if (!pPicture->pSourcePict) {
896 *error = BadAlloc11;
897 free(pPicture);
898 return 0;
899 }
900 pPicture->pSourcePict->type = SourcePictTypeSolidFill0;
901 pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
902 return pPicture;
903}
904
905PicturePtr
906CreateLinearGradientPicture(Picture pid, xPointFixed * p1, xPointFixed * p2,
907 int nStops, xFixed * stops, xRenderColor * colors,
908 int *error)
909{
910 PicturePtr pPicture;
911
912 if (nStops < 1) {
913 *error = BadValue2;
914 return 0;
915 }
916
917 pPicture = createSourcePicture();
918 if (!pPicture) {
919 *error = BadAlloc11;
920 return 0;
921 }
922
923 pPicture->id = pid;
924 pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictLinearGradient));
925 if (!pPicture->pSourcePict) {
926 *error = BadAlloc11;
927 free(pPicture);
928 return 0;
929 }
930
931 pPicture->pSourcePict->linear.type = SourcePictTypeLinear1;
932 pPicture->pSourcePict->linear.p1 = *p1;
933 pPicture->pSourcePict->linear.p2 = *p2;
934
935 initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
936 if (*error) {
937 free(pPicture);
938 return 0;
939 }
940 return pPicture;
941}
942
943PicturePtr
944CreateRadialGradientPicture(Picture pid, xPointFixed * inner,
945 xPointFixed * outer, xFixed innerRadius,
946 xFixed outerRadius, int nStops, xFixed * stops,
947 xRenderColor * colors, int *error)
948{
949 PicturePtr pPicture;
950 PictRadialGradient *radial;
951
952 if (nStops < 1) {
953 *error = BadValue2;
954 return 0;
955 }
956
957 pPicture = createSourcePicture();
958 if (!pPicture) {
959 *error = BadAlloc11;
960 return 0;
961 }
962
963 pPicture->id = pid;
964 pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictRadialGradient));
965 if (!pPicture->pSourcePict) {
966 *error = BadAlloc11;
967 free(pPicture);
968 return 0;
969 }
970 radial = &pPicture->pSourcePict->radial;
971
972 radial->type = SourcePictTypeRadial2;
973 radial->c1.x = inner->x;
974 radial->c1.y = inner->y;
975 radial->c1.radius = innerRadius;
976 radial->c2.x = outer->x;
977 radial->c2.y = outer->y;
978 radial->c2.radius = outerRadius;
979
980 initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
981 if (*error) {
982 free(pPicture);
983 return 0;
984 }
985 return pPicture;
986}
987
988PicturePtr
989CreateConicalGradientPicture(Picture pid, xPointFixed * center, xFixed angle,
990 int nStops, xFixed * stops, xRenderColor * colors,
991 int *error)
992{
993 PicturePtr pPicture;
994
995 if (nStops < 1) {
996 *error = BadValue2;
997 return 0;
998 }
999
1000 pPicture = createSourcePicture();
1001 if (!pPicture) {
1002 *error = BadAlloc11;
1003 return 0;
1004 }
1005
1006 pPicture->id = pid;
1007 pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictConicalGradient));
1008 if (!pPicture->pSourcePict) {
1009 *error = BadAlloc11;
1010 free(pPicture);
1011 return 0;
1012 }
1013
1014 pPicture->pSourcePict->conical.type = SourcePictTypeConical3;
1015 pPicture->pSourcePict->conical.center = *center;
1016 pPicture->pSourcePict->conical.angle = angle;
1017
1018 initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
1019 if (*error) {
1020 free(pPicture);
1021 return 0;
1022 }
1023 return pPicture;
1024}
1025
1026static int
1027cpAlphaMap(void **result, XID id, ScreenPtr screen, ClientPtr client, Mask mode)
1028{
1029#ifdef PANORAMIX1
1030 if (!noPanoramiXExtension) {
1031 PanoramiXRes *res;
1032 int err = dixLookupResourceByType((void **)&res, id, XRT_PICTURE,
1033 client, mode);
1034 if (err != Success0)
1035 return err;
1036 id = res->info[screen->myNum].id;
1037 }
1038#endif
1039 return dixLookupResourceByType(result, id, PictureType, client, mode);
1040}
1041
1042static int
1043cpClipMask(void **result, XID id, ScreenPtr screen, ClientPtr client, Mask mode)
1044{
1045#ifdef PANORAMIX1
1046 if (!noPanoramiXExtension) {
1047 PanoramiXRes *res;
1048 int err = dixLookupResourceByType((void **)&res, id, XRT_PIXMAP,
1049 client, mode);
1050 if (err != Success0)
1051 return err;
1052 id = res->info[screen->myNum].id;
1053 }
1054#endif
1055 return dixLookupResourceByType(result, id, RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), client, mode);
1056}
1057
1058#define NEXT_VAL(_type)(vlist ? (_type) *vlist++ : (_type) ulist++->val) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
1059
1060#define NEXT_PTR(_type)((_type) ulist++->ptr) ((_type) ulist++->ptr)
1061
1062int
1063ChangePicture(PicturePtr pPicture,
1064 Mask vmask, XID *vlist, DevUnion *ulist, ClientPtr client)
1065{
1066 ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
1067 PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen)((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec)))
: 0;
1068 BITS32 index2;
1069 int error = 0;
1070 BITS32 maskQ;
1071
1072 pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
1073 maskQ = vmask;
1074 while (vmask && !error) {
1075 index2 = (BITS32) lowbit(vmask)((vmask) & (~(vmask) + 1));
1076 vmask &= ~index2;
1077 pPicture->stateChanges |= index2;
1078 switch (index2) {
1079 case CPRepeat(1 << 0):
1080 {
1081 unsigned int newr;
1082 newr = NEXT_VAL(unsigned int)(vlist ? (unsigned int) *vlist++ : (unsigned int) ulist++->
val)
;
1083
1084 if (newr <= RepeatReflect3) {
1085 pPicture->repeat = (newr != RepeatNone0);
1086 pPicture->repeatType = newr;
1087 }
1088 else {
1089 client->errorValue = newr;
1090 error = BadValue2;
1091 }
1092 }
1093 break;
1094 case CPAlphaMap(1 << 1):
1095 {
1096 PicturePtr pAlpha;
1097
1098 if (vlist) {
1099 Picture pid = NEXT_VAL(Picture)(vlist ? (Picture) *vlist++ : (Picture) ulist++->val);
1100
1101 if (pid == None0L)
1102 pAlpha = 0;
1103 else {
1104 error = cpAlphaMap((void **) &pAlpha, pid, pScreen,
1105 client, DixReadAccess(1<<0));
1106 if (error != Success0) {
1107 client->errorValue = pid;
1108 break;
1109 }
1110 if (pAlpha->pDrawable == NULL((void*)0) ||
1111 pAlpha->pDrawable->type != DRAWABLE_PIXMAP1) {
1112 client->errorValue = pid;
1113 error = BadMatch8;
1114 break;
1115 }
1116 }
1117 }
1118 else
1119 pAlpha = NEXT_PTR(PicturePtr)((PicturePtr) ulist++->ptr);
1120 if (!error) {
1121 if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP1)
1122 pAlpha->refcnt++;
1123 if (pPicture->alphaMap)
1124 FreePicture((void *) pPicture->alphaMap, (XID) 0);
1125 pPicture->alphaMap = pAlpha;
1126 }
1127 }
1128 break;
1129 case CPAlphaXOrigin(1 << 2):
1130 pPicture->alphaOrigin.x = NEXT_VAL(INT16)(vlist ? (INT16) *vlist++ : (INT16) ulist++->val);
1131
1132 break;
1133 case CPAlphaYOrigin(1 << 3):
1134 pPicture->alphaOrigin.y = NEXT_VAL(INT16)(vlist ? (INT16) *vlist++ : (INT16) ulist++->val);
1135
1136 break;
1137 case CPClipXOrigin(1 << 4):
1138 pPicture->clipOrigin.x = NEXT_VAL(INT16)(vlist ? (INT16) *vlist++ : (INT16) ulist++->val);
1139
1140 break;
1141 case CPClipYOrigin(1 << 5):
1142 pPicture->clipOrigin.y = NEXT_VAL(INT16)(vlist ? (INT16) *vlist++ : (INT16) ulist++->val);
1143
1144 break;
1145 case CPClipMask(1 << 6):
1146 {
1147 Pixmap pid;
1148 PixmapPtr pPixmap;
1149 int clipType;
1150
1151 if (!pScreen)
1152 return BadDrawable9;
1153
1154 if (vlist) {
1155 pid = NEXT_VAL(Pixmap)(vlist ? (Pixmap) *vlist++ : (Pixmap) ulist++->val);
1156 if (pid == None0L) {
1157 clipType = CT_NONE0;
1158 pPixmap = NullPixmap((PixmapPtr)0);
1159 }
1160 else {
1161 clipType = CT_PIXMAP1;
1162 error = cpClipMask((void **) &pPixmap, pid, pScreen,
1163 client, DixReadAccess(1<<0));
1164 if (error != Success0) {
1165 client->errorValue = pid;
1166 break;
1167 }
1168 }
1169 }
1170 else {
1171 pPixmap = NEXT_PTR(PixmapPtr)((PixmapPtr) ulist++->ptr);
1172
1173 if (pPixmap)
1174 clipType = CT_PIXMAP1;
1175 else
1176 clipType = CT_NONE0;
1177 }
1178
1179 if (pPixmap) {
1180 if ((pPixmap->drawable.depth != 1) ||
1181 (pPixmap->drawable.pScreen != pScreen)) {
1182 error = BadMatch8;
1183 break;
1184 }
1185 else {
1186 clipType = CT_PIXMAP1;
1187 pPixmap->refcnt++;
1188 }
1189 }
1190 error = (*ps->ChangePictureClip) (pPicture, clipType,
1191 (void *) pPixmap, 0);
1192 break;
1193 }
1194 case CPGraphicsExposure(1 << 7):
1195 {
1196 unsigned int newe;
1197 newe = NEXT_VAL(unsigned int)(vlist ? (unsigned int) *vlist++ : (unsigned int) ulist++->
val)
;
1198
1199 if (newe <= xTrue1)
1200 pPicture->graphicsExposures = newe;
1201 else {
1202 client->errorValue = newe;
1203 error = BadValue2;
1204 }
1205 }
1206 break;
1207 case CPSubwindowMode(1 << 8):
1208 {
1209 unsigned int news;
1210 news = NEXT_VAL(unsigned int)(vlist ? (unsigned int) *vlist++ : (unsigned int) ulist++->
val)
;
1211
1212 if (news == ClipByChildren0 || news == IncludeInferiors1)
1213 pPicture->subWindowMode = news;
1214 else {
1215 client->errorValue = news;
1216 error = BadValue2;
1217 }
1218 }
1219 break;
1220 case CPPolyEdge(1 << 9):
1221 {
1222 unsigned int newe;
1223 newe = NEXT_VAL(unsigned int)(vlist ? (unsigned int) *vlist++ : (unsigned int) ulist++->
val)
;
1224
1225 if (newe == PolyEdgeSharp0 || newe == PolyEdgeSmooth1)
1226 pPicture->polyEdge = newe;
1227 else {
1228 client->errorValue = newe;
1229 error = BadValue2;
1230 }
1231 }
1232 break;
1233 case CPPolyMode(1 << 10):
1234 {
1235 unsigned int newm;
1236 newm = NEXT_VAL(unsigned int)(vlist ? (unsigned int) *vlist++ : (unsigned int) ulist++->
val)
;
1237
1238 if (newm == PolyModePrecise0 || newm == PolyModeImprecise1)
1239 pPicture->polyMode = newm;
1240 else {
1241 client->errorValue = newm;
1242 error = BadValue2;
1243 }
1244 }
1245 break;
1246 case CPDither(1 << 11):
1247 (void) NEXT_VAL(Atom)(vlist ? (Atom) *vlist++ : (Atom) ulist++->val); /* unimplemented */
1248
1249 break;
1250 case CPComponentAlpha(1 << 12):
1251 {
1252 unsigned int newca;
1253
1254 newca = NEXT_VAL(unsigned int)(vlist ? (unsigned int) *vlist++ : (unsigned int) ulist++->
val)
;
1255
1256 if (newca <= xTrue1)
1257 pPicture->componentAlpha = newca;
1258 else {
1259 client->errorValue = newca;
1260 error = BadValue2;
1261 }
1262 }
1263 break;
1264 default:
1265 client->errorValue = maskQ;
1266 error = BadValue2;
1267 break;
1268 }
1269 }
1270 if (ps)
1271 (*ps->ChangePicture) (pPicture, maskQ);
1272 return error;
1273}
1274
1275int
1276SetPictureClipRects(PicturePtr pPicture,
1277 int xOrigin, int yOrigin, int nRect, xRectangle *rects)
1278{
1279 ScreenPtr pScreen = pPicture->pDrawable->pScreen;
1280 PictureScreenPtr ps = GetPictureScreen(pScreen)((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec)))
;
1281 RegionPtr clientClip;
1282 int result;
1283
1284 clientClip = RegionFromRects(nRect, rects, CT_UNSORTED6);
1285 if (!clientClip)
1286 return BadAlloc11;
1287 result = (*ps->ChangePictureClip) (pPicture, CT_REGION2,
1288 (void *) clientClip, 0);
1289 if (result == Success0) {
1290 pPicture->clipOrigin.x = xOrigin;
1291 pPicture->clipOrigin.y = yOrigin;
1292 pPicture->stateChanges |= CPClipXOrigin(1 << 4) | CPClipYOrigin(1 << 5) | CPClipMask(1 << 6);
1293 pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
1294 }
1295 return result;
1296}
1297
1298int
1299SetPictureClipRegion(PicturePtr pPicture,
1300 int xOrigin, int yOrigin, RegionPtr pRegion)
1301{
1302 ScreenPtr pScreen = pPicture->pDrawable->pScreen;
1303 PictureScreenPtr ps = GetPictureScreen(pScreen)((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec)))
;
1304 RegionPtr clientClip;
1305 int result;
1306 int type;
1307
1308 if (pRegion) {
1309 type = CT_REGION2;
1310 clientClip = RegionCreate(RegionExtents(pRegion),
1311 RegionNumRects(pRegion));
1312 if (!clientClip)
1313 return BadAlloc11;
1314 if (!RegionCopy(clientClip, pRegion)) {
1315 RegionDestroy(clientClip);
1316 return BadAlloc11;
1317 }
1318 }
1319 else {
1320 type = CT_NONE0;
1321 clientClip = 0;
1322 }
1323
1324 result = (*ps->ChangePictureClip) (pPicture, type, (void *) clientClip, 0);
1325 if (result == Success0) {
1326 pPicture->clipOrigin.x = xOrigin;
1327 pPicture->clipOrigin.y = yOrigin;
1328 pPicture->stateChanges |= CPClipXOrigin(1 << 4) | CPClipYOrigin(1 << 5) | CPClipMask(1 << 6);
1329 pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
1330 }
1331 return result;
1332}
1333
1334static Bool
1335transformIsIdentity(PictTransform * t)
1336{
1337 return ((t->matrix[0][0] == t->matrix[1][1]) &&
1338 (t->matrix[0][0] == t->matrix[2][2]) &&
1339 (t->matrix[0][0] != 0) &&
1340 (t->matrix[0][1] == 0) &&
1341 (t->matrix[0][2] == 0) &&
1342 (t->matrix[1][0] == 0) &&
1343 (t->matrix[1][2] == 0) &&
1344 (t->matrix[2][0] == 0) && (t->matrix[2][1] == 0));
1345}
1346
1347int
1348SetPictureTransform(PicturePtr pPicture, PictTransform * transform)
1349{
1350 if (transform && transformIsIdentity(transform))
1351 transform = 0;
1352
1353 if (transform) {
1354 if (!pPicture->transform) {
1355 pPicture->transform =
1356 (PictTransform *) malloc(sizeof(PictTransform));
1357 if (!pPicture->transform)
1358 return BadAlloc11;
1359 }
1360 *pPicture->transform = *transform;
1361 }
1362 else {
1363 free(pPicture->transform);
1364 pPicture->transform = NULL((void*)0);
1365 }
1366 pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
1367
1368 if (pPicture->pDrawable != NULL((void*)0)) {
1369 int result;
1370 PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pPicture->pDrawable
->pScreen)->devPrivates, (&PictureScreenPrivateKeyRec
)))
;
1371
1372 result = (*ps->ChangePictureTransform) (pPicture, transform);
1373
1374 return result;
1375 }
1376
1377 return Success0;
1378}
1379
1380static void
1381ValidateOnePicture(PicturePtr pPicture)
1382{
1383 if (pPicture->pDrawable &&
1384 pPicture->serialNumber != pPicture->pDrawable->serialNumber) {
1385 PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pPicture->pDrawable
->pScreen)->devPrivates, (&PictureScreenPrivateKeyRec
)))
;
1386
1387 (*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
1388 pPicture->stateChanges = 0;
1389 pPicture->serialNumber = pPicture->pDrawable->serialNumber;
1390 }
1391}
1392
1393void
1394ValidatePicture(PicturePtr pPicture)
1395{
1396 ValidateOnePicture(pPicture);
1397 if (pPicture->alphaMap)
1398 ValidateOnePicture(pPicture->alphaMap);
1399}
1400
1401int
1402FreePicture(void *value, XID pid)
1403{
1404 PicturePtr pPicture = (PicturePtr) value;
1405
1406 if (--pPicture->refcnt == 0) {
1407 free(pPicture->transform);
1408 free(pPicture->filter_params);
1409
1410 if (pPicture->pSourcePict) {
1411 if (pPicture->pSourcePict->type != SourcePictTypeSolidFill0)
1412 free(pPicture->pSourcePict->linear.stops);
1413
1414 free(pPicture->pSourcePict);
1415 }
1416
1417 if (pPicture->pDrawable) {
1418 ScreenPtr pScreen = pPicture->pDrawable->pScreen;
1419 PictureScreenPtr ps = GetPictureScreen(pScreen)((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec)))
;
1420
1421 if (pPicture->alphaMap)
1422 FreePicture((void *) pPicture->alphaMap, (XID) 0);
1423 (*ps->DestroyPicture) (pPicture);
1424 (*ps->DestroyPictureClip) (pPicture);
1425 if (pPicture->pDrawable->type == DRAWABLE_WINDOW0) {
1426 WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
1427 PicturePtr *pPrev;
1428
1429 for (pPrev = (PicturePtr *) dixLookupPrivateAddr
1430 (&pWindow->devPrivates, PictureWindowPrivateKey(&PictureWindowPrivateKeyRec));
1431 *pPrev; pPrev = &(*pPrev)->pNext) {
1432 if (*pPrev == pPicture) {
1433 *pPrev = pPicture->pNext;
1434 break;
1435 }
1436 }
1437 }
1438 else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP1) {
1439 (*pScreen->DestroyPixmap) ((PixmapPtr) pPicture->pDrawable);
1440 }
1441 }
1442 dixFreeObjectWithPrivates(pPicture, PRIVATE_PICTURE)_dixFreeObjectWithPrivates(pPicture, (pPicture)->devPrivates
, PRIVATE_PICTURE)
;
1443 }
1444 return Success0;
1445}
1446
1447/**
1448 * ReduceCompositeOp is used to choose simpler ops for cases where alpha
1449 * channels are always one and so math on the alpha channel per pixel becomes
1450 * unnecessary. It may also avoid destination reads sometimes if apps aren't
1451 * being careful to avoid these cases.
1452 */
1453static CARD8
1454ReduceCompositeOp(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
1455 INT16 xSrc, INT16 ySrc, CARD16 width, CARD16 height)
1456{
1457 Bool no_src_alpha, no_dst_alpha;
1458
1459 /* Sampling off the edge of a RepeatNone picture introduces alpha
1460 * even if the picture itself doesn't have alpha. We don't try to
1461 * detect every case where we don't sample off the edge, just the
1462 * simplest case where there is no transform on the source
1463 * picture.
1464 */
1465 no_src_alpha = PICT_FORMAT_COLOR(pSrc->format)((((pSrc->format) >> 16) & 0xff) == 2 || (((pSrc
->format) >> 16) & 0xff) == 3 || (((pSrc->format
) >> 16) & 0xff) == 8 || (((pSrc->format) >>
16) & 0xff) == 9)
&&
1466 PICT_FORMAT_A(pSrc->format)(((pSrc->format) >> 12) & 0x0f) == 0 &&
1467 (pSrc->repeatType != RepeatNone0 ||
1468 (!pSrc->transform &&
1469 xSrc >= 0 && ySrc >= 0 &&
1470 xSrc + width <= pSrc->pDrawable->width &&
1471 ySrc + height <= pSrc->pDrawable->height)) &&
1472 pSrc->alphaMap == NULL((void*)0) && pMask == NULL((void*)0);
1473 no_dst_alpha = PICT_FORMAT_COLOR(pDst->format)((((pDst->format) >> 16) & 0xff) == 2 || (((pDst
->format) >> 16) & 0xff) == 3 || (((pDst->format
) >> 16) & 0xff) == 8 || (((pDst->format) >>
16) & 0xff) == 9)
&&
1474 PICT_FORMAT_A(pDst->format)(((pDst->format) >> 12) & 0x0f) == 0 && pDst->alphaMap == NULL((void*)0);
1475
1476 /* TODO, maybe: Conjoint and Disjoint op reductions? */
1477
1478 /* Deal with simplifications where the source alpha is always 1. */
1479 if (no_src_alpha) {
1480 switch (op) {
1481 case PictOpOver3:
1482 op = PictOpSrc1;
1483 break;
1484 case PictOpInReverse6:
1485 op = PictOpDst2;
1486 break;
1487 case PictOpOutReverse8:
1488 op = PictOpClear0;
1489 break;
1490 case PictOpAtop9:
1491 op = PictOpIn5;
1492 break;
1493 case PictOpAtopReverse10:
1494 op = PictOpOverReverse4;
1495 break;
1496 case PictOpXor11:
1497 op = PictOpOut7;
1498 break;
1499 default:
1500 break;
1501 }
1502 }
1503
1504 /* Deal with simplifications when the destination alpha is always 1 */
1505 if (no_dst_alpha) {
1506 switch (op) {
1507 case PictOpOverReverse4:
1508 op = PictOpDst2;
1509 break;
1510 case PictOpIn5:
1511 op = PictOpSrc1;
1512 break;
1513 case PictOpOut7:
1514 op = PictOpClear0;
1515 break;
1516 case PictOpAtop9:
1517 op = PictOpOver3;
1518 break;
1519 case PictOpXor11:
1520 op = PictOpOutReverse8;
1521 break;
1522 default:
1523 break;
1524 }
1525 }
1526
1527 /* Reduce some con/disjoint ops to the basic names. */
1528 switch (op) {
1529 case PictOpDisjointClear0x10:
1530 case PictOpConjointClear0x20:
1531 op = PictOpClear0;
1532 break;
1533 case PictOpDisjointSrc0x11:
1534 case PictOpConjointSrc0x21:
1535 op = PictOpSrc1;
1536 break;
1537 case PictOpDisjointDst0x12:
1538 case PictOpConjointDst0x22:
1539 op = PictOpDst2;
1540 break;
1541 default:
1542 break;
1543 }
1544
1545 return op;
1546}
1547
1548void
1549CompositePicture(CARD8 op,
1550 PicturePtr pSrc,
1551 PicturePtr pMask,
1552 PicturePtr pDst,
1553 INT16 xSrc,
1554 INT16 ySrc,
1555 INT16 xMask,
1556 INT16 yMask,
1557 INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
1558{
1559 PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDst->pDrawable->
pScreen)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
1560
1561 ValidatePicture(pSrc);
1562 if (pMask)
1563 ValidatePicture(pMask);
1564 ValidatePicture(pDst);
1565
1566 op = ReduceCompositeOp(op, pSrc, pMask, pDst, xSrc, ySrc, width, height);
1567 if (op == PictOpDst2)
1568 return;
1569
1570 (*ps->Composite) (op,
1571 pSrc,
1572 pMask,
1573 pDst,
1574 xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
1575}
1576
1577void
1578CompositeRects(CARD8 op,
1579 PicturePtr pDst,
1580 xRenderColor * color, int nRect, xRectangle *rects)
1581{
1582 PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDst->pDrawable->
pScreen)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
1583
1584 ValidatePicture(pDst);
1585 (*ps->CompositeRects) (op, pDst, color, nRect, rects);
1586}
1587
1588void
1589CompositeTrapezoids(CARD8 op,
1590 PicturePtr pSrc,
1591 PicturePtr pDst,
1592 PictFormatPtr maskFormat,
1593 INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps)
1594{
1595 PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDst->pDrawable->
pScreen)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
1596
1597 ValidatePicture(pSrc);
1598 ValidatePicture(pDst);
1599 (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
1600}
1601
1602void
1603CompositeTriangles(CARD8 op,
1604 PicturePtr pSrc,
1605 PicturePtr pDst,
1606 PictFormatPtr maskFormat,
1607 INT16 xSrc,
1608 INT16 ySrc, int ntriangles, xTriangle * triangles)
1609{
1610 PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDst->pDrawable->
pScreen)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
1611
1612 ValidatePicture(pSrc);
1613 ValidatePicture(pDst);
1614 (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles,
1615 triangles);
1616}
1617
1618void
1619CompositeTriStrip(CARD8 op,
1620 PicturePtr pSrc,
1621 PicturePtr pDst,
1622 PictFormatPtr maskFormat,
1623 INT16 xSrc, INT16 ySrc, int npoints, xPointFixed * points)
1624{
1625 PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDst->pDrawable->
pScreen)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
1626
1627 if (npoints < 3)
1628 return;
1629
1630 ValidatePicture(pSrc);
1631 ValidatePicture(pDst);
1632 (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
1633}
1634
1635void
1636CompositeTriFan(CARD8 op,
1637 PicturePtr pSrc,
1638 PicturePtr pDst,
1639 PictFormatPtr maskFormat,
1640 INT16 xSrc, INT16 ySrc, int npoints, xPointFixed * points)
1641{
1642 PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDst->pDrawable->
pScreen)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
1643
1644 if (npoints < 3)
1645 return;
1646
1647 ValidatePicture(pSrc);
1648 ValidatePicture(pDst);
1649 (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
1650}
1651
1652void
1653AddTraps(PicturePtr pPicture, INT16 xOff, INT16 yOff, int ntrap, xTrap * traps)
1654{
1655 PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pPicture->pDrawable
->pScreen)->devPrivates, (&PictureScreenPrivateKeyRec
)))
;
1656
1657 ValidatePicture(pPicture);
1658 (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
1659}