diff options
author | peter <peter@FreeBSD.org> | 1996-11-01 06:45:43 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-11-01 06:45:43 +0000 |
commit | 59cc89c2c2e686da3bdab2d5cfac4f33462d29fe (patch) | |
tree | 88f923c9c0be2e2a225a9b21716fd582de668b42 /contrib/nvi/tk/tk_read.c | |
download | FreeBSD-src-59cc89c2c2e686da3bdab2d5cfac4f33462d29fe.zip FreeBSD-src-59cc89c2c2e686da3bdab2d5cfac4f33462d29fe.tar.gz |
Import of nvi-1.79, minus a few bits that we dont need (eg: postscript
files, curses, db, regex etc that we already have). The other glue will
follow shortly.
Obtained from: Keith Bostic <bostic@bostic.com>
Diffstat (limited to 'contrib/nvi/tk/tk_read.c')
-rw-r--r-- | contrib/nvi/tk/tk_read.c | 207 |
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); +} |