diff options
Diffstat (limited to 'tty.c')
-rw-r--r-- | tty.c | 121 |
1 files changed, 67 insertions, 54 deletions
@@ -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); |