[net.emacs] wide-screen editing with emacs

zorat (03/05/83)

I had the same problem regarding the number of lines on my ambassador:
in general I like to use 30 lines, but occasionally I like to have all
60 of them on the screen.
Here was my changes to display.c and the ambassador and vt100 drivers:
(to get 132 columns on screen, you then type 
ESC-x columns-on-screen 132)
(to extract the 3 files, edit this message and put the next part,
starting with :Run this through sh (not csh), in some file (say  tmp), 
possibly in a clean directory. Go to that directory and type 
sh tmp
to get the three files.

: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
/bin/echo 'Extracting display.c'
sed 's/^X//' <<'//go.sysin dd *' >display.c
X#define ACT
X/* Ultra-hot screen management package
X  		James Gosling, January 1980			*/
X
X/*		Copyright (c) 1981,1980 James Gosling		*/
X
X/****************************************************************
X
X
X
X			 /-------------\
X			/		\
X		       /		 \
X		      /			  \
X		      |	  XXXX	   XXXX	  |
X		      |	  XXXX	   XXXX	  |
X		      |	  XXX	    XXX	  |
X		      \		X	  /
X		       --\     XXX     /--
X			| |    XXX    | |
X			| |	      | |
X			| I I I I I I I |
X			|  I I I I I I	|
X			 \	       /
X			  --	     --
X			    \-------/
X		    XXX			   XXX
X		   XXXXX		  XXXXX
X		   XXXXXXXXX	     XXXXXXXXXX
X			  XXXXX	  XXXXX
X			     XXXXXXX
X			  XXXXX	  XXXXX
X		   XXXXXXXXX	     XXXXXXXXXX
X		   XXXXX		  XXXXX
X		    XXX			   XXX
X
X			  **************
X			  *  BEWARE!!  *
X			  **************
X
X			All ye who enter here:
X		    Most of the code in this module
X		       is twisted beyond belief!
X
X			   Tread carefully.
X
X		    If you think you understand it,
X			      You Don't,
X			    So Look Again.
X
X ****************************************************************/
X
X/* DJH -- Added Ding() for bell */
X
X
X#include "display.h"
X#include "window.h"
X#include "keyboard.h"
X#include "mlisp.h"
X#include <sgtty.h>
X
X/* the following macros are used to access terminal specific routines.
X   Really, no one outside of display.c should be using them, except for
X   the initialize/cleanup routines */
X#define topos (*tt.t_topos)
X#define reset (*tt.t_reset)
X#define INSmode (*tt.t_INSmode)
X#define insertlines (*tt.t_inslines)
X#define deletelines (*tt.t_dellines)
X#define blanks (*tt.t_blanks)
X#define wipeline (*tt.t_wipeline)
X#define wipescreen (*tt.t_wipescreen)
X#define deletechars (*tt.t_delchars)
X#define dumpstring (*tt.t_writechars)
X
X#define MScreenWidth 135
X#define MScreenLength 70
X#define min(a,b) (a<b ? a : b)
X#define max(a,b) (a>b ? a : b)
X#define hidden static
X#define visible
X#define procedure
X#define function
X
Xhidden struct line {		/* a line as it appears in a list of
X				   lines (as in the physical and virtual
X				   display lists) */
X    int     hash;		/* hash value for this line, 0 if not
X				   known */
X    struct line *next;		/* pointer to the next line in a list of
X				   lines */
X    short   DrawCost;		/* the cost of redrawing this line */
X    short   length;		/* the number of valid characters in the
X				   line */
X    char    highlighted;	/* true iff this line is to be
X				   highlighted */
X    char    body[MScreenWidth];	/* the actual text of the line */
X}
X                   *FreeLines;	/* free space list */
X
Xhidden WindowSize;		/* the number of lines on which line ID
X				   operations should be done */
Xint baud_rate;			/* Terminal speed, so we can calculate
X				   the number of characters required to
X				   make the cursor sit still for n secs. */
Xhidden CheckForInput;		/* -ve iff UpdateLine should bother
X				   checking for input */
X
X/* 'newline' returns a pointer to a new line object, either from the
X   free list or from the general unix pool */
Xstruct line *newline () {
X    register struct line   *p = FreeLines;
X
X    if (p) {
X	FreeLines = p -> next;
X	if (p -> hash != 12345) {
X/*	    register FILE *f = fopen ("EMACS_TRACE", "w");
X	    topos (23, 1);
X	    printf ("*****Bogus value in display free list"); */
X	    FreeLines = 0;
X/*	    if (f) {
X		register int *p1 = ((int *) p) - 10;
X		register char *p2 = (char *) p1;
X		register i;
X		fprintf (f, "Bogus value in display free list at %o\n", p);
X		for (i=0; i<25; i++) {
X		    fprintf (f, "%11o: %011o %9d  %03o %03o %03o %03o\n",
X				p1, *p1, *p1,
X				p2[0], p2[1], p2[2], p2[3]);
X		    p1++; p2 += 4;
X		}
X		fclose (f);
X	    } */
X	    return newline ();
X	}
X    }
X    else {
X	static Leakage;
X	p = (struct line   *) malloc (sizeof *p);
X	if (++Leakage>(2*MScreenLength)) printf ("*****Display core leakage!");
X    }
X    p -> length = 0;
X    p -> hash = 0;
X    p -> highlighted = 0;
X    return p;
X}
X
X/* 'ReleaseLine' returns a line object to the free list */
Xhidden procedure ReleaseLine (p)
Xregister struct line   *p; {
X    if (p) {
X	if (p -> hash == 12345) {
X	    printf("\rBogus re-release!");
X	    fflush(stdout);
X	    /* abort(); */
X	    return;
X	}
X	p -> next = FreeLines;
X	p -> hash = 12345;
X	FreeLines = p;
X    }
X}
X
Xhidden struct line *PhysScreen[MScreenLength + 1];
X /* the current (physical) screen */
Xhidden struct line *DesiredScreen[MScreenLength + 1];
X /* the desired (virtual) screen */
X
Xvisible int
X            ScreenGarbaged,	/* set to 1 iff screen content is
X				   uncertain. */
X            RDdebug,		/* line redraw debug switch */
X            IDdebug,		/* line insertion/deletion debug */
X            cursX,		/* X and Y coordinates of the cursor */
X            cursY,		/* between updates. */
X            CurrentLine,	/* current line for writing to the
X				   virtual screen. */
X            left;		/* number of columns left on the current
X				   line of the virtual screen. */
Xvisible char
X               *cursor;		/* pointer into a line object, indicates
X				   where to put the next character */
X
X
X/* 'setpos' positions the cursor at position (row,col) in the virtual
X   screen */
Xvisible procedure setpos (row, col)
Xregister    row,
X            col; {
X    register struct line   *p;
X    register    n;
X
X    if (CurrentLine >= 0
X	    && (p = DesiredScreen[CurrentLine]) -> length
X	    <= (n = ScreenWidth - left))
X	p -> length = left > 0 ? n : ScreenWidth;
X    if (!DesiredScreen[row])
X	DesiredScreen[row] = newline ();
X    (p = DesiredScreen[row]) -> hash = 0;
X    while (p -> length + 1 < col)
X	p -> body[p -> length++] = ' ';
X    CurrentLine = row;
X    left = ScreenWidth + 1 - col;
X    cursor = &DesiredScreen[row] -> body[col - 1];
X}
X
X/* 'clearline' positions the cursor at the beginning of the
X   indicated line and clears the line (in the image) */
Xclearline (row) {
X    setpos (row, 1);
X    DesiredScreen[row] -> length = 0;
X}
X
X/* 'HighLine' causes the current line to be highlighted */
XHighLine () {
X    if (CurrentLine >= 0)
X	DesiredScreen[CurrentLine] -> highlighted++;
X}
X
X/* 'hashline' computes a hash value for a line, unless the hash value
X   is already known.  This hash code has a few important properties:
X	- it is independant of the number of leading and trailing spaces
X	- it will never be zero
X 
X   As a side effect, an estimate of the cost of redrawing the line is
X   calculated */
Xhidden procedure hashline (p)
Xregister struct line   *p; {
X    register char  *c,
X                   *l;
X    register    h;
X
X    if (!p || p -> hash) {
X	if (p && p->hash==12345) printf ("****Free line in screen");
X	return;
X    }
X    h = 0;
X    c = p -> body;
X    l = &p -> body[p -> length];
X    while (--l > c && *l == ' ');
X    while (c <= l && *c == ' ')
X	c++;
X    p -> DrawCost = l - c + 1;
X    if (p -> highlighted) {
X	p -> hash = -200;
X	return;
X    }
X    while (c <= l)
X	h = (h << 5) + h + *c++;
X    p -> hash = h!=12345 && h ? h : 1;
X}
X
X/*	1   2   3   4   ....	Each Mij represents the minumum cost of
X      +---+---+---+---+-----	rearranging the first i lines to map onto
X    1 |   |   |   |   |		the first j lines (the j direction
X      +---+---+---+---+-----	represents the desired contents of a line,
X    2 |   |  \| ^ |   |		i the current contents).  The algorithm
X      +---+---\-|-+---+-----	used is a dynamic programming one, where
X    3 |   | <-+Mij|   |		M[i,j] = min( M[i-1,j],
X      +---+---+---+---+-----		      M[i,j-1]+redraw cost for j,2
X    4 |   |   |   |   |			      M[i-1,j-1]+the cost of
X      +---+---+---+---+-----			converting line i to line j);
X    . |   |   |   |   |		Line i can be converted to line j by either
X    .				just drawing j, or if they match, by moving
X    .				line i to line j (with insert/delete line)
X */
X
Xhidden struct Msquare {
X    short   cost;		/* the value of Mij */
X    char    fromi,
X            fromj;		/* the coordinates of the square that
X				   the optimal move comes from */
X}                       M[MScreenLength + 1][MScreenLength + 1];
X
Xhidden procedure calcM () {
X    register struct Msquare *p;
X    register    i,
X                j,
X                movecost,
X                cost;
X    int     reDrawCost,
X            idcost,
X            leftcost;
X    double  fidcost;
X
X    cost = 0;
X    movecost = 0;
X    for (i = 0; i <= ScreenLength; i++) {
X	p = &M[i][0];
X/*	M[i][i].cost = 0;  */
X	p[i].cost = 0;
X	M[0][i].cost = cost + movecost;
X/*	M[i][0].cost = movecost;  */
X	p[0].cost = movecost;
X	M[0][i].fromi = 0; 
X/*	M[0][i].fromj = M[i][i].fromj = i - 1;  */
X	M[0][i].fromj = p[i].fromj = i - 1;
X/*	M[i][0].fromi = M[i][i].fromi = i - 1;  */
X	p[0].fromi = p[i].fromi = i - 1;
X/*	M[i][0].fromj = 0;  */
X	p[0].fromj = 0;
X	movecost += tt.t_ILmf * (ScreenLength - i) + tt.t_ILov;
X	if (DesiredScreen[i + 1])
X	    cost += DesiredScreen[i + 1] -> DrawCost;
X    }
X
X    fidcost = tt.t_ILmf * (WindowSize + 1) + tt.t_ILov;
X    for (i = 1; i <= WindowSize; i++)
X    {
X	p = &M[i][0];
X	fidcost -= tt.t_ILmf;
X	idcost = fidcost;
X	for (j = 1; j <= WindowSize; j++) {
X	    p++; 
X/*	    p = &M[i][j]; */
X	    cost =  DesiredScreen[j] ? DesiredScreen[j] -> DrawCost : 0;
X	    reDrawCost = cost;
X	    if (PhysScreen[i] && DesiredScreen[j]
X		    && PhysScreen[i] -> hash == DesiredScreen[j] -> hash)
X		cost = 0;
X/*	    idcost = tt.t_ILmf * (WindowSize - i + 1) + tt.t_ILov; */
X/*	    movecost = M[i - 1][j].cost + (j == WindowSize ? 0 : idcost); */
X	    movecost = p[-MScreenLength-1].cost
X				+ (j == WindowSize ? 0 : idcost);
X	    p -> fromi = i - 1;	/* now using movecost for */
X	    p -> fromj = j;	/* the minumum cost. */
X	    if ((
X/*			leftcost = M[i][j - 1].cost */
X			leftcost = p[-1].cost
X				+ (i == WindowSize ? 0 : idcost) + reDrawCost
X		    ) < movecost) {
X		movecost = leftcost;
X		p -> fromi = i;
X		p -> fromj = j - 1;
X	    }
X/*	    cost += M[i - 1][j - 1].cost; */
X	    cost += p[-MScreenLength-2].cost;
X	    if (cost < movecost)
X		movecost = cost,
X		    p -> fromi = i - 1, p -> fromj = j - 1;
X	    p -> cost = movecost;
X	}
X    }
X}
X
X/* calculate and perform the optimal sequence of insertions/deltions
X   given the matrix M from routine calcM */
X
Xhidden procedure CalcID (i, j, InsertsDesired)
Xregister    i,
X            j; {
X    register    ni,
X                nj;
X    register struct Msquare *p = &M[i][j];
X    if (i > 0 || j > 0) {
X	ni = p -> fromi;
X	nj = p -> fromj;
X	if (ni == i) {
X	    CalcID (ni, nj, i != WindowSize ? InsertsDesired + 1 : 0);
X	    InsertsDesired = 0;
X	    if (InputPending) {
X		if (PhysScreen[j] != DesiredScreen[j])
X		    ReleaseLine (PhysScreen[j]);
X		PhysScreen[j] = 0;
X		ReleaseLine (DesiredScreen[j]);
X		DesiredScreen[j] = 0;
X		LastRedisplayPaused++;
X	    }
X	    else {
X		UpdateLine ((struct line *) 0, DesiredScreen[j], j);
X		if (PhysScreen[j] != DesiredScreen[j])
X		    ReleaseLine (PhysScreen[j]);
X		PhysScreen[j] = DesiredScreen[j];
X		DesiredScreen[j] = 0;
X	    }
X	}
X	else
X	    if (nj == j) {
X		if (j != WindowSize) {
X		    register    nni,
X		                dlc = 1;
X		    for (; ni;) {
X			p = &M[ni][nj];
X			nni = p -> fromi;
X			if (p -> fromj == nj) {
X			    dlc++;
X			    ni = nni;
X			}
X			else
X			    break;
X		    }
X		    topos (i - dlc + 1, 1);
X		    deletelines (dlc);
X		}
X		CalcID (ni, nj, 0);
X	    }
X	    else {
X		register struct line   *old = PhysScreen[i];
X		register    DoneEarly = 0;
X		if (old == DesiredScreen[i]) DesiredScreen[i] = 0;
X		PhysScreen[i] = 0;
X
X	    /* The following hack and all following lines involving the
X	       variable "DoneEarly" cause the bottom line of the screen to
X	       be redisplayed before any others if it has changed and it
X	       would be redrawn in-place.  This is purely for Emacs,
X	       people using this package for other things might want to
X	       lobotomize this section. */
X		if (i == ScreenLength && j == ScreenLength
X/*			&& old != PhysScreen[j]) { */
X			&& DesiredScreen[j]) {
X		    DoneEarly++;
X		    UpdateLine (old, DesiredScreen[j], j);
X		}
X		CalcID (ni, nj, 0);
X		if (InputPending && !DoneEarly) {
X		    if (PhysScreen[j] != old)
X			ReleaseLine (PhysScreen[j]);
X		    if (DesiredScreen[j] != old
X			    && DesiredScreen[j] != PhysScreen[j])
X			ReleaseLine (DesiredScreen[j]);
X		    PhysScreen[j] = old;
X		    DesiredScreen[j] = 0;
X		    LastRedisplayPaused++;
X		}
X		else {
X		    if (!DoneEarly && (DesiredScreen[j] || i != j))
X			UpdateLine (old, DesiredScreen[j], j);
X		    if (PhysScreen[j] != DesiredScreen[j])
X			ReleaseLine (PhysScreen[j]);
X		    if (old != DesiredScreen[j] && old != PhysScreen[j])
X			ReleaseLine (old);
X		    PhysScreen[j] = DesiredScreen[j];
X		    DesiredScreen[j] = 0;
X		}
X	    }
X    }
X    if (InsertsDesired) {
X	topos (j + 1, 1);
X	insertlines (InsertsDesired);
X    }
X}
X
X/* modify current screen line 'old' to match desired line 'new',
X   the old line is at position ln.  Each line
X   is scanned and partitioned into 4 regions:
X
X	     <osp><----m1-----><-od--><----m2----->
X    old:    "     Twas brillig and the slithy toves"
X    new:    "        Twas brillig where a slithy toves"
X             <-nsp--><----m1-----><-nd--><----m2----->
X
X	nsp, osp	- number of leading spaces on each line
X	m1		- length of a leading matching sequence
X	m2		- length of a trailing matching sequence
X	nd, od		- length of the differing sequences
X */
Xhidden procedure UpdateLine (old, new, ln)
Xregister struct line	*old,
X			*new; {
X    register char	*op,
X			*np,
X			*ol,
X			*nl;
X    int	osp,
X	nsp,
X	m1,
X	m2,
X	od,
X	nd,
X	OldHL,
X	NewHL,
X	t,
X	OldLineWipeTo;
X
X    if (old == new)
X	return;
X    if (old) {
X	op = old -> body;
X	ol = &old -> body[OldLineWipeTo = old -> length];
X	OldHL = old -> highlighted;
X    }
X    else
X	op = "", ol = op, OldHL = 0, OldLineWipeTo = 1;
X    if (new) {
X	np = new -> body;
X	nl = &new -> body[new -> length];
X	NewHL = new -> highlighted;
X    }
X    else
X	np = "", nl = np, NewHL = 0;
X    osp = nsp = m1 = m2 = od = od = 0;
X
X/* calculate the magic parameters */
X    if (NewHL == OldHL) {
X	while (*--ol == ' ' && ol >= op) --OldLineWipeTo;
X	while (*--nl == ' ' && nl >= np);
X	while (*op == ' ' && op <= ol)
X	    op++, osp++;
X	while (*np == ' ' && np <= nl)
X	    np++, nsp++;
X#ifdef ACT
X	if (!NewHL && ol < op && !tt.t_needspaces)
X	    osp = nsp;
X#endif
X	while (*op == *np && op <= ol && np <= nl)
X	    op++, np++, m1++;
X#ifdef ACT
X	if (!NewHL && op > ol && !tt.t_needspaces)
X	    while (*np == ' ' && np <= nl)
X		np++, m1++;
X#endif
X	while (*ol == *nl && op <= ol && np <= nl)
X	    ol--, nl--, m2++;
X    }
X    else {
X	ol--;
X	nl--;
X	osp = 0;
X	while (*np == ' ' && np < nl)
X	    np++, nsp++;
X    }
X    od = ol - op + 1;
X    nd = nl - np + 1;
X
X/* forget matches which would be expensive to capitalize on */
X    if (m1 || m2) {
X	register int    c0,
X	                c1,
X	                c2,
X	                c3;
X	c0 = nsp + m1 + m2;
X	if (c1 = nsp - osp)
X	    c1 = c1<0 ? tt.t_DCov - c1*tt.t_DCmf
X		      : tt.t_ICov + c1*tt.t_ICmf;
X	if (c3 = nd - od)
X	    c3 = c3<0 ? tt.t_DCov - c3*tt.t_DCmf
X		      : tt.t_ICov + c3*tt.t_ICmf;
X	if (c2 = (nsp + nd) - (osp + od))
X	    c2 = c2<0 ? tt.t_DCov - c2*tt.t_DCmf
X		      : tt.t_ICov + c2*tt.t_ICmf;
X	c3 += c1;
X	c1 += m2;
X	c2 += m1;
X	if (m2 && (c0 < c2 && c0 < c3 || c1 < c2 && c1 < c3)) {
X	    nd += m2;
X	    od += m2;
X	    ol += m2;
X	    nl += m2;
X	    m2 = 0;
X	}
X	if (m1 && (c0 < c1 && c0 < c3 || c2 < c1 && c2 < c3)) {
X	    nd += m1;
X	    od += m1;
X	    np -= m1;
X	    op -= m1;
X	    m1 = 0;
X	}
X    }
X    if (RDdebug && (m1 || m2 || nd || od)) {
X	fprintf (stderr, "%2d nsp=%2d  osp=%2d  m1=%2d  nd=%2d  od=%2d  m2=%2d",
X		ln, nsp, osp, m1, nd, od, m2);
X    }
X    (*tt.t_HLmode) (NewHL);
X    if (NewHL != OldHL) {
X	topos (ln, 1);
X	wipeline (1, OldLineWipeTo);
X	OldLineWipeTo = 1;
X    }
X    if (m1 == 0)
X	if (m2 == 0) {
X	    if (od == 0 && nd == 0)
X		goto cleanup;
X#ifndef ACT
X	    if (od == 0 && !tt.t_needspaces)
X		osp = nsp;
X#endif
X	    topos (ln, (t = min (nsp, osp)) + 1);
X	    INSmode (0);
X	    if (nsp > osp)
X		blanks (nsp - osp);
X	    dumpstring (np, nl);
X	    if (nsp + nd < osp + od)
X		wipeline (0, OldLineWipeTo);
X	}
X	else {			/* m1==0 && m2!=0 && (nd!=0 || od!=0) */
X	    t = (nsp + nd) - (osp + od);
X	    topos (ln, min (nsp, osp) + 1);
X	    if (nsp > osp)
X		np -= nsp - osp;
X	    if (t >= 0) {
X		if (nl - t >= np)
X		    INSmode (0), dumpstring (np, nl - t);
X		if (t > 0)
X		    INSmode (1), dumpstring (nl - t + 1, nl);
X	    }
X	    else
X		INSmode (0), dumpstring (np, nl), deletechars (-t);
X	}
X    else {			/* m1!=0 */
X	register    lsp = osp;
X	if (nsp < osp) {
X	    topos (ln, 1);
X	    deletechars (osp - nsp);
X	    lsp = nsp;
X	}
X	if (m2 == 0) {
X	    if (nd == 0 && od == 0) {
X		if (nsp > osp) {
X		    topos (ln, 1);
X		    INSmode (1);
X		    blanks (nsp - osp);
X		}
X		goto cleanup;
X	    }
X#ifndef ACT
X	    if (od == 0 && !tt.t_needspaces)
X		while (*np==' ') np++, m1++;
X#endif
X	    topos (ln, lsp + m1 + 1);
X	    INSmode (0);
X	    dumpstring (np, nl);
X	    if (nd < od)
X		wipeline (0, OldLineWipeTo);
X	    if (nsp > osp) {
X		topos (ln, 1);
X		INSmode (1);
X		blanks (nsp - osp);
X	    }
X	}
X	else {			/* m1!=0 && m2!=0 && (nd!=0 || od!=0) */
X	    topos (ln, lsp + m1 + 1);
X	    t = nd - od;
X	    if (nd > 0 && od > 0)
X		INSmode (0), dumpstring (np, np + min (nd, od) - 1);
X	    if (nd < od)
X		deletechars (od - nd);
X	    else
X		if (nd > od)
X		    INSmode (1), dumpstring (np + od, nl);
X	    if (nsp > osp) {
X		topos (ln, 1);
X		INSmode (1);
X		blanks (nsp - osp);
X	    }
X	}
X    }
Xcleanup:
X#ifdef FIONREAD
X    if(--CheckForInput<0 && !InputPending &&
X				((stdout->_ptr - stdout->_base) > 20)){
X	fflush (stdout);
X#ifdef TIOCOUTQ			/* prevent system I/O buffering */
X	if (baud_rate < 2400) {
X	    int out1;
X	    float outtime;
X	    ioctl (fileno(stdin), TIOCOUTQ, &out1);
X	    out1 *= 10;
X	    outtime = ((float) out1) / ((float) baud_rate);
X	    if (outtime >= 1.5) sleep ((unsigned) (outtime - .5));
X	}
X#endif
X	ioctl (fileno(stdin), FIONREAD, &InputPending);
X	CheckForInput = baud_rate / 2400;
X    }
X#endif
X}
X
Xvisible procedure UpdateScreen (SlowUpdate) {
X    register    n,
X                c;
X
X    CheckForInput = 999;
X    if (ScreenGarbaged) {
X	reset ();
X	ScreenGarbaged = 0;
X	for (n = 0; n <= ScreenLength; n++) {
X	    ReleaseLine (PhysScreen[n]);
X	    PhysScreen[n] = 0;
X	}
X    }
X#ifdef FIONREAD			/* one quick test */
X    if (!InputPending) ioctl (fileno(stdin), FIONREAD, &InputPending);
X#endif
X    if (CurrentLine >= 0
X	    && DesiredScreen[CurrentLine] -> length <= ScreenWidth - left)
X	DesiredScreen[CurrentLine] -> length =
X	    left > 0 ? ScreenWidth - left : ScreenWidth;
X    CurrentLine = -1;
X    if (tt.t_ILov == MissingFeature)
X	SlowUpdate = 0;
X    if (SlowUpdate) {
X	for (n = 1; n <= ScreenLength; n++) {
X	    if (DesiredScreen[n] == 0)
X		DesiredScreen[n] = PhysScreen[n];
X	    else
X		hashline (DesiredScreen[n]);
X	    hashline (PhysScreen[n]);
X	}
X/*  if(oldhighlights.applied)
X	ApplyHighlights(1, oldhighlights.HLbody, 0); */
X	c = 0;
X	for (n = ScreenLength; n >= 1 && c <= 2; n--)
X	    if (PhysScreen[n] != DesiredScreen[n]
X		    && PhysScreen[n]
X		    && DesiredScreen[n] -> hash != PhysScreen[n] -> hash)
X		c++;
X	if (c <= 2)
X	    SlowUpdate = 0;
X	else {
X	    if (tt.t_window) {
X		for (n = ScreenLength;
X			n >= 1
X			&& (PhysScreen[n] == DesiredScreen[n]
X			    || PhysScreen[n]
X			    && DesiredScreen[n] -> hash == PhysScreen[n] -> hash);
X			n--);
X		WindowSize = n;
X		(*tt.t_window) (n);
X	    }
X	    else
X		WindowSize = ScreenLength;
X	    calcM ();
X	    CheckForInput = baud_rate / 2400;
X	    CalcID (ScreenLength, ScreenLength, 0);
X/*	for (n = 1; n <= ScreenLength; n++) {
X	    if (DesiredScreen[n] != PhysScreen[n]) {
X		ReleaseLine (PhysScreen[n]);
X		PhysScreen[n] = DesiredScreen[n];
X	    }
X	    DesiredScreen[n] = 0;
X	} */
X/*  if (DoHighlights){
X	oldhighlights = newhighlights;
X	ApplyHighlights (0,newhighlights.HLbody,1);
X	oldhighlights.applied++;
X    }
X    else oldhighlights.applied = 0; */
X	}
X    }
X    if (!SlowUpdate) {		/* fast update */
X	for (n = 1; n <= ScreenLength; n++)
X	    if (DesiredScreen[n]) {
X		UpdateLine (PhysScreen[n], DesiredScreen[n], n);
X		if (PhysScreen[n] != DesiredScreen[n])
X		    ReleaseLine (PhysScreen[n]);
X		PhysScreen[n] = DesiredScreen[n];
X		DesiredScreen[n] = 0;
X	    }
X    }
X    (*tt.t_HLmode) (0);
X    if (!InputPending)
X	topos (cursY, cursX);
X}
X
Xstatic VisibleBell;		/* If true and the terminal will support it
X				   then the screen will flash instead of
X				   feeping when an error occurs */
Xvisible int InverseVideo;	/* If true and the terminal will support it
X				   then we will use inverse video */
X
X/* AZ routine to change number of lines on screen */
Xvisible procedure ScreenLines(){
X     tt.t_length = getnum (": lines-on-screen ");
X     ScreenGarbaged = 1;
X     InitWin();
X     DoDsp(1);
X}
X/* AZ routine to change number of cols. on screen */
Xvisible procedure ScreenCols(){
X     tt.t_width = getnum (": columns-on-screen ");
X     ScreenGarbaged = 1;
X     DoDsp(1);
X}
X
X/* DJH common routine for a feep */
XDing () {			/* BOGUS!  this should really be terminal
X				   type specific! */
X    if (VisibleBell && tt.t_flash) (*tt.t_flash) ();
X    else putchar (07);
X}
X
X/* DLK routine to make the cursor sit for n/10 secs */
Xhidden procedure SitFor () {
X    register    num_chars, CharsPerInputCheck;
X
X    if(InputPending || stdin->_cnt!= 0) return 0;
X    CharsPerInputCheck = baud_rate / 100;
X    num_chars = getnum (": sit-for ") * CharsPerInputCheck;
X    DoDsp (1);			/* Make the screen correct */
X    INSmode (0);
X    while (num_chars-- && !InputPending){
X#ifdef FIONREAD
X	if ( ((num_chars+1) % CharsPerInputCheck) == 0){
X		fflush (stdout);
X		ioctl (fileno(stdin), FIONREAD, &InputPending);
X	}
X#endif
X	putchar(tt.t_padc);
X    }
X    return 0;
X}
X
X/* ACT 18-Oct-1982 sleep for n seconds, do not update display */
Xhidden procedure SleepFor () {
X    register t = getnum (": sleep-for ");
X    if (t >= 1 && t <= 10) sleep (t);
X    return 0;
X}
X
X/* initialize the teminal package */
Xterm_init () {
X    static short    baud_convert[] =
X    {
X	0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
X	1800, 2400, 4800, 9600, 19200
X    };
X    struct sgttyb   sg;
X    extern short    ospeed;
X    static  BeenHere;		/* true iff we've been here before (some
X				   things must only be done once!) */
X
X    RDdebug = 0;		/* line redraw debug switch */
X    IDdebug = 0;		/* line insertion/deletion debug */
X    cursX = 1;			/* X and Y coordinates of the cursor */
X    cursY = 1;			/* between updates. */
X    CurrentLine = -1;		/* current line for writing to the
X				   virtual screen. */
X    left = -1;			/* number of columns left on the current
X				   line of the virtual screen. */
X    gtty (fileno (stdin), &sg);
X    ospeed = sg.sg_ospeed;
X    baud_rate = sg.sg_ospeed == 0 ? 1200
X	: sg.sg_ospeed < sizeof baud_convert / sizeof baud_convert[0]
X	? baud_convert[sg.sg_ospeed] : 9600;
X    if (!BeenHere) {
X	char   *tname = (char *) getenv ("TERM");
X	struct termtype {
X	    char   *name;
X	    int     cmplen;
X	    int     (*startup) ();
X	};
X    /* A terminal driver is selected by looking up the value of the
X       environment variable TERM in the following table.  The string is
X       matched against the name, considering at most "cmplen" characters
X       to be significant.  "startup" points to the function that sets up
X       the terminal driver.  The driver is called with the terminal type
X       as a parameter and is free to use that to specialize itself. */
X	struct termtype *p;
X	extern  TrmAmb ();
X	extern  TrmVT100 ();	
X/*	extern  TrmTEK4025 ();	*/
X/*	extern  TrmC100 ();	*/
X/*	extern  TrmI400 ();	*/
X/*	extern  TrmMiniB ();	*/
X/*	extern  TrmPERQ ();	*/
X/*	extern	TrmBitG ();	*/
X/*	extern	TrmGT40 ();	*/
X/*	extern	TrmGigi ();	*/
X	static struct termtype  termtable[] = {
X	    "aaa",	3, TrmAmb,
X	    "amb",	3, TrmAmb,
X	    "ambassador",99, TrmAmb,
X	    "VT1",	3,  TrmVT100,
X	    "vt1",	3,  TrmVT100,
X/*	    "4025",	99, TrmTEK4025,		*/
X/*	    "BG",	99, TrmBitG,		*/
X/*	    "Bit",	3,  TrmBitG,		*/
X/*	    "C10",	3,  TrmC100,		*/
X/*	    "c10",	3,  TrmC100,		*/
X/*	    "Concept",	7,  TrmC100,		*/
X/*	    "concept",	7,  TrmC100,		*/
X/*	    "d4",	99, TrmGT40,		*/
X/*	    "D5",	99, TrmVT100,		*/
X/*	    "Dq",	2,  TrmVT100,		*/
X/*	    "DT80",	99, TrmVT100,		*/
X/*	    "GG",	99, TrmGigi,		*/
X/*	    "Gigi",	4,  TrmGigi,		*/
X/*	    "gt40",	99, TrmGT40,		*/
X/*	    "GT40",	99, TrmGT40,		*/
X/*	    "perq",	4,  TrmC100,		*/
X/*	    "i400",	99, TrmI400,		*/
X/*	    "Mb",	99, TrmAmb,		*/
X/*	    "minibee",	99, TrmMiniB,		*/
X/*	    "tek4025",	99, TrmTEK4025,		*/
X/*	    "X5",	99, TrmTEK4025,		*/
X	    0, 0, 0
X	};
X	BeenHere++;
X	if (tname == 0)
X	    tname = "concept";
X	for (p = termtable; p -> name; p++)
X	    if (strcmpn (p -> name, tname, p -> cmplen) == 0) {
X		(*p -> startup) (tname);
X		break;
X	    }
X	if (p -> name == 0)
X	    TrmTERM (tname);
X	defproc (ScreenLines, "lines-on-screen");
X	defproc (ScreenCols, "columns-on-screen");
X	defproc (SitFor, "sit-for");
X	defproc (SleepFor, "sleep-for");
X	DefIntVar ("visible-bell", &VisibleBell);
X	DefIntVar ("inverse-video", &InverseVideo);
X    }
X    (*tt.t_init) (baud_rate);
X    if (tt.t_length > MScreenLength)
X	tt.t_length = MScreenLength;
X    if (tt.t_width > MScreenWidth)
X	tt.t_width = MScreenWidth;
X    (*tt.t_reset) ();
X}
X
X/* Debugging routines -- called from sdb only */
X
X/* print out the insert/delete cost matrix */
X#ifdef DEBUG
XPrintM () {
X    register    i,
X                j;
X    register struct Msquare *p;
X    for (i = 0; i <= ScreenLength; i++) {
X	for (j = 0; j <= ScreenLength; j++) {
X	    p = &M[i][j];
X	    fprintf (stderr, "%4d%c", p -> cost,
X		    p -> fromi < i && p -> fromj < j ? '\\' :
X		    p -> fromi < i ? '^' :
X		    p -> fromj < j ? '<' : ' ');
X	}
X	fprintf (stderr, "\n");
X    }
X    fprintf (stderr, "\014");
X}
X#endif
X
Xvisible procedure
XNoOperation () {}
//go.sysin dd *
/bin/chmod 644 display.c
/bin/echo -n '	'; /bin/ls -l display.c
/bin/echo 'Extracting TrmAmb.c'
sed 's/^X//' <<'//go.sysin dd *' >TrmAmb.c
X/* terminal control module for Ann Arbor Ambassadors */
X
X/* ACT 16-Oct-1982: Combined Gosling's version and mine to write this one */
X
X#include <stdio.h>
X#include "Trm.h"
X#include "keyboard.h"
X#define	PAD(n,f)	if (Baud > 9600) pad(n,f); else
X
Xstatic
Xint	curX, curY, Baud, CurHL, DesHL;
X
Xstatic
Xfloat	BaudFactor;
X
Xstatic
Xenum IDmode { m_insert = 1, m_overwrite = 0} DesiredMode;
X
Xstatic
XINSmode (new)
Xenum IDmode new; {
X	DesiredMode = new;
X}
X
Xstatic
XHLmode (new) {
X	DesHL = new;
X}
X
Xstatic
XSetHL (OverRide) {
X	register Des = OverRide ? 0 : DesHL;
X	if (Des == CurHL)
X		return;
X	if (InverseVideo) printf ("\033[%cm", Des ? '0' : '7');
X		else 	  printf ("\033[%cm", Des ? '7' : '0');
X	PAD (1, 0.30);
X	CurHL = Des;
X}
X
Xstatic
Xinslines (n) {
X    SetHL (1);
X    printf (n <= 1 ? "\033[L" : "\033[%dL", n);
X    PAD (61-curY, 4.00);
X}
X
Xstatic
Xdellines (n) {
X    SetHL (1);
X    printf (n <= 1 ? "\033[M" : "\033[%dM", n);
X    PAD (61-curY, 4.00);
X    if (tt.t_length == 60)
X	return;
X    if (Baud < 4800) {		/* yeesh! */
X	topos (tt.t_length-n+1, 1);
X	printf ("\033[J");
X    }
X    else {
X	register i;
X	for (i=tt.t_length-n+1; i<=tt.t_length; i++) {
X	    topos (i, 1);
X	    wipeline ();
X	}
X/*	i = tt.t_length - n + 1;
X	topos (i, 1);
X	printf (n <= 1 ? "\033[M" : "\033[%dM", n);
X	PAD (60-curY, 4.00);	*/
X
X    }
X}
X
Xstatic
Xwritechars (start, end)
Xregister char *start, *end; {
X    register char *p;
X    register runlen;
X
X    SetHL (0);
X    if (DesiredMode == m_insert) {
X	printf ("\033[%d@", end - start + 1);
X	PAD (80-curX, 0.16);
X    }
X    while (start <= end) {
X	if (*start < 040 || *start >= 0177) {
X	    printf (InverseVideo ? "\033[m%c\033[7m" : "\033[7m%c\033[m",
X		    	*start < 040 ? (*start & 037) + 0100 : '?');
X		/* enter hi-light mode, print char, exit hi-light mode */
X	    PAD (1, 1.00);
X	    start++;
X	    curX++;
X	}
X	else {
X	    if (start+5 < end && *start == start[1]) {
X		runlen = 0;
X		p = start;
X		do runlen++; while (*++start == *p && start <= end);
X		if (runlen > 5) {
X		    putchar (*p);
X		    printf ("\033[%db", runlen - 1);
X		    PAD (runlen-1, 1.00);
X		    curX += runlen;
X		}
X		else {
X		    start = p;
X		    goto normal;
X		}
X	    }
X	    else {
Xnormal:
X		putchar (*start++);
X		curX++;
X	    }
X	}
X    }
X}
X
Xstatic
Xblanks (n) register n; {
X    if (n > 0) {
X	SetHL (0);
X	curX += n;
X	if (DesiredMode == m_insert) {
X	    printf ("\033[%d@", n);
X	    PAD (80-curX, 0.16);
X	}
X	if (n > 5) {
X	    printf (" \033[%db", n-1);
X	    PAD (n-1, 1.00);
X	}
X	else while (--n >= 0) putchar (' ');
X    }
X}
X
Xstatic
Xpad (n, f)
Xfloat f; {
X    register	k = n * f * BaudFactor;
X    while (--k >= 0)
X	putchar (0);
X}
X
Xstatic
Xtopos (row, column) register row, column; {
X    if (curY == row) {
X	if (curX == column)
X	    return;
X	if (curX == column + 1) {
X	    putchar (010);
X	    goto done;
X	}
X	printf ("\033[%d`", column);
X	goto done;
X    }
X    if (curY+1 == row && (column == 1 || column == curX)) {
X	if (column != curX) putchar (015);
X	putchar (012);
X	goto done;
X    }
X    if (row == 1 && column == 1) {
X	printf ("\033[f");
X	goto done;
X    }
X    if (column == 1) {
X	printf ("\033[%df", row);
X	goto done;
X    }
X    if (row == 1) {
X	printf ("\033[;%df", column);
X	goto done;
X    }
X    printf ("\033[%d;%df", row, column);
Xdone:
X    curX = column;
X    curY = row;
X    PAD (1, 1.00);
X}
X
Xstatic
Xinit (BaudRate) {
Xchar   *tname = (char *) getenv ("TERM");
X    MetaFlag = strcmp (tname, "aaamt") ? 0 : 1;
X    BaudFactor = BaudRate / 10000.;
X    Baud = BaudRate;
X}
X
X#define ScreenLength (tt.t_length)
X#define ScreenWidth (tt.t_width)
X
Xstatic
Xreset () {
X    CurHL = -1;
X    SetHL (1);
X    if (ScreenLength <= 18 ) printf ("\033[60;0;0;18p");
X    if (ScreenLength > 18 && ScreenLength <= 22) printf ("\033[60;0;0;22p");
X    if (ScreenLength > 22 && ScreenLength <= 24) printf ("\033[60;0;0;24p");
X    if (ScreenLength > 24 && ScreenLength <= 26) printf ("\033[60;0;0;26p");
X    if (ScreenLength > 26 && ScreenLength <= 28) printf ("\033[60;0;0;28p");
X    if (ScreenLength > 28 && ScreenLength <= 30) printf ("\033[60;0;0;30p");
X    if (ScreenLength > 30 && ScreenLength <= 36) printf ("\033[60;0;0;36p");
X    if (ScreenLength > 36 && ScreenLength <= 40) printf ("\033[60;0;0;40p");
X    if (ScreenLength > 40 && ScreenLength <= 48) printf ("\033[60;0;0;48p");
X    if (ScreenLength > 48 && ScreenLength <= 60) printf ("\033[60;0;0;60p");
X    pad (1, 10.00);
X    printf ("\033[>52h");	/* SM meta key */
X    printf ("\033[>30;33;34;37;38;39l");
X    /* RM(ZDBM,ZWFM,ZWBM,ZAXM,ZAPM,ZSSM) */
X    printf ("\033[1Q");		/* SEE */
X    printf ("\033[H");		/* CUP */
X    printf ("\033[2J");		/* ED */
X    pad (1, 350.00);
X/*    wipescreen(); */
X    curX = curY = 1;
X    DesiredMode = m_overwrite;
X}
X
Xstatic
Xcleanup () {
X    InverseVideo = 0;	/* reset to normal video */
X    CurHL = -1;
X    SetHL (0);
X    topos (tt.t_length, 1);
X    printf ("\033[J\033[m");
X    pad (10, 1.00);
X    printf ("\033[>30;33;34;37h"); /* SM(ZDBM,ZWFM;ZWBM;ZAXM) */
X    pad (20, 1.00);
X    printf ("\033[>52l");	  /* RM Metakey */
X    pad (10, 1.00);
X}
X
Xstatic
Xwipeline () {
X    SetHL (0);
X    printf ("\033[K");
X    PAD (80-curX, 0.25);
X}
X
Xstatic
Xwipescreen () {
X    SetHL (0);
X    printf ("\033[2J");
X    pad (1, 350.00);
X}
X
Xstatic
Xdelchars (n) {
X    if (n <= 0) return;
X    SetHL (0);
X    printf (n == 1 ? "\033[P" : "\033[%dP", n);
X    PAD (80-curX, 0.20);
X}
X
XTrmAmb () {
X    int i;				/* get preferred page length from */
X    char   *p = (char *) getenv ("PL"); /* environment - DCL */
X
X    tt.t_length = p == 0 ? 30 : atoi (p);	/* default 30 lines */
X    tt.t_INSmode = INSmode;
X    tt.t_HLmode = HLmode;
X    tt.t_inslines = inslines;
X    tt.t_dellines = dellines;
X    tt.t_blanks = blanks;
X    tt.t_init = init;
X    tt.t_cleanup = cleanup;
X    tt.t_wipeline = wipeline;
X    tt.t_wipescreen = wipescreen;
X    tt.t_topos = topos;
X    tt.t_reset = reset;
X    tt.t_delchars = delchars;
X    tt.t_writechars = writechars;
X    tt.t_window = 0;
X    tt.t_ILmf = 0;
X    tt.t_ILov = 4;
X    tt.t_ICmf = 1;
X    tt.t_ICov = 4;
X    tt.t_DCmf = 0;
X    tt.t_DCov = 5;
X    tt.t_width = 80;
X}
//go.sysin dd *
/bin/chmod 644 TrmAmb.c
/bin/echo -n '	'; /bin/ls -l TrmAmb.c
/bin/echo 'Extracting TrmVT100.c'
sed 's/^X//' <<'//go.sysin dd *' >TrmVT100.c
X/* terminal control module for DEC VT100's */
X
X/* Modified version of Gosling's C100 driver -- jpershing@bbn */
X
X/* This is a somewhat primitive driver for the DEC VT100 terminal.  The
X   terminal is driven in so-called "ansi" mode, using jump scroll.  It is
X   assumed to have the Control-S misfeature disabled (although this
X   shouldn't get in the way -- it does anyway).  Specific optimization left
X   to be done are (1) deferral of setting the window until necessary (as
X   the escape sequence to do this is expensive) and (2) being more clever
X   about optimizing motion (as the direct-cursor-motion sequence is also
X   quite verbose).  Also, something needs to be done about putting the
X   terminal back into slow-scroll mode if that's the luser's preference (or
X   perhaps having EMACS itself use slow-scroll mode [lose, lose]).
X*/
X
X#include <stdio.h>
X#include "display.h"
X
Xstatic
Xint	curX, curY;
Xstatic
Xint	WindowSize;
X
Xstatic curHL;
Xstatic
XHLmode (on) register on; {
X    if (curHL == on)
X	return;
X    printf (on ? "\033[7m" : "\033[m" );
X    pad (1, 2.0);
X    curHL = on;
X}
X
Xstatic
Xinslines (n) register n; {
X    printf ("\033[%d;%dr\033[%dH", curY, WindowSize, curY);
X    curX = 1;
X    while (--n >= 0) {
X	printf ("\033M");
X	pad (1, 20.);		/* DEC sez pad=30, but what do they know? */
X    }
X    printf ("\033[r");
X    pad (1, 2.);		/* ACT */
X    curX = curY = 1;
X};
X
Xstatic
Xdellines (n) register n; {
X    printf ("\033[%d;%dr\033[%dH", curY, WindowSize, WindowSize);
X    curX = 1;
X    curY = WindowSize;
X    while (--n >= 0) {
X	printf ("\033E");
X	pad (1, 20.);		/* [see above comment] */
X    }
X    printf ("\033[r");
X    pad (1, 2.);		/* ACT */
X    curX = curY = 1;
X};
X
Xstatic	Baud;
X
Xstatic
Xwritechars (start, end)
Xregister char	*start,
X		*end; {
X    register count = 0;
X    while (start <= end) {
X	if (*start < 040 || *start >= 0177) {
X	    printf (InverseVideo ? "\033[m%c\033[7m" : "\033[7m%c\033[m",
X		    	*start < 040 ? (*start & 037) + 0100 : '?');
X	    pad (1, 5.0);
X	    start++;
X	    curX++;
X	}
X	else
X	putchar (*start++);
X	curX++;
X	if (count++ > 15 && Baud >= 9600) count = 0, pad (1, 2.5);/* ACT */
X    }
X};
X
Xstatic
Xblanks (n) register n; {
X    while (--n >= 0) {
X	putchar (' ');
X	curX++;
X    }
X};
X
Xstatic float BaudFactor;
X
Xstatic pad (n,f)
Xregister n;
Xregister float f; {
X    register    k = n * f * BaudFactor;
X    while (--k >= 0)
X 	putchar (0);
X};
X
Xstatic				/* This routine needs lots of work */
Xtopos (row, column) register row, column; {
X    register k;
X    if (curY == row) {
X	k = curX - column;
X	if (k) {
X	    if (k > 0 && k < 4) {
X		while (k--) putchar(010);
X		goto done;
X	    }
X	}
X	else return;
X    }
X    if (curY + 1 == row && (column == 1 || column==curX)) {
X	if(column!=curX) putchar (015);
X	putchar (012);
X	goto done;
X    }
X    if (row == 1 && column == 1) {
X	printf ("\033[H");
X	pad (1, 5.);		/* ACT */
X	goto done;
X    }
X    printf ("\033[%d;%dH", row, column );
X    pad (1, 10.);		/* ACT */
Xdone:
X    curX = column;
X    curY = row;
X};
X
Xstatic
Xinit (BaudRate) {
X    char *getenv();
X    static inited = 0;
X    if (!inited) {
X	static char tbuf[1024];		/* ACT Try for termcap's co# */
X	register char *t = getenv ("COL");
X	tt.t_width = t ? atoi (t)
X	: ((t = getenv ("TERM")) && tgetent (tbuf,t)>0) ? tgetnum ("co") : 80;
X    }
X    Baud = BaudRate;
X    BaudFactor = strcmp (getenv ("TERM"), "vt100") ? 
X    	BaudRate/4000. : BaudRate/10000.; /* AZ: slow it down for vt101 */
X    tt.t_ILmf = 0.0;
X    tt.t_ILov = 15 + 2+BaudFactor*20.;
X};
X
Xstatic
Xreset () {
X    printf ("\033<\033[r\033[m\033[?4;6l\033[2J\033=");/* Whew! */
X    if (InverseVideo) printf ("\033[?5h");/* Use inverse video */
X    else printf ("\033[?5l");
X    pad (1, 60.);
X    printf (ScreenWidth <= 80 ? "\033[?3l" : "\033[?3h");
X    	/* set to 80 or 132 columns */
X    pad (1, 150.);
X       WindowSize = 24;
X    curHL = 0;
X    curX = curY = 1;
X};
X
Xstatic
Xcleanup () {
X    HLmode (0);
X    window (0);
X    topos (WindowSize, 1);
X    wipeline ();
X};
X
Xstatic
Xwipeline () {
X    printf("\033[K");
X    pad (1, 10.);
X};
X
Xstatic
Xwipescreen () {
X    printf("\033[2J");
X    pad (1, 100.);		/* ACT was 45. */
X};
X
Xstatic
Xwindow (n) register n; {
X    if (n <= 0 || n > 24)
X	n = 24;
X    WindowSize = n;
X}
X
X/* Visible Bell for DT80/1 -ACT */
Xstatic
Xflash () {
X    printf (InverseVideo ? "\033[?5l" : "\033[?5h");
X    pad (1, 40.);
X    printf (InverseVideo ? "\033[?5h" : "\033[?5l");
X}
X
XTrmVT100 () {
X	tt.t_INSmode = NoOperation;
X	tt.t_HLmode = HLmode;
X	tt.t_inslines = inslines;
X	tt.t_dellines = dellines;
X	tt.t_blanks = blanks;
X	tt.t_init = init;
X	tt.t_cleanup = cleanup;
X	tt.t_wipeline = wipeline;
X	tt.t_wipescreen = wipescreen;
X	tt.t_topos = topos;
X	tt.t_reset = reset;
X	tt.t_delchars = 0;
X	tt.t_writechars = writechars;
X	tt.t_window = window;
X	tt.t_flash = flash;
X	tt.t_ILmf = 0;
X	tt.t_ILov = 0;
X	tt.t_ICmf = MissingFeature;
X	tt.t_ICov = MissingFeature;
X	tt.t_DCmf = MissingFeature;
X	tt.t_DCov = MissingFeature;
X	tt.t_length = 24;
X	tt.t_width = 80;
X};
//go.sysin dd *
/bin/chmod 644 TrmVT100.c
/bin/echo -n '	'; /bin/ls -l TrmVT100.c