Merge branch 'obsd-master'

Conflicts:
	utf8.c
This commit is contained in:
Thomas Adam 2016-03-02 18:10:51 +00:00
commit e304673c65
18 changed files with 150 additions and 481 deletions

View File

@ -35,7 +35,7 @@ const struct cmd_entry cmd_break_pane_entry = {
.alias = "breakp", .alias = "breakp",
.args = { "dPF:s:t:", 0, 0 }, .args = { "dPF:s:t:", 0, 0 },
.usage = "[-dP] [-F format] " CMD_SRCDST_PANE_USAGE, .usage = "[-dP] [-F format] [-s src-pane] [-t dst-window]",
.sflag = CMD_PANE, .sflag = CMD_PANE,
.tflag = CMD_WINDOW_INDEX, .tflag = CMD_WINDOW_INDEX,

View File

@ -73,14 +73,13 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
struct format_tree *ft; struct format_tree *ft;
const char *cwd; const char *cwd;
cwd = wp->cwd;
if (cmdq->client != NULL && cmdq->client->session == NULL) if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd; cwd = cmdq->client->cwd;
else if (s != NULL) else if (s != NULL)
cwd = s->cwd; cwd = s->cwd;
else else
cwd = NULL; cwd = NULL;
ft = format_create(cmdq, 0); ft = format_create(cmdq, 0);
format_defaults(ft, NULL, s, wl, wp); format_defaults(ft, NULL, s, wl, wp);
shellcmd = format_expand(ft, args->argv[0]); shellcmd = format_expand(ft, args->argv[0]);

View File

@ -68,7 +68,6 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
w = wl->window;
if (args_has(args, 'Z')) { if (args_has(args, 'Z')) {
if (w->flags & WINDOW_ZOOMED) if (w->flags & WINDOW_ZOOMED)
window_unzoom(w); window_unzoom(w);

View File

@ -45,28 +45,23 @@ const struct cmd_entry cmd_swap_pane_entry = {
enum cmd_retval enum cmd_retval
cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq) cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{ {
struct winlink *src_wl, *dst_wl;
struct window *src_w, *dst_w; struct window *src_w, *dst_w;
struct window_pane *tmp_wp, *src_wp, *dst_wp; struct window_pane *tmp_wp, *src_wp, *dst_wp;
struct layout_cell *src_lc, *dst_lc; struct layout_cell *src_lc, *dst_lc;
u_int sx, sy, xoff, yoff; u_int sx, sy, xoff, yoff;
dst_wl = cmdq->state.tflag.wl; dst_w = cmdq->state.tflag.wl->window;
dst_w = dst_wl->window;
dst_wp = cmdq->state.tflag.wp; dst_wp = cmdq->state.tflag.wp;
src_wl = cmdq->state.sflag.wl; src_w = cmdq->state.sflag.wl->window;
src_w = src_wl->window;
src_wp = cmdq->state.sflag.wp; src_wp = cmdq->state.sflag.wp;
server_unzoom_window(dst_w); server_unzoom_window(dst_w);
if (args_has(self->args, 'D')) { if (args_has(self->args, 'D')) {
src_wl = dst_wl;
src_w = dst_w; src_w = dst_w;
src_wp = TAILQ_NEXT(dst_wp, entry); src_wp = TAILQ_NEXT(dst_wp, entry);
if (src_wp == NULL) if (src_wp == NULL)
src_wp = TAILQ_FIRST(&dst_w->panes); src_wp = TAILQ_FIRST(&dst_w->panes);
} else if (args_has(self->args, 'U')) { } else if (args_has(self->args, 'U')) {
src_wl = dst_wl;
src_w = dst_w; src_w = dst_w;
src_wp = TAILQ_PREV(dst_wp, window_panes, entry); src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
if (src_wp == NULL) if (src_wp == NULL)

1
cmd.c
View File

@ -481,7 +481,6 @@ cmd_prepare_state_flag(char c, const char *target, enum cmd_entry_flag flag,
CMD_FIND_SESSION, CMD_FIND_QUIET); CMD_FIND_SESSION, CMD_FIND_QUIET);
if (error == 0) if (error == 0)
break; break;
flag = CMD_WINDOW_INDEX;
/* FALLTHROUGH */ /* FALLTHROUGH */
case CMD_WINDOW: case CMD_WINDOW:
case CMD_WINDOW_CANFAIL: case CMD_WINDOW_CANFAIL:

View File

@ -134,6 +134,19 @@ const struct input_key_ent input_keys[] = {
{ KEYC_KP_PERIOD, ".", 0 }, { KEYC_KP_PERIOD, ".", 0 },
}; };
/* Split a character into two UTF-8 bytes. */
static size_t
input_split2(u_int c, u_char *dst)
{
if (c > 0x7f) {
dst[0] = (c >> 6) | 0xc0;
dst[1] = (c & 0x3f) | 0x80;
return (2);
}
dst[0] = c;
return (1);
}
/* Translate a key code into an output key sequence. */ /* Translate a key code into an output key sequence. */
void void
input_key(struct window_pane *wp, key_code key, struct mouse_event *m) input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
@ -249,10 +262,12 @@ input_key_mouse(struct window_pane *wp, struct mouse_event *m)
len = xsnprintf(buf, sizeof buf, "\033[<%u;%u;%u%c", len = xsnprintf(buf, sizeof buf, "\033[<%u;%u;%u%c",
m->sgr_b, x + 1, y + 1, m->sgr_type); m->sgr_b, x + 1, y + 1, m->sgr_type);
} else if (wp->screen->mode & MODE_MOUSE_UTF8) { } else if (wp->screen->mode & MODE_MOUSE_UTF8) {
if (m->b > 0x7ff - 32 || x > 0x7ff - 33 || y > 0x7ff - 33)
return;
len = xsnprintf(buf, sizeof buf, "\033[M"); len = xsnprintf(buf, sizeof buf, "\033[M");
len += utf8_split2(m->b + 32, &buf[len]); len += input_split2(m->b + 32, &buf[len]);
len += utf8_split2(x + 33, &buf[len]); len += input_split2(x + 33, &buf[len]);
len += utf8_split2(y + 33, &buf[len]); len += input_split2(y + 33, &buf[len]);
} else { } else {
if (m->b > 223) if (m->b > 223)
return; return;

10
input.c
View File

@ -1960,8 +1960,14 @@ input_utf8_close(struct input_ctx *ictx)
{ {
struct utf8_data *ud = &ictx->utf8data; struct utf8_data *ud = &ictx->utf8data;
if (utf8_append(ud, ictx->ch) != UTF8_DONE) if (utf8_append(ud, ictx->ch) != UTF8_DONE) {
fatalx("UTF-8 close invalid %#x", ictx->ch); /*
* An error here could be invalid UTF-8 or it could be a
* nonprintable character for which we can't get the
* width. Drop it.
*/
return (0);
}
log_debug("%s %hhu '%*s' (width %hhu)", __func__, ud->size, log_debug("%s %hhu '%*s' (width %hhu)", __func__, ud->size,
(int)ud->size, ud->data, ud->width); (int)ud->size, ud->data, ud->width);

View File

@ -68,12 +68,12 @@ void
key_bindings_unref_table(struct key_table *table) key_bindings_unref_table(struct key_table *table)
{ {
struct key_binding *bd; struct key_binding *bd;
struct key_binding *bd1;
if (--table->references != 0) if (--table->references != 0)
return; return;
while (!RB_EMPTY(&table->key_bindings)) { RB_FOREACH_SAFE(bd, key_bindings, &table->key_bindings, bd1) {
bd = RB_ROOT(&table->key_bindings);
RB_REMOVE(key_bindings, &table->key_bindings, bd); RB_REMOVE(key_bindings, &table->key_bindings, bd);
cmd_list_free(bd->cmdlist); cmd_list_free(bd->cmdlist);
free(bd); free(bd);

View File

@ -149,6 +149,7 @@ key_string_lookup_string(const char *string)
struct utf8_data ud; struct utf8_data ud;
u_int i; u_int i;
enum utf8_state more; enum utf8_state more;
wchar_t wc;
/* Is this no key? */ /* Is this no key? */
if (strcasecmp(string, "None") == 0) if (strcasecmp(string, "None") == 0)
@ -185,8 +186,9 @@ key_string_lookup_string(const char *string)
more = utf8_append(&ud, (u_char)string[i]); more = utf8_append(&ud, (u_char)string[i]);
if (more != UTF8_DONE) if (more != UTF8_DONE)
return (KEYC_UNKNOWN); return (KEYC_UNKNOWN);
key = utf8_combine(&ud); if (utf8_combine(&ud, &wc) != UTF8_DONE)
return (key | modifiers); return (KEYC_UNKNOWN);
return (wc | modifiers);
} }
/* Otherwise look the key up in the table. */ /* Otherwise look the key up in the table. */

View File

@ -347,6 +347,7 @@ const struct mode_key_entry mode_key_vi_copy[] = {
{ KEYC_WHEELUP_PANE, 0, MODEKEYCOPY_SCROLLUP }, { KEYC_WHEELUP_PANE, 0, MODEKEYCOPY_SCROLLUP },
{ KEYC_WHEELDOWN_PANE, 0, MODEKEYCOPY_SCROLLDOWN }, { KEYC_WHEELDOWN_PANE, 0, MODEKEYCOPY_SCROLLDOWN },
{ KEYC_MOUSEDRAG1_PANE, 0, MODEKEYCOPY_STARTSELECTION }, { KEYC_MOUSEDRAG1_PANE, 0, MODEKEYCOPY_STARTSELECTION },
{ KEYC_MOUSEUP1_PANE, 0, MODEKEYCOPY_COPYSELECTION },
{ 0, -1, 0 } { 0, -1, 0 }
}; };
@ -495,6 +496,7 @@ const struct mode_key_entry mode_key_emacs_copy[] = {
{ KEYC_WHEELUP_PANE, 0, MODEKEYCOPY_SCROLLUP }, { KEYC_WHEELUP_PANE, 0, MODEKEYCOPY_SCROLLUP },
{ KEYC_WHEELDOWN_PANE, 0, MODEKEYCOPY_SCROLLDOWN }, { KEYC_WHEELDOWN_PANE, 0, MODEKEYCOPY_SCROLLDOWN },
{ KEYC_MOUSEDRAG1_PANE, 0, MODEKEYCOPY_STARTSELECTION }, { KEYC_MOUSEDRAG1_PANE, 0, MODEKEYCOPY_STARTSELECTION },
{ KEYC_MOUSEUP1_PANE, 0, MODEKEYCOPY_COPYSELECTION },
{ 0, -1, 0 } { 0, -1, 0 }
}; };

View File

@ -382,8 +382,42 @@ server_client_check_mouse(struct client *c)
c->tty.mouse_drag_update = NULL; c->tty.mouse_drag_update = NULL;
c->tty.mouse_drag_release = NULL; c->tty.mouse_drag_release = NULL;
/*
* End a mouse drag by passing a MouseUp key corresponding to
* the button that started the drag.
*/
switch (c->tty.mouse_drag_flag) {
case 1:
if (where == PANE)
key = KEYC_MOUSEUP1_PANE;
if (where == STATUS)
key = KEYC_MOUSEUP1_STATUS;
if (where == BORDER)
key = KEYC_MOUSEUP1_BORDER;
break;
case 2:
if (where == PANE)
key = KEYC_MOUSEUP2_PANE;
if (where == STATUS)
key = KEYC_MOUSEUP2_STATUS;
if (where == BORDER)
key = KEYC_MOUSEUP2_BORDER;
break;
case 3:
if (where == PANE)
key = KEYC_MOUSEUP3_PANE;
if (where == STATUS)
key = KEYC_MOUSEUP3_STATUS;
if (where == BORDER)
key = KEYC_MOUSEUP3_BORDER;
break;
default:
key = KEYC_MOUSE;
break;
}
c->tty.mouse_drag_flag = 0; c->tty.mouse_drag_flag = 0;
return (KEYC_MOUSE); /* not a key, but still may want to pass */
return (key);
} }
/* Convert to a key binding. */ /* Convert to a key binding. */
@ -423,7 +457,11 @@ server_client_check_mouse(struct client *c)
} }
} }
c->tty.mouse_drag_flag = 1; /*
* Begin a drag by setting the flag to a non-zero value that
* corresponds to the mouse button in use.
*/
c->tty.mouse_drag_flag = MOUSE_BUTTONS(b) + 1;
break; break;
case WHEEL: case WHEEL:
if (MOUSE_BUTTONS(b) == MOUSE_WHEEL_UP) { if (MOUSE_BUTTONS(b) == MOUSE_WHEEL_UP) {

13
tmux.1
View File

@ -721,7 +721,7 @@ will set the session working directory (used for new windows) to
.Pp .Pp
If If
.Fl E .Fl E
is used, is used, the
.Ic update-environment .Ic update-environment
option will not be applied. option will not be applied.
.It Xo Ic detach-client .It Xo Ic detach-client
@ -857,13 +857,12 @@ with
.Ar target-session . .Ar target-session .
This means they share the same set of windows - all windows from This means they share the same set of windows - all windows from
.Ar target-session .Ar target-session
are linked to the new session and any subsequent new windows or windows being are linked to the new session, any new windows are linked to both sessions and
closed are applied to both sessions. any windows closed removed from both sessions.
The current and previous window and any session options remain independent and The current and previous window and any session options remain independent and
either session may be killed without affecting the other. either session may be killed without affecting the other.
Giving
.Fl n .Fl n
or and
.Ar shell-command .Ar shell-command
are invalid if are invalid if
.Fl t .Fl t
@ -879,7 +878,7 @@ but a different format may be specified with
.Pp .Pp
If If
.Fl E .Fl E
is used, is used, the
.Ic update-environment .Ic update-environment
option will not be applied. option will not be applied.
.It Xo Ic refresh-client .It Xo Ic refresh-client
@ -1254,7 +1253,7 @@ Commands related to windows and panes are as follows:
.Op Fl dP .Op Fl dP
.Op Fl F Ar format .Op Fl F Ar format
.Op Fl s Ar src-pane .Op Fl s Ar src-pane
.Op Fl t Ar dst-pane .Op Fl t Ar dst-window
.Xc .Xc
.D1 (alias: Ic breakp ) .D1 (alias: Ic breakp )
Break Break

2
tmux.c
View File

@ -190,7 +190,9 @@ main(int argc, char **argv)
const char *s; const char *s;
int opt, flags, keys; int opt, flags, keys;
setlocale(LC_CTYPE, "en_US.UTF-8");
setlocale(LC_TIME, ""); setlocale(LC_TIME, "");
tzset(); tzset();
if (**argv == '-') if (**argv == '-')

7
tmux.h
View File

@ -29,6 +29,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <termios.h> #include <termios.h>
#include <wchar.h>
#ifdef HAVE_UTEMPTER #ifdef HAVE_UTEMPTER
#include <utempter.h> #include <utempter.h>
@ -2313,14 +2314,12 @@ void session_group_synchronize1(struct session *, struct session *);
void session_renumber_windows(struct session *); void session_renumber_windows(struct session *);
/* utf8.c */ /* utf8.c */
u_int utf8_width(u_int);
void utf8_set(struct utf8_data *, u_char); void utf8_set(struct utf8_data *, u_char);
void utf8_copy(struct utf8_data *, const struct utf8_data *); void utf8_copy(struct utf8_data *, const struct utf8_data *);
enum utf8_state utf8_open(struct utf8_data *, u_char); enum utf8_state utf8_open(struct utf8_data *, u_char);
enum utf8_state utf8_append(struct utf8_data *, u_char); enum utf8_state utf8_append(struct utf8_data *, u_char);
u_int utf8_combine(const struct utf8_data *); enum utf8_state utf8_combine(const struct utf8_data *, wchar_t *);
enum utf8_state utf8_split(u_int, struct utf8_data *); enum utf8_state utf8_split(wchar_t, struct utf8_data *);
u_int utf8_split2(u_int, u_char *);
int utf8_strvis(char *, const char *, size_t, int); int utf8_strvis(char *, const char *, size_t, int);
char *utf8_sanitize(const char *); char *utf8_sanitize(const char *);
struct utf8_data *utf8_fromcstr(const char *); struct utf8_data *utf8_fromcstr(const char *);

View File

@ -477,6 +477,7 @@ tty_keys_next(struct tty *tty)
struct utf8_data ud; struct utf8_data ud;
enum utf8_state more; enum utf8_state more;
u_int i; u_int i;
wchar_t wc;
/* Get key buffer. */ /* Get key buffer. */
buf = EVBUFFER_DATA(tty->event->input); buf = EVBUFFER_DATA(tty->event->input);
@ -552,7 +553,11 @@ first_key:
more = utf8_append(&ud, (u_char)buf[i]); more = utf8_append(&ud, (u_char)buf[i]);
if (more != UTF8_DONE) if (more != UTF8_DONE)
goto discard_key; goto discard_key;
key = utf8_combine(&ud);
if (utf8_combine(&ud, &wc) != UTF8_DONE)
goto discard_key;
key = wc;
log_debug("UTF-8 key %.*s %#llx", (int)size, buf, key); log_debug("UTF-8 key %.*s %#llx", (int)size, buf, key);
goto complete_key; goto complete_key;
} }

482
utf8.c
View File

@ -23,329 +23,7 @@
#include "tmux.h" #include "tmux.h"
struct utf8_width_entry { static int utf8_width(wchar_t);
u_int first;
u_int last;
int width;
struct utf8_width_entry *left;
struct utf8_width_entry *right;
};
/* Sorted, then repeatedly split in the middle to balance the tree. */
static struct utf8_width_entry utf8_width_table[] = {
{ 0x00b41, 0x00b44, 0, NULL, NULL },
{ 0x008e4, 0x00902, 0, NULL, NULL },
{ 0x006d6, 0x006dd, 0, NULL, NULL },
{ 0x005c4, 0x005c5, 0, NULL, NULL },
{ 0x00591, 0x005bd, 0, NULL, NULL },
{ 0x00300, 0x0036f, 0, NULL, NULL },
{ 0x00483, 0x00489, 0, NULL, NULL },
{ 0x005bf, 0x005bf, 0, NULL, NULL },
{ 0x005c1, 0x005c2, 0, NULL, NULL },
{ 0x00610, 0x0061a, 0, NULL, NULL },
{ 0x00600, 0x00605, 0, NULL, NULL },
{ 0x005c7, 0x005c7, 0, NULL, NULL },
{ 0x0064b, 0x0065f, 0, NULL, NULL },
{ 0x0061c, 0x0061c, 0, NULL, NULL },
{ 0x00670, 0x00670, 0, NULL, NULL },
{ 0x007a6, 0x007b0, 0, NULL, NULL },
{ 0x006ea, 0x006ed, 0, NULL, NULL },
{ 0x006df, 0x006e4, 0, NULL, NULL },
{ 0x006e7, 0x006e8, 0, NULL, NULL },
{ 0x00711, 0x00711, 0, NULL, NULL },
{ 0x0070f, 0x0070f, 0, NULL, NULL },
{ 0x00730, 0x0074a, 0, NULL, NULL },
{ 0x0081b, 0x00823, 0, NULL, NULL },
{ 0x007eb, 0x007f3, 0, NULL, NULL },
{ 0x00816, 0x00819, 0, NULL, NULL },
{ 0x00829, 0x0082d, 0, NULL, NULL },
{ 0x00825, 0x00827, 0, NULL, NULL },
{ 0x00859, 0x0085b, 0, NULL, NULL },
{ 0x00a41, 0x00a42, 0, NULL, NULL },
{ 0x00981, 0x00981, 0, NULL, NULL },
{ 0x00941, 0x00948, 0, NULL, NULL },
{ 0x0093a, 0x0093a, 0, NULL, NULL },
{ 0x0093c, 0x0093c, 0, NULL, NULL },
{ 0x00951, 0x00957, 0, NULL, NULL },
{ 0x0094d, 0x0094d, 0, NULL, NULL },
{ 0x00962, 0x00963, 0, NULL, NULL },
{ 0x009e2, 0x009e3, 0, NULL, NULL },
{ 0x009c1, 0x009c4, 0, NULL, NULL },
{ 0x009bc, 0x009bc, 0, NULL, NULL },
{ 0x009cd, 0x009cd, 0, NULL, NULL },
{ 0x00a01, 0x00a02, 0, NULL, NULL },
{ 0x00a3c, 0x00a3c, 0, NULL, NULL },
{ 0x00ac1, 0x00ac5, 0, NULL, NULL },
{ 0x00a70, 0x00a71, 0, NULL, NULL },
{ 0x00a4b, 0x00a4d, 0, NULL, NULL },
{ 0x00a47, 0x00a48, 0, NULL, NULL },
{ 0x00a51, 0x00a51, 0, NULL, NULL },
{ 0x00a81, 0x00a82, 0, NULL, NULL },
{ 0x00a75, 0x00a75, 0, NULL, NULL },
{ 0x00abc, 0x00abc, 0, NULL, NULL },
{ 0x00ae2, 0x00ae3, 0, NULL, NULL },
{ 0x00ac7, 0x00ac8, 0, NULL, NULL },
{ 0x00acd, 0x00acd, 0, NULL, NULL },
{ 0x00b3c, 0x00b3c, 0, NULL, NULL },
{ 0x00b01, 0x00b01, 0, NULL, NULL },
{ 0x00b3f, 0x00b3f, 0, NULL, NULL },
{ 0x03190, 0x031ba, 2, NULL, NULL },
{ 0x017c9, 0x017d3, 0, NULL, NULL },
{ 0x00ec8, 0x00ecd, 0, NULL, NULL },
{ 0x00cc6, 0x00cc6, 0, NULL, NULL },
{ 0x00c3e, 0x00c40, 0, NULL, NULL },
{ 0x00b82, 0x00b82, 0, NULL, NULL },
{ 0x00b56, 0x00b56, 0, NULL, NULL },
{ 0x00b4d, 0x00b4d, 0, NULL, NULL },
{ 0x00b62, 0x00b63, 0, NULL, NULL },
{ 0x00bcd, 0x00bcd, 0, NULL, NULL },
{ 0x00bc0, 0x00bc0, 0, NULL, NULL },
{ 0x00c00, 0x00c00, 0, NULL, NULL },
{ 0x00c62, 0x00c63, 0, NULL, NULL },
{ 0x00c4a, 0x00c4d, 0, NULL, NULL },
{ 0x00c46, 0x00c48, 0, NULL, NULL },
{ 0x00c55, 0x00c56, 0, NULL, NULL },
{ 0x00cbc, 0x00cbc, 0, NULL, NULL },
{ 0x00c81, 0x00c81, 0, NULL, NULL },
{ 0x00cbf, 0x00cbf, 0, NULL, NULL },
{ 0x00dd2, 0x00dd4, 0, NULL, NULL },
{ 0x00d41, 0x00d44, 0, NULL, NULL },
{ 0x00ce2, 0x00ce3, 0, NULL, NULL },
{ 0x00ccc, 0x00ccd, 0, NULL, NULL },
{ 0x00d01, 0x00d01, 0, NULL, NULL },
{ 0x00d62, 0x00d63, 0, NULL, NULL },
{ 0x00d4d, 0x00d4d, 0, NULL, NULL },
{ 0x00dca, 0x00dca, 0, NULL, NULL },
{ 0x00e47, 0x00e4e, 0, NULL, NULL },
{ 0x00e31, 0x00e31, 0, NULL, NULL },
{ 0x00dd6, 0x00dd6, 0, NULL, NULL },
{ 0x00e34, 0x00e3a, 0, NULL, NULL },
{ 0x00eb4, 0x00eb9, 0, NULL, NULL },
{ 0x00eb1, 0x00eb1, 0, NULL, NULL },
{ 0x00ebb, 0x00ebc, 0, NULL, NULL },
{ 0x0105e, 0x01060, 0, NULL, NULL },
{ 0x00f8d, 0x00f97, 0, NULL, NULL },
{ 0x00f39, 0x00f39, 0, NULL, NULL },
{ 0x00f35, 0x00f35, 0, NULL, NULL },
{ 0x00f18, 0x00f19, 0, NULL, NULL },
{ 0x00f37, 0x00f37, 0, NULL, NULL },
{ 0x00f80, 0x00f84, 0, NULL, NULL },
{ 0x00f71, 0x00f7e, 0, NULL, NULL },
{ 0x00f86, 0x00f87, 0, NULL, NULL },
{ 0x01032, 0x01037, 0, NULL, NULL },
{ 0x00fc6, 0x00fc6, 0, NULL, NULL },
{ 0x00f99, 0x00fbc, 0, NULL, NULL },
{ 0x0102d, 0x01030, 0, NULL, NULL },
{ 0x0103d, 0x0103e, 0, NULL, NULL },
{ 0x01039, 0x0103a, 0, NULL, NULL },
{ 0x01058, 0x01059, 0, NULL, NULL },
{ 0x0135d, 0x0135f, 0, NULL, NULL },
{ 0x01085, 0x01086, 0, NULL, NULL },
{ 0x01071, 0x01074, 0, NULL, NULL },
{ 0x01082, 0x01082, 0, NULL, NULL },
{ 0x0109d, 0x0109d, 0, NULL, NULL },
{ 0x0108d, 0x0108d, 0, NULL, NULL },
{ 0x01100, 0x011ff, 2, NULL, NULL },
{ 0x01772, 0x01773, 0, NULL, NULL },
{ 0x01732, 0x01734, 0, NULL, NULL },
{ 0x01712, 0x01714, 0, NULL, NULL },
{ 0x01752, 0x01753, 0, NULL, NULL },
{ 0x017b7, 0x017bd, 0, NULL, NULL },
{ 0x017b4, 0x017b5, 0, NULL, NULL },
{ 0x017c6, 0x017c6, 0, NULL, NULL },
{ 0x01c2c, 0x01c33, 0, NULL, NULL },
{ 0x01a7f, 0x01a7f, 0, NULL, NULL },
{ 0x01a17, 0x01a18, 0, NULL, NULL },
{ 0x01920, 0x01922, 0, NULL, NULL },
{ 0x0180b, 0x0180e, 0, NULL, NULL },
{ 0x017dd, 0x017dd, 0, NULL, NULL },
{ 0x018a9, 0x018a9, 0, NULL, NULL },
{ 0x01932, 0x01932, 0, NULL, NULL },
{ 0x01927, 0x01928, 0, NULL, NULL },
{ 0x01939, 0x0193b, 0, NULL, NULL },
{ 0x01a60, 0x01a60, 0, NULL, NULL },
{ 0x01a56, 0x01a56, 0, NULL, NULL },
{ 0x01a1b, 0x01a1b, 0, NULL, NULL },
{ 0x01a58, 0x01a5e, 0, NULL, NULL },
{ 0x01a65, 0x01a6c, 0, NULL, NULL },
{ 0x01a62, 0x01a62, 0, NULL, NULL },
{ 0x01a73, 0x01a7c, 0, NULL, NULL },
{ 0x01b80, 0x01b81, 0, NULL, NULL },
{ 0x01b36, 0x01b3a, 0, NULL, NULL },
{ 0x01b00, 0x01b03, 0, NULL, NULL },
{ 0x01ab0, 0x01abe, 0, NULL, NULL },
{ 0x01b34, 0x01b34, 0, NULL, NULL },
{ 0x01b42, 0x01b42, 0, NULL, NULL },
{ 0x01b3c, 0x01b3c, 0, NULL, NULL },
{ 0x01b6b, 0x01b73, 0, NULL, NULL },
{ 0x01be6, 0x01be6, 0, NULL, NULL },
{ 0x01ba8, 0x01ba9, 0, NULL, NULL },
{ 0x01ba2, 0x01ba5, 0, NULL, NULL },
{ 0x01bab, 0x01bad, 0, NULL, NULL },
{ 0x01bed, 0x01bed, 0, NULL, NULL },
{ 0x01be8, 0x01be9, 0, NULL, NULL },
{ 0x01bef, 0x01bf1, 0, NULL, NULL },
{ 0x02329, 0x0232a, 2, NULL, NULL },
{ 0x01dc0, 0x01df5, 0, NULL, NULL },
{ 0x01ce2, 0x01ce8, 0, NULL, NULL },
{ 0x01cd0, 0x01cd2, 0, NULL, NULL },
{ 0x01c36, 0x01c37, 0, NULL, NULL },
{ 0x01cd4, 0x01ce0, 0, NULL, NULL },
{ 0x01cf4, 0x01cf4, 0, NULL, NULL },
{ 0x01ced, 0x01ced, 0, NULL, NULL },
{ 0x01cf8, 0x01cf9, 0, NULL, NULL },
{ 0x02060, 0x02064, 0, NULL, NULL },
{ 0x0200b, 0x0200f, 0, NULL, NULL },
{ 0x01dfc, 0x01dff, 0, NULL, NULL },
{ 0x0202a, 0x0202e, 0, NULL, NULL },
{ 0x02066, 0x0206f, 0, NULL, NULL },
{ 0x020d0, 0x020f0, 0, NULL, NULL },
{ 0x03001, 0x03029, 2, NULL, NULL },
{ 0x02e80, 0x02e99, 2, NULL, NULL },
{ 0x02d7f, 0x02d7f, 0, NULL, NULL },
{ 0x02cef, 0x02cf1, 0, NULL, NULL },
{ 0x02de0, 0x02dff, 0, NULL, NULL },
{ 0x02f00, 0x02fd5, 2, NULL, NULL },
{ 0x02e9b, 0x02ef3, 2, NULL, NULL },
{ 0x02ff0, 0x02ffb, 2, NULL, NULL },
{ 0x03099, 0x0309a, 0, NULL, NULL },
{ 0x0302e, 0x0303e, 2, NULL, NULL },
{ 0x0302a, 0x0302d, 0, NULL, NULL },
{ 0x03041, 0x03096, 2, NULL, NULL },
{ 0x03105, 0x0312d, 2, NULL, NULL },
{ 0x0309b, 0x030ff, 2, NULL, NULL },
{ 0x03131, 0x0318e, 2, NULL, NULL },
{ 0x10a3f, 0x10a3f, 0, NULL, NULL },
{ 0x0aa4c, 0x0aa4c, 0, NULL, NULL },
{ 0x0a825, 0x0a826, 0, NULL, NULL },
{ 0x0a490, 0x0a4c6, 2, NULL, NULL },
{ 0x03250, 0x032fe, 2, NULL, NULL },
{ 0x031f0, 0x0321e, 2, NULL, NULL },
{ 0x031c0, 0x031e3, 2, NULL, NULL },
{ 0x03220, 0x03247, 2, NULL, NULL },
{ 0x04e00, 0x09fcc, 2, NULL, NULL },
{ 0x03300, 0x04db5, 2, NULL, NULL },
{ 0x0a000, 0x0a48c, 2, NULL, NULL },
{ 0x0a6f0, 0x0a6f1, 0, NULL, NULL },
{ 0x0a674, 0x0a67d, 0, NULL, NULL },
{ 0x0a66f, 0x0a672, 0, NULL, NULL },
{ 0x0a69f, 0x0a69f, 0, NULL, NULL },
{ 0x0a806, 0x0a806, 0, NULL, NULL },
{ 0x0a802, 0x0a802, 0, NULL, NULL },
{ 0x0a80b, 0x0a80b, 0, NULL, NULL },
{ 0x0a9b6, 0x0a9b9, 0, NULL, NULL },
{ 0x0a947, 0x0a951, 0, NULL, NULL },
{ 0x0a8e0, 0x0a8f1, 0, NULL, NULL },
{ 0x0a8c4, 0x0a8c4, 0, NULL, NULL },
{ 0x0a926, 0x0a92d, 0, NULL, NULL },
{ 0x0a980, 0x0a982, 0, NULL, NULL },
{ 0x0a960, 0x0a97c, 2, NULL, NULL },
{ 0x0a9b3, 0x0a9b3, 0, NULL, NULL },
{ 0x0aa29, 0x0aa2e, 0, NULL, NULL },
{ 0x0a9bc, 0x0a9bc, 0, NULL, NULL },
{ 0x0a9e5, 0x0a9e5, 0, NULL, NULL },
{ 0x0aa35, 0x0aa36, 0, NULL, NULL },
{ 0x0aa31, 0x0aa32, 0, NULL, NULL },
{ 0x0aa43, 0x0aa43, 0, NULL, NULL },
{ 0x0fb1e, 0x0fb1e, 0, NULL, NULL },
{ 0x0aaf6, 0x0aaf6, 0, NULL, NULL },
{ 0x0aab7, 0x0aab8, 0, NULL, NULL },
{ 0x0aab0, 0x0aab0, 0, NULL, NULL },
{ 0x0aa7c, 0x0aa7c, 0, NULL, NULL },
{ 0x0aab2, 0x0aab4, 0, NULL, NULL },
{ 0x0aac1, 0x0aac1, 0, NULL, NULL },
{ 0x0aabe, 0x0aabf, 0, NULL, NULL },
{ 0x0aaec, 0x0aaed, 0, NULL, NULL },
{ 0x0ac00, 0x0d7a3, 2, NULL, NULL },
{ 0x0abe8, 0x0abe8, 0, NULL, NULL },
{ 0x0abe5, 0x0abe5, 0, NULL, NULL },
{ 0x0abed, 0x0abed, 0, NULL, NULL },
{ 0x0f900, 0x0fa6d, 2, NULL, NULL },
{ 0x0d800, 0x0dfff, 0, NULL, NULL },
{ 0x0fa70, 0x0fad9, 2, NULL, NULL },
{ 0x0fff9, 0x0fffb, 0, NULL, NULL },
{ 0x0fe30, 0x0fe52, 2, NULL, NULL },
{ 0x0fe10, 0x0fe19, 2, NULL, NULL },
{ 0x0fe00, 0x0fe0f, 0, NULL, NULL },
{ 0x0fe20, 0x0fe2d, 0, NULL, NULL },
{ 0x0fe68, 0x0fe6b, 2, NULL, NULL },
{ 0x0fe54, 0x0fe66, 2, NULL, NULL },
{ 0x0feff, 0x0feff, 0, NULL, NULL },
{ 0x10a01, 0x10a03, 0, NULL, NULL },
{ 0x102e0, 0x102e0, 0, NULL, NULL },
{ 0x101fd, 0x101fd, 0, NULL, NULL },
{ 0x10376, 0x1037a, 0, NULL, NULL },
{ 0x10a0c, 0x10a0f, 0, NULL, NULL },
{ 0x10a05, 0x10a06, 0, NULL, NULL },
{ 0x10a38, 0x10a3a, 0, NULL, NULL },
{ 0x11633, 0x1163a, 0, NULL, NULL },
{ 0x11236, 0x11237, 0, NULL, NULL },
{ 0x11100, 0x11102, 0, NULL, NULL },
{ 0x1107f, 0x11081, 0, NULL, NULL },
{ 0x11001, 0x11001, 0, NULL, NULL },
{ 0x10ae5, 0x10ae6, 0, NULL, NULL },
{ 0x11038, 0x11046, 0, NULL, NULL },
{ 0x110b9, 0x110ba, 0, NULL, NULL },
{ 0x110b3, 0x110b6, 0, NULL, NULL },
{ 0x110bd, 0x110bd, 0, NULL, NULL },
{ 0x11180, 0x11181, 0, NULL, NULL },
{ 0x1112d, 0x11134, 0, NULL, NULL },
{ 0x11127, 0x1112b, 0, NULL, NULL },
{ 0x11173, 0x11173, 0, NULL, NULL },
{ 0x1122f, 0x11231, 0, NULL, NULL },
{ 0x111b6, 0x111be, 0, NULL, NULL },
{ 0x11234, 0x11234, 0, NULL, NULL },
{ 0x11370, 0x11374, 0, NULL, NULL },
{ 0x11301, 0x11301, 0, NULL, NULL },
{ 0x112df, 0x112df, 0, NULL, NULL },
{ 0x112e3, 0x112ea, 0, NULL, NULL },
{ 0x11340, 0x11340, 0, NULL, NULL },
{ 0x1133c, 0x1133c, 0, NULL, NULL },
{ 0x11366, 0x1136c, 0, NULL, NULL },
{ 0x114c2, 0x114c3, 0, NULL, NULL },
{ 0x114ba, 0x114ba, 0, NULL, NULL },
{ 0x114b3, 0x114b8, 0, NULL, NULL },
{ 0x114bf, 0x114c0, 0, NULL, NULL },
{ 0x115bc, 0x115bd, 0, NULL, NULL },
{ 0x115b2, 0x115b5, 0, NULL, NULL },
{ 0x115bf, 0x115c0, 0, NULL, NULL },
{ 0x1d1aa, 0x1d1ad, 0, NULL, NULL },
{ 0x16b30, 0x16b36, 0, NULL, NULL },
{ 0x116ad, 0x116ad, 0, NULL, NULL },
{ 0x1163f, 0x11640, 0, NULL, NULL },
{ 0x1163d, 0x1163d, 0, NULL, NULL },
{ 0x116ab, 0x116ab, 0, NULL, NULL },
{ 0x116b7, 0x116b7, 0, NULL, NULL },
{ 0x116b0, 0x116b5, 0, NULL, NULL },
{ 0x16af0, 0x16af4, 0, NULL, NULL },
{ 0x1bca0, 0x1bca3, 0, NULL, NULL },
{ 0x1b000, 0x1b001, 2, NULL, NULL },
{ 0x16f8f, 0x16f92, 0, NULL, NULL },
{ 0x1bc9d, 0x1bc9e, 0, NULL, NULL },
{ 0x1d173, 0x1d182, 0, NULL, NULL },
{ 0x1d167, 0x1d169, 0, NULL, NULL },
{ 0x1d185, 0x1d18b, 0, NULL, NULL },
{ 0x2a700, 0x2b734, 2, NULL, NULL },
{ 0x1f210, 0x1f23a, 2, NULL, NULL },
{ 0x1e8d0, 0x1e8d6, 0, NULL, NULL },
{ 0x1d242, 0x1d244, 0, NULL, NULL },
{ 0x1f200, 0x1f202, 2, NULL, NULL },
{ 0x1f250, 0x1f251, 2, NULL, NULL },
{ 0x1f240, 0x1f248, 2, NULL, NULL },
{ 0x20000, 0x2a6d6, 2, NULL, NULL },
{ 0xe0020, 0xe007f, 0, NULL, NULL },
{ 0x2f800, 0x2fa1d, 2, NULL, NULL },
{ 0x2b740, 0x2b81d, 2, NULL, NULL },
{ 0xe0001, 0xe0001, 0, NULL, NULL },
{ 0xf0000, 0xffffd, 0, NULL, NULL },
{ 0xe0100, 0xe01ef, 0, NULL, NULL },
{ 0x100000, 0x10fffd, 0, NULL, NULL },
};
static struct utf8_width_entry *utf8_width_root = NULL;
static void utf8_build(void);
/* Set a single character. */ /* Set a single character. */
void void
@ -402,6 +80,9 @@ utf8_open(struct utf8_data *ud, u_char ch)
enum utf8_state enum utf8_state
utf8_append(struct utf8_data *ud, u_char ch) utf8_append(struct utf8_data *ud, u_char ch)
{ {
wchar_t wc;
int width;
if (ud->have >= ud->size) if (ud->have >= ud->size)
fatalx("UTF-8 character overflow"); fatalx("UTF-8 character overflow");
if (ud->size > sizeof ud->data) if (ud->size > sizeof ud->data)
@ -416,122 +97,59 @@ utf8_append(struct utf8_data *ud, u_char ch)
if (ud->width == 0xff) if (ud->width == 0xff)
return (UTF8_ERROR); return (UTF8_ERROR);
ud->width = utf8_width(utf8_combine(ud));
return (UTF8_DONE);
}
/* Build UTF-8 width tree. */ if (utf8_combine(ud, &wc) != UTF8_DONE)
static void
utf8_build(void)
{
struct utf8_width_entry **ptr, *item, *node;
u_int i;
for (i = 0; i < nitems(utf8_width_table); i++) {
item = &utf8_width_table[i];
ptr = &utf8_width_root;
while (*ptr != NULL) {
node = *ptr;
if (item->last < node->first)
ptr = &node->left;
else if (item->first > node->last)
ptr = &node->right;
}
*ptr = item;
}
}
/* Lookup width of UTF-8 data in tree. */
u_int
utf8_width(u_int uc)
{
struct utf8_width_entry *item;
if (utf8_width_root == NULL)
utf8_build();
item = utf8_width_root;
while (item != NULL) {
if (uc < item->first)
item = item->left;
else if (uc > item->last)
item = item->right;
else
return (item->width);
}
return (1);
}
/* Combine UTF-8 into 32-bit Unicode. */
u_int
utf8_combine(const struct utf8_data *ud)
{
u_int uc;
uc = 0xfffd;
switch (ud->size) {
case 1:
uc = ud->data[0];
break;
case 2:
uc = ud->data[1] & 0x3f;
uc |= (ud->data[0] & 0x1f) << 6;
break;
case 3:
uc = ud->data[2] & 0x3f;
uc |= (ud->data[1] & 0x3f) << 6;
uc |= (ud->data[0] & 0xf) << 12;
break;
case 4:
uc = ud->data[3] & 0x3f;
uc |= (ud->data[2] & 0x3f) << 6;
uc |= (ud->data[1] & 0x3f) << 12;
uc |= (ud->data[0] & 0x7) << 18;
break;
}
return (uc);
}
/* Split 32-bit Unicode into UTF-8. */
enum utf8_state
utf8_split(u_int uc, struct utf8_data *ud)
{
if (uc < 0x7f) {
ud->size = 1;
ud->data[0] = uc;
} else if (uc < 0x7ff) {
ud->size = 2;
ud->data[0] = 0xc0 | ((uc >> 6) & 0x1f);
ud->data[1] = 0x80 | (uc & 0x3f);
} else if (uc < 0xffff) {
ud->size = 3;
ud->data[0] = 0xe0 | ((uc >> 12) & 0xf);
ud->data[1] = 0x80 | ((uc >> 6) & 0x3f);
ud->data[2] = 0x80 | (uc & 0x3f);
} else if (uc < 0x1fffff) {
ud->size = 4;
ud->data[0] = 0xf0 | ((uc >> 18) & 0x7);
ud->data[1] = 0x80 | ((uc >> 12) & 0x3f);
ud->data[2] = 0x80 | ((uc >> 6) & 0x3f);
ud->data[3] = 0x80 | (uc & 0x3f);
} else
return (UTF8_ERROR); return (UTF8_ERROR);
ud->width = utf8_width(uc); if ((width = utf8_width(wc)) < 0)
return (UTF8_ERROR);
ud->width = width;
return (UTF8_DONE); return (UTF8_DONE);
} }
/* Split a two-byte UTF-8 character. */ /* Get width of Unicode character. */
u_int static int
utf8_split2(u_int uc, u_char *ptr) utf8_width(wchar_t wc)
{ {
if (uc > 0x7f) { int width;
ptr[0] = (uc >> 6) | 0xc0;
ptr[1] = (uc & 0x3f) | 0x80; width = wcwidth(wc);
return (2); if (width < 0 || width > 0xff)
return (-1);
return (width);
}
/* Combine UTF-8 into Unicode. */
enum utf8_state
utf8_combine(const struct utf8_data *ud, wchar_t *wc)
{
switch (mbtowc(wc, ud->data, ud->size)) {
case -1:
mbtowc(NULL, NULL, MB_CUR_MAX);
return (UTF8_ERROR);
case 0:
return (UTF8_ERROR);
default:
return (UTF8_DONE);
} }
ptr[0] = uc; }
return (1);
/* Split Unicode into UTF-8. */
enum utf8_state
utf8_split(wchar_t wc, struct utf8_data *ud)
{
char s[MB_LEN_MAX];
int slen;
slen = wctomb(s, wc);
if (slen <= 0 || slen > (int)sizeof ud->data)
return (UTF8_ERROR);
memcpy(ud->data, s, slen);
ud->size = slen;
ud->width = utf8_width(wc);
return (UTF8_DONE);
} }
/* /*

View File

@ -2248,7 +2248,7 @@ window_copy_start_drag(struct client *c, struct mouse_event *m)
return; return;
c->tty.mouse_drag_update = window_copy_drag_update; c->tty.mouse_drag_update = window_copy_drag_update;
c->tty.mouse_drag_release = window_copy_drag_release; c->tty.mouse_drag_release = NULL; /* will fire MouseUp key */
window_copy_update_cursor(wp, x, y); window_copy_update_cursor(wp, x, y);
window_copy_start_selection(wp); window_copy_start_selection(wp);
@ -2275,16 +2275,3 @@ window_copy_drag_update(__unused struct client *c, struct mouse_event *m)
if (window_copy_update_selection(wp, 1)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_selection(wp, old_cy); window_copy_redraw_selection(wp, old_cy);
} }
void
window_copy_drag_release(__unused struct client *c, struct mouse_event *m)
{
struct window_pane *wp;
wp = cmd_mouse_pane(m, NULL, NULL);
if (wp == NULL || wp->mode != &window_copy_mode)
return;
window_copy_copy_selection(wp, NULL);
window_pane_reset_mode(wp);
}

View File

@ -1100,6 +1100,8 @@ window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode)
if ((s = wp->mode->init(wp)) != NULL) if ((s = wp->mode->init(wp)) != NULL)
wp->screen = s; wp->screen = s;
wp->flags |= (PANE_REDRAW|PANE_CHANGED); wp->flags |= (PANE_REDRAW|PANE_CHANGED);
server_status_window(wp->window);
return (0); return (0);
} }
@ -1114,6 +1116,8 @@ window_pane_reset_mode(struct window_pane *wp)
wp->screen = &wp->base; wp->screen = &wp->base;
wp->flags |= (PANE_REDRAW|PANE_CHANGED); wp->flags |= (PANE_REDRAW|PANE_CHANGED);
server_status_window(wp->window);
} }
void void