10cc2eac3Smrg/* 26c321187Smrg 36c321187SmrgCopyright 1989, 1998 The Open Group 46c321187Smrg 56c321187SmrgPermission to use, copy, modify, distribute, and sell this software and its 66c321187Smrgdocumentation for any purpose is hereby granted without fee, provided that 76c321187Smrgthe above copyright notice appear in all copies and that both that 86c321187Smrgcopyright notice and this permission notice appear in supporting 96c321187Smrgdocumentation. 106c321187Smrg 116c321187SmrgThe above copyright notice and this permission notice shall be included in 126c321187Smrgall copies or substantial portions of the Software. 136c321187Smrg 146c321187SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 156c321187SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 166c321187SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 176c321187SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 186c321187SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 196c321187SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 206c321187Smrg 216c321187SmrgExcept as contained in this notice, the name of The Open Group shall not be 226c321187Smrgused in advertising or otherwise to promote the sale, use or other dealings 236c321187Smrgin this Software without prior written authorization from The Open Group. 246c321187Smrg 256c321187Smrg*/ 266c321187Smrg 276c321187Smrg/* 286c321187Smrg * Author: Donna Converse, MIT X Consortium 296c321187Smrg */ 306c321187Smrg 316c321187Smrg/* 326c321187Smrg * CreateCmap.c - given a standard colormap description, make the map. 336c321187Smrg */ 346c321187Smrg 356c321187Smrg#ifdef HAVE_CONFIG_H 366c321187Smrg#include <config.h> 376c321187Smrg#endif 386c321187Smrg#include <stdio.h> 396c321187Smrg#include <stdlib.h> 406c321187Smrg#include <X11/Xlib.h> 416c321187Smrg#include <X11/Xutil.h> 426c321187Smrg#include <X11/Xmu/StdCmap.h> 436c321187Smrg 446c321187Smrg/* 456c321187Smrg * Prototypes 466c321187Smrg */ 476c321187Smrg/* allocate entire map Read Only */ 486c321187Smrgstatic int ROmap(Display*, Colormap, unsigned long[], int, int); 496c321187Smrg 506c321187Smrg/* allocate a cell, prefer Read Only */ 516c321187Smrgstatic Status ROorRWcell(Display*, Colormap, unsigned long[], int, 526c321187Smrg XColor*, unsigned long); 536c321187Smrg 546c321187Smrg/* allocate a cell Read Write */ 556c321187Smrgstatic Status RWcell(Display*, Colormap, XColor*, XColor*, unsigned long*); 566c321187Smrg 576c321187Smrg/* for quicksort */ 586c321187Smrgstatic int compare(_Xconst void*, _Xconst void*); 596c321187Smrg 606c321187Smrg/* find contiguous sequence of cells */ 616c321187Smrgstatic Status contiguous(unsigned long[], int, int, unsigned long, int*, int*); 626c321187Smrg 636c321187Smrg/* frees resources before quitting */ 646c321187Smrgstatic void free_cells(Display*, Colormap, unsigned long[], int, int); 656c321187Smrg 666c321187Smrg/* create a map in a RO visual type */ 676c321187Smrgstatic Status readonly_map(Display*, XVisualInfo*, XStandardColormap*); 686c321187Smrg 696c321187Smrg/* create a map in a RW visual type */ 706c321187Smrgstatic Status readwrite_map(Display*, XVisualInfo*, XStandardColormap*); 716c321187Smrg 726c321187Smrg#define lowbit(x) ((x) & (~(x) + 1)) 736c321187Smrg#define TRUEMATCH(mult,max,mask) \ 746c321187Smrg (colormap->max * colormap->mult <= vinfo->mask && \ 756c321187Smrg lowbit(vinfo->mask) == colormap->mult) 766c321187Smrg 776c321187Smrg/* 786c321187Smrg * To create any one colormap which is described by an XStandardColormap 796c321187Smrg * structure, use XmuCreateColormap(). 806c321187Smrg * 816c321187Smrg * Return 0 on failure, non-zero on success. 826c321187Smrg * Resources created by this function are not made permanent. 836c321187Smrg * No argument error checking is provided. Use at your own risk. 846c321187Smrg * 856c321187Smrg * All colormaps are created with read only allocations, with the exception 866c321187Smrg * of read only allocations of colors in the default map or otherwise 870cc2eac3Smrg * which fail to return the expected pixel value, and these are individually 886c321187Smrg * defined as read/write allocations. This is done so that all the cells 896c321187Smrg * defined in the default map are contiguous, for use in image processing. 906c321187Smrg * This typically happens with White and Black in the default map. 916c321187Smrg * 926c321187Smrg * Colormaps of static visuals are considered to be successfully created if 936c321187Smrg * the map of the static visual matches the definition given in the 946c321187Smrg * standard colormap structure. 956c321187Smrg */ 960cc2eac3Smrg 976c321187SmrgStatus 986c321187SmrgXmuCreateColormap(Display *dpy, XStandardColormap *colormap) 996c321187Smrg /* dpy - specifies the connection under which the map is created 1006c321187Smrg * colormap - specifies the map to be created, and returns, particularly 1016c321187Smrg * if the map is created as a subset of the default colormap 1026c321187Smrg * of the screen, the base_pixel of the map. 1036c321187Smrg */ 1046c321187Smrg{ 1056c321187Smrg XVisualInfo vinfo_template; /* template visual information */ 1066c321187Smrg XVisualInfo *vinfo; /* matching visual information */ 1076c321187Smrg XVisualInfo *vpointer; /* for freeing the entire list */ 1086c321187Smrg long vinfo_mask; /* specifies the visual mask value */ 1096c321187Smrg int n; /* number of matching visuals */ 1100cc2eac3Smrg int status; 1116c321187Smrg 1126c321187Smrg vinfo_template.visualid = colormap->visualid; 1136c321187Smrg vinfo_mask = VisualIDMask; 1146c321187Smrg if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL) 1156c321187Smrg return 0; 1166c321187Smrg 1170cc2eac3Smrg /* A visual id may be valid on multiple screens. Also, there may 1180cc2eac3Smrg * be multiple visuals with identical visual ids at different depths. 1196c321187Smrg * If the colormap is the Default Colormap, use the Default Visual. 1206c321187Smrg * Otherwise, arbitrarily, use the deepest visual. 1216c321187Smrg */ 1226c321187Smrg vpointer = vinfo; 1236c321187Smrg if (n > 1) 1246c321187Smrg { 1256c321187Smrg register int i; 1266c321187Smrg register int screen_number; 1276c321187Smrg Bool def_cmap; 1286c321187Smrg 1296c321187Smrg def_cmap = False; 1306c321187Smrg for (screen_number = ScreenCount(dpy); --screen_number >= 0; ) 1316c321187Smrg if (colormap->colormap == DefaultColormap(dpy, screen_number)) { 1326c321187Smrg def_cmap = True; 1336c321187Smrg break; 1346c321187Smrg } 1356c321187Smrg 1366c321187Smrg if (def_cmap) { 1376c321187Smrg for (i=0; i < n; i++, vinfo++) { 1386c321187Smrg if (vinfo->visual == DefaultVisual(dpy, screen_number)) 1396c321187Smrg break; 1406c321187Smrg } 1416c321187Smrg } else { 1426c321187Smrg int maxdepth = 0; 1436c321187Smrg XVisualInfo *v = NULL; 1446c321187Smrg 1456c321187Smrg for (i=0; i < n; i++, vinfo++) 1466c321187Smrg if (vinfo->depth > maxdepth) { 1476c321187Smrg maxdepth = vinfo->depth; 1486c321187Smrg v = vinfo; 1496c321187Smrg } 1506c321187Smrg vinfo = v; 1516c321187Smrg } 1526c321187Smrg } 1536c321187Smrg 1546c321187Smrg if (vinfo->class == PseudoColor || vinfo->class == DirectColor || 1556c321187Smrg vinfo->class == GrayScale) 1566c321187Smrg status = readwrite_map(dpy, vinfo, colormap); 1576c321187Smrg else if (vinfo->class == TrueColor) 1586c321187Smrg status = TRUEMATCH(red_mult, red_max, red_mask) && 1596c321187Smrg TRUEMATCH(green_mult, green_max, green_mask) && 1606c321187Smrg TRUEMATCH(blue_mult, blue_max, blue_mask); 1610cc2eac3Smrg else 1626c321187Smrg status = readonly_map(dpy, vinfo, colormap); 1630cc2eac3Smrg 1646c321187Smrg XFree((char *) vpointer); 1656c321187Smrg return status; 1666c321187Smrg} 1676c321187Smrg 1686c321187Smrg/****************************************************************************/ 1696c321187Smrgstatic Status 1706c321187Smrgreadwrite_map(Display *dpy, XVisualInfo *vinfo, XStandardColormap *colormap) 1716c321187Smrg{ 1726c321187Smrg register unsigned long i, n; /* index counters */ 1736c321187Smrg unsigned long ncolors; /* number of colors to be defined */ 1746c321187Smrg int npixels; /* number of pixels allocated R/W */ 1756c321187Smrg int first_index; /* first index of pixels to use */ 1766c321187Smrg int remainder; /* first index of remainder */ 1776c321187Smrg XColor color; /* the definition of a color */ 1786c321187Smrg unsigned long *pixels; /* array of colormap pixels */ 1796c321187Smrg unsigned long delta; 1806c321187Smrg 1810cc2eac3Smrg 1826c321187Smrg /* Determine ncolors, the number of colors to be defined. 1836c321187Smrg * Insure that 1 < ncolors <= the colormap size. 1846c321187Smrg */ 1856c321187Smrg if (vinfo->class == DirectColor) { 1866c321187Smrg ncolors = colormap->red_max; 1876c321187Smrg if (colormap->green_max > ncolors) 1886c321187Smrg ncolors = colormap->green_max; 1896c321187Smrg if (colormap->blue_max > ncolors) 1906c321187Smrg ncolors = colormap->blue_max; 1916c321187Smrg ncolors++; 1926c321187Smrg delta = lowbit(vinfo->red_mask) + 1936c321187Smrg lowbit(vinfo->green_mask) + 1946c321187Smrg lowbit(vinfo->blue_mask); 1956c321187Smrg } else { 1966c321187Smrg ncolors = colormap->red_max * colormap->red_mult + 1976c321187Smrg colormap->green_max * colormap->green_mult + 1986c321187Smrg colormap->blue_max * colormap->blue_mult + 1; 1996c321187Smrg delta = 1; 2006c321187Smrg } 2016c321187Smrg if (ncolors <= 1 || (int) ncolors > vinfo->colormap_size) return 0; 2026c321187Smrg 2036c321187Smrg /* Allocate Read/Write as much of the colormap as we can possibly get. 2040cc2eac3Smrg * Then insure that the pixels we were allocated are given in 2056c321187Smrg * monotonically increasing order, using a quicksort. Next, insure 2066c321187Smrg * that our allocation includes a subset of contiguous pixels at least 2070cc2eac3Smrg * as long as the number of colors to be defined. Now we know that 2086c321187Smrg * these conditions are met: 2096c321187Smrg * 1) There are no free cells in the colormap. 2100cc2eac3Smrg * 2) We have a contiguous sequence of pixels, monotonically 2116c321187Smrg * increasing, of length >= the number of colors requested. 2126c321187Smrg * 2130cc2eac3Smrg * One cell at a time, we will free, compute the next color value, 2146c321187Smrg * then allocate read only. This takes a long time. 2156c321187Smrg * This is done to insure that cells are allocated read only in the 2166c321187Smrg * contiguous order which we prefer. If the server has a choice of 2176c321187Smrg * cells to grant to an allocation request, the server may give us any 2186c321187Smrg * cell, so that is why we do these slow gymnastics. 2196c321187Smrg */ 2206c321187Smrg 2219dedec0cSmrg if ((pixels = calloc((unsigned) vinfo->colormap_size, 2229dedec0cSmrg sizeof(unsigned long))) == NULL) 2236c321187Smrg return 0; 2246c321187Smrg 2256c321187Smrg if ((npixels = ROmap(dpy, colormap->colormap, pixels, 2266c321187Smrg vinfo->colormap_size, ncolors)) == 0) { 2279dedec0cSmrg free(pixels); 2286c321187Smrg return 0; 2296c321187Smrg } 2306c321187Smrg 2316c321187Smrg qsort((char *) pixels, npixels, sizeof(unsigned long), compare); 2326c321187Smrg 2336c321187Smrg if (!contiguous(pixels, npixels, ncolors, delta, &first_index, &remainder)) 2346c321187Smrg { 2356c321187Smrg /* can't find enough contiguous cells, give up */ 2366c321187Smrg XFreeColors(dpy, colormap->colormap, pixels, npixels, 2376c321187Smrg (unsigned long) 0); 2389dedec0cSmrg free(pixels); 2396c321187Smrg return 0; 2406c321187Smrg } 2416c321187Smrg colormap->base_pixel = pixels[first_index]; 2426c321187Smrg 2436c321187Smrg /* construct a gray map */ 2446c321187Smrg if (colormap->red_mult == 1 && colormap->green_mult == 1 && 2456c321187Smrg colormap->blue_mult == 1) 2466c321187Smrg for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta) 2476c321187Smrg { 2486c321187Smrg color.pixel = n; 2496c321187Smrg color.blue = color.green = color.red = 2506c321187Smrg (unsigned short) ((i * 65535) / (colormap->red_max + 2516c321187Smrg colormap->green_max + 2526c321187Smrg colormap->blue_max)); 2536c321187Smrg 2546c321187Smrg if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, 2556c321187Smrg first_index + i)) 2566c321187Smrg return 0; 2576c321187Smrg } 2586c321187Smrg 2596c321187Smrg /* construct a red ramp map */ 2606c321187Smrg else if (colormap->green_max == 0 && colormap->blue_max == 0) 2616c321187Smrg for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta) 2626c321187Smrg { 2636c321187Smrg color.pixel = n; 2646c321187Smrg color.red = (unsigned short) ((i * 65535) / colormap->red_max); 2656c321187Smrg color.green = color.blue = 0; 2666c321187Smrg 2676c321187Smrg if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, 2686c321187Smrg first_index + i)) 2696c321187Smrg return 0; 2706c321187Smrg } 2716c321187Smrg 2726c321187Smrg /* construct a green ramp map */ 2736c321187Smrg else if (colormap->red_max == 0 && colormap->blue_max == 0) 2746c321187Smrg for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta) 2756c321187Smrg { 2766c321187Smrg color.pixel = n; 2776c321187Smrg color.green = (unsigned short) ((i * 65535) / colormap->green_max); 2786c321187Smrg color.red = color.blue = 0; 2796c321187Smrg 2806c321187Smrg if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, 2816c321187Smrg first_index + i)) 2826c321187Smrg return 0; 2836c321187Smrg } 2846c321187Smrg 2856c321187Smrg /* construct a blue ramp map */ 2866c321187Smrg else if (colormap->red_max == 0 && colormap->green_max == 0) 2876c321187Smrg for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta) 2886c321187Smrg { 2896c321187Smrg color.pixel = n; 2906c321187Smrg color.blue = (unsigned short) ((i * 65535) / colormap->blue_max); 2916c321187Smrg color.red = color.green = 0; 2926c321187Smrg 2936c321187Smrg if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, 2946c321187Smrg first_index + i)) 2956c321187Smrg return 0; 2966c321187Smrg } 2976c321187Smrg 2986c321187Smrg /* construct a standard red green blue cube map */ 2996c321187Smrg else 3006c321187Smrg { 3016c321187Smrg#define calc(max,mult) (((n / colormap->mult) % \ 3026c321187Smrg (colormap->max + 1)) * 65535) / colormap->max 3036c321187Smrg 3046c321187Smrg for (n=0, i=0; i < ncolors; i++, n += delta) 3056c321187Smrg { 3066c321187Smrg color.pixel = n + colormap->base_pixel; 3076c321187Smrg color.red = calc(red_max, red_mult); 3086c321187Smrg color.green = calc(green_max, green_mult); 3096c321187Smrg color.blue = calc(blue_max, blue_mult); 3106c321187Smrg if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, 3116c321187Smrg first_index + i)) 3126c321187Smrg return 0; 3136c321187Smrg } 3146c321187Smrg#undef calc 3156c321187Smrg } 3166c321187Smrg /* We have a read-only map defined. Now free unused cells, 3179dedec0cSmrg * first those occurring before the contiguous sequence begins, 3186c321187Smrg * then any following the contiguous sequence. 3196c321187Smrg */ 3206c321187Smrg 3216c321187Smrg if (first_index) 3220cc2eac3Smrg XFreeColors(dpy, colormap->colormap, pixels, first_index, 3236c321187Smrg (unsigned long) 0); 3246c321187Smrg if (remainder) 3256c321187Smrg XFreeColors(dpy, colormap->colormap, 3266c321187Smrg &(pixels[first_index + ncolors]), remainder, 3276c321187Smrg (unsigned long) 0); 3286c321187Smrg 3299dedec0cSmrg free(pixels); 3306c321187Smrg return 1; 3316c321187Smrg} 3326c321187Smrg 3336c321187Smrg 3346c321187Smrg/****************************************************************************/ 3356c321187Smrgstatic int 3366c321187SmrgROmap(Display *dpy, Colormap cmap, unsigned long pixels[], int m, int n) 3376c321187Smrg /* 3386c321187Smrg * dpy - the X server connection 3396c321187Smrg * cmap - specifies colormap ID 3406c321187Smrg * pixels - returns pixel allocations 3416c321187Smrg * m - specifies colormap size 3426c321187Smrg * n - specifies number of colors 3436c321187Smrg */ 3446c321187Smrg{ 3456c321187Smrg register int p; 3466c321187Smrg 3476c321187Smrg /* first try to allocate the entire colormap */ 3480cc2eac3Smrg if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL, 3496c321187Smrg (unsigned) 0, pixels, (unsigned) m)) 3506c321187Smrg return m; 3516c321187Smrg 3526c321187Smrg /* Allocate all available cells in the colormap, using a binary 3536c321187Smrg * algorithm to discover how many cells we can allocate in the colormap. 3546c321187Smrg */ 3556c321187Smrg m--; 3566c321187Smrg while (n <= m) { 3576c321187Smrg p = n + ((m - n + 1) / 2); 3586c321187Smrg if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL, 3596c321187Smrg (unsigned) 0, pixels, (unsigned) p)) { 3606c321187Smrg if (p == m) 3616c321187Smrg return p; 3626c321187Smrg else { 3636c321187Smrg XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0); 3646c321187Smrg n = p; 3656c321187Smrg } 3666c321187Smrg } 3676c321187Smrg else 3686c321187Smrg m = p - 1; 3696c321187Smrg } 3706c321187Smrg return 0; 3716c321187Smrg} 3720cc2eac3Smrg 3736c321187Smrg 3746c321187Smrg/****************************************************************************/ 3756c321187Smrgstatic Status 3766c321187Smrgcontiguous(unsigned long pixels[], int npixels, int ncolors, 3776c321187Smrg unsigned long delta, int *first, int *rem) 3786c321187Smrg /* pixels - specifies allocated pixels 3796c321187Smrg * npixels - specifies count of alloc'd pixels 3806c321187Smrg * ncolors - specifies needed sequence length 3816c321187Smrg * delta - between pixels 3826c321187Smrg * first - returns first index of sequence 3836c321187Smrg * rem - returns first index after sequence, or 0, if none follow 3846c321187Smrg */ 3856c321187Smrg{ 3866c321187Smrg register int i = 1; /* walking index into the pixel array */ 3876c321187Smrg register int count = 1; /* length of sequence discovered so far */ 3886c321187Smrg 3896c321187Smrg *first = 0; 3906c321187Smrg if (npixels == ncolors) { 3916c321187Smrg *rem = 0; 3926c321187Smrg return 1; 3936c321187Smrg } 3946c321187Smrg *rem = npixels - 1; 3956c321187Smrg while (count < ncolors && ncolors - count <= *rem) 3966c321187Smrg { 3976c321187Smrg if (pixels[i-1] + delta == pixels[i]) 3986c321187Smrg count++; 3996c321187Smrg else { 4006c321187Smrg count = 1; 4016c321187Smrg *first = i; 4026c321187Smrg } 4036c321187Smrg i++; 4046c321187Smrg (*rem)--; 4056c321187Smrg } 4066c321187Smrg if (count != ncolors) 4076c321187Smrg return 0; 4086c321187Smrg return 1; 4096c321187Smrg} 4106c321187Smrg 4116c321187Smrg 4126c321187Smrg/****************************************************************************/ 4136c321187Smrgstatic Status 4146c321187SmrgROorRWcell(Display *dpy, Colormap cmap, unsigned long pixels[], 4156c321187Smrg int npixels, XColor *color, unsigned long p) 4166c321187Smrg{ 4176c321187Smrg unsigned long pixel; 4186c321187Smrg XColor request; 4196c321187Smrg 4206c321187Smrg /* Free the read/write allocation of one cell in the colormap. 4216c321187Smrg * Request a read only allocation of one cell in the colormap. 4226c321187Smrg * If the read only allocation cannot be granted, give up, because 4236c321187Smrg * there must be no free cells in the colormap. 4246c321187Smrg * If the read only allocation is granted, but gives us a cell which 4256c321187Smrg * is not the one that we just freed, it is probably the case that 4266c321187Smrg * we are trying allocate White or Black or some other color which 4270cc2eac3Smrg * already has a read-only allocation in the map. So we try to 4286c321187Smrg * allocate the previously freed cell with a read/write allocation, 4296c321187Smrg * because we want contiguous cells for image processing algorithms. 4306c321187Smrg */ 4310cc2eac3Smrg 4326c321187Smrg pixel = color->pixel; 4336c321187Smrg request.red = color->red; 4346c321187Smrg request.green = color->green; 4356c321187Smrg request.blue = color->blue; 4366c321187Smrg 4376c321187Smrg XFreeColors(dpy, cmap, &pixel, 1, (unsigned long) 0); 4380cc2eac3Smrg if (! XAllocColor(dpy, cmap, color) 4396c321187Smrg || (color->pixel != pixel && 4400cc2eac3Smrg (!RWcell(dpy, cmap, color, &request, &pixel)))) 4416c321187Smrg { 4426c321187Smrg free_cells(dpy, cmap, pixels, npixels, (int)p); 4436c321187Smrg return 0; 4446c321187Smrg } 4456c321187Smrg return 1; 4466c321187Smrg} 4476c321187Smrg 4486c321187Smrg 4496c321187Smrg/****************************************************************************/ 4506c321187Smrgstatic void 4516c321187Smrgfree_cells(Display *dpy, Colormap cmap, unsigned long pixels[], 4526c321187Smrg int npixels, int p) 4536c321187Smrg /* 4546c321187Smrg * pixels - to be freed 4556c321187Smrg * npixels - original number allocated 4566c321187Smrg */ 4576c321187Smrg{ 4586c321187Smrg /* One of the npixels allocated has already been freed. 4596c321187Smrg * p is the index of the freed pixel. 4609dedec0cSmrg * First free the pixels preceding p, and there are p of them; 4616c321187Smrg * then free the pixels following p, there are npixels - p - 1 of them. 4626c321187Smrg */ 4636c321187Smrg XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0); 4646c321187Smrg XFreeColors(dpy, cmap, &(pixels[p+1]), npixels - p - 1, (unsigned long) 0); 4659dedec0cSmrg free(pixels); 4666c321187Smrg} 4676c321187Smrg 4686c321187Smrg 4696c321187Smrg/****************************************************************************/ 4706c321187Smrgstatic Status 4716c321187SmrgRWcell(Display *dpy, Colormap cmap, XColor *color, XColor *request, 4726c321187Smrg unsigned long *pixel) 4736c321187Smrg{ 4746c321187Smrg unsigned long n = *pixel; 4756c321187Smrg 4766c321187Smrg XFreeColors(dpy, cmap, &(color->pixel), 1, (unsigned long)0); 4776c321187Smrg if (! XAllocColorCells(dpy, cmap, (Bool) 0, (unsigned long *) NULL, 4786c321187Smrg (unsigned) 0, pixel, (unsigned) 1)) 4796c321187Smrg return 0; 4806c321187Smrg if (*pixel != n) 4816c321187Smrg { 4826c321187Smrg XFreeColors(dpy, cmap, pixel, 1, (unsigned long) 0); 4836c321187Smrg return 0; 4846c321187Smrg } 4856c321187Smrg color->pixel = *pixel; 4866c321187Smrg color->flags = DoRed | DoGreen | DoBlue; 4876c321187Smrg color->red = request->red; 4886c321187Smrg color->green = request->green; 4896c321187Smrg color->blue = request->blue; 4906c321187Smrg XStoreColors(dpy, cmap, color, 1); 4916c321187Smrg return 1; 4926c321187Smrg} 4936c321187Smrg 4946c321187Smrg 4956c321187Smrg/****************************************************************************/ 4966c321187Smrgstatic int 4976c321187Smrgcompare(_Xconst void *e1, _Xconst void *e2) 4986c321187Smrg{ 4999d0b5e55Smrg return ((int)(*(_Xconst long *)e1 - *(_Xconst long *)e2)); 5006c321187Smrg} 5016c321187Smrg 5026c321187Smrg 5036c321187Smrg/****************************************************************************/ 5046c321187Smrgstatic Status 5056c321187Smrgreadonly_map(Display *dpy, XVisualInfo *vinfo, XStandardColormap *colormap) 5066c321187Smrg{ 5076c321187Smrg int i, last_pixel; 5086c321187Smrg XColor color; 5096c321187Smrg 5100cc2eac3Smrg last_pixel = (colormap->red_max + 1) * (colormap->green_max + 1) * 5116c321187Smrg (colormap->blue_max + 1) + colormap->base_pixel - 1; 5126c321187Smrg 5136c321187Smrg for(i=colormap->base_pixel; i <= last_pixel; i++) { 5146c321187Smrg 5156c321187Smrg color.pixel = (unsigned long) i; 5166c321187Smrg color.red = (unsigned short) 5176c321187Smrg (((i/colormap->red_mult) * 65535) / colormap->red_max); 5186c321187Smrg 5196c321187Smrg if (vinfo->class == StaticColor) { 5206c321187Smrg color.green = (unsigned short) 5216c321187Smrg ((((i/colormap->green_mult) % (colormap->green_max + 1)) * 5226c321187Smrg 65535) / colormap->green_max); 5236c321187Smrg color.blue = (unsigned short) 5246c321187Smrg (((i%colormap->green_mult) * 65535) / colormap->blue_max); 5256c321187Smrg } 5266c321187Smrg else /* vinfo->class == GrayScale, old style allocation XXX */ 5276c321187Smrg color.green = color.blue = color.red; 5286c321187Smrg 5296c321187Smrg XAllocColor(dpy, colormap->colormap, &color); 5306c321187Smrg if (color.pixel != (unsigned long) i) 5316c321187Smrg return 0; 5326c321187Smrg } 5336c321187Smrg return 1; 5346c321187Smrg} 535