First import
[xorg_rtime.git] / xorg-server-1.4 / mi / micmap.c
blob33d948179ac3252a4c70f2950ed49301bf497399
1 /************************************************************
2 Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
4 All Rights Reserved
6 Permission to use, copy, modify, and distribute this
7 software and its documentation for any purpose and without
8 fee is hereby granted, provided that the above copyright no-
9 tice appear in all copies and that both that copyright no-
10 tice and this permission notice appear in supporting docu-
11 mentation, and that the names of Sun or X Consortium
12 not be used in advertising or publicity pertaining to
13 distribution of the software without specific prior
14 written permission. Sun and X Consortium make no
15 representations about the suitability of this software for
16 any purpose. It is provided "as is" without any express or
17 implied warranty.
19 SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
20 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
21 NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
22 ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
23 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
24 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
25 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
26 THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 ********************************************************/
31 * This is based on cfbcmap.c. The functions here are useful independently
32 * of cfb, which is the reason for including them here. How "mi" these
33 * are may be debatable.
37 #ifdef HAVE_DIX_CONFIG_H
38 #include <dix-config.h>
39 #endif
41 #include <X11/X.h>
42 #include <X11/Xproto.h>
43 #include "scrnintstr.h"
44 #include "colormapst.h"
45 #include "resource.h"
46 #include "globals.h"
47 #include "micmap.h"
49 _X_EXPORT ColormapPtr miInstalledMaps[MAXSCREENS];
51 static Bool miDoInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
52 int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
53 unsigned long sizes, int bitsPerRGB, int preferredVis);
55 _X_EXPORT miInitVisualsProcPtr miInitVisualsProc = miDoInitVisuals;
57 _X_EXPORT int
58 miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
60 if (miInstalledMaps[pScreen->myNum]) {
61 *pmaps = miInstalledMaps[pScreen->myNum]->mid;
62 return (1);
64 return 0;
67 _X_EXPORT void
68 miInstallColormap(ColormapPtr pmap)
70 int index = pmap->pScreen->myNum;
71 ColormapPtr oldpmap = miInstalledMaps[index];
73 if(pmap != oldpmap)
75 /* Uninstall pInstalledMap. No hardware changes required, just
76 * notify all interested parties. */
77 if(oldpmap != (ColormapPtr)None)
78 WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
79 /* Install pmap */
80 miInstalledMaps[index] = pmap;
81 WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
86 _X_EXPORT void
87 miUninstallColormap(ColormapPtr pmap)
89 int index = pmap->pScreen->myNum;
90 ColormapPtr curpmap = miInstalledMaps[index];
92 if(pmap == curpmap)
94 if (pmap->mid != pmap->pScreen->defColormap)
96 curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
97 RT_COLORMAP);
98 (*pmap->pScreen->InstallColormap)(curpmap);
103 _X_EXPORT void
104 miResolveColor(unsigned short *pred, unsigned short *pgreen,
105 unsigned short *pblue, VisualPtr pVisual)
107 int shift = 16 - pVisual->bitsPerRGBValue;
108 unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1;
110 if ((pVisual->class | DynamicClass) == GrayScale)
112 /* rescale to gray then rgb bits */
113 *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
114 *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
116 else
118 /* rescale to rgb bits */
119 *pred = ((*pred >> shift) * 65535) / lim;
120 *pgreen = ((*pgreen >> shift) * 65535) / lim;
121 *pblue = ((*pblue >> shift) * 65535) / lim;
125 _X_EXPORT Bool
126 miInitializeColormap(ColormapPtr pmap)
128 unsigned i;
129 VisualPtr pVisual;
130 unsigned lim, maxent, shift;
132 pVisual = pmap->pVisual;
133 lim = (1 << pVisual->bitsPerRGBValue) - 1;
134 shift = 16 - pVisual->bitsPerRGBValue;
135 maxent = pVisual->ColormapEntries - 1;
136 if (pVisual->class == TrueColor)
138 unsigned limr, limg, limb;
140 limr = pVisual->redMask >> pVisual->offsetRed;
141 limg = pVisual->greenMask >> pVisual->offsetGreen;
142 limb = pVisual->blueMask >> pVisual->offsetBlue;
143 for(i = 0; i <= maxent; i++)
145 /* rescale to [0..65535] then rgb bits */
146 pmap->red[i].co.local.red =
147 ((((i * 65535) / limr) >> shift) * 65535) / lim;
148 pmap->green[i].co.local.green =
149 ((((i * 65535) / limg) >> shift) * 65535) / lim;
150 pmap->blue[i].co.local.blue =
151 ((((i * 65535) / limb) >> shift) * 65535) / lim;
154 else if (pVisual->class == StaticColor)
156 unsigned limr, limg, limb;
158 limr = pVisual->redMask >> pVisual->offsetRed;
159 limg = pVisual->greenMask >> pVisual->offsetGreen;
160 limb = pVisual->blueMask >> pVisual->offsetBlue;
161 for(i = 0; i <= maxent; i++)
163 /* rescale to [0..65535] then rgb bits */
164 pmap->red[i].co.local.red =
165 ((((((i & pVisual->redMask) >> pVisual->offsetRed)
166 * 65535) / limr) >> shift) * 65535) / lim;
167 pmap->red[i].co.local.green =
168 ((((((i & pVisual->greenMask) >> pVisual->offsetGreen)
169 * 65535) / limg) >> shift) * 65535) / lim;
170 pmap->red[i].co.local.blue =
171 ((((((i & pVisual->blueMask) >> pVisual->offsetBlue)
172 * 65535) / limb) >> shift) * 65535) / lim;
175 else if (pVisual->class == StaticGray)
177 for(i = 0; i <= maxent; i++)
179 /* rescale to [0..65535] then rgb bits */
180 pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift)
181 * 65535) / lim;
182 pmap->red[i].co.local.green = pmap->red[i].co.local.red;
183 pmap->red[i].co.local.blue = pmap->red[i].co.local.red;
186 return TRUE;
189 /* When simulating DirectColor on PseudoColor hardware, multiple
190 entries of the colormap must be updated
193 #define AddElement(mask) { \
194 pixel = red | green | blue; \
195 for (i = 0; i < nresult; i++) \
196 if (outdefs[i].pixel == pixel) \
197 break; \
198 if (i == nresult) \
200 nresult++; \
201 outdefs[i].pixel = pixel; \
202 outdefs[i].flags = 0; \
204 outdefs[i].flags |= (mask); \
205 outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \
206 outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \
207 outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \
210 _X_EXPORT int
211 miExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem *indefs,
212 xColorItem *outdefs)
214 int red, green, blue;
215 int maxred, maxgreen, maxblue;
216 int stepred, stepgreen, stepblue;
217 VisualPtr pVisual;
218 int pixel;
219 int nresult;
220 int i;
222 pVisual = pmap->pVisual;
224 stepred = 1 << pVisual->offsetRed;
225 stepgreen = 1 << pVisual->offsetGreen;
226 stepblue = 1 << pVisual->offsetBlue;
227 maxred = pVisual->redMask;
228 maxgreen = pVisual->greenMask;
229 maxblue = pVisual->blueMask;
230 nresult = 0;
231 for (;ndef--; indefs++)
233 if (indefs->flags & DoRed)
235 red = indefs->pixel & pVisual->redMask;
236 for (green = 0; green <= maxgreen; green += stepgreen)
238 for (blue = 0; blue <= maxblue; blue += stepblue)
240 AddElement (DoRed)
244 if (indefs->flags & DoGreen)
246 green = indefs->pixel & pVisual->greenMask;
247 for (red = 0; red <= maxred; red += stepred)
249 for (blue = 0; blue <= maxblue; blue += stepblue)
251 AddElement (DoGreen)
255 if (indefs->flags & DoBlue)
257 blue = indefs->pixel & pVisual->blueMask;
258 for (red = 0; red <= maxred; red += stepred)
260 for (green = 0; green <= maxgreen; green += stepgreen)
262 AddElement (DoBlue)
267 return nresult;
270 _X_EXPORT Bool
271 miCreateDefColormap(ScreenPtr pScreen)
274 * In the following sources PC X server vendors may want to delete
275 * "_not_tog" from "#ifdef WIN32_not_tog"
277 #ifdef WIN32_not_tog
279 * these are the MS-Windows desktop colors, adjusted for X's 16-bit
280 * color specifications.
282 static xColorItem citems[] = {
283 { 0, 0, 0, 0, 0, 0 },
284 { 1, 0x8000, 0, 0, 0, 0 },
285 { 2, 0, 0x8000, 0, 0, 0 },
286 { 3, 0x8000, 0x8000, 0, 0, 0 },
287 { 4, 0, 0, 0x8000, 0, 0 },
288 { 5, 0x8000, 0, 0x8000, 0, 0 },
289 { 6, 0, 0x8000, 0x8000, 0, 0 },
290 { 7, 0xc000, 0xc000, 0xc000, 0, 0 },
291 { 8, 0xc000, 0xdc00, 0xc000, 0, 0 },
292 { 9, 0xa600, 0xca00, 0xf000, 0, 0 },
293 { 246, 0xff00, 0xfb00, 0xf000, 0, 0 },
294 { 247, 0xa000, 0xa000, 0xa400, 0, 0 },
295 { 248, 0x8000, 0x8000, 0x8000, 0, 0 },
296 { 249, 0xff00, 0, 0, 0, 0 },
297 { 250, 0, 0xff00, 0, 0, 0 },
298 { 251, 0xff00, 0xff00, 0, 0, 0 },
299 { 252, 0, 0, 0xff00, 0, 0 },
300 { 253, 0xff00, 0, 0xff00, 0, 0 },
301 { 254, 0, 0xff00, 0xff00, 0, 0 },
302 { 255, 0xff00, 0xff00, 0xff00, 0, 0 }
304 #define NUM_DESKTOP_COLORS sizeof citems / sizeof citems[0]
305 int i;
306 #else
307 unsigned short zero = 0, ones = 0xFFFF;
308 #endif
309 Pixel wp, bp;
310 VisualPtr pVisual;
311 ColormapPtr cmap;
312 int alloctype;
314 for (pVisual = pScreen->visuals;
315 pVisual->vid != pScreen->rootVisual;
316 pVisual++)
319 if (pScreen->rootDepth == 1 || (pVisual->class & DynamicClass))
320 alloctype = AllocNone;
321 else
322 alloctype = AllocAll;
324 if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap,
325 alloctype, 0) != Success)
326 return FALSE;
328 if (pScreen->rootDepth > 1) {
329 wp = pScreen->whitePixel;
330 bp = pScreen->blackPixel;
331 #ifdef WIN32_not_tog
332 for (i = 0; i < NUM_DESKTOP_COLORS; i++) {
333 if (AllocColor (cmap,
334 &citems[i].red, &citems[i].green, &citems[i].blue,
335 &citems[i].pixel, 0) != Success)
336 return FALSE;
338 #else
339 if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) !=
340 Success) ||
341 (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) !=
342 Success))
343 return FALSE;
344 pScreen->whitePixel = wp;
345 pScreen->blackPixel = bp;
346 #endif
349 (*pScreen->InstallColormap)(cmap);
350 return TRUE;
354 * Default true color bitmasks, should be overridden by
355 * driver
358 #define _RZ(d) ((d + 2) / 3)
359 #define _RS(d) 0
360 #define _RM(d) ((1 << _RZ(d)) - 1)
361 #define _GZ(d) ((d - _RZ(d) + 1) / 2)
362 #define _GS(d) _RZ(d)
363 #define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d))
364 #define _BZ(d) (d - _RZ(d) - _GZ(d))
365 #define _BS(d) (_RZ(d) + _GZ(d))
366 #define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d))
367 #define _CE(d) (1 << _RZ(d))
369 typedef struct _miVisuals {
370 struct _miVisuals *next;
371 int depth;
372 int bitsPerRGB;
373 int visuals;
374 int count;
375 int preferredCVC;
376 Pixel redMask, greenMask, blueMask;
377 } miVisualsRec, *miVisualsPtr;
379 static int miVisualPriority[] = {
380 PseudoColor, GrayScale, StaticColor, TrueColor, DirectColor, StaticGray
383 #define NUM_PRIORITY 6
385 static miVisualsPtr miVisuals;
387 _X_EXPORT void
388 miClearVisualTypes(void)
390 miVisualsPtr v;
392 while ((v = miVisuals)) {
393 miVisuals = v->next;
394 xfree(v);
399 _X_EXPORT Bool
400 miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB,
401 int preferredCVC,
402 Pixel redMask, Pixel greenMask, Pixel blueMask)
404 miVisualsPtr new, *prev, v;
405 int count;
407 new = (miVisualsPtr) xalloc (sizeof *new);
408 if (!new)
409 return FALSE;
410 if (!redMask || !greenMask || !blueMask)
412 redMask = _RM(depth);
413 greenMask = _GM(depth);
414 blueMask = _BM(depth);
416 new->next = 0;
417 new->depth = depth;
418 new->visuals = visuals;
419 new->bitsPerRGB = bitsPerRGB;
420 new->preferredCVC = preferredCVC;
421 new->redMask = redMask;
422 new->greenMask = greenMask;
423 new->blueMask = blueMask;
424 count = (visuals >> 1) & 033333333333;
425 count = visuals - count - ((count >> 1) & 033333333333);
426 count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */
427 new->count = count;
428 for (prev = &miVisuals; (v = *prev); prev = &v->next);
429 *prev = new;
430 return TRUE;
433 _X_EXPORT Bool
434 miSetVisualTypes(int depth, int visuals, int bitsPerRGB, int preferredCVC)
436 return miSetVisualTypesAndMasks (depth, visuals, bitsPerRGB,
437 preferredCVC, 0, 0, 0);
440 _X_EXPORT int
441 miGetDefaultVisualMask(int depth)
443 if (depth > MAX_PSEUDO_DEPTH)
444 return LARGE_VISUALS;
445 else if (depth >= MIN_TRUE_DEPTH)
446 return ALL_VISUALS;
447 else if (depth == 1)
448 return StaticGrayMask;
449 else
450 return SMALL_VISUALS;
453 static Bool
454 miVisualTypesSet (int depth)
456 miVisualsPtr visuals;
458 for (visuals = miVisuals; visuals; visuals = visuals->next)
459 if (visuals->depth == depth)
460 return TRUE;
461 return FALSE;
464 _X_EXPORT Bool
465 miSetPixmapDepths (void)
467 int d, f;
469 /* Add any unlisted depths from the pixmap formats */
470 for (f = 0; f < screenInfo.numPixmapFormats; f++)
472 d = screenInfo.formats[f].depth;
473 if (!miVisualTypesSet (d))
475 if (!miSetVisualTypes (d, 0, 0, -1))
476 return FALSE;
479 return TRUE;
482 _X_EXPORT Bool
483 miInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
484 int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
485 unsigned long sizes, int bitsPerRGB, int preferredVis)
488 if (miInitVisualsProc)
489 return miInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
490 rootDepthp, defaultVisp, sizes, bitsPerRGB,
491 preferredVis);
492 else
493 return FALSE;
497 * Distance to least significant one bit
499 static int
500 maskShift (Pixel p)
502 int s;
504 if (!p) return 0;
505 s = 0;
506 while (!(p & 1))
508 s++;
509 p >>= 1;
511 return s;
515 * Given a list of formats for a screen, create a list
516 * of visuals and depths for the screen which corespond to
517 * the set which can be used with this version of cfb.
520 static Bool
521 miDoInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
522 int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
523 unsigned long sizes, int bitsPerRGB, int preferredVis)
525 int i, j = 0, k;
526 VisualPtr visual;
527 DepthPtr depth;
528 VisualID *vid;
529 int d, b;
530 int f;
531 int ndepth, nvisual;
532 int nvtype;
533 int vtype;
534 miVisualsPtr visuals, nextVisuals;
535 int *preferredCVCs, *prefp;
536 int first_depth;
538 /* none specified, we'll guess from pixmap formats */
539 if (!miVisuals)
541 for (f = 0; f < screenInfo.numPixmapFormats; f++)
543 d = screenInfo.formats[f].depth;
544 b = screenInfo.formats[f].bitsPerPixel;
545 if (sizes & (1 << (b - 1)))
546 vtype = miGetDefaultVisualMask(d);
547 else
548 vtype = 0;
549 if (!miSetVisualTypes (d, vtype, bitsPerRGB, -1))
550 return FALSE;
553 nvisual = 0;
554 ndepth = 0;
555 for (visuals = miVisuals; visuals; visuals = nextVisuals)
557 nextVisuals = visuals->next;
558 ndepth++;
559 nvisual += visuals->count;
561 depth = (DepthPtr) xalloc (ndepth * sizeof (DepthRec));
562 visual = (VisualPtr) xalloc (nvisual * sizeof (VisualRec));
563 preferredCVCs = (int *)xalloc(ndepth * sizeof(int));
564 if (!depth || !visual || !preferredCVCs)
566 xfree (depth);
567 xfree (visual);
568 xfree (preferredCVCs);
569 return FALSE;
571 *depthp = depth;
572 *visualp = visual;
573 *ndepthp = ndepth;
574 *nvisualp = nvisual;
575 prefp = preferredCVCs;
576 for (visuals = miVisuals; visuals; visuals = nextVisuals)
578 nextVisuals = visuals->next;
579 d = visuals->depth;
580 vtype = visuals->visuals;
581 nvtype = visuals->count;
582 *prefp = visuals->preferredCVC;
583 prefp++;
584 vid = NULL;
585 if (nvtype)
587 vid = (VisualID *) xalloc (nvtype * sizeof (VisualID));
588 if (!vid) {
589 xfree(preferredCVCs);
590 return FALSE;
593 depth->depth = d;
594 depth->numVids = nvtype;
595 depth->vids = vid;
596 depth++;
597 for (i = 0; i < NUM_PRIORITY; i++) {
598 if (! (vtype & (1 << miVisualPriority[i])))
599 continue;
600 visual->class = miVisualPriority[i];
601 visual->bitsPerRGBValue = visuals->bitsPerRGB;
602 visual->ColormapEntries = 1 << d;
603 visual->nplanes = d;
604 visual->vid = *vid = FakeClientID (0);
605 switch (visual->class) {
606 case PseudoColor:
607 case GrayScale:
608 case StaticGray:
609 visual->redMask = 0;
610 visual->greenMask = 0;
611 visual->blueMask = 0;
612 visual->offsetRed = 0;
613 visual->offsetGreen = 0;
614 visual->offsetBlue = 0;
615 break;
616 case DirectColor:
617 case TrueColor:
618 visual->ColormapEntries = _CE(d);
619 /* fall through */
620 case StaticColor:
621 visual->redMask = visuals->redMask;
622 visual->greenMask = visuals->greenMask;
623 visual->blueMask = visuals->blueMask;
624 visual->offsetRed = maskShift (visuals->redMask);
625 visual->offsetGreen = maskShift (visuals->greenMask);
626 visual->offsetBlue = maskShift (visuals->blueMask);
628 vid++;
629 visual++;
631 xfree (visuals);
633 miVisuals = NULL;
634 visual = *visualp;
635 depth = *depthp;
638 * if we did not supplyied by a preferred visual class
639 * check if there is a preferred class in one of the depth
640 * structures - if there is, we want to start looking for the
641 * default visual/depth from that depth.
643 first_depth = 0;
644 if (preferredVis < 0 && defaultColorVisualClass < 0 ) {
645 for (i = 0; i < ndepth; i++) {
646 if (preferredCVCs[i] >= 0) {
647 first_depth = i;
648 break;
653 for (i = first_depth; i < ndepth; i++)
655 int prefColorVisualClass = -1;
657 if (defaultColorVisualClass >= 0)
658 prefColorVisualClass = defaultColorVisualClass;
659 else if (preferredVis >= 0)
660 prefColorVisualClass = preferredVis;
661 else if (preferredCVCs[i] >= 0)
662 prefColorVisualClass = preferredCVCs[i];
664 if (*rootDepthp && *rootDepthp != depth[i].depth)
665 continue;
667 for (j = 0; j < depth[i].numVids; j++)
669 for (k = 0; k < nvisual; k++)
670 if (visual[k].vid == depth[i].vids[j])
671 break;
672 if (k == nvisual)
673 continue;
674 if (prefColorVisualClass < 0 ||
675 visual[k].class == prefColorVisualClass)
676 break;
678 if (j != depth[i].numVids)
679 break;
681 if (i == ndepth) {
682 i = 0;
683 j = 0;
685 *rootDepthp = depth[i].depth;
686 *defaultVisp = depth[i].vids[j];
687 xfree(preferredCVCs);
689 return TRUE;
692 void
693 miResetInitVisuals(void)
695 miInitVisualsProc = miDoInitVisuals;