|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)wwscroll.c 3.13 4/24/85";
3: #endif
4:
5: /*
6: * Copyright (c) 1983 Regents of the University of California,
7: * All rights reserved. Redistribution permitted subject to
8: * the terms of the Berkeley Software License Agreement.
9: */
10:
11: #include "ww.h"
12: #include "tt.h"
13:
14: wwscroll(w, n)
15: register struct ww *w;
16: int n;
17: {
18: register dir;
19: register top;
20:
21: if (n == 0)
22: return;
23: dir = n < 0 ? -1 : 1;
24: top = w->ww_b.t - n;
25: if (top > w->ww_w.t)
26: top = w->ww_w.t;
27: else if (top + w->ww_b.nr < w->ww_w.b)
28: top = w->ww_w.b - w->ww_b.nr;
29: n = abs(top - w->ww_b.t);
30: if (n < w->ww_i.nr) {
31: while (--n >= 0) {
32: (void) wwscroll1(w, w->ww_i.t, w->ww_i.b, dir, 0);
33: w->ww_buf += dir;
34: w->ww_b.t -= dir;
35: w->ww_b.b -= dir;
36: }
37: } else {
38: w->ww_buf -= top - w->ww_b.t;
39: w->ww_b.t = top;
40: w->ww_b.b = top + w->ww_b.nr;
41: wwredrawwin(w);
42: }
43: }
44:
45: /*
46: * Scroll one line, between 'row1' and 'row2', in direction 'dir'.
47: * Don't adjust ww_scroll.
48: * And don't redraw 'leaveit' lines.
49: */
50: wwscroll1(w, row1, row2, dir, leaveit)
51: register struct ww *w;
52: int row1, row2, dir;
53: int leaveit;
54: {
55: register i;
56: int row1x, row2x;
57: int nvis;
58: int nvismax;
59: int deleted = 0;
60:
61: /*
62: * See how many lines on the screen are affected.
63: * And calculate row1x, row2x, and left at the same time.
64: */
65: for (i = row1; i < row2 && w->ww_nvis[i] == 0; i++)
66: ;
67: if (i >= row2) /* can't do any fancy stuff */
68: goto out;
69: row1x = i;
70: for (i = row2 - 1; i >= row1 && w->ww_nvis[i] == 0; i--)
71: ;
72: if (i <= row1x)
73: goto out; /* just one line is easy */
74: row2x = i + 1;
75:
76: /*
77: * See how much of this window is visible.
78: */
79: nvismax = wwncol * (row2x - row1x);
80: nvis = 0;
81: for (i = row1x; i < row2x; i++)
82: nvis += w->ww_nvis[i];
83:
84: /*
85: * If it's a good idea to use delete and insert line
86: * and the terminal can, then do it.
87: */
88: if (nvis > nvismax / 2 && tt.tt_delline && tt.tt_insline) {
89: register union ww_char *tmp;
90: register union ww_char **cpp, **cqq;
91:
92: /*
93: * Don't worry about retain when scrolling down.
94: * But do worry when scrolling up. For hp2621.
95: */
96: if (dir > 0) {
97: (*tt.tt_move)(row1x, 0);
98: (*tt.tt_delline)();
99: if (row2x < wwnrow) {
100: (*tt.tt_move)(row2x - 1, 0);
101: (*tt.tt_insline)();
102: }
103: /*
104: * Fix up the old screen.
105: */
106: cpp = &wwos[row1x];
107: cqq = cpp + 1;
108: tmp = *cpp;
109: for (i = row2x - row1x; --i > 0;)
110: *cpp++ = *cqq++;
111: *cpp = tmp;
112: } else {
113: if (tt.tt_retain || row2x != wwnrow) {
114: (*tt.tt_move)(row2x - 1, 0);
115: (*tt.tt_delline)();
116: }
117: (*tt.tt_move)(row1x, 0);
118: (*tt.tt_insline)();
119: /*
120: * Fix up the old screen.
121: */
122: cpp = &wwos[row2x];
123: cqq = cpp - 1;
124: tmp = *cqq;
125: for (i = row2x - row1x; --i > 0;)
126: *--cpp = *--cqq;
127: *cqq = tmp;
128: }
129: for (i = wwncol; --i >= 0;)
130: tmp++->c_w = ' ';
131: deleted++;
132: }
133:
134: /*
135: * Fix the new screen.
136: */
137: if (nvis == nvismax) {
138: /*
139: * Can shift whole lines.
140: */
141: if (dir > 0) {
142: {
143: register union ww_char *tmp;
144: register union ww_char **cpp, **cqq;
145:
146: cpp = &wwns[row1x];
147: cqq = cpp + 1;
148: tmp = *cpp;
149: for (i = row2x - row1x; --i > 0;)
150: *cpp++ = *cqq++;
151: *cpp = tmp;
152: }
153: if (deleted) {
154: register char *p, *q;
155:
156: p = &wwtouched[row1x];
157: q = p + 1;
158: for (i = row2x - row1x; --i > 0;)
159: *p++ = *q++;
160: *p |= WWU_TOUCHED;
161: } else {
162: register char *p;
163:
164: p = &wwtouched[row1x];
165: for (i = row2x - row1x; --i >= 0;)
166: *p++ |= WWU_MAJOR|WWU_TOUCHED;
167: }
168: wwredrawwin1(w, row1, row1x, dir);
169: wwredrawwin1(w, row2x - 1, row2 - leaveit, dir);
170: } else {
171: {
172: register union ww_char *tmp;
173: register union ww_char **cpp, **cqq;
174:
175: cpp = &wwns[row2x];
176: cqq = cpp - 1;
177: tmp = *cqq;
178: for (i = row2x - row1x; --i > 0;)
179: *--cpp = *--cqq;
180: *cqq = tmp;
181: }
182: if (deleted) {
183: register char *p, *q;
184:
185: p = &wwtouched[row2x];
186: q = p - 1;
187: for (i = row2x - row1x; --i > 0;)
188: *--p = *--q;
189: *q |= WWU_MAJOR|WWU_TOUCHED;
190: } else {
191: register char *p;
192:
193: p = &wwtouched[row1x];
194: for (i = row2x - row1x; --i >= 0;)
195: *p++ |= WWU_TOUCHED;
196: }
197: wwredrawwin1(w, row1 + leaveit, row1x + 1, dir);
198: wwredrawwin1(w, row2x, row2, dir);
199: }
200: } else {
201: out:
202: if (dir > 0)
203: wwredrawwin1(w, row1, row2 - leaveit, dir);
204: else
205: wwredrawwin1(w, row1 + leaveit, row2, dir);
206: }
207: return deleted;
208: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.