tty.c revision 1.9 1 1.9 christos /* $NetBSD: tty.c,v 1.9 1998/09/27 18:04:12 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.9 christos __RCSID("$NetBSD: tty.c,v 1.9 1998/09/27 18:04:12 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.8 christos { "ignbrk", IGNBRK, MD_INP },
165 1.1 cgd # endif /* IGNBRK */
166 1.1 cgd # ifdef BRKINT
167 1.8 christos { "brkint", BRKINT, MD_INP },
168 1.1 cgd # endif /* BRKINT */
169 1.1 cgd # ifdef IGNPAR
170 1.8 christos { "ignpar", IGNPAR, MD_INP },
171 1.1 cgd # endif /* IGNPAR */
172 1.1 cgd # ifdef PARMRK
173 1.8 christos { "parmrk", PARMRK, MD_INP },
174 1.1 cgd # endif /* PARMRK */
175 1.1 cgd # ifdef INPCK
176 1.8 christos { "inpck", INPCK, MD_INP },
177 1.1 cgd # endif /* INPCK */
178 1.1 cgd # ifdef ISTRIP
179 1.8 christos { "istrip", ISTRIP, MD_INP },
180 1.1 cgd # endif /* ISTRIP */
181 1.1 cgd # ifdef INLCR
182 1.8 christos { "inlcr", INLCR, MD_INP },
183 1.1 cgd # endif /* INLCR */
184 1.1 cgd # ifdef IGNCR
185 1.8 christos { "igncr", IGNCR, MD_INP },
186 1.1 cgd # endif /* IGNCR */
187 1.1 cgd # ifdef ICRNL
188 1.8 christos { "icrnl", ICRNL, MD_INP },
189 1.1 cgd # endif /* ICRNL */
190 1.1 cgd # ifdef IUCLC
191 1.8 christos { "iuclc", IUCLC, MD_INP },
192 1.1 cgd # endif /* IUCLC */
193 1.1 cgd # ifdef IXON
194 1.8 christos { "ixon", IXON, MD_INP },
195 1.1 cgd # endif /* IXON */
196 1.1 cgd # ifdef IXANY
197 1.8 christos { "ixany", IXANY, MD_INP },
198 1.1 cgd # endif /* IXANY */
199 1.1 cgd # ifdef IXOFF
200 1.8 christos { "ixoff", IXOFF, MD_INP },
201 1.1 cgd # endif /* IXOFF */
202 1.1 cgd # ifdef IMAXBEL
203 1.8 christos { "imaxbel",IMAXBEL,MD_INP },
204 1.1 cgd # endif /* IMAXBEL */
205 1.1 cgd
206 1.1 cgd # ifdef OPOST
207 1.8 christos { "opost", OPOST, MD_OUT },
208 1.1 cgd # endif /* OPOST */
209 1.1 cgd # ifdef OLCUC
210 1.8 christos { "olcuc", OLCUC, MD_OUT },
211 1.1 cgd # endif /* OLCUC */
212 1.1 cgd # ifdef ONLCR
213 1.8 christos { "onlcr", ONLCR, MD_OUT },
214 1.1 cgd # endif /* ONLCR */
215 1.1 cgd # ifdef OCRNL
216 1.8 christos { "ocrnl", OCRNL, MD_OUT },
217 1.1 cgd # endif /* OCRNL */
218 1.1 cgd # ifdef ONOCR
219 1.8 christos { "onocr", ONOCR, MD_OUT },
220 1.1 cgd # endif /* ONOCR */
221 1.1 cgd # ifdef ONOEOT
222 1.8 christos { "onoeot", ONOEOT, MD_OUT },
223 1.1 cgd # endif /* ONOEOT */
224 1.1 cgd # ifdef ONLRET
225 1.8 christos { "onlret", ONLRET, MD_OUT },
226 1.1 cgd # endif /* ONLRET */
227 1.1 cgd # ifdef OFILL
228 1.8 christos { "ofill", OFILL, MD_OUT },
229 1.1 cgd # endif /* OFILL */
230 1.1 cgd # ifdef OFDEL
231 1.8 christos { "ofdel", OFDEL, MD_OUT },
232 1.1 cgd # endif /* OFDEL */
233 1.1 cgd # ifdef NLDLY
234 1.8 christos { "nldly", NLDLY, MD_OUT },
235 1.1 cgd # endif /* NLDLY */
236 1.1 cgd # ifdef CRDLY
237 1.8 christos { "crdly", CRDLY, MD_OUT },
238 1.1 cgd # endif /* CRDLY */
239 1.1 cgd # ifdef TABDLY
240 1.8 christos { "tabdly", TABDLY, MD_OUT },
241 1.1 cgd # endif /* TABDLY */
242 1.1 cgd # ifdef XTABS
243 1.8 christos { "xtabs", XTABS, MD_OUT },
244 1.1 cgd # endif /* XTABS */
245 1.1 cgd # ifdef BSDLY
246 1.8 christos { "bsdly", BSDLY, MD_OUT },
247 1.1 cgd # endif /* BSDLY */
248 1.1 cgd # ifdef VTDLY
249 1.8 christos { "vtdly", VTDLY, MD_OUT },
250 1.1 cgd # endif /* VTDLY */
251 1.1 cgd # ifdef FFDLY
252 1.8 christos { "ffdly", FFDLY, MD_OUT },
253 1.1 cgd # endif /* FFDLY */
254 1.1 cgd # ifdef PAGEOUT
255 1.8 christos { "pageout",PAGEOUT,MD_OUT },
256 1.1 cgd # endif /* PAGEOUT */
257 1.1 cgd # ifdef WRAP
258 1.8 christos { "wrap", WRAP, MD_OUT },
259 1.1 cgd # endif /* WRAP */
260 1.1 cgd
261 1.1 cgd # ifdef CIGNORE
262 1.8 christos { "cignore",CIGNORE,MD_CTL },
263 1.1 cgd # endif /* CBAUD */
264 1.1 cgd # ifdef CBAUD
265 1.8 christos { "cbaud", CBAUD, MD_CTL },
266 1.1 cgd # endif /* CBAUD */
267 1.1 cgd # ifdef CSTOPB
268 1.8 christos { "cstopb", CSTOPB, MD_CTL },
269 1.1 cgd # endif /* CSTOPB */
270 1.1 cgd # ifdef CREAD
271 1.8 christos { "cread", CREAD, MD_CTL },
272 1.1 cgd # endif /* CREAD */
273 1.1 cgd # ifdef PARENB
274 1.8 christos { "parenb", PARENB, MD_CTL },
275 1.1 cgd # endif /* PARENB */
276 1.1 cgd # ifdef PARODD
277 1.8 christos { "parodd", PARODD, MD_CTL },
278 1.1 cgd # endif /* PARODD */
279 1.1 cgd # ifdef HUPCL
280 1.8 christos { "hupcl", HUPCL, MD_CTL },
281 1.1 cgd # endif /* HUPCL */
282 1.1 cgd # ifdef CLOCAL
283 1.8 christos { "clocal", CLOCAL, MD_CTL },
284 1.1 cgd # endif /* CLOCAL */
285 1.1 cgd # ifdef LOBLK
286 1.8 christos { "loblk", LOBLK, MD_CTL },
287 1.1 cgd # endif /* LOBLK */
288 1.1 cgd # ifdef CIBAUD
289 1.8 christos { "cibaud", CIBAUD, MD_CTL },
290 1.1 cgd # endif /* CIBAUD */
291 1.1 cgd # ifdef CRTSCTS
292 1.1 cgd # ifdef CCTS_OFLOW
293 1.8 christos { "ccts_oflow",CCTS_OFLOW,MD_CTL },
294 1.1 cgd # else
295 1.8 christos { "crtscts",CRTSCTS,MD_CTL },
296 1.1 cgd # endif /* CCTS_OFLOW */
297 1.1 cgd # endif /* CRTSCTS */
298 1.1 cgd # ifdef CRTS_IFLOW
299 1.8 christos { "crts_iflow",CRTS_IFLOW,MD_CTL },
300 1.1 cgd # endif /* CRTS_IFLOW */
301 1.6 scottr # ifdef CDTRCTS
302 1.8 christos { "cdtrcts",CDTRCTS,MD_CTL },
303 1.6 scottr # endif /* CDTRCTS */
304 1.1 cgd # ifdef MDMBUF
305 1.8 christos { "mdmbuf", MDMBUF, MD_CTL },
306 1.1 cgd # endif /* MDMBUF */
307 1.1 cgd # ifdef RCV1EN
308 1.8 christos { "rcv1en", RCV1EN, MD_CTL },
309 1.1 cgd # endif /* RCV1EN */
310 1.1 cgd # ifdef XMT1EN
311 1.8 christos { "xmt1en", XMT1EN, MD_CTL },
312 1.1 cgd # endif /* XMT1EN */
313 1.1 cgd
314 1.1 cgd # ifdef ISIG
315 1.8 christos { "isig", ISIG, MD_LIN },
316 1.1 cgd # endif /* ISIG */
317 1.1 cgd # ifdef ICANON
318 1.8 christos { "icanon", ICANON, MD_LIN },
319 1.1 cgd # endif /* ICANON */
320 1.1 cgd # ifdef XCASE
321 1.8 christos { "xcase", XCASE, MD_LIN },
322 1.1 cgd # endif /* XCASE */
323 1.1 cgd # ifdef ECHO
324 1.8 christos { "echo", ECHO, MD_LIN },
325 1.1 cgd # endif /* ECHO */
326 1.1 cgd # ifdef ECHOE
327 1.8 christos { "echoe", ECHOE, MD_LIN },
328 1.1 cgd # endif /* ECHOE */
329 1.1 cgd # ifdef ECHOK
330 1.8 christos { "echok", ECHOK, MD_LIN },
331 1.1 cgd # endif /* ECHOK */
332 1.1 cgd # ifdef ECHONL
333 1.8 christos { "echonl", ECHONL, MD_LIN },
334 1.1 cgd # endif /* ECHONL */
335 1.1 cgd # ifdef NOFLSH
336 1.8 christos { "noflsh", NOFLSH, MD_LIN },
337 1.1 cgd # endif /* NOFLSH */
338 1.1 cgd # ifdef TOSTOP
339 1.8 christos { "tostop", TOSTOP, MD_LIN },
340 1.1 cgd # endif /* TOSTOP */
341 1.1 cgd # ifdef ECHOCTL
342 1.8 christos { "echoctl",ECHOCTL,MD_LIN },
343 1.1 cgd # endif /* ECHOCTL */
344 1.1 cgd # ifdef ECHOPRT
345 1.8 christos { "echoprt",ECHOPRT,MD_LIN },
346 1.1 cgd # endif /* ECHOPRT */
347 1.1 cgd # ifdef ECHOKE
348 1.8 christos { "echoke", ECHOKE, MD_LIN },
349 1.1 cgd # endif /* ECHOKE */
350 1.1 cgd # ifdef DEFECHO
351 1.8 christos { "defecho",DEFECHO,MD_LIN },
352 1.1 cgd # endif /* DEFECHO */
353 1.1 cgd # ifdef FLUSHO
354 1.8 christos { "flusho", FLUSHO, MD_LIN },
355 1.1 cgd # endif /* FLUSHO */
356 1.1 cgd # ifdef PENDIN
357 1.8 christos { "pendin", PENDIN, MD_LIN },
358 1.1 cgd # endif /* PENDIN */
359 1.1 cgd # ifdef IEXTEN
360 1.8 christos { "iexten", IEXTEN, MD_LIN },
361 1.1 cgd # endif /* IEXTEN */
362 1.1 cgd # ifdef NOKERNINFO
363 1.8 christos { "nokerninfo",NOKERNINFO,MD_LIN },
364 1.1 cgd # endif /* NOKERNINFO */
365 1.1 cgd # ifdef ALTWERASE
366 1.8 christos { "altwerase",ALTWERASE,MD_LIN },
367 1.1 cgd # endif /* ALTWERASE */
368 1.1 cgd # ifdef EXTPROC
369 1.8 christos { "extproc",EXTPROC, MD_LIN },
370 1.1 cgd # endif /* EXTPROC */
371 1.1 cgd
372 1.1 cgd # if defined(VINTR)
373 1.8 christos { "intr", C_SH(C_INTR), MD_CHAR },
374 1.1 cgd # endif /* VINTR */
375 1.1 cgd # if defined(VQUIT)
376 1.8 christos { "quit", C_SH(C_QUIT), MD_CHAR },
377 1.1 cgd # endif /* VQUIT */
378 1.1 cgd # if defined(VERASE)
379 1.8 christos { "erase", C_SH(C_ERASE), MD_CHAR },
380 1.1 cgd # endif /* VERASE */
381 1.1 cgd # if defined(VKILL)
382 1.8 christos { "kill", C_SH(C_KILL), MD_CHAR },
383 1.1 cgd # endif /* VKILL */
384 1.1 cgd # if defined(VEOF)
385 1.8 christos { "eof", C_SH(C_EOF), MD_CHAR },
386 1.1 cgd # endif /* VEOF */
387 1.1 cgd # if defined(VEOL)
388 1.8 christos { "eol", C_SH(C_EOL), MD_CHAR },
389 1.1 cgd # endif /* VEOL */
390 1.1 cgd # if defined(VEOL2)
391 1.8 christos { "eol2", C_SH(C_EOL2), MD_CHAR },
392 1.1 cgd # endif /* VEOL2 */
393 1.1 cgd # if defined(VSWTCH)
394 1.8 christos { "swtch", C_SH(C_SWTCH), MD_CHAR },
395 1.1 cgd # endif /* VSWTCH */
396 1.1 cgd # if defined(VDSWTCH)
397 1.8 christos { "dswtch", C_SH(C_DSWTCH), MD_CHAR },
398 1.1 cgd # endif /* VDSWTCH */
399 1.1 cgd # if defined(VERASE2)
400 1.8 christos { "erase2", C_SH(C_ERASE2), MD_CHAR },
401 1.1 cgd # endif /* VERASE2 */
402 1.1 cgd # if defined(VSTART)
403 1.8 christos { "start", C_SH(C_START), MD_CHAR },
404 1.1 cgd # endif /* VSTART */
405 1.1 cgd # if defined(VSTOP)
406 1.8 christos { "stop", C_SH(C_STOP), MD_CHAR },
407 1.1 cgd # endif /* VSTOP */
408 1.1 cgd # if defined(VWERASE)
409 1.8 christos { "werase", C_SH(C_WERASE), MD_CHAR },
410 1.1 cgd # endif /* VWERASE */
411 1.1 cgd # if defined(VSUSP)
412 1.8 christos { "susp", C_SH(C_SUSP), MD_CHAR },
413 1.1 cgd # endif /* VSUSP */
414 1.1 cgd # if defined(VDSUSP)
415 1.8 christos { "dsusp", C_SH(C_DSUSP), MD_CHAR },
416 1.1 cgd # endif /* VDSUSP */
417 1.1 cgd # if defined(VREPRINT)
418 1.8 christos { "reprint", C_SH(C_REPRINT),MD_CHAR },
419 1.1 cgd # endif /* VREPRINT */
420 1.1 cgd # if defined(VDISCARD)
421 1.8 christos { "discard", C_SH(C_DISCARD),MD_CHAR },
422 1.1 cgd # endif /* VDISCARD */
423 1.1 cgd # if defined(VLNEXT)
424 1.8 christos { "lnext", C_SH(C_LNEXT), MD_CHAR },
425 1.1 cgd # endif /* VLNEXT */
426 1.1 cgd # if defined(VSTATUS)
427 1.8 christos { "status", C_SH(C_STATUS), MD_CHAR },
428 1.1 cgd # endif /* VSTATUS */
429 1.1 cgd # if defined(VPAGE)
430 1.8 christos { "page", C_SH(C_PAGE), MD_CHAR },
431 1.1 cgd # endif /* VPAGE */
432 1.1 cgd # if defined(VPGOFF)
433 1.8 christos { "pgoff", C_SH(C_PGOFF), MD_CHAR },
434 1.1 cgd # endif /* VPGOFF */
435 1.1 cgd # if defined(VKILL2)
436 1.8 christos { "kill2", C_SH(C_KILL2), MD_CHAR },
437 1.1 cgd # endif /* VKILL2 */
438 1.1 cgd # if defined(VBRK)
439 1.8 christos { "brk", C_SH(C_BRK), MD_CHAR },
440 1.1 cgd # endif /* VBRK */
441 1.1 cgd # if defined(VMIN)
442 1.8 christos { "min", C_SH(C_MIN), MD_CHAR },
443 1.1 cgd # endif /* VMIN */
444 1.1 cgd # if defined(VTIME)
445 1.8 christos { "time", C_SH(C_TIME), MD_CHAR },
446 1.1 cgd # endif /* VTIME */
447 1.1 cgd { NULL, 0, -1 },
448 1.1 cgd };
449 1.1 cgd
450 1.1 cgd
451 1.1 cgd
452 1.1 cgd #define tty_getty(el, td) tcgetattr((el)->el_infd, (td))
453 1.1 cgd #define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td))
454 1.1 cgd
455 1.1 cgd #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
456 1.1 cgd #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
457 1.1 cgd #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
458 1.1 cgd
459 1.1 cgd private void tty__getchar __P((struct termios *, unsigned char *));
460 1.1 cgd private void tty__setchar __P((struct termios *, unsigned char *));
461 1.1 cgd private speed_t tty__getspeed __P((struct termios *));
462 1.1 cgd private int tty_setup __P((EditLine *));
463 1.1 cgd
464 1.1 cgd #define t_qu t_ts
465 1.1 cgd
466 1.1 cgd
467 1.1 cgd /* tty_setup():
468 1.1 cgd * Get the tty parameters and initialize the editing state
469 1.1 cgd */
470 1.1 cgd private int
471 1.1 cgd tty_setup(el)
472 1.1 cgd EditLine *el;
473 1.1 cgd {
474 1.1 cgd int rst = 1;
475 1.1 cgd if (tty_getty(el, &el->el_tty.t_ed) == -1) {
476 1.1 cgd #ifdef DEBUG_TTY
477 1.1 cgd (void) fprintf(el->el_errfile,
478 1.1 cgd "tty_setup: tty_getty: %s\n", strerror(errno));
479 1.1 cgd #endif /* DEBUG_TTY */
480 1.1 cgd return(-1);
481 1.1 cgd }
482 1.1 cgd el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
483 1.1 cgd
484 1.1 cgd el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
485 1.1 cgd el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
486 1.1 cgd el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
487 1.1 cgd
488 1.8 christos el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
489 1.8 christos el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
490 1.1 cgd
491 1.8 christos el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
492 1.8 christos el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
493 1.1 cgd
494 1.8 christos el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
495 1.8 christos el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
496 1.1 cgd
497 1.8 christos el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
498 1.8 christos el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
499 1.1 cgd
500 1.1 cgd /*
501 1.1 cgd * Reset the tty chars to reasonable defaults
502 1.1 cgd * If they are disabled, then enable them.
503 1.1 cgd */
504 1.1 cgd if (rst) {
505 1.1 cgd if (tty__cooked_mode(&el->el_tty.t_ts)) {
506 1.1 cgd tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
507 1.1 cgd /*
508 1.1 cgd * Don't affect CMIN and CTIME for the editor mode
509 1.1 cgd */
510 1.1 cgd for (rst = 0; rst < C_NCC - 2; rst++)
511 1.1 cgd if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable &&
512 1.1 cgd el->el_tty.t_c[ED_IO][rst] != el->el_tty.t_vdisable)
513 1.1 cgd el->el_tty.t_c[ED_IO][rst] = el->el_tty.t_c[TS_IO][rst];
514 1.1 cgd for (rst = 0; rst < C_NCC; rst++)
515 1.5 christos if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable)
516 1.1 cgd el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst];
517 1.1 cgd }
518 1.1 cgd tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
519 1.1 cgd if (tty_setty(el, &el->el_tty.t_ex) == -1) {
520 1.1 cgd #ifdef DEBUG_TTY
521 1.1 cgd (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n",
522 1.1 cgd strerror(errno));
523 1.1 cgd #endif /* DEBUG_TTY */
524 1.1 cgd return(-1);
525 1.1 cgd }
526 1.1 cgd }
527 1.1 cgd else
528 1.1 cgd tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
529 1.1 cgd
530 1.8 christos el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
531 1.8 christos el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
532 1.1 cgd
533 1.8 christos el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
534 1.8 christos el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
535 1.1 cgd
536 1.8 christos el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
537 1.8 christos el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
538 1.1 cgd
539 1.8 christos el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
540 1.8 christos el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
541 1.1 cgd
542 1.1 cgd tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
543 1.9 christos tty_bind_char(el, 1);
544 1.1 cgd return 0;
545 1.1 cgd }
546 1.1 cgd
547 1.1 cgd protected int
548 1.1 cgd tty_init(el)
549 1.1 cgd EditLine *el;
550 1.1 cgd {
551 1.1 cgd el->el_tty.t_mode = EX_IO;
552 1.1 cgd el->el_tty.t_vdisable = _POSIX_VDISABLE;
553 1.1 cgd (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
554 1.1 cgd (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
555 1.1 cgd return tty_setup(el);
556 1.1 cgd } /* end tty_init */
557 1.1 cgd
558 1.1 cgd
559 1.1 cgd /* tty_end():
560 1.1 cgd * Restore the tty to its original settings
561 1.1 cgd */
562 1.1 cgd protected void
563 1.1 cgd /*ARGSUSED*/
564 1.1 cgd tty_end(el)
565 1.1 cgd EditLine *el;
566 1.1 cgd {
567 1.1 cgd /* XXX: Maybe reset to an initial state? */
568 1.1 cgd }
569 1.1 cgd
570 1.1 cgd
571 1.1 cgd /* tty__getspeed():
572 1.1 cgd * Get the tty speed
573 1.1 cgd */
574 1.1 cgd private speed_t
575 1.1 cgd tty__getspeed(td)
576 1.1 cgd struct termios *td;
577 1.1 cgd {
578 1.1 cgd speed_t spd;
579 1.1 cgd
580 1.1 cgd if ((spd = cfgetispeed(td)) == 0)
581 1.1 cgd spd = cfgetospeed(td);
582 1.1 cgd return spd;
583 1.1 cgd } /* end tty__getspeed */
584 1.1 cgd
585 1.1 cgd
586 1.1 cgd /* tty__getchar():
587 1.1 cgd * Get the tty characters
588 1.1 cgd */
589 1.1 cgd private void
590 1.1 cgd tty__getchar(td, s)
591 1.1 cgd struct termios *td;
592 1.1 cgd unsigned char *s;
593 1.1 cgd {
594 1.1 cgd # ifdef VINTR
595 1.1 cgd s[C_INTR] = td->c_cc[VINTR];
596 1.1 cgd # endif /* VINTR */
597 1.1 cgd # ifdef VQUIT
598 1.1 cgd s[C_QUIT] = td->c_cc[VQUIT];
599 1.1 cgd # endif /* VQUIT */
600 1.1 cgd # ifdef VERASE
601 1.1 cgd s[C_ERASE] = td->c_cc[VERASE];
602 1.1 cgd # endif /* VERASE */
603 1.1 cgd # ifdef VKILL
604 1.1 cgd s[C_KILL] = td->c_cc[VKILL];
605 1.1 cgd # endif /* VKILL */
606 1.1 cgd # ifdef VEOF
607 1.1 cgd s[C_EOF] = td->c_cc[VEOF];
608 1.1 cgd # endif /* VEOF */
609 1.1 cgd # ifdef VEOL
610 1.1 cgd s[C_EOL] = td->c_cc[VEOL];
611 1.1 cgd # endif /* VEOL */
612 1.1 cgd # ifdef VEOL2
613 1.1 cgd s[C_EOL2] = td->c_cc[VEOL2];
614 1.1 cgd # endif /* VEOL2 */
615 1.1 cgd # ifdef VSWTCH
616 1.1 cgd s[C_SWTCH] = td->c_cc[VSWTCH];
617 1.1 cgd # endif /* VSWTCH */
618 1.1 cgd # ifdef VDSWTCH
619 1.1 cgd s[C_DSWTCH] = td->c_cc[VDSWTCH];
620 1.1 cgd # endif /* VDSWTCH */
621 1.1 cgd # ifdef VERASE2
622 1.1 cgd s[C_ERASE2] = td->c_cc[VERASE2];
623 1.1 cgd # endif /* VERASE2 */
624 1.1 cgd # ifdef VSTART
625 1.1 cgd s[C_START] = td->c_cc[VSTART];
626 1.1 cgd # endif /* VSTART */
627 1.1 cgd # ifdef VSTOP
628 1.1 cgd s[C_STOP] = td->c_cc[VSTOP];
629 1.1 cgd # endif /* VSTOP */
630 1.1 cgd # ifdef VWERASE
631 1.1 cgd s[C_WERASE] = td->c_cc[VWERASE];
632 1.1 cgd # endif /* VWERASE */
633 1.1 cgd # ifdef VSUSP
634 1.1 cgd s[C_SUSP] = td->c_cc[VSUSP];
635 1.1 cgd # endif /* VSUSP */
636 1.1 cgd # ifdef VDSUSP
637 1.1 cgd s[C_DSUSP] = td->c_cc[VDSUSP];
638 1.1 cgd # endif /* VDSUSP */
639 1.1 cgd # ifdef VREPRINT
640 1.1 cgd s[C_REPRINT]= td->c_cc[VREPRINT];
641 1.1 cgd # endif /* VREPRINT */
642 1.1 cgd # ifdef VDISCARD
643 1.1 cgd s[C_DISCARD]= td->c_cc[VDISCARD];
644 1.1 cgd # endif /* VDISCARD */
645 1.1 cgd # ifdef VLNEXT
646 1.1 cgd s[C_LNEXT] = td->c_cc[VLNEXT];
647 1.1 cgd # endif /* VLNEXT */
648 1.1 cgd # ifdef VSTATUS
649 1.1 cgd s[C_STATUS] = td->c_cc[VSTATUS];
650 1.1 cgd # endif /* VSTATUS */
651 1.1 cgd # ifdef VPAGE
652 1.1 cgd s[C_PAGE] = td->c_cc[VPAGE];
653 1.1 cgd # endif /* VPAGE */
654 1.1 cgd # ifdef VPGOFF
655 1.1 cgd s[C_PGOFF] = td->c_cc[VPGOFF];
656 1.1 cgd # endif /* VPGOFF */
657 1.1 cgd # ifdef VKILL2
658 1.1 cgd s[C_KILL2] = td->c_cc[VKILL2];
659 1.1 cgd # endif /* KILL2 */
660 1.1 cgd # ifdef VMIN
661 1.1 cgd s[C_MIN] = td->c_cc[VMIN];
662 1.1 cgd # endif /* VMIN */
663 1.1 cgd # ifdef VTIME
664 1.1 cgd s[C_TIME] = td->c_cc[VTIME];
665 1.1 cgd # endif /* VTIME */
666 1.1 cgd } /* tty__getchar */
667 1.1 cgd
668 1.1 cgd
669 1.1 cgd /* tty__setchar():
670 1.1 cgd * Set the tty characters
671 1.1 cgd */
672 1.1 cgd private void
673 1.1 cgd tty__setchar(td, s)
674 1.1 cgd struct termios *td;
675 1.1 cgd unsigned char *s;
676 1.1 cgd {
677 1.1 cgd # ifdef VINTR
678 1.1 cgd td->c_cc[VINTR] = s[C_INTR];
679 1.1 cgd # endif /* VINTR */
680 1.1 cgd # ifdef VQUIT
681 1.1 cgd td->c_cc[VQUIT] = s[C_QUIT];
682 1.1 cgd # endif /* VQUIT */
683 1.1 cgd # ifdef VERASE
684 1.1 cgd td->c_cc[VERASE] = s[C_ERASE];
685 1.1 cgd # endif /* VERASE */
686 1.1 cgd # ifdef VKILL
687 1.1 cgd td->c_cc[VKILL] = s[C_KILL];
688 1.1 cgd # endif /* VKILL */
689 1.1 cgd # ifdef VEOF
690 1.1 cgd td->c_cc[VEOF] = s[C_EOF];
691 1.1 cgd # endif /* VEOF */
692 1.1 cgd # ifdef VEOL
693 1.1 cgd td->c_cc[VEOL] = s[C_EOL];
694 1.1 cgd # endif /* VEOL */
695 1.1 cgd # ifdef VEOL2
696 1.1 cgd td->c_cc[VEOL2] = s[C_EOL2];
697 1.1 cgd # endif /* VEOL2 */
698 1.1 cgd # ifdef VSWTCH
699 1.1 cgd td->c_cc[VSWTCH] = s[C_SWTCH];
700 1.1 cgd # endif /* VSWTCH */
701 1.1 cgd # ifdef VDSWTCH
702 1.1 cgd td->c_cc[VDSWTCH] = s[C_DSWTCH];
703 1.1 cgd # endif /* VDSWTCH */
704 1.1 cgd # ifdef VERASE2
705 1.1 cgd td->c_cc[VERASE2] = s[C_ERASE2];
706 1.1 cgd # endif /* VERASE2 */
707 1.1 cgd # ifdef VSTART
708 1.1 cgd td->c_cc[VSTART] = s[C_START];
709 1.1 cgd # endif /* VSTART */
710 1.1 cgd # ifdef VSTOP
711 1.1 cgd td->c_cc[VSTOP] = s[C_STOP];
712 1.1 cgd # endif /* VSTOP */
713 1.1 cgd # ifdef VWERASE
714 1.1 cgd td->c_cc[VWERASE] = s[C_WERASE];
715 1.1 cgd # endif /* VWERASE */
716 1.1 cgd # ifdef VSUSP
717 1.1 cgd td->c_cc[VSUSP] = s[C_SUSP];
718 1.1 cgd # endif /* VSUSP */
719 1.1 cgd # ifdef VDSUSP
720 1.1 cgd td->c_cc[VDSUSP] = s[C_DSUSP];
721 1.1 cgd # endif /* VDSUSP */
722 1.1 cgd # ifdef VREPRINT
723 1.1 cgd td->c_cc[VREPRINT] = s[C_REPRINT];
724 1.1 cgd # endif /* VREPRINT */
725 1.1 cgd # ifdef VDISCARD
726 1.1 cgd td->c_cc[VDISCARD] = s[C_DISCARD];
727 1.1 cgd # endif /* VDISCARD */
728 1.1 cgd # ifdef VLNEXT
729 1.1 cgd td->c_cc[VLNEXT] = s[C_LNEXT];
730 1.1 cgd # endif /* VLNEXT */
731 1.1 cgd # ifdef VSTATUS
732 1.1 cgd td->c_cc[VSTATUS] = s[C_STATUS];
733 1.1 cgd # endif /* VSTATUS */
734 1.1 cgd # ifdef VPAGE
735 1.1 cgd td->c_cc[VPAGE] = s[C_PAGE];
736 1.1 cgd # endif /* VPAGE */
737 1.1 cgd # ifdef VPGOFF
738 1.1 cgd td->c_cc[VPGOFF] = s[C_PGOFF];
739 1.1 cgd # endif /* VPGOFF */
740 1.1 cgd # ifdef VKILL2
741 1.1 cgd td->c_cc[VKILL2] = s[C_KILL2];
742 1.1 cgd # endif /* VKILL2 */
743 1.1 cgd # ifdef VMIN
744 1.1 cgd td->c_cc[VMIN] = s[C_MIN];
745 1.1 cgd # endif /* VMIN */
746 1.1 cgd # ifdef VTIME
747 1.1 cgd td->c_cc[VTIME] = s[C_TIME];
748 1.1 cgd # endif /* VTIME */
749 1.1 cgd } /* tty__setchar */
750 1.1 cgd
751 1.1 cgd
752 1.1 cgd /* tty_bind_char():
753 1.1 cgd * Rebind the editline functions
754 1.1 cgd */
755 1.1 cgd protected void
756 1.1 cgd tty_bind_char(el, force)
757 1.1 cgd EditLine *el;
758 1.1 cgd int force;
759 1.1 cgd {
760 1.1 cgd unsigned char *t_n = el->el_tty.t_c[ED_IO];
761 1.1 cgd unsigned char *t_o = el->el_tty.t_ed.c_cc;
762 1.1 cgd char new[2], old[2];
763 1.1 cgd ttymap_t *tp;
764 1.1 cgd el_action_t *dmap, *dalt, *map, *alt;
765 1.1 cgd new[1] = old[1] = '\0';
766 1.1 cgd
767 1.1 cgd
768 1.1 cgd map = el->el_map.key;
769 1.1 cgd alt = el->el_map.alt;
770 1.1 cgd if (el->el_map.type == MAP_VI) {
771 1.1 cgd dmap = el->el_map.vii;
772 1.1 cgd dalt = el->el_map.vic;
773 1.1 cgd }
774 1.1 cgd else {
775 1.1 cgd dmap = el->el_map.emacs;
776 1.1 cgd dalt = NULL;
777 1.1 cgd }
778 1.1 cgd
779 1.1 cgd for (tp = tty_map; tp->nch != -1; tp++) {
780 1.1 cgd new[0] = t_n[tp->nch];
781 1.1 cgd old[0] = t_o[tp->och];
782 1.1 cgd if (new[0] == old[0] && !force)
783 1.1 cgd continue;
784 1.1 cgd /* Put the old default binding back, and set the new binding */
785 1.1 cgd key_clear(el, map, old);
786 1.7 mrg map[(int)old[0]] = dmap[(int)old[0]];
787 1.1 cgd key_clear(el, map, new);
788 1.1 cgd /* MAP_VI == 1, MAP_EMACS == 0... */
789 1.7 mrg map[(int)new[0]] = tp->bind[(int)el->el_map.type];
790 1.1 cgd if (dalt) {
791 1.1 cgd key_clear(el, alt, old);
792 1.7 mrg alt[(int)old[0]] = dalt[(int)old[0]];
793 1.1 cgd key_clear(el, alt, new);
794 1.7 mrg alt[(int)new[0]] = tp->bind[(int)el->el_map.type+1];
795 1.1 cgd }
796 1.1 cgd }
797 1.1 cgd }
798 1.1 cgd
799 1.1 cgd /* tty_rawmode():
800 1.1 cgd * Set terminal into 1 character at a time mode.
801 1.1 cgd */
802 1.1 cgd protected int
803 1.1 cgd tty_rawmode(el)
804 1.1 cgd EditLine *el;
805 1.1 cgd {
806 1.1 cgd if (el->el_tty.t_mode == ED_IO)
807 1.1 cgd return (0);
808 1.1 cgd
809 1.1 cgd if (tty_getty(el, &el->el_tty.t_ts) == -1) {
810 1.1 cgd #ifdef DEBUG_TTY
811 1.1 cgd (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", strerror(errno));
812 1.1 cgd #endif /* DEBUG_TTY */
813 1.1 cgd return(-1);
814 1.1 cgd }
815 1.1 cgd
816 1.1 cgd /*
817 1.1 cgd * We always keep up with the eight bit setting and the speed of the
818 1.1 cgd * tty. But only we only believe changes that are made to cooked mode!
819 1.1 cgd */
820 1.1 cgd el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
821 1.1 cgd el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
822 1.1 cgd
823 1.1 cgd if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
824 1.1 cgd tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
825 1.1 cgd (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
826 1.1 cgd (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
827 1.1 cgd (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
828 1.1 cgd (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
829 1.1 cgd }
830 1.1 cgd
831 1.1 cgd if (tty__cooked_mode(&el->el_tty.t_ts)) {
832 1.1 cgd if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
833 1.1 cgd el->el_tty.t_ex.c_cflag = el->el_tty.t_ts.c_cflag;
834 1.8 christos el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
835 1.8 christos el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
836 1.1 cgd
837 1.1 cgd el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag;
838 1.8 christos el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
839 1.8 christos el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
840 1.1 cgd }
841 1.1 cgd
842 1.1 cgd if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
843 1.1 cgd (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
844 1.1 cgd el->el_tty.t_ex.c_lflag = el->el_tty.t_ts.c_lflag;
845 1.8 christos el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
846 1.8 christos el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
847 1.1 cgd
848 1.1 cgd el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag;
849 1.8 christos el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
850 1.8 christos el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
851 1.1 cgd }
852 1.1 cgd
853 1.1 cgd if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
854 1.1 cgd (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
855 1.1 cgd el->el_tty.t_ex.c_iflag = el->el_tty.t_ts.c_iflag;
856 1.8 christos el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
857 1.8 christos el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
858 1.1 cgd
859 1.1 cgd el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag;
860 1.8 christos el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
861 1.8 christos el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
862 1.1 cgd }
863 1.1 cgd
864 1.1 cgd if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
865 1.1 cgd (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
866 1.1 cgd el->el_tty.t_ex.c_oflag = el->el_tty.t_ts.c_oflag;
867 1.8 christos el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
868 1.8 christos el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
869 1.1 cgd
870 1.1 cgd el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag;
871 1.8 christos el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
872 1.8 christos el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
873 1.1 cgd }
874 1.1 cgd
875 1.1 cgd if (tty__gettabs(&el->el_tty.t_ex) == 0)
876 1.1 cgd el->el_tty.t_tabs = 0;
877 1.1 cgd else
878 1.1 cgd el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
879 1.1 cgd
880 1.1 cgd {
881 1.1 cgd int i;
882 1.1 cgd
883 1.1 cgd tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
884 1.1 cgd /*
885 1.1 cgd * Check if the user made any changes.
886 1.1 cgd * If he did, then propagate the changes to the
887 1.1 cgd * edit and execute data structures.
888 1.1 cgd */
889 1.1 cgd for (i = 0; i < C_NCC; i++)
890 1.1 cgd if (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])
891 1.1 cgd break;
892 1.1 cgd
893 1.1 cgd if (i != C_NCC) {
894 1.1 cgd /*
895 1.1 cgd * Propagate changes only to the unprotected chars
896 1.1 cgd * that have been modified just now.
897 1.1 cgd */
898 1.1 cgd for (i = 0; i < C_NCC; i++) {
899 1.8 christos if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i)))
900 1.1 cgd && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
901 1.1 cgd el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
902 1.8 christos if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i))
903 1.1 cgd el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
904 1.1 cgd }
905 1.1 cgd tty_bind_char(el, 0);
906 1.1 cgd tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
907 1.1 cgd
908 1.1 cgd for (i = 0; i < C_NCC; i++) {
909 1.8 christos if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i)))
910 1.1 cgd && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
911 1.1 cgd el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
912 1.8 christos if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i))
913 1.1 cgd el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
914 1.1 cgd }
915 1.1 cgd tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
916 1.1 cgd }
917 1.1 cgd }
918 1.1 cgd }
919 1.1 cgd
920 1.1 cgd if (tty_setty(el, &el->el_tty.t_ed) == -1) {
921 1.1 cgd #ifdef DEBUG_TTY
922 1.1 cgd (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
923 1.1 cgd strerror(errno));
924 1.1 cgd #endif /* DEBUG_TTY */
925 1.1 cgd return -1;
926 1.1 cgd }
927 1.1 cgd el->el_tty.t_mode = ED_IO;
928 1.1 cgd return (0);
929 1.1 cgd } /* end tty_rawmode */
930 1.1 cgd
931 1.1 cgd
932 1.1 cgd /* tty_cookedmode():
933 1.1 cgd * Set the tty back to normal mode
934 1.1 cgd */
935 1.1 cgd protected int
936 1.1 cgd tty_cookedmode(el)
937 1.1 cgd EditLine *el;
938 1.1 cgd { /* set tty in normal setup */
939 1.1 cgd if (el->el_tty.t_mode == EX_IO)
940 1.1 cgd return (0);
941 1.1 cgd
942 1.1 cgd if (tty_setty(el, &el->el_tty.t_ex) == -1) {
943 1.1 cgd #ifdef DEBUG_TTY
944 1.1 cgd (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n",
945 1.1 cgd strerror(errno));
946 1.1 cgd #endif /* DEBUG_TTY */
947 1.1 cgd return -1;
948 1.1 cgd }
949 1.1 cgd el->el_tty.t_mode = EX_IO;
950 1.1 cgd return (0);
951 1.1 cgd } /* end tty_cookedmode */
952 1.1 cgd
953 1.1 cgd
954 1.1 cgd /* tty_quotemode():
955 1.1 cgd * Turn on quote mode
956 1.1 cgd */
957 1.1 cgd protected int
958 1.1 cgd tty_quotemode(el)
959 1.1 cgd EditLine *el;
960 1.1 cgd {
961 1.1 cgd if (el->el_tty.t_mode == QU_IO)
962 1.1 cgd return 0;
963 1.1 cgd
964 1.1 cgd el->el_tty.t_qu = el->el_tty.t_ed;
965 1.1 cgd
966 1.8 christos el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask;
967 1.8 christos el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask;
968 1.1 cgd
969 1.8 christos el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask;
970 1.8 christos el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask;
971 1.1 cgd
972 1.8 christos el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask;
973 1.8 christos el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask;
974 1.1 cgd
975 1.8 christos el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask;
976 1.8 christos el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask;
977 1.1 cgd
978 1.1 cgd if (tty_setty(el, &el->el_tty.t_qu) == -1) {
979 1.1 cgd #ifdef DEBUG_TTY
980 1.1 cgd (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
981 1.1 cgd strerror(errno));
982 1.1 cgd #endif /* DEBUG_TTY */
983 1.1 cgd return -1;
984 1.1 cgd }
985 1.1 cgd el->el_tty.t_mode = QU_IO;
986 1.1 cgd return 0;
987 1.1 cgd } /* end tty_quotemode */
988 1.1 cgd
989 1.1 cgd
990 1.1 cgd /* tty_noquotemode():
991 1.1 cgd * Turn off quote mode
992 1.1 cgd */
993 1.1 cgd protected int
994 1.1 cgd tty_noquotemode(el)
995 1.1 cgd EditLine *el;
996 1.1 cgd {
997 1.1 cgd if (el->el_tty.t_mode != QU_IO)
998 1.1 cgd return 0;
999 1.1 cgd if (tty_setty(el, &el->el_tty.t_ed) == -1) {
1000 1.1 cgd #ifdef DEBUG_TTY
1001 1.1 cgd (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
1002 1.1 cgd strerror(errno));
1003 1.1 cgd #endif /* DEBUG_TTY */
1004 1.1 cgd return -1;
1005 1.1 cgd }
1006 1.1 cgd el->el_tty.t_mode = ED_IO;
1007 1.1 cgd return 0;
1008 1.1 cgd }
1009 1.1 cgd
1010 1.1 cgd /* tty_stty():
1011 1.1 cgd * Stty builtin
1012 1.1 cgd */
1013 1.1 cgd protected int
1014 1.1 cgd /*ARGSUSED*/
1015 1.1 cgd tty_stty(el, argc, argv)
1016 1.1 cgd EditLine *el;
1017 1.1 cgd int argc;
1018 1.1 cgd char **argv;
1019 1.1 cgd {
1020 1.1 cgd ttymodes_t *m;
1021 1.1 cgd char x, *d;
1022 1.1 cgd int aflag = 0;
1023 1.1 cgd char *s;
1024 1.1 cgd char *name;
1025 1.1 cgd int z = EX_IO;
1026 1.1 cgd
1027 1.1 cgd if (argv == NULL)
1028 1.1 cgd return -1;
1029 1.1 cgd name = *argv++;
1030 1.1 cgd
1031 1.1 cgd while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
1032 1.1 cgd switch (argv[0][1]) {
1033 1.1 cgd case 'a':
1034 1.1 cgd aflag++;
1035 1.1 cgd argv++;
1036 1.1 cgd break;
1037 1.1 cgd case 'd':
1038 1.1 cgd argv++;
1039 1.1 cgd z = ED_IO;
1040 1.1 cgd break;
1041 1.1 cgd case 'x':
1042 1.1 cgd argv++;
1043 1.1 cgd z = EX_IO;
1044 1.1 cgd break;
1045 1.1 cgd case 'q':
1046 1.1 cgd argv++;
1047 1.1 cgd z = QU_IO;
1048 1.1 cgd break;
1049 1.1 cgd default:
1050 1.1 cgd (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n",
1051 1.1 cgd name, argv[0][1]);
1052 1.1 cgd return -1;
1053 1.1 cgd }
1054 1.1 cgd
1055 1.1 cgd if (!argv || !*argv) {
1056 1.1 cgd int i = -1;
1057 1.1 cgd int len = 0, st = 0, cu;
1058 1.1 cgd for (m = ttymodes; m->m_name; m++) {
1059 1.1 cgd if (m->m_type != i) {
1060 1.1 cgd (void) fprintf(el->el_outfile, "%s%s", i != -1 ? "\n" : "",
1061 1.1 cgd el->el_tty.t_t[z][m->m_type].t_name);
1062 1.1 cgd i = m->m_type;
1063 1.1 cgd st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name);
1064 1.1 cgd }
1065 1.1 cgd
1066 1.1 cgd x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0';
1067 1.1 cgd x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '-' : x;
1068 1.1 cgd
1069 1.1 cgd if (x != '\0' || aflag) {
1070 1.1 cgd
1071 1.1 cgd cu = strlen(m->m_name) + (x != '\0') + 1;
1072 1.1 cgd
1073 1.1 cgd if (len + cu >= el->el_term.t_size.h) {
1074 1.1 cgd (void) fprintf(el->el_outfile, "\n%*s", st, "");
1075 1.1 cgd len = st + cu;
1076 1.1 cgd }
1077 1.1 cgd else
1078 1.1 cgd len += cu;
1079 1.1 cgd
1080 1.1 cgd if (x != '\0')
1081 1.1 cgd (void) fprintf(el->el_outfile, "%c%s ", x, m->m_name);
1082 1.1 cgd else
1083 1.1 cgd (void) fprintf(el->el_outfile, "%s ", m->m_name);
1084 1.1 cgd }
1085 1.1 cgd }
1086 1.1 cgd (void) fprintf(el->el_outfile, "\n");
1087 1.1 cgd return 0;
1088 1.1 cgd }
1089 1.1 cgd
1090 1.1 cgd while (argv && (s = *argv++)) {
1091 1.1 cgd switch (*s) {
1092 1.1 cgd case '+':
1093 1.1 cgd case '-':
1094 1.1 cgd x = *s++;
1095 1.1 cgd break;
1096 1.1 cgd default:
1097 1.1 cgd x = '\0';
1098 1.1 cgd break;
1099 1.1 cgd }
1100 1.1 cgd d = s;
1101 1.1 cgd for (m = ttymodes; m->m_name; m++)
1102 1.1 cgd if (strcmp(m->m_name, d) == 0)
1103 1.1 cgd break;
1104 1.1 cgd
1105 1.1 cgd if (!m->m_name) {
1106 1.1 cgd (void) fprintf(el->el_errfile, "%s: Invalid argument `%s'.\n",
1107 1.1 cgd name, d);
1108 1.1 cgd return -1;
1109 1.1 cgd }
1110 1.1 cgd
1111 1.1 cgd switch (x) {
1112 1.1 cgd case '+':
1113 1.1 cgd el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
1114 1.1 cgd el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1115 1.1 cgd break;
1116 1.1 cgd case '-':
1117 1.1 cgd el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1118 1.1 cgd el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
1119 1.1 cgd break;
1120 1.1 cgd default:
1121 1.1 cgd el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
1122 1.1 cgd el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
1123 1.1 cgd break;
1124 1.1 cgd }
1125 1.1 cgd }
1126 1.1 cgd return 0;
1127 1.1 cgd } /* end tty_stty */
1128 1.1 cgd
1129 1.1 cgd
1130 1.1 cgd #ifdef notyet
1131 1.1 cgd /* tty_printchar():
1132 1.1 cgd * DEbugging routine to print the tty characters
1133 1.1 cgd */
1134 1.1 cgd private void
1135 1.1 cgd tty_printchar(el, s)
1136 1.1 cgd EditLine *el;
1137 1.1 cgd unsigned char *s;
1138 1.1 cgd {
1139 1.1 cgd ttyperm_t *m;
1140 1.1 cgd int i;
1141 1.1 cgd
1142 1.1 cgd for (i = 0; i < C_NCC; i++) {
1143 1.1 cgd for (m = el->el_tty.t_t; m->m_name; m++)
1144 1.8 christos if (m->m_type == MD_CHAR && C_SH(i) == m->m_value)
1145 1.1 cgd break;
1146 1.1 cgd if (m->m_name)
1147 1.1 cgd (void) fprintf(el->el_errfile, "%s ^%c ", m->m_name, s[i] + 'A'-1);
1148 1.1 cgd if (i % 5 == 0)
1149 1.1 cgd (void) fprintf(el->el_errfile, "\n");
1150 1.1 cgd }
1151 1.1 cgd (void) fprintf(el->el_errfile, "\n");
1152 1.1 cgd }
1153 1.1 cgd #endif /* notyet */
1154