Window source #7 [of 0-7]: TrmTERM.c
chris at umcp-cs.UUCP
chris at umcp-cs.UUCP
Mon Jul 4 12:33:37 AEST 1983
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
all=FALSE
if [ $1x = -ax ]; then
all=TRUE
fi
/bin/echo 'This thing needs to be rewritten, but it works.'
/bin/echo 'Extracting TrmTERM.c'
sed 's/^X//' <<'//go.sysin dd *' >TrmTERM.c
X/* Copyright (c) 1983 University of Maryland Computer Science Department */
X/* terminal control module for terminals described by TERMCAP */
X
X/* This thing needs a complete rewrite but I'm not ready for that yet.
X 30 Jun 1983 ACT */
X
X/* Origincal code copyright (c) 1981,1980 James Gosling */
X
X/* Modified 1-Dec-80 by Dan Hoey (DJH) to understand C100 underlines
X * Modified 2-Dec-80 (DJH) to turn off highlighting on insertline
X * Modified 4 Aug 81 by JQ Johnson: use "dm","ei","pc","mi"
X * Modified 24-Aug-81 by Jeff Mogul (JCM) at Stanford
X * - uses "nl" instead of \n in case \n is destructive
X * Modified 8-Sept-81 by JCM @ Stanford
X * - re-integrated changes from Gosling since July '81
X * Modified by Chris Torek (ACT) @ Umcp-Cs
X * - can hack terminals without erase-to-eol (12-Aug-81)
X * - Sets NullsAreSpecial if :in: (12-June-82)
X * - Uses "cr" instead of \r (13-June-82)
X * - Rewrote cursor positioning routines, added:
X * "ms", "ho", "xr", "nc", "xt", "ta", "xn", "ll" (etc)
X * - Also cleaned up various things that were cleanable
X * - Rewrote all the cursor positioning stuff around 21-June-82
X * - Handles :db: (11-Jul-82)
X * - Secured the cost algorithms from buffer overflow (16-Jul-82)
X * - Does not use standout if 'sg#' is nonzero.
X * Modified by Chris Torek (ACT): added %m cursor motion code
X */
X
X/*
X * Notes on things not normally in TERMCAP:
X * :rn: indicates that \r acts like \r\n
X * :nn: indicates that \n doesn't work
X * :ds=: gives a "don't send" string; these characters will not
X * be written to the terminal for cursor motion (:cm=:). If this
X * is nonempty the terminal MUST have an upline and a backspace.
X * If defined, it is assumed to also have a null in it. If not
X * included in a termcap, it defaults to ^D\t\n\r. To get
X * real binary use ":ds=:" to say can send anything.
X * :bo=: is bold-start string
X * :be=: is bold-end string
X * :ws=: is wink-start (ie blink) string
X * :we=: is wink-end string
X */
X
X#include <stdio.h>
X#include <sgtty.h>
X#include "Trm.h"
X#include "win.h"
X
X/* ACT: This has gotta be at least 800 for some terminals (!!) */
X#define CMBUFSIZ 1000 /* Cursor motion buffer size */
X
Xstatic
Xint curX, curY;
X
Xchar *tgetstr (), *getenv ();
Xchar *UP, *BC, PC;
Xshort ospeed;
X
Xstatic char *ILstr, *DLstr, *ICstr, *DCstr, *ELstr, *ESstr, *HLBstr,
X *HLEstr, *ICPstr, *ICPDstr, *CursStr, *CteoDstr,
X *TIstr, *TEstr, *VSstr, *VEstr, *HOstr, *TBstr, *LLstr,
X *ICEstr, *NDstr, *VBstr, *EDstr, *DMstr, *NLstr, *CRstr,
X *DSstr, *WSstr, *WEstr, *ULstr, *UEstr, *BSstr, *BEstr;
Xstatic int ULflag, /* DJH -- 1 if terminal has underline */
X MIflag, /* JQJ -- 1 if safe to move while in insert mode */
X XRflag, /* ACT -- if (:xr:nc:) CR's don't work correctly */
X XTflag, /* 1 if can't use tabs for cursor motion */
X XNflag, /* 1 if can't use \n's for cursor motion */
X HZflag, /* 1 if hazeltine, can't print tilde */
X RNflag, /* 1 if \r does a \r\n */
X DBflag, /* 1 if display retained below */
X MSflag; /* 1 if safe to move while in standout */
X
Xstatic BOLDOFF, BLINKOFF, ULINEOFF, HLOFF; /* Bits that tell what
X modes arent independent */
X
Xstatic
Xdumpchar (c) register c; {
X putchar (c);
X}
X
Xstatic
Xenum IDmode { m_insert = 1, m_overwrite = 0 }
X CurMode, DesMode;
X
Xstatic
XINSmode (new)
Xregister enum IDmode new; {
X DesMode = new;
X};
X
Xstatic curmodes, desmodes;
Xstatic
Xmodes (on) {
X desmodes = on;
X}
X
X/* This routine needs work! */
Xstatic
Xsetmodes () {
X register char *com;
X int bold, under, blink, hl;
X if (curmodes == desmodes)
X return;
X/* The "end" strings are often the same. All this is to get around that. */
X bold = desmodes & WBOLD;
X under = desmodes & WULINE;
X blink = desmodes & WBLINK;
X hl = desmodes & WINVERSE;
X if (bold==0 && (curmodes & WBOLD)) {/* Then turn off bold */
X if (com = BEstr) tputs (com, 0, dumpchar);
X curmodes &= ~BOLDOFF; /* May have turned others off too */
X }
X if (under==0 && (curmodes & WULINE)) {/* etc */
X if (com = UEstr) tputs (com, 0, dumpchar);
X curmodes &= ~ULINEOFF;
X }
X if (blink==0 && (curmodes & WBLINK)) {
X if (com = WEstr) tputs (com, 0, dumpchar);
X curmodes &= ~BLINKOFF;
X }
X if (hl==0 && (curmodes & WINVERSE)) {
X if (com = HLEstr) tputs (com, 0, dumpchar);
X curmodes &= ~HLOFF;
X }
X if (bold != 0 && (curmodes & WBOLD) == 0 && (com = BSstr))
X tputs (com, 0, dumpchar);
X if (under != 0 && (curmodes & WULINE) == 0 && (com = ULstr))
X tputs (com, 0, dumpchar);
X if (blink != 0 && (curmodes & WBLINK) == 0 && (com = WSstr))
X tputs (com, 0, dumpchar);
X if (hl != 0 && (curmodes & WINVERSE) == 0 && (com = HLBstr))
X tputs (com, 0, dumpchar);
X curmodes = desmodes;
X}
X
Xstatic
Xclearmodes () {
X if (curmodes) {
X register oldes = desmodes;
X desmodes = 0;
X setmodes ();
X desmodes = oldes;
X }
X}
X
Xstatic
Xsetmode () {
X if (DesMode == CurMode)
X return;
X tputs (DesMode==m_insert ? ICstr : ICEstr, 0, dumpchar);
X CurMode = DesMode;
X};
X
Xstatic
Xinslines (n) {
X clearmodes ();
X while (--n >= 0)
X tputs (ILstr, W_tt.t_length-curY, dumpchar);
X};
X
Xstatic
Xdellines (n) {
X register save = n;
X while (--n >= 0)
X tputs(DLstr, W_tt.t_length-curY, dumpchar);
X if (DBflag) { /* Must clear new lines */
X if (CteoDstr) {
X topos (W_tt.t_length - save + 1, 1);
X tputs (CteoDstr, W_tt.t_length-curY, dumpchar);
X }
X else {
X register i;
X for (i=W_tt.t_length-save+1;i<=W_tt.t_length;++i) {
X topos (i, 1);
X wipeline (0, W_tt.t_width);
X }
X }
X }
X};
X
Xstatic
Xwritechars (start, end)
Xregister char *start,
X *end; {
X setmode ();
X setmodes();
X while (start <= end) {
X if(CurMode == m_insert && ICPstr)
X tputs(ICPstr, W_tt.t_width-curX, dumpchar);
X /* DJH -- blank out space before underlines */
X if(*start == '_' && CurMode != m_insert && ULflag) {
X putchar (' ');
X putchar (*BC);
X }
X if (HZflag && *start == '~') putchar ('`'), ++start;
X else putchar (*start++);
X if (CurMode == m_insert && ICPDstr)
X tputs(ICPDstr, W_tt.t_width-curX, dumpchar);
X curX++;
X }
X};
X
Xstatic
Xblanks (n) {
X setmode ();
X setmodes ();
X while (--n >= 0) {
X if (CurMode == m_insert && ICPstr)
X tputs (ICPstr, W_tt.t_width - curX, dumpchar);
X putchar (' ');
X if (CurMode == m_insert && ICPDstr)
X tputs (ICPDstr, W_tt.t_width - curX, dumpchar);
X curX++;
X }
X};
X
X/* ACT 8-Sep-1982 Commented all the pad stuff out, termlib already takes care
X of it. */
X
Xstatic float BaudFactor;
X
X/*
Xstatic pad(n,f)
Xfloat f; {
X register k = n * f * BaudFactor;
X while (--k >= 0)
X putchar (W_tt.t_padc);
X};
X*/
X
Xstatic char *CM, *bufp, save[CMBUFSIZ], *bufbase;
Xstatic CMcost, FixCM;
X
X#define SETSTUFF(buf) bufp=bufbase=buf
X#define SETBASE(buf) bufbase=buf
X
Xstuffchar (c)
Xregister char c;
X{
X if (bufp - bufbase < CMBUFSIZ)
X *bufp++ = c;
X}
X
X/*
X * Compute cost for going from (sy, sx) to (dy, dx) with extra (add)
X * and if less than current least-cost, change current least-cost.
X * Algorithm is:
X * 1. If we can use tabs, then try that; get as close as possible
X * without going too far. Then try using cursor right from there,
X * and cursor left from one tab stop later. Be careful not to go
X * past the end of the line.
X * 2. Try using cursor right and cursor left.
X * 3. Use the least length version of 1 & 2
X * 4. Add in up/down motion(s)
X */
X
Xstatic
Xtestcost (sy, sx, dy, dx, add)
Xregister sy, sx, dy, dx;
Xchar *add;
X{
X static char tbuf1[CMBUFSIZ], mbuf[CMBUFSIZ];
X /* Buffers for cursor motion stuff */
X int tabcost, movecost, tmp, tmp2, tmp3;
X
X if (sx == dx && sy == dy) {
X movecost = 0;
X goto done;
X }
X if (dy > sy && !NLstr || dy < sy && !UP) /* Can't get there from here */
X return;
X if (!XTflag && sx < dx) { /* Try tabs */
X tmp = sx;
X SETSTUFF (tbuf1);
X while ((tmp2 = ((tmp - 1) & ~7) + 9) <= dx)
X tputs (TBstr, 0, stuffchar), tmp = tmp2;
X if (NDstr) {
X bcopy (tbuf1, mbuf, movecost = bufp - tbuf1);
X tmp3 = tmp;
X }
X if (tmp < dx) tputs (TBstr, 0, stuffchar), tmp = tmp2;
X if (tmp > dx && !BC || tmp > W_tt.t_length)
X tabcost = 9999;
X else {
X while (tmp-- > dx) tputs (BC, 0, stuffchar);
X tabcost = bufp - tbuf1;
X }
X if (NDstr) {
X bufp = mbuf + movecost;
X SETBASE (mbuf);
X tmp = tmp3;
X while (tmp++ < dx) tputs (NDstr, 0, stuffchar);
X movecost = bufp - mbuf;
X if (movecost < tabcost) {
X bcopy (mbuf, tbuf1, tabcost = movecost);
X }
X }
X }
X else tabcost = 9999;
X if (sx < dx) {
X if (NDstr) {
X SETSTUFF (mbuf);
X while (sx++ < dx) tputs (NDstr, 0, stuffchar);
X movecost = bufp - mbuf;
X }
X else movecost = 9999;
X }
X else {
X if (BC) {
X SETSTUFF (mbuf);
X while (sx-- > dx) tputs (BC, 0, stuffchar);
X movecost = bufp - mbuf;
X }
X else movecost = 9999;
X }
X if (movecost == 9999 && tabcost == 9999) return;
X if (tabcost < movecost) bcopy (tbuf1, mbuf, movecost = tabcost);
X bufp = mbuf + movecost;
X SETBASE (mbuf);
X if (sy < dy) while (sy++ < dy) tputs (NLstr, 0, stuffchar);
X else while (sy-- > dy) tputs (UP, 0, stuffchar);
X movecost = bufp - mbuf;
Xdone:
X SETSTUFF (tbuf1);
X tputs (add, 0, stuffchar);
X tabcost = bufp - tbuf1; /* I know, it's the wrong variable name */
X if (movecost + tabcost < CMcost) {
X bcopy (tbuf1, save, tabcost);
X bcopy (mbuf, save + tabcost, movecost);
X CM = save;
X CMcost = movecost + tabcost;
X }
X};
X
X/* Perhaps a word of explanation ... in case we manage to get nulls into the
X cursor motion string, we change them to 0377s first, or all of the library
X routines used will stop after the null. (0377 is just an "unlikely" code,
X especially because it has the high bit on.) Anyway, these must be
X converted back after the library routines are done. This is a horrible
X hack and will probably cause someone untold trouble later. -ACT */
X
Xstatic
Xtopos (row, column) {
X char *tgoto ();
X
X if (curY == row && curX == column) return;
X
X if (CursStr) {
X CM = tgoto (CursStr, column-1, row-1);
X SETSTUFF (save);
X tputs (CM, 0, stuffchar);
X CM = save;
X CMcost = bufp - save;
X if (FixCM) { /* Must change 0377's to 0's */
X register char *s = save;
X register len = CMcost;
X for (;len--;++s) if ((*s & 0377) == 0377) *s = 0;
X }
X }
X else CMcost = 9999;
X
X if (HOstr) testcost (1, 1, row, column, HOstr);
X if (!XRflag) testcost (curY, 1, row, column, CRstr);
X if (RNflag && curY < W_tt.t_length)
X testcost (curY + 1, 1, row, column, "\r");
X testcost (curY, curX, row, column, "");
X if (LLstr) testcost (W_tt.t_length, 1, row, column, LLstr);
X
X if (! MSflag)
X clearmodes (); /* many terminals can't hack highlighting
X around cursor positioning. Silly twits! */
X if (CurMode==m_insert && ! MIflag) {
X tputs(ICEstr, 0, dumpchar); /* some terminals can't move in */
X CurMode = m_overwrite; /* insert mode -- JQJ */
X }
X while (CMcost--) putchar (*CM++); /* Now, wasn't that easy? */
X curX = column;
X curY = row;
X};
X
Xstatic
Xflash () { /* dump a visible bell */
X tputs (VBstr, 0, dumpchar);
X}
X
Xstatic
Xinit (BaudRate) {
X static char tbuf[1024];
X static char combuf[1024];
X register char *temp;
X extern struct sgttyb WOld;
X extern int WTtyFd;
X char *fill = combuf;
X static inited;
X if (!inited)
X if (tgetent (tbuf, getenv ("TERM")) <= 0) {
X return 1;
X/* stty (WTtyFd, &WOld);
X quit (1,
X"No environment-specified terminal type -- see TSET(1), sh(1)\n"); */
X }
X inited = 1;
X W_tt.t_needspaces = tgetflag ("in");
X XTflag = ((WOld.sg_flags & TBDELAY) == XTABS) || tgetflag ("xt");
X XRflag = tgetflag ("nc") || tgetflag ("xr");
X XNflag = tgetflag ("xn") || tgetflag ("nn");
X MSflag = tgetflag ("ms");
X HZflag = tgetflag ("hz");
X DBflag = tgetflag ("db");
X RNflag = tgetflag ("rn");
X DSstr = (temp = tgetstr ("ds", &fill)) ? temp : "\004\t\n\r";
X if (!*DSstr) DSstr = 0;
X if (!XRflag) CRstr = (temp = tgetstr ("cr", &fill)) ? temp : "\r";
X if (!XTflag) TBstr = (temp = tgetstr ("ta", &fill)) ? temp : "\t";
X ILstr = tgetstr ("al", &fill);
X HOstr = tgetstr ("ho", &fill);
X LLstr = tgetstr ("ll", &fill);
X DLstr = tgetstr ("dl", &fill);
X ICstr = tgetstr ("im", &fill);
X ICEstr = tgetstr ("ei", &fill);
X MIflag = tgetflag ("mi"); /* can move in insert mode */
X DCstr = tgetstr ("dc", &fill);
X ELstr = tgetstr ("ce", &fill);
X ESstr = tgetstr ("cl", &fill);
X if (tgetnum ("sg") < 1) {
X HLBstr = tgetstr ("so", &fill);
X HLEstr = tgetstr ("se", &fill);
X }
X if (tgetnum ("ug") < 1) {
X ULstr = tgetstr ("us", &fill);
X UEstr = tgetstr ("ue", &fill);
X }
X WSstr = tgetstr ("ws", &fill);
X WEstr = tgetstr ("we", &fill);
X BSstr = tgetstr ("bo", &fill);
X BEstr = tgetstr ("be", &fill);
X ICPstr = tgetstr ("ic", &fill);
X ICPDstr = tgetstr ("ip", &fill);
X CursStr = tgetstr ("cm", &fill);
X if (DBflag) CteoDstr = tgetstr ("cd", &fill);
X UP = tgetstr ("up", &fill);
X NDstr = tgetstr ("nd", &fill);
X VBstr = tgetstr ("vb", &fill);
X TIstr = tgetstr ("ti", &fill);
X TEstr = tgetstr ("te", &fill);
X DMstr = tgetstr ("dm", &fill);/* start delete mode */
X EDstr = tgetstr ("ed", &fill);/* end delete mode */
X VSstr = tgetstr ("vs", &fill);
X VEstr = tgetstr ("ve", &fill);/* ``visual'' start/end -ACT */
X if (tgetflag ("bs")) BC = "\b";
X else BC = tgetstr ("bc", &fill);
X ULflag = tgetflag ("ul"); /* DJH -- Find out about underline */
X if (!XNflag) NLstr = (temp = tgetstr ("nl", &fill)) ? temp : "\n";
X PC = W_tt.t_padc = (temp = tgetstr ("pc", &fill)) ? *temp : 0;
X/* Where does he get this weird formula?? ACT */
X/* BaudFactor = 1 / (1 - (.45 + .3*BaudRate/9600.)) * (BaudRate/10000.);*/
X BaudFactor = ((float) BaudRate) / 10000.;
X if (!ESstr || (CursStr ? DSstr && !UP && !BC
X : !UP || !BC || !NLstr || !NDstr)) {
X return 1;
X/* stty (WTtyFd, &WOld);
X quit (1, "Sorry, this terminal isn't powerful enough to run windows.\n\
XIt is missing some important features.\n"); */
X }
X W_tt.t_ILmf = BaudFactor * 0.75;
X if (ILstr) W_tt.t_ILov = 2;
X else {
X W_tt.t_ILov = MissingFeature;
X W_tt.t_inslines = W_tt.t_dellines = (int (*) ()) - 1;
X }
X if (VBstr) W_tt.t_flash = flash;
X if (ICstr) {
X W_tt.t_ICmf = 1;
X W_tt.t_ICov = strlen(ICstr) + (ICEstr ? strlen(ICEstr) : 0) +
X (ICPstr ? strlen(ICPstr) : 0) + (ICPDstr ? strlen(ICPDstr) : 0);
X } else W_tt.t_ICmf = W_tt.t_ICov = MissingFeature;
X if (DCstr) {
X W_tt.t_DCmf = strlen (DCstr);
X W_tt.t_DCov = (DMstr ? strlen(DMstr) : 0) + (EDstr ? strlen(EDstr) : 0);
X } else W_tt.t_DCmf = W_tt.t_DCov = MissingFeature;
X temp = getenv ("PL"); /* (ACT) Test for desired page len */
X W_tt.t_length = temp && atoi (temp) ? atoi (temp) : tgetnum ("li");
X temp = getenv ("COL"); /* (ACT) Test for desired line len */
X W_tt.t_width = (temp && atoi (temp) ? atoi (temp) : tgetnum ("co"))
X - (tgetflag ("am") ? 1 : 0);
X
X BOLDOFF = WBOLD; /* Turning off bold turns off bold */
X BLINKOFF = WBLINK; /* Turning off blink turns off blink */
X ULINEOFF = WULINE; /* Turning off uline turns off uline */
X HLOFF = WINVERSE; /* Turning off hl turns off hl */
X if (lstrcmp (BEstr, WEstr) == 0) {
X BOLDOFF |= WBLINK; /* bold & blink interrelate */
X BLINKOFF |= WBOLD;
X }
X if (lstrcmp (BEstr, UEstr) == 0) {
X BOLDOFF |= WULINE; /* bold & under interrelate */
X ULINEOFF |= WBOLD;
X }
X if (lstrcmp (BEstr, HLEstr) == 0) {
X BOLDOFF |= WINVERSE; /* etc */
X HLOFF |= WBOLD;
X }
X if (lstrcmp (WEstr, UEstr) == 0) {
X BLINKOFF |= WULINE;
X ULINEOFF |= WBLINK;
X }
X if (lstrcmp (WEstr, HLEstr) == 0) {
X BLINKOFF |= WINVERSE;
X HLOFF |= WBLINK;
X }
X if (lstrcmp (UEstr, HLEstr) == 0) {
X ULINEOFF |= WINVERSE;
X HLOFF |= WULINE;
X }
X return 0;
X};
X
Xstatic
Xlstrcmp (s1, s2) /* Version of strcmp takes care of NULL */
Xregister char *s1, *s2;
X{
X if (s1 == 0 || s2 == 0)
X return 1; /* Don't bother -- call 'em different */
X while (*s1 == *s2++)
X if (*s1++ == 0)
X return 0;
X return 1; /* Order not important */
X}
X
Xstatic
Xreset () {
X if (TIstr) tputs(TIstr, 0, dumpchar);
X if (VSstr) tputs(VSstr, 0, dumpchar);
X tputs(ESstr, 0, dumpchar); /* Also homes cursor: */
X curX = curY = 1;
X CurMode = m_insert;
X DesMode = m_overwrite;
X};
X
Xstatic
Xcleanup () {
X modes (0); setmodes ();
X DesMode = m_overwrite;
X setmode();
X topos (W_tt.t_length, 1);
X if (VEstr) tputs(VEstr, 0, dumpchar);
X if (TEstr) tputs(TEstr, 0, dumpchar);
X};
X
Xstatic
Xwipeline (z,p) register p; {
X clearmodes ();
X if (ELstr) tputs (ELstr, W_tt.t_width-curX, dumpchar);
X else {
X register i = p - curX + 1/*, oldX = curX*/;
X if (i < 1) return;
X if (CurMode == m_insert) {
X tputs(ICEstr, 0, dumpchar); /* We don't want these inserted */
X CurMode = m_overwrite;
X }
X while (--i >= 0) putchar(' '), ++curX;
X/* topos (curY, oldX); /* This appears to be unnecessary */
X }
X};
X
Xstatic
Xwipescreen () {
X tputs(ESstr, 0, dumpchar);
X curX = curY = 1;
X};
X
Xstatic
Xdelchars (n) {
X if (DMstr) { /* we may have delete mode, or delete == insert */
X if (strcmp(DMstr,ICstr) /*ACT*/ == 0 /*END*/) {
X if (CurMode == m_overwrite) {
X tputs(ICstr,0,dumpchar);
X CurMode = m_insert; /* we're now in both */
X }
X }
X else {
X if (CurMode == m_insert) {
X tputs(ICEstr, 0, dumpchar);
X CurMode = m_overwrite;
X }
X tputs(DMstr,0,dumpchar);
X }
X }
X while (--n >= 0) {
X tputs(DCstr, W_tt.t_width-curX, dumpchar);
X }
X if (EDstr) { /* for some, insert mode == delete mode */
X /* bug! /etc/termcap pads ICEstr but not EDstr */
X if (strcmp(DMstr,ICstr) /*ACT*/ == 0 /*END*/)
X CurMode = m_insert; /* (ACT) But you already did this! */
X else
X tputs(EDstr,0,dumpchar);
X }
X};
X
XTrmTERM () {
X W_tt.t_INSmode = INSmode;
X W_tt.t_modes = modes;
X W_tt.t_inslines = inslines;
X W_tt.t_dellines = dellines;
X W_tt.t_blanks = blanks;
X W_tt.t_init = init;
X W_tt.t_cleanup = cleanup;
X W_tt.t_wipeline = wipeline;
X W_tt.t_wipescreen = wipescreen;
X W_tt.t_topos = topos;
X W_tt.t_reset = reset;
X W_tt.t_delchars = delchars;
X W_tt.t_writechars = writechars;
X W_tt.t_window = 0;
X W_tt.t_ILmf = 0;
X W_tt.t_ILov = 0;
X W_tt.t_ICmf = 0;
X W_tt.t_ICov = 0;
X W_tt.t_length = 24;
X W_tt.t_width = 80;
X return 0;
X};
X
X/*
X * A home-brew "tgoto" with some special mods
X * If termlib ever changes this'll need updating
X *
X * %d decimal
X * %2 %2d
X * %3 %3d
X * %. binary, with "don't send"s
X * %+x Adds x, then like binary
X * %>xy if >x add y
X * %r next is col
X * %i Increment row/col
X * %% = %
X * %B BCD
X * %D Backwards BCD
X * %m xor with 0177
X * %<foo> like %+<foo>
X */
X
Xstatic char *
Xtgoto (CM, col, line)
Xchar *CM;
Xint col, line;
X{
X static char cmbuf[50], add[20];
X register char *cp = CM, *op = cmbuf;
X register c;
X int val = line, toggle = 0;
X
X if (! cp) return "OOPS";
X *add = 0;
X *op = 0;
X FixCM = 0;
X while (c = *cp++) {
X if (c != '%') {
X *op++ = c;
X continue;
X }
X switch (c = *cp++) {
X case 'm':
X col ^= 0177;
X line ^= 0177;
X goto setval;
X case 'n':
X col ^= 0140;
X line ^= 0140;
X goto setval;
X case 'd':
X if (val < 10) goto onedigit;
X if (val < 100) goto twodigit;
X case '3':
X *op++ = (val / 100) + '0';
X val %= 100;
X case '2':
Xtwodigit:
X *op++ = (val / 10) + '0';
Xonedigit:
X *op++ = (val % 10) + '0';
Xswap:
X toggle = 1 - toggle;
Xsetval:
X val = toggle ? col : line;
X continue;
X case '>':
X if (val > *cp++) val += *cp++;
X else cp++;
X continue;
X case '+':
X val += *cp++;
X case '.':
Xuse:
X if (DSstr) {
X while (val == 0 || index (DSstr, val)) {
X strcat (add, toggle ? BC : UP);
X ++val;
X }
X }
X else if (val == 0) {
X *op++ = 0377;
X FixCM = 1;
X goto swap;
X }
X *op++ = val;
X goto swap;
X case 'r':
X toggle = 1;
X goto setval;
X case 'i':
X ++col, ++line, ++val;
X continue;
X case '%':
X *op++ = c;
X continue;
X case 'B':
X val = ((val / 10) << 4) + val % 10;
X continue;
X case 'D':
X val = val - 2 * (val % 16);
X continue;
X default:
X val += c;
X goto use;
X }
X }
X *op = 0;
X strcat (op, add);
X return cmbuf;
X}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 644 TrmTERM.c
/bin/echo -n ' '; /bin/ls -ld TrmTERM.c
fi
--
UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet: chris at umcp-cs
ARPA: chris.umcp-cs at UDel-Relay
More information about the Comp.sources.unix
mailing list