home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2408 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  39.2 KB

  1. From: pjc@pcbox.UUCP (Paul J. Condie)
  2. Newsgroups: alt.sources
  3. Subject: menu(1) part 3 of 14
  4. Message-ID: <437@pcbox.UUCP>
  5. Date: 26 Dec 90 20:05:20 GMT
  6.  
  7.  
  8. #!/bin/sh
  9. # this is part 3 of a multipart archive
  10. # do not concatenate these parts, unpack them in order with /bin/sh
  11. # file menu.1 continued
  12. #
  13. CurArch=3
  14. if test ! -r s2_seq_.tmp
  15. then echo "Please unpack part 1 first!"
  16.      exit 1; fi
  17. ( read Scheck
  18.   if test "$Scheck" != $CurArch
  19.   then echo "Please unpack part $Scheck next!"
  20.        exit 1;
  21.   else exit 0; fi
  22. ) < s2_seq_.tmp || exit 1
  23. echo "x - Continuing file menu.1"
  24. sed 's/^X//' << 'SHAR_EOF' >> menu.1
  25. X     KEY_CANCEL = 27    # (esc)  Cancel all input from a GETINPUT screen or cancel a pop-up menu selection.
  26. X                       Exit a help screen.
  27. X     KEY_SAVE = 6    # (^f)  Save a GETINPUT screen to a file.
  28. X     KEY_PRINT = 16    # (^p)  Print a GETINPUT screen to lp.
  29. X.fi
  30. X
  31. X.SH EXAMPLE menufile
  32. X.nf
  33. X\fB###\fR     This is a example of a menu script file.
  34. X
  35. X\fB .AUTHORIZE\fR  pjc nortons boink mozart
  36. X
  37. X\fB###\fR    Initialize function keys for TERM=5425
  38. X\fB .UNIX\fR  echo "\\033[1;2;0;0q  HELP          h\\r\\c"
  39. X
  40. X\fB###\fR    Define goto menu names.
  41. X\fB .GNAME\fR  main  main.m
  42. X\fB .GNAME\fR  reports  reports.m
  43. X
  44. X\fB###\fR     Title Lines Section.
  45. X\fB .TITLE\fR
  46. X  Version 3.00...\\RPACIFIC * BELL\\N...$DATE
  47. X\fB .TITLE\fR
  48. X $MAIL...Sample Menu...\\S$TIME\\N
  49. X\fB .TITLE\fR
  50. X ...MAIN MENU...
  51. X\fB .LINE\fR
  52. X
  53. X\fB###\fR     Left column of screen - Options
  54. X\fB .WINDOW\fR 0 23 0 39
  55. X\fB .SYSTEM\fR who
  56. XList who is on the system.
  57. X\fB .SYSTEM\fR ps -ef; \\
  58. X    echo "Press [ Return ] to continue.\\c"; read reply
  59. XPrint process status table.
  60. X
  61. X\fB###\fR     Right column of screen - Options
  62. X\fB .WINDOW\fR 0 23 40 79 \\R SUB MENU \\N
  63. X\fB .MENU\fR reports.m
  64. XGo to report menu.
  65. X
  66. X\fB .TEXT\fP 22 50
  67. XSelection [ ? for help ]
  68. X.fi
  69. X
  70. X.SH GENERALLY ACCEPTED GUIDELINES
  71. X.PD 0.1
  72. X.IP -> 3
  73. XPut a meaningful title on the top of every menu.
  74. X.IP -> 3
  75. XProvide symmetric balance by centering the title and the menu options
  76. Xaround the center axis of the screen.
  77. X.IP -> 3
  78. XChoose an organizing principle for the menu options.
  79. XOrganize menu hierarchies according to the tasks users will perform, rather
  80. Xthan the structure of the software modules.
  81. X.br
  82. XHints in organizing options:
  83. X.RS 6
  84. X.IP * 3
  85. XChronological ordering
  86. X.IP * 3
  87. XAscending or descending numerical ordering
  88. X.IP * 3
  89. XItems grouped by physical properties, (Increasing volume, weight or temperature)
  90. X.IP * 3
  91. XAlphabetic sequence of terms
  92. X.IP * 3
  93. XGrouping of related options with spatial demarcation between groups
  94. X.IP * 3
  95. XMost frequently used options first
  96. X.IP * 3
  97. XMost important options first
  98. X.RE
  99. X.IP -> 3
  100. XTo facilitate scanning, put blank lines between logical groupings of menu
  101. Xoptions and after about every fifth option in a long list.
  102. X.IP -> 3
  103. XLimit the number of menu choices of one screen.
  104. XThe breadth (number of options per menu) should be no more than eight and the
  105. Xdepth (number of levels of menus) should be no more than four.
  106. X.IP -> 3
  107. XUse words for your menu options that clearly and specifically describe 
  108. Xwhat the user is selecting; use simple, active verbs to describe menu options.
  109. XUse common, short English words that clearly describe the action that the 
  110. Xcommand will carry out; choose words that are distinctive from one another.
  111. X.IP -> 3
  112. XDisplay the menu options in mixed, upper and lower case letters.
  113. X.IP -> 3
  114. XBe sure that any function keys that you use will operate correctly on all of
  115. Xthe different types of keyboards the users have.
  116. X.IP -> 3
  117. XBe consistent in the use of menu formats, procedures, and wording; the 
  118. Xmapping of keys to functions; the naming of menu options.
  119. X.IP -> 3
  120. XOptions should suggest or entail closure.  If a menu option calls another
  121. Xmenu (.MENU) the option description should be the title of the called menu
  122. Xto provide continuity.  Likewise, if a menu option calls a program (reports,
  123. Xscreens) the option description should be the title of the report/screen.
  124. X.IP -> 3
  125. XDisplay only information that the user needs to know.
  126. X.IP -> 3
  127. XEvery menu should indicate how to exit from the screen.
  128. X.IP -> 3
  129. XAvoid hyphenation of words between lines.
  130. X.IP -> 3
  131. XUse abbreviation and acronyms only when they are significantly shorter than
  132. Xthe full text and when they will be understood by the user.
  133. X.IP -> 3
  134. XOptions in a multiple column list should be organized in vertical columns
  135. Xwhich are read from left to right on the screen.
  136. X.IP -> 3
  137. XPut a least two spaces between the longest item in a column and the beginning
  138. Xof the next column.
  139. X.IP -> 3
  140. XUse highlighting to emphasize important information only.  Do not overuse
  141. Xit.
  142. X.IP -> 3
  143. XA \fI.POPMENU\fP, if possible, should appear as close to and to the right 
  144. Xof the option that selected it.  Probably a \fI.GETINPUT\fP screen should also.
  145. X.PD
  146. X
  147. X.SS References
  148. XHuman Factors Engineering, User Interface Guidelines, Pacific Bell, Sept (1987)
  149. X.PP
  150. XShore, John, The Sachertorte Algorithm and Other Antidotes to Computer
  151. XAnxiety, Viking Penguid Inc. (1985)
  152. X.IP * 3
  153. XShore's book for the general public which translates into why designing 
  154. Xgood user interfaces are necessary.
  155. X.PP
  156. XBeer, S. and Schoefer, W., Screen Development Guidelines - Draft,
  157. XVersion 1.0, Pacific Bell, April (1987)
  158. X.PP
  159. XRubinstein R., and Hersch H.M., with Ledgard, H.F., The Human Factor:
  160. XDesigning Computer Systems for People.  Digital Press, Digital Equipment
  161. XCorporation, (1984).
  162. X.IP * 3
  163. XRubinstein's work is very interesting and original.  The text is readable
  164. Xand the ideas presented are clear and attractive.  This is not a text book.
  165. X.PP
  166. XFuture Technology Architecture District, Proposed Pacific*Bell Screen 
  167. XStandards For NonProgrammable Terminals,  Pacific Bell, May (1988)
  168. X.PP
  169. XDumas Joseph S., Designing User Interface for Software, Prentice Hall, 1988
  170. X
  171. X.SH CREDITS
  172. XPaul J. Condie        8/18/86    original author
  173. X.br
  174. X{att,bellcore,sun,ames,pyramid}!pacbell!pcbox!pjc
  175. X.br
  176. X
  177. XIrving Griesman            GetInput(3X).
  178. X.br
  179. XSam S. Lok            popmenu(3) enhancements, runrealid(3).
  180. X
  181. X.SH NOTE
  182. XIf memory size is important modify LoadKeys.c and remove all references
  183. Xto keywords your application does not use then relink.  This will reduce
  184. Xthe size of menu.
  185. X
  186. X.SH FILES
  187. Xmenu.hlp    -  menu help file
  188. X.br
  189. X/usr/local/lib/menus    - some menus you might want to use or look at.
  190. X.br
  191. X/usr/local/lib/menus/sample.m    -  a sample menu file
  192. X.br
  193. X/usr/local/lib/menus/printers.m    -  printers pop-up menu
  194. X.br
  195. X/usr/local/lib/menus/reportsrn.m    -  report option input screen
  196. X.br
  197. X/usr/lib/acct/holidays        - holidays file.
  198. X
  199. XThe library of menus may vary from machine to machine.
  200. X
  201. X.SH SEE ALSO
  202. XMenuAccess(1), curses(3X), system(3), mail(1), getenv(3), 
  203. Xlock(1), unlock(1), GetInput(3X), checkpass(1), runrealid(1), MenuMsg(1),
  204. XMenuPrompt(1).
  205. X
  206. X.SH WARNING
  207. XBecause menu uses the environment to pass and save data you are limited on the
  208. Xvolume of data you can have based upon the size of your environment.  
  209. XThis will vary from machine to machine.  If you see the 
  210. Xmessage "Unable to allocate environment memory..." then you have reached
  211. Xyour limit.  Actually you've surpassed the limit or you wouldn't have
  212. Xgotten the message.  But lets not squabble.
  213. X
  214. XMenu has very little intelligence built in to check if you exceed the bounds
  215. Xof any fields.  If menu core dumps, especially with a bus error, you are
  216. Xprobably trying to load too large a value into a field.
  217. X
  218. X.SH BUGS
  219. XCurses bug - When a attribute is the last character on the line (spaces don't 
  220. Xcount) the attributes do not get turned off until it hits the next character 
  221. Xon the next line.
  222. X
  223. X.PP
  224. XWhen you use the mail notification $MAIL the alarms get buffered up when
  225. Xthe cursor is just sitting there, so, as soon as the user types something
  226. Xat the keyboard all the alarms that were buffered take off, which means, you
  227. Xget a beep...beep...beep...beep.  This doesn't happen on AT&T 3b machines
  228. Xbut I've noticed it on SUNS and ARETE machines.
  229. XYou should take the -DALARM off the CFLAGS in the makefile which tells
  230. Xmenu not to use the alarm(2) to check for mail, but check when a key
  231. Xhas been pressed.
  232. X
  233. X.PP
  234. XMenu has not really been tested on terminals/windows that is not 24x80,
  235. Xok,ok... it hasn't been tested at all.  For the most part it should work
  236. Xfine, EXCEPT (you knew that was coming), when you want to create columns
  237. Xof options using the .WINDOW keyword.  The parameters to .WINDOW are
  238. Xabsolute therefore when you line up your columns for a 24x80 terminal and
  239. Xyour menu is run on say a 34x132 terminal your columns will not be
  240. Xcentered right.  Probably a new keyword should be introduced ".COLUMN"
  241. Xwhich would have some intelligence built in to try to center columns within
  242. Xthe window space.  It might have some problems going from a larger window
  243. Xto a smaller window if the columns won't fit.
  244. X.br
  245. XAnyone volunteer to write this one?
  246. X
  247. X.PP
  248. XTerminal attributes sometimes don't work right.  Especially when putting
  249. Xmultiple attributes on one line.  In all cases I've seen it is a restriction
  250. Xof the terminal (hardware).
  251. X
  252. X.bp
  253. X.SH PROGRAMMING NOTES
  254. XThis section is for those of you who want to or need to add new keywords.
  255. X.PP
  256. XThe keywords that have been provided should accommodate most
  257. Xapplication menus, however, if customization is needed the following
  258. Xmay come in handy.  If you introduce any neat new keywords (say like 
  259. X".IF THEN ELSE") I would
  260. Xappreciate you sending them to me so I can incorporate them.  Send your
  261. XParse, Show, and Run functions along with a copy of \fILoadKeys.c\fP.
  262. X.PP
  263. XMenu is primarily driven from the LoadKeys.c module.  This 
  264. Xmodule describes to menu what keywords it needs to scan for and what
  265. Xaction to take when found.
  266. XThere are four sections in LoadKeys (see LoadKeys example) each of which 
  267. Xneed to be
  268. Xdefined if you are introducing a new keyword.  LoadKkeys provides three areas
  269. Xof control (sections 2,3,4), and it is important that you know what you
  270. Xwant to accomplish at each control point:
  271. X.TP 4
  272. XParse
  273. XWhat do you want menu to do with your keyword once it has found it during
  274. Xthe parsing routine?  Any data you need to store for a later step, etc..
  275. X.TP 4
  276. XShow
  277. XHow do you want your keyword displayed to the screen?  Define as NULL if
  278. Xnot appropriate.
  279. X.TP 4
  280. XRun
  281. XIf the user selects an option that is your keyword, what do you want done?
  282. X
  283. X.PP
  284. XIf you want to put debugging code in your functions then the following
  285. Xformat should be used.
  286. X.nf
  287. Xextern int  debug;
  288. X    if (debug)
  289. X    {
  290. X        fprintf (stderr, "\n[%s] <%s> ...", __FILE__,
  291. X            menu->option[opnumber]->keyword, ...);
  292. X        fflush (stderr);
  293. X    }
  294. X.fi
  295. Xwhere [Function] is the function name and <KeyWord> is the keyword being
  296. Xprocessed.
  297. X
  298. X.SS ADDING A NEW KEYWORD
  299. X.TP 8
  300. XStep 1:
  301. XDecide on the name of the new keyword.  For consistency sake, I suggest, it
  302. Xshould begin with a "." and be all in caps.  Maximum length of keyword is
  303. XMAXKEYLENGTH (15).  Then formulate a syntax for the keyword (what the user
  304. Xneeds to type in the menufile).
  305. X.br
  306. XAlso, get clear in your mind what you want done at each of the three control
  307. Xpoints.
  308. X
  309. X.TP 8
  310. XStep 2:
  311. Xvi LoadKeys.c
  312. X.br
  313. XStrcpy your keyword into the next available slot in KeyWord[], under SECTION 1.
  314. XMake sure MAXKEYS in menu.h is >= the slot you strcpy'ied your keyword into.
  315. XSee KeyWord[] below.
  316. X
  317. X.TP 8
  318. XStep 3:
  319. XIn SECTION 2 of LoadKeys.c assign the Parse function that is going 
  320. Xto parse your keyword.
  321. XIt should be assigned to the same slot as in SECTION 1.  First see if one
  322. Xof the Parse functions already written will do the job.  If so use that one,
  323. Xif not you will have to write one.  For consistency call it Parse????.c or
  324. XPar????.c, and declare it at the beginning of LoadKeys.c.
  325. XAll keywords must have a parse function.
  326. XThis function is called immediately when your keyword is found while parsing
  327. Xthe menufile.
  328. XSee ParseKey[]() below.
  329. X.br
  330. XReturn Values:
  331. X.RS 8
  332. X.TP 9
  333. X0
  334. XContinue to parse next keyword.
  335. X.TP 9
  336. X-1
  337. XQuit/Exit menu program.
  338. X.TP 9
  339. X-2
  340. XReturn to main menu.
  341. X.TP 9
  342. X-4
  343. XNOWAYJOSE - Not authorized to run this menu.
  344. X.TP
  345. Xanything else
  346. XAbort this menu and return to previous menu.
  347. X.RE
  348. X
  349. X.TP 8
  350. XStep 4:
  351. XIn SECTION 3 of LoadKeys.c assign the Show function (if your keyword is a
  352. Xuser selectable option) that will display the
  353. Xoption to the screen.
  354. XIt should be assigned to the same slot as in SECTION 1.  First see if one
  355. Xof the Show functions already written will do the job.  If so use that one,
  356. Xif not you will have to write one.  For consistency call it Show????.c, and
  357. Xdeclare it at the beginning of LoadKeys.c.
  358. XThis function is called when displaying options to the screen.
  359. XIf you don't need a Show function for your keyword assign slot to NULL.
  360. XSee ShowKey[]() below.
  361. X
  362. X.TP 8
  363. XStep 5:
  364. XIn SECTION 4 of LoadKeys.c assign the Run function (if your keyword is a
  365. Xuser selectable option) that will be called when the user selects this option.
  366. XIt should be assigned to the same slot as in SECTION 1.  First see if one
  367. Xof the Run functions already written will do the job.  If so use that one,
  368. Xif not you will have to write one.  For consistency call it Run????.c, and
  369. Xdeclare it at the beginning of LoadKeys.c.
  370. XIf you don't need a Run function for your keyword assign slot to NULL.
  371. X.br
  372. XReturn Values:
  373. X.RS 8
  374. X.TP 9
  375. X0
  376. XAOK, continue with normal menu processing.
  377. X.TP 9
  378. XMAINMENU
  379. XGoto main menu.  This is as if the user had typed an "M".
  380. X.TP
  381. XPREVIOUSMENU
  382. XGoto previous menu.  This is as if the user had typed a "P".
  383. X.TP
  384. XQUIT
  385. XQuit program.  This is as if the user had typed an "E".
  386. X.TP
  387. XSUBMENU
  388. XIf you are introducing
  389. Xa new submenu keyword (like \fI.MENU\fP) the Run??? function must return 
  390. X(SUBMENU), a #define.
  391. XRefer to \fIRunMenu.c\fP for an example.
  392. X.TP
  393. XGNAMEOFFSET + gindex
  394. XGoto a specific (.GNAME) menu.
  395. XWhere gindex = the index into the gnames array (base 0).
  396. XThis is as if the user had typed a goto menu.
  397. X.RE
  398. X
  399. X.TP 6
  400. XStep 6:
  401. XCompile your new functions, LoadKeys.c  and link into menu.  
  402. XYour KeyWord should work.
  403. XThere should be no need to change any of the existing driver routines 
  404. X(other than LoadKeys.c)?
  405. X
  406. X
  407. X.SS char  KeyWord[]
  408. XThis array identifies all the keywords to be scanned for in your
  409. Xmenufile.  Maximum number of keys is "MAXKEYS" defined in menu.h
  410. Xfile.  Increasing MAXKEYS will allow more keys.
  411. X
  412. X.SS "int (*ParseKey[]) (keyword, menufile, menu, KeyWord, ParseKey, gnames, gfiles, gindex, opnumber)"
  413. X.nf
  414. Xchar        keyword[];
  415. XFILE        *menufile;
  416. Xstruct MenuInfo    *menu;
  417. Xchar        KeyWord[][MAXKEYLENGTH];
  418. Xint        (*ParseKey[])();
  419. Xchar        gnames[][15], gfiles[][15];
  420. Xint        *gindex;
  421. Xint        *opnumber;
  422. X.fi
  423. XArray of pointers to functions that will be called to parse the
  424. Xkeyword when found.  Any processing you want done while program
  425. Xis parsing your keyword should be placed in this function.
  426. XIf you have defined a new keyword you must
  427. Xdescribe how that keyword is to be parsed.  Unless you are doing
  428. Xsomething special ParseOption() should do the job.
  429. XYour new function will need to malloc struct OptionInfo if you
  430. Xwant to store some information for the option.  The following describes
  431. Xthe data passed to all parsing functions.
  432. X.RS 6
  433. X.TP 6
  434. Xkeyword
  435. XThe keyword that was found in menufile.
  436. X.TP 6
  437. X*menufile
  438. XA pointer to your menufile.  When function returns you must leave
  439. Xthe pointer set to read in the next keyword.
  440. X.TP 6
  441. X*menu
  442. XA struct holding information about the menufile.  You need to maintain
  443. Xthe information for later processing. The Show and Run functions use the
  444. Xinformation you store here.  See struct MenuInfo and struct OptionInfo.
  445. X.TP 6
  446. Xgnames
  447. XThe goto menu names (.GNAME) presently defined (base 0).
  448. X.TP 6
  449. Xgfiles
  450. XThe menufiles associated with the goto names (base 0) (.GNAME).
  451. X.TP 6
  452. Xgindex
  453. XThe number of goto names (.GNAME) presently defined.
  454. X.TP 6
  455. Xopnumber
  456. XThe last option number.  This is the number that will appear to the left
  457. Xof the option, and the number the user will type in to select the option.
  458. XYou should increment this for the next option if your keyword will
  459. Xcontain a option number.
  460. XThe option number should be set to zero for options you don't want a
  461. Xnumber to appear to the left of the option.
  462. X.nf
  463. X.RE
  464. X
  465. X/*
  466. X**     Menu structure layout
  467. X*/
  468. Xstruct MenuInfo
  469. X{
  470. X    char            name    [15];        /* file name */
  471. X    int            wfrow;            /* window first row */
  472. X    int            wlrow;            /* window last row */
  473. X    int            wfcol;            /* window first col */
  474. X    int            wlcol;            /* window last col */
  475. X    int            row_cursor;        /* row for cursor */
  476. X    int            col_cursor;        /* col for cursor */
  477. X    unsigned        boxtype;        /* 0 = no box */
  478. X    unsigned        linetype;        /* same as box */
  479. X    int            titlecount;
  480. X    int            optioncount;        /* base 0 */
  481. X    struct OptionInfo    *option    [MAXOPTION];
  482. X    struct ScreenInfo    *srn    [MAXSCREENS+1];    /* .DEFINE_SCREEN */
  483. X                            /* NULL = EOL */
  484. X};
  485. X
  486. X
  487. Xstruct OptionInfo
  488. X{
  489. X    char    keyword        [MAXKEYLENGTH+1];
  490. X    int    opnumber;                /* option number */
  491. X    char    description    [200];
  492. X    char    command        [MAXLEN];
  493. X    int    row;                    /* row to display */
  494. X    int    col;                    /* col to display */
  495. X};
  496. X
  497. Xstruct ScreenInfo
  498. X{
  499. X    char            name    [30];        /* screen name */
  500. X    char            title    [100];        /* window title */
  501. X    int            toprow;            /* upper left corner */
  502. X    int            leftcol;
  503. X    int            rows;            /* # rows in win */
  504. X    int            cols;            /* # cols in win */
  505. X    unsigned        boxtype;        /* 0 = no box */
  506. X    int            exitlastfield;        /* after last field */
  507. X    char            helpfile[16];
  508. X    char            *fielddefaults;        /* init field command */
  509. X    struct FieldInfo    *field    [MAXFIELDS+1];
  510. X};
  511. X
  512. X
  513. Xstruct FieldInfo
  514. X{
  515. X    char    name    [30];                /* field name */
  516. X    char    label    [50];                /* field label */
  517. X    int    row;                    /* start position */
  518. X    int    col;
  519. X    int    length;
  520. X    int    min_input;
  521. X    char    mask    [100];
  522. X    char    range    [1025];
  523. X    char    type;
  524. X    char    adjust;
  525. X    int    mustenter;
  526. X    char    prompt    [100];
  527. X    char    terminator[3];                /* field terminators */
  528. X    int    noinput;
  529. X};
  530. X.fi
  531. X.RE
  532. X
  533. X.SS "int (*ShowKey[]) (menu, index)"
  534. X.nf
  535. Xstruct MenuInfo   *menu;
  536. Xint               index;
  537. X
  538. X.fi
  539. XThe following describes the data passed to all Show functions.
  540. XArray of pointers to functions that will be called to display
  541. Xthat option to the screen.  Unless you are doing something special
  542. XShowOption() should do the job.
  543. X.RS 6
  544. X.TP 6
  545. X*menu
  546. XSee above for description of menu structure.
  547. X.br
  548. Xmenu.option[index]->description gets displayed to the screen.
  549. X.TP 6
  550. Xindex
  551. XOption number in menu structure that is to be displayed.
  552. X
  553. X.SS "int (*RunKey[]) (menu, opnumber, KeyWord, ParseKey, ShowKey, RunKey, gnames, gfiles, gindex)"
  554. X.nf
  555. Xstruct MenuInfo    *menu;
  556. Xint        opnumber;
  557. Xint        (*ParseKey[MAXKEYS])();
  558. Xint        (*ShowKey[MAXKEYS])();
  559. Xint        (*RunKey[MAXKEYS])();
  560. Xchar        KeyWord[MAXKEYS][MAXKEYLENGTH];
  561. Xchar        gnames[MAXGNAME][15];
  562. Xchar        gfiles[MAXGNAME][15];
  563. Xint        gindex;
  564. X.fi
  565. XThe following describes the data passed to all Run functions.
  566. XArray of pointers to functions that will be called when the
  567. Xuser selects the option on the screen.
  568. X.RS 6
  569. X.TP 6
  570. X*option
  571. XSee above for description of struct OptionInfo.
  572. X.br
  573. Xoption->command is what is to be executed for this option.
  574. X.RE
  575. X
  576. X.SS LoadKeys Example:
  577. X.nf
  578. XLoadKeys (KeyWord, ParseKey, ShowKey, RunKey)
  579. X
  580. X    char    KeyWord[][10];
  581. X    int    (*ParseKey[])(), (*ShowKey[])(), (*RunKey[])();
  582. X{
  583. X    int    ParseTitle(), ParseOption();
  584. X    int    ShowOption();
  585. X    int    RunSystem();
  586. X
  587. X    /*
  588. X    **   Section 1:
  589. X    **       Identify the new keyword here.
  590. X    */
  591. X    strcpy (KeyWord[1], ".TITLE");
  592. X    strcpy (KeyWord[2], ".MENU");
  593. X    strcpy (KeyWord[3], ".SYSTEM");
  594. X
  595. X    /*
  596. X    **  Section 2:
  597. X    **    Identify the parse function for the new keyword.
  598. X    **      Every keyword needs a parse function.
  599. X    */
  600. X    ParseKey[1] = ParseTitle;
  601. X    ParseKey[2] = ParseOption;
  602. X    ParseKey[3] = ParseOption;
  603. X
  604. X    /*
  605. X    **  Section 3:
  606. X    **    Identify the show function for keywords that are options.
  607. X    **      If ShowKey is set to NULL the option will not be displayed.
  608. X    */
  609. X    ShowKey[1] = NULL;    /* Title gets displayed in the parse function */
  610. X    ShowKey[2] = ShowOption;
  611. X    ShowKey[3] = ShowOption;
  612. X
  613. X    /*
  614. X    **  Section 4:
  615. X    **    Identify the run function for keywords that are options.
  616. X    **      If RunKey is set to NULL the cursor will not stop at 
  617. X    **      the option.  The user will not be able to select it.
  618. X    */
  619. X    RunKey[1] = NULL;    /* You can't select a title */
  620. X    RunKey[2] = RunMenu;
  621. X    RunKey[3] = RunSystem;
  622. X}
  623. X.fi
  624. X
  625. X
  626. X
  627. X
  628. X.PP
  629. XTHE END     (whew)
  630. SHAR_EOF
  631. echo "File menu.1 is complete"
  632. chmod 0644 menu.1 || echo "restore of menu.1 fails"
  633. echo "x - extracting Main.c (Text)"
  634. sed 's/^X//' << 'SHAR_EOF' > Main.c &&
  635. Xstatic char Sccsid[] = "%W%   DeltaDate %G%   ExtrDate %H%";
  636. X/*    PROGRAM       Menu  (generic)
  637. X**    AUTHOR       Paul J. Condie
  638. X**    DATE       8/18/86
  639. X*/
  640. X
  641. X#include    <curses.h>
  642. X#include    <signal.h>
  643. X#include    "menu.h"
  644. X
  645. Xint    MAILCALL = FALSE;
  646. Xint    mailrow;
  647. Xint    mailcol;
  648. Xint    debug = FALSE;                /* debug flag */
  649. Xint    trapsigs = 1;                /* flag - trap ignore signals */
  650. X
  651. Xchar        KeyWord[MAXKEYS][MAXKEYLENGTH];    /* the keywords */
  652. Xint        (*ShowKey[MAXKEYS])();
  653. Xstruct MenuInfo    menu;
  654. X
  655. X
  656. Xmain (argc, argv)
  657. X
  658. X    int        argc;
  659. X    char        *argv[];
  660. X{
  661. X    FILE        *fopen(), *menufile;
  662. X    char        *getenv();
  663. X    char        *findfile();
  664. X    int        shutdown();        /* clean up before exit */
  665. X    int        (*ParseKey[MAXKEYS])(), 
  666. X            (*RunKey[MAXKEYS])();
  667. X/*
  668. X**    menuname keeps track of nested submenus.
  669. X**    mptr is the index into menuname 0 = main menu
  670. X**                    1 = sub menu 2 = sub sub menu etc.
  671. X**                    menuname[mptr--] = previous menu
  672. X*/
  673. X    char        menuname[MAXMENU][15];            /* filenames  */
  674. X    char        filename[80];
  675. X    int        menuoption[MAXMENU];    /* what option to highlight */
  676. X    int        i, exitkey, mptr=0, rc;
  677. X    int        j;            /* loop variable */
  678. X    char        gnames[MAXGNAME][15];    /* goto menu names */
  679. X    char        gfiles[MAXGNAME][15];    /* goto file names */
  680. X    int        gindex = 0;        /* goto index */
  681. X    char        *ws;
  682. X    extern int    optind;
  683. X    extern char    *optarg;
  684. X    int        gotorow = 6;        /* default goto menu row */
  685. X    int        gotocol = 8;        /* default goto menu col */
  686. X    int        keys = 0;        /* show keyboard values */
  687. X    int        parse_rc = 0;        /* parsedriver return code */
  688. X
  689. X
  690. X
  691. X       while ((rc = getopt (argc, argv, "dp:vk:n:")) != EOF)
  692. X              switch (rc)
  693. X              {
  694. X            case 'd':
  695. X            /* Get debug excited */
  696. X            debug++;
  697. X            break;
  698. X
  699. X            case 'p':
  700. X            /* Set row and column for ^g */
  701. X            sscanf (optarg, "%d,%d", &gotorow, &gotocol);
  702. X            break;
  703. X
  704. X                case 'v':
  705. X            /* Show Version */
  706. X            fprintf (stderr, "%s   Version %s\n", argv[0], VERSION);
  707. X            exit (0);
  708. X            break;
  709. X           case 'k':
  710. X            /* Show keyboard key values - for .menuinit */
  711. X            keys++;
  712. X            break;
  713. X           case 'n':
  714. X            /* don't trap signals */
  715. X            trapsigs = 0;
  716. X            break;
  717. X              }
  718. X       if (argc == optind  &&  (!keys))
  719. X       {
  720. X              fprintf (stderr, 
  721. X               "\nUsage: %s [-v] [-p row,col] [ -keyboard ] menufile\n",
  722. X                argv[0]);
  723. X              exit (1);
  724. X       }
  725. X    if (!keys)
  726. X           sscanf (argv[optind], "%s", menuname[0]);
  727. X       menuoption[0] = 1;
  728. X
  729. X    if (trapsigs)
  730. X    {
  731. X        signal (SIGINT, SIG_IGN);
  732. X        signal (SIGQUIT, SIG_IGN);
  733. X    }
  734. X    else
  735. X    {
  736. X        signal (SIGINT, shutdown);
  737. X        signal (SIGQUIT, shutdown);
  738. X    }
  739. X    signal (SIGHUP, shutdown);
  740. X       signal (SIGALRM, SIG_IGN);        /* to fix bug in curses */
  741. X
  742. X    /* curses stuff */
  743. X       initscr ();
  744. X       cbreak ();
  745. X       noecho ();
  746. X       nonl ();
  747. X#ifdef SYS5
  748. X       keypad (stdscr, TRUE);
  749. X#endif
  750. X
  751. X       SetTerm ();                /* set terminal keyboard */
  752. X    if (keys)
  753. X    {
  754. X        keyboard ();
  755. X        shutdown ();
  756. X    }
  757. X
  758. X       LoadKeys (KeyWord, ParseKey, ShowKey, RunKey);
  759. X
  760. X
  761. X    /*
  762. X    **    Parse, Show and Run each menu selected until exit program.
  763. X    */
  764. X       do
  765. X       {
  766. X              move (0,0);
  767. X              clrtobot ();                /* clear screen */
  768. X
  769. X        /*
  770. X        **  Check the parse return code from the last parse
  771. X        **  to determine what message to display.
  772. X        */
  773. X        switch (parse_rc)
  774. X        {
  775. X           case NOWAYJOSE:
  776. X            BEEP;
  777. X            attrset (A_REVERSE|A_BOLD);
  778. X                  mvprintw (ErrRow, 0, 
  779. X                  "You have not been authorized to run that menu.");
  780. X            attrset (A_NORMAL);
  781. X            break;
  782. X        }
  783. X
  784. X              initmenu (&menu);            /* init menu defaults */
  785. X
  786. X        /* open menu script file */
  787. X        strcpy (filename, findfile (menuname[mptr], ".",
  788. X            getenv("MENUDIR"), ""));
  789. X              if ((menufile = fopen (filename, "r")) == NULL)
  790. X        {
  791. X                    BEEP;
  792. X                    mvprintw (20, 0, "Unable to locate (%s) file.", 
  793. X                    menuname[mptr]);
  794. X                    shutdown ();
  795. X        }
  796. X
  797. X
  798. X        /*
  799. X        **  Return Codes from parsedriver:
  800. X        **    NOWAYJOSE - not authorized for this menu.
  801. X        */
  802. X              parse_rc = parsedriver (menufile, KeyWord, ParseKey, &menu, 
  803. X                gnames, gfiles, &gindex);
  804. X              fclose (menufile);
  805. X
  806. X        switch (parse_rc)
  807. X        {
  808. X           case 0:
  809. X            /* success */
  810. X            break;
  811. X
  812. X           case QUIT:
  813. X            shutdown ();
  814. X            break;
  815. X
  816. X           case MAINMENU:
  817. X            /* not tested */
  818. X            mptr = 0;
  819. X            break;
  820. X
  821. X           default:
  822. X             if (mptr > 0)
  823. X             {
  824. X                    mptr--;        /* return to previous menu */
  825. X                    continue;
  826. X             }
  827. X             else
  828. X            {
  829. X                BEEP;
  830. X                attrset (A_REVERSE|A_BOLD);
  831. X                      mvprintw (ErrRow, 0, 
  832. X                      "You have not been authorized to run that menu.");
  833. X                attrset (A_NORMAL);
  834. X                    shutdown ();  /* not authorized for main menu */
  835. X            }
  836. X            break;
  837. X        } /* end switch (parse_rc) */
  838. X
  839. X        /* display menu */
  840. X              showdriver (KeyWord, ShowKey, &menu);
  841. X
  842. X        /*
  843. X        **  rundriver will return:
  844. X        **    MAINMENU    go directly to main menu
  845. X        **    PREVIOUSMENU    go to previous menu
  846. X        **    REPARSE        reparse & display current menu
  847. X        **    QUIT        quit program.
  848. X        **    0 - 99        option number containing sub menu 
  849. X        **            filename.
  850. X        **    GNAMEOFFSET-199 go directly to menu 
  851. X        **            gnames[exitkey%GNAMEOFFSET]
  852. X        */
  853. X              exitkey = rundriver (RunKey, ParseKey,
  854. X                &menuoption[mptr], gnames, gfiles, gindex,
  855. X                gotorow, gotocol);
  856. X        if (menu.after_menu != (char *)NULL)
  857. X            RunAftMenu (&menu);
  858. X
  859. X
  860. X
  861. X              switch (exitkey)
  862. X              {
  863. X                case MAINMENU:
  864. X            mptr = 0;
  865. X            break;
  866. X                case PREVIOUSMENU:
  867. X            if (mptr > 0)   mptr--;
  868. X            break;
  869. X            case REPARSE:
  870. X            break;
  871. X            case QUIT:
  872. X            break;
  873. X
  874. X            /*
  875. X            ** A submenu option has been selected or a goto menu.
  876. X            ** exitkey is the option # selected (which is a submenu)
  877. X            ** The submenu filename is in 
  878. X            ** menu.option[exitkey]->command
  879. X            */
  880. X                default:
  881. X            if (exitkey >= GNAMEOFFSET)    /* goto gname menu */
  882. X                   strcpy (menuname[++mptr], 
  883. X                    gfiles[exitkey % GNAMEOFFSET]);
  884. X            else
  885. X                   sscanf (menu.option[exitkey]->command, "%s", 
  886. X                       menuname[++mptr]);
  887. X
  888. X            menuoption[mptr] = 1;
  889. X            break;
  890. X              } /* end switch */
  891. X
  892. X        clean_menu (&menu);        /* free menu space */
  893. X
  894. X       } while (exitkey != QUIT);
  895. X       shutdown ();
  896. X}
  897. X
  898. X
  899. X
  900. Xshutdown ()
  901. X{
  902. X   move (LINES-1, 0);
  903. X   refresh ();
  904. X   endwin ();
  905. X   exit (1);
  906. X}
  907. SHAR_EOF
  908. chmod 0644 Main.c || echo "restore of Main.c fails"
  909. echo "x - extracting LoadKeys.c (Text)"
  910. sed 's/^X//' << 'SHAR_EOF' > LoadKeys.c &&
  911. X#ifndef LINT
  912. Xstatic char Sccsid[] = "%W%   DeltaDate %G%   ExtrDate %H%";
  913. X#endif
  914. X
  915. X/*  FUNCTION:    LoadKeys()
  916. X**        Identifies all the recognizable keywords and the
  917. X**        function(s) 2b called to process the keyword.
  918. X**  ARGS:    KeyWord        array to hold keywords
  919. X**        ParseKey    array to hold parse functions
  920. X**        ShowKey        array to hold display functions
  921. X**        RunKey        array to hold run functions
  922. X**  RETURNS:    zilch
  923. X*/
  924. X
  925. X#include        "menu.h"
  926. X
  927. XLoadKeys (KeyWord, ParseKey, ShowKey, RunKey)
  928. X
  929. X    char    KeyWord[][MAXKEYLENGTH];
  930. X    int    (*ParseKey[])(), (*ShowKey[])(), (*RunKey[])();
  931. X{
  932. X    int    ParseTitle(), ParseOption(), ParseBanner(), ParseBox(), 
  933. X        ParseLine(), ParseWindow(), ParseComnt(), ParseUnix(),
  934. X        ParseGname(), ParseAuthr(), ParseText(), ParseCursor(),
  935. X        ParseSpace(), ParseDefineScreen(), ParInclude(), ParAssign(),
  936. X        ParAftMenu();
  937. X    int    ShowOption();
  938. X    int    RunSystem(), RunExit(), RunSetenv(), RunMenu(), RunPopMenu(),
  939. X        RunGetInput();
  940. X
  941. X
  942. X/*
  943. X**    SECTION 1:
  944. X**    Starting with base 1.
  945. X**    Identify keywords to be acted upon when found in your
  946. X**    menu file.
  947. X**    Make sure MAXKEYS is >= the number of entries here.
  948. X*/
  949. X
  950. X   strcpy (KeyWord[1], ".TITLE");    /* title line */
  951. X   strcpy (KeyWord[2], ".MENU");    /* submenu option */
  952. X   strcpy (KeyWord[3], ".SYSTEM");    /* system call option */
  953. X   strcpy (KeyWord[4], ".BOX");      /* encase menu in a box */
  954. X   strcpy (KeyWord[5], ".BANNER");     /* welcome banner screen */
  955. X   strcpy (KeyWord[6], ".LINE");     /* line between title & options */
  956. X   strcpy (KeyWord[7], ".WINDOW");     /* window area for options */
  957. X   strcpy (KeyWord[8], "###");         /* comment line */
  958. X   strcpy (KeyWord[9], ".UNIX");     /* unix command line */
  959. X   strcpy (KeyWord[10], ".GNAME");     /* menu name (used in goto menu) */
  960. X   strcpy (KeyWord[11], ".AUTHORIZE");     /* login's authorized to run menu */
  961. X   strcpy (KeyWord[12], ".TEXT");     /* display text at row and column */
  962. X   strcpy (KeyWord[13], ".CURSOR");     /* where to put the cursor */
  963. X   strcpy (KeyWord[14], ".EXIT");     /* exit menu program */
  964. X   strcpy (KeyWord[15], ".SETENV");     /* set enviroment variable */
  965. X   strcpy (KeyWord[16], ".SPACE");     /* put a space between options */
  966. X   strcpy (KeyWord[17], ".POPMENU");     /* pop menu option */
  967. X   strcpy (KeyWord[18], ".DEFINE_SCREEN");/* define a prompt screen */
  968. X   strcpy (KeyWord[19], ".GETINPUT");    /* prompt screen */
  969. X   strcpy (KeyWord[20], ".INCLUDE");    /* include a menu file */
  970. X   strcpy (KeyWord[21], "*=*");        /* assignment - variable=value */
  971. X   strcpy (KeyWord[22], ".AFTER_MENU");    /* command to run after menu */
  972. X
  973. X   strcpy (KeyWord[23], "");         /* END OF LIST */
  974. X
  975. X
  976. X/*
  977. X**    SECTION 2:
  978. X**    Starting with base 1.
  979. X**    Identify function names to correspond with above keywords.
  980. X**    These functions describe what is to be done when above keyword
  981. X**    is found while parsing the "menu file".
  982. X**    Every keyword needs a Parse??? function.
  983. X*/
  984. X
  985. X   ParseKey[1] = ParseTitle;
  986. X   ParseKey[2] = ParseOption;
  987. X   ParseKey[3] = ParseOption;
  988. X   ParseKey[4] = ParseBox;
  989. X   ParseKey[5] = ParseBanner;
  990. X   ParseKey[6] = ParseLine;
  991. X   ParseKey[7] = ParseWindow;
  992. X   ParseKey[8] = ParseComnt;
  993. X   ParseKey[9] = ParseUnix;
  994. X   ParseKey[10] = ParseGname;
  995. X   ParseKey[11] = ParseAuthr;
  996. X   ParseKey[12] = ParseText;
  997. X   ParseKey[13] = ParseCursor;
  998. X   ParseKey[14] = ParseOption;
  999. X   ParseKey[15] = ParseOption;
  1000. X   ParseKey[16] = ParseSpace;
  1001. X   ParseKey[17] = ParseOption;
  1002. X   ParseKey[18] = ParseDefineScreen;
  1003. X   ParseKey[19] = ParseOption;
  1004. X   ParseKey[20] = ParInclude;
  1005. X   ParseKey[21] = ParAssign;
  1006. X   ParseKey[22] = ParAftMenu;
  1007. X
  1008. X
  1009. X/*
  1010. X**    SECTION 3:
  1011. X**    These functions describe what is to be done to display the
  1012. X**    option to the screen.  The option you loaded into OptionInfo.
  1013. X**    If set to NULL then the option is not displayed.
  1014. X*/
  1015. X
  1016. X   ShowKey[1] = NULL;
  1017. X   ShowKey[2] = ShowOption;
  1018. X   ShowKey[3] = ShowOption;
  1019. X   ShowKey[4] = NULL;
  1020. X   ShowKey[5] = NULL;
  1021. X   ShowKey[6] = NULL;
  1022. X   ShowKey[7] = NULL;
  1023. X   ShowKey[8] = NULL;
  1024. X   ShowKey[9] = NULL;
  1025. X   ShowKey[10] = NULL;
  1026. X   ShowKey[11] = NULL;
  1027. X   ShowKey[12] = NULL;
  1028. X   ShowKey[13] = NULL;
  1029. X   ShowKey[14] = ShowOption;
  1030. X   ShowKey[15] = ShowOption;
  1031. X   ShowKey[16] = NULL;
  1032. X   ShowKey[17] = ShowOption;
  1033. X   ShowKey[18] = NULL;
  1034. X   ShowKey[19] = ShowOption;
  1035. X   ShowKey[20] = NULL;
  1036. X   ShowKey[21] = NULL;
  1037. X   ShowKey[22] = NULL;
  1038. X
  1039. X
  1040. X/*
  1041. X**    SECTION 4:
  1042. X**    These functions explain what you want done when the user
  1043. X**    selects the option on the screen with the corresponding 
  1044. X**    keyword.
  1045. X**    If set to NULL the keyword becomes unselectable.
  1046. X*/
  1047. X
  1048. X   RunKey[1] = NULL;
  1049. X   RunKey[2] = RunMenu;
  1050. X   RunKey[3] = RunSystem;
  1051. X   RunKey[4] = NULL;
  1052. X   RunKey[5] = NULL;
  1053. X   RunKey[6] = NULL;
  1054. X   RunKey[7] = NULL;
  1055. X   RunKey[8] = NULL;
  1056. X   RunKey[9] = NULL;
  1057. X   RunKey[10] = NULL;
  1058. X   RunKey[11] = NULL;
  1059. X   RunKey[12] = NULL;
  1060. X   RunKey[13] = NULL;
  1061. X   RunKey[14] = RunExit;
  1062. X   RunKey[15] = RunSetenv;
  1063. X   RunKey[16] = NULL;
  1064. X   RunKey[17] = RunPopMenu;
  1065. X   RunKey[18] = NULL;
  1066. X   RunKey[19] = RunGetInput;
  1067. X   RunKey[20] = NULL;
  1068. X   RunKey[21] = NULL;
  1069. X   RunKey[22] = NULL;
  1070. X}
  1071. SHAR_EOF
  1072. chmod 0644 LoadKeys.c || echo "restore of LoadKeys.c fails"
  1073. echo "x - extracting parsedrive.c (Text)"
  1074. sed 's/^X//' << 'SHAR_EOF' > parsedrive.c &&
  1075. Xstatic char Sccsid[] = "@(#)parsedrive.c    1.5   DeltaDate 1/22/90   ExtrDate 1/22/90";
  1076. X
  1077. X/*  FUNCTION:    parsedriver()
  1078. X**        This is the driver routine in parseing the menu
  1079. X**        file.  This function calls the appropriate parse
  1080. X**        function for that keyword.
  1081. X**  ARGS:    keyword        the keyword "AUTHORIZE"
  1082. X**        menufile    the unix menu file
  1083. X**        menu        menu structure
  1084. X**        gnames        holder of goto menu names
  1085. X**        gfiles        holder of goto menu names (menu file)
  1086. X**        gindex        # of gnames
  1087. X**  RETURNS:    0    success
  1088. X*/
  1089. X
  1090. X#include    <curses.h>
  1091. X#include    "menu.h"
  1092. X
  1093. X    int    swin, ewin, longest;
  1094. X
  1095. Xparsedriver (menufile, KeyWord, ParseKey, menu, gname, gfile, gindex)
  1096. X
  1097. X    FILE        *menufile;
  1098. X    char        KeyWord[][MAXKEYLENGTH];
  1099. X    int        (*ParseKey[])();
  1100. X    struct MenuInfo    *menu;
  1101. X    char        gname[][15], gfile[][15];
  1102. X    int        *gindex;
  1103. X{
  1104. X    char    keyword[80];
  1105. X    int    rcde, I, KEYFOUND;
  1106. X    int    opnumber = 0;                /* last option number */
  1107. X
  1108. X
  1109. X       /* Set default .WINDOW area */
  1110. X       menu->wfcol = 0;
  1111. X       menu->wlcol = COLS-1;
  1112. X    menu->wfrow = 0;
  1113. X       menu->wlrow = LINES-1;
  1114. X       menu->titlecount = 0;
  1115. X       menu->optioncount = 0;
  1116. X       swin = ewin = longest = 0;
  1117. X
  1118. X       /* loop through each keyword */
  1119. X       rcde = fscanf (menufile, "%s", keyword);
  1120. X       while (rcde != EOF)
  1121. X       {
  1122. X        if (strlen (keyword) >= 80-2)
  1123. X        {
  1124. X                  BEEP;
  1125. X                  mvprintw (ErrRow-2, 0, 
  1126. X                "Your keyword <%s> is toooo looong.  Max = %d",
  1127. X                keyword, 80-2);
  1128. X                  shutdown ();
  1129. X        }
  1130. X        /*
  1131. X        **  Check if we found a defined keyword
  1132. X        */
  1133. X              KEYFOUND = FALSE;
  1134. X              for (I = 1; I <= MAXKEYS; I++)
  1135. X              {
  1136. X            /*
  1137. X                 if (strcmp (keyword, KeyWord[I]) == 0)
  1138. X            */
  1139. X                 if (strmatch (keyword, KeyWord[I]))
  1140. X                 {
  1141. X                        KEYFOUND = TRUE;
  1142. X                    if (ParseKey[I] != NULL)
  1143. X                    {
  1144. X                               rcde = (*ParseKey[I]) (keyword, 
  1145. X                        menufile, menu, KeyWord, 
  1146. X                        ParseKey, gname, gfile, gindex, 
  1147. X                        &opnumber);
  1148. X                    /*
  1149. X                    ** The return code from each parse
  1150. X                    ** function must be 0 in order to
  1151. X                    ** continue.
  1152. X                    */
  1153. X                           if (rcde != 0)   return (rcde);
  1154. X                    }
  1155. X                        break;
  1156. X                 }
  1157. X              }
  1158. X              if (!KEYFOUND)
  1159. X              {
  1160. X                 BEEP;
  1161. X                 mvprintw (ErrRow-2, 0, "ERROR: (%s) Key not found.", 
  1162. X                    keyword);
  1163. X                 shutdown ();
  1164. X              }
  1165. X              rcde = fscanf (menufile, "%s", keyword);
  1166. X       } 
  1167. X
  1168. X       EndWindow (menu);
  1169. X       return (0);
  1170. X}
  1171. SHAR_EOF
  1172. chmod 0444 parsedrive.c || echo "restore of parsedrive.c fails"
  1173. echo "x - extracting showdriver.c (Text)"
  1174. sed 's/^X//' << 'SHAR_EOF' > showdriver.c &&
  1175. Xstatic char Sccsid[] = "@(#)showdriver.c    1.2   DeltaDate 10/16/88   ExtrDate 1/22/90";
  1176. X
  1177. X/*  FUNCTION:    showdriver()
  1178. X**        The driver module to initially display the options
  1179. X**        to the screen.
  1180. X**  ARGS:    keyword        the keyword found
  1181. X**        ShowKey        show functions
  1182. X**        menu        menu structure
  1183. X**  RETURNS:    none
  1184. X*/
  1185. X
  1186. X#include    <curses.h>
  1187. X#include    "menu.h"
  1188. X
  1189. X
  1190. Xshowdriver (KeyWord, ShowKey, menu)
  1191. X
  1192. X    char        KeyWord[][MAXKEYLENGTH];
  1193. X    int        (*ShowKey[])();
  1194. X    struct MenuInfo    *menu;
  1195. X{
  1196. X    int        i, j;
  1197. X
  1198. X
  1199. X
  1200. X    /*
  1201. X    **    Loop through options and call apropriate function.
  1202. X    */
  1203. X
  1204. X       for (i = 0; i < menu->optioncount; i++)
  1205. X              for (j = 1; j <= MAXKEYS; j++)
  1206. X                 if (strcmp (menu->option[i]->keyword, KeyWord[j]) == 0)
  1207. X             {
  1208. X                    if (ShowKey[j] != NULL)   
  1209. X                    (*ShowKey[j]) (menu, i);
  1210. X                    break;
  1211. X             }
  1212. X       refresh ();
  1213. X}
  1214. SHAR_EOF
  1215. chmod 0444 showdriver.c || echo "restore of showdriver.c fails"
  1216. echo "x - extracting rundriver.c (Text)"
  1217. sed 's/^X//' << 'SHAR_EOF' > rundriver.c &&
  1218. Xstatic char Sccsid[] = "%W%   DeltaDate %G%   ExtrDate %H%";
  1219. X
  1220. X/*  FUNCTION:    rundriver()
  1221. X**        The driver module to run each selectable option.
  1222. X**        Runmenu will call the appropriate run function
  1223. X**        for that keyword.
  1224. X**  ARGS:    keyword        the keyword "AUTHORIZE"
  1225. X**        menufile    the unix menu file
  1226. X**        menu        menu structure
  1227. X**        gnames        holder of goto menu names
  1228. X**        gfiles        holder of goto menu names (menu file)
  1229. X**        gindex        # of gnames
  1230. X**  RETURNS:    QUIT        exit pgm
  1231. X**        MAIN        go to main menu
  1232. X**        PREVIOUS    go to previous menu
  1233. X**        index to submenu
  1234. X*/
  1235. X
  1236. X#include    <curses.h>
  1237. X#include    <signal.h>
  1238. X#include    "menu.h"
  1239. X#include    "terminal.h"
  1240. X
  1241. X#define        INITMENU    0
  1242. X#define        GOTOMENU    1
  1243. X
  1244. Xextern int    MAILCALL;
  1245. Xextern int    trapsigs;
  1246. Xextern int    debug;
  1247. X
  1248. Xextern    struct MenuInfo    menu;
  1249. Xint        tmpoption;
  1250. Xint        ckik;                /* current keyword in KeyWord */
  1251. Xextern    int    (*ShowKey[])();
  1252. Xextern    char    KeyWord[][MAXKEYLENGTH];
  1253. X
  1254. X
  1255. Xrundriver (RunKey, ParseKey, option, gnames, 
  1256. X        gfiles, gindex, gotorow, gotocol)
  1257. X
  1258. X    int        (*RunKey[])(), *option;
  1259. X    int        (*ParseKey[])();
  1260. X    char        gnames[][15], gfiles[][15];
  1261. X    int        gindex;
  1262. X    int        gotorow;
  1263. X    int        gotocol;
  1264. X{
  1265. X    FILE        *fopen(), *fp;
  1266. X    char        *findfile();
  1267. X    char        *upper();
  1268. X    int        shutdown();
  1269. X    char        select[78], command[MAXLEN];
  1270. X    char        matchstr[60];
  1271. X    int        exitkey, index;
  1272. X    int        i, j;
  1273. X    int        lastopnumber = 0;        /* last option # */
  1274. X    int        MATCHED;            /* char match flag */
  1275. X    int        ch;
  1276. X
  1277. X
  1278. X
  1279. X    /*
  1280. X       **  What is the last option number ?
  1281. X       */
  1282. X    for (i = menu.optioncount-1; i >= 0; i--)
  1283. X        if (menu.option[i]->opnumber != 0)
  1284. X        {
  1285. X            lastopnumber = menu.option[i]->opnumber;
  1286. X            break;
  1287. X        }
  1288. X
  1289. X    if (lastopnumber <= 0)   return (QUIT);        /* no options */
  1290. X    select[0] = '\0';
  1291. X    matchstr[0] = '\0';
  1292. X
  1293. X    /*
  1294. X       **  Loop through options untill user exits menu or selects
  1295. X       **  another menu.
  1296. X       */
  1297. X    for (;;)
  1298. X    {
  1299. X#ifndef ALARM
  1300. X        if (MAILCALL)
  1301. X            checkmail ();
  1302. X#endif
  1303. X
  1304. X        /* highlight current option */
  1305. X        for (ckik = 1; ckik <= MAXKEYS  &&  KeyWord[ckik] != NULL;
  1306. X             ckik++)
  1307. X            if (strcmp (menu.option[*option-1]->keyword, 
  1308. X                    KeyWord[ckik]) == 0)
  1309. X            {
  1310. X                if (ShowKey[ckik] != NULL)
  1311. X                {
  1312. X                    /* display option */
  1313. X                    (*ShowKey[ckik]) (&menu, (*option)-1);
  1314. X                    mvaddch (menu.option[(*option)-1]->row,
  1315. X                           menu.option[(*option)-1]->col-1,
  1316. X                           ' ');
  1317. X                    /*
  1318. X                    ** turn on reverse video 
  1319. X                    ** maintaining current attributes
  1320. X                    */
  1321. X                    exitkey =  slength(menu.option[(*option)-1]->description) + menu.option[(*option)-1]->col + 5;
  1322. X                    for (j = menu.option[(*option)-1]->col-1; j <= exitkey; j++)
  1323. X                    {
  1324. X                        ch = mvinch (menu.option[(*option)-1]->row, j);
  1325. X                        ch |= A_REVERSE;
  1326. X                        mvaddch (menu.option[(*option)-1]->row, j, ch);
  1327. X                    }
  1328. X
  1329. X                }
  1330. X                break;
  1331. X            }
  1332. X
  1333. X#ifdef BSD
  1334. X        standend ();
  1335. X#else
  1336. X        attrset (A_NORMAL);
  1337. X#endif
  1338. X
  1339. X        tmpoption = *option;
  1340. X        if (RunKey[ckik] != NULL)
  1341. X            exitkey = GetOption (menu.row_cursor, menu.col_cursor,
  1342. X                         select);
  1343. X        else
  1344. X            /* so we don't go in a loop */
  1345. X            exitkey = (exitkey == KEY_UP || 
  1346. X                       exitkey == KeyUp) ? KEY_UP : KEY_DOWN;
  1347. X        *option = tmpoption;
  1348. X
  1349. X        if (exitkey == KeyDown)       exitkey = KEY_DOWN;
  1350. X        if (exitkey == KeyUp)        exitkey = KEY_UP;
  1351. X        if (exitkey == KeyTab)        exitkey = KEY_TAB;
  1352. X        if (exitkey == KeyBTab)        exitkey = KEY_BTAB;
  1353. X        if (exitkey == KeyReturn)    exitkey = KEY_RETURN;
  1354. X        if (exitkey == KeyMainMenu)    exitkey = KEY_MAINMENU;
  1355. X        if (exitkey == KeyPrevMenu)    exitkey = KEY_PREVMENU;
  1356. X        if (exitkey == KeyExitMenu)    exitkey = KEY_EXITMENU;
  1357. X        if (exitkey == KeyGname)    exitkey = KEY_GNAME;
  1358. X
  1359. X        /* unhighlight current option */
  1360. X        if (ShowKey[ckik] != NULL)
  1361. X        {
  1362. X            mvaddch (menu.option[(*option)-1]->row, 
  1363. X                menu.option[(*option)-1]->col-1, ' ');
  1364. X            strcat (menu.option[(*option)-1]->description, " ");
  1365. X            (*ShowKey[ckik]) (&menu, *option-1);
  1366. X            menu.option[(*option)-1]->description[strlen(menu.option[(*option)-1]->description)-1] = '\0';
  1367. X        }
  1368. X
  1369. X
  1370. X        switch (exitkey)
  1371. X        {
  1372. X        case KEY_DOWN:
  1373. X        case 'j':
  1374. X            *option = (*option) >= menu.optioncount 
  1375. X                    ? 1 : ++(*option);
  1376. X            break;
  1377. X
  1378. X        case KEY_UP:
  1379. X        case 'k':
  1380. X            *option = (*option) <= 1 
  1381. X                    ? menu.optioncount : --(*option);
  1382. X            break;
  1383. X
  1384. X        case KEY_TAB:
  1385. X            /* A tab will hop forward four options at a time. */
  1386. X            if (menu.optioncount > 4)
  1387. X            {
  1388. X                *option += 4;
  1389. X                if (*option > menu.optioncount)
  1390. X                    *option = 1 + *option - 
  1391. X                          menu.optioncount - 1;
  1392. X            }
  1393. X            else
  1394. X                *option = *option >= menu.optioncount ? 1 : 
  1395. SHAR_EOF
  1396. echo "End of part 3"
  1397. echo "File rundriver.c is continued in part 4"
  1398. echo "4" > s2_seq_.tmp
  1399. exit 0
  1400.