[comp.windows.x] Setting up color tables for an image.

davis@karl.ucar.edu (Glenn P. Davis) (10/18/89)

I'm experimenting with a very simple X client to render color images.
I'm using the R3 Athena widgets only.  I have looked at 'xim' and
NCSA 'ximage' as examples and use the folowing sequence of calls:

	Widget box ; /* boxWidget class */
	Display *dpy ;
	GC gc ;
	XGCValues  gcvalues ;
	Visual *vis ;
	XImage *cimage ;

	dpy = XtDisplay(box3) ;
	vis = GetVisual(dpy) ;

	cimage = XCreateImage(dpy,vis,8,ZPixmap,0,ap->image,
		 ap->dir->esiz, ap->dir->lsiz, 8, ap->dir->esiz);

	/*   XInstallColormap(dpy,cmap); */

	gc = XtGetGC(box3, NULL, &gcvalues) ;
	XPutImage( dpy, XtWindow(box3), gc,
	     cimage, 0,0,0,0, ap->dir->esiz, ap->dir->lsiz) ;

('ap' is the input image structure I have to work with. )
This works and I get the image in the box.

My questions has to do with the color mapping. The input images are 8 bit
greyscale.

What is the correct sequence of calls to create and install the new colormap?
Actually I have two cases,
	one where there are 'nearly' 256 distinct grey levels - 8 bit sensor
	a second where there are more like 64 distinct grey levels -
		6 bit sensor
Actually, in both of these cases the top and bottom few grey values
do not occur in the actual images.

The sequence I have started with is

	Xcolor colors[256] ;
	int ncolors ; /* 64 or 256 */

	/* set up color table */
	for (ii=0; ii < ncolors; ii++)
	{
		colors[ii].pixel = (u_long)ii;
		colors[ii].red =
		colors[ii].green =
		colors[ii].blue = (u_short)(ii * 257 *(256/ncolors)) ;
		colors[ii].flags = DoRed | DoGreen | DoBlue;
	}

	.
	.
	.
	
	/* set up colormap */
	{
		Display *dpy ;
		Visual *vis ;
		void SetColormap() ;

		dpy = XtDisplay(box3) ;
		vis = GetVisual(dpy) ;
		if ((vis->class != PseudoColor) && (vis->class != StaticColor))
		{
		  	fprintf(stderr,
			"Can't use this display. Not a Pseudo Color device\n");
			exit(-1) ;
		}
		if ( DisplayPlanes(dpy,XDefaultScreen(dpy)) != 8 )
		{
			fprintf(stderr,
				"Can't use this display.  Not an 8 bit display\n");
			exit(-2) ;
		}
		cmap = XCreateColormap(dpy, XtWindow(box3), vis, AllocAll) ;
		XStoreColors(dpy, cmap, colors, ncolors) ;
		XInstallColormap(dpy,cmap);
	}


I have also fooled around with not executing 'XInstallColormap'
in the main line code, instead adding two event handler to 'box' for
entering and leaving the box, Install and UnInstall the colormap.

This latter system works when I'm not running any window manager.
It doesn't with twm, even with ncolors = 64. 
I assume I'm not being 'a good client'.  What should I be doing?
For the case ncolors = 64, I would prefer to set things up so there
is no 'flash', if possible.

Thanks

Glenn P. Davis
UCAR / Unidata
PO Box 3000                   1685 38th St.
Boulder, CO 80307-3000        Boulder, CO  80301

(303) 497 8643

mnp@cs.brown.edu (Matthew Nicholas Pappas) (10/20/89)

In article <4743@ncar.ucar.edu> davis@karl.ucar.edu (Glenn P. Davis) writes:

   From: davis@karl.ucar.edu (Glenn P. Davis)
   Newsgroups: comp.windows.x
   Keywords: XInstallColormap
   Date: 17 Oct 89 20:36:16 GMT
   Reply-To: davis@karl.UCAR.EDU (Glenn P. Davis)
   Organization: Unidata/UCAR, Boulder CO

   I'm experimenting with a very simple X client to render color images.
   ...
   What is the correct sequence of calls to create and install the new
   colormap? 
   ...
	   cmap = XCreateColormap(dpy, XtWindow(box3), vis, AllocAll) ;
ok
	   XStoreColors(dpy, cmap, colors, ncolors) ;
ok
	   XInstallColormap(dpy,cmap);
NOT ok.  Read the manpage for this function.  Only window managers should
call this function.  Or look at the Gettys & Scheifler book (you know--the
maroon one).

   I have also fooled around with not executing 'XInstallColormap'
   in the main line code, instead adding two event handler to 'box' for
   entering and leaving the box, Install and UnInstall the colormap.
You're still not allowed to call XInstallColormap (even if the mouse entered
your window).

   This latter system works when I'm not running any window manager.
You are in effect acting as the window manager.

   It doesn't with twm, even with ncolors = 64. 
   I assume I'm not being 'a good client'.  
This is true.  But it's hard to know that without trying first.

   What should I be doing?
Assuming your toplevel widget has the same visual type as the root window
(which it must if you are using release 3), call XSetWindowColormap after you
call XStoreColors in the code above.  XSetWindowColormap sets a property on
your toplevel window; this property is read by the window manager, and the
window manager then makes sure that your colormap is installed (using
XInstallColormap) whenever your window has the colormap focus.  Note that the
mous probably has to be inside your window for the window manager to give you
the colormap focus.

If you are using a nonstandard visual, or just want a better sense of the
more complex issues of colormap sharing/installation, read the ICCCM doc,
which is available on expo (18.30.0.212).  It's actually one of the shorter X
documents, and reasonably readable.

   For the case ncolors = 64, I would prefer to set things up so there
   is no 'flash', if possible.
There shouldn't be any serious flash.  Be more specific if you think this is
a problem.

   Thanks

   Glenn P. Davis
   UCAR / Unidata
   PO Box 3000                   1685 38th St.
   Boulder, CO 80307-3000        Boulder, CO  80301

   (303) 497 8643

Good luck,

-matt
Brown Graphics Group
_________________________________________________________________________
   uunet ! brunix ! mnp                           Matthew Nicholas Pappas
or mnp @ {cs.brown.edu, browncs.bitnet }                 Brown University

mouse@LARRY.MCRCIM.MCGILL.EDU (der Mouse) (10/23/89)

>> I'm experimenting with a very simple X client to render color images.

>> What is the correct sequence of calls to create and install the new
>> colormap?

>> cmap = XCreateColormap(dpy, XtWindow(box3), vis, AllocAll) ;
>> XStoreColors(dpy, cmap, colors, ncolors) ;
>> XInstallColormap(dpy,cmap);

This is the correct sequence to do what you said.  However, as someone
else pointed out, this is not the Right Thing To Do.  Only window
managers should call XInstallColormap.  What you should be doing is
calling XSetWindowColormap.

However, if you want your program to work when there is no window
manager running, or when you're running under an old window manager
that doesn't handle colormaps, you will probably find you have to call
XInstallColormap yourself.

I know of no reliable way to tell whether you will need to call
XInstallColormap yourself (ie, a way to tell whether there's a
colormap-compliant window manager running).  What I chose to do when I
ran into this problem was to assume the window manager will handle it,
but provide an option the user can give on the command line to direct
the program to do the installation itself, for use on another display
with no wm or under a wm that doesn't handle colormaps correctly.

					der Mouse

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