/* * Name: MicroEMACS * Amiga console device virtual terminal display * Version: GNU v30 * Last Edit: 19-Jan-87 ...!ihnp4!seismo!ut-sally!ut-ngp!mic * Created: 19-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic * * Drives the Amiga console device display. The code * is basically like the termcap driver in that it * uses the console device scrolling region. It also * has some hacks to manage the console device colors. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef MANX #include #endif #include #undef TRUE #undef FALSE #include "def.h" #define BEL 0x07 /* BEL character. */ #define ESC 0x1B /* ESC character. */ #define LF 0x0A /* Linefeed character */ #define CSI 0x9B /* Command Sequence Introducer */ 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; #ifdef CHANGE_COLOR short mode_rendition = MODE_RENDITION, /* set standard colors */ text_rendition = TEXT_RENDITION, text_fg = TEXT_FG + 30, text_bg = TEXT_BG + 40, mode_fg = MODE_FG + 30, mode_bg = MODE_BG + 40; #else /* colors are hard-coded */ #define mode_rendition MODE_RENDITION #define text_rendition TEXT_RENDITION #define text_fg (TEXT_FG + 30) #define text_bg (TEXT_BG + 40) #define mode_fg (MODE_FG + 30) #define mode_bg (MODE_BG + 40) #endif #ifdef LATTICE VOID asciiparm(int) ; #else VOID asciiparm() ; #endif VOID ttnowindow() ; VOID ttwindow() ; /* * Initialize the terminal when the editor * Initialize the virtual terminal. * Set the console device's top edge below * the front-to-back gadgets, to avoid * garbage when scrolling. */ VOID ttinit() { ttputc(CSI); asciiparm(TOP_OFFSET); ttputc('y'); } /* * Clean up the terminal, in anticipation of * a return to the command interpreter. This * is a no-op on the Amiga, since the window * is deleted anyway. */ VOID 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! */ VOID 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. */ VOID tteeol() { ttputc(ESC); ttputc('['); ttputc('K'); } /* * Erase to end of page. */ VOID tteeop() { ttputc(ESC); /* reinforce current color values */ ttputc('['); asciiparm((tthue == CTEXT) ? text_rendition : mode_rendition); ttputc(';'); asciiparm(text_fg); ttputc(';'); asciiparm(text_bg); ttputc('m'); ttputc(ESC); /* clear to end of display */ ttputc('['); ttputc('J'); } /* * Make a noise. */ VOID ttbeep() { ttputc(BEL); ttflush(); } /* * Convert a number to decimal * ascii, and write it out. Used to * deal with numeric arguments. */ VOID asciiparm(n) register int n; { if (n > 9) asciiparm(n/10); ttputc((n%10) + '0'); } /* * Insert a block of blank lines onto the * screen, using a scrolling region that starts at row * "row" and extends down to row "bot". Deal with the one * line case, which is a little bit special, with special * case code. */ VOID ttinsl(row, bot, nchunk) { if (row == bot) { /* Funny case. */ if (nchunk != 1) panic("ttinsl: nchunk != 1"); ttmove(row, 0); tteeol(); return; } ttmove(1+bot-nchunk, 0); if (nchunk > 0) { ttwindow(row, bot); ttputc(CSI); asciiparm(nchunk); ttputc('T'); /* Scroll scrolling region down */ ttnowindow(); } } /* * 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. It's really easy with the console * device scrolling region. */ VOID ttdell(row, bot, nchunk) { if (row == bot) { /* One line special case */ ttmove(row, 0); tteeol(); return; } if (nchunk > 0) { ttwindow(row, bot); ttputc(CSI); asciiparm(nchunk); ttputc('S'); /* Scroll scrolling region up */ ttnowindow(); } ttrow = HUGE; ttcol = HUGE; ttmove(bot-nchunk,0); } /* * 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 on all systems, and avoids it. * The "ttrow" and "ttcol" variables are set to a * crazy value to ensure that ttmove() actually does * something. */ extern struct Window *EmW; /* The window MG uses */ VOID ttwindow(top,bot) { if (tttop != top || ttbot != bot) { ttputc(CSI); /* Home cursor */ ttputc('H'); ttputc(CSI); /* Set top offset */ asciiparm(TOP_OFFSET + top * FontHeight(EmW)); ttputc('y'); ttputc(CSI); asciiparm(bot - top + 1); /* Set page length */ ttputc('t'); ttrow = HUGE; /* Force cursor reset */ ttcol = HUGE; tttop = top; /* Save region state */ ttbot = bot; } } /* * Switch to full screen scrolling */ VOID ttnowindow() { ttputc(CSI); /* Home cursor */ ttputc('H'); ttputc(CSI); /* Set top offset to normal */ asciiparm(TOP_OFFSET); ttputc('y'); ttputc(CSI); /* Set page length to nrow */ asciiparm(nrow); ttputc('t'); ttrow = HUGE; /* Make cursor unknown. */ ttcol = HUGE; tttop = HUGE; ttbot = HUGE; } #ifdef CHANGE_COLOR /* * Set the rendition of the mode line by * selecting colors from the following: * 0 -- plain text * 1 -- bold-face * 3 -- italic * 4 -- underscore * 7 -- inverse video * Certain of these selections may be less than * appealing :-) */ ttmode(f, n, k) { register int s; char buf[2]; if (f == FALSE) { if ((s = ereply("Set mode line rendition (0-7): ", buf, sizeof(buf))) != TRUE) return (s); n = atoi(buf); } if (n < 0 || n > 7) return (FALSE); mode_rendition = n; /* store the color */ sgarbf = TRUE; return (TRUE); } /* * Set the rendition of the text area. * Most of these selections will be * less than appealing :-] */ tttext(f, n, k) { register int s; char buf[2]; if (f == FALSE) { if ((s = ereply("Set text rendition (0-7): ", buf, sizeof(buf))) != TRUE) return (s); n = atoi(buf); } if (n < 0 || n > 7) return (FALSE); text_rendition = n; /* store the color */ sgarbf = TRUE; return (TRUE); } /* * Set foreground color for entire window * to a value between 30 and 37, which * corresponds to the arguments 0-7. * This requires a total refresh, which * sets up the screen. */ textforeground(f, n, k) { register int s; char buf[2]; if (f == FALSE) { if ((s = ereply("Text foreground color (0-7): ", buf, sizeof(buf))) != TRUE) return (s); n = atoi(buf); } if (n < 0 || n > 7) return (FALSE); text_fg = n + 30; sgarbf = TRUE; return (TRUE); } /* * Set background color for entire window * to a value between 40 and 47 inclusive. */ textbackground(f, n, k) { register int s; char buf[2]; if (f == FALSE) { if ((s = ereply("Text background color (0-7): ", buf, sizeof(buf))) != TRUE) return (s); n = atoi(buf); } if (n < 0 || n > 7) return (FALSE); text_bg = n + 40; sgarbf = TRUE; return (TRUE); } /* * Set foreground color for entire the mode line */ modeforeground(f, n, k) { register int s; char buf[2]; if (f == FALSE) { if ((s = ereply("Mode line foreground color (0-7): ", buf, sizeof(buf))) != TRUE) return (s); n = atoi(buf); } if (n < 0 || n > 7) return (FALSE); mode_fg = n + 30; sgarbf = TRUE; return (TRUE); } /* * Set background color for the mode line */ modebackground(f, n, k) { register int s; char buf[2]; if (f == FALSE) { if ((s = ereply("Mode line background color (0-7): ", buf, sizeof(buf))) != TRUE) return (s); n = atoi(buf); } if (n < 0 || n > 7) return (FALSE); mode_bg = n + 40; sgarbf = TRUE; return (TRUE); } #endif /* * 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. */ VOID ttcolor(color) register int color; { if (color != tthue) { if (color == CTEXT) { /* Normal video. */ ttputc(ESC); /* Reset to 0 */ ttputc('['); ttputc('m'); ttputc(ESC); /* Set text style */ ttputc('['); asciiparm(text_rendition); ttputc(';'); asciiparm(text_fg); ttputc(';'); asciiparm(text_bg); ttputc('m'); } else if (color == CMODE) { /* Standout mode */ ttputc(ESC); /* Reset to 0 */ ttputc('['); ttputc('m'); ttputc(ESC); /* Set standout mode */ ttputc('['); asciiparm(mode_rendition); ttputc(';'); asciiparm(mode_fg); /* Use mode line colors */ ttputc(';'); asciiparm(mode_bg); 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, is 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. * On the Amiga, we make the Intuition terminal driver * do all the work. */ VOID ttresize() { setttysize(); }