summaryrefslogtreecommitdiffstats
path: root/contrib/nvi/tk/tk_read.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/nvi/tk/tk_read.c')
-rw-r--r--contrib/nvi/tk/tk_read.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/contrib/nvi/tk/tk_read.c b/contrib/nvi/tk/tk_read.c
new file mode 100644
index 0000000..b5cfab7
--- /dev/null
+++ b/contrib/nvi/tk/tk_read.c
@@ -0,0 +1,207 @@
+/*-
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1993, 1994, 1995, 1996
+ * Keith Bostic. All rights reserved.
+ *
+ * See the LICENSE file for redistribution information.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char sccsid[] = "@(#)tk_read.c 8.12 (Berkeley) 9/24/96";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include <bitstring.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "../common/common.h"
+#include "../ex/script.h"
+#include "tki.h"
+
+static input_t tk_read __P((SCR *, int));
+static int tk_resize __P((SCR *, size_t, size_t));
+
+
+/*
+ * tk_event --
+ * Return a single event.
+ *
+ * PUBLIC: int tk_event __P((SCR *, EVENT *, u_int32_t, int));
+ */
+int
+tk_event(sp, evp, flags, timeout)
+ SCR *sp;
+ EVENT *evp;
+ u_int32_t flags;
+ int timeout;
+{
+ EVENT *tevp;
+ TK_PRIVATE *tkp;
+ size_t lines, columns;
+ int changed;
+
+ /*
+ * Queue signal based events. We never clear SIGHUP or SIGTERM events,
+ * so that we just keep returning them until the editor dies.
+ */
+ tkp = TKP(sp);
+sig: if (LF_ISSET(EC_INTERRUPT) || F_ISSET(tkp, TK_SIGINT)) {
+ if (F_ISSET(tkp, TK_SIGINT)) {
+ F_CLR(tkp, TK_SIGINT);
+ evp->e_event = E_INTERRUPT;
+ } else
+ evp->e_event = E_TIMEOUT;
+ return (0);
+ }
+ if (F_ISSET(tkp, TK_SIGHUP | TK_SIGTERM | TK_SIGWINCH)) {
+ if (F_ISSET(tkp, TK_SIGHUP)) {
+ evp->e_event = E_SIGHUP;
+ return (0);
+ }
+ if (F_ISSET(tkp, TK_SIGTERM)) {
+ evp->e_event = E_SIGTERM;
+ return (0);
+ }
+ if (F_ISSET(tkp, TK_SIGWINCH)) {
+ F_CLR(tkp, TK_SIGWINCH);
+ (void)tk_ssize(sp, 1, &lines, &columns, &changed);
+ if (changed) {
+ (void)tk_resize(sp, lines, columns);
+ evp->e_event = E_WRESIZE;
+ return (0);
+ }
+ /* No change, so ignore the signal. */
+ }
+ }
+
+ /* Queue special ops. */
+ops: if ((tevp = tkp->evq.tqh_first) != NULL) {
+ *evp = *tevp;
+ TAILQ_REMOVE(&tkp->evq, tevp, q);
+ free(tevp);
+ return (0);
+ }
+
+ /* Read input characters. */
+ switch (tk_read(sp, timeout)) {
+ case INP_OK:
+ evp->e_csp = tkp->ibuf;
+ evp->e_len = tkp->ibuf_cnt;
+ evp->e_event = E_STRING;
+ tkp->ibuf_cnt = 0;
+ break;
+ case INP_EOF:
+ evp->e_event = E_EOF;
+ break;
+ case INP_ERR:
+ evp->e_event = E_ERR;
+ break;
+ case INP_INTR:
+ goto sig;
+ break;
+ case INP_TIMEOUT:
+ /* May have returned because queued a special op. */
+ if (tkp->evq.tqh_first != NULL)
+ goto ops;
+
+ /* Otherwise, we timed out. */
+ evp->e_event = E_TIMEOUT;
+ break;
+ default:
+ abort();
+ }
+ return (0);
+}
+
+/*
+ * tk_read --
+ * Read characters from the input.
+ */
+static input_t
+tk_read(sp, timeout)
+ SCR *sp;
+ int timeout;
+{
+ TK_PRIVATE *tkp;
+ char buf[20];
+
+ /*
+ * Check scripting window file descriptors. It's ugly that we wait
+ * on scripting file descriptors here, but it's the only way to keep
+ * from locking out scripting windows.
+ */
+ if (F_ISSET(sp->gp, G_SCRWIN) && sscr_input(sp))
+ return (INP_ERR);
+
+ /* Read characters. */
+ tkp = TKP(sp);
+ (void)snprintf(buf, sizeof(buf), "%d", timeout);
+ (void)Tcl_VarEval(tkp->interp, "tk_key_wait ", buf, NULL);
+
+ return (tkp->ibuf_cnt == 0 ? INP_TIMEOUT : INP_OK);
+}
+
+/*
+ * tk_key --
+ * Receive an input key.
+ *
+ * PUBLIC: int tk_key __P((ClientData, Tcl_Interp *, int, char *[]));
+ */
+int
+tk_key(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char *argv[];
+{
+ TK_PRIVATE *tkp;
+ u_int8_t *p, *t;
+
+ tkp = (TK_PRIVATE *)clientData;
+ for (p =
+ tkp->ibuf + tkp->ibuf_cnt, t = argv[1]; (*p++ = *t++) != '\0';
+ ++tkp->ibuf_cnt);
+ return (TCL_OK);
+}
+
+/*
+ * tk_resize --
+ * Reset the options for a resize event.
+ */
+static int
+tk_resize(sp, lines, columns)
+ SCR *sp;
+ size_t lines, columns;
+{
+ ARGS *argv[2], a, b;
+ int rval;
+ char b1[1024];
+
+ a.bp = b1;
+ b.bp = NULL;
+ a.len = b.len = 0;
+ argv[0] = &a;
+ argv[1] = &b;
+
+ (void)snprintf(b1, sizeof(b1), "lines=%lu", (u_long)lines);
+ a.len = strlen(b1);
+ if (opts_set(sp, argv, NULL))
+ return (1);
+ (void)snprintf(b1, sizeof(b1), "columns=%lu", (u_long)columns);
+ a.len = strlen(b1);
+ if (opts_set(sp, argv, NULL))
+ return (1);
+ return (0);
+}
OpenPOWER on IntegriCloud