mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
Conflicts: Makefile
This commit is contained in:
		@@ -136,7 +136,6 @@ dist_tmux_SOURCES = \
 | 
			
		||||
	control-notify.c \
 | 
			
		||||
	environ.c \
 | 
			
		||||
	format.c \
 | 
			
		||||
	grid-cell.c \
 | 
			
		||||
	grid-view.c \
 | 
			
		||||
	grid.c \
 | 
			
		||||
	input-keys.c \
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								format.c
									
									
									
									
									
								
							@@ -432,6 +432,7 @@ format_cb_history_bytes(struct format_tree *ft, struct format_entry *fe)
 | 
			
		||||
	for (i = 0; i < gd->hsize; i++) {
 | 
			
		||||
		gl = &gd->linedata[i];
 | 
			
		||||
		size += gl->cellsize * sizeof *gl->celldata;
 | 
			
		||||
		size += gl->extdsize * sizeof *gl->extddata;
 | 
			
		||||
	}
 | 
			
		||||
	size += gd->hsize * sizeof *gd->linedata;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										55
									
								
								grid-cell.c
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								grid-cell.c
									
									
									
									
									
								
							@@ -1,55 +0,0 @@
 | 
			
		||||
/* $OpenBSD$ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
			
		||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 * copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
/* Get cell width. */
 | 
			
		||||
u_int
 | 
			
		||||
grid_cell_width(const struct grid_cell *gc)
 | 
			
		||||
{
 | 
			
		||||
	return (gc->xstate >> 4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get cell data. */
 | 
			
		||||
void
 | 
			
		||||
grid_cell_get(const struct grid_cell *gc, struct utf8_data *ud)
 | 
			
		||||
{
 | 
			
		||||
	ud->size = gc->xstate & 0xf;
 | 
			
		||||
	ud->width = gc->xstate >> 4;
 | 
			
		||||
	memcpy(ud->data, gc->xdata, ud->size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set cell data. */
 | 
			
		||||
void
 | 
			
		||||
grid_cell_set(struct grid_cell *gc, const struct utf8_data *ud)
 | 
			
		||||
{
 | 
			
		||||
	memcpy(gc->xdata, ud->data, ud->size);
 | 
			
		||||
	gc->xstate = (ud->width << 4) | ud->size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set a single character as cell data. */
 | 
			
		||||
void
 | 
			
		||||
grid_cell_one(struct grid_cell *gc, u_char ch)
 | 
			
		||||
{
 | 
			
		||||
	*gc->xdata = ch;
 | 
			
		||||
	gc->xstate = (1 << 4) | 1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								grid-view.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								grid-view.c
									
									
									
									
									
								
							@@ -30,24 +30,17 @@
 | 
			
		||||
#define grid_view_x(gd, x) (x)
 | 
			
		||||
#define grid_view_y(gd, y) ((gd)->hsize + (y))
 | 
			
		||||
 | 
			
		||||
/* Get cell for reading. */
 | 
			
		||||
const struct grid_cell *
 | 
			
		||||
grid_view_peek_cell(struct grid *gd, u_int px, u_int py)
 | 
			
		||||
/* Get cel. */
 | 
			
		||||
void
 | 
			
		||||
grid_view_get_cell(struct grid *gd, u_int px, u_int py, struct grid_cell *gc)
 | 
			
		||||
{
 | 
			
		||||
	return (grid_peek_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get cell for writing. */
 | 
			
		||||
struct grid_cell *
 | 
			
		||||
grid_view_get_cell(struct grid *gd, u_int px, u_int py)
 | 
			
		||||
{
 | 
			
		||||
	return (grid_get_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
 | 
			
		||||
	grid_get_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set cell. */
 | 
			
		||||
void
 | 
			
		||||
grid_view_set_cell(
 | 
			
		||||
    struct grid *gd, u_int px, u_int py, const struct grid_cell *gc)
 | 
			
		||||
grid_view_set_cell(struct grid *gd, u_int px, u_int py,
 | 
			
		||||
    const struct grid_cell *gc)
 | 
			
		||||
{
 | 
			
		||||
	grid_set_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										169
									
								
								grid.c
									
									
									
									
									
								
							
							
						
						
									
										169
									
								
								grid.c
									
									
									
									
									
								
							@@ -36,15 +36,17 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Default grid cell data. */
 | 
			
		||||
const struct grid_cell grid_default_cell = { 0, 0, 8, 8, (1 << 4) | 1, " " };
 | 
			
		||||
 | 
			
		||||
#define grid_put_cell(gd, px, py, gc) do {			\
 | 
			
		||||
	memcpy(&gd->linedata[py].celldata[px], 			\
 | 
			
		||||
	    gc, sizeof gd->linedata[py].celldata[px]);		\
 | 
			
		||||
} while (0)
 | 
			
		||||
const struct grid_cell grid_default_cell = {
 | 
			
		||||
	0, 0, 8, 8, { { ' ' }, 0, 1, 1 }
 | 
			
		||||
};
 | 
			
		||||
const struct grid_cell_entry grid_default_entry = {
 | 
			
		||||
	0, { .data = { 0, 8, 8, ' ' } }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int	grid_check_y(struct grid *, u_int);
 | 
			
		||||
 | 
			
		||||
void	grid_reflow_copy(struct grid_line *, u_int, struct grid_line *l,
 | 
			
		||||
	    u_int, u_int);
 | 
			
		||||
void	grid_reflow_join(struct grid *, u_int *, struct grid_line *, u_int);
 | 
			
		||||
void	grid_reflow_split(struct grid *, u_int *, struct grid_line *, u_int,
 | 
			
		||||
	    u_int);
 | 
			
		||||
@@ -54,6 +56,13 @@ size_t	grid_string_cells_bg(const struct grid_cell *, int *);
 | 
			
		||||
void	grid_string_cells_code(const struct grid_cell *,
 | 
			
		||||
	    const struct grid_cell *, char *, size_t, int);
 | 
			
		||||
 | 
			
		||||
/* Copy default into a cell. */
 | 
			
		||||
static void
 | 
			
		||||
grid_clear_cell(struct grid *gd, u_int px, u_int py)
 | 
			
		||||
{
 | 
			
		||||
	gd->linedata[py].celldata[px] = grid_default_entry;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Check grid y position. */
 | 
			
		||||
int
 | 
			
		||||
grid_check_y(struct grid *gd, u_int py)
 | 
			
		||||
@@ -95,6 +104,7 @@ grid_destroy(struct grid *gd)
 | 
			
		||||
	for (yy = 0; yy < gd->hsize + gd->sy; yy++) {
 | 
			
		||||
		gl = &gd->linedata[yy];
 | 
			
		||||
		free(gl->celldata);
 | 
			
		||||
		free(gl->extddata);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	free(gd->linedata);
 | 
			
		||||
@@ -107,7 +117,7 @@ int
 | 
			
		||||
grid_compare(struct grid *ga, struct grid *gb)
 | 
			
		||||
{
 | 
			
		||||
	struct grid_line	*gla, *glb;
 | 
			
		||||
	struct grid_cell	*gca, *gcb;
 | 
			
		||||
	struct grid_cell	 gca, gcb;
 | 
			
		||||
	u_int			 xx, yy;
 | 
			
		||||
 | 
			
		||||
	if (ga->sx != gb->sx || ga->sy != gb->sy)
 | 
			
		||||
@@ -118,10 +128,10 @@ grid_compare(struct grid *ga, struct grid *gb)
 | 
			
		||||
		glb = &gb->linedata[yy];
 | 
			
		||||
		if (gla->cellsize != glb->cellsize)
 | 
			
		||||
			return (1);
 | 
			
		||||
		for (xx = 0; xx < ga->sx; xx++) {
 | 
			
		||||
			gca = &gla->celldata[xx];
 | 
			
		||||
			gcb = &glb->celldata[xx];
 | 
			
		||||
			if (memcmp(gca, gcb, sizeof (struct grid_cell)) != 0)
 | 
			
		||||
		for (xx = 0; xx < gla->cellsize; xx++) {
 | 
			
		||||
			grid_get_cell(ga, xx, yy, &gca);
 | 
			
		||||
			grid_get_cell(gb, xx, yy, &gcb);
 | 
			
		||||
			if (memcmp(&gca, &gcb, sizeof (struct grid_cell)) != 0)
 | 
			
		||||
				return (1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -224,7 +234,7 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx)
 | 
			
		||||
 | 
			
		||||
	gl->celldata = xreallocarray(gl->celldata, sx, sizeof *gl->celldata);
 | 
			
		||||
	for (xx = gl->cellsize; xx < sx; xx++)
 | 
			
		||||
		grid_put_cell(gd, xx, py, &grid_default_cell);
 | 
			
		||||
		grid_clear_cell(gd, xx, py);
 | 
			
		||||
	gl->cellsize = sx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -238,37 +248,72 @@ grid_peek_line(struct grid *gd, u_int py)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get cell for reading. */
 | 
			
		||||
const struct grid_cell *
 | 
			
		||||
grid_peek_cell(struct grid *gd, u_int px, u_int py)
 | 
			
		||||
void
 | 
			
		||||
grid_get_cell(struct grid *gd, u_int px, u_int py, struct grid_cell *gc)
 | 
			
		||||
{
 | 
			
		||||
	if (grid_check_y(gd, py) != 0)
 | 
			
		||||
		return (&grid_default_cell);
 | 
			
		||||
	struct grid_line	*gl;
 | 
			
		||||
	struct grid_cell_entry	*gce;
 | 
			
		||||
 | 
			
		||||
	if (px >= gd->linedata[py].cellsize)
 | 
			
		||||
		return (&grid_default_cell);
 | 
			
		||||
	return (&gd->linedata[py].celldata[px]);
 | 
			
		||||
}
 | 
			
		||||
	if (grid_check_y(gd, py) != 0 || px >= gd->linedata[py].cellsize) {
 | 
			
		||||
		memcpy(gc, &grid_default_cell, sizeof *gc);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/* Get cell at relative position (for writing). */
 | 
			
		||||
struct grid_cell *
 | 
			
		||||
grid_get_cell(struct grid *gd, u_int px, u_int py)
 | 
			
		||||
{
 | 
			
		||||
	if (grid_check_y(gd, py) != 0)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	gl = &gd->linedata[py];
 | 
			
		||||
	gce = &gl->celldata[px];
 | 
			
		||||
 | 
			
		||||
	grid_expand_line(gd, py, px + 1);
 | 
			
		||||
	return (&gd->linedata[py].celldata[px]);
 | 
			
		||||
	if (gce->flags & GRID_FLAG_EXTENDED) {
 | 
			
		||||
		if (gce->offset >= gl->extdsize)
 | 
			
		||||
			memcpy(gc, &grid_default_cell, sizeof *gc);
 | 
			
		||||
		else
 | 
			
		||||
			memcpy(gc, &gl->extddata[gce->offset], sizeof *gc);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gc->flags = gce->flags & ~GRID_FLAG_EXTENDED;
 | 
			
		||||
	gc->attr = gce->data.attr;
 | 
			
		||||
	gc->fg = gce->data.fg;
 | 
			
		||||
	gc->bg = gce->data.bg;
 | 
			
		||||
	utf8_set(&gc->data, gce->data.data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set cell at relative position. */
 | 
			
		||||
void
 | 
			
		||||
grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc)
 | 
			
		||||
{
 | 
			
		||||
	struct grid_line	*gl;
 | 
			
		||||
	struct grid_cell_entry	*gce;
 | 
			
		||||
	struct grid_cell 	*gcp;
 | 
			
		||||
 | 
			
		||||
	if (grid_check_y(gd, py) != 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	grid_expand_line(gd, py, px + 1);
 | 
			
		||||
	grid_put_cell(gd, px, py, gc);
 | 
			
		||||
 | 
			
		||||
	gl = &gd->linedata[py];
 | 
			
		||||
	gce = &gl->celldata[px];
 | 
			
		||||
 | 
			
		||||
	if ((gce->flags & GRID_FLAG_EXTENDED) || gc->data.size != 1 ||
 | 
			
		||||
	    gc->data.width != 1) {
 | 
			
		||||
		if (~gce->flags & GRID_FLAG_EXTENDED) {
 | 
			
		||||
			gl->extddata = xreallocarray(gl->extddata,
 | 
			
		||||
			    gl->extdsize + 1, sizeof *gl->extddata);
 | 
			
		||||
			gce->offset = gl->extdsize++;
 | 
			
		||||
			gce->flags = gc->flags | GRID_FLAG_EXTENDED;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (gce->offset >= gl->extdsize)
 | 
			
		||||
			fatalx("offset too big");
 | 
			
		||||
		gcp = &gl->extddata[gce->offset];
 | 
			
		||||
		memcpy(gcp, gc, sizeof *gcp);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gce->flags = gc->flags & ~GRID_FLAG_EXTENDED;
 | 
			
		||||
	gce->data.attr = gc->attr;
 | 
			
		||||
	gce->data.fg = gc->fg;
 | 
			
		||||
	gce->data.bg = gc->bg;
 | 
			
		||||
	gce->data.data = gc->data.data[0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Clear area. */
 | 
			
		||||
@@ -300,7 +345,7 @@ grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny)
 | 
			
		||||
		for (xx = px; xx < px + nx; xx++) {
 | 
			
		||||
			if (xx >= gd->linedata[yy].cellsize)
 | 
			
		||||
				break;
 | 
			
		||||
			grid_put_cell(gd, xx, yy, &grid_default_cell);
 | 
			
		||||
			grid_clear_cell(gd, xx, yy);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -324,6 +369,10 @@ grid_clear_lines(struct grid *gd, u_int py, u_int ny)
 | 
			
		||||
		gl = &gd->linedata[yy];
 | 
			
		||||
		free(gl->celldata);
 | 
			
		||||
		memset(gl, 0, sizeof *gl);
 | 
			
		||||
 | 
			
		||||
		free(gl->extddata);
 | 
			
		||||
		gl->extddata = NULL;
 | 
			
		||||
		gl->extdsize = 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -386,7 +435,7 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
 | 
			
		||||
	for (xx = px; xx < px + nx; xx++) {
 | 
			
		||||
		if (xx >= dx && xx < dx + nx)
 | 
			
		||||
			continue;
 | 
			
		||||
		grid_put_cell(gd, xx, py, &grid_default_cell);
 | 
			
		||||
		grid_clear_cell(gd, xx, py);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -568,9 +617,8 @@ char *
 | 
			
		||||
grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
 | 
			
		||||
    struct grid_cell **lastgc, int with_codes, int escape_c0, int trim)
 | 
			
		||||
{
 | 
			
		||||
	const struct grid_cell	*gc;
 | 
			
		||||
	struct grid_cell	 gc;
 | 
			
		||||
	static struct grid_cell	 lastgc1;
 | 
			
		||||
	struct utf8_data	 ud;
 | 
			
		||||
	const char		*data;
 | 
			
		||||
	char			*buf, code[128];
 | 
			
		||||
	size_t			 len, off, size, codelen;
 | 
			
		||||
@@ -590,21 +638,20 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
 | 
			
		||||
	for (xx = px; xx < px + nx; xx++) {
 | 
			
		||||
		if (gl == NULL || xx >= gl->cellsize)
 | 
			
		||||
			break;
 | 
			
		||||
		gc = &gl->celldata[xx];
 | 
			
		||||
		if (gc->flags & GRID_FLAG_PADDING)
 | 
			
		||||
		grid_get_cell(gd, xx, py, &gc);
 | 
			
		||||
		if (gc.flags & GRID_FLAG_PADDING)
 | 
			
		||||
			continue;
 | 
			
		||||
		grid_cell_get(gc, &ud);
 | 
			
		||||
 | 
			
		||||
		if (with_codes) {
 | 
			
		||||
			grid_string_cells_code(*lastgc, gc, code, sizeof code,
 | 
			
		||||
			grid_string_cells_code(*lastgc, &gc, code, sizeof code,
 | 
			
		||||
			    escape_c0);
 | 
			
		||||
			codelen = strlen(code);
 | 
			
		||||
			memcpy(*lastgc, gc, sizeof *gc);
 | 
			
		||||
			memcpy(*lastgc, &gc, sizeof **lastgc);
 | 
			
		||||
		} else
 | 
			
		||||
			codelen = 0;
 | 
			
		||||
 | 
			
		||||
		data = ud.data;
 | 
			
		||||
		size = ud.size;
 | 
			
		||||
		data = gc.data.data;
 | 
			
		||||
		size = gc.data.size;
 | 
			
		||||
		if (escape_c0 && size == 1 && *data == '\\') {
 | 
			
		||||
			data = "\\\\";
 | 
			
		||||
			size = 2;
 | 
			
		||||
@@ -663,11 +710,44 @@ grid_duplicate_lines(struct grid *dst, u_int dy, struct grid *src, u_int sy,
 | 
			
		||||
		} else
 | 
			
		||||
			dstl->celldata = NULL;
 | 
			
		||||
 | 
			
		||||
		if (srcl->extdsize != 0) {
 | 
			
		||||
			dstl->extdsize = srcl->extdsize;
 | 
			
		||||
			dstl->extddata = xreallocarray(NULL, dstl->extdsize,
 | 
			
		||||
			    sizeof *dstl->extddata);
 | 
			
		||||
			memcpy(dstl->extddata, srcl->extddata, dstl->extdsize *
 | 
			
		||||
			    sizeof *dstl->extddata);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sy++;
 | 
			
		||||
		dy++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Copy a section of a line. */
 | 
			
		||||
void
 | 
			
		||||
grid_reflow_copy(struct grid_line *dst_gl, u_int to, struct grid_line *src_gl,
 | 
			
		||||
    u_int from, u_int to_copy)
 | 
			
		||||
{
 | 
			
		||||
	struct grid_cell_entry	*gce;
 | 
			
		||||
	u_int			 i, was;
 | 
			
		||||
 | 
			
		||||
	memcpy(&dst_gl->celldata[to], &src_gl->celldata[from],
 | 
			
		||||
	    to_copy * sizeof *dst_gl->celldata);
 | 
			
		||||
 | 
			
		||||
	for (i = to; i < to + to_copy; i++) {
 | 
			
		||||
		gce = &dst_gl->celldata[i];
 | 
			
		||||
		if (~gce->flags & GRID_FLAG_EXTENDED)
 | 
			
		||||
			continue;
 | 
			
		||||
		was = gce->offset;
 | 
			
		||||
 | 
			
		||||
		dst_gl->extddata = xreallocarray(dst_gl->extddata,
 | 
			
		||||
		    dst_gl->extdsize + 1, sizeof *dst_gl->extddata);
 | 
			
		||||
		gce->offset = dst_gl->extdsize++;
 | 
			
		||||
		memcpy(&dst_gl->extddata[gce->offset], &src_gl->extddata[was],
 | 
			
		||||
		    sizeof *dst_gl->extddata);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Join line data. */
 | 
			
		||||
void
 | 
			
		||||
grid_reflow_join(struct grid *dst, u_int *py, struct grid_line *src_gl,
 | 
			
		||||
@@ -692,8 +772,7 @@ grid_reflow_join(struct grid *dst, u_int *py, struct grid_line *src_gl,
 | 
			
		||||
	dst_gl->cellsize = nx;
 | 
			
		||||
 | 
			
		||||
	/* Append as much as possible. */
 | 
			
		||||
	memcpy(&dst_gl->celldata[ox], &src_gl->celldata[0],
 | 
			
		||||
	    to_copy * sizeof src_gl->celldata[0]);
 | 
			
		||||
	grid_reflow_copy(dst_gl, ox, src_gl, 0, to_copy);
 | 
			
		||||
 | 
			
		||||
	/* If there is any left in the source, split it. */
 | 
			
		||||
	if (src_gl->cellsize > to_copy) {
 | 
			
		||||
@@ -732,8 +811,7 @@ grid_reflow_split(struct grid *dst, u_int *py, struct grid_line *src_gl,
 | 
			
		||||
		dst_gl->flags |= GRID_LINE_WRAPPED;
 | 
			
		||||
 | 
			
		||||
		/* Copy the data. */
 | 
			
		||||
		memcpy(&dst_gl->celldata[0], &src_gl->celldata[offset],
 | 
			
		||||
		    to_copy * sizeof dst_gl->celldata[0]);
 | 
			
		||||
		grid_reflow_copy(dst_gl, 0, src_gl, offset, to_copy);
 | 
			
		||||
 | 
			
		||||
		/* Move offset and reduce old line size. */
 | 
			
		||||
		offset += to_copy;
 | 
			
		||||
@@ -763,6 +841,7 @@ grid_reflow_move(struct grid *dst, u_int *py, struct grid_line *src_gl)
 | 
			
		||||
 | 
			
		||||
	/* Clear old line. */
 | 
			
		||||
	src_gl->celldata = NULL;
 | 
			
		||||
	src_gl->extddata = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -792,7 +871,7 @@ grid_reflow(struct grid *dst, struct grid *src, u_int new_x)
 | 
			
		||||
			/* Previous was wrapped. Try to join. */
 | 
			
		||||
			grid_reflow_join(dst, &py, src_gl, new_x);
 | 
			
		||||
		}
 | 
			
		||||
		previous_wrapped = src_gl->flags & GRID_LINE_WRAPPED;
 | 
			
		||||
		previous_wrapped = (src_gl->flags & GRID_LINE_WRAPPED);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	grid_destroy(src);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								input.c
									
									
									
									
									
								
							@@ -1006,7 +1006,7 @@ input_print(struct input_ctx *ictx)
 | 
			
		||||
	else
 | 
			
		||||
		ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
 | 
			
		||||
 | 
			
		||||
	grid_cell_one(&ictx->cell.cell, ictx->ch);
 | 
			
		||||
	utf8_set(&ictx->cell.cell.data, ictx->ch);
 | 
			
		||||
	screen_write_cell(&ictx->ctx, &ictx->cell.cell);
 | 
			
		||||
 | 
			
		||||
	ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
 | 
			
		||||
@@ -1945,7 +1945,7 @@ input_utf8_close(struct input_ctx *ictx)
 | 
			
		||||
 | 
			
		||||
	utf8_append(&ictx->utf8data, ictx->ch);
 | 
			
		||||
 | 
			
		||||
	grid_cell_set(&ictx->cell.cell, &ictx->utf8data);
 | 
			
		||||
	utf8_copy(&ictx->cell.cell.data, &ictx->utf8data);
 | 
			
		||||
	screen_write_cell(&ictx->ctx, &ictx->cell.cell);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
 
 | 
			
		||||
@@ -67,7 +67,7 @@ void
 | 
			
		||||
screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc,
 | 
			
		||||
    u_char ch)
 | 
			
		||||
{
 | 
			
		||||
	grid_cell_one(gc, ch);
 | 
			
		||||
	utf8_set(&gc->data, ch);
 | 
			
		||||
	screen_write_cell(ctx, gc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -126,7 +126,7 @@ screen_write_strlen(const char *fmt, ...)
 | 
			
		||||
			ptr++;
 | 
			
		||||
 | 
			
		||||
			left = strlen(ptr);
 | 
			
		||||
			if (left < ud.size - 1)
 | 
			
		||||
			if (left < (size_t)ud.size - 1)
 | 
			
		||||
				break;
 | 
			
		||||
			while (utf8_append(&ud, *ptr))
 | 
			
		||||
				ptr++;
 | 
			
		||||
@@ -185,7 +185,7 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
 | 
			
		||||
			ptr++;
 | 
			
		||||
 | 
			
		||||
			left = strlen(ptr);
 | 
			
		||||
			if (left < ud.size - 1)
 | 
			
		||||
			if (left < (size_t)ud.size - 1)
 | 
			
		||||
				break;
 | 
			
		||||
			while (utf8_append(&ud, *ptr))
 | 
			
		||||
				ptr++;
 | 
			
		||||
@@ -201,7 +201,7 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
 | 
			
		||||
			}
 | 
			
		||||
			size += ud.width;
 | 
			
		||||
 | 
			
		||||
			grid_cell_set(gc, &ud);
 | 
			
		||||
			utf8_copy(&gc->data, &ud);
 | 
			
		||||
			screen_write_cell(ctx, gc);
 | 
			
		||||
		} else {
 | 
			
		||||
			if (maxlen > 0 && size + 1 > (size_t) maxlen)
 | 
			
		||||
@@ -258,7 +258,7 @@ screen_write_cnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
 | 
			
		||||
			ptr++;
 | 
			
		||||
 | 
			
		||||
			left = strlen(ptr);
 | 
			
		||||
			if (left < ud.size - 1)
 | 
			
		||||
			if (left < (size_t)ud.size - 1)
 | 
			
		||||
				break;
 | 
			
		||||
			while (utf8_append(&ud, *ptr))
 | 
			
		||||
				ptr++;
 | 
			
		||||
@@ -274,7 +274,7 @@ screen_write_cnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
 | 
			
		||||
			}
 | 
			
		||||
			size += ud.width;
 | 
			
		||||
 | 
			
		||||
			grid_cell_set(&lgc, &ud);
 | 
			
		||||
			utf8_copy(&lgc.data, &ud);
 | 
			
		||||
			screen_write_cell(ctx, &lgc);
 | 
			
		||||
		} else {
 | 
			
		||||
			if (maxlen > 0 && size + 1 > (size_t) maxlen)
 | 
			
		||||
@@ -299,8 +299,7 @@ screen_write_copy(struct screen_write_ctx *ctx,
 | 
			
		||||
	struct screen		*s = ctx->s;
 | 
			
		||||
	struct grid		*gd = src->grid;
 | 
			
		||||
	struct grid_line	*gl;
 | 
			
		||||
	const struct grid_cell	*gc;
 | 
			
		||||
	struct utf8_data	 ud;
 | 
			
		||||
	struct grid_cell	 gc;
 | 
			
		||||
	u_int		 	 xx, yy, cx, cy, ax, bx;
 | 
			
		||||
 | 
			
		||||
	cx = s->cx;
 | 
			
		||||
@@ -324,12 +323,8 @@ screen_write_copy(struct screen_write_ctx *ctx,
 | 
			
		||||
				bx = px + nx;
 | 
			
		||||
 | 
			
		||||
			for (xx = ax; xx < bx; xx++) {
 | 
			
		||||
				if (xx >= gl->cellsize)
 | 
			
		||||
					gc = &grid_default_cell;
 | 
			
		||||
				else
 | 
			
		||||
					gc = &gl->celldata[xx];
 | 
			
		||||
				grid_cell_get(gc, &ud);
 | 
			
		||||
				screen_write_cell(ctx, gc);
 | 
			
		||||
				grid_get_cell(gd, xx, yy, &gc);
 | 
			
		||||
				screen_write_cell(ctx, &gc);
 | 
			
		||||
			}
 | 
			
		||||
			if (px + nx == gd->sx && px + nx > gl->cellsize)
 | 
			
		||||
				screen_write_clearendofline(ctx);
 | 
			
		||||
@@ -342,12 +337,12 @@ screen_write_copy(struct screen_write_ctx *ctx,
 | 
			
		||||
 | 
			
		||||
/* Set up context for TTY command. */
 | 
			
		||||
void
 | 
			
		||||
screen_write_initctx(
 | 
			
		||||
    struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, int save_last)
 | 
			
		||||
screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
 | 
			
		||||
    int save_last)
 | 
			
		||||
{
 | 
			
		||||
	struct screen		*s = ctx->s;
 | 
			
		||||
	struct grid		*gd = s->grid;
 | 
			
		||||
	const struct grid_cell	*gc;
 | 
			
		||||
	struct grid_cell	 gc;
 | 
			
		||||
	u_int			 xx;
 | 
			
		||||
 | 
			
		||||
	ttyctx->wp = ctx->wp;
 | 
			
		||||
@@ -362,14 +357,14 @@ screen_write_initctx(
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* Save the last cell on the screen. */
 | 
			
		||||
	gc = &grid_default_cell;
 | 
			
		||||
	memcpy(&gc, &grid_default_cell, sizeof gc);
 | 
			
		||||
	for (xx = 1; xx <= screen_size_x(s); xx++) {
 | 
			
		||||
		gc = grid_view_peek_cell(gd, screen_size_x(s) - xx, s->cy);
 | 
			
		||||
		if (!(gc->flags & GRID_FLAG_PADDING))
 | 
			
		||||
		grid_view_get_cell(gd, screen_size_x(s) - xx, s->cy, &gc);
 | 
			
		||||
		if (~gc.flags & GRID_FLAG_PADDING)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	ttyctx->last_width = xx;
 | 
			
		||||
	memcpy(&ttyctx->last_cell, gc, sizeof ttyctx->last_cell);
 | 
			
		||||
	memcpy(&ttyctx->last_cell, &gc, sizeof ttyctx->last_cell);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set a mode. */
 | 
			
		||||
@@ -507,7 +502,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx)
 | 
			
		||||
	screen_write_initctx(ctx, &ttyctx, 0);
 | 
			
		||||
 | 
			
		||||
	memcpy(&gc, &grid_default_cell, sizeof gc);
 | 
			
		||||
	grid_cell_one(&gc, 'E');
 | 
			
		||||
	utf8_set(&gc.data, 'E');
 | 
			
		||||
 | 
			
		||||
	for (yy = 0; yy < screen_size_y(s); yy++) {
 | 
			
		||||
		for (xx = 0; xx < screen_size_x(s); xx++)
 | 
			
		||||
@@ -904,14 +899,13 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
 | 
			
		||||
	struct grid		*gd = s->grid;
 | 
			
		||||
	struct tty_ctx		 ttyctx;
 | 
			
		||||
	u_int		 	 width, xx, last;
 | 
			
		||||
	struct grid_cell 	 tmp_gc, *tmp_gcp;
 | 
			
		||||
	struct utf8_data	 ud;
 | 
			
		||||
	struct grid_cell 	 tmp_gc;
 | 
			
		||||
	int			 insert;
 | 
			
		||||
 | 
			
		||||
	/* Ignore padding. */
 | 
			
		||||
	if (gc->flags & GRID_FLAG_PADDING)
 | 
			
		||||
		return;
 | 
			
		||||
	width = grid_cell_width(gc);
 | 
			
		||||
	width = gc->data.width;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If this is a wide character and there is no room on the screen, for
 | 
			
		||||
@@ -928,8 +922,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
 | 
			
		||||
	 * there is space.
 | 
			
		||||
	 */
 | 
			
		||||
	if (width == 0) {
 | 
			
		||||
		grid_cell_get(gc, &ud);
 | 
			
		||||
		if (screen_write_combine(ctx, &ud) == 0) {
 | 
			
		||||
		if (screen_write_combine(ctx, &gc->data) == 0) {
 | 
			
		||||
			screen_write_initctx(ctx, &ttyctx, 0);
 | 
			
		||||
			tty_write(tty_cmd_utf8character, &ttyctx);
 | 
			
		||||
		}
 | 
			
		||||
@@ -964,11 +957,11 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
 | 
			
		||||
	 * 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;
 | 
			
		||||
	}
 | 
			
		||||
	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);
 | 
			
		||||
@@ -990,8 +983,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
 | 
			
		||||
	}
 | 
			
		||||
	if (screen_check_selection(s, s->cx - width, s->cy)) {
 | 
			
		||||
		memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc);
 | 
			
		||||
		grid_cell_get(gc, &ud);
 | 
			
		||||
		grid_cell_set(&tmp_gc, &ud);
 | 
			
		||||
		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);
 | 
			
		||||
@@ -1011,8 +1003,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct utf8_data *ud)
 | 
			
		||||
{
 | 
			
		||||
	struct screen		*s = ctx->s;
 | 
			
		||||
	struct grid		*gd = s->grid;
 | 
			
		||||
	struct grid_cell	*gc;
 | 
			
		||||
	struct utf8_data	 ud1;
 | 
			
		||||
	struct grid_cell	 gc;
 | 
			
		||||
 | 
			
		||||
	/* Can't combine if at 0. */
 | 
			
		||||
	if (s->cx == 0)
 | 
			
		||||
@@ -1023,17 +1014,18 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct utf8_data *ud)
 | 
			
		||||
		fatalx("UTF-8 data empty");
 | 
			
		||||
 | 
			
		||||
	/* Retrieve the previous cell. */
 | 
			
		||||
	gc = grid_view_get_cell(gd, s->cx - 1, s->cy);
 | 
			
		||||
	grid_cell_get(gc, &ud1);
 | 
			
		||||
	grid_view_get_cell(gd, s->cx - 1, s->cy, &gc);
 | 
			
		||||
 | 
			
		||||
	/* Check there is enough space. */
 | 
			
		||||
	if (ud1.size + ud->size > sizeof ud1.data)
 | 
			
		||||
	if (gc.data.size + ud->size > sizeof gc.data.data)
 | 
			
		||||
		return (-1);
 | 
			
		||||
 | 
			
		||||
	/* Append the data and set the cell. */
 | 
			
		||||
	memcpy(ud1.data + ud1.size, ud->data, ud->size);
 | 
			
		||||
	ud1.size += ud->size;
 | 
			
		||||
	grid_cell_set(gc, &ud1);
 | 
			
		||||
	/* Append the data. */
 | 
			
		||||
	memcpy(gc.data.data + gc.data.size, ud->data, ud->size);
 | 
			
		||||
	gc.data.size += ud->size;
 | 
			
		||||
 | 
			
		||||
	/* Set the new cell. */
 | 
			
		||||
	grid_view_set_cell(gd, s->cx - 1, s->cy, &gc);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
@@ -1052,11 +1044,11 @@ screen_write_overwrite(struct screen_write_ctx *ctx, u_int width)
 | 
			
		||||
{
 | 
			
		||||
	struct screen		*s = ctx->s;
 | 
			
		||||
	struct grid		*gd = s->grid;
 | 
			
		||||
	const struct grid_cell	*gc;
 | 
			
		||||
	struct grid_cell	 gc;
 | 
			
		||||
	u_int			 xx;
 | 
			
		||||
 | 
			
		||||
	gc = grid_view_peek_cell(gd, s->cx, s->cy);
 | 
			
		||||
	if (gc->flags & GRID_FLAG_PADDING) {
 | 
			
		||||
	grid_view_get_cell(gd, s->cx, s->cy, &gc);
 | 
			
		||||
	if (gc.flags & GRID_FLAG_PADDING) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * A padding cell, so clear any following and leading padding
 | 
			
		||||
		 * cells back to the character. Don't overwrite the current
 | 
			
		||||
@@ -1064,8 +1056,8 @@ screen_write_overwrite(struct screen_write_ctx *ctx, u_int width)
 | 
			
		||||
		 */
 | 
			
		||||
		xx = s->cx + 1;
 | 
			
		||||
		while (--xx > 0) {
 | 
			
		||||
			gc = grid_view_peek_cell(gd, xx, s->cy);
 | 
			
		||||
			if (!(gc->flags & GRID_FLAG_PADDING))
 | 
			
		||||
			grid_view_get_cell(gd, xx, s->cy, &gc);
 | 
			
		||||
			if (~gc.flags & GRID_FLAG_PADDING)
 | 
			
		||||
				break;
 | 
			
		||||
			grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
 | 
			
		||||
		}
 | 
			
		||||
@@ -1080,8 +1072,8 @@ screen_write_overwrite(struct screen_write_ctx *ctx, u_int width)
 | 
			
		||||
	 */
 | 
			
		||||
	xx = s->cx + width - 1;
 | 
			
		||||
	while (++xx < screen_size_x(s)) {
 | 
			
		||||
		gc = grid_view_peek_cell(gd, xx, s->cy);
 | 
			
		||||
		if (!(gc->flags & GRID_FLAG_PADDING))
 | 
			
		||||
		grid_view_get_cell(gd, xx, s->cy, &gc);
 | 
			
		||||
		if (~gc.flags & GRID_FLAG_PADDING)
 | 
			
		||||
			break;
 | 
			
		||||
		grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								status.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								status.c
									
									
									
									
									
								
							@@ -746,7 +746,7 @@ status_prompt_redraw(struct client *c)
 | 
			
		||||
	struct session		       *s = c->session;
 | 
			
		||||
	struct screen		        old_status;
 | 
			
		||||
	size_t			        i, size, left, len, off;
 | 
			
		||||
	struct grid_cell		gc, *gcp;
 | 
			
		||||
	struct grid_cell		gc;
 | 
			
		||||
 | 
			
		||||
	if (c->tty.sx == 0 || c->tty.sy == 0)
 | 
			
		||||
		return (0);
 | 
			
		||||
@@ -789,8 +789,9 @@ status_prompt_redraw(struct client *c)
 | 
			
		||||
 | 
			
		||||
	/* Apply fake cursor. */
 | 
			
		||||
	off = len + c->prompt_index - off;
 | 
			
		||||
	gcp = grid_view_get_cell(c->status.grid, off, 0);
 | 
			
		||||
	gcp->attr ^= GRID_ATTR_REVERSE;
 | 
			
		||||
	grid_view_get_cell(c->status.grid, off, 0, &gc);
 | 
			
		||||
	gc.attr ^= GRID_ATTR_REVERSE;
 | 
			
		||||
	grid_view_set_cell(c->status.grid, off, 0, &gc);
 | 
			
		||||
 | 
			
		||||
	if (grid_compare(c->status.grid, old_status.grid) == 0) {
 | 
			
		||||
		screen_free(&old_status);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										72
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								tmux.h
									
									
									
									
									
								
							@@ -624,11 +624,11 @@ struct mode_key_table {
 | 
			
		||||
struct utf8_data {
 | 
			
		||||
	u_char	data[UTF8_SIZE];
 | 
			
		||||
 | 
			
		||||
	size_t	have;
 | 
			
		||||
	size_t	size;
 | 
			
		||||
	u_char	have;
 | 
			
		||||
	u_char	size;
 | 
			
		||||
 | 
			
		||||
	u_int	width;
 | 
			
		||||
};
 | 
			
		||||
	u_char	width;
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
/* Grid attributes. */
 | 
			
		||||
#define GRID_ATTR_BRIGHT 0x1
 | 
			
		||||
@@ -644,41 +644,56 @@ struct utf8_data {
 | 
			
		||||
#define GRID_FLAG_FG256 0x1
 | 
			
		||||
#define GRID_FLAG_BG256 0x2
 | 
			
		||||
#define GRID_FLAG_PADDING 0x4
 | 
			
		||||
#define GRID_FLAG_EXTENDED 0x8
 | 
			
		||||
 | 
			
		||||
/* Grid line flags. */
 | 
			
		||||
#define GRID_LINE_WRAPPED 0x1
 | 
			
		||||
 | 
			
		||||
/* Grid cell data. */
 | 
			
		||||
struct grid_cell {
 | 
			
		||||
	u_char	attr;
 | 
			
		||||
	u_char	flags;
 | 
			
		||||
	u_char	fg;
 | 
			
		||||
	u_char	bg;
 | 
			
		||||
	u_char			flags;
 | 
			
		||||
	u_char			attr;
 | 
			
		||||
	u_char			fg;
 | 
			
		||||
	u_char			bg;
 | 
			
		||||
	struct utf8_data	data;
 | 
			
		||||
 | 
			
		||||
	u_char	xstate; /* top 4 bits width, bottom 4 bits size */
 | 
			
		||||
	u_char	xdata[UTF8_SIZE];
 | 
			
		||||
};
 | 
			
		||||
struct grid_cell_entry {
 | 
			
		||||
	u_char			flags;
 | 
			
		||||
	union {
 | 
			
		||||
		u_int		offset;
 | 
			
		||||
		struct {
 | 
			
		||||
			u_char	attr;
 | 
			
		||||
			u_char	fg;
 | 
			
		||||
			u_char	bg;
 | 
			
		||||
			u_char	data;
 | 
			
		||||
		} data;
 | 
			
		||||
	};
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
/* Grid line. */
 | 
			
		||||
struct grid_line {
 | 
			
		||||
	u_int	cellsize;
 | 
			
		||||
	struct grid_cell *celldata;
 | 
			
		||||
	u_int			 cellsize;
 | 
			
		||||
	struct grid_cell_entry	*celldata;
 | 
			
		||||
 | 
			
		||||
	int	flags;
 | 
			
		||||
	u_int			 extdsize;
 | 
			
		||||
	struct grid_cell	*extddata;
 | 
			
		||||
 | 
			
		||||
	int			 flags;
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
/* Entire grid of cells. */
 | 
			
		||||
struct grid {
 | 
			
		||||
	int	flags;
 | 
			
		||||
#define GRID_HISTORY 0x1	/* scroll lines into history */
 | 
			
		||||
	int			 flags;
 | 
			
		||||
#define GRID_HISTORY 0x1 /* scroll lines into history */
 | 
			
		||||
 | 
			
		||||
	u_int	sx;
 | 
			
		||||
	u_int	sy;
 | 
			
		||||
	u_int			 sx;
 | 
			
		||||
	u_int			 sy;
 | 
			
		||||
 | 
			
		||||
	u_int	hsize;
 | 
			
		||||
	u_int	hlimit;
 | 
			
		||||
	u_int			 hsize;
 | 
			
		||||
	u_int			 hlimit;
 | 
			
		||||
 | 
			
		||||
	struct grid_line *linedata;
 | 
			
		||||
	struct grid_line	*linedata;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Option data structures. */
 | 
			
		||||
@@ -1857,9 +1872,8 @@ void	 grid_scroll_history(struct grid *);
 | 
			
		||||
void	 grid_scroll_history_region(struct grid *, u_int, u_int);
 | 
			
		||||
void	 grid_clear_history(struct grid *);
 | 
			
		||||
void	 grid_expand_line(struct grid *, u_int, u_int);
 | 
			
		||||
const struct grid_cell *grid_peek_cell(struct grid *, u_int, u_int);
 | 
			
		||||
const struct grid_line *grid_peek_line(struct grid *, u_int);
 | 
			
		||||
struct grid_cell *grid_get_cell(struct grid *, u_int, u_int);
 | 
			
		||||
void	 grid_get_cell(struct grid *, u_int, u_int, struct grid_cell *);
 | 
			
		||||
void	 grid_set_cell(struct grid *, u_int, u_int, const struct grid_cell *);
 | 
			
		||||
void	 grid_clear(struct grid *, u_int, u_int, u_int, u_int);
 | 
			
		||||
void	 grid_clear_lines(struct grid *, u_int, u_int);
 | 
			
		||||
@@ -1871,17 +1885,10 @@ void	 grid_duplicate_lines(
 | 
			
		||||
	     struct grid *, u_int, struct grid *, u_int, u_int);
 | 
			
		||||
u_int	 grid_reflow(struct grid *, struct grid *, u_int);
 | 
			
		||||
 | 
			
		||||
/* grid-cell.c */
 | 
			
		||||
u_int	 grid_cell_width(const struct grid_cell *);
 | 
			
		||||
void	 grid_cell_get(const struct grid_cell *, struct utf8_data *);
 | 
			
		||||
void	 grid_cell_set(struct grid_cell *, const struct utf8_data *);
 | 
			
		||||
void	 grid_cell_one(struct grid_cell *, u_char);
 | 
			
		||||
 | 
			
		||||
/* grid-view.c */
 | 
			
		||||
const struct grid_cell *grid_view_peek_cell(struct grid *, u_int, u_int);
 | 
			
		||||
struct grid_cell *grid_view_get_cell(struct grid *, u_int, u_int);
 | 
			
		||||
void	 grid_view_set_cell(
 | 
			
		||||
	     struct grid *, u_int, u_int, const struct grid_cell *);
 | 
			
		||||
void	 grid_view_get_cell(struct grid *, u_int, u_int, struct grid_cell *);
 | 
			
		||||
void	 grid_view_set_cell(struct grid *, u_int, u_int,
 | 
			
		||||
	     const struct grid_cell *);
 | 
			
		||||
void	 grid_view_clear_history(struct grid *);
 | 
			
		||||
void	 grid_view_clear(struct grid *, u_int, u_int, u_int, u_int);
 | 
			
		||||
void	 grid_view_scroll_region_up(struct grid *, u_int, u_int);
 | 
			
		||||
@@ -2186,6 +2193,7 @@ void		 session_renumber_windows(struct session *);
 | 
			
		||||
/* utf8.c */
 | 
			
		||||
u_int		 utf8_width(u_int);
 | 
			
		||||
void		 utf8_set(struct utf8_data *, u_char);
 | 
			
		||||
void		 utf8_copy(struct utf8_data *, const struct utf8_data *);
 | 
			
		||||
int		 utf8_open(struct utf8_data *, u_char);
 | 
			
		||||
int		 utf8_append(struct utf8_data *, u_char);
 | 
			
		||||
u_int		 utf8_combine(const struct utf8_data *);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								tty.c
									
									
									
									
									
								
							@@ -656,10 +656,8 @@ void
 | 
			
		||||
tty_draw_line(struct tty *tty, const struct window_pane *wp,
 | 
			
		||||
    struct screen *s, u_int py, u_int ox, u_int oy)
 | 
			
		||||
{
 | 
			
		||||
	const struct grid_cell	*gc;
 | 
			
		||||
	struct grid_cell	 gc;
 | 
			
		||||
	struct grid_line	*gl;
 | 
			
		||||
	struct grid_cell	 tmpgc;
 | 
			
		||||
	struct utf8_data	 ud;
 | 
			
		||||
	u_int			 i, sx;
 | 
			
		||||
	int			 flags;
 | 
			
		||||
 | 
			
		||||
@@ -686,18 +684,13 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp,
 | 
			
		||||
		tty_cursor(tty, ox, oy + py);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < sx; i++) {
 | 
			
		||||
		gc = grid_view_peek_cell(s->grid, i, py);
 | 
			
		||||
		grid_view_get_cell(s->grid, i, py, &gc);
 | 
			
		||||
		if (screen_check_selection(s, i, py)) {
 | 
			
		||||
			memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc);
 | 
			
		||||
			grid_cell_get(gc, &ud);
 | 
			
		||||
			grid_cell_set(&tmpgc, &ud);
 | 
			
		||||
			tmpgc.flags = gc->flags &
 | 
			
		||||
			    ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
 | 
			
		||||
			tmpgc.flags |= s->sel.cell.flags &
 | 
			
		||||
			gc.flags &= ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
 | 
			
		||||
			gc.flags |= s->sel.cell.flags &
 | 
			
		||||
			    (GRID_FLAG_FG256|GRID_FLAG_BG256);
 | 
			
		||||
			tty_cell(tty, &tmpgc, wp);
 | 
			
		||||
		} else
 | 
			
		||||
			tty_cell(tty, gc, wp);
 | 
			
		||||
		}
 | 
			
		||||
		tty_cell(tty, &gc, wp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (sx < tty->sx) {
 | 
			
		||||
@@ -1078,7 +1071,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
 | 
			
		||||
	tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
 | 
			
		||||
 | 
			
		||||
	/* Is the cursor in the very last position? */
 | 
			
		||||
	width = grid_cell_width(ctx->cell);
 | 
			
		||||
	width = ctx->cell->data.width;
 | 
			
		||||
	if (ctx->ocx > wp->sx - width) {
 | 
			
		||||
		if (ctx->xoff != 0 || wp->sx != tty->sx) {
 | 
			
		||||
			/*
 | 
			
		||||
@@ -1095,7 +1088,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
 | 
			
		||||
			 * move as far left as possible and redraw the last
 | 
			
		||||
			 * cell to move into the last position.
 | 
			
		||||
			 */
 | 
			
		||||
			cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell);
 | 
			
		||||
			cx = screen_size_x(s) - ctx->last_cell.data.width;
 | 
			
		||||
			tty_cursor_pane(tty, ctx, cx, ctx->ocy);
 | 
			
		||||
			tty_cell(tty, &ctx->last_cell, wp);
 | 
			
		||||
		}
 | 
			
		||||
@@ -1155,8 +1148,7 @@ void
 | 
			
		||||
tty_cell(struct tty *tty, const struct grid_cell *gc,
 | 
			
		||||
    const struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	struct utf8_data	ud;
 | 
			
		||||
	u_int			i;
 | 
			
		||||
	u_int	i;
 | 
			
		||||
 | 
			
		||||
	/* Skip last character if terminal is stupid. */
 | 
			
		||||
	if (tty->term->flags & TERM_EARLYWRAP &&
 | 
			
		||||
@@ -1171,23 +1163,22 @@ tty_cell(struct tty *tty, const struct grid_cell *gc,
 | 
			
		||||
	tty_attributes(tty, gc, wp);
 | 
			
		||||
 | 
			
		||||
	/* Get the cell and if ASCII write with putc to do ACS translation. */
 | 
			
		||||
	grid_cell_get(gc, &ud);
 | 
			
		||||
	if (ud.size == 1) {
 | 
			
		||||
		if (*ud.data < 0x20 || *ud.data == 0x7f)
 | 
			
		||||
	if (gc->data.size == 1) {
 | 
			
		||||
		if (*gc->data.data < 0x20 || *gc->data.data == 0x7f)
 | 
			
		||||
			return;
 | 
			
		||||
		tty_putc(tty, *ud.data);
 | 
			
		||||
		tty_putc(tty, *gc->data.data);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* If not UTF-8, write _. */
 | 
			
		||||
	if (!(tty->flags & TTY_UTF8)) {
 | 
			
		||||
		for (i = 0; i < ud.width; i++)
 | 
			
		||||
		for (i = 0; i < gc->data.width; i++)
 | 
			
		||||
			tty_putc(tty, '_');
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Write the data. */
 | 
			
		||||
	tty_putn(tty, ud.data, ud.size, ud.width);
 | 
			
		||||
	tty_putn(tty, gc->data.data, gc->data.size, gc->data.width);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								utf8.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								utf8.c
									
									
									
									
									
								
							@@ -351,10 +351,27 @@ static void	utf8_build(void);
 | 
			
		||||
void
 | 
			
		||||
utf8_set(struct utf8_data *ud, u_char ch)
 | 
			
		||||
{
 | 
			
		||||
	u_int	i;
 | 
			
		||||
 | 
			
		||||
	*ud->data = ch;
 | 
			
		||||
	ud->size = 1;
 | 
			
		||||
 | 
			
		||||
	ud->width = 1;
 | 
			
		||||
 | 
			
		||||
	for (i = ud->size; i < sizeof ud->data; i++)
 | 
			
		||||
		ud->data[i] = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Copy UTF-8 character. */
 | 
			
		||||
void
 | 
			
		||||
utf8_copy(struct utf8_data *to, const struct utf8_data *from)
 | 
			
		||||
{
 | 
			
		||||
	u_int	i;
 | 
			
		||||
 | 
			
		||||
	memcpy(to, from, sizeof *to);
 | 
			
		||||
 | 
			
		||||
	for (i = to->size; i < sizeof to->data; i++)
 | 
			
		||||
		to->data[i] = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										105
									
								
								window-copy.c
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								window-copy.c
									
									
									
									
									
								
							@@ -942,21 +942,21 @@ int
 | 
			
		||||
window_copy_search_compare(struct grid *gd, u_int px, u_int py,
 | 
			
		||||
    struct grid *sgd, u_int spx, int cis)
 | 
			
		||||
{
 | 
			
		||||
	const struct grid_cell	*gc, *sgc;
 | 
			
		||||
	struct utf8_data	 ud, sud;
 | 
			
		||||
	struct grid_cell	 gc, sgc;
 | 
			
		||||
	const struct utf8_data	*ud, *sud;
 | 
			
		||||
 | 
			
		||||
	gc = grid_peek_cell(gd, px, py);
 | 
			
		||||
	grid_cell_get(gc, &ud);
 | 
			
		||||
	sgc = grid_peek_cell(sgd, spx, 0);
 | 
			
		||||
	grid_cell_get(sgc, &sud);
 | 
			
		||||
	grid_get_cell(gd, px, py, &gc);
 | 
			
		||||
	ud = &gc.data;
 | 
			
		||||
	grid_get_cell(sgd, spx, 0, &sgc);
 | 
			
		||||
	sud = &sgc.data;
 | 
			
		||||
 | 
			
		||||
	if (ud.size != sud.size || ud.width != sud.width)
 | 
			
		||||
	if (ud->size != sud->size || ud->width != sud->width)
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	if (cis && ud.size == 1)
 | 
			
		||||
		return (tolower(ud.data[0]) == sud.data[0]);
 | 
			
		||||
	if (cis && ud->size == 1)
 | 
			
		||||
		return (tolower(ud->data[0]) == sud->data[0]);
 | 
			
		||||
 | 
			
		||||
	return (memcmp(ud.data, sud.data, ud.size) == 0);
 | 
			
		||||
	return (memcmp(ud->data, sud->data, ud->size) == 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
@@ -1541,12 +1541,12 @@ window_copy_append_selection(struct window_pane *wp, const char *bufname)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_copy_copy_line(struct window_pane *wp,
 | 
			
		||||
    char **buf, size_t *off, u_int sy, u_int sx, u_int ex)
 | 
			
		||||
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;
 | 
			
		||||
	struct grid_cell		 gc;
 | 
			
		||||
	struct grid_line		*gl;
 | 
			
		||||
	struct utf8_data		 ud;
 | 
			
		||||
	u_int				 i, xx, wrapped = 0;
 | 
			
		||||
@@ -1575,11 +1575,11 @@ window_copy_copy_line(struct window_pane *wp,
 | 
			
		||||
 | 
			
		||||
	if (sx < ex) {
 | 
			
		||||
		for (i = sx; i < ex; i++) {
 | 
			
		||||
			gc = grid_peek_cell(gd, i, sy);
 | 
			
		||||
			if (gc->flags & GRID_FLAG_PADDING)
 | 
			
		||||
			grid_get_cell(gd, i, sy, &gc);
 | 
			
		||||
			if (gc.flags & GRID_FLAG_PADDING)
 | 
			
		||||
				continue;
 | 
			
		||||
			grid_cell_get(gc, &ud);
 | 
			
		||||
			if (ud.size == 1 && (gc->attr & GRID_ATTR_CHARSET)) {
 | 
			
		||||
			utf8_copy(&ud, &gc.data);
 | 
			
		||||
			if (ud.size == 1 && (gc.attr & GRID_ATTR_CHARSET)) {
 | 
			
		||||
				s = tty_acs_get(NULL, ud.data[0]);
 | 
			
		||||
				if (s != NULL && strlen(s) <= sizeof ud.data) {
 | 
			
		||||
					ud.size = strlen(s);
 | 
			
		||||
@@ -1618,16 +1618,17 @@ int
 | 
			
		||||
window_copy_in_set(struct window_pane *wp, u_int px, u_int py, const char *set)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	const struct grid_cell		*gc;
 | 
			
		||||
	struct utf8_data		 ud;
 | 
			
		||||
	struct grid_cell		 gc;
 | 
			
		||||
	const struct utf8_data		*ud;
 | 
			
		||||
 | 
			
		||||
	gc = grid_peek_cell(data->backing->grid, px, py);
 | 
			
		||||
	grid_cell_get(gc, &ud);
 | 
			
		||||
	if (ud.size != 1 || gc->flags & GRID_FLAG_PADDING)
 | 
			
		||||
	grid_get_cell(data->backing->grid, px, py, &gc);
 | 
			
		||||
 | 
			
		||||
	ud = &gc.data;
 | 
			
		||||
	if (ud->size != 1 || (gc.flags & GRID_FLAG_PADDING))
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (*ud.data == 0x00 || *ud.data == 0x7f)
 | 
			
		||||
	if (*ud->data == 0x00 || *ud->data == 0x7f)
 | 
			
		||||
		return (0);
 | 
			
		||||
	return (strchr(set, *ud.data) != NULL);
 | 
			
		||||
	return (strchr(set, *ud->data) != NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u_int
 | 
			
		||||
@@ -1635,8 +1636,7 @@ window_copy_find_length(struct window_pane *wp, u_int py)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	struct screen			*s = data->backing;
 | 
			
		||||
	const struct grid_cell		*gc;
 | 
			
		||||
	struct utf8_data		 ud;
 | 
			
		||||
	struct grid_cell		 gc;
 | 
			
		||||
	u_int				 px;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
@@ -1649,9 +1649,8 @@ window_copy_find_length(struct window_pane *wp, u_int py)
 | 
			
		||||
	if (px > screen_size_x(s))
 | 
			
		||||
		px = screen_size_x(s);
 | 
			
		||||
	while (px > 0) {
 | 
			
		||||
		gc = grid_peek_cell(s->grid, px - 1, py);
 | 
			
		||||
		grid_cell_get(gc, &ud);
 | 
			
		||||
		if (ud.size != 1 || *ud.data != ' ')
 | 
			
		||||
		grid_get_cell(s->grid, px - 1, py, &gc);
 | 
			
		||||
		if (gc.data.size != 1 || *gc.data.data != ' ')
 | 
			
		||||
			break;
 | 
			
		||||
		px--;
 | 
			
		||||
	}
 | 
			
		||||
@@ -1685,17 +1684,15 @@ window_copy_cursor_back_to_indentation(struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	u_int				 px, py, xx;
 | 
			
		||||
	const struct grid_cell		*gc;
 | 
			
		||||
	struct utf8_data		 ud;
 | 
			
		||||
	struct grid_cell		 gc;
 | 
			
		||||
 | 
			
		||||
	px = 0;
 | 
			
		||||
	py = screen_hsize(data->backing) + data->cy - data->oy;
 | 
			
		||||
	xx = window_copy_find_length(wp, py);
 | 
			
		||||
 | 
			
		||||
	while (px < xx) {
 | 
			
		||||
		gc = grid_peek_cell(data->backing->grid, px, py);
 | 
			
		||||
		grid_cell_get(gc, &ud);
 | 
			
		||||
		if (ud.size != 1 || *ud.data != ' ')
 | 
			
		||||
		grid_get_cell(data->backing->grid, px, py, &gc);
 | 
			
		||||
		if (gc.data.size != 1 || *gc.data.data != ' ')
 | 
			
		||||
			break;
 | 
			
		||||
		px++;
 | 
			
		||||
	}
 | 
			
		||||
@@ -1909,8 +1906,7 @@ window_copy_cursor_jump(struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	struct screen			*back_s = data->backing;
 | 
			
		||||
	const struct grid_cell		*gc;
 | 
			
		||||
	struct utf8_data		 ud;
 | 
			
		||||
	struct grid_cell		 gc;
 | 
			
		||||
	u_int				 px, py, xx;
 | 
			
		||||
 | 
			
		||||
	px = data->cx + 1;
 | 
			
		||||
@@ -1918,10 +1914,9 @@ window_copy_cursor_jump(struct window_pane *wp)
 | 
			
		||||
	xx = window_copy_find_length(wp, py);
 | 
			
		||||
 | 
			
		||||
	while (px < xx) {
 | 
			
		||||
		gc = grid_peek_cell(back_s->grid, px, py);
 | 
			
		||||
		grid_cell_get(gc, &ud);
 | 
			
		||||
		if (!(gc->flags & GRID_FLAG_PADDING) &&
 | 
			
		||||
		    ud.size == 1 && *ud.data == data->jumpchar) {
 | 
			
		||||
		grid_get_cell(back_s->grid, px, py, &gc);
 | 
			
		||||
		if (!(gc.flags & GRID_FLAG_PADDING) &&
 | 
			
		||||
		    gc.data.size == 1 && *gc.data.data == data->jumpchar) {
 | 
			
		||||
			window_copy_update_cursor(wp, px, data->cy);
 | 
			
		||||
			if (window_copy_update_selection(wp, 1))
 | 
			
		||||
				window_copy_redraw_lines(wp, data->cy, 1);
 | 
			
		||||
@@ -1936,8 +1931,7 @@ window_copy_cursor_jump_back(struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	struct screen			*back_s = data->backing;
 | 
			
		||||
	const struct grid_cell		*gc;
 | 
			
		||||
	struct utf8_data		 ud;
 | 
			
		||||
	struct grid_cell		 gc;
 | 
			
		||||
	u_int				 px, py;
 | 
			
		||||
 | 
			
		||||
	px = data->cx;
 | 
			
		||||
@@ -1947,10 +1941,9 @@ window_copy_cursor_jump_back(struct window_pane *wp)
 | 
			
		||||
		px--;
 | 
			
		||||
 | 
			
		||||
	for (;;) {
 | 
			
		||||
		gc = grid_peek_cell(back_s->grid, px, py);
 | 
			
		||||
		grid_cell_get(gc, &ud);
 | 
			
		||||
		if (!(gc->flags & GRID_FLAG_PADDING) &&
 | 
			
		||||
		    ud.size == 1 && *ud.data == data->jumpchar) {
 | 
			
		||||
		grid_get_cell(back_s->grid, px, py, &gc);
 | 
			
		||||
		if (!(gc.flags & GRID_FLAG_PADDING) &&
 | 
			
		||||
		    gc.data.size == 1 && *gc.data.data == data->jumpchar) {
 | 
			
		||||
			window_copy_update_cursor(wp, px, data->cy);
 | 
			
		||||
			if (window_copy_update_selection(wp, 1))
 | 
			
		||||
				window_copy_redraw_lines(wp, data->cy, 1);
 | 
			
		||||
@@ -1967,8 +1960,7 @@ window_copy_cursor_jump_to(struct window_pane *wp, int jump_again)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	struct screen			*back_s = data->backing;
 | 
			
		||||
	const struct grid_cell		*gc;
 | 
			
		||||
	struct utf8_data		 ud;
 | 
			
		||||
	struct grid_cell		 gc;
 | 
			
		||||
	u_int				 px, py, xx;
 | 
			
		||||
 | 
			
		||||
	px = data->cx + 1 + jump_again;
 | 
			
		||||
@@ -1976,10 +1968,9 @@ window_copy_cursor_jump_to(struct window_pane *wp, int jump_again)
 | 
			
		||||
	xx = window_copy_find_length(wp, py);
 | 
			
		||||
 | 
			
		||||
	while (px < xx) {
 | 
			
		||||
		gc = grid_peek_cell(back_s->grid, px, py);
 | 
			
		||||
		grid_cell_get(gc, &ud);
 | 
			
		||||
		if (!(gc->flags & GRID_FLAG_PADDING) &&
 | 
			
		||||
		    ud.size == 1 && *ud.data == data->jumpchar) {
 | 
			
		||||
		grid_get_cell(back_s->grid, px, py, &gc);
 | 
			
		||||
		if (!(gc.flags & GRID_FLAG_PADDING) &&
 | 
			
		||||
		    gc.data.size == 1 && *gc.data.data == data->jumpchar) {
 | 
			
		||||
			window_copy_update_cursor(wp, px - 1, data->cy);
 | 
			
		||||
			if (window_copy_update_selection(wp, 1))
 | 
			
		||||
				window_copy_redraw_lines(wp, data->cy, 1);
 | 
			
		||||
@@ -1994,8 +1985,7 @@ window_copy_cursor_jump_to_back(struct window_pane *wp, int jump_again)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	struct screen			*back_s = data->backing;
 | 
			
		||||
	const struct grid_cell		*gc;
 | 
			
		||||
	struct utf8_data		 ud;
 | 
			
		||||
	struct grid_cell		 gc;
 | 
			
		||||
	u_int				 px, py;
 | 
			
		||||
 | 
			
		||||
	px = data->cx;
 | 
			
		||||
@@ -2008,10 +1998,9 @@ window_copy_cursor_jump_to_back(struct window_pane *wp, int jump_again)
 | 
			
		||||
		px--;
 | 
			
		||||
 | 
			
		||||
	for (;;) {
 | 
			
		||||
		gc = grid_peek_cell(back_s->grid, px, py);
 | 
			
		||||
		grid_cell_get(gc, &ud);
 | 
			
		||||
		if (!(gc->flags & GRID_FLAG_PADDING) &&
 | 
			
		||||
		    ud.size == 1 && *ud.data == data->jumpchar) {
 | 
			
		||||
		grid_get_cell(back_s->grid, px, py, &gc);
 | 
			
		||||
		if (!(gc.flags & GRID_FLAG_PADDING) &&
 | 
			
		||||
		    gc.data.size == 1 && *gc.data.data == data->jumpchar) {
 | 
			
		||||
			window_copy_update_cursor(wp, px + 1, data->cy);
 | 
			
		||||
			if (window_copy_update_selection(wp, 1))
 | 
			
		||||
				window_copy_redraw_lines(wp, data->cy, 1);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user