* by the beauty of the shapes one receives when playing with sine waves
* Here is a little experiment to show that beauty is simple
*/
+
#include <stdio.h>
#include <math.h>
#include "screenhack.h"
-#define NCOLORS 1000
+#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
+# include "xdbe.h"
+#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+
+#define NCOLORS 100
#define FULL_CYCLE 429496729
#define START_ARC 0
#define END_ARC 23040
struct info {
- Bool writable; /* Is the screen writable */
- double xspeed; /* A factor to modify the horizontal movement */
- double yspeed; /* A factor to modify vertical movement */
- double xamplitude;
- double yamplitude;
- int whirlies; /* How many whirlies per line do you want? */
- int nlines; /* How many lines of whirlies do you want? */
- int half_width; /* 1/2 the width of the screen */
- int half_height;
- int speed;
- int trail;
- int color_modifier;
- double xoffset;
- double yoffset;
- double offset_period;
- int wrap;
+/* Bool writable; / * Is the screen writable */
+ double xspeed; /* A factor to modify the horizontal movement */
+ double yspeed; /* A factor to modify vertical movement */
+ double xamplitude;
+ double yamplitude;
+ int whirlies; /* How many whirlies per line do you want? */
+ int nlines; /* How many lines of whirlies do you want? */
+ int half_width; /* 1/2 the width of the screen */
+ int half_height;
+ int speed;
+ int trail;
+ int color_modifier;
+ double xoffset;
+ double yoffset;
+ double offset_period;
+ Bool wrap;
};
enum object_mode {
spin_mode, funky_mode, circle_mode, linear_mode, test_mode, fun_mode, innie_mode, lissajous_mode
-} mode;
+};
-static void explain(int, struct info *, Display *, Window, GC);
+struct state {
+ Display *dpy;
+ Window window;
-static void spin(unsigned long int, struct info *, int *, int);
-static void funky(unsigned long int, struct info *, int *, int);
-static void circle(unsigned long int, struct info *, int *, int);
-static void fun(unsigned long int, struct info *, int *, int);
-static void linear(unsigned long int, struct info *, int *, int);
-static void lissajous(unsigned long int, struct info *, int *, int);
-static void test(unsigned long int, struct info *, int *, int);
-static void innie(unsigned long int, struct info *, int *, int, double);
+ XGCValues gcv; /* The structure to hold the GC data */
+ XWindowAttributes xgwa; /* A structure to hold window data */
+ Pixmap b, ba; /* double-buffer to reduce flicker */
+#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
+ Bool dbeclear_p;
+ XdbeBackBuffer backb;
+#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+ GC fgc, bgc;
+ int screen;
+ Bool dbuf;
+ unsigned long int current_time; /* The global int telling the current time */
+ unsigned long int start_time;
+ struct info *info;
+ char *xmode_str, *ymode_str; /* holds the current mode for x and y computation */
-XColor colors[NCOLORS];
-int ncolors = NCOLORS;
-char *progclass = "Whirlygig";
+ /* pos is the current position x,y -- last_x contains one cell of
+ every x coordinate for every position of every whirly in every
+ line up to 100 whirlies in 100 lines -- lasy_y and last_size hold
+ the same information for y and size respectively */
-char *defaults [] = {
- ".background: black",
- ".foreground: white",
- "*xspeed: 1.0",
- "*yspeed: 1.0",
- "*xamplitude: 1.0",
- "*yamplitude: 1.0",
- "*whirlies: -1",
- "*nlines: -1",
- "*xmode: change",
- "*ymode: change",
- "*speed: 1",
- "*trail: 0",
- "*color_modifier: -1",
- "*start_time: -1",
- "*explain: 0",
- "*xoffset: 1.0",
- "*yoffset: 1.0",
- "*offset_period: 1",
- "*wrap: 0",
- 0
-};
+ int pos[2], last_x[100][100], last_y[100][100], last_size[100][100];
+ int current_color;
+ Bool wrap;
+ int xmode, ymode;
+ double modifier; /* for innie */
-XrmOptionDescRec options [] = {
- { "-xspeed", ".xspeed", XrmoptionSepArg, 0 },
- /* xspeed is a modifier of the argument to cos -- changing it thus
- changes the frequency of cos */
- { "-yspeed", ".yspeed", XrmoptionSepArg, 0 },
- /* Similiarly, yspeed changes the frequency of sin */
- { "-xamplitude", ".xamplitude", XrmoptionSepArg, 0 },
- /* A factor by which to increase/decrease the amplitude of the sin */
- { "-yamplitude", ".yamplitude", XrmoptionSepArg, 0 },
- /* A factor by which to increase/decrease the amplitude of the cos */
- { "-whirlies", ".whirlies",XrmoptionSepArg, 0 },
- /* whirlies defines the number of circles to draw per line */
- { "-nlines", ".nlines",XrmoptionSepArg, 0 },
- /* nlines is the number of lines of whirlies to draw */
- { "-xmode", ".xmode", XrmoptionSepArg, 0 },
- /* There are a few different modes that I have written -- each mode
- is in theory a different experiment with the possible modifiers to sin/cos */
- { "-ymode", ".ymode", XrmoptionSepArg, 0 },
- { "-speed", ".speed", XrmoptionSepArg, 0 },
- /* This will modify how often it should draw, changing it will probably suck */
- { "-trail", ".trail", XrmoptionSepArg, 0 },
- /* Control whether or not you want the old circles to be erased */
- { "-color_modifier", ".color_modifier", XrmoptionSepArg, 0 },
- /* How many colors away from the current should the next whirly be? */
- { "-start_time", ".start_time", XrmoptionSepArg, 0 },
- /* Specify exactly at what time to start graphing... */
- { "-xoffset", ".xoffset", XrmoptionSepArg, 0 },
- /* Tell the whirlies to be offset by this factor of a sin */
- { "-yoffset", ".yoffset", XrmoptionSepArg, 0 },
- /* Tell the whirlies to be offset by this factor of a cos */
- { "-offset_period", ".offset_period", XrmoptionSepArg, 0 },
- /* Change the period of an offset cycle */
- { "-explain", ".explain", XrmoptionSepArg, 0 },
- /* Specify whether or not to print an explanation of the function used. */
- { "-wrap", ".wrap", XrmoptionSepArg, 0 },
- /* Specify if you want whirlies which are out of the boundary of the screen to be
- wrapped around to the other side */
- { 0, 0, 0, 0 }
+ XColor colors[NCOLORS];
+ int ncolors;
+ int explaining;
};
+static void draw_explain_string(struct state *, int, int, Display *, Window, GC);
+static void spin(struct state *, unsigned long int, struct info *, int *, int);
+static void funky(struct state *, unsigned long int, struct info *, int *, int);
+static void circle(struct state *, unsigned long int, struct info *, int *, int);
+static void fun(struct state *, unsigned long int, struct info *, int *, int);
+static void linear(struct state *, unsigned long int, struct info *, int *, int);
+static void lissajous(struct state *, unsigned long int, struct info *, int *, int);
+static void test(struct state *, unsigned long int, struct info *, int *, int);
+static void innie(struct state *, unsigned long int, struct info *, int *, int, double);
-static const char funky_explanation[] =
-"Funky mode is me goofing off.";
-static const char test_explanation[] =
-"Test mode is a mode that I play around with ideas in.";
static const char spin_explanation[] =
"Spin mode is a simple sin/cos with every argument modified";
+static const char funky_explanation[] =
+"Funky mode is me goofing off.";
+
static const char circle_explanation[] =
"Circle mode graphs the x and y positions as you trace the edge of a circle over time.";
+static const char linear_explanation[] =
+"Linear mode draws a straight line";
+
+static const char test_explanation[] =
+"Test mode is a mode that I play around with ideas in.";
+
static const char fun_explanation[] =
"Fun mode is the coolest.";
-static const char linear_explanation[] =
-"I draw a straight line -- woo hoo";
+static const char innie_explanation[] =
+"Innie mode does something or other. Looks cool, though.";
static const char lissajous_explanation[] =
-"This draws a slightly modified lissajous curve";
+"Lissajous mode draws a slightly modified lissajous curve";
static void
-explain(int mode, struct info *info, Display *display, Window window, GC fgc)
+draw_explain_string(struct state *st, int mode, int offset, Display *dpy, Window window, GC fgc)
{
- XClearWindow(display, window);
- switch(mode) {
- case spin_mode:
- XDrawString(display, window, fgc, 50, info->half_height-100, spin_explanation, strlen(spin_explanation));
- break;
- case funky_mode:
- XDrawString(display, window, fgc, 50, info->half_height-100, funky_explanation, strlen(funky_explanation));
- break;
- case circle_mode:
- XDrawString(display, window, fgc, 50, info->half_height-100, circle_explanation, strlen(circle_explanation));
- break;
- case fun_mode:
- XDrawString(display, window, fgc, 50, info->half_height-100, fun_explanation, strlen(fun_explanation));
- break;
- case linear_mode:
- XDrawString(display, window, fgc, 50, info->half_height-100, linear_explanation, strlen(linear_explanation));
- break;
- case lissajous_mode:
- XDrawString(display, window, fgc, 50, info->half_height-100, lissajous_explanation, strlen(linear_explanation));
-
- }
- XSync(display, False);
- sleep(3);
- XClearWindow(display, window);
+ switch(mode) {
+ case spin_mode:
+ XDrawString(st->dpy, st->window, st->fgc, 50, offset,
+ (char*) spin_explanation, strlen(spin_explanation));
+ break;
+ case funky_mode:
+ XDrawString(st->dpy, st->window, st->fgc, 50, offset,
+ (char*) funky_explanation, strlen(funky_explanation));
+ break;
+ case circle_mode:
+ XDrawString(st->dpy, st->window, st->fgc, 50, offset,
+ (char*) circle_explanation, strlen(circle_explanation));
+ break;
+ case linear_mode:
+ XDrawString(st->dpy, st->window, st->fgc, 50, offset,
+ (char*) linear_explanation, strlen(linear_explanation));
+ break;
+ case test_mode:
+ XDrawString(st->dpy, st->window, st->fgc, 50, offset,
+ (char*) test_explanation, strlen(test_explanation));
+ break;
+ case fun_mode:
+ XDrawString(st->dpy, st->window, st->fgc, 50, offset,
+ (char*) fun_explanation, strlen(fun_explanation));
+ break;
+ case innie_mode:
+ XDrawString(st->dpy, st->window, st->fgc, 50, offset,
+ (char*) innie_explanation, strlen(innie_explanation));
+ break;
+ case lissajous_mode:
+ XDrawString(st->dpy, st->window, st->fgc, 50, offset,
+ (char*) lissajous_explanation, strlen(linear_explanation));
+ }
}
static void
-funky(unsigned long int the_time, struct info *info, int pos[], int index)
+funky(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
{
double new_time = ((the_time % 360 ) / 180.0) * M_PI;
if (index == 0) {
double time_modifier = cos(new_time / 180.0);
- double the_cos = cos((new_time * (double)info->xspeed) + (time_modifier * 80.0));
- double dist_mod_x = cos(new_time) * (info->half_width - 50);
- pos[index]= info->xamplitude * (the_cos * dist_mod_x) + info->half_width;
+ double the_cos = cos((new_time * (double)st->info->xspeed) + (time_modifier * 80.0));
+ double dist_mod_x = cos(new_time) * (st->info->half_width - 50);
+ st->pos[index]= st->info->xamplitude * (the_cos * dist_mod_x) + st->info->half_width;
}
else {
double new_time = ((the_time % 360 ) / 180.0) * M_PI;
double time_modifier = sin(new_time / 180.0);
- double the_sin = sin((new_time * (double)info->yspeed) + (time_modifier * 80.0));
- double dist_mod_y = sin(new_time) * (info->half_height - 50);
- pos[index] = info->yamplitude * (the_sin * dist_mod_y) + info->half_height;
+ double the_sin = sin((new_time * (double)st->info->yspeed) + (time_modifier * 80.0));
+ double dist_mod_y = sin(new_time) * (st->info->half_height - 50);
+ st->pos[index] = st->info->yamplitude * (the_sin * dist_mod_y) + st->info->half_height;
}
}
static void
-innie(unsigned long int the_time, struct info *info, int pos[], int index, double modifier)
+innie(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index, double modifier)
{
- double frequency = 2000000.0 + (modifier * cos(((double)the_time / 100.0)));
+ double frequency = 2000000.0 + (st->modifier * cos(((double)the_time / 100.0)));
double arg = (double)the_time / frequency;
double amplitude = 200.0 * cos(arg);
double fun = 150.0 * cos((double)the_time / 2000.0);
int vert_mod, horiz_mod;
if (index == 0) {
- horiz_mod = (int)(fun * cos((double)the_time / 100.0)) + info->half_width;
- pos[index] = (amplitude * cos((double)the_time / 100.0 * info->xspeed)) + horiz_mod;
+ horiz_mod = (int)(fun * cos((double)the_time / 100.0)) + st->info->half_width;
+ st->pos[index] = (amplitude * cos((double)the_time / 100.0 * st->info->xspeed)) + horiz_mod;
}
else {
- vert_mod = (int)(fun * sin((double)the_time / 100.0)) + info->half_height;
- pos[index] = (amplitude * sin((double)the_time / 100.0 * info->yspeed)) + vert_mod;
+ vert_mod = (int)(fun * sin((double)the_time / 100.0)) + st->info->half_height;
+ st->pos[index] = (amplitude * sin((double)the_time / 100.0 * st->info->yspeed)) + vert_mod;
}
}
static void
-lissajous(unsigned long int the_time, struct info *info, int pos[], int index)
+lissajous(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
{
/* This is a pretty standard lissajous curve
x = a sin(nt + c)
double weird = cos((time / 1100000.0) / 1000.0);
if (index == 0) {
- result = info->xamplitude * 200.0 * sin((weird * time) + fun) + info->half_width;
+ result = st->info->xamplitude * 200.0 * sin((weird * time) + fun) + st->info->half_width;
}
else {
- result = info->yamplitude * 200.0 * sin(time) + info->half_height;
+ result = st->info->yamplitude * 200.0 * sin(time) + st->info->half_height;
}
- pos[index] = result;
+ st->pos[index] = result;
}
static void
-circle(unsigned long int the_time, struct info *info, int pos[], int index)
+circle(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
{
int result;
if (index == 0) {
- result = info->xamplitude * (cos((double)the_time / 100.0 * info->xspeed) * (info->half_width / 2)) + info->half_width;
+ result = st->info->xamplitude * (cos((double)the_time / 100.0 * st->info->xspeed) * (st->info->half_width / 2)) + st->info->half_width;
}
else {
- result = info->yamplitude * (sin((double)the_time / 100.0 * info->yspeed) * (info->half_height / 2)) + info->half_height;
+ result = st->info->yamplitude * (sin((double)the_time / 100.0 * st->info->yspeed) * (st->info->half_height / 2)) + st->info->half_height;
}
- pos[index] = result;
+ st->pos[index] = result;
}
#if 0
mod(unsigned long int the_time, struct info *info, int pos[], int index)
{
int amplitude;
- int max = info->half_width;
+ int max = st->info->half_width;
if ((the_time % (max * 2)) < max)
amplitude = max - ((the_time % (max * 2)) - max);
else
#endif
static void
-spin(unsigned long int the_time, struct info *info, int pos[], int index)
+spin(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
{
double funky = (((the_time % 360) * 1.0) / 180.0) * M_PI;
if (index ==0) {
- double the_cos = cos((double)the_time / (180.0 * info->xspeed));
- double dist_mod_x = cos((double)funky) * (info->half_width - 50);
- pos[index] = info->xamplitude * (the_cos * dist_mod_x) + info->half_width;
+ double the_cos = cos((double)the_time / (180.0 * st->info->xspeed));
+ double dist_mod_x = cos((double)funky) * (st->info->half_width - 50);
+ st->pos[index] = st->info->xamplitude * (the_cos * dist_mod_x) + st->info->half_width;
}
else {
- double the_sin = sin((double)the_time / (180.0 * info->yspeed));
- double dist_mod_y = sin((double)funky) * (info->half_height - 50);
- pos[index] = info->yamplitude * (the_sin * dist_mod_y) + info->half_height;
+ double the_sin = sin((double)the_time / (180.0 * st->info->yspeed));
+ double dist_mod_y = sin((double)funky) * (st->info->half_height - 50);
+ st->pos[index] = st->info->yamplitude * (the_sin * dist_mod_y) + st->info->half_height;
}
}
static void
-fun(unsigned long int the_time, struct info *info, int pos[], int index)
+fun(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
{
int amplitude;
- int max = info->half_width;
+ int max = st->info->half_width;
if ((the_time % (max * 2)) < max)
amplitude = max - ((the_time % (max * 2)) - max);
else
amplitude = the_time % (max * 2);
amplitude = amplitude - max;
if (index ==0) {
- pos[index] = (amplitude * cos((double)the_time / 100.0 * info->xspeed)) + info->half_width;
+ st->pos[index] = (amplitude * cos((double)the_time / 100.0 * st->info->xspeed)) + st->info->half_width;
}
else {
- pos[index] = (amplitude * sin((double)the_time / 100.0 * info->yspeed)) + info->half_height;
+ st->pos[index] = (amplitude * sin((double)the_time / 100.0 * st->info->yspeed)) + st->info->half_height;
}
}
static void
-linear(unsigned long int the_time, struct info *info, int pos[], int index)
+linear(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
{
if (index == 0) /* Calculate for the x axis */
- pos[index] = ((the_time / 2) % (info->half_width * 2));
+ st->pos[index] = ((the_time / 2) % (st->info->half_width * 2));
else
- pos[index] = ((the_time / 2) % (info->half_height * 2));
+ st->pos[index] = ((the_time / 2) % (st->info->half_height * 2));
}
static void
-test(unsigned long int the_time, struct info *info, int pos[], int index)
+test(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
{
if (index == 0) {
- pos[index] = info->xamplitude * (cos((double)the_time / 100.0 * info->xspeed) * (info->half_width / 2)) + info->half_width;
+ st->pos[index] = st->info->xamplitude * (cos((double)the_time / 100.0 * st->info->xspeed) * (st->info->half_width / 2)) + st->info->half_width;
}
else {
- pos[index] = info->yamplitude * (sin((double)the_time / 100.0 * info->yspeed) * (info->half_height / 2)) + info->half_height;
+ st->pos[index] = st->info->yamplitude * (sin((double)the_time / 100.0 * st->info->yspeed) * (st->info->half_height / 2)) + st->info->half_height;
}
}
return(current);
}
+#if 0
static void
-smoothen(int x, int lastx, int y, int lasty, int size, int last_color, XColor *colors, Display *display, Window window, GC bgc, int screen, struct info *info)
+smoothen(struct state *st, int x, int lastx, int y, int lasty, int size, int last_color, XColor *colors, Display *dpy, Window window, GC bgc, int screen, struct info *info)
{
double xdistance = abs((double)x-(double)lastx);
double ydistance = abs((double)y-(double)lasty);
if (distance > 2.0) {
int newx = (int)((xdistance / distance) * slope);
int newy = (int)((ydistance / distance) * slope);
- if (! info->trail) {
- XSetForeground(display, bgc, BlackPixel(display, screen));
- XFillArc(display, window, bgc, lastx, lasty, size, size, START_ARC, END_ARC);
+ if (! st->info->trail) {
+ XSetForeground(st->dpy, st->bgc, BlackPixel(st->dpy, st->screen));
+ XFillArc(st->dpy, st->window, st->bgc, lastx, lasty, size, size, START_ARC, END_ARC);
}
- XSetForeground(display, bgc, colors[last_color].pixel);
- XFillArc(display, window, bgc, newx, newy, size, size, START_ARC, END_ARC);
- XSync(display, False);
- smoothen(newx, x, newy, y, size, last_color, colors, display, window, bgc, screen, info);
+ XSetForeground(st->dpy, st->bgc, st->colors[last_color].pixel);
+ XFillArc(st->dpy, st->window, st->bgc, newx, newy, size, size, START_ARC, END_ARC);
+ smoothen(st, newx, x, newy, y, size, last_color, st->colors, st->dpy, st->window, st->bgc, st->screen, st->info);
}
}
+#endif
-void
-screenhack (Display *display, Window window)
+static void *
+whirlygig_init (Display *dpy, Window window)
{
- /* The following are all X related toys */
- XGCValues gcv; /* The structure to hold the GC data */
- XWindowAttributes xgwa; /* A structure to hold window data */
- GC fgc, bgc;
- int screen;
+ struct state *st = (struct state *) calloc (1, sizeof(*st));
+ st->dpy = dpy;
+ st->window = window;
+
+ st->ncolors = NCOLORS;
+
+ st->dbuf = get_boolean_resource (st->dpy, "doubleBuffer", "Boolean");
+
+# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+ st->dbuf = False;
+# endif
+
+ st->start_time = st->current_time;
+ st->info = (struct info *)malloc(sizeof(struct info));
+
+ st->screen = DefaultScreen(st->dpy);
+ XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
+ if (st->dbuf)
+ {
+#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
+ if (get_boolean_resource(st->dpy,"useDBE","Boolean"))
+ {
+ st->dbeclear_p = get_boolean_resource (st->dpy, "useDBEClear",
+ "Boolean");
+ if (st->dbeclear_p)
+ st->b = xdbe_get_backbuffer (st->dpy, st->window, XdbeBackground);
+ else
+ st->b = xdbe_get_backbuffer (st->dpy, st->window, XdbeUndefined);
+ st->backb = st->b;
+ }
+#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+
+ if (!st->b)
+ {
+ st->ba = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height,st->xgwa.depth);
+ st->b = st->ba;
+ }
+ }
+ else
+ {
+ st->b = st->window;
+ }
+
+ st->gcv.foreground = get_pixel_resource(st->dpy, st->xgwa.colormap, "foreground", "Foreground");
+ st->fgc = XCreateGC (st->dpy, st->b, GCForeground, &st->gcv);
+ st->gcv.foreground = get_pixel_resource(st->dpy, st->xgwa.colormap, "background", "Background");
+ st->bgc = XCreateGC (st->dpy, st->b, GCForeground, &st->gcv);
+
+#ifdef HAVE_COCOA /* #### should turn off double-buffering instead */
+ jwxyz_XSetAntiAliasing (dpy, st->fgc, False);
+ jwxyz_XSetAntiAliasing (dpy, st->bgc, False);
+#endif
+
+ {
+ Bool writable_p = False;
+ make_uniform_colormap (st->xgwa.screen, st->xgwa.visual,
+ st->xgwa.colormap, st->colors, &st->ncolors,
+ True, &writable_p, True);
+ }
+
+ if (st->ba) XFillRectangle (st->dpy, st->ba, st->bgc, 0, 0, st->xgwa.width, st->xgwa.height);
- unsigned long int current_time = 0; /* The global int telling the current time */
- unsigned long int start_time = current_time;
- struct info *info = (struct info *)malloc(sizeof(struct info)); /* Dont forget to call free() later */
- char *xmode_str, *ymode_str; /* holds the current mode for x and y computation */
- /* pos is the current position x,y -- last_x contains one cell of every x coordinate
- for every position of every whirly in every line up to 100 whirlies in 100 lines
- -- lasy_y and last_size hold the same information for y and size respectively */
- int pos[2], last_x[100][100], last_y[100][100], last_size[100][100];
- int current_color;
- int wrap;
- int xmode, ymode;
- double modifier; /* for innie */
- /* Set up the X toys that I will be using later */
- screen = DefaultScreen(display);
- XGetWindowAttributes (display, window, &xgwa);
- gcv.foreground = get_pixel_resource("foreground", "Foreground", display, xgwa.colormap);
- fgc = XCreateGC (display, window, GCForeground, &gcv);
- gcv.foreground = get_pixel_resource("background", "Background", display, xgwa.colormap);
- bgc = XCreateGC (display, window, GCForeground, &gcv);
- make_uniform_colormap (display, xgwa.visual, xgwa.colormap, colors, &ncolors, True, &info->writable, True);
/* info is a structure holding all the random pieces of information I may want to
pass to my baby functions -- much of it I may never use, but it is nice to
have around just in case I want it to make a funky function funkier */
- info->writable = get_boolean_resource ("cycle", "Boolean");
- info->xspeed = get_float_resource("xspeed" , "Float");
- info->yspeed = get_float_resource("yspeed" , "Float");
- info->xamplitude = get_float_resource("xamplitude", "Float");
- info->yamplitude = get_float_resource("yamplitude", "Float");
- info->offset_period = get_float_resource("offset_period", "Float");
- info->whirlies = get_integer_resource("whirlies", "Integer");
- info->nlines = get_integer_resource("nlines", "Integer");
- info->half_width = xgwa.width / 2;
- info->half_height = xgwa.height / 2;
- info->speed = get_integer_resource("speed" , "Integer");
- info->trail = get_integer_resource("trail", "Integer");
- info->color_modifier = get_integer_resource("color_modifier", "Integer");
- info->xoffset = get_float_resource("xoffset", "Float");
- info->yoffset = get_float_resource("yoffset", "Float");
- xmode_str = get_string_resource("xmode", "Mode");
- ymode_str = get_string_resource("ymode", "Mode");
- wrap = get_integer_resource("wrap", "Integer");
- modifier = 3000.0 + (1500.0 * random() / (RAND_MAX + 1.0));
- if (! xmode_str) xmode = spin_mode;
- else if (! strcmp (xmode_str, "spin")) xmode = spin_mode;
- else if (! strcmp (xmode_str, "funky")) xmode = funky_mode;
- else if (! strcmp (xmode_str, "linear")) xmode = linear_mode;
- else if (! strcmp (xmode_str, "fun")) xmode = fun_mode;
- else if (! strcmp (xmode_str, "innie")) xmode = innie_mode;
- else if (! strcmp (xmode_str, "lissajous")) xmode = lissajous_mode;
- else if (! strcmp (xmode_str, "test")) xmode = test_mode;
+/* info->writable = get_boolean_resource (dpy, "cycle", "Boolean"); */
+ st->info->xspeed = get_float_resource(st->dpy, "xspeed" , "Float");
+ st->info->yspeed = get_float_resource(st->dpy, "yspeed" , "Float");
+ st->info->xamplitude = get_float_resource(st->dpy, "xamplitude", "Float");
+ st->info->yamplitude = get_float_resource(st->dpy, "yamplitude", "Float");
+ st->info->offset_period = get_float_resource(st->dpy, "offset_period", "Float");
+ st->info->whirlies = get_integer_resource(st->dpy, "whirlies", "Integer");
+ st->info->nlines = get_integer_resource(st->dpy, "nlines", "Integer");
+ st->info->half_width = st->xgwa.width / 2;
+ st->info->half_height = st->xgwa.height / 2;
+ st->info->speed = get_integer_resource(st->dpy, "speed" , "Integer");
+ st->info->trail = get_boolean_resource(st->dpy, "trail", "Integer");
+ st->info->color_modifier = get_integer_resource(st->dpy, "color_modifier", "Integer");
+ st->info->xoffset = get_float_resource(st->dpy, "xoffset", "Float");
+ st->info->yoffset = get_float_resource(st->dpy, "yoffset", "Float");
+ st->xmode_str = get_string_resource(st->dpy, "xmode", "Mode");
+ st->ymode_str = get_string_resource(st->dpy, "ymode", "Mode");
+ st->wrap = get_boolean_resource(st->dpy, "wrap", "Boolean");
+ st->modifier = 3000.0 + frand(1500.0);
+ if (! st->xmode_str) st->xmode = spin_mode;
+ else if (! strcmp (st->xmode_str, "spin")) st->xmode = spin_mode;
+ else if (! strcmp (st->xmode_str, "funky")) st->xmode = funky_mode;
+ else if (! strcmp (st->xmode_str, "circle")) st->xmode = circle_mode;
+ else if (! strcmp (st->xmode_str, "linear")) st->xmode = linear_mode;
+ else if (! strcmp (st->xmode_str, "test")) st->xmode = test_mode;
+ else if (! strcmp (st->xmode_str, "fun")) st->xmode = fun_mode;
+ else if (! strcmp (st->xmode_str, "innie")) st->xmode = innie_mode;
+ else if (! strcmp (st->xmode_str, "lissajous")) st->xmode = lissajous_mode;
else {
- xmode = spin_mode;
+ st->xmode = random() % (int) lissajous_mode;
}
- if (! ymode_str) ymode = spin_mode;
- else if (! strcmp (ymode_str, "spin")) ymode = spin_mode;
- else if (! strcmp (ymode_str, "funky")) ymode = funky_mode;
- else if (! strcmp (ymode_str, "linear")) ymode = linear_mode;
- else if (! strcmp (ymode_str, "fun")) ymode = fun_mode;
- else if (! strcmp (ymode_str, "innie")) ymode = innie_mode;
- else if (! strcmp (ymode_str, "lissajous")) ymode = lissajous_mode;
- else if (! strcmp (ymode_str, "test")) ymode = test_mode;
+ if (! st->ymode_str) st->ymode = spin_mode;
+ else if (! strcmp (st->ymode_str, "spin")) st->ymode = spin_mode;
+ else if (! strcmp (st->ymode_str, "funky")) st->ymode = funky_mode;
+ else if (! strcmp (st->ymode_str, "circle")) st->ymode = circle_mode;
+ else if (! strcmp (st->ymode_str, "linear")) st->ymode = linear_mode;
+ else if (! strcmp (st->ymode_str, "test")) st->ymode = test_mode;
+ else if (! strcmp (st->ymode_str, "fun")) st->ymode = fun_mode;
+ else if (! strcmp (st->ymode_str, "innie")) st->ymode = innie_mode;
+ else if (! strcmp (st->ymode_str, "lissajous")) st->ymode = lissajous_mode;
else {
- ymode = spin_mode;
+ st->ymode = random() % (int) lissajous_mode;
}
- if (get_integer_resource("start_time", "Integer") == -1)
- current_time = (unsigned long int)(random());
+ if (get_integer_resource(st->dpy, "start_time", "Integer") == -1)
+ st->current_time = (unsigned long int)(random());
else
- current_time = get_integer_resource("start_time", "Integer");
- if (info->whirlies == -1)
- info->whirlies = 1 + (int)(15.0 * random() / (RAND_MAX + 1.0));
- if (info->nlines == -1)
- info->nlines = 1 + (int)(5.0 * random() / (RAND_MAX + 1.0));
- if (info->color_modifier == -1)
- info->color_modifier = 1 + (int)(25.0 * random() / (RAND_MAX + 1.0));
- if (get_integer_resource("explain", "Integer") == 1)
- explain(mode, info, display, window, fgc);
- current_color = 1 + (int)((double)NCOLORS * random() / (RAND_MAX + 1.0));
- /* Now that info is full, lets play! */
-
- while (1) {
- int wcount; /* wcount is a counter incremented for every whirly take note of
- internal_time before you mess with it */
- int change_time = 4000;
- if (! strcmp (xmode_str, "change") && ! strcmp (ymode_str, "change")) {
- if ((current_time - start_time) > change_time) {
- start_time = current_time;
- xmode = 1 + (int)(4.0 * random() / (RAND_MAX + 1.0));
- ymode = 1 + (int)(4.0 * random() / (RAND_MAX + 1.0));
- }
+ st->current_time = get_integer_resource(st->dpy, "start_time", "Integer");
+ if (st->info->whirlies == -1)
+ st->info->whirlies = 1 + (random() % 15);
+ if (st->info->nlines == -1)
+ st->info->nlines = 1 + (random() % 5);
+ if (st->info->color_modifier == -1)
+ st->info->color_modifier = 1 + (random() % 25);
+ if (get_boolean_resource(st->dpy, "explain", "Integer"))
+ st->explaining = 1;
+ st->current_color = 1 + (random() % NCOLORS);
+
+ return st;
+}
+
+static unsigned long
+whirlygig_draw (Display *dpy, Window window, void *closure)
+{
+ struct state *st = (struct state *) closure;
+ int wcount; /* wcount is a counter incremented for every whirly take note of
+ internal_time before you mess with it */
+ int change_time = 4000;
+
+ if (st->explaining == 1) {
+ XClearWindow (st->dpy, st->window);
+ draw_explain_string(st, st->xmode, st->info->half_height-100,
+ st->dpy, st->window, st->fgc);
+ st->explaining++;
+ return 3000000;
+ } else if (st->explaining == 2) {
+ XClearWindow (st->dpy, st->window);
+ st->explaining = 0;
+ }
+
+ if (! strcmp (st->xmode_str, "change") && ! strcmp (st->ymode_str, "change")) {
+ if ((st->current_time - st->start_time) > change_time) {
+ st->start_time = st->current_time;
+ st->xmode = 1 + (random() % 4);
+ st->ymode = 1 + (random() % 4);
+ }
+ }
+ else if (! strcmp (st->xmode_str, "change")) {
+ if ((st->current_time - st->start_time) > change_time) {
+ st->start_time = st->current_time;
+ st->xmode = 1 + (random() % 4);
+ }
+ }
+ else if (! strcmp (st->ymode_str, "change")) {
+ if ((st->current_time - st->start_time) > change_time) {
+ st->start_time = st->current_time;
+ st->ymode = 1 + (random() % 3);
+ printf("Changing ymode to %d\n", st->ymode);
+ }
+ }
+ if (++st->current_color >= NCOLORS)
+ st->current_color = 0;
+ for (wcount = 0; wcount < st->info->whirlies; wcount++) {
+ int lcount; /* lcount is a counter for every line -- take note of the offsets changing */
+ int internal_time = st->current_time;
+ int color_offset = (st->current_color + (st->info->color_modifier * wcount)) % NCOLORS;
+ if (st->current_time == 0)
+ internal_time = 0;
+ else
+ /* I want the distance between whirlies to increase more each whirly */
+ internal_time = st->current_time + (10 * wcount) + (wcount * wcount);
+ switch (st->xmode) {
+ /* All these functions expect an int time, the struct info,
+ a pointer to an array of positions, and the index that the
+ the function will fill of the array */
+ case spin_mode:
+ spin(st, internal_time, st->info, st->pos, 0);
+ break;
+ case funky_mode:
+ funky(st, internal_time, st->info, st->pos, 0);
+ break;
+ case circle_mode:
+ circle(st, internal_time, st->info, st->pos, 0);
+ break;
+ case linear_mode:
+ linear(st, internal_time, st->info, st->pos, 0);
+ break;
+ case fun_mode:
+ fun(st, internal_time, st->info, st->pos, 0);
+ break;
+ case test_mode:
+ test(st, internal_time, st->info, st->pos, 0);
+ break;
+ case innie_mode:
+ innie(st, internal_time, st->info, st->pos, 0, st->modifier);
+ break;
+ case lissajous_mode:
+ lissajous(st, internal_time, st->info, st->pos, 0);
+ break;
+ default:
+ spin(st, internal_time, st->info, st->pos, 0);
+ break;
+ } /* End of the switch for the x position*/
+ switch (st->ymode) {
+ case spin_mode:
+ spin(st, internal_time, st->info, st->pos, 1);
+ break;
+ case funky_mode:
+ funky(st, internal_time, st->info, st->pos, 1);
+ break;
+ case circle_mode:
+ circle(st, internal_time, st->info, st->pos, 1);
+ break;
+ case linear_mode:
+ linear(st, internal_time, st->info, st->pos, 1);
+ break;
+ case fun_mode:
+ fun(st, internal_time, st->info, st->pos, 1);
+ break;
+ case test_mode:
+ test(st, internal_time, st->info, st->pos, 1);
+ break;
+ case innie_mode:
+ innie(st, internal_time, st->info, st->pos, 1, st->modifier);
+ break;
+ case lissajous_mode:
+ lissajous(st, internal_time, st->info, st->pos, 1);
+ break;
+ default:
+ spin(st, internal_time, st->info, st->pos, 1);
+ break;
+ } /* End of the switch for the y position*/
+ for (lcount = 0; lcount < st->info->nlines; lcount++) {
+ double arg = (double)((internal_time * st->info->offset_period) / 90.0);
+ double line_offset = 20.0 * (double)lcount * sin(arg);
+ int size;
+ size = (int)(15.0 + 5.0 * sin((double)internal_time / 180.0));
+ /* First delete the old circle... */
+ if (!st->info->trail
+#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
+ && ( !st->dbeclear_p || !st->backb)
+#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+ ) {
+ XSetForeground(st->dpy, st->bgc, BlackPixel(st->dpy, st->screen));
+ XFillArc(st->dpy, st->b, st->bgc, st->last_x[wcount][lcount], st->last_y[wcount][lcount], st->last_size[wcount][lcount], st->last_size[wcount][lcount], START_ARC, END_ARC);
+ }
+ /* Now, lets draw in the new circle */
+ { /* Starting new scope for local x_pos and y_pos */
+ int xpos, ypos;
+ if (st->wrap) {
+ xpos = preen((int)(st->info->xoffset*line_offset)+st->pos[0], st->info->half_width * 2);
+ ypos = preen((int)(st->info->yoffset*line_offset)+st->pos[1], st->info->half_height * 2);
}
- else if (! strcmp (xmode_str, "change")) {
- if ((current_time - start_time) > change_time) {
- start_time = current_time;
- xmode = 1 + (int)(3.5 * random() / (RAND_MAX + 1.0));
- }
+ else {
+ xpos = (int)(st->info->xoffset*line_offset)+st->pos[0];
+ ypos = (int)(st->info->yoffset*line_offset)+st->pos[1];
}
- else if (! strcmp (ymode_str, "change")) {
- if ((current_time - start_time) > change_time) {
- start_time = current_time;
- ymode = 1 + (int)(3.0 * random() / (RAND_MAX + 1.0));
- printf("Changing ymode to %d\n", ymode);
- }
+ if (st->start_time == st->current_time) {
+ /* smoothen should move from one mode to another prettily... */
+
+ /* Note: smoothen has not been modified to take the double
+ buffering code into account, and needs to be hacked on
+ before uncommenting.
+ */
+ /*
+ smoothen(xpos, last_x[wcount][lcount], ypos, last_y[wcount][lcount], size, color_offset, colors, dpy, window, bgc, screen, info);
+ */
}
- if (++current_color >= NCOLORS)
- current_color = 0;
- for (wcount = 0; wcount < info->whirlies; wcount++) {
- int lcount; /* lcount is a counter for every line -- take note of the offsets changing */
- int internal_time = current_time;
- int color_offset = (current_color + (info->color_modifier * wcount)) % NCOLORS;
- if (current_time == 0)
- internal_time = 0;
- else
- /* I want the distance between whirlies to increase more each whirly */
- internal_time = current_time + (10 * wcount) + (wcount * wcount);
- switch (xmode) {
- /* All these functions expect an int time, the struct info, a pointer to an array of positions,
- and the index that the the function will fill of the array */
- case spin_mode:
- spin(internal_time, info, pos, 0);
- break;
- case funky_mode:
- funky(internal_time, info, pos, 0);
- break;
- case circle_mode:
- circle(internal_time, info, pos, 0);
- break;
- case linear_mode:
- linear(internal_time, info, pos, 0);
- break;
- case fun_mode:
- fun(internal_time, info, pos, 0);
- break;
- case test_mode:
- test(internal_time, info, pos, 0);
- break;
- case innie_mode:
- innie(internal_time, info, pos, 0, modifier);
- break;
- case lissajous_mode:
- lissajous(internal_time, info, pos, 0);
- break;
- default:
- spin(internal_time, info, pos, 0);
- break;
- } /* End of the switch for the x position*/
- switch (ymode) {
- case spin_mode:
- spin(internal_time, info, pos, 1);
- break;
- case funky_mode:
- funky(internal_time, info, pos, 1);
- break;
- case circle_mode:
- circle(internal_time, info, pos, 1);
- break;
- case linear_mode:
- linear(internal_time, info, pos, 1);
- break;
- case fun_mode:
- fun(internal_time, info, pos, 1);
- break;
- case test_mode:
- test(internal_time, info, pos, 1);
- break;
- case innie_mode:
- innie(internal_time, info, pos, 1, modifier);
- break;
- case lissajous_mode:
- lissajous(internal_time, info, pos, 1);
- break;
- default:
- spin(internal_time, info, pos, 1);
- break;
- } /* End of the switch for the y position*/
- for (lcount = 0; lcount < info->nlines; lcount++) {
- double arg = (double)((internal_time * info->offset_period) / 90.0);
- double line_offset = 20.0 * (double)lcount * sin(arg);
- int size;
- size = (int)(15.0 + 5.0 * sin((double)internal_time / 180.0));
-/* First delete the old circle... */
- if (! info->trail) {
- XSetForeground(display, bgc, BlackPixel(display, screen));
- XFillArc(display, window, bgc, last_x[wcount][lcount], last_y[wcount][lcount], last_size[wcount][lcount], last_size[wcount][lcount], START_ARC, END_ARC);
- }
- /* Now, lets draw in the new circle */
- { /* Starting new scope for local x_pos and y_pos */
- int xpos, ypos;
- if (wrap) {
- xpos = preen((int)(info->xoffset*line_offset)+pos[0], info->half_width * 2);
- ypos = preen((int)(info->yoffset*line_offset)+pos[1], info->half_height * 2);
- }
- else {
- xpos = (int)(info->xoffset*line_offset)+pos[0];
- ypos = (int)(info->yoffset*line_offset)+pos[1];
- }
- if (start_time == current_time) {
- /* smoothen should move from one mode to another prettily... */
-/*
- smoothen(xpos, last_x[wcount][lcount], ypos, last_y[wcount][lcount], size, color_offset, colors, display, window, bgc, screen, info);
- */
- }
- last_x[wcount][lcount] = xpos;
- last_y[wcount][lcount] = ypos;
- last_size[wcount][lcount] = size;
- XSetForeground(display, bgc, colors[color_offset].pixel);
- XFillArc(display, window, bgc, xpos, ypos, size, size, START_ARC, END_ARC);
- } /* End of my temporary scope for xpos and ypos */
- } /* End of the for each line in nlines */
- } /* End of the for each whirly in whirlies */
- XSync(display, False);
- if (current_time == FULL_CYCLE)
- current_time = 1;
- else
- current_time = current_time + info->speed;
- screenhack_handle_events(display);
- if (!info->writable)
- usleep(10000);
- } /* End the while loop! */
- free(info);
+ st->last_x[wcount][lcount] = xpos;
+ st->last_y[wcount][lcount] = ypos;
+ st->last_size[wcount][lcount] = size;
+ XSetForeground(st->dpy, st->bgc, st->colors[color_offset].pixel);
+ XFillArc(st->dpy, st->b, st->bgc, xpos, ypos, size, size, START_ARC, END_ARC);
+ } /* End of my temporary scope for xpos and ypos */
+ } /* End of the for each line in nlines */
+ } /* End of the for each whirly in whirlies */
+
+
+#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
+ if (st->backb)
+ {
+ XdbeSwapInfo info[1];
+ info[0].swap_window = st->window;
+ info[0].swap_action = (st->dbeclear_p ? XdbeBackground : XdbeUndefined);
+ XdbeSwapBuffers (st->dpy, info, 1);
+ }
+ else
+#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+ if (st->dbuf)
+ {
+ XCopyArea (st->dpy, st->b, st->window, st->bgc, 0, 0,
+ st->xgwa.width, st->xgwa.height, 0, 0);
+ }
+
+ if (st->current_time == FULL_CYCLE)
+ st->current_time = 1;
+ else
+ st->current_time = st->current_time + st->info->speed;
+
+ return 10000;
+}
+
+
+static void
+whirlygig_reshape (Display *dpy, Window window, void *closure,
+ unsigned int w, unsigned int h)
+{
+}
+
+static Bool
+whirlygig_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+ return False;
+}
+
+static void
+whirlygig_free (Display *dpy, Window window, void *closure)
+{
}
+
+
+static const char *whirlygig_defaults [] = {
+ ".background: black",
+ ".foreground: white",
+ "*fpsSolid: true",
+ "*xspeed: 1.0",
+ "*yspeed: 1.0",
+ "*xamplitude: 1.0",
+ "*yamplitude: 1.0",
+ "*whirlies: -1",
+ "*nlines: -1",
+ "*xmode: change",
+ "*ymode: change",
+ "*speed: 1",
+ "*trail: false",
+ "*color_modifier: -1",
+ "*start_time: -1",
+ "*explain: False",
+ "*xoffset: 1.0",
+ "*yoffset: 1.0",
+ "*offset_period: 1",
+ "*wrap: False",
+ "*doubleBuffer: True",
+#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
+ "*useDBEClear: True",
+ "*useDBE: True",
+#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
+ 0
+};
+
+static XrmOptionDescRec whirlygig_options [] = {
+ { "-xspeed", ".xspeed", XrmoptionSepArg, 0 },
+ /* xspeed is a modifier of the argument to cos -- changing it thus
+ changes the frequency of cos */
+ { "-yspeed", ".yspeed", XrmoptionSepArg, 0 },
+ /* Similiarly, yspeed changes the frequency of sin */
+ { "-xamplitude", ".xamplitude", XrmoptionSepArg, 0 },
+ /* A factor by which to increase/decrease the amplitude of the sin */
+ { "-yamplitude", ".yamplitude", XrmoptionSepArg, 0 },
+ /* A factor by which to increase/decrease the amplitude of the cos */
+ { "-whirlies", ".whirlies",XrmoptionSepArg, 0 },
+ /* whirlies defines the number of circles to draw per line */
+ { "-nlines", ".nlines",XrmoptionSepArg, 0 },
+ /* nlines is the number of lines of whirlies to draw */
+ { "-xmode", ".xmode", XrmoptionSepArg, 0 },
+ /* There are a few different modes that I have written -- each mode
+ is in theory a different experiment with the possible modifiers to sin/cos */
+ { "-ymode", ".ymode", XrmoptionSepArg, 0 },
+ { "-speed", ".speed", XrmoptionSepArg, 0 },
+ /* This will modify how often it should draw, changing it will probably suck */
+ { "-trail", ".trail", XrmoptionNoArg, "True" },
+ /* Control whether or not you want the old circles to be erased */
+ { "-color_modifier", ".color_modifier", XrmoptionSepArg, 0 },
+ /* How many colors away from the current should the next whirly be? */
+ { "-start_time", ".start_time", XrmoptionSepArg, 0 },
+ /* Specify exactly at what time to start graphing... */
+ { "-xoffset", ".xoffset", XrmoptionSepArg, 0 },
+ /* Tell the whirlies to be offset by this factor of a sin */
+ { "-yoffset", ".yoffset", XrmoptionSepArg, 0 },
+ /* Tell the whirlies to be offset by this factor of a cos */
+ { "-offset_period", ".offset_period", XrmoptionSepArg, 0 },
+ /* Change the period of an offset cycle */
+ { "-explain", ".explain", XrmoptionNoArg, "True" },
+ /* Specify whether or not to print an explanation of the function used. */
+ { "-wrap", ".wrap", XrmoptionNoArg, "True" },
+ { "-no-wrap", ".wrap", XrmoptionNoArg, "False" },
+ /* Specify if you want whirlies which are out of the boundary of the screen to be
+ wrapped around to the other side */
+ { "-db", ".doubleBuffer", XrmoptionNoArg, "True" },
+ { "-no-db", ".doubleBuffer", XrmoptionNoArg, "False" },
+ { 0, 0, 0, 0 }
+};
+
+XSCREENSAVER_MODULE ("Whirlygig", whirlygig)