3 Copyright 1993 by Davor Matic
5 Permission to use, copy, modify, distribute, and sell this software
6 and its documentation for any purpose is hereby granted without fee,
7 provided that the above copyright notice appear in all copies and that
8 both that copyright notice and this permission notice appear in
9 supporting documentation. Davor Matic makes no representations about
10 the suitability of this software for any purpose. It is provided "as
11 is" without express or implied warranty.
15 #ifdef HAVE_XNEST_CONFIG_H
16 #include <xnest-config.h>
20 #include <X11/Xproto.h>
21 #include "scrnintstr.h"
23 #include "windowstr.h"
24 #include "colormapst.h"
36 DevPrivateKeyRec xnestColormapPrivateKeyRec
;
38 static DevPrivateKeyRec cmapScrPrivateKeyRec
;
40 #define cmapScrPrivateKey (&cmapScrPrivateKeyRec)
42 #define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
43 #define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
46 xnestCreateColormap(ColormapPtr pCmap
)
51 Pixel red
, green
, blue
;
52 Pixel redInc
, greenInc
, blueInc
;
54 pVisual
= pCmap
->pVisual
;
55 ncolors
= pVisual
->ColormapEntries
;
57 xnestColormapPriv(pCmap
)->colormap
=
58 XCreateColormap(xnestDisplay
,
59 xnestDefaultWindows
[pCmap
->pScreen
->myNum
],
61 (pVisual
->class & DynamicClass
) ? AllocAll
: AllocNone
);
63 switch (pVisual
->class) {
64 case StaticGray
: /* read only */
65 colors
= (XColor
*) malloc(ncolors
* sizeof(XColor
));
66 for (i
= 0; i
< ncolors
; i
++)
68 XQueryColors(xnestDisplay
, xnestColormap(pCmap
), colors
, ncolors
);
69 for (i
= 0; i
< ncolors
; i
++) {
70 pCmap
->red
[i
].co
.local
.red
= colors
[i
].red
;
71 pCmap
->red
[i
].co
.local
.green
= colors
[i
].red
;
72 pCmap
->red
[i
].co
.local
.blue
= colors
[i
].red
;
77 case StaticColor
: /* read only */
78 colors
= (XColor
*) malloc(ncolors
* sizeof(XColor
));
79 for (i
= 0; i
< ncolors
; i
++)
81 XQueryColors(xnestDisplay
, xnestColormap(pCmap
), colors
, ncolors
);
82 for (i
= 0; i
< ncolors
; i
++) {
83 pCmap
->red
[i
].co
.local
.red
= colors
[i
].red
;
84 pCmap
->red
[i
].co
.local
.green
= colors
[i
].green
;
85 pCmap
->red
[i
].co
.local
.blue
= colors
[i
].blue
;
90 case TrueColor
: /* read only */
91 colors
= (XColor
*) malloc(ncolors
* sizeof(XColor
));
92 red
= green
= blue
= 0L;
93 redInc
= lowbit(pVisual
->redMask
);
94 greenInc
= lowbit(pVisual
->greenMask
);
95 blueInc
= lowbit(pVisual
->blueMask
);
96 for (i
= 0; i
< ncolors
; i
++) {
97 colors
[i
].pixel
= red
| green
| blue
;
99 if (red
> pVisual
->redMask
)
102 if (green
> pVisual
->greenMask
)
105 if (blue
> pVisual
->blueMask
)
108 XQueryColors(xnestDisplay
, xnestColormap(pCmap
), colors
, ncolors
);
109 for (i
= 0; i
< ncolors
; i
++) {
110 pCmap
->red
[i
].co
.local
.red
= colors
[i
].red
;
111 pCmap
->green
[i
].co
.local
.green
= colors
[i
].green
;
112 pCmap
->blue
[i
].co
.local
.blue
= colors
[i
].blue
;
117 case GrayScale
: /* read and write */
120 case PseudoColor
: /* read and write */
123 case DirectColor
: /* read and write */
131 xnestDestroyColormap(ColormapPtr pCmap
)
133 XFreeColormap(xnestDisplay
, xnestColormap(pCmap
));
136 #define SEARCH_PREDICATE \
137 (xnestWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
140 xnestCountInstalledColormapWindows(WindowPtr pWin
, pointer ptr
)
142 xnestInstalledColormapWindows
*icws
= (xnestInstalledColormapWindows
*) ptr
;
145 for (i
= 0; i
< icws
->numCmapIDs
; i
++)
146 if (SEARCH_PREDICATE
) {
148 return WT_DONTWALKCHILDREN
;
151 return WT_WALKCHILDREN
;
155 xnestGetInstalledColormapWindows(WindowPtr pWin
, pointer ptr
)
157 xnestInstalledColormapWindows
*icws
= (xnestInstalledColormapWindows
*) ptr
;
160 for (i
= 0; i
< icws
->numCmapIDs
; i
++)
161 if (SEARCH_PREDICATE
) {
162 icws
->windows
[icws
->index
++] = xnestWindow(pWin
);
163 return WT_DONTWALKCHILDREN
;
166 return WT_WALKCHILDREN
;
169 static Window
*xnestOldInstalledColormapWindows
= NULL
;
170 static int xnestNumOldInstalledColormapWindows
= 0;
173 xnestSameInstalledColormapWindows(Window
*windows
, int numWindows
)
175 if (xnestNumOldInstalledColormapWindows
!= numWindows
)
178 if (xnestOldInstalledColormapWindows
== windows
)
181 if (xnestOldInstalledColormapWindows
== NULL
|| windows
== NULL
)
184 if (memcmp(xnestOldInstalledColormapWindows
, windows
,
185 numWindows
* sizeof(Window
)))
192 xnestSetInstalledColormapWindows(ScreenPtr pScreen
)
194 xnestInstalledColormapWindows icws
;
197 icws
.cmapIDs
= (Colormap
*) malloc(pScreen
->maxInstalledCmaps
*
199 icws
.numCmapIDs
= xnestListInstalledColormaps(pScreen
, icws
.cmapIDs
);
201 WalkTree(pScreen
, xnestCountInstalledColormapWindows
, (pointer
) &icws
);
202 if (icws
.numWindows
) {
204 (Window
*) malloc((icws
.numWindows
+ 1) * sizeof(Window
));
206 WalkTree(pScreen
, xnestGetInstalledColormapWindows
, (pointer
) &icws
);
207 icws
.windows
[icws
.numWindows
] = xnestDefaultWindows
[pScreen
->myNum
];
208 numWindows
= icws
.numWindows
+ 1;
217 if (!xnestSameInstalledColormapWindows(icws
.windows
, icws
.numWindows
)) {
218 free(xnestOldInstalledColormapWindows
);
224 (Window64
*) malloc(numWindows
* sizeof(Window64
));
226 for (i
= 0; i
< numWindows
; ++i
)
227 windows
[i
] = icws
.windows
[i
];
228 XSetWMColormapWindows(xnestDisplay
,
229 xnestDefaultWindows
[pScreen
->myNum
], windows
,
234 XSetWMColormapWindows(xnestDisplay
, xnestDefaultWindows
[pScreen
->myNum
],
235 icws
.windows
, numWindows
);
238 xnestOldInstalledColormapWindows
= icws
.windows
;
239 xnestNumOldInstalledColormapWindows
= icws
.numWindows
;
241 #ifdef DUMB_WINDOW_MANAGERS
243 This code is for dumb window managers.
244 This will only work with default local visual colormaps.
246 if (icws
.numWindows
) {
251 pWin
= xnestWindowPtr(icws
.windows
[0]);
252 visual
= xnestVisualFromID(pScreen
, wVisual(pWin
));
254 if (visual
== xnestDefaultVisual(pScreen
))
255 dixLookupResourceByType((pointer
*) &pCmap
, wColormap(pWin
),
256 RT_COLORMAP
, serverClient
,
259 dixLookupResourceByType((pointer
*) &pCmap
,
260 pScreen
->defColormap
, RT_COLORMAP
,
261 serverClient
, DixUseAccess
);
263 XSetWindowColormap(xnestDisplay
,
264 xnestDefaultWindows
[pScreen
->myNum
],
265 xnestColormap(pCmap
));
267 #endif /* DUMB_WINDOW_MANAGERS */
274 xnestSetScreenSaverColormapWindow(ScreenPtr pScreen
)
276 free(xnestOldInstalledColormapWindows
);
282 window
= xnestScreenSaverWindows
[pScreen
->myNum
];
283 XSetWMColormapWindows(xnestDisplay
, xnestDefaultWindows
[pScreen
->myNum
],
285 xnestScreenSaverWindows
[pScreen
->myNum
] = window
;
288 XSetWMColormapWindows(xnestDisplay
, xnestDefaultWindows
[pScreen
->myNum
],
289 &xnestScreenSaverWindows
[pScreen
->myNum
], 1);
290 #endif /* _XSERVER64 */
292 xnestOldInstalledColormapWindows
= NULL
;
293 xnestNumOldInstalledColormapWindows
= 0;
295 xnestDirectUninstallColormaps(pScreen
);
299 xnestDirectInstallColormaps(ScreenPtr pScreen
)
302 Colormap pCmapIDs
[MAXCMAPS
];
304 if (!xnestDoDirectColormaps
)
307 n
= (*pScreen
->ListInstalledColormaps
) (pScreen
, pCmapIDs
);
309 for (i
= 0; i
< n
; i
++) {
312 dixLookupResourceByType((pointer
*) &pCmap
, pCmapIDs
[i
], RT_COLORMAP
,
313 serverClient
, DixInstallAccess
);
315 XInstallColormap(xnestDisplay
, xnestColormap(pCmap
));
320 xnestDirectUninstallColormaps(ScreenPtr pScreen
)
323 Colormap pCmapIDs
[MAXCMAPS
];
325 if (!xnestDoDirectColormaps
)
328 n
= (*pScreen
->ListInstalledColormaps
) (pScreen
, pCmapIDs
);
330 for (i
= 0; i
< n
; i
++) {
333 dixLookupResourceByType((pointer
*) &pCmap
, pCmapIDs
[i
], RT_COLORMAP
,
334 serverClient
, DixUninstallAccess
);
336 XUninstallColormap(xnestDisplay
, xnestColormap(pCmap
));
341 xnestInstallColormap(ColormapPtr pCmap
)
343 ColormapPtr pOldCmap
= GetInstalledColormap(pCmap
->pScreen
);
345 if (pCmap
!= pOldCmap
) {
346 xnestDirectUninstallColormaps(pCmap
->pScreen
);
348 /* Uninstall pInstalledMap. Notify all interested parties. */
349 if (pOldCmap
!= (ColormapPtr
) None
)
350 WalkTree(pCmap
->pScreen
, TellLostMap
, (pointer
) &pOldCmap
->mid
);
352 SetInstalledColormap(pCmap
->pScreen
, pCmap
);
353 WalkTree(pCmap
->pScreen
, TellGainedMap
, (pointer
) &pCmap
->mid
);
355 xnestSetInstalledColormapWindows(pCmap
->pScreen
);
356 xnestDirectInstallColormaps(pCmap
->pScreen
);
361 xnestUninstallColormap(ColormapPtr pCmap
)
363 ColormapPtr pCurCmap
= GetInstalledColormap(pCmap
->pScreen
);
365 if (pCmap
== pCurCmap
) {
366 if (pCmap
->mid
!= pCmap
->pScreen
->defColormap
) {
367 dixLookupResourceByType((pointer
*) &pCurCmap
,
368 pCmap
->pScreen
->defColormap
,
370 serverClient
, DixInstallAccess
);
371 (*pCmap
->pScreen
->InstallColormap
) (pCurCmap
);
376 static Bool xnestInstalledDefaultColormap
= False
;
379 xnestListInstalledColormaps(ScreenPtr pScreen
, Colormap
* pCmapIDs
)
381 if (xnestInstalledDefaultColormap
) {
382 *pCmapIDs
= GetInstalledColormap(pScreen
)->mid
;
390 xnestStoreColors(ColormapPtr pCmap
, int nColors
, xColorItem
* pColors
)
392 if (pCmap
->pVisual
->class & DynamicClass
)
396 XColor
*pColors64
= (XColor
*) malloc(nColors
* sizeof(XColor
));
398 for (i
= 0; i
< nColors
; ++i
) {
399 pColors64
[i
].pixel
= pColors
[i
].pixel
;
400 pColors64
[i
].red
= pColors
[i
].red
;
401 pColors64
[i
].green
= pColors
[i
].green
;
402 pColors64
[i
].blue
= pColors
[i
].blue
;
403 pColors64
[i
].flags
= pColors
[i
].flags
;
405 XStoreColors(xnestDisplay
, xnestColormap(pCmap
), pColors64
, nColors
);
409 XStoreColors(xnestDisplay
, xnestColormap(pCmap
),
410 (XColor
*) pColors
, nColors
);
415 xnestResolveColor(unsigned short *pRed
, unsigned short *pGreen
,
416 unsigned short *pBlue
, VisualPtr pVisual
)
421 shift
= 16 - pVisual
->bitsPerRGBValue
;
422 lim
= (1 << pVisual
->bitsPerRGBValue
) - 1;
424 if ((pVisual
->class == PseudoColor
) || (pVisual
->class == DirectColor
)) {
425 /* rescale to rgb bits */
426 *pRed
= ((*pRed
>> shift
) * 65535) / lim
;
427 *pGreen
= ((*pGreen
>> shift
) * 65535) / lim
;
428 *pBlue
= ((*pBlue
>> shift
) * 65535) / lim
;
430 else if (pVisual
->class == GrayScale
) {
431 /* rescale to gray then rgb bits */
432 *pRed
= (30L * *pRed
+ 59L * *pGreen
+ 11L * *pBlue
) / 100;
433 *pBlue
= *pGreen
= *pRed
= ((*pRed
>> shift
) * 65535) / lim
;
435 else if (pVisual
->class == StaticGray
) {
438 limg
= pVisual
->ColormapEntries
- 1;
439 /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
440 *pRed
= (30L * *pRed
+ 59L * *pGreen
+ 11L * *pBlue
) / 100;
441 *pRed
= ((((*pRed
* (limg
+ 1))) >> 16) * 65535) / limg
;
442 *pBlue
= *pGreen
= *pRed
= ((*pRed
>> shift
) * 65535) / lim
;
445 unsigned limr
, limg
, limb
;
447 limr
= pVisual
->redMask
>> pVisual
->offsetRed
;
448 limg
= pVisual
->greenMask
>> pVisual
->offsetGreen
;
449 limb
= pVisual
->blueMask
>> pVisual
->offsetBlue
;
450 /* rescale to [0..limN] then [0..65535] then rgb bits */
451 *pRed
= ((((((*pRed
* (limr
+ 1)) >> 16) *
452 65535) / limr
) >> shift
) * 65535) / lim
;
453 *pGreen
= ((((((*pGreen
* (limg
+ 1)) >> 16) *
454 65535) / limg
) >> shift
) * 65535) / lim
;
455 *pBlue
= ((((((*pBlue
* (limb
+ 1)) >> 16) *
456 65535) / limb
) >> shift
) * 65535) / lim
;
461 xnestCreateDefaultColormap(ScreenPtr pScreen
)
465 unsigned short zero
= 0, ones
= 0xFFFF;
468 if (!dixRegisterPrivateKey(&cmapScrPrivateKeyRec
, PRIVATE_SCREEN
, 0))
471 for (pVisual
= pScreen
->visuals
;
472 pVisual
->vid
!= pScreen
->rootVisual
; pVisual
++);
474 if (CreateColormap(pScreen
->defColormap
, pScreen
, pVisual
, &pCmap
,
475 (pVisual
->class & DynamicClass
) ? AllocNone
: AllocAll
,
480 wp
= pScreen
->whitePixel
;
481 bp
= pScreen
->blackPixel
;
482 if ((AllocColor(pCmap
, &ones
, &ones
, &ones
, &wp
, 0) !=
484 (AllocColor(pCmap
, &zero
, &zero
, &zero
, &bp
, 0) != Success
))
486 pScreen
->whitePixel
= wp
;
487 pScreen
->blackPixel
= bp
;
488 (*pScreen
->InstallColormap
) (pCmap
);
490 xnestInstalledDefaultColormap
= True
;