From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / polyominoes.c
index 02645b72431c40c593b0f9f832ba84901f130a8c..c89fb31f4c42c5d8be190299204f4e288de26bda 100644 (file)
@@ -33,20 +33,19 @@ static const char sccsid[] = "@(#)polyominoes.c 5.01 2000/12/18 xlockmore";
  */
 
 #ifdef STANDALONE
-#define MODE_polyominoes
-#define PROGCLASS "Polyominoes"
-#define HACK_INIT init_polyominoes
-#define HACK_DRAW draw_polyominoes
-#define polyominoes_opts xlockmore_opts
-#define DEFAULTS "*delay: 10000 \n" \
-"*cycles: 2000 \n" \
-"*ncolors: 64 \n"
-#define SMOOTH_COLORS
-#include "xlockmore.h"         /* in xscreensaver distribution */
-#include "erase.h"
-#include <X11/Xutil.h>
+# define MODE_polyominoes
+#define DEFAULTS       "*delay: 10000 \n" \
+                                       "*cycles: 2000 \n" \
+                                       "*ncolors: 64 \n" \
+                                       "*fpsSolid: true \n" \
+
+# define release_polyominoes 0
+# define polyominoes_handle_event 0
+# define SMOOTH_COLORS
+# include "xlockmore.h"                /* in xscreensaver distribution */
+# include "erase.h"
 #else /* STANDALONE */
-#include "xlock.h"             /* in xlockmore distribution */
+# include "xlock.h"            /* in xlockmore distribution */
 #endif /* STANDALONE */
 
 #ifdef MODE_polyominoes
@@ -56,12 +55,15 @@ static const char sccsid[] = "@(#)polyominoes.c 5.01 2000/12/18 xlockmore";
 static Bool identical;
 static Bool plain;
 
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
 static XrmOptionDescRec opts[] =
 {
-  {(char *) "-identical", (char *) ".polyominoes.identical", XrmoptionNoArg, (caddr_t) "on"},
-  {(char *) "+identical", (char *) ".polyominoes.identical", XrmoptionNoArg, (caddr_t) "off"},
-  {(char *) "-plain", (char *) ".polyominoes.plain", XrmoptionNoArg, (caddr_t) "on"},
-  {(char *) "+plain", (char *) ".polyominoes.plain", XrmoptionNoArg, (caddr_t) "off"}
+  {"-identical", ".polyominoes.identical", XrmoptionNoArg, "on"},
+  {"+identical", ".polyominoes.identical", XrmoptionNoArg, "off"},
+  {"-plain", ".polyominoes.plain", XrmoptionNoArg, "on"},
+  {"+plain", ".polyominoes.plain", XrmoptionNoArg, "off"}
 };
 static argtype vars[] =
 {
@@ -70,17 +72,17 @@ static argtype vars[] =
 };
 static OptionStruct desc[] =
 {
-  {(char *) "-/+identical", (char *) "turn on/off puzzles where the polyomino pieces are identical"},
-  {(char *) "-/+plain", (char *) "turn on/off plain pieces"}
+  {"-/+identical", "turn on/off puzzles where the polyomino pieces are identical"},
+  {"-/+plain", "turn on/off plain pieces"}
 };
 
-ModeSpecOpt polyominoes_opts =
+ENTRYPOINT ModeSpecOpt polyominoes_opts =
 {sizeof opts / sizeof opts[0], opts,
  sizeof vars / sizeof vars[0], vars, desc};
 
 #ifdef USE_MODULES
 ModStruct   polyominoes_description = {
-  "polyominoes", "init_polyominoes", "draw_polyominoes", "release_polyominoes",
+  "polyominoes", "init_polyominoes", "draw_polyominoes", (char *) NULL,
   "refresh_polyominoes", "init_polyominoes", (char *) NULL, &polyominoes_opts,
   6000, 1, 8192, 1, 64, 1.0, "",
   "Shows attempts to place polyominoes into a rectangle", 0, NULL
@@ -175,6 +177,10 @@ typedef struct _polyominoesstruct{
   int *reason_to_not_attach;
 
   int counter;
+
+#ifdef STANDALONE
+  eraser_state *eraser;
+#endif
 } polyominoesstruct;
 
 #define ARRAY(x,y)         (sp->array[(x)*sp->height+(y)])
@@ -276,7 +282,8 @@ static int bitmaps_needed[] =
  -1
 };
 
-static int bitmap_needed(int n) {
+static int bitmap_needed(int n)
+{
   int i;
 
   for (i=0;bitmaps_needed[i]!=-1;i++)
@@ -289,7 +296,8 @@ static int bitmap_needed(int n) {
 
 /* Some debugging routines.
 
-static void print_board(polyominoesstruct *sp) {
+static void print_board(polyominoesstruct *sp)
+{
   int x,y;
   for (y=0;y<sp->height;y++) {
     for (x=0;x<sp->width;x++)
@@ -302,14 +310,16 @@ static void print_board(polyominoesstruct *sp) {
   fprintf(stderr,"\n");
 }
 
-static void print_points(point_type *point, int len) {
+static void print_points(point_type *point, int len)
+{
   int i;
 
   for (i=0;i<len;i++)
     fprintf(stderr,"(%d %d) ",point[i].x,point[i].y);
 }
 
-static void print_polyomino(polyomino_type poly) {
+static void print_polyomino(polyomino_type poly)
+{
   int i;
 
   print_points(poly.point,poly.len);
@@ -323,7 +333,8 @@ static void print_polyomino(polyomino_type poly) {
 static polyominoesstruct *polyominoeses = (polyominoesstruct *) NULL;
 
 static
-void random_permutation(int n, int a[]) {
+void random_permutation(int n, int a[])
+{
   int i,j,k,r;
 
   for (i=0;i<n;i++) a[i] = -1;
@@ -375,7 +386,8 @@ static void transform(point_type in, point_type offset, int transform_no,
   }
 }
 
-static int first_poly_no(polyominoesstruct *sp) {
+static int first_poly_no(polyominoesstruct *sp)
+{
   int poly_no;
 
   poly_no = 0;
@@ -384,7 +396,8 @@ static int first_poly_no(polyominoesstruct *sp) {
   return poly_no;
 }
 
-static void next_poly_no(polyominoesstruct *sp, int *poly_no) {
+static void next_poly_no(polyominoesstruct *sp, int *poly_no)
+{
 
   if (sp->identical) {
     *poly_no = sp->nr_polyominoes;
@@ -400,7 +413,8 @@ static void next_poly_no(polyominoesstruct *sp, int *poly_no) {
    a number of blanks that is not a multiple of n.
 */
 
-static void count_adjacent_blanks(polyominoesstruct *sp, int *count, int x, int y, int blank_mark) {
+static void count_adjacent_blanks(polyominoesstruct *sp, int *count, int x, int y, int blank_mark)
+{
 
   if (ARRAY(x,y) == -1) {
     (*count)++;
@@ -412,7 +426,8 @@ static void count_adjacent_blanks(polyominoesstruct *sp, int *count, int x, int
   }
 }
 
-static int check_all_regions_multiple_of(polyominoesstruct *sp, int n) {
+static int check_all_regions_multiple_of(polyominoesstruct *sp, int n)
+{
   int x,y,count,good = 1;
 
   for (x=0;x<sp->width && good;x++) for (y=0;y<sp->height && good;y++) {
@@ -428,7 +443,8 @@ static int check_all_regions_multiple_of(polyominoesstruct *sp, int n) {
   return good;
 }
 
-static int check_all_regions_positive_combination_of(polyominoesstruct *sp, int m, int n) {
+static int check_all_regions_positive_combination_of(polyominoesstruct *sp, int m, int n)
+{
   int x,y,count,good = 1;
 
   for (x=0;x<sp->width && good;x++) for (y=0;y<sp->height && good;y++) {
@@ -446,7 +462,8 @@ static int check_all_regions_positive_combination_of(polyominoesstruct *sp, int
   return good;
 }
 
-static int find_smallest_blank_component(polyominoesstruct *sp) {
+static int find_smallest_blank_component(polyominoesstruct *sp)
+{
   int x,y,size,smallest_size,blank_mark,smallest_mark;
 
   smallest_mark = blank_mark = -10;
@@ -473,7 +490,8 @@ static int find_smallest_blank_component(polyominoesstruct *sp) {
    array has a valid number of white or black remaining blanks left.
 */
 
-static int whites_ok(polyominoesstruct *sp) {
+static int whites_ok(polyominoesstruct *sp)
+{
   int x,y,poly_no,whites=0,blacks=0,max_white=0,min_white=0;
 
   for (x=0;x<sp->width;x++) for (y=0;y<sp->height;y++) {
@@ -493,9 +511,10 @@ static int whites_ok(polyominoesstruct *sp) {
 */
 
 static int
-score_point(polyominoesstruct *sp, int x, int y, int min_score_so_far) {
+score_point(polyominoesstruct *sp, int x, int y, int min_score_so_far)
+{
   int poly_no, point_no, transform_index, i, attachable;
-  point_type attach_point, target_point;
+  point_type attach_point = { 0, 0 }, target_point = { 0, 0 };
   int score = 0;
 
   if (x>=1 && x<sp->width-1 && y>=1 && y<sp->height-1 &&
@@ -534,7 +553,8 @@ score_point(polyominoesstruct *sp, int x, int y, int min_score_so_far) {
   return score;
 }
 
-static void find_blank(polyominoesstruct *sp, point_type *point) {
+static void find_blank(polyominoesstruct *sp, point_type *point)
+{
   int score, worst_score;
   int x, y;
   int blank_mark;
@@ -564,9 +584,10 @@ static void find_blank(polyominoesstruct *sp, point_type *point) {
 /* Detaches the most recently attached polyomino. */
 
 static
-void detach(polyominoesstruct *sp, int *poly_no, int *point_no, int *transform_index, point_type *attach_point, int rot180) {
+void detach(polyominoesstruct *sp, int *poly_no, int *point_no, int *transform_index, point_type *attach_point, int rot180)
+{
   int i;
-  point_type target_point;
+  point_type target_point = { 0, 0 };
 
   if (sp->nr_attached == 0) return;
   sp->nr_attached--;
@@ -594,7 +615,7 @@ void detach(polyominoesstruct *sp, int *poly_no, int *point_no, int *transform_i
 static
 int attach(polyominoesstruct *sp, int poly_no, int point_no, int transform_index, point_type attach_point, int rot180,
            int *reason_to_not_attach) {
-  point_type target_point;
+  point_type target_point = { 0, 0 };
   int i;
   int attachable = 1, worst_reason_not_to_attach = 1000000000;
 
@@ -659,7 +680,8 @@ int attach(polyominoesstruct *sp, int poly_no, int point_no, int transform_index
 }
 
 static
-int next_attach_try(polyominoesstruct *sp, int *poly_no, int *point_no, int *transform_index) {
+int next_attach_try(polyominoesstruct *sp, int *poly_no, int *point_no, int *transform_index)
+{
 
   (*transform_index)++;
   if (*transform_index>=sp->polyomino[*poly_no].transform_len) {
@@ -683,7 +705,8 @@ Display routines.
 *******************************************************/
 
 static void
-draw_without_bitmaps(ModeInfo * mi, polyominoesstruct *sp) {
+draw_without_bitmaps(ModeInfo * mi, polyominoesstruct *sp)
+{
   Display *display = MI_DISPLAY(mi);
   Window  window = MI_WINDOW(mi);
   GC gc = MI_GC(mi);
@@ -765,14 +788,14 @@ draw_without_bitmaps(ModeInfo * mi, polyominoesstruct *sp) {
   }
   XDrawSegments(display, window, gc, sp->lines, nr_lines);
   XSetLineAttributes(display,gc,1,LineSolid,CapRound,JoinRound);
-  XFlush(display);
 }
 
-static void create_bitmaps(ModeInfo * mi, polyominoesstruct *sp) {
+static void create_bitmaps(ModeInfo * mi, polyominoesstruct *sp)
+{
   int x,y,n;
   char *data;
 
-  for (n=0;n<256;n++) {
+  for (n=0;n<countof(sp->bitmaps);n++) {
 
 /* Avoid duplication of identical bitmaps. */
     if (IS_LEFT_UP(n) && (IS_LEFT(n) || IS_UP(n)))
@@ -958,7 +981,8 @@ static void create_bitmaps(ModeInfo * mi, polyominoesstruct *sp) {
   sp->use_bitmaps = 1;
 }
 
-static void draw_with_bitmaps(ModeInfo * mi, polyominoesstruct *sp) {
+static void draw_with_bitmaps(ModeInfo * mi, polyominoesstruct *sp)
+{
   Display *display = MI_DISPLAY(mi);
   Window  window = MI_WINDOW(mi);
   GC gc = MI_GC(mi);
@@ -999,7 +1023,6 @@ static void draw_with_bitmaps(ModeInfo * mi, polyominoesstruct *sp) {
     XDrawRectangle(display,window,gc,
                    sp->x_margin-t-1,sp->y_margin-t-1,
                    sp->box*sp->width+1+2*t, sp->box*sp->height+1+2*t);
-  XFlush(display);
 }
 
 
@@ -1007,10 +1030,11 @@ static void draw_with_bitmaps(ModeInfo * mi, polyominoesstruct *sp) {
 Routines to initialise and close down polyominoes.
 ***************************************************/
 
-static void free_bitmaps(polyominoesstruct *sp) {
+static void free_bitmaps(polyominoesstruct *sp)
+{
   int n;
   
-  for (n=0;n<256;n++)
+  for (n=0;n<countof(sp->bitmaps);n++)
 /* Don't bother to free duplicates */
     if (IS_LEFT_UP(n) && (IS_LEFT(n) || IS_UP(n)))
       sp->bitmaps[n] = None;
@@ -1029,7 +1053,9 @@ static void free_bitmaps(polyominoesstruct *sp) {
 
 #define deallocate(p,t) if ((p)!=NULL) {free(p); p=(t*)NULL;}
 
-static void free_polyominoes(polyominoesstruct *sp) {
+static void free_polyominoes(ModeInfo * mi)
+{
+  polyominoesstruct *sp = &polyominoeses[MI_SCREEN(mi)];
   int n;
 
   for (n=0;n<sp->nr_polyominoes;n++) {
@@ -1048,7 +1074,7 @@ static void free_polyominoes(polyominoesstruct *sp) {
 }
 
 #define set_allocate(p,type,size) p = (type *) malloc(size);           \
-                             if ((p)==NULL) {free_polyominoes(sp);return 0;}
+                             if ((p)==NULL) {free_polyominoes(mi);return 0;}
 
 #define copy_polyomino(dst,src,new_rand)                               \
   (dst).len=(src).len;                                                 \
@@ -1072,42 +1098,50 @@ Puzzle specific initialization routines.
 ***************************************************/
 
 static
-int check_pentomino_puzzle(polyominoesstruct *sp) {
+int check_pentomino_puzzle(polyominoesstruct *sp)
+{
   return check_all_regions_multiple_of(sp, 5) && whites_ok(sp);
 }
 
 static
-int check_hexomino_puzzle(polyominoesstruct *sp) {
+int check_hexomino_puzzle(polyominoesstruct *sp)
+{
   return check_all_regions_multiple_of(sp, 6) && whites_ok(sp);
 }
 
 static
-int check_tetr_pentomino_puzzle(polyominoesstruct *sp) {
+int check_tetr_pentomino_puzzle(polyominoesstruct *sp)
+{
   return check_all_regions_positive_combination_of(sp, 5, 4) && whites_ok(sp);
 }
 
 static
-int check_pent_hexomino_puzzle(polyominoesstruct *sp) {
+int check_pent_hexomino_puzzle(polyominoesstruct *sp)
+{
   return check_all_regions_positive_combination_of(sp, 6, 5) && whites_ok(sp);
 }
 
 static
-int check_heptomino_puzzle(polyominoesstruct *sp) {
+int check_heptomino_puzzle(polyominoesstruct *sp)
+{
   return check_all_regions_multiple_of(sp, 7) && whites_ok(sp);
 }
 
 static
-int check_octomino_puzzle(polyominoesstruct *sp) {
+int check_octomino_puzzle(polyominoesstruct *sp)
+{
   return check_all_regions_multiple_of(sp, 8) && whites_ok(sp);
 }
 
 static
-int check_dekomino_puzzle(polyominoesstruct *sp) {
+int check_dekomino_puzzle(polyominoesstruct *sp)
+{
   return check_all_regions_multiple_of(sp, 10) && whites_ok(sp);
 }
 
 static
-int check_elevenomino_puzzle(polyominoesstruct *sp) {
+int check_elevenomino_puzzle(polyominoesstruct *sp)
+{
   return check_all_regions_multiple_of(sp, 11) && whites_ok(sp);
 }
 
@@ -1466,11 +1500,12 @@ xx
 
 static struct pentomino_struct one_sided_pentomino[60];
 
-void make_one_sided_pentomino(void) {
+static void make_one_sided_pentomino(void)
+{
   int i,j,t,u;
 
   j=0;
-  for (i=0;i<18;i++) {
+  for (i=0;i<countof(pentomino);i++) {
     one_sided_pentomino[j] = pentomino[i];
     for (t=0;t<8;t++)
       if (one_sided_pentomino[j].transform_list[t]>=4) {
@@ -1487,11 +1522,12 @@ void make_one_sided_pentomino(void) {
 
 static struct hexomino_struct one_sided_hexomino[60];
 
-void make_one_sided_hexomino(void) {
+static void make_one_sided_hexomino(void)
+{
   int i,j,t,u;
 
   j=0;
-  for (i=0;i<35;i++) {
+  for (i=0;i<countof(hexomino);i++) {
     one_sided_hexomino[j] = hexomino[i];
     for (t=0;t<8;t++)
       if (one_sided_hexomino[j].transform_list[t]>=4) {
@@ -1512,7 +1548,8 @@ into a rectangle whose size is 20x3, 15x4, 12x5 or 10x6.
 */
 
 static
-int set_pentomino_puzzle(polyominoesstruct *sp) {
+int set_pentomino_puzzle(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_poly[12], perm_point[5], perm_transform[8], i, p;
 
   switch (NRAND(4)) {
@@ -1535,9 +1572,10 @@ int set_pentomino_puzzle(polyominoesstruct *sp) {
   }
 
   sp->nr_polyominoes = 12;
-  set_allocate(sp->polyomino,polyomino_type,12*sizeof(polyomino_type));
-  random_permutation(12,perm_poly);
-  for (p=0;p<12;p++) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  random_permutation(sp->nr_polyominoes,perm_poly);
+  for (p=0;p<sp->nr_polyominoes;p++) {
     copy_polyomino(sp->polyomino[p],pentomino[perm_poly[p]],1);
   }
 
@@ -1557,7 +1595,8 @@ into a rectangle.
 */
 
 static
-int set_one_sided_pentomino_puzzle(polyominoesstruct *sp) {
+int set_one_sided_pentomino_puzzle(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_poly[18], perm_point[5], perm_transform[8], i, p;
 
   make_one_sided_pentomino();
@@ -1582,9 +1621,10 @@ int set_one_sided_pentomino_puzzle(polyominoesstruct *sp) {
   }
 
   sp->nr_polyominoes = 18;
-  set_allocate(sp->polyomino,polyomino_type,18*sizeof(polyomino_type));
-  random_permutation(18,perm_poly);
-  for (p=0;p<18;p++) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  random_permutation(sp->nr_polyominoes,perm_poly);
+  for (p=0;p<sp->nr_polyominoes;p++) {
     copy_polyomino(sp->polyomino[p],one_sided_pentomino[perm_poly[p]],1);
   }
 
@@ -1599,7 +1639,8 @@ into a rectangle.
 */
 
 static
-int set_one_sided_hexomino_puzzle(polyominoesstruct *sp) {
+int set_one_sided_hexomino_puzzle(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_poly[60], perm_point[6], perm_transform[8], i, p;
 
   make_one_sided_hexomino();
@@ -1640,9 +1681,10 @@ int set_one_sided_hexomino_puzzle(polyominoesstruct *sp) {
   }
 
   sp->nr_polyominoes = 60;
-  set_allocate(sp->polyomino,polyomino_type,60*sizeof(polyomino_type));
-  random_permutation(60,perm_poly);
-  for (p=0;p<60;p++) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  random_permutation(sp->nr_polyominoes,perm_poly);
+  for (p=0;p<sp->nr_polyominoes;p++) {
     copy_polyomino(sp->polyomino[p],one_sided_hexomino[perm_poly[p]],1);
   }
 
@@ -1657,7 +1699,8 @@ pentominoes into a rectangle.
 */
 
 static
-int set_tetr_pentomino_puzzle(polyominoesstruct *sp) {
+int set_tetr_pentomino_puzzle(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_poly[17], perm_point[5], perm_transform[8], i, p;
 
   switch (NRAND(3)) {
@@ -1676,12 +1719,13 @@ int set_tetr_pentomino_puzzle(polyominoesstruct *sp) {
   }
 
   sp->nr_polyominoes = 17;
-  set_allocate(sp->polyomino,polyomino_type,17*sizeof(polyomino_type));
-  random_permutation(17,perm_poly);
-  for (p=0;p<5;p++) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  random_permutation(sp->nr_polyominoes,perm_poly);
+  for (p=0;p<countof(tetromino);p++) {
     copy_polyomino(sp->polyomino[perm_poly[p]],tetromino[p],1);
   }
-  for (p=0;p<12;p++) {
+  for (p=0;p<countof(pentomino);p++) {
     copy_polyomino(sp->polyomino[perm_poly[p+5]],pentomino[p],1);
   }
 
@@ -1695,7 +1739,8 @@ hexominoes into a rectangle whose size is 18x15.
 */
 
 static
-int set_pent_hexomino_puzzle(polyominoesstruct *sp) {
+int set_pent_hexomino_puzzle(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_poly[47], perm_point[6], perm_transform[8], i, p;
 
   switch (NRAND(5)) {
@@ -1724,10 +1769,10 @@ int set_pent_hexomino_puzzle(polyominoesstruct *sp) {
   sp->nr_polyominoes = 47;
   set_allocate(sp->polyomino,polyomino_type,47*sizeof(polyomino_type));
   random_permutation(47,perm_poly);
-  for (p=0;p<12;p++) {
+  for (p=0;p<countof(pentomino);p++) {
     copy_polyomino(sp->polyomino[perm_poly[p]],pentomino[p],1);
   }
-  for (p=0;p<35;p++) {
+  for (p=0;p<countof(hexomino);p++) {
     copy_polyomino(sp->polyomino[perm_poly[p+12]],hexomino[p],1);
   }
 
@@ -1756,15 +1801,17 @@ static struct {int len; point_type point[5];
    8, {0, 1, 2, 3, 4, 5, 6, 7}, 3};
 
 static
-int set_pentomino_puzzle1(polyominoesstruct *sp) {
+int set_pentomino_puzzle1(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_point[5], perm_transform[8], i, p;
 
   sp->width = 10;
   sp->height =5;
 
   sp->nr_polyominoes = 10;
-  set_allocate(sp->polyomino,polyomino_type,10*sizeof(polyomino_type));
-  for (p=0;p<10;p++) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  for (p=0;p<sp->nr_polyominoes;p++) {
     copy_polyomino(sp->polyomino[p],pentomino1,1);
   }
 
@@ -1786,15 +1833,17 @@ static struct {int len; point_type point[6];
    8, {0, 1, 2, 3, 4, 5, 6, 7}, 4};
 
 static
-int set_hexomino_puzzle1(polyominoesstruct *sp) {
+int set_hexomino_puzzle1(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_point[6], perm_transform[8], i, p;
 
   sp->width = 24;
   sp->height =23;
 
   sp->nr_polyominoes = 92;
-  set_allocate(sp->polyomino,polyomino_type,92*sizeof(polyomino_type));
-  for (p=0;p<92;p++) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  for (p=0;p<sp->nr_polyominoes;p++) {
     copy_polyomino(sp->polyomino[p],hexomino1,1);
   }
 
@@ -1818,7 +1867,8 @@ static struct {int len; point_type point[7];
    8, {0, 1, 2, 3, 4, 5, 6, 7}, 4};
 
 static
-int set_heptomino_puzzle1(polyominoesstruct *sp) {
+int set_heptomino_puzzle1(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_point[7], perm_transform[8], i, p;
 
   sp->rot180 = 1;
@@ -1827,8 +1877,9 @@ int set_heptomino_puzzle1(polyominoesstruct *sp) {
   sp->height =21;
 
   sp->nr_polyominoes = 78;
-  set_allocate(sp->polyomino,polyomino_type,78*sizeof(polyomino_type));
-  for (p=0;p<78;p+=2) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  for (p=0;p<sp->nr_polyominoes;p+=2) {
     copy_polyomino(sp->polyomino[p],heptomino1,1);
     copy_polyomino(sp->polyomino[p+1],heptomino1,0);
   }
@@ -1850,15 +1901,17 @@ by Solomon W. Golomb   Princeton University Press 1994
 
 */
 static
-int set_heptomino_puzzle2(polyominoesstruct *sp) {
+int set_heptomino_puzzle2(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_point[7], perm_transform[8], i, p;
 
   sp->width = 28;
   sp->height =19;
 
   sp->nr_polyominoes = 76;
-  set_allocate(sp->polyomino,polyomino_type,76*sizeof(polyomino_type));
-  for (p=0;p<76;p++) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  for (p=0;p<sp->nr_polyominoes;p++) {
     copy_polyomino(sp->polyomino[p],heptomino1,1);
   }
 
@@ -1883,7 +1936,8 @@ static struct {int len; point_type point[11];
    8, {0, 1, 2, 3, 4, 5, 6, 7}, 6};
 
 static
-int set_elevenomino_puzzle1(polyominoesstruct *sp) {
+int set_elevenomino_puzzle1(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_point[11], perm_transform[8], i, p;
 
   sp->rot180 = 1;
@@ -1892,8 +1946,9 @@ int set_elevenomino_puzzle1(polyominoesstruct *sp) {
   sp->height =22;
 
   sp->nr_polyominoes = 50;
-  set_allocate(sp->polyomino,polyomino_type,50*sizeof(polyomino_type));
-  for (p=0;p<50;p+=2) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  for (p=0;p<sp->nr_polyominoes;p+=2) {
     copy_polyomino(sp->polyomino[p],elevenomino1,1);
     copy_polyomino(sp->polyomino[p+1],elevenomino1,0);
   }
@@ -1921,15 +1976,17 @@ static struct {int len; point_type point[10];
    8, {0, 1, 2, 3, 4, 5, 6, 7}, 5};
 
 static
-int set_dekomino_puzzle1(polyominoesstruct *sp) {
+int set_dekomino_puzzle1(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_point[10], perm_transform[8], i, p;
 
   sp->width = 32;
   sp->height =30;
 
   sp->nr_polyominoes = 96;
-  set_allocate(sp->polyomino,polyomino_type,96*sizeof(polyomino_type));
-  for (p=0;p<96;p++) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  for (p=0;p<sp->nr_polyominoes;p++) {
     copy_polyomino(sp->polyomino[p],dekomino1,1);
   }
 
@@ -1954,15 +2011,17 @@ static struct {int len; point_type point[10];
    8, {0, 1, 2, 3, 4, 5, 6, 7}, 5};
 
 static
-int set_octomino_puzzle1(polyominoesstruct *sp) {
+int set_octomino_puzzle1(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_point[8], perm_transform[8], i, p;
 
   sp->width = 96;
   sp->height =26;
 
   sp->nr_polyominoes = 312;
-  set_allocate(sp->polyomino,polyomino_type,312*sizeof(polyomino_type));
-  for (p=0;p<312;p++) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  for (p=0;p<sp->nr_polyominoes;p++) {
     copy_polyomino(sp->polyomino[p],octomino1,1);
   }
 
@@ -1979,15 +2038,17 @@ int set_octomino_puzzle1(polyominoesstruct *sp) {
 */
 
 static
-int set_pentomino_puzzle2(polyominoesstruct *sp) {
+int set_pentomino_puzzle2(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_point[5], perm_transform[8], i, p;
 
   sp->width = 15;
   sp->height =15;
 
   sp->nr_polyominoes = 45;
-  set_allocate(sp->polyomino,polyomino_type,45*sizeof(polyomino_type));
-  for (p=0;p<45;p++) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  for (p=0;p<sp->nr_polyominoes;p++) {
     copy_polyomino(sp->polyomino[p],pentomino1,1);
   }
 
@@ -2005,15 +2066,17 @@ int set_pentomino_puzzle2(polyominoesstruct *sp) {
 */
 
 static
-int set_elevenomino_puzzle2(polyominoesstruct *sp) {
+int set_elevenomino_puzzle2(ModeInfo * mi, polyominoesstruct *sp)
+{
   int perm_point[11], perm_transform[8], i, p;
 
   sp->width = 47;
   sp->height =33;
 
   sp->nr_polyominoes = 141;
-  set_allocate(sp->polyomino,polyomino_type,141*sizeof(polyomino_type));
-  for (p=0;p<141;p++) {
+  set_allocate(sp->polyomino,polyomino_type,
+               sp->nr_polyominoes*sizeof(polyomino_type));
+  for (p=0;p<sp->nr_polyominoes;p++) {
     copy_polyomino(sp->polyomino[p],elevenomino1,1);
   }
 
@@ -2026,25 +2089,19 @@ int set_elevenomino_puzzle2(polyominoesstruct *sp) {
 The main functions.
 **************************************************/
 
-#define allocate(p,type,size) p = (type *) malloc(size); if ((p)==NULL) {free_polyominoes(sp); return;}
+#define allocate(p,type,size) p = (type *) malloc(size); if ((p)==NULL) {free_polyominoes(mi); return;}
 
-void
-init_polyominoes(ModeInfo * mi) {
+ENTRYPOINT void
+init_polyominoes (ModeInfo * mi)
+{
   polyominoesstruct *sp;
   int i,x,y, start;
   int box1, box2;
   int *perm;
 
-  if (polyominoeses == NULL) {
-    if ((polyominoeses
-         = (polyominoesstruct *) calloc(MI_NUM_SCREENS(mi),sizeof (polyominoesstruct))) 
-        == NULL)
-      return;
-  }
+  MI_INIT (mi, polyominoeses, free_polyominoes);
   sp = &polyominoeses[MI_SCREEN(mi)];
 
-  free_polyominoes(sp);
-
   sp->rot180 = 0;
   sp->counter = 0;
 
@@ -2058,62 +2115,62 @@ init_polyominoes(ModeInfo * mi) {
   if (sp->identical) {
     switch (NRAND(9)) {
       case 0:
-        if (!set_pentomino_puzzle1(sp))
+        if (!set_pentomino_puzzle1(mi, sp))
           return;
         break;
       case 1:
-        if (!set_hexomino_puzzle1(sp))
+        if (!set_hexomino_puzzle1(mi, sp))
           return;
         break;
       case 2:
-        if (!set_heptomino_puzzle1(sp))
+        if (!set_heptomino_puzzle1(mi, sp))
           return;
         break;
       case 3:
-        if (!set_heptomino_puzzle2(sp))
+        if (!set_heptomino_puzzle2(mi, sp))
           return;
         break;
       case 4:
-        if (!set_elevenomino_puzzle1(sp))
+        if (!set_elevenomino_puzzle1(mi, sp))
           return;
         break;
       case 5:
-        if (!set_dekomino_puzzle1(sp))
+        if (!set_dekomino_puzzle1(mi, sp))
           return;
         break;
       case 6:
-        if (!set_octomino_puzzle1(sp))
+        if (!set_octomino_puzzle1(mi, sp))
           return;
         break;
       case 7:
-        if (!set_pentomino_puzzle2(sp))
+        if (!set_pentomino_puzzle2(mi, sp))
           return;
         break;
       case 8:
-        if (!set_elevenomino_puzzle2(sp))
+        if (!set_elevenomino_puzzle2(mi, sp))
           return;
         break;
     }
   } else {
     switch (NRAND(5)) {
       case 0:
-        if (!set_pentomino_puzzle(sp))
+        if (!set_pentomino_puzzle(mi, sp))
           return;
         break;
       case 1:
-        if (!set_one_sided_pentomino_puzzle(sp))
+        if (!set_one_sided_pentomino_puzzle(mi, sp))
           return;
         break;
       case 2:
-        if (!set_one_sided_hexomino_puzzle(sp))
+        if (!set_one_sided_hexomino_puzzle(mi, sp))
           return;
         break;
       case 3:
-        if (!set_pent_hexomino_puzzle(sp))
+        if (!set_pent_hexomino_puzzle(mi, sp))
           return;
         break;
       case 4:
-        if (!set_tetr_pentomino_puzzle(sp))
+        if (!set_tetr_pentomino_puzzle(mi, sp))
           return;
         break;
     }
@@ -2185,13 +2242,16 @@ init_polyominoes(ModeInfo * mi) {
 
   sp->wait = 0;
 
+#ifndef STANDALONE
   /* Clear the background. */
   MI_CLEARWINDOW(mi);
+#endif
   
 }
 
-void
-draw_polyominoes(ModeInfo * mi) {
+ENTRYPOINT void
+draw_polyominoes (ModeInfo * mi)
+{
   polyominoesstruct *sp;
   int poly_no,point_no,transform_index,done,another_attachment_try;
   point_type attach_point;
@@ -2201,21 +2261,32 @@ draw_polyominoes(ModeInfo * mi) {
     return;
   sp = &polyominoeses[MI_SCREEN(mi)];
 
+#ifdef STANDALONE
+    if (sp->eraser) {
+      sp->eraser = erase_window (MI_DISPLAY(mi), MI_WINDOW(mi), sp->eraser);
+      if (!sp->eraser)
+        init_polyominoes(mi);
+      return;
+    }
+#endif
+
   if (MI_CYCLES(mi) != 0) {
     if (++sp->counter > MI_CYCLES(mi)) {
 #ifdef STANDALONE
-      erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi));
-#endif /* STANDALONE */
+      sp->eraser = erase_window (MI_DISPLAY(mi), MI_WINDOW(mi), sp->eraser);
+#else /* !STANDALONE */
       init_polyominoes(mi);
+#endif /* !STANDALONE */
       return;
     }
   }
 
   if (sp->box == 0) {
 #ifdef STANDALONE
-    erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi));
-#endif /* STANDALONE */
+    sp->eraser = erase_window (MI_DISPLAY(mi), MI_WINDOW(mi), sp->eraser);
+#else /* !STANDALONE */
     init_polyominoes(mi);
+#endif
     return;
   }
 
@@ -2294,21 +2365,19 @@ draw_polyominoes(ModeInfo * mi) {
     sp->wait = 0;
 }
 
-void
-release_polyominoes(ModeInfo * mi) {
-  int screen;
-  
-  if (polyominoeses != NULL) {
-    for (screen=0;screen<MI_NUM_SCREENS(mi); screen++)
-      free_polyominoes(&polyominoeses[screen]);
-    (void) free((void *) polyominoeses);
-    polyominoeses = (polyominoesstruct *) NULL;
-  }
+ENTRYPOINT void
+reshape_polyominoes(ModeInfo * mi, int width, int height)
+{
+  XClearWindow (MI_DISPLAY (mi), MI_WINDOW(mi));
+  init_polyominoes (mi);
 }
 
-void
-refresh_polyominoes(ModeInfo * mi) {
+ENTRYPOINT void
+refresh_polyominoes (ModeInfo * mi)
+{
   MI_CLEARWINDOW(mi);
 }
 
+XSCREENSAVER_MODULE ("Polyominoes", polyominoes)
+
 #endif /* MODE_polyominoes */