/* Copyright (c) 1983 University of Maryland Computer Science Department */ /* terminal control module for DEC VT100's */ /* Modified version of Gosling's C100 driver -- jpershing@bbn */ /* This is a somewhat primitive driver for the DEC VT100 terminal. The terminal is driven in so-called "ansi" mode, using jump scroll. It is assumed to have the Control-S misfeature disabled (although this shouldn't get in the way -- it does anyway). Specific optimization left to be done are (1) deferral of setting the window until necessary (as the escape sequence to do this is expensive) and (2) being more clever about optimizing motion (as the direct-cursor-motion sequence is also quite verbose). Also, something needs to be done about putting the terminal back into slow-scroll mode if that's the luser's preference (or perhaps having EMACS itself use slow-scroll mode [lose, lose]). */ #include #include "Trm.h" static int curX, curY; static int WindowSize; static curmodes, CurGraph; static modes (m) register m; { static char *mds[16] = { "0", "0;1", "0;4", "0;1;4", "0;5", "0;1;5", "0;4;5", "0;1;4;5", "0;7", "0;1;7", "0;4;7", "0;1;4;7", "0;5;7", "0;1;5;7", "0;4;5;7", "1;4;5;7" }; if (curmodes == m) return; printf ("\033[%sm", mds[m]); curmodes = m; } static inslines (n) register n; { printf ("\033[%d;%dr\033[%dH", curY, WindowSize, curY); curX = 1; while (--n >= 0) { printf ("\033M"); pad (1, 20.); /* DEC sez pad=30, but what do they know? */ } printf ("\033[r"); pad (1, 2.); /* ACT */ curX = curY = 1; }; static dellines (n) register n; { printf ("\033[%d;%dr\033[%dH", curY, WindowSize, WindowSize); curX = 1; curY = WindowSize; while (--n >= 0) { printf ("\033E"); pad (1, 20.); /* [see above comment] */ } printf ("\033[r"); pad (1, 2.); /* ACT */ curX = curY = 1; }; static Baud; static writechars (start, end) register char *start, *end; { register count = 0; while (start <= end) { if (*start & 0x80) { if (CurGraph == 0) { printf ("\033(0"); CurGraph++; } putchar (*start++ & 0x7f); } else { if (CurGraph && *start != ' ') { printf ("\033(B"); CurGraph = 0; } putchar (*start++); } curX++; if (count++ > 15 && Baud > 9600) count = 0, pad (1, 2.5);/* ACT */ } }; static blanks (n) register n; { while (--n >= 0) { putchar (' '); curX++; } }; static float BaudFactor; static pad(n,f) register n; register float f; { register k = n * f * BaudFactor; while (--k >= 0) putchar (0); }; static /* This routine needs lots of work */ topos (row, column) register row, column; { register k; if (curY == row) { k = curX - column; if (k) { if (k > 0 && k < 4) { while (k--) putchar(010); goto done; } } else return; } if (curY + 1 == row && (column == 1 || column==curX)) { if(column!=curX) putchar (015); putchar (012); goto done; } if (row == 1 && column == 1) { printf ("\033[H"); pad (1, 5.); /* ACT */ goto done; } printf ("\033[%d;%dH", row, column ); pad (1, 5.); /* ACT */ done: curX = column; curY = row; }; static init (BaudRate) { static inited = 0; if (!inited) { char *getenv(); static char tbuf[1024]; /* ACT Try for termcap's co# */ register char *t = getenv ("COL"); W_tt.t_width = t ? atoi (t) : ((t = getenv ("TERM")) && tgetent (tbuf,t)>0) ? tgetnum ("co") : 80; } Baud = BaudRate; BaudFactor = BaudRate/10000.; W_tt.t_ILmf = 0.0; W_tt.t_ILov = 15 + 2+BaudFactor*20.; return 0; }; static reset () { printf ("\033<\033[r\033[m\033[?4;6l\033[2J\033(B\017");/* Whew! */ if (InverseVideo) printf ("\033[?5h");/* Use inverse video */ pad (1, 55.); WindowSize = 24; curmodes = 0; CurGraph = 0; curX = curY = 1; }; static cleanup () { modes (0); if (CurGraph) { printf ("\033(B"); CurGraph = 0; } window (0); topos (WindowSize, 1); wipeline (); }; static wipeline () { printf("\033[K"); pad (1, 2.); }; static wipescreen () { printf("\033[2J"); pad (1, 60.); /* ACT was 45. */ }; static window (n) register n; { if (n <= 0 || n > 24) n = 24; WindowSize = n; } /* Visible Bell for DT80/1 -ACT */ static flash () { printf (InverseVideo ? "\033[?5l" : "\033[?5h"); pad (1, 40.); printf (InverseVideo ? "\033[?5h" : "\033[?5l"); } /* Turn off graphics mode */ static donerefresh () { if (CurGraph) { printf ("\033(B"); CurGraph = 0; } } TrmVT100 () { W_tt.t_INSmode = NoOperation; W_tt.t_modes = modes; W_tt.t_inslines = inslines; W_tt.t_dellines = dellines; W_tt.t_blanks = blanks; W_tt.t_init = init; W_tt.t_cleanup = cleanup; W_tt.t_wipeline = wipeline; W_tt.t_wipescreen = wipescreen; W_tt.t_topos = topos; W_tt.t_reset = reset; W_tt.t_delchars = 0; W_tt.t_writechars = writechars; W_tt.t_window = window; W_tt.t_flash = flash; W_tt.t_donerefresh = donerefresh; W_tt.t_ILmf = 0; W_tt.t_ILov = 0; W_tt.t_ICmf = MissingFeature; W_tt.t_ICov = MissingFeature; W_tt.t_DCmf = MissingFeature; W_tt.t_DCov = MissingFeature; W_tt.t_length = 24; W_tt.t_width = 80; W_tt.t_frames[0] = 'l' | 0x80; /* ulc */ W_tt.t_frames[1] = W_tt.t_frames[6] = 'q' | 0x80; /* top, bottom */ W_tt.t_frames[2] = 'k' | 0x80; /* urc */ W_tt.t_frames[3] = W_tt.t_frames[4] = 'x' | 0x80; /* left, right sides */ W_tt.t_frames[5] = 'm' | 0x80; /* llc */ W_tt.t_frames[7] = 'j' | 0x80; /* lrc */ return 0; };