xrefresh.c revision bded5d25
1/*********************************************************** 2 3Copyright 1987, 1988, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25 26Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 27 28 All Rights Reserved 29 30Permission to use, copy, modify, and distribute this software and its 31documentation for any purpose and without fee is hereby granted, 32provided that the above copyright notice appear in all copies and that 33both that copyright notice and this permission notice appear in 34supporting documentation, and that the name of Digital not be 35used in advertising or publicity pertaining to distribution of the 36software without specific, written prior permission. 37 38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 44SOFTWARE. 45 46******************************************************************/ 47 48/* 49 * Kitchen sink version, useful for clearing small areas and flashing the 50 * screen. 51 */ 52 53#include <stdio.h> 54#include <errno.h> 55#include <X11/Xos.h> 56#include <X11/Xlib.h> 57#include <X11/Xutil.h> 58#include <ctype.h> 59#include <stdlib.h> 60 61static Window win; 62 63static char *ProgramName; 64 65static void 66Syntax(void) 67{ 68 fprintf (stderr, "usage: %s [-options] [geometry] [display]\n\n", 69 ProgramName); 70 fprintf (stderr, "where the available options are:\n"); 71 fprintf (stderr, " -display host:dpy or -d\n"); 72 fprintf (stderr, " -geometry WxH+X+Y or -g spec\n"); 73 fprintf (stderr, " -black use BlackPixel\n"); 74 fprintf (stderr, " -white use WhitePixel\n"); 75 fprintf (stderr, " -solid colorname use the color indicated\n"); 76 fprintf (stderr, " -root use the root background\n"); 77 fprintf (stderr, " -none no background in window\n"); 78 fprintf (stderr, "\nThe default is: %s -none\n\n", ProgramName); 79 exit (1); 80} 81 82/* 83 * The following parses options that should be yes or no; it returns -1, 0, 1 84 * for error, no, yes. 85 */ 86 87static int 88parse_boolean_option(char *option) 89{ 90 static struct _booltable { 91 char *name; 92 int value; 93 } booltable[] = { 94 { "off", 0 }, { "n", 0 }, { "no", 0 }, { "false", 0 }, 95 { "on", 1 }, { "y", 1 }, { "yes", 1 }, { "true", 1 }, 96 { NULL, -1 }}; 97 register struct _booltable *t; 98 register char *cp; 99 100 for (cp = option; *cp; cp++) { 101 if (isascii (*cp) && isupper (*cp)) *cp = tolower (*cp); 102 } 103 104 for (t = booltable; t->name; t++) { 105 if (strcmp (option, t->name) == 0) return (t->value); 106 } 107 return (-1); 108} 109 110 111/* 112 * The following is a hack until XrmParseCommand is ready. It determines 113 * whether or not the given string is an abbreviation of the arg. 114 */ 115 116static Bool 117isabbreviation(char *arg, char *s, int minslen) 118{ 119 int arglen; 120 int slen; 121 122 /* exact match */ 123 if (strcmp (arg, s) == 0) return (True); 124 125 arglen = strlen (arg); 126 slen = strlen (s); 127 128 /* too long or too short */ 129 if (slen >= arglen || slen < minslen) return (False); 130 131 /* abbreviation */ 132 if (strncmp (arg, s, slen) == 0) return (True); 133 134 /* bad */ 135 return (False); 136} 137 138 139enum e_action {doDefault, doBlack, doWhite, doSolid, doNone, doRoot}; 140 141static struct s_pair { 142 char *resource_name; 143 enum e_action action; 144} pair_table[] = { 145 { "Black", doBlack }, 146 { "White", doWhite }, 147 { "None", doNone }, 148 { "Root", doRoot }, 149 { NULL, doDefault }}; 150 151int 152main(int argc, char *argv[]) 153{ 154 Visual visual; 155 XSetWindowAttributes xswa; 156 int i; 157 char *displayname = NULL; 158 Display *dpy; 159 Colormap cmap; 160 enum e_action action = doDefault; 161 unsigned long mask; 162 int screen; 163 int x, y, width, height; 164 char *geom = NULL; 165 int geom_result; 166 int display_width, display_height; 167 char *solidcolor = NULL; 168 XColor cdef; 169 170 ProgramName = argv[0]; 171 172 for (i = 1; i < argc; i++) { 173 char *arg = argv[i]; 174 175 if (arg[0] == '-') { 176 if (isabbreviation ("-display", arg, 2)) { 177 if (++i >= argc) Syntax (); 178 displayname = argv[i]; 179 continue; 180 } else if (isabbreviation ("-geometry", arg, 2)) { 181 if (++i >= argc) Syntax (); 182 geom = argv[i]; 183 continue; 184 } else if (isabbreviation ("-black", arg, 2)) { 185 action = doBlack; 186 continue; 187 } else if (isabbreviation ("-white", arg, 2)) { 188 action = doWhite; 189 continue; 190 } else if (isabbreviation ("-solid", arg, 2)) { 191 if (++i >= argc) Syntax (); 192 solidcolor = argv[i]; 193 action = doSolid; 194 continue; 195 } else if (isabbreviation ("-none", arg, 2)) { 196 action = doNone; 197 continue; 198 } else if (isabbreviation ("-root", arg, 2)) { 199 action = doRoot; 200 continue; 201 } else 202 Syntax (); 203 } else if (arg[0] == '=') /* obsolete */ 204 geom = arg; 205 else 206 Syntax (); 207 } 208 209 if ((dpy = XOpenDisplay(displayname)) == NULL) { 210 fprintf (stderr, "%s: unable to open display '%s'\n", 211 ProgramName, XDisplayName (displayname)); 212 exit (1); 213 } 214 215 if (action == doDefault) { 216 char *def; 217 218 if ((def = XGetDefault (dpy, ProgramName, "Solid")) != NULL) { 219 solidcolor = strdup (def); 220 if (solidcolor == NULL) { 221 fprintf (stderr, 222 "%s: unable to allocate memory for string.\n", 223 ProgramName); 224 exit (1); 225 } 226 action = doSolid; 227 } else { 228 struct s_pair *pp; 229 230 for (pp = pair_table; pp->resource_name != NULL; pp++) { 231 def = XGetDefault (dpy, ProgramName, pp->resource_name); 232 if (def && parse_boolean_option (def) == 1) { 233 action = pp->action; 234 } 235 } 236 } 237 } 238 239 if (geom == NULL) geom = XGetDefault (dpy, ProgramName, "Geometry"); 240 241 screen = DefaultScreen (dpy); 242 display_width = DisplayWidth (dpy, screen); 243 display_height = DisplayHeight (dpy, screen); 244 x = y = 0; 245 width = display_width; 246 height = display_height; 247 248 if (DisplayCells (dpy, screen) <= 2 && action == doSolid) { 249 if (strcmp (solidcolor, "black") == 0) 250 action = doBlack; 251 else if (strcmp (solidcolor, "white") == 0) 252 action = doWhite; 253 else { 254 fprintf (stderr, 255 "%s: can't use colors on a monochrome display.\n", 256 ProgramName); 257 action = doNone; 258 } 259 } 260 261 if (geom) 262 geom_result = XParseGeometry (geom, &x, &y, 263 (unsigned int *)&width, 264 (unsigned int *)&height); 265 else 266 geom_result = NoValue; 267 268 /* 269 * For parsing geometry, we want to have the following 270 * 271 * = (0,0) for (display_width,display_height) 272 * =WxH+X+Y (X,Y) for (W,H) 273 * =WxH-X-Y (display_width-W-X,display_height-H-Y) for (W,H) 274 * =+X+Y (X,Y) for (display_width-X,display_height-Y) 275 * =WxH (0,0) for (W,H) 276 * =-X-Y (0,0) for (display_width-X,display_height-Y) 277 * 278 * If we let any missing values be taken from (0,0) for 279 * (display_width,display_height) we just have to deal with the 280 * negative offsets. 281 */ 282 283 if (geom_result & XNegative) { 284 if (geom_result & WidthValue) { 285 x = display_width - width + x; 286 } else { 287 width = display_width + x; 288 x = 0; 289 } 290 } 291 if (geom_result & YNegative) { 292 if (geom_result & HeightValue) { 293 y = display_height - height + y; 294 } else { 295 height = display_height + y; 296 y = 0; 297 } 298 } 299 300 mask = 0; 301 switch (action) { 302 case doBlack: 303 xswa.background_pixel = BlackPixel (dpy, screen); 304 mask |= CWBackPixel; 305 break; 306 case doWhite: 307 xswa.background_pixel = WhitePixel (dpy, screen); 308 mask |= CWBackPixel; 309 break; 310 case doSolid: 311 cmap = DefaultColormap (dpy, screen); 312 if (XParseColor (dpy, cmap, solidcolor, &cdef) && 313 XAllocColor (dpy, cmap, &cdef)) { 314 xswa.background_pixel = cdef.pixel; 315 mask |= CWBackPixel; 316 } else { 317 fprintf (stderr,"%s: unable to allocate color '%s'.\n", 318 ProgramName, solidcolor); 319 action = doNone; 320 } 321 break; 322 case doDefault: 323 case doNone: 324 xswa.background_pixmap = None; 325 mask |= CWBackPixmap; 326 break; 327 case doRoot: 328 xswa.background_pixmap = ParentRelative; 329 mask |= CWBackPixmap; 330 break; 331 } 332 xswa.override_redirect = True; 333 xswa.backing_store = NotUseful; 334 xswa.save_under = False; 335 mask |= (CWOverrideRedirect | CWBackingStore | CWSaveUnder); 336 visual.visualid = CopyFromParent; 337 win = XCreateWindow(dpy, DefaultRootWindow(dpy), x, y, width, height, 338 0, DefaultDepth(dpy, screen), InputOutput, &visual, mask, &xswa); 339 340 /* 341 * at some point, we really ought to go walk the tree and turn off 342 * backing store; or do a ClearArea generating exposures on all windows 343 */ 344 XMapWindow (dpy, win); 345 /* the following will free the color that we might have allocateded */ 346 XCloseDisplay (dpy); 347 exit (0); 348} 349 350