17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23*f6db9f27Scf46844 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate /* Copyright (c) 1981 Regents of the University of California */ 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include "ex.h" 367c478bd9Sstevel@tonic-gate #include "ex_tty.h" 377c478bd9Sstevel@tonic-gate #include "ex_vis.h" 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate /* 407c478bd9Sstevel@tonic-gate * Deal with the screen, clearing, cursor positioning, putting characters 417c478bd9Sstevel@tonic-gate * into the screen image, and deleting characters. 427c478bd9Sstevel@tonic-gate * Really hard stuff here is utilizing insert character operations 437c478bd9Sstevel@tonic-gate * on intelligent terminals which differs widely from terminal to terminal. 447c478bd9Sstevel@tonic-gate */ 45*f6db9f27Scf46844 void 46*f6db9f27Scf46844 vclear(void) 477c478bd9Sstevel@tonic-gate { 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #ifdef TRACE 507c478bd9Sstevel@tonic-gate if (trace) 517c478bd9Sstevel@tonic-gate tfixnl(), fprintf(trace, "------\nvclear, clear_screen '%s'\n", clear_screen); 527c478bd9Sstevel@tonic-gate #endif 537c478bd9Sstevel@tonic-gate tputs(clear_screen, lines, putch); 547c478bd9Sstevel@tonic-gate destcol = 0; 557c478bd9Sstevel@tonic-gate outcol = 0; 567c478bd9Sstevel@tonic-gate destline = 0; 577c478bd9Sstevel@tonic-gate outline = 0; 587c478bd9Sstevel@tonic-gate if (inopen) 597c478bd9Sstevel@tonic-gate vclrbyte(vtube0, WCOLS * (WECHO - ZERO + 1)); 607c478bd9Sstevel@tonic-gate } 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate /* 637c478bd9Sstevel@tonic-gate * Clear memory. 647c478bd9Sstevel@tonic-gate */ 65*f6db9f27Scf46844 void 66*f6db9f27Scf46844 vclrbyte(wchar_t *cp, int i) 677c478bd9Sstevel@tonic-gate { 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate if (i > 0) 707c478bd9Sstevel@tonic-gate do 717c478bd9Sstevel@tonic-gate *cp++ = 0; 727c478bd9Sstevel@tonic-gate while (--i != 0); 737c478bd9Sstevel@tonic-gate } 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate /* 767c478bd9Sstevel@tonic-gate * Clear a physical display line, high level. 777c478bd9Sstevel@tonic-gate */ 78*f6db9f27Scf46844 void 79*f6db9f27Scf46844 vclrlin(int l, line *tp) 807c478bd9Sstevel@tonic-gate { 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate vigoto(l, 0); 837c478bd9Sstevel@tonic-gate if ((hold & HOLDAT) == 0) 847c478bd9Sstevel@tonic-gate putchar(tp > dol ? ((UPPERCASE || tilde_glitch) ? '^' : '~') : '@'); 857c478bd9Sstevel@tonic-gate if (state == HARDOPEN) 867c478bd9Sstevel@tonic-gate sethard(); 877c478bd9Sstevel@tonic-gate vclreol(); 887c478bd9Sstevel@tonic-gate } 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate /* 917c478bd9Sstevel@tonic-gate * Clear to the end of the current physical line 927c478bd9Sstevel@tonic-gate */ 93*f6db9f27Scf46844 void 94*f6db9f27Scf46844 vclreol(void) 957c478bd9Sstevel@tonic-gate { 96*f6db9f27Scf46844 int i; 97*f6db9f27Scf46844 wchar_t *tp, j; 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate #ifdef TRACE 1007c478bd9Sstevel@tonic-gate if (trace) 1017c478bd9Sstevel@tonic-gate fprintf(trace, "vclreol(), destcol %d, ateopr() %d\n", destcol, ateopr()); 1027c478bd9Sstevel@tonic-gate #endif 1037c478bd9Sstevel@tonic-gate if (destcol == WCOLS) 1047c478bd9Sstevel@tonic-gate return; 1057c478bd9Sstevel@tonic-gate destline += destcol / WCOLS; 1067c478bd9Sstevel@tonic-gate destcol %= WCOLS; 1077c478bd9Sstevel@tonic-gate if (destline < 0 || destline > WECHO) 1087c478bd9Sstevel@tonic-gate error(gettext("Internal error: vclreol")); 1097c478bd9Sstevel@tonic-gate i = WCOLS - destcol; 1107c478bd9Sstevel@tonic-gate tp = vtube[destline] + destcol; 1117c478bd9Sstevel@tonic-gate if (clr_eol) { 1127c478bd9Sstevel@tonic-gate if (insert_null_glitch && *tp || !ateopr()) { 1137c478bd9Sstevel@tonic-gate vcsync(); 1147c478bd9Sstevel@tonic-gate vputp(clr_eol, 1); 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate vclrbyte(tp, i); 1177c478bd9Sstevel@tonic-gate return; 1187c478bd9Sstevel@tonic-gate } 1197c478bd9Sstevel@tonic-gate if (*tp == 0) 1207c478bd9Sstevel@tonic-gate return; 1217c478bd9Sstevel@tonic-gate while (i > 0 && (j = *tp & (QUOTE|TRIM))) { 1227c478bd9Sstevel@tonic-gate if (j != ' ' && (j & QUOTE) == 0) { 1237c478bd9Sstevel@tonic-gate destcol = WCOLS - i; 124*f6db9f27Scf46844 (void) vputchar(' '); 1257c478bd9Sstevel@tonic-gate } 1267c478bd9Sstevel@tonic-gate --i, *tp++ = 0; 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate /* 1317c478bd9Sstevel@tonic-gate * Clear the echo line. 1327c478bd9Sstevel@tonic-gate * If didphys then its been cleared physically (as 1337c478bd9Sstevel@tonic-gate * a side effect of a clear to end of display, e.g.) 1347c478bd9Sstevel@tonic-gate * so just do it logically. 1357c478bd9Sstevel@tonic-gate * If work here is being held off, just remember, in 1367c478bd9Sstevel@tonic-gate * heldech, if work needs to be done, don't do anything. 1377c478bd9Sstevel@tonic-gate */ 138*f6db9f27Scf46844 void 1397c478bd9Sstevel@tonic-gate vclrech(didphys) 1407c478bd9Sstevel@tonic-gate bool didphys; 1417c478bd9Sstevel@tonic-gate { 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate #ifdef ADEBUG 1447c478bd9Sstevel@tonic-gate if (trace) 1457c478bd9Sstevel@tonic-gate fprintf(trace, "vclrech(%d), Peekkey %d, hold %o\n", didphys, Peekkey, hold); 1467c478bd9Sstevel@tonic-gate #endif 1477c478bd9Sstevel@tonic-gate if (Peekkey == ATTN) 1487c478bd9Sstevel@tonic-gate return; 1497c478bd9Sstevel@tonic-gate if (hold & HOLDECH) { 1507c478bd9Sstevel@tonic-gate heldech = !didphys; 1517c478bd9Sstevel@tonic-gate return; 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate if (!didphys && (clr_eos || clr_eol)) { 1547c478bd9Sstevel@tonic-gate splitw++; 1557c478bd9Sstevel@tonic-gate /* 1567c478bd9Sstevel@tonic-gate * If display is retained below, then MUST use clr_eos or 1577c478bd9Sstevel@tonic-gate * clr_eol since we don't really know whats out there. 1587c478bd9Sstevel@tonic-gate * Vigoto might decide (incorrectly) to do nothing. 1597c478bd9Sstevel@tonic-gate */ 1607c478bd9Sstevel@tonic-gate if (memory_below) { 1617c478bd9Sstevel@tonic-gate vgoto(WECHO, 0); 1627c478bd9Sstevel@tonic-gate /* 1637c478bd9Sstevel@tonic-gate * This is tricky. If clr_eos is as cheap we 1647c478bd9Sstevel@tonic-gate * should use it, so we don't have extra junk 1657c478bd9Sstevel@tonic-gate * floating around in memory below. But if 1667c478bd9Sstevel@tonic-gate * clr_eol costs less we should use it. The real 1677c478bd9Sstevel@tonic-gate * reason here is that clr_eos is incredibly 1687c478bd9Sstevel@tonic-gate * expensive on the HP 2626 (1/2 second or more) 1697c478bd9Sstevel@tonic-gate * which makes ^D scroll really slow. But the 1707c478bd9Sstevel@tonic-gate * 2621 has a bug that shows up if we use clr_eol 1717c478bd9Sstevel@tonic-gate * instead of clr_eos, so we make sure the costs 1727c478bd9Sstevel@tonic-gate * are equal so it will prefer clr_eol. 1737c478bd9Sstevel@tonic-gate */ 1747c478bd9Sstevel@tonic-gate if (costCE < costCD) 1757c478bd9Sstevel@tonic-gate vputp(clr_eol, 1); 1767c478bd9Sstevel@tonic-gate else 1777c478bd9Sstevel@tonic-gate vputp(clr_eos, 1); 1787c478bd9Sstevel@tonic-gate } else { 1797c478bd9Sstevel@tonic-gate if (teleray_glitch) { 1807c478bd9Sstevel@tonic-gate /* This code basically handles the t1061 1817c478bd9Sstevel@tonic-gate * where positioning at (0, 0) won't work 1827c478bd9Sstevel@tonic-gate * because the terminal won't let you put 1837c478bd9Sstevel@tonic-gate * the cursor on it's magic cookie. 1847c478bd9Sstevel@tonic-gate * 1857c478bd9Sstevel@tonic-gate * Should probably be ceol_standout_glitch 1867c478bd9Sstevel@tonic-gate * above, or even a 1877c478bd9Sstevel@tonic-gate * new glitch, but right now t1061 is the 1887c478bd9Sstevel@tonic-gate * only terminal with teleray_glitch. 1897c478bd9Sstevel@tonic-gate */ 1907c478bd9Sstevel@tonic-gate vgoto(WECHO, 0); 1917c478bd9Sstevel@tonic-gate vputp(delete_line, 1); 1927c478bd9Sstevel@tonic-gate } else { 1937c478bd9Sstevel@tonic-gate vigoto(WECHO, 0); 1947c478bd9Sstevel@tonic-gate vclreol(); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate splitw = 0; 1987c478bd9Sstevel@tonic-gate didphys = 1; 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate if (didphys) 2017c478bd9Sstevel@tonic-gate vclrbyte(vtube[WECHO], WCOLS); 2027c478bd9Sstevel@tonic-gate heldech = 0; 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate /* 2067c478bd9Sstevel@tonic-gate * Fix the echo area for use, setting 2077c478bd9Sstevel@tonic-gate * the state variable splitw so we wont rollup 2087c478bd9Sstevel@tonic-gate * when we move the cursor there. 2097c478bd9Sstevel@tonic-gate */ 210*f6db9f27Scf46844 void 211*f6db9f27Scf46844 fixech(void) 2127c478bd9Sstevel@tonic-gate { 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate splitw++; 2157c478bd9Sstevel@tonic-gate if (state != VISUAL && state != CRTOPEN) { 2167c478bd9Sstevel@tonic-gate vclean(); 2177c478bd9Sstevel@tonic-gate vcnt = 0; 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate vgoto(WECHO, 0); flusho(); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate /* 2237c478bd9Sstevel@tonic-gate * Put the cursor ``before'' cp. 2247c478bd9Sstevel@tonic-gate */ 225*f6db9f27Scf46844 void 226*f6db9f27Scf46844 vcursbef(unsigned char *cp) 2277c478bd9Sstevel@tonic-gate { 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate if (cp <= linebuf) 2307c478bd9Sstevel@tonic-gate vgotoCL(value(vi_NUMBER) << 3); 2317c478bd9Sstevel@tonic-gate else 2327c478bd9Sstevel@tonic-gate vgotoCL(lcolumn(cp)-1); 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate /* 2367c478bd9Sstevel@tonic-gate * Put the cursor ``at'' cp. 2377c478bd9Sstevel@tonic-gate */ 238*f6db9f27Scf46844 void 239*f6db9f27Scf46844 vcursat(unsigned char *cp) 2407c478bd9Sstevel@tonic-gate { 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate if (cp <= linebuf && linebuf[0] == 0) 2437c478bd9Sstevel@tonic-gate vgotoCL(value(vi_NUMBER) << 3); 2447c478bd9Sstevel@tonic-gate else 2457c478bd9Sstevel@tonic-gate vgotoCL(lcolumn(cp)); 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate /* 2497c478bd9Sstevel@tonic-gate * Put the cursor ``after'' cp. 2507c478bd9Sstevel@tonic-gate */ 251*f6db9f27Scf46844 void 252*f6db9f27Scf46844 vcursaft(unsigned char *cp) 2537c478bd9Sstevel@tonic-gate { 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate vgotoCL(lcolumn(nextchr(cp))); 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate /* 2597c478bd9Sstevel@tonic-gate * Fix the cursor to be positioned in the correct place 2607c478bd9Sstevel@tonic-gate * to accept a command. 2617c478bd9Sstevel@tonic-gate */ 262*f6db9f27Scf46844 void 263*f6db9f27Scf46844 vfixcurs(void) 2647c478bd9Sstevel@tonic-gate { 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate vsetcurs(cursor); 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate /* 2707c478bd9Sstevel@tonic-gate * Compute the column position implied by the cursor at ``nc'', 2717c478bd9Sstevel@tonic-gate * and move the cursor there. 2727c478bd9Sstevel@tonic-gate */ 273*f6db9f27Scf46844 void 274*f6db9f27Scf46844 vsetcurs(unsigned char *nc) 2757c478bd9Sstevel@tonic-gate { 276*f6db9f27Scf46844 int col; 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate col = column(nc); 2797c478bd9Sstevel@tonic-gate if (linebuf[0]) 2807c478bd9Sstevel@tonic-gate col--; 2817c478bd9Sstevel@tonic-gate vgotoCL(col); 2827c478bd9Sstevel@tonic-gate cursor = nc; 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate /* 2867c478bd9Sstevel@tonic-gate * Move the cursor invisibly, i.e. only remember to do it. 2877c478bd9Sstevel@tonic-gate */ 288*f6db9f27Scf46844 void 289*f6db9f27Scf46844 vigoto(int y, int x) 2907c478bd9Sstevel@tonic-gate { 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate destline = y; 2937c478bd9Sstevel@tonic-gate destcol = x; 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate /* 2977c478bd9Sstevel@tonic-gate * Move the cursor to the position implied by any previous 2987c478bd9Sstevel@tonic-gate * vigoto (or low level hacking with destcol/destline as in readecho). 2997c478bd9Sstevel@tonic-gate */ 300*f6db9f27Scf46844 void 301*f6db9f27Scf46844 vcsync(void) 3027c478bd9Sstevel@tonic-gate { 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate vgoto(destline, destcol); 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate /* 3087c478bd9Sstevel@tonic-gate * Goto column x of the current line. 3097c478bd9Sstevel@tonic-gate */ 310*f6db9f27Scf46844 void 311*f6db9f27Scf46844 vgotoCL(int x) 3127c478bd9Sstevel@tonic-gate { 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate if (splitw) 3157c478bd9Sstevel@tonic-gate vgoto(WECHO, x); 3167c478bd9Sstevel@tonic-gate else 3177c478bd9Sstevel@tonic-gate vgoto(LINE(vcline), x); 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate /* 3217c478bd9Sstevel@tonic-gate * Invisible goto column x of current line. 3227c478bd9Sstevel@tonic-gate */ 323*f6db9f27Scf46844 void 324*f6db9f27Scf46844 vigotoCL(int x) 3257c478bd9Sstevel@tonic-gate { 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate if (splitw) 3287c478bd9Sstevel@tonic-gate vigoto(WECHO, x); 3297c478bd9Sstevel@tonic-gate else 3307c478bd9Sstevel@tonic-gate vigoto(LINE(vcline), x); 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate /* 3347c478bd9Sstevel@tonic-gate * Show the current mode in the right hand part of the echo line, 3357c478bd9Sstevel@tonic-gate * then return the cursor to where it is now. 3367c478bd9Sstevel@tonic-gate */ 337*f6db9f27Scf46844 void 338*f6db9f27Scf46844 vshowmode(unsigned char *msg) 3397c478bd9Sstevel@tonic-gate { 3407c478bd9Sstevel@tonic-gate int savecol, saveline, savesplit; 3417c478bd9Sstevel@tonic-gate unsigned char *p; 3427c478bd9Sstevel@tonic-gate wchar_t wchar; 3437c478bd9Sstevel@tonic-gate int length; 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate if (!value(vi_SHOWMODE)) 3467c478bd9Sstevel@tonic-gate return; 3477c478bd9Sstevel@tonic-gate /* Don't alter mode message for macros (arrow keys) or yank/put */ 3487c478bd9Sstevel@tonic-gate if (vmacp || vglobp) 3497c478bd9Sstevel@tonic-gate return; 3507c478bd9Sstevel@tonic-gate savecol = outcol; saveline = outline; savesplit = splitw; 3517c478bd9Sstevel@tonic-gate splitw = 1; /* To avoid scrolling */ 3527c478bd9Sstevel@tonic-gate vigoto(WECHO, WCOLS-20); 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate if (*msg) { 3557c478bd9Sstevel@tonic-gate vcsync(); 3567c478bd9Sstevel@tonic-gate for (p = msg; *p;) { 3577c478bd9Sstevel@tonic-gate length = mbtowc(&wchar, (char *)p, MULTI_BYTE_MAX); 3587c478bd9Sstevel@tonic-gate if (length <= 0) { 3597c478bd9Sstevel@tonic-gate /* 3607c478bd9Sstevel@tonic-gate * This should never happen, but 3617c478bd9Sstevel@tonic-gate * if 'msg' doesn't make a valid string, 3627c478bd9Sstevel@tonic-gate * treat this case as the same as the 3637c478bd9Sstevel@tonic-gate * null string 'msg'. 3647c478bd9Sstevel@tonic-gate */ 3657c478bd9Sstevel@tonic-gate /* 3667c478bd9Sstevel@tonic-gate * Going back to command mode - clear the message. 3677c478bd9Sstevel@tonic-gate */ 3687c478bd9Sstevel@tonic-gate vclreol(); 3697c478bd9Sstevel@tonic-gate break; 3707c478bd9Sstevel@tonic-gate } else { 371*f6db9f27Scf46844 (void) vputchar(wchar); 3727c478bd9Sstevel@tonic-gate p += length; 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate } else { 3767c478bd9Sstevel@tonic-gate /* 3777c478bd9Sstevel@tonic-gate * Going back to command mode - clear the message. 3787c478bd9Sstevel@tonic-gate */ 3797c478bd9Sstevel@tonic-gate vclreol(); 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate FLAGS(WECHO) |= VDIRT; 3837c478bd9Sstevel@tonic-gate vgoto(saveline, savecol); 3847c478bd9Sstevel@tonic-gate splitw = savesplit; 3857c478bd9Sstevel@tonic-gate } 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate /* 3887c478bd9Sstevel@tonic-gate * Move cursor to line y, column x, handling wraparound and scrolling. 3897c478bd9Sstevel@tonic-gate */ 390*f6db9f27Scf46844 void 391*f6db9f27Scf46844 vgoto(int y, int x) 3927c478bd9Sstevel@tonic-gate { 393*f6db9f27Scf46844 wchar_t *tp; 394*f6db9f27Scf46844 wchar_t c; 3957c478bd9Sstevel@tonic-gate int col; 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate /* 3987c478bd9Sstevel@tonic-gate * Fold the possibly too large value of x. 3997c478bd9Sstevel@tonic-gate */ 4007c478bd9Sstevel@tonic-gate if (x >= WCOLS) { 4017c478bd9Sstevel@tonic-gate y += x / WCOLS; 4027c478bd9Sstevel@tonic-gate x %= WCOLS; 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate if (y < 0) { 4057c478bd9Sstevel@tonic-gate error("Internal error: vgoto"); 4067c478bd9Sstevel@tonic-gate } 4077c478bd9Sstevel@tonic-gate if (outcol >= WCOLS) { 4087c478bd9Sstevel@tonic-gate if (auto_right_margin) { 4097c478bd9Sstevel@tonic-gate outline += outcol / WCOLS; 4107c478bd9Sstevel@tonic-gate outcol %= WCOLS; 4117c478bd9Sstevel@tonic-gate } else 4127c478bd9Sstevel@tonic-gate outcol = WCOLS - 1; 4137c478bd9Sstevel@tonic-gate } 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate /* 4167c478bd9Sstevel@tonic-gate * In a hardcopy or glass crt open, print the stuff 4177c478bd9Sstevel@tonic-gate * implied by a motion, or backspace. 4187c478bd9Sstevel@tonic-gate */ 4197c478bd9Sstevel@tonic-gate if (state == HARDOPEN || state == ONEOPEN) { 4207c478bd9Sstevel@tonic-gate if (y != outline) 4217c478bd9Sstevel@tonic-gate error(gettext("Line too long for open")); 4227c478bd9Sstevel@tonic-gate if (x + 1 < outcol - x || (outcol > x && !cursor_left)) 4237c478bd9Sstevel@tonic-gate destcol = 0, fgoto(); 4247c478bd9Sstevel@tonic-gate tp = vtube[WBOT] + outcol; 4257c478bd9Sstevel@tonic-gate while (outcol != x) 4267c478bd9Sstevel@tonic-gate if (outcol < x) { 4277c478bd9Sstevel@tonic-gate int length; 4287c478bd9Sstevel@tonic-gate unsigned char multic[MULTI_BYTE_MAX]; 4297c478bd9Sstevel@tonic-gate if (*tp == 0) 4307c478bd9Sstevel@tonic-gate *tp = ' '; 4317c478bd9Sstevel@tonic-gate c = *tp++ & TRIM; 4327c478bd9Sstevel@tonic-gate length = wctomb((char *)multic, c); 4337c478bd9Sstevel@tonic-gate if(length == 0) 4347c478bd9Sstevel@tonic-gate length = 1; 4357c478bd9Sstevel@tonic-gate while(length--) 436*f6db9f27Scf46844 (void) vputc(c && 437*f6db9f27Scf46844 (!over_strike || erase_overstrike) 438*f6db9f27Scf46844 ? c : ' '); 4397c478bd9Sstevel@tonic-gate if (c) { 4407c478bd9Sstevel@tonic-gate if ((col = wcwidth(c)) < 0) 4417c478bd9Sstevel@tonic-gate col = 0; 4427c478bd9Sstevel@tonic-gate } else 4437c478bd9Sstevel@tonic-gate col = 1; 4447c478bd9Sstevel@tonic-gate outcol += col; 4457c478bd9Sstevel@tonic-gate } else { 4467c478bd9Sstevel@tonic-gate vputp(cursor_left, 0); 4477c478bd9Sstevel@tonic-gate outcol--; 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate destcol = outcol = x; 4507c478bd9Sstevel@tonic-gate destline = outline; 4517c478bd9Sstevel@tonic-gate return; 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate /* 4557c478bd9Sstevel@tonic-gate * If the destination position implies a scroll, do it. 4567c478bd9Sstevel@tonic-gate */ 4577c478bd9Sstevel@tonic-gate destline = y; 4587c478bd9Sstevel@tonic-gate if (destline > WBOT && (!splitw || destline > WECHO)) { 4597c478bd9Sstevel@tonic-gate endim(); 4607c478bd9Sstevel@tonic-gate vrollup(destline); 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate /* 4647c478bd9Sstevel@tonic-gate * If there really is a motion involved, do it. 4657c478bd9Sstevel@tonic-gate * The check here is an optimization based on profiling. 4667c478bd9Sstevel@tonic-gate */ 4677c478bd9Sstevel@tonic-gate destcol = x; 4687c478bd9Sstevel@tonic-gate if ((destline - outline) * WCOLS != destcol - outcol) { 4697c478bd9Sstevel@tonic-gate if (!move_insert_mode) 4707c478bd9Sstevel@tonic-gate endim(); 4717c478bd9Sstevel@tonic-gate fgoto(); 4727c478bd9Sstevel@tonic-gate } 4737c478bd9Sstevel@tonic-gate } 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate /* 4767c478bd9Sstevel@tonic-gate * This is the hardest code in the editor, and deals with insert modes 4777c478bd9Sstevel@tonic-gate * on different kinds of intelligent terminals. The complexity is due 4787c478bd9Sstevel@tonic-gate * to the cross product of three factors: 4797c478bd9Sstevel@tonic-gate * 4807c478bd9Sstevel@tonic-gate * 1. Lines may display as more than one segment on the screen. 4817c478bd9Sstevel@tonic-gate * 2. There are 2 kinds of intelligent terminal insert modes. 4827c478bd9Sstevel@tonic-gate * 3. Tabs squash when you insert characters in front of them, 4837c478bd9Sstevel@tonic-gate * in a way in which current intelligent terminals don't handle. 4847c478bd9Sstevel@tonic-gate * 4857c478bd9Sstevel@tonic-gate * The two kinds of terminals are typified by the DM2500 or HP2645 for 4867c478bd9Sstevel@tonic-gate * one and the CONCEPT-100 or the FOX for the other. 4877c478bd9Sstevel@tonic-gate * 4887c478bd9Sstevel@tonic-gate * The first (HP2645) kind has an insert mode where the characters 4897c478bd9Sstevel@tonic-gate * fall off the end of the line and the screen is shifted rigidly 4907c478bd9Sstevel@tonic-gate * no matter how the display came about. 4917c478bd9Sstevel@tonic-gate * 4927c478bd9Sstevel@tonic-gate * The second (CONCEPT-100) kind comes from terminals which are designed 4937c478bd9Sstevel@tonic-gate * for forms editing and which distinguish between blanks and ``spaces'' 4947c478bd9Sstevel@tonic-gate * on the screen, spaces being like blank, but never having had 4957c478bd9Sstevel@tonic-gate * and data typed into that screen position (since, e.g. a clear operation 4967c478bd9Sstevel@tonic-gate * like clear screen). On these terminals, when you insert a character, 4977c478bd9Sstevel@tonic-gate * the characters from where you are to the end of the screen shift 4987c478bd9Sstevel@tonic-gate * over till a ``space'' is found, and the null character there gets 4997c478bd9Sstevel@tonic-gate * eaten up. 5007c478bd9Sstevel@tonic-gate * 5017c478bd9Sstevel@tonic-gate * 5027c478bd9Sstevel@tonic-gate * The code here considers the line as consisting of several parts 5037c478bd9Sstevel@tonic-gate * the first part is the ``doomed'' part, i.e. a part of the line 5047c478bd9Sstevel@tonic-gate * which is being typed over. Next comes some text up to the first 5057c478bd9Sstevel@tonic-gate * following tab. The tab is the next segment of the line, and finally 5067c478bd9Sstevel@tonic-gate * text after the tab. 5077c478bd9Sstevel@tonic-gate * 5087c478bd9Sstevel@tonic-gate * We have to consider each of these segments and the effect of the 5097c478bd9Sstevel@tonic-gate * insertion of a character on them. On terminals like HP2645's we 5107c478bd9Sstevel@tonic-gate * must simulate a multi-line insert mode using the primitive one 5117c478bd9Sstevel@tonic-gate * line insert mode. If we are inserting in front of a tab, we have 5127c478bd9Sstevel@tonic-gate * to either delete characters from the tab or insert white space 5137c478bd9Sstevel@tonic-gate * (when the tab reaches a new spot where it gets larger) before we 5147c478bd9Sstevel@tonic-gate * insert the new character. 5157c478bd9Sstevel@tonic-gate * 5167c478bd9Sstevel@tonic-gate * On a terminal like a CONCEPT our strategy is to make all 5177c478bd9Sstevel@tonic-gate * blanks be displayed, while trying to keep the screen having ``spaces'' 5187c478bd9Sstevel@tonic-gate * for portions of tabs. In this way the terminal hardware does some 5197c478bd9Sstevel@tonic-gate * of the hacking for compression of tabs, although this tends to 5207c478bd9Sstevel@tonic-gate * disappear as you work on the line and spaces change into blanks. 5217c478bd9Sstevel@tonic-gate * 5227c478bd9Sstevel@tonic-gate * There are a number of boundary conditions (like typing just before 5237c478bd9Sstevel@tonic-gate * the first following tab) where we can avoid a lot of work. Most 5247c478bd9Sstevel@tonic-gate * of them have to be dealt with explicitly because performance is 5257c478bd9Sstevel@tonic-gate * much, much worse if we don't. 5267c478bd9Sstevel@tonic-gate * 5277c478bd9Sstevel@tonic-gate * A final thing which is hacked here is two flavors of insert mode. 5287c478bd9Sstevel@tonic-gate * Datamedia's do this by an insert mode which you enter and leave 5297c478bd9Sstevel@tonic-gate * and by having normal motion character operate differently in this 5307c478bd9Sstevel@tonic-gate * mode, notably by having a newline insert a line on the screen in 5317c478bd9Sstevel@tonic-gate * this mode. This generally means it is unsafe to move around 5327c478bd9Sstevel@tonic-gate * the screen ignoring the fact that we are in this mode. 5337c478bd9Sstevel@tonic-gate * This is possible on some terminals, and wins big (e.g. HP), so 5347c478bd9Sstevel@tonic-gate * we encode this as a ``can move in insert capability'' mi, 5357c478bd9Sstevel@tonic-gate * and terminals which have it can do insert mode with much less 5367c478bd9Sstevel@tonic-gate * work when tabs are present following the cursor on the current line. 5377c478bd9Sstevel@tonic-gate */ 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate /* 5407c478bd9Sstevel@tonic-gate * Routine to expand a tab, calling the normal Outchar routine 5417c478bd9Sstevel@tonic-gate * to put out each implied character. Note that we call outchar 5427c478bd9Sstevel@tonic-gate * with a QUOTE. We use QUOTE internally to represent a position 5437c478bd9Sstevel@tonic-gate * which is part of the expansion of a tab. 5447c478bd9Sstevel@tonic-gate */ 545*f6db9f27Scf46844 void 546*f6db9f27Scf46844 vgotab(void) 5477c478bd9Sstevel@tonic-gate { 548*f6db9f27Scf46844 int i = tabcol(destcol, value(vi_TABSTOP)) - destcol; 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate do 5517c478bd9Sstevel@tonic-gate (*Outchar)(QUOTE); 5527c478bd9Sstevel@tonic-gate while (--i); 5537c478bd9Sstevel@tonic-gate } 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate /* 5567c478bd9Sstevel@tonic-gate * Variables for insert mode. 5577c478bd9Sstevel@tonic-gate */ 5587c478bd9Sstevel@tonic-gate int linend; /* The column position of end of line */ 5597c478bd9Sstevel@tonic-gate int tabstart; /* Column of start of first following tab */ 5607c478bd9Sstevel@tonic-gate int tabend; /* Column of end of following tabs */ 5617c478bd9Sstevel@tonic-gate int tabsize; /* Size of the following tabs */ 5627c478bd9Sstevel@tonic-gate int tabslack; /* Number of ``spaces'' in following tabs */ 5637c478bd9Sstevel@tonic-gate int inssiz; /* Number of characters to be inserted */ 5647c478bd9Sstevel@tonic-gate int inscol; /* Column where insertion is taking place */ 5657c478bd9Sstevel@tonic-gate int shft; /* Amount tab expansion shifted rest of line */ 5667c478bd9Sstevel@tonic-gate int slakused; /* This much of tabslack will be used up */ 5677c478bd9Sstevel@tonic-gate 5687c478bd9Sstevel@tonic-gate /* 5697c478bd9Sstevel@tonic-gate * This routine MUST be called before insert mode is run, 5707c478bd9Sstevel@tonic-gate * and brings all segments of the current line to the top 5717c478bd9Sstevel@tonic-gate * of the screen image buffer so it is easier for us to 5727c478bd9Sstevel@tonic-gate * manipulate them. 5737c478bd9Sstevel@tonic-gate */ 574*f6db9f27Scf46844 void 575*f6db9f27Scf46844 vprepins(void) 5767c478bd9Sstevel@tonic-gate { 577*f6db9f27Scf46844 int i; 578*f6db9f27Scf46844 wchar_t *cp = vtube0; 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate for (i = 0; i < DEPTH(vcline); i++) { 5817c478bd9Sstevel@tonic-gate vmaktop(LINE(vcline) + i, cp); 5827c478bd9Sstevel@tonic-gate cp += WCOLS; 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate 586*f6db9f27Scf46844 void 587*f6db9f27Scf46844 vmaktop(int p, wchar_t *cp) 5887c478bd9Sstevel@tonic-gate { 589*f6db9f27Scf46844 int i; 5907c478bd9Sstevel@tonic-gate wchar_t temp[TUBECOLS]; 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate if (p < 0 || vtube[p] == cp) 5937c478bd9Sstevel@tonic-gate return; 5947c478bd9Sstevel@tonic-gate for (i = ZERO; i <= WECHO; i++) 5957c478bd9Sstevel@tonic-gate if (vtube[i] == cp) { 5967c478bd9Sstevel@tonic-gate copy(temp, vtube[i], WCOLS * sizeof(wchar_t)); 5977c478bd9Sstevel@tonic-gate copy(vtube[i], vtube[p], WCOLS * sizeof(wchar_t)); 5987c478bd9Sstevel@tonic-gate copy(vtube[p], temp, WCOLS * sizeof(wchar_t)); 5997c478bd9Sstevel@tonic-gate vtube[i] = vtube[p]; 6007c478bd9Sstevel@tonic-gate vtube[p] = cp; 6017c478bd9Sstevel@tonic-gate return; 6027c478bd9Sstevel@tonic-gate } 6037c478bd9Sstevel@tonic-gate error(gettext("Line too long")); 6047c478bd9Sstevel@tonic-gate } 6057c478bd9Sstevel@tonic-gate 6067c478bd9Sstevel@tonic-gate /* 6077c478bd9Sstevel@tonic-gate * Insert character c at current cursor position. 6087c478bd9Sstevel@tonic-gate * Multi-character inserts occur only as a result 6097c478bd9Sstevel@tonic-gate * of expansion of tabs (i.e. inssize == 1 except 6107c478bd9Sstevel@tonic-gate * for tabs or multibyte characters) 6117c478bd9Sstevel@tonic-gate * and code assumes this in several place 6127c478bd9Sstevel@tonic-gate * to make life simpler. 6137c478bd9Sstevel@tonic-gate */ 614*f6db9f27Scf46844 int 615*f6db9f27Scf46844 vinschar(wchar_t c) 6167c478bd9Sstevel@tonic-gate { 617*f6db9f27Scf46844 int i; 618*f6db9f27Scf46844 wchar_t *tp, wchar; 6197c478bd9Sstevel@tonic-gate 6207c478bd9Sstevel@tonic-gate if ((!enter_insert_mode || !exit_insert_mode) && ((hold & HOLDQIK) || !value(vi_REDRAW) || value(vi_SLOWOPEN))) { 6217c478bd9Sstevel@tonic-gate /* 6227c478bd9Sstevel@tonic-gate * Don't want to try to use terminal 6237c478bd9Sstevel@tonic-gate * insert mode, or to try to fake it. 6247c478bd9Sstevel@tonic-gate * Just put the character out; the screen 6257c478bd9Sstevel@tonic-gate * will probably be wrong but we will fix it later. 6267c478bd9Sstevel@tonic-gate */ 6277c478bd9Sstevel@tonic-gate if (c == '\t') { 6287c478bd9Sstevel@tonic-gate vgotab(); 629*f6db9f27Scf46844 return (0); 6307c478bd9Sstevel@tonic-gate } 631*f6db9f27Scf46844 (void) vputchar(c); 6327c478bd9Sstevel@tonic-gate if (DEPTH(vcline) * WCOLS + !value(vi_REDRAW) > 6337c478bd9Sstevel@tonic-gate (destline - LINE(vcline)) * WCOLS + destcol) 634*f6db9f27Scf46844 return (0); 6357c478bd9Sstevel@tonic-gate /* 6367c478bd9Sstevel@tonic-gate * The next line is about to be clobbered 6377c478bd9Sstevel@tonic-gate * make space for another segment of this line 6387c478bd9Sstevel@tonic-gate * (on an intelligent terminal) or just remember 6397c478bd9Sstevel@tonic-gate * that next line was clobbered (on a dumb one 6407c478bd9Sstevel@tonic-gate * if we don't care to redraw the tail. 6417c478bd9Sstevel@tonic-gate */ 6427c478bd9Sstevel@tonic-gate if (insert_line) { 6437c478bd9Sstevel@tonic-gate vnpins(0); 6447c478bd9Sstevel@tonic-gate } else { 6457c478bd9Sstevel@tonic-gate int i2 = LINE(vcline) + DEPTH(vcline); 6467c478bd9Sstevel@tonic-gate if (i2 < LINE(vcline + 1) || i2 > WBOT) 647*f6db9f27Scf46844 return (0); 6487c478bd9Sstevel@tonic-gate i = destcol; 6497c478bd9Sstevel@tonic-gate vinslin(i2, 1, vcline); 6507c478bd9Sstevel@tonic-gate DEPTH(vcline)++; 6517c478bd9Sstevel@tonic-gate vigoto(i2, i); 6527c478bd9Sstevel@tonic-gate vprepins(); 6537c478bd9Sstevel@tonic-gate } 654*f6db9f27Scf46844 return (0); 6557c478bd9Sstevel@tonic-gate } 6567c478bd9Sstevel@tonic-gate 6577c478bd9Sstevel@tonic-gate /* 6587c478bd9Sstevel@tonic-gate * Compute the number of positions in the line image of the 6597c478bd9Sstevel@tonic-gate * current line. This is done from the physical image 6607c478bd9Sstevel@tonic-gate * since that is faster. Note that we have no memory 6617c478bd9Sstevel@tonic-gate * from insertion to insertion so that routines which use 6627c478bd9Sstevel@tonic-gate * us don't have to worry about moving the cursor around. 6637c478bd9Sstevel@tonic-gate */ 6647c478bd9Sstevel@tonic-gate if (*vtube0 == 0) 6657c478bd9Sstevel@tonic-gate linend = 0; 6667c478bd9Sstevel@tonic-gate else { 6677c478bd9Sstevel@tonic-gate /* 6687c478bd9Sstevel@tonic-gate * Search backwards for a non-null character 6697c478bd9Sstevel@tonic-gate * from the end of the displayed line. 6707c478bd9Sstevel@tonic-gate */ 6717c478bd9Sstevel@tonic-gate i = WCOLS * DEPTH(vcline); 6727c478bd9Sstevel@tonic-gate if (i == 0) 6737c478bd9Sstevel@tonic-gate i = WCOLS; 6747c478bd9Sstevel@tonic-gate tp = vtube0 + i; 6757c478bd9Sstevel@tonic-gate while (*--tp == 0) 6767c478bd9Sstevel@tonic-gate if (--i == 0) 6777c478bd9Sstevel@tonic-gate break; 6787c478bd9Sstevel@tonic-gate linend = i; 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate /* 6827c478bd9Sstevel@tonic-gate * We insert at a position based on the physical location 6837c478bd9Sstevel@tonic-gate * of the output cursor. 6847c478bd9Sstevel@tonic-gate */ 6857c478bd9Sstevel@tonic-gate inscol = destcol + (destline - LINE(vcline)) * WCOLS; 6867c478bd9Sstevel@tonic-gate if (c == '\t') { 6877c478bd9Sstevel@tonic-gate /* 6887c478bd9Sstevel@tonic-gate * Characters inserted from a tab must be 6897c478bd9Sstevel@tonic-gate * remembered as being part of a tab, but we can't 6907c478bd9Sstevel@tonic-gate * use QUOTE here since we really need to print blanks. 6917c478bd9Sstevel@tonic-gate * QUOTE|' ' is the representation of this. 6927c478bd9Sstevel@tonic-gate */ 6937c478bd9Sstevel@tonic-gate inssiz = tabcol(inscol, value(vi_TABSTOP)) - inscol; 6947c478bd9Sstevel@tonic-gate c = ' ' | QUOTE; 6957c478bd9Sstevel@tonic-gate } else { 6967c478bd9Sstevel@tonic-gate if ((inssiz = wcwidth(c)) < 0) 6977c478bd9Sstevel@tonic-gate inssiz = 0; 6987c478bd9Sstevel@tonic-gate } 6997c478bd9Sstevel@tonic-gate 7007c478bd9Sstevel@tonic-gate /* 7017c478bd9Sstevel@tonic-gate * If the text to be inserted is less than the number 7027c478bd9Sstevel@tonic-gate * of doomed positions, then we don't need insert mode, 7037c478bd9Sstevel@tonic-gate * rather we can just typeover. 7047c478bd9Sstevel@tonic-gate */ 7057c478bd9Sstevel@tonic-gate if (inssiz <= doomed) { 7067c478bd9Sstevel@tonic-gate endim(); 7077c478bd9Sstevel@tonic-gate if (inscol != linend) 7087c478bd9Sstevel@tonic-gate doomed -= inssiz; 7097c478bd9Sstevel@tonic-gate do { 710*f6db9f27Scf46844 (void) vputchar(c); 7117c478bd9Sstevel@tonic-gate if(c & QUOTE) 7127c478bd9Sstevel@tonic-gate inssiz--; 7137c478bd9Sstevel@tonic-gate else 7147c478bd9Sstevel@tonic-gate break; 7157c478bd9Sstevel@tonic-gate } while (inssiz); 716*f6db9f27Scf46844 return (0); 7177c478bd9Sstevel@tonic-gate } 7187c478bd9Sstevel@tonic-gate 7197c478bd9Sstevel@tonic-gate /* 7207c478bd9Sstevel@tonic-gate * Have to really do some insertion, thus 7217c478bd9Sstevel@tonic-gate * stake out the bounds of the first following 7227c478bd9Sstevel@tonic-gate * group of tabs, computing starting position, 7237c478bd9Sstevel@tonic-gate * ending position, and the number of ``spaces'' therein 7247c478bd9Sstevel@tonic-gate * so we can tell how much it will squish. 7257c478bd9Sstevel@tonic-gate */ 7267c478bd9Sstevel@tonic-gate tp = vtube0 + inscol; 7277c478bd9Sstevel@tonic-gate for (i = inscol; i < linend; i++) 7287c478bd9Sstevel@tonic-gate if (*tp++ & QUOTE) { 7297c478bd9Sstevel@tonic-gate --tp; 7307c478bd9Sstevel@tonic-gate break; 7317c478bd9Sstevel@tonic-gate } 7327c478bd9Sstevel@tonic-gate tabstart = tabend = i; 7337c478bd9Sstevel@tonic-gate tabslack = 0; 7347c478bd9Sstevel@tonic-gate while (tabend < linend) { 7357c478bd9Sstevel@tonic-gate wchar = *tp++; 7367c478bd9Sstevel@tonic-gate if ((wchar & QUOTE) == 0) 7377c478bd9Sstevel@tonic-gate break; 7387c478bd9Sstevel@tonic-gate if ((wchar & TRIM) == 0) 7397c478bd9Sstevel@tonic-gate tabslack++; 7407c478bd9Sstevel@tonic-gate tabsize++; 7417c478bd9Sstevel@tonic-gate tabend++; 7427c478bd9Sstevel@tonic-gate } 7437c478bd9Sstevel@tonic-gate tabsize = tabend - tabstart; 7447c478bd9Sstevel@tonic-gate 7457c478bd9Sstevel@tonic-gate /* 7467c478bd9Sstevel@tonic-gate * For HP's and DM's, e.g. tabslack has no meaning. 7477c478bd9Sstevel@tonic-gate */ 7487c478bd9Sstevel@tonic-gate if (!insert_null_glitch) 7497c478bd9Sstevel@tonic-gate tabslack = 0; 7507c478bd9Sstevel@tonic-gate #ifdef IDEBUG 7517c478bd9Sstevel@tonic-gate if (trace) { 7527c478bd9Sstevel@tonic-gate fprintf(trace, "inscol %d, inssiz %d, tabstart %d, ", 7537c478bd9Sstevel@tonic-gate inscol, inssiz, tabstart); 7547c478bd9Sstevel@tonic-gate fprintf(trace, "tabend %d, tabslack %d, linend %d\n", 7557c478bd9Sstevel@tonic-gate tabend, tabslack, linend); 7567c478bd9Sstevel@tonic-gate } 7577c478bd9Sstevel@tonic-gate #endif 7587c478bd9Sstevel@tonic-gate 7597c478bd9Sstevel@tonic-gate /* 7607c478bd9Sstevel@tonic-gate * The real work begins. 7617c478bd9Sstevel@tonic-gate */ 7627c478bd9Sstevel@tonic-gate slakused = 0; 7637c478bd9Sstevel@tonic-gate shft = 0; 7647c478bd9Sstevel@tonic-gate if (tabsize) { 7657c478bd9Sstevel@tonic-gate /* 7667c478bd9Sstevel@tonic-gate * There are tabs on this line. 7677c478bd9Sstevel@tonic-gate * If they need to expand, then the rest of the line 7687c478bd9Sstevel@tonic-gate * will have to be shifted over. In this case, 7697c478bd9Sstevel@tonic-gate * we will need to make sure there are no ``spaces'' 7707c478bd9Sstevel@tonic-gate * in the rest of the line (on e.g. CONCEPT-100) 7717c478bd9Sstevel@tonic-gate * and then grab another segment on the screen if this 7727c478bd9Sstevel@tonic-gate * line is now deeper. We then do the shift 7737c478bd9Sstevel@tonic-gate * implied by the insertion. 7747c478bd9Sstevel@tonic-gate */ 7757c478bd9Sstevel@tonic-gate if (inssiz >= doomed + tabcol(tabstart, value(vi_TABSTOP)) - tabstart) { 7767c478bd9Sstevel@tonic-gate if (insert_null_glitch) 7777c478bd9Sstevel@tonic-gate vrigid(); 7787c478bd9Sstevel@tonic-gate vneedpos(value(vi_TABSTOP)); 7797c478bd9Sstevel@tonic-gate vishft(); 7807c478bd9Sstevel@tonic-gate } 7817c478bd9Sstevel@tonic-gate } else if (inssiz > doomed) 7827c478bd9Sstevel@tonic-gate /* 7837c478bd9Sstevel@tonic-gate * No tabs, but line may still get deeper. 7847c478bd9Sstevel@tonic-gate */ 7857c478bd9Sstevel@tonic-gate vneedpos(inssiz - doomed); 7867c478bd9Sstevel@tonic-gate /* 7877c478bd9Sstevel@tonic-gate * Now put in the inserted characters. 7887c478bd9Sstevel@tonic-gate */ 7897c478bd9Sstevel@tonic-gate viin(c); 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate /* 7927c478bd9Sstevel@tonic-gate * Now put the cursor in its final resting place. 7937c478bd9Sstevel@tonic-gate */ 7947c478bd9Sstevel@tonic-gate destline = LINE(vcline); 7957c478bd9Sstevel@tonic-gate destcol = inscol + inssiz; 7967c478bd9Sstevel@tonic-gate vcsync(); 797*f6db9f27Scf46844 return (0); 7987c478bd9Sstevel@tonic-gate } 7997c478bd9Sstevel@tonic-gate 8007c478bd9Sstevel@tonic-gate /* 8017c478bd9Sstevel@tonic-gate * Rigidify the rest of the line after the first 8027c478bd9Sstevel@tonic-gate * group of following tabs, typing blanks over ``spaces''. 8037c478bd9Sstevel@tonic-gate */ 804*f6db9f27Scf46844 void 805*f6db9f27Scf46844 vrigid(void) 8067c478bd9Sstevel@tonic-gate { 807*f6db9f27Scf46844 int col; 808*f6db9f27Scf46844 wchar_t *tp = vtube0 + tabend; 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate for (col = tabend; col < linend; col++) 8117c478bd9Sstevel@tonic-gate if ((*tp++ & TRIM) == 0) { 8127c478bd9Sstevel@tonic-gate endim(); 8137c478bd9Sstevel@tonic-gate vgotoCL(col); 814*f6db9f27Scf46844 (void) vputchar(' ' | QUOTE); 8157c478bd9Sstevel@tonic-gate } 8167c478bd9Sstevel@tonic-gate } 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate /* 8197c478bd9Sstevel@tonic-gate * We need cnt more positions on this line. 8207c478bd9Sstevel@tonic-gate * Open up new space on the screen (this may in fact be a 8217c478bd9Sstevel@tonic-gate * screen rollup). 8227c478bd9Sstevel@tonic-gate * 8237c478bd9Sstevel@tonic-gate * On a dumb terminal we may infact redisplay the rest of the 8247c478bd9Sstevel@tonic-gate * screen here brute force to keep it pretty. 8257c478bd9Sstevel@tonic-gate */ 826*f6db9f27Scf46844 void 827*f6db9f27Scf46844 vneedpos(int cnt) 8287c478bd9Sstevel@tonic-gate { 829*f6db9f27Scf46844 int d = DEPTH(vcline); 830*f6db9f27Scf46844 int rmdr = d * WCOLS - linend; 8317c478bd9Sstevel@tonic-gate if (cnt <= rmdr - insert_null_glitch) 8327c478bd9Sstevel@tonic-gate return; 8337c478bd9Sstevel@tonic-gate endim(); 8347c478bd9Sstevel@tonic-gate vnpins(1); 8357c478bd9Sstevel@tonic-gate } 8367c478bd9Sstevel@tonic-gate 837*f6db9f27Scf46844 void 838*f6db9f27Scf46844 vnpins(int dosync) 8397c478bd9Sstevel@tonic-gate { 840*f6db9f27Scf46844 int d = DEPTH(vcline); 841*f6db9f27Scf46844 int e; 8427c478bd9Sstevel@tonic-gate 8437c478bd9Sstevel@tonic-gate e = LINE(vcline) + DEPTH(vcline); 8447c478bd9Sstevel@tonic-gate if (e < LINE(vcline + 1)) { 8457c478bd9Sstevel@tonic-gate vigoto(e, 0); 8467c478bd9Sstevel@tonic-gate vclreol(); 8477c478bd9Sstevel@tonic-gate return; 8487c478bd9Sstevel@tonic-gate } 8497c478bd9Sstevel@tonic-gate DEPTH(vcline)++; 8507c478bd9Sstevel@tonic-gate if (e < WECHO) { 8517c478bd9Sstevel@tonic-gate e = vglitchup(vcline, d); 8527c478bd9Sstevel@tonic-gate vigoto(e, 0); vclreol(); 8537c478bd9Sstevel@tonic-gate if (dosync) { 8547c478bd9Sstevel@tonic-gate int (*Ooutchar)() = Outchar; 8557c478bd9Sstevel@tonic-gate Outchar = vputchar; 8567c478bd9Sstevel@tonic-gate vsync(e + 1); 8577c478bd9Sstevel@tonic-gate Outchar = Ooutchar; 8587c478bd9Sstevel@tonic-gate } 8597c478bd9Sstevel@tonic-gate } else { 8607c478bd9Sstevel@tonic-gate vup1(); 8617c478bd9Sstevel@tonic-gate vigoto(WBOT, 0); 8627c478bd9Sstevel@tonic-gate vclreol(); 8637c478bd9Sstevel@tonic-gate } 8647c478bd9Sstevel@tonic-gate vprepins(); 8657c478bd9Sstevel@tonic-gate } 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate /* 8687c478bd9Sstevel@tonic-gate * Do the shift of the next tabstop implied by 8697c478bd9Sstevel@tonic-gate * insertion so it expands. 8707c478bd9Sstevel@tonic-gate */ 871*f6db9f27Scf46844 void 872*f6db9f27Scf46844 vishft(void) 8737c478bd9Sstevel@tonic-gate { 8747c478bd9Sstevel@tonic-gate int tshft = 0; 8757c478bd9Sstevel@tonic-gate int j; 876*f6db9f27Scf46844 int i; 877*f6db9f27Scf46844 wchar_t *tp = vtube0; 878*f6db9f27Scf46844 wchar_t *up, wchar; 8797c478bd9Sstevel@tonic-gate short oldhold = hold; 8807c478bd9Sstevel@tonic-gate 8817c478bd9Sstevel@tonic-gate shft = value(vi_TABSTOP); 8827c478bd9Sstevel@tonic-gate hold |= HOLDPUPD; 8837c478bd9Sstevel@tonic-gate if (!enter_insert_mode && !exit_insert_mode) { 8847c478bd9Sstevel@tonic-gate /* 8857c478bd9Sstevel@tonic-gate * Dumb terminals are easy, we just have 8867c478bd9Sstevel@tonic-gate * to retype the text. 8877c478bd9Sstevel@tonic-gate */ 8887c478bd9Sstevel@tonic-gate vigotoCL(tabend + shft); 8897c478bd9Sstevel@tonic-gate up = tp + tabend; 8907c478bd9Sstevel@tonic-gate for (i = tabend; i < linend; i++) 8917c478bd9Sstevel@tonic-gate if((wchar = *up++) != FILLER) 892*f6db9f27Scf46844 (void) vputchar(wchar); 8937c478bd9Sstevel@tonic-gate } else if (insert_null_glitch) { 8947c478bd9Sstevel@tonic-gate /* 8957c478bd9Sstevel@tonic-gate * CONCEPT-like terminals do most of the work for us, 8967c478bd9Sstevel@tonic-gate * we don't have to muck with simulation of multi-line 8977c478bd9Sstevel@tonic-gate * insert mode. Some of the shifting may come for free 8987c478bd9Sstevel@tonic-gate * also if the tabs don't have enough slack to take up 8997c478bd9Sstevel@tonic-gate * all the inserted characters. 9007c478bd9Sstevel@tonic-gate */ 9017c478bd9Sstevel@tonic-gate i = shft; 9027c478bd9Sstevel@tonic-gate slakused = inssiz - doomed; 9037c478bd9Sstevel@tonic-gate if (slakused > tabslack) { 9047c478bd9Sstevel@tonic-gate i -= slakused - tabslack; 9057c478bd9Sstevel@tonic-gate slakused -= tabslack; 9067c478bd9Sstevel@tonic-gate } 9077c478bd9Sstevel@tonic-gate if (i > 0 && tabend != linend) { 9087c478bd9Sstevel@tonic-gate tshft = i; 9097c478bd9Sstevel@tonic-gate vgotoCL(tabend); 9107c478bd9Sstevel@tonic-gate goim(); 9117c478bd9Sstevel@tonic-gate do 912*f6db9f27Scf46844 (void) vputchar(' ' | QUOTE); 9137c478bd9Sstevel@tonic-gate while (--i); 9147c478bd9Sstevel@tonic-gate } 9157c478bd9Sstevel@tonic-gate } else { 9167c478bd9Sstevel@tonic-gate /* 9177c478bd9Sstevel@tonic-gate * HP and Datamedia type terminals have to have multi-line 9187c478bd9Sstevel@tonic-gate * insert faked. Hack each segment after where we are 9197c478bd9Sstevel@tonic-gate * (going backwards to where we are.) We then can 9207c478bd9Sstevel@tonic-gate * hack the segment where the end of the first following 9217c478bd9Sstevel@tonic-gate * tab group is. 9227c478bd9Sstevel@tonic-gate */ 9237c478bd9Sstevel@tonic-gate for (j = DEPTH(vcline) - 1; j > (tabend + shft) / WCOLS; j--) { 9247c478bd9Sstevel@tonic-gate vgotoCL(j * WCOLS); 9257c478bd9Sstevel@tonic-gate goim(); 9267c478bd9Sstevel@tonic-gate up = tp + j * WCOLS - shft; 9277c478bd9Sstevel@tonic-gate i = shft; 9287c478bd9Sstevel@tonic-gate do { 9297c478bd9Sstevel@tonic-gate wchar_t wchar; 9307c478bd9Sstevel@tonic-gate if (wchar = *up) { 9317c478bd9Sstevel@tonic-gate if(wchar != FILLER) 932*f6db9f27Scf46844 (void) vputchar(wchar); 9337c478bd9Sstevel@tonic-gate up++; 9347c478bd9Sstevel@tonic-gate } else 9357c478bd9Sstevel@tonic-gate break; 9367c478bd9Sstevel@tonic-gate } while (--i); 9377c478bd9Sstevel@tonic-gate } 9387c478bd9Sstevel@tonic-gate vigotoCL(tabstart); 9397c478bd9Sstevel@tonic-gate i = shft - (inssiz - doomed); 9407c478bd9Sstevel@tonic-gate if (i > 0) { 9417c478bd9Sstevel@tonic-gate tabslack = inssiz - doomed; 9427c478bd9Sstevel@tonic-gate vcsync(); 9437c478bd9Sstevel@tonic-gate goim(); 9447c478bd9Sstevel@tonic-gate do 945*f6db9f27Scf46844 (void) vputchar(' '); 9467c478bd9Sstevel@tonic-gate while (--i); 9477c478bd9Sstevel@tonic-gate } 9487c478bd9Sstevel@tonic-gate } 9497c478bd9Sstevel@tonic-gate /* 9507c478bd9Sstevel@tonic-gate * Now do the data moving in the internal screen 9517c478bd9Sstevel@tonic-gate * image which is common to all three cases. 9527c478bd9Sstevel@tonic-gate */ 9537c478bd9Sstevel@tonic-gate tp += linend; 9547c478bd9Sstevel@tonic-gate up = tp + shft; 9557c478bd9Sstevel@tonic-gate i = linend - tabend; 9567c478bd9Sstevel@tonic-gate if (i > 0) 9577c478bd9Sstevel@tonic-gate do 9587c478bd9Sstevel@tonic-gate *--up = *--tp; 9597c478bd9Sstevel@tonic-gate while (--i); 9607c478bd9Sstevel@tonic-gate if (insert_null_glitch && tshft) { 9617c478bd9Sstevel@tonic-gate i = tshft; 9627c478bd9Sstevel@tonic-gate do 9637c478bd9Sstevel@tonic-gate *--up = ' ' | QUOTE; 9647c478bd9Sstevel@tonic-gate while (--i); 9657c478bd9Sstevel@tonic-gate } 9667c478bd9Sstevel@tonic-gate hold = oldhold; 9677c478bd9Sstevel@tonic-gate } 9687c478bd9Sstevel@tonic-gate 9697c478bd9Sstevel@tonic-gate /* 9707c478bd9Sstevel@tonic-gate * Now do the insert of the characters (finally). 9717c478bd9Sstevel@tonic-gate */ 972*f6db9f27Scf46844 void 973*f6db9f27Scf46844 viin(wchar_t c) 9747c478bd9Sstevel@tonic-gate { 975*f6db9f27Scf46844 wchar_t *tp, *up; 976*f6db9f27Scf46844 int i, j; 977*f6db9f27Scf46844 bool noim = 0; 9787c478bd9Sstevel@tonic-gate int remdoom; 9797c478bd9Sstevel@tonic-gate short oldhold = hold; 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate hold |= HOLDPUPD; 9827c478bd9Sstevel@tonic-gate if (tabsize && (enter_insert_mode && exit_insert_mode) && inssiz - doomed > tabslack) 9837c478bd9Sstevel@tonic-gate /* 9847c478bd9Sstevel@tonic-gate * There is a tab out there which will be affected 9857c478bd9Sstevel@tonic-gate * by the insertion since there aren't enough doomed 9867c478bd9Sstevel@tonic-gate * characters to take up all the insertion and we do 9877c478bd9Sstevel@tonic-gate * have insert mode capability. 9887c478bd9Sstevel@tonic-gate */ 9897c478bd9Sstevel@tonic-gate if (inscol + doomed == tabstart) { 9907c478bd9Sstevel@tonic-gate /* 9917c478bd9Sstevel@tonic-gate * The end of the doomed characters sits right at the 9927c478bd9Sstevel@tonic-gate * start of the tabs, then we don't need to use insert 9937c478bd9Sstevel@tonic-gate * mode; unless the tab has already been expanded 9947c478bd9Sstevel@tonic-gate * in which case we MUST use insert mode. 9957c478bd9Sstevel@tonic-gate */ 9967c478bd9Sstevel@tonic-gate slakused = 0; 9977c478bd9Sstevel@tonic-gate noim = !shft; 9987c478bd9Sstevel@tonic-gate } else { 9997c478bd9Sstevel@tonic-gate /* 10007c478bd9Sstevel@tonic-gate * The last really special case to handle is case 10017c478bd9Sstevel@tonic-gate * where the tab is just sitting there and doesn't 10027c478bd9Sstevel@tonic-gate * have enough slack to let the insertion take 10037c478bd9Sstevel@tonic-gate * place without shifting the rest of the line 10047c478bd9Sstevel@tonic-gate * over. In this case we have to go out and 10057c478bd9Sstevel@tonic-gate * delete some characters of the tab before we start 10067c478bd9Sstevel@tonic-gate * or the answer will be wrong, as the rest of the 10077c478bd9Sstevel@tonic-gate * line will have been shifted. This code means 10087c478bd9Sstevel@tonic-gate * that terminals with only insert character (no 10097c478bd9Sstevel@tonic-gate * delete character) won't work correctly. 10107c478bd9Sstevel@tonic-gate */ 10117c478bd9Sstevel@tonic-gate i = inssiz - doomed - tabslack - slakused; 10127c478bd9Sstevel@tonic-gate i %= value(vi_TABSTOP); 10137c478bd9Sstevel@tonic-gate if (i > 0) { 10147c478bd9Sstevel@tonic-gate vgotoCL(tabstart); 10157c478bd9Sstevel@tonic-gate godm(); 10167c478bd9Sstevel@tonic-gate for (i = inssiz - doomed - tabslack; i > 0; i--) 10177c478bd9Sstevel@tonic-gate vputp(delete_character, DEPTH(vcline)); 10187c478bd9Sstevel@tonic-gate enddm(); 10197c478bd9Sstevel@tonic-gate } 10207c478bd9Sstevel@tonic-gate } 10217c478bd9Sstevel@tonic-gate 10227c478bd9Sstevel@tonic-gate /* 10237c478bd9Sstevel@tonic-gate * Now put out the characters of the actual insertion. 10247c478bd9Sstevel@tonic-gate */ 10257c478bd9Sstevel@tonic-gate vigotoCL(inscol); 10267c478bd9Sstevel@tonic-gate remdoom = doomed; 10277c478bd9Sstevel@tonic-gate for (i = inssiz; i > 0; i--) { 10287c478bd9Sstevel@tonic-gate if (remdoom > 0) { 10297c478bd9Sstevel@tonic-gate remdoom--; 10307c478bd9Sstevel@tonic-gate endim(); 10317c478bd9Sstevel@tonic-gate } else if (noim) 10327c478bd9Sstevel@tonic-gate endim(); 10337c478bd9Sstevel@tonic-gate else if (enter_insert_mode && exit_insert_mode) { 10347c478bd9Sstevel@tonic-gate vcsync(); 10357c478bd9Sstevel@tonic-gate goim(); 10367c478bd9Sstevel@tonic-gate } 1037*f6db9f27Scf46844 (void) vputchar(c); 10387c478bd9Sstevel@tonic-gate if((c & QUOTE) == 0) 10397c478bd9Sstevel@tonic-gate break; 10407c478bd9Sstevel@tonic-gate } 10417c478bd9Sstevel@tonic-gate 10427c478bd9Sstevel@tonic-gate if (!enter_insert_mode || !exit_insert_mode) { 10437c478bd9Sstevel@tonic-gate /* 10447c478bd9Sstevel@tonic-gate * We are a dumb terminal; brute force update 10457c478bd9Sstevel@tonic-gate * the rest of the line; this is very much an n^^2 process, 10467c478bd9Sstevel@tonic-gate * and totally unreasonable at low speed. 10477c478bd9Sstevel@tonic-gate * 10487c478bd9Sstevel@tonic-gate * You asked for it, you get it. 10497c478bd9Sstevel@tonic-gate */ 10507c478bd9Sstevel@tonic-gate int width; 10517c478bd9Sstevel@tonic-gate tp = vtube0 + inscol + doomed; 10527c478bd9Sstevel@tonic-gate for (i = inscol + doomed; i < tabstart; i++) { 10537c478bd9Sstevel@tonic-gate if(*tp != FILLER) 1054*f6db9f27Scf46844 (void) vputchar(*tp); 10557c478bd9Sstevel@tonic-gate tp++; 10567c478bd9Sstevel@tonic-gate } 10577c478bd9Sstevel@tonic-gate hold = oldhold; 10587c478bd9Sstevel@tonic-gate vigotoCL(tabstart + inssiz - doomed); 10597c478bd9Sstevel@tonic-gate for (i = tabsize - (inssiz - doomed) + shft; i > 0; i--) 1060*f6db9f27Scf46844 (void) vputchar(' ' | QUOTE); 10617c478bd9Sstevel@tonic-gate } else { 10627c478bd9Sstevel@tonic-gate if (!insert_null_glitch) { 10637c478bd9Sstevel@tonic-gate /* 10647c478bd9Sstevel@tonic-gate * On terminals without multi-line 10657c478bd9Sstevel@tonic-gate * insert in the hardware, we must go fix the segments 10667c478bd9Sstevel@tonic-gate * between the inserted text and the following 10677c478bd9Sstevel@tonic-gate * tabs, if they are on different lines. 10687c478bd9Sstevel@tonic-gate * 10697c478bd9Sstevel@tonic-gate * Aaargh. 10707c478bd9Sstevel@tonic-gate */ 10717c478bd9Sstevel@tonic-gate tp = vtube0; 10727c478bd9Sstevel@tonic-gate for (j = (inscol + inssiz - 1) / WCOLS + 1; 10737c478bd9Sstevel@tonic-gate j <= (tabstart + inssiz - doomed - 1) / WCOLS; j++) { 10747c478bd9Sstevel@tonic-gate vgotoCL(j * WCOLS); 10757c478bd9Sstevel@tonic-gate i = inssiz - doomed; 10767c478bd9Sstevel@tonic-gate up = tp + j * WCOLS - i; 10777c478bd9Sstevel@tonic-gate goim(); 10787c478bd9Sstevel@tonic-gate do { 10797c478bd9Sstevel@tonic-gate wchar_t wchar; 10807c478bd9Sstevel@tonic-gate if((wchar = *up++) != FILLER) 1081*f6db9f27Scf46844 (void) vputchar(wchar); 10827c478bd9Sstevel@tonic-gate } while (--i && *up); 10837c478bd9Sstevel@tonic-gate } 10847c478bd9Sstevel@tonic-gate } else { 10857c478bd9Sstevel@tonic-gate /* 10867c478bd9Sstevel@tonic-gate * On terminals with multi line inserts, 10877c478bd9Sstevel@tonic-gate * life is simpler, just reflect eating of 10887c478bd9Sstevel@tonic-gate * the slack. 10897c478bd9Sstevel@tonic-gate */ 10907c478bd9Sstevel@tonic-gate tp = vtube0 + tabend; 10917c478bd9Sstevel@tonic-gate for (i = tabsize - (inssiz - doomed); i >= 0; i--) { 10927c478bd9Sstevel@tonic-gate if ((*--tp & (QUOTE|TRIM)) == QUOTE) { 10937c478bd9Sstevel@tonic-gate --tabslack; 10947c478bd9Sstevel@tonic-gate if (tabslack >= slakused) 10957c478bd9Sstevel@tonic-gate continue; 10967c478bd9Sstevel@tonic-gate } 10977c478bd9Sstevel@tonic-gate *tp = ' ' | QUOTE; 10987c478bd9Sstevel@tonic-gate } 10997c478bd9Sstevel@tonic-gate } 11007c478bd9Sstevel@tonic-gate /* 11017c478bd9Sstevel@tonic-gate * Blank out the shifted positions to be tab positions. 11027c478bd9Sstevel@tonic-gate */ 11037c478bd9Sstevel@tonic-gate if (shft) { 11047c478bd9Sstevel@tonic-gate tp = vtube0 + tabend + shft; 11057c478bd9Sstevel@tonic-gate for (i = tabsize - (inssiz - doomed) + shft; i > 0; i--) 11067c478bd9Sstevel@tonic-gate if ((*--tp & QUOTE) == 0) 11077c478bd9Sstevel@tonic-gate *tp = ' ' | QUOTE; 11087c478bd9Sstevel@tonic-gate } 11097c478bd9Sstevel@tonic-gate } 11107c478bd9Sstevel@tonic-gate 11117c478bd9Sstevel@tonic-gate /* 11127c478bd9Sstevel@tonic-gate * Finally, complete the screen image update 11137c478bd9Sstevel@tonic-gate * to reflect the insertion. 11147c478bd9Sstevel@tonic-gate */ 11157c478bd9Sstevel@tonic-gate hold = oldhold; 11167c478bd9Sstevel@tonic-gate tp = vtube0 + tabstart; up = tp + inssiz - doomed; 11177c478bd9Sstevel@tonic-gate for (i = tabstart; i > inscol + doomed; i--) 11187c478bd9Sstevel@tonic-gate *--up = *--tp; 11197c478bd9Sstevel@tonic-gate for (i = inssiz; i > 0; i--) 11207c478bd9Sstevel@tonic-gate if((c & QUOTE) == 0) { 11217c478bd9Sstevel@tonic-gate int width = wcwidth(c); 11227c478bd9Sstevel@tonic-gate if (width < 0) 11237c478bd9Sstevel@tonic-gate width = 0; 11247c478bd9Sstevel@tonic-gate up -= width; 11257c478bd9Sstevel@tonic-gate *up++ = c; 11267c478bd9Sstevel@tonic-gate if(width) 11277c478bd9Sstevel@tonic-gate while(--width) 11287c478bd9Sstevel@tonic-gate *up++ = FILLER; 11297c478bd9Sstevel@tonic-gate break; 11307c478bd9Sstevel@tonic-gate } 11317c478bd9Sstevel@tonic-gate else 11327c478bd9Sstevel@tonic-gate *--up = c; 11337c478bd9Sstevel@tonic-gate doomed = 0; 11347c478bd9Sstevel@tonic-gate } 11357c478bd9Sstevel@tonic-gate 11367c478bd9Sstevel@tonic-gate /* 11377c478bd9Sstevel@tonic-gate * Go into ``delete mode''. If the 11387c478bd9Sstevel@tonic-gate * sequence which goes into delete mode 11397c478bd9Sstevel@tonic-gate * is the same as that which goes into insert 11407c478bd9Sstevel@tonic-gate * mode, then we are in delete mode already. 11417c478bd9Sstevel@tonic-gate */ 1142*f6db9f27Scf46844 void 1143*f6db9f27Scf46844 godm(void) 11447c478bd9Sstevel@tonic-gate { 11457c478bd9Sstevel@tonic-gate 11467c478bd9Sstevel@tonic-gate if (insmode) { 11477c478bd9Sstevel@tonic-gate if (eq(enter_delete_mode, enter_insert_mode)) 11487c478bd9Sstevel@tonic-gate return; 11497c478bd9Sstevel@tonic-gate endim(); 11507c478bd9Sstevel@tonic-gate } 11517c478bd9Sstevel@tonic-gate vputp(enter_delete_mode, 0); 11527c478bd9Sstevel@tonic-gate } 11537c478bd9Sstevel@tonic-gate 11547c478bd9Sstevel@tonic-gate /* 11557c478bd9Sstevel@tonic-gate * If we are coming out of delete mode, but 11567c478bd9Sstevel@tonic-gate * delete and insert mode end with the same sequence, 11577c478bd9Sstevel@tonic-gate * it wins to pretend we are now in insert mode, 11587c478bd9Sstevel@tonic-gate * since we will likely want to be there again soon 11597c478bd9Sstevel@tonic-gate * if we just moved over to delete space from part of 11607c478bd9Sstevel@tonic-gate * a tab (above). 11617c478bd9Sstevel@tonic-gate */ 1162*f6db9f27Scf46844 void 1163*f6db9f27Scf46844 enddm(void) 11647c478bd9Sstevel@tonic-gate { 11657c478bd9Sstevel@tonic-gate 11667c478bd9Sstevel@tonic-gate if (eq(enter_delete_mode, enter_insert_mode)) { 11677c478bd9Sstevel@tonic-gate insmode = 1; 11687c478bd9Sstevel@tonic-gate return; 11697c478bd9Sstevel@tonic-gate } 11707c478bd9Sstevel@tonic-gate vputp(exit_delete_mode, 0); 11717c478bd9Sstevel@tonic-gate } 11727c478bd9Sstevel@tonic-gate 11737c478bd9Sstevel@tonic-gate /* 11747c478bd9Sstevel@tonic-gate * In and out of insert mode. 11757c478bd9Sstevel@tonic-gate * Note that the code here demands that there be 11767c478bd9Sstevel@tonic-gate * a string for insert mode (the null string) even 11777c478bd9Sstevel@tonic-gate * if the terminal does all insertions a single character 11787c478bd9Sstevel@tonic-gate * at a time, since it branches based on whether enter_insert_mode is null. 11797c478bd9Sstevel@tonic-gate */ 1180*f6db9f27Scf46844 void 1181*f6db9f27Scf46844 goim(void) 11827c478bd9Sstevel@tonic-gate { 11837c478bd9Sstevel@tonic-gate 11847c478bd9Sstevel@tonic-gate if (!insmode) 11857c478bd9Sstevel@tonic-gate vputp(enter_insert_mode, 0); 11867c478bd9Sstevel@tonic-gate insmode = 1; 11877c478bd9Sstevel@tonic-gate } 11887c478bd9Sstevel@tonic-gate 1189*f6db9f27Scf46844 void 1190*f6db9f27Scf46844 endim(void) 11917c478bd9Sstevel@tonic-gate { 11927c478bd9Sstevel@tonic-gate 11937c478bd9Sstevel@tonic-gate if (insmode) { 11947c478bd9Sstevel@tonic-gate vputp(exit_insert_mode, 0); 11957c478bd9Sstevel@tonic-gate insmode = 0; 11967c478bd9Sstevel@tonic-gate } 11977c478bd9Sstevel@tonic-gate } 11987c478bd9Sstevel@tonic-gate 11997c478bd9Sstevel@tonic-gate /* 12007c478bd9Sstevel@tonic-gate * Put the character c on the screen at the current cursor position. 12017c478bd9Sstevel@tonic-gate * This routine handles wraparound and scrolling and understands not 12027c478bd9Sstevel@tonic-gate * to roll when splitw is set, i.e. we are working in the echo area. 12037c478bd9Sstevel@tonic-gate * There is a bunch of hacking here dealing with the difference between 12047c478bd9Sstevel@tonic-gate * QUOTE, QUOTE|' ', and ' ' for CONCEPT-100 like terminals, and also 12057c478bd9Sstevel@tonic-gate * code to deal with terminals which overstrike, including CRT's where 12067c478bd9Sstevel@tonic-gate * you can erase overstrikes with some work. CRT's which do underlining 12077c478bd9Sstevel@tonic-gate * implicitly which has to be erased (like CONCEPTS) are also handled. 12087c478bd9Sstevel@tonic-gate */ 1209*f6db9f27Scf46844 int 1210*f6db9f27Scf46844 vputchar(wchar_t c) 12117c478bd9Sstevel@tonic-gate { 12127c478bd9Sstevel@tonic-gate unsigned char multic[MULTI_BYTE_MAX]; 1213*f6db9f27Scf46844 wchar_t *tp; 1214*f6db9f27Scf46844 int d, length, length2, bytelength; 1215*f6db9f27Scf46844 unsigned char *p; 12167c478bd9Sstevel@tonic-gate short oldhold = hold; 12177c478bd9Sstevel@tonic-gate 12187c478bd9Sstevel@tonic-gate c &= (QUOTE|TRIM); 12197c478bd9Sstevel@tonic-gate #ifdef TRACE 12207c478bd9Sstevel@tonic-gate if (trace) { 12217c478bd9Sstevel@tonic-gate tracec(c); 12227c478bd9Sstevel@tonic-gate } 12237c478bd9Sstevel@tonic-gate #endif 12247c478bd9Sstevel@tonic-gate if(c & QUOTE) 12257c478bd9Sstevel@tonic-gate length = 1; 12267c478bd9Sstevel@tonic-gate else 12277c478bd9Sstevel@tonic-gate if ((length = wcwidth(c)) < 0) 12287c478bd9Sstevel@tonic-gate length = 0; 12297c478bd9Sstevel@tonic-gate /* Fix problem of >79 chars on echo line. */ 12307c478bd9Sstevel@tonic-gate if (destcol >= WCOLS-1 && splitw && destline == WECHO) 12317c478bd9Sstevel@tonic-gate pofix(); 12327c478bd9Sstevel@tonic-gate if (destcol >= WCOLS) { 12337c478bd9Sstevel@tonic-gate destline += destcol / WCOLS; 12347c478bd9Sstevel@tonic-gate destcol %= WCOLS; 12357c478bd9Sstevel@tonic-gate } 12367c478bd9Sstevel@tonic-gate if (destline > WBOT && (!splitw || destline > WECHO)) 12377c478bd9Sstevel@tonic-gate vrollup(destline); 12387c478bd9Sstevel@tonic-gate if (destline < 0) 12397c478bd9Sstevel@tonic-gate error(gettext("Line too long to fit on screen")); 12407c478bd9Sstevel@tonic-gate if(destcol + length - 1 >= WCOLS) { 12417c478bd9Sstevel@tonic-gate /* print out split multibyte character using '>' */ 12427c478bd9Sstevel@tonic-gate hold |= HOLDPUPD; 12437c478bd9Sstevel@tonic-gate #ifdef PRESUNEUC 12447c478bd9Sstevel@tonic-gate while(length--) 1245*f6db9f27Scf46844 (void) vputchar('>'); 12467c478bd9Sstevel@tonic-gate #else 12477c478bd9Sstevel@tonic-gate if (mc_wrap == 0) 12487c478bd9Sstevel@tonic-gate while(length--) 1249*f6db9f27Scf46844 (void) vputchar(mc_filler); 12507c478bd9Sstevel@tonic-gate else { 12517c478bd9Sstevel@tonic-gate for (length = WCOLS - destcol; length; length--) 1252*f6db9f27Scf46844 (void) vputchar(mc_filler); 12537c478bd9Sstevel@tonic-gate hold = oldhold; 12547c478bd9Sstevel@tonic-gate if ((length = wcwidth(c)) < 0) 12557c478bd9Sstevel@tonic-gate length = 0; 1256*f6db9f27Scf46844 (void) vputchar(c); 12577c478bd9Sstevel@tonic-gate } 12587c478bd9Sstevel@tonic-gate #endif /* PRESUNEUC */ 12597c478bd9Sstevel@tonic-gate hold = oldhold; 1260*f6db9f27Scf46844 return (0); 12617c478bd9Sstevel@tonic-gate } 12627c478bd9Sstevel@tonic-gate tp = vtube[destline] + destcol; 12637c478bd9Sstevel@tonic-gate switch (c) { 12647c478bd9Sstevel@tonic-gate 12657c478bd9Sstevel@tonic-gate case '\t': 12667c478bd9Sstevel@tonic-gate vgotab(); 1267*f6db9f27Scf46844 return (0); 12687c478bd9Sstevel@tonic-gate 12697c478bd9Sstevel@tonic-gate case ' ': 12707c478bd9Sstevel@tonic-gate /* 12717c478bd9Sstevel@tonic-gate * We can get away without printing a space in a number 12727c478bd9Sstevel@tonic-gate * of cases, but not always. We get away with doing nothing 12737c478bd9Sstevel@tonic-gate * if we are not in insert mode, and not on a CONCEPT-100 12747c478bd9Sstevel@tonic-gate * like terminal, and either not in hardcopy open or in hardcopy 12757c478bd9Sstevel@tonic-gate * open on a terminal with no overstriking, provided, 12767c478bd9Sstevel@tonic-gate * in all cases, that nothing has ever been displayed 12777c478bd9Sstevel@tonic-gate * at this position. Ugh. 12787c478bd9Sstevel@tonic-gate */ 12797c478bd9Sstevel@tonic-gate if (!insmode && !insert_null_glitch && (state != HARDOPEN || over_strike) && (*tp&TRIM) == 0) { 12807c478bd9Sstevel@tonic-gate *tp = ' '; 12817c478bd9Sstevel@tonic-gate destcol++; 1282*f6db9f27Scf46844 return (0); 12837c478bd9Sstevel@tonic-gate } 12847c478bd9Sstevel@tonic-gate goto def; 12857c478bd9Sstevel@tonic-gate 12867c478bd9Sstevel@tonic-gate case QUOTE: 12877c478bd9Sstevel@tonic-gate if (insmode) { 12887c478bd9Sstevel@tonic-gate /* 12897c478bd9Sstevel@tonic-gate * When in insert mode, tabs have to expand 12907c478bd9Sstevel@tonic-gate * to real, printed blanks. 12917c478bd9Sstevel@tonic-gate */ 12927c478bd9Sstevel@tonic-gate c = ' ' | QUOTE; 12937c478bd9Sstevel@tonic-gate goto def; 12947c478bd9Sstevel@tonic-gate } 12957c478bd9Sstevel@tonic-gate if (*tp == 0) { 12967c478bd9Sstevel@tonic-gate /* 12977c478bd9Sstevel@tonic-gate * A ``space''. 12987c478bd9Sstevel@tonic-gate */ 12997c478bd9Sstevel@tonic-gate if ((hold & HOLDPUPD) == 0) 13007c478bd9Sstevel@tonic-gate *tp = QUOTE; 13017c478bd9Sstevel@tonic-gate destcol++; 1302*f6db9f27Scf46844 return (0); 13037c478bd9Sstevel@tonic-gate } 13047c478bd9Sstevel@tonic-gate /* 13057c478bd9Sstevel@tonic-gate * A ``space'' ontop of a part of a tab. 13067c478bd9Sstevel@tonic-gate */ 13077c478bd9Sstevel@tonic-gate if (*tp & QUOTE) { 13087c478bd9Sstevel@tonic-gate destcol++; 1309*f6db9f27Scf46844 return (0); 13107c478bd9Sstevel@tonic-gate } 13117c478bd9Sstevel@tonic-gate c = ' ' | QUOTE; 13127c478bd9Sstevel@tonic-gate /* fall into ... */ 13137c478bd9Sstevel@tonic-gate 13147c478bd9Sstevel@tonic-gate def: 13157c478bd9Sstevel@tonic-gate default: 13167c478bd9Sstevel@tonic-gate d = *tp & TRIM; 13177c478bd9Sstevel@tonic-gate /* 13187c478bd9Sstevel@tonic-gate * Now get away with doing nothing if the characters 13197c478bd9Sstevel@tonic-gate * are the same, provided we are not in insert mode 13207c478bd9Sstevel@tonic-gate * and if we are in hardopen, that the terminal has overstrike. 13217c478bd9Sstevel@tonic-gate */ 13227c478bd9Sstevel@tonic-gate #ifdef PRESUNEUC 13237c478bd9Sstevel@tonic-gate if (rewrite == _OFF && d == (c & TRIM) && !insmode && (state != HARDOPEN || over_strike)) { 13247c478bd9Sstevel@tonic-gate #else 13257c478bd9Sstevel@tonic-gate if (rewrite == _OFF && d == (c & TRIM) && !insmode && 13267c478bd9Sstevel@tonic-gate (state != HARDOPEN || over_strike) && !multibyte) { 13277c478bd9Sstevel@tonic-gate #endif /* PRESUNEUC */ 13287c478bd9Sstevel@tonic-gate if ((hold & HOLDPUPD) == 0) { 13297c478bd9Sstevel@tonic-gate *tp++ = c; 13307c478bd9Sstevel@tonic-gate if(length) { 13317c478bd9Sstevel@tonic-gate length2 = length; 13327c478bd9Sstevel@tonic-gate while(--length2) 13337c478bd9Sstevel@tonic-gate *tp++ = FILLER; 13347c478bd9Sstevel@tonic-gate } 13357c478bd9Sstevel@tonic-gate } 13367c478bd9Sstevel@tonic-gate destcol += length; 1337*f6db9f27Scf46844 return (0); 13387c478bd9Sstevel@tonic-gate } 13397c478bd9Sstevel@tonic-gate /* 13407c478bd9Sstevel@tonic-gate * Backwards looking optimization. 13417c478bd9Sstevel@tonic-gate * The low level cursor motion routines will use 13427c478bd9Sstevel@tonic-gate * a cursor motion right sequence to step 1 character 13437c478bd9Sstevel@tonic-gate * right. On, e.g., a DM3025A this is 2 characters 13447c478bd9Sstevel@tonic-gate * and printing is noticeably slower at 300 baud. 13457c478bd9Sstevel@tonic-gate * Since the low level routines are not allowed to use 13467c478bd9Sstevel@tonic-gate * spaces for positioning, we discover the common 13477c478bd9Sstevel@tonic-gate * case of a single space here and force a space 13487c478bd9Sstevel@tonic-gate * to be printed. 13497c478bd9Sstevel@tonic-gate */ 13507c478bd9Sstevel@tonic-gate if (destcol == outcol + 1 && tp[-1] == ' ' && outline == destline) { 1351*f6db9f27Scf46844 (void) vputc(' '); 13527c478bd9Sstevel@tonic-gate outcol++; 13537c478bd9Sstevel@tonic-gate } 13547c478bd9Sstevel@tonic-gate 13557c478bd9Sstevel@tonic-gate /* 13567c478bd9Sstevel@tonic-gate * This is an inline expansion a call to vcsync() dictated 13577c478bd9Sstevel@tonic-gate * by high frequency in a profile. 13587c478bd9Sstevel@tonic-gate */ 13597c478bd9Sstevel@tonic-gate if (outcol != destcol || outline != destline) 13607c478bd9Sstevel@tonic-gate vgoto(destline, destcol); 13617c478bd9Sstevel@tonic-gate 13627c478bd9Sstevel@tonic-gate /* 13637c478bd9Sstevel@tonic-gate * Deal with terminals which have overstrike. 13647c478bd9Sstevel@tonic-gate * We handle erasing general overstrikes, erasing 13657c478bd9Sstevel@tonic-gate * underlines on terminals (such as CONCEPTS) which 13667c478bd9Sstevel@tonic-gate * do underlining correctly automatically (e.g. on nroff 13677c478bd9Sstevel@tonic-gate * output), and remembering, in hardcopy mode, 13687c478bd9Sstevel@tonic-gate * that we have overstruct something. 13697c478bd9Sstevel@tonic-gate */ 13707c478bd9Sstevel@tonic-gate if (!insmode && d && d != ' ' && d != (c & TRIM)) { 13717c478bd9Sstevel@tonic-gate if (erase_overstrike && (over_strike || transparent_underline && (c == '_' || d == '_'))) { 1372*f6db9f27Scf46844 (void) vputc(' '); 13737c478bd9Sstevel@tonic-gate outcol++, destcol++; 13747c478bd9Sstevel@tonic-gate back1(); 13757c478bd9Sstevel@tonic-gate } else 13767c478bd9Sstevel@tonic-gate rubble = 1; 13777c478bd9Sstevel@tonic-gate } 13787c478bd9Sstevel@tonic-gate 13797c478bd9Sstevel@tonic-gate /* 13807c478bd9Sstevel@tonic-gate * Unless we are just bashing characters around for 13817c478bd9Sstevel@tonic-gate * inner working of insert mode, update the display. 13827c478bd9Sstevel@tonic-gate */ 13837c478bd9Sstevel@tonic-gate if ((hold & HOLDPUPD) == 0) { 13847c478bd9Sstevel@tonic-gate *tp++ = c; 13857c478bd9Sstevel@tonic-gate length2 = length; 13867c478bd9Sstevel@tonic-gate /* put in filler characters */ 13877c478bd9Sstevel@tonic-gate if(length) 13887c478bd9Sstevel@tonic-gate while(--length2) 13897c478bd9Sstevel@tonic-gate *tp++ = FILLER; 13907c478bd9Sstevel@tonic-gate 13917c478bd9Sstevel@tonic-gate } 13927c478bd9Sstevel@tonic-gate /* 13937c478bd9Sstevel@tonic-gate * In insert mode, put out the insert_character sequence, padded 13947c478bd9Sstevel@tonic-gate * based on the depth of the current line. 13957c478bd9Sstevel@tonic-gate * A terminal which had no real insert mode, rather 13967c478bd9Sstevel@tonic-gate * opening a character position at a time could do this. 13977c478bd9Sstevel@tonic-gate * Actually should use depth to end of current line 13987c478bd9Sstevel@tonic-gate * but this rarely matters. 13997c478bd9Sstevel@tonic-gate */ 14007c478bd9Sstevel@tonic-gate if (insmode) 14017c478bd9Sstevel@tonic-gate vputp(insert_character, DEPTH(vcline)); 14027c478bd9Sstevel@tonic-gate c &= TRIM; 14037c478bd9Sstevel@tonic-gate bytelength = wctomb((char *)multic, c); 14047c478bd9Sstevel@tonic-gate p = multic; 14057c478bd9Sstevel@tonic-gate while(bytelength--) 1406*f6db9f27Scf46844 (void) vputc(*p++); 14077c478bd9Sstevel@tonic-gate 14087c478bd9Sstevel@tonic-gate /* 14097c478bd9Sstevel@tonic-gate * In insert mode, insert_padding is a post insert pad. 14107c478bd9Sstevel@tonic-gate */ 14117c478bd9Sstevel@tonic-gate if (insmode) 14127c478bd9Sstevel@tonic-gate vputp(insert_padding, DEPTH(vcline)); 14137c478bd9Sstevel@tonic-gate destcol += length; 14147c478bd9Sstevel@tonic-gate outcol += length; 14157c478bd9Sstevel@tonic-gate 14167c478bd9Sstevel@tonic-gate /* 14177c478bd9Sstevel@tonic-gate * CONCEPT braindamage in early models: after a wraparound 14187c478bd9Sstevel@tonic-gate * the next newline is eaten. It's hungry so we just 14197c478bd9Sstevel@tonic-gate * feed it now rather than worrying about it. 14207c478bd9Sstevel@tonic-gate * Fixed to use return linefeed to work right 14217c478bd9Sstevel@tonic-gate * on vt100/tab132 as well as concept. 14227c478bd9Sstevel@tonic-gate */ 14237c478bd9Sstevel@tonic-gate if (eat_newline_glitch && outcol % WCOLS == 0) { 1424*f6db9f27Scf46844 (void) vputc('\r'); 1425*f6db9f27Scf46844 (void) vputc('\n'); 14267c478bd9Sstevel@tonic-gate } 14277c478bd9Sstevel@tonic-gate } 1428*f6db9f27Scf46844 return (0); 14297c478bd9Sstevel@tonic-gate } 14307c478bd9Sstevel@tonic-gate 14317c478bd9Sstevel@tonic-gate /* 14327c478bd9Sstevel@tonic-gate * Delete display positions stcol through endcol. 14337c478bd9Sstevel@tonic-gate * Amount of use of special terminal features here is limited. 14347c478bd9Sstevel@tonic-gate */ 1435*f6db9f27Scf46844 void 1436*f6db9f27Scf46844 physdc(int stcol, int endcol) 14377c478bd9Sstevel@tonic-gate { 1438*f6db9f27Scf46844 wchar_t *tp, *up; 14397c478bd9Sstevel@tonic-gate wchar_t *tpe; 1440*f6db9f27Scf46844 int i; 1441*f6db9f27Scf46844 int nc = endcol - stcol; 14427c478bd9Sstevel@tonic-gate 14437c478bd9Sstevel@tonic-gate #ifdef IDEBUG 14447c478bd9Sstevel@tonic-gate if (trace) 14457c478bd9Sstevel@tonic-gate tfixnl(), fprintf(trace, "physdc(%d, %d)\n", stcol, endcol); 14467c478bd9Sstevel@tonic-gate #endif 14477c478bd9Sstevel@tonic-gate if (!delete_character || nc <= 0) 14487c478bd9Sstevel@tonic-gate return; 14497c478bd9Sstevel@tonic-gate if (insert_null_glitch) { 14507c478bd9Sstevel@tonic-gate /* 14517c478bd9Sstevel@tonic-gate * CONCEPT-100 like terminal. 14527c478bd9Sstevel@tonic-gate * If there are any ``spaces'' in the material to be 14537c478bd9Sstevel@tonic-gate * deleted, then this is too hard, just retype. 14547c478bd9Sstevel@tonic-gate */ 14557c478bd9Sstevel@tonic-gate vprepins(); 14567c478bd9Sstevel@tonic-gate up = vtube0 + stcol; 14577c478bd9Sstevel@tonic-gate i = nc; 14587c478bd9Sstevel@tonic-gate do 14597c478bd9Sstevel@tonic-gate if ((*up++ & (QUOTE|TRIM)) == QUOTE) 14607c478bd9Sstevel@tonic-gate return; 14617c478bd9Sstevel@tonic-gate while (--i); 14627c478bd9Sstevel@tonic-gate i = 2 * nc; 14637c478bd9Sstevel@tonic-gate do 14647c478bd9Sstevel@tonic-gate if (*up == 0 || (*up++ & QUOTE) == QUOTE) 14657c478bd9Sstevel@tonic-gate return; 14667c478bd9Sstevel@tonic-gate while (--i); 14677c478bd9Sstevel@tonic-gate vgotoCL(stcol); 14687c478bd9Sstevel@tonic-gate } else { 14697c478bd9Sstevel@tonic-gate /* 14707c478bd9Sstevel@tonic-gate * HP like delete mode. 14717c478bd9Sstevel@tonic-gate * Compute how much text we are moving over by deleting. 14727c478bd9Sstevel@tonic-gate * If it appears to be faster to just retype 14737c478bd9Sstevel@tonic-gate * the line, do nothing and that will be done later. 14747c478bd9Sstevel@tonic-gate * We are assuming 2 output characters per deleted 14757c478bd9Sstevel@tonic-gate * characters and that clear to end of line is available. 14767c478bd9Sstevel@tonic-gate */ 14777c478bd9Sstevel@tonic-gate i = stcol / WCOLS; 14787c478bd9Sstevel@tonic-gate if (i != endcol / WCOLS) 14797c478bd9Sstevel@tonic-gate return; 14807c478bd9Sstevel@tonic-gate i += LINE(vcline); 14817c478bd9Sstevel@tonic-gate stcol %= WCOLS; 14827c478bd9Sstevel@tonic-gate endcol %= WCOLS; 14837c478bd9Sstevel@tonic-gate up = vtube[i]; tp = up + endcol; tpe = up + WCOLS; 14847c478bd9Sstevel@tonic-gate while (tp < tpe && *tp) 14857c478bd9Sstevel@tonic-gate tp++; 14867c478bd9Sstevel@tonic-gate if (tp - (up + stcol) < 2 * nc) 14877c478bd9Sstevel@tonic-gate return; 14887c478bd9Sstevel@tonic-gate vgoto(i, stcol); 14897c478bd9Sstevel@tonic-gate } 14907c478bd9Sstevel@tonic-gate 14917c478bd9Sstevel@tonic-gate /* 14927c478bd9Sstevel@tonic-gate * Go into delete mode and do the actual delete. 14937c478bd9Sstevel@tonic-gate * Padding is on delete_character itself. 14947c478bd9Sstevel@tonic-gate */ 14957c478bd9Sstevel@tonic-gate godm(); 14967c478bd9Sstevel@tonic-gate for (i = nc; i > 0; i--) 14977c478bd9Sstevel@tonic-gate vputp(delete_character, DEPTH(vcline)); 14987c478bd9Sstevel@tonic-gate vputp(exit_delete_mode, 0); 14997c478bd9Sstevel@tonic-gate 15007c478bd9Sstevel@tonic-gate /* 15017c478bd9Sstevel@tonic-gate * Straighten up. 15027c478bd9Sstevel@tonic-gate * With CONCEPT like terminals, characters are pulled left 15037c478bd9Sstevel@tonic-gate * from first following null. HP like terminals shift rest of 15047c478bd9Sstevel@tonic-gate * this (single physical) line rigidly. 15057c478bd9Sstevel@tonic-gate */ 15067c478bd9Sstevel@tonic-gate if (insert_null_glitch) { 15077c478bd9Sstevel@tonic-gate up = vtube0 + stcol; 15087c478bd9Sstevel@tonic-gate tp = vtube0 + endcol; 15097c478bd9Sstevel@tonic-gate while (i = *tp++) { 15107c478bd9Sstevel@tonic-gate if ((i & (QUOTE|TRIM)) == QUOTE) 15117c478bd9Sstevel@tonic-gate break; 15127c478bd9Sstevel@tonic-gate *up++ = i; 15137c478bd9Sstevel@tonic-gate } 15147c478bd9Sstevel@tonic-gate do 15157c478bd9Sstevel@tonic-gate *up++ = i; 15167c478bd9Sstevel@tonic-gate while (--nc); 15177c478bd9Sstevel@tonic-gate } else { 15187c478bd9Sstevel@tonic-gate copy(up + stcol, up + endcol, (WCOLS - endcol) * sizeof(wchar_t)); 15197c478bd9Sstevel@tonic-gate vclrbyte(tpe - nc, nc); 15207c478bd9Sstevel@tonic-gate } 15217c478bd9Sstevel@tonic-gate } 15227c478bd9Sstevel@tonic-gate 15237c478bd9Sstevel@tonic-gate #ifdef TRACE 15247c478bd9Sstevel@tonic-gate tfixnl() 15257c478bd9Sstevel@tonic-gate { 15267c478bd9Sstevel@tonic-gate 15277c478bd9Sstevel@tonic-gate if (trubble || techoin) 15287c478bd9Sstevel@tonic-gate fprintf(trace, "\n"); 15297c478bd9Sstevel@tonic-gate trubble = 0, techoin = 0; 15307c478bd9Sstevel@tonic-gate } 15317c478bd9Sstevel@tonic-gate 15327c478bd9Sstevel@tonic-gate tvliny() 15337c478bd9Sstevel@tonic-gate { 1534*f6db9f27Scf46844 int i; 15357c478bd9Sstevel@tonic-gate 15367c478bd9Sstevel@tonic-gate if (!trace) 15377c478bd9Sstevel@tonic-gate return; 15387c478bd9Sstevel@tonic-gate tfixnl(); 15397c478bd9Sstevel@tonic-gate fprintf(trace, "vcnt = %d, vcline = %d, vliny = ", vcnt, vcline); 15407c478bd9Sstevel@tonic-gate for (i = 0; i <= vcnt; i++) { 15417c478bd9Sstevel@tonic-gate fprintf(trace, "%d", LINE(i)); 15427c478bd9Sstevel@tonic-gate if (FLAGS(i) & VDIRT) 15437c478bd9Sstevel@tonic-gate fprintf(trace, "*"); 15447c478bd9Sstevel@tonic-gate if (DEPTH(i) != 1) 15457c478bd9Sstevel@tonic-gate fprintf(trace, "<%d>", DEPTH(i)); 15467c478bd9Sstevel@tonic-gate if (i < vcnt) 15477c478bd9Sstevel@tonic-gate fprintf(trace, " "); 15487c478bd9Sstevel@tonic-gate } 15497c478bd9Sstevel@tonic-gate fprintf(trace, "\n"); 15507c478bd9Sstevel@tonic-gate } 15517c478bd9Sstevel@tonic-gate 15527c478bd9Sstevel@tonic-gate tracec(c) 15537c478bd9Sstevel@tonic-gate int c; /* char --> int */ 15547c478bd9Sstevel@tonic-gate { 15557c478bd9Sstevel@tonic-gate 15567c478bd9Sstevel@tonic-gate if (!techoin) 15577c478bd9Sstevel@tonic-gate trubble = 1; 15587c478bd9Sstevel@tonic-gate if (c == ESCAPE) 15597c478bd9Sstevel@tonic-gate fprintf(trace, "$"); 15607c478bd9Sstevel@tonic-gate else if (c & QUOTE) /* for 3B (no sign extension) */ 15617c478bd9Sstevel@tonic-gate fprintf(trace, "~%c", ctlof(c&TRIM)); 15627c478bd9Sstevel@tonic-gate else if (c < ' ' || c == DELETE) 15637c478bd9Sstevel@tonic-gate fprintf(trace, "^%c", ctlof(c)); 15647c478bd9Sstevel@tonic-gate else 15657c478bd9Sstevel@tonic-gate fprintf(trace, "%c", c); 15667c478bd9Sstevel@tonic-gate } 15677c478bd9Sstevel@tonic-gate #endif 15687c478bd9Sstevel@tonic-gate 15697c478bd9Sstevel@tonic-gate /* 15707c478bd9Sstevel@tonic-gate * Put a character with possible tracing. 15717c478bd9Sstevel@tonic-gate */ 15727c478bd9Sstevel@tonic-gate int 15737c478bd9Sstevel@tonic-gate vputch(char c) 15747c478bd9Sstevel@tonic-gate { 15757c478bd9Sstevel@tonic-gate 15767c478bd9Sstevel@tonic-gate #ifdef TRACE 15777c478bd9Sstevel@tonic-gate if (trace) { 15787c478bd9Sstevel@tonic-gate tracec(c); 15797c478bd9Sstevel@tonic-gate } 15807c478bd9Sstevel@tonic-gate #endif 1581*f6db9f27Scf46844 (void) vputc(c); 1582*f6db9f27Scf46844 return (0); 15837c478bd9Sstevel@tonic-gate } 1584