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 #pragma ident "%Z%%M% %I% %E% SMI" 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include "ex.h" 357c478bd9Sstevel@tonic-gate #include "ex_tty.h" 367c478bd9Sstevel@tonic-gate #include "ex_vis.h" 377c478bd9Sstevel@tonic-gate #ifndef PRESUNEUC 387c478bd9Sstevel@tonic-gate #include <wctype.h> 397c478bd9Sstevel@tonic-gate /* Undef putchar/getchar if they're defined. */ 407c478bd9Sstevel@tonic-gate #ifdef putchar 417c478bd9Sstevel@tonic-gate # undef putchar 427c478bd9Sstevel@tonic-gate #endif 437c478bd9Sstevel@tonic-gate #ifdef getchar 447c478bd9Sstevel@tonic-gate # undef getchar 457c478bd9Sstevel@tonic-gate #endif 467c478bd9Sstevel@tonic-gate #endif /* PRESUNEUC */ 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate /* 497c478bd9Sstevel@tonic-gate * Terminal driving and line formatting routines. 507c478bd9Sstevel@tonic-gate * Basic motion optimizations are done here as well 517c478bd9Sstevel@tonic-gate * as formatting of lines (printing of control characters, 527c478bd9Sstevel@tonic-gate * line numbering and the like). 537c478bd9Sstevel@tonic-gate */ 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate /* 567c478bd9Sstevel@tonic-gate * The routines outchar, putchar and pline are actually 577c478bd9Sstevel@tonic-gate * variables, and these variables point at the current definitions 587c478bd9Sstevel@tonic-gate * of the routines. See the routine setflav. 597c478bd9Sstevel@tonic-gate * We sometimes make outchar be routines which catch the characters 607c478bd9Sstevel@tonic-gate * to be printed, e.g. if we want to see how long a line is. 617c478bd9Sstevel@tonic-gate * During open/visual, outchar and putchar will be set to 627c478bd9Sstevel@tonic-gate * routines in the file ex_vput.c (vputchar, vinschar, etc.). 637c478bd9Sstevel@tonic-gate */ 647c478bd9Sstevel@tonic-gate int (*Outchar)() = termchar; 657c478bd9Sstevel@tonic-gate int (*Putchar)() = normchar; 667c478bd9Sstevel@tonic-gate int (*Pline)() = normline; 677c478bd9Sstevel@tonic-gate static unsigned char multic[MULTI_BYTE_MAX]; 687c478bd9Sstevel@tonic-gate bool putoctal; /* flag to say if byte should be printed as octal */ 697c478bd9Sstevel@tonic-gate int termiosflag = -1; /* flag for using termios ioctl 707c478bd9Sstevel@tonic-gate * structure */ 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate int (* 737c478bd9Sstevel@tonic-gate setlist(t))() 747c478bd9Sstevel@tonic-gate bool t; 757c478bd9Sstevel@tonic-gate { 76*f6db9f27Scf46844 int (*P)(); 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate listf = t; 797c478bd9Sstevel@tonic-gate P = Putchar; 807c478bd9Sstevel@tonic-gate Putchar = t ? listchar : normchar; 817c478bd9Sstevel@tonic-gate return (P); 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate int (* 857c478bd9Sstevel@tonic-gate setnumb(t))() 867c478bd9Sstevel@tonic-gate bool t; 877c478bd9Sstevel@tonic-gate { 88*f6db9f27Scf46844 int (*P)(); 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate numberf = t; 917c478bd9Sstevel@tonic-gate P = Pline; 92*f6db9f27Scf46844 Pline = t ? (int (*)())numbline : normline; 937c478bd9Sstevel@tonic-gate return (P); 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate /* 977c478bd9Sstevel@tonic-gate * Format c for list mode; leave things in common 987c478bd9Sstevel@tonic-gate * with normal print mode to be done by normchar. 997c478bd9Sstevel@tonic-gate */ 100*f6db9f27Scf46844 int 101*f6db9f27Scf46844 listchar(wchar_t c) 1027c478bd9Sstevel@tonic-gate { 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate c &= (int)(TRIM|QUOTE); 1057c478bd9Sstevel@tonic-gate switch (c) { 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate case '\t': 1087c478bd9Sstevel@tonic-gate case '\b': 1097c478bd9Sstevel@tonic-gate outchar('^'); 1107c478bd9Sstevel@tonic-gate c = ctlof(c); 1117c478bd9Sstevel@tonic-gate break; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate case '\n': 1147c478bd9Sstevel@tonic-gate break; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate case (int)('\n' | QUOTE): 1177c478bd9Sstevel@tonic-gate outchar('$'); 1187c478bd9Sstevel@tonic-gate break; 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate default: 1217c478bd9Sstevel@tonic-gate if((int)(c & QUOTE)) 1227c478bd9Sstevel@tonic-gate break; 1237c478bd9Sstevel@tonic-gate if (c < ' ' && c != '\n' || c == DELETE) 1247c478bd9Sstevel@tonic-gate outchar('^'), c = ctlof(c); 1257c478bd9Sstevel@tonic-gate } 126*f6db9f27Scf46844 (void) normchar(c); 127*f6db9f27Scf46844 return (0); 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate /* 1317c478bd9Sstevel@tonic-gate * Format c for printing. Handle funnies of upper case terminals 1327c478bd9Sstevel@tonic-gate * and hazeltines which don't have ~. 1337c478bd9Sstevel@tonic-gate */ 134*f6db9f27Scf46844 int 135*f6db9f27Scf46844 normchar(wchar_t c) 1367c478bd9Sstevel@tonic-gate { 137*f6db9f27Scf46844 char *colp; 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate c &= (int)(TRIM|QUOTE); 1407c478bd9Sstevel@tonic-gate if (c == '~' && tilde_glitch) { 141*f6db9f27Scf46844 (void) normchar('\\'); 1427c478bd9Sstevel@tonic-gate c = '^'; 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate if ((int)(c & QUOTE)) 1457c478bd9Sstevel@tonic-gate switch (c) { 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate case (int)(' ' | QUOTE): 1487c478bd9Sstevel@tonic-gate case (int)('\b' | QUOTE): 1497c478bd9Sstevel@tonic-gate break; 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate case (int)QUOTE: 152*f6db9f27Scf46844 return (0); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate default: 1557c478bd9Sstevel@tonic-gate c &= (int)TRIM; 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate else if (c < ' ' && (c != '\b' || !over_strike) && c != '\n' && c != '\t' || c == DELETE) 1587c478bd9Sstevel@tonic-gate putchar('^'), c = ctlof(c); 1597c478bd9Sstevel@tonic-gate else if (c >= 0200 && (putoctal || !iswprint(c))) { 1607c478bd9Sstevel@tonic-gate outchar('\\'); 1617c478bd9Sstevel@tonic-gate outchar(((c >> 6) & 07) + '0'); 1627c478bd9Sstevel@tonic-gate outchar(((c >> 3) & 07) + '0'); 1637c478bd9Sstevel@tonic-gate outchar((c & 07) + '0'); 164*f6db9f27Scf46844 return (0); 1657c478bd9Sstevel@tonic-gate } else if (UPPERCASE) 1667c478bd9Sstevel@tonic-gate if (isupper(c)) { 1677c478bd9Sstevel@tonic-gate outchar('\\'); 1687c478bd9Sstevel@tonic-gate c = tolower(c); 1697c478bd9Sstevel@tonic-gate } else { 1707c478bd9Sstevel@tonic-gate colp = "({)}!|^~'`"; 1717c478bd9Sstevel@tonic-gate while (*colp++) 1727c478bd9Sstevel@tonic-gate if (c == *colp++) { 1737c478bd9Sstevel@tonic-gate outchar('\\'); 1747c478bd9Sstevel@tonic-gate c = colp[-2]; 1757c478bd9Sstevel@tonic-gate break; 1767c478bd9Sstevel@tonic-gate } 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate outchar(c); 179*f6db9f27Scf46844 return (0); 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate /* 1837c478bd9Sstevel@tonic-gate * Print a line with a number. 1847c478bd9Sstevel@tonic-gate */ 185*f6db9f27Scf46844 int 186*f6db9f27Scf46844 numbline(int i) 1877c478bd9Sstevel@tonic-gate { 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate if (shudclob) 1907c478bd9Sstevel@tonic-gate slobber(' '); 191*f6db9f27Scf46844 viprintf("%6d ", i); 192*f6db9f27Scf46844 (void) normline(); 193*f6db9f27Scf46844 return (0); 1947c478bd9Sstevel@tonic-gate } 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate /* 1977c478bd9Sstevel@tonic-gate * Normal line output, no numbering. 1987c478bd9Sstevel@tonic-gate */ 199*f6db9f27Scf46844 int 200*f6db9f27Scf46844 normline(void) 2017c478bd9Sstevel@tonic-gate { 202*f6db9f27Scf46844 unsigned char *cp; 203*f6db9f27Scf46844 int n; 2047c478bd9Sstevel@tonic-gate wchar_t wchar; 2057c478bd9Sstevel@tonic-gate if (shudclob) 2067c478bd9Sstevel@tonic-gate slobber(linebuf[0]); 2077c478bd9Sstevel@tonic-gate /* pdp-11 doprnt is not reentrant so can't use "printf" here 2087c478bd9Sstevel@tonic-gate in case we are tracing */ 2097c478bd9Sstevel@tonic-gate for (cp = linebuf; *cp;) 2107c478bd9Sstevel@tonic-gate if((n = mbtowc(&wchar, (char *)cp, MULTI_BYTE_MAX)) < 0) { 2117c478bd9Sstevel@tonic-gate putoctal = 1; 2127c478bd9Sstevel@tonic-gate putchar(*cp++); 2137c478bd9Sstevel@tonic-gate putoctal = 0; 2147c478bd9Sstevel@tonic-gate } else { 2157c478bd9Sstevel@tonic-gate cp += n; 2167c478bd9Sstevel@tonic-gate putchar(wchar); 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate if (!inopen) 2197c478bd9Sstevel@tonic-gate putchar((int)('\n' | QUOTE)); 220*f6db9f27Scf46844 return (0); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate /* 2247c478bd9Sstevel@tonic-gate * Given c at the beginning of a line, determine whether 2257c478bd9Sstevel@tonic-gate * the printing of the line will erase or otherwise obliterate 2267c478bd9Sstevel@tonic-gate * the prompt which was printed before. If it won't, do it now. 2277c478bd9Sstevel@tonic-gate */ 228*f6db9f27Scf46844 void 229*f6db9f27Scf46844 slobber(int c) 2307c478bd9Sstevel@tonic-gate { 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate shudclob = 0; 2337c478bd9Sstevel@tonic-gate switch (c) { 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate case '\t': 2367c478bd9Sstevel@tonic-gate if (Putchar == listchar) 2377c478bd9Sstevel@tonic-gate return; 2387c478bd9Sstevel@tonic-gate break; 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate default: 2417c478bd9Sstevel@tonic-gate return; 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate case ' ': 2447c478bd9Sstevel@tonic-gate case 0: 2457c478bd9Sstevel@tonic-gate break; 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate if (over_strike) 2487c478bd9Sstevel@tonic-gate return; 2497c478bd9Sstevel@tonic-gate flush(); 250*f6db9f27Scf46844 (void) putch(' '); 2517c478bd9Sstevel@tonic-gate tputs(cursor_left, 0, putch); 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate /* 2557c478bd9Sstevel@tonic-gate * The output buffer is initialized with a useful error 2567c478bd9Sstevel@tonic-gate * message so we don't have to keep it in data space. 2577c478bd9Sstevel@tonic-gate */ 2587c478bd9Sstevel@tonic-gate static wchar_t linb[66]; 2597c478bd9Sstevel@tonic-gate wchar_t *linp = linb; 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate /* 2627c478bd9Sstevel@tonic-gate * Phadnl records when we have already had a complete line ending with \n. 2637c478bd9Sstevel@tonic-gate * If another line starts without a flush, and the terminal suggests it, 2647c478bd9Sstevel@tonic-gate * we switch into -nl mode so that we can send linefeeds to avoid 2657c478bd9Sstevel@tonic-gate * a lot of spacing. 2667c478bd9Sstevel@tonic-gate */ 2677c478bd9Sstevel@tonic-gate static bool phadnl; 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate /* 2707c478bd9Sstevel@tonic-gate * Indirect to current definition of putchar. 2717c478bd9Sstevel@tonic-gate */ 272*f6db9f27Scf46844 int 2737c478bd9Sstevel@tonic-gate putchar(int c) 2747c478bd9Sstevel@tonic-gate { 275*f6db9f27Scf46844 return ((*Putchar)((wchar_t)c)); 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate /* 2797c478bd9Sstevel@tonic-gate * Termchar routine for command mode. 2807c478bd9Sstevel@tonic-gate * Watch for possible switching to -nl mode. 2817c478bd9Sstevel@tonic-gate * Otherwise flush into next level of buffering when 2827c478bd9Sstevel@tonic-gate * small buffer fills or at a newline. 2837c478bd9Sstevel@tonic-gate */ 284*f6db9f27Scf46844 int 285*f6db9f27Scf46844 termchar(wchar_t c) 2867c478bd9Sstevel@tonic-gate { 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate if (pfast == 0 && phadnl) 2897c478bd9Sstevel@tonic-gate pstart(); 2907c478bd9Sstevel@tonic-gate if (c == '\n') 2917c478bd9Sstevel@tonic-gate phadnl = 1; 2927c478bd9Sstevel@tonic-gate else if (linp >= &linb[63]) 2937c478bd9Sstevel@tonic-gate flush1(); 2947c478bd9Sstevel@tonic-gate *linp++ = c; 2957c478bd9Sstevel@tonic-gate if (linp >= &linb[63]) { 2967c478bd9Sstevel@tonic-gate fgoto(); 2977c478bd9Sstevel@tonic-gate flush1(); 2987c478bd9Sstevel@tonic-gate } 299*f6db9f27Scf46844 return (0); 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate 302*f6db9f27Scf46844 void 303*f6db9f27Scf46844 flush(void) 3047c478bd9Sstevel@tonic-gate { 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate flush1(); 3077c478bd9Sstevel@tonic-gate flush2(); 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate /* 3117c478bd9Sstevel@tonic-gate * Flush from small line buffer into output buffer. 3127c478bd9Sstevel@tonic-gate * Work here is destroying motion into positions, and then 3137c478bd9Sstevel@tonic-gate * letting fgoto do the optimized motion. 3147c478bd9Sstevel@tonic-gate */ 315*f6db9f27Scf46844 void 316*f6db9f27Scf46844 flush1(void) 3177c478bd9Sstevel@tonic-gate { 318*f6db9f27Scf46844 wchar_t *lp; 319*f6db9f27Scf46844 wchar_t c; 3207c478bd9Sstevel@tonic-gate #ifdef PRESUNEUC 3217c478bd9Sstevel@tonic-gate /* used for multibyte characters split between lines */ 322*f6db9f27Scf46844 int splitcnt = 0; 3237c478bd9Sstevel@tonic-gate #else 3247c478bd9Sstevel@tonic-gate /* used for multicolumn character substitution and padding */ 325*f6db9f27Scf46844 int fillercnt = 0; 3267c478bd9Sstevel@tonic-gate #endif /* PRESUNEUC */ 3277c478bd9Sstevel@tonic-gate *linp = 0; 3287c478bd9Sstevel@tonic-gate lp = linb; 3297c478bd9Sstevel@tonic-gate while (*lp) 3307c478bd9Sstevel@tonic-gate switch (c = *lp++) { 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate case '\r': 3337c478bd9Sstevel@tonic-gate destline += destcol / columns; 3347c478bd9Sstevel@tonic-gate destcol = 0; 3357c478bd9Sstevel@tonic-gate continue; 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate case '\b': 3387c478bd9Sstevel@tonic-gate if (destcol) 3397c478bd9Sstevel@tonic-gate destcol--; 3407c478bd9Sstevel@tonic-gate continue; 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate case ' ': 3437c478bd9Sstevel@tonic-gate destcol++; 3447c478bd9Sstevel@tonic-gate continue; 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate case '\t': 3477c478bd9Sstevel@tonic-gate destcol += value(vi_TABSTOP) - destcol % value(vi_TABSTOP); 3487c478bd9Sstevel@tonic-gate continue; 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate case '\n': 3517c478bd9Sstevel@tonic-gate destline += destcol / columns + 1; 3527c478bd9Sstevel@tonic-gate if (destcol != 0 && destcol % columns == 0) 3537c478bd9Sstevel@tonic-gate destline--; 3547c478bd9Sstevel@tonic-gate destcol = 0; 3557c478bd9Sstevel@tonic-gate continue; 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate default: 3587c478bd9Sstevel@tonic-gate fgoto(); 3597c478bd9Sstevel@tonic-gate for (;;) { 3607c478bd9Sstevel@tonic-gate int length, length2; 3617c478bd9Sstevel@tonic-gate unsigned char *p; 3627c478bd9Sstevel@tonic-gate c &= TRIM; 3637c478bd9Sstevel@tonic-gate if ((length = wcwidth(c)) < 0) 3647c478bd9Sstevel@tonic-gate length = 0; 3657c478bd9Sstevel@tonic-gate if (auto_right_margin == 0 && outcol >= columns) 3667c478bd9Sstevel@tonic-gate fgoto(); 3677c478bd9Sstevel@tonic-gate if((destcol % columns) + length - 1 >= columns) { 3687c478bd9Sstevel@tonic-gate #ifdef PRESUNEUC 3697c478bd9Sstevel@tonic-gate /* represent split chars by '>' */ 3707c478bd9Sstevel@tonic-gate splitcnt = length - 1; 3717c478bd9Sstevel@tonic-gate c = '>'; 3727c478bd9Sstevel@tonic-gate #else 3737c478bd9Sstevel@tonic-gate /* substitute/wrap multicolumn char */ 3747c478bd9Sstevel@tonic-gate if(mc_wrap) { 3757c478bd9Sstevel@tonic-gate fillercnt = columns - 3767c478bd9Sstevel@tonic-gate (destcol % columns); 3777c478bd9Sstevel@tonic-gate while(fillercnt) { 378*f6db9f27Scf46844 (void) putch(mc_filler); 3797c478bd9Sstevel@tonic-gate outcol++; 3807c478bd9Sstevel@tonic-gate destcol++; 3817c478bd9Sstevel@tonic-gate fillercnt--; 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate } else { 3847c478bd9Sstevel@tonic-gate fillercnt = length - 1; 3857c478bd9Sstevel@tonic-gate c = mc_filler; 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate #endif /* PRESUNEUC */ 3887c478bd9Sstevel@tonic-gate continue; 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate length2 = wctomb((char *)multic, c); 3917c478bd9Sstevel@tonic-gate p = multic; 3927c478bd9Sstevel@tonic-gate while(length2--) 393*f6db9f27Scf46844 (void) putch(*p++); 3947c478bd9Sstevel@tonic-gate if (c == '\b') { 3957c478bd9Sstevel@tonic-gate outcol--; 3967c478bd9Sstevel@tonic-gate destcol--; 3977c478bd9Sstevel@tonic-gate } else if (c >= ' ' && c != DELETE) { 3987c478bd9Sstevel@tonic-gate outcol += length; 3997c478bd9Sstevel@tonic-gate destcol += length; 4007c478bd9Sstevel@tonic-gate if (eat_newline_glitch && outcol % columns == 0) 401*f6db9f27Scf46844 (void) putch('\r'), 402*f6db9f27Scf46844 (void) putch('\n'); 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate #ifdef PRESUNEUC 4057c478bd9Sstevel@tonic-gate if(splitcnt) { 4067c478bd9Sstevel@tonic-gate splitcnt--; 4077c478bd9Sstevel@tonic-gate c = '>'; 4087c478bd9Sstevel@tonic-gate } else 4097c478bd9Sstevel@tonic-gate c = *lp++; 4107c478bd9Sstevel@tonic-gate #else 4117c478bd9Sstevel@tonic-gate if(fillercnt) { 4127c478bd9Sstevel@tonic-gate fillercnt--; 4137c478bd9Sstevel@tonic-gate c = mc_filler; 4147c478bd9Sstevel@tonic-gate if(c == ' ') 4157c478bd9Sstevel@tonic-gate continue; 4167c478bd9Sstevel@tonic-gate } else 4177c478bd9Sstevel@tonic-gate c = *lp++; 4187c478bd9Sstevel@tonic-gate #endif /* PRESUNEUC */ 4197c478bd9Sstevel@tonic-gate if (c <= ' ') 4207c478bd9Sstevel@tonic-gate break; 4217c478bd9Sstevel@tonic-gate } 4227c478bd9Sstevel@tonic-gate --lp; 4237c478bd9Sstevel@tonic-gate continue; 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate linp = linb; 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate 428*f6db9f27Scf46844 void 429*f6db9f27Scf46844 flush2(void) 4307c478bd9Sstevel@tonic-gate { 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate fgoto(); 4337c478bd9Sstevel@tonic-gate flusho(); 4347c478bd9Sstevel@tonic-gate pstop(); 4357c478bd9Sstevel@tonic-gate } 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate /* 4387c478bd9Sstevel@tonic-gate * Sync the position of the output cursor. 4397c478bd9Sstevel@tonic-gate * Most work here is rounding for terminal boundaries getting the 4407c478bd9Sstevel@tonic-gate * column position implied by wraparound or the lack thereof and 4417c478bd9Sstevel@tonic-gate * rolling up the screen to get destline on the screen. 4427c478bd9Sstevel@tonic-gate */ 443*f6db9f27Scf46844 void 444*f6db9f27Scf46844 fgoto(void) 4457c478bd9Sstevel@tonic-gate { 446*f6db9f27Scf46844 int l, c; 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate if (destcol > columns - 1) { 4497c478bd9Sstevel@tonic-gate destline += destcol / columns; 4507c478bd9Sstevel@tonic-gate destcol %= columns; 4517c478bd9Sstevel@tonic-gate } 4527c478bd9Sstevel@tonic-gate if (outcol > columns - 1) { 4537c478bd9Sstevel@tonic-gate l = (outcol + 1) / columns; 4547c478bd9Sstevel@tonic-gate outline += l; 4557c478bd9Sstevel@tonic-gate outcol %= columns; 4567c478bd9Sstevel@tonic-gate if (auto_right_margin == 0) { 4577c478bd9Sstevel@tonic-gate while (l > 0) { 4587c478bd9Sstevel@tonic-gate if (pfast) 4597c478bd9Sstevel@tonic-gate tputs(carriage_return, 0, putch); 4607c478bd9Sstevel@tonic-gate tputs(cursor_down, 0, putch); 4617c478bd9Sstevel@tonic-gate l--; 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate outcol = 0; 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate if (outline > lines - 1) { 4667c478bd9Sstevel@tonic-gate destline -= outline - (lines - 1); 4677c478bd9Sstevel@tonic-gate outline = lines - 1; 4687c478bd9Sstevel@tonic-gate } 4697c478bd9Sstevel@tonic-gate } 4707c478bd9Sstevel@tonic-gate if (destline > lines - 1) { 4717c478bd9Sstevel@tonic-gate l = destline; 4727c478bd9Sstevel@tonic-gate destline = lines - 1; 4737c478bd9Sstevel@tonic-gate if (outline < lines - 1) { 4747c478bd9Sstevel@tonic-gate c = destcol; 4757c478bd9Sstevel@tonic-gate if (pfast == 0 && (!cursor_address || holdcm)) 4767c478bd9Sstevel@tonic-gate destcol = 0; 4777c478bd9Sstevel@tonic-gate fgoto(); 4787c478bd9Sstevel@tonic-gate destcol = c; 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate while (l > lines - 1) { 4817c478bd9Sstevel@tonic-gate /* 4827c478bd9Sstevel@tonic-gate * The following linefeed (or simulation thereof) 4837c478bd9Sstevel@tonic-gate * is supposed to scroll up the screen, since we 4847c478bd9Sstevel@tonic-gate * are on the bottom line. 4857c478bd9Sstevel@tonic-gate * 4867c478bd9Sstevel@tonic-gate * Superbee glitch: in the middle of the screen we 4877c478bd9Sstevel@tonic-gate * have to use esc B (down) because linefeed messes up 4887c478bd9Sstevel@tonic-gate * in "Efficient Paging" mode (which is essential in 4897c478bd9Sstevel@tonic-gate * some SB's because CRLF mode puts garbage 4907c478bd9Sstevel@tonic-gate * in at end of memory), but you must use linefeed to 4917c478bd9Sstevel@tonic-gate * scroll since down arrow won't go past memory end. 4927c478bd9Sstevel@tonic-gate * I turned this off after receiving Paul Eggert's 4937c478bd9Sstevel@tonic-gate * Superbee description which wins better. 4947c478bd9Sstevel@tonic-gate */ 4957c478bd9Sstevel@tonic-gate if (scroll_forward /* && !beehive_glitch */ && pfast) 4967c478bd9Sstevel@tonic-gate tputs(scroll_forward, 0, putch); 4977c478bd9Sstevel@tonic-gate else 498*f6db9f27Scf46844 (void) putch('\n'); 4997c478bd9Sstevel@tonic-gate l--; 5007c478bd9Sstevel@tonic-gate if (pfast == 0) 5017c478bd9Sstevel@tonic-gate outcol = 0; 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate } 5047c478bd9Sstevel@tonic-gate if (destline < outline && !(cursor_address && !holdcm || cursor_up || cursor_home)) 5057c478bd9Sstevel@tonic-gate destline = outline; 5067c478bd9Sstevel@tonic-gate if (cursor_address && !holdcm) 5077c478bd9Sstevel@tonic-gate if (plod(costCM) > 0) 5087c478bd9Sstevel@tonic-gate plod(0); 5097c478bd9Sstevel@tonic-gate else 5107c478bd9Sstevel@tonic-gate tputs(tparm(cursor_address, destline, destcol), 0, putch); 5117c478bd9Sstevel@tonic-gate else 5127c478bd9Sstevel@tonic-gate plod(0); 5137c478bd9Sstevel@tonic-gate outline = destline; 5147c478bd9Sstevel@tonic-gate outcol = destcol; 5157c478bd9Sstevel@tonic-gate } 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate /* 5187c478bd9Sstevel@tonic-gate * Tab to column col by flushing and then setting destcol. 5197c478bd9Sstevel@tonic-gate * Used by "set all". 5207c478bd9Sstevel@tonic-gate */ 521*f6db9f27Scf46844 void 522*f6db9f27Scf46844 gotab(int col) 5237c478bd9Sstevel@tonic-gate { 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate flush1(); 5267c478bd9Sstevel@tonic-gate destcol = col; 5277c478bd9Sstevel@tonic-gate } 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate /* 5307c478bd9Sstevel@tonic-gate * Move (slowly) to destination. 5317c478bd9Sstevel@tonic-gate * Hard thing here is using home cursor on really deficient terminals. 5327c478bd9Sstevel@tonic-gate * Otherwise just use cursor motions, hacking use of tabs and overtabbing 5337c478bd9Sstevel@tonic-gate * and backspace. 5347c478bd9Sstevel@tonic-gate */ 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate static int plodcnt, plodflg; 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate int 5397c478bd9Sstevel@tonic-gate #ifdef __STDC__ 5407c478bd9Sstevel@tonic-gate plodput(char c) 5417c478bd9Sstevel@tonic-gate #else 5427c478bd9Sstevel@tonic-gate plodput(c) 5437c478bd9Sstevel@tonic-gate char c; 5447c478bd9Sstevel@tonic-gate #endif 5457c478bd9Sstevel@tonic-gate { 5467c478bd9Sstevel@tonic-gate 5477c478bd9Sstevel@tonic-gate if (plodflg) 5487c478bd9Sstevel@tonic-gate plodcnt--; 5497c478bd9Sstevel@tonic-gate else 550*f6db9f27Scf46844 (void) putch(c); 551*f6db9f27Scf46844 return (0); 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate 554*f6db9f27Scf46844 int 555*f6db9f27Scf46844 plod(int cnt) 5567c478bd9Sstevel@tonic-gate { 557*f6db9f27Scf46844 int i, j, k; 558*f6db9f27Scf46844 int soutcol, soutline; 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate plodcnt = plodflg = cnt; 5617c478bd9Sstevel@tonic-gate soutcol = outcol; 5627c478bd9Sstevel@tonic-gate soutline = outline; 5637c478bd9Sstevel@tonic-gate /* 5647c478bd9Sstevel@tonic-gate * Consider homing and moving down/right from there, vs moving 5657c478bd9Sstevel@tonic-gate * directly with local motions to the right spot. 5667c478bd9Sstevel@tonic-gate */ 5677c478bd9Sstevel@tonic-gate if (cursor_home) { 5687c478bd9Sstevel@tonic-gate /* 5697c478bd9Sstevel@tonic-gate * i is the cost to home and tab/space to the right to 5707c478bd9Sstevel@tonic-gate * get to the proper column. This assumes cursor_right costs 5717c478bd9Sstevel@tonic-gate * 1 char. So i+destcol is cost of motion with home. 5727c478bd9Sstevel@tonic-gate */ 5737c478bd9Sstevel@tonic-gate if (tab && value(vi_HARDTABS)) 5747c478bd9Sstevel@tonic-gate i = (destcol / value(vi_HARDTABS)) + (destcol % value(vi_HARDTABS)); 5757c478bd9Sstevel@tonic-gate else 5767c478bd9Sstevel@tonic-gate i = destcol; 5777c478bd9Sstevel@tonic-gate /* 5787c478bd9Sstevel@tonic-gate * j is cost to move locally without homing 5797c478bd9Sstevel@tonic-gate */ 5807c478bd9Sstevel@tonic-gate if (destcol >= outcol) { /* if motion is to the right */ 5817c478bd9Sstevel@tonic-gate if (value(vi_HARDTABS)) { 5827c478bd9Sstevel@tonic-gate j = destcol / value(vi_HARDTABS) - outcol / value(vi_HARDTABS); 5837c478bd9Sstevel@tonic-gate if (tab && j) 5847c478bd9Sstevel@tonic-gate j += destcol % value(vi_HARDTABS); 5857c478bd9Sstevel@tonic-gate else 5867c478bd9Sstevel@tonic-gate j = destcol - outcol; 5877c478bd9Sstevel@tonic-gate } else 5887c478bd9Sstevel@tonic-gate j = destcol - outcol; 5897c478bd9Sstevel@tonic-gate } else 5907c478bd9Sstevel@tonic-gate /* leftward motion only works if we can backspace. */ 5917c478bd9Sstevel@tonic-gate if (outcol - destcol <= i && (cursor_left)) 5927c478bd9Sstevel@tonic-gate i = j = outcol - destcol; /* cheaper to backspace */ 5937c478bd9Sstevel@tonic-gate else 5947c478bd9Sstevel@tonic-gate j = i + 1; /* impossibly expensive */ 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate /* k is the absolute value of vertical distance */ 5977c478bd9Sstevel@tonic-gate k = outline - destline; 5987c478bd9Sstevel@tonic-gate if (k < 0) 5997c478bd9Sstevel@tonic-gate k = -k; 6007c478bd9Sstevel@tonic-gate j += k; 6017c478bd9Sstevel@tonic-gate 6027c478bd9Sstevel@tonic-gate /* 6037c478bd9Sstevel@tonic-gate * Decision. We may not have a choice if no cursor_up. 6047c478bd9Sstevel@tonic-gate */ 6057c478bd9Sstevel@tonic-gate if (i + destline < j || (!cursor_up && destline < outline)) { 6067c478bd9Sstevel@tonic-gate /* 6077c478bd9Sstevel@tonic-gate * Cheaper to home. Do it now and pretend it's a 6087c478bd9Sstevel@tonic-gate * regular local motion. 6097c478bd9Sstevel@tonic-gate */ 6107c478bd9Sstevel@tonic-gate tputs(cursor_home, 0, plodput); 6117c478bd9Sstevel@tonic-gate outcol = outline = 0; 6127c478bd9Sstevel@tonic-gate } else if (cursor_to_ll) { 6137c478bd9Sstevel@tonic-gate /* 6147c478bd9Sstevel@tonic-gate * Quickly consider homing down and moving from there. 6157c478bd9Sstevel@tonic-gate * Assume cost of cursor_to_ll is 2. 6167c478bd9Sstevel@tonic-gate */ 6177c478bd9Sstevel@tonic-gate k = (lines - 1) - destline; 6187c478bd9Sstevel@tonic-gate if (i + k + 2 < j && (k<=0 || cursor_up)) { 6197c478bd9Sstevel@tonic-gate tputs(cursor_to_ll, 0, plodput); 6207c478bd9Sstevel@tonic-gate outcol = 0; 6217c478bd9Sstevel@tonic-gate outline = lines - 1; 6227c478bd9Sstevel@tonic-gate } 6237c478bd9Sstevel@tonic-gate } 6247c478bd9Sstevel@tonic-gate } else 6257c478bd9Sstevel@tonic-gate /* 6267c478bd9Sstevel@tonic-gate * No home and no up means it's impossible, so we return an 6277c478bd9Sstevel@tonic-gate * incredibly big number to make cursor motion win out. 6287c478bd9Sstevel@tonic-gate */ 6297c478bd9Sstevel@tonic-gate if (!cursor_up && destline < outline) 6307c478bd9Sstevel@tonic-gate return (500); 6317c478bd9Sstevel@tonic-gate if (tab && value(vi_HARDTABS)) 6327c478bd9Sstevel@tonic-gate i = destcol % value(vi_HARDTABS) 6337c478bd9Sstevel@tonic-gate + destcol / value(vi_HARDTABS); 6347c478bd9Sstevel@tonic-gate else 6357c478bd9Sstevel@tonic-gate i = destcol; 6367c478bd9Sstevel@tonic-gate /* 6377c478bd9Sstevel@tonic-gate if (back_tab && outcol > destcol && (j = (((outcol+7) & ~7) - destcol - 1) >> 3)) { 6387c478bd9Sstevel@tonic-gate j *= (k = strlen(back_tab)); 6397c478bd9Sstevel@tonic-gate if ((k += (destcol&7)) > 4) 6407c478bd9Sstevel@tonic-gate j += 8 - (destcol&7); 6417c478bd9Sstevel@tonic-gate else 6427c478bd9Sstevel@tonic-gate j += k; 6437c478bd9Sstevel@tonic-gate } else 6447c478bd9Sstevel@tonic-gate */ 6457c478bd9Sstevel@tonic-gate j = outcol - destcol; 6467c478bd9Sstevel@tonic-gate /* 6477c478bd9Sstevel@tonic-gate * If we will later need a \n which will turn into a \r\n by 6487c478bd9Sstevel@tonic-gate * the system or the terminal, then don't bother to try to \r. 6497c478bd9Sstevel@tonic-gate */ 6507c478bd9Sstevel@tonic-gate if ((NONL || !pfast) && outline < destline) 6517c478bd9Sstevel@tonic-gate goto dontcr; 6527c478bd9Sstevel@tonic-gate /* 6537c478bd9Sstevel@tonic-gate * If the terminal will do a \r\n and there isn't room for it, 6547c478bd9Sstevel@tonic-gate * then we can't afford a \r. 6557c478bd9Sstevel@tonic-gate */ 6567c478bd9Sstevel@tonic-gate if (!carriage_return && outline >= destline) 6577c478bd9Sstevel@tonic-gate goto dontcr; 6587c478bd9Sstevel@tonic-gate /* 6597c478bd9Sstevel@tonic-gate * If it will be cheaper, or if we can't back up, then send 6607c478bd9Sstevel@tonic-gate * a return preliminarily. 6617c478bd9Sstevel@tonic-gate */ 6627c478bd9Sstevel@tonic-gate if (j > i + 1 || outcol > destcol && !cursor_left) { 6637c478bd9Sstevel@tonic-gate /* 6647c478bd9Sstevel@tonic-gate * BUG: this doesn't take the (possibly long) length 6657c478bd9Sstevel@tonic-gate * of carriage_return into account. 6667c478bd9Sstevel@tonic-gate */ 6677c478bd9Sstevel@tonic-gate if (carriage_return) { 6687c478bd9Sstevel@tonic-gate tputs(carriage_return, 0, plodput); 6697c478bd9Sstevel@tonic-gate outcol = 0; 6707c478bd9Sstevel@tonic-gate } else if (newline) { 6717c478bd9Sstevel@tonic-gate tputs(newline, 0, plodput); 6727c478bd9Sstevel@tonic-gate outline++; 6737c478bd9Sstevel@tonic-gate outcol = 0; 6747c478bd9Sstevel@tonic-gate } 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate dontcr: 6777c478bd9Sstevel@tonic-gate /* Move down, if necessary, until we are at the desired line */ 6787c478bd9Sstevel@tonic-gate while (outline < destline) { 6797c478bd9Sstevel@tonic-gate j = destline - outline; 6807c478bd9Sstevel@tonic-gate if (j > costDP && parm_down_cursor) { 6817c478bd9Sstevel@tonic-gate /* Win big on Tek 4025 */ 6827c478bd9Sstevel@tonic-gate tputs(tparm(parm_down_cursor, j), j, plodput); 6837c478bd9Sstevel@tonic-gate outline += j; 6847c478bd9Sstevel@tonic-gate } 6857c478bd9Sstevel@tonic-gate else { 6867c478bd9Sstevel@tonic-gate outline++; 6877c478bd9Sstevel@tonic-gate if (cursor_down && pfast) 6887c478bd9Sstevel@tonic-gate tputs(cursor_down, 0, plodput); 6897c478bd9Sstevel@tonic-gate else 690*f6db9f27Scf46844 (void) plodput('\n'); 6917c478bd9Sstevel@tonic-gate } 6927c478bd9Sstevel@tonic-gate if (plodcnt < 0) 6937c478bd9Sstevel@tonic-gate goto out; 6947c478bd9Sstevel@tonic-gate if (NONL || pfast == 0) 6957c478bd9Sstevel@tonic-gate outcol = 0; 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate if (back_tab) 6987c478bd9Sstevel@tonic-gate k = strlen(back_tab); /* should probably be cost(back_tab) and moved out */ 6997c478bd9Sstevel@tonic-gate /* Move left, if necessary, to desired column */ 7007c478bd9Sstevel@tonic-gate while (outcol > destcol) { 7017c478bd9Sstevel@tonic-gate if (plodcnt < 0) 7027c478bd9Sstevel@tonic-gate goto out; 7037c478bd9Sstevel@tonic-gate if (back_tab && !insmode && outcol - destcol > 4+k) { 7047c478bd9Sstevel@tonic-gate tputs(back_tab, 0, plodput); 7057c478bd9Sstevel@tonic-gate outcol--; 7067c478bd9Sstevel@tonic-gate if (value(vi_HARDTABS)) 7077c478bd9Sstevel@tonic-gate outcol -= outcol % value(vi_HARDTABS); /* outcol &= ~7; */ 7087c478bd9Sstevel@tonic-gate continue; 7097c478bd9Sstevel@tonic-gate } 7107c478bd9Sstevel@tonic-gate j = outcol - destcol; 7117c478bd9Sstevel@tonic-gate if (j > costLP && parm_left_cursor) { 7127c478bd9Sstevel@tonic-gate tputs(tparm(parm_left_cursor, j), j, plodput); 7137c478bd9Sstevel@tonic-gate outcol -= j; 7147c478bd9Sstevel@tonic-gate } 7157c478bd9Sstevel@tonic-gate else { 7167c478bd9Sstevel@tonic-gate outcol--; 7177c478bd9Sstevel@tonic-gate tputs(cursor_left, 0, plodput); 7187c478bd9Sstevel@tonic-gate } 7197c478bd9Sstevel@tonic-gate } 7207c478bd9Sstevel@tonic-gate /* Move up, if necessary, to desired row */ 7217c478bd9Sstevel@tonic-gate while (outline > destline) { 7227c478bd9Sstevel@tonic-gate j = outline - destline; 7237c478bd9Sstevel@tonic-gate if (parm_up_cursor && j > 1) { 7247c478bd9Sstevel@tonic-gate /* Win big on Tek 4025 */ 7257c478bd9Sstevel@tonic-gate tputs(tparm(parm_up_cursor, j), j, plodput); 7267c478bd9Sstevel@tonic-gate outline -= j; 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate else { 7297c478bd9Sstevel@tonic-gate outline--; 7307c478bd9Sstevel@tonic-gate tputs(cursor_up, 0, plodput); 7317c478bd9Sstevel@tonic-gate } 7327c478bd9Sstevel@tonic-gate if (plodcnt < 0) 7337c478bd9Sstevel@tonic-gate goto out; 7347c478bd9Sstevel@tonic-gate } 7357c478bd9Sstevel@tonic-gate /* 7367c478bd9Sstevel@tonic-gate * Now move to the right, if necessary. We first tab to 7377c478bd9Sstevel@tonic-gate * as close as we can get. 7387c478bd9Sstevel@tonic-gate */ 7397c478bd9Sstevel@tonic-gate if (value(vi_HARDTABS) && tab && !insmode && destcol - outcol > 1) { 7407c478bd9Sstevel@tonic-gate /* tab to right as far as possible without passing col */ 7417c478bd9Sstevel@tonic-gate for (;;) { 7427c478bd9Sstevel@tonic-gate i = tabcol(outcol, value(vi_HARDTABS)); 7437c478bd9Sstevel@tonic-gate if (i > destcol) 7447c478bd9Sstevel@tonic-gate break; 7457c478bd9Sstevel@tonic-gate if (tab) 7467c478bd9Sstevel@tonic-gate tputs(tab, 0, plodput); 7477c478bd9Sstevel@tonic-gate else 748*f6db9f27Scf46844 (void) plodput('\t'); 7497c478bd9Sstevel@tonic-gate outcol = i; 7507c478bd9Sstevel@tonic-gate } 7517c478bd9Sstevel@tonic-gate /* consider another tab and then some backspaces */ 7527c478bd9Sstevel@tonic-gate if (destcol - outcol > 4 && i < columns && cursor_left) { 7537c478bd9Sstevel@tonic-gate tputs(tab, 0, plodput); 7547c478bd9Sstevel@tonic-gate outcol = i; 7557c478bd9Sstevel@tonic-gate /* 7567c478bd9Sstevel@tonic-gate * Back up. Don't worry about parm_left_cursor because 7577c478bd9Sstevel@tonic-gate * it's never more than 4 spaces anyway. 7587c478bd9Sstevel@tonic-gate */ 7597c478bd9Sstevel@tonic-gate while (outcol > destcol) { 7607c478bd9Sstevel@tonic-gate outcol--; 7617c478bd9Sstevel@tonic-gate tputs(cursor_left, 0, plodput); 7627c478bd9Sstevel@tonic-gate } 7637c478bd9Sstevel@tonic-gate } 7647c478bd9Sstevel@tonic-gate } 7657c478bd9Sstevel@tonic-gate /* 7667c478bd9Sstevel@tonic-gate * We've tabbed as much as possible. If we still need to go 7677c478bd9Sstevel@tonic-gate * further (not exact or can't tab) space over. This is a 7687c478bd9Sstevel@tonic-gate * very common case when moving to the right with space. 7697c478bd9Sstevel@tonic-gate */ 7707c478bd9Sstevel@tonic-gate while (outcol < destcol) { 7717c478bd9Sstevel@tonic-gate j = destcol - outcol; 7727c478bd9Sstevel@tonic-gate if (j > costRP && parm_right_cursor) { 7737c478bd9Sstevel@tonic-gate /* 7747c478bd9Sstevel@tonic-gate * This probably happens rarely, if at all. 7757c478bd9Sstevel@tonic-gate * It seems mainly useful for ANSI terminals 7767c478bd9Sstevel@tonic-gate * with no hardware tabs, and I don't know 7777c478bd9Sstevel@tonic-gate * of any such terminal at the moment. 7787c478bd9Sstevel@tonic-gate */ 7797c478bd9Sstevel@tonic-gate tputs(tparm(parm_right_cursor, j), j, plodput); 7807c478bd9Sstevel@tonic-gate outcol += j; 7817c478bd9Sstevel@tonic-gate } 7827c478bd9Sstevel@tonic-gate else { 7837c478bd9Sstevel@tonic-gate /* 7847c478bd9Sstevel@tonic-gate * move one char to the right. We don't use right 7857c478bd9Sstevel@tonic-gate * because it's better to just print the char we are 7867c478bd9Sstevel@tonic-gate * moving over. There are various exceptions, however. 7877c478bd9Sstevel@tonic-gate * If !inopen, vtube contains garbage. If the char is 7887c478bd9Sstevel@tonic-gate * a null or a tab we want to print a space. Other 7897c478bd9Sstevel@tonic-gate * random chars we use space for instead, too. 7907c478bd9Sstevel@tonic-gate */ 791*f6db9f27Scf46844 wchar_t wchar; 792*f6db9f27Scf46844 int length, scrlength; 7937c478bd9Sstevel@tonic-gate unsigned char multic[MB_LEN_MAX]; 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate if (!inopen || vtube[outline]==NULL || 7967c478bd9Sstevel@tonic-gate (wchar=vtube[outline][outcol]) < ' ') 7977c478bd9Sstevel@tonic-gate wchar = ' '; 7987c478bd9Sstevel@tonic-gate if((int)(wchar & QUOTE)) /* no sign extension on 3B */ 7997c478bd9Sstevel@tonic-gate wchar = ' '; 8007c478bd9Sstevel@tonic-gate length = wctomb((char *)multic, wchar); 8017c478bd9Sstevel@tonic-gate if ((scrlength = wcwidth(wchar)) < 0) 8027c478bd9Sstevel@tonic-gate scrlength = 0; 8037c478bd9Sstevel@tonic-gate /* assume multibyte terminals have cursor_right */ 8047c478bd9Sstevel@tonic-gate if (insmode && cursor_right || length > 1 || wchar == FILLER) { 8057c478bd9Sstevel@tonic-gate int diff = destcol - outcol; 8067c478bd9Sstevel@tonic-gate j = (wchar == FILLER ? 1 : scrlength > diff ? diff : scrlength); 8077c478bd9Sstevel@tonic-gate while(j--) { 8087c478bd9Sstevel@tonic-gate outcol++; 8097c478bd9Sstevel@tonic-gate tputs(cursor_right, 0, plodput); 8107c478bd9Sstevel@tonic-gate } 8117c478bd9Sstevel@tonic-gate } else { 812*f6db9f27Scf46844 (void) plodput((char)multic[0]); 8137c478bd9Sstevel@tonic-gate outcol++; 8147c478bd9Sstevel@tonic-gate } 8157c478bd9Sstevel@tonic-gate } 8167c478bd9Sstevel@tonic-gate if (plodcnt < 0) 8177c478bd9Sstevel@tonic-gate goto out; 8187c478bd9Sstevel@tonic-gate } 8197c478bd9Sstevel@tonic-gate out: 8207c478bd9Sstevel@tonic-gate if(plodflg) { 8217c478bd9Sstevel@tonic-gate outcol = soutcol; 8227c478bd9Sstevel@tonic-gate outline = soutline; 8237c478bd9Sstevel@tonic-gate } 8247c478bd9Sstevel@tonic-gate return(plodcnt); 8257c478bd9Sstevel@tonic-gate } 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate /* 8287c478bd9Sstevel@tonic-gate * An input line arrived. 8297c478bd9Sstevel@tonic-gate * Calculate new (approximate) screen line position. 8307c478bd9Sstevel@tonic-gate * Approximate because kill character echoes newline with 8317c478bd9Sstevel@tonic-gate * no feedback and also because of long input lines. 8327c478bd9Sstevel@tonic-gate */ 833*f6db9f27Scf46844 void 834*f6db9f27Scf46844 noteinp(void) 8357c478bd9Sstevel@tonic-gate { 8367c478bd9Sstevel@tonic-gate 8377c478bd9Sstevel@tonic-gate outline++; 8387c478bd9Sstevel@tonic-gate if (outline > lines - 1) 8397c478bd9Sstevel@tonic-gate outline = lines - 1; 8407c478bd9Sstevel@tonic-gate destline = outline; 8417c478bd9Sstevel@tonic-gate destcol = outcol = 0; 8427c478bd9Sstevel@tonic-gate } 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate /* 8457c478bd9Sstevel@tonic-gate * Something weird just happened and we 8467c478bd9Sstevel@tonic-gate * lost track of what's happening out there. 8477c478bd9Sstevel@tonic-gate * Since we can't, in general, read where we are 8487c478bd9Sstevel@tonic-gate * we just reset to some known state. 8497c478bd9Sstevel@tonic-gate * On cursor addressable terminals setting to unknown 8507c478bd9Sstevel@tonic-gate * will force a cursor address soon. 8517c478bd9Sstevel@tonic-gate */ 852*f6db9f27Scf46844 void 853*f6db9f27Scf46844 termreset(void) 8547c478bd9Sstevel@tonic-gate { 8557c478bd9Sstevel@tonic-gate 8567c478bd9Sstevel@tonic-gate endim(); 8577c478bd9Sstevel@tonic-gate if (enter_ca_mode) 858*f6db9f27Scf46844 putpad((unsigned char *)enter_ca_mode); 8597c478bd9Sstevel@tonic-gate destcol = 0; 8607c478bd9Sstevel@tonic-gate destline = lines - 1; 8617c478bd9Sstevel@tonic-gate if (cursor_address) { 8627c478bd9Sstevel@tonic-gate outcol = UKCOL; 8637c478bd9Sstevel@tonic-gate outline = UKCOL; 8647c478bd9Sstevel@tonic-gate } else { 8657c478bd9Sstevel@tonic-gate outcol = destcol; 8667c478bd9Sstevel@tonic-gate outline = destline; 8677c478bd9Sstevel@tonic-gate } 8687c478bd9Sstevel@tonic-gate } 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate /* 8717c478bd9Sstevel@tonic-gate * Low level buffering, with the ability to drain 8727c478bd9Sstevel@tonic-gate * buffered output without printing it. 8737c478bd9Sstevel@tonic-gate */ 8747c478bd9Sstevel@tonic-gate unsigned char *obp = obuf; 8757c478bd9Sstevel@tonic-gate 876*f6db9f27Scf46844 void 877*f6db9f27Scf46844 draino(void) 8787c478bd9Sstevel@tonic-gate { 8797c478bd9Sstevel@tonic-gate 8807c478bd9Sstevel@tonic-gate obp = obuf; 8817c478bd9Sstevel@tonic-gate } 8827c478bd9Sstevel@tonic-gate 883*f6db9f27Scf46844 void 884*f6db9f27Scf46844 flusho(void) 8857c478bd9Sstevel@tonic-gate { 8867c478bd9Sstevel@tonic-gate if (obp != obuf) { 8877c478bd9Sstevel@tonic-gate write(1, obuf, obp - obuf); 8887c478bd9Sstevel@tonic-gate #ifdef TRACE 8897c478bd9Sstevel@tonic-gate if (trace) 8907c478bd9Sstevel@tonic-gate fwrite(obuf, 1, obp-obuf, trace); 8917c478bd9Sstevel@tonic-gate #endif 8927c478bd9Sstevel@tonic-gate obp = obuf; 8937c478bd9Sstevel@tonic-gate } 8947c478bd9Sstevel@tonic-gate } 8957c478bd9Sstevel@tonic-gate 896*f6db9f27Scf46844 void 897*f6db9f27Scf46844 putnl(void) 8987c478bd9Sstevel@tonic-gate { 8997c478bd9Sstevel@tonic-gate 9007c478bd9Sstevel@tonic-gate putchar('\n'); 9017c478bd9Sstevel@tonic-gate } 9027c478bd9Sstevel@tonic-gate 903*f6db9f27Scf46844 void 904*f6db9f27Scf46844 putS(unsigned char *cp) 9057c478bd9Sstevel@tonic-gate { 9067c478bd9Sstevel@tonic-gate 9077c478bd9Sstevel@tonic-gate if (cp == NULL) 9087c478bd9Sstevel@tonic-gate return; 9097c478bd9Sstevel@tonic-gate while (*cp) 910*f6db9f27Scf46844 (void) putch(*cp++); 9117c478bd9Sstevel@tonic-gate } 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate int 9147c478bd9Sstevel@tonic-gate putch(char c) 9157c478bd9Sstevel@tonic-gate { 9167c478bd9Sstevel@tonic-gate 9177c478bd9Sstevel@tonic-gate #ifdef OLD3BTTY 9187c478bd9Sstevel@tonic-gate if(c == '\n') /* Fake "\n\r" for '\n' til fix in 3B firmware */ 919*f6db9f27Scf46844 (void) putch('\r'); /* vi does "stty -icanon" => -onlcr !! */ 9207c478bd9Sstevel@tonic-gate #endif 9217c478bd9Sstevel@tonic-gate *obp++ = c; 9227c478bd9Sstevel@tonic-gate if (obp >= &obuf[sizeof obuf]) 9237c478bd9Sstevel@tonic-gate flusho(); 924*f6db9f27Scf46844 return (0); 9257c478bd9Sstevel@tonic-gate } 9267c478bd9Sstevel@tonic-gate 9277c478bd9Sstevel@tonic-gate /* 9287c478bd9Sstevel@tonic-gate * Miscellaneous routines related to output. 9297c478bd9Sstevel@tonic-gate */ 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate /* 9327c478bd9Sstevel@tonic-gate * Put with padding 9337c478bd9Sstevel@tonic-gate */ 934*f6db9f27Scf46844 void 935*f6db9f27Scf46844 putpad(unsigned char *cp) 9367c478bd9Sstevel@tonic-gate { 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate flush(); 9397c478bd9Sstevel@tonic-gate tputs((char *)cp, 0, putch); 9407c478bd9Sstevel@tonic-gate } 9417c478bd9Sstevel@tonic-gate 9427c478bd9Sstevel@tonic-gate /* 9437c478bd9Sstevel@tonic-gate * Set output through normal command mode routine. 9447c478bd9Sstevel@tonic-gate */ 945*f6db9f27Scf46844 void 946*f6db9f27Scf46844 setoutt(void) 9477c478bd9Sstevel@tonic-gate { 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate Outchar = termchar; 9507c478bd9Sstevel@tonic-gate } 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate /* 9537c478bd9Sstevel@tonic-gate * Printf (temporarily) in list mode. 9547c478bd9Sstevel@tonic-gate */ 9557c478bd9Sstevel@tonic-gate /*VARARGS2*/ 956*f6db9f27Scf46844 void 957*f6db9f27Scf46844 lprintf(unsigned char *cp, unsigned char *dp, ...) 9587c478bd9Sstevel@tonic-gate { 959*f6db9f27Scf46844 int (*P)(); 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate P = setlist(1); 9627c478bd9Sstevel@tonic-gate #ifdef PRESUNEUC 963*f6db9f27Scf46844 viprintf(cp, dp); 9647c478bd9Sstevel@tonic-gate #else 965*f6db9f27Scf46844 viprintf((char *)cp, (char *)dp); 9667c478bd9Sstevel@tonic-gate #endif /* PRESUNEUC */ 9677c478bd9Sstevel@tonic-gate Putchar = P; 9687c478bd9Sstevel@tonic-gate } 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate /* 9717c478bd9Sstevel@tonic-gate * Newline + flush. 9727c478bd9Sstevel@tonic-gate */ 973*f6db9f27Scf46844 void 9747c478bd9Sstevel@tonic-gate putNFL() 9757c478bd9Sstevel@tonic-gate { 9767c478bd9Sstevel@tonic-gate 9777c478bd9Sstevel@tonic-gate putnl(); 9787c478bd9Sstevel@tonic-gate flush(); 9797c478bd9Sstevel@tonic-gate } 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate /* 9827c478bd9Sstevel@tonic-gate * Try to start -nl mode. 9837c478bd9Sstevel@tonic-gate */ 984*f6db9f27Scf46844 void 985*f6db9f27Scf46844 pstart(void) 9867c478bd9Sstevel@tonic-gate { 9877c478bd9Sstevel@tonic-gate 9887c478bd9Sstevel@tonic-gate if (NONL) 9897c478bd9Sstevel@tonic-gate return; 9907c478bd9Sstevel@tonic-gate if (!value(vi_OPTIMIZE)) 9917c478bd9Sstevel@tonic-gate return; 9927c478bd9Sstevel@tonic-gate if (ruptible == 0 || pfast) 9937c478bd9Sstevel@tonic-gate return; 9947c478bd9Sstevel@tonic-gate fgoto(); 9957c478bd9Sstevel@tonic-gate flusho(); 9967c478bd9Sstevel@tonic-gate pfast = 1; 9977c478bd9Sstevel@tonic-gate normtty++; 9987c478bd9Sstevel@tonic-gate tty = normf; 9997c478bd9Sstevel@tonic-gate tty.c_oflag &= ~(ONLCR|TAB3); 10007c478bd9Sstevel@tonic-gate tty.c_lflag &= ~ECHO; 10017c478bd9Sstevel@tonic-gate saveterm(); 10027c478bd9Sstevel@tonic-gate sTTY(2); 10037c478bd9Sstevel@tonic-gate } 10047c478bd9Sstevel@tonic-gate 10057c478bd9Sstevel@tonic-gate /* 10067c478bd9Sstevel@tonic-gate * Stop -nl mode. 10077c478bd9Sstevel@tonic-gate */ 1008*f6db9f27Scf46844 void 1009*f6db9f27Scf46844 pstop(void) 10107c478bd9Sstevel@tonic-gate { 10117c478bd9Sstevel@tonic-gate 10127c478bd9Sstevel@tonic-gate if (inopen) 10137c478bd9Sstevel@tonic-gate return; 10147c478bd9Sstevel@tonic-gate phadnl = 0; 10157c478bd9Sstevel@tonic-gate linp = linb; 10167c478bd9Sstevel@tonic-gate draino(); 10177c478bd9Sstevel@tonic-gate normal(normf); 10187c478bd9Sstevel@tonic-gate pfast &= ~1; 10197c478bd9Sstevel@tonic-gate } 10207c478bd9Sstevel@tonic-gate 10217c478bd9Sstevel@tonic-gate /* 10227c478bd9Sstevel@tonic-gate * Prep tty for open mode. 10237c478bd9Sstevel@tonic-gate */ 10247c478bd9Sstevel@tonic-gate ttymode 10257c478bd9Sstevel@tonic-gate ostart() 10267c478bd9Sstevel@tonic-gate { 10277c478bd9Sstevel@tonic-gate ttymode f; 10287c478bd9Sstevel@tonic-gate 10297c478bd9Sstevel@tonic-gate /* 10307c478bd9Sstevel@tonic-gate if (!intty) 10317c478bd9Sstevel@tonic-gate error("Open and visual must be used interactively"); 10327c478bd9Sstevel@tonic-gate */ 1033*f6db9f27Scf46844 (void) gTTY(2); 10347c478bd9Sstevel@tonic-gate normtty++; 10357c478bd9Sstevel@tonic-gate f = tty; 10367c478bd9Sstevel@tonic-gate tty = normf; 10377c478bd9Sstevel@tonic-gate tty.c_iflag &= ~ICRNL; 10387c478bd9Sstevel@tonic-gate tty.c_lflag &= ~(ECHO|ICANON); 10397c478bd9Sstevel@tonic-gate tty.c_oflag &= ~(TAB3|ONLCR); 10407c478bd9Sstevel@tonic-gate tty.c_cc[VMIN] = 1; 10417c478bd9Sstevel@tonic-gate tty.c_cc[VTIME] = 1; 10427c478bd9Sstevel@tonic-gate ttcharoff(); 10437c478bd9Sstevel@tonic-gate sTTY(2); 10447c478bd9Sstevel@tonic-gate tostart(); 10457c478bd9Sstevel@tonic-gate pfast |= 2; 10467c478bd9Sstevel@tonic-gate saveterm(); 10477c478bd9Sstevel@tonic-gate return (f); 10487c478bd9Sstevel@tonic-gate } 10497c478bd9Sstevel@tonic-gate 10507c478bd9Sstevel@tonic-gate /* actions associated with putting the terminal in open mode */ 1051*f6db9f27Scf46844 void 1052*f6db9f27Scf46844 tostart(void) 10537c478bd9Sstevel@tonic-gate { 1054*f6db9f27Scf46844 putpad((unsigned char *)cursor_visible); 1055*f6db9f27Scf46844 putpad((unsigned char *)keypad_xmit); 10567c478bd9Sstevel@tonic-gate if (!value(vi_MESG)) { 10577c478bd9Sstevel@tonic-gate if (ttynbuf[0] == 0) { 1058*f6db9f27Scf46844 char *tn; 10597c478bd9Sstevel@tonic-gate if ((tn=ttyname(2)) == NULL && 10607c478bd9Sstevel@tonic-gate (tn=ttyname(1)) == NULL && 10617c478bd9Sstevel@tonic-gate (tn=ttyname(0)) == NULL) 10627c478bd9Sstevel@tonic-gate ttynbuf[0] = 1; 10637c478bd9Sstevel@tonic-gate else 10647c478bd9Sstevel@tonic-gate strcpy(ttynbuf, tn); 10657c478bd9Sstevel@tonic-gate } 10667c478bd9Sstevel@tonic-gate if (ttynbuf[0] != 1) { 10677c478bd9Sstevel@tonic-gate struct stat64 sbuf; 10687c478bd9Sstevel@tonic-gate stat64((char *)ttynbuf, &sbuf); 10697c478bd9Sstevel@tonic-gate ttymesg = FMODE(sbuf) & 0777; 10707c478bd9Sstevel@tonic-gate chmod((char *)ttynbuf, 0600); 10717c478bd9Sstevel@tonic-gate } 10727c478bd9Sstevel@tonic-gate } 10737c478bd9Sstevel@tonic-gate } 10747c478bd9Sstevel@tonic-gate 10757c478bd9Sstevel@tonic-gate /* 10767c478bd9Sstevel@tonic-gate * Turn off start/stop chars if they aren't the default ^S/^Q. 10777c478bd9Sstevel@tonic-gate * This is so people who make esc their start/stop don't lose. 10787c478bd9Sstevel@tonic-gate * We always turn off quit since datamedias send ^\ for their 10797c478bd9Sstevel@tonic-gate * right arrow key. 10807c478bd9Sstevel@tonic-gate */ 10817c478bd9Sstevel@tonic-gate 1082*f6db9f27Scf46844 void 1083*f6db9f27Scf46844 ttcharoff(void) 10847c478bd9Sstevel@tonic-gate { 10857c478bd9Sstevel@tonic-gate /* 10867c478bd9Sstevel@tonic-gate * use 200 instead of 377 because 377 is y-umlaut 10877c478bd9Sstevel@tonic-gate * in ISO 8859/1 10887c478bd9Sstevel@tonic-gate */ 10897c478bd9Sstevel@tonic-gate tty.c_cc[VQUIT] = termiosflag ? _POSIX_VDISABLE : '\200'; 10907c478bd9Sstevel@tonic-gate if (tty.c_cc[VSTART] != CTRL('q')) 10917c478bd9Sstevel@tonic-gate tty.c_cc[VSTART] = _POSIX_VDISABLE; 10927c478bd9Sstevel@tonic-gate if (tty.c_cc[VSTOP] != CTRL('s')) 10937c478bd9Sstevel@tonic-gate tty.c_cc[VSTOP] = _POSIX_VDISABLE; 10947c478bd9Sstevel@tonic-gate /* We will read ^z and suspend ourselves via kill */ 10957c478bd9Sstevel@tonic-gate tty.c_cc[VSUSP] = _POSIX_VDISABLE; 10967c478bd9Sstevel@tonic-gate tty.c_cc[VDSUSP] = _POSIX_VDISABLE; 10977c478bd9Sstevel@tonic-gate tty.c_cc[VREPRINT] = _POSIX_VDISABLE; 10987c478bd9Sstevel@tonic-gate tty.c_cc[VDISCARD] = _POSIX_VDISABLE; 10997c478bd9Sstevel@tonic-gate tty.c_cc[VWERASE] = _POSIX_VDISABLE; 11007c478bd9Sstevel@tonic-gate tty.c_cc[VLNEXT] = _POSIX_VDISABLE; 11017c478bd9Sstevel@tonic-gate } 11027c478bd9Sstevel@tonic-gate 11037c478bd9Sstevel@tonic-gate /* 11047c478bd9Sstevel@tonic-gate * Stop open, restoring tty modes. 11057c478bd9Sstevel@tonic-gate */ 1106*f6db9f27Scf46844 void 1107*f6db9f27Scf46844 ostop(ttymode f) 11087c478bd9Sstevel@tonic-gate { 11097c478bd9Sstevel@tonic-gate 11107c478bd9Sstevel@tonic-gate pfast = (f.c_oflag & ONLCR) == 0; 11117c478bd9Sstevel@tonic-gate termreset(), fgoto(), flusho(); 11127c478bd9Sstevel@tonic-gate normal(f); 11137c478bd9Sstevel@tonic-gate tostop(); 11147c478bd9Sstevel@tonic-gate } 11157c478bd9Sstevel@tonic-gate 11167c478bd9Sstevel@tonic-gate /* Actions associated with putting the terminal in the right mode. */ 1117*f6db9f27Scf46844 void 1118*f6db9f27Scf46844 tostop(void) 11197c478bd9Sstevel@tonic-gate { 1120*f6db9f27Scf46844 putpad((unsigned char *)clr_eos); 1121*f6db9f27Scf46844 putpad((unsigned char *)cursor_normal); 1122*f6db9f27Scf46844 putpad((unsigned char *)keypad_local); 11237c478bd9Sstevel@tonic-gate if (!value(vi_MESG) && ttynbuf[0]>1) 11247c478bd9Sstevel@tonic-gate chmod((char *)ttynbuf, ttymesg); 11257c478bd9Sstevel@tonic-gate } 11267c478bd9Sstevel@tonic-gate 11277c478bd9Sstevel@tonic-gate #ifndef CBREAK 11287c478bd9Sstevel@tonic-gate /* 11297c478bd9Sstevel@tonic-gate * Into cooked mode for interruptibility. 11307c478bd9Sstevel@tonic-gate */ 11317c478bd9Sstevel@tonic-gate vcook() 11327c478bd9Sstevel@tonic-gate { 11337c478bd9Sstevel@tonic-gate 11347c478bd9Sstevel@tonic-gate tty.sg_flags &= ~RAW; 11357c478bd9Sstevel@tonic-gate sTTY(2); 11367c478bd9Sstevel@tonic-gate } 11377c478bd9Sstevel@tonic-gate 11387c478bd9Sstevel@tonic-gate /* 11397c478bd9Sstevel@tonic-gate * Back into raw mode. 11407c478bd9Sstevel@tonic-gate */ 11417c478bd9Sstevel@tonic-gate vraw() 11427c478bd9Sstevel@tonic-gate { 11437c478bd9Sstevel@tonic-gate 11447c478bd9Sstevel@tonic-gate tty.sg_flags |= RAW; 11457c478bd9Sstevel@tonic-gate sTTY(2); 11467c478bd9Sstevel@tonic-gate } 11477c478bd9Sstevel@tonic-gate #endif 11487c478bd9Sstevel@tonic-gate 11497c478bd9Sstevel@tonic-gate /* 11507c478bd9Sstevel@tonic-gate * Restore flags to normal state f. 11517c478bd9Sstevel@tonic-gate */ 1152*f6db9f27Scf46844 void 1153*f6db9f27Scf46844 normal(ttymode f) 11547c478bd9Sstevel@tonic-gate { 11557c478bd9Sstevel@tonic-gate 11567c478bd9Sstevel@tonic-gate if (normtty > 0) { 11577c478bd9Sstevel@tonic-gate setty(f); 11587c478bd9Sstevel@tonic-gate normtty--; 11597c478bd9Sstevel@tonic-gate } 11607c478bd9Sstevel@tonic-gate } 11617c478bd9Sstevel@tonic-gate 11627c478bd9Sstevel@tonic-gate /* 11637c478bd9Sstevel@tonic-gate * Straight set of flags to state f. 11647c478bd9Sstevel@tonic-gate */ 11657c478bd9Sstevel@tonic-gate ttymode 11667c478bd9Sstevel@tonic-gate setty(f) 11677c478bd9Sstevel@tonic-gate ttymode f; 11687c478bd9Sstevel@tonic-gate { 11697c478bd9Sstevel@tonic-gate int isnorm = 0; 11707c478bd9Sstevel@tonic-gate ttymode ot; 11717c478bd9Sstevel@tonic-gate ot = tty; 11727c478bd9Sstevel@tonic-gate 11737c478bd9Sstevel@tonic-gate if (tty.c_lflag & ICANON) 11747c478bd9Sstevel@tonic-gate ttcharoff(); 11757c478bd9Sstevel@tonic-gate else 11767c478bd9Sstevel@tonic-gate isnorm = 1; 11777c478bd9Sstevel@tonic-gate tty = f; 11787c478bd9Sstevel@tonic-gate sTTY(2); 11797c478bd9Sstevel@tonic-gate if (!isnorm) 11807c478bd9Sstevel@tonic-gate saveterm(); 11817c478bd9Sstevel@tonic-gate return (ot); 11827c478bd9Sstevel@tonic-gate } 11837c478bd9Sstevel@tonic-gate 11847c478bd9Sstevel@tonic-gate static struct termio termio; 11857c478bd9Sstevel@tonic-gate 1186*f6db9f27Scf46844 int 1187*f6db9f27Scf46844 gTTY(int i) 11887c478bd9Sstevel@tonic-gate { 11897c478bd9Sstevel@tonic-gate if(termiosflag < 0) { 11907c478bd9Sstevel@tonic-gate if(ioctl(i, TCGETS, &tty) == 0) 11917c478bd9Sstevel@tonic-gate termiosflag = 1; 11927c478bd9Sstevel@tonic-gate else { 11937c478bd9Sstevel@tonic-gate termiosflag = 0; 11947c478bd9Sstevel@tonic-gate if(ioctl(i, TCGETA, &termio) < 0) 1195*f6db9f27Scf46844 return (-1); 11967c478bd9Sstevel@tonic-gate tty.c_iflag = termio.c_iflag; 11977c478bd9Sstevel@tonic-gate tty.c_oflag = termio.c_oflag; 11987c478bd9Sstevel@tonic-gate tty.c_cflag = termio.c_cflag; 11997c478bd9Sstevel@tonic-gate tty.c_lflag = termio.c_lflag; 12007c478bd9Sstevel@tonic-gate for(i = 0; i < NCC; i++) 12017c478bd9Sstevel@tonic-gate tty.c_cc[i] = termio.c_cc[i]; 12027c478bd9Sstevel@tonic-gate } 1203*f6db9f27Scf46844 return (0); 12047c478bd9Sstevel@tonic-gate } 12057c478bd9Sstevel@tonic-gate if(termiosflag) 1206*f6db9f27Scf46844 return (ioctl(i, TCGETS, &tty)); 12077c478bd9Sstevel@tonic-gate if(ioctl(i, TCGETA, &termio) < 0) 1208*f6db9f27Scf46844 return (-1); 12097c478bd9Sstevel@tonic-gate tty.c_iflag = termio.c_iflag; 12107c478bd9Sstevel@tonic-gate tty.c_oflag = termio.c_oflag; 12117c478bd9Sstevel@tonic-gate tty.c_cflag = termio.c_cflag; 12127c478bd9Sstevel@tonic-gate tty.c_lflag = termio.c_lflag; 12137c478bd9Sstevel@tonic-gate for(i = 0; i < NCC; i++) 12147c478bd9Sstevel@tonic-gate tty.c_cc[i] = termio.c_cc[i]; 1215*f6db9f27Scf46844 return (0); 12167c478bd9Sstevel@tonic-gate } 12177c478bd9Sstevel@tonic-gate 12187c478bd9Sstevel@tonic-gate /* 12197c478bd9Sstevel@tonic-gate * sTTY: set the tty modes on file descriptor i to be what's 12207c478bd9Sstevel@tonic-gate * currently in global "tty". (Also use nttyc if needed.) 12217c478bd9Sstevel@tonic-gate */ 1222*f6db9f27Scf46844 void 1223*f6db9f27Scf46844 sTTY(int i) 12247c478bd9Sstevel@tonic-gate { 12257c478bd9Sstevel@tonic-gate int j; 12267c478bd9Sstevel@tonic-gate if(termiosflag) 12277c478bd9Sstevel@tonic-gate ioctl(i, TCSETSW, &tty); 12287c478bd9Sstevel@tonic-gate else { 12297c478bd9Sstevel@tonic-gate termio.c_iflag = tty.c_iflag; 12307c478bd9Sstevel@tonic-gate termio.c_oflag = tty.c_oflag; 12317c478bd9Sstevel@tonic-gate termio.c_cflag = tty.c_cflag; 12327c478bd9Sstevel@tonic-gate termio.c_lflag = tty.c_lflag; 12337c478bd9Sstevel@tonic-gate for(j = 0; j < NCC; j++) 12347c478bd9Sstevel@tonic-gate termio.c_cc[j] = tty.c_cc[j]; 12357c478bd9Sstevel@tonic-gate ioctl(i, TCSETAW, &termio); 12367c478bd9Sstevel@tonic-gate } 12377c478bd9Sstevel@tonic-gate } 12387c478bd9Sstevel@tonic-gate 12397c478bd9Sstevel@tonic-gate /* 12407c478bd9Sstevel@tonic-gate * Print newline, or blank if in open/visual 12417c478bd9Sstevel@tonic-gate */ 1242*f6db9f27Scf46844 void 1243*f6db9f27Scf46844 noonl(void) 12447c478bd9Sstevel@tonic-gate { 12457c478bd9Sstevel@tonic-gate 12467c478bd9Sstevel@tonic-gate putchar(Outchar != termchar ? ' ' : '\n'); 12477c478bd9Sstevel@tonic-gate } 1248