1
/* $Xorg: Color.c,v 1.3 2000/08/17 19:53:27 cpqbld Exp $ */
4
Copyright 1993 by Davor Matic
6
Permission to use, copy, modify, distribute, and sell this software
7
and its documentation for any purpose is hereby granted without fee,
8
provided that the above copyright notice appear in all copies and that
9
both that copyright notice and this permission notice appear in
10
supporting documentation. Davor Matic makes no representations about
11
the suitability of this software for any purpose. It is provided "as
12
is" without express or implied warranty.
17
#include "scrnintstr.h"
19
#include "windowstr.h"
20
#include "colormapst.h"
33
static ColormapPtr InstalledMaps[MAXSCREENS];
35
Bool xnestCreateColormap(pCmap)
41
Pixel red, green, blue;
42
Pixel redInc, greenInc, blueInc;
44
pVisual = pCmap->pVisual;
45
ncolors = pVisual->ColormapEntries;
47
pCmap->devPriv = (pointer)xalloc(sizeof(xnestPrivColormap));
49
xnestColormapPriv(pCmap)->colormap =
50
XCreateColormap(xnestDisplay,
51
xnestDefaultWindows[pCmap->pScreen->myNum],
53
(pVisual->class & DynamicClass) ?
54
AllocAll : AllocNone);
57
switch (pVisual->class) {
58
case StaticGray: /* read only */
59
colors = (XColor *)xalloc(ncolors * sizeof(XColor));
60
for (i = 0; i < ncolors; i++)
62
XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
63
for (i = 0; i < ncolors; i++) {
64
pCmap->red[i].co.local.red = colors[i].red;
65
pCmap->red[i].co.local.green = colors[i].red;
66
pCmap->red[i].co.local.blue = colors[i].red;
71
case StaticColor: /* read only */
72
colors = (XColor *)xalloc(ncolors * sizeof(XColor));
73
for (i = 0; i < ncolors; i++)
75
XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
76
for (i = 0; i < ncolors; i++) {
77
pCmap->red[i].co.local.red = colors[i].red;
78
pCmap->red[i].co.local.green = colors[i].green;
79
pCmap->red[i].co.local.blue = colors[i].blue;
84
case TrueColor: /* read only */
85
colors = (XColor *)xalloc(ncolors * sizeof(XColor));
86
red = green = blue = 0L;
87
redInc = lowbit(pVisual->redMask);
88
greenInc = lowbit(pVisual->greenMask);
89
blueInc = lowbit(pVisual->blueMask);
90
for (i = 0; i < ncolors; i++) {
91
colors[i].pixel = red | green | blue;
93
if (red > pVisual->redMask) red = 0L;
95
if (green > pVisual->greenMask) green = 0L;
97
if (blue > pVisual->blueMask) blue = 0L;
99
XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
100
for (i = 0; i < ncolors; i++) {
101
pCmap->red[i].co.local.red = colors[i].red;
102
pCmap->green[i].co.local.green = colors[i].green;
103
pCmap->blue[i].co.local.blue = colors[i].blue;
108
case GrayScale: /* read and write */
111
case PseudoColor: /* read and write */
114
case DirectColor: /* read and write */
121
void xnestDestroyColormap (pCmap)
124
XFreeColormap(xnestDisplay, xnestColormap(pCmap));
125
xfree(pCmap->devPriv);
128
#define SEARCH_PREDICATE \
129
(xnestWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
131
static int xnestCountInstalledColormapWindows(pWin, ptr)
135
xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *)ptr;
138
for (i = 0; i < icws->numCmapIDs; i++)
139
if (SEARCH_PREDICATE) {
141
return WT_DONTWALKCHILDREN;
144
return WT_WALKCHILDREN;
147
static int xnestGetInstalledColormapWindows(pWin, ptr)
151
xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *)ptr;
154
for (i = 0; i < icws->numCmapIDs; i++)
155
if (SEARCH_PREDICATE) {
156
icws->windows[icws->index++] = xnestWindow(pWin);
157
return WT_DONTWALKCHILDREN;
160
return WT_WALKCHILDREN;
163
static Window *xnestOldInstalledColormapWindows = NULL;
164
static int xnestNumOldInstalledColormapWindows = 0;
166
static Bool xnestSameInstalledColormapWindows(windows, numWindows)
170
if (xnestNumOldInstalledColormapWindows != numWindows)
173
if (xnestOldInstalledColormapWindows == windows)
176
if (xnestOldInstalledColormapWindows == NULL || windows == NULL)
179
if (memcmp(xnestOldInstalledColormapWindows, windows,
180
numWindows * sizeof(Window)))
186
void xnestSetInstalledColormapWindows(pScreen)
189
xnestInstalledColormapWindows icws;
192
icws.cmapIDs = (Colormap *)xalloc(pScreen->maxInstalledCmaps *
194
icws.numCmapIDs = xnestListInstalledColormaps(pScreen, icws.cmapIDs);
196
WalkTree(pScreen, xnestCountInstalledColormapWindows, (pointer)&icws);
197
if (icws.numWindows) {
198
icws.windows = (Window *)xalloc((icws.numWindows + 1) * sizeof(Window));
200
WalkTree(pScreen, xnestGetInstalledColormapWindows, (pointer)&icws);
201
icws.windows[icws.numWindows] = xnestDefaultWindows[pScreen->myNum];
202
numWindows = icws.numWindows + 1;
211
if (!xnestSameInstalledColormapWindows(icws.windows, icws.numWindows)) {
212
if (xnestOldInstalledColormapWindows)
213
xfree(xnestOldInstalledColormapWindows);
218
Window64 *windows = (Window64 *)xalloc(numWindows * sizeof(Window64));
220
for(i = 0; i < numWindows; ++i)
221
windows[i] = icws.windows[i];
222
XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
223
windows, numWindows);
227
XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
228
icws.windows, numWindows);
231
xnestOldInstalledColormapWindows = icws.windows;
232
xnestNumOldInstalledColormapWindows = icws.numWindows;
234
#ifdef DUMB_WINDOW_MANAGERS
236
This code is for dumb window managers.
237
This will only work with default local visual colormaps.
245
pWin = xnestWindowPtr(icws.windows[0]);
246
visual = xnestVisualFromID(pScreen, wVisual(pWin));
248
if (visual == xnestDefaultVisual(pScreen))
249
pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin),
252
pCmap = (ColormapPtr)LookupIDByType(pScreen->defColormap,
255
XSetWindowColormap(xnestDisplay,
256
xnestDefaultWindows[pScreen->myNum],
257
xnestColormap(pCmap));
259
#endif /* DUMB_WINDOW_MANAGERS */
262
if (icws.windows) xfree(icws.windows);
265
void xnestSetScreenSaverColormapWindow(pScreen)
268
if (xnestOldInstalledColormapWindows)
269
xfree(xnestOldInstalledColormapWindows);
275
window = xnestScreenSaverWindows[pScreen->myNum];
276
XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
278
xnestScreenSaverWindows[pScreen->myNum] = window;
281
XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
282
&xnestScreenSaverWindows[pScreen->myNum], 1);
283
#endif /* _XSERVER64 */
285
xnestOldInstalledColormapWindows = NULL;
286
xnestNumOldInstalledColormapWindows = 0;
288
xnestDirectUninstallColormaps(pScreen);
291
void xnestDirectInstallColormaps(pScreen)
295
Colormap pCmapIDs[MAXCMAPS];
297
if (!xnestDoDirectColormaps) return;
299
n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
301
for (i = 0; i < n; i++) {
304
pCmap = (ColormapPtr)LookupIDByType(pCmapIDs[i], RT_COLORMAP);
306
XInstallColormap(xnestDisplay, xnestColormap(pCmap));
310
void xnestDirectUninstallColormaps(pScreen)
314
Colormap pCmapIDs[MAXCMAPS];
316
if (!xnestDoDirectColormaps) return;
318
n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
320
for (i = 0; i < n; i++) {
323
pCmap = (ColormapPtr)LookupIDByType(pCmapIDs[i], RT_COLORMAP);
325
XUninstallColormap(xnestDisplay, xnestColormap(pCmap));
329
void xnestInstallColormap(pCmap)
333
ColormapPtr pOldCmap;
335
index = pCmap->pScreen->myNum;
336
pOldCmap = InstalledMaps[index];
338
if(pCmap != pOldCmap)
340
xnestDirectUninstallColormaps(pCmap->pScreen);
342
/* Uninstall pInstalledMap. Notify all interested parties. */
343
if(pOldCmap != (ColormapPtr)None)
344
WalkTree(pCmap->pScreen, TellLostMap, (pointer)&pOldCmap->mid);
346
InstalledMaps[index] = pCmap;
347
WalkTree(pCmap->pScreen, TellGainedMap, (pointer)&pCmap->mid);
349
xnestSetInstalledColormapWindows(pCmap->pScreen);
350
xnestDirectInstallColormaps(pCmap->pScreen);
354
void xnestUninstallColormap(pCmap)
358
ColormapPtr pCurCmap;
360
index = pCmap->pScreen->myNum;
361
pCurCmap = InstalledMaps[index];
363
if(pCmap == pCurCmap)
365
if (pCmap->mid != pCmap->pScreen->defColormap)
367
pCurCmap = (ColormapPtr)LookupIDByType(pCmap->pScreen->defColormap,
369
(*pCmap->pScreen->InstallColormap)(pCurCmap);
374
static Bool xnestInstalledDefaultColormap = False;
376
int xnestListInstalledColormaps(pScreen, pCmapIDs)
380
if (xnestInstalledDefaultColormap) {
381
*pCmapIDs = InstalledMaps[pScreen->myNum]->mid;
388
void xnestStoreColors(pCmap, nColors, pColors)
393
if (pCmap->pVisual->class & DynamicClass)
397
XColor *pColors64 = (XColor *)xalloc(nColors * sizeof(XColor) );
399
for(i = 0; i < nColors; ++i)
401
pColors64[i].pixel = pColors[i].pixel;
402
pColors64[i].red = pColors[i].red;
403
pColors64[i].green = pColors[i].green;
404
pColors64[i].blue = pColors[i].blue;
405
pColors64[i].flags = pColors[i].flags;
407
XStoreColors(xnestDisplay, xnestColormap(pCmap), pColors64, nColors);
411
XStoreColors(xnestDisplay, xnestColormap(pCmap),
412
(XColor *)pColors, nColors);
416
void xnestResolveColor(pRed, pGreen, pBlue, pVisual)
417
unsigned short *pRed;
418
unsigned short *pGreen;
419
unsigned short *pBlue;
425
shift = 16 - pVisual->bitsPerRGBValue;
426
lim = (1 << pVisual->bitsPerRGBValue) - 1;
428
if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor))
430
/* rescale to rgb bits */
431
*pRed = ((*pRed >> shift) * 65535) / lim;
432
*pGreen = ((*pGreen >> shift) * 65535) / lim;
433
*pBlue = ((*pBlue >> shift) * 65535) / lim;
435
else if (pVisual->class == GrayScale)
437
/* rescale to gray then rgb bits */
438
*pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
439
*pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
441
else if (pVisual->class == StaticGray)
445
limg = pVisual->ColormapEntries - 1;
446
/* rescale to gray then [0..limg] then [0..65535] then rgb bits */
447
*pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
448
*pRed = ((((*pRed * (limg + 1))) >> 16) * 65535) / limg;
449
*pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
453
unsigned limr, limg, limb;
455
limr = pVisual->redMask >> pVisual->offsetRed;
456
limg = pVisual->greenMask >> pVisual->offsetGreen;
457
limb = pVisual->blueMask >> pVisual->offsetBlue;
458
/* rescale to [0..limN] then [0..65535] then rgb bits */
459
*pRed = ((((((*pRed * (limr + 1)) >> 16) *
460
65535) / limr) >> shift) * 65535) / lim;
461
*pGreen = ((((((*pGreen * (limg + 1)) >> 16) *
462
65535) / limg) >> shift) * 65535) / lim;
463
*pBlue = ((((((*pBlue * (limb + 1)) >> 16) *
464
65535) / limb) >> shift) * 65535) / lim;
468
Bool xnestCreateDefaultColormap(pScreen)
473
unsigned short zero = 0, ones = 0xFFFF;
476
for (pVisual = pScreen->visuals;
477
pVisual->vid != pScreen->rootVisual;
480
if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &pCmap,
481
(pVisual->class & DynamicClass) ? AllocNone : AllocAll, 0)
485
wp = pScreen->whitePixel;
486
bp = pScreen->blackPixel;
487
if ((AllocColor(pCmap, &ones, &ones, &ones, &wp, 0) !=
489
(AllocColor(pCmap, &zero, &zero, &zero, &bp, 0) !=
492
pScreen->whitePixel = wp;
493
pScreen->blackPixel = bp;
494
(*pScreen->InstallColormap)(pCmap);
496
xnestInstalledDefaultColormap = True;