http://x.cybermirror.org/R5contrib/xscreensaver-1.21.tar.Z
[xscreensaver] / utils / fade.c
1 /* xscreensaver, Copyright (c) 1992 Jamie Zawinski <jwz@lucid.com>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or 
9  * implied warranty.
10  */
11
12 #if __STDC__
13 # include <stdlib.h>
14 #endif
15
16 #include <stdio.h>
17 #include <X11/Xlib.h>
18 #include <X11/Xos.h>
19
20 extern void screenhack_usleep ();
21 #define usleep screenhack_usleep
22
23 #define MAX_COLORS 4096
24 static XColor orig_colors [MAX_COLORS];
25 static XColor current_colors [MAX_COLORS];
26 static int ncolors;
27
28 Colormap
29 copy_colormap (dpy, cmap, into_cmap)
30      Display *dpy;
31      Colormap cmap, into_cmap;
32 {
33   int i;
34   ncolors = CellsOfScreen (DefaultScreenOfDisplay (dpy));
35   if (ncolors <= 2 || ncolors > MAX_COLORS)
36     return 0;
37   if (! into_cmap)
38     into_cmap = XCreateColormap (dpy, RootWindow (dpy, DefaultScreen (dpy)),
39                                  DefaultVisual (dpy, DefaultScreen (dpy)),
40                                  AllocAll);
41   if (! cmap)
42     cmap = DefaultColormap (dpy, DefaultScreen (dpy));
43   for (i = 0; i < ncolors; i++)
44     orig_colors [i].pixel = i;
45   XQueryColors (dpy, cmap, orig_colors, ncolors);
46   XStoreColors (dpy, into_cmap, orig_colors, ncolors);
47   return into_cmap;
48 }
49
50 void
51 blacken_colormap (dpy, cmap)
52      Display *dpy;
53      Colormap cmap;
54 {
55   int i;
56   for (i = 0; i < ncolors; i++)
57     {
58       current_colors [i].pixel = i;
59       current_colors [i].red = current_colors [i].green =
60         current_colors [i].blue = 0;
61     }
62   XStoreColors (dpy, cmap, current_colors, ncolors);
63 }
64
65
66 void
67 fade_colormap (dpy, cmap, cmap2, seconds, ticks, out_p)
68      Display *dpy;
69      Colormap cmap, cmap2;
70      int seconds, ticks;
71      Bool out_p;
72 {
73   int i;
74   int steps = seconds * ticks;
75   XEvent dummy_event;
76
77   if (! cmap2)
78     return;
79
80   for (i = 0; i < ncolors; i++)
81     orig_colors [i].pixel = i;
82   XQueryColors (dpy, cmap, orig_colors, ncolors);
83   memcpy (current_colors, orig_colors, ncolors * sizeof (XColor));
84
85   for (i = (out_p ? steps : 0);
86        (out_p ? i > 0 : i < steps);
87        (out_p ? i-- : i++))
88     {
89       int j;
90       for (j = 0; j < ncolors; j++)
91         {
92           current_colors[j].red   = orig_colors[j].red   * i / steps;
93           current_colors[j].green = orig_colors[j].green * i / steps;
94           current_colors[j].blue  = orig_colors[j].blue  * i / steps;
95         }
96       XStoreColors (dpy, cmap2, current_colors, ncolors);
97       XSync (dpy, False);
98
99       /* If there is user activity, bug out.
100          We put the event back so that the calling code can notice it too.
101          It would be better to not remove it at all, but that's harder
102          because Xlib has such a non-design for this kind of crap, and
103          in this application it doesn't matter if the events end up out
104          of order, so in the grand unix tradition we say "fuck it" and
105          do something that mostly works for the time being.
106        */
107       if (XCheckMaskEvent (dpy, (KeyPressMask | KeyReleaseMask |
108                                  ButtonPressMask | ButtonReleaseMask |
109                                  PointerMotionMask),
110                            &dummy_event))
111         {
112           XPutBackEvent (dpy, &dummy_event);
113           return;
114         }
115
116       usleep (1000000 / (ticks * 2)); /* the 2 is a hack... */
117     }
118 }
119
120 #if 0
121
122 \f
123 char *progclass = "foo";
124
125 char *defaults [] = {
126   0
127 };
128
129 XrmOptionDescRec options [] = {0};
130 int options_size = 0;
131
132 void
133 screenhack (dpy, w)
134      Display *dpy;
135      Window w;
136 {
137   Colormap cmap = DefaultColormap (dpy, DefaultScreen (dpy));
138   Colormap cmap2 = copy_colormap (dpy, cmap, 0);
139
140   int seconds = 1;
141   int ticks = 30 * seconds;
142   int delay = 1;
143
144   while (1)
145     {
146       XSync (dpy, False);
147       XGrabServer (dpy);
148       XInstallColormap (dpy, cmap2);
149       fade_colormap (dpy, cmap, cmap2, seconds, ticks, True);
150       if (delay) sleep (delay);
151       fade_colormap (dpy, cmap, cmap2, seconds, ticks, False);
152       XInstallColormap (dpy, cmap);
153       XUngrabServer (dpy);
154       XSync (dpy, False);
155       if (delay) sleep (delay);
156     }
157 }
158
159 #endif