1b2d5d167SMark Peek /* $Header: /src/pub/tcsh/ed.refresh.c,v 3.30 2003/02/08 20:03:25 christos Exp $ */ 2c80476e4SDavid E. O'Brien /* 3c80476e4SDavid E. O'Brien * ed.refresh.c: Lower level screen refreshing functions 4c80476e4SDavid E. O'Brien */ 5c80476e4SDavid E. O'Brien /*- 6c80476e4SDavid E. O'Brien * Copyright (c) 1980, 1991 The Regents of the University of California. 7c80476e4SDavid E. O'Brien * All rights reserved. 8c80476e4SDavid E. O'Brien * 9c80476e4SDavid E. O'Brien * Redistribution and use in source and binary forms, with or without 10c80476e4SDavid E. O'Brien * modification, are permitted provided that the following conditions 11c80476e4SDavid E. O'Brien * are met: 12c80476e4SDavid E. O'Brien * 1. Redistributions of source code must retain the above copyright 13c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer. 14c80476e4SDavid E. O'Brien * 2. Redistributions in binary form must reproduce the above copyright 15c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer in the 16c80476e4SDavid E. O'Brien * documentation and/or other materials provided with the distribution. 1729301572SMark Peek * 3. Neither the name of the University nor the names of its contributors 18c80476e4SDavid E. O'Brien * may be used to endorse or promote products derived from this software 19c80476e4SDavid E. O'Brien * without specific prior written permission. 20c80476e4SDavid E. O'Brien * 21c80476e4SDavid E. O'Brien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22c80476e4SDavid E. O'Brien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23c80476e4SDavid E. O'Brien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24c80476e4SDavid E. O'Brien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25c80476e4SDavid E. O'Brien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26c80476e4SDavid E. O'Brien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27c80476e4SDavid E. O'Brien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28c80476e4SDavid E. O'Brien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29c80476e4SDavid E. O'Brien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30c80476e4SDavid E. O'Brien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31c80476e4SDavid E. O'Brien * SUCH DAMAGE. 32c80476e4SDavid E. O'Brien */ 33c80476e4SDavid E. O'Brien #include "sh.h" 34c80476e4SDavid E. O'Brien 35b2d5d167SMark Peek RCSID("$Id: ed.refresh.c,v 3.30 2003/02/08 20:03:25 christos Exp $") 36c80476e4SDavid E. O'Brien 37c80476e4SDavid E. O'Brien #include "ed.h" 38c80476e4SDavid E. O'Brien /* #define DEBUG_UPDATE */ 39c80476e4SDavid E. O'Brien /* #define DEBUG_REFRESH */ 40c80476e4SDavid E. O'Brien /* #define DEBUG_LITERAL */ 41c80476e4SDavid E. O'Brien 42c80476e4SDavid E. O'Brien /* refresh.c -- refresh the current set of lines on the screen */ 43c80476e4SDavid E. O'Brien 44c80476e4SDavid E. O'Brien Char *litptr[256]; 45c80476e4SDavid E. O'Brien static int vcursor_h, vcursor_v; 46c80476e4SDavid E. O'Brien static int rprompt_h, rprompt_v; 47c80476e4SDavid E. O'Brien 48c80476e4SDavid E. O'Brien static void Draw __P((int)); 49c80476e4SDavid E. O'Brien static void Vdraw __P((int)); 50c80476e4SDavid E. O'Brien static void RefreshPromptpart __P((Char *)); 51c80476e4SDavid E. O'Brien static void update_line __P((Char *, Char *, int)); 52c80476e4SDavid E. O'Brien static void str_insert __P((Char *, int, int, Char *, int)); 53c80476e4SDavid E. O'Brien static void str_delete __P((Char *, int, int, int)); 54c80476e4SDavid E. O'Brien static void str_cp __P((Char *, Char *, int)); 55b2d5d167SMark Peek #ifndef WINNT_NATIVE 56b2d5d167SMark Peek static 57b2d5d167SMark Peek #else 58b2d5d167SMark Peek extern 59b2d5d167SMark Peek #endif 60b2d5d167SMark Peek void PutPlusOne __P((int)); 61c80476e4SDavid E. O'Brien static void cpy_pad_spaces __P((Char *, Char *, int)); 62c80476e4SDavid E. O'Brien #if defined(DSPMBYTE) 63c80476e4SDavid E. O'Brien static Char *update_line_fix_mbyte_point __P((Char *, Char *, int)); 64c80476e4SDavid E. O'Brien #endif 65c80476e4SDavid E. O'Brien #if defined(DEBUG_UPDATE) || defined(DEBUG_REFRESH) || defined(DEBUG_LITERAL) 66c80476e4SDavid E. O'Brien static void dprintf __P((char *, ...)); 67c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 68c80476e4SDavid E. O'Brien static void dprintstr __P((char *, Char *, Char *)); 69c80476e4SDavid E. O'Brien 70c80476e4SDavid E. O'Brien static void 71c80476e4SDavid E. O'Brien dprintstr(str, f, t) 72c80476e4SDavid E. O'Brien char *str; 73c80476e4SDavid E. O'Brien Char *f, *t; 74c80476e4SDavid E. O'Brien { 75c80476e4SDavid E. O'Brien dprintf("%s:\"", str); 76c80476e4SDavid E. O'Brien while (f < t) 77c80476e4SDavid E. O'Brien dprintf("%c", *f++ & ASCII); 78c80476e4SDavid E. O'Brien dprintf("\"\r\n"); 79c80476e4SDavid E. O'Brien } 80c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 81c80476e4SDavid E. O'Brien 82c80476e4SDavid E. O'Brien /* dprintf(): 83c80476e4SDavid E. O'Brien * Print to $DEBUGTTY, so that we can test editing on one pty, and 84c80476e4SDavid E. O'Brien * print debugging stuff on another. Don't interrupt the shell while 85c80476e4SDavid E. O'Brien * debugging cause you'll mangle up the file descriptors! 86c80476e4SDavid E. O'Brien */ 87c80476e4SDavid E. O'Brien static void 88c80476e4SDavid E. O'Brien #ifdef FUNCPROTO 89c80476e4SDavid E. O'Brien dprintf(char *fmt, ...) 90c80476e4SDavid E. O'Brien #else 91c80476e4SDavid E. O'Brien dprintf(va_list) 92c80476e4SDavid E. O'Brien va_dcl 93c80476e4SDavid E. O'Brien #endif /* __STDC__ */ 94c80476e4SDavid E. O'Brien { 95c80476e4SDavid E. O'Brien static int fd = -1; 96c80476e4SDavid E. O'Brien char *dtty; 97c80476e4SDavid E. O'Brien 98c80476e4SDavid E. O'Brien if ((dtty = getenv("DEBUGTTY"))) { 99c80476e4SDavid E. O'Brien int o; 100c80476e4SDavid E. O'Brien va_list va; 101c80476e4SDavid E. O'Brien #ifdef FUNCPROTO 102c80476e4SDavid E. O'Brien va_start(va, fmt); 103c80476e4SDavid E. O'Brien #else 104c80476e4SDavid E. O'Brien char *fmt; 105c80476e4SDavid E. O'Brien va_start(va); 106c80476e4SDavid E. O'Brien fmt = va_arg(va, char *); 107c80476e4SDavid E. O'Brien #endif /* __STDC__ */ 108c80476e4SDavid E. O'Brien 109c80476e4SDavid E. O'Brien if (fd == -1) 110c80476e4SDavid E. O'Brien fd = open(dtty, O_RDWR); 111c80476e4SDavid E. O'Brien o = SHOUT; 112c80476e4SDavid E. O'Brien flush(); 113c80476e4SDavid E. O'Brien SHOUT = fd; 114c80476e4SDavid E. O'Brien xvprintf(fmt, va); 115c80476e4SDavid E. O'Brien va_end(va); 116c80476e4SDavid E. O'Brien flush(); 117c80476e4SDavid E. O'Brien SHOUT = o; 118c80476e4SDavid E. O'Brien } 119c80476e4SDavid E. O'Brien } 120c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE || DEBUG_REFRESH || DEBUG_LITERAL */ 121c80476e4SDavid E. O'Brien 122c80476e4SDavid E. O'Brien static void 123c80476e4SDavid E. O'Brien Draw(c) /* draw c, expand tabs, ctl chars */ 124c80476e4SDavid E. O'Brien register int c; 125c80476e4SDavid E. O'Brien { 126c80476e4SDavid E. O'Brien register Char ch = c & CHAR; 127c80476e4SDavid E. O'Brien 128c80476e4SDavid E. O'Brien if (Isprint(ch)) { 129c80476e4SDavid E. O'Brien Vdraw(c); 130c80476e4SDavid E. O'Brien return; 131c80476e4SDavid E. O'Brien } 132c80476e4SDavid E. O'Brien /* from wolman%crltrx.DEC@decwrl.dec.com (Alec Wolman) */ 133c80476e4SDavid E. O'Brien if (ch == '\n') { /* expand the newline */ 134c80476e4SDavid E. O'Brien /* 135c80476e4SDavid E. O'Brien * Don't force a newline if Vdraw does it (i.e. we're at end of line) 136c80476e4SDavid E. O'Brien * - or we will get two newlines and possibly garbage in between 137c80476e4SDavid E. O'Brien */ 138c80476e4SDavid E. O'Brien int oldv = vcursor_v; 139c80476e4SDavid E. O'Brien 140c80476e4SDavid E. O'Brien Vdraw('\0'); /* assure end of line */ 141c80476e4SDavid E. O'Brien if (oldv == vcursor_v) { 142c80476e4SDavid E. O'Brien vcursor_h = 0; /* reset cursor pos */ 143c80476e4SDavid E. O'Brien vcursor_v++; 144c80476e4SDavid E. O'Brien } 145c80476e4SDavid E. O'Brien return; 146c80476e4SDavid E. O'Brien } 147c80476e4SDavid E. O'Brien if (ch == '\t') { /* expand the tab */ 148c80476e4SDavid E. O'Brien for (;;) { 149c80476e4SDavid E. O'Brien Vdraw(' '); 150c80476e4SDavid E. O'Brien if ((vcursor_h & 07) == 0) 151c80476e4SDavid E. O'Brien break; /* go until tab stop */ 152c80476e4SDavid E. O'Brien } 153c80476e4SDavid E. O'Brien } 154c80476e4SDavid E. O'Brien else if (Iscntrl(ch)) { 1553b6eaa7bSAndrey A. Chernov #ifdef IS_ASCII 156c80476e4SDavid E. O'Brien Vdraw('^'); 157c80476e4SDavid E. O'Brien if (ch == CTL_ESC('\177')) { 158c80476e4SDavid E. O'Brien Vdraw('?'); 159c80476e4SDavid E. O'Brien } 160c80476e4SDavid E. O'Brien else { 161c80476e4SDavid E. O'Brien /* uncontrolify it; works only for iso8859-1 like sets */ 162c80476e4SDavid E. O'Brien Vdraw((c | 0100)); 1633b6eaa7bSAndrey A. Chernov #else 164c80476e4SDavid E. O'Brien if (ch == CTL_ESC('\177')) { 165c80476e4SDavid E. O'Brien Vdraw('^'); 166c80476e4SDavid E. O'Brien Vdraw('?'); 167c80476e4SDavid E. O'Brien } 168c80476e4SDavid E. O'Brien else { 169c80476e4SDavid E. O'Brien if (Isupper(_toebcdic[_toascii[c]|0100]) 170c80476e4SDavid E. O'Brien || strchr("@[\\]^_", _toebcdic[_toascii[c]|0100]) != NULL) 171c80476e4SDavid E. O'Brien { 172c80476e4SDavid E. O'Brien Vdraw('^'); 173c80476e4SDavid E. O'Brien Vdraw(_toebcdic[_toascii[c]|0100]); 174c80476e4SDavid E. O'Brien } 175c80476e4SDavid E. O'Brien else 176c80476e4SDavid E. O'Brien { 177c80476e4SDavid E. O'Brien Vdraw('\\'); 178c80476e4SDavid E. O'Brien Vdraw(((c >> 6) & 7) + '0'); 179c80476e4SDavid E. O'Brien Vdraw(((c >> 3) & 7) + '0'); 180c80476e4SDavid E. O'Brien Vdraw((c & 7) + '0'); 181c80476e4SDavid E. O'Brien } 1823b6eaa7bSAndrey A. Chernov #endif 183c80476e4SDavid E. O'Brien } 184c80476e4SDavid E. O'Brien } 185c80476e4SDavid E. O'Brien #ifdef KANJI 18600c801edSDavid E. O'Brien else if ( 18700c801edSDavid E. O'Brien #ifdef DSPMBYTE 18800c801edSDavid E. O'Brien _enable_mbdisp && 18900c801edSDavid E. O'Brien #endif 19000c801edSDavid E. O'Brien !adrof(STRnokanji)) { 191c80476e4SDavid E. O'Brien Vdraw(c); 192c80476e4SDavid E. O'Brien return; 193c80476e4SDavid E. O'Brien } 194c80476e4SDavid E. O'Brien #endif 195c80476e4SDavid E. O'Brien else { 196c80476e4SDavid E. O'Brien Vdraw('\\'); 197c80476e4SDavid E. O'Brien Vdraw(((c >> 6) & 7) + '0'); 198c80476e4SDavid E. O'Brien Vdraw(((c >> 3) & 7) + '0'); 199c80476e4SDavid E. O'Brien Vdraw((c & 7) + '0'); 200c80476e4SDavid E. O'Brien } 201c80476e4SDavid E. O'Brien } 202c80476e4SDavid E. O'Brien 203c80476e4SDavid E. O'Brien static void 204c80476e4SDavid E. O'Brien Vdraw(c) /* draw char c onto V lines */ 205c80476e4SDavid E. O'Brien register int c; 206c80476e4SDavid E. O'Brien { 207c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 208c80476e4SDavid E. O'Brien # ifdef SHORT_STRINGS 209c80476e4SDavid E. O'Brien dprintf("Vdrawing %6.6o '%c'\r\n", c, c & ASCII); 210c80476e4SDavid E. O'Brien # else 211c80476e4SDavid E. O'Brien dprintf("Vdrawing %3.3o '%c'\r\n", c, c); 212c80476e4SDavid E. O'Brien # endif /* SHORT_STRNGS */ 213c80476e4SDavid E. O'Brien #endif /* DEBUG_REFRESH */ 214c80476e4SDavid E. O'Brien 215c80476e4SDavid E. O'Brien Vdisplay[vcursor_v][vcursor_h] = (Char) c; 216c80476e4SDavid E. O'Brien vcursor_h++; /* advance to next place */ 217c80476e4SDavid E. O'Brien if (vcursor_h >= TermH) { 218c80476e4SDavid E. O'Brien Vdisplay[vcursor_v][TermH] = '\0'; /* assure end of line */ 219c80476e4SDavid E. O'Brien vcursor_h = 0; /* reset it. */ 220c80476e4SDavid E. O'Brien vcursor_v++; 221c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 222c80476e4SDavid E. O'Brien if (vcursor_v >= TermV) { /* should NEVER happen. */ 223c80476e4SDavid E. O'Brien dprintf("\r\nVdraw: vcursor_v overflow! Vcursor_v == %d > %d\r\n", 224c80476e4SDavid E. O'Brien vcursor_v, TermV); 225c80476e4SDavid E. O'Brien abort(); 226c80476e4SDavid E. O'Brien } 227c80476e4SDavid E. O'Brien #endif /* DEBUG_REFRESH */ 228c80476e4SDavid E. O'Brien } 229c80476e4SDavid E. O'Brien } 230c80476e4SDavid E. O'Brien 231c80476e4SDavid E. O'Brien /* 232c80476e4SDavid E. O'Brien * RefreshPromptpart() 233c80476e4SDavid E. O'Brien * draws a prompt element, expanding literals (we know it's ASCIZ) 234c80476e4SDavid E. O'Brien */ 235c80476e4SDavid E. O'Brien static void 236c80476e4SDavid E. O'Brien RefreshPromptpart(buf) 237c80476e4SDavid E. O'Brien Char *buf; 238c80476e4SDavid E. O'Brien { 239c80476e4SDavid E. O'Brien register Char *cp; 240c80476e4SDavid E. O'Brien static unsigned int litnum = 0; 241c80476e4SDavid E. O'Brien if (buf == NULL) 242c80476e4SDavid E. O'Brien { 243c80476e4SDavid E. O'Brien litnum = 0; 244c80476e4SDavid E. O'Brien return; 245c80476e4SDavid E. O'Brien } 246c80476e4SDavid E. O'Brien 247c80476e4SDavid E. O'Brien for (cp = buf; *cp; cp++) { 248c80476e4SDavid E. O'Brien if (*cp & LITERAL) { 249c80476e4SDavid E. O'Brien if (litnum < (sizeof(litptr) / sizeof(litptr[0]))) { 250c80476e4SDavid E. O'Brien litptr[litnum] = cp; 251c80476e4SDavid E. O'Brien #ifdef DEBUG_LITERAL 252c80476e4SDavid E. O'Brien dprintf("litnum = %d, litptr = %x:\r\n", 253c80476e4SDavid E. O'Brien litnum, litptr[litnum]); 254c80476e4SDavid E. O'Brien #endif /* DEBUG_LITERAL */ 255c80476e4SDavid E. O'Brien } 256c80476e4SDavid E. O'Brien while (*cp & LITERAL) 257c80476e4SDavid E. O'Brien cp++; 258c80476e4SDavid E. O'Brien if (*cp) 259c80476e4SDavid E. O'Brien Vdraw((int) (litnum++ | LITERAL)); 260c80476e4SDavid E. O'Brien else { 261c80476e4SDavid E. O'Brien /* 262c80476e4SDavid E. O'Brien * XXX: This is a bug, we lose the last literal, if it is not 263c80476e4SDavid E. O'Brien * followed by a normal character, but it is too hard to fix 264c80476e4SDavid E. O'Brien */ 265c80476e4SDavid E. O'Brien break; 266c80476e4SDavid E. O'Brien } 267c80476e4SDavid E. O'Brien } 268c80476e4SDavid E. O'Brien else 269c80476e4SDavid E. O'Brien Draw(*cp); 270c80476e4SDavid E. O'Brien } 271c80476e4SDavid E. O'Brien } 272c80476e4SDavid E. O'Brien 273c80476e4SDavid E. O'Brien /* 274c80476e4SDavid E. O'Brien * Refresh() 275c80476e4SDavid E. O'Brien * draws the new virtual screen image from the current input 276c80476e4SDavid E. O'Brien * line, then goes line-by-line changing the real image to the new 277c80476e4SDavid E. O'Brien * virtual image. The routine to re-draw a line can be replaced 278c80476e4SDavid E. O'Brien * easily in hopes of a smarter one being placed there. 279c80476e4SDavid E. O'Brien */ 280b2d5d167SMark Peek #ifndef WINNT_NATIVE 281b2d5d167SMark Peek static 282b2d5d167SMark Peek #endif 283b2d5d167SMark Peek int OldvcV = 0; 284b2d5d167SMark Peek 285c80476e4SDavid E. O'Brien void 286c80476e4SDavid E. O'Brien Refresh() 287c80476e4SDavid E. O'Brien { 288c80476e4SDavid E. O'Brien register int cur_line; 289c80476e4SDavid E. O'Brien register Char *cp; 290c80476e4SDavid E. O'Brien int cur_h, cur_v = 0, new_vcv; 291c80476e4SDavid E. O'Brien int rhdiff; 292c80476e4SDavid E. O'Brien Char oldgetting; 293c80476e4SDavid E. O'Brien 294c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 295c80476e4SDavid E. O'Brien dprintf("PromptBuf = :%s:\r\n", short2str(PromptBuf)); 296c80476e4SDavid E. O'Brien dprintf("InputBuf = :%s:\r\n", short2str(InputBuf)); 297c80476e4SDavid E. O'Brien #endif /* DEBUG_REFRESH */ 298c80476e4SDavid E. O'Brien oldgetting = GettingInput; 299c80476e4SDavid E. O'Brien GettingInput = 0; /* avoid re-entrance via SIGWINCH */ 300c80476e4SDavid E. O'Brien 301c80476e4SDavid E. O'Brien /* reset the Vdraw cursor, temporarily draw rprompt to calculate its size */ 302c80476e4SDavid E. O'Brien vcursor_h = 0; 303c80476e4SDavid E. O'Brien vcursor_v = 0; 304c80476e4SDavid E. O'Brien RefreshPromptpart(NULL); 305c80476e4SDavid E. O'Brien RefreshPromptpart(RPromptBuf); 306c80476e4SDavid E. O'Brien rprompt_h = vcursor_h; 307c80476e4SDavid E. O'Brien rprompt_v = vcursor_v; 308c80476e4SDavid E. O'Brien 309c80476e4SDavid E. O'Brien /* reset the Vdraw cursor, draw prompt */ 310c80476e4SDavid E. O'Brien vcursor_h = 0; 311c80476e4SDavid E. O'Brien vcursor_v = 0; 312c80476e4SDavid E. O'Brien RefreshPromptpart(NULL); 313c80476e4SDavid E. O'Brien RefreshPromptpart(PromptBuf); 314c80476e4SDavid E. O'Brien cur_h = -1; /* set flag in case I'm not set */ 315c80476e4SDavid E. O'Brien 316c80476e4SDavid E. O'Brien /* draw the current input buffer */ 317c80476e4SDavid E. O'Brien for (cp = InputBuf; (cp < LastChar); cp++) { 318c80476e4SDavid E. O'Brien if (cp == Cursor) { 319c80476e4SDavid E. O'Brien cur_h = vcursor_h; /* save for later */ 320c80476e4SDavid E. O'Brien cur_v = vcursor_v; 321c80476e4SDavid E. O'Brien } 322c80476e4SDavid E. O'Brien Draw(*cp); 323c80476e4SDavid E. O'Brien } 324c80476e4SDavid E. O'Brien 325c80476e4SDavid E. O'Brien if (cur_h == -1) { /* if I haven't been set yet, I'm at the end */ 326c80476e4SDavid E. O'Brien cur_h = vcursor_h; 327c80476e4SDavid E. O'Brien cur_v = vcursor_v; 328c80476e4SDavid E. O'Brien } 329c80476e4SDavid E. O'Brien 330c80476e4SDavid E. O'Brien rhdiff = TermH - vcursor_h - rprompt_h; 331c80476e4SDavid E. O'Brien if (rprompt_h != 0 && rprompt_v == 0 && vcursor_v == 0 && rhdiff > 1) { 332c80476e4SDavid E. O'Brien /* 333c80476e4SDavid E. O'Brien * have a right-hand side prompt that will fit on 334c80476e4SDavid E. O'Brien * the end of the first line with at least one 335c80476e4SDavid E. O'Brien * character gap to the input buffer. 336c80476e4SDavid E. O'Brien */ 337c80476e4SDavid E. O'Brien while (--rhdiff > 0) /* pad out with spaces */ 338c80476e4SDavid E. O'Brien Draw(' '); 339c80476e4SDavid E. O'Brien RefreshPromptpart(RPromptBuf); 340c80476e4SDavid E. O'Brien } 341c80476e4SDavid E. O'Brien else { 342c80476e4SDavid E. O'Brien rprompt_h = 0; /* flag "not using rprompt" */ 343c80476e4SDavid E. O'Brien rprompt_v = 0; 344c80476e4SDavid E. O'Brien } 345c80476e4SDavid E. O'Brien 346c80476e4SDavid E. O'Brien new_vcv = vcursor_v; /* must be done BEFORE the NUL is written */ 347c80476e4SDavid E. O'Brien Vdraw('\0'); /* put NUL on end */ 348c80476e4SDavid E. O'Brien 349c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 350c80476e4SDavid E. O'Brien dprintf("TermH=%d, vcur_h=%d, vcur_v=%d, Vdisplay[0]=\r\n:%80.80s:\r\n", 351c80476e4SDavid E. O'Brien TermH, vcursor_h, vcursor_v, short2str(Vdisplay[0])); 352c80476e4SDavid E. O'Brien #endif /* DEBUG_REFRESH */ 353c80476e4SDavid E. O'Brien 354c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 355c80476e4SDavid E. O'Brien dprintf("updating %d lines.\r\n", new_vcv); 356c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 357c80476e4SDavid E. O'Brien for (cur_line = 0; cur_line <= new_vcv; cur_line++) { 358c80476e4SDavid E. O'Brien /* NOTE THAT update_line MAY CHANGE Display[cur_line] */ 359c80476e4SDavid E. O'Brien update_line(Display[cur_line], Vdisplay[cur_line], cur_line); 3603b6eaa7bSAndrey A. Chernov #ifdef WINNT_NATIVE 361c80476e4SDavid E. O'Brien flush(); 3623b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */ 363c80476e4SDavid E. O'Brien 364c80476e4SDavid E. O'Brien /* 365c80476e4SDavid E. O'Brien * Copy the new line to be the current one, and pad out with spaces 366c80476e4SDavid E. O'Brien * to the full width of the terminal so that if we try moving the 367c80476e4SDavid E. O'Brien * cursor by writing the character that is at the end of the 368c80476e4SDavid E. O'Brien * screen line, it won't be a NUL or some old leftover stuff. 369c80476e4SDavid E. O'Brien */ 370c80476e4SDavid E. O'Brien cpy_pad_spaces(Display[cur_line], Vdisplay[cur_line], TermH); 371c80476e4SDavid E. O'Brien #ifdef notdef 372c80476e4SDavid E. O'Brien (void) Strncpy(Display[cur_line], Vdisplay[cur_line], (size_t) TermH); 373c80476e4SDavid E. O'Brien Display[cur_line][TermH] = '\0'; /* just in case */ 374c80476e4SDavid E. O'Brien #endif 375c80476e4SDavid E. O'Brien } 376c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 377c80476e4SDavid E. O'Brien dprintf("\r\nvcursor_v = %d, OldvcV = %d, cur_line = %d\r\n", 378c80476e4SDavid E. O'Brien vcursor_v, OldvcV, cur_line); 379c80476e4SDavid E. O'Brien #endif /* DEBUG_REFRESH */ 380c80476e4SDavid E. O'Brien if (OldvcV > new_vcv) { 381c80476e4SDavid E. O'Brien for (; cur_line <= OldvcV; cur_line++) { 382c80476e4SDavid E. O'Brien update_line(Display[cur_line], STRNULL, cur_line); 383c80476e4SDavid E. O'Brien *Display[cur_line] = '\0'; 384c80476e4SDavid E. O'Brien } 385c80476e4SDavid E. O'Brien } 386c80476e4SDavid E. O'Brien OldvcV = new_vcv; /* set for next time */ 387c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 388c80476e4SDavid E. O'Brien dprintf("\r\nCursorH = %d, CursorV = %d, cur_h = %d, cur_v = %d\r\n", 389c80476e4SDavid E. O'Brien CursorH, CursorV, cur_h, cur_v); 390c80476e4SDavid E. O'Brien #endif /* DEBUG_REFRESH */ 3913b6eaa7bSAndrey A. Chernov #ifdef WINNT_NATIVE 392c80476e4SDavid E. O'Brien flush(); 3933b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */ 394c80476e4SDavid E. O'Brien MoveToLine(cur_v); /* go to where the cursor is */ 395c80476e4SDavid E. O'Brien MoveToChar(cur_h); 396c80476e4SDavid E. O'Brien SetAttributes(0); /* Clear all attributes */ 397c80476e4SDavid E. O'Brien flush(); /* send the output... */ 398c80476e4SDavid E. O'Brien GettingInput = oldgetting; /* reset to old value */ 399c80476e4SDavid E. O'Brien } 400c80476e4SDavid E. O'Brien 401c80476e4SDavid E. O'Brien #ifdef notdef 402c80476e4SDavid E. O'Brien GotoBottom() 403c80476e4SDavid E. O'Brien { /* used to go to last used screen line */ 404c80476e4SDavid E. O'Brien MoveToLine(OldvcV); 405c80476e4SDavid E. O'Brien } 406c80476e4SDavid E. O'Brien 407c80476e4SDavid E. O'Brien #endif 408c80476e4SDavid E. O'Brien 409c80476e4SDavid E. O'Brien void 410c80476e4SDavid E. O'Brien PastBottom() 411c80476e4SDavid E. O'Brien { /* used to go to last used screen line */ 412c80476e4SDavid E. O'Brien MoveToLine(OldvcV); 413c80476e4SDavid E. O'Brien (void) putraw('\r'); 414c80476e4SDavid E. O'Brien (void) putraw('\n'); 415c80476e4SDavid E. O'Brien ClearDisp(); 416c80476e4SDavid E. O'Brien flush(); 417c80476e4SDavid E. O'Brien } 418c80476e4SDavid E. O'Brien 419c80476e4SDavid E. O'Brien 420c80476e4SDavid E. O'Brien /* insert num characters of s into d (in front of the character) at dat, 421c80476e4SDavid E. O'Brien maximum length of d is dlen */ 422c80476e4SDavid E. O'Brien static void 423c80476e4SDavid E. O'Brien str_insert(d, dat, dlen, s, num) 424c80476e4SDavid E. O'Brien register Char *d; 425c80476e4SDavid E. O'Brien register int dat, dlen; 426c80476e4SDavid E. O'Brien register Char *s; 427c80476e4SDavid E. O'Brien register int num; 428c80476e4SDavid E. O'Brien { 429c80476e4SDavid E. O'Brien register Char *a, *b; 430c80476e4SDavid E. O'Brien 431c80476e4SDavid E. O'Brien if (num <= 0) 432c80476e4SDavid E. O'Brien return; 433c80476e4SDavid E. O'Brien if (num > dlen - dat) 434c80476e4SDavid E. O'Brien num = dlen - dat; 435c80476e4SDavid E. O'Brien 436c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 437c80476e4SDavid E. O'Brien dprintf("str_insert() starting: %d at %d max %d, d == \"%s\"\n", 438c80476e4SDavid E. O'Brien num, dat, dlen, short2str(d)); 439c80476e4SDavid E. O'Brien dprintf("s == \"%s\"n", short2str(s)); 440c80476e4SDavid E. O'Brien #endif /* DEBUG_REFRESH */ 441c80476e4SDavid E. O'Brien 442c80476e4SDavid E. O'Brien /* open up the space for num chars */ 443c80476e4SDavid E. O'Brien if (num > 0) { 444c80476e4SDavid E. O'Brien b = d + dlen - 1; 445c80476e4SDavid E. O'Brien a = b - num; 446c80476e4SDavid E. O'Brien while (a >= &d[dat]) 447c80476e4SDavid E. O'Brien *b-- = *a--; 448c80476e4SDavid E. O'Brien d[dlen] = '\0'; /* just in case */ 449c80476e4SDavid E. O'Brien } 450c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 451c80476e4SDavid E. O'Brien dprintf("str_insert() after insert: %d at %d max %d, d == \"%s\"\n", 452c80476e4SDavid E. O'Brien num, dat, dlen, short2str(d)); 453c80476e4SDavid E. O'Brien dprintf("s == \"%s\"n", short2str(s)); 454c80476e4SDavid E. O'Brien #endif /* DEBUG_REFRESH */ 455c80476e4SDavid E. O'Brien 456c80476e4SDavid E. O'Brien /* copy the characters */ 457c80476e4SDavid E. O'Brien for (a = d + dat; (a < d + dlen) && (num > 0); num--) 458c80476e4SDavid E. O'Brien *a++ = *s++; 459c80476e4SDavid E. O'Brien 460c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 461c80476e4SDavid E. O'Brien dprintf("str_insert() after copy: %d at %d max %d, d == \"%s\"\n", 462c80476e4SDavid E. O'Brien num, dat, dlen, d, short2str(s)); 463c80476e4SDavid E. O'Brien dprintf("s == \"%s\"n", short2str(s)); 464c80476e4SDavid E. O'Brien #endif /* DEBUG_REFRESH */ 465c80476e4SDavid E. O'Brien } 466c80476e4SDavid E. O'Brien 467c80476e4SDavid E. O'Brien /* delete num characters d at dat, maximum length of d is dlen */ 468c80476e4SDavid E. O'Brien static void 469c80476e4SDavid E. O'Brien str_delete(d, dat, dlen, num) 470c80476e4SDavid E. O'Brien register Char *d; 471c80476e4SDavid E. O'Brien register int dat, dlen, num; 472c80476e4SDavid E. O'Brien { 473c80476e4SDavid E. O'Brien register Char *a, *b; 474c80476e4SDavid E. O'Brien 475c80476e4SDavid E. O'Brien if (num <= 0) 476c80476e4SDavid E. O'Brien return; 477c80476e4SDavid E. O'Brien if (dat + num >= dlen) { 478c80476e4SDavid E. O'Brien d[dat] = '\0'; 479c80476e4SDavid E. O'Brien return; 480c80476e4SDavid E. O'Brien } 481c80476e4SDavid E. O'Brien 482c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 483c80476e4SDavid E. O'Brien dprintf("str_delete() starting: %d at %d max %d, d == \"%s\"\n", 484c80476e4SDavid E. O'Brien num, dat, dlen, short2str(d)); 485c80476e4SDavid E. O'Brien #endif /* DEBUG_REFRESH */ 486c80476e4SDavid E. O'Brien 487c80476e4SDavid E. O'Brien /* open up the space for num chars */ 488c80476e4SDavid E. O'Brien if (num > 0) { 489c80476e4SDavid E. O'Brien b = d + dat; 490c80476e4SDavid E. O'Brien a = b + num; 491c80476e4SDavid E. O'Brien while (a < &d[dlen]) 492c80476e4SDavid E. O'Brien *b++ = *a++; 493c80476e4SDavid E. O'Brien d[dlen] = '\0'; /* just in case */ 494c80476e4SDavid E. O'Brien } 495c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 496c80476e4SDavid E. O'Brien dprintf("str_delete() after delete: %d at %d max %d, d == \"%s\"\n", 497c80476e4SDavid E. O'Brien num, dat, dlen, short2str(d)); 498c80476e4SDavid E. O'Brien #endif /* DEBUG_REFRESH */ 499c80476e4SDavid E. O'Brien } 500c80476e4SDavid E. O'Brien 501c80476e4SDavid E. O'Brien static void 502c80476e4SDavid E. O'Brien str_cp(a, b, n) 503c80476e4SDavid E. O'Brien register Char *a, *b; 504c80476e4SDavid E. O'Brien register int n; 505c80476e4SDavid E. O'Brien { 506c80476e4SDavid E. O'Brien while (n-- && *b) 507c80476e4SDavid E. O'Brien *a++ = *b++; 508c80476e4SDavid E. O'Brien } 509c80476e4SDavid E. O'Brien 510c80476e4SDavid E. O'Brien 511c80476e4SDavid E. O'Brien #if defined(DSPMBYTE) /* BY TAGA Nayuta VERY THANKS */ 512c80476e4SDavid E. O'Brien static Char * 513c80476e4SDavid E. O'Brien update_line_fix_mbyte_point(start, target, d) 514c80476e4SDavid E. O'Brien Char *start, *target; 515c80476e4SDavid E. O'Brien int d; 516c80476e4SDavid E. O'Brien { 517c80476e4SDavid E. O'Brien if (_enable_mbdisp) { 518c80476e4SDavid E. O'Brien while (*start) { 519c80476e4SDavid E. O'Brien if (target == start) 520c80476e4SDavid E. O'Brien break; 521c80476e4SDavid E. O'Brien if (target < start) 522c80476e4SDavid E. O'Brien return target + d; 523c80476e4SDavid E. O'Brien if (Ismbyte1(*start) && Ismbyte2(*(start + 1))) 524c80476e4SDavid E. O'Brien start++; 525c80476e4SDavid E. O'Brien start++; 526c80476e4SDavid E. O'Brien } 527c80476e4SDavid E. O'Brien } 528c80476e4SDavid E. O'Brien return target; 529c80476e4SDavid E. O'Brien } 530c80476e4SDavid E. O'Brien #endif 531c80476e4SDavid E. O'Brien 532c80476e4SDavid E. O'Brien /* **************************************************************** 533c80476e4SDavid E. O'Brien update_line() is based on finding the middle difference of each line 534c80476e4SDavid E. O'Brien on the screen; vis: 535c80476e4SDavid E. O'Brien 536c80476e4SDavid E. O'Brien /old first difference 537c80476e4SDavid E. O'Brien /beginning of line | /old last same /old EOL 538c80476e4SDavid E. O'Brien v v v v 539c80476e4SDavid E. O'Brien old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as 540c80476e4SDavid E. O'Brien new: eddie> Oh, my little buggy says to me, as lurgid as 541c80476e4SDavid E. O'Brien ^ ^ ^ ^ 542c80476e4SDavid E. O'Brien \beginning of line | \new last same \new end of line 543c80476e4SDavid E. O'Brien \new first difference 544c80476e4SDavid E. O'Brien 545c80476e4SDavid E. O'Brien all are character pointers for the sake of speed. Special cases for 546c80476e4SDavid E. O'Brien no differences, as well as for end of line additions must be handled. 547c80476e4SDavid E. O'Brien **************************************************************** */ 548c80476e4SDavid E. O'Brien 549c80476e4SDavid E. O'Brien /* Minimum at which doing an insert it "worth it". This should be about 550c80476e4SDavid E. O'Brien * half the "cost" of going into insert mode, inserting a character, and 551c80476e4SDavid E. O'Brien * going back out. This should really be calculated from the termcap 552c80476e4SDavid E. O'Brien * data... For the moment, a good number for ANSI terminals. 553c80476e4SDavid E. O'Brien */ 554c80476e4SDavid E. O'Brien #define MIN_END_KEEP 4 555c80476e4SDavid E. O'Brien 556c80476e4SDavid E. O'Brien static void /* could be changed to make it smarter */ 557c80476e4SDavid E. O'Brien update_line(old, new, cur_line) 558c80476e4SDavid E. O'Brien register Char *old, *new; 559c80476e4SDavid E. O'Brien int cur_line; 560c80476e4SDavid E. O'Brien { 561c80476e4SDavid E. O'Brien register Char *o, *n, *p, c; 562c80476e4SDavid E. O'Brien Char *ofd, *ols, *oe, *nfd, *nls, *ne; 563c80476e4SDavid E. O'Brien Char *osb, *ose, *nsb, *nse; 564c80476e4SDavid E. O'Brien int fx, sx; 565c80476e4SDavid E. O'Brien 566c80476e4SDavid E. O'Brien /* 567c80476e4SDavid E. O'Brien * find first diff 568c80476e4SDavid E. O'Brien */ 569c80476e4SDavid E. O'Brien for (o = old, n = new; *o && (*o == *n); o++, n++) 570c80476e4SDavid E. O'Brien continue; 571c80476e4SDavid E. O'Brien ofd = o; 572c80476e4SDavid E. O'Brien nfd = n; 573c80476e4SDavid E. O'Brien 574c80476e4SDavid E. O'Brien /* 575c80476e4SDavid E. O'Brien * Find the end of both old and new 576c80476e4SDavid E. O'Brien */ 577c80476e4SDavid E. O'Brien while (*o) 578c80476e4SDavid E. O'Brien o++; 579c80476e4SDavid E. O'Brien /* 580c80476e4SDavid E. O'Brien * Remove any trailing blanks off of the end, being careful not to 581c80476e4SDavid E. O'Brien * back up past the beginning. 582c80476e4SDavid E. O'Brien */ 583c80476e4SDavid E. O'Brien while (ofd < o) { 584c80476e4SDavid E. O'Brien if (o[-1] != ' ') 585c80476e4SDavid E. O'Brien break; 586c80476e4SDavid E. O'Brien o--; 587c80476e4SDavid E. O'Brien } 588c80476e4SDavid E. O'Brien oe = o; 589c80476e4SDavid E. O'Brien *oe = (Char) 0; 590c80476e4SDavid E. O'Brien 591c80476e4SDavid E. O'Brien while (*n) 592c80476e4SDavid E. O'Brien n++; 593c80476e4SDavid E. O'Brien 594c80476e4SDavid E. O'Brien /* remove blanks from end of new */ 595c80476e4SDavid E. O'Brien while (nfd < n) { 596c80476e4SDavid E. O'Brien if (n[-1] != ' ') 597c80476e4SDavid E. O'Brien break; 598c80476e4SDavid E. O'Brien n--; 599c80476e4SDavid E. O'Brien } 600c80476e4SDavid E. O'Brien ne = n; 601c80476e4SDavid E. O'Brien *ne = (Char) 0; 602c80476e4SDavid E. O'Brien 603c80476e4SDavid E. O'Brien /* 604c80476e4SDavid E. O'Brien * if no diff, continue to next line of redraw 605c80476e4SDavid E. O'Brien */ 606c80476e4SDavid E. O'Brien if (*ofd == '\0' && *nfd == '\0') { 607c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 608c80476e4SDavid E. O'Brien dprintf("no difference.\r\n"); 609c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 610c80476e4SDavid E. O'Brien return; 611c80476e4SDavid E. O'Brien } 612c80476e4SDavid E. O'Brien 613c80476e4SDavid E. O'Brien /* 614c80476e4SDavid E. O'Brien * find last same pointer 615c80476e4SDavid E. O'Brien */ 616c80476e4SDavid E. O'Brien while ((o > ofd) && (n > nfd) && (*--o == *--n)) 617c80476e4SDavid E. O'Brien continue; 618c80476e4SDavid E. O'Brien ols = ++o; 619c80476e4SDavid E. O'Brien nls = ++n; 620c80476e4SDavid E. O'Brien 621c80476e4SDavid E. O'Brien /* 622c80476e4SDavid E. O'Brien * find same begining and same end 623c80476e4SDavid E. O'Brien */ 624c80476e4SDavid E. O'Brien osb = ols; 625c80476e4SDavid E. O'Brien nsb = nls; 626c80476e4SDavid E. O'Brien ose = ols; 627c80476e4SDavid E. O'Brien nse = nls; 628c80476e4SDavid E. O'Brien 629c80476e4SDavid E. O'Brien /* 630c80476e4SDavid E. O'Brien * case 1: insert: scan from nfd to nls looking for *ofd 631c80476e4SDavid E. O'Brien */ 632c80476e4SDavid E. O'Brien if (*ofd) { 633c80476e4SDavid E. O'Brien for (c = *ofd, n = nfd; n < nls; n++) { 634c80476e4SDavid E. O'Brien if (c == *n) { 635c80476e4SDavid E. O'Brien for (o = ofd, p = n; p < nls && o < ols && *o == *p; o++, p++) 636c80476e4SDavid E. O'Brien continue; 637c80476e4SDavid E. O'Brien /* 638c80476e4SDavid E. O'Brien * if the new match is longer and it's worth keeping, then we 639c80476e4SDavid E. O'Brien * take it 640c80476e4SDavid E. O'Brien */ 641c80476e4SDavid E. O'Brien if (((nse - nsb) < (p - n)) && (2 * (p - n) > n - nfd)) { 642c80476e4SDavid E. O'Brien nsb = n; 643c80476e4SDavid E. O'Brien nse = p; 644c80476e4SDavid E. O'Brien osb = ofd; 645c80476e4SDavid E. O'Brien ose = o; 646c80476e4SDavid E. O'Brien } 647c80476e4SDavid E. O'Brien } 648c80476e4SDavid E. O'Brien } 649c80476e4SDavid E. O'Brien } 650c80476e4SDavid E. O'Brien 651c80476e4SDavid E. O'Brien /* 652c80476e4SDavid E. O'Brien * case 2: delete: scan from ofd to ols looking for *nfd 653c80476e4SDavid E. O'Brien */ 654c80476e4SDavid E. O'Brien if (*nfd) { 655c80476e4SDavid E. O'Brien for (c = *nfd, o = ofd; o < ols; o++) { 656c80476e4SDavid E. O'Brien if (c == *o) { 657c80476e4SDavid E. O'Brien for (n = nfd, p = o; p < ols && n < nls && *p == *n; p++, n++) 658c80476e4SDavid E. O'Brien continue; 659c80476e4SDavid E. O'Brien /* 660c80476e4SDavid E. O'Brien * if the new match is longer and it's worth keeping, then we 661c80476e4SDavid E. O'Brien * take it 662c80476e4SDavid E. O'Brien */ 663c80476e4SDavid E. O'Brien if (((ose - osb) < (p - o)) && (2 * (p - o) > o - ofd)) { 664c80476e4SDavid E. O'Brien nsb = nfd; 665c80476e4SDavid E. O'Brien nse = n; 666c80476e4SDavid E. O'Brien osb = o; 667c80476e4SDavid E. O'Brien ose = p; 668c80476e4SDavid E. O'Brien } 669c80476e4SDavid E. O'Brien } 670c80476e4SDavid E. O'Brien } 671c80476e4SDavid E. O'Brien } 672c80476e4SDavid E. O'Brien #ifdef notdef 673c80476e4SDavid E. O'Brien /* 674c80476e4SDavid E. O'Brien * If `last same' is before `same end' re-adjust 675c80476e4SDavid E. O'Brien */ 676c80476e4SDavid E. O'Brien if (ols < ose) 677c80476e4SDavid E. O'Brien ols = ose; 678c80476e4SDavid E. O'Brien if (nls < nse) 679c80476e4SDavid E. O'Brien nls = nse; 680c80476e4SDavid E. O'Brien #endif 681c80476e4SDavid E. O'Brien 682c80476e4SDavid E. O'Brien /* 683c80476e4SDavid E. O'Brien * Pragmatics I: If old trailing whitespace or not enough characters to 684c80476e4SDavid E. O'Brien * save to be worth it, then don't save the last same info. 685c80476e4SDavid E. O'Brien */ 686c80476e4SDavid E. O'Brien if ((oe - ols) < MIN_END_KEEP) { 687c80476e4SDavid E. O'Brien ols = oe; 688c80476e4SDavid E. O'Brien nls = ne; 689c80476e4SDavid E. O'Brien } 690c80476e4SDavid E. O'Brien 691c80476e4SDavid E. O'Brien /* 692c80476e4SDavid E. O'Brien * Pragmatics II: if the terminal isn't smart enough, make the data dumber 693c80476e4SDavid E. O'Brien * so the smart update doesn't try anything fancy 694c80476e4SDavid E. O'Brien */ 695c80476e4SDavid E. O'Brien 696c80476e4SDavid E. O'Brien /* 697c80476e4SDavid E. O'Brien * fx is the number of characters we need to insert/delete: in the 698c80476e4SDavid E. O'Brien * beginning to bring the two same begins together 699c80476e4SDavid E. O'Brien */ 700c80476e4SDavid E. O'Brien fx = (int) ((nsb - nfd) - (osb - ofd)); 701c80476e4SDavid E. O'Brien /* 702c80476e4SDavid E. O'Brien * sx is the number of characters we need to insert/delete: in the end to 703c80476e4SDavid E. O'Brien * bring the two same last parts together 704c80476e4SDavid E. O'Brien */ 705c80476e4SDavid E. O'Brien sx = (int) ((nls - nse) - (ols - ose)); 706c80476e4SDavid E. O'Brien 707c80476e4SDavid E. O'Brien if (!T_CanIns) { 708c80476e4SDavid E. O'Brien if (fx > 0) { 709c80476e4SDavid E. O'Brien osb = ols; 710c80476e4SDavid E. O'Brien ose = ols; 711c80476e4SDavid E. O'Brien nsb = nls; 712c80476e4SDavid E. O'Brien nse = nls; 713c80476e4SDavid E. O'Brien } 714c80476e4SDavid E. O'Brien if (sx > 0) { 715c80476e4SDavid E. O'Brien ols = oe; 716c80476e4SDavid E. O'Brien nls = ne; 717c80476e4SDavid E. O'Brien } 718c80476e4SDavid E. O'Brien if ((ols - ofd) < (nls - nfd)) { 719c80476e4SDavid E. O'Brien ols = oe; 720c80476e4SDavid E. O'Brien nls = ne; 721c80476e4SDavid E. O'Brien } 722c80476e4SDavid E. O'Brien } 723c80476e4SDavid E. O'Brien if (!T_CanDel) { 724c80476e4SDavid E. O'Brien if (fx < 0) { 725c80476e4SDavid E. O'Brien osb = ols; 726c80476e4SDavid E. O'Brien ose = ols; 727c80476e4SDavid E. O'Brien nsb = nls; 728c80476e4SDavid E. O'Brien nse = nls; 729c80476e4SDavid E. O'Brien } 730c80476e4SDavid E. O'Brien if (sx < 0) { 731c80476e4SDavid E. O'Brien ols = oe; 732c80476e4SDavid E. O'Brien nls = ne; 733c80476e4SDavid E. O'Brien } 734c80476e4SDavid E. O'Brien if ((ols - ofd) > (nls - nfd)) { 735c80476e4SDavid E. O'Brien ols = oe; 736c80476e4SDavid E. O'Brien nls = ne; 737c80476e4SDavid E. O'Brien } 738c80476e4SDavid E. O'Brien } 739c80476e4SDavid E. O'Brien 740c80476e4SDavid E. O'Brien /* 741c80476e4SDavid E. O'Brien * Pragmatics III: make sure the middle shifted pointers are correct if 742c80476e4SDavid E. O'Brien * they don't point to anything (we may have moved ols or nls). 743c80476e4SDavid E. O'Brien */ 744c80476e4SDavid E. O'Brien /* if the change isn't worth it, don't bother */ 745c80476e4SDavid E. O'Brien /* was: if (osb == ose) */ 746c80476e4SDavid E. O'Brien if ((ose - osb) < MIN_END_KEEP) { 747c80476e4SDavid E. O'Brien osb = ols; 748c80476e4SDavid E. O'Brien ose = ols; 749c80476e4SDavid E. O'Brien nsb = nls; 750c80476e4SDavid E. O'Brien nse = nls; 751c80476e4SDavid E. O'Brien } 752c80476e4SDavid E. O'Brien 753c80476e4SDavid E. O'Brien /* 754c80476e4SDavid E. O'Brien * Now that we are done with pragmatics we recompute fx, sx 755c80476e4SDavid E. O'Brien */ 756c80476e4SDavid E. O'Brien fx = (int) ((nsb - nfd) - (osb - ofd)); 757c80476e4SDavid E. O'Brien sx = (int) ((nls - nse) - (ols - ose)); 758c80476e4SDavid E. O'Brien 759c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 760c80476e4SDavid E. O'Brien dprintf("\n"); 761c80476e4SDavid E. O'Brien dprintf("ofd %d, osb %d, ose %d, ols %d, oe %d\n", 762c80476e4SDavid E. O'Brien ofd - old, osb - old, ose - old, ols - old, oe - old); 763c80476e4SDavid E. O'Brien dprintf("nfd %d, nsb %d, nse %d, nls %d, ne %d\n", 764c80476e4SDavid E. O'Brien nfd - new, nsb - new, nse - new, nls - new, ne - new); 765c80476e4SDavid E. O'Brien dprintf("xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n"); 766c80476e4SDavid E. O'Brien dprintf("xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n"); 767c80476e4SDavid E. O'Brien dprintstr("old- oe", old, oe); 768c80476e4SDavid E. O'Brien dprintstr("new- ne", new, ne); 769c80476e4SDavid E. O'Brien dprintstr("old-ofd", old, ofd); 770c80476e4SDavid E. O'Brien dprintstr("new-nfd", new, nfd); 771c80476e4SDavid E. O'Brien dprintstr("ofd-osb", ofd, osb); 772c80476e4SDavid E. O'Brien dprintstr("nfd-nsb", nfd, nsb); 773c80476e4SDavid E. O'Brien dprintstr("osb-ose", osb, ose); 774c80476e4SDavid E. O'Brien dprintstr("nsb-nse", nsb, nse); 775c80476e4SDavid E. O'Brien dprintstr("ose-ols", ose, ols); 776c80476e4SDavid E. O'Brien dprintstr("nse-nls", nse, nls); 777c80476e4SDavid E. O'Brien dprintstr("ols- oe", ols, oe); 778c80476e4SDavid E. O'Brien dprintstr("nls- ne", nls, ne); 779c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 780c80476e4SDavid E. O'Brien 781c80476e4SDavid E. O'Brien /* 782c80476e4SDavid E. O'Brien * CursorV to this line cur_line MUST be in this routine so that if we 783c80476e4SDavid E. O'Brien * don't have to change the line, we don't move to it. CursorH to first 784c80476e4SDavid E. O'Brien * diff char 785c80476e4SDavid E. O'Brien */ 786c80476e4SDavid E. O'Brien MoveToLine(cur_line); 787c80476e4SDavid E. O'Brien 788c80476e4SDavid E. O'Brien #if defined(DSPMBYTE) /* BY TAGA Nayuta VERY THANKS */ 789c80476e4SDavid E. O'Brien ofd = update_line_fix_mbyte_point(old, ofd, -1); 790c80476e4SDavid E. O'Brien osb = update_line_fix_mbyte_point(old, osb, 1); 791c80476e4SDavid E. O'Brien ose = update_line_fix_mbyte_point(old, ose, -1); 792c80476e4SDavid E. O'Brien ols = update_line_fix_mbyte_point(old, ols, 1); 793c80476e4SDavid E. O'Brien nfd = update_line_fix_mbyte_point(new, nfd, -1); 794c80476e4SDavid E. O'Brien nsb = update_line_fix_mbyte_point(new, nsb, 1); 795c80476e4SDavid E. O'Brien nse = update_line_fix_mbyte_point(new, nse, -1); 796c80476e4SDavid E. O'Brien nls = update_line_fix_mbyte_point(new, nls, 1); 797c80476e4SDavid E. O'Brien #endif 798c80476e4SDavid E. O'Brien 799c80476e4SDavid E. O'Brien /* 800c80476e4SDavid E. O'Brien * at this point we have something like this: 801c80476e4SDavid E. O'Brien * 802c80476e4SDavid E. O'Brien * /old /ofd /osb /ose /ols /oe 803c80476e4SDavid E. O'Brien * v.....................v v..................v v........v 804c80476e4SDavid E. O'Brien * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as 805c80476e4SDavid E. O'Brien * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as 806c80476e4SDavid E. O'Brien * ^.....................^ ^..................^ ^........^ 807c80476e4SDavid E. O'Brien * \new \nfd \nsb \nse \nls \ne 808c80476e4SDavid E. O'Brien * 809c80476e4SDavid E. O'Brien * fx is the difference in length between the the chars between nfd and 810c80476e4SDavid E. O'Brien * nsb, and the chars between ofd and osb, and is thus the number of 811c80476e4SDavid E. O'Brien * characters to delete if < 0 (new is shorter than old, as above), 812c80476e4SDavid E. O'Brien * or insert (new is longer than short). 813c80476e4SDavid E. O'Brien * 814c80476e4SDavid E. O'Brien * sx is the same for the second differences. 815c80476e4SDavid E. O'Brien */ 816c80476e4SDavid E. O'Brien 817c80476e4SDavid E. O'Brien /* 818c80476e4SDavid E. O'Brien * if we have a net insert on the first difference, AND inserting the net 819c80476e4SDavid E. O'Brien * amount ((nsb-nfd) - (osb-ofd)) won't push the last useful character 820c80476e4SDavid E. O'Brien * (which is ne if nls != ne, otherwise is nse) off the edge of the screen 821c80476e4SDavid E. O'Brien * (TermH - 1) else we do the deletes first so that we keep everything we 822c80476e4SDavid E. O'Brien * need to. 823c80476e4SDavid E. O'Brien */ 824c80476e4SDavid E. O'Brien 825c80476e4SDavid E. O'Brien /* 826c80476e4SDavid E. O'Brien * if the last same is the same like the end, there is no last same part, 827c80476e4SDavid E. O'Brien * otherwise we want to keep the last same part set p to the last useful 828c80476e4SDavid E. O'Brien * old character 829c80476e4SDavid E. O'Brien */ 830c80476e4SDavid E. O'Brien p = (ols != oe) ? oe : ose; 831c80476e4SDavid E. O'Brien 832c80476e4SDavid E. O'Brien /* 833c80476e4SDavid E. O'Brien * if (There is a diffence in the beginning) && (we need to insert 834c80476e4SDavid E. O'Brien * characters) && (the number of characters to insert is less than the term 835c80476e4SDavid E. O'Brien * width) We need to do an insert! else if (we need to delete characters) 836c80476e4SDavid E. O'Brien * We need to delete characters! else No insert or delete 837c80476e4SDavid E. O'Brien */ 838c80476e4SDavid E. O'Brien if ((nsb != nfd) && fx > 0 && ((p - old) + fx < TermH)) { 839c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 840c80476e4SDavid E. O'Brien dprintf("first diff insert at %d...\r\n", nfd - new); 841c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 842c80476e4SDavid E. O'Brien /* 843c80476e4SDavid E. O'Brien * Move to the first char to insert, where the first diff is. 844c80476e4SDavid E. O'Brien */ 845c80476e4SDavid E. O'Brien MoveToChar(nfd - new); 846c80476e4SDavid E. O'Brien /* 847c80476e4SDavid E. O'Brien * Check if we have stuff to keep at end 848c80476e4SDavid E. O'Brien */ 849c80476e4SDavid E. O'Brien if (nsb != ne) { 850c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 851c80476e4SDavid E. O'Brien dprintf("with stuff to keep at end\r\n"); 852c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 853c80476e4SDavid E. O'Brien /* 854c80476e4SDavid E. O'Brien * insert fx chars of new starting at nfd 855c80476e4SDavid E. O'Brien */ 856c80476e4SDavid E. O'Brien if (fx > 0) { 857c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 858c80476e4SDavid E. O'Brien if (!T_CanIns) 859c80476e4SDavid E. O'Brien dprintf(" ERROR: cannot insert in early first diff\n"); 860c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 861c80476e4SDavid E. O'Brien Insert_write(nfd, fx); 862c80476e4SDavid E. O'Brien str_insert(old, (int) (ofd - old), TermH, nfd, fx); 863c80476e4SDavid E. O'Brien } 864c80476e4SDavid E. O'Brien /* 865c80476e4SDavid E. O'Brien * write (nsb-nfd) - fx chars of new starting at (nfd + fx) 866c80476e4SDavid E. O'Brien */ 867c80476e4SDavid E. O'Brien so_write(nfd + fx, (nsb - nfd) - fx); 868c80476e4SDavid E. O'Brien str_cp(ofd + fx, nfd + fx, (int) ((nsb - nfd) - fx)); 869c80476e4SDavid E. O'Brien } 870c80476e4SDavid E. O'Brien else { 871c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 872c80476e4SDavid E. O'Brien dprintf("without anything to save\r\n"); 873c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 874c80476e4SDavid E. O'Brien so_write(nfd, (nsb - nfd)); 875c80476e4SDavid E. O'Brien str_cp(ofd, nfd, (int) (nsb - nfd)); 876c80476e4SDavid E. O'Brien /* 877c80476e4SDavid E. O'Brien * Done 878c80476e4SDavid E. O'Brien */ 879c80476e4SDavid E. O'Brien return; 880c80476e4SDavid E. O'Brien } 881c80476e4SDavid E. O'Brien } 882c80476e4SDavid E. O'Brien else if (fx < 0) { 883c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 884c80476e4SDavid E. O'Brien dprintf("first diff delete at %d...\r\n", ofd - old); 885c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 886c80476e4SDavid E. O'Brien /* 887c80476e4SDavid E. O'Brien * move to the first char to delete where the first diff is 888c80476e4SDavid E. O'Brien */ 889c80476e4SDavid E. O'Brien MoveToChar(ofd - old); 890c80476e4SDavid E. O'Brien /* 891c80476e4SDavid E. O'Brien * Check if we have stuff to save 892c80476e4SDavid E. O'Brien */ 893c80476e4SDavid E. O'Brien if (osb != oe) { 894c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 895c80476e4SDavid E. O'Brien dprintf("with stuff to save at end\r\n"); 896c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 897c80476e4SDavid E. O'Brien /* 898c80476e4SDavid E. O'Brien * fx is less than zero *always* here but we check for code 899c80476e4SDavid E. O'Brien * symmetry 900c80476e4SDavid E. O'Brien */ 901c80476e4SDavid E. O'Brien if (fx < 0) { 902c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 903c80476e4SDavid E. O'Brien if (!T_CanDel) 904c80476e4SDavid E. O'Brien dprintf(" ERROR: cannot delete in first diff\n"); 905c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 906c80476e4SDavid E. O'Brien DeleteChars(-fx); 907c80476e4SDavid E. O'Brien str_delete(old, (int) (ofd - old), TermH, -fx); 908c80476e4SDavid E. O'Brien } 909c80476e4SDavid E. O'Brien /* 910c80476e4SDavid E. O'Brien * write (nsb-nfd) chars of new starting at nfd 911c80476e4SDavid E. O'Brien */ 912c80476e4SDavid E. O'Brien so_write(nfd, (nsb - nfd)); 913c80476e4SDavid E. O'Brien str_cp(ofd, nfd, (int) (nsb - nfd)); 914c80476e4SDavid E. O'Brien 915c80476e4SDavid E. O'Brien } 916c80476e4SDavid E. O'Brien else { 917c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 918c80476e4SDavid E. O'Brien dprintf("but with nothing left to save\r\n"); 919c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 920c80476e4SDavid E. O'Brien /* 921c80476e4SDavid E. O'Brien * write (nsb-nfd) chars of new starting at nfd 922c80476e4SDavid E. O'Brien */ 923c80476e4SDavid E. O'Brien so_write(nfd, (nsb - nfd)); 924c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 925c80476e4SDavid E. O'Brien dprintf("cleareol %d\n", (oe - old) - (ne - new)); 926c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 9273b6eaa7bSAndrey A. Chernov #ifndef WINNT_NATIVE 928c80476e4SDavid E. O'Brien ClearEOL((oe - old) - (ne - new)); 929c80476e4SDavid E. O'Brien #else 930c80476e4SDavid E. O'Brien /* 931c80476e4SDavid E. O'Brien * The calculation above does not work too well on NT 932c80476e4SDavid E. O'Brien */ 933c80476e4SDavid E. O'Brien ClearEOL(TermH - CursorH); 9343b6eaa7bSAndrey A. Chernov #endif /*WINNT_NATIVE*/ 935c80476e4SDavid E. O'Brien /* 936c80476e4SDavid E. O'Brien * Done 937c80476e4SDavid E. O'Brien */ 938c80476e4SDavid E. O'Brien return; 939c80476e4SDavid E. O'Brien } 940c80476e4SDavid E. O'Brien } 941c80476e4SDavid E. O'Brien else 942c80476e4SDavid E. O'Brien fx = 0; 943c80476e4SDavid E. O'Brien 944c80476e4SDavid E. O'Brien if (sx < 0) { 945c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 946c80476e4SDavid E. O'Brien dprintf("second diff delete at %d...\r\n", (ose - old) + fx); 947c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 948c80476e4SDavid E. O'Brien /* 949c80476e4SDavid E. O'Brien * Check if we have stuff to delete 950c80476e4SDavid E. O'Brien */ 951c80476e4SDavid E. O'Brien /* 952c80476e4SDavid E. O'Brien * fx is the number of characters inserted (+) or deleted (-) 953c80476e4SDavid E. O'Brien */ 954c80476e4SDavid E. O'Brien 955c80476e4SDavid E. O'Brien MoveToChar((ose - old) + fx); 956c80476e4SDavid E. O'Brien /* 957c80476e4SDavid E. O'Brien * Check if we have stuff to save 958c80476e4SDavid E. O'Brien */ 959c80476e4SDavid E. O'Brien if (ols != oe) { 960c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 961c80476e4SDavid E. O'Brien dprintf("with stuff to save at end\r\n"); 962c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 963c80476e4SDavid E. O'Brien /* 964c80476e4SDavid E. O'Brien * Again a duplicate test. 965c80476e4SDavid E. O'Brien */ 966c80476e4SDavid E. O'Brien if (sx < 0) { 967c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 968c80476e4SDavid E. O'Brien if (!T_CanDel) 969c80476e4SDavid E. O'Brien dprintf(" ERROR: cannot delete in second diff\n"); 970c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 971c80476e4SDavid E. O'Brien DeleteChars(-sx); 972c80476e4SDavid E. O'Brien } 973c80476e4SDavid E. O'Brien 974c80476e4SDavid E. O'Brien /* 975c80476e4SDavid E. O'Brien * write (nls-nse) chars of new starting at nse 976c80476e4SDavid E. O'Brien */ 977c80476e4SDavid E. O'Brien so_write(nse, (nls - nse)); 978c80476e4SDavid E. O'Brien } 979c80476e4SDavid E. O'Brien else { 980c80476e4SDavid E. O'Brien int olen = (int) (oe - old + fx); 981c80476e4SDavid E. O'Brien if (olen > TermH) 982c80476e4SDavid E. O'Brien olen = TermH; 983c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 984c80476e4SDavid E. O'Brien dprintf("but with nothing left to save\r\n"); 985c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 986c80476e4SDavid E. O'Brien so_write(nse, (nls - nse)); 987c80476e4SDavid E. O'Brien #ifdef DEBUG_REFRESH 988c80476e4SDavid E. O'Brien dprintf("cleareol %d\n", olen - (ne - new)); 989c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 9903b6eaa7bSAndrey A. Chernov #ifndef WINNT_NATIVE 991c80476e4SDavid E. O'Brien ClearEOL(olen - (ne - new)); 992c80476e4SDavid E. O'Brien #else 993c80476e4SDavid E. O'Brien /* 994c80476e4SDavid E. O'Brien * The calculation above does not work too well on NT 995c80476e4SDavid E. O'Brien */ 996c80476e4SDavid E. O'Brien ClearEOL(TermH - CursorH); 9973b6eaa7bSAndrey A. Chernov #endif /*WINNT_NATIVE*/ 998c80476e4SDavid E. O'Brien } 999c80476e4SDavid E. O'Brien } 1000c80476e4SDavid E. O'Brien 1001c80476e4SDavid E. O'Brien /* 1002c80476e4SDavid E. O'Brien * if we have a first insert AND WE HAVEN'T ALREADY DONE IT... 1003c80476e4SDavid E. O'Brien */ 1004c80476e4SDavid E. O'Brien if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) { 1005c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 1006c80476e4SDavid E. O'Brien dprintf("late first diff insert at %d...\r\n", nfd - new); 1007c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 1008c80476e4SDavid E. O'Brien 1009c80476e4SDavid E. O'Brien MoveToChar(nfd - new); 1010c80476e4SDavid E. O'Brien /* 1011c80476e4SDavid E. O'Brien * Check if we have stuff to keep at the end 1012c80476e4SDavid E. O'Brien */ 1013c80476e4SDavid E. O'Brien if (nsb != ne) { 1014c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 1015c80476e4SDavid E. O'Brien dprintf("with stuff to keep at end\r\n"); 1016c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 1017c80476e4SDavid E. O'Brien /* 1018c80476e4SDavid E. O'Brien * We have to recalculate fx here because we set it 1019c80476e4SDavid E. O'Brien * to zero above as a flag saying that we hadn't done 1020c80476e4SDavid E. O'Brien * an early first insert. 1021c80476e4SDavid E. O'Brien */ 1022c80476e4SDavid E. O'Brien fx = (int) ((nsb - nfd) - (osb - ofd)); 1023c80476e4SDavid E. O'Brien if (fx > 0) { 1024c80476e4SDavid E. O'Brien /* 1025c80476e4SDavid E. O'Brien * insert fx chars of new starting at nfd 1026c80476e4SDavid E. O'Brien */ 1027c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 1028c80476e4SDavid E. O'Brien if (!T_CanIns) 1029c80476e4SDavid E. O'Brien dprintf(" ERROR: cannot insert in late first diff\n"); 1030c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 1031c80476e4SDavid E. O'Brien Insert_write(nfd, fx); 1032c80476e4SDavid E. O'Brien str_insert(old, (int) (ofd - old), TermH, nfd, fx); 1033c80476e4SDavid E. O'Brien } 1034c80476e4SDavid E. O'Brien 1035c80476e4SDavid E. O'Brien /* 1036c80476e4SDavid E. O'Brien * write (nsb-nfd) - fx chars of new starting at (nfd + fx) 1037c80476e4SDavid E. O'Brien */ 1038c80476e4SDavid E. O'Brien so_write(nfd + fx, (nsb - nfd) - fx); 1039c80476e4SDavid E. O'Brien str_cp(ofd + fx, nfd + fx, (int) ((nsb - nfd) - fx)); 1040c80476e4SDavid E. O'Brien } 1041c80476e4SDavid E. O'Brien else { 1042c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 1043c80476e4SDavid E. O'Brien dprintf("without anything to save\r\n"); 1044c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 1045c80476e4SDavid E. O'Brien so_write(nfd, (nsb - nfd)); 1046c80476e4SDavid E. O'Brien str_cp(ofd, nfd, (int) (nsb - nfd)); 1047c80476e4SDavid E. O'Brien } 1048c80476e4SDavid E. O'Brien } 1049c80476e4SDavid E. O'Brien 1050c80476e4SDavid E. O'Brien /* 1051c80476e4SDavid E. O'Brien * line is now NEW up to nse 1052c80476e4SDavid E. O'Brien */ 1053c80476e4SDavid E. O'Brien if (sx >= 0) { 1054c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 1055c80476e4SDavid E. O'Brien dprintf("second diff insert at %d...\r\n", nse - new); 1056c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 1057c80476e4SDavid E. O'Brien MoveToChar(nse - new); 1058c80476e4SDavid E. O'Brien if (ols != oe) { 1059c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 1060c80476e4SDavid E. O'Brien dprintf("with stuff to keep at end\r\n"); 1061c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 1062c80476e4SDavid E. O'Brien if (sx > 0) { 1063c80476e4SDavid E. O'Brien /* insert sx chars of new starting at nse */ 1064c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 1065c80476e4SDavid E. O'Brien if (!T_CanIns) 1066c80476e4SDavid E. O'Brien dprintf(" ERROR: cannot insert in second diff\n"); 1067c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 1068c80476e4SDavid E. O'Brien Insert_write(nse, sx); 1069c80476e4SDavid E. O'Brien } 1070c80476e4SDavid E. O'Brien 1071c80476e4SDavid E. O'Brien /* 1072c80476e4SDavid E. O'Brien * write (nls-nse) - sx chars of new starting at (nse + sx) 1073c80476e4SDavid E. O'Brien */ 1074c80476e4SDavid E. O'Brien so_write(nse + sx, (nls - nse) - sx); 1075c80476e4SDavid E. O'Brien } 1076c80476e4SDavid E. O'Brien else { 1077c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 1078c80476e4SDavid E. O'Brien dprintf("without anything to save\r\n"); 1079c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 1080c80476e4SDavid E. O'Brien so_write(nse, (nls - nse)); 1081c80476e4SDavid E. O'Brien 1082c80476e4SDavid E. O'Brien /* 1083c80476e4SDavid E. O'Brien * No need to do a clear-to-end here because we were doing 1084c80476e4SDavid E. O'Brien * a second insert, so we will have over written all of the 1085c80476e4SDavid E. O'Brien * old string. 1086c80476e4SDavid E. O'Brien */ 1087c80476e4SDavid E. O'Brien } 1088c80476e4SDavid E. O'Brien } 1089c80476e4SDavid E. O'Brien #ifdef DEBUG_UPDATE 1090c80476e4SDavid E. O'Brien dprintf("done.\r\n"); 1091c80476e4SDavid E. O'Brien #endif /* DEBUG_UPDATE */ 1092c80476e4SDavid E. O'Brien } 1093c80476e4SDavid E. O'Brien 1094c80476e4SDavid E. O'Brien 1095c80476e4SDavid E. O'Brien static void 1096c80476e4SDavid E. O'Brien cpy_pad_spaces(dst, src, width) 1097c80476e4SDavid E. O'Brien register Char *dst, *src; 1098c80476e4SDavid E. O'Brien register int width; 1099c80476e4SDavid E. O'Brien { 1100c80476e4SDavid E. O'Brien register int i; 1101c80476e4SDavid E. O'Brien 1102c80476e4SDavid E. O'Brien for (i = 0; i < width; i++) { 1103c80476e4SDavid E. O'Brien if (*src == (Char) 0) 1104c80476e4SDavid E. O'Brien break; 1105c80476e4SDavid E. O'Brien *dst++ = *src++; 1106c80476e4SDavid E. O'Brien } 1107c80476e4SDavid E. O'Brien 1108c80476e4SDavid E. O'Brien while (i < width) { 1109c80476e4SDavid E. O'Brien *dst++ = ' '; 1110c80476e4SDavid E. O'Brien i++; 1111c80476e4SDavid E. O'Brien } 1112c80476e4SDavid E. O'Brien *dst = (Char) 0; 1113c80476e4SDavid E. O'Brien } 1114c80476e4SDavid E. O'Brien 1115c80476e4SDavid E. O'Brien void 1116c80476e4SDavid E. O'Brien RefCursor() 1117c80476e4SDavid E. O'Brien { /* only move to new cursor pos */ 1118c80476e4SDavid E. O'Brien register Char *cp, c; 1119c80476e4SDavid E. O'Brien register int h, th, v; 1120c80476e4SDavid E. O'Brien 1121c80476e4SDavid E. O'Brien /* first we must find where the cursor is... */ 1122c80476e4SDavid E. O'Brien h = 0; 1123c80476e4SDavid E. O'Brien v = 0; 1124c80476e4SDavid E. O'Brien th = TermH; /* optimize for speed */ 1125c80476e4SDavid E. O'Brien 1126c80476e4SDavid E. O'Brien for (cp = PromptBuf; *cp; cp++) { /* do prompt */ 1127c80476e4SDavid E. O'Brien if (*cp & LITERAL) 1128c80476e4SDavid E. O'Brien continue; 1129c80476e4SDavid E. O'Brien c = *cp & CHAR; /* extra speed plus strip the inverse */ 1130c80476e4SDavid E. O'Brien h++; /* all chars at least this long */ 1131c80476e4SDavid E. O'Brien 1132c80476e4SDavid E. O'Brien /* from wolman%crltrx.DEC@decwrl.dec.com (Alec Wolman) */ 1133c80476e4SDavid E. O'Brien /* lets handle newline as part of the prompt */ 1134c80476e4SDavid E. O'Brien 1135c80476e4SDavid E. O'Brien if (c == '\n') { 1136c80476e4SDavid E. O'Brien h = 0; 1137c80476e4SDavid E. O'Brien v++; 1138c80476e4SDavid E. O'Brien } 1139c80476e4SDavid E. O'Brien else { 1140c80476e4SDavid E. O'Brien if (c == '\t') { /* if a tab, to next tab stop */ 1141c80476e4SDavid E. O'Brien while (h & 07) { 1142c80476e4SDavid E. O'Brien h++; 1143c80476e4SDavid E. O'Brien } 1144c80476e4SDavid E. O'Brien } 1145c80476e4SDavid E. O'Brien else if (Iscntrl(c)) { /* if control char */ 1146c80476e4SDavid E. O'Brien h++; 1147c80476e4SDavid E. O'Brien if (h > th) { /* if overflow, compensate */ 1148c80476e4SDavid E. O'Brien h = 1; 1149c80476e4SDavid E. O'Brien v++; 1150c80476e4SDavid E. O'Brien } 1151c80476e4SDavid E. O'Brien } 1152c80476e4SDavid E. O'Brien else if (!Isprint(c)) { 1153c80476e4SDavid E. O'Brien h += 3; 1154c80476e4SDavid E. O'Brien if (h > th) { /* if overflow, compensate */ 1155c80476e4SDavid E. O'Brien h = h - th; 1156c80476e4SDavid E. O'Brien v++; 1157c80476e4SDavid E. O'Brien } 1158c80476e4SDavid E. O'Brien } 1159c80476e4SDavid E. O'Brien } 1160c80476e4SDavid E. O'Brien 1161c80476e4SDavid E. O'Brien if (h >= th) { /* check, extra long tabs picked up here also */ 1162c80476e4SDavid E. O'Brien h = 0; 1163c80476e4SDavid E. O'Brien v++; 1164c80476e4SDavid E. O'Brien } 1165c80476e4SDavid E. O'Brien } 1166c80476e4SDavid E. O'Brien 1167c80476e4SDavid E. O'Brien for (cp = InputBuf; cp < Cursor; cp++) { /* do input buffer to Cursor */ 1168c80476e4SDavid E. O'Brien c = *cp & CHAR; /* extra speed plus strip the inverse */ 1169c80476e4SDavid E. O'Brien h++; /* all chars at least this long */ 1170c80476e4SDavid E. O'Brien 1171c80476e4SDavid E. O'Brien if (c == '\n') { /* handle newline in data part too */ 1172c80476e4SDavid E. O'Brien h = 0; 1173c80476e4SDavid E. O'Brien v++; 1174c80476e4SDavid E. O'Brien } 1175c80476e4SDavid E. O'Brien else { 1176c80476e4SDavid E. O'Brien if (c == '\t') { /* if a tab, to next tab stop */ 1177c80476e4SDavid E. O'Brien while (h & 07) { 1178c80476e4SDavid E. O'Brien h++; 1179c80476e4SDavid E. O'Brien } 1180c80476e4SDavid E. O'Brien } 1181c80476e4SDavid E. O'Brien else if (Iscntrl(c)) { /* if control char */ 1182c80476e4SDavid E. O'Brien h++; 1183c80476e4SDavid E. O'Brien if (h > th) { /* if overflow, compensate */ 1184c80476e4SDavid E. O'Brien h = 1; 1185c80476e4SDavid E. O'Brien v++; 1186c80476e4SDavid E. O'Brien } 1187c80476e4SDavid E. O'Brien } 1188c80476e4SDavid E. O'Brien else if (!Isprint(c)) { 1189c80476e4SDavid E. O'Brien h += 3; 1190c80476e4SDavid E. O'Brien if (h > th) { /* if overflow, compensate */ 1191c80476e4SDavid E. O'Brien h = h - th; 1192c80476e4SDavid E. O'Brien v++; 1193c80476e4SDavid E. O'Brien } 1194c80476e4SDavid E. O'Brien } 1195c80476e4SDavid E. O'Brien } 1196c80476e4SDavid E. O'Brien 1197c80476e4SDavid E. O'Brien if (h >= th) { /* check, extra long tabs picked up here also */ 1198c80476e4SDavid E. O'Brien h = 0; 1199c80476e4SDavid E. O'Brien v++; 1200c80476e4SDavid E. O'Brien } 1201c80476e4SDavid E. O'Brien } 1202c80476e4SDavid E. O'Brien 1203c80476e4SDavid E. O'Brien /* now go there */ 1204c80476e4SDavid E. O'Brien MoveToLine(v); 1205c80476e4SDavid E. O'Brien MoveToChar(h); 1206c80476e4SDavid E. O'Brien flush(); 1207c80476e4SDavid E. O'Brien } 1208c80476e4SDavid E. O'Brien 1209b2d5d167SMark Peek #ifndef WINTT_NATIVE 1210c80476e4SDavid E. O'Brien static void 1211c80476e4SDavid E. O'Brien PutPlusOne(c) 1212c80476e4SDavid E. O'Brien int c; 1213c80476e4SDavid E. O'Brien { 1214c80476e4SDavid E. O'Brien (void) putraw(c); 1215c80476e4SDavid E. O'Brien Display[CursorV][CursorH++] = (Char) c; 1216c80476e4SDavid E. O'Brien if (CursorH >= TermH) { /* if we must overflow */ 1217c80476e4SDavid E. O'Brien CursorH = 0; 1218c80476e4SDavid E. O'Brien CursorV++; 1219c80476e4SDavid E. O'Brien OldvcV++; 1220c80476e4SDavid E. O'Brien if (T_Margin & MARGIN_AUTO) { 1221c80476e4SDavid E. O'Brien if (T_Margin & MARGIN_MAGIC) { 1222c80476e4SDavid E. O'Brien (void) putraw(' '); 1223c80476e4SDavid E. O'Brien (void) putraw('\b'); 1224c80476e4SDavid E. O'Brien } 1225c80476e4SDavid E. O'Brien } 1226c80476e4SDavid E. O'Brien else { 1227c80476e4SDavid E. O'Brien (void) putraw('\r'); 1228c80476e4SDavid E. O'Brien (void) putraw('\n'); 1229c80476e4SDavid E. O'Brien } 1230c80476e4SDavid E. O'Brien } 1231c80476e4SDavid E. O'Brien } 1232b2d5d167SMark Peek #endif 1233c80476e4SDavid E. O'Brien 1234c80476e4SDavid E. O'Brien void 1235c80476e4SDavid E. O'Brien RefPlusOne() 1236c80476e4SDavid E. O'Brien { /* we added just one char, handle it fast. 1237c80476e4SDavid E. O'Brien * assumes that screen cursor == real cursor */ 1238c80476e4SDavid E. O'Brien register Char c, mc; 1239c80476e4SDavid E. O'Brien 1240c80476e4SDavid E. O'Brien c = Cursor[-1] & CHAR; /* the char we just added */ 1241c80476e4SDavid E. O'Brien 1242c80476e4SDavid E. O'Brien if (c == '\t' || Cursor != LastChar) { 1243c80476e4SDavid E. O'Brien Refresh(); /* too hard to handle */ 1244c80476e4SDavid E. O'Brien return; 1245c80476e4SDavid E. O'Brien } 1246c80476e4SDavid E. O'Brien 1247c80476e4SDavid E. O'Brien if (rprompt_h != 0 && (TermH - CursorH - rprompt_h < 3)) { 1248c80476e4SDavid E. O'Brien Refresh(); /* clear out rprompt if less than one char gap*/ 1249c80476e4SDavid E. O'Brien return; 1250c80476e4SDavid E. O'Brien } /* else (only do at end of line, no TAB) */ 1251c80476e4SDavid E. O'Brien 1252c80476e4SDavid E. O'Brien if (Iscntrl(c)) { /* if control char, do caret */ 12533b6eaa7bSAndrey A. Chernov #ifdef IS_ASCII 1254c80476e4SDavid E. O'Brien mc = (c == '\177') ? '?' : (c | 0100); 1255c80476e4SDavid E. O'Brien PutPlusOne('^'); 1256c80476e4SDavid E. O'Brien PutPlusOne(mc); 12573b6eaa7bSAndrey A. Chernov #else 1258c80476e4SDavid E. O'Brien if (_toascii[c] == '\177' || Isupper(_toebcdic[_toascii[c]|0100]) 1259c80476e4SDavid E. O'Brien || strchr("@[\\]^_", _toebcdic[_toascii[c]|0100]) != NULL) 1260c80476e4SDavid E. O'Brien { 1261c80476e4SDavid E. O'Brien mc = (_toascii[c] == '\177') ? '?' : _toebcdic[_toascii[c]|0100]; 1262c80476e4SDavid E. O'Brien PutPlusOne('^'); 1263c80476e4SDavid E. O'Brien PutPlusOne(mc); 1264c80476e4SDavid E. O'Brien } 1265c80476e4SDavid E. O'Brien else 1266c80476e4SDavid E. O'Brien { 1267c80476e4SDavid E. O'Brien PutPlusOne('\\'); 1268c80476e4SDavid E. O'Brien PutPlusOne(((c >> 6) & 7) + '0'); 1269c80476e4SDavid E. O'Brien PutPlusOne(((c >> 3) & 7) + '0'); 1270c80476e4SDavid E. O'Brien PutPlusOne((c & 7) + '0'); 1271c80476e4SDavid E. O'Brien } 12723b6eaa7bSAndrey A. Chernov #endif 1273c80476e4SDavid E. O'Brien } 1274c80476e4SDavid E. O'Brien else if (Isprint(c)) { /* normal char */ 1275c80476e4SDavid E. O'Brien PutPlusOne(c); 1276c80476e4SDavid E. O'Brien } 1277c80476e4SDavid E. O'Brien #ifdef KANJI 127800c801edSDavid E. O'Brien else if ( 127900c801edSDavid E. O'Brien #ifdef DSPMBYTE 128000c801edSDavid E. O'Brien _enable_mbdisp && 128100c801edSDavid E. O'Brien #endif 128200c801edSDavid E. O'Brien !adrof(STRnokanji)) { 1283c80476e4SDavid E. O'Brien PutPlusOne(c); 1284c80476e4SDavid E. O'Brien } 1285c80476e4SDavid E. O'Brien #endif 1286c80476e4SDavid E. O'Brien else { 1287c80476e4SDavid E. O'Brien PutPlusOne('\\'); 1288c80476e4SDavid E. O'Brien PutPlusOne(((c >> 6) & 7) + '0'); 1289c80476e4SDavid E. O'Brien PutPlusOne(((c >> 3) & 7) + '0'); 1290c80476e4SDavid E. O'Brien PutPlusOne((c & 7) + '0'); 1291c80476e4SDavid E. O'Brien } 1292c80476e4SDavid E. O'Brien flush(); 1293c80476e4SDavid E. O'Brien } 1294c80476e4SDavid E. O'Brien 1295c80476e4SDavid E. O'Brien /* clear the screen buffers so that new new prompt starts fresh. */ 1296c80476e4SDavid E. O'Brien 1297c80476e4SDavid E. O'Brien void 1298c80476e4SDavid E. O'Brien ClearDisp() 1299c80476e4SDavid E. O'Brien { 1300c80476e4SDavid E. O'Brien register int i; 1301c80476e4SDavid E. O'Brien 1302c80476e4SDavid E. O'Brien CursorV = 0; /* clear the display buffer */ 1303c80476e4SDavid E. O'Brien CursorH = 0; 1304c80476e4SDavid E. O'Brien for (i = 0; i < TermV; i++) 1305c80476e4SDavid E. O'Brien (void) memset(Display[i], 0, TermH * sizeof(Display[0][0])); 1306c80476e4SDavid E. O'Brien OldvcV = 0; 1307c80476e4SDavid E. O'Brien } 1308c80476e4SDavid E. O'Brien 1309c80476e4SDavid E. O'Brien void 1310c80476e4SDavid E. O'Brien ClearLines() 1311c80476e4SDavid E. O'Brien { /* Make sure all lines are *really* blank */ 1312c80476e4SDavid E. O'Brien register int i; 1313c80476e4SDavid E. O'Brien 1314c80476e4SDavid E. O'Brien if (T_CanCEOL) { 1315c80476e4SDavid E. O'Brien /* 1316c80476e4SDavid E. O'Brien * Clear the lines from the bottom up so that if we try moving 1317c80476e4SDavid E. O'Brien * the cursor down by writing the character that is at the end 1318c80476e4SDavid E. O'Brien * of the screen line, we won't rewrite a character that shouldn't 1319c80476e4SDavid E. O'Brien * be there. 1320c80476e4SDavid E. O'Brien */ 1321c80476e4SDavid E. O'Brien for (i = OldvcV; i >= 0; i--) { /* for each line on the screen */ 1322c80476e4SDavid E. O'Brien MoveToLine(i); 1323c80476e4SDavid E. O'Brien MoveToChar(0); 1324c80476e4SDavid E. O'Brien ClearEOL(TermH); 1325c80476e4SDavid E. O'Brien } 1326c80476e4SDavid E. O'Brien } 1327c80476e4SDavid E. O'Brien else { 1328c80476e4SDavid E. O'Brien MoveToLine(OldvcV); /* go to last line */ 1329c80476e4SDavid E. O'Brien (void) putraw('\r'); /* go to BOL */ 1330c80476e4SDavid E. O'Brien (void) putraw('\n'); /* go to new line */ 1331c80476e4SDavid E. O'Brien } 1332c80476e4SDavid E. O'Brien } 1333