示例#1
0
/* Execute C0 control sequence. */
int
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.attr |= GRID_ATTR_CHARSET;
		break;
	case '\017':	/* SI */
		ictx->cell.attr &= ~GRID_ATTR_CHARSET;
		break;
	default:
		log_debug("%s: unknown '%c'", __func__, ictx->ch);
		break;
	}

	return (0);
}
示例#2
0
void
window_copy_vadd(struct window_pane *wp, const char *fmt, va_list ap)
{
	struct window_copy_mode_data	*data = wp->modedata;
	struct screen			*backing = data->backing;
	struct screen_write_ctx	 	 back_ctx, ctx;
	struct grid_cell		 gc;
	int				 utf8flag;
	u_int				 old_hsize;

	if (backing == &wp->base)
		return;

	utf8flag = options_get_number(&wp->window->options, "utf8");
	memcpy(&gc, &grid_default_cell, sizeof gc);

	old_hsize = screen_hsize(data->backing);
	screen_write_start(&back_ctx, NULL, backing);
	if (data->backing_written) {
		/*
		 * On the second or later line, do a CRLF before writing
		 * (so it's on a new line).
		 */
		screen_write_carriagereturn(&back_ctx);
		screen_write_linefeed(&back_ctx, 0);
	} else
		data->backing_written = 1;
	screen_write_vnputs(&back_ctx, 0, &gc, utf8flag, fmt, ap);
	screen_write_stop(&back_ctx);

	data->oy += screen_hsize(data->backing) - old_hsize;

	screen_write_start(&ctx, wp, &data->screen);

	/*
	 * If the history has changed, draw the top line.
	 * (If there's any history at all, it has changed.)
	 */
	if (screen_hsize(data->backing))
		window_copy_redraw_lines(wp, 0, 1);

	/* Write the line, if it's visible. */
	if (backing->cy + data->oy < screen_size_y(backing))
		window_copy_redraw_lines(wp, backing->cy, 1);

	screen_write_stop(&ctx);
}
示例#3
0
/* Write cell data. */
void
screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
{
	struct screen		*s = ctx->s;
	struct grid		*gd = s->grid;
	struct tty_ctx		 ttyctx;
	u_int		 	 width, xx, last;
	u_int			 sx = screen_size_x(s), sy = screen_size_y(s);
	struct grid_line	*gl;
	struct grid_cell 	 tmp_gc, now_gc;
	struct grid_cell_entry	*gce;
	int			 insert, skip, selected, wrapped = 0;

	ctx->cells++;

	/* Ignore padding. */
	if (gc->flags & GRID_FLAG_PADDING)
		return;
	width = gc->data.width;

	/*
	 * If this is a wide character and there is no room on the screen, for
	 * the entire character, don't print it.
	 */
	if (!(s->mode & MODE_WRAP) && (width > 1 &&
	    (width > sx || (s->cx != sx && s->cx > sx - width))))
		return;

	/*
	 * If the width is zero, combine onto the previous character, if
	 * there is space.
	 */
	if (width == 0) {
		if (screen_write_combine(ctx, &gc->data) == 0) {
			screen_write_initctx(ctx, &ttyctx);
			tty_write(tty_cmd_utf8character, &ttyctx);
		}
		return;
	}

	/* Initialise the redraw context. */
	screen_write_initctx(ctx, &ttyctx);

	/* If in insert mode, make space for the cells. */
	if (s->mode & MODE_INSERT) {
		if (s->cx <= sx - width) {
			screen_write_flush(ctx);
			xx = sx - s->cx - width;
			grid_view_insert_cells(s->grid, s->cx, s->cy, xx, 8);
		}
		insert = 1;
	} else
		insert = 0;
	skip = !insert;

	/* Check this will fit on the current line and wrap if not. */
	if ((s->mode & MODE_WRAP) && s->cx > sx - width) {
		screen_write_flush(ctx);
		screen_write_save_last(ctx, &ttyctx);
		screen_write_linefeed(ctx, 1);
		s->cx = 0;	/* carriage return */
		skip = 0;
		wrapped = 1;
	}

	/* Sanity check cursor position. */
	if (s->cx > sx - width || s->cy > sy - 1)
		return;

	/* Handle overwriting of UTF-8 characters. */
	gl = &s->grid->linedata[s->grid->hsize + s->cy];
	if (gl->flags & GRID_LINE_EXTENDED) {
		grid_view_get_cell(gd, s->cx, s->cy, &now_gc);
		if (screen_write_overwrite(ctx, &now_gc, width))
			skip = 0;
	}

	/*
	 * If the new character is UTF-8 wide, fill in padding cells. Have
	 * already ensured there is enough room.
	 */
	for (xx = s->cx + 1; xx < s->cx + width; xx++) {
		grid_view_set_cell(gd, xx, s->cy, &screen_write_pad_cell);
		skip = 0;
	}

	/* If no change, do not draw. */
	if (skip) {
		if (s->cx >= gl->cellsize)
			skip = grid_cells_equal(gc, &grid_default_cell);
		else {
			gce = &gl->celldata[s->cx];
			if (gce->flags & GRID_FLAG_EXTENDED)
				skip = 0;
			else if (gc->flags != gce->flags)
				skip = 0;
			else if (gc->attr != gce->data.attr)
				skip = 0;
			else if (gc->fg != gce->data.fg)
				skip = 0;
			else if (gc->bg != gce->data.bg)
				skip = 0;
			else if (gc->data.width != 1)
				skip = 0;
			else if (gce->data.data != gc->data.data[0])
				skip = 0;
		}
	}

	/* Update the selection the flag and set the cell. */
	selected = screen_check_selection(s, s->cx, s->cy);
	if (selected && ~gc->flags & GRID_FLAG_SELECTED) {
		skip = 0;
		memcpy(&tmp_gc, gc, sizeof tmp_gc);
		tmp_gc.flags |= GRID_FLAG_SELECTED;
		grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc);
	} else if (!selected && gc->flags & GRID_FLAG_SELECTED) {
		skip = 0;
		memcpy(&tmp_gc, gc, sizeof tmp_gc);
		tmp_gc.flags &= ~GRID_FLAG_SELECTED;
		grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc);
	} else if (!skip)
		grid_view_set_cell(gd, s->cx, s->cy, gc);

	/*
	 * Move the cursor. If not wrapping, stick at the last character and
	 * replace it.
	 */
	last = !(s->mode & MODE_WRAP);
	if (s->cx <= sx - last - width)
		s->cx += width;
	else
		s->cx = sx - last;

	/* Create space for character in insert mode. */
	if (insert) {
		ttyctx.num = width;
		tty_write(tty_cmd_insertcharacter, &ttyctx);
	}

	/* Write to the screen. */
	if (selected) {
		screen_write_flush(ctx);
		screen_select_cell(s, &tmp_gc, gc);
		ttyctx.cell = &tmp_gc;
		tty_write(tty_cmd_cell, &ttyctx);
		ctx->written++;
	} else if (!skip) {
		if (wrapped) {
			ttyctx.cell = gc;
			tty_write(tty_cmd_cell, &ttyctx);
			ctx->written++;
		} else {
			/*
			 * If wp is NULL, we are not updating the terminal and
			 * don't care about actually writing the cells
			 * (tty_write will just return). So don't even bother
			 * allocating the dirty array.
			 */
			if (ctx->wp != NULL && s->dirty == NULL) {
				log_debug("%s: allocating %u bits", __func__,
				    s->dirtysize);
				s->dirty = bit_alloc(s->dirtysize);
			}
			if (s->dirty != NULL) {
				bit_set(s->dirty, screen_dirty_bit(s,
				    ttyctx.ocx, ttyctx.ocy));
				ctx->dirty++;
			}
		}
	} else
		ctx->skipped++;
}
示例#4
0
文件: input.c 项目: akracun/tmux
/* Execute escape sequence. */
int
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:
		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;

		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_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;
		break;
	case INPUT_ESC_SCSOFF_G0:
		ictx->cell.attr |= GRID_ATTR_CHARSET;
		break;
	}

	return (0);
}
示例#5
0
/* Write cell data. */
void
screen_write_cell(struct screen_write_ctx *ctx,
    const struct grid_cell *gc, const struct utf8_data *utf8data)
{
	struct screen		*s = ctx->s;
	struct grid		*gd = s->grid;
	struct tty_ctx		 ttyctx;
	struct grid_utf8	 gu;
	u_int		 	 width, xx;
	struct grid_cell 	 tmp_gc, *tmp_gcp;
	int			 insert = 0;

	/* Ignore padding. */
	if (gc->flags & GRID_FLAG_PADDING)
		return;

	/* Find character width. */
	if (gc->flags & GRID_FLAG_UTF8)
		width = utf8data->width;
	else
		width = 1;

	/*
	 * If this is a wide character and there is no room on the screen, for
	 * the entire character, don't print it.
	 */
	if (!(s->mode & MODE_WRAP)
	    && (width > 1 && (width > screen_size_x(s) ||
		(s->cx != screen_size_x(s)
		 && s->cx > screen_size_x(s) - width))))
		return;

	/*
	 * If the width is zero, combine onto the previous character, if
	 * there is space.
	 */
	if (width == 0) {
		if (screen_write_combine(ctx, utf8data) == 0) {
			screen_write_initctx(ctx, &ttyctx, 0);
			tty_write(tty_cmd_utf8character, &ttyctx);
		}
		return;
	}

	/* Initialise the redraw context, saving the last cell. */
	screen_write_initctx(ctx, &ttyctx, 1);

	/* If in insert mode, make space for the cells. */
	if ((s->mode & MODE_INSERT) && s->cx <= screen_size_x(s) - width) {
		xx = screen_size_x(s) - s->cx - width;
		grid_move_cells(s->grid, s->cx + width, s->cx, s->cy, xx);
		insert = 1;
	}

	/* Check this will fit on the current line and wrap if not. */
	if ((s->mode & MODE_WRAP) && s->cx > screen_size_x(s) - width) {
		screen_write_linefeed(ctx, 1);
		s->cx = 0;	/* carriage return */
	}

	/* Sanity checks. */
	if (((s->mode & MODE_WRAP) && s->cx > screen_size_x(s) - width)
	    || s->cy > screen_size_y(s) - 1)
		return;

	/* Handle overwriting of UTF-8 characters. */
	screen_write_overwrite(ctx, width);

	/*
	 * If the new character is UTF-8 wide, fill in padding cells. Have
	 * already ensured there is enough room.
	 */
	for (xx = s->cx + 1; xx < s->cx + width; xx++) {
		tmp_gcp = grid_view_get_cell(gd, xx, s->cy);
		if (tmp_gcp != NULL)
			tmp_gcp->flags |= GRID_FLAG_PADDING;
	}

	/* Set the cell. */
	grid_view_set_cell(gd, s->cx, s->cy, gc);
	if (gc->flags & GRID_FLAG_UTF8) {
		/* Construct UTF-8 and write it. */
		grid_utf8_set(&gu, utf8data);
		grid_view_set_utf8(gd, s->cx, s->cy, &gu);
	}

	/* Move the cursor. */
	s->cx += width;

	/* Draw to the screen if necessary. */
	if (insert) {
		ttyctx.num = width;
		tty_write(tty_cmd_insertcharacter, &ttyctx);
	}
	ttyctx.utf8 = &gu;
	if (screen_check_selection(s, s->cx - width, s->cy)) {
		memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc);
		tmp_gc.data = gc->data;
		tmp_gc.flags = gc->flags &
		    ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
		tmp_gc.flags |= s->sel.cell.flags &
		    (GRID_FLAG_FG256|GRID_FLAG_BG256);
		ttyctx.cell = &tmp_gc;
		tty_write(tty_cmd_cell, &ttyctx);
	} else {
		ttyctx.cell = gc;
		tty_write(tty_cmd_cell, &ttyctx);
	}
}
示例#6
0
文件: screen-write.c 项目: 7heo/tmux
/* Write cell data. */
void
screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
{
	struct screen		*s = ctx->s;
	struct grid		*gd = s->grid;
	struct tty_ctx		 ttyctx;
	u_int		 	 width, xx, last;
	struct grid_cell 	 tmp_gc, now_gc;
	int			 insert, skip, selected;

	/* Ignore padding. */
	if (gc->flags & GRID_FLAG_PADDING)
		return;
	width = gc->data.width;

	/*
	 * If this is a wide character and there is no room on the screen, for
	 * the entire character, don't print it.
	 */
	if (!(s->mode & MODE_WRAP)
	    && (width > 1 && (width > screen_size_x(s) ||
		(s->cx != screen_size_x(s)
		 && s->cx > screen_size_x(s) - width))))
		return;

	/*
	 * If the width is zero, combine onto the previous character, if
	 * there is space.
	 */
	if (width == 0) {
		if (screen_write_combine(ctx, &gc->data) == 0) {
			screen_write_initctx(ctx, &ttyctx);
			tty_write(tty_cmd_utf8character, &ttyctx);
		}
		return;
	}

	/* Initialise the redraw context. */
	screen_write_initctx(ctx, &ttyctx);

	/* If in insert mode, make space for the cells. */
	if ((s->mode & MODE_INSERT) && s->cx <= screen_size_x(s) - width) {
		xx = screen_size_x(s) - s->cx - width;
		grid_move_cells(s->grid, s->cx + width, s->cx, s->cy, xx);
		insert = 1;
	} else
		insert = 0;
	skip = !insert;

	/* Check this will fit on the current line and wrap if not. */
	if ((s->mode & MODE_WRAP) && s->cx > screen_size_x(s) - width) {
		screen_write_linefeed(ctx, 1);
		s->cx = 0;	/* carriage return */
		skip = 0;
	}

	/* Sanity check cursor position. */
	if (s->cx > screen_size_x(s) - width || s->cy > screen_size_y(s) - 1)
		return;

	/* Handle overwriting of UTF-8 characters. */
	grid_view_get_cell(gd, s->cx, s->cy, &now_gc);
	if (screen_write_overwrite(ctx, &now_gc, width))
		skip = 0;

	/*
	 * If the new character is UTF-8 wide, fill in padding cells. Have
	 * already ensured there is enough room.
	 */
	for (xx = s->cx + 1; xx < s->cx + width; xx++) {
		grid_view_set_cell(gd, xx, s->cy, &screen_write_pad_cell);
		skip = 0;
	}

	/* If no change, do not draw. */
	if (skip)
		skip = (memcmp(&now_gc, gc, sizeof now_gc) == 0);

	/* Update the selection the flag and set the cell. */
	selected = screen_check_selection(s, s->cx, s->cy);
	if (selected && ~gc->flags & GRID_FLAG_SELECTED) {
		skip = 0;
		memcpy(&tmp_gc, gc, sizeof tmp_gc);
		tmp_gc.flags |= GRID_FLAG_SELECTED;
		grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc);
	} else if (!selected && gc->flags & GRID_FLAG_SELECTED) {
		skip = 0;
		memcpy(&tmp_gc, gc, sizeof tmp_gc);
		tmp_gc.flags &= ~GRID_FLAG_SELECTED;
		grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc);
	} else if (!skip)
		grid_view_set_cell(gd, s->cx, s->cy, gc);

	/*
	 * Move the cursor. If not wrapping, stick at the last character and
	 * replace it.
	 */
	last = !(s->mode & MODE_WRAP);
	if (s->cx <= screen_size_x(s) - last - width)
		s->cx += width;
	else
		s->cx = screen_size_x(s) - last;

	/* Create space for character in insert mode. */
	if (insert) {
		ttyctx.num = width;
		tty_write(tty_cmd_insertcharacter, &ttyctx);
	}

	/* Save last cell if it will be needed. */
	if (!skip && ctx->wp != NULL && ttyctx.ocx > ctx->wp->sx - width)
		screen_write_save_last(ctx, &ttyctx);

	/* Write to the screen. */
	if (selected) {
		memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc);
		utf8_copy(&tmp_gc.data, &gc->data);
		tmp_gc.attr = tmp_gc.attr & ~GRID_ATTR_CHARSET;
		tmp_gc.attr |= gc->attr & GRID_ATTR_CHARSET;
		tmp_gc.flags = gc->flags;
		tmp_gc.flags &= ~(GRID_FLAG_FGRGB|GRID_FLAG_BGRGB);
		tmp_gc.flags &= ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
		tmp_gc.flags |= s->sel.cell.flags &
		    (GRID_FLAG_FG256|GRID_FLAG_BG256);
		ttyctx.cell = &tmp_gc;
		tty_write(tty_cmd_cell, &ttyctx);
	} else if (!skip) {
		ttyctx.cell = gc;
		tty_write(tty_cmd_cell, &ttyctx);
	}
}
示例#7
0
文件: screen-write.c 项目: nbetm/tmux
/* Write cell data. */
void
screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
{
	struct screen		*s = ctx->s;
	struct grid		*gd = s->grid;
	struct tty_ctx		 ttyctx;
	u_int		 	 width, xx, last;
	struct grid_cell 	 tmp_gc;
	int			 insert;

	/* Ignore padding. */
	if (gc->flags & GRID_FLAG_PADDING)
		return;
	width = gc->data.width;

	/*
	 * If this is a wide character and there is no room on the screen, for
	 * the entire character, don't print it.
	 */
	if (!(s->mode & MODE_WRAP)
	    && (width > 1 && (width > screen_size_x(s) ||
		(s->cx != screen_size_x(s)
		 && s->cx > screen_size_x(s) - width))))
		return;

	/*
	 * If the width is zero, combine onto the previous character, if
	 * there is space.
	 */
	if (width == 0) {
		if (screen_write_combine(ctx, &gc->data) == 0) {
			screen_write_initctx(ctx, &ttyctx, 0);
			tty_write(tty_cmd_utf8character, &ttyctx);
		}
		return;
	}

	/* Initialise the redraw context, saving the last cell. */
	screen_write_initctx(ctx, &ttyctx, 1);

	/* If in insert mode, make space for the cells. */
	if ((s->mode & MODE_INSERT) && s->cx <= screen_size_x(s) - width) {
		xx = screen_size_x(s) - s->cx - width;
		grid_move_cells(s->grid, s->cx + width, s->cx, s->cy, xx);
		insert = 1;
	} else
		insert = 0;

	/* Check this will fit on the current line and wrap if not. */
	if ((s->mode & MODE_WRAP) && s->cx > screen_size_x(s) - width) {
		screen_write_linefeed(ctx, 1);
		s->cx = 0;	/* carriage return */
	}

	/* Sanity check cursor position. */
	if (s->cx > screen_size_x(s) - width || s->cy > screen_size_y(s) - 1)
		return;

	/* Handle overwriting of UTF-8 characters. */
	screen_write_overwrite(ctx, width);

	/*
	 * If the new character is UTF-8 wide, fill in padding cells. Have
	 * already ensured there is enough room.
	 */
	memcpy(&tmp_gc, &grid_default_cell, sizeof tmp_gc);
	tmp_gc.flags |= GRID_FLAG_PADDING;
	tmp_gc.data.width = 0;
	for (xx = s->cx + 1; xx < s->cx + width; xx++)
		grid_view_set_cell(gd, xx, s->cy, &tmp_gc);

	/* Set the cell. */
	grid_view_set_cell(gd, s->cx, s->cy, gc);

	/*
	 * Move the cursor. If not wrapping, stick at the last character and
	 * replace it.
	 */
	last = !(s->mode & MODE_WRAP);
	if (s->cx <= screen_size_x(s) - last - width)
		s->cx += width;
	else
		s->cx = screen_size_x(s) - last;

	/* Draw to the screen if necessary. */
	if (insert) {
		ttyctx.num = width;
		tty_write(tty_cmd_insertcharacter, &ttyctx);
	}
	if (screen_check_selection(s, s->cx - width, s->cy)) {
		memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc);
		utf8_copy(&tmp_gc.data, &gc->data);
		tmp_gc.attr = tmp_gc.attr & ~GRID_ATTR_CHARSET;
		tmp_gc.attr |= gc->attr & GRID_ATTR_CHARSET;
		tmp_gc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
		tmp_gc.flags |= s->sel.cell.flags &
		    (GRID_FLAG_FG256|GRID_FLAG_BG256);
		ttyctx.cell = &tmp_gc;
		tty_write(tty_cmd_cell, &ttyctx);
	} else {
		ttyctx.cell = gc;
		tty_write(tty_cmd_cell, &ttyctx);
	}
}
示例#8
0
文件: input.c 项目: rkowalick/tmux
/* Execute escape sequence. */
int
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);
}
示例#9
0
/* Execute C0 control sequence. */
int
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;
	u_int			 trigger;

	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);
		goto count_c0;
	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);
		goto count_c0;
	case '\015':	/* CR */
		screen_write_carriagereturn(sctx);
		goto count_c0;
	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);

count_c0:
	trigger = options_get_number(&wp->window->options, "c0-change-trigger");
	if (trigger != 0 && ++wp->changes >= trigger) {
		wp->flags |= PANE_DROP;
		window_pane_timer_start(wp);
	}

	return (0);
}