tty.c revision 1.4 1 1.4 christos /* $NetBSD: tty.c,v 1.4 1997/07/06 18:25:38 christos Exp $ */
2 1.2 lukem
3 1.1 cgd /*-
4 1.1 cgd * Copyright (c) 1992, 1993
5 1.1 cgd * The Regents of the University of California. All rights reserved.
6 1.1 cgd *
7 1.1 cgd * This code is derived from software contributed to Berkeley by
8 1.1 cgd * Christos Zoulas of Cornell University.
9 1.1 cgd *
10 1.1 cgd * Redistribution and use in source and binary forms, with or without
11 1.1 cgd * modification, are permitted provided that the following conditions
12 1.1 cgd * are met:
13 1.1 cgd * 1. Redistributions of source code must retain the above copyright
14 1.1 cgd * notice, this list of conditions and the following disclaimer.
15 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 cgd * notice, this list of conditions and the following disclaimer in the
17 1.1 cgd * documentation and/or other materials provided with the distribution.
18 1.1 cgd * 3. All advertising materials mentioning features or use of this software
19 1.1 cgd * must display the following acknowledgement:
20 1.1 cgd * This product includes software developed by the University of
21 1.1 cgd * California, Berkeley and its contributors.
22 1.1 cgd * 4. Neither the name of the University nor the names of its contributors
23 1.1 cgd * may be used to endorse or promote products derived from this software
24 1.1 cgd * without specific prior written permission.
25 1.1 cgd *
26 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 1.1 cgd * SUCH DAMAGE.
37 1.1 cgd */
38 1.1 cgd
39 1.4 christos #include <sys/cdefs.h>
40 1.1 cgd #if !defined(lint) && !defined(SCCSID)
41 1.2 lukem #if 0
42 1.1 cgd static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
43 1.2 lukem #else
44 1.4 christos __RCSID("$NetBSD: tty.c,v 1.4 1997/07/06 18:25:38 christos Exp $");
45 1.2 lukem #endif
46 1.1 cgd #endif /* not lint && not SCCSID */
47 1.1 cgd
48 1.1 cgd /*
49 1.1 cgd * tty.c: tty interface stuff
50 1.1 cgd */
51 1.1 cgd #include "sys.h"
52 1.1 cgd #include "tty.h"
53 1.1 cgd #include "el.h"
54 1.1 cgd
55 1.1 cgd typedef struct ttymodes_t {
56 1.1 cgd char *m_name;
57 1.3 christos u_int m_value;
58 1.1 cgd int m_type;
59 1.1 cgd } ttymodes_t;
60 1.1 cgd
61 1.1 cgd typedef struct ttymap_t {
62 1.1 cgd int nch, och; /* Internal and termio rep of chars */
63 1.1 cgd el_action_t bind[3]; /* emacs, vi, and vi-cmd */
64 1.1 cgd } ttymap_t;
65 1.1 cgd
66 1.1 cgd
67 1.1 cgd private ttyperm_t ttyperm = {
68 1.1 cgd {
69 1.1 cgd { "iflag:", ICRNL, (INLCR|IGNCR) },
70 1.1 cgd { "oflag:", (OPOST|ONLCR), ONLRET },
71 1.1 cgd { "cflag:", 0, 0 },
72 1.1 cgd { "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN),
73 1.1 cgd (NOFLSH|ECHONL|EXTPROC|FLUSHO) },
74 1.1 cgd { "chars:", 0, 0 },
75 1.1 cgd },
76 1.1 cgd {
77 1.1 cgd { "iflag:", (INLCR|ICRNL), IGNCR },
78 1.1 cgd { "oflag:", (OPOST|ONLCR), ONLRET },
79 1.1 cgd { "cflag:", 0, 0 },
80 1.1 cgd { "lflag:", ISIG,
81 1.1 cgd (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO) },
82 1.1 cgd { "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)|
83 1.1 cgd C_SH(C_SUSP)|C_SH(C_DSUSP)|C_SH(C_EOL)|C_SH(C_DISCARD)|
84 1.1 cgd C_SH(C_PGOFF)|C_SH(C_PAGE)|C_SH(C_STATUS)), 0 }
85 1.1 cgd },
86 1.1 cgd {
87 1.1 cgd { "iflag:", 0, IXON | IXOFF },
88 1.1 cgd { "oflag:", 0, 0 },
89 1.1 cgd { "cflag:", 0, 0 },
90 1.1 cgd { "lflag:", 0, ISIG | IEXTEN },
91 1.1 cgd { "chars:", 0, 0 },
92 1.1 cgd }
93 1.1 cgd };
94 1.1 cgd
95 1.1 cgd private ttychar_t ttychar = {
96 1.1 cgd {
97 1.1 cgd CINTR, CQUIT, CERASE, CKILL,
98 1.1 cgd CEOF, CEOL, CEOL2, CSWTCH,
99 1.1 cgd CDSWTCH, CERASE2, CSTART, CSTOP,
100 1.1 cgd CWERASE, CSUSP, CDSUSP, CREPRINT,
101 1.1 cgd CDISCARD, CLNEXT, CSTATUS, CPAGE,
102 1.1 cgd CPGOFF, CKILL2, CBRK, CMIN,
103 1.1 cgd CTIME
104 1.1 cgd },
105 1.1 cgd {
106 1.1 cgd CINTR, CQUIT, CERASE, CKILL,
107 1.1 cgd _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
108 1.1 cgd _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
109 1.1 cgd _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
110 1.1 cgd CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
111 1.1 cgd _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
112 1.1 cgd 0
113 1.1 cgd },
114 1.1 cgd {
115 1.1 cgd 0, 0, 0, 0,
116 1.1 cgd 0, 0, 0, 0,
117 1.1 cgd 0, 0, 0, 0,
118 1.1 cgd 0, 0, 0, 0,
119 1.1 cgd 0, 0, 0, 0,
120 1.1 cgd 0, 0, 0, 0,
121 1.1 cgd 0
122 1.1 cgd }
123 1.1 cgd };
124 1.1 cgd
125 1.1 cgd private ttymap_t tty_map[] = {
126 1.1 cgd #ifdef VERASE
127 1.1 cgd { C_ERASE, VERASE,
128 1.1 cgd { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
129 1.1 cgd #endif /* VERASE */
130 1.1 cgd #ifdef VERASE2
131 1.1 cgd { C_ERASE2, VERASE2,
132 1.1 cgd { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
133 1.1 cgd #endif /* VERASE2 */
134 1.1 cgd #ifdef VKILL
135 1.1 cgd { C_KILL, VKILL,
136 1.1 cgd { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
137 1.1 cgd #endif /* VKILL */
138 1.1 cgd #ifdef VKILL2
139 1.1 cgd { C_KILL2, VKILL2,
140 1.1 cgd { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
141 1.1 cgd #endif /* VKILL2 */
142 1.1 cgd #ifdef VEOF
143 1.1 cgd { C_EOF, VEOF,
144 1.1 cgd { EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED } },
145 1.1 cgd #endif /* VEOF */
146 1.1 cgd #ifdef VWERASE
147 1.1 cgd { C_WERASE, VWERASE,
148 1.1 cgd { ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD } },
149 1.1 cgd #endif /* VWERASE */
150 1.1 cgd #ifdef VREPRINT
151 1.1 cgd { C_REPRINT, VREPRINT,
152 1.1 cgd { ED_REDISPLAY, ED_INSERT, ED_REDISPLAY } },
153 1.1 cgd #endif /* VREPRINT */
154 1.1 cgd #ifdef VLNEXT
155 1.1 cgd { C_LNEXT, VLNEXT,
156 1.1 cgd { ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED } },
157 1.1 cgd #endif /* VLNEXT */
158 1.1 cgd { -1, -1,
159 1.1 cgd { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } }
160 1.1 cgd };
161 1.1 cgd
162 1.1 cgd private ttymodes_t ttymodes[] = {
163 1.1 cgd # ifdef IGNBRK
164 1.1 cgd { "ignbrk", IGNBRK, M_INP },
165 1.1 cgd # endif /* IGNBRK */
166 1.1 cgd # ifdef BRKINT
167 1.1 cgd { "brkint", BRKINT, M_INP },
168 1.1 cgd # endif /* BRKINT */
169 1.1 cgd # ifdef IGNPAR
170 1.1 cgd { "ignpar", IGNPAR, M_INP },
171 1.1 cgd # endif /* IGNPAR */
172 1.1 cgd # ifdef PARMRK
173 1.1 cgd { "parmrk", PARMRK, M_INP },
174 1.1 cgd # endif /* PARMRK */
175 1.1 cgd # ifdef INPCK
176 1.1 cgd { "inpck", INPCK, M_INP },
177 1.1 cgd # endif /* INPCK */
178 1.1 cgd # ifdef ISTRIP
179 1.1 cgd { "istrip", ISTRIP, M_INP },
180 1.1 cgd # endif /* ISTRIP */
181 1.1 cgd # ifdef INLCR
182 1.1 cgd { "inlcr", INLCR, M_INP },
183 1.1 cgd # endif /* INLCR */
184 1.1 cgd # ifdef IGNCR
185 1.1 cgd { "igncr", IGNCR, M_INP },
186 1.1 cgd # endif /* IGNCR */
187 1.1 cgd # ifdef ICRNL
188 1.1 cgd { "icrnl", ICRNL, M_INP },
189 1.1 cgd # endif /* ICRNL */
190 1.1 cgd # ifdef IUCLC
191 1.1 cgd { "iuclc", IUCLC, M_INP },
192 1.1 cgd # endif /* IUCLC */
193 1.1 cgd # ifdef IXON
194 1.1 cgd { "ixon", IXON, M_INP },
195 1.1 cgd # endif /* IXON */
196 1.1 cgd # ifdef IXANY
197 1.1 cgd { "ixany", IXANY, M_INP },
198 1.1 cgd # endif /* IXANY */
199 1.1 cgd # ifdef IXOFF
200 1.1 cgd { "ixoff", IXOFF, M_INP },
201 1.1 cgd # endif /* IXOFF */
202 1.1 cgd # ifdef IMAXBEL
203 1.1 cgd { "imaxbel",IMAXBEL,M_INP },
204 1.1 cgd # endif /* IMAXBEL */
205 1.1 cgd
206 1.1 cgd # ifdef OPOST
207 1.1 cgd { "opost", OPOST, M_OUT },
208 1.1 cgd # endif /* OPOST */
209 1.1 cgd # ifdef OLCUC
210 1.1 cgd { "olcuc", OLCUC, M_OUT },
211 1.1 cgd # endif /* OLCUC */
212 1.1 cgd # ifdef ONLCR
213 1.1 cgd { "onlcr", ONLCR, M_OUT },
214 1.1 cgd # endif /* ONLCR */
215 1.1 cgd # ifdef OCRNL
216 1.1 cgd { "ocrnl", OCRNL, M_OUT },
217 1.1 cgd # endif /* OCRNL */
218 1.1 cgd # ifdef ONOCR
219 1.1 cgd { "onocr", ONOCR, M_OUT },
220 1.1 cgd # endif /* ONOCR */
221 1.1 cgd # ifdef ONOEOT
222 1.1 cgd { "onoeot", ONOEOT, M_OUT },
223 1.1 cgd # endif /* ONOEOT */
224 1.1 cgd # ifdef ONLRET
225 1.1 cgd { "onlret", ONLRET, M_OUT },
226 1.1 cgd # endif /* ONLRET */
227 1.1 cgd # ifdef OFILL
228 1.1 cgd { "ofill", OFILL, M_OUT },
229 1.1 cgd # endif /* OFILL */
230 1.1 cgd # ifdef OFDEL
231 1.1 cgd { "ofdel", OFDEL, M_OUT },
232 1.1 cgd # endif /* OFDEL */
233 1.1 cgd # ifdef NLDLY
234 1.1 cgd { "nldly", NLDLY, M_OUT },
235 1.1 cgd # endif /* NLDLY */
236 1.1 cgd # ifdef CRDLY
237 1.1 cgd { "crdly", CRDLY, M_OUT },
238 1.1 cgd # endif /* CRDLY */
239 1.1 cgd # ifdef TABDLY
240 1.1 cgd { "tabdly", TABDLY, M_OUT },
241 1.1 cgd # endif /* TABDLY */
242 1.1 cgd # ifdef XTABS
243 1.1 cgd { "xtabs", XTABS, M_OUT },
244 1.1 cgd # endif /* XTABS */
245 1.1 cgd # ifdef BSDLY
246 1.1 cgd { "bsdly", BSDLY, M_OUT },
247 1.1 cgd # endif /* BSDLY */
248 1.1 cgd # ifdef VTDLY
249 1.1 cgd { "vtdly", VTDLY, M_OUT },
250 1.1 cgd # endif /* VTDLY */
251 1.1 cgd # ifdef FFDLY
252 1.1 cgd { "ffdly", FFDLY, M_OUT },
253 1.1 cgd # endif /* FFDLY */
254 1.1 cgd # ifdef PAGEOUT
255 1.1 cgd { "pageout",PAGEOUT,M_OUT },
256 1.1 cgd # endif /* PAGEOUT */
257 1.1 cgd # ifdef WRAP
258 1.1 cgd { "wrap", WRAP, M_OUT },
259 1.1 cgd # endif /* WRAP */
260 1.1 cgd
261 1.1 cgd # ifdef CIGNORE
262 1.1 cgd { "cignore",CIGNORE,M_CTL },
263 1.1 cgd # endif /* CBAUD */
264 1.1 cgd # ifdef CBAUD
265 1.1 cgd { "cbaud", CBAUD, M_CTL },
266 1.1 cgd # endif /* CBAUD */
267 1.1 cgd # ifdef CSTOPB
268 1.1 cgd { "cstopb", CSTOPB, M_CTL },
269 1.1 cgd # endif /* CSTOPB */
270 1.1 cgd # ifdef CREAD
271 1.1 cgd { "cread", CREAD, M_CTL },
272 1.1 cgd # endif /* CREAD */
273 1.1 cgd # ifdef PARENB
274 1.1 cgd { "parenb", PARENB, M_CTL },
275 1.1 cgd # endif /* PARENB */
276 1.1 cgd # ifdef PARODD
277 1.1 cgd { "parodd", PARODD, M_CTL },
278 1.1 cgd # endif /* PARODD */
279 1.1 cgd # ifdef HUPCL
280 1.1 cgd { "hupcl", HUPCL, M_CTL },
281 1.1 cgd # endif /* HUPCL */
282 1.1 cgd # ifdef CLOCAL
283 1.1 cgd { "clocal", CLOCAL, M_CTL },
284 1.1 cgd # endif /* CLOCAL */
285 1.1 cgd # ifdef LOBLK
286 1.1 cgd { "loblk", LOBLK, M_CTL },
287 1.1 cgd # endif /* LOBLK */
288 1.1 cgd # ifdef CIBAUD
289 1.1 cgd { "cibaud", CIBAUD, M_CTL },
290 1.1 cgd # endif /* CIBAUD */
291 1.1 cgd # ifdef CRTSCTS
292 1.1 cgd # ifdef CCTS_OFLOW
293 1.1 cgd { "ccts_oflow",CCTS_OFLOW,M_CTL },
294 1.1 cgd # else
295 1.1 cgd { "crtscts",CRTSCTS,M_CTL },
296 1.1 cgd # endif /* CCTS_OFLOW */
297 1.1 cgd # endif /* CRTSCTS */
298 1.1 cgd # ifdef CRTS_IFLOW
299 1.1 cgd { "crts_iflow",CRTS_IFLOW,M_CTL },
300 1.1 cgd # endif /* CRTS_IFLOW */
301 1.1 cgd # ifdef MDMBUF
302 1.1 cgd { "mdmbuf", MDMBUF, M_CTL },
303 1.1 cgd # endif /* MDMBUF */
304 1.1 cgd # ifdef RCV1EN
305 1.1 cgd { "rcv1en", RCV1EN, M_CTL },
306 1.1 cgd # endif /* RCV1EN */
307 1.1 cgd # ifdef XMT1EN
308 1.1 cgd { "xmt1en", XMT1EN, M_CTL },
309 1.1 cgd # endif /* XMT1EN */
310 1.1 cgd
311 1.1 cgd # ifdef ISIG
312 1.1 cgd { "isig", ISIG, M_LIN },
313 1.1 cgd # endif /* ISIG */
314 1.1 cgd # ifdef ICANON
315 1.1 cgd { "icanon", ICANON, M_LIN },
316 1.1 cgd # endif /* ICANON */
317 1.1 cgd # ifdef XCASE
318 1.1 cgd { "xcase", XCASE, M_LIN },
319 1.1 cgd # endif /* XCASE */
320 1.1 cgd # ifdef ECHO
321 1.1 cgd { "echo", ECHO, M_LIN },
322 1.1 cgd # endif /* ECHO */
323 1.1 cgd # ifdef ECHOE
324 1.1 cgd { "echoe", ECHOE, M_LIN },
325 1.1 cgd # endif /* ECHOE */
326 1.1 cgd # ifdef ECHOK
327 1.1 cgd { "echok", ECHOK, M_LIN },
328 1.1 cgd # endif /* ECHOK */
329 1.1 cgd # ifdef ECHONL
330 1.1 cgd { "echonl", ECHONL, M_LIN },
331 1.1 cgd # endif /* ECHONL */
332 1.1 cgd # ifdef NOFLSH
333 1.1 cgd { "noflsh", NOFLSH, M_LIN },
334 1.1 cgd # endif /* NOFLSH */
335 1.1 cgd # ifdef TOSTOP
336 1.1 cgd { "tostop", TOSTOP, M_LIN },
337 1.1 cgd # endif /* TOSTOP */
338 1.1 cgd # ifdef ECHOCTL
339 1.1 cgd { "echoctl",ECHOCTL,M_LIN },
340 1.1 cgd # endif /* ECHOCTL */
341 1.1 cgd # ifdef ECHOPRT
342 1.1 cgd { "echoprt",ECHOPRT,M_LIN },
343 1.1 cgd # endif /* ECHOPRT */
344 1.1 cgd # ifdef ECHOKE
345 1.1 cgd { "echoke", ECHOKE, M_LIN },
346 1.1 cgd # endif /* ECHOKE */
347 1.1 cgd # ifdef DEFECHO
348 1.1 cgd { "defecho",DEFECHO,M_LIN },
349 1.1 cgd # endif /* DEFECHO */
350 1.1 cgd # ifdef FLUSHO
351 1.1 cgd { "flusho", FLUSHO, M_LIN },
352 1.1 cgd # endif /* FLUSHO */
353 1.1 cgd # ifdef PENDIN
354 1.1 cgd { "pendin", PENDIN, M_LIN },
355 1.1 cgd # endif /* PENDIN */
356 1.1 cgd # ifdef IEXTEN
357 1.1 cgd { "iexten", IEXTEN, M_LIN },
358 1.1 cgd # endif /* IEXTEN */
359 1.1 cgd # ifdef NOKERNINFO
360 1.1 cgd { "nokerninfo",NOKERNINFO,M_LIN },
361 1.1 cgd # endif /* NOKERNINFO */
362 1.1 cgd # ifdef ALTWERASE
363 1.1 cgd { "altwerase",ALTWERASE,M_LIN },
364 1.1 cgd # endif /* ALTWERASE */
365 1.1 cgd # ifdef EXTPROC
366 1.1 cgd { "extproc",EXTPROC, M_LIN },
367 1.1 cgd # endif /* EXTPROC */
368 1.1 cgd
369 1.1 cgd # if defined(VINTR)
370 1.1 cgd { "intr", C_SH(C_INTR), M_CHAR },
371 1.1 cgd # endif /* VINTR */
372 1.1 cgd # if defined(VQUIT)
373 1.1 cgd { "quit", C_SH(C_QUIT), M_CHAR },
374 1.1 cgd # endif /* VQUIT */
375 1.1 cgd # if defined(VERASE)
376 1.1 cgd { "erase", C_SH(C_ERASE), M_CHAR },
377 1.1 cgd # endif /* VERASE */
378 1.1 cgd # if defined(VKILL)
379 1.1 cgd { "kill", C_SH(C_KILL), M_CHAR },
380 1.1 cgd # endif /* VKILL */
381 1.1 cgd # if defined(VEOF)
382 1.1 cgd { "eof", C_SH(C_EOF), M_CHAR },
383 1.1 cgd # endif /* VEOF */
384 1.1 cgd # if defined(VEOL)
385 1.1 cgd { "eol", C_SH(C_EOL), M_CHAR },
386 1.1 cgd # endif /* VEOL */
387 1.1 cgd # if defined(VEOL2)
388 1.1 cgd { "eol2", C_SH(C_EOL2), M_CHAR },
389 1.1 cgd # endif /* VEOL2 */
390 1.1 cgd # if defined(VSWTCH)
391 1.1 cgd { "swtch", C_SH(C_SWTCH), M_CHAR },
392 1.1 cgd # endif /* VSWTCH */
393 1.1 cgd # if defined(VDSWTCH)
394 1.1 cgd { "dswtch", C_SH(C_DSWTCH), M_CHAR },
395 1.1 cgd # endif /* VDSWTCH */
396 1.1 cgd # if defined(VERASE2)
397 1.1 cgd { "erase2", C_SH(C_ERASE2), M_CHAR },
398 1.1 cgd # endif /* VERASE2 */
399 1.1 cgd # if defined(VSTART)
400 1.1 cgd { "start", C_SH(C_START), M_CHAR },
401 1.1 cgd # endif /* VSTART */
402 1.1 cgd # if defined(VSTOP)
403 1.1 cgd { "stop", C_SH(C_STOP), M_CHAR },
404 1.1 cgd # endif /* VSTOP */
405 1.1 cgd # if defined(VWERASE)
406 1.1 cgd { "werase", C_SH(C_WERASE), M_CHAR },
407 1.1 cgd # endif /* VWERASE */
408 1.1 cgd # if defined(VSUSP)
409 1.1 cgd { "susp", C_SH(C_SUSP), M_CHAR },
410 1.1 cgd # endif /* VSUSP */
411 1.1 cgd # if defined(VDSUSP)
412 1.1 cgd { "dsusp", C_SH(C_DSUSP), M_CHAR },
413 1.1 cgd # endif /* VDSUSP */
414 1.1 cgd # if defined(VREPRINT)
415 1.1 cgd { "reprint", C_SH(C_REPRINT),M_CHAR },
416 1.1 cgd # endif /* VREPRINT */
417 1.1 cgd # if defined(VDISCARD)
418 1.1 cgd { "discard", C_SH(C_DISCARD),M_CHAR },
419 1.1 cgd # endif /* VDISCARD */
420 1.1 cgd # if defined(VLNEXT)
421 1.1 cgd { "lnext", C_SH(C_LNEXT), M_CHAR },
422 1.1 cgd # endif /* VLNEXT */
423 1.1 cgd # if defined(VSTATUS)
424 1.1 cgd { "status", C_SH(C_STATUS), M_CHAR },
425 1.1 cgd # endif /* VSTATUS */
426 1.1 cgd # if defined(VPAGE)
427 1.1 cgd { "page", C_SH(C_PAGE), M_CHAR },
428 1.1 cgd # endif /* VPAGE */
429 1.1 cgd # if defined(VPGOFF)
430 1.1 cgd { "pgoff", C_SH(C_PGOFF), M_CHAR },
431 1.1 cgd # endif /* VPGOFF */
432 1.1 cgd # if defined(VKILL2)
433 1.1 cgd { "kill2", C_SH(C_KILL2), M_CHAR },
434 1.1 cgd # endif /* VKILL2 */
435 1.1 cgd # if defined(VBRK)
436 1.1 cgd { "brk", C_SH(C_BRK), M_CHAR },
437 1.1 cgd # endif /* VBRK */
438 1.1 cgd # if defined(VMIN)
439 1.1 cgd { "min", C_SH(C_MIN), M_CHAR },
440 1.1 cgd # endif /* VMIN */
441 1.1 cgd # if defined(VTIME)
442 1.1 cgd { "time", C_SH(C_TIME), M_CHAR },
443 1.1 cgd # endif /* VTIME */
444 1.1 cgd { NULL, 0, -1 },
445 1.1 cgd };
446 1.1 cgd
447 1.1 cgd
448 1.1 cgd
449 1.1 cgd #define tty_getty(el, td) tcgetattr((el)->el_infd, (td))
450 1.1 cgd #define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td))
451 1.1 cgd
452 1.1 cgd #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
453 1.1 cgd #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
454 1.1 cgd #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
455 1.1 cgd
456 1.1 cgd private void tty__getchar __P((struct termios *, unsigned char *));
457 1.1 cgd private void tty__setchar __P((struct termios *, unsigned char *));
458 1.1 cgd private speed_t tty__getspeed __P((struct termios *));
459 1.1 cgd private int tty_setup __P((EditLine *));
460 1.1 cgd
461 1.1 cgd #define t_qu t_ts
462 1.1 cgd
463 1.1 cgd
464 1.1 cgd /* tty_setup():
465 1.1 cgd * Get the tty parameters and initialize the editing state
466 1.1 cgd */
467 1.1 cgd private int
468 1.1 cgd tty_setup(el)
469 1.1 cgd EditLine *el;
470 1.1 cgd {
471 1.1 cgd int rst = 1;
472 1.1 cgd if (tty_getty(el, &el->el_tty.t_ed) == -1) {
473 1.1 cgd #ifdef DEBUG_TTY
474 1.1 cgd (void) fprintf(el->el_errfile,
475 1.1 cgd "tty_setup: tty_getty: %s\n", strerror(errno));
476 1.1 cgd #endif /* DEBUG_TTY */
477 1.1 cgd return(-1);
478 1.1 cgd }
479 1.1 cgd el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
480 1.1 cgd
481 1.1 cgd el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
482 1.1 cgd el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
483 1.1 cgd el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
484 1.1 cgd
485 1.1 cgd el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask;
486 1.1 cgd el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask;
487 1.1 cgd
488 1.1 cgd el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask;
489 1.1 cgd el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask;
490 1.1 cgd
491 1.1 cgd el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask;
492 1.1 cgd el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask;
493 1.1 cgd
494 1.1 cgd el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask;
495 1.1 cgd el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask;
496 1.1 cgd
497 1.1 cgd /*
498 1.1 cgd * Reset the tty chars to reasonable defaults
499 1.1 cgd * If they are disabled, then enable them.
500 1.1 cgd */
501 1.1 cgd if (rst) {
502 1.1 cgd if (tty__cooked_mode(&el->el_tty.t_ts)) {
503 1.1 cgd tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
504 1.1 cgd /*
505 1.1 cgd * Don't affect CMIN and CTIME for the editor mode
506 1.1 cgd */
507 1.1 cgd for (rst = 0; rst < C_NCC - 2; rst++)
508 1.1 cgd if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
509 1.1 cgd el->el_tty.t_c[ED_IO][rst] != el->el_tty.t_vdisable)
510 1.1 cgd el->el_tty.t_c[ED_IO][rst] = el->el_tty.t_c[TS_IO][rst];
511 1.1 cgd for (rst = 0; rst < C_NCC; rst++)
512 1.1 cgd if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
513 1.1 cgd el->el_tty.t_c[EX_IO][rst] != el->el_tty.t_vdisable)
514 1.1 cgd el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst];
515 1.1 cgd }
516 1.1 cgd tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
517 1.1 cgd if (tty_setty(el, &el->el_tty.t_ex) == -1) {
518 1.1 cgd #ifdef DEBUG_TTY
519 1.1 cgd (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n",
520 1.1 cgd strerror(errno));
521 1.1 cgd #endif /* DEBUG_TTY */
522 1.1 cgd return(-1);
523 1.1 cgd }
524 1.1 cgd }
525 1.1 cgd else
526 1.1 cgd tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
527 1.1 cgd
528 1.1 cgd el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
529 1.1 cgd el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
530 1.1 cgd
531 1.1 cgd el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
532 1.1 cgd el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
533 1.1 cgd
534 1.1 cgd el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
535 1.1 cgd el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
536 1.1 cgd
537 1.1 cgd el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
538 1.1 cgd el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
539 1.1 cgd
540 1.1 cgd tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
541 1.1 cgd return 0;
542 1.1 cgd }
543 1.1 cgd
544 1.1 cgd protected int
545 1.1 cgd tty_init(el)
546 1.1 cgd EditLine *el;
547 1.1 cgd {
548 1.1 cgd el->el_tty.t_mode = EX_IO;
549 1.1 cgd el->el_tty.t_vdisable = _POSIX_VDISABLE;
550 1.1 cgd (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
551 1.1 cgd (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
552 1.1 cgd return tty_setup(el);
553 1.1 cgd } /* end tty_init */
554 1.1 cgd
555 1.1 cgd
556 1.1 cgd /* tty_end():
557 1.1 cgd * Restore the tty to its original settings
558 1.1 cgd */
559 1.1 cgd protected void
560 1.1 cgd /*ARGSUSED*/
561 1.1 cgd tty_end(el)
562 1.1 cgd EditLine *el;
563 1.1 cgd {
564 1.1 cgd /* XXX: Maybe reset to an initial state? */
565 1.1 cgd }
566 1.1 cgd
567 1.1 cgd
568 1.1 cgd /* tty__getspeed():
569 1.1 cgd * Get the tty speed
570 1.1 cgd */
571 1.1 cgd private speed_t
572 1.1 cgd tty__getspeed(td)
573 1.1 cgd struct termios *td;
574 1.1 cgd {
575 1.1 cgd speed_t spd;
576 1.1 cgd
577 1.1 cgd if ((spd = cfgetispeed(td)) == 0)
578 1.1 cgd spd = cfgetospeed(td);
579 1.1 cgd return spd;
580 1.1 cgd } /* end tty__getspeed */
581 1.1 cgd
582 1.1 cgd
583 1.1 cgd /* tty__getchar():
584 1.1 cgd * Get the tty characters
585 1.1 cgd */
586 1.1 cgd private void
587 1.1 cgd tty__getchar(td, s)
588 1.1 cgd struct termios *td;
589 1.1 cgd unsigned char *s;
590 1.1 cgd {
591 1.1 cgd # ifdef VINTR
592 1.1 cgd s[C_INTR] = td->c_cc[VINTR];
593 1.1 cgd # endif /* VINTR */
594 1.1 cgd # ifdef VQUIT
595 1.1 cgd s[C_QUIT] = td->c_cc[VQUIT];
596 1.1 cgd # endif /* VQUIT */
597 1.1 cgd # ifdef VERASE
598 1.1 cgd s[C_ERASE] = td->c_cc[VERASE];
599 1.1 cgd # endif /* VERASE */
600 1.1 cgd # ifdef VKILL
601 1.1 cgd s[C_KILL] = td->c_cc[VKILL];
602 1.1 cgd # endif /* VKILL */
603 1.1 cgd # ifdef VEOF
604 1.1 cgd s[C_EOF] = td->c_cc[VEOF];
605 1.1 cgd # endif /* VEOF */
606 1.1 cgd # ifdef VEOL
607 1.1 cgd s[C_EOL] = td->c_cc[VEOL];
608 1.1 cgd # endif /* VEOL */
609 1.1 cgd # ifdef VEOL2
610 1.1 cgd s[C_EOL2] = td->c_cc[VEOL2];
611 1.1 cgd # endif /* VEOL2 */
612 1.1 cgd # ifdef VSWTCH
613 1.1 cgd s[C_SWTCH] = td->c_cc[VSWTCH];
614 1.1 cgd # endif /* VSWTCH */
615 1.1 cgd # ifdef VDSWTCH
616 1.1 cgd s[C_DSWTCH] = td->c_cc[VDSWTCH];
617 1.1 cgd # endif /* VDSWTCH */
618 1.1 cgd # ifdef VERASE2
619 1.1 cgd s[C_ERASE2] = td->c_cc[VERASE2];
620 1.1 cgd # endif /* VERASE2 */
621 1.1 cgd # ifdef VSTART
622 1.1 cgd s[C_START] = td->c_cc[VSTART];
623 1.1 cgd # endif /* VSTART */
624 1.1 cgd # ifdef VSTOP
625 1.1 cgd s[C_STOP] = td->c_cc[VSTOP];
626 1.1 cgd # endif /* VSTOP */
627 1.1 cgd # ifdef VWERASE
628 1.1 cgd s[C_WERASE] = td->c_cc[VWERASE];
629 1.1 cgd # endif /* VWERASE */
630 1.1 cgd # ifdef VSUSP
631 1.1 cgd s[C_SUSP] = td->c_cc[VSUSP];
632 1.1 cgd # endif /* VSUSP */
633 1.1 cgd # ifdef VDSUSP
634 1.1 cgd s[C_DSUSP] = td->c_cc[VDSUSP];
635 1.1 cgd # endif /* VDSUSP */
636 1.1 cgd # ifdef VREPRINT
637 1.1 cgd s[C_REPRINT]= td->c_cc[VREPRINT];
638 1.1 cgd # endif /* VREPRINT */
639 1.1 cgd # ifdef VDISCARD
640 1.1 cgd s[C_DISCARD]= td->c_cc[VDISCARD];
641 1.1 cgd # endif /* VDISCARD */
642 1.1 cgd # ifdef VLNEXT
643 1.1 cgd s[C_LNEXT] = td->c_cc[VLNEXT];
644 1.1 cgd # endif /* VLNEXT */
645 1.1 cgd # ifdef VSTATUS
646 1.1 cgd s[C_STATUS] = td->c_cc[VSTATUS];
647 1.1 cgd # endif /* VSTATUS */
648 1.1 cgd # ifdef VPAGE
649 1.1 cgd s[C_PAGE] = td->c_cc[VPAGE];
650 1.1 cgd # endif /* VPAGE */
651 1.1 cgd # ifdef VPGOFF
652 1.1 cgd s[C_PGOFF] = td->c_cc[VPGOFF];
653 1.1 cgd # endif /* VPGOFF */
654 1.1 cgd # ifdef VKILL2
655 1.1 cgd s[C_KILL2] = td->c_cc[VKILL2];
656 1.1 cgd # endif /* KILL2 */
657 1.1 cgd # ifdef VMIN
658 1.1 cgd s[C_MIN] = td->c_cc[VMIN];
659 1.1 cgd # endif /* VMIN */
660 1.1 cgd # ifdef VTIME
661 1.1 cgd s[C_TIME] = td->c_cc[VTIME];
662 1.1 cgd # endif /* VTIME */
663 1.1 cgd } /* tty__getchar */
664 1.1 cgd
665 1.1 cgd
666 1.1 cgd /* tty__setchar():
667 1.1 cgd * Set the tty characters
668 1.1 cgd */
669 1.1 cgd private void
670 1.1 cgd tty__setchar(td, s)
671 1.1 cgd struct termios *td;
672 1.1 cgd unsigned char *s;
673 1.1 cgd {
674 1.1 cgd # ifdef VINTR
675 1.1 cgd td->c_cc[VINTR] = s[C_INTR];
676 1.1 cgd # endif /* VINTR */
677 1.1 cgd # ifdef VQUIT
678 1.1 cgd td->c_cc[VQUIT] = s[C_QUIT];
679 1.1 cgd # endif /* VQUIT */
680 1.1 cgd # ifdef VERASE
681 1.1 cgd td->c_cc[VERASE] = s[C_ERASE];
682 1.1 cgd # endif /* VERASE */
683 1.1 cgd # ifdef VKILL
684 1.1 cgd td->c_cc[VKILL] = s[C_KILL];
685 1.1 cgd # endif /* VKILL */
686 1.1 cgd # ifdef VEOF
687 1.1 cgd td->c_cc[VEOF] = s[C_EOF];
688 1.1 cgd # endif /* VEOF */
689 1.1 cgd # ifdef VEOL
690 1.1 cgd td->c_cc[VEOL] = s[C_EOL];
691 1.1 cgd # endif /* VEOL */
692 1.1 cgd # ifdef VEOL2
693 1.1 cgd td->c_cc[VEOL2] = s[C_EOL2];
694 1.1 cgd # endif /* VEOL2 */
695 1.1 cgd # ifdef VSWTCH
696 1.1 cgd td->c_cc[VSWTCH] = s[C_SWTCH];
697 1.1 cgd # endif /* VSWTCH */
698 1.1 cgd # ifdef VDSWTCH
699 1.1 cgd td->c_cc[VDSWTCH] = s[C_DSWTCH];
700 1.1 cgd # endif /* VDSWTCH */
701 1.1 cgd # ifdef VERASE2
702 1.1 cgd td->c_cc[VERASE2] = s[C_ERASE2];
703 1.1 cgd # endif /* VERASE2 */
704 1.1 cgd # ifdef VSTART
705 1.1 cgd td->c_cc[VSTART] = s[C_START];
706 1.1 cgd # endif /* VSTART */
707 1.1 cgd # ifdef VSTOP
708 1.1 cgd td->c_cc[VSTOP] = s[C_STOP];
709 1.1 cgd # endif /* VSTOP */
710 1.1 cgd # ifdef VWERASE
711 1.1 cgd td->c_cc[VWERASE] = s[C_WERASE];
712 1.1 cgd # endif /* VWERASE */
713 1.1 cgd # ifdef VSUSP
714 1.1 cgd td->c_cc[VSUSP] = s[C_SUSP];
715 1.1 cgd # endif /* VSUSP */
716 1.1 cgd # ifdef VDSUSP
717 1.1 cgd td->c_cc[VDSUSP] = s[C_DSUSP];
718 1.1 cgd # endif /* VDSUSP */
719 1.1 cgd # ifdef VREPRINT
720 1.1 cgd td->c_cc[VREPRINT] = s[C_REPRINT];
721 1.1 cgd # endif /* VREPRINT */
722 1.1 cgd # ifdef VDISCARD
723 1.1 cgd td->c_cc[VDISCARD] = s[C_DISCARD];
724 1.1 cgd # endif /* VDISCARD */
725 1.1 cgd # ifdef VLNEXT
726 1.1 cgd td->c_cc[VLNEXT] = s[C_LNEXT];
727 1.1 cgd # endif /* VLNEXT */
728 1.1 cgd # ifdef VSTATUS
729 1.1 cgd td->c_cc[VSTATUS] = s[C_STATUS];
730 1.1 cgd # endif /* VSTATUS */
731 1.1 cgd # ifdef VPAGE
732 1.1 cgd td->c_cc[VPAGE] = s[C_PAGE];
733 1.1 cgd # endif /* VPAGE */
734 1.1 cgd # ifdef VPGOFF
735 1.1 cgd td->c_cc[VPGOFF] = s[C_PGOFF];
736 1.1 cgd # endif /* VPGOFF */
737 1.1 cgd # ifdef VKILL2
738 1.1 cgd td->c_cc[VKILL2] = s[C_KILL2];
739 1.1 cgd # endif /* VKILL2 */
740 1.1 cgd # ifdef VMIN
741 1.1 cgd td->c_cc[VMIN] = s[C_MIN];
742 1.1 cgd # endif /* VMIN */
743 1.1 cgd # ifdef VTIME
744 1.1 cgd td->c_cc[VTIME] = s[C_TIME];
745 1.1 cgd # endif /* VTIME */
746 1.1 cgd } /* tty__setchar */
747 1.1 cgd
748 1.1 cgd
749 1.1 cgd /* tty_bind_char():
750 1.1 cgd * Rebind the editline functions
751 1.1 cgd */
752 1.1 cgd protected void
753 1.1 cgd tty_bind_char(el, force)
754 1.1 cgd EditLine *el;
755 1.1 cgd int force;
756 1.1 cgd {
757 1.1 cgd unsigned char *t_n = el->el_tty.t_c[ED_IO];
758 1.1 cgd unsigned char *t_o = el->el_tty.t_ed.c_cc;
759 1.1 cgd char new[2], old[2];
760 1.1 cgd ttymap_t *tp;
761 1.1 cgd el_action_t *dmap, *dalt, *map, *alt;
762 1.1 cgd new[1] = old[1] = '\0';
763 1.1 cgd
764 1.1 cgd
765 1.1 cgd map = el->el_map.key;
766 1.1 cgd alt = el->el_map.alt;
767 1.1 cgd if (el->el_map.type == MAP_VI) {
768 1.1 cgd dmap = el->el_map.vii;
769 1.1 cgd dalt = el->el_map.vic;
770 1.1 cgd }
771 1.1 cgd else {
772 1.1 cgd dmap = el->el_map.emacs;
773 1.1 cgd dalt = NULL;
774 1.1 cgd }
775 1.1 cgd
776 1.1 cgd for (tp = tty_map; tp->nch != -1; tp++) {
777 1.1 cgd new[0] = t_n[tp->nch];
778 1.1 cgd old[0] = t_o[tp->och];
779 1.1 cgd if (new[0] == old[0] && !force)
780 1.1 cgd continue;
781 1.1 cgd /* Put the old default binding back, and set the new binding */
782 1.1 cgd key_clear(el, map, old);
783 1.1 cgd map[old[0]] = dmap[old[0]];
784 1.1 cgd key_clear(el, map, new);
785 1.1 cgd /* MAP_VI == 1, MAP_EMACS == 0... */
786 1.1 cgd map[new[0]] = tp->bind[el->el_map.type];
787 1.1 cgd if (dalt) {
788 1.1 cgd key_clear(el, alt, old);
789 1.1 cgd alt[old[0]] = dalt[old[0]];
790 1.1 cgd key_clear(el, alt, new);
791 1.1 cgd alt[new[0]] = tp->bind[el->el_map.type+1];
792 1.1 cgd }
793 1.1 cgd }
794 1.1 cgd }
795 1.1 cgd
796 1.1 cgd /* tty_rawmode():
797 1.1 cgd * Set terminal into 1 character at a time mode.
798 1.1 cgd */
799 1.1 cgd protected int
800 1.1 cgd tty_rawmode(el)
801 1.1 cgd EditLine *el;
802 1.1 cgd {
803 1.1 cgd if (el->el_tty.t_mode == ED_IO)
804 1.1 cgd return (0);
805 1.1 cgd
806 1.1 cgd if (tty_getty(el, &el->el_tty.t_ts) == -1) {
807 1.1 cgd #ifdef DEBUG_TTY
808 1.1 cgd (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", strerror(errno));
809 1.1 cgd #endif /* DEBUG_TTY */
810 1.1 cgd return(-1);
811 1.1 cgd }
812 1.1 cgd
813 1.1 cgd /*
814 1.1 cgd * We always keep up with the eight bit setting and the speed of the
815 1.1 cgd * tty. But only we only believe changes that are made to cooked mode!
816 1.1 cgd */
817 1.1 cgd el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
818 1.1 cgd el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
819 1.1 cgd
820 1.1 cgd if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
821 1.1 cgd tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
822 1.1 cgd (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
823 1.1 cgd (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
824 1.1 cgd (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
825 1.1 cgd (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
826 1.1 cgd }
827 1.1 cgd
828 1.1 cgd if (tty__cooked_mode(&el->el_tty.t_ts)) {
829 1.1 cgd if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
830 1.1 cgd el->el_tty.t_ex.c_cflag = el->el_tty.t_ts.c_cflag;
831 1.1 cgd el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask;
832 1.1 cgd el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask;
833 1.1 cgd
834 1.1 cgd el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag;
835 1.1 cgd el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask;
836 1.1 cgd el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask;
837 1.1 cgd }
838 1.1 cgd
839 1.1 cgd if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
840 1.1 cgd (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
841 1.1 cgd el->el_tty.t_ex.c_lflag = el->el_tty.t_ts.c_lflag;
842 1.1 cgd el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask;
843 1.1 cgd el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask;
844 1.1 cgd
845 1.1 cgd el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag;
846 1.1 cgd el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask;
847 1.1 cgd el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask;
848 1.1 cgd }
849 1.1 cgd
850 1.1 cgd if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
851 1.1 cgd (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
852 1.1 cgd el->el_tty.t_ex.c_iflag = el->el_tty.t_ts.c_iflag;
853 1.1 cgd el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask;
854 1.1 cgd el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask;
855 1.1 cgd
856 1.1 cgd el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag;
857 1.1 cgd el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask;
858 1.1 cgd el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask;
859 1.1 cgd }
860 1.1 cgd
861 1.1 cgd if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
862 1.1 cgd (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
863 1.1 cgd el->el_tty.t_ex.c_oflag = el->el_tty.t_ts.c_oflag;
864 1.1 cgd el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask;
865 1.1 cgd el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask;
866 1.1 cgd
867 1.1 cgd el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag;
868 1.1 cgd el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask;
869 1.1 cgd el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask;
870 1.1 cgd }
871 1.1 cgd
872 1.1 cgd if (tty__gettabs(&el->el_tty.t_ex) == 0)
873 1.1 cgd el->el_tty.t_tabs = 0;
874 1.1 cgd else
875 1.1 cgd el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
876 1.1 cgd
877 1.1 cgd {
878 1.1 cgd int i;
879 1.1 cgd
880 1.1 cgd tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
881 1.1 cgd /*
882 1.1 cgd * Check if the user made any changes.
883 1.1 cgd * If he did, then propagate the changes to the
884 1.1 cgd * edit and execute data structures.
885 1.1 cgd */
886 1.1 cgd for (i = 0; i < C_NCC; i++)
887 1.1 cgd if (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])
888 1.1 cgd break;
889 1.1 cgd
890 1.1 cgd if (i != C_NCC) {
891 1.1 cgd /*
892 1.1 cgd * Propagate changes only to the unprotected chars
893 1.1 cgd * that have been modified just now.
894 1.1 cgd */
895 1.1 cgd for (i = 0; i < C_NCC; i++) {
896 1.1 cgd if (!((el->el_tty.t_t[ED_IO][M_CHAR].t_setmask & C_SH(i)))
897 1.1 cgd && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
898 1.1 cgd el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
899 1.1 cgd if (el->el_tty.t_t[ED_IO][M_CHAR].t_clrmask & C_SH(i))
900 1.1 cgd el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
901 1.1 cgd }
902 1.1 cgd tty_bind_char(el, 0);
903 1.1 cgd tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
904 1.1 cgd
905 1.1 cgd for (i = 0; i < C_NCC; i++) {
906 1.1 cgd if (!((el->el_tty.t_t[EX_IO][M_CHAR].t_setmask & C_SH(i)))
907 1.1 cgd && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
908 1.1 cgd el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
909 1.1 cgd if (el->el_tty.t_t[EX_IO][M_CHAR].t_clrmask & C_SH(i))
910 1.1 cgd el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
911 1.1 cgd }
912 1.1 cgd tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
913 1.1 cgd }
914 1.1 cgd
915 1.1 cgd }
916 1.1 cgd }
917 1.1 cgd
918 1.1 cgd if (tty_setty(el, &el->el_tty.t_ed) == -1) {
919 1.1 cgd #ifdef DEBUG_TTY
920 1.1 cgd (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
921 1.1 cgd strerror(errno));
922 1.1 cgd #endif /* DEBUG_TTY */
923 1.1 cgd return -1;
924 1.1 cgd }
925 1.1 cgd el->el_tty.t_mode = ED_IO;
926 1.1 cgd return (0);
927 1.1 cgd } /* end tty_rawmode */
928 1.1 cgd
929 1.1 cgd
930 1.1 cgd /* tty_cookedmode():
931 1.1 cgd * Set the tty back to normal mode
932 1.1 cgd */
933 1.1 cgd protected int
934 1.1 cgd tty_cookedmode(el)
935 1.1 cgd EditLine *el;
936 1.1 cgd { /* set tty in normal setup */
937 1.1 cgd if (el->el_tty.t_mode == EX_IO)
938 1.1 cgd return (0);
939 1.1 cgd
940 1.1 cgd if (tty_setty(el, &el->el_tty.t_ex) == -1) {
941 1.1 cgd #ifdef DEBUG_TTY
942 1.1 cgd (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n",
943 1.1 cgd strerror(errno));
944 1.1 cgd #endif /* DEBUG_TTY */
945 1.1 cgd return -1;
946 1.1 cgd }
947 1.1 cgd el->el_tty.t_mode = EX_IO;
948 1.1 cgd return (0);
949 1.1 cgd } /* end tty_cookedmode */
950 1.1 cgd
951 1.1 cgd
952 1.1 cgd /* tty_quotemode():
953 1.1 cgd * Turn on quote mode
954 1.1 cgd */
955 1.1 cgd protected int
956 1.1 cgd tty_quotemode(el)
957 1.1 cgd EditLine *el;
958 1.1 cgd {
959 1.1 cgd if (el->el_tty.t_mode == QU_IO)
960 1.1 cgd return 0;
961 1.1 cgd
962 1.1 cgd el->el_tty.t_qu = el->el_tty.t_ed;
963 1.1 cgd
964 1.1 cgd el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][M_INP].t_clrmask;
965 1.1 cgd el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][M_INP].t_setmask;
966 1.1 cgd
967 1.1 cgd el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][M_OUT].t_clrmask;
968 1.1 cgd el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][M_OUT].t_setmask;
969 1.1 cgd
970 1.1 cgd el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][M_CTL].t_clrmask;
971 1.1 cgd el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][M_CTL].t_setmask;
972 1.1 cgd
973 1.1 cgd el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][M_LIN].t_clrmask;
974 1.1 cgd el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][M_LIN].t_setmask;
975 1.1 cgd
976 1.1 cgd if (tty_setty(el, &el->el_tty.t_qu) == -1) {
977 1.1 cgd #ifdef DEBUG_TTY
978 1.1 cgd (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
979 1.1 cgd strerror(errno));
980 1.1 cgd #endif /* DEBUG_TTY */
981 1.1 cgd return -1;
982 1.1 cgd }
983 1.1 cgd el->el_tty.t_mode = QU_IO;
984 1.1 cgd return 0;
985 1.1 cgd } /* end tty_quotemode */
986 1.1 cgd
987 1.1 cgd
988 1.1 cgd /* tty_noquotemode():
989 1.1 cgd * Turn off quote mode
990 1.1 cgd */
991 1.1 cgd protected int
992 1.1 cgd tty_noquotemode(el)
993 1.1 cgd EditLine *el;
994 1.1 cgd {
995 1.1 cgd if (el->el_tty.t_mode != QU_IO)
996 1.1 cgd return 0;
997 1.1 cgd if (tty_setty(el, &el->el_tty.t_ed) == -1) {
998 1.1 cgd #ifdef DEBUG_TTY
999 1.1 cgd (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
1000 1.1 cgd strerror(errno));
1001 1.1 cgd #endif /* DEBUG_TTY */
1002 1.1 cgd return -1;
1003 1.1 cgd }
1004 1.1 cgd el->el_tty.t_mode = ED_IO;
1005 1.1 cgd return 0;
1006 1.1 cgd }
1007 1.1 cgd
1008 1.1 cgd /* tty_stty():
1009 1.1 cgd * Stty builtin
1010 1.1 cgd */
1011 1.1 cgd protected int
1012 1.1 cgd /*ARGSUSED*/
1013 1.1 cgd tty_stty(el, argc, argv)
1014 1.1 cgd EditLine *el;
1015 1.1 cgd int argc;
1016 1.1 cgd char **argv;
1017 1.1 cgd {
1018 1.1 cgd ttymodes_t *m;
1019 1.1 cgd char x, *d;
1020 1.1 cgd int aflag = 0;
1021 1.1 cgd char *s;
1022 1.1 cgd char *name;
1023 1.1 cgd int z = EX_IO;
1024 1.1 cgd
1025 1.1 cgd if (argv == NULL)
1026 1.1 cgd return -1;
1027 1.1 cgd name = *argv++;
1028 1.1 cgd
1029 1.1 cgd while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
1030 1.1 cgd switch (argv[0][1]) {
1031 1.1 cgd case 'a':
1032 1.1 cgd aflag++;
1033 1.1 cgd argv++;
1034 1.1 cgd break;
1035 1.1 cgd case 'd':
1036 1.1 cgd argv++;
1037 1.1 cgd z = ED_IO;
1038 1.1 cgd break;
1039 1.1 cgd case 'x':
1040 1.1 cgd argv++;
1041 1.1 cgd z = EX_IO;
1042 1.1 cgd break;
1043 1.1 cgd case 'q':
1044 1.1 cgd argv++;
1045 1.1 cgd z = QU_IO;
1046 1.1 cgd break;
1047 1.1 cgd default:
1048 1.1 cgd (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n",
1049 1.1 cgd name, argv[0][1]);
1050 1.1 cgd return -1;
1051 1.1 cgd }
1052 1.1 cgd
1053 1.1 cgd if (!argv || !*argv) {
1054 1.1 cgd int i = -1;
1055 1.1 cgd int len = 0, st = 0, cu;
1056 1.1 cgd for (m = ttymodes; m->m_name; m++) {
1057 1.1 cgd if (m->m_type != i) {
1058 1.1 cgd (void) fprintf(el->el_outfile, "%s%s", i != -1 ? "\n" : "",
1059 1.1 cgd el->el_tty.t_t[z][m->m_type].t_name);
1060 1.1 cgd i = m->m_type;
1061 1.1 cgd st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name);
1062 1.1 cgd }
1063 1.1 cgd
1064 1.1 cgd x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0';
1065 1.1 cgd x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '-' : x;
1066 1.1 cgd
1067 1.1 cgd if (x != '\0' || aflag) {
1068 1.1 cgd
1069 1.1 cgd cu = strlen(m->m_name) + (x != '\0') + 1;
1070 1.1 cgd
1071 1.1 cgd if (len + cu >= el->el_term.t_size.h) {
1072 1.1 cgd (void) fprintf(el->el_outfile, "\n%*s", st, "");
1073 1.1 cgd len = st + cu;
1074 1.1 cgd }
1075 1.1 cgd else
1076 1.1 cgd len += cu;
1077 1.1 cgd
1078 1.1 cgd if (x != '\0')
1079 1.1 cgd (void) fprintf(el->el_outfile, "%c%s ", x, m->m_name);
1080 1.1 cgd else
1081 1.1 cgd (void) fprintf(el->el_outfile, "%s ", m->m_name);
1082 1.1 cgd }
1083 1.1 cgd }
1084 1.1 cgd (void) fprintf(el->el_outfile, "\n");
1085 1.1 cgd return 0;
1086 1.1 cgd }
1087 1.1 cgd
1088 1.1 cgd while (argv && (s = *argv++)) {
1089 1.1 cgd switch (*s) {
1090 1.1 cgd case '+':
1091 1.1 cgd case '-':
1092 1.1 cgd x = *s++;
1093 1.1 cgd break;
1094 1.1 cgd default:
1095 1.1 cgd x = '\0';
1096 1.1 cgd break;
1097 1.1 cgd }
1098 1.1 cgd d = s;
1099 1.1 cgd for (m = ttymodes; m->m_name; m++)
1100 1.1 cgd if (strcmp(m->m_name, d) == 0)
1101 1.1 cgd break;
1102 1.1 cgd
1103 1.1 cgd if (!m->m_name) {
1104 1.1 cgd (void) fprintf(el->el_errfile, "%s: Invalid argument `%s'.\n",
1105 1.1 cgd name, d);
1106 1.1 cgd return -1;
1107 1.1 cgd }
1108 1.1 cgd
1109 1.1 cgd switch (x) {
1110 1.1 cgd case '+':
1111 1.1 cgd el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
1112 1.1 cgd el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1113 1.1 cgd break;
1114 1.1 cgd case '-':
1115 1.1 cgd el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1116 1.1 cgd el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
1117 1.1 cgd break;
1118 1.1 cgd default:
1119 1.1 cgd el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1120 1.1 cgd el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1121 1.1 cgd break;
1122 1.1 cgd }
1123 1.1 cgd }
1124 1.1 cgd return 0;
1125 1.1 cgd } /* end tty_stty */
1126 1.1 cgd
1127 1.1 cgd
1128 1.1 cgd #ifdef notyet
1129 1.1 cgd /* tty_printchar():
1130 1.1 cgd * DEbugging routine to print the tty characters
1131 1.1 cgd */
1132 1.1 cgd private void
1133 1.1 cgd tty_printchar(el, s)
1134 1.1 cgd EditLine *el;
1135 1.1 cgd unsigned char *s;
1136 1.1 cgd {
1137 1.1 cgd ttyperm_t *m;
1138 1.1 cgd int i;
1139 1.1 cgd
1140 1.1 cgd for (i = 0; i < C_NCC; i++) {
1141 1.1 cgd for (m = el->el_tty.t_t; m->m_name; m++)
1142 1.1 cgd if (m->m_type == M_CHAR && C_SH(i) == m->m_value)
1143 1.1 cgd break;
1144 1.1 cgd if (m->m_name)
1145 1.1 cgd (void) fprintf(el->el_errfile, "%s ^%c ", m->m_name, s[i] + 'A'-1);
1146 1.1 cgd if (i % 5 == 0)
1147 1.1 cgd (void) fprintf(el->el_errfile, "\n");
1148 1.1 cgd }
1149 1.1 cgd (void) fprintf(el->el_errfile, "\n");
1150 1.1 cgd }
1151 1.1 cgd #endif /* notyet */
1152