|
|
1.1 ! root 1: /* ! 2: * Screen control routines for termcap. ! 3: * A good example of how to use termcap. ! 4: * For more information get ! 5: * Termcap & Terminfo ! 6: * O'Reilly & Associates, Inc. ! 7: * ISBN 0-93717522-6 ! 8: */ ! 9: #include <stdio.h> ! 10: #include <sgtty.h> ! 11: #include "ed.h" ! 12: ! 13: #if TERMCAP ! 14: ! 15: #define NROW 24 /* default rows on the screen */ ! 16: #define NCOL 80 /* default columns on the screen */ ! 17: #define BEL 0x07 ! 18: #define ESC 0x1B ! 19: ! 20: #define TERMBUF 1024 /* the largest buffer termcap can use */ ! 21: ! 22: extern int ttopen(); ! 23: extern int ttgetc(); ! 24: extern int ttputc(); ! 25: extern int ttflush(); ! 26: extern int ttclose(); ! 27: extern int tcapmove(); ! 28: extern int tcapeeol(); ! 29: extern int tcapeeop(); ! 30: extern int tcapbeep(); ! 31: extern int tcapopen(); ! 32: extern int tcapstand(); ! 33: extern int tput(); ! 34: extern char *tgoto(); ! 35: extern char *tgetstr(); ! 36: extern char *realloc(); ! 37: ! 38: /* pointers to various tcap strings */ ! 39: static char *CM, *CE, *CL, *SO, *SE; ! 40: static uchar *ptr; /* pointer to first free spot in termcap buffer */ ! 41: ! 42: ! 43: TERM term = { ! 44: NROW-1, ! 45: NCOL, ! 46: tcapopen, ! 47: ttclose, ! 48: ttgetc, ! 49: ttputc, ! 50: ttflush, ! 51: tcapmove, ! 52: tcapeeol, ! 53: tcapeeop, ! 54: tcapbeep, ! 55: tcapstand ! 56: }; ! 57: ! 58: /* ! 59: * Get a required termcap string or exit with a message. ! 60: */ ! 61: static uchar * ! 62: qgetstr(ref) ! 63: register uchar *ref; ! 64: { ! 65: register uchar *tmp; ! 66: ! 67: if (NULL == (tmp = tgetstr(ref, &ptr))) { ! 68: printf("/etc/termcap must have a '%s' entry\n", ref); ! 69: exit(1); ! 70: } ! 71: return (tmp); ! 72: } ! 73: ! 74: /* ! 75: * Get termcap information for this terminal type ! 76: */ ! 77: tcapopen() ! 78: { ! 79: /* buffer for the strings we need to keep */ ! 80: static uchar *tcapbuf = NULL; ! 81: uchar tcbuf[TERMBUF]; /* address saved by termcap for tgetstr */ ! 82: ! 83: if (NULL != tcapbuf) { /* we've been here before */ ! 84: ttopen(); ! 85: return; ! 86: } ! 87: ! 88: /* ! 89: * Set up termcap type. ! 90: */ ! 91: { ! 92: extern char *getenv(); ! 93: uchar *tv_stype; ! 94: ! 95: if ((tv_stype = getenv("TERM")) == NULL) { ! 96: puts("Environment variable TERM not defined!"); ! 97: exit(1); ! 98: } ! 99: ! 100: if (tgetent(tcbuf, tv_stype) != 1) { ! 101: printf("Unknown terminal type %s!\n", tv_stype); ! 102: exit(1); ! 103: } ! 104: } ! 105: ! 106: /* ! 107: * Get termcap entries for later use. ! 108: */ ! 109: { ! 110: extern short ospeed; /* termcap's device speed */ ! 111: extern char PC; /* termcap's pad character */ ! 112: char *p; ! 113: struct sgttyb tty; ! 114: ! 115: ospeed = 0; /* set terminal output speed */ ! 116: if (isatty(fileno(stdout))) { ! 117: gtty(fileno(stdout), &tty); ! 118: ospeed = tty.sg_ospeed; ! 119: } ! 120: ! 121: /* get far too much space and shrink later */ ! 122: if (NULL == (ptr = tcapbuf = malloc(TERMBUF))) ! 123: abort(); ! 124: ! 125: /* ! 126: * Get required entries. There must be cd= clear after cursor ! 127: * or cl= clear screen ! 128: */ ! 129: if (NULL == (CL = tgetstr("cl", &ptr))) ! 130: CL = qgetstr("cd"); ! 131: ! 132: CM = qgetstr("cm"); /* move cursor to row, col */ ! 133: CE = qgetstr("ce"); /* clear to end of line */ ! 134: ! 135: /* Get optional entries. */ ! 136: SO = tgetstr("so", &ptr); /* begin standout mode */ ! 137: SE = tgetstr("se", &ptr); /* end standout mode */ ! 138: ! 139: /* set termcap's pad char */ ! 140: PC = ((NULL == (p = tgetstr("pc", &ptr))) ? 0 : *p); ! 141: ! 142: /* ! 143: * check that realloc truncates buffer in place. ! 144: */ ! 145: if (tcapbuf != realloc(tcapbuf, (unsigned)(ptr - tcapbuf))) ! 146: { ! 147: puts("Buffer not shrunk in place!\n"); ! 148: exit(1); ! 149: } ! 150: } ! 151: ! 152: /* ! 153: * Get the number of lines and collumns for the terminal. ! 154: * Leave NCOL and NROW if data is not there. ! 155: */ ! 156: { ! 157: int i; ! 158: extern int tgetnum(); ! 159: ! 160: if (0 < (i = tgetnum("co"))) ! 161: term.t_ncol = i; ! 162: if (0 < (i = tgetnum("li"))) ! 163: term.t_nrow = i - 1; ! 164: } ! 165: ! 166: ttopen(); ! 167: } ! 168: ! 169: /* ! 170: * Move to row and collum. ! 171: */ ! 172: tcapmove(row, col) ! 173: register int row, col; ! 174: { ! 175: putpad(tgoto(CM, col, row)); ! 176: } ! 177: ! 178: /* ! 179: * Clear to end of line. ! 180: */ ! 181: tcapeeol() ! 182: { ! 183: putpad(CE); ! 184: } ! 185: ! 186: /* ! 187: * Clear screen. The CL command may contain either clear screen cl= ! 188: * or clear from cursor to end of screen cd=. ! 189: */ ! 190: tcapeeop() ! 191: { ! 192: tcapmove(0, 0); ! 193: putpad(CL); ! 194: } ! 195: ! 196: /* ! 197: * Say beep. ! 198: */ ! 199: tcapbeep() ! 200: { ! 201: ttputc(BEL); ! 202: } ! 203: ! 204: /* ! 205: * output string, set padding to one line affected. ! 206: */ ! 207: putpad(str) ! 208: uchar *str; ! 209: { ! 210: tputs(str, 1, ttputc); ! 211: } ! 212: ! 213: /* ! 214: * if (f) ! 215: * Put terminal in standout, if possible. ! 216: * else ! 217: * Take terminal out of standout, if possible. ! 218: * ! 219: * Used for status line standout mode. ! 220: */ ! 221: tcapstand(f) ! 222: { ! 223: register char *msg; ! 224: ! 225: if (NULL != (msg = (f ? SO : SE))) ! 226: putpad(msg); ! 227: } ! 228: #endif TERMCAP
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.