home *** CD-ROM | disk | FTP | other *** search
- From: pgf@cayman.COM (Paul Fox)
- Newsgroups: alt.sources
- Subject: Vile 03/17 - vi feel-alike (multi-window)
- Message-ID: <4522@cayman.COM>
- Date: 7 Jun 91 22:09:16 GMT
-
- #!/bin/sh
- # this is vileshar.03 (part 3 of Vile)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file crypt.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 3; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- echo 'x - continuing file crypt.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'crypt.c' &&
- X * file from one computer should be able to be decrypted
- X * on another computer.
- X *
- X * 3. The encryption had to be inexpensive, both in terms
- X * of speed and space.
- X *
- X * 4. The system needed to be secure against all but the
- X * most determined of attackers.
- X *
- X * For encryption of a block of data, one calls crypt passing
- X * a pointer to the data block and its length. The data block is
- X * encrypted in place, that is, the encrypted output overwrites
- X * the input. Decryption is totally isomorphic, and is performed
- X * in the same manner by the same routine.
- X *
- X * Before using this routine for encrypting data, you are expected
- X * to specify an encryption key. This key is an arbitrary string,
- X * to be supplied by the user. To set the key takes two calls to
- X * crypt(). First, you call
- X *
- X * crypt(NULL, vector)
- X *
- X * This resets all internal control information. Typically (and
- X * specifically in the case on MICRO-emacs) you would use a "vector"
- X * of 0. Other values can be used to customize your editor to be
- X * "incompatable" with the normally distributed version. For
- X * this purpose, the best results will be obtained by avoiding
- X * multiples of 95.
- X *
- X * Then, you "encrypt" your password by calling
- X *
- X * crypt(pass, strlen(pass))
- X *
- X * where "pass" is your password string. Crypt() will destroy
- X * the original copy of the password (it becomes encrypted),
- X * which is good. You do not want someone on a multiuser system
- X * to peruse your memory space and bump into your password.
- X * Still, it is a better idea to erase the password buffer to
- X * defeat memory perusal by a more technical snooper.
- X *
- X * For the interest of cryptologists, at the heart of this
- X * function is a Beaufort Cipher. The cipher alphabet is the
- X * range of printable characters (' ' to '~'), all "control"
- X * and "high-bit" characters are left unaltered.
- X *
- X * The key is a variant autokey, derived from a wieghted sum
- X * of all the previous clear text and cipher text. A counter
- X * is used as salt to obiterate any simple cyclic behavior
- X * from the clear text, and key feedback is used to assure
- X * that the entire message is based on the original key,
- X * preventing attacks on the last part of the message as if
- X * it were a pure autokey system.
- X *
- X * Overall security of encrypted data depends upon three
- X * factors: the fundamental cryptographic system must be
- X * difficult to compromise; exhaustive searching of the key
- X * space must be computationally expensive; keys and plaintext
- X * must remain out of sight. This system satisfies this set
- X * of conditions to within the degree desired for MicroEMACS.
- X *
- X * Though direct methods of attack (against systems such as
- X * this) do exist, they are not well known and will consume
- X * considerable amounts of computing time. An exhaustive
- X * search requires over a billion investigations, on average.
- X *
- X * The choice, entry, storage, manipulation, alteration,
- X * protection and security of the keys themselves are the
- X * responsiblity of the user.
- X *
- X **********/
- X
- crypt(bptr, len)
- register char *bptr; /* buffer of characters to be encrypted */
- register int len; /* number of characters in the buffer */
- {
- X register int cc; /* current character being considered */
- X
- X static long key = 0; /* 29 bit encipherment key */
- X static int salt = 0; /* salt to spice up key with */
- X
- X if (!bptr) { /* is there anything here to encrypt? */
- X key = len; /* set the new key */
- X salt = len; /* set the new salt */
- X return;
- X }
- X while (len--) { /* for every character in the buffer */
- X
- X cc = *bptr; /* get a character out of the buffer */
- X
- X /* only encipher printable characters */
- X if ((cc >= ' ') && (cc <= '~')) {
- X
- /** If the upper bit (bit 29) is set, feed it back into the key. This
- X assures us that the starting key affects the entire message. **/
- X
- X key &= 0x1FFFFFFFL; /* strip off overflow */
- X if (key & 0x10000000L) {
- X key ^= 0x0040A001L; /* feedback */
- X }
- X
- /** Down-bias the character, perform a Beaufort encipherment, and
- X up-bias the character again. We want key to be positive
- X so that the left shift here will be more portable and the
- X mod95() faster **/
- X
- X cc = mod95((int)(key % 95) - (cc - ' ')) + ' ';
- X
- /** the salt will spice up the key a little bit, helping to obscure
- X any patterns in the clear text, particularly when all the
- X characters (or long sequences of them) are the same. We do
- X not want the salt to go negative, or it will affect the key
- X too radically. It is always a good idea to chop off cyclics
- X to prime values. **/
- X
- X if (++salt >= 20857) { /* prime modulus */
- X salt = 0;
- X }
- X
- /** our autokey (a special case of the running key) is being
- X generated by a wieghted checksum of clear text, cipher
- X text, and salt. **/
- X
- X key = key + key + cc + *bptr + salt;
- X }
- X *bptr++ = cc; /* put character back into buffer */
- X }
- X return;
- }
- X
- static int mod95(val)
- X
- register int val;
- X
- {
- X /* The mathematical MOD does not match the computer MOD */
- X
- X /* Yes, what I do here may look strange, but it gets the
- X job done, and portably at that. */
- X
- X while (val >= 9500)
- X val -= 9500;
- X while (val >= 950)
- X val -= 950;
- X while (val >= 95)
- X val -= 95;
- X while (val < 0)
- X val += 95;
- X return (val);
- }
- #else
- nocrypt()
- {
- }
- #endif
- SHAR_EOF
- echo 'File crypt.c is complete' &&
- chmod 0444 crypt.c ||
- echo 'restore of crypt.c failed'
- Wc_c="`wc -c < 'crypt.c'`"
- test 6989 -eq "$Wc_c" ||
- echo 'crypt.c: original size 6989, current size' "$Wc_c"
- # ============= csrch.c ==============
- echo 'x - extracting csrch.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'csrch.c' &&
- X
- #include "estruct.h"
- #include "edef.h"
- X
- /* These functions perform vi's on-this-line character scanning functions.
- X written for vile by Paul Fox, (c)1990
- */
- static short lastscan;
- static short lastchar;
- #define BACK 0
- #define FORW 1
- #define DIREC 1
- X
- #define F 0
- #define T 2
- #define TYPE 2
- X
- X
- fscan(f,n,c)
- {
- X int i = 0;
- X int doto;
- X
- X if (n <= 0) n = 1;
- X
- X lastchar = c;
- X lastscan = FORW;
- X
- X doto = curwp->w_doto;
- X
- X i = doto+1;
- X while(i < llength(curwp->w_dotp)) {
- X if ( c == lgetc(curwp->w_dotp,i)) {
- X doto = i;
- X n--;
- X if (!n) break;
- X }
- X i++;
- X }
- X
- X if ( i == llength(curwp->w_dotp)) {
- X TTbeep();
- X return(FALSE);
- X }
- X if (doingopcmd)
- X doto++;
- X
- X curwp->w_doto = doto;
- X curwp->w_flag |= WFMOVE;
- X return(TRUE);
- X
- }
- X
- bscan(f,n,c)
- {
- X int i = 0;
- X int doto;
- X
- X if (n <= 0) n = 1;
- X
- X lastchar = c;
- X lastscan = BACK;
- X
- X doto = curwp->w_doto;
- X
- X i = doto-1;
- X while(i >= 0) {
- X if ( c == lgetc(curwp->w_dotp,i)) {
- X doto = i;
- X n--;
- X if (!n) break;
- X }
- X i--;
- X }
- X
- X if ( i < 0 ) {
- X TTbeep();
- X return(FALSE);
- X }
- X
- X curwp->w_doto = doto;
- X curwp->w_flag |= WFMOVE;
- X return(TRUE);
- X
- }
- X
- /* f */
- fcsrch(f,n)
- {
- X register int c;
- X
- X c = kbd_key();
- X if (c == quotec)
- X c = tgetc();
- X else if (c == abortc)
- X return FALSE;
- X else
- X c = kcod2key(c);
- X
- X return(fscan(f,n,c));
- }
- X
- /* F */
- bcsrch(f,n)
- {
- X register int c;
- X
- X c = kbd_key();
- X if (c == quotec)
- X c = tgetc();
- X else if (c == abortc)
- X return FALSE;
- X else
- X c = kcod2key(c);
- X
- X return(bscan(f,n,c));
- }
- X
- /* t */
- fcsrch_to(f,n)
- {
- X int s;
- X s = fcsrch(f,n);
- X if (s == TRUE)
- X s = backchar(FALSE,1);
- X lastscan |= T;
- X return(s);
- }
- X
- /* T */
- bcsrch_to(f,n)
- {
- X int s;
- X s = bcsrch(f,n);
- X if (s == TRUE)
- X s = forwchar(FALSE,1);
- X lastscan |= T;
- X return(s);
- }
- X
- /* ; */
- rep_csrch(f,n)
- {
- X int s;
- X int ls = lastscan;
- X
- X if ((ls & DIREC) == FORW) {
- X s = fscan(f,n,lastchar);
- X if ((ls & TYPE) == T) {
- X if (s == TRUE)
- X s = backchar(FALSE,1);
- X lastscan |= T;
- X }
- X return(s);
- X } else {
- X s = bscan(f,n,lastchar);
- X if ((ls & TYPE) == T) {
- X if (s == TRUE)
- X s = forwchar(FALSE,1);
- X lastscan |= T;
- X }
- X return(s);
- X }
- }
- X
- /* , */
- rev_csrch(f,n)
- {
- X int s;
- X
- X lastscan ^= DIREC;
- X s = rep_csrch(f,n);
- X lastscan ^= DIREC;
- X return(s);
- }
- SHAR_EOF
- chmod 0444 csrch.c ||
- echo 'restore of csrch.c failed'
- Wc_c="`wc -c < 'csrch.c'`"
- test 2171 -eq "$Wc_c" ||
- echo 'csrch.c: original size 2171, current size' "$Wc_c"
- # ============= dg10.c ==============
- echo 'x - extracting dg10.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'dg10.c' &&
- /*
- X * The routines in this file provide support for the Data General Model 10
- X * Microcomputer.
- X */
- X
- #define termdef 1 /* don't define "term" external */
- X
- #include <stdio.h>
- #include "estruct.h"
- #include "edef.h"
- X
- #if DG10
- X
- #define NROW 24 /* Screen size. */
- #define NCOL 80 /* Edit if you want to. */
- #define NPAUSE 100 /* # times thru update to pause */
- #define MARGIN 8 /* size of minimim margin and */
- #define SCRSIZ 64 /* scroll size for extended lines */
- #define BEL 0x07 /* BEL character. */
- #define ESC 30 /* DG10 ESC character. */
- X
- extern int ttopen(); /* Forward references. */
- extern int ttgetc();
- extern int ttputc();
- extern int ttflush();
- extern int ttclose();
- extern int dg10kopen();
- extern int dg10kclose();
- extern int dg10move();
- extern int dg10eeol();
- extern int dg10eeop();
- extern int dg10beep();
- extern int dg10open();
- extern int dg10rev();
- extern int dg10close();
- extern int dg10cres();
- X
- #if COLOR
- extern int dg10fcol();
- extern int dg10bcol();
- X
- int cfcolor = -1; /* current forground color */
- int cbcolor = -1; /* current background color */
- int ctrans[] = { /* emacs -> DG10 color translation table */
- X 0, 4, 2, 6, 1, 5, 3, 7};
- #endif
- X
- /*
- X * Standard terminal interface dispatch table. Most of the fields point into
- X * "termio" code.
- X */
- TERM term = {
- X NROW-1,
- X NROW-1,
- X NCOL,
- X NCOL,
- X MARGIN,
- X SCRSIZ,
- X NPAUSE,
- X dg10open,
- X dg10close,
- X dg10kopen,
- X dg10kclose,
- X ttgetc,
- X ttputc,
- X ttflush,
- X dg10move,
- X dg10eeol,
- X dg10eeop,
- X dg10beep,
- X dg10rev,
- X dg10cres
- #if COLOR
- X , dg10fcol,
- X dg10bcol
- #endif
- };
- X
- #if COLOR
- dg10fcol(color) /* set the current output color */
- X
- int color; /* color to set */
- X
- {
- X if (color == cfcolor)
- X return;
- X ttputc(ESC);
- X ttputc(0101);
- X ttputc(ctrans[color]);
- X cfcolor = color;
- }
- X
- dg10bcol(color) /* set the current background color */
- X
- int color; /* color to set */
- X
- {
- X if (color == cbcolor)
- X return;
- X ttputc(ESC);
- X ttputc(0102);
- X ttputc(ctrans[color]);
- X cbcolor = color;
- }
- #endif
- X
- dg10move(row, col)
- {
- X ttputc(16);
- X ttputc(col);
- X ttputc(row);
- }
- X
- dg10eeol()
- {
- X ttputc(11);
- }
- X
- dg10eeop()
- {
- #if COLOR
- X dg10fcol(gfcolor);
- X dg10bcol(gbcolor);
- #endif
- X ttputc(ESC);
- X ttputc(0106);
- X ttputc(0106);
- }
- X
- dg10rev(state) /* change reverse video state */
- X
- int state; /* TRUE = reverse, FALSE = normal */
- X
- {
- #if COLOR
- X if (state == TRUE) {
- X dg10fcol(0);
- X dg10bcol(7);
- X }
- #else
- X ttputc(ESC);
- X ttputc(state ? 0104: 0105);
- #endif
- }
- X
- dg10cres() /* change screen resolution */
- X
- {
- X return(TRUE);
- }
- X
- spal() /* change palette string */
- X
- {
- X /* Does nothing here */
- }
- X
- dg10beep()
- {
- X ttputc(BEL);
- X ttflush();
- }
- X
- dg10open()
- {
- X strcpy(sres, "NORMAL");
- X revexist = TRUE;
- X ttopen();
- }
- X
- dg10close()
- X
- {
- #if COLOR
- X dg10fcol(7);
- X dg10bcol(0);
- #endif
- X ttclose();
- }
- X
- dg10kopen()
- X
- {
- }
- X
- dg10kclose()
- X
- {
- }
- X
- #if FLABEL
- fnclabel(f, n) /* label a function key */
- X
- int f,n; /* default flag, numeric argument [unused] */
- X
- {
- X /* on machines with no function keys...don't bother */
- X return(TRUE);
- }
- #endif
- #else
- dg10hello()
- {
- }
- #endif
- SHAR_EOF
- chmod 0444 dg10.c ||
- echo 'restore of dg10.c failed'
- Wc_c="`wc -c < 'dg10.c'`"
- test 3333 -eq "$Wc_c" ||
- echo 'dg10.c: original size 3333, current size' "$Wc_c"
- # ============= display.c ==============
- echo 'x - extracting display.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'display.c' &&
- /*
- X * The functions in this file handle redisplay. There are two halves, the
- X * ones that update the virtual display screen, and the ones that make the
- X * physical display screen the same as the virtual display screen. These
- X * functions use hints that are left in the windows by the commands.
- X *
- X */
- X
- X
- #include <stdio.h>
- #include <varargs.h>
- #include "estruct.h"
- #include "edef.h"
- #if UNIX
- #include <signal.h>
- #include <termio.h>
- #if ODT
- #include <sys/types.h>
- #include <sys/stream.h>
- #include <sys/ptem.h>
- #endif
- #endif
- X
- typedef struct VIDEO {
- X int v_flag; /* Flags */
- #if COLOR
- X int v_fcolor; /* current forground color */
- X int v_bcolor; /* current background color */
- X int v_rfcolor; /* requested forground color */
- X int v_rbcolor; /* requested background color */
- #endif
- X /* allocate 4 bytes here, and malloc 4 bytes less than we need,
- X to keep malloc from rounding up. */
- X char v_text[4]; /* Screen data. */
- } VIDEO;
- X
- #define VFCHG 0x0001 /* Changed flag */
- #define VFEXT 0x0002 /* extended (beyond column 80) */
- #define VFREV 0x0004 /* reverse video status */
- #define VFREQ 0x0008 /* reverse video request */
- #define VFCOL 0x0010 /* color change requested */
- X
- VIDEO **vscreen; /* Virtual screen. */
- #if ! MEMMAP
- VIDEO **pscreen; /* Physical screen. */
- #endif
- X
- X
- int displaying = FALSE;
- #ifdef SIGWINCH
- /* for window size changes */
- int chg_width, chg_height;
- #endif
- X
- /*
- X * Initialize the data structures used by the display code. The edge vectors
- X * used to access the screens are set up. The operating system's terminal I/O
- X * channel is set up. All the other things get initialized at compile time.
- X * The original window has "WFCHG" set, so that it will get completely
- X * redrawn on the first call to "update".
- X */
- vtinit()
- {
- X register int i;
- X register VIDEO *vp;
- X
- X TTopen(); /* open the screen */
- X TTkopen(); /* open the keyboard */
- X TTrev(FALSE);
- X vscreen = (VIDEO **) malloc(term.t_mrow*sizeof(VIDEO *));
- X
- X if (vscreen == NULL)
- X exit(1);
- X
- #if ! MEMMAP
- X pscreen = (VIDEO **) malloc(term.t_mrow*sizeof(VIDEO *));
- X
- X if (pscreen == NULL)
- X exit(1);
- #endif
- X
- X for (i = 0; i < term.t_mrow; ++i) {
- X /* struct VIDEO already has 4 of the bytes */
- X vp = (VIDEO *) malloc(sizeof(struct VIDEO) + term.t_mcol - 4);
- X
- X if (vp == NULL)
- X exit(1);
- X
- X vp->v_flag = 0;
- #if COLOR
- X vp->v_rfcolor = 7;
- X vp->v_rbcolor = 0;
- #endif
- X vscreen[i] = vp;
- #if ! MEMMAP
- X /* struct VIDEO already has 4 of the bytes */
- X vp = (VIDEO *) malloc(sizeof(struct VIDEO) + term.t_mcol - 4);
- X
- X if (vp == NULL)
- X exit(1);
- X
- X vp->v_flag = 0;
- X pscreen[i] = vp;
- #endif
- X }
- }
- X
- /*
- X * Clean up the virtual terminal system, in anticipation for a return to the
- X * operating system. Move down to the last line and advance, to make room
- X * for the system prompt. Shut down the channel to the
- X * terminal.
- X */
- vttidy(f)
- {
- X ttclean(f); /* does it all now */
- }
- X
- /*
- X * Set the virtual cursor to the specified row and column on the virtual
- X * screen. There is no checking for nonsense values.
- X */
- vtmove(row, col)
- {
- X vtrow = row;
- X vtcol = col;
- }
- X
- /* Write a character to the virtual screen. The virtual row and
- X column are updated. If we are not yet on left edge, don't print
- X it yet. If the line is too long put a ">" in the last column.
- X This routine only puts printing characters into the virtual
- X terminal buffers. Only column overflow is checked.
- */
- X
- vtputc(c,list)
- int c,list;
- {
- X register VIDEO *vp; /* ptr to line being updated */
- X
- X vp = vscreen[vtrow];
- X
- X if (c == '\t' && !list) {
- X do {
- X vtputc(' ',FALSE);
- X } while (((vtcol + taboff)&TABMASK) != 0);
- X } else if (c == '\n' && !list) {
- X return;
- X } else if (vtcol >= term.t_ncol) {
- X ++vtcol;
- X vp->v_text[term.t_ncol - 1] = '>';
- X } else if (!isprint(c)) {
- X vtputc('^',FALSE);
- X vtputc(toalpha(c),FALSE);
- X } else {
- X if (vtcol >= 0)
- X vp->v_text[vtcol] = c;
- X ++vtcol;
- X }
- }
- X
- vtgetc(col)
- {
- X return vscreen[vtrow]->v_text[col];
- }
- X
- vtputsn(s,n)
- char *s;
- {
- X int c;
- X while (n-- && (c = *s++) != 0)
- X vtputc(c,FALSE);
- }
- X
- /*
- X * Erase from the end of the software cursor to the end of the line on which
- X * the software cursor is located.
- X */
- vteeol()
- {
- X while (vtcol < term.t_ncol)
- X vtputc(' ',FALSE);
- }
- X
- /* upscreen: user routine to force a screen update
- X always finishes complete update */
- upscreen(f, n)
- {
- X update(TRUE);
- X return(TRUE);
- }
- X
- int scrflags;
- /*
- X * Make sure that the display is right. This is a three part process. First,
- X * scan through all of the windows looking for dirty ones. Check the framing,
- X * and refresh the screen. Second, make sure that "currow" and "curcol" are
- X * correct for the current window. Third, make the virtual and physical
- X * screens the same.
- X */
- update(force)
- int force; /* force update past type ahead? */
- {
- X register WINDOW *wp;
- X int screencol;
- X
- #if TYPEAH
- X if (force == FALSE && typahead())
- X return(SORTOFTRUE);
- #endif
- #if VISMAC == 0
- X if (force == FALSE && (kbdmode == PLAY || dotcmdmode == PLAY))
- X return(TRUE);
- #endif
- X
- X displaying = TRUE;
- X
- X /* first, propagate mode line changes to all instances of
- X a buffer displayed in more than one window */
- X wp = wheadp;
- X while (wp != NULL) {
- X if (wp->w_flag & WFMODE) {
- X if (wp->w_bufp->b_nwnd > 1) {
- X /* make sure all previous windows have this */
- X register WINDOW *owp;
- X owp = wheadp;
- X while (owp != NULL) {
- X if (owp->w_bufp == wp->w_bufp)
- X owp->w_flag |= WFMODE;
- X owp = owp->w_wndp;
- X }
- X }
- X }
- X wp = wp->w_wndp;
- X }
- X
- X /* update any windows that need refreshing */
- X wp = wheadp;
- X while (wp != NULL) {
- X if (wp->w_flag) {
- X /* if the window has changed, service it */
- X reframe(wp); /* check the framing */
- X if (wp->w_flag & (WFKILLS|WFINS)) {
- X scrflags |= (wp->w_flag & (WFINS|WFKILLS));
- X wp->w_flag &= ~(WFKILLS|WFINS);
- X }
- X if ((wp->w_flag & ~(/* WFMOVE| */WFMODE)) == WFEDIT)
- X updone(wp); /* update EDITed line */
- X else if (wp->w_flag & ~(WFMOVE))
- X updall(wp); /* update all lines */
- X if (scrflags || (wp->w_flag & WFMODE))
- X modeline(wp); /* update modeline */
- X wp->w_flag = 0;
- X wp->w_force = 0;
- X }
- X /* on to the next window */
- X wp = wp->w_wndp;
- X }
- X
- X /* recalc the current hardware cursor location */
- X screencol = updpos();
- X
- #if MEMMAP
- X /* update the cursor and flush the buffers */
- X movecursor(currow, screencol);
- #endif
- X
- X /* check for lines to de-extend */
- X upddex();
- X
- #if NeWS
- X newsupd(force) ;
- #else
- X /* if screen is garbage, re-plot it */
- X if (sgarbf)
- X updgar();
- X
- X /* update the virtual screen to the physical screen */
- X updupd(force);
- #endif
- X
- X /* update the cursor and flush the buffers */
- X movecursor(currow, screencol);
- X TTflush();
- X displaying = FALSE;
- #if SIGWINCH
- X while (chg_width || chg_height)
- X newscreensize(chg_height,chg_width);
- #endif
- X return(TRUE);
- }
- X
- /* reframe: check to see if the cursor is on in the window
- X and re-frame it if needed or wanted */
- reframe(wp)
- WINDOW *wp;
- {
- X register LINE *lp;
- X register int i;
- X
- X /* if not a requested reframe, check for a needed one */
- X if ((wp->w_flag & WFFORCE) == 0) {
- #if SCROLLCODE
- X /* loop from one line above the window to one line after */
- X lp = lback(wp->w_linep);
- X for (i = -1; i <= wp->w_ntrows; i++)
- #else
- X /* loop through the window */
- X lp = wp->w_linep;
- X for (i = 0; i < wp->w_ntrows; i++)
- #endif
- X {
- X
- X /* if the line is in the window, no reframe */
- X if (lp == wp->w_dotp) {
- #if SCROLLCODE
- X /* if not _quite_ in, we'll reframe gently */
- X if ( i < 0 || i == wp->w_ntrows) {
- X /* if the terminal can't help, then
- X we're simply outside */
- X if (term.t_scroll == NULL)
- X i = wp->w_force;
- X break;
- X }
- #endif
- X return(TRUE);
- X }
- X
- X /* if we are at the end of the file, reframe */
- X if (i >= 0 && lp == wp->w_bufp->b_linep)
- X break;
- X
- X /* on to the next line */
- X lp = lforw(lp);
- X }
- X }
- X
- #if SCROLLCODE
- X if (i == -1) { /* we're just above the window */
- X i = 1; /* put dot at first line */
- X scrflags |= WFINS;
- X } else if (i == wp->w_ntrows) { /* we're just below the window */
- X i = -1; /* put dot at last line */
- X scrflags |= WFKILLS;
- X } else /* put dot where requested */
- #endif
- X i = wp->w_force; /* (is 0, unless reposition() was called) */
- X
- X wp->w_flag |= WFMODE;
- X
- X /* w_force specifies which line of the window dot should end up on */
- X /* positive --> lines from the top */
- X /* negative --> lines from the bottom */
- X /* zero --> middle of window */
- X
- X /* enforce some maximums */
- X if (i > 0) {
- X if (--i >= wp->w_ntrows)
- X i = wp->w_ntrows - 1;
- X } else if (i < 0) { /* negative update???? */
- X i += wp->w_ntrows;
- X if (i < 0)
- X i = 0;
- X } else
- X i = wp->w_ntrows / 2;
- X
- X /* backup to new line at top of window */
- X lp = wp->w_dotp;
- X while (i != 0 && lback(lp) != wp->w_bufp->b_linep) {
- X --i;
- X lp = lback(lp);
- X }
- X
- X if (lp == wp->w_bufp->b_linep)
- X lp = lback(lp);
- X
- X /* and reset the current line-at-top-of-window */
- X wp->w_linep = lp;
- X wp->w_flag |= WFHARD;
- X wp->w_flag &= ~WFFORCE;
- X return(TRUE);
- }
- X
- /* updone: update the current line to the virtual screen */
- X
- updone(wp)
- WINDOW *wp; /* window to update current line in */
- {
- X register LINE *lp; /* line to update */
- X register int sline; /* physical screen line to update */
- X
- X /* search down the line we want */
- X lp = wp->w_linep;
- X sline = wp->w_toprow;
- X while (lp != wp->w_dotp) {
- X ++sline;
- X lp = lforw(lp);
- X }
- X
- X l_to_vline(wp,lp,sline);
- X vteeol();
- }
- X
- /* updall: update all the lines in a window on the virtual screen */
- X
- updall(wp)
- WINDOW *wp; /* window to update lines in */
- {
- X register LINE *lp; /* line to update */
- X register int sline; /* physical screen line to update */
- X
- X /* search down the lines, updating them */
- X lp = wp->w_linep;
- X sline = wp->w_toprow;
- X while (sline < wp->w_toprow + wp->w_ntrows) {
- X l_to_vline(wp,lp,sline);
- X vteeol();
- X if (lp != wp->w_bufp->b_linep)
- X lp = lforw(lp);
- X ++sline;
- X }
- X
- }
- X
- /* line to virtual screen line */
- l_to_vline(wp,lp,sline)
- WINDOW *wp; /* window to update lines in */
- LINE *lp;
- {
- X int i,c;
- X
- X /* and update the virtual line */
- X vscreen[sline]->v_flag |= VFCHG;
- X vscreen[sline]->v_flag &= ~VFREQ;
- X if (wp->w_sideways)
- X taboff = wp->w_sideways;
- X if (lp != wp->w_bufp->b_linep) {
- X vtmove(sline, -wp->w_sideways);
- X i = 0;
- X while ( i < llength(lp) ) {
- X vtputc(lgetc(lp, i), wp->w_bufp->b_mode & MDLIST);
- X ++i;
- X }
- X vtputc('\n', wp->w_bufp->b_mode & MDLIST);
- X if (wp->w_sideways) {
- X vscreen[sline]->v_text[0] = '<';
- X if (vtcol < 1) vtcol = 1;
- X }
- X } else {
- X vtmove(sline, 0);
- X vtputc('~',FALSE);
- X }
- X taboff = 0;
- #if COLOR
- X vscreen[sline]->v_rfcolor = wp->w_fcolor;
- X vscreen[sline]->v_rbcolor = wp->w_bcolor;
- #endif
- }
- X
- /* updpos: update the position of the hardware cursor and handle extended
- X lines. This is the only update for simple moves.
- X returns the screen column for the cursor */
- updpos()
- {
- X register LINE *lp;
- X register int c;
- X register int i;
- X
- X /* find the current row */
- X lp = curwp->w_linep;
- X currow = curwp->w_toprow;
- X while (lp != curwp->w_dotp) {
- X ++currow;
- X lp = lforw(lp);
- X if (lp == curwp->w_linep) {
- X mlwrite("Bug: lost dot updpos(). setting at top");
- X curwp->w_linep = curwp->w_dotp = lforw(curbp->b_linep);
- X currow = curwp->w_toprow;
- X }
- X }
- X
- X /* find the current column */
- X curcol = -curwp->w_sideways;
- X i = 0;
- X while (i < curwp->w_doto) {
- X c = lgetc(lp, i++);
- X if (((curwp->w_bufp->b_mode&MDLIST) == 0) && c == '\t') {
- X do {
- X curcol++;
- X } while (((curcol + curwp->w_sideways)&TABMASK) != 0);
- X } else {
- X if (!isprint(c))
- X ++curcol;
- X ++curcol;
- X }
- X
- X }
- X
- X /* if extended, flag so and update the virtual line image */
- X if (curcol >= term.t_ncol - 1) {
- X return updext_past();
- X } else if (curwp->w_sideways && curcol < 1){
- X return updext_before();
- X } else {
- X return curcol;
- X }
- }
- X
- /* upddex: de-extend any line that deserves it */
- X
- upddex()
- {
- X register WINDOW *wp;
- X register LINE *lp;
- X register int i,j;
- X
- X wp = wheadp;
- X
- X while (wp != NULL) {
- X lp = wp->w_linep;
- X i = wp->w_toprow;
- X
- X while (i < wp->w_toprow + wp->w_ntrows) {
- X if (vscreen[i]->v_flag & VFEXT) {
- X if ((wp != curwp) || (lp != wp->w_dotp) ||
- X (curcol < term.t_ncol - 1)) {
- X l_to_vline(wp,lp,i);
- X vteeol();
- X /* this line no longer is extended */
- X vscreen[i]->v_flag &= ~VFEXT;
- X }
- X }
- X lp = lforw(lp);
- X ++i;
- X }
- X /* and onward to the next window */
- X wp = wp->w_wndp;
- X }
- }
- X
- /* updgar: if the screen is garbage, clear the physical screen and
- X the virtual screen and force a full update */
- X
- updgar()
- {
- X register char *txt;
- X register int i,j;
- X
- X for (i = 0; i < term.t_nrow; ++i) {
- X vscreen[i]->v_flag |= VFCHG;
- #if REVSTA
- X vscreen[i]->v_flag &= ~VFREV;
- #endif
- #if COLOR
- X vscreen[i]->v_fcolor = gfcolor;
- X vscreen[i]->v_bcolor = gbcolor;
- #endif
- #if ! MEMMAP
- X txt = pscreen[i]->v_text;
- X for (j = 0; j < term.t_ncol; ++j)
- X txt[j] = ' ';
- #endif
- X }
- X
- X movecursor(0, 0); /* Erase the screen. */
- X (*term.t_eeop)();
- X sgarbf = FALSE; /* Erase-page clears */
- X mpresf = FALSE; /* the message area. */
- #if COLOR
- X mlerase(); /* needs to be cleared if colored */
- #endif
- }
- X
- /* updupd: update the physical screen from the virtual screen */
- X
- updupd(force)
- int force; /* forced update flag */
- {
- X register VIDEO *vp1;
- X register int i;
- #if SCROLLCODE
- X if (scrflags & WFKILLS)
- X scrolls(FALSE);
- X if (scrflags & WFINS)
- X scrolls(TRUE);
- X scrflags = 0;
- #endif
- X
- X for (i = 0; i < term.t_nrow; ++i) {
- X vp1 = vscreen[i];
- X
- X /* for each line that needs to be updated*/
- X if ((vp1->v_flag & VFCHG) != 0) {
- #if TYPEAH
- X if (force == FALSE && typahead())
- X return(TRUE);
- #endif
- #if MEMMAP
- X updateline(i, vp1);
- #else
- X updateline(i, vp1, pscreen[i]);
- #endif
- X }
- X }
- X return(TRUE);
- }
- X
- #if SCROLLCODE
- /* optimize out scrolls (line breaks, and newlines) */
- /* arg. chooses between looking for inserts or deletes */
- int
- scrolls(inserts) /* returns true if it does something */
- {
- X struct VIDEO *vpv ; /* virtual screen image */
- X struct VIDEO *vpp ; /* physical screen image */
- X int i, j, k ;
- X int rows, cols ;
- X int first, match, count, ptarget, vtarget, end ;
- X int longmatch, longcount;
- X int from, to;
- X
- X if (!term.t_scroll) /* no way to scroll */
- X return FALSE;
- X
- X rows = term.t_nrow ;
- X cols = term.t_ncol ;
- X
- X first = -1 ;
- X for (i = 0; i < rows; i++) { /* find first wrong line */
- X if (!texttest(i,i)) {
- X first = i;
- X break;
- X }
- X }
- X
- X if (first < 0)
- X return FALSE; /* no text changes */
- X
- X vpv = vscreen[first] ;
- X vpp = pscreen[first] ;
- X
- X if (inserts) {
- X /* determine types of potential scrolls */
- X end = endofline(vpv->v_text,cols) ;
- X if ( end == 0 )
- X ptarget = first ; /* newlines */
- X else if ( strncmp(vpp->v_text, vpv->v_text, end) == 0 )
- X ptarget = first + 1 ; /* broken line newlines */
- X else
- X ptarget = first ;
- X } else {
- X vtarget = first + 1 ;
- X }
- X
- X /* find the matching shifted area */
- X match = -1 ;
- X longmatch = -1;
- X longcount = 0;
- X from = inserts ? ptarget : vtarget;
- X for (i = from+1; i < rows; i++) {
- X if (inserts ? texttest(i,from) : texttest(from,i) ) {
- X match = i ;
- X count = 1 ;
- X for (j=match+1, k=from+1; j<rows && k<rows; j++, k++) {
- X if (inserts ? texttest(j,k) : texttest(k,j))
- X count++ ;
- X else
- X break ;
- X }
- X if (longcount < count) {
- X longcount = count;
- X longmatch = match;
- X }
- X }
- X }
- X match = longmatch;
- X count = longcount;
- X
- X if (!inserts) {
- X /* full kill case? */
- X if (match > 0 && texttest(first, match-1)) {
- X vtarget-- ;
- X match-- ;
- X count++ ;
- X }
- X }
- X
- X /* do the scroll */
- X if (match>0 && count>2) { /* got a scroll */
- X /* move the count lines starting at ptarget to match */
- X /* mlwrite("scrolls: move the %d lines starting at %d to %d",
- X count,ptarget,match);
- X */
- X if (inserts) {
- X from = ptarget;
- X to = match;
- X } else {
- X from = match;
- X to = vtarget;
- X }
- X scrscroll(from, to, count) ;
- X for (i = 0; i < count; i++) {
- X vpp = pscreen[to+i] ;
- X vpv = vscreen[to+i];
- X strncpy(vpp->v_text, vpv->v_text, cols) ;
- X }
- X if (inserts) {
- X from = ptarget;
- X to = match;
- X } else {
- X from = vtarget+count;
- X to = match+count;
- X }
- X for (i = from; i < to; i++) {
- X char *txt;
- X txt = pscreen[i]->v_text;
- X for (j = 0; j < term.t_ncol; ++j)
- X txt[j] = ' ';
- X vscreen[i]->v_flag |= VFCHG;
- X }
- X return(TRUE) ;
- X }
- X return(FALSE) ;
- }
- X
- /* move the "count" lines starting at "from" to "to" */
- scrscroll(from, to, count)
- {
- X ttrow = ttcol = -1;
- X (*term.t_scroll)(from,to,count);
- }
- X
- texttest(vrow,prow) /* return TRUE on text match */
- int vrow, prow ; /* virtual, physical rows */
- {
- struct VIDEO *vpv = vscreen[vrow] ; /* virtual screen image */
- struct VIDEO *vpp = pscreen[prow] ; /* physical screen image */
- X
- X return (!memcmp(vpv->v_text, vpp->v_text, term.t_ncol)) ;
- }
- X
- /* return the index of the first blank of trailing whitespace */
- int
- endofline(s,n)
- char *s ;
- {
- int i ;
- X for (i = n - 1; i >= 0; i--)
- X if (s[i] != ' ') return(i+1) ;
- X return(0) ;
- }
- X
- #endif /* SCROLLCODE */
- X
- X
- /* updext_past: update the extended line which the cursor is currently
- X on at a column greater than the terminal width. The line
- X will be scrolled right or left to let the user see where
- X the cursor is */
- updext_past()
- {
- X register int lbound, rcursor;
- X register LINE *lp; /* pointer to current line */
- X register int j; /* index into line */
- X
- X /* calculate what column the real cursor will end up in */
- X /* why is term.t_ncol in here? */
- X rcursor = ((curcol - term.t_ncol) % term.t_scrsiz) + term.t_margin;
- X lbound = curcol - rcursor;
- X taboff = lbound + curwp->w_sideways;
- X
- X /* scan through the line outputing characters to the virtual screen */
- X /* once we reach the left edge */
- X vtmove(currow, -lbound-curwp->w_sideways); /* start scanning offscreen */
- X lp = curwp->w_dotp; /* line to output */
- X for (j = 0; j < llength(lp); ++j)
- X vtputc(lgetc(lp, j), curwp->w_bufp->b_mode&MDLIST);
- X vtputc('\n', curwp->w_bufp->b_mode&MDLIST);
- X
- X /* truncate the virtual line, restore tab offset */
- X vteeol();
- X taboff = 0;
- X
- X /* and put a '<' in column 1 */
- X vscreen[currow]->v_text[0] = '<';
- X vscreen[currow]->v_flag |= (VFEXT | VFCHG);
- X return rcursor;
- }
- X
- /* updext_before: update the extended line which the cursor is currently
- X on at a column less than the terminal width. The line
- X will be scrolled right or left to let the user see where
- X the cursor is */
- updext_before()
- {
- X register int lbound, rcursor;
- X register LINE *lp; /* pointer to current line */
- X register int j; /* index into line */
- X
- X /* calculate what column the real cursor will end up in */
- X rcursor = (curcol % (term.t_ncol-term.t_margin));
- X lbound = curcol - rcursor + 1;
- X taboff = lbound;
- X
- X /* scan through the line outputing characters to the virtual screen */
- X /* once we reach the left edge */
- X vtmove(currow, -lbound); /* start scanning offscreen */
- X lp = curwp->w_dotp; /* line to output */
- X for (j = 0; j < llength(lp); ++j)
- X vtputc(lgetc(lp, j), curwp->w_bufp->b_mode&MDLIST);
- X vtputc('\n', curwp->w_bufp->b_mode&MDLIST);
- X
- X /* truncate the virtual line, restore tab offset */
- X vteeol();
- X taboff = 0;
- X
- X /* and put a '<' in column 1 */
- X vscreen[currow]->v_text[0] = '<';
- X vscreen[currow]->v_flag |= (VFEXT | VFCHG);
- X return rcursor;
- }
- X
- X
- #if NeWS
- newsupd(force) /* update the physical screen from the virtual screen */
- int force; /* forced update flag */
- {
- register int i ;
- struct VIDEO *vpv ; /* virtual screen image */
- struct VIDEO *vpp ; /* physical screen image */
- int bad, badcol, rows ;
- X
- X rows = term.t_nrow ;
- X
- X if (force == FALSE && typahead()) return ;
- X if (sgarbf) {
- X fastupdate() ;
- X return ;
- X }
- X
- X /* if enough lines are bad try to optimize scrolls/kills */
- X for (bad = 0, i = 0; i < rows; ++i)
- X if (!texttest(i,i)) {
- X bad++ ;
- X if (bad > 3) {
- X if (!scrolls()) kills() ;
- X break ;
- X }
- X }
- X
- X /* count bad lines, if enough need fixed redo whole screen */
- X for (bad = 0, badcol = 0, i = 0; i < rows; ++i) {
- X vpv = vscreen[i] ;
- X vpv->v_flag &= ~(VFCHG|VFCOL) ; /* clear flag */
- X if (!texttest(i,i)) {
- X vpv->v_flag |= VFCHG ;
- X bad++ ;
- X }
- X if (!colortest(i)) {
- X vpv->v_flag |= VFCOL ;
- X badcol++ ;
- X }
- X }
- X if (bad == 0 && badcol > 0) { /* pure color update */
- X colorupdate() ;
- X return ;
- X }
- X if (bad > (3*rows)/4) { /* full update */
- X fastupdate() ;
- X return ;
- X }
- X
- X /* Fix the bad lines one by one */
- X for (i = 0; i < rows; ++i)
- X if (vscreen[i]->v_flag & (VFCHG|VFCOL)) updateline(i) ;
- }
- X
- X
- /* optimize out scrolls (line breaks, and newlines) */
- int scrolls() /* returns true if it does something */
- {
- struct VIDEO *vpv ; /* virtual screen image */
- struct VIDEO *vpp ; /* physical screen image */
- int i, j, k ;
- int rows, cols ;
- int first, match, count, ptarget, end ;
- X
- X rows = term.t_nrow ;
- X cols = term.t_ncol ;
- X
- X first = -1 ;
- X for (i = 0; i < rows; i++) /* find first wrong line */
- X if (!texttest(i,i)) {first = i ; break ;}
- X
- X if (first < 0) return(FALSE) ; /* no text changes */
- X
- X vpv = vscreen[first] ;
- X vpp = pscreen[first] ;
- X
- X /* determine types of potential scrolls */
- X end = endofline(vpv->v_text,cols) ;
- X if ( end == 0 )
- X ptarget = first ; /* newlines */
- X else if ( strncmp(vpp->v_text, vpv->v_text, end) == 0 )
- X ptarget = first + 1 ; /* broken line newlines */
- X else return(FALSE) ; /* no scrolls */
- X
- X /* find the matching shifted area */
- X match = -1 ;
- X for (i = ptarget+1; i < rows; i++) {
- X if (texttest(i, ptarget)) {
- X match = i ;
- X count = 1 ;
- X for (j=match+1, k=ptarget+1; j<rows && k<rows; j++, k++) {
- X if (texttest(j,k))
- X count++ ;
- X else
- X break ;
- X }
- X break ;
- X }
- X }
- X
- X /* do the scroll */
- X if (match>0 && count>2) { /* got a scroll */
- X newsscroll(ptarget, match, count) ;
- X for (i = 0; i < count; i++) {
- X vpv = vscreen[match+i] ; vpp = pscreen[match+i] ;
- X strncpy(vpp->v_text, vpv->v_text, cols) ;
- X }
- X return(TRUE) ;
- X }
- X return(FALSE) ;
- }
- X
- X
- /* optimize out line kills (full and with a partial kill) */
- int kills() /* returns true if it does something */
- {
- struct VIDEO *vpv ; /* virtual screen image */
- struct VIDEO *vpp ; /* physical screen image */
- int i, j, k ;
- int rows, cols ;
- int first, match, count, vtarget, end ;
- X
- X rows = term.t_nrow ;
- X cols = term.t_ncol ;
- X
- X first = -1 ;
- X for (i = 0; i < rows; i++) /* find first wrong line */
- X if (!texttest(i,i)) {first = i ; break ;}
- X
- X if (first < 0) return(FALSE) ; /* no text changes */
- X
- X vpv = vscreen[first] ;
- X vpp = pscreen[first] ;
- X
- X vtarget = first + 1 ;
- X
- X /* find the matching shifted area */
- X match = -1 ;
- X for (i = vtarget+1; i < rows; i++) {
- X if (texttest(vtarget, i)) {
- X match = i ;
- X count = 1 ;
- X for (j=match+1, k=vtarget+1; j<rows && k<rows; j++, k++) {
- X if (texttest(k,j))
- X count++ ;
- X else
- X break ;
- X }
- X break ;
- X }
- X }
- X if (texttest(first, match-1)) { /* full kill case */
- X vtarget-- ;
- X match-- ;
- X count++ ;
- X }
- X
- X /* do the scroll */
- X if (match>0 && count>2) { /* got a scroll */
- X newsscroll(match, vtarget, count) ;
- X for (i = 0; i < count; i++) {
- X vpv = vscreen[vtarget+i] ; vpp = pscreen[vtarget+i] ;
- X strncpy(vpp->v_text, vpv->v_text, cols) ;
- X }
- X return(TRUE) ;
- X }
- X return(FALSE) ;
- }
- X
- X
- texttest(vrow,prow) /* return TRUE on text match */
- int vrow, prow ; /* virtual, physical rows */
- {
- struct VIDEO *vpv = vscreen[vrow] ; /* virtual screen image */
- struct VIDEO *vpp = pscreen[prow] ; /* physical screen image */
- X
- X vpp->v_text[term.t_ncol] = 0 ;
- X vpv->v_text[term.t_ncol] = 0 ;
- X return (!strncmp(vpv->v_text, vpp->v_text, term.t_ncol)) ;
- }
- X
- colortest(row) /* TRUE on color match */
- int row ;
- {
- struct VIDEO *vpv = vscreen[row] ; /* virtual screen image */
- X
- X return (vpv->v_fcolor == vpv->v_rfcolor &&
- X vpv->v_bcolor == vpv->v_rbcolor) ;
- }
- X
- X
- updateline(row)
- int row ; /* row of screen to update */
- {
- struct VIDEO *vpv = vscreen[row] ; /* virtual screen image */
- struct VIDEO *vpp = pscreen[row] ; /* physical screen image */
- int end ;
- X
- X end = endofline(vpv->v_text, term.t_ncol) ;
- X strncpy(vpp->v_text, vpv->v_text, term.t_ncol) ;
- X vpv->v_text[end] = 0 ;
- X newsputline(row, vpv->v_text, vpv->v_rfcolor, vpv->v_rbcolor) ;
- X vpv->v_text[end] = ' ' ;
- X vpv->v_fcolor = vpv->v_rfcolor;
- X vpv->v_bcolor = vpv->v_rbcolor;
- X vpv->v_flag &= ~(VFCHG|VFCOL); /* clear flag */
- }
- X
- X
- colorupdate()
- {
- struct VIDEO *vpv ; /* virtual screen image */
- int row ;
- X
- X for (row=0; row<term.t_nrow; row++) { /* send the row colors */
- X vpv = vscreen[row] ;
- X if (vpv->v_flag & VFCOL) {
- X newssetrowcolors(row, vpv->v_rfcolor, vpv->v_rbcolor) ;
- X vpv->v_fcolor = vpv->v_rfcolor;
- X vpv->v_bcolor = vpv->v_rbcolor;
- X }
- X vpv->v_flag &= ~VFCOL ;
- X }
- X
- X newslocalupdate() ; /* ask for a screen refresh */
- }
- X
- X
- fastupdate() /* redo the entire screen fast */
- {
- int row ;
- register char *cp, *first ;
- struct VIDEO *vpv ; /* virtual screen image */
- struct VIDEO *vpp ; /* physical screen image */
- X
- X /* send the row colors */
- X for (row=0; row<term.t_nrow; row++) {
- X vpv = vscreen[row] ;
- X if (!colortest(row)) {
- X newssetrowcolors(row, vpv->v_rfcolor, vpv->v_rbcolor) ;
- X vpv->v_fcolor = vpv->v_rfcolor;
- X vpv->v_bcolor = vpv->v_rbcolor;
- X }
- X vpv->v_flag &= ~VFCOL ;
- X }
- X
- X /* virtual -> physical buffer */
- X for (row=0; row<term.t_nrow; row++) {
- X vpv = vscreen[row] ; vpp = pscreen[row] ;
- X memcpy(vpp->v_text, vpv->v_text, term.t_ncol);
- X vpp->v_text[term.t_ncol] = 0 ;
- X vpv->v_text[term.t_ncol] = 0 ;
- X vpv->v_flag &= ~VFCHG;
- X }
- X /* send the stuff */
- X newscls() ;
- X for (row=0; row<term.t_nrow; row++) {
- X first = pscreen[row]->v_text ;
- X /* don't send trailing blanks */
- X cp = &first[endofline(first,term.t_ncol)] ;
- X if (cp > first) {
- X *cp = 0 ;
- X newsfastputline(row, first) ;
- X *cp = ' ' ;
- X }
- X }
- X sgarbf = FALSE;
- }
- X
- X
- /* return the index of the first blank of trailing whitespace */
- int endofline(s,n)
- char *s ;
- {
- int i ;
- X for (i = n - 1; i >= 0; i--)
- X if (s[i] != ' ') return(i+1) ;
- X return(0) ;
- }
- #else
- X
- /*
- X * Update a single line. This does not know how to use insert or delete
- X * character sequences; we are using VT52 functionality. Update the physical
- X * row and column variables. It does try an exploit erase to end of line. The
- X * RAINBOW version of this routine uses fast video.
- X */
- #if MEMMAP
- /* UPDATELINE specific code for the IBM-PC and other compatables */
- X
- updateline(row, vp1)
- X
- int row; /* row of screen to update */
- struct VIDEO *vp1; /* virtual screen image */
- X
- {
- #if COLOR
- X scwrite(row, vp1->v_text, vp1->v_rfcolor, vp1->v_rbcolor);
- X vp1->v_fcolor = vp1->v_rfcolor;
- X vp1->v_bcolor = vp1->v_rbcolor;
- #else
- X if (vp1->v_flag & VFREQ)
- X scwrite(row, vp1->v_text, 0, 7);
- X else
- X scwrite(row, vp1->v_text, 7, 0);
- #endif
- X vp1->v_flag &= ~(VFCHG | VFCOL); /* flag this line as changed */
- X
- }
- X
- #else
- X
- updateline(row, vp1, vp2)
- X
- int row; /* row of screen to update */
- struct VIDEO *vp1; /* virtual screen image */
- struct VIDEO *vp2; /* physical screen image */
- X
- {
- #if RAINBOW
- /* UPDATELINE specific code for the DEC rainbow 100 micro */
- X
- X register char *cp1;
- X register char *cp2;
- X register int nch;
- X
- X /* since we don't know how to make the rainbow do this, turn it off */
- X flags &= (~VFREV & ~VFREQ);
- X
- X cp1 = &vp1->v_text[0]; /* Use fast video. */
- X cp2 = &vp2->v_text[0];
- X putline(row+1, 1, cp1);
- X nch = term.t_ncol;
- X
- X do
- X {
- X *cp2 = *cp1;
- X ++cp2;
- X ++cp1;
- X }
- X while (--nch);
- X *flags &= ~VFCHG;
- #else
- /* UPDATELINE code for all other versions */
- X
- X register char *cp1;
- X register char *cp2;
- X register char *cp3;
- X register char *cp4;
- X register char *cp5;
- X register int nbflag; /* non-blanks to the right flag? */
- X int rev; /* reverse video flag */
- X int req; /* reverse video request flag */
- X
- X
- X /* set up pointers to virtual and physical lines */
- X cp1 = &vp1->v_text[0];
- X cp2 = &vp2->v_text[0];
- X
- #if COLOR
- X TTforg(vp1->v_rfcolor);
- X TTbacg(vp1->v_rbcolor);
- #endif
- X
- #if REVSTA | COLOR
- X /* if we need to change the reverse video status of the
- X current line, we need to re-write the entire line */
- X rev = (vp1->v_flag & VFREV) == VFREV;
- X req = (vp1->v_flag & VFREQ) == VFREQ;
- X if ((rev != req)
- #if COLOR
- X || (vp1->v_fcolor != vp1->v_rfcolor) || (vp1->v_bcolor != vp1->v_rbcolor)
- #endif
- #if HP150
- X /* the HP150 has some reverse video problems */
- X || req || rev
- #endif
- X ) {
- X movecursor(row, 0); /* Go to start of line. */
- X /* set rev video if needed */
- X if (rev != req)
- X (*term.t_rev)(req);
- X
- X /* scan through the line and dump it to the screen and
- X the virtual screen array */
- X cp3 = &vp1->v_text[term.t_ncol];
- X while (cp1 < cp3) {
- X TTputc(*cp1);
- X ++ttcol;
- X *cp2++ = *cp1++;
- X }
- X /* turn rev video off */
- X if (rev != req)
- X (*term.t_rev)(FALSE);
- X
- X /* update the needed flags */
- X vp1->v_flag &= ~VFCHG;
- X if (req)
- X vp1->v_flag |= VFREV;
- X else
- X vp1->v_flag &= ~VFREV;
- #if COLOR
- X vp1->v_fcolor = vp1->v_rfcolor;
- X vp1->v_bcolor = vp1->v_rbcolor;
- #endif
- X return(TRUE);
- X }
- #endif
- X
- X /* advance past any common chars at the left */
- X while (cp1 != &vp1->v_text[term.t_ncol] && *cp1 == *cp2) {
- X ++cp1;
- X ++cp2;
- X }
- X
- /* This can still happen, even though we only call this routine on changed
- X * lines. A hard update is always done when a line splits, a massive
- X * change is done, or a buffer is displayed twice. This optimizes out most
- X * of the excess updating. A lot of computes are used, but these tend to
- X * be hard operations that do a lot of update, so I don't really care.
- X */
- X /* if both lines are the same, no update needs to be done */
- X if (cp1 == &vp1->v_text[term.t_ncol]) {
- X vp1->v_flag &= ~VFCHG; /* flag this line is changed */
- X return(TRUE);
- X }
- X
- X /* find out if there is a match on the right */
- X nbflag = FALSE;
- X cp3 = &vp1->v_text[term.t_ncol];
- X cp4 = &vp2->v_text[term.t_ncol];
- X
- X while (cp3[-1] == cp4[-1]) {
- X --cp3;
- X --cp4;
- X if (cp3[0] != ' ') /* Note if any nonblank */
- X nbflag = TRUE; /* in right match. */
- X }
- X
- X cp5 = cp3;
- X
- X /* Erase to EOL ? */
- X if (nbflag == FALSE && eolexist == TRUE && (req != TRUE)) {
- X while (cp5!=cp1 && cp5[-1]==' ')
- X --cp5;
- X
- X if (cp3-cp5 <= 3) /* Use only if erase is */
- X cp5 = cp3; /* fewer characters. */
- X }
- X
- X movecursor(row, cp1 - &vp1->v_text[0]); /* Go to start of line. */
- #if REVSTA
- X TTrev(rev);
- #endif
- X
- X while (cp1 != cp5) { /* Ordinary. */
- X TTputc(*cp1);
- X ++ttcol;
- X *cp2++ = *cp1++;
- X }
- X
- X if (cp5 != cp3) { /* Erase. */
- X TTeeol();
- X while (cp1 != cp3)
- X *cp2++ = *cp1++;
- X }
- #if REVSTA
- X TTrev(FALSE);
- #endif
- X vp1->v_flag &= ~VFCHG; /* flag this line as updated */
- X return(TRUE);
- #endif
- }
- #endif
- X
- #endif /* NeWS */
- X
- /*
- X * Redisplay the mode line for the window pointed to by the "wp". This is the
- X * only routine that has any idea of how the modeline is formatted. You can
- X * change the modeline format by hacking at this routine. Called by "update"
- X * any time there is a dirty window.
- X */
- modeline(wp)
- WINDOW *wp;
- {
- X register int n;
- X register BUFFER *bp;
- X register lchar; /* character to draw line in buffer with */
- X
- X n = wp->w_toprow+wp->w_ntrows; /* Location. */
- X vscreen[n]->v_flag |= VFCHG | VFREQ | VFCOL;/* Redraw next time. */
- X
- #if NeWS
- X vscreen[n]->v_rfcolor = 0;
- X vscreen[n]->v_rbcolor = 7;
- X if (wp == curwp) { /* mark the current buffer */
- X lchar = '^' ;
- X } else {
- X lchar = ' ' ;
- X }
- X vtmove(n, 0); /* Seek to right line. */
- #else
- X
- #if COLOR
- X vscreen[n]->v_rfcolor = 0; /* black on */
- X vscreen[n]->v_rbcolor = 7; /* white.....*/
- #endif
- X vtmove(n, 0); /* Seek to right line. */
- X if (wp == curwp) { /* mark the current buffer */
- X lchar = '=';
- X } else {
- #if REVSTA
- X if (revexist)
- X lchar = ' ';
- X else
- #endif
- X lchar = '-';
- #endif
- X }
- X bp = wp->w_bufp;
- X
- X vtputc(lchar,FALSE);
- X vtputc(' ',FALSE);
- X vtputsn(bp->b_bname, NBUFN);
- X if (bp->b_mode&MDVIEW)
- X vtputsn(" [view only]", 20);
- X if (bp->b_mode&MDDOS)
- X vtputsn(" [dos-style]", 20);
- X if (bp->b_flag&BFCHG)
- X vtputsn(" [modified]", 20);
- X /* don't print a filename if they're the same,
- X or the filename is null */
- X if (strcmp(bp->b_fname,bp->b_bname)) {
- X if (bp->b_fname[0] != '\0') {
- X if (isspace(bp->b_fname[0])) {
- X /* some of the internally generated buffers
- X put other info. in filename slot */
- X vtputsn(bp->b_fname, NFILEN);
- X } else {
- X if (ispunct(bp->b_fname[0]))
- X vtputsn(" is \"", 20);
- X else
- X vtputsn(" is file \"", 20);
- X vtputsn(bp->b_fname, NFILEN);
- X vtputsn("\"", 20);
- X }
- X }
- X }
- X vtputc(' ',FALSE);
- X
- X
- X /* Pad to full width, then go back and overwrite right-end info */
- X n = term.t_ncol;
- X while (vtcol < n)
- X vtputc(lchar,FALSE);
- X
- X { /* determine if top line, bottom line, or both are visible */
- X LINE *lp = wp->w_linep;
- X int rows = wp->w_ntrows;
- X char *msg = NULL;
- X
- X vtcol = n - 7; /* strlen(" top ") plus a couple */
- X while (rows--) {
- X lp = lforw(lp);
- X if (lp == wp->w_bufp->b_linep) {
- X msg = " bot ";
- X break;
- X }
- X }
- X if (lback(wp->w_linep) == wp->w_bufp->b_linep) {
- X if (msg) {
- X if (wp->w_linep == wp->w_bufp->b_linep)
- X msg = " emp ";
- X else
- X msg = " all ";
- X } else {
- X msg = " top ";
- X }
- X }
- X if (!msg)
- X msg = " mid ";
- X vtputsn(msg,20);
- X }
- X
- X if (vtgetc(80) == lchar) {
- X vtcol = 80;
- X vtputc('|',FALSE);
- X }
- }
- X
- upmode() /* update all the mode lines */
- {
- X register WINDOW *wp;
- X
- #if NeWS /* tell workstation the current modes */
- X newsreportmodes() ;
- #endif
- X wp = wheadp;
- X while (wp != NULL) {
- X wp->w_flag |= WFMODE;
- X wp = wp->w_wndp;
- X }
- }
- X
- /*
- X * Send a command to the terminal to move the hardware cursor to row "row"
- X * and column "col". The row and column arguments are origin 0. Optimize out
- X * random calls. Update "ttrow" and "ttcol".
- X */
- movecursor(row, col)
- {
- #if ! NeWS /* "line buffered" */
- X if (row!=ttrow || col!=ttcol)
- #endif
- X {
- X ttrow = row;
- X ttcol = col;
- X TTmove(row, col);
- X }
- }
- X
- X
- X
- #if NeWS /* buffer the message line stuff, newsputc is slow */
- #define NEWSBUFSIZ 256
- #undef TTputc
- #undef TTflush
- #define TTputc(c) bufputc(c)
- #define TTflush() bufputc((char)0)
- X
- bufputc(c)
- char c ;
- {
- X static bufindex = 0 ;
- X static char outbuf[NEWSBUFSIZ] ;
- X
- X if (c == NULL || bufindex >= NEWSBUFSIZ || bufindex >= term.t_ncol) {
- X outbuf[bufindex] = NULL ;
- X newsputline(term.t_nrow, outbuf, 7, 0) ;
- X movecursor(term.t_nrow, strlen(outbuf)) ;
- X newsflush() ;
- X bufindex = 0 ;
- X }
- X else outbuf[bufindex++] = c ;
- }
- #endif
- X
- X
- /*
- X * Erase the message line. This is a special routine because the message line
- X * is not considered to be part of the virtual screen. It always works
- X * immediately; the terminal buffer is flushed via a call to the flusher.
- X */
- mlerase()
- {
- X int i;
- X
- X if (mpresf == FALSE)
- X return;
- X movecursor(term.t_nrow, 0);
- X if (discmd == FALSE)
- X return;
- X
- #if COLOR
- X TTforg(7);
- X TTbacg(0);
- #endif
- X if (eolexist == TRUE)
- X TTeeol();
- X else {
- X for (i = 0; i < term.t_ncol - 1; i++)
- X TTputc(' ');
- X movecursor(term.t_nrow, 1); /* force the move! */
- X movecursor(term.t_nrow, 0);
- X }
- X TTflush();
- X mpresf = FALSE;
- }
- X
- X
- X
- X
- #ifndef va_dcl /* then try these out */
- X
- typedef char *va_list;
- #define va_dcl int va_alist;
- #define va_start(list) list = (char *) &va_alist
- #define va_end(list)
- #define va_arg(list, mode) ((mode *)(list += sizeof(mode)))[-1]
- X
- #endif
- X
- dbgwrite(s,x,y,z)
- {
- X mlwrite(s,x,y,z);
- X tgetc();
- }
- X
- /*
- X * Write a message into the message line. Keep track of the physical cursor
- X * position. A small class of printf like format items is handled.
- X * Set the "message line" flag TRUE.
- X */
- X
- /* VARARGS */
- mlwrite(fmt, va_alist)
- char *fmt; /* format string for output */
- va_dcl
- {
- X register int c; /* current char in format string */
- X register va_list ap; /* ptr to current data field */
- X
- X /* if we are not currently echoing on the command line, abort this */
- X if (dotcmdmode == PLAY || discmd == FALSE) {
- X movecursor(term.t_nrow, 0);
- X return;
- X }
- X
- #if COLOR
- X /* set up the proper colors for the command line */
- X TTforg(7);
- X TTbacg(0);
- #endif
- X
- X /* if we can not erase to end-of-line, do it manually */
- X if (eolexist == FALSE) {
- X mlerase();
- X TTflush();
- X }
- X
- X va_start(ap);
- X
- X movecursor(term.t_nrow, 0);
- X while ((c = *fmt) != 0 && ttcol < term.t_ncol-1) {
- X if (c != '%') {
- X mlputc(c);
- X } else {
- X c = *++fmt;
- X switch (c) {
- X case '\0':
- X break;
- X case 'c':
- X mlputc(va_arg(ap,int));
- X break;
- X
- X case 'd':
- X mlputi(va_arg(ap,int), 10);
- X break;
- X
- X case 'o':
- X mlputi(va_arg(ap,int), 8);
- X break;
- X
- X case 'x':
- X mlputi(va_arg(ap,int), 16);
- X break;
- X
- X case 'D':
- X mlputli(va_arg(ap,long), 10);
- X break;
- X
- X case 's':
- X mlputs(va_arg(ap,char *));
- X break;
- X
- X case 'S': {
- X int wid = va_arg(ap,int);
- X mlputsn(va_arg(ap,char *),wid);
- X break;
- X }
- X
- X case 'f':
- X mlputf(va_arg(ap,int));
- X break;
- X
- X default:
- X mlputc(c);
- X }
- X }
- X fmt++;
- X }
- X
- X va_end(ap);
- X
- X /* if we can, erase to the end of screen */
- X if (eolexist == TRUE)
- X TTeeol();
- X TTflush();
- X mpresf = TRUE;
- }
- X
- /* Force a string out to the message line regardless of the
- X current $discmd setting. This is needed when $debug is TRUE
- X and for the write-message and clear-message-line commands
- */
- X
- mlforce(s)
- char *s; /* string to force out */
- {
- X register oldcmd; /* original command display flag */
- X
- X oldcmd = discmd; /* save the discmd value */
- X discmd = TRUE; /* and turn display on */
- X mlwrite(s); /* write the string out */
- X discmd = oldcmd; /* and restore the original setting */
- }
- X
- /*
- X * Write out a character. Update the physical cursor position. This assumes that
- X * the character has width "1"; if this is not the case
- X * things will get screwed up a little.
- X */
- mlputc(c)
- char c;
- {
- X if (c == '\r') ttcol = 0;
- X if (ttcol < term.t_ncol-1) {
- X TTputc(c);
- X ++ttcol;
- X }
- }
- X
- /*
- X * Write out a string. Update the physical cursor position. This assumes that
- X * the characters in the string all have width "1"; if this is not the case
- X * things will get screwed up a little.
- X */
- mlputs(s)
- char *s;
- {
- X register int c;
- X
- X while ((c = *s++) != 0) {
- X mlputc(c);
- X }
- }
- X
- /* as above, but takes a count for s's length */
- mlputsn(s,n)
- char *s;
- {
- X register int c;
- X while ((c = *s++) != 0 && n-- != 0) {
- X mlputc(c);
- X }
- }
- X
- /*
- X * Write out an integer, in the specified radix. Update the physical cursor
- X * position.
- X */
- mlputi(i, r)
- {
- X register int q;
- X static char hexdigits[] = "0123456789ABCDEF";
- X
- X if (i < 0) {
- X i = -i;
- X mlputc('-');
- X }
- X
- X q = i/r;
- X
- X if (q != 0)
- X mlputi(q, r);
- X
- X mlputc(hexdigits[i%r]);
- }
- X
- /*
- X * do the same except as a long integer.
- X */
- mlputli(l, r)
- long l;
- {
- X register long q;
- X
- X if (l < 0) {
- X l = -l;
- X mlputc('-');
- X }
- X
- X q = l/r;
- X
- X if (q != 0)
- X mlputli(q, r);
- X
- X mlputc((int)(l%r)+'0');
- }
- X
- /*
- X * write out a scaled integer with two decimal places
- X */
- X
- mlputf(s)
- int s; /* scaled integer to output */
- {
- X register int i; /* integer portion of number */
- X register int f; /* fractional portion of number */
- X
- X /* break it up */
- X i = s / 100;
- X f = s % 100;
- X
- X /* send out the integer portion */
- X mlputi(i, 10);
- X mlputc('.');
- X mlputc((f / 10) + '0');
- X mlputc((f % 10) + '0');
- }
- X
- #if RAINBOW
- X
- putline(row, col, buf)
- int row, col;
- char buf[];
- {
- X int n;
- X
- X n = strlen(buf);
- X if (col + n - 1 > term.t_ncol)
- X n = term.t_ncol - col + 1;
- X Put_Data(row, col, n, buf);
- }
- #endif
- X
- /* Get terminal size from system.
- X Store number of lines into *heightp and width into *widthp.
- X If zero or a negative number is stored, the value is not valid. */
- X
- getscreensize (widthp, heightp)
- int *widthp, *heightp;
- {
- #ifdef TIOCGWINSZ
- X struct winsize size;
- X *widthp = 0;
- X *heightp = 0;
- X if (ioctl (0, TIOCGWINSZ, &size) < 0)
- X return;
- X *widthp = size.ws_col;
- X *heightp = size.ws_row;
- #else
- X *widthp = 0;
- X *heightp = 0;
- #endif
- }
- X
- #ifdef SIGWINCH
- sizesignal ()
- {
- X int w, h;
- X extern int errno;
- X int old_errno = errno;
- X
- X getscreensize (&w, &h);
- X
- X if ((h && h-1 != term.t_nrow) || (w && w != term.t_ncol))
- X newscreensize(h, w);
- X
- X signal (SIGWINCH, sizesignal);
- X errno = old_errno;
- }
- X
- newscreensize (h, w)
- int h, w;
- {
- X /* do the change later */
- X if (displaying) {
- X chg_width = w;
- X chg_height = h;
- X return;
- X }
- X chg_width = chg_height = 0;
- X if (h - 1 < term.t_mrow)
- X newlength(TRUE,h);
- X if (w < term.t_mcol)
- X newwidth(TRUE,w);
- X
- X update(TRUE);
- X return TRUE;
- }
- X
- #endif
- SHAR_EOF
- chmod 0444 display.c ||
- echo 'restore of display.c failed'
- Wc_c="`wc -c < 'display.c'`"
- test 40087 -eq "$Wc_c" ||
- echo 'display.c: original size 40087, current size' "$Wc_c"
- # ============= dolock.c ==============
- echo 'x - extracting dolock.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'dolock.c' &&
- #if 0
- /* dolock: MDBS specific Unix 4.2BSD file locking mechinism
- X this is not to be distributed generally */
- X
- #include <mdbs.h>
- #include <mdbsio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- X
- /* included by port.h: mdbs.h, mdbsio.h, sys/types.h, sys/stat.h */
- X
- X
- #ifndef bsdunix
- char *dolock(){return(NULL);}
- char *undolock(){return(NULL);}
- #else
- X
- #include <pwd.h>
- #include <errno.h>
- X
- extern int errno;
- X
- #define LOCKDIR ".xlk"
- X
- #define LOCKMSG "LOCK ERROR -- "
- #define LOCKMSZ sizeof(LOCKMSG)
- #define LOCKERR(s) { strcat(lmsg,s); oldumask = umask(oldumask); return(lmsg); }
- X
- /**********************
- X *
- X * dolock -- lock the file fname
- X *
- X * if successful, returns NULL
- X * if file locked, returns username of person locking the file
- X * if other error, returns "LOCK ERROR: explanation"
- X *
- X * Jon Reid, 2/19/86
- X *
- X *********************/
- X
- BOOL parent = FALSE;
- BOOL tellall = FALSE;
- X
- char *gtname(filespec) /* get name component of unix-style filespec */
- char *filespec;
- {
- X char *rname, *rindex();
- X
- X rname = rindex(filespec,'/');
- SHAR_EOF
- true || echo 'restore of dolock.c failed'
- echo 'End of Vile part 3'
- echo 'File dolock.c is continued in part 4'
- echo 4 > _shar_seq_.tmp
- exit 0
- --
- paul fox, pgf@cayman.com, (617)494-1999
- Cayman Systems, 26 Landsdowne St., Cambridge, MA 02139
-