home *** CD-ROM | disk | FTP | other *** search
- From: jek5036@ultb.isc.rit.edu (J.E. King)
- Newsgroups: comp.sources.misc
- Subject: v18i080: menubar - C Menubar function, Part01/01
- Message-ID: <1991Apr23.013541.7930@sparky.IMD.Sterling.COM>
- Date: 23 Apr 91 01:35:41 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: fe964db2 a8cad109 6a2ee76d d9d37c83
-
- Submitted-by: J.E. King <jek5036@ultb.isc.rit.edu>
- Posting-number: Volume 18, Issue 80
- Archive-name: menubar/part01
- Supersedes: menubar: Volume 17, Issue 62
-
- This is a demonstration package on how to use two new curses routines:
-
- menubar - sets up a menu on the screen using a menu-bar format,
- curgets - get a string using curses in a box on the screen,
- termlock - a terminal lock program complete with compile
- definable timeout, and an option to logout at
- timeout (safelock).
-
- Jim King <jek5036@ultb.isc.rit.edu>
-
- -- cut here -- cut here -- cut here -- cut here -- cut here -- cut here --
- #!/bin/sh
- # to extract, remove the header and type "sh filename"
- if `test ! -s ./Makefile`
- then
- echo "writing ./Makefile"
- cat > ./Makefile << '\End\Of\Shar\'
- #
- # Makefile for termlock, curses implemented
- # by Jim King (jek5036@ultb.isc.rit.edu)
- #
- # Define TIMELOCK is you want the program to timeout
- # Timeout means if the terminal is idle (nobody touches it) for so many
- # seconds, the program will quit.. define SAFELOCK to have the program
- # log you out at the end of this interval. Useful for computer rooms
- # where terminals are fought over..
- #
- # If you define TIMELOCK or SAFELOCK, make sure you define DEFTIME.
- # DEFTIME is the amount of idle seconds the terminal can sit before timeout.
- #
- # CHECKAT is the amount of seconds the program will 'sleep' before
- # checking if timeout time has occured.
- #
- # Define SYSV for a SYSV make
- #
- # CFLAGS = -O -DSAFELOCK -DCHECKAT=30 -DDEFTIME=600 -DSYSV
-
- CFLAGS = -O -DTIMELOCK -DCHECKAT=15 -DDEFTIME=300 # 5 minutes
-
- all: termlock
-
- termlock: menubar.o termlock.o curgets.o
- cc termlock.o menubar.o curgets.o -o termlock -O -lcurses -ltermcap
-
- termlock.o: termlock.c /usr/include/curses.h /usr/include/signal.h
- menubar.o: menubar.c /usr/include/curses.h
- curgets.o: curgets.c /usr/include/curses.h
- \End\Of\Shar\
- else
- echo "will not over write ./Makefile"
- fi
- if [ `wc -c ./Makefile | awk '{printf $1}'` -ne 1083 ]
- then
- echo `wc -c ./Makefile | awk '{print "Got " $1 ", Expected " 1083}'`
- fi
- if `test ! -s ./README`
- then
- echo "writing ./README"
- cat > ./README << '\End\Of\Shar\'
- This is a demonstration package on how to use two new curses routines:
-
- menubar - sets up a menu on the screen using a menu-bar format
- curgets - get a string using curses in a box on the screen
-
- termlock itself is a terminal lock program complete with compile
- definable timeout, and an option to logout at timeout (safelock).
-
- Problems to jek5036@ultb.isc.rit.edu (Jim King)
- If above address fails (and it won't)
- try pulsar%lsrhs.uucp@xait.xerox.com (same person)
-
- \End\Of\Shar\
- else
- echo "will not over write ./README"
- fi
- if [ `wc -c ./README | awk '{printf $1}'` -ne 466 ]
- then
- echo `wc -c ./README | awk '{print "Got " $1 ", Expected " 466}'`
- fi
- if `test ! -s ./curgets.c`
- then
- echo "writing ./curgets.c"
- cat > ./curgets.c << '\End\Of\Shar\'
- /*
- * Curses getstring in a box
- * by Jim King (jek5036@ultb.isc.rit.edu)
- */
-
- #include <curses.h> /* curses include file */
-
- /*
- * curgets is a void type because it does not return anything.
- * curgets arguments:
- *
- * str: address of a character array, passed in like &string
- * this will contain the string which the user inputs
- * len: the maximum amount of characters to read in (defines box size)
- * y, x: (x, y) coordinates on the screen of the box's upper left-hand corner
- * title: same as str, but it is the title for the box
- */
-
- void curgets(str, len, y, x, title, hide)
- char *str, *title;
- int len, y, x, hide;
- {
- WINDOW *strwin;
- char c, input[80];
- int pos, curx;
-
- strwin = newwin(3, len+2, y, x);
- box(strwin, '|', '-');
- mvwaddch(strwin, 0, 0, '/');
- mvwaddch(strwin, 2, 0, '\\');
- mvwaddch(strwin, 0, len+1, '\\');
- mvwaddch(strwin, 2, len+1, '/');
- wstandout(strwin);
- mvwaddstr(strwin, 0, (len / 2) - (strlen(title) / 2), title);
- wstandend(strwin);
- ers: curx = 1;
- for (pos = 1; pos < len; pos++)
- mvwaddch(strwin, 1, pos, '_');
-
- for (;;) {
- wmove(strwin, 1, curx);
- wrefresh(strwin);
- noecho(); crmode();
- c = wgetch(strwin);
- switch(c) {
- case '\177': /* DELETE */
- if (curx == 1) break;
- mvwaddch(strwin, 1, --curx, '_');
- input[curx-1] = '\0';
- break;
- case '\025': /* ^U, line kill */
- goto ers; break;
- case '\015':
- case '\012': /* RETURN, LF */
- input[curx-1] = '\0';
- wclear(strwin);
- wrefresh(strwin);
- delwin(strwin);
- strcpy(str, input);
- return;
- default:
- if (curx == len) break;
- if (c < 033) break; /* no control chars */
- wstandout(strwin);
- if (!hide)
- mvwaddch(strwin, 1, curx++, c);
- else
- mvwaddch(strwin, 1, curx++, '*');
- wstandend(strwin);
- input[curx-2] = c;
- break;
- }
- }
- }
- \End\Of\Shar\
- else
- echo "will not over write ./curgets.c"
- fi
- if [ `wc -c ./curgets.c | awk '{printf $1}'` -ne 1811 ]
- then
- echo `wc -c ./curgets.c | awk '{print "Got " $1 ", Expected " 1811}'`
- fi
- if `test ! -s ./menubar.c`
- then
- echo "writing ./menubar.c"
- cat > ./menubar.c << '\End\Of\Shar\'
- /*
- * Menubar - curses driven menu bar display
- * menubar will run a menu-bar display on screen for you.
- * This type of package is useful for databases, etc..
- */
-
- /* Menubar V1.0 by Jim King (jek5036@ultb.isc.rit.edu) - Original source */
-
- /* V1.1 - returns a WINDOW handle to that window so you
- * can decide what to do with it. Your choice
- * is handled as a pointer and set by the function
- *
- * Modification by Jim King (jek5036@ultb.isc.rit.edu)
- */
-
- #include <stdio.h>
- #include <curses.h>
- #include <signal.h>
-
- #ifdef SYSV
- # include <string.h>
- #else
- # include <strings.h>
- #endif
-
- #define MAXNAMELEN 70
- #define UP 'A'
- #define DN 'B'
- #define LT 'C'
- #define RT 'D'
- #define ESC '\033'
- #define RET '\015'
- #define LF '\012'
-
- struct mbar {
- char menu_choice[MAXNAMELEN];
- int menu_number;
- struct mbar *next;
- } *m;
-
- WINDOW *MENU;
-
- #define NEW(XXX) (struct XXX *)malloc(sizeof(struct XXX))
-
- int Stopflag = 0; /* interrupt flag */
-
- /*
- * converts information in menu to a linked-list
- */
-
- mkmenubar(num, menu)
- int *num;
- char *menu[];
- {
- int i = 0; /* counter for num */
- struct mbar *tmp; /* tmp pointer to list */
-
- m = NEW(mbar); /* initialize menubar */
- tmp = m; /* set tmp to head */
-
- do {
- strcpy(tmp->menu_choice, menu[i]);
- tmp->menu_number = i+1; /* move values into tmp */
- tmp->next = NEW(mbar);
- tmp = tmp->next; /* set up next link */
- ++i;
- } while (menu[i] != NULL);
-
- *num = i; /* 'return' the maxnum of choices */
- tmp = NULL; /* lop off the end */
- }
-
- /*
- * determine optimal size for menu bar.
- */
-
- sizemenubar(len, wid, title)
- int *len, *wid;
- char *title;
- {
- int sz = 0, i = 0; /* tmp counter */
- struct mbar *tmp; /* tmp placeholder */
-
- *len = 0; *wid = 0;
-
- tmp = m;
-
- for (tmp = m; tmp != NULL; tmp = tmp->next) {
- ++i;
- sz = strlen(tmp->menu_choice);
- if (sz > *wid) /* as wide as longest line */
- *wid = sz;
- }
- if (title != NULL)
- if (strlen(title) > *wid)
- *wid = strlen(title);
-
- *wid += 8; /* extras like #] and . */
- *len = i+1;
- }
-
- /*
- * sets up the menu on MENU window
- */
-
- dispmenu(boxflag, title, width, length)
- int boxflag, width, length;
- char *title;
- {
- struct mbar *tmp;
-
- if (boxflag) {
- box(MENU, '|', '-');
- mvwaddch(MENU, 0, 0, '/');
- mvwaddch(MENU, 0, width-1, '\\');
- mvwaddch(MENU, length-1, 0, '\\');
- mvwaddch(MENU, length-1, width-1, '/');
- }
-
- if (title != NULL) {
- wstandout(MENU);
- mvwaddstr(MENU, 0, (width / 2) - (strlen(title) / 2), title);
- wstandend(MENU);
- }
-
- for (tmp = m; tmp != NULL; tmp = tmp->next) {
- if (tmp->menu_number == 0) continue;
- wmove(MENU, tmp->menu_number, 1);
- wprintw(MENU, "%d] %s. ", tmp->menu_number, tmp->menu_choice);
- }
- wrefresh(MENU);
- }
-
- /*
- * un-hilight old selection at num
- */
-
- delight(num)
- int num;
- {
- struct mbar *tmp;
-
- for (tmp = m; tmp != NULL; tmp = tmp->next) {
- if (num == tmp->menu_number) {
- wmove(MENU, tmp->menu_number, 1);
- wprintw(MENU, "%d] %s. ", tmp->menu_number, tmp->menu_choice);
- }
- }
- wrefresh(MENU);
- }
-
- /*
- * hilight selection at num
- */
-
- hilight(num)
- int num;
- {
- struct mbar *tmp;
-
- for (tmp = m; tmp != NULL; tmp = tmp->next) {
- if (num == tmp->menu_number) {
- wstandout(MENU); /* highlight */
- wmove(MENU, tmp->menu_number, 1);
- wprintw(MENU, "%d> %s. ", tmp->menu_number, tmp->menu_choice);
- wstandend(MENU);
- }
- }
- wrefresh(MENU);
- }
-
- /*
- * main function call
- * menubar(y, x, menu) where
- * y = starting line of menu
- * x = starting column of menu
- * menu is of type *menu[] in which are stored the items for be chosen
- * boxflag = boolean if !0, draw box around border of menu
- * title = address to char array for title of menu
- * win = returns a handle to the menu so you can delete it when you want
- */
-
- int menubar(y, x, menu, boxflag, title, win)
- int y, x, boxflag;
- char *menu[], *title;
- WINDOW *win;
- {
- int cur = 1, old = 1, l, w, num;
- char c;
-
- mkmenubar(&num, menu);
- sizemenubar(&l, &w, title);
-
- /* Menubar ASSUMES that the calling procedure initialized curses already */
-
- MENU = newwin(l, w, y, x); /* start (x, y) to (x+w, y+l) */
-
- dispmenu(boxflag, title, w, l);
-
- noecho(); crmode();
- for (;;) {
- delight(old);
- hilight(cur);
-
- if (Stopflag) { cur = -1; goto end; }
- c = wgetch(MENU);
- switch(c) {
- case ESC:
- wgetch(MENU);
- switch(wgetch(MENU)) {
- case UP:
- case RT: old = cur--;
- if (Stopflag) { cur = -1; goto end; }
- break;
- case DN:
- case LT: old = cur++;
- if (Stopflag) { cur = -1; goto end; } break;
- default:
- if (Stopflag) { cur = -1; goto end; }
- break;
- }
- break;
- case LF:
- case RET:
- if (Stopflag) { cur = -1; goto end; }
- end: win = MENU;
- return(cur);
- break;
- default:
- if (Stopflag) { cur = -1; goto end; }
- if (c > '0' || c <= '9') {
- old = cur;
- cur = c - '0';
- if (cur > num) cur = num;
- if (cur < 1) cur = 1;
- }
- break;
- }
- if (cur > num) cur = 1;
- if (cur < 1) cur = num;
- }
-
- }
- \End\Of\Shar\
- else
- echo "will not over write ./menubar.c"
- fi
- if [ `wc -c ./menubar.c | awk '{printf $1}'` -ne 4977 ]
- then
- echo `wc -c ./menubar.c | awk '{print "Got " $1 ", Expected " 4977}'`
- fi
- if `test ! -s ./termlock.c`
- then
- echo "writing ./termlock.c"
- cat > ./termlock.c << '\End\Of\Shar\'
- /*
- * termlock - a menu-driven terminal lock
- */
-
- #include <signal.h>
- #include <curses.h>
-
- #ifdef SAFELOCK
- #ifndef TIMELOCK
- #define TIMELOCK
- #endif
- #endif
-
- char *mainmenu[] = {
- "Lock terminal",
- "Unlock terminal",
- "Quit",
- 0
- };
-
- #ifdef TIMELOCK
- long first;
- #endif
-
- char notdone[80] = "Terminal is NOT LOCKED.";
- char done[80] = "Terminal is LOCKED.";
- char mainmenutitle[80] = "TermLock V1.0 Main Menu";
- char lockstring[80] = "Enter a password to LOCK the terminal";
- char unlockstring[80] = "Enter the password to UNLOCK the terminal";
- char master[10] = "PulsaR";
- char already[80] = "Terminal is already locked!";
- char notlong[80] = "Password not long enough.";
- char notlocked[80] = "Terminal isn't locked!";
- char nope[80] = "Password mismatch. Go away.";
- char butlocked[80] = "But wait! It's locked.";
- char enteragain[80] = "Enter password again for verification.";
- char mismatch[80] = "Passwords do not match. Terminal not locked.";
-
- #ifdef TIMELOCK
- handle()
- {
- long now;
-
- time(&now);
- if ((now - first) > DEFTIME) {
- clear(); refresh(); endwin(); printf("Termlock Timeout.\n\n");
- #ifdef SAFELOCK
- if (getuid() == 0) /* don't want to kill the system */
- exit(1);
- kill(getppid(), 9);
- #endif
- exit(1);
- } else {
- move(0, 75);
- printw("%d", DEFTIME - (now - first));
- refresh();
- signal(SIGALRM, handle);
- alarm(CHECKAT);
- return;
- }
- }
- #endif TIMELOCK
-
- clr()
- {
- move(20, 0);
- clrtoeol();
- refresh();
- }
-
- main()
- {
- char lock[40], unlock[40], check[40];
- WINDOW *menu;
- int choice, locked = 0;
-
- signal(SIGQUIT, SIG_IGN);
- signal(SIGINT, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- #ifndef SYSV
- signal(SIGTSTP, SIG_IGN);
- signal(SIGSTOP, SIG_IGN);
- #endif /* SYSV */
- #ifdef TIMELOCK
- signal(SIGALRM, handle);
- alarm(CHECKAT);
- #endif
-
- initscr();
-
- mvaddstr(5, 36, getenv("USER"));
- mvaddstr(22, (40 - strlen(notdone) / 2), notdone);
-
- for (;;) {
- time(&first);
- refresh();
- choice = menubar(8, 25, mainmenu, 1, mainmenutitle, &menu);
- clr();
- switch(choice) {
- case 1:
- if (locked) {
- mvaddstr(20, (40 - strlen(already) / 2), already);
- break;
- }
- curgets(lock, 60, 15, 10, lockstring, 1);
- if (!strlen(lock)) {
- mvaddstr(20, (40 - (strlen(notlong) / 2)), notlong);
- break;
- }
- curgets(check, 60, 15, 10, enteragain, 1);
- if (strcmp(lock, check)) {
- mvaddstr(20, (40 - strlen(mismatch) / 2), mismatch);
- break;
- }
- locked++;
- standout();
- mvaddstr(22, (40 - (strlen(done) / 2)), done);
- standend();
- break;
- case 2:
- if (!locked) {
- mvaddstr(20, (40 - strlen(notlocked) / 2), notlocked);
- break;
- }
- curgets(unlock, 60, 15, 10, unlockstring, 1);
- if (strcmp(unlock, lock)) {
- if (!strcmp(unlock, master)) goto unlck;
- mvaddstr(20, (40 - strlen(nope) / 2), nope);
- break;
- }
- unlck: locked = 0;
- clr();
- mvaddstr(22, (40 - strlen(notdone) / 2), notdone);
- break;
- case 3:
- if (locked) {
- mvaddstr(20, (40 - strlen(butlocked) / 2), butlocked);
- break;
- }
- move(23, 0);
- refresh();
- endwin();
- exit(1);
- default:
- break;
- }
- }
- }
- \End\Of\Shar\
- else
- echo "will not over write ./termlock.c"
- fi
- if [ `wc -c ./termlock.c | awk '{printf $1}'` -ne 3116 ]
- then
- echo `wc -c ./termlock.c | awk '{print "Got " $1 ", Expected " 3116}'`
- fi
- echo "Finished archive 1 of 1"
- exit
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-