ftp://ftp.demon.nl/disk1/redhat-contrib/libc5/SRPMS/xscreensaver-2.14-1.src.rpm
[xscreensaver] / hacks / decayscreen.c
index 604500491fb891d002cdb23e4884ad95497ce4ab..ed7a084007b1a19ea7ff847a710cad04c12cc7c3 100644 (file)
@@ -28,6 +28,8 @@
  *
  *  Vivek Khera <khera@cs.duke.edu>
  *  5-AUG-1993
+ *
+ *  Hacked by jwz, 28-Nov-97 (sped up and added new motion directions)
  */
 
 #include "screenhack.h"
 static int sizex, sizey;
 static int delay;
 static GC gc;
+static int mode;
+
+#define SHUFFLE 0
+#define UP 1
+#define LEFT 2
+#define RIGHT 3
+#define DOWN 4
+#define UPLEFT 5
+#define DOWNLEFT 6
+#define UPRIGHT 7
+#define DOWNRIGHT 8
+#define IN 9
+#define OUT 10
+
 
 static void
 init_decay (Display *dpy, Window window)
 {
   XGCValues gcv;
   XWindowAttributes xgwa;
+  long gcflags;
+
+  char *s = get_string_resource("mode", "Mode");
+  if      (s && !strcmp(s, "shuffle")) mode = SHUFFLE;
+  else if (s && !strcmp(s, "up")) mode = UP;
+  else if (s && !strcmp(s, "left")) mode = LEFT;
+  else if (s && !strcmp(s, "right")) mode = RIGHT;
+  else if (s && !strcmp(s, "down")) mode = DOWN;
+  else if (s && !strcmp(s, "upleft")) mode = UPLEFT;
+  else if (s && !strcmp(s, "downleft")) mode = DOWNLEFT;
+  else if (s && !strcmp(s, "upright")) mode = UPRIGHT;
+  else if (s && !strcmp(s, "downright")) mode = DOWNRIGHT;
+  else if (s && !strcmp(s, "in")) mode = IN;
+  else if (s && !strcmp(s, "out")) mode = OUT;
+  else {
+    if (s && *s && !!strcmp(s, "random"))
+      fprintf(stderr, "%s: unknown mode %s\n", progname, s);
+    mode = random() % (OUT+1);
+  }
 
   delay = get_integer_resource ("delay", "Integer");
 
@@ -48,8 +83,10 @@ init_decay (Display *dpy, Window window)
 
   gcv.function = GXcopy;
   gcv.subwindow_mode = IncludeInferiors;
-  gc = XCreateGC (dpy, window, GCForeground |GCFunction | GCSubwindowMode,
-                 &gcv);
+  gcflags = GCForeground |GCFunction;
+  if (use_subwindow_mode_p(xgwa.screen, window)) /* see grabscreen.c */
+    gcflags |= GCSubwindowMode;
+  gc = XCreateGC (dpy, window, gcflags, &gcv);
 
   XGetWindowAttributes (dpy, window, &xgwa);
   sizex = xgwa.width;
@@ -65,47 +102,77 @@ init_decay (Display *dpy, Window window)
 static void
 decay1 (Display *dpy, Window window)
 {
-    int left, top, width, height;
+    int left, top, width, height, toleft, totop;
+
+#define L 101
+#define R 102
+#define U 103
+#define D 104
+    static int no_bias[]        = { L,L,L,L, R,R,R,R, U,U,U,U, D,D,D,D };
+    static int up_bias[]        = { L,L,L,L, R,R,R,R, U,U,U,U, U,U,D,D };
+    static int down_bias[]      = { L,L,L,L, R,R,R,R, U,U,D,D, D,D,D,D };
+    static int left_bias[]      = { L,L,L,L, L,L,R,R, U,U,U,U, D,D,D,D };
+    static int right_bias[]     = { L,L,R,R, R,R,R,R, U,U,U,U, D,D,D,D };
+
+    static int upleft_bias[]    = { L,L,L,L, L,R,R,R, U,U,U,U, U,D,D,D };
+    static int downleft_bias[]  = { L,L,L,L, L,R,R,R, U,U,U,D, D,D,D,D };
+    static int upright_bias[]   = { L,L,L,R, R,R,R,R, U,U,U,U, U,D,D,D };
+    static int downright_bias[] = { L,L,L,R, R,R,R,R, U,U,U,D, D,D,D,D };
+    static int *bias;
+
+    switch (mode) {
+      case SHUFFLE:    bias = no_bias; break;
+      case UP:         bias = up_bias; break;
+      case LEFT:       bias = left_bias; break;
+      case RIGHT:      bias = right_bias; break;
+      case DOWN:       bias = down_bias; break;
+      case UPLEFT:     bias = upleft_bias; break;
+      case DOWNLEFT:   bias = downleft_bias; break;
+      case UPRIGHT:    bias = upright_bias; break;
+      case DOWNRIGHT:  bias = downright_bias; break;
+      case IN:         bias = no_bias; break;
+      case OUT:                bias = no_bias; break;
+      default: abort();
+    }
 
 #define nrnd(x) (random() % (x))
 
-    switch (random() % 8) {
-      case 0:                  /* move a block left */
-      case 1:
-       left = nrnd(sizex - 1) + 1;
-       top = nrnd(sizey);
-       width = nrnd(sizex - left);
-       height = nrnd(sizey - top);
-       XCopyArea (dpy, window, window, gc, left, top, width, height,
-                  left - 1, top);
-       break;
-      case 2:                  /* move a block right */
-      case 3:
-       left = nrnd(sizex - 1);
-       top = nrnd(sizey);
-       width = nrnd(sizex - 1 - left);
-       height = nrnd(sizey - top);
-       XCopyArea (dpy, window, window, gc, left, top, width, height,
-                  left + 1, top);
-       break;
-      case 4:                  /* move a block up */
-       left = nrnd(sizex);
-       top = nrnd(sizey - 1) + 1;
-       width = nrnd(sizex - left);
-       height = nrnd(sizey - top);
-       XCopyArea (dpy, window, window, gc, left, top, width, height,
-                  left, top - 1);
-       break;
-      default:                 /* move block down (biased to this) */
-       left = nrnd(sizex);
-       top = nrnd(sizey - 1);
-       width = nrnd(sizex - left);
-       height = nrnd(sizey - 1 - top);
-       XCopyArea (dpy, window, window, gc, left, top, width, height,
-                  left, top + 1);
-       break;
+    left = nrnd(sizex - 1);
+    top = nrnd(sizey);
+    width = nrnd(sizex - left);
+    height = nrnd(sizey - top);
+
+    toleft = left;
+    totop = top;
+
+    if (mode == IN || mode == OUT) {
+      int x = left+(width/2);
+      int y = top+(height/2);
+      int cx = sizex/2;
+      int cy = sizey/2;
+      if (mode == IN) {
+       if      (x > cx && y > cy)   bias = upleft_bias;
+       else if (x < cx && y > cy)   bias = upright_bias;
+       else if (x < cx && y < cy)   bias = downright_bias;
+       else /* (x > cx && y < cy)*/ bias = downleft_bias;
+      } else {
+       if      (x > cx && y > cy)   bias = downright_bias;
+       else if (x < cx && y > cy)   bias = downleft_bias;
+       else if (x < cx && y < cy)   bias = upleft_bias;
+       else /* (x > cx && y < cy)*/ bias = upright_bias;
+      }
     }
-    XSync (dpy, True);
+
+    switch (bias[random() % (sizeof(no_bias)/sizeof(*no_bias))]) {
+      case L: toleft = left-1; break;
+      case R: toleft = left+1; break;
+      case U: totop = top-1; break;
+      case D: totop = top+1; break;
+      default: abort(); break;
+    }
+
+    XCopyArea (dpy, window, window, gc, left, top, width, height,
+              toleft, totop);
 #undef nrnd
 }
 
@@ -119,12 +186,14 @@ char *defaults [] = {
   "*visualID:                  Best",
 #endif
 
-  "*delay:                     10",
+  "*delay:                     10000",
+  "*mode:                      random",
   0
 };
 
 XrmOptionDescRec options [] = {
   { "-delay",          ".delay",               XrmoptionSepArg, 0 },
+  { "-mode",           ".mode",                XrmoptionSepArg, 0 },
   { 0, 0, 0, 0 }
 };
 
@@ -133,7 +202,10 @@ screenhack (Display *dpy, Window window)
 {
     init_decay (dpy, window);
     while (1) {
+      int i;
+      for (i = 0; i < 100; i++)
        decay1 (dpy, window);
-       if (delay) usleep (delay);
+      XSync(dpy, False);
+      if (delay) usleep (delay);
     }
 }