xref: /csrg-svn/lib/libedit/tty.c (revision 61276)
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