From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / slip.c
index 44672e7b17e80a2ba5f6c1ca390c678523db7a7e..6537086b731aab668da321c51a8709b7a2dcaea4 100644 (file)
@@ -1,9 +1,8 @@
 /* -*- Mode: C; tab-width: 4 -*- */
 /* slip --- lots of slipping blits */
 
-#if !defined( lint ) && !defined( SABER )
+#if 0
 static const char sccsid[] = "@(#)slip.c       5.00 2000/11/01 xlockmore";
-
 #endif
 
 /*-
@@ -27,28 +26,29 @@ static const char sccsid[] = "@(#)slip.c    5.00 2000/11/01 xlockmore";
  */
 
 #ifdef STANDALONE
-#define MODE_slip
-#define PROGCLASS "Slip"
-#define HACK_INIT init_slip
-#define HACK_DRAW draw_slip
-#define slip_opts xlockmore_opts
-#define DEFAULTS "*delay: 50000 \n" \
- "*count: 35 \n" \
- "*cycles: 50 \n" \
- "*ncolors: 200 \n"
-#include "xlockmore.h"         /* in xscreensaver distribution */
+# define MODE_slip
+# define DEFAULTS      "*delay: 50000 \n" \
+                                       "*count: 35 \n" \
+                                       "*cycles: 50 \n" \
+                                       "*ncolors: 200 \n" \
+                                       "*fpsSolid:     true \n" \
+                                       "*ignoreRotation: True \n" \
+
+# define refresh_slip 0
+# define release_slip 0
+# include "xlockmore.h"                /* in xscreensaver distribution */
 #else /* STANDALONE */
-#include "xlock.h"             /* in xlockmore distribution */
+# include "xlock.h"            /* in xlockmore distribution */
 #endif /* STANDALONE */
 
 #ifdef MODE_slip
 
-ModeSpecOpt slip_opts =
+ENTRYPOINT ModeSpecOpt slip_opts =
 {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
 
 #ifdef USE_MODULES
 ModStruct   slip_description =
-{"slip", "init_slip", "draw_slip", "release_slip",
+{"slip", "init_slip", "draw_slip", (char *) NULL,
  "init_slip", "init_slip", (char *) NULL, &slip_opts,
  50000, 35, 50, 1, 64, 1.0, "",
  "Shows slipping blits", 0, NULL};
@@ -65,6 +65,7 @@ typedef struct {
        short       lasthalf;
        int         stage;
        unsigned long r;
+    Bool image_loading_p;
 } slipstruct;
 static slipstruct *slips = (slipstruct *) NULL;
 
@@ -101,6 +102,22 @@ erandom(slipstruct *sp, int mv)
                return -(res & mv);
 }
 
+#ifdef STANDALONE
+static void
+image_loaded_cb (Screen *screen, Window w, Drawable d,
+                 const char *name, XRectangle *geom,
+                 void *closure)
+{
+  ModeInfo *mi = (ModeInfo *) closure;
+  slipstruct *sp = &slips[MI_SCREEN(mi)];
+  Display *dpy = DisplayOfScreen (screen);
+  XCopyArea (dpy, d, w, mi->gc, 0, 0,
+             sp->width, sp->height, 0, 0);
+  XFreePixmap (dpy, d);
+  sp->image_loading_p = False;
+}
+#endif /* STANDALONE */
+
 static void
 prepare_screen(ModeInfo * mi, slipstruct * sp)
 {
@@ -110,13 +127,6 @@ prepare_screen(ModeInfo * mi, slipstruct * sp)
        int         i, n, w = sp->width / 20;
        int         not_solid = halfrandom(sp, 10);
 
-#ifdef STANDALONE                        /* jwz -- sometimes hack the desktop image! */
-       if (halfrandom(sp, 2) == 0) {
-               grab_screen_image(DefaultScreenOfDisplay(display),
-                                 MI_WINDOW(mi));
-       }
-#endif
-
        sp->backwards = (int) (LRAND() & 1);    /* jwz: go the other way sometimes */
 
        if (sp->first_time || !halfrandom(sp, 10)) {
@@ -155,6 +165,21 @@ prepare_screen(ModeInfo * mi, slipstruct * sp)
                               ww, ww);
        }
        sp->first_time = 0;
+
+
+#ifdef STANDALONE                        /* jwz -- sometimes hack the desktop image! */
+       if (!sp->image_loading_p &&
+        (1||halfrandom(sp, 2) == 0)) {
+      /* Load it into a pixmap so that the "Loading" message and checkerboard
+         don't show up on the window -- we keep running while the image is
+         in progress... */
+      Pixmap p = XCreatePixmap (MI_DISPLAY(mi), MI_WINDOW(mi),
+                                sp->width, sp->height, mi->xgwa.depth);
+      sp->image_loading_p = True;
+      load_image_async (ScreenOfDisplay (MI_DISPLAY(mi), 0/*####MI_SCREEN(mi)*/),
+                        MI_WINDOW(mi), p, image_loaded_cb, mi);
+       }
+#endif
 }
 
 static int
@@ -168,33 +193,39 @@ quantize(double d)
        return i;
 }
 
-void
-init_slip(ModeInfo * mi)
+ENTRYPOINT void
+reshape_slip (ModeInfo * mi, int w, int h)
+{
+  slipstruct *sp = &slips[MI_SCREEN(mi)];
+  sp->width = w;
+  sp->height = h;
+  sp->blit_width = sp->width / 25;
+  sp->blit_height = sp->height / 25;
+
+  sp->mode = 0;
+  sp->nblits_remaining = 0;
+}
+
+ENTRYPOINT void
+init_slip (ModeInfo * mi)
 {
        slipstruct *sp;
 
-       if (slips == NULL) {
-               if ((slips = (slipstruct *) calloc(MI_NUM_SCREENS(mi),
-                                              sizeof (slipstruct))) == NULL)
-                       return;
-       }
+       MI_INIT (mi, slips, 0);
        sp = &slips[MI_SCREEN(mi)];
 
-       sp->width = MI_WIDTH(mi);
-       sp->height = MI_HEIGHT(mi);
-
-       sp->blit_width = sp->width / 25;
-       sp->blit_height = sp->height / 25;
        sp->nblits_remaining = 0;
        sp->mode = 0;
        sp->first_time = 1;
 
        /* no "NoExpose" events from XCopyArea wanted */
        XSetGraphicsExposures(MI_DISPLAY(mi), MI_GC(mi), False);
+
+    reshape_slip (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
 }
 
-void
-draw_slip(ModeInfo * mi)
+ENTRYPOINT void
+draw_slip (ModeInfo * mi)
 {
        Display    *display = MI_DISPLAY(mi);
        Window      window = MI_WINDOW(mi);
@@ -216,8 +247,7 @@ draw_slip(ModeInfo * mi)
                double      x, y, dx = 0, dy = 0, t, s1, s2;
 
                if (0 == sp->nblits_remaining--) {
-                       static int  lut[] =
-                       {0, 0, 0, 1, 1, 1, 2};
+                       static const int lut[] = {0, 0, 0, 1, 1, 1, 2};
 
                        prepare_screen(mi, sp);
                        sp->nblits_remaining = MI_COUNT(mi) *
@@ -320,13 +350,19 @@ X Error of failed request:  BadDrawable (invalid Pixmap or Window parameter)
        }
 }
 
-void
-release_slip(ModeInfo * mi)
+ENTRYPOINT Bool
+slip_handle_event (ModeInfo *mi, XEvent *event)
 {
-       if (slips != NULL) {
-               (void) free((void *) slips);
-               slips = (slipstruct *) NULL;
-       }
+  slipstruct *sp = &slips[MI_SCREEN(mi)];
+  if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event))
+    {
+      sp->first_time = 1;
+      sp->nblits_remaining = 0;
+      return True;
+    }
+  return False;
 }
 
+XSCREENSAVER_MODULE ("Slip", slip)
+
 #endif /* MODE_slip */