From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / ripples.c
index aa286426a960537ce62e6360e1d049bde3d50001..447a4555995b8a88ec8ebfbb20522c71e6f76935 100644 (file)
@@ -39,6 +39,7 @@
  * 31 Oct 1999: Added in lighting hack
  * 13 Nov 1999: Speed up tweaks
  *              Adjust "light" for different bits per colour (-water only)
+ * 09 Oct 2016: Updated for new xshm.c
  *
  */
 
@@ -47,9 +48,7 @@
 
 typedef enum {ripple_drop, ripple_blob, ripple_box, ripple_stir} ripple_mode;
 
-#ifdef HAVE_XSHM_EXTENSION
 #include "xshm.h"
-#endif /* HAVE_XSHM_EXTENSION */
 
 #define TABLE 256
 
@@ -62,6 +61,7 @@ struct state {
   XImage *orig_map, *buffer_map;
   int ctab[256];
   Colormap colormap;
+  Screen *screen;
   int ncolors;
   int light;
 
@@ -97,10 +97,7 @@ struct state {
 
   async_load_state *img_loader;
 
-#ifdef HAVE_XSHM_EXTENSION
-  Bool use_shm;
   XShmSegmentInfo shm_info;
-#endif /* HAVE_XSHM_EXTENSION */
 };
 
 
@@ -242,8 +239,9 @@ draw_transparent_vanilla(struct state *st, short *src)
 
 
 static void
-set_mask(unsigned long color, unsigned long *mask, int *shift)
+set_mask(unsigned long *mask, int *shift)
 {
+  unsigned long color = *mask;
   *shift = 0;
   while (color != 0 && (color & 1) == 0) {
     (*shift)++;
@@ -495,6 +493,7 @@ setup_X(struct state *st)
   XGetWindowAttributes(st->dpy, st->window, &xgwa);
   depth = xgwa.depth;
   st->colormap = xgwa.colormap;
+  st->screen = xgwa.screen;
   st->bigwidth = xgwa.width;
   st->bigheight = xgwa.height;
   st->visual = xgwa.visual;
@@ -531,7 +530,7 @@ setup_X(struct state *st)
 
     st->img_loader = load_image_async_simple (0, xgwa.screen, st->window,
                                               st->window, 0, 0);
-    st->start_time = time ((time_t) 0);
+    st->start_time = time ((time_t *) 0);
   } else {
     XGCValues gcv;
 
@@ -544,40 +543,16 @@ setup_X(struct state *st)
     exit(1);
   }
 
-  st->buffer_map = 0;
-
-#ifdef HAVE_XSHM_EXTENSION
-  if (st->use_shm) {
-    st->buffer_map = create_xshm_image(st->dpy, xgwa.visual, depth,
-                                  ZPixmap, 0, &st->shm_info, st->bigwidth, st->bigheight);
-    if (!st->buffer_map) {
-      st->use_shm = False;
-      fprintf(stderr, "create_xshm_image failed\n");
-    }
-  }
-#endif /* HAVE_XSHM_EXTENSION */
-
-  if (!st->buffer_map) {
-    st->buffer_map = XCreateImage(st->dpy, xgwa.visual,
-                             depth, ZPixmap, 0, 0,
-                             st->bigwidth, st->bigheight, 8, 0);
-    st->buffer_map->data = (char *)
-      calloc(st->buffer_map->height, st->buffer_map->bytes_per_line);
-  }
+  st->buffer_map = create_xshm_image(st->dpy, xgwa.visual, depth,
+                                     ZPixmap, &st->shm_info, st->bigwidth, st->bigheight);
 }
 
 
 static void
 DisplayImage(struct state *st)
 {
-#ifdef HAVE_XSHM_EXTENSION
-  if (st->use_shm)
-    XShmPutImage(st->dpy, st->window, st->gc, st->buffer_map, 0, 0, 0, 0,
-                st->bigwidth, st->bigheight, False);
-  else
-#endif /* HAVE_XSHM_EXTENSION */
-    XPutImage(st->dpy, st->window, st->gc, st->buffer_map, 0, 0, 0, 0,
-             st->bigwidth, st->bigheight);
+  put_xshm_image(st->dpy, st->window, st->gc, st->buffer_map, 0, 0, 0, 0,
+                 st->bigwidth, st->bigheight, &st->shm_info);
 }
 
 
@@ -656,7 +631,8 @@ init_oily_colors(struct state *st)
 
   if (!mono_p) {
     colors = (XColor *)malloc(sizeof(*colors) * (st->ncolors+1));
-    make_smooth_colormap(st->dpy, st->visual, st->colormap, colors, &st->ncolors,
+    make_smooth_colormap(st->screen, st->visual, st->colormap,
+                         colors, &st->ncolors,
                          True, /* allocate */
                          False, /* not writable */
                          True); /* verbose (complain about failure) */
@@ -703,6 +679,7 @@ sinc(struct state *st, double x)
   int i;
   i = (int)(x * TABLE + 0.5);
   if (i >= TABLE) i = (TABLE-1) - (i-(TABLE-1));
+  if (i < 0) return 0.;
   return st->cos_tab[i];
 #elif 0
   return cos(x * M_PI/2);
@@ -718,19 +695,21 @@ sinc(struct state *st, double x)
 static void
 add_circle_drop(struct state *st, int x, int y, int radius, int dheight)
 {
-  int i, r2, cx, cy;
+  int r, r2, cx, cy;
   short *buf = (random()&1) ? st->bufferA : st->bufferB;
 
-  i = y * st->width + x;
   r2 = radius * radius;
 
+
   for (cy = -radius; cy <= radius; cy++)
     for (cx = -radius; cx <= radius; cx++) {
-      int r = cx*cx + cy*cy;
-      if (r <= r2) {
-        buf[i + cx + cy*st->width] =
-          (short)(dheight * sinc(st, sqrt(r)/radius));
-      }
+      int xx = x+cx;
+      int yy = y+cy;
+      if (xx < 0 || yy < 0 || xx >= st->width || yy >= st->height) {break;}
+      r = cx*cx + cy*cy;
+      if (r > r2) break;
+      buf[xx + yy*st->width] =
+        (short)(dheight * sinc(st, (radius > 0) ? sqrt(r)/radius : 0));
     }
 }
 
@@ -962,9 +941,6 @@ ripples_init (Display *disp, Window win)
   st->fluidity = get_integer_resource(disp, "fluidity", "Integer");
   st->transparent = get_boolean_resource(disp, "water", "Boolean");
   st->grayscale_p = get_boolean_resource(disp, "grayscale", "Boolean");
-#ifdef HAVE_XSHM_EXTENSION
-  st->use_shm = get_boolean_resource(disp, "useSHM", "Boolean");
-#endif /* HAVE_XSHM_EXTENSION */
   st->light = get_integer_resource(disp, "light", "Integer");
 
   if (st->delay < 0) st->delay = 0;
@@ -991,9 +967,11 @@ ripples_init (Display *disp, Window win)
   if (st->transparent && st->light > 0) {
     int maxbits;
     st->draw_transparent = draw_transparent_light;
-    set_mask(st->visual->red_mask,   &st->rmask, &st->rshift);
-    set_mask(st->visual->green_mask, &st->gmask, &st->gshift);
-    set_mask(st->visual->blue_mask,  &st->bmask, &st->bshift);
+    visual_rgb_masks (st->screen, st->visual,
+                      &st->rmask, &st->gmask, &st->bmask);
+    set_mask(&st->rmask, &st->rshift);
+    set_mask(&st->gmask, &st->gshift);
+    set_mask(&st->bmask, &st->bshift);
     if (st->rmask == 0) st->draw_transparent = draw_transparent_vanilla;
 
     /* Adjust the shift value "light" when we don't have 8 bits per colour */
@@ -1003,9 +981,11 @@ ripples_init (Display *disp, Window win)
   } else {
     if (st->grayscale_p)
     { 
-      set_mask(st->visual->red_mask,   &st->rmask, &st->rshift);
-      set_mask(st->visual->green_mask, &st->gmask, &st->gshift);
-      set_mask(st->visual->blue_mask,  &st->bmask, &st->bshift);
+      visual_rgb_masks (st->screen, st->visual,
+                        &st->rmask, &st->gmask, &st->bmask);
+      set_mask(&st->rmask, &st->rshift);
+      set_mask(&st->gmask, &st->gshift);
+      set_mask(&st->bmask, &st->bshift);
     }
     st->draw_transparent = draw_transparent_vanilla;
   }
@@ -1027,7 +1007,7 @@ ripples_draw (Display *dpy, Window window, void *closure)
       if (! st->img_loader) {  /* just finished */
         XWindowAttributes xgwa;
         XGetWindowAttributes(st->dpy, st->window, &xgwa);
-        st->start_time = time ((time_t) 0);
+        st->start_time = time ((time_t *) 0);
         st->orig_map = XGetImage (st->dpy, st->window, 0, 0, 
                                   xgwa.width, xgwa.height,
                                   ~0L, ZPixmap);
@@ -1037,12 +1017,12 @@ ripples_draw (Display *dpy, Window window, void *closure)
     }
 
     if (!st->img_loader &&
-        st->start_time + st->duration < time ((time_t) 0)) {
+        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->start_time = time ((time_t *) 0);
       return st->delay;
     }
 
@@ -1071,6 +1051,12 @@ ripples_reshape (Display *dpy, Window window, void *closure,
 static Bool
 ripples_event (Display *dpy, Window window, void *closure, XEvent *event)
 {
+  struct state *st = (struct state *) closure;
+  if (screenhack_event_helper (dpy, window, event))
+    {
+      st->start_time = 0;
+      return True;
+    }
   return False;
 }
 
@@ -1091,16 +1077,20 @@ static const char *ripples_defaults[] =
   "*duration:          120",
   "*rate:              5",
   "*box:               0",
-  "*water:             False",
+  "*water:             True",
   "*oily:              False",
   "*stir:              False",
   "*fluidity:          6",
-  "*light:             0",
+  "*light:             4",
   "*grayscale:                 False",
 #ifdef HAVE_XSHM_EXTENSION
   "*useSHM: True",
 #else
   "*useSHM: False",
+#endif
+#ifdef HAVE_MOBILE
+  "*ignoreRotation: True",
+  "*rotateImages:   True",
 #endif
   0
 };