1 /* xscreensaver, Copyright (c) 1992, 1995 Jamie Zawinski <jwz@mcom.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/Shell.h>
39 #include <X11/StringDefs.h>
40 #include <X11/Xmu/Error.h>
41 #include "screenhack.h"
54 static XrmOptionDescRec default_options [] = {
55 { "-root", ".root", XrmoptionNoArg, "True" },
56 { "-window", ".root", XrmoptionNoArg, "False" },
57 { "-mono", ".mono", XrmoptionNoArg, "True" },
58 { "-install", ".installColormap", XrmoptionNoArg, "True" },
59 { "-visual", ".visualID", XrmoptionSepArg, 0 }
62 static char *default_defaults[] = {
64 "*geometry: 500x500", /* this should be .geometry, but nooooo... */
66 "*installColormap: false",
71 static XrmOptionDescRec *merged_options;
72 static int merged_options_size;
73 static char **merged_defaults;
76 merge_options P((void))
78 int options_sizeof = options_size * sizeof (options[0]);
80 merged_options_size = XtNumber (default_options) + options_size;
81 merged_options = (XrmOptionDescRec *)
82 malloc (sizeof (default_options) + options_sizeof);
83 memcpy (merged_options, options, options_sizeof);
84 memcpy (merged_options + options_size, default_options,
85 sizeof (default_options));
87 for (defaults_size = 0; defaults [defaults_size]; defaults_size++);
88 merged_defaults = (char **)
89 malloc (sizeof (default_defaults) + (defaults_size * sizeof (char *)));
90 memcpy (merged_defaults, default_defaults, sizeof (default_defaults));
91 memcpy ((merged_defaults - 1 +
92 (sizeof (default_defaults) / sizeof (default_defaults[0]))),
93 defaults, ((defaults_size + 1) * sizeof (defaults[0])));
97 /* Make the X errors print out the name of this program, so we have some
98 clue which one has a bug when they die under the screensaver.
102 screenhack_ehandler (dpy, error)
106 fprintf (stderr, "\nX error in %s:\n", progname);
107 if (XmuPrintDefaultErrorMessage (dpy, error, stderr))
110 fprintf (stderr, " (nonfatal.)\n");
115 MapNotify_event_p (dpy, event, window)
120 return (event->xany.type == MapNotify &&
121 event->xvisibility.window == (Window) window);
140 toplevel = XtAppInitialize (&app, progclass, merged_options,
141 merged_options_size, &argc, argv,
142 merged_defaults, 0, 0);
143 dpy = XtDisplay (toplevel);
144 db = XtDatabase (dpy);
145 XtGetApplicationNameAndClass (dpy, &progname, &progclass);
146 XSetErrorHandler (screenhack_ehandler);
152 fprintf (stderr, "%s: unrecognised option \"%s\"\n", progname, argv[1]);
153 fprintf (stderr, "Options include: ");
154 for (i = 0; i < merged_options_size; i++)
156 char *sw = merged_options [i].option;
157 Bool argp = (merged_options [i].argKind == XrmoptionSepArg);
158 int size = strlen (sw) + (argp ? 6 : 0) + 2;
161 fprintf (stderr, "\n\t\t ");
165 fprintf (stderr, "%s", sw);
166 if (argp) fprintf (stderr, " <arg>");
167 if (i != merged_options_size - 1) fprintf (stderr, ", ");
169 fprintf (stderr, ".\n");
173 mono_p = get_boolean_resource ("mono", "Boolean");
174 if (CellsOfScreen (DefaultScreenOfDisplay (dpy)) <= 2)
177 root_p = get_boolean_resource ("root", "Boolean");
180 XWindowAttributes xgwa;
181 window = RootWindowOfScreen (XtScreen (toplevel));
182 XtDestroyWidget (toplevel);
183 XGetWindowAttributes (dpy, window, &xgwa);
184 cmap = xgwa.colormap;
185 visual = xgwa.visual;
189 visual = get_visual_resource (dpy, "visualID", "VisualID");
191 XtVaSetValues (toplevel, XtNmappedWhenManaged, False, 0);
192 XtRealizeWidget (toplevel);
193 window = XtWindow (toplevel);
195 if (visual != DefaultVisualOfScreen (XtScreen (toplevel)))
201 cmap = XCreateColormap (dpy, window, visual, AllocNone);
202 bg = get_pixel_resource ("background", "Background", dpy, cmap);
203 bd = get_pixel_resource ("borderColor", "Foreground", dpy, cmap);
205 XtSetArg (av[ac], XtNvisual, visual); ac++;
206 XtSetArg (av[ac], XtNcolormap, cmap); ac++;
207 XtSetArg (av[ac], XtNdepth, get_visual_depth (dpy, visual)); ac++;
208 XtSetArg (av[ac], XtNbackground, (Pixel) bg); ac++;
209 XtSetArg (av[ac], XtNborderColor, (Pixel) bd); ac++;
210 new = XtAppCreateShell (progname, progclass,
211 topLevelShellWidgetClass, dpy,
213 XtDestroyWidget (toplevel);
216 else if (get_boolean_resource ("installColormap", "InstallColormap"))
218 cmap = XCreateColormap (dpy, window,
219 DefaultVisualOfScreen (XtScreen (toplevel)),
221 XSetWindowColormap (dpy, window, cmap);
225 cmap = DefaultColormap (dpy, DefaultScreen (dpy));
228 XtPopup (toplevel, XtGrabNone);
229 window = XtWindow (toplevel);
232 if (!get_boolean_resource ("dontClearWindow", "Boolean")) /* kludge-o-rama */
234 XSetWindowBackground (dpy, window,
235 get_pixel_resource ("background", "Background",
237 XClearWindow (dpy, window);
240 if (!root_p && toplevel->core.mapped_when_managed)
241 /* wait for it to be mapped */
242 XIfEvent (dpy, &event, MapNotify_event_p, (XPointer) window);
245 srandom ((int) time ((time_t *) 0));
246 screenhack (dpy, window);