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