How to find out the escape sequence the keyboards sends to terminal

escape-characterskeyboardterminal

Let's say we have a generic keyboard with some unknown keys which may send escape sequences to terminal.

The keyboard is connected to an xterm terminal emulator running on a generic BSD/Linux.

To create correct mapping for the unknown keys, we must first know what escape sequences they send to the xterm.

But how to know what escape sequences the keys send?

Best Answer

Your keyboard is not connected to xterm. It's connected to your PC. A kernel driver knows how to decode the key press and release sent by the keyboard and make that available to applications via a generic API on special device file.

An X server is such an application that uses that API.

It translates those key presses and releases into X "KeyPress" and "KeyRelease" events which carry with them the information of the key pressed as both a keycode and a keysym. That's another API.

xterm is an X application. It connects to an X server and tells it: I'm interested in all KeyPress and KeyRelease events. When it has the focus and when the KeyPress and KeyRelease events are not hijacked by your Window Manager or other applications that register for some KeyPress events globally, xterm will receive the KeyPress and KeyRelease events.

xterm translates a keysym in a KeyPress event into a sequence of characters it sends to the master side of a pseudo-terminal driver. Applications running in your xterm will eventually read from the slave side of that pseudo-terminal driver the characters sent by xterm, but potentially altered by the pseudo-terminal driver (for instance, under some conditions, 0xd characters are translated to 0xa ones, 0x3 would cause a SIGINT to be sent...).

With those clarifications out of the way. To know which keycode or keysym is sent by the X server upon a given key press, you can use xev.

To know which sequence of characters (if any) is sent by xterm, you need to tell the pseudo-terminal driver not to mingle with them first (stty raw) and then you can use cat -vt or sed -n l or od to see them:

{
  stty  raw min 1 time 20 -echo
  dd count=1 2> /dev/null | od -vAn -tx1
  stty sane
}

(above adding a min 1 time 20 and using dd so it exits after one keypress as you wouldn't be able to exit with Ctrl-C otherwise).