mirror of
https://github.com/tmate-io/tmate.git
synced 2025-04-02 03:46:47 +02:00
Properly track switching G0 and G1 modes between US-ASCII and VT100 line
drawing rather than just treating them as SO and SI.
This commit is contained in:
parent
74becbfd6f
commit
21ade85f24
104
input.c
104
input.c
@ -52,6 +52,7 @@ int input_split(struct input_ctx *);
|
|||||||
int input_get(struct input_ctx *, u_int, int, int);
|
int input_get(struct input_ctx *, u_int, int, int);
|
||||||
void input_reply(struct input_ctx *, const char *, ...);
|
void input_reply(struct input_ctx *, const char *, ...);
|
||||||
void input_set_state(struct window_pane *, const struct input_transition *);
|
void input_set_state(struct window_pane *, const struct input_transition *);
|
||||||
|
void input_reset_cell(struct input_ctx *);
|
||||||
|
|
||||||
/* Transition entry/exit handlers. */
|
/* Transition entry/exit handlers. */
|
||||||
void input_clear(struct input_ctx *);
|
void input_clear(struct input_ctx *);
|
||||||
@ -104,19 +105,23 @@ enum input_esc_type {
|
|||||||
INPUT_ESC_NEL,
|
INPUT_ESC_NEL,
|
||||||
INPUT_ESC_RI,
|
INPUT_ESC_RI,
|
||||||
INPUT_ESC_RIS,
|
INPUT_ESC_RIS,
|
||||||
INPUT_ESC_SCSOFF_G0,
|
INPUT_ESC_SCSG0_OFF,
|
||||||
INPUT_ESC_SCSON_G0,
|
INPUT_ESC_SCSG0_ON,
|
||||||
|
INPUT_ESC_SCSG1_OFF,
|
||||||
|
INPUT_ESC_SCSG1_ON,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Escape command table. */
|
/* Escape command table. */
|
||||||
const struct input_table_entry input_esc_table[] = {
|
const struct input_table_entry input_esc_table[] = {
|
||||||
{ '0', "(", INPUT_ESC_SCSOFF_G0 },
|
{ '0', "(", INPUT_ESC_SCSG0_ON },
|
||||||
|
{ '0', ")", INPUT_ESC_SCSG1_ON },
|
||||||
{ '7', "", INPUT_ESC_DECSC },
|
{ '7', "", INPUT_ESC_DECSC },
|
||||||
{ '8', "", INPUT_ESC_DECRC },
|
{ '8', "", INPUT_ESC_DECRC },
|
||||||
{ '8', "#", INPUT_ESC_DECALN },
|
{ '8', "#", INPUT_ESC_DECALN },
|
||||||
{ '=', "", INPUT_ESC_DECKPAM },
|
{ '=', "", INPUT_ESC_DECKPAM },
|
||||||
{ '>', "", INPUT_ESC_DECKPNM },
|
{ '>', "", INPUT_ESC_DECKPNM },
|
||||||
{ 'B', "(", INPUT_ESC_SCSON_G0 },
|
{ 'B', "(", INPUT_ESC_SCSG0_OFF },
|
||||||
|
{ 'B', ")", INPUT_ESC_SCSG1_OFF },
|
||||||
{ 'D', "", INPUT_ESC_IND },
|
{ 'D', "", INPUT_ESC_IND },
|
||||||
{ 'E', "", INPUT_ESC_NEL },
|
{ 'E', "", INPUT_ESC_NEL },
|
||||||
{ 'H', "", INPUT_ESC_HTS },
|
{ 'H', "", INPUT_ESC_HTS },
|
||||||
@ -684,17 +689,26 @@ input_table_compare(const void *key, const void *value)
|
|||||||
return (strcmp(ictx->interm_buf, entry->interm));
|
return (strcmp(ictx->interm_buf, entry->interm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset cell state to default. */
|
||||||
|
void
|
||||||
|
input_reset_cell(struct input_ctx *ictx)
|
||||||
|
{
|
||||||
|
memcpy(&ictx->cell.cell, &grid_default_cell, sizeof ictx->cell.cell);
|
||||||
|
ictx->cell.set = 0;
|
||||||
|
ictx->cell.g0set = ictx->cell.g1set = 0;
|
||||||
|
|
||||||
|
memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
|
||||||
|
ictx->old_cx = 0;
|
||||||
|
ictx->old_cy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialise input parser. */
|
/* Initialise input parser. */
|
||||||
void
|
void
|
||||||
input_init(struct window_pane *wp)
|
input_init(struct window_pane *wp)
|
||||||
{
|
{
|
||||||
struct input_ctx *ictx = &wp->ictx;
|
struct input_ctx *ictx = &wp->ictx;
|
||||||
|
|
||||||
memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell);
|
input_reset_cell(ictx);
|
||||||
|
|
||||||
memcpy(&ictx->old_cell, &grid_default_cell, sizeof ictx->old_cell);
|
|
||||||
ictx->old_cx = 0;
|
|
||||||
ictx->old_cy = 0;
|
|
||||||
|
|
||||||
*ictx->interm_buf = '\0';
|
*ictx->interm_buf = '\0';
|
||||||
ictx->interm_len = 0;
|
ictx->interm_len = 0;
|
||||||
@ -903,8 +917,18 @@ input_ground(struct input_ctx *ictx)
|
|||||||
int
|
int
|
||||||
input_print(struct input_ctx *ictx)
|
input_print(struct input_ctx *ictx)
|
||||||
{
|
{
|
||||||
grid_cell_one(&ictx->cell, ictx->ch);
|
int set;
|
||||||
screen_write_cell(&ictx->ctx, &ictx->cell);
|
|
||||||
|
set = ictx->cell.set == 0 ? ictx->cell.g0set : ictx->cell.g1set;
|
||||||
|
if (set == 1)
|
||||||
|
ictx->cell.cell.attr |= GRID_ATTR_CHARSET;
|
||||||
|
else
|
||||||
|
ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
|
||||||
|
|
||||||
|
grid_cell_one(&ictx->cell.cell, ictx->ch);
|
||||||
|
screen_write_cell(&ictx->ctx, &ictx->cell.cell);
|
||||||
|
|
||||||
|
ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -1000,10 +1024,10 @@ input_c0_dispatch(struct input_ctx *ictx)
|
|||||||
screen_write_carriagereturn(sctx);
|
screen_write_carriagereturn(sctx);
|
||||||
goto count_c0;
|
goto count_c0;
|
||||||
case '\016': /* SO */
|
case '\016': /* SO */
|
||||||
ictx->cell.attr |= GRID_ATTR_CHARSET;
|
ictx->cell.set = 1;
|
||||||
break;
|
break;
|
||||||
case '\017': /* SI */
|
case '\017': /* SI */
|
||||||
ictx->cell.attr &= ~GRID_ATTR_CHARSET;
|
ictx->cell.set = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_debug("%s: unknown '%c'", __func__, ictx->ch);
|
log_debug("%s: unknown '%c'", __func__, ictx->ch);
|
||||||
@ -1014,7 +1038,7 @@ input_c0_dispatch(struct input_ctx *ictx)
|
|||||||
|
|
||||||
count_c0:
|
count_c0:
|
||||||
trigger = options_get_number(&wp->window->options, "c0-change-trigger");
|
trigger = options_get_number(&wp->window->options, "c0-change-trigger");
|
||||||
if (++wp->changes == trigger) {
|
if (trigger != 0 && ++wp->changes >= trigger) {
|
||||||
wp->flags |= PANE_DROP;
|
wp->flags |= PANE_DROP;
|
||||||
window_pane_timer_start(wp);
|
window_pane_timer_start(wp);
|
||||||
}
|
}
|
||||||
@ -1043,11 +1067,7 @@ input_esc_dispatch(struct input_ctx *ictx)
|
|||||||
|
|
||||||
switch (entry->type) {
|
switch (entry->type) {
|
||||||
case INPUT_ESC_RIS:
|
case INPUT_ESC_RIS:
|
||||||
memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell);
|
input_reset_cell(ictx);
|
||||||
memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
|
|
||||||
ictx->old_cx = 0;
|
|
||||||
ictx->old_cy = 0;
|
|
||||||
|
|
||||||
screen_write_reset(sctx);
|
screen_write_reset(sctx);
|
||||||
break;
|
break;
|
||||||
case INPUT_ESC_IND:
|
case INPUT_ESC_IND:
|
||||||
@ -1082,16 +1102,17 @@ input_esc_dispatch(struct input_ctx *ictx)
|
|||||||
case INPUT_ESC_DECALN:
|
case INPUT_ESC_DECALN:
|
||||||
screen_write_alignmenttest(sctx);
|
screen_write_alignmenttest(sctx);
|
||||||
break;
|
break;
|
||||||
case INPUT_ESC_SCSON_G0:
|
case INPUT_ESC_SCSG0_ON:
|
||||||
/*
|
ictx->cell.g0set = 1;
|
||||||
* Not really supported, but fake it up enough for those that
|
|
||||||
* use it to switch character sets (by redefining G0 to
|
|
||||||
* graphics set, rather than switching to G1).
|
|
||||||
*/
|
|
||||||
ictx->cell.attr &= ~GRID_ATTR_CHARSET;
|
|
||||||
break;
|
break;
|
||||||
case INPUT_ESC_SCSOFF_G0:
|
case INPUT_ESC_SCSG0_OFF:
|
||||||
ictx->cell.attr |= GRID_ATTR_CHARSET;
|
ictx->cell.g0set = 0;
|
||||||
|
break;
|
||||||
|
case INPUT_ESC_SCSG1_ON:
|
||||||
|
ictx->cell.g1set = 1;
|
||||||
|
break;
|
||||||
|
case INPUT_ESC_SCSG1_OFF:
|
||||||
|
ictx->cell.g1set = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1332,7 +1353,8 @@ input_csi_dispatch_rm(struct input_ctx *ictx)
|
|||||||
void
|
void
|
||||||
input_csi_dispatch_rm_private(struct input_ctx *ictx)
|
input_csi_dispatch_rm_private(struct input_ctx *ictx)
|
||||||
{
|
{
|
||||||
u_int i;
|
struct window_pane *wp = ictx->wp;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
for (i = 0; i < ictx->param_list_len; i++) {
|
for (i = 0; i < ictx->param_list_len; i++) {
|
||||||
switch (input_get(ictx, i, 0, -1)) {
|
switch (input_get(ictx, i, 0, -1)) {
|
||||||
@ -1366,10 +1388,10 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
|
|||||||
break;
|
break;
|
||||||
case 47:
|
case 47:
|
||||||
case 1047:
|
case 1047:
|
||||||
window_pane_alternate_off(ictx->wp, &ictx->cell, 0);
|
window_pane_alternate_off(wp, &ictx->cell.cell, 0);
|
||||||
break;
|
break;
|
||||||
case 1049:
|
case 1049:
|
||||||
window_pane_alternate_off(ictx->wp, &ictx->cell, 1);
|
window_pane_alternate_off(wp, &ictx->cell.cell, 1);
|
||||||
break;
|
break;
|
||||||
case 2004:
|
case 2004:
|
||||||
screen_write_mode_clear(&ictx->ctx, MODE_BRACKETPASTE);
|
screen_write_mode_clear(&ictx->ctx, MODE_BRACKETPASTE);
|
||||||
@ -1403,7 +1425,8 @@ input_csi_dispatch_sm(struct input_ctx *ictx)
|
|||||||
void
|
void
|
||||||
input_csi_dispatch_sm_private(struct input_ctx *ictx)
|
input_csi_dispatch_sm_private(struct input_ctx *ictx)
|
||||||
{
|
{
|
||||||
u_int i;
|
struct window_pane *wp = ictx->wp;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
for (i = 0; i < ictx->param_list_len; i++) {
|
for (i = 0; i < ictx->param_list_len; i++) {
|
||||||
switch (input_get(ictx, i, 0, -1)) {
|
switch (input_get(ictx, i, 0, -1)) {
|
||||||
@ -1436,7 +1459,7 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
|
|||||||
if (ictx->ctx.s->mode & MODE_FOCUSON)
|
if (ictx->ctx.s->mode & MODE_FOCUSON)
|
||||||
break;
|
break;
|
||||||
screen_write_mode_set(&ictx->ctx, MODE_FOCUSON);
|
screen_write_mode_set(&ictx->ctx, MODE_FOCUSON);
|
||||||
ictx->wp->flags |= PANE_FOCUSPUSH; /* force update */
|
wp->flags |= PANE_FOCUSPUSH; /* force update */
|
||||||
break;
|
break;
|
||||||
case 1005:
|
case 1005:
|
||||||
screen_write_mode_set(&ictx->ctx, MODE_MOUSE_UTF8);
|
screen_write_mode_set(&ictx->ctx, MODE_MOUSE_UTF8);
|
||||||
@ -1446,10 +1469,10 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
|
|||||||
break;
|
break;
|
||||||
case 47:
|
case 47:
|
||||||
case 1047:
|
case 1047:
|
||||||
window_pane_alternate_on(ictx->wp, &ictx->cell, 0);
|
window_pane_alternate_on(wp, &ictx->cell.cell, 0);
|
||||||
break;
|
break;
|
||||||
case 1049:
|
case 1049:
|
||||||
window_pane_alternate_on(ictx->wp, &ictx->cell, 1);
|
window_pane_alternate_on(wp, &ictx->cell.cell, 1);
|
||||||
break;
|
break;
|
||||||
case 2004:
|
case 2004:
|
||||||
screen_write_mode_set(&ictx->ctx, MODE_BRACKETPASTE);
|
screen_write_mode_set(&ictx->ctx, MODE_BRACKETPASTE);
|
||||||
@ -1514,15 +1537,12 @@ input_csi_dispatch_winops(struct input_ctx *ictx)
|
|||||||
void
|
void
|
||||||
input_csi_dispatch_sgr(struct input_ctx *ictx)
|
input_csi_dispatch_sgr(struct input_ctx *ictx)
|
||||||
{
|
{
|
||||||
struct grid_cell *gc = &ictx->cell;
|
struct grid_cell *gc = &ictx->cell.cell;
|
||||||
u_int i;
|
u_int i;
|
||||||
int n, m;
|
int n, m;
|
||||||
u_char attr;
|
|
||||||
|
|
||||||
if (ictx->param_list_len == 0) {
|
if (ictx->param_list_len == 0) {
|
||||||
attr = gc->attr;
|
|
||||||
memcpy(gc, &grid_default_cell, sizeof *gc);
|
memcpy(gc, &grid_default_cell, sizeof *gc);
|
||||||
gc->attr |= (attr & GRID_ATTR_CHARSET);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1560,9 +1580,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
|
|||||||
switch (n) {
|
switch (n) {
|
||||||
case 0:
|
case 0:
|
||||||
case 10:
|
case 10:
|
||||||
attr = gc->attr;
|
|
||||||
memcpy(gc, &grid_default_cell, sizeof *gc);
|
memcpy(gc, &grid_default_cell, sizeof *gc);
|
||||||
gc->attr |= (attr & GRID_ATTR_CHARSET);
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
gc->attr |= GRID_ATTR_BRIGHT;
|
gc->attr |= GRID_ATTR_BRIGHT;
|
||||||
@ -1806,8 +1824,8 @@ input_utf8_close(struct input_ctx *ictx)
|
|||||||
|
|
||||||
utf8_append(&ictx->utf8data, ictx->ch);
|
utf8_append(&ictx->utf8data, ictx->ch);
|
||||||
|
|
||||||
grid_cell_set(&ictx->cell, &ictx->utf8data);
|
grid_cell_set(&ictx->cell.cell, &ictx->utf8data);
|
||||||
screen_write_cell(&ictx->ctx, &ictx->cell);
|
screen_write_cell(&ictx->ctx, &ictx->cell.cell);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
14
tmux.h
14
tmux.h
@ -803,14 +803,22 @@ struct screen_write_ctx {
|
|||||||
#define screen_hsize(s) ((s)->grid->hsize)
|
#define screen_hsize(s) ((s)->grid->hsize)
|
||||||
#define screen_hlimit(s) ((s)->grid->hlimit)
|
#define screen_hlimit(s) ((s)->grid->hlimit)
|
||||||
|
|
||||||
|
/* Input parser cell. */
|
||||||
|
struct input_cell {
|
||||||
|
struct grid_cell cell;
|
||||||
|
int set;
|
||||||
|
int g0set; /* 1 if ACS */
|
||||||
|
int g1set; /* 1 if ACS */
|
||||||
|
};
|
||||||
|
|
||||||
/* Input parser context. */
|
/* Input parser context. */
|
||||||
struct input_ctx {
|
struct input_ctx {
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
struct screen_write_ctx ctx;
|
struct screen_write_ctx ctx;
|
||||||
|
|
||||||
struct grid_cell cell;
|
struct input_cell cell;
|
||||||
|
|
||||||
struct grid_cell old_cell;
|
struct input_cell old_cell;
|
||||||
u_int old_cx;
|
u_int old_cx;
|
||||||
u_int old_cy;
|
u_int old_cy;
|
||||||
|
|
||||||
@ -822,7 +830,7 @@ struct input_ctx {
|
|||||||
|
|
||||||
#define INPUT_BUF_START 32
|
#define INPUT_BUF_START 32
|
||||||
#define INPUT_BUF_LIMIT 1048576
|
#define INPUT_BUF_LIMIT 1048576
|
||||||
u_char* input_buf;
|
u_char *input_buf;
|
||||||
size_t input_len;
|
size_t input_len;
|
||||||
size_t input_space;
|
size_t input_space;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user