153c4c077Sbostic /*-
2*f5b291e3Sbostic * Copyright (c) 1992, 1993
3*f5b291e3Sbostic * The Regents of the University of California. All rights reserved.
453c4c077Sbostic *
553c4c077Sbostic * This code is derived from software contributed to Berkeley by
653c4c077Sbostic * Christos Zoulas of Cornell University.
753c4c077Sbostic *
853c4c077Sbostic * %sccs.include.redist.c%
953c4c077Sbostic */
1053c4c077Sbostic
118cbf4338Schristos #if !defined(lint) && !defined(SCCSID)
12*f5b291e3Sbostic static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 06/04/93";
138cbf4338Schristos #endif /* not lint && not SCCSID */
1453c4c077Sbostic
1553c4c077Sbostic /*
168cbf4338Schristos * tty.c: tty interface stuff
1753c4c077Sbostic */
1853c4c077Sbostic #include "sys.h"
1953c4c077Sbostic #include "tty.h"
2053c4c077Sbostic #include "el.h"
2153c4c077Sbostic
220d4ffa7bSmarc typedef struct ttymodes_t {
230d4ffa7bSmarc char *m_name;
240d4ffa7bSmarc int m_value;
250d4ffa7bSmarc int m_type;
260d4ffa7bSmarc } ttymodes_t;
270d4ffa7bSmarc
280d4ffa7bSmarc typedef struct ttymap_t {
290d4ffa7bSmarc int nch, och; /* Internal and termio rep of chars */
300d4ffa7bSmarc el_action_t bind[3]; /* emacs, vi, and vi-cmd */
310d4ffa7bSmarc } ttymap_t;
320d4ffa7bSmarc
330d4ffa7bSmarc
3453c4c077Sbostic private ttyperm_t ttyperm = {
3553c4c077Sbostic {
3653c4c077Sbostic { "iflag:", ICRNL, (INLCR|IGNCR) },
3753c4c077Sbostic { "oflag:", (OPOST|ONLCR), ONLRET },
3853c4c077Sbostic { "cflag:", 0, 0 },
3953c4c077Sbostic { "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN),
4053c4c077Sbostic (NOFLSH|ECHONL|EXTPROC|FLUSHO) },
4153c4c077Sbostic { "chars:", 0, 0 },
4253c4c077Sbostic },
4353c4c077Sbostic {
4453c4c077Sbostic { "iflag:", (INLCR|ICRNL), IGNCR },
4553c4c077Sbostic { "oflag:", (OPOST|ONLCR), ONLRET },
4653c4c077Sbostic { "cflag:", 0, 0 },
4753c4c077Sbostic { "lflag:", ISIG,
4853c4c077Sbostic (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO) },
4953c4c077Sbostic { "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)|
500d4ffa7bSmarc C_SH(C_SUSP)|C_SH(C_DSUSP)|C_SH(C_EOL)|C_SH(C_DISCARD)|
510d4ffa7bSmarc C_SH(C_PGOFF)|C_SH(C_PAGE)|C_SH(C_STATUS)), 0 }
5253c4c077Sbostic },
5353c4c077Sbostic {
5453c4c077Sbostic { "iflag:", 0, IXON | IXOFF },
5553c4c077Sbostic { "oflag:", 0, 0 },
5653c4c077Sbostic { "cflag:", 0, 0 },
5753c4c077Sbostic { "lflag:", 0, ISIG | IEXTEN },
5853c4c077Sbostic { "chars:", 0, 0 },
5953c4c077Sbostic }
6053c4c077Sbostic };
6153c4c077Sbostic
6253c4c077Sbostic private ttychar_t ttychar = {
6353c4c077Sbostic {
6453c4c077Sbostic CINTR, CQUIT, CERASE, CKILL,
6553c4c077Sbostic CEOF, CEOL, CEOL2, CSWTCH,
6653c4c077Sbostic CDSWTCH, CERASE2, CSTART, CSTOP,
6753c4c077Sbostic CWERASE, CSUSP, CDSUSP, CREPRINT,
6853c4c077Sbostic CDISCARD, CLNEXT, CSTATUS, CPAGE,
6953c4c077Sbostic CPGOFF, CKILL2, CBRK, CMIN,
7053c4c077Sbostic CTIME
7153c4c077Sbostic },
7253c4c077Sbostic {
7353c4c077Sbostic CINTR, CQUIT, CERASE, CKILL,
7453c4c077Sbostic _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
7553c4c077Sbostic _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
7653c4c077Sbostic _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
7753c4c077Sbostic CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
7853c4c077Sbostic _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
7953c4c077Sbostic 0
8053c4c077Sbostic },
8153c4c077Sbostic {
8253c4c077Sbostic 0, 0, 0, 0,
8353c4c077Sbostic 0, 0, 0, 0,
8453c4c077Sbostic 0, 0, 0, 0,
8553c4c077Sbostic 0, 0, 0, 0,
8653c4c077Sbostic 0, 0, 0, 0,
8753c4c077Sbostic 0, 0, 0, 0,
8853c4c077Sbostic 0
8953c4c077Sbostic }
9053c4c077Sbostic };
9153c4c077Sbostic
920d4ffa7bSmarc private ttymap_t tty_map[] = {
930d4ffa7bSmarc #ifdef VERASE
940d4ffa7bSmarc { C_ERASE, VERASE,
950d4ffa7bSmarc { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
960d4ffa7bSmarc #endif /* VERASE */
970d4ffa7bSmarc #ifdef VERASE2
980d4ffa7bSmarc { C_ERASE2, VERASE2,
990d4ffa7bSmarc { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
1000d4ffa7bSmarc #endif /* VERASE2 */
1010d4ffa7bSmarc #ifdef VKILL
1020d4ffa7bSmarc { C_KILL, VKILL,
1030d4ffa7bSmarc { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
1040d4ffa7bSmarc #endif /* VKILL */
1050d4ffa7bSmarc #ifdef VKILL2
1060d4ffa7bSmarc { C_KILL2, VKILL2,
1070d4ffa7bSmarc { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
1080d4ffa7bSmarc #endif /* VKILL2 */
1090d4ffa7bSmarc #ifdef VEOF
1100d4ffa7bSmarc { C_EOF, VEOF,
1110d4ffa7bSmarc { EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED } },
1120d4ffa7bSmarc #endif /* VEOF */
1130d4ffa7bSmarc #ifdef VWERASE
1140d4ffa7bSmarc { C_WERASE, VWERASE,
1150d4ffa7bSmarc { ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD } },
1160d4ffa7bSmarc #endif /* VWERASE */
1170d4ffa7bSmarc #ifdef VREPRINT
1180d4ffa7bSmarc { C_REPRINT, VREPRINT,
1190d4ffa7bSmarc { ED_REDISPLAY, ED_INSERT, ED_REDISPLAY } },
1200d4ffa7bSmarc #endif /* VREPRINT */
1210d4ffa7bSmarc #ifdef VLNEXT
1220d4ffa7bSmarc { C_LNEXT, VLNEXT,
1230d4ffa7bSmarc { ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED } },
1240d4ffa7bSmarc #endif /* VLNEXT */
1250d4ffa7bSmarc { -1, -1,
1260d4ffa7bSmarc { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } }
1270d4ffa7bSmarc };
12853c4c077Sbostic
12953c4c077Sbostic private ttymodes_t ttymodes[] = {
13053c4c077Sbostic # ifdef IGNBRK
13153c4c077Sbostic { "ignbrk", IGNBRK, M_INP },
13253c4c077Sbostic # endif /* IGNBRK */
13353c4c077Sbostic # ifdef BRKINT
13453c4c077Sbostic { "brkint", BRKINT, M_INP },
13553c4c077Sbostic # endif /* BRKINT */
13653c4c077Sbostic # ifdef IGNPAR
13753c4c077Sbostic { "ignpar", IGNPAR, M_INP },
13853c4c077Sbostic # endif /* IGNPAR */
13953c4c077Sbostic # ifdef PARMRK
14053c4c077Sbostic { "parmrk", PARMRK, M_INP },
14153c4c077Sbostic # endif /* PARMRK */
14253c4c077Sbostic # ifdef INPCK
14353c4c077Sbostic { "inpck", INPCK, M_INP },
14453c4c077Sbostic # endif /* INPCK */
14553c4c077Sbostic # ifdef ISTRIP
14653c4c077Sbostic { "istrip", ISTRIP, M_INP },
14753c4c077Sbostic # endif /* ISTRIP */
14853c4c077Sbostic # ifdef INLCR
14953c4c077Sbostic { "inlcr", INLCR, M_INP },
15053c4c077Sbostic # endif /* INLCR */
15153c4c077Sbostic # ifdef IGNCR
15253c4c077Sbostic { "igncr", IGNCR, M_INP },
15353c4c077Sbostic # endif /* IGNCR */
15453c4c077Sbostic # ifdef ICRNL
15553c4c077Sbostic { "icrnl", ICRNL, M_INP },
15653c4c077Sbostic # endif /* ICRNL */
15753c4c077Sbostic # ifdef IUCLC
15853c4c077Sbostic { "iuclc", IUCLC, M_INP },
15953c4c077Sbostic # endif /* IUCLC */
16053c4c077Sbostic # ifdef IXON
16153c4c077Sbostic { "ixon", IXON, M_INP },
16253c4c077Sbostic # endif /* IXON */
16353c4c077Sbostic # ifdef IXANY
16453c4c077Sbostic { "ixany", IXANY, M_INP },
16553c4c077Sbostic # endif /* IXANY */
16653c4c077Sbostic # ifdef IXOFF
16753c4c077Sbostic { "ixoff", IXOFF, M_INP },
16853c4c077Sbostic # endif /* IXOFF */
16953c4c077Sbostic # ifdef IMAXBEL
17053c4c077Sbostic { "imaxbel",IMAXBEL,M_INP },
17153c4c077Sbostic # endif /* IMAXBEL */
17253c4c077Sbostic
17353c4c077Sbostic # ifdef OPOST
17453c4c077Sbostic { "opost", OPOST, M_OUT },
17553c4c077Sbostic # endif /* OPOST */
17653c4c077Sbostic # ifdef OLCUC
17753c4c077Sbostic { "olcuc", OLCUC, M_OUT },
17853c4c077Sbostic # endif /* OLCUC */
17953c4c077Sbostic # ifdef ONLCR
18053c4c077Sbostic { "onlcr", ONLCR, M_OUT },
18153c4c077Sbostic # endif /* ONLCR */
18253c4c077Sbostic # ifdef OCRNL
18353c4c077Sbostic { "ocrnl", OCRNL, M_OUT },
18453c4c077Sbostic # endif /* OCRNL */
18553c4c077Sbostic # ifdef ONOCR
18653c4c077Sbostic { "onocr", ONOCR, M_OUT },
18753c4c077Sbostic # endif /* ONOCR */
18853c4c077Sbostic # ifdef ONOEOT
18953c4c077Sbostic { "onoeot", ONOEOT, M_OUT },
19053c4c077Sbostic # endif /* ONOEOT */
19153c4c077Sbostic # ifdef ONLRET
19253c4c077Sbostic { "onlret", ONLRET, M_OUT },
19353c4c077Sbostic # endif /* ONLRET */
19453c4c077Sbostic # ifdef OFILL
19553c4c077Sbostic { "ofill", OFILL, M_OUT },
19653c4c077Sbostic # endif /* OFILL */
19753c4c077Sbostic # ifdef OFDEL
19853c4c077Sbostic { "ofdel", OFDEL, M_OUT },
19953c4c077Sbostic # endif /* OFDEL */
20053c4c077Sbostic # ifdef NLDLY
20153c4c077Sbostic { "nldly", NLDLY, M_OUT },
20253c4c077Sbostic # endif /* NLDLY */
20353c4c077Sbostic # ifdef CRDLY
20453c4c077Sbostic { "crdly", CRDLY, M_OUT },
20553c4c077Sbostic # endif /* CRDLY */
20653c4c077Sbostic # ifdef TABDLY
20753c4c077Sbostic { "tabdly", TABDLY, M_OUT },
20853c4c077Sbostic # endif /* TABDLY */
20953c4c077Sbostic # ifdef XTABS
21053c4c077Sbostic { "xtabs", XTABS, M_OUT },
21153c4c077Sbostic # endif /* XTABS */
21253c4c077Sbostic # ifdef BSDLY
21353c4c077Sbostic { "bsdly", BSDLY, M_OUT },
21453c4c077Sbostic # endif /* BSDLY */
21553c4c077Sbostic # ifdef VTDLY
21653c4c077Sbostic { "vtdly", VTDLY, M_OUT },
21753c4c077Sbostic # endif /* VTDLY */
21853c4c077Sbostic # ifdef FFDLY
21953c4c077Sbostic { "ffdly", FFDLY, M_OUT },
22053c4c077Sbostic # endif /* FFDLY */
22153c4c077Sbostic # ifdef PAGEOUT
22253c4c077Sbostic { "pageout",PAGEOUT,M_OUT },
22353c4c077Sbostic # endif /* PAGEOUT */
22453c4c077Sbostic # ifdef WRAP
22553c4c077Sbostic { "wrap", WRAP, M_OUT },
22653c4c077Sbostic # endif /* WRAP */
22753c4c077Sbostic
22853c4c077Sbostic # ifdef CIGNORE
22953c4c077Sbostic { "cignore",CIGNORE,M_CTL },
23053c4c077Sbostic # endif /* CBAUD */
23153c4c077Sbostic # ifdef CBAUD
23253c4c077Sbostic { "cbaud", CBAUD, M_CTL },
23353c4c077Sbostic # endif /* CBAUD */
23453c4c077Sbostic # ifdef CSTOPB
23553c4c077Sbostic { "cstopb", CSTOPB, M_CTL },
23653c4c077Sbostic # endif /* CSTOPB */
23753c4c077Sbostic # ifdef CREAD
23853c4c077Sbostic { "cread", CREAD, M_CTL },
23953c4c077Sbostic # endif /* CREAD */
24053c4c077Sbostic # ifdef PARENB
24153c4c077Sbostic { "parenb", PARENB, M_CTL },
24253c4c077Sbostic # endif /* PARENB */
24353c4c077Sbostic # ifdef PARODD
24453c4c077Sbostic { "parodd", PARODD, M_CTL },
24553c4c077Sbostic # endif /* PARODD */
24653c4c077Sbostic # ifdef HUPCL
24753c4c077Sbostic { "hupcl", HUPCL, M_CTL },
24853c4c077Sbostic # endif /* HUPCL */
24953c4c077Sbostic # ifdef CLOCAL
25053c4c077Sbostic { "clocal", CLOCAL, M_CTL },
25153c4c077Sbostic # endif /* CLOCAL */
25253c4c077Sbostic # ifdef LOBLK
25353c4c077Sbostic { "loblk", LOBLK, M_CTL },
25453c4c077Sbostic # endif /* LOBLK */
25553c4c077Sbostic # ifdef CIBAUD
25653c4c077Sbostic { "cibaud", CIBAUD, M_CTL },
25753c4c077Sbostic # endif /* CIBAUD */
25853c4c077Sbostic # ifdef CRTSCTS
25953c4c077Sbostic # ifdef CCTS_OFLOW
26053c4c077Sbostic { "ccts_oflow",CCTS_OFLOW,M_CTL },
26153c4c077Sbostic # else
26253c4c077Sbostic { "crtscts",CRTSCTS,M_CTL },
26353c4c077Sbostic # endif /* CCTS_OFLOW */
26453c4c077Sbostic # endif /* CRTSCTS */
26553c4c077Sbostic # ifdef CRTS_IFLOW
26653c4c077Sbostic { "crts_iflow",CRTS_IFLOW,M_CTL },
26753c4c077Sbostic # endif /* CRTS_IFLOW */
26853c4c077Sbostic # ifdef MDMBUF
26953c4c077Sbostic { "mdmbuf", MDMBUF, M_CTL },
27053c4c077Sbostic # endif /* MDMBUF */
27153c4c077Sbostic # ifdef RCV1EN
27253c4c077Sbostic { "rcv1en", RCV1EN, M_CTL },
27353c4c077Sbostic # endif /* RCV1EN */
27453c4c077Sbostic # ifdef XMT1EN
27553c4c077Sbostic { "xmt1en", XMT1EN, M_CTL },
27653c4c077Sbostic # endif /* XMT1EN */
27753c4c077Sbostic
27853c4c077Sbostic # ifdef ISIG
27953c4c077Sbostic { "isig", ISIG, M_LIN },
28053c4c077Sbostic # endif /* ISIG */
28153c4c077Sbostic # ifdef ICANON
28253c4c077Sbostic { "icanon", ICANON, M_LIN },
28353c4c077Sbostic # endif /* ICANON */
28453c4c077Sbostic # ifdef XCASE
28553c4c077Sbostic { "xcase", XCASE, M_LIN },
28653c4c077Sbostic # endif /* XCASE */
28753c4c077Sbostic # ifdef ECHO
28853c4c077Sbostic { "echo", ECHO, M_LIN },
28953c4c077Sbostic # endif /* ECHO */
29053c4c077Sbostic # ifdef ECHOE
29153c4c077Sbostic { "echoe", ECHOE, M_LIN },
29253c4c077Sbostic # endif /* ECHOE */
29353c4c077Sbostic # ifdef ECHOK
29453c4c077Sbostic { "echok", ECHOK, M_LIN },
29553c4c077Sbostic # endif /* ECHOK */
29653c4c077Sbostic # ifdef ECHONL
29753c4c077Sbostic { "echonl", ECHONL, M_LIN },
29853c4c077Sbostic # endif /* ECHONL */
29953c4c077Sbostic # ifdef NOFLSH
30053c4c077Sbostic { "noflsh", NOFLSH, M_LIN },
30153c4c077Sbostic # endif /* NOFLSH */
30253c4c077Sbostic # ifdef TOSTOP
30353c4c077Sbostic { "tostop", TOSTOP, M_LIN },
30453c4c077Sbostic # endif /* TOSTOP */
30553c4c077Sbostic # ifdef ECHOCTL
30653c4c077Sbostic { "echoctl",ECHOCTL,M_LIN },
30753c4c077Sbostic # endif /* ECHOCTL */
30853c4c077Sbostic # ifdef ECHOPRT
30953c4c077Sbostic { "echoprt",ECHOPRT,M_LIN },
31053c4c077Sbostic # endif /* ECHOPRT */
31153c4c077Sbostic # ifdef ECHOKE
31253c4c077Sbostic { "echoke", ECHOKE, M_LIN },
31353c4c077Sbostic # endif /* ECHOKE */
31453c4c077Sbostic # ifdef DEFECHO
31553c4c077Sbostic { "defecho",DEFECHO,M_LIN },
31653c4c077Sbostic # endif /* DEFECHO */
31753c4c077Sbostic # ifdef FLUSHO
31853c4c077Sbostic { "flusho", FLUSHO, M_LIN },
31953c4c077Sbostic # endif /* FLUSHO */
32053c4c077Sbostic # ifdef PENDIN
32153c4c077Sbostic { "pendin", PENDIN, M_LIN },
32253c4c077Sbostic # endif /* PENDIN */
32353c4c077Sbostic # ifdef IEXTEN
32453c4c077Sbostic { "iexten", IEXTEN, M_LIN },
32553c4c077Sbostic # endif /* IEXTEN */
32653c4c077Sbostic # ifdef NOKERNINFO
32753c4c077Sbostic { "nokerninfo",NOKERNINFO,M_LIN },
32853c4c077Sbostic # endif /* NOKERNINFO */
32953c4c077Sbostic # ifdef ALTWERASE
33053c4c077Sbostic { "altwerase",ALTWERASE,M_LIN },
33153c4c077Sbostic # endif /* ALTWERASE */
33253c4c077Sbostic # ifdef EXTPROC
33353c4c077Sbostic { "extproc",EXTPROC, M_LIN },
33453c4c077Sbostic # endif /* EXTPROC */
33553c4c077Sbostic
33653c4c077Sbostic # if defined(VINTR)
33753c4c077Sbostic { "intr", C_SH(C_INTR), M_CHAR },
33853c4c077Sbostic # endif /* VINTR */
33953c4c077Sbostic # if defined(VQUIT)
34053c4c077Sbostic { "quit", C_SH(C_QUIT), M_CHAR },
34153c4c077Sbostic # endif /* VQUIT */
34253c4c077Sbostic # if defined(VERASE)
34353c4c077Sbostic { "erase", C_SH(C_ERASE), M_CHAR },
34453c4c077Sbostic # endif /* VERASE */
34553c4c077Sbostic # if defined(VKILL)
34653c4c077Sbostic { "kill", C_SH(C_KILL), M_CHAR },
34753c4c077Sbostic # endif /* VKILL */
34853c4c077Sbostic # if defined(VEOF)
34953c4c077Sbostic { "eof", C_SH(C_EOF), M_CHAR },
35053c4c077Sbostic # endif /* VEOF */
35153c4c077Sbostic # if defined(VEOL)
35253c4c077Sbostic { "eol", C_SH(C_EOL), M_CHAR },
35353c4c077Sbostic # endif /* VEOL */
35453c4c077Sbostic # if defined(VEOL2)
35553c4c077Sbostic { "eol2", C_SH(C_EOL2), M_CHAR },
35653c4c077Sbostic # endif /* VEOL2 */
35753c4c077Sbostic # if defined(VSWTCH)
35853c4c077Sbostic { "swtch", C_SH(C_SWTCH), M_CHAR },
35953c4c077Sbostic # endif /* VSWTCH */
36053c4c077Sbostic # if defined(VDSWTCH)
36153c4c077Sbostic { "dswtch", C_SH(C_DSWTCH), M_CHAR },
36253c4c077Sbostic # endif /* VDSWTCH */
36353c4c077Sbostic # if defined(VERASE2)
36453c4c077Sbostic { "erase2", C_SH(C_ERASE2), M_CHAR },
36553c4c077Sbostic # endif /* VERASE2 */
36653c4c077Sbostic # if defined(VSTART)
36753c4c077Sbostic { "start", C_SH(C_START), M_CHAR },
36853c4c077Sbostic # endif /* VSTART */
36953c4c077Sbostic # if defined(VSTOP)
37053c4c077Sbostic { "stop", C_SH(C_STOP), M_CHAR },
37153c4c077Sbostic # endif /* VSTOP */
37253c4c077Sbostic # if defined(VWERASE)
37353c4c077Sbostic { "werase", C_SH(C_WERASE), M_CHAR },
37453c4c077Sbostic # endif /* VWERASE */
37553c4c077Sbostic # if defined(VSUSP)
37653c4c077Sbostic { "susp", C_SH(C_SUSP), M_CHAR },
37753c4c077Sbostic # endif /* VSUSP */
37853c4c077Sbostic # if defined(VDSUSP)
37953c4c077Sbostic { "dsusp", C_SH(C_DSUSP), M_CHAR },
38053c4c077Sbostic # endif /* VDSUSP */
38153c4c077Sbostic # if defined(VREPRINT)
38253c4c077Sbostic { "reprint", C_SH(C_REPRINT),M_CHAR },
3830d4ffa7bSmarc # endif /* VREPRINT */
38453c4c077Sbostic # if defined(VDISCARD)
38553c4c077Sbostic { "discard", C_SH(C_DISCARD),M_CHAR },
38653c4c077Sbostic # endif /* VDISCARD */
38753c4c077Sbostic # if defined(VLNEXT)
38853c4c077Sbostic { "lnext", C_SH(C_LNEXT), M_CHAR },
38953c4c077Sbostic # endif /* VLNEXT */
39053c4c077Sbostic # if defined(VSTATUS)
39153c4c077Sbostic { "status", C_SH(C_STATUS), M_CHAR },
39253c4c077Sbostic # endif /* VSTATUS */
39353c4c077Sbostic # if defined(VPAGE)
39453c4c077Sbostic { "page", C_SH(C_PAGE), M_CHAR },
39553c4c077Sbostic # endif /* VPAGE */
39653c4c077Sbostic # if defined(VPGOFF)
39753c4c077Sbostic { "pgoff", C_SH(C_PGOFF), M_CHAR },
39853c4c077Sbostic # endif /* VPGOFF */
39953c4c077Sbostic # if defined(VKILL2)
40053c4c077Sbostic { "kill2", C_SH(C_KILL2), M_CHAR },
40153c4c077Sbostic # endif /* VKILL2 */
40253c4c077Sbostic # if defined(VBRK)
40353c4c077Sbostic { "brk", C_SH(C_BRK), M_CHAR },
40453c4c077Sbostic # endif /* VBRK */
40553c4c077Sbostic # if defined(VMIN)
40653c4c077Sbostic { "min", C_SH(C_MIN), M_CHAR },
40753c4c077Sbostic # endif /* VMIN */
40853c4c077Sbostic # if defined(VTIME)
40953c4c077Sbostic { "time", C_SH(C_TIME), M_CHAR },
41053c4c077Sbostic # endif /* VTIME */
41153c4c077Sbostic { NULL, 0, -1 },
41253c4c077Sbostic };
41353c4c077Sbostic
41453c4c077Sbostic
41553c4c077Sbostic
41653c4c077Sbostic #define tty_getty(el, td) tcgetattr((el)->el_infd, (td))
41753c4c077Sbostic #define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td))
41853c4c077Sbostic
41953c4c077Sbostic #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
42053c4c077Sbostic #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
42153c4c077Sbostic #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
42253c4c077Sbostic
42353c4c077Sbostic private void tty__getchar __P((struct termios *, unsigned char *));
42453c4c077Sbostic private void tty__setchar __P((struct termios *, unsigned char *));
42553c4c077Sbostic private speed_t tty__getspeed __P((struct termios *));
42653c4c077Sbostic private int tty_setup __P((EditLine *));
42753c4c077Sbostic
42853c4c077Sbostic #define t_qu t_ts
42953c4c077Sbostic
43053c4c077Sbostic
43153c4c077Sbostic /* tty_setup():
43253c4c077Sbostic * Get the tty parameters and initialize the editing state
43353c4c077Sbostic */
43453c4c077Sbostic private int
tty_setup(el)43553c4c077Sbostic tty_setup(el)
43653c4c077Sbostic EditLine *el;
43753c4c077Sbostic {
43853c4c077Sbostic int rst = 1;
43953c4c077Sbostic if (tty_getty(el, &el->el_tty.t_ed) == -1) {
44053c4c077Sbostic #ifdef DEBUG_TTY
44153c4c077Sbostic (void) fprintf(el->el_errfile,
44253c4c077Sbostic "tty_setup: tty_getty: %s\n", strerror(errno));
44353c4c077Sbostic #endif /* DEBUG_TTY */
44453c4c077Sbostic return(-1);
44553c4c077Sbostic }
44653c4c077Sbostic el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
44753c4c077Sbostic
44853c4c077Sbostic el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
44953c4c077Sbostic el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
45053c4c077Sbostic el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
45153c4c077Sbostic
45253c4c077Sbostic el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask;
45353c4c077Sbostic el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask;
45453c4c077Sbostic
45553c4c077Sbostic el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask;
45653c4c077Sbostic el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask;
45753c4c077Sbostic
45853c4c077Sbostic el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask;
45953c4c077Sbostic el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask;
46053c4c077Sbostic
46153c4c077Sbostic el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask;
46253c4c077Sbostic el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask;
46353c4c077Sbostic
46453c4c077Sbostic /*
46553c4c077Sbostic * Reset the tty chars to reasonable defaults
46653c4c077Sbostic * If they are disabled, then enable them.
46753c4c077Sbostic */
46853c4c077Sbostic if (rst) {
46953c4c077Sbostic if (tty__cooked_mode(&el->el_tty.t_ts)) {
47053c4c077Sbostic tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
47153c4c077Sbostic /*
47253c4c077Sbostic * Don't affect CMIN and CTIME for the editor mode
47353c4c077Sbostic */
47453c4c077Sbostic for (rst = 0; rst < C_NCC - 2; rst++)
47553c4c077Sbostic if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
47653c4c077Sbostic el->el_tty.t_c[ED_IO][rst] != el->el_tty.t_vdisable)
47753c4c077Sbostic el->el_tty.t_c[ED_IO][rst] = el->el_tty.t_c[TS_IO][rst];
47853c4c077Sbostic for (rst = 0; rst < C_NCC; rst++)
47953c4c077Sbostic if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
48053c4c077Sbostic el->el_tty.t_c[EX_IO][rst] != el->el_tty.t_vdisable)
48153c4c077Sbostic el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst];
48253c4c077Sbostic }
48353c4c077Sbostic tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
48453c4c077Sbostic if (tty_setty(el, &el->el_tty.t_ex) == -1) {
48553c4c077Sbostic #ifdef DEBUG_TTY
48653c4c077Sbostic (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n",
48753c4c077Sbostic strerror(errno));
48853c4c077Sbostic #endif /* DEBUG_TTY */
48953c4c077Sbostic return(-1);
49053c4c077Sbostic }
49153c4c077Sbostic }
49253c4c077Sbostic else
49353c4c077Sbostic tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
49453c4c077Sbostic
49553c4c077Sbostic el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
49653c4c077Sbostic el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
49753c4c077Sbostic
49853c4c077Sbostic el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
49953c4c077Sbostic el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
50053c4c077Sbostic
50153c4c077Sbostic el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
50253c4c077Sbostic el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
50353c4c077Sbostic
50453c4c077Sbostic el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
50553c4c077Sbostic el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
50653c4c077Sbostic
50753c4c077Sbostic tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
50853c4c077Sbostic return 0;
50953c4c077Sbostic }
51053c4c077Sbostic
51153c4c077Sbostic protected int
tty_init(el)51253c4c077Sbostic tty_init(el)
51353c4c077Sbostic EditLine *el;
51453c4c077Sbostic {
51553c4c077Sbostic el->el_tty.t_mode = EX_IO;
51653c4c077Sbostic el->el_tty.t_vdisable = _POSIX_VDISABLE;
51753c4c077Sbostic (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
51853c4c077Sbostic (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
51953c4c077Sbostic return tty_setup(el);
52053c4c077Sbostic } /* end tty_init */
52153c4c077Sbostic
52253c4c077Sbostic
52353c4c077Sbostic /* tty_end():
52453c4c077Sbostic * Restore the tty to its original settings
52553c4c077Sbostic */
52653c4c077Sbostic protected void
52753c4c077Sbostic /*ARGSUSED*/
tty_end(el)52853c4c077Sbostic tty_end(el)
52953c4c077Sbostic EditLine *el;
53053c4c077Sbostic {
53153c4c077Sbostic /* XXX: Maybe reset to an initial state? */
53253c4c077Sbostic }
53353c4c077Sbostic
53453c4c077Sbostic
53553c4c077Sbostic /* tty__getspeed():
53653c4c077Sbostic * Get the tty speed
53753c4c077Sbostic */
53853c4c077Sbostic private speed_t
tty__getspeed(td)53953c4c077Sbostic tty__getspeed(td)
54053c4c077Sbostic struct termios *td;
54153c4c077Sbostic {
54253c4c077Sbostic speed_t spd;
54353c4c077Sbostic
54453c4c077Sbostic if ((spd = cfgetispeed(td)) == 0)
54553c4c077Sbostic spd = cfgetospeed(td);
54653c4c077Sbostic return spd;
54753c4c077Sbostic } /* end tty__getspeed */
54853c4c077Sbostic
54953c4c077Sbostic
55053c4c077Sbostic /* tty__getchar():
55153c4c077Sbostic * Get the tty characters
55253c4c077Sbostic */
55353c4c077Sbostic private void
tty__getchar(td,s)55453c4c077Sbostic tty__getchar(td, s)
55553c4c077Sbostic struct termios *td;
55653c4c077Sbostic unsigned char *s;
55753c4c077Sbostic {
55853c4c077Sbostic # ifdef VINTR
55953c4c077Sbostic s[C_INTR] = td->c_cc[VINTR];
56053c4c077Sbostic # endif /* VINTR */
56153c4c077Sbostic # ifdef VQUIT
56253c4c077Sbostic s[C_QUIT] = td->c_cc[VQUIT];
56353c4c077Sbostic # endif /* VQUIT */
56453c4c077Sbostic # ifdef VERASE
56553c4c077Sbostic s[C_ERASE] = td->c_cc[VERASE];
56653c4c077Sbostic # endif /* VERASE */
56753c4c077Sbostic # ifdef VKILL
56853c4c077Sbostic s[C_KILL] = td->c_cc[VKILL];
56953c4c077Sbostic # endif /* VKILL */
57053c4c077Sbostic # ifdef VEOF
57153c4c077Sbostic s[C_EOF] = td->c_cc[VEOF];
57253c4c077Sbostic # endif /* VEOF */
57353c4c077Sbostic # ifdef VEOL
57453c4c077Sbostic s[C_EOL] = td->c_cc[VEOL];
57553c4c077Sbostic # endif /* VEOL */
57653c4c077Sbostic # ifdef VEOL2
57753c4c077Sbostic s[C_EOL2] = td->c_cc[VEOL2];
57853c4c077Sbostic # endif /* VEOL2 */
57953c4c077Sbostic # ifdef VSWTCH
58053c4c077Sbostic s[C_SWTCH] = td->c_cc[VSWTCH];
58153c4c077Sbostic # endif /* VSWTCH */
58253c4c077Sbostic # ifdef VDSWTCH
58353c4c077Sbostic s[C_DSWTCH] = td->c_cc[VDSWTCH];
58453c4c077Sbostic # endif /* VDSWTCH */
58553c4c077Sbostic # ifdef VERASE2
58653c4c077Sbostic s[C_ERASE2] = td->c_cc[VERASE2];
58753c4c077Sbostic # endif /* VERASE2 */
58853c4c077Sbostic # ifdef VSTART
58953c4c077Sbostic s[C_START] = td->c_cc[VSTART];
59053c4c077Sbostic # endif /* VSTART */
59153c4c077Sbostic # ifdef VSTOP
59253c4c077Sbostic s[C_STOP] = td->c_cc[VSTOP];
59353c4c077Sbostic # endif /* VSTOP */
59453c4c077Sbostic # ifdef VWERASE
59553c4c077Sbostic s[C_WERASE] = td->c_cc[VWERASE];
59653c4c077Sbostic # endif /* VWERASE */
59753c4c077Sbostic # ifdef VSUSP
59853c4c077Sbostic s[C_SUSP] = td->c_cc[VSUSP];
59953c4c077Sbostic # endif /* VSUSP */
60053c4c077Sbostic # ifdef VDSUSP
60153c4c077Sbostic s[C_DSUSP] = td->c_cc[VDSUSP];
60253c4c077Sbostic # endif /* VDSUSP */
60353c4c077Sbostic # ifdef VREPRINT
60453c4c077Sbostic s[C_REPRINT]= td->c_cc[VREPRINT];
6050d4ffa7bSmarc # endif /* VREPRINT */
60653c4c077Sbostic # ifdef VDISCARD
60753c4c077Sbostic s[C_DISCARD]= td->c_cc[VDISCARD];
60853c4c077Sbostic # endif /* VDISCARD */
60953c4c077Sbostic # ifdef VLNEXT
61053c4c077Sbostic s[C_LNEXT] = td->c_cc[VLNEXT];
61153c4c077Sbostic # endif /* VLNEXT */
61253c4c077Sbostic # ifdef VSTATUS
61353c4c077Sbostic s[C_STATUS] = td->c_cc[VSTATUS];
61453c4c077Sbostic # endif /* VSTATUS */
61553c4c077Sbostic # ifdef VPAGE
61653c4c077Sbostic s[C_PAGE] = td->c_cc[VPAGE];
61753c4c077Sbostic # endif /* VPAGE */
61853c4c077Sbostic # ifdef VPGOFF
61953c4c077Sbostic s[C_PGOFF] = td->c_cc[VPGOFF];
62053c4c077Sbostic # endif /* VPGOFF */
62153c4c077Sbostic # ifdef VKILL2
62253c4c077Sbostic s[C_KILL2] = td->c_cc[VKILL2];
62353c4c077Sbostic # endif /* KILL2 */
62453c4c077Sbostic # ifdef VMIN
62553c4c077Sbostic s[C_MIN] = td->c_cc[VMIN];
62653c4c077Sbostic # endif /* VMIN */
62753c4c077Sbostic # ifdef VTIME
62853c4c077Sbostic s[C_TIME] = td->c_cc[VTIME];
62953c4c077Sbostic # endif /* VTIME */
63053c4c077Sbostic } /* tty__getchar */
63153c4c077Sbostic
63253c4c077Sbostic
63353c4c077Sbostic /* tty__setchar():
63453c4c077Sbostic * Set the tty characters
63553c4c077Sbostic */
63653c4c077Sbostic private void
tty__setchar(td,s)63753c4c077Sbostic tty__setchar(td, s)
63853c4c077Sbostic struct termios *td;
63953c4c077Sbostic unsigned char *s;
64053c4c077Sbostic {
64153c4c077Sbostic # ifdef VINTR
64253c4c077Sbostic td->c_cc[VINTR] = s[C_INTR];
64353c4c077Sbostic # endif /* VINTR */
64453c4c077Sbostic # ifdef VQUIT
64553c4c077Sbostic td->c_cc[VQUIT] = s[C_QUIT];
64653c4c077Sbostic # endif /* VQUIT */
64753c4c077Sbostic # ifdef VERASE
64853c4c077Sbostic td->c_cc[VERASE] = s[C_ERASE];
64953c4c077Sbostic # endif /* VERASE */
65053c4c077Sbostic # ifdef VKILL
65153c4c077Sbostic td->c_cc[VKILL] = s[C_KILL];
65253c4c077Sbostic # endif /* VKILL */
65353c4c077Sbostic # ifdef VEOF
65453c4c077Sbostic td->c_cc[VEOF] = s[C_EOF];
65553c4c077Sbostic # endif /* VEOF */
65653c4c077Sbostic # ifdef VEOL
65753c4c077Sbostic td->c_cc[VEOL] = s[C_EOL];
65853c4c077Sbostic # endif /* VEOL */
65953c4c077Sbostic # ifdef VEOL2
66053c4c077Sbostic td->c_cc[VEOL2] = s[C_EOL2];
66153c4c077Sbostic # endif /* VEOL2 */
66253c4c077Sbostic # ifdef VSWTCH
66353c4c077Sbostic td->c_cc[VSWTCH] = s[C_SWTCH];
66453c4c077Sbostic # endif /* VSWTCH */
66553c4c077Sbostic # ifdef VDSWTCH
66653c4c077Sbostic td->c_cc[VDSWTCH] = s[C_DSWTCH];
66753c4c077Sbostic # endif /* VDSWTCH */
66853c4c077Sbostic # ifdef VERASE2
66953c4c077Sbostic td->c_cc[VERASE2] = s[C_ERASE2];
67053c4c077Sbostic # endif /* VERASE2 */
67153c4c077Sbostic # ifdef VSTART
67253c4c077Sbostic td->c_cc[VSTART] = s[C_START];
67353c4c077Sbostic # endif /* VSTART */
67453c4c077Sbostic # ifdef VSTOP
67553c4c077Sbostic td->c_cc[VSTOP] = s[C_STOP];
67653c4c077Sbostic # endif /* VSTOP */
67753c4c077Sbostic # ifdef VWERASE
67853c4c077Sbostic td->c_cc[VWERASE] = s[C_WERASE];
67953c4c077Sbostic # endif /* VWERASE */
68053c4c077Sbostic # ifdef VSUSP
68153c4c077Sbostic td->c_cc[VSUSP] = s[C_SUSP];
68253c4c077Sbostic # endif /* VSUSP */
68353c4c077Sbostic # ifdef VDSUSP
68453c4c077Sbostic td->c_cc[VDSUSP] = s[C_DSUSP];
68553c4c077Sbostic # endif /* VDSUSP */
68653c4c077Sbostic # ifdef VREPRINT
68753c4c077Sbostic td->c_cc[VREPRINT] = s[C_REPRINT];
6880d4ffa7bSmarc # endif /* VREPRINT */
68953c4c077Sbostic # ifdef VDISCARD
69053c4c077Sbostic td->c_cc[VDISCARD] = s[C_DISCARD];
69153c4c077Sbostic # endif /* VDISCARD */
69253c4c077Sbostic # ifdef VLNEXT
69353c4c077Sbostic td->c_cc[VLNEXT] = s[C_LNEXT];
69453c4c077Sbostic # endif /* VLNEXT */
69553c4c077Sbostic # ifdef VSTATUS
69653c4c077Sbostic td->c_cc[VSTATUS] = s[C_STATUS];
69753c4c077Sbostic # endif /* VSTATUS */
69853c4c077Sbostic # ifdef VPAGE
69953c4c077Sbostic td->c_cc[VPAGE] = s[C_PAGE];
70053c4c077Sbostic # endif /* VPAGE */
70153c4c077Sbostic # ifdef VPGOFF
70253c4c077Sbostic td->c_cc[VPGOFF] = s[C_PGOFF];
70353c4c077Sbostic # endif /* VPGOFF */
70453c4c077Sbostic # ifdef VKILL2
70553c4c077Sbostic td->c_cc[VKILL2] = s[C_KILL2];
70653c4c077Sbostic # endif /* VKILL2 */
70753c4c077Sbostic # ifdef VMIN
70853c4c077Sbostic td->c_cc[VMIN] = s[C_MIN];
70953c4c077Sbostic # endif /* VMIN */
71053c4c077Sbostic # ifdef VTIME
71153c4c077Sbostic td->c_cc[VTIME] = s[C_TIME];
71253c4c077Sbostic # endif /* VTIME */
71353c4c077Sbostic } /* tty__setchar */
71453c4c077Sbostic
71553c4c077Sbostic
7160d4ffa7bSmarc /* tty_bind_char():
7170d4ffa7bSmarc * Rebind the editline functions
7180d4ffa7bSmarc */
7194835d4c2Schristos protected void
tty_bind_char(el,force)7204835d4c2Schristos tty_bind_char(el, force)
7210d4ffa7bSmarc EditLine *el;
7224835d4c2Schristos int force;
7230d4ffa7bSmarc {
7240d4ffa7bSmarc unsigned char *t_n = el->el_tty.t_c[ED_IO];
7250d4ffa7bSmarc unsigned char *t_o = el->el_tty.t_ed.c_cc;
7264835d4c2Schristos char new[2], old[2];
7270d4ffa7bSmarc ttymap_t *tp;
7280d4ffa7bSmarc el_action_t *dmap, *dalt, *map, *alt;
7290d4ffa7bSmarc new[1] = old[1] = '\0';
7300d4ffa7bSmarc
7310d4ffa7bSmarc
7320d4ffa7bSmarc map = el->el_map.key;
7330d4ffa7bSmarc alt = el->el_map.alt;
7340d4ffa7bSmarc if (el->el_map.type == MAP_VI) {
7350d4ffa7bSmarc dmap = el->el_map.vii;
7360d4ffa7bSmarc dalt = el->el_map.vic;
7370d4ffa7bSmarc }
7380d4ffa7bSmarc else {
7390d4ffa7bSmarc dmap = el->el_map.emacs;
7400d4ffa7bSmarc dalt = NULL;
7410d4ffa7bSmarc }
7420d4ffa7bSmarc
7430d4ffa7bSmarc for (tp = tty_map; tp->nch != -1; tp++) {
7440d4ffa7bSmarc new[0] = t_n[tp->nch];
7450d4ffa7bSmarc old[0] = t_o[tp->och];
7464835d4c2Schristos if (new[0] == old[0] && !force)
7470d4ffa7bSmarc continue;
7480d4ffa7bSmarc /* Put the old default binding back, and set the new binding */
7494835d4c2Schristos key_clear(el, map, old);
7500d4ffa7bSmarc map[old[0]] = dmap[old[0]];
7514835d4c2Schristos key_clear(el, map, new);
7520d4ffa7bSmarc /* MAP_VI == 1, MAP_EMACS == 0... */
7530d4ffa7bSmarc map[new[0]] = tp->bind[el->el_map.type];
7540d4ffa7bSmarc if (dalt) {
7554835d4c2Schristos key_clear(el, alt, old);
7560d4ffa7bSmarc alt[old[0]] = dalt[old[0]];
7574835d4c2Schristos key_clear(el, alt, new);
7580d4ffa7bSmarc alt[new[0]] = tp->bind[el->el_map.type+1];
7590d4ffa7bSmarc }
7600d4ffa7bSmarc }
7610d4ffa7bSmarc }
7620d4ffa7bSmarc
76353c4c077Sbostic /* tty_rawmode():
76453c4c077Sbostic * Set terminal into 1 character at a time mode.
76553c4c077Sbostic */
76653c4c077Sbostic protected int
tty_rawmode(el)76753c4c077Sbostic tty_rawmode(el)
76853c4c077Sbostic EditLine *el;
76953c4c077Sbostic {
77053c4c077Sbostic if (el->el_tty.t_mode == ED_IO)
77153c4c077Sbostic return (0);
77253c4c077Sbostic
77353c4c077Sbostic if (tty_getty(el, &el->el_tty.t_ts) == -1) {
77453c4c077Sbostic #ifdef DEBUG_TTY
77553c4c077Sbostic (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", strerror(errno));
77653c4c077Sbostic #endif /* DEBUG_TTY */
77753c4c077Sbostic return(-1);
77853c4c077Sbostic }
77953c4c077Sbostic
78053c4c077Sbostic /*
78153c4c077Sbostic * We always keep up with the eight bit setting and the speed of the
78253c4c077Sbostic * tty. But only we only believe changes that are made to cooked mode!
78353c4c077Sbostic */
78453c4c077Sbostic el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
78553c4c077Sbostic el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
78653c4c077Sbostic
78753c4c077Sbostic if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
78853c4c077Sbostic tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
78953c4c077Sbostic (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
79053c4c077Sbostic (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
79153c4c077Sbostic (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
79253c4c077Sbostic (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
79353c4c077Sbostic }
79453c4c077Sbostic
79553c4c077Sbostic if (tty__cooked_mode(&el->el_tty.t_ts)) {
79653c4c077Sbostic if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
79753c4c077Sbostic el->el_tty.t_ex.c_cflag = el->el_tty.t_ts.c_cflag;
79853c4c077Sbostic el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask;
79953c4c077Sbostic el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask;
80053c4c077Sbostic
80153c4c077Sbostic el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag;
80253c4c077Sbostic el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
80353c4c077Sbostic el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
80453c4c077Sbostic }
80553c4c077Sbostic
80653c4c077Sbostic if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
80753c4c077Sbostic (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
80853c4c077Sbostic el->el_tty.t_ex.c_lflag = el->el_tty.t_ts.c_lflag;
80953c4c077Sbostic el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask;
81053c4c077Sbostic el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask;
81153c4c077Sbostic
81253c4c077Sbostic el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag;
81353c4c077Sbostic el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
81453c4c077Sbostic el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
81553c4c077Sbostic }
81653c4c077Sbostic
81753c4c077Sbostic if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
81853c4c077Sbostic (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
81953c4c077Sbostic el->el_tty.t_ex.c_iflag = el->el_tty.t_ts.c_iflag;
82053c4c077Sbostic el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask;
82153c4c077Sbostic el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask;
82253c4c077Sbostic
82353c4c077Sbostic el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag;
82453c4c077Sbostic el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
82553c4c077Sbostic el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
82653c4c077Sbostic }
82753c4c077Sbostic
82853c4c077Sbostic if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
82953c4c077Sbostic (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
83053c4c077Sbostic el->el_tty.t_ex.c_oflag = el->el_tty.t_ts.c_oflag;
83153c4c077Sbostic el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask;
83253c4c077Sbostic el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask;
83353c4c077Sbostic
83453c4c077Sbostic el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag;
83553c4c077Sbostic el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
83653c4c077Sbostic el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
83753c4c077Sbostic }
83853c4c077Sbostic
83953c4c077Sbostic if (tty__gettabs(&el->el_tty.t_ex) == 0)
84053c4c077Sbostic el->el_tty.t_tabs = 0;
84153c4c077Sbostic else
84253c4c077Sbostic el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
84353c4c077Sbostic
84453c4c077Sbostic {
84553c4c077Sbostic int i;
84653c4c077Sbostic
84753c4c077Sbostic tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
84853c4c077Sbostic /*
84953c4c077Sbostic * Check if the user made any changes.
85053c4c077Sbostic * If he did, then propagate the changes to the
85153c4c077Sbostic * edit and execute data structures.
85253c4c077Sbostic */
85353c4c077Sbostic for (i = 0; i < C_NCC; i++)
85453c4c077Sbostic if (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])
85553c4c077Sbostic break;
85653c4c077Sbostic
85753c4c077Sbostic if (i != C_NCC) {
85853c4c077Sbostic /*
85953c4c077Sbostic * Propagate changes only to the unprotected chars
86053c4c077Sbostic * that have been modified just now.
86153c4c077Sbostic */
86253c4c077Sbostic for (i = 0; i < C_NCC; i++) {
86353c4c077Sbostic if (!((el->el_tty.t_t[ED_IO][M_CHAR].t_setmask & C_SH(i)))
86453c4c077Sbostic && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
86553c4c077Sbostic el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
86653c4c077Sbostic if (el->el_tty.t_t[ED_IO][M_CHAR].t_clrmask & C_SH(i))
86753c4c077Sbostic el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
86853c4c077Sbostic }
8694835d4c2Schristos tty_bind_char(el, 0);
87053c4c077Sbostic tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
87153c4c077Sbostic
87253c4c077Sbostic for (i = 0; i < C_NCC; i++) {
87353c4c077Sbostic if (!((el->el_tty.t_t[EX_IO][M_CHAR].t_setmask & C_SH(i)))
87453c4c077Sbostic && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
87553c4c077Sbostic el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
87653c4c077Sbostic if (el->el_tty.t_t[EX_IO][M_CHAR].t_clrmask & C_SH(i))
87753c4c077Sbostic el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
87853c4c077Sbostic }
87953c4c077Sbostic tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
88053c4c077Sbostic }
88153c4c077Sbostic
88253c4c077Sbostic }
88353c4c077Sbostic }
88453c4c077Sbostic
88553c4c077Sbostic if (tty_setty(el, &el->el_tty.t_ed) == -1) {
88653c4c077Sbostic #ifdef DEBUG_TTY
88753c4c077Sbostic (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
88853c4c077Sbostic strerror(errno));
88953c4c077Sbostic #endif /* DEBUG_TTY */
89053c4c077Sbostic return -1;
89153c4c077Sbostic }
89253c4c077Sbostic el->el_tty.t_mode = ED_IO;
89353c4c077Sbostic return (0);
89453c4c077Sbostic } /* end tty_rawmode */
89553c4c077Sbostic
89653c4c077Sbostic
89753c4c077Sbostic /* tty_cookedmode():
89853c4c077Sbostic * Set the tty back to normal mode
89953c4c077Sbostic */
90053c4c077Sbostic protected int
tty_cookedmode(el)90153c4c077Sbostic tty_cookedmode(el)
90253c4c077Sbostic EditLine *el;
90353c4c077Sbostic { /* set tty in normal setup */
90453c4c077Sbostic if (el->el_tty.t_mode == EX_IO)
90553c4c077Sbostic return (0);
90653c4c077Sbostic
90753c4c077Sbostic if (tty_setty(el, &el->el_tty.t_ex) == -1) {
90853c4c077Sbostic #ifdef DEBUG_TTY
90953c4c077Sbostic (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n",
91053c4c077Sbostic strerror(errno));
91153c4c077Sbostic #endif /* DEBUG_TTY */
91253c4c077Sbostic return -1;
91353c4c077Sbostic }
91453c4c077Sbostic el->el_tty.t_mode = EX_IO;
91553c4c077Sbostic return (0);
91653c4c077Sbostic } /* end tty_cookedmode */
91753c4c077Sbostic
91853c4c077Sbostic
91953c4c077Sbostic /* tty_quotemode():
92053c4c077Sbostic * Turn on quote mode
92153c4c077Sbostic */
92253c4c077Sbostic protected int
tty_quotemode(el)92353c4c077Sbostic tty_quotemode(el)
92453c4c077Sbostic EditLine *el;
92553c4c077Sbostic {
92653c4c077Sbostic if (el->el_tty.t_mode == QU_IO)
92753c4c077Sbostic return 0;
92853c4c077Sbostic
92953c4c077Sbostic el->el_tty.t_qu = el->el_tty.t_ed;
93053c4c077Sbostic
93153c4c077Sbostic el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][M_INP].t_clrmask;
93253c4c077Sbostic el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][M_INP].t_setmask;
93353c4c077Sbostic
93453c4c077Sbostic el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][M_OUT].t_clrmask;
93553c4c077Sbostic el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][M_OUT].t_setmask;
93653c4c077Sbostic
93753c4c077Sbostic el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][M_CTL].t_clrmask;
93853c4c077Sbostic el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][M_CTL].t_setmask;
93953c4c077Sbostic
94053c4c077Sbostic el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][M_LIN].t_clrmask;
94153c4c077Sbostic el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][M_LIN].t_setmask;
94253c4c077Sbostic
94353c4c077Sbostic if (tty_setty(el, &el->el_tty.t_qu) == -1) {
94453c4c077Sbostic #ifdef DEBUG_TTY
94553c4c077Sbostic (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
94653c4c077Sbostic strerror(errno));
94753c4c077Sbostic #endif /* DEBUG_TTY */
94853c4c077Sbostic return -1;
94953c4c077Sbostic }
95053c4c077Sbostic el->el_tty.t_mode = QU_IO;
95153c4c077Sbostic return 0;
95253c4c077Sbostic } /* end tty_quotemode */
95353c4c077Sbostic
95453c4c077Sbostic
95553c4c077Sbostic /* tty_noquotemode():
95653c4c077Sbostic * Turn off quote mode
95753c4c077Sbostic */
95853c4c077Sbostic protected int
tty_noquotemode(el)95953c4c077Sbostic tty_noquotemode(el)
96053c4c077Sbostic EditLine *el;
96153c4c077Sbostic {
96253c4c077Sbostic if (el->el_tty.t_mode != QU_IO)
96353c4c077Sbostic return 0;
96453c4c077Sbostic if (tty_setty(el, &el->el_tty.t_ed) == -1) {
96553c4c077Sbostic #ifdef DEBUG_TTY
96653c4c077Sbostic (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
96753c4c077Sbostic strerror(errno));
96853c4c077Sbostic #endif /* DEBUG_TTY */
96953c4c077Sbostic return -1;
97053c4c077Sbostic }
97153c4c077Sbostic el->el_tty.t_mode = ED_IO;
97253c4c077Sbostic return 0;
97353c4c077Sbostic }
97453c4c077Sbostic
97553c4c077Sbostic /* tty_stty():
97653c4c077Sbostic * Stty builtin
97753c4c077Sbostic */
97853c4c077Sbostic protected int
97953c4c077Sbostic /*ARGSUSED*/
tty_stty(el,argc,argv)98053c4c077Sbostic tty_stty(el, argc, argv)
98153c4c077Sbostic EditLine *el;
98253c4c077Sbostic int argc;
98353c4c077Sbostic char **argv;
98453c4c077Sbostic {
98553c4c077Sbostic ttymodes_t *m;
98653c4c077Sbostic char x, *d;
98753c4c077Sbostic int aflag = 0;
98853c4c077Sbostic char *s;
98953c4c077Sbostic char *name;
99053c4c077Sbostic int z = EX_IO;
99153c4c077Sbostic
99253c4c077Sbostic if (argv == NULL)
99353c4c077Sbostic return -1;
99453c4c077Sbostic name = *argv++;
99553c4c077Sbostic
99653c4c077Sbostic while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
99753c4c077Sbostic switch (argv[0][1]) {
99853c4c077Sbostic case 'a':
99953c4c077Sbostic aflag++;
100053c4c077Sbostic argv++;
100153c4c077Sbostic break;
100253c4c077Sbostic case 'd':
100353c4c077Sbostic argv++;
100453c4c077Sbostic z = ED_IO;
100553c4c077Sbostic break;
100653c4c077Sbostic case 'x':
100753c4c077Sbostic argv++;
100853c4c077Sbostic z = EX_IO;
100953c4c077Sbostic break;
101053c4c077Sbostic case 'q':
101153c4c077Sbostic argv++;
101253c4c077Sbostic z = QU_IO;
101353c4c077Sbostic break;
101453c4c077Sbostic default:
101553c4c077Sbostic (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n",
101653c4c077Sbostic name, argv[0][1]);
101753c4c077Sbostic return -1;
101853c4c077Sbostic }
101953c4c077Sbostic
102053c4c077Sbostic if (!argv || !*argv) {
102153c4c077Sbostic int i = -1;
102253c4c077Sbostic int len = 0, st = 0, cu;
102353c4c077Sbostic for (m = ttymodes; m->m_name; m++) {
102453c4c077Sbostic if (m->m_type != i) {
102553c4c077Sbostic (void) fprintf(el->el_outfile, "%s%s", i != -1 ? "\n" : "",
102653c4c077Sbostic el->el_tty.t_t[z][m->m_type].t_name);
102753c4c077Sbostic i = m->m_type;
102853c4c077Sbostic st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name);
102953c4c077Sbostic }
103053c4c077Sbostic
103153c4c077Sbostic x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0';
103253c4c077Sbostic x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '-' : x;
103353c4c077Sbostic
103453c4c077Sbostic if (x != '\0' || aflag) {
103553c4c077Sbostic
103653c4c077Sbostic cu = strlen(m->m_name) + (x != '\0') + 1;
103753c4c077Sbostic
103853c4c077Sbostic if (len + cu >= el->el_term.t_size.h) {
103953c4c077Sbostic (void) fprintf(el->el_outfile, "\n%*s", st, "");
104053c4c077Sbostic len = st + cu;
104153c4c077Sbostic }
104253c4c077Sbostic else
104353c4c077Sbostic len += cu;
104453c4c077Sbostic
104553c4c077Sbostic if (x != '\0')
104653c4c077Sbostic (void) fprintf(el->el_outfile, "%c%s ", x, m->m_name);
104753c4c077Sbostic else
104853c4c077Sbostic (void) fprintf(el->el_outfile, "%s ", m->m_name);
104953c4c077Sbostic }
105053c4c077Sbostic }
105153c4c077Sbostic (void) fprintf(el->el_outfile, "\n");
105253c4c077Sbostic return 0;
105353c4c077Sbostic }
105453c4c077Sbostic
105553c4c077Sbostic while (argv && (s = *argv++)) {
105653c4c077Sbostic switch (*s) {
105753c4c077Sbostic case '+':
105853c4c077Sbostic case '-':
105953c4c077Sbostic x = *s++;
106053c4c077Sbostic break;
106153c4c077Sbostic default:
106253c4c077Sbostic x = '\0';
106353c4c077Sbostic break;
106453c4c077Sbostic }
106553c4c077Sbostic d = s;
106653c4c077Sbostic for (m = ttymodes; m->m_name; m++)
106753c4c077Sbostic if (strcmp(m->m_name, d) == 0)
106853c4c077Sbostic break;
106953c4c077Sbostic
107053c4c077Sbostic if (!m->m_name) {
107153c4c077Sbostic (void) fprintf(el->el_errfile, "%s: Invalid argument `%s'.\n",
107253c4c077Sbostic name, d);
107353c4c077Sbostic return -1;
107453c4c077Sbostic }
107553c4c077Sbostic
107653c4c077Sbostic switch (x) {
107753c4c077Sbostic case '+':
107853c4c077Sbostic el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
107953c4c077Sbostic el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
108053c4c077Sbostic break;
108153c4c077Sbostic case '-':
108253c4c077Sbostic el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
108353c4c077Sbostic el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
108453c4c077Sbostic break;
108553c4c077Sbostic default:
108653c4c077Sbostic el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
108753c4c077Sbostic el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
108853c4c077Sbostic break;
108953c4c077Sbostic }
109053c4c077Sbostic }
109153c4c077Sbostic return 0;
109253c4c077Sbostic } /* end tty_stty */
109353c4c077Sbostic
109453c4c077Sbostic
109553c4c077Sbostic #ifdef notyet
109653c4c077Sbostic /* tty_printchar():
109753c4c077Sbostic * DEbugging routine to print the tty characters
109853c4c077Sbostic */
109953c4c077Sbostic private void
tty_printchar(el,s)110053c4c077Sbostic tty_printchar(el, s)
110153c4c077Sbostic EditLine *el;
110253c4c077Sbostic unsigned char *s;
110353c4c077Sbostic {
110453c4c077Sbostic ttyperm_t *m;
110553c4c077Sbostic int i;
110653c4c077Sbostic
110753c4c077Sbostic for (i = 0; i < C_NCC; i++) {
110853c4c077Sbostic for (m = el->el_tty.t_t; m->m_name; m++)
110953c4c077Sbostic if (m->m_type == M_CHAR && C_SH(i) == m->m_value)
111053c4c077Sbostic break;
111153c4c077Sbostic if (m->m_name)
111253c4c077Sbostic (void) fprintf(el->el_errfile, "%s ^%c ", m->m_name, s[i] + 'A'-1);
111353c4c077Sbostic if (i % 5 == 0)
111453c4c077Sbostic (void) fprintf(el->el_errfile, "\n");
111553c4c077Sbostic }
111653c4c077Sbostic (void) fprintf(el->el_errfile, "\n");
111753c4c077Sbostic }
111853c4c077Sbostic #endif /* notyet */
1119