diff options
-rw-r--r-- | src/cmd/9term/9term.c | 19 | ||||
-rw-r--r-- | src/cmd/9term/Darwin.c | 12 | ||||
-rw-r--r-- | src/cmd/9term/FreeBSD.c | 12 | ||||
-rw-r--r-- | src/cmd/9term/Linux.c | 17 | ||||
-rw-r--r-- | src/cmd/9term/OpenBSD.c | 13 | ||||
-rw-r--r-- | src/cmd/9term/SunOS.c | 84 | ||||
-rw-r--r-- | src/cmd/9term/rcstart.c | 20 | ||||
-rw-r--r-- | src/cmd/9term/term.h | 4 | ||||
-rw-r--r-- | src/cmd/9term/win.c | 2 |
9 files changed, 173 insertions, 10 deletions
diff --git a/src/cmd/9term/9term.c b/src/cmd/9term/9term.c index 2923deea..852e7dac 100644 --- a/src/cmd/9term/9term.c +++ b/src/cmd/9term/9term.c @@ -124,6 +124,7 @@ int scrolling; /* window scrolls */ int clickmsec; /* time of last click */ uint clickq0; /* point of last click */ int rcfd; +int sfd; /* slave fd, to get/set terminal mode */ int rcpid; int maxtab; int use9wm; @@ -223,7 +224,7 @@ threadmain(int argc, char *argv[]) mc = initmouse(nil, screen); kc = initkeyboard(nil); - rcpid = rcstart(argc, argv, &rcfd); + rcpid = rcstart(argc, argv, &rcfd, &sfd); hoststart(); plumbstart(); @@ -270,6 +271,10 @@ hangupnote(void *a, char *msg) postnote(PNGROUP, rcpid, "hangup"); noted(NDFLT); } + if(strstr(msg, "child")){ + /* bug: do better */ + exits(0); + } noted(NDFLT); } @@ -284,6 +289,8 @@ hostproc(void *arg) i = 0; for(;;){ /* Let typing have a go -- maybe there's a rubout waiting. */ + yield(); + i = 1-i; /* toggle */ n = threadread(rcfd, rcbuf[i].data, sizeof rcbuf[i].data); if(n <= 0){ @@ -828,6 +835,7 @@ key(Rune r) return; } + rawon = israw(sfd); if(rawon && t.q0==t.nr){ addraw(&r, 1); consread(); @@ -837,6 +845,7 @@ key(Rune r) if(r==ESC || (holdon && r==0x7F)){ /* toggle hold */ holdon = !holdon; drawhold(holdon); + // replaceintegerproperty("_9WM_HOLD_MODE", 1, 32, holdon); if(!holdon) consread(); if(r==ESC) @@ -918,6 +927,7 @@ consready(void) if(holdon) return 0; + rawon = israw(sfd); if(rawon) return t.nraw != 0; @@ -936,6 +946,7 @@ consread(void) { char buf[8000], *p; int c, width, n; + int echo; for(;;) { if(!consready()) @@ -954,13 +965,18 @@ consread(void) c = *p; p += width; n -= width; + rawon = israw(sfd); if(!rawon && (c == '\n' || c == '\004' || c == '\x7F')) break; } /* take out control-d when not doing a zero length write */ n = p-buf; + if(0) fprint(2, "write buf\n"); + /* temporarily disable echo for buf. sensitive to race? Axel. */ + // echo = setecho(sfd, 0); if(write(rcfd, buf, n) < 0) exits(0); + // setecho(sfd, echo); /* mallocstats(); */ } } @@ -1242,6 +1258,7 @@ paste(Rune *r, int n, int advance) { Rune *rbuf; + rawon = israw(sfd); if(rawon && t.q0==t.nr){ addraw(r, n); return; diff --git a/src/cmd/9term/Darwin.c b/src/cmd/9term/Darwin.c index 38212d6b..8fff13f8 100644 --- a/src/cmd/9term/Darwin.c +++ b/src/cmd/9term/Darwin.c @@ -133,3 +133,15 @@ myopenpty(int fd[], char *name) } +int +israw(int fd) +{ + return 0; +} + +int +setecho(int fd, int on) +{ + return 0; +} + diff --git a/src/cmd/9term/FreeBSD.c b/src/cmd/9term/FreeBSD.c index 89f7c7b6..75a97a4a 100644 --- a/src/cmd/9term/FreeBSD.c +++ b/src/cmd/9term/FreeBSD.c @@ -44,3 +44,15 @@ updatewinsize(int row, int col, int dx, int dy) ows = ws; } +int +israw(int fd) +{ + return 0; +} + +int +setecho(int fd, int on) +{ + return 0; +} + diff --git a/src/cmd/9term/Linux.c b/src/cmd/9term/Linux.c index 872417e6..823344c9 100644 --- a/src/cmd/9term/Linux.c +++ b/src/cmd/9term/Linux.c @@ -44,3 +44,20 @@ updatewinsize(int row, int col, int dx, int dy) ows = ws; } + +int +israw(int fd) +{ + return 0; +/* + if(tcgetattr(fd, &ttmode) < 0) + fprint(2, "tcgetattr: %r\n"); + return !(ttmode.c_lflag&(ICANON|ECHO)); +*/ +} + +int +setecho(int fd, int on) +{ + return 0; +} diff --git a/src/cmd/9term/OpenBSD.c b/src/cmd/9term/OpenBSD.c index 7f18bb43..e4753de2 100644 --- a/src/cmd/9term/OpenBSD.c +++ b/src/cmd/9term/OpenBSD.c @@ -44,3 +44,16 @@ updatewinsize(int row, int col, int dx, int dy) fprint(2, "ioctl: %r\n"); ows = ws; } + +int +israw(int fd) +{ + return 0; +} + +int +setecho(int fd, int on) +{ + return 0; +} + diff --git a/src/cmd/9term/SunOS.c b/src/cmd/9term/SunOS.c index d9104ed7..25228344 100644 --- a/src/cmd/9term/SunOS.c +++ b/src/cmd/9term/SunOS.c @@ -1,6 +1,6 @@ #include <u.h> #include <termios.h> -#include <sys/termios.h> +#include <stropts.h> #include <libc.h> #include "term.h" @@ -11,8 +11,17 @@ getpts(int fd[], char *slave) if ((grantpt(fd[1]) < 0) || (unlockpt(fd[1]) < 0)) return -1; fchmod(fd[1], 0622); + strcpy(slave, ptsname(fd[1])); - fd[0] = open(slave, OREAD); + + fd[0] = open(slave, ORDWR); + if(fd[0] < 0) + sysfatal("open %s: %r\n", slave); + + /* set up the right streams modules for a tty */ + ioctl(fd[0], I_PUSH, "ptem"); /* push ptem */ + ioctl(fd[0], I_PUSH, "ldterm"); /* push ldterm */ + return 0; } @@ -42,7 +51,76 @@ updatewinsize(int row, int col, int dx, int dy) ws.ws_ypixel = dy; if(ws.ws_row != ows.ws_row || ws.ws_col != ows.ws_col) if(ioctl(rcfd, TIOCSWINSZ, &ws) < 0) - fprint(2, "ioctl: %r\n"); + fprint(2, "ioctl TIOCSWINSZ: %r\n"); ows = ws; } +/* + * israw has been inspired by Matty Farrow's 9term. + * The code below is probably a gross simplification -- + * for the few cases tested it seems to be enough. + * However, for example, Matty's code also looks at ISIG, + * whereas, we do not (yet?). Axel. + * + *Note: I guess only the get/set terminal mode attribute + * code needs to be here; the logic around it could be + * elswhere (9term.c) - but if the code below is split, + * the question is what a nice interface would be. Axel. + */ + +static struct termios ttmode; + +int +israw(int fd) +{ + int e, c, i; + + tcgetattr(fd, &ttmode); + c = (ttmode.c_lflag & ICANON) ? 1 : 0; + e = (ttmode.c_lflag & ECHO) ? 1 : 0; + i = (ttmode.c_lflag & ISIG) ? 1 : 0; + + if(0) fprint(2, "israw: icanon=%d echo=%d isig=%d\n", c, e, i); + + return !c || !e ; +} + + +int +setecho(int fd, int on) +{ + int e, c, i; + int oldecho; + + tcgetattr(fd, &ttmode); + c = (ttmode.c_lflag & ICANON) ? 1 : 0; + e = (ttmode.c_lflag & ECHO) ? 1 : 0; + i = (ttmode.c_lflag & ISIG) ? 1 : 0; + + if(0) fprint(2, "setecho(%d) pre: icanon=%d echo=%d isig=%d\n", on, c, e, i); + + oldecho = e; + + if (oldecho == on) + return oldecho; + + if (on) { + ttmode.c_lflag |= ECHO; + tcsetattr(fd, TCSANOW, &ttmode); + } else { + ttmode.c_lflag &= ~ECHO; + tcsetattr(fd, TCSANOW, &ttmode); + } + + if (0){ + tcgetattr(fd, &ttmode); + c = (ttmode.c_lflag & ICANON) ? 1 : 0; + e = (ttmode.c_lflag & ECHO) ? 1 : 0; + i = (ttmode.c_lflag & ISIG) ? 1 : 0; + + fprint(2, "setecho(%d) post: icanon=%d echo=%d isig=%d\n", on, c, e, i); + } + + return oldecho; +} + diff --git a/src/cmd/9term/rcstart.c b/src/cmd/9term/rcstart.c index ec168e99..499c5918 100644 --- a/src/cmd/9term/rcstart.c +++ b/src/cmd/9term/rcstart.c @@ -1,11 +1,21 @@ #include <u.h> #include <libc.h> +#if 0 +#include <sys/wait.h> +#endif +#include <signal.h> #include "term.h" +/* + * Somehow we no longer automatically exit + * when the shell exits; hence the SIGCHLD stuff. + * Something that can be fixed? Axel. + */ +static int pid; + int -rcstart(int argc, char **argv, int *pfd) +rcstart(int argc, char **argv, int *pfd, int *tfd) { - int pid; int fd[2]; char *xargv[3]; char slave[256]; @@ -27,7 +37,6 @@ rcstart(int argc, char **argv, int *pfd) if(getpts(fd, slave) < 0) sysfatal("getpts: %r\n"); - switch(pid = fork()) { case 0: putenv("TERM", "9term"); @@ -44,8 +53,11 @@ rcstart(int argc, char **argv, int *pfd) sysfatal("proc failed: %r"); break; } - close(fd[0]); *pfd = fd[1]; + if(tfd) + *tfd = fd[0]; + else + close(fd[0]); return pid; } diff --git a/src/cmd/9term/term.h b/src/cmd/9term/term.h index a608b7ed..c35ff4a7 100644 --- a/src/cmd/9term/term.h +++ b/src/cmd/9term/term.h @@ -2,4 +2,6 @@ extern int getpts(int[], char*); extern int childpty(int[], char*); extern void updatewinsize(int, int, int, int); extern int rcfd; -extern int rcstart(int, char*[], int*); +extern int rcstart(int, char*[], int*, int*); +extern int israw(int); +extern int setecho(int, int); diff --git a/src/cmd/9term/win.c b/src/cmd/9term/win.c index d5dbef2c..0e1fd8a6 100644 --- a/src/cmd/9term/win.c +++ b/src/cmd/9term/win.c @@ -161,7 +161,7 @@ threadmain(int argc, char **argv) cwait = threadwaitchan(); threadcreate(waitthread, nil, STACK); - pid = rcstart(argc, argv, &rcfd); + pid = rcstart(argc, argv, &rcfd, nil); if(pid == -1) sysfatal("exec failed"); |