summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pitre <npitre@baylibre.com>2026-02-02 23:52:46 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-03-12 15:07:51 +0100
commit4af70f151671da6acd7a1d7bae1469c576673d2d (patch)
tree4cb2e834bfc2032df2c66720ed2809db16098165
parent24728b93fafe0949b5353e1a7b3a94175fe26d6e (diff)
downloadlwn-4af70f151671da6acd7a1d7bae1469c576673d2d.tar.gz
lwn-4af70f151671da6acd7a1d7bae1469c576673d2d.zip
vt: add modifier support to cursor keys
Generate xterm-style CSI sequences with modifier parameters for arrow keys when Shift, Alt, or Ctrl are held. For example, Shift+Up produces ESC [ 1 ; 2 A instead of plain ESC [ A. The modifier encoding follows the standard xterm convention: mod = 1 + (shift ? 1 : 0) + (alt ? 2 : 0) + (ctrl ? 4 : 0) When no modifiers are pressed, the original behavior is preserved. Explicit keymap bindings for modified cursor keys (e.g., "shift keycode 103 = Find") take precedence over this automatic modifier encoding. Signed-off-by: Nicolas Pitre <npitre@baylibre.com> Link: https://patch.msgid.link/20260203045457.1049793-2-nico@fluxnic.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/vt/keyboard.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 13bc048f45e8..cb907a3b9d3d 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -765,14 +765,39 @@ static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
pr_err("k_fn called with value=%d\n", value);
}
+/*
+ * Compute xterm-style modifier parameter for CSI sequences.
+ * Returns 1 + (shift ? 1 : 0) + (alt ? 2 : 0) + (ctrl ? 4 : 0)
+ */
+static int csi_modifier_param(void)
+{
+ int mod = 1;
+
+ if (shift_state & (BIT(KG_SHIFT) | BIT(KG_SHIFTL) | BIT(KG_SHIFTR)))
+ mod += 1;
+ if (shift_state & (BIT(KG_ALT) | BIT(KG_ALTGR)))
+ mod += 2;
+ if (shift_state & (BIT(KG_CTRL) | BIT(KG_CTRLL) | BIT(KG_CTRLR)))
+ mod += 4;
+ return mod;
+}
+
static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
{
static const char cur_chars[] = "BDCA";
+ int mod;
if (up_flag)
return;
- applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
+ mod = csi_modifier_param();
+ if (mod > 1) {
+ char buf[] = { 0x1b, '[', '1', ';', '0' + mod, cur_chars[value], 0x00 };
+
+ puts_queue(vc, buf);
+ } else {
+ applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
+ }
}
static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)