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