mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Properly track switching G0 and G1 modes between US-ASCII and VT100 line
drawing rather than just treating them as SO and SI.
This commit is contained in:
		
							
								
								
									
										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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								tmux.h
									
									
									
									
									
								
							@@ -803,14 +803,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;
 | 
			
		||||
 | 
			
		||||
@@ -822,7 +830,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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user