Commit | Line | Data |
---|---|---|
577dff1e | 1 | #ifndef lint |
861cd1ed | 2 | static char *sccsid = "@(#)wwscroll.c 3.3 83/08/16"; |
577dff1e EW |
3 | #endif |
4 | ||
5 | #include "ww.h" | |
e908bfac | 6 | #include "tt.h" |
577dff1e EW |
7 | |
8 | /* | |
9 | * Scroll down one line, starting at 'line'. | |
10 | * Don't adjust ww_scroll. | |
11 | */ | |
12 | wwscroll1(w, srow, erow, dir, leaveit) | |
13 | register struct ww *w; | |
14 | int srow, erow, dir; | |
15 | char leaveit; | |
16 | { | |
17 | register i; | |
577dff1e EW |
18 | int startrow, endrow; |
19 | int nvis; | |
20 | int nvismax; | |
21 | int deleted = 0; | |
22 | ||
23 | /* | |
24 | * See how many lines on the screen are affected. | |
25 | * And calculate srow, erow, and left at the same time. | |
26 | */ | |
27 | for (i = srow; i <= erow && w->ww_nvis[i] == 0; i++) | |
28 | ; | |
29 | if ((startrow = i) > erow) { | |
30 | /* can't do any fancy stuff */ | |
31 | endrow = startrow - 1; | |
32 | goto out; | |
33 | } | |
34 | for (i = erow; i >= srow && w->ww_nvis[i] == 0; i--) | |
35 | ; | |
36 | if ((endrow = i) == startrow) | |
37 | goto out; /* just one line is easy */ | |
38 | ||
39 | /* | |
40 | * See how much of this window is visible. | |
41 | */ | |
42 | nvismax = wwncol * (endrow - startrow + 1); | |
43 | nvis = 0; | |
44 | for (i = startrow; i <= endrow; i++) | |
45 | nvis += w->ww_nvis[i]; | |
46 | ||
47 | /* | |
48 | * If it's a good idea to use delete and insert line | |
49 | * and the terminal can, then do it. | |
50 | */ | |
51 | if (nvis > nvismax / 2 && tt.tt_delline && tt.tt_insline) { | |
52 | register union ww_char *tmp; | |
53 | register union ww_char **cpp, **cqq; | |
54 | ||
55 | if (dir > 0) { | |
56 | (*tt.tt_move)(startrow + w->ww_w.t, 0); | |
57 | (*tt.tt_delline)(); | |
58 | if (endrow + w->ww_w.t != wwnrow - 1) { | |
59 | (*tt.tt_move)(endrow + w->ww_w.t, 0); | |
60 | (*tt.tt_insline)(); | |
61 | } | |
62 | /* | |
63 | * Fix up the old screen. | |
64 | */ | |
65 | cpp = &wwos[startrow + w->ww_w.t]; | |
66 | cqq = cpp + 1; | |
67 | tmp = *cpp; | |
68 | for (i = endrow - startrow; --i >= 0;) | |
69 | *cpp++ = *cqq++; | |
70 | *cpp = tmp; | |
71 | for (i = wwncol; --i >= 0;) | |
72 | tmp++->c_w = ' '; | |
73 | } else { | |
74 | if (endrow + w->ww_w.t != wwnrow - 1) { | |
75 | (*tt.tt_move)(endrow + w->ww_w.t, 0); | |
76 | (*tt.tt_delline)(); | |
77 | } | |
78 | (*tt.tt_move)(startrow + w->ww_w.t, 0); | |
79 | (*tt.tt_insline)(); | |
80 | /* | |
81 | * Fix up the old screen. | |
82 | */ | |
83 | cqq = &wwos[endrow + w->ww_w.t]; | |
84 | cpp = cqq + 1; | |
85 | tmp = *cqq; | |
86 | for (i = endrow - startrow; --i >= 0;) | |
87 | *--cpp = *--cqq; | |
88 | *cqq = tmp; | |
89 | for (i = wwncol; --i >= 0;) | |
90 | tmp++->c_w = ' '; | |
91 | } | |
92 | deleted++; | |
93 | } | |
94 | ||
95 | /* | |
96 | * Fix the new screen. | |
97 | */ | |
98 | if (nvis == nvismax) { | |
99 | /* | |
100 | * Can shift whole lines. | |
101 | */ | |
577dff1e | 102 | if (dir > 0) { |
861cd1ed EW |
103 | { |
104 | register union ww_char *tmp; | |
105 | register union ww_char **cpp, **cqq; | |
106 | ||
107 | cpp = &wwns[startrow + w->ww_w.t]; | |
108 | cqq = cpp + 1; | |
109 | tmp = *cpp; | |
110 | for (i = endrow - startrow; --i >= 0;) | |
111 | *cpp++ = *cqq++; | |
112 | *cpp = tmp; | |
113 | } | |
114 | { | |
115 | register char *p, *q; | |
116 | ||
117 | p = &wwtouched[startrow + w->ww_w.t]; | |
118 | q = p + 1; | |
119 | for (i = endrow - startrow; --i >= 0;) | |
120 | *p++ = *q++; | |
121 | *p = 1; | |
122 | } | |
577dff1e EW |
123 | wwredrawwin1(w, srow, startrow - 1, w->ww_scroll + dir); |
124 | wwredrawwin1(w, endrow + 1, erow - leaveit, | |
125 | w->ww_scroll + dir); | |
126 | } else { | |
861cd1ed EW |
127 | { |
128 | register union ww_char *tmp; | |
129 | register union ww_char **cpp, **cqq; | |
130 | ||
131 | cqq = &wwns[endrow + w->ww_w.t]; | |
132 | cpp = cqq + 1; | |
133 | tmp = *cqq; | |
134 | for (i = endrow - startrow; --i >= 0;) | |
135 | *--cpp = *--cqq; | |
136 | *cqq = tmp; | |
137 | } | |
138 | { | |
139 | register char *p, *q; | |
140 | ||
141 | q = &wwtouched[endrow + w->ww_w.t]; | |
142 | p = q + 1; | |
143 | for (i = endrow - startrow; --i >= 0;) | |
144 | *--p = *--q; | |
145 | *q = 1; | |
146 | } | |
577dff1e EW |
147 | wwredrawwin1(w, srow + leaveit, startrow - 1, |
148 | w->ww_scroll + dir); | |
149 | wwredrawwin1(w, endrow + 1, erow, w->ww_scroll + dir); | |
150 | } | |
151 | } else { | |
152 | out: | |
153 | if (dir > 0) | |
154 | wwredrawwin1(w, srow, erow - leaveit, | |
155 | w->ww_scroll + dir); | |
156 | else | |
157 | wwredrawwin1(w, srow + leaveit, erow, | |
158 | w->ww_scroll + dir); | |
159 | } | |
160 | return deleted; | |
161 | } |