1 | /* xscreensaver, Copyright (c) 1997, 1998, 2002 Jamie Zawinski <jwz@jwz.org> |
---|
2 | * |
---|
3 | * Permission to use, copy, modify, distribute, and sell this software and its |
---|
4 | * documentation for any purpose is hereby granted without fee, provided that |
---|
5 | * the above copyright notice appear in all copies and that both that |
---|
6 | * copyright notice and this permission notice appear in supporting |
---|
7 | * documentation. No representations are made about the suitability of this |
---|
8 | * software for any purpose. It is provided "as is" without express or |
---|
9 | * implied warranty. |
---|
10 | * |
---|
11 | * Concept snarfed from Michael D. Bayne in |
---|
12 | * http://www.go2net.com/internet/deep/1997/04/16/body.html |
---|
13 | */ |
---|
14 | |
---|
15 | #include "screenhack.h" |
---|
16 | #include <stdio.h> |
---|
17 | #include <time.h> |
---|
18 | #include <sys/time.h> |
---|
19 | |
---|
20 | static XColor colors[255]; |
---|
21 | static int ncolors = 0; |
---|
22 | static int max_depth = 0; |
---|
23 | static int min_height = 0; |
---|
24 | static int min_width = 0; |
---|
25 | |
---|
26 | static void |
---|
27 | deco (Display *dpy, |
---|
28 | Window window, |
---|
29 | Colormap cmap, |
---|
30 | GC fgc, GC bgc, |
---|
31 | int x, int y, int w, int h, int depth) |
---|
32 | { |
---|
33 | if (((random() % max_depth) < depth) || (w < min_width) || (h < min_height)) |
---|
34 | { |
---|
35 | if (!mono_p) |
---|
36 | { |
---|
37 | static int current_color = 0; |
---|
38 | if (++current_color >= ncolors) |
---|
39 | current_color = 0; |
---|
40 | XSetForeground(dpy, bgc, colors[current_color].pixel); |
---|
41 | } |
---|
42 | XFillRectangle (dpy, window, bgc, x, y, w, h); |
---|
43 | XDrawRectangle (dpy, window, fgc, x, y, w, h); |
---|
44 | } |
---|
45 | else |
---|
46 | { |
---|
47 | if (random() & 1) |
---|
48 | { |
---|
49 | deco (dpy, window, cmap, fgc, bgc, x, y, w/2, h, depth+1); |
---|
50 | deco (dpy, window, cmap, fgc, bgc, x+w/2, y, w/2, h, depth+1); |
---|
51 | } |
---|
52 | else |
---|
53 | { |
---|
54 | deco (dpy, window, cmap, fgc, bgc, x, y, w, h/2, depth+1); |
---|
55 | deco (dpy, window, cmap, fgc, bgc, x, y+h/2, w, h/2, depth+1); |
---|
56 | } |
---|
57 | } |
---|
58 | } |
---|
59 | |
---|
60 | |
---|
61 | char *progclass = "Deco"; |
---|
62 | |
---|
63 | char *defaults [] = { |
---|
64 | ".background: black", |
---|
65 | ".foreground: white", |
---|
66 | "*maxDepth: 12", |
---|
67 | "*minWidth: 20", |
---|
68 | "*minHeight: 20", |
---|
69 | "*cycle: False", |
---|
70 | "*delay: 5", |
---|
71 | "*cycleDelay: 1000000", |
---|
72 | "*ncolors: 64", |
---|
73 | 0 |
---|
74 | }; |
---|
75 | |
---|
76 | XrmOptionDescRec options [] = { |
---|
77 | { "-max-depth", ".maxDepth", XrmoptionSepArg, 0 }, |
---|
78 | { "-min-width", ".minWidth", XrmoptionSepArg, 0 }, |
---|
79 | { "-min-height", ".minHeight", XrmoptionSepArg, 0 }, |
---|
80 | { "-delay", ".delay", XrmoptionSepArg, 0 }, |
---|
81 | { "-ncolors", ".ncolors", XrmoptionSepArg, 0 }, |
---|
82 | { "-cycle", ".cycle", XrmoptionNoArg, "True" }, |
---|
83 | { "-no-cycle", ".cycle", XrmoptionNoArg, "False" }, |
---|
84 | { "-cycle-delay", ".cycleDelay", XrmoptionSepArg, 0 }, |
---|
85 | { 0, 0, 0, 0 } |
---|
86 | }; |
---|
87 | |
---|
88 | void |
---|
89 | screenhack (Display *dpy, Window window) |
---|
90 | { |
---|
91 | GC fgc, bgc; |
---|
92 | XGCValues gcv; |
---|
93 | XWindowAttributes xgwa; |
---|
94 | int delay = get_integer_resource ("delay", "Integer"); |
---|
95 | int cycle_delay = get_integer_resource ("cycleDelay", "Integer"); |
---|
96 | Bool writable = get_boolean_resource ("cycle", "Boolean"); |
---|
97 | |
---|
98 | max_depth = get_integer_resource ("maxDepth", "Integer"); |
---|
99 | if (max_depth < 1) max_depth = 1; |
---|
100 | else if (max_depth > 1000) max_depth = 1000; |
---|
101 | |
---|
102 | min_width = get_integer_resource ("minWidth", "Integer"); |
---|
103 | if (min_width < 2) min_width = 2; |
---|
104 | min_height = get_integer_resource ("minHeight", "Integer"); |
---|
105 | if (min_height < 2) min_height = 2; |
---|
106 | |
---|
107 | XGetWindowAttributes (dpy, window, &xgwa); |
---|
108 | |
---|
109 | gcv.foreground = get_pixel_resource("foreground", "Foreground", |
---|
110 | dpy, xgwa.colormap); |
---|
111 | fgc = XCreateGC (dpy, window, GCForeground, &gcv); |
---|
112 | |
---|
113 | gcv.foreground = get_pixel_resource("background", "Background", |
---|
114 | dpy, xgwa.colormap); |
---|
115 | bgc = XCreateGC (dpy, window, GCForeground, &gcv); |
---|
116 | |
---|
117 | ncolors = get_integer_resource ("ncolors", "Integer"); |
---|
118 | |
---|
119 | make_random_colormap (dpy, xgwa.visual, xgwa.colormap, colors, &ncolors, |
---|
120 | False, True, &writable, True); |
---|
121 | |
---|
122 | if (ncolors <= 2) |
---|
123 | mono_p = True; |
---|
124 | |
---|
125 | if (!mono_p) |
---|
126 | { |
---|
127 | GC tmp = fgc; |
---|
128 | fgc = bgc; |
---|
129 | bgc = tmp; |
---|
130 | } |
---|
131 | |
---|
132 | while (1) |
---|
133 | { |
---|
134 | XGetWindowAttributes (dpy, window, &xgwa); |
---|
135 | XFillRectangle(dpy, window, bgc, 0, 0, xgwa.width, xgwa.height); |
---|
136 | deco (dpy, window, xgwa.colormap, fgc, bgc, |
---|
137 | 0, 0, xgwa.width, xgwa.height, 0); |
---|
138 | XSync (dpy, False); |
---|
139 | screenhack_handle_events (dpy); |
---|
140 | |
---|
141 | if (!delay) continue; |
---|
142 | if (!writable) |
---|
143 | sleep (delay); |
---|
144 | else |
---|
145 | { |
---|
146 | time_t start = time((time_t) 0); |
---|
147 | while (start - delay < time((time_t) 0)) |
---|
148 | { |
---|
149 | rotate_colors (dpy, xgwa.colormap, colors, ncolors, 1); |
---|
150 | XSync (dpy, False); |
---|
151 | screenhack_handle_events (dpy); |
---|
152 | if (cycle_delay) |
---|
153 | usleep (cycle_delay); |
---|
154 | } |
---|
155 | } |
---|
156 | } |
---|
157 | } |
---|