http://slackware.bholcomb.com/slackware/slackware-11.0/source/xap/xscreensaver/xscree...
[xscreensaver] / hacks / kumppa.c
index fa908c06385355c6c0a5f0e44b5aea9cd8e7541b..a73fc94a0e19fc6f9ddd398dd8f86f60d9e460c0 100644 (file)
@@ -37,7 +37,6 @@ from the X Consortium.
 
 */
 
-
 #include <math.h>
 #include "screenhack.h"
 
@@ -45,438 +44,489 @@ from the X Consortium.
 # include "xdbe.h"
 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
 
-char *progclass="Kumppa";
-
-char *defaults [] ={
-       ".background:           black",
-       "*speed:                0.1",
-       "*delay:                10000",
-#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
-        /* leave this off by default, since it slows things down.  -- jwz. */
-        "*useDBE:              False",
-#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-       0
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+static const char *kumppa_defaults [] ={
+  ".background:                black",
+  "*speed:             0.1",
+  "*delay:             10000",
+  "*random:            True",
+  /* leave this off by default, since it slows things down.  -- jwz. */
+  "*useDBE:            False",
+  0
 };
 
-XrmOptionDescRec options [] = {
-       {"-delay",".delay",XrmoptionSepArg,0},
-       {"-speed",".speed",XrmoptionSepArg,0},
-       {"-random",".random",XrmoptionIsArg,0},
-#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
-       {"-dbuf",".dbuf",XrmoptionIsArg,0},
-#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-       {0,0,0,0}
+static XrmOptionDescRec kumppa_options [] = {
+  {"-delay",     ".delay",  XrmoptionSepArg, 0 },
+  {"-speed",     ".speed",  XrmoptionSepArg, 0 },
+  {"-random",    ".random", XrmoptionNoArg, "True"  },
+  {"-no-random", ".random", XrmoptionNoArg, "False" },
+  {"-db",       ".useDBE",  XrmoptionNoArg, "True"  },
+  {"-no-db",    ".useDBE",  XrmoptionNoArg, "False" },
+  {0,0,0,0}
 };
 
-const unsigned char colors[96]=
-       {0,0,255, 0,51,255, 0,102,255, 0,153,255, 0,204,255,
-       0,255,255,0,255,204, 0,255,153, 0,255,102, 0,255,51,
-       0,255,0, 51,255,0, 102,255,0, 153,255,0, 204,255,0,
-       255,255,0, 255,204,0, 255,153,0, 255,102,0, 255,51,0,
-       255,0,0, 255,0,51, 255,0,102, 255,0,153, 255,0,204,
-       255,0,255, 219,0,255, 182,0,255, 146,0,255, 109,0,255,
-       73,0,255, 37,0,255};
-const float cosinus[8][6]={{-0.07,0.12,-0.06,32,25,37},{0.08,-0.03,0.05,51,46,32},{0.12,0.07,-0.13,27,45,36},
-       {0.05,-0.04,-0.07,36,27,39},{-0.02,-0.07,0.1,21,43,42},{-0.11,0.06,0.02,51,25,34},{0.04,-0.15,0.02,42,32,25},
-       {-0.02,-0.04,-0.13,34,20,15}};
-
-static float acosinus[8][3]={{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
-static int coords[8];
-static int ocoords[8]={0,0,0,0,0,0,0,0};
-
-static Display *dpy;
-static Window win[2];
-static GC fgc[33];
-static GC cgc;
-static int sizx,sizy;
-static int midx,midy;
-static unsigned long delay;
-static Bool cosilines=True;
-#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
-static Bool usedouble=False;
-#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+static const unsigned char colors[96]=
+  {0,0,255, 0,51,255, 0,102,255, 0,153,255, 0,204,255,
+   0,255,255,0,255,204, 0,255,153, 0,255,102, 0,255,51,
+   0,255,0, 51,255,0, 102,255,0, 153,255,0, 204,255,0,
+   255,255,0, 255,204,0, 255,153,0, 255,102,0, 255,51,0,
+   255,0,0, 255,0,51, 255,0,102, 255,0,153, 255,0,204,
+   255,0,255, 219,0,255, 182,0,255, 146,0,255, 109,0,255,
+   73,0,255, 37,0,255};
+static const float cosinus[8][6]=
+ {{-0.07,0.12,-0.06,32,25,37},{0.08,-0.03,0.05,51,46,32},{0.12,0.07,-0.13,27,45,36},
+  {0.05,-0.04,-0.07,36,27,39},{-0.02,-0.07,0.1,21,43,42},{-0.11,0.06,0.02,51,25,34},{0.04,-0.15,0.02,42,32,25},
+  {-0.02,-0.04,-0.13,34,20,15}};
+
 
-static int *Xrotations;
-static int *Yrotations;
-static int *Xrottable;
-static int *Yrottable;
+struct state {
+  Display *dpy;
+  Window win[2];
 
-static int *rotateX;
-static int *rotateY;
+  float acosinus[8][3];
+  int coords[8];
+  int ocoords[8];
 
-static int rotsizeX,rotsizeY;
-static int stateX,stateY;
+  GC fgc[33];
+  GC cgc;
+  int sizx,sizy;
+  int midx,midy;
+  unsigned long delay;
+  Bool cosilines;
 
-static int rx,ry;
+  int *Xrotations;
+  int *Yrotations;
+  int *Xrottable;
+  int *Yrottable;
 
+  int *rotateX;
+  int *rotateY;
 
-int Satnum(int maxi)
+  int rotsizeX,rotsizeY;
+  int stateX,stateY;
+
+  int rx,ry;
+
+#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
+  XdbeSwapInfo xdswp;
+  Bool usedouble;
+#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+
+  int draw_count;
+};
+
+
+static int Satnum(int maxi)
 {
-return (int)(maxi*frand(1));
+  return (int)(maxi*frand(1));
 }
 
 
-void palaRotate(int x,int y)
+static void palaRotate(struct state *st, int x,int y)
 {
-int ax,ay,bx,by,cx,cy;
-
-ax=rotateX[x];
-ay=rotateY[y];
-bx=rotateX[x+1]+2;
-by=rotateY[y+1]+2;
-cx=rotateX[x]-(y-ry)+x-rx;
-cy=rotateY[y]+(x-rx)+y-ry;
-if (cx<0)
-       {
-       ax-=cx;
-       cx=0;
-       }
-if (cy<0)
-       {
-       ay-=cy;
-       cy=0;
-       }
-if (cx+bx-ax>sizx) bx=ax-cx+sizx;
-if (cy+by-ay>sizy) by=ay-cy+sizy;
-if (ax<bx && ay<by)
-       XCopyArea(dpy,win[0],win[1],cgc,ax,ay,bx-ax,by-ay,cx,cy);
+  int ax,ay,bx,by,cx,cy;
+
+  ax=st->rotateX[x];
+  ay=st->rotateY[y];
+  bx=st->rotateX[x+1]+2;
+  by=st->rotateY[y+1]+2;
+  cx=st->rotateX[x]-(y-st->ry)+x-st->rx;
+  cy=st->rotateY[y]+(x-st->rx)+y-st->ry;
+  if (cx<0)
+    {
+      ax-=cx;
+      cx=0;
+    }
+  if (cy<0)
+    {
+      ay-=cy;
+      cy=0;
+    }
+  if (cx+bx-ax>st->sizx) bx=ax-cx+st->sizx;
+  if (cy+by-ay>st->sizy) by=ay-cy+st->sizy;
+  if (ax<bx && ay<by)
+    XCopyArea(st->dpy,st->win[0],st->win[1],st->cgc,ax,ay,bx-ax,by-ay,cx,cy);
 }
 
 
-void rotate(void)
+static void rotate(struct state *st)
 {
-int x,y;
-int dx,dy;
-
-rx=Xrottable[stateX+1]-Xrottable[stateX];
-ry=Yrottable[stateY+1]-Yrottable[stateY];
-
-
-for (x=0;x<=rx;x++)
-       rotateX[x]=(x)?midx-1-Xrotations[Xrottable[stateX+1]-x]:0;
-for (x=0;x<=rx;x++)
-       rotateX[x+rx+1]=(x==rx)?sizx-1:midx+Xrotations[Xrottable[stateX]+x];
-for (y=0;y<=ry;y++)
-       rotateY[y]=(y)?midy-1-Yrotations[Yrottable[stateY+1]-y]:0;
-for (y=0;y<=ry;y++)
-       rotateY[y+ry+1]=(y==ry)?sizy-1:midy+Yrotations[Yrottable[stateY]+y];
-
-x=(rx>ry)?rx:ry;
-for (dy=0;dy<(x+1)<<1;dy++)
-       for (dx=0;dx<(x+1)<<1;dx++)
-               {
-               y=(rx>ry)?ry-rx:0;
-               if (dy+y>=0 && dy<(ry+1)<<1 && dx<(rx+1)<<1)
-                       if (dy+y+dx<=ry+rx && dy+y-dx<=ry-rx)
-                               {
-                               palaRotate((rx<<1)+1-dx,dy+y);
-                               palaRotate(dx,(ry<<1)+1-dy-y);
-                               }
-               y=(ry>rx)?rx-ry:0;
-               if (dy+y>=0 && dx<(ry+1)<<1 && dy<(rx+1)<<1)
-                       if (dy+y+dx<=ry+rx && dx-dy-y>=ry-rx)
-                               {
-                               palaRotate(dy+y,dx);
-                               palaRotate((rx<<1)+1-dy-y,(ry<<1)+1-dx);
-                               }
-               }
-stateX++;
-if (stateX==rotsizeX) stateX=0;
-stateY++;
-if (stateY==rotsizeY) stateY=0;
+  int x,y;
+  int dx,dy;
+
+  st->rx=st->Xrottable[st->stateX+1]-st->Xrottable[st->stateX];
+  st->ry=st->Yrottable[st->stateY+1]-st->Yrottable[st->stateY];
+
+
+  for (x=0;x<=st->rx;x++)
+    st->rotateX[x]=(x)?st->midx-1-st->Xrotations[st->Xrottable[st->stateX+1]-x]:0;
+  for (x=0;x<=st->rx;x++)
+    st->rotateX[x+st->rx+1]=(x==st->rx)?st->sizx-1:st->midx+st->Xrotations[st->Xrottable[st->stateX]+x];
+  for (y=0;y<=st->ry;y++)
+    st->rotateY[y]=(y)?st->midy-1-st->Yrotations[st->Yrottable[st->stateY+1]-y]:0;
+  for (y=0;y<=st->ry;y++)
+    st->rotateY[y+st->ry+1]=(y==st->ry)?st->sizy-1:st->midy+st->Yrotations[st->Yrottable[st->stateY]+y];
+
+  x=(st->rx>st->ry)?st->rx:st->ry;
+  for (dy=0;dy<(x+1)<<1;dy++)
+    for (dx=0;dx<(x+1)<<1;dx++)
+      {
+        y=(st->rx>st->ry)?st->ry-st->rx:0;
+        if (dy+y>=0 && dy<(st->ry+1)<<1 && dx<(st->rx+1)<<1)
+          if (dy+y+dx<=st->ry+st->rx && dy+y-dx<=st->ry-st->rx)
+            {
+              palaRotate(st, (st->rx<<1)+1-dx,dy+y);
+              palaRotate(st, dx,(st->ry<<1)+1-dy-y);
+            }
+        y=(st->ry>st->rx)?st->rx-st->ry:0;
+        if (dy+y>=0 && dx<(st->ry+1)<<1 && dy<(st->rx+1)<<1)
+          if (dy+y+dx<=st->ry+st->rx && dx-dy-y>=st->ry-st->rx)
+            {
+              palaRotate(st, dy+y,dx);
+              palaRotate(st, (st->rx<<1)+1-dy-y,(st->ry<<1)+1-dx);
+            }
+      }
+  st->stateX++;
+  if (st->stateX==st->rotsizeX) st->stateX=0;
+  st->stateY++;
+  if (st->stateY==st->rotsizeY) st->stateY=0;
 }
 
 
 
-Bool make_rots(double xspeed,double yspeed)
+static Bool make_rots(struct state *st, double xspeed,double yspeed)
 {
-int a,b,c,f,g,j,k=0,l;
-double m,om,ok;
-double d,ix,iy;
-int maxi;
-
-Bool *chks;
-
-rotsizeX=(int)(2/xspeed+1);
-ix=(double)(midx+1)/(double)(rotsizeX);
-rotsizeY=(int)(2/yspeed+1);
-iy=(double)(midy+1)/(double)(rotsizeY);
-
-Xrotations=malloc((midx+2)*sizeof(unsigned int));
-Xrottable=malloc((rotsizeX+1)*sizeof(unsigned int));
-Yrotations=malloc((midy+2)*sizeof(unsigned int));
-Yrottable=malloc((rotsizeY+1)*sizeof(unsigned int));
-chks=malloc(((midx>midy)?midx:midy)*sizeof(Bool));
-if (!Xrottable || !Yrottable || !Xrotations || !Yrotations || !chks) return False;
-
-
-maxi=0;
-c=0;
-d=0;
-g=0;
-for (a=0;a<midx;a++) chks[a]=True;
-for (a=0;a<rotsizeX;a++)
-       {
-       Xrottable[a]=c;
-       f=(int)(d+ix)-g;                                /*viivojen lkm.*/
-       g+=f;
-       if (g>midx)
-               {
-               f-=g-midx;
-               g=midx;
-               }
-       for (b=0;b<f;b++)
-               {
-               m=0;
-               for (j=0;j<midx;j++)                    /*testi*/
-                       {
-                       if (chks[j])
-                               {
-                               om=0;
-                               ok=1;
-                               l=0;
-                               while (j+l<midx && om+12*ok>m)
-                                       {
-                                       if (j-l>=0) if (chks[j-l]) om+=ok;
-                                               else; else if (chks[l-j]) om+=ok;
-                                       if (chks[j+l]) om+=ok;
-                                       ok/=1.5;
-                                       l++;
-                                       }
-                               if (om>=m)
-                                       {
-                                       k=j;
-                                       m=om;
-                                       }
-                               }
-                       }
-               chks[k]=False;
-               l=c;
-               while (l>=Xrottable[a])
-                       {
-                       if (l!=Xrottable[a]) Xrotations[l]=Xrotations[l-1];
-                       if (k>Xrotations[l] || l==Xrottable[a])
-                               {
-                               Xrotations[l]=k;
-                               c++;
-                               l=Xrottable[a];
-                               }
-                       l--;
-                       }
-               }
-       d+=ix;
-       if (maxi<c-Xrottable[a]) maxi=c-Xrottable[a];
-       }
-Xrottable[a]=c;
-rotateX=malloc((maxi+2)*sizeof(int)<<1);
-if (!rotateX) return False;
-
-maxi=0;
-c=0;
-d=0;
-g=0;
-for (a=0;a<midy;a++) chks[a]=True;
-for (a=0;a<rotsizeY;a++)
-       {
-       Yrottable[a]=c;
-       f=(int)(d+iy)-g;                                /*viivojen lkm.*/
-       g+=f;
-       if (g>midy)
-               {
-               f-=g-midy;
-               g=midy;
-               }
-       for (b=0;b<f;b++)
-               {
-               m=0;
-               for (j=0;j<midy;j++)                    /*testi*/
-                       {
-                       if (chks[j])
-                               {
-                               om=0;
-                               ok=1;
-                               l=0;
-                               while (j+l<midy && om+12*ok>m)
-                                       {
-                                       if (j-l>=0) if (chks[j-l]) om+=ok;
-                                               else; else if (chks[l-j]) om+=ok;
-                                       if (chks[j+l]) om+=ok;
-                                       ok/=1.5;
-                                       l++;
-                                       }
-                               if (om>=m)
-                                       {
-                                       k=j;
-                                       m=om;
-                                       }
-                               }
-                       }
-               chks[k]=False;
-               l=c;
-               while (l>=Yrottable[a])
-                       {
-                       if (l!=Yrottable[a]) Yrotations[l]=Yrotations[l-1];
-                       if (k>Yrotations[l] || l==Yrottable[a])
-                               {
-                               Yrotations[l]=k;
-                               c++;
-                               l=Yrottable[a];
-                               }
-                       l--;
-                       }
-
-               }
-       d+=iy;
-       if (maxi<c-Yrottable[a]) maxi=c-Yrottable[a];
-       }
-Yrottable[a]=c;
-rotateY=malloc((maxi+2)*sizeof(int)<<1);
-if (!rotateY) return False;
-
-free(chks);
-return (True);
+  int a,b,c,f,g,j,k=0,l;
+  double m,om,ok;
+  double d,ix,iy;
+  int maxi;
+
+  Bool *chks;
+
+  st->rotsizeX=(int)(2/xspeed+1);
+  ix=(double)(st->midx+1)/(double)(st->rotsizeX);
+  st->rotsizeY=(int)(2/yspeed+1);
+  iy=(double)(st->midy+1)/(double)(st->rotsizeY);
+
+  st->Xrotations=malloc((st->midx+2)*sizeof(unsigned int));
+  st->Xrottable=malloc((st->rotsizeX+1)*sizeof(unsigned int));
+  st->Yrotations=malloc((st->midy+2)*sizeof(unsigned int));
+  st->Yrottable=malloc((st->rotsizeY+1)*sizeof(unsigned int));
+  chks=malloc(((st->midx>st->midy)?st->midx:st->midy)*sizeof(Bool));
+  if (!st->Xrottable || !st->Yrottable || !st->Xrotations || !st->Yrotations || !chks) return False;
+
+
+  maxi=0;
+  c=0;
+  d=0;
+  g=0;
+  for (a=0;a<st->midx;a++) chks[a]=True;
+  for (a=0;a<st->rotsizeX;a++)
+    {
+      st->Xrottable[a]=c;
+      f=(int)(d+ix)-g;                         /*viivojen lkm.*/
+      g+=f;
+      if (g>st->midx)
+        {
+          f-=g-st->midx;
+          g=st->midx;
+        }
+      for (b=0;b<f;b++)
+        {
+          m=0;
+          for (j=0;j<st->midx;j++)                     /*testi*/
+            {
+              if (chks[j])
+                {
+                  om=0;
+                  ok=1;
+                  l=0;
+                  while (j+l<st->midx && om+12*ok>m)
+                    {
+                      if (j-l>=0) if (chks[j-l]) om+=ok;
+                      else; else if (chks[l-j]) om+=ok;
+                      if (chks[j+l]) om+=ok;
+                      ok/=1.5;
+                      l++;
+                    }
+                  if (om>=m)
+                    {
+                      k=j;
+                      m=om;
+                    }
+                }
+            }
+          chks[k]=False;
+          l=c;
+          while (l>=st->Xrottable[a])
+            {
+              if (l!=st->Xrottable[a]) st->Xrotations[l]=st->Xrotations[l-1];
+              if (k>st->Xrotations[l] || l==st->Xrottable[a])
+                {
+                  st->Xrotations[l]=k;
+                  c++;
+                  l=st->Xrottable[a];
+                }
+              l--;
+            }
+        }
+      d+=ix;
+      if (maxi<c-st->Xrottable[a]) maxi=c-st->Xrottable[a];
+    }
+  st->Xrottable[a]=c;
+  st->rotateX=malloc((maxi+2)*sizeof(int)<<1);
+  if (!st->rotateX) return False;
+
+  maxi=0;
+  c=0;
+  d=0;
+  g=0;
+  for (a=0;a<st->midy;a++) chks[a]=True;
+  for (a=0;a<st->rotsizeY;a++)
+    {
+      st->Yrottable[a]=c;
+      f=(int)(d+iy)-g;                         /*viivojen lkm.*/
+      g+=f;
+      if (g>st->midy)
+        {
+          f-=g-st->midy;
+          g=st->midy;
+        }
+      for (b=0;b<f;b++)
+        {
+          m=0;
+          for (j=0;j<st->midy;j++)                     /*testi*/
+            {
+              if (chks[j])
+                {
+                  om=0;
+                  ok=1;
+                  l=0;
+                  while (j+l<st->midy && om+12*ok>m)
+                    {
+                      if (j-l>=0) if (chks[j-l]) om+=ok;
+                      else; else if (chks[l-j]) om+=ok;
+                      if (chks[j+l]) om+=ok;
+                      ok/=1.5;
+                      l++;
+                    }
+                  if (om>=m)
+                    {
+                      k=j;
+                      m=om;
+                    }
+                }
+            }
+          chks[k]=False;
+          l=c;
+          while (l>=st->Yrottable[a])
+            {
+              if (l!=st->Yrottable[a]) st->Yrotations[l]=st->Yrotations[l-1];
+              if (k>st->Yrotations[l] || l==st->Yrottable[a])
+                {
+                  st->Yrotations[l]=k;
+                  c++;
+                  l=st->Yrottable[a];
+                }
+              l--;
+            }
+
+        }
+      d+=iy;
+      if (maxi<c-st->Yrottable[a]) maxi=c-st->Yrottable[a];
+    }
+  st->Yrottable[a]=c;
+  st->rotateY=malloc((maxi+2)*sizeof(int)<<1);
+  if (!st->rotateY) return False;
+
+  free(chks);
+  return (True);
 }
 
 
-Bool InitializeAll(void)
+static Bool InitializeAll(struct state *st)
 {
-XGCValues xgcv;
-XWindowAttributes xgwa;
-XSetWindowAttributes xswa;
-Colormap cmap;
-XColor color;
-int n,i;
-double rspeed;
-
-XGetWindowAttributes(dpy,win[0],&xgwa);
-cmap=xgwa.colormap;
-xswa.backing_store=Always;
-XChangeWindowAttributes(dpy,win[0],CWBackingStore,&xswa);
-xgcv.function=GXcopy;
-
-xgcv.foreground=get_pixel_resource ("background", "Background", dpy, cmap);
-fgc[32]=XCreateGC(dpy,win[0],GCForeground|GCFunction,&xgcv);
-
-n=0;
-if (mono_p)
-       {
-       fgc[0]=fgc[32];
-       xgcv.foreground=get_pixel_resource ("foreground", "Foreground", dpy, cmap);
-       fgc[1]=XCreateGC(dpy,win[0],GCForeground|GCFunction,&xgcv);
-       for (i=0;i<32;i+=2) fgc[i]=fgc[0];
-       for (i=1;i<32;i+=2) fgc[i]=fgc[1];
-       } else
-       for (i=0;i<32;i++)
-       {
-               color.red=colors[n++]<<8;
-               color.green=colors[n++]<<8;
-               color.blue=colors[n++]<<8;
-               color.flags=DoRed|DoGreen|DoBlue;
-               XAllocColor(dpy,cmap,&color);
-               xgcv.foreground=color.pixel;
-               fgc[i]=XCreateGC(dpy,win[0],GCForeground|GCFunction,&xgcv);
-       }
-cgc=XCreateGC(dpy,win[0],GCForeground|GCFunction,&xgcv);
-XSetGraphicsExposures(dpy,cgc,False);
-
-if (get_string_resource("random","String")!=NULL && get_string_resource("random","String")[0]!=0) cosilines=False;
+  XGCValues xgcv;
+  XWindowAttributes xgwa;
+/*  XSetWindowAttributes xswa;*/
+  Colormap cmap;
+  XColor color;
+  int n,i;
+  double rspeed;
+
+  st->cosilines = True;
+
+  XGetWindowAttributes(st->dpy,st->win[0],&xgwa);
+  cmap=xgwa.colormap;
+/*  xswa.backing_store=Always;
+  XChangeWindowAttributes(st->dpy,st->win[0],CWBackingStore,&xswa);*/
+  xgcv.function=GXcopy;
+
+  xgcv.foreground=get_pixel_resource (st->dpy, cmap, "background", "Background");
+  st->fgc[32]=XCreateGC(st->dpy,st->win[0],GCForeground|GCFunction,&xgcv);
+
+  n=0;
+  if (mono_p)
+    {
+      st->fgc[0]=st->fgc[32];
+      xgcv.foreground=get_pixel_resource (st->dpy, cmap, "foreground", "Foreground");
+      st->fgc[1]=XCreateGC(st->dpy,st->win[0],GCForeground|GCFunction,&xgcv);
+      for (i=0;i<32;i+=2) st->fgc[i]=st->fgc[0];
+      for (i=1;i<32;i+=2) st->fgc[i]=st->fgc[1];
+    } else
+    for (i=0;i<32;i++)
+      {
+        color.red=colors[n++]<<8;
+        color.green=colors[n++]<<8;
+        color.blue=colors[n++]<<8;
+        color.flags=DoRed|DoGreen|DoBlue;
+        XAllocColor(st->dpy,cmap,&color);
+        xgcv.foreground=color.pixel;
+        st->fgc[i]=XCreateGC(st->dpy,st->win[0],GCForeground|GCFunction,&xgcv);
+      }
+  st->cgc=XCreateGC(st->dpy,st->win[0],GCForeground|GCFunction,&xgcv);
+  XSetGraphicsExposures(st->dpy,st->cgc,False);
+
+  st->cosilines = get_boolean_resource(st->dpy, "random","Boolean");
 
 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
- usedouble = True;
- win[1] = xdbe_get_backbuffer (dpy, win[0], XdbeUndefined);
- if (!win[1])
-   {
-     usedouble = False;
-     win[1] = win[0];
-   }
+  if (get_boolean_resource (st->dpy, "useDBE", "Boolean"))
+    st->usedouble = True;
+  st->win[1] = xdbe_get_backbuffer (st->dpy, st->win[0], XdbeUndefined);
+  if (!st->win[1])
+    {
+      st->usedouble = False;
+      st->win[1] = st->win[0];
+    }
 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
 
-delay=get_integer_resource("delay","Integer");
-rspeed=get_float_resource("speed","Float");
-if (rspeed<0.0001 || rspeed>0.2)
-       {
-       fprintf(stderr,"Speed not in valid range! (0.0001 - 0.2), using 0.1 \n");
-       rspeed=0.1;
-       }
-
-sizx=xgwa.width;
-sizy=xgwa.height;
-midx=sizx>>1;
-midy=sizy>>1;
-stateX=0;
-stateY=0;
-
-if (!make_rots(rspeed,rspeed))
-       {
-       fprintf(stderr,"Not enough memory for tables!\n");
-       return False;
-       }
-return True;
+  st->delay=get_integer_resource(st->dpy, "delay","Integer");
+  rspeed=get_float_resource(st->dpy, "speed","Float");
+  if (rspeed<0.0001 || rspeed>0.2)
+    {
+      fprintf(stderr,"Speed not in valid range! (0.0001 - 0.2), using 0.1 \n");
+      rspeed=0.1;
+    }
+
+  st->sizx=xgwa.width;
+  st->sizy=xgwa.height;
+  st->midx=st->sizx>>1;
+  st->midy=st->sizy>>1;
+  st->stateX=0;
+  st->stateY=0;
+
+  if (!make_rots(st,rspeed,rspeed))
+    {
+      fprintf(stderr,"Not enough memory for tables!\n");
+      return False;
+    }
+  return True;
 }
 
-
-void screenhack(Display *d, Window w)
+static void *
+kumppa_init (Display *d, Window w)
 {
+  struct state *st = (struct state *) calloc (1, sizeof(*st));
+  st->dpy=d;
+  st->win[0]=w;
+  if (!InitializeAll(st)) abort();
+
 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
-XdbeSwapInfo xdswp;
+  if (st->usedouble)
+    {
+      st->xdswp.swap_action=XdbeUndefined;
+      st->xdswp.swap_window=st->win[0];
+    }
+  else
 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-int a,b,c=0,e;
-float f;
+    st->win[1]=st->win[0];
 
-dpy=d;
-win[0]=w;
-if (!InitializeAll()) return;
+  return st;
+}
 
+static unsigned long
+kumppa_draw (Display *d, Window w, void *closure)
+{
+  struct state *st = (struct state *) closure;
+  if (st->cosilines)
+    {
+      int a;
+      st->draw_count++;
+      for (a=0;a<8;a++)
+        {
+          float f=0;
+          int b;
+          for (b=0;b<3;b++)
+            {
+              st->acosinus[a][b]+=cosinus[a][b];
+              f+=cosinus[a][b+3]*sin((double)st->acosinus[a][b]);
+            }
+          st->coords[a]=(int)f;
+        }
+      for (a=0;a<4;a++)
+        {
+          XDrawLine(st->dpy,st->win[0],(mono_p)?st->fgc[1]:st->fgc[((a<<2)+st->draw_count)&31],st->midx+st->ocoords[a<<1],st->midy+st->ocoords[(a<<1)+1]
+                    ,st->midx+st->coords[a<<1],st->midy+st->coords[(a<<1)+1]);
+          st->ocoords[a<<1]=st->coords[a<<1];
+          st->ocoords[(a<<1)+1]=st->coords[(a<<1)+1];
+        }
+
+    } else {
+    int e;
+    for (e=0;e<8;e++)
+      {
+        int a=Satnum(50);
+        int b;
+        if (a>=32) a=32;
+        b=Satnum(32)-16+st->midx;
+        st->draw_count=Satnum(32)-16+st->midy;
+        XFillRectangle(st->dpy,st->win[0],st->fgc[a],b,st->draw_count,2,2);
+      }
+  }
+  XFillRectangle(st->dpy,st->win[0],st->fgc[32],st->midx-2,st->midy-2,4,4);
+  rotate(st);
 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
-if (usedouble)
-       {
-       xdswp.swap_action=XdbeUndefined;
-       xdswp.swap_window=win[0];
-       }
- else
-#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-   win[1]=win[0];
-
-while (0==0)
-       {
-       if (cosilines)
-               {
-               c++;
-               for (a=0;a<8;a++)
-                       {
-                       f=0;
-                       for (b=0;b<3;b++)
-                               {
-                               acosinus[a][b]+=cosinus[a][b];
-                               f+=cosinus[a][b+3]*sin((double)acosinus[a][b]);
-                               }
-                       coords[a]=(int)f;
-                       }
-               for (a=0;a<4;a++)
-                       {
-                       XDrawLine(dpy,win[0],(mono_p)?fgc[1]:fgc[((a<<2)+c)&31],midx+ocoords[a<<1],midy+ocoords[(a<<1)+1]
-                       ,midx+coords[a<<1],midy+coords[(a<<1)+1]);
-                       ocoords[a<<1]=coords[a<<1];
-                       ocoords[(a<<1)+1]=coords[(a<<1)+1];
-                       }
-
-               } else {
-               for (e=0;e<8;e++)
-                       {
-                       a=Satnum(50);
-                       if (a>=32) a=32;
-                       b=Satnum(32)-16+midx;
-                       c=Satnum(32)-16+midy;
-                       XFillRectangle(dpy,win[0],fgc[a],b,c,2,2);
-                       }
-               }
-       XFillRectangle(dpy,win[0],fgc[32],midx-2,midy-2,4,4);
-       rotate();
-#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
-       if (usedouble) XdbeSwapBuffers(dpy,&xdswp,1);
+  if (st->usedouble) XdbeSwapBuffers(st->dpy,&st->xdswp,1);
 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
-       XSync(dpy, False);
-        screenhack_handle_events (dpy);
-       if (delay) usleep (delay);
-       }
+
+  return st->delay;
 }
+
+
+static void
+kumppa_reshape (Display *dpy, Window window, void *closure, 
+                 unsigned int w, unsigned int h)
+{
+  struct state *st = (struct state *) closure;
+  st->sizx=w;
+  st->sizy=w;
+  st->midx=st->sizx>>1;
+  st->midy=st->sizy>>1;
+  st->stateX=0;
+  st->stateY=0;
+}
+
+static Bool
+kumppa_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+  return False;
+}
+
+static void
+kumppa_free (Display *dpy, Window window, void *closure)
+{
+  struct state *st = (struct state *) closure;
+  int i;
+  for (i = 0; i < countof(st->fgc); i++)
+    if (st->fgc[i]) XFreeGC (dpy, st->fgc[i]);
+  XFreeGC (dpy, st->cgc);
+  free (st->Xrotations);
+  free (st->Yrotations);
+  free (st->Xrottable);
+  free (st->Yrottable);
+  free (st);
+}
+
+XSCREENSAVER_MODULE ("Kumppa", kumppa)