Here is an updated version of this patch. Unlike the first version which just added some new control sequences in order to fix the display, this also touches some input code.
New in this version: * F1 - F4 now send different sequences. * F13 - F24 now send different sequences, but see notes below about F13 - F16. * With numlock OFF, keypad 5 is now 'begin' rather than unused. * Home, End, keypad home, and keypad end now send different sequences. * A new keysym has been added - KS_Backtab. * Shift-TAB is now defined as KS_Backtab and sends ESC [ Z. * Shift-F1 - Shift-F12 now send F13 - F24. Details: * F1 - F24 now send different sequences F1 - F4 and F17 - F24 now send the sequences expected by the xterm terminfo entry. Those for F1 - F4 are the same as the PF1 - PF4 sequences. The sequences previously used for F1 - F4 did not correspond to a particular hardware terminal. F13 - F16 are interesting. By default, a real xterm running on OpenBSD does not get the sequences it wants for these keys: F13, for example, sends 'ESC O 2 P'. But the terminfo wants 'ESC [ 1 ; 2 P'. The codes that xterm actually sends for these keys by default on OpenBSD are the codes defined in xterm-xf86-v40 and xterm+pcf0, but by using the plain xterm entry, we're expecting the codes for xterm+pcf2. So F13 - F16 have long been broken in xterm, and nobody has complained. F13 and F14 currently work in vt220, but F15 and F16 don't. A real hardware vt220 doesn't have keys marked F15 and F16, instead they are marked help and do. This is reflected in the vt220 terminfo entry. F13 - F16 do currently work in pccon, (without my patch). My patch changes wscons to send the codes that will be recognised by the xterm terminfo entry, making this aspect of TERM=xterm work on the console. So the only users who might be disappointed will be those who currently rely on the buggy behaviour of a real xterm running with the OpenBSD default settings, and who hope or expect to now see this same buggy behaviour on the console. * With numlock OFF, keypad 5 is now 'begin' rather than being unused. Previously, KS_Begin was a NOP. However, the xterm terminfo entry includes a sequence for keypad begin, so I've made wscons send that sequence. This matches the behaviour of a real xterm, so anybody actually using this key in a program should be happy that it now works on the console. * Home, End, keypad home, and keypad end now send different sequences. These codes have been changed to match the xterm terminfo entry. The vt220 terminfo entry does not recognise the old codes for home and end, so only users using pccon or a similar terminal type would have been able to use it in programs that parse terminfo. Now it works fine on the console with TERM=xterm. * A new keysym has been added - KS_Backtab, mapped to Shift-TAB X sees shift-tab as ISO_Left_Tab, and xterm maps this to ESC [ Z, which the terminfo interprets as Backtab. With my patch, a new keysym KS_Backtab is defined, and the console also generates the sequence ESC [ Z. This is then also mapped to Backtab. * Shift-F1 - Shift-F12 now send F13 - F24. This matches what X does, and also makes testing F13 - F24 possible for the majority of users who don't have a keyboard with these physical keys. ******************** * Issues remaining * ******************** The main area left in which the console does not match a real xterm in terms of keyboard input is in _application mode_. Note to those testing this: when switching between the console and X, the numlock LED on the keyboard may become out of sync with the actual status of numlock on the system. So toggle it before doing further tests. In xterm, with keypad application mode ON, (DECKPAM), and numlock OFF: * The keypad keys work as their cursor movement counterparts on the main keyboard, I.E. they send the sequences for home, end, page up, etc. * The keypad - key sends ESC O m, like a real vt220 * The keypad / * and + keys send ESC O o, ESC O j, and ESC O k, but these do not correspond to a real vt220, because the real vt220 didn't have these keys. In xterm, with keypad application mode ON, (DECKPAM), and numlock ON: * The keypad works the same as in non-application mode, I.E. numbers produce numbers, and / * - and + produce / * - and +. This means that with a real xterm in our current default configuration, you _cannot_ get distinct sequences for the keypad keys. On the console, with keypad application mode ON, (DECKPAM), and numlock OFF: * The keypad keys behave the same as described above for xterm in this situation. On the console, with keypad application mode ON, (DECKPAM), and numlock ON: * The keypad generates sequences consistent with a real vt220 for keys that exist on a real vt220, and ones in a similar vein for those that don't. So on the console, you currently can get distinct sequences. This is a bit awkward, because even though the distinct sequences generated in application mode are not recognised by any of the terminfo entries that are in common use on OpenBSD systems, (vt220, xterm, and pccon), there might plausibly be users using them, either in software that ignores terminfo and does it's own thing, or on remote systems, (E.G. mainframe applications), where these vt220 sequences are recognised. Of course, this doesn't currently work by default in X, so any such users would presumably be using the console. For the time being, I have left the current behaviour. The upshot of this is that if you currently use a curses program in a real xterm that uses the keypad in application mode and expects to get numbers when numlock is ON, then it will not, (yet), work on the console using my patches. If, on the other hand, you currently use a program on the console that sends unique control sequences for keypad keys, then this might break in a future version of this patch. --- dev/wscons/wsemul_vt100_keys.c.dist Sat Mar 14 00:38:50 2015 +++ dev/wscons/wsemul_vt100_keys.c Mon Jan 2 16:01:42 2023 @@ -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: @@ -174,14 +180,27 @@ case KS_KP_Next: *out = "\033[6~"; return (4); + 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) --- dev/wscons/wsemul_vt100_subr.c.dist Mon May 25 06:55:49 2020 +++ dev/wscons/wsemul_vt100_subr.c Mon Jan 2 18:26:03 2023 @@ -461,6 +461,9 @@ edp->ccol -= min(DEF1_ARG(0), edp->ccol); edp->flags &= ~VTFL_LASTCHAR; break; + case 'G': /* HPA */ + edp->ccol = min(DEF1_ARG(0)-1, edp->ncols-1); + break; case 'H': /* CUP */ case 'f': /* HVP */ if (edp->flags & VTFL_DECOM) @@ -502,16 +505,37 @@ WSEMULOP(rc, edp, &edp->abortstate, erasecols, ERASECOLS(NCOLS - n, n, edp->bkgdattr)); break; + case 'S': /* INDN */ + wsemul_vt100_scrollup (edp,DEF1_ARG(0)); + break; + case 'T': /* RIN */ + wsemul_vt100_scrolldown (edp,DEF1_ARG(0)); + break; case 'X': /* ECH erase character */ n = min(DEF1_ARG(0), COLS_LEFT + 1); WSEMULOP(rc, edp, &edp->abortstate, erasecols, ERASECOLS(edp->ccol, n, edp->bkgdattr)); break; + case 'Z': /* KCBT */ + if (!edp->ccol) + break; + if (edp->tabs) { + for (n=edp->ccol-1 ; n>0; n--) + if (edp->tabs[n]) + break; + } else { + n=((edp->ccol - 1) & 8); + } + edp->ccol=n; + break; case 'c': /* DA primary */ if (ARG(0) == 0) wsdisplay_emulinput(edp->cbcookie, WSEMUL_VT_ID1, sizeof(WSEMUL_VT_ID1)); break; + case 'd': /* VPA */ + edp->crow = min(DEF1_ARG(0)-1, edp->nrows-1); + break; case 'g': /* TBC */ if (edp->tabs != NULL) switch (ARG(0)) { --- dev/wscons/wsksymdef.h.dist Mon Sep 20 14:32:39 2021 +++ dev/wscons/wsksymdef.h Mon Jan 2 15:48:18 2023 @@ -626,6 +626,7 @@ #define KS_Open 0xf393 #define KS_Paste 0xf394 #define KS_Cut 0xf395 +#define KS_Backtab 0xf396 #define KS_Menu 0xf3c0 #define KS_Pause 0xf3c1 --- dev/pckbc/wskbdmap_mfii.c.dist Sat May 1 13:11:16 2021 +++ dev/pckbc/wskbdmap_mfii.c Mon Jan 2 13:51:12 2023 @@ -59,7 +59,7 @@ KC(12), KS_minus, KS_underscore, KC(13), KS_equal, KS_plus, KC(14), KS_Cmd_ResetEmul, KS_Delete, - KC(15), KS_Tab, + KC(15), KS_Tab, KS_Backtab, KC(16), KS_q, KC(17), KS_w, KC(18), KS_e, @@ -103,16 +103,16 @@ KC(56), KS_Cmd2, KS_Alt_L, KC(57), KS_space, KC(58), KS_Caps_Lock, - KC(59), KS_Cmd_Screen0, KS_f1, - KC(60), KS_Cmd_Screen1, KS_f2, - KC(61), KS_Cmd_Screen2, KS_f3, - KC(62), KS_Cmd_Screen3, KS_f4, - KC(63), KS_Cmd_Screen4, KS_f5, - KC(64), KS_Cmd_Screen5, KS_f6, - KC(65), KS_Cmd_Screen6, KS_f7, - KC(66), KS_Cmd_Screen7, KS_f8, - KC(67), KS_Cmd_Screen8, KS_f9, - KC(68), KS_Cmd_Screen9, KS_f10, + KC(59), KS_Cmd_Screen0, KS_f1, KS_f13, + KC(60), KS_Cmd_Screen1, KS_f2, KS_f14, + KC(61), KS_Cmd_Screen2, KS_f3, KS_f15, + KC(62), KS_Cmd_Screen3, KS_f4, KS_f16, + KC(63), KS_Cmd_Screen4, KS_f5, KS_f17, + KC(64), KS_Cmd_Screen5, KS_f6, KS_f18, + KC(65), KS_Cmd_Screen6, KS_f7, KS_f19, + KC(66), KS_Cmd_Screen7, KS_f8, KS_f20, + KC(67), KS_Cmd_Screen8, KS_f9, KS_f21, + KC(68), KS_Cmd_Screen9, KS_f10, KS_f22, KC(69), KS_Num_Lock, KC(70), KS_Hold_Screen, KC(71), KS_KP_Home, KS_KP_7, @@ -128,8 +128,8 @@ KC(81), KS_KP_Next, KS_KP_3, KC(82), KS_KP_Insert, KS_KP_0, KC(83), KS_KP_Delete, KS_KP_Decimal, - KC(87), KS_Cmd_Screen10, KS_f11, - KC(88), KS_Cmd_Screen11, KS_f12, + KC(87), KS_Cmd_Screen10, KS_f11, KS_f23, + KC(88), KS_Cmd_Screen11, KS_f12, KS_f24, KC(91), KS_f13, KC(92), KS_f14, KC(93), KS_f15,