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
main(int argc,char ** argv)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
_Pr(int ch)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
_Sprint(int n,char * string)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
_Mprint(int n,char * memory)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 */
_Vr2getsh(char * p)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
_Getsh(char * p)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
setupterm(char * term,int filenum,int * errret)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
_blast_keys(TERMINAL * terminal)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
reset_prog_mode(void)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
def_shell_mode(void)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