mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Rather than having two grids for each pane, one for ASCII and one for
UTF-8, collapse the two together. Simplifies the code at the expense of more memory (which can probably be reduced again later).
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -85,7 +85,7 @@ SRCS=	arguments.c \ | ||||
| 	control-notify.c \ | ||||
| 	environ.c \ | ||||
| 	format.c \ | ||||
| 	grid-utf8.c \ | ||||
| 	grid-cell.c \ | ||||
| 	grid-view.c \ | ||||
| 	grid.c \ | ||||
| 	input-keys.c \ | ||||
|   | ||||
| @@ -59,12 +59,11 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx) | ||||
| 	struct job				*job; | ||||
| 	struct grid				*gd; | ||||
| 	struct grid_line			*gl; | ||||
| 	u_int		 			 i, j, k; | ||||
| 	u_int		 			 i, j, k, lines; | ||||
| 	size_t					 size; | ||||
| 	char					 out[80]; | ||||
| 	char					*tim; | ||||
| 	time_t		 			 t; | ||||
| 	u_int					 lines, ulines; | ||||
| 	size_t					 size, usize; | ||||
|  | ||||
| 	tim = ctime(&start_time); | ||||
| 	*strchr(tim, '\n') = '\0'; | ||||
| @@ -97,8 +96,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx) | ||||
| 	} | ||||
| 	ctx->print(ctx, "%s", ""); | ||||
|  | ||||
| 	ctx->print(ctx, "Sessions: [%zu/%zu]", | ||||
| 	    sizeof (struct grid_cell), sizeof (struct grid_utf8)); | ||||
| 	ctx->print(ctx, "Sessions: [%zu]", sizeof (struct grid_cell)); | ||||
| 	RB_FOREACH(s, sessions, &sessions) { | ||||
| 		t = s->creation_time.tv_sec; | ||||
| 		tim = ctime(&t); | ||||
| @@ -115,26 +113,20 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx) | ||||
| 			    w->lastlayout); | ||||
| 			j = 0; | ||||
| 			TAILQ_FOREACH(wp, &w->panes, entry) { | ||||
| 				lines = ulines = size = usize = 0; | ||||
| 				lines = size = 0; | ||||
| 				gd = wp->base.grid; | ||||
| 				for (k = 0; k < gd->hsize + gd->sy; k++) { | ||||
| 					gl = &gd->linedata[k]; | ||||
| 					if (gl->celldata != NULL) { | ||||
| 						lines++; | ||||
| 						size += gl->cellsize * | ||||
| 						    sizeof *gl->celldata; | ||||
| 					} | ||||
| 					if (gl->utf8data != NULL) { | ||||
| 						ulines++; | ||||
| 						usize += gl->utf8size * | ||||
| 						    sizeof *gl->utf8data; | ||||
| 					} | ||||
| 					if (gl->celldata == NULL) | ||||
| 						continue; | ||||
| 					lines++; | ||||
| 					size += gl->cellsize * | ||||
| 					    sizeof *gl->celldata; | ||||
| 				} | ||||
| 				ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu " | ||||
| 				    "bytes; UTF-8 %u/%u, %zu bytes", j, | ||||
| 				ctx->print(ctx, | ||||
| 				    "%6u: %s %lu %d %u/%u, %zu bytes", j, | ||||
| 				    wp->tty, (u_long) wp->pid, wp->fd, lines, | ||||
| 				    gd->hsize + gd->sy, size, ulines, | ||||
| 				    gd->hsize + gd->sy, usize); | ||||
| 				    gd->hsize + gd->sy, size); | ||||
| 				j++; | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										1
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								format.c
									
									
									
									
									
								
							| @@ -370,7 +370,6 @@ format_window_pane(struct format_tree *ft, struct window_pane *wp) | ||||
| 	for (i = 0; i < gd->hsize; i++) { | ||||
| 		gl = &gd->linedata[i]; | ||||
| 		size += gl->cellsize * sizeof *gl->celldata; | ||||
| 		size += gl->utf8size * sizeof *gl->utf8data; | ||||
| 	} | ||||
| 	size += gd->hsize * sizeof *gd->linedata; | ||||
|  | ||||
|   | ||||
							
								
								
									
										55
									
								
								grid-cell.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								grid-cell.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| /* $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; | ||||
| } | ||||
							
								
								
									
										96
									
								
								grid-utf8.c
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								grid-utf8.c
									
									
									
									
									
								
							| @@ -1,96 +0,0 @@ | ||||
| /* $OpenBSD$ */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 2009 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" | ||||
|  | ||||
| /* | ||||
|  * Grid UTF-8 utility functions. | ||||
|  */ | ||||
|  | ||||
| /* Calculate UTF-8 grid cell size. Data is terminated by 0xff. */ | ||||
| size_t | ||||
| grid_utf8_size(const struct grid_utf8 *gu) | ||||
| { | ||||
| 	size_t	size; | ||||
|  | ||||
| 	for (size = 0; size < sizeof gu->data; size++) { | ||||
| 		if (gu->data[size] == 0xff) | ||||
| 			break; | ||||
| 	} | ||||
| 	return (size); | ||||
| } | ||||
|  | ||||
| /* Copy UTF-8 out into a buffer. */ | ||||
| size_t | ||||
| grid_utf8_copy(const struct grid_utf8 *gu, char *buf, size_t len) | ||||
| { | ||||
| 	size_t	size; | ||||
|  | ||||
| 	size = grid_utf8_size(gu); | ||||
| 	if (size > len) | ||||
| 		fatalx("UTF-8 copy overflow"); | ||||
| 	memcpy(buf, gu->data, size); | ||||
| 	return (size); | ||||
| } | ||||
|  | ||||
| /* Set UTF-8 grid data from input UTF-8. */ | ||||
| void | ||||
| grid_utf8_set(struct grid_utf8 *gu, const struct utf8_data *utf8data) | ||||
| { | ||||
| 	if (utf8data->size == 0) | ||||
| 		fatalx("UTF-8 data empty"); | ||||
| 	if (utf8data->size > sizeof gu->data) | ||||
| 		fatalx("UTF-8 data too long"); | ||||
| 	memcpy(gu->data, utf8data->data, utf8data->size); | ||||
| 	if (utf8data->size != sizeof gu->data) | ||||
| 		gu->data[utf8data->size] = 0xff; | ||||
| 	gu->width = utf8data->width; | ||||
| } | ||||
|  | ||||
| /* Append UTF-8 character onto the cell data (for combined characters). */ | ||||
| int | ||||
| grid_utf8_append(struct grid_utf8 *gu, const struct utf8_data *utf8data) | ||||
| { | ||||
| 	size_t	old_size; | ||||
|  | ||||
| 	old_size = grid_utf8_size(gu); | ||||
| 	if (old_size + utf8data->size > sizeof gu->data) | ||||
| 		return (-1); | ||||
| 	memcpy(gu->data + old_size, utf8data->data, utf8data->size); | ||||
| 	if (old_size + utf8data->size != sizeof gu->data) | ||||
| 		gu->data[old_size + utf8data->size] = 0xff; | ||||
| 	return (0); | ||||
| } | ||||
|  | ||||
| /* Compare two UTF-8 cells. */ | ||||
| int | ||||
| grid_utf8_compare(const struct grid_utf8 *gu1, const struct grid_utf8 *gu2) | ||||
| { | ||||
| 	size_t	size; | ||||
|  | ||||
| 	size = grid_utf8_size(gu1); | ||||
| 	if (size != grid_utf8_size(gu2)) | ||||
| 		return (0); | ||||
| 	if (memcmp(gu1->data, gu2->data, size) != 0) | ||||
| 		return (0); | ||||
| 	return (1); | ||||
| } | ||||
							
								
								
									
										24
									
								
								grid-view.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								grid-view.c
									
									
									
									
									
								
							| @@ -52,28 +52,6 @@ grid_view_set_cell( | ||||
| 	grid_set_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc); | ||||
| } | ||||
|  | ||||
| /* Get UTF-8 for reading. */ | ||||
| const struct grid_utf8 * | ||||
| grid_view_peek_utf8(struct grid *gd, u_int px, u_int py) | ||||
| { | ||||
| 	return (grid_peek_utf8(gd, grid_view_x(gd, px), grid_view_y(gd, py))); | ||||
| } | ||||
|  | ||||
| /* Get UTF-8 for writing. */ | ||||
| struct grid_utf8 * | ||||
| grid_view_get_utf8(struct grid *gd, u_int px, u_int py) | ||||
| { | ||||
| 	return (grid_get_utf8(gd, grid_view_x(gd, px), grid_view_y(gd, py))); | ||||
| } | ||||
|  | ||||
| /* Set UTF-8. */ | ||||
| void | ||||
| grid_view_set_utf8( | ||||
|     struct grid *gd, u_int px, u_int py, const struct grid_utf8 *gu) | ||||
| { | ||||
| 	grid_set_utf8(gd, grid_view_x(gd, px), grid_view_y(gd, py), gu); | ||||
| } | ||||
|  | ||||
| /* Clear into history. */ | ||||
| void | ||||
| grid_view_clear_history(struct grid *gd) | ||||
| @@ -87,7 +65,7 @@ grid_view_clear_history(struct grid *gd) | ||||
| 	last = 0; | ||||
| 	for (yy = 0; yy < gd->sy; yy++) { | ||||
| 		gl = &gd->linedata[grid_view_y(gd, yy)]; | ||||
| 		if (gl->cellsize != 0 || gl->utf8size != 0) | ||||
| 		if (gl->cellsize != 0) | ||||
| 			last = yy + 1; | ||||
| 	} | ||||
| 	if (last == 0) | ||||
|   | ||||
							
								
								
									
										103
									
								
								grid.c
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								grid.c
									
									
									
									
									
								
							| @@ -36,8 +36,8 @@ | ||||
|  */ | ||||
|  | ||||
| /* Default grid cell data. */ | ||||
| const struct grid_cell grid_default_cell = { 0, 0, 8, 8, ' ' }; | ||||
| const struct grid_cell grid_marker_cell = { 0, 0, 8, 8, '_' }; | ||||
| const struct grid_cell grid_default_cell = { 0, 0, 8, 8, (1 << 4) | 1, " " }; | ||||
| const struct grid_cell grid_marker_cell = { 0, 0, 8, 8, (1 << 4) | 1, "_" }; | ||||
|  | ||||
| #define grid_put_cell(gd, px, py, gc) do {			\ | ||||
| 	memcpy(&gd->linedata[py].celldata[px], 			\ | ||||
| @@ -100,7 +100,6 @@ grid_destroy(struct grid *gd) | ||||
| 	for (yy = 0; yy < gd->hsize + gd->sy; yy++) { | ||||
| 		gl = &gd->linedata[yy]; | ||||
| 		free(gl->celldata); | ||||
| 		free(gl->utf8data); | ||||
| 	} | ||||
|  | ||||
| 	free(gd->linedata); | ||||
| @@ -114,7 +113,6 @@ grid_compare(struct grid *ga, struct grid *gb) | ||||
| { | ||||
| 	struct grid_line	*gla, *glb; | ||||
| 	struct grid_cell	*gca, *gcb; | ||||
| 	struct grid_utf8	*gua, *gub; | ||||
| 	u_int			 xx, yy; | ||||
|  | ||||
| 	if (ga->sx != gb->sx || ga->sy != ga->sy) | ||||
| @@ -130,12 +128,6 @@ grid_compare(struct grid *ga, struct grid *gb) | ||||
| 			gcb = &glb->celldata[xx]; | ||||
| 			if (memcmp(gca, gcb, sizeof (struct grid_cell)) != 0) | ||||
| 				return (1); | ||||
| 			if (!(gca->flags & GRID_FLAG_UTF8)) | ||||
| 				continue; | ||||
| 			gua = &gla->utf8data[xx]; | ||||
| 			gub = &glb->utf8data[xx]; | ||||
| 			if (memcmp(gua, gub, sizeof (struct grid_utf8)) != 0) | ||||
| 				return (1); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -233,20 +225,6 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx) | ||||
| 	gl->cellsize = sx; | ||||
| } | ||||
|  | ||||
| /* Expand line to fit to cell for UTF-8. */ | ||||
| void | ||||
| grid_expand_line_utf8(struct grid *gd, u_int py, u_int sx) | ||||
| { | ||||
| 	struct grid_line	*gl; | ||||
|  | ||||
| 	gl = &gd->linedata[py]; | ||||
| 	if (sx <= gl->utf8size) | ||||
| 		return; | ||||
|  | ||||
| 	gl->utf8data = xrealloc(gl->utf8data, sx, sizeof *gl->utf8data); | ||||
| 	gl->utf8size = sx; | ||||
| } | ||||
|  | ||||
| /* Get cell for reading. */ | ||||
| const struct grid_cell * | ||||
| grid_peek_cell(struct grid *gd, u_int px, u_int py) | ||||
| @@ -282,41 +260,6 @@ grid_set_cell( | ||||
| 	grid_put_cell(gd, px, py, gc); | ||||
| } | ||||
|  | ||||
| /* Get UTF-8 for reading. */ | ||||
| const struct grid_utf8 * | ||||
| grid_peek_utf8(struct grid *gd, u_int px, u_int py) | ||||
| { | ||||
| 	if (grid_check_y(gd, py) != 0) | ||||
| 		return (NULL); | ||||
|  | ||||
| 	if (px >= gd->linedata[py].utf8size) | ||||
| 		return (NULL); | ||||
| 	return (&gd->linedata[py].utf8data[px]); | ||||
| } | ||||
|  | ||||
| /* Get utf8 at relative position (for writing). */ | ||||
| struct grid_utf8 * | ||||
| grid_get_utf8(struct grid *gd, u_int px, u_int py) | ||||
| { | ||||
| 	if (grid_check_y(gd, py) != 0) | ||||
| 		return (NULL); | ||||
|  | ||||
| 	grid_expand_line_utf8(gd, py, px + 1); | ||||
| 	return (&gd->linedata[py].utf8data[px]); | ||||
| } | ||||
|  | ||||
| /* Set utf8 at relative position. */ | ||||
| void | ||||
| grid_set_utf8( | ||||
|     struct grid *gd, u_int px, u_int py, const struct grid_utf8 *gc) | ||||
| { | ||||
| 	if (grid_check_y(gd, py) != 0) | ||||
| 		return; | ||||
|  | ||||
| 	grid_expand_line_utf8(gd, py, px + 1); | ||||
| 	grid_put_utf8(gd, px, py, gc); | ||||
| } | ||||
|  | ||||
| /* Clear area. */ | ||||
| void | ||||
| grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny) | ||||
| @@ -373,7 +316,6 @@ grid_clear_lines(struct grid *gd, u_int py, u_int ny) | ||||
| 	for (yy = py; yy < py + ny; yy++) { | ||||
| 		gl = &gd->linedata[yy]; | ||||
| 		free(gl->celldata); | ||||
| 		free(gl->utf8data); | ||||
| 		memset(gl, 0, sizeof *gl); | ||||
| 	} | ||||
| } | ||||
| @@ -437,13 +379,6 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx) | ||||
| 	memmove( | ||||
| 	    &gl->celldata[dx], &gl->celldata[px], nx * sizeof *gl->celldata); | ||||
|  | ||||
| 	if (gl->utf8data != NULL) { | ||||
| 		grid_expand_line_utf8(gd, py, px + nx); | ||||
| 		grid_expand_line_utf8(gd, py, dx + nx); | ||||
| 		memmove(&gl->utf8data[dx], | ||||
| 		    &gl->utf8data[px], nx * sizeof *gl->utf8data); | ||||
| 	} | ||||
|  | ||||
| 	/* Wipe any cells that have been moved. */ | ||||
| 	for (xx = px; xx < px + nx; xx++) { | ||||
| 		if (xx >= dx && xx < dx + nx) | ||||
| @@ -457,9 +392,9 @@ 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; | ||||
| 	struct utf8_data	 ud; | ||||
| 	char			*buf; | ||||
| 	size_t			 len, off, size; | ||||
| 	size_t			 len, off; | ||||
| 	u_int			 xx; | ||||
|  | ||||
| 	GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx); | ||||
| @@ -472,25 +407,15 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx) | ||||
| 		gc = grid_peek_cell(gd, xx, py); | ||||
| 		if (gc->flags & GRID_FLAG_PADDING) | ||||
| 			continue; | ||||
| 		grid_cell_get(gc, &ud); | ||||
|  | ||||
| 		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 (len < off + ud.size + 1) { | ||||
| 			buf = xrealloc(buf, 2, len); | ||||
| 			len *= 2; | ||||
| 		} | ||||
|  | ||||
| 		memcpy(buf + off, ud.data, ud.size); | ||||
| 		off += ud.size; | ||||
| 	} | ||||
|  | ||||
| 	while (off > 0 && buf[off - 1] == ' ') | ||||
| @@ -530,12 +455,6 @@ grid_duplicate_lines( | ||||
| 			memcpy(dstl->celldata, srcl->celldata, | ||||
| 			    srcl->cellsize * sizeof *dstl->celldata); | ||||
| 		} | ||||
| 		if (srcl->utf8size != 0) { | ||||
| 			dstl->utf8data = xcalloc( | ||||
| 			    srcl->utf8size, sizeof *dstl->utf8data); | ||||
| 			memcpy(dstl->utf8data, srcl->utf8data, | ||||
| 			    srcl->utf8size * sizeof *dstl->utf8data); | ||||
| 		} | ||||
|  | ||||
| 		sy++; | ||||
| 		dy++; | ||||
|   | ||||
							
								
								
									
										9
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								input.c
									
									
									
									
									
								
							| @@ -879,8 +879,8 @@ input_clear(struct input_ctx *ictx) | ||||
| int | ||||
| input_print(struct input_ctx *ictx) | ||||
| { | ||||
| 	ictx->cell.data = ictx->ch; | ||||
| 	screen_write_cell(&ictx->ctx, &ictx->cell, NULL); | ||||
| 	grid_cell_one(&ictx->cell, ictx->ch); | ||||
| 	screen_write_cell(&ictx->ctx, &ictx->cell); | ||||
|  | ||||
| 	return (0); | ||||
| } | ||||
| @@ -1657,9 +1657,8 @@ input_utf8_close(struct input_ctx *ictx) | ||||
|  | ||||
| 	utf8_append(&ictx->utf8data, ictx->ch); | ||||
|  | ||||
| 	ictx->cell.flags |= GRID_FLAG_UTF8; | ||||
| 	screen_write_cell(&ictx->ctx, &ictx->cell, &ictx->utf8data); | ||||
| 	ictx->cell.flags &= ~GRID_FLAG_UTF8; | ||||
| 	grid_cell_set(&ictx->cell, &ictx->utf8data); | ||||
| 	screen_write_cell(&ictx->ctx, &ictx->cell); | ||||
|  | ||||
| 	return (0); | ||||
| } | ||||
|   | ||||
							
								
								
									
										108
									
								
								screen-write.c
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								screen-write.c
									
									
									
									
									
								
							| @@ -67,11 +67,10 @@ screen_write_reset(struct screen_write_ctx *ctx) | ||||
|  | ||||
| /* Write character. */ | ||||
| void | ||||
| screen_write_putc( | ||||
|     struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch) | ||||
| screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch) | ||||
| { | ||||
| 	gc->data = ch; | ||||
| 	screen_write_cell(ctx, gc, NULL); | ||||
| 	grid_cell_one(gc, ch); | ||||
| 	screen_write_cell(ctx, gc); | ||||
| } | ||||
|  | ||||
| /* Calculate string length, with embedded formatting. */ | ||||
| @@ -203,9 +202,8 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen, | ||||
| 			} | ||||
| 			size += utf8data.width; | ||||
|  | ||||
| 			gc->flags |= GRID_FLAG_UTF8; | ||||
| 			screen_write_cell(ctx, gc, &utf8data); | ||||
| 			gc->flags &= ~GRID_FLAG_UTF8; | ||||
| 			grid_cell_set(gc, &utf8data); | ||||
| 			screen_write_cell(ctx, gc); | ||||
| 		} else { | ||||
| 			if (maxlen > 0 && size + 1 > (size_t) maxlen) | ||||
| 				break; | ||||
| @@ -277,9 +275,8 @@ screen_write_cnputs(struct screen_write_ctx *ctx, | ||||
| 			} | ||||
| 			size += utf8data.width; | ||||
|  | ||||
| 			lgc.flags |= GRID_FLAG_UTF8; | ||||
| 			screen_write_cell(ctx, &lgc, &utf8data); | ||||
| 			lgc.flags &= ~GRID_FLAG_UTF8; | ||||
| 			grid_cell_set(&lgc, &utf8data); | ||||
| 			screen_write_cell(ctx, &lgc); | ||||
| 		} else { | ||||
| 			if (maxlen > 0 && size + 1 > (size_t) maxlen) | ||||
| 				break; | ||||
| @@ -385,8 +382,7 @@ screen_write_copy(struct screen_write_ctx *ctx, | ||||
| 	struct grid		*gd = src->grid; | ||||
| 	struct grid_line	*gl; | ||||
| 	const struct grid_cell	*gc; | ||||
| 	const struct grid_utf8	*gu; | ||||
| 	struct utf8_data	 utf8data; | ||||
| 	struct utf8_data	 ud; | ||||
| 	u_int		 	 xx, yy, cx, cy, ax, bx; | ||||
|  | ||||
| 	cx = s->cx; | ||||
| @@ -414,16 +410,8 @@ screen_write_copy(struct screen_write_ctx *ctx, | ||||
| 					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); | ||||
| 				grid_cell_get(gc, &ud); | ||||
| 				screen_write_cell(ctx, gc); | ||||
| 			} | ||||
| 			if (px + nx == gd->sx && px + nx > gl->cellsize) | ||||
| 				screen_write_clearendofline(ctx); | ||||
| @@ -442,7 +430,6 @@ screen_write_initctx( | ||||
| 	struct screen		*s = ctx->s; | ||||
| 	struct grid		*gd = s->grid; | ||||
| 	const struct grid_cell	*gc; | ||||
| 	const struct grid_utf8	*gu; | ||||
| 	u_int			 xx; | ||||
|  | ||||
| 	ttyctx->wp = ctx->wp; | ||||
| @@ -465,10 +452,6 @@ screen_write_initctx( | ||||
| 	} | ||||
| 	ttyctx->last_width = xx; | ||||
| 	memcpy(&ttyctx->last_cell, gc, sizeof ttyctx->last_cell); | ||||
| 	if (gc->flags & GRID_FLAG_UTF8) { | ||||
| 		gu = grid_view_peek_utf8(gd, screen_size_x(s) - xx, s->cy); | ||||
| 		memcpy(&ttyctx->last_utf8, gu, sizeof ttyctx->last_utf8); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Cursor up by ny. */ | ||||
| @@ -584,7 +567,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx) | ||||
| 	screen_write_initctx(ctx, &ttyctx, 0); | ||||
|  | ||||
| 	memcpy(&gc, &grid_default_cell, sizeof gc); | ||||
| 	gc.data = 'E'; | ||||
| 	grid_cell_one(&gc, 'E'); | ||||
|  | ||||
| 	for (yy = 0; yy < screen_size_y(s); yy++) { | ||||
| 		for (xx = 0; xx < screen_size_x(s); xx++) | ||||
| @@ -1066,26 +1049,20 @@ screen_write_clearhistory(struct screen_write_ctx *ctx) | ||||
|  | ||||
| /* Write cell data. */ | ||||
| void | ||||
| screen_write_cell(struct screen_write_ctx *ctx, | ||||
|     const struct grid_cell *gc, const struct utf8_data *utf8data) | ||||
| 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; | ||||
| 	struct grid_utf8	 gu; | ||||
| 	u_int		 	 width, xx; | ||||
| 	struct grid_cell 	 tmp_gc, *tmp_gcp; | ||||
| 	struct utf8_data	 ud; | ||||
| 	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; | ||||
| 	width = grid_cell_width(gc); | ||||
|  | ||||
| 	/* | ||||
| 	 * If this is a wide character and there is no room on the screen, for | ||||
| @@ -1102,7 +1079,8 @@ screen_write_cell(struct screen_write_ctx *ctx, | ||||
| 	 * there is space. | ||||
| 	 */ | ||||
| 	if (width == 0) { | ||||
| 		if (screen_write_combine(ctx, utf8data) == 0) { | ||||
| 		grid_cell_get(gc, &ud); | ||||
| 		if (screen_write_combine(ctx, &ud) == 0) { | ||||
| 			screen_write_initctx(ctx, &ttyctx, 0); | ||||
| 			tty_write(tty_cmd_utf8character, &ttyctx); | ||||
| 		} | ||||
| @@ -1145,11 +1123,6 @@ screen_write_cell(struct screen_write_ctx *ctx, | ||||
|  | ||||
| 	/* 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; | ||||
| @@ -1159,12 +1132,11 @@ screen_write_cell(struct screen_write_ctx *ctx, | ||||
| 		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); | ||||
| 		grid_cell_get(gc, &ud); | ||||
| 		grid_cell_set(&tmp_gc, &ud); | ||||
| 		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; | ||||
| @@ -1177,49 +1149,33 @@ screen_write_cell(struct screen_write_ctx *ctx, | ||||
|  | ||||
| /* Combine a UTF-8 zero-width character onto the previous. */ | ||||
| int | ||||
| screen_write_combine( | ||||
|     struct screen_write_ctx *ctx, const struct utf8_data *utf8data) | ||||
| 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 grid_utf8	*gu, tmp_gu; | ||||
| 	u_int			 i; | ||||
| 	struct utf8_data	 ud1; | ||||
|  | ||||
| 	/* Can't combine if at 0. */ | ||||
| 	if (s->cx == 0) | ||||
| 		return (-1); | ||||
|  | ||||
| 	/* Empty utf8data is out. */ | ||||
| 	if (utf8data->size == 0) | ||||
| 	/* Empty data is out. */ | ||||
| 	if (ud->size == 0) | ||||
| 		fatalx("UTF-8 data empty"); | ||||
|  | ||||
| 	/* Retrieve the previous cell and convert to UTF-8 if not already. */ | ||||
| 	/* Retrieve the previous cell. */ | ||||
| 	gc = grid_view_get_cell(gd, s->cx - 1, s->cy); | ||||
| 	if (!(gc->flags & GRID_FLAG_UTF8)) { | ||||
| 		tmp_gu.data[0] = gc->data; | ||||
| 		tmp_gu.data[1] = 0xff; | ||||
| 		tmp_gu.width = 1; | ||||
| 	grid_cell_get(gc, &ud1); | ||||
|  | ||||
| 		grid_view_set_utf8(gd, s->cx - 1, s->cy, &tmp_gu); | ||||
| 		gc->flags |= GRID_FLAG_UTF8; | ||||
| 	} | ||||
| 	/* Check there is enough space. */ | ||||
| 	if (ud1.size + ud->size > sizeof ud1.data) | ||||
| 		return (-1); | ||||
|  | ||||
| 	/* Append the current cell. */ | ||||
| 	gu = grid_view_get_utf8(gd, s->cx - 1, s->cy); | ||||
| 	if (grid_utf8_append(gu, utf8data) != 0) { | ||||
| 		/* Failed: scrap this character and replace with underscores. */ | ||||
| 		if (gu->width == 1) { | ||||
| 			gc->data = '_'; | ||||
| 			gc->flags &= ~GRID_FLAG_UTF8; | ||||
| 		} else { | ||||
| 			for (i = 0; i < gu->width && i != sizeof gu->data; i++) | ||||
| 				gu->data[i] = '_'; | ||||
| 			if (i != sizeof gu->data) | ||||
| 				gu->data[i] = 0xff; | ||||
| 			gu->width = i; | ||||
| 		} | ||||
| 	} | ||||
| 	/* 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); | ||||
|  | ||||
| 	return (0); | ||||
| } | ||||
|   | ||||
							
								
								
									
										49
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -669,13 +669,7 @@ struct mode_key_table { | ||||
|  | ||||
| #define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ANY) | ||||
|  | ||||
| /* | ||||
|  * A single UTF-8 character. | ||||
|  * | ||||
|  * The data member in this must be UTF8_SIZE to allow screen_write_copy to | ||||
|  * reinject stored UTF-8 data back into screen_write_cell after combining (ugh | ||||
|  * XXX XXX). | ||||
|  */ | ||||
| /* A single UTF-8 character. */ | ||||
| struct utf8_data { | ||||
| 	u_char	data[UTF8_SIZE]; | ||||
|  | ||||
| @@ -709,7 +703,6 @@ struct utf8_data { | ||||
| #define GRID_FLAG_FG256 0x1 | ||||
| #define GRID_FLAG_BG256 0x2 | ||||
| #define GRID_FLAG_PADDING 0x4 | ||||
| #define GRID_FLAG_UTF8 0x8 | ||||
|  | ||||
| /* Grid line flags. */ | ||||
| #define GRID_LINE_WRAPPED 0x1 | ||||
| @@ -720,13 +713,9 @@ struct grid_cell { | ||||
| 	u_char	flags; | ||||
| 	u_char	fg; | ||||
| 	u_char	bg; | ||||
| 	u_char	data; | ||||
| } __packed; | ||||
|  | ||||
| /* Grid cell UTF-8 data. Used instead of data in grid_cell for UTF-8 cells. */ | ||||
| struct grid_utf8 { | ||||
| 	u_char	width; | ||||
| 	u_char	data[UTF8_SIZE]; | ||||
| 	u_char	xstate; /* top 4 bits width, bottom 4 bits size */ | ||||
| 	u_char	xdata[UTF8_SIZE]; | ||||
| } __packed; | ||||
|  | ||||
| /* Grid line. */ | ||||
| @@ -734,9 +723,6 @@ struct grid_line { | ||||
| 	u_int	cellsize; | ||||
| 	struct grid_cell *celldata; | ||||
|  | ||||
| 	u_int	utf8size; | ||||
| 	struct grid_utf8 *utf8data; | ||||
|  | ||||
| 	int	flags; | ||||
| } __packed; | ||||
|  | ||||
| @@ -1233,7 +1219,6 @@ struct tty_ctx { | ||||
| 	struct window_pane *wp; | ||||
|  | ||||
| 	const struct grid_cell *cell; | ||||
| 	const struct grid_utf8 *utf8; | ||||
|  | ||||
| 	u_int		 num; | ||||
| 	void		*ptr; | ||||
| @@ -1254,7 +1239,6 @@ struct tty_ctx { | ||||
|  | ||||
| 	/* Saved last cell on line. */ | ||||
| 	struct grid_cell last_cell; | ||||
| 	struct grid_utf8 last_utf8; | ||||
| 	u_int		 last_width; | ||||
| }; | ||||
|  | ||||
| @@ -1623,10 +1607,11 @@ void	tty_putcode(struct tty *, enum tty_code_code); | ||||
| void	tty_putcode1(struct tty *, enum tty_code_code, int); | ||||
| void	tty_putcode2(struct tty *, enum tty_code_code, int, int); | ||||
| void	tty_putcode_ptr1(struct tty *, enum tty_code_code, const void *); | ||||
| void	tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *, const void *); | ||||
| void	tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *, | ||||
| 	    const void *); | ||||
| void	tty_puts(struct tty *, const char *); | ||||
| void	tty_putc(struct tty *, u_char); | ||||
| void	tty_pututf8(struct tty *, const struct grid_utf8 *); | ||||
| void	tty_putn(struct tty *, const void *, size_t, u_int); | ||||
| void	tty_init(struct tty *, struct client *, int, char *); | ||||
| int	tty_resize(struct tty *); | ||||
| int	tty_set_size(struct tty *, u_int, u_int); | ||||
| @@ -1969,13 +1954,9 @@ void	 grid_collect_history(struct grid *); | ||||
| void	 grid_scroll_history(struct grid *); | ||||
| void	 grid_scroll_history_region(struct grid *, u_int, u_int); | ||||
| void	 grid_expand_line(struct grid *, u_int, u_int); | ||||
| void	 grid_expand_line_utf8(struct grid *, u_int, u_int); | ||||
| const struct grid_cell *grid_peek_cell(struct grid *, u_int, u_int); | ||||
| struct grid_cell *grid_get_cell(struct grid *, u_int, u_int); | ||||
| void	 grid_set_cell(struct grid *, u_int, u_int, const struct grid_cell *); | ||||
| const struct grid_utf8 *grid_peek_utf8(struct grid *, u_int, u_int); | ||||
| struct grid_utf8 *grid_get_utf8(struct grid *, u_int, u_int); | ||||
| void	 grid_set_utf8(struct grid *, u_int, u_int, const struct grid_utf8 *); | ||||
| void	 grid_clear(struct grid *, u_int, u_int, u_int, u_int); | ||||
| void	 grid_clear_lines(struct grid *, u_int, u_int); | ||||
| void	 grid_move_lines(struct grid *, u_int, u_int, u_int); | ||||
| @@ -1984,22 +1965,17 @@ char	*grid_string_cells(struct grid *, u_int, u_int, u_int); | ||||
| void	 grid_duplicate_lines( | ||||
| 	     struct grid *, u_int, struct grid *, u_int, u_int); | ||||
|  | ||||
| /* grid-utf8.c */ | ||||
| size_t	 grid_utf8_size(const struct grid_utf8 *); | ||||
| size_t	 grid_utf8_copy(const struct grid_utf8 *, char *, size_t); | ||||
| void	 grid_utf8_set(struct grid_utf8 *, const struct utf8_data *); | ||||
| int	 grid_utf8_append(struct grid_utf8 *, const struct utf8_data *); | ||||
| int	 grid_utf8_compare(const struct grid_utf8 *, const struct grid_utf8 *); | ||||
| /* 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 *); | ||||
| const struct grid_utf8 *grid_view_peek_utf8(struct grid *, u_int, u_int); | ||||
| struct grid_utf8 *grid_view_get_utf8(struct grid *, u_int, u_int); | ||||
| void	 grid_view_set_utf8( | ||||
| 	     struct grid *, u_int, u_int, const struct grid_utf8 *); | ||||
| 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); | ||||
| @@ -2064,8 +2040,7 @@ void	 screen_write_clearendofscreen(struct screen_write_ctx *); | ||||
| void	 screen_write_clearstartofscreen(struct screen_write_ctx *); | ||||
| void	 screen_write_clearscreen(struct screen_write_ctx *); | ||||
| void	 screen_write_clearhistory(struct screen_write_ctx *); | ||||
| void	 screen_write_cell(struct screen_write_ctx *, | ||||
| 	     const struct grid_cell *, const struct utf8_data *); | ||||
| void	 screen_write_cell(struct screen_write_ctx *, const struct grid_cell *); | ||||
| void	 screen_write_setselection(struct screen_write_ctx *, u_char *, u_int); | ||||
| void	 screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int); | ||||
| void	 screen_write_bracketpaste(struct screen_write_ctx *, int); | ||||
|   | ||||
							
								
								
									
										68
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								tty.c
									
									
									
									
									
								
							| @@ -48,8 +48,7 @@ void	tty_redraw_region(struct tty *, const struct tty_ctx *); | ||||
| void	tty_emulate_repeat( | ||||
| 	    struct tty *, enum tty_code_code, enum tty_code_code, u_int); | ||||
| void	tty_repeat_space(struct tty *, u_int); | ||||
| void	tty_cell(struct tty *, | ||||
| 	    const struct grid_cell *, const struct grid_utf8 *); | ||||
| void	tty_cell(struct tty *, const struct grid_cell *); | ||||
|  | ||||
| #define tty_use_acs(tty) \ | ||||
| 	(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) | ||||
| @@ -416,15 +415,12 @@ tty_putc(struct tty *tty, u_char ch) | ||||
| } | ||||
|  | ||||
| void | ||||
| tty_pututf8(struct tty *tty, const struct grid_utf8 *gu) | ||||
| tty_putn(struct tty *tty, const void *buf, size_t len, u_int width) | ||||
| { | ||||
| 	size_t	size; | ||||
|  | ||||
| 	size = grid_utf8_size(gu); | ||||
| 	bufferevent_write(tty->event, gu->data, size); | ||||
| 	bufferevent_write(tty->event, buf, len); | ||||
| 	if (tty->log_fd != -1) | ||||
| 		write(tty->log_fd, gu->data, size); | ||||
| 	tty->cx += gu->width; | ||||
| 		write(tty->log_fd, buf, len); | ||||
| 	tty->cx += width; | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -582,7 +578,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) | ||||
| 	const struct grid_cell	*gc; | ||||
| 	struct grid_line	*gl; | ||||
| 	struct grid_cell	 tmpgc; | ||||
| 	const struct grid_utf8	*gu; | ||||
| 	struct utf8_data	 ud; | ||||
| 	u_int			 i, sx; | ||||
|  | ||||
| 	tty_update_mode(tty, tty->mode & ~MODE_CURSOR, s); | ||||
| @@ -607,21 +603,17 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) | ||||
|  | ||||
| 	for (i = 0; i < sx; i++) { | ||||
| 		gc = grid_view_peek_cell(s->grid, i, py); | ||||
|  | ||||
| 		gu = NULL; | ||||
| 		if (gc->flags & GRID_FLAG_UTF8) | ||||
| 			gu = grid_view_peek_utf8(s->grid, i, py); | ||||
|  | ||||
| 		if (screen_check_selection(s, i, py)) { | ||||
| 			memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc); | ||||
| 			tmpgc.data = gc->data; | ||||
| 			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 & | ||||
| 			    (GRID_FLAG_FG256|GRID_FLAG_BG256); | ||||
| 			tty_cell(tty, &tmpgc, gu); | ||||
| 			tty_cell(tty, &tmpgc); | ||||
| 		} else | ||||
| 			tty_cell(tty, gc, gu); | ||||
| 			tty_cell(tty, gc); | ||||
| 	} | ||||
|  | ||||
| 	if (sx >= tty->sx) { | ||||
| @@ -984,17 +976,11 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) | ||||
| 	struct screen		*s = wp->screen; | ||||
| 	u_int			 cx; | ||||
| 	u_int			 width; | ||||
| 	const struct grid_cell	*gc = ctx->cell; | ||||
| 	const struct grid_utf8	*gu = ctx->utf8; | ||||
|  | ||||
| 	if (gc->flags & GRID_FLAG_UTF8) | ||||
| 		width = gu->width; | ||||
| 	else | ||||
| 		width = 1; | ||||
|  | ||||
| 	tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); | ||||
|  | ||||
| 	/* Is the cursor in the very last position? */ | ||||
| 	width = grid_cell_width(ctx->cell); | ||||
| 	if (ctx->ocx > wp->sx - width) { | ||||
| 		if (ctx->xoff != 0 || wp->sx != tty->sx) { | ||||
| 			/* | ||||
| @@ -1011,17 +997,14 @@ 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. | ||||
| 			 */ | ||||
| 			if (ctx->last_cell.flags & GRID_FLAG_UTF8) | ||||
| 				cx = screen_size_x(s) - ctx->last_utf8.width; | ||||
| 			else | ||||
| 				cx = screen_size_x(s) - 1; | ||||
| 			cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell); | ||||
| 			tty_cursor_pane(tty, ctx, cx, ctx->ocy); | ||||
| 			tty_cell(tty, &ctx->last_cell, &ctx->last_utf8); | ||||
| 			tty_cell(tty, &ctx->last_cell); | ||||
| 		} | ||||
| 	} else | ||||
| 		tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); | ||||
|  | ||||
| 	tty_cell(tty, ctx->cell, ctx->utf8); | ||||
| 	tty_cell(tty, ctx->cell); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1071,10 +1054,10 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx) | ||||
| } | ||||
|  | ||||
| void | ||||
| tty_cell( | ||||
|     struct tty *tty, const struct grid_cell *gc, const struct grid_utf8 *gu) | ||||
| tty_cell(struct tty *tty, const struct grid_cell *gc) | ||||
| { | ||||
| 	u_int	i; | ||||
| 	struct utf8_data	ud; | ||||
| 	u_int			i; | ||||
|  | ||||
| 	/* Skip last character if terminal is stupid. */ | ||||
| 	if (tty->term->flags & TERM_EARLYWRAP && | ||||
| @@ -1088,23 +1071,24 @@ tty_cell( | ||||
| 	/* Set the attributes. */ | ||||
| 	tty_attributes(tty, gc); | ||||
|  | ||||
| 	/* If not UTF-8, write directly. */ | ||||
| 	if (!(gc->flags & GRID_FLAG_UTF8)) { | ||||
| 		if (gc->data < 0x20 || gc->data == 0x7f) | ||||
| 	/* 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) | ||||
| 			return; | ||||
| 		tty_putc(tty, gc->data); | ||||
| 		tty_putc(tty, *ud.data); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* If the terminal doesn't support UTF-8, write underscores. */ | ||||
| 	/* If not UTF-8, write _. */ | ||||
| 	if (!(tty->flags & TTY_UTF8)) { | ||||
| 		for (i = 0; i < gu->width; i++) | ||||
| 		for (i = 0; i < ud.width; i++) | ||||
| 			tty_putc(tty, '_'); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* Otherwise, write UTF-8. */ | ||||
| 	tty_pututf8(tty, gu); | ||||
| 	/* Write the data. */ | ||||
| 	tty_putn(tty, ud.data, ud.size, ud.width); | ||||
| } | ||||
|  | ||||
| void | ||||
|   | ||||
| @@ -908,24 +908,16 @@ window_copy_search_compare( | ||||
|     struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx) | ||||
| { | ||||
| 	const struct grid_cell	*gc, *sgc; | ||||
| 	const struct grid_utf8	*gu, *sgu; | ||||
| 	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); | ||||
|  | ||||
| 	if ((gc->flags & GRID_FLAG_UTF8) != (sgc->flags & GRID_FLAG_UTF8)) | ||||
| 	if (ud.size != sud.size || ud.width != sud.width) | ||||
| 		return (0); | ||||
|  | ||||
| 	if (gc->flags & GRID_FLAG_UTF8) { | ||||
| 		gu = grid_peek_utf8(gd, px, py); | ||||
| 		sgu = grid_peek_utf8(sgd, spx, 0); | ||||
| 		if (grid_utf8_compare(gu, sgu)) | ||||
| 			return (1); | ||||
| 	} else { | ||||
| 		if (gc->data == sgc->data) | ||||
| 			return (1); | ||||
| 	} | ||||
| 	return (0); | ||||
| 	return (memcmp(ud.data, sud.data, ud.size) == 0); | ||||
| } | ||||
|  | ||||
| int | ||||
| @@ -1395,10 +1387,9 @@ window_copy_copy_line(struct window_pane *wp, | ||||
| 	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; | ||||
| 	struct utf8_data		 ud; | ||||
| 	u_int				 i, xx, wrapped = 0; | ||||
| 	size_t				 size; | ||||
|  | ||||
| 	if (sx > ex) | ||||
| 		return; | ||||
| @@ -1426,15 +1417,11 @@ window_copy_copy_line(struct window_pane *wp, | ||||
| 			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); | ||||
| 			} | ||||
| 			grid_cell_get(gc, &ud); | ||||
|  | ||||
| 			*buf = xrealloc(*buf, 1, (*off) + ud.size); | ||||
| 			memcpy(*buf + *off, ud.data, ud.size); | ||||
| 			*off += ud.size; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -1464,13 +1451,15 @@ 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; | ||||
|  | ||||
| 	gc = grid_peek_cell(data->backing->grid, px, py); | ||||
| 	if (gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) | ||||
| 	grid_cell_get(gc, &ud); | ||||
| 	if (ud.size != 1 || gc->flags & GRID_FLAG_PADDING) | ||||
| 		return (0); | ||||
| 	if (gc->data == 0x00 || gc->data == 0x7f) | ||||
| 	if (*ud.data == 0x00 || *ud.data == 0x7f) | ||||
| 		return (0); | ||||
| 	return (strchr(set, gc->data) != NULL); | ||||
| 	return (strchr(set, *ud.data) != NULL); | ||||
| } | ||||
|  | ||||
| u_int | ||||
| @@ -1479,6 +1468,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; | ||||
| 	u_int				 px; | ||||
|  | ||||
| 	/* | ||||
| @@ -1492,9 +1482,8 @@ window_copy_find_length(struct window_pane *wp, u_int py) | ||||
| 		px = screen_size_x(s); | ||||
| 	while (px > 0) { | ||||
| 		gc = grid_peek_cell(s->grid, px - 1, py); | ||||
| 		if (gc->flags & GRID_FLAG_UTF8) | ||||
| 			break; | ||||
| 		if (gc->data != ' ') | ||||
| 		grid_cell_get(gc, &ud); | ||||
| 		if (ud.size != 1 || *ud.data != ' ') | ||||
| 			break; | ||||
| 		px--; | ||||
| 	} | ||||
| @@ -1527,6 +1516,7 @@ 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; | ||||
|  | ||||
| 	px = 0; | ||||
| 	py = screen_hsize(data->backing) + data->cy - data->oy; | ||||
| @@ -1534,9 +1524,8 @@ window_copy_cursor_back_to_indentation(struct window_pane *wp) | ||||
|  | ||||
| 	while (px < xx) { | ||||
| 		gc = grid_peek_cell(data->backing->grid, px, py); | ||||
| 		if (gc->flags & GRID_FLAG_UTF8) | ||||
| 			break; | ||||
| 		if (gc->data != ' ') | ||||
| 		grid_cell_get(gc, &ud); | ||||
| 		if (ud.size != 1 || *ud.data != ' ') | ||||
| 			break; | ||||
| 		px++; | ||||
| 	} | ||||
| @@ -1696,6 +1685,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; | ||||
| 	u_int				 px, py, xx; | ||||
|  | ||||
| 	px = data->cx + 1; | ||||
| @@ -1704,9 +1694,9 @@ window_copy_cursor_jump(struct window_pane *wp) | ||||
|  | ||||
| 	while (px < xx) { | ||||
| 		gc = grid_peek_cell(back_s->grid, px, py); | ||||
| 		if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0 | ||||
| 		    && gc->data == data->jumpchar) { | ||||
|  | ||||
| 		grid_cell_get(gc, &ud); | ||||
| 		if (!(gc->flags & GRID_FLAG_PADDING) && | ||||
| 		    ud.size == 1 && *ud.data == data->jumpchar) { | ||||
| 			window_copy_update_cursor(wp, px, data->cy); | ||||
| 			if (window_copy_update_selection(wp)) | ||||
| 				window_copy_redraw_lines(wp, data->cy, 1); | ||||
| @@ -1722,6 +1712,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; | ||||
| 	u_int				 px, py; | ||||
|  | ||||
| 	px = data->cx; | ||||
| @@ -1732,9 +1723,9 @@ window_copy_cursor_jump_back(struct window_pane *wp) | ||||
|  | ||||
| 	for (;;) { | ||||
| 		gc = grid_peek_cell(back_s->grid, px, py); | ||||
| 		if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0 | ||||
| 		    && gc->data == data->jumpchar) { | ||||
|  | ||||
| 		grid_cell_get(gc, &ud); | ||||
| 		if (!(gc->flags & GRID_FLAG_PADDING) && | ||||
| 		    ud.size == 1 && *ud.data == data->jumpchar) { | ||||
| 			window_copy_update_cursor(wp, px, data->cy); | ||||
| 			if (window_copy_update_selection(wp)) | ||||
| 				window_copy_redraw_lines(wp, data->cy, 1); | ||||
| @@ -1752,6 +1743,7 @@ window_copy_cursor_jump_to(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; | ||||
| 	u_int				 px, py, xx; | ||||
|  | ||||
| 	px = data->cx + 1; | ||||
| @@ -1760,9 +1752,9 @@ window_copy_cursor_jump_to(struct window_pane *wp) | ||||
|  | ||||
| 	while (px < xx) { | ||||
| 		gc = grid_peek_cell(back_s->grid, px, py); | ||||
| 		if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0 | ||||
| 		    && gc->data == data->jumpchar) { | ||||
|  | ||||
| 		grid_cell_get(gc, &ud); | ||||
| 		if (!(gc->flags & GRID_FLAG_PADDING) && | ||||
| 		    ud.size == 1 && *ud.data == data->jumpchar) { | ||||
| 			window_copy_update_cursor(wp, px - 1, data->cy); | ||||
| 			if (window_copy_update_selection(wp)) | ||||
| 				window_copy_redraw_lines(wp, data->cy, 1); | ||||
| @@ -1778,6 +1770,7 @@ window_copy_cursor_jump_to_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; | ||||
| 	u_int				 px, py; | ||||
|  | ||||
| 	px = data->cx; | ||||
| @@ -1788,9 +1781,9 @@ window_copy_cursor_jump_to_back(struct window_pane *wp) | ||||
|  | ||||
| 	for (;;) { | ||||
| 		gc = grid_peek_cell(back_s->grid, px, py); | ||||
| 		if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0 | ||||
| 		    && gc->data == data->jumpchar) { | ||||
|  | ||||
| 		grid_cell_get(gc, &ud); | ||||
| 		if (!(gc->flags & GRID_FLAG_PADDING) && | ||||
| 		    ud.size == 1 && *ud.data == data->jumpchar) { | ||||
| 			window_copy_update_cursor(wp, px + 1, data->cy); | ||||
| 			if (window_copy_update_selection(wp)) | ||||
| 				window_copy_redraw_lines(wp, data->cy, 1); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Nicholas Marriott
					Nicholas Marriott