inmbolmie / 5250_usb_converter

Converter to plug an IBM 5251 terminal to a Linux PC via USB emulating a VT52 terminal
GNU General Public License v3.0
34 stars 6 forks source link

Backspace key generates character 8 but `stty -a` shows `erase = ^?` #19

Open dcoshea opened 7 months ago

dcoshea commented 7 months ago

The initial symptom I encountered was that in GNU Emacs 24.3.1 running on CentOS 7.9, pressing the Backspace key (with the 122KEY_EN scancode table, but I think they're all the same in this regard) caused Emacs to show "C-h (Type ? for further options)-" which is a help prompt that on a modern system you'd obtain by pressing Ctrl-H.

An initial workaround for that issue which worked was to run M-x normal-erase-is-backspace-mode RET (where M-x probably has to be entered as ESC x with all current scancode tables).

Running infocmp -L vt52 shows that the terminfo entry suggests that generating character 8 is correct, as its output includes key_backspace=^H.

However, this post suggests that at least for older Unix variants, what is set via stty is more important than what is in the terminal database, and from testing this seems to be true. stty -a shows erase = ^?, indicating that the delete character is actually what the backspace key should generate. That is what xterm and rxvt-unicode generate - even xterm -ti vt52 -tn vt52, or at least that's what showkey --ascii reveals.

It seems that 5250_terminal.py could set up the terminal appropriately itself without the need to run stty by calling termios.tcsetattr(). This seemed to work to indicate that backspace will generate character 8, when run from a method invoked by Interceptor._init_fd():

attrs = termios.tcgetattr(self.master_fd)
attrs[CC][termios.VERASE] = 0x08
termios.tcsetattr(self.master_fd, termios.TCSANOW, attrs)

I think the best solution would be if each dictionary in scancodeDictionaries:

  1. had an entry like 'BACKSPACE_CHAR': chr(0x08) which Interceptor could use to determine what to set attrs[CC][termios.VERASE] to; and
  2. set the character to be generated by the scan code for the backspace key - or any key the user wanted to act like backspace - to some new constant which was defined in such a way that it couldn't be mistaken for a string when processing the dictionary entry, e.g.:
    # @enum.unique
    class KeyAction(enum.Enum):
    BACKSPACE = 0
    ...
    scancodeDictionaries = {
    ...
        0x3D: [KeyAction.BACKSPACE, KeyAction.BACKSPACE, '', ''],  # BS

and then when generating input to the PTY based on a key press, if an entry is set to that special value, the BACKSPACE_CHAR set in the dictionary is sent.

I'll try to address this soon but am in the middle of too many other things.

dcoshea commented 7 months ago

Just for my reference: I filed this based on a recollection of what occurred on my 3476 and testing with my work-in-progress emulator, but I've since verified that this accurately describes behavior on my 3476.