From http://www.jwz.org/xscreensaver/xscreensaver-5.22.tar.gz
[xscreensaver] / hacks / slidescreen.c
index fe4d24aef62dbc3902ed9cc32bebf8dc1d4f272e..23c990c296d13c66bc461a9847919b53e496623c 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992-2006 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2008 Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -25,6 +25,7 @@ struct state {
   int xoff, yoff;
   int grid_w, grid_h;
   int delay, delay2;
+  int duration;
   GC gc;
   unsigned long fg, bg;
   int max_width, max_height;
@@ -36,6 +37,7 @@ struct state {
   int draw_last;
   int draw_initted;
 
+  time_t start_time;
   async_load_state *img_loader;
 };
 
@@ -45,7 +47,6 @@ slidescreen_init (Display *dpy, Window window)
 {
   struct state *st = (struct state *) calloc (1, sizeof(*st));
   XWindowAttributes xgwa;
-  Visual *visual;
   XGCValues gcv;
   long gcflags;
 
@@ -54,13 +55,14 @@ slidescreen_init (Display *dpy, Window window)
   XGetWindowAttributes (st->dpy, st->window, &xgwa);
   st->img_loader = load_image_async_simple (0, xgwa.screen, st->window,
                                             st->window, 0, 0);
+  st->start_time = time ((time_t) 0);
 
-  visual = xgwa.visual;
   st->max_width = xgwa.width;
   st->max_height = xgwa.height;
 
   st->delay = get_integer_resource (st->dpy, "delay", "Integer");
   st->delay2 = get_integer_resource (st->dpy, "delay2", "Integer");
+  st->duration = get_integer_resource (st->dpy, "duration", "Seconds");
   st->grid_size = get_integer_resource (st->dpy, "gridSize", "Integer");
   st->pix_inc = get_integer_resource (st->dpy, "pixelIncrement", "Integer");
 
@@ -72,6 +74,7 @@ slidescreen_init (Display *dpy, Window window)
 
   if (st->delay < 0) st->delay = 0;
   if (st->delay2 < 0) st->delay2 = 0;
+  if (st->duration < 1) st->duration = 1;
   if (st->pix_inc < 1) st->pix_inc = 1;
   if (st->grid_size < 1) st->grid_size = 1;
 
@@ -303,11 +306,24 @@ slidescreen_draw (Display *dpy, Window window, void *closure)
   if (st->img_loader)   /* still loading */
     {
       st->img_loader = load_image_async_simple (st->img_loader, 0, 0, 0, 0, 0);
-      if (! st->img_loader)  /* just finished */
+      if (! st->img_loader) {  /* just finished */
+        st->start_time = time ((time_t) 0);
         draw_grid (st);
+      }
       return st->delay;
     }
 
+  if (!st->img_loader &&
+      st->start_time + st->duration < time ((time_t) 0)) {
+    XWindowAttributes xgwa;
+    XGetWindowAttributes(st->dpy, st->window, &xgwa);
+    st->img_loader = load_image_async_simple (0, xgwa.screen, st->window,
+                                              st->window, 0, 0);
+    st->start_time = time ((time_t) 0);
+    st->draw_initted = 0;
+    return st->delay;
+  }
+
   if (! st->draw_initted)
     {
       if (!slidescreen_draw_early (st))
@@ -326,7 +342,8 @@ slidescreen_draw (Display *dpy, Window window, void *closure)
      /* alternate between horizontal and vertical slides */
      /* note that draw_dir specifies the direction the _hole_ moves, not the tiles */
      if (st->draw_last == VERTICAL) {
-       if ((st->draw_rnd = random () % (st->grid_w - 1)) < st->hole_x) {
+       if (((st->grid_w > 1) ? st->draw_rnd = random () % (st->grid_w - 1) : 0)
+          < st->hole_x) {
          st->draw_dx = -1; st->draw_dir = LEFT;  st->hole_x -= st->draw_rnd;
        } else {
          st->draw_dx =  1; st->draw_dir = RIGHT; st->draw_rnd -= st->hole_x;
@@ -334,7 +351,8 @@ slidescreen_draw (Display *dpy, Window window, void *closure)
        st->draw_dy = 0; st->draw_w = st->draw_size = st->draw_rnd + 1; st->draw_h = 1;
        st->draw_last = HORIZONTAL;
      } else {
-       if ((st->draw_rnd = random () % (st->grid_h - 1)) < st->hole_y) {
+       if (((st->grid_h > 1) ? st->draw_rnd = random () % (st->grid_h - 1) : 0)
+          < st->hole_y) {
          st->draw_dy = -1; st->draw_dir = UP;    st->hole_y -= st->draw_rnd;
        } else {
          st->draw_dy =  1; st->draw_dir = DOWN;  st->draw_rnd -= st->hole_y;
@@ -407,6 +425,16 @@ static void
 slidescreen_reshape (Display *dpy, Window window, void *closure, 
                  unsigned int w, unsigned int h)
 {
+  struct state *st = (struct state *) closure;
+  st->max_width = w;
+  st->max_height = h;
+  if (! st->img_loader) {
+    XWindowAttributes xgwa;
+    XGetWindowAttributes (st->dpy, st->window, &xgwa);
+    st->img_loader = load_image_async_simple (0, xgwa.screen, st->window,
+                                              st->window, 0, 0);
+    st->start_time = time ((time_t) 0);
+  }
 }
 
 static Bool
@@ -427,6 +455,7 @@ slidescreen_free (Display *dpy, Window window, void *closure)
 
 static const char *slidescreen_defaults [] = {
   "*dontClearRoot:             True",
+  "*fpsSolid:                  true",
 
 #ifdef __sgi   /* really, HAVE_READ_DISPLAY_EXTENSION */
   "*visualID:                  Best",
@@ -439,6 +468,10 @@ static const char *slidescreen_defaults [] = {
   "*internalBorderWidth:       4",
   "*delay:                     50000",
   "*delay2:                    1000000",
+  "*duration:                  120",
+#ifdef USE_IPHONE
+  "*ignoreRotation:             True",
+#endif
   0
 };
 
@@ -448,7 +481,8 @@ static XrmOptionDescRec slidescreen_options [] = {
   { "-increment",      ".pixelIncrement",      XrmoptionSepArg, 0 },
   { "-delay",          ".delay",               XrmoptionSepArg, 0 },
   { "-delay2",         ".delay2",              XrmoptionSepArg, 0 },
+  {"-duration",                ".duration",            XrmoptionSepArg, 0 },
   { 0, 0, 0, 0 }
 };
 
-XSCREENSAVER_MODULE ("Slidescreen", slidescreen)
+XSCREENSAVER_MODULE ("SlideScreen", slidescreen)