/* The zurburt example ... basic X application template */ /* to compile: cc zurburt_handout.c genrand.c -L/usr/X11R6/lib -lm -lX11 -o zurburt */ #include #include #include #include #define NUM_MI 5 #define MI_W 160 #define MI_H 40 #define MI_BSZ 1 char *choice [] = {"choice1", "choice2", "choice3", "choice4", "zurburt"}; Display *dpy; Window rootw, win, menu, mi [NUM_MI]; GC win_gc, menu_gc, mi_gc [NUM_MI]; void flip_video (); void take_action (); void write_menu_label (); main (int argc, char **argv) { XSizeHints whisper; XEvent report; XGCValues values; XFontStruct *font; XFontStruct *font2; unsigned long bp, wp, valuemask; int screen, width, height, bsz; int i; /* open (NULL) means get display name from environment variable DISPLAY, set by xterm */ if((dpy = XOpenDisplay (NULL)) == NULL) { fprintf (stderr, "can't open\n"); exit (1); } screen = DefaultScreen (dpy); width = 500; height = 400; bp = BlackPixel (dpy, screen); wp = WhitePixel (dpy, screen); rootw = RootWindow (dpy, screen); /* create output window with black border and white background; upper left corner will be at (400,100); border size at this level is overriden by window manager, so just make it 0 */ bsz = 0; win = XCreateSimpleWindow (dpy, rootw, 400, 100, width, height, bsz, bp, wp); menu = XCreateSimpleWindow (dpy, rootw, 200, 50, MI_W, MI_H * NUM_MI, bsz, bp, wp); /* individual menu items will overlay menu window */ bsz = MI_BSZ; for (i = 0; i < NUM_MI; i++) { mi [i] = XCreateSimpleWindow (dpy, menu, 0, MI_H * i, MI_W - bsz, MI_H - bsz, bsz, bp, wp); } /* whisper some hints to the window manager; suggest that it use the indicated position, width, and height for window placement */ whisper.flags = PSize|PPosition; XSetWMNormalHints (dpy, win, &whisper); XSetWMNormalHints (dpy, menu, &whisper); /* indicate which events are important; NOTE: buttonpress in menu (window) will determine which mi (subwindow); so, don't recognize buttonpress in subwindow */ XSelectInput (dpy, win, ExposureMask | KeyPressMask | StructureNotifyMask); XSelectInput (dpy, menu, ButtonPressMask | ButtonReleaseMask | KeyPressMask | StructureNotifyMask); for (i = 0; i < NUM_MI; i++) XSelectInput (dpy, mi [i], ExposureMask); /* set up graphics contexts and get the fonts ... but if you ask for one that isn't there ... BLAMO! */ valuemask = 0; font = XLoadQueryFont (dpy, "9x15"); for (i = 0; i < NUM_MI; i++) { mi_gc [i] = XCreateGC (dpy, mi [i], valuemask, &values); XSetFont (dpy, mi_gc[i], font -> fid); XSetForeground (dpy, mi_gc [i], bp); } font2 = XLoadQueryFont (dpy, "10x20"); win_gc = XCreateGC (dpy, win, valuemask, &values); XSetFont (dpy, win_gc, font2 -> fid); XSetForeground (dpy, win_gc, bp); menu_gc = XCreateGC (dpy, menu, valuemask, &values); XSetFont (dpy, menu_gc, font2 -> fid); XSetForeground (dpy, menu_gc, bp); XMapWindow (dpy, win); XMapWindow (dpy, menu); for (i = 0; i < NUM_MI; i++) XMapWindow (dpy, mi [i]); /* wait on expose from main window and expose from menu items; if you try to draw before this, you go down in flames */ for (i = 0; i <= NUM_MI; i++) { XNextEvent (dpy, &report); while (report.type != Expose) { fprintf (stderr, "waiting...\n"); XNextEvent (dpy, &report); } } for (i = 0; i < NUM_MI; i++) write_menu_label (i); while (1) { XNextEvent (dpy, &report); switch (report.type) { case Expose: for (i = 0; i < NUM_MI; i++) write_menu_label (i); break; case KeyPress: XUnloadFont (dpy, font -> fid); XUnloadFont (dpy, font2 -> fid); XFreeGC (dpy, win_gc); for (i = 0; i < NUM_MI; i++) XFreeGC (dpy, mi_gc [i]); XCloseDisplay (dpy); exit (0); case ButtonPress: for (i = 0; i < NUM_MI; i++) { if (report.xbutton.subwindow == mi [i]) break; } flip_video (i, wp, bp); /* wait for ham-handed user to let go of the button */ XNextEvent (dpy, &report); while (report.type != ButtonRelease) { XNextEvent (dpy, &report); } flip_video (i, bp, wp); take_action (i); break; default: break; } } } void flip_video (item, fore, back) int item; unsigned long fore, back; { XSetForeground (dpy, mi_gc [item], fore); XSetWindowBackground (dpy, mi [item], back); XClearWindow (dpy, mi [item]); write_menu_label (item); } void write_menu_label (i) int i; { XDrawString (dpy, mi [i], mi_gc [i], 2 * MI_BSZ, MI_H / 2, choice [i], strlen (choice [i])); } /* trivial action */ void take_action (i) int i; { XClearWindow (dpy, win); XDrawString (dpy, win, win_gc, 300, 300, choice [i], strlen (choice [i])); }