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