mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-02 07:15:31 -04:00
input: implement metaSendsEscape and eightBitMeta
This commit is contained in:
parent
4e87426712
commit
a3d919a90d
5 changed files with 101 additions and 34 deletions
21
csi.c
21
csi.c
|
|
@ -927,8 +927,16 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
term->mouse_reporting = MOUSE_URXVT;
|
term->mouse_reporting = MOUSE_URXVT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 1034:
|
||||||
|
/* smm */
|
||||||
|
LOG_DBG("enabling 8-bit meta mode");
|
||||||
|
term->meta.eight_bit = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case 1036:
|
case 1036:
|
||||||
/* metaSendsEscape - we always send escape */
|
/* metaSendsEscape */
|
||||||
|
LOG_DBG("enabling meta-sends-escape");
|
||||||
|
term->meta.esc_prefix = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -1037,9 +1045,16 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
term->alt_scrolling = false;
|
term->alt_scrolling = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 1034:
|
||||||
|
/* rmm */
|
||||||
|
LOG_DBG("disabling 8-bit meta mode");
|
||||||
|
term->meta.eight_bit = false;
|
||||||
|
break;
|
||||||
|
|
||||||
case 1036:
|
case 1036:
|
||||||
/* metaSendsEscape - we always send escape */
|
/* metaSendsEscape */
|
||||||
LOG_WARN("unimplemented: meta does *not* send escape");
|
LOG_DBG("disabling meta-sends-escape");
|
||||||
|
term->meta.esc_prefix = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
||||||
|
|
@ -221,6 +221,7 @@ foot+base|foot base fragment,
|
||||||
rmcup=\E[?1049l\E[23;0t,
|
rmcup=\E[?1049l\E[23;0t,
|
||||||
rmir=\E[4l,
|
rmir=\E[4l,
|
||||||
rmkx=\E[?1l\E>,
|
rmkx=\E[?1l\E>,
|
||||||
|
rmm=\E[?1034l,
|
||||||
rmso=\E[27m,
|
rmso=\E[27m,
|
||||||
rmul=\E[24m,
|
rmul=\E[24m,
|
||||||
rmxx=\E[29m,
|
rmxx=\E[29m,
|
||||||
|
|
@ -235,6 +236,7 @@ foot+base|foot base fragment,
|
||||||
smcup=\E[?1049h\E[22;0t,
|
smcup=\E[?1049h\E[22;0t,
|
||||||
smir=\E[4h,
|
smir=\E[4h,
|
||||||
smkx=\E[?1h\E=,
|
smkx=\E[?1h\E=,
|
||||||
|
smm=\E[?1034h,
|
||||||
smso=\E[7m,
|
smso=\E[7m,
|
||||||
smul=\E[4m,
|
smul=\E[4m,
|
||||||
smxx=\E[9m,
|
smxx=\E[9m,
|
||||||
|
|
|
||||||
100
input.c
100
input.c
|
|
@ -451,44 +451,82 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
||||||
#define is_control_key(x) ((x) >= 0x40 && (x) <= 0x7f)
|
#define is_control_key(x) ((x) >= 0x40 && (x) <= 0x7f)
|
||||||
#define IS_CTRL(x) ((x) < 0x20 || ((x) >= 0x7f && (x) <= 0x9f))
|
#define IS_CTRL(x) ((x) < 0x20 || ((x) >= 0x7f && (x) <= 0x9f))
|
||||||
|
|
||||||
if ((keymap_mods & MOD_CTRL) &&
|
if ((keymap_mods & MOD_CTRL) &&
|
||||||
!is_control_key(sym) &&
|
!is_control_key(sym) &&
|
||||||
(count == 1 && !IS_CTRL(buf[0])) &&
|
(count == 1 && !IS_CTRL(buf[0])) &&
|
||||||
sym < 256)
|
sym < 256)
|
||||||
{
|
{
|
||||||
static const int mod_param_map[32] = {
|
static const int mod_param_map[32] = {
|
||||||
[MOD_SHIFT] = 2,
|
[MOD_SHIFT] = 2,
|
||||||
[MOD_ALT] = 3,
|
[MOD_ALT] = 3,
|
||||||
[MOD_SHIFT | MOD_ALT] = 4,
|
[MOD_SHIFT | MOD_ALT] = 4,
|
||||||
[MOD_CTRL] = 5,
|
[MOD_CTRL] = 5,
|
||||||
[MOD_SHIFT | MOD_CTRL] = 6,
|
[MOD_SHIFT | MOD_CTRL] = 6,
|
||||||
[MOD_ALT | MOD_CTRL] = 7,
|
[MOD_ALT | MOD_CTRL] = 7,
|
||||||
[MOD_SHIFT | MOD_ALT | MOD_CTRL] = 8,
|
[MOD_SHIFT | MOD_ALT | MOD_CTRL] = 8,
|
||||||
[MOD_META] = 9,
|
[MOD_META] = 9,
|
||||||
[MOD_META | MOD_SHIFT] = 10,
|
[MOD_META | MOD_SHIFT] = 10,
|
||||||
[MOD_META | MOD_ALT] = 11,
|
[MOD_META | MOD_ALT] = 11,
|
||||||
[MOD_META | MOD_SHIFT | MOD_ALT] = 12,
|
[MOD_META | MOD_SHIFT | MOD_ALT] = 12,
|
||||||
[MOD_META | MOD_CTRL] = 13,
|
[MOD_META | MOD_CTRL] = 13,
|
||||||
[MOD_META | MOD_SHIFT | MOD_CTRL] = 14,
|
[MOD_META | MOD_SHIFT | MOD_CTRL] = 14,
|
||||||
[MOD_META | MOD_ALT | MOD_CTRL] = 15,
|
[MOD_META | MOD_ALT | MOD_CTRL] = 15,
|
||||||
[MOD_META | MOD_SHIFT | MOD_ALT | MOD_CTRL] = 16,
|
[MOD_META | MOD_SHIFT | MOD_ALT | MOD_CTRL] = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert(keymap_mods < sizeof(mod_param_map) / sizeof(mod_param_map[0]));
|
assert(keymap_mods < sizeof(mod_param_map) / sizeof(mod_param_map[0]));
|
||||||
int modify_param = mod_param_map[keymap_mods];
|
int modify_param = mod_param_map[keymap_mods];
|
||||||
assert(modify_param != 0);
|
assert(modify_param != 0);
|
||||||
|
|
||||||
char reply[1024];
|
char reply[1024];
|
||||||
snprintf(reply, sizeof(reply), "\x1b[27;%d;%d~", modify_param, sym);
|
snprintf(reply, sizeof(reply), "\x1b[27;%d;%d~", modify_param, sym);
|
||||||
term_to_slave(term, reply, strlen(reply));
|
term_to_slave(term, reply, strlen(reply));
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
if (effective_mods & alt) {
|
||||||
|
/*
|
||||||
|
* When the alt modifier is pressed, we do one out of three things:
|
||||||
|
*
|
||||||
|
* 1. we prefix the output bytes with ESC
|
||||||
|
* 2. we set the 8:th bit in the output byte
|
||||||
|
* 3. we ignore the alt modifier
|
||||||
|
*
|
||||||
|
* #1 is configured with \E[?1036, and is on by default
|
||||||
|
*
|
||||||
|
* If #1 has been disabled, we use #2, *if* it's a single
|
||||||
|
* byte we're emitting. Since this is an UTF-8 terminal,
|
||||||
|
* we then UTF8-encode the 8-bit character. #2 is
|
||||||
|
* configured with \E[?1034, and is on by default.
|
||||||
|
*
|
||||||
|
* Lastly, if both #1 and #2 have been disabled, the alt
|
||||||
|
* modifier is ignored.
|
||||||
|
*/
|
||||||
|
if (term->meta.esc_prefix) {
|
||||||
|
term_to_slave(term, "\x1b", 1);
|
||||||
|
term_to_slave(term, buf, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (term->meta.eight_bit && count == 1) {
|
||||||
|
const wchar_t wc = 0x80 | buf[0];
|
||||||
|
|
||||||
|
char utf8[8];
|
||||||
|
mbstate_t ps = {0};
|
||||||
|
size_t chars = wcrtomb(utf8, wc, &ps);
|
||||||
|
|
||||||
|
if (chars != (size_t)-1)
|
||||||
|
term_to_slave(term, utf8, chars);
|
||||||
|
else
|
||||||
|
term_to_slave(term, buf, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (effective_mods & alt)
|
/* Alt ignored */
|
||||||
term_to_slave(term, "\x1b", 1);
|
|
||||||
|
|
||||||
term_to_slave(term, buf, count);
|
term_to_slave(term, buf, count);
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
term_to_slave(term, buf, count);
|
||||||
|
}
|
||||||
|
|
||||||
clock_gettime(
|
clock_gettime(
|
||||||
term->wl->presentation_clock_id, &term->render.input_time);
|
term->wl->presentation_clock_id, &term->render.input_time);
|
||||||
|
|
|
||||||
|
|
@ -652,6 +652,10 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
||||||
.normal = {.damage = tll_init(), .scroll_damage = tll_init()},
|
.normal = {.damage = tll_init(), .scroll_damage = tll_init()},
|
||||||
.alt = {.damage = tll_init(), .scroll_damage = tll_init()},
|
.alt = {.damage = tll_init(), .scroll_damage = tll_init()},
|
||||||
.grid = &term->normal,
|
.grid = &term->normal,
|
||||||
|
.meta = {
|
||||||
|
.esc_prefix = true,
|
||||||
|
.eight_bit = true,
|
||||||
|
},
|
||||||
.tab_stops = tll_init(),
|
.tab_stops = tll_init(),
|
||||||
.wl = wayl,
|
.wl = wayl,
|
||||||
.render = {
|
.render = {
|
||||||
|
|
@ -1032,6 +1036,9 @@ term_reset(struct terminal *term, bool hard)
|
||||||
selection_cancel(term);
|
selection_cancel(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
term->meta.esc_prefix = true;
|
||||||
|
term->meta.eight_bit = true;
|
||||||
|
|
||||||
if (!hard)
|
if (!hard)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,11 @@ struct terminal {
|
||||||
|
|
||||||
struct font *fonts[4];
|
struct font *fonts[4];
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool esc_prefix;
|
||||||
|
bool eight_bit;
|
||||||
|
} meta;
|
||||||
|
|
||||||
tll(int) tab_stops;
|
tll(int) tab_stops;
|
||||||
|
|
||||||
struct wayland *wl;
|
struct wayland *wl;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue