1 /* $XConsortium: cfbcmap.c,v 4.19 94/04/17 20:28:46 dpw Exp $ */
2 /* $XFree86: xc/programs/Xserver/cfb/cfbcmap.c,v 3.1.8.2 1997/05/11 05:04:17 dawes Exp $ */
3 /************************************************************
4 Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
8 Permission to use, copy, modify, and distribute this
9 software and its documentation for any purpose and without
10 fee is hereby granted, provided that the above copyright no-
11 tice appear in all copies and that both that copyright no-
12 tice and this permission notice appear in supporting docu-
13 mentation, and that the names of Sun or X Consortium
14 not be used in advertising or publicity pertaining to
15 distribution of the software without specific prior
16 written permission. Sun and X Consortium make no
17 representations about the suitability of this software for
18 any purpose. It is provided "as is" without any express or
21 SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
23 NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
24 ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
25 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
27 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
28 THE USE OR PERFORMANCE OF THIS SOFTWARE.
30 ********************************************************/
35 #include "scrnintstr.h"
36 #include "colormapst.h"
41 Bool (*GlxInitVisualsPtr)(
43 extern Bool GlxInitVisuals(
45 #if NeedFunctionPrototypes
46 VisualPtr * /*visualp*/,
47 DepthPtr * /*depthp*/,
51 VisualID * /*defaultVisp*/,
52 unsigned long /*sizes*/,
64 static ColormapPtr InstalledMaps[MAXSCREENS];
67 cfbListInstalledColormaps(pScreen, pmaps)
71 /* By the time we are processing requests, we can guarantee that there
72 * is always a colormap installed */
73 *pmaps = InstalledMaps[pScreen->myNum]->mid;
79 cfbInstallColormap(pmap)
82 int index = pmap->pScreen->myNum;
83 ColormapPtr oldpmap = InstalledMaps[index];
87 /* Uninstall pInstalledMap. No hardware changes required, just
88 * notify all interested parties. */
89 if(oldpmap != (ColormapPtr)None)
90 WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
92 InstalledMaps[index] = pmap;
93 WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
99 cfbUninstallColormap(pmap)
102 int index = pmap->pScreen->myNum;
103 ColormapPtr curpmap = InstalledMaps[index];
107 if (pmap->mid != pmap->pScreen->defColormap)
109 curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
111 (*pmap->pScreen->InstallColormap)(curpmap);
119 cfbResolveColor(pred, pgreen, pblue, pVisual)
120 unsigned short *pred, *pgreen, *pblue;
121 register VisualPtr pVisual;
123 int shift = 16 - pVisual->bitsPerRGBValue;
124 unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1;
126 if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor))
128 /* rescale to rgb bits */
129 *pred = ((*pred >> shift) * 65535) / lim;
130 *pgreen = ((*pgreen >> shift) * 65535) / lim;
131 *pblue = ((*pblue >> shift) * 65535) / lim;
133 else if (pVisual->class == GrayScale)
135 /* rescale to gray then rgb bits */
136 *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
137 *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
139 else if (pVisual->class == StaticGray)
141 unsigned limg = pVisual->ColormapEntries - 1;
142 /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
143 *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
144 *pred = ((((*pred * (limg + 1))) >> 16) * 65535) / limg;
145 *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
149 unsigned limr, limg, limb;
151 limr = pVisual->redMask >> pVisual->offsetRed;
152 limg = pVisual->greenMask >> pVisual->offsetGreen;
153 limb = pVisual->blueMask >> pVisual->offsetBlue;
154 /* rescale to [0..limN] then [0..65535] then rgb bits */
155 *pred = ((((((*pred * (limr + 1)) >> 16) *
156 65535) / limr) >> shift) * 65535) / lim;
157 *pgreen = ((((((*pgreen * (limg + 1)) >> 16) *
158 65535) / limg) >> shift) * 65535) / lim;
159 *pblue = ((((((*pblue * (limb + 1)) >> 16) *
160 65535) / limb) >> shift) * 65535) / lim;
165 cfbInitializeColormap(pmap)
166 register ColormapPtr pmap;
169 register VisualPtr pVisual;
170 unsigned lim, maxent, shift;
172 pVisual = pmap->pVisual;
173 lim = (1 << pVisual->bitsPerRGBValue) - 1;
174 shift = 16 - pVisual->bitsPerRGBValue;
175 maxent = pVisual->ColormapEntries - 1;
176 if (pVisual->class == TrueColor)
178 unsigned limr, limg, limb;
180 limr = pVisual->redMask >> pVisual->offsetRed;
181 limg = pVisual->greenMask >> pVisual->offsetGreen;
182 limb = pVisual->blueMask >> pVisual->offsetBlue;
183 for(i = 0; i <= maxent; i++)
185 /* rescale to [0..65535] then rgb bits */
186 pmap->red[i].co.local.red =
187 ((((i * 65535) / limr) >> shift) * 65535) / lim;
188 pmap->green[i].co.local.green =
189 ((((i * 65535) / limg) >> shift) * 65535) / lim;
190 pmap->blue[i].co.local.blue =
191 ((((i * 65535) / limb) >> shift) * 65535) / lim;
194 else if (pVisual->class == StaticColor)
196 unsigned limr, limg, limb;
198 limr = pVisual->redMask >> pVisual->offsetRed;
199 limg = pVisual->greenMask >> pVisual->offsetGreen;
200 limb = pVisual->blueMask >> pVisual->offsetBlue;
201 for(i = 0; i <= maxent; i++)
203 /* rescale to [0..65535] then rgb bits */
204 pmap->red[i].co.local.red =
205 ((((((i & pVisual->redMask) >> pVisual->offsetRed)
206 * 65535) / limr) >> shift) * 65535) / lim;
207 pmap->red[i].co.local.green =
208 ((((((i & pVisual->greenMask) >> pVisual->offsetGreen)
209 * 65535) / limg) >> shift) * 65535) / lim;
210 pmap->red[i].co.local.blue =
211 ((((((i & pVisual->blueMask) >> pVisual->offsetBlue)
212 * 65535) / limb) >> shift) * 65535) / lim;
215 else if (pVisual->class == StaticGray)
217 for(i = 0; i <= maxent; i++)
219 /* rescale to [0..65535] then rgb bits */
220 pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift)
222 pmap->red[i].co.local.green = pmap->red[i].co.local.red;
223 pmap->red[i].co.local.blue = pmap->red[i].co.local.red;
229 /* When simulating DirectColor on PseudoColor hardware, multiple
230 entries of the colormap must be updated
233 #define AddElement(mask) { \
234 pixel = red | green | blue; \
235 for (i = 0; i < nresult; i++) \
236 if (outdefs[i].pixel == pixel) \
241 outdefs[i].pixel = pixel; \
242 outdefs[i].flags = 0; \
244 outdefs[i].flags |= (mask); \
245 outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \
246 outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \
247 outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \
250 cfbExpandDirectColors (pmap, ndef, indefs, outdefs)
253 xColorItem *indefs, *outdefs;
255 int minred, mingreen, minblue;
256 register int red, green, blue;
257 int maxred, maxgreen, maxblue;
258 int stepred, stepgreen, stepblue;
261 register int nresult;
264 pVisual = pmap->pVisual;
266 stepred = 1 << pVisual->offsetRed;
267 stepgreen = 1 << pVisual->offsetGreen;
268 stepblue = 1 << pVisual->offsetBlue;
269 maxred = pVisual->redMask;
270 maxgreen = pVisual->greenMask;
271 maxblue = pVisual->blueMask;
273 for (;ndef--; indefs++)
275 if (indefs->flags & DoRed)
277 red = indefs->pixel & pVisual->redMask;
278 for (green = 0; green <= maxgreen; green += stepgreen)
280 for (blue = 0; blue <= maxblue; blue += stepblue)
286 if (indefs->flags & DoGreen)
288 green = indefs->pixel & pVisual->greenMask;
289 for (red = 0; red <= maxred; red += stepred)
291 for (blue = 0; blue <= maxblue; blue += stepblue)
297 if (indefs->flags & DoBlue)
299 blue = indefs->pixel & pVisual->blueMask;
300 for (red = 0; red <= maxred; red += stepred)
302 for (green = 0; green <= maxgreen; green += stepgreen)
313 cfbCreateDefColormap(pScreen)
316 unsigned short zero = 0, ones = 0xFFFF;
321 for (pVisual = pScreen->visuals;
322 pVisual->vid != pScreen->rootVisual;
326 if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap,
327 (pVisual->class & DynamicClass) ? AllocNone : AllocAll,
331 wp = pScreen->whitePixel;
332 bp = pScreen->blackPixel;
333 if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) !=
335 (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) !=
338 pScreen->whitePixel = wp;
339 pScreen->blackPixel = bp;
340 (*pScreen->InstallColormap)(cmap);
344 extern int defaultColorVisualClass;
346 #define _RZ(d) ((d + 2) / 3)
348 #define _RM(d) ((1 << _RZ(d)) - 1)
349 #define _GZ(d) ((d - _RZ(d) + 1) / 2)
350 #define _GS(d) _RZ(d)
351 #define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d))
352 #define _BZ(d) (d - _RZ(d) - _GZ(d))
353 #define _BS(d) (_RZ(d) + _GZ(d))
354 #define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d))
355 #define _CE(d) (1 << _RZ(d))
357 #define MAX_PSEUDO_DEPTH 10 /* largest DAC size I know */
359 #define StaticGrayMask (1 << StaticGray)
360 #define GrayScaleMask (1 << GrayScale)
361 #define StaticColorMask (1 << StaticColor)
362 #define PseudoColorMask (1 << PseudoColor)
363 #define TrueColorMask (1 << TrueColor)
364 #define DirectColorMask (1 << DirectColor)
366 #define ALL_VISUALS (StaticGrayMask|\
373 #define LARGE_VISUALS (TrueColorMask|\
376 typedef struct _cfbVisuals {
377 struct _cfbVisuals *next;
382 } cfbVisualsRec, *cfbVisualsPtr;
384 static int cfbVisualPriority[] = {
385 PseudoColor, DirectColor, GrayScale, StaticColor, TrueColor, StaticGray
388 #define NUM_PRIORITY 6
390 static cfbVisualsPtr cfbVisuals;
393 cfbSetVisualTypes (depth, visuals, bitsPerRGB)
397 cfbVisualsPtr new, *prev, v;
400 new = (cfbVisualsPtr) xalloc (sizeof *new);
405 new->visuals = visuals;
406 new->bitsPerRGB = bitsPerRGB;
407 count = (visuals >> 1) & 033333333333;
408 count = visuals - count - ((count >> 1) & 033333333333);
409 count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */
411 for (prev = &cfbVisuals; v = *prev; prev = &v->next);
417 * Given a list of formats for a screen, create a list
418 * of visuals and depths for the screen which coorespond to
419 * the set which can be used with this version of cfb.
423 cfbInitVisuals (visualp, depthp, nvisualp, ndepthp, rootDepthp, defaultVisp, sizes, bitsPerRGB)
426 int *nvisualp, *ndepthp;
428 VisualID *defaultVisp;
441 VisualID defaultVisual;
442 cfbVisualsPtr visuals, nextVisuals;
444 /* none specified, we'll guess from pixmap formats */
447 for (f = 0; f < screenInfo.numPixmapFormats; f++)
449 d = screenInfo.formats[f].depth;
450 b = screenInfo.formats[f].bitsPerPixel;
451 if (sizes & (1 << (b - 1)))
453 if (d > MAX_PSEUDO_DEPTH)
454 vtype = LARGE_VISUALS;
456 vtype = StaticGrayMask;
462 if (!cfbSetVisualTypes (d, vtype, bitsPerRGB))
468 for (visuals = cfbVisuals; visuals; visuals = nextVisuals)
470 nextVisuals = visuals->next;
472 nvisual += visuals->count;
474 depth = (DepthPtr) xalloc (ndepth * sizeof (DepthRec));
475 visual = (VisualPtr) xalloc (nvisual * sizeof (VisualRec));
476 if (!depth || !visual)
486 for (visuals = cfbVisuals; visuals; visuals = nextVisuals)
488 nextVisuals = visuals->next;
490 vtype = visuals->visuals;
491 nvtype = visuals->count;
495 vid = (VisualID *) xalloc (nvtype * sizeof (VisualID));
500 depth->numVids = nvtype;
503 for (i = 0; i < NUM_PRIORITY; i++) {
504 if (! (vtype & (1 << cfbVisualPriority[i])))
506 visual->class = cfbVisualPriority[i];
507 visual->bitsPerRGBValue = visuals->bitsPerRGB;
508 visual->ColormapEntries = 1 << d;
510 visual->vid = *vid = FakeClientID (0);
511 switch (visual->class) {
516 visual->greenMask = 0;
517 visual->blueMask = 0;
518 visual->offsetRed = 0;
519 visual->offsetGreen = 0;
520 visual->offsetBlue = 0;
524 visual->ColormapEntries = _CE(d);
527 visual->redMask = _RM(d);
528 visual->greenMask = _GM(d);
529 visual->blueMask = _BM(d);
530 visual->offsetRed = _RS(d);
531 visual->offsetGreen = _GS(d);
532 visual->offsetBlue = _BS(d);
542 for (i = 0; i < ndepth; i++)
544 if (*rootDepthp && *rootDepthp != depth[i].depth)
546 for (j = 0; j < depth[i].numVids; j++)
548 for (k = 0; k < nvisual; k++)
549 if (visual[k].vid == depth[i].vids[j])
553 if (defaultColorVisualClass < 0 ||
554 visual[k].class == defaultColorVisualClass)
557 if (j != depth[i].numVids)
564 *rootDepthp = depth[i].depth;
565 *defaultVisp = depth[i].vids[j];
569 if( GlxInitVisualsPtr != NULL )
570 return (*GlxInitVisualsPtr)
572 return GlxInitVisuals