|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 13128 (0x3348) Types: TextFile Names: »chaos.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/X/Chaos/chaos.c«
#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; }