date and time created 83/08/22 15:19:40 by edward
[unix-history] / usr / src / usr.bin / window / wwscroll.c
CommitLineData
577dff1e 1#ifndef lint
26008571 2static 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
8wwscroll(w, n)
9register struct ww *w;
10register 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 */
40wwscroll1(w, srow, erow, dir, leaveit)
41register struct ww *w;
42int srow, erow, dir;
b0d4d9e2 43int 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 {
192out:
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}