1 | /* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998 |
---|
2 | * Jamie Zawinski <jwz@jwz.org> |
---|
3 | * |
---|
4 | * Permission to use, copy, modify, distribute, and sell this software and its |
---|
5 | * documentation for any purpose is hereby granted without fee, provided that |
---|
6 | * the above copyright notice appear in all copies and that both that |
---|
7 | * copyright notice and this permission notice appear in supporting |
---|
8 | * documentation. No representations are made about the suitability of this |
---|
9 | * software for any purpose. It is provided "as is" without express or |
---|
10 | * implied warranty. |
---|
11 | */ |
---|
12 | |
---|
13 | /* 18-Sep-97: Johannes Keukelaar <johannes@nada.kth.se>: Added some color. |
---|
14 | * Using -mono gives the old behaviour. (Modified by jwz.) |
---|
15 | */ |
---|
16 | /* Flying through an asteroid field. Based on TI Explorer Lisp code by |
---|
17 | John Nguyen <johnn@hx.lcs.mit.edu> |
---|
18 | */ |
---|
19 | |
---|
20 | #include <stdio.h> |
---|
21 | #include <math.h> |
---|
22 | #include "screenhack.h" |
---|
23 | |
---|
24 | #define MIN_ROCKS 1 |
---|
25 | #define MIN_DEPTH 2 /* rocks disappear when they get this close */ |
---|
26 | #define MAX_DEPTH 60 /* this is where rocks appear */ |
---|
27 | #define MIN_SIZE 3 /* how small where pixmaps are not used */ |
---|
28 | #define MAX_SIZE 200 /* how big (in pixels) rocks are at depth 1 */ |
---|
29 | #define DEPTH_SCALE 100 /* how many ticks there are between depths */ |
---|
30 | #define SIN_RESOLUTION 1000 |
---|
31 | |
---|
32 | #define MAX_DEP 0.3 /* how far the displacement can be (percent) */ |
---|
33 | #define DIRECTION_CHANGE_RATE 60 |
---|
34 | #define MAX_DEP_SPEED 5 /* Maximum speed for movement */ |
---|
35 | #define MOVE_STYLE 0 /* Only 0 and 1. Distinguishes the fact that |
---|
36 | these are the rocks that are moving (1) |
---|
37 | or the rocks source (0). */ |
---|
38 | |
---|
39 | /* there's not much point in the above being user-customizable, but those |
---|
40 | numbers might want to be tweaked for displays with an order of magnitude |
---|
41 | higher resolution or compute power. |
---|
42 | */ |
---|
43 | |
---|
44 | static double sins [SIN_RESOLUTION]; |
---|
45 | static double coss [SIN_RESOLUTION]; |
---|
46 | static double depths [(MAX_DEPTH + 1) * DEPTH_SCALE]; |
---|
47 | |
---|
48 | static Display *dpy; |
---|
49 | static Window window; |
---|
50 | static int width, height, midx, midy; |
---|
51 | static int dep_x, dep_y; |
---|
52 | static int ncolors; |
---|
53 | static XColor *colors; |
---|
54 | static float max_dep; |
---|
55 | static GC erase_gc; |
---|
56 | static GC *draw_gcs; |
---|
57 | static Bool rotate_p; |
---|
58 | static Bool move_p; |
---|
59 | static int speed; |
---|
60 | static Bool threed; |
---|
61 | static GC threed_left_gc, threed_right_gc; |
---|
62 | static double threed_delta; |
---|
63 | |
---|
64 | #define GETZDIFF(z) \ |
---|
65 | (threed_delta * 40.0 * \ |
---|
66 | (1.0 - ((MAX_DEPTH * DEPTH_SCALE / 2) / \ |
---|
67 | ((z) + 20.0 * DEPTH_SCALE)))) |
---|
68 | |
---|
69 | struct rock { |
---|
70 | int real_size; |
---|
71 | int r; |
---|
72 | int theta; |
---|
73 | int depth; |
---|
74 | int size, x, y; |
---|
75 | int diff; |
---|
76 | int color; |
---|
77 | }; |
---|
78 | |
---|
79 | static struct rock *rocks; |
---|
80 | static int nrocks; |
---|
81 | static Pixmap pixmaps [MAX_SIZE]; |
---|
82 | static int delay; |
---|
83 | |
---|
84 | static void rock_compute (struct rock *); |
---|
85 | static void rock_draw (struct rock *, Bool draw_p); |
---|
86 | |
---|
87 | static void |
---|
88 | rock_reset (struct rock *rock) |
---|
89 | { |
---|
90 | rock->real_size = MAX_SIZE; |
---|
91 | rock->r = (SIN_RESOLUTION * 0.7) + (random () % (30 * SIN_RESOLUTION)); |
---|
92 | rock->theta = random () % SIN_RESOLUTION; |
---|
93 | rock->depth = MAX_DEPTH * DEPTH_SCALE; |
---|
94 | rock->color = random() % ncolors; |
---|
95 | rock_compute (rock); |
---|
96 | rock_draw (rock, True); |
---|
97 | } |
---|
98 | |
---|
99 | static void |
---|
100 | rock_tick (struct rock *rock, int d) |
---|
101 | { |
---|
102 | if (rock->depth > 0) |
---|
103 | { |
---|
104 | rock_draw (rock, False); |
---|
105 | rock->depth -= speed; |
---|
106 | if (rotate_p) |
---|
107 | { |
---|
108 | rock->theta = (rock->theta + d) % SIN_RESOLUTION; |
---|
109 | } |
---|
110 | while (rock->theta < 0) |
---|
111 | rock->theta += SIN_RESOLUTION; |
---|
112 | if (rock->depth < (MIN_DEPTH * DEPTH_SCALE)) |
---|
113 | rock->depth = 0; |
---|
114 | else |
---|
115 | { |
---|
116 | rock_compute (rock); |
---|
117 | rock_draw (rock, True); |
---|
118 | } |
---|
119 | } |
---|
120 | else if ((random () % 40) == 0) |
---|
121 | rock_reset (rock); |
---|
122 | } |
---|
123 | |
---|
124 | static void |
---|
125 | rock_compute (struct rock *rock) |
---|
126 | { |
---|
127 | double factor = depths [rock->depth]; |
---|
128 | double rsize = rock->real_size * factor; |
---|
129 | |
---|
130 | rock->size = (int) (rsize + 0.5); |
---|
131 | rock->diff = (int) GETZDIFF(rock->depth); |
---|
132 | rock->x = midx + (coss [rock->theta] * rock->r * factor); |
---|
133 | rock->y = midy + (sins [rock->theta] * rock->r * factor); |
---|
134 | |
---|
135 | if (move_p) |
---|
136 | { |
---|
137 | double move_factor = (((double) MOVE_STYLE) - |
---|
138 | (((double) rock->depth) / |
---|
139 | (((double) (MAX_DEPTH + 1)) * |
---|
140 | ((double) DEPTH_SCALE)))); |
---|
141 | /* move_factor is 0 when the rock is close, 1 when far */ |
---|
142 | rock->x += (((double) dep_x) * move_factor); |
---|
143 | rock->y += (((double) dep_y) * move_factor); |
---|
144 | } |
---|
145 | } |
---|
146 | |
---|
147 | static void |
---|
148 | rock_draw (rock, draw_p) |
---|
149 | struct rock *rock; |
---|
150 | Bool draw_p; |
---|
151 | { |
---|
152 | GC gc = (draw_p |
---|
153 | ? (threed ? erase_gc : draw_gcs[rock->color]) |
---|
154 | : erase_gc); |
---|
155 | |
---|
156 | if (rock->x <= 0 || rock->y <= 0 || rock->x >= width || rock->y >= height) |
---|
157 | { |
---|
158 | /* this means that if a rock were to go off the screen at 12:00, but |
---|
159 | would have been visible at 3:00, it won't come back once the observer |
---|
160 | rotates around so that the rock would have been visible again. |
---|
161 | Oh well. |
---|
162 | */ |
---|
163 | if (!move_p) |
---|
164 | rock->depth = 0; |
---|
165 | return; |
---|
166 | } |
---|
167 | if (rock->size <= 1) |
---|
168 | { |
---|
169 | if (threed) |
---|
170 | { |
---|
171 | if (draw_p) gc = threed_left_gc; |
---|
172 | XDrawPoint (dpy, window, gc, rock->x - rock->diff, rock->y); |
---|
173 | if (draw_p) gc = threed_right_gc; |
---|
174 | XDrawPoint (dpy, window, gc, rock->x + rock->diff, rock->y); |
---|
175 | } |
---|
176 | else |
---|
177 | { |
---|
178 | XDrawPoint (dpy, window, gc, rock->x, rock->y); |
---|
179 | } |
---|
180 | } |
---|
181 | else if (rock->size <= MIN_SIZE || !draw_p) |
---|
182 | { |
---|
183 | if (threed) |
---|
184 | { |
---|
185 | if (draw_p) gc = threed_left_gc; |
---|
186 | XFillRectangle(dpy, window, gc, |
---|
187 | rock->x - rock->size / 2 - rock->diff, |
---|
188 | rock->y - rock->size / 2, |
---|
189 | rock->size, rock->size); |
---|
190 | if (draw_p) gc = threed_right_gc; |
---|
191 | XFillRectangle(dpy, window, gc, |
---|
192 | rock->x - rock->size / 2 + rock->diff, |
---|
193 | rock->y - rock->size / 2, |
---|
194 | rock->size, rock->size); |
---|
195 | } |
---|
196 | else |
---|
197 | { |
---|
198 | XFillRectangle (dpy, window, gc, |
---|
199 | rock->x - rock->size/2, rock->y - rock->size/2, |
---|
200 | rock->size, rock->size); |
---|
201 | } |
---|
202 | } |
---|
203 | else if (rock->size < MAX_SIZE) |
---|
204 | { |
---|
205 | if (threed) |
---|
206 | { |
---|
207 | gc = threed_left_gc; |
---|
208 | XCopyPlane(dpy, pixmaps[rock->size], window, gc, |
---|
209 | 0, 0, rock->size, rock->size, |
---|
210 | rock->x - rock->size / 2 - rock->diff, |
---|
211 | rock->y - rock->size / 2, 1L); |
---|
212 | gc = threed_right_gc; |
---|
213 | XCopyPlane(dpy, pixmaps[rock->size], window, gc, |
---|
214 | 0, 0, rock->size, rock->size, |
---|
215 | rock->x - rock->size / 2 + rock->diff, |
---|
216 | rock->y - rock->size / 2, 1L); |
---|
217 | } |
---|
218 | else |
---|
219 | { |
---|
220 | XCopyPlane (dpy, pixmaps [rock->size], window, gc, |
---|
221 | 0, 0, rock->size, rock->size, |
---|
222 | rock->x - rock->size/2, rock->y - rock->size/2, |
---|
223 | 1L); |
---|
224 | } |
---|
225 | } |
---|
226 | } |
---|
227 | |
---|
228 | |
---|
229 | static void |
---|
230 | init_pixmaps (Display *dpy, Window window) |
---|
231 | { |
---|
232 | int i; |
---|
233 | XGCValues gcv; |
---|
234 | GC fg_gc = 0, bg_gc = 0; |
---|
235 | pixmaps [0] = pixmaps [1] = 0; |
---|
236 | for (i = MIN_DEPTH; i < MAX_SIZE; i++) |
---|
237 | { |
---|
238 | int w = (1+(i/32))<<5; /* server might be faster if word-aligned */ |
---|
239 | int h = i; |
---|
240 | Pixmap p = XCreatePixmap (dpy, window, w, h, 1); |
---|
241 | XPoint points [7]; |
---|
242 | pixmaps [i] = p; |
---|
243 | if (! p) |
---|
244 | { |
---|
245 | fprintf (stderr, "%s: couldn't allocate pixmaps", progname); |
---|
246 | exit (1); |
---|
247 | } |
---|
248 | if (! fg_gc) |
---|
249 | { /* must use drawable of pixmap, not window (fmh) */ |
---|
250 | gcv.foreground = 1; |
---|
251 | fg_gc = XCreateGC (dpy, p, GCForeground, &gcv); |
---|
252 | gcv.foreground = 0; |
---|
253 | bg_gc = XCreateGC (dpy, p, GCForeground, &gcv); |
---|
254 | } |
---|
255 | XFillRectangle (dpy, p, bg_gc, 0, 0, w, h); |
---|
256 | points [0].x = i * 0.15; points [0].y = i * 0.85; |
---|
257 | points [1].x = i * 0.00; points [1].y = i * 0.20; |
---|
258 | points [2].x = i * 0.30; points [2].y = i * 0.00; |
---|
259 | points [3].x = i * 0.40; points [3].y = i * 0.10; |
---|
260 | points [4].x = i * 0.90; points [4].y = i * 0.10; |
---|
261 | points [5].x = i * 1.00; points [5].y = i * 0.55; |
---|
262 | points [6].x = i * 0.45; points [6].y = i * 1.00; |
---|
263 | XFillPolygon (dpy, p, fg_gc, points, 7, Nonconvex, CoordModeOrigin); |
---|
264 | } |
---|
265 | XFreeGC (dpy, fg_gc); |
---|
266 | XFreeGC (dpy, bg_gc); |
---|
267 | } |
---|
268 | |
---|
269 | |
---|
270 | static int |
---|
271 | compute_move(int axe) /* 0 for x, 1 for y */ |
---|
272 | { |
---|
273 | static int current_dep[2] = {0, 0}; |
---|
274 | static int speed[2] = {0, 0}; |
---|
275 | static short direction[2] = {0, 0}; |
---|
276 | static int limit[2] = {0, 0}; |
---|
277 | int change = 0; |
---|
278 | |
---|
279 | limit[0] = midx; |
---|
280 | limit[1] = midy; |
---|
281 | |
---|
282 | current_dep[axe] += speed[axe]; /* We adjust the displacement */ |
---|
283 | |
---|
284 | if (current_dep[axe] > (int) (limit[axe] * max_dep)) |
---|
285 | { |
---|
286 | if (current_dep[axe] > limit[axe]) |
---|
287 | current_dep[axe] = limit[axe]; |
---|
288 | direction[axe] = -1; |
---|
289 | } /* This is when we reach the upper screen limit */ |
---|
290 | if (current_dep[axe] < (int) (-limit[axe] * max_dep)) |
---|
291 | { |
---|
292 | if (current_dep[axe] < -limit[axe]) |
---|
293 | current_dep[axe] = -limit[axe]; |
---|
294 | direction[axe] = 1; |
---|
295 | } /* This is when we reach the lower screen limit */ |
---|
296 | if (direction[axe] == 1) /* We adjust the speed */ |
---|
297 | speed[axe] += 1; |
---|
298 | else if (direction[axe] == -1) |
---|
299 | speed[axe] -= 1; |
---|
300 | |
---|
301 | if (speed[axe] > MAX_DEP_SPEED) |
---|
302 | speed[axe] = MAX_DEP_SPEED; |
---|
303 | else if (speed[axe] < -MAX_DEP_SPEED) |
---|
304 | speed[axe] = -MAX_DEP_SPEED; |
---|
305 | |
---|
306 | if (move_p && !(random() % DIRECTION_CHANGE_RATE)) |
---|
307 | { |
---|
308 | /* We change direction */ |
---|
309 | change = random() & 1; |
---|
310 | if (change != 1) |
---|
311 | { |
---|
312 | if (direction[axe] == 0) |
---|
313 | direction[axe] = change - 1; /* 0 becomes either 1 or -1 */ |
---|
314 | else |
---|
315 | direction[axe] = 0; /* -1 or 1 become 0 */ |
---|
316 | } |
---|
317 | } |
---|
318 | return (current_dep[axe]); |
---|
319 | } |
---|
320 | |
---|
321 | static void |
---|
322 | tick_rocks (int d) |
---|
323 | { |
---|
324 | int i; |
---|
325 | |
---|
326 | if (move_p) |
---|
327 | { |
---|
328 | dep_x = compute_move(0); |
---|
329 | dep_y = compute_move(1); |
---|
330 | } |
---|
331 | |
---|
332 | for (i = 0; i < nrocks; i++) |
---|
333 | rock_tick (&rocks [i], d); |
---|
334 | } |
---|
335 | |
---|
336 | |
---|
337 | static void |
---|
338 | rocks_once (void) |
---|
339 | { |
---|
340 | static int current_delta = 0; /* observer Z rotation */ |
---|
341 | static int window_tick = 50; |
---|
342 | static int new_delta = 0; |
---|
343 | static int dchange_tick = 0; |
---|
344 | |
---|
345 | if (window_tick++ == 50) |
---|
346 | { |
---|
347 | XWindowAttributes xgwa; |
---|
348 | XGetWindowAttributes (dpy, window, &xgwa); |
---|
349 | window_tick = 0; |
---|
350 | width = xgwa.width; |
---|
351 | height = xgwa.height; |
---|
352 | midx = width/2; |
---|
353 | midy = height/2; |
---|
354 | } |
---|
355 | |
---|
356 | if (current_delta != new_delta) |
---|
357 | { |
---|
358 | if (dchange_tick++ == 5) |
---|
359 | { |
---|
360 | dchange_tick = 0; |
---|
361 | if (current_delta < new_delta) |
---|
362 | current_delta++; |
---|
363 | else |
---|
364 | current_delta--; |
---|
365 | } |
---|
366 | } |
---|
367 | else |
---|
368 | { |
---|
369 | if (! (random() % 50)) |
---|
370 | { |
---|
371 | new_delta = ((random() % 11) - 5); |
---|
372 | if (! (random() % 10)) |
---|
373 | new_delta *= 5; |
---|
374 | } |
---|
375 | } |
---|
376 | tick_rocks (current_delta); |
---|
377 | } |
---|
378 | |
---|
379 | static void |
---|
380 | init_rocks (Display *d, Window w) |
---|
381 | { |
---|
382 | int i; |
---|
383 | XGCValues gcv; |
---|
384 | Colormap cmap; |
---|
385 | XWindowAttributes xgwa; |
---|
386 | unsigned int bg; |
---|
387 | dpy = d; |
---|
388 | window = w; |
---|
389 | XGetWindowAttributes (dpy, window, &xgwa); |
---|
390 | cmap = xgwa.colormap; |
---|
391 | delay = get_integer_resource ("delay", "Integer"); |
---|
392 | if (delay < 0) delay = 0; |
---|
393 | speed = get_integer_resource ("speed", "Integer"); |
---|
394 | if (speed < 1) speed = 1; |
---|
395 | if (speed > 100) speed = 100; |
---|
396 | rotate_p = get_boolean_resource ("rotate", "Boolean"); |
---|
397 | move_p = get_boolean_resource ("move", "Boolean"); |
---|
398 | if (mono_p) |
---|
399 | ncolors = 2; |
---|
400 | else |
---|
401 | ncolors = get_integer_resource ("colors", "Colors"); |
---|
402 | |
---|
403 | if (ncolors < 2) |
---|
404 | { |
---|
405 | ncolors = 2; |
---|
406 | mono_p = True; |
---|
407 | } |
---|
408 | |
---|
409 | colors = (XColor *) malloc(ncolors * sizeof(*colors)); |
---|
410 | draw_gcs = (GC *) malloc(ncolors * sizeof(*draw_gcs)); |
---|
411 | |
---|
412 | bg = get_pixel_resource ("background", "Background", dpy, cmap); |
---|
413 | colors[0].pixel = bg; |
---|
414 | colors[0].flags = DoRed|DoGreen|DoBlue; |
---|
415 | XQueryColor(dpy, cmap, &colors[0]); |
---|
416 | |
---|
417 | ncolors--; |
---|
418 | make_random_colormap(dpy, xgwa.visual, cmap, colors+1, &ncolors, True, |
---|
419 | True, 0, True); |
---|
420 | ncolors++; |
---|
421 | |
---|
422 | if (ncolors < 2) |
---|
423 | { |
---|
424 | ncolors = 2; |
---|
425 | mono_p = True; |
---|
426 | } |
---|
427 | |
---|
428 | if (mono_p) |
---|
429 | { |
---|
430 | unsigned int fg = get_pixel_resource("foreground", "Foreground", |
---|
431 | dpy, cmap); |
---|
432 | colors[1].pixel = fg; |
---|
433 | colors[1].flags = DoRed|DoGreen|DoBlue; |
---|
434 | XQueryColor(dpy, cmap, &colors[1]); |
---|
435 | gcv.foreground = fg; |
---|
436 | gcv.background = bg; |
---|
437 | draw_gcs[0] = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv); |
---|
438 | draw_gcs[1] = draw_gcs[0]; |
---|
439 | } |
---|
440 | else |
---|
441 | for( i = 0; i < ncolors; i++ ) |
---|
442 | { |
---|
443 | gcv.foreground = colors[i].pixel; |
---|
444 | gcv.background = bg; |
---|
445 | draw_gcs[i] = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv); |
---|
446 | } |
---|
447 | |
---|
448 | gcv.foreground = bg; |
---|
449 | erase_gc = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv); |
---|
450 | |
---|
451 | max_dep = (move_p ? MAX_DEP : 0); |
---|
452 | |
---|
453 | for (i = 0; i < SIN_RESOLUTION; i++) |
---|
454 | { |
---|
455 | sins [i] = sin ((((double) i) / (SIN_RESOLUTION / 2)) * M_PI); |
---|
456 | coss [i] = cos ((((double) i) / (SIN_RESOLUTION / 2)) * M_PI); |
---|
457 | } |
---|
458 | /* we actually only need i/speed of these, but wtf */ |
---|
459 | for (i = 1; i < (sizeof (depths) / sizeof (depths[0])); i++) |
---|
460 | depths [i] = atan (((double) 0.5) / (((double) i) / DEPTH_SCALE)); |
---|
461 | depths [0] = M_PI/2; /* avoid division by 0 */ |
---|
462 | |
---|
463 | threed = get_boolean_resource("use3d", "Boolean"); |
---|
464 | if (threed) |
---|
465 | { |
---|
466 | gcv.background = bg; |
---|
467 | gcv.foreground = get_pixel_resource ("left3d", "Foreground", dpy, cmap); |
---|
468 | threed_left_gc = XCreateGC (dpy, window, GCForeground|GCBackground,&gcv); |
---|
469 | gcv.foreground = get_pixel_resource ("right3d", "Foreground", dpy, cmap); |
---|
470 | threed_right_gc = XCreateGC (dpy, window,GCForeground|GCBackground,&gcv); |
---|
471 | threed_delta = get_float_resource("delta3d", "Integer"); |
---|
472 | } |
---|
473 | |
---|
474 | /* don't want any exposure events from XCopyPlane */ |
---|
475 | for( i = 0; i < ncolors; i++) |
---|
476 | XSetGraphicsExposures (dpy, draw_gcs[i], False); |
---|
477 | XSetGraphicsExposures (dpy, erase_gc, False); |
---|
478 | |
---|
479 | nrocks = get_integer_resource ("count", "Count"); |
---|
480 | if (nrocks < 1) nrocks = 1; |
---|
481 | rocks = (struct rock *) calloc (nrocks, sizeof (struct rock)); |
---|
482 | init_pixmaps (dpy, window); |
---|
483 | XClearWindow (dpy, window); |
---|
484 | } |
---|
485 | |
---|
486 | |
---|
487 | |
---|
488 | char *progclass = "Rocks"; |
---|
489 | |
---|
490 | char *defaults [] = { |
---|
491 | ".background: Black", |
---|
492 | ".foreground: #E9967A", |
---|
493 | "*colors: 5", |
---|
494 | "*count: 100", |
---|
495 | "*delay: 50000", |
---|
496 | "*speed: 100", |
---|
497 | "*rotate: true", |
---|
498 | "*move: true", |
---|
499 | "*use3d: False", |
---|
500 | "*left3d: Blue", |
---|
501 | "*right3d: Red", |
---|
502 | "*delta3d: 1.5", |
---|
503 | 0 |
---|
504 | }; |
---|
505 | |
---|
506 | XrmOptionDescRec options [] = { |
---|
507 | { "-count", ".count", XrmoptionSepArg, 0 }, |
---|
508 | { "-rotate", ".rotate", XrmoptionNoArg, "true" }, |
---|
509 | { "-norotate", ".rotate", XrmoptionNoArg, "false" }, |
---|
510 | { "-move", ".move", XrmoptionNoArg, "true" }, |
---|
511 | { "-nomove", ".move", XrmoptionNoArg, "false" }, |
---|
512 | { "-delay", ".delay", XrmoptionSepArg, 0 }, |
---|
513 | { "-speed", ".speed", XrmoptionSepArg, 0 }, |
---|
514 | {"-3d", ".use3d", XrmoptionNoArg, "True"}, |
---|
515 | {"-no-3d", ".use3d", XrmoptionNoArg, "False"}, |
---|
516 | {"-left3d", ".left3d", XrmoptionSepArg, 0 }, |
---|
517 | {"-right3d", ".right3d", XrmoptionSepArg, 0 }, |
---|
518 | {"-delta3d", ".delta3d", XrmoptionSepArg, 0 }, |
---|
519 | { "-colors", ".colors", XrmoptionSepArg, 0 }, |
---|
520 | { 0, 0, 0, 0 } |
---|
521 | }; |
---|
522 | |
---|
523 | void |
---|
524 | screenhack (Display *dpy, Window window) |
---|
525 | { |
---|
526 | init_rocks (dpy, window); |
---|
527 | while (1) |
---|
528 | { |
---|
529 | rocks_once (); |
---|
530 | XSync (dpy, False); |
---|
531 | screenhack_handle_events (dpy); |
---|
532 | if (delay) usleep (delay); |
---|
533 | } |
---|
534 | } |
---|