ocker@lan.informatik.tu-muenchen.dbp.de (Wolfgang Ocker) (01/25/89)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 2 (of 3)." # Contents: ansi.c # Wrapped by weo@recco on Fri Jan 6 14:32:08 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'ansi.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'ansi.c'\" else echo shar: Extracting \"'ansi.c'\" \(30846 characters\) sed "s/^X//" >'ansi.c' <<'END_OF_FILE' X/* Copyright (c) 1987, Oliver Laumann, Technical University of Berlin. X * Not derived from licensed software. X * X * Permission is granted to freely use, copy, modify, and redistribute X * this software, provided that no attempt is made to gain profit from it, X * the author is not construed to be liable for any results of using the X * software, alterations are clearly marked as such, and this notice is X * not modified. X * X * Adapted to OS-9/68000 by reccoware systems, Wolfgang Ocker, Puchheim 1988 X */ X Xchar AnsiVersion[] = "ansi 1.0g 27-Apr-87"; X X#include <stdio.h> X#ifdef OSK X#include <types.h> X#include <time.h> X#else X#include <sys/types.h> X#endif X#include "screen.h" X X#ifdef OSK Xchar PC_, *BC, *UP; Xshort int ospeed; X#endif X X#define A_SO 0x1 /* Standout mode */ X#define A_US 0x2 /* Underscore mode */ X#define A_BL 0x4 /* Blinking */ X#define A_BD 0x8 /* Bold mode */ X#define A_DI 0x10 /* Dim mode */ X#define A_RV 0x20 /* Reverse mode */ X#define A_MAX 0x20 X X/* Types of movement used by Goto() */ Xenum move_t { X M_NONE, X M_UP, X M_DO, X M_LE, X M_RI, X M_RW, X M_CR, X}; X X#define MAXARGS 64 X#define EXPENSIVE 1000 X Xextern char *getenv(), *tgetstr(), *tgoto(), *malloc(); X Xint rows, cols; Xint status; Xint flowctl; Xchar Term[] = "TERM=screen"; Xchar Termcap[1024]; Xchar *blank; Xchar PC; Xtime_t TimeDisplayed; X X#ifdef OSK X#define SR SR_ X#endif X Xstatic char tbuf[1024], tentry[1024]; Xstatic char *tp = tentry; X#ifdef OSK Xstatic char *TI, *TE, *BL, *VB, *CR, *NL, *CL, *IS, *CM; X#else Xstatic char *TI, *TE, *BL, *VB, *BC, *CR, *NL, *CL, *IS, *CM; X#endif Xstatic char *US, *UE, *SO, *SE, *CE, *CD, *DO, *SR, *SF, *AL; X#ifdef OSK Xstatic char *CS, *DL, *DC, *IC, *IM, *EI, *ND, *KS, *KE; X#else Xstatic char *CS, *DL, *DC, *IC, *IM, *EI, *UP, *ND, *KS, *KE; X#endif Xstatic char *MB, *MD, *MH, *MR, *ME; Xstatic AM; Xstatic args[MAXARGS]; Xstatic char GotArg[MAXARGS]; Xstatic NumArgs; Xstatic char GlobalAttr, TmpAttr; Xstatic char *OldImage, *OldAttr; Xstatic last_x, last_y; Xstatic struct win *curr; Xstatic display = 1; Xstatic StrCost; Xstatic UPcost, DOcost, LEcost, NDcost, CRcost, IMcost, EIcost; Xstatic tcLineLen = 100; Xstatic char *null; Xstatic StatLen; Xstatic insert; Xstatic keypad; X Xstatic char *KeyCaps[] = { X "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7", "k8", "k9", X "kb", "kd", "kh", "kl", "ko", "kr", "ku", X 0 X}; X Xstatic char TermcapConst[] = "TERMCAP=\ XSC|screen|VT 100/ANSI X3.64 virtual terminal|\\\n\ X\t:DO=\\E[%dB:LE=\\E[%dD:RI=\\E[%dC:UP=\\E[%dA:bs:bt=\\E[Z:\\\n\ X\t:cd=\\E[J:ce=\\E[K:cl=\\E[2J\\E[H:cm=\\E[%i%d;%dH:ct=\\E[3g:\\\n\ X\t:do=\\E[B:nd=\\E[C:pt:rc=\\E8:rs=\\Ec:sc=\\E7:st=\\EH:up=\\E[A:"; X X#ifdef OSK Xvoid bzero(buf, num) X register char *buf; X register int num; X{ X for (; num > 0; num--) X *buf++ = '\0'; X} X#define bcopy(a,b,c) memcpy(b,a,c) X#endif X X XInitTerm () { X register char *s; X X if ((s = getenv ("TERM")) == 0) X Msg (0, "No TERM in environment."); X if (tgetent (tbuf, s) != 1) X Msg (0, "Cannot find termcap entry for %s.", s); X cols = tgetnum ("co"); X rows = tgetnum ("li"); X if (cols <= 0) X cols = 80; X if (rows <= 0) X rows = 24; X if (tgetflag ("hc")) X Msg (0, "You can't run screen on a hardcopy terminal."); X if (tgetflag ("os")) X Msg (0, "You can't run screen on a terminal that overstrikes."); X if (tgetflag ("ns")) X Msg (0, "Terminal must support scrolling."); X if (!(CL = tgetstr ("cl", &tp))) X Msg (0, "Clear screen capability required."); X if (!(CM = tgetstr ("cm", &tp))) X Msg (0, "Addressable cursor capability required."); X if (s = tgetstr ("ps", &tp)) X PC = s[0]; X flowctl = !tgetflag ("NF"); X AM = tgetflag ("am"); X if (tgetflag ("LP")) X AM = 0; X TI = tgetstr ("ti", &tp); X TE = tgetstr ("te", &tp); X if (!(BL = tgetstr ("bl", &tp))) X BL = "\007"; X VB = tgetstr ("vb", &tp); X if (!(BC = tgetstr ("bc", &tp))) { X if (tgetflag ("bs")) X BC = "\b"; X else X BC = tgetstr ("le", &tp); X } X if (!(CR = tgetstr ("cr", &tp))) X CR = "\r"; X if (!(NL = tgetstr ("nl", &tp))) X#ifdef OSK X NL = "\l"; X#else X NL = "\n"; X#endif X IS = tgetstr ("is", &tp); X if (tgetnum ("sg") <= 0) { X US = tgetstr ("us", &tp); X UE = tgetstr ("ue", &tp); X SO = tgetstr ("so", &tp); X SE = tgetstr ("se", &tp); X MB = tgetstr ("mb", &tp); X MD = tgetstr ("md", &tp); X MH = tgetstr ("mh", &tp); X MR = tgetstr ("mr", &tp); X ME = tgetstr ("me", &tp); X /* X * Does ME also reverse the effect of SO and/or US? This is not X * clearly specified by the termcap manual. X * Anyway, we should at least look whether ME and SE/UE are equal: X */ X if (SE && UE && ME && (strcmp (SE, UE) == 0 || strcmp (ME, UE) == 0)) X UE = 0; X if (SE && ME && strcmp (SE, ME) == 0) X SE = 0; X } X CE = tgetstr ("ce", &tp); X CD = tgetstr ("cd", &tp); X if (!(DO = tgetstr ("do", &tp))) X DO = NL; X UP = tgetstr ("up", &tp); X ND = tgetstr ("nd", &tp); X SR = tgetstr ("sr", &tp); X if (!(SF = tgetstr ("sf", &tp))) X SF = NL; X AL = tgetstr ("al", &tp); X DL = tgetstr ("dl", &tp); X CS = tgetstr ("cs", &tp); X DC = tgetstr ("dc", &tp); X IC = tgetstr ("ic", &tp); X IM = tgetstr ("im", &tp); X EI = tgetstr ("ei", &tp); X if (tgetflag ("in")) X IC = IM = 0; X if (IC && IC[0] == '\0') X IC = 0; X if (IM && IM[0] == '\0') X IM = 0; X if (EI && EI[0] == '\0') X EI = 0; X KS = tgetstr ("ks", &tp); X KE = tgetstr ("ke", &tp); X blank = malloc (cols); X null = malloc (cols); X OldImage = malloc (cols); X OldAttr = malloc (cols); X if (!(blank && null && OldImage && OldAttr)) X Msg (0, "Out of memory."); X MakeBlankLine (blank, cols); X bzero (null, cols); X UPcost = CalcCost (UP); X DOcost = CalcCost (DO); X LEcost = CalcCost (BC); X NDcost = CalcCost (ND); X CRcost = CalcCost (CR); X IMcost = CalcCost (IM); X EIcost = CalcCost (EI); X PutStr (IS); X PutStr (TI); X PutStr (CL); X} X XFinitTerm () { X PutStr (TE); X PutStr (IS); X} X Xstatic AddCap (s) char *s; { X register n; X X if (tcLineLen + (n = strlen (s)) > 55) { X strcat (Termcap, "\\\n\t:"); X tcLineLen = 0; X } X strcat (Termcap, s); X tcLineLen += n; X} X Xchar *MakeTermcap (aflag) { X char buf[1024]; X register char **pp, *p; X X strcpy (Termcap, TermcapConst); X sprintf (buf, "li#%d:co#%d:", rows, cols); X AddCap (buf); X if (VB) X AddCap ("vb=\\E[?5h\\E[?5l:"); X if (US) { X AddCap ("us=\\E[4m:"); X AddCap ("ue=\\E[24m:"); X } X if (SO) { X AddCap ("so=\\E[3m:"); X AddCap ("se=\\E[23m:"); X } X if (MB) X AddCap ("mb=\\E[5m:"); X if (MD) X AddCap ("md=\\E[1m:"); X if (MH) X AddCap ("mh=\\E[2m:"); X if (MR) X AddCap ("mr=\\E[7m:"); X if (MB || MD || MH || MR) X AddCap ("me=\\E[0m:"); X if ((CS && SR) || AL || aflag) { X AddCap ("sr=\\EM:"); X AddCap ("al=\\E[L:"); X AddCap ("AL=\\E[%dL:"); X } X if (CS || DL || aflag) { X AddCap ("dl=\\E[M:"); X AddCap ("DL=\\E[%dM:"); X } X if (CS) X AddCap ("cs=\\E[%i%d;%dr:"); X if (DC || aflag) { X AddCap ("dc=\\E[P:"); X AddCap ("DC=\\E[%dP:"); X } X if (IC || IM || aflag) { X AddCap ("im=\\E[4h:"); X AddCap ("ei=\\E[4l:"); X AddCap ("ic=:"); X AddCap ("IC=\\E[%d@:"); X } X if (KS) X AddCap ("ks=\\E=:"); X if (KE) X AddCap ("ke=\\E>:"); X for (pp = KeyCaps; *pp; ++pp) X if (p = tgetstr (*pp, &tp)) { X MakeString (*pp, buf, p); X AddCap (buf); X } X return Termcap; X} X XMakeString (cap, buf, s) char *cap, *buf; register char *s; { X register char *p = buf; X register unsigned c; X X *p++ = *cap++; *p++ = *cap; *p++ = '='; X while (c = *s++) { X switch (c) { X case '\033': X *p++ = '\\'; *p++ = 'E'; break; X case ':': X sprintf (p, "\\072"); p += 4; break; X case '^': case '\\': X *p++ = '\\'; *p++ = c; break; X default: X if (c >= 200) { X sprintf (p, "\\%03o", c & 0377); p += 4; X } else if (c < ' ') { X *p++ = '^'; *p++ = c + '@'; X } else *p++ = c; X } X } X *p++ = ':'; *p = '\0'; X} X XActivate (wp) struct win *wp; { X RemoveStatus (wp); X curr = wp; X display = 1; X NewRendition (GlobalAttr, curr->LocalAttr); X GlobalAttr = curr->LocalAttr; X InsertMode (curr->insert); X KeypadMode (curr->keypad); X if (CS) X PutStr (tgoto (CS, curr->bot, curr->top)); X Redisplay (); X} X XResetScreen (p) register struct win *p; { X register i; X X bzero (p->tabs, cols); X for (i = 8; i < cols; i += 8) X p->tabs[i] = 1; X p->wrap = 1; X p->origin = 0; X p->insert = 0; X p->vbwait = 0; X p->keypad = 0; X p->top = 0; X p->bot = rows - 1; X p->saved = 0; X p->LocalAttr = 0; X p->x = p->y = 0; X p->state = LIT; X p->StringType = NONE; X} X XWriteString (wp, buf, len) struct win *wp; register char *buf; { X register c, intermediate = 0; X X if (!len) X return; X curr = wp; X display = curr->active; X if (display) X RemoveStatus (wp); X do { X c = *buf++; X if (c == '\0' || c == '\177') X continue; XNextChar: X switch (curr->state) { X case TERM: X switch (c) { X case '\\': X curr->state = LIT; X *(curr->stringp) = '\0'; X if (curr->StringType == PM && display) { X MakeStatus (curr->string, curr); X if (status && len > 1) { X curr->outlen = len-1; X bcopy (buf, curr->outbuf, curr->outlen); X return; X } X } X break; X default: X curr->state = STR; X AddChar ('\033'); X AddChar (c); X } X break; X case STR: X switch (c) { X case '\0': X break; X case '\033': X curr->state = TERM; break; X default: X AddChar (c); X } X break; X case ESC: X switch (c) { X case '[': X NumArgs = 0; X intermediate = 0; X bzero ((char *)args, MAXARGS * sizeof (int)); X bzero (GotArg, MAXARGS); X curr->state = CSI; X break; X case ']': X StartString (OSC); break; X case '_': X StartString (APC); break; X case 'P': X StartString (DCS); break; X case '^': X StartString (PM); break; X default: X if (Special (c)) X break; X if (c >= ' ' && c <= '/') { X intermediate = intermediate ? -1 : c; X } else if (c >= '0' && c <= '~') { X DoESC (c, intermediate); X curr->state = LIT; X } else { X curr->state = LIT; X goto NextChar; X } X } X break; X case CSI: X switch (c) { X case '0': case '1': case '2': case '3': case '4': X case '5': case '6': case '7': case '8': case '9': X if (NumArgs < MAXARGS) { X args[NumArgs] = 10 * args[NumArgs] + c - '0'; X GotArg[NumArgs] = 1; X } X break; X case ';': case ':': X NumArgs++; break; X default: X if (Special (c)) X break; X if (c >= '@' && c <= '~') { X NumArgs++; X DoCSI (c, intermediate); X curr->state = LIT; X } else if ((c >= ' ' && c <= '/') || (c >= '<' && c <= '?')) { X intermediate = intermediate ? -1 : c; X } else { X curr->state = LIT; X goto NextChar; X } X } X break; X default: X if (!Special (c)) { X if (c == '\033') { X intermediate = 0; X curr->state = ESC; X } else if (c < ' ') { X break; X } else if (curr->x < cols-1) { X if (curr->insert) { X InsertAChar (c); X } else { X if (display) X putchar (c); X SetChar (c); X } X curr->x++; X } else if (curr->x == cols-1) { X SetChar (c); X if (!(AM && curr->y == rows-1)) { X if (display) X putchar (c); X Goto (-1, -1, curr->y, curr->x); X } X curr->x++; X } else { X if (curr->wrap) { X Return (); X LineFeed (); X if (curr->insert) { X InsertAChar (c); X } else { X if (display) X putchar (c); X SetChar (c); X } X curr->x = 1; X } else curr->x = cols; X } X } X } X } while (--len); X curr->outlen = 0; X} X Xstatic Special (c) register c; { X switch (c) { X case '\b': X BackSpace (); return 1; X case '\r': X Return (); return 1; X#ifdef OSK X case '\l': X#else X case '\n': X#endif X LineFeed (); return 1; X case '\007': X PutStr (BL); X if (!display) X curr->bell = 1; X return 1; X case '\t': X ForwardTab (); return 1; X } X return 0; X} X Xstatic DoESC (c, intermediate) { X switch (intermediate) { X case 0: X switch (c) { X case 'E': X Return (); X LineFeed (); X break; X case 'D': X LineFeed (); X break; X case 'M': X ReverseLineFeed (); X break; X case 'H': X curr->tabs[curr->x] = 1; X break; X case '7': X SaveCursor (); X break; X case '8': X RestoreCursor (); X break; X case 'c': X ClearScreen (); X Goto (curr->y, curr->x, 0, 0); X NewRendition (GlobalAttr, 0); X SetRendition (0); X if (curr->insert) X InsertMode (0); X if (curr->keypad) X KeypadMode (0); X if (CS) X PutStr (tgoto (CS, rows-1, 0)); X ResetScreen (curr); X break; X case '=': X KeypadMode (1); X curr->keypad = 1; X break; X case '>': X KeypadMode (0); X curr->keypad = 0; X break; X } X break; X case '#': X switch (c) { X case '8': X FillWithEs (); X break; X } X break; X } X} X Xstatic DoCSI (c, intermediate) { X register i, a1 = args[0], a2 = args[1]; X X if (NumArgs >= MAXARGS) X NumArgs = MAXARGS; X for (i = 0; i < NumArgs; ++i) X if (args[i] == 0) X GotArg[i] = 0; X switch (intermediate) { X case 0: X switch (c) { X case 'H': case 'f': X if (!GotArg[0]) a1 = 1; X if (!GotArg[1]) a2 = 1; X if (curr->origin) X a1 += curr->top; X if (a1 < 1) X a1 = 1; X if (a1 > rows) X a1 = rows; X if (a2 < 1) X a2 = 1; X if (a2 > cols) X a2 = cols; X a1--; a2--; X Goto (curr->y, curr->x, a1, a2); X curr->y = a1; X curr->x = a2; X break; X case 'J': X if (!GotArg[0] || a1 < 0 || a1 > 2) X a1 = 0; X switch (a1) { X case 0: X ClearToEOS (); break; X case 1: X ClearFromBOS (); break; X case 2: X ClearScreen (); X Goto (0, 0, curr->y, curr->x); X break; X } X break; X case 'K': X if (!GotArg[0] || a1 < 0 || a2 > 2) X a1 = 0; X switch (a1) { X case 0: X ClearToEOL (); break; X case 1: X ClearFromBOL (); break; X case 2: X ClearLine (); break; X } X break; X case 'A': X CursorUp (GotArg[0] ? a1 : 1); X break; X case 'B': X CursorDown (GotArg[0] ? a1 : 1); X break; X case 'C': X CursorRight (GotArg[0] ? a1 : 1); X break; X case 'D': X CursorLeft (GotArg[0] ? a1 : 1); X break; X case 'm': X SelectRendition (); X break; X case 'g': X if (!GotArg[0] || a1 == 0) X curr->tabs[curr->x] = 0; X else if (a1 == 3) X bzero (curr->tabs, cols); X break; X case 'r': X if (!CS) X break; X if (!GotArg[0]) a1 = 1; X if (!GotArg[1]) a2 = rows; X if (a1 < 1 || a2 > rows || a1 >= a2) X break; X curr->top = a1-1; X curr->bot = a2-1; X PutStr (tgoto (CS, curr->bot, curr->top)); X if (curr->origin) { X Goto (-1, -1, curr->top, 0); X curr->y = curr->top; X curr->x = 0; X } else { X Goto (-1, -1, 0, 0); X curr->y = curr->x = 0; X } X break; X case 'I': X if (!GotArg[0]) a1 = 1; X while (a1--) X ForwardTab (); X break; X case 'Z': X if (!GotArg[0]) a1 = 1; X while (a1--) X BackwardTab (); X break; X case 'L': X InsertLine (GotArg[0] ? a1 : 1); X break; X case 'M': X DeleteLine (GotArg[0] ? a1 : 1); X break; X case 'P': X DeleteChar (GotArg[0] ? a1 : 1); X break; X case '@': X InsertChar (GotArg[0] ? a1 : 1); X break; X case 'h': X SetMode (1); X break; X case 'l': X SetMode (0); X break; X } X break; X case '?': X if (c != 'h' && c != 'l') X break; X if (!GotArg[0]) X break; X i = (c == 'h'); X if (a1 == 5) { X if (i) { X curr->vbwait = 1; X } else { X if (curr->vbwait) X PutStr (VB); X curr->vbwait = 0; X } X } else if (a1 == 6) { X curr->origin = i; X if (curr->origin) { X Goto (curr->y, curr->x, curr->top, 0); X curr->y = curr->top; X curr->x = 0; X } else { X Goto (curr->y, curr->x, 0, 0); X curr->y = curr->x = 0; X } X } else if (a1 == 7) { X curr->wrap = i; X } X break; X } X} X Xstatic PutChar (c) { X putchar (c); X} X Xstatic PutStr (s) char *s; { X if (display && s) X tputs (s, 1, PutChar); X} X Xstatic SetChar (c) register c; { X register struct win *p = curr; X X p->image[p->y][p->x] = c; X p->attr[p->y][p->x] = p->LocalAttr; X} X Xstatic StartString (type) enum string_t type; { X curr->StringType = type; X curr->stringp = curr->string; X curr->state = STR; X} X Xstatic AddChar (c) { X if (curr->stringp > curr->string+MAXSTR-1) X curr->state = LIT; X else X *(curr->stringp)++ = c; X} X X/* Insert mode is a toggle on some terminals, so we need this hack: X */ XInsertMode (on) { X if (on) { X if (!insert) X PutStr (IM); X } else if (insert) X PutStr (EI); X insert = on; X} X X/* ...and maybe keypad application mode is a toggle, too: X */ XKeypadMode (on) { X if (on) { X if (!keypad) X PutStr (KS); X } else if (keypad) X PutStr (KE); X keypad = on; X} X Xstatic SaveCursor () { X curr->saved = 1; X curr->Saved_x = curr->x; X curr->Saved_y = curr->y; X curr->SavedLocalAttr = curr->LocalAttr; X} X Xstatic RestoreCursor () { X if (curr->saved) { X curr->LocalAttr = curr->SavedLocalAttr; X NewRendition (GlobalAttr, curr->LocalAttr); X GlobalAttr = curr->LocalAttr; X Goto (curr->y, curr->x, curr->Saved_y, curr->Saved_x); X curr->x = curr->Saved_x; X curr->y = curr->Saved_y; X } X} X X/*ARGSUSED*/ XCountChars (c) { X StrCost++; X} X XCalcCost (s) register char *s; { X if (s) { X StrCost = 0; X tputs (s, 1, CountChars); X return StrCost; X } else return EXPENSIVE; X} X Xstatic Goto (y1, x1, y2, x2) { X register dy, dx; X register cost = 0; X register char *s; X int CMcost, n, m; X enum move_t xm = M_NONE, ym = M_NONE; X X if (!display) X return; X if (x1 == cols || x2 == cols) { X if (x2 == cols) --x2; X goto DoCM; X } X dx = x2 - x1; X dy = y2 - y1; X if (dy == 0 && dx == 0) X return; X if (y1 == -1 || x1 == -1) { XDoCM: X PutStr (tgoto (CM, x2, y2)); X return; X } X CMcost = CalcCost (tgoto (CM, x2, y2)); X if (dx > 0) { X if ((n = RewriteCost (y1, x1, x2)) < (m = dx * NDcost)) { X cost = n; X xm = M_RW; X } else { X cost = m; X xm = M_RI; X } X } else if (dx < 0) { X cost = -dx * LEcost; X xm = M_LE; X } X if (dx && (n = RewriteCost (y1, 0, x2) + CRcost) < cost) { X cost = n; X xm = M_CR; X } X if (cost >= CMcost) X goto DoCM; X if (dy > 0) { X cost += dy * DOcost; X ym = M_DO; X } else if (dy < 0) { X cost += -dy * UPcost; X ym = M_UP; X } X if (cost >= CMcost) X goto DoCM; X if (xm != M_NONE) { X if (xm == M_LE || xm == M_RI) { X if (xm == M_LE) { X s = BC; dx = -dx; X } else s = ND; X while (dx-- > 0) X PutStr (s); X } else { X if (xm == M_CR) { X PutStr (CR); X x1 = 0; X } X if (x1 < x2) { X if (curr->insert) X InsertMode (0); X for (s = curr->image[y1]+x1; x1 < x2; x1++, s++) X putchar (*s); X if (curr->insert) X InsertMode (1); X } X } X } X if (ym != M_NONE) { X if (ym == M_UP) { X s = UP; dy = -dy; X } else s = DO; X while (dy-- > 0) X PutStr (s); X } X} X Xstatic RewriteCost (y, x1, x2) { X register cost, dx; X register char *p = curr->attr[y]+x1; X X if (AM && y == rows-1 && x2 == cols-1) X return EXPENSIVE; X cost = dx = x2 - x1; X if (dx == 0) X return 0; X if (curr->insert) X cost += EIcost + IMcost; X do { X if (*p++ != GlobalAttr) X return EXPENSIVE; X } while (--dx); X return cost; X} X Xstatic BackSpace () { X if (curr->x > 0) { X if (curr->x < cols) { X if (BC) X PutStr (BC); X else X Goto (curr->y, curr->x, curr->y, curr->x-1); X } X curr->x--; X } X} X Xstatic Return () { X if (curr->x > 0) { X curr->x = 0; X PutStr (CR); X } X} X Xstatic LineFeed () { X if (curr->y == curr->bot) { X ScrollUpMap (curr->image); X ScrollUpMap (curr->attr); X } else if (curr->y < rows-1) { X curr->y++; X } X PutStr (NL); X} X Xstatic ReverseLineFeed () { X if (curr->y == curr->top) { X ScrollDownMap (curr->image); X ScrollDownMap (curr->attr); X if (SR) { X PutStr (SR); X } else if (AL) { X Goto (curr->top, curr->x, curr->top, 0); X PutStr (AL); X Goto (curr->top, 0, curr->top, curr->x); X } else Redisplay (); X } else if (curr->y > 0) { X CursorUp (1); X } X} X Xstatic InsertAChar (c) { X register y = curr->y, x = curr->x; X X if (x == cols) X x--; X bcopy (curr->image[y], OldImage, cols); X bcopy (curr->attr[y], OldAttr, cols); X bcopy (curr->image[y]+x, curr->image[y]+x+1, cols-x-1); X bcopy (curr->attr[y]+x, curr->attr[y]+x+1, cols-x-1); X SetChar (c); X if (!display) X return; X if (IC || IM) { X if (!curr->insert) X InsertMode (1); X PutStr (IC); X putchar (c); X if (!curr->insert) X InsertMode (0); X } else { X RedisplayLine (OldImage, OldAttr, y, x, cols-1); X ++x; X Goto (y, last_x, y, x); X } X} X Xstatic InsertChar (n) { X register i, y = curr->y, x = curr->x; X X if (x == cols) X return; X bcopy (curr->image[y], OldImage, cols); X bcopy (curr->attr[y], OldAttr, cols); X if (n > cols-x) X n = cols-x; X bcopy (curr->image[y]+x, curr->image[y]+x+n, cols-x-n); X bcopy (curr->attr[y]+x, curr->attr[y]+x+n, cols-x-n); X ClearInLine (0, y, x, x+n-1); X if (!display) X return; X if (IC || IM) { X if (!curr->insert) X InsertMode (1); X for (i = n; i; i--) { X PutStr (IC); X putchar (' '); X } X if (!curr->insert) X InsertMode (0); X Goto (y, x+n, y, x); X } else { X RedisplayLine (OldImage, OldAttr, y, x, cols-1); X Goto (y, last_x, y, x); X } X} X Xstatic DeleteChar (n) { X register i, y = curr->y, x = curr->x; X X if (x == cols) X return; X bcopy (curr->image[y], OldImage, cols); X bcopy (curr->attr[y], OldAttr, cols); X if (n > cols-x) X n = cols-x; X bcopy (curr->image[y]+x+n, curr->image[y]+x, cols-x-n); X bcopy (curr->attr[y]+x+n, curr->attr[y]+x, cols-x-n); X ClearInLine (0, y, cols-n, cols-1); X if (!display) X return; X if (DC) { X for (i = n; i; i--) X PutStr (DC); X } else { X RedisplayLine (OldImage, OldAttr, y, x, cols-1); X Goto (y, last_x, y, x); X } X} X Xstatic DeleteLine (n) { X register i, old = curr->top; X X if (n > curr->bot-curr->y+1) X n = curr->bot-curr->y+1; X curr->top = curr->y; X for (i = n; i; i--) { X ScrollUpMap (curr->image); X ScrollUpMap (curr->attr); X } X if (DL) { X Goto (curr->y, curr->x, curr->y, 0); X for (i = n; i; i--) X PutStr (DL); X Goto (curr->y, 0, curr->y, curr->x); X } else if (CS) { X PutStr (tgoto (CS, curr->bot, curr->top)); X Goto (-1, -1, curr->bot, 0); X for (i = n; i; i--) X PutStr (SF); X PutStr (tgoto (CS, curr->bot, old)); X Goto (-1, -1, curr->y, curr->x); X } else Redisplay (); X curr->top = old; X} X Xstatic InsertLine (n) { X register i, old = curr->top; X X if (n > curr->bot-curr->y+1) X n = curr->bot-curr->y+1; X curr->top = curr->y; X for (i = n; i; i--) { X ScrollDownMap (curr->image); X ScrollDownMap (curr->attr); X } X if (AL) { X Goto (curr->y, curr->x, curr->y, 0); X for (i = n; i; i--) X PutStr (AL); X Goto (curr->y, 0, curr->y, curr->x); X } else if (CS && SR) { X PutStr (tgoto (CS, curr->bot, curr->top)); X Goto (-1, -1, curr->y, 0); X for (i = n; i; i--) X PutStr (SR); X PutStr (tgoto (CS, curr->bot, old)); X Goto (-1, -1, curr->y, curr->x); X } else Redisplay (); X curr->top = old; X} X Xstatic ScrollUpMap (pp) char **pp; { X register char *tmp = pp[curr->top]; X X bcopy (pp+curr->top+1, pp+curr->top, X (curr->bot-curr->top) * sizeof (char *)); X if (pp == curr->image) X bclear (tmp, cols); X else X bzero (tmp, cols); X pp[curr->bot] = tmp; X} X Xstatic ScrollDownMap (pp) char **pp; { X register char *tmp = pp[curr->bot]; X X bcopy (pp+curr->top, pp+curr->top+1, X (curr->bot-curr->top) * sizeof (char *)); X if (pp == curr->image) X bclear (tmp, cols); X else X bzero (tmp, cols); X pp[curr->top] = tmp; X} X Xstatic ForwardTab () { X register x = curr->x; X X if (curr->tabs[x] && x < cols-1) X ++x; X while (x < cols-1 && !curr->tabs[x]) X x++; X Goto (curr->y, curr->x, curr->y, x); X curr->x = x; X} X Xstatic BackwardTab () { X register x = curr->x; X X if (curr->tabs[x] && x > 0) X x--; X while (x > 0 && !curr->tabs[x]) X x--; X Goto (curr->y, curr->x, curr->y, x); X curr->x = x; X} X Xstatic ClearScreen () { X register i; X X PutStr (CL); X for (i = 0; i < rows; ++i) { X bclear (curr->image[i], cols); X bzero (curr->attr[i], cols); X } X} X Xstatic ClearFromBOS () { X register n, y = curr->y, x = curr->x; X X for (n = 0; n < y; ++n) X ClearInLine (1, n, 0, cols-1); X ClearInLine (1, y, 0, x); X Goto (curr->y, curr->x, y, x); X curr->y = y; curr->x = x; X} X Xstatic ClearToEOS () { X register n, y = curr->y, x = curr->x; X X if (CD) X PutStr (CD); X ClearInLine (!CD, y, x, cols-1); X for (n = y+1; n < rows; n++) X ClearInLine (!CD, n, 0, cols-1); X Goto (curr->y, curr->x, y, x); X curr->y = y; curr->x = x; X} X Xstatic ClearLine () { X register y = curr->y, x = curr->x; X X ClearInLine (1, y, 0, cols-1); X Goto (curr->y, curr->x, y, x); X curr->y = y; curr->x = x; X} X Xstatic ClearToEOL () { X register y = curr->y, x = curr->x; X X ClearInLine (1, y, x, cols-1); X Goto (curr->y, curr->x, y, x); X curr->y = y; curr->x = x; X} X Xstatic ClearFromBOL () { X register y = curr->y, x = curr->x; X X ClearInLine (1, y, 0, x); X Goto (curr->y, curr->x, y, x); X curr->y = y; curr->x = x; X} X Xstatic ClearInLine (displ, y, x1, x2) { X register i, n; X X if (x1 == cols) x1--; X if (x2 == cols) x2--; X if (n = x2 - x1 + 1) { X bclear (curr->image[y]+x1, n); X bzero (curr->attr[y]+x1, n); X if (displ && display) { X if (x2 == cols-1 && CE) { X Goto (curr->y, curr->x, y, x1); X curr->y = y; curr->x = x1; X PutStr (CE); X return; X } X if (y == rows-1 && AM) X --n; X if (n == 0) X return; X SaveAttr (); X Goto (curr->y, curr->x, y, x1); X for (i = n; i > 0; i--) X putchar (' '); X curr->y = y; curr->x = x1 + n; X RestoreAttr (); X } X } X} X Xstatic CursorRight (n) register n; { X register x = curr->x; X X if (x == cols) X return; X if ((curr->x += n) >= cols) X curr->x = cols-1; X Goto (curr->y, x, curr->y, curr->x); X} X Xstatic CursorUp (n) register n; { X register y = curr->y; X X if ((curr->y -= n) < curr->top) X curr->y = curr->top; X Goto (y, curr->x, curr->y, curr->x); X} X Xstatic CursorDown (n) register n; { X register y = curr->y; X X if ((curr->y += n) > curr->bot) X curr->y = curr->bot; X Goto (y, curr->x, curr->y, curr->x); X} X Xstatic CursorLeft (n) register n; { X register x = curr->x; X X if ((curr->x -= n) < 0) X curr->x = 0; X Goto (curr->y, x, curr->y, curr->x); X} X Xstatic SetMode (on) { X register i; X X for (i = 0; i < NumArgs; ++i) { X switch (args[i]) { X case 4: X curr->insert = on; X InsertMode (on); X break; X } X } X} X Xstatic SelectRendition () { X register i, old = GlobalAttr; X X if (NumArgs == 0) X SetRendition (0); X else for (i = 0; i < NumArgs; ++i) X SetRendition (args[i]); X NewRendition (old, GlobalAttr); X} X Xstatic SetRendition (n) register n; { X switch (n) { X case 0: X GlobalAttr = 0; break; X case 1: X GlobalAttr |= A_BD; break; X case 2: X GlobalAttr |= A_DI; break; X case 3: X GlobalAttr |= A_SO; break; X case 4: X GlobalAttr |= A_US; break; X case 5: X GlobalAttr |= A_BL; break; X case 7: X GlobalAttr |= A_RV; break; X case 22: X GlobalAttr &= ~(A_BD|A_SO|A_DI); break; X case 23: X GlobalAttr &= ~A_SO; break; X case 24: X GlobalAttr &= ~A_US; break; X case 25: X GlobalAttr &= ~A_BL; break; X case 27: X GlobalAttr &= ~A_RV; break; X } X curr->LocalAttr = GlobalAttr; X} X Xstatic NewRendition (old, new) register old, new; { X register i; X X if (old == new) X return; X for (i = 1; i <= A_MAX; i <<= 1) { X if ((old & i) && !(new & i)) { X PutStr (UE); X PutStr (SE); X PutStr (ME); X if (new & A_US) PutStr (US); X if (new & A_SO) PutStr (SO); X if (new & A_BL) PutStr (MB); X if (new & A_BD) PutStr (MD); X if (new & A_DI) PutStr (MH); X if (new & A_RV) PutStr (MR); X return; X } X } X if ((new & A_US) && !(old & A_US)) X PutStr (US); X if ((new & A_SO) && !(old & A_SO)) X PutStr (SO); X if ((new & A_BL) && !(old & A_BL)) X PutStr (MB); X if ((new & A_BD) && !(old & A_BD)) X PutStr (MD); X if ((new & A_DI) && !(old & A_DI)) X PutStr (MH); X if ((new & A_RV) && !(old & A_RV)) X PutStr (MR); X} X Xstatic SaveAttr () { X NewRendition (GlobalAttr, 0); X if (curr->insert) X InsertMode (0); X} X Xstatic RestoreAttr () { X NewRendition (0, GlobalAttr); X if (curr->insert) X InsertMode (1); X} X Xstatic FillWithEs () { X register i; X register char *p, *ep; X X curr->y = curr->x = 0; X NewRendition (GlobalAttr, 0); X SetRendition (0); X for (i = 0; i < rows; ++i) { X bzero (curr->attr[i], cols); X p = curr->image[i]; X ep = p + cols; X for ( ; p < ep; ++p) X *p = 'E'; X } X Redisplay (); X} X Xstatic Redisplay () { X register i; X X PutStr (CL); X TmpAttr = GlobalAttr; X last_x = last_y = 0; X for (i = 0; i < rows; ++i) X DisplayLine (blank, null, curr->image[i], curr->attr[i], i, 0, cols-1); X NewRendition (TmpAttr, GlobalAttr); X Goto (last_y, last_x, curr->y, curr->x); X} X Xstatic DisplayLine (os, oa, s, as, y, from, to) X register char *os, *oa, *s, *as; { X register i, x, a; X X if (to == cols) X --to; X if (AM && y == rows-1 && to == cols-1) X --to; X a = TmpAttr; X for (x = i = from; i <= to; ++i, ++x) { X if (s[i] == os[i] && as[i] == oa[i] && as[i] == a) X continue; X Goto (last_y, last_x, y, x); X last_y = y; X last_x = x; X if ((a = as[i]) != TmpAttr) { X NewRendition (TmpAttr, a); X TmpAttr = a; X } X putchar (s[i]); X last_x++; X } X} X Xstatic RedisplayLine (os, oa, y, from, to) char *os, *oa; { X if (curr->insert) X InsertMode (0); X NewRendition (GlobalAttr, 0); X TmpAttr = 0; X last_y = y; X last_x = from; X DisplayLine (os, oa, curr->image[y], curr->attr[y], y, from, to); X NewRendition (TmpAttr, GlobalAttr); X if (curr->insert) X InsertMode (1); X} X Xstatic MakeBlankLine (p, n) register char *p; register n; { X do *p++ = ' '; X while (--n); X} X XMakeStatus (msg, wp) char *msg; struct win *wp; { X struct win *ocurr = curr; X int odisplay = display; X register char *s, *t; X register max = AM ? cols-1 : cols; X X for (s = t = msg; *s && t - msg < max; ++s) X if (*s >= ' ' && *s <= '~') X *t++ = *s; X *t = '\0'; X curr = wp; X display = 1; X if (status) { X if (time ((time_t *)0) - TimeDisplayed < 2) X sleep (1); X RemoveStatus (wp); X } X if (t > msg) { X status = 1; X StatLen = t - msg; X Goto (curr->y, curr->x, rows-1, 0); X NewRendition (GlobalAttr, A_SO); X if (curr->insert) X InsertMode (0); X printf ("%s", msg); X if (curr->insert) X InsertMode (1); X NewRendition (A_SO, GlobalAttr); X fflush (stdout); X time (&TimeDisplayed); X } X curr = ocurr; X display = odisplay; X} X XRemoveStatus (p) struct win *p; { X struct win *ocurr = curr; X int odisplay = display; X X if (!status) X return; X status = 0; X curr = p; X display = 1; X Goto (-1, -1, rows-1, 0); X RedisplayLine (null, null, rows-1, 0, StatLen); X Goto (rows-1, last_x, curr->y, curr->x); X curr = ocurr; X display = odisplay; X} END_OF_FILE if test 30846 -ne `wc -c <'ansi.c'`; then echo shar: \"'ansi.c'\" unpacked with wrong size! fi # end of 'ansi.c' fi echo shar: End of archive 2 \(of 3\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- | Wolfgang Ocker | ocker@lan.informatik.tu-muenchen.dbp.de | | Lochhauserstr. 35a | pyramid!tmpmbx!recco!weo (home) | | D-8039 Puchheim | Technische Universitaet Muenchen | | Voice: +49 89 80 77 02 | Huh, What? Where am I? |