home *** CD-ROM | disk | FTP | other *** search
- /* $Header: E:\SRC\UUPC\RN\RCS/TERM.C 1.1 1992/11/21 06:14:58 ahd Exp $
- *
- * $Log: TERM.C $
- * Revision 1.1 1992/11/21 06:14:58 ahd
- * Initial
- *
- *
- * Rev 1.0 18 Nov 1990 0:21:56
- * Initial revision.
- * Revision 4.3.2.7 90/04/21 16:54:29 sob
- * Installed patches provided by SCO for SCO Xenix
- *
- * Revision 4.3.2.6 90/04/13 23:48:17 sob
- * Modifications provided by Gene Hackney for 3b2.
- *
- * Revision 4.3.2.5 90/04/06 20:35:08 sob
- * Added fixes for SCO Xenix sent by ronald@robobar.co.uk.
- *
- * Revision 4.3.2.4 90/03/22 23:05:38 sob
- * Fixes provided by Wayne Davison <drivax!davison>
- *
- * Revision 4.3.2.3 89/11/28 01:51:58 sob
- * Now handles SIGWINCH correctly.
- *
- * Revision 4.3.2.2 89/11/27 01:31:34 sob
- * Altered NNTP code per ideas suggested by Bela Lubkin
- * <filbo@gorn.santa-cruz.ca.us>
- *
- * Revision 4.3.2.1 89/11/06 01:02:12 sob
- * Added RRN support from NNTP 1.5
- *
- * Revision 4.3.1.3 85/09/10 11:05:23 lwall
- * Improved %m in in_char().
- *
- * Revision 4.3.1.2 85/05/16 16:45:35 lwall
- * Forced \r to \n on input.
- * Fix for terminfo braindamage regarding bc emulation.
- *
- * Revision 4.3.1.1 85/05/10 11:41:03 lwall
- * Branch for patches.
- *
- * Revision 4.3 85/05/01 11:51:10 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #include <string.h>
- #include <stdlib.h>
- #include <conio.h>
-
- #ifdef msdos
- #include <dos.h>
- #endif
-
-
- #include "EXTERN.h"
- #include "common.h"
- #include "util.h"
- #include "final.h"
- #include "help.h"
- #include "cheat.h"
- #include "intrp.h"
- #include "INTERN.h"
- #include "term.h"
-
- char ERASECH; /* rubout character */
- char KILLCH; /* line delete character */
- char tcarea[TCSIZE]; /* area for "compiled"
- * termcap strings */
-
- /* guarantee capability pointer != Nullch */
- /* (I believe terminfo will ignore the &tmpaddr argument.) */
-
- #define Tgetstr(key) ((tmpstr = tgetstr(key,&tmpaddr)) ? tmpstr : nullstr)
-
- #ifdef PUSHBACK
- struct keymap
- {
- char km_type[128];
- union km_union
- {
- struct keymap *km_km;
- char *km_str;
- } km_ptr[128];
- };
-
- #define KM_NOTHIN 0
- #define KM_STRING 1
- #define KM_KEYMAP 2
- #define KM_BOGUS 3
-
- #define KM_TMASK 3
- #define KM_GSHIFT 4
- #define KM_GMASK 7
-
- typedef struct keymap KEYMAP;
-
- KEYMAP *topmap INIT(Null(KEYMAP *));
-
- void mac_init();
- KEYMAP *newkeymap();
- void show_keymap();
- void pushstring();
-
- #endif
-
- void line_col_calcs();
-
- /* terminal initialization */
-
- void
- term_init()
- {
- savetty(); /* remember current tty
- * state */
-
- #ifdef unix
-
- #ifdef TERMIO
- ospeed = _tty.c_cflag & CBAUD; /* for tputs() */
- ERASECH = _tty.c_cc[VERASE]; /* for finish_command() */
- KILLCH = _tty.c_cc[VKILL];/* for finish_command() */
- #else
- ospeed = _tty.sg_ospeed; /* for tputs() */
- ERASECH = _tty.sg_erase; /* for finish_command() */
- KILLCH = _tty.sg_kill; /* for finish_command() */
- #endif
-
- #else /* unix */
- ERASECH = '\b';
- KILLCH = 'U' - '@';
- #endif /* unix */
-
- #if unix
- /* The following could be a table but I can't be sure that there isn't */
- /* some degree of sparsity out there in the world. */
-
- switch (ospeed)
- { /* 1 second of padding */
-
- #ifdef BEXTA
- case BEXTA:
- just_a_sec = 1920;
- break;
- #else
-
- #ifdef B19200
- case B19200:
- just_a_sec = 1920;
- break;
- #endif
-
- #endif
-
- case B9600:
- just_a_sec = 960;
- break;
- case B4800:
- just_a_sec = 480;
- break;
- case B2400:
- just_a_sec = 240;
- break;
- case B1800:
- just_a_sec = 180;
- break;
- case B1200:
- just_a_sec = 120;
- break;
- case B600:
- just_a_sec = 60;
- break;
- case B300:
- just_a_sec = 30;
- break;
- /* do I really have to type the rest of this??? */
- case B200:
- just_a_sec = 20;
- break;
- case B150:
- just_a_sec = 15;
- break;
- case B134:
- just_a_sec = 13;
- break;
- case B110:
- just_a_sec = 11;
- break;
- case B75:
- just_a_sec = 8;
- break;
- case B50:
- just_a_sec = 5;
- break;
- default:
- just_a_sec = 960;
- break;
- /* if we are running detached I */
- } /* don't want to know
- * about it! */
- #endif /* unix */
- }
-
- /* set terminal characteristics */
-
- void
- term_set(tcbuf)
- char *tcbuf; /* temp area for
- * "uncompiled" termcap
- * entry */
- {
- char *tmpaddr; /* must not be register */
- register char *tmpstr;
- char *tgetstr();
- char *s;
- int status;
-
- #ifdef TIOCGWINSZ
-
- #ifdef u3b2
- struct winsize
- {
- unsigned short ws_row; /* rows, in characters */
- unsigned short ws_col; /* columns, in character */
- unsigned short ws_xpixel; /* horizontal size,
- * pixels */
- unsigned short ws_ypixel; /* vertical size, pixels */
- };
-
- #endif
- struct winsize winsize;
-
- #endif
-
- #ifdef PENDING
-
- #if ! defined (FIONREAD) && ! defined (RDCHK) && !defined(msdos)
- /* do no delay reads on something that always gets closed on exit */
-
- devtty = open("/dev/tty", 0);
- if (devtty < 0)
- {
- printf(cantopen, "/dev/tty") FLUSH;
- finalize(1);
- }
- fcntl(devtty, F_SETFL, O_NDELAY);
- #endif
-
- #endif
-
- /* get all that good termcap stuff */
-
- #ifdef HAVETERMLIB
- status = tgetent(tcbuf, getenv("TERM")); /* get termcap entry */
- if (status < 1)
- {
-
- #ifdef VERBOSE
- printf("No termcap %s found.\n", status ? "file" : "entry") FLUSH;
- #else
- fputs("Termcap botch\n", stdout) FLUSH
- #endif
-
- finalize(1);
- }
- tmpaddr = tcarea; /* set up strange
- * tgetstr pointer */
- s = Tgetstr("pc"); /* get pad character */
- PC = *s; /* get it where tputs
- * wants it */
- if (!tgetflag("bs"))
- { /* is backspace not
- * used? */
- BC = Tgetstr("bc"); /* find out what is */
- if (BC == nullstr) /* terminfo grok's 'bs'
- * but not 'bc' */
- BC = Tgetstr("le");
- }
- else
- BC = "\b"; /* make a backspace
- * handy */
- UP = Tgetstr("up"); /* move up a line */
- if (!*UP) /* no UP string? */
- marking = 0; /* disable any marking */
- if (muck_up_clear) /* this is for weird HPs */
- CL = "\n\n\n\n";
- else
- CL = Tgetstr("cl"); /* get clear string */
- CE = Tgetstr("ce"); /* clear to end of line
- * string */
-
- #ifdef CLEAREOL
- CM = Tgetstr("cm"); /* cursor motion */
- HO = Tgetstr("ho"); /* home cursor if no CM */
- CD = Tgetstr("cd"); /* clear to end of
- * display */
- if (!*CE || !*CD || (!*CM && !*HO)) /* can we CE, CD, and
- * home? */
- can_home_clear = FALSE;/* no, so disable use of
- * clear eol */
- #endif /* CLEAREOL */
-
- SO = Tgetstr("so"); /* begin standout */
- SE = Tgetstr("se"); /* end standout */
- if ((SG = tgetnum("sg")) < 0)
- SG = 0; /* blanks left by SG, SE */
- US = Tgetstr("us"); /* start underline */
- UE = Tgetstr("ue"); /* end underline */
- if ((UG = tgetnum("ug")) < 0)
- UG = 0; /* blanks left by US, UE */
- if (*US)
- UC = nullstr; /* UC must not be NULL */
- else
- UC = Tgetstr("uc"); /* underline a character */
- if (!*US && !*UC)
- { /* no underline mode? */
- US = SO; /* substitute standout
- * mode */
- UE = SE;
- UG = SG;
- }
- LINES = tgetnum("li"); /* lines per page */
- COLS = tgetnum("co"); /* columns on page */
-
- #ifdef TIOCGWINSZ
- {
- struct winsize ws;
-
- if (ioctl(0, TIOCGWINSZ, &ws) >= 0 && ws.ws_row > 0 && ws.ws_col > 0)
- {
- LINES = ws.ws_row;
- COLS = ws.ws_col;
- }
- }
- #endif
-
- AM = tgetflag("am"); /* terminal wraps
- * automatically? */
- XN = tgetflag("xn"); /* then eats next
- * newline? */
- VB = Tgetstr("vb");
- if (!*VB)
- VB = "\007";
- CR = Tgetstr("cr");
- if (!*CR)
- {
- if (tgetflag("nc") && *UP)
- {
- CR = safemalloc((MEM_SIZE) strlen(UP) + 2);
- sprintf(CR, "%s\r", UP);
- }
- else
- CR = "\r";
- }
-
- #ifdef TIOCGWINSZ
- if (ioctl(1, TIOCGWINSZ, &winsize) >= 0)
- {
- if (winsize.ws_row > 0)
- LINES = winsize.ws_row;
- if (winsize.ws_col > 0)
- COLS = winsize.ws_col;
- }
- #endif
-
- #else
-
- #ifdef msdos
-
- #if 0
- PC = 0; /* get it where tputs
- * wants it */
- BC = "\b"; /* make a backspace
- * handy */
- UP = "\033[A"; /* move up a line */
- CL = "\033[H\033[J"; /* get clear string */
- CE = "\033[K"; /* clear to end of line
- * string */
-
- #ifdef CLEAREOL
- CM = NULL; /* cursor motion:
- * NEEDSWORK */
- HO = "\033[H"; /* home cursor if no CM */
- CD = "\033[J"; /* clear to end of
- * display */
- if (!*CE || !*CD || (!*CM && !*HO)) /* can we CE, CD, and
- * home? */
- can_home_clear = FALSE;/* no, so disable use of
- * clear eol */
- #endif /* CLEAREOL */
-
- SO = "\033[1m"; /* begin standout */
- SE = "\033[0m"; /* end standout */
- SG = 0; /* blanks left by SG, SE */
- US = "\033[4m"; /* start underline */
- UE = "\033[0m"; /* end underline */
- UG = 0; /* blanks left by US, UE */
- UC = nullstr; /* UC must not be NULL */
- if (!*US && !*UC)
- { /* no underline mode? */
- US = SO; /* substitute standout
- * mode */
- UE = SE;
- UG = SG;
- }
- LINES = 25; /* lines per page
- * NEEDSWORK */
- COLS = 80; /* columns on page
- * NEEDSWORK */
-
- AM = TRUE; /* terminal wraps
- * automatically? */
- XN = FALSE; /* then eats next
- * newline? */
- VB = "\007";
- CR = "\r";
- #endif /* 0 */
-
- #else
- ? ? ? ? ? ? /* Roll your own... */
- #endif
-
- #endif
-
- line_col_calcs();
- noecho(); /* turn off echo */
- crmode(); /* enter cbreak mode */
-
- #ifdef PUSHBACK
- mac_init(tcbuf);
- #endif
- }
-
- #ifdef PUSHBACK
- void
- mac_init(tcbuf)
- char *tcbuf;
- {
- char tmpbuf[1024];
-
- tmpfp = fopen(filexp(getval("RNMACRO", RNMACRO)), "r");
- if (tmpfp != Nullfp)
- {
- while (fgets(tcbuf, 1024, tmpfp) != Nullch)
- {
- mac_line(tcbuf, tmpbuf, (sizeof tmpbuf));
- }
- fclose(tmpfp);
- }
- }
-
- void
- mac_line(line, tmpbuf, tbsize)
- char *line;
- char *tmpbuf;
- int tbsize;
- {
- register char *s, *m;
- register KEYMAP *curmap;
- register int ch;
- register int garbage = 0;
- static char override[] = "\nkeymap overrides string\n";
-
- if (topmap == Null(KEYMAP *))
- topmap = newkeymap();
- if (*line == '#' || *line == '\n')
- return;
- if (line[ch = strlen(line) - 1] == '\n')
- line[ch] = '\0';
- m = dointerp(tmpbuf, tbsize, line, " \t");
- if (!*m)
- return;
- while (*m == ' ' || *m == '\t')
- m++;
- for (s = tmpbuf, curmap = topmap; *s; s++)
- {
- ch = *s & 0177;
- if (s[1] == '+' && isdigit(s[2]))
- {
- s += 2;
- garbage = (*s & KM_GMASK) << KM_GSHIFT;
- }
- else
- garbage = 0;
- if (s[1])
- {
- if ((curmap->km_type[ch] & KM_TMASK) == KM_STRING)
- {
- fputs(override, stdout) FLUSH;
- free(curmap->km_ptr[ch].km_str);
- curmap->km_ptr[ch].km_str = Nullch;
- }
- curmap->km_type[ch] = KM_KEYMAP + garbage;
- if (curmap->km_ptr[ch].km_km == Null(KEYMAP *))
- curmap->km_ptr[ch].km_km = newkeymap();
- curmap = curmap->km_ptr[ch].km_km;
- }
- else
- {
- if ((curmap->km_type[ch] & KM_TMASK) == KM_KEYMAP)
- fputs(override, stdout) FLUSH;
- else
- {
- curmap->km_type[ch] = KM_STRING + garbage;
- curmap->km_ptr[ch].km_str = savestr(m);
- }
- }
- }
- }
-
- KEYMAP *
- newkeymap()
- {
- register int i;
- register KEYMAP *map;
-
- #ifndef lint
- map = (KEYMAP *) safemalloc(sizeof (KEYMAP));
- #else
- map = Null(KEYMAP *);
- #endif /* lint */
-
- for (i = 127; i >= 0; --i)
- {
- map->km_ptr[i].km_km = Null(KEYMAP *);
- map->km_type[i] = KM_NOTHIN;
- }
- return map;
- }
-
- void
- show_macros()
- {
- char prebuf[64];
-
- if (topmap != Null(KEYMAP *))
- {
- print_lines("Macros:\n", STANDOUT);
- *prebuf = '\0';
- show_keymap(topmap, prebuf);
- }
- }
-
- void
- show_keymap(curmap, prefix)
- register KEYMAP *curmap;
- char *prefix;
- {
- register int i;
- register char *next = prefix + strlen(prefix);
- register int kt;
-
- for (i = 0; i < 128; i++)
- {
- if (kt = curmap->km_type[i])
- {
- if (i < ' ')
- sprintf(next, "^%c", i + 64);
- else if (i == ' ')
- strcpy(next, "\\040");
- else if (i == 127)
- strcpy(next, "^?");
- else
- sprintf(next, "%c", i);
- if ((kt >> KM_GSHIFT) & KM_GMASK)
- {
- sprintf(cmd_buf, "+%d", (kt >> KM_GSHIFT) & KM_GMASK);
- strcat(next, cmd_buf);
- }
- switch (kt & KM_TMASK)
- {
- case KM_NOTHIN:
- sprintf(cmd_buf, "%s %c\n", prefix, i);
- print_lines(cmd_buf, NOMARKING);
- break;
- case KM_KEYMAP:
- show_keymap(curmap->km_ptr[(char) i].km_km, prefix);
- break;
- case KM_STRING:
- sprintf(cmd_buf, "%s %s\n", prefix, curmap->km_ptr[i].km_str);
- print_lines(cmd_buf, NOMARKING);
- break;
- case KM_BOGUS:
- sprintf(cmd_buf, "%s BOGUS\n", prefix);
- print_lines(cmd_buf, STANDOUT);
- break;
- }
- }
- }
- }
-
- #endif
-
- /* routine to pass to tputs */
-
- char
- putchr(ch)
- register char ch;
- {
- putchar(ch);
-
- #ifdef lint
- ch = Null(char);
- ch = ch;
- #endif
-
- return ((char) 0);
- }
-
- /* input the 2nd and succeeding characters of a multi-character command */
- /* returns TRUE if command finished, FALSE if they rubbed out first character */
-
- bool
- finish_command(donewline)
- int donewline;
- {
- register char *s;
- register bool quoteone = FALSE;
-
- s = buf;
- if (s[1] != FINISHCMD) /* someone faking up a
- * command? */
- return TRUE;
- do
- {
- top:
- if (*s < ' ')
- {
- putchar('^');
- putchar(*s | 64);
- }
- else if (*s == '\177')
- {
- putchar('^');
- putchar('?');
- }
- else
- putchar(*s); /* echo previous
- * character */
- s++;
- re_read:
- fflush(stdout);
- getcmd(s);
- if (quoteone)
- {
- quoteone = FALSE;
- continue;
- }
- if (errno || *s == Ctl('l'))
- {
- *s = Ctl('r'); /* force rewrite on CONT */
- }
- if (*s == '\033')
- { /* substitution desired? */
-
- #ifdef ESCSUBS
- char tmpbuf[4], *cpybuf;
-
- tmpbuf[0] = '%';
- read_tty(&tmpbuf[1], 1);
-
- #ifdef RAWONLY
- tmpbuf[1] &= 0177;
- #endif
-
- tmpbuf[2] = '\0';
- if (tmpbuf[1] == 'h')
- {
- (void) help_subs();
- *s = '\0';
- reprint();
- goto re_read;
- }
- else if (tmpbuf[1] == '\033')
- {
- *s = '\0';
- cpybuf = savestr(buf);
- interp(buf, (sizeof buf), cpybuf);
- free(cpybuf);
- s = buf + strlen(buf);
- reprint();
- goto re_read;
- }
- else
- {
- interp(s, (sizeof buf) - (s - buf), tmpbuf);
- fputs(s, stdout);
- s += strlen(s);
- }
- goto re_read;
- #else
- notincl("^[");
- *s = '\0';
- reprint();
- goto re_read;
- #endif
- }
- else if (*s == ERASECH)
- { /* they want to rubout a
- * char? */
- rubout();
- s--; /* discount the char
- * rubbed out */
- if (*s < ' ' || *s == '\177')
- rubout();
- if (s == buf)
- { /* entire string gone? */
- fflush(stdout); /* return to single char
- * command mode */
- return FALSE;
- }
- else
- goto re_read;
- }
- else if (*s == KILLCH)
- { /* wipe out the whole
- * line? */
- while (s-- != buf)
- { /* emulate that many
- * ERASEs */
- rubout();
- if (*s < ' ' || *s == '\177')
- rubout();
- }
- fflush(stdout);
- return FALSE; /* return to single char
- * mode */
- }
-
- #ifdef WORDERASE
- else if (*s == Ctl('w'))
- { /* wipe out one word? */
- *s-- = ' ';
- while (!isspace(*s) || isspace(s[1]))
- {
- rubout();
- if (s-- == buf)
- {
- fflush(stdout);
- return FALSE; /* return to single char
- * mode */
- }
- if (*s < ' ' || *s == '\177')
- rubout();
- }
- s++;
- goto re_read;
- }
- #endif
-
- else if (*s == Ctl('r'))
- {
- *s = '\0';
- reprint();
- goto re_read;
- }
- else if (*s == Ctl('v'))
- {
- putchar('^');
- backspace();
- fflush(stdout);
- getcmd(s);
- goto top;
- }
- else if (*s == '\\')
- {
- quoteone = TRUE;
- }
- } while (*s != '\n'); /* till a newline (not
- * echoed) */
- *s = '\0'; /* terminate the string
- * nicely */
- if (donewline)
- putchar('\n') FLUSH;
- return TRUE; /* say we succeeded */
- }
-
- /* discard any characters typed ahead */
-
- void
- eat_typeahead()
- {
-
- #ifdef PUSHBACK
- if (!typeahead && nextin == nextout) /* cancel only keyboard
- * stuff */
- #else
- if (!typeahead)
- #endif
-
- {
-
- #ifdef PENDING
- while (input_pending())
- read_tty(buf, sizeof (buf));
- #else /* this is probably v7 */
- ioctl(_tty_ch, TIOCSETP, &_tty);
- #endif
- }
- }
-
- void
- settle_down()
- {
- dingaling();
- fflush(stdout);
- sleep(1);
-
- #ifdef PUSHBACK
- nextout = nextin; /* empty circlebuf */
- #endif
-
- eat_typeahead();
- }
-
- #ifdef PUSHBACK
-
- #ifdef msdos
- /* read a character from the terminal, with multi-character pushback */
-
- int
- read_tty(addr, size)
- char *addr;
- int size;
- {
- register int i;
-
- if (nextout != nextin)
- {
- *addr = circlebuf[nextout++];
- nextout %= PUSHSIZE;
- return 1;
- }
- else
- {
- i = 0;
- do
- {
- addr[i] = getch();
-
- #ifdef RAWONLY
- addr[i] &= 0177;
- #endif
- } while (++i < size && kbhit());
- return i;
- }
- }
-
- #else /* msdos */
- /* read a character from the terminal, with multi-character pushback */
-
- int
- read_tty(addr, size)
- char *addr;
- int size;
- {
- if (nextout != nextin)
- {
- *addr = circlebuf[nextout++];
- nextout %= PUSHSIZE;
- return 1;
- }
- else
- {
- size = read(0, addr, size);
-
- #ifdef RAWONLY
- *addr &= 0177;
- #endif
-
- return size;
- }
- }
-
- #endif /* msdos */
-
- #ifdef PENDING
-
- #if ! defined (FIONREAD) && ! defined (RDCHK) && !defined(msdos)
- int
- circfill()
- {
- register int Howmany = read(devtty, circlebuf + nextin, 1);
-
- if (Howmany)
- {
- nextin += Howmany;
- nextin %= PUSHSIZE;
- }
- return Howmany;
- }
-
- #endif /* PENDING */
-
- #endif /* FIONREAD */
-
- void
- pushchar(c)
- char c;
- {
- nextout--;
- if (nextout < 0)
- nextout = PUSHSIZE - 1;
- if (nextout == nextin)
- {
- fputs("\npushback buffer overflow\n", stdout) FLUSH;
- sig_catcher(0);
- }
- circlebuf[nextout] = c;
- }
-
- #else /* PUSHBACK */
-
- #ifndef read_tty
-
- #ifdef msdos
- /* read a character from the terminal */
-
- int
- read_tty(addr, size)
- char *addr;
- int size;
- {
- register int i;
-
- for (i = 0; i < size; i++)
- {
- addr[i] = getch();
-
- #ifdef RAWONLY
- addr[i] &= 0177;
- #endif
- }
- return i;
- }
-
- #else /* msdos */
- /* read a character from the terminal, with hacks for O_NDELAY reads */
-
- int
- read_tty(addr, size)
- char *addr;
- int size;
- {
- if (is_input)
- {
- *addr = pending_ch;
- is_input = FALSE;
- return 1;
- }
- else
- {
- size = read(0, addr, size);
-
- #ifdef RAWONLY
- *addr &= 0177;
- #endif
-
- return size;
- }
- }
-
- #endif /* msdos */
-
- #endif /* read_tty */
-
- #endif /* PUSHBACK */
-
- /* print an underlined string, one way or another */
-
- void
- underprint(s)
- register char *s;
- {
- assert(UC);
- if (*UC)
- { /* char by char
- * underline? */
- while (*s)
- {
- if (*s < ' ')
- {
- putchar('^');
- backspace(); /* back up over it */
- underchar(); /* and do the underline */
- putchar(*s + 64);
- backspace(); /* back up over it */
- underchar(); /* and do the underline */
- }
- else
- {
- putchar(*s);
- backspace(); /* back up over it */
- underchar(); /* and do the underline */
- }
- s++;
- }
- }
- else
- { /* start and stop
- * underline */
- underline(); /* start underlining */
- while (*s)
- {
- if (*s < ' ')
- {
- putchar('^');
- putchar(*s + 64);
- }
- else
- putchar(*s);
- s++;
- }
- un_underline(); /* stop underlining */
- }
- }
-
- /* keep screen from flashing strangely on magic cookie terminals */
-
- #ifdef NOFIREWORKS
- void
- no_sofire()
- {
- if (*UP && *SE)
- { /* should we disable
- * fireworks? */
- putchar('\n');
- un_standout();
- up_line();
- carriage_return();
- }
- }
-
- void
- no_ulfire()
- {
- if (*UP && *US)
- { /* should we disable
- * fireworks? */
- putchar('\n');
- un_underline();
- up_line();
- carriage_return();
- }
- }
-
- #endif
-
- /* get a character into a buffer */
-
- void
- getcmd(whatbuf)
- register char *whatbuf;
- {
-
- #ifdef PUSHBACK
- register KEYMAP *curmap;
- register int i;
- bool no_macros;
- int times = 0; /* loop detector */
- char scrchar;
-
- tryagain:
- curmap = topmap;
- no_macros = (whatbuf != buf && nextin == nextout);
- #endif
-
- for (;;)
- {
- int_count = 0;
- errno = 0;
- if (read_tty(whatbuf, 1) < 0)
- if (!errno)
- errno = EINTR;
- else
- {
- perror(readerr);
- sig_catcher(0);
- }
-
- #ifdef PUSHBACK
- if (*whatbuf & 0200 || no_macros)
- {
- *whatbuf &= 0177;
- goto got_canonical;
- }
- if (curmap == Null(KEYMAP *))
- goto got_canonical;
- for (i = (curmap->km_type[*whatbuf] >> KM_GSHIFT) & KM_GMASK; i; --i)
- {
- read_tty(&scrchar, 1);
- }
- switch (curmap->km_type[*whatbuf] & KM_TMASK)
- {
- case KM_NOTHIN: /* no entry? */
- if (curmap == topmap) /* unmapped canonical */
- goto got_canonical;
- settle_down();
- goto tryagain;
- case KM_KEYMAP: /* another keymap? */
- curmap = curmap->km_ptr[*whatbuf].km_km;
- assert(curmap != Null(KEYMAP *));
- break;
- case KM_STRING: /* a string? */
- pushstring(curmap->km_ptr[*whatbuf].km_str);
- if (++times > 20)
- { /* loop? */
- fputs("\nmacro loop?\n", stdout);
- settle_down();
- }
- no_macros = FALSE;
- goto tryagain;
- }
- #else
-
- #ifdef RAWONLY
- *whatbuf &= 0177;
- #endif
-
- break;
- #endif
- }
-
- got_canonical:
-
- #ifndef TERMIO
- if (*whatbuf == '\r')
- *whatbuf = '\n';
- #endif
-
- if (whatbuf == buf)
- whatbuf[1] = FINISHCMD;/* tell finish_command
- * to work */
- }
-
- #ifdef PUSHBACK
- void
- pushstring(str)
- char *str;
- {
- register int i;
- char tmpbuf[PUSHSIZE];
- register char *s = tmpbuf;
-
- assert(str != Nullch);
- interp(s, PUSHSIZE, str);
- for (i = strlen(s) - 1; i >= 0; --i)
- {
- s[i] ^= 0200;
- pushchar(s[i]);
- }
- }
-
- #endif
-
- int
- get_anything()
- {
- char tmpbuf[2];
-
- reask_anything:
- unflush_output(); /* disable any ^O in
- * effect */
- standout();
-
- #ifdef VERBOSE
- IF(verbose)
- fputs("[Type space to continue] ", stdout);
- ELSE
- #endif
-
- #ifdef TERSE
- fputs("[MORE] ", stdout);
- #endif
-
- un_standout();
- fflush(stdout);
- eat_typeahead();
- if (int_count)
- {
- return -1;
- }
- collect_subjects(); /* loads subject cache
- * until */
- /* input is pending */
- getcmd(tmpbuf);
- if (errno || *tmpbuf == '\f')
- {
- putchar('\n') FLUSH; /* if return from stop
- * signal */
- goto reask_anything; /* give them a prompt
- * again */
- }
- if (*tmpbuf == 'h')
- {
-
- #ifdef VERBOSE
- IF(verbose)
- fputs("\nType q to quit or space to continue.\n", stdout) FLUSH;
- ELSE
- #endif
-
- #ifdef TERSE
- fputs("\nq to quit, space to continue.\n", stdout) FLUSH;
- #endif
-
- goto reask_anything;
- }
- else if (*tmpbuf != ' ' && *tmpbuf != '\n')
- {
- carriage_return();
- erase_eol(); /* erase the prompt */
- carriage_return();
- return *tmpbuf == 'q' ? -1 : *tmpbuf;
- }
- if (*tmpbuf == '\n')
- {
- page_line = LINES - 1;
- carriage_return();
- erase_eol();
- carriage_return();
- }
- else
- {
- page_line = 1;
- if (erase_screen) /* -e? */
- clear(); /* clear screen */
- else
- {
- carriage_return();
- erase_eol(); /* erase the prompt */
- carriage_return();
- }
- }
- return 0;
- }
-
- void
- in_char(prompt, newmode)
- char *prompt;
- char newmode;
- {
- char oldmode = mode;
-
- reask_in_char:
- unflush_output(); /* disable any ^O in
- * effect */
- fputs(prompt, stdout);
- fflush(stdout);
- eat_typeahead();
- mode = newmode;
- getcmd(buf);
- if (errno || *buf == '\f')
- {
- putchar('\n') FLUSH; /* if return from stop
- * signal */
- goto reask_in_char; /* give them a prompt
- * again */
- }
- mode = oldmode;
- }
-
- int
- print_lines(what_to_print, hilite)
- char *what_to_print;
- int hilite;
- {
- register char *s;
- register int i;
-
- if (page_line < 0) /* they do not want to
- * see this? */
- return -1;
- for (s = what_to_print; *s;)
- {
- if (page_line >= LINES || int_count)
- {
- if (i = -1, int_count || (i = get_anything()))
- {
- page_line = -1; /* disable further
- * print_lines */
- return i;
- }
- }
- page_line++;
- if (hilite == STANDOUT)
- {
-
- #ifdef NOFIREWORKS
- if (erase_screen)
- no_sofire();
- #endif
-
- standout();
- }
- else if (hilite == UNDERLINE)
- {
-
- #ifdef NOFIREWORKS
- if (erase_screen)
- no_ulfire();
- #endif
-
- underline();
- }
- for (i = 0; i < COLS; i++)
- {
- if (!*s)
- break;
- if (*s >= ' ')
- putchar(*s);
- else if (*s == '\t')
- {
- putchar(*s);
- i = ((i + 8) & ~7) - 1;
- }
- else if (*s == '\n')
- {
- i = 32000;
- }
- else
- {
- i++;
- putchar('^');
- putchar(*s + 64);
- }
- s++;
- }
- if (i)
- {
- if (hilite == STANDOUT)
- un_standout();
- else if (hilite == UNDERLINE)
- un_underline();
- if (AM && i == COLS)
- fflush(stdout);
- else
- putchar('\n') FLUSH;
- }
- }
- return 0;
- }
-
- void
- page_init()
- {
- page_line = 1;
- if (erase_screen)
- clear();
- else
- putchar('\n') FLUSH;
- }
-
- void
- pad(num)
- int num;
- {
-
- #ifdef msdos
- /* eventually, wait "num" ms */
- #else
- register int i;
-
- for (i = num; i; --i)
- putchar(PC);
- fflush(stdout);
- #endif /* msdos */
- }
-
- /* echo the command just typed */
-
- #ifdef VERIFY
- void
- printcmd()
- {
- if (verify && buf[1] == FINISHCMD)
- {
- if (*buf < ' ')
- {
- putchar('^');
- putchar(*buf | 64);
- backspace();
- backspace();
- }
- else
- {
- putchar(*buf);
- backspace();
- }
- fflush(stdout);
- }
- }
-
- #endif
-
- void
- rubout()
- {
- backspace(); /* do the old backspace, */
- putchar(' '); /* space, */
- backspace(); /* backspace trick */
- }
-
- void
- reprint()
- {
- register char *s;
-
- fputs("^R\n", stdout) FLUSH;
- for (s = buf; *s; s++)
- {
- if (*s < ' ')
- {
- putchar('^');
- putchar(*s | 64);
- }
- else
- putchar(*s);
- }
- }
-
- #ifdef CLEAREOL
- void
- home_cursor()
- {
-
- if (!*HO)
- { /* no home sequence? */
- if (!*CM)
- { /* no cursor motion
- * either? */
- fputs("\n\n\n", stdout);
- return; /* forget it. */
- }
- tputs(tgoto(CM, 0, 0), 1, putchr); /* go to home via CM */
- return;
- }
- else
- { /* we have home sequence */
- tputs(HO, 1, putchr); /* home via HO */
- }
- }
-
- #endif /* CLEAREOL */
-
-
- void
- line_col_calcs()
- {
- if (LINES > 0)
- { /* is this a crt? */
- if ((!initlines) || (!initlines_specified))
- /* no -i or unreasonable value for initlines */
- if (ospeed >= B9600)/* whole page at >= 9600
- * baud */
- initlines = LINES;
- else if (ospeed >= B4800) /* 16 lines at 4800 */
- initlines = 16;
- else /* otherwise just header */
- initlines = 8;
- }
-
- #ifndef msdos
- else
- { /* not a crt */
- LINES = 30000; /* so don't page */
- CL = "\n\n"; /* put a couple of lines
- * between */
- if ((!initlines) || (!initlines_specified))
- /* make initlines reasonable */
- initlines = 8;
- }
- #endif /* msdos */
-
- if (COLS <= 0)
- COLS = 80;
- }
-
-
- #ifdef SIGWINCH
- int
- winch_catcher()
- {
- /* Come here if window size change signal received */
-
- #ifdef TIOCGWINSZ
- struct winsize ws;
-
- if (ioctl(0, TIOCGWINSZ, &ws) >= 0 && ws.ws_row > 0 && ws.ws_col > 0)
- {
- LINES = ws.ws_row;
- COLS = ws.ws_col;
- line_col_calcs();
- }
- #else
- ? ? ? ? ? ? ?
- /* Well, if SIGWINCH is defined, but TIOCGWINSZ isn't, there's */
- /* almost certainly something wrong. Figure it out for yourself, */
- /* because I don't know now to deal :-) */
- #endif
- }
-
- #endif
-
- #ifdef msdos
- noecho()
- {
- }
-
- char *tgoto(char *command, int x, int y)
- {
- }
-
- crmode()
- {
- }
-
- unflush_output()
- {
- }
-
- savetty()
- {
- }
-
- resetty()
- {
- }
-
- #endif /* msdos */
-