Merge branch 'vendor/GCC44'
[dragonfly.git] / contrib / nvi / tk / tk_read.c
blobb5cfab71c7e2ccabf5ecc65c33f0058591b37e7f
1 /*-
2 * Copyright (c) 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1993, 1994, 1995, 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
8 */
10 #include "config.h"
12 #ifndef lint
13 static const char sccsid[] = "@(#)tk_read.c 8.12 (Berkeley) 9/24/96";
14 #endif /* not lint */
16 #include <sys/types.h>
17 #include <sys/queue.h>
19 #include <bitstring.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <signal.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <termios.h>
27 #include <unistd.h>
29 #include "../common/common.h"
30 #include "../ex/script.h"
31 #include "tki.h"
33 static input_t tk_read __P((SCR *, int));
34 static int tk_resize __P((SCR *, size_t, size_t));
38 * tk_event --
39 * Return a single event.
41 * PUBLIC: int tk_event __P((SCR *, EVENT *, u_int32_t, int));
43 int
44 tk_event(sp, evp, flags, timeout)
45 SCR *sp;
46 EVENT *evp;
47 u_int32_t flags;
48 int timeout;
50 EVENT *tevp;
51 TK_PRIVATE *tkp;
52 size_t lines, columns;
53 int changed;
56 * Queue signal based events. We never clear SIGHUP or SIGTERM events,
57 * so that we just keep returning them until the editor dies.
59 tkp = TKP(sp);
60 sig: if (LF_ISSET(EC_INTERRUPT) || F_ISSET(tkp, TK_SIGINT)) {
61 if (F_ISSET(tkp, TK_SIGINT)) {
62 F_CLR(tkp, TK_SIGINT);
63 evp->e_event = E_INTERRUPT;
64 } else
65 evp->e_event = E_TIMEOUT;
66 return (0);
68 if (F_ISSET(tkp, TK_SIGHUP | TK_SIGTERM | TK_SIGWINCH)) {
69 if (F_ISSET(tkp, TK_SIGHUP)) {
70 evp->e_event = E_SIGHUP;
71 return (0);
73 if (F_ISSET(tkp, TK_SIGTERM)) {
74 evp->e_event = E_SIGTERM;
75 return (0);
77 if (F_ISSET(tkp, TK_SIGWINCH)) {
78 F_CLR(tkp, TK_SIGWINCH);
79 (void)tk_ssize(sp, 1, &lines, &columns, &changed);
80 if (changed) {
81 (void)tk_resize(sp, lines, columns);
82 evp->e_event = E_WRESIZE;
83 return (0);
85 /* No change, so ignore the signal. */
89 /* Queue special ops. */
90 ops: if ((tevp = tkp->evq.tqh_first) != NULL) {
91 *evp = *tevp;
92 TAILQ_REMOVE(&tkp->evq, tevp, q);
93 free(tevp);
94 return (0);
97 /* Read input characters. */
98 switch (tk_read(sp, timeout)) {
99 case INP_OK:
100 evp->e_csp = tkp->ibuf;
101 evp->e_len = tkp->ibuf_cnt;
102 evp->e_event = E_STRING;
103 tkp->ibuf_cnt = 0;
104 break;
105 case INP_EOF:
106 evp->e_event = E_EOF;
107 break;
108 case INP_ERR:
109 evp->e_event = E_ERR;
110 break;
111 case INP_INTR:
112 goto sig;
113 break;
114 case INP_TIMEOUT:
115 /* May have returned because queued a special op. */
116 if (tkp->evq.tqh_first != NULL)
117 goto ops;
119 /* Otherwise, we timed out. */
120 evp->e_event = E_TIMEOUT;
121 break;
122 default:
123 abort();
125 return (0);
129 * tk_read --
130 * Read characters from the input.
132 static input_t
133 tk_read(sp, timeout)
134 SCR *sp;
135 int timeout;
137 TK_PRIVATE *tkp;
138 char buf[20];
141 * Check scripting window file descriptors. It's ugly that we wait
142 * on scripting file descriptors here, but it's the only way to keep
143 * from locking out scripting windows.
145 if (F_ISSET(sp->gp, G_SCRWIN) && sscr_input(sp))
146 return (INP_ERR);
148 /* Read characters. */
149 tkp = TKP(sp);
150 (void)snprintf(buf, sizeof(buf), "%d", timeout);
151 (void)Tcl_VarEval(tkp->interp, "tk_key_wait ", buf, NULL);
153 return (tkp->ibuf_cnt == 0 ? INP_TIMEOUT : INP_OK);
157 * tk_key --
158 * Receive an input key.
160 * PUBLIC: int tk_key __P((ClientData, Tcl_Interp *, int, char *[]));
163 tk_key(clientData, interp, argc, argv)
164 ClientData clientData;
165 Tcl_Interp *interp;
166 int argc;
167 char *argv[];
169 TK_PRIVATE *tkp;
170 u_int8_t *p, *t;
172 tkp = (TK_PRIVATE *)clientData;
173 for (p =
174 tkp->ibuf + tkp->ibuf_cnt, t = argv[1]; (*p++ = *t++) != '\0';
175 ++tkp->ibuf_cnt);
176 return (TCL_OK);
180 * tk_resize --
181 * Reset the options for a resize event.
183 static int
184 tk_resize(sp, lines, columns)
185 SCR *sp;
186 size_t lines, columns;
188 ARGS *argv[2], a, b;
189 int rval;
190 char b1[1024];
192 a.bp = b1;
193 b.bp = NULL;
194 a.len = b.len = 0;
195 argv[0] = &a;
196 argv[1] = &b;
198 (void)snprintf(b1, sizeof(b1), "lines=%lu", (u_long)lines);
199 a.len = strlen(b1);
200 if (opts_set(sp, argv, NULL))
201 return (1);
202 (void)snprintf(b1, sizeof(b1), "columns=%lu", (u_long)columns);
203 a.len = strlen(b1);
204 if (opts_set(sp, argv, NULL))
205 return (1);
206 return (0);