154242Sbostic /*-
2*61276Sbostic * Copyright (c) 1992, 1993
3*61276Sbostic * The Regents of the University of California. All rights reserved.
454242Sbostic *
554242Sbostic * This code is derived from software contributed to Berkeley by
654242Sbostic * Christos Zoulas of Cornell University.
754242Sbostic *
854242Sbostic * %sccs.include.redist.c%
954242Sbostic */
1054242Sbostic
1154624Schristos #if !defined(lint) && !defined(SCCSID)
12*61276Sbostic static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 06/04/93";
1354624Schristos #endif /* not lint && not SCCSID */
1454242Sbostic
1554242Sbostic /*
1654624Schristos * tty.c: tty interface stuff
1754242Sbostic */
1854242Sbostic #include "sys.h"
1954242Sbostic #include "tty.h"
2054242Sbostic #include "el.h"
2154242Sbostic
2255299Smarc typedef struct ttymodes_t {
2355299Smarc char *m_name;
2455299Smarc int m_value;
2555299Smarc int m_type;
2655299Smarc } ttymodes_t;
2755299Smarc
2855299Smarc typedef struct ttymap_t {
2955299Smarc int nch, och; /* Internal and termio rep of chars */
3055299Smarc el_action_t bind[3]; /* emacs, vi, and vi-cmd */
3155299Smarc } ttymap_t;
3255299Smarc
3355299Smarc
3454242Sbostic private ttyperm_t ttyperm = {
3554242Sbostic {
3654242Sbostic { "iflag:", ICRNL, (INLCR|IGNCR) },
3754242Sbostic { "oflag:", (OPOST|ONLCR), ONLRET },
3854242Sbostic { "cflag:", 0, 0 },
3954242Sbostic { "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN),
4054242Sbostic (NOFLSH|ECHONL|EXTPROC|FLUSHO) },
4154242Sbostic { "chars:", 0, 0 },
4254242Sbostic },
4354242Sbostic {
4454242Sbostic { "iflag:", (INLCR|ICRNL), IGNCR },
4554242Sbostic { "oflag:", (OPOST|ONLCR), ONLRET },
4654242Sbostic { "cflag:", 0, 0 },
4754242Sbostic { "lflag:", ISIG,
4854242Sbostic (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO) },
4954242Sbostic { "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)|
5055299Smarc C_SH(C_SUSP)|C_SH(C_DSUSP)|C_SH(C_EOL)|C_SH(C_DISCARD)|
5155299Smarc C_SH(C_PGOFF)|C_SH(C_PAGE)|C_SH(C_STATUS)), 0 }
5254242Sbostic },
5354242Sbostic {
5454242Sbostic { "iflag:", 0, IXON | IXOFF },
5554242Sbostic { "oflag:", 0, 0 },
5654242Sbostic { "cflag:", 0, 0 },
5754242Sbostic { "lflag:", 0, ISIG | IEXTEN },
5854242Sbostic { "chars:", 0, 0 },
5954242Sbostic }
6054242Sbostic };
6154242Sbostic
6254242Sbostic private ttychar_t ttychar = {
6354242Sbostic {
6454242Sbostic CINTR, CQUIT, CERASE, CKILL,
6554242Sbostic CEOF, CEOL, CEOL2, CSWTCH,
6654242Sbostic CDSWTCH, CERASE2, CSTART, CSTOP,
6754242Sbostic CWERASE, CSUSP, CDSUSP, CREPRINT,
6854242Sbostic CDISCARD, CLNEXT, CSTATUS, CPAGE,
6954242Sbostic CPGOFF, CKILL2, CBRK, CMIN,
7054242Sbostic CTIME
7154242Sbostic },
7254242Sbostic {
7354242Sbostic CINTR, CQUIT, CERASE, CKILL,
7454242Sbostic _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
7554242Sbostic _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
7654242Sbostic _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
7754242Sbostic CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
7854242Sbostic _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
7954242Sbostic 0
8054242Sbostic },
8154242Sbostic {
8254242Sbostic 0, 0, 0, 0,
8354242Sbostic 0, 0, 0, 0,
8454242Sbostic 0, 0, 0, 0,
8554242Sbostic 0, 0, 0, 0,
8654242Sbostic 0, 0, 0, 0,
8754242Sbostic 0, 0, 0, 0,
8854242Sbostic 0
8954242Sbostic }
9054242Sbostic };
9154242Sbostic
9255299Smarc private ttymap_t tty_map[] = {
9355299Smarc #ifdef VERASE
9455299Smarc { C_ERASE, VERASE,
9555299Smarc { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
9655299Smarc #endif /* VERASE */
9755299Smarc #ifdef VERASE2
9855299Smarc { C_ERASE2, VERASE2,
9955299Smarc { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
10055299Smarc #endif /* VERASE2 */
10155299Smarc #ifdef VKILL
10255299Smarc { C_KILL, VKILL,
10355299Smarc { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
10455299Smarc #endif /* VKILL */
10555299Smarc #ifdef VKILL2
10655299Smarc { C_KILL2, VKILL2,
10755299Smarc { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
10855299Smarc #endif /* VKILL2 */
10955299Smarc #ifdef VEOF
11055299Smarc { C_EOF, VEOF,
11155299Smarc { EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED } },
11255299Smarc #endif /* VEOF */
11355299Smarc #ifdef VWERASE
11455299Smarc { C_WERASE, VWERASE,
11555299Smarc { ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD } },
11655299Smarc #endif /* VWERASE */
11755299Smarc #ifdef VREPRINT
11855299Smarc { C_REPRINT, VREPRINT,
11955299Smarc { ED_REDISPLAY, ED_INSERT, ED_REDISPLAY } },
12055299Smarc #endif /* VREPRINT */
12155299Smarc #ifdef VLNEXT
12255299Smarc { C_LNEXT, VLNEXT,
12355299Smarc { ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED } },
12455299Smarc #endif /* VLNEXT */
12555299Smarc { -1, -1,
12655299Smarc { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } }
12755299Smarc };
12854242Sbostic
12954242Sbostic private ttymodes_t ttymodes[] = {
13054242Sbostic # ifdef IGNBRK
13154242Sbostic { "ignbrk", IGNBRK, M_INP },
13254242Sbostic # endif /* IGNBRK */
13354242Sbostic # ifdef BRKINT
13454242Sbostic { "brkint", BRKINT, M_INP },
13554242Sbostic # endif /* BRKINT */
13654242Sbostic # ifdef IGNPAR
13754242Sbostic { "ignpar", IGNPAR, M_INP },
13854242Sbostic # endif /* IGNPAR */
13954242Sbostic # ifdef PARMRK
14054242Sbostic { "parmrk", PARMRK, M_INP },
14154242Sbostic # endif /* PARMRK */
14254242Sbostic # ifdef INPCK
14354242Sbostic { "inpck", INPCK, M_INP },
14454242Sbostic # endif /* INPCK */
14554242Sbostic # ifdef ISTRIP
14654242Sbostic { "istrip", ISTRIP, M_INP },
14754242Sbostic # endif /* ISTRIP */
14854242Sbostic # ifdef INLCR
14954242Sbostic { "inlcr", INLCR, M_INP },
15054242Sbostic # endif /* INLCR */
15154242Sbostic # ifdef IGNCR
15254242Sbostic { "igncr", IGNCR, M_INP },
15354242Sbostic # endif /* IGNCR */
15454242Sbostic # ifdef ICRNL
15554242Sbostic { "icrnl", ICRNL, M_INP },
15654242Sbostic # endif /* ICRNL */
15754242Sbostic # ifdef IUCLC
15854242Sbostic { "iuclc", IUCLC, M_INP },
15954242Sbostic # endif /* IUCLC */
16054242Sbostic # ifdef IXON
16154242Sbostic { "ixon", IXON, M_INP },
16254242Sbostic # endif /* IXON */
16354242Sbostic # ifdef IXANY
16454242Sbostic { "ixany", IXANY, M_INP },
16554242Sbostic # endif /* IXANY */
16654242Sbostic # ifdef IXOFF
16754242Sbostic { "ixoff", IXOFF, M_INP },
16854242Sbostic # endif /* IXOFF */
16954242Sbostic # ifdef IMAXBEL
17054242Sbostic { "imaxbel",IMAXBEL,M_INP },
17154242Sbostic # endif /* IMAXBEL */
17254242Sbostic
17354242Sbostic # ifdef OPOST
17454242Sbostic { "opost", OPOST, M_OUT },
17554242Sbostic # endif /* OPOST */
17654242Sbostic # ifdef OLCUC
17754242Sbostic { "olcuc", OLCUC, M_OUT },
17854242Sbostic # endif /* OLCUC */
17954242Sbostic # ifdef ONLCR
18054242Sbostic { "onlcr", ONLCR, M_OUT },
18154242Sbostic # endif /* ONLCR */
18254242Sbostic # ifdef OCRNL
18354242Sbostic { "ocrnl", OCRNL, M_OUT },
18454242Sbostic # endif /* OCRNL */
18554242Sbostic # ifdef ONOCR
18654242Sbostic { "onocr", ONOCR, M_OUT },
18754242Sbostic # endif /* ONOCR */
18854242Sbostic # ifdef ONOEOT
18954242Sbostic { "onoeot", ONOEOT, M_OUT },
19054242Sbostic # endif /* ONOEOT */
19154242Sbostic # ifdef ONLRET
19254242Sbostic { "onlret", ONLRET, M_OUT },
19354242Sbostic # endif /* ONLRET */
19454242Sbostic # ifdef OFILL
19554242Sbostic { "ofill", OFILL, M_OUT },
19654242Sbostic # endif /* OFILL */
19754242Sbostic # ifdef OFDEL
19854242Sbostic { "ofdel", OFDEL, M_OUT },
19954242Sbostic # endif /* OFDEL */
20054242Sbostic # ifdef NLDLY
20154242Sbostic { "nldly", NLDLY, M_OUT },
20254242Sbostic # endif /* NLDLY */
20354242Sbostic # ifdef CRDLY
20454242Sbostic { "crdly", CRDLY, M_OUT },
20554242Sbostic # endif /* CRDLY */
20654242Sbostic # ifdef TABDLY
20754242Sbostic { "tabdly", TABDLY, M_OUT },
20854242Sbostic # endif /* TABDLY */
20954242Sbostic # ifdef XTABS
21054242Sbostic { "xtabs", XTABS, M_OUT },
21154242Sbostic # endif /* XTABS */
21254242Sbostic # ifdef BSDLY
21354242Sbostic { "bsdly", BSDLY, M_OUT },
21454242Sbostic # endif /* BSDLY */
21554242Sbostic # ifdef VTDLY
21654242Sbostic { "vtdly", VTDLY, M_OUT },
21754242Sbostic # endif /* VTDLY */
21854242Sbostic # ifdef FFDLY
21954242Sbostic { "ffdly", FFDLY, M_OUT },
22054242Sbostic # endif /* FFDLY */
22154242Sbostic # ifdef PAGEOUT
22254242Sbostic { "pageout",PAGEOUT,M_OUT },
22354242Sbostic # endif /* PAGEOUT */
22454242Sbostic # ifdef WRAP
22554242Sbostic { "wrap", WRAP, M_OUT },
22654242Sbostic # endif /* WRAP */
22754242Sbostic
22854242Sbostic # ifdef CIGNORE
22954242Sbostic { "cignore",CIGNORE,M_CTL },
23054242Sbostic # endif /* CBAUD */
23154242Sbostic # ifdef CBAUD
23254242Sbostic { "cbaud", CBAUD, M_CTL },
23354242Sbostic # endif /* CBAUD */
23454242Sbostic # ifdef CSTOPB
23554242Sbostic { "cstopb", CSTOPB, M_CTL },
23654242Sbostic # endif /* CSTOPB */
23754242Sbostic # ifdef CREAD
23854242Sbostic { "cread", CREAD, M_CTL },
23954242Sbostic # endif /* CREAD */
24054242Sbostic # ifdef PARENB
24154242Sbostic { "parenb", PARENB, M_CTL },
24254242Sbostic # endif /* PARENB */
24354242Sbostic # ifdef PARODD
24454242Sbostic { "parodd", PARODD, M_CTL },
24554242Sbostic # endif /* PARODD */
24654242Sbostic # ifdef HUPCL
24754242Sbostic { "hupcl", HUPCL, M_CTL },
24854242Sbostic # endif /* HUPCL */
24954242Sbostic # ifdef CLOCAL
25054242Sbostic { "clocal", CLOCAL, M_CTL },
25154242Sbostic # endif /* CLOCAL */
25254242Sbostic # ifdef LOBLK
25354242Sbostic { "loblk", LOBLK, M_CTL },
25454242Sbostic # endif /* LOBLK */
25554242Sbostic # ifdef CIBAUD
25654242Sbostic { "cibaud", CIBAUD, M_CTL },
25754242Sbostic # endif /* CIBAUD */
25854242Sbostic # ifdef CRTSCTS
25954242Sbostic # ifdef CCTS_OFLOW
26054242Sbostic { "ccts_oflow",CCTS_OFLOW,M_CTL },
26154242Sbostic # else
26254242Sbostic { "crtscts",CRTSCTS,M_CTL },
26354242Sbostic # endif /* CCTS_OFLOW */
26454242Sbostic # endif /* CRTSCTS */
26554242Sbostic # ifdef CRTS_IFLOW
26654242Sbostic { "crts_iflow",CRTS_IFLOW,M_CTL },
26754242Sbostic # endif /* CRTS_IFLOW */
26854242Sbostic # ifdef MDMBUF
26954242Sbostic { "mdmbuf", MDMBUF, M_CTL },
27054242Sbostic # endif /* MDMBUF */
27154242Sbostic # ifdef RCV1EN
27254242Sbostic { "rcv1en", RCV1EN, M_CTL },
27354242Sbostic # endif /* RCV1EN */
27454242Sbostic # ifdef XMT1EN
27554242Sbostic { "xmt1en", XMT1EN, M_CTL },
27654242Sbostic # endif /* XMT1EN */
27754242Sbostic
27854242Sbostic # ifdef ISIG
27954242Sbostic { "isig", ISIG, M_LIN },
28054242Sbostic # endif /* ISIG */
28154242Sbostic # ifdef ICANON
28254242Sbostic { "icanon", ICANON, M_LIN },
28354242Sbostic # endif /* ICANON */
28454242Sbostic # ifdef XCASE
28554242Sbostic { "xcase", XCASE, M_LIN },
28654242Sbostic # endif /* XCASE */
28754242Sbostic # ifdef ECHO
28854242Sbostic { "echo", ECHO, M_LIN },
28954242Sbostic # endif /* ECHO */
29054242Sbostic # ifdef ECHOE
29154242Sbostic { "echoe", ECHOE, M_LIN },
29254242Sbostic # endif /* ECHOE */
29354242Sbostic # ifdef ECHOK
29454242Sbostic { "echok", ECHOK, M_LIN },
29554242Sbostic # endif /* ECHOK */
29654242Sbostic # ifdef ECHONL
29754242Sbostic { "echonl", ECHONL, M_LIN },
29854242Sbostic # endif /* ECHONL */
29954242Sbostic # ifdef NOFLSH
30054242Sbostic { "noflsh", NOFLSH, M_LIN },
30154242Sbostic # endif /* NOFLSH */
30254242Sbostic # ifdef TOSTOP
30354242Sbostic { "tostop", TOSTOP, M_LIN },
30454242Sbostic # endif /* TOSTOP */
30554242Sbostic # ifdef ECHOCTL
30654242Sbostic { "echoctl",ECHOCTL,M_LIN },
30754242Sbostic # endif /* ECHOCTL */
30854242Sbostic # ifdef ECHOPRT
30954242Sbostic { "echoprt",ECHOPRT,M_LIN },
31054242Sbostic # endif /* ECHOPRT */
31154242Sbostic # ifdef ECHOKE
31254242Sbostic { "echoke", ECHOKE, M_LIN },
31354242Sbostic # endif /* ECHOKE */
31454242Sbostic # ifdef DEFECHO
31554242Sbostic { "defecho",DEFECHO,M_LIN },
31654242Sbostic # endif /* DEFECHO */
31754242Sbostic # ifdef FLUSHO
31854242Sbostic { "flusho", FLUSHO, M_LIN },
31954242Sbostic # endif /* FLUSHO */
32054242Sbostic # ifdef PENDIN
32154242Sbostic { "pendin", PENDIN, M_LIN },
32254242Sbostic # endif /* PENDIN */
32354242Sbostic # ifdef IEXTEN
32454242Sbostic { "iexten", IEXTEN, M_LIN },
32554242Sbostic # endif /* IEXTEN */
32654242Sbostic # ifdef NOKERNINFO
32754242Sbostic { "nokerninfo",NOKERNINFO,M_LIN },
32854242Sbostic # endif /* NOKERNINFO */
32954242Sbostic # ifdef ALTWERASE
33054242Sbostic { "altwerase",ALTWERASE,M_LIN },
33154242Sbostic # endif /* ALTWERASE */
33254242Sbostic # ifdef EXTPROC
33354242Sbostic { "extproc",EXTPROC, M_LIN },
33454242Sbostic # endif /* EXTPROC */
33554242Sbostic
33654242Sbostic # if defined(VINTR)
33754242Sbostic { "intr", C_SH(C_INTR), M_CHAR },
33854242Sbostic # endif /* VINTR */
33954242Sbostic # if defined(VQUIT)
34054242Sbostic { "quit", C_SH(C_QUIT), M_CHAR },
34154242Sbostic # endif /* VQUIT */
34254242Sbostic # if defined(VERASE)
34354242Sbostic { "erase", C_SH(C_ERASE), M_CHAR },
34454242Sbostic # endif /* VERASE */
34554242Sbostic # if defined(VKILL)
34654242Sbostic { "kill", C_SH(C_KILL), M_CHAR },
34754242Sbostic # endif /* VKILL */
34854242Sbostic # if defined(VEOF)
34954242Sbostic { "eof", C_SH(C_EOF), M_CHAR },
35054242Sbostic # endif /* VEOF */
35154242Sbostic # if defined(VEOL)
35254242Sbostic { "eol", C_SH(C_EOL), M_CHAR },
35354242Sbostic # endif /* VEOL */
35454242Sbostic # if defined(VEOL2)
35554242Sbostic { "eol2", C_SH(C_EOL2), M_CHAR },
35654242Sbostic # endif /* VEOL2 */
35754242Sbostic # if defined(VSWTCH)
35854242Sbostic { "swtch", C_SH(C_SWTCH), M_CHAR },
35954242Sbostic # endif /* VSWTCH */
36054242Sbostic # if defined(VDSWTCH)
36154242Sbostic { "dswtch", C_SH(C_DSWTCH), M_CHAR },
36254242Sbostic # endif /* VDSWTCH */
36354242Sbostic # if defined(VERASE2)
36454242Sbostic { "erase2", C_SH(C_ERASE2), M_CHAR },
36554242Sbostic # endif /* VERASE2 */
36654242Sbostic # if defined(VSTART)
36754242Sbostic { "start", C_SH(C_START), M_CHAR },
36854242Sbostic # endif /* VSTART */
36954242Sbostic # if defined(VSTOP)
37054242Sbostic { "stop", C_SH(C_STOP), M_CHAR },
37154242Sbostic # endif /* VSTOP */
37254242Sbostic # if defined(VWERASE)
37354242Sbostic { "werase", C_SH(C_WERASE), M_CHAR },
37454242Sbostic # endif /* VWERASE */
37554242Sbostic # if defined(VSUSP)
37654242Sbostic { "susp", C_SH(C_SUSP), M_CHAR },
37754242Sbostic # endif /* VSUSP */
37854242Sbostic # if defined(VDSUSP)
37954242Sbostic { "dsusp", C_SH(C_DSUSP), M_CHAR },
38054242Sbostic # endif /* VDSUSP */
38154242Sbostic # if defined(VREPRINT)
38254242Sbostic { "reprint", C_SH(C_REPRINT),M_CHAR },
38355299Smarc # endif /* VREPRINT */
38454242Sbostic # if defined(VDISCARD)
38554242Sbostic { "discard", C_SH(C_DISCARD),M_CHAR },
38654242Sbostic # endif /* VDISCARD */
38754242Sbostic # if defined(VLNEXT)
38854242Sbostic { "lnext", C_SH(C_LNEXT), M_CHAR },
38954242Sbostic # endif /* VLNEXT */
39054242Sbostic # if defined(VSTATUS)
39154242Sbostic { "status", C_SH(C_STATUS), M_CHAR },
39254242Sbostic # endif /* VSTATUS */
39354242Sbostic # if defined(VPAGE)
39454242Sbostic { "page", C_SH(C_PAGE), M_CHAR },
39554242Sbostic # endif /* VPAGE */
39654242Sbostic # if defined(VPGOFF)
39754242Sbostic { "pgoff", C_SH(C_PGOFF), M_CHAR },
39854242Sbostic # endif /* VPGOFF */
39954242Sbostic # if defined(VKILL2)
40054242Sbostic { "kill2", C_SH(C_KILL2), M_CHAR },
40154242Sbostic # endif /* VKILL2 */
40254242Sbostic # if defined(VBRK)
40354242Sbostic { "brk", C_SH(C_BRK), M_CHAR },
40454242Sbostic # endif /* VBRK */
40554242Sbostic # if defined(VMIN)
40654242Sbostic { "min", C_SH(C_MIN), M_CHAR },
40754242Sbostic # endif /* VMIN */
40854242Sbostic # if defined(VTIME)
40954242Sbostic { "time", C_SH(C_TIME), M_CHAR },
41054242Sbostic # endif /* VTIME */
41154242Sbostic { NULL, 0, -1 },
41254242Sbostic };
41354242Sbostic
41454242Sbostic
41554242Sbostic
41654242Sbostic #define tty_getty(el, td) tcgetattr((el)->el_infd, (td))
41754242Sbostic #define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td))
41854242Sbostic
41954242Sbostic #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
42054242Sbostic #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
42154242Sbostic #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
42254242Sbostic
42354242Sbostic private void tty__getchar __P((struct termios *, unsigned char *));
42454242Sbostic private void tty__setchar __P((struct termios *, unsigned char *));
42554242Sbostic private speed_t tty__getspeed __P((struct termios *));
42654242Sbostic private int tty_setup __P((EditLine *));
42754242Sbostic
42854242Sbostic #define t_qu t_ts
42954242Sbostic
43054242Sbostic
43154242Sbostic /* tty_setup():
43254242Sbostic * Get the tty parameters and initialize the editing state
43354242Sbostic */
43454242Sbostic private int
tty_setup(el)43554242Sbostic tty_setup(el)
43654242Sbostic EditLine *el;
43754242Sbostic {
43854242Sbostic int rst = 1;
43954242Sbostic if (tty_getty(el, &el->el_tty.t_ed) == -1) {
44054242Sbostic #ifdef DEBUG_TTY
44154242Sbostic (void) fprintf(el->el_errfile,
44254242Sbostic "tty_setup: tty_getty: %s\n", strerror(errno));
44354242Sbostic #endif /* DEBUG_TTY */
44454242Sbostic return(-1);
44554242Sbostic }
44654242Sbostic el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
44754242Sbostic
44854242Sbostic el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
44954242Sbostic el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
45054242Sbostic el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
45154242Sbostic
45254242Sbostic el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask;
45354242Sbostic el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask;
45454242Sbostic
45554242Sbostic el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask;
45654242Sbostic el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask;
45754242Sbostic
45854242Sbostic el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask;
45954242Sbostic el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask;
46054242Sbostic
46154242Sbostic el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask;
46254242Sbostic el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask;
46354242Sbostic
46454242Sbostic /*
46554242Sbostic * Reset the tty chars to reasonable defaults
46654242Sbostic * If they are disabled, then enable them.
46754242Sbostic */
46854242Sbostic if (rst) {
46954242Sbostic if (tty__cooked_mode(&el->el_tty.t_ts)) {
47054242Sbostic tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
47154242Sbostic /*
47254242Sbostic * Don't affect CMIN and CTIME for the editor mode
47354242Sbostic */
47454242Sbostic for (rst = 0; rst < C_NCC - 2; rst++)
47554242Sbostic if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
47654242Sbostic el->el_tty.t_c[ED_IO][rst] != el->el_tty.t_vdisable)
47754242Sbostic el->el_tty.t_c[ED_IO][rst] = el->el_tty.t_c[TS_IO][rst];
47854242Sbostic for (rst = 0; rst < C_NCC; rst++)
47954242Sbostic if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
48054242Sbostic el->el_tty.t_c[EX_IO][rst] != el->el_tty.t_vdisable)
48154242Sbostic el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst];
48254242Sbostic }
48354242Sbostic tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
48454242Sbostic if (tty_setty(el, &el->el_tty.t_ex) == -1) {
48554242Sbostic #ifdef DEBUG_TTY
48654242Sbostic (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n",
48754242Sbostic strerror(errno));
48854242Sbostic #endif /* DEBUG_TTY */
48954242Sbostic return(-1);
49054242Sbostic }
49154242Sbostic }
49254242Sbostic else
49354242Sbostic tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
49454242Sbostic
49554242Sbostic el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
49654242Sbostic el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
49754242Sbostic
49854242Sbostic el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
49954242Sbostic el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
50054242Sbostic
50154242Sbostic el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
50254242Sbostic el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
50354242Sbostic
50454242Sbostic el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
50554242Sbostic el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
50654242Sbostic
50754242Sbostic tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
50854242Sbostic return 0;
50954242Sbostic }
51054242Sbostic
51154242Sbostic protected int
tty_init(el)51254242Sbostic tty_init(el)
51354242Sbostic EditLine *el;
51454242Sbostic {
51554242Sbostic el->el_tty.t_mode = EX_IO;
51654242Sbostic el->el_tty.t_vdisable = _POSIX_VDISABLE;
51754242Sbostic (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
51854242Sbostic (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
51954242Sbostic return tty_setup(el);
52054242Sbostic } /* end tty_init */
52154242Sbostic
52254242Sbostic
52354242Sbostic /* tty_end():
52454242Sbostic * Restore the tty to its original settings
52554242Sbostic */
52654242Sbostic protected void
52754242Sbostic /*ARGSUSED*/
tty_end(el)52854242Sbostic tty_end(el)
52954242Sbostic EditLine *el;
53054242Sbostic {
53154242Sbostic /* XXX: Maybe reset to an initial state? */
53254242Sbostic }
53354242Sbostic
53454242Sbostic
53554242Sbostic /* tty__getspeed():
53654242Sbostic * Get the tty speed
53754242Sbostic */
53854242Sbostic private speed_t
tty__getspeed(td)53954242Sbostic tty__getspeed(td)
54054242Sbostic struct termios *td;
54154242Sbostic {
54254242Sbostic speed_t spd;
54354242Sbostic
54454242Sbostic if ((spd = cfgetispeed(td)) == 0)
54554242Sbostic spd = cfgetospeed(td);
54654242Sbostic return spd;
54754242Sbostic } /* end tty__getspeed */
54854242Sbostic
54954242Sbostic
55054242Sbostic /* tty__getchar():
55154242Sbostic * Get the tty characters
55254242Sbostic */
55354242Sbostic private void
tty__getchar(td,s)55454242Sbostic tty__getchar(td, s)
55554242Sbostic struct termios *td;
55654242Sbostic unsigned char *s;
55754242Sbostic {
55854242Sbostic # ifdef VINTR
55954242Sbostic s[C_INTR] = td->c_cc[VINTR];
56054242Sbostic # endif /* VINTR */
56154242Sbostic # ifdef VQUIT
56254242Sbostic s[C_QUIT] = td->c_cc[VQUIT];
56354242Sbostic # endif /* VQUIT */
56454242Sbostic # ifdef VERASE
56554242Sbostic s[C_ERASE] = td->c_cc[VERASE];
56654242Sbostic # endif /* VERASE */
56754242Sbostic # ifdef VKILL
56854242Sbostic s[C_KILL] = td->c_cc[VKILL];
56954242Sbostic # endif /* VKILL */
57054242Sbostic # ifdef VEOF
57154242Sbostic s[C_EOF] = td->c_cc[VEOF];
57254242Sbostic # endif /* VEOF */
57354242Sbostic # ifdef VEOL
57454242Sbostic s[C_EOL] = td->c_cc[VEOL];
57554242Sbostic # endif /* VEOL */
57654242Sbostic # ifdef VEOL2
57754242Sbostic s[C_EOL2] = td->c_cc[VEOL2];
57854242Sbostic # endif /* VEOL2 */
57954242Sbostic # ifdef VSWTCH
58054242Sbostic s[C_SWTCH] = td->c_cc[VSWTCH];
58154242Sbostic # endif /* VSWTCH */
58254242Sbostic # ifdef VDSWTCH
58354242Sbostic s[C_DSWTCH] = td->c_cc[VDSWTCH];
58454242Sbostic # endif /* VDSWTCH */
58554242Sbostic # ifdef VERASE2
58654242Sbostic s[C_ERASE2] = td->c_cc[VERASE2];
58754242Sbostic # endif /* VERASE2 */
58854242Sbostic # ifdef VSTART
58954242Sbostic s[C_START] = td->c_cc[VSTART];
59054242Sbostic # endif /* VSTART */
59154242Sbostic # ifdef VSTOP
59254242Sbostic s[C_STOP] = td->c_cc[VSTOP];
59354242Sbostic # endif /* VSTOP */
59454242Sbostic # ifdef VWERASE
59554242Sbostic s[C_WERASE] = td->c_cc[VWERASE];
59654242Sbostic # endif /* VWERASE */
59754242Sbostic # ifdef VSUSP
59854242Sbostic s[C_SUSP] = td->c_cc[VSUSP];
59954242Sbostic # endif /* VSUSP */
60054242Sbostic # ifdef VDSUSP
60154242Sbostic s[C_DSUSP] = td->c_cc[VDSUSP];
60254242Sbostic # endif /* VDSUSP */
60354242Sbostic # ifdef VREPRINT
60454242Sbostic s[C_REPRINT]= td->c_cc[VREPRINT];
60555299Smarc # endif /* VREPRINT */
60654242Sbostic # ifdef VDISCARD
60754242Sbostic s[C_DISCARD]= td->c_cc[VDISCARD];
60854242Sbostic # endif /* VDISCARD */
60954242Sbostic # ifdef VLNEXT
61054242Sbostic s[C_LNEXT] = td->c_cc[VLNEXT];
61154242Sbostic # endif /* VLNEXT */
61254242Sbostic # ifdef VSTATUS
61354242Sbostic s[C_STATUS] = td->c_cc[VSTATUS];
61454242Sbostic # endif /* VSTATUS */
61554242Sbostic # ifdef VPAGE
61654242Sbostic s[C_PAGE] = td->c_cc[VPAGE];
61754242Sbostic # endif /* VPAGE */
61854242Sbostic # ifdef VPGOFF
61954242Sbostic s[C_PGOFF] = td->c_cc[VPGOFF];
62054242Sbostic # endif /* VPGOFF */
62154242Sbostic # ifdef VKILL2
62254242Sbostic s[C_KILL2] = td->c_cc[VKILL2];
62354242Sbostic # endif /* KILL2 */
62454242Sbostic # ifdef VMIN
62554242Sbostic s[C_MIN] = td->c_cc[VMIN];
62654242Sbostic # endif /* VMIN */
62754242Sbostic # ifdef VTIME
62854242Sbostic s[C_TIME] = td->c_cc[VTIME];
62954242Sbostic # endif /* VTIME */
63054242Sbostic } /* tty__getchar */
63154242Sbostic
63254242Sbostic
63354242Sbostic /* tty__setchar():
63454242Sbostic * Set the tty characters
63554242Sbostic */
63654242Sbostic private void
tty__setchar(td,s)63754242Sbostic tty__setchar(td, s)
63854242Sbostic struct termios *td;
63954242Sbostic unsigned char *s;
64054242Sbostic {
64154242Sbostic # ifdef VINTR
64254242Sbostic td->c_cc[VINTR] = s[C_INTR];
64354242Sbostic # endif /* VINTR */
64454242Sbostic # ifdef VQUIT
64554242Sbostic td->c_cc[VQUIT] = s[C_QUIT];
64654242Sbostic # endif /* VQUIT */
64754242Sbostic # ifdef VERASE
64854242Sbostic td->c_cc[VERASE] = s[C_ERASE];
64954242Sbostic # endif /* VERASE */
65054242Sbostic # ifdef VKILL
65154242Sbostic td->c_cc[VKILL] = s[C_KILL];
65254242Sbostic # endif /* VKILL */
65354242Sbostic # ifdef VEOF
65454242Sbostic td->c_cc[VEOF] = s[C_EOF];
65554242Sbostic # endif /* VEOF */
65654242Sbostic # ifdef VEOL
65754242Sbostic td->c_cc[VEOL] = s[C_EOL];
65854242Sbostic # endif /* VEOL */
65954242Sbostic # ifdef VEOL2
66054242Sbostic td->c_cc[VEOL2] = s[C_EOL2];
66154242Sbostic # endif /* VEOL2 */
66254242Sbostic # ifdef VSWTCH
66354242Sbostic td->c_cc[VSWTCH] = s[C_SWTCH];
66454242Sbostic # endif /* VSWTCH */
66554242Sbostic # ifdef VDSWTCH
66654242Sbostic td->c_cc[VDSWTCH] = s[C_DSWTCH];
66754242Sbostic # endif /* VDSWTCH */
66854242Sbostic # ifdef VERASE2
66954242Sbostic td->c_cc[VERASE2] = s[C_ERASE2];
67054242Sbostic # endif /* VERASE2 */
67154242Sbostic # ifdef VSTART
67254242Sbostic td->c_cc[VSTART] = s[C_START];
67354242Sbostic # endif /* VSTART */
67454242Sbostic # ifdef VSTOP
67554242Sbostic td->c_cc[VSTOP] = s[C_STOP];
67654242Sbostic # endif /* VSTOP */
67754242Sbostic # ifdef VWERASE
67854242Sbostic td->c_cc[VWERASE] = s[C_WERASE];
67954242Sbostic # endif /* VWERASE */
68054242Sbostic # ifdef VSUSP
68154242Sbostic td->c_cc[VSUSP] = s[C_SUSP];
68254242Sbostic # endif /* VSUSP */
68354242Sbostic # ifdef VDSUSP
68454242Sbostic td->c_cc[VDSUSP] = s[C_DSUSP];
68554242Sbostic # endif /* VDSUSP */
68654242Sbostic # ifdef VREPRINT
68754242Sbostic td->c_cc[VREPRINT] = s[C_REPRINT];
68855299Smarc # endif /* VREPRINT */
68954242Sbostic # ifdef VDISCARD
69054242Sbostic td->c_cc[VDISCARD] = s[C_DISCARD];
69154242Sbostic # endif /* VDISCARD */
69254242Sbostic # ifdef VLNEXT
69354242Sbostic td->c_cc[VLNEXT] = s[C_LNEXT];
69454242Sbostic # endif /* VLNEXT */
69554242Sbostic # ifdef VSTATUS
69654242Sbostic td->c_cc[VSTATUS] = s[C_STATUS];
69754242Sbostic # endif /* VSTATUS */
69854242Sbostic # ifdef VPAGE
69954242Sbostic td->c_cc[VPAGE] = s[C_PAGE];
70054242Sbostic # endif /* VPAGE */
70154242Sbostic # ifdef VPGOFF
70254242Sbostic td->c_cc[VPGOFF] = s[C_PGOFF];
70354242Sbostic # endif /* VPGOFF */
70454242Sbostic # ifdef VKILL2
70554242Sbostic td->c_cc[VKILL2] = s[C_KILL2];
70654242Sbostic # endif /* VKILL2 */
70754242Sbostic # ifdef VMIN
70854242Sbostic td->c_cc[VMIN] = s[C_MIN];
70954242Sbostic # endif /* VMIN */
71054242Sbostic # ifdef VTIME
71154242Sbostic td->c_cc[VTIME] = s[C_TIME];
71254242Sbostic # endif /* VTIME */
71354242Sbostic } /* tty__setchar */
71454242Sbostic
71554242Sbostic
71655299Smarc /* tty_bind_char():
71755299Smarc * Rebind the editline functions
71855299Smarc */
71955353Schristos protected void
tty_bind_char(el,force)72055353Schristos tty_bind_char(el, force)
72155299Smarc EditLine *el;
72255353Schristos int force;
72355299Smarc {
72455299Smarc unsigned char *t_n = el->el_tty.t_c[ED_IO];
72555299Smarc unsigned char *t_o = el->el_tty.t_ed.c_cc;
72655353Schristos char new[2], old[2];
72755299Smarc ttymap_t *tp;
72855299Smarc el_action_t *dmap, *dalt, *map, *alt;
72955299Smarc new[1] = old[1] = '\0';
73055299Smarc
73155299Smarc
73255299Smarc map = el->el_map.key;
73355299Smarc alt = el->el_map.alt;
73455299Smarc if (el->el_map.type == MAP_VI) {
73555299Smarc dmap = el->el_map.vii;
73655299Smarc dalt = el->el_map.vic;
73755299Smarc }
73855299Smarc else {
73955299Smarc dmap = el->el_map.emacs;
74055299Smarc dalt = NULL;
74155299Smarc }
74255299Smarc
74355299Smarc for (tp = tty_map; tp->nch != -1; tp++) {
74455299Smarc new[0] = t_n[tp->nch];
74555299Smarc old[0] = t_o[tp->och];
74655353Schristos if (new[0] == old[0] && !force)
74755299Smarc continue;
74855299Smarc /* Put the old default binding back, and set the new binding */
74955353Schristos key_clear(el, map, old);
75055299Smarc map[old[0]] = dmap[old[0]];
75155353Schristos key_clear(el, map, new);
75255299Smarc /* MAP_VI == 1, MAP_EMACS == 0... */
75355299Smarc map[new[0]] = tp->bind[el->el_map.type];
75455299Smarc if (dalt) {
75555353Schristos key_clear(el, alt, old);
75655299Smarc alt[old[0]] = dalt[old[0]];
75755353Schristos key_clear(el, alt, new);
75855299Smarc alt[new[0]] = tp->bind[el->el_map.type+1];
75955299Smarc }
76055299Smarc }
76155299Smarc }
76255299Smarc
76354242Sbostic /* tty_rawmode():
76454242Sbostic * Set terminal into 1 character at a time mode.
76554242Sbostic */
76654242Sbostic protected int
tty_rawmode(el)76754242Sbostic tty_rawmode(el)
76854242Sbostic EditLine *el;
76954242Sbostic {
77054242Sbostic if (el->el_tty.t_mode == ED_IO)
77154242Sbostic return (0);
77254242Sbostic
77354242Sbostic if (tty_getty(el, &el->el_tty.t_ts) == -1) {
77454242Sbostic #ifdef DEBUG_TTY
77554242Sbostic (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", strerror(errno));
77654242Sbostic #endif /* DEBUG_TTY */
77754242Sbostic return(-1);
77854242Sbostic }
77954242Sbostic
78054242Sbostic /*
78154242Sbostic * We always keep up with the eight bit setting and the speed of the
78254242Sbostic * tty. But only we only believe changes that are made to cooked mode!
78354242Sbostic */
78454242Sbostic el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
78554242Sbostic el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
78654242Sbostic
78754242Sbostic if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
78854242Sbostic tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
78954242Sbostic (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
79054242Sbostic (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
79154242Sbostic (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
79254242Sbostic (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
79354242Sbostic }
79454242Sbostic
79554242Sbostic if (tty__cooked_mode(&el->el_tty.t_ts)) {
79654242Sbostic if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
79754242Sbostic el->el_tty.t_ex.c_cflag = el->el_tty.t_ts.c_cflag;
79854242Sbostic el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask;
79954242Sbostic el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask;
80054242Sbostic
80154242Sbostic el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag;
80254242Sbostic el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
80354242Sbostic el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
80454242Sbostic }
80554242Sbostic
80654242Sbostic if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
80754242Sbostic (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
80854242Sbostic el->el_tty.t_ex.c_lflag = el->el_tty.t_ts.c_lflag;
80954242Sbostic el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask;
81054242Sbostic el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask;
81154242Sbostic
81254242Sbostic el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag;
81354242Sbostic el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
81454242Sbostic el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
81554242Sbostic }
81654242Sbostic
81754242Sbostic if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
81854242Sbostic (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
81954242Sbostic el->el_tty.t_ex.c_iflag = el->el_tty.t_ts.c_iflag;
82054242Sbostic el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask;
82154242Sbostic el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask;
82254242Sbostic
82354242Sbostic el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag;
82454242Sbostic el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
82554242Sbostic el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
82654242Sbostic }
82754242Sbostic
82854242Sbostic if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
82954242Sbostic (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
83054242Sbostic el->el_tty.t_ex.c_oflag = el->el_tty.t_ts.c_oflag;
83154242Sbostic el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask;
83254242Sbostic el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask;
83354242Sbostic
83454242Sbostic el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag;
83554242Sbostic el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
83654242Sbostic el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
83754242Sbostic }
83854242Sbostic
83954242Sbostic if (tty__gettabs(&el->el_tty.t_ex) == 0)
84054242Sbostic el->el_tty.t_tabs = 0;
84154242Sbostic else
84254242Sbostic el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
84354242Sbostic
84454242Sbostic {
84554242Sbostic int i;
84654242Sbostic
84754242Sbostic tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
84854242Sbostic /*
84954242Sbostic * Check if the user made any changes.
85054242Sbostic * If he did, then propagate the changes to the
85154242Sbostic * edit and execute data structures.
85254242Sbostic */
85354242Sbostic for (i = 0; i < C_NCC; i++)
85454242Sbostic if (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])
85554242Sbostic break;
85654242Sbostic
85754242Sbostic if (i != C_NCC) {
85854242Sbostic /*
85954242Sbostic * Propagate changes only to the unprotected chars
86054242Sbostic * that have been modified just now.
86154242Sbostic */
86254242Sbostic for (i = 0; i < C_NCC; i++) {
86354242Sbostic if (!((el->el_tty.t_t[ED_IO][M_CHAR].t_setmask & C_SH(i)))
86454242Sbostic && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
86554242Sbostic el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
86654242Sbostic if (el->el_tty.t_t[ED_IO][M_CHAR].t_clrmask & C_SH(i))
86754242Sbostic el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
86854242Sbostic }
86955353Schristos tty_bind_char(el, 0);
87054242Sbostic tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
87154242Sbostic
87254242Sbostic for (i = 0; i < C_NCC; i++) {
87354242Sbostic if (!((el->el_tty.t_t[EX_IO][M_CHAR].t_setmask & C_SH(i)))
87454242Sbostic && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
87554242Sbostic el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
87654242Sbostic if (el->el_tty.t_t[EX_IO][M_CHAR].t_clrmask & C_SH(i))
87754242Sbostic el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
87854242Sbostic }
87954242Sbostic tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
88054242Sbostic }
88154242Sbostic
88254242Sbostic }
88354242Sbostic }
88454242Sbostic
88554242Sbostic if (tty_setty(el, &el->el_tty.t_ed) == -1) {
88654242Sbostic #ifdef DEBUG_TTY
88754242Sbostic (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
88854242Sbostic strerror(errno));
88954242Sbostic #endif /* DEBUG_TTY */
89054242Sbostic return -1;
89154242Sbostic }
89254242Sbostic el->el_tty.t_mode = ED_IO;
89354242Sbostic return (0);
89454242Sbostic } /* end tty_rawmode */
89554242Sbostic
89654242Sbostic
89754242Sbostic /* tty_cookedmode():
89854242Sbostic * Set the tty back to normal mode
89954242Sbostic */
90054242Sbostic protected int
tty_cookedmode(el)90154242Sbostic tty_cookedmode(el)
90254242Sbostic EditLine *el;
90354242Sbostic { /* set tty in normal setup */
90454242Sbostic if (el->el_tty.t_mode == EX_IO)
90554242Sbostic return (0);
90654242Sbostic
90754242Sbostic if (tty_setty(el, &el->el_tty.t_ex) == -1) {
90854242Sbostic #ifdef DEBUG_TTY
90954242Sbostic (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n",
91054242Sbostic strerror(errno));
91154242Sbostic #endif /* DEBUG_TTY */
91254242Sbostic return -1;
91354242Sbostic }
91454242Sbostic el->el_tty.t_mode = EX_IO;
91554242Sbostic return (0);
91654242Sbostic } /* end tty_cookedmode */
91754242Sbostic
91854242Sbostic
91954242Sbostic /* tty_quotemode():
92054242Sbostic * Turn on quote mode
92154242Sbostic */
92254242Sbostic protected int
tty_quotemode(el)92354242Sbostic tty_quotemode(el)
92454242Sbostic EditLine *el;
92554242Sbostic {
92654242Sbostic if (el->el_tty.t_mode == QU_IO)
92754242Sbostic return 0;
92854242Sbostic
92954242Sbostic el->el_tty.t_qu = el->el_tty.t_ed;
93054242Sbostic
93154242Sbostic el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][M_INP].t_clrmask;
93254242Sbostic el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][M_INP].t_setmask;
93354242Sbostic
93454242Sbostic el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][M_OUT].t_clrmask;
93554242Sbostic el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][M_OUT].t_setmask;
93654242Sbostic
93754242Sbostic el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][M_CTL].t_clrmask;
93854242Sbostic el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][M_CTL].t_setmask;
93954242Sbostic
94054242Sbostic el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][M_LIN].t_clrmask;
94154242Sbostic el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][M_LIN].t_setmask;
94254242Sbostic
94354242Sbostic if (tty_setty(el, &el->el_tty.t_qu) == -1) {
94454242Sbostic #ifdef DEBUG_TTY
94554242Sbostic (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
94654242Sbostic strerror(errno));
94754242Sbostic #endif /* DEBUG_TTY */
94854242Sbostic return -1;
94954242Sbostic }
95054242Sbostic el->el_tty.t_mode = QU_IO;
95154242Sbostic return 0;
95254242Sbostic } /* end tty_quotemode */
95354242Sbostic
95454242Sbostic
95554242Sbostic /* tty_noquotemode():
95654242Sbostic * Turn off quote mode
95754242Sbostic */
95854242Sbostic protected int
tty_noquotemode(el)95954242Sbostic tty_noquotemode(el)
96054242Sbostic EditLine *el;
96154242Sbostic {
96254242Sbostic if (el->el_tty.t_mode != QU_IO)
96354242Sbostic return 0;
96454242Sbostic if (tty_setty(el, &el->el_tty.t_ed) == -1) {
96554242Sbostic #ifdef DEBUG_TTY
96654242Sbostic (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
96754242Sbostic strerror(errno));
96854242Sbostic #endif /* DEBUG_TTY */
96954242Sbostic return -1;
97054242Sbostic }
97154242Sbostic el->el_tty.t_mode = ED_IO;
97254242Sbostic return 0;
97354242Sbostic }
97454242Sbostic
97554242Sbostic /* tty_stty():
97654242Sbostic * Stty builtin
97754242Sbostic */
97854242Sbostic protected int
97954242Sbostic /*ARGSUSED*/
tty_stty(el,argc,argv)98054242Sbostic tty_stty(el, argc, argv)
98154242Sbostic EditLine *el;
98254242Sbostic int argc;
98354242Sbostic char **argv;
98454242Sbostic {
98554242Sbostic ttymodes_t *m;
98654242Sbostic char x, *d;
98754242Sbostic int aflag = 0;
98854242Sbostic char *s;
98954242Sbostic char *name;
99054242Sbostic int z = EX_IO;
99154242Sbostic
99254242Sbostic if (argv == NULL)
99354242Sbostic return -1;
99454242Sbostic name = *argv++;
99554242Sbostic
99654242Sbostic while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
99754242Sbostic switch (argv[0][1]) {
99854242Sbostic case 'a':
99954242Sbostic aflag++;
100054242Sbostic argv++;
100154242Sbostic break;
100254242Sbostic case 'd':
100354242Sbostic argv++;
100454242Sbostic z = ED_IO;
100554242Sbostic break;
100654242Sbostic case 'x':
100754242Sbostic argv++;
100854242Sbostic z = EX_IO;
100954242Sbostic break;
101054242Sbostic case 'q':
101154242Sbostic argv++;
101254242Sbostic z = QU_IO;
101354242Sbostic break;
101454242Sbostic default:
101554242Sbostic (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n",
101654242Sbostic name, argv[0][1]);
101754242Sbostic return -1;
101854242Sbostic }
101954242Sbostic
102054242Sbostic if (!argv || !*argv) {
102154242Sbostic int i = -1;
102254242Sbostic int len = 0, st = 0, cu;
102354242Sbostic for (m = ttymodes; m->m_name; m++) {
102454242Sbostic if (m->m_type != i) {
102554242Sbostic (void) fprintf(el->el_outfile, "%s%s", i != -1 ? "\n" : "",
102654242Sbostic el->el_tty.t_t[z][m->m_type].t_name);
102754242Sbostic i = m->m_type;
102854242Sbostic st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name);
102954242Sbostic }
103054242Sbostic
103154242Sbostic x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0';
103254242Sbostic x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '-' : x;
103354242Sbostic
103454242Sbostic if (x != '\0' || aflag) {
103554242Sbostic
103654242Sbostic cu = strlen(m->m_name) + (x != '\0') + 1;
103754242Sbostic
103854242Sbostic if (len + cu >= el->el_term.t_size.h) {
103954242Sbostic (void) fprintf(el->el_outfile, "\n%*s", st, "");
104054242Sbostic len = st + cu;
104154242Sbostic }
104254242Sbostic else
104354242Sbostic len += cu;
104454242Sbostic
104554242Sbostic if (x != '\0')
104654242Sbostic (void) fprintf(el->el_outfile, "%c%s ", x, m->m_name);
104754242Sbostic else
104854242Sbostic (void) fprintf(el->el_outfile, "%s ", m->m_name);
104954242Sbostic }
105054242Sbostic }
105154242Sbostic (void) fprintf(el->el_outfile, "\n");
105254242Sbostic return 0;
105354242Sbostic }
105454242Sbostic
105554242Sbostic while (argv && (s = *argv++)) {
105654242Sbostic switch (*s) {
105754242Sbostic case '+':
105854242Sbostic case '-':
105954242Sbostic x = *s++;
106054242Sbostic break;
106154242Sbostic default:
106254242Sbostic x = '\0';
106354242Sbostic break;
106454242Sbostic }
106554242Sbostic d = s;
106654242Sbostic for (m = ttymodes; m->m_name; m++)
106754242Sbostic if (strcmp(m->m_name, d) == 0)
106854242Sbostic break;
106954242Sbostic
107054242Sbostic if (!m->m_name) {
107154242Sbostic (void) fprintf(el->el_errfile, "%s: Invalid argument `%s'.\n",
107254242Sbostic name, d);
107354242Sbostic return -1;
107454242Sbostic }
107554242Sbostic
107654242Sbostic switch (x) {
107754242Sbostic case '+':
107854242Sbostic el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
107954242Sbostic el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
108054242Sbostic break;
108154242Sbostic case '-':
108254242Sbostic el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
108354242Sbostic el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
108454242Sbostic break;
108554242Sbostic default:
108654242Sbostic el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
108754242Sbostic el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
108854242Sbostic break;
108954242Sbostic }
109054242Sbostic }
109154242Sbostic return 0;
109254242Sbostic } /* end tty_stty */
109354242Sbostic
109454242Sbostic
109554242Sbostic #ifdef notyet
109654242Sbostic /* tty_printchar():
109754242Sbostic * DEbugging routine to print the tty characters
109854242Sbostic */
109954242Sbostic private void
tty_printchar(el,s)110054242Sbostic tty_printchar(el, s)
110154242Sbostic EditLine *el;
110254242Sbostic unsigned char *s;
110354242Sbostic {
110454242Sbostic ttyperm_t *m;
110554242Sbostic int i;
110654242Sbostic
110754242Sbostic for (i = 0; i < C_NCC; i++) {
110854242Sbostic for (m = el->el_tty.t_t; m->m_name; m++)
110954242Sbostic if (m->m_type == M_CHAR && C_SH(i) == m->m_value)
111054242Sbostic break;
111154242Sbostic if (m->m_name)
111254242Sbostic (void) fprintf(el->el_errfile, "%s ^%c ", m->m_name, s[i] + 'A'-1);
111354242Sbostic if (i % 5 == 0)
111454242Sbostic (void) fprintf(el->el_errfile, "\n");
111554242Sbostic }
111654242Sbostic (void) fprintf(el->el_errfile, "\n");
111754242Sbostic }
111854242Sbostic #endif /* notyet */
1119