1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (c) 1987, Oracle and/or its affiliates. All rights reserved.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"),
6*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation
7*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the
9*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions:
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * The above copyright notice and this permission notice (including the next
12*4882a593Smuzhiyun * paragraph) shall be included in all copies or substantial portions of the
13*4882a593Smuzhiyun * Software.
14*4882a593Smuzhiyun *
15*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*4882a593Smuzhiyun * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*4882a593Smuzhiyun * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*4882a593Smuzhiyun * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*4882a593Smuzhiyun * DEALINGS IN THE SOFTWARE.
22*4882a593Smuzhiyun */
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun /*
25*4882a593Smuzhiyun * This is based on cfbcmap.c. The functions here are useful independently
26*4882a593Smuzhiyun * of cfb, which is the reason for including them here. How "mi" these
27*4882a593Smuzhiyun * are may be debatable.
28*4882a593Smuzhiyun */
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
31*4882a593Smuzhiyun #include <dix-config.h>
32*4882a593Smuzhiyun #endif
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #include <X11/X.h>
35*4882a593Smuzhiyun #include <X11/Xproto.h>
36*4882a593Smuzhiyun #include "scrnintstr.h"
37*4882a593Smuzhiyun #include "colormapst.h"
38*4882a593Smuzhiyun #include "resource.h"
39*4882a593Smuzhiyun #include "globals.h"
40*4882a593Smuzhiyun #include "micmap.h"
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun DevPrivateKeyRec micmapScrPrivateKeyRec;
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun int
miListInstalledColormaps(ScreenPtr pScreen,Colormap * pmaps)45*4882a593Smuzhiyun miListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun if (GetInstalledmiColormap(pScreen)) {
48*4882a593Smuzhiyun *pmaps = GetInstalledmiColormap(pScreen)->mid;
49*4882a593Smuzhiyun return 1;
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun return 0;
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun void
miInstallColormap(ColormapPtr pmap)55*4882a593Smuzhiyun miInstallColormap(ColormapPtr pmap)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun ColormapPtr oldpmap = GetInstalledmiColormap(pmap->pScreen);
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun if (pmap != oldpmap) {
60*4882a593Smuzhiyun /* Uninstall pInstalledMap. No hardware changes required, just
61*4882a593Smuzhiyun * notify all interested parties. */
62*4882a593Smuzhiyun if (oldpmap != (ColormapPtr) None)
63*4882a593Smuzhiyun WalkTree(pmap->pScreen, TellLostMap, (char *) &oldpmap->mid);
64*4882a593Smuzhiyun /* Install pmap */
65*4882a593Smuzhiyun SetInstalledmiColormap(pmap->pScreen, pmap);
66*4882a593Smuzhiyun WalkTree(pmap->pScreen, TellGainedMap, (char *) &pmap->mid);
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun void
miUninstallColormap(ColormapPtr pmap)72*4882a593Smuzhiyun miUninstallColormap(ColormapPtr pmap)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun ColormapPtr curpmap = GetInstalledmiColormap(pmap->pScreen);
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun if (pmap == curpmap) {
77*4882a593Smuzhiyun if (pmap->mid != pmap->pScreen->defColormap) {
78*4882a593Smuzhiyun dixLookupResourceByType((void **) &curpmap,
79*4882a593Smuzhiyun pmap->pScreen->defColormap,
80*4882a593Smuzhiyun RT_COLORMAP, serverClient, DixUseAccess);
81*4882a593Smuzhiyun (*pmap->pScreen->InstallColormap) (curpmap);
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun void
miResolveColor(unsigned short * pred,unsigned short * pgreen,unsigned short * pblue,VisualPtr pVisual)87*4882a593Smuzhiyun miResolveColor(unsigned short *pred, unsigned short *pgreen,
88*4882a593Smuzhiyun unsigned short *pblue, VisualPtr pVisual)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun int shift = 16 - pVisual->bitsPerRGBValue;
91*4882a593Smuzhiyun unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun if ((pVisual->class | DynamicClass) == GrayScale) {
94*4882a593Smuzhiyun /* rescale to gray then rgb bits */
95*4882a593Smuzhiyun *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
96*4882a593Smuzhiyun *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun else {
99*4882a593Smuzhiyun /* rescale to rgb bits */
100*4882a593Smuzhiyun *pred = ((*pred >> shift) * 65535) / lim;
101*4882a593Smuzhiyun *pgreen = ((*pgreen >> shift) * 65535) / lim;
102*4882a593Smuzhiyun *pblue = ((*pblue >> shift) * 65535) / lim;
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun Bool
miInitializeColormap(ColormapPtr pmap)107*4882a593Smuzhiyun miInitializeColormap(ColormapPtr pmap)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun unsigned i;
110*4882a593Smuzhiyun VisualPtr pVisual;
111*4882a593Smuzhiyun unsigned lim, maxent, shift;
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun pVisual = pmap->pVisual;
114*4882a593Smuzhiyun lim = (1 << pVisual->bitsPerRGBValue) - 1;
115*4882a593Smuzhiyun shift = 16 - pVisual->bitsPerRGBValue;
116*4882a593Smuzhiyun maxent = pVisual->ColormapEntries - 1;
117*4882a593Smuzhiyun if (pVisual->class == TrueColor) {
118*4882a593Smuzhiyun unsigned limr, limg, limb;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun limr = pVisual->redMask >> pVisual->offsetRed;
121*4882a593Smuzhiyun limg = pVisual->greenMask >> pVisual->offsetGreen;
122*4882a593Smuzhiyun limb = pVisual->blueMask >> pVisual->offsetBlue;
123*4882a593Smuzhiyun for (i = 0; i <= maxent; i++) {
124*4882a593Smuzhiyun /* rescale to [0..65535] then rgb bits */
125*4882a593Smuzhiyun pmap->red[i].co.local.red =
126*4882a593Smuzhiyun ((((i * 65535) / limr) >> shift) * 65535) / lim;
127*4882a593Smuzhiyun pmap->green[i].co.local.green =
128*4882a593Smuzhiyun ((((i * 65535) / limg) >> shift) * 65535) / lim;
129*4882a593Smuzhiyun pmap->blue[i].co.local.blue =
130*4882a593Smuzhiyun ((((i * 65535) / limb) >> shift) * 65535) / lim;
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun else if (pVisual->class == StaticColor) {
134*4882a593Smuzhiyun unsigned limr, limg, limb;
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun limr = pVisual->redMask >> pVisual->offsetRed;
137*4882a593Smuzhiyun limg = pVisual->greenMask >> pVisual->offsetGreen;
138*4882a593Smuzhiyun limb = pVisual->blueMask >> pVisual->offsetBlue;
139*4882a593Smuzhiyun for (i = 0; i <= maxent; i++) {
140*4882a593Smuzhiyun /* rescale to [0..65535] then rgb bits */
141*4882a593Smuzhiyun pmap->red[i].co.local.red =
142*4882a593Smuzhiyun ((((((i & pVisual->redMask) >> pVisual->offsetRed)
143*4882a593Smuzhiyun * 65535) / limr) >> shift) * 65535) / lim;
144*4882a593Smuzhiyun pmap->red[i].co.local.green =
145*4882a593Smuzhiyun ((((((i & pVisual->greenMask) >> pVisual->offsetGreen)
146*4882a593Smuzhiyun * 65535) / limg) >> shift) * 65535) / lim;
147*4882a593Smuzhiyun pmap->red[i].co.local.blue =
148*4882a593Smuzhiyun ((((((i & pVisual->blueMask) >> pVisual->offsetBlue)
149*4882a593Smuzhiyun * 65535) / limb) >> shift) * 65535) / lim;
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun else if (pVisual->class == StaticGray) {
153*4882a593Smuzhiyun for (i = 0; i <= maxent; i++) {
154*4882a593Smuzhiyun /* rescale to [0..65535] then rgb bits */
155*4882a593Smuzhiyun pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift)
156*4882a593Smuzhiyun * 65535) / lim;
157*4882a593Smuzhiyun pmap->red[i].co.local.green = pmap->red[i].co.local.red;
158*4882a593Smuzhiyun pmap->red[i].co.local.blue = pmap->red[i].co.local.red;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun return TRUE;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun /* When simulating DirectColor on PseudoColor hardware, multiple
165*4882a593Smuzhiyun entries of the colormap must be updated
166*4882a593Smuzhiyun */
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun #define AddElement(mask) { \
169*4882a593Smuzhiyun pixel = red | green | blue; \
170*4882a593Smuzhiyun for (i = 0; i < nresult; i++) \
171*4882a593Smuzhiyun if (outdefs[i].pixel == pixel) \
172*4882a593Smuzhiyun break; \
173*4882a593Smuzhiyun if (i == nresult) \
174*4882a593Smuzhiyun { \
175*4882a593Smuzhiyun nresult++; \
176*4882a593Smuzhiyun outdefs[i].pixel = pixel; \
177*4882a593Smuzhiyun outdefs[i].flags = 0; \
178*4882a593Smuzhiyun } \
179*4882a593Smuzhiyun outdefs[i].flags |= (mask); \
180*4882a593Smuzhiyun outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \
181*4882a593Smuzhiyun outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \
182*4882a593Smuzhiyun outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun int
miExpandDirectColors(ColormapPtr pmap,int ndef,xColorItem * indefs,xColorItem * outdefs)186*4882a593Smuzhiyun miExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem * indefs,
187*4882a593Smuzhiyun xColorItem * outdefs)
188*4882a593Smuzhiyun {
189*4882a593Smuzhiyun int red, green, blue;
190*4882a593Smuzhiyun int maxred, maxgreen, maxblue;
191*4882a593Smuzhiyun int stepred, stepgreen, stepblue;
192*4882a593Smuzhiyun VisualPtr pVisual;
193*4882a593Smuzhiyun int pixel;
194*4882a593Smuzhiyun int nresult;
195*4882a593Smuzhiyun int i;
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun pVisual = pmap->pVisual;
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun stepred = 1 << pVisual->offsetRed;
200*4882a593Smuzhiyun stepgreen = 1 << pVisual->offsetGreen;
201*4882a593Smuzhiyun stepblue = 1 << pVisual->offsetBlue;
202*4882a593Smuzhiyun maxred = pVisual->redMask;
203*4882a593Smuzhiyun maxgreen = pVisual->greenMask;
204*4882a593Smuzhiyun maxblue = pVisual->blueMask;
205*4882a593Smuzhiyun nresult = 0;
206*4882a593Smuzhiyun for (; ndef--; indefs++) {
207*4882a593Smuzhiyun if (indefs->flags & DoRed) {
208*4882a593Smuzhiyun red = indefs->pixel & pVisual->redMask;
209*4882a593Smuzhiyun for (green = 0; green <= maxgreen; green += stepgreen) {
210*4882a593Smuzhiyun for (blue = 0; blue <= maxblue; blue += stepblue) {
211*4882a593Smuzhiyun AddElement(DoRed)
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun if (indefs->flags & DoGreen) {
216*4882a593Smuzhiyun green = indefs->pixel & pVisual->greenMask;
217*4882a593Smuzhiyun for (red = 0; red <= maxred; red += stepred) {
218*4882a593Smuzhiyun for (blue = 0; blue <= maxblue; blue += stepblue) {
219*4882a593Smuzhiyun AddElement(DoGreen)
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun if (indefs->flags & DoBlue) {
224*4882a593Smuzhiyun blue = indefs->pixel & pVisual->blueMask;
225*4882a593Smuzhiyun for (red = 0; red <= maxred; red += stepred) {
226*4882a593Smuzhiyun for (green = 0; green <= maxgreen; green += stepgreen) {
227*4882a593Smuzhiyun AddElement(DoBlue)
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun return nresult;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun Bool
miCreateDefColormap(ScreenPtr pScreen)236*4882a593Smuzhiyun miCreateDefColormap(ScreenPtr pScreen)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun unsigned short zero = 0, ones = 0xFFFF;
239*4882a593Smuzhiyun Pixel wp, bp;
240*4882a593Smuzhiyun VisualPtr pVisual;
241*4882a593Smuzhiyun ColormapPtr cmap;
242*4882a593Smuzhiyun int alloctype;
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&micmapScrPrivateKeyRec, PRIVATE_SCREEN, 0))
245*4882a593Smuzhiyun return FALSE;
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun for (pVisual = pScreen->visuals;
248*4882a593Smuzhiyun pVisual->vid != pScreen->rootVisual; pVisual++);
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun if (pScreen->rootDepth == 1 || (pVisual->class & DynamicClass))
251*4882a593Smuzhiyun alloctype = AllocNone;
252*4882a593Smuzhiyun else
253*4882a593Smuzhiyun alloctype = AllocAll;
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap,
256*4882a593Smuzhiyun alloctype, 0) != Success)
257*4882a593Smuzhiyun return FALSE;
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun if (pScreen->rootDepth > 1) {
260*4882a593Smuzhiyun wp = pScreen->whitePixel;
261*4882a593Smuzhiyun bp = pScreen->blackPixel;
262*4882a593Smuzhiyun if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) !=
263*4882a593Smuzhiyun Success) ||
264*4882a593Smuzhiyun (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) != Success))
265*4882a593Smuzhiyun return FALSE;
266*4882a593Smuzhiyun pScreen->whitePixel = wp;
267*4882a593Smuzhiyun pScreen->blackPixel = bp;
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun (*pScreen->InstallColormap) (cmap);
271*4882a593Smuzhiyun return TRUE;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun /*
275*4882a593Smuzhiyun * Default true color bitmasks, should be overridden by
276*4882a593Smuzhiyun * driver
277*4882a593Smuzhiyun */
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun #define _RZ(d) ((d + 2) / 3)
280*4882a593Smuzhiyun #define _RS(d) 0
281*4882a593Smuzhiyun #define _RM(d) ((1 << _RZ(d)) - 1)
282*4882a593Smuzhiyun #define _GZ(d) ((d - _RZ(d) + 1) / 2)
283*4882a593Smuzhiyun #define _GS(d) _RZ(d)
284*4882a593Smuzhiyun #define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d))
285*4882a593Smuzhiyun #define _BZ(d) (d - _RZ(d) - _GZ(d))
286*4882a593Smuzhiyun #define _BS(d) (_RZ(d) + _GZ(d))
287*4882a593Smuzhiyun #define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d))
288*4882a593Smuzhiyun #define _CE(d) (1 << _RZ(d))
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun typedef struct _miVisuals {
291*4882a593Smuzhiyun struct _miVisuals *next;
292*4882a593Smuzhiyun int depth;
293*4882a593Smuzhiyun int bitsPerRGB;
294*4882a593Smuzhiyun int visuals;
295*4882a593Smuzhiyun int count;
296*4882a593Smuzhiyun int preferredCVC;
297*4882a593Smuzhiyun Pixel redMask, greenMask, blueMask;
298*4882a593Smuzhiyun } miVisualsRec, *miVisualsPtr;
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun static int miVisualPriority[] = {
301*4882a593Smuzhiyun PseudoColor, GrayScale, StaticColor, TrueColor, DirectColor, StaticGray
302*4882a593Smuzhiyun };
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun #define NUM_PRIORITY 6
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun static miVisualsPtr miVisuals;
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun void
miClearVisualTypes(void)309*4882a593Smuzhiyun miClearVisualTypes(void)
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun miVisualsPtr v;
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun while ((v = miVisuals)) {
314*4882a593Smuzhiyun miVisuals = v->next;
315*4882a593Smuzhiyun free(v);
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun Bool
miSetVisualTypesAndMasks(int depth,int visuals,int bitsPerRGB,int preferredCVC,Pixel redMask,Pixel greenMask,Pixel blueMask)320*4882a593Smuzhiyun miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB,
321*4882a593Smuzhiyun int preferredCVC,
322*4882a593Smuzhiyun Pixel redMask, Pixel greenMask, Pixel blueMask)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun miVisualsPtr new, *prev, v;
325*4882a593Smuzhiyun int count;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun new = malloc(sizeof *new);
328*4882a593Smuzhiyun if (!new)
329*4882a593Smuzhiyun return FALSE;
330*4882a593Smuzhiyun if (!redMask || !greenMask || !blueMask) {
331*4882a593Smuzhiyun redMask = _RM(depth);
332*4882a593Smuzhiyun greenMask = _GM(depth);
333*4882a593Smuzhiyun blueMask = _BM(depth);
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun new->next = 0;
336*4882a593Smuzhiyun new->depth = depth;
337*4882a593Smuzhiyun new->visuals = visuals;
338*4882a593Smuzhiyun new->bitsPerRGB = bitsPerRGB;
339*4882a593Smuzhiyun new->preferredCVC = preferredCVC;
340*4882a593Smuzhiyun new->redMask = redMask;
341*4882a593Smuzhiyun new->greenMask = greenMask;
342*4882a593Smuzhiyun new->blueMask = blueMask;
343*4882a593Smuzhiyun count = (visuals >> 1) & 033333333333;
344*4882a593Smuzhiyun count = visuals - count - ((count >> 1) & 033333333333);
345*4882a593Smuzhiyun count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */
346*4882a593Smuzhiyun new->count = count;
347*4882a593Smuzhiyun for (prev = &miVisuals; (v = *prev); prev = &v->next);
348*4882a593Smuzhiyun *prev = new;
349*4882a593Smuzhiyun return TRUE;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun Bool
miSetVisualTypes(int depth,int visuals,int bitsPerRGB,int preferredCVC)353*4882a593Smuzhiyun miSetVisualTypes(int depth, int visuals, int bitsPerRGB, int preferredCVC)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun return miSetVisualTypesAndMasks(depth, visuals, bitsPerRGB,
356*4882a593Smuzhiyun preferredCVC, 0, 0, 0);
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun int
miGetDefaultVisualMask(int depth)360*4882a593Smuzhiyun miGetDefaultVisualMask(int depth)
361*4882a593Smuzhiyun {
362*4882a593Smuzhiyun if (depth > MAX_PSEUDO_DEPTH)
363*4882a593Smuzhiyun return LARGE_VISUALS;
364*4882a593Smuzhiyun else if (depth >= MIN_TRUE_DEPTH)
365*4882a593Smuzhiyun return ALL_VISUALS;
366*4882a593Smuzhiyun else if (depth == 1)
367*4882a593Smuzhiyun return StaticGrayMask;
368*4882a593Smuzhiyun else
369*4882a593Smuzhiyun return SMALL_VISUALS;
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun static Bool
miVisualTypesSet(int depth)373*4882a593Smuzhiyun miVisualTypesSet(int depth)
374*4882a593Smuzhiyun {
375*4882a593Smuzhiyun miVisualsPtr visuals;
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun for (visuals = miVisuals; visuals; visuals = visuals->next)
378*4882a593Smuzhiyun if (visuals->depth == depth)
379*4882a593Smuzhiyun return TRUE;
380*4882a593Smuzhiyun return FALSE;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun Bool
miSetPixmapDepths(void)384*4882a593Smuzhiyun miSetPixmapDepths(void)
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun int d, f;
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun /* Add any unlisted depths from the pixmap formats */
389*4882a593Smuzhiyun for (f = 0; f < screenInfo.numPixmapFormats; f++) {
390*4882a593Smuzhiyun d = screenInfo.formats[f].depth;
391*4882a593Smuzhiyun if (!miVisualTypesSet(d)) {
392*4882a593Smuzhiyun if (!miSetVisualTypes(d, 0, 0, -1))
393*4882a593Smuzhiyun return FALSE;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun return TRUE;
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun /*
400*4882a593Smuzhiyun * Distance to least significant one bit
401*4882a593Smuzhiyun */
402*4882a593Smuzhiyun static int
maskShift(Pixel p)403*4882a593Smuzhiyun maskShift(Pixel p)
404*4882a593Smuzhiyun {
405*4882a593Smuzhiyun int s;
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun if (!p)
408*4882a593Smuzhiyun return 0;
409*4882a593Smuzhiyun s = 0;
410*4882a593Smuzhiyun while (!(p & 1)) {
411*4882a593Smuzhiyun s++;
412*4882a593Smuzhiyun p >>= 1;
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun return s;
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun /*
418*4882a593Smuzhiyun * Given a list of formats for a screen, create a list
419*4882a593Smuzhiyun * of visuals and depths for the screen which corespond to
420*4882a593Smuzhiyun * the set which can be used with this version of cfb.
421*4882a593Smuzhiyun */
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun Bool
miInitVisuals(VisualPtr * visualp,DepthPtr * depthp,int * nvisualp,int * ndepthp,int * rootDepthp,VisualID * defaultVisp,unsigned long sizes,int bitsPerRGB,int preferredVis)424*4882a593Smuzhiyun miInitVisuals(VisualPtr * visualp, DepthPtr * depthp, int *nvisualp,
425*4882a593Smuzhiyun int *ndepthp, int *rootDepthp, VisualID * defaultVisp,
426*4882a593Smuzhiyun unsigned long sizes, int bitsPerRGB, int preferredVis)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun int i, j = 0, k;
429*4882a593Smuzhiyun VisualPtr visual;
430*4882a593Smuzhiyun DepthPtr depth;
431*4882a593Smuzhiyun VisualID *vid;
432*4882a593Smuzhiyun int d, b;
433*4882a593Smuzhiyun int f;
434*4882a593Smuzhiyun int ndepth, nvisual;
435*4882a593Smuzhiyun int nvtype;
436*4882a593Smuzhiyun int vtype;
437*4882a593Smuzhiyun miVisualsPtr visuals, nextVisuals;
438*4882a593Smuzhiyun int *preferredCVCs, *prefp;
439*4882a593Smuzhiyun int first_depth;
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun /* none specified, we'll guess from pixmap formats */
442*4882a593Smuzhiyun if (!miVisuals) {
443*4882a593Smuzhiyun for (f = 0; f < screenInfo.numPixmapFormats; f++) {
444*4882a593Smuzhiyun d = screenInfo.formats[f].depth;
445*4882a593Smuzhiyun b = screenInfo.formats[f].bitsPerPixel;
446*4882a593Smuzhiyun if (sizes & (1 << (b - 1)))
447*4882a593Smuzhiyun vtype = miGetDefaultVisualMask(d);
448*4882a593Smuzhiyun else
449*4882a593Smuzhiyun vtype = 0;
450*4882a593Smuzhiyun if (!miSetVisualTypes(d, vtype, bitsPerRGB, -1))
451*4882a593Smuzhiyun return FALSE;
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun nvisual = 0;
455*4882a593Smuzhiyun ndepth = 0;
456*4882a593Smuzhiyun for (visuals = miVisuals; visuals; visuals = nextVisuals) {
457*4882a593Smuzhiyun nextVisuals = visuals->next;
458*4882a593Smuzhiyun ndepth++;
459*4882a593Smuzhiyun nvisual += visuals->count;
460*4882a593Smuzhiyun }
461*4882a593Smuzhiyun depth = xallocarray(ndepth, sizeof(DepthRec));
462*4882a593Smuzhiyun visual = xallocarray(nvisual, sizeof(VisualRec));
463*4882a593Smuzhiyun preferredCVCs = xallocarray(ndepth, sizeof(int));
464*4882a593Smuzhiyun if (!depth || !visual || !preferredCVCs) {
465*4882a593Smuzhiyun free(depth);
466*4882a593Smuzhiyun free(visual);
467*4882a593Smuzhiyun free(preferredCVCs);
468*4882a593Smuzhiyun return FALSE;
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun *depthp = depth;
471*4882a593Smuzhiyun *visualp = visual;
472*4882a593Smuzhiyun *ndepthp = ndepth;
473*4882a593Smuzhiyun *nvisualp = nvisual;
474*4882a593Smuzhiyun prefp = preferredCVCs;
475*4882a593Smuzhiyun for (visuals = miVisuals; visuals; visuals = nextVisuals) {
476*4882a593Smuzhiyun nextVisuals = visuals->next;
477*4882a593Smuzhiyun d = visuals->depth;
478*4882a593Smuzhiyun vtype = visuals->visuals;
479*4882a593Smuzhiyun nvtype = visuals->count;
480*4882a593Smuzhiyun *prefp = visuals->preferredCVC;
481*4882a593Smuzhiyun prefp++;
482*4882a593Smuzhiyun vid = NULL;
483*4882a593Smuzhiyun if (nvtype) {
484*4882a593Smuzhiyun vid = xallocarray(nvtype, sizeof(VisualID));
485*4882a593Smuzhiyun if (!vid) {
486*4882a593Smuzhiyun free(depth);
487*4882a593Smuzhiyun free(visual);
488*4882a593Smuzhiyun free(preferredCVCs);
489*4882a593Smuzhiyun return FALSE;
490*4882a593Smuzhiyun }
491*4882a593Smuzhiyun }
492*4882a593Smuzhiyun depth->depth = d;
493*4882a593Smuzhiyun depth->numVids = nvtype;
494*4882a593Smuzhiyun depth->vids = vid;
495*4882a593Smuzhiyun depth++;
496*4882a593Smuzhiyun for (i = 0; i < NUM_PRIORITY; i++) {
497*4882a593Smuzhiyun if (!(vtype & (1 << miVisualPriority[i])))
498*4882a593Smuzhiyun continue;
499*4882a593Smuzhiyun visual->class = miVisualPriority[i];
500*4882a593Smuzhiyun visual->bitsPerRGBValue = visuals->bitsPerRGB;
501*4882a593Smuzhiyun visual->ColormapEntries = 1 << d;
502*4882a593Smuzhiyun visual->nplanes = d;
503*4882a593Smuzhiyun visual->vid = *vid = FakeClientID(0);
504*4882a593Smuzhiyun switch (visual->class) {
505*4882a593Smuzhiyun case PseudoColor:
506*4882a593Smuzhiyun case GrayScale:
507*4882a593Smuzhiyun case StaticGray:
508*4882a593Smuzhiyun visual->redMask = 0;
509*4882a593Smuzhiyun visual->greenMask = 0;
510*4882a593Smuzhiyun visual->blueMask = 0;
511*4882a593Smuzhiyun visual->offsetRed = 0;
512*4882a593Smuzhiyun visual->offsetGreen = 0;
513*4882a593Smuzhiyun visual->offsetBlue = 0;
514*4882a593Smuzhiyun break;
515*4882a593Smuzhiyun case DirectColor:
516*4882a593Smuzhiyun case TrueColor:
517*4882a593Smuzhiyun visual->ColormapEntries = _CE(d);
518*4882a593Smuzhiyun /* fall through */
519*4882a593Smuzhiyun case StaticColor:
520*4882a593Smuzhiyun visual->redMask = visuals->redMask;
521*4882a593Smuzhiyun visual->greenMask = visuals->greenMask;
522*4882a593Smuzhiyun visual->blueMask = visuals->blueMask;
523*4882a593Smuzhiyun visual->offsetRed = maskShift(visuals->redMask);
524*4882a593Smuzhiyun visual->offsetGreen = maskShift(visuals->greenMask);
525*4882a593Smuzhiyun visual->offsetBlue = maskShift(visuals->blueMask);
526*4882a593Smuzhiyun }
527*4882a593Smuzhiyun vid++;
528*4882a593Smuzhiyun visual++;
529*4882a593Smuzhiyun }
530*4882a593Smuzhiyun free(visuals);
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun miVisuals = NULL;
533*4882a593Smuzhiyun visual = *visualp;
534*4882a593Smuzhiyun depth = *depthp;
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun /*
537*4882a593Smuzhiyun * if we did not supplyied by a preferred visual class
538*4882a593Smuzhiyun * check if there is a preferred class in one of the depth
539*4882a593Smuzhiyun * structures - if there is, we want to start looking for the
540*4882a593Smuzhiyun * default visual/depth from that depth.
541*4882a593Smuzhiyun */
542*4882a593Smuzhiyun first_depth = 0;
543*4882a593Smuzhiyun if (preferredVis < 0 && defaultColorVisualClass < 0) {
544*4882a593Smuzhiyun for (i = 0; i < ndepth; i++) {
545*4882a593Smuzhiyun if (preferredCVCs[i] >= 0) {
546*4882a593Smuzhiyun first_depth = i;
547*4882a593Smuzhiyun break;
548*4882a593Smuzhiyun }
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun for (i = first_depth; i < ndepth; i++) {
553*4882a593Smuzhiyun int prefColorVisualClass = -1;
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun if (defaultColorVisualClass >= 0)
556*4882a593Smuzhiyun prefColorVisualClass = defaultColorVisualClass;
557*4882a593Smuzhiyun else if (preferredVis >= 0)
558*4882a593Smuzhiyun prefColorVisualClass = preferredVis;
559*4882a593Smuzhiyun else if (preferredCVCs[i] >= 0)
560*4882a593Smuzhiyun prefColorVisualClass = preferredCVCs[i];
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun if (*rootDepthp && *rootDepthp != depth[i].depth)
563*4882a593Smuzhiyun continue;
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun for (j = 0; j < depth[i].numVids; j++) {
566*4882a593Smuzhiyun for (k = 0; k < nvisual; k++)
567*4882a593Smuzhiyun if (visual[k].vid == depth[i].vids[j])
568*4882a593Smuzhiyun break;
569*4882a593Smuzhiyun if (k == nvisual)
570*4882a593Smuzhiyun continue;
571*4882a593Smuzhiyun if (prefColorVisualClass < 0 ||
572*4882a593Smuzhiyun visual[k].class == prefColorVisualClass)
573*4882a593Smuzhiyun break;
574*4882a593Smuzhiyun }
575*4882a593Smuzhiyun if (j != depth[i].numVids)
576*4882a593Smuzhiyun break;
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun if (i == ndepth) {
579*4882a593Smuzhiyun i = 0;
580*4882a593Smuzhiyun j = 0;
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun *rootDepthp = depth[i].depth;
583*4882a593Smuzhiyun *defaultVisp = depth[i].vids[j];
584*4882a593Smuzhiyun free(preferredCVCs);
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun return TRUE;
587*4882a593Smuzhiyun }
588