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