1 /* xscreensaver, Copyright (c) 1992 Jamie Zawinski <jwz@lucid.com>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
11 * And remember: X Windows is to graphics hacking as roman numerals are to
12 * the square root of pi.
15 /* This file contains simple code to open a window or draw on the root.
16 The idea being that, when writing a graphics hack, you can just link
17 with this .o to get all of the uninteresting junk out of the way.
19 - create a procedure `screenhack(dpy, window)'
21 - create a variable `char *progclass' which names this program's
24 - create a variable `char defaults []' for the default resources.
26 - create a variable `XrmOptionDescRec options []' for the command-line,
27 and `int options_size' which is `XtNumber (options)'.
35 #include <X11/Intrinsic.h>
36 #include <X11/IntrinsicP.h>
37 #include <X11/CoreP.h>
38 #include <X11/Xmu/Error.h>
39 #include "screenhack.h"
46 static XrmOptionDescRec default_options [] = {
47 { "-root", ".root", XrmoptionNoArg, "True" },
48 { "-window", ".root", XrmoptionNoArg, "False" },
49 { "-mono", ".mono", XrmoptionNoArg, "True" },
50 { "-install", ".installColormap", XrmoptionNoArg, "True" }
53 static char *default_defaults[] = {
55 "*geometry: 500x500", /* this should be .geometry, but nooooo... */
57 "*installColormap: false",
61 static XrmOptionDescRec *merged_options;
62 static int merged_options_size;
63 static char **merged_defaults;
68 int options_sizeof = options_size * sizeof (options[0]);
70 merged_options_size = XtNumber (default_options) + options_size;
71 merged_options = (XrmOptionDescRec *)
72 malloc (sizeof (default_options) + options_sizeof);
73 bcopy (options, merged_options, options_sizeof);
74 bcopy (default_options, merged_options + options_size,
75 sizeof (default_options));
77 for (defaults_size = 0; defaults [defaults_size]; defaults_size++);
78 merged_defaults = (char **)
79 malloc (sizeof (default_defaults) + (defaults_size * sizeof (char *)));
80 bcopy (default_defaults, merged_defaults, sizeof (default_defaults));
81 bcopy (defaults, merged_defaults - 1 +
82 (sizeof (default_defaults) / sizeof (default_defaults[0])),
83 ((defaults_size + 1) * sizeof (defaults[0])));
87 /* Make the X errors print out the name of this program, so we have some
88 clue which one has a bug when they die under the screensaver.
92 screenhack_ehandler (dpy, error)
96 fprintf (stderr, "\nX error in %s:\n", progname);
97 if (XmuPrintDefaultErrorMessage (dpy, error, stderr))
100 fprintf (stderr, " (nonfatal.)\n");
105 MapNotify_event_p (dpy, event, window)
110 return (event->xany.type == MapNotify &&
111 event->xvisibility.window == (Window) window);
129 toplevel = XtAppInitialize (&app, progclass, merged_options,
130 merged_options_size, &argc, argv,
131 merged_defaults, 0, 0);
132 dpy = XtDisplay (toplevel);
133 db = XtDatabase (dpy);
134 XtGetApplicationNameAndClass (dpy, &progname, &progclass);
135 XSetErrorHandler (screenhack_ehandler);
141 fprintf (stderr, "%s: unrecognised option \"%s\"\n", progname, argv[1]);
142 fprintf (stderr, "Options include: ");
143 for (i = 0; i < merged_options_size; i++)
145 char *sw = merged_options [i].option;
146 Bool argp = (merged_options [i].argKind == XrmoptionSepArg);
147 int size = strlen (sw) + (argp ? 6 : 0) + 2;
150 fprintf (stderr, "\n\t\t ");
154 fprintf (stderr, "%s", sw);
155 if (argp) fprintf (stderr, " <arg>");
156 if (i != merged_options_size - 1) fprintf (stderr, ", ");
158 fprintf (stderr, ".\n");
162 mono_p = get_boolean_resource ("mono", "Boolean");
163 if (CellsOfScreen (DefaultScreenOfDisplay (dpy)) <= 2)
166 root_p = get_boolean_resource ("root", "Boolean");
169 XWindowAttributes xgwa;
170 window = RootWindowOfScreen (XtScreen (toplevel));
171 XtDestroyWidget (toplevel);
172 XGetWindowAttributes (dpy, window, &xgwa);
173 cmap = xgwa.colormap;
177 XtRealizeWidget (toplevel);
178 window = XtWindow (toplevel);
179 if (get_boolean_resource ("installColormap", "InstallColormap"))
181 cmap = XCreateColormap (dpy, window,
182 DefaultVisualOfScreen (XtScreen (toplevel)),
184 XSetWindowColormap (dpy, window, cmap);
187 cmap = DefaultColormap (dpy, DefaultScreen (dpy));
189 if (!get_boolean_resource ("dontClearWindow", "Boolean")) /* kludge-o-rama */
191 XSetWindowBackground (dpy, window,
192 get_pixel_resource ("background", "Background",
194 XClearWindow (dpy, window);
197 if (!root_p && toplevel->core.mapped_when_managed)
198 /* wait for it to be mapped */
199 XIfEvent (dpy, &event, MapNotify_event_p, (XPointer) window);
202 srandom ((int) time ((time_t *) 0));
203 screenhack (dpy, window);