1 /* @(#)cmd7.c 8.1 (Berkeley) 6/6/93 */ 2 /* $NetBSD: cmd7.c,v 1.8 2006/05/02 22:30:25 christos 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 #include <stdlib.h> 37 #include <unistd.h> 38 #include "defs.h" 39 #include "window_string.h" 40 41 void unyank(void); 42 void yank_highlight(int, int, int, int); 43 void yank_highlight_line(int, int, int); 44 void yank_line(int, int, int); 45 46 /* 47 * Window size. 48 */ 49 void 50 c_size(struct ww *w) 51 { 52 int col, row; 53 54 if (!terse) 55 wwputs("New window size (lower right corner): ", cmdwin); 56 col = MIN(w->ww_w.r, wwncol) - 1; 57 row = MIN(w->ww_w.b, wwnrow) - 1; 58 wwadd(boxwin, framewin->ww_back); 59 for (;;) { 60 wwbox(boxwin, w->ww_w.t - 1, w->ww_w.l - 1, 61 row - w->ww_w.t + 3, col - w->ww_w.l + 3); 62 wwsetcursor(row, col); 63 while (wwpeekc() < 0) 64 wwiomux(); 65 switch (getpos(&row, &col, w->ww_w.t, w->ww_w.l, 66 wwnrow - 1, wwncol - 1)) { 67 case 3: 68 wwunbox(boxwin); 69 wwdelete(boxwin); 70 return; 71 case 2: 72 wwunbox(boxwin); 73 break; 74 case 1: 75 wwunbox(boxwin); 76 case 0: 77 continue; 78 } 79 break; 80 } 81 wwdelete(boxwin); 82 if (!terse) 83 wwputc('\n', cmdwin); 84 wwcurtowin(cmdwin); 85 sizewin(w, row - w->ww_w.t + 1, col - w->ww_w.l + 1); 86 } 87 88 /* 89 * Yank and put 90 */ 91 92 struct yb { 93 char *line; 94 int length; 95 struct yb *link; 96 }; 97 struct yb *yb_head, *yb_tail; 98 99 void 100 c_yank(void) 101 { 102 struct ww *w = selwin; 103 int col1, row1; 104 int col2, row2; 105 int r, c; 106 107 if (!terse) 108 wwputs("Yank starting position: ", cmdwin); 109 wwcursor(w, 0); 110 row1 = w->ww_cur.r; 111 col1 = w->ww_cur.c; 112 for (;;) { 113 wwsetcursor(row1, col1); 114 while (wwpeekc() < 0) 115 wwiomux(); 116 switch (getpos(&row1, &col1, w->ww_i.t, w->ww_i.l, 117 w->ww_i.b - 1, w->ww_i.r - 1)) { 118 case 3: 119 goto out; 120 case 2: 121 break; 122 case 1: 123 case 0: 124 continue; 125 } 126 break; 127 } 128 if (!terse) 129 wwputs("\nYank ending position: ", cmdwin); 130 row2 = row1; 131 col2 = col1; 132 for (;;) { 133 wwsetcursor(row2, col2); 134 while (wwpeekc() < 0) 135 wwiomux(); 136 r = row2; 137 c = col2; 138 switch (getpos(&row2, &col2, w->ww_i.t, w->ww_i.l, 139 w->ww_i.b - 1, w->ww_i.r - 1)) { 140 case 3: 141 yank_highlight(row1, col1, r, c); 142 goto out; 143 case 2: 144 break; 145 case 1: 146 yank_highlight(row1, col1, r, c); 147 yank_highlight(row1, col1, row2, col2); 148 case 0: 149 continue; 150 } 151 break; 152 } 153 if (row2 < row1 || (row2 == row1 && col2 < col1)) { 154 r = row1; 155 c = col1; 156 row1 = row2; 157 col1 = col2; 158 row2 = r; 159 col2 = c; 160 } 161 unyank(); 162 c = col1; 163 for (r = row1; r < row2; r++) { 164 yank_line(r, c, w->ww_b.r); 165 c = w->ww_b.l; 166 } 167 yank_line(r, c, col2); 168 yank_highlight(row1, col1, row2, col2); 169 if (!terse) 170 wwputc('\n', cmdwin); 171 out: 172 wwcursor(w, 1); 173 } 174 175 void 176 yank_highlight(int row1, int col1, int row2, int col2) 177 { 178 struct ww *w = selwin; 179 int r, c; 180 181 if ((wwavailmodes & WWM_REV) == 0) 182 return; 183 if (row2 < row1 || (row2 == row1 && col2 < col1)) { 184 r = row1; 185 c = col1; 186 row1 = row2; 187 col1 = col2; 188 row2 = r; 189 col2 = c; 190 } 191 c = col1; 192 for (r = row1; r < row2; r++) { 193 yank_highlight_line(r, c, w->ww_b.r); 194 c = w->ww_b.l; 195 } 196 yank_highlight_line(r, c, col2); 197 } 198 199 void 200 yank_highlight_line(int r, int c, int cend) 201 { 202 struct ww *w = selwin; 203 char *win; 204 205 if (r < w->ww_i.t || r >= w->ww_i.b) 206 return; 207 if (c < w->ww_i.l) 208 c = w->ww_i.l; 209 if (cend >= w->ww_i.r) 210 cend = w->ww_i.r; 211 for (win = w->ww_win[r] + c; c < cend; c++, win++) { 212 *win ^= WWM_REV; 213 if (wwsmap[r][c] == w->ww_index) { 214 if (*win == 0) 215 w->ww_nvis[r]++; 216 else if (*win == WWM_REV) 217 w->ww_nvis[r]--; 218 wwns[r][c].c_m ^= WWM_REV; 219 wwtouched[r] |= WWU_TOUCHED; 220 } 221 } 222 } 223 224 void 225 unyank(void) 226 { 227 struct yb *yp, *yq; 228 229 for (yp = yb_head; yp; yp = yq) { 230 yq = yp->link; 231 str_free(yp->line); 232 free((char *) yp); 233 } 234 yb_head = yb_tail = NULL; 235 } 236 237 void 238 yank_line(int r, int c, int 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)) == NULL) 249 return; 250 yp->link = NULL; 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 if ((yp->line = str_alloc(yp->length + 1)) == NULL) { 260 free(yp); 261 return; 262 } 263 for (bp += c, cp = yp->line; --n >= 0;) 264 *cp++ = bp++->c_c; 265 if (nl) 266 *cp++ = '\n'; 267 *cp = 0; 268 if (yb_head) 269 yb_tail = yb_tail->link = yp; 270 else 271 yb_head = yb_tail = yp; 272 } 273 274 void 275 c_put(void) 276 { 277 struct yb *yp; 278 279 for (yp = yb_head; yp; yp = yp->link) 280 (void) write(selwin->ww_pty, yp->line, yp->length); 281 } 282