1 /************************************************************
2 Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
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
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>
42 #include <X11/Xproto.h>
43 #include "scrnintstr.h"
44 #include "colormapst.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
;
58 miListInstalledColormaps(ScreenPtr pScreen
, Colormap
*pmaps
)
60 if (miInstalledMaps
[pScreen
->myNum
]) {
61 *pmaps
= miInstalledMaps
[pScreen
->myNum
]->mid
;
68 miInstallColormap(ColormapPtr pmap
)
70 int index
= pmap
->pScreen
->myNum
;
71 ColormapPtr oldpmap
= miInstalledMaps
[index
];
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
);
80 miInstalledMaps
[index
] = pmap
;
81 WalkTree(pmap
->pScreen
, TellGainedMap
, (char *)&pmap
->mid
);
87 miUninstallColormap(ColormapPtr pmap
)
89 int index
= pmap
->pScreen
->myNum
;
90 ColormapPtr curpmap
= miInstalledMaps
[index
];
94 if (pmap
->mid
!= pmap
->pScreen
->defColormap
)
96 curpmap
= (ColormapPtr
) LookupIDByType(pmap
->pScreen
->defColormap
,
98 (*pmap
->pScreen
->InstallColormap
)(curpmap
);
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
;
118 /* rescale to rgb bits */
119 *pred
= ((*pred
>> shift
) * 65535) / lim
;
120 *pgreen
= ((*pgreen
>> shift
) * 65535) / lim
;
121 *pblue
= ((*pblue
>> shift
) * 65535) / lim
;
126 miInitializeColormap(ColormapPtr pmap
)
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
)
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
;
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) \
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; \
211 miExpandDirectColors(ColormapPtr pmap
, int ndef
, xColorItem
*indefs
,
214 int red
, green
, blue
;
215 int maxred
, maxgreen
, maxblue
;
216 int stepred
, stepgreen
, stepblue
;
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
;
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
)
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
)
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
)
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"
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]
307 unsigned short zero
= 0, ones
= 0xFFFF;
314 for (pVisual
= pScreen
->visuals
;
315 pVisual
->vid
!= pScreen
->rootVisual
;
319 if (pScreen
->rootDepth
== 1 || (pVisual
->class & DynamicClass
))
320 alloctype
= AllocNone
;
322 alloctype
= AllocAll
;
324 if (CreateColormap(pScreen
->defColormap
, pScreen
, pVisual
, &cmap
,
325 alloctype
, 0) != Success
)
328 if (pScreen
->rootDepth
> 1) {
329 wp
= pScreen
->whitePixel
;
330 bp
= pScreen
->blackPixel
;
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
)
339 if ((AllocColor(cmap
, &ones
, &ones
, &ones
, &wp
, 0) !=
341 (AllocColor(cmap
, &zero
, &zero
, &zero
, &bp
, 0) !=
344 pScreen
->whitePixel
= wp
;
345 pScreen
->blackPixel
= bp
;
349 (*pScreen
->InstallColormap
)(cmap
);
354 * Default true color bitmasks, should be overridden by
358 #define _RZ(d) ((d + 2) / 3)
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
;
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
;
388 miClearVisualTypes(void)
392 while ((v
= miVisuals
)) {
400 miSetVisualTypesAndMasks(int depth
, int visuals
, int bitsPerRGB
,
402 Pixel redMask
, Pixel greenMask
, Pixel blueMask
)
404 miVisualsPtr
new, *prev
, v
;
407 new = (miVisualsPtr
) xalloc (sizeof *new);
410 if (!redMask
|| !greenMask
|| !blueMask
)
412 redMask
= _RM(depth
);
413 greenMask
= _GM(depth
);
414 blueMask
= _BM(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 */
428 for (prev
= &miVisuals
; (v
= *prev
); prev
= &v
->next
);
434 miSetVisualTypes(int depth
, int visuals
, int bitsPerRGB
, int preferredCVC
)
436 return miSetVisualTypesAndMasks (depth
, visuals
, bitsPerRGB
,
437 preferredCVC
, 0, 0, 0);
441 miGetDefaultVisualMask(int depth
)
443 if (depth
> MAX_PSEUDO_DEPTH
)
444 return LARGE_VISUALS
;
445 else if (depth
>= MIN_TRUE_DEPTH
)
448 return StaticGrayMask
;
450 return SMALL_VISUALS
;
454 miVisualTypesSet (int depth
)
456 miVisualsPtr visuals
;
458 for (visuals
= miVisuals
; visuals
; visuals
= visuals
->next
)
459 if (visuals
->depth
== depth
)
465 miSetPixmapDepths (void)
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))
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
,
497 * Distance to least significant one bit
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.
521 miDoInitVisuals(VisualPtr
*visualp
, DepthPtr
*depthp
, int *nvisualp
,
522 int *ndepthp
, int *rootDepthp
, VisualID
*defaultVisp
,
523 unsigned long sizes
, int bitsPerRGB
, int preferredVis
)
534 miVisualsPtr visuals
, nextVisuals
;
535 int *preferredCVCs
, *prefp
;
538 /* none specified, we'll guess from pixmap formats */
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
);
549 if (!miSetVisualTypes (d
, vtype
, bitsPerRGB
, -1))
555 for (visuals
= miVisuals
; visuals
; visuals
= nextVisuals
)
557 nextVisuals
= visuals
->next
;
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
)
568 xfree (preferredCVCs
);
575 prefp
= preferredCVCs
;
576 for (visuals
= miVisuals
; visuals
; visuals
= nextVisuals
)
578 nextVisuals
= visuals
->next
;
580 vtype
= visuals
->visuals
;
581 nvtype
= visuals
->count
;
582 *prefp
= visuals
->preferredCVC
;
587 vid
= (VisualID
*) xalloc (nvtype
* sizeof (VisualID
));
589 xfree(preferredCVCs
);
594 depth
->numVids
= nvtype
;
597 for (i
= 0; i
< NUM_PRIORITY
; i
++) {
598 if (! (vtype
& (1 << miVisualPriority
[i
])))
600 visual
->class = miVisualPriority
[i
];
601 visual
->bitsPerRGBValue
= visuals
->bitsPerRGB
;
602 visual
->ColormapEntries
= 1 << d
;
604 visual
->vid
= *vid
= FakeClientID (0);
605 switch (visual
->class) {
610 visual
->greenMask
= 0;
611 visual
->blueMask
= 0;
612 visual
->offsetRed
= 0;
613 visual
->offsetGreen
= 0;
614 visual
->offsetBlue
= 0;
618 visual
->ColormapEntries
= _CE(d
);
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
);
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.
644 if (preferredVis
< 0 && defaultColorVisualClass
< 0 ) {
645 for (i
= 0; i
< ndepth
; i
++) {
646 if (preferredCVCs
[i
] >= 0) {
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
)
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
])
674 if (prefColorVisualClass
< 0 ||
675 visual
[k
].class == prefColorVisualClass
)
678 if (j
!= depth
[i
].numVids
)
685 *rootDepthp
= depth
[i
].depth
;
686 *defaultVisp
= depth
[i
].vids
[j
];
687 xfree(preferredCVCs
);
693 miResetInitVisuals(void)
695 miInitVisualsProc
= miDoInitVisuals
;