mirror of
https://github.com/tmux/tmux.git
synced 2025-03-23 05:38:56 +00:00
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.
This commit is contained in:
parent
3aaf5b9b1e
commit
219442cff7
22
input-keys.c
22
input-keys.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
8
input.c
8
input.c
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
6
tmux.1
@ -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
3
tmux.c
@ -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
12
tmux.h
@ -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 *);
|
||||
|
62
tty-keys.c
62
tty-keys.c
@ -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
6
tty.c
@ -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
15
utf8.c
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user