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