Bug Summary

File:render/picture.c
Location:line 263, column 9
Description:Value stored to 'format' is never read

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
64Bool
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
85Bool
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
105void
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
166PictFormatPtr
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;
Value stored to 'format' is never read
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
442Bool
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
628Bool
629PictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
630{
631 PictureScreenPtr ps;
632 int n;
633 CARD32 type, a, r, g, b;
634
635 if (PictureGeneration != serverGeneration) {
636 PictureType = CreateNewResourceType(FreePicture, "PICTURE");
637 if (!PictureType)
638 return FALSE0;
639 SetResourceTypeSizeFunc(PictureType, GetPictureBytes);
640 PictFormatType = CreateNewResourceType(FreePictFormat, "PICTFORMAT");
641 if (!PictFormatType)
642 return FALSE0;
643 GlyphSetType = CreateNewResourceType(FreeGlyphSet, "GLYPHSET");
644 if (!GlyphSetType)
645 return FALSE0;
646 PictureGeneration = serverGeneration;
647 }
648 if (!dixRegisterPrivateKey(&PictureScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
649 return FALSE0;
650
651 if (!dixRegisterPrivateKey(&PictureWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
652 return FALSE0;
653
654 if (!formats) {
655 formats = PictureCreateDefaultFormats(pScreen, &nformats);
656 if (!formats)
657 return FALSE0;
658 }
659 for (n = 0; n < nformats; n++) {
660 if (!AddResourceDarwin_X_AddResource
661 (formats[n].id, PictFormatType, (void *) (formats + n))) {
662 free(formats);
663 return FALSE0;
664 }
665 if (formats[n].type == PictTypeIndexed0) {
666 VisualPtr pVisual =
667 PictureFindVisual(pScreen, formats[n].index.vid);
668 if ((pVisual->class | DynamicClass1) == PseudoColor3)
669 type = PICT_TYPE_COLOR4;
670 else
671 type = PICT_TYPE_GRAY5;
672 a = r = g = b = 0;
673 }
674 else {
675 if ((formats[n].direct.redMask |
676 formats[n].direct.blueMask | formats[n].direct.greenMask) == 0)
677 type = PICT_TYPE_A1;
678 else if (formats[n].direct.red > formats[n].direct.blue)
679 type = PICT_TYPE_ARGB2;
680 else if (formats[n].direct.red == 0)
681 type = PICT_TYPE_ABGR3;
682 else
683 type = PICT_TYPE_BGRA8;
684 a = Ones(formats[n].direct.alphaMask);
685 r = Ones(formats[n].direct.redMask);
686 g = Ones(formats[n].direct.greenMask);
687 b = Ones(formats[n].direct.blueMask);
688 }
689 formats[n].format = PICT_FORMAT(0, type, a, r, g, b)(((0) << 24) | ((type) << 16) | ((a) << 12)
| ((r) << 8) | ((g) << 4) | ((b)))
;
690 }
691 ps = (PictureScreenPtr) malloc(sizeof(PictureScreenRec));
692 if (!ps) {
693 free(formats);
694 return FALSE0;
695 }
696 SetPictureScreen(pScreen, ps)dixSetPrivate(&(pScreen)->devPrivates, (&PictureScreenPrivateKeyRec
), ps)
;
697
698 ps->formats = formats;
699 ps->fallback = formats;
700 ps->nformats = nformats;
701
702 ps->filters = 0;
703 ps->nfilters = 0;
704 ps->filterAliases = 0;
705 ps->nfilterAliases = 0;
706
707 ps->subpixel = SubPixelUnknown0;
708
709 ps->CloseScreen = pScreen->CloseScreen;
710 ps->DestroyWindow = pScreen->DestroyWindow;
711 ps->StoreColors = pScreen->StoreColors;
712 pScreen->DestroyWindow = PictureDestroyWindow;
713 pScreen->CloseScreen = PictureCloseScreen;
714 pScreen->StoreColors = PictureStoreColors;
715
716 if (!PictureSetDefaultFilters(pScreen)) {
717 PictureResetFilters(pScreen);
718 SetPictureScreen(pScreen, 0)dixSetPrivate(&(pScreen)->devPrivates, (&PictureScreenPrivateKeyRec
), 0)
;
719 free(formats);
720 free(ps);
721 return FALSE0;
722 }
723
724 return TRUE1;
725}
726
727void
728SetPictureToDefaults(PicturePtr pPicture)
729{
730 pPicture->refcnt = 1;
731 pPicture->repeat = 0;
732 pPicture->graphicsExposures = FALSE0;
733 pPicture->subWindowMode = ClipByChildren0;
734 pPicture->polyEdge = PolyEdgeSharp0;
735 pPicture->polyMode = PolyModePrecise0;
736 pPicture->freeCompClip = FALSE0;
737 pPicture->componentAlpha = FALSE0;
738 pPicture->repeatType = RepeatNone0;
739
740 pPicture->alphaMap = 0;
741 pPicture->alphaOrigin.x = 0;
742 pPicture->alphaOrigin.y = 0;
743
744 pPicture->clipOrigin.x = 0;
745 pPicture->clipOrigin.y = 0;
746 pPicture->clientClip = 0;
747
748 pPicture->transform = 0;
749
750 pPicture->filter = PictureGetFilterId(FilterNearest"nearest", -1, TRUE1);
751 pPicture->filter_params = 0;
752 pPicture->filter_nparams = 0;
753
754 pPicture->serialNumber = GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
755 pPicture->stateChanges = -1;
756 pPicture->pSourcePict = 0;
757}
758
759PicturePtr
760CreatePicture(Picture pid,
761 DrawablePtr pDrawable,
762 PictFormatPtr pFormat,
763 Mask vmask, XID *vlist, ClientPtr client, int *error)
764{
765 PicturePtr pPicture;
766 PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDrawable->pScreen
)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
767
768 pPicture = dixAllocateScreenObjectWithPrivates(pDrawable->pScreen,_dixAllocateScreenObjectWithPrivates(pDrawable->pScreen, sizeof
(PictureRec), sizeof(PictureRec), __builtin_offsetof(PictureRec
, devPrivates), PRIVATE_PICTURE)
769 PictureRec, PRIVATE_PICTURE)_dixAllocateScreenObjectWithPrivates(pDrawable->pScreen, sizeof
(PictureRec), sizeof(PictureRec), __builtin_offsetof(PictureRec
, devPrivates), PRIVATE_PICTURE)
;
770 if (!pPicture) {
771 *error = BadAlloc11;
772 return 0;
773 }
774
775 pPicture->id = pid;
776 pPicture->pDrawable = pDrawable;
777 pPicture->pFormat = pFormat;
778 pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
779
780 /* security creation/labeling check */
781 *error = XaceHook(XACE_RESOURCE_ACCESS2, client, pid, PictureType, pPicture,
782 RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), pDrawable, DixCreateAccess(1<<3) | DixSetAttrAccess(1<<5));
783 if (*error != Success0)
784 goto out;
785
786 if (pDrawable->type == DRAWABLE_PIXMAP1) {
787 ++((PixmapPtr) pDrawable)->refcnt;
788 pPicture->pNext = 0;
789 }
790 else {
791 pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable))((PicturePtr)dixLookupPrivate(&(((WindowPtr) pDrawable))->
devPrivates, (&PictureWindowPrivateKeyRec)))
;
792 SetPictureWindow(((WindowPtr) pDrawable), pPicture)dixSetPrivate(&(((WindowPtr) pDrawable))->devPrivates,
(&PictureWindowPrivateKeyRec), pPicture)
;
793 }
794
795 SetPictureToDefaults(pPicture);
796
797 if (vmask)
798 *error = ChangePicture(pPicture, vmask, vlist, 0, client);
799 else
800 *error = Success0;
801 if (*error == Success0)
802 *error = (*ps->CreatePicture) (pPicture);
803 out:
804 if (*error != Success0) {
805 FreePicture(pPicture, (XID) 0);
806 pPicture = 0;
807 }
808 return pPicture;
809}
810
811static CARD32
812xRenderColorToCard32(xRenderColor c)
813{
814 return
815 (c.alpha >> 8 << 24) |
816 (c.red >> 8 << 16) | (c.green & 0xff00) | (c.blue >> 8);
817}
818
819static void
820initGradient(SourcePictPtr pGradient, int stopCount,
821 xFixed * stopPoints, xRenderColor * stopColors, int *error)
822{
823 int i;
824 xFixed dpos;
825
826 if (stopCount <= 0) {
827 *error = BadValue2;
828 return;
829 }
830
831 dpos = -1;
832 for (i = 0; i < stopCount; ++i) {
833 if (stopPoints[i] < dpos || stopPoints[i] > (1 << 16)) {
834 *error = BadValue2;
835 return;
836 }
837 dpos = stopPoints[i];
838 }
839
840 pGradient->gradient.stops = malloc(stopCount * sizeof(PictGradientStop));
841 if (!pGradient->gradient.stops) {
842 *error = BadAlloc11;
843 return;
844 }
845
846 pGradient->gradient.nstops = stopCount;
847
848 for (i = 0; i < stopCount; ++i) {
849 pGradient->gradient.stops[i].x = stopPoints[i];
850 pGradient->gradient.stops[i].color = stopColors[i];
851 }
852}
853
854static PicturePtr
855createSourcePicture(void)
856{
857 PicturePtr pPicture;
858
859 pPicture = dixAllocateScreenObjectWithPrivates(NULL, PictureRec,_dixAllocateScreenObjectWithPrivates(((void*)0), sizeof(PictureRec
), sizeof(PictureRec), __builtin_offsetof(PictureRec, devPrivates
), PRIVATE_PICTURE)
860 PRIVATE_PICTURE)_dixAllocateScreenObjectWithPrivates(((void*)0), sizeof(PictureRec
), sizeof(PictureRec), __builtin_offsetof(PictureRec, devPrivates
), PRIVATE_PICTURE)
;
861 if (!pPicture)
862 return 0;
863
864 pPicture->pDrawable = 0;
865 pPicture->pFormat = 0;
866 pPicture->pNext = 0;
867 pPicture->format = PICT_a8r8g8b8;
868
869 SetPictureToDefaults(pPicture);
870 return pPicture;
871}
872
873PicturePtr
874CreateSolidPicture(Picture pid, xRenderColor * color, int *error)
875{
876 PicturePtr pPicture;
877
878 pPicture = createSourcePicture();
879 if (!pPicture) {
880 *error = BadAlloc11;
881 return 0;
882 }
883
884 pPicture->id = pid;
885 pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictSolidFill));
886 if (!pPicture->pSourcePict) {
887 *error = BadAlloc11;
888 free(pPicture);
889 return 0;
890 }
891 pPicture->pSourcePict->type = SourcePictTypeSolidFill0;
892 pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
893 return pPicture;
894}
895
896PicturePtr
897CreateLinearGradientPicture(Picture pid, xPointFixed * p1, xPointFixed * p2,
898 int nStops, xFixed * stops, xRenderColor * colors,
899 int *error)
900{
901 PicturePtr pPicture;
902
903 if (nStops < 1) {
904 *error = BadValue2;
905 return 0;
906 }
907
908 pPicture = createSourcePicture();
909 if (!pPicture) {
910 *error = BadAlloc11;
911 return 0;
912 }
913
914 pPicture->id = pid;
915 pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictLinearGradient));
916 if (!pPicture->pSourcePict) {
917 *error = BadAlloc11;
918 free(pPicture);
919 return 0;
920 }
921
922 pPicture->pSourcePict->linear.type = SourcePictTypeLinear1;
923 pPicture->pSourcePict->linear.p1 = *p1;
924 pPicture->pSourcePict->linear.p2 = *p2;
925
926 initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
927 if (*error) {
928 free(pPicture);
929 return 0;
930 }
931 return pPicture;
932}
933
934PicturePtr
935CreateRadialGradientPicture(Picture pid, xPointFixed * inner,
936 xPointFixed * outer, xFixed innerRadius,
937 xFixed outerRadius, int nStops, xFixed * stops,
938 xRenderColor * colors, int *error)
939{
940 PicturePtr pPicture;
941 PictRadialGradient *radial;
942
943 if (nStops < 1) {
944 *error = BadValue2;
945 return 0;
946 }
947
948 pPicture = createSourcePicture();
949 if (!pPicture) {
950 *error = BadAlloc11;
951 return 0;
952 }
953
954 pPicture->id = pid;
955 pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictRadialGradient));
956 if (!pPicture->pSourcePict) {
957 *error = BadAlloc11;
958 free(pPicture);
959 return 0;
960 }
961 radial = &pPicture->pSourcePict->radial;
962
963 radial->type = SourcePictTypeRadial2;
964 radial->c1.x = inner->x;
965 radial->c1.y = inner->y;
966 radial->c1.radius = innerRadius;
967 radial->c2.x = outer->x;
968 radial->c2.y = outer->y;
969 radial->c2.radius = outerRadius;
970
971 initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
972 if (*error) {
973 free(pPicture);
974 return 0;
975 }
976 return pPicture;
977}
978
979PicturePtr
980CreateConicalGradientPicture(Picture pid, xPointFixed * center, xFixed angle,
981 int nStops, xFixed * stops, xRenderColor * colors,
982 int *error)
983{
984 PicturePtr pPicture;
985
986 if (nStops < 1) {
987 *error = BadValue2;
988 return 0;
989 }
990
991 pPicture = createSourcePicture();
992 if (!pPicture) {
993 *error = BadAlloc11;
994 return 0;
995 }
996
997 pPicture->id = pid;
998 pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictConicalGradient));
999 if (!pPicture->pSourcePict) {
1000 *error = BadAlloc11;
1001 free(pPicture);
1002 return 0;
1003 }
1004
1005 pPicture->pSourcePict->conical.type = SourcePictTypeConical3;
1006 pPicture->pSourcePict->conical.center = *center;
1007 pPicture->pSourcePict->conical.angle = angle;
1008
1009 initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
1010 if (*error) {
1011 free(pPicture);
1012 return 0;
1013 }
1014 return pPicture;
1015}
1016
1017static int
1018cpAlphaMap(void **result, XID id, ScreenPtr screen, ClientPtr client, Mask mode)
1019{
1020#ifdef PANORAMIX1
1021 if (!noPanoramiXExtension) {
1022 PanoramiXRes *res;
1023 int err = dixLookupResourceByType((void **)&res, id, XRT_PICTURE,
1024 client, mode);
1025 if (err != Success0)
1026 return err;
1027 id = res->info[screen->myNum].id;
1028 }
1029#endif
1030 return dixLookupResourceByType(result, id, PictureType, client, mode);
1031}
1032
1033static int
1034cpClipMask(void **result, XID id, ScreenPtr screen, ClientPtr client, Mask mode)
1035{
1036#ifdef PANORAMIX1
1037 if (!noPanoramiXExtension) {
1038 PanoramiXRes *res;
1039 int err = dixLookupResourceByType((void **)&res, id, XRT_PIXMAP,
1040 client, mode);
1041 if (err != Success0)
1042 return err;
1043 id = res->info[screen->myNum].id;
1044 }
1045#endif
1046 return dixLookupResourceByType(result, id, RT_PIXMAP((RESTYPE)2|((RESTYPE)1<<30)), client, mode);
1047}
1048
1049#define NEXT_VAL(_type)(vlist ? (_type) *vlist++ : (_type) ulist++->val) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
1050
1051#define NEXT_PTR(_type)((_type) ulist++->ptr) ((_type) ulist++->ptr)
1052
1053int
1054ChangePicture(PicturePtr pPicture,
1055 Mask vmask, XID *vlist, DevUnion *ulist, ClientPtr client)
1056{
1057 ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
1058 PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen)((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec)))
: 0;
1059 BITS32 index2;
1060 int error = 0;
1061 BITS32 maskQ;
1062
1063 pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
1064 maskQ = vmask;
1065 while (vmask && !error) {
1066 index2 = (BITS32) lowbit(vmask)((vmask) & (~(vmask) + 1));
1067 vmask &= ~index2;
1068 pPicture->stateChanges |= index2;
1069 switch (index2) {
1070 case CPRepeat(1 << 0):
1071 {
1072 unsigned int newr;
1073 newr = NEXT_VAL(unsigned int)(vlist ? (unsigned int) *vlist++ : (unsigned int) ulist++->
val)
;
1074
1075 if (newr <= RepeatReflect3) {
1076 pPicture->repeat = (newr != RepeatNone0);
1077 pPicture->repeatType = newr;
1078 }
1079 else {
1080 client->errorValue = newr;
1081 error = BadValue2;
1082 }
1083 }
1084 break;
1085 case CPAlphaMap(1 << 1):
1086 {
1087 PicturePtr pAlpha;
1088
1089 if (vlist) {
1090 Picture pid = NEXT_VAL(Picture)(vlist ? (Picture) *vlist++ : (Picture) ulist++->val);
1091
1092 if (pid == None0L)
1093 pAlpha = 0;
1094 else {
1095 error = cpAlphaMap((void **) &pAlpha, pid, pScreen,
1096 client, DixReadAccess(1<<0));
1097 if (error != Success0) {
1098 client->errorValue = pid;
1099 break;
1100 }
1101 if (pAlpha->pDrawable == NULL((void*)0) ||
1102 pAlpha->pDrawable->type != DRAWABLE_PIXMAP1) {
1103 client->errorValue = pid;
1104 error = BadMatch8;
1105 break;
1106 }
1107 }
1108 }
1109 else
1110 pAlpha = NEXT_PTR(PicturePtr)((PicturePtr) ulist++->ptr);
1111 if (!error) {
1112 if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP1)
1113 pAlpha->refcnt++;
1114 if (pPicture->alphaMap)
1115 FreePicture((void *) pPicture->alphaMap, (XID) 0);
1116 pPicture->alphaMap = pAlpha;
1117 }
1118 }
1119 break;
1120 case CPAlphaXOrigin(1 << 2):
1121 pPicture->alphaOrigin.x = NEXT_VAL(INT16)(vlist ? (INT16) *vlist++ : (INT16) ulist++->val);
1122
1123 break;
1124 case CPAlphaYOrigin(1 << 3):
1125 pPicture->alphaOrigin.y = NEXT_VAL(INT16)(vlist ? (INT16) *vlist++ : (INT16) ulist++->val);
1126
1127 break;
1128 case CPClipXOrigin(1 << 4):
1129 pPicture->clipOrigin.x = NEXT_VAL(INT16)(vlist ? (INT16) *vlist++ : (INT16) ulist++->val);
1130
1131 break;
1132 case CPClipYOrigin(1 << 5):
1133 pPicture->clipOrigin.y = NEXT_VAL(INT16)(vlist ? (INT16) *vlist++ : (INT16) ulist++->val);
1134
1135 break;
1136 case CPClipMask(1 << 6):
1137 {
1138 Pixmap pid;
1139 PixmapPtr pPixmap;
1140 int clipType;
1141
1142 if (!pScreen)
1143 return BadDrawable9;
1144
1145 if (vlist) {
1146 pid = NEXT_VAL(Pixmap)(vlist ? (Pixmap) *vlist++ : (Pixmap) ulist++->val);
1147 if (pid == None0L) {
1148 clipType = CT_NONE0;
1149 pPixmap = NullPixmap((PixmapPtr)0);
1150 }
1151 else {
1152 clipType = CT_PIXMAP1;
1153 error = cpClipMask((void **) &pPixmap, pid, pScreen,
1154 client, DixReadAccess(1<<0));
1155 if (error != Success0) {
1156 client->errorValue = pid;
1157 break;
1158 }
1159 }
1160 }
1161 else {
1162 pPixmap = NEXT_PTR(PixmapPtr)((PixmapPtr) ulist++->ptr);
1163
1164 if (pPixmap)
1165 clipType = CT_PIXMAP1;
1166 else
1167 clipType = CT_NONE0;
1168 }
1169
1170 if (pPixmap) {
1171 if ((pPixmap->drawable.depth != 1) ||
1172 (pPixmap->drawable.pScreen != pScreen)) {
1173 error = BadMatch8;
1174 break;
1175 }
1176 else {
1177 clipType = CT_PIXMAP1;
1178 pPixmap->refcnt++;
1179 }
1180 }
1181 error = (*ps->ChangePictureClip) (pPicture, clipType,
1182 (void *) pPixmap, 0);
1183 break;
1184 }
1185 case CPGraphicsExposure(1 << 7):
1186 {
1187 unsigned int newe;
1188 newe = NEXT_VAL(unsigned int)(vlist ? (unsigned int) *vlist++ : (unsigned int) ulist++->
val)
;
1189
1190 if (newe <= xTrue1)
1191 pPicture->graphicsExposures = newe;
1192 else {
1193 client->errorValue = newe;
1194 error = BadValue2;
1195 }
1196 }
1197 break;
1198 case CPSubwindowMode(1 << 8):
1199 {
1200 unsigned int news;
1201 news = NEXT_VAL(unsigned int)(vlist ? (unsigned int) *vlist++ : (unsigned int) ulist++->
val)
;
1202
1203 if (news == ClipByChildren0 || news == IncludeInferiors1)
1204 pPicture->subWindowMode = news;
1205 else {
1206 client->errorValue = news;
1207 error = BadValue2;
1208 }
1209 }
1210 break;
1211 case CPPolyEdge(1 << 9):
1212 {
1213 unsigned int newe;
1214 newe = NEXT_VAL(unsigned int)(vlist ? (unsigned int) *vlist++ : (unsigned int) ulist++->
val)
;
1215
1216 if (newe == PolyEdgeSharp0 || newe == PolyEdgeSmooth1)
1217 pPicture->polyEdge = newe;
1218 else {
1219 client->errorValue = newe;
1220 error = BadValue2;
1221 }
1222 }
1223 break;
1224 case CPPolyMode(1 << 10):
1225 {
1226 unsigned int newm;
1227 newm = NEXT_VAL(unsigned int)(vlist ? (unsigned int) *vlist++ : (unsigned int) ulist++->
val)
;
1228
1229 if (newm == PolyModePrecise0 || newm == PolyModeImprecise1)
1230 pPicture->polyMode = newm;
1231 else {
1232 client->errorValue = newm;
1233 error = BadValue2;
1234 }
1235 }
1236 break;
1237 case CPDither(1 << 11):
1238 (void) NEXT_VAL(Atom)(vlist ? (Atom) *vlist++ : (Atom) ulist++->val); /* unimplemented */
1239
1240 break;
1241 case CPComponentAlpha(1 << 12):
1242 {
1243 unsigned int newca;
1244
1245 newca = NEXT_VAL(unsigned int)(vlist ? (unsigned int) *vlist++ : (unsigned int) ulist++->
val)
;
1246
1247 if (newca <= xTrue1)
1248 pPicture->componentAlpha = newca;
1249 else {
1250 client->errorValue = newca;
1251 error = BadValue2;
1252 }
1253 }
1254 break;
1255 default:
1256 client->errorValue = maskQ;
1257 error = BadValue2;
1258 break;
1259 }
1260 }
1261 if (ps)
1262 (*ps->ChangePicture) (pPicture, maskQ);
1263 return error;
1264}
1265
1266int
1267SetPictureClipRects(PicturePtr pPicture,
1268 int xOrigin, int yOrigin, int nRect, xRectangle *rects)
1269{
1270 ScreenPtr pScreen = pPicture->pDrawable->pScreen;
1271 PictureScreenPtr ps = GetPictureScreen(pScreen)((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec)))
;
1272 RegionPtr clientClip;
1273 int result;
1274
1275 clientClip = RegionFromRects(nRect, rects, CT_UNSORTED6);
1276 if (!clientClip)
1277 return BadAlloc11;
1278 result = (*ps->ChangePictureClip) (pPicture, CT_REGION2,
1279 (void *) clientClip, 0);
1280 if (result == Success0) {
1281 pPicture->clipOrigin.x = xOrigin;
1282 pPicture->clipOrigin.y = yOrigin;
1283 pPicture->stateChanges |= CPClipXOrigin(1 << 4) | CPClipYOrigin(1 << 5) | CPClipMask(1 << 6);
1284 pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
1285 }
1286 return result;
1287}
1288
1289int
1290SetPictureClipRegion(PicturePtr pPicture,
1291 int xOrigin, int yOrigin, RegionPtr pRegion)
1292{
1293 ScreenPtr pScreen = pPicture->pDrawable->pScreen;
1294 PictureScreenPtr ps = GetPictureScreen(pScreen)((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec)))
;
1295 RegionPtr clientClip;
1296 int result;
1297 int type;
1298
1299 if (pRegion) {
1300 type = CT_REGION2;
1301 clientClip = RegionCreate(RegionExtents(pRegion),
1302 RegionNumRects(pRegion));
1303 if (!clientClip)
1304 return BadAlloc11;
1305 if (!RegionCopy(clientClip, pRegion)) {
1306 RegionDestroy(clientClip);
1307 return BadAlloc11;
1308 }
1309 }
1310 else {
1311 type = CT_NONE0;
1312 clientClip = 0;
1313 }
1314
1315 result = (*ps->ChangePictureClip) (pPicture, type, (void *) clientClip, 0);
1316 if (result == Success0) {
1317 pPicture->clipOrigin.x = xOrigin;
1318 pPicture->clipOrigin.y = yOrigin;
1319 pPicture->stateChanges |= CPClipXOrigin(1 << 4) | CPClipYOrigin(1 << 5) | CPClipMask(1 << 6);
1320 pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
1321 }
1322 return result;
1323}
1324
1325static Bool
1326transformIsIdentity(PictTransform * t)
1327{
1328 return ((t->matrix[0][0] == t->matrix[1][1]) &&
1329 (t->matrix[0][0] == t->matrix[2][2]) &&
1330 (t->matrix[0][0] != 0) &&
1331 (t->matrix[0][1] == 0) &&
1332 (t->matrix[0][2] == 0) &&
1333 (t->matrix[1][0] == 0) &&
1334 (t->matrix[1][2] == 0) &&
1335 (t->matrix[2][0] == 0) && (t->matrix[2][1] == 0));
1336}
1337
1338int
1339SetPictureTransform(PicturePtr pPicture, PictTransform * transform)
1340{
1341 if (transform && transformIsIdentity(transform))
1342 transform = 0;
1343
1344 if (transform) {
1345 if (!pPicture->transform) {
1346 pPicture->transform =
1347 (PictTransform *) malloc(sizeof(PictTransform));
1348 if (!pPicture->transform)
1349 return BadAlloc11;
1350 }
1351 *pPicture->transform = *transform;
1352 }
1353 else {
1354 free(pPicture->transform);
1355 pPicture->transform = NULL((void*)0);
1356 }
1357 pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT(((unsigned long)1)<<31);
1358
1359 if (pPicture->pDrawable != NULL((void*)0)) {
1360 int result;
1361 PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pPicture->pDrawable
->pScreen)->devPrivates, (&PictureScreenPrivateKeyRec
)))
;
1362
1363 result = (*ps->ChangePictureTransform) (pPicture, transform);
1364
1365 return result;
1366 }
1367
1368 return Success0;
1369}
1370
1371static void
1372ValidateOnePicture(PicturePtr pPicture)
1373{
1374 if (pPicture->pDrawable &&
1375 pPicture->serialNumber != pPicture->pDrawable->serialNumber) {
1376 PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pPicture->pDrawable
->pScreen)->devPrivates, (&PictureScreenPrivateKeyRec
)))
;
1377
1378 (*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
1379 pPicture->stateChanges = 0;
1380 pPicture->serialNumber = pPicture->pDrawable->serialNumber;
1381 }
1382}
1383
1384void
1385ValidatePicture(PicturePtr pPicture)
1386{
1387 ValidateOnePicture(pPicture);
1388 if (pPicture->alphaMap)
1389 ValidateOnePicture(pPicture->alphaMap);
1390}
1391
1392int
1393FreePicture(void *value, XID pid)
1394{
1395 PicturePtr pPicture = (PicturePtr) value;
1396
1397 if (--pPicture->refcnt == 0) {
1398 free(pPicture->transform);
1399 free(pPicture->filter_params);
1400
1401 if (pPicture->pSourcePict) {
1402 if (pPicture->pSourcePict->type != SourcePictTypeSolidFill0)
1403 free(pPicture->pSourcePict->linear.stops);
1404
1405 free(pPicture->pSourcePict);
1406 }
1407
1408 if (pPicture->pDrawable) {
1409 ScreenPtr pScreen = pPicture->pDrawable->pScreen;
1410 PictureScreenPtr ps = GetPictureScreen(pScreen)((PictureScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates
, (&PictureScreenPrivateKeyRec)))
;
1411
1412 if (pPicture->alphaMap)
1413 FreePicture((void *) pPicture->alphaMap, (XID) 0);
1414 (*ps->DestroyPicture) (pPicture);
1415 (*ps->DestroyPictureClip) (pPicture);
1416 if (pPicture->pDrawable->type == DRAWABLE_WINDOW0) {
1417 WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
1418 PicturePtr *pPrev;
1419
1420 for (pPrev = (PicturePtr *) dixLookupPrivateAddr
1421 (&pWindow->devPrivates, PictureWindowPrivateKey(&PictureWindowPrivateKeyRec));
1422 *pPrev; pPrev = &(*pPrev)->pNext) {
1423 if (*pPrev == pPicture) {
1424 *pPrev = pPicture->pNext;
1425 break;
1426 }
1427 }
1428 }
1429 else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP1) {
1430 (*pScreen->DestroyPixmap) ((PixmapPtr) pPicture->pDrawable);
1431 }
1432 }
1433 dixFreeObjectWithPrivates(pPicture, PRIVATE_PICTURE)_dixFreeObjectWithPrivates(pPicture, (pPicture)->devPrivates
, PRIVATE_PICTURE)
;
1434 }
1435 return Success0;
1436}
1437
1438int
1439FreePictFormat(void *pPictFormat, XID pid)
1440{
1441 return Success0;
1442}
1443
1444/**
1445 * ReduceCompositeOp is used to choose simpler ops for cases where alpha
1446 * channels are always one and so math on the alpha channel per pixel becomes
1447 * unnecessary. It may also avoid destination reads sometimes if apps aren't
1448 * being careful to avoid these cases.
1449 */
1450static CARD8
1451ReduceCompositeOp(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
1452 INT16 xSrc, INT16 ySrc, CARD16 width, CARD16 height)
1453{
1454 Bool no_src_alpha, no_dst_alpha;
1455
1456 /* Sampling off the edge of a RepeatNone picture introduces alpha
1457 * even if the picture itself doesn't have alpha. We don't try to
1458 * detect every case where we don't sample off the edge, just the
1459 * simplest case where there is no transform on the source
1460 * picture.
1461 */
1462 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)
&&
1463 PICT_FORMAT_A(pSrc->format)(((pSrc->format) >> 12) & 0x0f) == 0 &&
1464 (pSrc->repeatType != RepeatNone0 ||
1465 (!pSrc->transform &&
1466 xSrc >= 0 && ySrc >= 0 &&
1467 xSrc + width <= pSrc->pDrawable->width &&
1468 ySrc + height <= pSrc->pDrawable->height)) &&
1469 pSrc->alphaMap == NULL((void*)0) && pMask == NULL((void*)0);
1470 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)
&&
1471 PICT_FORMAT_A(pDst->format)(((pDst->format) >> 12) & 0x0f) == 0 && pDst->alphaMap == NULL((void*)0);
1472
1473 /* TODO, maybe: Conjoint and Disjoint op reductions? */
1474
1475 /* Deal with simplifications where the source alpha is always 1. */
1476 if (no_src_alpha) {
1477 switch (op) {
1478 case PictOpOver3:
1479 op = PictOpSrc1;
1480 break;
1481 case PictOpInReverse6:
1482 op = PictOpDst2;
1483 break;
1484 case PictOpOutReverse8:
1485 op = PictOpClear0;
1486 break;
1487 case PictOpAtop9:
1488 op = PictOpIn5;
1489 break;
1490 case PictOpAtopReverse10:
1491 op = PictOpOverReverse4;
1492 break;
1493 case PictOpXor11:
1494 op = PictOpOut7;
1495 break;
1496 default:
1497 break;
1498 }
1499 }
1500
1501 /* Deal with simplifications when the destination alpha is always 1 */
1502 if (no_dst_alpha) {
1503 switch (op) {
1504 case PictOpOverReverse4:
1505 op = PictOpDst2;
1506 break;
1507 case PictOpIn5:
1508 op = PictOpSrc1;
1509 break;
1510 case PictOpOut7:
1511 op = PictOpClear0;
1512 break;
1513 case PictOpAtop9:
1514 op = PictOpOver3;
1515 break;
1516 case PictOpXor11:
1517 op = PictOpOutReverse8;
1518 break;
1519 default:
1520 break;
1521 }
1522 }
1523
1524 /* Reduce some con/disjoint ops to the basic names. */
1525 switch (op) {
1526 case PictOpDisjointClear0x10:
1527 case PictOpConjointClear0x20:
1528 op = PictOpClear0;
1529 break;
1530 case PictOpDisjointSrc0x11:
1531 case PictOpConjointSrc0x21:
1532 op = PictOpSrc1;
1533 break;
1534 case PictOpDisjointDst0x12:
1535 case PictOpConjointDst0x22:
1536 op = PictOpDst2;
1537 break;
1538 default:
1539 break;
1540 }
1541
1542 return op;
1543}
1544
1545void
1546CompositePicture(CARD8 op,
1547 PicturePtr pSrc,
1548 PicturePtr pMask,
1549 PicturePtr pDst,
1550 INT16 xSrc,
1551 INT16 ySrc,
1552 INT16 xMask,
1553 INT16 yMask,
1554 INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
1555{
1556 PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDst->pDrawable->
pScreen)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
1557
1558 ValidatePicture(pSrc);
1559 if (pMask)
1560 ValidatePicture(pMask);
1561 ValidatePicture(pDst);
1562
1563 op = ReduceCompositeOp(op, pSrc, pMask, pDst, xSrc, ySrc, width, height);
1564 if (op == PictOpDst2)
1565 return;
1566
1567 (*ps->Composite) (op,
1568 pSrc,
1569 pMask,
1570 pDst,
1571 xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
1572}
1573
1574void
1575CompositeRects(CARD8 op,
1576 PicturePtr pDst,
1577 xRenderColor * color, int nRect, xRectangle *rects)
1578{
1579 PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDst->pDrawable->
pScreen)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
1580
1581 ValidatePicture(pDst);
1582 (*ps->CompositeRects) (op, pDst, color, nRect, rects);
1583}
1584
1585void
1586CompositeTrapezoids(CARD8 op,
1587 PicturePtr pSrc,
1588 PicturePtr pDst,
1589 PictFormatPtr maskFormat,
1590 INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps)
1591{
1592 PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDst->pDrawable->
pScreen)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
1593
1594 ValidatePicture(pSrc);
1595 ValidatePicture(pDst);
1596 (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
1597}
1598
1599void
1600CompositeTriangles(CARD8 op,
1601 PicturePtr pSrc,
1602 PicturePtr pDst,
1603 PictFormatPtr maskFormat,
1604 INT16 xSrc,
1605 INT16 ySrc, int ntriangles, xTriangle * triangles)
1606{
1607 PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDst->pDrawable->
pScreen)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
1608
1609 ValidatePicture(pSrc);
1610 ValidatePicture(pDst);
1611 (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles,
1612 triangles);
1613}
1614
1615void
1616CompositeTriStrip(CARD8 op,
1617 PicturePtr pSrc,
1618 PicturePtr pDst,
1619 PictFormatPtr maskFormat,
1620 INT16 xSrc, INT16 ySrc, int npoints, xPointFixed * points)
1621{
1622 PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDst->pDrawable->
pScreen)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
1623
1624 if (npoints < 3)
1625 return;
1626
1627 ValidatePicture(pSrc);
1628 ValidatePicture(pDst);
1629 (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
1630}
1631
1632void
1633CompositeTriFan(CARD8 op,
1634 PicturePtr pSrc,
1635 PicturePtr pDst,
1636 PictFormatPtr maskFormat,
1637 INT16 xSrc, INT16 ySrc, int npoints, xPointFixed * points)
1638{
1639 PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pDst->pDrawable->
pScreen)->devPrivates, (&PictureScreenPrivateKeyRec)))
;
1640
1641 if (npoints < 3)
1642 return;
1643
1644 ValidatePicture(pSrc);
1645 ValidatePicture(pDst);
1646 (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
1647}
1648
1649void
1650AddTraps(PicturePtr pPicture, INT16 xOff, INT16 yOff, int ntrap, xTrap * traps)
1651{
1652 PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen)((PictureScreenPtr)dixLookupPrivate(&(pPicture->pDrawable
->pScreen)->devPrivates, (&PictureScreenPrivateKeyRec
)))
;
1653
1654 ValidatePicture(pPicture);
1655 (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
1656}