StdCmap.c revision 6c321187
1/* $Xorg: StdCmap.c,v 1.4 2001/02/09 02:03:53 xorgcvs Exp $ */ 2 3/* 4 5Copyright 1989, 1998 The Open Group 6 7Permission to use, copy, modify, distribute, and sell this software and its 8documentation for any purpose is hereby granted without fee, provided that 9the above copyright notice appear in all copies and that both that 10copyright notice and this permission notice appear in supporting 11documentation. 12 13The above copyright notice and this permission notice shall be included in 14all copies or substantial portions of the Software. 15 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 23Except as contained in this notice, the name of The Open Group shall not be 24used in advertising or otherwise to promote the sale, use or other dealings 25in this Software without prior written authorization from The Open Group. 26 27*/ 28/* $XFree86: xc/lib/Xmu/StdCmap.c,v 1.5 2001/01/17 19:42:56 dawes Exp $ */ 29 30/* 31 * Author: Donna Converse, MIT X Consortium 32 */ 33 34#ifdef HAVE_CONFIG_H 35#include <config.h> 36#endif 37#include <stdio.h> 38#include <X11/Xlib.h> 39#include <X11/Xatom.h> 40#include <X11/Xutil.h> 41#include <X11/Xmu/StdCmap.h> 42 43#define lowbit(x) ((x) & (~(x) + 1)) 44 45/* 46 * Prototypes 47 */ 48/* argument restrictions */ 49static Status valid_args(XVisualInfo*, unsigned long, unsigned long, 50 unsigned long, Atom); 51 52/* 53 * To create any one standard colormap, use XmuStandardColormap(). 54 * 55 * Create a standard colormap for the given screen, visualid, and visual 56 * depth, with the given red, green, and blue maximum values, with the 57 * given standard property name. Return a pointer to an XStandardColormap 58 * structure which describes the newly created colormap, upon success. 59 * Upon failure, return NULL. 60 * 61 * XmuStandardColormap() calls XmuCreateColormap() to create the map. 62 * 63 * Resources created by this function are not made permanent; that is the 64 * caller's responsibility. 65 */ 66 67XStandardColormap * 68XmuStandardColormap(Display *dpy, int screen, VisualID visualid, 69 unsigned int depth, Atom property, Colormap cmap, 70 unsigned long red_max, unsigned long green_max, 71 unsigned long blue_max) 72 /* 73 * dpy - specifies X server connection 74 * screen - specifies display screen 75 * visualid - identifies the visual type 76 * depth - identifies the visual type 77 * property - a standard colormap property 78 * cmap - specifies colormap ID or None 79 * red_max, green_max, blue_max - allocations 80 */ 81{ 82 XStandardColormap *stdcmap; 83 Status status; 84 XVisualInfo vinfo_template, *vinfo; 85 long vinfo_mask; 86 int n; 87 88 /* Match the required visual information to an actual visual */ 89 vinfo_template.visualid = visualid; 90 vinfo_template.screen = screen; 91 vinfo_template.depth = depth; 92 vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask; 93 if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL) 94 return NULL; 95 96 /* Check the validity of the combination of visual characteristics, 97 * allocation, and colormap property. Create an XStandardColormap 98 * structure. 99 */ 100 101 if (! valid_args(vinfo, red_max, green_max, blue_max, property) 102 || ((stdcmap = XAllocStandardColormap()) == NULL)) { 103 XFree((char *) vinfo); 104 return NULL; 105 } 106 107 /* Fill in the XStandardColormap structure */ 108 109 if (cmap == DefaultColormap(dpy, screen)) { 110 /* Allocating out of the default map, cannot use XFreeColormap() */ 111 Window win = XCreateWindow(dpy, RootWindow(dpy, screen), 1, 1, 1, 1, 112 0, 0, InputOnly, vinfo->visual, 113 (unsigned long) 0, 114 (XSetWindowAttributes *)NULL); 115 stdcmap->killid = (XID) XCreatePixmap(dpy, win, 1, 1, depth); 116 XDestroyWindow(dpy, win); 117 stdcmap->colormap = cmap; 118 } else { 119 stdcmap->killid = ReleaseByFreeingColormap; 120 stdcmap->colormap = XCreateColormap(dpy, RootWindow(dpy, screen), 121 vinfo->visual, AllocNone); 122 } 123 stdcmap->red_max = red_max; 124 stdcmap->green_max = green_max; 125 stdcmap->blue_max = blue_max; 126 if (property == XA_RGB_GRAY_MAP) 127 stdcmap->red_mult = stdcmap->green_mult = stdcmap->blue_mult = 1; 128 else if (vinfo->class == TrueColor || vinfo->class == DirectColor) { 129 stdcmap->red_mult = lowbit(vinfo->red_mask); 130 stdcmap->green_mult = lowbit(vinfo->green_mask); 131 stdcmap->blue_mult = lowbit(vinfo->blue_mask); 132 } else { 133 stdcmap->red_mult = (red_max > 0) 134 ? (green_max + 1) * (blue_max + 1) : 0; 135 stdcmap->green_mult = (green_max > 0) ? blue_max + 1 : 0; 136 stdcmap->blue_mult = (blue_max > 0) ? 1 : 0; 137 } 138 stdcmap->base_pixel = 0; /* base pixel may change */ 139 stdcmap->visualid = vinfo->visualid; 140 141 /* Make the colormap */ 142 143 status = XmuCreateColormap(dpy, stdcmap); 144 145 /* Clean up */ 146 147 XFree((char *) vinfo); 148 if (!status) { 149 150 /* Free the colormap or the pixmap, if we created one */ 151 if (stdcmap->killid == ReleaseByFreeingColormap) 152 XFreeColormap(dpy, stdcmap->colormap); 153 else if (stdcmap->killid != None) 154 XFreePixmap(dpy, stdcmap->killid); 155 156 XFree((char *) stdcmap); 157 return (XStandardColormap *) NULL; 158 } 159 return stdcmap; 160} 161 162/****************************************************************************/ 163static Status 164valid_args(XVisualInfo *vinfo, unsigned long red_max, unsigned long green_max, 165 unsigned long blue_max, Atom property) 166 /* 167 * vinfo - specifies visual 168 * red_max, green_max, blue_max - specifies alloc 169 * property - specifies property name 170 */ 171{ 172 unsigned long ncolors; /* number of colors requested */ 173 174 /* Determine that the number of colors requested is <= map size */ 175 176 if ((vinfo->class == DirectColor) || (vinfo->class == TrueColor)) { 177 unsigned long mask; 178 179 mask = vinfo->red_mask; 180 while (!(mask & 1)) 181 mask >>= 1; 182 if (red_max > mask) 183 return 0; 184 mask = vinfo->green_mask; 185 while (!(mask & 1)) 186 mask >>= 1; 187 if (green_max > mask) 188 return 0; 189 mask = vinfo->blue_mask; 190 while (!(mask & 1)) 191 mask >>= 1; 192 if (blue_max > mask) 193 return 0; 194 } else if (property == XA_RGB_GRAY_MAP) { 195 ncolors = red_max + green_max + blue_max + 1; 196 if (ncolors > vinfo->colormap_size) 197 return 0; 198 } else { 199 ncolors = (red_max + 1) * (green_max + 1) * (blue_max + 1); 200 if (ncolors > vinfo->colormap_size) 201 return 0; 202 } 203 204 /* Determine that the allocation and visual make sense for the property */ 205 206 switch (property) 207 { 208 case XA_RGB_DEFAULT_MAP: 209 if (red_max == 0 || green_max == 0 || blue_max == 0) 210 return 0; 211 break; 212 case XA_RGB_RED_MAP: 213 if (red_max == 0) 214 return 0; 215 break; 216 case XA_RGB_GREEN_MAP: 217 if (green_max == 0) 218 return 0; 219 break; 220 case XA_RGB_BLUE_MAP: 221 if (blue_max == 0) 222 return 0; 223 break; 224 case XA_RGB_BEST_MAP: 225 if (red_max == 0 || green_max == 0 || blue_max == 0) 226 return 0; 227 break; 228 case XA_RGB_GRAY_MAP: 229 if (red_max == 0 || blue_max == 0 || green_max == 0) 230 return 0; 231 break; 232 default: 233 return 0; 234 } 235 return 1; 236} 237