http://ftp.x.org/contrib/applications/xscreensaver-2.24.tar.gz
[xscreensaver] / hacks / bubbles.c
index 2033130c38b0f34a946e227cef42323c23fd6809..735033d191b587f2886a6aed4efa469e53e8cfe7 100644 (file)
@@ -1,19 +1,17 @@
 /* bubbles.c - frying pan / soft drink in a glass simulation */
 
-/*$Id: bubbles.c,v 1.1 1996/09/08 01:35:40 jwz Exp $*/
+/*$Id: bubbles.c,v 1.15 1998/06/21 23:49:25 jwz Exp $*/
 
 /*
  *  Copyright (C) 1995-1996 James Macnicol
  *
- *   This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any later
- * version.
- *
- *   This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details. 
+ * 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.
  */
 
 /*
  * Internet E-mail : J.Macnicol@student.anu.edu.au
  */
 
+#include <math.h>
+#include "screenhack.h"
 #include "bubbles.h"
 
-#ifdef BUBBLES_IO
-#include <dirent.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#endif /* BUBBLES_IO */
-
 #include <limits.h>
-#include <math.h>
-#include <signal.h>
+
 #include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include "screenhack.h"
-#include "../utils/yarandom.h"
+
+#ifndef VMS
+# include <sys/wait.h>
+#else /* VMS */
+# if __DECC_VER >= 50200000
+#  include <sys/wait.h>
+# endif
+#endif /* VMS */
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include "yarandom.h"
 
 #ifdef HAVE_XPM
-#include <X11/xpm.h>
+# include <X11/xpm.h>
 #endif
 
 /* 
  * Public variables 
  */
 
-#ifndef NO_DEFAULT_BUBBLE
+extern void init_default_bubbles(void);
 extern int num_default_bubbles;
 extern char **default_bubbles[];
-#endif /* NO_DEFAULT_BUBBLE */
 
 char *progclass = "Bubbles";
 
 char *defaults [] = {
-  "*background: black",
-  "*foreground: white",
-  "*simple:     false",
-  "*broken:     false",
-  "*delay:      2000",
-#ifdef BUBBLES_IO
-  "*file:       (default)",
-  "*directory:  (default)",
-#endif /* BUBBLES_IO */
-  "*quiet:      false", 
-  "*nodelay:    false",
-  "*3D:     false",
-  "*geometry:   400x300",
+  ".background:                black",
+  ".foreground:                white",
+  "*simple:            false",
+  "*broken:            false",
+  "*delay:             800",
+  "*quiet:             false", 
+  "*nodelay:           false",
+  "*3D:                        false",
   0
 };
 
@@ -100,13 +95,9 @@ XrmOptionDescRec options [] = {
   { "-quiet",           ".quiet",       XrmoptionNoArg, "true" },
   { "-nodelay",         ".nodelay",     XrmoptionNoArg, "true" },
   { "-3D",          ".3D",      XrmoptionNoArg, "true" },
-#ifdef BUBBLES_IO
-  { "-file",            ".file",        XrmoptionSepArg, 0 },
-  { "-directory",       ".directory",   XrmoptionSepArg, 0 },
-#endif /* BUBBLES_IO */
-  { "-delay",           ".delay",       XrmoptionSepArg, 0 }
+  { "-delay",           ".delay",       XrmoptionSepArg, 0 },
+  { 0, 0, 0, 0 }
 };
-int options_size = (sizeof (options) / sizeof (options[0]));
 
 /* 
  * Private variables 
@@ -131,6 +122,7 @@ static unsigned int default_fg_pixel, default_bg_pixel;
 static Display *defdsp;
 static Window defwin;
 static Colormap defcmap;
+static Visual *defvisual;
 
 /* For simple mode only */
 static int bubble_min_radius;
@@ -141,10 +133,6 @@ static GC draw_gc, erase_gc;
 #ifdef HAVE_XPM
 static int num_bubble_pixmaps;
 static Bubble_Step **step_pixmaps;
-#ifdef BUBBLES_IO
-static char *pixmap_file;
-#endif /* BUBBLES_IO */
-static int use_default_bubble;
 #endif /* HAVE_XPM */
 
 /* Options stuff */
@@ -163,8 +151,7 @@ static int delay;
  */
 
 static long
-calc_bubble_area(r)
-     int r;
+calc_bubble_area(int r)
 /* Calculate the area of a bubble of radius r */
 {
 #ifdef DEBUG
@@ -178,8 +165,7 @@ calc_bubble_area(r)
 }
 
 static void *
-xmalloc(size)
-     size_t size;
+xmalloc(size_t size)
 /* Safe malloc */
 {
   void *ret;
@@ -193,8 +179,7 @@ xmalloc(size)
 
 #ifdef DEBUG
 static void 
-die_bad_bubble(bb)
-     Bubble *bb;
+die_bad_bubble(Bubble *bb)
 /* This is for use with GDB */
 {
   fprintf(stderr, "Bad bubble detected at 0x%x!\n", (int)bb);
@@ -203,8 +188,7 @@ die_bad_bubble(bb)
 #endif
 
 static int
-null_bubble(bb)
-     Bubble *bb;
+null_bubble(Bubble *bb)
 /* Returns true if the pointer passed is NULL.  If not then this checks to
 see if the bubble is valid (i.e. the (x,y) position is valid and the magic
 number is set correctly.  This only a sanity check for debugging and is
@@ -227,8 +211,8 @@ turned off if DEBUG isn't set. */
        (bb->radius < bubble_min_radius) || (bb->radius >
                                             bubble_max_radius)) {
       fprintf(stderr,
-             "radius = %d, x = %d, y = %d, magic = %d, \
-cell index = %d\n", bb->radius, bb->x, bb->y, bb->magic, bb->cell_index);
+             "radius = %d, x = %d, y = %d, magic = %d, cell index = %d\n",
+             bb->radius, bb->x, bb->y, bb->magic, bb->cell_index);
       die_bad_bubble(bb);  
     }
 #ifdef HAVE_XPM
@@ -238,8 +222,8 @@ cell index = %d\n", bb->radius, bb->x, bb->y, bb->magic, bb->cell_index);
        (bb->radius < step_pixmaps[0]->radius) || 
        (bb->radius > step_pixmaps[num_bubble_pixmaps-1]->radius)) {
       fprintf(stderr,
-             "radius = %d, x = %d, y = %d, magic = %d, \
-cell index = %d\n", bb->radius, bb->x, bb->y, bb->magic, bb->cell_index);
+             "radius = %d, x = %d, y = %d, magic = %d, cell index = %d\n",
+             bb->radius, bb->x, bb->y, bb->magic, bb->cell_index);
       die_bad_bubble(bb);  
     }
 #endif /* HAVE_XPM */
@@ -250,8 +234,7 @@ cell index = %d\n", bb->radius, bb->x, bb->y, bb->magic, bb->cell_index);
 
 #ifdef DEBUG
 static void 
-print_bubble_list(bb)
-     Bubble *bb;
+print_bubble_list(Bubble *bb)
 /* Print list of where all the bubbles are.  For debugging purposes only. */
 {
   if (! null_bubble(bb)) {
@@ -262,9 +245,7 @@ print_bubble_list(bb)
 #endif /* DEBUG */
 
 static void 
-add_bubble_to_list(list, bb)
-     Bubble **list;
-     Bubble *bb;
+add_bubble_to_list(Bubble **list, Bubble *bb)
 /* Take a pointer to a list of bubbles and stick bb at the head of the
  list. */
 {
@@ -288,7 +269,7 @@ add_bubble_to_list(list, bb)
 
 
 static void 
-init_mesh()
+init_mesh (void)
 /* Setup the mesh of bubbles */
 {
   int i;
@@ -299,9 +280,7 @@ init_mesh()
 }
 
 static int
-cell_to_mesh(x, y)
-     int x;
-     int y;
+cell_to_mesh(int x, int y)
 /* convert cell coordinates to mesh index */
 {
 #ifdef DEBUG
@@ -314,10 +293,7 @@ cell_to_mesh(x, y)
 }
 
 static void 
-mesh_to_cell(mi, cx, cy)
-     int mi;
-     int *cx;
-     int *cy;
+mesh_to_cell(int mi, int *cx, int *cy)
 /* convert mesh index into cell coordinates */
 {
   *cx = mi % mesh_width;
@@ -325,18 +301,14 @@ mesh_to_cell(mi, cx, cy)
 }
 
 static int
-pixel_to_mesh(x, y)
-     int x;
-     int y;
+pixel_to_mesh(int x, int y)
 /* convert screen coordinates into mesh index */
 {
   return cell_to_mesh((x / mesh_length), (y / mesh_length));
 }
 
 static int
-verify_mesh_index(x, y)
-     int x;
-     int y;
+verify_mesh_index(int x, int y)
 /* check to see if (x,y) is in the mesh */
 {
   if ((x < 0) || (y < 0) || (x >= mesh_width) || (y >= mesh_height))
@@ -346,8 +318,7 @@ verify_mesh_index(x, y)
 
 #ifdef DEBUG
 static void 
-print_adjacents(adj)
-    int *adj;
+print_adjacents(int *adj)
 /* Print a list of the cells calculated above.  For debugging only. */
 {
   int i;
@@ -360,8 +331,7 @@ print_adjacents(adj)
 #endif /* DEBUG */
 
 static void 
-add_to_mesh(bb)
-     Bubble *bb;
+add_to_mesh(Bubble *bb)
 /* Add the given bubble to the mesh by sticking it on the front of the
 list.  bb is already allocated so no need to malloc() anything, just
 adjust pointers. */
@@ -378,7 +348,7 @@ adjust pointers. */
 
 #ifdef DEBUG
 static void 
-print_mesh()
+print_mesh (void)
 /* Print the contents of the mesh */
 {
   int i;
@@ -392,7 +362,7 @@ print_mesh()
 }
 
 static void 
-valid_mesh()
+valid_mesh (void)
 /* Check to see if the mesh is Okay.  For debugging only. */
 {
   int i;
@@ -406,7 +376,7 @@ valid_mesh()
 }
 
 static int
-total_bubbles()
+total_bubbles (void)
 /* Count how many bubbles there are in total.  For debugging only. */
 {
   int rv = 0;
@@ -426,7 +396,7 @@ total_bubbles()
 #endif /* DEBUG */
 
 static void 
-calculate_adjacent_list()
+calculate_adjacent_list (void)
 /* Calculate the list of cells adjacent to a particular cell for use
    later. */
 {
@@ -450,7 +420,7 @@ calculate_adjacent_list()
 }
 
 static void
-adjust_areas()
+adjust_areas (void)
 /* Adjust areas of bubbles so we don't get overflow in weighted_mean() */
 {
   double maxvalue;
@@ -512,7 +482,7 @@ adjust_areas()
  */
 
 static Bubble *
-new_bubble()
+new_bubble (void)
 /* Add a new bubble at some random position on the screen of the smallest
 size. */
 {
@@ -536,16 +506,15 @@ size. */
   }
   rv->visible = 0;
   rv->magic = BUBBLE_MAGIC;
-  rv->x = ya_random() % screen_width;
-  rv->y = ya_random() % screen_height;
+  rv->x = random() % screen_width;
+  rv->y = random() % screen_height;
   rv->cell_index = pixel_to_mesh(rv->x, rv->y);
 
   return rv;
 }
 
 static void 
-show_bubble(bb)
-     Bubble *bb;
+show_bubble(Bubble *bb)
 /* paint the bubble on the screen */
 {
   if (null_bubble(bb)) {
@@ -578,8 +547,7 @@ show_bubble(bb)
 }
 
 static void 
-hide_bubble(bb)
-     Bubble *bb;
+hide_bubble(Bubble *bb)
 /* erase the bubble */
 {
   if (null_bubble(bb)) {
@@ -612,9 +580,7 @@ hide_bubble(bb)
 }
 
 static void 
-delete_bubble_in_mesh(bb, keep_bubble)
-     Bubble *bb;
-     int keep_bubble;
+delete_bubble_in_mesh(Bubble *bb, int keep_bubble)
 /* Delete an individual bubble, adjusting list of bubbles around it.
    If keep_bubble is true then the bubble isn't actually deleted.  We
    use this to allow bubbles to change mesh cells without reallocating,
@@ -642,16 +608,14 @@ delete_bubble_in_mesh(bb, keep_bubble)
 }
 
 static unsigned long 
-ulongsqrint(x)
-     int x;
+ulongsqrint(int x)
 /* Saves ugly inline code */
 {
   return ((unsigned long)x * (unsigned long)x);
 }
 
 static Bubble *
-get_closest_bubble(bb)
-     Bubble *bb;
+get_closest_bubble(Bubble *bb)
 /* Find the closest bubble touching the this bubble, NULL if none are
    touching. */
 {
@@ -704,15 +668,13 @@ get_closest_bubble(bb)
 
 #ifdef DEBUG
 static void
-ldr_barf()
+ldr_barf (void)
 {
 }
 #endif /* DEBUG */
 
 static long
-long_div_round(num, dem)
-     long num;
-     long dem;
+long_div_round(long num, long dem)
 {
   long divvie, moddo;
 
@@ -741,17 +703,14 @@ long_div_round(num, dem)
 }
 
 static int
-weighted_mean(n1, n2, w1, w2)
-     int n1;
-     int n2;
-     long w1;
-     long w2;
+weighted_mean(int n1, int n2, long w1, long w2)
 /* Mean of n1 and n2 respectively weighted by weights w1 and w2. */
 {
 #ifdef DEBUG
   if ((w1 <= 0) || (w2 <= 0)) {
-    fprintf(stderr, "Bad weights passed to weighted_mean() - \
-(%d, %d, %ld, %ld)!\n", n1, n2, w1, w2);
+    fprintf(stderr,
+           "Bad weights passed to weighted_mean() - (%d, %d, %ld, %ld)!\n",
+           n1, n2, w1, w2);
     exit(1);
   }
 #endif /* DEBUG */
@@ -760,9 +719,7 @@ weighted_mean(n1, n2, w1, w2)
 }
 
 static int
-bubble_eat(diner, food)
-     Bubble *diner;
-     Bubble *food;
+bubble_eat(Bubble *diner, Bubble *food)
 /* The diner eats the food.  Returns true (1) if the diner still exists */
 { 
   int i;
@@ -835,9 +792,7 @@ bubble_eat(diner, food)
 }
 
 static int
-merge_bubbles(b1, b2)
-     Bubble *b1;
-     Bubble *b2;
+merge_bubbles(Bubble *b1, Bubble *b2)
 /* These two bubbles merge into one.  If the first one wins out return
 1 else return 2.  If there is no winner (it explodes) then return 0 */
 {
@@ -882,7 +837,7 @@ merge_bubbles(b1, b2)
       break;
     }
   } else {
-    if ((ya_random() % 2) == 0) {
+    if ((random() % 2) == 0) {
       switch (bubble_eat(b1, b2)) {
       case 0:
        return 0;
@@ -911,8 +866,7 @@ merge_bubbles(b1, b2)
 }
 
 static void 
-insert_new_bubble(tmp)
-     Bubble *tmp;
+insert_new_bubble(Bubble *tmp)
 /* Calculates which bubbles are eaten when a new bubble tmp is
    inserted.  This is called recursively in case when a bubble grows
    it eats others.  Careful to pick out disappearing bubbles. */
@@ -958,8 +912,7 @@ insert_new_bubble(tmp)
 
 #ifdef DEBUG
 static int
-get_length_of_bubble_list(bb)
-     Bubble *bb;
+get_length_of_bubble_list(Bubble *bb)
 {
   Bubble *tmp = bb;
   int rv = 0;
@@ -980,61 +933,12 @@ get_length_of_bubble_list(bb)
 
 #ifdef HAVE_XPM
 
-static void 
-free_pixmaps()
-/* Free resources associated with XPM */
-{
-  int i;
-
-#ifdef DEBUG
-  if (simple) {
-    fprintf(stderr, "free_pixmaps() called in simple mode\n");
-    exit(1);
-  }
-  printf("free_pixmaps()\n");
-#endif /* DEBUG */
-
-  for(i = 0; i < (num_bubble_pixmaps - 1); i++) {
-    XFreePixmap(defdsp, step_pixmaps[i]->ball);
-    XFreePixmap(defdsp, step_pixmaps[i]->shape_mask);
-    XFreeGC(defdsp, step_pixmaps[i]->draw_gc);
-    XFreeGC(defdsp, step_pixmaps[i]->erase_gc);
-    XFreeColors(defdsp, defcmap, step_pixmaps[i]->xpmattrs.pixels, 
-               step_pixmaps[i]->xpmattrs.npixels, 0);
-    XpmFreeAttributes(&step_pixmaps[i]->xpmattrs);
-  }
-}
-
-static void 
-onintr(a)
-     int a;
-/* This gets called when SIGINT or SIGTERM is received */
-{
-  free_pixmaps();
-  exit(0);
-}
-
-#ifdef DEBUG
-static void
-onsegv(a)
-     int a;
-/* Called when SEGV detected.   Hmmmmm.... */
-{
-  fflush(stdout);
-  fprintf(stderr, "SEGV detected! : %d\n", a);
-  exit(1);
-}
-#endif /* DEBUG */
-
-
 /*
  * Pixmaps without file I/O (but do have XPM)
  */
 
 static void 
-pixmap_sort(head, numelems)
-     Bubble_Step **head;
-     int numelems;
+pixmap_sort(Bubble_Step **head, int numelems)
 /* Couldn't get qsort to work right with this so I wrote my own.  This puts
 the numelems length array with first element at head into order of radius.
 */
@@ -1061,16 +965,13 @@ the numelems length array with first element at head into order of radius.
 }
 
 static int
-extrapolate(i1, i2)
-     int i1;
-     int i2;
+extrapolate(int i1, int i2)
 {
   return (i2 + (i2 - i1));
 }
 
 static void 
-make_pixmap_array(list)
-     Bubble_Step *list;
+make_pixmap_array(Bubble_Step *list)
 /* From a linked list of bubbles construct the array step_pixmaps */
 {
   Bubble_Step *tmp = list;
@@ -1143,11 +1044,8 @@ make_pixmap_array(list)
 #endif /* DEBUG */
 }
 
-#ifndef NO_DEFAULT_BUBBLE
 static void
-make_pixmap_from_default(pixmap_data, bl)
-     char **pixmap_data;
-     Bubble_Step *bl;
+make_pixmap_from_default(char **pixmap_data, Bubble_Step *bl)
 /* Read pixmap data which has been compiled into the program and a pointer
  to which has been passed. 
 
@@ -1169,9 +1067,25 @@ changes made to either should be propagated onwards! */
     exit(1);
   }
 
+  bl->xpmattrs.valuemask = 0;
+
+#ifdef XpmCloseness
+  bl->xpmattrs.valuemask |= XpmCloseness;
   bl->xpmattrs.closeness = 40000;
-  bl->xpmattrs.valuemask = XpmColormap | XpmCloseness;
+#endif
+#ifdef XpmVisual
+  bl->xpmattrs.valuemask |= XpmVisual;
+  bl->xpmattrs.visual = defvisual;
+#endif
+#ifdef XpmDepth
+  bl->xpmattrs.valuemask |= XpmDepth;
+  bl->xpmattrs.depth = screen_depth;
+#endif
+#ifdef XpmColormap
+  bl->xpmattrs.valuemask |= XpmColormap;
   bl->xpmattrs.colormap = defcmap;
+#endif
+
 
   /* This is the only line which is different from make_pixmap_from_file() */
   result = XpmCreatePixmapFromData(defdsp, defwin, pixmap_data, &bl->ball, 
@@ -1209,7 +1123,7 @@ changes made to either should be propagated onwards! */
 }
 
 static void 
-default_to_pixmaps(void)
+default_to_pixmaps (void)
 /* Make pixmaps out of default ball data stored in bubbles_default.c */
 {
   int i;
@@ -1217,21 +1131,7 @@ default_to_pixmaps(void)
   Bubble_Step *newpix, *tmppix;
   char **pixpt;
 
-  /* Make sure pixmaps are freed when program is terminated */
-  /* This is when I hit ^C */
-  if (signal(SIGINT, SIG_IGN) != SIG_IGN)
-    signal(SIGINT, onintr);
-  /* xscreensaver sends SIGTERM */
-  if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
-    signal(SIGTERM, onintr);
-#ifdef DEBUG
-  if (signal(SIGSEGV, SIG_IGN) != SIG_IGN) {
-    printf("Setting signal handler for SIGSEGV\n");
-    signal(SIGSEGV, onsegv);
-  } else {
-    printf("Didn't set signal hanlder for SIGSEGV\n");
-  }
-#endif /* DEBUG */
+  init_default_bubbles();
 
   for (i = 0; i < num_default_bubbles; i++) {
     pixpt = default_bubbles[i];
@@ -1253,419 +1153,8 @@ default_to_pixmaps(void)
   make_pixmap_array(pixmap_list);
 }
 
-#endif /* NO_DEFAULT_BUBBLE */
-
 #endif /* HAVE_XPM */
 
-/* 
- * File I/O stuff
- */
-
-#ifdef BUBBLES_IO
-
-static DIR *
-my_opendir(name)
-     char *name;
-/* Like opendir() but checks for things so we don't have to do it multiple
-times in the code. */
-{
-  DIR *rv;
-
-  if (name == (char *)NULL) {
-    fprintf(stderr, "NULL directory name\n");
-    return (DIR *)NULL;
-  }
-  
-  if ((rv = opendir(name)) == NULL) {
-    perror(name);
-    return (DIR *)NULL;
-  }
-
-  return rv;
-}
-
-static int
-regular_file(name)
-     char *name;
-/* Check to see if we can use the named file.  This was broken under Linux
-1.3.45 but seems to be okay under 1.3.54.  The parameter "name" was being
-trashed if the file didn't exist.  Yeah, I know 1.3.x are development
-kernels....
-*/
-{
-  int fd;
-
-  if ((fd = open(name, O_RDONLY)) == -1) {
-    perror(name);
-    return 0;
-  } else {
-    close(fd);
-    return 1;
-  }
-}
-
-static char *
-get_random_name(dir)
-     char *dir;
-/* Pick an appropriate file at random out of the files in the directory dir */
-{
-  STRUCT_DIRENT *dp;
-  DIR *dfd;
-  int numentries = 0;
-  int entnum;
-  int x;
-  char buf[PATH_BUF_SIZE];
-  char *rv;
-
-  if ((dfd = my_opendir(dir)) == (DIR *)NULL)
-    return (char *)NULL;
-
-  while ((dp = readdir(dfd)) != NULL) {
-    if ((strcmp(DIRENT_NAME, ".") == 0) || (strcmp(DIRENT_NAME, "..") == 0))
-      continue;
-    if ((strlen(dir)+strlen(DIRENT_NAME)+2) > 1024) {
-      fprintf(stderr, "name %s/%s too long\n", dir, DIRENT_NAME);
-      continue;
-    }
-    if (sprintf(buf, "%s/%s", dir, DIRENT_NAME) > (PATH_BUF_SIZE-1)) {
-      fprintf(stderr, "path buffer overflowed in get_random_name()\n");
-      continue;
-    }
-    if (regular_file(buf))
-      ++numentries;
-  }
-  closedir(dfd);
-  if (numentries == 0) {
-    fprintf(stderr, "No suitable files found in %s\n", dir);
-    return (char *)NULL;
-  }
-  entnum = ya_random() % numentries;
-  x = 0;
-
-  if ((dfd = my_opendir(dir)) == (DIR *)NULL)
-    return (char *)NULL;
-  while ((dp = readdir(dfd)) != NULL) {
-    if ((strcmp(DIRENT_NAME, ".") == 0) || (strcmp(DIRENT_NAME, "..") == 0))
-      continue;
-    if ((strlen(dir)+strlen(DIRENT_NAME)+2) > 1024) {
-      /* We warned about this previously */
-      continue;
-    }
-    if (sprintf(buf, "%s/%s", dir, DIRENT_NAME) > (PATH_BUF_SIZE-1)) {
-      fprintf(stderr, "path buffer overflowed in get_random_name()\n");
-      continue;
-    }
-    if (regular_file(buf)) {
-      if (x == entnum) {
-       rv = (char *)xmalloc(1024 * sizeof(char));
-       strcpy(rv, buf);
-       closedir(dfd);
-       return rv;
-      }
-      ++x;
-    }
-  }
-  /* We've screwed up if we reach here - someone must have deleted all the
-     files while we were counting them... */
-  fprintf(stderr, "get_random_name(): Oops!\n");
-  exit(1);
-}
-
-static int
-read_line(fd, buf, bufsize)
-     int fd;
-     char **buf;
-     int bufsize;
-/* A line is read from fd until a '\n' is found or EOF is reached.  (*buf)
-is initially of length bufsize and is extended by bufsize chars if need
-be (for as many times as it takes). */
-{
-  char x;
-  int pos = 0;
-  int size = bufsize;
-  int rv;
-  char *newbuf;
-
-  while (1) {
-    rv = read(fd, &x, 1);
-    if (rv == -1) {
-      perror("read_line(): ");
-      return IO_ERROR;
-    } else if (rv == 0) {
-      (*buf)[pos] = '\0';
-      return EOF_REACHED;
-    } else if (x == '\n') {
-      (*buf)[pos] = '\0';
-      return LINE_READ;
-    } else {
-      (*buf)[pos++] = x;
-      if (pos == (size - 1)) {
-       /* We've come to the end of the space */
-       newbuf = (char *)xmalloc((size+bufsize) * sizeof(char));
-       strncpy(newbuf, *buf, (size - 1));
-       free(*buf);
-       *buf = newbuf;
-       size += bufsize;
-      }
-    }
-  }
-}
-
-static int
-create_temp_file(name)
-     char **name;
-/* Create a temporary file in /tmp and return a filedescriptor to it */
-{
-  int rv;
-  if (*name != (char *)NULL)
-    free(*name);
-
-  if ((*name = tempnam("/tmp", "abxdfes")) == (char *)NULL) {
-    fprintf(stderr, "Couldn't make new temporary file\n");
-    exit(1);
-  }
-/*   printf("Temp file created : %s\n", *name); */
-  if ((rv = creat(*name, 0644)) == -1) {
-    fprintf(stderr, "Couldn't open temporary file\n");
-    exit(1);
-  }
-  
-  return rv;
-}
-
-
-#ifdef BUBBLES_IO
-static void 
-make_pixmap_from_file(fname, bl)
-     char *fname;
-     Bubble_Step *bl;
-/* Read the pixmap in file fname into structure bl which must already
- be allocated. */
-{
-  int result;
-  XGCValues gcv;
-
-  if (bl == (Bubble_Step *)NULL) {
-    fprintf(stderr, "NULL pointer passed to make_pixmap()\n");
-    exit(1);
-  }
-
-  bl->xpmattrs.closeness = 40000;
-  bl->xpmattrs.valuemask = XpmColormap | XpmCloseness;
-  bl->xpmattrs.colormap = defcmap;
-
-  result = XpmReadFileToPixmap(defdsp, defwin, fname, &bl->ball, 
-                              &bl->shape_mask, &bl->xpmattrs);
-
-  switch(result) {
-  case XpmColorError:
-    fprintf(stderr, "xpm: color substitution performed\n");
-    /* fall through */
-  case XpmSuccess:
-    bl->radius = MAX(bl->xpmattrs.width, bl->xpmattrs.height) / 2;
-    bl->area = calc_bubble_area(bl->radius);
-    break;
-  case XpmColorFailed:
-    fprintf(stderr, "xpm: color allocation failed\n");
-    exit(1);
-  case XpmNoMemory:
-    fprintf(stderr, "xpm: out of memory\n");
-    exit(1);
-  default:
-    fprintf(stderr, "xpm: unknown error code %d\n", result);
-    exit(1);
-  }
-  
-  gcv.plane_mask = AllPlanes;
-  gcv.foreground = default_fg_pixel;
-  gcv.function = GXcopy;
-  bl->draw_gc = XCreateGC (defdsp, defwin, GCForeground, &gcv);
-  XSetClipMask(defdsp, bl->draw_gc, bl->shape_mask);
-  
-  gcv.foreground = default_bg_pixel;
-  gcv.function = GXcopy;
-  bl->erase_gc = XCreateGC (defdsp, defwin, GCForeground, &gcv);
-  XSetClipMask(defdsp, bl->erase_gc, bl->shape_mask);  
-}
-#endif /* BUBBLES_IO */
-
-static void 
-read_file_to_pixmaps(fname)
-     char *fname;
-/* Read the pixmaps contained in the file fname into memory.  THESE SHOULD
-BE UNCOMPRESSED AND READY TO GO! */
-{
-  int fd, tmpfd=0, rv;
-  int inxpm = 0;
-  int xpmseen = 0;
-  char *buf = (char *)NULL;
-  char *tmpname = (char *)NULL;
-  Bubble_Step *pixmap_list = (Bubble_Step *)NULL;
-  Bubble_Step *newpix, *tmppix;
-
-  /* We first create a linked list of pixmaps before allocating
-     memory for the array */
-
-  if ((fd = open(fname, O_RDONLY)) == -1) {
-    fprintf(stderr, "Couldn't open %s\n", fname);
-    exit(1);
-  }
-
-  /* Make sure pixmaps are freed when program is terminated */
-  /* This is when I hit ^C */
-  if (signal(SIGINT, SIG_IGN) != SIG_IGN)
-    signal(SIGINT, onintr);
-  /* xscreensaver sends SIGTERM */
-  if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
-    signal(SIGTERM, onintr);
-#ifdef DEBUG
-  if (signal(SIGSEGV, SIGN_IGN) != SIG_IGN)
-    signal(SIGSEGV, onsegv);
-#endif /* DEBUG */
-  
-  while (1) {
-    if (inxpm == 2)
-      break;
-
-    buf = (char *)malloc(READ_LINE_BUF_SIZE * sizeof(char));
-
-    switch ((rv = read_line(fd, &buf, READ_LINE_BUF_SIZE))) {
-    case IO_ERROR:
-      fprintf(stderr, "An I/O error occurred\n");
-      exit(1);
-    case EOF_REACHED:
-      if (inxpm) {
-       fprintf(stderr, "EOF occurred inside an XPM block\n");
-       exit(1);
-      } else
-       inxpm = 2;
-      break;
-    case LINE_READ:
-      if (inxpm) {
-       if (strncmp("};", buf, 2) == 0) {
-         inxpm = 0;
-         write(tmpfd, buf, strlen(buf));
-         write(tmpfd, "\n", 1);
-         close(tmpfd);
-         /* Now process the tmpfile */
-         newpix = (Bubble_Step *)xmalloc(sizeof(Bubble_Step));
-         make_pixmap_from_file(tmpname, newpix);
-         /* Now add to list */
-         if (pixmap_list == (Bubble_Step *)NULL) {
-           pixmap_list = newpix;
-         } else {
-           tmppix = pixmap_list;
-           while (tmppix->next != (Bubble_Step *)NULL)
-             tmppix = tmppix->next;
-           tmppix->next = newpix;
-         }
-         newpix->next = (Bubble_Step *)NULL;
-         unlink(tmpname);
-       } else {
-         write(tmpfd, buf, strlen(buf));
-         write(tmpfd, "\n", 1);
-       }
-      } else {
-       if (strncmp("/* XPM */", buf, 9) == 0) {
-         tmpfd = create_temp_file(&tmpname);
-/* This proves XPM's performance is kinda pathetic */
-#ifdef DEBUG
-         printf("New XPM detected : %s, fd=%d\n", tmpname, tmpfd); 
-#endif /* DEBUG */
-         inxpm = 1;
-         xpmseen = 1;
-       }
-       write(tmpfd, buf, strlen(buf));
-       write(tmpfd, "\n", 1);
-      }
-      break;
-    default:
-      fprintf(stderr, "read_line returned unknown code %d\n", rv);
-      exit(1);
-    }
-
-    free(buf);
-  }
-
-  close(fd);
-  if (buf != (char *)NULL)
-    free(buf);
-  if (tmpname != (char *)NULL)
-    free(tmpname);
-
-  if (! xpmseen) {
-    fprintf(stderr, "There was no XPM data in the file %s\n", fname);
-    exit(1);
-  }
-
-  /* Finally construct step_pixmaps[] */
-  make_pixmap_array(pixmap_list);
-}
-
-static void 
-shell_exec(command)
-     char *command;
-/* Forks a shell to execute "command" then waits for command to finish */
-{
-  int pid, status, wval;
-
-  switch(pid=fork()) {
-  case 0:
-    if (execlp(BOURNESH, BOURNESH, "-c", command, (char *)NULL) == -1) {
-      fprintf(stderr, "Couldn't exec shell %s\n", BOURNESH);
-      exit(1);
-    }
-    /* fall through if execlp() fails */
-  case -1:
-    /* Couldn't fork */
-    perror(progname);
-    exit(1);
-  default:
-    while ((wval = wait(&status)) != pid)
-      if (wval == -1) {
-       perror(progname);
-       exit(1);
-      }    
-  }
-}
-
-static void 
-uncompress_file(current, namebuf)
-     char *current;
-     char *namebuf;
-/* If the file current is compressed (i.e. its name ends in .gz or .Z,
-no check is made to see if it is actually a compressed file...) then a
-new temporary file is created for it and it is decompressed into there,
-returning the name of the file to namebuf, else current is returned in
-namebuf */
-{
-  int fd;
-  char *tname = (char *)NULL;
-  char argbuf[COMMAND_BUF_SIZE];
-
-  if (((strlen(current) >=4) && 
-       (strncmp(&current[strlen(current)-3], ".gz", 3) == 0)) || 
-      ((strlen(current) >=3) && 
-       (strncmp(&current[strlen(current)-2], ".Z", 2) == 0))) {
-    fd = create_temp_file(&tname);
-    /* close immediately but don't unlink so we should have a zero length
-       file in /tmp which we can append to */
-    close(fd);
-    if (sprintf(argbuf, "%s -dc %s > %s", GZIP, current, tname) > 
-       (COMMAND_BUF_SIZE-1)) {
-      fprintf(stderr, "command buffer overflowed in uncompress_file()\n");
-      exit(1);
-    }
-    shell_exec(argbuf);
-    strcpy(namebuf, tname);
-  } else {
-    strcpy(namebuf, current);
-  }
-  return;
-}
-
-#endif /* BUBBLES_IO */
 
 /* 
  * Main stuff 
@@ -1673,18 +1162,14 @@ namebuf */
 
 
 static void 
-get_resources(dpy)
-     Display *dpy;
+get_resources(Display *dpy, Window window)
 /* Get the appropriate X resources and warn about any inconsistencies. */
 {
   Bool nodelay;
-#ifdef BUBBLES_IO
-#ifdef HAVE_XPM
-  char *dirname;
-#else
-  char *foo, *bar;
-#endif /* HAVE_XPM */
-#endif /* BUBBLES_IO */
+  XWindowAttributes xgwa;
+  Colormap cmap;
+  XGetWindowAttributes (dpy, window, &xgwa);
+  cmap = xgwa.colormap;
 
   threed = get_boolean_resource("3D", "Boolean");
   quiet = get_boolean_resource("quiet", "Boolean");
@@ -1692,8 +1177,8 @@ get_resources(dpy)
   /* Forbid rendered bubbles on monochrome displays */
   if ((mono_p) && (! simple)) {
     if (! quiet)
-      fprintf(stderr, "Rendered bubbles not supported on monochrome \
-displays\n");
+      fprintf(stderr,
+             "Rendered bubbles not supported on monochrome displays\n");
     simple = True;
   }
   delay = get_integer_resource("delay", "Integer");
@@ -1704,11 +1189,9 @@ displays\n");
     delay = 0;
 
   default_fg_pixel = get_pixel_resource ("foreground", "Foreground", dpy,
-                                        DefaultColormap(dpy, 
-                                                        DefaultScreen(dpy)));
+                                        cmap);
   default_bg_pixel = get_pixel_resource ("background", "Background", dpy,
-                                        DefaultColormap(dpy, 
-                                                        DefaultScreen(dpy)));
+                                        cmap);
 
   if (simple) {
     /* This is easy */
@@ -1721,59 +1204,21 @@ displays\n");
     simple = 1;
 #else
     broken = get_boolean_resource("broken", "Boolean");
-#ifdef BUBBLES_IO
-    pixmap_file = get_string_resource("file", "File");
-    dirname = get_string_resource("directory", "Directory");    
-#ifdef NO_DEFAULT_BUBBLE
-    /* Must specify -file or -directory if no default bubble compiled in */
-    if (strcmp(pixmap_file, "(default)") != 0) {
-    } else if (strcmp(dirname, "(default)") != 0) {
-      if ((pixmap_file = get_random_name(dirname)) == (char *)NULL) {
-       /* Die if we can't open directory - make it consistent with -file
-          when it fails, rather than falling back to default. */
-       exit(1);
-      }
-    } else {
-      fprintf(stderr, "No default bubble compiled in - use -file or \
--directory\n");
-      exit(1);
-    }
-#else
-    if (strcmp(pixmap_file, "(default)") != 0) {
-    } else if (strcmp(dirname, "(default)") != 0) {
-      if ((pixmap_file = get_random_name(dirname)) == (char *)NULL) {
-       exit(1);
-      }
-    } else {
-      /* Use default bubble */
-      use_default_bubble = 1;
-    }
-#endif /* NO_DEFAULT_BUBBLE */
-#else 
-    use_default_bubble = 1;
-#endif /* BUBBLES_IO */
 #endif /* HAVE_XPM */
   }
 }
 
 static void
-init_bubbles (dpy, window)
-     Display *dpy;
-     Window window;
+init_bubbles (Display *dpy, Window window)
 {
   XGCValues gcv;
   XWindowAttributes xgwa;
   int i;
-#ifdef BUBBLES_IO
-  char uncompressed[1024];
-#endif /* BUBBLES_IO */
 
   defdsp = dpy;
   defwin = window;
 
-  ya_rand_init(0);
-
-  get_resources(dpy);
+  get_resources(dpy, window);
 
   XGetWindowAttributes (dpy, window, &xgwa);
 
@@ -1786,6 +1231,7 @@ init_bubbles (dpy, window)
   screen_height = xgwa.height;
   screen_depth = xgwa.depth;
   defcmap = xgwa.colormap;
+  defvisual = xgwa.visual;
 
   if (simple) {
     /* These are pretty much plucked out of the air */
@@ -1812,41 +1258,16 @@ init_bubbles (dpy, window)
     mesh_length = (2 * bubble_max_radius) + 3;
   } else {
 #ifndef HAVE_XPM
-    fprintf(stderr, "Bug: simple mode code not set but HAVE_XPM not \
-defined\n");
+    fprintf(stderr,
+           "Bug: simple mode code not set but HAVE_XPM not defined\n");
     exit(1);
 #else
     /* Make sure all #ifdef sort of things have been taken care of in
        get_resources(). */
-    if (use_default_bubble) {
-#ifdef NO_DEFAULT_BUBBLE
-      fprintf(stderr, "Bug: use_default_bubble and NO_DEFAULT_BUBBLE both \
-defined\n");
-      exit(1);
-#else
-      default_to_pixmaps();
-#endif /* NO_DEFAULT_BUBBLE */
+    default_to_pixmaps();
 
-      /* Set mesh length */
-      mesh_length = (2 * step_pixmaps[num_bubble_pixmaps-1]->radius) + 3;
-    } else {
-#ifdef BUBBLES_IO
-      if (! regular_file(pixmap_file)) {
-       /* perror() in regular_file printed error message */
-       exit(1);
-      }
-      uncompress_file(pixmap_file, uncompressed);
-      read_file_to_pixmaps(uncompressed);
-      if (strcmp(pixmap_file, uncompressed))
-       unlink(uncompressed);
-
-      mesh_length = (2 * step_pixmaps[num_bubble_pixmaps-1]->radius) + 3;
-#else
-      fprintf(stderr, "Bug: use_default_bubble is not defined yet I/O is not \
-compiled in\n");
-      exit(1);
-#endif /* BUBBLES_IO */
-    }
+    /* Set mesh length */
+    mesh_length = (2 * step_pixmaps[num_bubble_pixmaps-1]->radius) + 3;
 #endif /* HAVE_XPM */
 
     /* Am I missing something in here??? */
@@ -1873,9 +1294,7 @@ compiled in\n");
 }
 
 static void 
-bubbles (dpy, window)
-     Display *dpy;
-     Window window;
+bubbles (Display *dpy, Window window)
 {
   Bubble *tmp;
 
@@ -1888,9 +1307,7 @@ bubbles (dpy, window)
 
 
 void 
-screenhack (dpy, window)
-     Display *dpy;
-     Window window;
+screenhack (Display *dpy, Window window)
 {
   init_bubbles (dpy, window);
   while (1) {