1 /* Whirlygig -- an experiment in X programming
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
11 * When I was in trigonometry class as a kid, I remember being fascinated
12 * by the beauty of the shapes one receives when playing with sine waves
13 * Here is a little experiment to show that beauty is simple
16 #include "screenhack.h"
19 static XColor colors[1000];
20 static int ncolors = 1000;
21 static int current_color = 0;
24 draw_dot(Display *dpy,
29 int origin_x, int origin_y,
30 int screen_num, double xspeed, double yspeed,
31 int whirlies, int nlines)
33 int size, last_size; /* The size of my dot */
34 int start_arc = 0; /* Start my circle at 0 degrees */
35 int end_arc = 23040; /* The number of degrees in a X circle (360 * 64) */
36 int horiz, vert; /* These will contain the new x,y coordinates to put my dot */
37 int last_horiz ,last_vert; /* These contain the positions to black out */
39 int count, line_count;
40 int line_offset, last_line_offset;
42 XWindowAttributes xgwa;
43 XGetWindowAttributes (dpy, window, &xgwa);
44 if (++current_color >= ncolors)
46 for (count = 0; count < whirlies; count++) {
47 color_offset = (current_color + (10 * count )) % ncolors;
48 if (current_time == count) {
49 last_time = current_time;
52 current_time = current_time + count;
53 last_time = current_time - 1;
55 last_horiz = compute_x(last_time, origin_x, xspeed);
56 last_vert = compute_y(last_time, origin_y, yspeed);
57 horiz = compute_x(current_time, origin_x, xspeed);
58 vert = compute_y(current_time, origin_y, yspeed);
59 for (line_count = 0; line_count < nlines; line_count++) {
60 last_line_offset = (int)(80.0 * line_count * sin((double)last_time / 90));
61 line_offset = (int)(80.0 * line_count * sin((double)current_time / 90));
62 last_size = (int)(15.0 + 5.0 * sin((double)last_time / 180.0));
63 size = (int)(15.0 + 5.0 * sin((double)current_time / 180.0));
64 /* Get rid of the old circle */
65 XSetForeground(dpy, bgc, BlackPixel(dpy, screen_num));
66 XFillArc(dpy, window, bgc, last_horiz, last_line_offset+last_vert, last_size, last_size, start_arc, end_arc);
67 /* Draw in the new circle */
68 XSetForeground(dpy, bgc, colors[color_offset].pixel);
69 XFillArc(dpy, window, bgc, horiz, line_offset+vert, size, size, start_arc, end_arc);
73 if (current_time == 23040)
83 int compute_x(int the_time, int origin, double xspeed)
85 double funky = (((the_time % 360) * 1.0) / 180.0) * M_PI;
86 double the_cosine = cos((double)the_time / (180.0 * xspeed));
87 double dist_mod_x = cos((double)funky) * (origin - 50);
88 int horiz_pos = origin + (the_cosine * dist_mod_x);
92 int compute_y(int the_time, int origin, double yspeed)
94 double funky = (((the_time % 360) * 1.0) / 180.0) * M_PI;
95 double the_sine = sin((double)the_time / (180.0 * yspeed));
96 double dist_mod_y = sin((double)funky) * (origin - 50);
97 int vert_pos = origin + (the_sine * dist_mod_y);
101 char *progclass = "Whirlygig";
103 char *defaults [] = {
104 ".background: black",
105 ".foreground: white",
113 XrmOptionDescRec options [] = {
114 { "-xspeed", ".xspeed", XrmoptionSepArg, 0 },
115 { "-yspeed", ".yspeed", XrmoptionSepArg, 0 },
116 { "-whirlies", ".whirlies",XrmoptionSepArg, 0 },
117 { "-nlines", ".nlines",XrmoptionSepArg, 0 },
121 void screenhack (Display *dpy, Window window)
123 GC fgc, bgc; /* the foreground and background graphics contexts */
124 XGCValues gcv; /* The structure to hold the GC data */
125 XWindowAttributes xgwa; /* A structure to hold window data */
126 Bool writable = get_boolean_resource ("cycle", "Boolean");
127 double xspeed = get_float_resource( "xspeed", "Float");
128 double yspeed = get_float_resource( "yspeed", "Float");
129 int whirlies = get_integer_resource( "whirlies", "Integer");
130 int nlines = get_integer_resource( "nlines", "Integer");
131 int time_counter = 0; /* This will be incremented in my while loop so that I can move my circle */
132 int screen_num = DefaultScreen(dpy);
133 int half_width, half_height;
134 XGetWindowAttributes (dpy, window, &xgwa);
136 half_width = xgwa.width / 2;
137 half_height = xgwa.height / 2;
139 gcv.foreground = get_pixel_resource("foreground", "Foreground", dpy, xgwa.colormap);
140 fgc = XCreateGC (dpy, window, GCForeground, &gcv);
141 gcv.foreground = get_pixel_resource("background", "Background", dpy, xgwa.colormap);
142 bgc = XCreateGC (dpy, window, GCForeground, &gcv);
143 make_uniform_colormap (dpy, xgwa.visual, xgwa.colormap,
145 True, &writable, True);
156 /* draw_dot will return an interger. If this interger is 0, then continue incrementing
157 time_counter, if it is 1, then reset it to zero... It should only become 1 with the sine
158 is 0 and the cosine is 1 */
159 if (draw_dot(dpy, window, xgwa.colormap, fgc, bgc, time_counter, half_width, half_height, screen_num, xspeed , yspeed, whirlies, nlines) == 1) {
165 screenhack_handle_events (dpy);