/* -*- Mode: C; tab-width: 4 -*- */ /* deco --- art as ugly as sin */ #if !defined( lint ) && !defined( SABER ) static const char sccsid[] = "@(#)deco.c 5.00 2000/11/01 xlockmore"; #endif /* * Copyright (c) 1997 by Jamie Zawinski * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * * Revision History: * 01-Nov-2000: Allocation checks * 29-Oct-1997: xlock version (David Bagley ) * 1997: xscreensaver version Jamie Zawinski */ /*- * original copyright * xscreensaver, Copyright (c) 1997 Jamie Zawinski * * 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. * * Concept snarfed from Michael D. Bayne in * http://www.go2net.com/internet/deep/1997/04/16/body.html */ #ifdef STANDALONE #define MODE_deco #define PROGCLASS "Deco" #define HACK_INIT init_deco #define HACK_DRAW draw_deco #define deco_opts xlockmore_opts #define DEFAULTS "*delay: 1000000 \n" \ "*count: -30 \n" \ "*cycles: 2 \n" \ "*size: -10 \n" \ "*ncolors: 200 \n" #include "xlockmore.h" /* in xscreensaver distribution */ #else /* STANDALONE */ #include "xlock.h" /* in xlockmore distribution */ #endif /* STANDALONE */ #ifdef MODE_deco ModeSpecOpt deco_opts = {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; #ifdef USE_MODULES ModStruct deco_description = {"deco", "init_deco", "draw_deco", "release_deco", "init_deco", "init_deco", (char *) NULL, &deco_opts, 1000000, -30, 2, -10, 64, 0.6, "", "Shows art as ugly as sin", 0, NULL}; #endif #define MINSIZE 2 #define MINDEPTH 1 typedef struct { int max_depth; int min_height; int min_width; int time; int colorindex; unsigned long bordercolor; } decostruct; static decostruct *decos = (decostruct *) NULL; static void deco(ModeInfo * mi, int x, int y, int w, int h, int depth) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); GC gc = MI_GC(mi); decostruct *dp = &decos[MI_SCREEN(mi)]; if ((NRAND(dp->max_depth) + 1 < depth) || (w < dp->min_width) || (h < dp->min_height)) { if (w > 2 && h > 2) { if (MI_NPIXELS(mi) > 2) { XSetForeground(display, gc, MI_PIXEL(mi, dp->colorindex)); if (++dp->colorindex >= MI_NPIXELS(mi)) dp->colorindex = 0; } else XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); XFillRectangle(display, window, gc, x + 1, y + 1, w - 2, h - 2); } } else { if (LRAND() & 1) { deco(mi, x, y, w / 2, h, depth + 1); deco(mi, x + w / 2, y, w - w / 2, h, depth + 1); } else { deco(mi, x, y, w, h / 2, depth + 1); deco(mi, x, y + h / 2, w, h - h / 2, depth + 1); } } } void init_deco(ModeInfo * mi) { decostruct *dp; int depth = MI_COUNT(mi); int size = MI_SIZE(mi); if (decos == NULL) { if ((decos = (decostruct *) calloc(MI_NUM_SCREENS(mi), sizeof (decostruct))) == NULL) return; } dp = &decos[MI_SCREEN(mi)]; if (MI_NPIXELS(mi) > 2) { dp->bordercolor = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi))); dp->colorindex = NRAND(MI_NPIXELS(mi)); } else dp->bordercolor = MI_BLACK_PIXEL(mi); if (depth < -MINDEPTH) dp->max_depth = NRAND(-depth - MINDEPTH + 1) + MINDEPTH; else if (depth < MINDEPTH) dp->max_depth = MINDEPTH; else dp->max_depth = depth; if (size < -MINSIZE) { dp->min_width = NRAND(-size - MINSIZE + 1) + MINSIZE; dp->min_height = NRAND(-size - MINSIZE + 1) + MINSIZE; } else if (size < MINDEPTH) dp->min_width = dp->min_height = MINSIZE; else dp->min_width = dp->min_height = size; dp->time = 0; } void draw_deco(ModeInfo * mi) { decostruct *dp; if (decos == NULL) return; dp = &decos[MI_SCREEN(mi)]; if (dp->time == 0) { /* This fills up holes */ MI_CLEARWINDOWCOLOR(mi, dp->bordercolor); #ifdef SOLARIS2 /* * if this is not done the first rectangle is sometimes messed up on * Solaris2 with 24 bit TrueColor (Ultra2) */ XDrawRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), 0, 0, MI_WIDTH(mi) / 2 + 1, MI_HEIGHT(mi) / 2 + 1); #endif deco(mi, 0, 0, MI_WIDTH(mi), MI_HEIGHT(mi), 0); } if (++dp->time > MI_CYCLES(mi)) init_deco(mi); MI_IS_DRAWN(mi) = True; } void release_deco(ModeInfo * mi) { if (decos != NULL) { free(decos); decos = (decostruct *) NULL; } } #endif /* MODE_deco */