Commit | Line | Data |
---|---|---|
60de5df9 | 1 | /* |
46e9ea25 KB |
2 | * Copyright (c) 1983 Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
3dd3a9e5 KB |
5 | * This code is derived from software contributed to Berkeley by |
6 | * Edward Wang at The University of California, Berkeley. | |
7 | * | |
87f529ec | 8 | * %sccs.include.redist.c% |
60de5df9 EW |
9 | */ |
10 | ||
46e9ea25 | 11 | #ifndef lint |
3dd3a9e5 | 12 | static char sccsid[] = "@(#)wwscroll.c 3.24 (Berkeley) %G%"; |
46e9ea25 KB |
13 | #endif /* not lint */ |
14 | ||
577dff1e | 15 | #include "ww.h" |
e908bfac | 16 | #include "tt.h" |
577dff1e | 17 | |
b0d4d9e2 EW |
18 | wwscroll(w, n) |
19 | register struct ww *w; | |
f2a77fe1 | 20 | int n; |
b0d4d9e2 | 21 | { |
f2a77fe1 EW |
22 | register dir; |
23 | register top; | |
b0d4d9e2 EW |
24 | |
25 | if (n == 0) | |
26 | return; | |
27 | dir = n < 0 ? -1 : 1; | |
f2a77fe1 EW |
28 | top = w->ww_b.t - n; |
29 | if (top > w->ww_w.t) | |
30 | top = w->ww_w.t; | |
31 | else if (top + w->ww_b.nr < w->ww_w.b) | |
32 | top = w->ww_w.b - w->ww_b.nr; | |
33 | n = abs(top - w->ww_b.t); | |
19f9784c | 34 | if (n < w->ww_i.nr) { |
b0d4d9e2 | 35 | while (--n >= 0) { |
f2a77fe1 EW |
36 | (void) wwscroll1(w, w->ww_i.t, w->ww_i.b, dir, 0); |
37 | w->ww_buf += dir; | |
38 | w->ww_b.t -= dir; | |
39 | w->ww_b.b -= dir; | |
b0d4d9e2 EW |
40 | } |
41 | } else { | |
f2a77fe1 EW |
42 | w->ww_buf -= top - w->ww_b.t; |
43 | w->ww_b.t = top; | |
44 | w->ww_b.b = top + w->ww_b.nr; | |
b0d4d9e2 EW |
45 | wwredrawwin(w); |
46 | } | |
47 | } | |
48 | ||
577dff1e | 49 | /* |
19f9784c | 50 | * Scroll one line, between 'row1' and 'row2', in direction 'dir'. |
577dff1e | 51 | * Don't adjust ww_scroll. |
b0d4d9e2 | 52 | * And don't redraw 'leaveit' lines. |
577dff1e | 53 | */ |
19f9784c | 54 | wwscroll1(w, row1, row2, dir, leaveit) |
577dff1e | 55 | register struct ww *w; |
19f9784c | 56 | int row1, row2, dir; |
b0d4d9e2 | 57 | int leaveit; |
577dff1e EW |
58 | { |
59 | register i; | |
19f9784c | 60 | int row1x, row2x; |
577dff1e EW |
61 | int nvis; |
62 | int nvismax; | |
16ea9636 | 63 | int scrolled = 0; |
577dff1e EW |
64 | |
65 | /* | |
66 | * See how many lines on the screen are affected. | |
19f9784c | 67 | * And calculate row1x, row2x, and left at the same time. |
577dff1e | 68 | */ |
19f9784c | 69 | for (i = row1; i < row2 && w->ww_nvis[i] == 0; i++) |
577dff1e | 70 | ; |
19f9784c | 71 | if (i >= row2) /* can't do any fancy stuff */ |
577dff1e | 72 | goto out; |
19f9784c EW |
73 | row1x = i; |
74 | for (i = row2 - 1; i >= row1 && w->ww_nvis[i] == 0; i--) | |
577dff1e | 75 | ; |
19f9784c | 76 | if (i <= row1x) |
577dff1e | 77 | goto out; /* just one line is easy */ |
19f9784c | 78 | row2x = i + 1; |
577dff1e EW |
79 | |
80 | /* | |
81 | * See how much of this window is visible. | |
82 | */ | |
19f9784c | 83 | nvismax = wwncol * (row2x - row1x); |
577dff1e | 84 | nvis = 0; |
19f9784c | 85 | for (i = row1x; i < row2x; i++) |
577dff1e EW |
86 | nvis += w->ww_nvis[i]; |
87 | ||
88 | /* | |
05fb5c3b | 89 | * If it's a good idea to scroll and the terminal can, then do it. |
577dff1e | 90 | */ |
16ea9636 EW |
91 | if (nvis < nvismax / 2) |
92 | goto no_scroll; /* not worth it */ | |
2d152f42 EW |
93 | if ((dir > 0 ? tt.tt_scroll_down == 0 : tt.tt_scroll_up == 0) || |
94 | (tt.tt_scroll_top != row1x || tt.tt_scroll_bot != row2x - 1) && | |
95 | tt.tt_setscroll == 0) | |
96 | if (tt.tt_delline == 0 || tt.tt_insline == 0) | |
97 | goto no_scroll; | |
98 | xxscroll(dir, row1x, row2x); | |
16ea9636 | 99 | scrolled = 1; |
05fb5c3b EW |
100 | /* |
101 | * Fix up the old screen. | |
102 | */ | |
16ea9636 | 103 | { |
05fb5c3b EW |
104 | register union ww_char *tmp; |
105 | register union ww_char **cpp, **cqq; | |
106 | ||
107 | if (dir > 0) { | |
f2a77fe1 | 108 | cpp = &wwos[row1x]; |
577dff1e EW |
109 | cqq = cpp + 1; |
110 | tmp = *cpp; | |
19f9784c | 111 | for (i = row2x - row1x; --i > 0;) |
577dff1e EW |
112 | *cpp++ = *cqq++; |
113 | *cpp = tmp; | |
577dff1e | 114 | } else { |
f2a77fe1 | 115 | cpp = &wwos[row2x]; |
19f9784c | 116 | cqq = cpp - 1; |
577dff1e | 117 | tmp = *cqq; |
19f9784c | 118 | for (i = row2x - row1x; --i > 0;) |
577dff1e EW |
119 | *--cpp = *--cqq; |
120 | *cqq = tmp; | |
577dff1e | 121 | } |
f2a77fe1 EW |
122 | for (i = wwncol; --i >= 0;) |
123 | tmp++->c_w = ' '; | |
577dff1e EW |
124 | } |
125 | ||
16ea9636 | 126 | no_scroll: |
577dff1e EW |
127 | /* |
128 | * Fix the new screen. | |
129 | */ | |
130 | if (nvis == nvismax) { | |
131 | /* | |
132 | * Can shift whole lines. | |
133 | */ | |
577dff1e | 134 | if (dir > 0) { |
861cd1ed EW |
135 | { |
136 | register union ww_char *tmp; | |
137 | register union ww_char **cpp, **cqq; | |
138 | ||
f2a77fe1 | 139 | cpp = &wwns[row1x]; |
861cd1ed EW |
140 | cqq = cpp + 1; |
141 | tmp = *cpp; | |
19f9784c | 142 | for (i = row2x - row1x; --i > 0;) |
861cd1ed EW |
143 | *cpp++ = *cqq++; |
144 | *cpp = tmp; | |
145 | } | |
16ea9636 | 146 | if (scrolled) { |
861cd1ed EW |
147 | register char *p, *q; |
148 | ||
f2a77fe1 | 149 | p = &wwtouched[row1x]; |
861cd1ed | 150 | q = p + 1; |
19f9784c | 151 | for (i = row2x - row1x; --i > 0;) |
861cd1ed | 152 | *p++ = *q++; |
04d70db4 | 153 | *p |= WWU_TOUCHED; |
26008571 EW |
154 | } else { |
155 | register char *p; | |
156 | ||
f2a77fe1 | 157 | p = &wwtouched[row1x]; |
19f9784c | 158 | for (i = row2x - row1x; --i >= 0;) |
6a1ef78a | 159 | *p++ |= WWU_TOUCHED; |
861cd1ed | 160 | } |
f2a77fe1 EW |
161 | wwredrawwin1(w, row1, row1x, dir); |
162 | wwredrawwin1(w, row2x - 1, row2 - leaveit, dir); | |
577dff1e | 163 | } else { |
861cd1ed EW |
164 | { |
165 | register union ww_char *tmp; | |
166 | register union ww_char **cpp, **cqq; | |
167 | ||
f2a77fe1 | 168 | cpp = &wwns[row2x]; |
19f9784c | 169 | cqq = cpp - 1; |
861cd1ed | 170 | tmp = *cqq; |
19f9784c | 171 | for (i = row2x - row1x; --i > 0;) |
861cd1ed EW |
172 | *--cpp = *--cqq; |
173 | *cqq = tmp; | |
174 | } | |
16ea9636 | 175 | if (scrolled) { |
861cd1ed EW |
176 | register char *p, *q; |
177 | ||
f2a77fe1 | 178 | p = &wwtouched[row2x]; |
19f9784c EW |
179 | q = p - 1; |
180 | for (i = row2x - row1x; --i > 0;) | |
861cd1ed | 181 | *--p = *--q; |
5360b004 | 182 | *q |= WWU_TOUCHED; |
26008571 EW |
183 | } else { |
184 | register char *p; | |
185 | ||
f2a77fe1 | 186 | p = &wwtouched[row1x]; |
19f9784c | 187 | for (i = row2x - row1x; --i >= 0;) |
6a1ef78a | 188 | *p++ |= WWU_TOUCHED; |
861cd1ed | 189 | } |
f2a77fe1 EW |
190 | wwredrawwin1(w, row1 + leaveit, row1x + 1, dir); |
191 | wwredrawwin1(w, row2x, row2, dir); | |
577dff1e EW |
192 | } |
193 | } else { | |
16ea9636 | 194 | if (scrolled) { |
5360b004 EW |
195 | register char *p; |
196 | ||
197 | p = &wwtouched[row1x]; | |
198 | for (i = row2x - row1x; --i >= 0;) | |
6a1ef78a | 199 | *p++ |= WWU_TOUCHED; |
5360b004 | 200 | } |
577dff1e EW |
201 | out: |
202 | if (dir > 0) | |
f2a77fe1 | 203 | wwredrawwin1(w, row1, row2 - leaveit, dir); |
577dff1e | 204 | else |
f2a77fe1 | 205 | wwredrawwin1(w, row1 + leaveit, row2, dir); |
577dff1e | 206 | } |
16ea9636 | 207 | return scrolled; |
577dff1e | 208 | } |