home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3511 < prev    next >
Encoding:
Internet Message Format  |  1991-06-20  |  46.5 KB

  1. From: rob@mtdiablo.Concord.CA.US (Rob Bernardo)
  2. Newsgroups: alt.sources
  3. Subject: DMM (Data entry and Menu screen Manager) - version 1.1 part 2/2
  4. Message-ID: <1991Jun18.012419.10146@mtdiablo.Concord.CA.US>
  5. Date: 18 Jun 91 01:24:19 GMT
  6.  
  7. #!/bin/sh
  8. # this is part 2 of a multipart archive
  9. # do not concatenate these parts, unpack them in order with /bin/sh
  10. # file dmm.c continued
  11. #
  12. CurArch=2
  13. if test ! -r s2_seq_.tmp
  14. then echo "Please unpack part 1 first!"
  15.      exit 1; fi
  16. ( read Scheck
  17.   if test "$Scheck" != $CurArch
  18.   then echo "Please unpack part $Scheck next!"
  19.        exit 1;
  20.   else exit 0; fi
  21. ) < s2_seq_.tmp || exit 1
  22. echo "x - Continuing file dmm.c"
  23. sed 's/^X//' << 'SHAR_EOF' >> dmm.c
  24. X    return;
  25. X}
  26. X
  27. X
  28. X/* This replaces the standard curses overlay(), which is broken:
  29. X * it does not preserve the attributes of the copied characters
  30. X */
  31. Xstatic void
  32. XoverLay (srcWin, dstWin)
  33. XWINDOW         *srcWin,
  34. X               *dstWin;
  35. X{
  36. X    register int    x,
  37. X                    y;
  38. X    register chtype mychar;
  39. X    for (y = 0; y < srcWin->_maxy; y++) {
  40. X    for (x = 0; x < srcWin->_maxx; x++) {
  41. X        mychar = mvwinch (srcWin, y, x);
  42. X        if (((mychar & A_CHARTEXT) != ' ')
  43. X        || ((mychar & A_ATTRIBUTES) != A_NORMAL))
  44. X        mvwinsch (dstWin, y, x, mychar);
  45. X    }
  46. X    }
  47. X    return;
  48. X}
  49. X
  50. X
  51. X
  52. X/* fieldMgr()    manage user interactions with the field window;
  53. X *        start by first positioning in the infput field
  54. X *        designated by fldNum; if fldNum is -1, use the
  55. X *        default input field, determined from the last
  56. X *        call to this function;
  57. X *        set the default field for use in the next call to
  58. X *        this function before returning.
  59. X *        return -1 if the user wants to leave for the menu;
  60. X *        else return the field number of a field if the
  61. X *        audit routine for that field returns dmmAuditReturnOkay
  62. X *        or dmmAuditReturnBad, which means that the screen 
  63. X *        handler must return to the application software;
  64. X */
  65. Xstatic int
  66. XfieldMgr (fldNum)
  67. Xregister int    fldNum;
  68. X{
  69. X    register int    curCol,    /* current column number in field */
  70. X                    curLine,    /* current line number in field */
  71. X                    curChar;    /* current char position in field */
  72. X    enum change     delta;    /* what to do upon user input keystroke */
  73. X    int             key,    /* user's input keystroke */
  74. X                    len;    /* length of field being manipulated */
  75. X    static          dfltInputFld;    /* default field for next call */
  76. X    char           *instructMesg;    /* message for instruct line */
  77. X
  78. X    /* display general instructions about how to go to menu */
  79. X    if (numMenuItems)
  80. X    instructMesg = GOTO_MENU_INSTRUCT;
  81. X    else
  82. X    instructMesg = NULL_MENU_INSTRUCT;
  83. X    dispInstruct (instructMesg);
  84. X
  85. X    /* first field: instruction and attribute */
  86. X    fldNum = (fldNum == -1) ? dfltInputFld : fldNum;
  87. X    arriveInField (dupeScreen[fldNum]);
  88. X
  89. X    /* separate parts of refresh for sake of dispInstruct() above */
  90. X    wnoutrefresh (fieldWin);
  91. X    doupdate ();
  92. X
  93. X    /* add messages as needed */
  94. X    if (needAddMsgs) {
  95. X    overwrite (fieldWin, fieldWinPreMsg);
  96. X    overLay (mesgWin, fieldWin);
  97. X    }
  98. X    /* position cursor in appropriate field */
  99. X    (void) chgInField (fldNum, stayput);
  100. X    curCol = curLine = curChar = 0;
  101. X
  102. X    /* process user input */
  103. X    while (1) {
  104. X    delta = stayput;    /* default is no chg in field/cursor pos. Any
  105. X                 * of the below choices that change the
  106. X                 * screen but stayput need to do their own
  107. X                 * wrefresh() */
  108. X
  109. X    switch (key = wGetCh (fieldWin)) {
  110. X
  111. X    case CTRL (h):
  112. X        /* display help */
  113. X        doPutMsgsHit (helpMsgVec, 1);
  114. X        break;
  115. X
  116. X    case CTRL (g):
  117. X        /* submit screen as is; set default field to current field and go
  118. X         * to menu
  119. X         */
  120. X        adjustFld (dupeScreen[fldNum]);
  121. X        leaveInField (dupeScreen[dfltInputFld = fldNum]);
  122. X        return -1;
  123. X
  124. X    case CTRL (c):
  125. X        /* clear to end of field, audit, move to next field */
  126. X        for (len = dupeScreen[fldNum]->inputLength;
  127. X         curChar < len; curChar++)
  128. X        dupeScreen[fldNum]->inputEditValue[curChar] = '\0';
  129. X        dispInField (dupeScreen[fldNum],
  130. X             dupeScreen[fldNum]->inputEditAttrib);
  131. X        delta = next;
  132. X        break;
  133. X
  134. X    case RETURN:
  135. X    case TAB:
  136. X    case CTRL (n):
  137. X        /* audit and move to next field */
  138. X        delta = next;
  139. X        break;
  140. X
  141. X    case CTRL (p):
  142. X        /* audit and move to previous field */
  143. X        delta = previous;
  144. X        break;
  145. X
  146. X    case CTRL (r):
  147. X        /* redraw screen */
  148. X        redraw ();
  149. X        break;
  150. X
  151. X    case KEY_LEFT:
  152. X        /* move cursor to left if possible */
  153. X        if (curCol) {
  154. X        curCol--;
  155. X        curChar--;
  156. X        delta = movecursor;
  157. X        } else
  158. X        flash();
  159. X        break;
  160. X
  161. X    case KEY_RIGHT:
  162. X        /* move cursor to right if possible */
  163. X        if (((curLine < dupeScreen[fldNum]->inputFullLines) &&
  164. X         (curCol + 1 < dupeScreen[fldNum]->inputMaxCols)) ||
  165. X        (curCol + 1 < dupeScreen[fldNum]->inputShortCols)) {
  166. X        curCol++;
  167. X        curChar++;
  168. X        delta = movecursor;
  169. X        } else
  170. X        flash();
  171. X        break;
  172. X
  173. X    case KEY_UP:
  174. X        /* move cursor up if possible */
  175. X        if (curLine != 0) {
  176. X        curLine--;
  177. X        curChar -= dupeScreen[fldNum]->inputMaxCols;
  178. X        delta = movecursor;
  179. X        } else
  180. X        flash();
  181. X        break;
  182. X
  183. X    case KEY_DOWN:
  184. X        /* move cursor down if possible */
  185. X        if ((curLine + 1 < dupeScreen[fldNum]->inputFullLines) ||
  186. X        ((curLine + 1 == dupeScreen[fldNum]->inputFullLines) &&
  187. X         (curCol < dupeScreen[fldNum]->inputShortCols))) {
  188. X        curLine++;
  189. X        curChar += dupeScreen[fldNum]->inputMaxCols;
  190. X        delta = movecursor;
  191. X        } else
  192. X        flash();
  193. X        break;
  194. X
  195. X    case DELETE:
  196. X        /* erase character to left of cursor and move cursor left,
  197. X         * except if we are in last character position and last
  198. X         * character is not a space, then erase last character
  199. X         * and don't move cursor.
  200. X         * Obviously, erase nothing if we are in the first character
  201. X         * position last is not also a last character position.
  202. X         */
  203. X        if((curChar + 1 == dupeScreen[fldNum]->inputLength) &&
  204. X           (dupeScreen[fldNum]->inputEditValue[curChar] != ' ')) {
  205. X
  206. X           /* erase last character internally */
  207. X        dupeScreen[fldNum]->inputEditValue[curChar] = ' ';
  208. X
  209. X        } else {
  210. X
  211. X        /* do nothing if we are in the first character position
  212. X         * which is not also the last character position */
  213. X        if (!curChar) {
  214. X            flash();
  215. X            break;
  216. X        }
  217. X
  218. X        /* erase last character internally */
  219. X        dupeScreen[fldNum]->inputEditValue[--curChar] = ' ';
  220. X
  221. X        /* retreat the cursor */
  222. X        if (curCol)
  223. X            curCol--;
  224. X        else {
  225. X            curLine--;
  226. X            curCol = dupeScreen[fldNum]->inputMaxCols - 1;
  227. X        }
  228. X        }
  229. X
  230. X        /* display space on screen */
  231. X        DMMWATTRON (fieldWin, dupeScreen[fldNum]->inputEditAttrib);
  232. X        mvwaddch (fieldWin,
  233. X              dupeScreen[fldNum]->inputLine + curLine,
  234. X              dupeScreen[fldNum]->inputCol + curCol, ' ');
  235. X        DMMWATTROFF (fieldWin, dupeScreen[fldNum]->inputEditAttrib);
  236. X
  237. X        delta = movecursor;
  238. X        break;
  239. X
  240. X    default:
  241. X        /* process only if a printing character */
  242. X        if (isascii (key) && isprint (key)) {
  243. X
  244. X        /* display character, or if A_INVIS  display space */
  245. X        DMMWATTRON (fieldWin, dupeScreen[fldNum]->inputEditAttrib);
  246. X        mvwaddch (fieldWin,
  247. X              dupeScreen[fldNum]->inputLine + curLine,
  248. X              dupeScreen[fldNum]->inputCol + curCol,
  249. X              (dupeScreen[fldNum]->inputEditAttrib & A_INVIS) ?
  250. X              ' ' : (char) key);
  251. X        DMMWATTROFF (fieldWin, dupeScreen[fldNum]->inputEditAttrib);
  252. X
  253. X        /* store internally */
  254. X        dupeScreen[fldNum]->inputEditValue[curChar] = (char) key;
  255. X
  256. X        /* if not at end of field, move cursor */
  257. X        if (curChar + 1 < dupeScreen[fldNum]->inputLength) {
  258. X            /* either move to next col in same line or first col of
  259. X             * next line
  260. X             */
  261. X            curChar++;
  262. X            if (((curLine < dupeScreen[fldNum]->inputFullLines) &&
  263. X             (curCol + 1 < dupeScreen[fldNum]->inputMaxCols)) ||
  264. X            (curCol + 1 < dupeScreen[fldNum]->inputShortCols))
  265. X            curCol++;
  266. X            else {
  267. X            curCol = 0;
  268. X            curLine++;
  269. X            }
  270. X            delta = movecursor;
  271. X        }
  272. X        } else
  273. X        flash ();
  274. X        break;
  275. X    }
  276. X
  277. X    /* now check if cursor position of field is to be changed */
  278. X    switch (delta) {
  279. X
  280. X    case next:
  281. X    case previous:
  282. X        /* advance or retreat a field */
  283. X
  284. X        /* remove trailing blanks and internal nulls */
  285. X        adjustFld (dupeScreen[fldNum]);
  286. X
  287. X        /* audit field */
  288. X        if (dupeScreen[fldNum]->inputAudit) {
  289. X
  290. X        switch (dupeScreen[fldNum]->inputAudit 
  291. X                (dupeScreen[fldNum]->inputEditValue)) {
  292. X
  293. X        case dmmAuditReturnOkay:
  294. X            /* must leave screen handler; first show any changes to
  295. X             * field value and set default field according to user's
  296. X             * last keystroke
  297. X             */
  298. X            dmmRetType = dmmOkayField;
  299. X            leaveInField (dupeScreen[fldNum]);
  300. X            wrefresh (fieldWin);
  301. X            dfltInputFld = delta == next ?
  302. X            dupeScreen[fldNum]->nextInField :
  303. X            dupeScreen[fldNum]->prevInField;
  304. X            return fldNum;
  305. X
  306. X        case dmmAuditReturnBad:
  307. X            /* must leave screen handler; first show any changes to
  308. X             * field value and set default field according to user's
  309. X             * last keystroke
  310. X             */
  311. X            dmmRetType = dmmBadField;
  312. X            leaveInField (dupeScreen[fldNum]);
  313. X            wrefresh (fieldWin);
  314. X            dfltInputFld = delta == next ?
  315. X            dupeScreen[fldNum]->nextInField :
  316. X            dupeScreen[fldNum]->prevInField;
  317. X            return fldNum;
  318. X
  319. X        case dmmAuditBad:
  320. X            /* failed; stay in this field */
  321. X            delta = stayput;
  322. X            break;
  323. X
  324. X        case dmmAuditOkay:
  325. X            /* audit okay; go to another field */
  326. X            break;
  327. X        }
  328. X        }
  329. X
  330. X        /* show any changes to field value */
  331. X        fldNum = chgInField (fldNum, delta);
  332. X        curCol = curLine = curChar = 0;
  333. X        wrefresh (fieldWin);
  334. X        break;
  335. X
  336. X    case stayput:
  337. X    case movecursor:
  338. X        /* move cursor to current column and line position in current
  339. X         * input field as just set or left as was
  340. X         */
  341. X        wmove (fieldWin, dupeScreen[fldNum]->inputLine + curLine,
  342. X           dupeScreen[fldNum]->inputCol + curCol);
  343. X        wrefresh (fieldWin);
  344. X        break;
  345. X    }
  346. X    }
  347. X}
  348. X
  349. X/* leaveMenu()    leave menu;
  350. X *        if menuitem is < 0, erase whole menu,
  351. X *         else unhighlight indicated item
  352. X */
  353. Xstatic void
  354. XleaveMenu (itemNum)
  355. Xint             itemNum;
  356. X{
  357. X    if (itemNum < 0) {
  358. X    wclear (menuWin);
  359. X    wnoutrefresh (menuWin);
  360. X    } else
  361. X    dispMenuPage (itemNum, 0, 0);
  362. X    return;
  363. X}
  364. X
  365. X
  366. X/* menuMgr        manage user interactions with the menu window;
  367. X *            return the number of the menu item selected
  368. X *            or -1 if the user wants to leave the menu without
  369. X *            a selection.
  370. X */
  371. Xstatic int
  372. XmenuMgr ()
  373. X{
  374. X    int             key;
  375. X
  376. X    /* display the current page of the menu with the current item highlighted */
  377. X    dispMenuPage (curMenuItem, 1, 1);
  378. X
  379. X    /* display general menu instruction */
  380. X    dispInstruct (MENU_INSTRUCT);
  381. X
  382. X    /* add messages as needed */
  383. X    if (needAddMsgs) {
  384. X    overwrite (fieldWin, fieldWinPreMsg);
  385. X    overLay (mesgWin, fieldWin);
  386. X    wnoutrefresh (fieldWin);
  387. X    }
  388. X
  389. X    /* process user input */
  390. X    while (1) {
  391. X
  392. X    /* refresh instruct and menu page on screen, as needed */
  393. X    outOfTheWay();
  394. X    doupdate ();
  395. X
  396. X    switch (key = wGetCh (menuWin)) {
  397. X
  398. X    case CTRL (h):
  399. X        /* display help */
  400. X        doPutMsgsHit (helpMsgVec, 1);
  401. X        break;
  402. X
  403. X    case CTRL (r):
  404. X        /* redraw screen */
  405. X        redraw ();
  406. X        break;
  407. X
  408. X    case CTRL (g):
  409. X        /* leave menu for input part of screen */
  410. X        leaveMenu (curMenuItem);
  411. X        return -1;
  412. X
  413. X    case RETURN:
  414. X        /* submit this choice */
  415. X        leaveMenu (-1);
  416. X        return curMenuItem;
  417. X
  418. X    case TAB:
  419. X    case CTRL (n):
  420. X        /* move to next item */
  421. X        if (++curMenuItem >= numMenuItems)
  422. X        curMenuItem = 0;
  423. X        dispMenuPage (curMenuItem, 1, 0);
  424. X        break;
  425. X
  426. X    case CTRL (p):
  427. X        /* move to previous item */
  428. X        if (--curMenuItem < 0)
  429. X        curMenuItem = numMenuItems - 1;
  430. X        dispMenuPage (curMenuItem, 1, 0);
  431. X        break;
  432. X
  433. X    default:
  434. X        /* find single menu item with matching first character */
  435. X        if (isascii (key) && isalpha (key)) {
  436. X        if (isupper (key))
  437. X            key = tolower (key);
  438. X        if (menuIndex[key - 'a'] >= 0) {
  439. X            dispMenuPage (curMenuItem = menuIndex[key - 'a'], 1, 0);
  440. X            break;
  441. X        }
  442. X        }
  443. X        flash ();
  444. X        break;
  445. X    }
  446. X    }
  447. X}
  448. X
  449. X
  450. X/* dmmRun    manage menu and data entry screen - see man page for fuller
  451. X *        description
  452. X */
  453. Xint
  454. XdmmRun (startField, screen, menu, dmmDrawFlag, dmmValFlag)
  455. Xint             startField;
  456. XDMMDRAWFLAG     dmmDrawFlag;
  457. XDMMVALFLAG      dmmValFlag;
  458. XDMMSCREEN       screen;
  459. XDMMMENU         menu;
  460. X{
  461. X    int             itemNum;    /* menu or field number */
  462. X    void            (*oldSignalValue) ();    /* current state for signal
  463. X                         * SIGALRM */
  464. X
  465. X    /* copy parameters to global variables */
  466. X    dupeScreen = screen;
  467. X    dupeMenu = menu;
  468. X
  469. X    /* initialize windows if needed */
  470. X    if (!isOpen)
  471. X    dmmInit ();
  472. X
  473. X    /* get rid of type-ahead input */
  474. X    flushinp ();
  475. X
  476. X    /* process dmmDrawFlag */
  477. X    switch (dmmDrawFlag) {
  478. X
  479. X    case dmmNew:
  480. X
  481. X    /* the first display of a screen - do initial layout calculations */
  482. X    if (layout ())
  483. X        return -1;
  484. X
  485. X    /* determine field for cursor */
  486. X    if (startField == -1)
  487. X        startField = firstInputFld;
  488. X
  489. X    /* do sanity checking */
  490. X    if (insane (startField))
  491. X        return -1;
  492. X
  493. X    /* display screen */
  494. X    redraw ();
  495. X
  496. X    break;
  497. X
  498. X
  499. X    case dmmOld:
  500. X    /* restore saved screen and redisplay menu with first item
  501. X     * highlighted; let a -1 startField stand - fieldMgr() will
  502. X     * interpret it to mean the last input field saved on the last call
  503. X     * of dmmRun().
  504. X     */
  505. X
  506. X    /* This overwrite gets rid of any messages displayed by
  507. X     * dmmPutMsgsNext(), and so the needAddMsgs flag is used to get them
  508. X     * reinstated in fieldMgr() and menuMgr().
  509. X     */
  510. X    overwrite (fieldWinCopy, fieldWin);
  511. X    redraw ();
  512. X    if (dupeMenu)
  513. X        dispMenuPage (0, 0, 1);
  514. X    break;
  515. X
  516. X    }
  517. X
  518. X    /* copy inputInitValue's if indicated by dmmValFlag */
  519. X    if (dmmValFlag == dmmInitVal)
  520. X    copyInFields ();
  521. X
  522. X    /* process user input */
  523. X
  524. X    /* ignore SIGALRM to avoid a bug in wgetch() that fails to cancel an
  525. X     * alarm() it sets after unsetting the catching of SIGALRM; this must be
  526. X     * reset to current value before returning.
  527. X     */
  528. X    oldSignalValue = signal (SIGALRM, SIG_IGN);
  529. X
  530. X    interactive = 1;
  531. X
  532. X    while (1) {
  533. X
  534. X    /* manage fields with input parts, if any */
  535. X    if (numInputParts) {
  536. X        if ((itemNum = fieldMgr (startField)) != -1)
  537. X        break;
  538. X        startField = itemNum;
  539. X    }
  540. X
  541. X    /* manage menu items, if any */
  542. X    if (numMenuItems) {
  543. X        if ((itemNum = menuMgr ()) != -1) {
  544. X        dmmRetType = dmmMenu;
  545. X        break;
  546. X        }
  547. X        doupdate ();
  548. X    }
  549. X    }
  550. X
  551. X    /* remove instruction and update screen */
  552. X    dispInstruct ("");
  553. X    doupdate ();
  554. X
  555. X    /* save copy of screen for restoral with dmmOld option */
  556. X    overwrite (fieldWin, fieldWinCopy);
  557. X
  558. X    /* undo ignoring of alarm signal */
  559. X    (void) signal (SIGALRM, oldSignalValue);
  560. X
  561. X    interactive = 0;
  562. X
  563. X    return itemNum;
  564. X}
  565. SHAR_EOF
  566. echo "File dmm.c is complete"
  567. chmod 0444 dmm.c || echo "restore of dmm.c fails"
  568. set `wc -c dmm.c`;Sum=$1
  569. if test "$Sum" != "44980"
  570. then echo original size 44980, current size $Sum;fi
  571. echo "x - extracting dmm.h (Text)"
  572. sed 's/^X//' << 'SHAR_EOF' > dmm.h &&
  573. X#ifndef LINT
  574. Xstatic char dmm_h_id[] = {"@(#)dmm.h    1.1 \
  575. XCopyright (c) 1991 Robert Bernardo, rob@mtdiablo.Concord.CA.US, \
  576. Xan employee of Pande, Inc. \
  577. XPermission  to use granted only if this notice is not removed from \
  578. Xthis source file nor from any binaries produced from it."};
  579. X
  580. X#endif
  581. X
  582. X/* data display and entry field descriptor */
  583. Xtypedef struct dmmField {
  584. X    char                   *labelValue;
  585. X    int                     labelCol,
  586. X                            labelLine;
  587. X    long                    labelAttrib;
  588. X    char                   *inputEditValue,
  589. X                           *inputInitValue;
  590. X    int                     inputCol,
  591. X                            inputLine,
  592. X                            inputLength,
  593. X                            inputMaxCols,
  594. X                            inputFullLines,
  595. X                            inputShortCols;
  596. X    long                    inputAttrib,
  597. X                            inputEditAttrib;
  598. X    char                  **inputInstructVec;
  599. X    int                     inputNumInstructs;
  600. X    enum dmmAuditReturn     (*inputAudit) ();
  601. X    int                     nextInField,
  602. X                            prevInField;
  603. X}                       DMMFIELD, *DMMSCREEN[], **DMMSCREEN2;
  604. X
  605. X/* menu item descriptor */
  606. Xtypedef struct dmmMenuItem {
  607. X    char                   *label,
  608. X                           *descript;
  609. X    int                     col,
  610. X                            page;
  611. X}                       DMMMENUITEM, *DMMMENU[], **DMMMENU2;
  612. X
  613. X/* message descriptor */
  614. Xtypedef struct dmmMessage {
  615. X    char                   *value;
  616. X    int                     col,
  617. X                            line;
  618. X    long                    attrib;
  619. X}                       DMMMESSAGE, *DMMMESGBLK[], **DMMMESGBLK2;
  620. X
  621. X/* return values for inputAudit() */
  622. Xtypedef enum dmmAuditReturn {
  623. X    dmmAuditOkay, dmmAuditBad, dmmAuditReturnOkay, dmmAuditReturnBad
  624. X}                       DMMAUDITRETURN;
  625. X
  626. X/* DrawFlag values */
  627. Xtypedef enum dmmDrawFlag {
  628. X    dmmNew, dmmOld
  629. X}                       DMMDRAWFLAG;
  630. X
  631. X/* ValFlag values */
  632. Xtypedef enum dmmValFlag {
  633. X    dmmInitVal, dmmEdVal
  634. X}                       DMMVALFLAG;
  635. X
  636. X/* dmmRetType values */
  637. Xtypedef enum dmmRetType {
  638. X    dmmOkayField, dmmBadField, dmmMenu
  639. X}                       DMMRETTYPE;
  640. X
  641. X/* dmmRemoveType values */
  642. Xtypedef enum dmmRemoveType {
  643. X    dmmRemoveAll, dmmRemoveLast
  644. X}                       DMMREMOVETYPE;
  645. X
  646. Xextern enum dmmRetType  dmmRetType;
  647. Xextern void             dmmPutMsgs(),
  648. X                        dmmPutMsgsTimer(),
  649. X                        dmmPutMsgsHit(),
  650. X                        dmmPutMsgsNext(),
  651. X                        dmmRmMsgs(),
  652. X                        dmmInit(),
  653. X                        dmmClear(),
  654. X                        dmmClose();
  655. X
  656. X#ifndef A_INVIS
  657. X#define A_INVIS         000020000000L
  658. X#endif
  659. SHAR_EOF
  660. chmod 0444 dmm.h || echo "restore of dmm.h fails"
  661. set `wc -c dmm.h`;Sum=$1
  662. if test "$Sum" != "2793"
  663. then echo original size 2793, current size $Sum;fi
  664. echo "x - extracting dmmdemo.h (Text)"
  665. sed 's/^X//' << 'SHAR_EOF' > dmmdemo.h &&
  666. X#ifndef LINT
  667. Xstatic char dmmdemo_h_id[] = {"@(#)dmmdemo.h    1.1 \
  668. XCopyright (c) 1991 Robert Bernardo, rob@mtdiablo.Concord.CA.US, \
  669. Xan employee of Pande, Inc. \
  670. XPermission  to use granted only if this notice is not removed from \
  671. Xthis source file nor from any binaries produced from it."};
  672. X#endif
  673. X
  674. X#define NUMBERCOL 5
  675. X#define BODYCOL (NUMBERCOL + 3)
  676. X
  677. Xextern void             calcdate(),
  678. X            msgdemo(),
  679. X            getcomment(),
  680. X            monthmenu();
  681. SHAR_EOF
  682. chmod 0444 dmmdemo.h || echo "restore of dmmdemo.h fails"
  683. set `wc -c dmmdemo.h`;Sum=$1
  684. if test "$Sum" != "432"
  685. then echo original size 432, current size $Sum;fi
  686. echo "x - extracting dmmdemo1.c (Text)"
  687. sed 's/^X//' << 'SHAR_EOF' > dmmdemo1.c &&
  688. X#ifndef LINT
  689. Xstatic char     dmmdemo_1_c_id[] = {"@(#)dmmdemo1.c    1.1 \
  690. XCopyright (c) 1991 Robert Bernardo, rob@mtdiablo.Concord.CA.US, \
  691. Xan employee of Pande, Inc. \
  692. XPermission to use granted only if this notice is not removed from \
  693. Xthis source file nor from any binaries produced from it."};
  694. X#endif
  695. X#include <curses.h>
  696. X#include "dmm.h"
  697. X#include "dmmdemo.h"
  698. X
  699. X/* messages */
  700. Xstatic DMMMESSAGE       intro1 =
  701. X{"Welcome to the DMM demonstration program. This program will use DMM",
  702. X0, 0, 0},
  703. X
  704. X                        intro2 =
  705. X{"functions to present a variety of screens. For each screen, it will",
  706. X0, 1, 0},
  707. X
  708. X                        intro3 =
  709. X{"state the associated source file and list its salient features.",
  710. X0, 2, 0},
  711. X
  712. X                        intro4 =
  713. X{"The source for this screen is in dmmdemo1.c.",
  714. X0, 4, 0},
  715. X
  716. X                        intro5 =
  717. X{"1. It has just called dmmInit() to start up curses (putting the",
  718. XNUMBERCOL, 5, 0},
  719. X
  720. X                        intro6 =
  721. X{"terminal into raw mode, etc.) and to initialize the DMM windows.",
  722. XBODYCOL, 6, 0},
  723. X
  724. X                        intro7 =
  725. X{"2. This block of messages is displayed with a call do dmmPutMsgsHit().",
  726. XNUMBERCOL, 7, 0},
  727. X
  728. X                        intro8 =
  729. X{"Notice the top line if this screen. After the next message, you",
  730. XBODYCOL, 8, 0},
  731. X
  732. X                        intro9 =
  733. X{"will be presented with a menuless screen. The top line always has",
  734. XBODYCOL, 9, 0},
  735. X
  736. X                        intro10 =
  737. X{"an appropriate general instruction when a call to dmmRun() presents",
  738. XBODYCOL, 10, 0},
  739. X
  740. X                        intro11 =
  741. X{"a screen. Pay attention to it throughout this demo. Remember that",
  742. XBODYCOL, 11, 0},
  743. X
  744. X                        intro12 =
  745. X{"control-H displays a useful help screen during a dmmRun() call.",
  746. XBODYCOL, 12, 0},
  747. X
  748. X                        intro13 =
  749. X{"The source for the menuless screen is in dmmdemo2.c Enter any log name",
  750. X0, 0, 0},
  751. X
  752. X                        intro14 =
  753. X{"and any password; it doesn't matter. The simulated login procedure is",
  754. X0, 1, 0},
  755. X
  756. X                        intro15 =
  757. X{"hardcoded to reject them the first time and succeed the second, so you",
  758. X0, 2, 0},
  759. X
  760. X                        intro16 =
  761. X{"will need to try a second time. Next time you run this program, enter 'y'",
  762. X0, 3, 0},
  763. X
  764. X                        intro17 =
  765. X{"to the \"give up\" question and see what happens.",
  766. X0, 4, 0},
  767. X
  768. X                        intro18 =
  769. X{"Note the following:",
  770. X0, 6, 0},
  771. X
  772. X                        intro19 =
  773. X{"1. Negative column numbers are used to separate the labels from the",
  774. XNUMBERCOL, 7, 0},
  775. X
  776. X                        intro20 =
  777. X{"input areas by a certain number of blank spaces.",
  778. XBODYCOL, 8, 0},
  779. X
  780. X                        intro21 =
  781. X{"2. The audit functions for the \"give up\" (if you enter 'y') and ",
  782. XNUMBERCOL, 9, 0},
  783. X
  784. X                        intro22 =
  785. X{"\"password\" fields return values that cause dmmRun() to return. Because ",
  786. XBODYCOL, 10, 0},
  787. X
  788. X                        intro23 =
  789. X{"this is a menuless screen and  no menu selection can be made, such is",
  790. XBODYCOL, 11, 0},
  791. X
  792. X                        intro24 =
  793. X{"necessary so that dmmRun() doesn't just go on indefinitely.",
  794. XBODYCOL, 12, 0},
  795. X
  796. X                        intro25 =
  797. X{"3. See how the data type DMMSCREEN2 is used for a pointer.",
  798. XNUMBERCOL, 13, 0},
  799. X
  800. X                        intro26 =
  801. X{"4. Data entered into the password field is invisible.",
  802. XNUMBERCOL, 14, 0},
  803. X            sizemsg1 =
  804. X{"The DMM demo requires your screen (or window) to have at least 24",
  805. X0, 0, A_REVERSE},
  806. X            sizemsg2 =
  807. X{"lines and 80 columns.",
  808. X0, 1, A_REVERSE},
  809. X            byemsg =
  810. X{"End of the DMM demonstration. Good bye.",
  811. X0, 0, A_REVERSE};
  812. X
  813. X
  814. X
  815. X
  816. Xstatic DMMMESGBLK       introA = {&intro1, &intro2, &intro3, &intro4, &intro5,
  817. X                  &intro6, &intro7, &intro8, &intro9, &intro10,
  818. X                      &intro11, &intro12, 0},
  819. X
  820. X                        introB = {&intro13, &intro14, &intro15, &intro16,
  821. X                  &intro17, &intro18, &intro19, &intro20,
  822. X                  &intro21, &intro22, &intro23, &intro24,
  823. X                  &intro25, &intro26, 0},
  824. X
  825. X            requirements = {&sizemsg1, &sizemsg2, 0},
  826. X
  827. X            byemsgblk = {&byemsg, 0};
  828. X
  829. Xmain()
  830. X{
  831. X    dmmInit();                /* start up curses; init DMM windows  */
  832. X    if((COLS < 80) || (LINES < 24)) {     /* make sure screen is large enough */
  833. X    dmmPutMsgsHit(requirements);
  834. X    dmmClose();
  835. X    exit(1);
  836. X    }
  837. X    
  838. X    dmmPutMsgsHit(introA);        /* display a message until user hits
  839. X                     * a key */
  840. X    dmmPutMsgsHit(introB);
  841. X    if (login() == 0) {            /* if login goes okay, do rest of
  842. X                     * demo screens
  843. X                     */
  844. X    monthmenu();
  845. X    msgdemo();
  846. X    calcdate();
  847. X    getcomment();
  848. X    }
  849. X    dmmPutMsgsTimer(byemsgblk, 2);
  850. X    dmmClose();                /* shut down curses and DMM windows */
  851. X    exit(0);
  852. X}
  853. SHAR_EOF
  854. chmod 0444 dmmdemo1.c || echo "restore of dmmdemo1.c fails"
  855. set `wc -c dmmdemo1.c`;Sum=$1
  856. if test "$Sum" != "4642"
  857. then echo original size 4642, current size $Sum;fi
  858. echo "x - extracting dmmdemo2.c (Text)"
  859. sed 's/^X//' << 'SHAR_EOF' > dmmdemo2.c &&
  860. X#ifndef LINT
  861. Xstatic char     dmmdemo_2_c_id[] = {"@(#)dmmdemo2.c    1.1 \
  862. XCopyright (c) 1991 Robert Bernardo, rob@mtdiablo.Concord.CA.US, \
  863. Xan employee of Pande, Inc. \
  864. XPermission to use granted only if this notice is not removed from \
  865. Xthis source file nor from any binaries produced from it."};
  866. X#endif
  867. X#include <strings.h>
  868. X#include <curses.h>
  869. X#include "dmm.h"
  870. X
  871. X/* field sizes */
  872. X#define USERNAMELEN 10
  873. X#define PASSWDLEN 8
  874. X#define YESNOLEN 1
  875. X
  876. X/* editable buffers */
  877. Xstatic char             username[USERNAMELEN + 1],
  878. X                        giveup[YESNOLEN + 1],
  879. X                        passwd[PASSWDLEN + 1],
  880. X                        auditbuf[80];
  881. X
  882. X/* instruction fields */
  883. Xstatic char            *usernameinstr[] = {"Enter your user name", 0},
  884. X                       *giveupinstr[] = {"Enter y or n", 0},
  885. X                       *passwdinstr[] = {"Enter your password", 0};
  886. X
  887. X/* data fields */
  888. X#define GIVEUPLINE    2
  889. X#define LNSPACING    2
  890. X#define LABELCOL    10
  891. X#define USERNAMELINE    (GIVEUPLINE + LNSPACING)
  892. X#define PASSWDLINE    (USERNAMELINE + LNSPACING)
  893. X#define MSGLINE        (PASSWDLINE + LNSPACING)
  894. Xextern DMMAUDITRETURN   giveupaudit(),
  895. X            auditUsername(),
  896. X            auditPasswd();
  897. X
  898. Xstatic DMMFIELD         giveupfld = {"Give up logging in?", LABELCOL,
  899. X                GIVEUPLINE, 0, giveup, "n", -2, GIVEUPLINE,
  900. X                YESNOLEN, 0, 0, 0, A_REVERSE, A_UNDERLINE,
  901. X                giveupinstr, 0, giveupaudit, 0},
  902. X
  903. X                        usernamefld = {"User name", LABELCOL,
  904. X                USERNAMELINE, 0, username, 0, -2,
  905. X                USERNAMELINE, USERNAMELEN, 0, 0, 0,
  906. X                A_REVERSE, A_UNDERLINE, usernameinstr,
  907. X                0, auditUsername, 0},
  908. X
  909. X                        passwdfld = {"Password", LABELCOL, PASSWDLINE, 0,
  910. X                passwd, 0, -2, PASSWDLINE,
  911. X                PASSWDLEN, 0, 0, 0, A_REVERSE | A_INVIS,
  912. X                A_UNDERLINE | A_INVIS, passwdinstr, 0,
  913. X                auditPasswd, 0};
  914. X
  915. X/* data field arrays */
  916. Xstatic DMMSCREEN        loginscreen1 = {&usernamefld, &passwdfld, 0},
  917. X                        loginscreen2 = {&giveupfld, &usernamefld, &passwdfld, 0};
  918. X
  919. X/* messages */
  920. Xstatic DMMMESSAGE       plswaitmsg = {"Please wait", 0, 0, A_REVERSE},
  921. X                        auditmsg = {auditbuf, 0, -2, A_REVERSE};
  922. X
  923. Xstatic DMMMESGBLK       plswaitmsgblk = {&plswaitmsg, 0},
  924. X                        auditmsgblk = {&auditmsg, 0};
  925. X
  926. X
  927. XDMMAUDITRETURN
  928. Xgiveupaudit(value)
  929. Xchar                   *value;
  930. X{
  931. X    if (*value == 'y' || *value == 'Y')
  932. X    return dmmAuditReturnOkay;
  933. X    if (*value != 'n' && *value == 'N')
  934. X    return dmmAuditBad;
  935. X    return dmmAuditOkay;
  936. X}
  937. X
  938. XDMMAUDITRETURN
  939. XauditPasswd(value)
  940. Xchar                   *value;        /* unused but required */
  941. X{
  942. X    return dmmAuditReturnOkay;
  943. X}
  944. X
  945. XDMMAUDITRETURN
  946. XauditUsername(username)
  947. Xchar                   *username;
  948. X{
  949. X    extern int              errno;
  950. X
  951. X    if (!*username)
  952. X    strcpy(auditbuf, "A user name must be specified");
  953. X    else
  954. X    return dmmAuditOkay;
  955. X    dmmPutMsgsNext(auditmsgblk);
  956. X    return dmmAuditBad;
  957. X}
  958. X
  959. X/* return 0 if user logs in correctly, else -1 */
  960. Xint
  961. Xlogin()
  962. X{
  963. X
  964. X    int                     retcode,
  965. X                            tries = 0;
  966. X    DMMSCREEN2              screen;
  967. X
  968. X    /* use the screen without give-up capabilities first time around */
  969. X    screen = loginscreen1;
  970. X    while (1) {
  971. X
  972. X    /* solicit login information */
  973. X    retcode = dmmRun(-1, screen, (DMMMENU2) 0, dmmNew, dmmInitVal);
  974. X    if (retcode == -1)
  975. X        return -1;
  976. X
  977. X    /* check if user wants to give up */
  978. X    if (*giveup == 'y' || *giveup == 'Y')
  979. X        return -1;
  980. X
  981. X    /* process login information in dummy fashion */
  982. X    dmmPutMsgs(plswaitmsgblk);
  983. X    sleep(2);
  984. X    if (tries++)
  985. X        return 0;
  986. X
  987. X    /* use the screen with give-up capabilities on  subsequent tries */
  988. X    screen = loginscreen2;
  989. X    }
  990. X}
  991. SHAR_EOF
  992. chmod 0444 dmmdemo2.c || echo "restore of dmmdemo2.c fails"
  993. set `wc -c dmmdemo2.c`;Sum=$1
  994. if test "$Sum" != "3637"
  995. then echo original size 3637, current size $Sum;fi
  996. echo "x - extracting dmmdemo3.c (Text)"
  997. sed 's/^X//' << 'SHAR_EOF' > dmmdemo3.c &&
  998. X#ifndef LINT
  999. Xstatic char     dmmdemo_3_c_id[] = {"@(#)dmmdemo3.c    1.1 \
  1000. XCopyright (c) 1991 Robert Bernardo, rob@mtdiablo.Concord.CA.US, \
  1001. Xan employee of Pande, Inc. \
  1002. XPermission to use granted only if this notice is not removed from \
  1003. Xthis source file nor from any binaries produced from it."};
  1004. X#endif
  1005. X#include <curses.h>
  1006. X#include "dmm.h"
  1007. X#include "dmmdemo.h"
  1008. X
  1009. X/* messages */
  1010. Xstatic DMMMESSAGE       month = {"January", 10, 2, A_REVERSE},
  1011. X                        days = {"S   M   T   W   T   F   S ", 5, 3, A_UNDERLINE},
  1012. X                        week1 = {"    1   2   3   4   5   6", 5, 4, 0},
  1013. X                        week2 = {"7   8   9   10  11  12  13", 5, 5, 0},
  1014. X                        week3 = {"14  15  16  17  18  19  20", 5, 6, 0},
  1015. X                        week4 = {"21  22  23  24  25  26  27", 5, 7, 0},
  1016. X                        week5 = {"28  29  30  31", 5, 8, 0};
  1017. X
  1018. Xstatic DMMMESGBLK       calendar = {&month, &days, &week1, &week2,
  1019. X&week3, &week4, &week5, 0};
  1020. X
  1021. X/* menu */
  1022. Xstatic DMMMENUITEM      jan = {"January", "Display calendar for January"},
  1023. X                        feb = {"February", "Display calendar for February"},
  1024. X                        mar = {"March", "Display calendar for March"},
  1025. X                        apr = {"April", "Display calendar for April"},
  1026. X                        may = {"May", "Display calendar for May"},
  1027. X                        jun = {"June", "Display calendar for June"},
  1028. X                        jul = {"July", "Display calendar for July"},
  1029. X                        aug = {"August", "Display calendar for August"},
  1030. X                        sep = {"September", "Display calendar for September"},
  1031. X                        oct = {"October", "Display calendar for October"},
  1032. X                        nov = {"November", "Display calendar for November"},
  1033. X                        dec = {"December", "Display calendar for December"};
  1034. X
  1035. Xstatic DMMMENU          menu = {&jan, &feb, &mar, &apr, &may, &jun,
  1036. X                &jul, &aug, &sep, &oct, &nov, &dec, 0};
  1037. X
  1038. X
  1039. X/* data screen */
  1040. X/* Notice that on the following fields, since they have no input part, only the
  1041. X * first three elements need be specified, letting the rest default to
  1042. X * zero, a feature of their being static
  1043. X */
  1044. Xstatic DMMFIELD         msg1 =
  1045. X{"Select any menu item; it doesn't matter which. A dummy calendar will be",
  1046. X0, 1, 0},
  1047. X
  1048. X                        msg2 =
  1049. X{"displayed. The source for this screen is in dmmdemo3.c. Note the following:",
  1050. X0, 2, 0},
  1051. X
  1052. X                        msg3 =
  1053. X{"1. The is a menu-only screen because the data fields have only",
  1054. XNUMBERCOL, 3, 0},
  1055. X
  1056. X                        msg4 =
  1057. X{"label parts and no input parts.",
  1058. XBODYCOL, 4, 0},
  1059. X
  1060. X                        msg5 =
  1061. X{"2. The menu is long enough to scroll. Notice that the end scrolls to the",
  1062. XNUMBERCOL, 5, 0},
  1063. X
  1064. X                        msg6 =
  1065. X{"beginning and vice versa.",
  1066. XBODYCOL, 6, 0},
  1067. X
  1068. X                        msg7 =
  1069. X{"3. The menu has some items with shared first letters and other items with",
  1070. XNUMBERCOL, 7, 0},
  1071. X
  1072. X                        msg8 =
  1073. X{"unique first letters by which they are selectable.",
  1074. XBODYCOL, 8, 0},
  1075. X
  1076. X                        msg9 =
  1077. X{"4. Messages lines can have a variety of attributes; see the calendar.",
  1078. XNUMBERCOL, 9, 0};
  1079. X
  1080. Xstatic DMMSCREEN        msgscreen = {&msg1, &msg2, &msg3, &msg4, &msg5,
  1081. X&msg6, &msg7, &msg8, &msg9, 0};
  1082. X
  1083. X
  1084. Xvoid
  1085. Xmonthmenu()
  1086. X{
  1087. X    dmmRun(-1, msgscreen, menu, dmmNew, dmmInitVal);
  1088. X    /* normally we'd process the return code of dmmRun() and learn the month
  1089. X     * that was selected from the menu and then display the proper calendar.
  1090. X     * But this is just a demo and we'll display the same calendar no matter
  1091. X     * what month was chosen. */
  1092. X    dmmClear();                /* remove data entry/display part of
  1093. X                     * screen */
  1094. X    dmmPutMsgsHit(calendar);        /* display calendar */
  1095. X    return;
  1096. X}
  1097. SHAR_EOF
  1098. chmod 0444 dmmdemo3.c || echo "restore of dmmdemo3.c fails"
  1099. set `wc -c dmmdemo3.c`;Sum=$1
  1100. if test "$Sum" != "3773"
  1101. then echo original size 3773, current size $Sum;fi
  1102. echo "x - extracting dmmdemo4.c (Text)"
  1103. sed 's/^X//' << 'SHAR_EOF' > dmmdemo4.c &&
  1104. X#ifndef LINT
  1105. Xstatic char     dmmdemo_4_c_id[] = {"@(#)dmmdemo4.c    1.1 \
  1106. XCopyright (c) 1991 Robert Bernardo, rob@mtdiablo.Concord.CA.US, \
  1107. Xan employee of Pande, Inc. \
  1108. XPermission to use granted only if this notice is not removed from \
  1109. Xthis source file nor from any binaries produced from it."};
  1110. X#endif
  1111. X#include "dmm.h"
  1112. X
  1113. X/* messages */
  1114. Xstatic DMMMESSAGE    msgA1 = 
  1115. X{"The source for this next set of messages is in dmmdemo4.c. It demonstrates",
  1116. X0, 0, 0},
  1117. X            msgA2 =
  1118. X{"various message display functions. This message is displayed with a call",
  1119. X0, 1, 0},
  1120. X            msgA3 =
  1121. X{"to dmmPutMsgsHit(), and will go away upon your next keystroke. After that",
  1122. X0, 2, 0},
  1123. X            msgA4 =
  1124. X{"a message will be displayed with dmmPutMsgsTimer for a few seconds. Then",
  1125. X0, 3, 0},
  1126. X            msgA5 =
  1127. X{"three short messages will be displayed. The last will be removed with",
  1128. X0, 4, 0},
  1129. X            msgA6 =
  1130. X{"a call to dmmRmMsgs(dmmRemoveLast), and then all messages will be removed",
  1131. X0, 5, 0},
  1132. X            msgA7 =
  1133. X{"with a call to dmmRmMsgs(dmmRemoveAll).",
  1134. X0, 6, 0},
  1135. X            msgB1 =
  1136. X{"This is the message displayed with dmmPutMsgsTimer() for a few seconds.",
  1137. X0, 1, 0},
  1138. X            msgC1 =
  1139. X{"This is the first of three messages.",
  1140. X0, 1, 0},
  1141. X            msgD1 =
  1142. X{"This is the second of three messages.",
  1143. X0, 3, 0},
  1144. X            msgE1 =
  1145. X{"This is the last of three messages.",
  1146. X0, 5, 0},
  1147. X            msgE2 =
  1148. X{"It will go away first, then all messages will be removed.",
  1149. X0, 6, 0};
  1150. X
  1151. Xstatic DMMMESGBLK    msgblkA = {&msgA1, &msgA2, &msgA3, &msgA4, &msgA5,
  1152. X                   &msgA6, &msgA7, 0},
  1153. X            msgblkB = {&msgB1, 0},
  1154. X            msgblkC = {&msgC1, 0},
  1155. X            msgblkD = {&msgD1, 0},
  1156. X            msgblkE = {&msgE1, &msgE2, 0};
  1157. X
  1158. Xvoid
  1159. Xmsgdemo()
  1160. X{
  1161. X    dmmPutMsgsHit(msgblkA);
  1162. X    dmmPutMsgsTimer(msgblkB, (unsigned)3);
  1163. X    dmmPutMsgs(msgblkC);
  1164. X    sleep(1);
  1165. X    dmmPutMsgs(msgblkD);
  1166. X    sleep(1);
  1167. X    dmmPutMsgs(msgblkE);
  1168. X    sleep(3);
  1169. X    dmmRmMsgs(dmmRemoveLast);
  1170. X    sleep(3);
  1171. X    dmmRmMsgs(dmmRemoveAll);
  1172. X    sleep(2);
  1173. X    return;
  1174. X}
  1175. SHAR_EOF
  1176. chmod 0444 dmmdemo4.c || echo "restore of dmmdemo4.c fails"
  1177. set `wc -c dmmdemo4.c`;Sum=$1
  1178. if test "$Sum" != "1886"
  1179. then echo original size 1886, current size $Sum;fi
  1180. echo "x - extracting dmmdemo5.c (Text)"
  1181. sed 's/^X//' << 'SHAR_EOF' > dmmdemo5.c &&
  1182. X#ifndef LINT
  1183. Xstatic char     dmmdemo_5_c_id[] = {"@(#)dmmdemo5.c    1.1 \
  1184. XCopyright (c) 1991 Robert Bernardo, rob@mtdiablo.Concord.CA.US, \
  1185. Xan employee of Pande, Inc. \
  1186. XPermission to use granted only if this notice is not removed from \
  1187. Xthis source file nor from any binaries produced from it."};
  1188. X#endif
  1189. X#include <ctype.h>
  1190. X#include <curses.h>
  1191. X#include "dmm.h"
  1192. X#include "dmmdemo.h"
  1193. X
  1194. X#define            MONTHLEN     2
  1195. X#define            DAYLEN         2
  1196. X#define            YEARLEN     2
  1197. X#define            MONTHCOL     10
  1198. X#define            DAYCOL        (MONTHCOL + MONTHLEN)
  1199. X#define            YEARCOL        (DAYCOL + DAYLEN + 1)
  1200. X#define            DATELINE    10
  1201. X
  1202. X/* messages */
  1203. Xstatic char             dayofweek[80];
  1204. X
  1205. Xstatic DMMMESSAGE    msgA1 =
  1206. X{"The source for the next screen (and these messages) is in dmmdemo5.c.",
  1207. X0, 0, 0},
  1208. X            msgA2 =
  1209. X{"That screen shows a fairly prototypical logic in processing of various",
  1210. X0, 1, 0},
  1211. X            msgA3 =
  1212. X{"return values and conditions.  The screen solicits a date from the user",
  1213. X0, 2, 0},
  1214. X            msgA4 =
  1215. X{"and the rest of the code simulates calculation of the day of the week of",
  1216. X0, 3, 0},
  1217. X            msgA5 =
  1218. X{"the date.",
  1219. X0, 4, 0},
  1220. X            msgA6 =
  1221. X{"Note the following:",
  1222. X0, 6, 0},
  1223. X            msgA7 =
  1224. X{"1. Look at the overall logic of the function calcdate().  It is a",
  1225. XNUMBERCOL, 7, 0},
  1226. X            msgA8 =
  1227. X{"forever loop with a single call to dmmRun().  Notice that some of",
  1228. XBODYCOL, 8, 0},
  1229. X            msgA9 =
  1230. X{"various arguments to dmmRun(), namely startfield, drawflag and",
  1231. XBODYCOL, 9, 0},
  1232. X            msgA10 =
  1233. X{"valflag, get set to different values on different iterations of",
  1234. XBODYCOL, 10, 0},
  1235. X            msgA11 =
  1236. X{"the forever loop according to various conditions.",
  1237. XBODYCOL, 11, 0},
  1238. X            msgB1 =
  1239. X{"2. dmmReview() is used to check the input field values after dmmRun()",
  1240. XNUMBERCOL, 0, 0},
  1241. X            msgB2 =
  1242. X{"returns.  This is needed because the default initial values of the",
  1243. XBODYCOL, 1, 0},
  1244. X            msgB3 =
  1245. X{"input fields are not valid values.  Notice how if dmmReview()",
  1246. XBODYCOL, 2, 0},
  1247. X            msgB4 =
  1248. X{"indicates an invalid field value, startfield, drawflag and valflag",
  1249. XBODYCOL, 3, 0},
  1250. X            msgB5 =
  1251. X{"are set to re-present the screen with the cursor in the offending",
  1252. XBODYCOL, 4, 0},
  1253. X            msgB6 =
  1254. X{"field. If dmmReview() shows that all field values are valid, the",
  1255. XBODYCOL, 5, 0},
  1256. X            msgB7 =
  1257. X{"day of the week is displayed as a message alongside the input fields,",
  1258. XBODYCOL, 6, 0},
  1259. X            msgB8 =
  1260. X{"which are still on the screen, and then the screen is redisplayed",
  1261. XBODYCOL, 7, 0},
  1262. X            msgB9 =
  1263. X{"afresh.",
  1264. XBODYCOL, 8, 0},
  1265. X            msgC1 =
  1266. X{"3. The three input fields have audit functions that return",
  1267. XNUMBERCOL, 0, 0},
  1268. X            msgC2 =
  1269. X{"dmmAuditReturnOkay so that dmmRun() returns for the surrounding",
  1270. XBODYCOL, 1, 0},
  1271. X            msgC3 =
  1272. X{"code to perform an inter-field audit. (The inter-field audit is here",
  1273. XBODYCOL, 2, 0},
  1274. X            msgC4 =
  1275. X{"only as an example. In a real program, it would be better not to have",
  1276. XBODYCOL, 3, 0},
  1277. X            msgC5 =
  1278. X{"the audit functions return dmmAuditReturnOkay, and just perform an",
  1279. XBODYCOL, 4, 0},
  1280. X            msgC6 =
  1281. X{"inter-field audit after dmmReview returns from verifying the validity",
  1282. XBODYCOL, 5, 0},
  1283. X            msgC7 =
  1284. X{"of the fields separately.) Notice how startfield, drawflag and valflag",
  1285. XBODYCOL, 6, 0},
  1286. X            msgC8 =
  1287. X{"are set if the inter-field audit fails and if it succeeds.",
  1288. XBODYCOL, 7, 0},
  1289. X            msgD1 =
  1290. X{"4. A negative line number is used for the error messages to place the",
  1291. XNUMBERCOL, 0, 0},
  1292. X            msgD2 =
  1293. X{"message a certain number of lines from the bottom. Notice that it is ",
  1294. XBODYCOL, 1, 0},
  1295. X            msgD3 =
  1296. X{"placed so as not to conflict with the bottom lines used by the",
  1297. XBODYCOL, 2, 0},
  1298. X            msgD4 =
  1299. X{"instruction messages.",
  1300. XBODYCOL, 3, 0},
  1301. X            errormsg = {0, 0, -3, A_REVERSE},
  1302. X                        dayofweekmsg = {dayofweek, YEARCOL + 4, DATELINE, 0};
  1303. X
  1304. Xstatic DMMMESGBLK    msgblkA = {&msgA1, &msgA2, &msgA3, &msgA4, &msgA5,
  1305. X                   &msgA6, &msgA7, &msgA8, &msgA9, &msgA10,
  1306. X                   &msgA11, 0},
  1307. X            msgblkB = {&msgB1, &msgB2, &msgB3, &msgB4, &msgB5,
  1308. X                   &msgB6, &msgB7, &msgB8, &msgB9, 0},
  1309. X            msgblkC = {&msgC1, &msgC2, &msgC3, &msgC4, &msgC5,
  1310. X                   &msgC6, &msgC7, &msgC8, 0},
  1311. X            msgblkD = {&msgD1, &msgD2, &msgD3, &msgD4, 0},
  1312. X            errormsgblk = {&errormsg, 0},
  1313. X                        dayofweekmsgblk = {&dayofweekmsg, 0};
  1314. X
  1315. X/* menu */
  1316. Xstatic DMMMENUITEM      calcitem = {"Calculate", "Calculate day of week"},
  1317. X                        quititem = {"Quit", "Quit this part of demo program"};
  1318. X
  1319. Xstatic DMMMENU          menu = {&calcitem, &quititem, 0};
  1320. X
  1321. X/* fields and screen */
  1322. Xstatic char            *monthinstruct[] = {"Enter month as two digits", 
  1323. X               "An example of a multiline instruction", 0},
  1324. X                       *dayinstruct[] =
  1325. X               {"Enter day of months as two digits", 0},
  1326. X                       *yearinstruct[] = {"Enter year as two digits", 0};
  1327. X
  1328. Xextern DMMAUDITRETURN   monthaudit(),
  1329. X            dayaudit(),
  1330. X            yearaudit();
  1331. X
  1332. Xstatic char             monthbuf[MONTHLEN + 1],
  1333. X                        daybuf[DAYLEN + 1],
  1334. X                        yearbuf[YEARLEN + 1];
  1335. X
  1336. Xstatic DMMFIELD         month = {0, 0, 0, 0, monthbuf, 0, MONTHCOL, DATELINE,
  1337. X                MONTHLEN, 0, 0, 0, A_REVERSE, A_UNDERLINE,
  1338. X                monthinstruct, 0, monthaudit},
  1339. X
  1340. X                        day = {"/", DAYCOL, DATELINE, 0, daybuf, 0, -1,
  1341. X                DATELINE, DAYLEN, 0, 0, 0, A_REVERSE,
  1342. X                A_UNDERLINE, dayinstruct, 0, dayaudit},
  1343. X
  1344. X                        year = {"/", YEARCOL, DATELINE, 0, yearbuf, 0, -1,
  1345. X                DATELINE, YEARLEN, 0, 0, 0, A_REVERSE,
  1346. X                A_UNDERLINE, yearinstruct, 0, yearaudit};
  1347. X
  1348. Xstatic DMMSCREEN        screen = {&month, &day, &year, 0};
  1349. X
  1350. Xstatic int              daysinmonth[] =
  1351. X                {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  1352. Xstatic char            *daysofweek[] = {"Monday", "Tuesday", "Wednesday",
  1353. X                "Thursday", "Friday", "Saturday", "Sunday"};
  1354. X
  1355. Xvoid
  1356. Xcalcdate()
  1357. X{
  1358. X    int                     retcode,
  1359. X                            startfield = -1,
  1360. X                            dayint,
  1361. X                            monthint,
  1362. X                            yearint;
  1363. X    DMMDRAWFLAG             drawflag = dmmNew;
  1364. X    DMMVALFLAG              valflag = dmmInitVal;
  1365. X
  1366. X    dmmPutMsgsHit(msgblkA);
  1367. X    dmmPutMsgsHit(msgblkB);
  1368. X    dmmPutMsgsHit(msgblkC);
  1369. X    dmmPutMsgsHit(msgblkD);
  1370. X    while (1) {
  1371. X    if((retcode = dmmRun(startfield, screen, menu, drawflag, valflag))
  1372. X       == -1)
  1373. X        return;
  1374. X    dayint = atoi(daybuf);
  1375. X    monthint = atoi(monthbuf);
  1376. X    yearint = atoi(yearbuf);
  1377. X    if (dmmRetType == dmmMenu) {
  1378. X
  1379. X        /* user selected a menu item; if it was 'quit', return, else user
  1380. X         * wants day of week calculated */
  1381. X        if (retcode == 1)
  1382. X        /* user selected 'quit' menu item */
  1383. X        return;
  1384. X
  1385. X        /* audit input values before calculating day of week */
  1386. X        if ((retcode = dmmReview(screen)) == -1) {
  1387. X        /* all individual values okay - display day of week */
  1388. X        sprintf(dayofweek, "falls on a %s",
  1389. X            daysofweek[(dayint + monthint + yearint) % 7]);
  1390. X        dmmPutMsgsHit(dayofweekmsgblk);
  1391. X
  1392. X        /* redisplay fresh screen */
  1393. X        startfield = -1;
  1394. X        drawflag = dmmNew;
  1395. X        valflag = dmmInitVal;
  1396. X        } else {
  1397. X        /* bad input value -- go back to offending field of last
  1398. X         * screen for user to correct it */
  1399. X        startfield = retcode;
  1400. X        drawflag = dmmOld;
  1401. X        valflag = dmmEdVal;
  1402. X        }
  1403. X    } else {
  1404. X        /* an audit function must have returned - do the interfield audit
  1405. X         * that fits the input the user gave so far */
  1406. X        if ((*monthbuf && *daybuf) &&
  1407. X        ((*yearbuf && !validdayofmonthandyear(dayint, monthint, yearint))
  1408. X         || !validdayofmonth(dayint, monthint))) {
  1409. X        /* bad day of month */
  1410. X        startfield = 1;        /* index of day field */
  1411. X        drawflag = dmmOld;
  1412. X        valflag = dmmEdVal;
  1413. X        } else {
  1414. X        /* continue with appropriate field */
  1415. X        startfield = -1;
  1416. X        drawflag = dmmOld;
  1417. X        valflag = dmmEdVal;
  1418. X        }
  1419. X    }
  1420. X    }
  1421. X}
  1422. X
  1423. Xvaliddayofmonthandyear(dayofmonth, month, year)
  1424. Xint                     dayofmonth,    /* presumed between 1 and 31 */
  1425. X                        month,        /* presumed between 1 and 12 */
  1426. X                        year;        /* presumed between 0 and 99 */
  1427. X{
  1428. X    if ((dayofmonth > daysinmonth[month]) ||
  1429. X        ((dayofmonth == 29) && (month == 2) &&
  1430. X         (year % 4 != 0) || (year % 100 == 0))) {
  1431. X    errormsg.value = "Not that many days in that month";
  1432. X    dmmPutMsgsNext(errormsgblk);
  1433. X    return 0;
  1434. X    }
  1435. X    return 1;
  1436. X}
  1437. X
  1438. Xvaliddayofmonth(dayofmonth, month)
  1439. Xint                     dayofmonth,    /* presumed between 1 and 31 */
  1440. X                        month;        /* presumed between 1 and 12 */
  1441. X{
  1442. X    if (dayofmonth > daysinmonth[month]) {
  1443. X    errormsg.value = "Not that many days in that month";
  1444. X    dmmPutMsgsNext(errormsgblk);
  1445. X    return 0;
  1446. X    }
  1447. X    return 1;
  1448. X}
  1449. X
  1450. XDMMAUDITRETURN
  1451. Xmonthaudit(month)
  1452. Xchar                   *month;
  1453. X{
  1454. X    int                     monthint = atoi(month);
  1455. X
  1456. X    /* check for valid month */
  1457. X    if ((strlen(month) != MONTHLEN) || (monthint < 1) || (monthint > 12)) {
  1458. X    errormsg.value = "Month must be given as two digits, 01 through 12";
  1459. X    dmmPutMsgsNext(errormsgblk);
  1460. X    return dmmAuditBad;
  1461. X    }
  1462. X    /* need to check month against day of month */
  1463. X    return dmmAuditReturnOkay;
  1464. X}
  1465. X
  1466. XDMMAUDITRETURN
  1467. Xdayaudit(day)
  1468. Xchar                   *day;
  1469. X{
  1470. X    int                     dayint = atoi(day);
  1471. X
  1472. X    /* check for valid day of month */
  1473. X    if ((strlen(day) != DAYLEN) || (dayint < 1) || (dayint > 31)) {
  1474. X    errormsg.value = "Day must be given as two digits, 01 through 31";
  1475. X    dmmPutMsgsHit(errormsgblk);
  1476. X    return dmmAuditBad;
  1477. X    }
  1478. X    /* need to check day of month against month */
  1479. X    return dmmAuditReturnOkay;
  1480. X}
  1481. X
  1482. XDMMAUDITRETURN
  1483. Xyearaudit(year)
  1484. Xchar                   *year;
  1485. X{
  1486. X    /* check for valid year */
  1487. X    if ((strlen(year) != YEARLEN) || (!isdigit(*year)) || (!isdigit(*(year + 1)))) {
  1488. X    errormsg.value = "Year must be given as two digits, 00 through 99";
  1489. X    dmmPutMsgsNext(errormsgblk);
  1490. X    return dmmAuditBad;
  1491. X    }
  1492. X    return dmmAuditReturnOkay;
  1493. X}
  1494. SHAR_EOF
  1495. chmod 0444 dmmdemo5.c || echo "restore of dmmdemo5.c fails"
  1496. set `wc -c dmmdemo5.c`;Sum=$1
  1497. if test "$Sum" != "9605"
  1498. then echo original size 9605, current size $Sum;fi
  1499. echo "x - extracting dmmdemo6.c (Text)"
  1500. sed 's/^X//' << 'SHAR_EOF' > dmmdemo6.c &&
  1501. X#ifndef LINT
  1502. Xstatic char     dmmdemo_6_c_id[] = {"@(#)dmmdemo6.c    1.1 \
  1503. XCopyright (c) 1991 Robert Bernardo, rob@mtdiablo.Concord.CA.US, \
  1504. Xan employee of Pande, Inc. \
  1505. XPermission to use granted only if this notice is not removed from \
  1506. Xthis source file nor from any binaries produced from it."};
  1507. X#endif
  1508. X#include <curses.h>
  1509. X#include "dmm.h"
  1510. X#include "dmmdemo.h"
  1511. X
  1512. X/* messages */
  1513. Xstatic DMMMESSAGE    infomsg1 =
  1514. X{"The source for the next screen (and these messages) is in dmmdemo6.c.",
  1515. X0, 0, 0},
  1516. X            infomsg2 =
  1517. X{"Note the following:",
  1518. X0, 1, 0},
  1519. X            infomsg3 =
  1520. X{"1. The first screen has one input field that spans more than one line.",
  1521. XNUMBERCOL, 2, 0},
  1522. X            infomsg4 =
  1523. X{"This is achieved by having the inputMaxcols datum in the",
  1524. XBODYCOL, 3, 0},
  1525. X            infomsg5 =
  1526. X{"DMMFIELD structure be non-zero and less than the inputLength",
  1527. XBODYCOL, 4, 0},
  1528. X            infomsg6 =
  1529. X{"datum. Play around with the arrow keys.",
  1530. XBODYCOL, 5, 0},
  1531. X            infomsg7 =
  1532. X{"2. The second screen is like the first, except that a line number is",
  1533. XNUMBERCOL, 6, 0},
  1534. X            infomsg8 =
  1535. X{"put out of range. Since the screen cannot be displayed as indicated",
  1536. XBODYCOL, 7, 0},
  1537. X            infomsg9 =
  1538. X{"by the DMMSCREEN data, dmmRun() displays a diagnostic message and",
  1539. XBODYCOL, 8, 0},
  1540. X            infomsg10 =
  1541. X{"returns -1. Notice how dmmGetNumLines() can be used to ascertain",
  1542. XBODYCOL, 9, 0},
  1543. X            infomsg11 =
  1544. X{"the number of lines available in the data entry window.",
  1545. XBODYCOL, 10, 0},
  1546. X            infomsg12 =
  1547. X{"This is the last part of the demonstration.",
  1548. X0, 12, 0};
  1549. X
  1550. Xstatic DMMMESGBLK    infomsgblk = {&infomsg1, &infomsg2, &infomsg3,
  1551. X                      &infomsg4, &infomsg5, &infomsg6,
  1552. X                      &infomsg7, &infomsg8, &infomsg9,
  1553. X                      &infomsg10, &infomsg11, &infomsg12, 0};
  1554. X
  1555. X/* menu */
  1556. Xstatic DMMMENUITEM      mailit = {"Mail", "Mail comment to administrator"},
  1557. X                        dontmailit = {"Quit", "Quit this part of demo program"};
  1558. X
  1559. Xstatic DMMMENU          menu = {&mailit, &dontmailit, 0};
  1560. X
  1561. X/* fields and screen */
  1562. Xstatic char            *commentinstruct[] = {"Enter comment for administrator",
  1563. X               0};
  1564. X
  1565. X#define COMMENTSIZE    700
  1566. Xstatic char             commentbuf[COMMENTSIZE + 1];
  1567. X
  1568. Xstatic DMMFIELD         comment = {"Comment", 10, 0, 0, commentbuf, 0, 10, 2,
  1569. X                COMMENTSIZE, 60, 0, 0, A_REVERSE, A_REVERSE,
  1570. X                commentinstruct, 0, 0};
  1571. X
  1572. Xstatic DMMSCREEN        screen = {&comment, 0};
  1573. X
  1574. Xvoid
  1575. Xgetcomment()
  1576. X{
  1577. X    int                     numlines;
  1578. X
  1579. X    dmmPutMsgsHit(infomsgblk);
  1580. X    dmmRun(-1, screen, menu, dmmNew, dmmInitVal);
  1581. X    numlines = dmmGetNumLines();
  1582. X    comment.labelLine = numlines;
  1583. X    dmmRun(-1, screen, menu, dmmNew, dmmInitVal);
  1584. X    return;
  1585. X}
  1586. SHAR_EOF
  1587. chmod 0444 dmmdemo6.c || echo "restore of dmmdemo6.c fails"
  1588. set `wc -c dmmdemo6.c`;Sum=$1
  1589. if test "$Sum" != "2582"
  1590. then echo original size 2582, current size $Sum;fi
  1591. rm -f s2_seq_.tmp
  1592. echo "You have unpacked the last part"
  1593. exit 0
  1594. -- 
  1595. Rob Bernardo                    Mt. Diablo Software Solutions
  1596. email: rob@mtdiablo.Concord.CA.US        phone: (415) 827-4301
  1597.