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>
23 # include <Xm/ToggleB.h>
25 #else /* HAVE_ATHENA */
26 /* Athena demo code contributed by Jon A. Christopher <jac8782@tamu.edu> */
27 /* Copyright 1997, with the same permissions as above. */
28 # include <X11/StringDefs.h>
29 # include <X11/Shell.h>
30 # include <X11/Xaw/Form.h>
31 # include <X11/Xaw/Box.h>
32 # include <X11/Xaw/List.h>
33 # include <X11/Xaw/Command.h>
34 # include <X11/Xaw/Toggle.h>
35 # include <X11/Xaw/Viewport.h>
36 # include <X11/Xaw/Dialog.h>
37 # include <X11/Xaw/Scrollbar.h>
38 #endif /* HAVE_ATHENA */
40 #include "xscreensaver.h"
41 #include "resources.h" /* for parse_time() */
46 static void demo_mode_hack (saver_info *si, char *);
47 static void demo_mode_done (saver_info *si);
49 extern Widget demo_dialog;
51 extern Widget text_line;
52 extern Widget demo_form;
53 extern Widget demo_list;
54 extern Widget next, prev, done, restart, edit;
56 extern Widget resources_dialog;
57 extern Widget resources_form;
58 extern Widget res_done, res_cancel;
59 extern Widget timeout_text, cycle_text, fade_text, ticks_text;
60 extern Widget lock_time_text, passwd_time_text;
61 extern Widget verbose_toggle, cmap_toggle, fade_toggle, unfade_toggle,
67 # define set_toggle_button_state(toggle,state) \
68 XmToggleButtonSetState ((toggle), (state), True)
69 # define set_text_string(text_widget,string) \
70 XmTextSetString ((text_widget), (string))
71 # define add_button_callback(button,cb,arg) \
72 XtAddCallback ((button), XmNactivateCallback, (cb), (arg))
73 # define add_toggle_callback(button,cb,arg) \
74 XtAddCallback ((button), XmNvalueChangedCallback, (cb), (arg))
75 # define add_text_callback add_toggle_callback
77 #else /* HAVE_ATHENA */
79 # define set_toggle_button_state(toggle,state) \
80 XtVaSetValues((toggle), XtNstate, (state), 0)
81 # define set_text_string(text_widget,string) \
82 XtVaSetValues ((text_widget), XtNvalue, (string), 0)
83 # define add_button_callback(button,cb,arg) \
84 XtAddCallback ((button), XtNcallback, (cb), (arg))
85 # define add_toggle_callback add_button_callback
86 # define add_text_callback(b,c,a) ERROR!
88 #endif /* HAVE_ATHENA */
91 #define disable_widget(widget) \
92 XtVaSetValues((widget), XtNsensitive, False, 0)
96 get_text_string (Widget text_widget)
99 return XmTextGetString (text_widget);
100 #else /* HAVE_ATHENA */
102 XtVaGetValues (text_widget, XtNvalue, &string, 0);
104 #endif /* HAVE_ATHENA */
108 get_label_string (Widget label_widget)
112 XmString xm_label = 0;
113 XtVaGetValues (label_widget, XmNlabelString, &xm_label, 0);
116 XmStringGetLtoR (xm_label, XmSTRING_DEFAULT_CHARSET, &label);
118 #else /* HAVE_ATHENA */
120 XtVaGetValues (label_widget, XtNlabel, &label, 0);
121 return (label ? strdup(label) : 0);
122 #endif /* HAVE_ATHENA */
127 set_label_string (Widget label_widget, char *string)
130 XmString xm_string = XmStringCreate (string, XmSTRING_DEFAULT_CHARSET);
131 XtVaSetValues (label_widget, XmNlabelString, xm_string, 0);
132 XmStringFree (xm_string);
133 #else /* HAVE_ATHENA */
134 XtVaSetValues (label_widget, XtNlabel, string, 0);
135 #endif /* HAVE_ATHENA */
140 format_into_label (Widget label, const char *arg)
142 char *text = get_label_string (label);
143 char *buf = (char *) malloc ((text ? strlen(text) : 100) + strlen(arg) + 10);
145 if (!text || !strcmp (text, XtName (label)))
146 strcpy (buf, "ERROR: RESOURCES ARE NOT INSTALLED CORRECTLY");
148 sprintf (buf, text, arg);
150 set_label_string (label, buf);
157 steal_focus_and_colormap (Widget dialog)
159 Display *dpy = XtDisplay (dialog);
160 Window window = XtWindow (dialog);
162 XSetInputFocus (dpy, window, RevertToParent, CurrentTime);
164 XtVaGetValues (dialog, XtNcolormap, &cmap, 0);
166 XInstallColormap (dpy, cmap);
170 raise_screenhack_dialog (void)
172 XMapRaised (XtDisplay (demo_dialog), XtWindow (demo_dialog));
173 if (resources_dialog)
174 XMapRaised (XtDisplay (resources_dialog), XtWindow (resources_dialog));
175 steal_focus_and_colormap (resources_dialog ? resources_dialog : demo_dialog);
179 destroy_screenhack_dialogs (saver_info *si)
181 saver_screen_info *ssi = si->default_screen;
183 if (demo_dialog) XtDestroyWidget (demo_dialog);
184 if (resources_dialog) XtDestroyWidget (resources_dialog);
185 demo_dialog = resources_dialog = 0;
187 if (ssi->demo_cmap &&
188 ssi->demo_cmap != ssi->cmap &&
189 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
191 XFreeColormap (si->dpy, ssi->demo_cmap);
195 /* Since we installed our colormap to display the dialogs properly, put
196 the old one back, so that the screensaver_window is now displayed
199 XInstallColormap (si->dpy, ssi->cmap);
205 text_cb (Widget text_widget, XtPointer client_data, XtPointer call_data)
207 saver_info *si = (saver_info *) client_data;
209 line = get_text_string (text_widget);
210 demo_mode_hack (si, line);
213 #endif /* HAVE_MOTIF */
217 select_cb (Widget button, XtPointer client_data, XtPointer call_data)
219 saver_info *si = (saver_info *) client_data;
222 XawListReturnStruct *item = (XawListReturnStruct*)call_data;
223 demo_mode_hack (si, item->string);
224 #else /* HAVE_MOTIF */
225 XmListCallbackStruct *lcb = (XmListCallbackStruct *) call_data;
228 XmStringGetLtoR (lcb->item, XmSTRING_DEFAULT_CHARSET, &string);
229 set_text_string (text_line, (string ? string : ""));
230 if (lcb->reason == XmCR_DEFAULT_ACTION && string)
231 demo_mode_hack (si, string);
234 #endif /* HAVE_MOTIF */
235 steal_focus_and_colormap (demo_dialog);
239 #if 0 /* configure does this now */
241 # if !defined(_Viewport_h)
242 /* The R4 Athena libs don't have this function. I don't know the right
243 way to tell, but I note that the R5 version of Viewport.h defines
244 _XawViewport_h, while the R4 version defines _Viewport_h. So we'll
245 try and key off of that... */
246 # define HAVE_XawViewportSetCoordinates
248 #endif /* HAVE_ATHENA */
252 /* Why this behavior isn't automatic in *either* toolkit, I'll never know.
255 ensure_selected_item_visible (Widget list)
260 if (XmListGetSelectedPos (list, &pos_list, &pos_count) && pos_count > 0)
265 XmNtopItemPosition, &top,
266 XmNvisibleItemCount, &visible,
268 if (pos_list[0] >= top + visible)
270 int pos = pos_list[0] - visible + 1;
271 if (pos < 0) pos = 0;
272 XmListSetPos (list, pos);
274 else if (pos_list[0] < top)
276 XmListSetPos (list, pos_list[0]);
280 XtFree ((char *) pos_list);
282 #else /* HAVE_ATHENA */
283 # ifdef HAVE_XawViewportSetCoordinates
285 int margin = 16; /* should be line height or something. */
288 Dimension list_h = 0, vp_h = 0;
289 Dimension top_margin = 4; /* I don't know where this value comes from */
290 Position vp_x = 0, vp_y = 0, current_y;
292 Widget viewport = XtParent(demo_list);
293 Widget sb = (viewport ? XtNameToWidget(viewport, "*vertical") : 0);
294 float sb_top = 0, sb_size = 0;
295 XawListReturnStruct *current = XawListShowCurrent(demo_list);
296 if (!current || !sb) return;
298 XtVaGetValues(demo_list,
299 XtNnumberStrings, &count,
302 if (count < 2 || list_h < 10) return;
304 XtVaGetValues(viewport, XtNheight, &vp_h, XtNx, &vp_x, XtNy, &vp_y, 0);
305 if (vp_h < 10) return;
307 XtVaGetValues(sb, XtNtopOfThumb, &sb_top, XtNshown, &sb_size, 0);
308 if (sb_size <= 0) return;
310 pos = current->list_index;
311 cratio = ((double) pos) / ((double) count);
312 current_y = (cratio * list_h);
314 if (cratio < sb_top ||
315 cratio > sb_top + sb_size)
318 current_y -= (vp_h - margin - margin);
322 if ((long)current_y >= (long) list_h)
323 current_y = (Position) ((long)list_h - (long)vp_h);
325 if ((long)current_y < (long)top_margin)
326 current_y = (Position)top_margin;
328 XawViewportSetCoordinates (viewport, vp_x, current_y);
330 # endif /* HAVE_XawViewportSetCoordinates */
331 #endif /* HAVE_ATHENA */
336 next_cb (Widget button, XtPointer client_data, XtPointer call_data)
338 saver_info *si = (saver_info *) client_data;
342 XawListReturnStruct *current = XawListShowCurrent(demo_list);
343 if (current->list_index == XAW_LIST_NONE)
344 XawListHighlight(demo_list,1);
347 XtVaGetValues(demo_list,
348 XtNnumberStrings, &cnt,
350 if (current->list_index + 1 < cnt)
352 current->list_index++;
353 XawListHighlight(demo_list, current->list_index);
357 ensure_selected_item_visible (demo_list);
358 current = XawListShowCurrent(demo_list);
359 demo_mode_hack (si, current->string);
361 #else /* HAVE_MOTIF */
365 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
366 XmListSelectPos (demo_list, 1, True);
369 int pos = pos_list [0];
370 XmListSelectPos (demo_list, pos + 1, True);
371 XtFree ((char *) pos_list);
372 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
374 if (pos_list [0] == pos)
375 XmListSelectPos (demo_list, 1, True);
376 XtFree ((char *) pos_list);
378 ensure_selected_item_visible (demo_list);
379 demo_mode_hack (si, get_text_string (text_line));
381 #endif /* HAVE_MOTIF */
386 prev_cb (Widget button, XtPointer client_data, XtPointer call_data)
388 saver_info *si = (saver_info *) client_data;
391 XawListReturnStruct *current=XawListShowCurrent(demo_list);
392 if (current->list_index == XAW_LIST_NONE)
393 XawListHighlight(demo_list,1);
396 if (current->list_index>=1)
398 current->list_index--;
399 XawListHighlight(demo_list, current->list_index);
403 ensure_selected_item_visible (demo_list);
404 current = XawListShowCurrent(demo_list);
405 demo_mode_hack (si, current->string);
407 #else /* HAVE_MOTIF */
411 if (! XmListGetSelectedPos (demo_list, &pos_list, &pos_count))
412 XmListSelectPos (demo_list, 0, True);
415 XmListSelectPos (demo_list, pos_list [0] - 1, True);
416 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 */
425 static void pop_resources_dialog (saver_info *si);
426 static void make_resources_dialog (saver_info *si, Widget parent);
429 edit_cb (Widget button, XtPointer client_data, XtPointer call_data)
431 saver_info *si = (saver_info *) client_data;
432 saver_screen_info *ssi = si->default_screen;
433 Widget parent = ssi->toplevel_shell;
434 if (! resources_dialog)
435 make_resources_dialog (si, parent);
436 pop_resources_dialog (si);
440 done_cb (Widget button, XtPointer client_data, XtPointer call_data)
442 saver_info *si = (saver_info *) client_data;
448 restart_cb (Widget button, XtPointer client_data, XtPointer call_data)
450 saver_info *si = (saver_info *) client_data;
451 demo_mode_restart_process (si);
455 pop_up_dialog_box (Widget dialog, Widget form, int where)
457 /* I'm sure this is the wrong way to pop up a dialog box, but I can't
458 figure out how else to do it.
460 It's important that the screensaver dialogs not get decorated or
461 otherwise reparented by the window manager, because they need to be
462 children of the *real* root window, not the WM's virtual root, in
463 order for us to guarentee that they are visible above the screensaver
468 Dimension sw, sh, x, y, w, h;
471 XtRealizeWidget (dialog);
472 #else /* HAVE_MOTIF */
473 /* Motif likes us to realize the *child* of the shell... */
474 XtRealizeWidget (form);
475 #endif /* HAVE_MOTIF */
477 sw = WidthOfScreen (XtScreen (dialog));
478 sh = HeightOfScreen (XtScreen (dialog));
480 XtSetArg (av [ac], XtNwidth, &w); ac++;
481 XtSetArg (av [ac], XtNheight, &h); ac++;
482 XtGetValues (form, av, ac);
494 case 0: /* center it in the top-right quadrant */
495 x = (sw/2 + w) / 2 + (sw/2) - w;
496 y = (sh/2 + h) / 2 - h;
498 case 1: /* center it in the bottom-right quadrant */
499 x = (sw/2 + w) / 2 + (sw/2) - w;
500 y = (sh/2 + h) / 2 + (sh/2) - h;
502 case 2: /* center it on the screen */
503 x = (sw + w) / 2 - w;
504 y = (sh + h) / 2 - h;
509 if (x + w > sw) x = sw - w;
510 if (y + h > sh) y = sh - h;
512 XtSetArg (av [ac], XtNx, x); ac++;
513 XtSetArg (av [ac], XtNy, y); ac++;
514 XtSetArg (av [ac], XtNoverrideRedirect, True); ac++;
517 XtSetArg (av [ac], XmNdefaultPosition, False); ac++;
518 #endif /* HAVE_MOTIF */
520 XtSetValues (dialog, av, ac);
521 XtSetValues (form, av, ac);
524 XtPopup (dialog, XtGrabNone);
525 #else /* HAVE_MOTIF */
526 XtManageChild (form);
527 #endif /* HAVE_MOTIF */
529 steal_focus_and_colormap (dialog);
534 make_screenhack_dialog (saver_info *si)
536 saver_screen_info *ssi = si->default_screen;
537 Widget parent = ssi->toplevel_shell;
538 char **hacks = si->prefs.screenhacks;
540 if (ssi->demo_cmap &&
541 ssi->demo_cmap != ssi->cmap &&
542 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
544 XFreeColormap (si->dpy, ssi->demo_cmap);
548 if (ssi->default_visual == DefaultVisualOfScreen (ssi->screen))
549 ssi->demo_cmap = DefaultColormapOfScreen (ssi->screen);
551 ssi->demo_cmap = XCreateColormap (si->dpy,
552 RootWindowOfScreen (ssi->screen),
553 ssi->default_visual, AllocNone);
555 create_demo_dialog (parent, ssi->default_visual, ssi->demo_cmap);
556 format_into_label (label1, si->version);
558 add_button_callback (next, next_cb, (XtPointer) si);
559 add_button_callback (prev, prev_cb, (XtPointer) si);
560 add_button_callback (done, done_cb, (XtPointer) si);
561 add_button_callback (restart, restart_cb, (XtPointer) si);
562 add_button_callback (edit, edit_cb, (XtPointer) si);
565 XtAddCallback (demo_list, XmNbrowseSelectionCallback,
566 select_cb, (XtPointer) si);
567 XtAddCallback (demo_list, XmNdefaultActionCallback,
568 select_cb, (XtPointer) si);
569 XtAddCallback (text_line, XmNactivateCallback, text_cb, (XtPointer) si);
571 for (; *hacks; hacks++)
573 XmString xmstr = XmStringCreate (*hacks, XmSTRING_DEFAULT_CHARSET);
574 XmListAddItem (demo_list, xmstr, 0);
575 XmStringFree (xmstr);
578 #else /* HAVE_ATHENA */
580 XtVaSetValues (demo_list,
582 XtNnumberStrings, si->prefs.screenhacks_count,
584 XtAddCallback (demo_list, XtNcallback, select_cb, si);
586 #endif /* HAVE_ATHENA */
588 pop_up_dialog_box(demo_dialog, demo_form,
590 (si->prefs.debug_p ? 69 : 0) +
596 /* the Screensaver Parameters dialog */
598 static struct resources {
599 int timeout, cycle, secs, ticks, lock_time, passwd_time;
600 int verb, cmap, fade, unfade, lock_p;
605 hack_time_cb (Display *dpy, char *line, int *store, Bool sec_p)
610 value = parse_time (line, sec_p, True);
619 res_sec_cb (Widget button, XtPointer client_data, XtPointer call_data)
621 hack_time_cb (XtDisplay (button), get_text_string (button),
622 (int *) client_data, True);
626 res_min_cb (Widget button, XtPointer client_data, XtPointer call_data)
628 hack_time_cb (XtDisplay (button), get_text_string (button),
629 (int *) client_data, False);
633 res_int_cb (Widget button, XtPointer client_data, XtPointer call_data)
635 char *line = get_text_string (button);
636 int *store = (int *) client_data;
641 else if (sscanf (line, "%u%c", &value, &c) != 1)
642 XBell (XtDisplay (button), 0);
648 res_bool_cb (Widget button, XtPointer client_data, XtPointer call_data)
650 int *store = (int *) client_data;
652 *store = ((XmToggleButtonCallbackStruct *) call_data)->set;
653 #else /* HAVE_ATHENA */
654 Boolean state = FALSE;
655 XtVaGetValues (button, XtNstate, &state, NULL);
657 #endif /* HAVE_ATHENA */
661 res_cancel_cb (Widget button, XtPointer client_data, XtPointer call_data)
663 XtDestroyWidget (resources_dialog);
664 resources_dialog = 0;
665 raise_screenhack_dialog ();
670 res_done_cb (Widget button, XtPointer client_data, XtPointer call_data)
672 saver_info *si = (saver_info *) client_data;
673 saver_preferences *p = &si->prefs;
675 res_cancel_cb (button, client_data, call_data);
678 /* Check all text widgets, since we don't have callbacks for these. */
679 res_min_cb (timeout_text, (XtPointer) &res.timeout, NULL);
680 res_min_cb (cycle_text, (XtPointer) &res.cycle, NULL);
681 res_sec_cb (fade_text, (XtPointer) &res.secs, NULL);
682 res_int_cb (ticks_text, (XtPointer) &res.ticks, NULL);
683 res_min_cb (lock_time_text, (XtPointer) &res.lock_time, NULL);
684 res_sec_cb (passwd_time_text, (XtPointer) &res.passwd_time, NULL);
685 #endif /* HAVE_ATHENA */
687 /* Throttle the timeouts to minimum sane values. */
688 if (res.timeout < 5) res.timeout = 5;
689 if (res.cycle < 2) res.cycle = 2;
690 if (res.passwd_time < 10) res.passwd_time = 10;
692 p->timeout = res.timeout * 1000;
693 p->cycle = res.cycle * 1000;
694 p->lock_timeout = res.lock_time * 1000;
696 p->passwd_timeout = res.passwd_time * 1000;
698 p->fade_seconds = res.secs;
699 p->fade_ticks = res.ticks;
700 p->verbose_p = res.verb;
701 p->install_cmap_p = res.cmap;
702 p->fade_p = res.fade;
703 p->unfade_p = res.unfade;
704 p->lock_p = res.lock_p;
707 if (p->debug_p && p->verbose_p)
708 fprintf (stderr, "%s: parameters changed:\n\
709 timeout: %d\n\tcycle: %d\n\tlock: %d\n\tpasswd: %d\n\
710 fade: %d\n\tfade: %d\n\tverbose: %d\n\tinstall: %d\n\
711 fade: %d\n\tunfade: %d\n\tlock: %d\n",
712 progname, p->timeout, p->cycle, p->lock_timeout,
718 p->fade_seconds, p->fade_ticks, p->verbose_p, p->install_cmap_p,
719 p->fade_p, p->unfade_p, p->lock_p);
722 #if defined(HAVE_MIT_SAVER_EXTENSION) || defined(HAVE_SGI_SAVER_EXTENSION)
723 if (p->use_mit_saver_extension || p->use_sgi_saver_extension)
725 /* Need to set the server timeout to the new one the user has picked.
727 int server_timeout, server_interval, prefer_blank, allow_exp;
728 XGetScreenSaver (si->dpy, &server_timeout, &server_interval,
729 &prefer_blank, &allow_exp);
730 if (server_timeout != (p->timeout / 1000))
732 server_timeout = (p->timeout / 1000);
735 "%s: configuring server for saver timeout of %d seconds.\n",
736 progname, server_timeout);
737 /* Leave all other parameters the same. */
738 XSetScreenSaver (si->dpy, server_timeout, server_interval,
739 prefer_blank, allow_exp);
742 #endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */
747 make_resources_dialog (saver_info *si, Widget parent)
749 saver_screen_info *ssi = si->default_screen;
751 if (ssi->demo_cmap &&
752 ssi->demo_cmap != ssi->cmap &&
753 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
755 XFreeColormap (si->dpy, ssi->demo_cmap);
759 if (ssi->default_visual == DefaultVisualOfScreen (ssi->screen))
760 ssi->demo_cmap = DefaultColormapOfScreen (ssi->screen);
762 ssi->demo_cmap = XCreateColormap (si->dpy,
763 RootWindowOfScreen (ssi->screen),
764 ssi->default_visual, AllocNone);
766 create_resources_dialog (parent, ssi->default_visual, ssi->demo_cmap);
768 add_button_callback (res_done, res_done_cb, (XtPointer) si);
769 add_button_callback (res_cancel, res_cancel_cb, (XtPointer) si);
771 #define CB(widget,type,slot) \
772 add_text_callback ((widget), (type), (XtPointer) (slot))
773 #define CBT(widget,type,slot) \
774 add_toggle_callback ((widget), (type), (XtPointer) (slot))
777 /* When using Athena widgets, we can't set callbacks for these,
778 so we'll check them all if "done" gets pressed.
780 CB (timeout_text, res_min_cb, &res.timeout);
781 CB (cycle_text, res_min_cb, &res.cycle);
782 CB (fade_text, res_sec_cb, &res.secs);
783 CB (ticks_text, res_int_cb, &res.ticks);
784 CB (lock_time_text, res_min_cb, &res.lock_time);
785 CB (passwd_time_text, res_sec_cb, &res.passwd_time);
786 #endif /* HAVE_MOTIF */
788 CBT (verbose_toggle, res_bool_cb, &res.verb);
789 CBT (cmap_toggle, res_bool_cb, &res.cmap);
790 CBT (fade_toggle, res_bool_cb, &res.fade);
791 CBT (unfade_toggle, res_bool_cb, &res.unfade);
792 CBT (lock_toggle, res_bool_cb, &res.lock_p);
796 if (si->locking_disabled_p)
798 disable_widget (passwd_time_text);
799 disable_widget (lock_time_text);
800 disable_widget (lock_toggle);
802 if (CellsOfScreen (XtScreen (parent)) <= 2)
804 disable_widget (fade_text);
805 disable_widget (ticks_text);
806 disable_widget (cmap_toggle);
807 disable_widget (fade_toggle);
808 disable_widget (unfade_toggle);
814 fmt_time (char *buf, unsigned int s, int min_p)
816 unsigned int h = 0, m = 0;
828 if (min_p && h == 0 && s == 0)
829 sprintf (buf, "%u", m);
830 else if (!min_p && h == 0 && m == 0)
831 sprintf (buf, "%u", s);
834 sprintf (buf, "%u:%02u", m, s);
837 sprintf (buf, "%u:%02u:%02u", h, m, s);
841 pop_resources_dialog (saver_info *si)
843 saver_preferences *p = &si->prefs;
846 res.timeout = p->timeout / 1000;
847 res.cycle = p->cycle / 1000;
848 res.lock_time = p->lock_timeout / 1000;
850 res.passwd_time = p->passwd_timeout / 1000;
852 res.secs = p->fade_seconds;
853 res.ticks = p->fade_ticks;
854 res.verb = p->verbose_p;
855 res.cmap = p->install_cmap_p;
856 res.fade = p->fade_p;
857 res.unfade = p->unfade_p;
858 res.lock_p = (p->lock_p && !si->locking_disabled_p);
860 fmt_time (buf, res.timeout, 1); set_text_string (timeout_text, buf);
861 fmt_time (buf, res.cycle, 1); set_text_string (cycle_text, buf);
862 fmt_time (buf, res.lock_time, 1); set_text_string (lock_time_text, buf);
863 fmt_time (buf, res.passwd_time, 0); set_text_string (passwd_time_text, buf);
864 fmt_time (buf, res.secs, 0); set_text_string (fade_text, buf);
865 sprintf (buf, "%u", res.ticks); set_text_string (ticks_text, buf);
867 set_toggle_button_state (verbose_toggle, res.verb);
868 set_toggle_button_state (cmap_toggle, res.cmap);
869 set_toggle_button_state (fade_toggle, res.fade);
870 set_toggle_button_state (unfade_toggle, res.unfade);
871 set_toggle_button_state (lock_toggle, res.lock_p);
873 pop_up_dialog_box (resources_dialog, resources_form,
875 (si->prefs.debug_p ? 69 : 0) +
881 /* The main demo-mode command loop.
885 demo_mode (saver_info *si)
887 saver_preferences *p = &si->prefs;
888 si->dbox_up_p = True;
889 initialize_screensaver_window (si);
890 raise_window (si, True, False, False);
891 make_screenhack_dialog (si);
892 while (si->demo_mode_p)
895 XtAppNextEvent (si->app, &event);
896 switch (event.xany.type)
898 case 0: /* synthetic "timeout" event */
902 handle_clientmessage (si, &event, False);
906 if (!p->use_xidle_extension &&
907 !p->use_mit_saver_extension &&
908 !p->use_sgi_saver_extension)
910 start_notice_events_timer (si, event.xcreatewindow.window);
913 printf ("%s: starting notice_events_timer for 0x%X (%lu)\n",
915 (unsigned int) event.xcreatewindow.window,
916 p->notice_events_timeout);
917 #endif /* DEBUG_TIMERS */
923 if (!XtWindowToWidget (si->dpy, event.xbutton.window))
924 raise_screenhack_dialog ();
928 #ifdef HAVE_MIT_SAVER_EXTENSION
929 if (event.type == si->mit_saver_ext_event_number)
931 /* Get the "real" server window(s) out of the way as soon
934 for (i = 0; i < si->nscreens; i++)
936 saver_screen_info *ssi = &si->screens[i];
937 if (ssi->server_mit_saver_window &&
938 window_exists_p (si->dpy, ssi->server_mit_saver_window))
939 XUnmapWindow (si->dpy, ssi->server_mit_saver_window);
943 #endif /* HAVE_MIT_SAVER_EXTENSION */
945 XtDispatchEvent (&event);
949 destroy_screenhack_dialogs (si);
950 initialize_screensaver_window (si);
952 si->demo_mode_p = True; /* kludge to inhibit unfade... */
954 si->demo_mode_p = False;
958 demo_mode_hack (saver_info *si, char *hack)
960 if (! si->demo_mode_p) abort ();
961 kill_screenhack (si);
964 si->demo_hack = hack;
965 spawn_screenhack (si, False);
966 /* raise_screenhack_dialog(); */
970 demo_mode_done (saver_info *si)
972 kill_screenhack (si);
975 si->demo_mode_p = False;
976 si->dbox_up_p = False;