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