insert mode bug fix and cleanup
[unix-history] / usr / src / usr.bin / window / wwinit.c
index 0624298..be9bfcb 100644 (file)
+/*
+ * 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    1.3 83/07/18";
-#endif
+static char sccsid[] = "@(#)wwinit.c   3.35 (Berkeley) %G%";
+#endif /* not lint */
 
 #include "ww.h"
 
 #include "ww.h"
-
-struct ww_tty wwoldtty;
-struct ww_tty wwnewtty = {
-       { 0, 0, -1, -1, 0 },
-       { -1, -1, -1, -1, -1, -1 },
-       { -1, -1, -1, -1, -1, -1 },
-       0, 0, 0
-};
+#include "tt.h"
+#include <sys/signal.h>
+#include <fcntl.h>
+#include "char.h"
 
 wwinit()
 {
 
 wwinit()
 {
-       static char done = 0;
+       register i, j;
+       char *kp;
+       int s;
+
+       wwdtablesize = getdtablesize();
+       wwhead.ww_forw = &wwhead;
+       wwhead.ww_back = &wwhead;
+
+       s = sigblock(sigmask(SIGIO));
+       if (signal(SIGIO, wwrint) == BADSIG ||
+           signal(SIGCHLD, wwchild) == BADSIG ||
+           signal(SIGPIPE, SIG_IGN) == BADSIG) {
+               wwerrno = WWE_SYS;
+               return -1;
+       }
 
 
-       if (done)
-               return 0;
-       done++;
        if (wwgettty(0, &wwoldtty) < 0)
                return -1;
        if (wwgettty(0, &wwoldtty) < 0)
                return -1;
-       wwnewtty.ww_sgttyb.sg_flags = wwoldtty.ww_sgttyb.sg_flags;
-       wwnewtty.ww_sgttyb.sg_ispeed = wwoldtty.ww_sgttyb.sg_ispeed;
-       wwnewtty.ww_sgttyb.sg_ospeed = wwoldtty.ww_sgttyb.sg_ospeed;
-       wwnewtty.ww_lmode = wwoldtty.ww_lmode;
-       wwnewtty.ww_pgrp = wwoldtty.ww_pgrp;
-       wwnewtty.ww_ldisc = wwoldtty.ww_ldisc;
+       wwwintty = wwoldtty;
+       wwwintty.ww_sgttyb.sg_flags &= ~XTABS;
+       wwnewtty.ww_sgttyb = wwoldtty.ww_sgttyb;
+       wwnewtty.ww_sgttyb.sg_erase = -1;
+       wwnewtty.ww_sgttyb.sg_kill = -1;
        wwnewtty.ww_sgttyb.sg_flags |= CBREAK;
        wwnewtty.ww_sgttyb.sg_flags &= ~(ECHO|CRMOD);
        wwnewtty.ww_sgttyb.sg_flags |= CBREAK;
        wwnewtty.ww_sgttyb.sg_flags &= ~(ECHO|CRMOD);
-       wwnewtty.ww_lmode |= LLITOUT;
-       wwnewtty.ww_tchars.t_quitc = wwoldtty.ww_tchars.t_quitc;
-       if (wwsettty(0, &wwnewtty) < 0)
-               return -1;
-       if (Winit(2, 1) != 0)
-               return -1;
-       WSetRealCursor = 1;
+       wwnewtty.ww_tchars.t_intrc = -1;
+       wwnewtty.ww_tchars.t_quitc = -1;
+       wwnewtty.ww_tchars.t_startc = -1;
+       wwnewtty.ww_tchars.t_stopc = -1;
+       wwnewtty.ww_tchars.t_eofc = -1;
+       wwnewtty.ww_tchars.t_brkc = -1;
+       wwnewtty.ww_ltchars.t_suspc = -1;
+       wwnewtty.ww_ltchars.t_dsuspc = -1;
+       wwnewtty.ww_ltchars.t_rprntc = -1;
+       wwnewtty.ww_ltchars.t_flushc = -1;
+       wwnewtty.ww_ltchars.t_werasc = -1;
+       wwnewtty.ww_ltchars.t_lnextc = -1;
+       wwnewtty.ww_lmode = wwoldtty.ww_lmode | LLITOUT;
+       wwnewtty.ww_ldisc = wwoldtty.ww_ldisc;
+       wwnewtty.ww_fflags = wwoldtty.ww_fflags | FASYNC;
+       if (wwsettty(0, &wwnewtty, &wwoldtty) < 0)
+               goto bad;
+
+       if ((wwterm = getenv("TERM")) == 0) {
+               wwerrno = WWE_BADTERM;
+               goto bad;
+       }
+       if (tgetent(wwtermcap, wwterm) != 1) {
+               wwerrno = WWE_BADTERM;
+               goto bad;
+       }
+       wwbaud = wwbaudmap[wwoldtty.ww_sgttyb.sg_ospeed];
+
+       if (xxinit() < 0)
+               goto bad;
+       wwnrow = tt.tt_nrow;
+       wwncol = tt.tt_ncol;
+       wwavailmodes = tt.tt_availmodes;
+       wwwrap = tt.tt_wrap;
+
+       if (wwavailmodes & WWM_REV)
+               wwcursormodes = WWM_REV | wwavailmodes & WWM_BLK;
+       else if (wwavailmodes & WWM_UL)
+               wwcursormodes = WWM_UL;
+
+       if ((wwib = malloc((unsigned) 512)) == 0)
+               goto bad;
+       wwibe = wwib + 512;
+       wwibq = wwibp = wwib;
+
+       if ((wwsmap = wwalloc(0, 0, wwnrow, wwncol, sizeof (char))) == 0)
+               goto bad;
+       for (i = 0; i < wwnrow; i++)
+               for (j = 0; j < wwncol; j++)
+                       wwsmap[i][j] = WWX_NOBODY;
+
+       wwos = (union ww_char **)
+               wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
+       if (wwos == 0)
+               goto bad;
+       for (i = 0; i < wwnrow; i++)
+               for (j = 0; j < wwncol; j++)
+                       wwos[i][j].c_w = ' ';
+       wwns = (union ww_char **)
+               wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char));
+       if (wwns == 0)
+               goto bad;
+       for (i = 0; i < wwnrow; i++)
+               for (j = 0; j < wwncol; j++)
+                       wwns[i][j].c_w = ' ';
+
+       wwtouched = malloc((unsigned) wwnrow);
+       if (wwtouched == 0) {
+               wwerrno = WWE_NOMEM;
+               goto bad;
+       }
+       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;
+
+       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];
+
+               (void) sprintf(kp, "kn#%d:", j);
+               for (; *kp; kp++)
+                       ;
+               for (i = 1; i <= j; i++) {
+                       (void) sprintf(cap, "k%d", i);
+                       wwaddcap(cap, &kp);
+                       cap[0] = 'l';
+                       wwaddcap(cap, &kp);
+               }
+       }
+       /*
+        * 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) sigsetmask(s);
+       /* catch typeahead before ASYNC was set */
+       (void) kill(getpid(), SIGIO);
+       xxstart();
        return 0;
        return 0;
+bad:
+       /*
+        * Don't bother to free storage.  We're supposed
+        * to exit when wwinit fails anyway.
+        */
+       (void) wwsettty(0, &wwoldtty, &wwnewtty);
+       (void) signal(SIGIO, SIG_DFL);
+       (void) sigsetmask(s);
+       return -1;
+}
+
+wwaddcap(cap, kp)
+       register char *cap;
+       register char **kp;
+{
+       char tbuf[512];
+       char *tp = tbuf;
+       register char *str, *p;
+
+       if ((str = tgetstr(cap, &tp)) != 0) {
+               while (*(*kp)++ = *cap++)
+                       ;
+               (*kp)[-1] = '=';
+               while (*str) {
+                       for (p = unctrl(*str++); *(*kp)++ = *p++;)
+                               ;
+                       (*kp)--;
+               }
+               *(*kp)++ = ':';
+               **kp = 0;
+       }
+}
+
+wwaddcap1(cap, kp)
+       register char *cap;
+       register char **kp;
+{
+       while (*(*kp)++ = *cap++)
+               ;
+       (*kp)--;
 }
 }