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>
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 #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);
495 /* for debugging -- don't ask */
504 case 0: /* center it in the top-right quadrant */
505 x = (sw/2 + w) / 2 + (sw/2) - w;
506 y = (sh/2 + h) / 2 - h;
508 case 1: /* center it in the bottom-right quadrant */
509 x = (sw/2 + w) / 2 + (sw/2) - w;
510 y = (sh/2 + h) / 2 + (sh/2) - h;
512 case 2: /* center it on the screen */
513 x = (sw + w) / 2 - w;
514 y = (sh + h) / 2 - h;
519 if (x + w > sw) x = sw - w;
520 if (y + h > sh) y = sh - h;
522 XtSetArg (av [ac], XtNx, x); ac++;
523 XtSetArg (av [ac], XtNy, y); ac++;
524 XtSetArg (av [ac], XtNoverrideRedirect, True); ac++;
527 XtSetArg (av [ac], XmNdefaultPosition, False); ac++;
528 #endif /* HAVE_MOTIF */
530 XtSetValues (dialog, av, ac);
531 XtSetValues (form, av, ac);
534 XtPopup (dialog, XtGrabNone);
535 #else /* HAVE_MOTIF */
536 XtManageChild (form);
537 #endif /* HAVE_MOTIF */
539 steal_focus_and_colormap (dialog);
544 make_screenhack_dialog (saver_info *si)
546 saver_screen_info *ssi = si->default_screen;
547 Widget parent = ssi->toplevel_shell;
548 char **hacks = si->prefs.screenhacks;
550 if (ssi->demo_cmap &&
551 ssi->demo_cmap != ssi->cmap &&
552 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
554 XFreeColormap (si->dpy, ssi->demo_cmap);
558 if (ssi->default_visual == DefaultVisualOfScreen (ssi->screen))
559 ssi->demo_cmap = DefaultColormapOfScreen (ssi->screen);
561 ssi->demo_cmap = XCreateColormap (si->dpy,
562 RootWindowOfScreen (ssi->screen),
563 ssi->default_visual, AllocNone);
565 create_demo_dialog (parent, ssi->default_visual, ssi->demo_cmap);
566 format_into_label (label1, si->version);
568 add_button_callback (next, next_cb, (XtPointer) si);
569 add_button_callback (prev, prev_cb, (XtPointer) si);
570 add_button_callback (done, done_cb, (XtPointer) si);
571 add_button_callback (restart, restart_cb, (XtPointer) si);
572 add_button_callback (edit, edit_cb, (XtPointer) si);
575 XtAddCallback (demo_list, XmNbrowseSelectionCallback,
576 select_cb, (XtPointer) si);
577 XtAddCallback (demo_list, XmNdefaultActionCallback,
578 select_cb, (XtPointer) si);
579 XtAddCallback (text_line, XmNactivateCallback, text_cb, (XtPointer) si);
581 for (; *hacks; hacks++)
583 XmString xmstr = XmStringCreate (*hacks, XmSTRING_DEFAULT_CHARSET);
584 XmListAddItem (demo_list, xmstr, 0);
585 XmStringFree (xmstr);
588 /* Cause the most-recently-run hack to be selected in the list.
589 Do some voodoo to make it be roughly centered in the list (really,
590 just make it not be within +/- 5 of the top/bottom if possible.)
592 if (ssi->current_hack > 0)
594 int i = ssi->current_hack+1;
597 if (bot < 1) bot = 1;
598 if (top > si->prefs.screenhacks_count)
599 top = si->prefs.screenhacks_count;
601 XmListDeselectAllItems(demo_list); /* LessTif lossage */
602 XmListSelectPos (demo_list, bot, False);
603 ensure_selected_item_visible (demo_list);
605 XmListDeselectAllItems(demo_list); /* LessTif lossage */
606 XmListSelectPos (demo_list, top, False);
607 ensure_selected_item_visible (demo_list);
609 XmListDeselectAllItems(demo_list); /* LessTif lossage */
610 XmListSelectPos (demo_list, i, False);
611 ensure_selected_item_visible (demo_list);
614 #else /* HAVE_ATHENA */
616 XtVaSetValues (demo_list,
618 XtNnumberStrings, si->prefs.screenhacks_count,
620 XtAddCallback (demo_list, XtNcallback, select_cb, si);
622 /* #### still need to do the "select most-recently-run hack"
623 #### thing for Athena.
626 #endif /* HAVE_ATHENA */
628 pop_up_dialog_box(demo_dialog, demo_form,
629 /* for debugging -- don't ask */
630 (si->prefs.debug_p ? 69 : 0) +
635 /* the Screensaver Parameters dialog */
637 static struct resources {
638 int timeout, cycle, secs, ticks, lock_time, passwd_time;
639 int verb, cmap, fade, unfade, lock_p;
644 hack_time_cb (Display *dpy, char *line, int *store, Bool sec_p)
649 value = parse_time (line, sec_p, True);
658 res_sec_cb (Widget button, XtPointer client_data, XtPointer call_data)
660 hack_time_cb (XtDisplay (button), get_text_string (button),
661 (int *) client_data, True);
665 res_min_cb (Widget button, XtPointer client_data, XtPointer call_data)
667 hack_time_cb (XtDisplay (button), get_text_string (button),
668 (int *) client_data, False);
672 res_int_cb (Widget button, XtPointer client_data, XtPointer call_data)
674 char *line = get_text_string (button);
675 int *store = (int *) client_data;
680 else if (sscanf (line, "%u%c", &value, &c) != 1)
681 XBell (XtDisplay (button), 0);
687 res_bool_cb (Widget button, XtPointer client_data, XtPointer call_data)
689 int *store = (int *) client_data;
691 *store = ((XmToggleButtonCallbackStruct *) call_data)->set;
692 #else /* HAVE_ATHENA */
693 Boolean state = FALSE;
694 XtVaGetValues (button, XtNstate, &state, NULL);
696 #endif /* HAVE_ATHENA */
700 res_cancel_cb (Widget button, XtPointer client_data, XtPointer call_data)
702 XtDestroyWidget (resources_dialog);
703 resources_dialog = 0;
704 raise_screenhack_dialog ();
709 res_done_cb (Widget button, XtPointer client_data, XtPointer call_data)
711 saver_info *si = (saver_info *) client_data;
712 saver_preferences *p = &si->prefs;
714 res_cancel_cb (button, client_data, call_data);
717 /* Check all text widgets, since we don't have callbacks for these. */
718 res_min_cb (timeout_text, (XtPointer) &res.timeout, NULL);
719 res_min_cb (cycle_text, (XtPointer) &res.cycle, NULL);
720 res_sec_cb (fade_text, (XtPointer) &res.secs, NULL);
721 res_int_cb (ticks_text, (XtPointer) &res.ticks, NULL);
722 res_min_cb (lock_time_text, (XtPointer) &res.lock_time, NULL);
723 res_sec_cb (passwd_time_text, (XtPointer) &res.passwd_time, NULL);
724 #endif /* HAVE_ATHENA */
726 /* Throttle the timeouts to minimum sane values. */
727 if (res.timeout < 5) res.timeout = 5;
728 if (res.cycle < 2) res.cycle = 2;
729 if (res.passwd_time < 10) res.passwd_time = 10;
731 p->timeout = res.timeout * 1000;
732 p->cycle = res.cycle * 1000;
733 p->lock_timeout = res.lock_time * 1000;
735 p->passwd_timeout = res.passwd_time * 1000;
737 p->fade_seconds = res.secs;
738 p->fade_ticks = res.ticks;
739 p->verbose_p = res.verb;
740 p->install_cmap_p = res.cmap;
741 p->fade_p = res.fade;
742 p->unfade_p = res.unfade;
743 p->lock_p = res.lock_p;
745 if (p->debug_p && p->verbose_p)
746 fprintf (stderr, "%s: parameters changed:\n\
747 timeout: %d\n\tcycle: %d\n\tlock: %d\n\tpasswd: %d\n\
748 fade: %d\n\tfade: %d\n\tverbose: %d\n\tinstall: %d\n\
749 fade: %d\n\tunfade: %d\n\tlock: %d\n",
750 progname, p->timeout, p->cycle, p->lock_timeout,
756 p->fade_seconds, p->fade_ticks, p->verbose_p, p->install_cmap_p,
757 p->fade_p, p->unfade_p, p->lock_p);
760 #if defined(HAVE_MIT_SAVER_EXTENSION) || defined(HAVE_SGI_SAVER_EXTENSION)
761 if (p->use_mit_saver_extension || p->use_sgi_saver_extension)
763 /* Need to set the server timeout to the new one the user has picked.
765 int server_timeout, server_interval, prefer_blank, allow_exp;
766 XGetScreenSaver (si->dpy, &server_timeout, &server_interval,
767 &prefer_blank, &allow_exp);
768 if (server_timeout != (p->timeout / 1000))
770 server_timeout = (p->timeout / 1000);
773 "%s: configuring server for saver timeout of %d seconds.\n",
774 progname, server_timeout);
775 /* Leave all other parameters the same. */
776 XSetScreenSaver (si->dpy, server_timeout, server_interval,
777 prefer_blank, allow_exp);
780 #endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */
785 make_resources_dialog (saver_info *si, Widget parent)
787 saver_screen_info *ssi = si->default_screen;
789 if (ssi->demo_cmap &&
790 ssi->demo_cmap != ssi->cmap &&
791 ssi->demo_cmap != DefaultColormapOfScreen (ssi->screen))
793 XFreeColormap (si->dpy, ssi->demo_cmap);
797 if (ssi->default_visual == DefaultVisualOfScreen (ssi->screen))
798 ssi->demo_cmap = DefaultColormapOfScreen (ssi->screen);
800 ssi->demo_cmap = XCreateColormap (si->dpy,
801 RootWindowOfScreen (ssi->screen),
802 ssi->default_visual, AllocNone);
804 create_resources_dialog (parent, ssi->default_visual, ssi->demo_cmap);
806 add_button_callback (res_done, res_done_cb, (XtPointer) si);
807 add_button_callback (res_cancel, res_cancel_cb, (XtPointer) si);
809 #define CB(widget,type,slot) \
810 add_text_callback ((widget), (type), (XtPointer) (slot))
811 #define CBT(widget,type,slot) \
812 add_toggle_callback ((widget), (type), (XtPointer) (slot))
815 /* When using Athena widgets, we can't set callbacks for these,
816 so we'll check them all if "done" gets pressed.
818 CB (timeout_text, res_min_cb, &res.timeout);
819 CB (cycle_text, res_min_cb, &res.cycle);
820 CB (fade_text, res_sec_cb, &res.secs);
821 CB (ticks_text, res_int_cb, &res.ticks);
822 CB (lock_time_text, res_min_cb, &res.lock_time);
823 CB (passwd_time_text, res_sec_cb, &res.passwd_time);
824 #endif /* HAVE_MOTIF */
826 CBT (verbose_toggle, res_bool_cb, &res.verb);
827 CBT (cmap_toggle, res_bool_cb, &res.cmap);
828 CBT (fade_toggle, res_bool_cb, &res.fade);
829 CBT (unfade_toggle, res_bool_cb, &res.unfade);
830 CBT (lock_toggle, res_bool_cb, &res.lock_p);
834 if (si->locking_disabled_p)
836 disable_widget (passwd_time_text);
837 disable_widget (lock_time_text);
838 disable_widget (lock_toggle);
840 if (CellsOfScreen (XtScreen (parent)) <= 2)
842 disable_widget (fade_text);
843 disable_widget (ticks_text);
844 disable_widget (cmap_toggle);
845 disable_widget (fade_toggle);
846 disable_widget (unfade_toggle);
852 fmt_time (char *buf, unsigned int s, int min_p)
854 unsigned int h = 0, m = 0;
866 if (min_p && h == 0 && s == 0)
867 sprintf (buf, "%u", m);
868 else if (!min_p && h == 0 && m == 0)
869 sprintf (buf, "%u", s);
872 sprintf (buf, "%u:%02u", m, s);
875 sprintf (buf, "%u:%02u:%02u", h, m, s);
879 pop_resources_dialog (saver_info *si)
881 saver_preferences *p = &si->prefs;
884 res.timeout = p->timeout / 1000;
885 res.cycle = p->cycle / 1000;
886 res.lock_time = p->lock_timeout / 1000;
888 res.passwd_time = p->passwd_timeout / 1000;
890 res.secs = p->fade_seconds;
891 res.ticks = p->fade_ticks;
892 res.verb = p->verbose_p;
893 res.cmap = p->install_cmap_p;
894 res.fade = p->fade_p;
895 res.unfade = p->unfade_p;
896 res.lock_p = (p->lock_p && !si->locking_disabled_p);
898 fmt_time (buf, res.timeout, 1); set_text_string (timeout_text, buf);
899 fmt_time (buf, res.cycle, 1); set_text_string (cycle_text, buf);
900 fmt_time (buf, res.lock_time, 1); set_text_string (lock_time_text, buf);
901 fmt_time (buf, res.passwd_time, 0); set_text_string (passwd_time_text, buf);
902 fmt_time (buf, res.secs, 0); set_text_string (fade_text, buf);
903 sprintf (buf, "%u", res.ticks); set_text_string (ticks_text, buf);
905 set_toggle_button_state (verbose_toggle, res.verb);
906 set_toggle_button_state (cmap_toggle, res.cmap);
907 set_toggle_button_state (fade_toggle, res.fade);
908 set_toggle_button_state (unfade_toggle, res.unfade);
909 set_toggle_button_state (lock_toggle, res.lock_p);
911 pop_up_dialog_box (resources_dialog, resources_form,
912 /* for debugging -- don't ask */
913 (si->prefs.debug_p ? 69 : 0) +
918 /* The main demo-mode command loop.
922 demo_mode (saver_info *si)
924 saver_preferences *p = &si->prefs;
925 si->dbox_up_p = True;
926 initialize_screensaver_window (si);
927 raise_window (si, True, False, False);
928 make_screenhack_dialog (si);
929 while (si->demo_mode_p)
932 XtAppNextEvent (si->app, &event);
933 switch (event.xany.type)
935 case 0: /* synthetic "timeout" event */
939 handle_clientmessage (si, &event, False);
943 if (!p->use_xidle_extension &&
944 !p->use_mit_saver_extension &&
945 !p->use_sgi_saver_extension)
947 start_notice_events_timer (si, event.xcreatewindow.window);
950 printf ("%s: starting notice_events_timer for 0x%X (%lu)\n",
952 (unsigned int) event.xcreatewindow.window,
953 p->notice_events_timeout);
954 #endif /* DEBUG_TIMERS */
960 if (!XtWindowToWidget (si->dpy, event.xbutton.window))
961 raise_screenhack_dialog ();
965 #ifdef HAVE_MIT_SAVER_EXTENSION
966 if (event.type == si->mit_saver_ext_event_number)
968 /* Get the "real" server window(s) out of the way as soon
971 for (i = 0; i < si->nscreens; i++)
973 saver_screen_info *ssi = &si->screens[i];
974 if (ssi->server_mit_saver_window &&
975 window_exists_p (si->dpy, ssi->server_mit_saver_window))
976 XUnmapWindow (si->dpy, ssi->server_mit_saver_window);
980 #endif /* HAVE_MIT_SAVER_EXTENSION */
982 XtDispatchEvent (&event);
986 destroy_screenhack_dialogs (si);
987 initialize_screensaver_window (si);
989 si->demo_mode_p = True; /* kludge to inhibit unfade... */
991 si->demo_mode_p = False;
995 demo_mode_hack (saver_info *si, char *hack)
997 if (! si->demo_mode_p) abort ();
998 kill_screenhack (si);
1001 si->demo_hack = hack;
1002 spawn_screenhack (si, False);
1003 /* raise_screenhack_dialog(); */
1007 demo_mode_done (saver_info *si)
1009 kill_screenhack (si);
1011 unblank_screen (si);
1012 si->demo_mode_p = False;
1013 si->dbox_up_p = False;