From 35876eaab991efc7759802f184cdd54663ea8a94 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 1 Jun 2009 22:58:49 +0000 Subject: Import tmux, a terminal multiplexor allowing (among other things) a single terminal to be switched between several different windows and programs displayed on one terminal be detached from one terminal and moved to another. ok deraadt pirofti --- tty.c | 1076 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1076 insertions(+) create mode 100644 tty.c (limited to 'tty.c') diff --git a/tty.c b/tty.c new file mode 100644 index 00000000..4d81910d --- /dev/null +++ b/tty.c @@ -0,0 +1,1076 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2007 Nicholas Marriott + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "tmux.h" + +void tty_fill_acs(struct tty *); + +void tty_raw(struct tty *, const char *); + +int tty_try_256(struct tty *, u_char, const char *); +int tty_try_88(struct tty *, u_char, const char *); + +void tty_attributes(struct tty *, const struct grid_cell *); +void tty_attributes_fg(struct tty *, const struct grid_cell *); +void tty_attributes_bg(struct tty *, const struct grid_cell *); + +void tty_cmd_cell(struct tty *, struct window_pane *, va_list); +void tty_cmd_clearendofline(struct tty *, struct window_pane *, va_list); +void tty_cmd_clearendofscreen(struct tty *, struct window_pane *, va_list); +void tty_cmd_clearline(struct tty *, struct window_pane *, va_list); +void tty_cmd_clearscreen(struct tty *, struct window_pane *, va_list); +void tty_cmd_clearstartofline(struct tty *, struct window_pane *, va_list); +void tty_cmd_clearstartofscreen(struct tty *, struct window_pane *, va_list); +void tty_cmd_deletecharacter(struct tty *, struct window_pane *, va_list); +void tty_cmd_deleteline(struct tty *, struct window_pane *, va_list); +void tty_cmd_insertcharacter(struct tty *, struct window_pane *, va_list); +void tty_cmd_insertline(struct tty *, struct window_pane *, va_list); +void tty_cmd_linefeed(struct tty *, struct window_pane *, va_list); +void tty_cmd_raw(struct tty *, struct window_pane *, va_list); +void tty_cmd_reverseindex(struct tty *, struct window_pane *, va_list); + +void (*tty_cmds[])(struct tty *, struct window_pane *, va_list) = { + tty_cmd_cell, + tty_cmd_clearendofline, + tty_cmd_clearendofscreen, + tty_cmd_clearline, + tty_cmd_clearscreen, + tty_cmd_clearstartofline, + tty_cmd_clearstartofscreen, + tty_cmd_deletecharacter, + tty_cmd_deleteline, + tty_cmd_insertcharacter, + tty_cmd_insertline, + tty_cmd_linefeed, + tty_cmd_raw, + tty_cmd_reverseindex, +}; + +void +tty_init(struct tty *tty, char *path, char *term) +{ + tty->path = xstrdup(path); + if (term == NULL) + tty->termname = xstrdup("unknown"); + else + tty->termname = xstrdup(term); + tty->flags = 0; + tty->term_flags = 0; +} + +int +tty_open(struct tty *tty, char **cause) +{ + int mode; + + tty->fd = open(tty->path, O_RDWR|O_NONBLOCK); + if (tty->fd == -1) { + xasprintf(cause, "%s: %s", tty->path, strerror(errno)); + return (-1); + } + + if ((mode = fcntl(tty->fd, F_GETFL)) == -1) + fatal("fcntl failed"); + if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1) + fatal("fcntl failedo"); + if (fcntl(tty->fd, F_SETFD, FD_CLOEXEC) == -1) + fatal("fcntl failed"); + + if (debug_level > 3) + tty->log_fd = open("tmux.out", O_WRONLY|O_CREAT|O_TRUNC, 0644); + else + tty->log_fd = -1; + + if ((tty->term = tty_term_find(tty->termname, tty->fd, cause)) == NULL) + goto error; + + tty->in = buffer_create(BUFSIZ); + tty->out = buffer_create(BUFSIZ); + + tty->flags &= TTY_UTF8; + + tty_start_tty(tty); + + tty_keys_init(tty); + + tty_fill_acs(tty); + + return (0); + +error: + close(tty->fd); + tty->fd = -1; + + return (-1); +} + +void +tty_start_tty(struct tty *tty) +{ + struct termios tio; + int what; + + tty_detect_utf8(tty); + + if (tcgetattr(tty->fd, &tty->tio) != 0) + fatal("tcgetattr failed"); + 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|ECHOCTL|ISIG); + tio.c_cc[VMIN] = 1; + tio.c_cc[VTIME] = 0; + if (tcsetattr(tty->fd, TCSANOW, &tio) != 0) + fatal("tcsetattr failed"); + + what = 0; + if (ioctl(tty->fd, TIOCFLUSH, &what) != 0) + fatal("ioctl(TIOCFLUSH)"); + + tty_putcode(tty, TTYC_IS1); + tty_putcode(tty, TTYC_IS2); + tty_putcode(tty, TTYC_IS3); + + tty_putcode(tty, TTYC_SMCUP); + tty_putcode(tty, TTYC_SMKX); + tty_putcode(tty, TTYC_ENACS); + tty_putcode(tty, TTYC_CLEAR); + + tty_putcode(tty, TTYC_CNORM); + if (tty_term_has(tty->term, TTYC_KMOUS)) + tty_puts(tty, "\033[?1000l"); + + memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell); + + tty->cx = UINT_MAX; + tty->cy = UINT_MAX; + + tty->rlower = UINT_MAX; + tty->rupper = UINT_MAX; + + tty->mode = MODE_CURSOR; +} + +void +tty_stop_tty(struct tty *tty) +{ + struct winsize ws; + + /* + * Be flexible about error handling and try not kill the server just + * because the fd is invalid. Things like ssh -t can easily leave us + * with a dead tty. + */ + if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1) + return; + if (tcsetattr(tty->fd, TCSANOW, &tty->tio) == -1) + return; + + tty_raw(tty, tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1)); + tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS)); + tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0)); + tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX)); + tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); + tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR)); + + tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM)); + if (tty_term_has(tty->term, TTYC_KMOUS)) + tty_raw(tty, "\033[?1000l"); +} + +void +tty_detect_utf8(struct tty *tty) +{ + struct pollfd pfd; + char buf[7]; + size_t len; + ssize_t n; + int nfds; + struct termios tio, old_tio; + int what; + + if (tty->flags & TTY_UTF8) + return; + + /* + * If the terminal looks reasonably likely to support this, try to + * write a three-byte UTF-8 wide character to the terminal, then read + * the cursor position. + * + * XXX This entire function is a hack. + */ + + /* Check if the terminal looks sort of vt100. */ + if (strstr(tty_term_string(tty->term, TTYC_CLEAR), "[2J") == NULL || + strstr(tty_term_string(tty->term, TTYC_CUP), "H") == NULL) + return; + + if (tcgetattr(tty->fd, &old_tio) != 0) + fatal("tcgetattr failed"); + cfmakeraw(&tio); + if (tcsetattr(tty->fd, TCSANOW, &tio) != 0) + fatal("tcsetattr failed"); + + what = 0; + if (ioctl(tty->fd, TIOCFLUSH, &what) != 0) + fatal("ioctl(TIOCFLUSH)"); + +#define UTF8_TEST_DATA "\033[H\357\277\246\033[6n" + if (write(tty->fd, UTF8_TEST_DATA, (sizeof UTF8_TEST_DATA) - 1) == -1) + fatal("write failed"); +#undef UTF8_TEST_DATA + + len = 0; + for (;;) { + pfd.fd = tty->fd; + pfd.events = POLLIN; + + nfds = poll(&pfd, 1, 500); + if (nfds == -1) { + if (errno == EAGAIN || errno == EINTR) + continue; + fatal("poll failed"); + } + if (nfds == 0) + break; + if (pfd.revents & (POLLERR|POLLNVAL|POLLHUP)) + break; + if (!(pfd.revents & POLLIN)) + continue; + + if ((n = read(tty->fd, buf + len, 1)) != 1) + break; + buf[++len] = '\0'; + + if (len == (sizeof buf) - 1) { + if (strcmp(buf, "\033[1;3R") == 0) + tty->flags |= TTY_UTF8; + break; + } + } + + if (tcsetattr(tty->fd, TCSANOW, &old_tio) != 0) + fatal("tcsetattr failed"); +} + +void +tty_fill_acs(struct tty *tty) +{ + const char *ptr; + + memset(tty->acs, 0, sizeof tty->acs); + if (!tty_term_has(tty->term, TTYC_ACSC)) + return; + + ptr = tty_term_string(tty->term, TTYC_ACSC); + if (strlen(ptr) % 2 != 0) + return; + for (; *ptr != '\0'; ptr += 2) + tty->acs[(u_char) ptr[0]] = ptr[1]; +} + +u_char +tty_get_acs(struct tty *tty, u_char ch) +{ + if (tty->acs[ch] != '\0') + return (tty->acs[ch]); + return (ch); +} + +void +tty_close(struct tty *tty, int no_stop) +{ + if (tty->fd == -1) + return; + + if (tty->log_fd != -1) { + close(tty->log_fd); + tty->log_fd = -1; + } + + if (!no_stop) + tty_stop_tty(tty); + + tty_term_free(tty->term); + tty_keys_free(tty); + + close(tty->fd); + tty->fd = -1; + + buffer_destroy(tty->in); + buffer_destroy(tty->out); +} + +void +tty_free(struct tty *tty, int no_stop) +{ + tty_close(tty, no_stop); + + if (tty->path != NULL) + xfree(tty->path); + if (tty->termname != NULL) + xfree(tty->termname); +} + +void +tty_raw(struct tty *tty, const char *s) +{ + write(tty->fd, s, strlen(s)); +} + +void +tty_putcode(struct tty *tty, enum tty_code_code code) +{ + tty_puts(tty, tty_term_string(tty->term, code)); +} + +void +tty_putcode1(struct tty *tty, enum tty_code_code code, int a) +{ + if (a < 0) + return; + tty_puts(tty, tty_term_string1(tty->term, code, a)); +} + +void +tty_putcode2(struct tty *tty, enum tty_code_code code, int a, int b) +{ + if (a < 0 || b < 0) + return; + tty_puts(tty, tty_term_string2(tty->term, code, a, b)); +} + +void +tty_puts(struct tty *tty, const char *s) +{ + if (*s == '\0') + return; + buffer_write(tty->out, s, strlen(s)); + + if (tty->log_fd != -1) + write(tty->log_fd, s, strlen(s)); +} + +void +tty_putc(struct tty *tty, u_char ch) +{ + u_int sx; + + if (tty->cell.attr & GRID_ATTR_CHARSET) + ch = tty_get_acs(tty, ch); + buffer_write8(tty->out, ch); + + if (ch >= 0x20 && ch != 0x7f) { + sx = tty->sx; + if (tty->term->flags & TERM_EARLYWRAP) + sx--; + + if (tty->cx == sx) { + tty->cx = 0; + tty->cy++; + } else + tty->cx++; + } + + if (tty->log_fd != -1) + write(tty->log_fd, &ch, 1); +} + +void +tty_set_title(struct tty *tty, const char *title) +{ + if (strstr(tty->termname, "xterm") == NULL && + strstr(tty->termname, "rxvt") == NULL && + strcmp(tty->termname, "screen") != 0) + return; + + tty_puts(tty, "\033]0;"); + tty_puts(tty, title); + tty_putc(tty, '\007'); +} + +void +tty_update_mode(struct tty *tty, int mode) +{ + int changed; + + if (tty->flags & TTY_NOCURSOR) + mode &= ~MODE_CURSOR; + + changed = mode ^ tty->mode; + if (changed & MODE_CURSOR) { + if (mode & MODE_CURSOR) + tty_putcode(tty, TTYC_CNORM); + else + tty_putcode(tty, TTYC_CIVIS); + } + if (changed & MODE_MOUSE) { + if (mode & MODE_MOUSE) + tty_puts(tty, "\033[?1000h"); + else + tty_puts(tty, "\033[?1000l"); + } + tty->mode = mode; +} + +void +tty_emulate_repeat( + struct tty *tty, enum tty_code_code code, enum tty_code_code code1, u_int n) +{ + if (tty_term_has(tty->term, code)) + tty_putcode1(tty, code, n); + else { + while (n-- > 0) + tty_putcode(tty, code1); + } +} + +/* + * Redraw scroll region using data from screen (already updated). Used when + * CSR not supported, or window is a pane that doesn't take up the full + * width of the terminal. + */ +void +tty_redraw_region(struct tty *tty, struct window_pane *wp) +{ + struct screen *s = wp->screen; + u_int i; + + /* + * If region is >= 50% of the screen, just schedule a window redraw. In + * most cases, this is likely to be followed by some more scrolling - + * without this, the entire pane ends up being redrawn many times which + * can be much more data. + */ + if (s->old_rupper - s->old_rlower >= screen_size_y(s) / 2) { + wp->flags |= PANE_REDRAW; + return; + } + + if (s->old_cy < s->old_rupper || s->old_cy > s->old_rlower) { + for (i = s->old_cy; i < screen_size_y(s); i++) + tty_draw_line(tty, s, i, wp->xoff, wp->yoff); + } else { + for (i = s->old_rupper; i <= s->old_rlower; i++) + tty_draw_line(tty, s, i, wp->xoff, wp->yoff); + } +} + +void +tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) +{ + const struct grid_cell *gc; + const struct grid_utf8 *gu; + u_int i, sx; + + sx = screen_size_x(s); + if (sx > s->grid->size[s->grid->hsize + py]) + sx = s->grid->size[s->grid->hsize + py]; + if (sx > tty->sx) + sx = tty->sx; + + tty_cursor(tty, 0, py, ox, oy); + for (i = 0; i < sx; i++) { + gc = grid_view_peek_cell(s->grid, i, py); + + gu = NULL; + if (gc->flags & GRID_FLAG_UTF8) + gu = grid_view_peek_utf8(s->grid, i, py); + + if (screen_check_selection(s, i, py)) { + s->sel.cell.data = gc->data; + tty_cell(tty, &s->sel.cell, gu); + } else + tty_cell(tty, gc, gu); + } + + if (sx >= tty->sx) + return; + tty_reset(tty); + + tty_cursor(tty, sx, py, ox, oy); + if (screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) + tty_putcode(tty, TTYC_EL); + else { + for (i = sx; i < screen_size_x(s); i++) + tty_putc(tty, ' '); + } +} + +void +tty_write(struct tty *tty, struct window_pane *wp, enum tty_cmd cmd, ...) +{ + va_list ap; + + va_start(ap, cmd); + tty_vwrite(tty, wp, cmd, ap); + va_end(ap); +} + +void +tty_vwrite( + struct tty *tty, struct window_pane *wp, enum tty_cmd cmd, va_list ap) +{ + if (tty->flags & TTY_FREEZE || tty->term == NULL) + return; + if (tty_cmds[cmd] != NULL) + tty_cmds[cmd](tty, wp, ap); +} + +void +tty_cmd_insertcharacter(struct tty *tty, struct window_pane *wp, va_list ap) +{ + struct screen *s = wp->screen; + u_int ua; + + if (wp->xoff != 0 || screen_size_x(s) < tty->sx) { + tty_draw_line(tty, wp->screen, s->old_cy, wp->xoff, wp->yoff); + return; + } + + ua = va_arg(ap, u_int); + + tty_reset(tty); + + tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + if (tty_term_has(tty->term, TTYC_ICH) || + tty_term_has(tty->term, TTYC_ICH1)) + tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ua); + else { + tty_putcode(tty, TTYC_SMIR); + while (ua-- > 0) + tty_putc(tty, ' '); + tty_putcode(tty, TTYC_RMIR); + } +} + +void +tty_cmd_deletecharacter(struct tty *tty, struct window_pane *wp, va_list ap) +{ + struct screen *s = wp->screen; + u_int ua; + + if (wp->xoff != 0 || screen_size_x(s) < tty->sx) { + tty_draw_line(tty, wp->screen, s->old_cy, wp->xoff, wp->yoff); + return; + } + + ua = va_arg(ap, u_int); + + tty_reset(tty); + + tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ua); +} + +void +tty_cmd_insertline(struct tty *tty, struct window_pane *wp, va_list ap) +{ + struct screen *s = wp->screen; + u_int ua; + + if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + !tty_term_has(tty->term, TTYC_CSR)) { + tty_redraw_region(tty, wp); + return; + } + + ua = va_arg(ap, u_int); + + tty_reset(tty); + + tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); + + tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ua); +} + +void +tty_cmd_deleteline(struct tty *tty, struct window_pane *wp, va_list ap) +{ + struct screen *s = wp->screen; + u_int ua; + + if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + !tty_term_has(tty->term, TTYC_CSR)) { + tty_redraw_region(tty, wp); + return; + } + + ua = va_arg(ap, u_int); + + tty_reset(tty); + + tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); + + tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ua); +} + +void +tty_cmd_clearline(struct tty *tty, struct window_pane *wp, unused va_list ap) +{ + struct screen *s = wp->screen; + u_int i; + + tty_reset(tty); + + tty_cursor(tty, 0, s->old_cy, wp->xoff, wp->yoff); + if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && + tty_term_has(tty->term, TTYC_EL)) { + tty_putcode(tty, TTYC_EL); + } else { + for (i = 0; i < screen_size_x(s); i++) + tty_putc(tty, ' '); + } +} + +void +tty_cmd_clearendofline( + struct tty *tty, struct window_pane *wp, unused va_list ap) +{ + struct screen *s = wp->screen; + u_int i; + + tty_reset(tty); + + tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && + tty_term_has(tty->term, TTYC_EL)) + tty_putcode(tty, TTYC_EL); + else { + for (i = s->old_cx; i < screen_size_x(s); i++) + tty_putc(tty, ' '); + } +} + +void +tty_cmd_clearstartofline( + struct tty *tty, struct window_pane *wp, unused va_list ap) +{ + struct screen *s = wp->screen; + u_int i; + + tty_reset(tty); + + if (wp->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) { + tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_putcode(tty, TTYC_EL1); + } else { + tty_cursor(tty, 0, s->old_cy, wp->xoff, wp->yoff); + for (i = 0; i < s->old_cx + 1; i++) + tty_putc(tty, ' '); + } +} + +void +tty_cmd_reverseindex(struct tty *tty, struct window_pane *wp, unused va_list ap) +{ + struct screen *s = wp->screen; + + if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + !tty_term_has(tty->term, TTYC_CSR)) { + tty_redraw_region(tty, wp); + return; + } + + tty_reset(tty); + + tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); + + if (s->old_cy == s->old_rupper) { + tty_cursor(tty, s->old_cx, s->old_rupper, wp->xoff, wp->yoff); + tty_putcode(tty, TTYC_RI); + } +} + +void +tty_cmd_linefeed(struct tty *tty, struct window_pane *wp, unused va_list ap) +{ + struct screen *s = wp->screen; + + if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + !tty_term_has(tty->term, TTYC_CSR)) { + tty_redraw_region(tty, wp); + return; + } + + tty_reset(tty); + + tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); + + if (s->old_cy == s->old_rlower) { + tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_putc(tty, '\n'); + } +} + +void +tty_cmd_clearendofscreen( + struct tty *tty, struct window_pane *wp, unused va_list ap) +{ + struct screen *s = wp->screen; + u_int i, j, oy; + + oy = wp->yoff; + + tty_reset(tty); + + tty_region(tty, 0, screen_size_y(s) - 1, wp->yoff); + tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && + tty_term_has(tty->term, TTYC_EL)) { + tty_putcode(tty, TTYC_EL); + if (s->old_cy != screen_size_y(s) - 1) { + tty_cursor(tty, 0, s->old_cy + 1, wp->xoff, wp->yoff); + for (i = s->old_cy + 1; i < screen_size_y(s); i++) { + tty_putcode(tty, TTYC_EL); + if (i == screen_size_y(s) - 1) + continue; + tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); + tty->cy++; + } + } + } else { + for (i = s->old_cx; i < screen_size_x(s); i++) + tty_putc(tty, ' '); + for (j = s->old_cy; j < screen_size_y(s); j++) { + tty_cursor(tty, 0, j, wp->xoff, wp->yoff); + for (i = 0; i < screen_size_x(s); i++) + tty_putc(tty, ' '); + } + } +} + +void +tty_cmd_clearstartofscreen( + struct tty *tty, struct window_pane *wp, unused va_list ap) +{ + struct screen *s = wp->screen; + u_int i, j; + + tty_reset(tty); + + tty_region(tty, 0, screen_size_y(s) - 1, wp->yoff); + tty_cursor(tty, 0, 0, wp->xoff, wp->yoff); + if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && + tty_term_has(tty->term, TTYC_EL)) { + for (i = 0; i < s->old_cy; i++) { + tty_putcode(tty, TTYC_EL); + tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); + tty->cy++; + } + } else { + for (j = 0; j < s->old_cy; j++) { + tty_cursor(tty, 0, j, wp->xoff, wp->yoff); + for (i = 0; i < screen_size_x(s); i++) + tty_putc(tty, ' '); + } + } + for (i = 0; i < s->old_cx; i++) + tty_putc(tty, ' '); +} + +void +tty_cmd_clearscreen( + struct tty *tty, struct window_pane *wp, unused va_list ap) +{ + struct screen *s = wp->screen; + u_int i, j; + + tty_reset(tty); + + tty_region(tty, 0, screen_size_y(s) - 1, wp->yoff); + tty_cursor(tty, 0, 0, wp->xoff, wp->yoff); + if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && + tty_term_has(tty->term, TTYC_EL)) { + for (i = 0; i < screen_size_y(s); i++) { + tty_putcode(tty, TTYC_EL); + if (i != screen_size_y(s) - 1) { + tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); + tty->cy++; + } + } + } else { + for (j = 0; j < screen_size_y(s); j++) { + tty_cursor(tty, 0, j, wp->xoff, wp->yoff); + for (i = 0; i < screen_size_x(s); i++) + tty_putc(tty, ' '); + } + } +} + +void +tty_cmd_cell(struct tty *tty, struct window_pane *wp, va_list ap) +{ + struct screen *s = wp->screen; + struct grid_cell *gc; + struct grid_utf8 *gu; + + gc = va_arg(ap, struct grid_cell *); + gu = va_arg(ap, struct grid_utf8 *); + + tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + + tty_cell(tty, gc, gu); +} + +void +tty_cmd_raw(struct tty *tty, unused struct window_pane *wp, va_list ap) +{ + u_char *buf; + size_t i, len; + + buf = va_arg(ap, u_char *); + len = va_arg(ap, size_t); + + for (i = 0; i < len; i++) + tty_putc(tty, buf[i]); +} + +void +tty_cell( + struct tty *tty, const struct grid_cell *gc, const struct grid_utf8 *gu) +{ + u_int i; + + /* Skip last character if terminal is stupid. */ + if (tty->term->flags & TERM_EARLYWRAP && + tty->cy == tty->sy - 1 && tty->cx == tty->sx - 1) + return; + + /* If this is a padding character, do nothing. */ + if (gc->flags & GRID_FLAG_PADDING) + return; + + /* Set the attributes. */ + tty_attributes(tty, gc); + + /* If not UTF-8, write directly. */ + if (!(gc->flags & GRID_FLAG_UTF8)) { + if (gc->data < 0x20 || gc->data == 0x7f) + return; + tty_putc(tty, gc->data); + return; + } + + /* If the terminal doesn't support UTF-8, write underscores. */ + if (!(tty->flags & TTY_UTF8)) { + for (i = 0; i < gu->width; i++) + tty_putc(tty, '_'); + return; + } + + /* Otherwise, write UTF-8. */ + for (i = 0; i < UTF8_SIZE; i++) { + if (gu->data[i] == 0xff) + break; + tty_putc(tty, gu->data[i]); + } +} + +void +tty_reset(struct tty *tty) +{ + struct grid_cell *gc = &tty->cell; + + if (memcmp(gc, &grid_default_cell, sizeof *gc) == 0) + return; + + if (tty_term_has(tty->term, TTYC_RMACS) && gc->attr & GRID_ATTR_CHARSET) + tty_putcode(tty, TTYC_RMACS); + tty_putcode(tty, TTYC_SGR0); + memcpy(gc, &grid_default_cell, sizeof *gc); +} + +void +tty_region(struct tty *tty, u_int rupper, u_int rlower, u_int oy) +{ + if (!tty_term_has(tty->term, TTYC_CSR)) + return; + if (tty->rlower != oy + rlower || tty->rupper != oy + rupper) { + tty->rlower = oy + rlower; + tty->rupper = oy + rupper; + tty->cx = 0; + tty->cy = 0; + tty_putcode2(tty, TTYC_CSR, tty->rupper, tty->rlower); + } +} + +void +tty_cursor(struct tty *tty, u_int cx, u_int cy, u_int ox, u_int oy) +{ + if (ox + cx == 0 && tty->cx != 0 && tty->cy == oy + cy) { + tty->cx = 0; + tty_putc(tty, '\r'); + } else if (tty->cx != ox + cx || tty->cy != oy + cy) { + tty->cx = ox + cx; + tty->cy = oy + cy; + tty_putcode2(tty, TTYC_CUP, tty->cy, tty->cx); + } +} + +void +tty_attributes(struct tty *tty, const struct grid_cell *gc) +{ + struct grid_cell *tc = &tty->cell; + u_char changed; + u_int fg, bg; + + /* If any bits are being cleared, reset everything. */ + if (tc->attr & ~gc->attr) + tty_reset(tty); + + /* Filter out attribute bits already set. */ + changed = gc->attr & ~tc->attr; + tc->attr = gc->attr; + + /* Set the attributes. */ + fg = gc->fg; + bg = gc->bg; + if (changed & GRID_ATTR_BRIGHT) + tty_putcode(tty, TTYC_BOLD); + if (changed & GRID_ATTR_DIM) + tty_putcode(tty, TTYC_DIM); + if (changed & GRID_ATTR_ITALICS) + tty_putcode(tty, TTYC_SMSO); + if (changed & GRID_ATTR_UNDERSCORE) + tty_putcode(tty, TTYC_SMUL); + if (changed & GRID_ATTR_BLINK) + tty_putcode(tty, TTYC_BLINK); + if (changed & GRID_ATTR_REVERSE) { + if (tty_term_has(tty->term, TTYC_REV)) + tty_putcode(tty, TTYC_REV); + else if (tty_term_has(tty->term, TTYC_SMSO)) + tty_putcode(tty, TTYC_SMSO); + } + if (changed & GRID_ATTR_HIDDEN) + tty_putcode(tty, TTYC_INVIS); + if (changed & GRID_ATTR_CHARSET) + tty_putcode(tty, TTYC_SMACS); + + /* Set foreground colour. */ + if (fg != tc->fg || + (gc->flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)) { + tty_attributes_fg(tty, gc); + tc->fg = fg; + } + + /* Set background colour. */ + if (bg != tc->bg || + (gc->flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)) { + tty_attributes_bg(tty, gc); + tc->bg = bg; + } +} + +int +tty_try_256(struct tty *tty, u_char colour, const char *type) +{ + char s[32]; + + if (!(tty->term->flags & TERM_256COLOURS) && + !(tty->term_flags & TERM_256COLOURS)) + return (-1); + + xsnprintf(s, sizeof s, "\033[%s;5;%hhum", type, colour); + tty_puts(tty, s); + return (0); +} + +int +tty_try_88(struct tty *tty, u_char colour, const char *type) +{ + char s[32]; + + if (!(tty->term->flags & TERM_88COLOURS) && + !(tty->term_flags & TERM_88COLOURS)) + return (-1); + colour = colour_256to88(colour); + + xsnprintf(s, sizeof s, "\033[%s;5;%hhum", type, colour); + tty_puts(tty, s); + return (0); +} + +void +tty_attributes_fg(struct tty *tty, const struct grid_cell *gc) +{ + u_char fg; + + fg = gc->fg; + if (gc->flags & GRID_FLAG_FG256) { + if (tty_try_256(tty, fg, "38") == 0) + return; + if (tty_try_88(tty, fg, "38") == 0) + return; + fg = colour_256to16(fg); + if (fg & 8) { + fg &= 7; + tty_putcode(tty, TTYC_BOLD); + tty->cell.attr |= GRID_ATTR_BRIGHT; + } else if (tty->cell.attr & GRID_ATTR_BRIGHT) + tty_reset(tty); + } + + if (fg == 8 && + !(tty->term->flags & TERM_HASDEFAULTS) && + !(tty->term_flags & TERM_HASDEFAULTS)) + fg = 7; + if (fg == 8) + tty_puts(tty, "\033[39m"); + else + tty_putcode1(tty, TTYC_SETAF, fg); +} + +void +tty_attributes_bg(struct tty *tty, const struct grid_cell *gc) +{ + u_char bg; + + bg = gc->bg; + if (gc->flags & GRID_FLAG_BG256) { + if (tty_try_256(tty, bg, "48") == 0) + return; + if (tty_try_88(tty, bg, "48") == 0) + return; + bg = colour_256to16(bg); + if (bg & 8) + bg &= 7; + } + + if (bg == 8 && + !(tty->term->flags & TERM_HASDEFAULTS) && + !(tty->term_flags & TERM_HASDEFAULTS)) + bg = 0; + if (bg == 8) + tty_puts(tty, "\033[49m"); + else + tty_putcode1(tty, TTYC_SETAB, bg); +} -- cgit From 3f76a973ee6b19071df1839cd218b2f6071c4380 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 2 Jun 2009 23:39:32 +0000 Subject: Recent code to try and detect if a terminal supports UTF-8 by printing to it fails spectacularly on (at least) sparc64, so disable it for now. Thanks to naddy and Josh Elsasser for help and testing. --- tty.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 4d81910d..06ce9248 100644 --- a/tty.c +++ b/tty.c @@ -134,7 +134,9 @@ tty_start_tty(struct tty *tty) struct termios tio; int what; +#if 0 tty_detect_utf8(tty); +#endif if (tcgetattr(tty->fd, &tty->tio) != 0) fatal("tcgetattr failed"); @@ -204,6 +206,7 @@ tty_stop_tty(struct tty *tty) tty_raw(tty, "\033[?1000l"); } +#if 0 void tty_detect_utf8(struct tty *tty) { @@ -278,6 +281,7 @@ tty_detect_utf8(struct tty *tty) if (tcsetattr(tty->fd, TCSANOW, &old_tio) != 0) fatal("tcsetattr failed"); } +#endif void tty_fill_acs(struct tty *tty) -- cgit From ebe07c27260c295256e7c66480057a3fcfdc9e7f Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 3 Jun 2009 23:26:56 +0000 Subject: Fix some miscalculations when clearing to start of screen: the number of lines to the cursor is cy not cy - 1, and the current cursor cell should be included. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 06ce9248..16a865eb 100644 --- a/tty.c +++ b/tty.c @@ -797,7 +797,7 @@ tty_cmd_clearstartofscreen( tty_putc(tty, ' '); } } - for (i = 0; i < s->old_cx; i++) + for (i = 0; i <= s->old_cx; i++) tty_putc(tty, ' '); } -- cgit From 52ec9b9ec418dbb80e0ebaf8a418eab22e2dd21f Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 3 Jun 2009 23:30:40 +0000 Subject: Implement the DEC alignment test. With the last change this is enough for the first cursor test in vttest (in ports) to pass; it still shops a few more problems though. --- tty.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 16a865eb..3149c8fb 100644 --- a/tty.c +++ b/tty.c @@ -38,6 +38,7 @@ void tty_attributes(struct tty *, const struct grid_cell *); void tty_attributes_fg(struct tty *, const struct grid_cell *); void tty_attributes_bg(struct tty *, const struct grid_cell *); +void tty_cmd_alignmenttest(struct tty *, struct window_pane *, va_list); void tty_cmd_cell(struct tty *, struct window_pane *, va_list); void tty_cmd_clearendofline(struct tty *, struct window_pane *, va_list); void tty_cmd_clearendofscreen(struct tty *, struct window_pane *, va_list); @@ -54,6 +55,7 @@ void tty_cmd_raw(struct tty *, struct window_pane *, va_list); void tty_cmd_reverseindex(struct tty *, struct window_pane *, va_list); void (*tty_cmds[])(struct tty *, struct window_pane *, va_list) = { + tty_cmd_alignmenttest, tty_cmd_cell, tty_cmd_clearendofline, tty_cmd_clearendofscreen, @@ -830,6 +832,24 @@ tty_cmd_clearscreen( } } +void +tty_cmd_alignmenttest( + struct tty *tty, struct window_pane *wp, unused va_list ap) +{ + struct screen *s = wp->screen; + u_int i, j; + + tty_reset(tty); + + tty_region(tty, 0, screen_size_y(s) - 1, wp->yoff); + + for (j = 0; j < screen_size_y(s); j++) { + tty_cursor(tty, 0, j, wp->xoff, wp->yoff); + for (i = 0; i < screen_size_x(s); i++) + tty_putc(tty, 'E'); + } +} + void tty_cmd_cell(struct tty *tty, struct window_pane *wp, va_list ap) { -- cgit From 2de599ac0ec0634282a52711378258e25839bc7f Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 24 Jun 2009 16:01:02 +0000 Subject: Trying to predict the cursor position for UTF-8 output in the same way as for normal eight-bit output is wrong, separate it into a different function. Fixes spacing when mixing UTF-8 with some escape sequences, notably the way w3m does it. --- tty.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 3149c8fb..d0c89afd 100644 --- a/tty.c +++ b/tty.c @@ -408,6 +408,23 @@ tty_putc(struct tty *tty, u_char ch) write(tty->log_fd, &ch, 1); } +void +tty_pututf8(struct tty *tty, const struct grid_utf8 *gu) +{ + u_int i, width; + + for (i = 0; i < UTF8_SIZE; i++) { + if (gu->data[i] == 0xff) + break; + buffer_write8(tty->out, gu->data[i]); + if (tty->log_fd != -1) + write(tty->log_fd, &gu->data[i], 1); + } + + width = utf8_width(gu->data); + tty->cx += width; +} + void tty_set_title(struct tty *tty, const char *title) { @@ -912,11 +929,7 @@ tty_cell( } /* Otherwise, write UTF-8. */ - for (i = 0; i < UTF8_SIZE; i++) { - if (gu->data[i] == 0xff) - break; - tty_putc(tty, gu->data[i]); - } + tty_pututf8(tty, gu); } void -- cgit From 83078bdcbcc845ea56cf05374190d2115c06dfcb Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 25 Jun 2009 05:56:44 +0000 Subject: Unused variables. Found by lint, no binary change. --- tty.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index d0c89afd..1a9307c5 100644 --- a/tty.c +++ b/tty.c @@ -759,9 +759,7 @@ tty_cmd_clearendofscreen( struct tty *tty, struct window_pane *wp, unused va_list ap) { struct screen *s = wp->screen; - u_int i, j, oy; - - oy = wp->yoff; + u_int i, j; tty_reset(tty); -- cgit From 1675ddb4d1880b834a2bd0bbae5a9ffa17eb596d Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 25 Jun 2009 06:15:04 +0000 Subject: Miscellaneous unused functions, including one which was basically a duplicate. Found by lint. --- tty.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 1a9307c5..459db0a4 100644 --- a/tty.c +++ b/tty.c @@ -546,16 +546,6 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) } } -void -tty_write(struct tty *tty, struct window_pane *wp, enum tty_cmd cmd, ...) -{ - va_list ap; - - va_start(ap, cmd); - tty_vwrite(tty, wp, cmd, ap); - va_end(ap); -} - void tty_vwrite( struct tty *tty, struct window_pane *wp, enum tty_cmd cmd, va_list ap) -- cgit From 2660692fb18499bedd1f81f8ec88fab1acfd80bc Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 27 Jun 2009 12:57:14 +0000 Subject: Copy the 256-colour flag into the tty saved cell as well as the actual colour, otherwise colour 8 isn't reset properly. --- tty.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 459db0a4..75986ef0 100644 --- a/tty.c +++ b/tty.c @@ -1005,6 +1005,8 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) (gc->flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)) { tty_attributes_fg(tty, gc); tc->fg = fg; + tc->flags &= ~GRID_FLAG_FG256; + tc->flags |= gc->flags & GRID_FLAG_FG256; } /* Set background colour. */ @@ -1012,6 +1014,8 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) (gc->flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)) { tty_attributes_bg(tty, gc); tc->bg = bg; + tc->flags &= ~GRID_FLAG_BG256; + tc->flags |= gc->flags & GRID_FLAG_BG256; } } -- cgit From 474fdebb7abf08aecbcf00a92b7d53cd9528649c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 7 Jul 2009 17:24:32 +0000 Subject: Handle empty or unset TERM correctly; also fix a fatal() message while here. --- tty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 75986ef0..1ce8b226 100644 --- a/tty.c +++ b/tty.c @@ -76,7 +76,7 @@ void tty_init(struct tty *tty, char *path, char *term) { tty->path = xstrdup(path); - if (term == NULL) + if (term == NULL || *term == '\0') tty->termname = xstrdup("unknown"); else tty->termname = xstrdup(term); @@ -98,7 +98,7 @@ tty_open(struct tty *tty, char **cause) if ((mode = fcntl(tty->fd, F_GETFL)) == -1) fatal("fcntl failed"); if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1) - fatal("fcntl failedo"); + fatal("fcntl failed"); if (fcntl(tty->fd, F_SETFD, FD_CLOEXEC) == -1) fatal("fcntl failed"); -- cgit From 4a6d62e40168fc8c33c0804dbe67bab2f29d4f68 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 10 Jul 2009 07:11:59 +0000 Subject: Don't send initialisation strings is1/2/3 (barely anything else does) and move smcup to the first and rmcup to the last sequences output to the terminal. This allows tmux to use the alternate screen (smcup/rmcup) when available. --- tty.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 1ce8b226..3a536bae 100644 --- a/tty.c +++ b/tty.c @@ -157,11 +157,8 @@ tty_start_tty(struct tty *tty) if (ioctl(tty->fd, TIOCFLUSH, &what) != 0) fatal("ioctl(TIOCFLUSH)"); - tty_putcode(tty, TTYC_IS1); - tty_putcode(tty, TTYC_IS2); - tty_putcode(tty, TTYC_IS3); - tty_putcode(tty, TTYC_SMCUP); + tty_putcode(tty, TTYC_SMKX); tty_putcode(tty, TTYC_ENACS); tty_putcode(tty, TTYC_CLEAR); @@ -200,12 +197,13 @@ tty_stop_tty(struct tty *tty) tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS)); tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0)); tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX)); - tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR)); tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM)); if (tty_term_has(tty->term, TTYC_KMOUS)) tty_raw(tty, "\033[?1000l"); + + tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); } #if 0 -- cgit From 5bd72ec62990d96c3af87858e263bff7a1c0f220 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 22 Jul 2009 15:55:32 +0000 Subject: tty_cmd_raw is only used once, for raw UTF-8 output, so rename it to tty_cmd_utf8character and eliminate the size argument. --- tty.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 3a536bae..0643a356 100644 --- a/tty.c +++ b/tty.c @@ -51,7 +51,7 @@ void tty_cmd_deleteline(struct tty *, struct window_pane *, va_list); void tty_cmd_insertcharacter(struct tty *, struct window_pane *, va_list); void tty_cmd_insertline(struct tty *, struct window_pane *, va_list); void tty_cmd_linefeed(struct tty *, struct window_pane *, va_list); -void tty_cmd_raw(struct tty *, struct window_pane *, va_list); +void tty_cmd_utf8character(struct tty *, struct window_pane *, va_list); void tty_cmd_reverseindex(struct tty *, struct window_pane *, va_list); void (*tty_cmds[])(struct tty *, struct window_pane *, va_list) = { @@ -68,7 +68,7 @@ void (*tty_cmds[])(struct tty *, struct window_pane *, va_list) = { tty_cmd_insertcharacter, tty_cmd_insertline, tty_cmd_linefeed, - tty_cmd_raw, + tty_cmd_utf8character, tty_cmd_reverseindex, }; @@ -869,16 +869,19 @@ tty_cmd_cell(struct tty *tty, struct window_pane *wp, va_list ap) } void -tty_cmd_raw(struct tty *tty, unused struct window_pane *wp, va_list ap) +tty_cmd_utf8character( + struct tty *tty, unused struct window_pane *wp, va_list ap) { u_char *buf; - size_t i, len; + size_t i; buf = va_arg(ap, u_char *); - len = va_arg(ap, size_t); - - for (i = 0; i < len; i++) + + for (i = 0; i < UTF8_SIZE; i++) { + if (buf[i] == 0xff) + break; tty_putc(tty, buf[i]); + } } void -- cgit From 6a309c53a8ae3142d132fe1c12e55bed9b62e4d5 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 22 Jul 2009 16:45:31 +0000 Subject: There are relatively few arguments to tty_cmd_* functions now, so tidy them up by using a struct rather than hiding everything with varargs. --- tty.c | 167 ++++++++++++++++++++++++++++++------------------------------------ 1 file changed, 77 insertions(+), 90 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 0643a356..dfa36a5e 100644 --- a/tty.c +++ b/tty.c @@ -38,23 +38,23 @@ void tty_attributes(struct tty *, const struct grid_cell *); void tty_attributes_fg(struct tty *, const struct grid_cell *); void tty_attributes_bg(struct tty *, const struct grid_cell *); -void tty_cmd_alignmenttest(struct tty *, struct window_pane *, va_list); -void tty_cmd_cell(struct tty *, struct window_pane *, va_list); -void tty_cmd_clearendofline(struct tty *, struct window_pane *, va_list); -void tty_cmd_clearendofscreen(struct tty *, struct window_pane *, va_list); -void tty_cmd_clearline(struct tty *, struct window_pane *, va_list); -void tty_cmd_clearscreen(struct tty *, struct window_pane *, va_list); -void tty_cmd_clearstartofline(struct tty *, struct window_pane *, va_list); -void tty_cmd_clearstartofscreen(struct tty *, struct window_pane *, va_list); -void tty_cmd_deletecharacter(struct tty *, struct window_pane *, va_list); -void tty_cmd_deleteline(struct tty *, struct window_pane *, va_list); -void tty_cmd_insertcharacter(struct tty *, struct window_pane *, va_list); -void tty_cmd_insertline(struct tty *, struct window_pane *, va_list); -void tty_cmd_linefeed(struct tty *, struct window_pane *, va_list); -void tty_cmd_utf8character(struct tty *, struct window_pane *, va_list); -void tty_cmd_reverseindex(struct tty *, struct window_pane *, va_list); - -void (*tty_cmds[])(struct tty *, struct window_pane *, va_list) = { +void tty_cmd_alignmenttest(struct tty *, struct tty_ctx *); +void tty_cmd_cell(struct tty *, struct tty_ctx *); +void tty_cmd_clearendofline(struct tty *, struct tty_ctx *); +void tty_cmd_clearendofscreen(struct tty *, struct tty_ctx *); +void tty_cmd_clearline(struct tty *, struct tty_ctx *); +void tty_cmd_clearscreen(struct tty *, struct tty_ctx *); +void tty_cmd_clearstartofline(struct tty *, struct tty_ctx *); +void tty_cmd_clearstartofscreen(struct tty *, struct tty_ctx *); +void tty_cmd_deletecharacter(struct tty *, struct tty_ctx *); +void tty_cmd_deleteline(struct tty *, struct tty_ctx *); +void tty_cmd_insertcharacter(struct tty *, struct tty_ctx *); +void tty_cmd_insertline(struct tty *, struct tty_ctx *); +void tty_cmd_linefeed(struct tty *, struct tty_ctx *); +void tty_cmd_utf8character(struct tty *, struct tty_ctx *); +void tty_cmd_reverseindex(struct tty *, struct tty_ctx *); + +void (*tty_cmds[])(struct tty *, struct tty_ctx *) = { tty_cmd_alignmenttest, tty_cmd_cell, tty_cmd_clearendofline, @@ -545,66 +545,61 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) } void -tty_vwrite( - struct tty *tty, struct window_pane *wp, enum tty_cmd cmd, va_list ap) +tty_write(struct tty *tty, enum tty_cmd cmd, struct tty_ctx *ctx) { if (tty->flags & TTY_FREEZE || tty->term == NULL) return; if (tty_cmds[cmd] != NULL) - tty_cmds[cmd](tty, wp, ap); + tty_cmds[cmd](tty, ctx); } void -tty_cmd_insertcharacter(struct tty *tty, struct window_pane *wp, va_list ap) +tty_cmd_insertcharacter(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; - u_int ua; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; if (wp->xoff != 0 || screen_size_x(s) < tty->sx) { tty_draw_line(tty, wp->screen, s->old_cy, wp->xoff, wp->yoff); return; } - ua = va_arg(ap, u_int); - tty_reset(tty); tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); if (tty_term_has(tty->term, TTYC_ICH) || tty_term_has(tty->term, TTYC_ICH1)) - tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ua); + tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num); else { tty_putcode(tty, TTYC_SMIR); - while (ua-- > 0) + while (ctx->num-- > 0) tty_putc(tty, ' '); tty_putcode(tty, TTYC_RMIR); } } void -tty_cmd_deletecharacter(struct tty *tty, struct window_pane *wp, va_list ap) +tty_cmd_deletecharacter(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; - u_int ua; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; if (wp->xoff != 0 || screen_size_x(s) < tty->sx) { tty_draw_line(tty, wp->screen, s->old_cy, wp->xoff, wp->yoff); return; } - ua = va_arg(ap, u_int); - tty_reset(tty); tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); - tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ua); + tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ctx->num); } void -tty_cmd_insertline(struct tty *tty, struct window_pane *wp, va_list ap) +tty_cmd_insertline(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; - u_int ua; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { @@ -612,21 +607,19 @@ tty_cmd_insertline(struct tty *tty, struct window_pane *wp, va_list ap) return; } - ua = va_arg(ap, u_int); - tty_reset(tty); tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); - tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ua); + tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ctx->num); } void -tty_cmd_deleteline(struct tty *tty, struct window_pane *wp, va_list ap) +tty_cmd_deleteline(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; - u_int ua; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { @@ -634,21 +627,20 @@ tty_cmd_deleteline(struct tty *tty, struct window_pane *wp, va_list ap) return; } - ua = va_arg(ap, u_int); - tty_reset(tty); tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); - tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ua); + tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ctx->num); } void -tty_cmd_clearline(struct tty *tty, struct window_pane *wp, unused va_list ap) +tty_cmd_clearline(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; - u_int i; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; + u_int i; tty_reset(tty); @@ -663,11 +655,11 @@ tty_cmd_clearline(struct tty *tty, struct window_pane *wp, unused va_list ap) } void -tty_cmd_clearendofline( - struct tty *tty, struct window_pane *wp, unused va_list ap) +tty_cmd_clearendofline(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; - u_int i; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; + u_int i; tty_reset(tty); @@ -682,11 +674,11 @@ tty_cmd_clearendofline( } void -tty_cmd_clearstartofline( - struct tty *tty, struct window_pane *wp, unused va_list ap) +tty_cmd_clearstartofline(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; - u_int i; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; + u_int i; tty_reset(tty); @@ -701,9 +693,10 @@ tty_cmd_clearstartofline( } void -tty_cmd_reverseindex(struct tty *tty, struct window_pane *wp, unused va_list ap) +tty_cmd_reverseindex(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { @@ -722,9 +715,10 @@ tty_cmd_reverseindex(struct tty *tty, struct window_pane *wp, unused va_list ap) } void -tty_cmd_linefeed(struct tty *tty, struct window_pane *wp, unused va_list ap) +tty_cmd_linefeed(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { @@ -743,11 +737,11 @@ tty_cmd_linefeed(struct tty *tty, struct window_pane *wp, unused va_list ap) } void -tty_cmd_clearendofscreen( - struct tty *tty, struct window_pane *wp, unused va_list ap) +tty_cmd_clearendofscreen(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; - u_int i, j; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; + u_int i, j; tty_reset(tty); @@ -778,11 +772,11 @@ tty_cmd_clearendofscreen( } void -tty_cmd_clearstartofscreen( - struct tty *tty, struct window_pane *wp, unused va_list ap) +tty_cmd_clearstartofscreen(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; - u_int i, j; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; + u_int i, j; tty_reset(tty); @@ -807,11 +801,11 @@ tty_cmd_clearstartofscreen( } void -tty_cmd_clearscreen( - struct tty *tty, struct window_pane *wp, unused va_list ap) +tty_cmd_clearscreen(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; - u_int i, j; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; + u_int i, j; tty_reset(tty); @@ -836,11 +830,11 @@ tty_cmd_clearscreen( } void -tty_cmd_alignmenttest( - struct tty *tty, struct window_pane *wp, unused va_list ap) +tty_cmd_alignmenttest(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; - u_int i, j; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; + u_int i, j; tty_reset(tty); @@ -854,33 +848,26 @@ tty_cmd_alignmenttest( } void -tty_cmd_cell(struct tty *tty, struct window_pane *wp, va_list ap) +tty_cmd_cell(struct tty *tty, struct tty_ctx *ctx) { + struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - struct grid_cell *gc; - struct grid_utf8 *gu; - - gc = va_arg(ap, struct grid_cell *); - gu = va_arg(ap, struct grid_utf8 *); tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); - tty_cell(tty, gc, gu); + tty_cell(tty, ctx->cell, ctx->utf8); } void -tty_cmd_utf8character( - struct tty *tty, unused struct window_pane *wp, va_list ap) +tty_cmd_utf8character(struct tty *tty, struct tty_ctx *ctx) { - u_char *buf; + u_char *ptr = ctx->ptr; size_t i; - buf = va_arg(ap, u_char *); - for (i = 0; i < UTF8_SIZE; i++) { - if (buf[i] == 0xff) + if (ptr[i] == 0xff) break; - tty_putc(tty, buf[i]); + tty_putc(tty, ptr[i]); } } -- cgit From 2ec2837daa428def7116848a17355f3423bf038e Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 22 Jul 2009 18:02:23 +0000 Subject: enum tty_cmd is only used as an index into the array of command function pointers, so remove it and use the function pointers directly to represent themselves. --- tty.c | 46 ++++------------------------------------------ 1 file changed, 4 insertions(+), 42 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index dfa36a5e..c09fe6c4 100644 --- a/tty.c +++ b/tty.c @@ -38,39 +38,10 @@ void tty_attributes(struct tty *, const struct grid_cell *); void tty_attributes_fg(struct tty *, const struct grid_cell *); void tty_attributes_bg(struct tty *, const struct grid_cell *); -void tty_cmd_alignmenttest(struct tty *, struct tty_ctx *); -void tty_cmd_cell(struct tty *, struct tty_ctx *); -void tty_cmd_clearendofline(struct tty *, struct tty_ctx *); -void tty_cmd_clearendofscreen(struct tty *, struct tty_ctx *); -void tty_cmd_clearline(struct tty *, struct tty_ctx *); -void tty_cmd_clearscreen(struct tty *, struct tty_ctx *); -void tty_cmd_clearstartofline(struct tty *, struct tty_ctx *); -void tty_cmd_clearstartofscreen(struct tty *, struct tty_ctx *); -void tty_cmd_deletecharacter(struct tty *, struct tty_ctx *); -void tty_cmd_deleteline(struct tty *, struct tty_ctx *); -void tty_cmd_insertcharacter(struct tty *, struct tty_ctx *); -void tty_cmd_insertline(struct tty *, struct tty_ctx *); -void tty_cmd_linefeed(struct tty *, struct tty_ctx *); -void tty_cmd_utf8character(struct tty *, struct tty_ctx *); -void tty_cmd_reverseindex(struct tty *, struct tty_ctx *); - -void (*tty_cmds[])(struct tty *, struct tty_ctx *) = { - tty_cmd_alignmenttest, - tty_cmd_cell, - tty_cmd_clearendofline, - tty_cmd_clearendofscreen, - tty_cmd_clearline, - tty_cmd_clearscreen, - tty_cmd_clearstartofline, - tty_cmd_clearstartofscreen, - tty_cmd_deletecharacter, - tty_cmd_deleteline, - tty_cmd_insertcharacter, - tty_cmd_insertline, - tty_cmd_linefeed, - tty_cmd_utf8character, - tty_cmd_reverseindex, -}; +void tty_emulate_repeat( + struct tty *, enum tty_code_code, enum tty_code_code, u_int); +void tty_cell(struct tty *, + const struct grid_cell *, const struct grid_utf8 *); void tty_init(struct tty *tty, char *path, char *term) @@ -544,15 +515,6 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) } } -void -tty_write(struct tty *tty, enum tty_cmd cmd, struct tty_ctx *ctx) -{ - if (tty->flags & TTY_FREEZE || tty->term == NULL) - return; - if (tty_cmds[cmd] != NULL) - tty_cmds[cmd](tty, ctx); -} - void tty_cmd_insertcharacter(struct tty *tty, struct tty_ctx *ctx) { -- cgit From ddad0be5f773978c09e7c86ad79596ce7af9ec71 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 22 Jul 2009 20:53:38 +0000 Subject: More tty code tidying: move the saved cursor/region position (from before the screen was updated) out of struct screen and into struct tty_ctx. --- tty.c | 90 +++++++++++++++++++++++++++++++++---------------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index c09fe6c4..cae894b8 100644 --- a/tty.c +++ b/tty.c @@ -38,10 +38,11 @@ void tty_attributes(struct tty *, const struct grid_cell *); void tty_attributes_fg(struct tty *, const struct grid_cell *); void tty_attributes_bg(struct tty *, const struct grid_cell *); +void tty_redraw_region(struct tty *, struct tty_ctx *); void tty_emulate_repeat( struct tty *, enum tty_code_code, enum tty_code_code, u_int); -void tty_cell(struct tty *, - const struct grid_cell *, const struct grid_utf8 *); +void tty_cell(struct tty *, + const struct grid_cell *, const struct grid_utf8 *); void tty_init(struct tty *tty, char *path, char *term) @@ -449,10 +450,11 @@ tty_emulate_repeat( * width of the terminal. */ void -tty_redraw_region(struct tty *tty, struct window_pane *wp) +tty_redraw_region(struct tty *tty, struct tty_ctx *ctx) { - struct screen *s = wp->screen; - u_int i; + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; + u_int i; /* * If region is >= 50% of the screen, just schedule a window redraw. In @@ -460,16 +462,16 @@ tty_redraw_region(struct tty *tty, struct window_pane *wp) * without this, the entire pane ends up being redrawn many times which * can be much more data. */ - if (s->old_rupper - s->old_rlower >= screen_size_y(s) / 2) { + if (ctx->orupper - ctx->orlower >= screen_size_y(s) / 2) { wp->flags |= PANE_REDRAW; return; } - if (s->old_cy < s->old_rupper || s->old_cy > s->old_rlower) { - for (i = s->old_cy; i < screen_size_y(s); i++) + if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) { + for (i = ctx->ocy; i < screen_size_y(s); i++) tty_draw_line(tty, s, i, wp->xoff, wp->yoff); } else { - for (i = s->old_rupper; i <= s->old_rlower; i++) + for (i = ctx->orupper; i <= ctx->orlower; i++) tty_draw_line(tty, s, i, wp->xoff, wp->yoff); } } @@ -522,13 +524,13 @@ tty_cmd_insertcharacter(struct tty *tty, struct tty_ctx *ctx) struct screen *s = wp->screen; if (wp->xoff != 0 || screen_size_x(s) < tty->sx) { - tty_draw_line(tty, wp->screen, s->old_cy, wp->xoff, wp->yoff); + tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); return; } tty_reset(tty); - tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); if (tty_term_has(tty->term, TTYC_ICH) || tty_term_has(tty->term, TTYC_ICH1)) tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num); @@ -547,13 +549,13 @@ tty_cmd_deletecharacter(struct tty *tty, struct tty_ctx *ctx) struct screen *s = wp->screen; if (wp->xoff != 0 || screen_size_x(s) < tty->sx) { - tty_draw_line(tty, wp->screen, s->old_cy, wp->xoff, wp->yoff); + tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); return; } tty_reset(tty); - tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ctx->num); } @@ -565,15 +567,15 @@ tty_cmd_insertline(struct tty *tty, struct tty_ctx *ctx) if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { - tty_redraw_region(tty, wp); + tty_redraw_region(tty, ctx); return; } tty_reset(tty); - tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); + tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); - tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ctx->num); } @@ -585,15 +587,15 @@ tty_cmd_deleteline(struct tty *tty, struct tty_ctx *ctx) if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { - tty_redraw_region(tty, wp); + tty_redraw_region(tty, ctx); return; } tty_reset(tty); - tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); + tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); - tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ctx->num); } @@ -606,7 +608,7 @@ tty_cmd_clearline(struct tty *tty, struct tty_ctx *ctx) tty_reset(tty); - tty_cursor(tty, 0, s->old_cy, wp->xoff, wp->yoff); + tty_cursor(tty, 0, ctx->ocy, wp->xoff, wp->yoff); if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { tty_putcode(tty, TTYC_EL); @@ -625,12 +627,12 @@ tty_cmd_clearendofline(struct tty *tty, struct tty_ctx *ctx) tty_reset(tty); - tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); else { - for (i = s->old_cx; i < screen_size_x(s); i++) + for (i = ctx->ocx; i < screen_size_x(s); i++) tty_putc(tty, ' '); } } @@ -639,17 +641,16 @@ void tty_cmd_clearstartofline(struct tty *tty, struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; u_int i; tty_reset(tty); if (wp->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) { - tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); tty_putcode(tty, TTYC_EL1); } else { - tty_cursor(tty, 0, s->old_cy, wp->xoff, wp->yoff); - for (i = 0; i < s->old_cx + 1; i++) + tty_cursor(tty, 0, ctx->ocy, wp->xoff, wp->yoff); + for (i = 0; i < ctx->ocx + 1; i++) tty_putc(tty, ' '); } } @@ -662,16 +663,16 @@ tty_cmd_reverseindex(struct tty *tty, struct tty_ctx *ctx) if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { - tty_redraw_region(tty, wp); + tty_redraw_region(tty, ctx); return; } tty_reset(tty); - tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); + tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); - if (s->old_cy == s->old_rupper) { - tty_cursor(tty, s->old_cx, s->old_rupper, wp->xoff, wp->yoff); + if (ctx->ocy == ctx->orupper) { + tty_cursor(tty, ctx->ocx, ctx->orupper, wp->xoff, wp->yoff); tty_putcode(tty, TTYC_RI); } } @@ -684,16 +685,16 @@ tty_cmd_linefeed(struct tty *tty, struct tty_ctx *ctx) if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { - tty_redraw_region(tty, wp); + tty_redraw_region(tty, ctx); return; } tty_reset(tty); - tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); + tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); - if (s->old_cy == s->old_rlower) { - tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + if (ctx->ocy == ctx->orlower) { + tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); tty_putc(tty, '\n'); } } @@ -708,13 +709,13 @@ tty_cmd_clearendofscreen(struct tty *tty, struct tty_ctx *ctx) tty_reset(tty); tty_region(tty, 0, screen_size_y(s) - 1, wp->yoff); - tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { tty_putcode(tty, TTYC_EL); - if (s->old_cy != screen_size_y(s) - 1) { - tty_cursor(tty, 0, s->old_cy + 1, wp->xoff, wp->yoff); - for (i = s->old_cy + 1; i < screen_size_y(s); i++) { + if (ctx->ocy != screen_size_y(s) - 1) { + tty_cursor(tty, 0, ctx->ocy + 1, wp->xoff, wp->yoff); + for (i = ctx->ocy + 1; i < screen_size_y(s); i++) { tty_putcode(tty, TTYC_EL); if (i == screen_size_y(s) - 1) continue; @@ -723,9 +724,9 @@ tty_cmd_clearendofscreen(struct tty *tty, struct tty_ctx *ctx) } } } else { - for (i = s->old_cx; i < screen_size_x(s); i++) + for (i = ctx->ocx; i < screen_size_x(s); i++) tty_putc(tty, ' '); - for (j = s->old_cy; j < screen_size_y(s); j++) { + for (j = ctx->ocy; j < screen_size_y(s); j++) { tty_cursor(tty, 0, j, wp->xoff, wp->yoff); for (i = 0; i < screen_size_x(s); i++) tty_putc(tty, ' '); @@ -746,19 +747,19 @@ tty_cmd_clearstartofscreen(struct tty *tty, struct tty_ctx *ctx) tty_cursor(tty, 0, 0, wp->xoff, wp->yoff); if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { - for (i = 0; i < s->old_cy; i++) { + for (i = 0; i < ctx->ocy; i++) { tty_putcode(tty, TTYC_EL); tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); tty->cy++; } } else { - for (j = 0; j < s->old_cy; j++) { + for (j = 0; j < ctx->ocy; j++) { tty_cursor(tty, 0, j, wp->xoff, wp->yoff); for (i = 0; i < screen_size_x(s); i++) tty_putc(tty, ' '); } } - for (i = 0; i <= s->old_cx; i++) + for (i = 0; i <= ctx->ocx; i++) tty_putc(tty, ' '); } @@ -813,9 +814,8 @@ void tty_cmd_cell(struct tty *tty, struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; - tty_cursor(tty, s->old_cx, s->old_cy, wp->xoff, wp->yoff); + tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); tty_cell(tty, ctx->cell, ctx->utf8); } -- cgit From dd4a3b24fc5b0d6e38e87b3a3c1bc0a47bdc9700 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 22 Jul 2009 20:56:58 +0000 Subject: tty_write is relatively short and the only function left in tty-write.c so move it into tty.c. --- tty.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index cae894b8..05342b82 100644 --- a/tty.c +++ b/tty.c @@ -517,6 +517,37 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) } } +void +tty_write(void (*cmdfn)(struct tty *, struct tty_ctx *), struct tty_ctx *ctx) +{ + struct window_pane *wp = ctx->wp; + struct client *c; + u_int i; + + if (wp == NULL) + return; + + if (wp->window->flags & WINDOW_REDRAW || wp->flags & PANE_REDRAW) + return; + if (wp->window->flags & WINDOW_HIDDEN || !window_pane_visible(wp)) + return; + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (c == NULL || c->session == NULL) + continue; + if (c->flags & CLIENT_SUSPENDED) + continue; + + if (c->session->curw->window == wp->window) { + if (c->tty.flags & TTY_FREEZE || c->tty.term == NULL) + continue; + tty_update_mode(&c->tty, c->tty.mode & ~MODE_CURSOR); + cmdfn(&c->tty, ctx); + } + } +} + void tty_cmd_insertcharacter(struct tty *tty, struct tty_ctx *ctx) { -- cgit From fc65da1eed07708030c0ae491cb8f4a6614de390 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 27 Jul 2009 11:33:21 +0000 Subject: Draw UTF-8 characters under the selection correctly. --- tty.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 05342b82..48b10f7d 100644 --- a/tty.c +++ b/tty.c @@ -480,6 +480,7 @@ void tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) { const struct grid_cell *gc; + struct grid_cell tmpgc; const struct grid_utf8 *gu; u_int i, sx; @@ -498,8 +499,10 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) gu = grid_view_peek_utf8(s->grid, i, py); if (screen_check_selection(s, i, py)) { - s->sel.cell.data = gc->data; - tty_cell(tty, &s->sel.cell, gu); + memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc); + tmpgc.data = gc->data; + tmpgc.flags = gc->flags; + tty_cell(tty, &tmpgc, gu); } else tty_cell(tty, gc, gu); } -- cgit From 1673735f0271c6f87e6ba0d85d8b4a1d0f2f3d35 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 3 Aug 2009 14:10:54 +0000 Subject: Add a terminal-overrides session option allowing individual terminfo(5) entries to be overridden. The 88col/256col checks are now moved into the default setting and out of the code. Also remove a couple of old workarounds for xterm and rxvt which are no longer necessary (tmux can emulate them if missing). --- tty.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 48b10f7d..d3a4ba1d 100644 --- a/tty.c +++ b/tty.c @@ -57,7 +57,7 @@ tty_init(struct tty *tty, char *path, char *term) } int -tty_open(struct tty *tty, char **cause) +tty_open(struct tty *tty, const char *overrides, char **cause) { int mode; @@ -79,7 +79,8 @@ tty_open(struct tty *tty, char **cause) else tty->log_fd = -1; - if ((tty->term = tty_term_find(tty->termname, tty->fd, cause)) == NULL) + tty->term = tty_term_find(tty->termname, tty->fd, overrides, cause); + if (tty->term == NULL) goto error; tty->in = buffer_create(BUFSIZ); -- cgit From bcddddf98d46bb9aef919d8e93b7328a7b040140 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 5 Aug 2009 16:26:38 +0000 Subject: If colours are not supported by the terminal, try to emulate a coloured background by setting or clearing the reverse attribute. This makes a few applications which don't use the reverse attribute themselves a little happier, and allows the status, message and mode options to have default attributes and fg/bg options that work as expected when set as reverse. --- tty.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index d3a4ba1d..cbdbec8d 100644 --- a/tty.c +++ b/tty.c @@ -951,19 +951,33 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell; u_char changed; - u_int fg, bg; + u_int fg, bg, attr; + + /* + * If no setab, try to use the reverse attribute as a best-effort for a + * non-default background. This is a bit of a hack but it doesn't do + * any serious harm and makes a couple of applications happier. + */ + fg = gc->fg; bg = gc->bg; attr = gc->attr; + if (!tty_term_has(tty->term, TTYC_SETAB)) { + if (attr & GRID_ATTR_REVERSE) { + if (fg != 7 && fg != 8) + attr &= ~GRID_ATTR_REVERSE; + } else { + if (bg != 0 && bg != 8) + attr |= GRID_ATTR_REVERSE; + } + } /* If any bits are being cleared, reset everything. */ - if (tc->attr & ~gc->attr) + if (tc->attr & ~attr) tty_reset(tty); /* Filter out attribute bits already set. */ - changed = gc->attr & ~tc->attr; - tc->attr = gc->attr; + changed = attr & ~tc->attr; + tc->attr = attr; /* Set the attributes. */ - fg = gc->fg; - bg = gc->bg; if (changed & GRID_ATTR_BRIGHT) tty_putcode(tty, TTYC_BOLD); if (changed & GRID_ATTR_DIM) -- cgit From 5e01b6d663abc086847c9bec145edeb9cd91530a Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 8 Aug 2009 13:29:27 +0000 Subject: Change the way the grid is stored, previously it was: - a two-dimensional array of cells; - a two-dimensional array of utf8 data; - an array of line lengths. Now it is a single array of a new struct grid_line each of which represents a line and containts the length and an array of cells and an array of utf8 data. This will make it easier to add additional per-line members, such as flags. --- tty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index cbdbec8d..33acb99d 100644 --- a/tty.c +++ b/tty.c @@ -486,8 +486,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) u_int i, sx; sx = screen_size_x(s); - if (sx > s->grid->size[s->grid->hsize + py]) - sx = s->grid->size[s->grid->hsize + py]; + if (sx > s->grid->linedata[s->grid->hsize + py].cellsize) + sx = s->grid->linedata[s->grid->hsize + py].cellsize; if (sx > tty->sx) sx = tty->sx; -- cgit From ff65e3754565f1d878c70257e96f6aea09c1c90e Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 11 Aug 2009 19:32:25 +0000 Subject: Drop the no_stop argument to tty_close and tty_free in favour of a flag in the tty struct. --- tty.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 33acb99d..1584444e 100644 --- a/tty.c +++ b/tty.c @@ -149,6 +149,8 @@ tty_start_tty(struct tty *tty) tty->rupper = UINT_MAX; tty->mode = MODE_CURSOR; + + tty->flags |= TTY_STARTED; } void @@ -156,6 +158,10 @@ tty_stop_tty(struct tty *tty) { struct winsize ws; + if (!(tty->flags & TTY_STARTED)) + return; + tty->flags &= ~TTY_STARTED; + /* * Be flexible about error handling and try not kill the server just * because the fd is invalid. Things like ssh -t can easily leave us @@ -281,7 +287,7 @@ tty_get_acs(struct tty *tty, u_char ch) } void -tty_close(struct tty *tty, int no_stop) +tty_close(struct tty *tty) { if (tty->fd == -1) return; @@ -291,8 +297,7 @@ tty_close(struct tty *tty, int no_stop) tty->log_fd = -1; } - if (!no_stop) - tty_stop_tty(tty); + tty_stop_tty(tty); tty_term_free(tty->term); tty_keys_free(tty); @@ -305,9 +310,9 @@ tty_close(struct tty *tty, int no_stop) } void -tty_free(struct tty *tty, int no_stop) +tty_free(struct tty *tty) { - tty_close(tty, no_stop); + tty_close(tty); if (tty->path != NULL) xfree(tty->path); -- cgit From 4ec8ade11c23eec4b652cdd7ea47ddf346b7be93 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 11 Aug 2009 20:29:04 +0000 Subject: Add a TTY_OPENED flag and tidy a little. --- tty.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 1584444e..1da0c2ff 100644 --- a/tty.c +++ b/tty.c @@ -80,8 +80,11 @@ tty_open(struct tty *tty, const char *overrides, char **cause) tty->log_fd = -1; tty->term = tty_term_find(tty->termname, tty->fd, overrides, cause); - if (tty->term == NULL) - goto error; + if (tty->term == NULL) { + tty_close(tty); + return (-1); + } + tty->flags |= TTY_OPENED; tty->in = buffer_create(BUFSIZ); tty->out = buffer_create(BUFSIZ); @@ -95,12 +98,6 @@ tty_open(struct tty *tty, const char *overrides, char **cause) tty_fill_acs(tty); return (0); - -error: - close(tty->fd); - tty->fd = -1; - - return (-1); } void @@ -289,9 +286,6 @@ tty_get_acs(struct tty *tty, u_char ch) void tty_close(struct tty *tty) { - if (tty->fd == -1) - return; - if (tty->log_fd != -1) { close(tty->log_fd); tty->log_fd = -1; @@ -299,14 +293,20 @@ tty_close(struct tty *tty) tty_stop_tty(tty); - tty_term_free(tty->term); - tty_keys_free(tty); + if (tty->flags & TTY_OPENED) { + tty_term_free(tty->term); + tty_keys_free(tty); + + buffer_destroy(tty->in); + buffer_destroy(tty->out); - close(tty->fd); - tty->fd = -1; + tty->flags &= ~TTY_OPENED; + } - buffer_destroy(tty->in); - buffer_destroy(tty->out); + if (tty->fd != -1) { + close(tty->fd); + tty->fd = -1; + } } void -- cgit From 4310282a4c52f1885ae2eb80b106c9c03564a0b8 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 11 Aug 2009 21:28:11 +0000 Subject: Have the client pass its stdin fd to the server when identifying itself and have the server use that rather than reopening the tty. If the fd isn't given, use the old behaviour (so no need for a version change). This allows tmux to be used as the shell, so also change so that when working out the command to execute if default-command is empty (the default), tmux will try not execute itself. --- tty.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 1da0c2ff..d850347a 100644 --- a/tty.c +++ b/tty.c @@ -45,9 +45,11 @@ void tty_cell(struct tty *, const struct grid_cell *, const struct grid_utf8 *); void -tty_init(struct tty *tty, char *path, char *term) +tty_init(struct tty *tty, int fd, char *path, char *term) { tty->path = xstrdup(path); + tty->fd = fd; + if (term == NULL || *term == '\0') tty->termname = xstrdup("unknown"); else @@ -59,12 +61,14 @@ tty_init(struct tty *tty, char *path, char *term) int tty_open(struct tty *tty, const char *overrides, char **cause) { - int mode; + int mode; - tty->fd = open(tty->path, O_RDWR|O_NONBLOCK); if (tty->fd == -1) { - xasprintf(cause, "%s: %s", tty->path, strerror(errno)); - return (-1); + tty->fd = open(tty->path, O_RDWR|O_NONBLOCK); + if (tty->fd == -1) { + xasprintf(cause, "%s: %s", tty->path, strerror(errno)); + return (-1); + } } if ((mode = fcntl(tty->fd, F_GETFL)) == -1) -- cgit From e0a19abb99aebcee544c451ff5e99f6a59d42d0c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 11 Aug 2009 22:34:17 +0000 Subject: Initialise log_fd to -1, prevents spurious disconnection of the client when it ends up as fd 0 (likely if the server is started with "tmux start"). Also add some extra debugging messages to server.c. --- tty.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index d850347a..c6904409 100644 --- a/tty.c +++ b/tty.c @@ -49,6 +49,7 @@ tty_init(struct tty *tty, int fd, char *path, char *term) { tty->path = xstrdup(path); tty->fd = fd; + tty->log_fd = -1; if (term == NULL || *term == '\0') tty->termname = xstrdup("unknown"); -- cgit From bc497dbb92268004e33c4f1deb09d3cbbeaa48a0 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 12 Aug 2009 09:41:59 +0000 Subject: A tty context must not be modified as it may be reused to update multiple clients, so make it const. Also fix an actual modification which caused a hang when a session was connected to multiple terminals at least one of which was missing ich/ich1. --- tty.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index c6904409..1c985dcc 100644 --- a/tty.c +++ b/tty.c @@ -38,7 +38,7 @@ void tty_attributes(struct tty *, const struct grid_cell *); void tty_attributes_fg(struct tty *, const struct grid_cell *); void tty_attributes_bg(struct tty *, const struct grid_cell *); -void tty_redraw_region(struct tty *, struct tty_ctx *); +void tty_redraw_region(struct tty *, const struct tty_ctx *); void tty_emulate_repeat( struct tty *, enum tty_code_code, enum tty_code_code, u_int); void tty_cell(struct tty *, @@ -461,7 +461,7 @@ tty_emulate_repeat( * width of the terminal. */ void -tty_redraw_region(struct tty *tty, struct tty_ctx *ctx) +tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; @@ -532,7 +532,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) } void -tty_write(void (*cmdfn)(struct tty *, struct tty_ctx *), struct tty_ctx *ctx) +tty_write(void (*cmdfn)( + struct tty *, const struct tty_ctx *), const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct client *c; @@ -563,10 +564,11 @@ tty_write(void (*cmdfn)(struct tty *, struct tty_ctx *), struct tty_ctx *ctx) } void -tty_cmd_insertcharacter(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; + u_int i; if (wp->xoff != 0 || screen_size_x(s) < tty->sx) { tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); @@ -581,14 +583,14 @@ tty_cmd_insertcharacter(struct tty *tty, struct tty_ctx *ctx) tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num); else { tty_putcode(tty, TTYC_SMIR); - while (ctx->num-- > 0) + for (i = 0; i < ctx->num; i++) tty_putc(tty, ' '); tty_putcode(tty, TTYC_RMIR); } } void -tty_cmd_deletecharacter(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; @@ -605,7 +607,7 @@ tty_cmd_deletecharacter(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_insertline(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; @@ -625,7 +627,7 @@ tty_cmd_insertline(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_deleteline(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; @@ -645,7 +647,7 @@ tty_cmd_deleteline(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_clearline(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; @@ -664,7 +666,7 @@ tty_cmd_clearline(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_clearendofline(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; @@ -683,7 +685,7 @@ tty_cmd_clearendofline(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_clearstartofline(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; u_int i; @@ -701,7 +703,7 @@ tty_cmd_clearstartofline(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_reverseindex(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; @@ -723,7 +725,7 @@ tty_cmd_reverseindex(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_linefeed(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; @@ -745,7 +747,7 @@ tty_cmd_linefeed(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_clearendofscreen(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; @@ -780,7 +782,7 @@ tty_cmd_clearendofscreen(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_clearstartofscreen(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; @@ -809,7 +811,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_clearscreen(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; @@ -838,7 +840,7 @@ tty_cmd_clearscreen(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_alignmenttest(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; @@ -856,7 +858,7 @@ tty_cmd_alignmenttest(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_cell(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; @@ -866,7 +868,7 @@ tty_cmd_cell(struct tty *tty, struct tty_ctx *ctx) } void -tty_cmd_utf8character(struct tty *tty, struct tty_ctx *ctx) +tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx) { u_char *ptr = ctx->ptr; size_t i; -- cgit From 5cf994856ffcbd95b1821e687dc271c6f81b6e35 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 14 Aug 2009 08:53:52 +0000 Subject: Send SGR0 when initialising the screen. Fixes problems on terminals with BCE (like putty) if the background colours is non-default when tmux starts. May also fix problems when resuming a suspended tmux. --- tty.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 1c985dcc..0428a0cc 100644 --- a/tty.c +++ b/tty.c @@ -134,6 +134,9 @@ tty_start_tty(struct tty *tty) tty_putcode(tty, TTYC_SMCUP); + tty_putcode(tty, TTYC_SGR0); + memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell); + tty_putcode(tty, TTYC_SMKX); tty_putcode(tty, TTYC_ENACS); tty_putcode(tty, TTYC_CLEAR); @@ -142,8 +145,6 @@ tty_start_tty(struct tty *tty) if (tty_term_has(tty->term, TTYC_KMOUS)) tty_puts(tty, "\033[?1000l"); - memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell); - tty->cx = UINT_MAX; tty->cy = UINT_MAX; -- cgit From 926b52b6002164b4bc82624674d488e7fe1e42c2 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 21 Aug 2009 12:29:59 +0000 Subject: Emulate dch/dch1 if missing by redrawing the entire line. --- tty.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 0428a0cc..158bd527 100644 --- a/tty.c +++ b/tty.c @@ -596,7 +596,9 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - if (wp->xoff != 0 || screen_size_x(s) < tty->sx) { + if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + (!tty_term_has(tty->term, TTYC_DCH) && + !tty_term_has(tty->term, TTYC_DCH1))) { tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); return; } @@ -604,7 +606,9 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); - tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ctx->num); + if (tty_term_has(tty->term, TTYC_DCH) || + tty_term_has(tty->term, TTYC_DCH1)) + tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ctx->num); } void -- cgit From 04319964b95304138dbe5cbce0b97222769d0c17 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 31 Aug 2009 20:46:19 +0000 Subject: Add a new display-panes command, with two options (display-panes-colour and display-panes-time), which displays a visual indication of the number of each pane. --- tty.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 158bd527..de6b4d0b 100644 --- a/tty.c +++ b/tty.c @@ -34,7 +34,6 @@ void tty_raw(struct tty *, const char *); int tty_try_256(struct tty *, u_char, const char *); int tty_try_88(struct tty *, u_char, const char *); -void tty_attributes(struct tty *, const struct grid_cell *); void tty_attributes_fg(struct tty *, const struct grid_cell *); void tty_attributes_bg(struct tty *, const struct grid_cell *); -- cgit From 372a8cb1d9c4306f74b592660b4ce394dff3e31d Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 10 Sep 2009 17:16:24 +0000 Subject: Permit options such as status-bg to be configured using the entire 256 colour palette by setting "colour0" to "colour255". --- tty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index de6b4d0b..3d2d17d3 100644 --- a/tty.c +++ b/tty.c @@ -512,7 +512,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) if (screen_check_selection(s, i, py)) { memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc); tmpgc.data = gc->data; - tmpgc.flags = gc->flags; + tmpgc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); + tmpgc.flags |= s->sel.cell.flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); tty_cell(tty, &tmpgc, gu); } else tty_cell(tty, gc, gu); -- cgit From 0a9005678da04b1e7783d26b02041e3973f26127 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 22 Sep 2009 19:11:52 +0000 Subject: Be more careful about what flags are cleared when opening the terminal, otherwise the opened/started flags are cleared and the terminal never released. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 3d2d17d3..b0810219 100644 --- a/tty.c +++ b/tty.c @@ -93,7 +93,7 @@ tty_open(struct tty *tty, const char *overrides, char **cause) tty->in = buffer_create(BUFSIZ); tty->out = buffer_create(BUFSIZ); - tty->flags &= TTY_UTF8; + tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE|TTY_ESCAPE); tty_start_tty(tty); -- cgit From 64caf59e84c3ae1c06773bb8ec91165eeedabe6d Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 23 Sep 2009 06:05:02 +0000 Subject: Don't attempt to open() the tty path, rely on the client sending its stdin fd with imsg and fatal if it doesn't, then set the FD_CLOEXEC flag in tty_init instead of tty_open to prevent them leaking into child processes if any are created between the two calls. This bumps the protocol version, so the tmux server should be killed before upgrading. --- tty.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index b0810219..574e9a7b 100644 --- a/tty.c +++ b/tty.c @@ -44,16 +44,31 @@ void tty_cell(struct tty *, const struct grid_cell *, const struct grid_utf8 *); void -tty_init(struct tty *tty, int fd, char *path, char *term) +tty_init(struct tty *tty, int fd, char *term) { - tty->path = xstrdup(path); - tty->fd = fd; + int mode; + char *path; + + memset(tty, 0, sizeof *tty); tty->log_fd = -1; if (term == NULL || *term == '\0') tty->termname = xstrdup("unknown"); else tty->termname = xstrdup(term); + + if ((mode = fcntl(fd, F_GETFL)) == -1) + fatal("fcntl failed"); + if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1) + fatal("fcntl failed"); + if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + fatal("fcntl failed"); + tty->fd = fd; + + if ((path = ttyname(fd)) == NULL) + fatalx("ttyname failed"); + tty->path = xstrdup(path); + tty->flags = 0; tty->term_flags = 0; } @@ -61,28 +76,15 @@ tty_init(struct tty *tty, int fd, char *path, char *term) int tty_open(struct tty *tty, const char *overrides, char **cause) { - int mode; + int fd; - if (tty->fd == -1) { - tty->fd = open(tty->path, O_RDWR|O_NONBLOCK); - if (tty->fd == -1) { - xasprintf(cause, "%s: %s", tty->path, strerror(errno)); - return (-1); - } + if (debug_level > 3) { + fd = open("tmux.out", O_WRONLY|O_CREAT|O_TRUNC, 0644); + if (fd != -1 && fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + fatal("fcntl failed"); + tty->log_fd = fd; } - if ((mode = fcntl(tty->fd, F_GETFL)) == -1) - fatal("fcntl failed"); - if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1) - fatal("fcntl failed"); - if (fcntl(tty->fd, F_SETFD, FD_CLOEXEC) == -1) - fatal("fcntl failed"); - - if (debug_level > 3) - tty->log_fd = open("tmux.out", O_WRONLY|O_CREAT|O_TRUNC, 0644); - else - tty->log_fd = -1; - tty->term = tty_term_find(tty->termname, tty->fd, overrides, cause); if (tty->term == NULL) { tty_close(tty); -- cgit From 962fa20b36cc6d38d9a44612441f3f706c29b71e Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 23 Sep 2009 06:12:58 +0000 Subject: Trim some code by moving the ioctl(TIOCGWINSZ) after SIGWINCH from the client into the server. This is another (the second of four) protocol version changes coming this morning, so again the server should be killed before upgrading. --- tty.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 574e9a7b..12535f94 100644 --- a/tty.c +++ b/tty.c @@ -73,6 +73,27 @@ tty_init(struct tty *tty, int fd, char *term) tty->term_flags = 0; } +void +tty_resize(struct tty *tty) +{ + struct winsize ws; + + if (ioctl(tty->fd, TIOCGWINSZ, &ws) != -1) { + tty->sx = ws.ws_col; + tty->sy = ws.ws_row; + } + if (tty->sx == 0) + tty->sx = 80; + if (tty->sy == 0) + tty->sy = 24; + + tty->cx = UINT_MAX; + tty->cy = UINT_MAX; + + tty->rupper = UINT_MAX; + tty->rlower = UINT_MAX; +} + int tty_open(struct tty *tty, const char *overrides, char **cause) { -- cgit From b01dcd79715d968cb39dc892215c2f6921d43974 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 23 Sep 2009 06:18:47 +0000 Subject: Remove the internal tmux locking and instead detach each client and run the command specified by a new option "lock-command" (by default "lock -np") in each client. This means each terminal has to be unlocked individually but simplifies the code and allows the system password to be used to unlock. Note that the set-password command is gone, so it will need to be removed from configuration files, and the -U command line flag has been removed. This is the third protocol version change so again it is best to stop the tmux server before upgrading. --- tty.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 12535f94..82cfac80 100644 --- a/tty.c +++ b/tty.c @@ -29,8 +29,6 @@ void tty_fill_acs(struct tty *); -void tty_raw(struct tty *, const char *); - int tty_try_256(struct tty *, u_char, const char *); int tty_try_88(struct tty *, u_char, const char *); -- cgit From 631a6182381f246c4c6aa9a200c744fcd5be015c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 23 Sep 2009 07:25:31 +0000 Subject: Don't die if the client is detaching (the tty has been closed) after waking up from locking. --- tty.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 82cfac80..2129747d 100644 --- a/tty.c +++ b/tty.c @@ -131,6 +131,9 @@ tty_start_tty(struct tty *tty) struct termios tio; int what; + if (tty->fd == -1) + return; + #if 0 tty_detect_utf8(tty); #endif -- cgit From 9200a0be7a515cd04c1a05d120002c73932cbf98 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 23 Sep 2009 12:03:30 +0000 Subject: Support -c like sh(1) to execute a command, useful when tmux is a login shell. Suggested by halex@. This includes another protocol version increase (the last for now) so again restart the tmux server before upgrading. --- tty.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 2129747d..774808db 100644 --- a/tty.c +++ b/tty.c @@ -44,7 +44,6 @@ void tty_cell(struct tty *, void tty_init(struct tty *tty, int fd, char *term) { - int mode; char *path; memset(tty, 0, sizeof *tty); @@ -55,10 +54,6 @@ tty_init(struct tty *tty, int fd, char *term) else tty->termname = xstrdup(term); - if ((mode = fcntl(fd, F_GETFL)) == -1) - fatal("fcntl failed"); - if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1) - fatal("fcntl failed"); if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) fatal("fcntl failed"); tty->fd = fd; @@ -129,11 +124,16 @@ void tty_start_tty(struct tty *tty) { struct termios tio; - int what; + int what, mode; if (tty->fd == -1) return; + if ((mode = fcntl(tty->fd, F_GETFL)) == -1) + fatal("fcntl failed"); + if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1) + fatal("fcntl failed"); + #if 0 tty_detect_utf8(tty); #endif @@ -183,6 +183,7 @@ void tty_stop_tty(struct tty *tty) { struct winsize ws; + int mode; if (!(tty->flags & TTY_STARTED)) return; @@ -193,6 +194,10 @@ tty_stop_tty(struct tty *tty) * because the fd is invalid. Things like ssh -t can easily leave us * with a dead tty. */ + if ((mode = fcntl(tty->fd, F_GETFL)) == -1) + return; + if (fcntl(tty->fd, F_SETFL, mode & ~O_NONBLOCK) == -1) + return; if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1) return; if (tcsetattr(tty->fd, TCSANOW, &tty->tio) == -1) -- cgit From d5281848361ede97d871553b011a706457acabd0 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 9 Oct 2009 07:23:28 +0000 Subject: Be less aggressive about turning the cursor off, only explicitly turn it off when tmux is redrawing, otherwise leave in the state set by the application. --- tty.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 774808db..8dde904c 100644 --- a/tty.c +++ b/tty.c @@ -524,6 +524,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) const struct grid_utf8 *gu; u_int i, sx; + tty_update_mode(tty, tty->mode & ~MODE_CURSOR); + sx = screen_size_x(s); if (sx > s->grid->linedata[s->grid->hsize + py].cellsize) sx = s->grid->linedata[s->grid->hsize + py].cellsize; @@ -548,8 +550,10 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) tty_cell(tty, gc, gu); } - if (sx >= tty->sx) + if (sx >= tty->sx) { + tty_update_mode(tty, tty->mode); return; + } tty_reset(tty); tty_cursor(tty, sx, py, ox, oy); @@ -559,6 +563,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) for (i = sx; i < screen_size_x(s); i++) tty_putc(tty, ' '); } + tty_update_mode(tty, tty->mode); } void @@ -587,7 +592,6 @@ tty_write(void (*cmdfn)( if (c->session->curw->window == wp->window) { if (c->tty.flags & TTY_FREEZE || c->tty.term == NULL) continue; - tty_update_mode(&c->tty, c->tty.mode & ~MODE_CURSOR); cmdfn(&c->tty, ctx); } } -- cgit From bf38a311daa8a8048974a401b88909aa56b25e19 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 9 Oct 2009 07:33:12 +0000 Subject: The UTF-8 detection idea doesn't work and I am reasonably happy with the current methods, so remove the (already #ifdef 0'd) code. --- tty.c | 81 ------------------------------------------------------------------- 1 file changed, 81 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 8dde904c..c61fd6b0 100644 --- a/tty.c +++ b/tty.c @@ -134,10 +134,6 @@ tty_start_tty(struct tty *tty) if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1) fatal("fcntl failed"); -#if 0 - tty_detect_utf8(tty); -#endif - if (tcgetattr(tty->fd, &tty->tio) != 0) fatal("tcgetattr failed"); memcpy(&tio, &tty->tio, sizeof tio); @@ -216,83 +212,6 @@ tty_stop_tty(struct tty *tty) tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); } -#if 0 -void -tty_detect_utf8(struct tty *tty) -{ - struct pollfd pfd; - char buf[7]; - size_t len; - ssize_t n; - int nfds; - struct termios tio, old_tio; - int what; - - if (tty->flags & TTY_UTF8) - return; - - /* - * If the terminal looks reasonably likely to support this, try to - * write a three-byte UTF-8 wide character to the terminal, then read - * the cursor position. - * - * XXX This entire function is a hack. - */ - - /* Check if the terminal looks sort of vt100. */ - if (strstr(tty_term_string(tty->term, TTYC_CLEAR), "[2J") == NULL || - strstr(tty_term_string(tty->term, TTYC_CUP), "H") == NULL) - return; - - if (tcgetattr(tty->fd, &old_tio) != 0) - fatal("tcgetattr failed"); - cfmakeraw(&tio); - if (tcsetattr(tty->fd, TCSANOW, &tio) != 0) - fatal("tcsetattr failed"); - - what = 0; - if (ioctl(tty->fd, TIOCFLUSH, &what) != 0) - fatal("ioctl(TIOCFLUSH)"); - -#define UTF8_TEST_DATA "\033[H\357\277\246\033[6n" - if (write(tty->fd, UTF8_TEST_DATA, (sizeof UTF8_TEST_DATA) - 1) == -1) - fatal("write failed"); -#undef UTF8_TEST_DATA - - len = 0; - for (;;) { - pfd.fd = tty->fd; - pfd.events = POLLIN; - - nfds = poll(&pfd, 1, 500); - if (nfds == -1) { - if (errno == EAGAIN || errno == EINTR) - continue; - fatal("poll failed"); - } - if (nfds == 0) - break; - if (pfd.revents & (POLLERR|POLLNVAL|POLLHUP)) - break; - if (!(pfd.revents & POLLIN)) - continue; - - if ((n = read(tty->fd, buf + len, 1)) != 1) - break; - buf[++len] = '\0'; - - if (len == (sizeof buf) - 1) { - if (strcmp(buf, "\033[1;3R") == 0) - tty->flags |= TTY_UTF8; - break; - } - } - - if (tcsetattr(tty->fd, TCSANOW, &old_tio) != 0) - fatal("tcsetattr failed"); -} -#endif - void tty_fill_acs(struct tty *tty) { -- cgit From 3a20a05a49bdf7cfd7d2131c6f31a2ebf76ad4e5 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 10 Oct 2009 10:36:46 +0000 Subject: There is no point setting the scroll region up for line feeds unless scrolling is actually going to happen, so don't. --- tty.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index c61fd6b0..7b0454f7 100644 --- a/tty.c +++ b/tty.c @@ -693,11 +693,10 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) return; } - tty_reset(tty); - - tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); if (ctx->ocy == ctx->orlower) { + tty_reset(tty); + tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); tty_putc(tty, '\n'); } -- cgit From 0a2a3544993a569e277f893ddac610313a42bfde Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 11 Oct 2009 22:35:10 +0000 Subject: Like linefeed, don't set the scroll region for reverse index unless it will be needed. While here, also tidy up a couple of long lines and remove an extraneous blank. --- tty.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 7b0454f7..389fe11f 100644 --- a/tty.c +++ b/tty.c @@ -462,8 +462,10 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) if (screen_check_selection(s, i, py)) { memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc); tmpgc.data = gc->data; - tmpgc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); - tmpgc.flags |= s->sel.cell.flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); + tmpgc.flags = gc->flags & + ~(GRID_FLAG_FG256|GRID_FLAG_BG256); + tmpgc.flags |= s->sel.cell.flags & + (GRID_FLAG_FG256|GRID_FLAG_BG256); tty_cell(tty, &tmpgc, gu); } else tty_cell(tty, gc, gu); @@ -671,11 +673,9 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) return; } - tty_reset(tty); - - tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); - if (ctx->ocy == ctx->orupper) { + tty_reset(tty); + tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); tty_cursor(tty, ctx->ocx, ctx->orupper, wp->xoff, wp->yoff); tty_putcode(tty, TTYC_RI); } @@ -693,7 +693,6 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) return; } - if (ctx->ocy == ctx->orlower) { tty_reset(tty); tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); -- cgit From f05b32f7adc7de4dac3afa59ce91986202f17769 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 12 Oct 2009 09:09:35 +0000 Subject: Cleanup: use two functions for region setting, one for absolute and one inside pane. --- tty.c | 51 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 389fe11f..fd271335 100644 --- a/tty.c +++ b/tty.c @@ -579,7 +579,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); + tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ctx->num); @@ -599,7 +599,7 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); + tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ctx->num); @@ -675,8 +675,10 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy == ctx->orupper) { tty_reset(tty); - tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); + + tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor(tty, ctx->ocx, ctx->orupper, wp->xoff, wp->yoff); + tty_putcode(tty, TTYC_RI); } } @@ -695,8 +697,10 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy == ctx->orlower) { tty_reset(tty); - tty_region(tty, ctx->orupper, ctx->orlower, wp->yoff); + + tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); + tty_putc(tty, '\n'); } } @@ -710,8 +714,9 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_region(tty, 0, screen_size_y(s) - 1, wp->yoff); + tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); + if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { tty_putcode(tty, TTYC_EL); @@ -745,8 +750,9 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_region(tty, 0, screen_size_y(s) - 1, wp->yoff); + tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor(tty, 0, 0, wp->xoff, wp->yoff); + if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { for (i = 0; i < ctx->ocy; i++) { @@ -774,8 +780,9 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_region(tty, 0, screen_size_y(s) - 1, wp->yoff); + tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor(tty, 0, 0, wp->xoff, wp->yoff); + if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { for (i = 0; i < screen_size_y(s); i++) { @@ -803,7 +810,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_region(tty, 0, screen_size_y(s) - 1, wp->yoff); + tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); for (j = 0; j < screen_size_y(s); j++) { tty_cursor(tty, 0, j, wp->xoff, wp->yoff); @@ -887,17 +894,29 @@ tty_reset(struct tty *tty) } void -tty_region(struct tty *tty, u_int rupper, u_int rlower, u_int oy) +tty_region_pane( + struct tty *tty, const struct tty_ctx *ctx, u_int rupper, u_int rlower) +{ + struct window_pane *wp = ctx->wp; + + tty_region_absolute(tty, wp->yoff + rupper, wp->yoff + rlower); +} + +void +tty_region_absolute(struct tty *tty, u_int rupper, u_int rlower) { + if (tty->rlower == rlower && tty->rupper == rupper) + return; if (!tty_term_has(tty->term, TTYC_CSR)) return; - if (tty->rlower != oy + rlower || tty->rupper != oy + rupper) { - tty->rlower = oy + rlower; - tty->rupper = oy + rupper; - tty->cx = 0; - tty->cy = 0; - tty_putcode2(tty, TTYC_CSR, tty->rupper, tty->rlower); - } + + tty->rupper = rupper; + tty->rlower = rlower; + + tty->cx = 0; + tty->cy = 0; + + tty_putcode2(tty, TTYC_CSR, tty->rupper, tty->rlower); } void -- cgit From 972a6f565660a7ca5c0307c1085825a254fba20e Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 12 Oct 2009 09:16:59 +0000 Subject: _absolute is redundant, just use tty_region. --- tty.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index fd271335..bddb83e3 100644 --- a/tty.c +++ b/tty.c @@ -893,17 +893,19 @@ tty_reset(struct tty *tty) memcpy(gc, &grid_default_cell, sizeof *gc); } +/* Set region inside pane. */ void tty_region_pane( struct tty *tty, const struct tty_ctx *ctx, u_int rupper, u_int rlower) { struct window_pane *wp = ctx->wp; - tty_region_absolute(tty, wp->yoff + rupper, wp->yoff + rlower); + tty_region(tty, wp->yoff + rupper, wp->yoff + rlower); } +/* Set region at absolute position. */ void -tty_region_absolute(struct tty *tty, u_int rupper, u_int rlower) +tty_region(struct tty *tty, u_int rupper, u_int rlower) { if (tty->rlower == rlower && tty->rupper == rupper) return; -- cgit From 762459954f1b8f00f93780212053288d6096a611 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 12 Oct 2009 09:29:58 +0000 Subject: Similarly add a tty_cursor_pane function to tidy up most of the calls. --- tty.c | 66 ++++++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 28 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index bddb83e3..f7ef8c0d 100644 --- a/tty.c +++ b/tty.c @@ -451,7 +451,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) if (sx > tty->sx) sx = tty->sx; - tty_cursor(tty, 0, py, ox, oy); + tty_cursor(tty, ox, oy + py); for (i = 0; i < sx; i++) { gc = grid_view_peek_cell(s->grid, i, py); @@ -477,7 +477,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) } tty_reset(tty); - tty_cursor(tty, sx, py, ox, oy); + tty_cursor(tty, ox + sx, oy + py); if (screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); else { @@ -532,7 +532,8 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); + if (tty_term_has(tty->term, TTYC_ICH) || tty_term_has(tty->term, TTYC_ICH1)) tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num); @@ -559,7 +560,8 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); + if (tty_term_has(tty->term, TTYC_DCH) || tty_term_has(tty->term, TTYC_DCH1)) tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ctx->num); @@ -580,8 +582,8 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ctx->num); } @@ -600,8 +602,8 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ctx->num); } @@ -614,7 +616,8 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_cursor(tty, 0, ctx->ocy, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, 0, ctx->ocy); + if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { tty_putcode(tty, TTYC_EL); @@ -633,7 +636,8 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); + if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); @@ -652,10 +656,10 @@ tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); if (wp->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) { - tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); tty_putcode(tty, TTYC_EL1); } else { - tty_cursor(tty, 0, ctx->ocy, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, 0, ctx->ocy); for (i = 0; i < ctx->ocx + 1; i++) tty_putc(tty, ' '); } @@ -677,7 +681,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); - tty_cursor(tty, ctx->ocx, ctx->orupper, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper); tty_putcode(tty, TTYC_RI); } @@ -699,7 +703,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); - tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); tty_putc(tty, '\n'); } @@ -715,13 +719,13 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); - tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { tty_putcode(tty, TTYC_EL); if (ctx->ocy != screen_size_y(s) - 1) { - tty_cursor(tty, 0, ctx->ocy + 1, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1); for (i = ctx->ocy + 1; i < screen_size_y(s); i++) { tty_putcode(tty, TTYC_EL); if (i == screen_size_y(s) - 1) @@ -734,7 +738,7 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) for (i = ctx->ocx; i < screen_size_x(s); i++) tty_putc(tty, ' '); for (j = ctx->ocy; j < screen_size_y(s); j++) { - tty_cursor(tty, 0, j, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, 0, j); for (i = 0; i < screen_size_x(s); i++) tty_putc(tty, ' '); } @@ -751,7 +755,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); - tty_cursor(tty, 0, 0, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, 0, 0); if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { @@ -762,7 +766,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) } } else { for (j = 0; j < ctx->ocy; j++) { - tty_cursor(tty, 0, j, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, 0, j); for (i = 0; i < screen_size_x(s); i++) tty_putc(tty, ' '); } @@ -781,7 +785,7 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); - tty_cursor(tty, 0, 0, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, 0, 0); if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { @@ -794,7 +798,7 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) } } else { for (j = 0; j < screen_size_y(s); j++) { - tty_cursor(tty, 0, j, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, 0, j); for (i = 0; i < screen_size_x(s); i++) tty_putc(tty, ' '); } @@ -813,7 +817,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); for (j = 0; j < screen_size_y(s); j++) { - tty_cursor(tty, 0, j, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, 0, j); for (i = 0; i < screen_size_x(s); i++) tty_putc(tty, 'E'); } @@ -822,9 +826,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; - - tty_cursor(tty, ctx->ocx, ctx->ocy, wp->xoff, wp->yoff); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); tty_cell(tty, ctx->cell, ctx->utf8); } @@ -922,14 +924,22 @@ tty_region(struct tty *tty, u_int rupper, u_int rlower) } void -tty_cursor(struct tty *tty, u_int cx, u_int cy, u_int ox, u_int oy) +tty_cursor_pane(struct tty *tty, const struct tty_ctx *ctx, u_int cx, u_int cy) +{ + struct window_pane *wp = ctx->wp; + + tty_cursor(tty, wp->xoff + cx, wp->yoff + cy); +} + +void +tty_cursor(struct tty *tty, u_int cx, u_int cy) { - if (ox + cx == 0 && tty->cx != 0 && tty->cy == oy + cy) { + if (cx == 0 && tty->cx != 0 && tty->cy == cy) { tty->cx = 0; tty_putc(tty, '\r'); - } else if (tty->cx != ox + cx || tty->cy != oy + cy) { - tty->cx = ox + cx; - tty->cy = oy + cy; + } else if (tty->cx != cx || tty->cy != cy) { + tty->cx = cx; + tty->cy = cy; tty_putcode2(tty, TTYC_CUP, tty->cy, tty->cx); } } -- cgit From 687c4a9fabbd1f6a2b7c8ae9050f087c13565f1b Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 12 Oct 2009 13:01:18 +0000 Subject: Use relative cursor movement instead of absolute when possible and when supported by the terminal to reduce the size of the output data (generally about 10-20%). --- tty.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 114 insertions(+), 7 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index f7ef8c0d..4172e38c 100644 --- a/tty.c +++ b/tty.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -916,13 +917,14 @@ tty_region(struct tty *tty, u_int rupper, u_int rlower) tty->rupper = rupper; tty->rlower = rlower; - + tty->cx = 0; tty->cy = 0; tty_putcode2(tty, TTYC_CSR, tty->rupper, tty->rlower); } +/* Move cursor inside pane. */ void tty_cursor_pane(struct tty *tty, const struct tty_ctx *ctx, u_int cx, u_int cy) { @@ -931,17 +933,122 @@ tty_cursor_pane(struct tty *tty, const struct tty_ctx *ctx, u_int cx, u_int cy) tty_cursor(tty, wp->xoff + cx, wp->yoff + cy); } +/* Move cursor to absolute position. */ void tty_cursor(struct tty *tty, u_int cx, u_int cy) { - if (cx == 0 && tty->cx != 0 && tty->cy == cy) { - tty->cx = 0; + struct tty_term *term = tty->term; + u_int thisx, thisy; + int change; + + if (cx > tty->sx - 1) + cx = tty->sx - 1; + + thisx = tty->cx; + if (thisx > tty->sx - 1) + thisx = tty->sx - 1; + thisy = tty->cy; + + /* No change. */ + if (cx == thisx && cy == thisy) + return; + + /* Move to home position (0, 0). */ + if (cx == 0 && cy == 0 && tty_term_has(term, TTYC_HOME)) { + tty_putcode(tty, TTYC_HOME); + goto out; + } + + /* Zero on the next line. */ + if (cx == 0 && cy == thisy + 1) { tty_putc(tty, '\r'); - } else if (tty->cx != cx || tty->cy != cy) { - tty->cx = cx; - tty->cy = cy; - tty_putcode2(tty, TTYC_CUP, tty->cy, tty->cx); + tty_putc(tty, '\n'); + goto out; + } + + /* Row staying the same. */ + if (cy == thisy) { + /* To left edge. */ + if (cx == 0) { + tty_putc(tty, '\r'); + goto out; + } + + /* One to the left. */ + if (cx == thisx - 1 && tty_term_has(term, TTYC_CUB1)) { + tty_putcode(tty, TTYC_CUB1); + goto out; + } + + /* One to the right. */ + if (cx == thisx + 1 && tty_term_has(term, TTYC_CUF1)) { + tty_putcode(tty, TTYC_CUF1); + goto out; + } + + /* Calculate difference. */ + change = thisx - cx; /* +ve left, -ve right */ + + /* + * Use HPA if change is larger than absolute, otherwise move + * the cursor with CUB/CUF. + */ + if (abs(change) > cx && tty_term_has(term, TTYC_HPA)) { + tty_putcode1(tty, TTYC_HPA, cx); + goto out; + } else if (change > 0 && tty_term_has(term, TTYC_CUB)) { + tty_putcode1(tty, TTYC_CUB, change); + goto out; + } else if (change < 0 && tty_term_has(term, TTYC_CUF)) { + tty_putcode1(tty, TTYC_CUF, -change); + goto out; + } + } + + /* Column staying the same. */ + if (cx == thisx ) { + /* One above. */ + if (cy != tty->rupper && + cy == thisy - 1 && tty_term_has(term, TTYC_CUU1)) { + tty_putcode(tty, TTYC_CUU1); + goto out; + } + + /* One below. */ + if (cy != tty->rlower && + cy == thisy + 1 && tty_term_has(term, TTYC_CUD1)) { + tty_putcode(tty, TTYC_CUD1); + goto out; + } + + /* Calculate difference. */ + change = thisy - cy; /* +ve up, -ve down */ + + /* + * Use VPA if change is larger than absolute or if this change + * would cross the scroll region, otherwise use CUU/CUD. + */ + if ((abs(change) > cy || + (change < 0 && cy - change > tty->rlower) || + (change > 0 && cy - change < tty->rupper)) && + tty_term_has(term, TTYC_VPA)) { + tty_putcode1(tty, TTYC_VPA, cy); + goto out; + } else if (change > 0 && tty_term_has(term, TTYC_CUU)) { + tty_putcode1(tty, TTYC_CUU, change); + goto out; + } else if (change < 0 && tty_term_has(term, TTYC_CUD)) { + tty_putcode1(tty, TTYC_CUD, -change); + goto out; + } } + + /* Absolute movement. */ + tty_putcode2(tty, TTYC_CUP, cy, cx); + +out: + tty->cx = cx; + tty->cy = cy; } void -- cgit From 0aab5811ca1d249b5c087241f77fbe21a6a1d31d Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 12 Oct 2009 14:54:19 +0000 Subject: Use absolute movement if right at the end of the line as it isn't a reliable place to move from relatively. --- tty.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 4172e38c..665d0871 100644 --- a/tty.c +++ b/tty.c @@ -945,14 +945,16 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy) cx = tty->sx - 1; thisx = tty->cx; - if (thisx > tty->sx - 1) - thisx = tty->sx - 1; thisy = tty->cy; /* No change. */ if (cx == thisx && cy == thisy) return; + /* Very end of the line, just use absolute movement. */ + if (thisx > tty->sx - 1) + goto absolute; + /* Move to home position (0, 0). */ if (cx == 0 && cy == 0 && tty_term_has(term, TTYC_HOME)) { tty_putcode(tty, TTYC_HOME); @@ -1043,6 +1045,7 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy) } } +absolute: /* Absolute movement. */ tty_putcode2(tty, TTYC_CUP, cy, cx); -- cgit From eb9826f65d5584bc791cb35eb91ab6a5894b888c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 12 Oct 2009 16:37:43 +0000 Subject: If the vertical cursor movement crosses the scroll region, CUU and CUD shouldn't be used even if VPA isn't present - in that case CUP should be used. --- tty.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 665d0871..29c84832 100644 --- a/tty.c +++ b/tty.c @@ -1027,15 +1027,16 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy) change = thisy - cy; /* +ve up, -ve down */ /* - * Use VPA if change is larger than absolute or if this change + * Try to use VPA if change is larger than absolute or if this change * would cross the scroll region, otherwise use CUU/CUD. */ - if ((abs(change) > cy || + if (abs(change) > cy || (change < 0 && cy - change > tty->rlower) || - (change > 0 && cy - change < tty->rupper)) && - tty_term_has(term, TTYC_VPA)) { - tty_putcode1(tty, TTYC_VPA, cy); - goto out; + (change > 0 && cy - change < tty->rupper)) { + if (tty_term_has(term, TTYC_VPA)) { + tty_putcode1(tty, TTYC_VPA, cy); + goto out; + } } else if (change > 0 && tty_term_has(term, TTYC_CUU)) { tty_putcode1(tty, TTYC_CUU, change); goto out; -- cgit From 693b3d03e66e5ab2f4c4e31b7d5d2c1629afbd8c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 12 Oct 2009 16:41:02 +0000 Subject: Don't run through the column unchanged case if the row was unchanged but there were no suitable optimisations, instead make it an else to fall through to absolute addressing. --- tty.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 29c84832..53e017bc 100644 --- a/tty.c +++ b/tty.c @@ -968,8 +968,12 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy) goto out; } - /* Row staying the same. */ + /* Moving column or row. */ if (cy == thisy) { + /* + * Moving column only, row staying the same. + */ + /* To left edge. */ if (cx == 0) { tty_putc(tty, '\r'); @@ -1005,10 +1009,11 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy) tty_putcode1(tty, TTYC_CUF, -change); goto out; } - } + } else if (cx == thisx) { + /* + * Moving row only, column staying the same. + */ - /* Column staying the same. */ - if (cx == thisx ) { /* One above. */ if (cy != tty->rupper && cy == thisy - 1 && tty_term_has(term, TTYC_CUU1)) { -- cgit From d7626cd9d766bdffb3f1dc729933a98c77379da2 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 12 Oct 2009 17:19:47 +0000 Subject: When drawing lines that have wrapped naturally, don't force a newline but permit them to wrap naturally again. This allows terminals that use this to guess where lines start and end for eg mouse selecting (like xterm) to work correctly. This was another long-standing issue raised by several people over the last while. Thanks to martynas@ for much testing. This was not trivial to get right so bringing it in for wider testing and adn to fix any further glitches in-tree. --- tty.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 53e017bc..866ee93c 100644 --- a/tty.c +++ b/tty.c @@ -327,9 +327,10 @@ tty_putc(struct tty *tty, u_char ch) if (tty->term->flags & TERM_EARLYWRAP) sx--; - if (tty->cx == sx) { - tty->cx = 0; - tty->cy++; + if (tty->cx >= sx) { + tty->cx = 1; + if (tty->cy != tty->rlower) + tty->cy++; } else tty->cx++; } @@ -440,6 +441,7 @@ void tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) { const struct grid_cell *gc; + struct grid_line *gl; struct grid_cell tmpgc; const struct grid_utf8 *gu; u_int i, sx; @@ -452,7 +454,17 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) if (sx > tty->sx) sx = tty->sx; - tty_cursor(tty, ox, oy + py); + /* + * Don't move the cursor to the start permission if it will wrap there + * itself; much the same as the conditions in tty_cmd_cell. + */ + gl = NULL; + if (py != 0) + gl = &s->grid->linedata[s->grid->hsize + py - 1]; + if (ox != 0 || (gl != NULL && !(gl->flags & GRID_LINE_WRAPPED)) || + tty->cy != oy + py - 1 || tty->cx < tty->sx) + tty_cursor(tty, ox, oy + py); + for (i = 0; i < sx; i++) { gc = grid_view_peek_cell(s->grid, i, py); @@ -827,7 +839,36 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) { - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); + struct window_pane *wp = ctx->wp; + struct screen *s = wp->screen; + struct grid_line *gl; + u_int wx, wy; + + tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); + + wx = ctx->ocx + wp->xoff; + wy = ctx->ocy + wp->yoff; + + /* + * If: + * + * - the line was wrapped: + * - the cursor is beyond the edge of the screen, + * - the desired position is at the left, + * - and either a) the desired next line is the one below the current + * or b) the current line is the bottom of the scroll region, + * + * Then just printing the next character will be enough to scroll into + * place, so don't do an explicit cursor move. + */ + gl = NULL; + if (ctx->ocy != 0) + gl = &s->grid->linedata[s->grid->hsize + ctx->ocy - 1]; + if (wy == 0 || (gl != NULL && !(gl->flags & GRID_LINE_WRAPPED)) || + tty->cx < tty->sx || /* not at edge of screen */ + wx != 0 || /* don't want 0 next */ + (wy != tty->cy + 1 && tty->cy != ctx->orlower + wp->yoff)) + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); tty_cell(tty, ctx->cell, ctx->utf8); } -- cgit From 4dcb5040a0bdf73ecbf504ed887600ec2f100d4c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 13 Oct 2009 00:44:16 +0000 Subject: Instead of using something sort of similar for both newline checks, use something the same. Doesn't fix the bug I'm looking for though :-/. --- tty.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 866ee93c..75721c63 100644 --- a/tty.c +++ b/tty.c @@ -461,8 +461,9 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) gl = NULL; if (py != 0) gl = &s->grid->linedata[s->grid->hsize + py - 1]; - if (ox != 0 || (gl != NULL && !(gl->flags & GRID_LINE_WRAPPED)) || - tty->cy != oy + py - 1 || tty->cx < tty->sx) + if (oy + py == 0 || (gl != NULL && !(gl->flags & GRID_LINE_WRAPPED)) || + tty->cx < tty->sx || ox != 0 || + (oy + py != tty->cy + 1 && tty->cy != s->rlower + oy)) tty_cursor(tty, ox, oy + py); for (i = 0; i < sx; i++) { -- cgit From 5d78371628a719d5d1f0e5a0ecc99b885f4e7d15 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 13 Oct 2009 08:37:15 +0000 Subject: Don't try to use \n across scroll region when doing \r\n either. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 75721c63..5bf9b6d3 100644 --- a/tty.c +++ b/tty.c @@ -1004,7 +1004,7 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy) } /* Zero on the next line. */ - if (cx == 0 && cy == thisy + 1) { + if (cx == 0 && cy == thisy + 1 && thisy != tty->rlower) { tty_putc(tty, '\r'); tty_putc(tty, '\n'); goto out; -- cgit From 70355021d8e8b83eaa3d947dc7a49b4eacff17fa Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 16 Oct 2009 19:09:40 +0000 Subject: When checking whether the region will scroll and the cursor position is thus unsuitable for using CUD/CUU, check the current cursor position not the target position. --- tty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 5bf9b6d3..53cd3362 100644 --- a/tty.c +++ b/tty.c @@ -1057,14 +1057,14 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy) */ /* One above. */ - if (cy != tty->rupper && + if (thisy != tty->rupper && cy == thisy - 1 && tty_term_has(term, TTYC_CUU1)) { tty_putcode(tty, TTYC_CUU1); goto out; } /* One below. */ - if (cy != tty->rlower && + if (thisy != tty->rlower && cy == thisy + 1 && tty_term_has(term, TTYC_CUD1)) { tty_putcode(tty, TTYC_CUD1); goto out; -- cgit From 43d62c1ae3846ba1b33d79349be367ed3b6763cf Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 17 Oct 2009 08:24:46 +0000 Subject: Instead of having a complicated check to see if the cursor is in the last position to avoid an explicit wrap, actually move it there. Some UTF-8 fixes to come. --- tty.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 53cd3362..37cff1fc 100644 --- a/tty.c +++ b/tty.c @@ -456,7 +456,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) /* * Don't move the cursor to the start permission if it will wrap there - * itself; much the same as the conditions in tty_cmd_cell. + * itself. */ gl = NULL; if (py != 0) @@ -842,33 +842,21 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - struct grid_line *gl; - u_int wx, wy; + u_int cx; tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); - wx = ctx->ocx + wp->xoff; - wy = ctx->ocy + wp->yoff; - /* - * If: - * - * - the line was wrapped: - * - the cursor is beyond the edge of the screen, - * - the desired position is at the left, - * - and either a) the desired next line is the one below the current - * or b) the current line is the bottom of the scroll region, - * - * Then just printing the next character will be enough to scroll into - * place, so don't do an explicit cursor move. + * Should the cursor be in the last cursor position ready for a natural + * wrap? If so - and it isn't - move to and rewrite the last cell. */ - gl = NULL; - if (ctx->ocy != 0) - gl = &s->grid->linedata[s->grid->hsize + ctx->ocy - 1]; - if (wy == 0 || (gl != NULL && !(gl->flags & GRID_LINE_WRAPPED)) || - tty->cx < tty->sx || /* not at edge of screen */ - wx != 0 || /* don't want 0 next */ - (wy != tty->cy + 1 && tty->cy != ctx->orlower + wp->yoff)) + if (ctx->ocx + wp->xoff > tty->sx - ctx->last_width) { + if (tty->cx < tty->sx) { + cx = screen_size_x(s) - ctx->last_width; + tty_cursor_pane(tty, ctx, cx, ctx->ocy); + tty_cell(tty, &ctx->last_cell, &ctx->last_utf8); + } + } else tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); tty_cell(tty, ctx->cell, ctx->utf8); -- cgit From daa26079ee82aed8a1eaf053ea3df5d2276eb472 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 17 Oct 2009 08:35:38 +0000 Subject: Always move the cursor position on !xenl terminals, since there is no invisible last cursor position. Also nuke an unused variable. --- tty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 37cff1fc..9f4fbc2e 100644 --- a/tty.c +++ b/tty.c @@ -850,7 +850,8 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) * Should the cursor be in the last cursor position ready for a natural * wrap? If so - and it isn't - move to and rewrite the last cell. */ - if (ctx->ocx + wp->xoff > tty->sx - ctx->last_width) { + if (!(tty->term->flags & TERM_EARLYWRAP) && + ctx->ocx + wp->xoff > tty->sx - ctx->last_width) { if (tty->cx < tty->sx) { cx = screen_size_x(s) - ctx->last_width; tty_cursor_pane(tty, ctx, cx, ctx->ocy); -- cgit From 387f4d42ccfb9aab1b8d5f10176dac2a3209c3fa Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 20 Oct 2009 16:32:23 +0000 Subject: Move the check for whether to force a line wrapper lower down into the tty code where it has access to the tty width, which is what should have been checked. --- tty.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 9f4fbc2e..93d61c0e 100644 --- a/tty.c +++ b/tty.c @@ -713,6 +713,14 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) return; } + /* + * If this line wrapped naturally (ctx->num is nonzero), don't do + * anything - the cursor can just be moved to the last cell and wrap + * naturally. + */ + if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP)) + return; + if (ctx->ocy == ctx->orlower) { tty_reset(tty); -- cgit From 62f234ce3b3fb10633f8bbb1d4159cd5c179345a Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 20 Oct 2009 17:33:33 +0000 Subject: UTF-8 combined character fixes. Thai can have treble combinations (1 x width=1 then 2 x width=0) so bump the UTF-8 cell data size to 9 and alter the code to allow this. Also break off the combining code into a separate function, handle any further combining beyond the buffer size by replacing the character with _s, and when redrawing the UTF-8 character don't assume the first part has just been printed, redraw the entire line. --- tty.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 93d61c0e..9ddffb95 100644 --- a/tty.c +++ b/tty.c @@ -874,14 +874,13 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx) { - u_char *ptr = ctx->ptr; - size_t i; + struct window_pane *wp = ctx->wp; - for (i = 0; i < UTF8_SIZE; i++) { - if (ptr[i] == 0xff) - break; - tty_putc(tty, ptr[i]); - } + /* + * Cannot rely on not being a partial character, so just redraw the + * whole line. + */ + tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); } void -- cgit From 1af09d6330ddba2d3ffc9c15d056fe8c4321f17e Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 20 Oct 2009 19:18:28 +0000 Subject: Try to reduce the UTF-8 mess. Get rid of passing around u_char[4]s and define a struct utf8_data which has character data, size (sequence length) and width. Move UTF-8 character collection into two functions utf8_open/utf8_append in utf8.c which fill in this struct and use these functions from input.c and the various functions in screen-write.c. Space for rather more data than is necessary for one UTF-8 sequence is in the utf8_data struct because screen_write_copy is still nasty and needs to reinject the character (after combining) into screen_write_cell. --- tty.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 9ddffb95..ee725edf 100644 --- a/tty.c +++ b/tty.c @@ -342,7 +342,7 @@ tty_putc(struct tty *tty, u_char ch) void tty_pututf8(struct tty *tty, const struct grid_utf8 *gu) { - u_int i, width; + u_int i; for (i = 0; i < UTF8_SIZE; i++) { if (gu->data[i] == 0xff) @@ -352,8 +352,7 @@ tty_pututf8(struct tty *tty, const struct grid_utf8 *gu) write(tty->log_fd, &gu->data[i], 1); } - width = utf8_width(gu->data); - tty->cx += width; + tty->cx += gu->width; } void -- cgit From 683ddbc466bbd6ff2a890c11edccc482bfe0dc87 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 21 Oct 2009 09:36:53 +0000 Subject: Some terminals don't correctly clear their let's-wrap flag after changing the scroll region (which moves the cursor to 0,0). This means that if the cursor was at the edge of the screen, any further output after scroll region change incorrectly causes a line wrap. Add a workaround to move the cursor to position 0 if it is at the screen edge before changing scroll region. --- tty.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index ee725edf..177648b7 100644 --- a/tty.c +++ b/tty.c @@ -955,6 +955,15 @@ tty_region(struct tty *tty, u_int rupper, u_int rlower) tty->rupper = rupper; tty->rlower = rlower; + /* + * Some terminals (such as PuTTY) do not correctly reset the cursor to + * 0,0 if it is beyond the last column (they do not reset their wrap + * flag so further output causes a line feed). As a workaround, do an + * explicit move to 0 first. + */ + if (tty->cx >= tty->sx) + tty_cursor(tty, 0, tty->cy); + tty->cx = 0; tty->cy = 0; -- cgit From 9b5da97e6f55b65fc892aa702fbe41aee9159865 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 21 Oct 2009 13:42:44 +0000 Subject: Don't redraw the scroll region on linefeed/reverse index unless it is necessary (the cursor is at the bottom/top). Should fix slow cursor movement when using vi in a pane spotted by pirofti@. --- tty.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 177648b7..89b245b1 100644 --- a/tty.c +++ b/tty.c @@ -684,20 +684,21 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; + if (ctx->ocy != ctx->orupper) + return; + if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { tty_redraw_region(tty, ctx); return; } - if (ctx->ocy == ctx->orupper) { - tty_reset(tty); - - tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper); - - tty_putcode(tty, TTYC_RI); - } + tty_reset(tty); + + tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper); + + tty_putcode(tty, TTYC_RI); } void @@ -706,6 +707,9 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; + if (ctx->ocy != ctx->orlower) + return; + if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { tty_redraw_region(tty, ctx); @@ -720,14 +724,12 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP)) return; - if (ctx->ocy == ctx->orlower) { - tty_reset(tty); - - tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - - tty_putc(tty, '\n'); - } + tty_reset(tty); + + tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); + + tty_putc(tty, '\n'); } void -- cgit From dd46f634fe807e4819f8ba3c5cc6f290e530a54e Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 21 Oct 2009 16:52:30 +0000 Subject: Now we are correctly not redrawing the whole pane on linefeed, redo the last-cursor-position code to move to the right position when panes reach EOL. --- tty.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 89b245b1..249e65c1 100644 --- a/tty.c +++ b/tty.c @@ -851,17 +851,24 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - u_int cx; + u_int cx, sx; tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); - /* - * Should the cursor be in the last cursor position ready for a natural - * wrap? If so - and it isn't - move to and rewrite the last cell. - */ - if (!(tty->term->flags & TERM_EARLYWRAP) && - ctx->ocx + wp->xoff > tty->sx - ctx->last_width) { - if (tty->cx < tty->sx) { + /* Is the cursor in the very last position? */ + if (ctx->ocx > wp->sx - ctx->last_width) { + if (wp->xoff != 0 || wp->sx != tty->sx) { + /* + * The pane doesn't fill the entire line, the linefeed + * will already have happened, so just move the cursor. + */ + tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1); + } else if (tty->cx < tty->sx) { + /* + * The cursor isn't in the last position already, so + * move as far left as possinble and redraw the last + * cell to move into the last position. + */ cx = screen_size_x(s) - ctx->last_width; tty_cursor_pane(tty, ctx, cx, ctx->ocy); tty_cell(tty, &ctx->last_cell, &ctx->last_utf8); -- cgit From 59e667906f2530a9dc7a6bdb2871c7f2a27a4906 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 21 Oct 2009 19:27:09 +0000 Subject: Unused variable. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 249e65c1..596779e1 100644 --- a/tty.c +++ b/tty.c @@ -851,7 +851,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - u_int cx, sx; + u_int cx; tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); -- cgit From 3a7636ff0f3eed214a847edbfb3bd8007128d49a Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 25 Oct 2009 21:11:21 +0000 Subject: Remove the -d flag to tmux and just use op/AX to detect default colours. Irritatingly, although op can be used to tell if a terminal supports default colours, it can't be used to set them because in some terminfo descriptions it resets attributes as a side-effect (acts as sgr0) and in others it doesn't, so it is not possible to determine reliably what the terminal state will be afterwards. So if AX is missing and op is present, tmux just sends sgr0. Anyone using -d for a terminal who finds they actually needed it can replace it using terminal-overrides, but please let me know as it is probably an omission from terminfo. --- tty.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 596779e1..d329e15b 100644 --- a/tty.c +++ b/tty.c @@ -1236,13 +1236,21 @@ tty_attributes_fg(struct tty *tty, const struct grid_cell *gc) tty_reset(tty); } - if (fg == 8 && - !(tty->term->flags & TERM_HASDEFAULTS) && - !(tty->term_flags & TERM_HASDEFAULTS)) - fg = 7; - if (fg == 8) - tty_puts(tty, "\033[39m"); - else + if (fg == 8) { + if (tty_term_has(tty->term, TTYC_AX)) { + /* AX is an extension that means \033[39m works. */ + tty_puts(tty, "\033[39m"); + } else if (tty_term_has(tty->term, TTYC_OP)) { + /* + * op can be used to look for default colours but there + * is no point in using it - with some terminals it + * does SGR0 and others not, so SGR0 is needed anyway + * to put the terminal into a known state. + */ + tty_reset(tty); + } else + tty_putcode1(tty, TTYC_SETAF, 7); + } else tty_putcode1(tty, TTYC_SETAF, fg); } @@ -1262,12 +1270,13 @@ tty_attributes_bg(struct tty *tty, const struct grid_cell *gc) bg &= 7; } - if (bg == 8 && - !(tty->term->flags & TERM_HASDEFAULTS) && - !(tty->term_flags & TERM_HASDEFAULTS)) - bg = 0; - if (bg == 8) - tty_puts(tty, "\033[49m"); - else + if (bg == 8) { + if (tty_term_has(tty->term, TTYC_AX)) { + tty_puts(tty, "\033[49m"); + } else if (tty_term_has(tty->term, TTYC_OP)) + tty_reset(tty); + else + tty_putcode1(tty, TTYC_SETAB, 0); + } else tty_putcode1(tty, TTYC_SETAB, bg); } -- cgit From ed62d1263ca180e8b088111bf77b8c7b4b2073de Mon Sep 17 00:00:00 2001 From: Theo Deraadt Date: Mon, 26 Oct 2009 21:42:04 +0000 Subject: tabs are better; ok nicm --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index d329e15b..b0a91ffc 100644 --- a/tty.c +++ b/tty.c @@ -144,7 +144,7 @@ tty_start_tty(struct tty *tty) tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHONL|ECHOCTL| ECHOPRT|ECHOKE|ECHOCTL|ISIG); tio.c_cc[VMIN] = 1; - tio.c_cc[VTIME] = 0; + tio.c_cc[VTIME] = 0; if (tcsetattr(tty->fd, TCSANOW, &tio) != 0) fatal("tcsetattr failed"); -- cgit From eb5f4460d1dcee0e53197f4d3c4f28768da4b7f8 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 28 Oct 2009 08:27:33 +0000 Subject: Setting SGR0 when setting the fg and bg has problems if only one of the two is meant to be default, so rewrite the code to move this outside, move setting colours before attributes and generally clean up. Tested by sthen@, fixes problems he was seeing with mutt and should fix some existing problems with (rarely) lost attributes. --- tty.c | 231 +++++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 144 insertions(+), 87 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index b0a91ffc..e384d97b 100644 --- a/tty.c +++ b/tty.c @@ -33,8 +33,9 @@ void tty_fill_acs(struct tty *); int tty_try_256(struct tty *, u_char, const char *); int tty_try_88(struct tty *, u_char, const char *); -void tty_attributes_fg(struct tty *, const struct grid_cell *); -void tty_attributes_bg(struct tty *, const struct grid_cell *); +void tty_colours(struct tty *, const struct grid_cell *, int *); +void tty_colours_fg(struct tty *, const struct grid_cell *, int *); +void tty_colours_bg(struct tty *, const struct grid_cell *, int *); void tty_redraw_region(struct tty *, const struct tty_ctx *); void tty_emulate_repeat( @@ -1120,14 +1121,23 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell; u_char changed; - u_int fg, bg, attr; + u_int fg = gc->fg, bg = gc->bg, attr = gc->attr; + + /* If any bits are being cleared, reset everything. */ + if (tc->attr & ~attr) + tty_reset(tty); + + /* + * Set the colours. This may call tty_reset() (so it comes next) and + * may add to the desired attributes in attr. + */ + tty_colours(tty, gc, &attr); /* * If no setab, try to use the reverse attribute as a best-effort for a * non-default background. This is a bit of a hack but it doesn't do * any serious harm and makes a couple of applications happier. */ - fg = gc->fg; bg = gc->bg; attr = gc->attr; if (!tty_term_has(tty->term, TTYC_SETAB)) { if (attr & GRID_ATTR_REVERSE) { if (fg != 7 && fg != 8) @@ -1138,10 +1148,6 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) } } - /* If any bits are being cleared, reset everything. */ - if (tc->attr & ~attr) - tty_reset(tty); - /* Filter out attribute bits already set. */ changed = attr & ~tc->attr; tc->attr = attr; @@ -1167,116 +1173,167 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) tty_putcode(tty, TTYC_INVIS); if (changed & GRID_ATTR_CHARSET) tty_putcode(tty, TTYC_SMACS); - - /* Set foreground colour. */ - if (fg != tc->fg || - (gc->flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)) { - tty_attributes_fg(tty, gc); - tc->fg = fg; - tc->flags &= ~GRID_FLAG_FG256; - tc->flags |= gc->flags & GRID_FLAG_FG256; - } - - /* Set background colour. */ - if (bg != tc->bg || - (gc->flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)) { - tty_attributes_bg(tty, gc); - tc->bg = bg; - tc->flags &= ~GRID_FLAG_BG256; - tc->flags |= gc->flags & GRID_FLAG_BG256; - } } -int -tty_try_256(struct tty *tty, u_char colour, const char *type) +void +tty_colours(struct tty *tty, const struct grid_cell *gc, int *attr) { - char s[32]; - - if (!(tty->term->flags & TERM_256COLOURS) && - !(tty->term_flags & TERM_256COLOURS)) - return (-1); + struct grid_cell *tc = &tty->cell; + u_char fg = gc->fg, bg = gc->bg; + int flags, have_ax; + int fg_default, bg_default; - xsnprintf(s, sizeof s, "\033[%s;5;%hhum", type, colour); - tty_puts(tty, s); - return (0); -} + /* No changes? Nothing is necessary. */ + flags = (gc->flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256); + if (fg == tc->fg && bg == tc->bg && flags == 0) + return; -int -tty_try_88(struct tty *tty, u_char colour, const char *type) -{ - char s[32]; + /* + * Is either the default colour? This is handled specially because the + * best solution might be to reset both colours to default, in which + * case if only one is default need to fall onward to set the other + * colour. + */ + fg_default = (fg == 8 && !(gc->flags & GRID_FLAG_FG256)); + bg_default = (bg == 8 && !(gc->flags & GRID_FLAG_BG256)); + if (fg_default || bg_default) { + /* + * If don't have AX but do have op, send sgr0 (op can't + * actually be used because it is sometimes the same as sgr0 + * and sometimes isn't). This resets both colours to default. + * + * Otherwise, try to set the default colour only as needed. + */ + have_ax = tty_term_has(tty->term, TTYC_AX); + if (!have_ax && tty_term_has(tty->term, TTYC_OP)) + tty_reset(tty); + else { + if (fg_default && + fg != tc->fg && !(tc->flags & GRID_FLAG_FG256)) { + if (have_ax) + tty_puts(tty, "\033[39m"); + else if (tc->fg != 7) + tty_putcode1(tty, TTYC_SETAF, 7); + tc->fg = 8; + tc->flags &= ~GRID_FLAG_FG256; + } + if (bg_default && + bg != tc->bg && !(tc->flags & GRID_FLAG_BG256)) { + if (have_ax) + tty_puts(tty, "\033[49m"); + else if (tc->bg != 0) + tty_putcode1(tty, TTYC_SETAB, 0); + tc->bg = 8; + tc->flags &= ~GRID_FLAG_BG256; + } + } + } - if (!(tty->term->flags & TERM_88COLOURS) && - !(tty->term_flags & TERM_88COLOURS)) - return (-1); - colour = colour_256to88(colour); + /* Set the foreground colour. */ + if (!fg_default && (fg != tc->fg || + ((gc->flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)))) + tty_colours_fg(tty, gc, attr); - xsnprintf(s, sizeof s, "\033[%s;5;%hhum", type, colour); - tty_puts(tty, s); - return (0); + /* + * Set the background colour. This must come after the foreground as + * tty_colour_fg() can call tty_reset(). + */ + if (!bg_default && (bg != tc->bg || + ((gc->flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)))) + tty_colours_bg(tty, gc, attr); } void -tty_attributes_fg(struct tty *tty, const struct grid_cell *gc) +tty_colours_fg(struct tty *tty, const struct grid_cell *gc, int *attr) { - u_char fg; + struct grid_cell *tc = &tty->cell; + u_char fg = gc->fg; - fg = gc->fg; + /* Is this a 256-colour colour? */ if (gc->flags & GRID_FLAG_FG256) { + /* Try as 256 colours or translating to 88. */ if (tty_try_256(tty, fg, "38") == 0) - return; + goto save_fg; if (tty_try_88(tty, fg, "38") == 0) - return; + goto save_fg; + + /* Translate to 16-colour palette, updating bold if needed. */ fg = colour_256to16(fg); if (fg & 8) { fg &= 7; - tty_putcode(tty, TTYC_BOLD); - tty->cell.attr |= GRID_ATTR_BRIGHT; - } else if (tty->cell.attr & GRID_ATTR_BRIGHT) - tty_reset(tty); + (*attr) |= GRID_ATTR_BRIGHT; + } else + tty_reset(tty); /* turn off bold */ } - if (fg == 8) { - if (tty_term_has(tty->term, TTYC_AX)) { - /* AX is an extension that means \033[39m works. */ - tty_puts(tty, "\033[39m"); - } else if (tty_term_has(tty->term, TTYC_OP)) { - /* - * op can be used to look for default colours but there - * is no point in using it - with some terminals it - * does SGR0 and others not, so SGR0 is needed anyway - * to put the terminal into a known state. - */ - tty_reset(tty); - } else - tty_putcode1(tty, TTYC_SETAF, 7); - } else - tty_putcode1(tty, TTYC_SETAF, fg); + /* Otherwise set the foreground colour. */ + tty_putcode1(tty, TTYC_SETAF, fg); + +save_fg: + /* Save the new values in the terminal current cell. */ + tc->fg = fg; + tc->flags &= ~GRID_FLAG_FG256; + tc->flags |= gc->flags & GRID_FLAG_FG256; } void -tty_attributes_bg(struct tty *tty, const struct grid_cell *gc) +tty_colours_bg(struct tty *tty, const struct grid_cell *gc, unused int *attr) { - u_char bg; + struct grid_cell *tc = &tty->cell; + u_char bg = gc->bg; - bg = gc->bg; + /* Is this a 256-colour colour? */ if (gc->flags & GRID_FLAG_BG256) { + /* Try as 256 colours or translating to 88. */ if (tty_try_256(tty, bg, "48") == 0) - return; + goto save_bg; if (tty_try_88(tty, bg, "48") == 0) - return; + goto save_bg; + + /* + * Translate to 16-colour palette. Bold background doesn't + * exist portably, so just discard the bold bit if set. + */ bg = colour_256to16(bg); if (bg & 8) bg &= 7; } - if (bg == 8) { - if (tty_term_has(tty->term, TTYC_AX)) { - tty_puts(tty, "\033[49m"); - } else if (tty_term_has(tty->term, TTYC_OP)) - tty_reset(tty); - else - tty_putcode1(tty, TTYC_SETAB, 0); - } else - tty_putcode1(tty, TTYC_SETAB, bg); + /* Otherwise set the background colour. */ + tty_putcode1(tty, TTYC_SETAB, bg); + +save_bg: + /* Save the new values in the terminal current cell. */ + tc->bg = bg; + tc->flags &= ~GRID_FLAG_BG256; + tc->flags |= gc->flags & GRID_FLAG_BG256; +} + +int +tty_try_256(struct tty *tty, u_char colour, const char *type) +{ + char s[32]; + + if (!(tty->term->flags & TERM_256COLOURS) && + !(tty->term_flags & TERM_256COLOURS)) + return (-1); + + xsnprintf(s, sizeof s, "\033[%s;5;%hhum", type, colour); + tty_puts(tty, s); + return (0); +} + +int +tty_try_88(struct tty *tty, u_char colour, const char *type) +{ + char s[32]; + + if (!(tty->term->flags & TERM_88COLOURS) && + !(tty->term_flags & TERM_88COLOURS)) + return (-1); + colour = colour_256to88(colour); + + xsnprintf(s, sizeof s, "\033[%s;5;%hhum", type, colour); + tty_puts(tty, s); + return (0); } -- cgit From 5730cbf3e3627d40177f9377b068f2ba50144ed9 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 28 Oct 2009 08:33:20 +0000 Subject: Twaek this slightly to avoid confusing use of flags variable. --- tty.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index e384d97b..8efc6866 100644 --- a/tty.c +++ b/tty.c @@ -1179,14 +1179,13 @@ void tty_colours(struct tty *tty, const struct grid_cell *gc, int *attr) { struct grid_cell *tc = &tty->cell; - u_char fg = gc->fg, bg = gc->bg; - int flags, have_ax; - int fg_default, bg_default; + u_char fg = gc->fg, bg = gc->bg, flags = gc->flags; + int have_ax, fg_default, bg_default; /* No changes? Nothing is necessary. */ - flags = (gc->flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256); - if (fg == tc->fg && bg == tc->bg && flags == 0) - return; + if (fg == tc->fg && bg == tc->bg && + ((flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256)) == 0) + return; /* * Is either the default colour? This is handled specially because the @@ -1194,8 +1193,8 @@ tty_colours(struct tty *tty, const struct grid_cell *gc, int *attr) * case if only one is default need to fall onward to set the other * colour. */ - fg_default = (fg == 8 && !(gc->flags & GRID_FLAG_FG256)); - bg_default = (bg == 8 && !(gc->flags & GRID_FLAG_BG256)); + fg_default = (fg == 8 && !(flags & GRID_FLAG_FG256)); + bg_default = (bg == 8 && !(flags & GRID_FLAG_BG256)); if (fg_default || bg_default) { /* * If don't have AX but do have op, send sgr0 (op can't @@ -1231,7 +1230,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc, int *attr) /* Set the foreground colour. */ if (!fg_default && (fg != tc->fg || - ((gc->flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)))) + ((flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)))) tty_colours_fg(tty, gc, attr); /* @@ -1239,7 +1238,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc, int *attr) * tty_colour_fg() can call tty_reset(). */ if (!bg_default && (bg != tc->bg || - ((gc->flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)))) + ((flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)))) tty_colours_bg(tty, gc, attr); } -- cgit From 1eaefbf1698fc66815e538fc3040f4446f444f7b Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 28 Oct 2009 08:52:36 +0000 Subject: Add a minor optimisatin: if the character being printed is space, don't worry about setting the background colour or attributes (except reverse). --- tty.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 8efc6866..1010217d 100644 --- a/tty.c +++ b/tty.c @@ -1119,10 +1119,24 @@ out: void tty_attributes(struct tty *tty, const struct grid_cell *gc) { - struct grid_cell *tc = &tty->cell; + struct grid_cell *tc = &tty->cell, gc2; u_char changed; u_int fg = gc->fg, bg = gc->bg, attr = gc->attr; + /* If the character is space, don't care about foreground. */ + if (gc->data == ' ' && !(gc->flags & GRID_FLAG_UTF8)) { + memcpy(&gc2, gc, sizeof gc2); + + if (gc->attr & GRID_ATTR_REVERSE) + gc2.bg = tc->bg; + else + gc2.fg = tc->fg; + gc2.attr = tc->attr & ~GRID_ATTR_REVERSE; + gc2.attr |= gc->attr & GRID_ATTR_REVERSE; + + gc = &gc2; + } + /* If any bits are being cleared, reset everything. */ if (tc->attr & ~attr) tty_reset(tty); @@ -1185,7 +1199,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc, int *attr) /* No changes? Nothing is necessary. */ if (fg == tc->fg && bg == tc->bg && ((flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256)) == 0) - return; + return; /* * Is either the default colour? This is handled specially because the -- cgit From a94535f318dc0c712327f5c7b3e96a62201ebcab Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 4 Nov 2009 13:34:26 +0000 Subject: Fix the reverse emulation when a terminal doesn't have setab to use the correct fg/bg (adjusted if spaces) and happen before attribute setting. --- tty.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 1010217d..1a6315e7 100644 --- a/tty.c +++ b/tty.c @@ -1121,7 +1121,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell, gc2; u_char changed; - u_int fg = gc->fg, bg = gc->bg, attr = gc->attr; + u_int new_attr; /* If the character is space, don't care about foreground. */ if (gc->data == ' ' && !(gc->flags & GRID_FLAG_UTF8)) { @@ -1137,34 +1137,40 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) gc = &gc2; } - /* If any bits are being cleared, reset everything. */ - if (tc->attr & ~attr) - tty_reset(tty); - - /* - * Set the colours. This may call tty_reset() (so it comes next) and - * may add to the desired attributes in attr. - */ - tty_colours(tty, gc, &attr); - /* * If no setab, try to use the reverse attribute as a best-effort for a * non-default background. This is a bit of a hack but it doesn't do * any serious harm and makes a couple of applications happier. */ if (!tty_term_has(tty->term, TTYC_SETAB)) { - if (attr & GRID_ATTR_REVERSE) { - if (fg != 7 && fg != 8) - attr &= ~GRID_ATTR_REVERSE; + if (gc != &gc2) { + memcpy(&gc2, gc, sizeof gc2); + gc = &gc2; + } + + if (gc->attr & GRID_ATTR_REVERSE) { + if (gc->fg != 7 && gc->fg != 8) + gc2.attr &= ~GRID_ATTR_REVERSE; } else { - if (bg != 0 && bg != 8) - attr |= GRID_ATTR_REVERSE; + if (gc->bg != 0 && gc->bg != 8) + gc2.attr |= GRID_ATTR_REVERSE; } } + /* If any bits are being cleared, reset everything. */ + if (tc->attr & ~gc->attr) + tty_reset(tty); + + /* + * Set the colours. This may call tty_reset() (so it comes next) and + * may add to (NOT remove) the desired attributes by changing new_attr. + */ + new_attr = gc->attr; + tty_colours(tty, gc, &new_attr); + /* Filter out attribute bits already set. */ - changed = attr & ~tc->attr; - tc->attr = attr; + changed = new_attr & ~tc->attr; + tc->attr = new_attr; /* Set the attributes. */ if (changed & GRID_ATTR_BRIGHT) -- cgit From 10f58cb1bc0ec010cc692f504d52adcb6312b8fb Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 4 Nov 2009 15:59:27 +0000 Subject: Ignore the colour on space, /not/ the attributes. --- tty.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 1a6315e7..0782e42d 100644 --- a/tty.c +++ b/tty.c @@ -1126,14 +1126,10 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) /* If the character is space, don't care about foreground. */ if (gc->data == ' ' && !(gc->flags & GRID_FLAG_UTF8)) { memcpy(&gc2, gc, sizeof gc2); - if (gc->attr & GRID_ATTR_REVERSE) gc2.bg = tc->bg; else gc2.fg = tc->fg; - gc2.attr = tc->attr & ~GRID_ATTR_REVERSE; - gc2.attr |= gc->attr & GRID_ATTR_REVERSE; - gc = &gc2; } -- cgit From 7342615c7ddd9b99820bd9c03fda2afe7bc868d3 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 4 Nov 2009 21:47:42 +0000 Subject: Switch tty fds over to a bufferevent. --- tty.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 0782e42d..e194febb 100644 --- a/tty.c +++ b/tty.c @@ -28,6 +28,8 @@ #include "tmux.h" +void tty_error_callback(struct bufferevent *, short, void *); + void tty_fill_acs(struct tty *); int tty_try_256(struct tty *, u_char, const char *); @@ -108,11 +110,11 @@ tty_open(struct tty *tty, const char *overrides, char **cause) } tty->flags |= TTY_OPENED; - tty->in = buffer_create(BUFSIZ); - tty->out = buffer_create(BUFSIZ); - tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE|TTY_ESCAPE); + tty->event = bufferevent_new( + tty->fd, NULL, NULL, tty_error_callback, tty); + tty_start_tty(tty); tty_keys_init(tty); @@ -122,6 +124,13 @@ tty_open(struct tty *tty, const char *overrides, char **cause) return (0); } +void +tty_error_callback( + unused struct bufferevent *bufev, unused short what, unused void *data) +{ + fatalx("lost terminal"); +} + void tty_start_tty(struct tty *tty) { @@ -136,6 +145,8 @@ tty_start_tty(struct tty *tty) if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1) fatal("fcntl failed"); + bufferevent_enable(tty->event, EV_READ|EV_WRITE); + if (tcgetattr(tty->fd, &tty->tio) != 0) fatal("tcgetattr failed"); memcpy(&tio, &tty->tio, sizeof tio); @@ -187,6 +198,8 @@ tty_stop_tty(struct tty *tty) return; tty->flags &= ~TTY_STARTED; + bufferevent_disable(tty->event, EV_READ|EV_WRITE); + /* * Be flexible about error handling and try not kill the server just * because the fd is invalid. Things like ssh -t can easily leave us @@ -249,12 +262,11 @@ tty_close(struct tty *tty) tty_stop_tty(tty); if (tty->flags & TTY_OPENED) { + bufferevent_free(tty->event); + tty_term_free(tty->term); tty_keys_free(tty); - buffer_destroy(tty->in); - buffer_destroy(tty->out); - tty->flags &= ~TTY_OPENED; } @@ -308,7 +320,7 @@ tty_puts(struct tty *tty, const char *s) { if (*s == '\0') return; - buffer_write(tty->out, s, strlen(s)); + bufferevent_write(tty->event, s, strlen(s)); if (tty->log_fd != -1) write(tty->log_fd, s, strlen(s)); @@ -321,7 +333,7 @@ tty_putc(struct tty *tty, u_char ch) if (tty->cell.attr & GRID_ATTR_CHARSET) ch = tty_get_acs(tty, ch); - buffer_write8(tty->out, ch); + bufferevent_write(tty->event, &ch, 1); if (ch >= 0x20 && ch != 0x7f) { sx = tty->sx; @@ -348,7 +360,7 @@ tty_pututf8(struct tty *tty, const struct grid_utf8 *gu) for (i = 0; i < UTF8_SIZE; i++) { if (gu->data[i] == 0xff) break; - buffer_write8(tty->out, gu->data[i]); + bufferevent_write(tty->event, &gu->data[i], 1); if (tty->log_fd != -1) write(tty->log_fd, &gu->data[i], 1); } -- cgit From b58bf49e913e61a4991c35257dd82e5dd4c907a2 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 5 Nov 2009 08:45:08 +0000 Subject: Switch tty key input over to happen on a read event. This is a bit more complicated because of escape input, but in that case instead of processing a key immediately, schedule a timer and reprocess the bufer when it expires. This currently assumes that keys will be atomic (ie that if eg F1 is pressed the entire sequence is present in the buffer). This is usually but not always true, a change in the tree format so it can differentiate potential (partial) key sequences will happens soon and will allow this to be fixed. --- tty.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index e194febb..6ab3a211 100644 --- a/tty.c +++ b/tty.c @@ -28,6 +28,7 @@ #include "tmux.h" +void tty_read_callback(struct bufferevent *, void *); void tty_error_callback(struct bufferevent *, short, void *); void tty_fill_acs(struct tty *); @@ -113,7 +114,7 @@ tty_open(struct tty *tty, const char *overrides, char **cause) tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE|TTY_ESCAPE); tty->event = bufferevent_new( - tty->fd, NULL, NULL, tty_error_callback, tty); + tty->fd, tty_read_callback, NULL, tty_error_callback, tty); tty_start_tty(tty); @@ -124,6 +125,15 @@ tty_open(struct tty *tty, const char *overrides, char **cause) return (0); } +void +tty_read_callback(unused struct bufferevent *bufev, void *data) +{ + struct tty *tty = data; + + while (tty_keys_next(tty)) + ; +} + void tty_error_callback( unused struct bufferevent *bufev, unused short what, unused void *data) @@ -259,6 +269,7 @@ tty_close(struct tty *tty) tty->log_fd = -1; } + evtimer_del(&tty->key_timer); tty_stop_tty(tty); if (tty->flags & TTY_OPENED) { -- cgit From bed8153ba00fef8ed2f618463fa631c71b8f51cf Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 5 Nov 2009 22:35:28 +0000 Subject: Clear to the end of the screen from the right starting point when drawing line-by-line (in panes or if ed not supported). Fixes problem spotted by Frank Terbeck. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 6ab3a211..b4da9983 100644 --- a/tty.c +++ b/tty.c @@ -784,7 +784,7 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) } else { for (i = ctx->ocx; i < screen_size_x(s); i++) tty_putc(tty, ' '); - for (j = ctx->ocy; j < screen_size_y(s); j++) { + for (j = ctx->ocy + 1; j < screen_size_y(s); j++) { tty_cursor_pane(tty, ctx, 0, j); for (i = 0; i < screen_size_x(s); i++) tty_putc(tty, ' '); -- cgit From 6609093625b8c48a69af737e6a02ba2befd06adb Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 9 Nov 2009 22:50:29 +0000 Subject: Just ignore tty fd errors rather than dying, stops the server dying if the session is disconnected abrubtly (eg ssh ~.). --- tty.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index b4da9983..f7b3ec03 100644 --- a/tty.c +++ b/tty.c @@ -138,7 +138,6 @@ void tty_error_callback( unused struct bufferevent *bufev, unused short what, unused void *data) { - fatalx("lost terminal"); } void -- cgit From 5ae542e7eed70cf37a658356f37a913a8c4aefef Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 12 Nov 2009 08:05:23 +0000 Subject: Emulate the ri (reverse index) capability: this allows tmux to at least start on Sun consoles (TERM=sun or sun-color), even if there appear to still be problems on some boxes (my Blade 100 is fine but edd's Blade 1000 shows odd screen corruption). --- tty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index f7b3ec03..8855a657 100644 --- a/tty.c +++ b/tty.c @@ -711,7 +711,8 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) return; if (wp->xoff != 0 || screen_size_x(s) < tty->sx || - !tty_term_has(tty->term, TTYC_CSR)) { + !tty_term_has(tty->term, TTYC_CSR) || + !tty_term_has(tty->term, TTYC_RI)) { tty_redraw_region(tty, ctx); return; } -- cgit From a78cc98c8bd79cecbb8574a9dff4c9867a8308d9 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 18 Nov 2009 17:02:17 +0000 Subject: Cleanup by moving various (mostly horrible) little bits handling UTF-8 grid data into functions in a new file, grid-utf8.c, and use sizeof intead of UTF8_DATA. Also nuke trailing whitespace from tmux.1, reminded by jmc. --- tty.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 8855a657..a3aeda5d 100644 --- a/tty.c +++ b/tty.c @@ -365,16 +365,12 @@ tty_putc(struct tty *tty, u_char ch) void tty_pututf8(struct tty *tty, const struct grid_utf8 *gu) { - u_int i; - - for (i = 0; i < UTF8_SIZE; i++) { - if (gu->data[i] == 0xff) - break; - bufferevent_write(tty->event, &gu->data[i], 1); - if (tty->log_fd != -1) - write(tty->log_fd, &gu->data[i], 1); - } + size_t size; + size = grid_utf8_size(gu); + bufferevent_write(tty->event, gu->data, size); + if (tty->log_fd != -1) + write(tty->log_fd, gu->data, size); tty->cx += gu->width; } -- cgit From d31d4c05cff725db571d4463da4106638304e29b Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 26 Nov 2009 14:46:08 +0000 Subject: Emulate il1, dl1, ich1 to run (albeit slowly) with vt100 feature set. --- tty.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index a3aeda5d..84931e78 100644 --- a/tty.c +++ b/tty.c @@ -569,12 +569,14 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) if (tty_term_has(tty->term, TTYC_ICH) || tty_term_has(tty->term, TTYC_ICH1)) tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num); - else { + else if (tty_term_has(tty->term, TTYC_SMIR) && + tty_term_has(tty->term, TTYC_RMIR)) { tty_putcode(tty, TTYC_SMIR); for (i = 0; i < ctx->num; i++) tty_putc(tty, ' '); tty_putcode(tty, TTYC_RMIR); - } + } else + tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); } void @@ -606,7 +608,8 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) struct screen *s = wp->screen; if (wp->xoff != 0 || screen_size_x(s) < tty->sx || - !tty_term_has(tty->term, TTYC_CSR)) { + !tty_term_has(tty->term, TTYC_CSR) || + !tty_term_has(tty->term, TTYC_IL1)) { tty_redraw_region(tty, ctx); return; } @@ -626,7 +629,8 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) struct screen *s = wp->screen; if (wp->xoff != 0 || screen_size_x(s) < tty->sx || - !tty_term_has(tty->term, TTYC_CSR)) { + !tty_term_has(tty->term, TTYC_CSR) || + !tty_term_has(tty->term, TTYC_DL1)) { tty_redraw_region(tty, ctx); return; } -- cgit From 4ca857e0e922d0afeb7896ff62e9f47c0c36c535 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 26 Nov 2009 21:37:13 +0000 Subject: Remove a couple of unused arguments where possible, and add /* ARGSUSED */ to the rest to reduce lint output. --- tty.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 84931e78..999c3919 100644 --- a/tty.c +++ b/tty.c @@ -38,7 +38,7 @@ int tty_try_88(struct tty *, u_char, const char *); void tty_colours(struct tty *, const struct grid_cell *, int *); void tty_colours_fg(struct tty *, const struct grid_cell *, int *); -void tty_colours_bg(struct tty *, const struct grid_cell *, int *); +void tty_colours_bg(struct tty *, const struct grid_cell *); void tty_redraw_region(struct tty *, const struct tty_ctx *); void tty_emulate_repeat( @@ -125,6 +125,7 @@ tty_open(struct tty *tty, const char *overrides, char **cause) return (0); } +/* ARGSUSED */ void tty_read_callback(unused struct bufferevent *bufev, void *data) { @@ -134,6 +135,7 @@ tty_read_callback(unused struct bufferevent *bufev, void *data) ; } +/* ARGSUSED */ void tty_error_callback( unused struct bufferevent *bufev, unused short what, unused void *data) @@ -1278,7 +1280,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc, int *attr) */ if (!bg_default && (bg != tc->bg || ((flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)))) - tty_colours_bg(tty, gc, attr); + tty_colours_bg(tty, gc); } void @@ -1315,7 +1317,7 @@ save_fg: } void -tty_colours_bg(struct tty *tty, const struct grid_cell *gc, unused int *attr) +tty_colours_bg(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell; u_char bg = gc->bg; -- cgit From e7f4319ac6c1341c0a31582693de54a02458a2b9 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 26 Nov 2009 22:47:14 +0000 Subject: Fix type - attributes should be u_char not int. --- tty.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 999c3919..1ed965ff 100644 --- a/tty.c +++ b/tty.c @@ -36,8 +36,8 @@ void tty_fill_acs(struct tty *); int tty_try_256(struct tty *, u_char, const char *); int tty_try_88(struct tty *, u_char, const char *); -void tty_colours(struct tty *, const struct grid_cell *, int *); -void tty_colours_fg(struct tty *, const struct grid_cell *, int *); +void tty_colours(struct tty *, const struct grid_cell *, u_char *); +void tty_colours_fg(struct tty *, const struct grid_cell *, u_char *); void tty_colours_bg(struct tty *, const struct grid_cell *); void tty_redraw_region(struct tty *, const struct tty_ctx *); @@ -1145,8 +1145,7 @@ void tty_attributes(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell, gc2; - u_char changed; - u_int new_attr; + u_char changed, new_attr; /* If the character is space, don't care about foreground. */ if (gc->data == ' ' && !(gc->flags & GRID_FLAG_UTF8)) { @@ -1217,7 +1216,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) } void -tty_colours(struct tty *tty, const struct grid_cell *gc, int *attr) +tty_colours(struct tty *tty, const struct grid_cell *gc, u_char *attr) { struct grid_cell *tc = &tty->cell; u_char fg = gc->fg, bg = gc->bg, flags = gc->flags; @@ -1284,7 +1283,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc, int *attr) } void -tty_colours_fg(struct tty *tty, const struct grid_cell *gc, int *attr) +tty_colours_fg(struct tty *tty, const struct grid_cell *gc, u_char *attr) { struct grid_cell *tc = &tty->cell; u_char fg = gc->fg; -- cgit From 2182e1badcc161c6e6f1ef6dec21a57cc510299e Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 27 Nov 2009 09:41:03 +0000 Subject: Add a couple of comments. --- tty.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 1ed965ff..07b744cb 100644 --- a/tty.c +++ b/tty.c @@ -529,6 +529,7 @@ tty_write(void (*cmdfn)( struct client *c; u_int i; + /* wp can be NULL if updating the screen but not the terminal. */ if (wp == NULL) return; -- cgit From 6bbc92a6f5799f0c3d9ce4fc8c10c161598757be Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 2 Dec 2009 22:13:15 +0000 Subject: Reflect the keypad mode of the application so that numlock works. --- tty.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 07b744cb..ac6a2cf7 100644 --- a/tty.c +++ b/tty.c @@ -180,7 +180,7 @@ tty_start_tty(struct tty *tty) tty_putcode(tty, TTYC_SGR0); memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell); - tty_putcode(tty, TTYC_SMKX); + tty_putcode(tty, TTYC_RMKX); tty_putcode(tty, TTYC_ENACS); tty_putcode(tty, TTYC_CLEAR); @@ -410,6 +410,12 @@ tty_update_mode(struct tty *tty, int mode) else tty_puts(tty, "\033[?1000l"); } + if (changed & MODE_KKEYPAD) { + if (mode & MODE_KKEYPAD) + tty_putcode(tty, TTYC_SMKX); + else + tty_putcode(tty, TTYC_RMKX); + } tty->mode = mode; } -- cgit From 15a64b805e46584d37cc6745383709632e287999 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 3 Dec 2009 22:50:09 +0000 Subject: Massive spaces->tabs and trailing whitespace cleanup, hopefully for the last time now I've configured emacs to make them displayed in really annoying colours... --- tty.c | 80 +++++++++++++++++++++++++++++++++---------------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index ac6a2cf7..b1026a97 100644 --- a/tty.c +++ b/tty.c @@ -44,7 +44,7 @@ void tty_redraw_region(struct tty *, const struct tty_ctx *); void tty_emulate_repeat( struct tty *, enum tty_code_code, enum tty_code_code, u_int); void tty_cell(struct tty *, - const struct grid_cell *, const struct grid_utf8 *); + const struct grid_cell *, const struct grid_utf8 *); void tty_init(struct tty *tty, int fd, char *term) @@ -502,7 +502,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) if (screen_check_selection(s, i, py)) { memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc); tmpgc.data = gc->data; - tmpgc.flags = gc->flags & + tmpgc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); tmpgc.flags |= s->sel.cell.flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); @@ -562,7 +562,7 @@ tty_write(void (*cmdfn)( void tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; u_int i; @@ -573,12 +573,12 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); if (tty_term_has(tty->term, TTYC_ICH) || tty_term_has(tty->term, TTYC_ICH1)) tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num); - else if (tty_term_has(tty->term, TTYC_SMIR) && + else if (tty_term_has(tty->term, TTYC_SMIR) && tty_term_has(tty->term, TTYC_RMIR)) { tty_putcode(tty, TTYC_SMIR); for (i = 0; i < ctx->num; i++) @@ -591,7 +591,7 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; if (wp->xoff != 0 || screen_size_x(s) < tty->sx || @@ -603,7 +603,7 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); if (tty_term_has(tty->term, TTYC_DCH) || tty_term_has(tty->term, TTYC_DCH1)) @@ -613,11 +613,11 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - if (wp->xoff != 0 || screen_size_x(s) < tty->sx || - !tty_term_has(tty->term, TTYC_CSR) || + if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_IL1)) { tty_redraw_region(tty, ctx); return; @@ -625,8 +625,8 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); + tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ctx->num); } @@ -634,10 +634,10 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_DL1)) { tty_redraw_region(tty, ctx); @@ -646,8 +646,8 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) tty_reset(tty); - tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); - tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); + tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ctx->num); } @@ -655,13 +655,13 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; u_int i; tty_reset(tty); - tty_cursor_pane(tty, ctx, 0, ctx->ocy); + tty_cursor_pane(tty, ctx, 0, ctx->ocy); if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { @@ -675,7 +675,7 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; u_int i; @@ -695,7 +695,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; u_int i; tty_reset(tty); @@ -713,13 +713,13 @@ tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; if (ctx->ocy != ctx->orupper) return; - if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_RI)) { tty_redraw_region(tty, ctx); @@ -727,23 +727,23 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) } tty_reset(tty); - + tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper); - + tty_putcode(tty, TTYC_RI); } void tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; if (ctx->ocy != ctx->orlower) return; - if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + if (wp->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { tty_redraw_region(tty, ctx); return; @@ -758,17 +758,17 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) return; tty_reset(tty); - + tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - + tty_putc(tty, '\n'); } void tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; u_int i, j; @@ -804,7 +804,7 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; u_int i, j; @@ -834,7 +834,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; u_int i, j; @@ -921,7 +921,7 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx) * Cannot rely on not being a partial character, so just redraw the * whole line. */ - tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); + tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); } void @@ -980,7 +980,7 @@ void tty_region_pane( struct tty *tty, const struct tty_ctx *ctx, u_int rupper, u_int rlower) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; tty_region(tty, wp->yoff + rupper, wp->yoff + rlower); } @@ -1016,7 +1016,7 @@ tty_region(struct tty *tty, u_int rupper, u_int rlower) void tty_cursor_pane(struct tty *tty, const struct tty_ctx *ctx, u_int cx, u_int cy) { - struct window_pane *wp = ctx->wp; + struct window_pane *wp = ctx->wp; tty_cursor(tty, wp->xoff + cx, wp->yoff + cy); } @@ -1028,7 +1028,7 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy) struct tty_term *term = tty->term; u_int thisx, thisy; int change; - + if (cx > tty->sx - 1) cx = tty->sx - 1; @@ -1103,7 +1103,7 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy) */ /* One above. */ - if (thisy != tty->rupper && + if (thisy != tty->rupper && cy == thisy - 1 && tty_term_has(term, TTYC_CUU1)) { tty_putcode(tty, TTYC_CUU1); goto out; @@ -1120,8 +1120,8 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy) change = thisy - cy; /* +ve up, -ve down */ /* - * Try to use VPA if change is larger than absolute or if this change - * would cross the scroll region, otherwise use CUU/CUD. + * Try to use VPA if change is larger than absolute or if this + * change would cross the scroll region, otherwise use CUU/CUD. */ if (abs(change) > cy || (change < 0 && cy - change > tty->rlower) || @@ -1265,7 +1265,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc, u_char *attr) } if (bg_default && bg != tc->bg && !(tc->flags & GRID_FLAG_BG256)) { - if (have_ax) + if (have_ax) tty_puts(tty, "\033[49m"); else if (tc->bg != 0) tty_putcode1(tty, TTYC_SETAB, 0); @@ -1315,7 +1315,7 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc, u_char *attr) /* Otherwise set the foreground colour. */ tty_putcode1(tty, TTYC_SETAF, fg); -save_fg: +save_fg: /* Save the new values in the terminal current cell. */ tc->fg = fg; tc->flags &= ~GRID_FLAG_FG256; -- cgit From 796eb522ac6534510b22c34296cbd172f8fab3ae Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 4 Dec 2009 11:01:29 +0000 Subject: vte is buggy and doesn't home the cursor after changing the scroll region. Several people are hitting this, so add a workaround. --- tty.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index b1026a97..32ee197c 100644 --- a/tty.c +++ b/tty.c @@ -1006,10 +1006,8 @@ tty_region(struct tty *tty, u_int rupper, u_int rlower) if (tty->cx >= tty->sx) tty_cursor(tty, 0, tty->cy); - tty->cx = 0; - tty->cy = 0; - tty_putcode2(tty, TTYC_CSR, tty->rupper, tty->rlower); + tty_cursor(tty, 0, 0); } /* Move cursor inside pane. */ -- cgit From 0dda866679009385d4973d18a123943f606c49ad Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 14 Dec 2009 21:33:38 +0000 Subject: Pass through the aixterm bright colours if the terminal supports them (>= 16 colours). --- tty.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 32ee197c..c06a4dde 100644 --- a/tty.c +++ b/tty.c @@ -1231,6 +1231,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc, u_char *attr) if (fg == tc->fg && bg == tc->bg && ((flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256)) == 0) return; + log_debug("fg was %hhu, now %hhu", tc->fg, fg); /* * Is either the default colour? This is handled specially because the @@ -1292,6 +1293,7 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc, u_char *attr) { struct grid_cell *tc = &tty->cell; u_char fg = gc->fg; + char s[32]; /* Is this a 256-colour colour? */ if (gc->flags & GRID_FLAG_FG256) { @@ -1310,6 +1312,18 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc, u_char *attr) tty_reset(tty); /* turn off bold */ } + /* Is this an aixterm bright colour? */ + if (fg >= 90 && fg <= 97) { + /* 16 colour terminals or above only. */ + if (tty_term_number(tty->term, TTYC_COLORS) >= 16) { + xsnprintf(s, sizeof s, "\033[%dm", fg); + tty_puts(tty, s); + goto save_fg; + } + fg -= 90; + (*attr) |= GRID_ATTR_BRIGHT; + } + /* Otherwise set the foreground colour. */ tty_putcode1(tty, TTYC_SETAF, fg); @@ -1325,6 +1339,7 @@ tty_colours_bg(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell; u_char bg = gc->bg; + char s[32]; /* Is this a 256-colour colour? */ if (gc->flags & GRID_FLAG_BG256) { @@ -1343,6 +1358,18 @@ tty_colours_bg(struct tty *tty, const struct grid_cell *gc) bg &= 7; } + /* Is this an aixterm bright colour? */ + if (bg >= 100 && bg <= 107) { + /* 16 colour terminals or above only. */ + if (tty_term_number(tty->term, TTYC_COLORS) >= 16) { + xsnprintf(s, sizeof s, "\033[%dm", bg); + tty_puts(tty, s); + goto save_bg; + } + bg -= 100; + /* no such thing as a bold background */ + } + /* Otherwise set the background colour. */ tty_putcode1(tty, TTYC_SETAB, bg); -- cgit From cd9b1b1fd399479ed58feb51201c2bc1db55faa5 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 26 Dec 2009 10:39:02 +0000 Subject: Nuke some stray debugging. --- tty.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index c06a4dde..43f1701a 100644 --- a/tty.c +++ b/tty.c @@ -1231,7 +1231,6 @@ tty_colours(struct tty *tty, const struct grid_cell *gc, u_char *attr) if (fg == tc->fg && bg == tc->bg && ((flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256)) == 0) return; - log_debug("fg was %hhu, now %hhu", tc->fg, fg); /* * Is either the default colour? This is handled specially because the -- cgit From a775107f5f346e66e92652fb2cbfabebe83de570 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 26 Dec 2009 11:02:32 +0000 Subject: Fix the logic so that transition from a 256 colour to default works properly. --- tty.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 43f1701a..a66c71a9 100644 --- a/tty.c +++ b/tty.c @@ -1253,19 +1253,21 @@ tty_colours(struct tty *tty, const struct grid_cell *gc, u_char *attr) tty_reset(tty); else { if (fg_default && - fg != tc->fg && !(tc->flags & GRID_FLAG_FG256)) { + (tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) { if (have_ax) tty_puts(tty, "\033[39m"); - else if (tc->fg != 7) + else if (tc->fg != 7 || + tc->flags & GRID_FLAG_FG256) tty_putcode1(tty, TTYC_SETAF, 7); tc->fg = 8; tc->flags &= ~GRID_FLAG_FG256; } if (bg_default && - bg != tc->bg && !(tc->flags & GRID_FLAG_BG256)) { + (tc->bg != 8 || tc->flags & GRID_FLAG_BG256)) { if (have_ax) tty_puts(tty, "\033[49m"); - else if (tc->bg != 0) + else if (tc->bg != 0 || + tc->flags & GRID_FLAG_BG256) tty_putcode1(tty, TTYC_SETAB, 0); tc->bg = 8; tc->flags &= ~GRID_FLAG_BG256; -- cgit From 9ee979167a433fe8a0fb76735cd220a37ee994f2 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 1 Jan 2010 14:29:18 +0000 Subject: Use tcflush(3) instead of TIOCFLUSH, from Ed Schouten. --- tty.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index a66c71a9..a84d8def 100644 --- a/tty.c +++ b/tty.c @@ -146,7 +146,7 @@ void tty_start_tty(struct tty *tty) { struct termios tio; - int what, mode; + int mode; if (tty->fd == -1) return; @@ -170,10 +170,7 @@ tty_start_tty(struct tty *tty) tio.c_cc[VTIME] = 0; if (tcsetattr(tty->fd, TCSANOW, &tio) != 0) fatal("tcsetattr failed"); - - what = 0; - if (ioctl(tty->fd, TIOCFLUSH, &what) != 0) - fatal("ioctl(TIOCFLUSH)"); + tcflush(tty->fd, TCIOFLUSH); tty_putcode(tty, TTYC_SMCUP); -- cgit From 9ffe549ab199b6af8cd5e7b8ac3611fdba1d6b62 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 1 Feb 2010 23:06:24 +0000 Subject: If redrawing line 0 of the screen onto the tty, there can't be a wrap flag on the previous line, so move the cursor. Fixes status line redraw issues when resizing in choose mode and hopefully at other times as well. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index a84d8def..02ceb54e 100644 --- a/tty.c +++ b/tty.c @@ -484,7 +484,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) gl = NULL; if (py != 0) gl = &s->grid->linedata[s->grid->hsize + py - 1]; - if (oy + py == 0 || (gl != NULL && !(gl->flags & GRID_LINE_WRAPPED)) || + if (oy + py == 0 || gl == NULL || !(gl->flags & GRID_LINE_WRAPPED) || tty->cx < tty->sx || ox != 0 || (oy + py != tty->cy + 1 && tty->cy != s->rlower + oy)) tty_cursor(tty, ox, oy + py); -- cgit From f1dd95650b6a193498b2a61694c57fb232ea41bd Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 24 Feb 2010 19:08:39 +0000 Subject: Don't set the terminal to nonblocking on detach until we have finished with it entirely. --- tty.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 02ceb54e..52d3803a 100644 --- a/tty.c +++ b/tty.c @@ -213,10 +213,6 @@ tty_stop_tty(struct tty *tty) * because the fd is invalid. Things like ssh -t can easily leave us * with a dead tty. */ - if ((mode = fcntl(tty->fd, F_GETFL)) == -1) - return; - if (fcntl(tty->fd, F_SETFL, mode & ~O_NONBLOCK) == -1) - return; if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1) return; if (tcsetattr(tty->fd, TCSANOW, &tty->tio) == -1) @@ -233,6 +229,9 @@ tty_stop_tty(struct tty *tty) tty_raw(tty, "\033[?1000l"); tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); + + if ((mode = fcntl(tty->fd, F_GETFL)) != -1) + fcntl(tty->fd, F_SETFL, mode & ~O_NONBLOCK); } void -- cgit From c7046b9a0c338323fc478e9146371f80b843e336 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 1 Mar 2010 22:44:31 +0000 Subject: Check for colour and attribute modifications early so the translated values can be stored in the cached terminal attributes rather than the requested (untranslated) values. Prevents tmux clearing and setting the attributes for every character when using aixterm colours. --- tty.c | 143 ++++++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 91 insertions(+), 52 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 52d3803a..72be2c84 100644 --- a/tty.c +++ b/tty.c @@ -36,8 +36,10 @@ void tty_fill_acs(struct tty *); int tty_try_256(struct tty *, u_char, const char *); int tty_try_88(struct tty *, u_char, const char *); -void tty_colours(struct tty *, const struct grid_cell *, u_char *); -void tty_colours_fg(struct tty *, const struct grid_cell *, u_char *); +void tty_colours(struct tty *, const struct grid_cell *); +void tty_check_fg(struct tty *, struct grid_cell *); +void tty_check_bg(struct tty *, struct grid_cell *); +void tty_colours_fg(struct tty *, const struct grid_cell *); void tty_colours_bg(struct tty *, const struct grid_cell *); void tty_redraw_region(struct tty *, const struct tty_ctx *); @@ -1146,17 +1148,9 @@ void tty_attributes(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell, gc2; - u_char changed, new_attr; + u_char changed; - /* If the character is space, don't care about foreground. */ - if (gc->data == ' ' && !(gc->flags & GRID_FLAG_UTF8)) { - memcpy(&gc2, gc, sizeof gc2); - if (gc->attr & GRID_ATTR_REVERSE) - gc2.bg = tc->bg; - else - gc2.fg = tc->fg; - gc = &gc2; - } + memcpy(&gc2, gc, sizeof gc2); /* * If no setab, try to use the reverse attribute as a best-effort for a @@ -1164,34 +1158,32 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) * any serious harm and makes a couple of applications happier. */ if (!tty_term_has(tty->term, TTYC_SETAB)) { - if (gc != &gc2) { - memcpy(&gc2, gc, sizeof gc2); - gc = &gc2; - } - - if (gc->attr & GRID_ATTR_REVERSE) { - if (gc->fg != 7 && gc->fg != 8) + if (gc2.attr & GRID_ATTR_REVERSE) { + if (gc2.fg != 7 && gc2.fg != 8) gc2.attr &= ~GRID_ATTR_REVERSE; } else { - if (gc->bg != 0 && gc->bg != 8) + if (gc2.bg != 0 && gc2.bg != 8) gc2.attr |= GRID_ATTR_REVERSE; } } + /* Fix up the colours if necessary. */ + tty_check_fg(tty, &gc2); + tty_check_bg(tty, &gc2); + /* If any bits are being cleared, reset everything. */ - if (tc->attr & ~gc->attr) + if (tc->attr & ~gc2.attr) tty_reset(tty); /* * Set the colours. This may call tty_reset() (so it comes next) and * may add to (NOT remove) the desired attributes by changing new_attr. */ - new_attr = gc->attr; - tty_colours(tty, gc, &new_attr); + tty_colours(tty, &gc2); /* Filter out attribute bits already set. */ - changed = new_attr & ~tc->attr; - tc->attr = new_attr; + changed = gc2.attr & ~tc->attr; + tc->attr = gc2.attr; /* Set the attributes. */ if (changed & GRID_ATTR_BRIGHT) @@ -1217,7 +1209,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) } void -tty_colours(struct tty *tty, const struct grid_cell *gc, u_char *attr) +tty_colours(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell; u_char fg = gc->fg, bg = gc->bg, flags = gc->flags; @@ -1274,7 +1266,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc, u_char *attr) /* Set the foreground colour. */ if (!fg_default && (fg != tc->fg || ((flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)))) - tty_colours_fg(tty, gc, attr); + tty_colours_fg(tty, gc); /* * Set the background colour. This must come after the foreground as @@ -1286,7 +1278,71 @@ tty_colours(struct tty *tty, const struct grid_cell *gc, u_char *attr) } void -tty_colours_fg(struct tty *tty, const struct grid_cell *gc, u_char *attr) +tty_check_fg(struct tty *tty, struct grid_cell *gc) +{ + u_int colours; + + /* Is this a 256-colour colour? */ + if (gc->flags & GRID_FLAG_FG256) { + /* And not a 256 colour mode? */ + if (!(tty->term->flags & TERM_88COLOURS) && + !(tty->term_flags & TERM_88COLOURS) && + !(tty->term->flags & TERM_256COLOURS) && + !(tty->term_flags & TERM_256COLOURS)) { + gc->fg = colour_256to16(gc->fg); + if (gc->fg & 8) { + gc->fg &= 7; + gc->attr |= GRID_ATTR_BRIGHT; + } else + gc->attr &= ~GRID_ATTR_BRIGHT; + gc->flags &= ~GRID_FLAG_FG256; + } + return; + } + + /* Is this an aixterm colour? */ + colours = tty_term_number(tty->term, TTYC_COLORS); + if (gc->fg >= 90 && gc->fg <= 97 && colours < 16) { + gc->fg -= 90; + gc->attr |= GRID_ATTR_BRIGHT; + } +} + +void +tty_check_bg(struct tty *tty, struct grid_cell *gc) +{ + u_int colours; + + /* Is this a 256-colour colour? */ + if (gc->flags & GRID_FLAG_BG256) { + /* + * And not a 256 colour mode? Translate to 16-colour + * palette. Bold background doesn't exist portably, so just + * discard the bold bit if set. + */ + if (!(tty->term->flags & TERM_88COLOURS) && + !(tty->term_flags & TERM_88COLOURS) && + !(tty->term->flags & TERM_256COLOURS) && + !(tty->term_flags & TERM_256COLOURS)) { + gc->bg = colour_256to16(gc->bg); + if (gc->bg & 8) + gc->bg &= 7; + gc->attr &= ~GRID_ATTR_BRIGHT; + gc->flags &= ~GRID_FLAG_BG256; + } + return; + } + + /* Is this an aixterm colour? */ + colours = tty_term_number(tty->term, TTYC_COLORS); + if (gc->bg >= 100 && gc->bg <= 107 && colours < 16) { + gc->bg -= 90; + gc->attr |= GRID_ATTR_BRIGHT; + } +} + +void +tty_colours_fg(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell; u_char fg = gc->fg; @@ -1299,26 +1355,15 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc, u_char *attr) goto save_fg; if (tty_try_88(tty, fg, "38") == 0) goto save_fg; - - /* Translate to 16-colour palette, updating bold if needed. */ - fg = colour_256to16(fg); - if (fg & 8) { - fg &= 7; - (*attr) |= GRID_ATTR_BRIGHT; - } else - tty_reset(tty); /* turn off bold */ + /* Else already handled by tty_check_fg. */ + return; } /* Is this an aixterm bright colour? */ if (fg >= 90 && fg <= 97) { - /* 16 colour terminals or above only. */ - if (tty_term_number(tty->term, TTYC_COLORS) >= 16) { - xsnprintf(s, sizeof s, "\033[%dm", fg); - tty_puts(tty, s); - goto save_fg; - } - fg -= 90; - (*attr) |= GRID_ATTR_BRIGHT; + xsnprintf(s, sizeof s, "\033[%dm", fg); + tty_puts(tty, s); + goto save_fg; } /* Otherwise set the foreground colour. */ @@ -1345,14 +1390,8 @@ tty_colours_bg(struct tty *tty, const struct grid_cell *gc) goto save_bg; if (tty_try_88(tty, bg, "48") == 0) goto save_bg; - - /* - * Translate to 16-colour palette. Bold background doesn't - * exist portably, so just discard the bold bit if set. - */ - bg = colour_256to16(bg); - if (bg & 8) - bg &= 7; + /* Else already handled by tty_check_bg. */ + return; } /* Is this an aixterm bright colour? */ -- cgit From 43fa9a9ba60f0fba1f5c7985ed9c65cea304d2c4 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 31 May 2010 19:51:29 +0000 Subject: When the mode-mouse option is on, support dragging to make a selection in copy mode. Also support the scroll wheel, although xterm strangely does not ignore it in application mouse mode, causing redraw artifacts when scrolling up (other terminals appear to be better behaved). --- tty.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 72be2c84..92ddf41f 100644 --- a/tty.c +++ b/tty.c @@ -402,11 +402,18 @@ tty_update_mode(struct tty *tty, int mode) else tty_putcode(tty, TTYC_CIVIS); } - if (changed & MODE_MOUSE) { - if (mode & MODE_MOUSE) - tty_puts(tty, "\033[?1000h"); - else - tty_puts(tty, "\033[?1000l"); + if (changed & (MODE_MOUSE|MODE_MOUSEMOTION)) { + if (mode & MODE_MOUSE) { + if (mode & MODE_MOUSEMOTION) + tty_puts(tty, "\033[?1003h"); + else + tty_puts(tty, "\033[?1000h"); + } else { + if (mode & MODE_MOUSEMOTION) + tty_puts(tty, "\033[?1003l"); + else + tty_puts(tty, "\033[?1000l"); + } } if (changed & MODE_KKEYPAD) { if (mode & MODE_KKEYPAD) -- cgit From 0440d325d9dcef2170f2b7695d06d0ba10e9875d Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 5 Jun 2010 16:32:22 +0000 Subject: Shut up gcc4 warnings. --- tty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 92ddf41f..4fe946af 100644 --- a/tty.c +++ b/tty.c @@ -1090,7 +1090,7 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy) * Use HPA if change is larger than absolute, otherwise move * the cursor with CUB/CUF. */ - if (abs(change) > cx && tty_term_has(term, TTYC_HPA)) { + if ((u_int) abs(change) > cx && tty_term_has(term, TTYC_HPA)) { tty_putcode1(tty, TTYC_HPA, cx); goto out; } else if (change > 0 && tty_term_has(term, TTYC_CUB)) { @@ -1126,7 +1126,7 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy) * Try to use VPA if change is larger than absolute or if this * change would cross the scroll region, otherwise use CUU/CUD. */ - if (abs(change) > cy || + if ((u_int) abs(change) > cy || (change < 0 && cy - change > tty->rlower) || (change > 0 && cy - change < tty->rupper)) { if (tty_term_has(term, TTYC_VPA)) { -- cgit From 510ec3fb9e14d5d611d13650f935c945025b12c9 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 5 Jun 2010 16:47:11 +0000 Subject: Fix problems with window sizing seen by Raghavendra D Prabhu when starting tmux from .xinitrc. One of the very few things the server relies on the client for now is to pass through a message on SIGWINCH, but there is a condition where potentially a SIGWINCH may be lost during the transition from unattached (main.c) to attached (client.c). So trigger a size change immediately after the client installs its SIGWINCH handler. Also, when the terminal is resized, reset the scroll region and cursor position. Previously, we were clearing our saved idea of these, but in fact some terminals do not reset them on resize, so this caused problems during redraw. While here make a resize to the same size not cause a redraw and rename the tmux.out output log file to include the tmux PID. --- tty.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 4fe946af..fa2cd552 100644 --- a/tty.c +++ b/tty.c @@ -73,34 +73,55 @@ tty_init(struct tty *tty, int fd, char *term) tty->term_flags = 0; } -void +int tty_resize(struct tty *tty) { struct winsize ws; + u_int sx, sy; if (ioctl(tty->fd, TIOCGWINSZ, &ws) != -1) { - tty->sx = ws.ws_col; - tty->sy = ws.ws_row; + sx = ws.ws_col; + if (sx == 0) + sx = 80; + sy = ws.ws_row; + if (sy == 0) + sy = 24; + } else { + sx = 80; + sy = 24; } - if (tty->sx == 0) - tty->sx = 80; - if (tty->sy == 0) - tty->sy = 24; + if (sx == tty->sx && sy == tty->sy) + return (0); + tty->sx = sx; + tty->sy = sy; tty->cx = UINT_MAX; tty->cy = UINT_MAX; tty->rupper = UINT_MAX; tty->rlower = UINT_MAX; + + /* + * If the terminal has been started, reset the actual scroll region and + * cursor position, as this may not have happened. + */ + if (tty->flags & TTY_STARTED) { + tty_cursor(tty, 0, 0); + tty_region(tty, 0, tty->sy - 1); + } + + return (1); } int tty_open(struct tty *tty, const char *overrides, char **cause) { + char out[64]; int fd; if (debug_level > 3) { - fd = open("tmux.out", O_WRONLY|O_CREAT|O_TRUNC, 0644); + xsnprintf(out, sizeof out, "tmux-out-%ld.log", (long) getpid()); + fd = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0644); if (fd != -1 && fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) fatal("fcntl failed"); tty->log_fd = fd; -- cgit From 8363e31953a346b3cd4141bf30a8d79d37ca2674 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 11 Aug 2010 07:34:43 +0000 Subject: Change the way backoff works. Instead of stopping reading from the pty when the client tty backs up too much, just stop updating the tty and only update the internal screen. Then when the tty recovers, force a redraw. This prevents a dodgy client from causing other clients to go into backoff while still allowing tmux to be responsive (locally) when seeing lots of output. --- tty.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index fa2cd552..bf0a48b0 100644 --- a/tty.c +++ b/tty.c @@ -578,7 +578,9 @@ tty_write(void (*cmdfn)( continue; if (c->session->curw->window == wp->window) { - if (c->tty.flags & TTY_FREEZE || c->tty.term == NULL) + if (c->tty.term == NULL) + continue; + if (c->tty.flags & (TTY_FREEZE|TTY_BACKOFF)) continue; cmdfn(&c->tty, ctx); } -- cgit From cb564bb427b9db5b1e48a74e6b818454f7ab0c77 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 11 Sep 2010 16:19:22 +0000 Subject: Use UTF-8 line drawing characters on UTF-8 terminals. Fixes some stupid terminals (I'm looking at you, putty) which disable the vt100 ACS mode switching sequences in UTF-8 mode. Also on terminals without ACS at all, use ASCII equivalents where obvious. --- tty.c | 55 +++++++++++++++++++------------------------------------ 1 file changed, 19 insertions(+), 36 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index bf0a48b0..642b9766 100644 --- a/tty.c +++ b/tty.c @@ -31,8 +31,6 @@ void tty_read_callback(struct bufferevent *, void *); void tty_error_callback(struct bufferevent *, short, void *); -void tty_fill_acs(struct tty *); - int tty_try_256(struct tty *, u_char, const char *); int tty_try_88(struct tty *, u_char, const char *); @@ -48,6 +46,9 @@ void tty_emulate_repeat( void tty_cell(struct tty *, const struct grid_cell *, const struct grid_utf8 *); +#define tty_use_acs(tty) \ + (tty_term_has(tty, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) + void tty_init(struct tty *tty, int fd, char *term) { @@ -143,8 +144,6 @@ tty_open(struct tty *tty, const char *overrides, char **cause) tty_keys_init(tty); - tty_fill_acs(tty); - return (0); } @@ -201,7 +200,8 @@ tty_start_tty(struct tty *tty) memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell); tty_putcode(tty, TTYC_RMKX); - tty_putcode(tty, TTYC_ENACS); + if (tty_use_acs(tty)) + tty_putcode(tty, TTYC_ENACS); tty_putcode(tty, TTYC_CLEAR); tty_putcode(tty, TTYC_CNORM); @@ -242,7 +242,8 @@ tty_stop_tty(struct tty *tty) return; tty_raw(tty, tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1)); - tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS)); + if (tty_use_acs(tty)) + tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS)); tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0)); tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX)); tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR)); @@ -257,30 +258,6 @@ tty_stop_tty(struct tty *tty) fcntl(tty->fd, F_SETFL, mode & ~O_NONBLOCK); } -void -tty_fill_acs(struct tty *tty) -{ - const char *ptr; - - memset(tty->acs, 0, sizeof tty->acs); - if (!tty_term_has(tty->term, TTYC_ACSC)) - return; - - ptr = tty_term_string(tty->term, TTYC_ACSC); - if (strlen(ptr) % 2 != 0) - return; - for (; *ptr != '\0'; ptr += 2) - tty->acs[(u_char) ptr[0]] = ptr[1]; -} - -u_char -tty_get_acs(struct tty *tty, u_char ch) -{ - if (tty->acs[ch] != '\0') - return (tty->acs[ch]); - return (ch); -} - void tty_close(struct tty *tty) { @@ -360,11 +337,17 @@ tty_puts(struct tty *tty, const char *s) void tty_putc(struct tty *tty, u_char ch) { - u_int sx; + const char *acs; + u_int sx; - if (tty->cell.attr & GRID_ATTR_CHARSET) - ch = tty_get_acs(tty, ch); - bufferevent_write(tty->event, &ch, 1); + if (tty->cell.attr & GRID_ATTR_CHARSET) { + acs = tty_acs_get(tty, ch); + if (acs != NULL) + bufferevent_write(tty->event, acs, strlen(acs)); + else + bufferevent_write(tty->event, &ch, 1); + } else + bufferevent_write(tty->event, &ch, 1); if (ch >= 0x20 && ch != 0x7f) { sx = tty->sx; @@ -997,7 +980,7 @@ tty_reset(struct tty *tty) if (memcmp(gc, &grid_default_cell, sizeof *gc) == 0) return; - if (tty_term_has(tty->term, TTYC_RMACS) && gc->attr & GRID_ATTR_CHARSET) + if ((gc->attr & GRID_ATTR_CHARSET) && tty_use_acs(tty)) tty_putcode(tty, TTYC_RMACS); tty_putcode(tty, TTYC_SGR0); memcpy(gc, &grid_default_cell, sizeof *gc); @@ -1234,7 +1217,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) } if (changed & GRID_ATTR_HIDDEN) tty_putcode(tty, TTYC_INVIS); - if (changed & GRID_ATTR_CHARSET) + if ((changed & GRID_ATTR_CHARSET) && tty_use_acs(tty)) tty_putcode(tty, TTYC_SMACS); } -- cgit From ea4487c6dad37429dbef6e6377f6f8f02f877380 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 11 Sep 2010 16:20:58 +0000 Subject: Ugh. Pass the right type into tty_term_has. Teaches me to make last minute changes :-/. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 642b9766..268ea2e8 100644 --- a/tty.c +++ b/tty.c @@ -47,7 +47,7 @@ void tty_cell(struct tty *, const struct grid_cell *, const struct grid_utf8 *); #define tty_use_acs(tty) \ - (tty_term_has(tty, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) + (tty_term_has(tty->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) void tty_init(struct tty *tty, int fd, char *term) -- cgit From f56b4ec2ffa6d5667a3bd86040a1c771c1de33a5 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 16 Oct 2010 08:31:55 +0000 Subject: Trying to set FD_CLOEXEC on every fd is a lost cause, just use closefrom() before exec. --- tty.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 268ea2e8..379fa42d 100644 --- a/tty.c +++ b/tty.c @@ -61,9 +61,6 @@ tty_init(struct tty *tty, int fd, char *term) tty->termname = xstrdup("unknown"); else tty->termname = xstrdup(term); - - if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) - fatal("fcntl failed"); tty->fd = fd; if ((path = ttyname(fd)) == NULL) -- cgit From ef9b2eb566fc090b773c79e406dd43d0006a3217 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 22 Nov 2010 21:13:13 +0000 Subject: There is somewhere that WINDOW_HIDDEN is getting set when it shouldn't be and I can't find it, but the flag itself is a useless optimisation that only applies to automatic-resize windows, so just dispose of it entirely. Fixes problems reported by Nicholas Riley. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 379fa42d..63f6127f 100644 --- a/tty.c +++ b/tty.c @@ -547,7 +547,7 @@ tty_write(void (*cmdfn)( if (wp->window->flags & WINDOW_REDRAW || wp->flags & PANE_REDRAW) return; - if (wp->window->flags & WINDOW_HIDDEN || !window_pane_visible(wp)) + if (!window_pane_visible(wp)) return; for (i = 0; i < ARRAY_LENGTH(&clients); i++) { -- cgit From f7c42c21bacf84af52079b239a18294851fbdb3a Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 29 Dec 2010 21:49:06 +0000 Subject: Support all four of the xterm mouse modes. Based on a diff from hsim at gmx.li. --- tty.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 63f6127f..f7698708 100644 --- a/tty.c +++ b/tty.c @@ -403,17 +403,25 @@ tty_update_mode(struct tty *tty, int mode) else tty_putcode(tty, TTYC_CIVIS); } - if (changed & (MODE_MOUSE|MODE_MOUSEMOTION)) { - if (mode & MODE_MOUSE) { - if (mode & MODE_MOUSEMOTION) - tty_puts(tty, "\033[?1003h"); - else + if (changed & ALL_MOUSE_MODES) { + if (mode & ALL_MOUSE_MODES) { + if (mode & MODE_MOUSE_STANDARD) tty_puts(tty, "\033[?1000h"); + else if (mode & MODE_MOUSE_HIGHLIGHT) + tty_puts(tty, "\033[?1001h"); + else if (mode & MODE_MOUSE_BUTTON) + tty_puts(tty, "\033[?1002h"); + else if (mode & MODE_MOUSE_ANY) + tty_puts(tty, "\033[?1003h"); } else { - if (mode & MODE_MOUSEMOTION) - tty_puts(tty, "\033[?1003l"); - else + if (tty->mode & MODE_MOUSE_STANDARD) tty_puts(tty, "\033[?1000l"); + else if (tty->mode & MODE_MOUSE_HIGHLIGHT) + tty_puts(tty, "\033[?1001l"); + else if (tty->mode & MODE_MOUSE_BUTTON) + tty_puts(tty, "\033[?1002l"); + else if (tty->mode & MODE_MOUSE_ANY) + tty_puts(tty, "\033[?1003l"); } } if (changed & MODE_KKEYPAD) { -- cgit From ac3b78a84178a308536a56ea114b0f6f8ce6fb47 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 3 Jan 2011 23:35:21 +0000 Subject: Support for UTF-8 mouse input (\033[1005h). This was added in xterm 262 and supports larger terminals than the older way. If the new mouse-utf8 option is on, UTF-8 mouse input is enabled for all UTF-8 terminals. The option defaults to on if LANG etc are set in the same manner as the utf8 option. With help and based on code from hsim at gmx.li. --- tty.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index f7698708..80afa2d4 100644 --- a/tty.c +++ b/tty.c @@ -405,6 +405,8 @@ tty_update_mode(struct tty *tty, int mode) } if (changed & ALL_MOUSE_MODES) { if (mode & ALL_MOUSE_MODES) { + if (mode & MODE_MOUSE_UTF8) + tty_puts(tty, "\033[?1005h"); if (mode & MODE_MOUSE_STANDARD) tty_puts(tty, "\033[?1000h"); else if (mode & MODE_MOUSE_HIGHLIGHT) @@ -422,6 +424,8 @@ tty_update_mode(struct tty *tty, int mode) tty_puts(tty, "\033[?1002l"); else if (tty->mode & MODE_MOUSE_ANY) tty_puts(tty, "\033[?1003l"); + if (tty->mode & MODE_MOUSE_UTF8) + tty_puts(tty, "\033[?1005l"); } } if (changed & MODE_KKEYPAD) { -- cgit From 69cb1f830e4fd2282ddcbc7ee2bbe30069b9e4cd Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 8 Jan 2011 01:52:36 +0000 Subject: Move all calls to fcntl(...O_NONBLOCK) into a function and clear the flag on the stdio file descriptors before closing them (fixes things like "tmux ls && cat"). --- tty.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 80afa2d4..451a5df6 100644 --- a/tty.c +++ b/tty.c @@ -165,15 +165,11 @@ void tty_start_tty(struct tty *tty) { struct termios tio; - int mode; if (tty->fd == -1) return; - if ((mode = fcntl(tty->fd, F_GETFL)) == -1) - fatal("fcntl failed"); - if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1) - fatal("fcntl failed"); + setblocking(tty->fd, 0); bufferevent_enable(tty->event, EV_READ|EV_WRITE); @@ -220,7 +216,6 @@ void tty_stop_tty(struct tty *tty) { struct winsize ws; - int mode; if (!(tty->flags & TTY_STARTED)) return; @@ -251,8 +246,7 @@ tty_stop_tty(struct tty *tty) tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); - if ((mode = fcntl(tty->fd, F_GETFL)) != -1) - fcntl(tty->fd, F_SETFL, mode & ~O_NONBLOCK); + setblocking(tty->fd, 1); } void -- cgit From 8f8e81c0c9a39b2977e3b2737d4825ab00bef52a Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 15 Jan 2011 00:16:00 +0000 Subject: Mouse highlight mode (1001) requires a program to cooperate so supporting it through tmux is not as easy as this, remove it for now. --- tty.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 451a5df6..aff0d08a 100644 --- a/tty.c +++ b/tty.c @@ -403,8 +403,6 @@ tty_update_mode(struct tty *tty, int mode) tty_puts(tty, "\033[?1005h"); if (mode & MODE_MOUSE_STANDARD) tty_puts(tty, "\033[?1000h"); - else if (mode & MODE_MOUSE_HIGHLIGHT) - tty_puts(tty, "\033[?1001h"); else if (mode & MODE_MOUSE_BUTTON) tty_puts(tty, "\033[?1002h"); else if (mode & MODE_MOUSE_ANY) @@ -412,8 +410,6 @@ tty_update_mode(struct tty *tty, int mode) } else { if (tty->mode & MODE_MOUSE_STANDARD) tty_puts(tty, "\033[?1000l"); - else if (tty->mode & MODE_MOUSE_HIGHLIGHT) - tty_puts(tty, "\033[?1001l"); else if (tty->mode & MODE_MOUSE_BUTTON) tty_puts(tty, "\033[?1002l"); else if (tty->mode & MODE_MOUSE_ANY) -- cgit From 3de1700f616a60a7c7d15a66b0637012b5cdb00a Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 15 Jan 2011 00:46:19 +0000 Subject: Only set a mouse mode for mouse-select-pane if none already set by the mode (any will do). --- tty.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index aff0d08a..497dacc6 100644 --- a/tty.c +++ b/tty.c @@ -401,19 +401,19 @@ tty_update_mode(struct tty *tty, int mode) if (mode & ALL_MOUSE_MODES) { if (mode & MODE_MOUSE_UTF8) tty_puts(tty, "\033[?1005h"); - if (mode & MODE_MOUSE_STANDARD) - tty_puts(tty, "\033[?1000h"); + if (mode & MODE_MOUSE_ANY) + tty_puts(tty, "\033[?1003h"); else if (mode & MODE_MOUSE_BUTTON) tty_puts(tty, "\033[?1002h"); - else if (mode & MODE_MOUSE_ANY) - tty_puts(tty, "\033[?1003h"); + else if (mode & MODE_MOUSE_STANDARD) + tty_puts(tty, "\033[?1000h"); } else { - if (tty->mode & MODE_MOUSE_STANDARD) - tty_puts(tty, "\033[?1000l"); + if (tty->mode & MODE_MOUSE_ANY) + tty_puts(tty, "\033[?1003l"); else if (tty->mode & MODE_MOUSE_BUTTON) tty_puts(tty, "\033[?1002l"); - else if (tty->mode & MODE_MOUSE_ANY) - tty_puts(tty, "\033[?1003l"); + else if (tty->mode & MODE_MOUSE_STANDARD) + tty_puts(tty, "\033[?1000l"); if (tty->mode & MODE_MOUSE_UTF8) tty_puts(tty, "\033[?1005l"); } -- cgit From 9fc2c34a3b794b6724c1e3fc96f55ee199286c44 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 29 Jan 2011 08:39:43 +0000 Subject: Accept tcgetattr/tcsetattr failure, fixes problems with fatal() if the terminal disappears while locked. --- tty.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 497dacc6..b44c5974 100644 --- a/tty.c +++ b/tty.c @@ -166,15 +166,13 @@ tty_start_tty(struct tty *tty) { struct termios tio; - if (tty->fd == -1) + if (tty->fd == -1 || tcgetattr(tty->fd, &tty->tio) != 0) return; setblocking(tty->fd, 0); bufferevent_enable(tty->event, EV_READ|EV_WRITE); - if (tcgetattr(tty->fd, &tty->tio) != 0) - fatal("tcgetattr failed"); memcpy(&tio, &tty->tio, sizeof tio); tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|IMAXBEL|ISTRIP); tio.c_iflag |= IGNBRK; @@ -183,9 +181,8 @@ tty_start_tty(struct tty *tty) ECHOPRT|ECHOKE|ECHOCTL|ISIG); tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; - if (tcsetattr(tty->fd, TCSANOW, &tio) != 0) - fatal("tcsetattr failed"); - tcflush(tty->fd, TCIOFLUSH); + if (tcsetattr(tty->fd, TCSANOW, &tio) == 0) + tcflush(tty->fd, TCIOFLUSH); tty_putcode(tty, TTYC_SMCUP); -- cgit From 79e30daeae1d49a1cf1dc4618edf1ec82804a80c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 7 Mar 2011 23:46:27 +0000 Subject: Support passing through escape sequences to the underlying terminal by using DCS with a "tmux;" prefix. Escape characters in the sequences must be doubled. For example: $ printf '\033Ptmux;\033\033]12;red\007\033\\' Will pass \033]12;red\007 to the terminal (and change the cursor colour in xterm). From Kevin Goodsell. --- tty.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index b44c5974..46b8a475 100644 --- a/tty.c +++ b/tty.c @@ -931,6 +931,16 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx) tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); } +void +tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx) +{ + u_int i; + u_char *str = ctx->ptr; + + for (i = 0; i < ctx->num; i++) + tty_putc(tty, str[i]); +} + void tty_cell( struct tty *tty, const struct grid_cell *gc, const struct grid_utf8 *gu) -- cgit From 54456d5602fb05ac30af0167242deaa44adf83ae Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 8 Mar 2011 19:23:49 +0000 Subject: Fix an incorrect test which was always true (oupper is always < olower), from Yusuke ENDOH. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 46b8a475..82162097 100644 --- a/tty.c +++ b/tty.c @@ -454,7 +454,7 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx) * without this, the entire pane ends up being redrawn many times which * can be much more data. */ - if (ctx->orupper - ctx->orlower >= screen_size_y(s) / 2) { + if (ctx->orlower - ctx->orupper >= screen_size_y(s) / 2) { wp->flags |= PANE_REDRAW; return; } -- cgit From d74e5bffbad33df742749b5983479dc2cfac273b Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 26 Mar 2011 19:07:33 +0000 Subject: Fix to properly wrap wide characters, from Micah Cowan. --- tty.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 82162097..57f0d217 100644 --- a/tty.c +++ b/tty.c @@ -892,11 +892,19 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; u_int cx; + u_int width; + const struct grid_cell *gc = ctx->cell; + const struct grid_utf8 *gu = ctx->utf8; + + if (gc->flags & GRID_FLAG_UTF8) + width = gu->width; + else + width = 1; tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); /* Is the cursor in the very last position? */ - if (ctx->ocx > wp->sx - ctx->last_width) { + if (ctx->ocx > wp->sx - width) { if (wp->xoff != 0 || wp->sx != tty->sx) { /* * The pane doesn't fill the entire line, the linefeed @@ -906,10 +914,10 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) } else if (tty->cx < tty->sx) { /* * The cursor isn't in the last position already, so - * move as far left as possinble and redraw the last + * move as far left as possible and redraw the last * cell to move into the last position. */ - cx = screen_size_x(s) - ctx->last_width; + cx = screen_size_x(s) - width; tty_cursor_pane(tty, ctx, cx, ctx->ocy); tty_cell(tty, &ctx->last_cell, &ctx->last_utf8); } -- cgit From 71e8e26ccc85a07c59d9b607c0e248376fa0a447 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 27 Mar 2011 20:36:19 +0000 Subject: Set the terminal blocking again earlier, before sending the reset sequences. --- tty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 57f0d217..bffb1f93 100644 --- a/tty.c +++ b/tty.c @@ -230,6 +230,8 @@ tty_stop_tty(struct tty *tty) if (tcsetattr(tty->fd, TCSANOW, &tty->tio) == -1) return; + setblocking(tty->fd, 1); + tty_raw(tty, tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1)); if (tty_use_acs(tty)) tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS)); @@ -242,8 +244,6 @@ tty_stop_tty(struct tty *tty) tty_raw(tty, "\033[?1000l"); tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); - - setblocking(tty->fd, 1); } void -- cgit From 0a09d04e1b63f816fb2bf16570ef63418349a4bf Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 9 Apr 2011 07:48:08 +0000 Subject: If the terminal supports sitm for italics, use it instead of standout (smso). From Tiago Resende. --- tty.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index bffb1f93..73dff0be 100644 --- a/tty.c +++ b/tty.c @@ -1218,7 +1218,12 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) if (changed & GRID_ATTR_DIM) tty_putcode(tty, TTYC_DIM); if (changed & GRID_ATTR_ITALICS) - tty_putcode(tty, TTYC_SMSO); + { + if (tty_term_has(tty->term, TTYC_SITM)) + tty_putcode(tty, TTYC_SITM); + else + tty_putcode(tty, TTYC_SMSO); + } if (changed & GRID_ATTR_UNDERSCORE) tty_putcode(tty, TTYC_SMUL); if (changed & GRID_ATTR_BLINK) -- cgit From 295ace682020769be8a6a6a02835099d93c392ef Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 8 May 2011 19:53:06 +0000 Subject: Use the tsl and fsl terminfo(5) capabilities to update terminal title and automatically fill them in on terminals with the XT capability (which means their title setting is xterm-compatible). From hsim at gmx.li. --- tty.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 73dff0be..b423f6d8 100644 --- a/tty.c +++ b/tty.c @@ -369,14 +369,13 @@ tty_pututf8(struct tty *tty, const struct grid_utf8 *gu) void tty_set_title(struct tty *tty, const char *title) { - if (strstr(tty->termname, "xterm") == NULL && - strstr(tty->termname, "rxvt") == NULL && - strcmp(tty->termname, "screen") != 0) + if (!tty_term_has(tty->term, TTYC_TSL) || + !tty_term_has(tty->term, TTYC_FSL)) return; - tty_puts(tty, "\033]0;"); + tty_putcode(tty, TTYC_TSL); tty_puts(tty, title); - tty_putc(tty, '\007'); + tty_putcode(tty, TTYC_FSL); } void -- cgit From 96e7f33da3078facc504c6c66d42956bc44b2e54 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 18 May 2011 20:24:29 +0000 Subject: Support setting the xterm clipboard when copying from copy mode using the xterm escape sequence for the purpose (if xterm is configured to allow it). Written by and much discussed Ailin Nemui, guidance on xterm/termcap/terminfo from Thomas Dickey. --- tty.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index b423f6d8..04503b60 100644 --- a/tty.c +++ b/tty.c @@ -19,8 +19,11 @@ #include #include +#include + #include #include +#include #include #include #include @@ -311,6 +314,13 @@ tty_putcode2(struct tty *tty, enum tty_code_code code, int a, int b) tty_puts(tty, tty_term_string2(tty->term, code, a, b)); } +void +tty_putcode_ptr2(struct tty *tty, enum tty_code_code code, const void *a, const void *b) +{ + if (a != NULL && b != NULL) + tty_puts(tty, tty_term_ptr2(tty->term, code, a, b)); +} + void tty_puts(struct tty *tty, const char *s) { @@ -938,6 +948,24 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx) tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); } +void +tty_cmd_setselection(struct tty *tty, const struct tty_ctx *ctx) +{ + char *buf; + size_t off; + + if (!tty_term_has(tty->term, TTYC_MS)) + return; + + off = 4 * ((ctx->num + 2) / 3) + 1; /* storage for base64 */ + buf = xmalloc(off); + + b64_ntop(ctx->ptr, ctx->num, buf, off); + tty_putcode_ptr2(tty, TTYC_MS, "", buf); + + xfree(buf); +} + void tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx) { -- cgit From 944b5e6fa04e014501f465e3898315c84d10bd9e Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 20 May 2011 19:03:58 +0000 Subject: Support xterm(1) cursor colour change sequences through terminfo(5) Cc (set) and Cr (reset) extensions. Originally by Sean Estabrooks, tweaked by me and Ailin Nemui. --- tty.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 04503b60..5f3ada8e 100644 --- a/tty.c +++ b/tty.c @@ -69,6 +69,7 @@ tty_init(struct tty *tty, int fd, char *term) if ((path = ttyname(fd)) == NULL) fatalx("ttyname failed"); tty->path = xstrdup(path); + tty->ccolour = xstrdup(""); tty->flags = 0; tty->term_flags = 0; @@ -210,6 +211,8 @@ tty_start_tty(struct tty *tty) tty->mode = MODE_CURSOR; tty->flags |= TTY_STARTED; + + tty_force_cursor_colour(tty, ""); } void @@ -241,6 +244,7 @@ tty_stop_tty(struct tty *tty) tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0)); tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX)); tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR)); + tty_raw(tty, tty_term_string(tty->term, TTYC_CR)); tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM)); if (tty_term_has(tty->term, TTYC_KMOUS)) @@ -280,6 +284,7 @@ tty_free(struct tty *tty) { tty_close(tty); + xfree(tty->ccolour); if (tty->path != NULL) xfree(tty->path); if (tty->termname != NULL) @@ -314,6 +319,13 @@ tty_putcode2(struct tty *tty, enum tty_code_code code, int a, int b) tty_puts(tty, tty_term_string2(tty->term, code, a, b)); } +void +tty_putcode_ptr1(struct tty *tty, enum tty_code_code code, const void *a) +{ + if (a != NULL) + tty_puts(tty, tty_term_ptr1(tty->term, code, a)); +} + void tty_putcode_ptr2(struct tty *tty, enum tty_code_code code, const void *a, const void *b) { @@ -389,10 +401,24 @@ tty_set_title(struct tty *tty, const char *title) } void -tty_update_mode(struct tty *tty, int mode) +tty_force_cursor_colour(struct tty *tty, const char *ccolour) +{ + if (*ccolour == '\0') + tty_putcode(tty, TTYC_CR); + else + tty_putcode_ptr1(tty, TTYC_CC, ccolour); + xfree(tty->ccolour); + tty->ccolour = xstrdup(ccolour); +} + +void +tty_update_mode(struct tty *tty, int mode, struct screen *s) { int changed; + if (strcmp(s->ccolour, tty->ccolour)) + tty_force_cursor_colour(tty, s->ccolour); + if (tty->flags & TTY_NOCURSOR) mode &= ~MODE_CURSOR; @@ -486,7 +512,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) const struct grid_utf8 *gu; u_int i, sx; - tty_update_mode(tty, tty->mode & ~MODE_CURSOR); + tty_update_mode(tty, tty->mode & ~MODE_CURSOR, s); sx = screen_size_x(s); if (sx > s->grid->linedata[s->grid->hsize + py].cellsize) @@ -526,7 +552,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) } if (sx >= tty->sx) { - tty_update_mode(tty, tty->mode); + tty_update_mode(tty, tty->mode, s); return; } tty_reset(tty); @@ -538,7 +564,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) for (i = sx; i < screen_size_x(s); i++) tty_putc(tty, ' '); } - tty_update_mode(tty, tty->mode); + tty_update_mode(tty, tty->mode, s); } void -- cgit From 3ea5e06bfb04278fa53885e551bc363a84bad8d1 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 20 May 2011 19:17:39 +0000 Subject: Support DECSCUSR sequence to set the cursor style with two new terminfo(5) extensions, Cs and Csr. Written by Ailin Nemui. --- tty.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 5f3ada8e..4fcf6f55 100644 --- a/tty.c +++ b/tty.c @@ -69,6 +69,7 @@ tty_init(struct tty *tty, int fd, char *term) if ((path = ttyname(fd)) == NULL) fatalx("ttyname failed"); tty->path = xstrdup(path); + tty->cstyle = 0; tty->ccolour = xstrdup(""); tty->flags = 0; @@ -244,6 +245,12 @@ tty_stop_tty(struct tty *tty) tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0)); tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX)); tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR)); + if (tty_term_has(tty->term, TTYC_CS1) && tty->cstyle != 0) { + if (tty_term_has(tty->term, TTYC_CSR1)) + tty_raw(tty, tty_term_string(tty->term, TTYC_CSR1)); + else if (tty_term_has(tty->term, TTYC_CS1)) + tty_raw(tty, tty_term_string1(tty->term, TTYC_CS1, 0)); + } tty_raw(tty, tty_term_string(tty->term, TTYC_CR)); tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM)); @@ -429,6 +436,16 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s) else tty_putcode(tty, TTYC_CIVIS); } + if (tty->cstyle != s->cstyle) { + if (tty_term_has(tty->term, TTYC_CS1)) { + if (s->cstyle == 0 && + tty_term_has(tty->term, TTYC_CSR1)) + tty_putcode(tty, TTYC_CSR1); + else + tty_putcode1(tty, TTYC_CS1, s->cstyle); + } + tty->cstyle = s->cstyle; + } if (changed & ALL_MOUSE_MODES) { if (mode & ALL_MOUSE_MODES) { if (mode & MODE_MOUSE_UTF8) -- cgit From 34e5ec18074b05f8ffc95bdefe7f7037ff046ecf Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 26 May 2011 07:08:48 +0000 Subject: Trim another useless if statement, from Ailin Nemui. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 4fcf6f55..efd779a6 100644 --- a/tty.c +++ b/tty.c @@ -248,7 +248,7 @@ tty_stop_tty(struct tty *tty) if (tty_term_has(tty->term, TTYC_CS1) && tty->cstyle != 0) { if (tty_term_has(tty->term, TTYC_CSR1)) tty_raw(tty, tty_term_string(tty->term, TTYC_CSR1)); - else if (tty_term_has(tty->term, TTYC_CS1)) + else tty_raw(tty, tty_term_string1(tty->term, TTYC_CS1, 0)); } tty_raw(tty, tty_term_string(tty->term, TTYC_CR)); -- cgit From 029c34ce6bc76168d06726bc81bda4514d245054 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 24 Aug 2011 09:58:44 +0000 Subject: Add a tty_bell wrapper function, from Dylan Alex Simon. --- tty.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index efd779a6..dce4887b 100644 --- a/tty.c +++ b/tty.c @@ -1546,3 +1546,9 @@ tty_try_88(struct tty *tty, u_char colour, const char *type) tty_puts(tty, s); return (0); } + +void +tty_bell(struct tty *tty) +{ + tty_putcode(tty, TTYC_BEL); +} -- cgit From 299a8fd4a3ced13ed678f888aa1b61484a2b613d Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 15 Jan 2012 19:39:42 +0000 Subject: Calculate last position correctly for UTF-8 wide characters, reported by Matthias Lederhofer. --- tty.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index dce4887b..d5fc106e 100644 --- a/tty.c +++ b/tty.c @@ -969,7 +969,10 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) * move as far left as possible and redraw the last * cell to move into the last position. */ - cx = screen_size_x(s) - width; + if (ctx->last_cell.flags & GRID_FLAG_UTF8) + cx = screen_size_x(s) - ctx->last_utf8.width; + else + cx = screen_size_x(s) - 1; tty_cursor_pane(tty, ctx, cx, ctx->ocy); tty_cell(tty, &ctx->last_cell, &ctx->last_utf8); } -- cgit From 7f24020cbe477548795754f2f7f01aafc2cd3cb8 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 21 Jan 2012 08:23:12 +0000 Subject: Add strings to allow the aixterm bright colours to be used when configuring colours, requested by Elliott Cable a few months ago. --- tty.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index d5fc106e..51718c3c 100644 --- a/tty.c +++ b/tty.c @@ -1440,7 +1440,7 @@ tty_check_bg(struct tty *tty, struct grid_cell *gc) /* Is this an aixterm colour? */ colours = tty_term_number(tty->term, TTYC_COLORS); - if (gc->bg >= 100 && gc->bg <= 107 && colours < 16) { + if (gc->bg >= 90 && gc->bg <= 97 && colours < 16) { gc->bg -= 90; gc->attr |= GRID_ATTR_BRIGHT; } @@ -1500,14 +1500,14 @@ tty_colours_bg(struct tty *tty, const struct grid_cell *gc) } /* Is this an aixterm bright colour? */ - if (bg >= 100 && bg <= 107) { + if (bg >= 90 && bg <= 97) { /* 16 colour terminals or above only. */ if (tty_term_number(tty->term, TTYC_COLORS) >= 16) { - xsnprintf(s, sizeof s, "\033[%dm", bg); + xsnprintf(s, sizeof s, "\033[%dm", bg + 10); tty_puts(tty, s); goto save_bg; } - bg -= 100; + bg -= 90; /* no such thing as a bold background */ } -- cgit From 230d0fbc9e273a171e811f58b540163fe871df5e Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 29 Jan 2012 09:37:02 +0000 Subject: Add an option to move the status line to the top of the screen, requested by many. --- tty.c | 65 +++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 30 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 51718c3c..6e3e2cf2 100644 --- a/tty.c +++ b/tty.c @@ -513,10 +513,10 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) { for (i = ctx->ocy; i < screen_size_y(s); i++) - tty_draw_line(tty, s, i, wp->xoff, wp->yoff); + tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff); } else { for (i = ctx->orupper; i <= ctx->orlower; i++) - tty_draw_line(tty, s, i, wp->xoff, wp->yoff); + tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff); } } @@ -585,11 +585,13 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) } void -tty_write(void (*cmdfn)( - struct tty *, const struct tty_ctx *), const struct tty_ctx *ctx) +tty_write( + void (*cmdfn)(struct tty *, const struct tty_ctx *), struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct client *c; + struct session *s; + struct options *oo; u_int i; /* wp can be NULL if updating the screen but not the terminal. */ @@ -607,12 +609,20 @@ tty_write(void (*cmdfn)( continue; if (c->flags & CLIENT_SUSPENDED) continue; + s = c->session; - if (c->session->curw->window == wp->window) { + if (s->curw->window == wp->window) { if (c->tty.term == NULL) continue; if (c->tty.flags & (TTY_FREEZE|TTY_BACKOFF)) continue; + oo = &s->options; + + ctx->xoff = wp->xoff; + ctx->yoff = wp->yoff; + if (status_at_line(c) == 0) + ctx->yoff++; + cmdfn(&c->tty, ctx); } } @@ -625,8 +635,8 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) struct screen *s = wp->screen; u_int i; - if (wp->xoff != 0 || screen_size_x(s) < tty->sx) { - tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); + if (ctx->xoff != 0 || screen_size_x(s) < tty->sx) { + tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); return; } @@ -644,7 +654,7 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) tty_putc(tty, ' '); tty_putcode(tty, TTYC_RMIR); } else - tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); + tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); } void @@ -653,10 +663,10 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + if (ctx->xoff != 0 || screen_size_x(s) < tty->sx || (!tty_term_has(tty->term, TTYC_DCH) && !tty_term_has(tty->term, TTYC_DCH1))) { - tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); + tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); return; } @@ -675,7 +685,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + if (ctx->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_IL1)) { tty_redraw_region(tty, ctx); @@ -696,7 +706,7 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + if (ctx->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_DL1)) { tty_redraw_region(tty, ctx); @@ -722,7 +732,7 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) tty_cursor_pane(tty, ctx, 0, ctx->ocy); - if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && + if (ctx->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { tty_putcode(tty, TTYC_EL); } else { @@ -742,7 +752,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && + if (ctx->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); else { @@ -754,12 +764,11 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; - u_int i; + u_int i; tty_reset(tty); - if (wp->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) { + if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) { tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); tty_putcode(tty, TTYC_EL1); } else { @@ -778,7 +787,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy != ctx->orupper) return; - if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + if (ctx->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_RI)) { tty_redraw_region(tty, ctx); @@ -802,7 +811,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy != ctx->orlower) return; - if (wp->xoff != 0 || screen_size_x(s) < tty->sx || + if (ctx->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { tty_redraw_region(tty, ctx); return; @@ -836,7 +845,7 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && + if (ctx->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { tty_putcode(tty, TTYC_EL); if (ctx->ocy != screen_size_y(s) - 1) { @@ -872,7 +881,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, 0, 0); - if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && + if (ctx->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { for (i = 0; i < ctx->ocy; i++) { tty_putcode(tty, TTYC_EL); @@ -902,7 +911,7 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, 0, 0); - if (wp->xoff == 0 && screen_size_x(s) >= tty->sx && + if (ctx->xoff == 0 && screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) { for (i = 0; i < screen_size_y(s); i++) { tty_putcode(tty, TTYC_EL); @@ -957,7 +966,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) /* Is the cursor in the very last position? */ if (ctx->ocx > wp->sx - width) { - if (wp->xoff != 0 || wp->sx != tty->sx) { + if (ctx->xoff != 0 || wp->sx != tty->sx) { /* * The pane doesn't fill the entire line, the linefeed * will already have happened, so just move the cursor. @@ -991,7 +1000,7 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx) * Cannot rely on not being a partial character, so just redraw the * whole line. */ - tty_draw_line(tty, wp->screen, ctx->ocy, wp->xoff, wp->yoff); + tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); } void @@ -1078,9 +1087,7 @@ void tty_region_pane( struct tty *tty, const struct tty_ctx *ctx, u_int rupper, u_int rlower) { - struct window_pane *wp = ctx->wp; - - tty_region(tty, wp->yoff + rupper, wp->yoff + rlower); + tty_region(tty, ctx->yoff + rupper, ctx->yoff + rlower); } /* Set region at absolute position. */ @@ -1112,9 +1119,7 @@ tty_region(struct tty *tty, u_int rupper, u_int rlower) void tty_cursor_pane(struct tty *tty, const struct tty_ctx *ctx, u_int cx, u_int cy) { - struct window_pane *wp = ctx->wp; - - tty_cursor(tty, wp->xoff + cx, wp->yoff + cy); + tty_cursor(tty, ctx->xoff + cx, ctx->yoff + cy); } /* Move cursor to absolute position. */ -- cgit From fddbd44c185c44ad1fff37d5113519eda883e702 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 15 Feb 2012 17:25:02 +0000 Subject: Add a wrapper function tty_set_size from George Nachman. --- tty.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 6e3e2cf2..6b0e503d 100644 --- a/tty.c +++ b/tty.c @@ -93,10 +93,8 @@ tty_resize(struct tty *tty) sx = 80; sy = 24; } - if (sx == tty->sx && sy == tty->sy) + if (!tty_set_size(tty, sx, sy)) return (0); - tty->sx = sx; - tty->sy = sy; tty->cx = UINT_MAX; tty->cy = UINT_MAX; @@ -116,6 +114,15 @@ tty_resize(struct tty *tty) return (1); } +int +tty_set_size(struct tty *tty, u_int sx, u_int sy) { + if (sx == tty->sx && sy == tty->sy) + return (0); + tty->sx = sx; + tty->sy = sy; + return (1); +} + int tty_open(struct tty *tty, const char *overrides, char **cause) { -- cgit From f4fdddc9306886e3ab5257f40003f6db83ac926b Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 3 Mar 2012 09:43:22 +0000 Subject: Support "bracketed paste" mode. This adds a -p flag to paste-buffer - if this is used and the application has requested bracketed pastes, then tmux surrounds the pasted text by \033[200~ and \033[201~. Applications like vim can (apparently) use this to avoid, for example, indenting the text. From Ailin Nemui. --- tty.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 6b0e503d..bbe2f1da 100644 --- a/tty.c +++ b/tty.c @@ -480,6 +480,12 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s) else tty_putcode(tty, TTYC_RMKX); } + if (changed & MODE_BRACKETPASTE) { + if (mode & MODE_BRACKETPASTE) + tty_puts(tty, "\033[?2004h"); + else + tty_puts(tty, "\033[?2004l"); + } tty->mode = mode; } -- cgit From 799f437effd83d8aaf03c82919e5acfbfa79230f Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 9 Mar 2012 21:42:13 +0000 Subject: Remove some bits leftover from unused backoff code. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index bbe2f1da..81c964b4 100644 --- a/tty.c +++ b/tty.c @@ -627,7 +627,7 @@ tty_write( if (s->curw->window == wp->window) { if (c->tty.term == NULL) continue; - if (c->tty.flags & (TTY_FREEZE|TTY_BACKOFF)) + if (c->tty.flags & TTY_FREEZE) continue; oo = &s->options; -- cgit From 31ddae77358b620c9b1776a472711018916ba1cb Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 12 Mar 2012 12:38:42 +0000 Subject: Use EL to clear to end of line if possible. --- tty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 81c964b4..80d2c4c4 100644 --- a/tty.c +++ b/tty.c @@ -588,7 +588,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) tty_reset(tty); tty_cursor(tty, ox + sx, oy + py); - if (screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) + if (ox + sx + screen_size_x(s) >= tty->sx && + tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); else { for (i = sx; i < screen_size_x(s); i++) -- cgit From 575bfa4b4b6d6f702abf4a6abf6cf1c82bf10b53 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 12 Mar 2012 12:43:18 +0000 Subject: Erm, use EL in a way that actually works... --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 80d2c4c4..502f2b98 100644 --- a/tty.c +++ b/tty.c @@ -588,7 +588,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) tty_reset(tty); tty_cursor(tty, ox + sx, oy + py); - if (ox + sx + screen_size_x(s) >= tty->sx && + if (ox + screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); else { -- cgit From 698361ccde262b82ce91c81891b767f6752ebf67 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 15 Mar 2012 09:10:33 +0000 Subject: Add a helper function for enabling an optimization to make some code clearer. --- tty.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 502f2b98..7c54913d 100644 --- a/tty.c +++ b/tty.c @@ -501,6 +501,19 @@ tty_emulate_repeat( } } +/* + * Is the region large enough to be worth redrawing once later rather than + * probably several times now? Currently yes if it is more than 50% of the + * pane. + */ +int +tty_large_region(unused struct tty *tty, const struct tty_ctx *ctx) +{ + struct window_pane *wp = ctx->wp; + + return (ctx->orlower - ctx->orupper >= screen_size_y(wp->screen) / 2); +} + /* * Redraw scroll region using data from screen (already updated). Used when * CSR not supported, or window is a pane that doesn't take up the full @@ -514,12 +527,10 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx) u_int i; /* - * If region is >= 50% of the screen, just schedule a window redraw. In - * most cases, this is likely to be followed by some more scrolling - - * without this, the entire pane ends up being redrawn many times which - * can be much more data. + * If region is large, schedule a window redraw. In most cases this is + * likely to be followed by some more scrolling. */ - if (ctx->orlower - ctx->orupper >= screen_size_y(s) / 2) { + if (tty_large_region(tty, ctx)) { wp->flags |= PANE_REDRAW; return; } -- cgit From 005566f915030d269fdf7a42e619f8469099b0f0 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 15 Mar 2012 09:22:31 +0000 Subject: Fix a warning. Doh. --- tty.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 7c54913d..5494ad4d 100644 --- a/tty.c +++ b/tty.c @@ -43,6 +43,7 @@ void tty_check_bg(struct tty *, struct grid_cell *); void tty_colours_fg(struct tty *, const struct grid_cell *); void tty_colours_bg(struct tty *, const struct grid_cell *); +int tty_large_region(struct tty *, const struct tty_ctx *); void tty_redraw_region(struct tty *, const struct tty_ctx *); void tty_emulate_repeat( struct tty *, enum tty_code_code, enum tty_code_code, u_int); -- cgit From c8c0d681285938a0f8f6aaa34f85ca50c5494f1d Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 15 Mar 2012 10:36:00 +0000 Subject: Send secondary DA to terminals with XT in terminfo when starting up and parse it to work out the xterm version. --- tty.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 5494ad4d..bf5eac09 100644 --- a/tty.c +++ b/tty.c @@ -211,6 +211,9 @@ tty_start_tty(struct tty *tty) if (tty_term_has(tty->term, TTYC_KMOUS)) tty_puts(tty, "\033[?1000l"); + if (tty_term_has(tty->term, TTYC_XT)) + tty_puts(tty, "\033[>c"); + tty->cx = UINT_MAX; tty->cy = UINT_MAX; -- cgit From 0489213b1bf6a3fc7e158951ba993f4b88f48557 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 17 Mar 2012 17:36:03 +0000 Subject: Revert screen-write.c r1.54 and fix the bug properly. After wrapping a line in a pane, the cursor needs to move to the next line unless it scrolled. --- tty.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index bf5eac09..c7e603c1 100644 --- a/tty.c +++ b/tty.c @@ -1000,7 +1000,10 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) * The pane doesn't fill the entire line, the linefeed * will already have happened, so just move the cursor. */ - tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1); + if (ctx->ocy != wp->yoff + wp->sy) + tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1); + else + tty_cursor_pane(tty, ctx, 0, ctx->ocy); } else if (tty->cx < tty->sx) { /* * The cursor isn't in the last position already, so -- cgit From d3c842d3678e52275c944123f00a2a974eb5d965 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 17 Mar 2012 18:24:07 +0000 Subject: Check event_initialized before event_del if event may not have been set up; libevent2 complains about this. Reported by Moriyoshi Koizumi. --- tty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index c7e603c1..4ea999ba 100644 --- a/tty.c +++ b/tty.c @@ -279,7 +279,8 @@ tty_close(struct tty *tty) tty->log_fd = -1; } - evtimer_del(&tty->key_timer); + if (event_initialized(&tty->key_timer)) + evtimer_del(&tty->key_timer); tty_stop_tty(tty); if (tty->flags & TTY_OPENED) { -- cgit From 928f40615c7a000b87a8fc843b97955a7cfc4a9a Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 17 Mar 2012 18:51:50 +0000 Subject: Tweak last fix to actually hit the right end of pane. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 4ea999ba..96932647 100644 --- a/tty.c +++ b/tty.c @@ -1001,7 +1001,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) * The pane doesn't fill the entire line, the linefeed * will already have happened, so just move the cursor. */ - if (ctx->ocy != wp->yoff + wp->sy) + if (ctx->ocy != wp->yoff + wp->sy - 1) tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1); else tty_cursor_pane(tty, ctx, 0, ctx->ocy); -- cgit From 0b34fefe6e007ca2eb68382d0b4042d7a1ab1dd4 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 17 Mar 2012 19:18:37 +0000 Subject: Use the region lower not the pane size to work out where the bottom line is. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 96932647..1f83ca74 100644 --- a/tty.c +++ b/tty.c @@ -1001,7 +1001,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) * The pane doesn't fill the entire line, the linefeed * will already have happened, so just move the cursor. */ - if (ctx->ocy != wp->yoff + wp->sy - 1) + if (ctx->ocy != wp->yoff + wp->screen->rlower) tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1); else tty_cursor_pane(tty, ctx, 0, ctx->ocy); -- cgit From 164e85cca75d5f7a6f36c286f597e03d08c90c2a Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 17 Mar 2012 19:29:46 +0000 Subject: Do not clear to end of line if the line is full, fixes missing last character in rightmost pane. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 1f83ca74..288d4bd1 100644 --- a/tty.c +++ b/tty.c @@ -604,7 +604,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) tty_reset(tty); tty_cursor(tty, ox + sx, oy + py); - if (ox + screen_size_x(s) >= tty->sx && + if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); else { -- cgit From 889fe42e1153ada95d73e5f9983d1a9d671837a1 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 17 Mar 2012 21:27:51 +0000 Subject: Break out termios initialization into a separate function, from George Nachman. --- tty.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 288d4bd1..a36bf787 100644 --- a/tty.c +++ b/tty.c @@ -175,18 +175,19 @@ tty_error_callback( } void -tty_start_tty(struct tty *tty) +tty_init_termios(int fd, struct termios *orig_tio, struct bufferevent *bufev) { struct termios tio; - if (tty->fd == -1 || tcgetattr(tty->fd, &tty->tio) != 0) + if (fd == -1 || tcgetattr(fd, orig_tio) != 0) return; - setblocking(tty->fd, 0); + setblocking(fd, 0); - bufferevent_enable(tty->event, EV_READ|EV_WRITE); + if (bufev != NULL) + bufferevent_enable(bufev, EV_READ|EV_WRITE); - memcpy(&tio, &tty->tio, sizeof tio); + 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); @@ -194,8 +195,14 @@ tty_start_tty(struct tty *tty) ECHOPRT|ECHOKE|ECHOCTL|ISIG); tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; - if (tcsetattr(tty->fd, TCSANOW, &tio) == 0) - tcflush(tty->fd, TCIOFLUSH); + if (tcsetattr(fd, TCSANOW, &tio) == 0) + tcflush(fd, TCIOFLUSH); +} + +void +tty_start_tty(struct tty *tty) +{ + tty_init_termios(tty->fd, &tty->tio, tty->event); tty_putcode(tty, TTYC_SMCUP); -- cgit From d8805af66bb876d762248d1695872eca3296f0e6 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 17 Mar 2012 22:56:04 +0000 Subject: On xterm 271 and later, put the terminal into SCL 5 and use DECCRA for scrolling the region in panes (if the large region check isn't hit). With help from Ailin Nemui. --- tty.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index a36bf787..c9191a6a 100644 --- a/tty.c +++ b/tty.c @@ -177,7 +177,7 @@ tty_error_callback( void tty_init_termios(int fd, struct termios *orig_tio, struct bufferevent *bufev) { - struct termios tio; + struct termios tio; if (fd == -1 || tcgetattr(fd, orig_tio) != 0) return; @@ -234,6 +234,27 @@ tty_start_tty(struct tty *tty) tty_force_cursor_colour(tty, ""); } +void +tty_set_version(struct tty *tty, u_int version) +{ + if (tty->xterm_version != 0) + return; + tty->xterm_version = version; + + if (tty->xterm_version > 270) { + tty_puts(tty, "\033[65;1\"p"); + + tty_putcode(tty, TTYC_RMACS); + memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell); + + tty->cx = UINT_MAX; + tty->cy = UINT_MAX; + + tty->rupper = UINT_MAX; + tty->rlower = UINT_MAX; + } +} + void tty_stop_tty(struct tty *tty) { @@ -276,6 +297,9 @@ tty_stop_tty(struct tty *tty) tty_raw(tty, "\033[?1000l"); tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); + + if (tty->xterm_version > 270) + tty_raw(tty, "\033[61;1\"p"); } void @@ -844,13 +868,28 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; + char tmp[64]; if (ctx->ocy != ctx->orlower) return; if (ctx->xoff != 0 || screen_size_x(s) < tty->sx || !tty_term_has(tty->term, TTYC_CSR)) { - tty_redraw_region(tty, ctx); + if (tty_large_region(tty, ctx)) + wp->flags |= PANE_REDRAW; + else if (tty->xterm_version > 270) { + snprintf(tmp, sizeof tmp, + "\033[%u;%u;%u;%u;1;%u;%u;1$v", + ctx->yoff + ctx->orupper + 2, + ctx->xoff + 1, + ctx->yoff + ctx->orlower + 1, + ctx->xoff + screen_size_x(s), + ctx->yoff + ctx->orupper + 1, + ctx->xoff + 1); + tty_puts(tty, tmp); + tty_cmd_clearline(tty, ctx); + } else + tty_redraw_region(tty, ctx); return; } -- cgit From f59971276ac02d8b42ef222509673ff356800f56 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 20 Mar 2012 11:01:00 +0000 Subject: Add a simple form of output rate limiting by counting the number of certain C0 sequences (linefeeds, backspaces, carriage returns) and if it exceeds a threshold (current default 50/millisecond), start to redraw the pane every 100 milliseconds instead of making each change as it comes. Two configuration options - c0-change-trigger and c0-change-interval. This makes tmux much more responsive under very fast output (for example yes(1) or accidentally cat'ing a large file) but may not be perfect on all terminals and connections - feedback very welcome, particularly where this change has a negative rather than positive effect (making it off by default is a possibility). After much experimentation based originally on a request Robin Lee Powell (which ended with a completely different solution), this idea from discussion with Ailin Nemui. --- tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index c9191a6a..03a99341 100644 --- a/tty.c +++ b/tty.c @@ -661,7 +661,7 @@ tty_write( if (wp->window->flags & WINDOW_REDRAW || wp->flags & PANE_REDRAW) return; - if (!window_pane_visible(wp)) + if (!window_pane_visible(wp) || wp->flags & PANE_DROP) return; for (i = 0; i < ARRAY_LENGTH(&clients); i++) { -- cgit From 3e6454f2d6a87cf173617b8232fca77934bc6a6c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 5 May 2012 18:17:59 +0000 Subject: Pull CRA out into a separate function and add ERA, from Ailin Nemui. --- tty.c | 53 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 11 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 03a99341..6b22c851 100644 --- a/tty.c +++ b/tty.c @@ -44,6 +44,10 @@ void tty_colours_fg(struct tty *, const struct grid_cell *); void tty_colours_bg(struct tty *, const struct grid_cell *); int tty_large_region(struct tty *, const struct tty_ctx *); +void tty_cra_pane(struct tty *, + const struct tty_ctx *, u_int, u_int, u_int, u_int, u_int, u_int); +void tty_era_pane(struct tty *, + const struct tty_ctx *, u_int, u_int, u_int, u_int); void tty_redraw_region(struct tty *, const struct tty_ctx *); void tty_emulate_repeat( struct tty *, enum tty_code_code, enum tty_code_code, u_int); @@ -52,6 +56,8 @@ void tty_cell(struct tty *, #define tty_use_acs(tty) \ (tty_term_has(tty->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) +#define tty_use_rect(tty) \ + (tty->xterm_version > 270) void tty_init(struct tty *tty, int fd, char *term) @@ -689,6 +695,38 @@ tty_write( } } +void +tty_cra_pane(struct tty *tty, const struct tty_ctx *ctx, + u_int t, u_int l, u_int b, u_int r, u_int tt, u_int tl) +{ + char tmp[64]; + + snprintf(tmp, sizeof tmp, + "\033[%u;%u;%u;%u;1;%u;%u;1$v", + ctx->yoff + t + 1, + ctx->xoff + l + 1, + ctx->yoff + b + 1, + ctx->xoff + r + 1, + ctx->yoff + tt + 1, + ctx->xoff + tl + 1); + tty_puts(tty, tmp); +} + +void +tty_era_pane(struct tty *tty, const struct tty_ctx *ctx, + u_int t, u_int l, u_int b, u_int r) +{ + char tmp[64]; + + snprintf(tmp, sizeof tmp, + "\033[%u;%u;%u;%u$z", + ctx->yoff + t + 1, + ctx->xoff + l + 1, + ctx->yoff + b + 1, + ctx->xoff + r + 1); + tty_puts(tty, tmp); +} + void tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { @@ -868,7 +906,6 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - char tmp[64]; if (ctx->ocy != ctx->orlower) return; @@ -877,16 +914,10 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) !tty_term_has(tty->term, TTYC_CSR)) { if (tty_large_region(tty, ctx)) wp->flags |= PANE_REDRAW; - else if (tty->xterm_version > 270) { - snprintf(tmp, sizeof tmp, - "\033[%u;%u;%u;%u;1;%u;%u;1$v", - ctx->yoff + ctx->orupper + 2, - ctx->xoff + 1, - ctx->yoff + ctx->orlower + 1, - ctx->xoff + screen_size_x(s), - ctx->yoff + ctx->orupper + 1, - ctx->xoff + 1); - tty_puts(tty, tmp); + else if (tty_use_rect(tty)) { + tty_cra_pane (tty, ctx, ctx->orupper + 1, 0, + ctx->orlower, screen_size_x(s) - 1, + ctx->orupper, 0); tty_cmd_clearline(tty, ctx); } else tty_redraw_region(tty, ctx); -- cgit From 132403b6bec15eaf02e4e9742f1f67a9ce271737 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 5 May 2012 18:31:09 +0000 Subject: Missing ()s in macros. --- tty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 6b22c851..1c6f7d5b 100644 --- a/tty.c +++ b/tty.c @@ -55,9 +55,9 @@ void tty_cell(struct tty *, const struct grid_cell *, const struct grid_utf8 *); #define tty_use_acs(tty) \ - (tty_term_has(tty->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) + (tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) #define tty_use_rect(tty) \ - (tty->xterm_version > 270) + ((tty)->xterm_version > 270) void tty_init(struct tty *tty, int fd, char *term) -- cgit From 96a34a0c0a6e42dc3cccc386f0d4809dc1facc68 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 5 May 2012 18:45:55 +0000 Subject: Tidy up by adding a macro for the pane being the full screen width, from Ailin Nemui. --- tty.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 1c6f7d5b..de153382 100644 --- a/tty.c +++ b/tty.c @@ -59,6 +59,9 @@ void tty_cell(struct tty *, #define tty_use_rect(tty) \ ((tty)->xterm_version > 270) +#define tty_pane_full_width(tty, ctx) \ + ((ctx)->xoff == 0 && screen_size_x((ctx)->wp->screen) >= (tty)->sx) + void tty_init(struct tty *tty, int fd, char *term) { @@ -781,10 +784,7 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; - - if (ctx->xoff != 0 || screen_size_x(s) < tty->sx || + if (!tty_pane_full_width(tty, ctx) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_IL1)) { tty_redraw_region(tty, ctx); @@ -802,10 +802,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; - - if (ctx->xoff != 0 || screen_size_x(s) < tty->sx || + if (!tty_pane_full_width(tty, ctx) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_DL1)) { tty_redraw_region(tty, ctx); @@ -831,8 +828,7 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) tty_cursor_pane(tty, ctx, 0, ctx->ocy); - if (ctx->xoff == 0 && screen_size_x(s) >= tty->sx && - tty_term_has(tty->term, TTYC_EL)) { + if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) { tty_putcode(tty, TTYC_EL); } else { for (i = 0; i < screen_size_x(s); i++) @@ -851,8 +847,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - if (ctx->xoff == 0 && screen_size_x(s) >= tty->sx && - tty_term_has(tty->term, TTYC_EL)) + if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); else { for (i = ctx->ocx; i < screen_size_x(s); i++) @@ -880,13 +875,10 @@ tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; - if (ctx->ocy != ctx->orupper) return; - if (ctx->xoff != 0 || screen_size_x(s) < tty->sx || + if (!tty_pane_full_width(tty, ctx) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_RI)) { tty_redraw_region(tty, ctx); @@ -910,7 +902,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy != ctx->orlower) return; - if (ctx->xoff != 0 || screen_size_x(s) < tty->sx || + if (!tty_pane_full_width(tty, ctx) || !tty_term_has(tty->term, TTYC_CSR)) { if (tty_large_region(tty, ctx)) wp->flags |= PANE_REDRAW; @@ -952,8 +944,7 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - if (ctx->xoff == 0 && screen_size_x(s) >= tty->sx && - tty_term_has(tty->term, TTYC_EL)) { + if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) { tty_putcode(tty, TTYC_EL); if (ctx->ocy != screen_size_y(s) - 1) { tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1); @@ -988,8 +979,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, 0, 0); - if (ctx->xoff == 0 && screen_size_x(s) >= tty->sx && - tty_term_has(tty->term, TTYC_EL)) { + if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) { for (i = 0; i < ctx->ocy; i++) { tty_putcode(tty, TTYC_EL); tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); @@ -1018,8 +1008,7 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, 0, 0); - if (ctx->xoff == 0 && screen_size_x(s) >= tty->sx && - tty_term_has(tty->term, TTYC_EL)) { + if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) { for (i = 0; i < screen_size_y(s); i++) { tty_putcode(tty, TTYC_EL); if (i != screen_size_y(s) - 1) { -- cgit From 243d12752c4ccb4f2cfabeff8c8cb843550078ae Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 22 May 2012 09:09:16 +0000 Subject: Move some common code to repeat spaces into a function. --- tty.c | 54 ++++++++++++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 32 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index de153382..63a54f0a 100644 --- a/tty.c +++ b/tty.c @@ -51,6 +51,7 @@ void tty_era_pane(struct tty *, void tty_redraw_region(struct tty *, const struct tty_ctx *); void tty_emulate_repeat( struct tty *, enum tty_code_code, enum tty_code_code, u_int); +void tty_repeat_space(struct tty *, u_int); void tty_cell(struct tty *, const struct grid_cell *, const struct grid_utf8 *); @@ -546,6 +547,13 @@ tty_emulate_repeat( } } +void +tty_repeat_space(struct tty *tty, u_int n) +{ + while (n-- > 0) + tty_putc(tty, ' '); +} + /* * Is the region large enough to be worth redrawing once later rather than * probably several times now? Currently yes if it is more than 50% of the @@ -647,10 +655,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); - else { - for (i = sx; i < screen_size_x(s); i++) - tty_putc(tty, ' '); - } + else + tty_repeat_space(tty, screen_size_x(s) - sx); tty_update_mode(tty, tty->mode, s); } @@ -735,7 +741,6 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - u_int i; if (ctx->xoff != 0 || screen_size_x(s) < tty->sx) { tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); @@ -752,8 +757,7 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) else if (tty_term_has(tty->term, TTYC_SMIR) && tty_term_has(tty->term, TTYC_RMIR)) { tty_putcode(tty, TTYC_SMIR); - for (i = 0; i < ctx->num; i++) - tty_putc(tty, ' '); + tty_repeat_space(tty, ctx->num); tty_putcode(tty, TTYC_RMIR); } else tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); @@ -822,18 +826,15 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - u_int i; tty_reset(tty); tty_cursor_pane(tty, ctx, 0, ctx->ocy); - if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) { + if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); - } else { - for (i = 0; i < screen_size_x(s); i++) - tty_putc(tty, ' '); - } + else + tty_repeat_space(tty, screen_size_x(s)); } void @@ -841,7 +842,6 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - u_int i; tty_reset(tty); @@ -849,17 +849,13 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); - else { - for (i = ctx->ocx; i < screen_size_x(s); i++) - tty_putc(tty, ' '); - } + else + tty_repeat_space(tty, screen_size_x(s) - ctx->ocx); } void tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) { - u_int i; - tty_reset(tty); if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) { @@ -867,8 +863,7 @@ tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) tty_putcode(tty, TTYC_EL1); } else { tty_cursor_pane(tty, ctx, 0, ctx->ocy); - for (i = 0; i < ctx->ocx + 1; i++) - tty_putc(tty, ' '); + tty_repeat_space(tty, ctx->ocx + 1); } } @@ -957,12 +952,10 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) } } } else { - for (i = ctx->ocx; i < screen_size_x(s); i++) - tty_putc(tty, ' '); + tty_repeat_space(tty, screen_size_x(s) - ctx->ocx); for (j = ctx->ocy + 1; j < screen_size_y(s); j++) { tty_cursor_pane(tty, ctx, 0, j); - for (i = 0; i < screen_size_x(s); i++) - tty_putc(tty, ' '); + tty_repeat_space(tty, screen_size_x(s)); } } } @@ -988,12 +981,10 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) } else { for (j = 0; j < ctx->ocy; j++) { tty_cursor_pane(tty, ctx, 0, j); - for (i = 0; i < screen_size_x(s); i++) - tty_putc(tty, ' '); + tty_repeat_space(tty, screen_size_x(s)); } } - for (i = 0; i <= ctx->ocx; i++) - tty_putc(tty, ' '); + tty_repeat_space(tty, ctx->ocx + 1); } void @@ -1019,8 +1010,7 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) } else { for (j = 0; j < screen_size_y(s); j++) { tty_cursor_pane(tty, ctx, 0, j); - for (i = 0; i < screen_size_x(s); i++) - tty_putc(tty, ' '); + tty_repeat_space(tty, screen_size_x(s)); } } } -- cgit From 2f93affb988ecdae1cfd3fb73801ce5b943a6525 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 22 May 2012 09:36:12 +0000 Subject: If there are any terminals with insert mode but not ich1, they can go through the slow path. Tidies code slightly. --- tty.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 63a54f0a..91ef75bd 100644 --- a/tty.c +++ b/tty.c @@ -754,12 +754,7 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) if (tty_term_has(tty->term, TTYC_ICH) || tty_term_has(tty->term, TTYC_ICH1)) tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num); - else if (tty_term_has(tty->term, TTYC_SMIR) && - tty_term_has(tty->term, TTYC_RMIR)) { - tty_putcode(tty, TTYC_SMIR); - tty_repeat_space(tty, ctx->num); - tty_putcode(tty, TTYC_RMIR); - } else + else tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); } -- cgit From 82b053a81135c0873f9aa8824386e63abd48bbc4 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 22 May 2012 09:37:54 +0000 Subject: Use tty_pane_full_width macro in some more places. --- tty.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 91ef75bd..5eb37ade 100644 --- a/tty.c +++ b/tty.c @@ -740,9 +740,8 @@ void tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; - if (ctx->xoff != 0 || screen_size_x(s) < tty->sx) { + if (!tty_pane_full_width(tty, ctx)) { tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); return; } @@ -762,9 +761,8 @@ void tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; - if (ctx->xoff != 0 || screen_size_x(s) < tty->sx || + if (!tty_pane_full_width(tty, ctx) || (!tty_term_has(tty->term, TTYC_DCH) && !tty_term_has(tty->term, TTYC_DCH1))) { tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); -- cgit From 84c708f3558d440be1a9e92ee8e6ead5c499fb0f Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 22 May 2012 14:32:28 +0000 Subject: Store client in tty struct directly instead of using a callback function pointer. --- tty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 5eb37ade..6e895f5c 100644 --- a/tty.c +++ b/tty.c @@ -64,7 +64,7 @@ void tty_cell(struct tty *, ((ctx)->xoff == 0 && screen_size_x((ctx)->wp->screen) >= (tty)->sx) void -tty_init(struct tty *tty, int fd, char *term) +tty_init(struct tty *tty, struct client *c, int fd, char *term) { char *path; @@ -76,6 +76,7 @@ tty_init(struct tty *tty, int fd, char *term) else tty->termname = xstrdup(term); tty->fd = fd; + tty->client = c; if ((path = ttyname(fd)) == NULL) fatalx("ttyname failed"); -- cgit From a7917430d8bb41792e1a8c1d6c6066763925a500 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 20 Jun 2012 12:55:55 +0000 Subject: Remove a couple of unused variables from redbrain at gcc dot gnu dot org. --- tty.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 6e895f5c..ca65bdb3 100644 --- a/tty.c +++ b/tty.c @@ -668,7 +668,6 @@ tty_write( struct window_pane *wp = ctx->wp; struct client *c; struct session *s; - struct options *oo; u_int i; /* wp can be NULL if updating the screen but not the terminal. */ @@ -693,7 +692,6 @@ tty_write( continue; if (c->tty.flags & TTY_FREEZE) continue; - oo = &s->options; ctx->xoff = wp->xoff; ctx->yoff = wp->yoff; -- cgit From df912e3540968a2a0b266e523ecc08bb2dc0ca20 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 10 Jul 2012 11:53:01 +0000 Subject: xfree is not particularly helpful, remove it. From Thomas Adam. --- tty.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index ca65bdb3..d40e95d7 100644 --- a/tty.c +++ b/tty.c @@ -345,11 +345,11 @@ tty_free(struct tty *tty) { tty_close(tty); - xfree(tty->ccolour); + free(tty->ccolour); if (tty->path != NULL) - xfree(tty->path); + free(tty->path); if (tty->termname != NULL) - xfree(tty->termname); + free(tty->termname); } void @@ -468,7 +468,7 @@ tty_force_cursor_colour(struct tty *tty, const char *ccolour) tty_putcode(tty, TTYC_CR); else tty_putcode_ptr1(tty, TTYC_CC, ccolour); - xfree(tty->ccolour); + free(tty->ccolour); tty->ccolour = xstrdup(ccolour); } @@ -1099,7 +1099,7 @@ tty_cmd_setselection(struct tty *tty, const struct tty_ctx *ctx) b64_ntop(ctx->ptr, ctx->num, buf, off); tty_putcode_ptr2(tty, TTYC_MS, "", buf); - xfree(buf); + free(buf); } void -- cgit From f61fc576d922b4eb3780933a7808d35bd3725917 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 14 Aug 2012 08:58:25 +0000 Subject: Tidy up tty_write, from Sean Estabrooks. --- tty.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index d40e95d7..68d23fc2 100644 --- a/tty.c +++ b/tty.c @@ -667,7 +667,6 @@ tty_write( { struct window_pane *wp = ctx->wp; struct client *c; - struct session *s; u_int i; /* wp can be NULL if updating the screen but not the terminal. */ @@ -681,25 +680,19 @@ tty_write( for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); - if (c == NULL || c->session == NULL) + if (c == NULL || c->session == NULL || c->tty.term == NULL) continue; - if (c->flags & CLIENT_SUSPENDED) + if (c->flags & (CLIENT_SUSPENDED|TTY_FREEZE)) + continue; + if (c->session->curw->window != wp->window) continue; - s = c->session; - - if (s->curw->window == wp->window) { - if (c->tty.term == NULL) - continue; - if (c->tty.flags & TTY_FREEZE) - continue; - ctx->xoff = wp->xoff; - ctx->yoff = wp->yoff; - if (status_at_line(c) == 0) - ctx->yoff++; + ctx->xoff = wp->xoff; + ctx->yoff = wp->yoff; + if (status_at_line(c) == 0) + ctx->yoff++; - cmdfn(&c->tty, ctx); - } + cmdfn(&c->tty, ctx); } } -- cgit From 6307d63715b7509b56384214d7a605e022c678bb Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 3 Sep 2012 15:47:40 +0000 Subject: Remove xterm CRA support - support is patchy and it will be done better using margins. --- tty.c | 59 +---------------------------------------------------------- 1 file changed, 1 insertion(+), 58 deletions(-) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 68d23fc2..01b3a93d 100644 --- a/tty.c +++ b/tty.c @@ -44,10 +44,6 @@ void tty_colours_fg(struct tty *, const struct grid_cell *); void tty_colours_bg(struct tty *, const struct grid_cell *); int tty_large_region(struct tty *, const struct tty_ctx *); -void tty_cra_pane(struct tty *, - const struct tty_ctx *, u_int, u_int, u_int, u_int, u_int, u_int); -void tty_era_pane(struct tty *, - const struct tty_ctx *, u_int, u_int, u_int, u_int); void tty_redraw_region(struct tty *, const struct tty_ctx *); void tty_emulate_repeat( struct tty *, enum tty_code_code, enum tty_code_code, u_int); @@ -57,8 +53,6 @@ void tty_cell(struct tty *, #define tty_use_acs(tty) \ (tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) -#define tty_use_rect(tty) \ - ((tty)->xterm_version > 270) #define tty_pane_full_width(tty, ctx) \ ((ctx)->xoff == 0 && screen_size_x((ctx)->wp->screen) >= (tty)->sx) @@ -251,19 +245,6 @@ tty_set_version(struct tty *tty, u_int version) if (tty->xterm_version != 0) return; tty->xterm_version = version; - - if (tty->xterm_version > 270) { - tty_puts(tty, "\033[65;1\"p"); - - tty_putcode(tty, TTYC_RMACS); - memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell); - - tty->cx = UINT_MAX; - tty->cy = UINT_MAX; - - tty->rupper = UINT_MAX; - tty->rlower = UINT_MAX; - } } void @@ -696,38 +677,6 @@ tty_write( } } -void -tty_cra_pane(struct tty *tty, const struct tty_ctx *ctx, - u_int t, u_int l, u_int b, u_int r, u_int tt, u_int tl) -{ - char tmp[64]; - - snprintf(tmp, sizeof tmp, - "\033[%u;%u;%u;%u;1;%u;%u;1$v", - ctx->yoff + t + 1, - ctx->xoff + l + 1, - ctx->yoff + b + 1, - ctx->xoff + r + 1, - ctx->yoff + tt + 1, - ctx->xoff + tl + 1); - tty_puts(tty, tmp); -} - -void -tty_era_pane(struct tty *tty, const struct tty_ctx *ctx, - u_int t, u_int l, u_int b, u_int r) -{ - char tmp[64]; - - snprintf(tmp, sizeof tmp, - "\033[%u;%u;%u;%u$z", - ctx->yoff + t + 1, - ctx->xoff + l + 1, - ctx->yoff + b + 1, - ctx->xoff + r + 1); - tty_puts(tty, tmp); -} - void tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { @@ -877,7 +826,6 @@ void tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - struct screen *s = wp->screen; if (ctx->ocy != ctx->orlower) return; @@ -886,12 +834,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) !tty_term_has(tty->term, TTYC_CSR)) { if (tty_large_region(tty, ctx)) wp->flags |= PANE_REDRAW; - else if (tty_use_rect(tty)) { - tty_cra_pane (tty, ctx, ctx->orupper + 1, 0, - ctx->orlower, screen_size_x(s) - 1, - ctx->orupper, 0); - tty_cmd_clearline(tty, ctx); - } else + else tty_redraw_region(tty, ctx); return; } -- cgit From b433886840ec4dba4b8b921b741b6a448a226d30 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 5 Sep 2012 09:59:41 +0000 Subject: We can't tell what the terminal has done with a DCS string, so reset the cursor and attributes afterwards. --- tty.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tty.c') diff --git a/tty.c b/tty.c index 01b3a93d..0270af93 100644 --- a/tty.c +++ b/tty.c @@ -1046,6 +1046,12 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx) for (i = 0; i < ctx->num; i++) tty_putc(tty, str[i]); + + tty->cx = tty->cy = UINT_MAX; + tty->rupper = tty->rlower = UINT_MAX; + + tty_reset(tty); + tty_cursor(tty, 0, 0); } void -- cgit