Ejemplo n.º 1
0
/* Clear to end of screen from cursor. */
void
screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;
	u_int		 sx = screen_size_x(s), sy = screen_size_y(s);

	screen_write_initctx(ctx, &ttyctx);
	ttyctx.bg = bg;

	/* Scroll into history if it is enabled and clearing entire screen. */
	if (s->cx == 0 && s->cy == 0 && s->grid->flags & GRID_HISTORY) {
		screen_dirty_clear(s, 0, 0, sx - 1, sy  - 1);
		grid_view_clear_history(s->grid, bg);
	} else {
		if (s->cx <= sx - 1) {
			screen_dirty_clear(s, s->cx, s->cy, sx - 1, s->cy);
			grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1,
			    bg);
		}
		screen_dirty_clear(s, 0, s->cy + 1, sx - 1, sy - 1);
		grid_view_clear(s->grid, 0, s->cy + 1, sx, sy - (s->cy + 1),
		    bg);
	}

	tty_write(tty_cmd_clearendofscreen, &ttyctx);
}
Ejemplo n.º 2
0
/* Line feed. */
void
screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
{
	struct screen		*s = ctx->s;
	struct grid_line	*gl;
	struct tty_ctx	 	 ttyctx;
	u_int			 sx = screen_size_x(s), sy = screen_size_y(s);

	screen_write_initctx(ctx, &ttyctx);

	gl = &s->grid->linedata[s->grid->hsize + s->cy];
	if (wrapped)
		gl->flags |= GRID_LINE_WRAPPED;
	else
		gl->flags &= ~GRID_LINE_WRAPPED;

	if (s->cy == s->rlower) {
		screen_dirty_clear(s, 0, s->rupper, sx - 1, s->rupper);
		screen_write_flush(ctx);
		grid_view_scroll_region_up(s->grid, s->rupper, s->rlower);
	} else if (s->cy < sy - 1)
		s->cy++;

	ttyctx.num = wrapped;
	tty_write(tty_cmd_linefeed, &ttyctx);
}
Ejemplo n.º 3
0
/* VT100 alignment test. */
void
screen_write_alignmenttest(struct screen_write_ctx *ctx)
{
	struct screen		*s = ctx->s;
	struct tty_ctx	 	 ttyctx;
	struct grid_cell       	 gc;
	u_int			 xx, yy;
	u_int		 	 sx = screen_size_x(s), sy = screen_size_y(s);

	screen_write_initctx(ctx, &ttyctx);

	screen_dirty_clear(s, 0, 0, sx - 1, sy  - 1);

	memcpy(&gc, &grid_default_cell, sizeof gc);
	utf8_set(&gc.data, 'E');

	for (yy = 0; yy < screen_size_y(s); yy++) {
		for (xx = 0; xx < screen_size_x(s); xx++)
			grid_view_set_cell(s->grid, xx, yy, &gc);
	}

	s->cx = 0;
	s->cy = 0;

	s->rupper = 0;
	s->rlower = screen_size_y(s) - 1;

	tty_write(tty_cmd_alignmenttest, &ttyctx);
}
Ejemplo n.º 4
0
/* VT100 alignment test. */
void
screen_write_alignmenttest(struct screen_write_ctx *ctx)
{
	struct screen		*s = ctx->s;
	struct tty_ctx	 	 ttyctx;
	struct grid_cell       	 gc;
	u_int			 xx, yy;

	screen_write_initctx(ctx, &ttyctx, 0);

	memcpy(&gc, &grid_default_cell, sizeof gc);
	grid_cell_one(&gc, 'E');

	for (yy = 0; yy < screen_size_y(s); yy++) {
		for (xx = 0; xx < screen_size_x(s); xx++)
			grid_view_set_cell(s->grid, xx, yy, &gc);
	}

	s->cx = 0;
	s->cy = 0;

	s->rupper = 0;

	s->rlower = screen_size_y(s) - 1;

	tty_write(tty_cmd_alignmenttest, &ttyctx);
}
Ejemplo n.º 5
0
/* Clear nx characters. */
void
screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;

	if (nx == 0)
		nx = 1;

	if (nx > screen_size_x(s) - s->cx)
		nx = screen_size_x(s) - s->cx;
	if (nx == 0)
		return;

	screen_write_initctx(ctx, &ttyctx);

	if (s->cx <= screen_size_x(s) - 1) {
		screen_dirty_clear(s, s->cx, s->cy, s->cx + nx - 1, s->cy);
		grid_view_clear(s->grid, s->cx, s->cy, nx, 1, 8);
	} else
		return;

	ttyctx.num = nx;
	tty_write(tty_cmd_clearcharacter, &ttyctx);
}
Ejemplo n.º 6
0
/* Delete ny lines. */
void
screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;

	if (ny == 0)
		ny = 1;

	if (s->cy < s->rupper || s->cy > s->rlower) {
		if (ny > screen_size_y(s) - s->cy)
			ny = screen_size_y(s) - s->cy;
		if (ny == 0)
			return;

		screen_write_flush(ctx);
		screen_write_initctx(ctx, &ttyctx);

		grid_view_delete_lines(s->grid, s->cy, ny, bg);

		ttyctx.num = ny;
		ttyctx.bg = bg;
		tty_write(tty_cmd_deleteline, &ttyctx);
		return;
	}

	if (ny > s->rlower + 1 - s->cy)
		ny = s->rlower + 1 - s->cy;
	if (ny == 0)
		return;

	screen_write_flush(ctx);
	screen_write_initctx(ctx, &ttyctx);

	if (s->cy < s->rupper || s->cy > s->rlower)
		grid_view_delete_lines(s->grid, s->cy, ny, bg);
	else {
		grid_view_delete_lines_region(s->grid, s->rlower, s->cy, ny,
		    bg);
	}

	ttyctx.num = ny;
	ttyctx.bg = bg;
	tty_write(tty_cmd_deleteline, &ttyctx);
}
Ejemplo n.º 7
0
void
screen_write_sixel(struct screen_write_ctx *ctx, u_char *str, u_int len)
{
	struct tty_ctx		 ttyctx;

	screen_write_initctx(ctx, &ttyctx, 0);
	ttyctx.ptr = str;
	ttyctx.num = len;

	tty_write(tty_cmd_write_sixel, &ttyctx);
}
Ejemplo n.º 8
0
void
screen_write_setselection(struct screen_write_ctx *ctx, u_char *str, u_int len)
{
	struct tty_ctx	ttyctx;

	screen_write_initctx(ctx, &ttyctx);
	ttyctx.ptr = str;
	ttyctx.num = len;

	tty_write(tty_cmd_setselection, &ttyctx);
}
Ejemplo n.º 9
0
void
screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len)
{
	struct tty_ctx	ttyctx;

	screen_write_initctx(ctx, &ttyctx);
	ttyctx.ptr = str;
	ttyctx.num = len;

	tty_write(tty_cmd_rawstring, &ttyctx);
}
Ejemplo n.º 10
0
/* Clear line at cursor. */
void
screen_write_clearline(struct screen_write_ctx *ctx)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;

	screen_write_initctx(ctx, &ttyctx, 0);

	grid_view_clear(s->grid, 0, s->cy, screen_size_x(s), 1);

	tty_write(tty_cmd_clearline, &ttyctx);
}
Ejemplo n.º 11
0
/* Insert ny lines. */
void
screen_write_insertline(struct screen_write_ctx *ctx, u_int ny)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;

	if (ny == 0)
		ny = 1;

	if (s->cy < s->rupper || s->cy > s->rlower) {
		if (ny > screen_size_y(s) - s->cy)
			ny = screen_size_y(s) - s->cy;
		if (ny == 0)
			return;

		screen_write_initctx(ctx, &ttyctx, 0);

		grid_view_insert_lines(s->grid, s->cy, ny);

		ttyctx.num = ny;
		tty_write(tty_cmd_insertline, &ttyctx);
		return;
	}

	if (ny > s->rlower + 1 - s->cy)
		ny = s->rlower + 1 - s->cy;
	if (ny == 0)
		return;

	screen_write_initctx(ctx, &ttyctx, 0);

	if (s->cy < s->rupper || s->cy > s->rlower)
		grid_view_insert_lines(s->grid, s->cy, ny);
	else
		grid_view_insert_lines_region(s->grid, s->rlower, s->cy, ny);

	ttyctx.num = ny;
	tty_write(tty_cmd_insertline, &ttyctx);
}
Ejemplo n.º 12
0
/* Reverse index (up with scroll).  */
void
screen_write_reverseindex(struct screen_write_ctx *ctx)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;

	screen_write_initctx(ctx, &ttyctx, 0);

	if (s->cy == s->rupper)
		grid_view_scroll_region_down(s->grid, s->rupper, s->rlower);
	else if (s->cy > 0)
		s->cy--;

	tty_write(tty_cmd_reverseindex, &ttyctx);
}
Ejemplo n.º 13
0
/* Clear to end of line from cursor. */
void
screen_write_clearendofline(struct screen_write_ctx *ctx)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;
	u_int		 sx;

	screen_write_initctx(ctx, &ttyctx, 0);

	sx = screen_size_x(s);

	if (s->cx <= sx - 1)
		grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1);

	tty_write(tty_cmd_clearendofline, &ttyctx);
}
Ejemplo n.º 14
0
/* Clear to start of line from cursor. */
void
screen_write_clearstartofline(struct screen_write_ctx *ctx)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;
	u_int		 sx;

	screen_write_initctx(ctx, &ttyctx);

	sx = screen_size_x(s);

	if (s->cx > sx - 1)
		grid_view_clear(s->grid, 0, s->cy, sx, 1);
	else
		grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1);

	tty_write(tty_cmd_clearstartofline, &ttyctx);
}
Ejemplo n.º 15
0
/* Clear entire screen. */
void
screen_write_clearscreen(struct screen_write_ctx *ctx)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;

	screen_write_initctx(ctx, &ttyctx, 0);

	/* Scroll into history if it is enabled. */
	if (s->grid->flags & GRID_HISTORY)
		grid_view_clear_history(s->grid);
	else {
		grid_view_clear(
		    s->grid, 0, 0, screen_size_x(s), screen_size_y(s));
	}

	tty_write(tty_cmd_clearscreen, &ttyctx);
}
Ejemplo n.º 16
0
/* Clear to end of line from cursor. */
void
screen_write_clearendofline(struct screen_write_ctx *ctx)
{
	struct screen		*s = ctx->s;
	struct grid_line	*gl;
	struct tty_ctx		 ttyctx;
	u_int			 sx = screen_size_x(s);

	screen_write_initctx(ctx, &ttyctx);

	gl = &s->grid->linedata[s->grid->hsize + s->cy];
	if (s->cx <= sx - 1 && s->cx < gl->cellsize) {
		screen_dirty_clear(s, s->cx, s->cy, sx - 1, s->cy);
		grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1);
	} else
		return;

	tty_write(tty_cmd_clearendofline, &ttyctx);
}
Ejemplo n.º 17
0
/* Clear entire screen. */
void
screen_write_clearscreen(struct screen_write_ctx *ctx)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;
	u_int		 sx = screen_size_x(s), sy = screen_size_y(s);

	screen_write_initctx(ctx, &ttyctx);

	screen_dirty_clear(s, 0, 0, sx - 1, sy  - 1);

	/* Scroll into history if it is enabled. */
	if (s->grid->flags & GRID_HISTORY)
		grid_view_clear_history(s->grid);
	else
		grid_view_clear(s->grid, 0, 0, sx, sy);

	tty_write(tty_cmd_clearscreen, &ttyctx);
}
Ejemplo n.º 18
0
/* Flush outstanding cell writes. */
static void
screen_write_flush(struct screen_write_ctx *ctx)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;
	u_int		 x, y, offset, cx, cy, dirty;
	struct grid_cell gc;

	if (ctx->dirty == 0)
		return;
	dirty = 0;
	log_debug("%s: dirty %u", __func__, ctx->dirty);

	cx = s->cx;
	cy = s->cy;

	offset = 0;
	for (y = 0; y < screen_size_y(s); y++) {
		for (x = 0; x < screen_size_x(s); x++) {
			offset++;
			if (!bit_test(s->dirty, offset - 1))
				continue;
			bit_clear(s->dirty, offset - 1);

			screen_write_cursormove(ctx, x, y);
			grid_view_get_cell(s->grid, x, y, &gc);

			screen_write_initctx(ctx, &ttyctx);
			ttyctx.cell = &gc;
			tty_write(tty_cmd_cell, &ttyctx);
			ctx->written++;

			if (++dirty == ctx->dirty)
				break;
		}
		if (dirty == ctx->dirty)
			break;
	}
	ctx->dirty = 0;

	s->cx = cx;
	s->cy = cy;
}
Ejemplo n.º 19
0
/* Clear to end of line from cursor. */
void
screen_write_clearendofline(struct screen_write_ctx *ctx, u_int bg)
{
	struct screen		*s = ctx->s;
	struct grid_line	*gl;
	struct tty_ctx		 ttyctx;
	u_int			 sx = screen_size_x(s);

	screen_write_initctx(ctx, &ttyctx);
	ttyctx.bg = bg;

	gl = &s->grid->linedata[s->grid->hsize + s->cy];
	if (s->cx > sx - 1 || (s->cx >= gl->cellsize && bg == 8))
		return;

	screen_dirty_clear(s, s->cx, s->cy, sx - 1, s->cy);
	grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1, bg);

	tty_write(tty_cmd_clearendofline, &ttyctx);
}
Ejemplo n.º 20
0
/* Clear to start of line from cursor. */
void
screen_write_clearstartofline(struct screen_write_ctx *ctx, u_int bg)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;
	u_int		 sx = screen_size_x(s);

	screen_write_initctx(ctx, &ttyctx);
	ttyctx.bg = bg;

	if (s->cx > sx - 1) {
		screen_dirty_clear(s, 0, s->cy, sx - 1, s->cy);
		grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
	} else {
		screen_dirty_clear(s, 0, s->cy, s->cx, s->cy);
		grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, bg);
	}

	tty_write(tty_cmd_clearstartofline, &ttyctx);
}
Ejemplo n.º 21
0
/* Delete nx characters. */
void
screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;

	if (nx == 0)
		nx = 1;

	if (nx > screen_size_x(s) - s->cx)
		nx = screen_size_x(s) - s->cx;
	if (nx == 0)
		return;

	screen_write_initctx(ctx, &ttyctx, 0);

	if (s->cx <= screen_size_x(s) - 1)
		grid_view_delete_cells(s->grid, s->cx, s->cy, nx);

	ttyctx.num = nx;
	tty_write(tty_cmd_deletecharacter, &ttyctx);
}
Ejemplo n.º 22
0
/* Clear to start of screen. */
void
screen_write_clearstartofscreen(struct screen_write_ctx *ctx)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;
	u_int		 sx = screen_size_x(s);

	screen_write_initctx(ctx, &ttyctx);

	if (s->cy > 0) {
		screen_dirty_clear(s, 0, 0, sx - 1, s->cy);
		grid_view_clear(s->grid, 0, 0, sx, s->cy, 8);
	}
	if (s->cx > sx - 1) {
		screen_dirty_clear(s, 0, s->cy, sx - 1, s->cy);
		grid_view_clear(s->grid, 0, s->cy, sx, 1, 8);
	} else {
		screen_dirty_clear(s, 0, s->cy, s->cx, s->cy);
		grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, 8);
	}

	tty_write(tty_cmd_clearstartofscreen, &ttyctx);
}
Ejemplo n.º 23
0
/* Clear to end of screen from cursor. */
void
screen_write_clearendofscreen(struct screen_write_ctx *ctx)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;
	u_int		 sx, sy;

	screen_write_initctx(ctx, &ttyctx, 0);

	sx = screen_size_x(s);
	sy = screen_size_y(s);

	/* Scroll into history if it is enabled and clearing entire screen. */
	if (s->cy == 0 && s->grid->flags & GRID_HISTORY)
		grid_view_clear_history(s->grid);
	else {
		if (s->cx <= sx - 1)
			grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1);
		grid_view_clear(s->grid, 0, s->cy + 1, sx, sy - (s->cy + 1));
	}

	tty_write(tty_cmd_clearendofscreen, &ttyctx);
}
Ejemplo n.º 24
0
/* Insert nx characters. */
void
screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
{
	struct screen	*s = ctx->s;
	struct tty_ctx	 ttyctx;

	if (nx == 0)
		nx = 1;

	if (nx > screen_size_x(s) - s->cx)
		nx = screen_size_x(s) - s->cx;
	if (nx == 0)
		return;

	screen_write_flush(ctx);
	screen_write_initctx(ctx, &ttyctx);

	if (s->cx <= screen_size_x(s) - 1)
		grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg);

	ttyctx.num = nx;
	ttyctx.bg = bg;
	tty_write(tty_cmd_insertcharacter, &ttyctx);
}
Ejemplo n.º 25
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;
	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);
	}
}
Ejemplo n.º 26
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);
	}
}
Ejemplo n.º 27
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;
	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);
	}
}
Ejemplo n.º 28
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++;
}