Commit | Line | Data |
---|---|---|
577dff1e | 1 | #ifndef lint |
f925dc2b | 2 | static char *sccsid = "@(#)wwscroll.c 3.8 83/08/24"; |
577dff1e EW |
3 | #endif |
4 | ||
5 | #include "ww.h" | |
e908bfac | 6 | #include "tt.h" |
577dff1e | 7 | |
b0d4d9e2 EW |
8 | wwscroll(w, n) |
9 | register struct ww *w; | |
10 | register n; | |
11 | { | |
12 | int dir; | |
13 | register scroll; | |
14 | ||
15 | if (n == 0) | |
16 | return; | |
17 | dir = n < 0 ? -1 : 1; | |
18 | scroll = w->ww_scroll + n; | |
19 | if (scroll < 0) | |
20 | scroll = 0; | |
21 | else if (scroll > w->ww_nline - w->ww_w.nr) | |
22 | scroll = w->ww_nline - w->ww_w.nr; | |
23 | n = abs(scroll - w->ww_scroll); | |
24 | if (n < w->ww_w.nr) { | |
25 | while (--n >= 0) { | |
e2c534a9 | 26 | (void) wwscroll1(w, 0, w->ww_w.nr - 1, dir, 0); |
b0d4d9e2 EW |
27 | w->ww_scroll += dir; |
28 | } | |
29 | } else { | |
30 | w->ww_scroll = scroll; | |
31 | wwredrawwin(w); | |
32 | } | |
33 | } | |
34 | ||
577dff1e | 35 | /* |
b0d4d9e2 | 36 | * Scroll one line, between 'srow' and 'erow', in direction 'dir'. |
577dff1e | 37 | * Don't adjust ww_scroll. |
b0d4d9e2 | 38 | * And don't redraw 'leaveit' lines. |
577dff1e EW |
39 | */ |
40 | wwscroll1(w, srow, erow, dir, leaveit) | |
41 | register struct ww *w; | |
42 | int srow, erow, dir; | |
b0d4d9e2 | 43 | int leaveit; |
577dff1e EW |
44 | { |
45 | register i; | |
b0d4d9e2 | 46 | int srow1, erow1; |
577dff1e EW |
47 | int nvis; |
48 | int nvismax; | |
49 | int deleted = 0; | |
50 | ||
51 | /* | |
52 | * See how many lines on the screen are affected. | |
53 | * And calculate srow, erow, and left at the same time. | |
54 | */ | |
55 | for (i = srow; i <= erow && w->ww_nvis[i] == 0; i++) | |
56 | ; | |
b0d4d9e2 | 57 | if ((srow1 = i) > erow) { |
577dff1e | 58 | /* can't do any fancy stuff */ |
b0d4d9e2 | 59 | erow1 = srow1 - 1; |
577dff1e EW |
60 | goto out; |
61 | } | |
62 | for (i = erow; i >= srow && w->ww_nvis[i] == 0; i--) | |
63 | ; | |
b0d4d9e2 | 64 | if ((erow1 = i) == srow1) |
577dff1e EW |
65 | goto out; /* just one line is easy */ |
66 | ||
67 | /* | |
68 | * See how much of this window is visible. | |
69 | */ | |
b0d4d9e2 | 70 | nvismax = wwncol * (erow1 - srow1 + 1); |
577dff1e | 71 | nvis = 0; |
b0d4d9e2 | 72 | for (i = srow1; i <= erow1; i++) |
577dff1e EW |
73 | nvis += w->ww_nvis[i]; |
74 | ||
75 | /* | |
76 | * If it's a good idea to use delete and insert line | |
77 | * and the terminal can, then do it. | |
78 | */ | |
79 | if (nvis > nvismax / 2 && tt.tt_delline && tt.tt_insline) { | |
80 | register union ww_char *tmp; | |
81 | register union ww_char **cpp, **cqq; | |
82 | ||
f925dc2b EW |
83 | /* |
84 | * Don't worry about retain when scrolling down. | |
85 | * But do worry when scrolling up. For hp2621. | |
86 | */ | |
577dff1e | 87 | if (dir > 0) { |
b0d4d9e2 | 88 | (*tt.tt_move)(srow1 + w->ww_w.t, 0); |
577dff1e | 89 | (*tt.tt_delline)(); |
f925dc2b | 90 | if (erow1 + w->ww_w.t != wwnrow - 1) { |
b0d4d9e2 | 91 | (*tt.tt_move)(erow1 + w->ww_w.t, 0); |
577dff1e EW |
92 | (*tt.tt_insline)(); |
93 | } | |
94 | /* | |
95 | * Fix up the old screen. | |
96 | */ | |
b0d4d9e2 | 97 | cpp = &wwos[srow1 + w->ww_w.t]; |
577dff1e EW |
98 | cqq = cpp + 1; |
99 | tmp = *cpp; | |
b0d4d9e2 | 100 | for (i = erow1 - srow1; --i >= 0;) |
577dff1e EW |
101 | *cpp++ = *cqq++; |
102 | *cpp = tmp; | |
103 | for (i = wwncol; --i >= 0;) | |
104 | tmp++->c_w = ' '; | |
105 | } else { | |
f925dc2b | 106 | if (tt.tt_retain || erow1 + w->ww_w.t != wwnrow - 1) { |
b0d4d9e2 | 107 | (*tt.tt_move)(erow1 + w->ww_w.t, 0); |
577dff1e EW |
108 | (*tt.tt_delline)(); |
109 | } | |
b0d4d9e2 | 110 | (*tt.tt_move)(srow1 + w->ww_w.t, 0); |
577dff1e EW |
111 | (*tt.tt_insline)(); |
112 | /* | |
113 | * Fix up the old screen. | |
114 | */ | |
b0d4d9e2 | 115 | cqq = &wwos[erow1 + w->ww_w.t]; |
577dff1e EW |
116 | cpp = cqq + 1; |
117 | tmp = *cqq; | |
b0d4d9e2 | 118 | for (i = erow1 - srow1; --i >= 0;) |
577dff1e EW |
119 | *--cpp = *--cqq; |
120 | *cqq = tmp; | |
121 | for (i = wwncol; --i >= 0;) | |
122 | tmp++->c_w = ' '; | |
123 | } | |
124 | deleted++; | |
125 | } | |
126 | ||
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 | ||
b0d4d9e2 | 139 | cpp = &wwns[srow1 + w->ww_w.t]; |
861cd1ed EW |
140 | cqq = cpp + 1; |
141 | tmp = *cpp; | |
b0d4d9e2 | 142 | for (i = erow1 - srow1; --i >= 0;) |
861cd1ed EW |
143 | *cpp++ = *cqq++; |
144 | *cpp = tmp; | |
145 | } | |
26008571 | 146 | if (deleted) { |
861cd1ed EW |
147 | register char *p, *q; |
148 | ||
b0d4d9e2 | 149 | p = &wwtouched[srow1 + w->ww_w.t]; |
861cd1ed | 150 | q = p + 1; |
b0d4d9e2 | 151 | for (i = erow1 - srow1; --i >= 0;) |
861cd1ed EW |
152 | *p++ = *q++; |
153 | *p = 1; | |
26008571 EW |
154 | } else { |
155 | register char *p; | |
156 | ||
157 | p = &wwtouched[srow1 + w->ww_w.t]; | |
158 | for (i = erow1 - srow1 + 1; --i >= 0;) | |
159 | *p++ = 1; | |
861cd1ed | 160 | } |
b0d4d9e2 EW |
161 | wwredrawwin1(w, srow, srow1 - 1, w->ww_scroll + dir); |
162 | wwredrawwin1(w, erow1, erow - leaveit, | |
577dff1e EW |
163 | w->ww_scroll + dir); |
164 | } else { | |
861cd1ed EW |
165 | { |
166 | register union ww_char *tmp; | |
167 | register union ww_char **cpp, **cqq; | |
168 | ||
b0d4d9e2 | 169 | cqq = &wwns[erow1 + w->ww_w.t]; |
861cd1ed EW |
170 | cpp = cqq + 1; |
171 | tmp = *cqq; | |
b0d4d9e2 | 172 | for (i = erow1 - srow1; --i >= 0;) |
861cd1ed EW |
173 | *--cpp = *--cqq; |
174 | *cqq = tmp; | |
175 | } | |
26008571 | 176 | if (deleted) { |
861cd1ed EW |
177 | register char *p, *q; |
178 | ||
b0d4d9e2 | 179 | q = &wwtouched[erow1 + w->ww_w.t]; |
861cd1ed | 180 | p = q + 1; |
b0d4d9e2 | 181 | for (i = erow1 - srow1; --i >= 0;) |
861cd1ed EW |
182 | *--p = *--q; |
183 | *q = 1; | |
26008571 EW |
184 | } else { |
185 | register char *p; | |
186 | ||
187 | p = &wwtouched[srow1 + w->ww_w.t]; | |
188 | for (i = erow1 - srow1 + 1; --i >= 0;) | |
189 | *p++ = 1; | |
861cd1ed | 190 | } |
b0d4d9e2 | 191 | wwredrawwin1(w, srow + leaveit, srow1, |
577dff1e | 192 | w->ww_scroll + dir); |
b0d4d9e2 | 193 | wwredrawwin1(w, erow1 + 1, erow, w->ww_scroll + dir); |
577dff1e EW |
194 | } |
195 | } else { | |
196 | out: | |
197 | if (dir > 0) | |
198 | wwredrawwin1(w, srow, erow - leaveit, | |
199 | w->ww_scroll + dir); | |
200 | else | |
201 | wwredrawwin1(w, srow + leaveit, erow, | |
202 | w->ww_scroll + dir); | |
203 | } | |
204 | return deleted; | |
205 | } |