From http://www.jwz.org/xscreensaver/xscreensaver-5.27.tar.gz
[xscreensaver] / driver / xscreensaver.c
index c608b76402a4318867a403e1e0574fdb80536be1..4526f27247380f6ebbbe0557d66e7e62663d38fa 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1991-2011 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1991-2013 Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -271,17 +271,24 @@ ERROR!  You must not include vroot.h in this file.
 static void
 do_help (saver_info *si)
 {
+  char *s, year[5];
+  s = strchr (screensaver_id, '-');
+  s = strrchr (s, '-');
+  s++;
+  strncpy (year, s, 4);
+  year[4] = 0;
+
   fflush (stdout);
   fflush (stderr);
   fprintf (stdout, "\
-xscreensaver %s, copyright (c) 1991-2008 by Jamie Zawinski <jwz@jwz.org>\n\
+xscreensaver %s, copyright (c) 1991-%s by Jamie Zawinski <jwz@jwz.org>\n\
 \n\
   All xscreensaver configuration is via the `~/.xscreensaver' file.\n\
   Rather than editing that file by hand, just run `xscreensaver-demo':\n\
   that program lets you configure the screen saver graphically,\n\
   including timeouts, locking, and display modes.\n\
 \n",
-         si->version);
+         si->version, year);
   fprintf (stdout, "\
   Just getting started?  Try this:\n\
 \n\
@@ -299,14 +306,28 @@ xscreensaver %s, copyright (c) 1991-2008 by Jamie Zawinski <jwz@jwz.org>\n\
 }
 
 
+Bool in_signal_handler_p = 0;  /* I hate C so much... */
+
 char *
 timestring (void)
 {
-  time_t now = time ((time_t *) 0);
-  char *str = (char *) ctime (&now);
-  char *nl = (char *) strchr (str, '\n');
-  if (nl) *nl = 0; /* take off that dang newline */
-  return str;
+  if (in_signal_handler_p)
+    {
+      /* Turns out that ctime() and even localtime_r() call malloc() on Linux!
+         So we can't call them from inside SIGCHLD.  WTF.
+       */
+      static char buf[30];
+      strcpy (buf, "... ... ..   signal ....");
+      return buf;
+    }
+  else
+    {
+      time_t now = time ((time_t *) 0);
+      char *str = (char *) ctime (&now);
+      char *nl = (char *) strchr (str, '\n');
+      if (nl) *nl = 0; /* take off that dang newline */
+      return str;
+    }
 }
 
 static Bool blurb_timestamp_p = True;   /* kludge */
@@ -726,6 +747,13 @@ print_banner (saver_info *si)
 {
   saver_preferences *p = &si->prefs;
 
+  char *s, year[5];
+  s = strchr (screensaver_id, '-');
+  s = strrchr (s, '-');
+  s++;
+  strncpy (year, s, 4);
+  year[4] = 0;
+
   /* This resource gets set some time before the others, so that we know
      whether to print the banner (and so that the banner gets printed before
      any resource-database-related error messages.)
@@ -738,9 +766,9 @@ print_banner (saver_info *si)
 
   if (p->verbose_p)
     fprintf (stderr,
-            "%s %s, copyright (c) 1991-2008 "
+            "%s %s, copyright (c) 1991-%s "
             "by Jamie Zawinski <jwz@jwz.org>.\n",
-            progname, si->version);
+            progname, si->version, year);
 
   if (p->debug_p)
     fprintf (stderr, "\n"
@@ -756,6 +784,17 @@ print_banner (saver_info *si)
             "\n",
             blurb());
 
+  if (p->verbose_p && senescent_p ())
+    fprintf (stderr, "\n"
+             "*************************************"
+             "**************************************\n"
+            "%s: Warning: this version of xscreensaver is VERY OLD!\n"
+            "%s: Please upgrade!  http://www.jwz.org/xscreensaver/\n"
+             "*************************************"
+             "**************************************\n"
+            "\n",
+             blurb(), blurb());
+
   if (p->verbose_p)
     {
       if (!si->uid_message || !*si->uid_message)
@@ -1099,6 +1138,7 @@ maybe_reload_init_file (saver_info *si)
       sync_server_dpms_settings (si->dpy,
                                  (p->dpms_enabled_p  &&
                                   p->mode != DONT_BLANK),
+                                 p->dpms_quickoff_p,
                                  p->dpms_standby / 1000,
                                  p->dpms_suspend / 1000,
                                  p->dpms_off / 1000,
@@ -1191,6 +1231,10 @@ main_loop (saver_info *si)
              we would never be able to un-blank it!  We would never
              see any events, and the display would be wedged.
 
+             In particular, without that keyboard grab, we will be
+             unable to ever read keypresses on the unlock dialog.
+             You can't unlock if you can't type your password.
+
              So, just go around the loop again and wait for the
              next bout of idleness.  (If the user remains idle, we
              will next try to blank the screen again in no more than
@@ -1227,19 +1271,16 @@ main_loop (saver_info *si)
         for (i = 0; i < si->nscreens; i++)
           spawn_screenhack (&si->screens[i]);
 
-      /* If we are blanking only, optionally power down monitor right now.
-         To do this, we might need to temporarily re-enable DPMS first.
-       */
+      /* If we are blanking only, optionally power down monitor right now. */
       if (p->mode == BLANK_ONLY &&
           p->dpms_enabled_p && 
           p->dpms_quickoff_p)
         {
           sync_server_dpms_settings (si->dpy, True,
+                                     p->dpms_quickoff_p,
                                      p->dpms_standby / 1000,
                                      p->dpms_suspend / 1000,
-                                     (p->dpms_off
-                                      ? (p->dpms_off / 1000)
-                                      : 0xFFFF),
+                                     p->dpms_off / 1000,
                                      False);
           monitor_power_on (si, False);
         }
@@ -1495,6 +1536,7 @@ main (int argc, char **argv)
   sync_server_dpms_settings (si->dpy,
                              (p->dpms_enabled_p  &&
                               p->mode != DONT_BLANK),
+                             p->dpms_quickoff_p,
                              p->dpms_standby / 1000,
                              p->dpms_suspend / 1000,
                              p->dpms_off / 1000,
@@ -1759,29 +1801,47 @@ handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p)
     }
   else if (type == XA_DEACTIVATE)
     {
-      if (! until_idle_p)
-       {
-          if (si->throttled_p && p->verbose_p)
-            fprintf (stderr, "%s: unthrottled.\n", blurb());
-         si->throttled_p = False;
+# if 0
+      /* When -deactivate is received while locked, pop up the dialog box
+         instead of just ignoring it.  Some people depend on this behavior
+         to be able to unlock by using e.g. a fingerprint reader without
+         also having to click the mouse first.
+       */
+      if (si->locked_p) 
+        {
+          clientmessage_response(si, window, False,
+              "DEACTIVATE ClientMessage received while locked: ignored.",
+              "screen is locked.");
+        }
+      else
+# endif /* 0 */
+        {
+          if (! until_idle_p)
+            {
+              if (si->throttled_p && p->verbose_p)
+                fprintf (stderr, "%s: unthrottled.\n", blurb());
+              si->throttled_p = False;
 
-         clientmessage_response(si, window, False,
-                                "DEACTIVATE ClientMessage received.",
-                                "deactivating.");
-         if (si->using_mit_saver_extension || si->using_sgi_saver_extension)
-           {
-             XForceScreenSaver (si->dpy, ScreenSaverReset);
-             return False;
-           }
-         else
-           {
-             return True;
-           }
-       }
-      clientmessage_response(si, window, False,
-     "ClientMessage DEACTIVATE received while inactive: resetting idle timer.",
-                            "not active: idle timer reset.");
-      reset_timers (si);
+              clientmessage_response(si, window, False,
+                                     "DEACTIVATE ClientMessage received.",
+                                     "deactivating.");
+              if (si->using_mit_saver_extension ||
+                  si->using_sgi_saver_extension)
+                {
+                  XForceScreenSaver (si->dpy, ScreenSaverReset);
+                  return False;
+                }
+              else
+                {
+                  return True;
+                }
+            }
+          clientmessage_response(si, window, False,
+                          "ClientMessage DEACTIVATE received while inactive: "
+                          "resetting idle timer.",
+                                 "not active: idle timer reset.");
+          reset_timers (si);
+        }
     }
   else if (type == XA_CYCLE)
     {
@@ -2270,11 +2330,13 @@ analyze_display (saver_info *si)
       vi_in.screen = ssi->real_screen_number;
       vi_out = XGetVisualInfo (si->dpy, VisualScreenMask, &vi_in, &out_count);
       if (!vi_out) continue;
-      for (j = 0; j < out_count; j++)
+      for (j = 0; j < out_count; j++) {
+       if (vi_out[j].depth >= 32) continue;
        if (vi_out[j].class == PseudoColor)
          colormapped_depths |= (1 << vi_out[j].depth);
        else
          non_mapped_depths  |= (1 << vi_out[j].depth);
+       }
       XFree ((char *) vi_out);
 
       if (colormapped_depths)