xstdcmap.c revision 8440cca4
1/* 2 * $Xorg: xstdcmap.c,v 1.5 2001/02/09 02:06:01 xorgcvs Exp $ 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 * Author: Donna Converse, MIT X Consortium 28 */ 29/* $XFree86: xc/programs/xstdcmap/xstdcmap.c,v 1.8tsi Exp $ */ 30 31#include <stdio.h> 32#include <stdlib.h> 33#include <X11/Xos.h> 34#include <X11/Xlib.h> 35#include <X11/Xutil.h> 36#include <X11/Xresource.h> 37#include <X11/Xatom.h> 38#include <X11/Xmu/StdCmap.h> 39 40#define REPLACE 1 41#define DO_NOT_REPLACE 0 42#define RETAIN 1 43#define DO_NOT_RETAIN 0 44 45static char *display_name = NULL; 46static char *program_name = NULL; 47static Bool all = 0; 48static Bool help = 0; 49static Bool verbose = 0; 50static Display *dpy = NULL; 51 52typedef struct 53{ 54 Bool create; 55 Bool delete; 56 Atom property; 57 char *name; 58 char *nickname; 59} colormap_property; 60 61static colormap_property propertyTable[]= 62{ 63{0, 0, XA_RGB_DEFAULT_MAP, "RGB_DEFAULT_MAP", "default"}, 64{0, 0, XA_RGB_BEST_MAP, "RGB_BEST_MAP", "best"}, 65{0, 0, XA_RGB_GRAY_MAP, "RGB_GRAY_MAP", "gray"}, 66{0, 0, XA_RGB_RED_MAP, "RGB_RED_MAP", "red"}, 67{0, 0, XA_RGB_GREEN_MAP, "RGB_GREEN_MAP", "green"}, 68{0, 0, XA_RGB_BLUE_MAP, "RGB_BLUE_MAP", "blue"}, 69}; 70#define NPROPERTIES (sizeof propertyTable / sizeof propertyTable[0]) 71 72#define DEFAULT 0 73#define BEST 1 74#define GRAY 2 75#define RED 3 76#define GREEN 4 77#define BLUE 5 78 79static char *usage_message[]= 80{ 81" -all make all standard colormaps for the display", 82" -best make the RGB_BEST_MAP", 83" -blue make the RGB_BLUE_MAP", 84" -default make the RGB_DEFAULT_MAP", 85" -delete name remove a standard colormap", 86" -display dpy X server to use", 87" -gray make the RGB_GRAY_MAP", 88" -green make the RGB_GREEN_MAP", 89" -red make the RGB_RED_MAP", 90" -verbose turn on logging", 91"", 92NULL }; 93 94static XrmOptionDescRec optionTable[]= 95{ 96{"-all", ".all", XrmoptionNoArg, (caddr_t) "on"}, 97{"-best", ".best", XrmoptionNoArg, (caddr_t) "on"}, 98{"-blue", ".blue", XrmoptionNoArg, (caddr_t) "on"}, 99{"-default", ".default", XrmoptionNoArg, (caddr_t) "on"}, 100{"-delete", ".delete", XrmoptionSepArg, (caddr_t) NULL}, 101{"-display", ".display", XrmoptionSepArg, (caddr_t) NULL}, 102{"-gray", ".gray", XrmoptionNoArg, (caddr_t) "on"}, 103{"-green", ".green", XrmoptionNoArg, (caddr_t) "on"}, 104{"-help", ".help", XrmoptionNoArg, (caddr_t) "on"}, 105{"-red", ".red", XrmoptionNoArg, (caddr_t) "on"}, 106{"-verbose", ".verbose", XrmoptionNoArg, (caddr_t) "on"}, 107}; 108#define NOPTIONS (sizeof optionTable / sizeof optionTable[0]) 109 110static void usage(Status status); 111 112static void 113parse(int argc, char **argv) 114{ 115 XrmDatabase database = NULL; 116 char *type; 117 XrmValue value; 118 char option[512]; 119 120 if (argc == 1) 121 usage(0); 122 123 XrmInitialize(); 124 XrmParseCommand(&database, optionTable, NOPTIONS, program_name, &argc, 125 argv); 126 if (--argc) 127 usage(1); 128 129 (void) sprintf(option, "%s%s", program_name, ".all"); 130 if (XrmGetResource(database, option, (char *) NULL, &type, &value)) 131 all++; 132 133 (void) sprintf(option, "%s%s", program_name, ".best"); 134 if (XrmGetResource(database, option, (char *) NULL, &type, &value)) 135 propertyTable[BEST].create++; 136 137 (void) sprintf(option, "%s%s", program_name, ".blue"); 138 if (XrmGetResource(database, option, (char *) NULL, &type, &value)) 139 propertyTable[BLUE].create++; 140 141 (void) sprintf(option, "%s%s", program_name, ".default"); 142 if (XrmGetResource(database, option, (char *) NULL, &type, &value)) 143 propertyTable[DEFAULT].create++; 144 145 (void) sprintf(option, "%s%s", program_name, ".delete"); 146 if (XrmGetResource(database, option, (char *) NULL, &type, &value)) { 147 register int i; 148 for (i=0; i < NPROPERTIES; i++) { 149 if (strcmp((char *) value.addr, propertyTable[i].nickname) == 0) { 150 propertyTable[i].delete++; 151 break; 152 } 153 if (strcmp((char *) value.addr, "all") == 0) 154 propertyTable[i].delete++; 155 } 156 } 157 158 (void) sprintf(option, "%s%s", program_name, ".display"); 159 if (XrmGetResource(database, option, (char *) NULL, &type, &value)) 160 display_name = value.addr; 161 162 (void) sprintf(option, "%s%s", program_name, ".gray"); 163 if (XrmGetResource(database, option, (char *) NULL, &type, &value)) 164 propertyTable[GRAY].create++; 165 166 (void) sprintf(option, "%s%s", program_name, ".green"); 167 if (XrmGetResource(database, option, (char *) NULL, &type, &value)) 168 propertyTable[GREEN].create++; 169 170 (void) sprintf(option, "%s%s", program_name, ".help"); 171 if (XrmGetResource(database, option, (char *) NULL, &type, &value)) 172 help++; 173 174 (void) sprintf(option, "%s%s", program_name, ".red"); 175 if (XrmGetResource(database, option, (char *) NULL, &type, &value)) 176 propertyTable[RED].create++; 177 178 (void) sprintf(option, "%s%s", program_name, ".verbose"); 179 if (XrmGetResource(database, option, (char *) NULL, &type, &value)) 180 verbose++; 181} 182 183static void 184Exit(Status status) 185{ 186 if (dpy) 187 XCloseDisplay(dpy); 188 exit(status); 189} 190 191static void 192usage(Status status) 193{ 194 register char **i; 195 (void) fprintf(stderr, "usage: %s [-options]\n\n", program_name); 196 (void) fprintf(stderr, "where options include:\n"); 197 for (i = usage_message; *i != NULL; i++) 198 (void) fprintf(stderr, "%s\n", *i); 199 Exit(status); 200} 201 202/* Determine the visual of greatest depth in a given visual class. 203 * If no such visual exists, return NULL. 204 */ 205static XVisualInfo * 206getDeepestVisual(int visual_class, /* specifies the desired visual class */ 207 XVisualInfo *vinfo, /* specifies all visuals for a screen */ 208 int nvisuals) /* specifies number of visuals in the list */ 209{ 210 register int i; 211 unsigned int maxdepth = 0; 212 XVisualInfo *v = NULL; 213 214 for (i=0; i < nvisuals; i++, vinfo++) 215 if (vinfo->class == visual_class && vinfo->depth > maxdepth) 216 { 217 maxdepth = vinfo->depth; 218 v = vinfo; 219 } 220 return(v); 221} 222 223/* Determine the ``best'' visual of the screen for a standard colormap 224 * property. Return NULL if no visual is appropriate. 225 */ 226static XVisualInfo * 227getBestVisual(Atom property, /* specifies the standard colormap */ 228 XVisualInfo *vinfo, /* specifies all visuals of the screen */ 229 int nvisuals) /* specifies number of visuals of screen */ 230{ 231 XVisualInfo *v1 = NULL, *v2 = NULL; 232 233 if (vinfo == NULL) /* unexpected: a screen with no visuals */ 234 return v1; 235 v1 = getDeepestVisual(DirectColor, vinfo, nvisuals); 236 v2 = getDeepestVisual(PseudoColor, vinfo, nvisuals); 237 if (v2 && (!v1 || (v2->colormap_size >= 238 ((v1->red_mask | v1->green_mask | v1->blue_mask) + 1)))) 239 return v2; 240 else if (v1) 241 return v1; 242 if (property == XA_RGB_BEST_MAP) 243 if (((v1 = getDeepestVisual(TrueColor, vinfo, nvisuals)) != NULL) || 244 ((v1 = getDeepestVisual(StaticColor, vinfo, nvisuals)) != NULL)) 245 return v1; 246 if (property == XA_RGB_GRAY_MAP) 247 if (((v1 = getDeepestVisual(GrayScale, vinfo, nvisuals)) != NULL) || 248 ((v1 = getDeepestVisual(StaticGray, vinfo, nvisuals)) != NULL)) 249 return v1; 250 if (property == XA_RGB_DEFAULT_MAP) 251 for (v1 = vinfo; v1->visual != DefaultVisual(dpy, v1->screen); v1++) 252 ; 253 return v1; 254 255} 256 257static char * 258visualStringFromClass(int class) 259{ 260 switch (class) { 261 case PseudoColor: return "PseudoColor"; 262 case DirectColor: return "DirectColor"; 263 case GrayScale: return "GrayScale"; 264 case StaticColor: return "StaticColor"; 265 case TrueColor: return "TrueColor"; 266 case StaticGray: return "StaticGray"; 267 } 268 return "unknown visual class"; 269} 270 271static int 272doIndividualColormaps(void) 273{ 274 int i, screen, nvisuals; 275 Status status = -1; 276 XVisualInfo *vinfo = NULL, *v = NULL, template; 277 278 screen = DefaultScreen(dpy); 279 template.screen = screen; 280 vinfo = XGetVisualInfo(dpy, VisualScreenMask, &template, &nvisuals); 281 282 /* check for individual standard colormap requests */ 283 for (i=0; i < NPROPERTIES; i++) { 284 285 if (propertyTable[i].delete) { 286 XmuDeleteStandardColormap(dpy, screen, propertyTable[i].property); 287 if (verbose) 288 fprintf(stderr, "%s: %s was deleted or did not exist.\n", 289 program_name, propertyTable[i].name); 290 } 291 292 if (! propertyTable[i].create) 293 continue; 294 295 /* which visual is best for this property? */ 296 v = getBestVisual(propertyTable[i].property, vinfo, nvisuals); 297 if (v == NULL) { 298 if (verbose) 299 (void) fprintf(stderr, 300 "%s: no visual appropriate for %s on screen %d.\n", 301 program_name, propertyTable[i].name, screen); 302 continue; 303 } 304 305 306 if (verbose) 307 (void) fprintf(stderr, 308 "%s: making %s on a %s visual of depth %u.\n", 309 program_name, propertyTable[i].name, 310 visualStringFromClass(v->class), v->depth); 311 312 status = XmuLookupStandardColormap(dpy, screen, v->visualid, 313 v->depth, 314 propertyTable[i].property, 315 DO_NOT_REPLACE, RETAIN); 316 if (verbose) 317 (void) fprintf(stderr, 318 "%s: %s standard colormap %s.\n", program_name, 319 propertyTable[i].name, (status) 320 ? "was created or already exists" 321 : "cannot be defined"); 322 if (!status) 323 break; 324 } 325 XFree((char *) vinfo); 326 return status; 327} 328 329/* Bare bones standard colormap generation utility */ 330int 331main(int argc, char *argv[]) 332{ 333 Status status = 0; 334 335 if ((program_name = strrchr(*argv, '/'))) 336 program_name++; 337 else 338 program_name = *argv; 339 340 parse(argc, argv); 341 342 if ((dpy = XOpenDisplay(display_name)) == NULL) { 343 (void) fprintf(stderr, "%s: cannot open display \"%s\".\n", 344 program_name, XDisplayName(display_name)); 345 exit(1); 346 } 347 348 if (help) { 349 usage(0); 350 Exit(0); 351 352 /* Muffle gcc */ 353 return 0; 354 } 355 356 if (all) { 357 if (verbose) 358 (void) fprintf(stderr, 359 "%s: making all appropriate standard colormaps...", 360 program_name); 361 status = XmuAllStandardColormaps(dpy); 362 if (verbose) 363 (void) fprintf(stderr, 364 "\n%s!\n", (status) ? "success" : "failure"); 365 } 366 else { 367 status = doIndividualColormaps(); 368 if (!status && verbose) 369 (void) fprintf(stderr, 370 "Not all new colormap definitions will be retained.\n"); 371 } 372 Exit((status == 0) ? 1 : 0); 373 /* Muffle compiler */ 374 return 0; 375} 376