[PATCH 1/3] libkeymap: add support for KT_CSI keysym type
Nicolas Pitre <[email protected]> Thu, 11 Jun 2026 21:48:55 -0400
| Newsgroups | dev.linux.lists.kbd |
|---|---|
| Message-ID | <[email protected]> |
Add support for the new KT_CSI keysym type which provides modifier-aware CSI escape sequences for navigation and function keys. This eliminates the need to exhaust the limited func_table string entries for modifier combinations. The new Csi_* keysyms (Csi_Home, Csi_End, Csi_Delete, Csi_Insert, Csi_PgUp, Csi_PgDn, Csi_F1-F20) generate tilde-format CSI sequences with automatic modifier encoding when used with a supporting kernel. The kernel automatically falls back to the plain keymap entry when modifiers are held, encoding the modifier state into the output sequence, so only plain map entries need to be defined. Also add documentation for modifier-aware keys to keymaps(5), and update the libkeymap test fixture for the extended symbol table. Note: Requires Linux kernel 7.1 or later for KT_CSI support. On older kernels these keysyms load without effect on consoles in Unicode mode (the affected keys produce no output), and are rejected with EINVAL on non-Unicode consoles (loadkeys reports an error for each such entry but carries on). Signed-off-by: Nicolas Pitre <[email protected]> --- docs/man/man5/keymaps.5 | 77 ++++++++++++++++++++++++++++++++++ src/libkeymap/ksyms.c | 3 +- src/libkeymap/syms.ktyp.h | 39 +++++++++++++++++ tests/data/keymap0-summary.txt | 26 ++++++++++++ 4 files changed, 144 insertions(+), 1 deletion(-) diff --git a/docs/man/man5/keymaps.5 b/docs/man/man5/keymaps.5 index 072afe3..bfa75aa 100644 --- a/docs/man/man5/keymaps.5 +++ b/docs/man/man5/keymaps.5 @@ -353,6 +353,83 @@ and describe how two bytes are combined to form a third one (when a dead accent or compose key is used). This is used to get accented letters and the like on a standard keyboard. +.SH "MODIFIER-AWARE KEYS" +Certain key types automatically encode the current modifier state into +the escape sequence they produce. This eliminates the need to define +separate keymap entries for each modifier combination. +.SS "Cursor Keys" +The cursor keys (Up, Down, Left, Right) automatically include modifier +information when Shift, Alt, or Control are held. With no modifiers, +they produce the standard sequences (e.g., ESC [ A for Up). With +modifiers, they produce extended sequences in the format ESC [ 1 ; \fImod\fP X, +where \fImod\fP encodes the modifier state and X is the direction letter. +.LP +The modifier value is calculated as: 1 + (Shift?1:0) + (Alt?2:0) + (Control?4:0). +AltGr counts as Alt for this purpose. +For example, Shift+Up produces ESC [ 1 ; 2 A, and Control+Alt+Up +produces ESC [ 1 ; 7 A. +.SS "CSI Keys" +The Csi_* keysyms provide similar modifier-aware behavior for navigation +and function keys, generating sequences in the CSI tilde format +(ESC [ \fIn\fP ~ or ESC [ \fIn\fP ; \fImod\fP ~ with modifiers). +.LP +Available CSI keysyms and their unmodified sequences: +.RS +.TP 16 +.B Csi_Home +ESC [ 1 ~ +.TP +.B Csi_Insert +ESC [ 2 ~ +.TP +.B Csi_Delete +ESC [ 3 ~ +.TP +.B Csi_End +ESC [ 4 ~ +.TP +.B Csi_PgUp +ESC [ 5 ~ +.TP +.B Csi_PgDn +ESC [ 6 ~ +.TP +.B Csi_F1 \fR...\fB Csi_F12 +ESC [ 11 ~ through ESC [ 24 ~ (skipping 16 and 22) +.TP +.B Csi_F13 \fR...\fB Csi_F20 +ESC [ 25 ~ through ESC [ 34 ~ (skipping 27 and 30) +.RE +.LP +Note: The Csi_F* sequences follow the xterm numbering scheme, including +its gaps in the parameter numbering, which differs from the traditional +Linux console F1-F5 sequences (ESC [ [ A through ESC [ [ E). +.SS "Fallback Behavior" +When a cursor or CSI key is pressed with modifiers, and no explicit binding +exists for that modifier combination, the kernel automatically falls back +to the plain (unmodified) keymap entry. The modifier state is still encoded +in the output sequence. +.LP +This means you only need to define the plain keymap entry: +.LP +.RS +.nf +keycode 102 = Csi_Home +.fi +.RE +.LP +and all modifier combinations (Shift+Home, Control+Home, etc.) will +automatically produce the correct modified sequences without additional +keymap entries. +.LP +.B Note: +Modifier-aware key behavior requires Linux kernel 7.1 or later. +On older kernels, cursor keys produce their traditional unmodified +sequences, and Csi_* keysyms have no effect: on a console in Unicode +mode the corresponding keys produce no output, while on a non-Unicode +console +.BR loadkeys (1) +reports an error for each Csi_* entry. .SH ABBREVIATIONS Various abbreviations can be used with kbd-0.96 and later. .TP diff --git a/src/libkeymap/ksyms.c b/src/libkeymap/ksyms.c index 219e5f2..98d1cf3 100644 --- a/src/libkeymap/ksyms.c +++ b/src/libkeymap/ksyms.c @@ -52,7 +52,8 @@ static const syms_entry syms[] = { { NULL, 0 }, /* KT_LETTER */ E(sticky_syms), /* KT_SLOCK */ { NULL, 0 }, /* KT_DEAD2 */ - E(brl_syms) /* KT_BRL */ + E(brl_syms), /* KT_BRL */ + E(csi_syms) /* KT_CSI */ }; #undef E diff --git a/src/libkeymap/syms.ktyp.h b/src/libkeymap/syms.ktyp.h index 504d67e..aca0fc6 100644 --- a/src/libkeymap/syms.ktyp.h +++ b/src/libkeymap/syms.ktyp.h @@ -588,3 +588,42 @@ static const char *const brl_syms[] = { "Brl_dot9", "Brl_dot10" }; + +/* + * Keysyms whose KTYP is KT_CSI. + * Index is the CSI parameter number for ESC [ <index> ~ sequences. + */ +static const char *const csi_syms[] = { + "", /* 0: unused */ + "Csi_Home", /* 1: ESC [ 1 ~ */ + "Csi_Insert", /* 2: ESC [ 2 ~ */ + "Csi_Delete", /* 3: ESC [ 3 ~ */ + "Csi_End", /* 4: ESC [ 4 ~ */ + "Csi_PgUp", /* 5: ESC [ 5 ~ */ + "Csi_PgDn", /* 6: ESC [ 6 ~ */ + "", "", "", "", /* 7-10: unused */ + "Csi_F1", /* 11: ESC [ 11 ~ */ + "Csi_F2", /* 12: ESC [ 12 ~ */ + "Csi_F3", /* 13: ESC [ 13 ~ */ + "Csi_F4", /* 14: ESC [ 14 ~ */ + "Csi_F5", /* 15: ESC [ 15 ~ */ + "", /* 16: unused */ + "Csi_F6", /* 17: ESC [ 17 ~ */ + "Csi_F7", /* 18: ESC [ 18 ~ */ + "Csi_F8", /* 19: ESC [ 19 ~ */ + "Csi_F9", /* 20: ESC [ 20 ~ */ + "Csi_F10", /* 21: ESC [ 21 ~ */ + "", /* 22: unused */ + "Csi_F11", /* 23: ESC [ 23 ~ */ + "Csi_F12", /* 24: ESC [ 24 ~ */ + "Csi_F13", /* 25: ESC [ 25 ~ */ + "Csi_F14", /* 26: ESC [ 26 ~ */ + "", /* 27: unused */ + "Csi_F15", /* 28: ESC [ 28 ~ */ + "Csi_F16", /* 29: ESC [ 29 ~ */ + "", /* 30: unused */ + "Csi_F17", /* 31: ESC [ 31 ~ */ + "Csi_F18", /* 32: ESC [ 32 ~ */ + "Csi_F19", /* 33: ESC [ 33 ~ */ + "Csi_F20", /* 34: ESC [ 34 ~ */ +}; diff --git a/tests/data/keymap0-summary.txt b/tests/data/keymap0-summary.txt index 0b66c06..6f757fd 100644 --- a/tests/data/keymap0-summary.txt +++ b/tests/data/keymap0-summary.txt @@ -810,6 +810,32 @@ nr of compose definitions in actual use: 0 0x0e08 Brl_dot8 0x0e09 Brl_dot9 0x0e0a Brl_dot10 +0x0f01 Csi_Home +0x0f02 Csi_Insert +0x0f03 Csi_Delete +0x0f04 Csi_End +0x0f05 Csi_PgUp +0x0f06 Csi_PgDn +0x0f0b Csi_F1 +0x0f0c Csi_F2 +0x0f0d Csi_F3 +0x0f0e Csi_F4 +0x0f0f Csi_F5 +0x0f11 Csi_F6 +0x0f12 Csi_F7 +0x0f13 Csi_F8 +0x0f14 Csi_F9 +0x0f15 Csi_F10 +0x0f17 Csi_F11 +0x0f18 Csi_F12 +0x0f19 Csi_F13 +0x0f1a Csi_F14 +0x0f1c Csi_F15 +0x0f1d Csi_F16 +0x0f1f Csi_F17 +0x0f20 Csi_F18 +0x0f21 Csi_F19 +0x0f22 Csi_F20 The following synonyms are recognized: -- 2.54.0