1 /* xscreensaver, Copyright (c) 1992 Jamie Zawinski <jwz@mcom.com>
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
12 #include "screenhack.h"
15 #define M_PI 3.14159265358979323846
18 #include <math.h> /* for M_PI */
21 static double sins [360];
22 static double coss [360];
24 static GC draw_gc, erase_gc;
25 static unsigned int default_fg_pixel;
28 init_helix (dpy, window)
34 XWindowAttributes xgwa;
36 XGetWindowAttributes (dpy, window, &xgwa);
38 gcv.foreground = default_fg_pixel =
39 get_pixel_resource ("foreground", "Foreground", dpy, cmap);
40 draw_gc = XCreateGC (dpy, window, GCForeground, &gcv);
41 gcv.foreground = get_pixel_resource ("background", "Background", dpy, cmap);
42 erase_gc = XCreateGC (dpy, window, GCForeground, &gcv);
44 for (i = 0; i < 360; i++)
46 sins [i] = sin ((((double) i) / 180.0) * M_PI);
47 coss [i] = cos ((((double) i) / 180.0) * M_PI);
62 return (a < 0 ? -a : a);
67 radius1, radius2, d_angle,
68 factor1, factor2, factor3, factor4)
71 int radius1, radius2, d_angle;
72 int factor1, factor2, factor3, factor4;
74 XWindowAttributes xgwa;
77 int x1, y1, x2, y2, angle, limit;
80 XClearWindow (dpy, window);
81 XGetWindowAttributes (dpy, window, &xgwa);
92 limit = 1 + (360 / gcd (360, d_angle));
94 for (i = 0; i < limit; i++)
97 #define pmod(x,y) (tmp = (x % y), (tmp >= 0 ? tmp : tmp + y))
98 x1 = xmid + (((double) radius1) * sins [pmod ((angle * factor1), 360)]);
99 y1 = ymid + (((double) radius2) * coss [pmod ((angle * factor2), 360)]);
100 XDrawLine (dpy, window, draw_gc, x1, y1, x2, y2);
101 x2 = xmid + (((double) radius2) * sins [pmod ((angle * factor3), 360)]);
102 y2 = ymid + (((double) radius1) * coss [pmod ((angle * factor4), 360)]);
103 XDrawLine (dpy, window, draw_gc, x1, y1, x2, y2);
109 #define min(a,b) ((a)<(b)?(a):(b))
112 random_helix (dpy, window)
118 int radius, radius1, radius2, d_angle, factor1, factor2, factor3, factor4;
121 int i, got_color = 0;
122 XWindowAttributes xgwa;
123 XGetWindowAttributes (dpy, window, &xgwa);
125 height = xgwa.height;
126 cmap = xgwa.colormap;
128 radius = min (width, height) / 2;
136 divisor = ((frand (3.0) + 1) * (((random() & 1) * 2) - 1));
138 if ((random () & 1) == 0)
141 radius2 = radius / divisor;
146 radius1 = radius / divisor;
149 while (gcd (360, d_angle) >= 2)
150 d_angle = random () % 360;
152 #define random_factor() \
153 (((random() % 7) ? ((random() & 1) + 1) : 3) \
154 * (((random() & 1) * 2) - 1))
156 while (gcd (gcd (gcd (factor1, factor2), factor3), factor4) != 1)
158 factor1 = random_factor ();
159 factor2 = random_factor ();
160 factor3 = random_factor ();
161 factor4 = random_factor ();
165 XSetForeground (dpy, draw_gc, default_fg_pixel);
168 hsv_to_rgb (random () % 360, frand (1.0), frand (0.5) + 0.5,
169 &color.red, &color.green, &color.blue);
170 if ((got_color = XAllocColor (dpy, cmap, &color)))
171 XSetForeground (dpy, draw_gc, color.pixel);
173 XSetForeground (dpy, draw_gc, default_fg_pixel);
175 helix (dpy, window, radius1, radius2, d_angle,
176 factor1, factor2, factor3, factor4);
181 for (i = 0; i < height; i++)
183 int y = (random () % height);
184 XDrawLine (dpy, window, erase_gc, 0, y, width, y);
189 XClearWindow (dpy, window);
190 if (got_color) XFreeColors (dpy, cmap, &color.pixel, 1, 0);
196 char *progclass = "Helix";
198 char *defaults [] = {
199 "Helix.background: black", /* to placate SGI */
203 XrmOptionDescRec options [] = { 0 };
204 int options_size = 0;
207 screenhack (dpy, window)
211 init_helix (dpy, window);
213 random_helix (dpy, window);