============== xstdcmap
/*
 * $XConsortium: xstdcmap.c,v 1.6 89/07/24 11:06:26 jim Exp $
 *
 * Copyright 1989 Massachusetts Institute of Technology
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of M.I.T. not be used in advertising
 * or publicity pertaining to distribution of the software without specific,
 * written prior permission.  M.I.T. makes no representations about the
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Author:  Donna Converse, MIT X Consortium
 */

#include <stdio.h>
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/Xatom.h>
#include <X11/Xmu/StdCmap.h>
                                                                                         >  #include <X11/Xmu/StdCmapExt.h>
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  #include <X11/PEX5/PEXlib.h>
                                                                                         >  #endif /* ] PEX_SUPPORT */

extern void exit();

#define REPLACE		1
#define DO_NOT_REPLACE  0
#define RETAIN		1
#define DO_NOT_RETAIN	0

static char		*display_name = NULL;
static char		*program_name = NULL;
static Bool		all = 0;
static Bool		help = 0;
                                                                                         >  static Bool		full_default = 0;
static Bool 		verbose = 0;
                                                                                         >  static int		ramp_hint = 0;
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  static Bool		pex = 0;
                                                                                         >  #endif /* ] PEX_SUPPORT */
static Display		*dpy = NULL;
                                                                                         >  static XmuExtendedParams params = {
                                                                                         >      0, NULL, 0, NULL
                                                                                         >  };

typedef struct
{
    Bool	create;
    Bool	delete;
    Atom	property;
    char	*name;
    char	*nickname;
} colormap_property;

static colormap_property propertyTable[]=
{
{0,	0,	XA_RGB_DEFAULT_MAP,	"RGB_DEFAULT_MAP",	"default"},
{0,	0,	XA_RGB_BEST_MAP,	"RGB_BEST_MAP",		"best"},
{0,	0,	XA_RGB_GRAY_MAP,	"RGB_GRAY_MAP",		"gray"},
{0,	0,	XA_RGB_RED_MAP,		"RGB_RED_MAP",		"red"},
{0,	0,	XA_RGB_GREEN_MAP,	"RGB_GREEN_MAP",	"green"},
{0,	0,	XA_RGB_BLUE_MAP,	"RGB_BLUE_MAP",		"blue"},
};
#define NPROPERTIES (sizeof propertyTable / sizeof propertyTable[0])

#define DEFAULT	0
#define BEST	1
#define GRAY	2
#define RED	3
#define GREEN	4
#define BLUE	5

static char	*usage_message[]=
{
"    -all               make all standard colormaps for the display",
"    -best              make the RGB_BEST_MAP",
"    -blue              make the RGB_BLUE_MAP",
"    -default           make the RGB_DEFAULT_MAP",
"    -delete name       remove a standard colormap",
"    -display dpy       X server to use",
                                                                                         >  "    -fullDefault       make entry for each Visual when making RGB_DEFAULT_MAP",
"    -gray              make the RGB_GRAY_MAP",
"    -green             make the RGB_GREEN_MAP",
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  "    -pex               make ramps that are supported by PEX",
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  "    -ramp ordering     hint for color ramps in PseudoColor/StaticColor",
"    -red               make the RGB_RED_MAP",
"    -verbose           turn on logging",
"",
NULL };

static XrmOptionDescRec optionTable[]=
{
{"-all",	".all",		XrmoptionNoArg,		(caddr_t) "on"},
{"-best",	".best",	XrmoptionNoArg,		(caddr_t) "on"},
{"-blue",	".blue",	XrmoptionNoArg,		(caddr_t) "on"},
{"-default",	".default",	XrmoptionNoArg,		(caddr_t) "on"},
{"-delete",	".delete",	XrmoptionSepArg,	(caddr_t) NULL},
{"-display",	".display", 	XrmoptionSepArg,	(caddr_t) NULL},
                                                                                         >  {"-fullDefault",".fullDefault",	XrmoptionNoArg,		(caddr_t) "on"},
{"-gray",	".gray",	XrmoptionNoArg,		(caddr_t) "on"},
{"-green",	".green",	XrmoptionNoArg,		(caddr_t) "on"},
{"-help",	".help",        XrmoptionNoArg,		(caddr_t) "on"},
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  {"-pex",	".pex",         XrmoptionNoArg,		(caddr_t) "on"},
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  {"-ramp",	".ramp",        XrmoptionSepArg,	(caddr_t) NULL},
{"-red",	".red",		XrmoptionNoArg,		(caddr_t) "on"},
{"-verbose",	".verbose",	XrmoptionNoArg,		(caddr_t) "on"},
};
#define NOPTIONS (sizeof optionTable / sizeof optionTable[0])

                                                                                         >  static int findRampHint (name)
                                                                                         >      char *name;
                                                                                         >  {
                                                                                         >      if (!strcmp(name,"rgb"))
                                                                                         >  	return RAMP_RGB;
                                                                                         >      else if (!strcmp(name,"gbr"))
                                                                                         >  	return RAMP_GBR;
                                                                                         >      else if (!strcmp(name,"brg"))
                                                                                         >  	return RAMP_BRG;
                                                                                         >      else if (!strcmp(name,"rbg"))
                                                                                         >  	return RAMP_RBG;
                                                                                         >      else if (!strcmp(name,"grb"))
                                                                                         >  	return RAMP_GRB;
                                                                                         >      else if (!strcmp(name,"bgr"))
                                                                                         >  	return RAMP_BGR;
                                                                                         >      else {
                                                                                         >  	usage(1);
                                                                                         >      }
                                                                                         >  }
                                                                                         >  
static void parse(argc, argv)
    int		argc;
    char	**argv;
{
    XrmDatabase		database = NULL;
    char		*type;
    XrmValue		value;
    char		option[512];

    if (argc == 1)
	usage(0);

    XrmInitialize();
    XrmParseCommand(&database, optionTable, NOPTIONS, program_name, &argc,
		    argv);
    if (--argc)
	usage(1);

    (void) sprintf(option, "%s%s", program_name, ".all");
    if (XrmGetResource(database, option, (char *) NULL, &type, &value))                  |      if (XrmGetResource(database, option, (char *) NULL, &type, &value)) {
    	all++;
                                                                                         >  	full_default++;
                                                                                         >      }

    (void) sprintf(option, "%s%s", program_name, ".best");
    if (XrmGetResource(database, option, (char *) NULL, &type, &value))
    	propertyTable[BEST].create++;

    (void) sprintf(option, "%s%s", program_name, ".blue");
    if (XrmGetResource(database, option, (char *) NULL, &type, &value))
	propertyTable[BLUE].create++;

    (void) sprintf(option, "%s%s", program_name, ".default");
    if (XrmGetResource(database, option, (char *) NULL, &type, &value))
	propertyTable[DEFAULT].create++;

    (void) sprintf(option, "%s%s", program_name, ".delete");
    if (XrmGetResource(database, option, (char *) NULL, &type, &value)) {
	register int i;
	for (i=0; i < NPROPERTIES; i++) 
	    if (strncmp((char *) value.addr, propertyTable[i].nickname,
			(int) value.size) == 0) {
		propertyTable[i].delete++;
		break;
	    }
    }

    (void) sprintf(option, "%s%s", program_name, ".display");
    if (XrmGetResource(database, option, (char *) NULL, &type, &value))
	display_name = value.addr;

                                                                                         >      (void) sprintf(option, "%s%s", program_name, ".fullDefault");
                                                                                         >      if (XrmGetResource(database, option, (char *) NULL, &type, &value)) {
                                                                                         >  	full_default++;
                                                                                         >  	propertyTable[DEFAULT].create++;
                                                                                         >      }
                                                                                         >  
    (void) sprintf(option, "%s%s", program_name, ".gray");
    if (XrmGetResource(database, option, (char *) NULL, &type, &value))
	propertyTable[GRAY].create++;

    (void) sprintf(option, "%s%s", program_name, ".green");
    if (XrmGetResource(database, option, (char *) NULL, &type, &value))
	propertyTable[GREEN].create++;

    (void) sprintf(option, "%s%s", program_name, ".help");
    if (XrmGetResource(database, option, (char *) NULL, &type, &value))
	help++;

                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >      (void) sprintf(option, "%s%s", program_name, ".pex");
                                                                                         >      if (XrmGetResource(database, option, (char *) NULL, &type, &value))
                                                                                         >      	pex++;
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
                                                                                         >      (void) sprintf(option, "%s%s", program_name, ".ramp");
                                                                                         >      if (XrmGetResource(database, option, (char *) NULL, &type, &value))
                                                                                         >  	ramp_hint = findRampHint(value.addr);
                                                                                         >  
    (void) sprintf(option, "%s%s", program_name, ".red");
    if (XrmGetResource(database, option, (char *) NULL, &type, &value))
	propertyTable[RED].create++;

    (void) sprintf(option, "%s%s", program_name, ".verbose");
    if (XrmGetResource(database, option, (char *) NULL, &type, &value))
	verbose++;
}

Exit(status)
    Status	status;
{
    if (dpy)
	XCloseDisplay(dpy);
    exit(status);
}

usage(status)
    Status		status;
{
    register char	**i;
    (void) fprintf(stderr, "usage:  %s [-options]\n\n", program_name);
    (void) fprintf(stderr, "where options include:\n");
    for (i = usage_message; *i != NULL; i++)
	(void) fprintf(stderr, "%s\n", *i);
    Exit(status);
}

/* Determine the visual of greatest depth in a given visual class.
 * If no such visual exists, return NULL.  
 */
static XVisualInfo *getDeepestVisual(visual_class, vinfo, nvisuals)                      |  static XVisualInfo *getDeepestVisual(visual_class, vinfo, nvisuals,
                                                                                         >  					targets, ntargets)
    int		visual_class;	/* specifies the desired visual class */
    XVisualInfo	*vinfo;		/* specifies all visuals for a screen */
    int		nvisuals;	/* specifies number of visuals in the list */
                                                                                         >      char 	*targets;	/* PEX target list, NULL if PEX not required */
                                                                                         >      int		ntargets;	/* specifes count of PEX targets */
{
    register int	i;
    unsigned int	maxdepth = 0;
    XVisualInfo		*v = NULL;

    for (i=0; i < nvisuals; i++, vinfo++)                                                |      for (i=0; i < nvisuals; i++, vinfo++) {
                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  	/*
                                                                                         >  	    Filter so only PEX-supported Visuals are considered.
                                                                                         >  	*/
                                                                                         >  	if (ntargets) {
                                                                                         >  	    int PEX_supported_on_Visual;
                                                                                         >  	    PEXRenderingTarget	*p_target;
                                                                                         >  	    int j;
                                                                                         >  
                                                                                         >  	    PEX_supported_on_Visual = False;
                                                                                         >  	    for (j=0, p_target = (PEXRenderingTarget *) targets; 
                                                                                         >  		    j < ntargets; j++, p_target++) {
                                                                                         >  
                                                                                         >  		if ((p_target->depth == vinfo->depth) &&
                                                                                         >  		   (XVisualIDFromVisual(p_target->visual) == vinfo->visualid)) {
                                                                                         >  		    PEX_supported_on_Visual = True;
                                                                                         >  		    break;
                                                                                         >  		}
                                                                                         >  	    }
                                                                                         >  	    if (!PEX_supported_on_Visual)
                                                                                         >  		continue;
                                                                                         >  	}
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
	if (vinfo->class == visual_class && vinfo->depth > maxdepth)
	{
	    maxdepth = vinfo->depth;
	    v = vinfo;
	}
                                                                                         >      }
    return(v);
}

/* Determine the ``best'' visual of the screen for a standard colormap
 * property.  Return NULL if no visual is appropriate.
 */
static XVisualInfo *getBestVisual(property, vinfo, nvisuals)
    Atom	property;	/* specifies the standard colormap */
    XVisualInfo *vinfo;		/* specifies all visuals of the screen */
    int		nvisuals;	/* specifies number of visuals of screen */
{	
    XVisualInfo	*v1 = NULL, *v2 = NULL;

    if (vinfo == NULL)		 /* unexpected: a screen with no visuals */
	return v1;
                                                                                         >  
    v1 = getDeepestVisual(DirectColor, vinfo, nvisuals);
    v2 = getDeepestVisual(PseudoColor, vinfo, nvisuals);
    if (v2 && (!v1 || (v2->colormap_size >=
		       ((v1->red_mask | v1->green_mask | v1->blue_mask) + 1))))
	return v2;
    else if (v1)
	return v1;
    if (property == XA_RGB_BEST_MAP)
	if (((v1 = getDeepestVisual(TrueColor, vinfo, nvisuals)) != NULL) ||
	    ((v1 = getDeepestVisual(StaticColor, vinfo, nvisuals)) != NULL))
	    return v1;
    if (property == XA_RGB_GRAY_MAP)
	if (((v1 = getDeepestVisual(GrayScale, vinfo, nvisuals)) != NULL) ||
	    ((v1 = getDeepestVisual(StaticGray, vinfo, nvisuals)) != NULL))
	    return v1;
    return v1;

}

                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  
                                                                                         >  #define	FREE_PEX_TARGETS 	if (ntargets) XFree (targets); \
                                                                                         >  				XFree ((char *) vinfo);
                                                                                         >  
                                                                                         >  static XVisualInfo *getBestPEXVisual(property, vinfo, nvisuals)
                                                                                         >      Atom	property;	/* specifies the standard colormap */
                                                                                         >      XVisualInfo *vinfo;		/* specifies all visuals of the screen */
                                                                                         >      int		nvisuals;	/* specifies number of visuals of screen */
                                                                                         >  {	
                                                                                         >      XVisualInfo		*v0 = NULL, *v1 = NULL, *v2 = NULL, *ret_ptr = NULL;
                                                                                         >      int			ncolors_v0 = 0, ncolors_v1 = 0, ncolors_v2 = 0;
                                                                                         >      int			ret_colors = 0;
                                                                                         >      unsigned long	ntargets = 0;
                                                                                         >      char *		targets = NULL;
                                                                                         >      PEXExtensionInfo	*ext_info;
                                                                                         >  
                                                                                         >  
                                                                                         >      if (vinfo == NULL)		 /* unexpected: a screen with no visuals */
                                                                                         >  	return v1;
                                                                                         >  
                                                                                         >      if (NULL == (ext_info = PEXGetExtensionInfo (dpy))) {
                                                                                         >  	XFree ((char *) vinfo);
                                                                                         >  	return 0;
                                                                                         >      }
                                                                                         >  
                                                                                         >      if ((ext_info->major_version == 5) &&
                                                                                         >  	(ext_info->minor_version >= 1)) {
                                                                                         >  
                                                                                         >  	if (! PEXMatchRenderingTargets (dpy, 
                                                                                         >  				    RootWindow(dpy, vinfo->screen),
                                                                                         >  				    0, PEXWindowDrawable, NULL,
                                                                                         >  				    64, &ntargets, 
                                                                                         >  				    (PEXRenderingTarget**) &targets)
                                                                                         >  	  || (ntargets == 0)) {
                                                                                         >  	    XFree ((char *) vinfo);
                                                                                         >  	    return 0;
                                                                                         >  	}
                                                                                         >      }
                                                                                         >  
                                                                                         >      if (v0 = getDeepestVisual(TrueColor, vinfo, nvisuals, targets, ntargets))
                                                                                         >  	ncolors_v0 = ((v0->red_mask | v0->green_mask | v0->blue_mask) + 1);
                                                                                         >  
                                                                                         >      if (v1 = getDeepestVisual(DirectColor, vinfo, nvisuals, targets, ntargets))
                                                                                         >  	ncolors_v1 = ((v1->red_mask | v1->green_mask | v1->blue_mask) + 1);
                                                                                         >  
                                                                                         >      if (v2 = getDeepestVisual(PseudoColor, vinfo, nvisuals, targets, ntargets))
                                                                                         >  	ncolors_v2 = v2->colormap_size;
                                                                                         >  
                                                                                         >      if (ncolors_v1 >= ncolors_v2) {
                                                                                         >  	ret_ptr = v1;
                                                                                         >  	ret_colors = ncolors_v1;
                                                                                         >      }
                                                                                         >      else {
                                                                                         >  	ret_ptr = v2;
                                                                                         >  	ret_colors = ncolors_v2;
                                                                                         >      }
                                                                                         >  
                                                                                         >      if ((property == XA_RGB_BEST_MAP) || (property == XA_RGB_DEFAULT_MAP)) {
                                                                                         >  	if (ncolors_v0 >= ret_colors) {
                                                                                         >  	    ret_ptr = v0;
                                                                                         >  	    ret_colors = ncolors_v0;
                                                                                         >  	}
                                                                                         >      }
                                                                                         >  
                                                                                         >      if (ret_ptr) {
                                                                                         >  	FREE_PEX_TARGETS
                                                                                         >  	return ret_ptr;
                                                                                         >      }
                                                                                         >      
                                                                                         >      if ((property == XA_RGB_BEST_MAP) || (property == XA_RGB_DEFAULT_MAP)) {
                                                                                         >  	if ((v1 = getDeepestVisual(StaticColor, vinfo, nvisuals, 
                                                                                         >  				    targets, ntargets)) != NULL){
                                                                                         >  	    FREE_PEX_TARGETS
                                                                                         >  	    return v1;
                                                                                         >  	}
                                                                                         >      }
                                                                                         >      if (property == XA_RGB_GRAY_MAP) {
                                                                                         >  	if (((v1 = getDeepestVisual(GrayScale, vinfo, nvisuals, 
                                                                                         >  				    targets, ntargets)) != NULL) ||
                                                                                         >  	    ((v1 = getDeepestVisual(StaticGray, vinfo, nvisuals, 
                                                                                         >  				    targets, ntargets)) != NULL)){
                                                                                         >  	    FREE_PEX_TARGETS
                                                                                         >  	    return v1;
                                                                                         >  	}
                                                                                         >      }
                                                                                         >      FREE_PEX_TARGETS
                                                                                         >      return v1;
                                                                                         >  }
                                                                                         >  
                                                                                         >  #undef	FREE_PEX_TARGETS
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
                                                                                         >  
static char *visualStringFromClass(class)
    int	class;
{
    switch (class) {
      case PseudoColor: return "PseudoColor";
      case DirectColor: return "DirectColor";
      case GrayScale: return "GrayScale";
      case StaticColor: return "StaticColor";
      case TrueColor: return "TrueColor";
      case StaticGray: return "StaticGray";
    }
    return "unknown visual class";
}

                                                                                         >  static Status doFullDefault(screen, vinfo, nvisuals, replace, retain)
                                                                                         >      int			screen;
                                                                                         >      XVisualInfo		*vinfo;
                                                                                         >      int			nvisuals;
                                                                                         >      int			replace;
                                                                                         >      int			retain;
                                                                                         >  {
                                                                                         >      int 		j;
                                                                                         >      XVisualInfo		*v;
                                                                                         >      Status 		status, overall_status = 0;
                                                                                         >  
                                                                                         >      for (j=0, v=vinfo; j<nvisuals; j++, v++) {
                                                                                         >  
                                                                                         >  	if ((verbose) & !all)
                                                                                         >  	    (void) fprintf(stderr,
                                                                                         >  		       "%s: making %s entry on a %s visual of depth %u.\n",
                                                                                         >  		       program_name, propertyTable[DEFAULT].name,
                                                                                         >  		       visualStringFromClass(v->class), v->depth);
                                                                                         >  
                                                                                         >  	status = XmuLookupStandardColormapExt(dpy, screen, v->visualid,
                                                                                         >  				   v->depth,
                                                                                         >  				   propertyTable[DEFAULT].property,
                                                                                         >  				   replace, retain, &params);
                                                                                         >  	overall_status |= status;
                                                                                         >  
                                                                                         >  	if ((verbose) & !all)
                                                                                         >  	    (void) fprintf(stderr,
                                                                                         >  		       "%s: %s standard colormap entry %s.\n", program_name,
                                                                                         >  		       propertyTable[DEFAULT].name, (status)
                                                                                         >  		       ? "was created or already exists"
                                                                                         >  		       : "cannot be defined");
                                                                                         >      }
                                                                                         >  
                                                                                         >      return overall_status;
                                                                                         >  }
                                                                                         >  
static int doIndividualColormaps()
{
    int			i, screen, nvisuals;
    Status		status;
    XVisualInfo		*vinfo = NULL, *v = NULL, template;

                                                                                         >      /*
                                                                                         >  	Note:   This procedure only creates properties on the default
                                                                                         >  	        screen for the connection.   If PEX is required, it will
                                                                                         >  		return a failure status if PEX is not supported on the
                                                                                         >  		default screen.  That means that -pex with any of the 
                                                                                         >  		individual options (-best, -default, etc.) might fail, 
                                                                                         >  		but -pex -all might succeed since it's happy with PEX support
                                                                                         >  		on any one screen.
                                                                                         >      */
    screen = DefaultScreen(dpy);
    template.screen = screen;
    vinfo = XGetVisualInfo(dpy, VisualScreenMask, &template, &nvisuals);

    /* check for individual standard colormap requests */
    for (i=0; i < NPROPERTIES; i++) {

	if (propertyTable[i].delete) {
	    XmuDeleteStandardColormap(dpy, screen, propertyTable[i].property);
	    if (verbose)
		fprintf(stderr, "%s: %s was deleted or did not exist.\n",
			program_name, propertyTable[i].name);
	}

	if (! propertyTable[i].create)	
	    continue;

                                                                                         >  	if ((propertyTable[i].property == XA_RGB_DEFAULT_MAP) && 
                                                                                         >  	    full_default)
                                                                                         >  
                                                                                         >  	    status = doFullDefault(screen, vinfo, nvisuals,
                                                                                         >  				   DO_NOT_REPLACE, RETAIN);
                                                                                         >  
                                                                                         >  	else {
	/* which visual is best for this property? */
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  	    if (pex)
                                                                                         >  		v = getBestPEXVisual(propertyTable[i].property, vinfo,nvisuals);
                                                                                         >  	    else
                                                                                         >  #endif /* ] PEX_SUPPORT */
	v = getBestVisual(propertyTable[i].property, vinfo, nvisuals);
                                                                                         >  
	if (v == NULL) {
	    if (verbose)
		(void) fprintf(stderr,
		       "%s: no visual appropriate for %s on screen %d.\n",
			program_name, propertyTable[i].name, screen);
	    continue;
	}

                                                                                         <  
	if (verbose)
	    (void) fprintf(stderr,
			   "%s: making %s on a %s visual of depth %u.\n",
			   program_name, propertyTable[i].name,
			   visualStringFromClass(v->class), v->depth);

	status = XmuLookupStandardColormap(dpy, screen, v->visualid,                     |  	    status = XmuLookupStandardColormapExt(dpy, screen, v->visualid,
					   v->depth,
					   propertyTable[i].property,
					   DO_NOT_REPLACE, RETAIN);                      |  					       DO_NOT_REPLACE, RETAIN, 
                                                                                         >  					       &params);
	if (verbose)
	    (void) fprintf(stderr,
			   "%s: %s standard colormap %s.\n", program_name,
			   propertyTable[i].name, (status)
			   ? "was created or already exists"
			   : "cannot be defined");
                                                                                         >  	}
                                                                                         >  
	if (!status)
	    break;
    }
    XFree((char *) vinfo);
    return status;
}

/* Bare bones standard colormap generation utility */
main(argc, argv)
    int		argc;
    char	**argv;
{
    Status	status = 0;
                                                                                         >      XmuParam    param_array[3];
                                                                                         >      int		param_index;

    if (program_name = rindex(*argv, '/'))
	program_name++;
    else
	program_name = *argv;

    parse(argc, argv);

    if ((dpy = XOpenDisplay(display_name)) == NULL) {
	(void) fprintf(stderr, "%s: cannot open display \"%s\".\n",
		       program_name, XDisplayName(display_name));
	exit(1);
    }

    if (help) {
	usage(0);
	Exit(0);
    }

                                                                                         >  /*
                                                                                         >  XSynchronize (dpy, 1);
                                                                                         >  */
                                                                                         >  
                                                                                         >      /*
                                                                                         >  	Set up controls and hints.  When modifying this code, make sure
                                                                                         >  	all controls are set up before any hints.  Also, you may need to
                                                                                         >  	increase size of param_array, above.
                                                                                         >      */
                                                                                         >  
                                                                                         >      param_index = 0;
                                                                                         >      params.num_controls = 0;
                                                                                         >      params.controls = &(param_array[param_index]);
                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >      if (pex) {
                                                                                         >  	PEXExtensionInfo *ext_info;
                                                                                         >  	char error_string[256];
                                                                                         >  
                                                                                         >  	if (PEXInitialize (dpy, &ext_info, 255, error_string)) {
                                                                                         >  	    status = 0;
                                                                                         >  	    (void) fprintf(stderr,
                                                                                         >  			   "%s: cannot initialize PEX on \"%s\".\n",
                                                                                         >  			   program_name, XDisplayName(display_name));
                                                                                         >  	    error_string[255] = '\0';
                                                                                         >  	    (void) fprintf(stderr,
                                                                                         >  			   "%s: PEX error string is \"%s\".\n",
                                                                                         >  			   program_name, error_string);
                                                                                         >  	    exit(1);
                                                                                         >  	}
                                                                                         >  
                                                                                         >  	params.num_controls++;
                                                                                         >  	param_array[param_index].name = XMU_CONTROL_PEX_SUPPORTED;
                                                                                         >  	param_array[param_index].value = True;
                                                                                         >  	param_index++;
                                                                                         >      }
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
                                                                                         >      params.num_hints = 0;
                                                                                         >      params.hints = &(param_array[param_index]);
                                                                                         >  
                                                                                         >      if (ramp_hint) {
                                                                                         >  	params.num_hints++;
                                                                                         >  	param_array[param_index].name = XMU_HINT_PSEUDO_RAMP;
                                                                                         >  	param_array[param_index].value = ramp_hint;
                                                                                         >  	param_index++;
                                                                                         >      }
                                                                                         >  
                                                                                         >      if (full_default) {
                                                                                         >  	params.num_hints++;
                                                                                         >  	param_array[param_index].name = XMU_HINT_CREATE_DEFAULT;
                                                                                         >  	param_array[param_index].value = True;
                                                                                         >  	param_index++;
                                                                                         >      }
                                                                                         >  
                                                                                         >  
                                                                                         >      /*
                                                                                         >  	Now create the properties.
                                                                                         >      */
    if (all) {
                                                                                         >  
	if (verbose)
	    (void) fprintf(stderr,
			   "%s: making all appropriate standard colormaps...",
			   program_name);
	status = XmuAllStandardColormaps(dpy);                                           |  	status = XmuAllStandardColormapsExt(dpy, &params);
                                                                                         >  
                                                                                         >  	if (status && full_default) {
                                                                                         >  
                                                                                         >  	    int			screen, nvisuals;
                                                                                         >  	    XVisualInfo		*vinfo = NULL, template;
                                                                                         >  	    int			overall_status = 1;
                                                                                         >  
                                                                                         >  	    /* for each screen, determine all visuals of this server */
                                                                                         >  	    for (screen=0; screen < ScreenCount(dpy); screen++)
                                                                                         >  	    {
                                                                                         >  		template.screen = screen;
                                                                                         >  		vinfo = XGetVisualInfo(dpy, VisualScreenMask, &template, 
                                                                                         >  					&nvisuals);
                                                                                         >  		if (vinfo == NULL)
                                                                                         >  		    continue;
                                                                                         >  
                                                                                         >  		status = doFullDefault(screen, vinfo, nvisuals, 
                                                                                         >  					REPLACE, RETAIN);
                                                                                         >  		overall_status &= status;
                                                                                         >  
                                                                                         >  		XFree ((char *) vinfo);
                                                                                         >  
                                                                                         >  		if (!status) break;
                                                                                         >  	    }
                                                                                         >  	    status = overall_status;
                                                                                         >  	}
                                                                                         >  
	if (verbose)
	    (void) fprintf(stderr,
			   "\n%s!\n", (status) ? "success" : "failure");
    }
    else {
	status = doIndividualColormaps();                                                |  	status = doIndividualColormaps(&params);
	if (!status && verbose)
	    (void) fprintf(stderr, 
		    "Not all new colormap definitions will be retained.\n");
    }
    Exit((status == 0) ? 1 : 0);
}
============== AllCmap
/* $XConsortium: AllCmap.c,v 1.6 89/10/08 14:52:32 rws Exp $
 * 
 * Copyright 1989 by the Massachusetts Institute of Technology
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided 
 * that the above copyright notice appear in all copies and that both that 
 * copyright notice and this permission notice appear in supporting 
 * documentation, and that the name of M.I.T. not be used in advertising
 * or publicity pertaining to distribution of the software without specific, 
 * written prior permission. M.I.T. makes no representations about the 
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Author:  Donna Converse, MIT X Consortium
 */

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/Xmu/StdCmap.h>
                                                                                         >  #include <X11/Xmu/StdCmapExt.h>
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  #include <X11/PEX5/PEXlib.h>
                                                                                         >  #endif /* ] PEX_SUPPORT */

static XVisualInfo *getDeepestVisual();

/*
 * To create all of the appropriate standard colormaps for every visual of
 * every screen on a given display, use XmuAllStandardColormaps.                         |   * every screen on a given display, use XmuAllStandardColormapsExt().
 *
 * Define and retain as permanent resources all standard colormaps which are
 * meaningful for the visuals of each screen of the display.  Return 0 on
 * failure, non-zero on success.  If the property of any standard colormap 
 * is already defined, redefine it.
 *
 * This interface is intended to be used by window managers or a client
 * upon start-up of a session.
 *
 * The standard colormaps of a screen are defined by properties associated
 * with the screen's root window.  Each screen has exactly one root window.
 * The property names of standard colormaps are predefined, and each property
 * name may describe at most one colormap.
 * 
 * The standard colormaps are
 *		RGB_BEST_MAP
 *		RGB_RED_MAP
 *		RGB_GREEN_MAP
 *		RGB_BLUE_MAP
 *		RGB_DEFAULT_MAP
 *		RGB_GRAY_MAP
 *
                                                                                         >   *
 * Therefore a screen may have at most 6 standard colormap properties defined.
 *
 * A standard colormap is associated with a particular visual of the screen.
 * A screen may have multiple visuals defined, including visuals of the same
 * class at different depths.  Note that a visual id might be repeated for
 * more than one depth, so the visual id and the depth of a visual identify
 * the visual.  The characteristics of the visual will determine which
 * standard colormaps are meaningful under that visual, and will determine
 * how the standard colormap is defined.  Because a standard colormap is
 * associated with a specific visual, there must be a method of determining
 * which visuals take precedence in defining standard colormaps.
 * 
 * The method used here is: for the visual of greatest depth, define all 
 * standard colormaps meaningful to that visual class, according to this                 |   * standard colormaps meaningful to that visual class.  The visual is chosen
 * order of (descending) precedence:                                                     |   * according to this order of (descending) precedence:
 *	1. DirectColor                                                                   <  
 *	2. PseudoColor                                                                   <  
 *	3. TrueColor and GrayScale                                                       <  
 *	4. StaticColor and StaticGray                                                    <  
 *
                                                                                         >   * Without the XMU_CONTROL_PEX_SUPPORTED requirement:
                                                                                         >   *
                                                                                         >   *	if there is a DirectColor or PseudoColor Visual
                                                                                         >   *        the one with the most colors is chosen for all properties, 
                                                                                         >   *	  PseudoColor preferred in a tie
                                                                                         >   *	else
                                                                                         >   *	  if there is a TrueColor it is chosen 
                                                                                         >   *	  else if a StaticColor it is chosen
                                                                                         >   *
                                                                                         >   *	  if there is a GrayScale it is chosen (possibly in addition to
                                                                                         >   *          to TrueColor/StaticColor)
                                                                                         >   *	  else if there is a StaticGray it is chosen (possibly in addition to
                                                                                         >   *          to TrueColor/StaticColor)
                                                                                         >   *
                                                                                         >   * With the XMU_CONTROL_PEX_SUPPORTED requirement:
                                                                                         >   *
                                                                                         >   *	if there is a TrueColor, DirectColor, or PseudoColor Visual
                                                                                         >   *        the one with the most colors is chosen for all properties, 
                                                                                         >   *	  tiebreaker order is TrueColor, DirectColor, PseudoColor
                                                                                         >   *	else
                                                                                         >   *	  if there is a StaticColor it is chosen
                                                                                         >   *
                                                                                         >   *	  if there is a GrayScale it is chosen (possibly in addition to
                                                                                         >   *          to StaticColor)
                                                                                         >   *	  else if there is a StaticGray it is chosen (possibly in addition to
                                                                                         >   *          to StaticColor)
                                                                                         >   *
 * Allows partial success by screenful.  For example, if a map on screen 1
 * fails, the maps on screen 0, created earlier, will remain.  However,
 * none on screen 1 will remain.  If a map on 0 fails, none will remain.
 *
 * See the comments under XmuVisualStandardColormaps() for notes on which                |   * See the comments under XmuVisualStandardColormapsExt() for notes on which
 * standard colormaps are meaningful under these classes of visuals.
 */

Status XmuAllStandardColormaps(dpy)                                                      |  Status XmuAllStandardColormapsExt(dpy, params)
    Display	*dpy;		/* Specifies the connection to the X server */
                                                                                         >      XmuExtendedParams 	*params;/* controls and hints */
{
    int 	nvisuals, scr;
    Status	status;
    long	vinfo_mask;
    XVisualInfo	template, *vinfo, *v1, *v2;                                              |      XVisualInfo		template, *vinfo;
                                                                                         >      XVisualInfo		*v0 = NULL, *v1 = NULL, *v2 = NULL, *v_chosen = NULL;
                                                                                         >      int			ncolors_v0 = 0, ncolors_v1 = 0, ncolors_v2 = 0;
                                                                                         >      int			ncolors_chosen = 0;
                                                                                         >      unsigned long	ntargets = 0;
                                                                                         >      char *		targets = NULL;
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >      int			PEX_required = False;
                                                                                         >      int			PEX_required_on_screen = False;
                                                                                         >      int			pex_control_index;
                                                                                         >  #endif /* ] PEX_SUPPORT */

                                                                                         >      /*
                                                                                         >  	Decipher the controls and hints currently supported in this procedure.
                                                                                         >  	Set flags for the PEX requirement, and for the static policy hint.
                                                                                         >      */
                                                                                         >      if (params) {
                                                                                         >  	int i;
                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  	for (i=0; i < params->num_controls; i++) {
                                                                                         >  	    if (params->controls[i].name == XMU_CONTROL_PEX_SUPPORTED) {
                                                                                         >  		PEX_required = params->controls[i].value;
                                                                                         >  		pex_control_index = i;
                                                                                         >  	    }
                                                                                         >  	}
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >      }
                                                                                         >  
                                                                                         >  
    /* for each screen, determine all visuals of this server */
    for (scr=0; scr < ScreenCount(dpy); scr++)
    {
                                                                                         >  	status = 0;
                                                                                         >  
	template.screen = scr;
	vinfo_mask = VisualScreenMask;
	vinfo = XGetVisualInfo(dpy, vinfo_mask, &template, &nvisuals);
	if (vinfo == NULL) /* unexpected: a screen with no visuals */
	    continue;

	v1 = getDeepestVisual(DirectColor, vinfo, nvisuals);                             |  	targets = NULL;
	v2 = getDeepestVisual(PseudoColor, vinfo, nvisuals);                             |  	ntargets = 0;

	if (v2 &&                                                                        |  #ifdef PEX_SUPPORT /* [ */
	    (!v1 || (v2->colormap_size >=                                                |  	/*
		     ((v1->red_mask | v1->green_mask | v1->blue_mask) + 1))))            |  	    If PEX support is required, get the targets if possible.
	    status = XmuVisualStandardColormaps(dpy, scr, v2->visualid,                  |  	*/
						(unsigned) v2->depth, 1, 1);             |  	if (PEX_required) {
	else if (v1)                                                                     |  	    PEXExtensionInfo	*ext_info;
	    status = XmuVisualStandardColormaps(dpy, scr, v1->visualid,                  <  
						(unsigned) v1->depth, 1, 1);             <  

                                                                                         >  	    if (NULL == (ext_info = PEXGetExtensionInfo (dpy))) {
                                                                                         >  		XFree ((char *) vinfo);
                                                                                         >  		return 0;
                                                                                         >  	    }
                                                                                         >  
                                                                                         >  	    if ((ext_info->major_version == 5) &&
                                                                                         >  		(ext_info->minor_version >= 1)) {
                                                                                         >  
                                                                                         >  		if (! PEXMatchRenderingTargets (dpy, 
                                                                                         >  					    RootWindow(dpy, scr),
                                                                                         >  					    0, PEXWindowDrawable, NULL,
                                                                                         >  					    64, &ntargets, 
                                                                                         >  					    (PEXRenderingTarget**) &targets)) {
                                                                                         >  		    XFree ((char *) vinfo);
                                                                                         >  		    return 0;
                                                                                         >  		}
                                                                                         >  	    }
                                                                                         >  
                                                                                         >  	    if (ntargets == 0) {
                                                                                         >  		/* 
                                                                                         >  		    If PEX is not supported on this screen (and it's not 
                                                                                         >  		    the only screen) then don't require PEX for this screen.
                                                                                         >  		*/
                                                                                         >  		if (ScreenCount(dpy) > 1) {
                                                                                         >  		    PEX_required_on_screen = False;
                                                                                         >  		    params->controls[pex_control_index].value = False;
                                                                                         >  		}
	else {
	    if (((v1 = getDeepestVisual(TrueColor, vinfo, nvisuals)) != NULL)            |  		    XFree ((char *) vinfo);
		|| ((v1 = getDeepestVisual(StaticColor, vinfo, nvisuals)) !=             |  		    return 0;
                                                                                         >  		}
                                                                                         >  	    }
                                                                                         >  	    else
                                                                                         >  		PEX_required_on_screen = True;
                                                                                         >  	}
                                                                                         >  
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
                                                                                         >  	if (v1 = getDeepestVisual(DirectColor, vinfo, nvisuals, 
                                                                                         >  						targets, ntargets))
                                                                                         >  	    ncolors_v1 = ((v1->red_mask | v1->green_mask | v1->blue_mask) + 1);
                                                                                         >  
                                                                                         >  	if (v2 = getDeepestVisual(PseudoColor, vinfo, nvisuals, 
                                                                                         >  						targets, ntargets))
                                                                                         >  	    ncolors_v2 = v2->colormap_size;
                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  	if (PEX_required_on_screen) {
                                                                                         >  
                                                                                         >  	    if (v0 = getDeepestVisual(TrueColor, vinfo, nvisuals, 
                                                                                         >  						    targets, ntargets))
                                                                                         >  		ncolors_v0 = ((v0->red_mask | v0->green_mask | v0->blue_mask) 
                                                                                         >  				+ 1);
                                                                                         >  
                                                                                         >  	    if (ncolors_v1 >= ncolors_v2) {
                                                                                         >  		v_chosen = v1;
                                                                                         >  		ncolors_chosen = ncolors_v1;
                                                                                         >  	    }
                                                                                         >  	    else {
                                                                                         >  		v_chosen = v2;
                                                                                         >  		ncolors_chosen = ncolors_v2;
                                                                                         >  	    }
                                                                                         >  
                                                                                         >  	    if (ncolors_v0 >= ncolors_chosen) {
                                                                                         >  		v_chosen = v0;
                                                                                         >  		ncolors_chosen = ncolors_v0;
                                                                                         >  	    }
                                                                                         >  	}
                                                                                         >  	else {
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
                                                                                         >  	if (ncolors_v2 >= ncolors_v1) 
                                                                                         >  	{
                                                                                         >  	    v_chosen = v2;
                                                                                         >  	    ncolors_chosen = ncolors_v2;
                                                                                         >  	}
                                                                                         >  	else 
                                                                                         >  	{
                                                                                         >  	    v_chosen = v1;
                                                                                         >  	    ncolors_chosen = ncolors_v1;
                                                                                         >  	}
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  	}
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
                                                                                         >  	if (v_chosen) {
                                                                                         >  	    status = XmuVisualStandardColormapsExt(dpy, scr, v_chosen->visualid,
                                                                                         >  					(unsigned) v_chosen->depth, 1, 1, 
                                                                                         >  					params);
                                                                                         >  	}
                                                                                         >  	else {
                                                                                         >  	    if ((
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  		!PEX_required_on_screen && 
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  		((v1 = getDeepestVisual(TrueColor, vinfo, nvisuals, 
                                                                                         >  				    targets, ntargets)) != NULL))
                                                                                         >  		|| ((v1 = getDeepestVisual(StaticColor, vinfo, nvisuals, 
                                                                                         >  				    targets, ntargets)) !=
		NULL))
		status = XmuVisualStandardColormaps(dpy, scr, v1->visualid,              |  		status = XmuVisualStandardColormapsExt(dpy, scr, 
						   (unsigned) v1->depth, 1, 1);          |  			v1->visualid, (unsigned) v1->depth, 1, 1, params);
	    if (status && 
	       (((v1 = getDeepestVisual(GrayScale, vinfo, nvisuals)) != NULL)            |  	       (((v1 = getDeepestVisual(GrayScale, vinfo, nvisuals, 
		|| ((v1 = getDeepestVisual(StaticGray, vinfo, nvisuals)) !=              |  				    targets, ntargets)) != NULL)
                                                                                         >  		|| ((v1 = getDeepestVisual(StaticGray, vinfo, nvisuals, 
                                                                                         >  				    targets, ntargets)) != 
		    NULL)))
		status = XmuVisualStandardColormaps(dpy, scr, v1->visualid,              |  		status = XmuVisualStandardColormapsExt(dpy, scr, 
						   (unsigned) v1->depth, 1, 1);          |  			v1->visualid, (unsigned) v1->depth, 1, 1, params);
	}
                                                                                         >  
	XFree ((char *) vinfo);
                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  	if (PEX_required) {
                                                                                         >  	    params->controls[pex_control_index].value = True;
                                                                                         >  	    if (ntargets) XFree (targets);
                                                                                         >  	}
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
	if (!status) break;
    }
                                                                                         >  
    return status;
}

static XVisualInfo *getDeepestVisual(visual_class, vinfo, nvisuals)                      |  
                                                                                         >  static XVisualInfo *getDeepestVisual(visual_class, vinfo, nvisuals, 
                                                                                         >  					targets, ntargets)
    int		visual_class;	/* specifies the visual class */
    XVisualInfo	*vinfo;		/* specifies all visuals for a screen */
    int		nvisuals;	/* specifies number of visuals in the list */
                                                                                         >      char 	*targets;	/* PEX target list, NULL if PEX not required */
                                                                                         >      int		ntargets;	/* specifes count of PEX targets */
{
    register int	i;
    unsigned int	maxdepth = 0;
    XVisualInfo		*v = NULL;

    for (i=0; i < nvisuals; i++, vinfo++)                                                |      for (i=0; i < nvisuals; i++, vinfo++) {
                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  	/*
                                                                                         >  	    Filter so only PEX-supported Visuals are considered.
                                                                                         >  	*/
                                                                                         >  	if (ntargets) {
                                                                                         >  	    int PEX_supported_on_Visual;
                                                                                         >  	    PEXRenderingTarget	*p_target;
                                                                                         >  	    int j;
                                                                                         >  
                                                                                         >  	    PEX_supported_on_Visual = False;
                                                                                         >  	    for (j=0, p_target = (PEXRenderingTarget *) targets; 
                                                                                         >  		    j < ntargets; j++, p_target++) {
                                                                                         >  
                                                                                         >  		if ((p_target->depth == vinfo->depth) &&
                                                                                         >  		   (XVisualIDFromVisual(p_target->visual) == vinfo->visualid)) {
                                                                                         >  		    PEX_supported_on_Visual = True;
                                                                                         >  		    break;
                                                                                         >  		}
                                                                                         >  	    }
                                                                                         >  	    if (!PEX_supported_on_Visual)
                                                                                         >  		continue;
                                                                                         >  	}
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
	if (vinfo->class == visual_class && vinfo->depth > maxdepth)
	{
	    maxdepth = vinfo->depth;
	    v = vinfo;
                                                                                         >  	}
	}
    return(v);
}

============== CmapAlloc
/*
 * $XConsortium: CmapAlloc.c,v 1.7 92/11/24 14:15:51 rws Exp $
 * 
 * Copyright 1989 by the Massachusetts Institute of Technology
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided 
 * that the above copyright notice appear in all copies and that both that 
 * copyright notice and this permission notice appear in supporting 
 * documentation, and that the name of M.I.T. not be used in advertising
 * or publicity pertaining to distribution of the software without specific, 
 * written prior permission. M.I.T. makes no representations about the 
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Author:  Donna Converse, MIT X Consortium
 */

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <stdio.h>
                                                                                         >  #include <X11/Xmu/StdCmapExt.h>

#define lowbit(x) ((x) & (~(x) + 1))

static int default_allocation();
static void best_allocation();
static void gray_allocation();
static int icbrt();
static int icbrt_with_bits();
static int icbrt_with_guess();

/* To determine the best allocation of reds, greens, and blues in a 
 * standard colormap, use XmuGetColormapAllocation.                                      |   * standard colormap, use XmuGetColormapAllocationExt.
 * 	vinfo		specifies visual information for a chosen visual
 *	property	specifies one of the standard colormap property names
                                                                                         >   *	params		specifies controls and hints to be applied
 * 	red_max		returns maximum red value 
 *      green_max	returns maximum green value
 * 	blue_max	returns maximum blue value
 *
 * XmuGetColormapAllocation returns 0 on failure, non-zero on success.                   |   * XmuGetColormapAllocationExt returns 0 on failure, non-zero on success.
 * It is assumed that the visual is appropriate for the colormap property.
 */

Status XmuGetColormapAllocation(vinfo, property, red_max, green_max, blue_max)           |  Status XmuGetColormapAllocationExt(vinfo, property, params,
                                                                                         >  				red_max, green_max, blue_max)
    XVisualInfo		*vinfo;
    Atom		property;
                                                                                         >      XmuExtendedParams 	*params;			/* controls and hints */
    unsigned long	*red_max, *green_max, *blue_max;
{
    Status 	status = 1;

    if (vinfo->colormap_size <= 2)
	return 0;

    switch (property)
    {
      case XA_RGB_DEFAULT_MAP:
	status = default_allocation(vinfo, red_max, green_max, blue_max);
	break;
      case XA_RGB_BEST_MAP:
	best_allocation(vinfo, red_max, green_max, blue_max);
	break;
      case XA_RGB_GRAY_MAP:
	gray_allocation(vinfo->colormap_size, red_max, green_max, blue_max);
	break;
      case XA_RGB_RED_MAP:
	*red_max = vinfo->colormap_size - 1;
	*green_max = *blue_max = 0;
	break;
      case XA_RGB_GREEN_MAP:
	*green_max = vinfo->colormap_size - 1;
	*red_max = *blue_max = 0;
	break;
      case XA_RGB_BLUE_MAP:
	*blue_max = vinfo->colormap_size - 1;
	*red_max = *green_max = 0;
	break;
      default:
	status = 0;
    }
    return status;
}

/****************************************************************************/
/* Determine the appropriate color allocations of a gray scale.
 *
 * Keith Packard, MIT X Consortium
 */

static void gray_allocation(n, red_max, green_max, blue_max)
    int		n;	/* the number of cells of the gray scale */
    unsigned long *red_max, *green_max, *blue_max;
{
    *red_max = (n * 30) / 100;
    *green_max = (n * 59) / 100; 
    *blue_max = (n * 11) / 100; 
    *green_max += ((n - 1) - (*red_max + *green_max + *blue_max));
}

/****************************************************************************/
/* Determine an appropriate color allocation for the RGB_DEFAULT_MAP.
 * If a map has less than a minimum number of definable entries, we do not
 * produce an allocation for an RGB_DEFAULT_MAP.  
 *
 * For 16 planes, the default colormap will have 27 each RGB; for 12 planes,
 * 12 each.  For 8 planes, let n = the number of colormap entries, which may
 * be 256 or 254.  Then, maximum red value = floor(cube_root(n - 125)) - 1.
 * Maximum green and maximum blue values are identical to maximum red.
 * This leaves at least 125 cells which clients can allocate.
 *
 * Return 0 if an allocation has been determined, non-zero otherwise.
 */

static int default_allocation(vinfo, red, green, blue)
    XVisualInfo		*vinfo;
    unsigned long	*red, *green, *blue;
{
    int			ngrays;		/* number of gray cells */

                                                                                         >      if ((vinfo->class != TrueColor) && (vinfo->class != DirectColor))
    if (vinfo->colormap_size < 250)	/* skip it */
	return 0;

    switch (vinfo->class) {
      case PseudoColor:

	if (vinfo->colormap_size > 65000)
	    /* intended for displays with 16 planes */
	    *red = *green = *blue = (unsigned long) 27;
	else if (vinfo->colormap_size > 4000)
	    /* intended for displays with 12 planes */
	    *red = *green = *blue = (unsigned long) 12;
	else
	    /* intended for displays with 8 planes */
	    *red = *green = *blue = (unsigned long)
		(icbrt(vinfo->colormap_size - 125) - 1);
	break;

      case DirectColor:

	*red = *green = *blue = vinfo->colormap_size / 2 - 1;
	break;

      case TrueColor:

	*red = vinfo->red_mask / lowbit(vinfo->red_mask);
	*green = vinfo->green_mask / lowbit(vinfo->green_mask);
	*blue = vinfo->blue_mask / lowbit(vinfo->blue_mask);
	break;

      case GrayScale:

	if (vinfo->colormap_size > 65000)
	    ngrays = 4096;
	else if (vinfo->colormap_size > 4000)
	    ngrays = 512;
	else
	    ngrays = 12;
	gray_allocation(ngrays, red, green, blue);
	break;

      default:
	return 0;
    }
    return 1;
}

/****************************************************************************/
/* Determine an appropriate color allocation for the RGB_BEST_MAP.
 *
 * For a DirectColor or TrueColor visual, the allocation is determined
 * by the red_mask, green_mask, and blue_mask members of the visual info.
 *
 * Otherwise, if the colormap size is an integral power of 2, determine
 * the allocation according to the number of bits given to each color,
 * with green getting more than red, and red more than blue, if there
 * are to be inequities in the distribution.  If the colormap size is
 * not an integral power of 2, let n = the number of colormap entries.
 * Then maximum red value = floor(cube_root(n)) - 1;
 * 	maximum blue value = floor(cube_root(n)) - 1;
 *	maximum green value = n / ((# red values) * (# blue values)) - 1;
 * Which, on a GPX, allows for 252 entries in the best map, out of 254
 * defineable colormap entries.
 */

static void best_allocation(vinfo, red, green, blue)
    XVisualInfo		*vinfo;
    unsigned long	*red, *green, *blue;
{

    if (vinfo->class == DirectColor ||	vinfo->class == TrueColor)
    {
	*red = vinfo->red_mask;
	while ((*red & 01) == 0)
	    *red >>= 1;
	*green = vinfo->green_mask;
	while ((*green & 01) == 0)
	    *green >>=1;
	*blue = vinfo->blue_mask;
	while ((*blue & 01) == 0)
	    *blue >>= 1;
    }
    else
    {
	register int bits, n;

	/* Determine n such that n is the least integral power of 2 which is
	 * greater than or equal to the number of entries in the colormap.
         */
	n = 1;
	bits = 0;
	while (vinfo->colormap_size > n)
	{
	    n = n << 1;
	    bits++;
	}

	/* If the number of entries in the colormap is a power of 2, determine
	 * the allocation by "dealing" the bits, first to green, then red, then
	 * blue.  If not, find the maximum integral red, green, and blue values
	 * which, when multiplied together, do not exceed the number of 

	 * colormap entries.
	 */
	if (n == vinfo->colormap_size)
	{
	    register int r, g, b;
	    b = bits / 3;
	    g = b + ((bits % 3) ? 1 : 0);
	    r = b + (((bits % 3) == 2) ? 1 : 0);
	    *red = 1 << r;
	    *green = 1 << g;
	    *blue = 1 << b;
	}
	else
	{
	    *red = icbrt_with_bits(vinfo->colormap_size, bits);
	    *blue = *red;	
	    *green = (vinfo->colormap_size / ((*red) * (*blue)));
	}
	(*red)--;
	(*green)--;
	(*blue)--;
    }
    return;
}

/*
 * integer cube roots by Newton's method
 *
 * Stephen Gildea, MIT X Consortium, July 1991
 */

static int icbrt(a)		/* integer cube root */
    int a;
{
    register int bits = 0;
    register unsigned n = a;

    while (n)
    {
	bits++;
	n >>= 1;
    }
    return icbrt_with_bits(a, bits);
}


static int icbrt_with_bits(a, bits)
    int a;
    int bits;			/* log 2 of a */
{
    return icbrt_with_guess(a, a>>2*bits/3);
}

#ifdef _X_ROOT_STATS
int icbrt_loopcount;
#endif

/* Newton's Method:  x_n+1 = x_n - ( f(x_n) / f'(x_n) ) */

/* for cube roots, x^3 - a = 0,  x_new = x - 1/3 (x - a/x^2) */

/*
 * Quick and dirty cube roots.  Nothing fancy here, just Newton's method.
 * Only works for positive integers (since that's all we need).
 * We actually return floor(cbrt(a)) because that's what we need here, too.
 */

static int icbrt_with_guess(a, guess)
    int a, guess;
{
    register int delta;

#ifdef _X_ROOT_STATS
    icbrt_loopcount = 0;
#endif
    if (a <= 0)
	return 0;
    if (guess < 1)
	guess = 1;

    do {
#ifdef _X_ROOT_STATS
	icbrt_loopcount++;
#endif
	delta = (guess - a/(guess*guess))/3;
#ifdef DEBUG
	printf("pass %d: guess=%d, delta=%d\n", icbrt_loopcount, guess, delta);
#endif
	guess -= delta;
    } while (delta != 0);

    if (guess*guess*guess > a)
	guess--;

    return guess;
}
============== CrCmap
/* $XConsortium: CrCmap.c,v 1.5 92/11/24 14:40:47 rws Exp $
 *
 * CreateCmap.c - given a standard colormap description, make the map.
 * 
 * Copyright 1989 by the Massachusetts Institute of Technology
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided 
 * that the above copyright notice appear in all copies and that both that 
 * copyright notice and this permission notice appear in supporting 
 * documentation, and that the name of M.I.T. not be used in advertising
 * or publicity pertaining to distribution of the software without specific, 
 * written prior permission. M.I.T. makes no representations about the 
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Author:  Donna Converse, MIT X Consortium
 */

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
                                                                                         >  #include <X11/Xmu/StdCmapExt.h>

extern char	*calloc();

static int	ROmap();		/* allocate entire map Read Only */
static Status	ROorRWcell();		/* allocate a cell, prefer Read Only */
static Status	RWcell();		/* allocate a cell Read Write */
static int	compare();		/* for quicksort */
static Status 	contiguous();		/* find contiguous sequence of cells */
static void	free_cells();		/* frees resources before quitting */
static Status	readonly_map();		/* create a map in a RO visual type */
static Status	readwrite_map();	/* create a map in a RW visual type */

#define lowbit(x) ((x) & (~(x) + 1))
#define TRUEMATCH(mult,max,mask) \
    (colormap->max * colormap->mult <= vinfo->mask && \
     lowbit(vinfo->mask) == colormap->mult)

/*
 * To create any one colormap which is described by an XStandardColormap
 * structure, use XmuCreateColormap().                                                   |   * structure, use XmuCreateColormapExt().
 *
 * Return 0 on failure, non-zero on success.
 * Resources created by this function are not made permanent.
 * No argument error checking is provided.  Use at your own risk.
 *
 * All colormaps are created with read only allocations, with the exception
 * of read only allocations of colors in the default map or otherwise
 * which fail to return the expected pixel value, and these are individually 
 * defined as read/write allocations.  This is done so that all the cells
 * defined in the default map are contiguous, for use in image processing.
 * This typically happens with White and Black in the default map.
 *
 * Colormaps of static visuals are considered to be successfully created if
 * the map of the static visual matches the definition given in the
 * standard colormap structure.
 */

Status XmuCreateColormap(dpy, colormap)                                                  |  Status XmuCreateColormapExt(dpy, colormap, params)
    Display		*dpy;		/* specifies the connection under 
					 * which the map is created */
    XStandardColormap	*colormap;	/* specifies the map to be created,
					 * and returns, particularly if the
					 * map is created as a subset of the
					 * default colormap of the screen,
					 * the base_pixel of the map.
					 */
                                                                                         >      XmuExtendedParams 	*params;	/* controls and hints */
{
    XVisualInfo		vinfo_template;	/* template visual information */
    XVisualInfo		*vinfo;		/* matching visual information */
    XVisualInfo		*vpointer;	/* for freeing the entire list */
    long		vinfo_mask;	/* specifies the visual mask value */
    int 		n;		/* number of matching visuals */
    int			status;		
                                                                                         >      unsigned long	base_pixel_value = NOT_DETERMINED;

                                                                                         >      /*
                                                                                         >  	Decode the controls and hints to be applied in this procedure.
                                                                                         >      */
                                                                                         >      if (params) {
                                                                                         >  	int i;
                                                                                         >  	for (i=0; i < params->num_controls; i++) {
                                                                                         >  	    if (params->controls[i].name == XMU_CONTROL_BASE_PIXEL)
                                                                                         >  		base_pixel_value = (unsigned long) params->controls[i].value;
                                                                                         >  	}
                                                                                         >      }
                                                                                         >  
    vinfo_template.visualid = colormap->visualid;
    vinfo_mask = VisualIDMask;
    if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
	return 0;

                                                                                         >  
    /* A visual id may be valid on multiple screens.  Also, there may 
     * be multiple visuals with identical visual ids at different depths.  
     * If the colormap is the Default Colormap, use the Default Visual.
     * Otherwise, arbitrarily, use the deepest visual.                                   |       * Otherwise, arbitrarily, use the deepest visual with that ID.
     */
    vpointer = vinfo;
    if (n > 1)
    {
	register int	i;
	register int	screen_number;
	Bool 		def_cmap;

	def_cmap = False;
	for (screen_number = ScreenCount(dpy); --screen_number >= 0; )
	    if (colormap->colormap == DefaultColormap(dpy, screen_number)) {
		def_cmap = True;
		break;
	    }

	if (def_cmap) {
	    for (i=0; i < n; i++, vinfo++) {
		if (vinfo->visual == DefaultVisual(dpy, screen_number))
			break;
	    }
	} else {
	    unsigned int	maxdepth = 0;
	    XVisualInfo		*v;

	    for (i=0; i < n; i++, vinfo++)
		if (vinfo->depth > maxdepth) {
		    maxdepth = vinfo->depth;
		    v = vinfo;
		}
	    vinfo = v;
	}
    }

    if (vinfo->class == PseudoColor || vinfo->class == DirectColor ||                    |      if (vinfo->class == PseudoColor || 
                                                                                         >  	vinfo->class == DirectColor ||
	vinfo->class == GrayScale)
	status = readwrite_map(dpy, vinfo, colormap);                                    |  	status = readwrite_map(dpy, vinfo, colormap, base_pixel_value);
                                                                                         >  
    else if (vinfo->class == TrueColor)
	status = TRUEMATCH(red_mult, red_max, red_mask) &&
	         TRUEMATCH(green_mult, green_max, green_mask) &&
		 TRUEMATCH(blue_mult, blue_max, blue_mask);
                                                                                         >      else {
                                                                                         >  	/*
                                                                                         >  	    If base_pixel_value is not NOT_DETERMINED, 
                                                                                         >  	    check value in colormap versus dictated.
                                                                                         >  	*/
                                                                                         >  	if (base_pixel_value != NOT_DETERMINED)
                                                                                         >  	    status = (colormap->base_pixel == base_pixel_value);
    else 
                                                                                         >  	    status = 1;
                                                                                         >  
                                                                                         >  	if (status)
	status = readonly_map(dpy, vinfo, colormap);
                                                                                         >      }

    XFree((char *) vpointer);
    return status;
}

/****************************************************************************/
static Status readwrite_map(dpy, vinfo, colormap)                                        |  static Status readwrite_map(dpy, vinfo, colormap, base_pixel_value)
    Display		*dpy;
    XVisualInfo		*vinfo;
    XStandardColormap	*colormap;
                                                                                         >      unsigned long	base_pixel_value;
{
    register unsigned long i, n;	/* index counters */
    int			ncolors;	/* number of colors to be defined */
    int			npixels;	/* number of pixels allocated R/W */
    int			first_index;	/* first index of pixels to use */
    int			remainder;	/* first index of remainder */
    XColor		color;		/* the definition of a color */
    unsigned long	*pixels;	/* array of colormap pixels */
    unsigned long	delta;


    /* Determine ncolors, the number of colors to be defined.
     * Insure that 1 < ncolors <= the colormap size.
     */
    if (vinfo->class == DirectColor) {
	ncolors = colormap->red_max;
	if (colormap->green_max > ncolors)
	    ncolors = colormap->green_max;
	if (colormap->blue_max > ncolors)
	    ncolors = colormap->blue_max;
	ncolors++;
	delta = lowbit(vinfo->red_mask) +
	        lowbit(vinfo->green_mask) +
		lowbit(vinfo->blue_mask);
                                                                                         >  
                                                                                         >  	if (base_pixel_value != NOT_DETERMINED) {
                                                                                         >  	    if ((((base_pixel_value & vinfo->red_mask) + 
                                                                                         >  		(colormap->red_max * colormap->red_mult)) > 
                                                                                         >  		    vinfo->colormap_size * colormap->red_mult) ||
                                                                                         >  		(((base_pixel_value & vinfo->green_mask) + 
                                                                                         >  		(colormap->green_max * colormap->green_mult)) > 
                                                                                         >  		    vinfo->colormap_size * colormap->green_mult) ||
                                                                                         >  		(((base_pixel_value & vinfo->blue_mask) + 
                                                                                         >  		(colormap->blue_max * colormap->blue_mult)) > 
                                                                                         >  		    vinfo->colormap_size * colormap->blue_mult))
                                                                                         >  		return 0;
                                                                                         >  	}
    } else {
	ncolors = colormap->red_max * colormap->red_mult +
		  colormap->green_max * colormap->green_mult +
		  colormap->blue_max * colormap->blue_mult + 1;
	delta = 1;
                                                                                         >  
                                                                                         >  	if ((base_pixel_value != NOT_DETERMINED) &&
                                                                                         >  	    ((base_pixel_value + ncolors) > vinfo->colormap_size))
                                                                                         >  	    return 0;
    }
    if (ncolors <= 1 || ncolors > vinfo->colormap_size)	return 0;

    /* Allocate Read/Write as much of the colormap as we can possibly get.
     * Then insure that the pixels we were allocated are given in 
     * monotonically increasing order, using a quicksort.  Next, insure
     * that our allocation includes a subset of contiguous pixels at least
     * as long as the number of colors to be defined.  Now we know that 
     * these conditions are met:
     *	1) There are no free cells in the colormap.
     *  2) We have a contiguous sequence of pixels, monotonically 
     *     increasing, of length >= the number of colors requested.
     *
     * One cell at a time, we will free, compute the next color value, 
     * then allocate read only.  This takes a long time.
     * This is done to insure that cells are allocated read only in the
     * contiguous order which we prefer.  If the server has a choice of
     * cells to grant to an allocation request, the server may give us any
     * cell, so that is why we do these slow gymnastics.
     */

    if ((pixels = (unsigned long *) calloc((unsigned) vinfo->colormap_size,
				      sizeof(unsigned long))) == NULL)
	return 0;

    if ((npixels = ROmap(dpy, colormap->colormap, pixels,
			   vinfo->colormap_size, ncolors)) == 0) {
	free((char *) pixels);
	return 0;
    }

    qsort((char *) pixels, npixels, sizeof(unsigned long), compare);

    if (!contiguous(pixels, npixels, ncolors, delta, &first_index, &remainder))          |      if (!contiguous(pixels, npixels, ncolors, delta, base_pixel_value, 
                                                                                         >  			&first_index, &remainder))
    {
	/* can't find enough contiguous cells, give up */
	XFreeColors(dpy, colormap->colormap, pixels, npixels,
		    (unsigned long) 0);
	free((char *) pixels);
	return 0;
    }
                                                                                         >  
    colormap->base_pixel = pixels[first_index];

    /* construct a gray map */
    if (colormap->red_mult == 1 && colormap->green_mult == 1 &&
	colormap->blue_mult == 1)
	for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
	{
	    color.pixel = n;
	    color.blue = color.green = color.red =
		(unsigned short) ((i * 65535) / (colormap->red_max +
						 colormap->green_max +
						 colormap->blue_max));

	    if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
			     first_index + i))
		return 0;
	}

    /* construct a red ramp map */
    else if (colormap->green_max == 0 && colormap->blue_max == 0)
    	for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
	{
	    color.pixel = n;
	    color.red = (unsigned short) ((i * 65535) / colormap->red_max);
	    color.green = color.blue = 0;

	    if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
			     first_index + i))
		return 0;
	}

    /* construct a green ramp map */
    else if (colormap->red_max == 0 && colormap->blue_max == 0)
    	for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
	{
	    color.pixel = n;
	    color.green = (unsigned short) ((i * 65535) / colormap->green_max);
	    color.red = color.blue = 0;

	    if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
			     first_index + i))
		return 0;
	}

    /* construct a blue ramp map */
    else if (colormap->red_max == 0 && colormap->green_max == 0)
    	for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
	{
	    color.pixel = n;
	    color.blue = (unsigned short) ((i * 65535) / colormap->blue_max);
	    color.red = color.green = 0;

	    if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
			     first_index + i))
		return 0;
	}

    /* construct a standard red green blue cube map */
    else
    {
#define calc(max,mult) (((n / colormap->mult) % \
			 (colormap->max + 1)) * 65535) / colormap->max

    	for (n=0, i=0; i < ncolors; i++, n += delta)
	{
	    color.pixel = n + colormap->base_pixel;
	    color.red = calc(red_max, red_mult);
	    color.green = calc(green_max, green_mult);
	    color.blue = calc(blue_max, blue_mult);
	    if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
			     first_index + i))
		return 0;
	}
#undef calc
    }
    /* We have a read-only map defined.  Now free unused cells,
     * first those occuring before the contiguous sequence begins,
     * then any following the contiguous sequence.
     */

    if (first_index)
	XFreeColors(dpy, colormap->colormap, pixels, first_index, 
		    (unsigned long) 0);
    if (remainder)
	XFreeColors(dpy, colormap->colormap,
		    &(pixels[first_index + ncolors]), remainder,
		    (unsigned long) 0);

    free((char *) pixels);
    return 1;
}


/****************************************************************************/
static int ROmap(dpy, cmap, pixels, m, n)
    Display		*dpy;		/* the X server connection */
    Colormap		cmap;		/* specifies colormap ID */
    unsigned long	pixels[];	/* returns pixel allocations */
    int			m;		/* specifies colormap size */
    int			n;		/* specifies number of colors */
{
    register int	p;

    /* first try to allocate the entire colormap */
    if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL, 
			 (unsigned) 0, pixels, (unsigned) m))
	return m;

    /* Allocate all available cells in the colormap, using a binary
     * algorithm to discover how many cells we can allocate in the colormap.
     */
    m--;
    while (n <= m) {
	p = n + ((m - n + 1) / 2);
	if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL,
			     (unsigned) 0, pixels, (unsigned) p)) {
	    if (p == m)
		return p;
	    else {
		XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
		n = p;
	    }
	}
	else
	    m = p - 1;
    }
    return 0;
}


/****************************************************************************/
static Status contiguous(pixels, npixels, ncolors, delta, first, rem)                    |  static Status contiguous(pixels, npixels, ncolors, delta, base_pixel,
                                                                                         >  				first, rem)
    unsigned long	pixels[];	/* specifies allocated pixels */
    int			npixels;	/* specifies count of alloc'd pixels */
    int			ncolors;	/* specifies needed sequence length */
    unsigned long	delta;		/* between pixels */
                                                                                         >      unsigned long	base_pixel;	/* required base or NOT_DETERMINED */
    int			*first;		/* returns first index of sequence */
    int			*rem;		/* returns first index after sequence,
					 * or 0, if none follow */
{
    register int i = 1;		/* walking index into the pixel array */
    register int count = 1;	/* length of sequence discovered so far */

    *first = 0;
    if (npixels == ncolors) {
	*rem = 0;
	return 1;
    }
    *rem = npixels - 1;
                                                                                         >  
                                                                                         >      if (base_pixel != NOT_DETERMINED) {
                                                                                         >  	while ((i < npixels) && 
                                                                                         >  	    (pixels[i-1] != base_pixel)) {
                                                                                         >  	    i++;
                                                                                         >  	    (*rem)--;
                                                                                         >  	}
                                                                                         >  	if (pixels[i-1] == base_pixel)
                                                                                         >  	    *first = i-1;
                                                                                         >  	else
                                                                                         >  	    return 0;
                                                                                         >      }
                                                                                         >  
    while (count < ncolors && ncolors - count <= *rem)
    {
	if (pixels[i-1] + delta == pixels[i])
	    count++;
	else {
                                                                                         >  	    if (base_pixel == NOT_DETERMINED) {
	    count = 1;
	    *first = i;
                                                                                         >  	    }
                                                                                         >  	    else
                                                                                         >  		return 0;
	}
	i++;
	(*rem)--;
    }
    if (count != ncolors)
	return 0;
    return 1;
}


/****************************************************************************/
static Status ROorRWcell(dpy, cmap, pixels, npixels, color, p)
    Display		*dpy;
    Colormap		cmap;
    unsigned long	pixels[];
    int			npixels;
    XColor		*color;
    unsigned long	p;
{
    unsigned long	pixel;
    XColor		request;

    /* Free the read/write allocation of one cell in the colormap.
     * Request a read only allocation of one cell in the colormap.
     * If the read only allocation cannot be granted, give up, because
     * there must be no free cells in the colormap.
     * If the read only allocation is granted, but gives us a cell which
     * is not the one that we just freed, it is probably the case that
     * we are trying allocate White or Black or some other color which
     * already has a read-only allocation in the map.  So we try to 
     * allocate the previously freed cell with a read/write allocation,
     * because we want contiguous cells for image processing algorithms.
     */

    pixel = color->pixel;
    request.red = color->red;
    request.green = color->green;
    request.blue = color->blue;

    XFreeColors(dpy, cmap, &pixel, 1, (unsigned long) 0);
    if (! XAllocColor(dpy, cmap, color) 
	|| (color->pixel != pixel &&
	    (!RWcell(dpy, cmap, color, &request, &pixel)))) 
    {
	free_cells(dpy, cmap, pixels, npixels, (int)p);
	return 0;
    }
    return 1;
}


/****************************************************************************/
static void free_cells(dpy, cmap, pixels, npixels,  p)
    Display		*dpy;
    Colormap		cmap;
    unsigned long	pixels[];	/* to be freed */
    int			npixels;        /* original number allocated */
    int			p;	  
{
    /* One of the npixels allocated has already been freed.
     * p is the index of the freed pixel.
     * First free the pixels preceeding p, and there are p of them;
     * then free the pixels following p, there are npixels - p - 1 of them.
     */
    XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
    XFreeColors(dpy, cmap, &(pixels[p+1]), npixels - p - 1, (unsigned long) 0);
    free((char *) pixels);
}


/****************************************************************************/
static Status RWcell(dpy, cmap, color, request, pixel)
    Display		*dpy;
    Colormap		cmap;
    XColor		*color;
    XColor		*request;
    unsigned long	*pixel;
{
    unsigned long	n = *pixel;

    XFreeColors(dpy, cmap, &(color->pixel), 1, (unsigned long)0);
    if (! XAllocColorCells(dpy, cmap, (Bool) 0, (unsigned long *) NULL,
			   (unsigned) 0, pixel, (unsigned) 1))
	return 0;
    if (*pixel != n)
    {
	XFreeColors(dpy, cmap, pixel, 1, (unsigned long) 0);
	return 0;
    }
    color->pixel = *pixel;
    color->flags = DoRed | DoGreen | DoBlue;
    color->red = request->red;
    color->green = request->green;
    color->blue = request->blue;
    XStoreColors(dpy, cmap, color, 1);
    return 1;
}


/****************************************************************************/
static int compare(e1, e2)
    unsigned long	*e1, *e2;
{
    if (*e1 < *e2)	return -1;
    if (*e1 > *e2)	return 1;
    return 0;
}


/****************************************************************************/
static Status readonly_map(dpy, vinfo, colormap)
    Display		*dpy;
    XVisualInfo		*vinfo;
    XStandardColormap	*colormap;
{
    int			i, last_pixel;
    XColor		color;

    last_pixel = (colormap->red_max + 1) * (colormap->green_max + 1) * 
	(colormap->blue_max + 1) + colormap->base_pixel - 1;

    for(i=colormap->base_pixel; i <= last_pixel; i++) {

	color.pixel = (unsigned long) i;
	color.red = (unsigned short)
	    (((i/colormap->red_mult) * 65535) / colormap->red_max);

	if (vinfo->class == StaticColor) {
	    color.green = (unsigned short)
		((((i/colormap->green_mult) % (colormap->green_max + 1)) *
		  65535) / colormap->green_max);
	    color.blue = (unsigned short)
		(((i%colormap->green_mult) * 65535) / colormap->blue_max);
	}
	else	/* vinfo->class == GrayScale, old style allocation XXX */
	    color.green = color.blue = color.red;

	XAllocColor(dpy, colormap->colormap, &color);
	if (color.pixel != (unsigned long) i)
	    return 0;
    }
    return 1;
}
============== LookupCmap
/* $XConsortium: LookupCmap.c,v 1.8 92/11/23 15:43:44 rws Exp $ 
 * 
 * Copyright 1989 by the Massachusetts Institute of Technology
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided 
 * that the above copyright notice appear in all copies and that both that 
 * copyright notice and this permission notice appear in supporting 
 * documentation, and that the name of M.I.T. not be used in advertising
 * or publicity pertaining to distribution of the software without specific, 
 * written prior permission. M.I.T. makes no representations about the 
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Author:  Donna Converse, MIT X Consortium
 */

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/Xmu/StdCmap.h>
                                                                                         >  #include <X11/Xmu/StdCmapExt.h>
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  #include <X11/PEX5/PEXlib.h>
                                                                                         >  #include <X11/Xmu/StdCmapPEX.h>
                                                                                         >  #endif /* ] PEX_SUPPORT */

extern char *malloc();
static Status lookup();
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  static Status checkPEXColorApprox();
                                                                                         >  static Status createTemporaryWindow();
                                                                                         >  static Status destroyTemporaryWindow();
                                                                                         >  #endif /* ] PEX_SUPPORT */

/*
 * To create a standard colormap if one does not currently exist, or
 * replace the currently existing standard colormap, use 
 * XmuLookupStandardColormap().                                                          |   * XmuLookupStandardColormapExt().
 *
 * Given a screen, a visual, and a property, XmuLookupStandardColormap()                 |   * Given a screen, a visual, and a property, XmuLookupStandardColormapExt()
 * will determine the best allocation for the property under the specified
 * visual, and determine the whether to create a new colormap or to use
 * the default colormap of the screen.  It will call XmuStandardColormap()               |   * the default colormap of the screen.  It will call XmuStandardColormapExt()
 * to create the standard colormap.
 *
 * If replace is true, any previous definition of the property will be 
 * replaced.  If retain is true, the property and the colormap will be
 * made permanent for the duration of the server session.  However,
 * pre-existing property definitions which are not replaced cannot be made
 * permanent by a call to XmuLookupStandardColormap(); a request to retain               |   * permanent by a call to XmuLookupStandardColormapExt(); a request to retain 
 * resources pertains to newly created resources.
 *
 * Returns 0 on failure, non-zero on success.  A request to create a 
 * standard colormap upon a visual which cannot support such a map is
 * considered a failure.  An example of this would be requesting any
 * standard colormap property on a monochrome visual, or, requesting an
 * RGB_BEST_MAP on a display whose colormap size is 16.                                  |   * RGB_BEST_MAP on a PseudoColor Visual whose colormap size is 16.
 */

Status XmuLookupStandardColormap(dpy, screen, visualid, depth, property,                 |  Status XmuLookupStandardColormapExt(dpy, screen, visualid, depth, property,
				 replace, retain)                                        |  				 replace, retain, params)
    Display		*dpy;		/* specifies X server connection */
    int			screen; 	/* specifies screen of display */
    VisualID		visualid;	/* specifies the visual type */
    unsigned int	depth;		/* specifies  the visual type */
    Atom		property;	/* a standard colormap property */
    Bool		replace;	/* specifies whether to replace */
    Bool		retain;		/* specifies whether to retain */
                                                                                         >      XmuExtendedParams 	*params;	/* controls and hints */
{
    Display		*odpy;		/* original display connection */
    XStandardColormap	*colormap;	
    XVisualInfo		vinfo_template, *vinfo;	/* visual */
    long		vinfo_mask;
    unsigned long	r_max, g_max, b_max;	/* allocation */
    int			count;	
    Colormap		cmap;			/* colormap ID */
    Status		status = 0;
                                                                                         >      int			create_default = False;
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >      int			PEX_required = False;
                                                                                         >  #endif /* ] PEX_SUPPORT */

                                                                                         >      /*
                                                                                         >  	Decode the controls and hints supported in this procedure.
                                                                                         >  	Set flag for the PEX requirement, but don't set it unless 
                                                                                         >  	property is RGB_DEFAULT_MAP or RGB_BEST_MAP.
                                                                                         >  	Set flag for the create_default hint, that allows a backup
                                                                                         >  	strategy of creating a new Colormap in case the default Colormap
                                                                                         >  	is over-allocated.
                                                                                         >      */
                                                                                         >      if (params) {
                                                                                         >  	int i;

                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  	for (i=0; i < params->num_controls; i++) {
                                                                                         >  	    if ((params->controls[i].name == XMU_CONTROL_PEX_SUPPORTED) &&
                                                                                         >  		((property == XA_RGB_DEFAULT_MAP) ||
                                                                                         >  		(property == XA_RGB_BEST_MAP)))
                                                                                         >  		PEX_required = params->controls[i].value;
                                                                                         >  	}
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
                                                                                         >  	for (i=0; i < params->num_hints; i++) {
                                                                                         >  	    if (params->hints[i].name == XMU_HINT_CREATE_DEFAULT)
                                                                                         >  		create_default = params->hints[i].value;
                                                                                         >  	}
                                                                                         >      }
                                                                                         >  
    /* Match the requested visual */

    vinfo_template.visualid = visualid;	
    vinfo_template.screen = screen;
    vinfo_template.depth = depth;
    vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
    if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &count)) ==
	NULL)
	return 0;

    /* Monochrome visuals have no standard maps */

    if (vinfo->colormap_size <= 2) {
	XFree((char *) vinfo);
	return 0;	
    }

                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >      /*
                                                                                         >  	If PEX is required, check support for the Visual.
                                                                                         >      */
                                                                                         >      if (PEX_required) {
                                                                                         >  
                                                                                         >  	PEXExtensionInfo	*ext_info;
                                                                                         >  	PEXRenderingTarget	*targets;
                                                                                         >  	unsigned long		target_count;
                                                                                         >  
                                                                                         >  	targets = NULL;
                                                                                         >  	target_count = 0;
                                                                                         >  
                                                                                         >  	if (NULL == (ext_info = PEXGetExtensionInfo (dpy)))
                                                                                         >  	    return 0;
                                                                                         >  
                                                                                         >  	if ((ext_info->major_version == 5) &&
                                                                                         >  	    (ext_info->minor_version >= 1)) {
                                                                                         >  
                                                                                         >  	    if ((! PEXMatchRenderingTargets (dpy, 
                                                                                         >  					RootWindow(dpy, screen),
                                                                                         >  					depth, PEXWindowDrawable, vinfo->visual,
                                                                                         >  					1, &target_count, &targets)) ||
                                                                                         >  		(target_count == 0)) {
                                                                                         >  		XFree((char *) vinfo);
                                                                                         >  		return 0;
                                                                                         >  	    }
                                                                                         >  
                                                                                         >  	    XFree (targets);
                                                                                         >  	}
                                                                                         >      }
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
    /* If the requested property already exists on this screen, and, 
     * if the replace flag has not been set to true, return success.
     * lookup() will remove a pre-existing map if replace is true.
     */

    if (lookup(dpy, screen, visualid, property, (XStandardColormap *) NULL,
	       replace) && !replace) {
                                                                                         >  	int status;
                                                                                         >  	status = 1;
                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  	/*
                                                                                         >  	    Check to see whether the existing property that was found
                                                                                         >  	    contains a color ramp supported by PEX.
                                                                                         >  	*/
                                                                                         >  	if (PEX_required) {
                                                                                         >  	    int count;
                                                                                         >  	    XStandardColormap *stdcmaps;
                                                                                         >  
                                                                                         >  	    count = 0;
                                                                                         >  	    XGetRGBColormaps (dpy, RootWindow(dpy, screen), 
                                                                                         >  				&stdcmaps, &count, property);
                                                                                         >  
                                                                                         >  	    if (count)
                                                                                         >  		status = checkPEXColorApprox (dpy, vinfo, 
                                                                                         >  					    stdcmaps, count, property);
                                                                                         >  
                                                                                         >  	    XFree ((char *) stdcmaps);
                                                                                         >  	}
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
	XFree((char *) vinfo);
	return 1;                                                                        |  	return status;
    }

    /* Determine the best allocation for this property under the requested
     * visualid and depth, and determine whether or not to use the default
     * colormap of the screen.
     */

    if (!XmuGetColormapAllocation(vinfo, property, &r_max, &g_max, &b_max)) {            |      if (!XmuGetColormapAllocationExt(vinfo, property, params,
                                                                                         >  					&r_max, &g_max, &b_max)) {
	XFree((char *) vinfo);
	return 0;
    }

    cmap = (property == XA_RGB_DEFAULT_MAP &&
	    visualid == XVisualIDFromVisual(DefaultVisual(dpy, screen)))
	? DefaultColormap(dpy, screen) : None;

    /* If retaining resources, open a new connection to the same server */

    if (retain) {
                                                                                         >  	XSync (dpy, 0);
	odpy = dpy;
	if ((dpy = XOpenDisplay(XDisplayString(odpy))) == NULL) {
	    XFree((char *) vinfo);
	    return 0;
	}
                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  	/*
                                                                                         >  	    If PEX required, need to open PEXlib on the new connection.
                                                                                         >  	*/
                                                                                         >  	if (PEX_required) {
                                                                                         >  	    PEXExtensionInfo *ext_info;
                                                                                         >  
                                                                                         >  	    if (PEXInitialize (dpy, &ext_info, 0, NULL)) {
                                                                                         >  		XFree((char *) vinfo);
                                                                                         >  		return 0;
    }
                                                                                         >  	}
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >      }

    /* Create the standard colormap */

    colormap = XmuStandardColormap(dpy, screen, visualid, depth, property,               |      colormap = XmuStandardColormapExt(dpy, screen, visualid, depth, property,
				   cmap, r_max, g_max, b_max);                           |  				   cmap, r_max, g_max, b_max, params);

                                                                                         >      if (create_default) {
                                                                                         >  	if ((colormap == NULL) &&
                                                                                         >  	    (property == XA_RGB_DEFAULT_MAP) &&
                                                                                         >  	    (visualid == XVisualIDFromVisual(DefaultVisual(dpy, screen)))) {
                                                                                         >  
                                                                                         >  	    cmap = None;
                                                                                         >  	    colormap = XmuStandardColormapExt(dpy, screen, visualid, depth, 
                                                                                         >  				property, cmap, r_max, g_max, b_max, params);
                                                                                         >  	}
                                                                                         >      }
                                                                                         >  
    /* Set the standard colormap property */

    if (colormap) {
	XGrabServer(dpy);

	if (lookup(dpy, screen, visualid, property, colormap, replace) &&
	    !replace) {
	    /* Someone has defined the property since we last looked.
	     * Since we will not replace it, release our own resources.
	     * If this is the default map, our allocations will be freed 
	     * when this connection closes.
	     */
	    if (colormap->killid == ReleaseByFreeingColormap)
		XFreeColormap(dpy, colormap->colormap);
	}
	else if (retain) {
		XSetCloseDownMode(dpy, RetainPermanent);
	}
	XUngrabServer(dpy);
	XFree((char *) colormap);
	status = 1;
    }

    if (retain)
	XCloseDisplay(dpy);
    XFree((char *) vinfo);
    return status;
}

/***************************************************************************/

/* Lookup a standard colormap property.  If the property is RGB_DEFAULT_MAP,
 * the visualid is used to determine whether the indicated standard colormap
 * exists.  If the map exists and replace is true, delete the resources used
 * by the map and remove the property.  Return true if the map exists,
 * or did exist and was deleted; return false if the map was not found.
 *
 * Note that this is not the way that a Status return is normally used.
 *
 * If new is not NULL, new points to an XStandardColormap structure which
 * describes a standard colormap of the specified property.  It will be made
 * a standard colormap of the screen if none already exists, or if replace 
 * is true.
 */

static Status lookup(dpy, screen, visualid, property, new, replace)
    Display		*dpy;		/* specifies display connection */
    int			screen;		/* specifies screen number */
    VisualID		visualid;	/* specifies visualid for std map */
    Atom		property;	/* specifies colormap property name */
    XStandardColormap	*new;		/* specifies a standard colormap */
    Bool		replace;	/* specifies whether to replace */
{
    register int	i;
    int			count;
    XStandardColormap	*stdcmaps, *s;
    Window		win = RootWindow(dpy, screen);

    /* The property does not already exist */

    if (! XGetRGBColormaps(dpy, win, &stdcmaps, &count, property)) {
	if (new)
	    XSetRGBColormaps(dpy, win, new, 1, property);
	return 0;
    }

    /* The property exists and is not describing the RGB_DEFAULT_MAP */

    if (property != XA_RGB_DEFAULT_MAP) {
	if (replace) {
	    XmuDeleteStandardColormap(dpy, screen, property);
	    if (new)
		XSetRGBColormaps(dpy, win, new, 1, property);
	}
	XFree((char *)stdcmaps);
	return 1;
    }

    /* The property exists and is RGB_DEFAULT_MAP */

    for (i=0, s=stdcmaps; (i < count) && (s->visualid != visualid); i++, s++)
	;

    /* No RGB_DEFAULT_MAP property matches the given visualid */

    if (i == count) {
	if (new) {
	    XStandardColormap	*m, *maps;

	    s = (XStandardColormap *) malloc((unsigned) ((count+1) * sizeof
					      (XStandardColormap)));

	    for (i = 0, m = s, maps = stdcmaps; i < count; i++, m++, maps++) {
		m->colormap   = maps->colormap;
		m->red_max    = maps->red_max;
		m->red_mult   = maps->red_mult;
		m->green_max  = maps->green_max;
		m->green_mult = maps->green_mult;
		m->blue_max   = maps->blue_max;
		m->blue_mult  = maps->blue_mult;
                                                                                         >  		m->base_pixel = maps->base_pixel;
		m->visualid   = maps->visualid;
		m->killid     = maps->killid;
	    }
	    m->colormap   = new->colormap;
	    m->red_max    = new->red_max;
	    m->red_mult   = new->red_mult;
	    m->green_max  = new->green_max;
	    m->green_mult = new->green_mult;
	    m->blue_max   = new->blue_max;
	    m->blue_mult  = new->blue_mult;
                                                                                         >  	    m->base_pixel = new->base_pixel;
	    m->visualid   = new->visualid;
	    m->killid     = new->killid;

	    XSetRGBColormaps(dpy, win, s, ++count, property);
	    free((char *) s);
	}
	XFree((char *) stdcmaps);
	return 0;
    }

    /* Found an RGB_DEFAULT_MAP property with a matching visualid */

    if (replace) {
	/* Free old resources first - we may need them, particularly in 
	 * the default colormap of the screen.  However, because of this,
	 * it is possible that we will destroy the old resource and fail 
	 * to create a new one if XmuStandardColormap() fails.
	 */

	if (count == 1) {
	    XmuDeleteStandardColormap(dpy, screen, property);
	    if (new)
		XSetRGBColormaps(dpy, win, new, 1, property);
	}
	else {
	    XStandardColormap	*map;

	    /* s still points to the matching standard colormap */

	    if (s->killid == ReleaseByFreeingColormap) {
		if ((s->colormap != None) &&
		    (s->colormap != DefaultColormap(dpy, screen)))
		    XFreeColormap(dpy, s->colormap);
	    }
	    else if (s->killid != None)
		XKillClient(dpy, s->killid);

	    map = (new) ? new : stdcmaps + --count;

	    s->colormap   = map->colormap;
	    s->red_max    = map->red_max;
	    s->red_mult   = map->red_mult;
	    s->green_max  = map->green_max;
	    s->green_mult = map->green_mult;
	    s->blue_max   = map->blue_max;
	    s->blue_mult  = map->blue_mult;
                                                                                         >  	    s->base_pixel = map->base_pixel;
	    s->visualid   = map->visualid;
	    s->killid     = map->killid;

	    XSetRGBColormaps(dpy, win, stdcmaps, count, property);
	}
    }
    XFree((char *) stdcmaps);
    return 1;
}
                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  
                                                                                         >  static Status checkPEXColorApprox (dpy, vinfo, stdcmap_array, count, property)
                                                                                         >      Display		*dpy;
                                                                                         >      XVisualInfo		*vinfo;
                                                                                         >      XStandardColormap	*stdcmap_array;
                                                                                         >      int			count;
                                                                                         >      Atom		property;
                                                                                         >  {
                                                                                         >      int 		i;
                                                                                         >      XStandardColormap 	*stdcmap;
                                                                                         >      int			return_value;
                                                                                         >      Window		window;
                                                                                         >      int			inquiry_supported;
                                                                                         >      PEXExtensionInfo	*ext_info;
                                                                                         >  
                                                                                         >  
                                                                                         >      /*
                                                                                         >  	Get the property entry to use.
                                                                                         >      */
                                                                                         >      if (property != XA_RGB_DEFAULT_MAP)
                                                                                         >  	stdcmap = stdcmap_array;
                                                                                         >      else {
                                                                                         >  	for (i=0, stdcmap=stdcmap_array; 
                                                                                         >  	    (i < count) && (stdcmap->visualid != vinfo->visualid); 
                                                                                         >  	    i++, stdcmap++) ;
                                                                                         >  
                                                                                         >  	if (i == count)
                                                                                         >  	    /* unexpected */
                                                                                         >  	    return 0;
                                                                                         >      }
                                                                                         >  
                                                                                         >  
                                                                                         >      if (NULL == (ext_info = PEXGetExtensionInfo (dpy)))
                                                                                         >  	return 0;
                                                                                         >  
                                                                                         >      /*
                                                                                         >  	Create a temporary unmapped window in the Visual.
                                                                                         >      */
                                                                                         >      if (!createTemporaryWindow (dpy, vinfo, &window))
                                                                                         >  	return 0;
                                                                                         >  
                                                                                         >      inquiry_supported = False;
                                                                                         >      if ((ext_info->major_version == 5) &&
                                                                                         >  	(ext_info->minor_version >= 1)) 
                                                                                         >      {
                                                                                         >  	int		enum_types[1];
                                                                                         >  	unsigned long 	*enum_count;
                                                                                         >  	PEXEnumTypeDesc	*enum_data;
                                                                                         >  	int		enum_index;
                                                                                         >  
                                                                                         >  	/*
                                                                                         >  	    Verify that the QueryColorApprox escape is supported
                                                                                         >  	    using PEXGetEnumTypeInfo.  If not, we just can't verify
                                                                                         >  	    support, so we'll assume the color ramp is supported.
                                                                                         >  	*/
                                                                                         >  
                                                                                         >  	enum_types[0] = PEXETEscape;
                                                                                         >  	if (!PEXGetEnumTypeInfo (dpy, window, 1, enum_types, 
                                                                                         >  				PEXETIndex, &enum_count, &enum_data)) {
                                                                                         >  
                                                                                         >  	    destroyTemporaryWindow (dpy, vinfo, window);
                                                                                         >  	    return 0;
                                                                                         >  	}
                                                                                         >  	else {
                                                                                         >  
                                                                                         >  	    for (enum_index = 0; enum_index < *enum_count; enum_index++) {
                                                                                         >  		if ((short) enum_data[enum_index].index == 
                                                                                         >  		    (short) PEXETEscapeQueryColorApprox) {
                                                                                         >  		    inquiry_supported = True;
                                                                                         >  		    break;
                                                                                         >  		}
                                                                                         >  	    }
                                                                                         >  	    PEXFreeEnumInfo (1, enum_count, enum_data);
                                                                                         >  	}
                                                                                         >      }
                                                                                         >  
                                                                                         >      if (inquiry_supported) {
                                                                                         >  
                                                                                         >  	PEXEscapeQueryColorApproxData		query;
                                                                                         >  	PEXEscapeQueryColorApproxReplyData	*reply;
                                                                                         >  	unsigned long 				reply_length;
                                                                                         >  
                                                                                         >  	/*
                                                                                         >  	    Load up the query structure from the property.
                                                                                         >  	    Currently assuming only PEXColorSpace is of interest.
                                                                                         >  	    Note dither flag is a hint, so it shouldn't affect result.
                                                                                         >  	*/
                                                                                         >  
                                                                                         >  	query.capx.type = PEXColorSpace;
                                                                                         >  	query.capx.model = PEXColorApproxRGB;
                                                                                         >  	query.capx.dither = PEXOn;
                                                                                         >  	query.capx.base_pixel = stdcmap->base_pixel;
                                                                                         >  	query.capx.max1 = stdcmap->red_max;
                                                                                         >  	query.capx.max2 = stdcmap->green_max;
                                                                                         >  	query.capx.max3 = stdcmap->blue_max;
                                                                                         >  	query.capx.weight1 = 0.0;
                                                                                         >  	query.capx.weight2 = 0.0;
                                                                                         >  	query.capx.weight3 = 0.0;
                                                                                         >  	query.capx.mult1 = stdcmap->red_mult;
                                                                                         >  	query.capx.mult2 = stdcmap->green_mult;
                                                                                         >  	query.capx.mult3 = stdcmap->blue_mult;
                                                                                         >  
                                                                                         >  	query.drawable = window;
                                                                                         >  
                                                                                         >  	reply = (PEXEscapeQueryColorApproxReplyData *)
                                                                                         >  		PEXEscapeWithReply (dpy, PEXEscapeQueryColorApprox, 
                                                                                         >  				    sizeof(query), ((char *) &query), 
                                                                                         >  				    &reply_length);
                                                                                         >  
                                                                                         >  	if (reply != NULL) {
                                                                                         >  
                                                                                         >  	    return_value = (reply->capx_is_supported);
                                                                                         >  	    XFree ((char *) reply);
                                                                                         >  	}
                                                                                         >  	else {
                                                                                         >  	    destroyTemporaryWindow (dpy, vinfo, window);
                                                                                         >  	    return 0;
                                                                                         >  	}
                                                                                         >      }
                                                                                         >      else {
                                                                                         >  	/* Can't determine support or non-support. */
                                                                                         >  	return_value = 1;
                                                                                         >      }
                                                                                         >  
                                                                                         >  
                                                                                         >      /*
                                                                                         >  	Destroy the temporary window.
                                                                                         >      */
                                                                                         >      destroyTemporaryWindow (dpy, vinfo, window);
                                                                                         >  
                                                                                         >      return return_value;
                                                                                         >  }
                                                                                         >  
                                                                                         >  
                                                                                         >  static Status createTemporaryWindow (display, vinfo, window_return)
                                                                                         >      Display	*display;
                                                                                         >      XVisualInfo	*vinfo;
                                                                                         >      Window	*window_return;
                                                                                         >  {
                                                                                         >      unsigned long 		window_mask;
                                                                                         >      XSetWindowAttributes	window_attrs;
                                                                                         >      Colormap			cmap_id;
                                                                                         >  
                                                                                         >  
                                                                                         >      /*
                                                                                         >  	Create a window using override-redirect.  Do not map it.
                                                                                         >  	If the Visual is the default, use the root window.
                                                                                         >  	Otherwise, create a colormap to use.
                                                                                         >      */
                                                                                         >  
                                                                                         >      if (vinfo->visual == DefaultVisual (display, vinfo->screen)) {
                                                                                         >  
                                                                                         >  	*window_return = RootWindow (display, vinfo->screen);
                                                                                         >  	return 1;
                                                                                         >      }
                                                                                         >      else {
                                                                                         >  	cmap_id = XCreateColormap (display, 
                                                                                         >  				    RootWindow(display, vinfo->screen),
                                                                                         >  				    vinfo->visual, AllocNone );
                                                                                         >  	if (cmap_id == None)
                                                                                         >  	    return 0;
                                                                                         >  
                                                                                         >  	window_attrs.colormap = cmap_id;
                                                                                         >  	window_mask = CWColormap;
                                                                                         >  
                                                                                         >  	window_attrs.override_redirect = True;
                                                                                         >  	window_mask |= CWOverrideRedirect;
                                                                                         >  
                                                                                         >  	window_attrs.background_pixel = 0;
                                                                                         >  	window_mask |= CWBackPixel;
                                                                                         >  
                                                                                         >  	window_attrs.border_pixel = 0;
                                                                                         >  	window_mask |= CWBorderPixel;
                                                                                         >  
                                                                                         >  	*window_return = XCreateWindow (display, 
                                                                                         >  				RootWindow (display, vinfo->screen),
                                                                                         >  				10, 10, 1, 1, 0,
                                                                                         >  				vinfo->depth, 
                                                                                         >  				InputOutput,
                                                                                         >  				vinfo->visual,
                                                                                         >  				window_mask,
                                                                                         >  				&(window_attrs));
                                                                                         >  
                                                                                         >  	if (*window_return == None)
                                                                                         >  	    return 0;
                                                                                         >  	else
                                                                                         >  	    return 1;
                                                                                         >      }
                                                                                         >  } /* createTemporaryWindow */
                                                                                         >  
                                                                                         >  
                                                                                         >  static Status destroyTemporaryWindow (display, vinfo, window)
                                                                                         >      Display	*display;
                                                                                         >      XVisualInfo	*vinfo;
                                                                                         >      Window	window;
                                                                                         >  {
                                                                                         >      XWindowAttributes	window_attrs;
                                                                                         >  
                                                                                         >      /*
                                                                                         >  	If this window is not in the default Visual, 
                                                                                         >  	the Colormap and Window need to be freed.
                                                                                         >      */
                                                                                         >  
                                                                                         >      if (vinfo->visual != DefaultVisual (display, vinfo->screen)) {
                                                                                         >  
                                                                                         >  	if (XGetWindowAttributes (display, window, &window_attrs))
                                                                                         >  	    XFreeColormap (display, window_attrs.colormap);
                                                                                         >  
                                                                                         >  	XDestroyWindow (display, window);
                                                                                         >      }
                                                                                         >  
                                                                                         >      return 1;
                                                                                         >  
                                                                                         >  } /* destroyTemporaryWindow */
                                                                                         >  
                                                                                         >  #endif /* ] PEX_SUPPORT */
============== StdCmap
/* $XConsortium: StdCmap.c,v 1.13 92/11/24 14:16:21 rws Exp $ 
 * 
 * Copyright 1989 by the Massachusetts Institute of Technology
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided 
 * that the above copyright notice appear in all copies and that both that 
 * copyright notice and this permission notice appear in supporting 
 * documentation, and that the name of M.I.T. not be used in advertising
 * or publicity pertaining to distribution of the software without specific, 
 * written prior permission. M.I.T. makes no representations about the 
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Author:  Donna Converse, MIT X Consortium
 */

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/Xmu/StdCmap.h>
                                                                                         >  #include <X11/Xmu/StdCmapExt.h>
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  #include <X11/PEX5/PEXlib.h>
                                                                                         >  #include <X11/Xmu/StdCmapPEX.h>
                                                                                         >  #endif /* ] PEX_SUPPORT */

#define lowbit(x) ((x) & (~(x) + 1))

                                                                                         >  extern char *malloc();
static Status valid_args();		/* argument restrictions */
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  static Status verifyPEXSupport();
                                                                                         >  static Status createTemporaryWindow();
                                                                                         >  static Status destroyTemporaryWindow();
                                                                                         >  #endif /* ] PEX_SUPPORT */

/*
 * To create any one standard colormap, use XmuStandardColormap().                       |   * To create any one standard colormap, use XmuStandardColormapExt().
 *
 * Create a standard colormap for the given screen, visualid, and visual
 * depth, with the given red, green, and blue maximum values, with the
 * given standard property name.  Return a pointer to an XStandardColormap
 * structure which describes the newly created colormap, upon success.
 * Upon failure, return NULL.
 * 
 * XmuStandardColormap() calls XmuCreateColormap() to create the map.                    |   * XmuStandardColormapExt() calls XmuCreateColormapExt() to create the map.
 *
 * Resources created by this function are not made permanent; that is the
 * caller's responsibility.
 */

XStandardColormap *XmuStandardColormap(dpy, screen, visualid, depth, property,           |  XStandardColormap *XmuStandardColormapExt(dpy, screen, visualid, depth, 
				       cmap, red_max, green_max, blue_max)               |  					property, cmap, 
                                                                                         >  					red_max, green_max, blue_max,
                                                                                         >  					params)
    Display		*dpy;		/* specifies X server connection */
    int			screen; 	/* specifies display screen */
    VisualID		visualid;	/* identifies the visual type */
    unsigned int	depth;		/* identifies the visual type */
    Atom		property;	/* a standard colormap property */
    Colormap		cmap;		/* specifies colormap ID or None */
    unsigned long	red_max, green_max, blue_max;	/* allocations */
                                                                                         >      XmuExtendedParams 	*params;	/* controls and hints */
{
    XStandardColormap	*stdcmap;
    Status		status;
    XVisualInfo		vinfo_template, *vinfo;
    long		vinfo_mask;
    int			n;
                                                                                         >      int			ramp_hint = RAMP_RGB;
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >      int			PEX_required = False;
                                                                                         >      XmuExtendedParams 	*local_params;
                                                                                         >      int			allocated_params = False;
                                                                                         >  #endif /* ] PEX_SUPPORT */

                                                                                         >      /*
                                                                                         >  	Decode the controls and hints supported in this procedure.
                                                                                         >  	Set flag for the PEX requirement, but don't set it unless 
                                                                                         >  	property is RGB_DEFAULT_MAP or RGB_BEST_MAP.
                                                                                         >      */
                                                                                         >      if (params) {
                                                                                         >  	int i;
                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  	for (i=0; i < params->num_controls; i++) {
                                                                                         >  	    if ((params->controls[i].name == XMU_CONTROL_PEX_SUPPORTED) &&
                                                                                         >  		((property == XA_RGB_DEFAULT_MAP) ||
                                                                                         >  		(property == XA_RGB_BEST_MAP)))
                                                                                         >  		PEX_required = params->controls[i].value;
                                                                                         >  	}
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
                                                                                         >  	for (i=0; i < params->num_hints; i++) {
                                                                                         >  	    if (params->hints[i].name == XMU_HINT_PSEUDO_RAMP)
                                                                                         >  		ramp_hint = params->hints[i].value;
                                                                                         >  	}
                                                                                         >      }
                                                                                         >  
                                                                                         >  
    /* Match the required visual information to an actual visual */
    vinfo_template.visualid = visualid;	
    vinfo_template.screen = screen;
    vinfo_template.depth = depth;
    vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
    if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
	return 0;

    /* Check the validity of the combination of visual characteristics,
     * allocation, and colormap property.  Create an XStandardColormap
     * structure.
     */

    if (! valid_args(vinfo, red_max, green_max, blue_max, property)
	|| ((stdcmap = XAllocStandardColormap()) == NULL)) {
	XFree((char *) vinfo);
	return 0;
    }

                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >      /*
                                                                                         >  	If PEX is required, check support for the Visual.
                                                                                         >      */
                                                                                         >      if (PEX_required) {
                                                                                         >  
                                                                                         >  	PEXExtensionInfo	*ext_info;
                                                                                         >  	PEXRenderingTarget	*targets;
                                                                                         >  	unsigned long		target_count;
                                                                                         >  
                                                                                         >  	targets = NULL;
                                                                                         >  	target_count = 0;
                                                                                         >  
                                                                                         >  	if (NULL == (ext_info = PEXGetExtensionInfo (dpy)))
                                                                                         >  	    return 0;
                                                                                         >  
                                                                                         >  	if ((ext_info->major_version == 5) &&
                                                                                         >  	    (ext_info->minor_version >= 1)) {
                                                                                         >  
                                                                                         >  	    if ((! PEXMatchRenderingTargets (dpy, 
                                                                                         >  					RootWindow(dpy, screen),
                                                                                         >  					depth, PEXWindowDrawable, vinfo->visual,
                                                                                         >  					1, &target_count, &targets)) ||
                                                                                         >  		(target_count == 0)) {
                                                                                         >  		XFree((char *) vinfo);
                                                                                         >  		return 0;
                                                                                         >  	    }
                                                                                         >  
                                                                                         >  	    XFree (targets);
                                                                                         >  	}
                                                                                         >      }
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
                                                                                         >  
    /* Fill in the XStandardColormap structure */

    if (cmap == DefaultColormap(dpy, screen)) {
	/* Allocating out of the default map, cannot use XFreeColormap() */
	Window win = XCreateWindow(dpy, RootWindow(dpy, screen), 1, 1, 1, 1,
				   0, 0, InputOnly, vinfo->visual,
				   (unsigned long) 0,
				   (XSetWindowAttributes *)NULL);
	stdcmap->killid  = (XID) XCreatePixmap(dpy, win, 1, 1, depth);
	XDestroyWindow(dpy, win);
	stdcmap->colormap = cmap;
    } else {
	stdcmap->killid = ReleaseByFreeingColormap;
	stdcmap->colormap = XCreateColormap(dpy, RootWindow(dpy, screen),
					    vinfo->visual, AllocNone);
    }
    stdcmap->red_max = red_max;
    stdcmap->green_max = green_max;
    stdcmap->blue_max = blue_max;
    if (property == XA_RGB_GRAY_MAP) 
	stdcmap->red_mult = stdcmap->green_mult = stdcmap->blue_mult = 1;
    else if (vinfo->class == TrueColor || vinfo->class == DirectColor) {
	stdcmap->red_mult = lowbit(vinfo->red_mask);
	stdcmap->green_mult = lowbit(vinfo->green_mask);
	stdcmap->blue_mult = lowbit(vinfo->blue_mask);
    } else {
                                                                                         >  	int red_pri, green_pri, blue_pri;
                                                                                         >  
                                                                                         >  	/* There's probably a more clever way to do this.  */
                                                                                         >  	red_pri = (ramp_hint >> RAMP_SHIFT_RED) & 0xF;
                                                                                         >  	green_pri = (ramp_hint >> RAMP_SHIFT_GREEN) & 0xF;
                                                                                         >  	blue_pri = (ramp_hint >> RAMP_SHIFT_BLUE) & 0xF;
                                                                                         >  	if (red_pri == 2) {
	stdcmap->red_mult = (red_max > 0)
	    ? (green_max + 1) * (blue_max + 1) : 0;
                                                                                         >  	    if (green_pri == 1) {
	stdcmap->green_mult = (green_max > 0) ? blue_max + 1 : 0;
	stdcmap->blue_mult = (blue_max > 0) ? 1 : 0;
    }
                                                                                         >  	    else {
                                                                                         >  		stdcmap->blue_mult = (blue_max > 0) ? green_max + 1 : 0;
                                                                                         >  		stdcmap->green_mult = (green_max > 0) ? 1 : 0;
                                                                                         >  	    }
                                                                                         >  	}
                                                                                         >  	else if (red_pri == 1) {
                                                                                         >  	    if (green_pri == 2) {
                                                                                         >  		stdcmap->green_mult = (green_max > 0)
                                                                                         >  		    ? (red_max + 1) * (blue_max + 1) : 0;
                                                                                         >  		stdcmap->red_mult = (red_max > 0) ? blue_max + 1 : 0;
                                                                                         >  		stdcmap->blue_mult = (blue_max > 0) ? 1 : 0;
                                                                                         >  	    }
                                                                                         >  	    else {
                                                                                         >  		stdcmap->blue_mult = (blue_max > 0)
                                                                                         >  		    ? (red_max + 1) * (green_max + 1) : 0;
                                                                                         >  		stdcmap->red_mult = (red_max > 0) ? green_max + 1 : 0;
                                                                                         >  		stdcmap->green_mult = (green_max > 0) ? 1 : 0;
                                                                                         >  	    }
                                                                                         >  	}
                                                                                         >  	else {
                                                                                         >  	    stdcmap->red_mult = (red_max > 0) ? 1 : 0;
                                                                                         >  	    if (green_pri == 2) {
                                                                                         >  		stdcmap->green_mult = (green_max > 0)
                                                                                         >  		    ? (blue_max + 1) * (red_max + 1) : 0;
                                                                                         >  		stdcmap->blue_mult = (blue_max > 0) ? red_max + 1 : 0;
                                                                                         >  	    }
                                                                                         >  	    else {
                                                                                         >  		stdcmap->blue_mult = (blue_max > 0)
                                                                                         >  		    ? (green_max + 1) * (red_max + 1) : 0;
                                                                                         >  		stdcmap->green_mult = (green_max > 0) ? red_max + 1 : 0;
                                                                                         >  	    }
                                                                                         >  	}
                                                                                         >      }
    stdcmap->base_pixel = 0;			/* base pixel may change */
    stdcmap->visualid = vinfo->visualid;

                                                                                         >      status = 1;
                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >      /*
                                                                                         >  	Check the "proposed" ramp for PEX support.
                                                                                         >  	If there's a problem, the verifyPEXSupport() procedure includes
                                                                                         >  	vendor-specific code to attempt to fix it.
                                                                                         >      */
                                                                                         >      if (PEX_required) {
                                                                                         >  
                                                                                         >  
                                                                                         >  	status = verifyPEXSupport (dpy, vinfo, stdcmap, params, 
                                                                                         >  					&local_params, &allocated_params);
                                                                                         >      }
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
                                                                                         >  
    /* Make the colormap */

    status = XmuCreateColormap(dpy, stdcmap);                                            |      if (status) {

                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  	if (PEX_required) {
                                                                                         >  	    status = XmuCreateColormapExt(dpy, stdcmap, local_params);
                                                                                         >  	    if (allocated_params) 
                                                                                         >  		free((char *) local_params);
                                                                                         >  	}
                                                                                         >  	else
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
                                                                                         >  	    status = XmuCreateColormapExt(dpy, stdcmap, params);
                                                                                         >      }
                                                                                         >  
    /* Clean up */

    XFree((char *) vinfo);
    if (!status) {

	/* Free the colormap or the pixmap, if we created one */
	if (stdcmap->killid == ReleaseByFreeingColormap)
	    XFreeColormap(dpy, stdcmap->colormap);
	else if (stdcmap->killid != None)
	    XFreePixmap(dpy, stdcmap->killid);

	XFree((char *) stdcmap);
	return (XStandardColormap *) NULL;
    }
    return stdcmap;
}

/****************************************************************************/
static Status valid_args(vinfo, red_max, green_max, blue_max, property)
    XVisualInfo		*vinfo;		/* specifies visual */
    unsigned long	red_max, green_max, blue_max;	/* specifies alloc */
    Atom		property;	/* specifies property name */
{
    unsigned long	ncolors;	/* number of colors requested */

    /* Determine that the number of colors requested is <= map size */

    if ((vinfo->class == DirectColor) || (vinfo->class == TrueColor)) {
	unsigned long mask;

	mask = vinfo->red_mask;
	while (!(mask & 1))
	    mask >>= 1;
	if (red_max > mask)
	    return 0;
	mask = vinfo->green_mask;
	while (!(mask & 1))
	    mask >>= 1;
	if (green_max > mask)
	    return 0;
	mask = vinfo->blue_mask;
	while (!(mask & 1))
	    mask >>= 1;
	if (blue_max > mask)
	    return 0;
    } else if (property == XA_RGB_GRAY_MAP) {
	ncolors = red_max + green_max + blue_max + 1;
	if (ncolors > vinfo->colormap_size)
	    return 0;
    } else {
	ncolors = (red_max + 1) * (green_max + 1) * (blue_max + 1);
	if (ncolors > vinfo->colormap_size)
	    return 0;
    }

    /* Determine that the allocation and visual make sense for the property */

    switch (property)
    {
      case XA_RGB_DEFAULT_MAP:
	if (red_max == 0 || green_max == 0 || blue_max == 0)
	    return 0;
	break;
      case XA_RGB_RED_MAP:
	if (red_max == 0)
	    return 0;
	break;
      case XA_RGB_GREEN_MAP:
	if (green_max == 0)
	    return 0;
	break;
      case XA_RGB_BLUE_MAP:	
	if (blue_max == 0)
	    return 0;
	break;
      case XA_RGB_BEST_MAP:
	if (red_max == 0 || green_max == 0 || blue_max == 0)
	    return 0;
	break;
      case XA_RGB_GRAY_MAP:
	if (red_max == 0 || blue_max == 0 || green_max == 0)
	    return 0;
	break;
      default:
	return 0;
    }
    return 1;
}
                                                                                         >  
                                                                                         >  
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  
                                                                                         >  static Status verifyPEXSupport (dpy, vinfo, stdcmap, params, new_params, alloc)
                                                                                         >      Display		*dpy;
                                                                                         >      XVisualInfo		*vinfo;
                                                                                         >      XStandardColormap	*stdcmap;
                                                                                         >      XmuExtendedParams	*params;
                                                                                         >      XmuExtendedParams	**new_params;
                                                                                         >      int			*alloc;
                                                                                         >  {
                                                                                         >      int 		i;
                                                                                         >      Status		status;
                                                                                         >      Window		window;
                                                                                         >      int			inquiry_supported;
                                                                                         >      int			capx_supported;
                                                                                         >      PEXExtensionInfo	*ext_info;
                                                                                         >      PEXEscapeQueryColorApproxReplyData	*reply;
                                                                                         >  
                                                                                         >      *alloc = False;
                                                                                         >      *new_params = NULL;
                                                                                         >  
                                                                                         >      if (NULL == (ext_info = PEXGetExtensionInfo (dpy)))
                                                                                         >  	return 0;
                                                                                         >  
                                                                                         >      /*
                                                                                         >  	Create a temporary unmapped window in the Visual.
                                                                                         >      */
                                                                                         >  
                                                                                         >      if (!createTemporaryWindow (dpy, vinfo, &window))
                                                                                         >  	return 0;
                                                                                         >  
                                                                                         >      capx_supported = False;
                                                                                         >      inquiry_supported = False;
                                                                                         >  
                                                                                         >      if ((ext_info->major_version == 5) &&
                                                                                         >  	(ext_info->minor_version >= 1)) 
                                                                                         >      {
                                                                                         >  	int		enum_types[1];
                                                                                         >  	unsigned long 	*enum_count;
                                                                                         >  	PEXEnumTypeDesc	*enum_data;
                                                                                         >  	int		enum_index;
                                                                                         >  
                                                                                         >  	/*
                                                                                         >  	    Verify that the QueryColorApprox escape is supported
                                                                                         >  	    using PEXGetEnumTypeInfo.  If not, we just can't verify
                                                                                         >  	    support, so we'll assume the color approximation entry is
                                                                                         >  	    supported.
                                                                                         >  	*/
                                                                                         >  
                                                                                         >  	enum_types[0] = PEXETEscape;
                                                                                         >  	if (!PEXGetEnumTypeInfo (dpy, window, 1, enum_types, 
                                                                                         >  				PEXETIndex, &enum_count, &enum_data)) {
                                                                                         >  
                                                                                         >  	    destroyTemporaryWindow (dpy, vinfo, window);
                                                                                         >  	    return 0;
                                                                                         >  	}
                                                                                         >  	else {
                                                                                         >  
                                                                                         >  	    for (enum_index = 0; enum_index < *enum_count; enum_index++) {
                                                                                         >  		if ((short) enum_data[enum_index].index == 
                                                                                         >  		    (short) PEXETEscapeQueryColorApprox) {
                                                                                         >  		    inquiry_supported = True;
                                                                                         >  		    break;
                                                                                         >  		}
                                                                                         >  	    }
                                                                                         >  	    PEXFreeEnumInfo (1, enum_count, enum_data);
                                                                                         >  	}
                                                                                         >      }
                                                                                         >  
                                                                                         >      if (inquiry_supported) {
                                                                                         >  
                                                                                         >  	PEXEscapeQueryColorApproxData		query;
                                                                                         >  	unsigned long 				reply_length;
                                                                                         >  
                                                                                         >  	/*
                                                                                         >  	    Load up the query structure from the property.
                                                                                         >  	*/
                                                                                         >  
                                                                                         >  	query.capx.type = PEXColorSpace;
                                                                                         >  	query.capx.model = PEXColorApproxRGB;
                                                                                         >  	query.capx.dither = PEXOn;
                                                                                         >  	query.capx.base_pixel = stdcmap->base_pixel;
                                                                                         >  	query.capx.max1 = stdcmap->red_max;
                                                                                         >  	query.capx.max2 = stdcmap->green_max;
                                                                                         >  	query.capx.max3 = stdcmap->blue_max;
                                                                                         >  	query.capx.weight1 = 0.0;
                                                                                         >  	query.capx.weight2 = 0.0;
                                                                                         >  	query.capx.weight3 = 0.0;
                                                                                         >  	query.capx.mult1 = stdcmap->red_mult;
                                                                                         >  	query.capx.mult2 = stdcmap->green_mult;
                                                                                         >  	query.capx.mult3 = stdcmap->blue_mult;
                                                                                         >  
                                                                                         >  	query.drawable = window;
                                                                                         >  
                                                                                         >  	reply = (PEXEscapeQueryColorApproxReplyData *)
                                                                                         >  		PEXEscapeWithReply (dpy, PEXEscapeQueryColorApprox, 
                                                                                         >  				    sizeof(query), ((char *) &query), 
                                                                                         >  				    &reply_length);
                                                                                         >  
                                                                                         >  	if (reply != NULL) {
                                                                                         >  
                                                                                         >  	    capx_supported = (reply->capx_is_supported);
                                                                                         >  	}
                                                                                         >  	else {
                                                                                         >  	    destroyTemporaryWindow (dpy, vinfo, window);
                                                                                         >  	    return 0;
                                                                                         >  	}
                                                                                         >      }
                                                                                         >      else {
                                                                                         >  	/* Can't determine support or non-support. */
                                                                                         >  	capx_supported = True;
                                                                                         >      }
                                                                                         >  
                                                                                         >      /*
                                                                                         >  	If the ramp as "proposed" isn't supported, make adjustments.
                                                                                         >      */
                                                                                         >  
                                                                                         >      if (!capx_supported) {
                                                                                         >  
                                                                                         >  	/*
                                                                                         >  	    These vendors have verified that the "else" clause in
                                                                                         >  	    the following if-then-else cascade is adequate for their
                                                                                         >  	    implementations.  If a particular vendor has needs that are
                                                                                         >  	    not met by the common "else" section, an "if" section should
                                                                                         >  	    be added for that vendor before the common "else" (see the
                                                                                         >  	    commented-out example below).
                                                                                         >  	*/
                                                                                         >  
                                                                                         >  	/*
                                                                                         >  	if (!strcmp(ext_info->vendor_name, "vendor_X")) {
                                                                                         >  	}
                                                                                         >  	else 
                                                                                         >  	*/
                                                                                         >  
                                                                                         >  	{
                                                                                         >  	    XmuExtendedParams 	*local_params;
                                                                                         >  	    XmuParam 		*src_ptr, *dst_ptr;
                                                                                         >  	    PEXColorApproxEntry *p_capx;
                                                                                         >  
                                                                                         >  	    /* Assuming inquiry is supported, so reply exists */
                                                                                         >  	    if (reply->count) {
                                                                                         >  		p_capx = (PEXColorApproxEntry *) (((char *) reply) + 
                                                                                         >  			    sizeof(PEXEscapeQueryColorApproxReplyData));
                                                                                         >  
                                                                                         >  		/* search for the best match, here, maybe, someday 
                                                                                         >  		if (reply->count > 1) {
                                                                                         >  		}
                                                                                         >  		*/
                                                                                         >  
                                                                                         >  		/* copy chosen entry into stdcmap */
                                                                                         >  		stdcmap->base_pixel = p_capx->base_pixel;
                                                                                         >  		stdcmap->red_max = p_capx->max1;
                                                                                         >  		stdcmap->green_max = p_capx->max2;
                                                                                         >  		stdcmap->blue_max = p_capx->max3;
                                                                                         >  		stdcmap->red_mult = p_capx->mult1;
                                                                                         >  		stdcmap->green_mult = p_capx->mult2;
                                                                                         >  		stdcmap->blue_mult = p_capx->mult3;
                                                                                         >  
                                                                                         >  		/* add control for base pixel */
                                                                                         >  		local_params = (XmuExtendedParams *)
                                                                                         >  				malloc ((sizeof(XmuExtendedParams) +
                                                                                         >  					(1 + params->num_controls + 
                                                                                         >  					params->num_hints) * 
                                                                                         >  					sizeof(XmuParam)));
                                                                                         >  		if (local_params == NULL) {
                                                                                         >  		    XFree ((char *) reply);
                                                                                         >  		    return 0;
                                                                                         >  		}
                                                                                         >  
                                                                                         >  		*alloc = True;
                                                                                         >  		*new_params = local_params;
                                                                                         >  		src_ptr = (XmuParam *) (((char *) params) +
                                                                                         >  					sizeof(XmuExtendedParams));
                                                                                         >  		dst_ptr = (XmuParam *) (((char *) local_params) +
                                                                                         >  					sizeof(XmuExtendedParams));
                                                                                         >  
                                                                                         >  		local_params->num_controls = params->num_controls+1;
                                                                                         >  		local_params->controls = dst_ptr;
                                                                                         >  		for (i=0; i<params->num_controls; i++) {
                                                                                         >  		    *dst_ptr = *src_ptr;
                                                                                         >  		    dst_ptr++;
                                                                                         >  		    src_ptr++;
                                                                                         >  		}
                                                                                         >  		dst_ptr->name = XMU_CONTROL_BASE_PIXEL;
                                                                                         >  		dst_ptr->value = p_capx->base_pixel;
                                                                                         >  		dst_ptr++;
                                                                                         >  
                                                                                         >  		local_params->num_hints = params->num_hints;
                                                                                         >  		for (i=0; i<params->num_hints; i++) {
                                                                                         >  		    *dst_ptr = *src_ptr;
                                                                                         >  		    dst_ptr++;
                                                                                         >  		    src_ptr++;
                                                                                         >  		}
                                                                                         >  	    }
                                                                                         >  	    else {
                                                                                         >  		/* don't know what to try */
                                                                                         >  		XFree ((char *) reply);
                                                                                         >  		return 0;
                                                                                         >  	    }
                                                                                         >  	}
                                                                                         >      }
                                                                                         >      else {
                                                                                         >  	*alloc = False;
                                                                                         >  	*new_params = params;
                                                                                         >      }
                                                                                         >  
                                                                                         >      if (inquiry_supported)
                                                                                         >  	XFree ((char *) reply);
                                                                                         >  
                                                                                         >      /*
                                                                                         >  	Destroy the temporary window.
                                                                                         >      */
                                                                                         >      destroyTemporaryWindow (dpy, vinfo, window);
                                                                                         >  
                                                                                         >      return 1;
                                                                                         >  }
                                                                                         >  
                                                                                         >  
                                                                                         >  static Status createTemporaryWindow (display, vis_info, window_return)
                                                                                         >      Display	*display;
                                                                                         >      XVisualInfo	*vis_info;
                                                                                         >      Window	*window_return;
                                                                                         >  {
                                                                                         >      unsigned long 		window_mask;
                                                                                         >      XSetWindowAttributes	window_attrs;
                                                                                         >      Colormap			cmap_id;
                                                                                         >  
                                                                                         >  
                                                                                         >      /*
                                                                                         >  	Create a window using override-redirect.  Do not map it.
                                                                                         >  	If the Visual is the default, use the root window.
                                                                                         >  	Otherwise, create a colormap to use.
                                                                                         >      */
                                                                                         >  
                                                                                         >      if (vis_info->visual == DefaultVisual (display, vis_info->screen)) {
                                                                                         >  
                                                                                         >  	*window_return = RootWindow (display, vis_info->screen);
                                                                                         >  	return 1;
                                                                                         >      }
                                                                                         >      else {
                                                                                         >  	cmap_id = XCreateColormap (display, 
                                                                                         >  				    RootWindow(display, vis_info->screen),
                                                                                         >  				    vis_info->visual, AllocNone );
                                                                                         >  	if (cmap_id == None)
                                                                                         >  	    return 0;
                                                                                         >  
                                                                                         >  	window_attrs.colormap = cmap_id;
                                                                                         >  	window_mask = CWColormap;
                                                                                         >  
                                                                                         >  	window_attrs.override_redirect = True;
                                                                                         >  	window_mask |= CWOverrideRedirect;
                                                                                         >  
                                                                                         >  	window_attrs.background_pixel = 0;
                                                                                         >  	window_mask |= CWBackPixel;
                                                                                         >  
                                                                                         >  	window_attrs.border_pixel = 0;
                                                                                         >  	window_mask |= CWBorderPixel;
                                                                                         >  
                                                                                         >  	*window_return = XCreateWindow (display, 
                                                                                         >  				RootWindow (display, vis_info->screen),
                                                                                         >  				10, 10, 1, 1, 0,
                                                                                         >  				vis_info->depth, 
                                                                                         >  				InputOutput,
                                                                                         >  				vis_info->visual,
                                                                                         >  				window_mask,
                                                                                         >  				&(window_attrs));
                                                                                         >  
                                                                                         >  	if (*window_return == None)
                                                                                         >  	    return 0;
                                                                                         >  	else
                                                                                         >  	    return 1;
                                                                                         >      }
                                                                                         >  } /* createTemporaryWindow */
                                                                                         >  
                                                                                         >  
                                                                                         >  static Status destroyTemporaryWindow (display, vis_info, window)
                                                                                         >      Display	*display;
                                                                                         >      XVisualInfo	*vis_info;
                                                                                         >      Window	window;
                                                                                         >  {
                                                                                         >      XWindowAttributes	window_attrs;
                                                                                         >  
                                                                                         >      /*
                                                                                         >  	If this window is not in the default Visual, 
                                                                                         >  	the Colormap and Window need to be freed.
                                                                                         >      */
                                                                                         >  
                                                                                         >      if (vis_info->visual != DefaultVisual (display, vis_info->screen)) {
                                                                                         >  
                                                                                         >  	if (XGetWindowAttributes (display, window, &window_attrs))
                                                                                         >  	    XFreeColormap (display, window_attrs.colormap);
                                                                                         >  
                                                                                         >  	XDestroyWindow (display, window);
                                                                                         >      }
                                                                                         >  
                                                                                         >      return 1;
                                                                                         >  
                                                                                         >  } /* destroyTemporaryWindow */
                                                                                         >  
                                                                                         >  #endif /* ] PEX_SUPPORT */
============== VisCmap
/* $XConsortium: VisCmap.c,v 1.10 89/10/08 15:05:47 rws Exp $ 
 * 
 * Copyright 1989 by the Massachusetts Institute of Technology
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided 
 * that the above copyright notice appear in all copies and that both that 
 * copyright notice and this permission notice appear in supporting 
 * documentation, and that the name of M.I.T. not be used in advertising
 * or publicity pertaining to distribution of the software without specific, 
 * written prior permission. M.I.T. makes no representations about the 
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Author:  Donna Converse, MIT X Consortium
 */

#include <stdio.h>
#include <math.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/Xmu/StdCmap.h>
                                                                                         >  #include <X11/Xmu/StdCmapExt.h>
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >  #include <X11/PEX5/PEXlib.h>
                                                                                         >  #endif /* ] PEX_SUPPORT */

/*
 * To create all of the appropriate standard colormaps for a given visual on
 * a given screen, use XmuVisualStandardColormaps.                                       |   * a given screen, use XmuVisualStandardColormapsExt().
 * 
 * Define all appropriate standard colormap properties for the given visual.
 * If replace is true, any previous definition will be removed.
 * If retain is true, new properties will be retained for the duration of
 * the server session.  Return 0 on failure, non-zero on success.
 * On failure, no new properties will be defined, and, old ones may have
 * been removed if replace was True.
 *
 * Not all standard colormaps are meaningful to all visual classes.  This
 * routine will check and define the following properties for the following
 * classes, provided that the size of the colormap is not too small.
 *
 *	DirectColor and PseudoColor
 *	    RGB_DEFAULT_MAP
 *	    RGB_BEST_MAP
 *	    RGB_RED_MAP
 *	    RGB_GREEN_MAP
 * 	    RGB_BLUE_MAP
 *          RGB_GRAY_MAP
 *
 *	TrueColor and StaticColor
 *	    RGB_BEST_MAP
                                                                                         >   *	    if PEX support required, RGB_DEFAULT_MAP
 *
 *	GrayScale and StaticGray                                                         |   *	GrayScale
                                                                                         >   *	    RGB_DEFAULT_MAP
 *	    RGB_GRAY_MAP
                                                                                         >   *
                                                                                         >   *	StaticGray
                                                                                         >   *	    RGB_GRAY_MAP
 */

Status XmuVisualStandardColormaps(dpy, screen, visualid, depth, replace,                 |  Status XmuVisualStandardColormapsExt(dpy, screen, visualid, depth, replace,
				  retain)                                                |  				  retain, params)
    Display		*dpy;		/* specifies server connection */
    int			screen;		/* specifies screen number */
    VisualID		visualid;	/* specifies the visual */
    unsigned int	depth;		/* specifies the visual */
    Bool		replace;	/* specifies whether to replace */
    Bool		retain;		/* specifies whether to retain */
                                                                                         >      XmuExtendedParams 	*params;	/* controls and hints */
{
    Status		status;
    int			n;
    long		vinfo_mask;
    XVisualInfo		vinfo_template, *vinfo;
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >      int			PEX_required = False;
                                                                                         >  #endif /* ] PEX_SUPPORT */

                                                                                         >      /*
                                                                                         >  	Decode controls and hints supported in this procedure.
                                                                                         >      */
                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >      if (params) {
                                                                                         >  	int i;
                                                                                         >  	for (i=0; i < params->num_controls; i++) {
                                                                                         >  	    if (params->controls[i].name == XMU_CONTROL_PEX_SUPPORTED)
                                                                                         >  		PEX_required = params->controls[i].value;
                                                                                         >  	}
                                                                                         >      }
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >          
    vinfo_template.screen = screen;
    vinfo_template.visualid = visualid;
    vinfo_template.depth = depth;
    vinfo_mask = VisualScreenMask | VisualIDMask | VisualDepthMask;
    if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
	return 0;

    if (vinfo->colormap_size <= 2) {
	/* Monochrome visuals have no standard maps; considered successful */
	XFree((char *) vinfo);
	return 1;
    }

                                                                                         >  #ifdef PEX_SUPPORT /* [ */
                                                                                         >      /*
                                                                                         >  	If PEX is required, check support for the Visual.
                                                                                         >      */
                                                                                         >      if (PEX_required) {
                                                                                         >  
                                                                                         >  	PEXExtensionInfo	*ext_info;
                                                                                         >  	PEXRenderingTarget	*targets;
                                                                                         >  	unsigned long		target_count;
                                                                                         >  
                                                                                         >  	targets = NULL;
                                                                                         >  	target_count = 0;
                                                                                         >  
                                                                                         >  	if (NULL == (ext_info = PEXGetExtensionInfo (dpy)))
                                                                                         >  	    return 0;
                                                                                         >  
                                                                                         >  	if ((ext_info->major_version == 5) &&
                                                                                         >  	    (ext_info->minor_version >= 1)) {
                                                                                         >  
                                                                                         >  	    if ((! PEXMatchRenderingTargets (dpy, 
                                                                                         >  					RootWindow(dpy, screen),
                                                                                         >  					depth, PEXWindowDrawable, vinfo->visual,
                                                                                         >  					1, &target_count, &targets)) ||
                                                                                         >  		(target_count == 0)) {
                                                                                         >  		XFree((char *) vinfo);
                                                                                         >  		return 0;
                                                                                         >  	    }
                                                                                         >  
                                                                                         >  	    XFree (targets);
                                                                                         >  	}
                                                                                         >      }
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
    switch (vinfo->class)
    {
      case PseudoColor:
      case DirectColor:
	status = XmuLookupStandardColormap(dpy, screen, visualid, depth,                 |  	status = XmuLookupStandardColormapExt(dpy, screen, visualid, depth,
					   XA_RGB_DEFAULT_MAP, replace,retain);          |  					   XA_RGB_DEFAULT_MAP, replace,retain,
                                                                                         >  					   params);
	if (!status) break;

	status = XmuLookupStandardColormap(dpy, screen, visualid, depth,                 |  	status = XmuLookupStandardColormapExt(dpy, screen, visualid, depth,
					   XA_RGB_GRAY_MAP, replace, retain);            |  					   XA_RGB_GRAY_MAP, replace, retain,
                                                                                         >  					   params);
	if (!status) {
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_DEFAULT_MAP);
	    break;
	}

	status = XmuLookupStandardColormap(dpy, screen, visualid, depth,                 |  	status = XmuLookupStandardColormapExt(dpy, screen, visualid, depth,
					   XA_RGB_RED_MAP, replace, retain);             |  					   XA_RGB_RED_MAP, replace, retain,
                                                                                         >  					   params);
	if (!status) {
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_DEFAULT_MAP);
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_GRAY_MAP);
	    break;
	}

	status = XmuLookupStandardColormap(dpy, screen, visualid, depth,                 |  	status = XmuLookupStandardColormapExt(dpy, screen, visualid, depth,
					   XA_RGB_GREEN_MAP, replace, retain);           |  					   XA_RGB_GREEN_MAP, replace, retain,
                                                                                         >  					   params);
	if (!status) {
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_DEFAULT_MAP);
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_GRAY_MAP);
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_RED_MAP);
	    break;
	}

	status = XmuLookupStandardColormap(dpy, screen, visualid, depth,                 |  	status = XmuLookupStandardColormapExt(dpy, screen, visualid, depth,
					   XA_RGB_BLUE_MAP, replace, retain);            |  					   XA_RGB_BLUE_MAP, replace, retain,
                                                                                         >  					   params);
	if (!status) {
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_DEFAULT_MAP);
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_GRAY_MAP);
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_RED_MAP);
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_GREEN_MAP);
	    break;
	}
	/* fall through */

      case StaticColor:
      case TrueColor:

	status = XmuLookupStandardColormap(dpy, screen, visualid, depth,                 |  #ifdef PEX_SUPPORT /* [ */
					   XA_RGB_BEST_MAP, replace, retain);            |  	if (PEX_required &&
	if (!status && (vinfo->class == PseudoColor ||                                   |  	    ((vinfo->class == TrueColor) || (vinfo->class == StaticColor))) {
			vinfo->class == DirectColor)) {                                  |  
                                                                                         >  	    status = XmuLookupStandardColormapExt(dpy, screen, visualid, depth,
                                                                                         >  					   XA_RGB_DEFAULT_MAP, replace,retain,
                                                                                         >  					   params);
                                                                                         >  	    if (!status) break;
                                                                                         >  	}
                                                                                         >  #endif /* ] PEX_SUPPORT */
                                                                                         >  
                                                                                         >  	status = XmuLookupStandardColormapExt(dpy, screen, visualid, depth,
                                                                                         >  					   XA_RGB_BEST_MAP, replace, retain,
                                                                                         >  					   params);
                                                                                         >  
                                                                                         >  	if (!status) {
                                                                                         >  	    if (vinfo->class == PseudoColor || 
                                                                                         >  		vinfo->class == DirectColor) {
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_DEFAULT_MAP);
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_GRAY_MAP);
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_RED_MAP);
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_GREEN_MAP);
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_BLUE_MAP);
	}
                                                                                         >  	    else {
                                                                                         >  		XmuDeleteStandardColormap(dpy, screen, XA_RGB_DEFAULT_MAP);
                                                                                         >  	    }
                                                                                         >  	}
	break;
	/* the end for PseudoColor, DirectColor, StaticColor, and TrueColor */

      case GrayScale:
	status = XmuLookupStandardColormap(dpy, screen, visualid, depth,                 |  	status = XmuLookupStandardColormapExt(dpy, screen, visualid, depth,
					   XA_RGB_DEFAULT_MAP, replace,
					   retain);                                      |  					   retain, params);
	if (! status) break;
	/* fall through */

      case StaticGray:

	status = XmuLookupStandardColormap(dpy, screen, visualid, depth,                 |  	status = XmuLookupStandardColormapExt(dpy, screen, visualid, depth,
					   XA_RGB_GRAY_MAP, replace, retain);            |  					   XA_RGB_GRAY_MAP, replace, retain,
                                                                                         >  					   params);
	if (! status && vinfo->class == GrayScale) {
	    XmuDeleteStandardColormap(dpy, screen, XA_RGB_DEFAULT_MAP);
	    break;
	}
    }

    XFree((char *) vinfo);
    return status;
}
