1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 /*LINTLIBRARY*/ 43 44 #include <stdio.h> 45 #include <sys/types.h> 46 #include <fcntl.h> 47 #include <stdlib.h> 48 #include <string.h> 49 #include <unistd.h> 50 #include <errno.h> 51 #include "curses_inc.h" 52 53 #define TERMPATH "/usr/share/lib/terminfo/" 54 #define TERMPATHLEN 512 55 56 extern bool _use_env; /* in curses.c */ 57 58 chtype bit_attributes[NUM_ATTRIBUTES] = { 59 A_STANDOUT, 60 A_UNDERLINE, 61 A_ALTCHARSET, 62 A_REVERSE, 63 A_BLINK, 64 A_DIM, 65 A_BOLD, 66 A_INVIS, 67 A_PROTECT 68 }; 69 70 char *Def_term = "unknown", /* default terminal type */ 71 term_parm_err[32], ttytype[BUFSIZ], _frst_tblstr[1400]; 72 73 TERMINAL _first_term, *cur_term = &_first_term; 74 struct _bool_struct _frst_bools, *cur_bools = &_frst_bools; 75 struct _num_struct _frst_nums, *cur_nums = &_frst_nums; 76 struct _str_struct _frst_strs, *cur_strs = &_frst_strs; 77 78 /* _called_before is used/cleared by delterm.c and restart.c */ 79 char _called_before = 0; 80 short term_errno = -1; 81 82 #ifdef SYSV 83 int prog_istermios = -1; 84 int shell_istermios = -1; 85 #endif 86 87 #ifdef DUMPTI 88 extern char *boolfnames[], *boolnames[], *boolcodes[], 89 *numfnames[], *numnames[], *numcodes[], 90 *strfnames[], *strnames[], *strcodes[]; 91 92 main(int argc, char **argv) /* FOR DEBUG ONLY */ 93 { 94 if (argc > 1) 95 setupterm(argv[1], 1, (int *)0); 96 else 97 setupterm((char *)0, 1, (int *)0); 98 return (0); 99 } 100 101 _Pr(int ch) /* FOR DEBUG ONLY */ 102 { 103 if (ch >= 0200) { 104 printf("M-"); 105 ch -= 0200; 106 } 107 if ((ch < ' ') || (ch == 0177)) 108 printf("^%c", ch ^ 0100); 109 else 110 printf("%c", ch); 111 } 112 113 _Sprint(int n, char *string) /* FOR DEBUG ONLY */ 114 { 115 int ch; 116 117 if (n == -1) { 118 printf(".\n"); 119 return; 120 } 121 printf(", string = '"); 122 while (ch = *string++) 123 _Pr(ch&0377); 124 125 printf("'.\n"); 126 } 127 128 _Mprint(int n, char *memory) /* FOR DEBUG ONLY */ 129 { 130 unsigned char ch; 131 132 while (ch = *memory++, n-- > 0) 133 _Pr(ch&0377); 134 } 135 136 #define _Vr2getshi() _Vr2getsh(ip-2) 137 138 #if vax || pdp11 139 #define _Vr2getsh(ip) (* (short *)(ip)) 140 #endif /* vax || pdp11 */ 141 142 #ifndef _Vr2getsh 143 /* 144 * Here is a more portable version, which does not assume byte ordering 145 * in shorts, sign extension, etc. 146 */ 147 _Vr2getsh(char *p) 148 { 149 int rv; 150 151 if (*p == (char)0377) 152 return (-1); 153 rv = (unsigned char) *p++; 154 rv += (unsigned char) *p * 256; 155 return (rv); 156 } 157 #endif /* _Vr2getsh */ 158 159 #endif /* DUMPTI */ 160 161 #define _Getshi() _Getsh(ip); ip += 2 162 163 /* 164 * "function" to get a short from a pointer. The short is in a standard 165 * format: two bytes, the first is the low order byte, the second is 166 * the high order byte (base 256). The only negative numbers allowed are 167 * -1 and -2, which are represented as 255,255 and 255,254 This format 168 * happens to be the same as the hardware on the pdp-11, vax, and 386, 169 * making it fast and convenient and small to do this on a pdp-11. 170 */ 171 172 #if vax || pdp11 || i386 173 #define _Getsh(ip) (* (short *)ip) 174 #endif /* vax || pdp11 */ 175 /* 176 * The following macro is partly due to Mike Laman, laman@sdcsvax 177 * NCR @ Torrey Pines. - Tony Hansen 178 */ 179 #if u3b || u3b15 || u3b2 || m68000 180 #define _Getsh(ip) ((short)(*((unsigned char *)ip) | (*(ip+1) << 8))) 181 #endif /* u3b || u3b15 || u3b2 || m68000 */ 182 183 #ifndef _Getsh 184 /* 185 * Here is a more portable version, which does not assume byte ordering 186 * in shorts, sign extension, etc. For the sake of the porters, 187 * two alternative implementations, for the machines that don't have 188 * casting to "unsigned char", are also given, but commented out. 189 * Not ANSI C implementation assumes that the * C preprocessor does 190 * sign-extension the same as on the machine being compiled for. 191 */ 192 static int 193 _Getsh(char *p) 194 { 195 int rv, rv2; 196 197 rv = (unsigned char) p[0]; 198 rv2 = (unsigned char) p[1]; 199 200 /* the following stuff is only for porting. See the comment above */ 201 202 #ifdef FOR_PORTING 203 #if CHAR_MIN < 0 204 rv = (*p++) & 0377; 205 rv2 = (*p) & 0377; 206 #else /* CHAR_MIN < 0 */ 207 rv = *p++; 208 rv2 = *p; 209 #endif /* CHAR_MIN < 0 */ 210 211 #endif /* FOR_PORTING */ 212 213 if ((rv2 == 0377) && ((rv == 0377) || (rv == 0376))) 214 return (-1); 215 return (rv + (rv2 * 256)); 216 } 217 #endif /* _Getsh */ 218 219 /* 220 * setupterm: low level routine to dig up terminfo from database 221 * and read it in. Parms are terminal type (0 means use getenv("TERM"), 222 * file descriptor all output will go to (for ioctls), and a pointer 223 * to an int into which the error return code goes (0 means to bomb 224 * out with an error message if there's an error). Thus, 225 * setupterm((char *)0, 1, (int *)0) is a reasonable way for a simple 226 * program to set up. 227 */ 228 int 229 setupterm(char *term, int filenum, int *errret) 230 /* filenum - This is a UNIX file descriptor, not a stdio ptr. */ 231 { 232 char tiebuf[4096]; 233 char fname[TERMPATHLEN]; 234 char *ip; 235 char *cp; 236 int n, tfd; 237 char *lcp, *ccp, **on_sequences, **str_array; 238 int snames, nbools, nints, nstrs, sstrtab; 239 char *strtab; 240 #ifdef DUMPTI 241 int Vr2val; 242 #endif /* DUMPTI */ 243 244 (void) mbgetwidth(); 245 246 if (term == NULL) 247 term = getenv("TERM"); 248 249 if (term == NULL || *term == '\0') 250 term = Def_term; 251 252 tfd = -1; 253 errno = 0; /* ehr3 */ 254 255 if (errret != 0) 256 *errret = -1; 257 258 if (((cp = getenv("TERMINFO")) != 0) && *cp) { 259 /* $TERMINFO/?/$TERM */ 260 if (snprintf(fname, sizeof (fname), 261 "%s/%c/%s", cp, *term, term) >= sizeof (fname)) { 262 term_errno = TERMINFO_TOO_LONG; 263 goto out_err; 264 } 265 266 tfd = open(fname, 0); 267 #ifdef DUMPTI 268 printf("looking in file %s\n", fname); 269 #endif /* DUMPTI */ 270 if ((tfd < 0) && (errno == EACCES)) 271 goto cant_read; 272 } 273 274 if (tfd < 0) { 275 /* /usr/share/lib/terminfo/?/$TERM */ 276 if (snprintf(fname, sizeof (fname), 277 "%s/%c/%s", TERMPATH, *term, term) >= sizeof (fname)) { 278 term_errno = TERMINFO_TOO_LONG; 279 goto out_err; 280 } 281 282 tfd = open(fname, 0); 283 #ifdef DUMPTI 284 printf("looking in file %s\n", fname); 285 #endif /* DUMPTI */ 286 287 } 288 289 if (tfd < 0) { 290 if (errno == EACCES) { 291 cant_read: 292 term_errno = NOT_READABLE; 293 } else { 294 if (access(TERMPATH, 0) == -1) 295 term_errno = UNACCESSIBLE; 296 else { 297 term_errno = NO_TERMINAL; 298 if (errret != 0) 299 *errret = 0; 300 } 301 } 302 /* 303 * if the length of the specified terminal name is longer 304 * than 31, it will be chopped after the 31st byte. 305 * This should be a rare case. 306 */ 307 (void) strncpy(term_parm_err, term, 31); 308 term_parm_err[31] = '\0'; 309 goto out_err; 310 } 311 312 /* LINTED */ 313 n = (int)read(tfd, tiebuf, sizeof (tiebuf)); 314 (void) close(tfd); 315 316 if (n <= 0) { 317 corrupt: 318 term_errno = CORRUPTED; 319 goto out_err; 320 } else 321 if (n == sizeof (tiebuf)) { 322 term_errno = ENTRY_TOO_LONG; 323 goto out_err; 324 } 325 cp = ttytype; 326 ip = tiebuf; 327 328 /* Pick up header */ 329 snames = _Getshi(); 330 #ifdef DUMPTI 331 Vr2val = _Vr2getshi(); 332 printf("Magic number = %d, %#o [%d, %#o].\n", snames, 333 snames, Vr2val, Vr2val); 334 #endif /* DUMPTI */ 335 if (snames != MAGNUM) 336 goto corrupt; 337 snames = _Getshi(); 338 #ifdef DUMPTI 339 Vr2val = _Vr2getshi(); 340 printf("Size of names = %d, %#o [%d, %#o].\n", snames, 341 snames, Vr2val, Vr2val); 342 #endif /* DUMPTI */ 343 344 nbools = _Getshi(); 345 #ifdef DUMPTI 346 Vr2val = _Vr2getshi(); 347 printf("Number of bools = %d, %#o [%d, %#o].\n", nbools, 348 nbools, Vr2val, Vr2val); 349 #endif /* DUMPTI */ 350 351 nints = _Getshi(); 352 #ifdef DUMPTI 353 Vr2val = _Vr2getshi(); 354 printf("Number of ints = %d, %#o [%d, %#o].\n", nints, nints, 355 Vr2val, Vr2val); 356 #endif /* DUMPTI */ 357 358 nstrs = _Getshi(); 359 #ifdef DUMPTI 360 Vr2val = _Vr2getshi(); 361 printf("Number of strings = %d, %#o [%d, %#o].\n", nstrs, nstrs, 362 Vr2val, Vr2val); 363 #endif /* DUMPTI */ 364 365 sstrtab = _Getshi(); 366 #ifdef DUMPTI 367 Vr2val = _Vr2getshi(); 368 printf("Size of string table = %d, %#o [%d, %#o].\n", sstrtab, 369 sstrtab, Vr2val, Vr2val); 370 printf("Names are: %.*s.\n", snames, ip); 371 #endif /* DUMPTI */ 372 373 /* allocate all of the space */ 374 strtab = NULL; 375 if (_called_before) { 376 /* 2nd or more times through */ 377 if ((cur_term = (TERMINAL *) 378 calloc(sizeof (TERMINAL), 1)) == NULL) 379 goto badmalloc; 380 if ((cur_bools = (struct _bool_struct *) 381 calloc(sizeof (struct _bool_struct), 1)) == NULL) 382 goto freeterminal; 383 if ((cur_nums = (struct _num_struct *) 384 calloc(sizeof (struct _num_struct), 1)) == NULL) 385 goto freebools; 386 if ((cur_strs = (struct _str_struct *) 387 calloc(sizeof (struct _str_struct), 1)) == NULL) { 388 freenums: 389 free((char *)cur_nums); 390 freebools: 391 free((char *)cur_bools); 392 freeterminal: 393 free((char *)cur_term); 394 badmalloc: 395 term_errno = TERM_BAD_MALLOC; 396 #ifdef DEBUG 397 strcpy(term_parm_err, "setupterm"); 398 #endif /* DEBUG */ 399 out_err: 400 if (errret == 0) { 401 termerr(); 402 exit(-term_errno); 403 } else 404 return (ERR); 405 } 406 } else { 407 /* First time through */ 408 _called_before = TRUE; 409 cur_term = &_first_term; 410 cur_bools = &_frst_bools; 411 cur_nums = &_frst_nums; 412 cur_strs = &_frst_strs; 413 if (sstrtab < sizeof (_frst_tblstr)) 414 strtab = _frst_tblstr; 415 } 416 417 if (strtab == NULL) { 418 if ((strtab = (char *)malloc((unsigned)sstrtab)) == NULL) { 419 if (cur_strs != &_frst_strs) 420 free((char *)cur_strs); 421 goto freenums; 422 } 423 } 424 425 /* no more catchable errors */ 426 if (errret) 427 *errret = 1; 428 429 (void) strncpy(cur_term->_termname, term, 14); 430 /* In case the name is exactly 15 characters */ 431 cur_term->_termname[14] = '\0'; 432 cur_term->_bools = cur_bools; 433 cur_term->_nums = cur_nums; 434 cur_term->_strs = cur_strs; 435 cur_term->_strtab = strtab; 436 cur_term->sgr_mode = cur_term->sgr_faked = A_NORMAL; 437 438 if (filenum == 1) { 439 /* 440 * isatty(3C) will set errno as a side-effect of returning 0. 441 * Hide this from callers so that they do not see errno 442 * changing for no apparent reason. 443 */ 444 int err = errno; 445 if (isatty(filenum) == 0) 446 filenum = 2; /* Allow output redirect */ 447 errno = err; 448 } 449 /* LINTED */ 450 cur_term->Filedes = (short)filenum; 451 _blast_keys(cur_term); 452 cur_term->_iwait = cur_term->fl_typeahdok = cur_term->_chars_on_queue = 453 cur_term->_fl_rawmode = cur_term->_ungotten = 0; 454 cur_term->_cursorstate = 1; 455 cur_term->_delay = cur_term->_inputfd = cur_term->_check_fd = -1; 456 (void) memset((char *)cur_term->_regs, 0, 26 * sizeof (short)); 457 458 #ifndef DUMPTI 459 (void) def_shell_mode(); 460 /* This is a useful default for PROGTTY, too */ 461 #ifdef SYSV 462 if (shell_istermios < 0) { 463 int i; 464 465 SHELLTTY.c_lflag = SHELLTTYS.c_lflag; 466 SHELLTTY.c_oflag = SHELLTTYS.c_oflag; 467 SHELLTTY.c_iflag = SHELLTTYS.c_iflag; 468 SHELLTTY.c_cflag = SHELLTTYS.c_cflag; 469 for (i = 0; i < NCC; i++) 470 SHELLTTY.c_cc[i] = SHELLTTYS.c_cc[i]; 471 PROGTTY = SHELLTTY; 472 prog_istermios = -1; 473 474 PROGTTYS.c_lflag = PROGTTY.c_lflag; 475 PROGTTYS.c_oflag = PROGTTY.c_oflag; 476 PROGTTYS.c_iflag = PROGTTY.c_iflag; 477 PROGTTYS.c_cflag = PROGTTY.c_cflag; 478 for (i = 0; i < NCC; i++) 479 PROGTTYS.c_cc[i] = PROGTTY.c_cc[i]; 480 } else { 481 PROGTTYS = SHELLTTYS; 482 prog_istermios = 0; 483 } 484 #else /* SYSV */ 485 PROGTTY = SHELLTTY; 486 #endif /* SYSV */ 487 #endif /* DUMPTI */ 488 489 /* Skip names of terminals */ 490 (void) memcpy((char *)cp, (char *)ip, (snames * sizeof (*cp))); 491 ip += snames; 492 493 /* 494 * Pull out the booleans. 495 * The for loop below takes care of a new curses with an old tic 496 * file and visa-versa. nbools says how many bools the tic file has. 497 * So, we only loop for as long as there are bools to read. 498 * However, if this is an old curses that doesn't have all the 499 * bools that this new tic has dumped, then the extra if 500 * "if (cp < fp)" says that if we are going to read into our structure 501 * passed its size don't do it but we still need to keep bumping 502 * up the pointer of what we read in from the terminfo file. 503 */ 504 { 505 char *fp = &cur_bools->Sentinel; 506 char s; 507 #ifdef DUMPTI 508 int tempindex = 0; 509 #endif /* DUMPTI */ 510 cp = &cur_bools->_auto_left_margin; 511 while (nbools--) { 512 s = *ip++; 513 #ifdef DUMPTI 514 printf("Bool %s [%s] (%s) = %d.\n", 515 boolfnames[tempindex], boolnames[tempindex], 516 boolcodes[tempindex], s); 517 tempindex++; 518 #endif /* DUMPTI */ 519 if (cp < fp) 520 *cp++ = s & 01; 521 } 522 if (cp < fp) 523 (void) memset(cp, 0, ((fp - cp) * sizeof (bool))); 524 } 525 526 /* Force proper alignment */ 527 if (((unsigned long) ip) & 1) 528 ip++; 529 530 /* 531 * Pull out the numbers. 532 */ 533 { 534 short *sp = &cur_nums->_columns; 535 short *fp = &cur_nums->Sentinel; 536 int s; 537 #ifdef DUMPTI 538 int tempindex = 0; 539 #endif /* DUMPTI */ 540 541 while (nints--) { 542 s = _Getshi(); 543 #ifdef DUMPTI 544 Vr2val = _Vr2getshi(); 545 printf("Num %s [%s] (%s) = %d [%d].\n", 546 numfnames[tempindex], numnames[tempindex], 547 numcodes[tempindex], s, Vr2val); 548 tempindex++; 549 #endif /* DUMPTI */ 550 if (sp < fp) 551 if (s < 0) 552 *sp++ = -1; 553 else 554 /* LINTED */ 555 *sp++ = (short)s; 556 } 557 if (sp < fp) 558 (void) memset((char *)sp, '\377', 559 ((fp - sp) * sizeof (short))); 560 } 561 562 if (_use_env) { 563 /* 564 * This ioctl defines the window size and overrides what 565 * it says in terminfo. 566 */ 567 { 568 struct winsize w; 569 570 if (ioctl(filenum, TIOCGWINSZ, &w) != -1) { 571 if (w.ws_row != 0) 572 cur_nums->_lines = w.ws_row; 573 if (w.ws_col != 0) 574 cur_nums->_columns = w.ws_col; 575 #ifdef DUMPTI 576 printf("ioctl TIOCGWINSZ override: " 577 "(lines, columns) = (%d, %d)\n", 578 w.ws_row, w.ws_col); 579 #endif /* DUMPTI */ 580 } 581 } 582 583 /* 584 * Check $LINES and $COLUMNS. 585 */ 586 { 587 int ilines, icolumns; 588 589 lcp = getenv("LINES"); 590 ccp = getenv("COLUMNS"); 591 if (lcp) 592 if ((ilines = atoi(lcp)) > 0) { 593 /* LINTED */ 594 cur_nums->_lines = (short)ilines; 595 #ifdef DUMPTI 596 printf("$LINES override: lines = %d\n", 597 ilines); 598 #endif /* DUMPTI */ 599 } 600 if (ccp) 601 if ((icolumns = atoi(ccp)) > 0) { 602 /* LINTED */ 603 cur_nums->_columns = (short)icolumns; 604 #ifdef DUMPTI 605 printf("$COLUMNS override: columns = " 606 "%d\n", icolumns); 607 #endif /* DUMPTI */ 608 } 609 } 610 } 611 612 /* Pull out the strings. */ 613 { 614 char **pp = &cur_strs->strs._back_tab; 615 char **fp = &cur_strs->strs4.Sentinel; 616 #ifdef DUMPTI 617 int tempindex = 0; 618 char *startstr = ip + sizeof (short) * 619 nstrs; 620 621 printf("string table = '"); 622 _Mprint(sstrtab, startstr); 623 printf("'\n"); 624 #endif /* DUMPTI */ 625 626 while (nstrs--) { 627 n = _Getshi(); 628 #ifdef DUMPTI 629 Vr2val = _Vr2getshi(); 630 printf("String %s [%s] (%s) offset = %d [%d]", 631 strfnames[tempindex], strnames[tempindex], 632 strcodes[tempindex], n, Vr2val); 633 tempindex++; 634 #endif /* DUMPTI */ 635 if (pp < fp) { 636 #ifdef DUMPTI 637 _Sprint(n, startstr+n); 638 #endif /* DUMPTI */ 639 if (n < 0) 640 *pp++ = NULL; 641 else 642 *pp++ = strtab + n; 643 } 644 #ifdef DUMPTI 645 else 646 _Sprint(-1, (char *)0); 647 #endif /* DUMPTI */ 648 } 649 if (pp < fp) 650 (void) memset((char *)pp, 0, ((fp - pp) * sizeof (charptr))); 651 } 652 653 (void) memcpy(strtab, ip, sstrtab); 654 655 #ifndef DUMPTI 656 657 /* 658 * If tabs are being expanded in software, turn this off 659 * so output won't get messed up. Also, don't use tab 660 * or backtab, even if the terminal has them, since the 661 * user might not have hardware tabs set right. 662 */ 663 #ifdef SYSV 664 if ((PROGTTYS.c_oflag & TABDLY) == TAB3) { 665 PROGTTYS.c_oflag &= ~TABDLY; 666 (void) reset_prog_mode(); 667 goto next; 668 } 669 #else /* SYSV */ 670 if ((PROGTTY.sg_flags & XTABS) == XTABS) { 671 PROGTTY.sg_flags &= ~XTABS; 672 (void) reset_prog_mode(); 673 goto next; 674 } 675 #endif /* SYSV */ 676 if (dest_tabs_magic_smso) { 677 next: 678 cur_strs->strs2._tab = cur_strs->strs._back_tab = NULL; 679 } 680 681 #ifdef LTILDE 682 ioctl(cur_term -> Filedes, TIOCLGET, &n); 683 #endif /* LTILDE */ 684 #endif /* DUMPTI */ 685 686 #ifdef _VR2_COMPAT_CODE 687 (void) memcpy(&cur_term->_b1, &cur_bools->_auto_left_margin, 688 (char *)&cur_term->_c1 - (char *)&cur_term->_b1); 689 (void) memcpy((char *)&cur_term->_c1, (char *)&cur_nums->_columns, 690 (char *)&cur_term->_Vr2_Astrs._s1 - (char *)&cur_term->_c1); 691 (void) memcpy((char *)&cur_term->_Vr2_Astrs._s1, 692 (char *)&cur_strs->strs._back_tab, 693 (char *)&cur_term->Filedes - (char *)&cur_term->_Vr2_Astrs._s1); 694 #endif /* _VR2_COMPAT_CODE */ 695 696 on_sequences = cur_term->turn_on_seq; 697 str_array = (char **)cur_strs; 698 { 699 static char offsets[] = { 700 35, /* enter_standout_mode, */ 701 36, /* enter_underline_mode, */ 702 25, /* enter_alt_charset_mode, */ 703 34, /* enter_reverse_mode, */ 704 26, /* enter_blink_mode, */ 705 30, /* enter_dim_mode, */ 706 27, /* enter_bold_mode, */ 707 32, /* enter_secure_mode, */ 708 33, /* enter_protected_mode, */ 709 }; 710 711 for (n = 0; n < NUM_ATTRIBUTES; n++) { 712 if ((on_sequences[n] = str_array[offsets[n]]) != 0) 713 cur_term->bit_vector |= bit_attributes[n]; 714 } 715 } 716 717 if (!(set_attributes)) { 718 static char faked_attrs[] = { 1, 3, 4, 6 }, 719 offsets[] = { 720 43, /* exit_standout_mode, */ 721 44, /* exit_underline_mode, */ 722 38, /* exit_alt_charset_mode, */ 723 }; 724 char **off_sequences = cur_term->turn_off_seq; 725 int i; 726 727 if ((max_attributes == -1) && (ceol_standout_glitch || 728 (magic_cookie_glitch >= 0))) 729 max_attributes = 1; 730 731 /* Figure out what attributes need to be faked. */ 732 /* See vidupdate.c */ 733 734 for (n = 0; n < sizeof (faked_attrs); n++) { 735 if (on_sequences[0] != NULL) { 736 if ((!on_sequences[i = faked_attrs[n]]) || 737 (strcmp(on_sequences[i], 738 on_sequences[0]) == 0)) { 739 cur_term->sgr_faked |= 740 bit_attributes[i]; 741 } 742 } else { 743 if (!on_sequences[i = faked_attrs[n]]) { 744 cur_term->sgr_faked |= 745 bit_attributes[i]; 746 } 747 } 748 } 749 750 cur_term->check_turn_off = A_STANDOUT | A_UNDERLINE | 751 A_ALTCHARSET; 752 753 for (n = 0; n < sizeof (offsets); n++) { 754 if ((!(off_sequences[n] = str_array[offsets[n]])) || 755 ((n > 0) && off_sequences[0] && 756 (strcmp(off_sequences[n], off_sequences[0]) == 757 0)) || ((n == 2) && (exit_attribute_mode) && 758 (strcmp(exit_attribute_mode, off_sequences[n]) == 759 0))) { 760 cur_term->check_turn_off &= ~bit_attributes[n]; 761 } 762 } 763 } 764 cur_term->cursor_seq[0] = cursor_invisible; 765 cur_term->cursor_seq[1] = cursor_normal; 766 cur_term->cursor_seq[2] = cursor_visible; 767 cur_term->_pairs_tbl = (_Color_pair *) NULL; 768 cur_term->_color_tbl = (_Color *) NULL; 769 770 return (OK); 771 } 772 773 void 774 _blast_keys(TERMINAL *terminal) 775 { 776 terminal->_keys = NULL; 777 terminal->internal_keys = NULL; 778 terminal->_ksz = terminal->_first_macro = 0; 779 terminal->_lastkey_ordered = terminal->_lastmacro_ordered = -1; 780 (void) memset((char *)terminal->funckeystarter, 0, 0400 * 781 sizeof (bool)); 782 } 783 784 #ifndef DUMPTI 785 786 int 787 reset_prog_mode(void) 788 { 789 #ifdef SYSV 790 if (_BRS(PROGTTYS)) { 791 if (prog_istermios < 0) { 792 int i; 793 794 PROGTTY.c_lflag = PROGTTYS.c_lflag; 795 PROGTTY.c_oflag = PROGTTYS.c_oflag; 796 PROGTTY.c_iflag = PROGTTYS.c_iflag; 797 PROGTTY.c_cflag = PROGTTYS.c_cflag; 798 for (i = 0; i < NCC; i++) 799 PROGTTY.c_cc[i] = PROGTTYS.c_cc[i]; 800 (void) ioctl(cur_term -> Filedes, TCSETAW, &PROGTTY); 801 } else 802 (void) ioctl(cur_term -> Filedes, TCSETSW, &PROGTTYS); 803 } 804 #else /* SYSV */ 805 if (_BR(PROGTTY)) 806 (void) ioctl(cur_term -> Filedes, TIOCSETN, &PROGTTY); 807 #endif /* SYSV */ 808 809 #ifdef LTILDE 810 ioctl(cur_term -> Filedes, TIOCLGET, &cur_term -> oldlmode); 811 cur_term -> newlmode = cur_term -> oldlmode & ~LTILDE; 812 if (cur_term -> newlmode != cur_term -> oldlmode) 813 ioctl(cur_term -> Filedes, TIOCLSET, &cur_term -> newlmode); 814 #endif /* LTILDE */ 815 #ifdef DIOCSETT 816 if (cur_term -> old.st_termt == 0) 817 ioctl(cur_term->Filedes, DIOCGETT, &cur_term -> old); 818 cur_term -> new = cur_term -> old; 819 cur_term -> new.st_termt = 0; 820 cur_term -> new.st_flgs |= TM_SET; 821 ioctl(cur_term->Filedes, DIOCSETT, &cur_term -> new); 822 #endif /* DIOCSETT */ 823 return (OK); 824 } 825 826 int 827 def_shell_mode(void) 828 { 829 #ifdef SYSV 830 if ((shell_istermios = 831 ioctl(cur_term -> Filedes, TCGETS, &SHELLTTYS)) < 0) { 832 int i; 833 834 (void) ioctl(cur_term -> Filedes, TCGETA, &SHELLTTY); 835 SHELLTTYS.c_lflag = SHELLTTY.c_lflag; 836 SHELLTTYS.c_oflag = SHELLTTY.c_oflag; 837 SHELLTTYS.c_iflag = SHELLTTY.c_iflag; 838 SHELLTTYS.c_cflag = SHELLTTY.c_cflag; 839 for (i = 0; i < NCC; i++) 840 SHELLTTYS.c_cc[i] = SHELLTTY.c_cc[i]; 841 } 842 #else /* SYSV */ 843 (void) ioctl(cur_term -> Filedes, TIOCGETP, &SHELLTTY); 844 #endif /* SYSV */ 845 return (OK); 846 } 847 848 #endif /* DUMPTI */ 849