1 /* demo.c --- implements the interactive demo-mode and options dialogs.
2 * xscreensaver, Copyright (c) 1993-1998 Jamie Zawinski <jwz@jwz.org>
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
17 #include <X11/Intrinsic.h>
18 #include <X11/StringDefs.h>
20 /* We don't actually use any widget internals, but these are included
21 so that gdb will have debug info for the widgets... */
22 #include <X11/IntrinsicP.h>
23 #include <X11/ShellP.h>
29 # include <Xm/ToggleB.h>
31 #else /* HAVE_ATHENA */
32 /* Athena demo code contributed by Jon A. Christopher <jac8782@tamu.edu> */
33 /* Copyright 1997, with the same permissions as above. */
34 # include <X11/Shell.h>
35 # include <X11/Xaw/Form.h>
36 # include <X11/Xaw/Box.h>
37 # include <X11/Xaw/List.h>
38 # include <X11/Xaw/Command.h>
39 # include <X11/Xaw/Toggle.h>
40 # include <X11/Xaw/Viewport.h>
41 # include <X11/Xaw/Dialog.h>
42 # include <X11/Xaw/Scrollbar.h>
43 # include <X11/Xaw/Text.h>
44 #endif /* HAVE_ATHENA */
46 #include "xscreensaver.h"
47 #include "resources.h" /* for parse_time() */
53 ERROR! You must not include vroot.h in this file.
56 static void demo_mode_hack (saver_info *si, char *);
57 static void demo_mode_done (saver_info *si);
59 extern Widget demo_dialog;
61 extern Widget text_line;
62 extern Widget demo_form;
63 extern Widget demo_list;
64 extern Widget next, prev, done, restart, edit;
66 extern Widget resources_dialog;
67 extern Widget resources_form;
68 extern Widget res_done, res_cancel;
69 extern Widget timeout_text, cycle_text, fade_text, ticks_text;
70 extern Widget lock_time_text, passwd_time_text;
71 extern Widget verbose_toggle, cmap_toggle, fade_toggle, unfade_toggle,
77 # define set_toggle_button_state(toggle,state) \
78 XmToggleButtonSetState ((toggle), (state), True)
79 # define set_text_string(text_widget,string) \
80 XmTextSetString ((text_widget), (string))
81 # define add_button_callback(button,cb,arg) \
82 XtAddCallback ((button), XmNactivateCallback, (cb), (arg))
83 # define add_toggle_callback(button,cb,arg) \
84 XtAddCallback ((button), XmNvalueChangedCallback, (cb), (arg))
85 # define add_text_callback add_toggle_callback
87 #else /* HAVE_ATHENA */
89 # define set_toggle_button_state(toggle,state) \
90 XtVaSetValues((toggle), XtNstate, (state), 0)
91 # define set_text_string(text_widget,string) \
92 XtVaSetValues ((text_widget), XtNvalue, (string), 0)
93 # define add_button_callback(button,cb,arg) \
94 XtAddCallback ((button), XtNcallback, (cb), (arg))
95 # define add_toggle_callback add_button_callback
96 # define add_text_callback(b,c,a) ERROR!
98 #endif /* HAVE_ATHENA */
101 #define disable_widget(widget) \
102 XtVaSetValues((widget), XtNsensitive, False, 0)
106 get_text_string (Widget text_widget)
109 return XmTextGetString (text_widget);
110 #else /* HAVE_ATHENA */
112 if (XtIsSubclass(text_widget, textWidgetClass))
113 XtVaGetValues (text_widget, XtNstring, &string, 0);
114 else if (XtIsSubclass(text_widget, dialogWidgetClass))
115 XtVaGetValues (text_widget, XtNvalue, &string, 0);
120 #endif /* HAVE_ATHENA */
124 get_label_string (Widget label_widget)
128 XmString xm_label = 0;
129 XtVaGetValues (label_widget, XmNlabelString, &xm_label, 0);
132 XmStringGetLtoR (xm_label, XmSTRING_DEFAULT_CHARSET, &label);
134 #else /* HAVE_ATHENA */
136 XtVaGetValues (label_widget, XtNlabel, &label, 0);
137 return (label ? strdup(label) : 0);
138 #endif /* HAVE_ATHENA */
143 set_label_string (Widget label_widget, char *string)
146 XmString xm_string = XmStringCreate (string, XmSTRING_DEFAULT_CHARSET);
147 XtVaSetValues (label_widget, XmNlabelString, xm_string, 0);
148 XmStringFree (xm_string);
149 #else /* HAVE_ATHENA */
150 XtVaSetValues (label_widget, XtNlabel, string, 0);
151 #endif /* HAVE_ATHENA */
156 format_into_label (Widget label, const char *arg)
158 char *text = get_label_string (label);
159 char *buf = (char *) malloc ((text ? strlen(text) : 100) + strlen(arg) + 10);
161 if (!text || !strcmp (text, XtName (label)))
162 strcpy (buf, "ERROR: RESOURCES ARE NOT INSTALLED CORRECTLY");
164 sprintf (buf, text, arg);
166 set_label_string (label, buf);
173 steal_focus_and_colormap (Widget dialog)
175 Display *dpy = XtDisplay (dialog);
176 Window window = XtWindow (dialog);
178 XSetInputFocus (dpy, window, RevertToParent, CurrentTime);
180 XtVaGetValues (dialog, XtNcolormap, &cmap, 0);
182 XInstallColormap (dpy, cmap);
186 raise_screenhack_dialog (void)
188 XMapRaised (XtDisplay (demo_dialog), XtWindow (demo_dialog));
189 if (resources_dialog)
190 XMapRaised (XtDisplay (resources_dialog), XtWindow (resources_dialog));
191 steal_focus_and_colormap (resources_dialog ? resources_dialog : demo_dialog);
195 destroy_screenhack_dialogs (saver_info *si)
197 saver_screen_info *ssi = si->default_screen;
199 if (demo_dialog) XtDestroyWidget (demo_dialog);
200 if (resources_dialog) XtDestroyWidget (resources_dialog);
201 demo_dialog = resources_dialog = 0;
203 if (ssi->demo_cmap &&
204 ssi->demo_cmap != ssi->cmap &&
205 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
207 XFreeColormap (si->dpy, ssi->demo_cmap);
211 /* Since we installed our colormap to display the dialogs properly, put
212 the old one back, so that the screensaver_window is now displayed
215 XInstallColormap (si->dpy, ssi->cmap);
220 text_cb (Widget text_widget, XtPointer client_data, XtPointer call_data)
222 saver_info *si = (saver_info *) client_data;
223 saver_preferences *p = &si->prefs;
225 line = get_text_string (text_widget);
228 fprintf (stderr, "%s: processing text \"%s\".\n", blurb(), line);
230 demo_mode_hack (si, line);
235 /* Bend over backwards to make hitting Return in the text field do the
238 extern saver_info *global_si_kludge;
239 static void text_enter (Widget w, XEvent *event, String *av, Cardinal *ac)
241 text_cb (w, global_si_kludge, 0);
244 static XtActionsRec actions[] = {{"done", text_enter}
246 static char translations[] = ("<Key>Return: done()\n"
247 "<Key>Linefeed: done()\n"
248 "Ctrl<Key>M: done()\n"
249 "Ctrl<Key>J: done()\n");
250 #endif /* HAVE_ATHENA */
254 select_cb (Widget button, XtPointer client_data, XtPointer call_data)
256 saver_info *si = (saver_info *) client_data;
259 XawListReturnStruct *item = (XawListReturnStruct*)call_data;
260 XtVaSetValues(text_line, XtNstring, item->string, 0);
262 demo_mode_hack (si, item->string);
263 if (item->list_index >= 0)
264 si->default_screen->current_hack = item->list_index;
266 #else /* HAVE_MOTIF */
267 XmListCallbackStruct *lcb = (XmListCallbackStruct *) call_data;
270 XmStringGetLtoR (lcb->item, XmSTRING_DEFAULT_CHARSET, &string);
271 set_text_string (text_line, (string ? string : ""));
272 if (lcb->reason == XmCR_DEFAULT_ACTION && string)
274 demo_mode_hack (si, string);
275 if (lcb->item_position > 0)
276 si->default_screen->current_hack = lcb->item_position - 1;
280 #endif /* HAVE_MOTIF */
281 steal_focus_and_colormap (demo_dialog);
285 /* Why this behavior isn't automatic in *either* toolkit, I'll never know.
288 ensure_selected_item_visible (Widget list)
293 if (XmListGetSelectedPos (list, &pos_list, &pos_count) && pos_count > 0)
298 XmNtopItemPosition, &top,
299 XmNvisibleItemCount, &visible,
301 if (pos_list[0] >= top + visible)
303 int pos = pos_list[0] - visible + 1;
304 if (pos < 0) pos = 0;
305 XmListSetPos (list, pos);
307 else if (pos_list[0] < top)
309 XmListSetPos (list, pos_list[0]);
313 XtFree ((char *) pos_list);
315 #else /* HAVE_ATHENA */
316 # ifdef HAVE_XawViewportSetCoordinates
318 int margin = 16; /* should be line height or something. */
321 Dimension list_h = 0, vp_h = 0;
322 Dimension top_margin = 4; /* I don't know where this value comes from */
323 Position vp_x = 0, vp_y = 0, current_y;
325 Widget viewport = XtParent(demo_list);
326 Widget sb = (viewport ? XtNameToWidget(viewport, "*vertical") : 0);
327 float sb_top = 0, sb_size = 0;
328 XawListReturnStruct *current = XawListShowCurrent(demo_list);
329 if (!current || !sb) return;
331 XtVaGetValues(demo_list,
332 XtNnumberStrings, &count,
335 if (count < 2 || list_h < 10) return;
337 XtVaGetValues(viewport, XtNheight, &vp_h, XtNx, &vp_x, XtNy, &vp_y, 0);
338 if (vp_h < 10) return;
340 XtVaGetValues(sb, XtNtopOfThumb, &sb_top, XtNshown, &sb_size, 0);
341 if (sb_size <= 0) return;
343 pos = current->list_index;
344 cratio = ((double) pos) / ((double) count);
345 current_y = (cratio * list_h);
347 if (cratio < sb_top ||
348 cratio > sb_top + sb_size)
351 current_y -= (vp_h - margin - margin);
355 if ((long)current_y >= (long) list_h)
356 current_y = (Position) ((long)list_h - (long)vp_h);
358 if ((long)current_y < (long)top_margin)
359 current_y = (Position)top_margin;
361 XawViewportSetCoordinates (viewport, vp_x, current_y);
363 # endif /* HAVE_XawViewportSetCoordinates */
364 #endif /* HAVE_ATHENA */
369 next_cb (Widget button, XtPointer client_data, XtPointer call_data)
371 saver_info *si = (saver_info *) client_data;
372 saver_preferences *p = &si->prefs;
375 fprintf (stderr, "%s: Run Next\n", blurb());
380 XawListReturnStruct *current = XawListShowCurrent(demo_list);
381 if (current->list_index == XAW_LIST_NONE)
382 XawListHighlight(demo_list, 0);
385 XtVaGetValues(demo_list,
386 XtNnumberStrings, &cnt,
388 if (current->list_index + 1 < cnt)
390 current->list_index++;
391 XawListHighlight(demo_list, current->list_index);
395 ensure_selected_item_visible (demo_list);
396 current = XawListShowCurrent(demo_list);
397 XtVaSetValues(text_line, XtNstring, current->string, 0);
398 demo_mode_hack (si, current->string);
400 #else /* HAVE_MOTIF */
404 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
406 XmListDeselectAllItems(demo_list); /* LessTif lossage */
407 XmListSelectPos (demo_list, 1, True);
411 int pos = pos_list[0] + 1;
412 if (pos > si->prefs.screenhacks_count)
414 XmListDeselectAllItems(demo_list); /* LessTif lossage */
415 XmListSelectPos (demo_list, pos, True);
417 XtFree ((char *) pos_list);
418 ensure_selected_item_visible (demo_list);
419 demo_mode_hack (si, get_text_string (text_line));
421 #endif /* HAVE_MOTIF */
427 prev_cb (Widget button, XtPointer client_data, XtPointer call_data)
429 saver_info *si = (saver_info *) client_data;
430 saver_preferences *p = &si->prefs;
433 fprintf (stderr, "%s: Run Previous\n", blurb());
437 XawListReturnStruct *current=XawListShowCurrent(demo_list);
438 if (current->list_index == XAW_LIST_NONE)
439 XawListHighlight(demo_list, 0);
442 if (current->list_index >= 1)
444 current->list_index--;
445 XawListHighlight(demo_list, current->list_index);
449 ensure_selected_item_visible (demo_list);
450 current = XawListShowCurrent(demo_list);
451 XtVaSetValues(text_line, XtNstring, current->string, 0);
452 demo_mode_hack (si, current->string);
454 #else /* HAVE_MOTIF */
458 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
460 XmListDeselectAllItems(demo_list); /* LessTif lossage */
461 XmListSelectPos (demo_list, 0, True);
465 XmListDeselectAllItems(demo_list); /* LessTif lossage */
466 XmListSelectPos (demo_list, pos_list [0] - 1, True);
467 XtFree ((char *) pos_list);
469 ensure_selected_item_visible (demo_list);
470 demo_mode_hack (si, get_text_string (text_line));
472 #endif /* HAVE_MOTIF */
477 static void pop_resources_dialog (saver_info *si);
478 static void make_resources_dialog (saver_info *si, Widget parent);
481 edit_cb (Widget button, XtPointer client_data, XtPointer call_data)
483 saver_info *si = (saver_info *) client_data;
484 saver_screen_info *ssi = si->default_screen;
485 saver_preferences *p = &si->prefs;
486 Widget parent = ssi->toplevel_shell;
489 fprintf (stderr, "%s: Preferences\n", blurb());
491 if (! resources_dialog)
492 make_resources_dialog (si, parent);
493 pop_resources_dialog (si);
497 done_cb (Widget button, XtPointer client_data, XtPointer call_data)
499 saver_info *si = (saver_info *) client_data;
505 restart_cb (Widget button, XtPointer client_data, XtPointer call_data)
507 saver_info *si = (saver_info *) client_data;
508 saver_preferences *p = &si->prefs;
510 fprintf (stderr, "%s: Restart\n", blurb());
511 demo_mode_restart_process (si);
516 pop_up_dialog_box (Widget dialog, Widget form, int where)
518 /* I'm sure this is the wrong way to pop up a dialog box, but I can't
519 figure out how else to do it.
521 It's important that the screensaver dialogs not get decorated or
522 otherwise reparented by the window manager, because they need to be
523 children of the *real* root window, not the WM's virtual root, in
524 order for us to guarentee that they are visible above the screensaver
529 Dimension sw, sh, x, y, w, h;
532 XtRealizeWidget (dialog);
533 #else /* HAVE_MOTIF */
534 /* Motif likes us to realize the *child* of the shell... */
535 XtRealizeWidget (form);
536 #endif /* HAVE_MOTIF */
538 sw = WidthOfScreen (XtScreen (dialog));
539 sh = HeightOfScreen (XtScreen (dialog));
541 XtSetArg (av [ac], XtNwidth, &w); ac++;
542 XtSetArg (av [ac], XtNheight, &h); ac++;
543 XtGetValues (form, av, ac);
545 /* for debugging -- don't ask */
554 case 0: /* center it in the top-right quadrant */
555 x = (sw/2 + w) / 2 + (sw/2) - w;
556 y = (sh/2 + h) / 2 - h;
558 case 1: /* center it in the bottom-right quadrant */
559 x = (sw/2 + w) / 2 + (sw/2) - w;
560 y = (sh/2 + h) / 2 + (sh/2) - h;
562 case 2: /* center it on the screen */
563 x = (sw + w) / 2 - w;
564 y = (sh + h) / 2 - h;
566 case 3: /* center it in the top 2/3rds of the screen */
567 x = (sw + w) / 2 - w;
568 y = (sh*2/3 + h) / 2 - h;
573 if (x + w > sw) x = sw - w;
574 if (y + h > sh) y = sh - h;
576 XtSetArg (av [ac], XtNx, x); ac++;
577 XtSetArg (av [ac], XtNy, y); ac++;
578 XtSetArg (av [ac], XtNoverrideRedirect, True); ac++;
581 XtSetArg (av [ac], XmNdefaultPosition, False); ac++;
582 #endif /* HAVE_MOTIF */
584 XtSetValues (dialog, av, ac);
585 XtSetValues (form, av, ac);
588 XtPopup (dialog, XtGrabNone);
589 #else /* HAVE_MOTIF */
590 XtManageChild (form);
591 #endif /* HAVE_MOTIF */
593 steal_focus_and_colormap (dialog);
598 make_screenhack_dialog (saver_info *si)
600 saver_screen_info *ssi = si->default_screen;
601 Widget parent = ssi->toplevel_shell;
602 char **hacks = si->prefs.screenhacks;
604 if (ssi->demo_cmap &&
605 ssi->demo_cmap != ssi->cmap &&
606 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
608 XFreeColormap (si->dpy, ssi->demo_cmap);
612 if (ssi->default_visual == DefaultVisualOfScreen (ssi->screen))
613 ssi->demo_cmap = DefaultColormapOfScreen (ssi->screen);
615 ssi->demo_cmap = XCreateColormap (si->dpy,
616 RootWindowOfScreen (ssi->screen),
617 ssi->default_visual, AllocNone);
619 create_demo_dialog (parent, ssi->default_visual, ssi->demo_cmap);
620 format_into_label (label1, si->version);
622 add_button_callback (next, next_cb, (XtPointer) si);
623 add_button_callback (prev, prev_cb, (XtPointer) si);
624 add_button_callback (done, done_cb, (XtPointer) si);
625 add_button_callback (restart, restart_cb, (XtPointer) si);
626 add_button_callback (edit, edit_cb, (XtPointer) si);
629 XtAddCallback (demo_list, XmNbrowseSelectionCallback,
630 select_cb, (XtPointer) si);
631 XtAddCallback (demo_list, XmNdefaultActionCallback,
632 select_cb, (XtPointer) si);
633 XtAddCallback (text_line, XmNactivateCallback, text_cb, (XtPointer) si);
636 for (; *hacks; hacks++)
638 XmString xmstr = XmStringCreate (*hacks, XmSTRING_DEFAULT_CHARSET);
639 XmListAddItem (demo_list, xmstr, 0);
640 XmStringFree (xmstr);
643 /* Cause the most-recently-run hack to be selected in the list.
644 Do some voodoo to make it be roughly centered in the list (really,
645 just make it not be within +/- 5 of the top/bottom if possible.)
647 if (ssi->current_hack > 0)
649 int i = ssi->current_hack+1;
652 if (bot < 1) bot = 1;
653 if (top > si->prefs.screenhacks_count)
654 top = si->prefs.screenhacks_count;
656 XmListDeselectAllItems(demo_list); /* LessTif lossage */
657 XmListSelectPos (demo_list, bot, False);
658 ensure_selected_item_visible (demo_list);
660 XmListDeselectAllItems(demo_list); /* LessTif lossage */
661 XmListSelectPos (demo_list, top, False);
662 ensure_selected_item_visible (demo_list);
664 XmListDeselectAllItems(demo_list); /* LessTif lossage */
665 XmListSelectPos (demo_list, i, False);
666 ensure_selected_item_visible (demo_list);
669 #else /* HAVE_ATHENA */
671 /* Hook up the text line. */
673 XtAppAddActions(XtWidgetToApplicationContext(text_line),
674 actions, XtNumber(actions));
675 XtOverrideTranslations(text_line, XtParseTranslationTable(translations));
678 /* Must realize the widget before populating the list, or the dialog
679 will be as wide as the longest string.
681 XtRealizeWidget (demo_dialog);
683 XtVaSetValues (demo_list,
685 XtNnumberStrings, si->prefs.screenhacks_count,
687 XtAddCallback (demo_list, XtNcallback, select_cb, si);
688 if (ssi->current_hack > 0)
689 XawListHighlight(demo_list, ssi->current_hack);
691 /* Now that we've populated the list, make sure that the list is as
692 wide as the dialog itself.
695 Widget viewport = XtParent(demo_list);
696 Widget subform = XtParent(viewport);
697 Widget box = XtNameToWidget(demo_dialog, "*box");
698 Widget label1 = XtNameToWidget(demo_dialog, "*label1");
699 Widget label2 = XtNameToWidget(demo_dialog, "*label2");
700 Dimension x=0, y=0, w=0, h=0, bw=0, w2=0;
701 XtVaGetValues(subform,
702 XtNwidth, &w, XtNheight, &h, XtNborderWidth, &bw, 0);
703 XtVaGetValues(box, XtNwidth, &w2, 0);
705 XtResizeWidget(subform, w2, h, bw);
707 /* Why isn't the viewport getting centered? */
708 XtVaGetValues(viewport,
709 XtNx, &x, XtNy, &y, XtNheight, &h, XtNborderWidth, &bw, 0);
710 /* printf("%d %d %d %d\n", x, y, w, h); */
711 XtConfigureWidget(viewport, x, y, w2-x-x, h, bw);
713 /* And the text line, too. */
714 XtVaGetValues(text_line,
715 XtNwidth, &w, XtNheight, &h, XtNborderWidth, &bw, 0);
716 XtVaGetValues(viewport, XtNwidth, &w2, 0);
718 XtResizeWidget(text_line, w2, h, bw);
720 /* And the labels too. */
721 XtVaGetValues(label1,
722 XtNwidth, &w, XtNheight, &h, XtNborderWidth, &bw, 0);
724 XtResizeWidget(label1, w2, h, bw);
726 XtVaGetValues(label2,
727 XtNwidth, &w, XtNheight, &h, XtNborderWidth, &bw, 0);
729 XtResizeWidget(label2, w2, h, bw);
733 #endif /* HAVE_ATHENA */
735 monitor_power_on (si);
736 pop_up_dialog_box(demo_dialog, demo_form,
737 /* for debugging -- don't ask */
738 (si->prefs.debug_p ? 69 : 0) +
742 /* For Athena, have to do this after the dialog is managed. */
743 ensure_selected_item_visible (demo_list);
744 #endif /* HAVE_ATHENA */
748 /* the Screensaver Parameters dialog */
750 static struct resources {
751 int timeout, cycle, secs, ticks, lock_time, passwd_time;
752 int verb, cmap, fade, unfade, lock_p;
757 hack_time_cb (Display *dpy, char *line, int *store, Bool sec_p)
762 value = parse_time (line, sec_p, True);
771 res_sec_cb (Widget button, XtPointer client_data, XtPointer call_data)
773 hack_time_cb (XtDisplay (button), get_text_string (button),
774 (int *) client_data, True);
778 res_min_cb (Widget button, XtPointer client_data, XtPointer call_data)
780 hack_time_cb (XtDisplay (button), get_text_string (button),
781 (int *) client_data, False);
785 res_int_cb (Widget button, XtPointer client_data, XtPointer call_data)
787 char *line = get_text_string (button);
788 int *store = (int *) client_data;
793 else if (sscanf (line, "%u%c", &value, &c) != 1)
794 XBell (XtDisplay (button), 0);
800 res_bool_cb (Widget button, XtPointer client_data, XtPointer call_data)
802 int *store = (int *) client_data;
804 *store = ((XmToggleButtonCallbackStruct *) call_data)->set;
805 #else /* HAVE_ATHENA */
806 Boolean state = FALSE;
807 XtVaGetValues (button, XtNstate, &state, NULL);
809 #endif /* HAVE_ATHENA */
813 res_cancel_cb (Widget button, XtPointer client_data, XtPointer call_data)
815 saver_info *si = (saver_info *) client_data;
816 saver_preferences *p = &si->prefs;
818 XtDestroyWidget (resources_dialog);
819 resources_dialog = 0;
820 raise_screenhack_dialog ();
823 fprintf (stderr, "%s: lowering preferences dialog.\n", blurb());
828 res_done_cb (Widget button, XtPointer client_data, XtPointer call_data)
830 saver_info *si = (saver_info *) client_data;
831 saver_preferences *p = &si->prefs;
833 res_cancel_cb (button, client_data, call_data);
836 /* Check all text widgets, since we don't have callbacks for these. */
837 res_min_cb (timeout_text, (XtPointer) &res.timeout, NULL);
838 res_min_cb (cycle_text, (XtPointer) &res.cycle, NULL);
839 res_sec_cb (fade_text, (XtPointer) &res.secs, NULL);
840 res_int_cb (ticks_text, (XtPointer) &res.ticks, NULL);
841 res_min_cb (lock_time_text, (XtPointer) &res.lock_time, NULL);
842 res_sec_cb (passwd_time_text, (XtPointer) &res.passwd_time, NULL);
843 #endif /* HAVE_ATHENA */
845 /* Throttle the timeouts to minimum sane values. */
846 if (res.timeout < 5) res.timeout = 5;
847 if (res.cycle < 2) res.cycle = 2;
848 if (res.passwd_time < 10) res.passwd_time = 10;
850 p->timeout = res.timeout * 1000;
851 p->cycle = res.cycle * 1000;
852 p->lock_timeout = res.lock_time * 1000;
854 p->passwd_timeout = res.passwd_time * 1000;
856 p->fade_seconds = res.secs;
857 p->fade_ticks = res.ticks;
858 p->verbose_p = res.verb;
859 p->install_cmap_p = res.cmap;
860 p->fade_p = res.fade;
861 p->unfade_p = res.unfade;
862 p->lock_p = res.lock_p;
864 if (p->debug_p && p->verbose_p)
865 fprintf (stderr, "%s: parameters changed:\n\
866 timeout: %d\n\tcycle: %d\n\tlock: %d\n\tpasswd: %d\n\
867 fade: %d\n\tfade: %d\n\tverbose: %d\n\tinstall: %d\n\
868 fade: %d\n\tunfade: %d\n\tlock: %d\n",
869 blurb(), p->timeout, p->cycle, p->lock_timeout,
875 p->fade_seconds, p->fade_ticks, p->verbose_p, p->install_cmap_p,
876 p->fade_p, p->unfade_p, p->lock_p);
879 #if defined(HAVE_MIT_SAVER_EXTENSION) || defined(HAVE_SGI_SAVER_EXTENSION)
880 if (p->use_mit_saver_extension || p->use_sgi_saver_extension)
882 /* Need to set the server timeout to the new one the user has picked.
884 int server_timeout, server_interval, prefer_blank, allow_exp;
885 XGetScreenSaver (si->dpy, &server_timeout, &server_interval,
886 &prefer_blank, &allow_exp);
887 if (server_timeout != (p->timeout / 1000))
889 server_timeout = (p->timeout / 1000);
892 "%s: configuring server for saver timeout of %d seconds.\n",
893 blurb(), server_timeout);
894 /* Leave all other parameters the same. */
895 XSetScreenSaver (si->dpy, server_timeout, server_interval,
896 prefer_blank, allow_exp);
899 #endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */
901 write_init_file (si);
906 make_resources_dialog (saver_info *si, Widget parent)
908 saver_screen_info *ssi = si->default_screen;
910 if (ssi->demo_cmap &&
911 ssi->demo_cmap != ssi->cmap &&
912 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
914 XFreeColormap (si->dpy, ssi->demo_cmap);
918 if (ssi->default_visual == DefaultVisualOfScreen (ssi->screen))
919 ssi->demo_cmap = DefaultColormapOfScreen (ssi->screen);
921 ssi->demo_cmap = XCreateColormap (si->dpy,
922 RootWindowOfScreen (ssi->screen),
923 ssi->default_visual, AllocNone);
925 create_resources_dialog (parent, ssi->default_visual, ssi->demo_cmap);
927 add_button_callback (res_done, res_done_cb, (XtPointer) si);
928 add_button_callback (res_cancel, res_cancel_cb, (XtPointer) si);
930 #define CB(widget,type,slot) \
931 add_text_callback ((widget), (type), (XtPointer) (slot))
932 #define CBT(widget,type,slot) \
933 add_toggle_callback ((widget), (type), (XtPointer) (slot))
936 /* When using Athena widgets, we can't set callbacks for these,
937 so we'll check them all if "done" gets pressed.
939 CB (timeout_text, res_min_cb, &res.timeout);
940 CB (cycle_text, res_min_cb, &res.cycle);
941 CB (fade_text, res_sec_cb, &res.secs);
942 CB (ticks_text, res_int_cb, &res.ticks);
943 CB (lock_time_text, res_min_cb, &res.lock_time);
944 CB (passwd_time_text, res_sec_cb, &res.passwd_time);
945 #endif /* HAVE_MOTIF */
947 CBT (verbose_toggle, res_bool_cb, &res.verb);
948 CBT (cmap_toggle, res_bool_cb, &res.cmap);
949 CBT (fade_toggle, res_bool_cb, &res.fade);
950 CBT (unfade_toggle, res_bool_cb, &res.unfade);
951 CBT (lock_toggle, res_bool_cb, &res.lock_p);
955 if (si->locking_disabled_p)
957 disable_widget (passwd_time_text);
958 disable_widget (lock_time_text);
959 disable_widget (lock_toggle);
961 if (!si->fading_possible_p)
963 disable_widget (fade_text);
964 disable_widget (ticks_text);
965 disable_widget (cmap_toggle);
966 disable_widget (fade_toggle);
967 disable_widget (unfade_toggle);
973 fmt_time (char *buf, unsigned int s, int min_p)
975 unsigned int h = 0, m = 0;
987 if (min_p && h == 0 && s == 0)
988 sprintf (buf, "%u", m);
989 else if (!min_p && h == 0 && m == 0)
990 sprintf (buf, "%u", s);
993 sprintf (buf, "%u:%02u", m, s);
996 sprintf (buf, "%u:%02u:%02u", h, m, s);
1000 pop_resources_dialog (saver_info *si)
1002 saver_preferences *p = &si->prefs;
1006 fprintf (stderr, "%s: raising preferences dialog.\n", blurb());
1008 res.timeout = p->timeout / 1000;
1009 res.cycle = p->cycle / 1000;
1010 res.lock_time = p->lock_timeout / 1000;
1012 res.passwd_time = p->passwd_timeout / 1000;
1014 res.secs = p->fade_seconds;
1015 res.ticks = p->fade_ticks;
1016 res.verb = p->verbose_p;
1017 res.cmap = p->install_cmap_p;
1018 res.fade = p->fade_p;
1019 res.unfade = p->unfade_p;
1020 res.lock_p = (p->lock_p && !si->locking_disabled_p);
1022 fmt_time (buf, res.timeout, 1); set_text_string (timeout_text, buf);
1023 fmt_time (buf, res.cycle, 1); set_text_string (cycle_text, buf);
1024 fmt_time (buf, res.lock_time, 1); set_text_string (lock_time_text, buf);
1025 fmt_time (buf, res.passwd_time, 0); set_text_string (passwd_time_text, buf);
1026 fmt_time (buf, res.secs, 0); set_text_string (fade_text, buf);
1027 sprintf (buf, "%u", res.ticks); set_text_string (ticks_text, buf);
1029 set_toggle_button_state (verbose_toggle, res.verb);
1030 set_toggle_button_state (cmap_toggle, res.cmap);
1031 set_toggle_button_state (fade_toggle, res.fade);
1032 set_toggle_button_state (unfade_toggle, res.unfade);
1033 set_toggle_button_state (lock_toggle, res.lock_p);
1035 monitor_power_on (si);
1036 pop_up_dialog_box (resources_dialog, resources_form,
1037 /* for debugging -- don't ask */
1038 (si->prefs.debug_p ? 69 : 0) +
1043 /* The main demo-mode command loop.
1047 demo_mode (saver_info *si)
1049 saver_preferences *p = &si->prefs;
1050 Bool prefs_p = (si->demo_mode_p == (Bool) 2); /* kludge! */
1053 fprintf (stderr, "%s: Demo Mode.\n", blurb());
1055 si->selection_mode = 0;
1056 si->dbox_up_p = True;
1057 monitor_power_on (si);
1058 raise_window (si, True, False, False);
1059 make_screenhack_dialog (si);
1062 edit_cb (0, si, 0); /* pop up preferences panel */
1064 while (si->demo_mode_p)
1067 XtAppNextEvent (si->app, &event);
1068 switch (event.xany.type)
1070 case 0: /* synthetic "timeout" event */
1074 handle_clientmessage (si, &event, False);
1078 if (!p->use_xidle_extension &&
1079 !p->use_mit_saver_extension &&
1080 !p->use_sgi_saver_extension)
1082 start_notice_events_timer (si, event.xcreatewindow.window);
1086 "%s: starting notice_events_timer for 0x%X (%lu)\n",
1088 (unsigned int) event.xcreatewindow.window,
1089 p->notice_events_timeout);
1090 #endif /* DEBUG_TIMERS */
1096 if (!XtWindowToWidget (si->dpy, event.xbutton.window))
1097 raise_screenhack_dialog ();
1101 #ifdef HAVE_MIT_SAVER_EXTENSION
1102 if (event.type == si->mit_saver_ext_event_number)
1104 /* Get the "real" server window(s) out of the way as soon
1107 for (i = 0; i < si->nscreens; i++)
1109 saver_screen_info *ssi = &si->screens[i];
1110 if (ssi->server_mit_saver_window &&
1111 window_exists_p (si->dpy, ssi->server_mit_saver_window))
1112 XUnmapWindow (si->dpy, ssi->server_mit_saver_window);
1116 #endif /* HAVE_MIT_SAVER_EXTENSION */
1118 XtDispatchEvent (&event);
1124 fprintf (stderr, "%s: Demo Mode done.\n", blurb());
1126 kill_screenhack (si);
1128 destroy_screenhack_dialogs (si);
1129 initialize_screensaver_window (si);
1131 si->dbox_up_p = False;
1134 si->demo_mode_p = True; /* kludge to inhibit unfade... */
1135 unblank_screen (si);
1136 si->demo_mode_p = False;
1140 demo_mode_hack (saver_info *si, char *hack)
1142 if (! si->demo_mode_p) abort ();
1143 kill_screenhack (si);
1144 if (! si->demo_hack)
1146 si->demo_hack = hack;
1147 spawn_screenhack (si, False);
1148 /* raise_screenhack_dialog(); */
1152 demo_mode_done (saver_info *si)
1154 si->demo_mode_p = False;