Keyboard Internationalisation

Keyboard processing including internationalisation
Different input devices can be attached to the XBMC:
 * gamepad
 * remote
 * universal remote
 * keyboard

All these devices have several hardware buttons. Keyboards usually have about 100+ keys. Each key sends a unique scancode. Scancodes are usually encoded within a byte (a decimal from 0 to 255) sometime with some additional control codes signalizing the press or the release of the key. From the press of one button until an action in XBMC starts several mappings take place that are described below. None of these mappings are done by the keyboard! They are all done by the operating system and its embedded applications!

(Modern keyboards often do mappings on their own, e.g. the Speed-Link SL-6495-SSV has a blue key labeled "Fn" similar to/like many notebooks. If this key is pressed no scancode seems to be send to the computer. Instead other keys that have additional blue labels are sending different scancodes when pressed in combination. The MS Natural 4000 has a another modifier for the F(function) keys that works in the same fashion. But the following only applies to the software in the computer not to the scancode modifications of the keyboard. The keyboard always only sends scancodes even if keys are mapped to other scancodes!)

1. Symbolic scancode names: in the source code the scancodes also have symbolic names which are more readable and comprehensible than only numbers. The position of the key with a symbolic name e.g. SCANCODE_A (or the corresponding scancode number) on the keyboard is nearly always on the left side of the keyboard and is usually labeled with A. This is the first mapping from scancode numbers to symbolic names (including key labels of english keyboards).

The most common PC keys are standardized. But IBM PC keyboards have a long history: XT-keyboards, AT-keyboards, MF2?, PS2 and so on. They all have differing scancodes. To make it even worse producers of PC keyboards always have been creative inventing unconventional keyboards with unconventional keys (e.g. 24 function-keys from IBM?, windows keys from MS). Funnily enough today there is a trend for multimedia and gamer keyboards with multimedia, internet/browser or other keys. But those unconventional keys do not always have a standardized mapping or symbolic name anymore. The only chance to process such keys is processing the raw scancode, that still is in the range from 0 to 255.

And IBM is not the only producer of "standards". There are other producers with their totally own scancodes: atari, apple, ... (see SDL implementation).

2. Real label mapping/keyboard layout: allthough the symbolic name always refers to the usual label of a keyboard with english layout (QWERTY), the real label is not always the same as the symbolic name suggests (see http://en.wikipedia.org/wiki/Keyboard_layout). (Only the physical position of the key on the keyboard should always be the same!) Keyboards that do not have an english layout, e.g. german keyboards often/always use the same physical implementation of the keyboard, that always send the same scancodes if you press the same keys on the same physical position, but those keys maybe and often are labeled different, e.g. german keyboards always interchange the labels of Y and Z (QWERTZ) in contrast to english keyboards. And nearly all other keys besides a to z and 0 to 9 are labeled different, e.g. <>,;.:-_#'+*"§$%&/=?{[]}\ and so on. If the software ignores this fact, like XBMC does till now, such a keyboard is nearly useless. So it is necessary to make a second mapping from scancodes or symbolic names to the real labels. At the moment XBMC does not map real labels! This mapping is necessary (for other keyboards than english ones or special/individual keyboards) but does not take place in XBMC till now.

3. Character encoding: even, if you now know, that you want to process a character "#" (the real label) how should this and all the other characters be encoded binary? Historically this is done with 7 bit and ascii encoding.Unfortunately this is not enough for encoding all the possible characters that are known and needed worldwide, e.g. for german umlauts. Till now, XBMC processes only ascii and is not able to process all/any special national characters like german umlauts from keyboard input. Conceptual the simplest solution today would be the use of unicode (WCHAR in the programming language C++) but this might need much rework of the XBMC code and the use of its libraries. The additional complicaton of special national characters like german umlauts is negligible in comparison to the mentioned problem of real label mapping, at least for german keyboards.

4. Functional mapping: keyboards do not only have keys that should result in characters. They also have keys that should result in behaviour/functions. Some keys should influence other keys e.g. modifiers like shift (see below: simultaneous key combination mapping) and some other keys should influence applications, e.g. the blinking cursor should be moved if the arrow keys are pressed or application specific functions should be called when the F-keys are pressed. These keys should NOT be mapped to characters even not unicode! So they must be processed alongside characters.

5. Simultaneous key combination mapping: if the user only presses the key labeled with "1" the character/number "1" should be processed. If the user additionally presses a second key labeled with "shift" at the same time, the character "!" should be processed. Thus, pressing several physical keys should be processed as if only one totally other key has been pressed (should be "mapped"). This does not apply only for characters but also for functional keys.

6. Typicial modifier processing: even if the resulting character "!" is calculated/mapped after the processing of the key "1" and its modifier "shift", the modifier "shift" is not "consumed". Sometimes the application still needs the information, which modifier has been pressed. Therefore the modifiers must be processed alongside the characters and functions, too. There is an additional subtlety: modifiers like shift usually should effect the same, but for ergonomic reasons there are two modifier keys for shift and other modifiers, one for the left hand side and one for the other. Sometimes even these keys should be differentiated, mostly not.

7. Untypical modifier processing: and even this might be not enough. Only the typical modifiers are processed, but theoretically even untypical modifiers could be processed: every key can be combined with or modified by any other key respectively even more than two keys, e.g. Ctrl-Alt, Ctrl-Shift. Perhaps someone wants to process the press of the key ESC while other keys are already pressed and repeating. But this full flexibility is only possible by full scancode access of the whole keyboard (not only single key presses). This is only a complex example why it is important to be able to access even scancodes. (SDL_keyboard HAS access to scancodes.)

8. Logical mapping: all key presses that should not represent characters/unicode can be combined to a virtual or logical key. This not only applies for pure functional keys like arrow keys and F-keys but also for modifiers and even keys labeled with characters. Especially the latter mean, that pressing a key labeled with a character results in several different representations of the key at application level: the scancode, a character and a logical representation. Pressing one key results in several codes/numbers representing all the same key at the same time! No single/isolated code is able to represent all possible meanings of the single key (scancode = physical position, character = printable/visible, logical = behaviour)!

Windows and XBMC usually seem to use VKeys (virtual keys) internally, DirectX seems to use DIK (direct input keys) and SDL uses SDLK (SDL Keys). They all differ and XBMC uses them all as "low level" input on the different platforms. VKeys and DIK range from 0 to 255 (one byte), SDLK from 0 to 322 (more than one byte!), they all "merge" functional keys, modifiers and labeled keys into one range.

9. XBMC key codes (ButtonTranslator.cpp): as mentioned at the beginning of this text, keyboard input is not the only possibility of input for XBMC. All other devices have something similar like scancodes and such mappings. All those different inputs, buttons, ascii characters and vkeys are finally mapped and "merged" into one internal XBMC key code that ranges from 0 to 65535 (2^16-1 or 2 Bytes).

10. Symbolic key mapping (ButtonTranslator.cpp): it is possible to customize, what should happen in XBMC, if these buttons/keys are pressed (keymap.xml). To be able to use comprehensible names of these buttons instead of knowing their XBMC internal key code/number, there is a mapping from comprehensible key names to the internal key codes.

11. Actions and scripts: finally, the symbolic key names can be assigned (mapped) to actions or scripts within keymap.xml to customize, what should happen, when a physical key is pressed.

Current discussion now at: http://www.xboxmediacenter.com/forum/showthread.php?t=26796