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
5*23a1cceaSRoger A. Faulkner * Common Development and Distribution License (the "License").
6*23a1cceaSRoger A. Faulkner * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21*23a1cceaSRoger A. Faulkner
22f6db9f27Scf46844 /*
23*23a1cceaSRoger A. Faulkner * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24f6db9f27Scf46844 */
25f6db9f27Scf46844
267c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
277c478bd9Sstevel@tonic-gate /* All Rights Reserved */
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate /* Copyright (c) 1981 Regents of the University of California */
31f6db9f27Scf46844
327c478bd9Sstevel@tonic-gate #include "ex.h"
337c478bd9Sstevel@tonic-gate #include "ex_tty.h"
347c478bd9Sstevel@tonic-gate #include "ex_vis.h"
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate /*
377c478bd9Sstevel@tonic-gate * Routines to adjust the window, showing specified lines
387c478bd9Sstevel@tonic-gate * in certain positions on the screen, and scrolling in both
397c478bd9Sstevel@tonic-gate * directions. Code here is very dependent on mode (open versus visual).
407c478bd9Sstevel@tonic-gate */
417c478bd9Sstevel@tonic-gate
427c478bd9Sstevel@tonic-gate /*
437c478bd9Sstevel@tonic-gate * Move in a nonlocal way to line addr.
447c478bd9Sstevel@tonic-gate * If it isn't on screen put it in specified context.
457c478bd9Sstevel@tonic-gate * New position for cursor is curs.
467c478bd9Sstevel@tonic-gate * Like most routines here, we vsave().
477c478bd9Sstevel@tonic-gate */
48f6db9f27Scf46844 void
vmoveto(addr,curs,context)497c478bd9Sstevel@tonic-gate vmoveto(addr, curs, context)
50f6db9f27Scf46844 line *addr;
517c478bd9Sstevel@tonic-gate unsigned char *curs;
527c478bd9Sstevel@tonic-gate unsigned char context;
537c478bd9Sstevel@tonic-gate {
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate markit(addr);
567c478bd9Sstevel@tonic-gate vsave();
577c478bd9Sstevel@tonic-gate vjumpto(addr, curs, context);
587c478bd9Sstevel@tonic-gate }
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate /*
617c478bd9Sstevel@tonic-gate * Vjumpto is like vmoveto, but doesn't mark previous
627c478bd9Sstevel@tonic-gate * context or save linebuf as current line.
637c478bd9Sstevel@tonic-gate */
64f6db9f27Scf46844 void
vjumpto(line * addr,unsigned char * curs,unsigned char context)65f6db9f27Scf46844 vjumpto(line *addr, unsigned char *curs, unsigned char context)
667c478bd9Sstevel@tonic-gate {
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate noteit(0);
697c478bd9Sstevel@tonic-gate if (context != 0)
707c478bd9Sstevel@tonic-gate vcontext(addr, context);
717c478bd9Sstevel@tonic-gate else
727c478bd9Sstevel@tonic-gate vshow(addr, NOLINE);
737c478bd9Sstevel@tonic-gate noteit(1);
747c478bd9Sstevel@tonic-gate vnline(curs);
757c478bd9Sstevel@tonic-gate }
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate * Go up or down cnt (negative is up) to new position curs.
797c478bd9Sstevel@tonic-gate */
80f6db9f27Scf46844 void
vupdown(int cnt,unsigned char * curs)81f6db9f27Scf46844 vupdown(int cnt, unsigned char *curs)
827c478bd9Sstevel@tonic-gate {
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate if (cnt > 0)
857c478bd9Sstevel@tonic-gate vdown(cnt, 0, 0);
867c478bd9Sstevel@tonic-gate else if (cnt < 0)
877c478bd9Sstevel@tonic-gate vup(-cnt, 0, 0);
887c478bd9Sstevel@tonic-gate if (vcnt == 0)
897c478bd9Sstevel@tonic-gate vrepaint(curs);
907c478bd9Sstevel@tonic-gate else
917c478bd9Sstevel@tonic-gate vnline(curs);
927c478bd9Sstevel@tonic-gate }
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate /*
957c478bd9Sstevel@tonic-gate * Go up cnt lines, afterwards preferring to be ind
967c478bd9Sstevel@tonic-gate * logical lines from the top of the screen.
977c478bd9Sstevel@tonic-gate * If scroll, then we MUST use a scroll.
987c478bd9Sstevel@tonic-gate * Otherwise clear and redraw if motion is far.
997c478bd9Sstevel@tonic-gate */
100f6db9f27Scf46844 void
vup(int cnt,int ind,bool scroll)101f6db9f27Scf46844 vup(int cnt, int ind, bool scroll)
1027c478bd9Sstevel@tonic-gate {
103f6db9f27Scf46844 int i, tot;
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate if (dot == one) {
106f6db9f27Scf46844 (void) beep();
1077c478bd9Sstevel@tonic-gate return;
1087c478bd9Sstevel@tonic-gate }
1097c478bd9Sstevel@tonic-gate vsave();
1107c478bd9Sstevel@tonic-gate i = lineDOT() - 1;
1117c478bd9Sstevel@tonic-gate if (cnt > i) {
1127c478bd9Sstevel@tonic-gate ind -= cnt - i;
1137c478bd9Sstevel@tonic-gate if (ind < 0)
1147c478bd9Sstevel@tonic-gate ind = 0;
1157c478bd9Sstevel@tonic-gate cnt = i;
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate if (!scroll && cnt <= vcline) {
1187c478bd9Sstevel@tonic-gate vshow(dot - cnt, NOLINE);
1197c478bd9Sstevel@tonic-gate return;
1207c478bd9Sstevel@tonic-gate }
1217c478bd9Sstevel@tonic-gate cnt -= vcline, dot -= vcline, vcline = 0;
1227c478bd9Sstevel@tonic-gate if (hold & HOLDWIG)
1237c478bd9Sstevel@tonic-gate goto contxt;
1247c478bd9Sstevel@tonic-gate if (state == VISUAL && !insert_line && !scroll_reverse &&
1257c478bd9Sstevel@tonic-gate cnt <= WTOP - ZERO && vfit(dot - cnt, cnt) <= WTOP - ZERO)
1267c478bd9Sstevel@tonic-gate goto okr;
1277c478bd9Sstevel@tonic-gate tot = WECHO - WTOP;
1287c478bd9Sstevel@tonic-gate if (state != VISUAL || (!insert_line && !scroll_reverse) || (!scroll && (cnt > tot || vfit(dot - cnt, cnt) > tot / 3 + 1))) {
1297c478bd9Sstevel@tonic-gate if (ind > basWLINES / 2)
1307c478bd9Sstevel@tonic-gate ind = basWLINES / 3;
1317c478bd9Sstevel@tonic-gate contxt:
1327c478bd9Sstevel@tonic-gate vcontext(dot + ind - cnt, '.');
1337c478bd9Sstevel@tonic-gate return;
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate okr:
1367c478bd9Sstevel@tonic-gate vrollR(cnt);
1377c478bd9Sstevel@tonic-gate if (scroll) {
1387c478bd9Sstevel@tonic-gate vcline += ind, dot += ind;
1397c478bd9Sstevel@tonic-gate if (vcline >= vcnt)
1407c478bd9Sstevel@tonic-gate dot -= vcline - vcnt + 1, vcline = vcnt - 1;
1417c478bd9Sstevel@tonic-gate getDOT();
1427c478bd9Sstevel@tonic-gate }
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate
1457c478bd9Sstevel@tonic-gate /*
1467c478bd9Sstevel@tonic-gate * Like vup, but scrolling down.
1477c478bd9Sstevel@tonic-gate */
148f6db9f27Scf46844 void
vdown(int cnt,int ind,bool scroll)149f6db9f27Scf46844 vdown(int cnt, int ind, bool scroll)
1507c478bd9Sstevel@tonic-gate {
151f6db9f27Scf46844 int i, tot;
1527c478bd9Sstevel@tonic-gate
1537c478bd9Sstevel@tonic-gate if (dot == dol) {
154f6db9f27Scf46844 (void) beep();
1557c478bd9Sstevel@tonic-gate return;
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate vsave();
1587c478bd9Sstevel@tonic-gate i = dol - dot;
1597c478bd9Sstevel@tonic-gate if (cnt > i) {
1607c478bd9Sstevel@tonic-gate ind -= cnt - i;
1617c478bd9Sstevel@tonic-gate if (ind < 0)
1627c478bd9Sstevel@tonic-gate ind = 0;
1637c478bd9Sstevel@tonic-gate cnt = i;
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate i = vcnt - vcline - 1;
1667c478bd9Sstevel@tonic-gate if (!scroll && cnt <= i) {
1677c478bd9Sstevel@tonic-gate vshow(dot + cnt, NOLINE);
1687c478bd9Sstevel@tonic-gate return;
1697c478bd9Sstevel@tonic-gate }
1707c478bd9Sstevel@tonic-gate cnt -= i, dot += i, vcline += i;
1717c478bd9Sstevel@tonic-gate if (hold & HOLDWIG)
1727c478bd9Sstevel@tonic-gate goto dcontxt;
1737c478bd9Sstevel@tonic-gate if (!scroll) {
1747c478bd9Sstevel@tonic-gate tot = WECHO - WTOP;
1757c478bd9Sstevel@tonic-gate if (state != VISUAL || cnt - tot > 0 || vfit(dot, cnt) > tot / 3 + 1) {
1767c478bd9Sstevel@tonic-gate dcontxt:
1777c478bd9Sstevel@tonic-gate vcontext(dot + cnt, '.');
1787c478bd9Sstevel@tonic-gate return;
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate if (cnt > 0)
1827c478bd9Sstevel@tonic-gate vroll(cnt);
1837c478bd9Sstevel@tonic-gate if (state == VISUAL && scroll) {
1847c478bd9Sstevel@tonic-gate vcline -= ind, dot -= ind;
1857c478bd9Sstevel@tonic-gate if (vcline < 0)
1867c478bd9Sstevel@tonic-gate dot -= vcline, vcline = 0;
1877c478bd9Sstevel@tonic-gate getDOT();
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate }
1907c478bd9Sstevel@tonic-gate
1917c478bd9Sstevel@tonic-gate /*
1927c478bd9Sstevel@tonic-gate * Show line addr in context where on the screen.
1937c478bd9Sstevel@tonic-gate * Work here is in determining new top line implied by
1947c478bd9Sstevel@tonic-gate * this placement of line addr, since we always draw from the top.
1957c478bd9Sstevel@tonic-gate */
196f6db9f27Scf46844 void
vcontext(line * addr,unsigned char where)197f6db9f27Scf46844 vcontext(line *addr, unsigned char where)
1987c478bd9Sstevel@tonic-gate {
199f6db9f27Scf46844 line *top;
2007c478bd9Sstevel@tonic-gate
201*23a1cceaSRoger A. Faulkner getaline(*addr);
2027c478bd9Sstevel@tonic-gate if (state != VISUAL)
2037c478bd9Sstevel@tonic-gate top = addr;
2047c478bd9Sstevel@tonic-gate else switch (where) {
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate case '^':
2077c478bd9Sstevel@tonic-gate addr = vback(addr, basWLINES - vdepth());
208*23a1cceaSRoger A. Faulkner getaline(*addr);
2097c478bd9Sstevel@tonic-gate /* fall into ... */
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate case '-':
2127c478bd9Sstevel@tonic-gate top = vback(addr, basWLINES - vdepth());
213*23a1cceaSRoger A. Faulkner getaline(*addr);
2147c478bd9Sstevel@tonic-gate break;
2157c478bd9Sstevel@tonic-gate
2167c478bd9Sstevel@tonic-gate case '.':
2177c478bd9Sstevel@tonic-gate top = vback(addr, basWLINES / 2 - vdepth());
218*23a1cceaSRoger A. Faulkner getaline(*addr);
2197c478bd9Sstevel@tonic-gate break;
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate default:
2227c478bd9Sstevel@tonic-gate top = addr;
2237c478bd9Sstevel@tonic-gate break;
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate if (state == ONEOPEN && LINE(0) == WBOT)
2267c478bd9Sstevel@tonic-gate vup1();
2277c478bd9Sstevel@tonic-gate vcnt = vcline = 0;
2287c478bd9Sstevel@tonic-gate vclean();
2297c478bd9Sstevel@tonic-gate if (state == CRTOPEN)
2307c478bd9Sstevel@tonic-gate vup1();
2317c478bd9Sstevel@tonic-gate vshow(addr, top);
2327c478bd9Sstevel@tonic-gate }
2337c478bd9Sstevel@tonic-gate
2347c478bd9Sstevel@tonic-gate /*
2357c478bd9Sstevel@tonic-gate * Get a clean line. If we are in a hard open
2367c478bd9Sstevel@tonic-gate * we may be able to reuse the line we are on
2377c478bd9Sstevel@tonic-gate * if it is blank. This is a real win.
2387c478bd9Sstevel@tonic-gate */
239f6db9f27Scf46844 void
vclean(void)240f6db9f27Scf46844 vclean(void)
2417c478bd9Sstevel@tonic-gate {
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate if (state != VISUAL && state != CRTOPEN) {
2447c478bd9Sstevel@tonic-gate destcol = 0;
2457c478bd9Sstevel@tonic-gate if (!ateopr())
2467c478bd9Sstevel@tonic-gate vup1();
2477c478bd9Sstevel@tonic-gate vcnt = 0;
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate /*
2527c478bd9Sstevel@tonic-gate * Show line addr with the specified top line on the screen.
2537c478bd9Sstevel@tonic-gate * Top may be 0; in this case have vcontext compute the top
2547c478bd9Sstevel@tonic-gate * (and call us recursively). Eventually, we clear the screen
2557c478bd9Sstevel@tonic-gate * (or its open mode equivalent) and redraw.
2567c478bd9Sstevel@tonic-gate */
257f6db9f27Scf46844 void
vshow(line * addr,line * top)258f6db9f27Scf46844 vshow(line *addr, line *top)
2597c478bd9Sstevel@tonic-gate {
2607c478bd9Sstevel@tonic-gate #ifndef CBREAK
261f6db9f27Scf46844 bool fried = 0;
2627c478bd9Sstevel@tonic-gate #endif
263f6db9f27Scf46844 int cnt = addr - dot;
264f6db9f27Scf46844 int i = vcline + cnt;
2657c478bd9Sstevel@tonic-gate short oldhold = hold;
2667c478bd9Sstevel@tonic-gate
2677c478bd9Sstevel@tonic-gate if (state != HARDOPEN && state != ONEOPEN && i >= 0 && i < vcnt) {
2687c478bd9Sstevel@tonic-gate dot = addr;
2697c478bd9Sstevel@tonic-gate getDOT();
2707c478bd9Sstevel@tonic-gate vcline = i;
2717c478bd9Sstevel@tonic-gate return;
2727c478bd9Sstevel@tonic-gate }
2737c478bd9Sstevel@tonic-gate if (state != VISUAL) {
2747c478bd9Sstevel@tonic-gate dot = addr;
2757c478bd9Sstevel@tonic-gate vopen(dot, WBOT);
2767c478bd9Sstevel@tonic-gate return;
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate if (top == 0) {
2797c478bd9Sstevel@tonic-gate vcontext(addr, '.');
2807c478bd9Sstevel@tonic-gate return;
2817c478bd9Sstevel@tonic-gate }
2827c478bd9Sstevel@tonic-gate dot = top;
2837c478bd9Sstevel@tonic-gate #ifndef CBREAK
2847c478bd9Sstevel@tonic-gate if (vcookit(2))
2857c478bd9Sstevel@tonic-gate fried++, vcook();
2867c478bd9Sstevel@tonic-gate #endif
2877c478bd9Sstevel@tonic-gate oldhold = hold;
2887c478bd9Sstevel@tonic-gate hold |= HOLDAT;
2897c478bd9Sstevel@tonic-gate vclear();
2907c478bd9Sstevel@tonic-gate vreset(0);
2917c478bd9Sstevel@tonic-gate vredraw(WTOP);
2927c478bd9Sstevel@tonic-gate /* error if vcline >= vcnt ! */
2937c478bd9Sstevel@tonic-gate vcline = addr - top;
2947c478bd9Sstevel@tonic-gate dot = addr;
2957c478bd9Sstevel@tonic-gate getDOT();
2967c478bd9Sstevel@tonic-gate hold = oldhold;
2977c478bd9Sstevel@tonic-gate vsync(LASTLINE);
2987c478bd9Sstevel@tonic-gate #ifndef CBREAK
2997c478bd9Sstevel@tonic-gate if (fried)
3007c478bd9Sstevel@tonic-gate flusho(), vraw();
3017c478bd9Sstevel@tonic-gate #endif
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate /*
3057c478bd9Sstevel@tonic-gate * reset the state.
3067c478bd9Sstevel@tonic-gate * If inecho then leave us at the beginning of the echo
3077c478bd9Sstevel@tonic-gate * area; we are called this way in the middle of a :e escape
3087c478bd9Sstevel@tonic-gate * from visual, e.g.
3097c478bd9Sstevel@tonic-gate */
310f6db9f27Scf46844 void
vreset(bool inecho)311f6db9f27Scf46844 vreset(bool inecho)
3127c478bd9Sstevel@tonic-gate {
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate vcnt = vcline = 0;
3157c478bd9Sstevel@tonic-gate WTOP = basWTOP;
3167c478bd9Sstevel@tonic-gate WLINES = basWLINES;
3177c478bd9Sstevel@tonic-gate if (inecho)
3187c478bd9Sstevel@tonic-gate splitw = 1, vgoto(WECHO, 0);
3197c478bd9Sstevel@tonic-gate }
3207c478bd9Sstevel@tonic-gate
3217c478bd9Sstevel@tonic-gate /*
3227c478bd9Sstevel@tonic-gate * Starting from which line preceding tp uses almost (but not more
3237c478bd9Sstevel@tonic-gate * than) cnt physical lines?
3247c478bd9Sstevel@tonic-gate */
3257c478bd9Sstevel@tonic-gate line *
vback(tp,cnt)3267c478bd9Sstevel@tonic-gate vback(tp, cnt)
327f6db9f27Scf46844 int cnt;
328f6db9f27Scf46844 line *tp;
3297c478bd9Sstevel@tonic-gate {
330f6db9f27Scf46844 int d;
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate if (cnt > 0)
3337c478bd9Sstevel@tonic-gate for (; tp > one; tp--) {
334*23a1cceaSRoger A. Faulkner getaline(tp[-1]);
3357c478bd9Sstevel@tonic-gate d = vdepth();
3367c478bd9Sstevel@tonic-gate if (d > cnt)
3377c478bd9Sstevel@tonic-gate break;
3387c478bd9Sstevel@tonic-gate cnt -= d;
3397c478bd9Sstevel@tonic-gate }
3407c478bd9Sstevel@tonic-gate return (tp);
3417c478bd9Sstevel@tonic-gate }
3427c478bd9Sstevel@tonic-gate
3437c478bd9Sstevel@tonic-gate /*
3447c478bd9Sstevel@tonic-gate * How much scrolling will it take to roll cnt lines starting at tp?
3457c478bd9Sstevel@tonic-gate */
346f6db9f27Scf46844 int
vfit(line * tp,int cnt)347f6db9f27Scf46844 vfit(line *tp, int cnt)
3487c478bd9Sstevel@tonic-gate {
349f6db9f27Scf46844 int j;
3507c478bd9Sstevel@tonic-gate
3517c478bd9Sstevel@tonic-gate j = 0;
3527c478bd9Sstevel@tonic-gate while (cnt > 0) {
3537c478bd9Sstevel@tonic-gate cnt--;
354*23a1cceaSRoger A. Faulkner getaline(tp[cnt]);
3557c478bd9Sstevel@tonic-gate j += vdepth();
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate if (tp > dot)
3587c478bd9Sstevel@tonic-gate j -= WBOT - LASTLINE;
3597c478bd9Sstevel@tonic-gate return (j);
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate
3627c478bd9Sstevel@tonic-gate /*
3637c478bd9Sstevel@tonic-gate * Roll cnt lines onto the screen.
3647c478bd9Sstevel@tonic-gate */
365f6db9f27Scf46844 void
vroll(int cnt)366f6db9f27Scf46844 vroll(int cnt)
3677c478bd9Sstevel@tonic-gate {
3687c478bd9Sstevel@tonic-gate #ifndef CBREAK
369f6db9f27Scf46844 bool fried = 0;
3707c478bd9Sstevel@tonic-gate #endif
3717c478bd9Sstevel@tonic-gate short oldhold = hold;
3727c478bd9Sstevel@tonic-gate
3737c478bd9Sstevel@tonic-gate #ifdef ADEBUG
3747c478bd9Sstevel@tonic-gate if (trace)
3757c478bd9Sstevel@tonic-gate tfixnl(), fprintf(trace, "vroll(%d)\n", cnt);
3767c478bd9Sstevel@tonic-gate #endif
3777c478bd9Sstevel@tonic-gate if (state != VISUAL)
3787c478bd9Sstevel@tonic-gate hold |= HOLDAT|HOLDROL;
3797c478bd9Sstevel@tonic-gate if (WBOT == WECHO) {
3807c478bd9Sstevel@tonic-gate vcnt = 0;
3817c478bd9Sstevel@tonic-gate if (state == ONEOPEN)
3827c478bd9Sstevel@tonic-gate vup1();
3837c478bd9Sstevel@tonic-gate }
3847c478bd9Sstevel@tonic-gate #ifndef CBREAK
3857c478bd9Sstevel@tonic-gate if (vcookit(cnt))
3867c478bd9Sstevel@tonic-gate fried++, vcook();
3877c478bd9Sstevel@tonic-gate #endif
3887c478bd9Sstevel@tonic-gate for (; cnt > 0 && Peekkey != ATTN; cnt--) {
3897c478bd9Sstevel@tonic-gate dot++, vcline++;
3907c478bd9Sstevel@tonic-gate vopen(dot, LASTLINE);
3917c478bd9Sstevel@tonic-gate vscrap();
3927c478bd9Sstevel@tonic-gate }
3937c478bd9Sstevel@tonic-gate hold = oldhold;
3947c478bd9Sstevel@tonic-gate if (state == HARDOPEN)
3957c478bd9Sstevel@tonic-gate sethard();
3967c478bd9Sstevel@tonic-gate vsyncCL();
3977c478bd9Sstevel@tonic-gate #ifndef CBREAK
3987c478bd9Sstevel@tonic-gate if (fried)
3997c478bd9Sstevel@tonic-gate flusho(), vraw();
4007c478bd9Sstevel@tonic-gate #endif
4017c478bd9Sstevel@tonic-gate }
4027c478bd9Sstevel@tonic-gate
4037c478bd9Sstevel@tonic-gate /*
4047c478bd9Sstevel@tonic-gate * Roll backwards (scroll up).
4057c478bd9Sstevel@tonic-gate */
406f6db9f27Scf46844 void
vrollR(int cnt)407f6db9f27Scf46844 vrollR(int cnt)
4087c478bd9Sstevel@tonic-gate {
409f6db9f27Scf46844 bool fried = 0;
4107c478bd9Sstevel@tonic-gate short oldhold = hold;
4117c478bd9Sstevel@tonic-gate
4127c478bd9Sstevel@tonic-gate #ifdef ADEBUG
4137c478bd9Sstevel@tonic-gate if (trace)
4147c478bd9Sstevel@tonic-gate tfixnl(), fprintf(trace, "vrollR(%d), dot=%d\n", cnt, lineDOT());
4157c478bd9Sstevel@tonic-gate #endif
4167c478bd9Sstevel@tonic-gate #ifndef CBREAK
4177c478bd9Sstevel@tonic-gate if (vcookit(cnt))
4187c478bd9Sstevel@tonic-gate fried++, vcook();
4197c478bd9Sstevel@tonic-gate #endif
4207c478bd9Sstevel@tonic-gate if (WBOT == WECHO)
4217c478bd9Sstevel@tonic-gate vcnt = 0;
4227c478bd9Sstevel@tonic-gate heldech = 0;
4237c478bd9Sstevel@tonic-gate hold |= HOLDAT|HOLDECH;
4247c478bd9Sstevel@tonic-gate for (; cnt > 0 && Peekkey != ATTN; cnt--) {
4257c478bd9Sstevel@tonic-gate dot--;
4267c478bd9Sstevel@tonic-gate vopen(dot, WTOP);
4277c478bd9Sstevel@tonic-gate vscrap();
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate hold = oldhold;
4307c478bd9Sstevel@tonic-gate if (heldech)
4317c478bd9Sstevel@tonic-gate vclrech(0);
4327c478bd9Sstevel@tonic-gate vsync(LINE(vcnt-1));
4337c478bd9Sstevel@tonic-gate #ifndef CBREAK
4347c478bd9Sstevel@tonic-gate if (fried)
4357c478bd9Sstevel@tonic-gate flusho(), vraw();
4367c478bd9Sstevel@tonic-gate #endif
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate
4397c478bd9Sstevel@tonic-gate /*
4407c478bd9Sstevel@tonic-gate * Go into cooked mode (allow interrupts) during
4417c478bd9Sstevel@tonic-gate * a scroll if we are at less than 1200 baud and not
4427c478bd9Sstevel@tonic-gate * a 'vi' command, of if we are in a 'vi' command and the
4437c478bd9Sstevel@tonic-gate * scroll is more than 2 full screens.
4447c478bd9Sstevel@tonic-gate *
4457c478bd9Sstevel@tonic-gate * BUG: An interrupt during a scroll in this way
4467c478bd9Sstevel@tonic-gate * dumps to command mode.
4477c478bd9Sstevel@tonic-gate */
448f6db9f27Scf46844 int
vcookit(int cnt)449f6db9f27Scf46844 vcookit(int cnt)
4507c478bd9Sstevel@tonic-gate {
4517c478bd9Sstevel@tonic-gate
4527c478bd9Sstevel@tonic-gate return (cnt > 1 && (ospeed < B1200 && !initev || cnt > lines * 2));
4537c478bd9Sstevel@tonic-gate }
4547c478bd9Sstevel@tonic-gate
4557c478bd9Sstevel@tonic-gate /*
4567c478bd9Sstevel@tonic-gate * Determine displayed depth of current line.
4577c478bd9Sstevel@tonic-gate */
458f6db9f27Scf46844 int
vdepth(void)459f6db9f27Scf46844 vdepth(void)
4607c478bd9Sstevel@tonic-gate {
461f6db9f27Scf46844 int d;
4627c478bd9Sstevel@tonic-gate
4637c478bd9Sstevel@tonic-gate d = (column(NOSTR) + WCOLS - 1 + (Putchar == listchar) + insert_null_glitch) / WCOLS;
4647c478bd9Sstevel@tonic-gate #ifdef ADEBUG
4657c478bd9Sstevel@tonic-gate if (trace)
4667c478bd9Sstevel@tonic-gate tfixnl(), fprintf(trace, "vdepth returns %d\n", d == 0 ? 1 : d);
4677c478bd9Sstevel@tonic-gate #endif
4687c478bd9Sstevel@tonic-gate return (d == 0 ? 1 : d);
4697c478bd9Sstevel@tonic-gate }
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate /*
4727c478bd9Sstevel@tonic-gate * Move onto a new line, with cursor at position curs.
4737c478bd9Sstevel@tonic-gate */
474f6db9f27Scf46844 void
vnline(unsigned char * curs)475f6db9f27Scf46844 vnline(unsigned char *curs)
4767c478bd9Sstevel@tonic-gate {
4777c478bd9Sstevel@tonic-gate unsigned char *owcursor;
4787c478bd9Sstevel@tonic-gate int j;
4797c478bd9Sstevel@tonic-gate if (curs) {
4807c478bd9Sstevel@tonic-gate if(curs >= strend(linebuf)) {
4817c478bd9Sstevel@tonic-gate if(!*linebuf)
4827c478bd9Sstevel@tonic-gate wcursor = linebuf;
4837c478bd9Sstevel@tonic-gate else {
4847c478bd9Sstevel@tonic-gate wcursor = strend(linebuf);
4857c478bd9Sstevel@tonic-gate wcursor = lastchr(linebuf, wcursor);
4867c478bd9Sstevel@tonic-gate }
4877c478bd9Sstevel@tonic-gate } else {
4887c478bd9Sstevel@tonic-gate owcursor = wcursor = curs;
4897c478bd9Sstevel@tonic-gate j = wcursor - linebuf;
4907c478bd9Sstevel@tonic-gate for(wcursor = linebuf; wcursor - linebuf < j; ) {
4917c478bd9Sstevel@tonic-gate owcursor = wcursor;
4927c478bd9Sstevel@tonic-gate wcursor = nextchr(wcursor);
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate if(wcursor - linebuf > j)
4957c478bd9Sstevel@tonic-gate wcursor = owcursor;
4967c478bd9Sstevel@tonic-gate }
4977c478bd9Sstevel@tonic-gate
4987c478bd9Sstevel@tonic-gate } else if (vmoving)
4997c478bd9Sstevel@tonic-gate wcursor = vfindcol(vmovcol);
5007c478bd9Sstevel@tonic-gate else
5017c478bd9Sstevel@tonic-gate wcursor = vskipwh(linebuf);
5027c478bd9Sstevel@tonic-gate cursor = linebuf;
503f6db9f27Scf46844 (void) vmove();
5047c478bd9Sstevel@tonic-gate }
505