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