1 /* demo.c --- implements the interactive demo-mode and options dialogs.
2 * xscreensaver, Copyright (c) 1993-1998 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
17 #include <X11/Intrinsic.h>
19 /* We don't actually use any widget internals, but these are included
20 so that gdb will have debug info for the widgets... */
21 #include <X11/IntrinsicP.h>
22 #include <X11/ShellP.h>
28 # include <Xm/ToggleB.h>
30 #else /* HAVE_ATHENA */
31 /* Athena demo code contributed by Jon A. Christopher <jac8782@tamu.edu> */
32 /* Copyright 1997, with the same permissions as above. */
33 # include <X11/StringDefs.h>
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 #endif /* HAVE_ATHENA */
45 #include "xscreensaver.h"
46 #include "resources.h" /* for parse_time() */
51 static void demo_mode_hack (saver_info *si, char *);
52 static void demo_mode_done (saver_info *si);
54 extern Widget demo_dialog;
56 extern Widget text_line;
57 extern Widget demo_form;
58 extern Widget demo_list;
59 extern Widget next, prev, done, restart, edit;
61 extern Widget resources_dialog;
62 extern Widget resources_form;
63 extern Widget res_done, res_cancel;
64 extern Widget timeout_text, cycle_text, fade_text, ticks_text;
65 extern Widget lock_time_text, passwd_time_text;
66 extern Widget verbose_toggle, cmap_toggle, fade_toggle, unfade_toggle,
72 # define set_toggle_button_state(toggle,state) \
73 XmToggleButtonSetState ((toggle), (state), True)
74 # define set_text_string(text_widget,string) \
75 XmTextSetString ((text_widget), (string))
76 # define add_button_callback(button,cb,arg) \
77 XtAddCallback ((button), XmNactivateCallback, (cb), (arg))
78 # define add_toggle_callback(button,cb,arg) \
79 XtAddCallback ((button), XmNvalueChangedCallback, (cb), (arg))
80 # define add_text_callback add_toggle_callback
82 #else /* HAVE_ATHENA */
84 # define set_toggle_button_state(toggle,state) \
85 XtVaSetValues((toggle), XtNstate, (state), 0)
86 # define set_text_string(text_widget,string) \
87 XtVaSetValues ((text_widget), XtNvalue, (string), 0)
88 # define add_button_callback(button,cb,arg) \
89 XtAddCallback ((button), XtNcallback, (cb), (arg))
90 # define add_toggle_callback add_button_callback
91 # define add_text_callback(b,c,a) ERROR!
93 #endif /* HAVE_ATHENA */
96 #define disable_widget(widget) \
97 XtVaSetValues((widget), XtNsensitive, False, 0)
101 get_text_string (Widget text_widget)
104 return XmTextGetString (text_widget);
105 #else /* HAVE_ATHENA */
107 XtVaGetValues (text_widget, XtNvalue, &string, 0);
109 #endif /* HAVE_ATHENA */
113 get_label_string (Widget label_widget)
117 XmString xm_label = 0;
118 XtVaGetValues (label_widget, XmNlabelString, &xm_label, 0);
121 XmStringGetLtoR (xm_label, XmSTRING_DEFAULT_CHARSET, &label);
123 #else /* HAVE_ATHENA */
125 XtVaGetValues (label_widget, XtNlabel, &label, 0);
126 return (label ? strdup(label) : 0);
127 #endif /* HAVE_ATHENA */
132 set_label_string (Widget label_widget, char *string)
135 XmString xm_string = XmStringCreate (string, XmSTRING_DEFAULT_CHARSET);
136 XtVaSetValues (label_widget, XmNlabelString, xm_string, 0);
137 XmStringFree (xm_string);
138 #else /* HAVE_ATHENA */
139 XtVaSetValues (label_widget, XtNlabel, string, 0);
140 #endif /* HAVE_ATHENA */
145 format_into_label (Widget label, const char *arg)
147 char *text = get_label_string (label);
148 char *buf = (char *) malloc ((text ? strlen(text) : 100) + strlen(arg) + 10);
150 if (!text || !strcmp (text, XtName (label)))
151 strcpy (buf, "ERROR: RESOURCES ARE NOT INSTALLED CORRECTLY");
153 sprintf (buf, text, arg);
155 set_label_string (label, buf);
162 steal_focus_and_colormap (Widget dialog)
164 Display *dpy = XtDisplay (dialog);
165 Window window = XtWindow (dialog);
167 XSetInputFocus (dpy, window, RevertToParent, CurrentTime);
169 XtVaGetValues (dialog, XtNcolormap, &cmap, 0);
171 XInstallColormap (dpy, cmap);
175 raise_screenhack_dialog (void)
177 XMapRaised (XtDisplay (demo_dialog), XtWindow (demo_dialog));
178 if (resources_dialog)
179 XMapRaised (XtDisplay (resources_dialog), XtWindow (resources_dialog));
180 steal_focus_and_colormap (resources_dialog ? resources_dialog : demo_dialog);
184 destroy_screenhack_dialogs (saver_info *si)
186 saver_screen_info *ssi = si->default_screen;
188 if (demo_dialog) XtDestroyWidget (demo_dialog);
189 if (resources_dialog) XtDestroyWidget (resources_dialog);
190 demo_dialog = resources_dialog = 0;
192 if (ssi->demo_cmap &&
193 ssi->demo_cmap != ssi->cmap &&
194 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
196 XFreeColormap (si->dpy, ssi->demo_cmap);
200 /* Since we installed our colormap to display the dialogs properly, put
201 the old one back, so that the screensaver_window is now displayed
204 XInstallColormap (si->dpy, ssi->cmap);
210 text_cb (Widget text_widget, XtPointer client_data, XtPointer call_data)
212 saver_info *si = (saver_info *) client_data;
214 line = get_text_string (text_widget);
215 demo_mode_hack (si, line);
218 #endif /* HAVE_MOTIF */
222 select_cb (Widget button, XtPointer client_data, XtPointer call_data)
224 saver_info *si = (saver_info *) client_data;
227 XawListReturnStruct *item = (XawListReturnStruct*)call_data;
228 demo_mode_hack (si, item->string);
229 if (item->list_index >= 0)
230 si->default_screen->current_hack = item->list_index;
232 #else /* HAVE_MOTIF */
233 XmListCallbackStruct *lcb = (XmListCallbackStruct *) call_data;
236 XmStringGetLtoR (lcb->item, XmSTRING_DEFAULT_CHARSET, &string);
237 set_text_string (text_line, (string ? string : ""));
238 if (lcb->reason == XmCR_DEFAULT_ACTION && string)
240 demo_mode_hack (si, string);
241 if (lcb->item_position > 0)
242 si->default_screen->current_hack = lcb->item_position - 1;
246 #endif /* HAVE_MOTIF */
247 steal_focus_and_colormap (demo_dialog);
251 #if 0 /* configure does this now */
253 # if !defined(_Viewport_h)
254 /* The R4 Athena libs don't have this function. I don't know the right
255 way to tell, but I note that the R5 version of Viewport.h defines
256 _XawViewport_h, while the R4 version defines _Viewport_h. So we'll
257 try and key off of that... */
258 # define HAVE_XawViewportSetCoordinates
260 #endif /* HAVE_ATHENA */
264 /* Why this behavior isn't automatic in *either* toolkit, I'll never know.
267 ensure_selected_item_visible (Widget list)
272 if (XmListGetSelectedPos (list, &pos_list, &pos_count) && pos_count > 0)
277 XmNtopItemPosition, &top,
278 XmNvisibleItemCount, &visible,
280 if (pos_list[0] >= top + visible)
282 int pos = pos_list[0] - visible + 1;
283 if (pos < 0) pos = 0;
284 XmListSetPos (list, pos);
286 else if (pos_list[0] < top)
288 XmListSetPos (list, pos_list[0]);
292 XtFree ((char *) pos_list);
294 #else /* HAVE_ATHENA */
295 # ifdef HAVE_XawViewportSetCoordinates
297 int margin = 16; /* should be line height or something. */
300 Dimension list_h = 0, vp_h = 0;
301 Dimension top_margin = 4; /* I don't know where this value comes from */
302 Position vp_x = 0, vp_y = 0, current_y;
304 Widget viewport = XtParent(demo_list);
305 Widget sb = (viewport ? XtNameToWidget(viewport, "*vertical") : 0);
306 float sb_top = 0, sb_size = 0;
307 XawListReturnStruct *current = XawListShowCurrent(demo_list);
308 if (!current || !sb) return;
310 XtVaGetValues(demo_list,
311 XtNnumberStrings, &count,
314 if (count < 2 || list_h < 10) return;
316 XtVaGetValues(viewport, XtNheight, &vp_h, XtNx, &vp_x, XtNy, &vp_y, 0);
317 if (vp_h < 10) return;
319 XtVaGetValues(sb, XtNtopOfThumb, &sb_top, XtNshown, &sb_size, 0);
320 if (sb_size <= 0) return;
322 pos = current->list_index;
323 cratio = ((double) pos) / ((double) count);
324 current_y = (cratio * list_h);
326 if (cratio < sb_top ||
327 cratio > sb_top + sb_size)
330 current_y -= (vp_h - margin - margin);
334 if ((long)current_y >= (long) list_h)
335 current_y = (Position) ((long)list_h - (long)vp_h);
337 if ((long)current_y < (long)top_margin)
338 current_y = (Position)top_margin;
340 XawViewportSetCoordinates (viewport, vp_x, current_y);
342 # endif /* HAVE_XawViewportSetCoordinates */
343 #endif /* HAVE_ATHENA */
348 next_cb (Widget button, XtPointer client_data, XtPointer call_data)
350 saver_info *si = (saver_info *) client_data;
354 XawListReturnStruct *current = XawListShowCurrent(demo_list);
355 if (current->list_index == XAW_LIST_NONE)
356 XawListHighlight(demo_list,1);
359 XtVaGetValues(demo_list,
360 XtNnumberStrings, &cnt,
362 if (current->list_index + 1 < cnt)
364 current->list_index++;
365 XawListHighlight(demo_list, current->list_index);
369 ensure_selected_item_visible (demo_list);
370 current = XawListShowCurrent(demo_list);
371 demo_mode_hack (si, current->string);
373 #else /* HAVE_MOTIF */
377 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
379 XmListDeselectAllItems(demo_list); /* LessTif lossage */
380 XmListSelectPos (demo_list, 1, True);
384 int pos = pos_list[0] + 1;
385 if (pos > si->prefs.screenhacks_count)
387 XmListDeselectAllItems(demo_list); /* LessTif lossage */
388 XmListSelectPos (demo_list, pos, True);
390 XtFree ((char *) pos_list);
391 ensure_selected_item_visible (demo_list);
392 demo_mode_hack (si, get_text_string (text_line));
394 #endif /* HAVE_MOTIF */
399 prev_cb (Widget button, XtPointer client_data, XtPointer call_data)
401 saver_info *si = (saver_info *) client_data;
404 XawListReturnStruct *current=XawListShowCurrent(demo_list);
405 if (current->list_index == XAW_LIST_NONE)
406 XawListHighlight(demo_list,1);
409 if (current->list_index>=1)
411 current->list_index--;
412 XawListHighlight(demo_list, current->list_index);
416 ensure_selected_item_visible (demo_list);
417 current = XawListShowCurrent(demo_list);
418 demo_mode_hack (si, current->string);
420 #else /* HAVE_MOTIF */
424 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
426 XmListDeselectAllItems(demo_list); /* LessTif lossage */
427 XmListSelectPos (demo_list, 0, True);
431 XmListDeselectAllItems(demo_list); /* LessTif lossage */
432 XmListSelectPos (demo_list, pos_list [0] - 1, True);
433 XtFree ((char *) pos_list);
435 ensure_selected_item_visible (demo_list);
436 demo_mode_hack (si, get_text_string (text_line));
438 #endif /* HAVE_MOTIF */
442 static void pop_resources_dialog (saver_info *si);
443 static void make_resources_dialog (saver_info *si, Widget parent);
446 edit_cb (Widget button, XtPointer client_data, XtPointer call_data)
448 saver_info *si = (saver_info *) client_data;
449 saver_screen_info *ssi = si->default_screen;
450 Widget parent = ssi->toplevel_shell;
451 if (! resources_dialog)
452 make_resources_dialog (si, parent);
453 pop_resources_dialog (si);
457 done_cb (Widget button, XtPointer client_data, XtPointer call_data)
459 saver_info *si = (saver_info *) client_data;
465 restart_cb (Widget button, XtPointer client_data, XtPointer call_data)
467 saver_info *si = (saver_info *) client_data;
468 demo_mode_restart_process (si);
473 pop_up_dialog_box (Widget dialog, Widget form, int where)
475 /* I'm sure this is the wrong way to pop up a dialog box, but I can't
476 figure out how else to do it.
478 It's important that the screensaver dialogs not get decorated or
479 otherwise reparented by the window manager, because they need to be
480 children of the *real* root window, not the WM's virtual root, in
481 order for us to guarentee that they are visible above the screensaver
486 Dimension sw, sh, x, y, w, h;
489 XtRealizeWidget (dialog);
490 #else /* HAVE_MOTIF */
491 /* Motif likes us to realize the *child* of the shell... */
492 XtRealizeWidget (form);
493 #endif /* HAVE_MOTIF */
495 sw = WidthOfScreen (XtScreen (dialog));
496 sh = HeightOfScreen (XtScreen (dialog));
498 XtSetArg (av [ac], XtNwidth, &w); ac++;
499 XtSetArg (av [ac], XtNheight, &h); ac++;
500 XtGetValues (form, av, ac);
502 /* for debugging -- don't ask */
511 case 0: /* center it in the top-right quadrant */
512 x = (sw/2 + w) / 2 + (sw/2) - w;
513 y = (sh/2 + h) / 2 - h;
515 case 1: /* center it in the bottom-right quadrant */
516 x = (sw/2 + w) / 2 + (sw/2) - w;
517 y = (sh/2 + h) / 2 + (sh/2) - h;
519 case 2: /* center it on the screen */
520 x = (sw + w) / 2 - w;
521 y = (sh + h) / 2 - h;
526 if (x + w > sw) x = sw - w;
527 if (y + h > sh) y = sh - h;
529 XtSetArg (av [ac], XtNx, x); ac++;
530 XtSetArg (av [ac], XtNy, y); ac++;
531 XtSetArg (av [ac], XtNoverrideRedirect, True); ac++;
534 XtSetArg (av [ac], XmNdefaultPosition, False); ac++;
535 #endif /* HAVE_MOTIF */
537 XtSetValues (dialog, av, ac);
538 XtSetValues (form, av, ac);
541 XtPopup (dialog, XtGrabNone);
542 #else /* HAVE_MOTIF */
543 XtManageChild (form);
544 #endif /* HAVE_MOTIF */
546 steal_focus_and_colormap (dialog);
551 make_screenhack_dialog (saver_info *si)
553 saver_screen_info *ssi = si->default_screen;
554 Widget parent = ssi->toplevel_shell;
555 char **hacks = si->prefs.screenhacks;
557 if (ssi->demo_cmap &&
558 ssi->demo_cmap != ssi->cmap &&
559 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
561 XFreeColormap (si->dpy, ssi->demo_cmap);
565 if (ssi->default_visual == DefaultVisualOfScreen (ssi->screen))
566 ssi->demo_cmap = DefaultColormapOfScreen (ssi->screen);
568 ssi->demo_cmap = XCreateColormap (si->dpy,
569 RootWindowOfScreen (ssi->screen),
570 ssi->default_visual, AllocNone);
572 create_demo_dialog (parent, ssi->default_visual, ssi->demo_cmap);
573 format_into_label (label1, si->version);
575 add_button_callback (next, next_cb, (XtPointer) si);
576 add_button_callback (prev, prev_cb, (XtPointer) si);
577 add_button_callback (done, done_cb, (XtPointer) si);
578 add_button_callback (restart, restart_cb, (XtPointer) si);
579 add_button_callback (edit, edit_cb, (XtPointer) si);
582 XtAddCallback (demo_list, XmNbrowseSelectionCallback,
583 select_cb, (XtPointer) si);
584 XtAddCallback (demo_list, XmNdefaultActionCallback,
585 select_cb, (XtPointer) si);
586 XtAddCallback (text_line, XmNactivateCallback, text_cb, (XtPointer) si);
588 for (; *hacks; hacks++)
590 XmString xmstr = XmStringCreate (*hacks, XmSTRING_DEFAULT_CHARSET);
591 XmListAddItem (demo_list, xmstr, 0);
592 XmStringFree (xmstr);
595 /* Cause the most-recently-run hack to be selected in the list.
596 Do some voodoo to make it be roughly centered in the list (really,
597 just make it not be within +/- 5 of the top/bottom if possible.)
599 if (ssi->current_hack > 0)
601 int i = ssi->current_hack+1;
604 if (bot < 1) bot = 1;
605 if (top > si->prefs.screenhacks_count)
606 top = si->prefs.screenhacks_count;
608 XmListDeselectAllItems(demo_list); /* LessTif lossage */
609 XmListSelectPos (demo_list, bot, False);
610 ensure_selected_item_visible (demo_list);
612 XmListDeselectAllItems(demo_list); /* LessTif lossage */
613 XmListSelectPos (demo_list, top, False);
614 ensure_selected_item_visible (demo_list);
616 XmListDeselectAllItems(demo_list); /* LessTif lossage */
617 XmListSelectPos (demo_list, i, False);
618 ensure_selected_item_visible (demo_list);
621 #else /* HAVE_ATHENA */
623 XtVaSetValues (demo_list,
625 XtNnumberStrings, si->prefs.screenhacks_count,
627 XtAddCallback (demo_list, XtNcallback, select_cb, si);
628 if (ssi->current_hack > 0)
629 XawListHighlight(demo_list, ssi->current_hack);
631 #endif /* HAVE_ATHENA */
633 monitor_power_on (si);
634 pop_up_dialog_box(demo_dialog, demo_form,
635 /* for debugging -- don't ask */
636 (si->prefs.debug_p ? 69 : 0) +
640 /* For Athena, have to do this after the dialog is managed. */
641 ensure_selected_item_visible (demo_list);
642 #endif /* HAVE_ATHENA */
646 /* the Screensaver Parameters dialog */
648 static struct resources {
649 int timeout, cycle, secs, ticks, lock_time, passwd_time;
650 int verb, cmap, fade, unfade, lock_p;
655 hack_time_cb (Display *dpy, char *line, int *store, Bool sec_p)
660 value = parse_time (line, sec_p, True);
669 res_sec_cb (Widget button, XtPointer client_data, XtPointer call_data)
671 hack_time_cb (XtDisplay (button), get_text_string (button),
672 (int *) client_data, True);
676 res_min_cb (Widget button, XtPointer client_data, XtPointer call_data)
678 hack_time_cb (XtDisplay (button), get_text_string (button),
679 (int *) client_data, False);
683 res_int_cb (Widget button, XtPointer client_data, XtPointer call_data)
685 char *line = get_text_string (button);
686 int *store = (int *) client_data;
691 else if (sscanf (line, "%u%c", &value, &c) != 1)
692 XBell (XtDisplay (button), 0);
698 res_bool_cb (Widget button, XtPointer client_data, XtPointer call_data)
700 int *store = (int *) client_data;
702 *store = ((XmToggleButtonCallbackStruct *) call_data)->set;
703 #else /* HAVE_ATHENA */
704 Boolean state = FALSE;
705 XtVaGetValues (button, XtNstate, &state, NULL);
707 #endif /* HAVE_ATHENA */
711 res_cancel_cb (Widget button, XtPointer client_data, XtPointer call_data)
713 XtDestroyWidget (resources_dialog);
714 resources_dialog = 0;
715 raise_screenhack_dialog ();
720 res_done_cb (Widget button, XtPointer client_data, XtPointer call_data)
722 saver_info *si = (saver_info *) client_data;
723 saver_preferences *p = &si->prefs;
725 res_cancel_cb (button, client_data, call_data);
728 /* Check all text widgets, since we don't have callbacks for these. */
729 res_min_cb (timeout_text, (XtPointer) &res.timeout, NULL);
730 res_min_cb (cycle_text, (XtPointer) &res.cycle, NULL);
731 res_sec_cb (fade_text, (XtPointer) &res.secs, NULL);
732 res_int_cb (ticks_text, (XtPointer) &res.ticks, NULL);
733 res_min_cb (lock_time_text, (XtPointer) &res.lock_time, NULL);
734 res_sec_cb (passwd_time_text, (XtPointer) &res.passwd_time, NULL);
735 #endif /* HAVE_ATHENA */
737 /* Throttle the timeouts to minimum sane values. */
738 if (res.timeout < 5) res.timeout = 5;
739 if (res.cycle < 2) res.cycle = 2;
740 if (res.passwd_time < 10) res.passwd_time = 10;
742 p->timeout = res.timeout * 1000;
743 p->cycle = res.cycle * 1000;
744 p->lock_timeout = res.lock_time * 1000;
746 p->passwd_timeout = res.passwd_time * 1000;
748 p->fade_seconds = res.secs;
749 p->fade_ticks = res.ticks;
750 p->verbose_p = res.verb;
751 p->install_cmap_p = res.cmap;
752 p->fade_p = res.fade;
753 p->unfade_p = res.unfade;
754 p->lock_p = res.lock_p;
756 if (p->debug_p && p->verbose_p)
757 fprintf (stderr, "%s: parameters changed:\n\
758 timeout: %d\n\tcycle: %d\n\tlock: %d\n\tpasswd: %d\n\
759 fade: %d\n\tfade: %d\n\tverbose: %d\n\tinstall: %d\n\
760 fade: %d\n\tunfade: %d\n\tlock: %d\n",
761 progname, p->timeout, p->cycle, p->lock_timeout,
767 p->fade_seconds, p->fade_ticks, p->verbose_p, p->install_cmap_p,
768 p->fade_p, p->unfade_p, p->lock_p);
771 #if defined(HAVE_MIT_SAVER_EXTENSION) || defined(HAVE_SGI_SAVER_EXTENSION)
772 if (p->use_mit_saver_extension || p->use_sgi_saver_extension)
774 /* Need to set the server timeout to the new one the user has picked.
776 int server_timeout, server_interval, prefer_blank, allow_exp;
777 XGetScreenSaver (si->dpy, &server_timeout, &server_interval,
778 &prefer_blank, &allow_exp);
779 if (server_timeout != (p->timeout / 1000))
781 server_timeout = (p->timeout / 1000);
784 "%s: configuring server for saver timeout of %d seconds.\n",
785 progname, server_timeout);
786 /* Leave all other parameters the same. */
787 XSetScreenSaver (si->dpy, server_timeout, server_interval,
788 prefer_blank, allow_exp);
791 #endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */
796 make_resources_dialog (saver_info *si, Widget parent)
798 saver_screen_info *ssi = si->default_screen;
800 if (ssi->demo_cmap &&
801 ssi->demo_cmap != ssi->cmap &&
802 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
804 XFreeColormap (si->dpy, ssi->demo_cmap);
808 if (ssi->default_visual == DefaultVisualOfScreen (ssi->screen))
809 ssi->demo_cmap = DefaultColormapOfScreen (ssi->screen);
811 ssi->demo_cmap = XCreateColormap (si->dpy,
812 RootWindowOfScreen (ssi->screen),
813 ssi->default_visual, AllocNone);
815 create_resources_dialog (parent, ssi->default_visual, ssi->demo_cmap);
817 add_button_callback (res_done, res_done_cb, (XtPointer) si);
818 add_button_callback (res_cancel, res_cancel_cb, (XtPointer) si);
820 #define CB(widget,type,slot) \
821 add_text_callback ((widget), (type), (XtPointer) (slot))
822 #define CBT(widget,type,slot) \
823 add_toggle_callback ((widget), (type), (XtPointer) (slot))
826 /* When using Athena widgets, we can't set callbacks for these,
827 so we'll check them all if "done" gets pressed.
829 CB (timeout_text, res_min_cb, &res.timeout);
830 CB (cycle_text, res_min_cb, &res.cycle);
831 CB (fade_text, res_sec_cb, &res.secs);
832 CB (ticks_text, res_int_cb, &res.ticks);
833 CB (lock_time_text, res_min_cb, &res.lock_time);
834 CB (passwd_time_text, res_sec_cb, &res.passwd_time);
835 #endif /* HAVE_MOTIF */
837 CBT (verbose_toggle, res_bool_cb, &res.verb);
838 CBT (cmap_toggle, res_bool_cb, &res.cmap);
839 CBT (fade_toggle, res_bool_cb, &res.fade);
840 CBT (unfade_toggle, res_bool_cb, &res.unfade);
841 CBT (lock_toggle, res_bool_cb, &res.lock_p);
845 if (si->locking_disabled_p)
847 disable_widget (passwd_time_text);
848 disable_widget (lock_time_text);
849 disable_widget (lock_toggle);
851 if (CellsOfScreen (XtScreen (parent)) <= 2)
853 disable_widget (fade_text);
854 disable_widget (ticks_text);
855 disable_widget (cmap_toggle);
856 disable_widget (fade_toggle);
857 disable_widget (unfade_toggle);
863 fmt_time (char *buf, unsigned int s, int min_p)
865 unsigned int h = 0, m = 0;
877 if (min_p && h == 0 && s == 0)
878 sprintf (buf, "%u", m);
879 else if (!min_p && h == 0 && m == 0)
880 sprintf (buf, "%u", s);
883 sprintf (buf, "%u:%02u", m, s);
886 sprintf (buf, "%u:%02u:%02u", h, m, s);
890 pop_resources_dialog (saver_info *si)
892 saver_preferences *p = &si->prefs;
895 res.timeout = p->timeout / 1000;
896 res.cycle = p->cycle / 1000;
897 res.lock_time = p->lock_timeout / 1000;
899 res.passwd_time = p->passwd_timeout / 1000;
901 res.secs = p->fade_seconds;
902 res.ticks = p->fade_ticks;
903 res.verb = p->verbose_p;
904 res.cmap = p->install_cmap_p;
905 res.fade = p->fade_p;
906 res.unfade = p->unfade_p;
907 res.lock_p = (p->lock_p && !si->locking_disabled_p);
909 fmt_time (buf, res.timeout, 1); set_text_string (timeout_text, buf);
910 fmt_time (buf, res.cycle, 1); set_text_string (cycle_text, buf);
911 fmt_time (buf, res.lock_time, 1); set_text_string (lock_time_text, buf);
912 fmt_time (buf, res.passwd_time, 0); set_text_string (passwd_time_text, buf);
913 fmt_time (buf, res.secs, 0); set_text_string (fade_text, buf);
914 sprintf (buf, "%u", res.ticks); set_text_string (ticks_text, buf);
916 set_toggle_button_state (verbose_toggle, res.verb);
917 set_toggle_button_state (cmap_toggle, res.cmap);
918 set_toggle_button_state (fade_toggle, res.fade);
919 set_toggle_button_state (unfade_toggle, res.unfade);
920 set_toggle_button_state (lock_toggle, res.lock_p);
922 monitor_power_on (si);
923 pop_up_dialog_box (resources_dialog, resources_form,
924 /* for debugging -- don't ask */
925 (si->prefs.debug_p ? 69 : 0) +
930 /* The main demo-mode command loop.
934 demo_mode (saver_info *si)
936 saver_preferences *p = &si->prefs;
937 si->dbox_up_p = True;
938 monitor_power_on (si);
939 raise_window (si, True, False, False);
940 make_screenhack_dialog (si);
941 while (si->demo_mode_p)
944 XtAppNextEvent (si->app, &event);
945 switch (event.xany.type)
947 case 0: /* synthetic "timeout" event */
951 handle_clientmessage (si, &event, False);
955 if (!p->use_xidle_extension &&
956 !p->use_mit_saver_extension &&
957 !p->use_sgi_saver_extension)
959 start_notice_events_timer (si, event.xcreatewindow.window);
962 printf ("%s: starting notice_events_timer for 0x%X (%lu)\n",
964 (unsigned int) event.xcreatewindow.window,
965 p->notice_events_timeout);
966 #endif /* DEBUG_TIMERS */
972 if (!XtWindowToWidget (si->dpy, event.xbutton.window))
973 raise_screenhack_dialog ();
977 #ifdef HAVE_MIT_SAVER_EXTENSION
978 if (event.type == si->mit_saver_ext_event_number)
980 /* Get the "real" server window(s) out of the way as soon
983 for (i = 0; i < si->nscreens; i++)
985 saver_screen_info *ssi = &si->screens[i];
986 if (ssi->server_mit_saver_window &&
987 window_exists_p (si->dpy, ssi->server_mit_saver_window))
988 XUnmapWindow (si->dpy, ssi->server_mit_saver_window);
992 #endif /* HAVE_MIT_SAVER_EXTENSION */
994 XtDispatchEvent (&event);
998 destroy_screenhack_dialogs (si);
999 initialize_screensaver_window (si);
1001 si->demo_mode_p = True; /* kludge to inhibit unfade... */
1002 unblank_screen (si);
1003 si->demo_mode_p = False;
1007 demo_mode_hack (saver_info *si, char *hack)
1009 if (! si->demo_mode_p) abort ();
1010 kill_screenhack (si);
1011 if (! si->demo_hack)
1013 si->demo_hack = hack;
1014 spawn_screenhack (si, False);
1015 /* raise_screenhack_dialog(); */
1019 demo_mode_done (saver_info *si)
1021 kill_screenhack (si);
1023 unblank_screen (si);
1024 si->demo_mode_p = False;
1025 si->dbox_up_p = False;