rick@hanauma (Richard Ottolini) (12/20/89)
/* display Hanukkah Menorah options: -display DISPLAY display -size 0.2 size fraction -bg blue background color (monochrome black) -candle red menorah color (monochrome white) -flame yellow flame color (monochrome white) -ncandle 8 number of candles -flicker -noflicker flame flicker interactivity: clicking candle ignites or douses flame; exposure and resize. */ /* compile: cc hanu.c -lX11 wakes up once a second to flicker and process events */ #include <stdio.h> #include <X11/Xlib.h> /* x window definitions and globals */ #define SIZE 0.2 #define TITLE "HANUKKAH GREETINGS!" Display *display; int screen; int depth; int width; int height; Colormap colormap; Window window; GC gc; char back_color[30] = "blue"; int back_pixel; /* candle definitions and globals */ #define NCANDLE 8 int ncandle = NCANDLE; char candle_color[30] = "red"; int candle_pixel; /* flame definitions and globals */ #define FLAME_OFF 0 #define FLAME_ON 1 #define FLAME1 1 #define FLAME2 2 char flame_color[30] = "yellow"; int flame_pixel; int flame_state[20]; int flicker = 1; main (argc,argv) int argc; char **argv; { GetparInit (argc,argv); Init (); Loop (); } /* initialize x windows */ Init () { char display_name[80]; float size = SIZE; XColor color1, color2; if (Getpar ("display","s",display_name) == 0) { strcpy (display_name,getenv("DISPLAY")); } if ((display = XOpenDisplay (display_name)) == NULL) { err ("cant open display"); } screen = DefaultScreen (display); depth = DefaultDepth (display,screen); colormap = XDefaultColormap (display,screen); if (depth == 1) { /* monochrome */ back_pixel = BlackPixel (display,screen); candle_pixel = WhitePixel (display,screen); flame_pixel = WhitePixel (display,screen); } else { Getpar ("bg","s",back_color); XAllocNamedColor (display,colormap,back_color,&color1,&color2); back_pixel = color1.pixel; Getpar ("candle","s",candle_color); XAllocNamedColor (display,colormap,candle_color,&color1,&color2); candle_pixel = color1.pixel; Getpar ("flame","s",candle_color); XAllocNamedColor (display,colormap,flame_color,&color1,&color2); flame_pixel = color1.pixel; } Getpar ("size","f",&size); width = DisplayWidth (display,screen) * size; height = DisplayHeight (display,screen) * size; window = XCreateSimpleWindow (display,RootWindow(display,screen), 0,0,width,height, 1,WhitePixel(display,screen),back_pixel); gc = XCreateGC (display,window,0,0); XStoreName (display,window,TITLE); XSelectInput (display,window,VisibilityChangeMask|StructureNotifyMask|ButtonPressMask); XMapWindow (display,window); Getpar ("ncandle","d",&ncandle); if (Getpar ("flicker","0",&flicker)) flicker = 1; if (Getpar ("noflicker","0",&flicker)) flicker = 0; printf ("Click to ignite flame\n"); XFlush (display); } Loop () { int i; static XEvent event; while (1) { while (XPending(display)) { XNextEvent (display,&event); switch (event.type) { /* resize */ case ConfigureNotify: if (width == event.xconfigure.width && height == event.xconfigure.height) break; width = event.xconfigure.width; height = event.xconfigure.height; case VisibilityNotify: DrawCandle (); for (i=0; i<ncandle; i++) DrawFlame (i); break; /* ignite or douse flame */ case ButtonPress: i = (event.xbutton.x*ncandle) / width; if (flame_state[i] != FLAME_OFF) { flame_state[i] = FLAME_OFF; } else { flame_state[i] = FLAME_ON; } DrawFlame (i); break; } } /* flicker */ if (flicker) { for (i=0; i<ncandle; i++) { if (flame_state[i] != FLAME_OFF) DrawFlame (i); } } /* decrease load */ sleep (1); } } DrawCandle () { int i; XClearWindow (display,window); XSetForeground (display,gc,candle_pixel); /* stalks */ for (i=0; i<ncandle; i++) { XFillRectangle (display,window,gc, (int)((i+.5)*width/(ncandle+.5)), (int)(height*0.2), (int)(width/((ncandle+.5)*2)), (int)(height*0.4)); } /* base */ XFillRectangle (display,window,gc, (int)(.5*width/(ncandle+.5)), (int)(height*0.6)-1, (int)(width*(1.-1./(ncandle+.5))), (int)(height*0.1)); XFillRectangle (display,window,gc, (int)((ncandle*.5)*width/(ncandle+.5)), (int)(height*0.7)-2, (int)(width/((ncandle+.5)*2)), (int)(height*0.2)); XFlush (display); } DrawFlame (i) int i; { switch (flame_state[i]) { /* erase */ case FLAME_OFF: XSetForeground (display,gc,back_pixel); XFillRectangle (display,window,gc, (int)((i+.5)*width/(ncandle+.5)), (int)(height*0.03), (int)(width/((ncandle+.5)*2)), (int)(height*0.15)); break; /* draw large */ case FLAME1: XSetForeground (display,gc,flame_pixel); XFillRectangle (display,window,gc, (int)((i+.5)*width/(ncandle+.5)), (int)(height*0.03), (int)(width/((ncandle+.5)*2)), (int)(height*0.15)); if (flicker) flame_state[i] = FLAME2; break; /* shrink */ case FLAME2: XSetForeground (display,gc,back_pixel); XFillRectangle (display,window,gc, (int)((i+.5)*width/(ncandle+.5)), (int)(height*0.03), (int)(width/((ncandle+.5)*2)), (int)(height*0.05)); flame_state[i] = FLAME1; break; } } err (message) char *message; { printf ("%s\n",message); exit (-1); } /* getpar routines */ int xargc; char **xargv; GetparInit (argc,argv) int argc; char **argv; { xargc = argc; xargv = argv; } Getpar (key,type,value) char *key, *type; union {int *i; float *f; char *s;} value; { int iarg, status; double atof(); status = 0; for (iarg=1; iarg<xargc; iarg++) if (xargv[iarg][0] == '-' && !strcmp (xargv[iarg]+1,key)) { switch (type[0]) { case 'd': *value.i = atoi (xargv[++iarg]); status = 1; break; case 'f': *value.f = atof (xargv[++iarg]); status = 1; break; case 's': strcpy (value.s,xargv[++iarg]); status = 1; break; case '0': status = 1; break; case '1': iarg++; if (xargv[iarg][0] == '1' || xargv[iarg][0] == 'y') *value.i = 1; if (xargv[iarg][0] == '0' || xargv[iarg][0] == 'n') *value.i = 0; status = 1; break; } } return (status); }
jonnyg@umd5.umd.edu (Jon Greenblatt) (12/21/89)
In article <6591@lindy.Stanford.EDU> rick@hanauma (Richard Ottolini) writes: >/* >display Hanukkah Menorah I think this patch speaks for itself! JonnyG. *** hanuka.c.bak Wed Dec 20 12:18:06 1989 --- hanuka.c Wed Dec 20 12:32:11 1989 *************** *** 36,39 **** int back_pixel; /* candle definitions and globals */ ! #define NCANDLE 8 --- 36,39 ---- int back_pixel; /* candle definitions and globals */ ! #define NCANDLE 9
lou@atanasoff.rutgers.edu (Lou Steinberg) (12/27/89)
Cute! I revised the program to add a shamash (an additional "servant" candle, usually placed higher than the others). Here are diffs: *** hanu.c.ORIG Tue Dec 26 15:39:42 1989 --- hanu.c.NEW Tue Dec 26 15:40:01 1989 *************** *** 37,41 **** /* candle definitions and globals */ ! #define NCANDLE 8 int ncandle = NCANDLE; char candle_color[30] = "red"; --- 37,42 ---- /* candle definitions and globals */ ! #define NCANDLE 9 ! #define SHAMASH 4 /* which candle is shamash - 0 is leftmost */ int ncandle = NCANDLE; char candle_color[30] = "red"; *************** *** 153,156 **** --- 154,163 ---- } + int shoff (i) /* if candle i is shamash, extra height for */ + int i; /* shamash, else 0 */ + { + return ( (i == SHAMASH ? (height*.1) : 0) ); + } + DrawCandle () { *************** *** 162,168 **** XFillRectangle (display,window,gc, (int)((i+.5)*width/(ncandle+.5)), ! (int)(height*0.2), (int)(width/((ncandle+.5)*2)), ! (int)(height*0.4)); } /* base */ --- 169,175 ---- XFillRectangle (display,window,gc, (int)((i+.5)*width/(ncandle+.5)), ! (int)(height*0.3-shoff(i)), (int)(width/((ncandle+.5)*2)), ! (int)(height*0.4)+shoff(i)); } /* base */ *************** *** 169,173 **** XFillRectangle (display,window,gc, (int)(.5*width/(ncandle+.5)), ! (int)(height*0.6)-1, (int)(width*(1.-1./(ncandle+.5))), (int)(height*0.1)); --- 176,180 ---- XFillRectangle (display,window,gc, (int)(.5*width/(ncandle+.5)), ! (int)(height*0.7)-1, (int)(width*(1.-1./(ncandle+.5))), (int)(height*0.1)); *************** *** 174,180 **** XFillRectangle (display,window,gc, (int)((ncandle*.5)*width/(ncandle+.5)), ! (int)(height*0.7)-2, (int)(width/((ncandle+.5)*2)), ! (int)(height*0.2)); XFlush (display); } --- 181,187 ---- XFillRectangle (display,window,gc, (int)((ncandle*.5)*width/(ncandle+.5)), ! (int)(height*0.8)-2, (int)(width/((ncandle+.5)*2)), ! (int)(height*0.18)); XFlush (display); } *************** *** 189,193 **** XFillRectangle (display,window,gc, (int)((i+.5)*width/(ncandle+.5)), ! (int)(height*0.03), (int)(width/((ncandle+.5)*2)), (int)(height*0.15)); --- 196,200 ---- XFillRectangle (display,window,gc, (int)((i+.5)*width/(ncandle+.5)), ! (int)(height*0.13-shoff(i)), (int)(width/((ncandle+.5)*2)), (int)(height*0.15)); *************** *** 198,202 **** XFillRectangle (display,window,gc, (int)((i+.5)*width/(ncandle+.5)), ! (int)(height*0.03), (int)(width/((ncandle+.5)*2)), (int)(height*0.15)); --- 205,209 ---- XFillRectangle (display,window,gc, (int)((i+.5)*width/(ncandle+.5)), ! (int)(height*0.13-shoff(i)), (int)(width/((ncandle+.5)*2)), (int)(height*0.15)); *************** *** 208,212 **** XFillRectangle (display,window,gc, (int)((i+.5)*width/(ncandle+.5)), ! (int)(height*0.03), (int)(width/((ncandle+.5)*2)), (int)(height*0.05)); --- 215,219 ---- XFillRectangle (display,window,gc, (int)((i+.5)*width/(ncandle+.5)), ! (int)(height*0.13-shoff(i)), (int)(width/((ncandle+.5)*2)), (int)(height*0.05)); -- Lou Steinberg uucp: {pretty much any major site}!rutgers!aramis.rutgers.edu!lou arpa: lou@cs.rutgers.edu