| Commit | Line | Data |
|---|---|---|
| 2c872e05 | 1 | /* @(#)wwinit.c 8.2 (Berkeley) 4/28/95 */ |
| abecab39 SW |
2 | /* $NetBSD: wwinit.c,v 1.19 2009/04/14 08:50:06 lukem Exp $ */ |
| 3 | ||
| 984263bc MD |
4 | /* |
| 5 | * Copyright (c) 1983, 1993 | |
| 6 | * The Regents of the University of California. All rights reserved. | |
| 7 | * | |
| 8 | * This code is derived from software contributed to Berkeley by | |
| 9 | * Edward Wang at The University of California, Berkeley. | |
| 10 | * | |
| 11 | * Redistribution and use in source and binary forms, with or without | |
| 12 | * modification, are permitted provided that the following conditions | |
| 13 | * are met: | |
| 14 | * 1. Redistributions of source code must retain the above copyright | |
| 15 | * notice, this list of conditions and the following disclaimer. | |
| 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 17 | * notice, this list of conditions and the following disclaimer in the | |
| 18 | * documentation and/or other materials provided with the distribution. | |
| abecab39 | 19 | * 3. Neither the name of the University nor the names of its contributors |
| 984263bc MD |
20 | * may be used to endorse or promote products derived from this software |
| 21 | * without specific prior written permission. | |
| 22 | * | |
| 23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
| 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
| 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 33 | * SUCH DAMAGE. | |
| 34 | */ | |
| 35 | ||
| 984263bc | 36 | #include <fcntl.h> |
| abecab39 SW |
37 | #include <signal.h> |
| 38 | #include <stdlib.h> | |
| 7a2e9d59 | 39 | #include <stdio.h> |
| 984263bc | 40 | #include <termcap.h> |
| 7a2e9d59 SW |
41 | #include "ww.h" |
| 42 | #include "tt.h" | |
| abecab39 | 43 | #include "xx.h" |
| 984263bc MD |
44 | #include "char.h" |
| 45 | ||
| abecab39 SW |
46 | int |
| 47 | wwinit(void) | |
| 984263bc | 48 | { |
| abecab39 | 49 | int i, j; |
| 984263bc | 50 | char *kp; |
| abecab39 | 51 | sigset_t nsigset, osigset; |
| 984263bc | 52 | |
| abecab39 | 53 | wwdtablesize = 3; |
| 984263bc MD |
54 | wwhead.ww_forw = &wwhead; |
| 55 | wwhead.ww_back = &wwhead; | |
| 56 | ||
| abecab39 SW |
57 | sigemptyset(&nsigset); |
| 58 | sigaddset(&nsigset, SIGCHLD); | |
| 59 | sigaddset(&nsigset, SIGALRM); | |
| 60 | sigaddset(&nsigset, SIGHUP); | |
| 61 | sigaddset(&nsigset, SIGTERM); | |
| 62 | sigprocmask(SIG_BLOCK, &nsigset, &osigset); | |
| 63 | ||
| 64 | if (signal(SIGCHLD, wwchild) == SIG_ERR || | |
| 65 | signal(SIGHUP, wwquit) == SIG_ERR || | |
| 66 | signal(SIGTERM, wwquit) == SIG_ERR || | |
| 67 | signal(SIGPIPE, SIG_IGN) == SIG_ERR) { | |
| 984263bc MD |
68 | wwerrno = WWE_SYS; |
| 69 | return -1; | |
| 70 | } | |
| 71 | ||
| 72 | if (wwgettty(0, &wwoldtty) < 0) | |
| 73 | return -1; | |
| 74 | wwwintty = wwoldtty; | |
| 75 | #ifdef OLD_TTY | |
| 76 | wwwintty.ww_sgttyb.sg_flags &= ~XTABS; | |
| 77 | wwnewtty.ww_sgttyb = wwoldtty.ww_sgttyb; | |
| 78 | wwnewtty.ww_sgttyb.sg_erase = -1; | |
| 79 | wwnewtty.ww_sgttyb.sg_kill = -1; | |
| 80 | wwnewtty.ww_sgttyb.sg_flags |= CBREAK; | |
| 81 | wwnewtty.ww_sgttyb.sg_flags &= ~(ECHO|CRMOD); | |
| 82 | wwnewtty.ww_tchars.t_intrc = -1; | |
| 83 | wwnewtty.ww_tchars.t_quitc = -1; | |
| 84 | wwnewtty.ww_tchars.t_startc = -1; | |
| 85 | wwnewtty.ww_tchars.t_stopc = -1; | |
| 86 | wwnewtty.ww_tchars.t_eofc = -1; | |
| 87 | wwnewtty.ww_tchars.t_brkc = -1; | |
| 88 | wwnewtty.ww_ltchars.t_suspc = -1; | |
| 89 | wwnewtty.ww_ltchars.t_dsuspc = -1; | |
| 90 | wwnewtty.ww_ltchars.t_rprntc = -1; | |
| 91 | wwnewtty.ww_ltchars.t_flushc = -1; | |
| 92 | wwnewtty.ww_ltchars.t_werasc = -1; | |
| 93 | wwnewtty.ww_ltchars.t_lnextc = -1; | |
| 94 | wwnewtty.ww_lmode = wwoldtty.ww_lmode | LLITOUT; | |
| 95 | wwnewtty.ww_ldisc = wwoldtty.ww_ldisc; | |
| 96 | #else | |
| 97 | #ifndef OXTABS | |
| 98 | #define OXTABS XTABS | |
| 99 | #endif | |
| 100 | #ifndef _POSIX_VDISABLE | |
| 101 | #define _POSIX_VDISABLE -1 | |
| 102 | #endif | |
| 103 | wwwintty.ww_termios.c_oflag &= ~OXTABS; | |
| abecab39 SW |
104 | wwwintty.ww_termios.c_cflag &= ~CLOCAL; |
| 105 | wwwintty.ww_termios.c_cflag |= HUPCL; | |
| 984263bc MD |
106 | wwnewtty.ww_termios = wwoldtty.ww_termios; |
| 107 | wwnewtty.ww_termios.c_iflag &= | |
| 108 | ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IMAXBEL); | |
| 109 | wwnewtty.ww_termios.c_oflag = 0; | |
| 110 | wwnewtty.ww_termios.c_cflag &= ~(CSIZE | PARENB); | |
| 111 | wwnewtty.ww_termios.c_cflag |= CS8; | |
| 112 | wwnewtty.ww_termios.c_lflag = 0; | |
| 113 | for (i = 0; i < NCCS; i++) | |
| 114 | wwnewtty.ww_termios.c_cc[i] = _POSIX_VDISABLE; | |
| abecab39 | 115 | wwnewtty.ww_termios.c_cc[VMIN] = 1; |
| 984263bc MD |
116 | wwnewtty.ww_termios.c_cc[VTIME] = 0; |
| 117 | #endif | |
| 984263bc MD |
118 | if (wwsettty(0, &wwnewtty) < 0) |
| 119 | goto bad; | |
| 120 | ||
| 121 | if ((wwterm = getenv("TERM")) == 0) { | |
| 122 | wwerrno = WWE_BADTERM; | |
| 123 | goto bad; | |
| 124 | } | |
| 125 | if (tgetent(wwtermcap, wwterm) != 1) { | |
| 126 | wwerrno = WWE_BADTERM; | |
| 127 | goto bad; | |
| 128 | } | |
| 129 | #ifdef OLD_TTY | |
| abecab39 SW |
130 | wwospeed = wwoldtty.ww_sgttyb.sg_ospeed; |
| 131 | #else | |
| 132 | wwospeed = cfgetospeed(&wwoldtty.ww_termios); | |
| 133 | wwbaud = wwospeed; | |
| 134 | #endif | |
| 135 | switch (wwospeed) { | |
| 984263bc MD |
136 | default: |
| 137 | case B0: | |
| abecab39 SW |
138 | wwbaud = 9600; |
| 139 | break; | |
| 984263bc MD |
140 | case B50: |
| 141 | wwbaud = 50; | |
| 142 | break; | |
| 143 | case B75: | |
| 144 | wwbaud = 75; | |
| 145 | break; | |
| 146 | case B110: | |
| 147 | wwbaud = 110; | |
| 148 | break; | |
| 149 | case B134: | |
| 150 | wwbaud = 134; | |
| 151 | break; | |
| 152 | case B150: | |
| 153 | wwbaud = 150; | |
| 154 | break; | |
| 155 | case B200: | |
| 156 | wwbaud = 200; | |
| 157 | break; | |
| 158 | case B300: | |
| 159 | wwbaud = 300; | |
| 160 | break; | |
| 161 | case B600: | |
| 162 | wwbaud = 600; | |
| 163 | break; | |
| 164 | case B1200: | |
| 165 | wwbaud = 1200; | |
| 166 | break; | |
| 167 | case B1800: | |
| 168 | wwbaud = 1800; | |
| 169 | break; | |
| 170 | case B2400: | |
| 171 | wwbaud = 2400; | |
| 172 | break; | |
| 173 | case B4800: | |
| 174 | wwbaud = 4800; | |
| 175 | break; | |
| 176 | case B9600: | |
| 177 | wwbaud = 9600; | |
| 178 | break; | |
| 179 | #ifdef B19200 | |
| 180 | case B19200: | |
| 181 | #else | |
| 182 | case EXTA: | |
| 183 | #endif | |
| 184 | wwbaud = 19200; | |
| 185 | break; | |
| 186 | #ifdef B38400 | |
| 187 | case B38400: | |
| 188 | #else | |
| 189 | case EXTB: | |
| 190 | #endif | |
| 191 | wwbaud = 38400; | |
| 192 | break; | |
| 193 | #ifdef B57600 | |
| 194 | case B57600: | |
| 195 | wwbaud = 57600; | |
| 196 | break; | |
| 197 | #endif | |
| 198 | #ifdef B115200 | |
| 199 | case B115200: | |
| 200 | wwbaud = 115200; | |
| 201 | break; | |
| 202 | #endif | |
| 203 | } | |
| 984263bc MD |
204 | |
| 205 | if (xxinit() < 0) | |
| 206 | goto bad; | |
| 207 | wwnrow = tt.tt_nrow; | |
| 208 | wwncol = tt.tt_ncol; | |
| 209 | wwavailmodes = tt.tt_availmodes; | |
| 210 | wwwrap = tt.tt_wrap; | |
| 211 | ||
| 212 | if (wwavailmodes & WWM_REV) | |
| abecab39 | 213 | wwcursormodes = WWM_REV | (wwavailmodes & WWM_BLK); |
| 984263bc MD |
214 | else if (wwavailmodes & WWM_UL) |
| 215 | wwcursormodes = WWM_UL; | |
| 216 | ||
| 217 | if ((wwib = malloc((unsigned) 512)) == 0) | |
| 218 | goto bad; | |
| 219 | wwibe = wwib + 512; | |
| 220 | wwibq = wwibp = wwib; | |
| 221 | ||
| abecab39 SW |
222 | wwsmap = (unsigned char **) |
| 223 | wwalloc(0, 0, wwnrow, wwncol, sizeof (unsigned char)); | |
| 224 | if (wwsmap == 0) | |
| 984263bc MD |
225 | goto bad; |
| 226 | for (i = 0; i < wwnrow; i++) | |
| 227 | for (j = 0; j < wwncol; j++) | |
| 228 | wwsmap[i][j] = WWX_NOBODY; | |
| 229 | ||
| 230 | wwos = (union ww_char **) | |
| 231 | wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char)); | |
| 232 | if (wwos == 0) | |
| 233 | goto bad; | |
| 234 | /* wwos is cleared in wwstart1() */ | |
| 235 | wwns = (union ww_char **) | |
| 236 | wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char)); | |
| 237 | if (wwns == 0) | |
| 238 | goto bad; | |
| 239 | for (i = 0; i < wwnrow; i++) | |
| 240 | for (j = 0; j < wwncol; j++) | |
| 241 | wwns[i][j].c_w = ' '; | |
| 242 | if (tt.tt_checkpoint) { | |
| 243 | /* wwcs is also cleared in wwstart1() */ | |
| 244 | wwcs = (union ww_char **) | |
| 245 | wwalloc(0, 0, wwnrow, wwncol, sizeof (union ww_char)); | |
| 246 | if (wwcs == 0) | |
| 247 | goto bad; | |
| 248 | } | |
| 249 | ||
| 250 | wwtouched = malloc((unsigned) wwnrow); | |
| 251 | if (wwtouched == 0) { | |
| 252 | wwerrno = WWE_NOMEM; | |
| 253 | goto bad; | |
| 254 | } | |
| 255 | for (i = 0; i < wwnrow; i++) | |
| 256 | wwtouched[i] = 0; | |
| 257 | ||
| 258 | wwupd = (struct ww_update *) malloc((unsigned) wwnrow * sizeof *wwupd); | |
| 259 | if (wwupd == 0) { | |
| 260 | wwerrno = WWE_NOMEM; | |
| 261 | goto bad; | |
| 262 | } | |
| 263 | ||
| 264 | wwindex[WWX_NOBODY] = &wwnobody; | |
| 265 | wwnobody.ww_order = NWW; | |
| 266 | ||
| 267 | kp = wwwintermcap; | |
| 268 | if (wwavailmodes & WWM_REV) | |
| 269 | wwaddcap1(WWT_REV, &kp); | |
| 270 | if (wwavailmodes & WWM_BLK) | |
| 271 | wwaddcap1(WWT_BLK, &kp); | |
| 272 | if (wwavailmodes & WWM_UL) | |
| 273 | wwaddcap1(WWT_UL, &kp); | |
| 274 | if (wwavailmodes & WWM_GRP) | |
| 275 | wwaddcap1(WWT_GRP, &kp); | |
| 276 | if (wwavailmodes & WWM_DIM) | |
| 277 | wwaddcap1(WWT_DIM, &kp); | |
| 278 | if (wwavailmodes & WWM_USR) | |
| 279 | wwaddcap1(WWT_USR, &kp); | |
| abecab39 | 280 | if ((tt.tt_insline && tt.tt_delline) || tt.tt_setscroll) |
| 984263bc MD |
281 | wwaddcap1(WWT_ALDL, &kp); |
| 282 | if (tt.tt_inschar) | |
| 283 | wwaddcap1(WWT_IMEI, &kp); | |
| 284 | if (tt.tt_insspace) | |
| 285 | wwaddcap1(WWT_IC, &kp); | |
| 286 | if (tt.tt_delchar) | |
| 287 | wwaddcap1(WWT_DC, &kp); | |
| 288 | wwaddcap("kb", &kp); | |
| abecab39 SW |
289 | wwaddcap("ku", &kp); |
| 290 | wwaddcap("kd", &kp); | |
| 291 | wwaddcap("kl", &kp); | |
| 292 | wwaddcap("kr", &kp); | |
| 984263bc MD |
293 | wwaddcap("kh", &kp); |
| 294 | if ((j = tgetnum("kn")) >= 0) { | |
| 295 | char cap[32]; | |
| 296 | ||
| 297 | (void) sprintf(kp, "kn#%d:", j); | |
| 298 | for (; *kp; kp++) | |
| 299 | ; | |
| 300 | for (i = 1; i <= j; i++) { | |
| 301 | (void) sprintf(cap, "k%d", i); | |
| 302 | wwaddcap(cap, &kp); | |
| 303 | cap[0] = 'l'; | |
| 304 | wwaddcap(cap, &kp); | |
| 305 | } | |
| 306 | } | |
| 307 | /* | |
| 308 | * It's ok to do this here even if setenv() is destructive | |
| 309 | * since tt_init() has already made its own copy of it and | |
| 310 | * wwterm now points to the copy. | |
| 311 | */ | |
| abecab39 | 312 | (void) setenv("TERM", WWT_TERM, 1); |
| 984263bc MD |
313 | #ifdef TERMINFO |
| 314 | if (wwterminfoinit() < 0) | |
| 315 | goto bad; | |
| 316 | #endif | |
| 317 | ||
| 318 | if (tt.tt_checkpoint) | |
| abecab39 | 319 | if (signal(SIGALRM, wwalarm) == SIG_ERR) { |
| 984263bc MD |
320 | wwerrno = WWE_SYS; |
| 321 | goto bad; | |
| 322 | } | |
| 984263bc | 323 | wwstart1(); |
| abecab39 SW |
324 | |
| 325 | sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0); | |
| 984263bc | 326 | return 0; |
| abecab39 | 327 | |
| 984263bc MD |
328 | bad: |
| 329 | /* | |
| 330 | * Don't bother to free storage. We're supposed | |
| 331 | * to exit when wwinit fails anyway. | |
| 332 | */ | |
| 984263bc | 333 | (void) wwsettty(0, &wwoldtty); |
| abecab39 SW |
334 | |
| 335 | sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0); | |
| 984263bc MD |
336 | return -1; |
| 337 | } | |
| 338 | ||
| abecab39 SW |
339 | void |
| 340 | wwaddcap(const char *cap, char **kp) | |
| 984263bc MD |
341 | { |
| 342 | char tbuf[512]; | |
| 343 | char *tp = tbuf; | |
| abecab39 SW |
344 | char *str; |
| 345 | const char *p; | |
| 984263bc MD |
346 | |
| 347 | if ((str = tgetstr(cap, &tp)) != 0) { | |
| abecab39 | 348 | while ((*(*kp)++ = *cap++)) |
| 984263bc MD |
349 | ; |
| 350 | (*kp)[-1] = '='; | |
| 351 | while (*str) { | |
| abecab39 | 352 | for (p = unctrl(*str++); (*(*kp)++ = *p++);) |
| 984263bc MD |
353 | ; |
| 354 | (*kp)--; | |
| 355 | } | |
| 356 | *(*kp)++ = ':'; | |
| 357 | **kp = 0; | |
| 358 | } | |
| 359 | } | |
| 360 | ||
| abecab39 SW |
361 | void |
| 362 | wwaddcap1(const char *cap, char **kp) | |
| 984263bc | 363 | { |
| abecab39 | 364 | while ((*(*kp)++ = *cap++)) |
| 984263bc MD |
365 | ; |
| 366 | (*kp)--; | |
| 367 | } | |
| 368 | ||
| abecab39 SW |
369 | void |
| 370 | wwstart(void) | |
| 984263bc | 371 | { |
| abecab39 | 372 | int i; |
| 984263bc MD |
373 | |
| 374 | (void) wwsettty(0, &wwnewtty); | |
| 984263bc MD |
375 | for (i = 0; i < wwnrow; i++) |
| 376 | wwtouched[i] = WWU_TOUCHED; | |
| 377 | wwstart1(); | |
| 378 | } | |
| 379 | ||
| abecab39 SW |
380 | void |
| 381 | wwstart1(void) | |
| 984263bc | 382 | { |
| abecab39 | 383 | int i, j; |
| 984263bc MD |
384 | |
| 385 | for (i = 0; i < wwnrow; i++) | |
| 386 | for (j = 0; j < wwncol; j++) { | |
| 387 | wwos[i][j].c_w = ' '; | |
| 388 | if (tt.tt_checkpoint) | |
| 389 | wwcs[i][j].c_w = ' '; | |
| 390 | } | |
| 391 | xxstart(); | |
| 392 | if (tt.tt_checkpoint) | |
| 393 | wwdocheckpoint = 1; | |
| 394 | } | |
| 395 | ||
| 396 | /* | |
| 397 | * Reset data structures and terminal from an unknown state. | |
| 398 | * Restoring wwos has been taken care of elsewhere. | |
| 399 | */ | |
| abecab39 SW |
400 | void |
| 401 | wwreset(void) | |
| 984263bc | 402 | { |
| abecab39 | 403 | int i; |
| 984263bc MD |
404 | |
| 405 | xxreset(); | |
| 406 | for (i = 0; i < wwnrow; i++) | |
| 407 | wwtouched[i] = WWU_TOUCHED; | |
| 408 | } |