xref: /onnv-gate/usr/src/cmd/vi/port/ex_v.c (revision 802:73b56fb6544b)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
23*802Scf46844  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
280Sstevel@tonic-gate /*	  All Rights Reserved  	*/
290Sstevel@tonic-gate 
300Sstevel@tonic-gate 
310Sstevel@tonic-gate /* Copyright (c) 1981 Regents of the University of California */
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
340Sstevel@tonic-gate 
350Sstevel@tonic-gate #include "ex.h"
360Sstevel@tonic-gate #include "ex_re.h"
370Sstevel@tonic-gate #include "ex_tty.h"
380Sstevel@tonic-gate #include "ex_vis.h"
390Sstevel@tonic-gate 
400Sstevel@tonic-gate /*
410Sstevel@tonic-gate  * Entry points to open and visual from command mode processor.
420Sstevel@tonic-gate  * The open/visual code breaks down roughly as follows:
430Sstevel@tonic-gate  *
440Sstevel@tonic-gate  * ex_v.c	entry points, checking of terminal characteristics
450Sstevel@tonic-gate  *
460Sstevel@tonic-gate  * ex_vadj.c	logical screen control, use of intelligent operations
470Sstevel@tonic-gate  *		insert/delete line and coordination with screen image;
480Sstevel@tonic-gate  *		updating of screen after changes.
490Sstevel@tonic-gate  *
500Sstevel@tonic-gate  * ex_vget.c	input of single keys and reading of input lines
510Sstevel@tonic-gate  *		from the echo area, handling of \ escapes on input for
520Sstevel@tonic-gate  *		uppercase only terminals, handling of memory for repeated
530Sstevel@tonic-gate  *		commands and small saved texts from inserts and partline
540Sstevel@tonic-gate  *		deletes, notification of multi line changes in the echo
550Sstevel@tonic-gate  *		area.
560Sstevel@tonic-gate  *
570Sstevel@tonic-gate  * ex_vmain.c	main command decoding, some command processing.
580Sstevel@tonic-gate  *
590Sstevel@tonic-gate  * ex_voperate.c   decoding of operator/operand sequences and
600Sstevel@tonic-gate  *		contextual scans, implementation of word motions.
610Sstevel@tonic-gate  *
620Sstevel@tonic-gate  * ex_vops.c	major operator interfaces, undos, motions, deletes,
630Sstevel@tonic-gate  *		changes, opening new lines, shifts, replacements and yanks
640Sstevel@tonic-gate  *		coordinating logical and physical changes.
650Sstevel@tonic-gate  *
660Sstevel@tonic-gate  * ex_vops2.c	subroutines for operator interfaces in ex_vops.c,
670Sstevel@tonic-gate  *		insert mode, read input line processing at lowest level.
680Sstevel@tonic-gate  *
690Sstevel@tonic-gate  * ex_vops3.c	structured motion definitions of ( ) { } and [ ] operators,
700Sstevel@tonic-gate  *		indent for lisp routines, () and {} balancing.
710Sstevel@tonic-gate  *
720Sstevel@tonic-gate  * ex_vput.c	output routines, clearing, physical mapping of logical cursor
730Sstevel@tonic-gate  *		positioning, cursor motions, handling of insert character
740Sstevel@tonic-gate  *		and delete character functions of intelligent and unintelligent
750Sstevel@tonic-gate  *		terminals, visual mode tracing routines (for debugging),
760Sstevel@tonic-gate  *		control of screen image and its updating.
770Sstevel@tonic-gate  *
780Sstevel@tonic-gate  * ex_vwind.c	window level control of display, forward and backward rolls,
790Sstevel@tonic-gate  *		absolute motions, contextual displays, line depth determination
800Sstevel@tonic-gate  */
810Sstevel@tonic-gate 
820Sstevel@tonic-gate void setsize();
830Sstevel@tonic-gate void winch();
840Sstevel@tonic-gate void vintr();
85*802Scf46844 void ovend(ttymode);
860Sstevel@tonic-gate 
870Sstevel@tonic-gate wchar_t	atube[TUBESIZE];
880Sstevel@tonic-gate jmp_buf	venv;
890Sstevel@tonic-gate int windowchg;
900Sstevel@tonic-gate int sigok;
910Sstevel@tonic-gate 
920Sstevel@tonic-gate /* reinitialize window size after SIGWINCH */
windowinit()930Sstevel@tonic-gate void windowinit()
940Sstevel@tonic-gate {
950Sstevel@tonic-gate 	windowchg = 0;
960Sstevel@tonic-gate 	setsize();
970Sstevel@tonic-gate 	if(value(vi_WINDOW) >= lines || options[vi_WINDOW].odefault == value(vi_WINDOW))
980Sstevel@tonic-gate 		value(vi_WINDOW) = lines -1;
990Sstevel@tonic-gate 	options[vi_WINDOW].odefault = lines - 1;
1000Sstevel@tonic-gate 	if(options[vi_SCROLL].odefault == value(vi_SCROLL))
1010Sstevel@tonic-gate 		value(vi_SCROLL) = value(vi_WINDOW)/2;
1020Sstevel@tonic-gate 	options[vi_SCROLL].odefault = (lines - 1)/2;
1030Sstevel@tonic-gate 	vsetsiz(value(vi_WINDOW));
1040Sstevel@tonic-gate 	setwind();
1050Sstevel@tonic-gate 	vok(atube, 1);
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate 
redraw()1080Sstevel@tonic-gate void redraw()
1090Sstevel@tonic-gate {
1100Sstevel@tonic-gate 	vsave();
1110Sstevel@tonic-gate 	windowinit();
1120Sstevel@tonic-gate 	vclear();
1130Sstevel@tonic-gate 	vdirty(0, lines);
1140Sstevel@tonic-gate 	if(state != VISUAL) {
1150Sstevel@tonic-gate 		vclean();
1160Sstevel@tonic-gate 		vmoveto(dot, cursor, 0);
1170Sstevel@tonic-gate 	} else {
1180Sstevel@tonic-gate 		vredraw(WTOP);
1190Sstevel@tonic-gate 		vrepaint(cursor);
1200Sstevel@tonic-gate 		vfixcurs();
1210Sstevel@tonic-gate 	}
1220Sstevel@tonic-gate }
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate /*ARGSUSED*/
1250Sstevel@tonic-gate void
1260Sstevel@tonic-gate #ifdef __STDC__
winch(int sig)1270Sstevel@tonic-gate winch(int sig)
1280Sstevel@tonic-gate #else
1290Sstevel@tonic-gate winch(sig)
1300Sstevel@tonic-gate int sig;
1310Sstevel@tonic-gate #endif
1320Sstevel@tonic-gate {
1330Sstevel@tonic-gate 	struct winsize jwin;
134*802Scf46844 	int l;
1350Sstevel@tonic-gate 
1360Sstevel@tonic-gate 	if(ioctl(0, TIOCGWINSZ, &jwin) != -1) {
1370Sstevel@tonic-gate #ifdef XPG4
1380Sstevel@tonic-gate 		oldlines = jwin.ws_row;
1390Sstevel@tonic-gate 		oldcolumns = jwin.ws_col;
1400Sstevel@tonic-gate #endif /* XPG4 */
1410Sstevel@tonic-gate 		if (sigok) {
1420Sstevel@tonic-gate 			if (columns != jwin.ws_col || lines != jwin.ws_row)
1430Sstevel@tonic-gate 			    redraw();
1440Sstevel@tonic-gate 		}
1450Sstevel@tonic-gate 	}
1460Sstevel@tonic-gate 	else
1470Sstevel@tonic-gate 		windowchg++;
1480Sstevel@tonic-gate 	(void)signal(SIGWINCH, winch);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate void
setsize()1520Sstevel@tonic-gate setsize()
1530Sstevel@tonic-gate {
1540Sstevel@tonic-gate 	struct winsize jwin;
155*802Scf46844 	int l;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	if(ioctl(0, TIOCGWINSZ, &jwin) != -1) {
1580Sstevel@tonic-gate 		if (jwin.ws_col > 0)
1590Sstevel@tonic-gate 			columns = jwin.ws_col;
1600Sstevel@tonic-gate 		if (jwin.ws_row > 0)
1610Sstevel@tonic-gate 			lines = jwin.ws_row;
1620Sstevel@tonic-gate 	}
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate #ifdef XPG4
1650Sstevel@tonic-gate 	if (envlines != -1) {
1660Sstevel@tonic-gate 		lines = envlines;
1670Sstevel@tonic-gate 	}
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	if (envcolumns != -1) {
1700Sstevel@tonic-gate 		columns = envcolumns;
1710Sstevel@tonic-gate 	}
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate 	if (envlines != -1 || envcolumns != -1) {
1740Sstevel@tonic-gate 		jwin.ws_row = lines;
1750Sstevel@tonic-gate 		jwin.ws_col = columns;
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate 		if (ioctl(0, TIOCSWINSZ, &jwin) == -1) {
1780Sstevel@tonic-gate 			jwin.ws_row = oldlines;
1790Sstevel@tonic-gate 			jwin.ws_col = oldcolumns;
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate 			ioctl(0, TIOCSWINSZ, &jwin);
1820Sstevel@tonic-gate 		}
1830Sstevel@tonic-gate 	}
1840Sstevel@tonic-gate #endif /* XPG4 */
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 	if (lines <= 1)
1870Sstevel@tonic-gate 		lines = 24;
1880Sstevel@tonic-gate 	l = lines;
1890Sstevel@tonic-gate 	if (columns <= 4)
1900Sstevel@tonic-gate 		columns = 1000;
1910Sstevel@tonic-gate 	value(vi_WINDOW) = options[vi_WINDOW].odefault = l - 1;
1920Sstevel@tonic-gate }
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate /*
1950Sstevel@tonic-gate  * Enter open mode
1960Sstevel@tonic-gate  */
197*802Scf46844 void
oop(void)198*802Scf46844 oop(void)
1990Sstevel@tonic-gate {
200*802Scf46844 	unsigned char *ic;
2010Sstevel@tonic-gate 	ttymode f;	/* was register */
2020Sstevel@tonic-gate 	int resize;
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate 	windowchg = 0;
2050Sstevel@tonic-gate 	(void)signal(SIGWINCH, winch);
2060Sstevel@tonic-gate 	ovbeg();
2070Sstevel@tonic-gate 	if (peekchar() == '/') {
2080Sstevel@tonic-gate 		(void)vi_compile(getchar(), 1);
2090Sstevel@tonic-gate 		savere(&scanre);
2100Sstevel@tonic-gate 		if (execute(0, dot) == 0)
2110Sstevel@tonic-gate 			error(value(vi_TERSE) ? gettext("Fail") :
2120Sstevel@tonic-gate gettext("Pattern not found on addressed line"));
2130Sstevel@tonic-gate 		ic = (unsigned char *)loc1;
2140Sstevel@tonic-gate 		if (ic > linebuf && *ic == 0)
2150Sstevel@tonic-gate 			ic--;
2160Sstevel@tonic-gate 	} else {
2170Sstevel@tonic-gate 		getDOT();
2180Sstevel@tonic-gate 		ic = vskipwh(linebuf);
2190Sstevel@tonic-gate 	}
2200Sstevel@tonic-gate 	donewline();
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate 	/*
2230Sstevel@tonic-gate 	 * If overstrike then have to HARDOPEN
2240Sstevel@tonic-gate 	 * else if can move cursor up off current line can use CRTOPEN (~~vi1)
2250Sstevel@tonic-gate 	 * otherwise have to use ONEOPEN (like adm3)
2260Sstevel@tonic-gate 	 */
2270Sstevel@tonic-gate 	if (over_strike && !erase_overstrike)
2280Sstevel@tonic-gate 		bastate = HARDOPEN;
2290Sstevel@tonic-gate 	else if (cursor_address || cursor_up)
2300Sstevel@tonic-gate 		bastate = CRTOPEN;
2310Sstevel@tonic-gate 	else
2320Sstevel@tonic-gate 		bastate = ONEOPEN;
2330Sstevel@tonic-gate 	setwind();
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate 	/*
2360Sstevel@tonic-gate 	 * To avoid bombing on glass-crt's when the line is too long
2370Sstevel@tonic-gate 	 * pretend that such terminals are 160 columns wide.
2380Sstevel@tonic-gate 	 * If a line is too wide for display, we will dynamically
2390Sstevel@tonic-gate 	 * switch to hardcopy open mode.
2400Sstevel@tonic-gate 	 */
2410Sstevel@tonic-gate 	if (state != CRTOPEN)
2420Sstevel@tonic-gate 		WCOLS = TUBECOLS;
2430Sstevel@tonic-gate 	if (!inglobal)
2440Sstevel@tonic-gate 		savevis();
2450Sstevel@tonic-gate 	vok(atube, 0);
2460Sstevel@tonic-gate 	if (state != CRTOPEN)
2470Sstevel@tonic-gate 		columns = WCOLS;
2480Sstevel@tonic-gate 	Outchar = vputchar;
2490Sstevel@tonic-gate 	f = ostart();
2500Sstevel@tonic-gate 	if (state == CRTOPEN) {
2510Sstevel@tonic-gate 		if (outcol == UKCOL)
2520Sstevel@tonic-gate 			outcol = 0;
2530Sstevel@tonic-gate 		vmoveitup(1, 1);
2540Sstevel@tonic-gate 	} else
2550Sstevel@tonic-gate 		outline = destline = WBOT;
2560Sstevel@tonic-gate 	vshow(dot, NOLINE);
2570Sstevel@tonic-gate 	vnline(ic);
2580Sstevel@tonic-gate 	vmain();
2590Sstevel@tonic-gate 	if (state != CRTOPEN)
2600Sstevel@tonic-gate 		vclean();
2610Sstevel@tonic-gate 	Command = (unsigned char *)"open";
2620Sstevel@tonic-gate 	ovend(f);
2630Sstevel@tonic-gate 	(void)signal(SIGWINCH, SIG_DFL);
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate 
266*802Scf46844 void
ovbeg(void)267*802Scf46844 ovbeg(void)
2680Sstevel@tonic-gate {
2690Sstevel@tonic-gate 
2700Sstevel@tonic-gate 	if (inopen)
2710Sstevel@tonic-gate 		error(gettext("Recursive open/visual not allowed"));
2720Sstevel@tonic-gate 	Vlines = lineDOL();
2730Sstevel@tonic-gate 	fixzero();
2740Sstevel@tonic-gate 	setdot();
2750Sstevel@tonic-gate 	pastwh();
2760Sstevel@tonic-gate 	dot = addr2;
2770Sstevel@tonic-gate }
2780Sstevel@tonic-gate 
279*802Scf46844 void
ovend(ttymode f)280*802Scf46844 ovend(ttymode f)
2810Sstevel@tonic-gate {
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate 	splitw++;
2840Sstevel@tonic-gate 	vgoto(WECHO, 0);
2850Sstevel@tonic-gate 	vclreol();
2860Sstevel@tonic-gate 	vgoto(WECHO, 0);
2870Sstevel@tonic-gate 	holdcm = 0;
2880Sstevel@tonic-gate 	splitw = 0;
2890Sstevel@tonic-gate 	ostop(f);
2900Sstevel@tonic-gate 	setoutt();
2910Sstevel@tonic-gate 	undvis();
2920Sstevel@tonic-gate 	columns = OCOLUMNS;
2930Sstevel@tonic-gate 	inopen = 0;
2940Sstevel@tonic-gate 	flusho();
2950Sstevel@tonic-gate 	netchHAD(Vlines);
2960Sstevel@tonic-gate }
2970Sstevel@tonic-gate 
2980Sstevel@tonic-gate /*
2990Sstevel@tonic-gate  * Enter visual mode
3000Sstevel@tonic-gate  */
301*802Scf46844 void
vop(void)302*802Scf46844 vop(void)
3030Sstevel@tonic-gate {
304*802Scf46844 	int c;
3050Sstevel@tonic-gate 	ttymode f;	/* was register */
3060Sstevel@tonic-gate 	extern unsigned char termtype[];
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate 	if (!cursor_address && !cursor_up) {
3090Sstevel@tonic-gate 		if (initev) {
3100Sstevel@tonic-gate toopen:
3110Sstevel@tonic-gate 			if (generic_type)
3120Sstevel@tonic-gate 				merror(gettext("I don't know what kind of terminal you are on - all I have is '%s'."), termtype);
3130Sstevel@tonic-gate 			putNFL();
3140Sstevel@tonic-gate 			merror(gettext("[Using open mode]"));
3150Sstevel@tonic-gate 			putNFL();
3160Sstevel@tonic-gate 			oop();
3170Sstevel@tonic-gate 			return;
3180Sstevel@tonic-gate 		}
3190Sstevel@tonic-gate 		error(gettext("Visual needs addressable cursor or upline capability"));
3200Sstevel@tonic-gate 	}
3210Sstevel@tonic-gate 	if (over_strike && !erase_overstrike) {
3220Sstevel@tonic-gate 		if (initev)
3230Sstevel@tonic-gate 			goto toopen;
3240Sstevel@tonic-gate 		error(gettext("Can't use visual on a terminal which overstrikes"));
3250Sstevel@tonic-gate 	}
3260Sstevel@tonic-gate 	if (!clear_screen) {
3270Sstevel@tonic-gate 		if (initev)
3280Sstevel@tonic-gate 			goto toopen;
3290Sstevel@tonic-gate 		error(gettext("Visual requires clear screen capability"));
3300Sstevel@tonic-gate 	}
3310Sstevel@tonic-gate 	if (!scroll_forward) {
3320Sstevel@tonic-gate 		if (initev)
3330Sstevel@tonic-gate 			goto toopen;
3340Sstevel@tonic-gate 		error(gettext("Visual requires scrolling"));
3350Sstevel@tonic-gate 	}
3360Sstevel@tonic-gate 	windowchg = 0;
3370Sstevel@tonic-gate 	(void)signal(SIGWINCH, winch);
3380Sstevel@tonic-gate 	ovbeg();
3390Sstevel@tonic-gate 	bastate = VISUAL;
3400Sstevel@tonic-gate 	c = 0;
3410Sstevel@tonic-gate 	if (any(peekchar(), "+-^."))
3420Sstevel@tonic-gate 		c = getchar();
3430Sstevel@tonic-gate 	pastwh();
3440Sstevel@tonic-gate 	vsetsiz(isdigit(peekchar()) ? getnum() : value(vi_WINDOW));
3450Sstevel@tonic-gate 	setwind();
3460Sstevel@tonic-gate 	donewline();
3470Sstevel@tonic-gate 	vok(atube, 0);
3480Sstevel@tonic-gate 	if (!inglobal)
3490Sstevel@tonic-gate 		savevis();
3500Sstevel@tonic-gate 	Outchar = vputchar;
3510Sstevel@tonic-gate 	vmoving = 0;
3520Sstevel@tonic-gate 	f = ostart();
3530Sstevel@tonic-gate 	if (initev == 0) {
3540Sstevel@tonic-gate 		vcontext(dot, c);
355*802Scf46844 		vnline((unsigned char *)NOSTR);
3560Sstevel@tonic-gate 	}
3570Sstevel@tonic-gate 	vmain();
3580Sstevel@tonic-gate 	Command = (unsigned char *)"visual";
3590Sstevel@tonic-gate 	ovend(f);
3600Sstevel@tonic-gate 	(void)signal(SIGWINCH, SIG_DFL);
3610Sstevel@tonic-gate }
3620Sstevel@tonic-gate 
3630Sstevel@tonic-gate /*
3640Sstevel@tonic-gate  * Hack to allow entry to visual with
3650Sstevel@tonic-gate  * empty buffer since routines internally
3660Sstevel@tonic-gate  * demand at least one line.
3670Sstevel@tonic-gate  */
368*802Scf46844 void
fixzero(void)369*802Scf46844 fixzero(void)
3700Sstevel@tonic-gate {
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate 	if (dol == zero) {
373*802Scf46844 		bool ochng = chng;
3740Sstevel@tonic-gate 
375*802Scf46844 		vdoappend((unsigned char *)"");
3760Sstevel@tonic-gate 		if (!ochng)
3770Sstevel@tonic-gate 			sync();
3780Sstevel@tonic-gate 		addr1 = addr2 = one;
3790Sstevel@tonic-gate 	} else if (addr2 == zero)
3800Sstevel@tonic-gate 		addr2 = one;
3810Sstevel@tonic-gate }
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate /*
3840Sstevel@tonic-gate  * Save lines before visual between unddol and truedol.
3850Sstevel@tonic-gate  * Accomplish this by throwing away current [unddol,truedol]
3860Sstevel@tonic-gate  * and then saving all the lines in the buffer and moving
3870Sstevel@tonic-gate  * unddol back to dol.  Don't do this if in a global.
3880Sstevel@tonic-gate  *
3890Sstevel@tonic-gate  * If you do
3900Sstevel@tonic-gate  *	g/xxx/vi.
3910Sstevel@tonic-gate  * and then do a
3920Sstevel@tonic-gate  *	:e xxxx
3930Sstevel@tonic-gate  * at some point, and then quit from the visual and undo
3940Sstevel@tonic-gate  * you get the old file back.  Somewhat weird.
3950Sstevel@tonic-gate  */
396*802Scf46844 void
savevis(void)397*802Scf46844 savevis(void)
3980Sstevel@tonic-gate {
3990Sstevel@tonic-gate 
4000Sstevel@tonic-gate 	if (inglobal)
4010Sstevel@tonic-gate 		return;
4020Sstevel@tonic-gate 	truedol = unddol;
4030Sstevel@tonic-gate 	saveall();
4040Sstevel@tonic-gate 	unddol = dol;
4050Sstevel@tonic-gate 	undkind = UNDNONE;
4060Sstevel@tonic-gate }
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate /*
4090Sstevel@tonic-gate  * Restore a sensible state after a visual/open, moving the saved
4100Sstevel@tonic-gate  * stuff back to [unddol,dol], and killing the partial line kill indicators.
4110Sstevel@tonic-gate  */
412*802Scf46844 void
undvis(void)413*802Scf46844 undvis(void)
4140Sstevel@tonic-gate {
4150Sstevel@tonic-gate 
4160Sstevel@tonic-gate 	if (ruptible)
4170Sstevel@tonic-gate 		signal(SIGINT, onintr);
4180Sstevel@tonic-gate 	squish();
4190Sstevel@tonic-gate 	pkill[0] = pkill[1] = 0;
4200Sstevel@tonic-gate 	unddol = truedol;
4210Sstevel@tonic-gate 	unddel = zero;
4220Sstevel@tonic-gate 	undap1 = one;
4230Sstevel@tonic-gate 	undap2 = dol + 1;
4240Sstevel@tonic-gate 	undkind = UNDALL;
4250Sstevel@tonic-gate 	if (undadot <= zero || undadot > dol)
4260Sstevel@tonic-gate 		undadot = zero+1;
4270Sstevel@tonic-gate }
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate /*
4300Sstevel@tonic-gate  * Set the window parameters based on the base state bastate
4310Sstevel@tonic-gate  * and the available buffer space.
4320Sstevel@tonic-gate  */
433*802Scf46844 void
setwind(void)434*802Scf46844 setwind(void)
4350Sstevel@tonic-gate {
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate 	WCOLS = columns;
4380Sstevel@tonic-gate 	switch (bastate) {
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate 	case ONEOPEN:
4410Sstevel@tonic-gate 		if (auto_right_margin)
4420Sstevel@tonic-gate 			WCOLS--;
4430Sstevel@tonic-gate 		/* fall into ... */
4440Sstevel@tonic-gate 
4450Sstevel@tonic-gate 	case HARDOPEN:
4460Sstevel@tonic-gate 		basWTOP = WTOP = WBOT = WECHO = 0;
4470Sstevel@tonic-gate 		ZERO = 0;
4480Sstevel@tonic-gate 		holdcm++;
4490Sstevel@tonic-gate 		break;
4500Sstevel@tonic-gate 
4510Sstevel@tonic-gate 	case CRTOPEN:
4520Sstevel@tonic-gate 		basWTOP = lines - 2;
4530Sstevel@tonic-gate 		/* fall into */
4540Sstevel@tonic-gate 
4550Sstevel@tonic-gate 	case VISUAL:
4560Sstevel@tonic-gate 		ZERO = lines - TUBESIZE / WCOLS;
4570Sstevel@tonic-gate 		if (ZERO < 0)
4580Sstevel@tonic-gate 			ZERO = 0;
4590Sstevel@tonic-gate 		if (ZERO > basWTOP)
4600Sstevel@tonic-gate 			error(gettext("Screen too large for internal buffer"));
4610Sstevel@tonic-gate 		WTOP = basWTOP; WBOT = lines - 2; WECHO = lines - 1;
4620Sstevel@tonic-gate 		break;
4630Sstevel@tonic-gate 	}
4640Sstevel@tonic-gate 	state = bastate;
4650Sstevel@tonic-gate 	basWLINES = WLINES = WBOT - WTOP + 1;
4660Sstevel@tonic-gate }
4670Sstevel@tonic-gate 
4680Sstevel@tonic-gate /*
4690Sstevel@tonic-gate  * Can we hack an open/visual on this terminal?
4700Sstevel@tonic-gate  * If so, then divide the screen buffer up into lines,
4710Sstevel@tonic-gate  * and initialize a bunch of state variables before we start.
4720Sstevel@tonic-gate  */
4730Sstevel@tonic-gate static unsigned char vlinebuf[LBSIZE];
4740Sstevel@tonic-gate 
475*802Scf46844 void
vok(wchar_t * atube,int undo)476*802Scf46844 vok(wchar_t *atube, int undo)
4770Sstevel@tonic-gate {
478*802Scf46844 	int i;
4790Sstevel@tonic-gate 	static int beenhere;
4800Sstevel@tonic-gate 
4810Sstevel@tonic-gate 	if (WCOLS == 1000)
482*802Scf46844 		serror((unsigned char *)
483*802Scf46844 		    gettext("Don't know enough about your terminal to use %s"),
484*802Scf46844 		    Command);
4850Sstevel@tonic-gate 	if (WCOLS > TUBECOLS)
4860Sstevel@tonic-gate 		error(gettext("Terminal too wide"));
4870Sstevel@tonic-gate 	if (WLINES >= TUBELINES || WCOLS * (WECHO - ZERO + 1) > TUBESIZE)
4880Sstevel@tonic-gate 		error(gettext("Screen too large"));
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate 	vtube0 = atube;
4910Sstevel@tonic-gate 	if(beenhere)
4920Sstevel@tonic-gate 		vclrbyte(atube, WCOLS * (WECHO - ZERO + 1));
4930Sstevel@tonic-gate 	for (i = 0; i < ZERO; i++)
4940Sstevel@tonic-gate 		vtube[i] = (wchar_t *) 0;
4950Sstevel@tonic-gate 	for (; i <= WECHO; i++)
4960Sstevel@tonic-gate 		vtube[i] = atube, atube += WCOLS;
4970Sstevel@tonic-gate 	if(beenhere++) {
4980Sstevel@tonic-gate 		for (; i < TUBELINES; i++)
4990Sstevel@tonic-gate 			vtube[i] = (wchar_t *) 0;
5000Sstevel@tonic-gate 	}
5010Sstevel@tonic-gate 	vutmp = vlinebuf;
5020Sstevel@tonic-gate 	if(!undo) {
5030Sstevel@tonic-gate 		vundkind = VNONE;
5040Sstevel@tonic-gate 		vUNDdot = 0;
5050Sstevel@tonic-gate 	}
5060Sstevel@tonic-gate 	OCOLUMNS = columns;
5070Sstevel@tonic-gate 	inopen = 1;
5080Sstevel@tonic-gate #ifdef CBREAK
5090Sstevel@tonic-gate 	signal(SIGINT, vintr);
5100Sstevel@tonic-gate #endif
5110Sstevel@tonic-gate 	vmoving = 0;
5120Sstevel@tonic-gate 	splitw = 0;
5130Sstevel@tonic-gate 	doomed = 0;
5140Sstevel@tonic-gate 	holdupd = 0;
5150Sstevel@tonic-gate 	if(!undo)
5160Sstevel@tonic-gate 		Peekkey = 0;
5170Sstevel@tonic-gate 	vcnt = vcline = 0;
5180Sstevel@tonic-gate 	if (vSCROLL == 0)
5190Sstevel@tonic-gate 		vSCROLL = value(vi_SCROLL);
5200Sstevel@tonic-gate }
5210Sstevel@tonic-gate 
5220Sstevel@tonic-gate #ifdef CBREAK
5230Sstevel@tonic-gate /*ARGSUSED*/
5240Sstevel@tonic-gate void
5250Sstevel@tonic-gate #ifdef __STDC__
vintr(int sig)5260Sstevel@tonic-gate vintr(int sig)
5270Sstevel@tonic-gate #else
5280Sstevel@tonic-gate vintr(sig)
5290Sstevel@tonic-gate int sig;
5300Sstevel@tonic-gate #endif
5310Sstevel@tonic-gate {
5320Sstevel@tonic-gate 
5330Sstevel@tonic-gate 	signal(SIGINT, vintr);
5340Sstevel@tonic-gate 	if (vcatch)
5350Sstevel@tonic-gate 		onintr(0);
5360Sstevel@tonic-gate 	ungetkey(ATTN);
5370Sstevel@tonic-gate 	draino();
5380Sstevel@tonic-gate }
5390Sstevel@tonic-gate #endif
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate /*
5420Sstevel@tonic-gate  * Set the size of the screen to size lines, to take effect the
5430Sstevel@tonic-gate  * next time the screen is redrawn.
5440Sstevel@tonic-gate  */
545*802Scf46844 void
vsetsiz(int size)546*802Scf46844 vsetsiz(int size)
5470Sstevel@tonic-gate {
548*802Scf46844 	int b;
5490Sstevel@tonic-gate 
5500Sstevel@tonic-gate 	if (bastate != VISUAL)
5510Sstevel@tonic-gate 		return;
5520Sstevel@tonic-gate 	b = lines - 1 - size;
5530Sstevel@tonic-gate 	if (b >= lines - 1)
5540Sstevel@tonic-gate 		b = lines - 2;
5550Sstevel@tonic-gate 	if (b < 0)
5560Sstevel@tonic-gate 		b = 0;
5570Sstevel@tonic-gate 	basWTOP = b;
5580Sstevel@tonic-gate 	basWLINES = WBOT - b + 1;
5590Sstevel@tonic-gate }
560