From http://www.jwz.org/xscreensaver/xscreensaver-5.18.tar.gz
[xscreensaver] / driver / xscreensaver.c
index 2fdc4ac6d20b5a04ae6ff66f14ec8cedf854274a..ed5bf3032fbc7e86b1c477c304ae22dc23491b7f 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1991-2011 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1991-2012 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
@@ -299,14 +299,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 */
@@ -1191,6 +1205,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,10 +1245,22 @@ main_loop (saver_info *si)
         for (i = 0; i < si->nscreens; i++)
           spawn_screenhack (&si->screens[i]);
 
-      /* If we are blanking only, we might as well power down the monitor
-         right now, regardless of what the DPMS settings are. */
-      if (p->mode == BLANK_ONLY)
-        monitor_power_on (si, False);
+      /* If we are blanking only, optionally power down monitor right now.
+         To do this, we might need to temporarily re-enable DPMS first.
+       */
+      if (p->mode == BLANK_ONLY &&
+          p->dpms_enabled_p && 
+          p->dpms_quickoff_p)
+        {
+          sync_server_dpms_settings (si->dpy, True,
+                                     p->dpms_standby / 1000,
+                                     p->dpms_suspend / 1000,
+                                     (p->dpms_off
+                                      ? (p->dpms_off / 1000)
+                                      : 0xFFFF),
+                                     False);
+          monitor_power_on (si, False);
+        }
 
       /* Don't start the cycle timer in demo mode. */
       if (!si->demoing_p && p->cycle)
@@ -1387,18 +1417,28 @@ main (int argc, char **argv)
   struct passwd *spasswd;
   int i;
 
-  /* It turns out that if we do NLS stuff here, people running in Japanese
-     locales get font craziness on the password dialog, presumably because
-     it is displaying Japanese characters in a non-Japanese font.  I don't
-     understand how to automatically make all this crap work properly by
-     default, so until someone sends me a better patch, just leave it off
-     and run the daemon in English.  -- jwz, 29-Sep-2010
-   */
-#undef ENABLE_NLS
+  /* It turns out that if we do setlocale (LC_ALL, "") here, people
+     running in Japanese locales get font craziness on the password
+     dialog, presumably because it is displaying Japanese characters
+     in a non-Japanese font.  However, if we don't call setlocale()
+     at all, then XLookupString() never returns multi-byte UTF-8
+     characters when people type non-Latin1 characters on the
+     keyboard.
+
+     The current theory (and at this point, I'm really guessing!) is
+     that using LC_CTYPE instead of LC_ALL will make XLookupString()
+     behave usefully, without having the side-effect of screwing up
+     the fonts on the unlock dialog.
 
+     See https://bugs.launchpad.net/ubuntu/+source/xscreensaver/+bug/671923
+     from comment #20 onward.
+
+       -- jwz, 24-Sep-2011
+   */
 #ifdef ENABLE_NLS
-  if (!setlocale (LC_ALL, ""))
-    fprintf (stderr, "locale not supported by C library\n");
+  if (!setlocale (LC_CTYPE, ""))
+    fprintf (stderr, "%s: warning: could not set default locale\n",
+             progname);
 
   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
   textdomain (GETTEXT_PACKAGE);