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 $
37 * $DragonFly: src/lib/libedit/tty.c,v 1.3 2003/11/12 20:21:29 eirikn Exp $
39 * @(#)tty.c 8.1 (Berkeley) 6/4/93
43 * tty.c: tty interface stuff
49 typedef struct ttymodes_t {
55 typedef struct ttymap_t {
56 int nch, och; /* Internal and termio rep of chars */
57 el_action_t bind[3]; /* emacs, vi, and vi-cmd */
61 private ttyperm_t ttyperm = {
63 { "iflag:", ICRNL, (INLCR|IGNCR) },
64 { "oflag:", (OPOST|ONLCR), ONLRET },
66 { "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN),
67 (NOFLSH|ECHONL|EXTPROC|FLUSHO) },
71 { "iflag:", (INLCR|ICRNL), IGNCR },
72 { "oflag:", (OPOST|ONLCR), ONLRET },
75 (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO) },
76 { "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)|
77 C_SH(C_SUSP)|C_SH(C_DSUSP)|C_SH(C_EOL)|C_SH(C_DISCARD)|
78 C_SH(C_PGOFF)|C_SH(C_PAGE)|C_SH(C_STATUS)), 0 }
81 { "iflag:", 0, IXON | IXOFF | INLCR | ICRNL },
84 { "lflag:", 0, ISIG | IEXTEN },
89 private ttychar_t ttychar = {
91 CINTR, CQUIT, CERASE, CKILL,
92 CEOF, CEOL, CEOL2, CSWTCH,
93 CDSWTCH, CERASE2, CSTART, CSTOP,
94 CWERASE, CSUSP, CDSUSP, CREPRINT,
95 CDISCARD, CLNEXT, CSTATUS, CPAGE,
96 CPGOFF, CKILL2, CBRK, CMIN,
100 CINTR, CQUIT, CERASE, CKILL,
101 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
102 _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
103 _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
104 CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
105 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
119 private ttymap_t tty_map[] = {
122 { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
126 { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
130 { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
134 { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
138 { EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED } },
142 { ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD } },
145 { C_REPRINT, VREPRINT,
146 { ED_REDISPLAY, ED_INSERT, ED_REDISPLAY } },
147 #endif /* VREPRINT */
150 { ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED } },
153 { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } }
156 private ttymodes_t ttymodes[] = {
158 { "ignbrk", IGNBRK, M_INP },
161 { "brkint", BRKINT, M_INP },
164 { "ignpar", IGNPAR, M_INP },
167 { "parmrk", PARMRK, M_INP },
170 { "inpck", INPCK, M_INP },
173 { "istrip", ISTRIP, M_INP },
176 { "inlcr", INLCR, M_INP },
179 { "igncr", IGNCR, M_INP },
182 { "icrnl", ICRNL, M_INP },
185 { "iuclc", IUCLC, M_INP },
188 { "ixon", IXON, M_INP },
191 { "ixany", IXANY, M_INP },
194 { "ixoff", IXOFF, M_INP },
197 { "imaxbel",IMAXBEL,M_INP },
198 # endif /* IMAXBEL */
201 { "opost", OPOST, M_OUT },
204 { "olcuc", OLCUC, M_OUT },
207 { "onlcr", ONLCR, M_OUT },
210 { "ocrnl", OCRNL, M_OUT },
213 { "onocr", ONOCR, M_OUT },
216 { "onoeot", ONOEOT, M_OUT },
219 { "onlret", ONLRET, M_OUT },
222 { "ofill", OFILL, M_OUT },
225 { "ofdel", OFDEL, M_OUT },
228 { "nldly", NLDLY, M_OUT },
231 { "crdly", CRDLY, M_OUT },
234 { "tabdly", TABDLY, M_OUT },
237 { "xtabs", XTABS, M_OUT },
240 { "bsdly", BSDLY, M_OUT },
243 { "vtdly", VTDLY, M_OUT },
246 { "ffdly", FFDLY, M_OUT },
249 { "pageout",PAGEOUT,M_OUT },
250 # endif /* PAGEOUT */
252 { "wrap", WRAP, M_OUT },
256 { "cignore",CIGNORE,M_CTL },
259 { "cbaud", CBAUD, M_CTL },
262 { "cstopb", CSTOPB, M_CTL },
265 { "cread", CREAD, M_CTL },
268 { "parenb", PARENB, M_CTL },
271 { "parodd", PARODD, M_CTL },
274 { "hupcl", HUPCL, M_CTL },
277 { "clocal", CLOCAL, M_CTL },
280 { "loblk", LOBLK, M_CTL },
283 { "cibaud", CIBAUD, M_CTL },
287 { "ccts_oflow",CCTS_OFLOW,M_CTL },
289 { "crtscts",CRTSCTS,M_CTL },
290 # endif /* CCTS_OFLOW */
291 # endif /* CRTSCTS */
293 { "crts_iflow",CRTS_IFLOW,M_CTL },
294 # endif /* CRTS_IFLOW */
296 { "mdmbuf", MDMBUF, M_CTL },
299 { "rcv1en", RCV1EN, M_CTL },
302 { "xmt1en", XMT1EN, M_CTL },
306 { "isig", ISIG, M_LIN },
309 { "icanon", ICANON, M_LIN },
312 { "xcase", XCASE, M_LIN },
315 { "echo", ECHO, M_LIN },
318 { "echoe", ECHOE, M_LIN },
321 { "echok", ECHOK, M_LIN },
324 { "echonl", ECHONL, M_LIN },
327 { "noflsh", NOFLSH, M_LIN },
330 { "tostop", TOSTOP, M_LIN },
333 { "echoctl",ECHOCTL,M_LIN },
334 # endif /* ECHOCTL */
336 { "echoprt",ECHOPRT,M_LIN },
337 # endif /* ECHOPRT */
339 { "echoke", ECHOKE, M_LIN },
342 { "defecho",DEFECHO,M_LIN },
343 # endif /* DEFECHO */
345 { "flusho", FLUSHO, M_LIN },
348 { "pendin", PENDIN, M_LIN },
351 { "iexten", IEXTEN, M_LIN },
354 { "nokerninfo",NOKERNINFO,M_LIN },
355 # endif /* NOKERNINFO */
357 { "altwerase",ALTWERASE,M_LIN },
358 # endif /* ALTWERASE */
360 { "extproc",EXTPROC, M_LIN },
361 # endif /* EXTPROC */
364 { "intr", C_SH(C_INTR), M_CHAR },
367 { "quit", C_SH(C_QUIT), M_CHAR },
370 { "erase", C_SH(C_ERASE), M_CHAR },
373 { "kill", C_SH(C_KILL), M_CHAR },
376 { "eof", C_SH(C_EOF), M_CHAR },
379 { "eol", C_SH(C_EOL), M_CHAR },
382 { "eol2", C_SH(C_EOL2), M_CHAR },
385 { "swtch", C_SH(C_SWTCH), M_CHAR },
387 # if defined(VDSWTCH)
388 { "dswtch", C_SH(C_DSWTCH), M_CHAR },
389 # endif /* VDSWTCH */
390 # if defined(VERASE2)
391 { "erase2", C_SH(C_ERASE2), M_CHAR },
392 # endif /* VERASE2 */
394 { "start", C_SH(C_START), M_CHAR },
397 { "stop", C_SH(C_STOP), M_CHAR },
399 # if defined(VWERASE)
400 { "werase", C_SH(C_WERASE), M_CHAR },
401 # endif /* VWERASE */
403 { "susp", C_SH(C_SUSP), M_CHAR },
406 { "dsusp", C_SH(C_DSUSP), M_CHAR },
408 # if defined(VREPRINT)
409 { "reprint", C_SH(C_REPRINT),M_CHAR },
410 # endif /* VREPRINT */
411 # if defined(VDISCARD)
412 { "discard", C_SH(C_DISCARD),M_CHAR },
413 # endif /* VDISCARD */
415 { "lnext", C_SH(C_LNEXT), M_CHAR },
417 # if defined(VSTATUS)
418 { "status", C_SH(C_STATUS), M_CHAR },
419 # endif /* VSTATUS */
421 { "page", C_SH(C_PAGE), M_CHAR },
424 { "pgoff", C_SH(C_PGOFF), M_CHAR },
427 { "kill2", C_SH(C_KILL2), M_CHAR },
430 { "brk", C_SH(C_BRK), M_CHAR },
433 { "min", C_SH(C_MIN), M_CHAR },
436 { "time", C_SH(C_TIME), M_CHAR },
443 #define tty_getty(el, td) tcgetattr((el)->el_infd, (td))
444 #define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td))
446 #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
447 #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
448 #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
450 private void tty__getchar (struct termios *, unsigned char *);
451 private void tty__setchar (struct termios *, unsigned char *);
452 private speed_t tty__getspeed (struct termios *);
453 private int tty_setup (EditLine *);
459 * Get the tty parameters and initialize the editing state
466 if (tty_getty(el, &el->el_tty.t_ed) == -1) {
468 (void) fprintf(el->el_errfile,
469 "tty_setup: tty_getty: %s\n", strerror(errno));
470 #endif /* DEBUG_TTY */
473 el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
475 el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
476 el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
477 el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
480 * Reset the tty chars to reasonable defaults
481 * If they are disabled, then enable them.
484 if (tty__cooked_mode(&el->el_tty.t_ts)) {
485 tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
487 * Don't affect CMIN and CTIME for the editor mode
489 for (rst = 0; rst < C_NCC - 2; rst++)
490 if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
491 el->el_tty.t_c[ED_IO][rst] != el->el_tty.t_vdisable)
492 el->el_tty.t_c[ED_IO][rst] = el->el_tty.t_c[TS_IO][rst];
493 for (rst = 0; rst < C_NCC; rst++)
494 if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
495 el->el_tty.t_c[EX_IO][rst] != el->el_tty.t_vdisable)
496 el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst];
500 el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
501 el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
503 el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
504 el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
506 el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
507 el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
509 el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
510 el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
512 tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
520 el->el_tty.t_mode = EX_IO;
521 el->el_tty.t_vdisable = _POSIX_VDISABLE;
522 (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
523 (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
524 return tty_setup(el);
529 * Restore the tty to its original settings
536 /* XXX: Maybe reset to an initial state? */
549 if ((spd = cfgetispeed(td)) == 0)
550 spd = cfgetospeed(td);
552 } /* end tty__getspeed */
556 * Get the tty characters
564 s[C_INTR] = td->c_cc[VINTR];
567 s[C_QUIT] = td->c_cc[VQUIT];
570 s[C_ERASE] = td->c_cc[VERASE];
573 s[C_KILL] = td->c_cc[VKILL];
576 s[C_EOF] = td->c_cc[VEOF];
579 s[C_EOL] = td->c_cc[VEOL];
582 s[C_EOL2] = td->c_cc[VEOL2];
585 s[C_SWTCH] = td->c_cc[VSWTCH];
588 s[C_DSWTCH] = td->c_cc[VDSWTCH];
589 # endif /* VDSWTCH */
591 s[C_ERASE2] = td->c_cc[VERASE2];
592 # endif /* VERASE2 */
594 s[C_START] = td->c_cc[VSTART];
597 s[C_STOP] = td->c_cc[VSTOP];
600 s[C_WERASE] = td->c_cc[VWERASE];
601 # endif /* VWERASE */
603 s[C_SUSP] = td->c_cc[VSUSP];
606 s[C_DSUSP] = td->c_cc[VDSUSP];
609 s[C_REPRINT]= td->c_cc[VREPRINT];
610 # endif /* VREPRINT */
612 s[C_DISCARD]= td->c_cc[VDISCARD];
613 # endif /* VDISCARD */
615 s[C_LNEXT] = td->c_cc[VLNEXT];
618 s[C_STATUS] = td->c_cc[VSTATUS];
619 # endif /* VSTATUS */
621 s[C_PAGE] = td->c_cc[VPAGE];
624 s[C_PGOFF] = td->c_cc[VPGOFF];
627 s[C_KILL2] = td->c_cc[VKILL2];
630 s[C_MIN] = td->c_cc[VMIN];
633 s[C_TIME] = td->c_cc[VTIME];
639 * Set the tty characters
647 td->c_cc[VINTR] = s[C_INTR];
650 td->c_cc[VQUIT] = s[C_QUIT];
653 td->c_cc[VERASE] = s[C_ERASE];
656 td->c_cc[VKILL] = s[C_KILL];
659 td->c_cc[VEOF] = s[C_EOF];
662 td->c_cc[VEOL] = s[C_EOL];
665 td->c_cc[VEOL2] = s[C_EOL2];
668 td->c_cc[VSWTCH] = s[C_SWTCH];
671 td->c_cc[VDSWTCH] = s[C_DSWTCH];
672 # endif /* VDSWTCH */
674 td->c_cc[VERASE2] = s[C_ERASE2];
675 # endif /* VERASE2 */
677 td->c_cc[VSTART] = s[C_START];
680 td->c_cc[VSTOP] = s[C_STOP];
683 td->c_cc[VWERASE] = s[C_WERASE];
684 # endif /* VWERASE */
686 td->c_cc[VSUSP] = s[C_SUSP];
689 td->c_cc[VDSUSP] = s[C_DSUSP];
692 td->c_cc[VREPRINT] = s[C_REPRINT];
693 # endif /* VREPRINT */
695 td->c_cc[VDISCARD] = s[C_DISCARD];
696 # endif /* VDISCARD */
698 td->c_cc[VLNEXT] = s[C_LNEXT];
701 td->c_cc[VSTATUS] = s[C_STATUS];
702 # endif /* VSTATUS */
704 td->c_cc[VPAGE] = s[C_PAGE];
707 td->c_cc[VPGOFF] = s[C_PGOFF];
710 td->c_cc[VKILL2] = s[C_KILL2];
713 td->c_cc[VMIN] = s[C_MIN];
716 td->c_cc[VTIME] = s[C_TIME];
722 * Rebind the editline functions
725 tty_bind_char(el, force)
729 unsigned char *t_n = el->el_tty.t_c[ED_IO];
730 unsigned char *t_o = el->el_tty.t_ed.c_cc;
733 el_action_t *dmap, *dalt, *map, *alt;
734 new[1] = old[1] = '\0';
737 map = el->el_map.key;
738 alt = el->el_map.alt;
739 if (el->el_map.type == MAP_VI) {
740 dmap = el->el_map.vii;
741 dalt = el->el_map.vic;
744 dmap = el->el_map.emacs;
748 for (tp = tty_map; tp->nch != -1; tp++) {
749 new[0] = t_n[tp->nch];
750 old[0] = t_o[tp->och];
751 if (new[0] == old[0] && !force)
753 /* Put the old default binding back, and set the new binding */
754 key_clear(el, map, old);
755 map[old[0]] = dmap[old[0]];
756 key_clear(el, map, new);
757 /* MAP_VI == 1, MAP_EMACS == 0... */
758 map[new[0]] = tp->bind[el->el_map.type];
760 key_clear(el, alt, old);
761 alt[old[0]] = dalt[old[0]];
762 key_clear(el, alt, new);
763 alt[new[0]] = tp->bind[el->el_map.type+1];
769 * Set terminal into 1 character at a time mode.
775 if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
778 if (tty_getty(el, &el->el_tty.t_ts) == -1) {
780 (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", strerror(errno));
781 #endif /* DEBUG_TTY */
786 * We always keep up with the eight bit setting and the speed of the
787 * tty. But only we only believe changes that are made to cooked mode!
789 el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
790 el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
792 if (tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
793 (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
794 (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
797 if (tty__cooked_mode(&el->el_tty.t_ts)) {
798 if ((el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) &&
799 (el->el_tty.t_ts.c_cflag != el->el_tty.t_ed.c_cflag)) {
800 el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag;
801 el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
802 el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
805 if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
806 (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
807 el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag;
808 el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
809 el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
812 if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
813 (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
814 el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag;
815 el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
816 el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
819 if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
820 (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
821 el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag;
822 el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
823 el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
826 if (tty__gettabs(&el->el_tty.t_ex) == 0)
827 el->el_tty.t_tabs = 0;
829 el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
834 tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
836 * Check if the user made any changes.
837 * If he did, then propagate the changes to the
838 * edit and execute data structures.
840 for (i = 0; i < C_NCC; i++)
841 if (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])
846 * Propagate changes only to the unprotected chars
847 * that have been modified just now.
849 for (i = 0; i < C_NCC; i++) {
850 if (!((el->el_tty.t_t[ED_IO][M_CHAR].t_setmask & C_SH(i)))
851 && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
852 el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
853 if (el->el_tty.t_t[ED_IO][M_CHAR].t_clrmask & C_SH(i))
854 el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
856 tty_bind_char(el, 0);
857 tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
859 for (i = 0; i < C_NCC; i++) {
860 if (!((el->el_tty.t_t[EX_IO][M_CHAR].t_setmask & C_SH(i)))
861 && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
862 el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
863 if (el->el_tty.t_t[EX_IO][M_CHAR].t_clrmask & C_SH(i))
864 el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
871 if (el->el_tty.t_mode == EX_IO)
872 el->el_tty.t_ex = el->el_tty.t_ts;
874 if (tty_setty(el, &el->el_tty.t_ed) == -1) {
876 (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
878 #endif /* DEBUG_TTY */
881 el->el_tty.t_mode = ED_IO;
883 } /* end tty_rawmode */
887 * Set the tty back to normal mode
892 { /* set tty in normal setup */
893 if (el->el_tty.t_mode == EX_IO)
896 if (tty_setty(el, &el->el_tty.t_ex) == -1) {
898 (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n",
900 #endif /* DEBUG_TTY */
903 el->el_tty.t_mode = EX_IO;
905 } /* end tty_cookedmode */
915 if (el->el_tty.t_mode == QU_IO)
918 el->el_tty.t_qu = el->el_tty.t_ed;
920 el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][M_INP].t_clrmask;
921 el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][M_INP].t_setmask;
923 el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][M_OUT].t_clrmask;
924 el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][M_OUT].t_setmask;
926 el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][M_CTL].t_clrmask;
927 el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][M_CTL].t_setmask;
929 el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][M_LIN].t_clrmask;
930 el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][M_LIN].t_setmask;
932 if (tty_setty(el, &el->el_tty.t_qu) == -1) {
934 (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
936 #endif /* DEBUG_TTY */
939 el->el_tty.t_mode = QU_IO;
941 } /* end tty_quotemode */
944 /* tty_noquotemode():
945 * Turn off quote mode
951 if (el->el_tty.t_mode != QU_IO)
953 if (tty_setty(el, &el->el_tty.t_ed) == -1) {
955 (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
957 #endif /* DEBUG_TTY */
960 el->el_tty.t_mode = ED_IO;
969 tty_stty(el, argc, argv)
985 while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
986 switch (argv[0][1]) {
1004 (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n",
1009 if (!argv || !*argv) {
1011 int len = 0, st = 0, cu;
1012 for (m = ttymodes; m->m_name; m++) {
1013 if (m->m_type != i) {
1014 (void) fprintf(el->el_outfile, "%s%s", i != -1 ? "\n" : "",
1015 el->el_tty.t_t[z][m->m_type].t_name);
1017 st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name);
1020 x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0';
1021 x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '-' : x;
1023 if (x != '\0' || aflag) {
1025 cu = strlen(m->m_name) + (x != '\0') + 1;
1027 if (len + cu >= el->el_term.t_size.h) {
1028 (void) fprintf(el->el_outfile, "\n%*s", st, "");
1035 (void) fprintf(el->el_outfile, "%c%s ", x, m->m_name);
1037 (void) fprintf(el->el_outfile, "%s ", m->m_name);
1040 (void) fprintf(el->el_outfile, "\n");
1044 while (argv && (s = *argv++)) {
1055 for (m = ttymodes; m->m_name; m++)
1056 if (strcmp(m->m_name, d) == 0)
1060 (void) fprintf(el->el_errfile, "%s: Invalid argument `%s'.\n",
1067 el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
1068 el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1071 el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1072 el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
1075 el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1076 el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1081 } /* end tty_stty */
1086 * DEbugging routine to print the tty characters
1089 tty_printchar(el, s)
1096 for (i = 0; i < C_NCC; i++) {
1097 for (m = el->el_tty.t_t; m->m_name; m++)
1098 if (m->m_type == M_CHAR && C_SH(i) == m->m_value)
1101 (void) fprintf(el->el_errfile, "%s ^%c ", m->m_name, s[i] + 'A'-1);
1103 (void) fprintf(el->el_errfile, "\n");
1105 (void) fprintf(el->el_errfile, "\n");