Commit message: When searching for tabs, start from screen width, fixes out-of-bounds
read found by Kuang-che Wu.
CVE: None
Vulnerability description: None

Project: tmux
File: input.c

input_free(struct window_pane *wp)
{
	struct input_ctx	*ictx = wp->ictx;

	free(ictx->input_buf);
	evbuffer_free(ictx->since_ground);

	free (ictx);
	wp->ictx = NULL;
}

Project: tmux
File: input.c

input_utf8_open(struct input_ctx *ictx)
{
	if (!options_get_number(&ictx->wp->window->options, "utf8")) {
		/* Print, and do not switch state. */
		input_print(ictx);
		return (-1);
	}
	log_debug("%s", __func__);

	utf8_open(&ictx->utf8data, ictx->ch);
	return (0);
}

Project: tmux
File: input.c

input_exit_osc(struct input_ctx *ictx)
{
	u_char	*p = ictx->input_buf;
	u_int	 option;

	if (ictx->flags & INPUT_DISCARD)
		return;
	if (ictx->input_len < 1 || *p < '0' || *p > '9')
		return;

	log_debug("%s: \"%s\"", __func__, p);

	option = 0;
	while (*p >= '0' && *p <= '9')
		option = option * 10 + *p++ - '0';
	if (*p == ';')
		p++;

	switch (option) {
	case 0:
	case 2:
		screen_set_title(ictx->ctx.s, p);
		server_status_window(ictx->wp->window);
		break;
	case 12:
		if (*p != '?') /* ? is colour request */
			screen_set_cursor_colour(ictx->ctx.s, p);
		break;
	case 112:
		if (*p == '\0') /* no arguments allowed */
			screen_set_cursor_colour(ictx->ctx.s, "");
		break;
	default:
		log_debug("%s: unknown '%u'", __func__, option);
		break;
	}
}

Project: tmux
File: input.c

input_c0_dispatch(struct input_ctx *ictx)
{
	struct screen_write_ctx	*sctx = &ictx->ctx;
	struct window_pane	*wp = ictx->wp;
	struct screen		*s = sctx->s;

	log_debug("%s: '%c", __func__, ictx->ch);

	switch (ictx->ch) {
	case '\000':	/* NUL */
		break;
	case '\007':	/* BEL */
		wp->window->flags |= WINDOW_BELL;
		break;
	case '\010':	/* BS */
		screen_write_backspace(sctx);
		break;
	case '\011':	/* HT */
		/* Don't tab beyond the end of the line. */
		if (s->cx >= screen_size_x(s) - 1)
			break;

		/* Find the next tab point, or use the last column if none. */
		do {
			s->cx++;
			if (bit_test(s->tabs, s->cx))
				break;
		} while (s->cx < screen_size_x(s) - 1);
		break;
	case '\012':	/* LF */
	case '\013':	/* VT */
	case '\014':	/* FF */
		screen_write_linefeed(sctx, 0);
		break;
	case '\015':	/* CR */
		screen_write_carriagereturn(sctx);
		break;
	case '\016':	/* SO */
		ictx->cell.set = 1;
		break;
	case '\017':	/* SI */
		ictx->cell.set = 0;
		break;
	default:
		log_debug("%s: unknown '%c'", __func__, ictx->ch);
		break;
	}

	return (0);
}

Project: tmux
File: input.c

input_split(struct input_ctx *ictx)

{
	const char	*errstr;
	char		*ptr, *out;
	int		 n;

	ictx->param_list_len = 0;
	if (ictx->param_len == 0)
		return (0);

	ptr = ictx->param_buf;
	while ((out = strsep(&ptr, ";")) != NULL) {
		if (*out == '\0')
			n = -1;
		else {
			n = strtonum(out, 0, INT_MAX, &errstr);
			if (errstr != NULL)
				return (-1);
		}

		ictx->param_list[ictx->param_list_len++] = n;
		if (ictx->param_list_len == nitems(ictx->param_list))
			return (-1);
	}

	return (0);
}

Project: tmux
File: input.c

input_print(struct input_ctx *ictx)
{
	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);
}

Project: tmux
File: input.c

input_csi_dispatch(struct input_ctx *ictx)
{
	struct screen_write_ctx	       *sctx = &ictx->ctx;
	struct screen		       *s = sctx->s;
	struct input_table_entry       *entry;
	int				n, m;
	u_int				cx;

	if (ictx->flags & INPUT_DISCARD)
		return (0);
	if (input_split(ictx) != 0)
		return (0);
	log_debug("%s: '%c' \"%s\" \"%s\"",
	    __func__, ictx->ch, ictx->interm_buf, ictx->param_buf);

	entry = bsearch(ictx, input_csi_table, nitems(input_csi_table),
	    sizeof input_csi_table[0], input_table_compare);
	if (entry == NULL) {
		log_debug("%s: unknown '%c'", __func__, ictx->ch);
		return (0);
	}

	switch (entry->type) {
	case INPUT_CSI_CBT:
		/* Find the previous tab point, n times. */
		cx = s->cx;
		if (cx > screen_size_x(s) - 1)
			cx = screen_size_x(s) - 1;
		n = input_get(ictx, 0, 1, 1);
		while (cx > 0 && n-- > 0) {
			do
				cx--;
			while (cx > 0 && !bit_test(s->tabs, cx));
		}
		s->cx = cx;
		break;
	case INPUT_CSI_CUB:
		screen_write_cursorleft(sctx, input_get(ictx, 0, 1, 1));
		break;
	case INPUT_CSI_CUD:
		screen_write_cursordown(sctx, input_get(ictx, 0, 1, 1));
		break;
	case INPUT_CSI_CUF:
		screen_write_cursorright(sctx, input_get(ictx, 0, 1, 1));
		break;
	case INPUT_CSI_CUP:
		n = input_get(ictx, 0, 1, 1);
		m = input_get(ictx, 1, 1, 1);
		screen_write_cursormove(sctx, m - 1, n - 1);
		break;
	case INPUT_CSI_WINOPS:
		input_csi_dispatch_winops(ictx);
		break;
	case INPUT_CSI_CUU:
		screen_write_cursorup(sctx, input_get(ictx, 0, 1, 1));
		break;
	case INPUT_CSI_CNL:
		screen_write_carriagereturn(sctx);
		screen_write_cursordown(sctx, input_get(ictx, 0, 1, 1));
		break;
	case INPUT_CSI_CPL:
		screen_write_carriagereturn(sctx);
		screen_write_cursorup(sctx, input_get(ictx, 0, 1, 1));
		break;
	case INPUT_CSI_DA:
		switch (input_get(ictx, 0, 0, 0)) {
		case 0:
			input_reply(ictx, "\033[?1;2c");
			break;
		default:
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
			break;
		}
		break;
	case INPUT_CSI_DA_TWO:
		switch (input_get(ictx, 0, 0, 0)) {
		case 0:
			input_reply(ictx, "\033[>84;0;0c");
			break;
		default:
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
			break;
		}
		break;
	case INPUT_CSI_ECH:
		screen_write_clearcharacter(sctx, input_get(ictx, 0, 1, 1));
		break;
	case INPUT_CSI_DCH:
		screen_write_deletecharacter(sctx, input_get(ictx, 0, 1, 1));
		break;
	case INPUT_CSI_DECSTBM:
		n = input_get(ictx, 0, 1, 1);
		m = input_get(ictx, 1, 1, screen_size_y(s));
		screen_write_scrollregion(sctx, n - 1, m - 1);
		break;
	case INPUT_CSI_DL:
		screen_write_deleteline(sctx, input_get(ictx, 0, 1, 1));
		break;
	case INPUT_CSI_DSR:
		switch (input_get(ictx, 0, 0, 0)) {
		case 5:
			input_reply(ictx, "\033[0n");
			break;
		case 6:
			input_reply(ictx, "\033[%u;%uR", s->cy + 1, s->cx + 1);
			break;
		default:
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
			break;
		}
		break;
	case INPUT_CSI_ED:
		switch (input_get(ictx, 0, 0, 0)) {
		case 0:
			screen_write_clearendofscreen(sctx);
			break;
		case 1:
			screen_write_clearstartofscreen(sctx);
			break;
		case 2:
			screen_write_clearscreen(sctx);
			break;
		case 3:
			switch (input_get(ictx, 1, 0, 0)) {
			case 0:
				/*
				 * Linux console extension to clear history
				 * (for example before locking the screen).
				 */
				screen_write_clearhistory(sctx);
				break;
			}
			break;
		default:
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
			break;
		}
		break;
	case INPUT_CSI_EL:
		switch (input_get(ictx, 0, 0, 0)) {
		case 0:
			screen_write_clearendofline(sctx);
			break;
		case 1:
			screen_write_clearstartofline(sctx);
			break;
		case 2:
			screen_write_clearline(sctx);
			break;
		default:
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
			break;
		}
		break;
	case INPUT_CSI_HPA:
		n = input_get(ictx, 0, 1, 1);
		screen_write_cursormove(sctx, n - 1, s->cy);
		break;
	case INPUT_CSI_ICH:
		screen_write_insertcharacter(sctx, input_get(ictx, 0, 1, 1));
		break;
	case INPUT_CSI_IL:
		screen_write_insertline(sctx, input_get(ictx, 0, 1, 1));
		break;
	case INPUT_CSI_RCP:
		memcpy(&ictx->cell, &ictx->old_cell, sizeof ictx->cell);
		screen_write_cursormove(sctx, ictx->old_cx, ictx->old_cy);
		break;
	case INPUT_CSI_RM:
		input_csi_dispatch_rm(ictx);
		break;
	case INPUT_CSI_RM_PRIVATE:
		input_csi_dispatch_rm_private(ictx);
		break;
	case INPUT_CSI_SCP:
		memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
		ictx->old_cx = s->cx;
		ictx->old_cy = s->cy;
		break;
	case INPUT_CSI_SGR:
		input_csi_dispatch_sgr(ictx);
		break;
	case INPUT_CSI_SM:
		input_csi_dispatch_sm(ictx);
		break;
	case INPUT_CSI_SM_PRIVATE:
		input_csi_dispatch_sm_private(ictx);
		break;
	case INPUT_CSI_TBC:
		switch (input_get(ictx, 0, 0, 0)) {
		case 0:
			if (s->cx < screen_size_x(s))
				bit_clear(s->tabs, s->cx);
			break;
		case 3:
			bit_nclear(s->tabs, 0, screen_size_x(s) - 1);
			break;
		default:
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
			break;
		}
		break;
	case INPUT_CSI_VPA:
		n = input_get(ictx, 0, 1, 1);
		screen_write_cursormove(sctx, s->cx, n - 1);
		break;
	case INPUT_CSI_DECSCUSR:
		n = input_get(ictx, 0, 0, 0);
		screen_set_cursor_style(s, n);
		break;
	}

	return (0);
}

Project: tmux
File: input.c

input_enter_apc(struct input_ctx *ictx)
{
	log_debug("%s", __func__);

	input_clear(ictx);
}

Project: tmux
File: input.c

input_esc_dispatch(struct input_ctx *ictx)
{
	struct screen_write_ctx		*sctx = &ictx->ctx;
	struct screen			*s = sctx->s;
	struct input_table_entry	*entry;

	if (ictx->flags & INPUT_DISCARD)
		return (0);
	log_debug("%s: '%c', %s", __func__, ictx->ch, ictx->interm_buf);

	entry = bsearch(ictx, input_esc_table, nitems(input_esc_table),
	    sizeof input_esc_table[0], input_table_compare);
	if (entry == NULL) {
		log_debug("%s: unknown '%c'", __func__, ictx->ch);
		return (0);
	}

	switch (entry->type) {
	case INPUT_ESC_RIS:
		input_reset_cell(ictx);
		screen_write_reset(sctx);
		break;
	case INPUT_ESC_IND:
		screen_write_linefeed(sctx, 0);
		break;
	case INPUT_ESC_NEL:
		screen_write_carriagereturn(sctx);
		screen_write_linefeed(sctx, 0);
		break;
	case INPUT_ESC_HTS:
		if (s->cx < screen_size_x(s))
			bit_set(s->tabs, s->cx);
		break;
	case INPUT_ESC_RI:
		screen_write_reverseindex(sctx);
		break;
	case INPUT_ESC_DECKPAM:
		screen_write_mode_set(sctx, MODE_KKEYPAD);
		break;
	case INPUT_ESC_DECKPNM:
		screen_write_mode_clear(sctx, MODE_KKEYPAD);
		break;
	case INPUT_ESC_DECSC:
		memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
		ictx->old_cx = s->cx;
		ictx->old_cy = s->cy;
		break;
	case INPUT_ESC_DECRC:
		memcpy(&ictx->cell, &ictx->old_cell, sizeof ictx->cell);
		screen_write_cursormove(sctx, ictx->old_cx, ictx->old_cy);
		break;
	case INPUT_ESC_DECALN:
		screen_write_alignmenttest(sctx);
		break;
	case INPUT_ESC_SCSG0_ON:
		ictx->cell.g0set = 1;
		break;
	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;
	}

	return (0);
}

Project: tmux
File: input.c

input_csi_dispatch_sgr(struct input_ctx *ictx)
{
	struct grid_cell	*gc = &ictx->cell.cell;
	u_int			 i;
	int			 n;

	if (ictx->param_list_len == 0) {
		memcpy(gc, &grid_default_cell, sizeof *gc);
		return;
	}

	for (i = 0; i < ictx->param_list_len; i++) {
		n = input_get(ictx, i, 0, 0);

		if (n == 38 || n == 48) {
			i++;
			switch (input_get(ictx, i, 0, -1)) {
			case 2:
				input_csi_dispatch_sgr_rgb(ictx, n, &i);
				break;
			case 5:
				input_csi_dispatch_sgr_256(ictx, n, &i);
				break;
			}
			continue;
		}

		switch (n) {
		case 0:
		case 10:
			memcpy(gc, &grid_default_cell, sizeof *gc);
			break;
		case 1:
			gc->attr |= GRID_ATTR_BRIGHT;
			break;
		case 2:
			gc->attr |= GRID_ATTR_DIM;
			break;
		case 3:
			gc->attr |= GRID_ATTR_ITALICS;
			break;
		case 4:
			gc->attr |= GRID_ATTR_UNDERSCORE;
			break;
		case 5:
			gc->attr |= GRID_ATTR_BLINK;
			break;
		case 7:
			gc->attr |= GRID_ATTR_REVERSE;
			break;
		case 8:
			gc->attr |= GRID_ATTR_HIDDEN;
			break;
		case 22:
			gc->attr &= ~(GRID_ATTR_BRIGHT|GRID_ATTR_DIM);
			break;
		case 23:
			gc->attr &= ~GRID_ATTR_ITALICS;
			break;
		case 24:
			gc->attr &= ~GRID_ATTR_UNDERSCORE;
			break;
		case 25:
			gc->attr &= ~GRID_ATTR_BLINK;
			break;
		case 27:
			gc->attr &= ~GRID_ATTR_REVERSE;
			break;
		case 30:
		case 31:
		case 32:
		case 33:
		case 34:
		case 35:
		case 36:
		case 37:
			gc->flags &= ~GRID_FLAG_FG256;
			gc->fg = n - 30;
			break;
		case 39:
			gc->flags &= ~GRID_FLAG_FG256;
			gc->fg = 8;
			break;
		case 40:
		case 41:
		case 42:
		case 43:
		case 44:
		case 45:
		case 46:
		case 47:
			gc->flags &= ~GRID_FLAG_BG256;
			gc->bg = n - 40;
			break;
		case 49:
			gc->flags &= ~GRID_FLAG_BG256;
			gc->bg = 8;
			break;
		case 90:
		case 91:
		case 92:
		case 93:
		case 94:
		case 95:
		case 96:
		case 97:
			gc->flags &= ~GRID_FLAG_FG256;
			gc->fg = n;
			break;
		case 100:
		case 101:
		case 102:
		case 103:
		case 104:
		case 105:
		case 106:
		case 107:
			gc->flags &= ~GRID_FLAG_BG256;
			gc->bg = n - 10;
			break;
		}
	}
}

Project: tmux
File: input.c

input_csi_dispatch_sm(struct input_ctx *ictx)
{
	u_int	i;

	for (i = 0; i < ictx->param_list_len; i++) {
		switch (input_get(ictx, i, 0, -1)) {
		case 4:		/* IRM */
			screen_write_mode_set(&ictx->ctx, MODE_INSERT);
			break;
		case 34:
			screen_write_mode_clear(&ictx->ctx, MODE_BLINKING);
			break;
		default:
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
			break;
		}
	}
}

Project: tmux
File: input.c

input_exit_apc(struct input_ctx *ictx)
{
	if (ictx->flags & INPUT_DISCARD)
		return;
	log_debug("%s: \"%s\"", __func__, ictx->input_buf);

	screen_set_title(ictx->ctx.s, ictx->input_buf);
	server_status_window(ictx->wp->window);
}

Project: tmux
File: input.c

input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i)
{
	struct grid_cell	*gc = &ictx->cell.cell;
	int			 c, r, g, b;

	(*i)++;
	r = input_get(ictx, *i, 0, -1);
	if (r == -1 || r > 255)
		return;
	(*i)++;
	g = input_get(ictx, *i, 0, -1);
	if (g == -1 || g > 255)
		return;
	(*i)++;
	b = input_get(ictx, *i, 0, -1);
	if (b == -1 || b > 255)
		return;

	c = colour_find_rgb(r, g, b);
	if (fgbg == 38) {
		gc->flags |= GRID_FLAG_FG256;
		gc->fg = c;
	} else if (fgbg == 48) {
		gc->flags |= GRID_FLAG_BG256;
		gc->bg = c;
	}
}

Project: tmux
File: input.c

input_csi_dispatch_sgr_256(struct input_ctx *ictx, int fgbg, u_int *i)
{
	struct grid_cell	*gc = &ictx->cell.cell;
	int			 c;

	(*i)++;
	c = input_get(ictx, *i, 0, -1);
	if (c == -1) {
		if (fgbg == 38) {
			gc->flags &= ~GRID_FLAG_FG256;
			gc->fg = 8;
		} else if (fgbg == 48) {
			gc->flags &= ~GRID_FLAG_BG256;
			gc->bg = 8;
		}
	} else {
		if (fgbg == 38) {
			gc->flags |= GRID_FLAG_FG256;
			gc->fg = c;
		} else if (fgbg == 48) {
			gc->flags |= GRID_FLAG_BG256;
			gc->bg = c;
		}
	}
}

Project: tmux
File: input.c

input_clear(struct input_ctx *ictx)
{
	*ictx->interm_buf = '\0';
	ictx->interm_len = 0;

	*ictx->param_buf = '\0';
	ictx->param_len = 0;

	*ictx->input_buf = '\0';
	ictx->input_len = 0;

	ictx->flags &= ~INPUT_DISCARD;
}

Project: tmux
File: input.c

input_get(struct input_ctx *ictx, u_int validx, int minval, int defval)
{
	int	retval;

	if (validx >= ictx->param_list_len)
	    return (defval);

	retval = ictx->param_list[validx];
	if (retval == -1)
		return (defval);
	if (retval < minval)
		return (minval);
	return (retval);
}

Project: tmux
File: input.c

input_enter_osc(struct input_ctx *ictx)
{
	log_debug("%s", __func__);

	input_clear(ictx);
}

Project: tmux
File: input.c

input_utf8_close(struct input_ctx *ictx)
{
	log_debug("%s", __func__);

	utf8_append(&ictx->utf8data, ictx->ch);

	grid_cell_set(&ictx->cell.cell, &ictx->utf8data);
	screen_write_cell(&ictx->ctx, &ictx->cell.cell);

	return (0);
}

Project: tmux
File: input.c

input_reset(struct window_pane *wp)
{
	struct input_ctx	*ictx = wp->ictx;

	input_reset_cell(ictx);

	if (wp->mode == NULL)
		screen_write_start(&ictx->ctx, wp, &wp->base);
	else
		screen_write_start(&ictx->ctx, NULL, &wp->base);
	screen_write_reset(&ictx->ctx);
	screen_write_stop(&ictx->ctx);
}

Project: tmux
File: input.c

input_utf8_add(struct input_ctx *ictx)
{
	log_debug("%s", __func__);

	utf8_append(&ictx->utf8data, ictx->ch);
	return (0);
}

Project: tmux
File: input.c

input_parse(struct window_pane *wp)
{
	struct input_ctx		*ictx = wp->ictx;
	const struct input_transition	*itr;
	struct evbuffer			*evb = wp->event->input;
	u_char				*buf;
	size_t				 len, off;

	if (EVBUFFER_LENGTH(evb) == 0)
		return;

	wp->window->flags |= WINDOW_ACTIVITY;
	wp->window->flags &= ~WINDOW_SILENCE;

	if (gettimeofday(&wp->window->activity_time, NULL) != 0)
		fatal("gettimeofday failed");

	/*
	 * Open the screen. Use NULL wp if there is a mode set as don't want to
	 * update the tty.
	 */
	if (wp->mode == NULL)
		screen_write_start(&ictx->ctx, wp, &wp->base);
	else
		screen_write_start(&ictx->ctx, NULL, &wp->base);
	ictx->wp = wp;

	buf = EVBUFFER_DATA(evb);
	len = EVBUFFER_LENGTH(evb);
	notify_input(wp, evb);
	off = 0;

	/* Parse the input. */
	while (off < len) {
		ictx->ch = buf[off++];
		log_debug("%s: '%c' %s", __func__, ictx->ch, ictx->state->name);

		/* Find the transition. */
		itr = ictx->state->transitions;
		while (itr->first != -1 && itr->last != -1) {
			if (ictx->ch >= itr->first && ictx->ch <= itr->last)
				break;
			itr++;
		}
		if (itr->first == -1 || itr->last == -1) {
			/* No transition? Eh? */
			fatalx("No transition from state!");
		}

		/*
		 * Execute the handler, if any. Don't switch state if it
		 * returns non-zero.
		 */
		if (itr->handler != NULL && itr->handler(ictx) != 0)
			continue;

		/* And switch state, if necessary. */
		if (itr->state != NULL)
			input_set_state(wp, itr);

		/* If not in ground state, save input. */
		if (ictx->state != &input_state_ground)
			evbuffer_add(ictx->since_ground, &ictx->ch, 1);
	}

	/* Close the screen. */
	screen_write_stop(&ictx->ctx);

	evbuffer_drain(evb, len);
}

Project: tmux
File: input.c

input_exit_rename(struct input_ctx *ictx)
{
	if (ictx->flags & INPUT_DISCARD)
		return;
	if (!options_get_number(&ictx->wp->window->options, "allow-rename"))
		return;
	log_debug("%s: \"%s\"", __func__, ictx->input_buf);

	window_set_name(ictx->wp->window, ictx->input_buf);
	options_set_number(&ictx->wp->window->options, "automatic-rename", 0);

	server_status_window(ictx->wp->window);
}

Project: tmux
File: input.c

input_csi_dispatch_rm_private(struct input_ctx *ictx)
{
	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)) {
		case 1:		/* DECCKM */
			screen_write_mode_clear(&ictx->ctx, MODE_KCURSOR);
			break;
		case 3:		/* DECCOLM */
			screen_write_cursormove(&ictx->ctx, 0, 0);
			screen_write_clearscreen(&ictx->ctx);
			break;
		case 7:		/* DECAWM */
			screen_write_mode_clear(&ictx->ctx, MODE_WRAP);
			break;
		case 12:
			screen_write_mode_clear(&ictx->ctx, MODE_BLINKING);
			break;
		case 25:	/* TCEM */
			screen_write_mode_clear(&ictx->ctx, MODE_CURSOR);
			break;
		case 1000:
		case 1001:
		case 1002:
			screen_write_mode_clear(&ictx->ctx, ALL_MOUSE_MODES);
			break;
		case 1004:
			screen_write_mode_clear(&ictx->ctx, MODE_FOCUSON);
			break;
		case 1005:
			screen_write_mode_clear(&ictx->ctx, MODE_MOUSE_UTF8);
			break;
		case 1006:
			screen_write_mode_clear(&ictx->ctx, MODE_MOUSE_SGR);
			break;
		case 47:
		case 1047:
			window_pane_alternate_off(wp, &ictx->cell.cell, 0);
			break;
		case 1049:
			window_pane_alternate_off(wp, &ictx->cell.cell, 1);
			break;
		case 2004:
			screen_write_mode_clear(&ictx->ctx, MODE_BRACKETPASTE);
			break;
		default:
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
			break;
		}
	}
}

Project: tmux
File: input.c

input_enter_rename(struct input_ctx *ictx)
{
	log_debug("%s", __func__);

	input_clear(ictx);
}

Project: tmux
File: input.c

input_ground(struct input_ctx *ictx)
{
	evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground));

	if (ictx->input_space > INPUT_BUF_START) {
		ictx->input_space = INPUT_BUF_START;
		ictx->input_buf = xrealloc(ictx->input_buf, INPUT_BUF_START);
	}
}

Project: tmux
File: input.c

input_csi_dispatch_rm(struct input_ctx *ictx)
{
	u_int	i;

	for (i = 0; i < ictx->param_list_len; i++) {
		switch (input_get(ictx, i, 0, -1)) {
		case 4:		/* IRM */
			screen_write_mode_clear(&ictx->ctx, MODE_INSERT);
			break;
		case 34:
			screen_write_mode_set(&ictx->ctx, MODE_BLINKING);
			break;
		default:
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
			break;
		}
	}
}

Project: tmux
File: input.c

input_init(struct window_pane *wp)
{
	struct input_ctx	*ictx;

	ictx = wp->ictx = xcalloc(1, sizeof *ictx);

	input_reset_cell(ictx);

	*ictx->interm_buf = '\0';
	ictx->interm_len = 0;

	*ictx->param_buf = '\0';
	ictx->param_len = 0;

	ictx->input_space = INPUT_BUF_START;
	ictx->input_buf = xmalloc(INPUT_BUF_START);

	*ictx->input_buf = '\0';
	ictx->input_len = 0;

	ictx->state = &input_state_ground;
	ictx->flags = 0;

	ictx->since_ground = evbuffer_new();
}

Project: tmux
File: input.c

input_csi_dispatch_sm_private(struct input_ctx *ictx)
{
	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)) {
		case 1:		/* DECCKM */
			screen_write_mode_set(&ictx->ctx, MODE_KCURSOR);
			break;
		case 3:		/* DECCOLM */
			screen_write_cursormove(&ictx->ctx, 0, 0);
			screen_write_clearscreen(&ictx->ctx);
			break;
		case 7:		/* DECAWM */
			screen_write_mode_set(&ictx->ctx, MODE_WRAP);
			break;
		case 12:
			screen_write_mode_set(&ictx->ctx, MODE_BLINKING);
			break;
		case 25:	/* TCEM */
			screen_write_mode_set(&ictx->ctx, MODE_CURSOR);
			break;
		case 1000:
			screen_write_mode_clear(&ictx->ctx, ALL_MOUSE_MODES);
			screen_write_mode_set(&ictx->ctx, MODE_MOUSE_STANDARD);
			break;
		case 1002:
			screen_write_mode_clear(&ictx->ctx, ALL_MOUSE_MODES);
			screen_write_mode_set(&ictx->ctx, MODE_MOUSE_BUTTON);
			break;
		case 1004:
			if (ictx->ctx.s->mode & MODE_FOCUSON)
				break;
			screen_write_mode_set(&ictx->ctx, MODE_FOCUSON);
			wp->flags |= PANE_FOCUSPUSH; /* force update */
			break;
		case 1005:
			screen_write_mode_set(&ictx->ctx, MODE_MOUSE_UTF8);
			break;
		case 1006:
			screen_write_mode_set(&ictx->ctx, MODE_MOUSE_SGR);
			break;
		case 47:
		case 1047:
			window_pane_alternate_on(wp, &ictx->cell.cell, 0);
			break;
		case 1049:
			window_pane_alternate_on(wp, &ictx->cell.cell, 1);
			break;
		case 2004:
			screen_write_mode_set(&ictx->ctx, MODE_BRACKETPASTE);
			break;
		default:
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
			break;
		}
	}
}

Project: tmux
File: input.c

input_reply(struct input_ctx *ictx, const char *fmt, ...)
{
	va_list	ap;
	char   *reply;

	va_start(ap, fmt);
	vasprintf(&reply, fmt, ap);
	va_end(ap);

	bufferevent_write(ictx->wp->event, reply, strlen(reply));
	free(reply);
}

Project: tmux
File: input.c

input_csi_dispatch_winops(struct input_ctx *ictx)
{
	struct window_pane	*wp = ictx->wp;
	int			 n, m;

	m = 0;
	while ((n = input_get(ictx, m, 0, -1)) != -1) {
		switch (n) {
		case 1:
		case 2:
		case 5:
		case 6:
		case 7:
		case 11:
		case 13:
		case 14:
		case 19:
		case 20:
		case 21:
		case 24:
			break;
		case 3:
		case 4:
		case 8:
			m++;
			if (input_get(ictx, m, 0, -1) == -1)
				return;
			/* FALLTHROUGH */
		case 9:
		case 10:
		case 22:
		case 23:
			m++;
			if (input_get(ictx, m, 0, -1) == -1)
				return;
			break;
		case 18:
			input_reply(ictx, "\033[8;%u;%ut", wp->sy, wp->sx);
			break;
		default:
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
			break;
		}
		m++;
	}
}