DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T c

⟦4332e7a56⟧ TextFile

    Length: 13128 (0x3348)
    Types: TextFile
    Names: »chaos.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/X/Chaos/chaos.c« 

TextFile

#include <stdio.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/cursorfont.h>
#include "chaosicon.h"

/*

  The CHAOS Game

  As demonstrated on "Nova", 1/31/89

  By Nathan Meyers, nathanm@hp-pcd.hp.com.

*/

#define DOTSPERCALL 20

char *progname;

static char *what = "@(#)chaos.c $Revision: 1.17 $";

struct dattract {
  double x,y;
} dpoints[3] = { { 0.1, 0.153589838486 },
		 { 0.9, 0.153589838486 },
		 { 0.5, 0.846410161513 } };

struct dattract *fpoints = dpoints;
char *strchr();

main(argc,argv)
int argc;
char *argv[];
{
  Display *display;
  int screen;
  Window win;
  Pixmap bitmapicon, bitmap;
  GC bitmapgc1, bitmapgc2, wingc;
  XGCValues values;
  unsigned long fgcolor, bgcolor, bdcolor;
  int bwidth = 2;
  XSizeHints size_hints;
  XWMHints wm_hints;
  char *displayname = NULL;
  char *foreground = NULL, *background = NULL, *border = NULL;
  char *geomstring = NULL;
  XColor visual_def_return, exact_def_return;
  int o_argc = argc;
  char **o_argv = argv;
  int i;
  char *basename;
  int width, height;
  int mapped=0;
  long delayvalue = 10L;
  long udelayvalue = -1L;
  long rndm();
  double drand48(), x, y;
  char *bitmapfilename = "chaos.xbm";
  char *pointlist = NULL;
  int manpoints = 0;
  int npoints = 3;
  double mulcon = 0.5;
  long time(), atol();
  char *strrchr();

  progname = argv[0];

  if ((basename=strrchr(progname,'/'))!=NULL) basename++;
  else basename=progname;

  while (--argc>0) {
    char *option = (*++argv), *strchr();
    if (!strcmp(option,"-delay")) {
      if (--argc==0) usage();
      delayvalue = atol(*++argv);
      if (delayvalue < 0) delayvalue = 0;
    }
    else if (!strcmp(option,"-udelay")) {
      if (--argc==0) usage();
      udelayvalue = atol(*++argv);
      if (udelayvalue < 0) udelayvalue = 0;
    }
    else if (!strcmp(option,"-display")) {
      if (--argc==0) usage();
      displayname = (*++argv);
    }
    else if (strchr(option,':')) {
      displayname = option;
    }
    else if (!strcmp(option,"-fg")) {
      if (--argc==0) usage();
      foreground = (*++argv);
    }
    else if (!strcmp(option,"-bg")) {
      if (--argc==0) usage();
      background = (*++argv);
    }
    else if (!strcmp(option,"-bd")) {
      if (--argc==0) usage();
      border = (*++argv);
    }
    else if (!strcmp(option,"-bw")) {
      if (--argc==0) usage();
      bwidth = atoi(*++argv);
      if (bwidth<0) bwidth = 0;
    }
    else if (!strcmp(option,"-dist")) {
      double atof();
      if (--argc==0) usage();
      mulcon = atof(*++argv);
      if (mulcon < 0.0) mulcon = -mulcon;
    }
    else if (!strcmp(option,"-geometry")) {
      if (--argc==0) usage();
      geomstring = (*++argv);
    }
    else if (*option=='=') {
      geomstring = option;
    }
    else if (!strcmp(option,"-mpoints")) {
      manpoints = 1;
    }
    else if (!strcmp(option,"-out")) {
      if (--argc==0) usage();
      bitmapfilename = (*++argv);
    }
    else if (!strcmp(option,"-points")) {
      if (--argc==0) usage();
      pointlist = (*++argv);
    }
    else usage();
  }

  if (!manpoints && pointlist != NULL) {
    char *temp = pointlist;
    char *calloc();
    double strtod();
    int commacount = 0;
    while (*temp != '\0') commacount += (*(temp++) == ',') ? 1 : 0;
    if (!(commacount & 0x1)) usage();
    npoints = (commacount >> 1) + 1;
    fpoints = (struct dattract *)calloc(npoints, sizeof(struct dattract));
    if (fpoints == NULL) {
      fprintf(stderr,"%s: calloc() failed\n",progname);
      exit(1);
    }
    for (i=0; i<npoints; i++) {
      fpoints[i].x = strtod(pointlist, &temp);
      if (temp == pointlist) usage();
      pointlist = strchr(temp, ',') + 1;
      fpoints[i].y = strtod(pointlist, &temp);
      if (temp == pointlist) usage();
      pointlist = strchr(temp, ',') + 1;
    }
  }

  display = XOpenDisplay(displayname);
  if (display==NULL) {
    (void)fprintf(stderr,
	          (displayname==NULL) ?
	          "%s: Failed to open display.\n" :
	          "%s: Failed to open display %s.\n",
	          progname,displayname);
    exit(1);
  }
  screen = DefaultScreen(display);

  srand48(time((long *)NULL));
  x = drand48();
  y = drand48();

  if (background == NULL ||
      XAllocNamedColor(display,
		       DefaultColormap(display,screen),
		       background,
		       &visual_def_return,
		       &exact_def_return)==False)
    bgcolor = WhitePixel(display,screen);
  else bgcolor = exact_def_return.pixel;

  if (foreground==NULL ||
      XAllocNamedColor(display,
		       DefaultColormap(display,screen),
		       foreground,
		       &visual_def_return,
		       &exact_def_return)==False)
   fgcolor = BlackPixel(display,screen);
  else fgcolor = exact_def_return.pixel;

  if (border==NULL ||
      XAllocNamedColor(display,
		       DefaultColormap(display,screen),
		       border,
		       &visual_def_return,
		       &exact_def_return)==False)
   bdcolor = BlackPixel(display,screen);
  else bdcolor = exact_def_return.pixel;

  size_hints.x = 0;
  size_hints.y = 0;
  size_hints.width = 300;
  size_hints.height = 300;

  size_hints.flags = PPosition | PSize;
  if (geomstring!=NULL) {
    int result;
    result = XParseGeometry(geomstring,&size_hints.x,&size_hints.y,
		            &size_hints.width,&size_hints.height);
    if (result & XNegative)
      size_hints.x += DisplayWidth(display,screen)
		    - size_hints.width
		    - bwidth*2;
    if (result & YNegative)
      size_hints.y += DisplayHeight(display,screen)
		    - size_hints.height
		    - bwidth*2;
    if (result & XValue || result & YValue) {
      size_hints.flags |= USPosition;
      size_hints.flags &= ~PPosition;
    }
    if (result & WidthValue || result & HeightValue) {
      size_hints.flags |= USSize;
      size_hints.flags &= ~PSize;
    }
  }

  width = size_hints.width;
  height = size_hints.height;
  if (width < 1) width = 1;
  if (height < 1) height = 1;

  win = XCreateSimpleWindow(display,RootWindow(display,screen),
			       size_hints.x,size_hints.y,
			       size_hints.width,size_hints.height,
			       bwidth,bdcolor,bgcolor);

  values.foreground = fgcolor;
  values.background = bgcolor;
  wingc = XCreateGC(display, win, GCForeground|GCBackground, &values);

  bitmap = XCreatePixmap(display, win, width, height, 1);

  values.foreground = 0;
  bitmapgc1 = XCreateGC(display, bitmap, GCForeground, &values);
  XFillRectangle(display, bitmap, bitmapgc1, 0, 0, width, height);

  values.foreground = 1;
  bitmapgc2 = XCreateGC(display, bitmap, GCForeground, &values);

  XSetStandardProperties(display,win,"Chaos",basename,
			 None,o_argv,o_argc,&size_hints);

  bitmapicon=XCreateBitmapFromData(display,RootWindow(display,screen),
				   chaosicon_bits, chaosicon_width,
				   chaosicon_height);

  wm_hints.icon_pixmap = bitmapicon;
  wm_hints.flags = IconPixmapHint;
  XSetWMHints(display,win,&wm_hints);

  XSelectInput(display,win, StructureNotifyMask|ExposureMask|ButtonPressMask);
  XMapWindow(display,win);

  if (manpoints) {
    Cursor cursor = XCreateFontCursor(display, XC_cross);
    XDefineCursor(display, win, cursor);
    fpoints = NULL;
    npoints = 0;
    for (;;) {
      XEvent event;
      XNextEvent(display, &event);
      if (event.type == ButtonPress) {
        if (event.xbutton.button == Button3 && npoints) {
	  XUndefineCursor(display,win);
	  XClearWindow(display, win);
	  break;
        }
	else if (event.xbutton.button == Button1) {
	  char *calloc(), *realloc();
	  if (fpoints == NULL)
    	    fpoints = (struct dattract *)calloc(++npoints,
			sizeof(struct dattract));
	  else
    	    fpoints = (struct dattract *)realloc(fpoints,
			++npoints * sizeof(struct dattract));
	  if (fpoints == NULL) {
	    fprintf(stderr,"%s: Memory allocation failed\n",progname);
	    exit(1);
	  }
	  fpoints[npoints-1].x = (double)(event.xbutton.x)/(double)(width-1);
	  fpoints[npoints-1].y = (double)(event.xbutton.y)/(double)(height-1);
	}
      }
      else if (event.type == ConfigureNotify) {
        if (event.xconfigure.width != width ||
            event.xconfigure.height != height ) {

	  XClearWindow(display, win);

	  width = event.xconfigure.width;
	  height = event.xconfigure.height;
  	  if (width < 1) width = 1;
  	  if (height < 1) height = 1;

	  XFreePixmap(display, bitmap);
	  XFreeGC(display, bitmapgc1);
	  XFreeGC(display, bitmapgc2);

          bitmap = XCreatePixmap(display, win, width, height, 1);

          values.foreground = 0;
          bitmapgc1 = XCreateGC(display, bitmap, GCForeground, &values);
          XFillRectangle(display, bitmap, bitmapgc1, 0, 0, width, height);

          values.foreground = 1;
          bitmapgc2 = XCreateGC(display, bitmap, GCForeground, &values);
        }
      }
      else if (event.type == MapNotify) mapped=1;
      else if (event.type == UnmapNotify) mapped=0;

      XClearWindow(display, win);
      for (i=0; i<npoints; i++) {
	XDrawArc(display, win, wingc,
		 (int)(fpoints[i].x * (double)(width-1))-2,
		 (int)(fpoints[i].y * (double)(height-1))-2,
		 5, 5, 0, 360*64);
      }

    }
  }

  for (;;) {
    XEvent event;
    if (mapped || udelayvalue != -1)
      while (XCheckWindowEvent(display, win, ~0L, &event) == False) {
        int ix, iy;
        if (mapped && delayvalue || !mapped && udelayvalue) {
	  struct timeval delaystruct;
	  int fd = ConnectionNumber(display);
	  int readfds = 1<<fd;
	  long delay = mapped ? delayvalue : udelayvalue;
          getnextpoint(&x, &y, &ix, &iy, width, height, npoints, mulcon);
          XFillRectangle(display, win, wingc, ix, iy, 1, 1);
          XFillRectangle(display, bitmap, bitmapgc2, ix, iy, 1, 1);
	  if (mapped) XFlush(display);
	  delaystruct.tv_sec = delay/1000;
	  delaystruct.tv_usec = (delay%1000) * 1000;
	  (void)select(fd+1, &readfds, NULL, NULL, &delaystruct);
        }
        else {
	  XRectangle rects[DOTSPERCALL];
	  for (i=0; i<DOTSPERCALL; i++) {
            getnextpoint(&x, &y, &ix, &iy, width, height, npoints, mulcon);
	    rects[i].x = ix;
	    rects[i].y = iy;
	    rects[i].width = 1;
	    rects[i].height = 1;
	  }
	  XFillRectangles(display, win, wingc, rects, DOTSPERCALL);
	  XFillRectangles(display, bitmap, bitmapgc2, rects, DOTSPERCALL);
        }
    }
    else XNextEvent(display, &event);
    if (event.type == ConfigureNotify) {
      if (event.xconfigure.width != width ||
          event.xconfigure.height != height ) {

	XClearWindow(display, win);

	width = event.xconfigure.width;
	height = event.xconfigure.height;
  	if (width < 1) width = 1;
  	if (height < 1) height = 1;

	XFreePixmap(display, bitmap);
	XFreeGC(display, bitmapgc1);
	XFreeGC(display, bitmapgc2);

        bitmap = XCreatePixmap(display, win, width, height, 1);

        values.foreground = 0;
        bitmapgc1 = XCreateGC(display, bitmap, GCForeground, &values);
        XFillRectangle(display, bitmap, bitmapgc1, 0, 0, width, height);

        values.foreground = 1;
        bitmapgc2 = XCreateGC(display, bitmap, GCForeground, &values);
      }
    }
    else if (event.type == MapNotify) mapped=1;
    else if (event.type == UnmapNotify) mapped=0;
    else if (event.type == Expose) {
      XCopyPlane(display, bitmap, win, wingc,
		 event.xexpose.x, event.xexpose.y, 
		 event.xexpose.width, event.xexpose.height, 
		 event.xexpose.x, event.xexpose.y, 0x1);
    }
    else if (event.type == ButtonPress) {
      if (event.xbutton.button == Button3) {
	XBell(display, 100);
	XFlush(display);
	XWriteBitmapFile(display, bitmapfilename, bitmap,
			 width, height, -1, -1);
	XBell(display, 100);
	XFlush(display);
      }
      else if (event.xbutton.button == Button1) {
	XClearWindow(display, win);
        XFillRectangle(display, bitmap, bitmapgc1, 0, 0, width, height);
      }
    }
  }
}

getnextpoint(x, y, ix, iy, width, height, npoints, mulcon)
double *x, *y;
int *ix, *iy;
int width, height;
int npoints;
double mulcon;
{
  long rndm();
  int dest;
  dest = (int)rndm((long)npoints);
  *x = (fpoints[dest].x - *x) * mulcon + *x;
  *y = (fpoints[dest].y - *y) * mulcon + *y;
  *ix = (int)(*x * width + .5);
  *iy = (int)(*y * height + .5);
}

usage()
{
  int i,j,spaces,xloc;
  static char *options[] = {
    "[-bd <border>]",
    "[-bg <background>]",
    "[-bw <borderwidth>]",
    "[-delay <msec>]",
    "[-display <displayname>]",
    "[-dist <distance>]",
    "[-geometry <geometry>]",
    "[-mpoints]",
    "[-out <bitmapfile>]",
    "[-points <x1>,<y1>[,<x2>,<y2>[,<x3>,<y3>[,...]]]]",
    "[-udelay <msec>]"
  };
  (void)fprintf(stderr,"Usage: %s", progname);
  spaces=strlen(progname)+7;
  xloc=spaces;

  for (j=0; j<(sizeof(options)/sizeof(char *)); j++) {
    if (xloc+strlen(options[j]) > 78) {
      putc('\n',stderr);
      for (i = 0; i<spaces; i++) (void)putc(' ',stderr);
      xloc=spaces;
    }
    xloc += strlen(options[j])+1;
    fprintf(stderr," %s",options[j]);
  }
  putc('\n',stderr);

  exit(1);
}

long rndm(maxval)
long maxval;
{
  long lrand48();
  int sr1=15, sr2=16;
  long mv=maxval;
  while (mv > 0x8000L) {
    sr1++;
    sr2--;
    mv >>= 1;
  }
  return ((lrand48() >> sr1) * maxval) >> sr2;
}