http://se.aminet.net/pub/X11/ftp.x.org/contrib/vms/xscreensaver-124.zip
[xscreensaver] / hacks / screenhack.c
1 /* xscreensaver, Copyright (c) 1992 Jamie Zawinski <jwz@mcom.com>
2  *
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 
9  * implied warranty.
10  *
11  * And remember: X Windows is to graphics hacking as roman numerals are to
12  * the square root of pi.
13  */
14
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.
18
19    -  create a procedure `screenhack(dpy, window)'
20
21    -  create a variable `char *progclass' which names this program's
22       resource class.
23
24    -  create a variable `char defaults []' for the default resources.
25
26    -  create a variable `XrmOptionDescRec options []' for the command-line,
27       and `int options_size' which is `XtNumber (options)'.
28
29    And that's it...
30  */
31
32 #include "version.h"
33
34 #include <stdio.h>
35 #include <X11/Intrinsic.h>
36 #include <X11/IntrinsicP.h>
37 #include <X11/CoreP.h>
38 #ifndef VMS
39 #include <X11/Xmu/Error.h>
40 #else
41 #include "sys$common:[decw$include.xmu]Error.h"
42 #endif
43
44 #include "screenhack.h"
45
46 char *progname;
47 XrmDatabase db;
48 Bool mono_p;
49
50 #if __STDC__
51 # define P(x) x
52 #else
53 # define P(x)()
54 #endif
55
56
57 static XrmOptionDescRec default_options [] = {
58   { "-root",    ".root",                XrmoptionNoArg, "True" },
59   { "-window",  ".root",                XrmoptionNoArg, "False" },
60   { "-mono",    ".mono",                XrmoptionNoArg, "True" },
61   { "-install", ".installColormap",     XrmoptionNoArg, "True" }
62 };
63
64 static char *default_defaults[] = {
65   "*root:               false",
66   "*geometry:           500x500",
67   "*mono:               false",
68   "*installColormap:    false",
69   0
70 };
71
72 static XrmOptionDescRec *merged_options;
73 static int merged_options_size;
74 static char **merged_defaults;
75
76 static void
77 merge_options P((void))
78 {
79   int options_sizeof = options_size * sizeof (options[0]);
80   int defaults_size;
81   merged_options_size = XtNumber (default_options) + options_size;
82   merged_options = (XrmOptionDescRec *)
83     malloc (sizeof (default_options) + options_sizeof);
84   memcpy (merged_options, options, options_sizeof);
85   memcpy (merged_options + options_size, default_options,
86           sizeof (default_options));
87
88   for (defaults_size = 0; defaults [defaults_size]; defaults_size++);
89   merged_defaults = (char **)
90     malloc (sizeof (default_defaults) + (defaults_size * sizeof (char *)));
91   memcpy (merged_defaults, default_defaults, sizeof (default_defaults));
92   memcpy ((merged_defaults - 1 +
93            (sizeof (default_defaults) / sizeof (default_defaults[0]))),
94           defaults, ((defaults_size + 1) * sizeof (defaults[0])));
95 }
96
97 \f
98 /* Make the X errors print out the name of this program, so we have some
99    clue which one has a bug when they die under the screensaver.
100  */
101
102 static int
103 screenhack_ehandler (dpy, error)
104      Display *dpy;
105      XErrorEvent *error;
106 {
107   fprintf (stderr, "\nX error in %s:\n", progname);
108   if (XmuPrintDefaultErrorMessage (dpy, error, stderr))
109     exit (-1);
110   else
111     fprintf (stderr, " (nonfatal.)\n");
112   return 0;
113 }
114
115 static Bool
116 MapNotify_event_p (dpy, event, window)
117      Display *dpy;
118      XEvent *event;
119      XPointer window;
120 {
121   return (event->xany.type == MapNotify &&
122           event->xvisibility.window == (Window) window);
123 }
124
125
126 #ifndef VMS
127 void
128 #else
129 int
130 #endif
131 main (argc, argv)
132      int argc;
133      char **argv;
134 {
135   XtAppContext app;
136   Widget toplevel;
137   Display *dpy;
138   Window window;
139   Colormap cmap;
140   Bool root_p;
141   XEvent event;
142
143   merge_options ();
144   toplevel = XtAppInitialize (&app, progclass, merged_options,
145                               merged_options_size, &argc, argv,
146                               merged_defaults, 0, 0);
147   dpy = XtDisplay (toplevel);
148   db = XtDatabase (dpy);
149   XtGetApplicationNameAndClass (dpy, &progname, &progclass);
150   XSetErrorHandler (screenhack_ehandler);
151   if (argc > 1)
152     {
153       int i;
154       int x = 18;
155       int end = 78;
156       fprintf (stderr, "%s: unrecognised option \"%s\"\n", progname, argv[1]);
157       fprintf (stderr, "Options include: ");
158       for (i = 0; i < merged_options_size; i++)
159         {
160           char *sw = merged_options [i].option;
161           Bool argp = (merged_options [i].argKind == XrmoptionSepArg);
162           int size = strlen (sw) + (argp ? 6 : 0) + 2;
163           if (x + size >= end)
164             {
165               fprintf (stderr, "\n\t\t ");
166               x = 18;
167             }
168           x += size;
169           fprintf (stderr, "%s", sw);
170           if (argp) fprintf (stderr, " <arg>");
171           if (i != merged_options_size - 1) fprintf (stderr, ", ");
172         }
173       fprintf (stderr, ".\n");
174       exit (1);
175     }
176
177   mono_p = get_boolean_resource ("mono", "Boolean");
178   if (CellsOfScreen (DefaultScreenOfDisplay (dpy)) <= 2)
179     mono_p = True;
180
181   root_p = get_boolean_resource ("root", "Boolean");
182   if (root_p)
183     {
184       XWindowAttributes xgwa;
185       window = RootWindowOfScreen (XtScreen (toplevel));
186       XtDestroyWidget (toplevel);
187       XGetWindowAttributes (dpy, window, &xgwa);
188       cmap = xgwa.colormap;
189     }
190   else
191     {
192       XtRealizeWidget (toplevel);
193       window = XtWindow (toplevel);
194       if (get_boolean_resource ("installColormap", "InstallColormap"))
195         {
196           cmap = XCreateColormap (dpy, window,
197                                   DefaultVisualOfScreen (XtScreen (toplevel)),
198                                   AllocNone);
199           XSetWindowColormap (dpy, window, cmap);
200         }
201       else
202         cmap = DefaultColormap (dpy, DefaultScreen (dpy));
203     }
204   if (!get_boolean_resource ("dontClearWindow", "Boolean")) /* kludge-o-rama */
205     {
206       XSetWindowBackground (dpy, window,
207                             get_pixel_resource ("background", "Background",
208                                                 dpy, cmap));
209       XClearWindow (dpy, window);
210     }
211
212   if (!root_p && toplevel->core.mapped_when_managed)
213     /* wait for it to be mapped */
214     XIfEvent (dpy, &event, MapNotify_event_p, (XPointer) window);
215
216   XSync (dpy, False);
217   srandom ((int) time ((time_t *) 0));
218   screenhack (dpy, window);
219 }