/* * Name: MicroEMACS * UNIX termcap/terminfo display driver * Version: 2 * Last edit: 16-Apr-86 * By: paul@ohio-state * cbosgd!osu-eddie!paul * * Termcap is a terminal information database and routines to describe * terminals on a UNIX system. This should be used ALLWAYS on a UNIX system * that has it. */ #include "def.h" #define BEL 0x07 /* BEL character. */ #define ESC 0x1B /* ESC character. */ #define LF 0x0A /* Line feed. */ extern int ttrow; extern int ttcol; extern int tttop; extern int ttbot; extern int tthue; int tceeol; /* Costs are set later */ int tcinsl; int tcdell; #define TCAPSLEN 315 char tcapbuf[TCAPSLEN]; char PC, *CM, *CL, *CE, *UP, *IM, /* insert mode */ *IC, /* insert a single space */ *EI, /* end insert mode */ *DC, *AL, /* add line */ *DL, /* del line */ *TI, /* term init -- start using cursor motion */ *TE, /* term end --- end using cursor motion */ *SO, *SE, *CD; /* * Initialize the terminal when the editor * gets started up. This is a no-op on the ANSI * display. On the SCALD display, it turns off the * half-screen scroll, because this appears to really * confuse the scrolling region firmware in the * display. */ static char tcbuf[1024]; ttinit() { char *getenv(); char *t, *p, *tgetstr(); char *tv_stype; char err_str[72]; if ((tv_stype = getenv("TERM")) == NULL) { puts("Environment variable TERM not defined!"); exit(1); } if((tgetent(tcbuf, tv_stype)) != 1) { sprintf(err_str, "Unknown terminal type %s!", tv_stype); puts(err_str); exit(1); } p = tcapbuf; t = tgetstr("pc", &p); if(t) PC = *t; CD = tgetstr("cd", &p); CM = tgetstr("cm", &p); CE = tgetstr("ce", &p); UP = tgetstr("up", &p); IM = tgetstr("im", &p); IC = tgetstr("ic", &p); EI = tgetstr("ei", &p); DC = tgetstr("dc", &p); AL = tgetstr("al", &p); DL = tgetstr("dl", &p); TI = tgetstr("ti", &p); TE = tgetstr("te", &p); SO = tgetstr("so", &p); SE = tgetstr("se", &p); if(CD == NULL || CM == NULL || CE == NULL || UP == NULL) { puts("This terminal is not powerful enough to run Micro Emacs\n"); exit(1); } if (!*CE) { tceeol = ncol; } else { tceeol = charcost(CE); } if (AL == NULL || !*AL) { tcinsl = nrow * ncol; /* make this cost high enough that it */ /* won't ever happen */ } else { tcinsl = charcost(AL); } if (DL == NULL || !*DL) { tcdell = nrow * ncol; /* make this cost high enough that it */ /* won't ever happen */ } else { tcdell = charcost(DL); } if (p >= &tcapbuf[TCAPSLEN]) { puts("Terminal description too big!\n"); exit(1); } if (TI != NULL && *TI) tputs (TI); /* init the term */ } /* * Clean up the terminal, in anticipation of * a return to the command interpreter. This is a no-op * on the ANSI display. On the SCALD display, it sets the * window back to half screen scrolling. Perhaps it should * query the display for the increment, and put it * back to what it was. */ tttidy() { if (TE != NULL && *TE) tputs (TE); /* set the term back to normal mode */ } /* * Move the cursor to the specified * origin 0 row and column position. Try to * optimize out extra moves; redisplay may * have left the cursor in the right * location last time! */ ttmove(row, col) { if (ttrow!=row || ttcol!=col) { putpad(tgoto(CM, col, row)); ttrow = row; ttcol = col; } } /* * Erase to end of line. */ tteeol() { putpad(CE); } /* * Erase to end of page. */ tteeop() { putpad(CD); } /* * Make a noise. */ ttbeep() { ttputc(BEL); ttflush(); } /* * Insert nchunk blank line(s) onto the * screen, scrolling the last line on the * screen off the bottom. This is done with * a cluster of clever insert and delete commands, * because there are no scroll regions. */ ttinsl(row, bot, nchunk) { register int i; if (row == bot) { /* Case of one line insert is */ ttmove(row, 0); /* special */ tteeol(); return; } ttmove(1+bot-nchunk, 0); for (i=0; i NROW) newnrow = NROW; if (newncol < 1) newncol = 1; else if (newncol > NCOL) newncol = NCOL; nrow = newnrow; ncol = newncol; } static int cci; static fakec(c) /* fake char output for charcost() */ char c; { cci++; } charcost (s) /* calculate the cost of doing string s */ char *s; { cci = 0; tputs(s, nrow, fakec); return cci; } putpad(str) char *str; { tputs(str, 1, ttputc); }