ftp://ftp.uni-heidelberg.de/pub/X11/contrib/applications/xscreensaver-1.27.tar.Z
[xscreensaver] / driver / demo.c
index 0603a03a3c3461b18786d48cd1508bb1dfec1e06..4d4a7b073eb63357e654f10d9d8131b254ca5d7b 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1993 Jamie Zawinski <jwz@lucid.com>
+/* xscreensaver, Copyright (c) 1993-1996 Jamie Zawinski <jwz@netscape.com>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
 #include "xscreensaver.h"
 #include <stdio.h>
 
+#ifdef HAVE_MIT_SAVER_EXTENSION
+extern int mit_saver_ext_event_number;
+extern Window server_mit_saver_window;
+#endif /* HAVE_MIT_SAVER_EXTENSION */
+
+#ifdef HAVE_SGI_SAVER_EXTENSION
+/* extern int sgi_saver_ext_event_number; */
+#endif /* HAVE_SGI_SAVER_EXTENSION */
+
+extern Bool use_mit_saver_extension;
+extern Bool use_sgi_saver_extension;
+
 extern Time timeout, cycle, lock_timeout;
 #ifndef NO_LOCKING
 extern Time passwd_timeout;
@@ -34,6 +46,9 @@ extern Bool lock_p, locking_disabled_p;
 static void demo_mode_hack P((char *));
 static void demo_mode_done P((void));
 
+static void focus_fuckus P((Widget dialog));
+static void text_cb P((Widget button, XtPointer, XtPointer));
+
 extern void demo_mode_restart_process ();
 
 extern Widget demo_dialog;
@@ -102,6 +117,35 @@ select_cb (button, client_data, call_data)
   focus_fuckus (demo_dialog);
 }
 
+static void
+ensure_selected_item_visible (list)
+     Widget list;
+{
+  int *pos_list = 0;
+  int pos_count = 0;
+  if (XmListGetSelectedPos (list, &pos_list, &pos_count) && pos_count > 0)
+    {
+      int top = -2;
+      int visible = 0;
+      XtVaGetValues (list,
+                    XmNtopItemPosition, &top,
+                    XmNvisibleItemCount, &visible,
+                    0);
+      if (pos_list[0] >= top + visible)
+       {
+         int pos = pos_list[0] - visible + 1;
+         if (pos < 0) pos = 0;
+         XmListSetPos (list, pos);
+       }
+      else if (pos_list[0] < top)
+       {
+         XmListSetPos (list, pos_list[0]);
+       }
+    }
+  if (pos_list)
+    XtFree ((char *) pos_list);
+}
+
 static void
 next_cb (button, client_data, call_data)
      Widget button;
@@ -122,6 +166,7 @@ next_cb (button, client_data, call_data)
        XmListSelectPos (demo_list, 1, True);
       XtFree ((char *) pos_list);
     }
+  ensure_selected_item_visible (demo_list);
   text_cb (text_line, 0, 0);
 }
 
@@ -139,6 +184,7 @@ prev_cb (button, client_data, call_data)
       XmListSelectPos (demo_list, pos_list [0] - 1, True);
       XtFree ((char *) pos_list);
     }
+  ensure_selected_item_visible (demo_list);
   text_cb (text_line, 0, 0);
 }
 
@@ -185,7 +231,7 @@ pop_up_dialog_box (dialog, form, where)
      It's important that the screensaver dialogs not get decorated or
      otherwise reparented by the window manager, because they need to be
      children of the *real* root window, not the WM's virtual root, in
-     order for us to guarentee tha they are visible above the screensaver
+     order for us to guarentee that they are visible above the screensaver
      window itself.
    */
   Arg av [100];
@@ -241,7 +287,6 @@ make_screenhack_dialog (parent, hacks)
   Arg av[10];
   int ac;
   char *label;
-  Dimension max_w = 0;
   XmString xm_label = 0;
   XmString new_xm_label;
 
@@ -382,9 +427,10 @@ res_done_cb (button, client_data, call_data)
 {
   res_cancel_cb (button, client_data, call_data);
 
-  if (res.timeout < 10) res.timeout = 10;
+  /* Throttle the timeouts to minimum sane values. */
+  if (res.timeout < 5) res.timeout = 5;
   if (res.cycle < 2) res.cycle = 2;
-  if (res.passwd_time < 2) res.passwd_time = 30;
+  if (res.passwd_time < 10) res.passwd_time = 10;
 
   timeout = res.timeout * 1000;
   cycle = res.cycle * 1000;
@@ -399,6 +445,28 @@ res_done_cb (button, client_data, call_data)
   fade_p = res.fade;
   unfade_p = res.unfade;
   lock_p = res.lock_p;
+
+#if defined(HAVE_MIT_SAVER_EXTENSION) || defined(HAVE_SGI_SAVER_EXTENSION)
+  if (use_mit_saver_extension || use_sgi_saver_extension)
+    {
+      /* Need to set the server timeout to the new one the user has picked.
+       */
+      int server_timeout, server_interval, prefer_blank, allow_exp;
+      XGetScreenSaver (dpy, &server_timeout, &server_interval,
+                      &prefer_blank, &allow_exp);
+      if (server_timeout != (timeout / 1000))
+       {
+         server_timeout = (timeout / 1000);
+         if (verbose_p)
+           fprintf (stderr,
+                  "%s: configuring server for saver timeout of %d seconds.\n",
+                    progname, server_timeout);
+         /* Leave all other parameters the same. */
+         XSetScreenSaver (dpy, server_timeout, server_interval,
+                          prefer_blank, allow_exp);
+       }
+    }
+#endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */
 }
 
 
@@ -522,13 +590,15 @@ Bool demo_mode_p = False;
 
 extern XtAppContext app;
 extern Widget toplevel_shell;
-extern Bool use_xidle;
+extern Bool use_xidle_extension;
+extern Bool use_mit_saver_extension;
+extern Bool use_sgi_saver_extension;
 extern Time notice_events_timeout;
 
 extern char **screenhacks;
 extern char *demo_hack;
 
-extern void notice_events_timer P((XtPointer closure, void *timer));
+extern void notice_events_timer P((XtPointer closure, XtIntervalId *timer));
 extern Bool handle_clientmessage P((/*XEvent *, Bool*/));
 
 void
@@ -552,11 +622,20 @@ demo_mode ()
          break;
 
        case CreateNotify:
-#ifdef HAVE_XIDLE
-         if (! use_xidle)
-#endif
-           XtAppAddTimeOut (app, notice_events_timeout, notice_events_timer,
-                            (XtPointer) event.xcreatewindow.window);
+         if (!use_xidle_extension &&
+             !use_mit_saver_extension &&
+             !use_sgi_saver_extension)
+           {
+             XtAppAddTimeOut (app, notice_events_timeout, notice_events_timer,
+                              (XtPointer) event.xcreatewindow.window);
+#ifdef DEBUG_TIMERS
+             if (verbose_p)
+               printf ("%s: starting notice_events_timer for 0x%X (%lu)\n",
+                       progname,
+                       (unsigned int) event.xcreatewindow.window,
+                       notice_events_timeout);
+#endif /* DEBUG_TIMERS */
+           }
          break;
 
        case ButtonPress:
@@ -566,6 +645,18 @@ demo_mode ()
          /* fall through */
 
        default:
+#ifdef HAVE_MIT_SAVER_EXTENSION
+         if (event.type == mit_saver_ext_event_number)
+           {
+             /* Get the "real" server window out of the way as soon
+                as possible. */
+             if (server_mit_saver_window &&
+                 window_exists_p (dpy, server_mit_saver_window))
+               XUnmapWindow (dpy, server_mit_saver_window);
+           }
+         else
+#endif /* HAVE_MIT_SAVER_EXTENSION */
+
          XtDispatchEvent (&event);
          break;
        }
@@ -585,6 +676,7 @@ demo_mode_hack (hack)
     blank_screen ();
   demo_hack = hack;
   spawn_screenhack (False);
+  /* raise_screenhack_dialog(); */
 }
 
 static void