ftp://ftp.uni-heidelberg.de/pub/X11/contrib/applications/xscreensaver-1.27.tar.Z
[xscreensaver] / utils / fade.c
index 2fbb2e97fa4f872609c6413ff5ca243977c57982..de6ce0b91fa5dffa5c3b0d30bd4e36f58a523111 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1992 Jamie Zawinski <jwz@lucid.com>
+/* xscreensaver, Copyright (c) 1992-1996 Jamie Zawinski <jwz@netscape.com>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
 #include <X11/Xos.h>
 
 #if __STDC__
-# define bcopy(from,to,size) memcpy((to),(from),(size))
-# define bzero(addr,size) memset((addr),0,(size))
-extern void screenhack_usleep (unsigned long);
+# define P(x)x
 #else
-extern void screenhack_usleep ();
+# define P(x)()
 #endif
 
+extern int get_visual_class P((Display *, Visual *));
+extern void screenhack_usleep P((unsigned long));
 #define usleep screenhack_usleep
 
 #define MAX_COLORS 4096
@@ -38,13 +38,23 @@ copy_colormap (dpy, cmap, into_cmap)
      Colormap cmap, into_cmap;
 {
   int i;
-  ncolors = CellsOfScreen (DefaultScreenOfDisplay (dpy));
+  Screen *screen = DefaultScreenOfDisplay (dpy);
+  Visual *visual = DefaultVisualOfScreen (screen);
+  Window window = RootWindowOfScreen (screen);
+  int vclass = get_visual_class (dpy, visual);
+
+  ncolors = CellsOfScreen (screen);
+
+  /* If this is a colormap on a mono visual, or one with insanely many
+     color cells, bug out. */
   if (ncolors <= 2 || ncolors > MAX_COLORS)
     return 0;
+  /* If this is a non-writable visual, bug out. */
+  if (vclass == StaticGray || vclass == StaticColor || vclass == TrueColor)
+    return 0;
+
   if (! into_cmap)
-    into_cmap = XCreateColormap (dpy, RootWindow (dpy, DefaultScreen (dpy)),
-                                DefaultVisual (dpy, DefaultScreen (dpy)),
-                                AllocAll);
+    into_cmap = XCreateColormap (dpy, window, visual, AllocAll);
   if (! cmap)
     cmap = DefaultColormap (dpy, DefaultScreen (dpy));
   for (i = 0; i < ncolors; i++)
@@ -70,24 +80,43 @@ blacken_colormap (dpy, cmap)
 }
 
 
+/* The business with `install_p' and `extra_cmaps' is to fake out the SGI
+   8-bit video hardware, which is capable of installing multiple (4) colormaps
+   simultaniously.  We have to install multiple copies of the same set of
+   colors in order to fill up all the available slots in the hardware color
+   lookup table.
+ */
+
 void
-fade_colormap (dpy, cmap, cmap2, seconds, ticks, out_p)
+fade_colormap (dpy, cmap, cmap2, seconds, ticks, out_p, install_p)
      Display *dpy;
      Colormap cmap, cmap2;
      int seconds, ticks;
      Bool out_p;
+     Bool install_p;
 {
   int i;
   int steps = seconds * ticks;
   XEvent dummy_event;
 
+  Screen *screen = DefaultScreenOfDisplay (dpy);
+  Visual *visual = DefaultVisualOfScreen (screen);
+  Window window = RootWindowOfScreen (screen);
+  static Colormap extra_cmaps[4] = { 0, };
+  int n_extra_cmaps = sizeof(extra_cmaps)/sizeof(*extra_cmaps);
+
   if (! cmap2)
     return;
 
   for (i = 0; i < ncolors; i++)
     orig_colors [i].pixel = i;
   XQueryColors (dpy, cmap, orig_colors, ncolors);
-  bcopy (orig_colors, current_colors, ncolors * sizeof (XColor));
+  memcpy (current_colors, orig_colors, ncolors * sizeof (XColor));
+
+  if (install_p)
+    for (i=0; i < n_extra_cmaps; i++)
+      if (!extra_cmaps[i])
+       extra_cmaps[i] = XCreateColormap (dpy, window, visual, AllocAll);
 
   for (i = (out_p ? steps : 0);
        (out_p ? i > 0 : i < steps);
@@ -101,6 +130,19 @@ fade_colormap (dpy, cmap, cmap2, seconds, ticks, out_p)
          current_colors[j].blue  = orig_colors[j].blue  * i / steps;
        }
       XStoreColors (dpy, cmap2, current_colors, ncolors);
+
+      if (install_p)
+       {
+         for (j=0; j < n_extra_cmaps; j++)
+           if (extra_cmaps[j])
+             XStoreColors (dpy, extra_cmaps[j], current_colors, ncolors);
+
+         for (j=0; j < n_extra_cmaps; j++)
+           if (extra_cmaps[j])
+             XInstallColormap (dpy, extra_cmaps[j]);
+         XInstallColormap (dpy, cmap2);
+       }
+
       XSync (dpy, False);
 
       /* If there is user activity, bug out.
@@ -117,18 +159,28 @@ fade_colormap (dpy, cmap, cmap2, seconds, ticks, out_p)
                           &dummy_event))
        {
          XPutBackEvent (dpy, &dummy_event);
-         return;
+         goto DONE;
        }
 
       usleep (1000000 / (ticks * 2)); /* the 2 is a hack... */
     }
-}
 
-#if 0
+DONE:
+
+  if (install_p)
+    {
+      XInstallColormap (dpy, cmap2);
+/*      for (i=0; i < n_extra_cmaps; i++)
+       if (extra_cmaps[i])
+         XFreeColormap (dpy, extra_cmaps[i]);
+ */
+    }
+}
 
 \f
+#if 0
+#include "../hacks/screenhack.h"
 char *progclass = "foo";
-
 char *defaults [] = {
   0
 };
@@ -148,15 +200,21 @@ screenhack (dpy, w)
   int ticks = 30 * seconds;
   int delay = 1;
 
+  XSynchronize (dpy, True);
+
   while (1)
     {
       XSync (dpy, False);
-      XGrabServer (dpy);
+/*      XGrabServer (dpy); */
+      fprintf(stderr,"out..."); fflush(stderr);
       XInstallColormap (dpy, cmap2);
-      fade_colormap (dpy, cmap, cmap2, seconds, ticks, True);
+      fade_colormap (dpy, cmap, cmap2, seconds, ticks, True, True);
+      fprintf(stderr, "done.\n"); fflush(stderr);
       if (delay) sleep (delay);
-      fade_colormap (dpy, cmap, cmap2, seconds, ticks, False);
+      fprintf(stderr,"in..."); fflush(stderr);
+      fade_colormap (dpy, cmap, cmap2, seconds, ticks, False, True);
       XInstallColormap (dpy, cmap);
+      fprintf(stderr, "done.\n"); fflush(stderr);
       XUngrabServer (dpy);
       XSync (dpy, False);
       if (delay) sleep (delay);