1 /* demo.c --- implements the interactive demo-mode and options dialogs.
2 * xscreensaver, Copyright (c) 1993-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
17 #include <X11/Intrinsic.h>
20 # include <X11/IntrinsicP.h> /* just to get debug info for gdb... */
21 # 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 #else /* HAVE_MOTIF */
230 XmListCallbackStruct *lcb = (XmListCallbackStruct *) call_data;
233 XmStringGetLtoR (lcb->item, XmSTRING_DEFAULT_CHARSET, &string);
234 set_text_string (text_line, (string ? string : ""));
235 if (lcb->reason == XmCR_DEFAULT_ACTION && string)
236 demo_mode_hack (si, string);
239 #endif /* HAVE_MOTIF */
240 steal_focus_and_colormap (demo_dialog);
244 #if 0 /* configure does this now */
246 # if !defined(_Viewport_h)
247 /* The R4 Athena libs don't have this function. I don't know the right
248 way to tell, but I note that the R5 version of Viewport.h defines
249 _XawViewport_h, while the R4 version defines _Viewport_h. So we'll
250 try and key off of that... */
251 # define HAVE_XawViewportSetCoordinates
253 #endif /* HAVE_ATHENA */
257 /* Why this behavior isn't automatic in *either* toolkit, I'll never know.
260 ensure_selected_item_visible (Widget list)
265 if (XmListGetSelectedPos (list, &pos_list, &pos_count) && pos_count > 0)
270 XmNtopItemPosition, &top,
271 XmNvisibleItemCount, &visible,
273 if (pos_list[0] >= top + visible)
275 int pos = pos_list[0] - visible + 1;
276 if (pos < 0) pos = 0;
277 XmListSetPos (list, pos);
279 else if (pos_list[0] < top)
281 XmListSetPos (list, pos_list[0]);
285 XtFree ((char *) pos_list);
287 #else /* HAVE_ATHENA */
288 # ifdef HAVE_XawViewportSetCoordinates
290 int margin = 16; /* should be line height or something. */
293 Dimension list_h = 0, vp_h = 0;
294 Dimension top_margin = 4; /* I don't know where this value comes from */
295 Position vp_x = 0, vp_y = 0, current_y;
297 Widget viewport = XtParent(demo_list);
298 Widget sb = (viewport ? XtNameToWidget(viewport, "*vertical") : 0);
299 float sb_top = 0, sb_size = 0;
300 XawListReturnStruct *current = XawListShowCurrent(demo_list);
301 if (!current || !sb) return;
303 XtVaGetValues(demo_list,
304 XtNnumberStrings, &count,
307 if (count < 2 || list_h < 10) return;
309 XtVaGetValues(viewport, XtNheight, &vp_h, XtNx, &vp_x, XtNy, &vp_y, 0);
310 if (vp_h < 10) return;
312 XtVaGetValues(sb, XtNtopOfThumb, &sb_top, XtNshown, &sb_size, 0);
313 if (sb_size <= 0) return;
315 pos = current->list_index;
316 cratio = ((double) pos) / ((double) count);
317 current_y = (cratio * list_h);
319 if (cratio < sb_top ||
320 cratio > sb_top + sb_size)
323 current_y -= (vp_h - margin - margin);
327 if ((long)current_y >= (long) list_h)
328 current_y = (Position) ((long)list_h - (long)vp_h);
330 if ((long)current_y < (long)top_margin)
331 current_y = (Position)top_margin;
333 XawViewportSetCoordinates (viewport, vp_x, current_y);
335 # endif /* HAVE_XawViewportSetCoordinates */
336 #endif /* HAVE_ATHENA */
341 next_cb (Widget button, XtPointer client_data, XtPointer call_data)
343 saver_info *si = (saver_info *) client_data;
347 XawListReturnStruct *current = XawListShowCurrent(demo_list);
348 if (current->list_index == XAW_LIST_NONE)
349 XawListHighlight(demo_list,1);
352 XtVaGetValues(demo_list,
353 XtNnumberStrings, &cnt,
355 if (current->list_index + 1 < cnt)
357 current->list_index++;
358 XawListHighlight(demo_list, current->list_index);
362 ensure_selected_item_visible (demo_list);
363 current = XawListShowCurrent(demo_list);
364 demo_mode_hack (si, current->string);
366 #else /* HAVE_MOTIF */
370 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
372 XmListDeselectAllItems(demo_list); /* LessTif lossage */
373 XmListSelectPos (demo_list, 1, True);
377 int pos = pos_list[0] + 1;
378 if (pos > si->prefs.screenhacks_count)
380 XmListDeselectAllItems(demo_list); /* LessTif lossage */
381 XmListSelectPos (demo_list, pos, True);
383 XtFree ((char *) pos_list);
384 ensure_selected_item_visible (demo_list);
385 demo_mode_hack (si, get_text_string (text_line));
387 #endif /* HAVE_MOTIF */
392 prev_cb (Widget button, XtPointer client_data, XtPointer call_data)
394 saver_info *si = (saver_info *) client_data;
397 XawListReturnStruct *current=XawListShowCurrent(demo_list);
398 if (current->list_index == XAW_LIST_NONE)
399 XawListHighlight(demo_list,1);
402 if (current->list_index>=1)
404 current->list_index--;
405 XawListHighlight(demo_list, current->list_index);
409 ensure_selected_item_visible (demo_list);
410 current = XawListShowCurrent(demo_list);
411 demo_mode_hack (si, current->string);
413 #else /* HAVE_MOTIF */
417 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
419 XmListDeselectAllItems(demo_list); /* LessTif lossage */
420 XmListSelectPos (demo_list, 0, True);
424 XmListDeselectAllItems(demo_list); /* LessTif lossage */
425 XmListSelectPos (demo_list, pos_list [0] - 1, True);
426 XtFree ((char *) pos_list);
428 ensure_selected_item_visible (demo_list);
429 demo_mode_hack (si, get_text_string (text_line));
431 #endif /* HAVE_MOTIF */
435 static void pop_resources_dialog (saver_info *si);
436 static void make_resources_dialog (saver_info *si, Widget parent);
439 edit_cb (Widget button, XtPointer client_data, XtPointer call_data)
441 saver_info *si = (saver_info *) client_data;
442 saver_screen_info *ssi = si->default_screen;
443 Widget parent = ssi->toplevel_shell;
444 if (! resources_dialog)
445 make_resources_dialog (si, parent);
446 pop_resources_dialog (si);
450 done_cb (Widget button, XtPointer client_data, XtPointer call_data)
452 saver_info *si = (saver_info *) client_data;
458 restart_cb (Widget button, XtPointer client_data, XtPointer call_data)
460 saver_info *si = (saver_info *) client_data;
461 demo_mode_restart_process (si);
466 pop_up_dialog_box (Widget dialog, Widget form, int where)
468 /* I'm sure this is the wrong way to pop up a dialog box, but I can't
469 figure out how else to do it.
471 It's important that the screensaver dialogs not get decorated or
472 otherwise reparented by the window manager, because they need to be
473 children of the *real* root window, not the WM's virtual root, in
474 order for us to guarentee that they are visible above the screensaver
479 Dimension sw, sh, x, y, w, h;
482 XtRealizeWidget (dialog);
483 #else /* HAVE_MOTIF */
484 /* Motif likes us to realize the *child* of the shell... */
485 XtRealizeWidget (form);
486 #endif /* HAVE_MOTIF */
488 sw = WidthOfScreen (XtScreen (dialog));
489 sh = HeightOfScreen (XtScreen (dialog));
491 XtSetArg (av [ac], XtNwidth, &w); ac++;
492 XtSetArg (av [ac], XtNheight, &h); ac++;
493 XtGetValues (form, av, ac);
505 case 0: /* center it in the top-right quadrant */
506 x = (sw/2 + w) / 2 + (sw/2) - w;
507 y = (sh/2 + h) / 2 - h;
509 case 1: /* center it in the bottom-right quadrant */
510 x = (sw/2 + w) / 2 + (sw/2) - w;
511 y = (sh/2 + h) / 2 + (sh/2) - h;
513 case 2: /* center it on the screen */
514 x = (sw + w) / 2 - w;
515 y = (sh + h) / 2 - h;
520 if (x + w > sw) x = sw - w;
521 if (y + h > sh) y = sh - h;
523 XtSetArg (av [ac], XtNx, x); ac++;
524 XtSetArg (av [ac], XtNy, y); ac++;
525 XtSetArg (av [ac], XtNoverrideRedirect, True); ac++;
528 XtSetArg (av [ac], XmNdefaultPosition, False); ac++;
529 #endif /* HAVE_MOTIF */
531 XtSetValues (dialog, av, ac);
532 XtSetValues (form, av, ac);
535 XtPopup (dialog, XtGrabNone);
536 #else /* HAVE_MOTIF */
537 XtManageChild (form);
538 #endif /* HAVE_MOTIF */
540 steal_focus_and_colormap (dialog);
545 make_screenhack_dialog (saver_info *si)
547 saver_screen_info *ssi = si->default_screen;
548 Widget parent = ssi->toplevel_shell;
549 char **hacks = si->prefs.screenhacks;
551 if (ssi->demo_cmap &&
552 ssi->demo_cmap != ssi->cmap &&
553 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
555 XFreeColormap (si->dpy, ssi->demo_cmap);
559 if (ssi->default_visual == DefaultVisualOfScreen (ssi->screen))
560 ssi->demo_cmap = DefaultColormapOfScreen (ssi->screen);
562 ssi->demo_cmap = XCreateColormap (si->dpy,
563 RootWindowOfScreen (ssi->screen),
564 ssi->default_visual, AllocNone);
566 create_demo_dialog (parent, ssi->default_visual, ssi->demo_cmap);
567 format_into_label (label1, si->version);
569 add_button_callback (next, next_cb, (XtPointer) si);
570 add_button_callback (prev, prev_cb, (XtPointer) si);
571 add_button_callback (done, done_cb, (XtPointer) si);
572 add_button_callback (restart, restart_cb, (XtPointer) si);
573 add_button_callback (edit, edit_cb, (XtPointer) si);
576 XtAddCallback (demo_list, XmNbrowseSelectionCallback,
577 select_cb, (XtPointer) si);
578 XtAddCallback (demo_list, XmNdefaultActionCallback,
579 select_cb, (XtPointer) si);
580 XtAddCallback (text_line, XmNactivateCallback, text_cb, (XtPointer) si);
582 for (; *hacks; hacks++)
584 XmString xmstr = XmStringCreate (*hacks, XmSTRING_DEFAULT_CHARSET);
585 XmListAddItem (demo_list, xmstr, 0);
586 XmStringFree (xmstr);
589 /* Cause the most-recently-run hack to be selected in the list.
590 Do some voodoo to make it be roughly centered in the list (really,
591 just make it not be within +/- 5 of the top/bottom if possible.)
593 if (ssi->current_hack > 0)
595 int i = ssi->current_hack+1;
598 if (bot < 1) bot = 1;
599 if (top > si->prefs.screenhacks_count)
600 top = si->prefs.screenhacks_count;
602 XmListDeselectAllItems(demo_list); /* LessTif lossage */
603 XmListSelectPos (demo_list, bot, False);
604 ensure_selected_item_visible (demo_list);
606 XmListDeselectAllItems(demo_list); /* LessTif lossage */
607 XmListSelectPos (demo_list, top, False);
608 ensure_selected_item_visible (demo_list);
610 XmListDeselectAllItems(demo_list); /* LessTif lossage */
611 XmListSelectPos (demo_list, i, False);
612 ensure_selected_item_visible (demo_list);
615 #else /* HAVE_ATHENA */
617 XtVaSetValues (demo_list,
619 XtNnumberStrings, si->prefs.screenhacks_count,
621 XtAddCallback (demo_list, XtNcallback, select_cb, si);
623 /* #### still need to do the "select most-recently-run hack"
624 #### thing for Athena.
627 #endif /* HAVE_ATHENA */
629 pop_up_dialog_box(demo_dialog, demo_form,
631 (si->prefs.debug_p ? 69 : 0) +
637 /* the Screensaver Parameters dialog */
639 static struct resources {
640 int timeout, cycle, secs, ticks, lock_time, passwd_time;
641 int verb, cmap, fade, unfade, lock_p;
646 hack_time_cb (Display *dpy, char *line, int *store, Bool sec_p)
651 value = parse_time (line, sec_p, True);
660 res_sec_cb (Widget button, XtPointer client_data, XtPointer call_data)
662 hack_time_cb (XtDisplay (button), get_text_string (button),
663 (int *) client_data, True);
667 res_min_cb (Widget button, XtPointer client_data, XtPointer call_data)
669 hack_time_cb (XtDisplay (button), get_text_string (button),
670 (int *) client_data, False);
674 res_int_cb (Widget button, XtPointer client_data, XtPointer call_data)
676 char *line = get_text_string (button);
677 int *store = (int *) client_data;
682 else if (sscanf (line, "%u%c", &value, &c) != 1)
683 XBell (XtDisplay (button), 0);
689 res_bool_cb (Widget button, XtPointer client_data, XtPointer call_data)
691 int *store = (int *) client_data;
693 *store = ((XmToggleButtonCallbackStruct *) call_data)->set;
694 #else /* HAVE_ATHENA */
695 Boolean state = FALSE;
696 XtVaGetValues (button, XtNstate, &state, NULL);
698 #endif /* HAVE_ATHENA */
702 res_cancel_cb (Widget button, XtPointer client_data, XtPointer call_data)
704 XtDestroyWidget (resources_dialog);
705 resources_dialog = 0;
706 raise_screenhack_dialog ();
711 res_done_cb (Widget button, XtPointer client_data, XtPointer call_data)
713 saver_info *si = (saver_info *) client_data;
714 saver_preferences *p = &si->prefs;
716 res_cancel_cb (button, client_data, call_data);
719 /* Check all text widgets, since we don't have callbacks for these. */
720 res_min_cb (timeout_text, (XtPointer) &res.timeout, NULL);
721 res_min_cb (cycle_text, (XtPointer) &res.cycle, NULL);
722 res_sec_cb (fade_text, (XtPointer) &res.secs, NULL);
723 res_int_cb (ticks_text, (XtPointer) &res.ticks, NULL);
724 res_min_cb (lock_time_text, (XtPointer) &res.lock_time, NULL);
725 res_sec_cb (passwd_time_text, (XtPointer) &res.passwd_time, NULL);
726 #endif /* HAVE_ATHENA */
728 /* Throttle the timeouts to minimum sane values. */
729 if (res.timeout < 5) res.timeout = 5;
730 if (res.cycle < 2) res.cycle = 2;
731 if (res.passwd_time < 10) res.passwd_time = 10;
733 p->timeout = res.timeout * 1000;
734 p->cycle = res.cycle * 1000;
735 p->lock_timeout = res.lock_time * 1000;
737 p->passwd_timeout = res.passwd_time * 1000;
739 p->fade_seconds = res.secs;
740 p->fade_ticks = res.ticks;
741 p->verbose_p = res.verb;
742 p->install_cmap_p = res.cmap;
743 p->fade_p = res.fade;
744 p->unfade_p = res.unfade;
745 p->lock_p = res.lock_p;
748 if (p->debug_p && p->verbose_p)
749 fprintf (stderr, "%s: parameters changed:\n\
750 timeout: %d\n\tcycle: %d\n\tlock: %d\n\tpasswd: %d\n\
751 fade: %d\n\tfade: %d\n\tverbose: %d\n\tinstall: %d\n\
752 fade: %d\n\tunfade: %d\n\tlock: %d\n",
753 progname, p->timeout, p->cycle, p->lock_timeout,
759 p->fade_seconds, p->fade_ticks, p->verbose_p, p->install_cmap_p,
760 p->fade_p, p->unfade_p, p->lock_p);
763 #if defined(HAVE_MIT_SAVER_EXTENSION) || defined(HAVE_SGI_SAVER_EXTENSION)
764 if (p->use_mit_saver_extension || p->use_sgi_saver_extension)
766 /* Need to set the server timeout to the new one the user has picked.
768 int server_timeout, server_interval, prefer_blank, allow_exp;
769 XGetScreenSaver (si->dpy, &server_timeout, &server_interval,
770 &prefer_blank, &allow_exp);
771 if (server_timeout != (p->timeout / 1000))
773 server_timeout = (p->timeout / 1000);
776 "%s: configuring server for saver timeout of %d seconds.\n",
777 progname, server_timeout);
778 /* Leave all other parameters the same. */
779 XSetScreenSaver (si->dpy, server_timeout, server_interval,
780 prefer_blank, allow_exp);
783 #endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */
788 make_resources_dialog (saver_info *si, Widget parent)
790 saver_screen_info *ssi = si->default_screen;
792 if (ssi->demo_cmap &&
793 ssi->demo_cmap != ssi->cmap &&
794 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
796 XFreeColormap (si->dpy, ssi->demo_cmap);
800 if (ssi->default_visual == DefaultVisualOfScreen (ssi->screen))
801 ssi->demo_cmap = DefaultColormapOfScreen (ssi->screen);
803 ssi->demo_cmap = XCreateColormap (si->dpy,
804 RootWindowOfScreen (ssi->screen),
805 ssi->default_visual, AllocNone);
807 create_resources_dialog (parent, ssi->default_visual, ssi->demo_cmap);
809 add_button_callback (res_done, res_done_cb, (XtPointer) si);
810 add_button_callback (res_cancel, res_cancel_cb, (XtPointer) si);
812 #define CB(widget,type,slot) \
813 add_text_callback ((widget), (type), (XtPointer) (slot))
814 #define CBT(widget,type,slot) \
815 add_toggle_callback ((widget), (type), (XtPointer) (slot))
818 /* When using Athena widgets, we can't set callbacks for these,
819 so we'll check them all if "done" gets pressed.
821 CB (timeout_text, res_min_cb, &res.timeout);
822 CB (cycle_text, res_min_cb, &res.cycle);
823 CB (fade_text, res_sec_cb, &res.secs);
824 CB (ticks_text, res_int_cb, &res.ticks);
825 CB (lock_time_text, res_min_cb, &res.lock_time);
826 CB (passwd_time_text, res_sec_cb, &res.passwd_time);
827 #endif /* HAVE_MOTIF */
829 CBT (verbose_toggle, res_bool_cb, &res.verb);
830 CBT (cmap_toggle, res_bool_cb, &res.cmap);
831 CBT (fade_toggle, res_bool_cb, &res.fade);
832 CBT (unfade_toggle, res_bool_cb, &res.unfade);
833 CBT (lock_toggle, res_bool_cb, &res.lock_p);
837 if (si->locking_disabled_p)
839 disable_widget (passwd_time_text);
840 disable_widget (lock_time_text);
841 disable_widget (lock_toggle);
843 if (CellsOfScreen (XtScreen (parent)) <= 2)
845 disable_widget (fade_text);
846 disable_widget (ticks_text);
847 disable_widget (cmap_toggle);
848 disable_widget (fade_toggle);
849 disable_widget (unfade_toggle);
855 fmt_time (char *buf, unsigned int s, int min_p)
857 unsigned int h = 0, m = 0;
869 if (min_p && h == 0 && s == 0)
870 sprintf (buf, "%u", m);
871 else if (!min_p && h == 0 && m == 0)
872 sprintf (buf, "%u", s);
875 sprintf (buf, "%u:%02u", m, s);
878 sprintf (buf, "%u:%02u:%02u", h, m, s);
882 pop_resources_dialog (saver_info *si)
884 saver_preferences *p = &si->prefs;
887 res.timeout = p->timeout / 1000;
888 res.cycle = p->cycle / 1000;
889 res.lock_time = p->lock_timeout / 1000;
891 res.passwd_time = p->passwd_timeout / 1000;
893 res.secs = p->fade_seconds;
894 res.ticks = p->fade_ticks;
895 res.verb = p->verbose_p;
896 res.cmap = p->install_cmap_p;
897 res.fade = p->fade_p;
898 res.unfade = p->unfade_p;
899 res.lock_p = (p->lock_p && !si->locking_disabled_p);
901 fmt_time (buf, res.timeout, 1); set_text_string (timeout_text, buf);
902 fmt_time (buf, res.cycle, 1); set_text_string (cycle_text, buf);
903 fmt_time (buf, res.lock_time, 1); set_text_string (lock_time_text, buf);
904 fmt_time (buf, res.passwd_time, 0); set_text_string (passwd_time_text, buf);
905 fmt_time (buf, res.secs, 0); set_text_string (fade_text, buf);
906 sprintf (buf, "%u", res.ticks); set_text_string (ticks_text, buf);
908 set_toggle_button_state (verbose_toggle, res.verb);
909 set_toggle_button_state (cmap_toggle, res.cmap);
910 set_toggle_button_state (fade_toggle, res.fade);
911 set_toggle_button_state (unfade_toggle, res.unfade);
912 set_toggle_button_state (lock_toggle, res.lock_p);
914 pop_up_dialog_box (resources_dialog, resources_form,
916 (si->prefs.debug_p ? 69 : 0) +
922 /* The main demo-mode command loop.
926 demo_mode (saver_info *si)
928 saver_preferences *p = &si->prefs;
929 si->dbox_up_p = True;
930 initialize_screensaver_window (si);
931 raise_window (si, True, False, False);
932 make_screenhack_dialog (si);
933 while (si->demo_mode_p)
936 XtAppNextEvent (si->app, &event);
937 switch (event.xany.type)
939 case 0: /* synthetic "timeout" event */
943 handle_clientmessage (si, &event, False);
947 if (!p->use_xidle_extension &&
948 !p->use_mit_saver_extension &&
949 !p->use_sgi_saver_extension)
951 start_notice_events_timer (si, event.xcreatewindow.window);
954 printf ("%s: starting notice_events_timer for 0x%X (%lu)\n",
956 (unsigned int) event.xcreatewindow.window,
957 p->notice_events_timeout);
958 #endif /* DEBUG_TIMERS */
964 if (!XtWindowToWidget (si->dpy, event.xbutton.window))
965 raise_screenhack_dialog ();
969 #ifdef HAVE_MIT_SAVER_EXTENSION
970 if (event.type == si->mit_saver_ext_event_number)
972 /* Get the "real" server window(s) out of the way as soon
975 for (i = 0; i < si->nscreens; i++)
977 saver_screen_info *ssi = &si->screens[i];
978 if (ssi->server_mit_saver_window &&
979 window_exists_p (si->dpy, ssi->server_mit_saver_window))
980 XUnmapWindow (si->dpy, ssi->server_mit_saver_window);
984 #endif /* HAVE_MIT_SAVER_EXTENSION */
986 XtDispatchEvent (&event);
990 destroy_screenhack_dialogs (si);
991 initialize_screensaver_window (si);
993 si->demo_mode_p = True; /* kludge to inhibit unfade... */
995 si->demo_mode_p = False;
999 demo_mode_hack (saver_info *si, char *hack)
1001 if (! si->demo_mode_p) abort ();
1002 kill_screenhack (si);
1003 if (! si->demo_hack)
1005 si->demo_hack = hack;
1006 spawn_screenhack (si, False);
1007 /* raise_screenhack_dialog(); */
1011 demo_mode_done (saver_info *si)
1013 kill_screenhack (si);
1015 unblank_screen (si);
1016 si->demo_mode_p = False;
1017 si->dbox_up_p = False;