2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Christos Zoulas of Cornell University.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * $FreeBSD: src/lib/libedit/tty.c,v 1.4.6.1 2000/08/16 14:43:40 ache Exp $
39 #if !defined(lint) && !defined(SCCSID)
40 static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
41 #endif /* not lint && not SCCSID */
44 * tty.c: tty interface stuff
50 typedef struct ttymodes_t {
56 typedef struct ttymap_t {
57 int nch, och; /* Internal and termio rep of chars */
58 el_action_t bind[3]; /* emacs, vi, and vi-cmd */
62 private ttyperm_t ttyperm = {
64 { "iflag:", ICRNL, (INLCR|IGNCR) },
65 { "oflag:", (OPOST|ONLCR), ONLRET },
67 { "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN),
68 (NOFLSH|ECHONL|EXTPROC|FLUSHO) },
72 { "iflag:", (INLCR|ICRNL), IGNCR },
73 { "oflag:", (OPOST|ONLCR), ONLRET },
76 (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO) },
77 { "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)|
78 C_SH(C_SUSP)|C_SH(C_DSUSP)|C_SH(C_EOL)|C_SH(C_DISCARD)|
79 C_SH(C_PGOFF)|C_SH(C_PAGE)|C_SH(C_STATUS)), 0 }
82 { "iflag:", 0, IXON | IXOFF | INLCR | ICRNL },
85 { "lflag:", 0, ISIG | IEXTEN },
90 private ttychar_t ttychar = {
92 CINTR, CQUIT, CERASE, CKILL,
93 CEOF, CEOL, CEOL2, CSWTCH,
94 CDSWTCH, CERASE2, CSTART, CSTOP,
95 CWERASE, CSUSP, CDSUSP, CREPRINT,
96 CDISCARD, CLNEXT, CSTATUS, CPAGE,
97 CPGOFF, CKILL2, CBRK, CMIN,
101 CINTR, CQUIT, CERASE, CKILL,
102 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
103 _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
104 _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
105 CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
106 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
120 private ttymap_t tty_map[] = {
123 { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
127 { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
131 { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
135 { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
139 { EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED } },
143 { ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD } },
146 { C_REPRINT, VREPRINT,
147 { ED_REDISPLAY, ED_INSERT, ED_REDISPLAY } },
148 #endif /* VREPRINT */
151 { ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED } },
154 { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } }
157 private ttymodes_t ttymodes[] = {
159 { "ignbrk", IGNBRK, M_INP },
162 { "brkint", BRKINT, M_INP },
165 { "ignpar", IGNPAR, M_INP },
168 { "parmrk", PARMRK, M_INP },
171 { "inpck", INPCK, M_INP },
174 { "istrip", ISTRIP, M_INP },
177 { "inlcr", INLCR, M_INP },
180 { "igncr", IGNCR, M_INP },
183 { "icrnl", ICRNL, M_INP },
186 { "iuclc", IUCLC, M_INP },
189 { "ixon", IXON, M_INP },
192 { "ixany", IXANY, M_INP },
195 { "ixoff", IXOFF, M_INP },
198 { "imaxbel",IMAXBEL,M_INP },
199 # endif /* IMAXBEL */
202 { "opost", OPOST, M_OUT },
205 { "olcuc", OLCUC, M_OUT },
208 { "onlcr", ONLCR, M_OUT },
211 { "ocrnl", OCRNL, M_OUT },
214 { "onocr", ONOCR, M_OUT },
217 { "onoeot", ONOEOT, M_OUT },
220 { "onlret", ONLRET, M_OUT },
223 { "ofill", OFILL, M_OUT },
226 { "ofdel", OFDEL, M_OUT },
229 { "nldly", NLDLY, M_OUT },
232 { "crdly", CRDLY, M_OUT },
235 { "tabdly", TABDLY, M_OUT },
238 { "xtabs", XTABS, M_OUT },
241 { "bsdly", BSDLY, M_OUT },
244 { "vtdly", VTDLY, M_OUT },
247 { "ffdly", FFDLY, M_OUT },
250 { "pageout",PAGEOUT,M_OUT },
251 # endif /* PAGEOUT */
253 { "wrap", WRAP, M_OUT },
257 { "cignore",CIGNORE,M_CTL },
260 { "cbaud", CBAUD, M_CTL },
263 { "cstopb", CSTOPB, M_CTL },
266 { "cread", CREAD, M_CTL },
269 { "parenb", PARENB, M_CTL },
272 { "parodd", PARODD, M_CTL },
275 { "hupcl", HUPCL, M_CTL },
278 { "clocal", CLOCAL, M_CTL },
281 { "loblk", LOBLK, M_CTL },
284 { "cibaud", CIBAUD, M_CTL },
288 { "ccts_oflow",CCTS_OFLOW,M_CTL },
290 { "crtscts",CRTSCTS,M_CTL },
291 # endif /* CCTS_OFLOW */
292 # endif /* CRTSCTS */
294 { "crts_iflow",CRTS_IFLOW,M_CTL },
295 # endif /* CRTS_IFLOW */
297 { "mdmbuf", MDMBUF, M_CTL },
300 { "rcv1en", RCV1EN, M_CTL },
303 { "xmt1en", XMT1EN, M_CTL },
307 { "isig", ISIG, M_LIN },
310 { "icanon", ICANON, M_LIN },
313 { "xcase", XCASE, M_LIN },
316 { "echo", ECHO, M_LIN },
319 { "echoe", ECHOE, M_LIN },
322 { "echok", ECHOK, M_LIN },
325 { "echonl", ECHONL, M_LIN },
328 { "noflsh", NOFLSH, M_LIN },
331 { "tostop", TOSTOP, M_LIN },
334 { "echoctl",ECHOCTL,M_LIN },
335 # endif /* ECHOCTL */
337 { "echoprt",ECHOPRT,M_LIN },
338 # endif /* ECHOPRT */
340 { "echoke", ECHOKE, M_LIN },
343 { "defecho",DEFECHO,M_LIN },
344 # endif /* DEFECHO */
346 { "flusho", FLUSHO, M_LIN },
349 { "pendin", PENDIN, M_LIN },
352 { "iexten", IEXTEN, M_LIN },
355 { "nokerninfo",NOKERNINFO,M_LIN },
356 # endif /* NOKERNINFO */
358 { "altwerase",ALTWERASE,M_LIN },
359 # endif /* ALTWERASE */
361 { "extproc",EXTPROC, M_LIN },
362 # endif /* EXTPROC */
365 { "intr", C_SH(C_INTR), M_CHAR },
368 { "quit", C_SH(C_QUIT), M_CHAR },
371 { "erase", C_SH(C_ERASE), M_CHAR },
374 { "kill", C_SH(C_KILL), M_CHAR },
377 { "eof", C_SH(C_EOF), M_CHAR },
380 { "eol", C_SH(C_EOL), M_CHAR },
383 { "eol2", C_SH(C_EOL2), M_CHAR },
386 { "swtch", C_SH(C_SWTCH), M_CHAR },
388 # if defined(VDSWTCH)
389 { "dswtch", C_SH(C_DSWTCH), M_CHAR },
390 # endif /* VDSWTCH */
391 # if defined(VERASE2)
392 { "erase2", C_SH(C_ERASE2), M_CHAR },
393 # endif /* VERASE2 */
395 { "start", C_SH(C_START), M_CHAR },
398 { "stop", C_SH(C_STOP), M_CHAR },
400 # if defined(VWERASE)
401 { "werase", C_SH(C_WERASE), M_CHAR },
402 # endif /* VWERASE */
404 { "susp", C_SH(C_SUSP), M_CHAR },
407 { "dsusp", C_SH(C_DSUSP), M_CHAR },
409 # if defined(VREPRINT)
410 { "reprint", C_SH(C_REPRINT),M_CHAR },
411 # endif /* VREPRINT */
412 # if defined(VDISCARD)
413 { "discard", C_SH(C_DISCARD),M_CHAR },
414 # endif /* VDISCARD */
416 { "lnext", C_SH(C_LNEXT), M_CHAR },
418 # if defined(VSTATUS)
419 { "status", C_SH(C_STATUS), M_CHAR },
420 # endif /* VSTATUS */
422 { "page", C_SH(C_PAGE), M_CHAR },
425 { "pgoff", C_SH(C_PGOFF), M_CHAR },
428 { "kill2", C_SH(C_KILL2), M_CHAR },
431 { "brk", C_SH(C_BRK), M_CHAR },
434 { "min", C_SH(C_MIN), M_CHAR },
437 { "time", C_SH(C_TIME), M_CHAR },
444 #define tty_getty(el, td) tcgetattr((el)->el_infd, (td))
445 #define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td))
447 #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
448 #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
449 #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
451 private void tty__getchar __P((struct termios *, unsigned char *));
452 private void tty__setchar __P((struct termios *, unsigned char *));
453 private speed_t tty__getspeed __P((struct termios *));
454 private int tty_setup __P((EditLine *));
460 * Get the tty parameters and initialize the editing state
467 if (tty_getty(el, &el->el_tty.t_ed) == -1) {
469 (void) fprintf(el->el_errfile,
470 "tty_setup: tty_getty: %s\n", strerror(errno));
471 #endif /* DEBUG_TTY */
474 el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
476 el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
477 el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
478 el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
481 * Reset the tty chars to reasonable defaults
482 * If they are disabled, then enable them.
485 if (tty__cooked_mode(&el->el_tty.t_ts)) {
486 tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
488 * Don't affect CMIN and CTIME for the editor mode
490 for (rst = 0; rst < C_NCC - 2; rst++)
491 if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
492 el->el_tty.t_c[ED_IO][rst] != el->el_tty.t_vdisable)
493 el->el_tty.t_c[ED_IO][rst] = el->el_tty.t_c[TS_IO][rst];
494 for (rst = 0; rst < C_NCC; rst++)
495 if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
496 el->el_tty.t_c[EX_IO][rst] != el->el_tty.t_vdisable)
497 el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst];
501 el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
502 el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
504 el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
505 el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
507 el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
508 el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
510 el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
511 el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
513 tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
521 el->el_tty.t_mode = EX_IO;
522 el->el_tty.t_vdisable = _POSIX_VDISABLE;
523 (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
524 (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
525 return tty_setup(el);
530 * Restore the tty to its original settings
537 /* XXX: Maybe reset to an initial state? */
550 if ((spd = cfgetispeed(td)) == 0)
551 spd = cfgetospeed(td);
553 } /* end tty__getspeed */
557 * Get the tty characters
565 s[C_INTR] = td->c_cc[VINTR];
568 s[C_QUIT] = td->c_cc[VQUIT];
571 s[C_ERASE] = td->c_cc[VERASE];
574 s[C_KILL] = td->c_cc[VKILL];
577 s[C_EOF] = td->c_cc[VEOF];
580 s[C_EOL] = td->c_cc[VEOL];
583 s[C_EOL2] = td->c_cc[VEOL2];
586 s[C_SWTCH] = td->c_cc[VSWTCH];
589 s[C_DSWTCH] = td->c_cc[VDSWTCH];
590 # endif /* VDSWTCH */
592 s[C_ERASE2] = td->c_cc[VERASE2];
593 # endif /* VERASE2 */
595 s[C_START] = td->c_cc[VSTART];
598 s[C_STOP] = td->c_cc[VSTOP];
601 s[C_WERASE] = td->c_cc[VWERASE];
602 # endif /* VWERASE */
604 s[C_SUSP] = td->c_cc[VSUSP];
607 s[C_DSUSP] = td->c_cc[VDSUSP];
610 s[C_REPRINT]= td->c_cc[VREPRINT];
611 # endif /* VREPRINT */
613 s[C_DISCARD]= td->c_cc[VDISCARD];
614 # endif /* VDISCARD */
616 s[C_LNEXT] = td->c_cc[VLNEXT];
619 s[C_STATUS] = td->c_cc[VSTATUS];
620 # endif /* VSTATUS */
622 s[C_PAGE] = td->c_cc[VPAGE];
625 s[C_PGOFF] = td->c_cc[VPGOFF];
628 s[C_KILL2] = td->c_cc[VKILL2];
631 s[C_MIN] = td->c_cc[VMIN];
634 s[C_TIME] = td->c_cc[VTIME];
640 * Set the tty characters
648 td->c_cc[VINTR] = s[C_INTR];
651 td->c_cc[VQUIT] = s[C_QUIT];
654 td->c_cc[VERASE] = s[C_ERASE];
657 td->c_cc[VKILL] = s[C_KILL];
660 td->c_cc[VEOF] = s[C_EOF];
663 td->c_cc[VEOL] = s[C_EOL];
666 td->c_cc[VEOL2] = s[C_EOL2];
669 td->c_cc[VSWTCH] = s[C_SWTCH];
672 td->c_cc[VDSWTCH] = s[C_DSWTCH];
673 # endif /* VDSWTCH */
675 td->c_cc[VERASE2] = s[C_ERASE2];
676 # endif /* VERASE2 */
678 td->c_cc[VSTART] = s[C_START];
681 td->c_cc[VSTOP] = s[C_STOP];
684 td->c_cc[VWERASE] = s[C_WERASE];
685 # endif /* VWERASE */
687 td->c_cc[VSUSP] = s[C_SUSP];
690 td->c_cc[VDSUSP] = s[C_DSUSP];
693 td->c_cc[VREPRINT] = s[C_REPRINT];
694 # endif /* VREPRINT */
696 td->c_cc[VDISCARD] = s[C_DISCARD];
697 # endif /* VDISCARD */
699 td->c_cc[VLNEXT] = s[C_LNEXT];
702 td->c_cc[VSTATUS] = s[C_STATUS];
703 # endif /* VSTATUS */
705 td->c_cc[VPAGE] = s[C_PAGE];
708 td->c_cc[VPGOFF] = s[C_PGOFF];
711 td->c_cc[VKILL2] = s[C_KILL2];
714 td->c_cc[VMIN] = s[C_MIN];
717 td->c_cc[VTIME] = s[C_TIME];
723 * Rebind the editline functions
726 tty_bind_char(el, force)
730 unsigned char *t_n = el->el_tty.t_c[ED_IO];
731 unsigned char *t_o = el->el_tty.t_ed.c_cc;
734 el_action_t *dmap, *dalt, *map, *alt;
735 new[1] = old[1] = '\0';
738 map = el->el_map.key;
739 alt = el->el_map.alt;
740 if (el->el_map.type == MAP_VI) {
741 dmap = el->el_map.vii;
742 dalt = el->el_map.vic;
745 dmap = el->el_map.emacs;
749 for (tp = tty_map; tp->nch != -1; tp++) {
750 new[0] = t_n[tp->nch];
751 old[0] = t_o[tp->och];
752 if (new[0] == old[0] && !force)
754 /* Put the old default binding back, and set the new binding */
755 key_clear(el, map, old);
756 map[old[0]] = dmap[old[0]];
757 key_clear(el, map, new);
758 /* MAP_VI == 1, MAP_EMACS == 0... */
759 map[new[0]] = tp->bind[el->el_map.type];
761 key_clear(el, alt, old);
762 alt[old[0]] = dalt[old[0]];
763 key_clear(el, alt, new);
764 alt[new[0]] = tp->bind[el->el_map.type+1];
770 * Set terminal into 1 character at a time mode.
776 if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
779 if (tty_getty(el, &el->el_tty.t_ts) == -1) {
781 (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", strerror(errno));
782 #endif /* DEBUG_TTY */
787 * We always keep up with the eight bit setting and the speed of the
788 * tty. But only we only believe changes that are made to cooked mode!
790 el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
791 el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
793 if (tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
794 (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
795 (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
798 if (tty__cooked_mode(&el->el_tty.t_ts)) {
799 if ((el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) &&
800 (el->el_tty.t_ts.c_cflag != el->el_tty.t_ed.c_cflag)) {
801 el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag;
802 el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
803 el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
806 if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
807 (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
808 el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag;
809 el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
810 el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
813 if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
814 (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
815 el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag;
816 el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
817 el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
820 if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
821 (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
822 el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag;
823 el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
824 el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
827 if (tty__gettabs(&el->el_tty.t_ex) == 0)
828 el->el_tty.t_tabs = 0;
830 el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
835 tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
837 * Check if the user made any changes.
838 * If he did, then propagate the changes to the
839 * edit and execute data structures.
841 for (i = 0; i < C_NCC; i++)
842 if (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])
847 * Propagate changes only to the unprotected chars
848 * that have been modified just now.
850 for (i = 0; i < C_NCC; i++) {
851 if (!((el->el_tty.t_t[ED_IO][M_CHAR].t_setmask & C_SH(i)))
852 && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
853 el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
854 if (el->el_tty.t_t[ED_IO][M_CHAR].t_clrmask & C_SH(i))
855 el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
857 tty_bind_char(el, 0);
858 tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
860 for (i = 0; i < C_NCC; i++) {
861 if (!((el->el_tty.t_t[EX_IO][M_CHAR].t_setmask & C_SH(i)))
862 && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
863 el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
864 if (el->el_tty.t_t[EX_IO][M_CHAR].t_clrmask & C_SH(i))
865 el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
872 if (el->el_tty.t_mode == EX_IO)
873 el->el_tty.t_ex = el->el_tty.t_ts;
875 if (tty_setty(el, &el->el_tty.t_ed) == -1) {
877 (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
879 #endif /* DEBUG_TTY */
882 el->el_tty.t_mode = ED_IO;
884 } /* end tty_rawmode */
888 * Set the tty back to normal mode
893 { /* set tty in normal setup */
894 if (el->el_tty.t_mode == EX_IO)
897 if (tty_setty(el, &el->el_tty.t_ex) == -1) {
899 (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n",
901 #endif /* DEBUG_TTY */
904 el->el_tty.t_mode = EX_IO;
906 } /* end tty_cookedmode */
916 if (el->el_tty.t_mode == QU_IO)
919 el->el_tty.t_qu = el->el_tty.t_ed;
921 el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][M_INP].t_clrmask;
922 el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][M_INP].t_setmask;
924 el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][M_OUT].t_clrmask;
925 el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][M_OUT].t_setmask;
927 el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][M_CTL].t_clrmask;
928 el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][M_CTL].t_setmask;
930 el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][M_LIN].t_clrmask;
931 el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][M_LIN].t_setmask;
933 if (tty_setty(el, &el->el_tty.t_qu) == -1) {
935 (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
937 #endif /* DEBUG_TTY */
940 el->el_tty.t_mode = QU_IO;
942 } /* end tty_quotemode */
945 /* tty_noquotemode():
946 * Turn off quote mode
952 if (el->el_tty.t_mode != QU_IO)
954 if (tty_setty(el, &el->el_tty.t_ed) == -1) {
956 (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
958 #endif /* DEBUG_TTY */
961 el->el_tty.t_mode = ED_IO;
970 tty_stty(el, argc, argv)
986 while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
987 switch (argv[0][1]) {
1005 (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n",
1010 if (!argv || !*argv) {
1012 int len = 0, st = 0, cu;
1013 for (m = ttymodes; m->m_name; m++) {
1014 if (m->m_type != i) {
1015 (void) fprintf(el->el_outfile, "%s%s", i != -1 ? "\n" : "",
1016 el->el_tty.t_t[z][m->m_type].t_name);
1018 st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name);
1021 x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0';
1022 x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '-' : x;
1024 if (x != '\0' || aflag) {
1026 cu = strlen(m->m_name) + (x != '\0') + 1;
1028 if (len + cu >= el->el_term.t_size.h) {
1029 (void) fprintf(el->el_outfile, "\n%*s", st, "");
1036 (void) fprintf(el->el_outfile, "%c%s ", x, m->m_name);
1038 (void) fprintf(el->el_outfile, "%s ", m->m_name);
1041 (void) fprintf(el->el_outfile, "\n");
1045 while (argv && (s = *argv++)) {
1056 for (m = ttymodes; m->m_name; m++)
1057 if (strcmp(m->m_name, d) == 0)
1061 (void) fprintf(el->el_errfile, "%s: Invalid argument `%s'.\n",
1068 el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
1069 el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1072 el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1073 el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
1076 el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1077 el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1082 } /* end tty_stty */
1087 * DEbugging routine to print the tty characters
1090 tty_printchar(el, s)
1097 for (i = 0; i < C_NCC; i++) {
1098 for (m = el->el_tty.t_t; m->m_name; m++)
1099 if (m->m_type == M_CHAR && C_SH(i) == m->m_value)
1102 (void) fprintf(el->el_errfile, "%s ^%c ", m->m_name, s[i] + 'A'-1);
1104 (void) fprintf(el->el_errfile, "\n");
1106 (void) fprintf(el->el_errfile, "\n");