3 Copyright (C) Teemu Suutari (temisu@utu.fi) Feb 1998
5 Permission is hereby granted, free of charge, to any person obtaining
6 a copy of this software and associated documentation files (the
7 "Software"), to deal in the Software without restriction, including
8 without limitation the rights to use, copy, modify, merge, publish,
9 distribute, sublicense, and/or sell copies of the Software, and to
10 permit persons to whom the Software is furnished to do so, subject to
11 the following conditions:
13 The above copyright notice and this permission notice shall be included
14 in all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of the X Consortium shall
25 not be used in advertising or otherwise to promote the sale, use or
26 other dealings in this Software without prior written authorization
27 from the X Consortium.
36 *** This is contest-version. Don't look any further, code is *very* ugly.
41 #include "screenhack.h"
43 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
45 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
48 #define countof(x) (sizeof((x))/sizeof((*x)))
50 static const char *kumppa_defaults [] ={
56 /* leave this off by default, since it slows things down. -- jwz. */
59 "*ignoreRotation: True",
64 static XrmOptionDescRec kumppa_options [] = {
65 {"-delay", ".delay", XrmoptionSepArg, 0 },
66 {"-speed", ".speed", XrmoptionSepArg, 0 },
67 {"-random", ".random", XrmoptionNoArg, "True" },
68 {"-no-random", ".random", XrmoptionNoArg, "False" },
69 {"-db", ".useDBE", XrmoptionNoArg, "True" },
70 {"-no-db", ".useDBE", XrmoptionNoArg, "False" },
74 static const unsigned char colors[96]=
75 {0,0,255, 0,51,255, 0,102,255, 0,153,255, 0,204,255,
76 0,255,255,0,255,204, 0,255,153, 0,255,102, 0,255,51,
77 0,255,0, 51,255,0, 102,255,0, 153,255,0, 204,255,0,
78 255,255,0, 255,204,0, 255,153,0, 255,102,0, 255,51,0,
79 255,0,0, 255,0,51, 255,0,102, 255,0,153, 255,0,204,
80 255,0,255, 219,0,255, 182,0,255, 146,0,255, 109,0,255,
82 static const float cosinus[8][6]=
83 {{-0.07,0.12,-0.06,32,25,37},{0.08,-0.03,0.05,51,46,32},{0.12,0.07,-0.13,27,45,36},
84 {0.05,-0.04,-0.07,36,27,39},{-0.02,-0.07,0.1,21,43,42},{-0.11,0.06,0.02,51,25,34},{0.04,-0.15,0.02,42,32,25},
85 {-0.02,-0.04,-0.13,34,20,15}};
111 int rotsizeX,rotsizeY;
116 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
119 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
125 static int Satnum(int maxi)
127 return (int)(maxi*frand(1));
131 static void palaRotate(struct state *st, int x,int y)
133 int ax,ay,bx,by,cx,cy;
137 bx=st->rotateX[x+1]+2;
138 by=st->rotateY[y+1]+2;
139 cx=st->rotateX[x]-(y-st->ry)+x-st->rx;
140 cy=st->rotateY[y]+(x-st->rx)+y-st->ry;
151 if (cx+bx-ax>st->sizx) bx=ax-cx+st->sizx;
152 if (cy+by-ay>st->sizy) by=ay-cy+st->sizy;
154 XCopyArea(st->dpy,st->win[0],st->win[1],st->cgc,ax,ay,bx-ax,by-ay,cx,cy);
158 static void rotate(struct state *st)
163 st->rx=st->Xrottable[st->stateX+1]-st->Xrottable[st->stateX];
164 st->ry=st->Yrottable[st->stateY+1]-st->Yrottable[st->stateY];
167 for (x=0;x<=st->rx;x++)
168 st->rotateX[x]=(x)?st->midx-1-st->Xrotations[st->Xrottable[st->stateX+1]-x]:0;
169 for (x=0;x<=st->rx;x++)
170 st->rotateX[x+st->rx+1]=(x==st->rx)?st->sizx-1:st->midx+st->Xrotations[st->Xrottable[st->stateX]+x];
171 for (y=0;y<=st->ry;y++)
172 st->rotateY[y]=(y)?st->midy-1-st->Yrotations[st->Yrottable[st->stateY+1]-y]:0;
173 for (y=0;y<=st->ry;y++)
174 st->rotateY[y+st->ry+1]=(y==st->ry)?st->sizy-1:st->midy+st->Yrotations[st->Yrottable[st->stateY]+y];
176 x=(st->rx>st->ry)?st->rx:st->ry;
177 for (dy=0;dy<(x+1)<<1;dy++)
178 for (dx=0;dx<(x+1)<<1;dx++)
180 y=(st->rx>st->ry)?st->ry-st->rx:0;
181 if (dy+y>=0 && dy<(st->ry+1)<<1 && dx<(st->rx+1)<<1)
182 if (dy+y+dx<=st->ry+st->rx && dy+y-dx<=st->ry-st->rx)
184 palaRotate(st, (st->rx<<1)+1-dx,dy+y);
185 palaRotate(st, dx,(st->ry<<1)+1-dy-y);
187 y=(st->ry>st->rx)?st->rx-st->ry:0;
188 if (dy+y>=0 && dx<(st->ry+1)<<1 && dy<(st->rx+1)<<1)
189 if (dy+y+dx<=st->ry+st->rx && dx-dy-y>=st->ry-st->rx)
191 palaRotate(st, dy+y,dx);
192 palaRotate(st, (st->rx<<1)+1-dy-y,(st->ry<<1)+1-dx);
196 if (st->stateX==st->rotsizeX) st->stateX=0;
198 if (st->stateY==st->rotsizeY) st->stateY=0;
203 static Bool make_rots(struct state *st, double xspeed,double yspeed)
205 int a,b,c,f,g,j,k=0,l;
212 st->rotsizeX=(int)(2/xspeed+1);
213 ix=(double)(st->midx+1)/(double)(st->rotsizeX);
214 st->rotsizeY=(int)(2/yspeed+1);
215 iy=(double)(st->midy+1)/(double)(st->rotsizeY);
217 st->Xrotations=malloc((st->midx+2)*sizeof(unsigned int));
218 st->Xrottable=malloc((st->rotsizeX+1)*sizeof(unsigned int));
219 st->Yrotations=malloc((st->midy+2)*sizeof(unsigned int));
220 st->Yrottable=malloc((st->rotsizeY+1)*sizeof(unsigned int));
221 chks=malloc(((st->midx>st->midy)?st->midx:st->midy)*sizeof(Bool));
222 if (!st->Xrottable || !st->Yrottable || !st->Xrotations || !st->Yrotations || !chks) return False;
229 for (a=0;a<st->midx;a++) chks[a]=True;
230 for (a=0;a<st->rotsizeX;a++)
233 f=(int)(d+ix)-g; /*viivojen lkm.*/
243 for (j=0;j<st->midx;j++) /*testi*/
250 while (j+l<st->midx && om+12*ok>m)
252 if (j-l>=0) if (chks[j-l]) om+=ok;
253 else; else if (chks[l-j]) om+=ok;
254 if (chks[j+l]) om+=ok;
267 while (l>=st->Xrottable[a])
269 if (l!=st->Xrottable[a]) st->Xrotations[l]=st->Xrotations[l-1];
270 if (k>st->Xrotations[l] || l==st->Xrottable[a])
280 if (maxi<c-st->Xrottable[a]) maxi=c-st->Xrottable[a];
283 st->rotateX=malloc((maxi+2)*sizeof(int)<<1);
284 if (!st->rotateX) return False;
290 for (a=0;a<st->midy;a++) chks[a]=True;
291 for (a=0;a<st->rotsizeY;a++)
294 f=(int)(d+iy)-g; /*viivojen lkm.*/
304 for (j=0;j<st->midy;j++) /*testi*/
311 while (j+l<st->midy && om+12*ok>m)
313 if (j-l>=0) if (chks[j-l]) om+=ok;
314 else; else if (chks[l-j]) om+=ok;
315 if (chks[j+l]) om+=ok;
328 while (l>=st->Yrottable[a])
330 if (l!=st->Yrottable[a]) st->Yrotations[l]=st->Yrotations[l-1];
331 if (k>st->Yrotations[l] || l==st->Yrottable[a])
342 if (maxi<c-st->Yrottable[a]) maxi=c-st->Yrottable[a];
345 st->rotateY=malloc((maxi+2)*sizeof(int)<<1);
346 if (!st->rotateY) return False;
353 static Bool InitializeAll(struct state *st)
356 XWindowAttributes xgwa;
357 /* XSetWindowAttributes xswa;*/
363 st->cosilines = True;
365 XGetWindowAttributes(st->dpy,st->win[0],&xgwa);
367 /* xswa.backing_store=Always;
368 XChangeWindowAttributes(st->dpy,st->win[0],CWBackingStore,&xswa);*/
369 xgcv.function=GXcopy;
371 xgcv.foreground=get_pixel_resource (st->dpy, cmap, "background", "Background");
372 st->fgc[32]=XCreateGC(st->dpy,st->win[0],GCForeground|GCFunction,&xgcv);
377 st->fgc[0]=st->fgc[32];
378 xgcv.foreground=get_pixel_resource (st->dpy, cmap, "foreground", "Foreground");
379 st->fgc[1]=XCreateGC(st->dpy,st->win[0],GCForeground|GCFunction,&xgcv);
380 for (i=0;i<32;i+=2) st->fgc[i]=st->fgc[0];
381 for (i=1;i<32;i+=2) st->fgc[i]=st->fgc[1];
385 color.red=colors[n++]<<8;
386 color.green=colors[n++]<<8;
387 color.blue=colors[n++]<<8;
388 color.flags=DoRed|DoGreen|DoBlue;
389 XAllocColor(st->dpy,cmap,&color);
390 xgcv.foreground=color.pixel;
391 st->fgc[i]=XCreateGC(st->dpy,st->win[0],GCForeground|GCFunction,&xgcv);
393 st->cgc=XCreateGC(st->dpy,st->win[0],GCForeground|GCFunction,&xgcv);
394 XSetGraphicsExposures(st->dpy,st->cgc,False);
396 st->cosilines = get_boolean_resource(st->dpy, "random","Boolean");
398 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
399 if (get_boolean_resource (st->dpy, "useDBE", "Boolean"))
400 st->usedouble = True;
401 st->win[1] = xdbe_get_backbuffer (st->dpy, st->win[0], XdbeUndefined);
404 st->usedouble = False;
405 st->win[1] = st->win[0];
407 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
409 st->delay=get_integer_resource(st->dpy, "delay","Integer");
410 rspeed=get_float_resource(st->dpy, "speed","Float");
411 if (rspeed<0.0001 || rspeed>0.2)
413 fprintf(stderr,"Speed not in valid range! (0.0001 - 0.2), using 0.1 \n");
418 st->sizy=xgwa.height;
419 st->midx=st->sizx>>1;
420 st->midy=st->sizy>>1;
424 if (!make_rots(st,rspeed,rspeed))
426 fprintf(stderr,"Not enough memory for tables!\n");
433 kumppa_init (Display *d, Window w)
435 struct state *st = (struct state *) calloc (1, sizeof(*st));
438 if (!InitializeAll(st)) abort();
440 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
443 st->xdswp.swap_action=XdbeUndefined;
444 st->xdswp.swap_window=st->win[0];
447 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
448 st->win[1]=st->win[0];
454 kumppa_draw (Display *d, Window w, void *closure)
456 struct state *st = (struct state *) closure;
467 st->acosinus[a][b]+=cosinus[a][b];
468 f+=cosinus[a][b+3]*sin((double)st->acosinus[a][b]);
470 st->coords[a]=(int)f;
474 XDrawLine(st->dpy,st->win[0],(mono_p)?st->fgc[1]:st->fgc[((a<<2)+st->draw_count)&31],st->midx+st->ocoords[a<<1],st->midy+st->ocoords[(a<<1)+1]
475 ,st->midx+st->coords[a<<1],st->midy+st->coords[(a<<1)+1]);
476 st->ocoords[a<<1]=st->coords[a<<1];
477 st->ocoords[(a<<1)+1]=st->coords[(a<<1)+1];
487 b=Satnum(32)-16+st->midx;
488 st->draw_count=Satnum(32)-16+st->midy;
489 XFillRectangle(st->dpy,st->win[0],st->fgc[a],b,st->draw_count,2,2);
492 XFillRectangle(st->dpy,st->win[0],st->fgc[32],st->midx-2,st->midy-2,4,4);
494 #ifdef HAVE_DOUBLE_BUFFER_EXTENSION
495 if (st->usedouble) XdbeSwapBuffers(st->dpy,&st->xdswp,1);
496 #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
503 kumppa_reshape (Display *dpy, Window window, void *closure,
504 unsigned int w, unsigned int h)
506 struct state *st = (struct state *) closure;
509 st->midx=st->sizx>>1;
510 st->midy=st->sizy>>1;
516 kumppa_event (Display *dpy, Window window, void *closure, XEvent *event)
522 kumppa_free (Display *dpy, Window window, void *closure)
524 struct state *st = (struct state *) closure;
526 for (i = 0; i < countof(st->fgc); i++)
527 if (st->fgc[i]) XFreeGC (dpy, st->fgc[i]);
528 XFreeGC (dpy, st->cgc);
529 free (st->Xrotations);
530 free (st->Yrotations);
531 free (st->Xrottable);
532 free (st->Yrottable);
536 XSCREENSAVER_MODULE ("Kumppa", kumppa)