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;
28 extern Time passwd_timeout;
30 extern int fade_seconds, fade_ticks;
31 extern Bool verbose_p, install_cmap_p, fade_p, unfade_p;
32 extern Bool lock_p, locking_disabled_p;
34 static void demo_mode_hack P((char *));
35 static void demo_mode_done P((void));
37 extern void demo_mode_restart_process ();
39 extern Widget demo_dialog;
41 extern Widget text_line;
42 extern Widget demo_form;
43 extern Widget demo_list;
44 extern Widget next, prev, done, restart, edit;
46 extern Widget resources_dialog;
47 extern Widget resources_form;
48 extern Widget res_done, res_cancel;
49 extern Widget timeout_text, cycle_text, fade_text, ticks_text;
50 extern Widget lock_time_text, passwd_time_text;
51 extern Widget verbose_toggle, cmap_toggle, fade_toggle, unfade_toggle,
54 extern create_demo_dialog ();
55 extern create_resources_dialog ();
61 XSetInputFocus (XtDisplay (dialog), XtWindow (dialog),
62 RevertToParent, CurrentTime);
66 raise_screenhack_dialog ()
68 XMapRaised (XtDisplay (demo_dialog), XtWindow (demo_dialog));
70 XMapRaised (XtDisplay (resources_dialog), XtWindow (resources_dialog));
71 focus_fuckus (resources_dialog ? resources_dialog : demo_dialog);
75 destroy_screenhack_dialogs ()
77 if (demo_dialog) XtDestroyWidget (demo_dialog);
78 if (resources_dialog) XtDestroyWidget (resources_dialog);
79 demo_dialog = resources_dialog = 0;
83 text_cb (button, client_data, call_data)
85 XtPointer client_data, call_data;
87 char *line = XmTextGetString (button);
88 demo_mode_hack (line);
93 select_cb (button, client_data, call_data)
95 XtPointer client_data, call_data;
97 char **hacks = (char **) client_data;
98 XmListCallbackStruct *lcb = (XmListCallbackStruct *) call_data;
99 XmTextSetString (text_line, hacks [lcb->item_position - 1]);
100 if (lcb->reason == XmCR_DEFAULT_ACTION)
101 text_cb (text_line, 0, 0);
102 focus_fuckus (demo_dialog);
106 next_cb (button, client_data, call_data)
108 XtPointer client_data, call_data;
112 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
113 XmListSelectPos (demo_list, 1, True);
116 int pos = pos_list [0];
117 XmListSelectPos (demo_list, pos + 1, True);
118 XtFree ((char *) pos_list);
119 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
121 if (pos_list [0] == pos)
122 XmListSelectPos (demo_list, 1, True);
123 XtFree ((char *) pos_list);
125 text_cb (text_line, 0, 0);
129 prev_cb (button, client_data, call_data)
131 XtPointer client_data, call_data;
135 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
136 XmListSelectPos (demo_list, 0, True);
139 XmListSelectPos (demo_list, pos_list [0] - 1, True);
140 XtFree ((char *) pos_list);
142 text_cb (text_line, 0, 0);
146 static void pop_resources_dialog ();
147 static void make_resources_dialog ();
150 edit_cb (button, client_data, call_data)
152 XtPointer client_data, call_data;
154 Widget parent = (Widget) client_data;
155 if (! resources_dialog)
156 make_resources_dialog (parent);
157 pop_resources_dialog ();
161 done_cb (button, client_data, call_data)
163 XtPointer client_data, call_data;
170 restart_cb (button, client_data, call_data)
172 XtPointer client_data, call_data;
174 demo_mode_restart_process ();
178 pop_up_dialog_box (dialog, form, where)
182 /* I'm sure this is the wrong way to pop up a dialog box, but I can't
183 figure out how else to do it.
185 It's important that the screensaver dialogs not get decorated or
186 otherwise reparented by the window manager, because they need to be
187 children of the *real* root window, not the WM's virtual root, in
188 order for us to guarentee that they are visible above the screensaver
193 Dimension sw, sh, x, y, w, h;
194 XtRealizeWidget (form);
195 sw = WidthOfScreen (XtScreen (dialog));
196 sh = HeightOfScreen (XtScreen (dialog));
198 XtSetArg (av [ac], XmNwidth, &w); ac++;
199 XtSetArg (av [ac], XmNheight, &h); ac++;
200 XtGetValues (form, av, ac);
203 case 0: /* center it in the top-right quadrant */
204 x = (sw/2 + w) / 2 + (sw/2) - w;
205 y = (sh/2 + h) / 2 - h;
207 case 1: /* center it in the bottom-right quadrant */
208 x = (sw/2 + w) / 2 + (sw/2) - w;
209 y = (sh/2 + h) / 2 + (sh/2) - h;
211 case 2: /* center it on the screen */
212 x = (sw + w) / 2 - w;
213 y = (sh + h) / 2 - h;
218 if (x + w > sw) x = sw - w;
219 if (y + h > sh) y = sh - h;
221 XtSetArg (av [ac], XmNx, x); ac++;
222 XtSetArg (av [ac], XmNy, y); ac++;
223 XtSetArg (av [ac], XtNoverrideRedirect, True); ac++;
224 XtSetArg (av [ac], XmNdefaultPosition, False); ac++;
225 /* I wonder whether this does anything useful? */
226 /* XtSetArg (av [ac], XmNdialogStyle, XmDIALOG_SYSTEM_MODAL); ac++; */
227 XtSetValues (dialog, av, ac);
228 XtSetValues (form, av, ac);
229 XtManageChild (form);
231 focus_fuckus (dialog);
236 make_screenhack_dialog (parent, hacks)
245 XmString xm_label = 0;
246 XmString new_xm_label;
248 create_demo_dialog (parent);
250 XtSetArg (av [ac], XmNlabelString, &xm_label); ac++;
251 XtGetValues (label1, av, ac);
252 XmStringGetLtoR (xm_label, XmSTRING_DEFAULT_CHARSET, &label);
253 if (!strcmp (label, XtName (label1)))
254 strcpy (buf, "ERROR: RESOURCES ARE NOT INSTALLED CORRECTLY");
256 sprintf (buf, label, screensaver_version);
257 new_xm_label = XmStringCreate (buf, XmSTRING_DEFAULT_CHARSET);
259 XtSetArg (av [ac], XmNlabelString, new_xm_label); ac++;
260 XtSetValues (label1, av, ac);
261 XmStringFree (new_xm_label);
264 XtAddCallback (demo_list, XmNbrowseSelectionCallback, select_cb,
266 XtAddCallback (demo_list, XmNdefaultActionCallback, select_cb,
269 XtAddCallback (text_line, XmNactivateCallback, text_cb, 0);
270 XtAddCallback (next, XmNactivateCallback, next_cb, 0);
271 XtAddCallback (prev, XmNactivateCallback, prev_cb, 0);
272 XtAddCallback (done, XmNactivateCallback, done_cb, 0);
273 XtAddCallback (restart, XmNactivateCallback, restart_cb, 0);
274 XtAddCallback (edit, XmNactivateCallback, edit_cb, (XtPointer) parent);
276 for (; *hacks; hacks++)
278 XmString xmstr = XmStringCreate (*hacks, XmSTRING_DEFAULT_CHARSET);
279 XmListAddItem (demo_list, xmstr, 0);
280 /* XmListSelectPos (widget, i, False); */
281 XmStringFree (xmstr);
285 /* Dialogs that have scroll-lists don't obey maxWidth! Fuck!! Hack it. */
287 XtSetArg (av [ac], XmNmaxWidth, &max_w); ac++;
288 XtGetValues (demo_dialog, av, ac); /* great, this SEGVs */
291 pop_up_dialog_box (demo_dialog, demo_form, 0);
295 /* the Screensaver Parameters dialog */
297 static struct resources {
298 int timeout, cycle, secs, ticks, lock_time, passwd_time;
299 int verb, cmap, fade, unfade, lock_p;
303 extern int parse_time ();
306 hack_time_cb (dpy, line, store, sec_p)
315 value = parse_time (line, sec_p, True);
324 res_sec_cb (button, client_data, call_data)
326 XtPointer client_data, call_data;
328 hack_time_cb (XtDisplay (button), XmTextGetString (button),
329 (int *) client_data, True);
333 res_min_cb (button, client_data, call_data)
335 XtPointer client_data, call_data;
337 hack_time_cb (XtDisplay (button), XmTextGetString (button),
338 (int *) client_data, False);
342 res_int_cb (button, client_data, call_data)
344 XtPointer client_data, call_data;
346 char *line = XmTextGetString (button);
347 int *store = (int *) client_data;
352 else if (sscanf (line, "%u%c", &value, &c) != 1)
353 XBell (XtDisplay (button), 0);
359 res_bool_cb (button, client_data, call_data)
361 XtPointer client_data, call_data;
363 int *store = (int *) client_data;
364 *store = ((XmToggleButtonCallbackStruct *) call_data)->set;
368 res_cancel_cb (button, client_data, call_data)
370 XtPointer client_data, call_data;
372 XtDestroyWidget (resources_dialog);
373 resources_dialog = 0;
374 raise_screenhack_dialog ();
379 res_done_cb (button, client_data, call_data)
381 XtPointer client_data, call_data;
383 res_cancel_cb (button, client_data, call_data);
385 if (res.timeout < 10) res.timeout = 10;
386 if (res.cycle < 2) res.cycle = 2;
387 if (res.passwd_time < 2) res.passwd_time = 30;
389 timeout = res.timeout * 1000;
390 cycle = res.cycle * 1000;
391 lock_timeout = res.lock_time * 1000;
393 passwd_timeout = res.passwd_time * 1000;
395 fade_seconds = res.secs;
396 fade_ticks = res.ticks;
397 verbose_p = res.verb;
398 install_cmap_p = res.cmap;
400 unfade_p = res.unfade;
406 make_resources_dialog (parent)
412 create_resources_dialog (parent);
414 XtAddCallback (res_done, XmNactivateCallback, res_done_cb, 0);
415 XtAddCallback (res_cancel, XmNactivateCallback, res_cancel_cb, 0);
417 #define CB(widget,type,slot) \
418 XtAddCallback ((widget), XmNvalueChangedCallback, (type), \
420 CB (timeout_text, res_min_cb, &res.timeout);
421 CB (cycle_text, res_min_cb, &res.cycle);
422 CB (fade_text, res_sec_cb, &res.secs);
423 CB (ticks_text, res_int_cb, &res.ticks);
424 CB (lock_time_text, res_min_cb, &res.lock_time);
425 CB (passwd_time_text, res_sec_cb, &res.passwd_time);
426 CB (verbose_toggle, res_bool_cb, &res.verb);
427 CB (cmap_toggle, res_bool_cb, &res.cmap);
428 CB (fade_toggle, res_bool_cb, &res.fade);
429 CB (unfade_toggle, res_bool_cb, &res.unfade);
430 CB (lock_toggle, res_bool_cb, &res.lock_p);
433 XtSetArg (av[ac], XmNsensitive, False); ac++;
435 if (locking_disabled_p)
437 XtSetValues (passwd_time_text, av, ac);
438 XtSetValues (lock_time_text, av, ac);
439 XtSetValues (lock_toggle, av, ac);
441 if (CellsOfScreen (XtScreen (parent)) <= 2)
443 XtSetValues (fade_text, av, ac);
444 XtSetValues (ticks_text, av, ac);
445 XtSetValues (cmap_toggle, av, ac);
446 XtSetValues (fade_toggle, av, ac);
447 XtSetValues (unfade_toggle, av, ac);
453 fmt_time (buf, s, min_p)
458 unsigned int h = 0, m = 0;
470 if (min_p && h == 0 && s == 0)
471 sprintf (buf, "%u", m);
472 else if (!min_p && h == 0 && m == 0)
473 sprintf (buf, "%u", s);
476 sprintf (buf, "%u:%02u", m, s);
479 sprintf (buf, "%u:%02u:%02u", h, m, s);
483 pop_resources_dialog ()
487 res.timeout = timeout / 1000;
488 res.cycle = cycle / 1000;
489 res.lock_time = lock_timeout / 1000;
491 res.passwd_time = passwd_timeout / 1000;
493 res.secs = fade_seconds;
494 res.ticks = fade_ticks;
495 res.verb = verbose_p;
496 res.cmap = install_cmap_p;
498 res.unfade = unfade_p;
499 res.lock_p = (lock_p && !locking_disabled_p);
501 fmt_time (buf, res.timeout, 1); XmTextSetString (timeout_text, buf);
502 fmt_time (buf, res.cycle, 1); XmTextSetString (cycle_text, buf);
503 fmt_time (buf, res.lock_time, 1); XmTextSetString (lock_time_text, buf);
504 fmt_time (buf, res.passwd_time, 0); XmTextSetString (passwd_time_text, buf);
505 fmt_time (buf, res.secs, 0); XmTextSetString (fade_text, buf);
506 sprintf (buf, "%u", res.ticks); XmTextSetString (ticks_text, buf);
508 XmToggleButtonSetState (verbose_toggle, res.verb, True);
509 XmToggleButtonSetState (cmap_toggle, res.cmap, True);
510 XmToggleButtonSetState (fade_toggle, res.fade, True);
511 XmToggleButtonSetState (unfade_toggle, res.unfade, True);
512 XmToggleButtonSetState (lock_toggle, res.lock_p, True);
514 pop_up_dialog_box (resources_dialog, resources_form, 1);
518 /* The code on this page isn't actually Motif-specific */
520 Bool dbox_up_p = False;
521 Bool demo_mode_p = False;
523 extern XtAppContext app;
524 extern Widget toplevel_shell;
525 extern Bool use_xidle;
526 extern Time notice_events_timeout;
528 extern char **screenhacks;
529 extern char *demo_hack;
531 extern void notice_events_timer P((XtPointer closure, void *timer));
532 extern Bool handle_clientmessage P((/*XEvent *, Bool*/));
538 initialize_screensaver_window ();
539 raise_window (True, False);
540 make_screenhack_dialog (toplevel_shell, screenhacks);
544 XtAppNextEvent (app, &event);
545 switch (event.xany.type)
547 case 0: /* synthetic "timeout" event */
551 handle_clientmessage (&event, False);
558 XtAppAddTimeOut (app, notice_events_timeout, notice_events_timer,
559 (XtPointer) event.xcreatewindow.window);
564 if (!XtWindowToWidget (dpy, event.xbutton.window))
565 raise_screenhack_dialog ();
569 XtDispatchEvent (&event);
573 destroy_screenhack_dialogs ();
574 initialize_screensaver_window ();
579 demo_mode_hack (hack)
582 if (! demo_mode_p) abort ();
587 spawn_screenhack (False);