home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume2 / kaleid2 / part01 / kaleid.c < prev    next >
C/C++ Source or Header  |  1988-12-22  |  21KB  |  677 lines

  1. #include <stdio.h>
  2. #include <X11/X.h>
  3. #include <X11/Xlib.h>
  4. #include <X11/Xutil.h>
  5. #include <X11/Xos.h>
  6. #include <signal.h>
  7. #include "kalicon.h"
  8.  
  9. /*
  10.   KALEIDOSCOPE (X11 Version)
  11.  
  12.   Original EGA/VGA version (for IBM PCs and compatibles) by:
  13.     Judson D. McClendon
  14.     Sun Valley Systems
  15.     329 37th Court N.E.
  16.     Birmingham, AL 35215
  17.     Compuserve: [74415,1003]
  18.  
  19.   Ported to X11 by Nathan Meyers, nathanm@hp-pcd.hp.com.
  20. */
  21.  
  22. char *progname;
  23.  
  24.  
  25. /* Approximation of CGA/EGA/VGA colors -- (out of standard order) */
  26. unsigned long colors[][3] = { { 0x0000, 0x0000, 0x0000 },    /* black */
  27.                   { 0xffff, 0xffff, 0xffff },    /* bright white */
  28.                   { 0x0000, 0x0000, 0xaaaa },    /* blue */
  29.                   { 0x0000, 0xaaaa, 0x0000 },    /* green */
  30.                   { 0x0000, 0xaaaa, 0xaaaa },    /* cyan */
  31.                   { 0xaaaa, 0x0000, 0x0000 },    /* red */
  32.                   { 0xaaaa, 0x0000, 0xaaaa },    /* magenta */
  33.                   { 0xaaaa, 0x5555, 0x0000 },    /* brown */
  34.                   { 0xaaaa, 0xaaaa, 0xaaaa },    /* white  */
  35.                   { 0x5555, 0x5555, 0x5555 },    /* dark grey */
  36.                   { 0x5555, 0x5555, 0xffff },    /* light blue */
  37.                   { 0x5555, 0xffff, 0x5555 },    /* light green */
  38.                   { 0x5555, 0xffff, 0xffff },    /* light cyan */
  39.                   { 0xffff, 0x5555, 0x5555 },    /* light red */
  40.                   { 0xffff, 0x5555, 0xffff },    /* light magenta */
  41.                   { 0xffff, 0xffff, 0x5555 } };  /* yellow */
  42.  
  43. #define NCOLORS 16
  44.  
  45. static char *what = "@(#)kaleid.c $Revision: 1.60 $";
  46.  
  47. Display *display;
  48. int screen;
  49.  
  50. void refreshrootquit()
  51. {
  52.   XClearWindow(display,RootWindow(display,screen));
  53.   XSync(display,0);
  54.   exit(0);
  55. }
  56.  
  57. int nwindows=1, nvisible=0;
  58. int *visible;
  59. Window *window;
  60. int *CX, *CY, *M;
  61. int *X1, *Y1, *X2, *Y2, *XV1, *YV1, *XV2, *YV2, *HC;
  62. int *XA, *YA, *XB, *YB, *XC, *YC, *XD, *YD;
  63. struct timeval *schedule, *intervals;
  64. int numcolors;
  65. int dynamic_colors=0;
  66. unsigned long palette[NCOLORS];
  67. long rndm();
  68.  
  69. main(argc,argv)
  70. int argc;
  71. char *argv[];
  72. {
  73.   unsigned long bgcolor, bdcolor;
  74.   int bwidth = 2;
  75.   int i;
  76.   XSizeHints size_hints;
  77.   XIconSize icon_size_hints, *icon_size_list;
  78.   int numsizes, currsize;
  79.   XWMHints wm_hints;
  80.   char *displayname = NULL, *background = NULL, *border = NULL;
  81.   char *geomstring = NULL;
  82.   GC color_gcs[NCOLORS];
  83.   XColor screen_in_out, visual_def_return, exact_def_return;
  84.   int o_argc = argc;
  85.   char **o_argv = argv;
  86.   XEvent event;
  87.   long time();
  88.   int doroot = 0;
  89.   int delayvalue = -1, icondelay=100;
  90.   int iconic=0;
  91.   int monochrome=0;
  92.   char *basename, *strrchr();
  93.  
  94.   progname = argv[0];
  95.  
  96.   if ((basename=strrchr(progname,'/'))!=NULL) basename++;
  97.   else basename=progname;
  98.  
  99.   while (--argc>0) {
  100.     char *option = (*++argv);
  101.     if (!strcmp(option,"-display")) {
  102.       if (--argc==0) usage();
  103.       displayname = (*++argv);
  104.     }
  105.     else if (strchr(option,':')) {
  106.       displayname = option;
  107.     }
  108.     else if (!strcmp(option,"-bg")) {
  109.       if (--argc==0) usage();
  110.       background = (*++argv);
  111.     }
  112.     else if (!strcmp(option,"-bd")) {
  113.       if (--argc==0) usage();
  114.       border = (*++argv);
  115.     }
  116.     else if (!strcmp(option,"-bw")) {
  117.       if (--argc==0) usage();
  118.       bwidth = atoi(*++argv);
  119.       if (bwidth<0) bwidth = 0;
  120.     }
  121.     else if (!strcmp(option,"-delay")) {
  122.       if (--argc==0) usage();
  123.       delayvalue = atoi(*++argv);
  124.       if (delayvalue<0) delayvalue = 0;
  125.     }
  126.     else if (!strcmp(option,"-icondelay")) {
  127.       if (--argc==0) usage();
  128.       icondelay = atoi(*++argv);
  129.       if (icondelay<0) icondelay = 0;
  130.     }
  131.     else if (!strcmp(option,"-iconic")) {
  132.       iconic = 1;
  133.     }
  134.     else if (!strcmp(option,"-geometry")) {
  135.       if (--argc==0) usage();
  136.       geomstring = (*++argv);
  137.     }
  138.     else if (*option=='=') {
  139.       geomstring = option;
  140.     }
  141.     else if (!strcmp(option,"-mono")) {
  142.       monochrome=1;
  143.     }
  144.     else if (!strcmp(option,"-mult")) {
  145.       if (--argc==0) usage();
  146.       nwindows = atoi(*++argv);
  147.       if (nwindows<1) nwindows = 1;
  148.     }
  149.     else if (!strcmp(option,"-r")) {
  150.       doroot = 1;
  151.     }
  152.     else if (!strcmp(option,"-root")) {
  153.       doroot = 1;
  154.     }
  155.     else if (!strcmp(option,"-randomcolor")) {
  156.       dynamic_colors = 1;
  157.     }
  158.     else usage();
  159.   }
  160.  
  161.   if (delayvalue == -1) delayvalue = doroot ? 100 : 10;
  162.  
  163.   display = XOpenDisplay(displayname);
  164.   if (display==NULL) {
  165.     (void)fprintf(stderr,
  166.               (displayname==NULL) ?
  167.               "%s: Failed to open display.\n" :
  168.               "%s: Failed to open display %s.\n",
  169.               progname,displayname);
  170.     exit(1);
  171.   }
  172.   screen = DefaultScreen(display);
  173.  
  174.   if (background == NULL ||
  175.       XAllocNamedColor(display,
  176.                DefaultColormap(display,screen),
  177.                background,
  178.                &visual_def_return,
  179.                &exact_def_return)==False)
  180.     bgcolor = BlackPixel(display,screen);
  181.   else bgcolor = exact_def_return.pixel;
  182.  
  183.   if (border==NULL ||
  184.       XAllocNamedColor(display,
  185.                DefaultColormap(display,screen),
  186.                border,
  187.                &visual_def_return,
  188.                &exact_def_return)==False)
  189.    bdcolor = WhitePixel(display,screen);
  190.   else bdcolor = exact_def_return.pixel;
  191.  
  192.   if (!monochrome && DisplayCells(display,screen) > 2) {
  193.     if (dynamic_colors) {
  194.       for (numcolors=NCOLORS; numcolors>=2; numcolors--) {
  195.     if (XAllocColorCells(display,DefaultColormap(display,screen),
  196.                  0, (unsigned long *)NULL, 0,
  197.                  palette, (unsigned int)numcolors) == True) {
  198.       randomize_colors();
  199.       break;
  200.     }
  201.       }
  202.       if (numcolors < 2) fatalerror("Cannot allocate R/W color cells",NULL);
  203.     }
  204.     else {
  205.       for (numcolors=0; numcolors<NCOLORS; numcolors++) {
  206.         screen_in_out.flags = DoRed | DoGreen | DoBlue;
  207.         screen_in_out.red = colors[numcolors][0];
  208.         screen_in_out.green = colors[numcolors][1];
  209.         screen_in_out.blue = colors[numcolors][2];
  210.         if (XAllocColor(display, DefaultColormap(display,screen),
  211.                 &screen_in_out)==False) {
  212.       if (numcolors < 2) fatalerror("Cannot allocate colors",NULL);
  213.       break;
  214.         }
  215.         palette[numcolors] = screen_in_out.pixel;
  216.       }
  217.     }
  218.   }
  219.   else {
  220.     numcolors=2;
  221.     palette[0] = WhitePixel(display,screen);
  222.     palette[1] = BlackPixel(display,screen);
  223.   }
  224.  
  225.   size_hints.x = 0;
  226.   size_hints.y = 0;
  227.   size_hints.width = 300;
  228.   size_hints.height = 300;
  229.  
  230.   size_hints.flags = PPosition | PSize;
  231.   if (geomstring!=NULL) {
  232.     int result;
  233.     result = XParseGeometry(geomstring,&size_hints.x,&size_hints.y,
  234.                     &size_hints.width,&size_hints.height);
  235.     if (result & XNegative)
  236.       size_hints.x += DisplayWidth(display,screen)
  237.             - size_hints.width
  238.             - bwidth*2;
  239.     if (result & YNegative)
  240.       size_hints.y += DisplayHeight(display,screen)
  241.             - size_hints.height
  242.             - bwidth*2;
  243.     if (result & XValue || result & YValue) {
  244.       size_hints.flags |= USPosition;
  245.       size_hints.flags &= ~PPosition;
  246.     }
  247.     if (result & WidthValue || result & HeightValue) {
  248.       size_hints.flags |= USSize;
  249.       size_hints.flags &= ~PSize;
  250.     }
  251.   }
  252.  
  253.   if (doroot) {
  254.     char *calloc();
  255.     if (!allocate_arrays(1)) {
  256.       (void)fprintf(stderr,"%s: malloc() failure\n",progname);
  257.       exit(1);
  258.     }
  259.     intervals[0].tv_sec = delayvalue/1000;
  260.     intervals[0].tv_usec = (delayvalue % 1000) * 1000;
  261.     window[0] = RootWindow(display,screen);
  262.   }
  263.   else {
  264.     Pixmap bitmapicon;
  265.     char *calloc();
  266.  
  267.     if (!allocate_arrays((unsigned)(2*nwindows))) {
  268.       (void)fprintf(stderr,"%s: malloc() failure\n",progname);
  269.       exit(1);
  270.     }
  271.  
  272.     for (i=0; i<nwindows; i++)
  273.       window[i] = XCreateSimpleWindow(display,RootWindow(display,screen),
  274.                         size_hints.x,size_hints.y,
  275.                         size_hints.width,size_hints.height,
  276.                         bwidth,bdcolor,bgcolor);
  277.  
  278.     icon_size_hints.max_width=64;
  279.     icon_size_hints.max_height=64;
  280.     currsize=0;
  281.     if (XGetIconSizes(display,RootWindow(display,screen),
  282.               &icon_size_list,&numsizes)) {
  283.       for (i=1; i<numsizes; i++) {    /* Look for largest icon size */
  284.     if (icon_size_list[i].max_width >= icon_size_list[currsize].max_width &&
  285.         icon_size_list[i].max_height >= icon_size_list[currsize].max_height)
  286.       currsize=i;
  287.       }
  288.       if (icon_size_list[currsize].max_width <= 0 ||
  289.       icon_size_list[currsize].max_height <= 0 ) {
  290.     XFree(icon_size_list);
  291.         icon_size_list = &icon_size_hints;
  292.       }
  293.     }
  294.     else
  295.       icon_size_list = &icon_size_hints;
  296.  
  297.     for (i=0; i<nwindows; i++) {
  298.       window[i+nwindows] = XCreateSimpleWindow(display,
  299.                       RootWindow(display,screen), 0,0,
  300.                           icon_size_list[currsize].max_width,
  301.                           icon_size_list[currsize].max_height,
  302.                           2,BlackPixel(display,screen),
  303.                           WhitePixel(display,screen));
  304.  
  305.       CX[i+nwindows] = icon_size_list[currsize].max_width >> 1;
  306.       CY[i+nwindows] = icon_size_list[currsize].max_height >> 1;
  307.       M[i+nwindows] = (CX[i+nwindows]>CY[i+nwindows]) ?
  308.              CX[i+nwindows] :
  309.              CY[i+nwindows];
  310.       M[i+nwindows] = M[i+nwindows] ? M[i+nwindows] : 1;
  311.     }
  312.  
  313.     if (icon_size_list != &icon_size_hints) XFree(icon_size_list);
  314.  
  315.     for (i=0; i<nwindows; i++)
  316.       XSetStandardProperties(display,window[i],"Kaleidoscope",basename,
  317.                  None,o_argv,o_argc,&size_hints);
  318.  
  319.     /* Create bitmap icon for wm's that don't support window icons */
  320.     bitmapicon=XCreateBitmapFromData(display,RootWindow(display,screen),
  321.                      icon_bits, icon_width, icon_height);
  322.  
  323.     /* Use window icon for window managers that support one */
  324.     wm_hints.icon_pixmap = bitmapicon;
  325.     wm_hints.flags = IconPixmapHint | IconWindowHint;
  326.  
  327.     if (iconic) {
  328.       wm_hints.initial_state = IconicState;
  329.       wm_hints.flags |= StateHint;
  330.     }
  331.  
  332.     for (i=0; i<nwindows; i++) {
  333.       wm_hints.icon_window = window[i+nwindows];
  334.       XSetWMHints(display,window[i],&wm_hints);
  335.       XSelectInput(display,window[i],
  336.     StructureNotifyMask|VisibilityChangeMask);
  337.       XSelectInput(display,window[i+nwindows],
  338.     StructureNotifyMask|VisibilityChangeMask);
  339.       XMapWindow(display,window[i]);
  340.  
  341.       intervals[i].tv_sec = delayvalue/1000;
  342.       intervals[i].tv_usec = (delayvalue % 1000) * 1000;
  343.       intervals[i+nwindows].tv_sec = icondelay/1000;
  344.       intervals[i+nwindows].tv_usec = (icondelay % 1000) * 1000;
  345.  
  346.       CX[i] = size_hints.width/2;
  347.       CY[i] = size_hints.height/2;
  348.       M[i] = (CX[i]>CY[i]) ? CX[i] : CY[i];
  349.       M[i] = M[i] ? M[i] : 1;
  350.     }
  351.  
  352.   }
  353.  
  354.   for (i = 0; i<numcolors; i++) {
  355.     XGCValues values;
  356.     values.foreground = palette[i];
  357.     color_gcs[i] = XCreateGC(display,window[0],GCForeground,&values);
  358.   }
  359.  
  360.   nwindows <<= 1;
  361.   if (doroot) {
  362.     nwindows=1;
  363.     nvisible=1;
  364.     visible[0]=1;
  365.   }
  366.  
  367.   srand48(time((long *)NULL));
  368.  
  369.   for (;;) {
  370.     int winno;
  371.     for (winno=0; winno<nwindows; winno++) if (visible[winno]) break;
  372.     if (doroot) {
  373.       int dontcare;
  374.       Window wdontcare;
  375.       struct sigvec vec;
  376.       XGetGeometry(display,RootWindow(display,screen),&wdontcare,&dontcare,
  377.            &dontcare, &CX[0], &CY[0], &dontcare, &dontcare);
  378.       CX[0] >>= 1;
  379.       CY[0] >>= 1;
  380.       M[0] = (CX[0]>CY[0]) ? CX[0] : CY[0];
  381.       M[0] = M[0] ? M[0] : 1;
  382.       vec.sv_handler = refreshrootquit;
  383.       vec.sv_mask = 0x0;
  384.       vec.sv_flags = 0;
  385.       (void)sigvec(SIGINT, &vec, (struct sigvec *)NULL);
  386.       (void)sigvec(SIGQUIT, &vec, (struct sigvec *)NULL);
  387.       (void)sigvec(SIGTERM, &vec, (struct sigvec *)NULL);
  388.     }
  389.     while (nvisible) {
  390.       if (!rndm(50L)) {
  391.         X1[winno] = rndm((long)M[winno]) + 1;
  392.         X2[winno] = rndm((long)M[winno]) + 1;
  393.         Y1[winno] = rndm((long)X1[winno]);
  394.         Y2[winno] = rndm((long)X2[winno]);
  395.       }
  396.       if (!rndm(10L)) {
  397.         XV1[winno] = rndm(7L)-3;
  398.         XV2[winno] = rndm(7L)-3;
  399.         YV1[winno] = rndm(7L)-3;
  400.         YV2[winno] = rndm(7L)-3;
  401.         HC[winno] = rndm((long)numcolors);
  402.       }
  403.       if (CX[winno]<CY[winno]) {
  404.         XA[winno] = (long)X1[winno]*(long)CX[winno]/(long)CY[winno];
  405.         YA[winno] = (long)Y1[winno]*(long)CX[winno]/(long)CY[winno];
  406.         XB[winno] = X1[winno];
  407.         YB[winno] = Y1[winno];
  408.         XC[winno] = (long)X2[winno]*(long)CX[winno]/(long)CY[winno];
  409.         YC[winno] = (long)Y2[winno]*(long)CX[winno]/(long)CY[winno];
  410.         XD[winno] = X2[winno];
  411.         YD[winno] = Y2[winno];
  412.       }
  413.       else {
  414.         XA[winno] = X1[winno];
  415.         YA[winno] = Y1[winno];
  416.         XB[winno] = (long)X1[winno]*(long)CY[winno]/(long)CX[winno];
  417.         YB[winno] = (long)Y1[winno]*(long)CY[winno]/(long)CX[winno];
  418.         XC[winno] = X2[winno];
  419.         YC[winno] = Y2[winno];
  420.         XD[winno] = (long)X2[winno]*(long)CY[winno]/(long)CX[winno];
  421.         YD[winno] = (long)Y2[winno]*(long)CY[winno]/(long)CX[winno];
  422.       }
  423.       XDrawLine(display,window[winno],color_gcs[HC[winno]],
  424.                 CX[winno]+XA[winno],
  425.                 CY[winno]-YB[winno],
  426.                 CX[winno]+XC[winno],
  427.                 CY[winno]-YD[winno]);
  428.       XDrawLine(display,window[winno],color_gcs[HC[winno]],
  429.                 CX[winno]-YA[winno],
  430.                 CY[winno]+XB[winno],
  431.                 CX[winno]-YC[winno],
  432.                 CY[winno]+XD[winno]);
  433.       XDrawLine(display,window[winno],color_gcs[HC[winno]],
  434.                 CX[winno]-XA[winno],
  435.                 CY[winno]-YB[winno],
  436.                 CX[winno]-XC[winno],
  437.                 CY[winno]-YD[winno]);
  438.       XDrawLine(display,window[winno],color_gcs[HC[winno]],
  439.                 CX[winno]-YA[winno],
  440.                 CY[winno]-XB[winno],
  441.                 CX[winno]-YC[winno],
  442.                 CY[winno]-XD[winno]);
  443.       XDrawLine(display,window[winno],color_gcs[HC[winno]],
  444.                 CX[winno]-XA[winno],
  445.                 CY[winno]+YB[winno],
  446.                 CX[winno]-XC[winno],
  447.                 CY[winno]+YD[winno]);
  448.       XDrawLine(display,window[winno],color_gcs[HC[winno]],
  449.                 CX[winno]+YA[winno],
  450.                 CY[winno]-XB[winno],
  451.                 CX[winno]+YC[winno],
  452.                 CY[winno]-XD[winno]);
  453.       XDrawLine(display,window[winno],color_gcs[HC[winno]],
  454.                 CX[winno]+XA[winno],
  455.                 CY[winno]+YB[winno],
  456.                 CX[winno]+XC[winno],
  457.                 CY[winno]+YD[winno]);
  458.       XDrawLine(display,window[winno],color_gcs[HC[winno]],
  459.                 CX[winno]+YA[winno],
  460.                 CY[winno]+XB[winno],
  461.                 CX[winno]+YC[winno],
  462.                 CY[winno]+XD[winno]);
  463.       XFlush(display);
  464.       X1[winno]= (X1[winno] + XV1[winno]) % M[winno];
  465.       Y1[winno]= (Y1[winno] + YV1[winno]) % M[winno];
  466.       X2[winno]= (X2[winno] + XV2[winno]) % M[winno];
  467.       Y2[winno]= (Y2[winno] + YV2[winno]) % M[winno];
  468.       if (!rndm(500L)) XClearWindow(display,window[winno]);
  469.       if (dynamic_colors && !rndm((long)(800/numcolors))) randomize_color();
  470.       winno=scheduler();
  471.       if (XCheckMaskEvent(display,~0L,&event)==True) handle_event(&event);
  472.     }
  473.     XNextEvent(display,&event);
  474.     handle_event(&event);
  475.   }
  476. }
  477.  
  478. randomize_color()
  479. {
  480.   int i;
  481.   XColor color;
  482.   color.pixel = palette[rndm((long)numcolors)];
  483.   color.red = rndm(65535L);
  484.   color.green = rndm(65535L);
  485.   color.blue = rndm(65535L);
  486.   color.flags = DoRed|DoGreen|DoBlue;
  487.   XStoreColor(display, DefaultColormap(display,screen), &color);
  488. }
  489.  
  490. randomize_colors()
  491. {
  492.   int i;
  493.   XColor color[NCOLORS];
  494.   for (i=0; i<numcolors; i++) {
  495.     color[i].pixel = palette[i];
  496.     color[i].red = rndm(65535L);
  497.     color[i].green = rndm(65535L);
  498.     color[i].blue = rndm(65535L);
  499.     color[i].flags = DoRed|DoGreen|DoBlue;
  500.   }
  501.   XStoreColors(display, DefaultColormap(display,screen), color, numcolors);
  502. }
  503.  
  504. handle_event(event)
  505. XEvent *event;
  506. {
  507.   int i;
  508.   if (event->type==ConfigureNotify) {
  509.     for (i=0; i<nwindows; i++) {
  510.       if (event->xconfigure.window==window[i]) {
  511.         if (CX[i] != event->xconfigure.width/2 ||
  512.             CY[i] != event->xconfigure.height/2)
  513.       XClearWindow(display,event->xconfigure.window);
  514.         CX[i] = event->xconfigure.width/2;
  515.         CY[i] = event->xconfigure.height/2;
  516.         M[i] = (CX[i]>CY[i]) ? CX[i] : CY[i];
  517.         M[i] = M[i] ? M[i] : 1;
  518.         break;
  519.       }
  520.     }
  521.   }
  522.   else if (event->type==MapNotify) {
  523.     for (i=0; i<nwindows; i++) {
  524.       if (event->xmap.window==window[i]) {
  525.         X1[i] = rndm((long)M[i]) + 1;
  526.         X2[i] = rndm((long)M[i]) + 1;
  527.         Y1[i] = rndm((long)X1[i]);
  528.         Y2[i] = rndm((long)X2[i]);
  529.         XV1[i] = rndm(7L)-3;
  530.         XV2[i] = rndm(7L)-3;
  531.         YV1[i] = rndm(7L)-3;
  532.         YV2[i] = rndm(7L)-3;
  533.         HC[i] = rndm((long)numcolors);
  534.         break;
  535.       }
  536.     }
  537.   }
  538.   else if (event->type==VisibilityNotify) {
  539.     for (i=0; i<nwindows; i++) {
  540.       if (event->xvisibility.window==window[i]) {
  541.     if (visible[i] &&
  542.         event->xvisibility.state == VisibilityFullyObscured) {
  543.           visible[i]=0;
  544.           nvisible--;
  545.     }
  546.     else if (!visible[i] &&
  547.          event->xvisibility.state != VisibilityFullyObscured) {
  548.           visible[i]=1;
  549.           nvisible++;
  550.     }
  551.         break;
  552.       }
  553.     }
  554.   }
  555. }
  556.  
  557. usage()
  558. {
  559.   int i;
  560.   (void)fprintf(stderr,"Usage: %s [-display <displayname>] [-bg <background>]",
  561.       progname);
  562.   (void)fprintf(stderr," [-bd <border>]\n");
  563.   for (i = 0; i<(strlen(progname)+8); i++) (void)putc(' ',stderr);
  564.   (void)fprintf(stderr,"[-bw <borderwidth>] [-geometry <geometry>]");
  565.   (void)fprintf(stderr," [-delay <msec>]\n");
  566.   for (i = 0; i<(strlen(progname)+8); i++) (void)putc(' ',stderr);
  567.   (void)fprintf(stderr,"[-icondelay <msec>] [-iconic] [-mono]");
  568.   (void)fprintf(stderr," [-mult <number>] -r\n");
  569.   for (i = 0; i<(strlen(progname)+8); i++) (void)putc(' ',stderr);
  570.   (void)fprintf(stderr,"[-randomcolor]\n");
  571.   exit(1);
  572. }
  573.  
  574. fatalerror(s1,s2)
  575. char *s1,*s2;
  576. {
  577.   (void)fprintf(stderr,"%s: ",progname);
  578.   (void)fprintf(stderr,s1,s2);
  579.   (void)putc('\n',stderr);
  580.   exit(1);
  581. }
  582.  
  583. long rndm(maxval)
  584. long maxval;
  585. {
  586.   long lrand48();
  587.   return ((lrand48() >> 15) * maxval) >> 16;
  588. }
  589.  
  590. allocate_arrays(nwin)
  591. unsigned nwin;
  592. {
  593.   char *calloc();
  594.   if ((window=(Window *)calloc(nwin,sizeof(Window))) == NULL) return 0;
  595.   if ((CX=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  596.   if ((CY=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  597.   if ((M=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  598.   if ((visible=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  599.   if ((X1=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  600.   if ((Y1=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  601.   if ((X2=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  602.   if ((Y2=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  603.   if ((XV1=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  604.   if ((YV1=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  605.   if ((XV2=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  606.   if ((YV2=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  607.   if ((HC=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  608.   if ((XA=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  609.   if ((YA=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  610.   if ((XB=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  611.   if ((YB=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  612.   if ((XC=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  613.   if ((YC=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  614.   if ((XD=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  615.   if ((YD=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
  616.   if ((schedule=(struct timeval *)calloc(nwin,sizeof(struct timeval))) == NULL)
  617.     return 0;
  618.   if ((intervals=(struct timeval *)calloc(nwin,sizeof(struct timeval))) == NULL)
  619.     return 0;
  620.   return 1;
  621. }
  622.  
  623. int scheduler()
  624. {
  625.   struct timeval currtime, *nextalarm, *alarmindex;
  626.   struct timezone tzp;
  627.   int i;
  628.  
  629.   /* Get current time */
  630.   (void)gettimeofday(&currtime, &tzp);
  631.  
  632.   /* Find earliest alarm due */
  633.   alarmindex = nextalarm = schedule;
  634.   for (i=1; i<nwindows; i++) {
  635.     if (visible[++alarmindex - schedule] &&
  636.     ( alarmindex->tv_sec < nextalarm->tv_sec ||
  637.           alarmindex->tv_sec == nextalarm->tv_sec &&
  638.           alarmindex->tv_usec < nextalarm->tv_usec ))
  639.       nextalarm = alarmindex;
  640.   }
  641.  
  642.   /* If the next alarm is not past due, sleep until it comes due */
  643.   if (currtime.tv_sec < nextalarm->tv_sec ||
  644.       currtime.tv_sec == nextalarm->tv_sec &&
  645.       currtime.tv_usec < nextalarm->tv_usec) {
  646.     struct timeval timeout;
  647.     int fd=ConnectionNumber(display), readfds;
  648.  
  649.     timeout.tv_sec = 0;
  650.     timeout.tv_usec = 0;
  651.     timeout.tv_sec = nextalarm->tv_sec - currtime.tv_sec;
  652.     timeout.tv_usec = nextalarm->tv_usec - currtime.tv_usec;
  653.     if (timeout.tv_usec < 0) {
  654.       timeout.tv_sec -= 1L;
  655.       timeout.tv_usec += 1000000L;
  656.     }
  657.  
  658.     readfds = 1<<fd;
  659.     (void)select(fd+1, &readfds, NULL, NULL, &timeout);
  660.  
  661.     /* Recompute current time */
  662.     (void)gettimeofday(&currtime, &tzp);
  663.  
  664.   }
  665.  
  666.   /* Set next alarm to current time + interval */
  667.   nextalarm->tv_sec = currtime.tv_sec + intervals[nextalarm-schedule].tv_sec;
  668.   nextalarm->tv_usec = currtime.tv_usec + intervals[nextalarm-schedule].tv_usec;
  669.   if (nextalarm->tv_usec >= 1000000) {
  670.     nextalarm->tv_sec += 1;
  671.     nextalarm->tv_usec -= 1000000;
  672.   }
  673.  
  674.   /* Return index of next alarm */
  675.   return nextalarm-schedule;
  676. }
  677.