2 * Copyright (c) 1987, Oracle and/or its affiliates. All rights reserved.
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:
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
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.
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.
30 #ifdef HAVE_DIX_CONFIG_H
31 #include <dix-config.h>
35 #include <X11/Xproto.h>
36 #include "scrnintstr.h"
37 #include "colormapst.h"
42 DevPrivateKeyRec micmapScrPrivateKeyRec
;
45 miListInstalledColormaps(ScreenPtr pScreen
, Colormap
* pmaps
)
47 if (GetInstalledmiColormap(pScreen
)) {
48 *pmaps
= GetInstalledmiColormap(pScreen
)->mid
;
55 miInstallColormap(ColormapPtr pmap
)
57 ColormapPtr oldpmap
= GetInstalledmiColormap(pmap
->pScreen
);
59 if (pmap
!= oldpmap
) {
60 /* Uninstall pInstalledMap. No hardware changes required, just
61 * notify all interested parties. */
62 if (oldpmap
!= (ColormapPtr
) None
)
63 WalkTree(pmap
->pScreen
, TellLostMap
, (char *) &oldpmap
->mid
);
65 SetInstalledmiColormap(pmap
->pScreen
, pmap
);
66 WalkTree(pmap
->pScreen
, TellGainedMap
, (char *) &pmap
->mid
);
72 miUninstallColormap(ColormapPtr pmap
)
74 ColormapPtr curpmap
= GetInstalledmiColormap(pmap
->pScreen
);
76 if (pmap
== curpmap
) {
77 if (pmap
->mid
!= pmap
->pScreen
->defColormap
) {
78 dixLookupResourceByType((pointer
*) &curpmap
,
79 pmap
->pScreen
->defColormap
,
80 RT_COLORMAP
, serverClient
, DixUseAccess
);
81 (*pmap
->pScreen
->InstallColormap
) (curpmap
);
87 miResolveColor(unsigned short *pred
, unsigned short *pgreen
,
88 unsigned short *pblue
, VisualPtr pVisual
)
90 int shift
= 16 - pVisual
->bitsPerRGBValue
;
91 unsigned lim
= (1 << pVisual
->bitsPerRGBValue
) - 1;
93 if ((pVisual
->class | DynamicClass
) == GrayScale
) {
94 /* rescale to gray then rgb bits */
95 *pred
= (30L * *pred
+ 59L * *pgreen
+ 11L * *pblue
) / 100;
96 *pblue
= *pgreen
= *pred
= ((*pred
>> shift
) * 65535) / lim
;
99 /* rescale to rgb bits */
100 *pred
= ((*pred
>> shift
) * 65535) / lim
;
101 *pgreen
= ((*pgreen
>> shift
) * 65535) / lim
;
102 *pblue
= ((*pblue
>> shift
) * 65535) / lim
;
107 miInitializeColormap(ColormapPtr pmap
)
111 unsigned lim
, maxent
, shift
;
113 pVisual
= pmap
->pVisual
;
114 lim
= (1 << pVisual
->bitsPerRGBValue
) - 1;
115 shift
= 16 - pVisual
->bitsPerRGBValue
;
116 maxent
= pVisual
->ColormapEntries
- 1;
117 if (pVisual
->class == TrueColor
) {
118 unsigned limr
, limg
, limb
;
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
;
133 else if (pVisual
->class == StaticColor
) {
134 unsigned limr
, limg
, limb
;
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
;
152 else if (pVisual
->class == StaticGray
) {
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
)
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
;
164 /* When simulating DirectColor on PseudoColor hardware, multiple
165 entries of the colormap must be updated
168 #define AddElement(mask) { \
169 pixel = red | green | blue; \
170 for (i = 0; i < nresult; i++) \
171 if (outdefs[i].pixel == pixel) \
176 outdefs[i].pixel = pixel; \
177 outdefs[i].flags = 0; \
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; \
186 miExpandDirectColors(ColormapPtr pmap
, int ndef
, xColorItem
* indefs
,
187 xColorItem
* outdefs
)
189 int red
, green
, blue
;
190 int maxred
, maxgreen
, maxblue
;
191 int stepred
, stepgreen
, stepblue
;
197 pVisual
= pmap
->pVisual
;
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
;
206 for (; ndef
--; indefs
++) {
207 if (indefs
->flags
& DoRed
) {
208 red
= indefs
->pixel
& pVisual
->redMask
;
209 for (green
= 0; green
<= maxgreen
; green
+= stepgreen
) {
210 for (blue
= 0; blue
<= maxblue
; blue
+= stepblue
) {
215 if (indefs
->flags
& DoGreen
) {
216 green
= indefs
->pixel
& pVisual
->greenMask
;
217 for (red
= 0; red
<= maxred
; red
+= stepred
) {
218 for (blue
= 0; blue
<= maxblue
; blue
+= stepblue
) {
223 if (indefs
->flags
& DoBlue
) {
224 blue
= indefs
->pixel
& pVisual
->blueMask
;
225 for (red
= 0; red
<= maxred
; red
+= stepred
) {
226 for (green
= 0; green
<= maxgreen
; green
+= stepgreen
) {
236 miCreateDefColormap(ScreenPtr pScreen
)
239 * In the following sources PC X server vendors may want to delete
240 * "_not_tog" from "#ifdef WIN32_not_tog"
244 * these are the MS-Windows desktop colors, adjusted for X's 16-bit
245 * color specifications.
247 static xColorItem citems
[] = {
249 {1, 0x8000, 0, 0, 0, 0},
250 {2, 0, 0x8000, 0, 0, 0},
251 {3, 0x8000, 0x8000, 0, 0, 0},
252 {4, 0, 0, 0x8000, 0, 0},
253 {5, 0x8000, 0, 0x8000, 0, 0},
254 {6, 0, 0x8000, 0x8000, 0, 0},
255 {7, 0xc000, 0xc000, 0xc000, 0, 0},
256 {8, 0xc000, 0xdc00, 0xc000, 0, 0},
257 {9, 0xa600, 0xca00, 0xf000, 0, 0},
258 {246, 0xff00, 0xfb00, 0xf000, 0, 0},
259 {247, 0xa000, 0xa000, 0xa400, 0, 0},
260 {248, 0x8000, 0x8000, 0x8000, 0, 0},
261 {249, 0xff00, 0, 0, 0, 0},
262 {250, 0, 0xff00, 0, 0, 0},
263 {251, 0xff00, 0xff00, 0, 0, 0},
264 {252, 0, 0, 0xff00, 0, 0},
265 {253, 0xff00, 0, 0xff00, 0, 0},
266 {254, 0, 0xff00, 0xff00, 0, 0},
267 {255, 0xff00, 0xff00, 0xff00, 0, 0}
269 #define NUM_DESKTOP_COLORS sizeof citems / sizeof citems[0]
272 unsigned short zero
= 0, ones
= 0xFFFF;
279 if (!dixRegisterPrivateKey(&micmapScrPrivateKeyRec
, PRIVATE_SCREEN
, 0))
282 for (pVisual
= pScreen
->visuals
;
283 pVisual
->vid
!= pScreen
->rootVisual
; pVisual
++);
285 if (pScreen
->rootDepth
== 1 || (pVisual
->class & DynamicClass
))
286 alloctype
= AllocNone
;
288 alloctype
= AllocAll
;
290 if (CreateColormap(pScreen
->defColormap
, pScreen
, pVisual
, &cmap
,
291 alloctype
, 0) != Success
)
294 if (pScreen
->rootDepth
> 1) {
295 wp
= pScreen
->whitePixel
;
296 bp
= pScreen
->blackPixel
;
298 for (i
= 0; i
< NUM_DESKTOP_COLORS
; i
++) {
300 &citems
[i
].red
, &citems
[i
].green
, &citems
[i
].blue
,
301 &citems
[i
].pixel
, 0) != Success
)
305 if ((AllocColor(cmap
, &ones
, &ones
, &ones
, &wp
, 0) !=
307 (AllocColor(cmap
, &zero
, &zero
, &zero
, &bp
, 0) != Success
))
309 pScreen
->whitePixel
= wp
;
310 pScreen
->blackPixel
= bp
;
314 (*pScreen
->InstallColormap
) (cmap
);
319 * Default true color bitmasks, should be overridden by
323 #define _RZ(d) ((d + 2) / 3)
325 #define _RM(d) ((1 << _RZ(d)) - 1)
326 #define _GZ(d) ((d - _RZ(d) + 1) / 2)
327 #define _GS(d) _RZ(d)
328 #define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d))
329 #define _BZ(d) (d - _RZ(d) - _GZ(d))
330 #define _BS(d) (_RZ(d) + _GZ(d))
331 #define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d))
332 #define _CE(d) (1 << _RZ(d))
334 typedef struct _miVisuals
{
335 struct _miVisuals
*next
;
341 Pixel redMask
, greenMask
, blueMask
;
342 } miVisualsRec
, *miVisualsPtr
;
344 static int miVisualPriority
[] = {
345 PseudoColor
, GrayScale
, StaticColor
, TrueColor
, DirectColor
, StaticGray
348 #define NUM_PRIORITY 6
350 static miVisualsPtr miVisuals
;
353 miClearVisualTypes(void)
357 while ((v
= miVisuals
)) {
364 miSetVisualTypesAndMasks(int depth
, int visuals
, int bitsPerRGB
,
366 Pixel redMask
, Pixel greenMask
, Pixel blueMask
)
368 miVisualsPtr
new, *prev
, v
;
371 new = malloc(sizeof *new);
374 if (!redMask
|| !greenMask
|| !blueMask
) {
375 redMask
= _RM(depth
);
376 greenMask
= _GM(depth
);
377 blueMask
= _BM(depth
);
381 new->visuals
= visuals
;
382 new->bitsPerRGB
= bitsPerRGB
;
383 new->preferredCVC
= preferredCVC
;
384 new->redMask
= redMask
;
385 new->greenMask
= greenMask
;
386 new->blueMask
= blueMask
;
387 count
= (visuals
>> 1) & 033333333333;
388 count
= visuals
- count
- ((count
>> 1) & 033333333333);
389 count
= (((count
+ (count
>> 3)) & 030707070707) % 077); /* HAKMEM 169 */
391 for (prev
= &miVisuals
; (v
= *prev
); prev
= &v
->next
);
397 miSetVisualTypes(int depth
, int visuals
, int bitsPerRGB
, int preferredCVC
)
399 return miSetVisualTypesAndMasks(depth
, visuals
, bitsPerRGB
,
400 preferredCVC
, 0, 0, 0);
404 miGetDefaultVisualMask(int depth
)
406 if (depth
> MAX_PSEUDO_DEPTH
)
407 return LARGE_VISUALS
;
408 else if (depth
>= MIN_TRUE_DEPTH
)
411 return StaticGrayMask
;
413 return SMALL_VISUALS
;
417 miVisualTypesSet(int depth
)
419 miVisualsPtr visuals
;
421 for (visuals
= miVisuals
; visuals
; visuals
= visuals
->next
)
422 if (visuals
->depth
== depth
)
428 miSetPixmapDepths(void)
432 /* Add any unlisted depths from the pixmap formats */
433 for (f
= 0; f
< screenInfo
.numPixmapFormats
; f
++) {
434 d
= screenInfo
.formats
[f
].depth
;
435 if (!miVisualTypesSet(d
)) {
436 if (!miSetVisualTypes(d
, 0, 0, -1))
444 * Distance to least significant one bit
462 * Given a list of formats for a screen, create a list
463 * of visuals and depths for the screen which corespond to
464 * the set which can be used with this version of cfb.
468 miInitVisuals(VisualPtr
* visualp
, DepthPtr
* depthp
, int *nvisualp
,
469 int *ndepthp
, int *rootDepthp
, VisualID
* defaultVisp
,
470 unsigned long sizes
, int bitsPerRGB
, int preferredVis
)
481 miVisualsPtr visuals
, nextVisuals
;
482 int *preferredCVCs
, *prefp
;
485 /* none specified, we'll guess from pixmap formats */
487 for (f
= 0; f
< screenInfo
.numPixmapFormats
; f
++) {
488 d
= screenInfo
.formats
[f
].depth
;
489 b
= screenInfo
.formats
[f
].bitsPerPixel
;
490 if (sizes
& (1 << (b
- 1)))
491 vtype
= miGetDefaultVisualMask(d
);
494 if (!miSetVisualTypes(d
, vtype
, bitsPerRGB
, -1))
500 for (visuals
= miVisuals
; visuals
; visuals
= nextVisuals
) {
501 nextVisuals
= visuals
->next
;
503 nvisual
+= visuals
->count
;
505 depth
= malloc(ndepth
* sizeof(DepthRec
));
506 visual
= malloc(nvisual
* sizeof(VisualRec
));
507 preferredCVCs
= malloc(ndepth
* sizeof(int));
508 if (!depth
|| !visual
|| !preferredCVCs
) {
518 prefp
= preferredCVCs
;
519 for (visuals
= miVisuals
; visuals
; visuals
= nextVisuals
) {
520 nextVisuals
= visuals
->next
;
522 vtype
= visuals
->visuals
;
523 nvtype
= visuals
->count
;
524 *prefp
= visuals
->preferredCVC
;
528 vid
= malloc(nvtype
* sizeof(VisualID
));
537 depth
->numVids
= nvtype
;
540 for (i
= 0; i
< NUM_PRIORITY
; i
++) {
541 if (!(vtype
& (1 << miVisualPriority
[i
])))
543 visual
->class = miVisualPriority
[i
];
544 visual
->bitsPerRGBValue
= visuals
->bitsPerRGB
;
545 visual
->ColormapEntries
= 1 << d
;
547 visual
->vid
= *vid
= FakeClientID(0);
548 switch (visual
->class) {
553 visual
->greenMask
= 0;
554 visual
->blueMask
= 0;
555 visual
->offsetRed
= 0;
556 visual
->offsetGreen
= 0;
557 visual
->offsetBlue
= 0;
561 visual
->ColormapEntries
= _CE(d
);
564 visual
->redMask
= visuals
->redMask
;
565 visual
->greenMask
= visuals
->greenMask
;
566 visual
->blueMask
= visuals
->blueMask
;
567 visual
->offsetRed
= maskShift(visuals
->redMask
);
568 visual
->offsetGreen
= maskShift(visuals
->greenMask
);
569 visual
->offsetBlue
= maskShift(visuals
->blueMask
);
581 * if we did not supplyied by a preferred visual class
582 * check if there is a preferred class in one of the depth
583 * structures - if there is, we want to start looking for the
584 * default visual/depth from that depth.
587 if (preferredVis
< 0 && defaultColorVisualClass
< 0) {
588 for (i
= 0; i
< ndepth
; i
++) {
589 if (preferredCVCs
[i
] >= 0) {
596 for (i
= first_depth
; i
< ndepth
; i
++) {
597 int prefColorVisualClass
= -1;
599 if (defaultColorVisualClass
>= 0)
600 prefColorVisualClass
= defaultColorVisualClass
;
601 else if (preferredVis
>= 0)
602 prefColorVisualClass
= preferredVis
;
603 else if (preferredCVCs
[i
] >= 0)
604 prefColorVisualClass
= preferredCVCs
[i
];
606 if (*rootDepthp
&& *rootDepthp
!= depth
[i
].depth
)
609 for (j
= 0; j
< depth
[i
].numVids
; j
++) {
610 for (k
= 0; k
< nvisual
; k
++)
611 if (visual
[k
].vid
== depth
[i
].vids
[j
])
615 if (prefColorVisualClass
< 0 ||
616 visual
[k
].class == prefColorVisualClass
)
619 if (j
!= depth
[i
].numVids
)
626 *rootDepthp
= depth
[i
].depth
;
627 *defaultVisp
= depth
[i
].vids
[j
];