Bug Summary

File:mi/micmap.c
Location:line 503, column 32
Description:Dereference of null pointer (loaded from variable 'vid')

Annotated Source Code

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
42DevPrivateKeyRec micmapScrPrivateKeyRec;
43
44int
45miListInstalledColormaps(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
54void
55miInstallColormap(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
71void
72miUninstallColormap(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
86void
87miResolveColor(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
106Bool
107miInitializeColormap(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
185int
186miExpandDirectColors(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
235Bool
236miCreateDefColormap(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
290typedef 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
300static int miVisualPriority[] = {
301 PseudoColor3, GrayScale1, StaticColor2, TrueColor4, DirectColor5, StaticGray0
302};
303
304#define NUM_PRIORITY6 6
305
306static miVisualsPtr miVisuals;
307
308void
309miClearVisualTypes(void)
310{
311 miVisualsPtr v;
312
313 while ((v = miVisuals)) {
314 miVisuals = v->next;
315 free(v);
316 }
317}
318
319Bool
320miSetVisualTypesAndMasks(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
352Bool
353miSetVisualTypes(int depth, int visuals, int bitsPerRGB, int preferredCVC)
354{
355 return miSetVisualTypesAndMasks(depth, visuals, bitsPerRGB,
356 preferredCVC, 0, 0, 0);
357}
358
359int
360miGetDefaultVisualMask(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
372static Bool
373miVisualTypesSet(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
383Bool
384miSetPixmapDepths(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 */
402static int
403maskShift(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
423Bool
424miInitVisuals(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) {
1
Assuming 'miVisuals' is non-null
2
Taking false branch
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) {
3
Loop condition is true. Entering loop body
4
Loop condition is false. Execution continues on line 461
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) {
5
Assuming 'depth' is non-null
6
Assuming 'visual' is non-null
7
Assuming 'preferredCVCs' is non-null
8
Taking false branch
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) {
9
Loop condition is true. Entering loop body
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);
10
Null pointer value stored to 'vid'
483 if (nvtype) {
11
Assuming 'nvtype' is 0
12
Taking false branch
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++) {
13
Loop condition is true. Entering loop body
497 if (!(vtype & (1 << miVisualPriority[i])))
14
Taking false branch
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);
15
Dereference of null pointer (loaded from variable 'vid')
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}