1 /* xlockmore.c --- xscreensaver compatibility layer for xlockmore modules.
2 * xscreensaver, Copyright (c) 1997 Jamie Zawinski <jwz@netscape.com>
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation. No representations are made about the suitability of this
9 * software for any purpose. It is provided "as is" without express or
12 * This file, along with xlockmore.h, make it possible to compile an xlockmore
13 * module into a standalone program, and thus use it with xscreensaver.
14 * By Jamie Zawinski <jwz@netscape.com> on 10-May-97; based on the ideas
15 * in the older xlock.h by Charles Hannum <mycroft@ai.mit.edu>. (I had
16 * to redo it, since xlockmore has diverged so far from xlock...)
22 #include "screenhack.h"
23 #include "xlockmoreI.h"
25 #define countof(x) (sizeof((x))/sizeof(*(x)))
27 extern ModeSpecOpt xlockmore_opts[];
28 extern const char *app_defaults;
31 pre_merge_options (void)
36 /* Translate the xlockmore `opts[]' argument to a form that
39 for (i = 0; i < xlockmore_opts->numopts; i++)
41 XrmOptionDescRec *old = &xlockmore_opts->opts[i];
42 XrmOptionDescRec *new = &options[i];
44 if (old->option[0] == '-')
45 new->option = old->option;
48 /* Convert "+foo" to "-no-foo". */
49 new->option = (char *) malloc (strlen(old->option) + 5);
50 strcpy (new->option, "-no-");
51 strcat (new->option, old->option + 1);
54 new->specifier = strrchr (old->specifier, '.');
55 if (!new->specifier) abort();
57 new->argKind = old->argKind;
58 new->value = old->value;
61 /* Add extra args, if they're mentioned in the defaults... */
63 char *args[] = { "-count", "-cycles", "-delay", "-ncolors",
64 "-size", "-wireframe", "-use3d" };
65 for (j = 0; j < countof(args); j++)
66 if (strstr(app_defaults, args[j]+1))
68 XrmOptionDescRec *new = &options[i++];
69 new->option = args[j];
70 new->specifier = strdup(args[j]);
71 new->specifier[0] = '.';
72 if (!strcmp(new->option, "-wireframe"))
74 new->argKind = XrmoptionNoArg;
77 new->option = "-no-wireframe";
78 new->specifier = options[i-1].specifier;
79 new->argKind = XrmoptionNoArg;
82 else if (!strcmp(new->option, "-use3d"))
85 new->argKind = XrmoptionNoArg;
88 new->option = "-no-3d";
89 new->specifier = options[i-1].specifier;
90 new->argKind = XrmoptionNoArg;
95 new->argKind = XrmoptionSepArg;
102 /* Construct the kind of `defaults' that screenhack.c expects from
103 the xlockmore `vars[]' argument.
107 /* Put on the PROGCLASS.background/foreground resources. */
108 s = (char *) malloc(50);
109 strcpy (s, progclass);
110 strcat (s, ".background: black");
113 s = (char *) malloc(50);
114 strcpy (s, progclass);
115 strcat (s, ".foreground: white");
118 /* Copy the lines out of the `app_defaults' var and into this array. */
119 s = strdup (app_defaults);
128 /* Copy the defaults out of the `xlockmore_opts->' variable. */
129 for (j = 0; j < xlockmore_opts->numvarsdesc; j++)
131 const char *def = xlockmore_opts->vars[j].def;
132 if (!def) def = "False";
133 if (def == ((char*) 1)) def = "True";
134 s = (char *) malloc (strlen (xlockmore_opts->vars[j].name) +
137 strcat (s, xlockmore_opts->vars[j].name);
148 xlockmore_read_resources (void)
151 for (i = 0; i < xlockmore_opts->numvarsdesc; i++)
153 void *var = xlockmore_opts->vars[i].var;
154 Bool *var_b = (Bool *) var;
155 char **var_c = (char **) var;
156 int *var_i = (int *) var;
157 float *var_f = (float *) var;
159 switch (xlockmore_opts->vars[i].type)
162 *var_c = get_string_resource (xlockmore_opts->vars[i].name,
163 xlockmore_opts->vars[i].classname);
166 *var_f = get_float_resource (xlockmore_opts->vars[i].name,
167 xlockmore_opts->vars[i].classname);
170 *var_i = get_integer_resource (xlockmore_opts->vars[i].name,
171 xlockmore_opts->vars[i].classname);
174 *var_b = get_boolean_resource (xlockmore_opts->vars[i].name,
175 xlockmore_opts->vars[i].classname);
186 xlockmore_screenhack (Display *dpy, Window window,
187 Bool want_writable_colors,
188 Bool want_uniform_colors,
189 Bool want_smooth_colors,
190 Bool want_bright_colors,
191 void (*hack_init) (ModeInfo *),
192 void (*hack_draw) (ModeInfo *),
193 void (*hack_free) (ModeInfo *))
202 memset(&mi, 0, sizeof(mi));
205 XGetWindowAttributes (dpy, window, &mi.xgwa);
207 color.flags = DoRed|DoGreen|DoBlue;
208 color.red = color.green = color.blue = 0;
209 if (!XAllocColor(dpy, mi.xgwa.colormap, &color))
211 mi.black = color.pixel;
212 color.red = color.green = color.blue = 0xFFFF;
213 if (!XAllocColor(dpy, mi.xgwa.colormap, &color))
215 mi.white = color.pixel;
219 static unsigned long pixels[2];
220 static XColor colors[2];
225 pixels[0] = mi.black;
226 pixels[1] = mi.white;
227 colors[0].flags = DoRed|DoGreen|DoBlue;
228 colors[1].flags = DoRed|DoGreen|DoBlue;
229 colors[0].red = colors[0].green = colors[0].blue = 0;
230 colors[1].red = colors[1].green = colors[1].blue = 0xFFFF;
231 mi.writable_p = False;
235 mi.npixels = get_integer_resource ("ncolors", "Integer");
238 else if (mi.npixels > 256)
241 mi.colors = (XColor *) calloc (mi.npixels, sizeof (*mi.colors));
243 mi.writable_p = want_writable_colors;
245 if (want_uniform_colors)
246 make_uniform_colormap (dpy, mi.xgwa.visual, mi.xgwa.colormap,
247 mi.colors, &mi.npixels,
248 True, &mi.writable_p, True);
249 else if (want_smooth_colors)
250 make_smooth_colormap (dpy, mi.xgwa.visual, mi.xgwa.colormap,
251 mi.colors, &mi.npixels,
252 True, &mi.writable_p, True);
254 make_random_colormap (dpy, mi.xgwa.visual, mi.xgwa.colormap,
255 mi.colors, &mi.npixels,
257 True, &mi.writable_p, True);
264 mi.pixels = (unsigned long *)
265 calloc (mi.npixels, sizeof (*mi.pixels));
266 for (i = 0; i < mi.npixels; i++)
267 mi.pixels[i] = mi.colors[i].pixel;
271 gcv.foreground = mi.white;
272 gcv.background = mi.black;
273 mi.gc = XCreateGC(dpy, window, GCForeground|GCBackground, &gcv);
275 mi.fullrandom = True;
277 mi.pause = get_integer_resource ("delay", "Usecs");
279 mi.cycles = get_integer_resource ("cycles", "Int");
280 mi.batchcount = get_integer_resource ("count", "Int");
281 mi.size = get_integer_resource ("size", "Int");
284 decay = get_boolean_resource ("decay", "Boolean");
285 if (decay) mi.fullrandom = False;
287 trail = get_boolean_resource ("trail", "Boolean");
288 if (trail) mi.fullrandom = False;
290 grow = get_boolean_resource ("grow", "Boolean");
291 if (grow) mi.fullrandom = False;
293 liss = get_boolean_resource ("liss", "Boolean");
294 if (liss) mi.fullrandom = False;
296 ammann = get_boolean_resource ("ammann", "Boolean");
297 if (ammann) mi.fullrandom = False;
299 jong = get_boolean_resource ("jong", "Boolean");
300 if (jong) mi.fullrandom = False;
302 sine = get_boolean_resource ("sine", "Boolean");
303 if (sine) mi.fullrandom = False;
306 mi.threed = get_boolean_resource ("use3d", "Boolean");
307 mi.threed_delta = get_float_resource ("delta3d", "Boolean");
308 mi.threed_right_color = get_pixel_resource ("right3d", "Color", dpy,
310 mi.threed_left_color = get_pixel_resource ("left3d", "Color", dpy,
312 mi.threed_both_color = get_pixel_resource ("both3d", "Color", dpy,
314 mi.threed_none_color = get_pixel_resource ("none3d", "Color", dpy,
317 mi.wireframe_p = get_boolean_resource ("wireframe", "Boolean");
318 mi.root_p = (window == RootWindowOfScreen (mi.xgwa.screen));
323 else if (mi.pause > 100000000)
324 mi.pause = 100000000;
325 orig_pause = mi.pause;
327 xlockmore_read_resources ();
329 XClearWindow (dpy, window);
332 start = time((time_t) 0);
340 mi.pause = orig_pause;
344 if (i++ > (mi.batchcount / 4) &&
345 (start + 5) < (now = time((time_t) 0)))