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