http://www.jwz.org/xscreensaver/xscreensaver-5.13.tar.gz
[xscreensaver] / utils / fade.c
index 18e940680a1fb8d607118d66ac68e57058a12f23..7a2ce2be92ab43ccaff9b0934198a4ada829bda3 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992-2003 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2011 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
@@ -157,9 +157,31 @@ fade_screens (Display *dpy, Colormap *cmaps,
 }
 
 
+static void
+sleep_from (struct timeval *now, struct timeval *then, long usecs_per_step)
+{
+  /* If several seconds have passed, the machine must have been asleep
+     or thrashing or something.  Don't sleep in that case, to avoid
+     overflowing and sleeping for an unconscionably long time.  This
+     function should only be sleeping for very short periods.
+   */
+  if (now->tv_sec - then->tv_sec < 5)
+    {
+      long diff = (((now->tv_sec - then->tv_sec) * 1000000) +
+                   now->tv_usec - then->tv_usec);
+      if (usecs_per_step > diff)
+        usleep (usecs_per_step - diff);
+    }
+
+  then->tv_sec  = now->tv_sec;
+  then->tv_usec = now->tv_usec;
+}
+
+
+
 /* The business with `cmaps_per_screen' is to fake out the SGI 8-bit video
    hardware, which is capable of installing multiple (4) colormaps
-   simultaniously.  We have to install multiple copies of the same set of
+   simultaneously.  We have to install multiple copies of the same set of
    colors in order to fill up all the available slots in the hardware color
    lookup table, so we install an extra N colormaps per screen to make sure
    that all screens really go black.
@@ -329,14 +351,7 @@ fade_screens_1 (Display *dpy, Colormap *cmaps,
 
       /* If we haven't already used up our alotted time, sleep to avoid
         changing the colormap too fast. */
-      {
-       long diff = (((now.tv_sec - then.tv_sec) * 1000000) +
-                    now.tv_usec - then.tv_usec);
-       then.tv_sec = now.tv_sec;
-       then.tv_usec = now.tv_usec;
-       if (usecs_per_step > diff)
-         usleep (usecs_per_step - diff);
-      }
+      sleep_from (&now, &then, usecs_per_step);
     }
 
  DONE:
@@ -530,14 +545,7 @@ sgi_gamma_fade (Display *dpy,
 
          /* If we haven't already used up our alotted time, sleep to avoid
             changing the colormap too fast. */
-         {
-           long diff = (((now.tv_sec - then.tv_sec) * 1000000) +
-                        now.tv_usec - then.tv_usec);
-           then.tv_sec = now.tv_sec;
-           then.tv_usec = now.tv_usec;
-           if (usecs_per_step > diff)
-             usleep (usecs_per_step - diff);
-         }
+          sleep_from (&now, &then, usecs_per_step);
        }
     }
   
@@ -757,14 +765,7 @@ xf86_gamma_fade (Display *dpy,
 
          /* If we haven't already used up our alotted time, sleep to avoid
             changing the colormap too fast. */
-         {
-           long diff = (((now.tv_sec - then.tv_sec) * 1000000) +
-                        now.tv_usec - then.tv_usec);
-           then.tv_sec = now.tv_sec;
-           then.tv_usec = now.tv_usec;
-           if (usecs_per_step > diff)
-             usleep (usecs_per_step - diff);
-         }
+          sleep_from (&now, &then, usecs_per_step);
        }
     }
   
@@ -899,6 +900,11 @@ xf86_whack_gamma(Display *dpy, int screen, xf86_gamma_info *info,
 {
   Bool status;
 
+  XErrorHandler old_handler;
+  XSync (dpy, False);
+  error_handler_hit_p = False;
+  old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
+
   if (ratio < 0) ratio = 0;
   if (ratio > 1) ratio = 1;
 
@@ -946,7 +952,10 @@ xf86_whack_gamma(Display *dpy, int screen, xf86_gamma_info *info,
 # endif /* !HAVE_XF86VMODE_GAMMA_RAMP */
     }
 
-  XSync(dpy, False);
+  XSync (dpy, False);
+  XSetErrorHandler (old_handler);
+  XSync (dpy, False);
+
   return status;
 }