mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code
This commit is contained in:
		
							
								
								
									
										3
									
								
								FAQ
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								FAQ
									
									
									
									
									
								
							@@ -95,9 +95,6 @@ aware of are (bearing in mind I haven't used screen for a few years now):
 | 
			
		||||
- screen has builtin serial and telnet support; this is bloat and is unlikely
 | 
			
		||||
  to be added to tmux.
 | 
			
		||||
 | 
			
		||||
- screen has support for updating utmp. Nobody has really come up with a clean,
 | 
			
		||||
  portable way to do this without making tmux setuid or setgid yet.
 | 
			
		||||
 | 
			
		||||
- Environment handling is different.
 | 
			
		||||
 | 
			
		||||
- tmux tends to be more demanding on the terminal so tends to show up terminal
 | 
			
		||||
 
 | 
			
		||||
@@ -29,12 +29,12 @@
 | 
			
		||||
 | 
			
		||||
enum cmd_retval	 cmd_bind_key_exec(struct cmd *, struct cmd_q *);
 | 
			
		||||
 | 
			
		||||
enum cmd_retval	 cmd_bind_key_table(struct cmd *, struct cmd_q *, int);
 | 
			
		||||
enum cmd_retval	 cmd_bind_key_mode_table(struct cmd *, struct cmd_q *, int);
 | 
			
		||||
 | 
			
		||||
const struct cmd_entry cmd_bind_key_entry = {
 | 
			
		||||
	"bind-key", "bind",
 | 
			
		||||
	"cnrt:", 1, -1,
 | 
			
		||||
	"[-cnr] [-t key-table] key command [arguments]",
 | 
			
		||||
	"[-cnr] [-t mode-table] key command [arguments]",
 | 
			
		||||
	0,
 | 
			
		||||
	NULL,
 | 
			
		||||
	cmd_bind_key_exec
 | 
			
		||||
@@ -67,7 +67,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (args_has(args, 't'))
 | 
			
		||||
		return (cmd_bind_key_table(self, cmdq, key));
 | 
			
		||||
		return (cmd_bind_key_mode_table(self, cmdq, key));
 | 
			
		||||
 | 
			
		||||
	cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, NULL, 0,
 | 
			
		||||
	    &cause);
 | 
			
		||||
@@ -84,7 +84,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum cmd_retval
 | 
			
		||||
cmd_bind_key_table(struct cmd *self, struct cmd_q *cmdq, int key)
 | 
			
		||||
cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
 | 
			
		||||
{
 | 
			
		||||
	struct args			*args = self->args;
 | 
			
		||||
	const char			*tablename;
 | 
			
		||||
 
 | 
			
		||||
@@ -94,6 +94,7 @@ cmd_capture_pane_history(struct args *args, struct cmd_q *cmdq,
 | 
			
		||||
	int			 n, with_codes, escape_c0, join_lines;
 | 
			
		||||
	u_int			 i, sx, top, bottom, tmp;
 | 
			
		||||
	char			*cause, *buf, *line;
 | 
			
		||||
	const char		*Sflag, *Eflag;
 | 
			
		||||
	size_t			 linelen;
 | 
			
		||||
 | 
			
		||||
	sx = screen_size_x(&wp->base);
 | 
			
		||||
@@ -109,27 +110,37 @@ cmd_capture_pane_history(struct args *args, struct cmd_q *cmdq,
 | 
			
		||||
	} else
 | 
			
		||||
		gd = wp->base.grid;
 | 
			
		||||
 | 
			
		||||
	n = args_strtonum(args, 'S', INT_MIN, SHRT_MAX, &cause);
 | 
			
		||||
	if (cause != NULL) {
 | 
			
		||||
		top = gd->hsize;
 | 
			
		||||
		free(cause);
 | 
			
		||||
	} else if (n < 0 && (u_int) -n > gd->hsize)
 | 
			
		||||
	Sflag = args_get(args, 'S');
 | 
			
		||||
	if (Sflag != NULL && strcmp(Sflag, "-") == 0)
 | 
			
		||||
		top = 0;
 | 
			
		||||
	else
 | 
			
		||||
		top = gd->hsize + n;
 | 
			
		||||
	if (top > gd->hsize + gd->sy - 1)
 | 
			
		||||
		top = gd->hsize + gd->sy - 1;
 | 
			
		||||
	else {
 | 
			
		||||
		n = args_strtonum(args, 'S', INT_MIN, SHRT_MAX, &cause);
 | 
			
		||||
		if (cause != NULL) {
 | 
			
		||||
			top = gd->hsize;
 | 
			
		||||
			free(cause);
 | 
			
		||||
		} else if (n < 0 && (u_int) -n > gd->hsize)
 | 
			
		||||
			top = 0;
 | 
			
		||||
		else
 | 
			
		||||
			top = gd->hsize + n;
 | 
			
		||||
		if (top > gd->hsize + gd->sy - 1)
 | 
			
		||||
			top = gd->hsize + gd->sy - 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	n = args_strtonum(args, 'E', INT_MIN, SHRT_MAX, &cause);
 | 
			
		||||
	if (cause != NULL) {
 | 
			
		||||
		bottom = gd->hsize + gd->sy - 1;
 | 
			
		||||
		free(cause);
 | 
			
		||||
	} else if (n < 0 && (u_int) -n > gd->hsize)
 | 
			
		||||
		bottom = 0;
 | 
			
		||||
	else
 | 
			
		||||
		bottom = gd->hsize + n;
 | 
			
		||||
	if (bottom > gd->hsize + gd->sy - 1)
 | 
			
		||||
	Eflag = args_get(args, 'E');
 | 
			
		||||
	if (Eflag != NULL && strcmp(Eflag, "-") == 0)
 | 
			
		||||
		bottom = gd->hsize + gd->sy - 1;
 | 
			
		||||
	else {
 | 
			
		||||
		n = args_strtonum(args, 'E', INT_MIN, SHRT_MAX, &cause);
 | 
			
		||||
		if (cause != NULL) {
 | 
			
		||||
			bottom = gd->hsize + gd->sy - 1;
 | 
			
		||||
			free(cause);
 | 
			
		||||
		} else if (n < 0 && (u_int) -n > gd->hsize)
 | 
			
		||||
			bottom = 0;
 | 
			
		||||
		else
 | 
			
		||||
			bottom = gd->hsize + n;
 | 
			
		||||
		if (bottom > gd->hsize + gd->sy - 1)
 | 
			
		||||
			bottom = gd->hsize + gd->sy - 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (bottom < top) {
 | 
			
		||||
		tmp = bottom;
 | 
			
		||||
 
 | 
			
		||||
@@ -27,12 +27,12 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
enum cmd_retval	 cmd_unbind_key_exec(struct cmd *, struct cmd_q *);
 | 
			
		||||
enum cmd_retval	 cmd_unbind_key_table(struct cmd *, struct cmd_q *, int);
 | 
			
		||||
enum cmd_retval	 cmd_unbind_key_mode_table(struct cmd *, struct cmd_q *, int);
 | 
			
		||||
 | 
			
		||||
const struct cmd_entry cmd_unbind_key_entry = {
 | 
			
		||||
	"unbind-key", "unbind",
 | 
			
		||||
	"acnt:", 0, 1,
 | 
			
		||||
	"[-acn] [-t key-table] key",
 | 
			
		||||
	"[-acn] [-t mode-table] key",
 | 
			
		||||
	0,
 | 
			
		||||
	NULL,
 | 
			
		||||
	cmd_unbind_key_exec
 | 
			
		||||
@@ -64,7 +64,7 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (args_has(args, 't'))
 | 
			
		||||
		return (cmd_unbind_key_table(self, cmdq, key));
 | 
			
		||||
		return (cmd_unbind_key_mode_table(self, cmdq, key));
 | 
			
		||||
 | 
			
		||||
	if (key == KEYC_NONE) {
 | 
			
		||||
		while (!RB_EMPTY(&key_bindings)) {
 | 
			
		||||
@@ -81,7 +81,7 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum cmd_retval
 | 
			
		||||
cmd_unbind_key_table(struct cmd *self, struct cmd_q *cmdq, int key)
 | 
			
		||||
cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
 | 
			
		||||
{
 | 
			
		||||
	struct args			*args = self->args;
 | 
			
		||||
	const char			*tablename;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								format.c
									
									
									
									
									
								
							@@ -552,6 +552,13 @@ format_window_pane(struct format_tree *ft, struct window_pane *wp)
 | 
			
		||||
	format_add(ft, "pane_active", "%d", wp == wp->window->active);
 | 
			
		||||
	format_add(ft, "pane_dead", "%d", wp->fd == -1);
 | 
			
		||||
 | 
			
		||||
	if (window_pane_visible(wp)) {
 | 
			
		||||
		format_add(ft, "pane_left", "%u", wp->xoff);
 | 
			
		||||
		format_add(ft, "pane_top", "%u", wp->yoff);
 | 
			
		||||
		format_add(ft, "pane_right", "%u", wp->xoff + wp->sx - 1);
 | 
			
		||||
		format_add(ft, "pane_bottom", "%u", wp->yoff + wp->sy - 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	format_add(ft, "pane_in_mode", "%d", wp->screen != &wp->base);
 | 
			
		||||
	format_add(ft, "pane_synchronized", "%d",
 | 
			
		||||
	    !!options_get_number(&wp->window->options, "synchronize-panes"));
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										104
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								input.c
									
									
									
									
									
								
							@@ -52,6 +52,7 @@ int	input_split(struct input_ctx *);
 | 
			
		||||
int	input_get(struct input_ctx *, u_int, int, int);
 | 
			
		||||
void	input_reply(struct input_ctx *, const char *, ...);
 | 
			
		||||
void	input_set_state(struct window_pane *, const struct input_transition *);
 | 
			
		||||
void	input_reset_cell(struct input_ctx *);
 | 
			
		||||
 | 
			
		||||
/* Transition entry/exit handlers. */
 | 
			
		||||
void	input_clear(struct input_ctx *);
 | 
			
		||||
@@ -104,19 +105,23 @@ enum input_esc_type {
 | 
			
		||||
	INPUT_ESC_NEL,
 | 
			
		||||
	INPUT_ESC_RI,
 | 
			
		||||
	INPUT_ESC_RIS,
 | 
			
		||||
	INPUT_ESC_SCSOFF_G0,
 | 
			
		||||
	INPUT_ESC_SCSON_G0,
 | 
			
		||||
	INPUT_ESC_SCSG0_OFF,
 | 
			
		||||
	INPUT_ESC_SCSG0_ON,
 | 
			
		||||
	INPUT_ESC_SCSG1_OFF,
 | 
			
		||||
	INPUT_ESC_SCSG1_ON,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Escape command table. */
 | 
			
		||||
const struct input_table_entry input_esc_table[] = {
 | 
			
		||||
	{ '0', "(", INPUT_ESC_SCSOFF_G0 },
 | 
			
		||||
	{ '0', "(", INPUT_ESC_SCSG0_ON },
 | 
			
		||||
	{ '0', ")", INPUT_ESC_SCSG1_ON },
 | 
			
		||||
	{ '7', "",  INPUT_ESC_DECSC },
 | 
			
		||||
	{ '8', "",  INPUT_ESC_DECRC },
 | 
			
		||||
	{ '8', "#", INPUT_ESC_DECALN },
 | 
			
		||||
	{ '=', "",  INPUT_ESC_DECKPAM },
 | 
			
		||||
	{ '>', "",  INPUT_ESC_DECKPNM },
 | 
			
		||||
	{ 'B', "(", INPUT_ESC_SCSON_G0 },
 | 
			
		||||
	{ 'B', "(", INPUT_ESC_SCSG0_OFF },
 | 
			
		||||
	{ 'B', ")", INPUT_ESC_SCSG1_OFF },
 | 
			
		||||
	{ 'D', "",  INPUT_ESC_IND },
 | 
			
		||||
	{ 'E', "",  INPUT_ESC_NEL },
 | 
			
		||||
	{ 'H', "",  INPUT_ESC_HTS },
 | 
			
		||||
@@ -684,17 +689,26 @@ input_table_compare(const void *key, const void *value)
 | 
			
		||||
	return (strcmp(ictx->interm_buf, entry->interm));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Reset cell state to default. */
 | 
			
		||||
void
 | 
			
		||||
input_reset_cell(struct input_ctx *ictx)
 | 
			
		||||
{
 | 
			
		||||
	memcpy(&ictx->cell.cell, &grid_default_cell, sizeof ictx->cell.cell);
 | 
			
		||||
	ictx->cell.set = 0;
 | 
			
		||||
	ictx->cell.g0set = ictx->cell.g1set = 0;
 | 
			
		||||
 | 
			
		||||
	memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
 | 
			
		||||
	ictx->old_cx = 0;
 | 
			
		||||
	ictx->old_cy = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Initialise input parser. */
 | 
			
		||||
void
 | 
			
		||||
input_init(struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	struct input_ctx	*ictx = &wp->ictx;
 | 
			
		||||
 | 
			
		||||
	memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell);
 | 
			
		||||
 | 
			
		||||
	memcpy(&ictx->old_cell, &grid_default_cell, sizeof ictx->old_cell);
 | 
			
		||||
	ictx->old_cx = 0;
 | 
			
		||||
	ictx->old_cy = 0;
 | 
			
		||||
	input_reset_cell(ictx);
 | 
			
		||||
 | 
			
		||||
	*ictx->interm_buf = '\0';
 | 
			
		||||
	ictx->interm_len = 0;
 | 
			
		||||
@@ -903,8 +917,18 @@ input_ground(struct input_ctx *ictx)
 | 
			
		||||
int
 | 
			
		||||
input_print(struct input_ctx *ictx)
 | 
			
		||||
{
 | 
			
		||||
	grid_cell_one(&ictx->cell, ictx->ch);
 | 
			
		||||
	screen_write_cell(&ictx->ctx, &ictx->cell);
 | 
			
		||||
	int	set;
 | 
			
		||||
 | 
			
		||||
	set = ictx->cell.set == 0 ? ictx->cell.g0set : ictx->cell.g1set;
 | 
			
		||||
	if (set == 1)
 | 
			
		||||
		ictx->cell.cell.attr |= GRID_ATTR_CHARSET;
 | 
			
		||||
	else
 | 
			
		||||
		ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
 | 
			
		||||
 | 
			
		||||
	grid_cell_one(&ictx->cell.cell, ictx->ch);
 | 
			
		||||
	screen_write_cell(&ictx->ctx, &ictx->cell.cell);
 | 
			
		||||
 | 
			
		||||
	ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
@@ -1000,10 +1024,10 @@ input_c0_dispatch(struct input_ctx *ictx)
 | 
			
		||||
		screen_write_carriagereturn(sctx);
 | 
			
		||||
		goto count_c0;
 | 
			
		||||
	case '\016':	/* SO */
 | 
			
		||||
		ictx->cell.attr |= GRID_ATTR_CHARSET;
 | 
			
		||||
		ictx->cell.set = 1;
 | 
			
		||||
		break;
 | 
			
		||||
	case '\017':	/* SI */
 | 
			
		||||
		ictx->cell.attr &= ~GRID_ATTR_CHARSET;
 | 
			
		||||
		ictx->cell.set = 0;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		log_debug("%s: unknown '%c'", __func__, ictx->ch);
 | 
			
		||||
@@ -1014,7 +1038,7 @@ input_c0_dispatch(struct input_ctx *ictx)
 | 
			
		||||
 | 
			
		||||
count_c0:
 | 
			
		||||
	trigger = options_get_number(&wp->window->options, "c0-change-trigger");
 | 
			
		||||
	if (++wp->changes == trigger) {
 | 
			
		||||
	if (trigger != 0 && ++wp->changes >= trigger) {
 | 
			
		||||
		wp->flags |= PANE_DROP;
 | 
			
		||||
		window_pane_timer_start(wp);
 | 
			
		||||
	}
 | 
			
		||||
@@ -1043,11 +1067,7 @@ input_esc_dispatch(struct input_ctx *ictx)
 | 
			
		||||
 | 
			
		||||
	switch (entry->type) {
 | 
			
		||||
	case INPUT_ESC_RIS:
 | 
			
		||||
		memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell);
 | 
			
		||||
		memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
 | 
			
		||||
		ictx->old_cx = 0;
 | 
			
		||||
		ictx->old_cy = 0;
 | 
			
		||||
 | 
			
		||||
		input_reset_cell(ictx);
 | 
			
		||||
		screen_write_reset(sctx);
 | 
			
		||||
		break;
 | 
			
		||||
	case INPUT_ESC_IND:
 | 
			
		||||
@@ -1082,16 +1102,17 @@ input_esc_dispatch(struct input_ctx *ictx)
 | 
			
		||||
	case INPUT_ESC_DECALN:
 | 
			
		||||
		screen_write_alignmenttest(sctx);
 | 
			
		||||
		break;
 | 
			
		||||
	case INPUT_ESC_SCSON_G0:
 | 
			
		||||
		/*
 | 
			
		||||
		 * Not really supported, but fake it up enough for those that
 | 
			
		||||
		 * use it to switch character sets (by redefining G0 to
 | 
			
		||||
		 * graphics set, rather than switching to G1).
 | 
			
		||||
		 */
 | 
			
		||||
		ictx->cell.attr &= ~GRID_ATTR_CHARSET;
 | 
			
		||||
	case INPUT_ESC_SCSG0_ON:
 | 
			
		||||
		ictx->cell.g0set = 1;
 | 
			
		||||
		break;
 | 
			
		||||
	case INPUT_ESC_SCSOFF_G0:
 | 
			
		||||
		ictx->cell.attr |= GRID_ATTR_CHARSET;
 | 
			
		||||
	case INPUT_ESC_SCSG0_OFF:
 | 
			
		||||
		ictx->cell.g0set = 0;
 | 
			
		||||
		break;
 | 
			
		||||
	case INPUT_ESC_SCSG1_ON:
 | 
			
		||||
		ictx->cell.g1set = 1;
 | 
			
		||||
		break;
 | 
			
		||||
	case INPUT_ESC_SCSG1_OFF:
 | 
			
		||||
		ictx->cell.g1set = 0;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1332,7 +1353,8 @@ input_csi_dispatch_rm(struct input_ctx *ictx)
 | 
			
		||||
void
 | 
			
		||||
input_csi_dispatch_rm_private(struct input_ctx *ictx)
 | 
			
		||||
{
 | 
			
		||||
	u_int	i;
 | 
			
		||||
	struct window_pane	*wp = ictx->wp;
 | 
			
		||||
	u_int			 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ictx->param_list_len; i++) {
 | 
			
		||||
		switch (input_get(ictx, i, 0, -1)) {
 | 
			
		||||
@@ -1366,10 +1388,10 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
 | 
			
		||||
			break;
 | 
			
		||||
		case 47:
 | 
			
		||||
		case 1047:
 | 
			
		||||
			window_pane_alternate_off(ictx->wp, &ictx->cell, 0);
 | 
			
		||||
			window_pane_alternate_off(wp, &ictx->cell.cell, 0);
 | 
			
		||||
			break;
 | 
			
		||||
		case 1049:
 | 
			
		||||
			window_pane_alternate_off(ictx->wp, &ictx->cell, 1);
 | 
			
		||||
			window_pane_alternate_off(wp, &ictx->cell.cell, 1);
 | 
			
		||||
			break;
 | 
			
		||||
		case 2004:
 | 
			
		||||
			screen_write_mode_clear(&ictx->ctx, MODE_BRACKETPASTE);
 | 
			
		||||
@@ -1403,7 +1425,8 @@ input_csi_dispatch_sm(struct input_ctx *ictx)
 | 
			
		||||
void
 | 
			
		||||
input_csi_dispatch_sm_private(struct input_ctx *ictx)
 | 
			
		||||
{
 | 
			
		||||
	u_int	i;
 | 
			
		||||
	struct window_pane	*wp = ictx->wp;
 | 
			
		||||
	u_int			 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ictx->param_list_len; i++) {
 | 
			
		||||
		switch (input_get(ictx, i, 0, -1)) {
 | 
			
		||||
@@ -1436,7 +1459,7 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
 | 
			
		||||
			if (ictx->ctx.s->mode & MODE_FOCUSON)
 | 
			
		||||
				break;
 | 
			
		||||
			screen_write_mode_set(&ictx->ctx, MODE_FOCUSON);
 | 
			
		||||
			ictx->wp->flags |= PANE_FOCUSPUSH; /* force update */
 | 
			
		||||
			wp->flags |= PANE_FOCUSPUSH; /* force update */
 | 
			
		||||
			break;
 | 
			
		||||
		case 1005:
 | 
			
		||||
			screen_write_mode_set(&ictx->ctx, MODE_MOUSE_UTF8);
 | 
			
		||||
@@ -1446,10 +1469,10 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
 | 
			
		||||
			break;
 | 
			
		||||
		case 47:
 | 
			
		||||
		case 1047:
 | 
			
		||||
			window_pane_alternate_on(ictx->wp, &ictx->cell, 0);
 | 
			
		||||
			window_pane_alternate_on(wp, &ictx->cell.cell, 0);
 | 
			
		||||
			break;
 | 
			
		||||
		case 1049:
 | 
			
		||||
			window_pane_alternate_on(ictx->wp, &ictx->cell, 1);
 | 
			
		||||
			window_pane_alternate_on(wp, &ictx->cell.cell, 1);
 | 
			
		||||
			break;
 | 
			
		||||
		case 2004:
 | 
			
		||||
			screen_write_mode_set(&ictx->ctx, MODE_BRACKETPASTE);
 | 
			
		||||
@@ -1514,15 +1537,12 @@ input_csi_dispatch_winops(struct input_ctx *ictx)
 | 
			
		||||
void
 | 
			
		||||
input_csi_dispatch_sgr(struct input_ctx *ictx)
 | 
			
		||||
{
 | 
			
		||||
	struct grid_cell	*gc = &ictx->cell;
 | 
			
		||||
	struct grid_cell	*gc = &ictx->cell.cell;
 | 
			
		||||
	u_int			 i;
 | 
			
		||||
	int			 n, m;
 | 
			
		||||
	u_char			 attr;
 | 
			
		||||
 | 
			
		||||
	if (ictx->param_list_len == 0) {
 | 
			
		||||
		attr = gc->attr;
 | 
			
		||||
		memcpy(gc, &grid_default_cell, sizeof *gc);
 | 
			
		||||
		gc->attr |= (attr & GRID_ATTR_CHARSET);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1560,9 +1580,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
 | 
			
		||||
		switch (n) {
 | 
			
		||||
		case 0:
 | 
			
		||||
		case 10:
 | 
			
		||||
			attr = gc->attr;
 | 
			
		||||
			memcpy(gc, &grid_default_cell, sizeof *gc);
 | 
			
		||||
			gc->attr |= (attr & GRID_ATTR_CHARSET);
 | 
			
		||||
			break;
 | 
			
		||||
		case 1:
 | 
			
		||||
			gc->attr |= GRID_ATTR_BRIGHT;
 | 
			
		||||
@@ -1806,8 +1824,8 @@ input_utf8_close(struct input_ctx *ictx)
 | 
			
		||||
 | 
			
		||||
	utf8_append(&ictx->utf8data, ictx->ch);
 | 
			
		||||
 | 
			
		||||
	grid_cell_set(&ictx->cell, &ictx->utf8data);
 | 
			
		||||
	screen_write_cell(&ictx->ctx, &ictx->cell);
 | 
			
		||||
	grid_cell_set(&ictx->cell.cell, &ictx->utf8data);
 | 
			
		||||
	screen_write_cell(&ictx->ctx, &ictx->cell.cell);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,6 @@
 | 
			
		||||
RB_GENERATE(key_bindings, key_binding, entry, key_bindings_cmp);
 | 
			
		||||
 | 
			
		||||
struct key_bindings	key_bindings;
 | 
			
		||||
struct key_bindings	dead_key_bindings;
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
key_bindings_cmp(struct key_binding *bd1, struct key_binding *bd2)
 | 
			
		||||
@@ -78,20 +77,8 @@ key_bindings_remove(int key)
 | 
			
		||||
	if ((bd = key_bindings_lookup(key)) == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	RB_REMOVE(key_bindings, &key_bindings, bd);
 | 
			
		||||
	RB_INSERT(key_bindings, &dead_key_bindings, bd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
key_bindings_clean(void)
 | 
			
		||||
{
 | 
			
		||||
	struct key_binding	*bd;
 | 
			
		||||
 | 
			
		||||
	while (!RB_EMPTY(&dead_key_bindings)) {
 | 
			
		||||
		bd = RB_ROOT(&dead_key_bindings);
 | 
			
		||||
		RB_REMOVE(key_bindings, &dead_key_bindings, bd);
 | 
			
		||||
		cmd_list_free(bd->cmdlist);
 | 
			
		||||
		free(bd);
 | 
			
		||||
	}
 | 
			
		||||
	cmd_list_free(bd->cmdlist);
 | 
			
		||||
	free(bd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								paste.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								paste.c
									
									
									
									
									
								
							@@ -175,7 +175,7 @@ paste_add(char *data, size_t size)
 | 
			
		||||
int
 | 
			
		||||
paste_rename(const char *oldname, const char *newname, char **cause)
 | 
			
		||||
{
 | 
			
		||||
	struct paste_buffer	*pb;
 | 
			
		||||
	struct paste_buffer	*pb, *pb_new;
 | 
			
		||||
 | 
			
		||||
	if (cause != NULL)
 | 
			
		||||
		*cause = NULL;
 | 
			
		||||
@@ -194,7 +194,14 @@ paste_rename(const char *oldname, const char *newname, char **cause)
 | 
			
		||||
	pb = paste_get_name(oldname);
 | 
			
		||||
	if (pb == NULL) {
 | 
			
		||||
		if (cause != NULL)
 | 
			
		||||
		    xasprintf(cause, "no buffer %s", oldname);
 | 
			
		||||
			xasprintf(cause, "no buffer %s", oldname);
 | 
			
		||||
		return (-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pb_new = paste_get_name(newname);
 | 
			
		||||
	if (pb_new != NULL) {
 | 
			
		||||
		if (cause != NULL)
 | 
			
		||||
			xasprintf(cause, "buffer %s already exists", newname);
 | 
			
		||||
		return (-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								server.c
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								server.c
									
									
									
									
									
								
							@@ -209,7 +209,6 @@ server_loop(void)
 | 
			
		||||
		server_window_loop();
 | 
			
		||||
		server_client_loop();
 | 
			
		||||
 | 
			
		||||
		key_bindings_clean();
 | 
			
		||||
		server_clean_dead();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								tmux.1
									
									
									
									
									
								
							@@ -1152,6 +1152,12 @@ and
 | 
			
		||||
.Fl E
 | 
			
		||||
specify the starting and ending line numbers, zero is the first line of the
 | 
			
		||||
visible pane and negative numbers are lines in the history.
 | 
			
		||||
.Ql -
 | 
			
		||||
to
 | 
			
		||||
.Fl S
 | 
			
		||||
is the start of the history and to
 | 
			
		||||
.Fl E
 | 
			
		||||
the end of the visible pane.
 | 
			
		||||
The default is to capture only the visible contents of the pane.
 | 
			
		||||
.It Xo
 | 
			
		||||
.Ic choose-client
 | 
			
		||||
@@ -1865,7 +1871,7 @@ Commands related to key bindings are as follows:
 | 
			
		||||
.Bl -tag -width Ds
 | 
			
		||||
.It Xo Ic bind-key
 | 
			
		||||
.Op Fl cnr
 | 
			
		||||
.Op Fl t Ar key-table
 | 
			
		||||
.Op Fl t Ar mode-table
 | 
			
		||||
.Ar key Ar command Op Ar arguments
 | 
			
		||||
.Xc
 | 
			
		||||
.D1 (alias: Ic bind )
 | 
			
		||||
@@ -1894,7 +1900,7 @@ If
 | 
			
		||||
is present,
 | 
			
		||||
.Ar key
 | 
			
		||||
is bound in
 | 
			
		||||
.Ar key-table :
 | 
			
		||||
.Ar mode-table :
 | 
			
		||||
the binding for command mode with
 | 
			
		||||
.Fl c
 | 
			
		||||
or for normal mode without.
 | 
			
		||||
@@ -1952,7 +1958,7 @@ Send the prefix key, or with
 | 
			
		||||
the secondary prefix key, to a window as if it was pressed.
 | 
			
		||||
.It Xo Ic unbind-key
 | 
			
		||||
.Op Fl acn
 | 
			
		||||
.Op Fl t Ar key-table
 | 
			
		||||
.Op Fl t Ar mode-table
 | 
			
		||||
.Ar key
 | 
			
		||||
.Xc
 | 
			
		||||
.D1 (alias: Ic unbind )
 | 
			
		||||
@@ -1974,7 +1980,7 @@ If
 | 
			
		||||
is present,
 | 
			
		||||
.Ar key
 | 
			
		||||
in
 | 
			
		||||
.Ar key-table
 | 
			
		||||
.Ar mode-table
 | 
			
		||||
is unbound: the binding for command mode with
 | 
			
		||||
.Fl c
 | 
			
		||||
or for normal mode without.
 | 
			
		||||
@@ -3079,18 +3085,22 @@ The following variables are available, where appropriate:
 | 
			
		||||
.It Li "mouse_standard_flag" Ta "" Ta "Pane mouse standard flag"
 | 
			
		||||
.It Li "mouse_utf8_flag" Ta "" Ta "Pane mouse UTF-8 flag"
 | 
			
		||||
.It Li "pane_active" Ta "" Ta "1 if active pane"
 | 
			
		||||
.It Li "pane_bottom" Ta "" Ta "Bottom of pane"
 | 
			
		||||
.It Li "pane_current_command" Ta "" Ta "Current command if available"
 | 
			
		||||
.It Li "pane_current_path" Ta "" Ta "Current path if available"
 | 
			
		||||
.It Li "pane_dead" Ta "" Ta "1 if pane is dead"
 | 
			
		||||
.It Li "pane_height" Ta "" Ta "Height of pane"
 | 
			
		||||
.It Li "pane_id" Ta "#D" Ta "Unique pane ID"
 | 
			
		||||
.It Li "pane_in_mode" Ta "" Ta "If pane is in a mode"
 | 
			
		||||
.It Li "pane_synchronized" Ta "" Ta "If pane is synchronized"
 | 
			
		||||
.It Li "pane_index" Ta "#P" Ta "Index of pane"
 | 
			
		||||
.It Li "pane_left" Ta "" Ta "Left of pane"
 | 
			
		||||
.It Li "pane_pid" Ta "" Ta "PID of first process in pane"
 | 
			
		||||
.It Li "pane_right" Ta "" Ta "Right of pane"
 | 
			
		||||
.It Li "pane_start_command" Ta "" Ta "Command pane started with"
 | 
			
		||||
.It Li "pane_synchronized" Ta "" Ta "If pane is synchronized"
 | 
			
		||||
.It Li "pane_tabs" Ta "" Ta "Pane tab positions"
 | 
			
		||||
.It Li "pane_title" Ta "#T" Ta "Title of pane"
 | 
			
		||||
.It Li "pane_top" Ta "" Ta "Top of pane"
 | 
			
		||||
.It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane"
 | 
			
		||||
.It Li "pane_width" Ta "" Ta "Width of pane"
 | 
			
		||||
.It Li "saved_cursor_x" Ta "" Ta "Saved cursor X in pane"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								tmux.h
									
									
									
									
									
								
							@@ -800,14 +800,22 @@ struct screen_write_ctx {
 | 
			
		||||
#define screen_hsize(s) ((s)->grid->hsize)
 | 
			
		||||
#define screen_hlimit(s) ((s)->grid->hlimit)
 | 
			
		||||
 | 
			
		||||
/* Input parser cell. */
 | 
			
		||||
struct input_cell {
 | 
			
		||||
	struct grid_cell	cell;
 | 
			
		||||
	int			set;
 | 
			
		||||
	int			g0set;	/* 1 if ACS */
 | 
			
		||||
	int			g1set;	/* 1 if ACS */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Input parser context. */
 | 
			
		||||
struct input_ctx {
 | 
			
		||||
	struct window_pane     *wp;
 | 
			
		||||
	struct screen_write_ctx ctx;
 | 
			
		||||
 | 
			
		||||
	struct grid_cell	cell;
 | 
			
		||||
	struct input_cell	cell;
 | 
			
		||||
 | 
			
		||||
	struct grid_cell	old_cell;
 | 
			
		||||
	struct input_cell	old_cell;
 | 
			
		||||
	u_int 			old_cx;
 | 
			
		||||
	u_int			old_cy;
 | 
			
		||||
 | 
			
		||||
@@ -819,7 +827,7 @@ struct input_ctx {
 | 
			
		||||
 | 
			
		||||
#define INPUT_BUF_START 32
 | 
			
		||||
#define INPUT_BUF_LIMIT 1048576
 | 
			
		||||
	u_char*			input_buf;
 | 
			
		||||
	u_char		       *input_buf;
 | 
			
		||||
	size_t			input_len;
 | 
			
		||||
	size_t			input_space;
 | 
			
		||||
 | 
			
		||||
@@ -1886,7 +1894,6 @@ RB_PROTOTYPE(key_bindings, key_binding, entry, key_bindings_cmp);
 | 
			
		||||
struct key_binding *key_bindings_lookup(int);
 | 
			
		||||
void	 key_bindings_add(int, int, struct cmd_list *);
 | 
			
		||||
void	 key_bindings_remove(int);
 | 
			
		||||
void	 key_bindings_clean(void);
 | 
			
		||||
void	 key_bindings_init(void);
 | 
			
		||||
void	 key_bindings_dispatch(struct key_binding *, struct client *);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								tty-keys.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								tty-keys.c
									
									
									
									
									
								
							@@ -475,6 +475,8 @@ tty_keys_next(struct tty *tty)
 | 
			
		||||
		goto complete_key;
 | 
			
		||||
	case -1:	/* no, or not valid */
 | 
			
		||||
		break;
 | 
			
		||||
	case -2:	/* yes, but we don't care. */
 | 
			
		||||
		goto discard_key;
 | 
			
		||||
	case 1:		/* partial */
 | 
			
		||||
		goto partial_key;
 | 
			
		||||
	}
 | 
			
		||||
@@ -586,6 +588,14 @@ complete_key:
 | 
			
		||||
		server_client_handle_key(tty->client, key);
 | 
			
		||||
 | 
			
		||||
	return (1);
 | 
			
		||||
 | 
			
		||||
discard_key:
 | 
			
		||||
	log_debug("discard key %.*s %#x", (int) size, buf, key);
 | 
			
		||||
 | 
			
		||||
	/* Remove data from buffer. */
 | 
			
		||||
	evbuffer_drain(tty->event->input, size);
 | 
			
		||||
 | 
			
		||||
	return (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Key timer callback. */
 | 
			
		||||
@@ -730,6 +740,15 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
 | 
			
		||||
		sgr = 1;
 | 
			
		||||
		sgr_rel = (c == 'm');
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Some terminals (like PuTTY 0.63) mistakenly send
 | 
			
		||||
		 * button-release events for scroll-wheel button-press event.
 | 
			
		||||
		 * Discard it before it reaches any program running inside
 | 
			
		||||
		 * tmux.
 | 
			
		||||
		 */
 | 
			
		||||
		if (sgr_rel && (sgr_b & 64))
 | 
			
		||||
		    return (-2);
 | 
			
		||||
 | 
			
		||||
		/* Figure out what b would be in old format. */
 | 
			
		||||
		b = sgr_b;
 | 
			
		||||
		if (sgr_rel)
 | 
			
		||||
@@ -764,6 +783,8 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
 | 
			
		||||
		else if (b == 1)
 | 
			
		||||
			m->wheel = MOUSE_WHEEL_DOWN;
 | 
			
		||||
		m->event = MOUSE_EVENT_WHEEL;
 | 
			
		||||
 | 
			
		||||
		m->button = 3;
 | 
			
		||||
	} else if ((b & MOUSE_MASK_BUTTONS) == 3) {
 | 
			
		||||
		if (~m->event & MOUSE_EVENT_DRAG && x == m->x && y == m->y)
 | 
			
		||||
			m->event = MOUSE_EVENT_CLICK;
 | 
			
		||||
 
 | 
			
		||||
@@ -1360,7 +1360,7 @@ window_copy_get_selection(struct window_pane *wp, size_t *len)
 | 
			
		||||
	struct screen			*s = &data->screen;
 | 
			
		||||
	char				*buf;
 | 
			
		||||
	size_t				 off;
 | 
			
		||||
	u_int				 i, xx, yy, sx, sy, ex, ey;
 | 
			
		||||
	u_int				 i, xx, yy, sx, sy, ex, ey, ey_last;
 | 
			
		||||
	u_int				 firstsx, lastex, restex, restsx;
 | 
			
		||||
	int				 keys;
 | 
			
		||||
 | 
			
		||||
@@ -1389,9 +1389,9 @@ window_copy_get_selection(struct window_pane *wp, size_t *len)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Trim ex to end of line. */
 | 
			
		||||
	xx = window_copy_find_length(wp, ey);
 | 
			
		||||
	if (ex > xx)
 | 
			
		||||
		ex = xx;
 | 
			
		||||
	ey_last = window_copy_find_length(wp, ey);
 | 
			
		||||
	if (ex > ey_last)
 | 
			
		||||
		ex = ey_last;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Deal with rectangle-copy if necessary; four situations: start of
 | 
			
		||||
@@ -1442,17 +1442,10 @@ window_copy_get_selection(struct window_pane *wp, size_t *len)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Copy the lines. */
 | 
			
		||||
	if (sy == ey)
 | 
			
		||||
		window_copy_copy_line(wp, &buf, &off, sy, firstsx, lastex);
 | 
			
		||||
	else {
 | 
			
		||||
		window_copy_copy_line(wp, &buf, &off, sy, firstsx, restex);
 | 
			
		||||
		if (ey - sy > 1) {
 | 
			
		||||
			for (i = sy + 1; i < ey; i++) {
 | 
			
		||||
				window_copy_copy_line(
 | 
			
		||||
				    wp, &buf, &off, i, restsx, restex);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		window_copy_copy_line(wp, &buf, &off, ey, restsx, lastex);
 | 
			
		||||
	for (i = sy; i <= ey; i++) {
 | 
			
		||||
		window_copy_copy_line(wp, &buf, &off, i,
 | 
			
		||||
		    (i == sy ? firstsx : restsx),
 | 
			
		||||
		    (i == ey ? lastex : restex));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Don't bother if no data. */
 | 
			
		||||
@@ -1460,7 +1453,9 @@ window_copy_get_selection(struct window_pane *wp, size_t *len)
 | 
			
		||||
		free(buf);
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	}
 | 
			
		||||
	*len = off - 1;	/* remove final \n */
 | 
			
		||||
	if (keys == MODEKEY_EMACS || lastex <= ey_last)
 | 
			
		||||
		off -= 1; /* remove final \n (unless at end in vi mode) */
 | 
			
		||||
	*len = off;
 | 
			
		||||
	return (buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								window.c
									
									
									
									
									
								
							@@ -891,7 +891,6 @@ window_pane_timer_callback(unused int fd, unused short events, void *data)
 | 
			
		||||
	if (wp->changes_redraw++ == interval) {
 | 
			
		||||
		wp->flags |= PANE_REDRAW;
 | 
			
		||||
		wp->changes_redraw = 0;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (trigger == 0 || wp->changes < trigger) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										79
									
								
								xterm-keys.c
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								xterm-keys.c
									
									
									
									
									
								
							@@ -40,8 +40,8 @@
 | 
			
		||||
 * We accept any but always output the latter (it comes first in the table).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int	xterm_keys_match(const char *, const char *, size_t);
 | 
			
		||||
int	xterm_keys_modifiers(const char *, const char *, size_t);
 | 
			
		||||
int	xterm_keys_match(const char *, const char *, size_t, size_t *, u_int *);
 | 
			
		||||
int	xterm_keys_modifiers(const char *, size_t, size_t *, u_int *);
 | 
			
		||||
 | 
			
		||||
struct xterm_keys_entry {
 | 
			
		||||
	int		 key;
 | 
			
		||||
@@ -122,49 +122,62 @@ const struct xterm_keys_entry xterm_keys_table[] = {
 | 
			
		||||
 * 0 for match, 1 if the end of the buffer is reached (need more data).
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
xterm_keys_match(const char *template, const char *buf, size_t len)
 | 
			
		||||
xterm_keys_match(const char *template, const char *buf, size_t len,
 | 
			
		||||
    size_t *size, u_int *modifiers)
 | 
			
		||||
{
 | 
			
		||||
	size_t	pos;
 | 
			
		||||
	int	retval;
 | 
			
		||||
 | 
			
		||||
	if (len == 0)
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	pos = 0;
 | 
			
		||||
	do {
 | 
			
		||||
		if (*template == '_' && buf[pos] >= '1' && buf[pos] <= '8')
 | 
			
		||||
		if (*template == '_') {
 | 
			
		||||
			retval = xterm_keys_modifiers(buf, len, &pos,
 | 
			
		||||
			    modifiers);
 | 
			
		||||
			if (retval != 0)
 | 
			
		||||
				return (retval);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		if (buf[pos] != *template)
 | 
			
		||||
			return (-1);
 | 
			
		||||
	} while (*++template != '\0' && ++pos != len);
 | 
			
		||||
		pos++;
 | 
			
		||||
	} while (*++template != '\0' && pos != len);
 | 
			
		||||
 | 
			
		||||
	if (*template != '\0')	/* partial */
 | 
			
		||||
		return (1);
 | 
			
		||||
 | 
			
		||||
	*size = pos;
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find modifiers based on template. */
 | 
			
		||||
/* Find modifiers from buffer. */
 | 
			
		||||
int
 | 
			
		||||
xterm_keys_modifiers(const char *template, const char *buf, size_t len)
 | 
			
		||||
xterm_keys_modifiers(const char *buf, size_t len, size_t *pos, u_int *modifiers)
 | 
			
		||||
{
 | 
			
		||||
	size_t	idx;
 | 
			
		||||
	int     param, modifiers;
 | 
			
		||||
	u_int	flags;
 | 
			
		||||
 | 
			
		||||
	idx = strcspn(template, "_");
 | 
			
		||||
	if (idx >= len)
 | 
			
		||||
		return (0);
 | 
			
		||||
	param = buf[idx] - '1';
 | 
			
		||||
	if (len - *pos < 2)
 | 
			
		||||
		return (1);
 | 
			
		||||
 | 
			
		||||
	modifiers = 0;
 | 
			
		||||
	if (param & 1)
 | 
			
		||||
		modifiers |= KEYC_SHIFT;
 | 
			
		||||
	if (param & 2)
 | 
			
		||||
		modifiers |= KEYC_ESCAPE;
 | 
			
		||||
	if (param & 4)
 | 
			
		||||
		modifiers |= KEYC_CTRL;
 | 
			
		||||
	if (param & 8)
 | 
			
		||||
		modifiers |= KEYC_ESCAPE;
 | 
			
		||||
	return (modifiers);
 | 
			
		||||
	if (buf[*pos] < '0' || buf[*pos] > '9')
 | 
			
		||||
		return (-1);
 | 
			
		||||
	flags = buf[(*pos)++] - '0';
 | 
			
		||||
	if (buf[*pos] >= '0' && buf[*pos] <= '9')
 | 
			
		||||
		flags = (flags * 10) + (buf[(*pos)++] - '0');
 | 
			
		||||
	flags -= 1;
 | 
			
		||||
 | 
			
		||||
	*modifiers = 0;
 | 
			
		||||
	if (flags & 1)
 | 
			
		||||
		*modifiers |= KEYC_SHIFT;
 | 
			
		||||
	if (flags & 2)
 | 
			
		||||
		*modifiers |= KEYC_ESCAPE;
 | 
			
		||||
	if (flags & 4)
 | 
			
		||||
		*modifiers |= KEYC_CTRL;
 | 
			
		||||
	if (flags & 8)
 | 
			
		||||
		*modifiers |= KEYC_ESCAPE;
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -175,19 +188,19 @@ int
 | 
			
		||||
xterm_keys_find(const char *buf, size_t len, size_t *size, int *key)
 | 
			
		||||
{
 | 
			
		||||
	const struct xterm_keys_entry	*entry;
 | 
			
		||||
	u_int				 i;
 | 
			
		||||
	u_int				 i, modifiers;
 | 
			
		||||
	int				 matched;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < nitems(xterm_keys_table); i++) {
 | 
			
		||||
		entry = &xterm_keys_table[i];
 | 
			
		||||
		switch (xterm_keys_match(entry->template, buf, len)) {
 | 
			
		||||
		case 0:
 | 
			
		||||
			*size = strlen(entry->template);
 | 
			
		||||
			*key = entry->key;
 | 
			
		||||
			*key |= xterm_keys_modifiers(entry->template, buf, len);
 | 
			
		||||
			return (0);
 | 
			
		||||
		case 1:
 | 
			
		||||
			return (1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		matched = xterm_keys_match(entry->template, buf, len, size,
 | 
			
		||||
		    &modifiers);
 | 
			
		||||
		if (matched == -1)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (matched == 0)
 | 
			
		||||
			*key = entry->key | modifiers;
 | 
			
		||||
		return (matched);
 | 
			
		||||
	}
 | 
			
		||||
	return (-1);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user