ftp://ftp.sunet.se/pub/vendor/sco/skunkware/osr5/x11/savers/xscreensaver/xscreensaver...
[xscreensaver] / utils / fade.c
diff --git a/utils/fade.c b/utils/fade.c
deleted file mode 100644 (file)
index 07b1a4e..0000000
+++ /dev/null
@@ -1,621 +0,0 @@
-/* xscreensaver, Copyright (c) 1992-1998 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
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation.  No representations are made about the suitability of this
- * software for any purpose.  It is provided "as is" without express or 
- * implied warranty.
- */
-
-#include "utils.h"
-
-#include <sys/time.h> /* for gettimeofday() */
-
-#ifdef VMS
-# include "vms-gtod.h"
-#endif /* VMS */
-
-#include "visual.h"
-#include "usleep.h"
-#include "fade.h"
-
-
-Colormap
-copy_colormap (Screen *screen, Visual *visual,
-              Colormap cmap, Colormap into_cmap)
-{
-  int i;
-  Display *dpy = DisplayOfScreen (screen);
-  Window window = RootWindowOfScreen (screen);
-  int ncolors = CellsOfScreen (screen);
-  XColor *colors = 0;
-
-  /* If this is a colormap on a mono visual, or one with insanely many
-     color cells, bug out. */
-  if (ncolors <= 2 || ncolors > 4096)
-    return 0;
-  /* If this is a non-writable visual, bug out. */
-  if (!has_writable_cells (screen, visual))
-    return 0;
-
-  if (! into_cmap)
-    into_cmap = XCreateColormap (dpy, window, visual, AllocAll);
-  if (! cmap)
-    cmap = DefaultColormapOfScreen (screen);
-
-  colors = (XColor *) calloc(sizeof(XColor), ncolors);
-  for (i = 0; i < ncolors; i++)
-    colors [i].pixel = i;
-  XQueryColors (dpy, cmap, colors, ncolors);
-  XStoreColors (dpy, into_cmap, colors, ncolors);
-  free (colors);
-  return into_cmap;
-}
-
-
-void
-blacken_colormap (Screen *screen, Colormap cmap)
-{
-  Display *dpy = DisplayOfScreen (screen);
-  int ncolors = CellsOfScreen (screen);
-  XColor *colors;
-  int i;
-  if (ncolors > 4096)
-    return;
-  colors = (XColor *) calloc(sizeof(XColor), ncolors);
-  for (i = 0; i < ncolors; i++)
-    colors[i].pixel = i;
-  XStoreColors (dpy, cmap, colors, ncolors);
-  free (colors);
-}
-
-
-
-static void fade_screens_1 (Display *dpy, Colormap *cmaps,
-                           Window *black_windows, int seconds, int ticks,
-                           Bool out_p, Bool clear_windows);
-#ifdef HAVE_SGI_VC_EXTENSION
-static int sgi_gamma_fade (Display *dpy,
-                          Window *black_windows, int seconds, int ticks,
-                          Bool out_p, Bool clear_windows);
-#endif /* HAVE_SGI_VC_EXTENSION */
-
-
-
-void
-fade_screens (Display *dpy, Colormap *cmaps, Window *black_windows,
-             int seconds, int ticks,
-             Bool out_p, Bool clear_windows)
-{
-  int oseconds = seconds;
-  Bool was_in_p = !out_p;
-
-  /* When we're asked to fade in, first fade out, then fade in.
-     That way all the transitions are smooth -- from what's on the
-     screen, to black, to the desktop.
-   */
-  if (was_in_p)
-    {
-      clear_windows = True;
-      out_p = True;
-      seconds /= 3;
-      if (seconds == 0)
-       seconds = 1;
-    }
-
- AGAIN:
-
-#ifdef HAVE_SGI_VC_EXTENSION
-  /* First try to do it by fading the gamma in an SGI-specific way... */
-  if (0 != sgi_gamma_fade(dpy, black_windows, seconds, ticks, out_p,
-                         clear_windows))
-#endif /* HAVE_SGI_VC_EXTENSION */
-    /* Else, do it the old-fashioned way, which (somewhat) loses if
-       there are TrueColor windows visible. */
-    fade_screens_1 (dpy, cmaps, black_windows, seconds, ticks,
-                   out_p, clear_windows);
-
-  /* If we were supposed to be fading in, do so now (we just faded out,
-     so now fade back in.)
-   */
-  if (was_in_p)
-    {
-      was_in_p = False;
-      out_p = False;
-      seconds = oseconds * 2 / 3;
-      if (seconds == 0)
-       seconds = 1;
-      goto AGAIN;
-    }
-}
-
-
-/* The business with `cmaps_per_screen' 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, so we install an extra N colormaps per screen to make sure
-   that all screens really go black.
-
-   I'm told that this trick also works with XInside's AcceleratedX when using
-   the Matrox Millenium card (which also allows multiple PseudoColor and
-   TrueColor visuals to co-exist and display properly at the same time.)  
-
-   This trick works ok on the 24-bit Indy video hardware, but doesn't work at
-   all on the O2 24-bit hardware.  I guess the higher-end hardware is too
-   "good" for this to work (dammit.)  So... I figured out the "right" way to
-   do this on SGIs, which is to ramp the monitor's gamma down to 0.  That's
-   what is implemented in sgi_gamma_fade(), so we use that if we can.
- */
-static void
-fade_screens_1 (Display *dpy, Colormap *cmaps, Window *black_windows,
-               int seconds, int ticks,
-               Bool out_p, Bool clear_windows)
-{
-  int i, j, k;
-  int steps = seconds * ticks;
-  long usecs_per_step = (long)(seconds * 1000000) / (long)steps;
-  XEvent dummy_event;
-  int cmaps_per_screen = 5;
-  int nscreens = ScreenCount(dpy);
-  int ncmaps = nscreens * cmaps_per_screen;
-  Colormap *fade_cmaps = 0;
-  Bool installed = False;
-  int total_ncolors;
-  XColor *orig_colors, *current_colors, *screen_colors, *orig_screen_colors;
-  struct timeval then, now;
-#ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-#endif
-
-  total_ncolors = 0;
-  for (i = 0; i < nscreens; i++)
-    total_ncolors += CellsOfScreen (ScreenOfDisplay(dpy, i));
-
-  orig_colors    = (XColor *) calloc(sizeof(XColor), total_ncolors);
-  current_colors = (XColor *) calloc(sizeof(XColor), total_ncolors);
-
-  /* Get the contents of the colormap we are fading from or to. */
-  screen_colors = orig_colors;
-  for (i = 0; i < nscreens; i++)
-    {
-      int ncolors = CellsOfScreen (ScreenOfDisplay (dpy, i));
-      Colormap cmap = (cmaps ? cmaps[i] : 0);
-      if (!cmap) cmap = DefaultColormap(dpy, i);
-
-      for (j = 0; j < ncolors; j++)
-       screen_colors[j].pixel = j;
-      XQueryColors (dpy, cmap, screen_colors, ncolors);
-
-      screen_colors += ncolors;
-    }
-
-  memcpy (current_colors, orig_colors, total_ncolors * sizeof (XColor));
-
-
-  /* Make the writable colormaps (we keep these around and reuse them.) */
-  if (!fade_cmaps)
-    {
-      fade_cmaps = (Colormap *) calloc(sizeof(Colormap), ncmaps);
-      for (i = 0; i < nscreens; i++)
-       {
-         Visual *v = DefaultVisual(dpy, i);
-         Screen *s = ScreenOfDisplay(dpy, i);
-         if (has_writable_cells (s, v))
-           for (j = 0; j < cmaps_per_screen; j++)
-             fade_cmaps[(i * cmaps_per_screen) + j] =
-               XCreateColormap (dpy, RootWindowOfScreen (s), v, AllocAll);
-       }
-    }
-
-#ifdef GETTIMEOFDAY_TWO_ARGS
-  gettimeofday(&then, &tzp);
-#else
-  gettimeofday(&then);
-#endif
-
-  /* Iterate by steps of the animation... */
-  for (i = (out_p ? steps : 0);
-       (out_p ? i > 0 : i < steps);
-       (out_p ? i-- : i++))
-    {
-
-      /* For each screen, compute the current value of each color...
-       */
-      orig_screen_colors = orig_colors;
-      screen_colors = current_colors;
-      for (j = 0; j < nscreens; j++)
-       {
-         int ncolors = CellsOfScreen (ScreenOfDisplay (dpy, j));
-         for (k = 0; k < ncolors; k++)
-           {
-             /* This doesn't take into account the relative luminance of the
-                RGB components (0.299, 0.587, and 0.114 at gamma 2.2) but
-                the difference is imperceptible for this application... */
-             screen_colors[k].red   = orig_screen_colors[k].red   * i / steps;
-             screen_colors[k].green = orig_screen_colors[k].green * i / steps;
-             screen_colors[k].blue  = orig_screen_colors[k].blue  * i / steps;
-           }
-         screen_colors      += ncolors;
-         orig_screen_colors += ncolors;
-       }
-
-      /* Put the colors into the maps...
-       */
-      screen_colors = current_colors;
-      for (j = 0; j < nscreens; j++)
-       {
-         int ncolors = CellsOfScreen (ScreenOfDisplay (dpy, j));
-         for (k = 0; k < cmaps_per_screen; k++)
-           {
-             Colormap c = fade_cmaps[j * cmaps_per_screen + k];
-             if (c)
-               XStoreColors (dpy, c, screen_colors, ncolors);
-           }
-         screen_colors += ncolors;
-       }
-
-      /* Put the maps on the screens, and then take the windows off the screen.
-        (only need to do this the first time through the loop.)
-       */
-      if (!installed)
-       {
-         for (j = 0; j < ncmaps; j++)
-           if (fade_cmaps[j])
-             XInstallColormap (dpy, fade_cmaps[j]);
-         installed = True;
-
-         if (black_windows && !out_p)
-           for (j = 0; j < nscreens; j++)
-             if (black_windows[j])
-               {
-                 XUnmapWindow (dpy, black_windows[j]);
-                 XClearWindow (dpy, black_windows[j]);
-               }
-       }
-
-      XSync (dpy, False);
-
-      /* If there is user activity, bug out.  (Bug out on keypresses or
-        mouse presses, but not motion, and not release events.  Bugging
-        out on motion made the unfade hack be totally useless, I think.)
-
-        We put the event back so that the calling code can notice it too.
-        It would be better to not remove it at all, but that's harder
-        because Xlib has such a non-design for this kind of crap, and
-        in this application it doesn't matter if the events end up out
-        of order, so in the grand unix tradition we say "fuck it" and
-        do something that mostly works for the time being.
-       */
-      if (XCheckMaskEvent (dpy, (KeyPressMask|ButtonPressMask), &dummy_event))
-       {
-         XPutBackEvent (dpy, &dummy_event);
-         goto DONE;
-       }
-
-#ifdef GETTIMEOFDAY_TWO_ARGS
-      gettimeofday(&now, &tzp);
-#else
-      gettimeofday(&now);
-#endif
-
-      /* If we haven't already used up our alotted time, sleep to avoid
-        changing the colormap too fast. */
-      {
-       long diff = (((now.tv_sec - then.tv_sec) * 1000000) +
-                    now.tv_usec - then.tv_usec);
-       then.tv_sec = now.tv_sec;
-       then.tv_usec = now.tv_usec;
-       if (usecs_per_step > diff)
-         usleep (usecs_per_step - diff);
-      }
-    }
-
- DONE:
-
-  if (orig_colors)    free (orig_colors);
-  if (current_colors) free (current_colors);
-
-  /* If we've been given windows to raise after blackout, raise them before
-     releasing the colormaps.
-   */
-  if (out_p && black_windows)
-    {
-      for (i = 0; i < nscreens; i++)
-       {
-         if (clear_windows)
-           XClearWindow (dpy, black_windows[i]);
-         XMapRaised (dpy, black_windows[i]);
-       }
-      XSync(dpy, False);
-    }
-
-  /* Now put the target maps back.
-     If we're fading out, use the given cmap (or the default cmap, if none.)
-     If we're fading in, always use the default cmap.
-   */
-  for (i = 0; i < nscreens; i++)
-    {
-      Colormap cmap = (cmaps ? cmaps[i] : 0);
-      if (!cmap || !out_p)
-       cmap = DefaultColormap(dpy, i);
-      XInstallColormap (dpy, cmap);
-    }
-
-  /* The fade (in or out) is complete, so we don't need the black maps on
-     stage any more.
-   */
-  for (i = 0; i < ncmaps; i++)
-    if (fade_cmaps[i])
-      {
-       XUninstallColormap(dpy, fade_cmaps[i]);
-       XFreeColormap(dpy, fade_cmaps[i]);
-       fade_cmaps[i] = 0;
-      }
-  free(fade_cmaps);
-  fade_cmaps = 0;
-}
-
-
-#ifdef HAVE_SGI_VC_EXTENSION
-
-# include <X11/extensions/XSGIvc.h>
-
-struct screen_gamma_info {
-  int gamma_map;  /* ??? always using 0 */
-  int nred, ngreen, nblue;
-  unsigned short *red1, *green1, *blue1;
-  unsigned short *red2, *green2, *blue2;
-  int gamma_size;
-  int gamma_precision;
-  Bool alpha_p;
-};
-
-
-static void whack_gamma(Display *dpy, int screen,
-                       struct screen_gamma_info *info, float ratio);
-
-static int
-sgi_gamma_fade (Display *dpy,
-               Window *black_windows, int seconds, int ticks,
-               Bool out_p, Bool clear_windows)
-{
-  int steps = seconds * ticks;
-  long usecs_per_step = (long)(seconds * 1000000) / (long)steps;
-  XEvent dummy_event;
-  int nscreens = ScreenCount(dpy);
-  struct timeval then, now;
-#ifdef GETTIMEOFDAY_TWO_ARGS
-  struct timezone tzp;
-#endif
-  int i, screen;
-  int status = -1;
-  struct screen_gamma_info *info = (struct screen_gamma_info *)
-    calloc(nscreens, sizeof(*info));
-
-  /* Get the current gamma maps for all screens.
-     Bug out and return -1 if we can't get them for some screen.
-   */
-  for (screen = 0; screen < nscreens; screen++)
-    {
-      if (!XSGIvcQueryGammaMap(dpy, screen, info[screen].gamma_map,
-                              &info[screen].gamma_size,
-                              &info[screen].gamma_precision,
-                              &info[screen].alpha_p))
-       goto FAIL;
-
-      if (!XSGIvcQueryGammaColors(dpy, screen, info[screen].gamma_map,
-                                 XSGIVC_COMPONENT_RED,
-                                 &info[screen].nred, &info[screen].red1))
-       goto FAIL;
-      if (! XSGIvcQueryGammaColors(dpy, screen, info[screen].gamma_map,
-                                  XSGIVC_COMPONENT_GREEN,
-                                  &info[screen].ngreen, &info[screen].green1))
-       goto FAIL;
-      if (!XSGIvcQueryGammaColors(dpy, screen, info[screen].gamma_map,
-                                 XSGIVC_COMPONENT_BLUE,
-                                 &info[screen].nblue, &info[screen].blue1))
-       goto FAIL;
-
-      if (info[screen].gamma_precision == 8)    /* Scale it up to 16 bits. */
-       {
-         int j;
-         for(j = 0; j < info[screen].nred; j++)
-           info[screen].red1[j]   =
-             ((info[screen].red1[j]   << 8) | info[screen].red1[j]);
-         for(j = 0; j < info[screen].ngreen; j++)
-           info[screen].green1[j] =
-             ((info[screen].green1[j] << 8) | info[screen].green1[j]);
-         for(j = 0; j < info[screen].nblue; j++)
-           info[screen].blue1[j]  =
-             ((info[screen].blue1[j]  << 8) | info[screen].blue1[j]);
-       }
-
-      info[screen].red2   = (unsigned short *)
-       malloc(sizeof(*info[screen].red2)   * (info[screen].nred+1));
-      info[screen].green2 = (unsigned short *)
-       malloc(sizeof(*info[screen].green2) * (info[screen].ngreen+1));
-      info[screen].blue2  = (unsigned short *)
-       malloc(sizeof(*info[screen].blue2)  * (info[screen].nblue+1));
-    }
-
-#ifdef GETTIMEOFDAY_TWO_ARGS
-  gettimeofday(&then, &tzp);
-#else
-  gettimeofday(&then);
-#endif
-
-  /* If we're fading in (from black), then first crank the gamma all the
-     way down to 0, then take the windows off the screen.
-   */
-  if (!out_p)
-    for (screen = 0; screen < nscreens; screen++)
-      {
-       whack_gamma(dpy, screen, &info[screen], 0.0);
-       if (black_windows && black_windows[screen])
-         {
-           XUnmapWindow (dpy, black_windows[screen]);
-           XClearWindow (dpy, black_windows[screen]);
-           XSync(dpy, False);
-         }
-      }
-
-
-  /* Iterate by steps of the animation... */
-  for (i = (out_p ? steps : 0);
-       (out_p ? i > 0 : i < steps);
-       (out_p ? i-- : i++))
-    {
-      for (screen = 0; screen < nscreens; screen++)
-       {
-         whack_gamma(dpy, screen, &info[screen],
-                     (((float)i) / ((float)steps)));
-
-         /* If there is user activity, bug out.  (Bug out on keypresses or
-            mouse presses, but not motion, and not release events.  Bugging
-            out on motion made the unfade hack be totally useless, I think.)
-
-            We put the event back so that the calling code can notice it too.
-            It would be better to not remove it at all, but that's harder
-            because Xlib has such a non-design for this kind of crap, and
-            in this application it doesn't matter if the events end up out
-            of order, so in the grand unix tradition we say "fuck it" and
-            do something that mostly works for the time being.
-          */
-         if (XCheckMaskEvent (dpy, (KeyPressMask|ButtonPressMask),
-                              &dummy_event))
-           {
-             XPutBackEvent (dpy, &dummy_event);
-             goto DONE;
-           }
-
-#ifdef GETTIMEOFDAY_TWO_ARGS
-         gettimeofday(&now, &tzp);
-#else
-         gettimeofday(&now);
-#endif
-
-         /* If we haven't already used up our alotted time, sleep to avoid
-            changing the colormap too fast. */
-         {
-           long diff = (((now.tv_sec - then.tv_sec) * 1000000) +
-                        now.tv_usec - then.tv_usec);
-           then.tv_sec = now.tv_sec;
-           then.tv_usec = now.tv_usec;
-           if (usecs_per_step > diff)
-             usleep (usecs_per_step - diff);
-         }
-       }
-    }
-  
-
- DONE:
-
-  if (out_p && black_windows)
-    {
-      for (screen = 0; screen < nscreens; screen++)
-       {
-         if (clear_windows)
-           XClearWindow (dpy, black_windows[screen]);
-         XMapRaised (dpy, black_windows[screen]);
-       }
-      XSync(dpy, False);
-    }
-
-  /* I can't explain this; without this delay, we get a flicker.
-     I suppose there's some lossage with stale bits being in the
-     hardware frame buffer or something, and this delay gives it
-     time to flush out.  This sucks! */
-  usleep(100000);  /* 1/10th second */
-
-  for (screen = 0; screen < nscreens; screen++)
-    whack_gamma(dpy, screen, &info[screen], 1.0);
-  XSync(dpy, False);
-
-  status = 0;
-
- FAIL:
-  for (screen = 0; screen < nscreens; screen++)
-    {
-      if (info[screen].red1)   free (info[screen].red1);
-      if (info[screen].green1) free (info[screen].green1);
-      if (info[screen].blue1)  free (info[screen].blue1);
-      if (info[screen].red2)   free (info[screen].red2);
-      if (info[screen].green2) free (info[screen].green2);
-      if (info[screen].blue2)  free (info[screen].blue2);
-    }
-  free(info);
-
-  return status;
-}
-
-static void
-whack_gamma(Display *dpy, int screen, struct screen_gamma_info *info,
-           float ratio)
-{
-  int k;
-
-  if (ratio < 0) ratio = 0;
-  if (ratio > 1) ratio = 1;
-  for (k = 0; k < info->gamma_size; k++)
-    {
-      info->red2[k]   = info->red1[k]   * ratio;
-      info->green2[k] = info->green1[k] * ratio;
-      info->blue2[k]  = info->blue1[k]  * ratio;
-    }
-
-  XSGIvcStoreGammaColors16(dpy, screen, info->gamma_map, info->nred,
-                          XSGIVC_MComponentRed, info->red2);
-  XSGIvcStoreGammaColors16(dpy, screen, info->gamma_map, info->ngreen,
-                          XSGIVC_MComponentGreen, info->green2);
-  XSGIvcStoreGammaColors16(dpy, screen, info->gamma_map, info->nblue,
-                          XSGIVC_MComponentBlue, info->blue2);
-  XSync(dpy, False);
-}
-
-#endif /* HAVE_SGI_VC_EXTENSION */
-
-
-
-\f
-#if 0
-#include "screenhack.h"
-
-char *progclass = "foo";
-char *defaults [] = {
-  0
-};
-
-XrmOptionDescRec options [] = {0};
-int options_size = 0;
-
-void
-screenhack (dpy, w)
-     Display *dpy;
-     Window w;
-{
-  int seconds = 3;
-  int ticks = 20;
-  int delay = 1;
-
-  while (1)
-    {
-      XSync (dpy, False);
-
-      fprintf(stderr,"out..."); fflush(stderr);
-      fade_screens (dpy, 0, seconds, ticks, True);
-      fprintf(stderr, "done.\n"); fflush(stderr);
-
-      if (delay) sleep (delay);
-
-      fprintf(stderr,"in..."); fflush(stderr);
-      fade_screens (dpy, 0, seconds, ticks, False);
-      fprintf(stderr, "done.\n"); fflush(stderr);
-
-      if (delay) sleep (delay);
-    }
-}
-
-#endif