Index | Thread | Search

From:
Crystal Kolipe <kolipe.c@exoticsilicon.com>
Subject:
Make wscons F1 - F4 match xterm, (and fix vt220 breakage)
To:
tech@openbsd.org
Date:
Tue, 10 Jun 2025 15:57:49 -0300

Download raw body.

Thread
This patch changes the sequences sent by wscons for F1 - F4 to match xterm.

There are also changes for F13 - F24, begin, home, and end.


Rationale:

The default wscons termtype is vt220.  By default, programs that use terminfo
are broken on the console, because F1 - F4 are not recognised.

Sequences currently sent for F1 - F4 are: ^[[11~, ^[[12~, ^[[13~, and ^[[14~.

The vt220 emulation expects ^[OP, ^[OQ, ^[OR, and ^[OS.

The xterm terminfo entry also expects ^[OP, ^[OQ, ^[OR, and ^[OS.

Although the current sequences work with 'pccon', the pccon terminfo entry is
broken in various ways with respect to current wscons behaviour.

Furthermore, with the various improvements to wscons over the last few
releases, compatibility with the various xterm typetypes is now much better
than basically anything else, (including vt220).

--- wsemul_vt100_keys.c
+++ wsemul_vt100_keys.c
@@ -37,11 +37,9 @@
 #include <dev/wscons/wsemulvar.h>
 #include <dev/wscons/wsemul_vt100var.h>
 
+#define vt100_fkeys_len(x) (5 + (x >= 8) + (x >= 12))
+
 static const u_char *vt100_fkeys[] = {
-	"\033[11~",	/* F1 */
-	"\033[12~",
-	"\033[13~",		/* F1-F5 normally don't send codes */
-	"\033[14~",
 	"\033[15~",	/* F5 */
 	"\033[17~",	/* F6 */
 	"\033[18~",
@@ -50,18 +48,18 @@
 	"\033[21~",
 	"\033[23~",	/* VT100: ESC */
 	"\033[24~",	/* VT100: BS */
-	"\033[25~",	/* VT100: LF */
-	"\033[26~",
-	"\033[28~",	/* help */
-	"\033[29~",	/* do */
-	"\033[31~",
-	"\033[32~",
-	"\033[33~",
-	"\033[34~",	/* F20 */
-	"\033[35~",
-	"\033[36~",
-	"\033[37~",
-	"\033[38~"
+	"\033[1;2P",	/* VT100: LF */
+	"\033[1;2Q",
+	"\033[1;2R",	/* help */
+	"\033[1;2S",	/* do */
+	"\033[15;2~",
+	"\033[17;2~",
+	"\033[18;2~",
+	"\033[19;2~",	/* F20 */
+	"\033[20;2~",
+	"\033[21;2~",
+	"\033[23;2~",
+	"\033[24;2~"
 };
 
 static const u_char *vt100_pfkeys[] = {
@@ -96,14 +94,22 @@
 		    edp->translatebuf, edp->flags & VTFL_UTF8));
 	}
 
-	if (in >= KS_f1 && in <= KS_f24) {
-		*out = vt100_fkeys[in - KS_f1];
-		return (5);
+	if (in >= KS_f1 && in <= KS_f4) {
+		*out = vt100_pfkeys[in - KS_f1];
+		return (3);
 	}
-	if (in >= KS_F1 && in <= KS_F24) {
-		*out = vt100_fkeys[in - KS_F1];
-		return (5);
+	if (in >= KS_F1 && in <= KS_F4) {
+		*out = vt100_pfkeys[in - KS_F1];
+		return (3);
 	}
+	if (in >= KS_f5 && in <= KS_f24) {
+		*out = vt100_fkeys[in - KS_f5];
+		return vt100_fkeys_len(in - KS_f5);
+	}
+	if (in >= KS_F5 && in <= KS_F24) {
+		*out = vt100_fkeys[in - KS_F5];
+		return vt100_fkeys_len(in - KS_F5);
+	}
 	if (in >= KS_KP_F1 && in <= KS_KP_F4) {
 		*out = vt100_pfkeys[in - KS_KP_F1];
 		return (3);
@@ -148,12 +154,12 @@
 	}
 	switch (in) {
 	    case KS_Help:
-		*out = vt100_fkeys[15 - 1];
+		*out = vt100_fkeys[15 - 1 + 4]; /* vt100_fkeys starts at F5 */
 		return (5);
 	    case KS_Execute: /* "Do" */
-		*out = vt100_fkeys[16 - 1];
+		*out = vt100_fkeys[16 - 1 + 4]; /* vt100_fkeys starts at F5 */
 		return (5);
-	    case KS_Find:
+	    case KS_Find:			/* Not defined in xterm terminfo */
 		*out = "\033[1~";
 		return (4);
 	    case KS_Insert:
@@ -163,7 +169,7 @@
 	    case KS_KP_Delete:
 		*out = "\033[3~";
 		return (4);
-	    case KS_Select:
+	    case KS_Select:			/* Not defined in xterm terminfo */
 		*out = "\033[4~";
 		return (4);
 	    case KS_Prior:
@@ -177,14 +183,24 @@
 	    case KS_Backtab:
 		*out = "\033[Z";
 		return (3);
+	    /*
+	     * Unlike insert, delete, page up, and page down, we purposely don't
+	     * send the same sequence of \033OE for the non-keypad 'begin' key.
+	     *
+	     * This is because the terminfo xterm entry is mapping this to kb2,
+	     * which is defined as 'centre of keypad'.
+	     */
+	    case KS_KP_Begin:
+		*out = "\033OE";
+		return (3);
 	    case KS_Home:
 	    case KS_KP_Home:
-		*out = "\033[7~";
-		return (4);
+		*out = "\033OH";
+		return (3);
 	    case KS_End:
 	    case KS_KP_End:
-		*out = "\033[8~";
-		return (4);
+		*out = "\033OF";
+		return (3);
 	    case KS_Up:
 	    case KS_KP_Up:
 		if (edp->flags & VTFL_APPLCURSOR)