Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!bloom-beacon!apple!oliveb!amdahl!drivax!davison From: davison@drivax.DRI (Wayne Davison) Newsgroups: comp.sources.bugs Subject: My screen diffs (part 2 of 2) Message-ID: <4368@drivax.DRI> Date: 8 Mar 89 04:30:12 GMT Reply-To: davison@drivax.UUCP (Wayne Davison) Organization: Digital Research, Inc. Lines: 1233 Part two of the screen diffs. See part 1 for a description. -----------------------------------Cut Here----------------------------------- *** orig/screen.c Wed Feb 8 20:18:38 1989 --- ./screen.c Tue Feb 22 18:49:21 1989 *************** *** 7,13 **** * software, alterations are clearly marked as such, and this notice is * not modified. */ ! static char ScreenVersion[] = "screen 2.0a 19-Oct-88"; #include --- 7,15 ---- * software, alterations are clearly marked as such, and this notice is * not modified. + * + * Modifed by Wayne Davison (...amdhal!drivax!davison) */ ! static char ScreenVersion[] = "screen 2.0wd 22-Feb-89"; #include *************** *** 55,59 **** extern char AnsiVersion[]; extern short ospeed; ! extern flowctl; extern errno; extern sys_nerr; --- 57,61 ---- extern char AnsiVersion[]; extern short ospeed; ! extern flowctl, wrap; extern errno; extern sys_nerr; *************** *** 60,65 **** extern char *sys_errlist[]; extern char *index(), *rindex(), *malloc(), *getenv(), *MakeTermcap(); ! extern char *getlogin(), *ttyname(); ! static AttacherFinit(), Finit(), SigHup(), SigChld(); static char *MakeBellMsg(), *Filename(), **SaveArgs(), *GetTtyName(); --- 62,67 ---- extern char *sys_errlist[]; extern char *index(), *rindex(), *malloc(), *getenv(), *MakeTermcap(); ! extern char *getlogin(), *ttyname(), *ParseChar(); ! static AttacherFinit(), Finit(), SigHup(), SigChld(), SigInt(); static char *MakeBellMsg(), *Filename(), **SaveArgs(), *GetTtyName(); *************** *** 89,93 **** static char *LoginName; static char *BellString = "Bell in window %"; ! static mflag, nflag, fflag, rflag; static char HostName[MAXSTR]; static Detached; --- 91,96 ---- static char *LoginName; static char *BellString = "Bell in window %"; ! static mflag, nflag, fflag, rflag, iflag; ! static intrc, startc, stopc; static char HostName[MAXSTR]; static Detached; *************** *** 128,133 **** } OldMode, NewMode; ! static struct win *curr, *other; ! static CurrNum, OtherNum; static struct win *wtab[MAXWIN]; --- 131,136 ---- } OldMode, NewMode; ! static struct win *curr; ! static CurrNum, WinList = -1; static struct win *wtab[MAXWIN]; *************** *** 159,163 **** #define KEY_QUIT 25 #define KEY_DETACH 26 ! #define KEY_CREATE 27 struct key { --- 162,171 ---- #define KEY_QUIT 25 #define KEY_DETACH 26 ! #define KEY_WRAP 27 ! #define KEY_FLOW 28 ! #define KEY_TOGGLE 29 ! #define KEY_CLEAR 30 ! #define KEY_RESET 31 ! #define KEY_CREATE 255 struct key { *************** *** 171,174 **** --- 179,183 ---- "select4", "select5", "select6", "select7", "select8", "select9", "xon", "xoff", "info", "termcap", "quit", "detach", + "wrap", "flow", "toggle", "clear", "reset", 0 }; *************** *** 176,180 **** main (ac, av) char **av; { register n, len; ! register struct win **pp, *p; char *ap; int s, r, w, x = 0; --- 185,189 ---- main (ac, av) char **av; { register n, len; ! register struct win *p; char *ap; int s, r, w, x = 0; *************** *** 200,206 **** --- 209,223 ---- case 'n': nflag = 1; + flowctl = 1; break; case 'f': fflag = 1; + if (ap[2] != '/') + flowctl = 2; + else + flowctl = 3; + break; + case 'i': + iflag = 1; break; case 'r': *************** *** 220,227 **** ap = *++av; } ! if (strlen (ap) != 2) Msg (0, "Two characters are required with -e option."); - Esc = ap[0]; - MetaEsc = ap[1]; break; default: --- 237,242 ---- ap = *++av; } ! if (!ParseEscape (ap)) Msg (0, "Two characters are required with -e option."); break; default: *************** *** 264,269 **** strcat (SockPath, "/"); SockNamePtr = SockPath + strlen (SockPath); - if ((DevTty = open ("/dev/tty", O_RDWR|O_NDELAY)) == -1) - Msg (errno, "/dev/tty"); if (rflag) { Attach (MSG_ATTACH); --- 279,282 ---- *************** *** 273,280 **** if (GetSockName ()) { s = MakeClientSocket (1); ! SendCreateMsg (s, ac, av, aflag); close (s); exit (0); } switch (fork ()) { case -1: --- 286,295 ---- if (GetSockName ()) { s = MakeClientSocket (1); ! SendCreateMsg (s, ac, av, aflag, flowctl); close (s); exit (0); } + if ((DevTty = open ("/dev/tty", O_RDWR|O_NDELAY)) == -1) + Msg (errno, "/dev/tty"); switch (fork ()) { case -1: *************** *** 290,297 **** ServerSocket = s = MakeServerSocket (); InitTerm (); - if (fflag) - flowctl = 1; - else if (nflag) - flowctl = 0; MakeNewEnv (); GetTTY (0, &OldMode); --- 305,308 ---- *************** *** 302,306 **** #endif signal (SIGHUP, SigHup); ! signal (SIGINT, Finit); signal (SIGQUIT, Finit); signal (SIGTERM, Finit); --- 313,317 ---- #endif signal (SIGHUP, SigHup); ! signal (SIGINT, SigInt); signal (SIGQUIT, Finit); signal (SIGTERM, Finit); *************** *** 310,318 **** sprintf (rc, "%.*s/.screenrc", 245, home); ReadRc (rc); ! if ((n = MakeWindow (*av, av, aflag, 0, (char *)0)) == -1) { ! SetTTY (0, &OldMode); ! FinitTerm (); ! Kill (AttacherPid, SIGHUP); ! exit (1); } SetCurrWindow (n); --- 321,327 ---- sprintf (rc, "%.*s/.screenrc", 245, home); ReadRc (rc); ! if ((n = MakeWindow (*av, av, aflag, flowctl, 0, (char *)0)) == -1) { ! Finit (); ! /*NOTREACHED*/ } SetCurrWindow (n); *************** *** 335,346 **** else r |= 1 << 0; ! for (pp = wtab; pp < wtab+MAXWIN; ++pp) { ! if (!(p = *pp)) ! continue; ! if ((*pp)->active && status) continue; ! if ((*pp)->outlen > 0) continue; ! r |= 1 << (*pp)->ptyfd; } r |= 1 << s; --- 344,354 ---- else r |= 1 << 0; ! for (n = WinList; n != -1; n = p->WinLink) { ! p = wtab[n]; ! if (p->active && status) continue; ! if (p->outlen > 0) continue; ! r |= 1 << p->ptyfd; } r |= 1 << s; *************** *** 351,358 **** } if (select (32, &r, &w, &x, status ? &tv : (struct timeval *)0) == -1) { ! if (errno == EINTR) continue; ! HasWindow = 0; ! Msg (errno, "select"); /*NOTREACHED*/ } --- 359,368 ---- } if (select (32, &r, &w, &x, status ? &tv : (struct timeval *)0) == -1) { ! if (errno == EINTR) { ! errno = 0; continue; ! } ! perror ("select"); ! Finit (); /*NOTREACHED*/ } *************** *** 376,379 **** --- 386,393 ---- if (inlen > 0) inlen = ProcessInput (inbuf, inlen); + else { + perror ("read"); + Finit (); + } if (inlen > 0) continue; *************** *** 393,399 **** continue; } ! for (pp = wtab; pp < wtab+MAXWIN; ++pp) { ! if (!(p = *pp)) ! continue; if (p->outlen) { WriteString (p, p->outbuf, p->outlen); --- 407,412 ---- continue; } ! for (n = WinList; n != -1; n = p->WinLink) { ! p = wtab[n]; if (p->outlen) { WriteString (p, p->outbuf, p->outlen); *************** *** 408,412 **** if (p->bell) { p->bell = 0; ! Msg (0, MakeBellMsg (pp-wtab)); } } --- 421,425 ---- if (p->bell) { p->bell = 0; ! Msg (0, MakeBellMsg (n)); } } *************** *** 432,447 **** } static DoWait () { ! register pid; ! register struct win **pp; union wait wstat; while ((pid = wait3 (&wstat, WNOHANG|WUNTRACED, NULL)) > 0) { ! for (pp = wtab; pp < wtab+MAXWIN; ++pp) { ! if (*pp && pid == (*pp)->wpid) { if (WIFSTOPPED (wstat)) { ! (void) killpg (getpgrp ((*pp)->wpid), SIGCONT); } else { ! KillWindow (pp); } } --- 445,465 ---- } + static SigInt () { + inlen = 0; + write (curr->ptyfd, "\003", 1); + } + static DoWait () { ! register n, next, pid; union wait wstat; while ((pid = wait3 (&wstat, WNOHANG|WUNTRACED, NULL)) > 0) { ! for (n = WinList; n != -1; n = next) { ! next = wtab[n]->WinLink; ! if (pid == wtab[n]->wpid) { if (WIFSTOPPED (wstat)) { ! (void) killpg (getpgrp (wtab[n]->wpid), SIGCONT); } else { ! KillWindow (n); } } *************** *** 451,498 **** } ! static KillWindow (pp) struct win **pp; { ! if (*pp == curr) curr = 0; ! if (*pp == other) ! other = 0; ! FreeWindow (*pp); ! *pp = 0; } static CheckWindows () { ! register struct win **pp; ! ! /* If the current window disappeared and the "other" window is still ! * there, switch to the "other" window, else switch to the window ! * with the lowest index. ! * If there current window is still there, but the "other" window ! * vanished, "SetCurrWindow" is called in order to assign a new value ! * to "other". * If no window is alive at all, exit. */ ! if (!curr && other) { ! SwitchWindow (OtherNum); ! return; ! } ! if (curr && !other) { ! SetCurrWindow (CurrNum); ! return; ! } ! for (pp = wtab; pp < wtab+MAXWIN; ++pp) { ! if (*pp) { ! if (!curr) ! SwitchWindow (pp-wtab); ! return; ! } ! } ! Finit (); } static Finit () { ! register struct win *p, **pp; ! for (pp = wtab; pp < wtab+MAXWIN; ++pp) { ! if (p = *pp) ! FreeWindow (p); } SetTTY (0, &OldMode); --- 469,508 ---- } ! static KillWindow (n) { ! register i; ! ! /* ! * Remove window from linked list. ! */ ! if (n == WinList) { ! WinList = curr->WinLink; curr = 0; ! } else { ! i = WinList; ! while (wtab[i]->WinLink != n) ! i = wtab[i]->WinLink; ! wtab[i]->WinLink = wtab[n]->WinLink; ! } ! FreeWindow (wtab[n]); ! wtab[n] = 0; } static CheckWindows () { ! /* If the current window disappeared check the head of the linked ! * list of windows for the most recently used window. * If no window is alive at all, exit. */ ! if (WinList == -1) ! Finit (); ! if (!curr) ! SwitchWindow (WinList); } static Finit () { ! register n, next; ! for (n = WinList; n != -1; n = next) { ! next = wtab[n]->WinLink; ! FreeWindow (wtab[n]); } SetTTY (0, &OldMode); *************** *** 522,525 **** --- 532,540 ---- ktab[Ctrl('\\')].type = KEY_QUIT; ktab['d'].type = ktab[Ctrl('d')].type = KEY_DETACH; + ktab['r'].type = ktab[Ctrl('r')].type = KEY_WRAP; + ktab['f'].type = ktab[Ctrl('f')].type = KEY_FLOW; + ktab['/'].type = KEY_TOGGLE; + ktab['C'].type = KEY_CLEAR; + ktab['Z'].type = KEY_RESET; ktab[Esc].type = KEY_OTHER; for (i = 0; i <= 9; i++) *************** *** 530,534 **** register n, k; register char *s, *p; - register struct win **pp; for (s = p = buf; len > 0; len--, s++) { --- 545,548 ---- *************** *** 558,562 **** p = buf; if ((n = MakeWindow (ShellProg, ShellArgs, ! 0, 0, (char *)0)) != -1) SwitchWindow (n); break; --- 572,576 ---- p = buf; if ((n = MakeWindow (ShellProg, ShellArgs, ! 0, flowctl, 0, (char *)0)) != -1) SwitchWindow (n); break; *************** *** 573,585 **** case KEY_KILL: p = buf; ! FreeWindow (wtab[CurrNum]); ! if (other == curr) ! other = 0; ! curr = wtab[CurrNum] = 0; CheckWindows (); break; case KEY_QUIT: - for (pp = wtab; pp < wtab+MAXWIN; ++pp) - if (*pp) FreeWindow (*pp); Finit (); /*NOTREACHED*/ --- 587,594 ---- case KEY_KILL: p = buf; ! KillWindow (CurrNum); CheckWindows (); break; case KEY_QUIT: Finit (); /*NOTREACHED*/ *************** *** 590,594 **** case KEY_REDISPLAY: p = buf; ! Activate (wtab[CurrNum]); break; case KEY_WINDOWS: --- 599,603 ---- case KEY_REDISPLAY: p = buf; ! Activate (curr); break; case KEY_WINDOWS: *************** *** 607,611 **** p = buf; if (MoreWindows ()) ! SwitchWindow (OtherNum); break; case KEY_XON: --- 616,620 ---- p = buf; if (MoreWindows ()) ! SwitchWindow (curr->WinLink); break; case KEY_XON: *************** *** 618,624 **** p = buf; if ((n = MakeWindow (ktab[*s].args[0], ktab[*s].args, ! 0, 0, (char *)0)) != -1) SwitchWindow (n); break; } } else ESCseen = 1; --- 627,656 ---- p = buf; if ((n = MakeWindow (ktab[*s].args[0], ktab[*s].args, ! 0, flowctl, 0, (char *)0)) != -1) SwitchWindow (n); break; + case KEY_WRAP: + curr->wrap = !curr->wrap; + Msg (0, "%cwrap", curr->wrap ? '+' : '-'); + break; + case KEY_FLOW: + ToggleFlow (curr); + goto flow_msg; + case KEY_TOGGLE: + if ((curr->toggle = !curr->toggle) != 0 + && curr->flow == curr->keypad) + ToggleFlow (curr); + flow_msg: + Msg (0, "%c%sflow", curr->flow ? '+' : '-', + curr->toggle ? "/" : ""); + break; + case KEY_CLEAR: + if (curr->state == LIT) + WriteString (curr, "\033[2J\033[H", 7); + break; + case KEY_RESET: + if (curr->state == LIT) + WriteString (curr, "\033c", 2); + break; } } else ESCseen = 1; *************** *** 629,636 **** static SwitchWindow (n) { ! if (!wtab[n]) return; SetCurrWindow (n); ! Activate (wtab[n]); } --- 661,670 ---- static SwitchWindow (n) { ! if (!wtab[n]) { ! Msg (0, "No such window."); return; + } SetCurrWindow (n); ! Activate (curr); } *************** *** 637,647 **** static SetCurrWindow (n) { /* ! * If we come from another window, this window becomes the ! * "other" window: */ if (curr) { curr->active = 0; - other = curr; - OtherNum = CurrNum; } CurrNum = n; --- 671,678 ---- static SetCurrWindow (n) { /* ! * If we come from another window, make it inactive. */ if (curr) { curr->active = 0; } CurrNum = n; *************** *** 649,659 **** curr->active = 1; /* ! * If the "other" window is currently undefined (at program start ! * or because it has died), or if the "other" window is equal to the ! * one just selected, we try to find a new one: */ ! if (other == 0 || other == curr) { ! OtherNum = NextWindow (); ! other = wtab[OtherNum]; } } --- 680,691 ---- curr->active = 1; /* ! * Place the window at the head of the most-recently-used list. */ ! if ((n = WinList) != CurrNum) { ! while (wtab[n]->WinLink != CurrNum) ! n = wtab[n]->WinLink; ! wtab[n]->WinLink = curr->WinLink; ! curr->WinLink = WinList; ! WinList = CurrNum; } } *************** *** 684,697 **** static MoreWindows () { ! register struct win **pp; ! register n; ! ! for (n = 0, pp = wtab; pp < wtab+MAXWIN; ++pp) ! if (*pp) ++n; ! if (n <= 1) ! Msg (0, "No other window."); ! return n > 1; } static FreeWindow (wp) struct win *wp; { register i; --- 716,730 ---- static MoreWindows () { ! if (curr->WinLink != -1) ! return 1; ! Msg (0, "No other window."); ! return 0; } + void Free (p) register char *p; { + if (p) + free (p); + } + static FreeWindow (wp) struct win *wp; { register i; *************** *** 702,716 **** close (wp->ptyfd); for (i = 0; i < rows; ++i) { ! free (wp->image[i]); ! free (wp->attr[i]); ! free (wp->font[i]); } ! free (wp->image); ! free (wp->attr); ! free (wp->font); free (wp); } ! static MakeWindow (prog, args, aflag, StartAt, dir) char *prog, **args, *dir; { register struct win **pp, *p; --- 735,750 ---- close (wp->ptyfd); for (i = 0; i < rows; ++i) { ! Free (wp->image[i]); ! Free (wp->attr[i]); ! Free (wp->font[i]); } ! Free (wp->image); ! Free (wp->attr); ! Free (wp->font); ! Free (wp->tabs); free (wp); } ! static MakeWindow (prog, args, aflag, flowflag, StartAt, dir) char *prog, **args, *dir; { register struct win **pp, *p; *************** *** 739,748 **** (void) fcntl (f, F_SETFL, FNDELAY); if ((p = *pp = (struct win *)malloc (sizeof (struct win))) == 0) { nomem: Msg (0, "Out of memory."); return -1; } - if ((p->image = (char **)malloc (rows * sizeof (char *))) == 0) - goto nomem; for (cp = p->image; cp < p->image+rows; ++cp) { if ((*cp = malloc (cols)) == 0) --- 773,800 ---- (void) fcntl (f, F_SETFL, FNDELAY); if ((p = *pp = (struct win *)malloc (sizeof (struct win))) == 0) { + close (f); + Msg (0, "Out of memory."); + return -1; + } + bzero (p, sizeof (struct win)); + p->ptyfd = f; + p->aflag = aflag; + if (!flowflag) + flowflag = flowctl; + p->flow = (flowflag != 1); + p->toggle = (flowflag == 3); + strncpy (p->cmd, Filename (args[0]), MAXSTR-1); + strncpy (p->tty, TtyName, MAXSTR-1); + (void) chown (TtyName, getuid (), getgid ()); + (void) chmod (TtyName, TtyMode); + p->slot = SetUtmp (TtyName); + + if ((p->image = (char **)malloc (rows * sizeof (char *))) == 0) { nomem: + FreeWindow (p); + *pp = 0; Msg (0, "Out of memory."); return -1; } for (cp = p->image; cp < p->image+rows; ++cp) { if ((*cp = malloc (cols)) == 0) *************** *** 767,785 **** goto nomem; ResetScreen (p); - p->aflag = aflag; - p->active = 0; - p->bell = 0; - p->outlen = 0; - p->ptyfd = f; - strncpy (p->cmd, Filename (args[0]), MAXSTR-1); - p->cmd[MAXSTR-1] = '\0'; - strncpy (p->tty, TtyName, MAXSTR-1); - (void) chown (TtyName, getuid (), getgid ()); - (void) chmod (TtyName, TtyMode); - p->slot = SetUtmp (TtyName); switch (p->wpid = fork ()) { case -1: Msg (errno, "fork"); ! free ((char *)p); return -1; case 0: --- 819,826 ---- goto nomem; ResetScreen (p); switch (p->wpid = fork ()) { case -1: Msg (errno, "fork"); ! FreeWindow (p); return -1; case 0: *************** *** 817,820 **** --- 858,869 ---- exit (1); } + /* + * Place the newly created window at the head of the most-recently-used + * list. Since this spot is reserved for the "curr"ent window, you MUST + * call SetCurrWindow (with "n" or "CurrNum") when you finish creating + * your windows. + */ + p->WinLink = WinList; + WinList = n; return n; } *************** *** 910,915 **** register char *s; register struct win **pp, *p; ! for (s = buf, pp = wtab; pp < wtab+MAXWIN; ++pp) { if ((p = *pp) == 0) continue; --- 959,965 ---- register char *s; register struct win **pp, *p; + register i, OtherNum = curr->WinLink; ! for (i = 0, s = buf, pp = wtab; pp < wtab+MAXWIN; ++i, ++pp) { if ((p = *pp) == 0) continue; *************** *** 919,926 **** *s++ = ' '; *s++ = ' '; } ! *s++ = pp - wtab + '0'; ! if (p == curr) *s++ = '*'; ! else if (p == other) *s++ = '-'; *s++ = ' '; --- 969,976 ---- *s++ = ' '; *s++ = ' '; } ! *s++ = i + '0'; ! if (i == CurrNum) *s++ = '*'; ! else if (i == OtherNum) *s++ = '-'; *s++ = ' '; *************** *** 960,965 **** #endif p = buf + strlen (buf); ! sprintf (p, " (%d,%d) %cflow %cins %corg %cwrap %cpad", wp->y, wp->x, ! flowctl ? '+' : '-', wp->insert ? '+' : '-', wp->origin ? '+' : '-', wp->wrap ? '+' : '-', wp->keypad ? '+' : '-'); --- 1010,1015 ---- #endif p = buf + strlen (buf); ! sprintf (p, " (%d,%d) %c%sflow %cins %corg %cwrap %cpad", wp->y, wp->x, ! wp->flow ? '+' : '-', wp->toggle ? "/" : "", wp->insert ? '+' : '-', wp->origin ? '+' : '-', wp->wrap ? '+' : '-', wp->keypad ? '+' : '-'); *************** *** 982,987 **** --- 1032,1042 ---- strcpy (TtyName, TtyProto); for (p = PtyName, i = 0; *p != 'X'; ++p, ++i) ; + #ifdef sequent + for (l = "p"; *p = *l; ++l) { /*}*/ + for (d = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; p[1] = *d; ++d) { /*}*/ + #else for (l = "qpr"; *p = *l; ++l) { for (d = "0123456789abcdef"; p[1] = *d; ++d) { + #endif if ((f = open (PtyName, O_RDWR)) != -1) { TtyName[i] = p[0]; *************** *** 1016,1024 **** static SetMode (op, np) struct mode *op, *np; { *np = *op; np->m_ttyb.sg_flags &= ~(CRMOD|ECHO); np->m_ttyb.sg_flags |= CBREAK; - np->m_tchars.t_intrc = -1; np->m_tchars.t_quitc = -1; ! if (!flowctl) { np->m_tchars.t_startc = -1; np->m_tchars.t_stopc = -1; --- 1071,1085 ---- static SetMode (op, np) struct mode *op, *np; { *np = *op; + startc = op->m_tchars.t_startc; + stopc = op->m_tchars.t_stopc; + if (iflag) + intrc = op->m_tchars.t_intrc; + else + intrc = np->m_tchars.t_intrc = -1; np->m_ttyb.sg_flags &= ~(CRMOD|ECHO); np->m_ttyb.sg_flags |= CBREAK; np->m_tchars.t_quitc = -1; ! if (flowctl == 1) { ! np->m_tchars.t_intrc = -1; np->m_tchars.t_startc = -1; np->m_tchars.t_stopc = -1; *************** *** 1030,1033 **** --- 1091,1107 ---- } + SetFlow (on) { + if (on) { + NewMode.m_tchars.t_intrc = intrc; + NewMode.m_tchars.t_startc = startc; + NewMode.m_tchars.t_stopc = stopc; + } else { + NewMode.m_tchars.t_intrc = -1; + NewMode.m_tchars.t_startc = -1; + NewMode.m_tchars.t_stopc = -1; + } + ioctl (0, TIOCSETC, &NewMode.m_tchars); + } + static char *GetTtyName () { register char *p; *************** *** 1103,1106 **** --- 1177,1181 ---- static Attacher () { signal (SIGHUP, AttacherFinit); + signal (SIGINT, SIG_IGN); signal (SIGCONT, ReAttach); while (1) *************** *** 1109,1113 **** static Detach (suspend) { ! register struct win **pp; if (Detached) --- 1184,1188 ---- static Detach (suspend) { ! register n; if (Detached) *************** *** 1117,1124 **** FinitTerm (); if (suspend) { Kill (AttacherPid, SIGTSTP); } else { ! for (pp = wtab; pp < wtab+MAXWIN; ++pp) ! if (*pp) RemoveUtmp ((*pp)->slot); printf ("\n[detached]\n"); Kill (AttacherPid, SIGHUP); --- 1192,1200 ---- FinitTerm (); if (suspend) { + (void) fflush (stdout); Kill (AttacherPid, SIGTSTP); } else { ! for (n = WinList; n != -1; n = wtab[n]->WinLink) ! RemoveUtmp (wtab[n]->slot); printf ("\n[detached]\n"); Kill (AttacherPid, SIGHUP); *************** *** 1129,1132 **** --- 1205,1209 ---- close (2); ioctl (DevTty, TIOCNOTTY, (char *)0); + close (DevTty); Detached = 1; do { *************** *** 1133,1139 **** ReceiveMsg (ServerSocket); } while (Detached); if (!suspend) ! for (pp = wtab; pp < wtab+MAXWIN; ++pp) ! if (*pp) (*pp)->slot = SetUtmp ((*pp)->tty); signal (SIGHUP, SigHup); } --- 1210,1218 ---- ReceiveMsg (ServerSocket); } while (Detached); + if ((DevTty = open ("/dev/tty", O_RDWR|O_NDELAY)) == -1) + Msg (errno, "/dev/tty"); if (!suspend) ! for (n = WinList; n != -1; n = wtab[n]->WinLink) ! wtab[n]->slot = SetUtmp (wtab[n]->tty); signal (SIGHUP, SigHup); } *************** *** 1205,1209 **** } ! static SendCreateMsg (s, ac, av, aflag) char **av; { struct msg m; register char *p; --- 1284,1288 ---- } ! static SendCreateMsg (s, ac, av, aflag, flowflag) char **av; { struct msg m; register char *p; *************** *** 1221,1224 **** --- 1300,1304 ---- m.m.create.nargs = n; m.m.create.aflag = aflag; + m.m.create.flowflag = flowflag; if (getwd (m.m.create.dir) == 0) Msg (0, "%s", m.m.create.dir); *************** *** 1274,1278 **** if (Detached) { if (kill (m.m.attach.apid, 0) == 0 && ! open (m.m.attach.tty, O_RDWR) == 0) { (void) dup (0); (void) dup (0); --- 1354,1358 ---- if (Detached) { if (kill (m.m.attach.apid, 0) == 0 && ! open (m.m.attach.tty, O_RDWR|O_NDELAY) == 0) { (void) dup (0); (void) dup (0); *************** *** 1282,1286 **** SetMode (&OldMode, &NewMode); SetTTY (0, &NewMode); ! Activate (wtab[CurrNum]); } } else { --- 1362,1366 ---- SetMode (&OldMode, &NewMode); SetTTY (0, &NewMode); ! Activate (curr); } } else { *************** *** 1307,1312 **** } *pp = 0; ! if ((n = MakeWindow (mp->m.create.line, args, mp->m.create.aflag, 0, ! mp->m.create.dir)) != -1) SwitchWindow (n); } --- 1387,1392 ---- } *pp = 0; ! if ((n = MakeWindow (mp->m.create.line, args, mp->m.create.aflag, ! mp->m.create.flowflag, 0, mp->m.create.dir)) != -1) SwitchWindow (n); } *************** *** 1318,1322 **** char buf[256]; char *args[MAXARGS]; ! int key; ap = args; --- 1398,1402 ---- char buf[256]; char *args[MAXARGS]; ! char key, flowflag; ap = args; *************** *** 1331,1339 **** continue; if (strcmp (ap[0], "escape") == 0) { ! p = ap[1]; ! if (argc < 2 || strlen (p) != 2) Msg (0, "%s: two characters required after escape.", fn); ! Esc = *p++; ! MetaEsc = *p; } else if (strcmp (ap[0], "chdir") == 0) { p = argc < 2 ? home : ap[1]; --- 1411,1417 ---- continue; if (strcmp (ap[0], "escape") == 0) { ! if (argc < 2 || !ParseEscape (ap[1])) Msg (0, "%s: two characters required after escape.", fn); ! ktab[Esc].type = KEY_OTHER; } else if (strcmp (ap[0], "chdir") == 0) { p = argc < 2 ? home : ap[1]; *************** *** 1354,1358 **** --- 1432,1485 ---- strcpy (BellString, ap[1]); } + } else if (strcmp (ap[0], "wrap") == 0) { + num = 0; + if (argc == 2 && ap[1][0] == 'o') { + if (ap[1][1] == 'f') + num = 1; + else if (ap[1][1] == 'n') + num = 2; + } + if (!num) { + Msg (0, "%s: wrap: invalid argument.", fn); + } else { + wrap = num-1; + } + } else if (strcmp (ap[0], "flow") == 0) { + flowflag = 0; + if (argc == 2) { + if (ap[1][0] == 'o') { + if (ap[1][1] == 'f') + flowflag = 1; + else if (ap[1][1] == 'n') + flowflag = 2; + } else if (ap[1][0] == 't') + flowflag = 3; + } + if (!flowflag) { + Msg (0, "%s: flow: invalid argument.", fn); + } else { + flowctl = flowflag; + } } else if (strcmp (ap[0], "screen") == 0) { + flowflag = flowctl; + while (argc > 1 && ap[1][0] == '-') { + switch (ap[1][1]) { + case 'n': + flowflag = 1; + break; + case 'f': + if (ap[1][2] != '/') + flowflag = 2; + else + flowflag = 3; + break; + case 'a': + break; + default: + Msg (0, "%s: screen: invalid option -%c.", fn, ap[1][1]); + break; + } + --argc; ++ap; + } num = 0; if (argc > 1 && IsNum (ap[1], 10)) { *************** *** 1366,1370 **** } ap[argc] = 0; ! (void) MakeWindow (ap[1], ap+1, 0, num, (char *)0); } else if (strcmp (ap[0], "bind") == 0) { p = ap[1]; --- 1493,1497 ---- } ap[argc] = 0; ! (void) MakeWindow (ap[1], ap+1, 0, flowflag, num, (char *)0); } else if (strcmp (ap[0], "bind") == 0) { p = ap[1]; *************** *** 1371,1386 **** if (argc < 2 || *p == '\0') Msg (0, "%s: key expected after bind.", fn); ! if (p[1] == '\0') { ! key = *p; ! } else if (p[0] == '^' && p[1] != '\0' && p[2] == '\0') { ! c = p[1]; ! if (isupper (c)) ! p[1] = tolower (c); ! key = Ctrl(c); ! } else if (IsNum (p, 7)) { ! (void) sscanf (p, "%o", &key); ! } else { Msg (0, ! "%s: bind: character, ^x, or octal number expected.", fn); } if (argc < 3) { --- 1498,1504 ---- if (argc < 2 || *p == '\0') Msg (0, "%s: key expected after bind.", fn); ! if (!(p = ParseChar (p, &key)) || *p) { Msg (0, ! "%s: bind: character, ^x, or (octal) \\032 expected.", fn); } if (argc < 3) { *************** *** 1430,1433 **** --- 1548,1576 ---- } + static int ParseEscape (p) char *p; { + if (!(p = ParseChar (p, &Esc)) || !(p = ParseChar (p, &MetaEsc)) || *p) + return 0; + return 1; + } + + static char *ParseChar (p, cp) char *p, *cp; { + if (*p == '^') { + if (*++p == '?') + *cp = '\177'; + else if (*p >= '@') + *cp = Ctrl(*p); + else + return 0; + ++p; + } else if (*p == '\\' && *++p <= '7' && *p >= '0') { + *cp = 0; + do + *cp = *cp * 8 + *p - '0'; + while (*++p <= '7' && *p >= '0'); + } else + *cp = *p++; + return p; + } + static char **SaveArgs (argc, argv) register argc; register char **argv; { register char **ap, **pp; *************** *** 1459,1463 **** break; if (!IsSymbol (*op, "TERM") && !IsSymbol (*op, "TERMCAP") ! && !IsSymbol (*op, "STY")) *np++ = *op; } --- 1602,1606 ---- break; if (!IsSymbol (*op, "TERM") && !IsSymbol (*op, "TERMCAP") ! && !IsSymbol (*op, "STY") && !IsSymbol (*op, "WINDOW")) *np++ = *op; } *** orig/screen.h Wed Feb 8 20:19:02 1989 --- ./screen.h Fri Feb 17 16:46:27 1989 *************** *** 43,47 **** char tty[MAXSTR]; int args[MAXARGS]; - char GotArg[MAXARGS]; int NumArgs; int slot; --- 43,46 ---- *************** *** 72,75 **** --- 71,77 ---- int vbwait; int bell; + int flow; + int toggle; + int WinLink; }; *************** *** 86,89 **** --- 88,92 ---- struct { int aflag; + int flowflag; int nargs; char line[MAXLINE]; -----------------------------------Cut Here----------------------------------- Wayne Davison ...amdahl!drivax!davison