1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* deco --- art as ugly as sin */
3 
4 #if 0
5 static const char sccsid[] = "@(#)deco.c	5.00 2000/11/01 xlockmore";
6 
7 #endif
8 /*
9  * Copyright (c) 1997 by Jamie Zawinski <jwz AT jwz.org>
10  *
11  * Permission to use, copy, modify, and distribute this software and its
12  * documentation for any purpose and without fee is hereby granted,
13  * provided that the above copyright notice appear in all copies and that
14  * both that copyright notice and this permission notice appear in
15  * supporting documentation.
16  *
17  * This file is provided AS IS with no warranties of any kind.  The author
18  * shall have no liability with respect to the infringement of copyrights,
19  * trade secrets or any patents by this file or any part thereof.  In no
20  * event will the author be liable for any lost revenue or profits or
21  * other special, indirect and consequential damages.
22  *
23  * Revision History:
24  * 01-Nov-2000: Allocation checks
25  * 29-Oct-1997: xlock version (David Bagley <bagleyd AT verizon.net>)
26  * 1997: xscreensaver version Jamie Zawinski <jwz AT jwz.org>
27  */
28 
29 /*-
30  * original copyright
31  * xscreensaver, Copyright (c) 1997 Jamie Zawinski <jwz AT jwz.org>
32  *
33  * Permission to use, copy, modify, distribute, and sell this software and its
34  * documentation for any purpose is hereby granted without fee, provided that
35  * the above copyright notice appear in all copies and that both that
36  * copyright notice and this permission notice appear in supporting
37  * documentation.  No representations are made about the suitability of this
38  * software for any purpose.  It is provided "as is" without express or
39  * implied warranty.
40  *
41  * Concept snarfed from Michael D. Bayne in
42  * http://www.go2net.com/internet/deep/1997/04/16/body.html
43  */
44 
45 #ifdef STANDALONE
46 #define MODE_deco
47 #define DEFAULTS "*delay: 1000000 \n" \
48 	"*count: -30 \n" \
49 	"*cycles: 2 \n" \
50 	"*size: -10 \n" \
51 	"*ncolors: 200 \n" \
52 
53 # define free_deco 0
54 # define reshape_deco 0
55 # define deco_handle_event 0
56 #include "xlockmore.h"		/* in xscreensaver distribution */
57 #define UNIFORM_COLORS
58 #define BRIGHT_COLORS
59 #define SMOOTH_COLORS
60 #else /* STANDALONE */
61 #include "xlock.h"		/* in xlockmore distribution */
62 #endif /* STANDALONE */
63 
64 #ifdef MODE_deco
65 
66 ENTRYPOINT ModeSpecOpt deco_opts =
67 {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
68 
69 #ifdef USE_MODULES
70 ModStruct   deco_description =
71 {"deco", "init_deco", "draw_deco", "release_deco",
72  "init_deco", "init_deco", (char *) NULL, &deco_opts,
73  1000000, -30, 2, -10, 64, 0.6, "",
74  "Shows art as ugly as sin", 0, NULL};
75 
76 #endif
77 
78 #define MINSIZE 2
79 #define MINDEPTH 1
80 
81 typedef struct {
82 	int         max_depth;
83 	int         min_height;
84 	int         min_width;
85 	int         time;
86 	int         colorindex;
87 	unsigned long bordercolor;
88 } decostruct;
89 
90 static decostruct *decos = (decostruct *) NULL;
91 
92 static void
deco(ModeInfo * mi,int x,int y,int w,int h,int depth)93 deco(ModeInfo * mi, int x, int y, int w, int h, int depth)
94 {
95 	Display    *display = MI_DISPLAY(mi);
96 	Window      window = MI_WINDOW(mi);
97 	GC          gc = MI_GC(mi);
98 	decostruct *dp = &decos[MI_SCREEN(mi)];
99 
100 	if ((NRAND(dp->max_depth) + 1 < depth) ||
101 	    (w < dp->min_width) || (h < dp->min_height)) {
102 		if (w > 2 && h > 2) {
103 			if (MI_NPIXELS(mi) > 2) {
104 				XSetForeground(display, gc, MI_PIXEL(mi, dp->colorindex));
105 				if (++dp->colorindex >= MI_NPIXELS(mi))
106 					dp->colorindex = 0;
107 			} else
108 				XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
109 			XFillRectangle(display, window, gc, x + 1, y + 1, w - 2, h - 2);
110 		}
111 	} else {
112 		if (LRAND() & 1) {
113 			deco(mi, x, y, w / 2, h, depth + 1);
114 			deco(mi, x + w / 2, y, w - w / 2, h, depth + 1);
115 		} else {
116 			deco(mi, x, y, w, h / 2, depth + 1);
117 			deco(mi, x, y + h / 2, w, h - h / 2, depth + 1);
118 		}
119 	}
120 }
121 
122 ENTRYPOINT void
init_deco(ModeInfo * mi)123 init_deco(ModeInfo * mi)
124 {
125 	decostruct *dp;
126 	int         depth = MI_COUNT(mi);
127 	int         size = MI_SIZE(mi);
128 
129 	MI_INIT(mi, decos);
130 	dp = &decos[MI_SCREEN(mi)];
131 
132 	if (MI_NPIXELS(mi) > 2) {
133 		dp->bordercolor = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)));
134 		dp->colorindex = NRAND(MI_NPIXELS(mi));
135 	} else
136 		dp->bordercolor = MI_BLACK_PIXEL(mi);
137 	if (depth < -MINDEPTH)
138 		dp->max_depth = NRAND(-depth - MINDEPTH + 1) + MINDEPTH;
139 	else if (depth < MINDEPTH)
140 		dp->max_depth = MINDEPTH;
141 	else
142 		dp->max_depth = depth;
143 	if (size < -MINSIZE) {
144 		dp->min_width = NRAND(-size - MINSIZE + 1) + MINSIZE;
145 		dp->min_height = NRAND(-size - MINSIZE + 1) + MINSIZE;
146 	} else if (size < MINDEPTH)
147 		dp->min_width = dp->min_height = MINSIZE;
148 	else
149 		dp->min_width = dp->min_height = size;
150 	dp->time = 0;
151 }
152 
153 ENTRYPOINT void
draw_deco(ModeInfo * mi)154 draw_deco(ModeInfo * mi)
155 {
156 	decostruct *dp;
157 
158 	if (decos == NULL)
159 		return;
160 	dp = &decos[MI_SCREEN(mi)];
161 
162 	if (dp->time == 0) {
163 		/* This fills up holes */
164 		MI_CLEARWINDOWCOLOR(mi, dp->bordercolor);
165 #ifdef SOLARIS2
166 		/*
167 		 * if this is not done the first rectangle is sometimes messed up on
168 		 * Solaris2 with 24 bit TrueColor (Ultra2)
169 		 */
170 		XDrawRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi),
171 			  0, 0, MI_WIDTH(mi) / 2 + 1, MI_HEIGHT(mi) / 2 + 1);
172 #endif
173 		deco(mi, 0, 0, MI_WIDTH(mi), MI_HEIGHT(mi), 0);
174 	}
175 	if (++dp->time > MI_CYCLES(mi))
176 		init_deco(mi);
177 
178 	MI_IS_DRAWN(mi) = True;
179 
180 }
181 
182 ENTRYPOINT void
release_deco(ModeInfo * mi)183 release_deco(ModeInfo * mi)
184 {
185 	if (decos != NULL) {
186 		free(decos);
187 		decos = (decostruct *) NULL;
188 	}
189 }
190 
191 XSCREENSAVER_MODULE ("Deco", deco)
192 
193 #endif /* MODE_deco */
194