Unfortunately the concept of keysyms leaves too much room for vendor-dependent interpretations on how to bind keycodes to keysyms. A constant source for confusion and frustration is the key at the top right of the alphanumeric key area. Some vendors bind this key to the keysym XK_BackSpace, some others to the keysym XK_Delete.
The simplest way would be to change the keyboard mapping of the server. But this would affect all clients connected to that server - especially the non-LESSTIF ones. In order to reassert some (basic) consistency, the CSF introduced the ``CSF keysyms''. The CSF keysyms form a special set of keysyms. Depending on the X server's vendor, certain keycodes are translated into CSF keysyms. The mappings between keysyms and CSF keysyms are also known as the ``virtual bindings'' (see figure ). The conversion between keypresses and keysyms takes place in XmTranslateKey().
When converting ordinary innocent keysyms into CSF keysyms the modifiers must be taken into consideration. Unfortunately, we have to cope with different kinds of modifiers when looking at the virtual binding mechanism or the translation manager. An example shall enlighten the problem arising from this. Suppose your new WYSIWYWAA widget (WHAT YOU SEE ISN'T WHAT YOU WANTED AFTER ALL) also features an ``undo'' operation. The undo is activated by pressing the keys ALT and together. Somewhere in your widget's translation table you'll have to write:
Alt<Key>osfDelete: undo() Meta<Key>osfDelete: undo()
As LESSTIF - or its ``alter ego'' M*TIF - converts some of the standard keysyms into virtual keysyms, you can't use the standard keysym name Delete but must use osfDelete. The translation manager will never see the original keysym but only the virtual keysym.
Although the ``Alt'' modifier preceeding the keypress translation ``<Key>'' looks suspiciously like any ordinary modifier (e.g., Shift), it isn't one! X provides for eight modifiers alltogether, but only Shift, Lock, and Control are predefined. The remaining five modifiers Mod1 up to Mod5 can be freely mapped to any key. Smart as the Xt intrinsics are, they convert the translation Alt<Key>osfDelete into a translation using the Alt key instead of a (ficious) ``Alt'' modifier. Unfortunately, many programmers aren't aware of this.
Thus, when looking at translations, it is very important to distinct between the two sets of real modifiers and fake modifiers: The real modifiers are: Shift, Lock, Ctrl, Mod1 up to Mod5, and the mouse buttons Button1 up to Button5, whereas fake modifiers are: Alt, Meta, Super, and Hyper.
During the process of converting keysyms into CSF keysyms (in XmTranslateKey()) no translation mechanism is present. All we have is the current state of the modifiers recorded in the KeyPress event. But only Shift, Lock, and Control are predefined. So what to do with virtual bindings which are supposed to translate Alt'ed keysyms into CSF keysyms?
The CSF decided to ignore the problem as good as possible when developing M*TIF, and depends on the user mapping the Alt key on the keyboard to the Mod1 modifier. You can test this by changing your mapping such, that Alt maps to Mod2. The respective virtual bindings won't work any longer.
LESSTIF is much smarter than M*TIF (What?! Impossible!). Unfortunately, the XmTranslateKey() converter can't maintain the current keyboard state of the Alt and Meta keys as it gets called from the translation manager many times even for every single keystroke. Thus, during startup LESSTIF tries to find out to which modifier the Alt key has been bound to. LESSTIF does this basically by scanning the modifier mapping (as returned by XGetModifierMapping()) for the modifier bound to the keysyms XK_Alt_L or XK_Alt_R. If none can be found LESSTIF falls back to use Mod1. The whole procedure is so easy to implement, I can't understand why the CSF didn't get the trick in the past. If you're interested how LESSTIF does it, take a look at the file (LESSTIF_ROOT)/libXm/VirtKeys.c. The source is commented (really!).