http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.01.tar.gz
[xscreensaver] / hacks / fadeplot.c
1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* fadeplot --- a fading plot of sine squared */
3
4 #if !defined( lint ) && !defined( SABER )
5 static const char sccsid[] = "@(#)fadeplot.c    5.00 2000/11/01 xlockmore";
6
7 #endif
8
9 /*-
10  * Some easy plotting stuff, by Bas van Gaalen, Holland, PD
11  *
12  * Copyright (c) 1996 by Charles Vidal
13  *
14  * Permission to use, copy, modify, and distribute this software and its
15  * documentation for any purpose and without fee is hereby granted,
16  * provided that the above copyright notice appear in all copies and that
17  * both that copyright notice and this permission notice appear in
18  * supporting documentation.
19  *
20  * This file is provided AS IS with no warranties of any kind.  The author
21  * shall have no liability with respect to the infringement of copyrights,
22  * trade secrets or any patents by this file or any part thereof.  In no
23  * event will the author be liable for any lost revenue or profits or
24  * other special, indirect and consequential damages.
25  *
26  * Revision History:
27  * 01-Nov-2000: Allocation checks
28  * 10-May-1997: Compatible with screensaver
29  * 1996: Written by Charles Vidal based on work by Bas van Gaalen
30  */
31
32 #ifdef STANDALONE
33 #define MODE_fadeplot
34 #define PROGCLASS "Fadeplot"
35 #define HACK_INIT init_fadeplot
36 #define HACK_DRAW draw_fadeplot
37 #define fadeplot_opts xlockmore_opts
38 #define DEFAULTS "*delay: 30000 \n" \
39  "*count: 10 \n" \
40  "*cycles: 1500 \n" \
41  "*ncolors: 64 \n"
42 #define BRIGHT_COLORS
43 #define UNIFORM_COLORS
44 #include "xlockmore.h"          /* in xscreensaver distribution */
45 #else /* STANDALONE */
46 #include "xlock.h"              /* in xlockmore distribution */
47
48 #endif /* STANDALONE */
49
50 #ifdef MODE_fadeplot
51
52 ModeSpecOpt fadeplot_opts =
53 {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
54
55 #ifdef USE_MODULES
56 ModStruct   fadeplot_description =
57 {"fadeplot", "init_fadeplot", "draw_fadeplot", "release_fadeplot",
58  "refresh_fadeplot", "init_fadeplot", (char *) NULL, &fadeplot_opts,
59  30000, 10, 1500, 1, 64, 0.6, "",
60  "Shows a fading plot of sine squared", 0, NULL};
61
62 #endif
63
64 #define MINSTEPS 1
65
66 typedef struct {
67         XPoint      speed, step, factor, st;
68         int         temps, maxpts, nbstep;
69         int         min;
70         int         width, height;
71         int         pix;
72         int         angles;
73         int        *stab;
74         XPoint     *pts;
75 } fadeplotstruct;
76
77 static fadeplotstruct *fadeplots = (fadeplotstruct *) NULL;
78
79 static void
80 free_fadeplot(fadeplotstruct *fp)
81 {
82         if (fp->pts != NULL) {
83                 (void) free((void *) fp->pts);
84                 fp->pts = (XPoint *) NULL;
85         }
86         if (fp->stab != NULL) {
87                 (void) free((void *) fp->stab);
88                 fp->stab = (int *) NULL;
89         }
90 }
91
92 static Bool
93 initSintab(ModeInfo * mi)
94 {
95         fadeplotstruct *fp = &fadeplots[MI_SCREEN(mi)];
96         int         i;
97         float       x;
98
99         fp->angles = NRAND(950) + 250;
100         if ((fp->stab = (int *) malloc(fp->angles * sizeof (int))) == NULL) {
101                 free_fadeplot(fp);
102                 return False;
103         }
104         for (i = 0; i < fp->angles; i++) {
105                 x = SINF(2.0 * M_PI * i / fp->angles);
106                 fp->stab[i] = (int) (x * ABS(x) * fp->min) + fp->min;
107         }
108         return True;
109 }
110
111 void
112 init_fadeplot(ModeInfo * mi)
113 {
114         fadeplotstruct *fp;
115
116         if (fadeplots == NULL) {
117                 if ((fadeplots = (fadeplotstruct *) calloc(MI_NUM_SCREENS(mi),
118                                            sizeof (fadeplotstruct))) == NULL)
119                         return;
120         }
121         fp = &fadeplots[MI_SCREEN(mi)];
122
123         fp->width = MI_WIDTH(mi);
124         fp->height = MI_HEIGHT(mi);
125         fp->min = MAX(MIN(fp->width, fp->height) / 2, 1);
126
127         fp->speed.x = 8;
128         fp->speed.y = 10;
129         fp->step.x = 1;
130         fp->step.y = 1;
131         fp->temps = 0;
132         fp->factor.x = MAX(fp->width / (2 * fp->min), 1);
133         fp->factor.y = MAX(fp->height / (2 * fp->min), 1);
134
135         fp->nbstep = MI_COUNT(mi);
136         if (fp->nbstep < -MINSTEPS) {
137                 fp->nbstep = NRAND(-fp->nbstep - MINSTEPS + 1) + MINSTEPS;
138         } else if (fp->nbstep < MINSTEPS)
139                 fp->nbstep = MINSTEPS;
140
141         fp->maxpts = MI_CYCLES(mi);
142         if (fp->maxpts < 1)
143                 fp->maxpts = 1;
144
145         if (fp->pts == NULL) {
146                 if ((fp->pts = (XPoint *) calloc(fp->maxpts, sizeof (XPoint))) ==
147                                  NULL) {
148                         free_fadeplot(fp);
149                         return;
150                 }
151         }
152         if (MI_NPIXELS(mi) > 2)
153                 fp->pix = NRAND(MI_NPIXELS(mi));
154
155         if (fp->stab != NULL)
156                 (void) free((void *) fp->stab);
157         if (!initSintab(mi))
158                 return;
159         MI_CLEARWINDOW(mi);
160 }
161
162 void
163 draw_fadeplot(ModeInfo * mi)
164 {
165         Display    *display = MI_DISPLAY(mi);
166         Window      window = MI_WINDOW(mi);
167         GC          gc = MI_GC(mi);
168         int         i, j, temp;
169         fadeplotstruct *fp;
170
171         if (fadeplots == NULL)
172                 return;
173         fp = &fadeplots[MI_SCREEN(mi)];
174         if (fp->stab == NULL)
175                 return;
176
177         MI_IS_DRAWN(mi) = True;
178         XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
179         XDrawPoints(display, window, gc, fp->pts, fp->maxpts, CoordModeOrigin);
180
181         if (MI_NPIXELS(mi) > 2) {
182                 XSetForeground(display, gc, MI_PIXEL(mi, fp->pix));
183                 if (++fp->pix >= MI_NPIXELS(mi))
184                         fp->pix = 0;
185         } else
186                 XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
187
188         temp = 0;
189         for (j = 0; j < fp->nbstep; j++) {
190                 for (i = 0; i < fp->maxpts / fp->nbstep; i++) {
191                         fp->pts[temp].x =
192                                 fp->stab[(fp->st.x + fp->speed.x * j + i * fp->step.x) % fp->angles] *
193                                 fp->factor.x + fp->width / 2 - fp->min;
194                         fp->pts[temp].y =
195                                 fp->stab[(fp->st.y + fp->speed.y * j + i * fp->step.y) % fp->angles] *
196                                 fp->factor.y + fp->height / 2 - fp->min;
197                         temp++;
198                 }
199         }
200         XDrawPoints(display, window, gc, fp->pts, temp, CoordModeOrigin);
201         XFlush(display);
202         fp->st.x = (fp->st.x + fp->speed.x) % fp->angles;
203         fp->st.y = (fp->st.y + fp->speed.y) % fp->angles;
204         fp->temps++;
205         if ((fp->temps % (fp->angles / 2)) == 0) {
206                 fp->temps = fp->temps % fp->angles * 5;
207                 if ((fp->temps % (fp->angles)) == 0)
208                         fp->speed.y = (fp->speed.y++) % 30 + 1;
209                 if ((fp->temps % (fp->angles * 2)) == 0)
210                         fp->speed.x = (fp->speed.x) % 20;
211                 if ((fp->temps % (fp->angles * 3)) == 0)
212                         fp->step.y = (fp->step.y++) % 2 + 1;
213
214                 MI_CLEARWINDOW(mi);
215         }
216 }
217 void
218 refresh_fadeplot(ModeInfo * mi)
219 {
220         MI_CLEARWINDOW(mi);
221 }
222
223 void
224 release_fadeplot(ModeInfo * mi)
225 {
226         if (fadeplots != NULL) {
227                 int         screen;
228
229                 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
230                         free_fadeplot(&fadeplots[screen]);
231                 (void) free((void *) fadeplots);
232                 fadeplots = (fadeplotstruct *) NULL;
233         }
234 }
235
236 #endif /* MODE_fadeplot */