home *** CD-ROM | disk | FTP | other *** search
- From: pjc@pcbox.UUCP (Paul J. Condie)
- Newsgroups: alt.sources
- Subject: menu(1) part 3 of 14
- Message-ID: <437@pcbox.UUCP>
- Date: 26 Dec 90 20:05:20 GMT
-
-
- #!/bin/sh
- # this is part 3 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file menu.1 continued
- #
- CurArch=3
- if test ! -r s2_seq_.tmp
- then echo "Please unpack part 1 first!"
- exit 1; fi
- ( read Scheck
- if test "$Scheck" != $CurArch
- then echo "Please unpack part $Scheck next!"
- exit 1;
- else exit 0; fi
- ) < s2_seq_.tmp || exit 1
- echo "x - Continuing file menu.1"
- sed 's/^X//' << 'SHAR_EOF' >> menu.1
- X KEY_CANCEL = 27 # (esc) Cancel all input from a GETINPUT screen or cancel a pop-up menu selection.
- X Exit a help screen.
- X KEY_SAVE = 6 # (^f) Save a GETINPUT screen to a file.
- X KEY_PRINT = 16 # (^p) Print a GETINPUT screen to lp.
- X.fi
- X
- X.SH EXAMPLE menufile
- X.nf
- X\fB###\fR This is a example of a menu script file.
- X
- X\fB .AUTHORIZE\fR pjc nortons boink mozart
- X
- X\fB###\fR Initialize function keys for TERM=5425
- X\fB .UNIX\fR echo "\\033[1;2;0;0q HELP h\\r\\c"
- X
- X\fB###\fR Define goto menu names.
- X\fB .GNAME\fR main main.m
- X\fB .GNAME\fR reports reports.m
- X
- X\fB###\fR Title Lines Section.
- X\fB .TITLE\fR
- X Version 3.00...\\RPACIFIC * BELL\\N...$DATE
- X\fB .TITLE\fR
- X $MAIL...Sample Menu...\\S$TIME\\N
- X\fB .TITLE\fR
- X ...MAIN MENU...
- X\fB .LINE\fR
- X
- X\fB###\fR Left column of screen - Options
- X\fB .WINDOW\fR 0 23 0 39
- X\fB .SYSTEM\fR who
- XList who is on the system.
- X\fB .SYSTEM\fR ps -ef; \\
- X echo "Press [ Return ] to continue.\\c"; read reply
- XPrint process status table.
- X
- X\fB###\fR Right column of screen - Options
- X\fB .WINDOW\fR 0 23 40 79 \\R SUB MENU \\N
- X\fB .MENU\fR reports.m
- XGo to report menu.
- X
- X\fB .TEXT\fP 22 50
- XSelection [ ? for help ]
- X.fi
- X
- X.SH GENERALLY ACCEPTED GUIDELINES
- X.PD 0.1
- X.IP -> 3
- XPut a meaningful title on the top of every menu.
- X.IP -> 3
- XProvide symmetric balance by centering the title and the menu options
- Xaround the center axis of the screen.
- X.IP -> 3
- XChoose an organizing principle for the menu options.
- XOrganize menu hierarchies according to the tasks users will perform, rather
- Xthan the structure of the software modules.
- X.br
- XHints in organizing options:
- X.RS 6
- X.IP * 3
- XChronological ordering
- X.IP * 3
- XAscending or descending numerical ordering
- X.IP * 3
- XItems grouped by physical properties, (Increasing volume, weight or temperature)
- X.IP * 3
- XAlphabetic sequence of terms
- X.IP * 3
- XGrouping of related options with spatial demarcation between groups
- X.IP * 3
- XMost frequently used options first
- X.IP * 3
- XMost important options first
- X.RE
- X.IP -> 3
- XTo facilitate scanning, put blank lines between logical groupings of menu
- Xoptions and after about every fifth option in a long list.
- X.IP -> 3
- XLimit the number of menu choices of one screen.
- XThe breadth (number of options per menu) should be no more than eight and the
- Xdepth (number of levels of menus) should be no more than four.
- X.IP -> 3
- XUse words for your menu options that clearly and specifically describe
- Xwhat the user is selecting; use simple, active verbs to describe menu options.
- XUse common, short English words that clearly describe the action that the
- Xcommand will carry out; choose words that are distinctive from one another.
- X.IP -> 3
- XDisplay the menu options in mixed, upper and lower case letters.
- X.IP -> 3
- XBe sure that any function keys that you use will operate correctly on all of
- Xthe different types of keyboards the users have.
- X.IP -> 3
- XBe consistent in the use of menu formats, procedures, and wording; the
- Xmapping of keys to functions; the naming of menu options.
- X.IP -> 3
- XOptions should suggest or entail closure. If a menu option calls another
- Xmenu (.MENU) the option description should be the title of the called menu
- Xto provide continuity. Likewise, if a menu option calls a program (reports,
- Xscreens) the option description should be the title of the report/screen.
- X.IP -> 3
- XDisplay only information that the user needs to know.
- X.IP -> 3
- XEvery menu should indicate how to exit from the screen.
- X.IP -> 3
- XAvoid hyphenation of words between lines.
- X.IP -> 3
- XUse abbreviation and acronyms only when they are significantly shorter than
- Xthe full text and when they will be understood by the user.
- X.IP -> 3
- XOptions in a multiple column list should be organized in vertical columns
- Xwhich are read from left to right on the screen.
- X.IP -> 3
- XPut a least two spaces between the longest item in a column and the beginning
- Xof the next column.
- X.IP -> 3
- XUse highlighting to emphasize important information only. Do not overuse
- Xit.
- X.IP -> 3
- XA \fI.POPMENU\fP, if possible, should appear as close to and to the right
- Xof the option that selected it. Probably a \fI.GETINPUT\fP screen should also.
- X.PD
- X
- X.SS References
- XHuman Factors Engineering, User Interface Guidelines, Pacific Bell, Sept (1987)
- X.PP
- XShore, John, The Sachertorte Algorithm and Other Antidotes to Computer
- XAnxiety, Viking Penguid Inc. (1985)
- X.IP * 3
- XShore's book for the general public which translates into why designing
- Xgood user interfaces are necessary.
- X.PP
- XBeer, S. and Schoefer, W., Screen Development Guidelines - Draft,
- XVersion 1.0, Pacific Bell, April (1987)
- X.PP
- XRubinstein R., and Hersch H.M., with Ledgard, H.F., The Human Factor:
- XDesigning Computer Systems for People. Digital Press, Digital Equipment
- XCorporation, (1984).
- X.IP * 3
- XRubinstein's work is very interesting and original. The text is readable
- Xand the ideas presented are clear and attractive. This is not a text book.
- X.PP
- XFuture Technology Architecture District, Proposed Pacific*Bell Screen
- XStandards For NonProgrammable Terminals, Pacific Bell, May (1988)
- X.PP
- XDumas Joseph S., Designing User Interface for Software, Prentice Hall, 1988
- X
- X.SH CREDITS
- XPaul J. Condie 8/18/86 original author
- X.br
- X{att,bellcore,sun,ames,pyramid}!pacbell!pcbox!pjc
- X.br
- X
- XIrving Griesman GetInput(3X).
- X.br
- XSam S. Lok popmenu(3) enhancements, runrealid(3).
- X
- X.SH NOTE
- XIf memory size is important modify LoadKeys.c and remove all references
- Xto keywords your application does not use then relink. This will reduce
- Xthe size of menu.
- X
- X.SH FILES
- Xmenu.hlp - menu help file
- X.br
- X/usr/local/lib/menus - some menus you might want to use or look at.
- X.br
- X/usr/local/lib/menus/sample.m - a sample menu file
- X.br
- X/usr/local/lib/menus/printers.m - printers pop-up menu
- X.br
- X/usr/local/lib/menus/reportsrn.m - report option input screen
- X.br
- X/usr/lib/acct/holidays - holidays file.
- X
- XThe library of menus may vary from machine to machine.
- X
- X.SH SEE ALSO
- XMenuAccess(1), curses(3X), system(3), mail(1), getenv(3),
- Xlock(1), unlock(1), GetInput(3X), checkpass(1), runrealid(1), MenuMsg(1),
- XMenuPrompt(1).
- X
- X.SH WARNING
- XBecause menu uses the environment to pass and save data you are limited on the
- Xvolume of data you can have based upon the size of your environment.
- XThis will vary from machine to machine. If you see the
- Xmessage "Unable to allocate environment memory..." then you have reached
- Xyour limit. Actually you've surpassed the limit or you wouldn't have
- Xgotten the message. But lets not squabble.
- X
- XMenu has very little intelligence built in to check if you exceed the bounds
- Xof any fields. If menu core dumps, especially with a bus error, you are
- Xprobably trying to load too large a value into a field.
- X
- X.SH BUGS
- XCurses bug - When a attribute is the last character on the line (spaces don't
- Xcount) the attributes do not get turned off until it hits the next character
- Xon the next line.
- X
- X.PP
- XWhen you use the mail notification $MAIL the alarms get buffered up when
- Xthe cursor is just sitting there, so, as soon as the user types something
- Xat the keyboard all the alarms that were buffered take off, which means, you
- Xget a beep...beep...beep...beep. This doesn't happen on AT&T 3b machines
- Xbut I've noticed it on SUNS and ARETE machines.
- XYou should take the -DALARM off the CFLAGS in the makefile which tells
- Xmenu not to use the alarm(2) to check for mail, but check when a key
- Xhas been pressed.
- X
- X.PP
- XMenu has not really been tested on terminals/windows that is not 24x80,
- Xok,ok... it hasn't been tested at all. For the most part it should work
- Xfine, EXCEPT (you knew that was coming), when you want to create columns
- Xof options using the .WINDOW keyword. The parameters to .WINDOW are
- Xabsolute therefore when you line up your columns for a 24x80 terminal and
- Xyour menu is run on say a 34x132 terminal your columns will not be
- Xcentered right. Probably a new keyword should be introduced ".COLUMN"
- Xwhich would have some intelligence built in to try to center columns within
- Xthe window space. It might have some problems going from a larger window
- Xto a smaller window if the columns won't fit.
- X.br
- XAnyone volunteer to write this one?
- X
- X.PP
- XTerminal attributes sometimes don't work right. Especially when putting
- Xmultiple attributes on one line. In all cases I've seen it is a restriction
- Xof the terminal (hardware).
- X
- X.bp
- X.SH PROGRAMMING NOTES
- XThis section is for those of you who want to or need to add new keywords.
- X.PP
- XThe keywords that have been provided should accommodate most
- Xapplication menus, however, if customization is needed the following
- Xmay come in handy. If you introduce any neat new keywords (say like
- X".IF THEN ELSE") I would
- Xappreciate you sending them to me so I can incorporate them. Send your
- XParse, Show, and Run functions along with a copy of \fILoadKeys.c\fP.
- X.PP
- XMenu is primarily driven from the LoadKeys.c module. This
- Xmodule describes to menu what keywords it needs to scan for and what
- Xaction to take when found.
- XThere are four sections in LoadKeys (see LoadKeys example) each of which
- Xneed to be
- Xdefined if you are introducing a new keyword. LoadKkeys provides three areas
- Xof control (sections 2,3,4), and it is important that you know what you
- Xwant to accomplish at each control point:
- X.TP 4
- XParse
- XWhat do you want menu to do with your keyword once it has found it during
- Xthe parsing routine? Any data you need to store for a later step, etc..
- X.TP 4
- XShow
- XHow do you want your keyword displayed to the screen? Define as NULL if
- Xnot appropriate.
- X.TP 4
- XRun
- XIf the user selects an option that is your keyword, what do you want done?
- X
- X.PP
- XIf you want to put debugging code in your functions then the following
- Xformat should be used.
- X.nf
- Xextern int debug;
- X if (debug)
- X {
- X fprintf (stderr, "\n[%s] <%s> ...", __FILE__,
- X menu->option[opnumber]->keyword, ...);
- X fflush (stderr);
- X }
- X.fi
- Xwhere [Function] is the function name and <KeyWord> is the keyword being
- Xprocessed.
- X
- X.SS ADDING A NEW KEYWORD
- X.TP 8
- XStep 1:
- XDecide on the name of the new keyword. For consistency sake, I suggest, it
- Xshould begin with a "." and be all in caps. Maximum length of keyword is
- XMAXKEYLENGTH (15). Then formulate a syntax for the keyword (what the user
- Xneeds to type in the menufile).
- X.br
- XAlso, get clear in your mind what you want done at each of the three control
- Xpoints.
- X
- X.TP 8
- XStep 2:
- Xvi LoadKeys.c
- X.br
- XStrcpy your keyword into the next available slot in KeyWord[], under SECTION 1.
- XMake sure MAXKEYS in menu.h is >= the slot you strcpy'ied your keyword into.
- XSee KeyWord[] below.
- X
- X.TP 8
- XStep 3:
- XIn SECTION 2 of LoadKeys.c assign the Parse function that is going
- Xto parse your keyword.
- XIt should be assigned to the same slot as in SECTION 1. First see if one
- Xof the Parse functions already written will do the job. If so use that one,
- Xif not you will have to write one. For consistency call it Parse????.c or
- XPar????.c, and declare it at the beginning of LoadKeys.c.
- XAll keywords must have a parse function.
- XThis function is called immediately when your keyword is found while parsing
- Xthe menufile.
- XSee ParseKey[]() below.
- X.br
- XReturn Values:
- X.RS 8
- X.TP 9
- X0
- XContinue to parse next keyword.
- X.TP 9
- X-1
- XQuit/Exit menu program.
- X.TP 9
- X-2
- XReturn to main menu.
- X.TP 9
- X-4
- XNOWAYJOSE - Not authorized to run this menu.
- X.TP
- Xanything else
- XAbort this menu and return to previous menu.
- X.RE
- X
- X.TP 8
- XStep 4:
- XIn SECTION 3 of LoadKeys.c assign the Show function (if your keyword is a
- Xuser selectable option) that will display the
- Xoption to the screen.
- XIt should be assigned to the same slot as in SECTION 1. First see if one
- Xof the Show functions already written will do the job. If so use that one,
- Xif not you will have to write one. For consistency call it Show????.c, and
- Xdeclare it at the beginning of LoadKeys.c.
- XThis function is called when displaying options to the screen.
- XIf you don't need a Show function for your keyword assign slot to NULL.
- XSee ShowKey[]() below.
- X
- X.TP 8
- XStep 5:
- XIn SECTION 4 of LoadKeys.c assign the Run function (if your keyword is a
- Xuser selectable option) that will be called when the user selects this option.
- XIt should be assigned to the same slot as in SECTION 1. First see if one
- Xof the Run functions already written will do the job. If so use that one,
- Xif not you will have to write one. For consistency call it Run????.c, and
- Xdeclare it at the beginning of LoadKeys.c.
- XIf you don't need a Run function for your keyword assign slot to NULL.
- X.br
- XReturn Values:
- X.RS 8
- X.TP 9
- X0
- XAOK, continue with normal menu processing.
- X.TP 9
- XMAINMENU
- XGoto main menu. This is as if the user had typed an "M".
- X.TP
- XPREVIOUSMENU
- XGoto previous menu. This is as if the user had typed a "P".
- X.TP
- XQUIT
- XQuit program. This is as if the user had typed an "E".
- X.TP
- XSUBMENU
- XIf you are introducing
- Xa new submenu keyword (like \fI.MENU\fP) the Run??? function must return
- X(SUBMENU), a #define.
- XRefer to \fIRunMenu.c\fP for an example.
- X.TP
- XGNAMEOFFSET + gindex
- XGoto a specific (.GNAME) menu.
- XWhere gindex = the index into the gnames array (base 0).
- XThis is as if the user had typed a goto menu.
- X.RE
- X
- X.TP 6
- XStep 6:
- XCompile your new functions, LoadKeys.c and link into menu.
- XYour KeyWord should work.
- XThere should be no need to change any of the existing driver routines
- X(other than LoadKeys.c)?
- X
- X
- X.SS char KeyWord[]
- XThis array identifies all the keywords to be scanned for in your
- Xmenufile. Maximum number of keys is "MAXKEYS" defined in menu.h
- Xfile. Increasing MAXKEYS will allow more keys.
- X
- X.SS "int (*ParseKey[]) (keyword, menufile, menu, KeyWord, ParseKey, gnames, gfiles, gindex, opnumber)"
- X.nf
- Xchar keyword[];
- XFILE *menufile;
- Xstruct MenuInfo *menu;
- Xchar KeyWord[][MAXKEYLENGTH];
- Xint (*ParseKey[])();
- Xchar gnames[][15], gfiles[][15];
- Xint *gindex;
- Xint *opnumber;
- X.fi
- XArray of pointers to functions that will be called to parse the
- Xkeyword when found. Any processing you want done while program
- Xis parsing your keyword should be placed in this function.
- XIf you have defined a new keyword you must
- Xdescribe how that keyword is to be parsed. Unless you are doing
- Xsomething special ParseOption() should do the job.
- XYour new function will need to malloc struct OptionInfo if you
- Xwant to store some information for the option. The following describes
- Xthe data passed to all parsing functions.
- X.RS 6
- X.TP 6
- Xkeyword
- XThe keyword that was found in menufile.
- X.TP 6
- X*menufile
- XA pointer to your menufile. When function returns you must leave
- Xthe pointer set to read in the next keyword.
- X.TP 6
- X*menu
- XA struct holding information about the menufile. You need to maintain
- Xthe information for later processing. The Show and Run functions use the
- Xinformation you store here. See struct MenuInfo and struct OptionInfo.
- X.TP 6
- Xgnames
- XThe goto menu names (.GNAME) presently defined (base 0).
- X.TP 6
- Xgfiles
- XThe menufiles associated with the goto names (base 0) (.GNAME).
- X.TP 6
- Xgindex
- XThe number of goto names (.GNAME) presently defined.
- X.TP 6
- Xopnumber
- XThe last option number. This is the number that will appear to the left
- Xof the option, and the number the user will type in to select the option.
- XYou should increment this for the next option if your keyword will
- Xcontain a option number.
- XThe option number should be set to zero for options you don't want a
- Xnumber to appear to the left of the option.
- X.nf
- X.RE
- X
- X/*
- X** Menu structure layout
- X*/
- Xstruct MenuInfo
- X{
- X char name [15]; /* file name */
- X int wfrow; /* window first row */
- X int wlrow; /* window last row */
- X int wfcol; /* window first col */
- X int wlcol; /* window last col */
- X int row_cursor; /* row for cursor */
- X int col_cursor; /* col for cursor */
- X unsigned boxtype; /* 0 = no box */
- X unsigned linetype; /* same as box */
- X int titlecount;
- X int optioncount; /* base 0 */
- X struct OptionInfo *option [MAXOPTION];
- X struct ScreenInfo *srn [MAXSCREENS+1]; /* .DEFINE_SCREEN */
- X /* NULL = EOL */
- X};
- X
- X
- Xstruct OptionInfo
- X{
- X char keyword [MAXKEYLENGTH+1];
- X int opnumber; /* option number */
- X char description [200];
- X char command [MAXLEN];
- X int row; /* row to display */
- X int col; /* col to display */
- X};
- X
- Xstruct ScreenInfo
- X{
- X char name [30]; /* screen name */
- X char title [100]; /* window title */
- X int toprow; /* upper left corner */
- X int leftcol;
- X int rows; /* # rows in win */
- X int cols; /* # cols in win */
- X unsigned boxtype; /* 0 = no box */
- X int exitlastfield; /* after last field */
- X char helpfile[16];
- X char *fielddefaults; /* init field command */
- X struct FieldInfo *field [MAXFIELDS+1];
- X};
- X
- X
- Xstruct FieldInfo
- X{
- X char name [30]; /* field name */
- X char label [50]; /* field label */
- X int row; /* start position */
- X int col;
- X int length;
- X int min_input;
- X char mask [100];
- X char range [1025];
- X char type;
- X char adjust;
- X int mustenter;
- X char prompt [100];
- X char terminator[3]; /* field terminators */
- X int noinput;
- X};
- X.fi
- X.RE
- X
- X.SS "int (*ShowKey[]) (menu, index)"
- X.nf
- Xstruct MenuInfo *menu;
- Xint index;
- X
- X.fi
- XThe following describes the data passed to all Show functions.
- XArray of pointers to functions that will be called to display
- Xthat option to the screen. Unless you are doing something special
- XShowOption() should do the job.
- X.RS 6
- X.TP 6
- X*menu
- XSee above for description of menu structure.
- X.br
- Xmenu.option[index]->description gets displayed to the screen.
- X.TP 6
- Xindex
- XOption number in menu structure that is to be displayed.
- X
- X.SS "int (*RunKey[]) (menu, opnumber, KeyWord, ParseKey, ShowKey, RunKey, gnames, gfiles, gindex)"
- X.nf
- Xstruct MenuInfo *menu;
- Xint opnumber;
- Xint (*ParseKey[MAXKEYS])();
- Xint (*ShowKey[MAXKEYS])();
- Xint (*RunKey[MAXKEYS])();
- Xchar KeyWord[MAXKEYS][MAXKEYLENGTH];
- Xchar gnames[MAXGNAME][15];
- Xchar gfiles[MAXGNAME][15];
- Xint gindex;
- X.fi
- XThe following describes the data passed to all Run functions.
- XArray of pointers to functions that will be called when the
- Xuser selects the option on the screen.
- X.RS 6
- X.TP 6
- X*option
- XSee above for description of struct OptionInfo.
- X.br
- Xoption->command is what is to be executed for this option.
- X.RE
- X
- X.SS LoadKeys Example:
- X.nf
- XLoadKeys (KeyWord, ParseKey, ShowKey, RunKey)
- X
- X char KeyWord[][10];
- X int (*ParseKey[])(), (*ShowKey[])(), (*RunKey[])();
- X{
- X int ParseTitle(), ParseOption();
- X int ShowOption();
- X int RunSystem();
- X
- X /*
- X ** Section 1:
- X ** Identify the new keyword here.
- X */
- X strcpy (KeyWord[1], ".TITLE");
- X strcpy (KeyWord[2], ".MENU");
- X strcpy (KeyWord[3], ".SYSTEM");
- X
- X /*
- X ** Section 2:
- X ** Identify the parse function for the new keyword.
- X ** Every keyword needs a parse function.
- X */
- X ParseKey[1] = ParseTitle;
- X ParseKey[2] = ParseOption;
- X ParseKey[3] = ParseOption;
- X
- X /*
- X ** Section 3:
- X ** Identify the show function for keywords that are options.
- X ** If ShowKey is set to NULL the option will not be displayed.
- X */
- X ShowKey[1] = NULL; /* Title gets displayed in the parse function */
- X ShowKey[2] = ShowOption;
- X ShowKey[3] = ShowOption;
- X
- X /*
- X ** Section 4:
- X ** Identify the run function for keywords that are options.
- X ** If RunKey is set to NULL the cursor will not stop at
- X ** the option. The user will not be able to select it.
- X */
- X RunKey[1] = NULL; /* You can't select a title */
- X RunKey[2] = RunMenu;
- X RunKey[3] = RunSystem;
- X}
- X.fi
- X
- X
- X
- X
- X.PP
- XTHE END (whew)
- SHAR_EOF
- echo "File menu.1 is complete"
- chmod 0644 menu.1 || echo "restore of menu.1 fails"
- echo "x - extracting Main.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > Main.c &&
- Xstatic char Sccsid[] = "%W% DeltaDate %G% ExtrDate %H%";
- X/* PROGRAM Menu (generic)
- X** AUTHOR Paul J. Condie
- X** DATE 8/18/86
- X*/
- X
- X#include <curses.h>
- X#include <signal.h>
- X#include "menu.h"
- X
- Xint MAILCALL = FALSE;
- Xint mailrow;
- Xint mailcol;
- Xint debug = FALSE; /* debug flag */
- Xint trapsigs = 1; /* flag - trap ignore signals */
- X
- Xchar KeyWord[MAXKEYS][MAXKEYLENGTH]; /* the keywords */
- Xint (*ShowKey[MAXKEYS])();
- Xstruct MenuInfo menu;
- X
- X
- Xmain (argc, argv)
- X
- X int argc;
- X char *argv[];
- X{
- X FILE *fopen(), *menufile;
- X char *getenv();
- X char *findfile();
- X int shutdown(); /* clean up before exit */
- X int (*ParseKey[MAXKEYS])(),
- X (*RunKey[MAXKEYS])();
- X/*
- X** menuname keeps track of nested submenus.
- X** mptr is the index into menuname 0 = main menu
- X** 1 = sub menu 2 = sub sub menu etc.
- X** menuname[mptr--] = previous menu
- X*/
- X char menuname[MAXMENU][15]; /* filenames */
- X char filename[80];
- X int menuoption[MAXMENU]; /* what option to highlight */
- X int i, exitkey, mptr=0, rc;
- X int j; /* loop variable */
- X char gnames[MAXGNAME][15]; /* goto menu names */
- X char gfiles[MAXGNAME][15]; /* goto file names */
- X int gindex = 0; /* goto index */
- X char *ws;
- X extern int optind;
- X extern char *optarg;
- X int gotorow = 6; /* default goto menu row */
- X int gotocol = 8; /* default goto menu col */
- X int keys = 0; /* show keyboard values */
- X int parse_rc = 0; /* parsedriver return code */
- X
- X
- X
- X while ((rc = getopt (argc, argv, "dp:vk:n:")) != EOF)
- X switch (rc)
- X {
- X case 'd':
- X /* Get debug excited */
- X debug++;
- X break;
- X
- X case 'p':
- X /* Set row and column for ^g */
- X sscanf (optarg, "%d,%d", &gotorow, &gotocol);
- X break;
- X
- X case 'v':
- X /* Show Version */
- X fprintf (stderr, "%s Version %s\n", argv[0], VERSION);
- X exit (0);
- X break;
- X case 'k':
- X /* Show keyboard key values - for .menuinit */
- X keys++;
- X break;
- X case 'n':
- X /* don't trap signals */
- X trapsigs = 0;
- X break;
- X }
- X if (argc == optind && (!keys))
- X {
- X fprintf (stderr,
- X "\nUsage: %s [-v] [-p row,col] [ -keyboard ] menufile\n",
- X argv[0]);
- X exit (1);
- X }
- X if (!keys)
- X sscanf (argv[optind], "%s", menuname[0]);
- X menuoption[0] = 1;
- X
- X if (trapsigs)
- X {
- X signal (SIGINT, SIG_IGN);
- X signal (SIGQUIT, SIG_IGN);
- X }
- X else
- X {
- X signal (SIGINT, shutdown);
- X signal (SIGQUIT, shutdown);
- X }
- X signal (SIGHUP, shutdown);
- X signal (SIGALRM, SIG_IGN); /* to fix bug in curses */
- X
- X /* curses stuff */
- X initscr ();
- X cbreak ();
- X noecho ();
- X nonl ();
- X#ifdef SYS5
- X keypad (stdscr, TRUE);
- X#endif
- X
- X SetTerm (); /* set terminal keyboard */
- X if (keys)
- X {
- X keyboard ();
- X shutdown ();
- X }
- X
- X LoadKeys (KeyWord, ParseKey, ShowKey, RunKey);
- X
- X
- X /*
- X ** Parse, Show and Run each menu selected until exit program.
- X */
- X do
- X {
- X move (0,0);
- X clrtobot (); /* clear screen */
- X
- X /*
- X ** Check the parse return code from the last parse
- X ** to determine what message to display.
- X */
- X switch (parse_rc)
- X {
- X case NOWAYJOSE:
- X BEEP;
- X attrset (A_REVERSE|A_BOLD);
- X mvprintw (ErrRow, 0,
- X "You have not been authorized to run that menu.");
- X attrset (A_NORMAL);
- X break;
- X }
- X
- X initmenu (&menu); /* init menu defaults */
- X
- X /* open menu script file */
- X strcpy (filename, findfile (menuname[mptr], ".",
- X getenv("MENUDIR"), ""));
- X if ((menufile = fopen (filename, "r")) == NULL)
- X {
- X BEEP;
- X mvprintw (20, 0, "Unable to locate (%s) file.",
- X menuname[mptr]);
- X shutdown ();
- X }
- X
- X
- X /*
- X ** Return Codes from parsedriver:
- X ** NOWAYJOSE - not authorized for this menu.
- X */
- X parse_rc = parsedriver (menufile, KeyWord, ParseKey, &menu,
- X gnames, gfiles, &gindex);
- X fclose (menufile);
- X
- X switch (parse_rc)
- X {
- X case 0:
- X /* success */
- X break;
- X
- X case QUIT:
- X shutdown ();
- X break;
- X
- X case MAINMENU:
- X /* not tested */
- X mptr = 0;
- X break;
- X
- X default:
- X if (mptr > 0)
- X {
- X mptr--; /* return to previous menu */
- X continue;
- X }
- X else
- X {
- X BEEP;
- X attrset (A_REVERSE|A_BOLD);
- X mvprintw (ErrRow, 0,
- X "You have not been authorized to run that menu.");
- X attrset (A_NORMAL);
- X shutdown (); /* not authorized for main menu */
- X }
- X break;
- X } /* end switch (parse_rc) */
- X
- X /* display menu */
- X showdriver (KeyWord, ShowKey, &menu);
- X
- X /*
- X ** rundriver will return:
- X ** MAINMENU go directly to main menu
- X ** PREVIOUSMENU go to previous menu
- X ** REPARSE reparse & display current menu
- X ** QUIT quit program.
- X ** 0 - 99 option number containing sub menu
- X ** filename.
- X ** GNAMEOFFSET-199 go directly to menu
- X ** gnames[exitkey%GNAMEOFFSET]
- X */
- X exitkey = rundriver (RunKey, ParseKey,
- X &menuoption[mptr], gnames, gfiles, gindex,
- X gotorow, gotocol);
- X if (menu.after_menu != (char *)NULL)
- X RunAftMenu (&menu);
- X
- X
- X
- X switch (exitkey)
- X {
- X case MAINMENU:
- X mptr = 0;
- X break;
- X case PREVIOUSMENU:
- X if (mptr > 0) mptr--;
- X break;
- X case REPARSE:
- X break;
- X case QUIT:
- X break;
- X
- X /*
- X ** A submenu option has been selected or a goto menu.
- X ** exitkey is the option # selected (which is a submenu)
- X ** The submenu filename is in
- X ** menu.option[exitkey]->command
- X */
- X default:
- X if (exitkey >= GNAMEOFFSET) /* goto gname menu */
- X strcpy (menuname[++mptr],
- X gfiles[exitkey % GNAMEOFFSET]);
- X else
- X sscanf (menu.option[exitkey]->command, "%s",
- X menuname[++mptr]);
- X
- X menuoption[mptr] = 1;
- X break;
- X } /* end switch */
- X
- X clean_menu (&menu); /* free menu space */
- X
- X } while (exitkey != QUIT);
- X shutdown ();
- X}
- X
- X
- X
- Xshutdown ()
- X{
- X move (LINES-1, 0);
- X refresh ();
- X endwin ();
- X exit (1);
- X}
- SHAR_EOF
- chmod 0644 Main.c || echo "restore of Main.c fails"
- echo "x - extracting LoadKeys.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > LoadKeys.c &&
- X#ifndef LINT
- Xstatic char Sccsid[] = "%W% DeltaDate %G% ExtrDate %H%";
- X#endif
- X
- X/* FUNCTION: LoadKeys()
- X** Identifies all the recognizable keywords and the
- X** function(s) 2b called to process the keyword.
- X** ARGS: KeyWord array to hold keywords
- X** ParseKey array to hold parse functions
- X** ShowKey array to hold display functions
- X** RunKey array to hold run functions
- X** RETURNS: zilch
- X*/
- X
- X#include "menu.h"
- X
- XLoadKeys (KeyWord, ParseKey, ShowKey, RunKey)
- X
- X char KeyWord[][MAXKEYLENGTH];
- X int (*ParseKey[])(), (*ShowKey[])(), (*RunKey[])();
- X{
- X int ParseTitle(), ParseOption(), ParseBanner(), ParseBox(),
- X ParseLine(), ParseWindow(), ParseComnt(), ParseUnix(),
- X ParseGname(), ParseAuthr(), ParseText(), ParseCursor(),
- X ParseSpace(), ParseDefineScreen(), ParInclude(), ParAssign(),
- X ParAftMenu();
- X int ShowOption();
- X int RunSystem(), RunExit(), RunSetenv(), RunMenu(), RunPopMenu(),
- X RunGetInput();
- X
- X
- X/*
- X** SECTION 1:
- X** Starting with base 1.
- X** Identify keywords to be acted upon when found in your
- X** menu file.
- X** Make sure MAXKEYS is >= the number of entries here.
- X*/
- X
- X strcpy (KeyWord[1], ".TITLE"); /* title line */
- X strcpy (KeyWord[2], ".MENU"); /* submenu option */
- X strcpy (KeyWord[3], ".SYSTEM"); /* system call option */
- X strcpy (KeyWord[4], ".BOX"); /* encase menu in a box */
- X strcpy (KeyWord[5], ".BANNER"); /* welcome banner screen */
- X strcpy (KeyWord[6], ".LINE"); /* line between title & options */
- X strcpy (KeyWord[7], ".WINDOW"); /* window area for options */
- X strcpy (KeyWord[8], "###"); /* comment line */
- X strcpy (KeyWord[9], ".UNIX"); /* unix command line */
- X strcpy (KeyWord[10], ".GNAME"); /* menu name (used in goto menu) */
- X strcpy (KeyWord[11], ".AUTHORIZE"); /* login's authorized to run menu */
- X strcpy (KeyWord[12], ".TEXT"); /* display text at row and column */
- X strcpy (KeyWord[13], ".CURSOR"); /* where to put the cursor */
- X strcpy (KeyWord[14], ".EXIT"); /* exit menu program */
- X strcpy (KeyWord[15], ".SETENV"); /* set enviroment variable */
- X strcpy (KeyWord[16], ".SPACE"); /* put a space between options */
- X strcpy (KeyWord[17], ".POPMENU"); /* pop menu option */
- X strcpy (KeyWord[18], ".DEFINE_SCREEN");/* define a prompt screen */
- X strcpy (KeyWord[19], ".GETINPUT"); /* prompt screen */
- X strcpy (KeyWord[20], ".INCLUDE"); /* include a menu file */
- X strcpy (KeyWord[21], "*=*"); /* assignment - variable=value */
- X strcpy (KeyWord[22], ".AFTER_MENU"); /* command to run after menu */
- X
- X strcpy (KeyWord[23], ""); /* END OF LIST */
- X
- X
- X/*
- X** SECTION 2:
- X** Starting with base 1.
- X** Identify function names to correspond with above keywords.
- X** These functions describe what is to be done when above keyword
- X** is found while parsing the "menu file".
- X** Every keyword needs a Parse??? function.
- X*/
- X
- X ParseKey[1] = ParseTitle;
- X ParseKey[2] = ParseOption;
- X ParseKey[3] = ParseOption;
- X ParseKey[4] = ParseBox;
- X ParseKey[5] = ParseBanner;
- X ParseKey[6] = ParseLine;
- X ParseKey[7] = ParseWindow;
- X ParseKey[8] = ParseComnt;
- X ParseKey[9] = ParseUnix;
- X ParseKey[10] = ParseGname;
- X ParseKey[11] = ParseAuthr;
- X ParseKey[12] = ParseText;
- X ParseKey[13] = ParseCursor;
- X ParseKey[14] = ParseOption;
- X ParseKey[15] = ParseOption;
- X ParseKey[16] = ParseSpace;
- X ParseKey[17] = ParseOption;
- X ParseKey[18] = ParseDefineScreen;
- X ParseKey[19] = ParseOption;
- X ParseKey[20] = ParInclude;
- X ParseKey[21] = ParAssign;
- X ParseKey[22] = ParAftMenu;
- X
- X
- X/*
- X** SECTION 3:
- X** These functions describe what is to be done to display the
- X** option to the screen. The option you loaded into OptionInfo.
- X** If set to NULL then the option is not displayed.
- X*/
- X
- X ShowKey[1] = NULL;
- X ShowKey[2] = ShowOption;
- X ShowKey[3] = ShowOption;
- X ShowKey[4] = NULL;
- X ShowKey[5] = NULL;
- X ShowKey[6] = NULL;
- X ShowKey[7] = NULL;
- X ShowKey[8] = NULL;
- X ShowKey[9] = NULL;
- X ShowKey[10] = NULL;
- X ShowKey[11] = NULL;
- X ShowKey[12] = NULL;
- X ShowKey[13] = NULL;
- X ShowKey[14] = ShowOption;
- X ShowKey[15] = ShowOption;
- X ShowKey[16] = NULL;
- X ShowKey[17] = ShowOption;
- X ShowKey[18] = NULL;
- X ShowKey[19] = ShowOption;
- X ShowKey[20] = NULL;
- X ShowKey[21] = NULL;
- X ShowKey[22] = NULL;
- X
- X
- X/*
- X** SECTION 4:
- X** These functions explain what you want done when the user
- X** selects the option on the screen with the corresponding
- X** keyword.
- X** If set to NULL the keyword becomes unselectable.
- X*/
- X
- X RunKey[1] = NULL;
- X RunKey[2] = RunMenu;
- X RunKey[3] = RunSystem;
- X RunKey[4] = NULL;
- X RunKey[5] = NULL;
- X RunKey[6] = NULL;
- X RunKey[7] = NULL;
- X RunKey[8] = NULL;
- X RunKey[9] = NULL;
- X RunKey[10] = NULL;
- X RunKey[11] = NULL;
- X RunKey[12] = NULL;
- X RunKey[13] = NULL;
- X RunKey[14] = RunExit;
- X RunKey[15] = RunSetenv;
- X RunKey[16] = NULL;
- X RunKey[17] = RunPopMenu;
- X RunKey[18] = NULL;
- X RunKey[19] = RunGetInput;
- X RunKey[20] = NULL;
- X RunKey[21] = NULL;
- X RunKey[22] = NULL;
- X}
- SHAR_EOF
- chmod 0644 LoadKeys.c || echo "restore of LoadKeys.c fails"
- echo "x - extracting parsedrive.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > parsedrive.c &&
- Xstatic char Sccsid[] = "@(#)parsedrive.c 1.5 DeltaDate 1/22/90 ExtrDate 1/22/90";
- X
- X/* FUNCTION: parsedriver()
- X** This is the driver routine in parseing the menu
- X** file. This function calls the appropriate parse
- X** function for that keyword.
- X** ARGS: keyword the keyword "AUTHORIZE"
- X** menufile the unix menu file
- X** menu menu structure
- X** gnames holder of goto menu names
- X** gfiles holder of goto menu names (menu file)
- X** gindex # of gnames
- X** RETURNS: 0 success
- X*/
- X
- X#include <curses.h>
- X#include "menu.h"
- X
- X int swin, ewin, longest;
- X
- Xparsedriver (menufile, KeyWord, ParseKey, menu, gname, gfile, gindex)
- X
- X FILE *menufile;
- X char KeyWord[][MAXKEYLENGTH];
- X int (*ParseKey[])();
- X struct MenuInfo *menu;
- X char gname[][15], gfile[][15];
- X int *gindex;
- X{
- X char keyword[80];
- X int rcde, I, KEYFOUND;
- X int opnumber = 0; /* last option number */
- X
- X
- X /* Set default .WINDOW area */
- X menu->wfcol = 0;
- X menu->wlcol = COLS-1;
- X menu->wfrow = 0;
- X menu->wlrow = LINES-1;
- X menu->titlecount = 0;
- X menu->optioncount = 0;
- X swin = ewin = longest = 0;
- X
- X /* loop through each keyword */
- X rcde = fscanf (menufile, "%s", keyword);
- X while (rcde != EOF)
- X {
- X if (strlen (keyword) >= 80-2)
- X {
- X BEEP;
- X mvprintw (ErrRow-2, 0,
- X "Your keyword <%s> is toooo looong. Max = %d",
- X keyword, 80-2);
- X shutdown ();
- X }
- X /*
- X ** Check if we found a defined keyword
- X */
- X KEYFOUND = FALSE;
- X for (I = 1; I <= MAXKEYS; I++)
- X {
- X /*
- X if (strcmp (keyword, KeyWord[I]) == 0)
- X */
- X if (strmatch (keyword, KeyWord[I]))
- X {
- X KEYFOUND = TRUE;
- X if (ParseKey[I] != NULL)
- X {
- X rcde = (*ParseKey[I]) (keyword,
- X menufile, menu, KeyWord,
- X ParseKey, gname, gfile, gindex,
- X &opnumber);
- X /*
- X ** The return code from each parse
- X ** function must be 0 in order to
- X ** continue.
- X */
- X if (rcde != 0) return (rcde);
- X }
- X break;
- X }
- X }
- X if (!KEYFOUND)
- X {
- X BEEP;
- X mvprintw (ErrRow-2, 0, "ERROR: (%s) Key not found.",
- X keyword);
- X shutdown ();
- X }
- X rcde = fscanf (menufile, "%s", keyword);
- X }
- X
- X EndWindow (menu);
- X return (0);
- X}
- SHAR_EOF
- chmod 0444 parsedrive.c || echo "restore of parsedrive.c fails"
- echo "x - extracting showdriver.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > showdriver.c &&
- Xstatic char Sccsid[] = "@(#)showdriver.c 1.2 DeltaDate 10/16/88 ExtrDate 1/22/90";
- X
- X/* FUNCTION: showdriver()
- X** The driver module to initially display the options
- X** to the screen.
- X** ARGS: keyword the keyword found
- X** ShowKey show functions
- X** menu menu structure
- X** RETURNS: none
- X*/
- X
- X#include <curses.h>
- X#include "menu.h"
- X
- X
- Xshowdriver (KeyWord, ShowKey, menu)
- X
- X char KeyWord[][MAXKEYLENGTH];
- X int (*ShowKey[])();
- X struct MenuInfo *menu;
- X{
- X int i, j;
- X
- X
- X
- X /*
- X ** Loop through options and call apropriate function.
- X */
- X
- X for (i = 0; i < menu->optioncount; i++)
- X for (j = 1; j <= MAXKEYS; j++)
- X if (strcmp (menu->option[i]->keyword, KeyWord[j]) == 0)
- X {
- X if (ShowKey[j] != NULL)
- X (*ShowKey[j]) (menu, i);
- X break;
- X }
- X refresh ();
- X}
- SHAR_EOF
- chmod 0444 showdriver.c || echo "restore of showdriver.c fails"
- echo "x - extracting rundriver.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > rundriver.c &&
- Xstatic char Sccsid[] = "%W% DeltaDate %G% ExtrDate %H%";
- X
- X/* FUNCTION: rundriver()
- X** The driver module to run each selectable option.
- X** Runmenu will call the appropriate run function
- X** for that keyword.
- X** ARGS: keyword the keyword "AUTHORIZE"
- X** menufile the unix menu file
- X** menu menu structure
- X** gnames holder of goto menu names
- X** gfiles holder of goto menu names (menu file)
- X** gindex # of gnames
- X** RETURNS: QUIT exit pgm
- X** MAIN go to main menu
- X** PREVIOUS go to previous menu
- X** index to submenu
- X*/
- X
- X#include <curses.h>
- X#include <signal.h>
- X#include "menu.h"
- X#include "terminal.h"
- X
- X#define INITMENU 0
- X#define GOTOMENU 1
- X
- Xextern int MAILCALL;
- Xextern int trapsigs;
- Xextern int debug;
- X
- Xextern struct MenuInfo menu;
- Xint tmpoption;
- Xint ckik; /* current keyword in KeyWord */
- Xextern int (*ShowKey[])();
- Xextern char KeyWord[][MAXKEYLENGTH];
- X
- X
- Xrundriver (RunKey, ParseKey, option, gnames,
- X gfiles, gindex, gotorow, gotocol)
- X
- X int (*RunKey[])(), *option;
- X int (*ParseKey[])();
- X char gnames[][15], gfiles[][15];
- X int gindex;
- X int gotorow;
- X int gotocol;
- X{
- X FILE *fopen(), *fp;
- X char *findfile();
- X char *upper();
- X int shutdown();
- X char select[78], command[MAXLEN];
- X char matchstr[60];
- X int exitkey, index;
- X int i, j;
- X int lastopnumber = 0; /* last option # */
- X int MATCHED; /* char match flag */
- X int ch;
- X
- X
- X
- X /*
- X ** What is the last option number ?
- X */
- X for (i = menu.optioncount-1; i >= 0; i--)
- X if (menu.option[i]->opnumber != 0)
- X {
- X lastopnumber = menu.option[i]->opnumber;
- X break;
- X }
- X
- X if (lastopnumber <= 0) return (QUIT); /* no options */
- X select[0] = '\0';
- X matchstr[0] = '\0';
- X
- X /*
- X ** Loop through options untill user exits menu or selects
- X ** another menu.
- X */
- X for (;;)
- X {
- X#ifndef ALARM
- X if (MAILCALL)
- X checkmail ();
- X#endif
- X
- X /* highlight current option */
- X for (ckik = 1; ckik <= MAXKEYS && KeyWord[ckik] != NULL;
- X ckik++)
- X if (strcmp (menu.option[*option-1]->keyword,
- X KeyWord[ckik]) == 0)
- X {
- X if (ShowKey[ckik] != NULL)
- X {
- X /* display option */
- X (*ShowKey[ckik]) (&menu, (*option)-1);
- X mvaddch (menu.option[(*option)-1]->row,
- X menu.option[(*option)-1]->col-1,
- X ' ');
- X /*
- X ** turn on reverse video
- X ** maintaining current attributes
- X */
- X exitkey = slength(menu.option[(*option)-1]->description) + menu.option[(*option)-1]->col + 5;
- X for (j = menu.option[(*option)-1]->col-1; j <= exitkey; j++)
- X {
- X ch = mvinch (menu.option[(*option)-1]->row, j);
- X ch |= A_REVERSE;
- X mvaddch (menu.option[(*option)-1]->row, j, ch);
- X }
- X
- X }
- X break;
- X }
- X
- X#ifdef BSD
- X standend ();
- X#else
- X attrset (A_NORMAL);
- X#endif
- X
- X tmpoption = *option;
- X if (RunKey[ckik] != NULL)
- X exitkey = GetOption (menu.row_cursor, menu.col_cursor,
- X select);
- X else
- X /* so we don't go in a loop */
- X exitkey = (exitkey == KEY_UP ||
- X exitkey == KeyUp) ? KEY_UP : KEY_DOWN;
- X *option = tmpoption;
- X
- X if (exitkey == KeyDown) exitkey = KEY_DOWN;
- X if (exitkey == KeyUp) exitkey = KEY_UP;
- X if (exitkey == KeyTab) exitkey = KEY_TAB;
- X if (exitkey == KeyBTab) exitkey = KEY_BTAB;
- X if (exitkey == KeyReturn) exitkey = KEY_RETURN;
- X if (exitkey == KeyMainMenu) exitkey = KEY_MAINMENU;
- X if (exitkey == KeyPrevMenu) exitkey = KEY_PREVMENU;
- X if (exitkey == KeyExitMenu) exitkey = KEY_EXITMENU;
- X if (exitkey == KeyGname) exitkey = KEY_GNAME;
- X
- X /* unhighlight current option */
- X if (ShowKey[ckik] != NULL)
- X {
- X mvaddch (menu.option[(*option)-1]->row,
- X menu.option[(*option)-1]->col-1, ' ');
- X strcat (menu.option[(*option)-1]->description, " ");
- X (*ShowKey[ckik]) (&menu, *option-1);
- X menu.option[(*option)-1]->description[strlen(menu.option[(*option)-1]->description)-1] = '\0';
- X }
- X
- X
- X switch (exitkey)
- X {
- X case KEY_DOWN:
- X case 'j':
- X *option = (*option) >= menu.optioncount
- X ? 1 : ++(*option);
- X break;
- X
- X case KEY_UP:
- X case 'k':
- X *option = (*option) <= 1
- X ? menu.optioncount : --(*option);
- X break;
- X
- X case KEY_TAB:
- X /* A tab will hop forward four options at a time. */
- X if (menu.optioncount > 4)
- X {
- X *option += 4;
- X if (*option > menu.optioncount)
- X *option = 1 + *option -
- X menu.optioncount - 1;
- X }
- X else
- X *option = *option >= menu.optioncount ? 1 :
- SHAR_EOF
- echo "End of part 3"
- echo "File rundriver.c is continued in part 4"
- echo "4" > s2_seq_.tmp
- exit 0
-