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