Sync OpenBSD patchset 828:

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.
pull/1/head
Tiago Cunha 2011-01-07 14:34:45 +00:00
parent 3aaf5b9b1e
commit 219442cff7
11 changed files with 139 additions and 33 deletions

View File

@ -1,4 +1,4 @@
/* $Id: input-keys.c,v 1.47 2011-01-03 23:32:04 tcunha Exp $ */
/* $Id: input-keys.c,v 1.48 2011-01-07 14:34:45 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -201,11 +201,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);
}
}

View File

@ -1,4 +1,4 @@
/* $Id: input.c,v 1.112 2010-12-30 22:27:38 tcunha Exp $ */
/* $Id: input.c,v 1.113 2011-01-07 14:34:45 tcunha 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;

View File

@ -1,4 +1,4 @@
/* $Id: options-table.c,v 1.2 2011-01-03 23:55:30 tcunha Exp $ */
/* $Id: options-table.c,v 1.3 2011-01-07 14:34:45 tcunha Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicm@users.sourceforge.net>
@ -197,6 +197,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

View File

@ -1,4 +1,4 @@
/* $Id: screen-write.c,v 1.91 2010-12-30 22:27:38 tcunha Exp $ */
/* $Id: screen-write.c,v 1.92 2011-01-07 14:34:45 tcunha 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)

View File

@ -1,4 +1,4 @@
/* $Id: server-client.c,v 1.50 2011-01-03 23:27:54 tcunha Exp $ */
/* $Id: server-client.c,v 1.51 2011-01-07 14:34:45 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@ -450,6 +450,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);
}

6
tmux.1
View File

@ -1,4 +1,4 @@
.\" $Id: tmux.1,v 1.285 2011-01-03 23:33:12 tcunha Exp $
.\" $Id: tmux.1,v 1.286 2011-01-07 14:34:45 tcunha Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
.\"
@ -1810,6 +1810,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

3
tmux.c
View File

@ -1,4 +1,4 @@
/* $Id: tmux.c,v 1.232 2011-01-03 23:52:38 tcunha Exp $ */
/* $Id: tmux.c,v 1.233 2011-01-07 14:34:45 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -340,6 +340,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);
}

12
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.600 2011-01-03 23:52:38 tcunha Exp $ */
/* $Id: tmux.h,v 1.601 2011-01-07 14:34:45 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -546,6 +546,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)
@ -1071,15 +1072,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. */
@ -1813,6 +1814,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);
@ -2011,6 +2013,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 *);
/* osdep-*.c */
char *osdep_get_name(int, char *);

View File

@ -1,4 +1,4 @@
/* $Id: tty-keys.c,v 1.58 2011-01-03 23:29:49 tcunha Exp $ */
/* $Id: tty-keys.c,v 1.59 2011-01-07 14:34:45 tcunha 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);
log_debug(
"mouse input: %.6s (%hhu,%hhu/%hhu)", buf, buf[4], buf[5], buf[3]);
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)++;
}
m->b = buf[3];
m->x = buf[4];
m->y = buf[5];
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);
/* 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);
}

6
tty.c
View File

@ -1,4 +1,4 @@
/* $Id: tty.c,v 1.198 2010-12-30 22:27:38 tcunha Exp $ */
/* $Id: tty.c,v 1.199 2011-01-07 14:34:45 tcunha 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) {

15
utf8.c
View File

@ -1,4 +1,4 @@
/* $Id: utf8.c,v 1.11 2009-10-23 17:21:34 tcunha Exp $ */
/* $Id: utf8.c,v 1.12 2011-01-07 14:34:45 tcunha 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)