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