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
c_size(w)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
c_yank()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
yank_highlight(row1,col1,row2,col2)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
yank_highlight_line(r,c,cend)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
unyank()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
yank_line(r,c,cend)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
c_put()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