/* * Name: MicroEMACS * AT&T UNIX PC 7300/3b1 terminal display * Version: 29 * Last edit: 25-Apr-86 * By: {sun, amdahl, mtxinu, cbosgd}!rtech!daveb * * This is nearly the ansi/tty.c, except the 7300 has broken scroll * region support with index and reverse index. Instead we do it * with parameterized insert/delete lines. * * It also has "smart" support for the window system. */ #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 = 3; /* Costs, ANSI display. */ int tcinsl = 17; int tcdell = 16; /* * Initialize the terminal when the editor * gets started up. This is a no-op on the ANSI * display. */ ttinit() { } /* * 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() { } /* * 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) { ttputc(ESC); ttputc('['); asciiparm(row+1); ttputc(';'); asciiparm(col+1); ttputc('H'); ttrow = row; ttcol = col; } } /* * Erase to end of line. */ tteeol() { ttputc(ESC); ttputc('['); ttputc('K'); } /* * Erase to end of page. */ tteeop() { ttputc(ESC); ttputc('['); ttputc('J'); } /* * Make a noise. */ ttbeep() { ttputc(BEL); ttflush(); } /* * Convert a number to decimal * ascii, and write it out. Used to * deal with numeric arguments. */ asciiparm(n) register int n; { register int q; q = n/10; if (q != 0) asciiparm(q); ttputc((n%10) + '0'); } /* * Insert a block of blank lines onto the * screen, using parameterized insert and delete line commands. * * Deal with the one * line case, which is a little bit special, with special * case code. Put all of the back index commands out * in a block. The SCALDstation loses the position * of the cursor. */ ttinsl(row, bot, nchunk) { if (row == bot) { /* Funny case. */ if (nchunk != 1) abort(); ttmove(row, 0); tteeol(); } else { /* General case. */ ttwindow(row, bot); /* delete the lines that are going away */ ttmove(bot + 1 - nchunk , 0); ttputc(ESC); ttputc('['); asciiparm( nchunk ); ttputc('M'); /* add the lines */ ttmove(row, 0); ttputc(ESC); ttputc('['); asciiparm( nchunk ); ttputc('L'); } } /* * Delete a block of lines, with the uppermost * line at row "row", in a screen slice that extends to * row "bot". The "nchunk" is the number of lines that have * to be deleted. Watch for the pathalogical 1 line case. * Done using delete and insert line commands. */ ttdell(row, bot, nchunk) { if (row == bot) { /* Funny case. */ if (nchunk != 1) abort(); ttmove(row, 0); tteeol(); } else { /* General case. */ /* delete the lines that are going away */ ttmove(row, 0); ttputc(ESC); ttputc('['); asciiparm( nchunk ); ttputc('M'); /* insert new lines to fill the empty space */ ttmove(bot + 1 - nchunk , 0); ttputc(ESC); ttputc('['); asciiparm( nchunk ); ttputc('L'); } } /* * This routine sets the scrolling window * on the display to go from line "top" to line * "bot" (origin 0, inclusive). The caller checks * for the pathalogical 1 line scroll window that * doesn't work right, and avoids it. The "ttrow" * and "ttcol" variables are set to a crazy value * to ensure that the next call to "ttmove" does * not turn into a no-op (the window adjustment * moves the cursor). */ ttwindow(top, bot) { /* No-op on 7300 */ } /* * Switch to full screen scroll. This is * used by "spawn.c" just before is suspends the * editor, and by "display.c" when it is getting ready * to exit. This function gets to full screen scroll * by sending a DECSTBM with default parameters, but * I think that this is wrong. The SRM seems to say * that the default for Pb is 24, not the size of the * screen, which seems really dumb. Do I really have * to read the size of the screen as in "ttresize" * to do this right? */ ttnowindow() { /* No-op on 7300 */ } /* * Set the current writing color to the * specified color. Watch for color changes that are * not going to do anything (the color is already right) * and don't send anything to the display. * The rainbow version does this in putline.s on a * line by line basis, so don't bother sending * out the color shift. */ ttcolor(color) register int color; { if (color != tthue) { if (color == CTEXT) { /* Normal video. */ ttputc(ESC); ttputc('['); ttputc('m'); } else if (color == CMODE) { /* Reverse video. */ ttputc(ESC); ttputc('['); ttputc('7'); ttputc('m'); } tthue = color; /* Save the color. */ } } /* * This routine is called by the * "refresh the screen" command to try and resize * the display. The new size, which must be deadstopped * to not exceed the NROW and NCOL limits, it stored * back into "nrow" and "ncol". Display can always deal * with a screen NROW by NCOL. Look in "window.c" to * see how the caller deals with a change. */ ttresize() { # if 0 register int c; register int newnrow; register int newncol; else if (newnrow > NROW) newnrow = NROW; if (newncol < 1) newncol = 1; else if (newncol > NCOL) newncol = NCOL; nrow = newnrow; ncol = newncol; # endif }