diff options
Diffstat (limited to 'hacks/halftone.c')
| -rw-r--r-- | hacks/halftone.c | 409 |
1 files changed, 0 insertions, 409 deletions
diff --git a/hacks/halftone.c b/hacks/halftone.c deleted file mode 100644 index c4e2667..0000000 --- a/hacks/halftone.c +++ /dev/null @@ -1,409 +0,0 @@ -/* halftone, Copyright (c) 2002 by Peter Jaric <peter@jaric.org> - * - * 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. - * - * Description: - * Draws the gravitational force in each point on the screen seen - * through a halftone dot pattern. The force is calculated from a set - * of moving mass points. View it from a distance for best effect. - */ - -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include "screenhack.h" - -#define DEFAULT_DELAY 10000 -#define DEFAULT_SPACING 14 -#define DEFAULT_SIZE_FACTOR 1.5 -#define DEFAULT_COUNT 10 -#define DEFAULT_MIN_MASS 0.001 -#define DEFAULT_MAX_MASS 0.02 -#define DEFAULT_MIN_SPEED 0.001 -#define DEFAULT_MAX_SPEED 0.02 - - -typedef struct -{ - /* halftone dots */ - double * dots; - int dots_width; - int dots_height; - int spacing; - int max_dot_size; - - /* Moving gravity points */ - int gravity_point_count; - - double* gravity_point_x; - double* gravity_point_y; - double* gravity_point_mass; - double* gravity_point_x_inc; - double* gravity_point_y_inc; - - /* X stuff */ - Display *dpy; - Window window; - GC gc; - - int ncolors; - XColor *colors; - int color0, color1; - int color_tick, cycle_speed; - - /* Off screen buffer */ - Pixmap buffer; - GC buffer_gc; - int buffer_width; - int buffer_height; - - int delay; - -} halftone_screen; - - -static void update_buffer(halftone_screen *halftone, XWindowAttributes * attrs) -{ - if (halftone->buffer_width != attrs->width || - halftone->buffer_height != attrs->height) - { - XGCValues gc_values; - - if (halftone->buffer_width != -1 && - halftone->buffer_height != -1) - { - if (halftone->buffer != halftone->window) - XFreePixmap(halftone->dpy, halftone->buffer); - XFreeGC(halftone->dpy, halftone->buffer_gc); - } - - halftone->buffer_width = attrs->width; - halftone->buffer_height = attrs->height; -#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */ - halftone->buffer = halftone->window; -#else - halftone->buffer = XCreatePixmap(halftone->dpy, halftone->window, halftone->buffer_width, halftone->buffer_height, attrs->depth); -#endif - - halftone->buffer_gc = XCreateGC(halftone->dpy, halftone->buffer, 0, &gc_values); - } -} - -static void update_dot_attributes(halftone_screen *halftone, XWindowAttributes * attrs) -{ - double dots_width = attrs->width / halftone->spacing + 1; - double dots_height = attrs->height / halftone->spacing + 1; - - if (halftone->dots == NULL || - (dots_width != halftone->dots_width || - dots_height != halftone->dots_height)) - { - if (halftone->dots != NULL) - free(halftone->dots); - - halftone->dots_width = dots_width; - halftone->dots_height = dots_height; - halftone->dots = (double *) malloc(halftone->dots_width * halftone->dots_height * sizeof(double)); - } -} - -static void * -halftone_init (Display *dpy, Window window) -{ - int x, y, i; - int count; - int spacing; - double factor; - double min_mass; - double max_mass; - double min_speed; - double max_speed; - XGCValues gc_values; - XWindowAttributes attrs; - halftone_screen *halftone; - - halftone = (halftone_screen *) calloc (1, sizeof(halftone_screen)); - - halftone->dpy = dpy; - halftone->window = window; - - halftone->delay = get_integer_resource (dpy, "delay", "Integer"); - halftone->delay = (halftone->delay < 0 ? DEFAULT_DELAY : halftone->delay); - - halftone->gc = XCreateGC (halftone->dpy, halftone->window, 0, &gc_values); - - halftone->buffer_width = -1; - halftone->buffer_height = -1; - halftone->dots = NULL; - - /* Read command line arguments and set all settings. */ - count = get_integer_resource (dpy, "count", "Count"); - halftone->gravity_point_count = count < 1 ? DEFAULT_COUNT : count; - - spacing = get_integer_resource (dpy, "spacing", "Integer"); - halftone->spacing = spacing < 1 ? DEFAULT_SPACING : spacing; - - factor = get_float_resource (dpy, "sizeFactor", "Double"); - halftone->max_dot_size = - (factor < 0 ? DEFAULT_SIZE_FACTOR : factor) * halftone->spacing; - - min_mass = get_float_resource (dpy, "minMass", "Double"); - min_mass = min_mass < 0 ? DEFAULT_MIN_MASS : min_mass; - - max_mass = get_float_resource (dpy, "maxMass", "Double"); - max_mass = max_mass < 0 ? DEFAULT_MAX_MASS : max_mass; - max_mass = max_mass < min_mass ? min_mass : max_mass; - - min_speed = get_float_resource (dpy, "minSpeed", "Double"); - min_speed = min_speed < 0 ? DEFAULT_MIN_SPEED : min_speed; - - max_speed = get_float_resource (dpy, "maxSpeed", "Double"); - max_speed = max_speed < 0 ? DEFAULT_MAX_SPEED : max_speed; - max_speed = max_speed < min_speed ? min_speed : max_speed; - - - /* Set up the moving gravity points. */ - halftone->gravity_point_x = (double *) malloc(halftone->gravity_point_count * sizeof(double)); - halftone->gravity_point_y = (double *) malloc(halftone->gravity_point_count * sizeof(double)); - halftone->gravity_point_mass = (double *) malloc(halftone->gravity_point_count * sizeof(double)); - halftone->gravity_point_x_inc = (double *) malloc(halftone->gravity_point_count * sizeof(double)); - halftone->gravity_point_y_inc = (double *) malloc(halftone->gravity_point_count * sizeof(double)); - - for (i = 0; i < halftone->gravity_point_count; i++) - { - halftone->gravity_point_x[i] = frand(1); - halftone->gravity_point_y[i] = frand(1); - halftone->gravity_point_mass[i] = min_mass + (max_mass - min_mass) * frand(1); - halftone->gravity_point_x_inc[i] = min_speed + (max_speed - min_speed) * frand(1); - halftone->gravity_point_y_inc[i] = min_speed + (max_speed - min_speed) * frand(1); - } - - - /* Set up the dots. */ - XGetWindowAttributes(halftone->dpy, halftone->window, &attrs); - - halftone->ncolors = get_integer_resource (dpy, "colors", "Colors"); - if (halftone->ncolors < 4) halftone->ncolors = 4; - halftone->colors = (XColor *) calloc(halftone->ncolors, sizeof(XColor)); - make_smooth_colormap (attrs.screen, attrs.visual, attrs.colormap, - halftone->colors, &halftone->ncolors, - True, 0, False); - halftone->color0 = 0; - halftone->color1 = halftone->ncolors / 2; - halftone->cycle_speed = get_integer_resource (dpy, "cycleSpeed", "CycleSpeed"); - halftone->color_tick = 0; - - update_buffer(halftone, &attrs); - update_dot_attributes(halftone, &attrs); - - for (x = 0; x < halftone->dots_width; x++) - for (y = 0; y < halftone->dots_height; y++) - { - halftone->dots[x + y * halftone->dots_width] = 0; - } - - return halftone; -} - - - -static void fill_circle(Display *dpy, Window window, GC gc, int x, int y, int size) -{ - int start_x = x - (size / 2); - int start_y = y - (size / 2); - unsigned int width = size; - unsigned int height = size; - int angle1 = 0; - int angle2 = 360 * 64; /* A full circle */ - - XFillArc (dpy, window, gc, - start_x, start_y, width, height, - angle1, angle2); -} - -static void repaint_halftone(halftone_screen *halftone) -{ - int x, y; - /* - int x_offset = halftone->spacing / 2; - int y_offset = halftone->spacing / 2; - */ - int x_offset = 0; - int y_offset = 0; - - - /* Fill buffer with background color */ - XSetForeground (halftone->dpy, halftone->buffer_gc, - halftone->colors[halftone->color0].pixel); - XFillRectangle(halftone->dpy, halftone->buffer, halftone->buffer_gc, 0, 0, halftone->buffer_width, halftone->buffer_height); - - /* Draw dots on buffer */ - XSetForeground (halftone->dpy, halftone->buffer_gc, - halftone->colors[halftone->color1].pixel); - - if (halftone->color_tick++ >= halftone->cycle_speed) - { - halftone->color_tick = 0; - halftone->color0 = (halftone->color0 + 1) % halftone->ncolors; - halftone->color1 = (halftone->color1 + 1) % halftone->ncolors; - } - - for (x = 0; x < halftone->dots_width; x++) - for (y = 0; y < halftone->dots_height; y++) - fill_circle(halftone->dpy, halftone->buffer, halftone->buffer_gc, - x_offset + x * halftone->spacing, y_offset + y * halftone->spacing, - halftone->max_dot_size * halftone->dots[x + y * halftone->dots_width]); - - /* Copy buffer to window */ - if (halftone->buffer != halftone->window) - XCopyArea(halftone->dpy, halftone->buffer, halftone->window, halftone->gc, 0, 0, halftone->buffer_width, halftone->buffer_height, 0, 0); -} - -static double calculate_gravity(halftone_screen *halftone, int x, int y) -{ - int i; - double gx = 0; - double gy = 0; - - for (i = 0; i < halftone->gravity_point_count; i++) - { - double dx = ((double) x) - halftone->gravity_point_x[i] * halftone->dots_width; - double dy = ((double) y) - halftone->gravity_point_y[i] * halftone->dots_height; - double distance = sqrt(dx * dx + dy * dy); - - if (distance != 0) - { - double gravity = halftone->gravity_point_mass[i] / (distance * distance / (halftone->dots_width * halftone->dots_height)); - - gx += (dx / distance) * gravity; - gy += (dy / distance) * gravity; - } - } - - return sqrt(gx * gx + gy * gy); -} - -static void update_halftone(halftone_screen *halftone) -{ - int x, y, i; - XWindowAttributes attrs; - - XGetWindowAttributes(halftone->dpy, halftone->window, &attrs); - - /* Make sure we have a valid buffer */ - update_buffer(halftone, &attrs); - - /* Make sure all dot attributes (spacing, width, height, etc) are correct */ - update_dot_attributes(halftone, &attrs); - - /* Move gravity points */ - for (i = 0; i < halftone->gravity_point_count; i++) - { - halftone->gravity_point_x_inc[i] = - (halftone->gravity_point_x[i] >= 1 || halftone->gravity_point_x[i] <= 0 ? - -halftone->gravity_point_x_inc[i] : - halftone->gravity_point_x_inc[i]); - halftone->gravity_point_y_inc[i] = - (halftone->gravity_point_y[i] >= 1 || halftone->gravity_point_y[i] <= 0 ? - -halftone->gravity_point_y_inc[i] : - halftone->gravity_point_y_inc[i]); - - halftone->gravity_point_x[i] += halftone->gravity_point_x_inc[i]; - halftone->gravity_point_y[i] += halftone->gravity_point_y_inc[i]; - } - - /* Update gravity in each dot .*/ - for (x = 0; x < halftone->dots_width; x++) - for (y = 0; y < halftone->dots_height; y++) - { - double gravity = calculate_gravity(halftone, x, y); - - halftone->dots[x + y * halftone->dots_width] = (gravity > 1 ? 1 : (gravity < 0 ? 0 : gravity)); - } -} - - -static unsigned long -halftone_draw (Display *dpy, Window window, void *closure) -{ - halftone_screen *halftone = (halftone_screen *) closure; - - repaint_halftone(halftone); - update_halftone(halftone); - - return halftone->delay; -} - - -static void -halftone_reshape (Display *dpy, Window window, void *closure, - unsigned int w, unsigned int h) -{ -} - -static Bool -halftone_event (Display *dpy, Window window, void *closure, XEvent *event) -{ - return False; -} - -static void -halftone_free (Display *dpy, Window window, void *closure) -{ - halftone_screen *halftone = (halftone_screen *) closure; - free (halftone->gravity_point_x); - free (halftone->gravity_point_y); - free (halftone->gravity_point_mass); - free (halftone->gravity_point_x_inc); - free (halftone->gravity_point_y_inc); - free (halftone->dots); - free (halftone->colors); - if (halftone->buffer && halftone->buffer != halftone->window) - XFreePixmap (dpy, halftone->buffer); - if (halftone->gc) XFreeGC (dpy, halftone->gc); - if (halftone->buffer_gc) XFreeGC (dpy, halftone->buffer_gc); - free (halftone); -} - - -static const char *halftone_defaults [] = { - ".background: Black", - "*delay: 10000", - "*count: 10", - "*minMass: 0.001", - "*maxMass: 0.02", - "*minSpeed: 0.001", - "*maxSpeed: 0.02", - "*spacing: 14", - "*sizeFactor: 1.5", - "*colors: 200", - "*cycleSpeed: 10", -#ifdef HAVE_MOBILE - "*ignoreRotation: True", -#endif - ".lowrez: true", /* Too slow on Retina screens otherwise */ - 0 -}; - -static XrmOptionDescRec halftone_options [] = { - { "-delay", ".delay", XrmoptionSepArg, 0 }, - { "-count", ".count", XrmoptionSepArg, 0 }, - { "-minmass", ".minMass", XrmoptionSepArg, 0 }, - { "-maxmass", ".maxMass", XrmoptionSepArg, 0 }, - { "-minspeed", ".minSpeed", XrmoptionSepArg, 0 }, - { "-maxspeed", ".maxSpeed", XrmoptionSepArg, 0 }, - { "-spacing", ".spacing", XrmoptionSepArg, 0 }, - { "-sizefactor", ".sizeFactor", XrmoptionSepArg, 0 }, - { "-colors", ".colors", XrmoptionSepArg, 0 }, - { "-cycle-speed", ".cycleSpeed", XrmoptionSepArg, 0 }, - { 0, 0, 0, 0 } -}; - - -XSCREENSAVER_MODULE ("Halftone", halftone) |
