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