http://ftp.x.org/contrib/applications/xscreensaver-3.06.tar.gz
authorZygo Blaxell <zblaxell@hungrycats.org>
Mon, 2 Mar 2009 05:42:31 +0000 (00:42 -0500)
committerZygo Blaxell <zblaxell@hungrycats.org>
Mon, 2 Mar 2009 05:42:31 +0000 (00:42 -0500)
-rw-r--r-- 1 zblaxell zblaxell 981196 Nov 21  1998 xscreensaver-3.06.tar.gz
bfd2d8852b00710dec41f2a2e335c008fe0b84de  xscreensaver-3.06.tar.gz

62 files changed:
README
driver/XScreenSaver.ad.in
driver/XScreenSaver_ad.h
driver/windows.c
driver/xscreensaver-command.man
driver/xscreensaver-demo.man
driver/xscreensaver.h
driver/xscreensaver.man
hacks/Makefile.in
hacks/attraction.c
hacks/blitspin.c
hacks/bsod.c
hacks/bubbles.c
hacks/compile_axp.com
hacks/compile_decc.com
hacks/coral.c
hacks/cynosure.c
hacks/decayscreen.c
hacks/deco.c
hacks/distort.c
hacks/epicycle.c
hacks/flame.c
hacks/glx/glplanet.c
hacks/glx/lament.c
hacks/glx/xpm-ximage.c
hacks/goop.c
hacks/greynetic.c
hacks/halo.c
hacks/helix.c
hacks/hypercube.c
hacks/imsmap.c
hacks/interference.c
hacks/jigsaw.c
hacks/kaleidescope.c
hacks/kumppa.c
hacks/lmorph.c
hacks/maze.c
hacks/moire.c
hacks/moire2.c
hacks/munch.c
hacks/noseguy.c
hacks/pedal.c
hacks/pyro.c
hacks/qix.c
hacks/rd-bomb.c
hacks/rocks.c
hacks/rorschach.c
hacks/screenhack.c
hacks/screenhack.h
hacks/slidescreen.c
hacks/sonar.c [new file with mode: 0644]
hacks/sonar.man [new file with mode: 0644]
hacks/starfish.c
hacks/truchet.c
hacks/xjack.c
hacks/xlockmore.c
hacks/xlyap.c
hacks/xroger-hack.c
setup.com
utils/version.h
xscreensaver.lsm
xscreensaver.spec

diff --git a/README b/README
index e866fcaabcc76e6c7e0d1368de19f6cf3d32191e..94da385a119a0aad2e8541ce96be801968c0a01f 100644 (file)
--- a/README
+++ b/README
@@ -77,6 +77,23 @@ http://www.jwz.org/xscreensaver/.
 
                               ============
 
 
                               ============
 
+Changes since 3.05:   * Oops, the "default-n" visual descriptor was broken;
+                        it was always installing a colormap if the
+                        `installColormap' preference was set, meaning that
+                        `xearth', `xv' and friends were using the wrong
+                        colors on 8-bit systems.
+                      * Turned off HAVE_PING in `sonar', since it compiles
+                        on some Linux systems, but not others of similar
+                        vintage...
+Changes since 3.04:   * Fixed an off-by-1 in `distort'.
+                      * Added `sonar' hack.
+                      * New version of `glplanet' (with stars.)
+                      * Made all hacks exit when you type `q' or `ESC' at them,
+                        and made them obey the WM_DELETE_WINDOW ClientMessage.
+                      * Fixed a nonfatal buffer overrun in lament (note:
+                        lament still doesn't work with MesaGL 3.0: it dies in
+                        lambda_textured_triangle1(), which is Mesa's bug, not
+                        mine.)
 Changes since 3.03:   * Added an `xscreensaver.spec' file, to make it easier
                         for other folks to generate RPMs.
                       * Made the password code work on HPUX in the situation
 Changes since 3.03:   * Added an `xscreensaver.spec' file, to make it easier
                         for other folks to generate RPMs.
                       * Made the password code work on HPUX in the situation
index 0fee5d3e1706fab634d14a84a206bc9c46e2ee47..ce557228ca27c077b0ecf0aa02fc8eaa6b9eab8c 100644 (file)
@@ -4,8 +4,8 @@
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
 !            a screen saver and locker for the X window system
 !                            by Jamie Zawinski
 !
-!                              version 3.04
-!                                16-Nov-98
+!                              version 3.06
+!                                22-Nov-98
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at http://www.jwz.org/xscreensaver/
 !
 ! See "man xscreensaver" for more info.  The latest version is always
 ! available at http://www.jwz.org/xscreensaver/
                kumppa -root                                            \n\
                rd-bomb -root                                           \n\
                rd-bomb -root -speed 1 -size 0.1                        \n\
                kumppa -root                                            \n\
                rd-bomb -root                                           \n\
                rd-bomb -root -speed 1 -size 0.1                        \n\
+               sonar -root                                             \n\
                                                                          \
        mono:   rocks -root                                             \n\
        color:  rocks -root -fg darksalmon                              \n\
                                                                          \
        mono:   rocks -root                                             \n\
        color:  rocks -root -fg darksalmon                              \n\
index 61de93c455747af9ead805712175ba7865007e6e..b49fc28b3acdf1fe13b0dc25351c97831ce66e31 100644 (file)
@@ -98,6 +98,7 @@
                kumppa -root                                            \\n\
                rd-bomb -root                                           \\n\
                rd-bomb -root -speed 1 -size 0.1                        \\n\
                kumppa -root                                            \\n\
                rd-bomb -root                                           \\n\
                rd-bomb -root -speed 1 -size 0.1                        \\n\
+               sonar -root                                             \\n\
                                                                          \
        mono:   rocks -root                                             \\n\
        color:  rocks -root -fg darksalmon                              \\n\
                                                                          \
        mono:   rocks -root                                             \\n\
        color:  rocks -root -fg darksalmon                              \\n\
index 73170415be7419b6ee7cbc2fbfc7cbde583c5cb2..e5231fb03270d7ab31c839929d9ef41046d406fe 100644 (file)
@@ -769,7 +769,7 @@ initialize_screensaver_window_1 (saver_screen_info *ssi)
 {
   saver_info *si = ssi->global;
   saver_preferences *p = &si->prefs;
 {
   saver_info *si = ssi->global;
   saver_preferences *p = &si->prefs;
-  Bool install_cmap_p = (ssi->install_cmap_p || p->install_cmap_p);
+  Bool install_cmap_p = ssi->install_cmap_p;   /* not p->install_cmap_p */
 
   /* This resets the screensaver window as fully as possible, since there's
      no way of knowing what some random client may have done to us in the
 
   /* This resets the screensaver window as fully as possible, since there's
      no way of knowing what some random client may have done to us in the
@@ -789,6 +789,7 @@ initialize_screensaver_window_1 (saver_screen_info *ssi)
     ssi->cmap = 0;
 
   if (ssi->current_visual != DefaultVisualOfScreen (ssi->screen))
     ssi->cmap = 0;
 
   if (ssi->current_visual != DefaultVisualOfScreen (ssi->screen))
+    /* It's not the default visual, so we have no choice but to install. */
     install_cmap_p = True;
 
   if (install_cmap_p)
     install_cmap_p = True;
 
   if (install_cmap_p)
@@ -1295,6 +1296,7 @@ select_visual (saver_screen_info *ssi, const char *visual_name)
   got_it = !!new_v;
 
   if (new_v && new_v != DefaultVisualOfScreen(ssi->screen))
   got_it = !!new_v;
 
   if (new_v && new_v != DefaultVisualOfScreen(ssi->screen))
+    /* It's not the default visual, so we have no choice but to install. */
     install_cmap_p = True;
 
   ssi->install_cmap_p = install_cmap_p;
     install_cmap_p = True;
 
   ssi->install_cmap_p = install_cmap_p;
index 5905b85d4fe8f3b96baf899f61928c6834d17586..48f81a35da9d84457813063028ed6e13df8b1216 100644 (file)
@@ -11,7 +11,7 @@
 .if n .sp 1
 .if t .sp .5
 ..
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "16-Nov-98 (3.04)" "X Version 11"
+.TH XScreenSaver 1 "22-Nov-98 (3.06)" "X Version 11"
 .SH NAME
 xscreensaver-command - control a running xscreensaver process
 .SH SYNOPSIS
 .SH NAME
 xscreensaver-command - control a running xscreensaver process
 .SH SYNOPSIS
index 44611dd769e141b03ac0670a7c625dc0942ddb7f..aee5d9e213252c856110e5b9dcd804fa595a375e 100644 (file)
@@ -11,7 +11,7 @@
 .if n .sp 1
 .if t .sp .5
 ..
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "16-Nov-98 (3.04)" "X Version 11"
+.TH XScreenSaver 1 "22-Nov-98 (3.06)" "X Version 11"
 .SH NAME
 xscreensaver-demo - interactively control the background xscreensaver daemon
 .SH SYNOPSIS
 .SH NAME
 xscreensaver-demo - interactively control the background xscreensaver daemon
 .SH SYNOPSIS
index 1926703ca48f413f5380522508601f4abf230255..be09025f7da5f3da5d648fe7902da7db7df89d74 100644 (file)
@@ -176,9 +176,11 @@ struct saver_screen_info {
                                   destroy and recreate it on different
                                   visuals. */
   Colormap cmap;               /* The colormap that goes with the window. */
                                   destroy and recreate it on different
                                   visuals. */
   Colormap cmap;               /* The colormap that goes with the window. */
-  Bool install_cmap_p;         /* whether we should use our own colormap.
-                                  This can be overridden on a per-hack basis.
-                                */
+  Bool install_cmap_p;         /* Whether this screen should have its own
+                                   colormap installed, for whichever of several
+                                   reasons.  This is definitive (even a false
+                                   value here overrides prefs->install_cmap_p.)
+                                 */
   Visual *current_visual;      /* The visual of the window. */
   Visual *default_visual;      /* visual to use when none other specified */
   int current_depth;           /* How deep the visual (and the window) are. */
   Visual *current_visual;      /* The visual of the window. */
   Visual *default_visual;      /* visual to use when none other specified */
   int current_depth;           /* How deep the visual (and the window) are. */
index 94754b17f2fca70865ad0facb7fa392764c7c791..ff978401ea6999d355bc3044fde4c7a6ecee74c0 100644 (file)
@@ -11,7 +11,7 @@
 .if n .sp 1
 .if t .sp .5
 ..
 .if n .sp 1
 .if t .sp .5
 ..
-.TH XScreenSaver 1 "16-Nov-98 (3.04)" "X Version 11"
+.TH XScreenSaver 1 "22-Nov-98 (3.06)" "X Version 11"
 .SH NAME
 xscreensaver - graphics hack and screen locker, launched when the user is idle
 .SH SYNOPSIS
 .SH NAME
 xscreensaver - graphics hack and screen locker, launched when the user is idle
 .SH SYNOPSIS
@@ -967,16 +967,30 @@ The
 .BR mwm (1)
 and
 .BR olwm (1)
 .BR mwm (1)
 and
 .BR olwm (1)
-window managers don't seem to have this problem.  The race condition exists
-because X does not provide a way for an OverrideRedirect window to have its
-own colormap, short of grabbing the server (which is neither a good idea, nor
-really possible with the current design.)  What happens is that, as soon as
-the screensaver installs its colormap, \fBtwm\fP responds to 
-the \fBColormapNotify\fP event that is generated by re-instaling the default
-colormap.  Apparently, \fBtwm\fP doesn't \fIalways\fP do this; it seems to do
-it regularly if the screensaver is activated from a menu item, but seems to
-not do it if the screensaver comes on of its own volition, or is activated
-from another console.  Any thoughts on this problem are welcome...
+window managers don't have this problem.  The race condition exists
+because X (really, ICCCM) does not provide a way for an OverrideRedirect 
+window to have its own colormap, short of grabbing the server (which is 
+neither a good idea, nor really possible with the current design.)  What 
+happens is that, as soon as xscreensaver installs its colormap, \fBtwm\fP 
+responds to the resultant \fBColormapNotify\fP event by re-instaling the 
+default colormap.  Apparently, \fBtwm\fP doesn't \fIalways\fP do this; it 
+seems to do it regularly if the screensaver is activated from a menu item, 
+but seems to not do it if the screensaver comes on of its own volition, or 
+is activated from another console.  
+.RS 8
+.TP 4
+.B Attention, window manager authors!
+You should only call
+.BR XInstallColormap (3)
+in response to user events.  That is, it is appropriate to install a colormap
+in response to \fBFocusIn\fP, \fBFocusOut\fP, \fBEnterNotify\fP, 
+and \fBLeaveNotify\fP events; but it is not appropriate to call it in
+response to \fBColormapNotify\fP events.  If you install colormaps in
+response to \fIapplication\fP actions as well as in response to \fIuser\fP
+actions, then you create the situation where it is impossible for 
+override-redirect applications (such as xscreensaver) to display their
+windows in the proper colors.
+.RE
 .TP 8
 .B Colormap lossage: XV, XAnim, XEarth
 Some programs don't operate properly on visuals other than the default one,
 .TP 8
 .B Colormap lossage: XV, XAnim, XEarth
 Some programs don't operate properly on visuals other than the default one,
@@ -985,8 +999,8 @@ magic "default-n" visual name in the description of the \fBprograms\fP
 resource in the \fIConfiguration\fP section.  When programs only work with
 the default colormap, you need to use a syntax like this:
 .EX
 resource in the \fIConfiguration\fP section.  When programs only work with
 the default colormap, you need to use a syntax like this:
 .EX
-    default-n: xv -root image-1.gif -quit  \\n\\
-    default-n: xearth -nostars -wait 0     \\n\\
+   default-n: xv -root image-1.gif -quit  \\n\\
+   default-n: xearth -nostars -wait 0     \\n\\
 .EE
 It would also work to turn off the \fBinstallColormap\fP option altogether,
 but that would deny extra colors to those programs that \fIcan\fP take
 .EE
 It would also work to turn off the \fBinstallColormap\fP option altogether,
 but that would deny extra colors to those programs that \fIcan\fP take
index de2c10e3f78636ef62d29a953df86d9a28da28fb..78726220a56308b69eb6399b98b070bc6d3994a4 100644 (file)
@@ -80,7 +80,8 @@ SRCS          = attraction.c blitspin.c bouboule.c braid.c bubbles.c \
                  rd-bomb.c coral.c mountain.c triangle.c lissie.c worm.c \
                  rotor.c ant.c xjack.c xlyap.c jigsaw.c xscreensaver-sgigl.c \
                  cynosure.c moire2.c flow.c epicycle.c interference.c \
                  rd-bomb.c coral.c mountain.c triangle.c lissie.c worm.c \
                  rotor.c ant.c xjack.c xlyap.c jigsaw.c xscreensaver-sgigl.c \
                  cynosure.c moire2.c flow.c epicycle.c interference.c \
-                 truchet.c bsod.c crystal.c discrete.c distort.c kumppa.c
+                 truchet.c bsod.c crystal.c discrete.c distort.c kumppa.c \
+                 sonar.c
 
 OBJS           = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
                  bubbles-default.o decayscreen.o deco.o drift.o flag.o \
 
 OBJS           = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
                  bubbles-default.o decayscreen.o deco.o drift.o flag.o \
@@ -94,7 +95,8 @@ OBJS          = attraction.o blitspin.o bouboule.o braid.o bubbles.o \
                  rd-bomb.o coral.o mountain.o triangle.o lissie.o worm.o \
                  rotor.o ant.o xjack.o xlyap.o jigsaw.o xscreensaver-sgigl.o \
                  cynosure.o moire2.o flow.o epicycle.o interference.o \
                  rd-bomb.o coral.o mountain.o triangle.o lissie.o worm.o \
                  rotor.o ant.o xjack.o xlyap.o jigsaw.o xscreensaver-sgigl.o \
                  cynosure.o moire2.o flow.o epicycle.o interference.o \
-                 truchet.o bsod.o crystal.o discrete.o distort.o kumppa.o
+                 truchet.o bsod.o crystal.o discrete.o distort.o kumppa.o \
+                 sonar.o
 
 EXES           = attraction blitspin bouboule braid bubbles decayscreen deco \
                  drift flag flame forest vines galaxy grav greynetic halo \
 
 EXES           = attraction blitspin bouboule braid bubbles decayscreen deco \
                  drift flag flame forest vines galaxy grav greynetic halo \
@@ -104,7 +106,8 @@ EXES                = attraction blitspin bouboule braid bubbles decayscreen deco \
                  slip sphere spiral strange swirl xroger goop starfish munch \
                  fadeplot rd-bomb coral mountain triangle lissie worm rotor \
                  ant xjack xlyap jigsaw cynosure moire2 flow epicycle \
                  slip sphere spiral strange swirl xroger goop starfish munch \
                  fadeplot rd-bomb coral mountain triangle lissie worm rotor \
                  ant xjack xlyap jigsaw cynosure moire2 flow epicycle \
-                 interference truchet bsod crystal discrete distort kumppa
+                 interference truchet bsod crystal discrete distort kumppa \
+                 sonar
 
 HACK_OBJS_1    = $(UTILS_BIN)/resources.o $(UTILS_BIN)/visual.o \
                  $(UTILS_BIN)/usleep.o $(UTILS_BIN)/yarandom.o @XMU_OBJS@
 
 HACK_OBJS_1    = $(UTILS_BIN)/resources.o $(UTILS_BIN)/visual.o \
                  $(UTILS_BIN)/usleep.o $(UTILS_BIN)/yarandom.o @XMU_OBJS@
@@ -127,7 +130,8 @@ MEN         = attraction.man blitspin.man bouboule.man braid.man \
                  rocks.man rorschach.man sierpinski.man slidescreen.man \
                  slip.man sphere.man spiral.man strange.man swirl.man \
                  xroger.man goop.man starfish.man munch.man rd-bomb.man \
                  rocks.man rorschach.man sierpinski.man slidescreen.man \
                  slip.man sphere.man spiral.man strange.man swirl.man \
                  xroger.man goop.man starfish.man munch.man rd-bomb.man \
-                 xjack.man xlyap.man jigsaw.man epicycle.man bsod.man
+                 xjack.man xlyap.man jigsaw.man epicycle.man bsod.man \
+                 sonar.man
 STAR           = *
 EXTRAS         = README Makefile.in xlock_23.h .gdbinit \
                  vidwhacker \
 STAR           = *
 EXTRAS         = README Makefile.in xlock_23.h .gdbinit \
                  vidwhacker \
@@ -452,6 +456,9 @@ distort:             $(HACK_OBJS) distort.o $(GRAB) $(SHM)
 kumppa:                 $(HACK_OBJS) kumppa.o
        $(CC_HACK) -o $@ $(HACK_OBJS) kumppa.o $(HACK_LIBS)
 
 kumppa:                 $(HACK_OBJS) kumppa.o
        $(CC_HACK) -o $@ $(HACK_OBJS) kumppa.o $(HACK_LIBS)
 
+sonar:          $(HACK_OBJS) sonar.o $(COL)
+       $(CC_HACK) -o $@ $(HACK_OBJS) sonar.o $(COL) $(HACK_LIBS)
+
 
 # The rules for those hacks which follow the `xlockmore' API.
 #
 
 # The rules for those hacks which follow the `xlockmore' API.
 #
@@ -1422,4 +1429,13 @@ kumppa.o: $(UTILS_SRC)/hsv.h
 kumppa.o: $(UTILS_SRC)/colors.h
 kumppa.o: $(UTILS_SRC)/grabscreen.h
 kumppa.o: $(UTILS_SRC)/visual.h
 kumppa.o: $(UTILS_SRC)/colors.h
 kumppa.o: $(UTILS_SRC)/grabscreen.h
 kumppa.o: $(UTILS_SRC)/visual.h
+sonar.o: $(srcdir)/screenhack.h
+sonar.o: ../config.h
+sonar.o: $(UTILS_SRC)/yarandom.h
+sonar.o: $(UTILS_SRC)/usleep.h
+sonar.o: $(UTILS_SRC)/resources.h
+sonar.o: $(UTILS_SRC)/hsv.h
+sonar.o: $(UTILS_SRC)/colors.h
+sonar.o: $(UTILS_SRC)/grabscreen.h
+sonar.o: $(UTILS_SRC)/visual.h
 
 
index 4b16af97b9b904d3201a2bd1ce5570065fd265e5..1a84833b80fb89a86becee326877b31260961108 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997
+/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -605,7 +605,7 @@ run_balls (Display *dpy, Window window)
       abort ();
     }
 
       abort ();
     }
 
-  XSync (dpy, True);
+  XSync (dpy, False);
 }
 
 \f
 }
 
 \f
@@ -661,6 +661,7 @@ screenhack (Display *dpy, Window window)
   while (1)
     {
       run_balls (dpy, window);
   while (1)
     {
       run_balls (dpy, window);
+      screenhack_handle_events (dpy);
       if (delay) usleep (delay);
     }
 }
       if (delay) usleep (delay);
     }
 }
index cf2941b5484040a98c5a3e34906e552b0b65244a..1c5272537718321a6dc68c84d9206c324ef7ec12 100644 (file)
@@ -299,6 +299,7 @@ init (void)
 
   display (self);
   XSync(dpy, False);
 
   display (self);
   XSync(dpy, False);
+  screenhack_handle_events (dpy);
 }
 
 static void
 }
 
 static void
@@ -326,7 +327,8 @@ display (Pixmap pixmap)
                  ((xgwa.width-size)>>1)-1, ((xgwa.height-size)>>1)-1,
                  size+2, size+2);
 */
                  ((xgwa.width-size)>>1)-1, ((xgwa.height-size)>>1)-1,
                  size+2, size+2);
 */
-  XSync (dpy, True);
+  XSync (dpy, False);
+  screenhack_handle_events (dpy);
 }
 
 \f
 }
 
 \f
@@ -360,6 +362,7 @@ screenhack (Display *d, Window w)
   while (1)
     {
       rotate ();
   while (1)
     {
       rotate ();
+      screenhack_handle_events (d);
       if (delay2) usleep (delay2);
     }
 }
       if (delay2) usleep (delay2);
     }
 }
index 3f3cd346fb69de8f803e41174e2ddbe5ac1963b2..4e3516059a3e373413111fab029cbf99597c0420 100644 (file)
@@ -157,18 +157,25 @@ double_pixmap(Display *dpy, GC gc, Visual *visual, int depth, Pixmap pixmap,
 static Bool
 bsod_sleep(Display *dpy, int seconds)
 {
 static Bool
 bsod_sleep(Display *dpy, int seconds)
 {
-  XEvent event;
   int q = seconds * 4;
   int q = seconds * 4;
-  int mask = KeyPressMask|ButtonPressMask;
   do
     {
       XSync(dpy, False);
   do
     {
       XSync(dpy, False);
-      if (XCheckMaskEvent(dpy, mask, &event))
-       {
-         while (XCheckMaskEvent(dpy, mask, &event))
-           ;
-         return True;
-       }
+      while (XPending (dpy))
+        {
+          XEvent event;
+          XNextEvent (dpy, &event);
+          if (event.xany.type == KeyPress)
+            {
+              KeySym keysym;
+              char c = 0;
+              XLookupString (&event.xkey, &c, 1, &keysym, 0);
+              if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
+                return True;
+            }
+          screenhack_handle_event (dpy, &event);
+        }
+
       if (q > 0)
        {
          q--;
       if (q > 0)
        {
          q--;
@@ -1031,7 +1038,12 @@ screenhack (Display *dpy, Window window)
   if (delay < 3) delay = 3;
 
   if (!get_boolean_resource ("root", "Boolean"))
   if (delay < 3) delay = 3;
 
   if (!get_boolean_resource ("root", "Boolean"))
-    XSelectInput(dpy, window, KeyPressMask|ButtonPressMask);
+    {
+      XWindowAttributes xgwa;
+      XGetWindowAttributes (dpy, window, &xgwa);
+      XSelectInput (dpy, window,
+                    xgwa.your_event_mask | KeyPressMask | ButtonPressMask);
+    }
 
   while (1)
     {
 
   while (1)
     {
@@ -1053,7 +1065,7 @@ screenhack (Display *dpy, Window window)
       if (loop > 100) j = -1;
       if (loop > 200) exit(-1);
       if (!did) continue;
       if (loop > 100) j = -1;
       if (loop > 200) exit(-1);
       if (!did) continue;
-      XSync (dpy, True);
+      XSync (dpy, False);
       j = i;
       loop = 0;
     }
       j = i;
       loop = 0;
     }
index 735033d191b587f2886a6aed4efa469e53e8cfe7..913fe03726df2c676d19b80902dfd24cbdb2a5db 100644 (file)
@@ -1,6 +1,6 @@
 /* bubbles.c - frying pan / soft drink in a glass simulation */
 
 /* bubbles.c - frying pan / soft drink in a glass simulation */
 
-/*$Id: bubbles.c,v 1.15 1998/06/21 23:49:25 jwz Exp $*/
+/*$Id: bubbles.c,v 1.16 1998/11/19 07:25:01 jwz Exp $*/
 
 /*
  *  Copyright (C) 1995-1996 James Macnicol
 
 /*
  *  Copyright (C) 1995-1996 James Macnicol
@@ -1302,7 +1302,7 @@ bubbles (Display *dpy, Window window)
   add_to_mesh(tmp);
   insert_new_bubble(tmp);
 
   add_to_mesh(tmp);
   insert_new_bubble(tmp);
 
-  XSync (dpy, True);
+  XSync (dpy, False);
 }
 
 
 }
 
 
@@ -1312,6 +1312,7 @@ screenhack (Display *dpy, Window window)
   init_bubbles (dpy, window);
   while (1) {
     bubbles (dpy, window);
   init_bubbles (dpy, window);
   while (1) {
     bubbles (dpy, window);
+    screenhack_handle_events (dpy);
     if (delay)
       usleep(delay);
   }
     if (delay)
       usleep(delay);
   }
index bcfa03f7739d2bf4911632f0a69124f23b6aed01..fc329272e07499fea3ba5d77965253a3bb64cf9e 100644 (file)
@@ -58,6 +58,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SIERPINSKI.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SLIDESCREEN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SLIP.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SIERPINSKI.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SLIDESCREEN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SLIP.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SONAR.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SPHERE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SPIRAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) STARFISH.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SPHERE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SPIRAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) STARFISH.C
index bcfa03f7739d2bf4911632f0a69124f23b6aed01..fc329272e07499fea3ba5d77965253a3bb64cf9e 100644 (file)
@@ -58,6 +58,7 @@ $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SIERPINSKI.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SLIDESCREEN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SLIP.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SIERPINSKI.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SLIDESCREEN.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SLIP.C
+$ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SONAR.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SPHERE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SPIRAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) STARFISH.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SPHERE.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) SPIRAL.C
 $ CC/DECC/PREFIX=ALL/DEFINE=(VMS,HAVE_CONFIG_H,STANDALONE)/INCL=([],[-],[-.UTILS]) STARFISH.C
index 55186747327297fbe731753507d061b0c3815064..7621d5eee4818b4b8b830547f9c77fc24535cf46 100644 (file)
@@ -170,7 +170,7 @@ coral(Display *dpy, Window window)
                  XDrawPoints(dpy, window, draw_gc, pointbuf, npoints,
                              CoordModeOrigin);
                  npoints = 0;
                  XDrawPoints(dpy, window, draw_gc, pointbuf, npoints,
                              CoordModeOrigin);
                  npoints = 0;
-                 XSync(dpy, True);
+                 XSync(dpy, False);
                }
 
                if (color) {
                }
 
                if (color) {
@@ -181,7 +181,7 @@ coral(Display *dpy, Window window)
                 }
 
                 if( 0 == nwalkers ) {
                 }
 
                 if( 0 == nwalkers ) {
-                    XSync(dpy, True);
+                    XSync(dpy, False);
                    free(pointbuf);
                     return;
                 }
                    free(pointbuf);
                     return;
                 }
@@ -217,8 +217,9 @@ coral(Display *dpy, Window window)
            XDrawPoints(dpy, window, draw_gc, pointbuf, npoints,
                        CoordModeOrigin);
            npoints = 0;
            XDrawPoints(dpy, window, draw_gc, pointbuf, npoints,
                        CoordModeOrigin);
            npoints = 0;
-           XSync(dpy, True);
+           XSync(dpy, False);
          }
          }
+          screenhack_handle_events (dpy);
          usleep(delay2);
        }
     }
          usleep(delay2);
        }
     }
@@ -253,6 +254,7 @@ Window window;
     while( 1 ) {
         init_coral(dpy, window);
         coral(dpy, window);
     while( 1 ) {
         init_coral(dpy, window);
         coral(dpy, window);
+        screenhack_handle_events (dpy);
         if( delay ) sleep(delay);
        erase_full_window(dpy, window);
     }
         if( delay ) sleep(delay);
        erase_full_window(dpy, window);
     }
index 568825803ec0d71f114cad10131291a31c26604b..052a9444b35a894d7a1beb3f5aae6dacd4707d48 100644 (file)
@@ -214,6 +214,7 @@ void screenhack(Display *d, Window w)
        }
       paint();
       XSync(dpy, False);
        }
       paint();
       XSync(dpy, False);
+      screenhack_handle_events (dpy);
       if (delay)
        usleep(delay);
     }
       if (delay)
        usleep(delay);
     }
index 7b91f63bbd52b0cc06a25f6fcf68e39b724b96f6..da6a5fef770826f6f955aa050f7a2642bf6850b8 100644 (file)
@@ -207,6 +207,7 @@ screenhack (Display *dpy, Window window)
       for (i = 0; i < 100; i++)
        decay1 (dpy, window);
       XSync(dpy, False);
       for (i = 0; i < 100; i++)
        decay1 (dpy, window);
       XSync(dpy, False);
+      screenhack_handle_events (dpy);
       if (delay) usleep (delay);
     }
 }
       if (delay) usleep (delay);
     }
 }
index 3b49c09a74be7afb589cebaf42908c2b7c459cbc..ae908051f05120448461673190127960ba973ba7 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1997 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1997, 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
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -133,7 +133,8 @@ screenhack (Display *dpy, Window window)
       XFillRectangle(dpy, window, bgc, 0, 0, xgwa.width, xgwa.height);
       deco (dpy, window, xgwa.colormap, fgc, bgc,
            0, 0, xgwa.width, xgwa.height, 0);
       XFillRectangle(dpy, window, bgc, 0, 0, xgwa.width, xgwa.height);
       deco (dpy, window, xgwa.colormap, fgc, bgc,
            0, 0, xgwa.width, xgwa.height, 0);
-      XSync (dpy, True);
+      XSync (dpy, False);
+      screenhack_handle_events (dpy);
 
       if (!delay) continue;
       if (!writable)
 
       if (!delay) continue;
       if (!writable)
@@ -144,6 +145,8 @@ screenhack (Display *dpy, Window window)
          while (start - delay < time((time_t) 0))
            {
              rotate_colors (dpy, xgwa.colormap, colors, ncolors, 1);
          while (start - delay < time((time_t) 0))
            {
              rotate_colors (dpy, xgwa.colormap, colors, ncolors, 1);
+              XSync (dpy, False);
+              screenhack_handle_events (dpy);
              if (cycle_delay)
                usleep (cycle_delay);
            }
              if (cycle_delay)
                usleep (cycle_delay);
            }
index 7eed6281c8b9c4d3ecef180c77956506ae080fd9..dc8852d01cf79db38b4f22763288c675447fa524 100644 (file)
@@ -432,8 +432,8 @@ void reflect_draw(int k)
                        else {
                                int     x = xy_coo[k].x + cx + (lx * rsq / dist);
                                int     y = xy_coo[k].y + cy + (ly * rsq / dist);
                        else {
                                int     x = xy_coo[k].x + cx + (lx * rsq / dist);
                                int     y = xy_coo[k].y + cy + (ly * rsq / dist);
-                               if (x < 0 || x > xgwa.width ||
-                                       y < 0 || y > xgwa.height)
+                               if (x < 0 || x >= xgwa.width ||
+                                       y < 0 || y >= xgwa.height)
                                        XPutPixel( buffer_map, j, i, black_pixel );
                                else
                                        XPutPixel( buffer_map, j, i,
                                        XPutPixel( buffer_map, j, i, black_pixel );
                                else
                                        XPutPixel( buffer_map, j, i,
@@ -592,7 +592,8 @@ void screenhack(Display *dpy, Window window)
                        draw(k);
                }
 
                        draw(k);
                }
 
-               XSync(dpy, True);
+               XSync(dpy, False);
+        screenhack_handle_events (dpy);
                if (delay) usleep(delay);
        }
 
                if (delay) usleep(delay);
        }
 
index eed186ca75551629d9b51cdc336ca949619b3797..b812e6ae38968adb6e036c9b8aed8d5e8e43c294 100644 (file)
@@ -534,6 +534,10 @@ check_events (void)                        /* X event handler [ rhess ] */
            printf("re-mapped!\n");
          unmapped = 0;
          break;
            printf("re-mapped!\n");
          unmapped = 0;
          break;
+
+        default:
+          screenhack_handle_event(dpy, &e);
+          break;
        }
                
       /* If we're unmapped, don't return to the caller.  This
        }
                
       /* If we're unmapped, don't return to the caller.  This
@@ -580,8 +584,11 @@ setup(void)
     }
   else
     {
     }
   else
     {
-      XSelectInput(dpy, window,
-                  ExposureMask|ButtonPressMask|StructureNotifyMask);
+      XWindowAttributes xgwa;
+      XGetWindowAttributes (dpy, window, &xgwa);
+      XSelectInput (dpy, window,
+                    xgwa.your_event_mask | ExposureMask |
+                    ButtonPressMask |StructureNotifyMask);
     }
   
 }
     }
   
 }
@@ -814,6 +821,7 @@ screenhack(Display *disp, Window win)
            {
              XSync (dpy, False);
 
            {
              XSync (dpy, False);
 
+              check_events();
              if (holdtime)
                sleep(holdtime); /* show complete figure for a bit. */
 
              if (holdtime)
                sleep(holdtime); /* show complete figure for a bit. */
 
@@ -821,6 +829,7 @@ screenhack(Display *disp, Window win)
            }
          
          
            }
          
          
+         check_events();
          if (delay)
            usleep (delay);
          
          if (delay)
            usleep (delay);
          
index 521d3cb7400f6b525554d299e770404e56530d22..0cc7f65970fb5f0f8e1ca7d790319e97fb97504c 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1993, 1995, 1996
+/* xscreensaver, Copyright (c) 1993, 1995, 1996, 1998
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -167,7 +167,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); */
              XDrawPoints (dpy, win, gc, points, num_points, CoordModeOrigin);
              num_points = 0;
              /* if (delay) usleep (delay); */
-             /* XSync (dpy, True); */
+             /* XSync (dpy, False); */
            }
        }
     }
            }
        }
     }
@@ -356,7 +356,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);
   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);
 }
 
   if (delay) usleep (delay);
 }
 
@@ -405,5 +405,8 @@ screenhack (Display *dpy, Window window)
 {
   init_flame (dpy, window);
   while (1)
 {
   init_flame (dpy, window);
   while (1)
-    flame (dpy, window);
+    {
+      flame (dpy, window);
+      screenhack_handle_events (dpy);
+    }
 }
 }
index ea74f429481af8ea117844fd79222694d8964183..7c71fc7d135c75e015801c462e70df6e16851c29 100644 (file)
@@ -20,6 +20,8 @@ static const char sccsid[] = "@(#)plate.c     4.07 97/11/24 xlockmore";
  * other special, indirect and consequential damages.
  *
  * Revision History:
  * other special, indirect and consequential damages.
  *
  * Revision History:
+ * 9-Oct-98:  dek@cgl.ucsf.edu  Added stars.
+ *
  * 8-Oct-98:  jwz@jwz.org   Made the 512x512x1 xearth image be built in.
  *                          Made it possible to load XPM or XBM files.
  *                          Made the planet bounce and roll around.
  * 8-Oct-98:  jwz@jwz.org   Made the 512x512x1 xearth image be built in.
  *                          Made it possible to load XPM or XBM files.
  *                          Made the planet bounce and roll around.
@@ -27,13 +29,9 @@ static const char sccsid[] = "@(#)plate.c    4.07 97/11/24 xlockmore";
  * 8-Oct-98: Released initial version of "glplanet"
  * (David Konerding, dek@cgl.ucsf.edu)
  *
  * 8-Oct-98: Released initial version of "glplanet"
  * (David Konerding, dek@cgl.ucsf.edu)
  *
- * TODO:
- * 1) stars
- * 3) better earth image
- * 4) "exploding" planet mode-- the surface will expand and explode
- * 5) Fix bug with annoying triangles moving on surface
- *
- *
+ * BUGS:
+ * -bounce is broken
+ * 
  *   For even more spectacular results, grab the images from the "SSysten"
  *   package (http://www.msu.edu/user/kamelkev/) and do this:
  *
  *   For even more spectacular results, grab the images from the "SSysten"
  *   package (http://www.msu.edu/user/kamelkev/) and do this:
  *
@@ -68,7 +66,7 @@ static const char sccsid[] = "@(#)plate.c     4.07 97/11/24 xlockmore";
                                        "*wireframe:            False   \n"     \
                                        "*light:                        True    \n"     \
                                        "*texture:                      True    \n" \
                                        "*wireframe:            False   \n"     \
                                        "*light:                        True    \n"     \
                                        "*texture:                      True    \n" \
-                                       "*stipple:                      False   \n" \
+                                       "*stars:                        True    \n" \
                                        "*image:                        BUILTIN \n" \
                                        "*imageForeground:      Green   \n" \
                                        "*imageBackground:      Blue    \n"
                                        "*image:                        BUILTIN \n" \
                                        "*imageForeground:      Green   \n" \
                                        "*imageBackground:      Blue    \n"
@@ -102,8 +100,8 @@ static const char sccsid[] = "@(#)plate.c   4.07 97/11/24 xlockmore";
 #define DEF_ROLL    "True"
 #define DEF_BOUNCE  "True"
 #define DEF_TEXTURE "True"
 #define DEF_ROLL    "True"
 #define DEF_BOUNCE  "True"
 #define DEF_TEXTURE "True"
+#define DEF_STARS "True"
 #define DEF_LIGHT   "True"
 #define DEF_LIGHT   "True"
-#define DEF_STIPPLE "False"
 #define DEF_IMAGE   "BUILTIN"
 
 #undef countof
 #define DEF_IMAGE   "BUILTIN"
 
 #undef countof
@@ -113,8 +111,8 @@ static int do_rotate;
 static int do_roll;
 static int do_bounce;
 static int do_texture;
 static int do_roll;
 static int do_bounce;
 static int do_texture;
+static int do_stars;
 static int do_light;
 static int do_light;
-static int do_stipple;
 static char *which_image;
 static XrmOptionDescRec opts[] = {
   {"-rotate",  ".glplanet.rotate",  XrmoptionNoArg, (caddr_t) "true" },
 static char *which_image;
 static XrmOptionDescRec opts[] = {
   {"-rotate",  ".glplanet.rotate",  XrmoptionNoArg, (caddr_t) "true" },
@@ -125,10 +123,10 @@ static XrmOptionDescRec opts[] = {
   {"+bounce",  ".glplanet.bounce",  XrmoptionNoArg, (caddr_t) "false" },
   {"-texture", ".glplanet.texture", XrmoptionNoArg, (caddr_t) "true" },
   {"+texture", ".glplanet.texture", XrmoptionNoArg, (caddr_t) "false" },
   {"+bounce",  ".glplanet.bounce",  XrmoptionNoArg, (caddr_t) "false" },
   {"-texture", ".glplanet.texture", XrmoptionNoArg, (caddr_t) "true" },
   {"+texture", ".glplanet.texture", XrmoptionNoArg, (caddr_t) "false" },
+  {"-stars",   ".glplanet.stars",   XrmoptionNoArg, (caddr_t) "true" },
+  {"+stars",   ".glplanet.stars",   XrmoptionNoArg, (caddr_t) "false" },
   {"-light",   ".glplanet.light",   XrmoptionNoArg, (caddr_t) "true" },
   {"+light",   ".glplanet.light",   XrmoptionNoArg, (caddr_t) "false" },
   {"-light",   ".glplanet.light",   XrmoptionNoArg, (caddr_t) "true" },
   {"+light",   ".glplanet.light",   XrmoptionNoArg, (caddr_t) "false" },
-  {"-stipple", ".glplanet.stipple", XrmoptionNoArg, (caddr_t) "true" },
-  {"+stipple", ".glplanet.stipple", XrmoptionNoArg, (caddr_t) "false" },
   {"-image",   ".glplanet.image",  XrmoptionSepArg, (caddr_t) 0 },
 };
 
   {"-image",   ".glplanet.image",  XrmoptionSepArg, (caddr_t) 0 },
 };
 
@@ -137,8 +135,8 @@ static argtype vars[] = {
   {(caddr_t *) &do_roll,     "roll",    "Roll",    DEF_ROLL,    t_Bool},
   {(caddr_t *) &do_bounce,   "bounce",  "Bounce",  DEF_BOUNCE,  t_Bool},
   {(caddr_t *) &do_texture,  "texture", "Texture", DEF_TEXTURE, t_Bool},
   {(caddr_t *) &do_roll,     "roll",    "Roll",    DEF_ROLL,    t_Bool},
   {(caddr_t *) &do_bounce,   "bounce",  "Bounce",  DEF_BOUNCE,  t_Bool},
   {(caddr_t *) &do_texture,  "texture", "Texture", DEF_TEXTURE, t_Bool},
+  {(caddr_t *) &do_stars,  "stars", "Stars", DEF_STARS, t_Bool},
   {(caddr_t *) &do_light,    "light",   "Light",   DEF_LIGHT,   t_Bool},
   {(caddr_t *) &do_light,    "light",   "Light",   DEF_LIGHT,   t_Bool},
-  {(caddr_t *) &do_stipple,  "stipple", "Stipple", DEF_STIPPLE, t_Bool},
   {(caddr_t *) &which_image, "image",   "Image",   DEF_IMAGE,   t_String},
 };
 
   {(caddr_t *) &which_image, "image",   "Image",   DEF_IMAGE,   t_String},
 };
 
@@ -162,32 +160,23 @@ ModStruct   planet_description =
  * at the expense of rendering speed
  */
 
  * at the expense of rendering speed
  */
 
-#define SLICES 25
-#define STACKS 25
-#define NUM_PLATES (STACKS * (SLICES+1))
+#define NUM_STARS 1000
+#define SLICES 15
+#define STACKS 15
 
 /* radius of the sphere- fairly arbitrary */
 
 /* radius of the sphere- fairly arbitrary */
-#define RADIUS 5.
+#define RADIUS 4
 
 
+/* distance away from the sphere model */
+#define DIST 40
 
 
 
 
-/*-
- * structure for holding the data for an individual plate.
- * RotationRate, Angle, Vector, Translation and Color
- * are not currently used, but may be used in the future
- */
-typedef struct {
-  GLfloat RotationRate;
-  GLfloat Angle[4];
-  GLfloat Vector[3];
-  GLfloat Translation[3];
-  GLfloat Color[3];
-  GLuint platelist;
-} plate;
 
 /* structure for holding the planet data */
 typedef struct {
 
 /* structure for holding the planet data */
 typedef struct {
-  plate plates[NUM_PLATES];
+  GLuint platelist;
+  GLuint starlist;
+  int screen_width, screen_height;
   GLXContext *glx_context;
   Window window;
 
   GLXContext *glx_context;
   Window window;
 
@@ -205,6 +194,21 @@ typedef struct {
 static planetstruct *planets = NULL;
 
 
 static planetstruct *planets = NULL;
 
 
+static inline void
+normalize(GLfloat v[3])
+{
+       GLfloat     d = (GLfloat) sqrt((double) (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]));
+
+       if (d != 0) {
+               v[0] /= d;
+               v[1] /= d;
+               v[2] /= d;
+       } else {
+               v[0] = v[1] = v[2] = 0;
+       }
+}
+
+
 /* Set up and enable texturing on our object */
 static void
 setup_xbm_texture (char *bits, int width, int height,
 /* Set up and enable texturing on our object */
 static void
 setup_xbm_texture (char *bits, int width, int height,
@@ -233,7 +237,6 @@ setup_xbm_texture (char *bits, int width, int height,
                *out++ = (word & 0x0000FF);
          }
 
                *out++ = (word & 0x0000FF);
          }
 
-  glEnable(GL_TEXTURE_2D);
   glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0,
                           GL_RGB, GL_UNSIGNED_BYTE, data);
 
   glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0,
                           GL_RGB, GL_UNSIGNED_BYTE, data);
 
@@ -242,8 +245,8 @@ setup_xbm_texture (char *bits, int width, int height,
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 }
 
 
 }
 
 
@@ -263,7 +266,6 @@ setup_file_texture (ModeInfo *mi, char *filename)
          {
                XImage *image = xpm_to_ximage (dpy, visual, cmap, xpm_data);
 
          {
                XImage *image = xpm_to_ximage (dpy, visual, cmap, xpm_data);
 
-               glEnable(GL_TEXTURE_2D);
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                                         image->width, image->height, 0,
                                         GL_RGBA, GL_UNSIGNED_BYTE, image->data);
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                                         image->width, image->height, 0,
                                         GL_RGBA, GL_UNSIGNED_BYTE, image->data);
@@ -275,8 +277,8 @@ setup_file_texture (ModeInfo *mi, char *filename)
                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                return;
          }
          break;
                return;
          }
          break;
@@ -354,52 +356,10 @@ setup_texture(ModeInfo * mi)
 static void
 setup_light(void)
 {
 static void
 setup_light(void)
 {
-
-  glEnable(GL_DEPTH_TEST);
-  glEnable(GL_AUTO_NORMAL);
-  glEnable(GL_NORMALIZE);
-  glShadeModel(GL_SMOOTH);
-
-  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-  glEnable(GL_LINE_SMOOTH);
+  /* set a number of parameters which make the scene look much nicer */
   glEnable(GL_BLEND);
   glEnable(GL_BLEND);
-
-  glEnable(GL_LIGHTING);
-  glEnable(GL_LIGHT0);
-
-  glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
-  glEnable(GL_COLOR_MATERIAL);
-
-}
-
-
-/* a stipple pattern */
-static GLubyte halftone[] =
-{
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-  0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
-};
-
-/* Set up and enable stippling */
-static void
-setup_stipple(void)
-{
-  glEnable(GL_POLYGON_STIPPLE);
-  glPolygonStipple(halftone);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  glShadeModel(GL_SMOOTH);
 }
 
 
 }
 
 
@@ -413,148 +373,194 @@ setup_face(void)
 
 
 /* Function for determining points on the surface of the sphere */
 
 
 /* Function for determining points on the surface of the sphere */
-void ParametricSphere(float theta, float rho, float *vector)
+static void inline ParametricSphere(float theta, float rho, GLfloat *vector)
 {
 {
-    vector[0] = -sin(theta) * sin(rho);
-    vector[1] = cos(theta) * sin(rho);
-    vector[2] = cos(rho);
+  vector[0] = -sin(theta) * sin(rho);
+  vector[1] = cos(theta) * sin(rho);
+  vector[2] = cos(rho);
+
+#if DO_HELIX
+  vector[0] = -(1- cos(theta)) * cos(rho); 
+  vector[1] = -(1- cos(theta)) * sin(rho); 
+  vector[2] = -(sin(theta) + rho); 
+#endif /* DO_HELIX */
+
        return;
 }
 
 
        return;
 }
 
 
+/* lame way to generate some random stars */
+void generate_stars(int width, int height)
+{
+  int i;
+/*  GLfloat size_range[2], size;*/
+  GLfloat x, y;
+
+  planetstruct *gp = &planets[MI_SCREEN(mi)];
+  
+/*    glGetFloatv(GL_POINT_SIZE_RANGE, size_range); */
+  
+/*    printf("size range: %f\t%f\n", size_range[0], size_range[1]); */
+  gp->starlist = glGenLists(1);
+  glNewList(gp->starlist, GL_COMPILE);
+
+  /* this hackery makes the viewport map one-to-one with Vertex arguments */
+  glMatrixMode(GL_PROJECTION);
+  glPushMatrix();
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluOrtho2D(0, width, 0, height);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+
+  /* disable depth testing for the stars, so they don't obscure the planet */
+  glDisable(GL_DEPTH_TEST);
+  glEnable(GL_POINT_SMOOTH);
+  glEnable(GL_BLEND);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  
+  glBegin(GL_POINTS);
+  for(i = 0 ; i < NUM_STARS ; i++)
+       {
+/*       size = (drand48()+size_range[0]) * size_range[1]/2.; */
+/*    glPointSize(size); */
+         x = drand48()*width;
+         y = drand48()*height;
+         glVertex2f(x,y);
+       }
+  glEnd();
+
+  /* return to original PROJECT and MODELVIEW */
+  glMatrixMode(GL_PROJECTION);
+  glPopMatrix();
+  glMatrixMode(GL_MODELVIEW);
+
+
+  glEndList();
+
+}
+
 /* Initialization function for screen saver */
 static void
 pinit(ModeInfo * mi)
 {
   Bool wire = MI_IS_WIREFRAME(mi);
   planetstruct *gp = &planets[MI_SCREEN(mi)];
 /* Initialization function for screen saver */
 static void
 pinit(ModeInfo * mi)
 {
   Bool wire = MI_IS_WIREFRAME(mi);
   planetstruct *gp = &planets[MI_SCREEN(mi)];
-  int i, j, list, dllist;
+  int i, j;
   int stacks=STACKS, slices=SLICES;
   float radius=RADIUS;
 
   float drho, dtheta;
   float rho, theta;
   int stacks=STACKS, slices=SLICES;
   float radius=RADIUS;
 
   float drho, dtheta;
   float rho, theta;
-  float vector[3];
-  float ds, dt, t, s;;
+  GLfloat vector[3];
+  GLfloat ds, dt, t, s;;
 
 
-  if (wire)
+  if (wire) {
+       glEnable(GL_LINE_SMOOTH);
        do_texture = False;
        do_texture = False;
+  }
 
   /* turn on various options we like */
   if (do_texture)
        setup_texture(mi);
   if (do_light)
        setup_light();
 
   /* turn on various options we like */
   if (do_texture)
        setup_texture(mi);
   if (do_light)
        setup_light();
-  if (do_stipple)
-       setup_stipple();
 
   setup_face();
 
 
   setup_face();
 
-  dllist=glGenLists(NUM_PLATES);
+  if (do_stars) {
+       glEnable(GL_POINT_SMOOTH);
+       generate_stars(MI_WIDTH(mi), MI_HEIGHT(mi));
+  }
 
 
-  drho = M_PI / stacks;
-  dtheta = 2.0 * M_PI / slices;
-  ds = 1.0 / slices;
-  dt = 1.0 / stacks;
-  t = 0.0 ;
-  
 
   /*-
 
   /*-
-   * Generate a huge sphere with quadrilaterals.
-   * Each quad is stored in its own display list; this is so we can
-   * move the quads around later (not yet done).
+   * Generate a sphere with quadrilaterals.
    * Quad vertices are determined using a parametric sphere function.
    * For fun, you could generate practically any parameteric surface and
    * map an image onto it. 
    */
 
    * Quad vertices are determined using a parametric sphere function.
    * For fun, you could generate practically any parameteric surface and
    * map an image onto it. 
    */
 
-  list = 0;
+  drho = M_PI / stacks;
+  dtheta = 2.0 * M_PI / slices;
+  ds = 1.0 / slices;
+  dt = 1.0 / stacks;
+  
+
+  gp->platelist=glGenLists(1);
+  glNewList(gp->platelist, GL_COMPILE);
+
+  glColor3f(1,1,1);
+  glBegin( wire ? GL_LINE_LOOP : GL_QUADS );
+
+  t = 0.0;
   for(i=0; i<stacks; i++) {
        rho = i * drho;
        s = 0.0;
   for(i=0; i<stacks; i++) {
        rho = i * drho;
        s = 0.0;
-       for(j=0; j<slices+1; j++) {
+       for(j=0; j<slices; j++) {
          theta = j * dtheta;
 
          theta = j * dtheta;
 
-         gp->plates[i].Translation[0] = 0.;
-         gp->plates[i].Translation[1] = 0.;
-         gp->plates[i].Translation[2] = 0.;
-
-         gp->plates[i].RotationRate = 0.;
-         gp->plates[i].Angle[0] = 0.;
-         gp->plates[i].Angle[1] = 0.;
-         gp->plates[i].Angle[2] = 0.;
-         gp->plates[i].Angle[3] = 0.;
-
-         gp->plates[i].Color[0] = 1.;
-         gp->plates[i].Color[1] = 1.;
-         gp->plates[i].Color[2] = 1.;
-
-         gp->plates[list].platelist = dllist+list;
-         glNewList(gp->plates[list].platelist, GL_COMPILE);
-         glBegin( wire ? GL_LINE_LOOP : GL_QUADS );
-
-         glColor3f(gp->plates[i].Color[0], gp->plates[i].Color[1], gp->plates[i].Color[2]);
 
          glTexCoord2f(s,t);
          ParametricSphere(theta, rho, vector);
 
          glTexCoord2f(s,t);
          ParametricSphere(theta, rho, vector);
+         normalize(vector);
          glNormal3fv(vector);
          glNormal3fv(vector);
+         ParametricSphere(theta, rho, vector);
          glVertex3f( vector[0]*radius, vector[1]*radius, vector[2]*radius );
 
          glTexCoord2f(s,t+dt);
          ParametricSphere(theta, rho+drho, vector);
          glVertex3f( vector[0]*radius, vector[1]*radius, vector[2]*radius );
 
          glTexCoord2f(s,t+dt);
          ParametricSphere(theta, rho+drho, vector);
+         normalize(vector);
          glNormal3fv(vector);
          glNormal3fv(vector);
+         ParametricSphere(theta, rho+drho, vector);
          glVertex3f( vector[0]*radius, vector[1]*radius, vector[2]*radius );
 
          glTexCoord2f(s+ds,t+dt);
          ParametricSphere(theta + dtheta, rho+drho, vector);
          glVertex3f( vector[0]*radius, vector[1]*radius, vector[2]*radius );
 
          glTexCoord2f(s+ds,t+dt);
          ParametricSphere(theta + dtheta, rho+drho, vector);
+         normalize(vector);
          glNormal3fv(vector);
          glNormal3fv(vector);
+         ParametricSphere(theta + dtheta, rho+drho, vector);
          glVertex3f( vector[0]*radius, vector[1]*radius, vector[2]*radius );
 
          glTexCoord2f(s+ds, t);
          ParametricSphere(theta + dtheta, rho, vector);
          glVertex3f( vector[0]*radius, vector[1]*radius, vector[2]*radius );
 
          glTexCoord2f(s+ds, t);
          ParametricSphere(theta + dtheta, rho, vector);
+         normalize(vector);
          glNormal3fv(vector);
          glNormal3fv(vector);
+         ParametricSphere(theta + dtheta, rho, vector);
          glVertex3f( vector[0]*radius, vector[1]*radius, vector[2]*radius );
 
          glVertex3f( vector[0]*radius, vector[1]*radius, vector[2]*radius );
 
-         glEnd();
          s = s + ds;
 
          s = s + ds;
 
-         glEndList();
-
-         list++;
        }
        t = t + dt;
   }
        }
        t = t + dt;
   }
+  glEnd();
+  glEndList();
 
 
  }
 
 static void
 
 
  }
 
 static void
-draw(ModeInfo * mi)
+draw_sphere(ModeInfo * mi)
 {
 {
-  int i;
   planetstruct *gp = &planets[MI_SCREEN(mi)];
 
   planetstruct *gp = &planets[MI_SCREEN(mi)];
 
-  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  glEnable(GL_DEPTH_TEST);
+
+  /* turn on the various attributes for making the sphere look nice */
+  if (do_texture)
+       glEnable(GL_TEXTURE_2D);
+
+  if (do_light)
+       {
+         glEnable(GL_LIGHTING);
+         glEnable(GL_LIGHT0);
+         glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
+         glEnable(GL_COLOR_MATERIAL);
+       }
+
+  glCallList(gp->platelist);
 
 
-  for (i=0; i < NUM_PLATES; i++) {
-       glPushMatrix();
-       /* currently, the angle and translation are 0, but later this can
-        * help us move the surface around */
-#if 0
-       glRotatef(gp->plates[i].Angle[0],
-                         gp->plates[i].Angle[1],
-                         gp->plates[i].Angle[2],
-                         gp->plates[i].Angle[3]); 
-       glTranslatef(gp->plates[i].Translation[0],
-                                gp->plates[i].Translation[1],
-                                gp->plates[i].Translation[2]);
-#endif
-       glCallList(gp->plates[i].platelist);
-       glPopMatrix();
-#if 0
-       gp->plates[i].Angle[0] += gp->plates[i].RotationRate;
-#endif
-  }
 }
 
 
 }
 
 
@@ -567,7 +573,7 @@ pick_velocity (ModeInfo * mi)
 
   gp->box_width =  15.0;
   gp->box_height = 15.0;
 
   gp->box_width =  15.0;
   gp->box_height = 15.0;
-  gp->box_depth =  60.0;
+  gp->box_depth =  5.0;
 
   gp->tx = 0.0;
   gp->ty = 0.0;
 
   gp->tx = 0.0;
   gp->ty = 0.0;
@@ -633,7 +639,6 @@ rotate_and_move (ModeInfo * mi)
 
 
 /* Standard reshape function */
 
 
 /* Standard reshape function */
-#define DIST 40
 static void
 reshape(int width, int height)
 {
 static void
 reshape(int width, int height)
 {
@@ -652,9 +657,6 @@ reshape(int width, int height)
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glTranslatef(0.0, 0.0, -DIST);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glTranslatef(0.0, 0.0, -DIST);
-  /* some messiness for orienting the earth normally */
-  glRotatef(90,0,0,1);
-  glRotatef(90,0,1,0);
   glLightfv(GL_LIGHT0, GL_POSITION, light);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
   glLightfv(GL_LIGHT0, GL_POSITION, light);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
@@ -727,18 +729,44 @@ draw_planet(ModeInfo * mi)
        return;
 
   glDrawBuffer(GL_BACK);
        return;
 
   glDrawBuffer(GL_BACK);
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
   glXMakeCurrent(display, window, *(gp->glx_context));
 
 
   glXMakeCurrent(display, window, *(gp->glx_context));
 
+
+  if (do_stars) {
+       /* protect our modelview matrix and attributes */
+       glPushMatrix();
+       glPushAttrib(GL_ALL_ATTRIB_BITS);
+       {
+         glColor3f(1,1,1);
+         /* draw the star field. */
+         glCallList(gp->starlist);
+
+       }
+       glPopMatrix();
+       glPopAttrib();
+  }
+
+  /* protect our modelview matrix and attributes */
   glPushMatrix();
   glPushMatrix();
+  glPushAttrib(GL_ALL_ATTRIB_BITS);
   {
   {
+       /* this pair of rotations seem to be necessary to orient the earth correctly */
+       glRotatef(90,0,0,1);
+       glRotatef(90,0,1,0);
+
        glTranslatef(gp->xpos, gp->ypos, gp->zpos);
        glRotatef(gp->tx, 1, 0, 0);
        glRotatef(gp->ty, 0, 1, 0);
        glRotatef(gp->tz, 0, 0, 1);
        glTranslatef(gp->xpos, gp->ypos, gp->zpos);
        glRotatef(gp->tx, 1, 0, 0);
        glRotatef(gp->ty, 0, 1, 0);
        glRotatef(gp->tz, 0, 0, 1);
-       draw(mi);
+       /* draw the sphere */
+       draw_sphere(mi);
   }
   glPopMatrix();
   }
   glPopMatrix();
+  glPopAttrib();
+
+
 
   glFinish();
   glXSwapBuffers(display, window);
 
   glFinish();
   glXSwapBuffers(display, window);
@@ -749,7 +777,6 @@ draw_planet(ModeInfo * mi)
 void
 release_planet(ModeInfo * mi)
 {
 void
 release_planet(ModeInfo * mi)
 {
-  int i;
   if (planets != NULL) {
        int         screen;
 
   if (planets != NULL) {
        int         screen;
 
@@ -760,10 +787,10 @@ release_planet(ModeInfo * mi)
                /* Display lists MUST be freed while their glXContext is current. */
                glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context));
 
                /* Display lists MUST be freed while their glXContext is current. */
                glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context));
 
-               for (i=0; i < NUM_PLATES; i++) {
-                 if (glIsList(gp->plates[i].platelist))
-                       glDeleteLists(gp->plates[i].platelist, 1);
-               }
+               if (glIsList(gp->platelist))
+                 glDeleteLists(gp->platelist, 1);
+               if (glIsList(gp->starlist))
+                 glDeleteLists(gp->starlist, 1);
          }
        }
        (void) free((void *) planets);
          }
        }
        (void) free((void *) planets);
index 8a2360958900f81b257f6518e750c5bafd28f3ac..d79376dde97ecca177abf0bd3fb36be50bcb4d71 100644 (file)
@@ -565,7 +565,7 @@ star(ModeInfo *mi, Bool top, Bool wire)
 #endif /* HAVE_GLBINDTEXTURE */
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color);
 
 #endif /* HAVE_GLBINDTEXTURE */
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color);
 
-  i = countof(points) - 3;
+  i = countof(points) - 9;
   do_normal(points[i+0][0], points[i+0][1], 0,
            points[i+4][0], points[i+4][1], 0,
            points[i+8][0], points[i+8][1], 0);
   do_normal(points[i+0][0], points[i+0][1], 0,
            points[i+4][0], points[i+4][1], 0,
            points[i+8][0], points[i+8][1], 0);
index 6ac712f0851f7fcdda1a72233b96a39c4e0e8404..44f64dbf3d97ae2425e03d11ce326fdc9a642045 100644 (file)
@@ -63,6 +63,8 @@ xpm_to_ximage (Display *dpy, Visual *visual, Colormap cmap, char **xpm_data)
   int bpl, wpl;
   XColor colors[255];
 
   int bpl, wpl;
   XColor colors[255];
 
+  memset (&xpm_image, 0, sizeof(xpm_image));
+  memset (&xpm_info, 0, sizeof(xpm_info));
   result = XpmCreateXpmImageFromData (xpm_data, &xpm_image, &xpm_info);
   if (result != XpmSuccess)
     {
   result = XpmCreateXpmImageFromData (xpm_data, &xpm_image, &xpm_info);
   if (result != XpmSuccess)
     {
index 233708e6913fc714ae1d0845792d42a3198a47bb..ef0e8e667b7f5dde44ba1905aa877a80bbcffff8 100644 (file)
@@ -528,7 +528,8 @@ screenhack (Display *dpy, Window window)
   while (1)
     {
       run_goop (dpy, window, g);
   while (1)
     {
       run_goop (dpy, window, g);
-      XSync (dpy, True);
+      XSync (dpy, False);
+      screenhack_handle_events (dpy);
       if (delay) usleep (delay);
     }
 }
       if (delay) usleep (delay);
     }
 }
index b2ddec4c0593764330629609035ae0cf70004035..1377c95d61e5793022d2bf6c3fbb673ce54c8756 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997
+/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -152,7 +152,7 @@ greynetic (Display *dpy, Window window)
     }
   XChangeGC (dpy, gc, GCStipple|GCForeground|GCBackground, &gcv);
   XFillRectangle (dpy, window, gc, x, y, w, h);
     }
   XChangeGC (dpy, gc, GCStipple|GCForeground|GCBackground, &gcv);
   XFillRectangle (dpy, window, gc, x, y, w, h);
-  XSync (dpy, True);
+  XSync (dpy, False);
 }
 
 \f
 }
 
 \f
@@ -177,6 +177,7 @@ screenhack (Display *dpy, Window window)
   while (1)
     {
       greynetic (dpy, window);
   while (1)
     {
       greynetic (dpy, window);
+      screenhack_handle_events (dpy);
       if (delay) usleep (delay);
     }
 }
       if (delay) usleep (delay);
     }
 }
index 474f0bc67962fede585b0fd22ae39359e17d01d5..7e8da8a2b2eead3e65baaa1045d9585eb22b7688 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1993, 1995, 1996, 1997
+/* xscreensaver, Copyright (c) 1993, 1995, 1996, 1997, 1998
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -365,7 +365,7 @@ run_circles (Display *dpy, Window window)
                 : (iterations & 1)))
     {
       XCopyPlane (dpy, buffer, window, copy_gc, 0, 0, width, height, 0, 0, 1);
                 : (iterations & 1)))
     {
       XCopyPlane (dpy, buffer, window, copy_gc, 0, 0, width, height, 0, 0, 1);
-      XSync (dpy, True);
+      XSync (dpy, False);
       if (anim_p && done)
        XFillRectangle (dpy, buffer, erase_gc, 0, 0, width, height);
     }
       if (anim_p && done)
        XFillRectangle (dpy, buffer, erase_gc, 0, 0, width, height);
     }
@@ -374,7 +374,7 @@ run_circles (Display *dpy, Window window)
   XCopyPlane (dpy, pixmap, window, copy_gc, 0,0,width,height,width,height, 1);
   if (buffer)
     XCopyPlane (dpy, buffer, window, copy_gc, 0,0,width,height,0,height, 1);
   XCopyPlane (dpy, pixmap, window, copy_gc, 0,0,width,height,width,height, 1);
   if (buffer)
     XCopyPlane (dpy, buffer, window, copy_gc, 0,0,width,height,0,height, 1);
-  XSync (dpy, True);
+  XSync (dpy, False);
 #endif
 
   if (done)
 #endif
 
   if (done)
@@ -446,5 +446,8 @@ screenhack (Display *dpy, Window window)
 {
   init_circles (dpy, window);
   while (1)
 {
   init_circles (dpy, window);
   while (1)
-    run_circles (dpy, window);
+    {
+      run_circles (dpy, window);
+      screenhack_handle_events (dpy);
+    }
 }
 }
index c2d81fa22dfd6785931160d3c8e03ed688e12135..27c9d43763b13fde1f26929949c82ebaffa89589 100644 (file)
@@ -268,13 +268,16 @@ random_helix_or_trig (Display *dpy, Window window)
   else
     random_trig(dpy, window, &color, &free_color);
 
   else
     random_trig(dpy, window, &color, &free_color);
 
-  XSync (dpy, True);
+  XSync (dpy, False);
+  screenhack_handle_events (dpy);
   sleep ( sleep_time );
 
   sleep ( sleep_time );
 
+  screenhack_handle_events (dpy);
   erase_full_window(dpy, window);
 
   if (free_color) XFreeColors (dpy, cmap, &color.pixel, 1, 0);
   erase_full_window(dpy, window);
 
   if (free_color) XFreeColors (dpy, cmap, &color.pixel, 1, 0);
-  XSync (dpy, True);
+  XSync (dpy, False);
+  screenhack_handle_events (dpy);
   sleep (1);
 }
 
   sleep (1);
 }
 
index 560f1306df32699c6fac0fdd0bacfdc77a57515a..5150ec3bdfbc130e49f6bf6ae4c66ba03ffc85cd 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992, 1995, 1996
+/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1998
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -210,7 +210,8 @@ hyper (double xy, double xz, double yz, double xw, double yw, double zw)
       rotates (y,w);
       rotates (z,w);
 
       rotates (y,w);
       rotates (z,w);
 
-      XSync (dpy, True);
+      XSync (dpy, False);
+      screenhack_handle_events (dpy);
       if (delay) usleep (delay);
     }
 }
       if (delay) usleep (delay);
     }
 }
index fa861ac0be1f4177c43e762fbf5a7a5cedd58ca7..15cb66ae9eea9d69df270f6f5ec2c7f582a94650 100644 (file)
@@ -439,14 +439,15 @@ draw_map (Display *dpy, Window window)
       xstep = xnextStep;
       ystep = ynextStep;
       if (!mono_p)
       xstep = xnextStep;
       ystep = ynextStep;
       if (!mono_p)
-       XSync (dpy, True);
+       XSync (dpy, False);
+      screenhack_handle_events (dpy);
     }
   if (mono_p)
     /* in mono-mode, we do all the drawing at the end */
     floyd_steinberg (dpy, window);
   
   free (cell);
     }
   if (mono_p)
     /* in mono-mode, we do all the drawing at the end */
     floyd_steinberg (dpy, window);
   
   free (cell);
-  XSync (dpy, True);
+  XSync (dpy, False);
 }
 
 
 }
 
 
@@ -493,10 +494,14 @@ screenhack (Display *dpy, Window window)
                    rotate_colors (dpy, cmap, colors, ncolors,
                                   cycle_direction);
                    if (cycle_delay) usleep(cycle_delay);
                    rotate_colors (dpy, cmap, colors, ncolors,
                                   cycle_direction);
                    if (cycle_delay) usleep(cycle_delay);
+                    screenhack_handle_events (dpy);
                  }
              }
            else
                  }
              }
            else
-             sleep (delay);
+              {
+                screenhack_handle_events (dpy);
+                sleep (delay);
+              }
          }
       }
 }
          }
       }
 }
index d877a01b1cd44c8804f4182dab33814a4b5b40ab..d856f30eb5213945c4bee39cb9aac8f168315f8c 100644 (file)
@@ -450,7 +450,7 @@ void screenhack(Display *dpy, Window win)
   inter_init(dpy, win, &c);
   while(1) {
     do_inter(&c); 
   inter_init(dpy, win, &c);
   while(1) {
     do_inter(&c); 
-    if(delay) 
-      usleep(delay);
+    screenhack_handle_events (dpy);
+    if(delay) usleep(delay);
   }
 }
   }
 }
index 83dcbe922f3e95cf2922d0ea2445872130a78f3e..246c9da77402f70df1b9a94b8b47705a36f77c8d 100644 (file)
@@ -567,10 +567,12 @@ screenhack (Display *dpy, Window window)
       while (!done())
        {
          unshuffle(dpy, window);
       while (!done())
        {
          unshuffle(dpy, window);
-         XSync (dpy, True);
+         XSync (dpy, False);
+          screenhack_handle_events (dpy);
          if (delay) usleep (delay);
        }
 
          if (delay) usleep (delay);
        }
 
+      screenhack_handle_events (dpy);
       if (delay2)
        usleep (delay2 * 1000000);
 
       if (delay2)
        usleep (delay2 * 1000000);
 
index 78890147c097c1e17388177a0ccc584fda9e7da6..6e66fdd837a0e08c6de6959b505e7611dac25a24 100644 (file)
@@ -444,9 +444,10 @@ screenhack (Display *dpy, Window window)
   while (1)
     {
      draw_objects ();
   while (1)
     {
      draw_objects ();
-     XSync (dpy, True);
+     XSync (dpy, False);
      if(g.delay) {
      if(g.delay) {
-       screenhack_usleep(g.delay);
+       screenhack_handle_events (dpy);
+       usleep(g.delay);
      }
      propogate_objects(); 
    }
      }
      propogate_objects(); 
    }
index 640a856ebb88ab0d64d5a1eb4dcbaa9640169263..bcc137af3d10110c6923a3f50495b84df6dd73e6 100644 (file)
@@ -529,7 +529,8 @@ while (0==0)
 #ifdef HAVE_XDBE_EXTENSION
        if (usedouble) XdbeSwapBuffers(dpy,&xdswp,1);
 #endif /* HAVE_XDBE_EXTENSION */
 #ifdef HAVE_XDBE_EXTENSION
        if (usedouble) XdbeSwapBuffers(dpy,&xdswp,1);
 #endif /* HAVE_XDBE_EXTENSION */
-       XSync(dpy,True);
+       XSync(dpy, False);
+        screenhack_handle_events (dpy);
        if (delay) usleep (delay);
        }
 }
        if (delay) usleep (delay);
        }
 }
index f372c1eeff7c8463bda4cda0fe5c826c0c9fa7aa..11099d26bcb58ced25ff3b344f8f44ba9705ae95 100644 (file)
@@ -507,6 +507,7 @@ screenhack(Display *disp, Window win)
     initLMorph();
     for (;;) {
        animateLMorph();
     initLMorph();
     for (;;) {
        animateLMorph();
-       screenhack_usleep(delay);
+        screenhack_handle_events (dpy);
+       usleep(delay);
     }
 }
     }
 }
index 7690555d2249f17439912edbb9b40be327325250..40edf41b58bf9e8dfdc310585680c9b963d037a2 100644 (file)
@@ -201,6 +201,9 @@ check_events (void)                        /* X event handler [ rhess ] */
     case Expose:
       restart = 1;
       break;
     case Expose:
       restart = 1;
       break;
+    default:
+      screenhack_handle_event(dpy, &e);
+      break;
     }
     return(1);
   }
     }
     return(1);
   }
@@ -1367,7 +1370,7 @@ find_dead_regions(void)
          }
        }
       }
          }
        }
       }
-    XSync(dpy, 0);
+    XSync(dpy, False);
 }
 
 static void
 }
 
 static void
@@ -1612,7 +1615,13 @@ screenhack(Display *display, Window window)
   set_maze_sizes (xgwa.width, xgwa.height);
 
   if (! root)
   set_maze_sizes (xgwa.width, xgwa.height);
 
   if (! root)
-    XSelectInput (dpy, win, ExposureMask|ButtonPressMask|StructureNotifyMask);
+    {
+      XWindowAttributes xgwa;
+      XGetWindowAttributes (dpy, window, &xgwa);
+      XSelectInput (dpy, win,
+                    xgwa.your_event_mask | ExposureMask |
+                    ButtonPressMask |StructureNotifyMask);
+    }
   
   gc  = XCreateGC(dpy, win, 0, 0);
   cgc = XCreateGC(dpy, win, 0, 0);
   
   gc  = XCreateGC(dpy, win, 0, 0);
   cgc = XCreateGC(dpy, win, 0, 0);
index f01fa28fe4e7e3bf9a73da888e83aded87684334..9b95c6b943e92bfb608da884d37e3aa16f741b78 100644 (file)
@@ -230,7 +230,8 @@ screenhack (Display *dpy, Window window)
     {
       init_moire (dpy, window);
       moire (dpy, window, offset, colors, ncolors);
     {
       init_moire (dpy, window);
       moire (dpy, window, offset, colors, ncolors);
-      XSync (dpy, True);
+      XSync (dpy, False);
+      screenhack_handle_events (dpy);
       if (delay)
        sleep(delay);
     }
       if (delay)
        sleep(delay);
     }
index e714b5e085b879323561c05dc49ef1ea53719f39..96bfd9ac0e4a1c87b8801f8144c9c5f87d9085c1 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1997 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1997, 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
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -270,6 +270,7 @@ screenhack (Display *dpy, Window window)
          for (i = 0; i < color_shift; i++)
            {
              moire2 (dpy, window);
          for (i = 0; i < color_shift; i++)
            {
              moire2 (dpy, window);
+              screenhack_handle_events (dpy);
              if (delay)
                usleep(delay);
            }
              if (delay)
                usleep(delay);
            }
index 84ff9608e332359332a29cb51590cc00503ebaa9..b3cd73517d2c477dc638eb727a72a7bdd1586476 100644 (file)
@@ -133,6 +133,7 @@ static void munchOnce (Display* dpy, Window w,
           same time (one for each value of x, surprisingly enough)
           */
        XSync(dpy, False);
           same time (one for each value of x, surprisingly enough)
           */
        XSync(dpy, False);
+        screenhack_handle_events (dpy);
        if (delay) usleep(delay);
     }
 }
        if (delay) usleep(delay);
     }
 }
@@ -246,6 +247,7 @@ screenhack (dpy, w) Display *dpy; Window w;
                  (randflags & GRAV)
                  );
        
                  (randflags & GRAV)
                  );
        
+        screenhack_handle_events (dpy);
        if (hold) usleep(hold);
        
        if (clear && ++n >= clear) {
        if (hold) usleep(hold);
        
        if (clear && ++n >= clear) {
index 0afb52c85d58d8ec531d5535540bd8c068eb181b..9ea9f4e54204247a6b4c8ce8475b46c0283e802c 100644 (file)
@@ -713,7 +713,8 @@ screenhack (Display *d, Window w)
   while (1)
     {
       next_fn();
   while (1)
     {
       next_fn();
-      XSync (dpy, True);
+      XSync (dpy, False);
+      screenhack_handle_events (dpy);
       usleep (interval * 1000);
     }
 }
       usleep (interval * 1000);
     }
 }
index 4306f8a2a2395270e1767cb35542112d7e9ee818..7f8e5bd6c8470d52a08e8da3b6010cd5afea989b 100644 (file)
@@ -276,7 +276,8 @@ fade_foreground (Display *dpy, Colormap cmap,
       inbetween.blue  = from.blue  + (to.blue  - from.blue)  * i / steps ;
       XStoreColor (dpy, cmap, &inbetween);
       /* If we don't sync, these can bunch up */
       inbetween.blue  = from.blue  + (to.blue  - from.blue)  * i / steps ;
       XStoreColor (dpy, cmap, &inbetween);
       /* If we don't sync, these can bunch up */
-      XSync(dpy, 0);
+      XSync(dpy, False);
+      screenhack_handle_events (dpy);
       usleep(udelay);
     }
 }
       usleep(udelay);
     }
 }
@@ -317,7 +318,7 @@ pedal (Display *dpy, Window window)
        XColor color;
        hsv_to_rgb (random()%360, 1.0, 1.0,
                   &color.red, &color.green, &color.blue);
        XColor color;
        hsv_to_rgb (random()%360, 1.0, 1.0,
                   &color.red, &color.green, &color.blue);
-       XSync(dpy, 0);
+       XSync(dpy, False);
        if (fade_p)
         {
           foreground.red = color.red;
        if (fade_p)
         {
           foreground.red = color.red;
@@ -335,7 +336,7 @@ pedal (Display *dpy, Window window)
           foreground.blue = color.blue;
           foreground.pixel = color.pixel;
         }
           foreground.blue = color.blue;
           foreground.pixel = color.pixel;
         }
-       XSync(dpy, 0);
+       XSync(dpy, False);
      }
 
     /* Fade in by bringing the foreground back from background */
      }
 
     /* Fade in by bringing the foreground back from background */
@@ -374,7 +375,8 @@ screenhack (Display *dpy, Window window)
     init_pedal (dpy, window);
     for (;;) {
        pedal (dpy, window);
     init_pedal (dpy, window);
     for (;;) {
        pedal (dpy, window);
-       XSync(dpy, 0);
+       XSync(dpy, False);
+        screenhack_handle_events (dpy);
        if (delay) sleep (delay);
     }
 }
        if (delay) sleep (delay);
     }
 }
index 05c12763b23c626e696778001bd5b58f2df733da..ddace3910fbeb3b942a2d5a321e4a4f472bb84af 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992, 1994, 1996
+/* xscreensaver, Copyright (c) 1992, 1994, 1996, 1998
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -164,7 +164,8 @@ pyro (Display *dpy, Window window, Colormap cmap)
       launch (xlim, ylim, g, dpy, cmap);
     }
 
       launch (xlim, ylim, g, dpy, cmap);
     }
 
-  XSync (dpy, True);
+  XSync (dpy, False);
+  screenhack_handle_events (dpy);
   usleep (10000);
 
   for (i = 0; i < how_many; i++)
   usleep (10000);
 
   for (i = 0; i < how_many; i++)
index c19f3bc6a33f9cd5e4f5f40438188739fefef91b..924b5422595c810d907477673f5c7fb58e1c3dca 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997
+/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -504,7 +504,8 @@ screenhack (Display *dpy, Window window)
     for (qn = q1; *qn; qn++)
       {
        qix1 (dpy, window, *qn);
     for (qn = q1; *qn; qn++)
       {
        qix1 (dpy, window, *qn);
-       XSync (dpy, True);
+       XSync (dpy, False);
+        screenhack_handle_events (dpy);
        if (delay) usleep (delay);
       }
 }
        if (delay) usleep (delay);
       }
 }
index 990abcf89dbd7121421f0a20bed5360dd83a069e..a537eadc6b49168ea367d294326cb61452460f61 100644 (file)
@@ -541,6 +541,7 @@ screenhack (Display *dpy, Window win)
     frame++;
 
     XSync(dpy, False);
     frame++;
 
     XSync(dpy, False);
+    screenhack_handle_events (dpy);
     if (delay > 0)
       usleep(1000 * delay);
   }
     if (delay > 0)
       usleep(1000 * delay);
   }
index aceef3bcf8073fe2b30981bbad08a16527777f7a..e5e0df5beaa78e8738d2fda0cfb264d6f62e509f 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997
+/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  *  Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -527,7 +527,8 @@ screenhack (Display *dpy, Window window)
   while (1)
     {
       rocks_once ();
   while (1)
     {
       rocks_once ();
-      XSync (dpy, True);
+      XSync (dpy, False);
+      screenhack_handle_events (dpy);
       if (delay) usleep (delay);
     }
 }
       if (delay) usleep (delay);
     }
 }
index 3c1a20e5fe9a9a59af3fdff586c336cfccf95082..430fa9dfb3373464428651dd90fd56ddef1da39e 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992, 1996 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992, 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
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -92,7 +92,8 @@ hurm (Display *dpy, Window window)
          j++;
        }
       XDrawPoints (dpy, window, draw_gc, points, j, CoordModeOrigin);
          j++;
        }
       XDrawPoints (dpy, window, draw_gc, points, j, CoordModeOrigin);
-      XSync (dpy, True);
+      XSync (dpy, False);
+      screenhack_handle_events (dpy);
     }
   sleep ( sleep_time );
 
     }
   sleep ( sleep_time );
 
@@ -100,7 +101,8 @@ hurm (Display *dpy, Window window)
 
   XClearWindow (dpy, window);
   if (got_color) XFreeColors (dpy, cmap, &color.pixel, 1, 0);
 
   XClearWindow (dpy, window);
   if (got_color) XFreeColors (dpy, cmap, &color.pixel, 1, 0);
-  XSync (dpy, True);
+  XSync (dpy, False);
+  screenhack_handle_events (dpy);
   sleep (1);
 }
 
   sleep (1);
 }
 
index 4d169939018de416fe59c05513d15aaab4b5ea1c..0e1c678e1039dc5451afec54ab5eca1ec7d14140 100644 (file)
@@ -37,6 +37,7 @@
 #include <X11/CoreP.h>
 #include <X11/Shell.h>
 #include <X11/StringDefs.h>
 #include <X11/CoreP.h>
 #include <X11/Shell.h>
 #include <X11/StringDefs.h>
+#include <X11/Xutil.h>
 
 #ifdef __sgi
 # include <X11/SGIScheme.h>    /* for SgiUseSchemes() */
 
 #ifdef __sgi
 # include <X11/SGIScheme.h>    /* for SgiUseSchemes() */
@@ -167,6 +168,70 @@ extern void pre_merge_options (void);
 #endif
 
 
 #endif
 
 
+static Atom XA_WM_PROTOCOLS, XA_WM_DELETE_WINDOW;
+
+/* Dead-trivial event handling: exits if "q" or "ESC" are typed.
+   Exit if the WM_PROTOCOLS WM_DELETE_WINDOW ClientMessage is received.
+ */
+void
+screenhack_handle_event (Display *dpy, XEvent *event)
+{
+  switch (event->xany.type)
+    {
+    case KeyPress:
+      {
+        KeySym keysym;
+        char c = 0;
+        XLookupString (&event->xkey, &c, 1, &keysym, 0);
+        if (c == 'q' ||
+            c == 'Q' ||
+            c == 3 ||  /* ^C */
+            c == 27)   /* ESC */
+          exit (0);
+      }
+    case ButtonPress:
+      XBell (dpy, 0);
+      break;
+    case ClientMessage:
+      {
+        if (event->xclient.message_type != XA_WM_PROTOCOLS)
+          {
+            char *s = XGetAtomName(dpy, event->xclient.message_type);
+            if (!s) s = "(null)";
+            fprintf (stderr, "%s: unknown ClientMessage %s received!\n",
+                     progname, s);
+          }
+        else if (event->xclient.data.l[0] != XA_WM_DELETE_WINDOW)
+          {
+            char *s1 = XGetAtomName(dpy, event->xclient.message_type);
+            char *s2 = XGetAtomName(dpy, event->xclient.data.l[0]);
+            if (!s1) s1 = "(null)";
+            if (!s2) s2 = "(null)";
+            fprintf (stderr, "%s: unknown ClientMessage %s[%s] received!\n",
+                     progname, s1, s2);
+          }
+        else
+          {
+            exit (0);
+          }
+      }
+      break;
+    }
+}
+
+
+void
+screenhack_handle_events (Display *dpy)
+{
+  while (XPending (dpy))
+    {
+      XEvent event;
+      XNextEvent (dpy, &event);
+      screenhack_handle_event (dpy, &event);
+    }
+}
+
+
 
 int
 main (int argc, char **argv)
 
 int
 main (int argc, char **argv)
@@ -208,12 +273,20 @@ main (int argc, char **argv)
   XtGetApplicationNameAndClass (dpy, &progname, &progclass);
   XSetErrorHandler (screenhack_ehandler);
 
   XtGetApplicationNameAndClass (dpy, &progname, &progclass);
   XSetErrorHandler (screenhack_ehandler);
 
+  XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False);
+  XA_WM_DELETE_WINDOW = XInternAtom (dpy, "WM_DELETE_WINDOW", False);
+
   {
     char *v = (char *) strdup(strchr(screensaver_id, ' '));
   {
     char *v = (char *) strdup(strchr(screensaver_id, ' '));
-    char *s = (char *) strchr(v, ',');
-    *s = 0;
-    sprintf (version, "%s: from the XScreenSaver%s distribution.",
-            progclass, v);
+    char *s1, *s2, *s3, *s4;
+    s1 = (char *) strchr(v,  ' '); s1++;
+    s2 = (char *) strchr(s1, ' ');
+    s3 = (char *) strchr(v,  '('); s3++;
+    s4 = (char *) strchr(s3, ')');
+    *s2 = 0;
+    *s4 = 0;
+    sprintf (version, "%s: from the XScreenSaver %s distribution (%s.)",
+            progclass, s1, s3);
     free(v);
   }
 
     free(v);
   }
 
@@ -359,6 +432,18 @@ main (int argc, char **argv)
        }
 
       XtVaSetValues(toplevel, XtNtitle, version, 0);
        }
 
       XtVaSetValues(toplevel, XtNtitle, version, 0);
+
+      /* For screenhack_handle_events(): select KeyPress, and
+         announce that we accept WM_DELETE_WINDOW. */
+      {
+        XWindowAttributes xgwa;
+        XGetWindowAttributes (dpy, window, &xgwa);
+        XSelectInput (dpy, window,
+                      xgwa.your_event_mask | KeyPressMask | ButtonPressMask);
+        XChangeProperty (dpy, window, XA_WM_PROTOCOLS, XA_ATOM, 32,
+                         PropModeReplace,
+                         (unsigned char *) &XA_WM_DELETE_WINDOW, 1);
+      }
     }
 
   if (!dont_clear)
     }
 
   if (!dont_clear)
index bb0344fb7543ec30f007ffef34168f53c20331eb..63222520c25bfa7ae193c7ec7b3db78d38e00a73 100644 (file)
@@ -94,5 +94,7 @@ extern XrmOptionDescRec options [];
 extern char *defaults [];
 
 extern void screenhack (Display*,Window);
 extern char *defaults [];
 
 extern void screenhack (Display*,Window);
+extern void screenhack_handle_event (Display*, XEvent*);
+extern void screenhack_handle_events (Display*);
 
 #endif /* __SCREENHACK_H__ */
 
 #endif /* __SCREENHACK_H__ */
index 9415ac22049aaccd5842e29d0b1784558e8aee97..c2fc03324b2900ac3e11113018ceb80737587f4e 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992, 1993, 1994, 1996, 1997 
+/* xscreensaver, Copyright (c) 1992, 1993, 1994, 1996, 1997, 1998 
  * Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -197,7 +197,7 @@ init_slide (Display *dpy, Window window)
       XFillRectangle (dpy, d, gc, 0, bitmap_h - yoff, bitmap_w, yoff);
     }
 
       XFillRectangle (dpy, d, gc, 0, bitmap_h - yoff, bitmap_w, yoff);
     }
 
-  XSync (dpy, True);
+  XSync (dpy, False);
   if (delay2) usleep (delay2 * 2);
  for (i = 0; i < grid_size; i += pix_inc)
    {
   if (delay2) usleep (delay2 * 2);
  for (i = 0; i < grid_size; i += pix_inc)
    {
@@ -228,7 +228,7 @@ init_slide (Display *dpy, Window window)
      points[2].y = points[1].y;
      XFillPolygon (dpy, window, gc, points, 3, Convex, CoordModeOrigin);
 
      points[2].y = points[1].y;
      XFillPolygon (dpy, window, gc, points, 3, Convex, CoordModeOrigin);
 
-     XSync (dpy, True);
+     XSync (dpy, False);
      if (delay) usleep (delay);
    }
 
      if (delay) usleep (delay);
    }
 
@@ -309,7 +309,7 @@ slide1 (Display *dpy, Window window)
         break;
        }
 
         break;
        }
 
-     XSync (dpy, True);
+     XSync (dpy, False);
      if (delay) usleep (delay);
    }
  switch (dir)
      if (delay) usleep (delay);
    }
  switch (dir)
@@ -357,6 +357,7 @@ screenhack (Display *dpy, Window window)
   while (1)
     {
       slide1 (dpy, window);
   while (1)
     {
       slide1 (dpy, window);
+      screenhack_handle_events (dpy);
       if (delay2) usleep (delay2);
     }
 }
       if (delay2) usleep (delay2);
     }
 }
diff --git a/hacks/sonar.c b/hacks/sonar.c
new file mode 100644 (file)
index 0000000..3c49218
--- /dev/null
@@ -0,0 +1,1687 @@
+/* sonar.c --- Simulate a sonar screen.
+ *
+ * This is an implementation of a general purpose reporting tool in the
+ * format of a Sonar display. It is designed such that a sensor is read
+ * on every movement of a sweep arm and the results of that sensor are
+ * displayed on the screen. The location of the display points (targets) on the
+ * screen are determined by the current localtion of the sweep and a distance
+ * value associated with the target. 
+ *
+ * Currently the only two sensors that are implemented are the simulator
+ * (the default) and the ping sensor. The simulator randomly creates a set
+ * of bogies that move around on the scope while the ping sensor can be
+ * used to display hosts on your network.
+ *
+ * The ping code is only compiled in if you define HAVE_PING, because, 
+ * unfortunately, creating an ICMP socket is a privileged operation, the
+ * program needs to be installed SUID root if you want to use the ping
+ * mode. If you check the code you will see that this privilige is given up
+ * immediately after the socket is created.
+ *
+ * It should be easy to extend this code to support other sorts of sensors.
+ * Some ideas:
+ *   - search the output of "netstat" for the list of hosts to ping;
+ *   - plot the contents of /proc/interrupts;
+ *   - plot the process table, by process size, cpu usage, or total time;
+ *   - plot the logged on users by idle time or cpu usage.
+ *
+ * Copyright (C) 1998 by Stephen Martin (smartin@canada.com).
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  No representations are made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ *
+ * $Revision: 1.6 $
+ *
+ * Version 1.0 April 27, 1998.
+ * - Initial version
+ * - Submitted to RedHat Screensaver Contest
+ * 
+ * Version 1.1 November 3, 1998.
+ * - Added simulation mode.
+ * - Added enhancements by Thomas Bahls <thommy@cs.tu-berlin.de>
+ * - Fixed huge memory leak.
+ * - Submitted to xscreensavers
+ * 
+ * Version 1.2
+ * - All ping code is now ifdef-ed by the compile time symbol HAVE_PING;
+ *   use -DHAVE_PING to include it when you compile.
+ * - Sweep now uses gradients.
+ * - Fixed portability problems with icmphdr on some systems.
+ * - removed lowColor option/resource.
+ * - changed copyright notice so that it could be included in the xscreensavers
+ *   collection.
+ *
+ * Version 1.3 November 16, 1998.
+ * - All ping code is now ifdef-ed by the compile time symbol PING use -DPING
+ *   to include it when you compile.
+ * - Sweep now uses gradients.
+ * - Fixed portability problems with icmphdr on some systems.
+ * - removed lowcolour option/resource.
+ * - changed copyright notice so that it could be included in the xscreensavers
+ *   collection.
+ *
+ * Version 1.4 November 18, 1998.
+ * - More ping portability fixes.
+ *
+ * Version 1.5 November 19, 1998.
+ * - Synced up with jwz's changes.
+ * - Now need to define HAVE_PING to compile in the ping stuff.
+ */
+
+/* Include Files */
+
+#ifdef HAVE_PING
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/udp.h>
+#include <arpa/inet.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <signal.h>
+#include <limits.h>
+#endif /* HAVE_PING */
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "screenhack.h"
+#include "colors.h"
+#include "hsv.h"
+#include <X11/extensions/XShm.h>
+
+/* Defines */
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a - 50):(b - 10))
+#endif /* MIN */
+
+/* Forward References */
+
+#ifdef HAVE_PING
+static u_short checksum(u_short *, int);
+#endif
+static long delta(struct timeval *, struct timeval *);
+
+/* Data Structures */
+
+/*
+ * The Bogie.
+ *
+ * This represents an object that is visable on the scope.
+ */
+
+typedef struct Bogie {
+    char *name;                        /* The name of the thing being displayed */
+    int distance;              /* The distance to this thing (0 - 100) */
+    int tick;                  /* The tick that it was found on */
+    int ttl;                   /* The time to live */
+    int age;                    /* How long it's been around */
+    struct Bogie *next;                /* The next one in the list */
+} Bogie;
+
+/*
+ * Sonar Information.
+ *
+ * This contains all of the runtime information about the sonar scope.
+ */
+
+typedef struct {
+    Display *dpy;              /* The X display */
+    Window win;                        /* The window */
+    GC hi,                     /* The leading edge of the sweep */
+       lo,                     /* The trailing part of the sweep */
+       erase,                  /* Used to erase things */
+       grid,                   /* Used to draw the grid */
+       text;                   /* Used to draw text */
+    Colormap cmap;             /* The colormap */
+    XFontStruct *font;          /* The font to use for the labels */
+    int text_steps;            /* How many steps to fade text. */
+    XColor *text_colors;       /* Pixel values used to fade text */
+    int sweep_degrees;         /* How much of the circle the sweep uses */
+    int sweep_segs;            /* How many gradients in the sweep. */
+    XColor *sweep_colors;        /* The sweep pixel values */
+    int width, height;         /* Window dimensions */
+    int minx, miny, maxx, maxy, /* Bounds of the scope */
+       centrex, centrey, radius; /* Parts of the scope circle */
+    Bogie *visable;            /* List of visable objects */
+    int current;               /* Current position of sweep */
+
+    int delay;                 /* how long between each frame of the anim */
+
+} sonar_info;
+
+/* 
+ * Variables to support the differnt Sonar modes.
+ */
+
+Bogie *(*sensor)(sonar_info *, void *);        /* The current sensor */
+void *sensor_info;                     /* Information about the sensor */
+
+/*
+ * A list of targets to ping.
+ */
+
+#ifdef HAVE_PING
+typedef struct ping_target {
+    char *name;                        /* The name of the target */
+    struct sockaddr address;   /* The address of the target */
+    struct ping_target *next;  /* The next one in the list */
+} ping_target;
+
+/*
+ * Ping Information.
+ *
+ * This contains the information for the ping sensor.
+ */
+
+typedef struct {
+    int icmpsock;              /* Socket for sending pings */
+    int pid;                   /* Our process ID */
+    int seq;                   /* Packet sequence number */
+    int timeout;               /* Timeout value for pings */
+    ping_target *targets;      /* List of targets to ping */
+    int numtargets;             /* The number of targets to ping */
+} ping_info;
+
+/* Flag to indicate that the timer has expired on us */
+
+static int timer_expired;
+
+
+#endif /* HAVE_PING */
+
+/*
+ * A list of targets for the simulator
+ */
+
+typedef struct sim_target {
+    char *name;                        /* The name of the target */
+    int nexttick;              /* The next tick that this will be seen */
+    int nextdist;              /* The distance on that tick */
+    int movedlasttick;         /* Flag to indicate we just moved this one */
+} sim_target;
+
+/*
+ * Simulator Information.
+ *
+ * This contains the information for the simulator mode.
+ */
+
+typedef struct {
+    sim_target *teamA;         /* The bogies for the A team */
+    int numA;                  /* The number of bogies in team A */
+    char *teamAID;             /* The identifier for bogies in team A */
+    sim_target *teamB;         /* The bogies for the B team */
+    int numB;                  /* The number of bogies in team B */
+    char *teamBID;             /* The identifier for bogies in team B */
+} sim_info;
+
+/* Name of the Screensaver hack */
+
+char *progclass="sonar";
+
+/* Application Defaults */
+
+char *defaults [] = {
+    ".background:      #000000",
+    ".sweepColor:      #00FF00",
+    "*delay:          100000",
+    "*scopeColor:      #003300",
+    "*gridColor:       #00AA00",
+    "*textColor:       #FFFF00",
+    "*ttl:             90",
+    "*mode:            default",
+    "*font:            fixed",
+    "*sweepDegrees:    30",
+
+    "*textSteps:       80",    /* npixels */
+    "*sweepSegments:   80",    /* npixels */
+
+#ifdef HAVE_PING
+    "*pingTimeout:     3000",
+    "*pingSource:      file",
+    "*pingFile:        /etc/hosts",
+    "*pingList:        localhost",
+#endif /* HAVE_PING */
+    "*teamAName:       F18",
+    "*teamBName:       MIG",
+    "*teamACount:      4",
+    "*teamBCount:      4",
+    0
+};
+
+/* Options passed to this program */
+
+XrmOptionDescRec options [] = {
+    {"-background",   ".background",   XrmoptionSepArg, 0 },
+    {"-sweep-color",  ".sweepColor",   XrmoptionSepArg, 0 },
+    {"-scope-color",  ".scopeColor",   XrmoptionSepArg, 0 },
+    {"-grid-color",   ".gridColor",    XrmoptionSepArg, 0 },
+    {"-text-color",   ".textColor",    XrmoptionSepArg, 0 },
+    {"-ttl",          ".ttl",          XrmoptionSepArg, 0 },
+    {"-mode",         ".mode",         XrmoptionSepArg, 0 },
+    {"-font",         ".font",         XrmoptionSepArg, 0 },
+#ifdef HAVE_PING
+    {"-ping-timeout", ".pingTimeout",  XrmoptionSepArg, 0 },
+    {"-ping-source",  ".pingSource",   XrmoptionSepArg, 0 },
+    {"-ping-file",    ".pingFile",     XrmoptionSepArg, 0 },
+    {"-ping-list",    ".pingList",     XrmoptionSepArg, 0 },
+#endif /* HAVE_PING */
+    {"-team-a-name",   ".teamAName",   XrmoptionSepArg, 0 },
+    {"-team-b-name",   ".teamBName",   XrmoptionSepArg, 0 },
+    {"-team-a-count",  ".teamACount",  XrmoptionSepArg, 0 },
+    {"-team-b-count",  ".teamBCount",  XrmoptionSepArg, 0 },
+    { 0, 0, 0, 0 }
+};
+
+/*
+ * The number of ticks that bogies are visable on the screen before they
+ * fade away.
+ */
+
+static int TTL;
+
+/*
+ * Create a new Bogie and set some initial values.
+ *
+ * Args:
+ *    name     - The name of the bogie.
+ *    distance - The distance value.
+ *    tick     - The tick value.
+ *    ttl      - The time to live value.
+ *
+ * Returns:
+ *    The newly allocated bogie or null if a memory problem occured.
+ */
+
+static Bogie *
+newBogie(char *name, int distance, int tick, int ttl) 
+{
+
+    /* Local Variables */
+
+    Bogie *new;
+
+    /* Allocate a bogie and initialize it */
+
+    if ((new = (Bogie *) calloc(1, sizeof(Bogie))) == NULL) {
+       fprintf(stderr, "Out of Memory\n");
+       return NULL;
+    }
+    new->name = name;
+    new->distance = distance;
+    new->tick = tick;
+    new->ttl = ttl;
+    new->age = 0;
+    new->next = (Bogie *) 0;
+    return new;
+}
+
+/*
+ * Free a Bogie.
+ *
+ * Args:
+ *    b - The bogie to free.
+ */
+
+static void
+freeBogie(Bogie *b) 
+{
+    if (b->name != (char *) 0)
+       free(b->name);
+    free(b);
+}
+
+/*
+ * Find a bogie by name in a list.
+ *
+ * This does a simple linear search of the list for a given name.
+ *
+ * Args:
+ *    bl   - The Bogie list to search.
+ *    name - The name to look for.
+ *
+ * Returns:
+ *    The requested Bogie or null if it wasn't found.
+ */
+
+static Bogie *
+findNode(Bogie *bl, char *name) 
+{
+
+    /* Local Variables */
+
+    Bogie *p;
+
+    /* Abort if the list is empty or no name is given */
+
+    if ((name == NULL) || (bl == NULL))
+       return NULL;
+
+    /* Search the list for the desired name */
+
+    p = bl;
+    while (p != NULL) {
+       if (strcmp(p->name, name) == 0)
+           return p;
+       p = p->next;
+    }
+
+    /* Not found */
+
+    return NULL;
+}
+
+#ifdef HAVE_PING
+
+/*
+ * Lookup the address for a ping target;
+ *
+ * Args:
+ *    target - The ping_target fill in the address for.
+ *
+ * Returns:
+ *    1 if the host was successfully resolved, 0 otherwise.
+ */
+
+static int
+lookupHost(ping_target *target) 
+{
+
+    /* Local Variables */
+
+    struct sockaddr_in *iaddr;
+
+    /* Set up the target address we first assume that the name is the
+       IP address as a string */
+
+    iaddr = (struct sockaddr_in *) &(target->address);
+    iaddr->sin_family = AF_INET;
+    if ((iaddr->sin_addr.s_addr = inet_addr(target->name)) == -1) {
+
+       /* Conversion of IP address failed, try to look the host up by name */
+
+       struct hostent *hent = gethostbyname(target->name);
+       if (hent == NULL) {
+           fprintf(stderr, "Could not resolve host %s\n", target->name);
+           return 0;
+       }
+       memcpy(&iaddr->sin_addr, hent->h_addr_list[0],
+              sizeof(iaddr->sin_addr));
+    }
+
+    /* Done */
+
+    return 1;
+}
+
+/*
+ * Create a target for a host.
+ *
+ * Args:
+ *    name - The name of the host.
+ *
+ * Returns:
+ *    A newly allocated target or null if the host could not be resolved.
+ */
+
+static ping_target *
+newHost(char *name) 
+{
+
+    /* Local Variables */
+
+    ping_target *target = NULL;
+
+    /* Create the target */
+
+    if ((target = calloc(1, sizeof(ping_target))) == NULL) {
+       fprintf(stderr, "Out of Memory\n");
+       goto target_init_error;
+    }
+    if ((target->name = strdup(name)) == NULL) {
+       fprintf(stderr, "Out of Memory\n");
+       goto target_init_error;
+    }
+
+    /* Lookup the host */
+
+    if (! lookupHost(target))
+       goto target_init_error;
+
+    /* Done */
+
+    return target;
+
+    /* Handle errors here */
+
+target_init_error:
+    if (target != NULL)
+       free(target);
+    return NULL;
+}
+
+/*
+ * Generate a list of ping targets from the entries in a file.
+ *
+ * Args:
+ *    fname - The name of the file. This file is expected to be in the same
+ *            format as /etc/hosts.
+ *
+ * Returns:
+ *    A list of targets to ping or null if an error occured.
+ */
+
+static ping_target *
+readPingHostsFile(char *fname) 
+{
+
+    /* Local Variables */
+
+    FILE *fp;
+    char buf[LINE_MAX];
+    char *p;
+    ping_target *list = NULL;
+    char *addr, *name;
+    ping_target *new;
+
+    /* Make sure we in fact have a file to process */
+
+    if ((fname == NULL) || (fname[0] == '\0')) {
+       fprintf(stderr, "Invalid ping host file name\n");
+       return NULL;
+    }
+
+    /* Open the file */
+
+    if ((fp = fopen(fname, "r")) == NULL) {
+       char msg[1024];
+       sprintf(msg, "Unable to open host file %s", fname);
+       perror(msg);
+       return NULL;
+    }
+
+    /* Read the file line by line */
+
+    while ((p = fgets(buf, LINE_MAX, fp)) != NULL) {
+
+       /*
+        * Parse the line skipping those that start with '#'.
+        * The rest of the lines in the file should be in the same
+        * format as a /etc/hosts file. We are only concerned with
+        * the first two field, the IP address and the name
+        */
+
+       while ((*p == ' ') || (*p == '\t'))
+           p++;
+       if (*p == '#')
+           continue;
+
+       /* Get the name and address */
+
+       name = addr = NULL;
+       if ((addr = strtok(buf, " \t\n")) != NULL)
+           name = strtok(NULL, " \t\n");
+       else
+           continue;
+
+       /* Create a new target using first the name then the address */
+
+       new = NULL;
+       if (name != NULL)
+           new = newHost(name);
+       if (new == NULL)
+           new = newHost(addr);
+
+       /* Add it to the list if we got one */
+
+       if (new != NULL) {
+           new->next = list;
+           list = new;
+       }
+    }
+
+    /* Close the file and return the list */
+
+    fclose(fp);
+    return list;
+}
+
+/*
+ * Generate a list of ping targets from the entries in a string.
+ *
+ * Args:
+ *    list - A list of comma separated host names.
+ *
+ * Returns:
+ *    A list of targets to ping or null if an error occured.
+ */
+
+static ping_target *
+readPingHostsList(char *list) 
+{
+
+    /* Local Variables */
+
+    char *host;
+    ping_target *hostlist = NULL;
+    ping_target *new;
+
+    /* Check that there is a list */
+
+    if ((list == NULL) || (list[0] == '\0'))
+       return NULL;
+
+    /* Loop through the hosts and add them to the list to return */
+
+    host = strtok(list, ",");
+    while (host != NULL) {
+       new = newHost(host);
+       if (new != NULL) {
+           new->next = hostlist;
+           hostlist = new;
+       }
+       host = strtok(NULL, ",");
+    }
+
+    /* Done */
+
+    return hostlist;
+}
+
+/*
+ * Generate a list ping targets consisting of all of the entries on
+ * the same subnet.
+ *
+ * Returns:
+ *    A list of all of the hosts on this net.
+ */
+
+static ping_target *
+subnetHostsList(void) 
+{
+
+    /* Local Variables */
+
+    char hostname[BUFSIZ];
+    char address[BUFSIZ];
+    struct hostent *hent;
+    char *p;
+    int i;
+    ping_target *new;
+    ping_target *list = NULL;
+
+    /* Get our hostname */
+
+    if (gethostname(hostname, BUFSIZ)) {
+       fprintf(stderr, "Unable to get local hostname\n");
+       return NULL;
+    }
+
+    /* Get our IP address and convert it to a string */
+
+    if ((hent = gethostbyname(hostname)) == NULL) {
+       fprintf(stderr, "Unable to lookup our IP address\n");
+       return NULL;
+    }
+    strcpy(address, inet_ntoa(*((struct in_addr *)hent->h_addr_list[0])));
+
+    /* Get a pointer to the last "." in the string */
+
+    if ((p = strrchr(address, '.')) == NULL) {
+       fprintf(stderr, "Can't parse IP address %s\n", address);
+       return NULL;
+    }
+    p++;
+
+    /* Construct targets for all addresses in this subnet */
+
+    for (i = 254; i > 0; i--) {
+       sprintf(p, "%d", i);
+       new = newHost(address);
+       if (new != NULL) {
+           new->next = list;
+           list = new;
+       }
+    }
+  
+    /* Done */
+
+    return list;
+}
+
+/*
+ * Initialize the ping sensor.
+ *
+ * Returns:
+ *    A newly allocated ping_info structure or null if an error occured.
+ */
+
+static ping_info *
+init_ping(void) 
+{
+
+    /* Local Variables */
+
+    ping_info *pi = NULL;              /* The new ping_info struct */
+    char *src;                         /* The source of the ping hosts */
+    ping_target *pt;                   /* Used to count the targets */
+
+    /* Create the ping info structure */
+
+    if ((pi = (ping_info *) calloc(1, sizeof(ping_info))) == NULL) {
+       fprintf(stderr, "Out of memory\n");
+       goto ping_init_error;
+    }
+
+    /* Create the ICMP socket and turn off SUID */
+
+    if ((pi->icmpsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
+       perror("Can't create ICMP socket");
+       fprintf(stderr,
+         "%s: this program must be setuid to root for `ping mode' to work.\n",
+                progname);
+       goto ping_init_error;
+    }
+    setuid(getuid());
+    pi->pid = getpid() & 0xFFFF;
+    pi->seq = 0;
+    pi->timeout = get_integer_resource("pingTimeout", "PingTimeout");
+
+    /* Generate a list of targets */
+
+    src = get_string_resource("pingSource", "PingSource");
+    if (strcmp(src, "file") == 0) {
+
+       /*
+         * The list of ping targets is to come from a file in
+        * /etc/hosts format
+        */
+
+       pi->targets = readPingHostsFile(get_string_resource("pingFile",
+                                                           "PingFile"));
+
+    } else if (strcmp(src, "list") == 0) {
+
+       /* The list of hosts is to come from the pinghostlist resource */
+
+       pi->targets = readPingHostsList(get_string_resource("pingList",
+                                                           "PingList"));
+
+    } else if (strcmp(src, "subnet") == 0) {
+
+       pi->targets = subnetHostsList();
+
+    } else {
+
+       /* Unknown source */
+
+       fprintf(stderr, "Illegal pingSource: %s\n", src);
+       goto ping_init_error;
+    }
+
+    /* Make sure there is something to ping */
+
+    if (pi->targets == NULL) {
+       fprintf(stderr, "Nothing to ping");
+       goto ping_init_error;
+    }
+
+    /* Count the targets */
+
+    pt = pi->targets;
+    pi->numtargets = 0;
+    while (pt != NULL) {
+       pi->numtargets++;
+       pt = pt->next;
+    }
+
+    /* Done */
+
+    return pi;
+
+    /* Handle initialization errors here */
+
+ping_init_error:
+    if (pi != NULL)
+       free(pi);
+    return NULL;
+}
+
+/*
+ * Ping a host.
+ *
+ * Args:
+ *    pi   - The ping information strcuture.
+ *    host - The name or IP address of the host to ping (in ascii).
+ */
+
+static void
+sendping(ping_info *pi, ping_target *pt) 
+{
+
+    /* Local Variables */
+
+    u_char *packet;
+    struct icmp *icmph;
+    int result;
+
+    /*
+     * Note, we will send the character name of the host that we are
+     * pinging in the packet so that we don't have to keep track of the
+     * name or do an address lookup when it comes back.
+     */
+
+    int pcktsiz = sizeof(struct icmp) + sizeof(struct timeval) +
+       strlen(pt->name) + 1;
+
+    /* Create the ICMP packet */
+
+    if ((packet = (u_char *) malloc(pcktsiz)) == (void *) 0)
+       return;  /* Out of memory */
+    icmph = (struct icmp *) packet;
+    icmph->icmp_type = ICMP_ECHO;
+    icmph->icmp_code = 0;
+    icmph->icmp_cksum = 0;
+    icmph->icmp_id = pi->pid;
+    icmph->icmp_seq = pi->seq++;
+    gettimeofday((struct timeval *) &packet[sizeof(struct icmp)],
+                (struct timezone *) 0);
+    strcpy((char *) &packet[sizeof(struct icmp) + sizeof(struct timeval)],
+          pt->name);
+    icmph->icmp_cksum = checksum((u_short *)packet, pcktsiz);
+
+    /* Send it */
+
+    if ((result = sendto(pi->icmpsock, packet, pcktsiz, 0, 
+                        &pt->address, sizeof(pt->address))) !=  pcktsiz) {
+#if 0
+        char errbuf[BUFSIZ];
+        sprintf(errbuf, "Error sending ping to %s", pt->name);
+       perror(errbuf);
+#endif
+    }
+}
+
+/*
+ * Catch a signal and do nothing.
+ *
+ * Args:
+ *    sig - The signal that was caught.
+ */
+
+static void
+sigcatcher(int sig)
+{
+    timer_expired = 1;
+}
+
+/*
+ * Compute the checksum on a ping packet.
+ *
+ * Args:
+ *    packet - A pointer to the packet to compute the checksum for.
+ *    size   - The size of the packet.
+ *
+ * Returns:
+ *    The computed checksum
+ *    
+ */
+
+static u_short
+checksum(u_short *packet, int size) 
+{
+
+    /* Local Variables */
+
+    register int nleft = size;
+    register u_short *w = packet;
+    register int sum = 0;
+    u_short answer = 0;
+
+    /*
+     * Our algorithm is simple, using a 32 bit accumulator (sum), we add
+     * sequential 16 bit words to it, and at the end, fold back all the
+     * carry bits from the top 16 bits into the lower 16 bits.
+     */
+
+    while (nleft > 1)  {
+       sum += *w++;
+       nleft -= 2;
+    }
+
+    /* mop up an odd byte, if necessary */
+
+    if (nleft == 1) {
+       *(u_char *)(&answer) = *(u_char *)w ;
+       sum += answer;
+    }
+
+    /* add back carry outs from top 16 bits to low 16 bits */
+
+    sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
+    sum += (sum >> 16);                     /* add carry */
+    answer = ~sum;                          /* truncate to 16 bits */
+
+    /* Done */
+
+    return(answer);
+}
+
+/*
+ * Look for ping replies.
+ *
+ * Retrieve all outstanding ping replies.
+ *
+ * Args:
+ *    si - Information about the sonar.
+ *    pi - Ping information.
+ *    ttl - The time each bogie is to live on the screen
+ *
+ * Returns:
+ *    A Bogie list of all the machines that replied.
+ */
+
+static Bogie *
+getping(sonar_info *si, ping_info *pi, int ttl) 
+{
+
+    /* Local Variables */
+
+    struct sockaddr from;
+    int fromlen;
+    int result;
+    u_char packet[1024];
+    struct timeval now;
+    struct timeval *then;
+    struct ip *ip;
+    int iphdrlen;
+    struct icmp *icmph;
+    Bogie *bl = NULL;
+    Bogie *new;
+    char *name;
+    struct sigaction sa;
+    struct itimerval it;
+
+    /* Set up a signal to interupt our wait for a packet */
+
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = 0;
+    sa.sa_handler = sigcatcher;
+    if (sigaction(SIGALRM, &sa, 0) == -1) {
+       perror("Unable to trap sigalarm");
+       exit(1);
+    }
+
+    /* Set up a timer to interupt us if we don't get a packet */
+
+    it.it_interval.tv_sec = 0;
+    it.it_interval.tv_usec = 0;
+    it.it_value.tv_sec = 0;
+    it.it_value.tv_usec = pi->timeout;
+    timer_expired = 0;
+    setitimer(ITIMER_REAL, &it, NULL);
+
+    /* Wait for a result packet */
+
+    fromlen = sizeof(from);
+    while (! timer_expired &&
+          (result = recvfrom(pi->icmpsock, packet, sizeof(packet),
+                             0, &from, &fromlen)) > 0) {
+
+       /* Check the packet */
+
+       gettimeofday(&now, (struct timezone *) 0);
+       ip = (struct ip *) packet;
+       iphdrlen = ip->ip_hl << 2;
+       icmph = (struct icmp *) &packet[iphdrlen];
+
+       /* Was the packet a reply?? */
+
+       if (icmph->icmp_type != ICMP_ECHOREPLY) {
+           /* Ignore anything but ICMP Replies */
+           continue; /* Nope */
+       }
+
+       /* Was it for us? */
+
+       if (icmph->icmp_id != pi->pid) {
+           /* Ignore packets not set from us */
+           continue; /* Nope */
+       }
+
+       /* Copy the name of the bogie */
+
+       if ((name =
+            strdup((char *) &packet[iphdrlen + 
+                                   + sizeof(struct icmp)
+                                   + sizeof(struct timeval)])) == NULL) {
+           fprintf(stderr, "Out of memory\n");
+           return bl;
+       }
+
+        /* If the name is an IP addr, try to resolve it. */
+        {
+          int iip[4];
+          char c;
+          if (4 == sscanf(name, " %d.%d.%d.%d %c",
+                          &iip[0], &iip[1], &iip[2], &iip[3], &c))
+            {
+              unsigned char ip[4];
+              struct hostent *h;
+              ip[0] = iip[0]; ip[1] = iip[1]; ip[2] = iip[2]; ip[3] = iip[3];
+              h = gethostbyaddr ((char *) ip, 4, AF_INET);
+              if (h && h->h_name && *h->h_name)
+                {
+                  free (name);
+                  name = strdup (h->h_name);
+                }
+            }
+        }
+
+       /* Create the new Bogie and add it to the list we are building */
+
+       if ((new = newBogie(name, 0, si->current, ttl)) == NULL)
+           return bl;
+       new->next = bl;
+       bl = new;
+
+       /* Compute the round trip time */
+
+       then =  (struct timeval *) &packet[iphdrlen +
+                                         sizeof(struct icmp)];
+       new->distance = delta(then, &now) / 100;
+       if (new->distance == 0)
+               new->distance = 2; /* HACK */
+    }
+
+    /* Done */
+
+    return bl;
+}
+
+/*
+ * Ping hosts.
+ *
+ * Args:
+ *    si - Sonar Information.
+ *    pi - Ping Information.
+ *
+ * Returns:
+ *    A list of hosts that replied to pings or null if there were none.
+ */
+
+static Bogie *
+ping(sonar_info *si, void *vpi) 
+{
+
+    ping_info *pi = (ping_info *) vpi;
+    static ping_target *ptr = NULL;
+
+    int tick = si->current * -1 + 1;
+    if ((ptr == NULL) && (tick == 1))
+       ptr = pi->targets;
+
+    if (pi->numtargets <= 90) {
+       int xdrant = 90 / pi->numtargets;
+       if ((tick % xdrant) == 0) {
+           if (ptr != (ping_target *) 0) {
+               sendping(pi, ptr);
+               ptr = ptr->next;
+           }
+       }
+
+    } else if (pi->numtargets > 90) {
+       if (ptr != (ping_target *) 0) {
+           sendping(pi, ptr);
+           ptr = ptr->next;
+       }
+    }
+
+    /* Get the results */
+
+    return getping(si, pi, TTL);
+}
+
+#endif /* HAVE_PING */
+
+/*
+ * Calculate the difference between two timevals in microseconds.
+ *
+ * Args:
+ *    then - The older timeval.
+ *    now  - The newer timeval.
+ *
+ * Returns:
+ *   The difference between the two in microseconds.
+ */
+
+static long
+delta(struct timeval *then, struct timeval *now) 
+{
+    return (((now->tv_sec - then->tv_sec) * 1000000) + 
+              (now->tv_usec - then->tv_usec));  
+}
+
+/*
+ * Initialize the simulation mode.
+ */
+
+static sim_info *
+init_sim(void) 
+{
+
+    /* Local Variables */
+
+    sim_info *si;
+    int i;
+
+    /* Seed the random number generator */
+
+    srand((int) time(NULL));
+
+    /* Create the simulation info structure */
+
+    if ((si = (sim_info *) calloc(1, sizeof(sim_info))) == NULL) {
+       fprintf(stderr, "Out of memory\n");
+       return NULL;
+    }
+
+    /* Team A */
+
+    si->numA = get_integer_resource("teamACount", "TeamACount");
+    if ((si->teamA = (sim_target *)calloc(si->numA, sizeof(sim_target)))
+       == NULL) {
+       free(si);
+       fprintf(stderr, "Out of Memory\n");
+       return NULL;
+    }
+    si->teamAID = get_string_resource("teamAName", "TeamAName");
+    for (i = 0; i < si->numA; i++) {
+       if ((si->teamA[i].name = (char *) malloc(strlen(si->teamAID) + 4))
+           == NULL) {
+           free(si);
+           fprintf(stderr, "Out of Memory\n");
+           return NULL;
+       }
+       sprintf(si->teamA[i].name, "%s%03d", si->teamAID, i+1);
+       si->teamA[i].nexttick = (int) (90.0 * rand() / RAND_MAX);
+       si->teamA[i].nextdist = (int) (100.0 * rand() / RAND_MAX);
+    }
+
+    /* Team B */
+
+    si->numB = get_integer_resource("teamBCount", "TeamBCount");
+    if ((si->teamB = (sim_target *)calloc(si->numB, sizeof(sim_target)))
+       == NULL) {
+       free(si);
+       fprintf(stderr, "Out of Memory\n");
+       return NULL;
+    }
+    si->teamBID = get_string_resource("teamBName", "TeamBName");
+    for (i = 0; i < si->numB; i++) {
+       if ((si->teamB[i].name = (char *) malloc(strlen(si->teamBID) + 4))
+           == NULL) {
+           free(si);
+           fprintf(stderr, "Out of Memory\n");
+           return NULL;
+       }
+       sprintf(si->teamB[i].name, "%s%03d", si->teamBID, i+1);
+       si->teamB[i].nexttick = (int) (90.0 * rand() / RAND_MAX);
+       si->teamB[i].nextdist = (int) (100.0 * rand() / RAND_MAX);
+    }
+
+    /* Done */
+
+    return si;
+}
+
+/*
+ * Initialize the Sonar.
+ *
+ * Args:
+ *    dpy - The X display.
+ *    win - The X window;
+ *
+ * Returns:
+ *   A sonar_info strcuture or null if memory allocation problems occur.
+ */
+
+static sonar_info *
+init_sonar(Display *dpy, Window win) 
+{
+
+    /* Local Variables */
+
+    XGCValues gcv;
+    XWindowAttributes xwa;
+    sonar_info *si;
+    XColor start, end;
+    int h1, h2;
+    double s1, s2, v1, v2;
+
+    /* Create the Sonar information structure */
+
+    if ((si = (sonar_info *) calloc(1, sizeof(sonar_info))) == NULL) {
+       fprintf(stderr, "Out of memory\n");
+       return NULL;
+    }
+
+    /* Initialize the structure for the current environment */
+
+    si->dpy = dpy;
+    si->win = win;
+    si->visable = NULL;
+    XGetWindowAttributes(dpy, win, &xwa);
+    si->cmap = xwa.colormap;
+    si->width = xwa.width;
+    si->height = xwa.height;
+    si->centrex = si->width / 2;
+    si->centrey = si->height / 2;
+    si->maxx = si->centrex + MIN(si->centrex, si->centrey) - 10;
+    si->minx = si->centrex - MIN(si->centrex, si->centrey) + 10;
+    si->maxy = si->centrey + MIN(si->centrex, si->centrey) - 10;
+    si->miny = si->centrey - MIN(si->centrex, si->centrey) + 10;
+    si->radius = si->maxx - si->centrex;
+    si->current = 0;
+
+    /* Get the font */
+
+    if (((si->font = XLoadQueryFont(dpy, get_string_resource ("font", "Font")))
+        == NULL) &&
+       ((si->font = XLoadQueryFont(dpy, "fixed")) == NULL)) {
+       fprintf(stderr, "Can't load an appropriate font\n");
+       return NULL;
+    }
+
+    /* Get the delay between animation frames */
+
+    si->delay = get_integer_resource ("delay", "Integer");
+    if (si->delay < 0) si->delay = 0;
+
+    /* Create the Graphics Contexts that will be used to draw things */
+
+    gcv.foreground = 
+       get_pixel_resource ("sweepColor", "SweepColor", dpy, si->cmap);
+    si->hi = XCreateGC(dpy, win, GCForeground, &gcv);
+    gcv.font = si->font->fid;
+    si->text = XCreateGC(dpy, win, GCForeground|GCFont, &gcv);
+    gcv.foreground = get_pixel_resource("scopeColor", "ScopeColor",
+                                       dpy, si->cmap);
+    si->erase = XCreateGC (dpy, win, GCForeground, &gcv);
+    gcv.foreground = get_pixel_resource("gridColor", "GridColor",
+                                       dpy, si->cmap);
+    si->grid = XCreateGC (dpy, win, GCForeground, &gcv);
+
+    /* Compute pixel values for fading text on the display */
+
+    XParseColor(dpy, si->cmap, 
+               get_string_resource("textColor", "TextColor"), &start);
+    XParseColor(dpy, si->cmap, 
+               get_string_resource("scopeColor", "ScopeColor"), &end);
+
+    rgb_to_hsv (start.red, start.green, start.blue, &h1, &s1, &v1);
+    rgb_to_hsv (end.red, end.green, end.blue, &h2, &s2, &v2);
+
+    si->text_steps = get_integer_resource("textSteps", "TextSteps");
+    if (si->text_steps < 0 || si->text_steps > 255)
+      si->text_steps = 10;
+
+    si->text_colors = (XColor *) calloc(si->text_steps, sizeof(XColor));
+    make_color_ramp (dpy, si->cmap,
+                     h1, s1, v1,
+                     h2, s2, v2,
+                     si->text_colors, &si->text_steps,
+                     False, True, False);
+
+    /* Compute the pixel values for the fading sweep */
+
+    XParseColor(dpy, si->cmap, 
+                get_string_resource("sweepColor", "SweepColor"), &start);
+
+    rgb_to_hsv (start.red, start.green, start.blue, &h1, &s1, &v1);
+
+    si->sweep_degrees = get_integer_resource("sweepDegrees", "Degrees");
+    if (si->sweep_degrees <= 0) si->sweep_degrees = 20;
+    if (si->sweep_degrees > 350) si->sweep_degrees = 350;
+
+    si->sweep_segs = get_integer_resource("sweepSegments", "SweepSegments");
+    if (si->sweep_segs < 1 || si->sweep_segs > 255)
+      si->sweep_segs = 255;
+
+    si->sweep_colors = (XColor *) calloc(si->sweep_segs, sizeof(XColor));
+    make_color_ramp (dpy, si->cmap,
+                     h1, s1, v1,
+                     h2, s2, v2,
+                     si->sweep_colors, &si->sweep_segs,
+                     False, True, False);
+
+    /* Done */
+
+    return si;
+}
+
+/*
+ * Update the location of a simulated bogie.
+ */
+
+static void
+updateLocation(sim_target *t) 
+{
+
+    int xdist, xtick;
+
+    t->movedlasttick = 1;
+    xtick = (int) (3.0 * rand() / RAND_MAX) - 1;
+    xdist = (int) (11.0 * rand() / RAND_MAX) - 5;
+    if (((t->nexttick + xtick) < 90) && ((t->nexttick + xtick) >= 0))
+       t->nexttick += xtick;
+    else
+       t->nexttick -= xtick;
+    if (((t->nextdist + xdist) < 100) && ((t->nextdist+xdist) >= 0))
+       t->nextdist += xdist;
+    else
+       t->nextdist -= xdist;
+}
+
+/*
+ * The simulator. This uses information in the sim_info to simulate a bunch
+ * of bogies flying around on the screen.
+ */
+
+/*
+ * TODO: It would be cool to have the two teams chase each other around and
+ *       shoot it out.
+ */
+
+static Bogie *
+simulator(sonar_info *si, void *vinfo) 
+{
+
+    /* Local Variables */
+
+    int i;
+    Bogie *list = NULL;
+    Bogie *new;
+    sim_target *t;
+    sim_info *info = (sim_info *) vinfo;
+
+    /* Check team A */
+
+    for (i = 0; i < info->numA; i++) {
+       t = &info->teamA[i];
+       if (!t->movedlasttick && (t->nexttick == (si->current * -1))) {
+           new = newBogie(strdup(t->name), t->nextdist, si->current, TTL);
+           if (list != NULL)
+               new->next = list;
+           list = new;
+           updateLocation(t);
+       } else
+           t->movedlasttick = 0;
+    }
+
+    /* Team B */
+
+    for (i = 0; i < info->numB; i++) {
+       t = &info->teamB[i];
+       if (!t->movedlasttick && (t->nexttick == (si->current * -1))) {
+           new = newBogie(strdup(t->name), t->nextdist, si->current, TTL);
+           if (list != NULL)
+               new->next = list;
+           list = new;
+           t->movedlasttick = 1;
+           updateLocation(t);
+       } else
+           t->movedlasttick = 0;
+    }
+
+    /* Done */
+
+    return list;
+}
+
+/*
+ * Compute the X coordinate of the label.
+ *
+ * Args:
+ *    si - The sonar info block.
+ *    label - The label that will be drawn.
+ *    x - The x coordinate of the bogie.
+ *
+ * Returns:
+ *    The x coordinate of the start of the label.
+ */
+
+static int
+computeStringX(sonar_info *si, char *label, int x) 
+{
+
+    int width = XTextWidth(si->font, label, strlen(label));
+    return x - (width / 2);
+}
+
+/*
+ * Compute the Y coordinate of the label.
+ *
+ * Args:
+ *    si - The sonar information.
+ *    y - The y coordinate of the bogie.
+ *
+ * Returns:
+ *    The y coordinate of the start of the label.
+ */
+
+/* TODO: Add smarts to keep label in sonar screen */
+
+static int
+computeStringY(sonar_info *si, int y) 
+{
+
+    int fheight = si->font->ascent + si->font->descent;
+    return y + 5 + fheight;
+}
+
+/*
+ * Draw a Bogie on the radar screen.
+ *
+ * Args:
+ *    si       - Sonar Information.
+ *    draw     - A flag to indicate if the bogie should be drawn or erased.
+ *    name     - The name of the bogie.
+ *    degrees  - The number of degrees that it should apprear at.
+ *    distance - The distance the object is from the centre.
+ *    ttl      - The time this bogie has to live.
+ *    age      - The time this bogie has been around.
+ */
+
+static void
+DrawBogie(sonar_info *si, int draw, char *name, int degrees, 
+         int distance, int ttl, int age) 
+{
+
+    /* Local Variables */
+
+    int x, y;
+    GC gc;
+    int ox = si->centrex;
+    int oy = si->centrey;
+    int index, delta;
+
+    /* Compute the coordinates of the object */
+
+    distance = (log((double) distance) / 10.0) * si->radius;
+    x = ox + ((double) distance * cos(4.0 * ((double) degrees)/57.29578));
+    y = oy - ((double) distance * sin(4.0 * ((double) degrees)/57.29578));
+
+    /* Set up the graphics context */
+
+    if (draw) {
+
+       /* Here we attempt to compute the distance into the total life of
+        * object that we currently are. This distance is used against
+        * the total lifetime to compute a fraction which is the index of
+        * the color to draw the bogie.
+        */
+
+       if (si->current <= degrees)
+           delta = (si->current - degrees) * -1;
+       else
+           delta = 90 + (degrees - si->current);
+       delta += (age * 90);
+       index = (si->text_steps - 1) * ((float) delta / (90.0 * (float) ttl));
+       gc = si->text;
+       XSetForeground(si->dpy, gc, si->text_colors[index].pixel);
+
+    } else
+       gc = si->erase;
+
+  /* Draw (or erase) the Bogie */
+
+    XFillArc(si->dpy, si->win, gc, x, y, 5, 5, 0, 360 * 64);
+    XDrawString(si->dpy, si->win, gc,
+               computeStringX(si, name, x),
+               computeStringY(si, y), name, strlen(name));
+}
+
+
+/*
+ * Draw the sonar grid.
+ *
+ * Args:
+ *    si - Sonar information block.
+ */
+
+static void
+drawGrid(sonar_info *si) 
+{
+
+    /* Local Variables */
+
+    int i;
+    int width = si->maxx - si->minx;
+    int height = si->maxy - si->miny;
+  
+    /* Draw the circles */
+
+    XDrawArc(si->dpy, si->win, si->grid, si->minx - 10, si->miny - 10, 
+            width + 20, height + 20,  0, (360 * 64));
+
+    XDrawArc(si->dpy, si->win, si->grid, si->minx, si->miny, 
+            width, height,  0, (360 * 64));
+
+    XDrawArc(si->dpy, si->win, si->grid, 
+            (int) (si->minx + (.166 * width)), 
+            (int) (si->miny + (.166 * height)), 
+            (unsigned int) (.666 * width), (unsigned int)(.666 * height),
+            0, (360 * 64));
+
+    XDrawArc(si->dpy, si->win, si->grid, 
+            (int) (si->minx + (.333 * width)),
+            (int) (si->miny + (.333 * height)), 
+            (unsigned int) (.333 * width), (unsigned int) (.333 * height),
+            0, (360 * 64));
+
+    /* Draw the radial lines */
+
+    for (i = 0; i < 360; i += 10)
+       if (i % 30 == 0)
+           XDrawLine(si->dpy, si->win, si->grid, si->centrex, si->centrey,
+                     (int) (si->centrex +
+                     (si->radius + 10) * (cos((double) i / 57.29578))),
+                     (int) (si->centrey -
+                     (si->radius + 10)*(sin((double) i / 57.29578))));
+       else
+           XDrawLine(si->dpy, si->win, si->grid, 
+                     (int) (si->centrex + si->radius *
+                            (cos((double) i / 57.29578))),
+                     (int) (si->centrey - si->radius *
+                            (sin((double) i / 57.29578))),
+                     (int) (si->centrex +
+                     (si->radius + 10) * (cos((double) i / 57.29578))),
+                     (int) (si->centrey - 
+                     (si->radius + 10) * (sin((double) i / 57.29578))));
+}
+
+/*
+ * Update the Sonar scope.
+ *
+ * Args:
+ *    si - The Sonar information.
+ *    bl - A list  of bogies to add to the scope.
+ */
+
+static void
+Sonar(sonar_info *si, Bogie *bl) 
+{
+
+    /* Local Variables */
+
+    Bogie *bp, *prev;
+    int i;
+
+    /* Check for expired tagets and remove them from the visable list */
+
+    prev = NULL;
+    for (bp = si->visable; bp != NULL; bp = bp->next) {
+
+       /*
+        * Remove it from the visable list if it's expired or we have
+        * a new target with the same name.
+        */
+
+       bp->age ++;
+
+       if (((bp->tick == si->current) && (++bp->age >= bp->ttl)) ||
+           (findNode(bl, bp->name) != NULL)) {
+           DrawBogie(si, 0, bp->name, bp->tick,
+                     bp->distance, bp->ttl, bp->age);
+           if (prev == NULL)
+               si->visable = bp->next;
+           else
+               prev->next = bp->next;
+           freeBogie(bp);
+       } else
+           prev = bp;
+    }
+
+    /* Draw the sweep */
+
+    {
+      int seg_deg = (si->sweep_degrees * 64) / si->sweep_segs;
+      int start_deg = si->current * 4 * 64;
+      if (seg_deg <= 0) seg_deg = 1;
+      for (i = 0; i < si->sweep_segs; i++) {
+       XSetForeground(si->dpy, si->hi, si->sweep_colors[i].pixel);
+       XFillArc(si->dpy, si->win, si->hi, si->minx, si->miny, 
+                si->maxx - si->minx, si->maxy - si->miny,
+                 start_deg + (i * seg_deg),
+                 seg_deg);
+      }
+
+      /* Remove the trailing wedge the sonar */
+      XFillArc(si->dpy, si->win, si->erase, si->minx, si->miny, 
+               si->maxx - si->minx, si->maxy - si->miny, 
+               start_deg + (i * seg_deg),
+               (4 * 64));
+    }
+
+    /* Move the new targets to the visable list */
+
+    for (bp = bl; bp != (Bogie *) 0; bp = bl) {
+       bl = bl->next;
+       bp->next = si->visable;
+       si->visable = bp;
+    }
+
+    /* Draw the visable targets */
+
+    for (bp = si->visable; bp != NULL; bp = bp->next) {
+       if (bp->age < bp->ttl)          /* grins */
+          DrawBogie(si, 1, bp->name, bp->tick, bp->distance, bp->ttl,bp->age);
+    }
+
+    /* Redraw the grid */
+
+    drawGrid(si);
+}
+
+/*
+ * Main screen saver hack.
+ *
+ * Args:
+ *    dpy - The X display.
+ *    win - The X window.
+ */
+
+void 
+screenhack(Display *dpy, Window win) 
+{
+
+    /* Local Variables */
+
+    sonar_info *si;
+    struct timeval start, finish;
+    Bogie *bl;
+    long sleeptime;
+    char *mode;
+
+    /* 
+     * Initialize 
+     * Adding new sensors would involve supporting more modes other than
+     * ping and initiailizing the sensor in the same way.
+     */
+
+    mode = get_string_resource("mode", "Mode");
+
+    if (!mode || !*mode || !strcmp(mode, "default")) /* Pick a good default. */
+      {
+#ifdef HAVE_PING
+        if (geteuid() == 0)    /* we're root or setuid -- ping will work. */
+          mode = "ping";
+        else
+#endif
+          mode = "simulation";
+      }
+
+#ifdef HAVE_PING
+    if (strcmp(mode, "ping") == 0) {
+       sensor = ping;
+       if ((sensor_info = (void *) init_ping()) == (void *) 0)
+          {
+            fprintf (stderr, "%s: running in `simulation mode' instead.\n",
+                     progname);
+           goto SIM;
+          }
+    } else
+#endif /* HAVE_PING */
+    if (strcmp(mode, "simulation") == 0) {
+#ifdef HAVE_PING
+    SIM:
+#endif
+       sensor = simulator;
+       if ((sensor_info = (void *) init_sim()) == NULL)
+           exit(1);
+    } else {
+       fprintf(stderr, "Unsupported Sonar mode: %s\n", mode);
+       fprintf(stderr,
+                "\tCurrently supported modes are `ping' and `simulation'\n");
+       exit(1);
+    }
+    if ((si = init_sonar(dpy, win)) == (sonar_info *) 0)
+       exit(1);
+  
+    /* Sonar loop */
+
+    TTL = get_integer_resource("ttl", "TTL");
+
+    while (1) {
+
+       /* Call the sensor and display the results */
+
+       gettimeofday(&start, (struct timezone *) 0);
+       bl = sensor(si, sensor_info);
+       Sonar(si, bl);
+
+        /* Set up and sleep for the next one */
+
+       si->current = (si->current - 1) % 90;
+       XSync (dpy, False);
+       gettimeofday(&finish, (struct timezone *) 0);
+       sleeptime = si->delay - delta(&start, &finish);
+        screenhack_handle_events (dpy);
+       if (sleeptime > 0L)
+           usleep(sleeptime);
+    }
+}
diff --git a/hacks/sonar.man b/hacks/sonar.man
new file mode 100644 (file)
index 0000000..7fe7761
--- /dev/null
@@ -0,0 +1,167 @@
+.TH Sonar 1 "3-Nov-98" "X Version 11"
+.SH NAME
+sonar - display a sonar scope
+.SH SYNOPSIS
+.B sonar
+[\-background \fIcolor\fP]
+[\-sweep\-color \fIcolor\fP]
+[\-low\-color \fIcolor\fP] 
+[\-scope\-color \fIcolor\fP]
+[\-grid\-color \fIcolor\fP]
+[\-text\-color \fIcolor\fP]
+[\-ttl \fIinteger\fP]
+[\-mode ping]
+[\-font \fIfont\fP]
+[\-ping\-timeout \fIint\fP]
+[\-ping\-source list | file | subnet ] 
+[\-ping\-file \fIhosts-file\fP]
+[\-ping\-list \fIhost-name-list\fP]
+[\-team-a-name \fIstring\fP] 
+[\-team-b-name \fIstring\fP]
+[\-team-a-count \fIint\fP]
+[\-team-b-count \fIint\fP]
+.SH DESCRIPTION
+The \fIsonar\fP program displays a sonar scope on the computer's screen.
+This scope polls a sensor as the sweep goes around the scope and displays
+what it finds as bogies on the screen.  The program is designed to support
+different modes representing different types of sensors.  Currently the
+only implemented sensors are a simulator, and a network ping function that
+pings hosts and plots the results on the scope.
+.SH OPTIONS
+.I sonar
+understands the following options:
+.TP 8
+.B \-background \fIColor\fP
+The background Color of the screen not covered by the scope.
+.TP 8
+.B \-sweep\-color \fIColor\fP
+The color of the brightest part of the sweep.
+.TP 8
+.B \-scope\-color \fIColor\fP
+The color of the circular part of the scope.
+.TP 8
+.B \-grid\-color \fIColor\fP
+The color to the grid lines overlaying the scope.
+.TP 8
+.B \-text\-color \fIColor\fP
+The color of the text identifying bogies on the scope.
+.TP 8
+.B \-ttl \fIinteger\fP
+"Time to live": visible time of a Bogie. Try values between 10 (very short)
+and 100. 
+.TP 8
+.B \-mode \fIsimulation | ping\fP
+The sensor mode to use, the currently supported modes \fIsimulate\fP (the
+default) and \fIping\fP.
+.TP 8
+.B \-font \fIfont\fP
+The font used to display text on the scope.  Default "fixed".
+.TP 8
+.B \-ping\-timeout \fIint\fP
+The amount of time in milliseconds the program will wait for an answer
+to a ping.
+.TP 8
+.B \-ping\-source list | file | subnet
+Th source of the list of hosts to ping. Valid values are: \fIlist\fP,
+\fIfile\fP, \fIsubnet\fP.  The first two values are described below;
+and \fIsubnet\fP indicates that the sonar should ping all hosts in the 
+same subnet as the current machine.  (All addresses are treated
+as class C nets, therefore this will at most ping about 256 hosts.)
+.TP 8
+.B \-ping\-file \fIfilename\fP
+The path to a file in \fI/etc/hosts\fP format. Only used when \fIpingSource\fP 
+is set to \fIfile\fP.
+.TP 8
+.B \-ping\-list \fIlist\fP
+A comma separated list of hostnames, eg \fI"pinky,brain,dot"\fP.
+Only used when \fIpingSource\fP is set to \fIlist\fP.
+.TP 8
+.B \-team-a-name \fIstring\fP
+The name of team A, in simulation-mode.
+.TP 8
+.B \-team-b-name \fIstring\fP
+The name of team B, in simulation-mode.
+.TP 8
+.B \-team-a-count \fIint\fP
+The number of bogies on team A, in simulation-mode.
+.TP 8
+.B \-team-b-count \fIint\fP
+The number of bogies on team B, in simulation-mode.
+.SH RESOURCES
+Configuration of the targets to ping is best done by setting X Resources.
+.PP
+.TP 8
+.B background \fI(Color)\fP
+See option \-background, above; default value is \fIblack\fP.
+.TP 8
+.B sweepColor \fI(Color)\fP
+See option \-sweep\-color, above; default value is \fI#00ff00\fP.
+.TP 8
+.B scopeColor \fI(Color)\fP
+See option \-scope\-color, above; default value is \fI#003300\fP.
+.TP 8
+.B gridColor \fI(Color)\fP
+See option \-grid\-color, above; default value is \fI#00aa00\fP.
+.TP 8
+.B textColor \fI(Color)\fP
+See option \-text\-color, above; default value is \fI#ffff00\fP.
+.TP 8
+.B ttl \fI(integer)\fP
+See option \-ttl, above; default value is \fI90\fP or one sweep.
+.TP 8
+.B mode \fI(ping)\fP
+See option \-mode, above.  If set to \fIdefault\fP, it will ping hosts if
+possible, otherwise, will run in simulation-mode.
+.TP 8
+.B font \fI(font)\fP
+See option \-font, above; default value is \fIfixed\fP.
+.TP 8
+.B pingTimeout \fI(Integer)\fP
+See option \-pingtimeout, above; default value is \fI3000\fP.
+.TP 8
+.B pingSource \fIlist | file | subnet\fP
+See option \-ping\-source, above.  Default value is \fIhostfile\fP.
+.TP 8
+.B pingFile \fIpathname\fP
+See option \-ping\-file, above.  Default value is \fI/etc/hosts\fP.
+.TP 8
+.B pingList \fIhost,host,host...\fP
+See option \-ping\-list, above; default value is \fI"localhost"\fP.
+.TP 8
+.B teamAName \fIstring\fP
+See option \-team\-a\-name, above.  Default value is "F18".
+.TP 8
+.B teamBName \fIstring\fP
+See option \-teamBName, above.  Default value is "MIG".
+.TP 8
+.B teamACount \fIint\fP
+See option \-teamACount, above.  Default value is 4.
+.TP 8
+.B teamBCount \fIint\fP
+See option \-teamBCount, above.  Default value is 4.
+.SH NOTES
+In order to use the ping sensor, this program must be installed as 
+setuid root, so that it can create an ICMP socket.
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1),
+.BR ping (8)
+.SH COPYRIGHT
+Copyright \(co 1998 by Stephen Martin. (smartin@canada.com)
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.  No representations are made about the suitability of this
+software for any purpose.  It is provided "as is" without express or 
+implied warranty.
+
+.SH AUTHORS
+Stephen Martin <smartin@canada.com>, 3-nov-98.
+
+Thanks to Tom Kelly for suggesting a modular approach to the sensor
+amoung other things.
+
+Thomas Bahls <thommy@cs.tu-berlin.de> hacked the "ttl" option, 12-jul-98.
+
index e368164d07b273609e232fb42c6c90648cc898bc..070c034109a1d3ec901c18ae0fb2a71c9555a3f2 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1997 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1997, 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
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -470,8 +470,9 @@ screenhack (Display *dpy, Window window)
   while (1)
     {
       run_starfish (dpy, window, s);
   while (1)
     {
       run_starfish (dpy, window, s);
-      XSync (dpy, True);
+      XSync (dpy, False);
 
 
+      screenhack_handle_events (dpy);
       if (cycle_p && cycle_delay)
        {
          if (cycle_delay <= delay)
       if (cycle_p && cycle_delay)
        {
          if (cycle_delay <= delay)
@@ -518,6 +519,7 @@ screenhack (Display *dpy, Window window)
                  while (i < delay2)
                    {
                      rotate_colors (dpy, cmap, colors, ncolors, direction);
                  while (i < delay2)
                    {
                      rotate_colors (dpy, cmap, colors, ncolors, direction);
+                      screenhack_handle_events (dpy);
                      usleep(cycle_delay);
                      i += cycle_delay;
                    }
                      usleep(cycle_delay);
                      i += cycle_delay;
                    }
index 66cec3db7f4c69b1e8f19eb5107b8e95d764c1a4..cb5391348b475e0a8ba8509331cbce218c4168fe 100644 (file)
@@ -458,8 +458,10 @@ void screenhack(Display *disp, Window win)
          delay = 0;
        }
       else
          delay = 0;
        }
       else
-       XSync(disp,True);
+       XSync(disp, False);
       
       
+      screenhack_handle_events (disp);
+
       /* the delay to try to minimize seizures */
       usleep((delay*1000)); 
       count++;
       /* the delay to try to minimize seizures */
       usleep((delay*1000)); 
       count++;
@@ -488,7 +490,7 @@ static void scroll_area(Display *disp, Window win, int delay, int step_size)
   while(scrollcount_x <= scroll)
     {
       XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
   while(scrollcount_x <= scroll)
     {
       XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
-      XSync(disp,True);
+      XSync(disp, False);
       scrollcount_x=scrollcount_x+step_size;
       scrollcount_y=scrollcount_y+step_size;
       usleep(1000*delay); 
       scrollcount_x=scrollcount_x+step_size;
       scrollcount_y=scrollcount_y+step_size;
       usleep(1000*delay); 
@@ -496,7 +498,7 @@ static void scroll_area(Display *disp, Window win, int delay, int step_size)
   while(scrollcount_x >= 0)
     {
       XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
   while(scrollcount_x >= 0)
     {
       XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
-      XSync(disp,True);
+      XSync(disp, False);
       scrollcount_y=scrollcount_y+step_size;
       scrollcount_x=scrollcount_x-step_size;
       usleep(1000*delay); 
       scrollcount_y=scrollcount_y+step_size;
       scrollcount_x=scrollcount_x-step_size;
       usleep(1000*delay); 
@@ -504,7 +506,7 @@ static void scroll_area(Display *disp, Window win, int delay, int step_size)
   while(scrollcount_y >= scroll)
     {
       XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
   while(scrollcount_y >= scroll)
     {
       XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
-      XSync(disp,True);
+      XSync(disp, False);
       scrollcount_x=scrollcount_x-step_size;
       scrollcount_y=scrollcount_y-step_size;
       usleep(1000*delay); 
       scrollcount_x=scrollcount_x-step_size;
       scrollcount_y=scrollcount_y-step_size;
       usleep(1000*delay); 
@@ -512,13 +514,13 @@ static void scroll_area(Display *disp, Window win, int delay, int step_size)
   while(scrollcount_y > 0)
     {
       XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
   while(scrollcount_y > 0)
     {
       XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
-      XSync(disp,True);
+      XSync(disp, False);
       scrollcount_y=scrollcount_y-step_size;
       scrollcount_x=scrollcount_x+step_size;
       usleep(1000*delay); 
     }
   
       scrollcount_y=scrollcount_y-step_size;
       scrollcount_x=scrollcount_x+step_size;
       usleep(1000*delay); 
     }
   
-  XSync(disp,True);
+  XSync(disp, False);
   scrollcount_x=0;
   scrollcount_y=0;
   
   scrollcount_x=0;
   scrollcount_y=0;
   
index 8f8c1a343dcb76e1c20fa47cc4811a9fce679640..4f50635bb161322aff18a849df7493fec348c2d4 100644 (file)
@@ -171,7 +171,7 @@ screenhack (Display *dpy, Window window)
                              hspace, xgwa.height, False);
                  y--;
                  lines--;
                              hspace, xgwa.height, False);
                  y--;
                  lines--;
-                 XSync (dpy, True);
+                 XSync (dpy, False);
                  if (delay) usleep (delay * 10);
                }
              if (y < 0) y = 0;
                  if (delay) usleep (delay * 10);
                }
              if (y < 0) y = 0;
@@ -238,7 +238,7 @@ screenhack (Display *dpy, Window window)
            {
              x--;
              s--;
            {
              x--;
              s--;
-             XSync (dpy, True);
+             XSync (dpy, False);
              if (delay) usleep (0xFFFF & (delay + (random() % (delay * 10))));
            }
        }
              if (delay) usleep (0xFFFF & (delay + (random() % (delay * 10))));
            }
        }
@@ -306,7 +306,7 @@ screenhack (Display *dpy, Window window)
          s = source;
        }
 
          s = source;
        }
 
-      XSync (dpy, True);
+      XSync (dpy, False);
       if (delay)
        {
          usleep (delay);
       if (delay)
        {
          usleep (delay);
@@ -340,7 +340,7 @@ screenhack (Display *dpy, Window window)
                  if (x >= columns) x = 0, y++;
                  n1++;
                }
                  if (x >= columns) x = 0, y++;
                  n1++;
                }
-             XSync (dpy, True);
+             XSync (dpy, False);
              usleep (5000000);
              while (*n2)
                {
              usleep (5000000);
              while (*n2)
                {
@@ -353,9 +353,10 @@ screenhack (Display *dpy, Window window)
                  n2++;
                }
              y++;
                  n2++;
                }
              y++;
-             XSync (dpy, True);
+             XSync (dpy, False);
              usleep (500000);
            }
        }
              usleep (500000);
            }
        }
+      screenhack_handle_events (dpy);
     }
 }
     }
 }
index ff18c4a0764f0ee8dd332166c99379157381f2b9..62c2dc79341ae86e56659006d35d591b95ac1400 100644 (file)
@@ -328,6 +328,7 @@ xlockmore_screenhack (Display *dpy, Window window,
   do {
     hack_draw (&mi);
     XSync(dpy, False);
   do {
     hack_draw (&mi);
     XSync(dpy, False);
+    screenhack_handle_events (dpy);
     if (mi.pause)
       usleep(mi.pause);
     mi.pause = orig_pause;
     if (mi.pause)
       usleep(mi.pause);
     mi.pause = orig_pause;
index 7557dce35064c6a212aeb027323bd0bb6176a2bc..b180fc43341828a85e6225e2fcb788491b2b6ad1 100644 (file)
@@ -582,6 +582,9 @@ main_event(void)
          break;
            case ButtonRelease:
     EndRubberBand(canvas, &rubber_data, &event);
          break;
            case ButtonRelease:
     EndRubberBand(canvas, &rubber_data, &event);
+         break;
+            default: 
+    screenhack_handle_event (dpy, &event);
          break;
            }
        }
          break;
            }
        }
index 278189c50216dfbbce98eef8333215c983dc59c0..f4fa11640811d6cd6d1ee2bf24798de6fe01b4a2 100644 (file)
@@ -73,7 +73,8 @@ screenhack (dpy, window)
 
 
       skull (dpy, window, draw_gc, erase_gc, x, y, ww, hh);
 
 
       skull (dpy, window, draw_gc, erase_gc, x, y, ww, hh);
-      XSync (dpy, True);
+      XSync (dpy, False);
+      screenhack_handle_events (dpy);
       start_time = time ((time_t *) 0);
       if (mono_p)
        sleep (delay);
       start_time = time ((time_t *) 0);
       if (mono_p)
        sleep (delay);
index d6d2d1e0124c597813a397849c9337694777c6a6..b32920af5806c4db7f13fe543d99e966c4e9b686 100644 (file)
--- a/setup.com
+++ b/setup.com
@@ -61,6 +61,7 @@ $ rotor               :== $'mydir'rotor
 $ sierpinski   :== $'mydir'sierpinski
 $ slidescreen  :== $'mydir'slidescreen
 $ slip         :== $'mydir'slip
 $ sierpinski   :== $'mydir'sierpinski
 $ slidescreen  :== $'mydir'slidescreen
 $ slip         :== $'mydir'slip
+$ sonar                :== $'mydir'sonar
 $ sphere       :== $'mydir'sphere
 $ spiral       :== $'mydir'spiral
 $ starfish     :== $'mydir'starfish
 $ sphere       :== $'mydir'sphere
 $ spiral       :== $'mydir'spiral
 $ starfish     :== $'mydir'starfish
index 4b67aa21eb3c78a9237d145703e5ccb7ab3c7f0a..0ef8295f2f24a9ef9e115c00be70db9b2886a298 100644 (file)
@@ -1,2 +1,2 @@
 static const char screensaver_id[] =
 static const char screensaver_id[] =
-       "@(#)xscreensaver 3.04 (15-Nov-98), by Jamie Zawinski (jwz@jwz.org)";
+       "@(#)xscreensaver 3.06 (21-Nov-98), by Jamie Zawinski (jwz@jwz.org)";
index f74c39209a3e37a8e9d55f7851d58b129fb58ca5..babdbccb827e1876607a8d184e15322ede64c7ab 100644 (file)
@@ -1,7 +1,7 @@
 Begin3
 Title:          xscreensaver
 Begin3
 Title:          xscreensaver
-Version:        3.04
-Entered-date:   16NOV98
+Version:        3.06
+Entered-date:   22NOV98
 Description:    A modular screen saver and locker for the X Window System.
                 Highly customizable: allows the use of any program that
                 can draw on the root window as a display mode.
 Description:    A modular screen saver and locker for the X Window System.
                 Highly customizable: allows the use of any program that
                 can draw on the root window as a display mode.
@@ -10,16 +10,16 @@ Keywords:       screen saver, screen lock, lock, xlock, X11
 Author:         jwz@jwz.org (Jamie Zawinski)
 Maintained-by:  jwz@jwz.org (Jamie Zawinski)
 Primary-site:   http://www.jwz.org/xscreensaver/
 Author:         jwz@jwz.org (Jamie Zawinski)
 Maintained-by:  jwz@jwz.org (Jamie Zawinski)
 Primary-site:   http://www.jwz.org/xscreensaver/
-                964K xscreensaver-3.04.tar.gz
-                25K  xscreensaver.README
+                981K xscreensaver-3.06.tar.gz
+                26K  xscreensaver.README
                 1K   xscreensaver.lsm
 Alternate-site: sunsite.unc.edu /pub/Linux/X11/screensavers/
                 1K   xscreensaver.lsm
 Alternate-site: sunsite.unc.edu /pub/Linux/X11/screensavers/
-                964K xscreensaver-3.04.tar.gz
-                25K  xscreensaver.README
+                981K xscreensaver-3.06.tar.gz
+                26K  xscreensaver.README
                 1K   xscreensaver.lsm
 Alternate-site: ftp.x.org /contrib/applications/
                 1K   xscreensaver.lsm
 Alternate-site: ftp.x.org /contrib/applications/
-                964K xscreensaver-3.04.tar.gz
-                25K  xscreensaver.README
+                981K xscreensaver-3.06.tar.gz
+                26K  xscreensaver.README
                 1K   xscreensaver.lsm
 Platforms:      Linux, Irix, SunOS, Solaris, HPUX, AIX, FreeBSD, NetBSD,
                 BSDI, SCO, OSF1, Ultrix, VMS.
                 1K   xscreensaver.lsm
 Platforms:      Linux, Irix, SunOS, Solaris, HPUX, AIX, FreeBSD, NetBSD,
                 BSDI, SCO, OSF1, Ultrix, VMS.
index c31c1ad1e8facb7aee359c170d79e141ebec3a4c..89dd6d9191b9a9abbbc948df540397619fe052d3 100644 (file)
@@ -1,7 +1,7 @@
 Name: xscreensaver
 Summary: X screen saver and locker
 Name: xscreensaver
 Summary: X screen saver and locker
-Vendor: Jamie Zawinski
-Version: 3.04
+Vendor: Jamie Zawinski <jwz@jwz.org>
+Version: 3.06
 Release: 1
 URL: http://www.jwz.org/xscreensaver/
 Source: xscreensaver-%{version}.tar.gz
 Release: 1
 URL: http://www.jwz.org/xscreensaver/
 Source: xscreensaver-%{version}.tar.gz