1*11986Sslatteng /* @(#)textio.c	1.2	04/18/83
211962Sslatteng  *
311962Sslatteng  * Copyright -C- 1982 Barry S. Roitblat
411962Sslatteng  *
511962Sslatteng  *
611962Sslatteng  * This file contains functions that manipulate the text interface
711962Sslatteng  *
811962Sslatteng  * (Modified from software written by John Ousterhout for the caesar
911962Sslatteng  *  program)
1011962Sslatteng  */
1111962Sslatteng 
1211962Sslatteng #include "gremlin.h"
1311962Sslatteng #include <sgtty.h>
1411962Sslatteng 
1511962Sslatteng /* Library routines: */
1611962Sslatteng 
1711962Sslatteng char *tgetstr(), *sprintf(), *tgoto(), *strcpy(), *strcat();
1811962Sslatteng 
1911962Sslatteng /* The following definitions are used by the termlib routines
2011962Sslatteng  */
2111962Sslatteng 
2211962Sslatteng char PC;
2311962Sslatteng char *BC, *UP, *cm, *ce, *vs, *cl;
2411962Sslatteng short ospeed, lastline=23,msgline=23,inline=22;
2511962Sslatteng 
2611962Sslatteng static char bp[1024];		/* Holds the termcap entry for the tty */
2711962Sslatteng static char buf[256];		/* Holds selected strings from bp */
2811962Sslatteng static struct sgttyb sttybuf;	/* Holds stty information for resetting tty */
2911962Sslatteng static int sttyflags;		/* Flag word from sttybuf */
3011962Sslatteng static struct tchars tchars;	/* Holds tchars information for resetting */
3111962Sslatteng static char brkc, eofc;		/* Fields from tchars, saved for resetting */
3211962Sslatteng static int c100;		/* TRUE means text display is c100 */
3311962Sslatteng static putmsg;			/* TRUE means TxPutMsg has been called
3411962Sslatteng 				 * since last character input.
3511962Sslatteng 				 */
3611962Sslatteng 
37*11986Sslatteng 
3811962Sslatteng /* The following structures define the various fields that are available
3911962Sslatteng  * on the terminal screen.
4011962Sslatteng  */
4111962Sslatteng 
4211962Sslatteng TXFIELD
4311962Sslatteng     TAlign = {56, 1, 3},
4411962Sslatteng     TAdjust = {63, 1, 13},
4511962Sslatteng     TBrush = {30, 1, 1},
4611962Sslatteng     TEdit = {10, 2, 32},
4711962Sslatteng     TJustmode = {76, 2, 2},
4811962Sslatteng     TFont = {10, 1, 1},
4911962Sslatteng     TGravity = {43, 1, 4},
5011962Sslatteng     TCSize = {19, 1, 1};
5111962Sslatteng 
5211962Sslatteng 
OutChar(val)5311962Sslatteng OutChar(val)
5411962Sslatteng char val;			/* The character to be output */
5511962Sslatteng 
5611962Sslatteng /*-----------------------------------------------------------------------------
5711962Sslatteng  *	OutChar merely outputs a character on the file being used for
5811962Sslatteng  *	text I/O.  This routine is passed as a parameter to the tputs
5911962Sslatteng  *	pad-generating routine.
6011962Sslatteng  *
6111962Sslatteng  *	Results:	None.
6211962Sslatteng  *	Side Effects:	The character is output.
6311962Sslatteng  *	Errors:		None.
6411962Sslatteng  *-----------------------------------------------------------------------------
6511962Sslatteng  */
6611962Sslatteng 
6711962Sslatteng {
6811962Sslatteng     putc(val, stdout);
6911962Sslatteng }
7011962Sslatteng 
71*11986Sslatteng 
TxInit(ttytype)7211962Sslatteng TxInit(ttytype)
7311962Sslatteng char *ttytype;			/* The name of the terminal type, as returned
7411962Sslatteng 				 * by getenv("TERM") */
7511962Sslatteng 
7611962Sslatteng /*-----------------------------------------------------------------------------
7711962Sslatteng  *	TxInit initializes the text terminal and saves state information
7811962Sslatteng  *	so that we can restore its characteristics later.
7911962Sslatteng  *
8011962Sslatteng  *	Results:	None.
8111962Sslatteng  *	Side Effects:	Terminal characteristics are saved.
8211962Sslatteng  *-----------------------------------------------------------------------------
8311962Sslatteng  */
8411962Sslatteng 
8511962Sslatteng {
8611962Sslatteng     char *p1, *p2, *pcap;
8711962Sslatteng     int i;
8811962Sslatteng 
8911962Sslatteng     /* Turn off buffering.  This is necessary to avoid mess-ups during
9011962Sslatteng      * the constant mode changes.
9111962Sslatteng      */
9211962Sslatteng 
9311962Sslatteng     setbuf(stdin, NULL);
9411962Sslatteng 
9511962Sslatteng     /* Find the termcap entry, and set up the strings and constants
9611962Sslatteng      * required by the termlib routines.
9711962Sslatteng      */
9811962Sslatteng 
9911962Sslatteng     if (tgetent(bp, ttytype) != 1)
10011962Sslatteng 	error("Cannot find terminal characteristics");
10111962Sslatteng     (void) gtty(fileno(stdout), &sttybuf);
10211962Sslatteng     ospeed = sttybuf.sg_ospeed;
10311962Sslatteng     pcap = buf;
10411962Sslatteng     p1 = tgetstr("pc", &pcap);  if (p1 == NULL) PC = 0; else PC = *p1;
10511962Sslatteng     pcap = buf;
10611962Sslatteng     BC = tgetstr("bc", &pcap);
10711962Sslatteng     UP = tgetstr("up", &pcap);
10811962Sslatteng     cm = tgetstr("cm", &pcap);
10911962Sslatteng     ce = tgetstr("ce", &pcap);
11011962Sslatteng     vs = tgetstr("vs", &pcap);
11111962Sslatteng     cl = tgetstr("cl", &pcap);
11211962Sslatteng     (void) gtty(fileno(stdin), &sttybuf);
11311962Sslatteng     sttyflags = sttybuf.sg_flags;
11411962Sslatteng     (void) ioctl(fileno(stdin), TIOCGETC, (char *) &tchars);
11511962Sslatteng     eofc = tchars.t_eofc;
11611962Sslatteng     brkc = tchars.t_brkc;
11711962Sslatteng     p1 = "c100";
11811962Sslatteng     p2 = ttytype;
11911962Sslatteng     c100 = FALSE;
12011962Sslatteng     putmsg = FALSE;
12111962Sslatteng     for (i = 4; i; i = i-1)
12211962Sslatteng     {
12311962Sslatteng 	if (*p1 != *p2) break;
12411962Sslatteng 	if (i=1) c100 = TRUE;
12511962Sslatteng     }
12611962Sslatteng }
12711962Sslatteng 
128*11986Sslatteng 
TxRedisplay()12911962Sslatteng TxRedisplay()
13011962Sslatteng 
13111962Sslatteng /*-----------------------------------------------------------------------------
13211962Sslatteng  *	This routine merely redisplays the command menu on the text screen,
13311962Sslatteng  *	and modifies text display parameters for menu processing.
13411962Sslatteng  *
13511962Sslatteng  *	Results:	None.
13611962Sslatteng  *
13711962Sslatteng  *	Side Effects:
13811962Sslatteng  *	The text display is cleared, menu information is reprinted, and
13911962Sslatteng  *	terminal characteristics are set for menu processing.
14011962Sslatteng  *-----------------------------------------------------------------------------
14111962Sslatteng  */
14211962Sslatteng 
14311962Sslatteng {
14411962Sslatteng     static char initstring1[] = "\n\
14511962Sslatteng      font 1   size 1    brush 6    gravi\
14611962Sslatteng ty OFF    align   4    NO ADJUSTMENT \n\
14711962Sslatteng Editing:                                \
14811962Sslatteng                      Justification: BL \n\
14911962Sslatteng ----------------------------------------\
15011962Sslatteng ---------------------------------------\n\
15111962Sslatteng     Long Commands:          |\
15211962Sslatteng          Short Commands:\n\
15311962Sslatteng                             |\n\
15411962Sslatteng    Align          MSize     |\
15511962Sslatteng    a - draw arc         ! - shell escape\n\
15611962Sslatteng    BRush          MText     |\
15711962Sslatteng    b - draw curve       . - repeat last command\n\
15811962Sslatteng    BUffer         Orient    |\
15911962Sslatteng    c - copy set        ^L - redraw picture\n\
16011962Sslatteng    Clearpoints    PAth      |\
16111962Sslatteng    d - define set       l - redisplay text screen\n\
16211962Sslatteng ";
16311962Sslatteng     static char initstring2[] = "\
16411962Sslatteng    Deletepoint    POint     |\
16511962Sslatteng    e - erase      1,2,3,4 - store set buffer\n\
16611962Sslatteng    Edit<!>        Quit<!>   |\
16711962Sslatteng    f - define area \n\
16811962Sslatteng    Font           Read      |\
16911962Sslatteng    g - gravity\n\
17011962Sslatteng    Gripe          SAveset<!>|\
17111962Sslatteng    q - grid\n\
17211962Sslatteng    Hadjust        SHowpoints|\
17311962Sslatteng    r - rotate set\n\
17411962Sslatteng    Includeset     SIze      |\
17511962Sslatteng    s - scale set\n\
17611962Sslatteng    Justify        Text      |\
17711962Sslatteng    t - translate set\n\
17811962Sslatteng    Littlepoint    Undo      |\
17911962Sslatteng    v - draw vectors\n\
18011962Sslatteng    MBrush         Vadjust   |\
18111962Sslatteng    w - draw arrow \n\
18211962Sslatteng    MFont          Write<!>  |\
18311962Sslatteng    x - draw box\n\
18411962Sslatteng    MIrror                   |\
18511962Sslatteng    z - manhattan adjust\n\
18611962Sslatteng    MPoint                   |\
18711962Sslatteng    \n\
18811962Sslatteng ";
18911962Sslatteng 
19011962Sslatteng     /* Clear the terminal screen and output the gremlin menu.  The
19111962Sslatteng      * TxClose call is necessary to put the terminal back into its standard
19211962Sslatteng      * operating mode;  otherwise this stuff will appear as garbage!
19311962Sslatteng      * However, turn off echoing to keep type-ahead from appearing
19411962Sslatteng      * in the middle of the screen.
19511962Sslatteng      */
19611962Sslatteng 
19711962Sslatteng     TxClose();
19811962Sslatteng     sttybuf.sg_flags &= ~ECHO;
19911962Sslatteng     (void) ioctl(fileno(stdin), TIOCSETN, (char *) &sttybuf);
20011962Sslatteng     fputs(vs, stdout);
20111962Sslatteng     tputs(cl, tgetnum("li"), OutChar);
20211962Sslatteng     fputs(tgoto(cm, 0, 0), stdout);
20311962Sslatteng     fputs(initstring1, stdout);
20411962Sslatteng     fputs(initstring2, stdout);
20511962Sslatteng 
20611962Sslatteng     /* If the terminal is a Concept 100, then output special characters
20711962Sslatteng      * for the border lines between the three screen areas.
20811962Sslatteng      */
20911962Sslatteng 
21011962Sslatteng     if (c100)
21111962Sslatteng     {
21211962Sslatteng 	fputs(tgoto(cm, 0, 3), stdout);
21311962Sslatteng 	fputs("\33U\33r\1p", stdout);
21411962Sslatteng 	putchar(0);
21511962Sslatteng 	putchar(0);
21611962Sslatteng 	putchar(0);
21711962Sslatteng 	putchar(0);
21811962Sslatteng 	fputs(tgoto(cm, 28, 4), stdout);
21911962Sslatteng 	putchar('\0');
22011962Sslatteng 	putchar('\0');
22111962Sslatteng 	fputs("\33R", stdout);
22211962Sslatteng 	putchar('\0');
22311962Sslatteng 	putchar('2');
22411962Sslatteng     }
22511962Sslatteng 
22611962Sslatteng     /* Place the cursor in the lower-left corner, save terminal
22711962Sslatteng      * characteristics so we can restore them later, then make ^M
22811962Sslatteng      * into a break character, put the terminal into CBREAK mode,
22911962Sslatteng      * and turn off echoing.
23011962Sslatteng      */
23111962Sslatteng 
23211962Sslatteng     fputs(tgoto(cm, 0, lastline), stdout);
23311962Sslatteng     sttybuf.sg_flags |= CBREAK;
23411962Sslatteng     sttybuf.sg_flags &= ~(ECHO|CRMOD);
23511962Sslatteng     (void) ioctl(fileno(stdin), TIOCSETN, (char *) &sttybuf);
23611962Sslatteng     tchars.t_eofc = -1;
23711962Sslatteng     tchars.t_brkc = '\r';
23811962Sslatteng     (void) ioctl(fileno(stdin), TIOCSETC, (char *) &tchars);
23911962Sslatteng     (void) fflush(stdout);
24011962Sslatteng     putmsg = FALSE;
24111962Sslatteng }
24211962Sslatteng 
243*11986Sslatteng 
TxClose()24411962Sslatteng TxClose()
24511962Sslatteng 
24611962Sslatteng /*-----------------------------------------------------------------------------
24711962Sslatteng  *	TxClose resets the terminal to the way we found it.
24811962Sslatteng  *
24911962Sslatteng  *	Results:	None.
25011962Sslatteng  *	Side Effects:	None.
25111962Sslatteng  *	Errors:		None.
25211962Sslatteng  *-----------------------------------------------------------------------------
25311962Sslatteng  */
25411962Sslatteng 
25511962Sslatteng {
256*11986Sslatteng     char *dummy, buf [100];
25711962Sslatteng     sttybuf.sg_flags = sttyflags;
25811962Sslatteng     (void) ioctl(fileno(stdin), TIOCSETN, (char *) &sttybuf);
25911962Sslatteng     tchars.t_eofc = eofc;
26011962Sslatteng     tchars.t_brkc = brkc;
26111962Sslatteng     (void) ioctl(fileno(stdin), TIOCSETC, (char *) &tchars);
26211962Sslatteng     fputs(tgoto(cm, 0, tgetnum("li")-1), stdout);
26311962Sslatteng     dummy = buf;
26411962Sslatteng     fputs(tgetstr("ve", &dummy), stdout);
26511962Sslatteng     fputs("\n", stdout);
26611962Sslatteng     (void) fflush(stdout);
26711962Sslatteng }
26811962Sslatteng 
269*11986Sslatteng 
TxPutString(field,string)27011962Sslatteng TxPutString(field, string)
27111962Sslatteng TXFIELD *field;			/* The screen field to be overwritten */
27211962Sslatteng char *string;			/* The character string to be written */
27311962Sslatteng 
27411962Sslatteng /*-----------------------------------------------------------------------------
27511962Sslatteng  *	TxPutString displays a string in a given field of the text display.
27611962Sslatteng  *
27711962Sslatteng  *	Results:	None.
27811962Sslatteng  *
27911962Sslatteng  *	Side Effects:
28011962Sslatteng  *	The given text screen field is overwritten with the given text
28111962Sslatteng  *	string, blank filled and left justified.
28211962Sslatteng  *
28311962Sslatteng  *	Errors:		None.
28411962Sslatteng  *-----------------------------------------------------------------------------
28511962Sslatteng  */
28611962Sslatteng 
28711962Sslatteng {
28811962Sslatteng     char format[20];
28911962Sslatteng     (void) sprintf(format, "%%s%%-%d.%ds", field->tx_size, field->tx_size);
29011962Sslatteng     (void) printf(format, tgoto(cm, field->tx_x, field->tx_y), string);
29111962Sslatteng     (void) fflush(stdout);
29211962Sslatteng }
29311962Sslatteng 
294*11986Sslatteng 
29511962Sslatteng char
TxGetChar()29611962Sslatteng TxGetChar()
29711962Sslatteng 
29811962Sslatteng /*-----------------------------------------------------------------------------
29911962Sslatteng  *	TxGetChar gets the next character from the text keyboard.
30011962Sslatteng  *
30111962Sslatteng  *	Results:	The next character.
30211962Sslatteng  *	Side Effects:	None.
30311962Sslatteng  *-----------------------------------------------------------------------------
30411962Sslatteng  */
30511962Sslatteng 
30611962Sslatteng {
30711962Sslatteng     putmsg = FALSE;
30811962Sslatteng     return getchar();
30911962Sslatteng }
31011962Sslatteng 
311*11986Sslatteng 
TxMsgOK()31211962Sslatteng TxMsgOK()
31311962Sslatteng 
31411962Sslatteng /*-----------------------------------------------------------------------------
31511962Sslatteng  *	This routine marks it OK to output messages again, just as if text
31611962Sslatteng  *	had been input.
31711962Sslatteng  *
31811962Sslatteng  *	Results:	None.
31911962Sslatteng  *	Side Effects:	As above.
32011962Sslatteng  *-----------------------------------------------------------------------------
32111962Sslatteng  */
32211962Sslatteng 
32311962Sslatteng {
32411962Sslatteng 	if (putmsg)          /* message on the screen to be blanked */
32511962Sslatteng 	{
32611962Sslatteng 		TxLine(msgline);
32711962Sslatteng 		printf("                                                                            ");
32811962Sslatteng 		TxLine(msgline);
32911962Sslatteng 	}
33011962Sslatteng 	putmsg = FALSE;
33111962Sslatteng }
33211962Sslatteng 
333*11986Sslatteng 
TxGetLine(prompt,ptr,maxsize)33411962Sslatteng TxGetLine(prompt, ptr, maxsize)
33511962Sslatteng char *prompt;			/* Prompt to be output at beginning of line */
33611962Sslatteng char *ptr;			/* Place to store the input line */
33711962Sslatteng int maxsize;			/* Maximum number of characters to be read */
33811962Sslatteng 
33911962Sslatteng /*-----------------------------------------------------------------------------
34011962Sslatteng  *	TxGetLine reads a line of text from the terminal.  It does so
34111962Sslatteng  *	by positioning the cursor at the bottom of the screen and enabling
34211962Sslatteng  *	echoes again.  When the line has been read, echoes etc. are turned
34311962Sslatteng  *	off once more.
34411962Sslatteng  *
34511962Sslatteng  *	Results:	None.
34611962Sslatteng  *	Side Effects:	The last line of the text screen is destroyed.
34711962Sslatteng  *	Errors:		None.
34811962Sslatteng  *-----------------------------------------------------------------------------
34911962Sslatteng  */
35011962Sslatteng 
35111962Sslatteng {
35211962Sslatteng     int i, j;
35311962Sslatteng 
35411962Sslatteng     putmsg = FALSE;
35511962Sslatteng     fputs(tgoto(cm, 0, inline), stdout);
35611962Sslatteng     tputs(ce, 1, OutChar);
35711962Sslatteng     fputs(prompt, stdout);
35811962Sslatteng     sttybuf.sg_flags |= ECHO;
35911962Sslatteng     sttybuf.sg_flags &= ~CBREAK;
36011962Sslatteng     (void) ioctl(fileno(stdin), TIOCSETN, (char *) &sttybuf);
36111962Sslatteng 
36211962Sslatteng     /* Input characters until a carriage return is found.  Then
36311962Sslatteng      * erase the control character from the screen.
36411962Sslatteng      */
36511962Sslatteng 
36611962Sslatteng     for (i=0; i<maxsize; i++)
36711962Sslatteng     {
36811962Sslatteng 	ptr[i] = getchar();
36911962Sslatteng 	if (ptr[i] == '\r') break;
37011962Sslatteng     }
37111962Sslatteng     for (j=i; j<maxsize; j++)
37211962Sslatteng         ptr[j] = '\0';
37311962Sslatteng     fputs("\b\b  \b\b", stdout);
37411962Sslatteng     (void) fflush(stdout);
37511962Sslatteng 
37611962Sslatteng     /* Reset the terminal into no-echo mode */
37711962Sslatteng 
37811962Sslatteng     sttybuf.sg_flags |= CBREAK;
37911962Sslatteng     sttybuf.sg_flags &= ~ECHO;
38011962Sslatteng     (void) ioctl(fileno(stdin), TIOCSETN, (char *) &sttybuf);
38111962Sslatteng }
38211962Sslatteng 
383*11986Sslatteng 
TxPutMsg(msg)38411962Sslatteng TxPutMsg(msg)
38511962Sslatteng char *msg;			/* A message (not containing \r or \n) to
38611962Sslatteng 				 * be output on the text screen.  It must
38711962Sslatteng 				 * fit on a single line.  /*
38811962Sslatteng 
38911962Sslatteng /*-----------------------------------------------------------------------------
39011962Sslatteng  *	TPutMsg outputs a one-line message onto the text screen.
39111962Sslatteng  *
39211962Sslatteng  *	Results:	None.
39311962Sslatteng  *
39411962Sslatteng  *	Side Effects:
39511962Sslatteng  *	The string in msg is output on the last line of the text display.
39611962Sslatteng  *	If TxPutMsg is called twice between calls to TxGetLine or TxGetChar
39711962Sslatteng  *	then we output the message "More" at the end of the line and
39811962Sslatteng  *	wait for a space to be typed.  This is to protect against
39911962Sslatteng  *	multiple error messages overwriting each other.
40011962Sslatteng  *
40111962Sslatteng  *	Errors:		None.
40211962Sslatteng  *-----------------------------------------------------------------------------
40311962Sslatteng  */
40411962Sslatteng 
40511962Sslatteng {
40611962Sslatteng     if (putmsg)
40711962Sslatteng     {
40811962Sslatteng 	fputs(tgoto(cm, 50, msgline), stdout);
40911962Sslatteng 	if (msg[0] == '\7')
41011962Sslatteng 	{
41111962Sslatteng 	    putchar ('\7');
41211962Sslatteng 	    msg++;
41311962Sslatteng 	}
41411962Sslatteng 	fputs("--More--", stdout);
41511962Sslatteng 	(void) fflush(stdout);
41611962Sslatteng 	while (getchar() != ' ');
41711962Sslatteng     }
41811962Sslatteng     putmsg = TRUE;
41911962Sslatteng     fputs(tgoto(cm, 0, msgline), stdout);
42011962Sslatteng     tputs(ce, 1, OutChar);
42111962Sslatteng     fputs(msg, stdout);
42211962Sslatteng     (void) fflush(stdout);
42311962Sslatteng }
42411962Sslatteng 
TxLine(line)42511962Sslatteng TxLine(line)
42611962Sslatteng short line;
42711962Sslatteng 
42811962Sslatteng /*-----------------------------------------------------------------------------
42911962Sslatteng  *	TxLastLine moves the cursor to the first character of the specified
43011962Sslatteng  *	line of the text display.
43111962Sslatteng  *
43211962Sslatteng  *	Results:	None.
43311962Sslatteng  *	Side Effects:	None.
43411962Sslatteng  *-----------------------------------------------------------------------------
43511962Sslatteng  */
43611962Sslatteng 
43711962Sslatteng {
43811962Sslatteng     fputs(tgoto(cm, 0, line), stdout);
43911962Sslatteng     (void) fflush(stdout);
44011962Sslatteng }
441