diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2011-01-03 23:35:23 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2011-01-03 23:35:23 +0000 |
commit | 60a5e3c43953dd77bf29755321b3d66b06f98807 (patch) | |
tree | 91217062f2651726a0c23d83127428f95860d928 /usr.bin | |
parent | 6ddc11e3560b59e0be8c0f3faf575383ef0c85f6 (diff) |
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.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/tmux/input-keys.c | 22 | ||||
-rw-r--r-- | usr.bin/tmux/input.c | 8 | ||||
-rw-r--r-- | usr.bin/tmux/options-table.c | 7 | ||||
-rw-r--r-- | usr.bin/tmux/screen-write.c | 14 | ||||
-rw-r--r-- | usr.bin/tmux/server-client.c | 17 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 8 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.c | 3 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 12 | ||||
-rw-r--r-- | usr.bin/tmux/tty-keys.c | 62 | ||||
-rw-r--r-- | usr.bin/tmux/tty.c | 6 | ||||
-rw-r--r-- | usr.bin/tmux/utf8.c | 15 |
11 files changed, 140 insertions, 34 deletions
diff --git a/usr.bin/tmux/input-keys.c b/usr.bin/tmux/input-keys.c index eea2104e1f4..0c16317f51f 100644 --- a/usr.bin/tmux/input-keys.c +++ b/usr.bin/tmux/input-keys.c @@ -1,4 +1,4 @@ -/* $OpenBSD: input-keys.c,v 1.20 2011/01/01 03:43:20 nicm Exp $ */ +/* $OpenBSD: input-keys.c,v 1.21 2011/01/03 23:35:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -202,11 +202,23 @@ input_key(struct window_pane *wp, int key) void input_mouse(struct window_pane *wp, struct mouse_event *m) { - char out[8]; + char buf[10]; + size_t len; if (wp->screen->mode & ALL_MOUSE_MODES) { - xsnprintf(out, sizeof out, - "\033[M%c%c%c", m->b + 32, m->x + 33, m->y + 33); - bufferevent_write(wp->event, out, strlen(out)); + if (wp->screen->mode & MODE_MOUSE_UTF8) { + len = xsnprintf(buf, sizeof buf, "\033[M"); + len += utf8_split2(m->b + 32, &buf[len]); + len += utf8_split2(m->x + 33, &buf[len]); + len += utf8_split2(m->y + 33, &buf[len]); + } else { + if (m->b > 223 || m->x >= 222 || m->y > 222) + return; + len = xsnprintf(buf, sizeof buf, "\033[M"); + buf[len++] = m->b + 32; + buf[len++] = m->x + 33; + buf[len++] = m->y + 33; + } + bufferevent_write(wp->event, buf, len); } } diff --git a/usr.bin/tmux/input.c b/usr.bin/tmux/input.c index 874b1eec39c..d13a1f5443e 100644 --- a/usr.bin/tmux/input.c +++ b/usr.bin/tmux/input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: input.c,v 1.32 2010/12/29 21:49:06 nicm Exp $ */ +/* $OpenBSD: input.c,v 1.33 2011/01/03 23:35:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -1161,6 +1161,9 @@ input_csi_dispatch(struct input_ctx *ictx) case 1003: screen_write_mousemode_off(&ictx->ctx); break; + case 1005: + screen_write_utf8mousemode(&ictx->ctx, 0); + break; case 1049: window_pane_alternate_off(wp, &ictx->cell); break; @@ -1209,6 +1212,9 @@ input_csi_dispatch(struct input_ctx *ictx) case 1003: screen_write_mousemode_on(&ictx->ctx, MODE_MOUSE_ANY); break; + case 1005: + screen_write_utf8mousemode(&ictx->ctx, 1); + break; case 1049: window_pane_alternate_on(wp, &ictx->cell); break; diff --git a/usr.bin/tmux/options-table.c b/usr.bin/tmux/options-table.c index c756e706003..423f0073f22 100644 --- a/usr.bin/tmux/options-table.c +++ b/usr.bin/tmux/options-table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options-table.c,v 1.1 2011/01/01 16:51:21 nicm Exp $ */ +/* $OpenBSD: options-table.c,v 1.2 2011/01/03 23:35:21 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott <nicm@users.sourceforge.net> @@ -198,6 +198,11 @@ const struct options_table_entry session_options_table[] = { .default_num = 0 }, + { .name = "mouse-utf8", + .type = OPTIONS_TABLE_FLAG, + .default_num = 0 + }, + { .name = "pane-active-border-bg", .type = OPTIONS_TABLE_COLOUR, .default_num = 8 diff --git a/usr.bin/tmux/screen-write.c b/usr.bin/tmux/screen-write.c index 2dec0940d17..17efd6e4fb7 100644 --- a/usr.bin/tmux/screen-write.c +++ b/usr.bin/tmux/screen-write.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen-write.c,v 1.44 2010/12/29 21:49:06 nicm Exp $ */ +/* $OpenBSD: screen-write.c,v 1.45 2011/01/03 23:35:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -829,6 +829,18 @@ screen_write_insertmode(struct screen_write_ctx *ctx, int state) s->mode &= ~MODE_INSERT; } +/* Set UTF-8 mouse mode. */ +void +screen_write_utf8mousemode(struct screen_write_ctx *ctx, int state) +{ + struct screen *s = ctx->s; + + if (state) + s->mode |= MODE_MOUSE_UTF8; + else + s->mode &= ~MODE_MOUSE_UTF8; +} + /* Set mouse mode off. */ void screen_write_mousemode_off(struct screen_write_ctx *ctx) diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index 1652eb8c66e..3bbb12a231e 100644 --- a/usr.bin/tmux/server-client.c +++ b/usr.bin/tmux/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.47 2011/01/01 01:12:09 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.48 2011/01/03 23:35:21 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> @@ -451,6 +451,21 @@ server_client_reset_state(struct client *c) if (TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry) != NULL && options_get_number(oo, "mouse-select-pane")) mode |= MODE_MOUSE_STANDARD; + + /* + * Set UTF-8 mouse input if required. If the terminal is UTF-8, the + * user has set mouse-utf8 and any mouse mode is in effect, turn on + * UTF-8 mouse input. If the receiving terminal hasn't requested it + * (that is, it isn't in s->mode), then it'll be converted in + * input_mouse. + */ + if ((c->tty.flags & TTY_UTF8) && + (mode & ALL_MOUSE_MODES) && options_get_number(oo, "mouse-utf8")) + mode |= MODE_MOUSE_UTF8; + else + mode &= ~MODE_MOUSE_UTF8; + + /* Set the terminal mode and reset attributes. */ tty_update_mode(&c->tty, mode); tty_reset(&c->tty); } diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 75fee39d086..418a2527e93 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.202 2011/01/01 11:24:45 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.203 2011/01/03 23:35:21 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 1 2011 $ +.Dd $Mdocdate: January 3 2011 $ .Dt TMUX 1 .Os .Sh NAME @@ -1806,6 +1806,10 @@ flag to Repeat is enabled for the default keys bound to the .Ic resize-pane command. +.It Xo Ic mouse-utf8 +.Op Ic on | off +.Xc +If enabled, request mouse input as UTF-8 on UTF-8 terminals. .It Xo Ic set-remain-on-exit .Op Ic on | off .Xc diff --git a/usr.bin/tmux/tmux.c b/usr.bin/tmux/tmux.c index 93317be2a96..58ea6662bc3 100644 --- a/usr.bin/tmux/tmux.c +++ b/usr.bin/tmux/tmux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.c,v 1.99 2011/01/01 16:51:21 nicm Exp $ */ +/* $OpenBSD: tmux.c,v 1.100 2011/01/03 23:35:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -334,6 +334,7 @@ main(int argc, char **argv) /* Enable UTF-8 if the first client is on UTF-8 terminal. */ if (flags & IDENTIFY_UTF8) { options_set_number(&global_s_options, "status-utf8", 1); + options_set_number(&global_s_options, "mouse-utf8", 1); options_set_number(&global_w_options, "utf8", 1); } diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index e0a149a2c04..bf5ace3e4e2 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.262 2011/01/01 16:51:21 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.263 2011/01/03 23:35:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -550,6 +550,7 @@ struct mode_key_table { #define MODE_MOUSE_HIGHLIGHT 0x40 #define MODE_MOUSE_BUTTON 0x80 #define MODE_MOUSE_ANY 0x100 +#define MODE_MOUSE_UTF8 0x200 #define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD| \ MODE_MOUSE_HIGHLIGHT|MODE_MOUSE_BUTTON|MODE_MOUSE_ANY) @@ -1075,15 +1076,15 @@ struct tty_ctx { */ /* Mouse input. */ struct mouse_event { - u_char b; + u_int b; #define MOUSE_1 0 #define MOUSE_2 1 #define MOUSE_3 2 #define MOUSE_UP 3 #define MOUSE_BUTTON 3 #define MOUSE_45 64 - u_char x; - u_char y; + u_int x; + u_int y; }; /* Saved message entry. */ @@ -1817,6 +1818,7 @@ void screen_write_cursormode(struct screen_write_ctx *, int); void screen_write_reverseindex(struct screen_write_ctx *); void screen_write_scrollregion(struct screen_write_ctx *, u_int, u_int); void screen_write_insertmode(struct screen_write_ctx *, int); +void screen_write_utf8mousemode(struct screen_write_ctx *, int); void screen_write_mousemode_on(struct screen_write_ctx *, int); void screen_write_mousemode_off(struct screen_write_ctx *); void screen_write_linefeed(struct screen_write_ctx *, int); @@ -2017,6 +2019,8 @@ void session_group_synchronize1(struct session *, struct session *); void utf8_build(void); int utf8_open(struct utf8_data *, u_char); int utf8_append(struct utf8_data *, u_char); +u_int utf8_combine(const struct utf8_data *); +u_int utf8_split2(u_int, u_char *); /* procname.c */ char *get_proc_name(int, char *); diff --git a/usr.bin/tmux/tty-keys.c b/usr.bin/tmux/tty-keys.c index 495c28dec1e..390c1f69f7d 100644 --- a/usr.bin/tmux/tty-keys.c +++ b/usr.bin/tmux/tty-keys.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-keys.c,v 1.32 2011/01/01 02:16:25 nicm Exp $ */ +/* $OpenBSD: tty-keys.c,v 1.33 2011/01/03 23:35:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -38,7 +38,7 @@ struct tty_key *tty_keys_find1( struct tty_key *, const char *, size_t, size_t *); struct tty_key *tty_keys_find(struct tty *, const char *, size_t, size_t *); void tty_keys_callback(int, short, void *); -int tty_keys_mouse( +int tty_keys_mouse(struct tty *, const char *, size_t, size_t *, struct mouse_event *); struct tty_key_ent { @@ -462,7 +462,7 @@ tty_keys_next(struct tty *tty) } /* Is this a mouse key press? */ - switch (tty_keys_mouse(buf, len, &size, &mouse)) { + switch (tty_keys_mouse(tty, buf, len, &size, &mouse)) { case 0: /* yes */ evbuffer_drain(tty->event->input, size); key = KEYC_MOUSE; @@ -584,44 +584,74 @@ tty_keys_callback(unused int fd, unused short events, void *data) * (probably a mouse sequence but need more data). */ int -tty_keys_mouse(const char *buf, size_t len, size_t *size, struct mouse_event *m) +tty_keys_mouse(struct tty *tty, + const char *buf, size_t len, size_t *size, struct mouse_event *m) { + struct utf8_data utf8data; + u_int i, value; + /* - * Mouse sequences are \033[M followed by three characters indicating - * buttons, X and Y, all based at 32 with 1,1 top-left. + * Standard mouse sequences are \033[M followed by three characters + * indicating buttons, X and Y, all based at 32 with 1,1 top-left. + * + * UTF-8 mouse sequences are similar but the three are expressed as + * UTF-8 characters. */ *size = 0; + /* First three bytes are always \033[M. */ if (buf[0] != '\033') return (-1); if (len == 1) return (1); - if (buf[1] != '[') return (-1); if (len == 2) return (1); - if (buf[2] != 'M') return (-1); if (len == 3) return (1); - if (len < 6) - return (1); - *size = 6; + /* Read the three inputs. */ + *size = 3; + for (i = 0; i < 3; i++) { + if (len < *size) + return (1); + + if (tty->mode & MODE_MOUSE_UTF8) { + if (utf8_open(&utf8data, buf[*size])) { + if (utf8data.size != 2) + return (-1); + (*size)++; + if (len < *size) + return (1); + utf8_append(&utf8data, buf[*size]); + value = utf8_combine(&utf8data); + } else + value = buf[*size]; + (*size)++; + } else { + value = buf[*size]; + (*size)++; + } - log_debug( - "mouse input: %.6s (%hhu,%hhu/%hhu)", buf, buf[4], buf[5], buf[3]); + if (i == 0) + m->b = value; + else if (i == 1) + m->x = value; + else + m->y = value; + } + log_debug("mouse input: %.*s", (int) *size, buf); - m->b = buf[3]; - m->x = buf[4]; - m->y = buf[5]; + /* Check and return the mouse input. */ if (m->b < 32 || m->x < 33 || m->y < 33) return (-1); m->b -= 32; m->x -= 33; m->y -= 33; + log_debug("mouse position: x=%u y=%u b=%u", m->x, m->y, m->b); return (0); } diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c index af567bae45f..f3704f3b4d0 100644 --- a/usr.bin/tmux/tty.c +++ b/usr.bin/tmux/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.94 2010/12/29 21:49:06 nicm Exp $ */ +/* $OpenBSD: tty.c,v 1.95 2011/01/03 23:35:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -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) { diff --git a/usr.bin/tmux/utf8.c b/usr.bin/tmux/utf8.c index c4af1c36bc2..53c2d1c6782 100644 --- a/usr.bin/tmux/utf8.c +++ b/usr.bin/tmux/utf8.c @@ -1,4 +1,4 @@ -/* $OpenBSD: utf8.c,v 1.5 2009/10/20 22:17:33 nicm Exp $ */ +/* $OpenBSD: utf8.c,v 1.6 2011/01/03 23:35:22 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -318,6 +318,19 @@ utf8_combine(const struct utf8_data *utf8data) return (value); } +/* Split a two-byte UTF-8 character. */ +u_int +utf8_split2(u_int uc, u_char *ptr) +{ + if (uc > 0x7f) { + ptr[0] = (uc >> 6) | 0xc0; + ptr[1] = (uc & 0x3f) | 0x80; + return (2); + } + ptr[0] = uc; + return (1); +} + /* Lookup width of UTF-8 data in tree. */ u_int utf8_width(const struct utf8_data *utf8data) |