summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2009-10-12 13:01:19 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2009-10-12 13:01:19 +0000
commitd9e0270e34344e93c34b8209ccd8720f0daa2d5f (patch)
treeadc4a0d9fd789b9a0725871dd737c62288ca6f18
parent0c392852c49dc137f5e6755d91c6df4af7995fbf (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%).
-rw-r--r--usr.bin/tmux/tmux.h13
-rw-r--r--usr.bin/tmux/tty-term.c13
-rw-r--r--usr.bin/tmux/tty.c123
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