[comp.windows.x] standard colormap utility

hallinan@metatron.harvard.edu (Peter Hallinan) (09/12/90)

I am trying to write a utility to change the standard colormap RGB_DEFAULT_MAP.
My reason for doing this is simply that one colormap can accomodate
all my applications if it is set up correctly, allowing all applications
to display correct colors simultaneously.  My intention is to call the utility
immediately after logging in on DecStations running DECWindows, and immediately
after starting X on Sun Workstations, i.e. before starting any X applications
such as xterm.

I would like RGB_DEFAULT_MAP to have the following structure:
192 read-only   color cells - my choice
 64 unallocated color cells - for various applications, eg xterm

The Xlib guide suggests using XSetStandardColormap(), but the code
sequence it describes does not clearly explain how to set RGB_DEFAULT_MAP
(it seems to be a special case), nor does it indicate exactly when
XSetStandardColormap() should be called. So now I am stuck.
A sketch of my (incorrect) code for this utility follows.
I would very much appreciate any comments and/or corrections.

Thanks in advance,
Peter Hallinan
hallinan@gramian.harvard.edu

/****************************************************************************/
main()
	{
	int i, scr, depth;
	Display *dsp;
	Window root;
	XVisualInfo vinfo;
	XColor cdef;
	Colormap cmap;
	XStandardColormap stdcmap;

	dsp = XOpenDisplay (getenv("DISPLAY"));
	scr = DefaultScreen (dsp);
	root = DefaultRootWindow(dsp);
	depth = DisplayPlanes (dsp, scr);

	/* create new color map w/ 192 read-only cells */
	XMatchVisualInfo (dsp, scr, depth, PseudoColor, &vinfo);
	cmap = XCreateColormap (dsp,root,vinfo.visual,AllocNone);

	/* allocate the new read-only default colors */
	for (i = 0; i < 192; i++)
		{
		cdef.pixel = i; cdef.red = xxx; etc
		XAllocColor (dsp, cmap, &cdef);
		}

	/* fill in XStandardColormap structure */
	stdcmap.colormap = cmap; etc

	/* somehow replace the old RGB_DEFAULT_MAP */
	XGrabServer (dsp);
	XChangeProperty (dsp, root, XA_RGB_DEFAULT_MAP, XA_RGB_COLOR_MAP,
		32, PropModeReplace, (char *)&stdcmap, 9);
	XSetStandardColormap (dsp, root, &stdcmap, XA_RGB_DEFAULT_MAP);
	XSetCloseDownMode (dsp, RetainPermanent);
	XUngrabServer (dsp);
	}

Peter W. Hallinan			Aiken 229
hallinan@gramian.harvard.edu		Harvard University
					Cambridge, MA  02138

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (09/13/90)

    I would like RGB_DEFAULT_MAP to have the following structure:

Look at the Xmu standard colormap routines in R4, e.g.
XmuStandardColormap and XmuCreateColormap.

mouse@SHAMASH.MCRCIM.MCGILL.EDU (der Mouse) (09/13/90)

> I am trying to write a utility to change the standard colormap
> RGB_DEFAULT_MAP.  My reason for doing this is simply that one
> colormap can accomodate all my applications if it is set up
> correctly, allowing all applications to display correct colors
> simultaneously.

> I would like RGB_DEFAULT_MAP to have the following structure:
> 192 read-only   color cells - my choice
>  64 unallocated color cells - for various applications, eg xterm

Hmmm, I suspect you actually want to change the default colormap;
current applications tend to allocate colors there when possible.
Installing the default colormap into the RGB_DEFAULT_MAP property
is an orthogonal issue.

> The Xlib guide
(What?  Someone who actually reads the documentation??  :-)
> suggests using XSetStandardColormap(), but the code sequence it
> describes does not clearly explain how to set RGB_DEFAULT_MAP (it
> seems to be a special case), nor does it indicate exactly when
> XSetStandardColormap() should be called.

The R4 Xlib documentation says that XSetStandardColormap has been
superseded by XSetRGBColormap (but this function is not mentioned
anywhere else, though XSetRGBColormaps is).

Also, reading over the section of the Xlib document on standard
colormaps gives me the impression the colors are intended to be
three-dimensional Cartesian splittings of the color cube, which
sounds as though it's inappropriate for your case.  It might be
better for you to allocate out of the default colormap and give
up on messing with standard colormaps.

So.  I have not actually tried any of this, but I would guess that the
following should help:

	cmap = XCreateColormap (dsp,root,vinfo.visual,AllocNone);

Just use the default colormap of the screen instead.  If the default
colormap has the wrong visual type, I don't really know what to
suggest; there seems to be only one default colormap per screen, not
one per visual (which would make more sense, IMO).

You have obviously paid attention to documentation, postings on the
net, or both, and are trying to Do The Right Thing.  This is a very
good thing, and somewhat refreshing to see on the net (thank you!).
But if the default visual type is not mutable, what the Right Thing
is is not entirely clear.

	XGrabServer (dsp);
	XChangeProperty (dsp, root, XA_RGB_DEFAULT_MAP, XA_RGB_COLOR_MAP,
		32, PropModeReplace, (char *)&stdcmap, 9);
	XSetStandardColormap (dsp, root, &stdcmap, XA_RGB_DEFAULT_MAP);
	XSetCloseDownMode (dsp, RetainPermanent);
	XUngrabServer (dsp);

I'd recommend a final XCloseDisplay in any case.  But I suspect the
only thing you need to keep of this is the XSetCloseDownMode.  If you
want to change the RGB_DEFAULT_MAP property, XSetRGBColormaps works
like

	XSetRGBColormaps(dsp,root,&stdcmap,1,XA_RGB_DEFAULT_MAP);

This call will throw away anything that used to be in the
RGB_DEFAULT_MAP property.  If you want to preserve what used to be
there, use XGetRGBColormaps first....

If you don't create a colormap, you might want to create some resource
with an ID - a 1x1 pixmap, say - on the same connection, and put its
XID into a property of the root window, so the colormap cells can be
freed with XKillClient if the need arises.

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu