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