예제 #1
0
/* Copy from another screen. */
void
screen_write_copy(struct screen_write_ctx *ctx,
    struct screen *src, u_int px, u_int py, u_int nx, u_int ny)
{
	struct screen		*s = ctx->s;
	struct grid		*gd = src->grid;
	struct grid_line	*gl;
	const struct grid_cell	*gc;
	const struct grid_utf8	*gu;
	struct utf8_data	 utf8data;
	u_int		 	 xx, yy, cx, cy, ax, bx;

	cx = s->cx;
	cy = s->cy;
	for (yy = py; yy < py + ny; yy++) {
		gl = &gd->linedata[yy];
		if (yy < gd->hsize + gd->sy) {
			/*
			 * Find start and end position and copy between
			 * them. Limit to the real end of the line then use a
			 * clear EOL only if copying to the end, otherwise
			 * could overwrite whatever is there already.
			 */
			if (px > gl->cellsize)
				ax = gl->cellsize;
			else
				ax = px;
			if (px + nx == gd->sx && px + nx > gl->cellsize)
				bx = gl->cellsize;
			else
				bx = px + nx;

			for (xx = ax; xx < bx; xx++) {
				if (xx >= gl->cellsize)
					gc = &grid_default_cell;
				else
					gc = &gl->celldata[xx];
				if (!(gc->flags & GRID_FLAG_UTF8)) {
					screen_write_cell(ctx, gc, NULL);
					continue;
				}
				/* Reinject the UTF-8 sequence. */
				gu = &gl->utf8data[xx];
				utf8data.size = grid_utf8_copy(
				    gu, utf8data.data, sizeof utf8data.data);
				utf8data.width = gu->width;
				screen_write_cell(ctx, gc, &utf8data);
			}
			if (px + nx == gd->sx && px + nx > gl->cellsize)
				screen_write_clearendofline(ctx);
		} else
			screen_write_clearline(ctx);
		cy++;
		screen_write_cursormove(ctx, cx, cy);
	}
}
예제 #2
0
파일: window-copy.c 프로젝트: ddollar/tmux
void
window_copy_copy_line(struct window_pane *wp,
    char **buf, size_t *off, u_int sy, u_int sx, u_int ex)
{
	struct window_copy_mode_data	*data = wp->modedata;
	struct grid			*gd = data->backing->grid;
	const struct grid_cell		*gc;
	const struct grid_utf8		*gu;
	struct grid_line		*gl;
	u_int				 i, xx, wrapped = 0;
	size_t				 size;

	if (sx > ex)
		return;

	/*
	 * Work out if the line was wrapped at the screen edge and all of it is
	 * on screen.
	 */
	gl = &gd->linedata[sy];
	if (gl->flags & GRID_LINE_WRAPPED && gl->cellsize <= gd->sx)
		wrapped = 1;

	/* If the line was wrapped, don't strip spaces (use the full length). */
	if (wrapped)
		xx = gl->cellsize;
	else
		xx = window_copy_find_length(wp, sy);
	if (ex > xx)
		ex = xx;
	if (sx > xx)
		sx = xx;

	if (sx < ex) {
		for (i = sx; i < ex; i++) {
			gc = grid_peek_cell(gd, i, sy);
			if (gc->flags & GRID_FLAG_PADDING)
				continue;
			if (!(gc->flags & GRID_FLAG_UTF8)) {
				*buf = xrealloc(*buf, 1, (*off) + 1);
				(*buf)[(*off)++] = gc->data;
			} else {
				gu = grid_peek_utf8(gd, i, sy);
				size = grid_utf8_size(gu);
				*buf = xrealloc(*buf, 1, (*off) + size);
				*off += grid_utf8_copy(gu, *buf + *off, size);
			}
		}
	}

	/* Only add a newline if the line wasn't wrapped. */
	if (!wrapped || ex != xx) {
		*buf = xrealloc(*buf, 1, (*off) + 1);
		(*buf)[(*off)++] = '\n';
	}
}
예제 #3
0
/* Convert cells into a string. */
char *
grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
{
	const struct grid_cell	*gc;
	const struct grid_utf8	*gu;
	char			*buf;
	size_t			 len, off, size;
	u_int			 xx;

	GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);

	len = 128;
	buf = xmalloc(len);
	off = 0;

	for (xx = px; xx < px + nx; xx++) {
		gc = grid_peek_cell(gd, xx, py);
		if (gc->flags & GRID_FLAG_PADDING)
			continue;

		if (gc->flags & GRID_FLAG_UTF8) {
			gu = grid_peek_utf8(gd, xx, py);

			size = grid_utf8_size(gu);
			while (len < off + size + 1) {
				buf = xrealloc(buf, 2, len);
				len *= 2;
			}

			off += grid_utf8_copy(gu, buf + off, len - off);
		} else {
			while (len < off + 2) {
				buf = xrealloc(buf, 2, len);
				len *= 2;
			}

			buf[off++] = gc->data;
		}
	}

	while (off > 0 && buf[off - 1] == ' ')
		off--;
	buf[off] = '\0';
	return (buf);
}