|
|
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;
}