From ef5c6a6edaf3dcf2cddd46841dc0dd8fce2bf967 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Fri, 3 Sep 2010 10:21:16 -0400 Subject: 9term, win: better echo cancellation Also just drop \r from output. It's a losing battle to keep turning it off. R=rsc http://codereview.appspot.com/2128042 --- src/cmd/9term/9term.c | 14 +++++----- src/cmd/9term/SunOS.c | 19 ------------- src/cmd/9term/bsdpty.c | 23 ---------------- src/cmd/9term/rcstart.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++-- src/cmd/9term/term.h | 4 ++- src/cmd/9term/win.c | 58 ++++++++++++++++++++++++++++++++------- 6 files changed, 129 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/cmd/9term/9term.c b/src/cmd/9term/9term.c index 92b253d3..806215df 100644 --- a/src/cmd/9term/9term.c +++ b/src/cmd/9term/9term.c @@ -22,7 +22,6 @@ int plumbfd; int rcpid; int rcfd; int sfd; -int noecho; Window *w; char *fontname; @@ -412,6 +411,9 @@ rcoutputproc(void *arg) fprint(2, "9term: rc read error: %r\n"); threadexitsall("eof on rc output"); } + n = echocancel(data+cnt, n); + if(n == 0) + continue; cnt += n; r = runemalloc(cnt); cvttorunes(data, cnt-UTFmax, r, &nb, &nr, nil); @@ -428,7 +430,7 @@ rcoutputproc(void *arg) nr = label(r, nr); if(nr == 0) continue; - + recv(w->conswrite, &cwm); pair.s = r; pair.ns = nr; @@ -499,7 +501,6 @@ void rcinputproc(void *arg) { static char data[9000]; - int s; Consreadmesg crm; Channel *c1, *c2; Stringpair pair; @@ -513,12 +514,11 @@ rcinputproc(void *arg) pair.ns = sizeof data; send(c1, &pair); recv(c2, &pair); - - s = setecho(sfd, 0); + + if(isecho(sfd)) + echoed(pair.s, pair.ns); if(write(rcfd, pair.s, pair.ns) < 0) threadexitsall(nil); - if(s) - setecho(sfd, s); } } diff --git a/src/cmd/9term/SunOS.c b/src/cmd/9term/SunOS.c index ac1432de..e0f866ab 100644 --- a/src/cmd/9term/SunOS.c +++ b/src/cmd/9term/SunOS.c @@ -77,25 +77,6 @@ isecho(int fd) return (ttmode.c_lflag&ICANON && ttmode.c_lflag&ECHO); } -int -setecho(int fd, int newe) -{ - int old; - - if(tcgetattr(fd, &ttmode) < 0) - fprint(2, "tcgetattr: %r\n"); - old = (ttmode.c_lflag&ECHO)==ECHO; - if(old != newe){ - if(newe) - ttmode.c_lflag |= ECHO; - else - ttmode.c_lflag &= ~ECHO; - if(tcsetattr(fd, TCSANOW, &ttmode) < 0) - fprint(2, "tcsetattr: %r\n"); - } - return old; -} - int getintr(int fd) { diff --git a/src/cmd/9term/bsdpty.c b/src/cmd/9term/bsdpty.c index 52b9bb8a..4836d24d 100644 --- a/src/cmd/9term/bsdpty.c +++ b/src/cmd/9term/bsdpty.c @@ -96,29 +96,6 @@ isecho(int fd) return ttmode.c_lflag&ECHO; } -int -setecho(int fd, int newe) -{ - int old; - - if(tcgetattr(fd, &ttmode) < 0) - fprint(2, "tcgetattr: %r\n"); - old = ttmode.c_lflag & ECHO; - if(old != newe){ - ttmode.c_lflag &= ~ECHO; - ttmode.c_lflag |= newe; - /* - * I tried using TCSADRAIN here, but that causes - * hangs if there is any output waiting for us. - * I guess TCSADRAIN is intended for use by our - * clients, not by us. - */ - if(tcsetattr(fd, 0, &ttmode) < 0) - fprint(2, "tcsetattr: %r\n"); - } - return old; -} - int getintr(int fd) { diff --git a/src/cmd/9term/rcstart.c b/src/cmd/9term/rcstart.c index 4d64349c..6b91c869 100644 --- a/src/cmd/9term/rcstart.c +++ b/src/cmd/9term/rcstart.c @@ -87,8 +87,6 @@ rcstart(int argc, char **argv, int *pfd, int *tfd) dup(sfd, 2); sys("stty tabs -onlcr icanon echo erase '^h' intr '^?'", 0); sys("stty onocr", 1); /* not available on mac */ - if(noecho) - sys("stty -echo", 0); for(i=3; i<100; i++) close(i); signal(SIGINT, SIG_DFL); @@ -111,3 +109,73 @@ rcstart(int argc, char **argv, int *pfd, int *tfd) return pid; } +struct { + Lock l; + char buf[1<<20]; + int r, w; +} echo; + +void +echoed(char *p, int n) +{ + lock(&echo.l); + if(echo.r > 0) { + memmove(echo.buf, echo.buf+echo.r, echo.w-echo.r); + echo.w -= echo.r; + echo.r = 0; + } + if(echo.w+n > sizeof echo.buf) + echo.r = echo.w = 0; + if(echo.w+n > sizeof echo.buf) + n = 0; + memmove(echo.buf+echo.w, p, n); + echo.w += n; + unlock(&echo.l); +} + +int +echocancel(char *p, int n) +{ + int i; + + lock(&echo.l); + for(i=0; i 0) + memmove(p, p+i, n-i); + return n-i; +} + +int +dropcrnl(char *p, int n) +{ + char *r, *w; + + for(r=w=p; r #include "term.h" -int noecho = 1; #define EVENTSIZE 256 #define STACK 32768 @@ -71,6 +70,7 @@ void sende(Event*, int, CFid*, CFid*, CFid*, int); char *onestring(int, char**); int delete(Event*); void deltype(uint, uint); +void sendbs(int, int); void runproc(void*); int @@ -349,6 +349,7 @@ stdinproc(void *v) CFid *afd = addrfd; int fd0 = rcfd; Event e, e2, e3, e4; + int n; USED(v); @@ -411,7 +412,10 @@ stdinproc(void *v) break; case 'D': - q.p -= delete(&e); + n = delete(&e); + q.p -= n; + if(!isecho(fd0)) + sendbs(fd0, n); break; case 'x': @@ -491,6 +495,14 @@ stdoutproc(void *v) n = read(fd1, buf+npart, 8192); if(n <= 0) error(nil); + + n = echocancel(buf+npart, n); + if(n == 0) + continue; + + n = dropcrnl(buf+npart, n); + if(n == 0) + continue; /* squash NULs */ s = memchr(buf+npart, 0, n); @@ -525,8 +537,10 @@ stdoutproc(void *v) qlock(&q.lk); m = sprint(x, "#%d", q.p); if(fswrite(afd, x, m) != m){ - fprint(2, "stdout writing address: %r; resetting\n"); - fswrite(afd, "$", 1); + fprint(2, "stdout writing address %s: %r; resetting\n", x); + if(fswrite(afd, "$", 1) < 0) + fprint(2, "reset: %r\n"); + fsseek(afd, 0, 0); m = fsread(afd, x, sizeof x-1); if(m >= 0){ x[m] = 0; @@ -660,13 +674,18 @@ addtype(int c, uint p0, char *b, int nb, int nr) void sendtype(int fd0) { - int i, n, nr; - - while(ntypebreak){ + int i, n, nr, raw; + + raw = !isecho(fd0); + while(ntypebreak || (raw && ntypeb > 0)){ for(i=0; i 0) + ntypebreak--; n = i+1; i++; + if(isecho(fd0)) + echoed(typing, n); if(write(fd0, typing, n) != n) error("sending to program"); nr = nrunes(typing, i); @@ -674,7 +693,6 @@ sendtype(int fd0) ntyper -= nr; ntypeb -= i; memmove(typing, typing+i, ntypeb); - ntypebreak--; goto cont2; } print("no breakchar\n"); @@ -683,6 +701,22 @@ cont2:; } } +void +sendbs(int fd0, int n) +{ + char buf[128]; + int m; + + memset(buf, 0x08, sizeof buf); + while(n > 0) { + m = sizeof buf; + if(m > n) + m = n; + n -= m; + write(fd0, buf, m); + } +} + void deltype(uint p0, uint p1) { @@ -738,6 +772,12 @@ type(Event *e, int fd0, CFid *afd, CFid *dfd) m += nr; } } + if(!isecho(fd0)) { + n = sprint(buf, "#%d,#%d", e->q0, e->q1); + fswrite(afd, buf, n); + fswrite(dfd, "", 0); + q.p -= e->q1 - e->q0; + } sendtype(fd0); } -- cgit v1.2.3