1 /* xscreensaver, Copyright (c) 1993 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
12 #include <X11/Intrinsic.h>
21 #include <Xm/ToggleB.h>
23 #include "xscreensaver.h"
26 extern Time timeout, cycle, lock_timeout, passwd_timeout;
27 extern int fade_seconds, fade_ticks;
28 extern Bool verbose_p, install_cmap_p, fade_p, unfade_p;
29 extern Bool lock_p, locking_disabled_p;
31 static void demo_mode_hack P((char *));
32 static void demo_mode_done P((void));
34 extern void demo_mode_restart_process ();
36 extern Widget demo_dialog;
38 extern Widget text_line;
39 extern Widget demo_form;
40 extern Widget demo_list;
41 extern Widget next, prev, done, restart, edit;
43 extern Widget resources_dialog;
44 extern Widget resources_form;
45 extern Widget res_done, res_cancel;
46 extern Widget timeout_text, cycle_text, fade_text, ticks_text;
47 extern Widget lock_time_text, passwd_time_text;
48 extern Widget verbose_toggle, cmap_toggle, fade_toggle, unfade_toggle,
51 extern create_demo_dialog ();
52 extern create_resources_dialog ();
58 XSetInputFocus (XtDisplay (dialog), XtWindow (dialog),
59 RevertToParent, CurrentTime);
63 raise_screenhack_dialog ()
65 XMapRaised (XtDisplay (demo_dialog), XtWindow (demo_dialog));
67 XMapRaised (XtDisplay (resources_dialog), XtWindow (resources_dialog));
68 focus_fuckus (resources_dialog ? resources_dialog : demo_dialog);
72 destroy_screenhack_dialogs ()
74 if (demo_dialog) XtDestroyWidget (demo_dialog);
75 if (resources_dialog) XtDestroyWidget (resources_dialog);
76 demo_dialog = resources_dialog = 0;
80 text_cb (button, client_data, call_data)
82 XtPointer client_data, call_data;
84 char *line = XmTextGetString (button);
85 demo_mode_hack (line);
90 select_cb (button, client_data, call_data)
92 XtPointer client_data, call_data;
94 char **hacks = (char **) client_data;
95 XmListCallbackStruct *lcb = (XmListCallbackStruct *) call_data;
96 XmTextSetString (text_line, hacks [lcb->item_position - 1]);
97 if (lcb->reason == XmCR_DEFAULT_ACTION)
98 text_cb (text_line, 0, 0);
99 focus_fuckus (demo_dialog);
103 next_cb (button, client_data, call_data)
105 XtPointer client_data, call_data;
109 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
110 XmListSelectPos (demo_list, 1, True);
113 int pos = pos_list [0];
114 XmListSelectPos (demo_list, pos + 1, True);
115 XtFree ((char *) pos_list);
116 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
118 if (pos_list [0] == pos)
119 XmListSelectPos (demo_list, 1, True);
120 XtFree ((char *) pos_list);
122 text_cb (text_line, 0, 0);
126 prev_cb (button, client_data, call_data)
128 XtPointer client_data, call_data;
132 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
133 XmListSelectPos (demo_list, 0, True);
136 XmListSelectPos (demo_list, pos_list [0] - 1, True);
137 XtFree ((char *) pos_list);
139 text_cb (text_line, 0, 0);
143 static void pop_resources_dialog ();
144 static void make_resources_dialog ();
147 edit_cb (button, client_data, call_data)
149 XtPointer client_data, call_data;
151 Widget parent = (Widget) client_data;
152 if (! resources_dialog)
153 make_resources_dialog (parent);
154 pop_resources_dialog ();
158 done_cb (button, client_data, call_data)
160 XtPointer client_data, call_data;
167 restart_cb (button, client_data, call_data)
169 XtPointer client_data, call_data;
171 demo_mode_restart_process ();
175 pop_up_dialog_box (dialog, form, where)
179 /* I'm sure this is the wrong way to pop up a dialog box, but I can't
180 figure out how else to do it.
182 It's important that the screensaver dialogs not get decorated or
183 otherwise reparented by the window manager, because they need to be
184 children of the *real* root window, not the WM's virtual root, in
185 order for us to guarentee tha they are visible above the screensaver
190 Dimension sw, sh, x, y, w, h;
191 XtRealizeWidget (form);
192 sw = WidthOfScreen (XtScreen (dialog));
193 sh = HeightOfScreen (XtScreen (dialog));
195 XtSetArg (av [ac], XmNwidth, &w); ac++;
196 XtSetArg (av [ac], XmNheight, &h); ac++;
197 XtGetValues (form, av, ac);
200 case 0: /* center it in the top-right quadrant */
201 x = (sw/2 + w) / 2 + (sw/2) - w;
202 y = (sh/2 + h) / 2 - h;
204 case 1: /* center it in the bottom-right quadrant */
205 x = (sw/2 + w) / 2 + (sw/2) - w;
206 y = (sh/2 + h) / 2 + (sh/2) - h;
208 case 2: /* center it on the screen */
209 x = (sw + w) / 2 - w;
210 y = (sh + h) / 2 - h;
215 if (x + w > sw) x = sw - w;
216 if (y + h > sh) y = sh - h;
218 XtSetArg (av [ac], XmNx, x); ac++;
219 XtSetArg (av [ac], XmNy, y); ac++;
220 XtSetArg (av [ac], XtNoverrideRedirect, True); ac++;
221 XtSetArg (av [ac], XmNdefaultPosition, False); ac++;
222 /* I wonder whether this does anything useful? */
223 /* XtSetArg (av [ac], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); ac++; */
224 XtSetValues (dialog, av, ac);
225 XtSetValues (form, av, ac);
226 XtManageChild (form);
228 focus_fuckus (dialog);
233 make_screenhack_dialog (parent, hacks)
242 XmString xm_label = 0;
243 XmString new_xm_label;
245 create_demo_dialog (parent);
247 XtSetArg (av [ac], XmNlabelString, &xm_label); ac++;
248 XtGetValues (label1, av, ac);
249 XmStringGetLtoR (xm_label, XmSTRING_DEFAULT_CHARSET, &label);
250 if (!strcmp (label, XtName (label1)))
251 strcpy (buf, "ERROR: RESOURCES ARE NOT INSTALLED CORRECTLY");
253 sprintf (buf, label, screensaver_version);
254 new_xm_label = XmStringCreate (buf, XmSTRING_DEFAULT_CHARSET);
256 XtSetArg (av [ac], XmNlabelString, new_xm_label); ac++;
257 XtSetValues (label1, av, ac);
258 XmStringFree (new_xm_label);
261 XtAddCallback (demo_list, XmNbrowseSelectionCallback, select_cb,
263 XtAddCallback (demo_list, XmNdefaultActionCallback, select_cb,
266 XtAddCallback (text_line, XmNactivateCallback, text_cb, 0);
267 XtAddCallback (next, XmNactivateCallback, next_cb, 0);
268 XtAddCallback (prev, XmNactivateCallback, prev_cb, 0);
269 XtAddCallback (done, XmNactivateCallback, done_cb, 0);
270 XtAddCallback (restart, XmNactivateCallback, restart_cb, 0);
271 XtAddCallback (edit, XmNactivateCallback, edit_cb, parent);
273 for (; *hacks; hacks++)
275 XmString xmstr = XmStringCreate (*hacks, XmSTRING_DEFAULT_CHARSET);
276 XmListAddItem (demo_list, xmstr, 0);
277 /* XmListSelectPos (widget, i, False); */
278 XmStringFree (xmstr);
282 /* Dialogs that have scroll-lists don't obey maxWidth! Fuck!! Hack it. */
284 XtSetArg (av [ac], XmNmaxWidth, &max_w); ac++;
285 XtGetValues (demo_dialog, av, ac); /* great, this SEGVs */
288 pop_up_dialog_box (demo_dialog, demo_form, 0);
292 /* the Screensaver Parameters dialog */
294 static struct resources {
295 int timeout, cycle, secs, ticks, lock_time, passwd_time;
296 int verb, cmap, fade, unfade, lock_p;
300 extern int parse_time ();
303 hack_time_cb (dpy, line, store, sec_p)
312 value = parse_time (line, sec_p, True);
321 res_sec_cb (button, client_data, call_data)
323 XtPointer client_data, call_data;
325 hack_time_cb (XtDisplay (button), XmTextGetString (button),
326 (int *) client_data, True);
330 res_min_cb (button, client_data, call_data)
332 XtPointer client_data, call_data;
334 hack_time_cb (XtDisplay (button), XmTextGetString (button),
335 (int *) client_data, False);
339 res_int_cb (button, client_data, call_data)
341 XtPointer client_data, call_data;
343 char *line = XmTextGetString (button);
344 int *store = (int *) client_data;
349 else if (sscanf (line, "%u%c", &value, &c) != 1)
350 XBell (XtDisplay (button), 0);
356 res_bool_cb (button, client_data, call_data)
358 XtPointer client_data, call_data;
360 int *store = (int *) client_data;
361 *store = ((XmToggleButtonCallbackStruct *) call_data)->set;
365 res_cancel_cb (button, client_data, call_data)
367 XtPointer client_data, call_data;
369 XtDestroyWidget (resources_dialog);
370 resources_dialog = 0;
371 raise_screenhack_dialog ();
376 res_done_cb (button, client_data, call_data)
378 XtPointer client_data, call_data;
380 res_cancel_cb (button, client_data, call_data);
382 if (res.timeout < 10) res.timeout = 10;
383 if (res.cycle < 2) res.cycle = 2;
384 if (res.passwd_time < 2) res.passwd_time = 30;
386 timeout = res.timeout * 1000;
387 cycle = res.cycle * 1000;
388 lock_timeout = res.lock_time * 1000;
389 passwd_timeout = res.passwd_time * 1000;
390 fade_seconds = res.secs;
391 fade_ticks = res.ticks;
392 verbose_p = res.verb;
393 install_cmap_p = res.cmap;
395 unfade_p = res.unfade;
401 make_resources_dialog (parent)
407 create_resources_dialog (parent);
409 XtAddCallback (res_done, XmNactivateCallback, res_done_cb, 0);
410 XtAddCallback (res_cancel, XmNactivateCallback, res_cancel_cb, 0);
412 #define CB(widget,type,slot) \
413 XtAddCallback ((widget), XmNvalueChangedCallback, (type), (slot))
414 CB (timeout_text, res_min_cb, &res.timeout);
415 CB (cycle_text, res_min_cb, &res.cycle);
416 CB (fade_text, res_sec_cb, &res.secs);
417 CB (ticks_text, res_int_cb, &res.ticks);
418 CB (lock_time_text, res_min_cb, &res.lock_time);
419 CB (passwd_time_text, res_sec_cb, &res.passwd_time);
420 CB (verbose_toggle, res_bool_cb, &res.verb);
421 CB (cmap_toggle, res_bool_cb, &res.cmap);
422 CB (fade_toggle, res_bool_cb, &res.fade);
423 CB (unfade_toggle, res_bool_cb, &res.unfade);
424 CB (lock_toggle, res_bool_cb, &res.lock_p);
427 XtSetArg (av[ac], XmNsensitive, False); ac++;
429 if (locking_disabled_p)
431 XtSetValues (passwd_time_text, av, ac);
432 XtSetValues (lock_time_text, av, ac);
433 XtSetValues (lock_toggle, av, ac);
435 if (CellsOfScreen (XtScreen (parent)) <= 2)
437 XtSetValues (fade_text, av, ac);
438 XtSetValues (ticks_text, av, ac);
439 XtSetValues (cmap_toggle, av, ac);
440 XtSetValues (fade_toggle, av, ac);
441 XtSetValues (unfade_toggle, av, ac);
447 fmt_time (buf, s, min_p)
452 unsigned int h = 0, m = 0;
464 if (min_p && h == 0 && s == 0)
465 sprintf (buf, "%u", m);
466 else if (!min_p && h == 0 && m == 0)
467 sprintf (buf, "%u", s);
470 sprintf (buf, "%u:%02u", m, s);
473 sprintf (buf, "%u:%02u:%02u", h, m, s);
477 pop_resources_dialog ()
481 res.timeout = timeout / 1000;
482 res.cycle = cycle / 1000;
483 res.lock_time = lock_timeout / 1000;
484 res.passwd_time = passwd_timeout / 1000;
485 res.secs = fade_seconds;
486 res.ticks = fade_ticks;
487 res.verb = verbose_p;
488 res.cmap = install_cmap_p;
490 res.unfade = unfade_p;
491 res.lock_p = (lock_p && !locking_disabled_p);
493 fmt_time (buf, res.timeout, 1); XmTextSetString (timeout_text, buf);
494 fmt_time (buf, res.cycle, 1); XmTextSetString (cycle_text, buf);
495 fmt_time (buf, res.lock_time, 1); XmTextSetString (lock_time_text, buf);
496 fmt_time (buf, res.passwd_time, 0); XmTextSetString (passwd_time_text, buf);
497 fmt_time (buf, res.secs, 0); XmTextSetString (fade_text, buf);
498 sprintf (buf, "%u", res.ticks); XmTextSetString (ticks_text, buf);
500 XmToggleButtonSetState (verbose_toggle, res.verb, True);
501 XmToggleButtonSetState (cmap_toggle, res.cmap, True);
502 XmToggleButtonSetState (fade_toggle, res.fade, True);
503 XmToggleButtonSetState (unfade_toggle, res.unfade, True);
504 XmToggleButtonSetState (lock_toggle, res.lock_p, True);
506 pop_up_dialog_box (resources_dialog, resources_form, 1);
510 /* The code on this page isn't actually Motif-specific */
512 Bool dbox_up_p = False;
513 Bool demo_mode_p = False;
515 extern XtAppContext app;
516 extern Widget toplevel_shell;
517 extern Bool use_xidle;
518 extern Time notice_events_timeout;
520 extern char **screenhacks;
521 extern char *demo_hack;
523 extern void notice_events_timer P((XtPointer closure, void *timer));
524 extern Bool handle_clientmessage P((/*XEvent *, Bool*/));
530 initialize_screensaver_window ();
531 raise_window (True, False);
532 make_screenhack_dialog (toplevel_shell, screenhacks);
536 XtAppNextEvent (app, &event);
537 switch (event.xany.type)
539 case 0: /* synthetic "timeout" event */
543 handle_clientmessage (&event, False);
550 XtAppAddTimeOut (app, notice_events_timeout, notice_events_timer,
551 (XtPointer) event.xcreatewindow.window);
556 if (!XtWindowToWidget (dpy, event.xbutton.window))
557 raise_screenhack_dialog ();
561 XtDispatchEvent (&event);
565 destroy_screenhack_dialogs ();
566 initialize_screensaver_window ();
571 demo_mode_hack (hack)
574 if (! demo_mode_p) abort ();
579 spawn_screenhack (False);