1 /* $OpenBSD: cmd7.c,v 1.6 2003/07/18 23:11:43 david Exp $ */
2 /* $NetBSD: cmd7.c,v 1.3 1995/09/28 10:34:12 tls Exp $ */
3
4 /*
5 * Copyright (c) 1983, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Edward Wang at The University of California, Berkeley.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)cmd7.c 8.1 (Berkeley) 6/6/93";
39 #else
40 static char rcsid[] = "$OpenBSD: cmd7.c,v 1.6 2003/07/18 23:11:43 david Exp $";
41 #endif
42 #endif /* not lint */
43
44 #include "defs.h"
45 #include "string.h"
46
47 #include <sys/types.h>
48 #include <unistd.h>
49
50 /*
51 * Window size.
52 */
53
54 c_size(w)
55 struct ww *w;
56 {
57 int col, row;
58
59 if (!terse)
60 wwputs("New window size (lower right corner): ", cmdwin);
61 col = MIN(w->ww_w.r, wwncol) - 1;
62 row = MIN(w->ww_w.b, wwnrow) - 1;
63 wwadd(boxwin, framewin->ww_back);
64 for (;;) {
65 wwbox(boxwin, w->ww_w.t - 1, w->ww_w.l - 1,
66 row - w->ww_w.t + 3, col - w->ww_w.l + 3);
67 wwsetcursor(row, col);
68 while (wwpeekc() < 0)
69 wwiomux();
70 switch (getpos(&row, &col, w->ww_w.t, w->ww_w.l,
71 wwnrow - 1, wwncol - 1)) {
72 case 3:
73 wwunbox(boxwin);
74 wwdelete(boxwin);
75 return;
76 case 2:
77 wwunbox(boxwin);
78 break;
79 case 1:
80 wwunbox(boxwin);
81 case 0:
82 continue;
83 }
84 break;
85 }
86 wwdelete(boxwin);
87 if (!terse)
88 wwputc('\n', cmdwin);
89 wwcurtowin(cmdwin);
90 sizewin(w, row - w->ww_w.t + 1, col - w->ww_w.l + 1);
91 }
92
93 /*
94 * Yank and put
95 */
96
97 struct yb {
98 char *line;
99 int length;
100 struct yb *link;
101 };
102 struct yb *yb_head, *yb_tail;
103
c_yank()104 c_yank()
105 {
106 struct ww *w = selwin;
107 int col1, row1;
108 int col2, row2;
109 int r, c;
110
111 if (!terse)
112 wwputs("Yank starting position: ", cmdwin);
113 wwcursor(w, 0);
114 row1 = w->ww_cur.r;
115 col1 = w->ww_cur.c;
116 for (;;) {
117 wwsetcursor(row1, col1);
118 while (wwpeekc() < 0)
119 wwiomux();
120 switch (getpos(&row1, &col1, w->ww_i.t, w->ww_i.l,
121 w->ww_i.b - 1, w->ww_i.r - 1)) {
122 case 3:
123 goto out;
124 case 2:
125 break;
126 case 1:
127 case 0:
128 continue;
129 }
130 break;
131 }
132 if (!terse)
133 wwputs("\nYank ending position: ", cmdwin);
134 row2 = row1;
135 col2 = col1;
136 for (;;) {
137 wwsetcursor(row2, col2);
138 while (wwpeekc() < 0)
139 wwiomux();
140 r = row2;
141 c = col2;
142 switch (getpos(&row2, &col2, w->ww_i.t, w->ww_i.l,
143 w->ww_i.b - 1, w->ww_i.r - 1)) {
144 case 3:
145 yank_highlight(row1, col1, r, c);
146 goto out;
147 case 2:
148 break;
149 case 1:
150 yank_highlight(row1, col1, r, c);
151 yank_highlight(row1, col1, row2, col2);
152 case 0:
153 continue;
154 }
155 break;
156 }
157 if (row2 < row1 || row2 == row1 && col2 < col1) {
158 r = row1;
159 c = col1;
160 row1 = row2;
161 col1 = col2;
162 row2 = r;
163 col2 = c;
164 }
165 unyank();
166 c = col1;
167 for (r = row1; r < row2; r++) {
168 yank_line(r, c, w->ww_b.r);
169 c = w->ww_b.l;
170 }
171 yank_line(r, c, col2);
172 yank_highlight(row1, col1, row2, col2);
173 if (!terse)
174 wwputc('\n', cmdwin);
175 out:
176 wwcursor(w, 1);
177 }
178
yank_highlight(row1,col1,row2,col2)179 yank_highlight(row1, col1, row2, col2)
180 {
181 struct ww *w = selwin;
182 int r, c;
183
184 if ((wwavailmodes & WWM_REV) == 0)
185 return;
186 if (row2 < row1 || row2 == row1 && col2 < col1) {
187 r = row1;
188 c = col1;
189 row1 = row2;
190 col1 = col2;
191 row2 = r;
192 col2 = c;
193 }
194 c = col1;
195 for (r = row1; r < row2; r++) {
196 yank_highlight_line(r, c, w->ww_b.r);
197 c = w->ww_b.l;
198 }
199 yank_highlight_line(r, c, col2);
200 }
201
yank_highlight_line(r,c,cend)202 yank_highlight_line(r, c, cend)
203 {
204 struct ww *w = selwin;
205 char *win;
206
207 if (r < w->ww_i.t || r >= w->ww_i.b)
208 return;
209 if (c < w->ww_i.l)
210 c = w->ww_i.l;
211 if (cend >= w->ww_i.r)
212 cend = w->ww_i.r;
213 for (win = w->ww_win[r] + c; c < cend; c++, win++) {
214 *win ^= WWM_REV;
215 if (wwsmap[r][c] == w->ww_index) {
216 if (*win == 0)
217 w->ww_nvis[r]++;
218 else if (*win == WWM_REV)
219 w->ww_nvis[r]--;
220 wwns[r][c].c_m ^= WWM_REV;
221 wwtouched[r] |= WWU_TOUCHED;
222 }
223 }
224 }
225
unyank()226 unyank()
227 {
228 struct yb *yp, *yq;
229
230 for (yp = yb_head; yp; yp = yq) {
231 yq = yp->link;
232 str_free(yp->line);
233 free((char *) yp);
234 }
235 yb_head = yb_tail = 0;
236 }
237
yank_line(r,c,cend)238 yank_line(r, c, cend)
239 {
240 struct yb *yp;
241 int nl = 0;
242 int n;
243 union ww_char *bp;
244 char *cp;
245
246 if (c == cend)
247 return;
248 if ((yp = (struct yb *) malloc(sizeof *yp)) == 0)
249 return;
250 yp->link = 0;
251 nl = cend == selwin->ww_b.r;
252 bp = selwin->ww_buf[r];
253 for (cend--; cend >= c; cend--)
254 if (bp[cend].c_c != ' ')
255 break;
256 yp->length = n = cend - c + 1;
257 if (nl)
258 yp->length++;
259 yp->line = str_alloc(yp->length + 1);
260 for (bp += c, cp = yp->line; --n >= 0;)
261 *cp++ = bp++->c_c;
262 if (nl)
263 *cp++ = '\n';
264 *cp = 0;
265 if (yb_head)
266 yb_tail = yb_tail->link = yp;
267 else
268 yb_head = yb_tail = yp;
269 }
270
c_put()271 c_put()
272 {
273 struct yb *yp;
274
275 for (yp = yb_head; yp; yp = yp->link)
276 (void) write(selwin->ww_pty, yp->line, yp->length);
277 }
278