xref: /original-bsd/usr.bin/window/cmd7.c (revision c3e32dec)
1 /*
2  * Copyright (c) 1983, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Edward Wang at The University of California, Berkeley.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 static char sccsid[] = "@(#)cmd7.c	8.1 (Berkeley) 06/06/93";
13 #endif /* not lint */
14 
15 #include "defs.h"
16 #include "string.h"
17 
18 /*
19  * Window size.
20  */
21 
22 c_size(w)
23 register struct ww *w;
24 {
25 	int col, row;
26 
27 	if (!terse)
28 		wwputs("New window size (lower right corner): ", cmdwin);
29 	col = MIN(w->ww_w.r, wwncol) - 1;
30 	row = MIN(w->ww_w.b, wwnrow) - 1;
31 	wwadd(boxwin, framewin->ww_back);
32 	for (;;) {
33 		wwbox(boxwin, w->ww_w.t - 1, w->ww_w.l - 1,
34 			row - w->ww_w.t + 3, col - w->ww_w.l + 3);
35 		wwsetcursor(row, col);
36 		while (wwpeekc() < 0)
37 			wwiomux();
38 		switch (getpos(&row, &col, w->ww_w.t, w->ww_w.l,
39 			wwnrow - 1, wwncol - 1)) {
40 		case 3:
41 			wwunbox(boxwin);
42 			wwdelete(boxwin);
43 			return;
44 		case 2:
45 			wwunbox(boxwin);
46 			break;
47 		case 1:
48 			wwunbox(boxwin);
49 		case 0:
50 			continue;
51 		}
52 		break;
53 	}
54 	wwdelete(boxwin);
55 	if (!terse)
56 		wwputc('\n', cmdwin);
57 	wwcurtowin(cmdwin);
58 	sizewin(w, row - w->ww_w.t + 1, col - w->ww_w.l + 1);
59 }
60 
61 /*
62  * Yank and put
63  */
64 
65 struct yb {
66 	char *line;
67 	int length;
68 	struct yb *link;
69 };
70 struct yb *yb_head, *yb_tail;
71 
72 c_yank()
73 {
74 	struct ww *w = selwin;
75 	int col1, row1;
76 	int col2, row2;
77 	int r, c;
78 
79 	if (!terse)
80 		wwputs("Yank starting position: ", cmdwin);
81 	wwcursor(w, 0);
82 	row1 = w->ww_cur.r;
83 	col1 = w->ww_cur.c;
84 	for (;;) {
85 		wwsetcursor(row1, col1);
86 		while (wwpeekc() < 0)
87 			wwiomux();
88 		switch (getpos(&row1, &col1, w->ww_i.t, w->ww_i.l,
89 			       w->ww_i.b - 1, w->ww_i.r - 1)) {
90 		case 3:
91 			goto out;
92 		case 2:
93 			break;
94 		case 1:
95 		case 0:
96 			continue;
97 		}
98 		break;
99 	}
100 	if (!terse)
101 		wwputs("\nYank ending position: ", cmdwin);
102 	row2 = row1;
103 	col2 = col1;
104 	for (;;) {
105 		wwsetcursor(row2, col2);
106 		while (wwpeekc() < 0)
107 			wwiomux();
108 		r = row2;
109 		c = col2;
110 		switch (getpos(&row2, &col2, w->ww_i.t, w->ww_i.l,
111 			       w->ww_i.b - 1, w->ww_i.r - 1)) {
112 		case 3:
113 			yank_highlight(row1, col1, r, c);
114 			goto out;
115 		case 2:
116 			break;
117 		case 1:
118 			yank_highlight(row1, col1, r, c);
119 			yank_highlight(row1, col1, row2, col2);
120 		case 0:
121 			continue;
122 		}
123 		break;
124 	}
125 	if (row2 < row1 || row2 == row1 && col2 < col1) {
126 		r = row1;
127 		c = col1;
128 		row1 = row2;
129 		col1 = col2;
130 		row2 = r;
131 		col2 = c;
132 	}
133 	unyank();
134 	c = col1;
135 	for (r = row1; r < row2; r++) {
136 		yank_line(r, c, w->ww_b.r);
137 		c = w->ww_b.l;
138 	}
139 	yank_line(r, c, col2);
140 	yank_highlight(row1, col1, row2, col2);
141 	if (!terse)
142 		wwputc('\n', cmdwin);
143 out:
144 	wwcursor(w, 1);
145 }
146 
147 yank_highlight(row1, col1, row2, col2)
148 {
149 	struct ww *w = selwin;
150 	int r, c;
151 
152 	if ((wwavailmodes & WWM_REV) == 0)
153 		return;
154 	if (row2 < row1 || row2 == row1 && col2 < col1) {
155 		r = row1;
156 		c = col1;
157 		row1 = row2;
158 		col1 = col2;
159 		row2 = r;
160 		col2 = c;
161 	}
162 	c = col1;
163 	for (r = row1; r < row2; r++) {
164 		yank_highlight_line(r, c, w->ww_b.r);
165 		c = w->ww_b.l;
166 	}
167 	yank_highlight_line(r, c, col2);
168 }
169 
170 yank_highlight_line(r, c, cend)
171 {
172 	struct ww *w = selwin;
173 	char *win;
174 
175 	if (r < w->ww_i.t || r >= w->ww_i.b)
176 		return;
177 	if (c < w->ww_i.l)
178 		c = w->ww_i.l;
179 	if (cend >= w->ww_i.r)
180 		cend = w->ww_i.r;
181 	for (win = w->ww_win[r] + c; c < cend; c++, win++) {
182 		*win ^= WWM_REV;
183 		if (wwsmap[r][c] == w->ww_index) {
184 			if (*win == 0)
185 				w->ww_nvis[r]++;
186 			else if (*win == WWM_REV)
187 				w->ww_nvis[r]--;
188 			wwns[r][c].c_m ^= WWM_REV;
189 			wwtouched[r] |= WWU_TOUCHED;
190 		}
191 	}
192 }
193 
194 unyank()
195 {
196 	struct yb *yp, *yq;
197 
198 	for (yp = yb_head; yp; yp = yq) {
199 		yq = yp->link;
200 		str_free(yp->line);
201 		free((char *) yp);
202 	}
203 	yb_head = yb_tail = 0;
204 }
205 
206 yank_line(r, c, cend)
207 {
208 	struct yb *yp;
209 	int nl = 0;
210 	int n;
211 	union ww_char *bp;
212 	char *cp;
213 
214 	if (c == cend)
215 		return;
216 	if ((yp = (struct yb *) malloc(sizeof *yp)) == 0)
217 		return;
218 	yp->link = 0;
219 	nl = cend == selwin->ww_b.r;
220 	bp = selwin->ww_buf[r];
221 	for (cend--; cend >= c; cend--)
222 		if (bp[cend].c_c != ' ')
223 			break;
224 	yp->length = n = cend - c + 1;
225 	if (nl)
226 		yp->length++;
227 	yp->line = str_alloc(yp->length + 1);
228 	for (bp += c, cp = yp->line; --n >= 0;)
229 		*cp++ = bp++->c_c;
230 	if (nl)
231 		*cp++ = '\n';
232 	*cp = 0;
233 	if (yb_head)
234 		yb_tail = yb_tail->link = yp;
235 	else
236 		yb_head = yb_tail = yp;
237 }
238 
239 c_put()
240 {
241 	struct yb *yp;
242 
243 	for (yp = yb_head; yp; yp = yp->link)
244 		(void) write(selwin->ww_pty, yp->line, yp->length);
245 }
246