aboutsummaryrefslogtreecommitdiff
path: root/tty.c
diff options
context:
space:
mode:
Diffstat (limited to 'tty.c')
-rw-r--r--tty.c121
1 files changed, 67 insertions, 54 deletions
diff --git a/tty.c b/tty.c
index 7bf24273..53f57713 100644
--- a/tty.c
+++ b/tty.c
@@ -34,11 +34,6 @@
static int tty_log_fd = -1;
-static void tty_init_termios(int, struct termios *, struct bufferevent *);
-
-static void tty_read_callback(struct bufferevent *, void *);
-static void tty_error_callback(struct bufferevent *, short, void *);
-
static int tty_client_ready(struct client *, struct window_pane *);
static void tty_set_italics(struct tty *);
@@ -159,72 +154,84 @@ tty_set_size(struct tty *tty, u_int sx, u_int sy)
return (1);
}
-int
-tty_open(struct tty *tty, char **cause)
-{
- tty->term = tty_term_find(tty->term_name, tty->fd, cause);
- if (tty->term == NULL) {
- tty_close(tty);
- return (-1);
- }
- tty->flags |= TTY_OPENED;
-
- tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE|TTY_TIMER);
-
- tty->event = bufferevent_new(tty->fd, tty_read_callback, NULL,
- tty_error_callback, tty);
-
- tty_start_tty(tty);
-
- tty_keys_build(tty);
-
- return (0);
-}
-
static void
-tty_read_callback(__unused struct bufferevent *bufev, void *data)
+tty_read_callback(__unused int fd, __unused short events, void *data)
{
struct tty *tty = data;
+ size_t size = EVBUFFER_LENGTH(tty->in);
+ int nread;
+
+ nread = evbuffer_read(tty->in, tty->fd, -1);
+ if (nread == -1)
+ return;
+ log_debug("%s: read %d bytes (already %zu)", tty->path, nread, size);
while (tty_keys_next(tty))
;
}
static void
-tty_error_callback(__unused struct bufferevent *bufev, __unused short what,
- __unused void *data)
+tty_write_callback(__unused int fd, __unused short events, void *data)
{
+ struct tty *tty = data;
+ size_t size = EVBUFFER_LENGTH(tty->out);
+ int nwrite;
+
+ nwrite = evbuffer_write(tty->out, tty->fd);
+ if (nwrite == -1)
+ return;
+ log_debug("%s: wrote %d bytes (of %zu)", tty->path, nwrite, size);
+
+ if (EVBUFFER_LENGTH(tty->out) != 0)
+ event_add(&tty->event_out, NULL);
}
-static void
-tty_init_termios(int fd, struct termios *orig_tio, struct bufferevent *bufev)
+int
+tty_open(struct tty *tty, char **cause)
{
- struct termios tio;
+ tty->term = tty_term_find(tty->term_name, tty->fd, cause);
+ if (tty->term == NULL) {
+ tty_close(tty);
+ return (-1);
+ }
+ tty->flags |= TTY_OPENED;
- if (fd == -1 || tcgetattr(fd, orig_tio) != 0)
- return;
+ tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
- setblocking(fd, 0);
+ event_set(&tty->event_in, tty->fd, EV_PERSIST|EV_READ,
+ tty_read_callback, tty);
+ tty->in = evbuffer_new();
- if (bufev != NULL)
- bufferevent_enable(bufev, EV_READ|EV_WRITE);
+ event_set(&tty->event_out, tty->fd, EV_WRITE, tty_write_callback, tty);
+ tty->out = evbuffer_new();
- memcpy(&tio, orig_tio, sizeof tio);
- tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|IMAXBEL|ISTRIP);
- tio.c_iflag |= IGNBRK;
- tio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET);
- tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHONL|ECHOCTL|
- ECHOPRT|ECHOKE|ISIG);
- tio.c_cc[VMIN] = 1;
- tio.c_cc[VTIME] = 0;
- if (tcsetattr(fd, TCSANOW, &tio) == 0)
- tcflush(fd, TCIOFLUSH);
+ tty_start_tty(tty);
+
+ tty_keys_build(tty);
+
+ return (0);
}
void
tty_start_tty(struct tty *tty)
{
- tty_init_termios(tty->fd, &tty->tio, tty->event);
+ struct termios tio;
+
+ if (tty->fd != -1 && tcgetattr(tty->fd, &tty->tio) == 0) {
+ setblocking(tty->fd, 0);
+ event_add(&tty->event_in, NULL);
+
+ memcpy(&tio, &tty->tio, sizeof tio);
+ tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|IMAXBEL|ISTRIP);
+ tio.c_iflag |= IGNBRK;
+ tio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET);
+ tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHONL|ECHOCTL|
+ ECHOPRT|ECHOKE|ISIG);
+ tio.c_cc[VMIN] = 1;
+ tio.c_cc[VTIME] = 0;
+ if (tcsetattr(tty->fd, TCSANOW, &tio) == 0)
+ tcflush(tty->fd, TCIOFLUSH);
+ }
tty_putcode(tty, TTYC_SMCUP);
@@ -264,7 +271,8 @@ tty_stop_tty(struct tty *tty)
return;
tty->flags &= ~TTY_STARTED;
- bufferevent_disable(tty->event, EV_READ|EV_WRITE);
+ event_del(&tty->event_in);
+ event_del(&tty->event_out);
/*
* Be flexible about error handling and try not kill the server just
@@ -318,7 +326,10 @@ tty_close(struct tty *tty)
tty_stop_tty(tty);
if (tty->flags & TTY_OPENED) {
- bufferevent_free(tty->event);
+ evbuffer_free(tty->in);
+ event_del(&tty->event_in);
+ evbuffer_free(tty->out);
+ event_del(&tty->event_out);
tty_term_free(tty->term);
tty_keys_free(tty);
@@ -411,11 +422,13 @@ tty_putcode_ptr2(struct tty *tty, enum tty_code_code code, const void *a,
static void
tty_add(struct tty *tty, const char *buf, size_t len)
{
- bufferevent_write(tty->event, buf, len);
- log_debug("%s: %.*s", tty->path, (int)len, buf);
+ evbuffer_add(tty->out, buf, len);
+ log_debug("%s: %.*s", tty->path, (int)len, (const char *)buf);
if (tty_log_fd != -1)
write(tty_log_fd, buf, len);
+ if (tty->flags & TTY_STARTED)
+ event_add(&tty->event_out, NULL);
}
void
@@ -730,7 +743,7 @@ tty_client_ready(struct client *c, struct window_pane *wp)
{
if (c->session == NULL || c->tty.term == NULL)
return (0);
- if (c->flags & CLIENT_SUSPENDED)
+ if (c->flags & (CLIENT_REDRAW|CLIENT_SUSPENDED))
return (0);
if (c->tty.flags & TTY_FREEZE)
return (0);