summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2009-10-12 13:01:18 +0000
committerNicholas Marriott <nicm@openbsd.org>2009-10-12 13:01:18 +0000
commit687c4a9fabbd1f6a2b7c8ae9050f087c13565f1b (patch)
tree7e78fe4305f7aaf152dd33ba0f9c0c6f5c85ffc7
parent33ae063cae422dc97633ac43a4f8ded43da5c143 (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--tmux.h11
-rw-r--r--tty-term.c11
-rw-r--r--tty.c121
3 files changed, 134 insertions, 9 deletions
diff --git a/tmux.h b/tmux.h
index 93e178e1..02f9bbd0 100644
--- a/tmux.h
+++ b/tmux.h
@@ -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/tty-term.c b/tty-term.c
index dd3e8e00..02dece6e 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -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/tty.c b/tty.c
index f7ef8c0d..4172e38c 100644
--- a/tty.c
+++ b/tty.c
@@ -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