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