date and time created 83/08/17 15:48:20 by edward
[unix-history] / usr / src / usr.bin / window / wwscroll.c
CommitLineData
577dff1e 1#ifndef lint
861cd1ed 2static 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 */
12wwscroll1(w, srow, erow, dir, leaveit)
13register struct ww *w;
14int srow, erow, dir;
15char 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 {
152out:
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}