mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Add an option to set the pane border lines style from a choice of single
lines (ACS or UTF-8), double or heavy (UTF-8), simple (plain ASCII) or number (the pane numbers). Lines that won't work on a non-UTF-8 terminal are translated back into ACS when they are output.
This commit is contained in:
		@@ -600,7 +600,8 @@ format_draw(struct screen_write_ctx *octx, const struct grid_cell *base,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		/* If this style pushed or popped the default, update it. */
 | 
							/* If this style pushed or popped the default, update it. */
 | 
				
			||||||
		if (sy.default_type == STYLE_DEFAULT_PUSH) {
 | 
							if (sy.default_type == STYLE_DEFAULT_PUSH) {
 | 
				
			||||||
			memcpy(¤t_default, &saved_sy.gc, sizeof current_default);
 | 
								memcpy(¤t_default, &saved_sy.gc,
 | 
				
			||||||
 | 
								    sizeof current_default);
 | 
				
			||||||
			sy.default_type = STYLE_DEFAULT_BASE;
 | 
								sy.default_type = STYLE_DEFAULT_BASE;
 | 
				
			||||||
		} else if (sy.default_type == STYLE_DEFAULT_POP) {
 | 
							} else if (sy.default_type == STYLE_DEFAULT_POP) {
 | 
				
			||||||
			memcpy(¤t_default, base, sizeof current_default);
 | 
								memcpy(¤t_default, base, sizeof current_default);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,6 +60,9 @@ static const char *options_table_visual_bell_list[] = {
 | 
				
			|||||||
static const char *options_table_pane_status_list[] = {
 | 
					static const char *options_table_pane_status_list[] = {
 | 
				
			||||||
	"off", "top", "bottom", NULL
 | 
						"off", "top", "bottom", NULL
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					static const char *options_table_pane_lines_list[] = {
 | 
				
			||||||
 | 
						"single", "double", "heavy", "simple", "number", NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
static const char *options_table_set_clipboard_list[] = {
 | 
					static const char *options_table_set_clipboard_list[] = {
 | 
				
			||||||
	"off", "external", "on", NULL
 | 
						"off", "external", "on", NULL
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -904,6 +907,14 @@ const struct options_table_entry options_table[] = {
 | 
				
			|||||||
	  .text = "Format of text in the pane status lines."
 | 
						  .text = "Format of text in the pane status lines."
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{ .name = "pane-border-lines",
 | 
				
			||||||
 | 
						  .type = OPTIONS_TABLE_CHOICE,
 | 
				
			||||||
 | 
						  .scope = OPTIONS_TABLE_WINDOW,
 | 
				
			||||||
 | 
						  .choices = options_table_pane_lines_list,
 | 
				
			||||||
 | 
						  .default_num = PANE_LINES_SINGLE,
 | 
				
			||||||
 | 
						  .text = "Type of the pane type lines."
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ .name = "pane-border-status",
 | 
						{ .name = "pane-border-status",
 | 
				
			||||||
	  .type = OPTIONS_TABLE_CHOICE,
 | 
						  .type = OPTIONS_TABLE_CHOICE,
 | 
				
			||||||
	  .scope = OPTIONS_TABLE_WINDOW,
 | 
						  .scope = OPTIONS_TABLE_WINDOW,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										129
									
								
								screen-redraw.c
									
									
									
									
									
								
							
							
						
						
									
										129
									
								
								screen-redraw.c
									
									
									
									
									
								
							@@ -45,8 +45,36 @@ static void	screen_redraw_draw_pane(struct screen_redraw_ctx *,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define CELL_BORDERS " xqlkmjwvtun~"
 | 
					#define CELL_BORDERS " xqlkmjwvtun~"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct grid_cell screen_redraw_border_cell = {
 | 
					static const struct utf8_data screen_redraw_double_borders[] = {
 | 
				
			||||||
	{ { ' ' }, 0, 1, 1 }, GRID_ATTR_CHARSET, 0, 8, 8, 0
 | 
						{ "", 0, 0, 0 },
 | 
				
			||||||
 | 
						{ "\342\225\221", 0, 3, 1 }, /* U+2551 */
 | 
				
			||||||
 | 
						{ "\342\225\220", 0, 3, 1 }, /* U+2550 */
 | 
				
			||||||
 | 
						{ "\342\225\224", 0, 3, 1 }, /* U+2554 */
 | 
				
			||||||
 | 
						{ "\342\225\227", 0, 3, 1 }, /* U+2557 */
 | 
				
			||||||
 | 
						{ "\342\225\232", 0, 3, 1 }, /* U+255A */
 | 
				
			||||||
 | 
						{ "\342\225\235", 0, 3, 1 }, /* U+255D */
 | 
				
			||||||
 | 
						{ "\342\225\246", 0, 3, 1 }, /* U+2566 */
 | 
				
			||||||
 | 
						{ "\342\225\251", 0, 3, 1 }, /* U+2569 */
 | 
				
			||||||
 | 
						{ "\342\225\240", 0, 3, 1 }, /* U+2560 */
 | 
				
			||||||
 | 
						{ "\342\225\243", 0, 3, 1 }, /* U+2563 */
 | 
				
			||||||
 | 
						{ "\342\225\254", 0, 3, 1 }, /* U+256C */
 | 
				
			||||||
 | 
						{ "\302\267",     0, 2, 1 }  /* U+00B7 */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct utf8_data screen_redraw_heavy_borders[] = {
 | 
				
			||||||
 | 
						{ "", 0, 0, 0 },
 | 
				
			||||||
 | 
						{ "\342\224\203", 0, 3, 1 }, /* U+2503 */
 | 
				
			||||||
 | 
						{ "\342\224\201", 0, 3, 1 }, /* U+2501 */
 | 
				
			||||||
 | 
						{ "\342\224\223", 0, 3, 1 }, /* U+2513 */
 | 
				
			||||||
 | 
						{ "\342\224\217", 0, 3, 1 }, /* U+250F */
 | 
				
			||||||
 | 
						{ "\342\224\227", 0, 3, 1 }, /* U+2517 */
 | 
				
			||||||
 | 
						{ "\342\224\233", 0, 3, 1 }, /* U+251B */
 | 
				
			||||||
 | 
						{ "\342\224\263", 0, 3, 1 }, /* U+2533 */
 | 
				
			||||||
 | 
						{ "\342\224\273", 0, 3, 1 }, /* U+253B */
 | 
				
			||||||
 | 
						{ "\342\224\243", 0, 3, 1 }, /* U+2523 */
 | 
				
			||||||
 | 
						{ "\342\224\253", 0, 3, 1 }, /* U+252B */
 | 
				
			||||||
 | 
						{ "\342\225\213", 0, 3, 1 }, /* U+254B */
 | 
				
			||||||
 | 
						{ "\302\267",     0, 2, 1 }  /* U+00B7 */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum screen_redraw_border_type {
 | 
					enum screen_redraw_border_type {
 | 
				
			||||||
@@ -55,6 +83,45 @@ enum screen_redraw_border_type {
 | 
				
			|||||||
	SCREEN_REDRAW_BORDER
 | 
						SCREEN_REDRAW_BORDER
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get cell border character. */
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					screen_redraw_border_set(struct window_pane *wp, int pane_lines, int cell_type,
 | 
				
			||||||
 | 
					    struct grid_cell *gc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (pane_lines) {
 | 
				
			||||||
 | 
						case PANE_LINES_NUMBER:
 | 
				
			||||||
 | 
							if (cell_type == CELL_OUTSIDE) {
 | 
				
			||||||
 | 
								gc->attr |= GRID_ATTR_CHARSET;
 | 
				
			||||||
 | 
								utf8_set(&gc->data, CELL_BORDERS[CELL_OUTSIDE]);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							gc->attr &= ~GRID_ATTR_CHARSET;
 | 
				
			||||||
 | 
							if (wp != NULL && window_pane_index(wp, &idx) == 0)
 | 
				
			||||||
 | 
								utf8_set(&gc->data, '0' + (idx % 10));
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								utf8_set(&gc->data, '*');
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case PANE_LINES_DOUBLE:
 | 
				
			||||||
 | 
							gc->attr &= ~GRID_ATTR_CHARSET;
 | 
				
			||||||
 | 
							utf8_copy(&gc->data, &screen_redraw_double_borders[cell_type]);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case PANE_LINES_HEAVY:
 | 
				
			||||||
 | 
							gc->attr &= ~GRID_ATTR_CHARSET;
 | 
				
			||||||
 | 
							utf8_copy(&gc->data, &screen_redraw_heavy_borders[cell_type]);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case PANE_LINES_SIMPLE:
 | 
				
			||||||
 | 
							gc->attr &= ~GRID_ATTR_CHARSET;
 | 
				
			||||||
 | 
							utf8_set(&gc->data, " |-+++++++++."[cell_type]);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							gc->attr |= GRID_ATTR_CHARSET;
 | 
				
			||||||
 | 
							utf8_set(&gc->data, CELL_BORDERS[cell_type]);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Return if window has only two panes. */
 | 
					/* Return if window has only two panes. */
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
screen_redraw_two_panes(struct window *w, int direction)
 | 
					screen_redraw_two_panes(struct window *w, int direction)
 | 
				
			||||||
@@ -317,7 +384,7 @@ screen_redraw_check_is(u_int px, u_int py, int pane_status,
 | 
				
			|||||||
/* Update pane status. */
 | 
					/* Update pane status. */
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
screen_redraw_make_pane_status(struct client *c, struct window *w,
 | 
					screen_redraw_make_pane_status(struct client *c, struct window *w,
 | 
				
			||||||
    struct window_pane *wp)
 | 
					    struct window_pane *wp, int pane_lines)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct grid_cell	 gc;
 | 
						struct grid_cell	 gc;
 | 
				
			||||||
	const char		*fmt;
 | 
						const char		*fmt;
 | 
				
			||||||
@@ -348,9 +415,9 @@ screen_redraw_make_pane_status(struct client *c, struct window *w,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	screen_write_start(&ctx, &wp->status_screen);
 | 
						screen_write_start(&ctx, &wp->status_screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gc.attr |= GRID_ATTR_CHARSET;
 | 
						screen_redraw_border_set(wp, pane_lines, CELL_TOPBOTTOM, &gc);
 | 
				
			||||||
	for (i = 0; i < width; i++)
 | 
						for (i = 0; i < width; i++)
 | 
				
			||||||
		screen_write_putc(&ctx, &gc, 'q');
 | 
							screen_write_cell(&ctx, &gc);
 | 
				
			||||||
	gc.attr &= ~GRID_ATTR_CHARSET;
 | 
						gc.attr &= ~GRID_ATTR_CHARSET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	screen_write_cursormove(&ctx, 0, 0, 0);
 | 
						screen_write_cursormove(&ctx, 0, 0, 0);
 | 
				
			||||||
@@ -436,7 +503,7 @@ screen_redraw_update(struct client *c, int flags)
 | 
				
			|||||||
	struct window		*w = c->session->curw->window;
 | 
						struct window		*w = c->session->curw->window;
 | 
				
			||||||
	struct window_pane	*wp;
 | 
						struct window_pane	*wp;
 | 
				
			||||||
	struct options		*wo = w->options;
 | 
						struct options		*wo = w->options;
 | 
				
			||||||
	int			 redraw;
 | 
						int			 redraw, lines;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (c->message_string != NULL)
 | 
						if (c->message_string != NULL)
 | 
				
			||||||
		redraw = status_message_redraw(c);
 | 
							redraw = status_message_redraw(c);
 | 
				
			||||||
@@ -451,9 +518,10 @@ screen_redraw_update(struct client *c, int flags)
 | 
				
			|||||||
		flags |= CLIENT_REDRAWOVERLAY;
 | 
							flags |= CLIENT_REDRAWOVERLAY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (options_get_number(wo, "pane-border-status") != PANE_STATUS_OFF) {
 | 
						if (options_get_number(wo, "pane-border-status") != PANE_STATUS_OFF) {
 | 
				
			||||||
 | 
							lines = options_get_number(wo, "pane-border-lines");
 | 
				
			||||||
		redraw = 0;
 | 
							redraw = 0;
 | 
				
			||||||
		TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
							TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
			if (screen_redraw_make_pane_status(c, w, wp))
 | 
								if (screen_redraw_make_pane_status(c, w, wp, lines))
 | 
				
			||||||
				redraw = 1;
 | 
									redraw = 1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (redraw)
 | 
							if (redraw)
 | 
				
			||||||
@@ -483,6 +551,7 @@ screen_redraw_set_context(struct client *c, struct screen_redraw_ctx *ctx)
 | 
				
			|||||||
	ctx->statuslines = lines;
 | 
						ctx->statuslines = lines;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx->pane_status = options_get_number(wo, "pane-border-status");
 | 
						ctx->pane_status = options_get_number(wo, "pane-border-status");
 | 
				
			||||||
 | 
						ctx->pane_lines = options_get_number(wo, "pane-border-lines");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tty_window_offset(&c->tty, &ctx->ox, &ctx->oy, &ctx->sx, &ctx->sy);
 | 
						tty_window_offset(&c->tty, &ctx->ox, &ctx->oy, &ctx->sx, &ctx->sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -560,7 +629,6 @@ screen_redraw_draw_borders_style(struct screen_redraw_ctx *ctx, u_int x,
 | 
				
			|||||||
	struct window		*w = s->curw->window;
 | 
						struct window		*w = s->curw->window;
 | 
				
			||||||
	struct window_pane	*active = server_client_get_pane(c);
 | 
						struct window_pane	*active = server_client_get_pane(c);
 | 
				
			||||||
	struct options		*oo = w->options;
 | 
						struct options		*oo = w->options;
 | 
				
			||||||
	struct grid_cell	*gc;
 | 
					 | 
				
			||||||
	struct format_tree	*ft;
 | 
						struct format_tree	*ft;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (wp->border_gc_set)
 | 
						if (wp->border_gc_set)
 | 
				
			||||||
@@ -568,18 +636,13 @@ screen_redraw_draw_borders_style(struct screen_redraw_ctx *ctx, u_int x,
 | 
				
			|||||||
	wp->border_gc_set = 1;
 | 
						wp->border_gc_set = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ft = format_create_defaults(NULL, c, s, s->curw, wp);
 | 
						ft = format_create_defaults(NULL, c, s, s->curw, wp);
 | 
				
			||||||
	gc = &wp->border_gc;
 | 
						if (screen_redraw_check_is(x, y, ctx->pane_status, active))
 | 
				
			||||||
 | 
							style_apply(&wp->border_gc, oo, "pane-active-border-style", ft);
 | 
				
			||||||
	if (screen_redraw_check_is(x, y, ctx->pane_status, active)) {
 | 
						else
 | 
				
			||||||
		style_apply(gc, oo, "pane-active-border-style", ft);
 | 
							style_apply(&wp->border_gc, oo, "pane-border-style", ft);
 | 
				
			||||||
		gc->attr |= GRID_ATTR_CHARSET;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		style_apply(gc, oo, "pane-border-style", ft);
 | 
					 | 
				
			||||||
		gc->attr |= GRID_ATTR_CHARSET;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	format_free(ft);
 | 
						format_free(ft);
 | 
				
			||||||
	return (gc);
 | 
					
 | 
				
			||||||
 | 
						return (&wp->border_gc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Draw a border cell. */
 | 
					/* Draw a border cell. */
 | 
				
			||||||
@@ -590,39 +653,37 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
 | 
				
			|||||||
	struct session		*s = c->session;
 | 
						struct session		*s = c->session;
 | 
				
			||||||
	struct tty		*tty = &c->tty;
 | 
						struct tty		*tty = &c->tty;
 | 
				
			||||||
	struct window_pane	*wp;
 | 
						struct window_pane	*wp;
 | 
				
			||||||
	u_int			 type, x = ctx->ox + i, y = ctx->oy + j;
 | 
						u_int			 cell_type, x = ctx->ox + i, y = ctx->oy + j;
 | 
				
			||||||
	int			 pane_status = ctx->pane_status;
 | 
						int			 pane_status = ctx->pane_status;
 | 
				
			||||||
	const struct grid_cell	*gc;
 | 
						struct grid_cell	 gc;
 | 
				
			||||||
	struct grid_cell	 copy;
 | 
						const struct grid_cell	*tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (c->overlay_check != NULL && !c->overlay_check(c, x, y))
 | 
						if (c->overlay_check != NULL && !c->overlay_check(c, x, y))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	type = screen_redraw_check_cell(c, x, y, pane_status, &wp);
 | 
						cell_type = screen_redraw_check_cell(c, x, y, pane_status, &wp);
 | 
				
			||||||
	if (type == CELL_INSIDE)
 | 
						if (cell_type == CELL_INSIDE)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (wp == NULL)
 | 
						if (wp == NULL)
 | 
				
			||||||
		gc = &screen_redraw_border_cell;
 | 
							memcpy(&gc, &grid_default_cell, sizeof gc);
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		gc = screen_redraw_draw_borders_style(ctx, x, y, wp);
 | 
							tmp = screen_redraw_draw_borders_style(ctx, x, y, wp);
 | 
				
			||||||
		if (gc == NULL)
 | 
							if (tmp == NULL)
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
							memcpy(&gc, tmp, sizeof gc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (server_is_marked(s, s->curw, marked_pane.wp) &&
 | 
							if (server_is_marked(s, s->curw, marked_pane.wp) &&
 | 
				
			||||||
		    screen_redraw_check_is(x, y, pane_status, marked_pane.wp)) {
 | 
							    screen_redraw_check_is(x, y, pane_status, marked_pane.wp))
 | 
				
			||||||
			memcpy(©, gc, sizeof copy);
 | 
								gc.attr ^= GRID_ATTR_REVERSE;
 | 
				
			||||||
			copy.attr ^= GRID_ATTR_REVERSE;
 | 
					 | 
				
			||||||
			gc = ©
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						screen_redraw_border_set(wp, ctx->pane_lines, cell_type, &gc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tty_attributes(tty, gc, &grid_default_cell, NULL);
 | 
					 | 
				
			||||||
	if (ctx->statustop)
 | 
						if (ctx->statustop)
 | 
				
			||||||
		tty_cursor(tty, i, ctx->statuslines + j);
 | 
							tty_cursor(tty, i, ctx->statuslines + j);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		tty_cursor(tty, i, j);
 | 
							tty_cursor(tty, i, j);
 | 
				
			||||||
	tty_putc(tty, CELL_BORDERS[type]);
 | 
						tty_cell(tty, &gc, &grid_default_cell, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Draw the borders. */
 | 
					/* Draw the borders. */
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								tmux.1
									
									
									
									
									
								
							@@ -3924,6 +3924,28 @@ but set the starting index for pane numbers.
 | 
				
			|||||||
.It Ic pane-border-format Ar format
 | 
					.It Ic pane-border-format Ar format
 | 
				
			||||||
Set the text shown in pane border status lines.
 | 
					Set the text shown in pane border status lines.
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
 | 
					.It Ic pane-border-lines Ar type
 | 
				
			||||||
 | 
					Set the type of characters used for drawing pane borders.
 | 
				
			||||||
 | 
					.Ar type
 | 
				
			||||||
 | 
					may be one of:
 | 
				
			||||||
 | 
					.Bl -tag -width Ds
 | 
				
			||||||
 | 
					.It single
 | 
				
			||||||
 | 
					single lines using ACS or UTF-8 characters
 | 
				
			||||||
 | 
					.It double
 | 
				
			||||||
 | 
					double lines using UTF-8 characters
 | 
				
			||||||
 | 
					.It heavy
 | 
				
			||||||
 | 
					heavy lines using UTF-8 characters
 | 
				
			||||||
 | 
					.It simple
 | 
				
			||||||
 | 
					simple ASCII characters
 | 
				
			||||||
 | 
					.It number
 | 
				
			||||||
 | 
					the pane number
 | 
				
			||||||
 | 
					.El
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					.Ql double
 | 
				
			||||||
 | 
					and
 | 
				
			||||||
 | 
					.Ql heavy
 | 
				
			||||||
 | 
					will fall back to standard ACS line drawing when UTF-8 is not supported.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
.It Xo Ic pane-border-status
 | 
					.It Xo Ic pane-border-status
 | 
				
			||||||
.Op Ic off | top | bottom
 | 
					.Op Ic off | top | bottom
 | 
				
			||||||
.Xc
 | 
					.Xc
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								tmux.h
									
									
									
									
									
								
							@@ -820,6 +820,7 @@ struct screen_redraw_ctx {
 | 
				
			|||||||
	int		 statustop;
 | 
						int		 statustop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int		 pane_status;
 | 
						int		 pane_status;
 | 
				
			||||||
 | 
						int		 pane_lines;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u_int		 sx;
 | 
						u_int		 sx;
 | 
				
			||||||
	u_int		 sy;
 | 
						u_int		 sy;
 | 
				
			||||||
@@ -1050,6 +1051,13 @@ TAILQ_HEAD(winlink_stack, winlink);
 | 
				
			|||||||
#define PANE_STATUS_TOP 1
 | 
					#define PANE_STATUS_TOP 1
 | 
				
			||||||
#define PANE_STATUS_BOTTOM 2
 | 
					#define PANE_STATUS_BOTTOM 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Pane border lines option. */
 | 
				
			||||||
 | 
					#define PANE_LINES_SINGLE 0
 | 
				
			||||||
 | 
					#define PANE_LINES_DOUBLE 1
 | 
				
			||||||
 | 
					#define PANE_LINES_HEAVY 2
 | 
				
			||||||
 | 
					#define PANE_LINES_SIMPLE 3
 | 
				
			||||||
 | 
					#define PANE_LINES_NUMBER 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Layout direction. */
 | 
					/* Layout direction. */
 | 
				
			||||||
enum layout_type {
 | 
					enum layout_type {
 | 
				
			||||||
	LAYOUT_LEFTRIGHT,
 | 
						LAYOUT_LEFTRIGHT,
 | 
				
			||||||
@@ -2030,6 +2038,8 @@ void	tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *,
 | 
				
			|||||||
void	tty_puts(struct tty *, const char *);
 | 
					void	tty_puts(struct tty *, const char *);
 | 
				
			||||||
void	tty_putc(struct tty *, u_char);
 | 
					void	tty_putc(struct tty *, u_char);
 | 
				
			||||||
void	tty_putn(struct tty *, const void *, size_t, u_int);
 | 
					void	tty_putn(struct tty *, const void *, size_t, u_int);
 | 
				
			||||||
 | 
					void	tty_cell(struct tty *, const struct grid_cell *,
 | 
				
			||||||
 | 
						    const struct grid_cell *, int *);
 | 
				
			||||||
int	tty_init(struct tty *, struct client *, int);
 | 
					int	tty_init(struct tty *, struct client *, int);
 | 
				
			||||||
void	tty_resize(struct tty *);
 | 
					void	tty_resize(struct tty *);
 | 
				
			||||||
void	tty_set_size(struct tty *, u_int, u_int, u_int, u_int);
 | 
					void	tty_set_size(struct tty *, u_int, u_int, u_int, u_int);
 | 
				
			||||||
@@ -2103,6 +2113,7 @@ void		 tty_default_features(int *, const char *, u_int);
 | 
				
			|||||||
/* tty-acs.c */
 | 
					/* tty-acs.c */
 | 
				
			||||||
int		 tty_acs_needed(struct tty *);
 | 
					int		 tty_acs_needed(struct tty *);
 | 
				
			||||||
const char	*tty_acs_get(struct tty *, u_char);
 | 
					const char	*tty_acs_get(struct tty *, u_char);
 | 
				
			||||||
 | 
					int		 tty_acs_reverse_get(struct tty *, const char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* tty-keys.c */
 | 
					/* tty-keys.c */
 | 
				
			||||||
void		tty_keys_build(struct tty *);
 | 
					void		tty_keys_build(struct tty *);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										85
									
								
								tty-acs.c
									
									
									
									
									
								
							
							
						
						
									
										85
									
								
								tty-acs.c
									
									
									
									
									
								
							@@ -19,11 +19,10 @@
 | 
				
			|||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "tmux.h"
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int	tty_acs_cmp(const void *, const void *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Table mapping ACS entries to UTF-8. */
 | 
					/* Table mapping ACS entries to UTF-8. */
 | 
				
			||||||
struct tty_acs_entry {
 | 
					struct tty_acs_entry {
 | 
				
			||||||
	u_char	 	 key;
 | 
						u_char	 	 key;
 | 
				
			||||||
@@ -68,14 +67,65 @@ static const struct tty_acs_entry tty_acs_table[] = {
 | 
				
			|||||||
	{ '~', "\302\267" }		/* bullet */
 | 
						{ '~', "\302\267" }		/* bullet */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Table mapping UTF-8 to ACS entries. */
 | 
				
			||||||
 | 
					struct tty_acs_reverse_entry {
 | 
				
			||||||
 | 
						const char	*string;
 | 
				
			||||||
 | 
						u_char		 key;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					static const struct tty_acs_reverse_entry tty_acs_reverse2[] = {
 | 
				
			||||||
 | 
						{ "\302\267", '~' }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					static const struct tty_acs_reverse_entry tty_acs_reverse3[] = {
 | 
				
			||||||
 | 
						{ "\342\224\200", 'q' },
 | 
				
			||||||
 | 
						{ "\342\224\201", 'q' },
 | 
				
			||||||
 | 
						{ "\342\224\202", 'x' },
 | 
				
			||||||
 | 
						{ "\342\224\203", 'x' },
 | 
				
			||||||
 | 
						{ "\342\224\214", 'l' },
 | 
				
			||||||
 | 
						{ "\342\224\217", 'k' },
 | 
				
			||||||
 | 
						{ "\342\224\220", 'k' },
 | 
				
			||||||
 | 
						{ "\342\224\223", 'l' },
 | 
				
			||||||
 | 
						{ "\342\224\224", 'm' },
 | 
				
			||||||
 | 
						{ "\342\224\227", 'm' },
 | 
				
			||||||
 | 
						{ "\342\224\230", 'j' },
 | 
				
			||||||
 | 
						{ "\342\224\233", 'j' },
 | 
				
			||||||
 | 
						{ "\342\224\234", 't' },
 | 
				
			||||||
 | 
						{ "\342\224\243", 't' },
 | 
				
			||||||
 | 
						{ "\342\224\244", 'u' },
 | 
				
			||||||
 | 
						{ "\342\224\253", 'u' },
 | 
				
			||||||
 | 
						{ "\342\224\263", 'w' },
 | 
				
			||||||
 | 
						{ "\342\224\264", 'v' },
 | 
				
			||||||
 | 
						{ "\342\224\273", 'v' },
 | 
				
			||||||
 | 
						{ "\342\224\274", 'n' },
 | 
				
			||||||
 | 
						{ "\342\225\213", 'n' },
 | 
				
			||||||
 | 
						{ "\342\225\220", 'q' },
 | 
				
			||||||
 | 
						{ "\342\225\221", 'x' },
 | 
				
			||||||
 | 
						{ "\342\225\224", 'l' },
 | 
				
			||||||
 | 
						{ "\342\225\227", 'k' },
 | 
				
			||||||
 | 
						{ "\342\225\232", 'm' },
 | 
				
			||||||
 | 
						{ "\342\225\235", 'j' },
 | 
				
			||||||
 | 
						{ "\342\225\240", 't' },
 | 
				
			||||||
 | 
						{ "\342\225\243", 'u' },
 | 
				
			||||||
 | 
						{ "\342\225\246", 'w' },
 | 
				
			||||||
 | 
						{ "\342\225\251", 'v' },
 | 
				
			||||||
 | 
						{ "\342\225\254", 'n' },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
tty_acs_cmp(const void *key, const void *value)
 | 
					tty_acs_cmp(const void *key, const void *value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct tty_acs_entry	*entry = value;
 | 
						const struct tty_acs_entry	*entry = value;
 | 
				
			||||||
	u_char				 ch;
 | 
						int				 test = *(u_char *)key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ch = *(u_char *) key;
 | 
						return (test - entry->key);
 | 
				
			||||||
	return (ch - entry->key);
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					tty_acs_reverse_cmp(const void *key, const void *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct tty_acs_reverse_entry	*entry = value;
 | 
				
			||||||
 | 
						const char				*test = key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (strcmp(test, entry->string));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Should this terminal use ACS instead of UTF-8 line drawing? */
 | 
					/* Should this terminal use ACS instead of UTF-8 line drawing? */
 | 
				
			||||||
@@ -104,11 +154,11 @@ tty_acs_needed(struct tty *tty)
 | 
				
			|||||||
	return (1);
 | 
						return (1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Retrieve ACS to output as a string. */
 | 
					/* Retrieve ACS to output as UTF-8. */
 | 
				
			||||||
const char *
 | 
					const char *
 | 
				
			||||||
tty_acs_get(struct tty *tty, u_char ch)
 | 
					tty_acs_get(struct tty *tty, u_char ch)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct tty_acs_entry	*entry;
 | 
						const struct tty_acs_entry	*entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Use the ACS set instead of UTF-8 if needed. */
 | 
						/* Use the ACS set instead of UTF-8 if needed. */
 | 
				
			||||||
	if (tty_acs_needed(tty)) {
 | 
						if (tty_acs_needed(tty)) {
 | 
				
			||||||
@@ -124,3 +174,24 @@ tty_acs_get(struct tty *tty, u_char ch)
 | 
				
			|||||||
		return (NULL);
 | 
							return (NULL);
 | 
				
			||||||
	return (entry->string);
 | 
						return (entry->string);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Reverse UTF-8 into ACS. */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					tty_acs_reverse_get(__unused struct tty *tty, const char *s, size_t slen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct tty_acs_reverse_entry	*table, *entry;
 | 
				
			||||||
 | 
						u_int					 items;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (slen == 2) {
 | 
				
			||||||
 | 
							table = tty_acs_reverse2;
 | 
				
			||||||
 | 
							items = nitems(tty_acs_reverse2);
 | 
				
			||||||
 | 
						} else if (slen == 3) {
 | 
				
			||||||
 | 
							table = tty_acs_reverse3;
 | 
				
			||||||
 | 
							items = nitems(tty_acs_reverse3);
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						entry = bsearch(s, table, items, sizeof table[0], tty_acs_reverse_cmp);
 | 
				
			||||||
 | 
						if (entry == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						return (entry->key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										34
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								tty.c
									
									
									
									
									
								
							@@ -65,8 +65,6 @@ static void	tty_emulate_repeat(struct tty *, enum tty_code_code,
 | 
				
			|||||||
		    enum tty_code_code, u_int);
 | 
							    enum tty_code_code, u_int);
 | 
				
			||||||
static void	tty_repeat_space(struct tty *, u_int);
 | 
					static void	tty_repeat_space(struct tty *, u_int);
 | 
				
			||||||
static void	tty_draw_pane(struct tty *, const struct tty_ctx *, u_int);
 | 
					static void	tty_draw_pane(struct tty *, const struct tty_ctx *, u_int);
 | 
				
			||||||
static void	tty_cell(struct tty *, const struct grid_cell *,
 | 
					 | 
				
			||||||
		    const struct grid_cell *, int *);
 | 
					 | 
				
			||||||
static void	tty_default_attributes(struct tty *, const struct grid_cell *,
 | 
					static void	tty_default_attributes(struct tty *, const struct grid_cell *,
 | 
				
			||||||
		    int *, u_int);
 | 
							    int *, u_int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1243,7 +1241,7 @@ static const struct grid_cell *
 | 
				
			|||||||
tty_check_codeset(struct tty *tty, const struct grid_cell *gc)
 | 
					tty_check_codeset(struct tty *tty, const struct grid_cell *gc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static struct grid_cell	new;
 | 
						static struct grid_cell	new;
 | 
				
			||||||
	u_int			n;
 | 
						int			c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Characters less than 0x7f are always fine, no matter what. */
 | 
						/* Characters less than 0x7f are always fine, no matter what. */
 | 
				
			||||||
	if (gc->data.size == 1 && *gc->data.data < 0x7f)
 | 
						if (gc->data.size == 1 && *gc->data.data < 0x7f)
 | 
				
			||||||
@@ -1252,14 +1250,21 @@ tty_check_codeset(struct tty *tty, const struct grid_cell *gc)
 | 
				
			|||||||
	/* UTF-8 terminal and a UTF-8 character - fine. */
 | 
						/* UTF-8 terminal and a UTF-8 character - fine. */
 | 
				
			||||||
	if (tty->client->flags & CLIENT_UTF8)
 | 
						if (tty->client->flags & CLIENT_UTF8)
 | 
				
			||||||
		return (gc);
 | 
							return (gc);
 | 
				
			||||||
 | 
						memcpy(&new, gc, sizeof new);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* See if this can be mapped to an ACS character. */
 | 
				
			||||||
 | 
						c = tty_acs_reverse_get(tty, gc->data.data, gc->data.size);
 | 
				
			||||||
 | 
						if (c != -1) {
 | 
				
			||||||
 | 
							utf8_set(&new.data, c);
 | 
				
			||||||
 | 
							new.attr |= GRID_ATTR_CHARSET;
 | 
				
			||||||
 | 
							return (&new);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Replace by the right number of underscores. */
 | 
						/* Replace by the right number of underscores. */
 | 
				
			||||||
	n = gc->data.width;
 | 
						new.data.size = gc->data.width;
 | 
				
			||||||
	if (n > UTF8_SIZE)
 | 
						if (new.data.size > UTF8_SIZE)
 | 
				
			||||||
		n = UTF8_SIZE;
 | 
							new.data.size = UTF8_SIZE;
 | 
				
			||||||
	memcpy(&new, gc, sizeof new);
 | 
						memset(new.data.data, '_', new.data.size);
 | 
				
			||||||
	new.data.size = n;
 | 
					 | 
				
			||||||
	memset(new.data.data, '_', n);
 | 
					 | 
				
			||||||
	return (&new);
 | 
						return (&new);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1924,7 +1929,7 @@ tty_cmd_syncstart(struct tty *tty, __unused const struct tty_ctx *ctx)
 | 
				
			|||||||
	tty_sync_start(tty);
 | 
						tty_sync_start(tty);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					void
 | 
				
			||||||
tty_cell(struct tty *tty, const struct grid_cell *gc,
 | 
					tty_cell(struct tty *tty, const struct grid_cell *gc,
 | 
				
			||||||
    const struct grid_cell *defaults, int *palette)
 | 
					    const struct grid_cell *defaults, int *palette)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -1940,12 +1945,13 @@ tty_cell(struct tty *tty, const struct grid_cell *gc,
 | 
				
			|||||||
	if (gc->flags & GRID_FLAG_PADDING)
 | 
						if (gc->flags & GRID_FLAG_PADDING)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set the attributes. */
 | 
						/* Check the output codeset and apply attributes. */
 | 
				
			||||||
	tty_attributes(tty, gc, defaults, palette);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Get the cell and if ASCII write with putc to do ACS translation. */
 | 
					 | 
				
			||||||
	gcp = tty_check_codeset(tty, gc);
 | 
						gcp = tty_check_codeset(tty, gc);
 | 
				
			||||||
 | 
						tty_attributes(tty, gcp, defaults, palette);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If it is a single character, write with putc to handle ACS. */
 | 
				
			||||||
	if (gcp->data.size == 1) {
 | 
						if (gcp->data.size == 1) {
 | 
				
			||||||
 | 
							tty_attributes(tty, gcp, defaults, palette);
 | 
				
			||||||
		if (*gcp->data.data < 0x20 || *gcp->data.data == 0x7f)
 | 
							if (*gcp->data.data < 0x20 || *gcp->data.data == 0x7f)
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		tty_putc(tty, *gcp->data.data);
 | 
							tty_putc(tty, *gcp->data.data);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user