diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-10-12 13:01:19 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-10-12 13:01:19 +0000 |
commit | d9e0270e34344e93c34b8209ccd8720f0daa2d5f (patch) | |
tree | adc4a0d9fd789b9a0725871dd737c62288ca6f18 /usr.bin/tmux | |
parent | 0c392852c49dc137f5e6755d91c6df4af7995fbf (diff) |
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%).
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r-- | usr.bin/tmux/tmux.h | 13 | ||||
-rw-r--r-- | usr.bin/tmux/tty-term.c | 13 | ||||
-rw-r--r-- | usr.bin/tmux/tty.c | 123 |
3 files changed, 137 insertions, 12 deletions
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 4b85f80bc4f..c1fee7094d1 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.134 2009/10/12 09:29:58 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.135 2009/10/12 13:01:18 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -195,9 +195,15 @@ enum tty_code_code { TTYC_CNORM, /* cursor_normal, ve */ TTYC_COLORS, /* max_colors, Co */ TTYC_CSR, /* change_scroll_region, cs */ + TTYC_CUB, /* parm_left_cursor, LE */ + TTYC_CUB1, /* cursor_left, le */ TTYC_CUD, /* parm_down_cursor, DO */ TTYC_CUD1, /* cursor_down, do */ + TTYC_CUF, /* parm_right_cursor, RI */ + TTYC_CUF1, /* cursor_right, nd */ TTYC_CUP, /* cursor_address, cm */ + TTYC_CUU, /* parm_up_cursor, UP */ + TTYC_CUU1, /* cursor_up, up */ TTYC_DCH, /* parm_dch, DC */ TTYC_DCH1, /* delete_character, dc */ TTYC_DIM, /* enter_dim_mode, mh */ @@ -206,6 +212,8 @@ enum tty_code_code { TTYC_EL, /* clr_eol, ce */ TTYC_EL1, /* clr_bol, cb */ TTYC_ENACS, /* ena_acs, eA */ + TTYC_HOME, /* cursor_home, ho */ + TTYC_HPA, /* column_address, ch */ TTYC_ICH, /* parm_ich, IC */ TTYC_ICH1, /* insert_character, ic */ TTYC_IL, /* parm_insert_line, IL */ @@ -232,8 +240,8 @@ enum tty_code_code { TTYC_KF17, /* key_f17, F7 */ TTYC_KF18, /* key_f18, F8 */ TTYC_KF19, /* key_f19, F9 */ - TTYC_KF20, /* key_f20, F10 */ TTYC_KF2, /* key_f2, k2 */ + TTYC_KF20, /* key_f20, F10 */ TTYC_KF3, /* key_f3, k3 */ TTYC_KF4, /* key_f4, k4 */ TTYC_KF5, /* key_f5, k5 */ @@ -262,6 +270,7 @@ enum tty_code_code { TTYC_SMKX, /* keypad_xmit, ks */ TTYC_SMSO, /* enter_standout_mode, so */ TTYC_SMUL, /* enter_underline_mode, us */ + TTYC_VPA, /* row_address, cv */ TTYC_XENL, /* eat_newline_glitch, xn */ }; #define NTTYCODE (TTYC_XENL + 1) diff --git a/usr.bin/tmux/tty-term.c b/usr.bin/tmux/tty-term.c index 6b446bd2bdf..4c7c0c0c2b6 100644 --- a/usr.bin/tmux/tty-term.c +++ b/usr.bin/tmux/tty-term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-term.c,v 1.9 2009/08/23 11:40:05 nicm Exp $ */ +/* $OpenBSD: tty-term.c,v 1.10 2009/10/12 13:01:18 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -43,9 +43,15 @@ struct tty_term_code_entry tty_term_codes[NTTYCODE] = { { TTYC_CNORM, TTYCODE_STRING, "cnorm" }, { TTYC_COLORS, TTYCODE_NUMBER, "colors" }, { TTYC_CSR, TTYCODE_STRING, "csr" }, + { TTYC_CUB, TTYCODE_STRING, "cub" }, + { TTYC_CUB1, TTYCODE_STRING, "cub1" }, { TTYC_CUD, TTYCODE_STRING, "cud" }, { TTYC_CUD1, TTYCODE_STRING, "cud1" }, + { TTYC_CUF, TTYCODE_STRING, "cuf" }, + { TTYC_CUF1, TTYCODE_STRING, "cuf1" }, { TTYC_CUP, TTYCODE_STRING, "cup" }, + { TTYC_CUU, TTYCODE_STRING, "cuu" }, + { TTYC_CUU1, TTYCODE_STRING, "cuu1" }, { TTYC_DCH, TTYCODE_STRING, "dch" }, { TTYC_DCH1, TTYCODE_STRING, "dch1" }, { TTYC_DIM, TTYCODE_STRING, "dim" }, @@ -54,6 +60,8 @@ struct tty_term_code_entry tty_term_codes[NTTYCODE] = { { TTYC_EL, TTYCODE_STRING, "el" }, { TTYC_EL1, TTYCODE_STRING, "el1" }, { TTYC_ENACS, TTYCODE_STRING, "enacs" }, + { TTYC_HOME, TTYCODE_STRING, "home" }, + { TTYC_HPA, TTYCODE_STRING, "hpa" }, { TTYC_ICH, TTYCODE_STRING, "ich" }, { TTYC_ICH1, TTYCODE_STRING, "ich1" }, { TTYC_IL, TTYCODE_STRING, "il" }, @@ -80,8 +88,8 @@ struct tty_term_code_entry tty_term_codes[NTTYCODE] = { { TTYC_KF17, TTYCODE_STRING, "kf17" }, { TTYC_KF18, TTYCODE_STRING, "kf18" }, { TTYC_KF19, TTYCODE_STRING, "kf19" }, - { TTYC_KF20, TTYCODE_STRING, "kf20" }, { TTYC_KF2, TTYCODE_STRING, "kf2" }, + { TTYC_KF20, TTYCODE_STRING, "kf20" }, { TTYC_KF3, TTYCODE_STRING, "kf3" }, { TTYC_KF4, TTYCODE_STRING, "kf4" }, { TTYC_KF5, TTYCODE_STRING, "kf5" }, @@ -110,6 +118,7 @@ struct tty_term_code_entry tty_term_codes[NTTYCODE] = { { TTYC_SMKX, TTYCODE_STRING, "smkx" }, { TTYC_SMSO, TTYCODE_STRING, "smso" }, { TTYC_SMUL, TTYCODE_STRING, "smul" }, + { TTYC_VPA, TTYCODE_STRING, "vpa" }, { TTYC_XENL, TTYCODE_FLAG, "xenl" }, }; diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c index 663010d98bd..f9dd12bbd7c 100644 --- a/usr.bin/tmux/tty.c +++ b/usr.bin/tmux/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.41 2009/10/12 09:29:58 nicm Exp $ */ +/* $OpenBSD: tty.c,v 1.42 2009/10/12 13:01:18 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -21,6 +21,7 @@ #include <errno.h> #include <fcntl.h> +#include <stdlib.h> #include <string.h> #include <termios.h> #include <unistd.h> @@ -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 |