home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-08 | 56.6 KB | 2,553 lines |
- Newsgroups: comp.sources.misc
- From: jnweiger@immd4.informatik.uni-erlangen.de (Juergen Weigert)
- Subject: v28i018: screen-3.2 - multiple windows on an ASCII terminal, v3.2, Part01/11
- Message-ID: <csm-v28i018=screen-3.2.163016@sparky.IMD.Sterling.COM>
- X-Md4-Signature: 7ecf76aeefa3a688b10fdb6406d58388
- Date: Sun, 9 Feb 1992 22:33:55 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: jnweiger@immd4.informatik.uni-erlangen.de (Juergen Weigert)
- Posting-number: Volume 28, Issue 18
- Archive-name: screen-3.2/part01
- Environment: UNIX
-
- This is iScreen version 3.2. It is an upgrade to version 3.1.1 that was posted
- in dec 91 to comp.sources.unix. Versions 3.1.x of iScreen are potential
- security risks under SunOS 4.1.1. These versions fail to detach or terminate
- the session when the modem line hangs up. Anyone using telnet or rlogin could
- (unwillingly) connect to such a session.
-
- iScreen users on SunOS 4.1.1 please do upgrade to version 3.2!
-
- Although fixing the bug described above was the main reason for this posting,
- there are numerous other fixes/enhancements:
-
- * support for NeXT, Apollo, Ultrix, SVR4, SCO, ISC, SGI, bsd386, ...
- added or enhanced.
-
- * the "dead CTRL-O key" bug is fixed.
-
- * flow control has been redesigned.
-
- * I/O is no longer stripped to 7 bit.
-
- * new commands "hardcopy_append on", "bufferfile /tmp/myown",
- "(set) refresh off".
-
- * redesign of interrupt passing. The use of "screen -i" is now
- encouraged.
-
- * overall code cleanup.
-
- The complete distribution of iScreen 3.2 is available via ftp from:
-
- ftp.uni-erlangen.de[131.188.1.43]:portal/utilities/screen/screen32.tar.Z
-
- For a brief introduction and a short summary of essential commands
- refer to the files "readme" and "README".
-
- I wish to thank all contributors for requesting features or sending patches.
- Special thanks to Marc Boucher who tested and patched iScreen on numerous
- platforms.
-
- Juergen Weigert || jnweiger@immd4.informatik.uni-erlangen.de || irc: Ellrond
- Boing... Boing..|| feeping creaturism -- bugs and bunnies everywhere.
- Boing... Boing..|| "Oh! No!!!" -- Plopp!
- ------------------------------------------
- #!/bin/sh
- # This is a shell archive (produced by shar 3.49)
- # To extract the files from this archive, save it to a file, remove
- # everything above the "!/bin/sh" line above, and type "sh file_name".
- #
- # existing files will NOT be overwritten unless -c is specified
- #
- # This is part 1 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 68724 -r--r--r-- screen3.2/ansi.c
- # 2276 -r--r--r-- screen3.2/ansi.h
- # 9213 -r--r--r-- screen3.2/extern.h
- # 54830 -r--r--r-- screen3.2/fileio.c
- # 12878 -r--r--r-- screen3.2/help.c
- # 25395 -r--r--r-- screen3.2/mark.c
- # 3666 -r--r--r-- screen3.2/patchlevel.h
- # 5664 -r--r--r-- screen3.2/putenv.c
- # 63790 -r--r--r-- screen3.2/screen.1
- # 86700 -r--r--r-- screen3.2/screen.c
- # 12454 -r--r--r-- screen3.2/screen.h
- # 27101 -r--r--r-- screen3.2/socket.c
- # 14071 -r--r--r-- screen3.2/window.c
- # 643 -rw-r--r-- screen3.2/terminfo/s/screen-w
- # 999 -rw-r--r-- screen3.2/terminfo/s/screen
- # 668 -rw-r--r-- screen3.2/terminfo/screeninfo.src
- # 515 -rw-r--r-- screen3.2/terminfo/screencap
- # 671 -rw-r--r-- screen3.2/terminfo/screenwinfo.src
- # 768 -rw-r--r-- screen3.2/terminfo/getwinsize.c
- # 3056 -rw------- screen3.2/terminfo/screen-sco.src
- # 38899 -rw-rw-r-- screen3.2/terminfo/test.txt
- # 7535 -rw-r--r-- screen3.2/.iscreenrc
- # 3741 -r--r--r-- screen3.2/readme
- # 3036 -r--r--r-- screen3.2/README
- # 1377 -r--r--r-- screen3.2/Makefile
- # 1450 -rw-rw-r-- screen3.2/INSTALLATION
- # 9292 -r--r--r-- screen3.2/CHANGES
- # 9934 -rw-r--r-- screen3.2/COPYING
- # 1389 -rw-rw-r-- screen3.2/poster
- # 8666 -r--r--r-- screen3.2/config/config.all
- # 908 -r--r--r-- screen3.2/config/config.apollo
- # 1385 -r--r--r-- screen3.2/config/config.bsd386
- # 986 -r--r--r-- screen3.2/config/config.gould_np1
- # 841 -r--r--r-- screen3.2/config/config.hpux
- # 1213 -r--r--r-- screen3.2/config/config.isc
- # 940 -r--r--r-- screen3.2/config/config.mips
- # 1043 -r--r--r-- screen3.2/config/config.mot88
- # 1010 -r--r--r-- screen3.2/config/config.next
- # 879 -r--r--r-- screen3.2/config/config.rs600
- # 920 -r--r--r-- screen3.2/config/config.rs6000
- # 1314 -r--r--r-- screen3.2/config/config.sco32
- # 1007 -r--r--r-- screen3.2/config/config.sequent_ptx
- # 1071 -r--r--r-- screen3.2/config/config.sgi
- # 1000 -r--r--r-- screen3.2/config/config.sunos41
- # 1422 -r--r--r-- screen3.2/config/config.svr4
- # 993 -r--r--r-- screen3.2/config/config.symmetry
- # 1061 -r--r--r-- screen3.2/config/config.sysv68
- # 1174 -r--r--r-- screen3.2/config/config.ultrix4
- # 992 -r--r--r-- screen3.2/config/config.xelos
- # 1056 -r--r--r-- screen3.2/config/config.xenix
- # 1508 -r--r--r-- screen3.2/config/Makefile.bsd386
- # 1479 -r--r--r-- screen3.2/config/Makefile.gould_np1
- # 1073 -r--r--r-- screen3.2/config/Makefile.isc
- # 1626 -r--r--r-- screen3.2/config/Makefile.mips
- # 1545 -r--r--r-- screen3.2/config/Makefile.putenv
- # 1455 -r--r--r-- screen3.2/config/Makefile.rs6000
- # 1372 -r--r--r-- screen3.2/config/Makefile.sco32
- # 1466 -r--r--r-- screen3.2/config/Makefile.sgi
- # 1435 -r--r--r-- screen3.2/config/Makefile.svr4
- # 1485 -r--r--r-- screen3.2/config/Makefile.ultrix4
- # 1936 -r--r--r-- screen3.2/config/Makefile.xenix
- # 3523 -rw-rw-r-- screen3.2/etcscreenrc
- #
- if test -r _shar_seq_.tmp; then
- echo 'Must unpack archives in sequence!'
- echo Please unpack part `cat _shar_seq_.tmp` next
- exit 1
- fi
- # ============= screen3.2/ansi.c ==============
- if test ! -d 'screen3.2'; then
- echo 'x - creating directory screen3.2'
- mkdir 'screen3.2'
- fi
- if test -f 'screen3.2/ansi.c' -a X"$1" != X"-c"; then
- echo 'x - skipping screen3.2/ansi.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting screen3.2/ansi.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'screen3.2/ansi.c' &&
- /* Copyright (c) 1991
- X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- X * Copyright (c) 1987 Oliver Laumann
- X * All rights reserved. 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 authors are 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 * Noteworthy contributors to screen's design and implementation:
- X * Wayne Davison (davison@borland.com)
- X * Patrick Wolfe (pat@kai.com, kailand!pat)
- X * Bart Schaefer (schaefer@cse.ogi.edu)
- X * Nathan Glasser (nathan@brokaw.lcs.mit.edu)
- X * Larry W. Virden (lwv27%cas.BITNET@CUNYVM.CUNY.Edu)
- X * Howard Chu (hyc@hanauma.jpl.nasa.gov)
- X * Tim MacKenzie (tym@dibbler.cs.monash.edu.au)
- X * Markku Jarvinen (mta@{cc,cs,ee}.tut.fi)
- X * Marc Boucher (marc@CAM.ORG)
- X *
- X ****************************************************************
- X */
- X
- #ifndef lint
- X static char rcs_id[] = "$Id: ansi.c,v 1.2 92/02/03 02:27:30 jnweiger Exp $ FAU";
- #endif
- X
- #include <stdio.h>
- #include <sys/types.h>
- #ifdef BSDI
- #include <sys/signal.h>
- #endif /* BSDI */
- #include <fcntl.h>
- #include "config.h"
- #include "screen.h"
- #include "ansi.h"
- #include "extern.h"
- #ifndef sun /* we want to know about TIOCGWINSZ. jw. */
- # include <sys/ioctl.h>
- #endif
- X
- extern char *getenv(), *tgetstr(), *tgoto();
- #ifndef __STDC__
- extern char *malloc();
- #endif
- X
- extern struct win *fore;
- extern int ForeNum;
- extern force_vt, assume_LP;
- extern int BellDisplayed;
- extern int MsgMinWait;
- extern int all_norefresh;
- X
- int TermcapROWS, TermcapCOLS; /* defaults that we learned from termcap */
- int default_width, default_height; /* width/height a new window will get */
- X
- int maxwidth;
- X
- int Z0width, Z1width; /* widths for Z0/Z1 switching */
- X
- char display_tty[MAXPATH];
- int screenwidth, screenheight; /* width/height of the screen */
- int screentop, screenbot; /* scrollregion start/end */
- int screenx, screeny; /* cursor position */
- char GlobalAttr; /* current attributes */
- char GlobalCharset; /* current font */
- int insert; /* insert mode */
- int keypad; /* application keypad */
- int flow = 1; /* flow control */
- X
- int status; /* status is displayed */
- static int status_lastx, status_lasty;
- X
- static int rows, cols; /* window size of the curr window */
- X
- int default_flow = -1, wrap = 1, default_monitor = 0;
- int visual_bell = 0, termcapHS, use_hardstatus = 1;
- char *Termcap, *extra_incap, *extra_outcap;
- static int Termcaplen;
- char *blank, *null, *LastMsg;
- char Term[MAXSTR+5]; /* +5: "TERM=" */
- char screenterm[20] = "screen";
- char *Z0, *Z1;
- int ISO2022, HS;
- time_t TimeDisplayed, time();
- X
- /*
- X * the termcap routines need this to work
- X */
- short ospeed;
- char *BC;
- char *UP;
- X
- static void AddCap __P((char *));
- static void MakeString __P((char *, char *, int, char *));
- static int Special __P((int));
- static void DoESC __P((int, int ));
- static void DoCSI __P((int, int ));
- static void CPutStr __P((char *, int));
- static void SetChar __P(());
- static void StartString __P((enum string_t));
- static void AddChar __P((int ));
- static void PrintChar __P((int ));
- static void PrintFlush __P((void));
- static void KeypadMode __P((int));
- static void DesignateCharset __P((int, int ));
- static void MapCharset __P((int));
- static void SaveCursor __P((void));
- static void RestoreCursor __P((void));
- static void CountChars __P((int));
- static int CalcCost __P((char *));
- static int Rewrite __P((int, int, int, int));
- static void BackSpace __P((void));
- static void Return __P((void));
- static void LineFeed __P((int));
- static void ReverseLineFeed __P((void));
- static void InsertAChar __P((int));
- static void InsertChar __P((int));
- static void DeleteChar __P((int));
- static void DeleteLine __P((int));
- static void InsertLine __P((int));
- static void ScrollUpMap __P((int));
- static void ScrollDownMap __P((int));
- static void Scroll __P((char *, int, int, char *));
- static void ForwardTab __P((void));
- static void BackwardTab __P((void));
- static void ClearScreen __P((void));
- static void ClearFromBOS __P((void));
- static void ClearToEOS __P((void));
- static void ClearLine __P((void));
- static void ClearToEOL __P((void));
- static void ClearFromBOL __P((void));
- static void ClearInLine __P((int, int, int, int ));
- static void CursorRight __P(());
- static void CursorUp __P(());
- static void CursorDown __P(());
- static void CursorLeft __P(());
- static void ASetMode __P((int));
- static void SelectRendition __P((void));
- static void FillWithEs __P((void));
- static void RedisplayLine __P((char *, char *, char *, int, int, int ));
- static void FindAKA __P((void));
- static void SetCurr __P((struct win *));
- static void inpRedisplayLine __P((int, int, int, int));
- static void process_inp_input __P((char **, int *));
- static void AbortInp __P((void));
- static void AKAfin __P((char *, int));
- static void Colonfin __P((char *, int));
- static void RAW_PUTCHAR __P((int));
- static char *e_tgetstr __P((char *, char **));
- static int e_tgetflag __P((char *));
- static int e_tgetnum __P((char *));
- X
- X
- static char *tbuf, *tentry, *termname;
- static char *tp;
- static char *TI, *TE, *BL, *VB, *CR, *NL, *CL, *IS;
- char *WS; /* used in ResizeScreen() */
- char *CE; /* used in help.c */
- static char *CM, *US, *UE, *SO, *SE, *CD, *DO, *SR, *SF, *AL;
- static char *CS, *DL, *DC, *IC, *IM, *EI, *ND, *KS, *KE;
- static char *MB, *MD, *MH, *MR, *ME, *PO, *PF, *HO;
- static char *TS, *FS, *DS, *VI, *VE, *VS;
- static char *CDC, *CDL, *CAL, *CUP, *CDO, *CLE, *CRI, *CIC;
- static char *attrtab[NATTR];
- static AM, MS, COP;
- int LP;
- /*
- X * Do not confuse S0 (es-zero), E0 (e-zero) with SO (es-oh), PO (pe-oh),
- X * Z0 (z-zero), DO (de-oh)... :-)
- X */
- static char *C0, *S0, *E0;
- static char c0_tab[256];
- /*
- X */
- static screencap = 0;
- char *OldImage, *OldAttr, *OldFont;
- static struct win *curr;
- static display = 1;
- static StrCost;
- static UPcost, DOcost, LEcost, NDcost, CRcost, IMcost, EIcost, NLcost;
- static tcLineLen;
- static StatLen;
- static lp_missing = 0;
- X
- int in_ovl;
- int ovl_blockfore;
- void (*ovl_process)();
- void (*ovl_RedisplayLine)();
- int (*ovl_Rewrite)();
- X
- static char *KeyCaps[] =
- {
- X "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7", "k8", "k9",
- X "kb", "kd", "kh", "kl", "ko", "kr", "ku",
- X "K1", "K2", "K3", "K4", "K5",
- X "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", "l8", "l9"
- };
- #define NKEYCAPS ((int)(sizeof(KeyCaps)/sizeof(*KeyCaps)))
- static char *KeyCapsArr[NKEYCAPS];
- X
- static char TermcapConst[] = "\\\n\
- \t:DO=\\E[%dB:LE=\\E[%dD:RI=\\E[%dC:UP=\\E[%dA:bs:bt=\\E[Z:\\\n\
- \t:cd=\\E[J:ce=\\E[K:cl=\\E[H\\E[J:cm=\\E[%i%d;%dH:ct=\\E[3g:\\\n\
- \t:do=^J:nd=\\E[C:pt:rc=\\E8:rs=\\Ec:sc=\\E7:st=\\EH:up=\\EM:\\\n\
- \t:le=^H:bl=^G:cr=^M:it#8:ho=\\E[H:nw=\\EE:ta=^I:is=\\E)0:xv:";
- X
- void
- InitTermcap()
- {
- X register char *s;
- X int i;
- X
- X screencap = 0;
- X if ((s = getenv("SCREENCAP")) != 0)
- X {
- X if ((Termcap = malloc(strlen(s) + 10)) != 0)
- X {
- X sprintf(Termcap, "TERMCAP=%s", s);
- X screencap = 1;
- X }
- X }
- X else
- X Termcap = malloc((unsigned) 1024);
- X Termcaplen = 0;
- X tbuf = malloc((unsigned) 1024);
- X tentry = tp = malloc((unsigned) 1024);
- X if (!(Termcap && tbuf && tentry))
- X Msg_nomem;
- X bzero(tbuf, 1024);
- X if ((termname = getenv("TERM")) == 0)
- X Msg(0, "No TERM in environment.");
- X debug1("InitTermcap: looking for tgetent('%s');\n", termname);
- X if (tgetent(tbuf, termname) != 1)
- X Msg(0, "Cannot find termcap entry for %s.", termname);
- X debug1("got it:\n%s\n",tbuf);
- #ifdef DEBUG
- X if (extra_incap)
- X debug1("Extra incap: %s\n", extra_incap);
- X if (extra_outcap)
- X debug1("Extra outcap: %s\n", extra_outcap);
- #endif
- X
- X TermcapCOLS = TermcapROWS = 0;
- X if (s = getenv("COLUMNS"))
- X TermcapCOLS = atoi(s);
- X if (TermcapCOLS <= 0)
- X TermcapCOLS = e_tgetnum("co");
- X if (TermcapCOLS <= 0)
- X TermcapCOLS = 80;
- X if (s = getenv("LINES"))
- X TermcapROWS = atoi(s);
- X if (TermcapROWS <= 0)
- X TermcapROWS = e_tgetnum("li");
- X if (TermcapROWS <= 0)
- X TermcapROWS = 24;
- X
- X if (e_tgetflag("hc"))
- X Msg(0, "You can't run screen on a hardcopy terminal.");
- X if (e_tgetflag("os"))
- X Msg(0, "You can't run screen on a terminal that overstrikes.");
- X if (e_tgetflag("ns"))
- X Msg(0, "Terminal must support scrolling.");
- X if (!(CL = e_tgetstr("cl", &tp)))
- X Msg(0, "Clear screen capability required.");
- X if (!(CM = e_tgetstr("cm", &tp)))
- X Msg(0, "Addressable cursor capability required.");
- X if (default_flow < 0)
- X default_flow = e_tgetflag("NF") ? FLOW_NOW * 0 :
- X e_tgetflag("xo") ? FLOW_NOW * 1 :
- X FLOW_AUTOFLAG;
- X AM = e_tgetflag("am");
- X LP = assume_LP || (!extra_incap && !strncmp(termname, "vt", 2))
- X || !AM || e_tgetflag("LP") || e_tgetflag("xv");
- X COP = e_tgetflag("OP");
- X HO = e_tgetstr("ho", &tp);
- X TI = e_tgetstr("ti", &tp);
- X TE = e_tgetstr("te", &tp);
- X if (!(BL = e_tgetstr("bl", &tp)))
- X BL = "\007";
- X VB = e_tgetstr("vb", &tp);
- X if (!(BC = e_tgetstr("bc", &tp)))
- X {
- X if (e_tgetflag("bs"))
- X BC = "\b";
- X else
- X BC = e_tgetstr("le", &tp);
- X }
- X if (!(CR = e_tgetstr("cr", &tp)))
- X CR = "\r";
- X if (!(NL = e_tgetstr("nl", &tp)))
- X NL = "\n";
- X IS = e_tgetstr("is", &tp);
- X MS = 1;
- X if (e_tgetnum("sg") <= 0 && e_tgetnum("ug") <= 0)
- X {
- X MS = e_tgetflag("ms");
- X attrtab[ATTR_DI] = MH = e_tgetstr("mh", &tp); /* Dim */
- X attrtab[ATTR_US] = US = e_tgetstr("us", &tp); /* Underline */
- X attrtab[ATTR_BD] = MD = e_tgetstr("md", &tp); /* Bold */
- X attrtab[ATTR_RV] = MR = e_tgetstr("mr", &tp); /* Reverse */
- X attrtab[ATTR_SO] = SO = e_tgetstr("so", &tp); /* Standout */
- X attrtab[ATTR_BL] = MB = e_tgetstr("mb", &tp); /* Blinking */
- X ME = e_tgetstr("me", &tp);
- X SE = e_tgetstr("se", &tp);
- X UE = e_tgetstr("ue", &tp);
- X /*
- X * Does ME also reverse the effect of SO and/or US? This is not
- X * clearly specified by the termcap manual. Anyway, we should at
- X * least look whether ME and SE/UE are equal:
- X */
- X if (UE && ((SE && strcmp(SE, UE) == 0) || (ME && strcmp(ME, UE) == 0)))
- X UE = 0;
- X if (SE && (ME && strcmp(ME, SE) == 0))
- X SE = 0;
- X
- X /* Set up missing entries */
- X s = 0;
- X for (i = NATTR-1; i >= 0; i--)
- X if (attrtab[i])
- X s = attrtab[i];
- X for (i = 0; i < NATTR; i++)
- X {
- X if (attrtab[i] == 0)
- X attrtab[i] = s;
- X else
- X s = attrtab[i];
- X }
- X }
- X else
- X {
- X US = UE = SO = SE = MB = MD = MH = MR = ME = 0;
- X for (i = 0; i < NATTR; i++)
- X attrtab[i] = 0;
- X }
- X CE = e_tgetstr("ce", &tp);
- X CD = e_tgetstr("cd", &tp);
- X if (!(DO = e_tgetstr("do", &tp)))
- X DO = NL;
- X UP = e_tgetstr("up", &tp);
- X ND = e_tgetstr("nd", &tp);
- X SR = e_tgetstr("sr", &tp);
- X if (!(SF = e_tgetstr("sf", &tp)))
- X SF = NL;
- X AL = e_tgetstr("al", &tp);
- X DL = e_tgetstr("dl", &tp);
- X CS = e_tgetstr("cs", &tp);
- X DC = e_tgetstr("dc", &tp);
- X IC = e_tgetstr("ic", &tp);
- X CIC = e_tgetstr("IC", &tp);
- X CDC = e_tgetstr("DC", &tp);
- X CDL = e_tgetstr("DL", &tp);
- X CAL = e_tgetstr("AL", &tp);
- X CUP = e_tgetstr("UP", &tp);
- X CDO = e_tgetstr("DO", &tp);
- X CLE = e_tgetstr("LE", &tp);
- X CRI = e_tgetstr("RI", &tp);
- X IM = e_tgetstr("im", &tp);
- X EI = e_tgetstr("ei", &tp);
- X if (e_tgetflag("in"))
- X IC = IM = 0;
- X if (IC && IC[0] == '\0')
- X IC = 0;
- X if (CIC && CIC[0] == '\0')
- X CIC = 0;
- X if (IM && IM[0] == '\0')
- X IM = 0;
- X if (EI && EI[0] == '\0')
- X EI = 0;
- X if (EI == 0)
- X IM = 0;
- X if (IC && IM && strcmp(IC, IM) == 0)
- X IC = 0;
- X KS = e_tgetstr("ks", &tp);
- X KE = e_tgetstr("ke", &tp);
- X if (KE == 0)
- X KS = 0;
- X ISO2022 = e_tgetflag("G0");
- X if (ISO2022)
- X {
- X if ((S0 = e_tgetstr("S0", &tp)) == NULL)
- #ifdef TERMINFO
- X S0 = "\033(%p1%c";
- #else
- X S0 = "\033(%.";
- #endif
- X if ((E0 = e_tgetstr("E0", &tp)) == NULL)
- X E0 = "\033(B";
- X C0 = e_tgetstr("C0", &tp);
- X }
- X else if ((S0 = e_tgetstr("as", &tp)) != NULL
- X && (E0 = e_tgetstr("ae", &tp)) != NULL)
- X {
- X ISO2022 = 1;
- X C0 = e_tgetstr("ac", &tp);
- X }
- X else
- X {
- X S0 = E0 = "";
- X C0 = "g.h.i'j-k-l-m-n+o~p\"q-r-s_t+u+v+w+x|y<z>";
- X }
- X for (i = 0; i < 256; i++)
- X c0_tab[i] = i;
- X if (C0)
- X for (i = strlen(C0)&~1; i >= 0; i-=2)
- X c0_tab[C0[i]] = C0[i+1];
- X debug1("ISO2022 = %d\n", ISO2022);
- X /* WS changes the window size */
- X WS = e_tgetstr("WS", &tp);
- X VI = e_tgetstr("vi", &tp);
- X VE = e_tgetstr("ve", &tp);
- X VS = e_tgetstr("vs", &tp);
- X PO = e_tgetstr("po", &tp);
- X if (!(PF = e_tgetstr("pf", &tp)))
- X PO = 0;
- X debug2("terminal size is %d, %d (says TERMCAP)\n", TermcapCOLS, TermcapROWS);
- X /* Termcap fields Z0 & Z1 contain width-changing sequences. */
- X if ((Z0 = e_tgetstr("Z0", &tp)) != NULL
- X && (Z1 = e_tgetstr("Z1", &tp)) == NULL)
- X Z0 = NULL;
- X
- X Z0width = 132;
- X Z1width = 80;
- X
- X CheckScreenSize(0);
- X if ((HS = e_tgetflag("hs")) != 0)
- X {
- X debug("oy! we have a hardware status line, says termcap\n");
- X TS = e_tgetstr("ts", &tp);
- X FS = e_tgetstr("fs", &tp);
- X DS = e_tgetstr("ds", &tp);
- X if ((HS = e_tgetnum("ws")) <= 0)
- X HS = screenwidth;
- X if (!TS || !FS || !DS)
- X HS = 0;
- X }
- X termcapHS = HS;
- X if (!use_hardstatus)
- X HS = 0;
- X
- X UPcost = CalcCost(UP);
- X DOcost = CalcCost(DO);
- X NLcost = CalcCost(NL);
- X LEcost = CalcCost(BC);
- X NDcost = CalcCost(ND);
- X CRcost = CalcCost(CR);
- X IMcost = CalcCost(IM);
- X EIcost = CalcCost(EI);
- X for (i = 0; i < NKEYCAPS; i++)
- X KeyCapsArr[i] = e_tgetstr(KeyCaps[i], &tp);
- X MakeTermcap(0);
- }
- X
- /*
- X * if the adaptflag is on, we keep the size of this display, else
- X * we may try to restore our old window sizes.
- X */
- void
- InitTerm(adapt)
- int adapt;
- {
- X display = 1;
- X screentop = screenbot = -1;
- X PutStr(IS);
- X PutStr(TI);
- X if (IM && strcmp(IM, EI))
- X PutStr(EI);
- X insert = 0;
- X if (KS && strcmp(KS, KE))
- X PutStr(KE);
- X keypad = 0;
- X PutStr(E0);
- X GlobalCharset = ASCII;
- X ResizeScreen((struct win *)0);
- X ChangeScrollRegion(0, screenheight-1);
- X PutStr(CL);
- X screenx = screeny = 0;
- X fflush(stdout);
- X debug1("we %swant to adapt all our windows to the display\n",
- X (adapt) ? "" : "don't ");
- X /* In case the size was changed by a init sequence */
- X CheckScreenSize((adapt) ? 2 : 0);
- }
- X
- void
- FinitTerm()
- {
- X display = 1;
- X InsertMode(0);
- X KeypadMode(0);
- X ResizeScreen((struct win *)0);
- X ChangeScrollRegion(0, screenheight - 1);
- X SaveSetAttr(0, ASCII);
- X screenx = screeny = -1;
- X GotoPos(0, screenheight - 1);
- X PutStr(TE);
- X fflush(stdout);
- X if (Termcap)
- X {
- X Free(Termcap);
- X debug("FinitTerm: old termcap freed\n");
- X }
- X if (tbuf)
- X {
- X Free(tbuf);
- X debug("FinitTerm: old tbuf freed\n");
- X }
- X if (tentry)
- X {
- X Free(tentry);
- X debug("FinitTerm: old tentry freed\n");
- X }
- }
- X
- static void AddCap(s)
- char *s;
- {
- X register int n;
- X
- X if (tcLineLen + (n = strlen(s)) > 55 && Termcaplen < 1024-4)
- X {
- X strcpy(Termcap + Termcaplen, "\\\n\t:");
- X Termcaplen += 4;
- X tcLineLen = 0;
- X }
- X if (Termcaplen + n < 1024)
- X {
- X strcpy(Termcap + Termcaplen, s);
- X Termcaplen += n;
- X tcLineLen += n;
- X }
- X else
- X Msg(0, "TERMCAP overflow - sorry.");
- }
- X
- char *MakeTermcap(aflag)
- int aflag;
- {
- X char buf[1024];
- X register char *p, *cp, ch;
- X int i;
- X
- X if (screencap)
- X {
- X sprintf(Term, "TERM=screen");
- X return Termcap;
- X }
- X if (screenterm == 0 || *screenterm == '\0')
- X {
- X debug("MakeTermcap sets screenterm=screen\n");
- X strcpy(screenterm, "screen");
- X }
- X for (;;)
- X {
- X sprintf(Term, "TERM=");
- X p = Term + 5;
- X if (!aflag && strlen(screenterm) + strlen(termname) < MAXSTR-1)
- X {
- X sprintf(p, "%s.%s", screenterm, termname);
- X if (tgetent(buf, p) == 1)
- X break;
- X }
- X if (screenwidth >= 132)
- X {
- X sprintf(p, "%s-w", screenterm);
- X if (tgetent(buf, p) == 1)
- X break;
- X }
- X sprintf(p, "%s", screenterm);
- X if (tgetent(buf, p) == 1)
- X break;
- X sprintf(p, "vt100");
- X break;
- X }
- X tcLineLen = 100; /* Force NL */
- X sprintf(Termcap,
- X "TERMCAP=SC|%s|VT 100/ANSI X3.64 virtual terminal|", p);
- X Termcaplen = strlen(Termcap);
- X if (extra_outcap && *extra_outcap)
- X {
- X for (cp = extra_outcap; p = index(cp, ':'); cp = p)
- X {
- X ch = *++p;
- X *p = '\0';
- X AddCap(cp);
- X *p = ch;
- X }
- X tcLineLen = 100; /* Force NL */
- X }
- X if (Termcaplen + strlen(TermcapConst) < 1024)
- X {
- X strcpy(Termcap + Termcaplen, TermcapConst);
- X Termcaplen += strlen(TermcapConst);
- X }
- X sprintf(buf, "li#%d:co#%d:", screenheight, screenwidth);
- X AddCap(buf);
- X if ((force_vt && !COP) || LP || !AM)
- X AddCap("LP:");
- X else
- X AddCap("am:");
- X if (VB)
- X AddCap("vb=\\E[?5h\\E[?5l:");
- X if (US)
- X {
- X AddCap("us=\\E[4m:");
- X AddCap("ue=\\E[24m:");
- X }
- X if (SO)
- X {
- 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[m:ms:");
- X if ((CS && SR) || AL || CAL || aflag)
- X {
- X AddCap("sr=\\EM:");
- X AddCap("al=\\E[L:");
- X AddCap("AL=\\E[%dL:");
- X }
- X else if (SR)
- X AddCap("sr=\\EM:");
- X if (CS || DL || CDL || aflag)
- X {
- X AddCap("dl=\\E[M:");
- X AddCap("DL=\\E[%dM:");
- X }
- X if (CS)
- X AddCap("cs=\\E[%i%d;%dr:");
- X if (DC || CDC || aflag)
- X {
- X AddCap("dc=\\E[P:");
- X AddCap("DC=\\E[%dP:");
- X }
- X if (CIC || IC || IM || aflag)
- X {
- X AddCap("im=\\E[4h:");
- X AddCap("ei=\\E[4l:");
- X AddCap("mi:");
- X AddCap("ic=\\E[@:");
- X AddCap("IC=\\E[%d@:");
- X }
- X if (KS)
- X AddCap("ks=\\E=:");
- X if (KE)
- X AddCap("ke=\\E>:");
- X if (ISO2022)
- X AddCap("G0:");
- X if (PO)
- X {
- X AddCap("po=\\E[5i:");
- X AddCap("pf=\\E[4i:");
- X }
- X if (Z0)
- X {
- X AddCap("Z0=\\E[?3h:");
- X AddCap("Z1=\\E[?3l:");
- X }
- X if (WS)
- X AddCap("WS=\\E[8;%d;%dt:");
- X for (i = 0; i < NKEYCAPS; i++)
- X {
- X if (KeyCapsArr[i] == 0)
- X continue;
- X MakeString(KeyCaps[i], buf, sizeof(buf), KeyCapsArr[i]);
- X AddCap(buf);
- X }
- X return Termcap;
- }
- X
- static void MakeString(cap, buf, buflen, s)
- char *cap, *buf;
- int buflen;
- char *s;
- {
- X register char *p, *pmax;
- X register unsigned int c;
- X
- X p = buf;
- X pmax = p + buflen - (3+4+2);
- X *p++ = *cap++;
- X *p++ = *cap;
- X *p++ = '=';
- X while ((c = *s++) && (p < pmax))
- X {
- X switch (c)
- X {
- X case '\033':
- X *p++ = '\\';
- X *p++ = 'E';
- X break;
- X case ':':
- X sprintf(p, "\\072");
- X p += 4;
- X break;
- X case '^':
- X case '\\':
- X *p++ = '\\';
- X *p++ = c;
- X break;
- X default:
- X if (c >= 200)
- X {
- X sprintf(p, "\\%03o", c & 0377);
- X p += 4;
- X }
- X else if (c < ' ')
- X {
- X *p++ = '^';
- X *p++ = c + '@';
- X }
- X else
- X *p++ = c;
- X }
- X }
- X *p++ = ':';
- X *p = '\0';
- }
- X
- void
- Activate(norefresh)
- int norefresh;
- {
- X debug1("Activate(%d)\n", norefresh);
- X if (display)
- X RemoveStatus();
- X display = fore->active = 1;
- X ResizeScreen(fore);
- X SetCurr(fore);
- X debug3("Fore (%d) has size %dx%d", ForeNum, curr->width, curr->height);
- X debug1("(%d)\n", curr->histheight);
- X ChangeScrollRegion(curr->top, curr->bot);
- X KeypadMode(curr->keypad);
- X SetFlow(curr->flow & FLOW_NOW);
- X if (curr->monitor != MON_OFF)
- X curr->monitor = MON_ON;
- X curr->bell = BELL_OFF;
- X Redisplay(norefresh || all_norefresh);
- }
- X
- void
- ResetScreen(p)
- register struct win *p;
- {
- X register int i;
- X
- X p->wrap = wrap;
- X p->origin = 0;
- X p->insert = 0;
- X p->vbwait = 0;
- X p->keypad = 0;
- X p->top = 0;
- X p->bot = p->height - 1;
- X p->saved = 0;
- X p->LocalAttr = 0;
- X p->x = p->y = 0;
- X p->state = LIT;
- X p->StringType = NONE;
- X p->ss = 0;
- X p->LocalCharset = G0;
- X bzero(p->tabs, p->width);
- X for (i = 8; i < p->width; i += 8)
- X p->tabs[i] = 1;
- X for (i = G0; i <= G3; i++)
- X p->charsets[i] = ASCII;
- }
- X
- void
- WriteString(wp, buf, len)
- struct win *wp;
- char *buf;
- int len;
- {
- X register int c, intermediate = 0;
- X
- X if (!len)
- X return;
- X if (wp->logfp != NULL)
- X if ((int)fwrite(buf, len, 1, wp->logfp) < 1)
- X {
- X extern int errno;
- X
- X Msg(errno, "Error writing logfile");
- X fclose(wp->logfp);
- X wp->logfp = NULL;
- X }
- X /*
- X * SetCurr() here may prevent output, as it may set display = 0
- X */
- X SetCurr(wp);
- X if (display)
- X {
- X if (!HS)
- X RemoveStatus();
- X }
- X else if (curr->monitor == MON_ON)
- X curr->monitor = MON_FOUND;
- X
- X do
- X {
- X c = (unsigned char)*buf++;
- X if (c == '\0' || c == '\177')
- X continue;
- X NextChar:
- X switch (curr->state)
- X {
- X case PRIN:
- X switch (c)
- X {
- X case '\033':
- X curr->state = PRINESC;
- X break;
- X default:
- X PrintChar(c);
- X }
- X break;
- X case PRINESC:
- X switch (c)
- X {
- X case '[':
- X curr->state = PRINCSI;
- X break;
- X default:
- X PrintChar('\033');
- X PrintChar(c);
- X curr->state = PRIN;
- X }
- X break;
- X case PRINCSI:
- X switch (c)
- X {
- X case '4':
- X curr->state = PRIN4;
- X break;
- X default:
- X PrintChar('\033');
- X PrintChar('[');
- X PrintChar(c);
- X curr->state = PRIN;
- X }
- X break;
- X case PRIN4:
- X switch (c)
- X {
- X case 'i':
- X curr->state = LIT;
- X PrintFlush();
- X break;
- X default:
- X PrintChar('\033');
- X PrintChar('[');
- X PrintChar('4');
- X PrintChar(c);
- X curr->state = PRIN;
- X }
- X break;
- X case STRESC:
- X switch (c)
- X {
- X case '\\':
- X curr->state = LIT;
- X *(curr->stringp) = '\0';
- X switch (curr->StringType)
- X {
- X case PM:
- X if (!display)
- X break;
- X MakeStatus(curr->string);
- X if (!HS && status && len > 1)
- X {
- X curr->outlen = len - 1;
- X bcopy(buf, curr->outbuf, curr->outlen);
- X return;
- X }
- X break;
- X case DCS:
- X if (display)
- X printf("%s", curr->string);
- X break;
- X case AKA:
- X if (curr->akapos == 0 && !*curr->string)
- X break;
- X strncpy(curr->cmd + curr->akapos, curr->string, 20);
- X if (!*curr->string)
- X curr->autoaka = curr->y + 1;
- X break;
- X default:
- X break;
- X }
- X break;
- X default:
- X curr->state = ASTR;
- X AddChar('\033');
- X AddChar(c);
- X }
- X break;
- X case ASTR:
- X switch (c)
- X {
- X case '\0':
- X break;
- X case '\033':
- X curr->state = STRESC;
- X break;
- X default:
- X AddChar(c);
- X }
- X break;
- X case ESC:
- X switch (c)
- X {
- X case '[':
- X curr->NumArgs = 0;
- X intermediate = 0;
- X bzero((char *) curr->args, MAXARGS * sizeof(int));
- X curr->state = CSI;
- X break;
- X case ']':
- X StartString(OSC);
- X break;
- X case '_':
- X StartString(APC);
- X break;
- X case 'P':
- X StartString(DCS);
- X break;
- X case '^':
- X StartString(PM);
- X break;
- X case '"':
- X case 'k':
- X StartString(AKA);
- X 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 {
- X DoESC(c, intermediate);
- X curr->state = LIT;
- X }
- X else
- X {
- X curr->state = LIT;
- X goto NextChar;
- X }
- X }
- X break;
- X case CSI:
- X switch (c)
- X {
- X case '0':
- X case '1':
- X case '2':
- X case '3':
- X case '4':
- X case '5':
- X case '6':
- X case '7':
- X case '8':
- X case '9':
- X if (curr->NumArgs < MAXARGS)
- X {
- X curr->args[curr->NumArgs] =
- X 10 * curr->args[curr->NumArgs] + c - '0';
- X }
- X break;
- X case ';':
- X case ':':
- X curr->NumArgs++;
- X break;
- X default:
- X if (Special(c))
- X break;
- X if (c >= '@' && c <= '~')
- X {
- X curr->NumArgs++;
- X DoCSI(c, intermediate);
- X if (curr->state != PRIN)
- X curr->state = LIT;
- X }
- X else if ((c >= ' ' && c <= '/') || (c >= '<' && c <= '?'))
- X intermediate = intermediate ? -1 : c;
- X else
- X {
- X curr->state = LIT;
- X goto NextChar;
- X }
- X }
- X break;
- X case LIT:
- X default:
- X if (!Special(c))
- X {
- X if (c == '\033')
- X {
- X intermediate = 0;
- X curr->state = ESC;
- X if (display && lp_missing && (CIC || IC || IM))
- X {
- X RedisplayLine(blank, null, null, screenbot,
- X cols - 2, cols - 1);
- X GotoPos(curr->x, curr->y);
- X }
- X if (curr->autoaka < 0)
- X curr->autoaka = 0;
- X }
- X else if (c < ' ')
- X break;
- X else
- X {
- X NewRendition(curr->LocalAttr);
- X NewCharset(curr->charsets[(curr->ss) ? curr->ss :
- X curr->LocalCharset]);
- X if (curr->x < cols - 1)
- X {
- X if (curr->insert)
- X InsertAChar(c);
- X else
- X {
- X if (display)
- X PUTCHAR(c);
- X SetChar(c);
- X }
- X curr->x++;
- X }
- X else if (curr->x == cols - 1)
- X {
- X if (curr->wrap && (LP || !force_vt || COP))
- X {
- X if (display)
- X RAW_PUTCHAR(c);
- X SetChar(c);
- X if (AM && !LP)
- X {
- X curr->x = 0; /* terminal auto-wrapped */
- X LineFeed(0);
- X }
- X else
- X curr->x++;
- X }
- X else
- X {
- X if (display)
- X {
- X if (LP || curr->y != screenbot)
- X {
- X RAW_PUTCHAR(c);
- X GotoPos(curr->x, curr->y);
- X }
- X else
- X CheckLP(c);
- X }
- X SetChar(c);
- X if (curr->wrap)
- X curr->x++;
- X }
- X }
- X else
- X {
- X LineFeed(2); /* cr+lf, handle LP */
- X if (curr->insert)
- X InsertAChar(c);
- X else
- X {
- X if (display)
- X PUTCHAR(c);
- X SetChar(c);
- X }
- X curr->x = 1;
- X }
- X if (curr->ss)
- X {
- X NewCharset(curr->charsets[curr->LocalCharset]);
- X curr->ss = 0;
- X }
- X }
- X }
- X }
- X } while (--len);
- X curr->outlen = 0;
- X if (curr->state == PRIN)
- X PrintFlush();
- }
- X
- static int Special(c)
- register int c;
- {
- X switch (c)
- X {
- X case '\b':
- X BackSpace();
- X return 1;
- X case '\r':
- X Return();
- X return 1;
- X case '\n':
- X if (curr->autoaka)
- X FindAKA();
- X LineFeed(1);
- X return 1;
- X case '\007':
- X if (!visual_bell)
- X PutStr(BL);
- X else
- X {
- X if (!VB)
- X curr->bell = BELL_VISUAL;
- X else
- X PutStr(VB);
- X }
- X if (!display)
- X curr->bell = BELL_ON;
- X return 1;
- X case '\t':
- X ForwardTab();
- X return 1;
- X case '\017': /* SI */
- X MapCharset(G0);
- X return 1;
- X case '\016': /* SO */
- X MapCharset(G1);
- X return 1;
- X }
- X return 0;
- }
- X
- static void DoESC(c, intermediate)
- int c, intermediate;
- {
- X switch (intermediate)
- X {
- X case 0:
- X switch (c)
- X {
- X case 'E':
- X LineFeed(2);
- X break;
- X case 'D':
- X LineFeed(1);
- X break;
- X case 'M':
- X ReverseLineFeed();
- X break;
- X case 'H':
- X curr->tabs[curr->x] = 1;
- X break;
- X case 'Z': /* jph: Identify as VT100 */
- X Report(curr, "\033[?%d;%dc", 1, 2);
- X break;
- X case '7':
- X SaveCursor();
- X break;
- X case '8':
- X RestoreCursor();
- X break;
- X case 'c':
- X ClearScreen();
- X ResetScreen(curr);
- X NewRendition(0);
- X NewCharset(ASCII);
- X InsertMode(0);
- X KeypadMode(0);
- X ChangeScrollRegion(0, rows-1);
- X break;
- X case '=':
- X KeypadMode(curr->keypad = 1);
- #if !defined(TIOCPKT) || defined(sgi)
- X NewAutoFlow(curr, 0);
- #endif /* !TIOCPKT || sgi */
- X break;
- X case '>':
- X KeypadMode(curr->keypad = 0);
- #if !defined(TIOCPKT) || defined(sgi)
- X NewAutoFlow(curr, 1);
- #endif /* !TIOCPKT || sgi */
- X break;
- X case 'n': /* LS2 */
- X MapCharset(G2);
- X break;
- X case 'o': /* LS3 */
- X MapCharset(G3);
- X break;
- X case 'N': /* SS2 */
- X if (curr->charsets[curr->LocalCharset] != curr->charsets[G2])
- X curr->ss = G2;
- X else
- X curr->ss = 0;
- X break;
- X case 'O': /* SS3 */
- X if (curr->charsets[curr->LocalCharset] != curr->charsets[G3])
- X curr->ss = G3;
- X else
- X curr->ss = 0;
- X break;
- X }
- X break;
- X case '#':
- X switch (c)
- X {
- X case '8':
- X FillWithEs();
- X break;
- X }
- X break;
- X case '(':
- X DesignateCharset(c, G0);
- X break;
- X case ')':
- X DesignateCharset(c, G1);
- X break;
- X case '*':
- X DesignateCharset(c, G2);
- X break;
- X case '+':
- X DesignateCharset(c, G3);
- X break;
- X }
- }
- X
- static void DoCSI(c, intermediate)
- int c, intermediate;
- {
- X register int i, a1 = curr->args[0], a2 = curr->args[1];
- X
- X if (curr->NumArgs > MAXARGS)
- X curr->NumArgs = MAXARGS;
- X switch (intermediate)
- X {
- X case 0:
- X switch (c)
- X {
- X case 'H':
- X case 'f':
- X if (a1 < 1)
- X a1 = 1;
- X if (curr->origin)
- X a1 += curr->top;
- X if (a1 > rows)
- X a1 = rows;
- X if (a2 < 1)
- X a2 = 1;
- X if (a2 > cols)
- X a2 = cols;
- X GotoPos(--a2, --a1);
- X curr->x = a2;
- X curr->y = a1;
- X if (curr->autoaka)
- X curr->autoaka = a1 + 1;
- X break;
- X case 'J':
- X if (a1 < 0 || a1 > 2)
- X a1 = 0;
- X switch (a1)
- X {
- X case 0:
- X ClearToEOS();
- X break;
- X case 1:
- X ClearFromBOS();
- X break;
- X case 2:
- X ClearScreen();
- X GotoPos(curr->x, curr->y);
- X break;
- X }
- X break;
- X case 'K':
- X if (a1 < 0 || a1 > 2)
- X a1 %= 3;
- X switch (a1)
- X {
- X case 0:
- X ClearToEOL();
- X break;
- X case 1:
- X ClearFromBOL();
- X break;
- X case 2:
- X ClearLine();
- X break;
- X }
- X break;
- X case 'A':
- X CursorUp(a1 ? a1 : 1);
- X break;
- X case 'B':
- X CursorDown(a1 ? a1 : 1);
- X break;
- X case 'C':
- X CursorRight(a1 ? a1 : 1);
- X break;
- X case 'D':
- X CursorLeft(a1 ? a1 : 1);
- X break;
- X case 'm':
- X SelectRendition();
- X break;
- X case 'g':
- X if (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 (!a1)
- X a1 = 1;
- X if (!a2)
- X a2 = rows;
- X if (a1 < 1 || a2 > rows || a1 >= a2)
- X break;
- X curr->top = a1 - 1;
- X curr->bot = a2 - 1;
- X ChangeScrollRegion(curr->top, curr->bot);
- X if (curr->origin)
- X {
- X GotoPos(0, curr->top);
- X curr->y = curr->top;
- X curr->x = 0;
- X }
- X else
- X {
- X GotoPos(0, 0);
- X curr->y = curr->x = 0;
- X }
- X break;
- X case 's':
- X SaveCursor();
- X break;
- X case 't':
- X if (a1 != 8)
- X break;
- X a1 = curr->args[2];
- X if (a1 < 1)
- X a1 = curr->width;
- X if (a2 < 1)
- X a2 = curr->height;
- X if (WS == NULL)
- X {
- X a2 = curr->height;
- X if (Z0 == NULL || (a1 != Z0width && a1 != Z1width))
- X a1 = curr->width;
- X }
- X if (a1 == curr->width && a2 == curr->height)
- X break;
- X ChangeWindowSize(curr, a1, a2);
- X SetCurr(curr);
- X if (display)
- X Activate(0);
- X break;
- X case 'u':
- X RestoreCursor();
- X break;
- X case 'I':
- X if (!a1)
- X a1 = 1;
- X while (a1--)
- X ForwardTab();
- X break;
- X case 'Z':
- X if (!a1)
- X a1 = 1;
- X while (a1--)
- X BackwardTab();
- X break;
- X case 'L':
- X InsertLine(a1 ? a1 : 1);
- X break;
- X case 'M':
- X DeleteLine(a1 ? a1 : 1);
- X break;
- X case 'P':
- X DeleteChar(a1 ? a1 : 1);
- X break;
- X case '@':
- X InsertChar(a1 ? a1 : 1);
- X break;
- X case 'h':
- X ASetMode(1);
- X break;
- X case 'l':
- X ASetMode(0);
- X break;
- X case 'i':
- X if (PO && a1 == 5)
- X {
- X curr->stringp = curr->string;
- X curr->state = PRIN;
- X }
- X break;
- X case 'n':
- X if (a1 == 6) /* Report cursor position */
- X Report(curr, "\033[%d;%dR", curr->y + 1, curr->x + 1);
- X break;
- X case 'c': /* Identify as VT100 */
- X Report(curr, "\033[?%d;%dc", 1, 2);
- X break;
- X }
- X break;
- X case '?':
- X debug2("\\E[?%d%c\n",a1,c);
- X if (c != 'h' && c != 'l')
- X break;
- X i = (c == 'h');
- X switch (a1)
- X {
- X case 3:
- X i = (i ? Z0width : Z1width);
- X if ((Z0 || WS) && curr->width != i)
- X {
- X ChangeWindowSize(curr, i, curr->height);
- X SetCurr(curr);
- X if (display)
- X Activate(0);
- X }
- X break;
- X case 5:
- X if (i)
- X curr->vbwait = 1;
- X else
- X {
- X if (curr->vbwait)
- X PutStr(VB);
- X curr->vbwait = 0;
- X }
- X break;
- X case 6:
- X if ((curr->origin = i) != 0)
- X {
- X GotoPos(0, curr->top);
- X curr->y = curr->top;
- X curr->x = 0;
- X }
- X else
- X {
- X GotoPos(0, 0);
- X curr->y = curr->x = 0;
- X }
- X break;
- X case 7:
- X curr->wrap = i;
- X break;
- X case 35:
- X debug1("Cursor %svisible\n", i?"in":"");
- X curr->cursor_invisible = i;
- X break;
- X }
- X break;
- X }
- }
- X
- void
- INSERTCHAR(c)
- int c;
- {
- X if (!insert && (IC || CIC))
- X {
- X if (IC)
- X PutStr(IC);
- X else
- X CPutStr(CIC, 1);
- X RAW_PUTCHAR(c);
- X return;
- X }
- X InsertMode(1);
- X if (insert)
- X RAW_PUTCHAR(c);
- X else
- X RefreshLine(screeny, screenx, screenwidth-1);
- }
- X
- void
- PUTCHAR(c)
- int c;
- {
- X if (insert)
- X InsertMode(0);
- X RAW_PUTCHAR(c);
- }
- X
- /*
- X * RAW_PUTCHAR() is for all text that will be displayed.
- X * NOTE, that charset Nr. 0 has a conversion table, but c1, c2, ... don't.
- X */
- X
- static void
- RAW_PUTCHAR(c)
- int c;
- {
- X if (GlobalCharset == '0')
- X putchar(c0_tab[c]);
- X else
- X putchar(c);
- X if (screenx < screenwidth - 1)
- X screenx++;
- X else
- X {
- X screenx++;
- X if ((AM && !LP) || screenx > screenwidth)
- X {
- X screenx -= screenwidth;
- X if (screeny < screenheight-1 && screeny != screenbot)
- X screeny++;
- X }
- X }
- }
- X
- void
- PutChar(c)
- int c;
- {
- X /* this PutChar for ESC-sequences only */
- X putchar(c);
- }
- X
- void
- PutStr(s)
- char *s;
- {
- X if (display && s)
- X tputs(s, 1, PutChar);
- }
- X
- static void CPutStr(s, c)
- char *s;
- int c;
- {
- X if (display && s)
- X tputs(tgoto(s, 0, c), 1, PutChar);
- }
- X
- static void SetChar(c)
- register int 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 p->font[p->y][p->x] = p->charsets[p->ss ? p->ss : p->LocalCharset];
- }
- X
- static void StartString(type)
- enum string_t type;
- {
- X curr->StringType = type;
- X curr->stringp = curr->string;
- X curr->state = ASTR;
- }
- X
- static void AddChar(c)
- int c;
- {
- X if (curr->stringp >= curr->string + MAXSTR - 1)
- X curr->state = LIT;
- X else
- X *(curr->stringp)++ = c;
- }
- X
- static void PrintChar(c)
- int c;
- {
- X if (curr->stringp >= curr->string + MAXSTR - 1)
- X PrintFlush();
- X *(curr->stringp)++ = c;
- }
- X
- static void PrintFlush()
- {
- X if (curr->stringp > curr->string)
- X {
- X tputs(PO, 1, PutChar);
- X (void) fflush(stdout);
- X (void) write(1, curr->string, curr->stringp - curr->string);
- X tputs(PF, 1, PutChar);
- X (void) fflush(stdout);
- X curr->stringp = curr->string;
- X }
- }
- X
- /* Insert mode is a toggle on some terminals, so we need this hack:
- X */
- void
- InsertMode(on)
- int on;
- {
- X if (display && on != insert && IM)
- X {
- X insert = on;
- X if (insert)
- X PutStr(IM);
- X else
- X PutStr(EI);
- X }
- }
- X
- /* ...and maybe keypad application mode is a toggle, too:
- X */
- static void KeypadMode(on)
- int on;
- {
- X if (display && keypad != on && KS)
- X {
- X keypad = on;
- X if (keypad)
- X PutStr(KS);
- X else
- X PutStr(KE);
- X }
- }
- X
- void
- NewAutoFlow(win, on)
- struct win *win;
- int on;
- {
- X debug1("NewAutoFlow: %d\n", on);
- X SetCurr(win);
- X if (win->flow & FLOW_AUTOFLAG)
- X win->flow = FLOW_AUTOFLAG | (FLOW_AUTO|FLOW_NOW) * on;
- X else
- X win->flow = (win->flow & ~FLOW_AUTO) | FLOW_AUTO * on;
- X if (display)
- X SetFlow(win->flow & FLOW_NOW);
- }
- X
- static void DesignateCharset(c, n)
- int c, n;
- {
- X curr->ss = 0;
- X if (c == 'B')
- X c = ASCII;
- X if (curr->charsets[n] != c)
- X {
- X curr->charsets[n] = c;
- X if (curr->LocalCharset == n)
- X NewCharset(c);
- X }
- }
- X
- static void MapCharset(n)
- int n;
- {
- X curr->ss = 0;
- X if (curr->LocalCharset != n)
- X {
- X curr->LocalCharset = n;
- X NewCharset(curr->charsets[n]);
- X }
- }
- X
- void
- NewCharset(new)
- int new;
- {
- X if (!display || GlobalCharset == new)
- X return;
- X GlobalCharset = new;
- X if (new == ASCII)
- X PutStr(E0);
- X else
- X CPutStr(S0, new);
- }
- X
- static void SaveCursor()
- {
- X curr->saved = 1;
- X curr->Saved_x = curr->x;
- X curr->Saved_y = curr->y;
- X curr->SavedLocalAttr = curr->LocalAttr;
- X curr->SavedLocalCharset = curr->LocalCharset;
- X bcopy((char *) curr->charsets, (char *) curr->SavedCharsets,
- X 4 * sizeof(int));
- }
- X
- static void RestoreCursor()
- {
- X if (curr->saved)
- X {
- X GotoPos(curr->Saved_x, curr->Saved_y);
- X curr->x = curr->Saved_x;
- X curr->y = curr->Saved_y;
- X curr->LocalAttr = curr->SavedLocalAttr;
- X NewRendition(curr->LocalAttr);
- X bcopy((char *) curr->SavedCharsets, (char *) curr->charsets,
- X 4 * sizeof(int));
- X curr->LocalCharset = curr->SavedLocalCharset;
- X NewCharset(curr->charsets[curr->LocalCharset]);
- X }
- }
- X
- /*ARGSUSED*/
- static void CountChars(c)
- int c;
- {
- X StrCost++;
- }
- X
- static int CalcCost(s)
- register char *s;
- {
- X if (s)
- X {
- X StrCost = 0;
- X tputs(s, 1, CountChars);
- X return StrCost;
- X }
- X else
- X return EXPENSIVE;
- }
- X
- void
- GotoPos(x2, y2)
- int x2, y2;
- {
- X register int dy, dx, x1, y1;
- X register int costx, costy;
- X register int m;
- X register char *s;
- X int CMcost;
- X enum move_t xm = M_NONE, ym = M_NONE;
- X
- X if (!display)
- X return;
- X
- X x1 = screenx;
- X y1 = screeny;
- X
- X if (x1 == screenwidth)
- X if (LP && AM)
- X x1 = -1; /* don't know how the terminal treats this */
- X else
- X x1--;
- X if (x2 == screenwidth)
- X x2--;
- X dx = x2 - x1;
- X dy = y2 - y1;
- X if (dy == 0 && dx == 0)
- X {
- X return;
- X }
- X if (!MS && GlobalAttr) /* Safe to move in SO mode ? */
- X NewRendition(0);
- X if (y1 < 0 /* don't know the y position */
- X || (y2 > screenbot && y1 <= screenbot) /* have to cross border */
- X || (y2 < screentop && y1 >= screentop)) /* of scrollregion ? */
- X {
- X DoCM:
- X if (HO && !x2 && !y2)
- X PutStr(HO);
- X else
- X PutStr(tgoto(CM, x2, y2));
- X screenx = x2;
- X screeny = y2;
- X return;
- X }
- X /* Calculate CMcost */
- X if (HO && !x2 && !y2)
- X s = HO;
- X else
- X s = tgoto(CM, x2, y2);
- X CMcost = CalcCost(s);
- X
- X /* Calculate the cost to move the cursor to the right x position */
- X costx = EXPENSIVE;
- X if (x1 >= 0) /* relativ x positioning only if we know where we are */
- X {
- X if (dx > 0)
- X {
- X if (CRI && (dx > 1 || !ND))
- X {
- X costx = CalcCost(tgoto(CRI, 0, dx));
- X xm = M_CRI;
- X }
- X if ((m = NDcost * dx) < costx)
- X {
- X costx = m;
- X xm = M_RI;
- X }
- X /* Speedup: dx <= Rewrite() */
- X if (dx < costx && (m = Rewrite(y1, x1, x2, 0)) < costx)
- X {
- X costx = m;
- X xm = M_RW;
- X }
- X }
- X else if (dx < 0)
- X {
- X if (CLE && (dx < -1 || !BC))
- X {
- X costx = CalcCost(tgoto(CLE, 0, -dx));
- X xm = M_CLE;
- X }
- X if ((m = -dx * LEcost) < costx)
- X {
- X costx = m;
- X xm = M_LE;
- X }
- X }
- X else
- X costx = 0;
- X }
- X /* Speedup: Rewrite() >= x2 */
- X if (x2 + CRcost < costx && (m = Rewrite(y1, 0, x2, 0) + CRcost) < costx)
- X {
- X costx = m;
- X xm = M_CR;
- X }
- X
- X /* Check if it is already cheaper to do CM */
- X if (costx >= CMcost)
- X goto DoCM;
- X
- X /* Calculate the cost to move the cursor to the right y position */
- X costy = EXPENSIVE;
- X if (dy > 0)
- X {
- X if (CDO && dy > 1) /* DO & NL are always != 0 */
- X {
- X costy = CalcCost(tgoto(CDO, 0, dy));
- X ym = M_CDO;
- X }
- X if ((m = dy * ((x2 == 0) ? NLcost : DOcost)) < costy)
- X {
- X costy = m;
- X ym = M_DO;
- X }
- X }
- X else if (dy < 0)
- X {
- X if (CUP && (dy < -1 || !UP))
- X {
- X costy = CalcCost(tgoto(CUP, 0, -dy));
- X ym = M_CUP;
- X }
- X if ((m = -dy * UPcost) < costy)
- X {
- X costy = m;
- X ym = M_UP;
- X }
- X }
- X else
- X costy = 0;
- X
- X /* Finally check if it is cheaper to do CM */
- X if (costx + costy >= CMcost)
- X goto DoCM;
- X
- X switch (xm)
- X {
- X case M_LE:
- X while (dx++ < 0)
- X PutStr(BC);
- X break;
- X case M_CLE:
- X CPutStr(CLE, -dx);
- X break;
- X case M_RI:
- X while (dx-- > 0)
- X PutStr(ND);
- X break;
- X case M_CRI:
- X CPutStr(CRI, dx);
- X break;
- X case M_CR:
- X PutStr(CR);
- X screenx = 0;
- X x1 = 0;
- X /* FALLTHROUGH */
- X case M_RW:
- X if (x1 < x2)
- X (void) Rewrite(y1, x1, x2, 1);
- X break;
- X default:
- X break;
- X }
- X switch (ym)
- X {
- X case M_UP:
- X while (dy++ < 0)
- X PutStr(UP);
- X break;
- X case M_CUP:
- X CPutStr(CUP, -dy);
- X break;
- X case M_DO:
- X s = (x2 == 0) ? NL : DO;
- X while (dy-- > 0)
- X PutStr(s);
- X break;
- X case M_CDO:
- X CPutStr(CDO, dy);
- X break;
- X default:
- X break;
- X }
- X screenx = x2;
- X screeny = y2;
- }
- X
- static int
- Rewrite(y, x1, x2, doit)
- int y, x1, x2, doit;
- {
- X register int cost, dx;
- X register char *p, *f, *i;
- X
- X if (x1 == x2)
- X return(0);
- X if (in_ovl)
- X {
- X if (ovl_Rewrite == 0)
- X return EXPENSIVE;
- X else
- X return ((*ovl_Rewrite)(y, x1, x2, doit));
- X }
- X dx = x2 - x1;
- X if (doit)
- X {
- X i = curr->image[y] + x1;
- X while (dx-- > 0)
- X PUTCHAR(*i++);
- X return(0);
- X }
- X p = curr->attr[y] + x1;
- X f = curr->font[y] + x1;
- X
- X cost = dx = x2 - x1;
- X if (insert)
- X cost += EIcost + IMcost;
- X while(dx-- > 0)
- X {
- X if (*p++ != GlobalAttr || *f++ != GlobalCharset)
- X return EXPENSIVE;
- X }
- X return cost;
- }
- X
- static void BackSpace()
- {
- X if (curr->x > 0)
- X {
- X curr->x--;
- X }
- X else if (curr->wrap && curr->y > 0)
- X {
- X curr->x = cols - 1;
- X curr->y--;
- X }
- X if (display)
- X GotoPos(curr->x, curr->y);
- }
- X
- static void Return()
- {
- X if (curr->x > 0)
- X {
- X curr->x = 0;
- X if (display)
- X GotoPos(curr->x, curr->y);
- X }
- }
- X
- static void LineFeed(out_mode)
- int out_mode;
- {
- X /* out_mode: 0=no-output lf, 1=lf, 2=cr+lf */
- X if (out_mode == 2)
- X curr->x = 0;
- X if (curr->y != curr->bot) /* Don't scroll */
- X {
- X if (curr->y < rows-1)
- X curr->y++;
- X if (out_mode && display)
- X GotoPos(curr->x, curr->y);
- X return;
- X }
- X ScrollUpMap(1);
- X if (curr->autoaka > 1)
- X curr->autoaka--;
- X if (out_mode && display)
- X {
- X ScrollRegion(curr->top, curr->bot, 1);
- X GotoPos(curr->x, curr->y);
- X }
- }
- X
- static void ReverseLineFeed()
- {
- X if (curr->y == curr->top)
- X {
- X ScrollDownMap(1);
- X if (!display)
- X return;
- X ScrollRegion(curr->top, curr->bot, -1);
- X GotoPos(curr->x, curr->y);
- X }
- X else if (curr->y > 0)
- X CursorUp(1);
- }
- X
- static void InsertAChar(c)
- int c;
- {
- X register int 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->font[y], OldFont, 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 bcopy(curr->font[y] + x, curr->font[y] + x + 1, cols - x - 1);
- X SetChar(c);
- X if (!display)
- X return;
- X if (CIC || IC || IM)
- X {
- X InsertMode(curr->insert);
- X INSERTCHAR(c);
- X if (y == screenbot)
- X lp_missing = 0;
- X }
- X else
- X {
- X RedisplayLine(OldImage, OldAttr, OldFont, y, x, cols - 1);
- X GotoPos(++x, y);
- X }
- }
- X
- static void InsertChar(n)
- int n;
- {
- X register int i, y = curr->y, x = curr->x;
- X
- X if (n <= 0)
- X return;
- X /*
- X * The termcap manual states that only one of IM and IC is
- X * to be defined unless the terminal needs both sequences.
- X * We don't like this because we think that there may be cases
- X * where it is preferable to send IC instead of IM/EI.
- X * The hack is to ignore the IC sequence if we are already
- X * in insert mode, so that programs which follow the termcap
- X * guidelines still work. (I don't believe that there are
- X * terminals which need IC in the insert mode. Why switch to
- X * insert mode if you must send IC before every character ?)
- X */
- X if (curr->insert)
- X return;
- X if (x == cols)
- X --x;
- X bcopy(curr->image[y], OldImage, cols);
- X bcopy(curr->attr[y], OldAttr, cols);
- X bcopy(curr->font[y], OldFont, 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 bcopy(curr->font[y] + x, curr->font[y] + x + n, cols - x - n);
- X ClearInLine(0, y, x, x + n - 1);
- X if (!display)
- X return;
- X if (IC || CIC || IM)
- X {
- X if (y == screenbot)
- X lp_missing = 0;
- X if (!insert)
- X {
- X if (n == 1 && IC)
- X {
- X PutStr(IC);
- X return;
- X }
- X if (CIC)
- X {
- X CPutStr(CIC, n);
- X return;
- X }
- X }
- X InsertMode(1);
- X for (i = n; i--; )
- X INSERTCHAR(' ');
- X GotoPos(x, y);
- X }
- X else
- X {
- X RedisplayLine(OldImage, OldAttr, OldFont, y, x, cols - 1);
- X GotoPos(x, y);
- X }
- }
- X
- static void DeleteChar(n)
- int n;
- {
- X register int i, 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->font[y], OldFont, 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 bcopy(curr->font[y] + x + n, curr->font[y] + x, cols - x - n);
- X ClearInLine(0, y, cols - n, cols - 1);
- X if (!display)
- X return;
- X if (CDC && !(n == 1 && DC))
- X {
- X CPutStr(CDC, n);
- X if (lp_missing && y == screenbot)
- X {
- X FixLP(cols - 1 - n, y);
- X GotoPos(x, y);
- X }
- X }
- X else if (DC)
- X {
- X for (i = n; i; i--)
- X PutStr(DC);
- X if (lp_missing && y == screenbot)
- X {
- X FixLP(cols - 1 - n, y);
- X GotoPos(x, y);
- X }
- X }
- X else
- X {
- X RedisplayLine(OldImage, OldAttr, OldFont, y, x, cols - 1);
- X GotoPos(x, y);
- X }
- }
- X
- static void DeleteLine(n)
- int n;
- {
- X register int old = curr->top;
- X
- X if (curr->y < curr->top || curr->y > curr->bot)
- X return;
- X if (n > curr->bot - curr->y + 1)
- X n = curr->bot - curr->y + 1;
- X curr->top = curr->y;
- X ScrollUpMap(n);
- X curr->top = old;
- X if (!display)
- X return;
- X ScrollRegion(curr->y, curr->bot, n);
- X GotoPos(curr->x, curr->y);
- }
- X
- static void InsertLine(n)
- int n;
- {
- X register int old = curr->top;
- X
- X if (curr->y < curr->top || curr->y > curr->bot)
- X return;
- X if (n > curr->bot - curr->y + 1)
- X n = curr->bot - curr->y + 1;
- X curr->top = curr->y;
- X ScrollDownMap(n);
- X curr->top = old;
- X if (!display)
- X return;
- X ScrollRegion(curr->y, curr->bot, -n);
- X GotoPos(curr->x, curr->y);
- }
- X
- void
- ScrollRegion(ys, ye, n)
- int ys, ye, n;
- {
- X int i;
- X int up;
- X int oldtop, oldbot;
- X int alok, dlok, aldlfaster;
- X int missy = 0;
- X
- X if (n == 0)
- X return;
- X if (ys == 0 && ye == screenheight-1 &&
- X (n >= screenheight || -n >= screenheight))
- X {
- X PutStr(CL);
- X screeny = screenx = 0;
- X lp_missing = 0;
- X return;
- X }
- X
- X if (lp_missing)
- X {
- X if (screenbot>ye || screenbot<ys)
- X missy = screenbot;
- X else
- X {
- X missy = screenbot - n;
- X if (missy>ye || missy<ys)
- X lp_missing = 0;
- X }
- X }
- X
- X up = 1;
- X if (n < 0)
- X {
- X up = 0;
- X n = -n;
- X }
- X if (n >= ye-ys+1)
- X n = ye-ys+1;
- X
- X oldtop = screentop;
- X oldbot = screenbot;
- X if (screenbot != ye)
- X ChangeScrollRegion(ys, ye);
- X alok = (AL || CAL || (ye == screenbot && up));
- X dlok = (DL || CDL || (ye == screenbot && !up));
- X if (screentop != ys && !(alok && dlok))
- X ChangeScrollRegion(ys, ye);
- X
- X if (lp_missing &&
- X (oldbot != screenbot ||
- X (oldbot == screenbot && up && screentop == ys && screenbot == ye)))
- X {
- X /* Can't use FixLP */
- X GotoPos(screenwidth-1, oldbot);
- X SaveSetAttr(curr->attr[missy][screenwidth-1], curr->font[missy][screenwidth-1]);
- X PUTCHAR(curr->image[missy][screenwidth-1]);
- X RestoreAttr();
- X lp_missing = 0;
- X if (oldbot == screenbot) /* have scrolled */
- X {
- X if (--n == 0)
- X {
- X ChangeScrollRegion(oldtop, oldbot);
- X return;
- X }
- X }
- X }
- X
- X aldlfaster = (n > 1 && ye == screenbot && ((up && CDL) || (!up && CAL)));
- X
- X if ((up || SR) && screentop == ys && screenbot == ye && !aldlfaster)
- X {
- X if (up)
- X {
- X GotoPos(0, ye);
- X while (n-- > 0)
- X PutStr(NL); /* was SF, I think NL is faster */
- X }
- X else
- X {
- X GotoPos(0, ys);
- X while (n-- > 0)
- X PutStr(SR);
- X }
- X }
- X else if (alok && dlok)
- X {
- X if (up || ye != screenbot)
- X {
- X GotoPos(0, up ? ys : ye+1-n);
- X if (CDL && !(n == 1 && DL))
- X CPutStr(CDL, n);
- X else
- X for(i=n; i--; )
- X PutStr(DL);
- X }
- X if (!up || ye != screenbot)
- X {
- X GotoPos(0, up ? ye+1-n : ys);
- X if (CAL && !(n == 1 && AL))
- X CPutStr(CAL, n);
- X else
- X for(i=n; i--; )
- X PutStr(AL);
- X }
- X }
- X else
- X {
- X Redisplay(0);
- X return;
- X }
- X if (lp_missing && missy != screenbot)
- X FixLP(screenwidth-1, missy);
- X ChangeScrollRegion(oldtop, oldbot);
- X if (lp_missing && missy != screenbot)
- X FixLP(screenwidth-1, missy);
- }
- X
- static void ScrollUpMap(n)
- int n;
- {
- X char tmp[256 * sizeof(char *)];
- X register int ii, i, cnt1, cnt2;
- X register char **ppi, **ppa, **ppf;
- X
- X i = curr->top + n;
- X cnt1 = n * sizeof(char *);
- X cnt2 = (curr->bot - i + 1) * sizeof(char *);
- X ppi = curr->image + i;
- X ppa = curr->attr + i;
- X ppf = curr->font + i;
- X for(ii = curr->top; ii < i; ii++)
- X AddLineToHist(curr, &curr->image[ii], &curr->attr[ii], &curr->font[ii]);
- X for (i = n; i; --i)
- X {
- X bclear(*--ppi, cols);
- X bzero(*--ppa, cols);
- X bzero(*--ppf, cols);
- X }
- X Scroll((char *) ppi, cnt1, cnt2, tmp);
- X Scroll((char *) ppa, cnt1, cnt2, tmp);
- X Scroll((char *) ppf, cnt1, cnt2, tmp);
- }
- X
- static void ScrollDownMap(n)
- int n;
- {
- X char tmp[256 * sizeof(char *)];
- X register int i, cnt1, cnt2;
- X register char **ppi, **ppa, **ppf;
- X
- X i = curr->top;
- X cnt1 = (curr->bot - i - n + 1) * sizeof(char *);
- X cnt2 = n * sizeof(char *);
- X Scroll((char *) (ppi = curr->image + i), cnt1, cnt2, tmp);
- X Scroll((char *) (ppa = curr->attr + i), cnt1, cnt2, tmp);
- X Scroll((char *) (ppf = curr->font + i), cnt1, cnt2, tmp);
- X for (i = n; i; --i)
- X {
- X bclear(*ppi++, cols);
- X bzero(*ppa++, cols);
- X bzero(*ppf++, cols);
- X }
- }
- X
- static void Scroll(cp, cnt1, cnt2, tmp)
- char *cp, *tmp;
- int cnt1, cnt2;
- {
- X if (!cnt1 || !cnt2)
- X return;
- X if (cnt1 <= cnt2)
- X {
- X bcopy(cp, tmp, cnt1);
- X bcopy(cp + cnt1, cp, cnt2);
- X bcopy(tmp, cp + cnt2, cnt1);
- X }
- X else
- X {
- X bcopy(cp + cnt1, tmp, cnt2);
- X bcopy(cp, cp + cnt2, cnt1);
- X bcopy(tmp, cp, cnt2);
- X }
- }
- X
- static void ForwardTab()
- {
- X register int x = curr->x;
- X
- X if (x == cols)
- X {
- X LineFeed(2);
- X x = 0;
- X }
- X if (curr->tabs[x] && x < cols - 1)
- X x++;
- X while (x < cols - 1 && !curr->tabs[x])
- X x++;
- X GotoPos(x, curr->y);
- X curr->x = x;
- }
- X
- static void BackwardTab()
- {
- X register int x = curr->x;
- X
- X if (curr->tabs[x] && x > 0)
- SHAR_EOF
- true || echo 'restore of screen3.2/ansi.c failed'
- fi
- echo 'End of part 1'
- echo 'File screen3.2/ansi.c is continued in part 2'
- echo 2 > _shar_seq_.tmp
- exit 0
- exit 0 # Just in case...
-