X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/c417b6912b3b10fe62e2d4a14fb7f5b150e5bc8b..d93758100f2a0e2107957c31450a3e9c6bf278b8:/usr/src/usr.bin/window/wwwrite.c diff --git a/usr/src/usr.bin/window/wwwrite.c b/usr/src/usr.bin/window/wwwrite.c index 435203e788..90cf59bfe1 100644 --- a/usr/src/usr.bin/window/wwwrite.c +++ b/usr/src/usr.bin/window/wwwrite.c @@ -1,109 +1,276 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #ifndef lint -static char *sccsid = "@(#)wwwrite.c 1.4 83/07/22"; -#endif +static char sccsid[] = "@(#)wwwrite.c 3.30 (Berkeley) %G%"; +#endif /* not lint */ #include "ww.h" +#include "tt.h" +#include "char.h" -int wwnwrite = 0; +#define UPDATE() \ + if (!w->ww_noupdate && w->ww_cur.r >= 0 && w->ww_cur.r < wwnrow && \ + wwtouched[w->ww_cur.r]) \ + wwupdate1(w->ww_cur.r, w->ww_cur.r + 1) +/* + * To support control character expansion, we save the old + * p and q values in r and s, and point p at the beginning + * of the expanded string, and q at some safe place beyond it + * (p + 10). At strategic points in the loops, we check + * for (r && !*p) and restore the saved values back into + * p and q. Essentially, we implement a stack of depth 2, + * to avoid recursion, which might be a better idea. + */ wwwrite(w, p, n) register struct ww *w; register char *p; -register n; +int n; { - register char c; + char hascursor; + char *savep = p; + char *q = p + n; + char *r = 0; + char *s; - if (w == 0 || w->ww_win == 0) - return -1; - wwnwrite += n; - while (n-- > 0) { - c = *p++ & 0x7f; - switch (w->ww_wstate) { - case 0: - if (c >= ' ' && c < 0x7f) { - if (w->ww_insert) - Winschars(w->ww_win, 1); - Wputc(c, w->ww_win); - break; +#ifdef lint + s = 0; /* define it before possible use */ +#endif + if (hascursor = w->ww_hascursor) + wwcursor(w, 0); + while (p < q && !w->ww_stopped && (!wwinterrupt() || w->ww_nointr)) { + if (r && !*p) { + p = r; + q = s; + r = 0; + continue; + } + if (w->ww_wstate == 0 && + (isprt(*p) || w->ww_unctrl && isunctrl(*p))) { + register i; + register union ww_char *bp; + int col, col1; + + if (w->ww_insert) { /* this is very slow */ + if (*p == '\t') { + p++; + w->ww_cur.c += 8 - + (w->ww_cur.c - w->ww_w.l & 7); + goto chklf; + } + if (!isprt(*p)) { + r = p + 1; + s = q; + p = unctrl(*p); + q = p + 10; + } + wwinschar(w, w->ww_cur.r, w->ww_cur.c, + *p++, w->ww_modes); + goto right; + } + + bp = &w->ww_buf[w->ww_cur.r][w->ww_cur.c]; + i = w->ww_cur.c; + while (i < w->ww_w.r && p < q) + if (!*p && r) { + p = r; + q = s; + r = 0; + } else if (*p == '\t') { + register tmp = 8 - (i - w->ww_w.l & 7); + p++; + i += tmp; + bp += tmp; + } else if (isprt(*p)) { + bp++->c_w = *p++ + | w->ww_modes << WWC_MSHIFT; + i++; + } else if (w->ww_unctrl && isunctrl(*p)) { + r = p + 1; + s = q; + p = unctrl(*p); + q = p + 10; + } else + break; + col = MAX(w->ww_cur.c, w->ww_i.l); + col1 = MIN(i, w->ww_i.r); + w->ww_cur.c = i; + if (w->ww_cur.r >= w->ww_i.t + && w->ww_cur.r < w->ww_i.b) { + register union ww_char *ns = wwns[w->ww_cur.r]; + register char *smap = &wwsmap[w->ww_cur.r][col]; + register char *win = w->ww_win[w->ww_cur.r]; + int nchanged = 0; + + bp = w->ww_buf[w->ww_cur.r]; + for (i = col; i < col1; i++) + if (*smap++ == w->ww_index) { + nchanged++; + ns[i].c_w = bp[i].c_w + ^ win[i] << WWC_MSHIFT; + } + if (nchanged > 0) + wwtouched[w->ww_cur.r] |= WWU_TOUCHED; } - switch (c) { + chklf: + if (w->ww_cur.c >= w->ww_w.r) + goto crlf; + } else switch (w->ww_wstate) { + case 0: + switch (*p++) { case '\n': - Wputc(c, w->ww_win); - if (w->ww_refresh) - Wrefresh(1); + if (w->ww_mapnl) + crlf: + w->ww_cur.c = w->ww_w.l; + lf: + UPDATE(); + if (++w->ww_cur.r >= w->ww_w.b) { + w->ww_cur.r = w->ww_w.b - 1; + if (w->ww_w.b < w->ww_b.b) { + (void) wwscroll1(w, w->ww_i.t, + w->ww_i.b, 1, 0); + w->ww_buf++; + w->ww_b.t--; + w->ww_b.b--; + } else + wwdelline(w, w->ww_b.t); + } break; - case '\t': case '\b': + if (--w->ww_cur.c < w->ww_w.l) { + w->ww_cur.c = w->ww_w.r - 1; + goto up; + } + break; case '\r': - case CTRL(g): - Wputc(c, w->ww_win); + w->ww_cur.c = w->ww_w.l; break; - case CTRL([): + case ctrl('g'): + ttputc(ctrl('g')); + break; + case ctrl('['): w->ww_wstate = 1; break; } break; case 1: w->ww_wstate = 0; - switch (c) { + switch (*p++) { case '@': w->ww_insert = 1; break; case 'A': - Wcurup(w->ww_win, 1); + up: + UPDATE(); + if (--w->ww_cur.r < w->ww_w.t) { + w->ww_cur.r = w->ww_w.t; + if (w->ww_w.t > w->ww_b.t) { + (void) wwscroll1(w, w->ww_i.t, + w->ww_i.b, -1, 0); + w->ww_buf--; + w->ww_b.t++; + w->ww_b.b++; + } else + wwinsline(w, w->ww_b.t); + } break; case 'B': - Wcurdown(w->ww_win, 1); - break; + goto lf; case 'C': - Wcurright(w->ww_win, 1); - break; + right: + w->ww_cur.c++; + goto chklf; case 'E': - WWcursor(w->ww_win, 0, 0); - Wclear(w->ww_win, 2); - /* always refresh */ - Wrefresh(1); + w->ww_buf -= w->ww_w.t - w->ww_b.t; + w->ww_b.t = w->ww_w.t; + w->ww_b.b = w->ww_b.t + w->ww_b.nr; + w->ww_cur.r = w->ww_w.t; + w->ww_cur.c = w->ww_w.l; + wwclreos(w, w->ww_w.t, w->ww_w.l); break; case 'H': - WWcursor(w->ww_win, 0, 0); + UPDATE(); + w->ww_cur.r = w->ww_w.t; + w->ww_cur.c = w->ww_w.l; break; case 'J': - Wclear(w->ww_win, 0); + wwclreos(w, w->ww_cur.r, w->ww_cur.c); break; case 'K': - Wclearline(w->ww_win, 0); + wwclreol(w, w->ww_cur.r, w->ww_cur.c); break; case 'L': - Winslines(w->ww_win, 1); - if (w->ww_refresh) - Wrefresh(1); + UPDATE(); + wwinsline(w, w->ww_cur.r); break; case 'M': - Wdellines(w->ww_win, 1); - if (w->ww_refresh) - Wrefresh(1); + wwdelline(w, w->ww_cur.r); break; case 'N': - Wdelchars(w->ww_win, 1); + wwdelchar(w, w->ww_cur.r, w->ww_cur.c); break; case 'O': w->ww_insert = 0; break; + case 'X': + wwupdate(); + break; case 'Y': + UPDATE(); w->ww_wstate = 2; break; + case 'Z': + wwupdate(); + xxflush(0); + break; + case 's': + w->ww_wstate = 4; + break; + case 'r': + w->ww_wstate = 5; + break; } break; case 2: - WWcursor(w->ww_win, (c - ' ') % w->ww_i.nrow, - w->ww_win->w_cursor.col); - w->ww_wstate++; + w->ww_cur.r = w->ww_w.t + + (unsigned)(*p++ - ' ') % w->ww_w.nr; + w->ww_wstate = 3; break; case 3: - WWcursor(w->ww_win, w->ww_win->w_cursor.row, - (c - ' ') % w->ww_i.ncol); + w->ww_cur.c = w->ww_w.l + + (unsigned)(*p++ - ' ') % w->ww_w.nc; + w->ww_wstate = 0; + break; + case 4: + w->ww_modes |= *p++ & wwavailmodes; + w->ww_wstate = 0; + break; + case 5: + w->ww_modes &= ~*p++; w->ww_wstate = 0; break; } } + if (hascursor) + wwcursor(w, 1); + wwnwwr++; + wwnwwra += n; + n = p - savep; + wwnwwrc += n; + return n; }