home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume2
/
kaleid2
/
part01
/
kaleid.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-12-22
|
21KB
|
677 lines
#include <stdio.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <signal.h>
#include "kalicon.h"
/*
KALEIDOSCOPE (X11 Version)
Original EGA/VGA version (for IBM PCs and compatibles) by:
Judson D. McClendon
Sun Valley Systems
329 37th Court N.E.
Birmingham, AL 35215
Compuserve: [74415,1003]
Ported to X11 by Nathan Meyers, nathanm@hp-pcd.hp.com.
*/
char *progname;
/* Approximation of CGA/EGA/VGA colors -- (out of standard order) */
unsigned long colors[][3] = { { 0x0000, 0x0000, 0x0000 }, /* black */
{ 0xffff, 0xffff, 0xffff }, /* bright white */
{ 0x0000, 0x0000, 0xaaaa }, /* blue */
{ 0x0000, 0xaaaa, 0x0000 }, /* green */
{ 0x0000, 0xaaaa, 0xaaaa }, /* cyan */
{ 0xaaaa, 0x0000, 0x0000 }, /* red */
{ 0xaaaa, 0x0000, 0xaaaa }, /* magenta */
{ 0xaaaa, 0x5555, 0x0000 }, /* brown */
{ 0xaaaa, 0xaaaa, 0xaaaa }, /* white */
{ 0x5555, 0x5555, 0x5555 }, /* dark grey */
{ 0x5555, 0x5555, 0xffff }, /* light blue */
{ 0x5555, 0xffff, 0x5555 }, /* light green */
{ 0x5555, 0xffff, 0xffff }, /* light cyan */
{ 0xffff, 0x5555, 0x5555 }, /* light red */
{ 0xffff, 0x5555, 0xffff }, /* light magenta */
{ 0xffff, 0xffff, 0x5555 } }; /* yellow */
#define NCOLORS 16
static char *what = "@(#)kaleid.c $Revision: 1.60 $";
Display *display;
int screen;
void refreshrootquit()
{
XClearWindow(display,RootWindow(display,screen));
XSync(display,0);
exit(0);
}
int nwindows=1, nvisible=0;
int *visible;
Window *window;
int *CX, *CY, *M;
int *X1, *Y1, *X2, *Y2, *XV1, *YV1, *XV2, *YV2, *HC;
int *XA, *YA, *XB, *YB, *XC, *YC, *XD, *YD;
struct timeval *schedule, *intervals;
int numcolors;
int dynamic_colors=0;
unsigned long palette[NCOLORS];
long rndm();
main(argc,argv)
int argc;
char *argv[];
{
unsigned long bgcolor, bdcolor;
int bwidth = 2;
int i;
XSizeHints size_hints;
XIconSize icon_size_hints, *icon_size_list;
int numsizes, currsize;
XWMHints wm_hints;
char *displayname = NULL, *background = NULL, *border = NULL;
char *geomstring = NULL;
GC color_gcs[NCOLORS];
XColor screen_in_out, visual_def_return, exact_def_return;
int o_argc = argc;
char **o_argv = argv;
XEvent event;
long time();
int doroot = 0;
int delayvalue = -1, icondelay=100;
int iconic=0;
int monochrome=0;
char *basename, *strrchr();
progname = argv[0];
if ((basename=strrchr(progname,'/'))!=NULL) basename++;
else basename=progname;
while (--argc>0) {
char *option = (*++argv);
if (!strcmp(option,"-display")) {
if (--argc==0) usage();
displayname = (*++argv);
}
else if (strchr(option,':')) {
displayname = option;
}
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,"-delay")) {
if (--argc==0) usage();
delayvalue = atoi(*++argv);
if (delayvalue<0) delayvalue = 0;
}
else if (!strcmp(option,"-icondelay")) {
if (--argc==0) usage();
icondelay = atoi(*++argv);
if (icondelay<0) icondelay = 0;
}
else if (!strcmp(option,"-iconic")) {
iconic = 1;
}
else if (!strcmp(option,"-geometry")) {
if (--argc==0) usage();
geomstring = (*++argv);
}
else if (*option=='=') {
geomstring = option;
}
else if (!strcmp(option,"-mono")) {
monochrome=1;
}
else if (!strcmp(option,"-mult")) {
if (--argc==0) usage();
nwindows = atoi(*++argv);
if (nwindows<1) nwindows = 1;
}
else if (!strcmp(option,"-r")) {
doroot = 1;
}
else if (!strcmp(option,"-root")) {
doroot = 1;
}
else if (!strcmp(option,"-randomcolor")) {
dynamic_colors = 1;
}
else usage();
}
if (delayvalue == -1) delayvalue = doroot ? 100 : 10;
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);
if (background == NULL ||
XAllocNamedColor(display,
DefaultColormap(display,screen),
background,
&visual_def_return,
&exact_def_return)==False)
bgcolor = BlackPixel(display,screen);
else bgcolor = exact_def_return.pixel;
if (border==NULL ||
XAllocNamedColor(display,
DefaultColormap(display,screen),
border,
&visual_def_return,
&exact_def_return)==False)
bdcolor = WhitePixel(display,screen);
else bdcolor = exact_def_return.pixel;
if (!monochrome && DisplayCells(display,screen) > 2) {
if (dynamic_colors) {
for (numcolors=NCOLORS; numcolors>=2; numcolors--) {
if (XAllocColorCells(display,DefaultColormap(display,screen),
0, (unsigned long *)NULL, 0,
palette, (unsigned int)numcolors) == True) {
randomize_colors();
break;
}
}
if (numcolors < 2) fatalerror("Cannot allocate R/W color cells",NULL);
}
else {
for (numcolors=0; numcolors<NCOLORS; numcolors++) {
screen_in_out.flags = DoRed | DoGreen | DoBlue;
screen_in_out.red = colors[numcolors][0];
screen_in_out.green = colors[numcolors][1];
screen_in_out.blue = colors[numcolors][2];
if (XAllocColor(display, DefaultColormap(display,screen),
&screen_in_out)==False) {
if (numcolors < 2) fatalerror("Cannot allocate colors",NULL);
break;
}
palette[numcolors] = screen_in_out.pixel;
}
}
}
else {
numcolors=2;
palette[0] = WhitePixel(display,screen);
palette[1] = BlackPixel(display,screen);
}
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;
}
}
if (doroot) {
char *calloc();
if (!allocate_arrays(1)) {
(void)fprintf(stderr,"%s: malloc() failure\n",progname);
exit(1);
}
intervals[0].tv_sec = delayvalue/1000;
intervals[0].tv_usec = (delayvalue % 1000) * 1000;
window[0] = RootWindow(display,screen);
}
else {
Pixmap bitmapicon;
char *calloc();
if (!allocate_arrays((unsigned)(2*nwindows))) {
(void)fprintf(stderr,"%s: malloc() failure\n",progname);
exit(1);
}
for (i=0; i<nwindows; i++)
window[i] = XCreateSimpleWindow(display,RootWindow(display,screen),
size_hints.x,size_hints.y,
size_hints.width,size_hints.height,
bwidth,bdcolor,bgcolor);
icon_size_hints.max_width=64;
icon_size_hints.max_height=64;
currsize=0;
if (XGetIconSizes(display,RootWindow(display,screen),
&icon_size_list,&numsizes)) {
for (i=1; i<numsizes; i++) { /* Look for largest icon size */
if (icon_size_list[i].max_width >= icon_size_list[currsize].max_width &&
icon_size_list[i].max_height >= icon_size_list[currsize].max_height)
currsize=i;
}
if (icon_size_list[currsize].max_width <= 0 ||
icon_size_list[currsize].max_height <= 0 ) {
XFree(icon_size_list);
icon_size_list = &icon_size_hints;
}
}
else
icon_size_list = &icon_size_hints;
for (i=0; i<nwindows; i++) {
window[i+nwindows] = XCreateSimpleWindow(display,
RootWindow(display,screen), 0,0,
icon_size_list[currsize].max_width,
icon_size_list[currsize].max_height,
2,BlackPixel(display,screen),
WhitePixel(display,screen));
CX[i+nwindows] = icon_size_list[currsize].max_width >> 1;
CY[i+nwindows] = icon_size_list[currsize].max_height >> 1;
M[i+nwindows] = (CX[i+nwindows]>CY[i+nwindows]) ?
CX[i+nwindows] :
CY[i+nwindows];
M[i+nwindows] = M[i+nwindows] ? M[i+nwindows] : 1;
}
if (icon_size_list != &icon_size_hints) XFree(icon_size_list);
for (i=0; i<nwindows; i++)
XSetStandardProperties(display,window[i],"Kaleidoscope",basename,
None,o_argv,o_argc,&size_hints);
/* Create bitmap icon for wm's that don't support window icons */
bitmapicon=XCreateBitmapFromData(display,RootWindow(display,screen),
icon_bits, icon_width, icon_height);
/* Use window icon for window managers that support one */
wm_hints.icon_pixmap = bitmapicon;
wm_hints.flags = IconPixmapHint | IconWindowHint;
if (iconic) {
wm_hints.initial_state = IconicState;
wm_hints.flags |= StateHint;
}
for (i=0; i<nwindows; i++) {
wm_hints.icon_window = window[i+nwindows];
XSetWMHints(display,window[i],&wm_hints);
XSelectInput(display,window[i],
StructureNotifyMask|VisibilityChangeMask);
XSelectInput(display,window[i+nwindows],
StructureNotifyMask|VisibilityChangeMask);
XMapWindow(display,window[i]);
intervals[i].tv_sec = delayvalue/1000;
intervals[i].tv_usec = (delayvalue % 1000) * 1000;
intervals[i+nwindows].tv_sec = icondelay/1000;
intervals[i+nwindows].tv_usec = (icondelay % 1000) * 1000;
CX[i] = size_hints.width/2;
CY[i] = size_hints.height/2;
M[i] = (CX[i]>CY[i]) ? CX[i] : CY[i];
M[i] = M[i] ? M[i] : 1;
}
}
for (i = 0; i<numcolors; i++) {
XGCValues values;
values.foreground = palette[i];
color_gcs[i] = XCreateGC(display,window[0],GCForeground,&values);
}
nwindows <<= 1;
if (doroot) {
nwindows=1;
nvisible=1;
visible[0]=1;
}
srand48(time((long *)NULL));
for (;;) {
int winno;
for (winno=0; winno<nwindows; winno++) if (visible[winno]) break;
if (doroot) {
int dontcare;
Window wdontcare;
struct sigvec vec;
XGetGeometry(display,RootWindow(display,screen),&wdontcare,&dontcare,
&dontcare, &CX[0], &CY[0], &dontcare, &dontcare);
CX[0] >>= 1;
CY[0] >>= 1;
M[0] = (CX[0]>CY[0]) ? CX[0] : CY[0];
M[0] = M[0] ? M[0] : 1;
vec.sv_handler = refreshrootquit;
vec.sv_mask = 0x0;
vec.sv_flags = 0;
(void)sigvec(SIGINT, &vec, (struct sigvec *)NULL);
(void)sigvec(SIGQUIT, &vec, (struct sigvec *)NULL);
(void)sigvec(SIGTERM, &vec, (struct sigvec *)NULL);
}
while (nvisible) {
if (!rndm(50L)) {
X1[winno] = rndm((long)M[winno]) + 1;
X2[winno] = rndm((long)M[winno]) + 1;
Y1[winno] = rndm((long)X1[winno]);
Y2[winno] = rndm((long)X2[winno]);
}
if (!rndm(10L)) {
XV1[winno] = rndm(7L)-3;
XV2[winno] = rndm(7L)-3;
YV1[winno] = rndm(7L)-3;
YV2[winno] = rndm(7L)-3;
HC[winno] = rndm((long)numcolors);
}
if (CX[winno]<CY[winno]) {
XA[winno] = (long)X1[winno]*(long)CX[winno]/(long)CY[winno];
YA[winno] = (long)Y1[winno]*(long)CX[winno]/(long)CY[winno];
XB[winno] = X1[winno];
YB[winno] = Y1[winno];
XC[winno] = (long)X2[winno]*(long)CX[winno]/(long)CY[winno];
YC[winno] = (long)Y2[winno]*(long)CX[winno]/(long)CY[winno];
XD[winno] = X2[winno];
YD[winno] = Y2[winno];
}
else {
XA[winno] = X1[winno];
YA[winno] = Y1[winno];
XB[winno] = (long)X1[winno]*(long)CY[winno]/(long)CX[winno];
YB[winno] = (long)Y1[winno]*(long)CY[winno]/(long)CX[winno];
XC[winno] = X2[winno];
YC[winno] = Y2[winno];
XD[winno] = (long)X2[winno]*(long)CY[winno]/(long)CX[winno];
YD[winno] = (long)Y2[winno]*(long)CY[winno]/(long)CX[winno];
}
XDrawLine(display,window[winno],color_gcs[HC[winno]],
CX[winno]+XA[winno],
CY[winno]-YB[winno],
CX[winno]+XC[winno],
CY[winno]-YD[winno]);
XDrawLine(display,window[winno],color_gcs[HC[winno]],
CX[winno]-YA[winno],
CY[winno]+XB[winno],
CX[winno]-YC[winno],
CY[winno]+XD[winno]);
XDrawLine(display,window[winno],color_gcs[HC[winno]],
CX[winno]-XA[winno],
CY[winno]-YB[winno],
CX[winno]-XC[winno],
CY[winno]-YD[winno]);
XDrawLine(display,window[winno],color_gcs[HC[winno]],
CX[winno]-YA[winno],
CY[winno]-XB[winno],
CX[winno]-YC[winno],
CY[winno]-XD[winno]);
XDrawLine(display,window[winno],color_gcs[HC[winno]],
CX[winno]-XA[winno],
CY[winno]+YB[winno],
CX[winno]-XC[winno],
CY[winno]+YD[winno]);
XDrawLine(display,window[winno],color_gcs[HC[winno]],
CX[winno]+YA[winno],
CY[winno]-XB[winno],
CX[winno]+YC[winno],
CY[winno]-XD[winno]);
XDrawLine(display,window[winno],color_gcs[HC[winno]],
CX[winno]+XA[winno],
CY[winno]+YB[winno],
CX[winno]+XC[winno],
CY[winno]+YD[winno]);
XDrawLine(display,window[winno],color_gcs[HC[winno]],
CX[winno]+YA[winno],
CY[winno]+XB[winno],
CX[winno]+YC[winno],
CY[winno]+XD[winno]);
XFlush(display);
X1[winno]= (X1[winno] + XV1[winno]) % M[winno];
Y1[winno]= (Y1[winno] + YV1[winno]) % M[winno];
X2[winno]= (X2[winno] + XV2[winno]) % M[winno];
Y2[winno]= (Y2[winno] + YV2[winno]) % M[winno];
if (!rndm(500L)) XClearWindow(display,window[winno]);
if (dynamic_colors && !rndm((long)(800/numcolors))) randomize_color();
winno=scheduler();
if (XCheckMaskEvent(display,~0L,&event)==True) handle_event(&event);
}
XNextEvent(display,&event);
handle_event(&event);
}
}
randomize_color()
{
int i;
XColor color;
color.pixel = palette[rndm((long)numcolors)];
color.red = rndm(65535L);
color.green = rndm(65535L);
color.blue = rndm(65535L);
color.flags = DoRed|DoGreen|DoBlue;
XStoreColor(display, DefaultColormap(display,screen), &color);
}
randomize_colors()
{
int i;
XColor color[NCOLORS];
for (i=0; i<numcolors; i++) {
color[i].pixel = palette[i];
color[i].red = rndm(65535L);
color[i].green = rndm(65535L);
color[i].blue = rndm(65535L);
color[i].flags = DoRed|DoGreen|DoBlue;
}
XStoreColors(display, DefaultColormap(display,screen), color, numcolors);
}
handle_event(event)
XEvent *event;
{
int i;
if (event->type==ConfigureNotify) {
for (i=0; i<nwindows; i++) {
if (event->xconfigure.window==window[i]) {
if (CX[i] != event->xconfigure.width/2 ||
CY[i] != event->xconfigure.height/2)
XClearWindow(display,event->xconfigure.window);
CX[i] = event->xconfigure.width/2;
CY[i] = event->xconfigure.height/2;
M[i] = (CX[i]>CY[i]) ? CX[i] : CY[i];
M[i] = M[i] ? M[i] : 1;
break;
}
}
}
else if (event->type==MapNotify) {
for (i=0; i<nwindows; i++) {
if (event->xmap.window==window[i]) {
X1[i] = rndm((long)M[i]) + 1;
X2[i] = rndm((long)M[i]) + 1;
Y1[i] = rndm((long)X1[i]);
Y2[i] = rndm((long)X2[i]);
XV1[i] = rndm(7L)-3;
XV2[i] = rndm(7L)-3;
YV1[i] = rndm(7L)-3;
YV2[i] = rndm(7L)-3;
HC[i] = rndm((long)numcolors);
break;
}
}
}
else if (event->type==VisibilityNotify) {
for (i=0; i<nwindows; i++) {
if (event->xvisibility.window==window[i]) {
if (visible[i] &&
event->xvisibility.state == VisibilityFullyObscured) {
visible[i]=0;
nvisible--;
}
else if (!visible[i] &&
event->xvisibility.state != VisibilityFullyObscured) {
visible[i]=1;
nvisible++;
}
break;
}
}
}
}
usage()
{
int i;
(void)fprintf(stderr,"Usage: %s [-display <displayname>] [-bg <background>]",
progname);
(void)fprintf(stderr," [-bd <border>]\n");
for (i = 0; i<(strlen(progname)+8); i++) (void)putc(' ',stderr);
(void)fprintf(stderr,"[-bw <borderwidth>] [-geometry <geometry>]");
(void)fprintf(stderr," [-delay <msec>]\n");
for (i = 0; i<(strlen(progname)+8); i++) (void)putc(' ',stderr);
(void)fprintf(stderr,"[-icondelay <msec>] [-iconic] [-mono]");
(void)fprintf(stderr," [-mult <number>] -r\n");
for (i = 0; i<(strlen(progname)+8); i++) (void)putc(' ',stderr);
(void)fprintf(stderr,"[-randomcolor]\n");
exit(1);
}
fatalerror(s1,s2)
char *s1,*s2;
{
(void)fprintf(stderr,"%s: ",progname);
(void)fprintf(stderr,s1,s2);
(void)putc('\n',stderr);
exit(1);
}
long rndm(maxval)
long maxval;
{
long lrand48();
return ((lrand48() >> 15) * maxval) >> 16;
}
allocate_arrays(nwin)
unsigned nwin;
{
char *calloc();
if ((window=(Window *)calloc(nwin,sizeof(Window))) == NULL) return 0;
if ((CX=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((CY=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((M=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((visible=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((X1=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((Y1=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((X2=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((Y2=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((XV1=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((YV1=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((XV2=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((YV2=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((HC=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((XA=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((YA=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((XB=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((YB=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((XC=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((YC=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((XD=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((YD=(int *)calloc(nwin,sizeof(int))) == NULL) return 0;
if ((schedule=(struct timeval *)calloc(nwin,sizeof(struct timeval))) == NULL)
return 0;
if ((intervals=(struct timeval *)calloc(nwin,sizeof(struct timeval))) == NULL)
return 0;
return 1;
}
int scheduler()
{
struct timeval currtime, *nextalarm, *alarmindex;
struct timezone tzp;
int i;
/* Get current time */
(void)gettimeofday(&currtime, &tzp);
/* Find earliest alarm due */
alarmindex = nextalarm = schedule;
for (i=1; i<nwindows; i++) {
if (visible[++alarmindex - schedule] &&
( alarmindex->tv_sec < nextalarm->tv_sec ||
alarmindex->tv_sec == nextalarm->tv_sec &&
alarmindex->tv_usec < nextalarm->tv_usec ))
nextalarm = alarmindex;
}
/* If the next alarm is not past due, sleep until it comes due */
if (currtime.tv_sec < nextalarm->tv_sec ||
currtime.tv_sec == nextalarm->tv_sec &&
currtime.tv_usec < nextalarm->tv_usec) {
struct timeval timeout;
int fd=ConnectionNumber(display), readfds;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
timeout.tv_sec = nextalarm->tv_sec - currtime.tv_sec;
timeout.tv_usec = nextalarm->tv_usec - currtime.tv_usec;
if (timeout.tv_usec < 0) {
timeout.tv_sec -= 1L;
timeout.tv_usec += 1000000L;
}
readfds = 1<<fd;
(void)select(fd+1, &readfds, NULL, NULL, &timeout);
/* Recompute current time */
(void)gettimeofday(&currtime, &tzp);
}
/* Set next alarm to current time + interval */
nextalarm->tv_sec = currtime.tv_sec + intervals[nextalarm-schedule].tv_sec;
nextalarm->tv_usec = currtime.tv_usec + intervals[nextalarm-schedule].tv_usec;
if (nextalarm->tv_usec >= 1000000) {
nextalarm->tv_sec += 1;
nextalarm->tv_usec -= 1000000;
}
/* Return index of next alarm */
return nextalarm-schedule;
}