*
* CHANGES
*
+ * 1.1 dragorn Jan 04 2005 Fixed some indenting, typo in errors for parsing
+ * cmdline args
+ * 1.1 dagraz Jan 04 2005 Added option for circular cracks (David Agraz)
+ * Cleaned up issues with timeouts in start_crack (DA)
* 1.0 dragorn Oct 10 2004 First port done
*
* Directly based the hacks of:
* implied warranty.
*/
-#include "screenhack.h"
-#include <X11/Xutil.h>
-#include <stdio.h>
-#include <sys/time.h>
-
-#ifndef MAX_WIDTH
-#include <limits.h>
-#define MAX_WIDTH SHRT_MAX
-#endif
-
-#ifdef TIME_ME
-#include <time.h>
-#endif
-
#include <math.h>
+#include "screenhack.h"
/* this program goes faster if some functions are inline. The following is
* borrowed from ifs.c */
#define inline /* */
#endif
+#define STEP 0.42
+
/* Raw colormap extracted from pollockEFF.gif */
-char *rgb_colormap[] = {
- "rgb:20/1F/21", "rgb:26/2C/2E", "rgb:35/26/26", "rgb:37/2B/27",
- "rgb:30/2C/2E", "rgb:39/2B/2D", "rgb:32/32/29", "rgb:3F/32/29",
- "rgb:38/32/2E", "rgb:2E/33/3D", "rgb:33/3A/3D", "rgb:47/33/29",
- "rgb:40/39/2C", "rgb:40/39/2E", "rgb:47/40/2C", "rgb:47/40/2E",
- "rgb:4E/40/2C", "rgb:4F/40/2E", "rgb:4E/47/38", "rgb:58/40/37",
- "rgb:65/47/2D", "rgb:6D/5D/3D", "rgb:74/55/30", "rgb:75/55/32",
- "rgb:74/5D/32", "rgb:74/64/33", "rgb:7C/6C/36", "rgb:52/31/52",
- "rgb:44/48/42", "rgb:4C/56/47", "rgb:65/5D/45", "rgb:6D/5D/44",
- "rgb:6C/5D/4E", "rgb:74/6C/43", "rgb:7C/6C/42", "rgb:7C/6C/4B",
- "rgb:6B/73/4B", "rgb:73/73/4B", "rgb:7B/7B/4A", "rgb:6B/6C/55",
- "rgb:69/6D/5E", "rgb:7B/6C/5D", "rgb:6B/73/53", "rgb:6A/74/5D",
- "rgb:72/7B/52", "rgb:7B/7B/52", "rgb:57/74/6E", "rgb:68/74/66",
- "rgb:9C/54/2B", "rgb:9D/54/32", "rgb:9D/5B/35", "rgb:93/6B/36",
- "rgb:AA/73/30", "rgb:C4/5A/27", "rgb:D9/52/23", "rgb:D8/5A/20",
- "rgb:DB/5A/23", "rgb:E5/70/37", "rgb:83/6C/4B", "rgb:8C/6B/4B",
- "rgb:82/73/5C", "rgb:93/73/52", "rgb:81/7B/63", "rgb:81/7B/6D",
- "rgb:92/7B/63", "rgb:D9/89/3B", "rgb:E4/98/32", "rgb:DF/A1/33",
- "rgb:E5/A0/37", "rgb:F0/AB/3B", "rgb:8A/8A/59", "rgb:B2/9A/58",
- "rgb:89/82/6B", "rgb:9A/82/62", "rgb:88/8B/7C", "rgb:90/9A/7A",
- "rgb:A2/82/62", "rgb:A1/8A/69", "rgb:A9/99/68", "rgb:99/A1/60",
- "rgb:99/A1/68", "rgb:CA/81/48", "rgb:EB/8D/43", "rgb:C2/91/60",
- "rgb:C2/91/68", "rgb:D1/A9/77", "rgb:C9/B9/7F", "rgb:F0/E2/7B",
- "rgb:9F/92/8B", "rgb:C0/B9/99", "rgb:E6/B8/8F", "rgb:C8/C1/87",
- "rgb:E0/C8/86", "rgb:F2/CC/85", "rgb:F5/DA/83", "rgb:EC/DE/9D",
- "rgb:F5/D2/94", "rgb:F5/DA/94", "rgb:F4/E7/84", "rgb:F4/E1/8A",
- "rgb:F4/E1/93", "rgb:E7/D8/A7", "rgb:F1/D4/A5", "rgb:F1/DC/A5",
- "rgb:F4/DB/AD", "rgb:F1/DC/AE", "rgb:F4/DB/B5", "rgb:F5/DB/BD",
- "rgb:F4/E2/AD", "rgb:F5/E9/AD", "rgb:F4/E3/BE", "rgb:F5/EA/BE",
- "rgb:F7/F0/B6", "rgb:D9/D1/C1", "rgb:E0/D0/C0", "rgb:E7/D8/C0",
- "rgb:F1/DD/C6", "rgb:E8/E1/C0", "rgb:F3/ED/C7", "rgb:F6/EC/CE",
- "rgb:F8/F2/C7", "rgb:EF/EF/D0", 0
+static const char *rgb_colormap[] = {
+ "#201F21", "#262C2E", "#352626", "#372B27",
+ "#302C2E", "#392B2D", "#323229", "#3F3229",
+ "#38322E", "#2E333D", "#333A3D", "#473329",
+ "#40392C", "#40392E", "#47402C", "#47402E",
+ "#4E402C", "#4F402E", "#4E4738", "#584037",
+ "#65472D", "#6D5D3D", "#745530", "#755532",
+ "#745D32", "#746433", "#7C6C36", "#523152",
+ "#444842", "#4C5647", "#655D45", "#6D5D44",
+ "#6C5D4E", "#746C43", "#7C6C42", "#7C6C4B",
+ "#6B734B", "#73734B", "#7B7B4A", "#6B6C55",
+ "#696D5E", "#7B6C5D", "#6B7353", "#6A745D",
+ "#727B52", "#7B7B52", "#57746E", "#687466",
+ "#9C542B", "#9D5432", "#9D5B35", "#936B36",
+ "#AA7330", "#C45A27", "#D95223", "#D85A20",
+ "#DB5A23", "#E57037", "#836C4B", "#8C6B4B",
+ "#82735C", "#937352", "#817B63", "#817B6D",
+ "#927B63", "#D9893B", "#E49832", "#DFA133",
+ "#E5A037", "#F0AB3B", "#8A8A59", "#B29A58",
+ "#89826B", "#9A8262", "#888B7C", "#909A7A",
+ "#A28262", "#A18A69", "#A99968", "#99A160",
+ "#99A168", "#CA8148", "#EB8D43", "#C29160",
+ "#C29168", "#D1A977", "#C9B97F", "#F0E27B",
+ "#9F928B", "#C0B999", "#E6B88F", "#C8C187",
+ "#E0C886", "#F2CC85", "#F5DA83", "#ECDE9D",
+ "#F5D294", "#F5DA94", "#F4E784", "#F4E18A",
+ "#F4E193", "#E7D8A7", "#F1D4A5", "#F1DCA5",
+ "#F4DBAD", "#F1DCAE", "#F4DBB5", "#F5DBBD",
+ "#F4E2AD", "#F5E9AD", "#F4E3BE", "#F5EABE",
+ "#F7F0B6", "#D9D1C1", "#E0D0C0", "#E7D8C0",
+ "#F1DDC6", "#E8E1C0", "#F3EDC7", "#F6ECCE",
+ "#F8F2C7", "#EFEFD0", 0
};
typedef struct {
/* Synthesis of data from Crack:: and SandPainter:: */
float x, y;
float t;
+ float ys, xs, t_inc; /* for curvature calculations */
+
+ int curved;
unsigned long sandcolor;
float sandp, sandg;
+
+ float degrees_drawn;
+
+ int crack_num;
+
} crack;
struct field {
int grains; /* number of grains in the sand painting */
+ int circle_percent;
+
crack *cracks; /* grid of cracks */
int *cgrid; /* grid of actual crack placement */
unsigned int cycles;
unsigned int wireframe;
+ unsigned int seamless;
};
+struct state {
+ Display *dpy;
+ Window window;
+
+ struct field *f;
+ unsigned int max_cycles;
+ int growth_delay;
+ GC fgc;
+ XWindowAttributes xgwa;
+ XGCValues gcv;
+};
+
+
static void
*xrealloc(void *p, size_t size)
{
return ret;
}
-struct field
+static struct field
*init_field(void)
{
struct field *f = xrealloc(NULL, sizeof(struct field));
f->parsedcolors = NULL;
f->cycles = 0;
f->wireframe = 0;
+ f->seamless = 0;
f->fgcolor = 0;
f->bgcolor = 0;
f->visdepth = 0;
f->grains = 0;
+ f->circle_percent = 0;
return f;
}
#define ref_pixel(f, x, y) ((f)->off_img[(y) * (f)->width + (x)])
#define ref_cgrid(f, x, y) ((f)->cgrid[(y) * (f)->width + (x)])
-inline void start_crack(struct field *f, crack *cr) {
+static inline void start_crack(struct field *f, crack *cr)
+{
/* synthesis of Crack::findStart() and crack::startCrack() */
int px = 0;
int py = 0;
float a;
/* shift until crack is found */
- while ((!found) || (timeout++ > 10000)) {
+ while ((!found) && (timeout++ < 10000)) {
px = (int) (random() % f->width);
py = (int) (random() % f->height);
found = 1;
}
- if (found) {
- /* start a crack */
- a = ref_cgrid(f, px, py);
+ if ( !found ) {
+ /* We timed out. Use our default values */
+ px = cr->x;
+ py = cr->y;
+
+ /* Sanity check needed */
+ if (px < 0) px = 0;
+ if (px >= f->width) px = f->width - 1;
+ if (py < 0) py = 0;
+ if (py >= f->height) py = f->height - 1;
+
+ ref_cgrid(f, px, py) = cr->t;
+ }
+
+ /* start a crack */
+ a = ref_cgrid(f, px, py);
+
+ if ((random() % 100) < 50) {
+ /* conversion of the java int(random(-2, 2.1)) */
+ a -= 90 + (frand(4.1) - 2.0);
+ } else {
+ a += 90 + (frand(4.1) - 2.0);
+ }
+
+ if ((random() % 100) < f->circle_percent) {
+ float r; /* radius */
+ float radian_inc;
+
+ cr->curved = 1;
+ cr->degrees_drawn = 0;
+
+ r = 10 + (random() % ((f->width + f->height) / 2));
if ((random() % 100) < 50) {
- /* conversion of the java int(random(-2, 2.1)) */
- a -= 90 + (frand(4.1) - 2.0);
- } else {
- a += 90 + (frand(4.1) - 2.0);
+ r *= -1;
}
- /* Condensed from Crack::startCrack */
- cr->x = px + ((float) 0.61 * cos(a * M_PI / 180));
- cr->y = py + ((float) 0.61 * sin(a * M_PI / 180));
- cr->t = a;
- } else {
- /* timeout */
+ /* arc length = r * theta => theta = arc length / r */
+ radian_inc = STEP / r;
+ cr->t_inc = radian_inc * 360 / 2 / M_PI;
+
+ cr->ys = r * sin(radian_inc);
+ cr->xs = r * ( 1 - cos(radian_inc));
+
+ }
+ else {
+ cr->curved = 0;
}
+
+ /* Condensed from Crack::startCrack */
+ cr->x = px + ((float) 0.61 * cos(a * M_PI / 180));
+ cr->y = py + ((float) 0.61 * sin(a * M_PI / 180));
+ cr->t = a;
+
}
-inline void make_crack(struct field *f) {
+static inline void make_crack(struct field *f)
+{
crack *cr;
if (f->num < f->max_num) {
cr->sandp = 0;
cr->sandg = (frand(0.2) - 0.01);
cr->sandcolor = f->parsedcolors[random() % f->numcolors];
+ cr->crack_num = f->num;
+ cr->curved = 0;
+ cr->degrees_drawn = 0;
+
+ /* We could use these values in the timeout case of start_crack */
+
+ cr->x = random() % f->width;
+ cr->y = random() % f->height;
+ cr->t = random() % 360;
/* start it */
start_crack(f, cr);
}
}
-inline void point2rgb(int depth, unsigned long c, int *r, int *g, int *b) {
+static inline void point2rgb(int depth, unsigned long c, int *r, int *g, int *b)
+{
switch(depth) {
case 32:
case 24:
+#ifdef HAVE_JWXYZ
+ /* This program idiotically does not go through a color map, so
+ we have to hardcode in knowledge of how jwxyz.a packs pixels!
+ Fix it to go through st->colors[st->ncolors] instead!
+ */
+ *r = (c & 0x00ff0000) >> 16;
+ *g = (c & 0x0000ffff) >> 8;
+ *b = (c & 0x000000ff);
+#else
*g = (c & 0xff00) >> 8;
*r = (c & 0xff0000) >> 16;
*b = c & 0xff;
+#endif
break;
case 16:
*g = ((c >> 5) & 0x3f) << 2;
}
}
-inline unsigned long rgb2point(int depth, int r, int g, int b) {
+static inline unsigned long rgb2point(int depth, int r, int g, int b)
+{
unsigned long ret = 0;
switch(depth) {
case 32:
- ret = 0xff000000;
case 24:
+#ifdef HAVE_JWXYZ
+ /* This program idiotically does not go through a color map, so
+ we have to hardcode in knowledge of how jwxyz.a packs pixels!
+ Fix it to go through st->colors[st->ncolors] instead!
+ */
+ ret = 0xFF000000 | (r << 16) | (g << 8) | b;
+#else
ret |= (r << 16) | (g << 8) | b;
+#endif
break;
case 16:
ret = ((r>>3) << 11) | ((g>>2)<<5) | (b>>3);
return ret;
}
-/* alpha blended point drawing */
-inline unsigned long trans_point(int x1, int y1, unsigned long myc, float a, struct field *f) {
+/* alpha blended point drawing -- this is Not Right and will likely fail on
+ * non-intel platforms as it is now, needs fixing */
+static inline unsigned long
+trans_point(struct state *st,
+ int x1, int y1, unsigned long myc, float a,
+ struct field *f)
+{
if ((x1 >= 0) && (x1 < f->width) && (y1 >= 0) && (y1 < f->height)) {
if (a >= 1.0) {
ref_pixel(f, x1, y1) = myc;
} else {
- int or, og, ob;
- int r, g, b;
+ int or = 0, og = 0, ob = 0;
+ int r = 0, g = 0, b = 0;
int nr, ng, nb;
unsigned long c;
}
}
- return 0;
+ return f->bgcolor;
}
-inline void region_color(Display *dpy, Window window, GC fgc, struct field *f, crack *cr) {
+static inline void
+region_color(struct state *st, GC fgc, struct field *f, crack *cr)
+{
/* synthesis of Crack::regionColor() and SandPainter::render() */
float rx = cr->x;
cx = (int) rx;
cy = (int) ry;
+ if (f->seamless) {
+ cx %= f->width;
+ cy %= f->height;
+ }
if ((cx >= 0) && (cx < f->width) && (cy >= 0) && (cy < f->height)) {
/* safe to check */
for (i = 0; i < grains; i++) {
drawx = (cr->x + (rx - cr->x) * sin(cr->sandp + sin((float) i * w)));
drawy = (cr->y + (ry - cr->y) * sin(cr->sandp + sin((float) i * w)));
+ if (f->seamless) {
+ drawx = fmod(drawx + f->width, f->width);
+ drawy = fmod(drawy + f->height, f->height);
+ }
/* Draw sand bit */
- c = trans_point(drawx, drawy, cr->sandcolor, (0.1 - i / (grains * 10.0)), f);
+ c = trans_point(st, drawx, drawy, cr->sandcolor, (0.1 - i / (grains * 10.0)), f);
- XSetForeground(dpy, fgc, c);
- XDrawPoint(dpy, window, fgc, (int) drawx, (int) drawy);
- XSetForeground(dpy, fgc, f->fgcolor);
+ XSetForeground(st->dpy, fgc, c);
+ XDrawPoint(st->dpy, st->window, fgc, (int) drawx, (int) drawy);
+ XSetForeground(st->dpy, fgc, f->fgcolor);
}
}
-void build_substrate(struct field *f) {
- int tx, ty;
+static void build_substrate(struct field *f)
+{
+ int tx;
+ /* int ty; */
f->cycles = 0;
/* erase the crack grid */
f->cgrid = (int *) xrealloc(f->cgrid, sizeof(int) * f->height * f->width);
- memset(f->cgrid, 10001, f->height * f->width * sizeof(int));
+ {
+ int j;
+ int *p = f->cgrid;
+ for (j = 0; j < f->height * f->width; j++)
+ *p++ = 10001;
+ }
- /* make random crack seeds */
+ /* Not necessary now that make_crack ensures we have usable default
+ * values in start_crack's timeout case
+ * make random crack seeds *
for (tx = 0; tx < 16; tx++) {
ty = (int) (random() % (f->width * f->height - 1));
f->cgrid[ty] = (int) random() % 360;
}
-
+ */
+
/* make the initial cracks */
for (tx = 0; tx < f->initial_cracks; tx++)
make_crack(f);
}
-inline void movedrawcrack(Display *dpy, Window window, GC fgc, struct field *f, int cracknum) {
+static inline void
+movedrawcrack(struct state *st, GC fgc, struct field *f, int cracknum)
+{
/* Basically Crack::move() */
int cx, cy;
crack *cr = &(f->cracks[cracknum]);
/* continue cracking */
- cr->x += ((float) 0.42 * cos(cr->t * M_PI/180));
- cr->y += ((float) 0.42 * sin(cr->t * M_PI/180));
+ if ( !cr->curved ) {
+ cr->x += ((float) STEP * cos(cr->t * M_PI/180));
+ cr->y += ((float) STEP * sin(cr->t * M_PI/180));
+ }
+ else {
+ cr->x += ((float) cr->ys * cos(cr->t * M_PI/180));
+ cr->y += ((float) cr->ys * sin(cr->t * M_PI/180));
+
+ cr->x += ((float) cr->xs * cos(cr->t * M_PI/180 - M_PI / 2));
+ cr->y += ((float) cr->xs * sin(cr->t * M_PI/180 - M_PI / 2));
+
+ cr->t += cr->t_inc;
+ cr->degrees_drawn += fabsf(cr->t_inc);
+ }
+ if (f->seamless) {
+ cr->x = fmod(cr->x + f->width, f->width);
+ cr->y = fmod(cr->y + f->height, f->height);
+ }
/* bounds check */
/* modification of random(-0.33,0.33) */
cx = (int) (cr->x + (frand(0.66) - 0.33));
cy = (int) (cr->y + (frand(0.66) - 0.33));
+ if (f->seamless) {
+ cx %= f->width;
+ cy %= f->height;
+ }
if ((cx >= 0) && (cx < f->width) && (cy >= 0) && (cy < f->height)) {
/* draw sand painter if we're not wireframe */
if (!f->wireframe)
- region_color(dpy, window, fgc, f, cr);
+ region_color(st, fgc, f, cr);
/* draw fgcolor crack */
ref_pixel(f, cx, cy) = f->fgcolor;
- XDrawPoint(dpy, window, fgc, cx, cy);
+ XDrawPoint(st->dpy, st->window, fgc, cx, cy);
+ if ( cr->curved && (cr->degrees_drawn > 360) ) {
+ /* completed the circle, stop cracking */
+ start_crack(f, cr); /* restart ourselves */
+ make_crack(f); /* generate a new crack */
+ }
/* safe to check */
- if ((f->cgrid[cy * f->width + cx] > 10000) ||
- (abs(f->cgrid[cy * f->width + cx] - cr->t) < 5)) {
+ else if ((f->cgrid[cy * f->width + cx] > 10000) ||
+ (fabsf(f->cgrid[cy * f->width + cx] - cr->t) < 5)) {
/* continue cracking */
f->cgrid[cy * f->width + cx] = (int) cr->t;
- } else if (abs(f->cgrid[cy * f->width + cx] - cr->t) > 2) {
+ } else if (fabsf(f->cgrid[cy * f->width + cx] - cr->t) > 2) {
/* crack encountered (not self), stop cracking */
start_crack(f, cr); /* restart ourselves */
make_crack(f); /* generate a new crack */
}
} else {
- /* out of bounds, top cracking */
+ /* out of bounds, stop cracking */
+
+ /* need these in case of timeout in start_crack */
+ cr->x = random() % f->width;
+ cr->y = random() % f->height;
+ cr->t = random() % 360;
+
start_crack(f, cr); /* restart ourselves */
make_crack(f); /* generate a new crack */
}
}
-char *progclass = "Substrate";
-char *defaults[] = {
- ".background: white",
- ".foreground: black",
- "*wireFrame: false",
- "*maxCycles: 10000",
- "*growthDelay: 18000",
- "*initialCracks: 3",
- "*maxCracks: 100",
- "*sandGrains: 64",
- 0
-};
-
-XrmOptionDescRec options[] = {
- {"-background", ".background", XrmoptionSepArg, 0},
- {"-foreground", ".foreground", XrmoptionSepArg, 0},
- {"-wireframe", ".wireFrame", XrmoptionNoArg, "true"},
- {"-max-cycles", ".maxCycles", XrmoptionSepArg, 0},
- {"-growth-delay", ".growthDelay", XrmoptionSepArg, 0},
- {"-initial-cracks", ".initialCracks", XrmoptionSepArg, 0},
- {"-max-cracks", ".maxCracks", XrmoptionSepArg, 0},
- {"-sand-grains", ".sandGrains", XrmoptionSepArg, 0},
- {0, 0, 0, 0}
-};
-
-void build_img(Display *dpy, Window window, XWindowAttributes xgwa, GC fgc, struct field *f) {
+static void build_img(Display *dpy, Window window, XWindowAttributes xgwa, GC fgc,
+ struct field *f)
+{
if (f->off_img) {
free(f->off_img);
f->off_img = NULL;
memset(f->off_img, f->bgcolor, sizeof(unsigned long) * f->width * f->height);
}
-void screenhack(Display * dpy, Window window)
-{
- struct field *f = init_field();
-
- unsigned int max_cycles = 0;
- int growth_delay = 0;
- int tempx;
- GC fgc;
- XGCValues gcv;
- XWindowAttributes xgwa;
+static void *
+substrate_init (Display *dpy, Window window)
+{
+ struct state *st = (struct state *) calloc (1, sizeof(*st));
XColor tmpcolor;
- growth_delay = (get_integer_resource("growthDelay", "Integer"));
- max_cycles = (get_integer_resource("maxCycles", "Integer"));
- f->initial_cracks = (get_integer_resource("initialCracks", "Integer"));
- f->max_num = (get_integer_resource("maxCracks", "Integer"));
- f->wireframe = (get_boolean_resource("wireFrame", "Boolean"));
- f->grains = (get_integer_resource("sandGrains", "Integer"));
+ st->dpy = dpy;
+ st->window = window;
+ st->f = init_field();
+
+ st->growth_delay = (get_integer_resource(st->dpy, "growthDelay", "Integer"));
+ st->max_cycles = (get_integer_resource(st->dpy, "maxCycles", "Integer"));
+ st->f->initial_cracks = (get_integer_resource(st->dpy, "initialCracks", "Integer"));
+ st->f->max_num = (get_integer_resource(st->dpy, "maxCracks", "Integer"));
+ st->f->wireframe = (get_boolean_resource(st->dpy, "wireFrame", "Boolean"));
+ st->f->grains = (get_integer_resource(st->dpy, "sandGrains", "Integer"));
+ st->f->circle_percent = (get_integer_resource(st->dpy, "circlePercent", "Integer"));
+ st->f->seamless = (get_boolean_resource(st->dpy, "seamless", "Boolean"));
- if (f->initial_cracks <= 2) {
+ if (st->f->initial_cracks <= 2) {
fprintf(stderr, "%s: Initial cracks must be greater than 2\n", progname);
- return;
+ exit (1);
+ }
+
+ if (st->f->max_num <= 10) {
+ fprintf(stderr, "%s: Maximum number of cracks must be less than 10\n",
+ progname);
+ exit (1);
}
- if (f->max_num <= 10) {
- fprintf(stderr, "%s: Maximum number of cracks must be greater than 2\n", progname);
- return;
+ if (st->f->circle_percent < 0) {
+ fprintf(stderr, "%s: circle percent must be at least 0\n", progname);
+ exit (1);
+ }
+
+ if (st->f->circle_percent > 100) {
+ fprintf(stderr, "%s: circle percent must be less than 100\n", progname);
+ exit (1);
}
- XGetWindowAttributes(dpy, window, &xgwa);
+ XGetWindowAttributes(st->dpy, st->window, &st->xgwa);
- f->height = xgwa.height;
- f->width = xgwa.width;
- f->visdepth = xgwa.depth;
+ st->f->height = st->xgwa.height;
+ st->f->width = st->xgwa.width;
+ st->f->visdepth = st->xgwa.depth;
/* Count the colors in our map and assign them in a horrifically inefficient
* manner but it only happens once */
- while (rgb_colormap[f->numcolors] != NULL) {
- f->parsedcolors = (unsigned long *) xrealloc(f->parsedcolors,
- sizeof(unsigned long) * (f->numcolors + 1));
- if (!XParseColor(dpy, xgwa.colormap, rgb_colormap[f->numcolors], &tmpcolor)) {
+ while (rgb_colormap[st->f->numcolors] != NULL) {
+ st->f->parsedcolors = (unsigned long *) xrealloc(st->f->parsedcolors,
+ sizeof(unsigned long) *
+ (st->f->numcolors + 1));
+ if (!XParseColor(st->dpy, st->xgwa.colormap, rgb_colormap[st->f->numcolors], &tmpcolor)) {
fprintf(stderr, "%s: couldn't parse color %s\n", progname,
- rgb_colormap[f->numcolors]);
+ rgb_colormap[st->f->numcolors]);
exit(1);
}
- if (!XAllocColor(dpy, xgwa.colormap, &tmpcolor)) {
+ if (!XAllocColor(st->dpy, st->xgwa.colormap, &tmpcolor)) {
fprintf(stderr, "%s: couldn't allocate color %s\n", progname,
- rgb_colormap[f->numcolors]);
+ rgb_colormap[st->f->numcolors]);
exit(1);
}
- f->parsedcolors[f->numcolors] = tmpcolor.pixel;
+ st->f->parsedcolors[st->f->numcolors] = tmpcolor.pixel;
- f->numcolors++;
+ st->f->numcolors++;
}
- gcv.foreground = get_pixel_resource("foreground", "Foreground",
- dpy, xgwa.colormap);
- gcv.background = get_pixel_resource("background", "Background",
- dpy, xgwa.colormap);
- fgc = XCreateGC(dpy, window, GCForeground, &gcv);
+ st->gcv.foreground = get_pixel_resource(st->dpy, st->xgwa.colormap,
+ "foreground", "Foreground");
+ st->gcv.background = get_pixel_resource(st->dpy, st->xgwa.colormap,
+ "background", "Background");
+ st->fgc = XCreateGC(st->dpy, st->window, GCForeground, &st->gcv);
- f->fgcolor = gcv.foreground;
- f->bgcolor = gcv.background;
+ st->f->fgcolor = st->gcv.foreground;
+ st->f->bgcolor = st->gcv.background;
/* Initialize stuff */
- build_img(dpy, window, xgwa, fgc, f);
- build_substrate(f);
+ build_img(st->dpy, st->window, st->xgwa, st->fgc, st->f);
+ build_substrate(st->f);
- while (1) {
- if ((f->cycles % 10) == 0) {
- /* Restart if the window size changes */
- XGetWindowAttributes(dpy, window, &xgwa);
-
- if (f->height != xgwa.height || f->width != xgwa.width) {
- f->height = xgwa.height;
- f->width = xgwa.width;
- f->visdepth = xgwa.depth;
-
- build_substrate(f);
- build_img(dpy, window, xgwa, fgc, f);
- XSetForeground(dpy, fgc, gcv.background);
- XFillRectangle(dpy, window, fgc, 0, 0, xgwa.width, xgwa.height);
- XSetForeground(dpy, fgc, gcv.foreground);
- }
- }
+ return st;
+}
- for (tempx = 0; tempx < f->num; tempx++) {
- movedrawcrack(dpy, window, fgc, f, tempx);
- }
+static unsigned long
+substrate_draw (Display *dpy, Window window, void *closure)
+{
+ struct state *st = (struct state *) closure;
+ int tempx;
- f->cycles++;
+ if ((st->f->cycles % 10) == 0) {
- XSync(dpy, False);
+ /* Restart if the window size changes */
+ XGetWindowAttributes(st->dpy, st->window, &st->xgwa);
- screenhack_handle_events(dpy);
+ if (st->f->height != st->xgwa.height || st->f->width != st->xgwa.width) {
+ st->f->height = st->xgwa.height;
+ st->f->width = st->xgwa.width;
+ st->f->visdepth = st->xgwa.depth;
- if (f->cycles >= max_cycles && max_cycles != 0) {
- build_substrate(f);
- build_img(dpy, window, xgwa, fgc, f);
- XSetForeground(dpy, fgc, gcv.background);
- XFillRectangle(dpy, window, fgc, 0, 0, xgwa.width, xgwa.height);
- XSetForeground(dpy, fgc, gcv.foreground);
- }
+ build_substrate(st->f);
+ build_img(st->dpy, st->window, st->xgwa, st->fgc, st->f);
+ XSetForeground(st->dpy, st->fgc, st->gcv.background);
+ XFillRectangle(st->dpy, st->window, st->fgc, 0, 0, st->xgwa.width, st->xgwa.height);
+ XSetForeground(st->dpy, st->fgc, st->gcv.foreground);
+ }
+ }
+
+ for (tempx = 0; tempx < st->f->num; tempx++) {
+ movedrawcrack(st, st->fgc, st->f, tempx);
+ }
+
+ st->f->cycles++;
+
+ if (st->f->cycles >= st->max_cycles && st->max_cycles != 0) {
+ build_substrate(st->f);
+ build_img(st->dpy, st->window, st->xgwa, st->fgc, st->f);
+ XSetForeground(st->dpy, st->fgc, st->gcv.background);
+ XFillRectangle(st->dpy, st->window, st->fgc, 0, 0, st->xgwa.width, st->xgwa.height);
+ XSetForeground(st->dpy, st->fgc, st->gcv.foreground);
+ }
- if (growth_delay)
- usleep(growth_delay);
+ /* #### mi->recursion_depth = st->f->cycles; */
+ return st->growth_delay;
+}
+
+
+static void
+substrate_reshape (Display *dpy, Window window, void *closure,
+ unsigned int w, unsigned int h)
+{
+}
+
+static Bool
+substrate_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+ struct state *st = (struct state *) closure;
+ if (screenhack_event_helper (dpy, window, event))
+ {
+ st->f->cycles = st->max_cycles;
+ return True;
}
+ return False;
}
+
+static void
+substrate_free (Display *dpy, Window window, void *closure)
+{
+ struct state *st = (struct state *) closure;
+ free (st);
+}
+
+static const char *substrate_defaults[] = {
+ ".background: white",
+ ".foreground: black",
+ "*fpsSolid: true",
+ "*wireFrame: false",
+ "*seamless: false",
+ "*maxCycles: 10000",
+ "*growthDelay: 18000",
+ "*initialCracks: 3",
+ "*maxCracks: 100",
+ "*sandGrains: 64",
+ "*circlePercent: 33",
+#ifdef HAVE_MOBILE
+ "*ignoreRotation: True",
+#endif
+ 0
+};
+
+static XrmOptionDescRec substrate_options[] = {
+ {"-background", ".background", XrmoptionSepArg, 0},
+ {"-foreground", ".foreground", XrmoptionSepArg, 0},
+ {"-wireframe", ".wireFrame", XrmoptionNoArg, "true"},
+ {"-seamless", ".seamless", XrmoptionNoArg, "true"},
+ {"-max-cycles", ".maxCycles", XrmoptionSepArg, 0},
+ {"-growth-delay", ".growthDelay", XrmoptionSepArg, 0},
+ {"-initial-cracks", ".initialCracks", XrmoptionSepArg, 0},
+ {"-max-cracks", ".maxCracks", XrmoptionSepArg, 0},
+ {"-sand-grains", ".sandGrains", XrmoptionSepArg, 0},
+ {"-circle-percent", ".circlePercent", XrmoptionSepArg, 0},
+ {0, 0, 0, 0}
+};
+
+XSCREENSAVER_MODULE ("Substrate", substrate)