mirror of
https://github.com/tmux/tmux.git
synced 2025-03-28 01:08:53 +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:
parent
97c8374855
commit
31621036ad
@ -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);
|
||||||
|
@ -59,6 +59,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
|
||||||
};
|
};
|
||||||
@ -903,6 +906,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,
|
||||||
|
124
screen-redraw.c
124
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,40 @@ 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:
|
||||||
|
gc->attr &= ~GRID_ATTR_CHARSET;
|
||||||
|
if (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 +379,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 +410,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 +498,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 +513,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 +546,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 +624,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 +631,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 +648,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
@ -822,6 +822,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;
|
||||||
@ -1052,6 +1053,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,
|
||||||
@ -2032,6 +2040,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);
|
||||||
@ -2105,6 +2115,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);
|
||||||
|
Loading…
Reference in New Issue
Block a user