AUSAM/source/ded/tty.c
#include "ded.h"
#include "char.h"
#include "tty.h"
#include "signal.h"
/* map of the screen - set up in the first place by
* ttysetup
*/
char **rowmap 0, **auxscreen 0;
int nrows, ncols;
/* terminal characteristics */
int ttytype;
char c_MODIFY 0, c_BLOB 0, c_CONTROL 0;
/* mode-remembering stuff */
int setup_done false;
int saveflags;
struct TTYMODE
{ char ispeed, ospeed, erase, kill;
int flags;
char nldelay, crdelay, tbdelay, vtdelay;
char width, length;
int brktab[8];
} tmode;
struct TTYBUF ttybuf, dlogbuf, ttyinbuf;
ttyinterrupt()
{ signal(SIGINTR, ttyinterrupt);
ttyzonk();
}
ttyzonk()
{ ttyinbuf.n_in = 0;
ttyinbuf.nxfree = ttyinbuf.tbuf;
complain();
}
ttyquit()
{ signal(SIGQUIT, 1);
ttyzonk();
diag("do you really want a core dump?");
if ( lcase(ttyin()) == 'y' )
{ ttyreset(); abort(); }
else
{ diag("I'll let you off this time, then");
signal(SIGQUIT, ttyquit);
fixpos();
ttyflush();
}
}
/* start up funny tty mode */
ttysetup()
{ ttybuf.n_in = 0;
ttybuf.nxfree = ttybuf.tbuf;
dlogbuf.n_in = 0;
dlogbuf.nxfree = dlogbuf.tbuf;
ttyinbuf.n_in = 0;
ttyinbuf.nxfree = ttyinbuf.tbuf;
ttysetmode();
}
ttysetmode()
{ register int row, width;
register char oldmod;
if (!setup_done)
/* set up exotic tty modes */
{ gtty(2,&tmode);
saveflags = tmode.flags;
tmode.flags =& ~ (T_ITT | T_INDCTL | T_ECHO | T_TABS | T_CRLF);
tmode.flags =| (T_RAW | T_RARE);
ncols = 80; nrows = 24;
tmode.width = tmode.length = 0;
}
stty(2,&tmode);
setup_done=true;
signal(SIGINTR, ttyinterrupt);
signal(SIGQUIT, ttyquit);
/* set up teletype characteristics */
oldmod = c_MODIFY==0 ? '@' : c_MODIFY;
switch (ttytype = TTY)
{
case itt: c_BLOB = '{';
c_CONTROL = '\032';
set_modifier(oldmod);
break;
case hazeltine: c_BLOB = 0140;
c_CONTROL = '^' + 0200;
set_modifier(0);
ictab[c_LEADIN] = ectab[c_LEADIN] = TWO;
set_modifier(oldmod);
break;
case VC404:
case T1061: c_BLOB = '@';
c_CONTROL = '\032';
break;
default: editerror("ttytype not set up");
}
/* get space for screen of relevant size */
if (rowmap==0)
{ if (nrows==0 || ncols==0)
editerror("what screen size do you have? (ttysetup)");
else
if (ncols+1>ENOUGH)
editerror("this screen is too big for ded (ttysetup)");
else
rowmap = newscreen(); /* don't set up auxscreen yet */
}
}
ttyreset()
{ ttyflush(); dlogflush();
if (setup_done)
{ tmode.flags = saveflags;
tmode.width = ncols;
tmode.length = nrows;
stty(2,&tmode);
}
setup_done=false;
}
/* stuff characters in buffer, to save too many system calls */
ttyout(c)
int c;
{ register char *nxf;
register int rc;
if (ttybuf.n_in >= TTYBUFSIZE-10) ttyflush();
if ((rc=c)==int_CONTROL && ttytype==hazeltine)
{ nxf = ttybuf.nxfree;
*nxf++=c_LEADIN; *nxf++ = 037;
*nxf++ = c_CONTROL;
*nxf++ = c_LEADIN; *nxf++ = 031;
ttybuf.nxfree = nxf;
ttybuf.n_in =+ 5;
}
else
{ *(ttybuf.nxfree++)=rc; ttybuf.n_in++; }
}
/* empty buffer */
ttyflush()
{ bufflush(&ttybuf, 2); }
dlogflush()
{ if (bufflush(&dlogbuf, dlogger) < 0)
editerror("dlogwrite failed - not enough space?");
}
bufflush(abuf, chan)
struct TTYBUF *abuf;
int chan;
{ register struct TTYBUF *rbuf;
register int count;
rbuf = abuf;
if ((count = rbuf->n_in) != 0)
{ if (write(chan, rbuf->tbuf, count) != count) return(-1);
rbuf->nxfree = rbuf->tbuf;
rbuf->n_in=0;
}
return(1);
}
/* a procedure to read in from the teletype - now also
* provides an logfile (.dlog) facility
*/
int tty_input 2;
int dlogger;
char t1061map[4] { '\032','\037','\025','\010' };
ttyin()
{ register int count, input;
int icount;
register char c;
input = tty_input;
icount = (input==2 ? 1 : 512);
if (--ttyinbuf.n_in < 0)
{ while ((count = read(input, ttyinbuf.tbuf, icount)) <= 0)
if (input!=2)
{ input=tty_input=2; /* end of dlog input */
diag("** end of %s **", dlogname);
fixpos(); complain(); ttyflush();
}
ttyinbuf.n_in = --count; ttyinbuf.nxfree = ttyinbuf.tbuf;
}
c = *(ttyinbuf.nxfree++);
if ( c == '\033')
if ( ttytype == T1061 )
{ c = *(ttyinbuf.nxfree++);
if ( c == 'H' ) c = '\036';
else
if ( (c >= 'A') || (c <= 'D'))
c =t1061map[c-'A'];
}
if (input==2)
{ if (dlogbuf.n_in >= TTYBUFSIZE) dlogflush();
*(dlogbuf.nxfree++) = c;
dlogbuf.n_in++;
if (c<040) dlogflush();
}
return(c);
}