X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fccurve.c;h=02cb0ba329e87da2dd375f9c2f59b983384342b6;hp=efe5915c0137894b5da1d7affa6eaded962e3ef1;hb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;hpb=ccb7f4903325f92555a9722bba74b58346654ba0 diff --git a/hacks/ccurve.c b/hacks/ccurve.c index efe5915c..02cb0ba3 100644 --- a/hacks/ccurve.c +++ b/hacks/ccurve.c @@ -50,21 +50,50 @@ typedef struct Segment_struct } Segment; -static int color_count = 0; -static int color_index = 0; -static Colormap color_map = (Colormap)NULL; -static XColor colors [MAXIMUM_COLOR_COUNT]; -static int line_count = 0; -static int maximum_lines = 0; -static double plot_maximum_x = -1000.00; -static double plot_maximum_y = -1000.00; -static double plot_minimum_x = 1000.00; -static double plot_minimum_y = 1000.00; -static int total_lines = 0; +struct state { + Display *dpy; + Window window; + + int color_count; + int color_index; + Colormap color_map; + XColor colors [MAXIMUM_COLOR_COUNT]; + int line_count; + int maximum_lines; + double plot_maximum_x; + double plot_maximum_y; + double plot_minimum_x; + double plot_minimum_y; + int total_lines; + + unsigned long int background; + GC context; + Pixmap pixmap; + int width; + int height; + float delay; + float delay2; + + int draw_index; + + int draw_iterations; + double draw_maximum_x; + double draw_maximum_y; + double draw_minimum_x; + double draw_minimum_y; + int draw_segment_count; + Segment* draw_segments; + double draw_x1; + double draw_y1; + double draw_x2; + double draw_y2; +}; + + + /* normalize alters the sequence to go from (0,0) to (1,0) */ -static -void +static void normalized_plot (int segment_count, Segment* segments, Position* points) @@ -102,8 +131,7 @@ normalized_plot (int segment_count, } } -static -void +static void copy_points (int segment_count, Position* source, Position* target) @@ -116,8 +144,7 @@ copy_points (int segment_count, } } -static -void +static void realign (double x1, double y1, double x2, @@ -151,13 +178,8 @@ realign (double x1, } } -static -void -self_similar_normalized (Display* display, - Pixmap pixmap, - GC context, - int width, - int height, +static void +self_similar_normalized (struct state *st, int iterations, double x1, double y1, @@ -174,23 +196,23 @@ self_similar_normalized (Display* display, { double delta_x = maximum_x - minimum_x; double delta_y = maximum_y - minimum_y; - color_index = (int)(((double)(line_count * color_count)) - / ((double)total_lines)); - ++line_count; - XSetForeground (display, context, colors [color_index].pixel); - if (plot_maximum_x < x1) plot_maximum_x = x1; - if (plot_maximum_x < x2) plot_maximum_x = x2; - if (plot_maximum_y < y1) plot_maximum_y = y1; - if (plot_maximum_y < y2) plot_maximum_y = y2; - if (plot_minimum_x > x1) plot_minimum_x = x1; - if (plot_minimum_x > x2) plot_minimum_x = x2; - if (plot_minimum_y > y1) plot_minimum_y = y1; - if (plot_minimum_y > y2) plot_minimum_y = y2; - XDrawLine (display, pixmap, context, - (int)(((x1 - minimum_x) / delta_x) * width), - (int)(((maximum_y - y1) / delta_y) * height), - (int)(((x2 - minimum_x) / delta_x) * width), - (int)(((maximum_y - y2) / delta_y) * height)); + st->color_index = (int)(((double)(st->line_count * st->color_count)) + / ((double)st->total_lines)); + ++st->line_count; + XSetForeground (st->dpy, st->context, st->colors [st->color_index].pixel); + if (st->plot_maximum_x < x1) st->plot_maximum_x = x1; + if (st->plot_maximum_x < x2) st->plot_maximum_x = x2; + if (st->plot_maximum_y < y1) st->plot_maximum_y = y1; + if (st->plot_maximum_y < y2) st->plot_maximum_y = y2; + if (st->plot_minimum_x > x1) st->plot_minimum_x = x1; + if (st->plot_minimum_x > x2) st->plot_minimum_x = x2; + if (st->plot_minimum_y > y1) st->plot_minimum_y = y1; + if (st->plot_minimum_y > y2) st->plot_minimum_y = y2; + XDrawLine (st->dpy, st->pixmap, st->context, + (int)(((x1 - minimum_x) / delta_x) * st->width), + (int)(((maximum_y - y1) / delta_y) * st->height), + (int)(((x2 - minimum_x) / delta_x) * st->width), + (int)(((maximum_y - y2) / delta_y) * st->height)); } else { @@ -214,7 +236,7 @@ self_similar_normalized (Display* display, { next_x = replacement [index].x; next_y = replacement [index].y; - self_similar_normalized (display, pixmap, context, width, height, + self_similar_normalized (st, iterations - 1, x, y, next_x, next_y, maximum_x, maximum_y, minimum_x, minimum_y, @@ -226,9 +248,8 @@ self_similar_normalized (Display* display, } } -static -void -self_similar (Display* display, +static void +self_similar (struct state *st, Pixmap pixmap, GC context, int width, @@ -251,8 +272,7 @@ self_similar (Display* display, normalized_plot (segment_count, segments, points); assert (fabs ((points [segment_count - 1].x) - 1.0) < EPSILON); assert (fabs (points [segment_count - 1].y) < EPSILON); - self_similar_normalized (display, pixmap, context, - width, height, iterations, + self_similar_normalized (st, iterations, x1, y1, x2, y2, maximum_x, maximum_y, minimum_x, minimum_y, @@ -276,8 +296,7 @@ random_double (double base, return base + ((random () % steps) * epsilon); } -static -void +static void select_2_pattern (Segment* segments) { if ((random () % 2) == 0) @@ -317,8 +336,7 @@ select_2_pattern (Segment* segments) } } -static -void +static void select_3_pattern (Segment* segments) { switch (random () % 5) @@ -394,8 +412,7 @@ select_3_pattern (Segment* segments) } } -static -void +static void select_4_pattern (Segment* segments) { switch (random () % 9) @@ -640,156 +657,179 @@ select_pattern (int segment_count, } } -char *progclass = "Ccurve"; - -char *defaults [] = -{ - ".background: black", - ".foreground: white", - ".delay: 1", - ".pause: 3", - ".limit: 200000", - 0 -}; - -XrmOptionDescRec options [] = -{ - { "-delay", ".delay", XrmoptionSepArg, 0 }, - { "-pause", ".pause", XrmoptionSepArg, 0 }, - { "-limit", ".limit", XrmoptionSepArg, 0 }, - { 0, 0, 0, 0 } -}; - #define Y_START (0.5) -void -screenhack (Display* display, - Window window) +static void * +ccurve_init (Display *dpy, Window window) { - unsigned long int background = 0; + struct state *st = (struct state *) calloc (1, sizeof(*st)); unsigned long int black = 0; - GC context; - int delay = 0; int depth = 0; - Pixmap pixmap = (Pixmap)NULL; XWindowAttributes hack_attributes; - int height = 0; - int iterations = 0; - int pause = 0; XGCValues values; unsigned long int white = 0; - int width = 0; - - delay = get_integer_resource ("delay", "Integer"); - pause = get_integer_resource ("pause", "Integer"); - maximum_lines = get_integer_resource ("limit", "Integer"); - black = BlackPixel (display, DefaultScreen (display)); - white = WhitePixel (display, DefaultScreen (display)); - background = black; - XGetWindowAttributes (display, window, &hack_attributes); - width = hack_attributes.width; - height = hack_attributes.height; + + st->dpy = dpy; + st->window = window; + + st->delay = get_float_resource (st->dpy, "delay", "Integer"); + st->delay2 = get_float_resource (st->dpy, "pause", "Integer"); + st->maximum_lines = get_integer_resource (st->dpy, "limit", "Integer"); + black = BlackPixel (st->dpy, DefaultScreen (st->dpy)); + white = WhitePixel (st->dpy, DefaultScreen (st->dpy)); + st->background = black; + XGetWindowAttributes (st->dpy, st->window, &hack_attributes); + st->width = hack_attributes.width; + st->height = hack_attributes.height; depth = hack_attributes.depth; - color_map = hack_attributes.colormap; - pixmap = XCreatePixmap (display, window, width, height, depth); + st->color_map = hack_attributes.colormap; + st->pixmap = XCreatePixmap (st->dpy, st->window, st->width, st->height, depth); values.foreground = white; values.background = black; - context = XCreateGC (display, window, GCForeground | GCBackground, + st->context = XCreateGC (st->dpy, st->window, GCForeground | GCBackground, &values); - color_count = MAXIMUM_COLOR_COUNT; - make_color_loop (display, color_map, + st->color_count = MAXIMUM_COLOR_COUNT; + make_color_loop (st->dpy, st->color_map, 0, 1, 1, 120, 1, 1, 240, 1, 1, - colors, &color_count, True, False); - if (color_count <= 0) + st->colors, &st->color_count, True, False); + if (st->color_count <= 0) { - color_count = 1; - colors [0].red = colors [0].green = colors [0].blue = 0xFFFF; - XAllocColor (display, color_map, &colors [0]); + st->color_count = 1; + st->colors [0].red = st->colors [0].green = st->colors [0].blue = 0xFFFF; + XAllocColor (st->dpy, st->color_map, &st->colors [0]); } - while (1) - { - int index = 0; - double maximum_x = 1.20; - double maximum_y = 0.525; - double minimum_x = -0.20; - double minimum_y = -0.525; - static int lengths [] = { 4, 4, 4, 4, 4, 3, 3, 3, 2 }; - int segment_count = 0; - Segment* segments = (Segment*)NULL; - double x1 = 0.0; - double y1 = 0.0; - double x2 = 1.0; - double y2 = 0.0; - - segment_count + st->draw_maximum_x = 1.20; + st->draw_maximum_y = 0.525; + st->draw_minimum_x = -0.20; + st->draw_minimum_y = -0.525; + st->draw_x2 = 1.0; + + return st; +} + +static unsigned long +ccurve_draw (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; + static const int lengths [] = { 4, 4, 4, 4, 4, 3, 3, 3, 2 }; + + if (st->draw_index == 0) + { + st->draw_segment_count = lengths [random () % (sizeof (lengths) / sizeof (int))]; - segments - = (Segment*)(malloc ((segment_count) * sizeof (Segment))); - select_pattern (segment_count, segments); - iterations = floor (log (maximum_lines) - / log (((double)(segment_count)))); + st->draw_segments + = (Segment*)(malloc ((st->draw_segment_count) * sizeof (Segment))); + select_pattern (st->draw_segment_count, st->draw_segments); + st->draw_iterations = floor (log (st->maximum_lines) + / log (((double)(st->draw_segment_count)))); if ((random () % 3) != 0) { double factor = 0.45; - x1 += random_double (-factor, factor, 0.001); - y1 += random_double (-factor, factor, 0.001); - x2 += random_double (-factor, factor, 0.001); - y2 += random_double (-factor, factor, 0.001); + st->draw_x1 += random_double (-factor, factor, 0.001); + st->draw_y1 += random_double (-factor, factor, 0.001); + st->draw_x2 += random_double (-factor, factor, 0.001); + st->draw_y2 += random_double (-factor, factor, 0.001); } /* background = (random () % 2) ? black : white; */ - for (index = 0; index < iterations; ++index) + + } + + /* for (st->draw_index = 0; st->draw_index < st->draw_iterations; ++st->draw_index) */ { double delta_x = 0.0; double delta_y = 0.0; - XSetForeground (display, context, background); - XFillRectangle (display, pixmap, context, 0, 0, width, height); - line_count = 0; - total_lines = (int)(pow ((double)(segment_count), - (double)index)); - plot_maximum_x = -1000.00; - plot_maximum_y = -1000.00; - plot_minimum_x = 1000.00; - plot_minimum_y = 1000.00; - self_similar (display, pixmap, context, width, height, index, - x1, y1, x2, y2, - maximum_x, - maximum_y, - minimum_x, - minimum_y, - segment_count, segments); - delta_x = plot_maximum_x - plot_minimum_x; - delta_y = plot_maximum_y - plot_minimum_y; - maximum_x = plot_maximum_x + (delta_x * 0.2); - maximum_y = plot_maximum_y + (delta_y * 0.2); - minimum_x = plot_minimum_x - (delta_x * 0.2); - minimum_y = plot_minimum_y - (delta_y * 0.2); - delta_x = maximum_x - minimum_x; - delta_y = maximum_y - minimum_y; - if ((delta_y / delta_x) > (((double)height) / ((double)width))) + XSetForeground (st->dpy, st->context, st->background); + XFillRectangle (st->dpy, st->pixmap, st->context, 0, 0, st->width, st->height); + st->line_count = 0; + st->total_lines = (int)(pow ((double)(st->draw_segment_count), + (double)st->draw_index)); + st->plot_maximum_x = -1000.00; + st->plot_maximum_y = -1000.00; + st->plot_minimum_x = 1000.00; + st->plot_minimum_y = 1000.00; + self_similar (st, st->pixmap, st->context, st->width, st->height, st->draw_index, + st->draw_x1, st->draw_y1, st->draw_x2, st->draw_y2, + st->draw_maximum_x, + st->draw_maximum_y, + st->draw_minimum_x, + st->draw_minimum_y, + st->draw_segment_count, st->draw_segments); + delta_x = st->plot_maximum_x - st->plot_minimum_x; + delta_y = st->plot_maximum_y - st->plot_minimum_y; + st->draw_maximum_x = st->plot_maximum_x + (delta_x * 0.2); + st->draw_maximum_y = st->plot_maximum_y + (delta_y * 0.2); + st->draw_minimum_x = st->plot_minimum_x - (delta_x * 0.2); + st->draw_minimum_y = st->plot_minimum_y - (delta_y * 0.2); + delta_x = st->draw_maximum_x - st->draw_minimum_x; + delta_y = st->draw_maximum_y - st->draw_minimum_y; + if ((delta_y / delta_x) > (((double)st->height) / ((double)st->width))) { double new_delta_x - = (delta_y * ((double)width)) / ((double)height); - minimum_x -= (new_delta_x - delta_x) / 2.0; - maximum_x += (new_delta_x - delta_x) / 2.0; + = (delta_y * ((double)st->width)) / ((double)st->height); + st->draw_minimum_x -= (new_delta_x - delta_x) / 2.0; + st->draw_maximum_x += (new_delta_x - delta_x) / 2.0; } else { double new_delta_y - = (delta_x * ((double)height)) / ((double)width); - minimum_y -= (new_delta_y - delta_y) / 2.0; - maximum_y += (new_delta_y - delta_y) / 2.0; + = (delta_x * ((double)st->height)) / ((double)st->width); + st->draw_minimum_y -= (new_delta_y - delta_y) / 2.0; + st->draw_maximum_y += (new_delta_y - delta_y) / 2.0; } - XCopyArea (display, pixmap, window, context, 0, 0, width, height, + XCopyArea (st->dpy, st->pixmap, st->window, st->context, 0, 0, st->width, st->height, 0, 0); - if (delay) sleep (delay); - screenhack_handle_events (display); } - free((void*)segments); - if (pause) sleep (pause); - erase_full_window (display, window); - } + st->draw_index++; + + if (st->draw_index >= st->draw_iterations) + { + st->draw_index = 0; + free((void*)st->draw_segments); + st->draw_segments = 0; + return (int) (1000000 * st->delay); + } + else + return (int) (1000000 * st->delay2); +} + +static void +ccurve_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ +} + +static Bool +ccurve_event (Display *dpy, Window window, void *closure, XEvent *event) +{ + return False; +} + +static void +ccurve_free (Display *dpy, Window window, void *closure) +{ } + + +static const char *ccurve_defaults [] = +{ + ".background: black", + ".foreground: white", + ".delay: 3", + ".pause: 0.4", + ".limit: 200000", + 0 +}; + +static XrmOptionDescRec ccurve_options [] = +{ + { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-pause", ".pause", XrmoptionSepArg, 0 }, + { "-limit", ".limit", XrmoptionSepArg, 0 }, + { 0, 0, 0, 0 } +}; + +XSCREENSAVER_MODULE ("CCurve", ccurve)