[comp.windows.x] Problems with standard colormaps

cei@ipvvis.unipv.it (Ugo Cei) (06/05/91)

I am developing an imaging application and want to display images
using a gray-level colormap on an 8 bit display. I was thinking about
using the standard colormaps but could not succeed in doing this. Yes,
I have read the FAQ and used xstdcmap as mentioned, but to no avail.
Besides, my application is ready to create the requested colormap if
it does not exist, but it is unable to locate the XA_RGB_GRAY_MAP
property via XGetRGBColormaps.

The code I have used is derived from Volume 1 (second edition) of the
O'Reilly series on X (example 7-11, page 220). Since this example
contains some errors that I had to correct myself, I wonder if it is
any good at all. I only hope I did not make things worse.  Anyway, I
append my funcion at the end of the posting: the call to
XGetRGBColormaps invariably fails.

My environment is Sun Sparcstation 1, SunOS 4.0.3, MIT's X11R4 pl 18.
I use gcc to build my programs, however Sun's cc was used to build the
X11R4 release. The same problem happens also when the server is OW 2.0
on a Sparcstation 2 running 4.1.1.

Thanks in advance; code follows. I would also appreciate comments on
the rest of the function.

----------------------------------------------------------------------
#include <X11/Xlib.h>
#include <X11/Xatom.h>

static int
InstallGrayColormap(Display * dpy, Window w)
{
  XStandardColormap    * cmap   = NULL;
  XColor               * exact;
  int                    count  = 0;
  XSetWindowAttributes   attrib;
  Visual               * visual;
  int                    ncells;
  int                    i;

  if(!XGetRGBColormaps(dpy, w, & cmap, & count, XA_RGB_GRAY_MAP))
    {

      /* Here is where it always fails. cmap and count are both 0 on exit */

      fprintf(stderr, "InstallGrayColormap: XGetRGBColormaps failed.\n");
      return False;
    }
  if(cmap->colormap)		/* Colormap has already been created */
    {
      if(cmap->red_max == 0)
	{
	  fprintf(stderr, 
		  "InstallGrayColormap: colormap has already been "
		  "created but it is not valid.\n");
	  return False;
	}
    }
  else				/* Colormap must be created */
    {
      XVisualInfo * vlist, vinfo_template, * v;
      int num_vis;
      
      vlist = XGetVisualInfo(dpy, VisualNoMask, & vinfo_template, & num_vis);
      for(v = vlist ; v < vlist + num_vis ; v++)
	{
	  if(v->visualid == cmap->visualid)
	    {
	      visual = v->visual;
	      break;
	    }
	}

      cmap->colormap = XCreateColormap(dpy, w, visual, AllocAll);
      if(cmap->colormap == DefaultColormap(dpy, DefaultScreen(dpy)))
	{
	  fprintf(stderr,
		  "InstallGrayColormap: hardware colormap is immutable.\n");
	  return False;
	}
    }
  attrib.colormap = cmap->colormap;
  
  ncells = cmap->base_pixel + cmap->red_max * cmap->red_mult;
  if((exact = (XColor *) calloc(sizeof (XColor), ncells)) == NULL)
    {
      perror("InstallGrayColormap");
      return False;
    }
  
  for(i = 0; i < ncells ; i++)
    {
      exact[i].red =
	exact[i].green =
	  exact[i].blue = i * cmap->red_mult + cmap->base_pixel;
    }
  XStoreColors(dpy, cmap->colormap, exact, ncells);
  XSetRGBColormaps(dpy, w, cmap, count, XA_RGB_GRAY_MAP);
  XSetWindowColormap(dpy, w, cmap->colormap);
  
  return True;
}

----------------------------------------------------------------------
-- 
Ugo Cei - Dipartimento Informatica e Sistemistica 
          Via Abbiategrasso 209 - 27100 Pavia - ITALY   +39 382 391.372
          Internet: cei@ipvvis.unipv.it

adrian@ora.com (Adrian Nye) (06/12/91)

> I have read the FAQ and used xstdcmap as mentioned, but to no avail.
> Besides, my application is ready to create the requested colormap if
> it does not exist, but it is unable to locate the XA_RGB_GRAY_MAP
> property via XGetRGBColormaps.

xstdcmap is supposed to define the standard colormap properties
such as XA_RGB_GRAY_MAP.  If you have run it, and the property still isn't
defined, then xstdcmap may be broken.  It also could be that your server
does not expose a gray-scale visual, so xstdcmap does not try to define this
property.  xstdcmap also fails on my system, and I haven't delved in yet to
figure out why.

You can use xprop to help you
make sure the property isn't there (or is).