From http://www.jwz.org/xscreensaver/xscreensaver-5.22.tar.gz
[xscreensaver] / hacks / swirl.c
index 7f3764f02a75f9b5de626cf7186e7ca6fdf407c5..efe2f8d1d89b3b57d87c35a0373792294d515c01 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- Mode: C; tab-width: 4 -*-
  * swirl --- swirly color-cycling patterns.
  */
-#if !defined( lint ) && !defined( SABER )
+#if 0
 static const char sccsid[] = "@(#)swirl.c      4.00 97/01/01 xlockmore";
 #endif
 
@@ -19,7 +19,7 @@ static const char sccsid[] = "@(#)swirl.c     4.00 97/01/01 xlockmore";
  * event will the author be liable for any lost revenue or profits or
  * other special, indirect and consequential damages.
  *
- * 13-May-97: jwz@netscape.com: turned into a standalone program.
+ * 13-May-97: jwz@jwz.org: turned into a standalone program.
  * 21-Apr-95: improved startup time for TrueColour displays
  *            (limited to 16bpp to save memory) S.Early <sde1000@cam.ac.uk>
  * 09-Jan-95: fixed colour maps (more colourful) and the image now spirals
@@ -30,22 +30,26 @@ static const char sccsid[] = "@(#)swirl.c   4.00 97/01/01 xlockmore";
  */
 
 #ifdef STANDALONE
-# define PROGCLASS                                     "Swirl"
-# define HACK_INIT                                     init_swirl
-# define HACK_DRAW                                     draw_swirl
-# define swirl_opts                                    xlockmore_opts
 # define DEFAULTS      "*count:                5       \n"                     \
                                        "*delay:                10000   \n"                     \
-                                       "*ncolors:              200     \n"
+                                       "*ncolors:              200     \n"                     \
+                                       "*useSHM:               True    \n" \
+                                       "*fpsSolid:             true    \n" \
+                                       "*ignoreRotation: True \n" \
+
 # define SMOOTH_COLORS
 # define WRITABLE_COLORS
+# define swirl_handle_event 0
 # include "xlockmore.h"                                /* from the xscreensaver distribution */
-# include <X11/Xutil.h>
+# ifdef HAVE_XSHM_EXTENSION
+#  include "xshm.h"
+# endif /* HAVE_XSHM_EXTENSION */
 #else  /* !STANDALONE */
 # include "xlock.h"                                    /* from the xlockmore distribution */
+# undef HAVE_XSHM_EXTENSION
 #endif /* !STANDALONE */
 
-ModeSpecOpt swirl_opts = {
+ENTRYPOINT ModeSpecOpt swirl_opts = {
   0, NULL, 0, NULL, NULL };
 
 #include <time.h>
@@ -219,9 +223,7 @@ initialise_swirl(ModeInfo * mi, SWIRL_P swirl)
 #endif /* !STANDALONE */
 
 
-#ifdef STANDALONE
-# define MI_COLORMAP MI_WIN_COLORMAP
-#else /* !STANDALONE */
+#ifndef STANDALONE
        swirl->fg = MI_FG_COLOR(mi);
        swirl->bg = MI_BG_COLOR(mi);
        swirl->fgcol.pixel = swirl->fg;
@@ -241,37 +243,34 @@ initialise_swirl(ModeInfo * mi, SWIRL_P swirl)
  * -      swirl is the swirl data
  */
 static void
-initialise_image(Display * dpy, SWIRL_P swirl)
+initialise_image(ModeInfo * mi, SWIRL_P swirl)
 {
-       unsigned int pad;
-       int         bytes_per_line;
-       int image_depth = swirl->rdepth;
-       int data_depth = image_depth;
-
-       /* On SGIs at least, using an XImage of depth 24 on a Visual of depth 24
-          requires the XImage data to use 32 bits per pixel.  I don't understand
-          how one is supposed to determine this -- maybe XListPixmapFormats?
-          But on systems that don't work this way, allocating 32 bpp instead of
-          24 will be wasteful but non-fatal.  -- jwz, 16-May-97. */
-       if (data_depth >= 24 && data_depth < 32)
-         data_depth = 32;
-
-       /* get the bitmap pad */
-       pad = BitmapPad(dpy);
-       /* destroy the old image (destroy XImage and data) */
-       if (swirl->ximage != NULL)
-               XDestroyImage(swirl->ximage);
-
-       /* how many bytes per line? (bits rounded up to pad) */
-       bytes_per_line = ((swirl->width * data_depth + pad - 1) / pad) * (pad / 8);
-
-       /* allocate space for the image */
-       swirl->image = (unsigned char *) calloc(bytes_per_line * swirl->height, 1);
-
-       /* create an ximage with this */
-       swirl->ximage = XCreateImage(dpy, swirl->visual, image_depth, ZPixmap,
-                                    0, (char *) swirl->image, swirl->width,
-                                    swirl->height, pad, bytes_per_line);
+  Display *dpy = MI_DISPLAY(mi);
+
+  if (swirl->ximage != NULL)
+       XDestroyImage(swirl->ximage);
+
+  swirl->ximage = 0;
+#ifdef HAVE_XSHM_EXTENSION
+  if (mi->use_shm)
+       {
+         swirl->ximage = create_xshm_image(dpy, swirl->visual, swirl->rdepth,
+                                                                               ZPixmap, 0, &mi->shm_info,
+                                                                               swirl->width, swirl->height);
+         if (!swirl->ximage)
+               mi->use_shm = False;
+       }
+#endif /* HAVE_XSHM_EXTENSION */
+
+  if (!swirl->ximage)
+       {
+         swirl->ximage = XCreateImage(dpy, swirl->visual, swirl->rdepth, ZPixmap,
+                                                                  0, 0, swirl->width, swirl->height,
+                                                                  8, 0);
+         swirl->image = (unsigned char *)
+        calloc(swirl->height, swirl->ximage->bytes_per_line);
+      swirl->ximage->data = (char *) swirl->image;
+       }
 }
 
 /****************************************************************/
@@ -1126,10 +1125,17 @@ draw_point(ModeInfo * mi, SWIRL_P swirl)
                draw_block(swirl->ximage, x, y, r, do_point(swirl, x, y));
 
        /* update the screen */
-/* PURIFY 4.0.1 on SunOS4 and on Solaris 2 reports a 256 byte memory leak on * 
-   the next line. */
-       XPutImage(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), swirl->ximage,
-                 x, y, x, y, r, r);
+
+#ifdef HAVE_XSHM_EXTENSION
+       if (mi->use_shm)
+         XShmPutImage(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), swirl->ximage,
+                                  x, y, x, y, r, r, False);
+       else
+#endif /* !HAVE_XSHM_EXTENSION */
+         /* PURIFY 4.0.1 on SunOS4 and on Solaris 2 reports a 256 byte memory
+                leak on the next line. */
+         XPutImage(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), swirl->ximage,
+                               x, y, x, y, r, r);
 }
 
 /****************************************************************/
@@ -1239,7 +1245,7 @@ next_point(SWIRL_P swirl)
  *
  * -      win is the window to draw in
  */
-void
+ENTRYPOINT void
 init_swirl(ModeInfo * mi)
 {
        Display    *display = MI_DISPLAY(mi);
@@ -1248,19 +1254,14 @@ init_swirl(ModeInfo * mi)
 
        /* does the swirls array exist? */
        if (swirls == NULL) {
-               int         i;
-
                /* allocate an array, one entry for each screen */
-               swirls = (SWIRL_P) calloc(ScreenCount(display), sizeof (SWIRL));
-
-               /* initialise them all */
-               for (i = 0; i < ScreenCount(display); i++)
-                       initialise_swirl(mi, &swirls[i]);
+               swirls = (SWIRL_P) calloc(MI_NUM_SCREENS(mi), sizeof (SWIRL));
        }
        /* get a pointer to this swirl */
        swirl = &(swirls[MI_SCREEN(mi)]);
-
-       /* get window parameters */
+        initialise_swirl(mi, swirl);
+                
+        /* get window parameters */
        swirl->win = window;
        swirl->width = MI_WIN_WIDTH(mi);
        swirl->height = MI_WIN_HEIGHT(mi);
@@ -1272,7 +1273,7 @@ init_swirl(ModeInfo * mi)
                swirl->depth = 16;
 
        /* initialise image for speeding up drawing */
-       initialise_image(display, swirl);
+       initialise_image(mi, swirl);
 
        /* clear the window (before setting the colourmap) */
        XClearWindow(display, MI_WINDOW(mi));
@@ -1341,7 +1342,7 @@ init_swirl(ModeInfo * mi)
  *
  * -      win is the window to draw in
  */
-void
+ENTRYPOINT void
 draw_swirl(ModeInfo * mi)
 {
        SWIRL_P     swirl = &(swirls[MI_SCREEN(mi)]);
@@ -1352,7 +1353,7 @@ draw_swirl(ModeInfo * mi)
                if (swirl->drawing) {
 #ifdef STANDALONE
                  if (mi->writable_p)
-                       rotate_colors(MI_DISPLAY(mi), MI_COLORMAP(mi),
+                       rotate_colors(mi->xgwa.screen, MI_COLORMAP(mi),
                                                  swirl->rgb_values, swirl->colours, 1);
 #else  /* !STANDALONE */
                        /* rotate the colours */
@@ -1374,7 +1375,7 @@ draw_swirl(ModeInfo * mi)
                } else {
 #ifdef STANDALONE
                  if (mi->writable_p)
-                       rotate_colors(MI_DISPLAY(mi), MI_COLORMAP(mi),
+                       rotate_colors(mi->xgwa.screen, MI_COLORMAP(mi),
                                                  swirl->rgb_values, swirl->colours, 1);
 #else  /* !STANDALONE */
                        /* rotate the colours */
@@ -1412,10 +1413,9 @@ draw_swirl(ModeInfo * mi)
 #ifdef STANDALONE
                                        /* Pick a new colormap! */
                                        XClearWindow (MI_DISPLAY(mi), MI_WINDOW(mi));
-                                       free_colors (MI_DISPLAY(mi), MI_COLORMAP(mi),
+                                       free_colors (mi->xgwa.screen, MI_COLORMAP(mi),
                                                                 mi->colors, mi->npixels);
-                                       make_smooth_colormap (MI_DISPLAY(mi),
-                                                                                 MI_VISUAL(mi),
+                                       make_smooth_colormap (mi->xgwa.screen, MI_VISUAL(mi),
                                                                                  MI_COLORMAP(mi),
                                                                                  mi->colors, &mi->npixels, True,
                                                                                  &mi->writable_p, True);
@@ -1432,10 +1432,17 @@ draw_swirl(ModeInfo * mi)
        }
 }
 
+ENTRYPOINT void
+reshape_swirl(ModeInfo * mi, int width, int height)
+{
+  XClearWindow (MI_DISPLAY (mi), MI_WINDOW(mi));
+  init_swirl (mi);
+}
+
 /****************************************************************/
 
-void
-release_swirl(ModeInfo * mi)
+ENTRYPOINT void
+release_swirl (ModeInfo * mi)
 {
        /* does the swirls array exist? */
        if (swirls != NULL) {
@@ -1445,10 +1452,14 @@ release_swirl(ModeInfo * mi)
                for (i = 0; i < MI_NUM_SCREENS(mi); i++) {
                        SWIRL_P     swirl = &(swirls[i]);
 
+#ifndef STANDALONE
                        if (swirl->cmap != (Colormap) NULL)
                                XFreeColormap(MI_DISPLAY(mi), swirl->cmap);
+#endif /* STANDALONE */
+#ifndef STANDALONE
                        if (swirl->rgb_values != NULL)
                                XFree((void *) swirl->rgb_values);
+#endif /* !STANDALONE */
                        if (swirl->ximage != NULL)
                                XDestroyImage(swirl->ximage);
                        if (swirl->knots)
@@ -1462,8 +1473,8 @@ release_swirl(ModeInfo * mi)
 
 /****************************************************************/
 
-void
-refresh_swirl(ModeInfo * mi)
+ENTRYPOINT void
+refresh_swirl (ModeInfo * mi)
 {
        SWIRL_P     swirl = &(swirls[MI_SCREEN(mi)]);
 
@@ -1473,3 +1484,5 @@ refresh_swirl(ModeInfo * mi)
                swirl->drawing = False;
        }
 }
+
+XSCREENSAVER_MODULE ("Swirl", swirl)