4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 /* Copyright (c) 1981 Regents of the University of California */
37 * Routines to adjust the window, showing specified lines
38 * in certain positions on the screen, and scrolling in both
39 * directions. Code here is very dependent on mode (open versus visual).
43 * Move in a nonlocal way to line addr.
44 * If it isn't on screen put it in specified context.
45 * New position for cursor is curs.
46 * Like most routines here, we vsave().
49 vmoveto(addr
, curs
, context
)
52 unsigned char context
;
57 vjumpto(addr
, curs
, context
);
61 * Vjumpto is like vmoveto, but doesn't mark previous
62 * context or save linebuf as current line.
65 vjumpto(line
*addr
, unsigned char *curs
, unsigned char context
)
70 vcontext(addr
, context
);
78 * Go up or down cnt (negative is up) to new position curs.
81 vupdown(int cnt
, unsigned char *curs
)
95 * Go up cnt lines, afterwards preferring to be ind
96 * logical lines from the top of the screen.
97 * If scroll, then we MUST use a scroll.
98 * Otherwise clear and redraw if motion is far.
101 vup(int cnt
, int ind
, bool scroll
)
117 if (!scroll
&& cnt
<= vcline
) {
118 vshow(dot
- cnt
, NOLINE
);
121 cnt
-= vcline
, dot
-= vcline
, vcline
= 0;
124 if (state
== VISUAL
&& !insert_line
&& !scroll_reverse
&&
125 cnt
<= WTOP
- ZERO
&& vfit(dot
- cnt
, cnt
) <= WTOP
- ZERO
)
128 if (state
!= VISUAL
|| (!insert_line
&& !scroll_reverse
) || (!scroll
&& (cnt
> tot
|| vfit(dot
- cnt
, cnt
) > tot
/ 3 + 1))) {
129 if (ind
> basWLINES
/ 2)
132 vcontext(dot
+ ind
- cnt
, '.');
138 vcline
+= ind
, dot
+= ind
;
140 dot
-= vcline
- vcnt
+ 1, vcline
= vcnt
- 1;
146 * Like vup, but scrolling down.
149 vdown(int cnt
, int ind
, bool scroll
)
165 i
= vcnt
- vcline
- 1;
166 if (!scroll
&& cnt
<= i
) {
167 vshow(dot
+ cnt
, NOLINE
);
170 cnt
-= i
, dot
+= i
, vcline
+= i
;
175 if (state
!= VISUAL
|| cnt
- tot
> 0 || vfit(dot
, cnt
) > tot
/ 3 + 1) {
177 vcontext(dot
+ cnt
, '.');
183 if (state
== VISUAL
&& scroll
) {
184 vcline
-= ind
, dot
-= ind
;
186 dot
-= vcline
, vcline
= 0;
192 * Show line addr in context where on the screen.
193 * Work here is in determining new top line implied by
194 * this placement of line addr, since we always draw from the top.
197 vcontext(line
*addr
, unsigned char where
)
204 else switch (where
) {
207 addr
= vback(addr
, basWLINES
- vdepth());
212 top
= vback(addr
, basWLINES
- vdepth());
217 top
= vback(addr
, basWLINES
/ 2 - vdepth());
225 if (state
== ONEOPEN
&& LINE(0) == WBOT
)
229 if (state
== CRTOPEN
)
235 * Get a clean line. If we are in a hard open
236 * we may be able to reuse the line we are on
237 * if it is blank. This is a real win.
243 if (state
!= VISUAL
&& state
!= CRTOPEN
) {
252 * Show line addr with the specified top line on the screen.
253 * Top may be 0; in this case have vcontext compute the top
254 * (and call us recursively). Eventually, we clear the screen
255 * (or its open mode equivalent) and redraw.
258 vshow(line
*addr
, line
*top
)
263 int cnt
= addr
- dot
;
264 int i
= vcline
+ cnt
;
265 short oldhold
= hold
;
267 if (state
!= HARDOPEN
&& state
!= ONEOPEN
&& i
>= 0 && i
< vcnt
) {
273 if (state
!= VISUAL
) {
292 /* error if vcline >= vcnt ! */
306 * If inecho then leave us at the beginning of the echo
307 * area; we are called this way in the middle of a :e escape
318 splitw
= 1, vgoto(WECHO
, 0);
322 * Starting from which line preceding tp uses almost (but not more
323 * than) cnt physical lines?
333 for (; tp
> one
; tp
--) {
344 * How much scrolling will it take to roll cnt lines starting at tp?
347 vfit(line
*tp
, int cnt
)
358 j
-= WBOT
- LASTLINE
;
363 * Roll cnt lines onto the screen.
371 short oldhold
= hold
;
375 tfixnl(), fprintf(trace
, "vroll(%d)\n", cnt
);
378 hold
|= HOLDAT
|HOLDROL
;
381 if (state
== ONEOPEN
)
388 for (; cnt
> 0 && Peekkey
!= ATTN
; cnt
--) {
390 vopen(dot
, LASTLINE
);
394 if (state
== HARDOPEN
)
404 * Roll backwards (scroll up).
410 short oldhold
= hold
;
414 tfixnl(), fprintf(trace
, "vrollR(%d), dot=%d\n", cnt
, lineDOT());
423 hold
|= HOLDAT
|HOLDECH
;
424 for (; cnt
> 0 && Peekkey
!= ATTN
; cnt
--) {
440 * Go into cooked mode (allow interrupts) during
441 * a scroll if we are at less than 1200 baud and not
442 * a 'vi' command, of if we are in a 'vi' command and the
443 * scroll is more than 2 full screens.
445 * BUG: An interrupt during a scroll in this way
446 * dumps to command mode.
452 return (cnt
> 1 && (ospeed
< B1200
&& !initev
|| cnt
> lines
* 2));
456 * Determine displayed depth of current line.
463 d
= (column(NOSTR
) + WCOLS
- 1 + (Putchar
== listchar
) + insert_null_glitch
) / WCOLS
;
466 tfixnl(), fprintf(trace
, "vdepth returns %d\n", d
== 0 ? 1 : d
);
468 return (d
== 0 ? 1 : d
);
472 * Move onto a new line, with cursor at position curs.
475 vnline(unsigned char *curs
)
477 unsigned char *owcursor
;
480 if(curs
>= strend(linebuf
)) {
484 wcursor
= strend(linebuf
);
485 wcursor
= lastchr(linebuf
, wcursor
);
488 owcursor
= wcursor
= curs
;
489 j
= wcursor
- linebuf
;
490 for(wcursor
= linebuf
; wcursor
- linebuf
< j
; ) {
492 wcursor
= nextchr(wcursor
);
494 if(wcursor
- linebuf
> j
)
499 wcursor
= vfindcol(vmovcol
);
501 wcursor
= vskipwh(linebuf
);