1 /*
2 * xcl.c
3 * Control-Line in a box
4 * Copyright (c) 2000 by Martin Berentsen <berentsen@sent5.uni-duisburg.de>
5 *
6 * change-log
7 * 0.4pl2 -> 0.5pl0 25/07/2000
8 * -singl command line option becomes to -count num
9 * 0.5pl0 -> 0.5pl1 02.02.2001
10 * bugs in -oldcolor and -randomstart option removed
11 *
12 * TODO as next:
13 * - a user defined speed for every used plane
14 *
15 */
16
17 #if 0
18 static const char sccsid[] = "@(#)xcl.c 5.00 2000/11/01 xlockmore";
19
20 #endif
21
22 #define RAND(x) (((my_random() % x )- x/2)) /* random number around 0 */
23 #define ROTATEDELAY 20000 /* delay for view-model rotating */
24 #define STARTUPDELAY 5000 /* delay for the first calibration loop */
25 #define REGULATE 25 /* regulate delay every xx frames */
26 #define FRAMETIME 45000 /* time for one frame */
27 #define MINPLANES 1 /* define the min number of planes */
28 #define MAXCOUNT 30 /* define the max number of planes */
29
30 #ifdef STANDALONE
31 #define MODE_xcl
32 #define DEFAULTS "*delay: 20000 \n" \
33 "*count: 2 \n" \
34
35 # define free_xcl 0
36 # define reshape_xcl 0
37 # define xcl_handle_event 0
38 #define UNIFORM_COLORS
39 #include "xlockmore.h" /* in xscreensaver distribution */
40 #else /* STANDALONE */
41 #include "xlock.h" /* in xlockmore distribution */
42 #endif
43
44 #ifdef WIN32
45 #include <sys/time.h>
46 #endif
47
48 #include "xcl.h" /* model line data file */
49
50 #ifdef MODE_xcl
51
52 /* all parameters are global */
53 static float speed[MAXCOUNT]; /* Speed in km/h */
54 static float speed_in; /* speed set by user */
55 static int frametime; /* time for one frame in usecs */
56 static int line_length; /* lines in mm*/
57 static float spectator; /* spectator distance from zero*/
58 static Bool viewmodel; /* shows one rotating model*/
59 static Bool oldcolor; /* use the old yellow/red color combination */
60 static Bool debug; /* debug modus */
61 static Bool automatic; /* automatic scale for fit into window */
62 static Bool randomstart; /* don't use the same start position */
63 static int random_pid;
64
65
66 #define DEF_SPEED_IN "105.0"
67 #define DEF_FRAMETIME "45000"
68 #define DEF_LINE_LENGTH "15910"
69 #define DEF_SPECTATOR "22000"
70 #define DEF_VIEWMODEL "False"
71 #define DEF_OLDCOLOR "False"
72 #define DEF_XCLDEBUG "False"
73 #define DEF_AUTOMATIC "True"
74 #define DEF_RANDOMSTART "False"
75
76
77 static XrmOptionDescRec opts[] =
78 {
79 {(char *) "-speed", (char *) ".xcl.speed", XrmoptionSepArg, (caddr_t) NULL},
80 {(char *) "-frametime", (char *) ".xcl.frametime", XrmoptionSepArg, (caddr_t) NULL},
81 {(char *) "-line_length", (char *) ".xcl.line_length", XrmoptionSepArg, (caddr_t) NULL},
82 {(char *) "-spectator", (char *) ".xcl.spectator", XrmoptionSepArg, (caddr_t) NULL},
83 {(char *) "-viewmodel", (char *) ".xcl.viewmodel", XrmoptionNoArg, (caddr_t) "on"},
84 {(char *) "+viewmodel", (char *) ".xcl.viewmodel", XrmoptionNoArg, (caddr_t) "off"},
85 {(char *) "-oldcolor", (char *) ".xcl.oldcolor", XrmoptionNoArg, (caddr_t) "on"},
86 {(char *) "+oldcolor", (char *) ".xcl.oldcolor", XrmoptionNoArg, (caddr_t) "off"},
87 {(char *) "-xcldebug", (char *) ".xcl.xcldebug", XrmoptionNoArg, (caddr_t) "on"},
88 {(char *) "+xcldebug", (char *) ".xcl.xcldebug", XrmoptionNoArg, (caddr_t) "off"},
89 {(char *) "-automatic", (char *) ".xcl.automatic", XrmoptionNoArg, (caddr_t) "on"},
90 {(char *) "+automatic", (char *) ".xcl.automatic", XrmoptionNoArg, (caddr_t) "off"},
91 {(char *) "-randomstart", (char *) ".xcl.randomstart", XrmoptionNoArg, (caddr_t) "on"},
92 {(char *) "+randomstart", (char *) ".xcl.randomstart", XrmoptionNoArg, (caddr_t) "off"}
93 };
94 static argtype vars[] =
95 {
96 {(void *) & speed_in, (char *) "speed", (char *) "Speed", (char *) DEF_SPEED_IN, t_Float},
97 {(void *) & frametime, (char *) "frametime", (char *) "frametime", (char *) DEF_FRAMETIME, t_Int},
98 {(void *) & line_length, (char *) "line_length", (char *) "Line_length", (char *) DEF_LINE_LENGTH, t_Int},
99 {(void *) & spectator, (char *) "spectator", (char *) "Spectator", (char *) DEF_SPECTATOR, t_Float},
100 {(void *) & viewmodel, (char *) "viewmodel", (char *) "Viewmodel", (char *) DEF_VIEWMODEL, t_Bool},
101 {(void *) & oldcolor, (char *) "oldcolor", (char *) "Oldcolor", (char *) DEF_OLDCOLOR, t_Bool},
102 {(void *) & debug, (char *) "xcldebug", (char *) "Xcldebug", (char *) DEF_XCLDEBUG, t_Bool},
103 {(void *) & automatic, (char *) "automatic", (char *) "Automatic", (char *) DEF_AUTOMATIC, t_Bool},
104 {(void *) & randomstart, (char *) "randomstart", (char *) "Randomstart", (char *) DEF_RANDOMSTART, t_Bool}
105 };
106 static OptionStruct desc[] =
107 {
108 {(char *) "-speed num", (char *) "speed for the planes in km/h "},
109 {(char *) "-frametime num", (char *) "time for one frame on the screen in usecs "},
110 {(char *) "-line_length num", (char *) "distance between the pilot and the plane in mm "},
111 {(char *) "-spectator num", (char *) "distance between spectator and pilot in mm"},
112 {(char *) "-/+viewmodel", (char *) "turn on/off an anim view of one model"},
113 {(char *) "-/+oldcolor", (char *) "turn on/off the old yellow/red combination"},
114 {(char *) "-/+xcldebug", (char *) "turn on/off some timing information"},
115 {(char *) "-/+automatic", (char *) "turn on/off auto scale for fit into the window"},
116 {(char *) "-/+randomstart", (char *) "turn on/off a random start point for models at startup"}
117 };
118
119 ENTRYPOINT ModeSpecOpt xcl_opts =
120 {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
121
122 #ifdef USE_MODULES /* for xlockmore */
123 ModStruct xcl_description =
124 {"xcl", "init_xcl", "draw_xcl", "release_xcl",
125 "draw_xcl", "init_xcl", (char *) NULL, &xcl_opts ,
126 20000, -3, 1, 1, 64, 1.0, "",
127 "Shows a control line combat model race", 0, NULL};
128 #endif
129
130 typedef struct
131 {
132 int planes; /* number of planes viewed*/
133 int lines; /* number of lines counted in model */
134 double az[MAXCOUNT]; /* azimuth of plane */
135 double el[MAXCOUNT]; /* elevation of plane */
136 int width;
137 int height;
138 int mid_x;
139 int mid_y;
140 float Alpha; /* rotate.1 */
141 float Beta; /* rotate.2 */
142 float Gamma; /* rotate.3 */
143 float Vx; /* width from zero in X */
144 float Vy; /* width from zero in Y */
145 float Vz; /* width from zero in Z */
146 float G; /* ZOOM */
147 float Ca,Cb,Cc,Sa,Sb,Sc; /* only for faster calculation */
148 float Bx,By ;
149 struct timeval tv1;
150 double time1, time2, time3; /* calibrate time */
151 int drawtime;
152 double alpha[MAXCOUNT]; /* direction */
153 double omega_const[MAXCOUNT]; /* constant omega speed */
154 double delta_az[MAXCOUNT];
155 double delta_el[MAXCOUNT];
156 int turn[MAXCOUNT];
157 int turn_direction[MAXCOUNT];
158 int random_pid;
159 long planecolor[MAXCOUNT],bg; /* used colours */
160 GC gc[MAXCOUNT];
161 GC erase_gc;
162 XSegment *xseg[MAXCOUNT];
163 XSegment *xseg_old[MAXCOUNT];
164 int xcldelay;
165 int no_preset;
166 } xclstruct;
167
168 static xclstruct *xcls = (xclstruct *) NULL;
169
my_random(void)170 static int my_random(void) /* not really good, but it works */
171 {
172 static int number;
173 number -= random_pid;
174 return ( 0x0fff & (number));
175 }
176
countlines(void)177 static int countlines(void)
178 {
179 int array;
180 int count = 0;
181 for(array = 0;array<LINEARRAYS;array++) {
182 count += model_data2[array][0] - 1;
183 }
184 return(count);
185 }
186
um2(int X,int Y,int Z,xclstruct * dp)187 static void um2(int X, int Y, int Z, xclstruct *dp)
188 {
189 float X2,X3,X4,Y1,Y3,Y4,Z1,Z2,Z4;
190
191 Y1 = dp->Ca * Y - dp->Sa * Z;
192 Z1 = dp->Sa * Y + dp->Ca * Z;
193 X2 = dp->Cb * X - dp->Sb * Z1;
194 Z2 = dp->Sb * X + dp->Cb * Z1;
195 X3 = dp->Cc * X2 - dp->Sc * Y1;
196 Y3 = dp->Sc * X2 + dp->Cc * Y1;
197 X4 = X3 + dp->Vx;
198 Y4 = Y3 + dp->Vy;
199 Z4 = Z2 + dp->Vz;
200
201 dp->Bx = dp->mid_x + (-X4 / Y4 * dp->G);
202 dp->By = dp->mid_y - (-Z4 / Y4 * dp->G);
203 }
204
view_3d(XSegment * xseg,xclstruct * dp)205 static void view_3d(XSegment *xseg, xclstruct *dp)
206 {
207 int count = 0;
208 int I,J;
209 float BX [ENDPOINTS];
210 float BY [ENDPOINTS];
211
212 dp->Ca = cos(dp->Alpha);
213 dp->Cb = cos(dp->Beta);
214 dp->Cc = cos(dp->Gamma);
215 dp->Sa = sin(dp->Alpha);
216 dp->Sb = sin(dp->Beta);
217 dp->Sc = sin(dp->Gamma);
218
219 for(I = 0; I < ENDPOINTS; I++) {
220 um2( model_data1 [ I * 3 + 0], model_data1 [ I * 3 + 1],
221 model_data1 [ I * 3 + 2],dp);
222 BX [I] = dp->Bx;
223 BY [I] = dp->By;
224 }
225 for (I = 0; I < LINEARRAYS; I++) {
226 for (J = 1; J < model_data2[I][0]; J++) {
227 xseg[count].x1 = (short) BX[(model_data2[I][J])-1];
228 xseg[count].y1 = (short) BY[(model_data2[I][J])-1]+(dp->mid_y/2);
229 xseg[count].x2 = (short) BX[(model_data2[I][J+1])-1];
230 xseg[count].y2 = (short) BY[(model_data2[I][J+1])-1]+(dp->mid_y/2);
231 count++;
232 }
233 }
234 }
235
get_color(ModeInfo * mi,char * color,XColor * final_color)236 static long get_color(ModeInfo *mi, char *color, XColor *final_color)
237 {
238 Display *display = MI_DISPLAY(mi);
239 XColor cdef;
240 Colormap cmap;
241 cmap = DefaultColormap(display, MI_SCREEN(mi));
242
243 if (!XParseColor(display, cmap, color, &cdef) ||
244 !XAllocColor(display, cmap, &cdef))
245 {
246 (void) fprintf(stderr, "Color \"%s\" wasn't found\n", color);
247 }
248
249 if (final_color != NULL) *final_color = cdef; /* copy the final color. */
250
251 return(cdef.pixel);
252 }
253
get_GC(Display * dpy,Window win,GC * gc,long color)254 static Bool get_GC(Display *dpy,Window win,GC *gc,long color)
255 {
256 unsigned long valuemask = 0; /*ignore XGCvalues and use defaults */
257 XGCValues values;
258 unsigned int line_width = 1;
259 int line_style = LineSolid; /* LineOnOffDash;*/
260 int cap_style = CapRound;
261 int join_style = JoinRound;
262
263 if ((*gc = XCreateGC(dpy, win, valuemask , &values)) == None)
264 return False;
265 XSetForeground(dpy, *gc, color);
266
267 XSetLineAttributes(dpy, *gc, line_width, line_style,
268 cap_style, join_style);
269 return True;
270 }
271
272 static void
free_xcl_screen(Display * display,xclstruct * dp)273 free_xcl_screen(Display *display, xclstruct *dp)
274 {
275 int plane;
276
277 if (dp == NULL) {
278 return;
279 }
280 for (plane = 0; plane < dp->planes; plane++) {
281 if (dp->xseg[plane] != NULL) {
282 free(dp->xseg[plane]);
283 dp->xseg[plane] = (XSegment *) NULL;
284 }
285 if (dp->xseg_old[plane] != NULL) {
286 free(dp->xseg_old[plane]);
287 dp->xseg_old[plane] = (XSegment *) NULL;
288 }
289 if (dp->gc[plane] != None) {
290 XFreeGC(display, dp->gc[plane]);
291 dp->gc[plane] = None;
292 }
293 }
294 if (dp->erase_gc != None) {
295 XFreeGC(display, dp->erase_gc);
296 dp->erase_gc = None;
297 }
298 dp = NULL;
299 }
300
301 ENTRYPOINT void
init_xcl(ModeInfo * mi)302 init_xcl(ModeInfo * mi)
303 {
304 Display *display = MI_DISPLAY(mi);
305 int i; /* scratch */
306 xclstruct *dp;
307
308 MI_INIT(mi, xcls);
309 dp = &xcls[MI_SCREEN(mi)];
310
311 /* Update every time */
312 dp->width = MI_WIDTH(mi);
313 dp->height = MI_HEIGHT(mi);
314 dp->mid_x = (dp->width / 2);
315 dp->mid_y = (dp->height / 2);
316
317 if(dp->no_preset != 1) {
318 dp->no_preset = 1;
319 /* some presettings */
320 dp->planes = MI_COUNT(mi);
321 if (dp->planes < -MINPLANES) {
322 dp->planes = NRAND(-MI_COUNT(mi) -MINPLANES + 1) + MINPLANES;
323 } else if (dp->planes < MINPLANES) {
324 dp->planes = MINPLANES;
325 }
326 if(dp->planes > MAXCOUNT)
327 dp->planes = MAXCOUNT;
328 dp->Alpha = 0.0; /* rotate.1 */
329 dp->Beta = 0.0; /* rotate.2 */
330 dp->Gamma = 0.0; /* rotate.3 */
331 dp->Vx = 1; /* width from zero in X */
332 dp->Vy = 800; /* width from zero in Y */
333 dp->Vz = -300; /* width from zero in Z */
334 dp->G = 500.0; /* ZOOM */
335 dp->time3 = 1.0;
336 dp->drawtime = 25000;
337 dp->xcldelay = STARTUPDELAY;
338 for(i=0;i< dp->planes; i++) {
339 dp->az[i] = 2 * M_PI * i / (float)((dp->planes));
340 dp->el[i] = 0.0;
341 dp->alpha[i] = 0.75; /* direction */
342 dp->turn[i] = 0;
343 dp->turn_direction[i] = 1;
344
345 speed[i] = speed_in; /* see TODO */
346 }
347
348 random_pid = NRAND(31); /* goes here first for randomstart */
349
350 if(randomstart) {
351 for(i=0;i< dp->planes; i++) {
352 switch(i) {
353 case 0:
354 dp->az[0] += (random_pid % 31) / 5.0;
355 break;
356 default:
357 dp->az[i] = dp->az[0] + 2 * M_PI * i / (float)((dp->planes));
358 }
359 }
360 }
361
362 dp->bg = MI_BLACK_PIXEL(mi);
363
364 if(MI_NPIXELS(mi) <= 2)
365 for(i=0;i< dp->planes; i++) {
366 dp->planecolor[i] = MI_WHITE_PIXEL(mi);
367 }
368 else {
369 if(!oldcolor) {
370 for(i=0;i< dp->planes; i++) {
371 dp->planecolor[i] = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)));
372 }
373 }
374 else { /* with count >2 no so good */
375 for(i=0;i< dp->planes; i++) {
376 switch(i) {
377 case 0:
378 dp->planecolor[0] = get_color(mi, (char *) "yellow",
379 (XColor *) NULL);
380 break;
381 case 1:
382 dp->planecolor[1] = get_color(mi, (char *) "red",
383 (XColor *) NULL);
384 break;
385 default:
386 dp->planecolor[i] = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)));
387 }
388 }
389 }
390 }
391
392 if(dp->erase_gc == None)
393 if (!get_GC(display, MI_WINDOW(mi), &(dp->erase_gc),dp->bg)) {
394 free_xcl_screen(display, dp);
395 return;
396 }
397
398 dp->lines = countlines();
399
400 for(i=0;i< dp->planes; i++) {
401 if(dp->gc[i] == None)
402 if (!get_GC(display, MI_WINDOW(mi), &(dp->gc[i]),
403 dp->planecolor[i])) {
404 free_xcl_screen(display, dp);
405 return;
406 }
407 dp->omega_const[i] = speed[i]/3.6 /line_length*1000.0;
408
409 if(dp->xseg[i] == NULL)
410 if ((dp-> xseg[i] = (XSegment *) malloc(sizeof(XSegment) *
411 dp->lines)) == NULL) {
412 free_xcl_screen(display, dp);
413 return;
414 }
415 if(dp->xseg_old[i] == NULL)
416 if ((dp->xseg_old[i] = (XSegment *) malloc(sizeof(XSegment) *
417 dp->lines)) == NULL) {
418 free_xcl_screen(display, dp);
419 return;
420 }
421 }
422
423 if(MI_IS_VERBOSE(mi)) {
424 (void) printf("X control line combat in a box\n");
425 #if 0
426 (void) printf("Version: %s\n",sccsid);
427 #endif
428 (void) printf("Line length: %gm\n",line_length/1000.0);
429 (void) printf("Speed %g km/h \n",speed[0]);
430 (void) printf("Lines per plane: %d\n",dp->lines);
431 (void) printf("Spectator at %gm\n",spectator/1000.0);
432 (void) printf("Try %g frames per Second (frametime: %dus)\n",
433 1000000.0/frametime,frametime);
434 (void) printf("Calibration at %d frames\n",REGULATE);
435 }
436 }
437
438 /* clear the screen */
439
440 MI_CLEARWINDOW(mi);
441
442 (void) gettimeofday(&(dp->tv1),0);
443 dp->time1 = (double)dp->tv1.tv_sec +
444 (double)dp->tv1.tv_usec/(double)1000000;
445
446 dp->xcldelay = frametime;
447 }
448
449 ENTRYPOINT void
draw_xcl(ModeInfo * mi)450 draw_xcl(ModeInfo * mi)
451 {
452 static int count = 0;
453 int i;
454 xclstruct *dp;
455
456 if (xcls == NULL)
457 return;
458 dp = &xcls[MI_SCREEN(mi)];
459 if (dp->erase_gc == None)
460 return;
461
462 MI_IS_DRAWN(mi) = True;
463
464 if(viewmodel == True)
465 {
466 dp->Vx = 1; /* movement in X (width,negative)*/
467 if(dp->width < 900)
468 dp->Vy = 800*800/dp->width; /* Y (deep)*/
469 else
470 dp->Vy = 800*1200/dp->width; /* Y (deep)*/
471 dp->Vz = -300; /* Z (height) */
472 dp->G = 350.0; /* make it smaller when display is smaller */
473 dp->Alpha += 0.03;
474 dp->Beta += 0.006;
475 dp->Gamma += 0.009;
476
477 if (count != 0) {
478 XDrawSegments(MI_DISPLAY(mi),MI_WINDOW(mi),dp->erase_gc,
479 dp->xseg_old[0],dp->lines);
480 XDrawSegments(MI_DISPLAY(mi),MI_WINDOW(mi),dp->gc[0],
481 dp->xseg[0],dp->lines);
482 (void) usleep(ROTATEDELAY * 2);
483 }
484 (void) memcpy(dp->xseg_old[0],dp->xseg[0],sizeof(XSegment)*dp->lines);
485 view_3d(dp->xseg[0],dp);
486 count ++;
487 }
488 else {
489 if(automatic)
490 dp->G = dp->width / 2.1 ;
491
492 for(i=0;i<dp->planes;i++) {
493 (void) memcpy(dp->xseg_old[i],dp->xseg[i],sizeof(XSegment)*dp->lines);
494
495 dp->Alpha = - dp->alpha[i];
496 dp->Beta = - dp->el[i];
497 dp->Gamma = dp->az[i];
498
499 dp->Vx = -(int)(cos(dp->az[i]) * cos(dp->el[i]) * line_length);
500 dp->Vy = spectator -
501 (int)(sin(dp->az[i]) * cos(dp->el[i]) * line_length);
502 dp->Vz = (int)(sin(dp->el[i]) * line_length);
503
504 view_3d(dp->xseg[i],dp);
505 XDrawSegments(MI_DISPLAY(mi),MI_WINDOW(mi),dp->erase_gc,
506 dp->xseg_old[i],dp->lines);
507 XDrawSegments(MI_DISPLAY(mi),MI_WINDOW(mi),dp->gc[i],
508 dp->xseg[i],dp->lines);
509 }
510
511 XFlush(MI_DISPLAY(mi));
512
513 /* now move all planes */
514 for(i=0;i<dp->planes;i++) {
515 dp->delta_az[i] = cos(dp->alpha[i]) * dp->omega_const[i] *
516 frametime/1000000;
517 dp->delta_el[i] = sin(dp->alpha[i]) * dp->omega_const[i] *
518 frametime/1000000;
519
520 dp->az[i] -= dp->delta_az[i];
521 dp->el[i] -= dp->delta_el[i];
522
523 if (dp->el[i] >= 0.0)
524 switch (dp->turn[i]) {
525 case 0:
526 dp->turn_direction[i] *= -1;
527 dp->alpha[i] += 0.62831853 * dp->turn_direction[i];
528 dp->turn[i] ++;
529 break;
530 case 1:
531 case 2:
532 case 3:
533 case 4:
534 case 5:
535 dp->alpha[i] += 0.62831853 * dp->turn_direction[i];
536 dp->turn[i] ++;
537 break;
538 default:
539 dp->turn[i] ++;
540 break;
541 }
542 else
543 dp->turn[i] = 0;
544 if (dp->el[i] <= -(M_PI / 2.0))
545 {
546 dp->alpha[i] += M_PI;
547 dp->az[i] += M_PI;
548 /* el[i] = el[i] + (M_PI / 2.0) ; */
549 }
550 else
551 if(dp->turn[i] == 0)
552 dp->alpha[i] += (double)(RAND(600)) / 6283.0 * 2.0 * M_PI;
553 } /* for (i) */
554
555 count++;
556
557 (void) usleep(dp->xcldelay);
558 if((count % REGULATE) == 0) {
559 (void) gettimeofday(&(dp->tv1),0);
560 dp->time2 = (double)dp->tv1.tv_sec + (double)dp->tv1.tv_usec/
561 (double)1000000;
562 dp->time3 = dp->time2 - dp->time1;
563 dp->time1 = dp->time2;
564 dp->drawtime = (int) (dp->time3 * (1000000/REGULATE))
565 - dp->xcldelay;
566 if((dp->xcldelay = frametime - dp->drawtime) <= 0) {
567 dp->xcldelay = 10; /* 1 is possible xor xscreensaver mode */
568 }
569 if(debug == True)
570 (void) printf("t_draw: %d, t_delay: %d\n",dp->drawtime,
571 dp->xcldelay);
572 }
573 }
574 }
575
576 ENTRYPOINT void
release_xcl(ModeInfo * mi)577 release_xcl(ModeInfo * mi)
578 {
579 if (xcls != NULL) {
580 int screen;
581 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
582 free_xcl_screen(MI_DISPLAY(mi), &xcls[screen]);
583 free(xcls);
584 xcls = (xclstruct *) NULL;
585 }
586 }
587
588 XSCREENSAVER_MODULE ("Xcl", xcl)
589
590 #endif /* MODE_xcl */
591