1 /*
2  *  XGuts... hiding some of the X details
3  */
4 #include <stdio.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include <X11/X.h>
8 #include <X11/Xlib.h>
9 #include <X11/Xutil.h>
10 #include <X11/Xos.h>
11 #include "trippy.h"
12 #include "vroot.h"
13 #include "password.h"
14 
15 extern int *jj,startup,dropachicken;
16 extern char *password;
17 extern Visual *vis;
18 extern int l,r,t,b;
19 static void maybe_unlock(XEvent*);
20 static XWindowAttributes win_att;
21 static XSetWindowAttributes s_win_att;
22 extern struct particle **partlst;
23 extern int x,y;
24 extern struct timeval *schedule, *intervals;
25 
26 #define PASSLEN 20
27 
28 void
maybe_unlock(XEvent * event)29 maybe_unlock (XEvent * event)
30 {
31   Window          textWin;
32   char            checkme[80], c;
33   XGCValues       values;
34   int             charIndex = 0, len = 0, i = 0, done=False;
35   char            keystr[PASSLEN];
36 
37   checkme[0] = 0;
38 
39 /* create a window to take in the text */
40   textWin = XCreateSimpleWindow (display, window[0],
41 				 200, 50, 200, 50,
42 				 options.bwidth, options.bdcolor,
43 				 options.bgcolor);
44   XSelectInput (display, textWin, KeyPressMask);
45   XMapWindow (display, textWin);
46   XRaiseWindow (display, textWin);
47 
48   values.foreground = StrColor ("white", WhitePixel (display, screen));
49   XChangeGC (display, color_gcs[1], GCForeground, &values);
50   XDrawString (display, textWin, color_gcs[1], 5, 30,
51 	       options.inqPassword ? "Enter your key:" : "Enter Password:",16);
52   XFlush (display);
53 
54   /* grab the text. compare it to the password */
55   while (done==False)
56   {
57     if (XCheckMaskEvent (display, ~0L, event) == True)
58     {
59       switch (event->type)
60       {
61 	case KeyPress:
62 	  len = XLookupString ((XKeyEvent*)event, keystr, PASSLEN, NULL, NULL);
63 	  for (i = 0; i < len; i++)
64 	  {
65 	    c = keystr[i];
66 	    switch (c)
67 	    {
68 	      case 8:	/* ^H */
69 	      case 127:	/* DEL */
70 		if (charIndex > 0)
71 		  charIndex--;
72 		break;
73 	      case 10:	/* ^J */
74 	      case 13:	/* ^M */
75 		checkme[charIndex] = '\0';
76 		done=True;
77 		break;
78 	      case 21:	/* ^U */
79 		charIndex = 0;
80 		break;
81 	      default:
82 		checkme[charIndex] = c;
83 		if (charIndex < PASSLEN - 1)
84 		  charIndex++;
85 		else
86 		  XSync (display, True);	/* flush input buffer */
87 		break;
88 	    }
89 	  }
90 	  break;
91 	case ButtonPress:
92 	  done=True;
93 	  break;
94 	default:
95 	  break;
96       }
97     }
98   }
99 
100   /* if they're equal... kill the 2 windows */
101   if ((!options.inqPassword && (matchesPassword(checkme, options.allowroot)))||
102       (options.inqPassword && (!strcmp(checkme,password))))
103   {
104     XDestroyWindow (display, textWin);
105     if (!options.debug)
106     {
107       XUngrabKeyboard (display, CurrentTime);
108       XUngrabPointer (display, CurrentTime);
109     }
110     XFreeColors (display, colmap,(unsigned long*) colors[0], numcolors, 1);
111     XFreeColors (display, colmap,(unsigned long*)  colors[1], numcolors, 1);
112     XFreeColors (display, colmap,(unsigned long*)  colors[2], numcolors, 1);
113     exit (0);
114   }
115   else
116   {
117     XDestroyWindow (display, textWin);
118     return;
119   }
120 }
121 
122 
123 void
MakeWindow(int o_argc,char ** o_argv)124 MakeWindow(int o_argc,char **o_argv)
125 {
126   XSizeHints size_hints;
127   int i;
128   char *basename;
129   if ((basename=strrchr(progname,'/'))!=NULL)
130     basename++;
131   else
132     basename=progname;
133 
134 /* top corner of the window */
135   size_hints.x = 0;
136   size_hints.y = 0;
137 
138   if(options.mode==test)
139   {
140     size_hints.width = 800;
141     size_hints.height = 400;
142   }
143   else if(options.mode==mandel)
144   {
145     size_hints.width = 600;
146     size_hints.height = 600;
147   }
148   else
149   {
150     size_hints.height = 400;
151     size_hints.width = 400;
152   }
153 
154   size_hints.flags = PPosition | PSize;
155 
156 /* if there's a geometry string, parse it */
157   if (options.geomstring!=NULL)
158   {
159     int result;
160     result = XParseGeometry(options.geomstring,&size_hints.x,
161 			    &size_hints.y,(unsigned int*)&size_hints.width,
162 			    (unsigned int *)&size_hints.height);
163     if (result & XNegative)
164       size_hints.x += DisplayWidth(display,screen)
165 	- size_hints.width - options.bwidth*2;
166     if (result & YNegative)
167       size_hints.y += DisplayHeight(display,screen)
168 	- size_hints.height - options.bwidth*2;
169     if (result & XValue || result & YValue)
170     {
171       size_hints.flags |= USPosition;
172       size_hints.flags &= ~PPosition;
173     }
174     if (result & WidthValue || result & HeightValue)
175     {
176       size_hints.flags |= USSize;
177       size_hints.flags &= ~PSize;
178     }
179   }
180   for(i=0;i<options.windows;i++)
181   {
182     window[i] = XCreateSimpleWindow(display,RootWindow(display,screen),
183 				    size_hints.x,size_hints.y,
184 				    size_hints.width,size_hints.height,
185 				    options.bwidth,options.bdcolor,
186 				    options.bgcolor);
187     XSetStandardProperties(display,window[i],"Xtacy",basename,
188 			   None,o_argv,o_argc,&size_hints);
189     XSelectInput(display,window[i],
190 		 StructureNotifyMask|VisibilityChangeMask|
191 		 ButtonPressMask|ButtonReleaseMask|ButtonMotionMask);
192     XRaiseWindow (display, window[i]);
193     XMapWindow(display,window[i]);
194     XFlush(display);
195 /*      fprintf(stderr, "Window= %lx\n",window[i]); */
196   }
197   return;
198 }
199 
200 void
MakePerfectWindow(int o_argc,char ** o_argv)201 MakePerfectWindow(int o_argc, char **o_argv)
202 {
203   XSizeHints size_hints;
204   unsigned long vmask=0;
205   XSetWindowAttributes xswat;
206   XVisualInfo *vis_info;
207   int number,i;
208   char *basename;
209   if ((basename=strrchr(progname,'/'))!=NULL)
210     basename++;
211   else
212     basename=progname;
213   size_hints.x = 0;
214   size_hints.y = 0;
215   if(options.mode==test)
216   {
217     size_hints.height = 400;
218     size_hints.width = 800;
219   }
220   else if(options.mode==mandel)
221   {
222     size_hints.width = 600;
223     size_hints.height = 600;
224   }
225   else
226   {
227     size_hints.height = 400;
228     size_hints.width = 400;
229   }
230 
231   size_hints.flags = PPosition | PSize;
232 
233   if (options.geomstring!=NULL)
234   {
235     int result;
236     result = XParseGeometry(options.geomstring,&size_hints.x,
237 			    &size_hints.y,(unsigned int*)&size_hints.width,
238 			    (unsigned int*)&size_hints.height);
239     if (result & XNegative)
240       size_hints.x += DisplayWidth(display,screen)
241 	- size_hints.width - options.bwidth*2;
242     if (result & YNegative)
243       size_hints.y += DisplayHeight(display,screen)
244 	- size_hints.height - options.bwidth*2;
245     if (result & XValue || result & YValue)
246     {
247       size_hints.flags |= USPosition;
248       size_hints.flags &= ~PPosition;
249     }
250     if (result & WidthValue || result & HeightValue)
251     {
252       size_hints.flags |= USSize;
253       size_hints.flags &= ~PSize;
254     }
255   }
256 
257   xswat.override_redirect = False;
258   xswat.do_not_propagate_mask = KeyPressMask | KeyReleaseMask ;
259   xswat.background_pixmap=None;
260 /*      |	ButtonPressMask | ButtonReleaseMask; */
261 /*      vmask = CWOverrideRedirect | CWDontPropagate; */
262   vmask =  CWBackPixmap;
263   vis_info=(XVisualInfo *)malloc(sizeof(XVisualInfo));
264   vis_info->colormap_size=512;
265 #if defined (__cplusplus) || defined(c_plusplus)
266   vis_info->c_class=PseudoColor;
267 #else
268   vis_info->class=PseudoColor;
269 #endif
270 
271   vis_info = XGetVisualInfo(display, VisualClassMask|VisualColormapSizeMask,
272 			    vis_info,&number);
273   if(number!=0)
274   {
275     vis=vis_info->visual;
276   }
277   fprintf(stderr,"Vis->map_entries= %d\n",vis->map_entries);
278   options.tryfor=vis->map_entries;
279 
280   for(i=0;i<options.windows;i++)
281   {
282     window[i] = XCreateWindow(display, RootWindow(display, screen), 0, 0,
283 			      size_hints.width, size_hints.height,
284 			      options.bwidth, CopyFromParent, InputOutput,
285 			      vis , vmask, &xswat);
286     XSetStandardProperties(display,window[i],"Xtacy",basename,
287 			   None,o_argv,o_argc,&size_hints);
288     XSelectInput(display,window[i],
289 		 StructureNotifyMask|VisibilityChangeMask|
290 		 ButtonPressMask|ButtonMotionMask);
291     XMapWindow(display,window[i]);
292     XRaiseWindow(display,window[i]);
293   }
294 
295   free(vis_info);
296   return;
297 }
298 
299 /* for virtual root windows, split 'em up into sub-windows */
300 void
makeSubRootWins(int o_argc,char ** o_argv)301 makeSubRootWins(int o_argc, char** o_argv)
302 {
303   Window wdontcare;
304   int dontcare;
305   unsigned int udontcare;
306   char *basename;
307   unsigned long   vmask;
308   XSetWindowAttributes    xswat;
309   XSizeHints size_hints;
310   int foo,bar,i,x,y;
311   unsigned int sCY,sCX;
312 
313   window=(Window *)malloc(1*sizeof(Window));
314   window[0]=RootWindow(display,screen);
315   XGetGeometry(display,window[0],&wdontcare,
316 	       &dontcare,&dontcare, &sCX, &sCY, &udontcare, &udontcare);
317   foo=DisplayWidth(display,screen);
318   bar=DisplayHeight(display,screen);
319 
320 /*
321   fprintf(stderr,"SuperRoot CX=%d\t SuperRoot CY=%d\n",sCX,sCY);
322   fprintf(stderr,"Max visible (%dx%d)... so we can make %d windows\n",
323   foo=DisplayWidth(display,screen),
324   bar=DisplayHeight(display,screen),
325   (sCX/foo)*(sCY/bar));
326   */
327   if(options.mode == rot_shape || options.mode == cube ||
328      options.mode == tet       || options.mode == oct)
329   {
330     nwindows=1;
331     foo=sCX;
332     bar=sCY;
333   }
334   else
335   {
336     nwindows=((sCX/foo)*(sCY/bar));
337   }
338 
339   /*      printf("SuperRootWin:%lx\n",window); */
340 
341   free(window);			/* in every box of Corn Flakes */
342   window=(Window *)malloc(sizeof(Window)*nwindows);
343   CX=(unsigned int *)calloc(nwindows,sizeof(unsigned int));
344   CY=(unsigned int *)calloc(nwindows,sizeof(unsigned int));
345   options.windows=nwindows;
346   i=0;
347   for(x=0;x<(sCX/foo);x++)
348     for(y=0;y<(sCY/bar);y++)
349     {
350       if ((basename=strrchr(progname,'/'))!=NULL)
351 	basename++;
352       else
353 	basename=progname;
354       size_hints.flags = PPosition | PSize;
355       size_hints.x=DisplayWidth(display,screen);
356       size_hints.y=DisplayHeight(display,screen);
357 
358       xswat.override_redirect = True;
359       vmask = CWOverrideRedirect;
360 /*
361   fprintf(stderr,"Making a new window at %dx%d. (%d,%d)\t",x*foo,
362   y*bar, x*foo+foo, y*bar+bar);
363   */
364       window[i] = XCreateWindow(display, RootWindow(display, screen),
365 				x*foo, y*bar, foo, bar, 0,
366 				CopyFromParent, CopyFromParent, vis,
367 				vmask, &xswat);
368       /*
369 	fprintf(stderr,"Made #%d\n",i);
370 	*/
371       XSetStandardProperties(display,window[i],"Xtacy",basename,
372 			     None,o_argv,o_argc,&size_hints);
373       XSelectInput(display,window[i],0);
374       XLowerWindow(display,window[i]); /* shove the new window
375 					  down to the bottom */
376 
377       /*      window=RootWindow(display,screen);  */
378       XSync(display,0);
379       XMapWindow(display,window[i]);
380       XGetGeometry(display,window[i],&wdontcare, &dontcare,&dontcare,
381 		   &CX[i], &CY[i], &udontcare, &udontcare);
382       /*
383 	fprintf(stderr,"Root CX=%d\t Root CY=%d\n",CX[i],CY[i]);
384 	printf("RootWin:%lx\n",window[i]);
385 	*/
386       i++;
387     }
388 }
389 
390 void
makeLockWin(int o_argc,char ** o_argv)391 makeLockWin(int o_argc,char** o_argv)
392 {
393   unsigned int sCX=0,sCY=0,udontcare;
394   int bCX=0,bCY=0,dontcare;
395   Window wdontcare;
396   char *basename;
397   XSetWindowAttributes    xswat;
398   int vmask = CWOverrideRedirect|CWEventMask;
399   XSizeHints size_hints;
400 
401   size_hints.flags = PPosition | PSize;
402   size_hints.x=DisplayWidth(display,screen);
403   size_hints.y=DisplayHeight(display,screen);
404   xswat.override_redirect = True;
405   xswat.event_mask = KeyPressMask | ButtonPressMask;
406   if ((basename=strrchr(progname,'/'))!=NULL)
407     basename++;
408   else
409     basename=progname;
410   window=(Window *)malloc(sizeof(Window)*1);
411   XParseGeometry(options.geomstring,&bCX, &bCY,&sCX, &sCY);
412   window[0] = XCreateWindow(display, RootWindow(display, screen),
413 			    bCX, bCY, sCX , sCY, 0,
414 			    CopyFromParent, CopyFromParent, vis,
415 			    vmask, &xswat);
416   XSetStandardProperties(display,window[0],"Xtacy",basename,
417 			 None,o_argv,o_argc,&size_hints);
418   XSelectInput(display,window[0],
419 	       ButtonPressMask|KeyPressMask| VisibilityChangeMask);
420   XSync(display,0);
421   XMapWindow(display,window[0]);
422   XFlush(display);
423   XRaiseWindow(display,window[0]); /* shove the new window up to the top */
424 
425   CX=(unsigned int *)calloc(1,sizeof(unsigned int));
426   CY=(unsigned int *)calloc(1,sizeof(unsigned int));
427   XGetGeometry(display,window[0],&wdontcare, &dontcare,&dontcare,
428 	       &CX[0], &CY[0], &udontcare, &udontcare);
429 }
430 
431 void
refreshrootquit(int foo)432 refreshrootquit(int foo)
433 {
434 /* no clear. leave the current pattern on the background */
435   if(!options.noclear)
436   {
437     int i;
438 /*      fprintf(stderr,"Refreshing root and Quiting\n"); */
439     s_win_att.backing_store=WhenMapped;
440     for(i=0;i<options.windows;i++)
441       XChangeWindowAttributes(display,window[i],CWBackingStore,&s_win_att);
442 
443     XClearWindow(display,RootWindow(display,screen));
444     XFreeColors(display, colmap,(unsigned long*)  colors[0],numcolors,1);
445     XFreeColors(display, colmap,(unsigned long*)  colors[1],numcolors,1);
446     XFreeColors(display, colmap,(unsigned long*)  colors[2],numcolors,1);
447     XFlush(display);
448   }
449   exit(0);
450 }
451 
452 void
handle_event(XEvent * event)453 handle_event(XEvent *event)
454 {
455   int i;
456   static int pressed=0;
457   static long button_pushed = 0;
458 
459   do
460   {
461     if(event->type<2)
462       printf("Funky Event Type: %d\n",event->type);
463     else if (event->type==ConfigureNotify)
464     {
465       if (!startup)
466       {
467 	for(i=0;i<options.windows;i++)
468 	{
469 	  if (event->xconfigure.window==window[i])
470 	  {
471 	    if (CX[i] != event->xconfigure.width ||
472 		CY[i] != event->xconfigure.height )
473 	    {
474 	      XClearWindow(display,event->xconfigure.window);
475 	      CX[i] = event->xconfigure.width;
476 	      CY[i] = event->xconfigure.height;
477 /* 	    if ((options.mode==kaleid)&&(!options.doroot)) */
478 /* 	    { */
479 /* 	      CX[i]>>=1; */
480 /* 	      CY[i]>>=1; */
481 
482 /* 	    } */
483 	      M[i] = max(CY[i],CX[i]);
484 	      M[i] = M[i] ? M[i] : 1;
485 	      jj[i]=0;
486 	      if(options.mode==kaleid)
487 		randomize_kal(i);
488 	      /*
489 		fprintf(stderr,"CX[i]=%d CY[i]=%d M[i]=%d\n",CX[i],CY[i],M[i]);
490 	      */
491 
492 	    }
493 /*		  else
494 		  jj[i]=1;
495 */
496 	  }
497 	}
498       }
499     }
500     else if (event->type==MapNotify)
501     {
502       if(options.mode==kaleid)
503 	for(i=0;i<options.windows;i++)
504 	{
505 	  if (event->xmap.window==window[i])
506 	  {
507 	    randomize_kal(i);
508 
509 	    HC[i] = rndm((long)numcolors);
510 	  }
511 	}
512     }
513     else if (event->type==VisibilityNotify)
514     {
515       for(i=0;i<options.windows;i++)
516       {
517 	if (event->xvisibility.window==window[i])
518 	{
519 	  if (visible[i] &&
520 	      event->xvisibility.state == VisibilityFullyObscured)
521 	  {
522 	    visible[i]=0;
523 	    nvisible--;
524 	  }
525 	  else if (!visible[i] &&
526 		   event->xvisibility.state != VisibilityFullyObscured)
527 	  {
528 	    visible[i]=1;
529 	    nvisible++;
530 	  }
531 	  if ((options.lock) && (!options.debug)) {
532 	    XRaiseWindow (display, window[0]);	/* shove the window up to the top */
533 	  }
534 	}
535       }
536     }
537     else if (event->type==ButtonRelease)
538     {
539       if((button_pushed & event->xbutton.button) == event->xbutton.button)
540       {
541 	button_pushed ^= event->xbutton.button;
542 	if (event->xbutton.button==Button1)
543 	{
544 /*
545  * Zoom in on a section of the Mandelbrot set.. only goes 1 layer of zoom in
546  * ok, so I'm lazy and didn't bother figure how to store the new coords
547  * deal
548  */
549 	  if(options.mode==mandel)
550 	  {
551 	    r=event->xbutton.x;
552 	    b=event->xbutton.y;
553 	    printf("Button 1 Released at (%d,%d)\n",r,b);
554 	    pressed=0;
555 	    jj[0]=0;
556 	    dropachicken=1;
557 	  }
558 	}
559 	else if (event->xbutton.button==Button2)
560 	{
561 	  int i,found=0;
562 	  for(i=0;i<options.windows;i++)
563 	  {
564 	    if(event->xbutton.window==window[i])
565 	    {
566 	      found=1; break;
567 	    }
568 	  }
569 	  if(found)
570 	    jj[i]=0;
571 	  /* reset screen*/
572 	  XClearWindow(display,event->xbutton.window);
573 	  dropachicken=1;
574 	}
575       }
576       else
577       {
578 
579       }
580       /* printf("button pushed = %lx\n",button_pushed); */
581     }
582     else if (event->type==ButtonPress)
583     {
584       if((button_pushed & event->xbutton.button) == event->xbutton.button)
585       {
586 
587       }
588       else
589       {
590 	button_pushed ^= event->xbutton.button; /* flip it on */
591 
592 	if (event->xbutton.button==Button1)
593 	{
594 /*
595  * Zoom in on a section of the Mandelbrot set.. only goes 1 layer of zoom in
596  * ok, so I'm lazy and didn't bother figure how to store the new coords
597  * deal
598  */
599 	  if(options.mode==mandel)
600 	  {
601 	    l=event->xbutton.x;
602 	    t=event->xbutton.y;
603 	    printf("Button 1 Pressed at (%d,%d) \n",l,t);
604 	  }
605 /* drop a new particle in the chamber */
606 	  else if(options.mode==gravity)
607 	  {
608 	    int i,found=0,winno=0;
609 	    for(i=0;i<options.windows;i++)
610 	    {
611 	      if(event->xbutton.window==window[i])
612 	      {
613 		found=1; winno=i; break;
614 	      }
615 	    }
616 	    if(found)
617 	    {
618 	      set_part(winno,event->xbutton.x,event->xbutton.y,
619 		       &partlst[winno][rndm(options.numparts)]);
620 	    }
621 	  }
622 	  else if(options.mode==wandering)
623 	  {
624 	    int i,found=0,winno=0;
625 	    for(i=0;i<options.windows;i++)
626 	    {
627 	      if(event->xbutton.window==window[i])
628 	      {
629 		found=1; winno=i; break;
630 	      }
631 	    }
632 	    if(found)
633 	    {
634 	      x=event->xbutton.x;
635 	      y=event->xbutton.y;
636 	    }
637 	  }
638 	  else if(options.mode==blob)
639 	  {
640 	    int i,found=0,winno=0;
641 	    for(i=0;i<options.windows;i++)
642 	    {
643 	      if(event->xbutton.window==window[i])
644 	      {
645 		found=1; winno=i; break;
646 	      }
647 	    }
648 	    if(found)
649 	    {
650 	      blobAddFood(winno,event->xbutton.x,event->xbutton.y);
651 	    }
652 	  }
653 	  else if(options.mode==swarm)
654 	  {
655 	    int i,found=0,winno=0;
656 	    for(i=0;i<options.windows;i++)
657 	    {
658 	      if(event->xbutton.window==window[i])
659 	      {
660 		found=1; winno=i; break;
661 	      }
662 	    }
663 	    if(found)
664 	    {
665 	      moveQueen(winno,event->xbutton.x,event->xbutton.y);
666 	    }
667 	  }
668 	  else if(options.mode==tag)
669 	  {
670 	    int i,found=0,winno=0;
671 	    for(i=0;i<options.windows;i++)
672 	    {
673 	      if(event->xbutton.window==window[i])
674 	      {
675 		found=1; winno=i; break;
676 	      }
677 	    }
678 	    if(found)
679 	    {
680 	      moveIt(winno,event->xbutton.x,event->xbutton.y);
681 	    }
682 	  }
683 	  else if(options.mode==life)
684 	  {
685 	    int i,found=0,winno=0;
686 	    for(i=0;i<options.windows;i++)
687 	    {
688 	      if(event->xbutton.window==window[i])
689 	      {
690 		found=1; winno=i; break;
691 	      }
692 	    }
693 	    if(found)
694 	    {
695 	      dropACell(winno,event->xbutton.x,event->xbutton.y);
696 	    }
697 	  }
698 	  else if(!options.mono)
699 	  {
700 	    if(options.dynamic_colors)
701 	      randomize_colors();
702 	    else
703 	      rotate_colors();
704 	  }
705 	}
706 	else if (event->xbutton.button==Button3)
707 	{
708 	  int i,found=0;
709 	  /*
710 	    if(options.mode==tunnel)
711 	    {
712 	    EndofTunnel();  is there a light?
713 	    }
714 	  */
715 	  if(options.lock)
716 	  {
717 	    maybe_unlock(event);
718 	  }
719 	  else
720 	  {
721 	    /* do the zoomy close window thing */
722 	    for(i=0;i<options.windows;i++)
723 	    {
724 	      if(event->xbutton.window==window[i])
725 	      {
726 		found=1; break;
727 	      }
728 	    }
729 	    if(found)
730 	    {
731 	      /* if(nvisible == 1 )
732 		 fade_to_black();
733 	      */
734 	      if(options.annoy_tefler)
735 	      {
736 		int x,y,dx,dy;
737 		unsigned int udontcare;
738 		Window wdontcare;
739 
740 		XGetGeometry(display,window[i],&wdontcare,
741 			     &dx,&dy,(unsigned int*) &x,(unsigned int*)&y,
742 			     &udontcare, &udontcare);
743 
744 		while(x>0&&y>0)
745 		{
746 		  XMoveResizeWindow(display,window[i],dx+=2,dy+=2,x,y);
747 		  x=x-4;
748 		  y=y-4;
749 		  XFlush(display);
750 		}
751 	      }
752 
753 	      nwindows--;
754 	      /* options.windows--; */
755 	      visible[i]=0;
756 	      nvisible--;
757 	      /* fprintf(stderr,"Killing Window %d: %lx\n",i,window[i]); */
758 	      XUnmapWindow(display,window[i]);
759 	      jj[i]=1; /* don't redraw it */
760 
761 	      XSync(display,False);
762 	      if(nwindows==0)
763 	      {
764 		XFreeColors(display, colmap,(unsigned long*) colors[0],
765 			    numcolors, 1);
766 		XFreeColors(display, colmap,(unsigned long*) colors[1],
767 			    numcolors, 1);
768 		XFreeColors(display, colmap,(unsigned long*) colors[2],
769 			    numcolors, 1);
770 		exit(0);
771 	      }
772 	    }
773 	  }
774 	}
775       }
776 /*      printf("button pushed = %lx\n",button_pushed); */
777     }
778 
779     else if (event->type == KeyPress)
780     {
781       if (options.lock)
782       {
783 	XPutBackEvent(display, event);
784 	maybe_unlock (event);
785       }
786     }
787   } while (XCheckMaskEvent(display, ~0L,event)==True);
788 /*  *event=(XEvent*)0; */
789 }
790 
791 void
setup_windows()792 setup_windows()
793 {
794   int i;
795 
796   XGetWindowAttributes(display,window[0],&win_att);
797 
798   options.bdcolor = StrColor(options.border,WhitePixel(display,screen));
799   options.bgcolor = StrColor(options.background,
800 			     BlackPixel(display,screen));
801 
802   for(i=0;i<options.windows;i++)
803   {
804     if(options.perfect)
805     {
806       colmap = XCreateColormap(display,window[i],vis,AllocNone);
807       s_win_att.colormap=colmap;
808       XChangeWindowAttributes(display,window[i],CWColormap,&s_win_att);
809     }
810     else
811       colmap= win_att.colormap;
812 
813     XSetWindowBackground(display,window[i],options.bgcolor);
814     XSetWindowBorder(display,window[i],options.bdcolor);
815     XClearWindow(display,window[i]);
816 
817     if (options.totalrand || (options.mode==clover|| options.mode==wandering ||
818 			      options.mode==plasma|| options.mode==spiral    ||
819 			      options.mode==mandel|| options.mode==julia     ||
820 			      options.mode==tunnel|| options.mode==gravity   ||
821 			      options.mode==newton|| options.mode==test      ||
822 			      options.mode==dogplasma || options.mode==funky ||
823 			      options.mode==fields|| options.mode==xstatic  ||options.mode==mixer ||
824 			      options.mode==waves || options.mode==radial   ||options.mode==ripple ||
825 			      options.mode==cells || options.mode==taffy    ||options.mode==off   ||
826 			      options.mode==dline ||options.mode==dcurve    ||options.mode==sunrise||
827 			      options.mode==blur  || options.mode==flush))
828     {
829       s_win_att.backing_store=Always;
830       XChangeWindowAttributes(display,window[i],CWBackingStore,&s_win_att);
831     }
832 
833     if(options.lock)
834     {
835       s_win_att.override_redirect=True;
836       XChangeWindowAttributes(display,window[i],CWOverrideRedirect,
837 			      &s_win_att);
838     }
839 
840     intervals[i].tv_sec = (int)(options.delayvalue/1000);
841     intervals[i].tv_usec =(int)(options.delayvalue * 1000)%1000000;
842     visible[i]=1;
843     nvisible++;
844   }
845 }
846