http://ftp.x.org/contrib/applications/xscreensaver-3.07.tar.gz
[xscreensaver] / hacks / flame.c
index d723f055e8cee09572da6171878936590a477f99..ffadb67a601ff5f02cfcc50ebd69709383ff9964 100644 (file)
@@ -1,5 +1,5 @@
-/* xscreensaver, Copyright (c) 1993, 1995, 1996
- *  Jamie Zawinski <jwz@netscape.com>
+/* xscreensaver, Copyright (c) 1993, 1995, 1996, 1998
+ *  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
@@ -52,6 +52,8 @@
 #include <math.h>
 #include "screenhack.h"
 
+#include <signal.h>            /* so we can ignore SIGFPE */
+
 #define POINT_BUFFER_SIZE 10
 #define MAXLEV 4
 #define MAXKINDS  10
@@ -100,6 +102,15 @@ init_flame (Display *dpy, Window window)
   XGCValues gcv;
   XWindowAttributes xgwa;
   Colormap cmap;
+
+#if defined(SIGFPE) && defined(SIG_IGN)
+  /* No doubt a better fix would be to track down where the NaN is coming
+     from, and code around that; but this should do.  Apparently most systems
+     (Linux, Solaris, Irix, ...) ignore FPE by default -- but FreeBSD dumps
+     core by default. */
+  signal (SIGFPE, SIG_IGN);
+#endif
+
   XGetWindowAttributes (dpy, window, &xgwa);
   width = xgwa.width;
   height = xgwa.height;
@@ -167,7 +178,7 @@ recurse (double x, double y, int l, Display *dpy, Window win)
              XDrawPoints (dpy, win, gc, points, num_points, CoordModeOrigin);
              num_points = 0;
              /* if (delay) usleep (delay); */
-             /* XSync (dpy, True); */
+             /* XSync (dpy, False); */
            }
        }
     }
@@ -175,6 +186,14 @@ recurse (double x, double y, int l, Display *dpy, Window win)
     {
       for (i = 0; i < snum; i++)
        {
+
+         /* Scale back when values get very large. Spot sez:
+            "I think this happens on HPUX.  I think it's non-IEEE
+            to generate an exception instead of a silent NaN."
+          */
+         if ((abs(x) > 1.0E5) || (abs(y) > 1.0E5))
+           x = x / y;
+
          nx = f[0][0][i] * x + f[0][1][i] * y + f[0][2][i];
          ny = f[1][0][i] * x + f[1][1][i] * y + f[1][2][i];
          if (i < anum)
@@ -348,7 +367,7 @@ flame (Display *dpy, Window window)
   total_points = 0;
   (void) recurse (0.0, 0.0, 0, dpy, window);
   XDrawPoints (dpy, window, gc, points, num_points, CoordModeOrigin);
-  XSync (dpy, True);
+  XSync (dpy, False);
   if (delay) usleep (delay);
 }
 
@@ -373,8 +392,8 @@ int matherr(x)
 char *progclass = "Flame";
 
 char *defaults [] = {
-  "Flame.background:   black",         /* to placate SGI */
-  "Flame.foreground:   white",
+  ".background:        black",
+  ".foreground:        white",
   "*colors:    64",
   "*iterations:        25",
   "*delay:     50000",
@@ -397,5 +416,8 @@ screenhack (Display *dpy, Window window)
 {
   init_flame (dpy, window);
   while (1)
-    flame (dpy, window);
+    {
+      flame (dpy, window);
+      screenhack_handle_events (dpy);
+    }
 }