3 * Keith Bostic. All rights reserved.
5 * See the LICENSE file for redistribution information.
11 static const char sccsid[] = "@(#)ip_read.c 8.3 (Berkeley) 9/24/96";
14 #include <sys/types.h>
15 #include <sys/queue.h>
17 #include <bitstring.h>
22 #include "../common/common.h"
23 #include "../ex/script.h"
26 extern GS *__global_list;
28 typedef enum { INP_OK=0, INP_EOF, INP_ERR, INP_TIMEOUT } input_t;
30 static input_t ip_read __P((SCR *, IP_PRIVATE *, struct timeval *));
31 static int ip_resize __P((SCR *, size_t, size_t));
32 static int ip_trans __P((SCR *, IP_PRIVATE *, EVENT *));
36 * Return a single event.
38 * PUBLIC: int ip_event __P((SCR *, EVENT *, u_int32_t, int));
41 ip_event(sp, evp, flags, ms)
48 struct timeval t, *tp;
50 if (LF_ISSET(EC_INTERRUPT)) { /* XXX */
51 evp->e_event = E_TIMEOUT;
55 ipp = sp == NULL ? GIPP(__global_list) : IPP(sp);
57 /* Discard the last command. */
58 if (ipp->iskip != 0) {
59 ipp->iblen -= ipp->iskip;
60 memmove(ipp->ibuf, ipp->ibuf + ipp->iskip, ipp->iblen);
69 t.tv_usec = (ms % 1000) * 1000;
73 /* Read input events. */
75 switch (ip_read(sp, ipp, tp)) {
77 if (!ip_trans(sp, ipp, evp))
87 evp->e_event = E_TIMEOUT;
99 * Read characters from the input.
116 gp = sp == NULL ? __global_list : sp->gp;
117 bp = ipp->ibuf + ipp->iblen;
118 blen = sizeof(ipp->ibuf) - ipp->iblen;
121 * 1: A read with an associated timeout, e.g., trying to complete
122 * a map sequence. If input exists, we fall into #2.
128 FD_SET(ipp->i_fd, &rdfd);
129 switch (select(ipp->i_fd + 1,
130 &rdfd, NULL, NULL, tp == NULL ? &poll : tp)) {
132 return (INP_TIMEOUT);
143 * Select on the command input and scripting window file descriptors.
144 * It's ugly that we wait on scripting file descriptors here, but it's
145 * the only way to keep from locking out scripting windows.
147 if (sp != NULL && F_ISSET(gp, G_SCRWIN)) {
148 loop: FD_ZERO(&rdfd);
149 FD_SET(ipp->i_fd, &rdfd);
151 for (tsp = gp->dq.cqh_first;
152 tsp != (void *)&gp->dq; tsp = tsp->q.cqe_next)
153 if (F_ISSET(sp, SC_SCRIPT)) {
154 FD_SET(sp->script->sh_master, &rdfd);
155 if (sp->script->sh_master > maxfd)
156 maxfd = sp->script->sh_master;
158 switch (select(maxfd + 1, &rdfd, NULL, NULL, NULL)) {
166 if (!FD_ISSET(ipp->i_fd, &rdfd)) {
176 switch (nr = read(ipp->i_fd, bp, blen)) {
180 case -1: /* Error or interrupt. */
182 msgq(sp, M_SYSERR, "input");
184 default: /* Input characters. */
194 * Translate messages into events.
197 ip_trans(sp, ipp, evp)
202 u_int32_t val1, val2;
204 switch (ipp->ibuf[0]) {
206 evp->e_event = E_EOF;
207 ipp->iskip = IPO_CODE_LEN;
210 evp->e_event = E_ERR;
211 ipp->iskip = IPO_CODE_LEN;
214 evp->e_event = E_INTERRUPT;
215 ipp->iskip = IPO_CODE_LEN;
218 evp->e_event = E_QUIT;
219 ipp->iskip = IPO_CODE_LEN;
222 if (ipp->iblen < IPO_CODE_LEN + IPO_INT_LEN * 2)
224 evp->e_event = E_WRESIZE;
225 memcpy(&val1, ipp->ibuf + IPO_CODE_LEN, IPO_INT_LEN);
228 ipp->ibuf + IPO_CODE_LEN + IPO_INT_LEN, IPO_INT_LEN);
230 ip_resize(sp, val1, val2);
231 ipp->iskip = IPO_CODE_LEN + IPO_INT_LEN * 2;
234 evp->e_event = E_SIGHUP;
235 ipp->iskip = IPO_CODE_LEN;
238 evp->e_event = E_SIGTERM;
239 ipp->iskip = IPO_CODE_LEN;
242 evp->e_event = E_STRING;
243 string: if (ipp->iblen < IPO_CODE_LEN + IPO_INT_LEN)
245 memcpy(&val1, ipp->ibuf + IPO_CODE_LEN, IPO_INT_LEN);
247 if (ipp->iblen < IPO_CODE_LEN + IPO_INT_LEN + val1)
249 ipp->iskip = IPO_CODE_LEN + IPO_INT_LEN + val1;
250 evp->e_csp = ipp->ibuf + IPO_CODE_LEN + IPO_INT_LEN;
254 evp->e_event = E_WRITE;
255 ipp->iskip = IPO_CODE_LEN;
259 * XXX: Protocol is out of sync?
268 * Reset the options for a resize event.
271 ip_resize(sp, lines, columns)
273 size_t lines, columns;
281 * The IP screen has to know the lines and columns before anything
282 * else happens. So, we may not have a valid SCR pointer, and we
283 * have to deal with that.
287 OG_VAL(gp, GO_LINES) = OG_D_VAL(gp, GO_LINES) = lines;
288 OG_VAL(gp, GO_COLUMNS) = OG_D_VAL(gp, GO_COLUMNS) = columns;
298 (void)snprintf(b1, sizeof(b1), "lines=%lu", (u_long)lines);
300 if (opts_set(sp, argv, NULL))
302 (void)snprintf(b1, sizeof(b1), "columns=%lu", (u_long)columns);
304 if (opts_set(sp, argv, NULL))