home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume18
/
menubar
/
part01
next >
Wrap
Internet Message Format
|
1991-04-23
|
14KB
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.