check ww_haspty before closing ww_pty and ww_tty.
[unix-history] / usr / src / usr.bin / window / wwscroll.c
CommitLineData
577dff1e 1#ifndef lint
f925dc2b 2static 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
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
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 {
196out:
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}