ftp://ftp.uni-heidelberg.de/pub/X11/contrib/applications/xscreensaver-2.07.tar.gz
[xscreensaver] / hacks / slidescreen.c
index 37ca4d159392d5589123e227b50310d02bfde197..a3792cd08f9ecfe214bbc600727217fbf287b5ba 100644 (file)
@@ -1,4 +1,5 @@
-/* xscreensaver, Copyright (c) 1992, 1993 Jamie Zawinski <jwz@lucid.com>
+/* xscreensaver, Copyright (c) 1992, 1993, 1994, 1996, 1997 
+ * Jamie Zawinski <jwz@netscape.com>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -19,57 +20,25 @@ static int xoff, yoff;
 static int grid_w, grid_h;
 static int delay, delay2;
 static GC gc;
-
-static Bool
-MapNotify_event_p (dpy, event, window)
-     Display *dpy;
-     XEvent *event;
-     XPointer window;
-{
-  return (event->xany.type == MapNotify &&
-         event->xvisibility.window == (Window) window);
-}
-
-
-static Bool
-screensaver_window_p (dpy, window)
-     Display *dpy;
-     Window window;
-{
-  Atom type;
-  int format;
-  unsigned long nitems, bytesafter;
-  char *version;
-  Pixmap pixmap;
-  if (XGetWindowProperty (dpy, window,
-                         XInternAtom (dpy, "_SCREENSAVER_VERSION", False),
-                         0, 1, False, XA_STRING,
-                         &type, &format, &nitems, &bytesafter,
-                         (unsigned char **) &version)
-      == Success
-      && type != None)
-    return True;
-  return False;
-}
+int max_width, max_height;
 
 static void
-init_slide (dpy, window)
-     Display *dpy;
-     Window window;
+init_slide (Display *dpy, Window window)
 {
   int i;
-  XEvent event;
   XGCValues gcv;
   XWindowAttributes xgwa;
   int border;
-  int root_p;
   unsigned long fg;
-  Pixmap pixmap = 0;
   Drawable d;
   Colormap cmap;
+  Visual *visual;
 
   XGetWindowAttributes (dpy, window, &xgwa);
   cmap = xgwa.colormap;
+  visual = xgwa.visual;
+  max_width = xgwa.width;
+  max_height = xgwa.height;
 
   delay = get_integer_resource ("delay", "Integer");
   delay2 = get_integer_resource ("delay2", "Integer");
@@ -77,7 +46,17 @@ init_slide (dpy, window)
   pix_inc = get_integer_resource ("pixelIncrement", "Integer");
   border = get_integer_resource ("internalBorderWidth", "InternalBorderWidth");
   fg = get_pixel_resource ("background", "Background", dpy, cmap);
-  root_p = get_boolean_resource ("root", "Boolean");
+
+  grab_screen_image (xgwa.screen, window);
+
+
+  /* Total kludge -- if grab_screen_image() installed a new colormap, assume
+     that pixel 0 is the one we should use.  This further assumes that the
+     pixel is black, which overrides the user's -background setting, alas.
+   */
+  XGetWindowAttributes (dpy, window, &xgwa);
+  if (cmap != xgwa.colormap) fg = 0;
+
 
   if (delay < 0) delay = 0;
   if (delay2 < 0) delay2 = 0;
@@ -90,48 +69,6 @@ init_slide (dpy, window)
   gc = XCreateGC (dpy, window, GCForeground |GCFunction | GCSubwindowMode,
                  &gcv);
 
-  if (screensaver_window_p (dpy, window))
-    {
-      /* note: this assumes vroot.h didn't encapsulate the XRootWindowOfScreen
-        function, only the RootWindowOfScreen macro... */
-      Window real_root = XRootWindowOfScreen (DefaultScreenOfDisplay (dpy));
-
-      XSetWindowBackgroundPixmap (dpy, window, None);
-
-      /* prevent random viewer of the screen saver (locker) from messing
-        with windows.   We don't check whether it succeeded, because what
-        are our options, really... */
-      XGrabPointer (dpy, real_root, True, ButtonPressMask|ButtonReleaseMask,
-                   GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
-      XGrabKeyboard (dpy, real_root, True, GrabModeSync, GrabModeAsync,
-                    CurrentTime);
-
-      XUnmapWindow (dpy, window);
-      XSync (dpy, True);
-      sleep (5);     /* wait for everyone to swap in and handle exposes... */
-      XMapWindow (dpy, window);
-
-      XUngrabPointer (dpy, CurrentTime);
-      XUngrabKeyboard (dpy, CurrentTime);
-
-      XSync (dpy, True);
-    }
-  else if (root_p)
-    {
-      pixmap = XCreatePixmap(dpy, window, xgwa.width, xgwa.height, xgwa.depth);
-      XCopyArea (dpy, RootWindowOfScreen (xgwa.screen), pixmap, gc,
-                xgwa.x, xgwa.y, xgwa.width, xgwa.height, 0, 0);
-      XSetWindowBackgroundPixmap (dpy, window, pixmap);
-    }
-  else
-    {
-      XSetWindowBackgroundPixmap (dpy, window, None);
-      XMapWindow (dpy, window);
-      XFlush (dpy);
-      XIfEvent (dpy, &event, MapNotify_event_p, (XPointer) window);
-      XSync (dpy, True);
-    }
-
   XGetWindowAttributes (dpy, window, &xgwa);
   bitmap_w = xgwa.width;
   bitmap_h = xgwa.height;
@@ -143,11 +80,10 @@ init_slide (dpy, window)
   xoff = (bitmap_w - (grid_w * grid_size)) / 2;
   yoff = (bitmap_h - (grid_h * grid_size)) / 2;
 
-  d = (pixmap ? pixmap : window);
+  d = window;
 
   if (border)
     {
-      int i;
       for (i = 0; i <= bitmap_w; i += grid_size)
        XFillRectangle (dpy, d, gc, xoff+i-border/2, yoff, border, bitmap_h);
       for (i = 0; i <= bitmap_h; i += grid_size)
@@ -165,7 +101,6 @@ init_slide (dpy, window)
       XFillRectangle (dpy, d, gc, 0, bitmap_h - yoff, bitmap_w, yoff);
     }
 
-  if (pixmap) XClearWindow (dpy, window);
   XSync (dpy, True);
   if (delay2) usleep (delay2 * 2);
  for (i = 0; i < grid_size; i += pix_inc)
@@ -208,9 +143,7 @@ init_slide (dpy, window)
 }
 
 static void
-slide1 (dpy, window)
-     Display *dpy;
-     Window window;
+slide1 (Display *dpy, Window window)
 {
   /* this code is a total kludge, but who cares, it works... */
  int i, x, y, ix, iy, dx, dy, dir, w, h, size, inc;
@@ -223,6 +156,7 @@ slide1 (dpy, window)
      case 1: dx = -1, dy = 0;  break;
      case 2: dx = 0,  dy = -1; break;
      case 3: dx = 1,  dy = 0;  break;
+     default: abort ();
      }
  } while (dir == last ||
          hole_x + dx < 0 || hole_x + dx >= grid_w ||
@@ -236,6 +170,7 @@ slide1 (dpy, window)
    case 1: size = 1 + (random()%hole_x);               w = size; h = 1; break;
    case 2: size = 1 + (random()%hole_y);               h = size; w = 1; break;
    case 3: size = 1 + (random()%(grid_w - hole_x - 1)); w = size; h = 1; break;
+   default: abort ();
    }
 
  if (dx == -1) hole_x -= (size - 1);
@@ -246,10 +181,22 @@ slide1 (dpy, window)
  inc = pix_inc;
  for (i = 0; i < grid_size; i += inc)
    {
+     int fx, fy, tox, toy;
      if (inc + i > grid_size)
        inc = grid_size - i;
-     XCopyArea (dpy, window, window, gc, x, y, grid_size * w, grid_size * h,
-               x - dx * inc, y - dy * inc);
+     tox = x - dx * inc;
+     toy = y - dy * inc;
+
+     fx = (x < 0 ? 0 : x > max_width  ? max_width  : x);
+     fy = (y < 0 ? 0 : y > max_height ? max_height : y);
+     tox = (tox < 0 ? 0 : tox > max_width  ? max_width  : tox);
+     toy = (toy < 0 ? 0 : toy > max_height ? max_height : toy);
+
+     XCopyArea (dpy, window, window, gc,
+               fx, fy,
+               grid_size * w, grid_size * h,
+               tox, toy);
+
      x -= dx * inc;
      y -= dy * inc;
      switch (dir)
@@ -282,9 +229,13 @@ slide1 (dpy, window)
 char *progclass = "SlidePuzzle";
 
 char *defaults [] = {
-  "SlidePuzzle.mappedWhenManaged:false",
-  "SlidePuzzle.dontClearWindow:         true",
-  "*background:                        black",
+  "*dontClearRoot:             True",
+
+#ifdef __sgi   /* really, HAVE_READ_DISPLAY_EXTENSION */
+  "*visualID:                  Best",
+#endif
+
+  "*background:                        Black",
   "*gridSize:                  70",
   "*pixelIncrement:            10",
   "*internalBorderWidth:       1",
@@ -299,14 +250,11 @@ XrmOptionDescRec options [] = {
   { "-increment",      ".pixelIncrement",      XrmoptionSepArg, 0 },
   { "-delay",          ".delay",               XrmoptionSepArg, 0 },
   { "-delay2",         ".delay2",              XrmoptionSepArg, 0 },
+  { 0, 0, 0, 0 }
 };
 
-int options_size = (sizeof (options) / sizeof (options[0]));
-
 void
-screenhack (dpy, window)
-     Display *dpy;
-     Window window;
+screenhack (Display *dpy, Window window)
 {
   init_slide (dpy, window);
   while (1)