Commit | Line | Data |
---|---|---|
577dff1e | 1 | #ifndef lint |
26008571 | 2 | static char *sccsid = "@(#)wwscroll.c 3.6 83/08/22"; |
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 | ||
83 | if (dir > 0) { | |
b0d4d9e2 | 84 | (*tt.tt_move)(srow1 + w->ww_w.t, 0); |
577dff1e | 85 | (*tt.tt_delline)(); |
b0d4d9e2 EW |
86 | if (erow1 + w->ww_w.t != wwnrow - 1) { |
87 | (*tt.tt_move)(erow1 + w->ww_w.t, 0); | |
577dff1e EW |
88 | (*tt.tt_insline)(); |
89 | } | |
90 | /* | |
91 | * Fix up the old screen. | |
92 | */ | |
b0d4d9e2 | 93 | cpp = &wwos[srow1 + w->ww_w.t]; |
577dff1e EW |
94 | cqq = cpp + 1; |
95 | tmp = *cpp; | |
b0d4d9e2 | 96 | for (i = erow1 - srow1; --i >= 0;) |
577dff1e EW |
97 | *cpp++ = *cqq++; |
98 | *cpp = tmp; | |
99 | for (i = wwncol; --i >= 0;) | |
100 | tmp++->c_w = ' '; | |
101 | } else { | |
b0d4d9e2 EW |
102 | if (erow1 + w->ww_w.t != wwnrow - 1) { |
103 | (*tt.tt_move)(erow1 + w->ww_w.t, 0); | |
577dff1e EW |
104 | (*tt.tt_delline)(); |
105 | } | |
b0d4d9e2 | 106 | (*tt.tt_move)(srow1 + w->ww_w.t, 0); |
577dff1e EW |
107 | (*tt.tt_insline)(); |
108 | /* | |
109 | * Fix up the old screen. | |
110 | */ | |
b0d4d9e2 | 111 | cqq = &wwos[erow1 + w->ww_w.t]; |
577dff1e EW |
112 | cpp = cqq + 1; |
113 | tmp = *cqq; | |
b0d4d9e2 | 114 | for (i = erow1 - srow1; --i >= 0;) |
577dff1e EW |
115 | *--cpp = *--cqq; |
116 | *cqq = tmp; | |
117 | for (i = wwncol; --i >= 0;) | |
118 | tmp++->c_w = ' '; | |
119 | } | |
120 | deleted++; | |
121 | } | |
122 | ||
123 | /* | |
124 | * Fix the new screen. | |
125 | */ | |
126 | if (nvis == nvismax) { | |
127 | /* | |
128 | * Can shift whole lines. | |
129 | */ | |
577dff1e | 130 | if (dir > 0) { |
861cd1ed EW |
131 | { |
132 | register union ww_char *tmp; | |
133 | register union ww_char **cpp, **cqq; | |
134 | ||
b0d4d9e2 | 135 | cpp = &wwns[srow1 + w->ww_w.t]; |
861cd1ed EW |
136 | cqq = cpp + 1; |
137 | tmp = *cpp; | |
b0d4d9e2 | 138 | for (i = erow1 - srow1; --i >= 0;) |
861cd1ed EW |
139 | *cpp++ = *cqq++; |
140 | *cpp = tmp; | |
141 | } | |
26008571 | 142 | if (deleted) { |
861cd1ed EW |
143 | register char *p, *q; |
144 | ||
b0d4d9e2 | 145 | p = &wwtouched[srow1 + w->ww_w.t]; |
861cd1ed | 146 | q = p + 1; |
b0d4d9e2 | 147 | for (i = erow1 - srow1; --i >= 0;) |
861cd1ed EW |
148 | *p++ = *q++; |
149 | *p = 1; | |
26008571 EW |
150 | } else { |
151 | register char *p; | |
152 | ||
153 | p = &wwtouched[srow1 + w->ww_w.t]; | |
154 | for (i = erow1 - srow1 + 1; --i >= 0;) | |
155 | *p++ = 1; | |
861cd1ed | 156 | } |
b0d4d9e2 EW |
157 | wwredrawwin1(w, srow, srow1 - 1, w->ww_scroll + dir); |
158 | wwredrawwin1(w, erow1, erow - leaveit, | |
577dff1e EW |
159 | w->ww_scroll + dir); |
160 | } else { | |
861cd1ed EW |
161 | { |
162 | register union ww_char *tmp; | |
163 | register union ww_char **cpp, **cqq; | |
164 | ||
b0d4d9e2 | 165 | cqq = &wwns[erow1 + w->ww_w.t]; |
861cd1ed EW |
166 | cpp = cqq + 1; |
167 | tmp = *cqq; | |
b0d4d9e2 | 168 | for (i = erow1 - srow1; --i >= 0;) |
861cd1ed EW |
169 | *--cpp = *--cqq; |
170 | *cqq = tmp; | |
171 | } | |
26008571 | 172 | if (deleted) { |
861cd1ed EW |
173 | register char *p, *q; |
174 | ||
b0d4d9e2 | 175 | q = &wwtouched[erow1 + w->ww_w.t]; |
861cd1ed | 176 | p = q + 1; |
b0d4d9e2 | 177 | for (i = erow1 - srow1; --i >= 0;) |
861cd1ed EW |
178 | *--p = *--q; |
179 | *q = 1; | |
26008571 EW |
180 | } else { |
181 | register char *p; | |
182 | ||
183 | p = &wwtouched[srow1 + w->ww_w.t]; | |
184 | for (i = erow1 - srow1 + 1; --i >= 0;) | |
185 | *p++ = 1; | |
861cd1ed | 186 | } |
b0d4d9e2 | 187 | wwredrawwin1(w, srow + leaveit, srow1, |
577dff1e | 188 | w->ww_scroll + dir); |
b0d4d9e2 | 189 | wwredrawwin1(w, erow1 + 1, erow, w->ww_scroll + dir); |
577dff1e EW |
190 | } |
191 | } else { | |
192 | out: | |
193 | if (dir > 0) | |
194 | wwredrawwin1(w, srow, erow - leaveit, | |
195 | w->ww_scroll + dir); | |
196 | else | |
197 | wwredrawwin1(w, srow + leaveit, erow, | |
198 | w->ww_scroll + dir); | |
199 | } | |
200 | return deleted; | |
201 | } |