2
/* Copyright (c) Mark J. Kilgard, 1994, 1996, 1997. */
4
/* This program is freely distributable without licensing fees
5
and is provided without guarantee or warrantee expressed or
6
implied. This program is -not- in the public domain. */
9
//EK#include <GL/vms_x_fix.h>
14
#include <stdio.h> /* SunOS multithreaded assert() needs <stdio.h>. Lame. */
16
#if !defined(_WIN32) && !defined(__OS2__)
18
#include <X11/Xutil.h>
19
#include <X11/Xatom.h> /* for XA_RGB_DEFAULT_MAP atom */
21
#include <Xmu/StdCmap.h> /* for XmuLookupStandardColormap */
23
#include <X11/Xmu/StdCmap.h> /* for XmuLookupStandardColormap */
27
/* SGI optimization introduced in IRIX 6.3 to avoid X server
28
round trips for interning common X atoms. */
29
#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
30
#include <X11/SGIFastAtom.h>
32
#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
36
#include "layerutil.h"
38
GLUTcolormap *__glutColormapList = NULL;
41
__glutAssociateNewColormap(XVisualInfo * vis)
44
int transparentPixel, i;
45
unsigned long pixels[255];
47
cmap = (GLUTcolormap *) malloc(sizeof(GLUTcolormap));
49
__glutFatalError("out of memory.");
50
#if defined(_WIN32) || defined(__OS2__)
51
pixels[0] = 0; /* avoid compilation warnings on win32 */
53
cmap->size = 256; /* always assume 256 on Win32 */
55
cmap->visual = vis->visual;
56
cmap->size = vis->visual->map_entries;
59
cmap->cells = (GLUTcolorcell *)
60
malloc(sizeof(GLUTcolorcell) * cmap->size);
62
__glutFatalError("out of memory.");
63
/* make all color cell entries be invalid */
64
for (i = cmap->size - 1; i >= 0; i--) {
65
cmap->cells[i].component[GLUT_RED] = -1.0;
66
cmap->cells[i].component[GLUT_GREEN] = -1.0;
67
cmap->cells[i].component[GLUT_BLUE] = -1.0;
69
transparentPixel = __glutGetTransparentPixel(__glutDisplay, vis);
70
if (transparentPixel == -1 || transparentPixel >= cmap->size) {
72
/* If there is no transparent pixel or if the transparent
73
pixel is outside the range of valid colormap cells (HP
74
can implement their overlays this smart way since their
75
transparent pixel is 255), we can AllocAll the colormap.
78
cmap->cmap = XCreateColormap(__glutDisplay,
79
__glutRoot, cmap->visual, AllocAll);
82
/* On machines where zero (or some other value in the range
83
of 0 through map_entries-1), BadAlloc may be generated
84
when an AllocAll overlay colormap is allocated since the
85
transparent pixel precludes all the cells in the colormap
86
being allocated (the transparent pixel is pre-allocated).
87
So in this case, use XAllocColorCells to allocate
88
map_entries-1 pixels (that is, all but the transparent
91
#if defined(_WIN32) || defined(__OS2__)
92
cmap->cmap = XCreateColormap(__glutDisplay,
93
__glutRoot, 0, AllocNone);
95
cmap->cmap = XCreateColormap(__glutDisplay,
96
__glutRoot, vis->visual, AllocNone);
97
XAllocColorCells(__glutDisplay, cmap->cmap, False, 0, 0,
98
pixels, cmap->size - 1);
101
cmap->next = __glutColormapList;
102
__glutColormapList = cmap;
106
static GLUTcolormap *
107
associateColormap(XVisualInfo * vis)
109
#if !defined(_WIN32) && !defined(__OS2__)
110
GLUTcolormap *cmap = __glutColormapList;
112
while (cmap != NULL) {
113
/* Play safe: compare visual IDs, not Visual*'s. */
114
if (cmap->visual->visualid == vis->visual->visualid) {
115
/* Already have created colormap for the visual. */
122
return __glutAssociateNewColormap(vis);
126
__glutSetupColormap(XVisualInfo * vi, GLUTcolormap ** colormap, Colormap * cmap)
128
#if defined(_WIN32) || defined(__OS2__)
129
if (vi->dwFlags & PFD_NEED_PALETTE || vi->iPixelType == PFD_TYPE_COLORINDEX) {
130
*colormap = associateColormap(vi);
131
*cmap = (*colormap)->cmap;
138
XStandardColormap *standardCmaps;
140
static Atom hpColorRecoveryAtom = -1;
141
int isRGB, visualClass, rc;
143
#if defined(__cplusplus) || defined(c_plusplus)
144
visualClass = vi->c_class;
146
visualClass = vi->class;
148
switch (visualClass) {
150
/* Mesa might return a PseudoColor visual for RGB mode. */
151
rc = glXGetConfig(__glutDisplay, vi, GLX_RGBA, &isRGB);
152
if (rc == 0 && isRGB) {
155
if (MaxCmapsOfScreen(DefaultScreenOfDisplay(__glutDisplay)) == 1
156
&& vi->visual == DefaultVisual(__glutDisplay, __glutScreen)) {
157
char *privateCmap = getenv("MESA_PRIVATE_CMAP");
160
/* User doesn't want to share colormaps. */
161
*cmap = XCreateColormap(__glutDisplay, __glutRoot,
162
vi->visual, AllocNone);
164
/* Share the root colormap. */
165
*cmap = DefaultColormap(__glutDisplay, __glutScreen);
168
/* Get our own PseudoColor colormap. */
169
*cmap = XCreateColormap(__glutDisplay, __glutRoot,
170
vi->visual, AllocNone);
173
/* CI mode, real GLX never returns a PseudoColor visual
175
*colormap = associateColormap(vi);
176
*cmap = (*colormap)->cmap;
181
*colormap = NULL; /* NULL if RGBA */
183
/* Hewlett-Packard supports a feature called "HP Color
184
Recovery". Mesa has code to use HP Color Recovery. For
185
Mesa to use this feature, the atom
186
_HP_RGB_SMOOTH_MAP_LIST must be defined on the root
187
window AND the colormap obtainable by XGetRGBColormaps
188
for that atom must be set on the window. If that
189
colormap is not set, the output will look stripy. */
191
if (hpColorRecoveryAtom == -1) {
194
#define VENDOR_HP "Hewlett-Packard"
196
/* Only makes sense to make XInternAtom round-trip if we
197
know that we are connected to an HP X server. */
198
xvendor = ServerVendor(__glutDisplay);
199
if (!strncmp(xvendor, VENDOR_HP, sizeof(VENDOR_HP) - 1)) {
200
hpColorRecoveryAtom = XInternAtom(__glutDisplay, "_HP_RGB_SMOOTH_MAP_LIST", True);
202
hpColorRecoveryAtom = None;
205
if (hpColorRecoveryAtom != None) {
206
status = XGetRGBColormaps(__glutDisplay, __glutRoot,
207
&standardCmaps, &numCmaps, hpColorRecoveryAtom);
209
for (i = 0; i < numCmaps; i++) {
210
if (standardCmaps[i].visualid == vi->visualid) {
211
*cmap = standardCmaps[i].colormap;
212
XFree(standardCmaps);
216
XFree(standardCmaps);
219
#ifndef SOLARIS_2_4_BUG
220
/* Solaris 2.4 and 2.5 have a bug in their
221
XmuLookupStandardColormap implementations. Please
222
compile your Solaris 2.4 or 2.5 version of GLUT with
223
-DSOLARIS_2_4_BUG to work around this bug. The symptom
224
of the bug is that programs will get a BadMatch error
225
from X_CreateWindow when creating a GLUT window because
226
Solaris 2.4 and 2.5 create a corrupted RGB_DEFAULT_MAP
227
property. Note that this workaround prevents Colormap
228
sharing between applications, perhaps leading
229
unnecessary colormap installations or colormap flashing.
230
Sun fixed this bug in Solaris 2.6. */
231
status = XmuLookupStandardColormap(__glutDisplay,
232
vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP,
233
/* replace */ False, /* retain */ True);
235
status = XGetRGBColormaps(__glutDisplay, __glutRoot,
236
&standardCmaps, &numCmaps, XA_RGB_DEFAULT_MAP);
238
for (i = 0; i < numCmaps; i++) {
239
if (standardCmaps[i].visualid == vi->visualid) {
240
*cmap = standardCmaps[i].colormap;
241
XFree(standardCmaps);
245
XFree(standardCmaps);
249
/* If no standard colormap but TrueColor, just make a
251
/* XXX Should do a better job of internal sharing for
252
privately allocated TrueColor colormaps. */
253
/* XXX DirectColor probably needs ramps hand initialized! */
254
*cmap = XCreateColormap(__glutDisplay, __glutRoot,
255
vi->visual, AllocNone);
260
/* Mesa supports these visuals */
262
*cmap = XCreateColormap(__glutDisplay, __glutRoot,
263
vi->visual, AllocNone);
267
"could not allocate colormap for visual type: %d.",
274
#if !defined(_WIN32) && !defined(__OS2__)
276
findColormaps(GLUTwindow * window,
277
Window * winlist, Colormap * cmaplist, int num, int max)
282
/* Do not allow more entries that maximum number of
286
/* Is cmap for this window already on the list? */
287
for (i = 0; i < num; i++) {
288
if (cmaplist[i] == window->cmap)
289
goto normalColormapAlreadyListed;
291
/* Not found on the list; add colormap and window. */
292
winlist[num] = window->win;
293
cmaplist[num] = window->cmap;
296
normalColormapAlreadyListed:
298
/* Repeat above but for the overlay colormap if there one. */
299
if (window->overlay) {
302
for (i = 0; i < num; i++) {
303
if (cmaplist[i] == window->overlay->cmap)
304
goto overlayColormapAlreadyListed;
306
winlist[num] = window->overlay->win;
307
cmaplist[num] = window->overlay->cmap;
310
overlayColormapAlreadyListed:
312
/* Recursively search children. */
313
child = window->children;
315
num = findColormaps(child, winlist, cmaplist, num, max);
316
child = child->siblings;
322
__glutEstablishColormapsProperty(GLUTwindow * window)
324
/* this routine is strictly X. Win32 doesn't need to do
325
anything of this sort (but has to do other wacky stuff
327
static Atom wmColormapWindows = None;
333
assert(!window->parent);
334
maxcmaps = MaxCmapsOfScreen(ScreenOfDisplay(__glutDisplay,
336
/* For portability reasons we don't use alloca for winlist
337
and cmaplist, but we could. */
338
winlist = (Window *) malloc(maxcmaps * sizeof(Window));
339
cmaplist = (Colormap *) malloc(maxcmaps * sizeof(Colormap));
340
num = findColormaps(window, winlist, cmaplist, 0, maxcmaps);
342
/* Property no longer needed; remove it. */
343
wmColormapWindows = XSGIFastInternAtom(__glutDisplay,
344
"WM_COLORMAP_WINDOWS", SGI_XA_WM_COLORMAP_WINDOWS, False);
345
if (wmColormapWindows == None) {
346
__glutWarning("Could not intern X atom for WM_COLORMAP_WINDOWS.");
349
XDeleteProperty(__glutDisplay, window->win, wmColormapWindows);
351
status = XSetWMColormapWindows(__glutDisplay, window->win,
353
/* XSetWMColormapWindows should always work unless the
354
WM_COLORMAP_WINDOWS property cannot be intern'ed. We
357
__glutFatalError("XSetWMColormapWindows returned False.");
359
/* For portability reasons we don't use alloca for winlist
360
and cmaplist, but we could. */
366
__glutToplevelOf(GLUTwindow * window)
368
while (window->parent) {
369
window = window->parent;
376
__glutFreeColormap(GLUTcolormap * cmap)
378
GLUTcolormap *cur, **prev;
381
if (cmap->refcnt == 0) {
382
/* remove from colormap list */
383
cur = __glutColormapList;
384
prev = &__glutColormapList;
393
/* actually free colormap */
394
XFreeColormap(__glutDisplay, cmap->cmap);