date and time created 83/08/11 17:21:55 by edward
[unix-history] / usr / src / usr.bin / window / wwinsline.c
CommitLineData
2c7129ee
EW
1#ifndef lint
2static char *sccsid = "@(#)wwinsline.c 3.1 83/08/09";
3#endif
4
5#include "ww.h"
6
7wwinsline(w, line)
8register struct ww *w;
9int line;
10{
11 register i;
12 int j;
13 int row = line - w->ww_scroll;
14 int srow = MAX(row, 0) + w->ww_w.t;
15 int startrow, endrow;
16 int nvis;
17 int nvismax;
18 int deleted = 0;
19
20 /*
21 * Fix the buffer.
22 * But leave clearing the first line for wwclreol().
23 */
24 {
25 register union ww_char *tmp;
26 register union ww_char **cpp, **cqq;
27 cpp = &w->ww_buf[w->ww_nline];
28 cqq = cpp - 1;
29 tmp = *cqq;
30 for (i = w->ww_nline - line - 1; --i >= 0;)
31 *--cpp = *--cqq;
32 *cqq = tmp;
33 }
34 /*
35 * See how many lines on the screen are affected.
36 */
37 for (i = MAX(0, row); i < w->ww_w.nr && w->ww_nvis[i] == 0; i++)
38 ;
39 if ((startrow = i + w->ww_w.t) == w->ww_w.b) {
40 endrow = startrow - 1;
41 goto out;
42 }
43 for (i = w->ww_w.nr - 1; i > 0 && w->ww_nvis[i] == 0; i--)
44 ;
45 if ((endrow = i + w->ww_w.t) == startrow)
46 goto out; /* just one line is easy */
47 /*
48 * See how much of this window is visible.
49 */
50 nvismax = wwncol * (endrow - startrow + 1);
51 nvis = 0;
52 for (i = startrow; i <= endrow; i++)
53 nvis += w->ww_nvis[i];
54 /*
55 * If it's a good idea to use delete and insert line
56 * and the terminal can, then do it.
57 */
58 if (endrow > startrow && nvis > nvismax / 2
59 && tt.tt_delline && tt.tt_insline) {
60 register union ww_char *tmp;
61 register union ww_char **cpp, **cqq;
62
63 (*tt.tt_move)(startrow, 0);
64 (*tt.tt_delline)();
65 if (endrow != wwnrow - 1) {
66 (*tt.tt_move)(endrow, 0);
67 (*tt.tt_insline)();
68 }
69 /*
70 * Fix up the old screen.
71 */
72 cpp = &wwos[startrow];
73 cqq = cpp + 1;
74 tmp = *cpp;
75 for (i = endrow - startrow; --i >= 0;)
76 *cpp++ = *cqq++;
77 *cpp = tmp;
78 for (i = wwncol; --i >= 0;)
79 tmp++->c_w = ' ';
80 deleted++;
81 }
82 /*
83 * Fix the new screen.
84 */
85 if (endrow > startrow && nvis == nvismax) {
86 register union ww_char *tmp;
87 register union ww_char **cpp, **cqq;
88
89 cpp = &wwns[startrow];
90 cqq = cpp + 1;
91 tmp = *cpp;
92 for (i = endrow - startrow; --i >= 0;)
93 *cpp++ = *cqq;
94 *cpp = tmp;
95 i = startrow - 1;
96 } else {
97out:
98 /* wwclreol() will do the last line */
99 if ((i = endrow) == w->ww_nline - w->ww_scroll + w->ww_w.t - 1)
100 i--;
101 }
102 for (; i >= srow; i--) {
103 register char *smap;
104 register union ww_char *buf;
105 register char *win;
106 register union ww_char *ns;
107
108 ns = &wwns[i][w->ww_w.l];
109 smap = &wwsmap[i][w->ww_w.l];
110 buf = w->ww_buf[w->ww_scroll + i - w->ww_w.t];
111 win = w->ww_win[i - w->ww_w.t];
112 for (j = w->ww_w.nc; --j >= 0;)
113 if (*smap++ != w->ww_index)
114 win++, ns++, buf++;
115 else
116 ns++->c_w = buf++->c_w
117 ^ *win++ << WWC_MSHIFT;
118 }
119 wwclreol(w, w->ww_nline - 1, 0, deleted);
120}