193 lines
5.2 KiB
C
193 lines
5.2 KiB
C
/* -*- 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 <jwz@jwz.org>
|
|
*
|
|
* 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 <bagleyd@tux.org>)
|
|
* 1997: xscreensaver version Jamie Zawinski <jwz@jwz.org>
|
|
*/
|
|
|
|
/*-
|
|
* original copyright
|
|
* xscreensaver, Copyright (c) 1997 Jamie Zawinski <jwz@jwz.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.
|
|
*
|
|
* 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 */
|