1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* kumppa --- */
3
4 #if 0
5 static const char sccsid[] = "@(#)kumppa.c 5.00 2000/11/01 xlockmore";
6
7 #endif
8
9 /*-
10 Copyright (C) Teemu Suutari (temisu@utu.fi) Feb 1998
11
12 Permission is hereby granted, free of charge, to any person obtaining
13 a copy of this software and associated documentation files (the
14 "Software"), to deal in the Software without restriction, including
15 without limitation the rights to use, copy, modify, merge, publish,
16 distribute, sublicense, and/or sell copies of the Software, and to
17 permit persons to whom the Software is furnished to do so, subject to
18 the following conditions:
19
20 The above copyright notice and this permission notice shall be included
21 in all copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
27 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29 OTHER DEALINGS IN THE SOFTWARE.
30
31 Except as contained in this notice, the name of the X Consortium shall
32 not be used in advertising or otherwise to promote the sale, use or
33 other dealings in this Software without prior written authorization
34 from the X Consortium.
35
36 * Revision History:
37 * 01-Nov-2000: Allocation checks
38 * 16-Jul-1998: xlockmore version by Jouk Jansen <joukj AT hrem.nano.tudelft.nl>
39 * Feb 1998 : original xscreensaver version by Teemu Suutari <temisu@utu.fi>
40 */
41
42 /*-
43 *** This is contest-version. Don't look any further, code is *very* ugly.
44 */
45
46
47 #if 0
48 /* commented out since xlockmore does not support (yet) double buffering */
49 #ifdef HAVE_XDBE_EXTENSION
50 #include <X11/extensions/Xdbe.h>
51 #endif /* HAVE_XDBE_EXTENSION */
52 #endif
53
54 #ifdef STANDALONE
55 #define MODE_kumppa
56 #define DEFAULTS "*delay: 0 \n" \
57 "*cycles: 1000 \n" \
58 ".background: black\n" \
59
60 # define free_kumppa 0
61 # define reshape_kumppa 0
62 # define kumppa_handle_event 0
63 #include "xlockmore.h" /* in xscreensaver distribution */
64 #else /* STANDALONE */
65 #include "xlock.h" /* in xlockmore distribution */
66
67 #endif /* STANDALONE */
68
69 #ifdef MODE_kumppa
70
71 #define DEF_COSILINES "True"
72 #define DEF_SPEED "0.1"
73
74 #if 0
75 #ifdef HAVE_XDBE_EXTENSION
76 #define DEF_USEDOUBLE "False"
77
78 static Bool usedouble;
79
80 #endif /* HAVE_XDBE_EXTENSION */
81 #endif
82
83 static Bool cosilines;
84 static float speed;
85
86 static XrmOptionDescRec opts[] =
87 {
88 {(char *) "-speed", (char *) ".kumppa.speed", XrmoptionSepArg, (caddr_t) NULL},
89 #if 0
90 #ifdef HAVE_XDBE_EXTENSION
91 {(char *) "-dbuf", (char *) ".kumppa.dbuf", XrmoptionNoArg, (caddr_t) "on"},
92 {(char *) "+dbuf", (char *) ".kumppa.dbuf", XrmoptionNoArg, (caddr_t) "off"},
93 #endif /* HAVE_XDBE_EXTENSION */
94 #endif
95 {(char *) "-rrandom", (char *) ".kumppa.rrandom", XrmoptionNoArg, (caddr_t) "on"},
96 {(char *) "+rrandom", (char *) ".kumppa.rrandom", XrmoptionNoArg, (caddr_t) "off"}
97 };
98
99 static argtype vars[] =
100 {
101 {(void *) & speed, (char *) "speed", (char *) "speed", (char *) DEF_SPEED, t_Float},
102 #if 0
103 #ifdef HAVE_XDBE_EXTENSION
104 {(void *) & usedouble, (char *) "dbuf", (char *) "dbuf", (char *) DEF_USEDOUBLE, t_Bool},
105 #endif /* HAVE_XDBE_EXTENSION */
106 #endif
107 {(void *) & cosilines, (char *) "rrandom", (char *) "rrandom", (char *) DEF_COSILINES, t_Bool}
108 };
109 static OptionStruct desc[] =
110 {
111 {(char *) "-speed num", (char *) "Speed"},
112 #if 0
113 #ifdef HAVE_XDBE_EXTENSION
114 {(char *) "-/+dbuf", (char *) "turn on/off double buffering"},
115 #endif /* HAVE_XDBE_EXTENSION */
116 #endif
117 {(char *) "-/+rrandom", (char *) "turn on/off random"}
118 };
119
120 ENTRYPOINT ModeSpecOpt kumppa_opts =
121 {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
122
123 #ifdef USE_MODULES
124 ModStruct kumppa_description =
125 {"kumppa", "init_kumppa", "draw_kumppa", "release_kumppa",
126 "init_kumppa", "init_kumppa", (char *) NULL, &kumppa_opts,
127 10000, 1, 1000, 1, 64, 1.0, "",
128 "Shows Kumppa", 0, NULL};
129
130 #endif
131
132 static const unsigned char colors[96] =
133 {0, 0, 255, 0, 51, 255, 0, 102, 255, 0, 153, 255, 0, 204, 255,
134 0, 255, 255, 0, 255, 204, 0, 255, 153, 0, 255, 102, 0, 255, 51,
135 0, 255, 0, 51, 255, 0, 102, 255, 0, 153, 255, 0, 204, 255, 0,
136 255, 255, 0, 255, 204, 0, 255, 153, 0, 255, 102, 0, 255, 51, 0,
137 255, 0, 0, 255, 0, 51, 255, 0, 102, 255, 0, 153, 255, 0, 204,
138 255, 0, 255, 219, 0, 255, 182, 0, 255, 146, 0, 255, 109, 0, 255,
139 73, 0, 255, 37, 0, 255};
140
141 static const float cosinus[8][6] =
142 {
143 {-0.07, 0.12, -0.06, 32, 25, 37},
144 {0.08, -0.03, 0.05, 51, 46, 32},
145 {0.12, 0.07, -0.13, 27, 45, 36},
146 {0.05, -0.04, -0.07, 36, 27, 39},
147 {-0.02, -0.07, 0.1, 21, 43, 42},
148 {-0.11, 0.06, 0.02, 51, 25, 34},
149 {0.04, -0.15, 0.02, 42, 32, 25},
150 {-0.02, -0.04, -0.13, 34, 20, 15}};
151
152 static const float acosinus[24] =
153 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
154
155 static const int ocoords[8] =
156 {0, 0, 0, 0, 0, 0, 0, 0};
157
158 typedef struct {
159 Colormap cmap;
160 float *acosinus;
161 unsigned long blackpixel, whitepixel, fg, bg;
162 int coords[8];
163 int ocoords[8];
164
165 GC fgc[33];
166 GC cgc;
167 int sizx, sizy;
168 int midx, midy;
169
170 int *Xrotations;
171 int *Yrotations;
172 int *Xrottable;
173 int *Yrottable;
174
175 int *rotateX;
176 int *rotateY;
177
178 int rotsizeX, rotsizeY;
179 int stateX, stateY;
180 int dir, time;
181 int rx, ry;
182 int c;
183 long c1;
184 Bool cosilines;
185 } kumppastruct;
186
187 static kumppastruct *kumppas = (kumppastruct *) NULL;
188
189
190
191 static int
Satnum(int maxi)192 Satnum(int maxi)
193 {
194 return (int) (maxi * ((double) NRAND(2500) / 2500.0));
195 }
196
197
198 static void
palaRotate(ModeInfo * mi,int x,int y)199 palaRotate(ModeInfo * mi, int x, int y)
200 {
201 Display *display = MI_DISPLAY(mi);
202 Window window = MI_WINDOW(mi);
203 int ax, ay, bx, by, cx, cy;
204 kumppastruct *s = &kumppas[MI_SCREEN(mi)];
205
206 ax = s->rotateX[x];
207 ay = s->rotateY[y];
208 bx = s->rotateX[x + 1] + 2;
209 by = s->rotateY[y + 1] + 2;
210 cx = s->rotateX[x] + (x - s->rx) - s->dir * (y - s->ry);
211 cy = s->rotateY[y] + s->dir * (x - s->rx) + (y - s->ry);
212 if (cx < 0) {
213 ax -= cx;
214 cx = 0;
215 }
216 if (cy < 0) {
217 ay -= cy;
218 cy = 0;
219 }
220 if (cx + bx - ax > s->sizx)
221 bx = ax - cx + s->sizx;
222 if (cy + by - ay > s->sizy)
223 by = ay - cy + s->sizy;
224 if (ax < bx && ay < by) {
225 if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
226 XCopyArea(display, window, window, s->cgc, ax, ay, bx - ax, by - ay, cx, cy);
227 } else {
228 XCopyArea(display, window, window, MI_GC(mi), ax, ay, bx - ax, by - ay, cx, cy);
229 }
230 }
231 }
232
233
234 static void
rotate(ModeInfo * mi)235 rotate(ModeInfo * mi)
236 {
237 int x, y;
238 int dx, dy;
239 kumppastruct *s = &kumppas[MI_SCREEN(mi)];
240
241 s->rx = s->Xrottable[s->stateX + 1] - s->Xrottable[s->stateX];
242 s->ry = s->Yrottable[s->stateX + 1] - s->Yrottable[s->stateY];
243
244
245 for (x = 0; x <= s->rx; x++)
246 s->rotateX[x] = (x) ? s->midx - 1 - s->Xrotations[s->Xrottable[s->stateX + 1] - x] : 0;
247 for (x = 0; x <= s->rx; x++)
248 s->rotateX[x + s->rx + 1] = (x == s->rx) ? s->sizx - 1 : s->midx + s->Xrotations[s->Xrottable[s->stateX] + x];
249 for (y = 0; y <= s->ry; y++)
250 s->rotateY[y] = (y) ? s->midy - 1 - s->Yrotations[s->Yrottable[s->stateY + 1] - y] : 0;
251 for (y = 0; y <= s->ry; y++)
252 s->rotateY[y + s->ry + 1] = (y == s->ry) ? s->sizy - 1 : s->midy + s->Yrotations[s->Yrottable[s->stateY] + y];
253
254 x = (s->rx > s->ry) ? s->rx : s->ry;
255 for (dy = 0; dy < (x + 1) << 1; dy++)
256 for (dx = 0; dx < (x + 1) << 1; dx++) {
257 y = (s->rx > s->ry) ? s->ry - s->rx : 0;
258 if (dy + y >= 0 && dy < (s->ry + 1) << 1 && dx < (s->rx + 1) << 1)
259 if (dy + y + dx <= s->ry + s->rx && dy + y - dx <= s->ry - s->rx) {
260 palaRotate(mi, (s->rx << 1) + 1 - dx, dy + y);
261 palaRotate(mi, dx, (s->ry << 1) + 1 - dy - y);
262 }
263 y = (s->ry > s->rx) ? s->rx - s->ry : 0;
264 if (dy + y >= 0 && dx < (s->ry + 1) << 1 && dy < (s->rx + 1) << 1)
265 if (dy + y + dx <= s->ry + s->rx && dx - dy - y >= s->ry - s->rx) {
266 palaRotate(mi, dy + y, dx);
267 palaRotate(mi, (s->rx << 1) + 1 - dy - y, (s->ry << 1) + 1 - dx);
268 }
269 }
270 s->stateX++;
271 if (s->stateX == s->rotsizeX)
272 s->stateX = 0;
273 s->stateY++;
274 if (s->stateY == s->rotsizeY)
275 s->stateY = 0;
276 }
277
278 static void
free_kumppa_screen(ModeInfo * mi,kumppastruct * s)279 free_kumppa_screen(ModeInfo *mi, kumppastruct *s)
280 {
281 Display *display = MI_DISPLAY(mi);
282
283 if (s == NULL) {
284 return;
285 }
286 if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
287 int i;
288
289 MI_WHITE_PIXEL(mi) = s->whitepixel;
290 MI_BLACK_PIXEL(mi) = s->blackpixel;
291 #ifndef STANDALONE
292 MI_FG_PIXEL(mi) = s->fg;
293 MI_BG_PIXEL(mi) = s->bg;
294 #endif
295 if (s->fgc[32] != None) {
296 XFreeGC(display, s->fgc[32]);
297 s->fgc[32] = None;
298 }
299 #if 0
300 if (mono_p) {
301 if (s->fgc[1] != None) {
302 XFreeGC(display, s->fgc[1]);
303 s->fgc[1] = None;
304 }
305 } else
306 #endif
307 for (i = 0; i < 32; i++) {
308 if (s->fgc[i] != None) {
309 XFreeGC(display, s->fgc[i]);
310 s->fgc[i] = None;
311 }
312 }
313 if (s->cgc != None) {
314 XFreeGC(display, s->cgc);
315 s->cgc = None;
316 }
317 if (s->cmap != None) {
318 XFreeColormap(display, s->cmap);
319 s->cmap = None;
320 }
321 }
322 if (s->acosinus != NULL) {
323 free(s->acosinus);
324 s->acosinus = (float *) NULL;
325 }
326 if (s->Xrotations != NULL) {
327 free(s->Xrotations);
328 s->Xrotations = (int *) NULL;
329 }
330 if (s->Yrotations != NULL) {
331 free(s->Yrotations);
332 s->Yrotations = (int *) NULL;
333 }
334 if (s->Xrottable != NULL) {
335 free(s->Xrottable);
336 s->Xrottable = (int *) NULL;
337 }
338 if (s->Yrottable != NULL) {
339 free(s->Yrottable);
340 s->Yrottable = (int *) NULL;
341 }
342 if (s->rotateX != NULL) {
343 free(s->rotateX);
344 s->rotateX = (int *) NULL;
345 }
346 if (s->rotateY != NULL) {
347 free(s->rotateY);
348 s->rotateY = (int *) NULL;
349 }
350 s = NULL;
351 }
352
353 static void
make_rots(ModeInfo * mi,double xspeed,double yspeed)354 make_rots(ModeInfo * mi, double xspeed, double yspeed)
355 {
356 int a, b, c, f, g, j, k = 0, l;
357 double m, om, ok;
358 double d, ix, iy;
359 int maxi;
360 kumppastruct *s = &kumppas[MI_SCREEN(mi)];
361
362 Bool *chks;
363
364 s->rotsizeX = (int) (2 / xspeed + 1);
365 ix = (double) (s->midx + 1) / (double) (s->rotsizeX);
366 s->rotsizeY = (int) (2 / yspeed + 1);
367 iy = (double) (s->midy + 1) / (double) (s->rotsizeY);
368
369 if (s->Xrotations != NULL)
370 free(s->Xrotations);
371 if (s->Yrotations != NULL)
372 free(s->Yrotations);
373 if (s->Xrottable != NULL)
374 free(s->Xrottable);
375 if (s->Yrottable != NULL)
376 free(s->Yrottable);
377
378 if (((s->Xrotations = (int *) calloc((s->midx + 2),
379 sizeof (int))) == NULL) ||
380 ((s->Yrotations = (int *) calloc((s->midy + 2),
381 sizeof (int))) == NULL) ||
382 ((s->Xrottable = (int *) malloc((s->rotsizeX + 1) *
383 sizeof (int))) == NULL) ||
384 ((s->Yrottable = (int *) malloc((s->rotsizeY + 1) *
385 sizeof (int))) == NULL) ||
386 ((chks = (Bool *) malloc(((s->midx > s->midy) ? s->midx : s->midy) *
387 sizeof (Bool))) == NULL)) {
388 free_kumppa_screen(mi, s);
389 return;
390 }
391
392
393 maxi = 0;
394 c = 0;
395 d = 0;
396 g = 0;
397 for (a = 0; a < s->midx; a++)
398 chks[a] = True;
399 for (a = 0; a < s->rotsizeX; a++) {
400 s->Xrottable[a] = c;
401 f = (int) (d + ix) - g; /*viivojen lkm. */
402 g += f;
403 if (g > s->midx) {
404 f -= g - s->midx;
405 g = s->midx;
406 }
407 for (b = 0; b < f; b++) {
408 m = 0;
409 for (j = 0; j < s->midx; j++) { /*testi */
410 if (chks[j]) {
411 om = 0;
412 ok = 1;
413 l = 0;
414 while (j + l < s->midx && om + 12 * ok > m) {
415 if (j - l >= 0) {
416 if (chks[j - l])
417 om += ok;
418 } else if (chks[l - j])
419 om += ok;
420 if (chks[j + l])
421 om += ok;
422 ok /= 1.5;
423 l++;
424 }
425 if (om >= m) {
426 k = j;
427 m = om;
428 }
429 }
430 }
431 chks[k] = False;
432 l = c;
433 while (l >= s->Xrottable[a]) {
434 if (l != s->Xrottable[a])
435 s->Xrotations[l] = s->Xrotations[l - 1];
436 if (k > s->Xrotations[l] || l == s->Xrottable[a]) {
437 s->Xrotations[l] = k;
438 c++;
439 l = s->Xrottable[a];
440 }
441 l--;
442 }
443 }
444 d += ix;
445 if (maxi < c - s->Xrottable[a])
446 maxi = c - s->Xrottable[a];
447 }
448 s->Xrottable[a] = c;
449 if (s->rotateX)
450 free(s->rotateX);
451 if ((s->rotateX = (int *) calloc((maxi + 2) << 1,
452 sizeof (int))) == NULL) {
453 free_kumppa_screen(mi, s);
454 free(chks);
455 return;
456 }
457
458 maxi = 0;
459 c = 0;
460 d = 0;
461 g = 0;
462 for (a = 0; a < s->midy; a++)
463 chks[a] = True;
464 for (a = 0; a < s->rotsizeY; a++) {
465 s->Yrottable[a] = c;
466 f = (int) (d + iy) - g; /*viivojen lkm. */
467 g += f;
468 if (g > s->midy) {
469 f -= g - s->midy;
470 g = s->midy;
471 }
472 for (b = 0; b < f; b++) {
473 m = 0;
474 for (j = 0; j < s->midy; j++) { /*testi */
475 if (chks[j]) {
476 om = 0;
477 ok = 1;
478 l = 0;
479 while (j + l < s->midy && om + 12 * ok > m) {
480 if (j - l >= 0) {
481 if (chks[j - l])
482 om += ok;
483 } else if (chks[l - j])
484 om += ok;
485 if (chks[j + l])
486 om += ok;
487 ok /= 1.5;
488 l++;
489 }
490 if (om >= m) {
491 k = j;
492 m = om;
493 }
494 }
495 }
496 chks[k] = False;
497 l = c;
498 while (l >= s->Yrottable[a]) {
499 if (l != s->Yrottable[a])
500 s->Yrotations[l] = s->Yrotations[l - 1];
501 if (k > s->Yrotations[l] || l == s->Yrottable[a]) {
502 s->Yrotations[l] = k;
503 c++;
504 l = s->Yrottable[a];
505 }
506 l--;
507 }
508
509 }
510 d += iy;
511 if (maxi < c - s->Yrottable[a])
512 maxi = c - s->Yrottable[a];
513 }
514 s->Yrottable[a] = c;
515 if (s->rotateY)
516 free(s->rotateY);
517 if ((s->rotateY = (int *) calloc((maxi + 2) << 1,
518 sizeof (int))) == NULL) {
519 free_kumppa_screen(mi, s);
520 /* free(chks); */
521 /* return; */
522 }
523
524 free(chks);
525 }
526
527 #ifndef STANDALONE
528 extern char *background;
529 extern char *foreground;
530 #endif
531
532 ENTRYPOINT void
init_kumppa(ModeInfo * mi)533 init_kumppa(ModeInfo * mi)
534 {
535 Display *display = MI_DISPLAY(mi);
536 Window window = MI_WINDOW(mi);
537 XGCValues xgcv;
538 int n, i;
539 kumppastruct *s;
540 double rspeed;
541
542 MI_INIT(mi, kumppas);
543 s = &kumppas[MI_SCREEN(mi)];
544
545 if (!s->acosinus) {
546 if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
547 XColor color;
548
549 #ifndef STANDALONE
550 s->fg = MI_FG_PIXEL(mi);
551 s->bg = MI_BG_PIXEL(mi);
552 #endif
553 s->blackpixel = MI_BLACK_PIXEL(mi);
554 s->whitepixel = MI_WHITE_PIXEL(mi);
555 if ((s->cmap = XCreateColormap(display, window,
556 MI_VISUAL(mi), AllocNone)) == None) {
557 free_kumppa_screen(mi, s);
558 return;
559 }
560
561 XSetWindowColormap(display, window, s->cmap);
562 (void) XParseColor(display, s->cmap, "black", &color);
563 (void) XAllocColor(display, s->cmap, &color);
564 MI_BLACK_PIXEL(mi) = color.pixel;
565 (void) XParseColor(display, s->cmap, "white", &color);
566 (void) XAllocColor(display, s->cmap, &color);
567 MI_WHITE_PIXEL(mi) = color.pixel;
568 #ifndef STANDALONE
569 (void) XParseColor(display, s->cmap, background, &color);
570 (void) XAllocColor(display, s->cmap, &color);
571 MI_BG_PIXEL(mi) = color.pixel;
572 (void) XParseColor(display, s->cmap, foreground, &color);
573 (void) XAllocColor(display, s->cmap, &color);
574 MI_FG_PIXEL(mi) = color.pixel;
575 #endif
576
577 xgcv.function = GXcopy;
578 xgcv.foreground = MI_BLACK_PIXEL(mi);
579 if ((s->fgc[32] = XCreateGC(display, window,
580 GCForeground | GCFunction,
581 &xgcv)) == None) {
582 free_kumppa_screen(mi, s);
583 return;
584 }
585
586 n = 0;
587 #if 0
588 if (mono_p) {
589 s->fgc[0] = s->fgc[32];
590 xgcv.foreground = MI_BLACK_PIXEL(mi);
591 if ((s->fgc[1] = XCreateGC(display, window,
592 GCForeground | GCFunction,
593 &xgcv)) == None) {
594 free_kumppa_screen(mi, s);
595 return;
596 }
597 for (i = 0; i < 32; i += 2)
598 s->fgc[i] = s->fgc[0];
599 for (i = 1; i < 32; i += 2)
600 s->fgc[i] = s->fgc[1];
601 } else
602 #endif
603 for (i = 0; i < 32; i++) {
604 color.red = colors[n++] * 256;
605 color.green = colors[n++] * 256;
606 color.blue = colors[n++] * 256;
607 color.flags = DoRed | DoGreen | DoBlue;
608 (void) XAllocColor(display, s->cmap, &color);
609 xgcv.foreground = color.pixel;
610 if ((s->fgc[i] = XCreateGC(display, window,
611 GCForeground | GCFunction,
612 &xgcv)) == None) {
613 free_kumppa_screen(mi, s);
614 return;
615 }
616 }
617 xgcv.foreground = MI_BLACK_PIXEL(mi);
618 xgcv.function = GXcopy;
619 if ((s->cgc = XCreateGC(display, window,
620 GCForeground | GCFunction,
621 &xgcv)) == None) {
622 free_kumppa_screen(mi, s);
623 return;
624 }
625 }
626 if ((s->acosinus = (float *) malloc(24 *
627 sizeof (float))) == NULL) {
628 free_kumppa_screen(mi, s);
629 return;
630 }
631 (void) memcpy(s->acosinus, acosinus, 24 * sizeof (float));
632 (void) memcpy(s->ocoords, ocoords, 8 * sizeof (int));
633 }
634
635 if (MI_IS_FULLRANDOM(mi)) {
636 if (NRAND(2) == 1)
637 s->cosilines = False;
638 else
639 s->cosilines = True;
640 } else {
641 s->cosilines = cosilines;
642 }
643 if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
644 XInstallColormap(display, s->cmap);
645 XSetGraphicsExposures(display, s->cgc, False);
646 } else {
647 XSetGraphicsExposures(display, MI_GC(mi), False);
648 s->c1 = NRAND(MI_NPIXELS(mi));
649 }
650 if (MI_CYCLES(mi) < 1)
651 s->time = 1;
652 else
653 s->time = MI_CYCLES(mi) + NRAND(MI_CYCLES(mi));
654
655 #if 0
656 #ifdef HAVE_XDBE_EXTENSION
657 if (get_string_resource("dbuf", "String") != NULL && get_string_resource("dbuf", "String")[0] != 0)
658 usedouble = True;
659 if (usedouble) {
660 XdbeQueryExtension(display, &n, &i);
661 if (n == 0 && i == 0) {
662 (void) fprintf(stderr, "Double buffer extension not supported!\n");
663 usedouble = False;
664 }
665 }
666 if (usedouble)
667 win[1] = XdbeAllocateBackBufferName(display, win[0], XdbeUndefined);
668 #endif /* HAVE_XDBE_EXTENSION */
669 #endif
670
671 if (speed < (float) 0.0001 || speed > (float) 0.2) {
672 (void) fprintf(stderr,
673 "Speed %g not in valid range! (0.0001 - 0.2), using 0.1\n",
674 speed);
675 speed = 0.1;
676 }
677 rspeed = (double) speed;
678 s->sizx = MI_WIDTH(mi);
679 s->sizy = MI_HEIGHT(mi);
680 s->midx = s->sizx >> 1;
681 s->midy = s->sizy >> 1;
682 s->stateX = 0;
683 s->stateY = 0;
684 s->c = 0;
685 s->dir = (LRAND() & 1) ? -1 : 1;
686 MI_CLEARWINDOW(mi);
687 make_rots(mi, rspeed, rspeed);
688 }
689
690
691 ENTRYPOINT void
draw_kumppa(ModeInfo * mi)692 draw_kumppa(ModeInfo * mi)
693 {
694 Display *display = MI_DISPLAY(mi);
695 Window window = MI_WINDOW(mi);
696 GC gc;
697
698 #if 0
699 #ifdef HAVE_XDBE_EXTENSION
700 XdbeSwapInfo xdswp;
701
702 #endif /* HAVE_XDBE_EXTENSION */
703 #endif
704 int a, b, e;
705 float f;
706 kumppastruct *s;
707
708 if (kumppas == NULL)
709 return;
710 s = &kumppas[MI_SCREEN(mi)];
711 if (s->Xrotations == NULL)
712 return;
713
714 MI_IS_DRAWN(mi) = True;
715
716 #if 0
717 #ifdef HAVE_XDBE_EXTENSION
718 if (usedouble) {
719 xdswp.swap_action = XdbeUndefined;
720 xdswp.swap_window = win[0];
721 } else
722 #endif /* HAVE_XDBE_EXTENSION */
723 win[1] = win[0];
724 #endif
725
726 if (s->cosilines) {
727 s->c++;
728 for (a = 0; a < 8; a++) {
729 f = 0;
730 for (b = 0; b < 3; b++) {
731 s->acosinus[a * 3 + b] += cosinus[a][b];
732 f += cosinus[a][b + 3] *
733 sin((double) s->acosinus[a * 3 + b]);
734 }
735 s->coords[a] = (int) f;
736 }
737 for (a = 0; a < 4; a++) {
738 if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
739 #if 0
740 gc = (mono_p) ? s->fgc[1] : s->fgc[((a << 2) + s->c) & 31];
741 #endif
742 gc = s->fgc[((a << 2) + s->c) & 31];
743 } else {
744 gc = MI_GC(mi);
745 if (MI_NPIXELS(mi) <= 2)
746 XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
747 else
748 XSetForeground(display, gc, MI_PIXEL(mi, ((((a << 2) + s->c) & 31) * MI_NPIXELS(mi) / 32) % MI_NPIXELS(mi)));
749 }
750 XDrawLine(display, window, gc,
751 s->midx + s->ocoords[a << 1], s->midy + s->ocoords[(a << 1) + 1],
752 s->midx + s->coords[a << 1], s->midy + s->coords[(a << 1) + 1]);
753 s->ocoords[a << 1] = s->coords[a << 1];
754 s->ocoords[(a << 1) + 1] = s->coords[(a << 1) + 1];
755 }
756
757 } else {
758 for (e = 0; e < 8; e++) {
759 a = Satnum(50);
760 if (a >= 32)
761 a = 32;
762 b = Satnum(32) - 16 + s->midx;
763 s->c = Satnum(32) - 16 + s->midy;
764 if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
765 gc = s->fgc[a];
766 } else {
767 gc = MI_GC(mi);
768 if (a == 32)
769 XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
770 else if (MI_NPIXELS(mi) > 2)
771 XSetForeground(display, gc, MI_PIXEL(mi, (a * MI_NPIXELS(mi) / 32) % MI_NPIXELS(mi)));
772 else if (a == 0)
773 XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
774 else
775 XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
776 }
777 XFillRectangle(display, window, gc, b, s->c, 2, 2);
778 }
779 }
780 if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
781 gc = s->fgc[32];
782 } else {
783 gc = MI_GC(mi);
784 XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
785 }
786 XFillRectangle(display, window, gc, s->midx - 2, s->midy - 2, 4, 4);
787 rotate(mi);
788 #if 0
789 #ifdef HAVE_XDBE_EXTENSION
790 if (usedouble)
791 XdbeSwapBuffers(display, &xdswp, 1);
792 #endif /* HAVE_XDBE_EXTENSION */
793 #endif
794 if (--s->time <= 0) {
795 if (MI_CYCLES(mi) < 1)
796 s->time = 1;
797 else
798 s->time = MI_CYCLES(mi) + NRAND(MI_CYCLES(mi));
799 s->dir = s->dir * (-1);
800 }
801 }
802
803 ENTRYPOINT void
release_kumppa(ModeInfo * mi)804 release_kumppa(ModeInfo * mi)
805 {
806
807 if (kumppas != NULL) {
808 int screen;
809
810 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
811 free_kumppa_screen(mi, &kumppas[screen]);
812 free(kumppas);
813 kumppas = (kumppastruct *) NULL;
814 }
815 }
816
817 XSCREENSAVER_MODULE ("Kumppa", kumppa)
818
819 #endif /* MODE_kumppa */
820