insert mode bug fix and cleanup
[unix-history] / usr / src / usr.bin / window / wwinit.c
index a9b21a4..be9bfcb 100644 (file)
@@ -1,6 +1,23 @@
+/*
+ * 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
 #ifndef lint
-static char *sccsid = "@(#)wwinit.c    3.17 84/04/08";
-#endif
+static char sccsid[] = "@(#)wwinit.c   3.35 (Berkeley) %G%";
+#endif /* not lint */
 
 #include "ww.h"
 #include "tt.h"
 
 #include "ww.h"
 #include "tt.h"
@@ -12,22 +29,19 @@ wwinit()
 {
        register i, j;
        char *kp;
 {
        register i, j;
        char *kp;
-       register char **p, **q;
-       char **env, **termcap;
-       extern char **environ;
+       int s;
 
 
-#ifndef O_4_1A
        wwdtablesize = getdtablesize();
        wwdtablesize = getdtablesize();
-#else
-#include <sys/param.h>
-       wwdtablesize = NOFILE;
-#endif
        wwhead.ww_forw = &wwhead;
        wwhead.ww_back = &wwhead;
 
        wwhead.ww_forw = &wwhead;
        wwhead.ww_back = &wwhead;
 
-       if (signal(SIGIO, wwrint) == BADSIG)
+       s = sigblock(sigmask(SIGIO));
+       if (signal(SIGIO, wwrint) == BADSIG ||
+           signal(SIGCHLD, wwchild) == BADSIG ||
+           signal(SIGPIPE, SIG_IGN) == BADSIG) {
+               wwerrno = WWE_SYS;
                return -1;
                return -1;
-       (void) sighold(SIGIO);
+       }
 
        if (wwgettty(0, &wwoldtty) < 0)
                return -1;
 
        if (wwgettty(0, &wwoldtty) < 0)
                return -1;
@@ -53,8 +67,7 @@ wwinit()
        wwnewtty.ww_lmode = wwoldtty.ww_lmode | LLITOUT;
        wwnewtty.ww_ldisc = wwoldtty.ww_ldisc;
        wwnewtty.ww_fflags = wwoldtty.ww_fflags | FASYNC;
        wwnewtty.ww_lmode = wwoldtty.ww_lmode | LLITOUT;
        wwnewtty.ww_ldisc = wwoldtty.ww_ldisc;
        wwnewtty.ww_fflags = wwoldtty.ww_fflags | FASYNC;
-
-       if (wwsettty(0, &wwnewtty) < 0)
+       if (wwsettty(0, &wwnewtty, &wwoldtty) < 0)
                goto bad;
 
        if ((wwterm = getenv("TERM")) == 0) {
                goto bad;
 
        if ((wwterm = getenv("TERM")) == 0) {
@@ -67,13 +80,12 @@ wwinit()
        }
        wwbaud = wwbaudmap[wwoldtty.ww_sgttyb.sg_ospeed];
 
        }
        wwbaud = wwbaudmap[wwoldtty.ww_sgttyb.sg_ospeed];
 
-       if (ttinit() < 0)
+       if (xxinit() < 0)
                goto bad;
        wwnrow = tt.tt_nrow;
        wwncol = tt.tt_ncol;
        wwavailmodes = tt.tt_availmodes;
        wwwrap = tt.tt_wrap;
                goto bad;
        wwnrow = tt.tt_nrow;
        wwncol = tt.tt_ncol;
        wwavailmodes = tt.tt_availmodes;
        wwwrap = tt.tt_wrap;
-       (*tt.tt_init)();
 
        if (wwavailmodes & WWM_REV)
                wwcursormodes = WWM_REV | wwavailmodes & WWM_BLK;
 
        if (wwavailmodes & WWM_REV)
                wwcursormodes = WWM_REV | wwavailmodes & WWM_BLK;
@@ -114,63 +126,79 @@ wwinit()
        for (i = 0; i < wwnrow; i++)
                wwtouched[i] = 0;
 
        for (i = 0; i < wwnrow; i++)
                wwtouched[i] = 0;
 
+       wwupd = (struct ww_update *) malloc((unsigned) wwnrow * sizeof *wwupd);
+       if (wwupd == 0) {
+               wwerrno = WWE_NOMEM;
+               goto bad;
+       }
+
        wwindex[WWX_NOBODY] = &wwnobody;
        wwnobody.ww_order = NWW;
 
        wwindex[WWX_NOBODY] = &wwnobody;
        wwnobody.ww_order = NWW;
 
-       kp = wwkeys;
-       addcap("kb", &kp);
-       addcap("ku", &kp);
-       addcap("kd", &kp);
-       addcap("kl", &kp);
-       addcap("kr", &kp);
-       addcap("kh", &kp);
+       kp = wwwintermcap;
+       if (wwavailmodes & WWM_REV)
+               wwaddcap1(WWT_REV, &kp);
+       if (wwavailmodes & WWM_BLK)
+               wwaddcap1(WWT_BLK, &kp);
+       if (wwavailmodes & WWM_UL)
+               wwaddcap1(WWT_UL, &kp);
+       if (wwavailmodes & WWM_GRP)
+               wwaddcap1(WWT_GRP, &kp);
+       if (wwavailmodes & WWM_DIM)
+               wwaddcap1(WWT_DIM, &kp);
+       if (wwavailmodes & WWM_USR)
+               wwaddcap1(WWT_USR, &kp);
+       if (tt.tt_insline && tt.tt_delline || tt.tt_setscroll)
+               wwaddcap1(WWT_ALDL, &kp);
+       if (tt.tt_inschar || tt.tt_insspace)
+               wwaddcap1(WWT_IMEI, &kp);
+       if (tt.tt_delchar)
+               wwaddcap1(WWT_DC, &kp);
+       wwaddcap("kb", &kp);
+       wwaddcap("ku", &kp);
+       wwaddcap("kd", &kp);
+       wwaddcap("kl", &kp);
+       wwaddcap("kr", &kp);
+       wwaddcap("kh", &kp);
        if ((j = tgetnum("kn")) >= 0) {
                char cap[32];
        if ((j = tgetnum("kn")) >= 0) {
                char cap[32];
-               int i;
 
                (void) sprintf(kp, "kn#%d:", j);
                for (; *kp; kp++)
                        ;
                for (i = 1; i <= j; i++) {
                        (void) sprintf(cap, "k%d", i);
 
                (void) sprintf(kp, "kn#%d:", j);
                for (; *kp; kp++)
                        ;
                for (i = 1; i <= j; i++) {
                        (void) sprintf(cap, "k%d", i);
-                       addcap(cap, &kp);
+                       wwaddcap(cap, &kp);
                        cap[0] = 'l';
                        cap[0] = 'l';
-                       addcap(cap, &kp);
+                       wwaddcap(cap, &kp);
                }
        }
                }
        }
-       for (i = 0, p = environ; *p++; i++)
-               ;
-       if ((env = (char **)malloc((unsigned)(i + 3) * sizeof (char *))) == 0)
-               goto bad;
-       for (p = environ, q = env; *p; p++, q++) {
-               if (strncmp(*p, "TERM=", 5) == 0)
-                       *q = WWT_TERM;
-               else if (strncmp(*p, "TERMCAP=", 8) == 0)
-                       termcap = q;
-               else
-                       *q = *p;
-       }
-       *(termcap ? termcap : q++) = wwwintermcap;
-       *q = 0;
-       environ = env;
+       /*
+        * It's ok to do this here even if setenv() is destructive
+        * since tt_init() has already made its own copy of it and
+        * wwterm now points to the copy.
+        */
+       (void) setenv("TERM", WWT_TERM, 1);
 
 
-       (void) sigrelse(SIGIO);
+       (void) sigsetmask(s);
+       /* catch typeahead before ASYNC was set */
+       (void) kill(getpid(), SIGIO);
+       xxstart();
        return 0;
 bad:
        /*
         * Don't bother to free storage.  We're supposed
         * to exit when wwinit fails anyway.
         */
        return 0;
 bad:
        /*
         * Don't bother to free storage.  We're supposed
         * to exit when wwinit fails anyway.
         */
-       (void) wwsettty(0, &wwoldtty);
+       (void) wwsettty(0, &wwoldtty, &wwnewtty);
        (void) signal(SIGIO, SIG_DFL);
        (void) signal(SIGIO, SIG_DFL);
-       (void) sigrelse(SIGIO);
+       (void) sigsetmask(s);
        return -1;
 }
 
        return -1;
 }
 
-static
-addcap(cap, kp)
-register char *cap;
-register char **kp;
+wwaddcap(cap, kp)
+       register char *cap;
+       register char **kp;
 {
        char tbuf[512];
        char *tp = tbuf;
 {
        char tbuf[512];
        char *tp = tbuf;
@@ -189,3 +217,12 @@ register char **kp;
                **kp = 0;
        }
 }
                **kp = 0;
        }
 }
+
+wwaddcap1(cap, kp)
+       register char *cap;
+       register char **kp;
+{
+       while (*(*kp)++ = *cap++)
+               ;
+       (*kp)--;
+}