From d3a98cf6cbc3bd0b9efc570f58e8812c03931c18 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 16 Oct 2018 10:08:48 +0200 Subject: Original 5.40 --- hacks/wander.c | 280 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 hacks/wander.c (limited to 'hacks/wander.c') diff --git a/hacks/wander.c b/hacks/wander.c new file mode 100644 index 0000000..50fe255 --- /dev/null +++ b/hacks/wander.c @@ -0,0 +1,280 @@ +/* wander, by Rick Campbell , 19 December 1998. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#include + +#include "screenhack.h" +#include "colors.h" +#include "erase.h" + +#define MAXIMUM_COLOR_COUNT (256) + +struct state { + Display *dpy; + Window window; + + unsigned int advance; + Bool circles; + Colormap color_map; + int color_count; + int color_index; + XColor colors [MAXIMUM_COLOR_COUNT]; + GC context; + unsigned int density; + int depth; + int height; + unsigned int length; + unsigned int reset; + Bool reset_p; + unsigned int size; + int width; + int delay; + + int x, y, last_x, last_y, width_1, height_1, length_limit, reset_limit; + unsigned long color; + Pixmap pixmap; + + eraser_state *eraser; +}; + + +static void * +wander_init (Display *dpy, Window window) +{ + struct state *st = (struct state *) calloc (1, sizeof(*st)); + XGCValues values; + XWindowAttributes attributes; + + st->dpy = dpy; + st->window = window; + st->delay = get_integer_resource (st->dpy, "delay", "Integer"); + + XClearWindow (st->dpy, st->window); + XGetWindowAttributes (st->dpy, st->window, &attributes); + st->width = attributes.width; + st->height = attributes.height; + st->depth = attributes.depth; + st->color_map = attributes.colormap; + if (st->color_count) + { + free_colors (attributes.screen, st->color_map, + st->colors, st->color_count); + st->color_count = 0; + } + st->context = XCreateGC (st->dpy, st->window, 0, &values); + st->color_count = MAXIMUM_COLOR_COUNT; + make_color_loop (attributes.screen, attributes.visual, st->color_map, + 0, 1, 1, + 120, 1, 1, + 240, 1, 1, + st->colors, &st->color_count, True, False); + if (st->color_count <= 0) + { + st->color_count = 2; + st->colors [0].red = st->colors [0].green = st->colors [0].blue = 0; + st->colors [1].red = st->colors [1].green = st->colors [1].blue = 0xFFFF; + XAllocColor (st->dpy, st->color_map, &st->colors [0]); + XAllocColor (st->dpy, st->color_map, &st->colors [1]); + } + st->color_index = NRAND (st->color_count); + + st->advance = get_integer_resource (st->dpy, "advance", "Integer"); + st->density = get_integer_resource (st->dpy, "density", "Integer"); + if (st->density < 1) st->density = 1; + st->reset = get_integer_resource (st->dpy, "reset", "Integer"); + if (st->reset < 100) st->reset = 100; + st->circles = get_boolean_resource (st->dpy, "circles", "Boolean"); + st->size = get_integer_resource (st->dpy, "size", "Integer"); + if (st->size < 1) st->size = 1; + st->width = st->width / st->size; + st->height = st->height / st->size; + st->length = get_integer_resource (st->dpy, "length", "Integer"); + if (st->length < 1) st->length = 1; + XSetForeground (st->dpy, st->context, st->colors [st->color_index].pixel); + + + st->x = NRAND (st->width); + st->y = NRAND (st->height); + st->last_x = st->x; + st->last_y = st->y; + st->width_1 = st->width - 1; + st->height_1 = st->height - 1; + st->length_limit = st->length; + st->reset_limit = st->reset; + st->color_index = NRAND (st->color_count); + st->color = st->colors [NRAND (st->color_count)].pixel; + st->pixmap = XCreatePixmap (st->dpy, window, st->size, + st->size, st->depth); + + XSetForeground (st->dpy, st->context, + BlackPixel (st->dpy, DefaultScreen (st->dpy))); + XFillRectangle (st->dpy, st->pixmap, st->context, 0, 0, + st->width * st->size, st->height * st->size); + XSetForeground (st->dpy, st->context, st->color); + XFillArc (st->dpy, st->pixmap, st->context, 0, 0, st->size, st->size, 0, 360*64); + + return st; +} + + +static unsigned long +wander_draw (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; + int i; + + if (st->eraser) { + st->eraser = erase_window (st->dpy, st->window, st->eraser); + goto END; + } + + for (i = 0; i < 2000; i++) + { + if (NRAND (st->density)) + { + st->x = st->last_x; + st->y = st->last_y; + } + else + { + st->last_x = st->x; + st->last_y = st->y; + st->x += st->width_1 + NRAND (3); + while (st->x >= st->width) + st->x -= st->width; + st->y += st->height_1 + NRAND (3); + while (st->y >= st->height) + st->y -= st->height; + } + + if (NRAND (st->length_limit) == 0) + { + if (st->advance == 0) + { + st->color_index = NRAND (st->color_count); + } + else + { + st->color_index = (st->color_index + st->advance) % st->color_count; + } + st->color = st->colors [st->color_index].pixel; + XSetForeground (st->dpy, st->context, st->color); + if (st->circles) + { + XFillArc (st->dpy, st->pixmap, st->context, + 0, 0, st->size, st->size, 0, 360 * 64); + } + } + + if (st->reset_p || NRAND (st->reset_limit) == 0) + { + st->reset_p = 0; + st->eraser = erase_window (st->dpy, st->window, st->eraser); + st->color = st->colors [NRAND (st->color_count)].pixel; + st->x = NRAND (st->width); + st->y = NRAND (st->height); + st->last_x = st->x; + st->last_y = st->y; + if (st->circles) + { + XFillArc (st->dpy, st->pixmap, st->context, 0, 0, st->size, st->size, 0, 360*64); + } + } + + if (st->size == 1) + { + XDrawPoint (st->dpy, st->window, st->context, st->x, st->y); + } + else + { + if (st->circles) + { + XCopyArea (st->dpy, st->pixmap, st->window, st->context, 0, 0, st->size, st->size, + st->x * st->size, st->y * st->size); + } + else + { + XFillRectangle (st->dpy, st->window, st->context, st->x * st->size, st->y * st->size, + st->size, st->size); + } + } + } + + END: + return st->delay; +} + + +static void +wander_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ + struct state *st = (struct state *) closure; + st->width = w / st->size; + st->height = h / st->size; + st->width_1 = st->width - 1; + st->height_1 = st->height - 1; +} + +static Bool +wander_event (Display *dpy, Window window, void *closure, XEvent *event) +{ + struct state *st = (struct state *) closure; + if (screenhack_event_helper (dpy, window, event)) + { + st->reset_p = 1; + return True; + } + return False; +} + +static void +wander_free (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; + XFreeGC (st->dpy, st->context); + free (st); +} + +static const char *wander_defaults [] = +{ + ".lowrez: true", + ".background: black", + ".foreground: white", + ".fpsSolid: true", + ".advance: 1", + ".density: 2", + ".length: 25000", + ".delay: 20000", + ".reset: 2500000", + ".circles: False", + ".size: 1", +#ifdef HAVE_MOBILE + "*ignoreRotation: True", +#endif + 0 +}; + +static XrmOptionDescRec wander_options [] = +{ + { "-advance", ".advance", XrmoptionSepArg, 0 }, + { "-circles", ".circles", XrmoptionNoArg, "True" }, + { "-no-circles",".circles", XrmoptionNoArg, "False" }, + { "-density", ".density", XrmoptionSepArg, 0 }, + { "-length", ".length", XrmoptionSepArg, 0 }, + { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-reset", ".reset", XrmoptionSepArg, 0 }, + { "-size", ".size", XrmoptionSepArg, 0 }, + { 0, 0, 0, 0 } +}; + + +XSCREENSAVER_MODULE ("Wander", wander) -- cgit v1.2.3-55-g7522