Change to the linux kernel coding style
[wmaker-crm.git] / wrlib / CrCmap.c
dissimilarity index 79%
index 9ac102f..fca9d34 100644 (file)
-/* $XConsortium: CrCmap.c,v 1.6 94/04/17 20:15:53 rws Exp $ */
-
-/*
-
-Copyright (c) 1989  X Consortium
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the X Consortium shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from the X Consortium.
-
-*/
-
-/*
- * Author:  Donna Converse, MIT X Consortium
- */
-
-/*
- * CreateCmap.c - given a standard colormap description, make the map.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-
-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().
- *
- * 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)
-    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.
-                                         */
-{
-    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;
-
-    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.
-     */
-    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 = vinfo;
-
-            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 ||
-        vinfo->class == GrayScale)
-        status = readwrite_map(dpy, vinfo, colormap);
-    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
-        status = readonly_map(dpy, vinfo, colormap);
-
-    XFree((char *) vpointer);
-    return status;
-}
-
-/****************************************************************************/
-static Status readwrite_map(dpy, vinfo, colormap)
-    Display            *dpy;
-    XVisualInfo                *vinfo;
-    XStandardColormap  *colormap;
-{
-    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);
-    } else {
-        ncolors = colormap->red_max * colormap->red_mult +
-            colormap->green_max * colormap->green_mult +
-            colormap->blue_max * colormap->blue_mult + 1;
-        delta = 1;
-    }
-    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))
-    {
-        /* 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)
-    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 */
-    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;
-    while (count < ncolors && ncolors - count <= *rem)
-    {
-        if (pixels[i-1] + delta == pixels[i])
-            count++;
-        else {
-            count = 1;
-            *first = i;
-        }
-        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;
-}
-
+/* $XConsortium: CrCmap.c,v 1.6 94/04/17 20:15:53 rws Exp $ */
+
+/*
+
+Copyright (c) 1989  X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+*/
+
+/*
+ * Author:  Donna Converse, MIT X Consortium
+ */
+
+/*
+ * CreateCmap.c - given a standard colormap description, make the map.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+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().
+ *
+ * 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)
+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.
+                                */
+{
+       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;
+
+       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.
+        */
+       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 = vinfo;
+
+                       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 || vinfo->class == GrayScale)
+               status = readwrite_map(dpy, vinfo, colormap);
+       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
+               status = readonly_map(dpy, vinfo, colormap);
+
+       XFree((char *)vpointer);
+       return status;
+}
+
+/****************************************************************************/
+static Status readwrite_map(dpy, vinfo, colormap)
+Display *dpy;
+XVisualInfo *vinfo;
+XStandardColormap *colormap;
+{
+       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);
+       } else {
+               ncolors = colormap->red_max * colormap->red_mult +
+                   colormap->green_max * colormap->green_mult + colormap->blue_max * colormap->blue_mult + 1;
+               delta = 1;
+       }
+       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)) {
+               /* 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)
+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 */
+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;
+       while (count < ncolors && ncolors - count <= *rem) {
+               if (pixels[i - 1] + delta == pixels[i])
+                       count++;
+               else {
+                       count = 1;
+                       *first = i;
+               }
+               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;
+}