Blame src/CrCmap.c

Packit Service 2b1f13
/*
Packit Service 2b1f13
Packit Service 2b1f13
Copyright 1989, 1998  The Open Group
Packit Service 2b1f13
Packit Service 2b1f13
Permission to use, copy, modify, distribute, and sell this software and its
Packit Service 2b1f13
documentation for any purpose is hereby granted without fee, provided that
Packit Service 2b1f13
the above copyright notice appear in all copies and that both that
Packit Service 2b1f13
copyright notice and this permission notice appear in supporting
Packit Service 2b1f13
documentation.
Packit Service 2b1f13
Packit Service 2b1f13
The above copyright notice and this permission notice shall be included in
Packit Service 2b1f13
all copies or substantial portions of the Software.
Packit Service 2b1f13
Packit Service 2b1f13
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit Service 2b1f13
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit Service 2b1f13
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
Packit Service 2b1f13
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
Packit Service 2b1f13
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
Packit Service 2b1f13
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Packit Service 2b1f13
Packit Service 2b1f13
Except as contained in this notice, the name of The Open Group shall not be
Packit Service 2b1f13
used in advertising or otherwise to promote the sale, use or other dealings
Packit Service 2b1f13
in this Software without prior written authorization from The Open Group.
Packit Service 2b1f13
Packit Service 2b1f13
*/
Packit Service 2b1f13
Packit Service 2b1f13
/*
Packit Service 2b1f13
 * Author:  Donna Converse, MIT X Consortium
Packit Service 2b1f13
 */
Packit Service 2b1f13
Packit Service 2b1f13
/*
Packit Service 2b1f13
 * CreateCmap.c - given a standard colormap description, make the map.
Packit Service 2b1f13
 */
Packit Service 2b1f13
Packit Service 2b1f13
#ifdef HAVE_CONFIG_H
Packit Service 2b1f13
#include <config.h>
Packit Service 2b1f13
#endif
Packit Service 2b1f13
#include <stdio.h>
Packit Service 2b1f13
#include <stdlib.h>
Packit Service 2b1f13
#include <X11/Xlib.h>
Packit Service 2b1f13
#include <X11/Xutil.h>
Packit Service 2b1f13
#include <X11/Xmu/StdCmap.h>
Packit Service 2b1f13
Packit Service 2b1f13
/*
Packit Service 2b1f13
 * Prototypes
Packit Service 2b1f13
 */
Packit Service 2b1f13
/* allocate entire map Read Only */
Packit Service 2b1f13
static int ROmap(Display*, Colormap, unsigned long[], int, int);
Packit Service 2b1f13
Packit Service 2b1f13
/* allocate a cell, prefer Read Only */
Packit Service 2b1f13
static Status ROorRWcell(Display*, Colormap, unsigned long[], int,
Packit Service 2b1f13
			 XColor*, unsigned long);
Packit Service 2b1f13
Packit Service 2b1f13
/* allocate a cell Read Write */
Packit Service 2b1f13
static Status RWcell(Display*, Colormap, XColor*, XColor*, unsigned long*);
Packit Service 2b1f13
Packit Service 2b1f13
/* for quicksort */
Packit Service 2b1f13
static int compare(_Xconst void*, _Xconst void*);
Packit Service 2b1f13
Packit Service 2b1f13
/* find contiguous sequence of cells */
Packit Service 2b1f13
static Status contiguous(unsigned long[], int, int, unsigned long, int*, int*);
Packit Service 2b1f13
Packit Service 2b1f13
/* frees resources before quitting */
Packit Service 2b1f13
static void free_cells(Display*, Colormap, unsigned long[], int, int);
Packit Service 2b1f13
Packit Service 2b1f13
/* create a map in a RO visual type */
Packit Service 2b1f13
static Status readonly_map(Display*, XVisualInfo*, XStandardColormap*);
Packit Service 2b1f13
Packit Service 2b1f13
/* create a map in a RW visual type */
Packit Service 2b1f13
static Status readwrite_map(Display*, XVisualInfo*, XStandardColormap*);
Packit Service 2b1f13
Packit Service 2b1f13
#define lowbit(x) ((x) & (~(x) + 1))
Packit Service 2b1f13
#define TRUEMATCH(mult,max,mask) \
Packit Service 2b1f13
    (colormap->max * colormap->mult <= vinfo->mask && \
Packit Service 2b1f13
     lowbit(vinfo->mask) == colormap->mult)
Packit Service 2b1f13
Packit Service 2b1f13
/*
Packit Service 2b1f13
 * To create any one colormap which is described by an XStandardColormap
Packit Service 2b1f13
 * structure, use XmuCreateColormap().
Packit Service 2b1f13
 *
Packit Service 2b1f13
 * Return 0 on failure, non-zero on success.
Packit Service 2b1f13
 * Resources created by this function are not made permanent.
Packit Service 2b1f13
 * No argument error checking is provided.  Use at your own risk.
Packit Service 2b1f13
 *
Packit Service 2b1f13
 * All colormaps are created with read only allocations, with the exception
Packit Service 2b1f13
 * of read only allocations of colors in the default map or otherwise
Packit Service 2b1f13
 * which fail to return the expected pixel value, and these are individually
Packit Service 2b1f13
 * defined as read/write allocations.  This is done so that all the cells
Packit Service 2b1f13
 * defined in the default map are contiguous, for use in image processing.
Packit Service 2b1f13
 * This typically happens with White and Black in the default map.
Packit Service 2b1f13
 *
Packit Service 2b1f13
 * Colormaps of static visuals are considered to be successfully created if
Packit Service 2b1f13
 * the map of the static visual matches the definition given in the
Packit Service 2b1f13
 * standard colormap structure.
Packit Service 2b1f13
 */
Packit Service 2b1f13
Packit Service 2b1f13
Status
Packit Service 2b1f13
XmuCreateColormap(Display *dpy, XStandardColormap *colormap)
Packit Service 2b1f13
     /* dpy	 - specifies the connection under which the map is created
Packit Service 2b1f13
      * colormap - specifies the map to be created, and returns, particularly
Packit Service 2b1f13
      *		   if the map is created as a subset of the default colormap
Packit Service 2b1f13
      *		   of the screen, the base_pixel of the map.
Packit Service 2b1f13
					 */
Packit Service 2b1f13
{
Packit Service 2b1f13
    XVisualInfo		vinfo_template;	/* template visual information */
Packit Service 2b1f13
    XVisualInfo		*vinfo;		/* matching visual information */
Packit Service 2b1f13
    XVisualInfo		*vpointer;	/* for freeing the entire list */
Packit Service 2b1f13
    long		vinfo_mask;	/* specifies the visual mask value */
Packit Service 2b1f13
    int 		n;		/* number of matching visuals */
Packit Service 2b1f13
    int			status;
Packit Service 2b1f13
Packit Service 2b1f13
    vinfo_template.visualid = colormap->visualid;
Packit Service 2b1f13
    vinfo_mask = VisualIDMask;
Packit Service 2b1f13
    if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
Packit Service 2b1f13
	return 0;
Packit Service 2b1f13
Packit Service 2b1f13
    /* A visual id may be valid on multiple screens.  Also, there may
Packit Service 2b1f13
     * be multiple visuals with identical visual ids at different depths.
Packit Service 2b1f13
     * If the colormap is the Default Colormap, use the Default Visual.
Packit Service 2b1f13
     * Otherwise, arbitrarily, use the deepest visual.
Packit Service 2b1f13
     */
Packit Service 2b1f13
    vpointer = vinfo;
Packit Service 2b1f13
    if (n > 1)
Packit Service 2b1f13
    {
Packit Service 2b1f13
	register int	i;
Packit Service 2b1f13
	register int	screen_number;
Packit Service 2b1f13
	Bool 		def_cmap;
Packit Service 2b1f13
Packit Service 2b1f13
	def_cmap = False;
Packit Service 2b1f13
	for (screen_number = ScreenCount(dpy); --screen_number >= 0; )
Packit Service 2b1f13
	    if (colormap->colormap == DefaultColormap(dpy, screen_number)) {
Packit Service 2b1f13
		def_cmap = True;
Packit Service 2b1f13
		break;
Packit Service 2b1f13
	    }
Packit Service 2b1f13
Packit Service 2b1f13
	if (def_cmap) {
Packit Service 2b1f13
	    for (i=0; i < n; i++, vinfo++) {
Packit Service 2b1f13
		if (vinfo->visual == DefaultVisual(dpy, screen_number))
Packit Service 2b1f13
			break;
Packit Service 2b1f13
	    }
Packit Service 2b1f13
	} else {
Packit Service 2b1f13
	    int			maxdepth = 0;
Packit Service 2b1f13
	    XVisualInfo		*v = NULL;
Packit Service 2b1f13
Packit Service 2b1f13
	    for (i=0; i < n; i++, vinfo++)
Packit Service 2b1f13
		if (vinfo->depth > maxdepth) {
Packit Service 2b1f13
		    maxdepth = vinfo->depth;
Packit Service 2b1f13
		    v = vinfo;
Packit Service 2b1f13
		}
Packit Service 2b1f13
	    vinfo = v;
Packit Service 2b1f13
	}
Packit Service 2b1f13
    }
Packit Service 2b1f13
Packit Service 2b1f13
    if (vinfo->class == PseudoColor || vinfo->class == DirectColor ||
Packit Service 2b1f13
	vinfo->class == GrayScale)
Packit Service 2b1f13
	status = readwrite_map(dpy, vinfo, colormap);
Packit Service 2b1f13
    else if (vinfo->class == TrueColor)
Packit Service 2b1f13
	status = TRUEMATCH(red_mult, red_max, red_mask) &&
Packit Service 2b1f13
	         TRUEMATCH(green_mult, green_max, green_mask) &&
Packit Service 2b1f13
		 TRUEMATCH(blue_mult, blue_max, blue_mask);
Packit Service 2b1f13
    else
Packit Service 2b1f13
	status = readonly_map(dpy, vinfo, colormap);
Packit Service 2b1f13
Packit Service 2b1f13
    XFree((char *) vpointer);
Packit Service 2b1f13
    return status;
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
/****************************************************************************/
Packit Service 2b1f13
static Status
Packit Service 2b1f13
readwrite_map(Display *dpy, XVisualInfo *vinfo, XStandardColormap *colormap)
Packit Service 2b1f13
{
Packit Service 2b1f13
    register unsigned long i, n;	/* index counters */
Packit Service 2b1f13
    unsigned long	ncolors;	/* number of colors to be defined */
Packit Service 2b1f13
    int			npixels;	/* number of pixels allocated R/W */
Packit Service 2b1f13
    int			first_index;	/* first index of pixels to use */
Packit Service 2b1f13
    int			remainder;	/* first index of remainder */
Packit Service 2b1f13
    XColor		color;		/* the definition of a color */
Packit Service 2b1f13
    unsigned long	*pixels;	/* array of colormap pixels */
Packit Service 2b1f13
    unsigned long	delta;
Packit Service 2b1f13
Packit Service 2b1f13
Packit Service 2b1f13
    /* Determine ncolors, the number of colors to be defined.
Packit Service 2b1f13
     * Insure that 1 < ncolors <= the colormap size.
Packit Service 2b1f13
     */
Packit Service 2b1f13
    if (vinfo->class == DirectColor) {
Packit Service 2b1f13
	ncolors = colormap->red_max;
Packit Service 2b1f13
	if (colormap->green_max > ncolors)
Packit Service 2b1f13
	    ncolors = colormap->green_max;
Packit Service 2b1f13
	if (colormap->blue_max > ncolors)
Packit Service 2b1f13
	    ncolors = colormap->blue_max;
Packit Service 2b1f13
	ncolors++;
Packit Service 2b1f13
	delta = lowbit(vinfo->red_mask) +
Packit Service 2b1f13
	        lowbit(vinfo->green_mask) +
Packit Service 2b1f13
		lowbit(vinfo->blue_mask);
Packit Service 2b1f13
    } else {
Packit Service 2b1f13
	ncolors = colormap->red_max * colormap->red_mult +
Packit Service 2b1f13
		  colormap->green_max * colormap->green_mult +
Packit Service 2b1f13
		  colormap->blue_max * colormap->blue_mult + 1;
Packit Service 2b1f13
	delta = 1;
Packit Service 2b1f13
    }
Packit Service 2b1f13
    if (ncolors <= 1 || (int) ncolors > vinfo->colormap_size)	return 0;
Packit Service 2b1f13
Packit Service 2b1f13
    /* Allocate Read/Write as much of the colormap as we can possibly get.
Packit Service 2b1f13
     * Then insure that the pixels we were allocated are given in
Packit Service 2b1f13
     * monotonically increasing order, using a quicksort.  Next, insure
Packit Service 2b1f13
     * that our allocation includes a subset of contiguous pixels at least
Packit Service 2b1f13
     * as long as the number of colors to be defined.  Now we know that
Packit Service 2b1f13
     * these conditions are met:
Packit Service 2b1f13
     *	1) There are no free cells in the colormap.
Packit Service 2b1f13
     *  2) We have a contiguous sequence of pixels, monotonically
Packit Service 2b1f13
     *     increasing, of length >= the number of colors requested.
Packit Service 2b1f13
     *
Packit Service 2b1f13
     * One cell at a time, we will free, compute the next color value,
Packit Service 2b1f13
     * then allocate read only.  This takes a long time.
Packit Service 2b1f13
     * This is done to insure that cells are allocated read only in the
Packit Service 2b1f13
     * contiguous order which we prefer.  If the server has a choice of
Packit Service 2b1f13
     * cells to grant to an allocation request, the server may give us any
Packit Service 2b1f13
     * cell, so that is why we do these slow gymnastics.
Packit Service 2b1f13
     */
Packit Service 2b1f13
Packit Service 2b1f13
    if ((pixels = (unsigned long *) calloc((unsigned) vinfo->colormap_size,
Packit Service 2b1f13
				      sizeof(unsigned long))) == NULL)
Packit Service 2b1f13
	return 0;
Packit Service 2b1f13
Packit Service 2b1f13
    if ((npixels = ROmap(dpy, colormap->colormap, pixels,
Packit Service 2b1f13
			   vinfo->colormap_size, ncolors)) == 0) {
Packit Service 2b1f13
	free((char *) pixels);
Packit Service 2b1f13
	return 0;
Packit Service 2b1f13
    }
Packit Service 2b1f13
Packit Service 2b1f13
    qsort((char *) pixels, npixels, sizeof(unsigned long), compare);
Packit Service 2b1f13
Packit Service 2b1f13
    if (!contiguous(pixels, npixels, ncolors, delta, &first_index, &remainder))
Packit Service 2b1f13
    {
Packit Service 2b1f13
	/* can't find enough contiguous cells, give up */
Packit Service 2b1f13
	XFreeColors(dpy, colormap->colormap, pixels, npixels,
Packit Service 2b1f13
		    (unsigned long) 0);
Packit Service 2b1f13
	free((char *) pixels);
Packit Service 2b1f13
	return 0;
Packit Service 2b1f13
    }
Packit Service 2b1f13
    colormap->base_pixel = pixels[first_index];
Packit Service 2b1f13
Packit Service 2b1f13
    /* construct a gray map */
Packit Service 2b1f13
    if (colormap->red_mult == 1 && colormap->green_mult == 1 &&
Packit Service 2b1f13
	colormap->blue_mult == 1)
Packit Service 2b1f13
	for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
Packit Service 2b1f13
	{
Packit Service 2b1f13
	    color.pixel = n;
Packit Service 2b1f13
	    color.blue = color.green = color.red =
Packit Service 2b1f13
		(unsigned short) ((i * 65535) / (colormap->red_max +
Packit Service 2b1f13
						 colormap->green_max +
Packit Service 2b1f13
						 colormap->blue_max));
Packit Service 2b1f13
Packit Service 2b1f13
	    if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
Packit Service 2b1f13
			     first_index + i))
Packit Service 2b1f13
		return 0;
Packit Service 2b1f13
	}
Packit Service 2b1f13
Packit Service 2b1f13
    /* construct a red ramp map */
Packit Service 2b1f13
    else if (colormap->green_max == 0 && colormap->blue_max == 0)
Packit Service 2b1f13
    	for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
Packit Service 2b1f13
	{
Packit Service 2b1f13
	    color.pixel = n;
Packit Service 2b1f13
	    color.red = (unsigned short) ((i * 65535) / colormap->red_max);
Packit Service 2b1f13
	    color.green = color.blue = 0;
Packit Service 2b1f13
Packit Service 2b1f13
	    if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
Packit Service 2b1f13
			     first_index + i))
Packit Service 2b1f13
		return 0;
Packit Service 2b1f13
	}
Packit Service 2b1f13
Packit Service 2b1f13
    /* construct a green ramp map */
Packit Service 2b1f13
    else if (colormap->red_max == 0 && colormap->blue_max == 0)
Packit Service 2b1f13
    	for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
Packit Service 2b1f13
	{
Packit Service 2b1f13
	    color.pixel = n;
Packit Service 2b1f13
	    color.green = (unsigned short) ((i * 65535) / colormap->green_max);
Packit Service 2b1f13
	    color.red = color.blue = 0;
Packit Service 2b1f13
Packit Service 2b1f13
	    if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
Packit Service 2b1f13
			     first_index + i))
Packit Service 2b1f13
		return 0;
Packit Service 2b1f13
	}
Packit Service 2b1f13
Packit Service 2b1f13
    /* construct a blue ramp map */
Packit Service 2b1f13
    else if (colormap->red_max == 0 && colormap->green_max == 0)
Packit Service 2b1f13
    	for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
Packit Service 2b1f13
	{
Packit Service 2b1f13
	    color.pixel = n;
Packit Service 2b1f13
	    color.blue = (unsigned short) ((i * 65535) / colormap->blue_max);
Packit Service 2b1f13
	    color.red = color.green = 0;
Packit Service 2b1f13
Packit Service 2b1f13
	    if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
Packit Service 2b1f13
			     first_index + i))
Packit Service 2b1f13
		return 0;
Packit Service 2b1f13
	}
Packit Service 2b1f13
Packit Service 2b1f13
    /* construct a standard red green blue cube map */
Packit Service 2b1f13
    else
Packit Service 2b1f13
    {
Packit Service 2b1f13
#define calc(max,mult) (((n / colormap->mult) % \
Packit Service 2b1f13
			 (colormap->max + 1)) * 65535) / colormap->max
Packit Service 2b1f13
Packit Service 2b1f13
    	for (n=0, i=0; i < ncolors; i++, n += delta)
Packit Service 2b1f13
	{
Packit Service 2b1f13
	    color.pixel = n + colormap->base_pixel;
Packit Service 2b1f13
	    color.red = calc(red_max, red_mult);
Packit Service 2b1f13
	    color.green = calc(green_max, green_mult);
Packit Service 2b1f13
	    color.blue = calc(blue_max, blue_mult);
Packit Service 2b1f13
	    if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
Packit Service 2b1f13
			     first_index + i))
Packit Service 2b1f13
		return 0;
Packit Service 2b1f13
	}
Packit Service 2b1f13
#undef calc
Packit Service 2b1f13
    }
Packit Service 2b1f13
    /* We have a read-only map defined.  Now free unused cells,
Packit Service 2b1f13
     * first those occuring before the contiguous sequence begins,
Packit Service 2b1f13
     * then any following the contiguous sequence.
Packit Service 2b1f13
     */
Packit Service 2b1f13
Packit Service 2b1f13
    if (first_index)
Packit Service 2b1f13
	XFreeColors(dpy, colormap->colormap, pixels, first_index,
Packit Service 2b1f13
		    (unsigned long) 0);
Packit Service 2b1f13
    if (remainder)
Packit Service 2b1f13
	XFreeColors(dpy, colormap->colormap,
Packit Service 2b1f13
		    &(pixels[first_index + ncolors]), remainder,
Packit Service 2b1f13
		    (unsigned long) 0);
Packit Service 2b1f13
Packit Service 2b1f13
    free((char *) pixels);
Packit Service 2b1f13
    return 1;
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
Packit Service 2b1f13
/****************************************************************************/
Packit Service 2b1f13
static int
Packit Service 2b1f13
ROmap(Display *dpy, Colormap cmap, unsigned long pixels[], int m, int n)
Packit Service 2b1f13
     /*
Packit Service 2b1f13
      * dpy	- the X server connection
Packit Service 2b1f13
      * cmap	- specifies colormap ID
Packit Service 2b1f13
      * pixels	- returns pixel allocations
Packit Service 2b1f13
      * m	- specifies colormap size
Packit Service 2b1f13
      * n	- specifies number of colors
Packit Service 2b1f13
      */
Packit Service 2b1f13
{
Packit Service 2b1f13
    register int	p;
Packit Service 2b1f13
Packit Service 2b1f13
    /* first try to allocate the entire colormap */
Packit Service 2b1f13
    if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL,
Packit Service 2b1f13
			 (unsigned) 0, pixels, (unsigned) m))
Packit Service 2b1f13
	return m;
Packit Service 2b1f13
Packit Service 2b1f13
    /* Allocate all available cells in the colormap, using a binary
Packit Service 2b1f13
     * algorithm to discover how many cells we can allocate in the colormap.
Packit Service 2b1f13
     */
Packit Service 2b1f13
    m--;
Packit Service 2b1f13
    while (n <= m) {
Packit Service 2b1f13
	p = n + ((m - n + 1) / 2);
Packit Service 2b1f13
	if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL,
Packit Service 2b1f13
			     (unsigned) 0, pixels, (unsigned) p)) {
Packit Service 2b1f13
	    if (p == m)
Packit Service 2b1f13
		return p;
Packit Service 2b1f13
	    else {
Packit Service 2b1f13
		XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
Packit Service 2b1f13
		n = p;
Packit Service 2b1f13
	    }
Packit Service 2b1f13
	}
Packit Service 2b1f13
	else
Packit Service 2b1f13
	    m = p - 1;
Packit Service 2b1f13
    }
Packit Service 2b1f13
    return 0;
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
Packit Service 2b1f13
/****************************************************************************/
Packit Service 2b1f13
static Status
Packit Service 2b1f13
contiguous(unsigned long pixels[], int npixels, int ncolors,
Packit Service 2b1f13
	   unsigned long delta, int *first, int *rem)
Packit Service 2b1f13
     /* pixels	- specifies allocated pixels
Packit Service 2b1f13
      * npixels	- specifies count of alloc'd pixels
Packit Service 2b1f13
      * ncolors - specifies needed sequence length
Packit Service 2b1f13
      * delta	- between pixels
Packit Service 2b1f13
      * first	- returns first index of sequence
Packit Service 2b1f13
      * rem	- returns first index after sequence, or 0, if none follow
Packit Service 2b1f13
      */
Packit Service 2b1f13
{
Packit Service 2b1f13
    register int i = 1;		/* walking index into the pixel array */
Packit Service 2b1f13
    register int count = 1;	/* length of sequence discovered so far */
Packit Service 2b1f13
Packit Service 2b1f13
    *first = 0;
Packit Service 2b1f13
    if (npixels == ncolors) {
Packit Service 2b1f13
	*rem = 0;
Packit Service 2b1f13
	return 1;
Packit Service 2b1f13
    }
Packit Service 2b1f13
    *rem = npixels - 1;
Packit Service 2b1f13
    while (count < ncolors && ncolors - count <= *rem)
Packit Service 2b1f13
    {
Packit Service 2b1f13
	if (pixels[i-1] + delta == pixels[i])
Packit Service 2b1f13
	    count++;
Packit Service 2b1f13
	else {
Packit Service 2b1f13
	    count = 1;
Packit Service 2b1f13
	    *first = i;
Packit Service 2b1f13
	}
Packit Service 2b1f13
	i++;
Packit Service 2b1f13
	(*rem)--;
Packit Service 2b1f13
    }
Packit Service 2b1f13
    if (count != ncolors)
Packit Service 2b1f13
	return 0;
Packit Service 2b1f13
    return 1;
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
Packit Service 2b1f13
/****************************************************************************/
Packit Service 2b1f13
static Status
Packit Service 2b1f13
ROorRWcell(Display *dpy, Colormap cmap, unsigned long pixels[],
Packit Service 2b1f13
	   int npixels, XColor *color, unsigned long p)
Packit Service 2b1f13
{
Packit Service 2b1f13
    unsigned long	pixel;
Packit Service 2b1f13
    XColor		request;
Packit Service 2b1f13
Packit Service 2b1f13
    /* Free the read/write allocation of one cell in the colormap.
Packit Service 2b1f13
     * Request a read only allocation of one cell in the colormap.
Packit Service 2b1f13
     * If the read only allocation cannot be granted, give up, because
Packit Service 2b1f13
     * there must be no free cells in the colormap.
Packit Service 2b1f13
     * If the read only allocation is granted, but gives us a cell which
Packit Service 2b1f13
     * is not the one that we just freed, it is probably the case that
Packit Service 2b1f13
     * we are trying allocate White or Black or some other color which
Packit Service 2b1f13
     * already has a read-only allocation in the map.  So we try to
Packit Service 2b1f13
     * allocate the previously freed cell with a read/write allocation,
Packit Service 2b1f13
     * because we want contiguous cells for image processing algorithms.
Packit Service 2b1f13
     */
Packit Service 2b1f13
Packit Service 2b1f13
    pixel = color->pixel;
Packit Service 2b1f13
    request.red = color->red;
Packit Service 2b1f13
    request.green = color->green;
Packit Service 2b1f13
    request.blue = color->blue;
Packit Service 2b1f13
Packit Service 2b1f13
    XFreeColors(dpy, cmap, &pixel, 1, (unsigned long) 0);
Packit Service 2b1f13
    if (! XAllocColor(dpy, cmap, color)
Packit Service 2b1f13
	|| (color->pixel != pixel &&
Packit Service 2b1f13
	    (!RWcell(dpy, cmap, color, &request, &pixel))))
Packit Service 2b1f13
    {
Packit Service 2b1f13
	free_cells(dpy, cmap, pixels, npixels, (int)p);
Packit Service 2b1f13
	return 0;
Packit Service 2b1f13
    }
Packit Service 2b1f13
    return 1;
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
Packit Service 2b1f13
/****************************************************************************/
Packit Service 2b1f13
static void
Packit Service 2b1f13
free_cells(Display *dpy, Colormap cmap, unsigned long pixels[],
Packit Service 2b1f13
	   int npixels, int p)
Packit Service 2b1f13
     /*
Packit Service 2b1f13
      * pixels	- to be freed
Packit Service 2b1f13
      *	npixels	- original number allocated
Packit Service 2b1f13
      */
Packit Service 2b1f13
{
Packit Service 2b1f13
    /* One of the npixels allocated has already been freed.
Packit Service 2b1f13
     * p is the index of the freed pixel.
Packit Service 2b1f13
     * First free the pixels preceeding p, and there are p of them;
Packit Service 2b1f13
     * then free the pixels following p, there are npixels - p - 1 of them.
Packit Service 2b1f13
     */
Packit Service 2b1f13
    XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
Packit Service 2b1f13
    XFreeColors(dpy, cmap, &(pixels[p+1]), npixels - p - 1, (unsigned long) 0);
Packit Service 2b1f13
    free((char *) pixels);
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
Packit Service 2b1f13
/****************************************************************************/
Packit Service 2b1f13
static Status
Packit Service 2b1f13
RWcell(Display *dpy, Colormap cmap, XColor *color, XColor *request,
Packit Service 2b1f13
       unsigned long *pixel)
Packit Service 2b1f13
{
Packit Service 2b1f13
    unsigned long	n = *pixel;
Packit Service 2b1f13
Packit Service 2b1f13
    XFreeColors(dpy, cmap, &(color->pixel), 1, (unsigned long)0);
Packit Service 2b1f13
    if (! XAllocColorCells(dpy, cmap, (Bool) 0, (unsigned long *) NULL,
Packit Service 2b1f13
			   (unsigned) 0, pixel, (unsigned) 1))
Packit Service 2b1f13
	return 0;
Packit Service 2b1f13
    if (*pixel != n)
Packit Service 2b1f13
    {
Packit Service 2b1f13
	XFreeColors(dpy, cmap, pixel, 1, (unsigned long) 0);
Packit Service 2b1f13
	return 0;
Packit Service 2b1f13
    }
Packit Service 2b1f13
    color->pixel = *pixel;
Packit Service 2b1f13
    color->flags = DoRed | DoGreen | DoBlue;
Packit Service 2b1f13
    color->red = request->red;
Packit Service 2b1f13
    color->green = request->green;
Packit Service 2b1f13
    color->blue = request->blue;
Packit Service 2b1f13
    XStoreColors(dpy, cmap, color, 1);
Packit Service 2b1f13
    return 1;
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
Packit Service 2b1f13
/****************************************************************************/
Packit Service 2b1f13
static int
Packit Service 2b1f13
compare(_Xconst void *e1, _Xconst void *e2)
Packit Service 2b1f13
{
Packit Service 2b1f13
  return ((int)(*(_Xconst long *)e1 - *(_Xconst long *)e2));
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
Packit Service 2b1f13
/****************************************************************************/
Packit Service 2b1f13
static Status
Packit Service 2b1f13
readonly_map(Display *dpy, XVisualInfo *vinfo, XStandardColormap *colormap)
Packit Service 2b1f13
{
Packit Service 2b1f13
    int			i, last_pixel;
Packit Service 2b1f13
    XColor		color;
Packit Service 2b1f13
Packit Service 2b1f13
    last_pixel = (colormap->red_max + 1) * (colormap->green_max + 1) *
Packit Service 2b1f13
	(colormap->blue_max + 1) + colormap->base_pixel - 1;
Packit Service 2b1f13
Packit Service 2b1f13
    for(i=colormap->base_pixel; i <= last_pixel; i++) {
Packit Service 2b1f13
Packit Service 2b1f13
	color.pixel = (unsigned long) i;
Packit Service 2b1f13
	color.red = (unsigned short)
Packit Service 2b1f13
	    (((i/colormap->red_mult) * 65535) / colormap->red_max);
Packit Service 2b1f13
Packit Service 2b1f13
	if (vinfo->class == StaticColor) {
Packit Service 2b1f13
	    color.green = (unsigned short)
Packit Service 2b1f13
		((((i/colormap->green_mult) % (colormap->green_max + 1)) *
Packit Service 2b1f13
		  65535) / colormap->green_max);
Packit Service 2b1f13
	    color.blue = (unsigned short)
Packit Service 2b1f13
		(((i%colormap->green_mult) * 65535) / colormap->blue_max);
Packit Service 2b1f13
	}
Packit Service 2b1f13
	else	/* vinfo->class == GrayScale, old style allocation XXX */
Packit Service 2b1f13
	    color.green = color.blue = color.red;
Packit Service 2b1f13
Packit Service 2b1f13
	XAllocColor(dpy, colormap->colormap, &color;;
Packit Service 2b1f13
	if (color.pixel != (unsigned long) i)
Packit Service 2b1f13
	    return 0;
Packit Service 2b1f13
    }
Packit Service 2b1f13
    return 1;
Packit Service 2b1f13
}