| 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 = malloc(ndepth * sizeof(DepthRec)); | |||
| 462 | visual = malloc(nvisual * sizeof(VisualRec)); | |||
| 463 | preferredCVCs = malloc(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 = malloc(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 | } |