C3270/keymap
A keymap is a mapping from keys to actions. For example, pressing the F1 key on the keyboard may be mapped onto the action PF(1).
There is also a default handler for keyboard input, that handles input of text characters.
The keymap resource or the -keymap command-line option specify the name of the keymap to use. Multiple names can also be specified, separated by commas. If there are any conflicts in the entries, the entries from keymaps later in the list replace those from earlier in the list.
Mode-specific keymaps
c3270 also supports mode-specific keymaps.
By default, a keymap applies no matter what mode c3270 is in. However, if the current keymap is named foo, and a keymap definition exists for the name foo.3270, then the mappings in foo.3270 will apply only when c3270 is in 3270 mode. Similarly, if there is a keymap definition for foo.nvt, it will apply only when c3270 is in NVT mode.
Temporary keymaps
The Keymap() action allows for a temporary keymap. When Keymap() is invoked with a parameter, a keymap by that name will be applied, and its definitions will override any matching definitions in the current keymap. When Keymap() is invoked without a parameter, any temporary keymap will be removed.
Where c3270 finds keymap definitions
c3270 finds keymap definitions in three places, which it searches in order:
Compiled-in definitions
c3270 includes a compiled-in definition for the default keymap, called base.
Resource definitions
If there is no compiled-in definition for a keymap, c3270 will look for a resource definition. The resource containing the definition of the keymap named foo is keymap.foo.
Resources are defined in three places:
- In the file .c3270pro in the user's home directory.
- In a c3270 session file.
- Through a command-line option (-set or -xrm).
Files
If there is no compiled-in definition and no resource definition, c3270 will look for the keymap named foo in the file named foo. There is no file name suffix or path convention for keymap files.
Rules for keymap definitions
Keymaps in resources
If a keymap is defined in a resource, it must be defined as a multi-line resource. For example:
c3270.keymap.foo: \ Ctrl<Key>q: PrintText()\n\ Ctrl<Key>w: NextWord()\n\ Ctrl<Key>x: Disconnect()
Note that the first line ends with a \
. The "middle" lines end with the sequence \n\
, and the last line has no special ending.
Keymaps in files
When a keymap is defined in a file, none of the special line endings are needed. In a file, the above example would be:
Ctrl<Key>q: PrintText() Ctrl<Key>w: NextWord() Ctrl<Key>x: Disconnect()
Syntax
The format of a keymap entry is:
[modifier...]<Key>keyname: Action([arg[,...]])... [modifier...]<Key>keyname [modifier...]<Key>keyname: Action([arg[,...]])...
- modifier
- Zero or more keyboard modifiers:
- Ctrl: the Ctrl modifier key.
- Alt: the Alt modifier key.
- keyname
- A literal character such as a
- A curses key name such as F1
- An ISO 8859-1 symbolic name for a key, such as colon (the : key)
- A Unicode code point, e.g., U+0041 for A
- Action
- A c3270 action and its arguments.
Multiple-key matches
An entry can match a sequence of keys. For example:
Ctrl<Key>a <Key>r: Reset()
This entry matches the Ctrl-a key, followed by the r key.
Multiple-action entries
An entry can execute multiple actions. For example:
Ctrl<Key>x: String("hello") Newline()
This entry maps the key Ctrl-x to two actions, String() followed by Newline().
The Alt modifier
c3270 has a specific notion of the Alt key on a PC keyboard. Some terminal emulators generate a two-character sequence when Alt is pressed with a data key: they generate an ESC character (U+001B), followed by the usual value of the data key. For example, pressing Alt with a generates ESC (U+001B) followed by a (U+0061). But not all terminals behave this way.
c3270 does not know if your terminal or terminal emulator generates these two-character sequences, or does not. Your terminal might generate something altogether different, or it might not even have an Alt key on the keyboard. Regardless, if you define a keymap entry that uses the Alt modifier, c3270 will match that entry only if your terminal generates a two-character sequence as described here.
Ordering rules
Unlike in x3270, there are no ordering rules for c3270 keymaps. Entries for <Key>c, Ctrl<Key>c and Alt<Key>c are unrelated and can appear in any order.
If for some reason the same match appears in more than one entry, the first one will be used. This will be indicated in the output of Show(Keymap) with the unused entry(ies) replaced by the text superceded by xxx.
How to figure out what keys are being generated
To find out which key name or sequence of key names is being generated for any given key on your keyboard:
- Start c3270 with the -trace command-line option.
- Connect to a host.
- Press the key(s) in question.
- Exit c3270.
c3270 will create a trace file called /tmp/x3trc.pid
.
In that file, several lines of text will be generated for each key you press. For example:
20200324.223022.236 kbd_input: k=256 wch=265 20200324.223022.236 Key '<Key>F1' (curses key 0x109, char code 0x0)
In this trace, the key generated the input event <Key>F1, which you can paste directly into your keymap definition.
Fundamental limitations
c3270 has the weakest ability to configure the keyboard of any emulator in the x3270 family. This is because it is based on curses, and is designed to run on "dumb" terminals.
Unlike a PC or Mac, a "dumb" terminal keyboard does not generate any sort of input event when a modifier key (such as Shift, Ctrl or Alt) is pressed. So c3270 cannot see when these keys are pressed by themselves and released, which makes it impossible to do commonly-desired mappings such as using Right-Ctrl for Enter(). Also, a "dumb" terminal tends to generate the same input character (U+0009) when the Tab key is pressed, regardless of what other modifier keys are pressed. This makes an obvious mapping for BackTab() (Shift-Tab) impossible. Similarly, these devices (or device emulators) often generate the same input character for the keypad as for the main keyboard, such as U+000D for both Enter keys, so it is impossible to define different actions for each.
Keymap debugging
There are two c3270 options to aid with keymap debugging.
The -trace command-line option causes c3270 to create a
trace file, /tmp/x3trc.pid
.
That file traces (among other things) each keyboard event that c3270 processes.
The information traced includes the keymap (and line within the keymap)
that matched the event, and the c3270 actions that were run in response.
The Show(Keymap) action at the c3270> prompt displays the current keymap. This tells you exactly which keymap entries are active. Often times it will point out that c3270 isn't using the keymap you thought it was, or that some of your keymap entries are interfering with one another.
Note that a common problem in configuring c3270 is figuring out where resources are defined. The rules for specifying resource values are listed under c3270 resources.
The trouble with Alt
You may reach a point where you simply cannot find a terminfo entry (terminal name) that works correctly for your terminal or emulator. For example, you may find that a particular function key or keypad key generates garbage input instead of being translated into a clean abstract symbol like F1. In that case, you may need to create a keymap to explicitly match the escape sequence coming from the terminal, using a multi-key match.
The procedure outlined above will work for this, but with one caveat: the Alt modifier. c3270 thinks that the input sequence of Esc (U+001B) followed by some character means that Alt was pressed with that character. So for example, if when you press F1, your terminal generates this sequence:
Esc [ 1 1 ~
that is:
U+001B U+005B U+0031 U+0031 U+007E
c3270 will interpret this five-character sequence as a four-key sequence, combining the Esc and [ into Alt-[.
A keymap entry that will match this sequence is:
Alt<Key>[ <Key>1 <Key>1 <Key>~: PF(1)
Do not try this sort of entry. It will not work.
<Key>Esc <Key>[ <Key>1 <Key>1 <Key>~: PF(1) Wrong!