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