16747b715Smrg/* 29ace9065Smrg * Copyright (c) 1987, Oracle and/or its affiliates. All rights reserved. 36747b715Smrg * 46747b715Smrg * Permission is hereby granted, free of charge, to any person obtaining a 56747b715Smrg * copy of this software and associated documentation files (the "Software"), 66747b715Smrg * to deal in the Software without restriction, including without limitation 76747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 86747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the 96747b715Smrg * Software is furnished to do so, subject to the following conditions: 106747b715Smrg * 116747b715Smrg * The above copyright notice and this permission notice (including the next 126747b715Smrg * paragraph) shall be included in all copies or substantial portions of the 136747b715Smrg * Software. 146747b715Smrg * 156747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 166747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 176747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 186747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 196747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 206747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 216747b715Smrg * DEALINGS IN THE SOFTWARE. 226747b715Smrg */ 2305b261ecSmrg 2405b261ecSmrg/* 2505b261ecSmrg * This is based on cfbcmap.c. The functions here are useful independently 2605b261ecSmrg * of cfb, which is the reason for including them here. How "mi" these 2705b261ecSmrg * are may be debatable. 2805b261ecSmrg */ 2905b261ecSmrg 3005b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 3105b261ecSmrg#include <dix-config.h> 3205b261ecSmrg#endif 3305b261ecSmrg 3405b261ecSmrg#include <X11/X.h> 3505b261ecSmrg#include <X11/Xproto.h> 3605b261ecSmrg#include "scrnintstr.h" 3705b261ecSmrg#include "colormapst.h" 3805b261ecSmrg#include "resource.h" 3905b261ecSmrg#include "globals.h" 4005b261ecSmrg#include "micmap.h" 4105b261ecSmrg 426747b715SmrgDevPrivateKeyRec micmapScrPrivateKeyRec; 4305b261ecSmrg 446747b715Smrgint 4535c4bbdfSmrgmiListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps) 4605b261ecSmrg{ 476747b715Smrg if (GetInstalledmiColormap(pScreen)) { 4835c4bbdfSmrg *pmaps = GetInstalledmiColormap(pScreen)->mid; 4935c4bbdfSmrg return 1; 5005b261ecSmrg } 5105b261ecSmrg return 0; 5205b261ecSmrg} 5305b261ecSmrg 546747b715Smrgvoid 5505b261ecSmrgmiInstallColormap(ColormapPtr pmap) 5605b261ecSmrg{ 576747b715Smrg ColormapPtr oldpmap = GetInstalledmiColormap(pmap->pScreen); 5805b261ecSmrg 5935c4bbdfSmrg if (pmap != oldpmap) { 6035c4bbdfSmrg /* Uninstall pInstalledMap. No hardware changes required, just 6135c4bbdfSmrg * notify all interested parties. */ 6235c4bbdfSmrg if (oldpmap != (ColormapPtr) None) 6335c4bbdfSmrg WalkTree(pmap->pScreen, TellLostMap, (char *) &oldpmap->mid); 6435c4bbdfSmrg /* Install pmap */ 6535c4bbdfSmrg SetInstalledmiColormap(pmap->pScreen, pmap); 6635c4bbdfSmrg WalkTree(pmap->pScreen, TellGainedMap, (char *) &pmap->mid); 6705b261ecSmrg 6805b261ecSmrg } 6905b261ecSmrg} 7005b261ecSmrg 716747b715Smrgvoid 7205b261ecSmrgmiUninstallColormap(ColormapPtr pmap) 7305b261ecSmrg{ 746747b715Smrg ColormapPtr curpmap = GetInstalledmiColormap(pmap->pScreen); 7505b261ecSmrg 7635c4bbdfSmrg if (pmap == curpmap) { 7735c4bbdfSmrg if (pmap->mid != pmap->pScreen->defColormap) { 7835c4bbdfSmrg dixLookupResourceByType((void **) &curpmap, 7935c4bbdfSmrg pmap->pScreen->defColormap, 8035c4bbdfSmrg RT_COLORMAP, serverClient, DixUseAccess); 8135c4bbdfSmrg (*pmap->pScreen->InstallColormap) (curpmap); 8235c4bbdfSmrg } 8305b261ecSmrg } 8405b261ecSmrg} 8505b261ecSmrg 866747b715Smrgvoid 8705b261ecSmrgmiResolveColor(unsigned short *pred, unsigned short *pgreen, 8835c4bbdfSmrg unsigned short *pblue, VisualPtr pVisual) 8905b261ecSmrg{ 9005b261ecSmrg int shift = 16 - pVisual->bitsPerRGBValue; 9105b261ecSmrg unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1; 9205b261ecSmrg 9335c4bbdfSmrg if ((pVisual->class | DynamicClass) == GrayScale) { 9435c4bbdfSmrg /* rescale to gray then rgb bits */ 9535c4bbdfSmrg *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100; 9635c4bbdfSmrg *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim; 9705b261ecSmrg } 9835c4bbdfSmrg else { 9935c4bbdfSmrg /* rescale to rgb bits */ 10035c4bbdfSmrg *pred = ((*pred >> shift) * 65535) / lim; 10135c4bbdfSmrg *pgreen = ((*pgreen >> shift) * 65535) / lim; 10235c4bbdfSmrg *pblue = ((*pblue >> shift) * 65535) / lim; 10305b261ecSmrg } 10405b261ecSmrg} 10505b261ecSmrg 1066747b715SmrgBool 10705b261ecSmrgmiInitializeColormap(ColormapPtr pmap) 10805b261ecSmrg{ 10905b261ecSmrg unsigned i; 11005b261ecSmrg VisualPtr pVisual; 11105b261ecSmrg unsigned lim, maxent, shift; 11205b261ecSmrg 11305b261ecSmrg pVisual = pmap->pVisual; 11405b261ecSmrg lim = (1 << pVisual->bitsPerRGBValue) - 1; 11505b261ecSmrg shift = 16 - pVisual->bitsPerRGBValue; 11605b261ecSmrg maxent = pVisual->ColormapEntries - 1; 11735c4bbdfSmrg if (pVisual->class == TrueColor) { 11835c4bbdfSmrg unsigned limr, limg, limb; 11935c4bbdfSmrg 12035c4bbdfSmrg limr = pVisual->redMask >> pVisual->offsetRed; 12135c4bbdfSmrg limg = pVisual->greenMask >> pVisual->offsetGreen; 12235c4bbdfSmrg limb = pVisual->blueMask >> pVisual->offsetBlue; 12335c4bbdfSmrg for (i = 0; i <= maxent; i++) { 12435c4bbdfSmrg /* rescale to [0..65535] then rgb bits */ 12535c4bbdfSmrg pmap->red[i].co.local.red = 12635c4bbdfSmrg ((((i * 65535) / limr) >> shift) * 65535) / lim; 12735c4bbdfSmrg pmap->green[i].co.local.green = 12835c4bbdfSmrg ((((i * 65535) / limg) >> shift) * 65535) / lim; 12935c4bbdfSmrg pmap->blue[i].co.local.blue = 13035c4bbdfSmrg ((((i * 65535) / limb) >> shift) * 65535) / lim; 13135c4bbdfSmrg } 13205b261ecSmrg } 13335c4bbdfSmrg else if (pVisual->class == StaticColor) { 13435c4bbdfSmrg unsigned limr, limg, limb; 13535c4bbdfSmrg 13635c4bbdfSmrg limr = pVisual->redMask >> pVisual->offsetRed; 13735c4bbdfSmrg limg = pVisual->greenMask >> pVisual->offsetGreen; 13835c4bbdfSmrg limb = pVisual->blueMask >> pVisual->offsetBlue; 13935c4bbdfSmrg for (i = 0; i <= maxent; i++) { 14035c4bbdfSmrg /* rescale to [0..65535] then rgb bits */ 14135c4bbdfSmrg pmap->red[i].co.local.red = 14235c4bbdfSmrg ((((((i & pVisual->redMask) >> pVisual->offsetRed) 14335c4bbdfSmrg * 65535) / limr) >> shift) * 65535) / lim; 14435c4bbdfSmrg pmap->red[i].co.local.green = 14535c4bbdfSmrg ((((((i & pVisual->greenMask) >> pVisual->offsetGreen) 14635c4bbdfSmrg * 65535) / limg) >> shift) * 65535) / lim; 14735c4bbdfSmrg pmap->red[i].co.local.blue = 14835c4bbdfSmrg ((((((i & pVisual->blueMask) >> pVisual->offsetBlue) 14935c4bbdfSmrg * 65535) / limb) >> shift) * 65535) / lim; 15035c4bbdfSmrg } 15105b261ecSmrg } 15235c4bbdfSmrg else if (pVisual->class == StaticGray) { 15335c4bbdfSmrg for (i = 0; i <= maxent; i++) { 15435c4bbdfSmrg /* rescale to [0..65535] then rgb bits */ 15535c4bbdfSmrg pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift) 15635c4bbdfSmrg * 65535) / lim; 15735c4bbdfSmrg pmap->red[i].co.local.green = pmap->red[i].co.local.red; 15835c4bbdfSmrg pmap->red[i].co.local.blue = pmap->red[i].co.local.red; 15935c4bbdfSmrg } 16005b261ecSmrg } 16105b261ecSmrg return TRUE; 16205b261ecSmrg} 16305b261ecSmrg 16405b261ecSmrg/* When simulating DirectColor on PseudoColor hardware, multiple 16505b261ecSmrg entries of the colormap must be updated 16605b261ecSmrg */ 16705b261ecSmrg 16805b261ecSmrg#define AddElement(mask) { \ 16905b261ecSmrg pixel = red | green | blue; \ 17005b261ecSmrg for (i = 0; i < nresult; i++) \ 17105b261ecSmrg if (outdefs[i].pixel == pixel) \ 17205b261ecSmrg break; \ 17305b261ecSmrg if (i == nresult) \ 17405b261ecSmrg { \ 17505b261ecSmrg nresult++; \ 17605b261ecSmrg outdefs[i].pixel = pixel; \ 17705b261ecSmrg outdefs[i].flags = 0; \ 17805b261ecSmrg } \ 17905b261ecSmrg outdefs[i].flags |= (mask); \ 18005b261ecSmrg outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \ 18105b261ecSmrg outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \ 18205b261ecSmrg outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \ 18305b261ecSmrg} 18405b261ecSmrg 1856747b715Smrgint 18635c4bbdfSmrgmiExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem * indefs, 18735c4bbdfSmrg xColorItem * outdefs) 18805b261ecSmrg{ 18935c4bbdfSmrg int red, green, blue; 19035c4bbdfSmrg int maxred, maxgreen, maxblue; 19135c4bbdfSmrg int stepred, stepgreen, stepblue; 19235c4bbdfSmrg VisualPtr pVisual; 19335c4bbdfSmrg int pixel; 19435c4bbdfSmrg int nresult; 19535c4bbdfSmrg int i; 19605b261ecSmrg 19705b261ecSmrg pVisual = pmap->pVisual; 19805b261ecSmrg 19905b261ecSmrg stepred = 1 << pVisual->offsetRed; 20005b261ecSmrg stepgreen = 1 << pVisual->offsetGreen; 20105b261ecSmrg stepblue = 1 << pVisual->offsetBlue; 20205b261ecSmrg maxred = pVisual->redMask; 20305b261ecSmrg maxgreen = pVisual->greenMask; 20405b261ecSmrg maxblue = pVisual->blueMask; 20505b261ecSmrg nresult = 0; 20635c4bbdfSmrg for (; ndef--; indefs++) { 20735c4bbdfSmrg if (indefs->flags & DoRed) { 20835c4bbdfSmrg red = indefs->pixel & pVisual->redMask; 20935c4bbdfSmrg for (green = 0; green <= maxgreen; green += stepgreen) { 21035c4bbdfSmrg for (blue = 0; blue <= maxblue; blue += stepblue) { 21135c4bbdfSmrg AddElement(DoRed) 21235c4bbdfSmrg } 21335c4bbdfSmrg } 21435c4bbdfSmrg } 21535c4bbdfSmrg if (indefs->flags & DoGreen) { 21635c4bbdfSmrg green = indefs->pixel & pVisual->greenMask; 21735c4bbdfSmrg for (red = 0; red <= maxred; red += stepred) { 21835c4bbdfSmrg for (blue = 0; blue <= maxblue; blue += stepblue) { 21935c4bbdfSmrg AddElement(DoGreen) 22035c4bbdfSmrg } 22135c4bbdfSmrg } 22235c4bbdfSmrg } 22335c4bbdfSmrg if (indefs->flags & DoBlue) { 22435c4bbdfSmrg blue = indefs->pixel & pVisual->blueMask; 22535c4bbdfSmrg for (red = 0; red <= maxred; red += stepred) { 22635c4bbdfSmrg for (green = 0; green <= maxgreen; green += stepgreen) { 22735c4bbdfSmrg AddElement(DoBlue) 22835c4bbdfSmrg } 22935c4bbdfSmrg } 23035c4bbdfSmrg } 23105b261ecSmrg } 23205b261ecSmrg return nresult; 23305b261ecSmrg} 23405b261ecSmrg 2356747b715SmrgBool 23605b261ecSmrgmiCreateDefColormap(ScreenPtr pScreen) 23705b261ecSmrg{ 23835c4bbdfSmrg unsigned short zero = 0, ones = 0xFFFF; 23905b261ecSmrg Pixel wp, bp; 24035c4bbdfSmrg VisualPtr pVisual; 24135c4bbdfSmrg ColormapPtr cmap; 24205b261ecSmrg int alloctype; 24335c4bbdfSmrg 2446747b715Smrg if (!dixRegisterPrivateKey(&micmapScrPrivateKeyRec, PRIVATE_SCREEN, 0)) 24535c4bbdfSmrg return FALSE; 2466747b715Smrg 24705b261ecSmrg for (pVisual = pScreen->visuals; 24835c4bbdfSmrg pVisual->vid != pScreen->rootVisual; pVisual++); 24905b261ecSmrg 25005b261ecSmrg if (pScreen->rootDepth == 1 || (pVisual->class & DynamicClass)) 25135c4bbdfSmrg alloctype = AllocNone; 25205b261ecSmrg else 25335c4bbdfSmrg alloctype = AllocAll; 25405b261ecSmrg 25505b261ecSmrg if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap, 25635c4bbdfSmrg alloctype, 0) != Success) 25735c4bbdfSmrg return FALSE; 25805b261ecSmrg 25905b261ecSmrg if (pScreen->rootDepth > 1) { 26035c4bbdfSmrg wp = pScreen->whitePixel; 26135c4bbdfSmrg bp = pScreen->blackPixel; 26235c4bbdfSmrg if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) != 26335c4bbdfSmrg Success) || 26435c4bbdfSmrg (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) != Success)) 26535c4bbdfSmrg return FALSE; 26635c4bbdfSmrg pScreen->whitePixel = wp; 26735c4bbdfSmrg pScreen->blackPixel = bp; 26805b261ecSmrg } 26905b261ecSmrg 27035c4bbdfSmrg (*pScreen->InstallColormap) (cmap); 27105b261ecSmrg return TRUE; 27205b261ecSmrg} 27305b261ecSmrg 27405b261ecSmrg/* 27505b261ecSmrg * Default true color bitmasks, should be overridden by 27605b261ecSmrg * driver 27705b261ecSmrg */ 27805b261ecSmrg 27905b261ecSmrg#define _RZ(d) ((d + 2) / 3) 28005b261ecSmrg#define _RS(d) 0 281ed6184dfSmrg#define _RM(d) ((1U << _RZ(d)) - 1) 28205b261ecSmrg#define _GZ(d) ((d - _RZ(d) + 1) / 2) 28305b261ecSmrg#define _GS(d) _RZ(d) 284ed6184dfSmrg#define _GM(d) (((1U << _GZ(d)) - 1) << _GS(d)) 28505b261ecSmrg#define _BZ(d) (d - _RZ(d) - _GZ(d)) 28605b261ecSmrg#define _BS(d) (_RZ(d) + _GZ(d)) 287ed6184dfSmrg#define _BM(d) (((1U << _BZ(d)) - 1) << _BS(d)) 288ed6184dfSmrg#define _CE(d) (1U << _RZ(d)) 28905b261ecSmrg 29005b261ecSmrgtypedef struct _miVisuals { 29135c4bbdfSmrg struct _miVisuals *next; 29235c4bbdfSmrg int depth; 29335c4bbdfSmrg int bitsPerRGB; 29435c4bbdfSmrg int visuals; 29535c4bbdfSmrg int count; 29635c4bbdfSmrg int preferredCVC; 29735c4bbdfSmrg Pixel redMask, greenMask, blueMask; 29805b261ecSmrg} miVisualsRec, *miVisualsPtr; 29905b261ecSmrg 30035c4bbdfSmrgstatic int miVisualPriority[] = { 30105b261ecSmrg PseudoColor, GrayScale, StaticColor, TrueColor, DirectColor, StaticGray 30205b261ecSmrg}; 30305b261ecSmrg 30405b261ecSmrg#define NUM_PRIORITY 6 30505b261ecSmrg 30635c4bbdfSmrgstatic miVisualsPtr miVisuals; 30705b261ecSmrg 3086747b715Smrgvoid 30905b261ecSmrgmiClearVisualTypes(void) 31005b261ecSmrg{ 31105b261ecSmrg miVisualsPtr v; 31205b261ecSmrg 31305b261ecSmrg while ((v = miVisuals)) { 31435c4bbdfSmrg miVisuals = v->next; 31535c4bbdfSmrg free(v); 31605b261ecSmrg } 31705b261ecSmrg} 31805b261ecSmrg 3196747b715SmrgBool 32035c4bbdfSmrgmiSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB, 32135c4bbdfSmrg int preferredCVC, 32235c4bbdfSmrg Pixel redMask, Pixel greenMask, Pixel blueMask) 32305b261ecSmrg{ 32435c4bbdfSmrg miVisualsPtr new, *prev, v; 32535c4bbdfSmrg int count; 32605b261ecSmrg 3276747b715Smrg new = malloc(sizeof *new); 32805b261ecSmrg if (!new) 32935c4bbdfSmrg return FALSE; 33035c4bbdfSmrg if (!redMask || !greenMask || !blueMask) { 33135c4bbdfSmrg redMask = _RM(depth); 33235c4bbdfSmrg greenMask = _GM(depth); 33335c4bbdfSmrg blueMask = _BM(depth); 33405b261ecSmrg } 33505b261ecSmrg new->next = 0; 33605b261ecSmrg new->depth = depth; 33705b261ecSmrg new->visuals = visuals; 33805b261ecSmrg new->bitsPerRGB = bitsPerRGB; 33905b261ecSmrg new->preferredCVC = preferredCVC; 34005b261ecSmrg new->redMask = redMask; 34105b261ecSmrg new->greenMask = greenMask; 34205b261ecSmrg new->blueMask = blueMask; 34305b261ecSmrg count = (visuals >> 1) & 033333333333; 34405b261ecSmrg count = visuals - count - ((count >> 1) & 033333333333); 34535c4bbdfSmrg count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */ 34605b261ecSmrg new->count = count; 34705b261ecSmrg for (prev = &miVisuals; (v = *prev); prev = &v->next); 34805b261ecSmrg *prev = new; 34905b261ecSmrg return TRUE; 35005b261ecSmrg} 35105b261ecSmrg 3526747b715SmrgBool 35305b261ecSmrgmiSetVisualTypes(int depth, int visuals, int bitsPerRGB, int preferredCVC) 35405b261ecSmrg{ 35535c4bbdfSmrg return miSetVisualTypesAndMasks(depth, visuals, bitsPerRGB, 35635c4bbdfSmrg preferredCVC, 0, 0, 0); 35705b261ecSmrg} 35805b261ecSmrg 3596747b715Smrgint 36005b261ecSmrgmiGetDefaultVisualMask(int depth) 36105b261ecSmrg{ 36205b261ecSmrg if (depth > MAX_PSEUDO_DEPTH) 36335c4bbdfSmrg return LARGE_VISUALS; 36405b261ecSmrg else if (depth >= MIN_TRUE_DEPTH) 36535c4bbdfSmrg return ALL_VISUALS; 36605b261ecSmrg else if (depth == 1) 36735c4bbdfSmrg return StaticGrayMask; 36805b261ecSmrg else 36935c4bbdfSmrg return SMALL_VISUALS; 37005b261ecSmrg} 37105b261ecSmrg 37205b261ecSmrgstatic Bool 37335c4bbdfSmrgmiVisualTypesSet(int depth) 37405b261ecSmrg{ 37535c4bbdfSmrg miVisualsPtr visuals; 37605b261ecSmrg 37705b261ecSmrg for (visuals = miVisuals; visuals; visuals = visuals->next) 37835c4bbdfSmrg if (visuals->depth == depth) 37935c4bbdfSmrg return TRUE; 38005b261ecSmrg return FALSE; 38105b261ecSmrg} 38205b261ecSmrg 3836747b715SmrgBool 38435c4bbdfSmrgmiSetPixmapDepths(void) 38505b261ecSmrg{ 38635c4bbdfSmrg int d, f; 38735c4bbdfSmrg 38805b261ecSmrg /* Add any unlisted depths from the pixmap formats */ 38935c4bbdfSmrg for (f = 0; f < screenInfo.numPixmapFormats; f++) { 39035c4bbdfSmrg d = screenInfo.formats[f].depth; 39135c4bbdfSmrg if (!miVisualTypesSet(d)) { 39235c4bbdfSmrg if (!miSetVisualTypes(d, 0, 0, -1)) 39335c4bbdfSmrg return FALSE; 39435c4bbdfSmrg } 39505b261ecSmrg } 39605b261ecSmrg return TRUE; 39705b261ecSmrg} 39805b261ecSmrg 39905b261ecSmrg/* 40005b261ecSmrg * Distance to least significant one bit 40105b261ecSmrg */ 40205b261ecSmrgstatic int 40335c4bbdfSmrgmaskShift(Pixel p) 40405b261ecSmrg{ 40535c4bbdfSmrg int s; 40605b261ecSmrg 40735c4bbdfSmrg if (!p) 40835c4bbdfSmrg return 0; 40905b261ecSmrg s = 0; 41035c4bbdfSmrg while (!(p & 1)) { 41135c4bbdfSmrg s++; 41235c4bbdfSmrg p >>= 1; 41305b261ecSmrg } 41405b261ecSmrg return s; 41505b261ecSmrg} 41605b261ecSmrg 41705b261ecSmrg/* 41805b261ecSmrg * Given a list of formats for a screen, create a list 419ed6184dfSmrg * of visuals and depths for the screen which correspond to 42005b261ecSmrg * the set which can be used with this version of cfb. 42105b261ecSmrg */ 42205b261ecSmrg 4236747b715SmrgBool 42435c4bbdfSmrgmiInitVisuals(VisualPtr * visualp, DepthPtr * depthp, int *nvisualp, 42535c4bbdfSmrg int *ndepthp, int *rootDepthp, VisualID * defaultVisp, 42635c4bbdfSmrg unsigned long sizes, int bitsPerRGB, int preferredVis) 42705b261ecSmrg{ 42835c4bbdfSmrg int i, j = 0, k; 42935c4bbdfSmrg VisualPtr visual; 43035c4bbdfSmrg DepthPtr depth; 43135c4bbdfSmrg VisualID *vid; 43235c4bbdfSmrg int d, b; 43335c4bbdfSmrg int f; 43435c4bbdfSmrg int ndepth, nvisual; 43535c4bbdfSmrg int nvtype; 43635c4bbdfSmrg int vtype; 43735c4bbdfSmrg miVisualsPtr visuals, nextVisuals; 43835c4bbdfSmrg int *preferredCVCs, *prefp; 43935c4bbdfSmrg int first_depth; 44005b261ecSmrg 44105b261ecSmrg /* none specified, we'll guess from pixmap formats */ 44235c4bbdfSmrg if (!miVisuals) { 44335c4bbdfSmrg for (f = 0; f < screenInfo.numPixmapFormats; f++) { 44435c4bbdfSmrg d = screenInfo.formats[f].depth; 44535c4bbdfSmrg b = screenInfo.formats[f].bitsPerPixel; 44635c4bbdfSmrg if (sizes & (1 << (b - 1))) 44735c4bbdfSmrg vtype = miGetDefaultVisualMask(d); 44835c4bbdfSmrg else 44935c4bbdfSmrg vtype = 0; 45035c4bbdfSmrg if (!miSetVisualTypes(d, vtype, bitsPerRGB, -1)) 45135c4bbdfSmrg return FALSE; 45235c4bbdfSmrg } 45305b261ecSmrg } 45405b261ecSmrg nvisual = 0; 45505b261ecSmrg ndepth = 0; 45635c4bbdfSmrg for (visuals = miVisuals; visuals; visuals = nextVisuals) { 45735c4bbdfSmrg nextVisuals = visuals->next; 45835c4bbdfSmrg ndepth++; 45935c4bbdfSmrg nvisual += visuals->count; 46005b261ecSmrg } 46135c4bbdfSmrg depth = xallocarray(ndepth, sizeof(DepthRec)); 46235c4bbdfSmrg visual = xallocarray(nvisual, sizeof(VisualRec)); 46335c4bbdfSmrg preferredCVCs = xallocarray(ndepth, sizeof(int)); 46435c4bbdfSmrg if (!depth || !visual || !preferredCVCs) { 46535c4bbdfSmrg free(depth); 46635c4bbdfSmrg free(visual); 46735c4bbdfSmrg free(preferredCVCs); 46835c4bbdfSmrg return FALSE; 46905b261ecSmrg } 47005b261ecSmrg *depthp = depth; 47105b261ecSmrg *visualp = visual; 47205b261ecSmrg *ndepthp = ndepth; 47305b261ecSmrg *nvisualp = nvisual; 47405b261ecSmrg prefp = preferredCVCs; 47535c4bbdfSmrg for (visuals = miVisuals; visuals; visuals = nextVisuals) { 47635c4bbdfSmrg nextVisuals = visuals->next; 47735c4bbdfSmrg d = visuals->depth; 47835c4bbdfSmrg vtype = visuals->visuals; 47935c4bbdfSmrg nvtype = visuals->count; 48035c4bbdfSmrg *prefp = visuals->preferredCVC; 48135c4bbdfSmrg prefp++; 48235c4bbdfSmrg vid = NULL; 48335c4bbdfSmrg if (nvtype) { 48435c4bbdfSmrg vid = xallocarray(nvtype, sizeof(VisualID)); 48535c4bbdfSmrg if (!vid) { 48635c4bbdfSmrg free(depth); 48735c4bbdfSmrg free(visual); 48835c4bbdfSmrg free(preferredCVCs); 48935c4bbdfSmrg return FALSE; 49035c4bbdfSmrg } 49135c4bbdfSmrg } 49235c4bbdfSmrg depth->depth = d; 49335c4bbdfSmrg depth->numVids = nvtype; 49435c4bbdfSmrg depth->vids = vid; 49535c4bbdfSmrg depth++; 49635c4bbdfSmrg for (i = 0; i < NUM_PRIORITY; i++) { 49735c4bbdfSmrg if (!(vtype & (1 << miVisualPriority[i]))) 49835c4bbdfSmrg continue; 49935c4bbdfSmrg visual->class = miVisualPriority[i]; 50035c4bbdfSmrg visual->bitsPerRGBValue = visuals->bitsPerRGB; 50135c4bbdfSmrg visual->ColormapEntries = 1 << d; 50235c4bbdfSmrg visual->nplanes = d; 50335c4bbdfSmrg visual->vid = *vid = FakeClientID(0); 50435c4bbdfSmrg switch (visual->class) { 50535c4bbdfSmrg case PseudoColor: 50635c4bbdfSmrg case GrayScale: 50735c4bbdfSmrg case StaticGray: 50835c4bbdfSmrg visual->redMask = 0; 50935c4bbdfSmrg visual->greenMask = 0; 51035c4bbdfSmrg visual->blueMask = 0; 51135c4bbdfSmrg visual->offsetRed = 0; 51235c4bbdfSmrg visual->offsetGreen = 0; 51335c4bbdfSmrg visual->offsetBlue = 0; 51435c4bbdfSmrg break; 51535c4bbdfSmrg case DirectColor: 51635c4bbdfSmrg case TrueColor: 51735c4bbdfSmrg visual->ColormapEntries = _CE(d); 51835c4bbdfSmrg /* fall through */ 51935c4bbdfSmrg case StaticColor: 52035c4bbdfSmrg visual->redMask = visuals->redMask; 52135c4bbdfSmrg visual->greenMask = visuals->greenMask; 52235c4bbdfSmrg visual->blueMask = visuals->blueMask; 52335c4bbdfSmrg visual->offsetRed = maskShift(visuals->redMask); 52435c4bbdfSmrg visual->offsetGreen = maskShift(visuals->greenMask); 52535c4bbdfSmrg visual->offsetBlue = maskShift(visuals->blueMask); 52635c4bbdfSmrg } 52735c4bbdfSmrg vid++; 52835c4bbdfSmrg visual++; 52935c4bbdfSmrg } 53035c4bbdfSmrg free(visuals); 53105b261ecSmrg } 53205b261ecSmrg miVisuals = NULL; 53305b261ecSmrg visual = *visualp; 53405b261ecSmrg depth = *depthp; 53505b261ecSmrg 53605b261ecSmrg /* 53705b261ecSmrg * if we did not supplyied by a preferred visual class 53805b261ecSmrg * check if there is a preferred class in one of the depth 53905b261ecSmrg * structures - if there is, we want to start looking for the 54005b261ecSmrg * default visual/depth from that depth. 54105b261ecSmrg */ 54205b261ecSmrg first_depth = 0; 54335c4bbdfSmrg if (preferredVis < 0 && defaultColorVisualClass < 0) { 54435c4bbdfSmrg for (i = 0; i < ndepth; i++) { 54535c4bbdfSmrg if (preferredCVCs[i] >= 0) { 54635c4bbdfSmrg first_depth = i; 54735c4bbdfSmrg break; 54835c4bbdfSmrg } 54935c4bbdfSmrg } 55005b261ecSmrg } 55105b261ecSmrg 55235c4bbdfSmrg for (i = first_depth; i < ndepth; i++) { 55335c4bbdfSmrg int prefColorVisualClass = -1; 55435c4bbdfSmrg 55535c4bbdfSmrg if (defaultColorVisualClass >= 0) 55635c4bbdfSmrg prefColorVisualClass = defaultColorVisualClass; 55735c4bbdfSmrg else if (preferredVis >= 0) 55835c4bbdfSmrg prefColorVisualClass = preferredVis; 55935c4bbdfSmrg else if (preferredCVCs[i] >= 0) 56035c4bbdfSmrg prefColorVisualClass = preferredCVCs[i]; 56135c4bbdfSmrg 56235c4bbdfSmrg if (*rootDepthp && *rootDepthp != depth[i].depth) 56335c4bbdfSmrg continue; 56435c4bbdfSmrg 56535c4bbdfSmrg for (j = 0; j < depth[i].numVids; j++) { 56635c4bbdfSmrg for (k = 0; k < nvisual; k++) 56735c4bbdfSmrg if (visual[k].vid == depth[i].vids[j]) 56835c4bbdfSmrg break; 56935c4bbdfSmrg if (k == nvisual) 57035c4bbdfSmrg continue; 57135c4bbdfSmrg if (prefColorVisualClass < 0 || 57235c4bbdfSmrg visual[k].class == prefColorVisualClass) 57335c4bbdfSmrg break; 57435c4bbdfSmrg } 57535c4bbdfSmrg if (j != depth[i].numVids) 57635c4bbdfSmrg break; 57705b261ecSmrg } 57805b261ecSmrg if (i == ndepth) { 57935c4bbdfSmrg i = 0; 58035c4bbdfSmrg j = 0; 58105b261ecSmrg } 58205b261ecSmrg *rootDepthp = depth[i].depth; 58305b261ecSmrg *defaultVisp = depth[i].vids[j]; 5846747b715Smrg free(preferredCVCs); 58505b261ecSmrg 58605b261ecSmrg return TRUE; 58705b261ecSmrg} 588