Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Conditional mapping entries can be defined on the conditions which are mentioned in glossary conditional mapping entry.

 

How to identify input keycode and output keycode

...

(Taken from FS)

The journey of a key

When a key is pressed on the user keyboard, before it reaches its destination and displays a key output on the user VM, it passes through the browser the client uses, the client OS, the console proxy, the server side hypervisor, host OS, and displays a key on the VM. Even when console proxy does the key translation correctly according to the standard and keyboard layout, any component in this path can change the key translation, hence it can make the key output at the end user VM incorrect. 

Each component, for example, the OS, usually has its own key translation mechanism. With all the components’ own key translation involved, it adds complication to the console proxy key translation. In the end, the correct key translation for the console proxy is to make the correct key gets displayed at the end user VM.

For each different language keyboard, the main engine to be changed is the keyboard key translation rules and tables. There are ten parameters affecting which keyboard translation table to deploy. Five parameters are on server side, which include server OS, hypervisor, and keyboard. Server can obtain this information from the ManagementServer (MS) in Cloudstack. 

Parameters on server side: 

  1. s_os: OS type for VM, such as Windows, Linux (Rhel, Centos, …)
  2. s_osVersion: os version;
  3. s_hypervisor: hypervisor type, such as Vmware, Xen, LVM, Hyper
  4. s_hypVersion: version;
  5. s_keyb: VM keyboard, such as English keyboard(EN), Japanese, …

There are five parameters on client side:

  1. c_os: client OS type, such as Windows, Linux ...
  2. c_osVersion: OS version;
  3. c_browser: IE(IE can have different versions too, IE8, IE9, etc); Firefox, Chrome, Safari
  4. c_browserVersion: browser version;
  5. c_keyb: client keyboard, English keyboard(EN), Japanese(jp), ….
    Based on the different combination of the parameters on the server side and the client side, each combination corresponds to one keyboard mapping table.

Console proxy language keyboard translation

At present, if anyone needs to add a new keyboard support for a language, he needs to spend time understanding the console proxy code and the various key translation logic and rules. Then he can modify a javasript file to add the new language key translation table. However, since this javascript file contains complex logic and rules used for other languages, any change to this file needs to be thought out carefully, otherwise it can cause regression and made some existing keys fail. 

To make this process easier, we refactor the console proxy code for keyboard support. Our goal is to save users and developers time to understand the code path, and limit the scope of change as much as possible. Hence it can reduce the possibility of regression and testing time. After the refactor, the majority of keyboard translation rules and logic stay in a file which the users will not need to understand fully and make modifications. Users only need to modify a small table, which has direct input and output mapping, This small file to be modified handles some special keys for the special language keyboard. 

For special keyboard such as Japanese keyboard, it is required that the hypervisor, host OS and browser also need to deploy Japanese version. 
Even though the console proxy does the translation we expect, the final result at the end may not display the correct key, because of the other components and their own key translations along the way. Hence, all we need to find at the console proxy level is to get the input key translated to a value that eventually display the proper key at the user VM terminal.

What is input and output key codes
Ajaxviewer.js is a javascript file handles all the keys translations. We refer to this translation ‘T’. 

There are two codes users need to be aware of and work with:
Input_keycode: this is the keycode when user presses a key, before any translation. It is related to the key’s physical location on the keyboard;

Output_keycode: this is the keycode sent out by console proxy, to display the correct key on the VM, after all the translations;

T(input_keycode) = output_keycode; 

For example, a general ASCII letter a, we may have T(97) = 97; – when the key for ‘a’ is pressed, the input code is 97; when output keycode is 97, letter ‘a’ is displayed on user VM;

 Key type events 
There are two types of key events: key down/key up, and key press. 

There are two main translation schemes: X11 key system and non-X11 key systems. For X11 key system, the translation follows the X11 keys. It handles the key down/key up events, and skip the key press event. For example, a translation for CapsLock key may be like this (we use X11_ prefix to denote the X11 key):

T(KEY_CAPSLOCK) = X11_KEY_CAPSLOCK 

For non-X11 key system, it does not use the standard X11 key code. It mainly handles the key press event. We build a translation table to handle the majority of the keys for non-X11. 

For the majority of the keys, the logic and rules are set up in ajaxviewer.js. Users do not normally need to modify this file, unless there is a need to change or add any rule there. Users for a special keyboard support need to add entries into the table in ajaxkeys.js. This is a table to handle the special keys which are not covered by the rules and tables in ajaxviewer.js. The rules in ajaxviewer.js handles the default key translation and covers the common keys on the keyboard. It has rules for the special keys. It treats the special keys in a conditional mapping table. For each special keyboard, users just add the entries in the conditional event mapping table in ajaxkeys.js. 

Algorithm for the X11 type of keys:
Step 1: if entry exists in the jsX11KeysymMap table in ajaxviewer.js, translate that key to a corresponding X11_key in that table using key down/key up event;
Step 2: if the condition matches, translate the keys in the conditional map table with jsX11KeysymMap;

For non-X11 type of keys: it handles only the keyPress events; 
Step 1: for every keyPress event, do the key translation;
Step 2: shall only handles key down/up event if all the conditions are true for a special key in the conditional mapping table. 

The conditional mapping table is in a separate file ajaxkeys.js, it has the format for each conditional entry:

 

Conditional mapping entry   { 
    type: <event type>, code: <mapped key code>, modifiers: <modifiers>,
    shift : <shift state match condition>,        -- match on shift state
    guestos : <guest os match condition>,     -- match on guestos type
    browser: <browser type match condition>,  -- match on browser
    browserVersion: <brower version match condition>  -- match on browser version
    guestosDisplayName: <guest os display name condition>  -- matches on specific version of guest os
provide the guest os display name substring to uniquely identify version
for example if guestosDisplayName CentOS 5.2 (32-bit), then to match this condition
give unique substring to identify like 5.2 or CentOS 5.2 etc.
hypervisor: <hypervisor match condition> --match on hypervisor
hypervisorVersion: <hypervisor version match condition> --match on hypervisor version
}

 

For example a match for a particular browser can be like this:

 

{keycode: 59, entry: X11_KEY_COLON, browser: "Firefox"}, when the browser is Firefox, the rule will apply. Otherwise the rule will not apply. 

 

Browser, type and guestos all have string type.

 

Find the input_keycode and output_keycode for a particular key

The new translation table in ajaxkeys.js handles the conditional mappings for some special keys. It implements the “T” function: T(input_keycode) = output_keycode. 

When a key is pressed, we need to know its input_keycode, so that we can find out if it already has an entry in the table. If it has an entry in the table, but the output is not correct, we need to modify or add a conditional entry to match the current browser and os conditions. If there is no existing entry for this key, we need to add a new entry in the table. So by all means, we need to know its input_keycode. 

To find out the Input_keycode, we can turn on the keyboard logger window which will show the keycode for every key pressed. “CTRL-ATL-SHIFT+SPACE” turns on the lodger or click on green circle icon on top-right corner. To have a fresh window to show the code for a new key, clear the window first, and then press a key. 

However, for the value of output_keycode, it is tricky. It is more of a trial and error process. We can search the keyboard standard key document, and try various values. 

To find input keycode open the console logger. It can be opened by clicking big green button on top right of console. 

Press the input and see what keycode are generated. There will be two different kind of events will be generated KEY-UP/KEY-DOWN and KEY-PRESS.

Take a note of code and try to find the corresponding  output code from this. Finding output code is sometimes a big task as it could be dependent on various parameters. 

For details refer [1].

Changes to be done in ajaxviewer.js

...