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 && !isatty(filenum)) 439 filenum = 2; /* Allow output redirect */ 440 /* LINTED */ 441 cur_term->Filedes = (short)filenum; 442 _blast_keys(cur_term); 443 cur_term->_iwait = cur_term->fl_typeahdok = cur_term->_chars_on_queue = 444 cur_term->_fl_rawmode = cur_term->_ungotten = 0; 445 cur_term->_cursorstate = 1; 446 cur_term->_delay = cur_term->_inputfd = cur_term->_check_fd = -1; 447 (void) memset((char *)cur_term->_regs, 0, 26 * sizeof (short)); 448 449 #ifndef DUMPTI 450 (void) def_shell_mode(); 451 /* This is a useful default for PROGTTY, too */ 452 #ifdef SYSV 453 if (shell_istermios < 0) { 454 int i; 455 456 SHELLTTY.c_lflag = SHELLTTYS.c_lflag; 457 SHELLTTY.c_oflag = SHELLTTYS.c_oflag; 458 SHELLTTY.c_iflag = SHELLTTYS.c_iflag; 459 SHELLTTY.c_cflag = SHELLTTYS.c_cflag; 460 for (i = 0; i < NCC; i++) 461 SHELLTTY.c_cc[i] = SHELLTTYS.c_cc[i]; 462 PROGTTY = SHELLTTY; 463 prog_istermios = -1; 464 465 PROGTTYS.c_lflag = PROGTTY.c_lflag; 466 PROGTTYS.c_oflag = PROGTTY.c_oflag; 467 PROGTTYS.c_iflag = PROGTTY.c_iflag; 468 PROGTTYS.c_cflag = PROGTTY.c_cflag; 469 for (i = 0; i < NCC; i++) 470 PROGTTYS.c_cc[i] = PROGTTY.c_cc[i]; 471 } else { 472 PROGTTYS = SHELLTTYS; 473 prog_istermios = 0; 474 } 475 #else /* SYSV */ 476 PROGTTY = SHELLTTY; 477 #endif /* SYSV */ 478 #endif /* DUMPTI */ 479 480 /* Skip names of terminals */ 481 (void) memcpy((char *)cp, (char *)ip, (snames * sizeof (*cp))); 482 ip += snames; 483 484 /* 485 * Pull out the booleans. 486 * The for loop below takes care of a new curses with an old tic 487 * file and visa-versa. nbools says how many bools the tic file has. 488 * So, we only loop for as long as there are bools to read. 489 * However, if this is an old curses that doesn't have all the 490 * bools that this new tic has dumped, then the extra if 491 * "if (cp < fp)" says that if we are going to read into our structure 492 * passed its size don't do it but we still need to keep bumping 493 * up the pointer of what we read in from the terminfo file. 494 */ 495 { 496 char *fp = &cur_bools->Sentinel; 497 char s; 498 #ifdef DUMPTI 499 int tempindex = 0; 500 #endif /* DUMPTI */ 501 cp = &cur_bools->_auto_left_margin; 502 while (nbools--) { 503 s = *ip++; 504 #ifdef DUMPTI 505 printf("Bool %s [%s] (%s) = %d.\n", 506 boolfnames[tempindex], boolnames[tempindex], 507 boolcodes[tempindex], s); 508 tempindex++; 509 #endif /* DUMPTI */ 510 if (cp < fp) 511 *cp++ = s & 01; 512 } 513 if (cp < fp) 514 (void) memset(cp, 0, ((fp - cp) * sizeof (bool))); 515 } 516 517 /* Force proper alignment */ 518 if (((unsigned long) ip) & 1) 519 ip++; 520 521 /* 522 * Pull out the numbers. 523 */ 524 { 525 short *sp = &cur_nums->_columns; 526 short *fp = &cur_nums->Sentinel; 527 int s; 528 #ifdef DUMPTI 529 int tempindex = 0; 530 #endif /* DUMPTI */ 531 532 while (nints--) { 533 s = _Getshi(); 534 #ifdef DUMPTI 535 Vr2val = _Vr2getshi(); 536 printf("Num %s [%s] (%s) = %d [%d].\n", 537 numfnames[tempindex], numnames[tempindex], 538 numcodes[tempindex], s, Vr2val); 539 tempindex++; 540 #endif /* DUMPTI */ 541 if (sp < fp) 542 if (s < 0) 543 *sp++ = -1; 544 else 545 /* LINTED */ 546 *sp++ = (short)s; 547 } 548 if (sp < fp) 549 (void) memset((char *)sp, '\377', 550 ((fp - sp) * sizeof (short))); 551 } 552 553 if (_use_env) { 554 /* 555 * This ioctl defines the window size and overrides what 556 * it says in terminfo. 557 */ 558 { 559 struct winsize w; 560 561 if (ioctl(filenum, TIOCGWINSZ, &w) != -1) { 562 if (w.ws_row != 0) 563 cur_nums->_lines = w.ws_row; 564 if (w.ws_col != 0) 565 cur_nums->_columns = w.ws_col; 566 #ifdef DUMPTI 567 printf("ioctl TIOCGWINSZ override: " 568 "(lines, columns) = (%d, %d)\n", 569 w.ws_row, w.ws_col); 570 #endif /* DUMPTI */ 571 } 572 } 573 574 /* 575 * Check $LINES and $COLUMNS. 576 */ 577 { 578 int ilines, icolumns; 579 580 lcp = getenv("LINES"); 581 ccp = getenv("COLUMNS"); 582 if (lcp) 583 if ((ilines = atoi(lcp)) > 0) { 584 /* LINTED */ 585 cur_nums->_lines = (short)ilines; 586 #ifdef DUMPTI 587 printf("$LINES override: lines = %d\n", 588 ilines); 589 #endif /* DUMPTI */ 590 } 591 if (ccp) 592 if ((icolumns = atoi(ccp)) > 0) { 593 /* LINTED */ 594 cur_nums->_columns = (short)icolumns; 595 #ifdef DUMPTI 596 printf("$COLUMNS override: columns = " 597 "%d\n", icolumns); 598 #endif /* DUMPTI */ 599 } 600 } 601 } 602 603 /* Pull out the strings. */ 604 { 605 char **pp = &cur_strs->strs._back_tab; 606 char **fp = &cur_strs->strs4.Sentinel; 607 #ifdef DUMPTI 608 int tempindex = 0; 609 char *startstr = ip + sizeof (short) * 610 nstrs; 611 612 printf("string table = '"); 613 _Mprint(sstrtab, startstr); 614 printf("'\n"); 615 #endif /* DUMPTI */ 616 617 while (nstrs--) { 618 n = _Getshi(); 619 #ifdef DUMPTI 620 Vr2val = _Vr2getshi(); 621 printf("String %s [%s] (%s) offset = %d [%d]", 622 strfnames[tempindex], strnames[tempindex], 623 strcodes[tempindex], n, Vr2val); 624 tempindex++; 625 #endif /* DUMPTI */ 626 if (pp < fp) { 627 #ifdef DUMPTI 628 _Sprint(n, startstr+n); 629 #endif /* DUMPTI */ 630 if (n < 0) 631 *pp++ = NULL; 632 else 633 *pp++ = strtab + n; 634 } 635 #ifdef DUMPTI 636 else 637 _Sprint(-1, (char *)0); 638 #endif /* DUMPTI */ 639 } 640 if (pp < fp) 641 (void) memset((char *)pp, 0, ((fp - pp) * sizeof (charptr))); 642 } 643 644 (void) memcpy(strtab, ip, sstrtab); 645 646 #ifndef DUMPTI 647 648 /* 649 * If tabs are being expanded in software, turn this off 650 * so output won't get messed up. Also, don't use tab 651 * or backtab, even if the terminal has them, since the 652 * user might not have hardware tabs set right. 653 */ 654 #ifdef SYSV 655 if ((PROGTTYS.c_oflag & TABDLY) == TAB3) { 656 PROGTTYS.c_oflag &= ~TABDLY; 657 (void) reset_prog_mode(); 658 goto next; 659 } 660 #else /* SYSV */ 661 if ((PROGTTY.sg_flags & XTABS) == XTABS) { 662 PROGTTY.sg_flags &= ~XTABS; 663 (void) reset_prog_mode(); 664 goto next; 665 } 666 #endif /* SYSV */ 667 if (dest_tabs_magic_smso) { 668 next: 669 cur_strs->strs2._tab = cur_strs->strs._back_tab = NULL; 670 } 671 672 #ifdef LTILDE 673 ioctl(cur_term -> Filedes, TIOCLGET, &n); 674 #endif /* LTILDE */ 675 #endif /* DUMPTI */ 676 677 #ifdef _VR2_COMPAT_CODE 678 (void) memcpy(&cur_term->_b1, &cur_bools->_auto_left_margin, 679 (char *)&cur_term->_c1 - (char *)&cur_term->_b1); 680 (void) memcpy((char *)&cur_term->_c1, (char *)&cur_nums->_columns, 681 (char *)&cur_term->_Vr2_Astrs._s1 - (char *)&cur_term->_c1); 682 (void) memcpy((char *)&cur_term->_Vr2_Astrs._s1, 683 (char *)&cur_strs->strs._back_tab, 684 (char *)&cur_term->Filedes - (char *)&cur_term->_Vr2_Astrs._s1); 685 #endif /* _VR2_COMPAT_CODE */ 686 687 on_sequences = cur_term->turn_on_seq; 688 str_array = (char **)cur_strs; 689 { 690 static char offsets[] = { 691 35, /* enter_standout_mode, */ 692 36, /* enter_underline_mode, */ 693 25, /* enter_alt_charset_mode, */ 694 34, /* enter_reverse_mode, */ 695 26, /* enter_blink_mode, */ 696 30, /* enter_dim_mode, */ 697 27, /* enter_bold_mode, */ 698 32, /* enter_secure_mode, */ 699 33, /* enter_protected_mode, */ 700 }; 701 702 for (n = 0; n < NUM_ATTRIBUTES; n++) { 703 if ((on_sequences[n] = str_array[offsets[n]]) != 0) 704 cur_term->bit_vector |= bit_attributes[n]; 705 } 706 } 707 708 if (!(set_attributes)) { 709 static char faked_attrs[] = { 1, 3, 4, 6 }, 710 offsets[] = { 711 43, /* exit_standout_mode, */ 712 44, /* exit_underline_mode, */ 713 38, /* exit_alt_charset_mode, */ 714 }; 715 char **off_sequences = cur_term->turn_off_seq; 716 int i; 717 718 if ((max_attributes == -1) && (ceol_standout_glitch || 719 (magic_cookie_glitch >= 0))) 720 max_attributes = 1; 721 722 /* Figure out what attributes need to be faked. */ 723 /* See vidupdate.c */ 724 725 for (n = 0; n < sizeof (faked_attrs); n++) { 726 if (on_sequences[0] != NULL) { 727 if ((!on_sequences[i = faked_attrs[n]]) || 728 (strcmp(on_sequences[i], 729 on_sequences[0]) == 0)) { 730 cur_term->sgr_faked |= 731 bit_attributes[i]; 732 } 733 } else { 734 if (!on_sequences[i = faked_attrs[n]]) { 735 cur_term->sgr_faked |= 736 bit_attributes[i]; 737 } 738 } 739 } 740 741 cur_term->check_turn_off = A_STANDOUT | A_UNDERLINE | 742 A_ALTCHARSET; 743 744 for (n = 0; n < sizeof (offsets); n++) { 745 if ((!(off_sequences[n] = str_array[offsets[n]])) || 746 ((n > 0) && off_sequences[0] && 747 (strcmp(off_sequences[n], off_sequences[0]) == 748 0)) || ((n == 2) && (exit_attribute_mode) && 749 (strcmp(exit_attribute_mode, off_sequences[n]) == 750 0))) { 751 cur_term->check_turn_off &= ~bit_attributes[n]; 752 } 753 } 754 } 755 cur_term->cursor_seq[0] = cursor_invisible; 756 cur_term->cursor_seq[1] = cursor_normal; 757 cur_term->cursor_seq[2] = cursor_visible; 758 cur_term->_pairs_tbl = (_Color_pair *) NULL; 759 cur_term->_color_tbl = (_Color *) NULL; 760 761 return (OK); 762 } 763 764 void 765 _blast_keys(TERMINAL *terminal) 766 { 767 terminal->_keys = NULL; 768 terminal->internal_keys = NULL; 769 terminal->_ksz = terminal->_first_macro = 0; 770 terminal->_lastkey_ordered = terminal->_lastmacro_ordered = -1; 771 (void) memset((char *)terminal->funckeystarter, 0, 0400 * 772 sizeof (bool)); 773 } 774 775 #ifndef DUMPTI 776 777 int 778 reset_prog_mode(void) 779 { 780 #ifdef SYSV 781 if (_BRS(PROGTTYS)) { 782 if (prog_istermios < 0) { 783 int i; 784 785 PROGTTY.c_lflag = PROGTTYS.c_lflag; 786 PROGTTY.c_oflag = PROGTTYS.c_oflag; 787 PROGTTY.c_iflag = PROGTTYS.c_iflag; 788 PROGTTY.c_cflag = PROGTTYS.c_cflag; 789 for (i = 0; i < NCC; i++) 790 PROGTTY.c_cc[i] = PROGTTYS.c_cc[i]; 791 (void) ioctl(cur_term -> Filedes, TCSETAW, &PROGTTY); 792 } else 793 (void) ioctl(cur_term -> Filedes, TCSETSW, &PROGTTYS); 794 } 795 #else /* SYSV */ 796 if (_BR(PROGTTY)) 797 (void) ioctl(cur_term -> Filedes, TIOCSETN, &PROGTTY); 798 #endif /* SYSV */ 799 800 #ifdef LTILDE 801 ioctl(cur_term -> Filedes, TIOCLGET, &cur_term -> oldlmode); 802 cur_term -> newlmode = cur_term -> oldlmode & ~LTILDE; 803 if (cur_term -> newlmode != cur_term -> oldlmode) 804 ioctl(cur_term -> Filedes, TIOCLSET, &cur_term -> newlmode); 805 #endif /* LTILDE */ 806 #ifdef DIOCSETT 807 if (cur_term -> old.st_termt == 0) 808 ioctl(cur_term->Filedes, DIOCGETT, &cur_term -> old); 809 cur_term -> new = cur_term -> old; 810 cur_term -> new.st_termt = 0; 811 cur_term -> new.st_flgs |= TM_SET; 812 ioctl(cur_term->Filedes, DIOCSETT, &cur_term -> new); 813 #endif /* DIOCSETT */ 814 return (OK); 815 } 816 817 int 818 def_shell_mode(void) 819 { 820 #ifdef SYSV 821 if ((shell_istermios = 822 ioctl(cur_term -> Filedes, TCGETS, &SHELLTTYS)) < 0) { 823 int i; 824 825 (void) ioctl(cur_term -> Filedes, TCGETA, &SHELLTTY); 826 SHELLTTYS.c_lflag = SHELLTTY.c_lflag; 827 SHELLTTYS.c_oflag = SHELLTTY.c_oflag; 828 SHELLTTYS.c_iflag = SHELLTTY.c_iflag; 829 SHELLTTYS.c_cflag = SHELLTTY.c_cflag; 830 for (i = 0; i < NCC; i++) 831 SHELLTTYS.c_cc[i] = SHELLTTY.c_cc[i]; 832 } 833 #else /* SYSV */ 834 (void) ioctl(cur_term -> Filedes, TIOCGETP, &SHELLTTY); 835 #endif /* SYSV */ 836 return (OK); 837 } 838 839 #endif /* DUMPTI */ 840