xref: /onnv-gate/usr/src/cmd/vi/port/ex_vwind.c (revision 13093:48f2dbca79a2)
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
5*13093SRoger.Faulkner@Oracle.COM  * Common Development and Distribution License (the "License").
6*13093SRoger.Faulkner@Oracle.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*13093SRoger.Faulkner@Oracle.COM 
22802Scf46844 /*
23*13093SRoger.Faulkner@Oracle.COM  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24802Scf46844  */
25802Scf46844 
260Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
270Sstevel@tonic-gate /*	  All Rights Reserved  	*/
280Sstevel@tonic-gate 
290Sstevel@tonic-gate 
300Sstevel@tonic-gate /* Copyright (c) 1981 Regents of the University of California */
31802Scf46844 
320Sstevel@tonic-gate #include "ex.h"
330Sstevel@tonic-gate #include "ex_tty.h"
340Sstevel@tonic-gate #include "ex_vis.h"
350Sstevel@tonic-gate 
360Sstevel@tonic-gate /*
370Sstevel@tonic-gate  * Routines to adjust the window, showing specified lines
380Sstevel@tonic-gate  * in certain positions on the screen, and scrolling in both
390Sstevel@tonic-gate  * directions.  Code here is very dependent on mode (open versus visual).
400Sstevel@tonic-gate  */
410Sstevel@tonic-gate 
420Sstevel@tonic-gate /*
430Sstevel@tonic-gate  * Move in a nonlocal way to line addr.
440Sstevel@tonic-gate  * If it isn't on screen put it in specified context.
450Sstevel@tonic-gate  * New position for cursor is curs.
460Sstevel@tonic-gate  * Like most routines here, we vsave().
470Sstevel@tonic-gate  */
48802Scf46844 void
vmoveto(addr,curs,context)490Sstevel@tonic-gate vmoveto(addr, curs, context)
50802Scf46844 	line *addr;
510Sstevel@tonic-gate 	unsigned char *curs;
520Sstevel@tonic-gate 	unsigned char context;
530Sstevel@tonic-gate {
540Sstevel@tonic-gate 
550Sstevel@tonic-gate 	markit(addr);
560Sstevel@tonic-gate 	vsave();
570Sstevel@tonic-gate 	vjumpto(addr, curs, context);
580Sstevel@tonic-gate }
590Sstevel@tonic-gate 
600Sstevel@tonic-gate /*
610Sstevel@tonic-gate  * Vjumpto is like vmoveto, but doesn't mark previous
620Sstevel@tonic-gate  * context or save linebuf as current line.
630Sstevel@tonic-gate  */
64802Scf46844 void
vjumpto(line * addr,unsigned char * curs,unsigned char context)65802Scf46844 vjumpto(line *addr, unsigned char *curs, unsigned char context)
660Sstevel@tonic-gate {
670Sstevel@tonic-gate 
680Sstevel@tonic-gate 	noteit(0);
690Sstevel@tonic-gate 	if (context != 0)
700Sstevel@tonic-gate 		vcontext(addr, context);
710Sstevel@tonic-gate 	else
720Sstevel@tonic-gate 		vshow(addr, NOLINE);
730Sstevel@tonic-gate 	noteit(1);
740Sstevel@tonic-gate 	vnline(curs);
750Sstevel@tonic-gate }
760Sstevel@tonic-gate 
770Sstevel@tonic-gate /*
780Sstevel@tonic-gate  * Go up or down cnt (negative is up) to new position curs.
790Sstevel@tonic-gate  */
80802Scf46844 void
vupdown(int cnt,unsigned char * curs)81802Scf46844 vupdown(int cnt, unsigned char *curs)
820Sstevel@tonic-gate {
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	if (cnt > 0)
850Sstevel@tonic-gate 		vdown(cnt, 0, 0);
860Sstevel@tonic-gate 	else if (cnt < 0)
870Sstevel@tonic-gate 		vup(-cnt, 0, 0);
880Sstevel@tonic-gate 	if (vcnt == 0)
890Sstevel@tonic-gate 		vrepaint(curs);
900Sstevel@tonic-gate 	else
910Sstevel@tonic-gate 		vnline(curs);
920Sstevel@tonic-gate }
930Sstevel@tonic-gate 
940Sstevel@tonic-gate /*
950Sstevel@tonic-gate  * Go up cnt lines, afterwards preferring to be ind
960Sstevel@tonic-gate  * logical lines from the top of the screen.
970Sstevel@tonic-gate  * If scroll, then we MUST use a scroll.
980Sstevel@tonic-gate  * Otherwise clear and redraw if motion is far.
990Sstevel@tonic-gate  */
100802Scf46844 void
vup(int cnt,int ind,bool scroll)101802Scf46844 vup(int cnt, int ind, bool scroll)
1020Sstevel@tonic-gate {
103802Scf46844 	int i, tot;
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate 	if (dot == one) {
106802Scf46844 		(void) beep();
1070Sstevel@tonic-gate 		return;
1080Sstevel@tonic-gate 	}
1090Sstevel@tonic-gate 	vsave();
1100Sstevel@tonic-gate 	i = lineDOT() - 1;
1110Sstevel@tonic-gate 	if (cnt > i) {
1120Sstevel@tonic-gate 		ind -= cnt - i;
1130Sstevel@tonic-gate 		if (ind < 0)
1140Sstevel@tonic-gate 			ind = 0;
1150Sstevel@tonic-gate 		cnt = i;
1160Sstevel@tonic-gate 	}
1170Sstevel@tonic-gate 	if (!scroll && cnt <= vcline) {
1180Sstevel@tonic-gate 		vshow(dot - cnt, NOLINE);
1190Sstevel@tonic-gate 		return;
1200Sstevel@tonic-gate 	}
1210Sstevel@tonic-gate 	cnt -= vcline, dot -= vcline, vcline = 0;
1220Sstevel@tonic-gate 	if (hold & HOLDWIG)
1230Sstevel@tonic-gate 		goto contxt;
1240Sstevel@tonic-gate 	if (state == VISUAL && !insert_line && !scroll_reverse &&
1250Sstevel@tonic-gate 	    cnt <= WTOP - ZERO && vfit(dot - cnt, cnt) <= WTOP - ZERO)
1260Sstevel@tonic-gate 		goto okr;
1270Sstevel@tonic-gate 	tot = WECHO - WTOP;
1280Sstevel@tonic-gate 	if (state != VISUAL || (!insert_line && !scroll_reverse) || (!scroll && (cnt > tot || vfit(dot - cnt, cnt) > tot / 3 + 1))) {
1290Sstevel@tonic-gate 		if (ind > basWLINES / 2)
1300Sstevel@tonic-gate 			ind = basWLINES / 3;
1310Sstevel@tonic-gate contxt:
1320Sstevel@tonic-gate 		vcontext(dot + ind - cnt, '.');
1330Sstevel@tonic-gate 		return;
1340Sstevel@tonic-gate 	}
1350Sstevel@tonic-gate okr:
1360Sstevel@tonic-gate 	vrollR(cnt);
1370Sstevel@tonic-gate 	if (scroll) {
1380Sstevel@tonic-gate 		vcline += ind, dot += ind;
1390Sstevel@tonic-gate 		if (vcline >= vcnt)
1400Sstevel@tonic-gate 			dot -= vcline - vcnt + 1, vcline = vcnt - 1;
1410Sstevel@tonic-gate 		getDOT();
1420Sstevel@tonic-gate 	}
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate /*
1460Sstevel@tonic-gate  * Like vup, but scrolling down.
1470Sstevel@tonic-gate  */
148802Scf46844 void
vdown(int cnt,int ind,bool scroll)149802Scf46844 vdown(int cnt, int ind, bool scroll)
1500Sstevel@tonic-gate {
151802Scf46844 	int i, tot;
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate 	if (dot == dol) {
154802Scf46844 		(void) beep();
1550Sstevel@tonic-gate 		return;
1560Sstevel@tonic-gate 	}
1570Sstevel@tonic-gate 	vsave();
1580Sstevel@tonic-gate 	i = dol - dot;
1590Sstevel@tonic-gate 	if (cnt > i) {
1600Sstevel@tonic-gate 		ind -= cnt - i;
1610Sstevel@tonic-gate 		if (ind < 0)
1620Sstevel@tonic-gate 			ind = 0;
1630Sstevel@tonic-gate 		cnt = i;
1640Sstevel@tonic-gate 	}
1650Sstevel@tonic-gate 	i = vcnt - vcline - 1;
1660Sstevel@tonic-gate 	if (!scroll && cnt <= i) {
1670Sstevel@tonic-gate 		vshow(dot + cnt, NOLINE);
1680Sstevel@tonic-gate 		return;
1690Sstevel@tonic-gate 	}
1700Sstevel@tonic-gate 	cnt -= i, dot += i, vcline += i;
1710Sstevel@tonic-gate 	if (hold & HOLDWIG)
1720Sstevel@tonic-gate 		goto dcontxt;
1730Sstevel@tonic-gate 	if (!scroll) {
1740Sstevel@tonic-gate 		tot = WECHO - WTOP;
1750Sstevel@tonic-gate 		if (state != VISUAL || cnt - tot > 0 || vfit(dot, cnt) > tot / 3 + 1) {
1760Sstevel@tonic-gate dcontxt:
1770Sstevel@tonic-gate 			vcontext(dot + cnt, '.');
1780Sstevel@tonic-gate 			return;
1790Sstevel@tonic-gate 		}
1800Sstevel@tonic-gate 	}
1810Sstevel@tonic-gate 	if (cnt > 0)
1820Sstevel@tonic-gate 		vroll(cnt);
1830Sstevel@tonic-gate 	if (state == VISUAL && scroll) {
1840Sstevel@tonic-gate 		vcline -= ind, dot -= ind;
1850Sstevel@tonic-gate 		if (vcline < 0)
1860Sstevel@tonic-gate 			dot -= vcline, vcline = 0;
1870Sstevel@tonic-gate 		getDOT();
1880Sstevel@tonic-gate 	}
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate /*
1920Sstevel@tonic-gate  * Show line addr in context where on the screen.
1930Sstevel@tonic-gate  * Work here is in determining new top line implied by
1940Sstevel@tonic-gate  * this placement of line addr, since we always draw from the top.
1950Sstevel@tonic-gate  */
196802Scf46844 void
vcontext(line * addr,unsigned char where)197802Scf46844 vcontext(line *addr, unsigned char where)
1980Sstevel@tonic-gate {
199802Scf46844 	line *top;
2000Sstevel@tonic-gate 
201*13093SRoger.Faulkner@Oracle.COM 	getaline(*addr);
2020Sstevel@tonic-gate 	if (state != VISUAL)
2030Sstevel@tonic-gate 		top = addr;
2040Sstevel@tonic-gate 	else switch (where) {
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 	case '^':
2070Sstevel@tonic-gate 		addr = vback(addr, basWLINES - vdepth());
208*13093SRoger.Faulkner@Oracle.COM 		getaline(*addr);
2090Sstevel@tonic-gate 		/* fall into ... */
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 	case '-':
2120Sstevel@tonic-gate 		top = vback(addr, basWLINES - vdepth());
213*13093SRoger.Faulkner@Oracle.COM 		getaline(*addr);
2140Sstevel@tonic-gate 		break;
2150Sstevel@tonic-gate 
2160Sstevel@tonic-gate 	case '.':
2170Sstevel@tonic-gate 		top = vback(addr, basWLINES / 2 - vdepth());
218*13093SRoger.Faulkner@Oracle.COM 		getaline(*addr);
2190Sstevel@tonic-gate 		break;
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate 	default:
2220Sstevel@tonic-gate 		top = addr;
2230Sstevel@tonic-gate 		break;
2240Sstevel@tonic-gate 	}
2250Sstevel@tonic-gate 	if (state == ONEOPEN && LINE(0) == WBOT)
2260Sstevel@tonic-gate 		vup1();
2270Sstevel@tonic-gate 	vcnt = vcline = 0;
2280Sstevel@tonic-gate 	vclean();
2290Sstevel@tonic-gate 	if (state == CRTOPEN)
2300Sstevel@tonic-gate 		vup1();
2310Sstevel@tonic-gate 	vshow(addr, top);
2320Sstevel@tonic-gate }
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate /*
2350Sstevel@tonic-gate  * Get a clean line.  If we are in a hard open
2360Sstevel@tonic-gate  * we may be able to reuse the line we are on
2370Sstevel@tonic-gate  * if it is blank.  This is a real win.
2380Sstevel@tonic-gate  */
239802Scf46844 void
vclean(void)240802Scf46844 vclean(void)
2410Sstevel@tonic-gate {
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate 	if (state != VISUAL && state != CRTOPEN) {
2440Sstevel@tonic-gate 		destcol = 0;
2450Sstevel@tonic-gate 		if (!ateopr())
2460Sstevel@tonic-gate 			vup1();
2470Sstevel@tonic-gate 		vcnt = 0;
2480Sstevel@tonic-gate 	}
2490Sstevel@tonic-gate }
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate /*
2520Sstevel@tonic-gate  * Show line addr with the specified top line on the screen.
2530Sstevel@tonic-gate  * Top may be 0; in this case have vcontext compute the top
2540Sstevel@tonic-gate  * (and call us recursively).  Eventually, we clear the screen
2550Sstevel@tonic-gate  * (or its open mode equivalent) and redraw.
2560Sstevel@tonic-gate  */
257802Scf46844 void
vshow(line * addr,line * top)258802Scf46844 vshow(line *addr, line *top)
2590Sstevel@tonic-gate {
2600Sstevel@tonic-gate #ifndef CBREAK
261802Scf46844 	bool fried = 0;
2620Sstevel@tonic-gate #endif
263802Scf46844 	int cnt = addr - dot;
264802Scf46844 	int i = vcline + cnt;
2650Sstevel@tonic-gate 	short oldhold = hold;
2660Sstevel@tonic-gate 
2670Sstevel@tonic-gate 	if (state != HARDOPEN && state != ONEOPEN && i >= 0 && i < vcnt) {
2680Sstevel@tonic-gate 		dot = addr;
2690Sstevel@tonic-gate 		getDOT();
2700Sstevel@tonic-gate 		vcline = i;
2710Sstevel@tonic-gate 		return;
2720Sstevel@tonic-gate 	}
2730Sstevel@tonic-gate 	if (state != VISUAL) {
2740Sstevel@tonic-gate 		dot = addr;
2750Sstevel@tonic-gate 		vopen(dot, WBOT);
2760Sstevel@tonic-gate 		return;
2770Sstevel@tonic-gate 	}
2780Sstevel@tonic-gate 	if (top == 0) {
2790Sstevel@tonic-gate 		vcontext(addr, '.');
2800Sstevel@tonic-gate 		return;
2810Sstevel@tonic-gate 	}
2820Sstevel@tonic-gate 	dot = top;
2830Sstevel@tonic-gate #ifndef CBREAK
2840Sstevel@tonic-gate 	if (vcookit(2))
2850Sstevel@tonic-gate 		fried++, vcook();
2860Sstevel@tonic-gate #endif
2870Sstevel@tonic-gate 	oldhold = hold;
2880Sstevel@tonic-gate 	hold |= HOLDAT;
2890Sstevel@tonic-gate 	vclear();
2900Sstevel@tonic-gate 	vreset(0);
2910Sstevel@tonic-gate 	vredraw(WTOP);
2920Sstevel@tonic-gate 	/* error if vcline >= vcnt ! */
2930Sstevel@tonic-gate 	vcline = addr - top;
2940Sstevel@tonic-gate 	dot = addr;
2950Sstevel@tonic-gate 	getDOT();
2960Sstevel@tonic-gate 	hold = oldhold;
2970Sstevel@tonic-gate 	vsync(LASTLINE);
2980Sstevel@tonic-gate #ifndef CBREAK
2990Sstevel@tonic-gate 	if (fried)
3000Sstevel@tonic-gate 		flusho(), vraw();
3010Sstevel@tonic-gate #endif
3020Sstevel@tonic-gate }
3030Sstevel@tonic-gate 
3040Sstevel@tonic-gate /*
3050Sstevel@tonic-gate  * reset the state.
3060Sstevel@tonic-gate  * If inecho then leave us at the beginning of the echo
3070Sstevel@tonic-gate  * area;  we are called this way in the middle of a :e escape
3080Sstevel@tonic-gate  * from visual, e.g.
3090Sstevel@tonic-gate  */
310802Scf46844 void
vreset(bool inecho)311802Scf46844 vreset(bool inecho)
3120Sstevel@tonic-gate {
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate 	vcnt = vcline = 0;
3150Sstevel@tonic-gate 	WTOP = basWTOP;
3160Sstevel@tonic-gate 	WLINES = basWLINES;
3170Sstevel@tonic-gate 	if (inecho)
3180Sstevel@tonic-gate 		splitw = 1, vgoto(WECHO, 0);
3190Sstevel@tonic-gate }
3200Sstevel@tonic-gate 
3210Sstevel@tonic-gate /*
3220Sstevel@tonic-gate  * Starting from which line preceding tp uses almost (but not more
3230Sstevel@tonic-gate  * than) cnt physical lines?
3240Sstevel@tonic-gate  */
3250Sstevel@tonic-gate line *
vback(tp,cnt)3260Sstevel@tonic-gate vback(tp, cnt)
327802Scf46844 	int cnt;
328802Scf46844 	line *tp;
3290Sstevel@tonic-gate {
330802Scf46844 	int d;
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate 	if (cnt > 0)
3330Sstevel@tonic-gate 		for (; tp > one; tp--) {
334*13093SRoger.Faulkner@Oracle.COM 			getaline(tp[-1]);
3350Sstevel@tonic-gate 			d = vdepth();
3360Sstevel@tonic-gate 			if (d > cnt)
3370Sstevel@tonic-gate 				break;
3380Sstevel@tonic-gate 			cnt -= d;
3390Sstevel@tonic-gate 		}
3400Sstevel@tonic-gate 	return (tp);
3410Sstevel@tonic-gate }
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate /*
3440Sstevel@tonic-gate  * How much scrolling will it take to roll cnt lines starting at tp?
3450Sstevel@tonic-gate  */
346802Scf46844 int
vfit(line * tp,int cnt)347802Scf46844 vfit(line *tp, int cnt)
3480Sstevel@tonic-gate {
349802Scf46844 	int j;
3500Sstevel@tonic-gate 
3510Sstevel@tonic-gate 	j = 0;
3520Sstevel@tonic-gate 	while (cnt > 0) {
3530Sstevel@tonic-gate 		cnt--;
354*13093SRoger.Faulkner@Oracle.COM 		getaline(tp[cnt]);
3550Sstevel@tonic-gate 		j += vdepth();
3560Sstevel@tonic-gate 	}
3570Sstevel@tonic-gate 	if (tp > dot)
3580Sstevel@tonic-gate 		j -= WBOT - LASTLINE;
3590Sstevel@tonic-gate 	return (j);
3600Sstevel@tonic-gate }
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate /*
3630Sstevel@tonic-gate  * Roll cnt lines onto the screen.
3640Sstevel@tonic-gate  */
365802Scf46844 void
vroll(int cnt)366802Scf46844 vroll(int cnt)
3670Sstevel@tonic-gate {
3680Sstevel@tonic-gate #ifndef CBREAK
369802Scf46844 	bool fried = 0;
3700Sstevel@tonic-gate #endif
3710Sstevel@tonic-gate 	short oldhold = hold;
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate #ifdef ADEBUG
3740Sstevel@tonic-gate 	if (trace)
3750Sstevel@tonic-gate 		tfixnl(), fprintf(trace, "vroll(%d)\n", cnt);
3760Sstevel@tonic-gate #endif
3770Sstevel@tonic-gate 	if (state != VISUAL)
3780Sstevel@tonic-gate 		hold |= HOLDAT|HOLDROL;
3790Sstevel@tonic-gate 	if (WBOT == WECHO) {
3800Sstevel@tonic-gate 		vcnt = 0;
3810Sstevel@tonic-gate 		if (state == ONEOPEN)
3820Sstevel@tonic-gate 			vup1();
3830Sstevel@tonic-gate 	}
3840Sstevel@tonic-gate #ifndef CBREAK
3850Sstevel@tonic-gate 	if (vcookit(cnt))
3860Sstevel@tonic-gate 		fried++, vcook();
3870Sstevel@tonic-gate #endif
3880Sstevel@tonic-gate 	for (; cnt > 0 && Peekkey != ATTN; cnt--) {
3890Sstevel@tonic-gate 		dot++, vcline++;
3900Sstevel@tonic-gate 		vopen(dot, LASTLINE);
3910Sstevel@tonic-gate 		vscrap();
3920Sstevel@tonic-gate 	}
3930Sstevel@tonic-gate 	hold = oldhold;
3940Sstevel@tonic-gate 	if (state == HARDOPEN)
3950Sstevel@tonic-gate 		sethard();
3960Sstevel@tonic-gate 	vsyncCL();
3970Sstevel@tonic-gate #ifndef CBREAK
3980Sstevel@tonic-gate 	if (fried)
3990Sstevel@tonic-gate 		flusho(), vraw();
4000Sstevel@tonic-gate #endif
4010Sstevel@tonic-gate }
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate /*
4040Sstevel@tonic-gate  * Roll backwards (scroll up).
4050Sstevel@tonic-gate  */
406802Scf46844 void
vrollR(int cnt)407802Scf46844 vrollR(int cnt)
4080Sstevel@tonic-gate {
409802Scf46844 	bool fried = 0;
4100Sstevel@tonic-gate 	short oldhold = hold;
4110Sstevel@tonic-gate 
4120Sstevel@tonic-gate #ifdef ADEBUG
4130Sstevel@tonic-gate 	if (trace)
4140Sstevel@tonic-gate 		tfixnl(), fprintf(trace, "vrollR(%d), dot=%d\n", cnt, lineDOT());
4150Sstevel@tonic-gate #endif
4160Sstevel@tonic-gate #ifndef CBREAK
4170Sstevel@tonic-gate 	if (vcookit(cnt))
4180Sstevel@tonic-gate 		fried++, vcook();
4190Sstevel@tonic-gate #endif
4200Sstevel@tonic-gate 	if (WBOT == WECHO)
4210Sstevel@tonic-gate 		vcnt = 0;
4220Sstevel@tonic-gate 	heldech = 0;
4230Sstevel@tonic-gate 	hold |= HOLDAT|HOLDECH;
4240Sstevel@tonic-gate 	for (; cnt > 0 && Peekkey != ATTN; cnt--) {
4250Sstevel@tonic-gate 		dot--;
4260Sstevel@tonic-gate 		vopen(dot, WTOP);
4270Sstevel@tonic-gate 		vscrap();
4280Sstevel@tonic-gate 	}
4290Sstevel@tonic-gate 	hold = oldhold;
4300Sstevel@tonic-gate 	if (heldech)
4310Sstevel@tonic-gate 		vclrech(0);
4320Sstevel@tonic-gate 	vsync(LINE(vcnt-1));
4330Sstevel@tonic-gate #ifndef CBREAK
4340Sstevel@tonic-gate 	if (fried)
4350Sstevel@tonic-gate 		flusho(), vraw();
4360Sstevel@tonic-gate #endif
4370Sstevel@tonic-gate }
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate /*
4400Sstevel@tonic-gate  * Go into cooked mode (allow interrupts) during
4410Sstevel@tonic-gate  * a scroll if we are at less than 1200 baud and not
4420Sstevel@tonic-gate  * a 'vi' command, of if we are in a 'vi' command and the
4430Sstevel@tonic-gate  * scroll is more than 2 full screens.
4440Sstevel@tonic-gate  *
4450Sstevel@tonic-gate  * BUG:		An interrupt during a scroll in this way
4460Sstevel@tonic-gate  *		dumps to command mode.
4470Sstevel@tonic-gate  */
448802Scf46844 int
vcookit(int cnt)449802Scf46844 vcookit(int cnt)
4500Sstevel@tonic-gate {
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate 	return (cnt > 1 && (ospeed < B1200 && !initev || cnt > lines * 2));
4530Sstevel@tonic-gate }
4540Sstevel@tonic-gate 
4550Sstevel@tonic-gate /*
4560Sstevel@tonic-gate  * Determine displayed depth of current line.
4570Sstevel@tonic-gate  */
458802Scf46844 int
vdepth(void)459802Scf46844 vdepth(void)
4600Sstevel@tonic-gate {
461802Scf46844 	int d;
4620Sstevel@tonic-gate 
4630Sstevel@tonic-gate 	d = (column(NOSTR) + WCOLS - 1 + (Putchar == listchar) + insert_null_glitch) / WCOLS;
4640Sstevel@tonic-gate #ifdef ADEBUG
4650Sstevel@tonic-gate 	if (trace)
4660Sstevel@tonic-gate 		tfixnl(), fprintf(trace, "vdepth returns %d\n", d == 0 ? 1 : d);
4670Sstevel@tonic-gate #endif
4680Sstevel@tonic-gate 	return (d == 0 ? 1 : d);
4690Sstevel@tonic-gate }
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate /*
4720Sstevel@tonic-gate  * Move onto a new line, with cursor at position curs.
4730Sstevel@tonic-gate  */
474802Scf46844 void
vnline(unsigned char * curs)475802Scf46844 vnline(unsigned char *curs)
4760Sstevel@tonic-gate {
4770Sstevel@tonic-gate 	unsigned char *owcursor;
4780Sstevel@tonic-gate 	int j;
4790Sstevel@tonic-gate 	if (curs) {
4800Sstevel@tonic-gate 		if(curs >= strend(linebuf)) {
4810Sstevel@tonic-gate 			if(!*linebuf)
4820Sstevel@tonic-gate 				wcursor = linebuf;
4830Sstevel@tonic-gate 			else {
4840Sstevel@tonic-gate 				wcursor = strend(linebuf);
4850Sstevel@tonic-gate 				wcursor = lastchr(linebuf, wcursor);
4860Sstevel@tonic-gate 			}
4870Sstevel@tonic-gate 		} else {
4880Sstevel@tonic-gate 			owcursor = wcursor = curs;
4890Sstevel@tonic-gate 			j = wcursor - linebuf;
4900Sstevel@tonic-gate 			for(wcursor = linebuf; wcursor - linebuf < j; ) {
4910Sstevel@tonic-gate 				owcursor = wcursor;
4920Sstevel@tonic-gate 				wcursor = nextchr(wcursor);
4930Sstevel@tonic-gate 			}
4940Sstevel@tonic-gate 			if(wcursor - linebuf > j)
4950Sstevel@tonic-gate 				wcursor = owcursor;
4960Sstevel@tonic-gate 		}
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate 	} else if (vmoving)
4990Sstevel@tonic-gate 		wcursor = vfindcol(vmovcol);
5000Sstevel@tonic-gate 	else
5010Sstevel@tonic-gate 		wcursor = vskipwh(linebuf);
5020Sstevel@tonic-gate 	cursor = linebuf;
503802Scf46844 	(void) vmove();
5040Sstevel@tonic-gate }
505