DMM (Data entry and Menu screen Manager) - version 1.1 part 2/2

Rob Bernardo rob at mtdiablo.Concord.CA.US
Tue Jun 18 11:24:19 AEST 1991


#!/bin/sh
# this is part 2 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file dmm.c continued
#
CurArch=2
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file dmm.c"
sed 's/^X//' << 'SHAR_EOF' >> dmm.c
X    return;
X}
X
X
X/* This replaces the standard curses overlay(), which is broken:
X * it does not preserve the attributes of the copied characters
X */
Xstatic void
XoverLay (srcWin, dstWin)
XWINDOW         *srcWin,
X               *dstWin;
X{
X    register int    x,
X                    y;
X    register chtype mychar;
X    for (y = 0; y < srcWin->_maxy; y++) {
X	for (x = 0; x < srcWin->_maxx; x++) {
X	    mychar = mvwinch (srcWin, y, x);
X	    if (((mychar & A_CHARTEXT) != ' ')
X		|| ((mychar & A_ATTRIBUTES) != A_NORMAL))
X		mvwinsch (dstWin, y, x, mychar);
X	}
X    }
X    return;
X}
X
X
X
X/* fieldMgr()	manage user interactions with the field window;
X *		start by first positioning in the infput field
X *		designated by fldNum; if fldNum is -1, use the
X *		default input field, determined from the last
X *		call to this function;
X *		set the default field for use in the next call to
X *		this function before returning.
X *		return -1 if the user wants to leave for the menu;
X *		else return the field number of a field if the
X *		audit routine for that field returns dmmAuditReturnOkay
X *		or dmmAuditReturnBad, which means that the screen 
X *		handler must return to the application software;
X */
Xstatic int
XfieldMgr (fldNum)
Xregister int    fldNum;
X{
X    register int    curCol,	/* current column number in field */
X                    curLine,	/* current line number in field */
X                    curChar;	/* current char position in field */
X    enum change     delta;	/* what to do upon user input keystroke */
X    int             key,	/* user's input keystroke */
X                    len;	/* length of field being manipulated */
X    static          dfltInputFld;	/* default field for next call */
X    char           *instructMesg;	/* message for instruct line */
X
X    /* display general instructions about how to go to menu */
X    if (numMenuItems)
X	instructMesg = GOTO_MENU_INSTRUCT;
X    else
X	instructMesg = NULL_MENU_INSTRUCT;
X    dispInstruct (instructMesg);
X
X    /* first field: instruction and attribute */
X    fldNum = (fldNum == -1) ? dfltInputFld : fldNum;
X    arriveInField (dupeScreen[fldNum]);
X
X    /* separate parts of refresh for sake of dispInstruct() above */
X    wnoutrefresh (fieldWin);
X    doupdate ();
X
X    /* add messages as needed */
X    if (needAddMsgs) {
X	overwrite (fieldWin, fieldWinPreMsg);
X	overLay (mesgWin, fieldWin);
X    }
X    /* position cursor in appropriate field */
X    (void) chgInField (fldNum, stayput);
X    curCol = curLine = curChar = 0;
X
X    /* process user input */
X    while (1) {
X	delta = stayput;	/* default is no chg in field/cursor pos. Any
X				 * of the below choices that change the
X				 * screen but stayput need to do their own
X				 * wrefresh() */
X
X	switch (key = wGetCh (fieldWin)) {
X
X	case CTRL (h):
X	    /* display help */
X	    doPutMsgsHit (helpMsgVec, 1);
X	    break;
X
X	case CTRL (g):
X	    /* submit screen as is; set default field to current field and go
X	     * to menu
X	     */
X	    adjustFld (dupeScreen[fldNum]);
X	    leaveInField (dupeScreen[dfltInputFld = fldNum]);
X	    return -1;
X
X	case CTRL (c):
X	    /* clear to end of field, audit, move to next field */
X	    for (len = dupeScreen[fldNum]->inputLength;
X		 curChar < len; curChar++)
X		dupeScreen[fldNum]->inputEditValue[curChar] = '\0';
X	    dispInField (dupeScreen[fldNum],
X			 dupeScreen[fldNum]->inputEditAttrib);
X	    delta = next;
X	    break;
X
X	case RETURN:
X	case TAB:
X	case CTRL (n):
X	    /* audit and move to next field */
X	    delta = next;
X	    break;
X
X	case CTRL (p):
X	    /* audit and move to previous field */
X	    delta = previous;
X	    break;
X
X	case CTRL (r):
X	    /* redraw screen */
X	    redraw ();
X	    break;
X
X	case KEY_LEFT:
X	    /* move cursor to left if possible */
X	    if (curCol) {
X		curCol--;
X		curChar--;
X		delta = movecursor;
X	    } else
X		flash();
X	    break;
X
X	case KEY_RIGHT:
X	    /* move cursor to right if possible */
X	    if (((curLine < dupeScreen[fldNum]->inputFullLines) &&
X		 (curCol + 1 < dupeScreen[fldNum]->inputMaxCols)) ||
X		(curCol + 1 < dupeScreen[fldNum]->inputShortCols)) {
X		curCol++;
X		curChar++;
X		delta = movecursor;
X	    } else
X		flash();
X	    break;
X
X	case KEY_UP:
X	    /* move cursor up if possible */
X	    if (curLine != 0) {
X		curLine--;
X		curChar -= dupeScreen[fldNum]->inputMaxCols;
X		delta = movecursor;
X	    } else
X		flash();
X	    break;
X
X	case KEY_DOWN:
X	    /* move cursor down if possible */
X	    if ((curLine + 1 < dupeScreen[fldNum]->inputFullLines) ||
X		((curLine + 1 == dupeScreen[fldNum]->inputFullLines) &&
X		 (curCol < dupeScreen[fldNum]->inputShortCols))) {
X		curLine++;
X		curChar += dupeScreen[fldNum]->inputMaxCols;
X		delta = movecursor;
X	    } else
X		flash();
X	    break;
X
X	case DELETE:
X	    /* erase character to left of cursor and move cursor left,
X	     * except if we are in last character position and last
X	     * character is not a space, then erase last character
X	     * and don't move cursor.
X	     * Obviously, erase nothing if we are in the first character
X	     * position last is not also a last character position.
X	     */
X	    if((curChar + 1 == dupeScreen[fldNum]->inputLength) &&
X	       (dupeScreen[fldNum]->inputEditValue[curChar] != ' ')) {
X
X	       /* erase last character internally */
X		dupeScreen[fldNum]->inputEditValue[curChar] = ' ';
X
X	    } else {
X
X		/* do nothing if we are in the first character position
X		 * which is not also the last character position */
X		if (!curChar) {
X		    flash();
X		    break;
X		}
X
X		/* erase last character internally */
X		dupeScreen[fldNum]->inputEditValue[--curChar] = ' ';
X
X		/* retreat the cursor */
X		if (curCol)
X		    curCol--;
X		else {
X		    curLine--;
X		    curCol = dupeScreen[fldNum]->inputMaxCols - 1;
X		}
X	    }
X
X	    /* display space on screen */
X	    DMMWATTRON (fieldWin, dupeScreen[fldNum]->inputEditAttrib);
X	    mvwaddch (fieldWin,
X		      dupeScreen[fldNum]->inputLine + curLine,
X		      dupeScreen[fldNum]->inputCol + curCol, ' ');
X	    DMMWATTROFF (fieldWin, dupeScreen[fldNum]->inputEditAttrib);
X
X	    delta = movecursor;
X	    break;
X
X	default:
X	    /* process only if a printing character */
X	    if (isascii (key) && isprint (key)) {
X
X		/* display character, or if A_INVIS  display space */
X		DMMWATTRON (fieldWin, dupeScreen[fldNum]->inputEditAttrib);
X		mvwaddch (fieldWin,
X			  dupeScreen[fldNum]->inputLine + curLine,
X			  dupeScreen[fldNum]->inputCol + curCol,
X			  (dupeScreen[fldNum]->inputEditAttrib & A_INVIS) ?
X			  ' ' : (char) key);
X		DMMWATTROFF (fieldWin, dupeScreen[fldNum]->inputEditAttrib);
X
X		/* store internally */
X		dupeScreen[fldNum]->inputEditValue[curChar] = (char) key;
X
X		/* if not at end of field, move cursor */
X		if (curChar + 1 < dupeScreen[fldNum]->inputLength) {
X		    /* either move to next col in same line or first col of
X		     * next line
X		     */
X		    curChar++;
X		    if (((curLine < dupeScreen[fldNum]->inputFullLines) &&
X			 (curCol + 1 < dupeScreen[fldNum]->inputMaxCols)) ||
X			(curCol + 1 < dupeScreen[fldNum]->inputShortCols))
X			curCol++;
X		    else {
X			curCol = 0;
X			curLine++;
X		    }
X		    delta = movecursor;
X		}
X	    } else
X		flash ();
X	    break;
X	}
X
X	/* now check if cursor position of field is to be changed */
X	switch (delta) {
X
X	case next:
X	case previous:
X	    /* advance or retreat a field */
X
X	    /* remove trailing blanks and internal nulls */
X	    adjustFld (dupeScreen[fldNum]);
X
X	    /* audit field */
X	    if (dupeScreen[fldNum]->inputAudit) {
X
X		switch (dupeScreen[fldNum]->inputAudit 
X		        (dupeScreen[fldNum]->inputEditValue)) {
X
X		case dmmAuditReturnOkay:
X		    /* must leave screen handler; first show any changes to
X		     * field value and set default field according to user's
X		     * last keystroke
X		     */
X		    dmmRetType = dmmOkayField;
X		    leaveInField (dupeScreen[fldNum]);
X		    wrefresh (fieldWin);
X		    dfltInputFld = delta == next ?
X			dupeScreen[fldNum]->nextInField :
X			dupeScreen[fldNum]->prevInField;
X		    return fldNum;
X
X		case dmmAuditReturnBad:
X		    /* must leave screen handler; first show any changes to
X		     * field value and set default field according to user's
X		     * last keystroke
X		     */
X		    dmmRetType = dmmBadField;
X		    leaveInField (dupeScreen[fldNum]);
X		    wrefresh (fieldWin);
X		    dfltInputFld = delta == next ?
X			dupeScreen[fldNum]->nextInField :
X			dupeScreen[fldNum]->prevInField;
X		    return fldNum;
X
X		case dmmAuditBad:
X		    /* failed; stay in this field */
X		    delta = stayput;
X		    break;
X
X		case dmmAuditOkay:
X		    /* audit okay; go to another field */
X		    break;
X		}
X	    }
X
X	    /* show any changes to field value */
X	    fldNum = chgInField (fldNum, delta);
X	    curCol = curLine = curChar = 0;
X	    wrefresh (fieldWin);
X	    break;
X
X	case stayput:
X	case movecursor:
X	    /* move cursor to current column and line position in current
X	     * input field as just set or left as was
X	     */
X	    wmove (fieldWin, dupeScreen[fldNum]->inputLine + curLine,
X		   dupeScreen[fldNum]->inputCol + curCol);
X	    wrefresh (fieldWin);
X	    break;
X	}
X    }
X}
X 
X
X/* leaveMenu()	leave menu;
X *		if menuitem is < 0, erase whole menu,
X * 		else unhighlight indicated item
X */
Xstatic void
XleaveMenu (itemNum)
Xint             itemNum;
X{
X    if (itemNum < 0) {
X	wclear (menuWin);
X	wnoutrefresh (menuWin);
X    } else
X	dispMenuPage (itemNum, 0, 0);
X    return;
X}
X
X
X/* menuMgr		manage user interactions with the menu window;
X *			return the number of the menu item selected
X *			or -1 if the user wants to leave the menu without
X *			a selection.
X */
Xstatic int
XmenuMgr ()
X{
X    int             key;
X
X    /* display the current page of the menu with the current item highlighted */
X    dispMenuPage (curMenuItem, 1, 1);
X
X    /* display general menu instruction */
X    dispInstruct (MENU_INSTRUCT);
X
X    /* add messages as needed */
X    if (needAddMsgs) {
X	overwrite (fieldWin, fieldWinPreMsg);
X	overLay (mesgWin, fieldWin);
X	wnoutrefresh (fieldWin);
X    }
X
X    /* process user input */
X    while (1) {
X
X	/* refresh instruct and menu page on screen, as needed */
X	outOfTheWay();
X	doupdate ();
X
X	switch (key = wGetCh (menuWin)) {
X
X	case CTRL (h):
X	    /* display help */
X	    doPutMsgsHit (helpMsgVec, 1);
X	    break;
X
X	case CTRL (r):
X	    /* redraw screen */
X	    redraw ();
X	    break;
X
X	case CTRL (g):
X	    /* leave menu for input part of screen */
X	    leaveMenu (curMenuItem);
X	    return -1;
X
X	case RETURN:
X	    /* submit this choice */
X	    leaveMenu (-1);
X	    return curMenuItem;
X
X	case TAB:
X	case CTRL (n):
X	    /* move to next item */
X	    if (++curMenuItem >= numMenuItems)
X		curMenuItem = 0;
X	    dispMenuPage (curMenuItem, 1, 0);
X	    break;
X
X	case CTRL (p):
X	    /* move to previous item */
X	    if (--curMenuItem < 0)
X		curMenuItem = numMenuItems - 1;
X	    dispMenuPage (curMenuItem, 1, 0);
X	    break;
X
X	default:
X	    /* find single menu item with matching first character */
X	    if (isascii (key) && isalpha (key)) {
X		if (isupper (key))
X		    key = tolower (key);
X		if (menuIndex[key - 'a'] >= 0) {
X		    dispMenuPage (curMenuItem = menuIndex[key - 'a'], 1, 0);
X		    break;
X		}
X	    }
X	    flash ();
X	    break;
X	}
X    }
X}
X
X
X/* dmmRun	manage menu and data entry screen - see man page for fuller
X *		description
X */
Xint
XdmmRun (startField, screen, menu, dmmDrawFlag, dmmValFlag)
Xint             startField;
XDMMDRAWFLAG     dmmDrawFlag;
XDMMVALFLAG      dmmValFlag;
XDMMSCREEN       screen;
XDMMMENU         menu;
X{
X    int             itemNum;	/* menu or field number */
X    void            (*oldSignalValue) ();	/* current state for signal
X						 * SIGALRM */
X
X    /* copy parameters to global variables */
X    dupeScreen = screen;
X    dupeMenu = menu;
X
X    /* initialize windows if needed */
X    if (!isOpen)
X	dmmInit ();
X
X    /* get rid of type-ahead input */
X    flushinp ();
X
X    /* process dmmDrawFlag */
X    switch (dmmDrawFlag) {
X
X    case dmmNew:
X
X	/* the first display of a screen - do initial layout calculations */
X	if (layout ())
X	    return -1;
X
X	/* determine field for cursor */
X	if (startField == -1)
X	    startField = firstInputFld;
X
X	/* do sanity checking */
X	if (insane (startField))
X	    return -1;
X
X	/* display screen */
X	redraw ();
X
X	break;
X
X
X    case dmmOld:
X	/* restore saved screen and redisplay menu with first item
X	 * highlighted; let a -1 startField stand - fieldMgr() will
X	 * interpret it to mean the last input field saved on the last call
X	 * of dmmRun().
X	 */
X
X	/* This overwrite gets rid of any messages displayed by
X	 * dmmPutMsgsNext(), and so the needAddMsgs flag is used to get them
X	 * reinstated in fieldMgr() and menuMgr().
X	 */
X	overwrite (fieldWinCopy, fieldWin);
X	redraw ();
X	if (dupeMenu)
X	    dispMenuPage (0, 0, 1);
X	break;
X
X    }
X
X    /* copy inputInitValue's if indicated by dmmValFlag */
X    if (dmmValFlag == dmmInitVal)
X	copyInFields ();
X
X    /* process user input */
X
X    /* ignore SIGALRM to avoid a bug in wgetch() that fails to cancel an
X     * alarm() it sets after unsetting the catching of SIGALRM; this must be
X     * reset to current value before returning.
X     */
X    oldSignalValue = signal (SIGALRM, SIG_IGN);
X
X    interactive = 1;
X
X    while (1) {
X
X	/* manage fields with input parts, if any */
X	if (numInputParts) {
X	    if ((itemNum = fieldMgr (startField)) != -1)
X		break;
X	    startField = itemNum;
X	}
X
X	/* manage menu items, if any */
X	if (numMenuItems) {
X	    if ((itemNum = menuMgr ()) != -1) {
X		dmmRetType = dmmMenu;
X		break;
X	    }
X	    doupdate ();
X	}
X    }
X
X    /* remove instruction and update screen */
X    dispInstruct ("");
X    doupdate ();
X
X    /* save copy of screen for restoral with dmmOld option */
X    overwrite (fieldWin, fieldWinCopy);
X
X    /* undo ignoring of alarm signal */
X    (void) signal (SIGALRM, oldSignalValue);
X
X    interactive = 0;
X
X    return itemNum;
X}
SHAR_EOF
echo "File dmm.c is complete"
chmod 0444 dmm.c || echo "restore of dmm.c fails"
set `wc -c dmm.c`;Sum=$1
if test "$Sum" != "44980"
then echo original size 44980, current size $Sum;fi
echo "x - extracting dmm.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > dmm.h &&
X#ifndef LINT
Xstatic char dmm_h_id[] = {"@(#)dmm.h	1.1 \
XCopyright (c) 1991 Robert Bernardo, rob at mtdiablo.Concord.CA.US, \
Xan employee of Pande, Inc. \
XPermission  to use granted only if this notice is not removed from \
Xthis source file nor from any binaries produced from it."};
X
X#endif
X
X/* data display and entry field descriptor */
Xtypedef struct dmmField {
X    char                   *labelValue;
X    int                     labelCol,
X                            labelLine;
X    long                    labelAttrib;
X    char                   *inputEditValue,
X                           *inputInitValue;
X    int                     inputCol,
X                            inputLine,
X                            inputLength,
X                            inputMaxCols,
X                            inputFullLines,
X                            inputShortCols;
X    long                    inputAttrib,
X                            inputEditAttrib;
X    char                  **inputInstructVec;
X    int                     inputNumInstructs;
X    enum dmmAuditReturn     (*inputAudit) ();
X    int                     nextInField,
X                            prevInField;
X}                       DMMFIELD, *DMMSCREEN[], **DMMSCREEN2;
X
X/* menu item descriptor */
Xtypedef struct dmmMenuItem {
X    char                   *label,
X                           *descript;
X    int                     col,
X                            page;
X}                       DMMMENUITEM, *DMMMENU[], **DMMMENU2;
X
X/* message descriptor */
Xtypedef struct dmmMessage {
X    char                   *value;
X    int                     col,
X                            line;
X    long                    attrib;
X}                       DMMMESSAGE, *DMMMESGBLK[], **DMMMESGBLK2;
X
X/* return values for inputAudit() */
Xtypedef enum dmmAuditReturn {
X    dmmAuditOkay, dmmAuditBad, dmmAuditReturnOkay, dmmAuditReturnBad
X}                       DMMAUDITRETURN;
X
X/* DrawFlag values */
Xtypedef enum dmmDrawFlag {
X    dmmNew, dmmOld
X}                       DMMDRAWFLAG;
X
X/* ValFlag values */
Xtypedef enum dmmValFlag {
X    dmmInitVal, dmmEdVal
X}                       DMMVALFLAG;
X
X/* dmmRetType values */
Xtypedef enum dmmRetType {
X    dmmOkayField, dmmBadField, dmmMenu
X}                       DMMRETTYPE;
X
X/* dmmRemoveType values */
Xtypedef enum dmmRemoveType {
X    dmmRemoveAll, dmmRemoveLast
X}                       DMMREMOVETYPE;
X
Xextern enum dmmRetType  dmmRetType;
Xextern void             dmmPutMsgs(),
X                        dmmPutMsgsTimer(),
X                        dmmPutMsgsHit(),
X                        dmmPutMsgsNext(),
X                        dmmRmMsgs(),
X                        dmmInit(),
X                        dmmClear(),
X                        dmmClose();
X
X#ifndef A_INVIS
X#define A_INVIS         000020000000L
X#endif
SHAR_EOF
chmod 0444 dmm.h || echo "restore of dmm.h fails"
set `wc -c dmm.h`;Sum=$1
if test "$Sum" != "2793"
then echo original size 2793, current size $Sum;fi
echo "x - extracting dmmdemo.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > dmmdemo.h &&
X#ifndef LINT
Xstatic char dmmdemo_h_id[] = {"@(#)dmmdemo.h	1.1 \
XCopyright (c) 1991 Robert Bernardo, rob at mtdiablo.Concord.CA.US, \
Xan employee of Pande, Inc. \
XPermission  to use granted only if this notice is not removed from \
Xthis source file nor from any binaries produced from it."};
X#endif
X
X#define NUMBERCOL 5
X#define BODYCOL (NUMBERCOL + 3)
X
Xextern void             calcdate(),
X			msgdemo(),
X			getcomment(),
X			monthmenu();
SHAR_EOF
chmod 0444 dmmdemo.h || echo "restore of dmmdemo.h fails"
set `wc -c dmmdemo.h`;Sum=$1
if test "$Sum" != "432"
then echo original size 432, current size $Sum;fi
echo "x - extracting dmmdemo1.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > dmmdemo1.c &&
X#ifndef LINT
Xstatic char     dmmdemo_1_c_id[] = {"@(#)dmmdemo1.c	1.1 \
XCopyright (c) 1991 Robert Bernardo, rob at mtdiablo.Concord.CA.US, \
Xan employee of Pande, Inc. \
XPermission to use granted only if this notice is not removed from \
Xthis source file nor from any binaries produced from it."};
X#endif
X#include <curses.h>
X#include "dmm.h"
X#include "dmmdemo.h"
X
X/* messages */
Xstatic DMMMESSAGE       intro1 =
X{"Welcome to the DMM demonstration program. This program will use DMM",
X0, 0, 0},
X
X                        intro2 =
X{"functions to present a variety of screens. For each screen, it will",
X0, 1, 0},
X
X                        intro3 =
X{"state the associated source file and list its salient features.",
X0, 2, 0},
X
X                        intro4 =
X{"The source for this screen is in dmmdemo1.c.",
X0, 4, 0},
X
X                        intro5 =
X{"1. It has just called dmmInit() to start up curses (putting the",
XNUMBERCOL, 5, 0},
X
X                        intro6 =
X{"terminal into raw mode, etc.) and to initialize the DMM windows.",
XBODYCOL, 6, 0},
X
X                        intro7 =
X{"2. This block of messages is displayed with a call do dmmPutMsgsHit().",
XNUMBERCOL, 7, 0},
X
X                        intro8 =
X{"Notice the top line if this screen. After the next message, you",
XBODYCOL, 8, 0},
X
X                        intro9 =
X{"will be presented with a menuless screen. The top line always has",
XBODYCOL, 9, 0},
X
X                        intro10 =
X{"an appropriate general instruction when a call to dmmRun() presents",
XBODYCOL, 10, 0},
X
X                        intro11 =
X{"a screen. Pay attention to it throughout this demo. Remember that",
XBODYCOL, 11, 0},
X
X                        intro12 =
X{"control-H displays a useful help screen during a dmmRun() call.",
XBODYCOL, 12, 0},
X
X                        intro13 =
X{"The source for the menuless screen is in dmmdemo2.c Enter any log name",
X0, 0, 0},
X
X                        intro14 =
X{"and any password; it doesn't matter. The simulated login procedure is",
X0, 1, 0},
X
X                        intro15 =
X{"hardcoded to reject them the first time and succeed the second, so you",
X0, 2, 0},
X
X                        intro16 =
X{"will need to try a second time. Next time you run this program, enter 'y'",
X0, 3, 0},
X
X                        intro17 =
X{"to the \"give up\" question and see what happens.",
X0, 4, 0},
X
X                        intro18 =
X{"Note the following:",
X0, 6, 0},
X
X                        intro19 =
X{"1. Negative column numbers are used to separate the labels from the",
XNUMBERCOL, 7, 0},
X
X                        intro20 =
X{"input areas by a certain number of blank spaces.",
XBODYCOL, 8, 0},
X
X                        intro21 =
X{"2. The audit functions for the \"give up\" (if you enter 'y') and ",
XNUMBERCOL, 9, 0},
X
X                        intro22 =
X{"\"password\" fields return values that cause dmmRun() to return. Because ",
XBODYCOL, 10, 0},
X
X                        intro23 =
X{"this is a menuless screen and  no menu selection can be made, such is",
XBODYCOL, 11, 0},
X
X                        intro24 =
X{"necessary so that dmmRun() doesn't just go on indefinitely.",
XBODYCOL, 12, 0},
X
X                        intro25 =
X{"3. See how the data type DMMSCREEN2 is used for a pointer.",
XNUMBERCOL, 13, 0},
X
X                        intro26 =
X{"4. Data entered into the password field is invisible.",
XNUMBERCOL, 14, 0},
X			sizemsg1 =
X{"The DMM demo requires your screen (or window) to have at least 24",
X0, 0, A_REVERSE},
X			sizemsg2 =
X{"lines and 80 columns.",
X0, 1, A_REVERSE},
X			byemsg =
X{"End of the DMM demonstration. Good bye.",
X0, 0, A_REVERSE};
X
X
X
X
Xstatic DMMMESGBLK       introA = {&intro1, &intro2, &intro3, &intro4, &intro5,
X				  &intro6, &intro7, &intro8, &intro9, &intro10,
X			          &intro11, &intro12, 0},
X
X                        introB = {&intro13, &intro14, &intro15, &intro16,
X				  &intro17, &intro18, &intro19, &intro20,
X				  &intro21, &intro22, &intro23, &intro24,
X				  &intro25, &intro26, 0},
X
X			requirements = {&sizemsg1, &sizemsg2, 0},
X
X			byemsgblk = {&byemsg, 0};
X
Xmain()
X{
X    dmmInit();				/* start up curses; init DMM windows  */
X    if((COLS < 80) || (LINES < 24)) { 	/* make sure screen is large enough */
X	dmmPutMsgsHit(requirements);
X	dmmClose();
X	exit(1);
X    }
X    
X    dmmPutMsgsHit(introA);		/* display a message until user hits
X					 * a key */
X    dmmPutMsgsHit(introB);
X    if (login() == 0) {			/* if login goes okay, do rest of
X					 * demo screens
X					 */
X	monthmenu();
X	msgdemo();
X	calcdate();
X	getcomment();
X    }
X    dmmPutMsgsTimer(byemsgblk, 2);
X    dmmClose();				/* shut down curses and DMM windows */
X    exit(0);
X}
SHAR_EOF
chmod 0444 dmmdemo1.c || echo "restore of dmmdemo1.c fails"
set `wc -c dmmdemo1.c`;Sum=$1
if test "$Sum" != "4642"
then echo original size 4642, current size $Sum;fi
echo "x - extracting dmmdemo2.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > dmmdemo2.c &&
X#ifndef LINT
Xstatic char     dmmdemo_2_c_id[] = {"@(#)dmmdemo2.c	1.1 \
XCopyright (c) 1991 Robert Bernardo, rob at mtdiablo.Concord.CA.US, \
Xan employee of Pande, Inc. \
XPermission to use granted only if this notice is not removed from \
Xthis source file nor from any binaries produced from it."};
X#endif
X#include <strings.h>
X#include <curses.h>
X#include "dmm.h"
X
X/* field sizes */
X#define USERNAMELEN 10
X#define PASSWDLEN 8
X#define YESNOLEN 1
X
X/* editable buffers */
Xstatic char             username[USERNAMELEN + 1],
X                        giveup[YESNOLEN + 1],
X                        passwd[PASSWDLEN + 1],
X                        auditbuf[80];
X
X/* instruction fields */
Xstatic char            *usernameinstr[] = {"Enter your user name", 0},
X                       *giveupinstr[] = {"Enter y or n", 0},
X                       *passwdinstr[] = {"Enter your password", 0};
X
X/* data fields */
X#define GIVEUPLINE	2
X#define LNSPACING	2
X#define LABELCOL	10
X#define USERNAMELINE	(GIVEUPLINE + LNSPACING)
X#define PASSWDLINE	(USERNAMELINE + LNSPACING)
X#define MSGLINE		(PASSWDLINE + LNSPACING)
Xextern DMMAUDITRETURN   giveupaudit(),
X			auditUsername(),
X			auditPasswd();
X
Xstatic DMMFIELD         giveupfld = {"Give up logging in?", LABELCOL,
X			    GIVEUPLINE, 0, giveup, "n", -2, GIVEUPLINE,
X			    YESNOLEN, 0, 0, 0, A_REVERSE, A_UNDERLINE,
X			    giveupinstr, 0, giveupaudit, 0},
X
X                        usernamefld = {"User name", LABELCOL,
X			    USERNAMELINE, 0, username, 0, -2,
X			    USERNAMELINE, USERNAMELEN, 0, 0, 0,
X			    A_REVERSE, A_UNDERLINE, usernameinstr,
X			    0, auditUsername, 0},
X
X                        passwdfld = {"Password", LABELCOL, PASSWDLINE, 0,
X			    passwd, 0, -2, PASSWDLINE,
X			    PASSWDLEN, 0, 0, 0, A_REVERSE | A_INVIS,
X			    A_UNDERLINE | A_INVIS, passwdinstr, 0,
X			    auditPasswd, 0};
X
X/* data field arrays */
Xstatic DMMSCREEN        loginscreen1 = {&usernamefld, &passwdfld, 0},
X                        loginscreen2 = {&giveupfld, &usernamefld, &passwdfld, 0};
X
X/* messages */
Xstatic DMMMESSAGE       plswaitmsg = {"Please wait", 0, 0, A_REVERSE},
X                        auditmsg = {auditbuf, 0, -2, A_REVERSE};
X
Xstatic DMMMESGBLK       plswaitmsgblk = {&plswaitmsg, 0},
X                        auditmsgblk = {&auditmsg, 0};
X
X
XDMMAUDITRETURN
Xgiveupaudit(value)
Xchar                   *value;
X{
X    if (*value == 'y' || *value == 'Y')
X	return dmmAuditReturnOkay;
X    if (*value != 'n' && *value == 'N')
X	return dmmAuditBad;
X    return dmmAuditOkay;
X}
X
XDMMAUDITRETURN
XauditPasswd(value)
Xchar                   *value;		/* unused but required */
X{
X    return dmmAuditReturnOkay;
X}
X
XDMMAUDITRETURN
XauditUsername(username)
Xchar                   *username;
X{
X    extern int              errno;
X
X    if (!*username)
X	strcpy(auditbuf, "A user name must be specified");
X    else
X	return dmmAuditOkay;
X    dmmPutMsgsNext(auditmsgblk);
X    return dmmAuditBad;
X}
X
X/* return 0 if user logs in correctly, else -1 */
Xint
Xlogin()
X{
X
X    int                     retcode,
X                            tries = 0;
X    DMMSCREEN2              screen;
X
X    /* use the screen without give-up capabilities first time around */
X    screen = loginscreen1;
X    while (1) {
X
X	/* solicit login information */
X	retcode = dmmRun(-1, screen, (DMMMENU2) 0, dmmNew, dmmInitVal);
X	if (retcode == -1)
X	    return -1;
X
X	/* check if user wants to give up */
X	if (*giveup == 'y' || *giveup == 'Y')
X	    return -1;
X
X	/* process login information in dummy fashion */
X	dmmPutMsgs(plswaitmsgblk);
X	sleep(2);
X	if (tries++)
X	    return 0;
X
X	/* use the screen with give-up capabilities on  subsequent tries */
X	screen = loginscreen2;
X    }
X}
SHAR_EOF
chmod 0444 dmmdemo2.c || echo "restore of dmmdemo2.c fails"
set `wc -c dmmdemo2.c`;Sum=$1
if test "$Sum" != "3637"
then echo original size 3637, current size $Sum;fi
echo "x - extracting dmmdemo3.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > dmmdemo3.c &&
X#ifndef LINT
Xstatic char     dmmdemo_3_c_id[] = {"@(#)dmmdemo3.c	1.1 \
XCopyright (c) 1991 Robert Bernardo, rob at mtdiablo.Concord.CA.US, \
Xan employee of Pande, Inc. \
XPermission to use granted only if this notice is not removed from \
Xthis source file nor from any binaries produced from it."};
X#endif
X#include <curses.h>
X#include "dmm.h"
X#include "dmmdemo.h"
X
X/* messages */
Xstatic DMMMESSAGE       month = {"January", 10, 2, A_REVERSE},
X                        days = {"S   M   T   W   T   F   S ", 5, 3, A_UNDERLINE},
X                        week1 = {"    1   2   3   4   5   6", 5, 4, 0},
X                        week2 = {"7   8   9   10  11  12  13", 5, 5, 0},
X                        week3 = {"14  15  16  17  18  19  20", 5, 6, 0},
X                        week4 = {"21  22  23  24  25  26  27", 5, 7, 0},
X                        week5 = {"28  29  30  31", 5, 8, 0};
X
Xstatic DMMMESGBLK       calendar = {&month, &days, &week1, &week2,
X&week3, &week4, &week5, 0};
X
X/* menu */
Xstatic DMMMENUITEM      jan = {"January", "Display calendar for January"},
X                        feb = {"February", "Display calendar for February"},
X                        mar = {"March", "Display calendar for March"},
X                        apr = {"April", "Display calendar for April"},
X                        may = {"May", "Display calendar for May"},
X                        jun = {"June", "Display calendar for June"},
X                        jul = {"July", "Display calendar for July"},
X                        aug = {"August", "Display calendar for August"},
X                        sep = {"September", "Display calendar for September"},
X                        oct = {"October", "Display calendar for October"},
X                        nov = {"November", "Display calendar for November"},
X                        dec = {"December", "Display calendar for December"};
X
Xstatic DMMMENU          menu = {&jan, &feb, &mar, &apr, &may, &jun,
X				&jul, &aug, &sep, &oct, &nov, &dec, 0};
X
X
X/* data screen */
X/* Notice that on the following fields, since they have no input part, only the
X * first three elements need be specified, letting the rest default to
X * zero, a feature of their being static
X */
Xstatic DMMFIELD         msg1 =
X{"Select any menu item; it doesn't matter which. A dummy calendar will be",
X0, 1, 0},
X
X                        msg2 =
X{"displayed. The source for this screen is in dmmdemo3.c. Note the following:",
X0, 2, 0},
X
X                        msg3 =
X{"1. The is a menu-only screen because the data fields have only",
XNUMBERCOL, 3, 0},
X
X                        msg4 =
X{"label parts and no input parts.",
XBODYCOL, 4, 0},
X
X                        msg5 =
X{"2. The menu is long enough to scroll. Notice that the end scrolls to the",
XNUMBERCOL, 5, 0},
X
X                        msg6 =
X{"beginning and vice versa.",
XBODYCOL, 6, 0},
X
X                        msg7 =
X{"3. The menu has some items with shared first letters and other items with",
XNUMBERCOL, 7, 0},
X
X                        msg8 =
X{"unique first letters by which they are selectable.",
XBODYCOL, 8, 0},
X
X                        msg9 =
X{"4. Messages lines can have a variety of attributes; see the calendar.",
XNUMBERCOL, 9, 0};
X
Xstatic DMMSCREEN        msgscreen = {&msg1, &msg2, &msg3, &msg4, &msg5,
X&msg6, &msg7, &msg8, &msg9, 0};
X
X
Xvoid
Xmonthmenu()
X{
X    dmmRun(-1, msgscreen, menu, dmmNew, dmmInitVal);
X    /* normally we'd process the return code of dmmRun() and learn the month
X     * that was selected from the menu and then display the proper calendar.
X     * But this is just a demo and we'll display the same calendar no matter
X     * what month was chosen. */
X    dmmClear();				/* remove data entry/display part of
X					 * screen */
X    dmmPutMsgsHit(calendar);		/* display calendar */
X    return;
X}
SHAR_EOF
chmod 0444 dmmdemo3.c || echo "restore of dmmdemo3.c fails"
set `wc -c dmmdemo3.c`;Sum=$1
if test "$Sum" != "3773"
then echo original size 3773, current size $Sum;fi
echo "x - extracting dmmdemo4.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > dmmdemo4.c &&
X#ifndef LINT
Xstatic char     dmmdemo_4_c_id[] = {"@(#)dmmdemo4.c	1.1 \
XCopyright (c) 1991 Robert Bernardo, rob at mtdiablo.Concord.CA.US, \
Xan employee of Pande, Inc. \
XPermission to use granted only if this notice is not removed from \
Xthis source file nor from any binaries produced from it."};
X#endif
X#include "dmm.h"
X
X/* messages */
Xstatic DMMMESSAGE	msgA1 = 
X{"The source for this next set of messages is in dmmdemo4.c. It demonstrates",
X0, 0, 0},
X			msgA2 =
X{"various message display functions. This message is displayed with a call",
X0, 1, 0},
X			msgA3 =
X{"to dmmPutMsgsHit(), and will go away upon your next keystroke. After that",
X0, 2, 0},
X			msgA4 =
X{"a message will be displayed with dmmPutMsgsTimer for a few seconds. Then",
X0, 3, 0},
X			msgA5 =
X{"three short messages will be displayed. The last will be removed with",
X0, 4, 0},
X			msgA6 =
X{"a call to dmmRmMsgs(dmmRemoveLast), and then all messages will be removed",
X0, 5, 0},
X			msgA7 =
X{"with a call to dmmRmMsgs(dmmRemoveAll).",
X0, 6, 0},
X			msgB1 =
X{"This is the message displayed with dmmPutMsgsTimer() for a few seconds.",
X0, 1, 0},
X			msgC1 =
X{"This is the first of three messages.",
X0, 1, 0},
X			msgD1 =
X{"This is the second of three messages.",
X0, 3, 0},
X			msgE1 =
X{"This is the last of three messages.",
X0, 5, 0},
X			msgE2 =
X{"It will go away first, then all messages will be removed.",
X0, 6, 0};
X
Xstatic DMMMESGBLK	msgblkA = {&msgA1, &msgA2, &msgA3, &msgA4, &msgA5,
X				   &msgA6, &msgA7, 0},
X			msgblkB = {&msgB1, 0},
X			msgblkC = {&msgC1, 0},
X			msgblkD = {&msgD1, 0},
X			msgblkE = {&msgE1, &msgE2, 0};
X
Xvoid
Xmsgdemo()
X{
X    dmmPutMsgsHit(msgblkA);
X    dmmPutMsgsTimer(msgblkB, (unsigned)3);
X    dmmPutMsgs(msgblkC);
X    sleep(1);
X    dmmPutMsgs(msgblkD);
X    sleep(1);
X    dmmPutMsgs(msgblkE);
X    sleep(3);
X    dmmRmMsgs(dmmRemoveLast);
X    sleep(3);
X    dmmRmMsgs(dmmRemoveAll);
X    sleep(2);
X    return;
X}
SHAR_EOF
chmod 0444 dmmdemo4.c || echo "restore of dmmdemo4.c fails"
set `wc -c dmmdemo4.c`;Sum=$1
if test "$Sum" != "1886"
then echo original size 1886, current size $Sum;fi
echo "x - extracting dmmdemo5.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > dmmdemo5.c &&
X#ifndef LINT
Xstatic char     dmmdemo_5_c_id[] = {"@(#)dmmdemo5.c	1.1 \
XCopyright (c) 1991 Robert Bernardo, rob at mtdiablo.Concord.CA.US, \
Xan employee of Pande, Inc. \
XPermission to use granted only if this notice is not removed from \
Xthis source file nor from any binaries produced from it."};
X#endif
X#include <ctype.h>
X#include <curses.h>
X#include "dmm.h"
X#include "dmmdemo.h"
X
X#define			MONTHLEN 	2
X#define			DAYLEN 		2
X#define			YEARLEN 	2
X#define			MONTHCOL 	10
X#define			DAYCOL		(MONTHCOL + MONTHLEN)
X#define			YEARCOL		(DAYCOL + DAYLEN + 1)
X#define			DATELINE	10
X
X/* messages */
Xstatic char             dayofweek[80];
X
Xstatic DMMMESSAGE	msgA1 =
X{"The source for the next screen (and these messages) is in dmmdemo5.c.",
X0, 0, 0},
X			msgA2 =
X{"That screen shows a fairly prototypical logic in processing of various",
X0, 1, 0},
X			msgA3 =
X{"return values and conditions.  The screen solicits a date from the user",
X0, 2, 0},
X			msgA4 =
X{"and the rest of the code simulates calculation of the day of the week of",
X0, 3, 0},
X			msgA5 =
X{"the date.",
X0, 4, 0},
X			msgA6 =
X{"Note the following:",
X0, 6, 0},
X			msgA7 =
X{"1. Look at the overall logic of the function calcdate().  It is a",
XNUMBERCOL, 7, 0},
X			msgA8 =
X{"forever loop with a single call to dmmRun().  Notice that some of",
XBODYCOL, 8, 0},
X			msgA9 =
X{"various arguments to dmmRun(), namely startfield, drawflag and",
XBODYCOL, 9, 0},
X			msgA10 =
X{"valflag, get set to different values on different iterations of",
XBODYCOL, 10, 0},
X			msgA11 =
X{"the forever loop according to various conditions.",
XBODYCOL, 11, 0},
X			msgB1 =
X{"2. dmmReview() is used to check the input field values after dmmRun()",
XNUMBERCOL, 0, 0},
X			msgB2 =
X{"returns.  This is needed because the default initial values of the",
XBODYCOL, 1, 0},
X			msgB3 =
X{"input fields are not valid values.  Notice how if dmmReview()",
XBODYCOL, 2, 0},
X			msgB4 =
X{"indicates an invalid field value, startfield, drawflag and valflag",
XBODYCOL, 3, 0},
X			msgB5 =
X{"are set to re-present the screen with the cursor in the offending",
XBODYCOL, 4, 0},
X			msgB6 =
X{"field. If dmmReview() shows that all field values are valid, the",
XBODYCOL, 5, 0},
X			msgB7 =
X{"day of the week is displayed as a message alongside the input fields,",
XBODYCOL, 6, 0},
X			msgB8 =
X{"which are still on the screen, and then the screen is redisplayed",
XBODYCOL, 7, 0},
X			msgB9 =
X{"afresh.",
XBODYCOL, 8, 0},
X			msgC1 =
X{"3. The three input fields have audit functions that return",
XNUMBERCOL, 0, 0},
X			msgC2 =
X{"dmmAuditReturnOkay so that dmmRun() returns for the surrounding",
XBODYCOL, 1, 0},
X			msgC3 =
X{"code to perform an inter-field audit. (The inter-field audit is here",
XBODYCOL, 2, 0},
X			msgC4 =
X{"only as an example. In a real program, it would be better not to have",
XBODYCOL, 3, 0},
X			msgC5 =
X{"the audit functions return dmmAuditReturnOkay, and just perform an",
XBODYCOL, 4, 0},
X			msgC6 =
X{"inter-field audit after dmmReview returns from verifying the validity",
XBODYCOL, 5, 0},
X			msgC7 =
X{"of the fields separately.) Notice how startfield, drawflag and valflag",
XBODYCOL, 6, 0},
X			msgC8 =
X{"are set if the inter-field audit fails and if it succeeds.",
XBODYCOL, 7, 0},
X			msgD1 =
X{"4. A negative line number is used for the error messages to place the",
XNUMBERCOL, 0, 0},
X			msgD2 =
X{"message a certain number of lines from the bottom. Notice that it is ",
XBODYCOL, 1, 0},
X			msgD3 =
X{"placed so as not to conflict with the bottom lines used by the",
XBODYCOL, 2, 0},
X			msgD4 =
X{"instruction messages.",
XBODYCOL, 3, 0},
X			errormsg = {0, 0, -3, A_REVERSE},
X                        dayofweekmsg = {dayofweek, YEARCOL + 4, DATELINE, 0};
X
Xstatic DMMMESGBLK	msgblkA = {&msgA1, &msgA2, &msgA3, &msgA4, &msgA5,
X				   &msgA6, &msgA7, &msgA8, &msgA9, &msgA10,
X				   &msgA11, 0},
X			msgblkB = {&msgB1, &msgB2, &msgB3, &msgB4, &msgB5,
X				   &msgB6, &msgB7, &msgB8, &msgB9, 0},
X			msgblkC = {&msgC1, &msgC2, &msgC3, &msgC4, &msgC5,
X				   &msgC6, &msgC7, &msgC8, 0},
X			msgblkD = {&msgD1, &msgD2, &msgD3, &msgD4, 0},
X			errormsgblk = {&errormsg, 0},
X                        dayofweekmsgblk = {&dayofweekmsg, 0};
X
X/* menu */
Xstatic DMMMENUITEM      calcitem = {"Calculate", "Calculate day of week"},
X                        quititem = {"Quit", "Quit this part of demo program"};
X
Xstatic DMMMENU          menu = {&calcitem, &quititem, 0};
X
X/* fields and screen */
Xstatic char            *monthinstruct[] = {"Enter month as two digits", 
X			   "An example of a multiline instruction", 0},
X                       *dayinstruct[] =
X			   {"Enter day of months as two digits", 0},
X                       *yearinstruct[] = {"Enter year as two digits", 0};
X
Xextern DMMAUDITRETURN   monthaudit(),
X			dayaudit(),
X			yearaudit();
X
Xstatic char             monthbuf[MONTHLEN + 1],
X                        daybuf[DAYLEN + 1],
X                        yearbuf[YEARLEN + 1];
X
Xstatic DMMFIELD         month = {0, 0, 0, 0, monthbuf, 0, MONTHCOL, DATELINE,
X			    MONTHLEN, 0, 0, 0, A_REVERSE, A_UNDERLINE,
X			    monthinstruct, 0, monthaudit},
X
X                        day = {"/", DAYCOL, DATELINE, 0, daybuf, 0, -1,
X			    DATELINE, DAYLEN, 0, 0, 0, A_REVERSE,
X			    A_UNDERLINE, dayinstruct, 0, dayaudit},
X
X                        year = {"/", YEARCOL, DATELINE, 0, yearbuf, 0, -1,
X			    DATELINE, YEARLEN, 0, 0, 0, A_REVERSE,
X			    A_UNDERLINE, yearinstruct, 0, yearaudit};
X
Xstatic DMMSCREEN        screen = {&month, &day, &year, 0};
X
Xstatic int              daysinmonth[] =
X			    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
Xstatic char            *daysofweek[] = {"Monday", "Tuesday", "Wednesday",
X			    "Thursday", "Friday", "Saturday", "Sunday"};
X
Xvoid
Xcalcdate()
X{
X    int                     retcode,
X                            startfield = -1,
X                            dayint,
X                            monthint,
X                            yearint;
X    DMMDRAWFLAG             drawflag = dmmNew;
X    DMMVALFLAG              valflag = dmmInitVal;
X
X    dmmPutMsgsHit(msgblkA);
X    dmmPutMsgsHit(msgblkB);
X    dmmPutMsgsHit(msgblkC);
X    dmmPutMsgsHit(msgblkD);
X    while (1) {
X	if((retcode = dmmRun(startfield, screen, menu, drawflag, valflag))
X	   == -1)
X	    return;
X	dayint = atoi(daybuf);
X	monthint = atoi(monthbuf);
X	yearint = atoi(yearbuf);
X	if (dmmRetType == dmmMenu) {
X
X	    /* user selected a menu item; if it was 'quit', return, else user
X	     * wants day of week calculated */
X	    if (retcode == 1)
X		/* user selected 'quit' menu item */
X		return;
X
X	    /* audit input values before calculating day of week */
X	    if ((retcode = dmmReview(screen)) == -1) {
X		/* all individual values okay - display day of week */
X		sprintf(dayofweek, "falls on a %s",
X			daysofweek[(dayint + monthint + yearint) % 7]);
X		dmmPutMsgsHit(dayofweekmsgblk);
X
X		/* redisplay fresh screen */
X		startfield = -1;
X		drawflag = dmmNew;
X		valflag = dmmInitVal;
X	    } else {
X		/* bad input value -- go back to offending field of last
X		 * screen for user to correct it */
X		startfield = retcode;
X		drawflag = dmmOld;
X		valflag = dmmEdVal;
X	    }
X	} else {
X	    /* an audit function must have returned - do the interfield audit
X	     * that fits the input the user gave so far */
X	    if ((*monthbuf && *daybuf) &&
X	    ((*yearbuf && !validdayofmonthandyear(dayint, monthint, yearint))
X	     || !validdayofmonth(dayint, monthint))) {
X		/* bad day of month */
X		startfield = 1;		/* index of day field */
X		drawflag = dmmOld;
X		valflag = dmmEdVal;
X	    } else {
X		/* continue with appropriate field */
X		startfield = -1;
X		drawflag = dmmOld;
X		valflag = dmmEdVal;
X	    }
X	}
X    }
X}
X
Xvaliddayofmonthandyear(dayofmonth, month, year)
Xint                     dayofmonth,	/* presumed between 1 and 31 */
X                        month,		/* presumed between 1 and 12 */
X                        year;		/* presumed between 0 and 99 */
X{
X    if ((dayofmonth > daysinmonth[month]) ||
X	    ((dayofmonth == 29) && (month == 2) &&
X	     (year % 4 != 0) || (year % 100 == 0))) {
X	errormsg.value = "Not that many days in that month";
X	dmmPutMsgsNext(errormsgblk);
X	return 0;
X    }
X    return 1;
X}
X
Xvaliddayofmonth(dayofmonth, month)
Xint                     dayofmonth,	/* presumed between 1 and 31 */
X                        month;		/* presumed between 1 and 12 */
X{
X    if (dayofmonth > daysinmonth[month]) {
X	errormsg.value = "Not that many days in that month";
X	dmmPutMsgsNext(errormsgblk);
X	return 0;
X    }
X    return 1;
X}
X
XDMMAUDITRETURN
Xmonthaudit(month)
Xchar                   *month;
X{
X    int                     monthint = atoi(month);
X
X    /* check for valid month */
X    if ((strlen(month) != MONTHLEN) || (monthint < 1) || (monthint > 12)) {
X	errormsg.value = "Month must be given as two digits, 01 through 12";
X	dmmPutMsgsNext(errormsgblk);
X	return dmmAuditBad;
X    }
X    /* need to check month against day of month */
X    return dmmAuditReturnOkay;
X}
X
XDMMAUDITRETURN
Xdayaudit(day)
Xchar                   *day;
X{
X    int                     dayint = atoi(day);
X
X    /* check for valid day of month */
X    if ((strlen(day) != DAYLEN) || (dayint < 1) || (dayint > 31)) {
X	errormsg.value = "Day must be given as two digits, 01 through 31";
X	dmmPutMsgsHit(errormsgblk);
X	return dmmAuditBad;
X    }
X    /* need to check day of month against month */
X    return dmmAuditReturnOkay;
X}
X
XDMMAUDITRETURN
Xyearaudit(year)
Xchar                   *year;
X{
X    /* check for valid year */
X    if ((strlen(year) != YEARLEN) || (!isdigit(*year)) || (!isdigit(*(year + 1)))) {
X	errormsg.value = "Year must be given as two digits, 00 through 99";
X	dmmPutMsgsNext(errormsgblk);
X	return dmmAuditBad;
X    }
X    return dmmAuditReturnOkay;
X}
SHAR_EOF
chmod 0444 dmmdemo5.c || echo "restore of dmmdemo5.c fails"
set `wc -c dmmdemo5.c`;Sum=$1
if test "$Sum" != "9605"
then echo original size 9605, current size $Sum;fi
echo "x - extracting dmmdemo6.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > dmmdemo6.c &&
X#ifndef LINT
Xstatic char     dmmdemo_6_c_id[] = {"@(#)dmmdemo6.c	1.1 \
XCopyright (c) 1991 Robert Bernardo, rob at mtdiablo.Concord.CA.US, \
Xan employee of Pande, Inc. \
XPermission to use granted only if this notice is not removed from \
Xthis source file nor from any binaries produced from it."};
X#endif
X#include <curses.h>
X#include "dmm.h"
X#include "dmmdemo.h"
X
X/* messages */
Xstatic DMMMESSAGE	infomsg1 =
X{"The source for the next screen (and these messages) is in dmmdemo6.c.",
X0, 0, 0},
X			infomsg2 =
X{"Note the following:",
X0, 1, 0},
X			infomsg3 =
X{"1. The first screen has one input field that spans more than one line.",
XNUMBERCOL, 2, 0},
X			infomsg4 =
X{"This is achieved by having the inputMaxcols datum in the",
XBODYCOL, 3, 0},
X			infomsg5 =
X{"DMMFIELD structure be non-zero and less than the inputLength",
XBODYCOL, 4, 0},
X			infomsg6 =
X{"datum. Play around with the arrow keys.",
XBODYCOL, 5, 0},
X			infomsg7 =
X{"2. The second screen is like the first, except that a line number is",
XNUMBERCOL, 6, 0},
X			infomsg8 =
X{"put out of range. Since the screen cannot be displayed as indicated",
XBODYCOL, 7, 0},
X			infomsg9 =
X{"by the DMMSCREEN data, dmmRun() displays a diagnostic message and",
XBODYCOL, 8, 0},
X			infomsg10 =
X{"returns -1. Notice how dmmGetNumLines() can be used to ascertain",
XBODYCOL, 9, 0},
X			infomsg11 =
X{"the number of lines available in the data entry window.",
XBODYCOL, 10, 0},
X			infomsg12 =
X{"This is the last part of the demonstration.",
X0, 12, 0};
X
Xstatic DMMMESGBLK	infomsgblk = {&infomsg1, &infomsg2, &infomsg3,
X				      &infomsg4, &infomsg5, &infomsg6,
X				      &infomsg7, &infomsg8, &infomsg9,
X				      &infomsg10, &infomsg11, &infomsg12, 0};
X
X/* menu */
Xstatic DMMMENUITEM      mailit = {"Mail", "Mail comment to administrator"},
X                        dontmailit = {"Quit", "Quit this part of demo program"};
X
Xstatic DMMMENU          menu = {&mailit, &dontmailit, 0};
X
X/* fields and screen */
Xstatic char            *commentinstruct[] = {"Enter comment for administrator",
X			   0};
X
X#define COMMENTSIZE	700
Xstatic char             commentbuf[COMMENTSIZE + 1];
X
Xstatic DMMFIELD         comment = {"Comment", 10, 0, 0, commentbuf, 0, 10, 2,
X			    COMMENTSIZE, 60, 0, 0, A_REVERSE, A_REVERSE,
X			    commentinstruct, 0, 0};
X
Xstatic DMMSCREEN        screen = {&comment, 0};
X
Xvoid
Xgetcomment()
X{
X    int                     numlines;
X
X    dmmPutMsgsHit(infomsgblk);
X    dmmRun(-1, screen, menu, dmmNew, dmmInitVal);
X    numlines = dmmGetNumLines();
X    comment.labelLine = numlines;
X    dmmRun(-1, screen, menu, dmmNew, dmmInitVal);
X    return;
X}
SHAR_EOF
chmod 0444 dmmdemo6.c || echo "restore of dmmdemo6.c fails"
set `wc -c dmmdemo6.c`;Sum=$1
if test "$Sum" != "2582"
then echo original size 2582, current size $Sum;fi
rm -f s2_seq_.tmp
echo "You have unpacked the last part"
exit 0
-- 
Rob Bernardo					Mt. Diablo Software Solutions
email: rob at mtdiablo.Concord.CA.US		phone: (415) 827-4301



More information about the Alt.sources mailing list