From http://www.jwz.org/xscreensaver/xscreensaver-5.39.tar.gz
[xscreensaver] / hacks / blitspin.c
index 83f9bd4c8e5a29682ab0525be2c32cc9448a67c4..d27271d36a10b019dbbfac39a2390f3c0c29e211 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992-2012 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2018 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
  */
 
 #include "screenhack.h"
-#include "xpm-pixmap.h"
+#include "pow2.h"
+#include "ximage-loader.h"
 #include <stdio.h>
+#include <time.h>
 
-#include "images/som.xbm"
+#include "images/gen/som_png.h"
 
 /* Implementing this using XCopyArea doesn't work with color images on OSX.
    This means that the Cocoa implementation of XCopyArea in jwxyz.m is 
@@ -40,7 +42,7 @@
    So, on OSX, we implement the blitter by hand.  It is correct, but
    orders of magnitude slower.
  */
-#ifndef HAVE_COCOA
+#ifndef HAVE_JWXYZ
 # define USE_XCOPYAREA
 #endif
 
@@ -154,7 +156,7 @@ blitspin_draw (Display *dpy, Window window, void *closure)
         st->first_time = 0;
         st->loaded_p = True;
         st->qwad = -1;
-        st->start_time = time ((time_t) 0);
+        st->start_time = time ((time_t *) 0);
         blitspin_init_2 (st);
       }
 
@@ -165,7 +167,7 @@ blitspin_draw (Display *dpy, Window window, void *closure)
 
   if (!st->img_loader &&
       st->load_ext_p &&
-      st->start_time + st->duration < time ((time_t) 0)) {
+      st->start_time + st->duration < time ((time_t *) 0)) {
     /* Start a new image loading, but keep rotating the old image 
        until the new one arrives. */
     st->img_loader = load_image_async_simple (0, st->xgwa.screen, st->window,
@@ -219,17 +221,13 @@ blitspin_draw (Display *dpy, Window window, void *closure)
 
 
 static int 
-to_pow2(struct state *st, int n, Bool up)
+blitspin_to_pow2(int n, Bool up)
 {
-  int powers_of_2[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024,
-                       2048, 4096, 8192, 16384, 32768, 65536 };
-  int i = 0;
-  if (n > 65536) st->size = 65536;
-  while (n >= powers_of_2[i]) i++;
-  if (n == powers_of_2[i-1])
+  int pow2 = to_pow2 (n);
+  if (n == pow2)
     return n;
   else
-    return powers_of_2[up ? i : i-1];
+    return up ? pow2 : pow2 >> 1;
 }
 
 static void *
@@ -254,7 +252,7 @@ blitspin_init (Display *d_arg, Window w_arg)
   if (st->delay2 < 0) st->delay2 = 0;
   if (st->duration < 1) st->duration = 1;
 
-  st->start_time = time ((time_t) 0);
+  st->start_time = time ((time_t *) 0);
 
   bitmap_name = get_string_resource (st->dpy, "bitmap", "Bitmap");
   if (! bitmap_name || !*bitmap_name)
@@ -267,13 +265,25 @@ blitspin_init (Display *d_arg, Window w_arg)
   if (!strcasecmp (bitmap_name, "(builtin)") ||
       !strcasecmp (bitmap_name, "builtin"))
     {
-      st->width = som_width;
-      st->height = som_height;
-      st->bitmap = XCreatePixmapFromBitmapData (st->dpy, st->window,
-                                                (char *) som_bits,
-                                                st->width, st->height, 
-                                                st->fg, st->bg, 
-                                                st->xgwa.depth);
+      Pixmap mask = 0;
+      Pixmap pixmap = image_data_to_pixmap (st->dpy, st->window,
+                                            som_png, sizeof(som_png),
+                                            &st->width, &st->height, &mask);
+      XGCValues gcv;
+      GC gc;
+      gcv.foreground = st->bg;
+      gc = XCreateGC (st->dpy, st->window, GCForeground, &gcv);
+      st->bitmap = XCreatePixmap (st->dpy, st->window, 
+                                  st->xgwa.width, st->xgwa.height,
+                                  st->xgwa.depth);
+      XFillRectangle (st->dpy, st->bitmap, gc, 0, 0, st->width, st->height);
+      XSetClipMask (st->dpy, gc, mask);
+      XCopyArea (st->dpy, pixmap, st->bitmap, gc, 0, 0, st->width, st->height,
+                 0, 0);
+      XFreeGC (st->dpy, gc);
+      XFreePixmap (st->dpy, pixmap);
+      XFreePixmap (st->dpy, mask);
+
       st->scale_up = True; /* definitely. */
       st->loaded_p = True;
       blitspin_init_2 (st);
@@ -293,7 +303,7 @@ blitspin_init (Display *d_arg, Window w_arg)
     }
   else
     {
-      st->bitmap = xpm_file_to_pixmap (st->dpy, st->window, bitmap_name,
+      st->bitmap = file_to_pixmap (st->dpy, st->window, bitmap_name,
                                    &st->width, &st->height, 0);
       st->scale_up = True; /* probably? */
       blitspin_init_2 (st);
@@ -310,11 +320,12 @@ blitspin_init_2 (struct state *st)
 
   /* make it square */
   st->size = (st->width < st->height) ? st->height : st->width;
-  st->size = to_pow2(st, st->size, st->scale_up); /* round up to power of 2 */
+  /* round up to power of 2 */
+  st->size = blitspin_to_pow2(st->size, st->scale_up);
   {                                            /* don't exceed screen size */
     int s = XScreenNumberOfScreen(st->xgwa.screen);
-    int w = to_pow2(st, XDisplayWidth(st->dpy, s), False);
-    int h = to_pow2(st, XDisplayHeight(st->dpy, s), False);
+    int w = blitspin_to_pow2(XDisplayWidth(st->dpy, s), False);
+    int h = blitspin_to_pow2(XDisplayHeight(st->dpy, s), False);
     if (st->size > w) st->size = w;
     if (st->size > h) st->size = h;
   }
@@ -398,6 +409,12 @@ blitspin_reshape (Display *dpy, Window window, void *closure,
 static Bool
 blitspin_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;
 }
 
@@ -415,8 +432,8 @@ static const char *blitspin_defaults [] = {
   "*delay2:    500000",
   "*duration:  120",
   "*bitmap:    (default)",
-  "*geometry:  512x512",
-#ifdef USE_IPHONE
+  "*geometry:  1080x1080",
+#ifdef HAVE_MOBILE
   "*ignoreRotation: True",
 #endif
   0