Logo (klik voor homepage)
 
WimpKey module

WimpKey - Technical backgrounds
New hardware, such as recent USB cards and the IYONIX pc, may require the keyboard system to be revised in order to allow more of the special keys on modern keyboards to be used. In order to allow such new functionality to be used at best, it is probably unwise to issue new low-level RISC OS Internal Key Numbers for each new key encountered. Although new internal key codes are perfectly legitimate for the more common keys, it would be impractible to assign new numbers for the huge amount of special keyboards around. Besides internal key numbers are in short supply and should only be allocated for good reasons.

Current situation
In the current situation, a keyboard sends an internal scan code to the computer. The keyboard driver (e.g. the PS2Driver or the USBKeyboard driver) translates the internal key number into a low-level RISC OS key code. The key code is then reported to the Kernel using KeyV with reason codes 1 and 2 (KeyUp and KeyDown respectively).

The Kernel will try do debounce the keys and also keeps track of any depressed and/or released keys (e.g. the modifiers). After processing, the Kernel will send the keys to the keyboard handler who will in turn send the information onto the keyboard buffer using InsV where some special format is used to allow for top-bit set characters.

Some programs are known to intercept both KeyV and InsV in order to modify ASCII codes before they hit the buffer. An example of such software is the AltKeys module which is used to add a compose mode facility to RISC OS (i.e. intuitive entering of foreign characters).

Extensions
The current situation is kept in order to maintain compatibility with existing software. To allow for new functionality to be added to RISC OS, a new set of KeyV reason codes is used. Any existing key that already has an internal key code assigned, would be sent through KeyV reason codes 1 and 2 to the kernel in the normal way. Processing of these keys doesn't change. Any special or unknown key, would translate (in the driver's key table) to &FF, indicating that it is not valid. The driver should then 'broadcast' the scan code instead, through the new set of KeyV reason codes given below.

In order to allow both PS2 and USB systems to use this mechanism, the USB KeyCodes will be used. The following new KeyV reason codes have been registered for the above interface:
  • KeyV_SpecialKeyUp (12)
  • KeyV_SpecialKeyDown (13)

The registers should be setup as follows when calling KeyV:
  • r0 : Reason code (12 or 13)
  • r1 :
KeyCode
  • r2 :
DeviceID
  • r3 :
PortID

System load
In order to avoid unnecessary system load, the new KeyV reason codes should only be issued whenever an unrecognised key is encountered. A keyboard device driver would typically do this once the lookup from its internal key table has failed. Some additional load is introduced by the fact that the 'helper' program sits on KeyV permanently. As a result it will be called at each key press. However, as the keyboard is considered a 'slow' device, it will only cause KeyV to be called at typing speed and hence will not introduce a significant system load.

Key codes
The key code is always a 32-bit value. Any 'standard' key from the 'normal' keyboard range, will always be sent through the standard KeyV 1 and 2 reason codes in 8-bit format.

Special keys from a USB keyboard can be 16 bits in length. Depending on the type of usage (in USB terms called the Usage Page), the same key codes could be used for different usages. As a USB keyboard reports the Usage Page for each key, it is possible to include this usage in the KeyCode. The KeyCode is represented as an 8-digit hexadecimal number and each byte has a special meaning in the order mmuuggkk.
 The KeyCode in more detail

Position Description
mm Modifier state (see below)
uu Usage (8 bit value, taken from the USB UsagePage)
gg Group (general usage of the keys in the kk-field)
kk KeyValue from the USB lookup table (16-bits)
Some examples:

&000c00cd : Play/Pause
&000c00e9 : Volume up
&000c00ea : Volume down
&000c018a : AL Email Reader
&000c0223 : AC Home


In this example the AL keys (Application Launchers) have a 01 in the seconde byte. Likewise, AC keys (Application Control) have 02 in the second byte. All as per USB spec.

Some keyboard manufacturers have added extra keys, such as the Internet keys, that are not in the USB specification and hence are classified as vendor-specific. When writing a keyboard driver you should add the &FF in the gg-byte as this is not done by the USB device.

Some examples:

&000cFF11 : iTouch key
&000cFF13 : Finance

Please read this
    Some keyboards do not support a true 6 key roll-over despite the information in the HID Report Descriptor. It may therefore be possible that e.g. the key combination Ctrl-Shift-[Mail] doesn't produce any code. Such is the case with the wireless iTouch keyboard & mouse combination from Logitech. This should be considered a misfeature of these devices.

DeviceID
In order to allow a helper program to interpret the vendor-specific KeyCodes correctly, the DeviceID is passed in R2 when issueing KeyV with the new reason codes (12 and 13).

The DeviceID is a 32-bit number that is build from the USB VendorID and ProductID (16-bits each), taken directly from the USB hardware. The upper 2 bytes hold the Vendor ID and the lower 2 bytes hold the Product ID. The combination of these numbers is unique for each product and both numbers are always present in any USB device. The format is: &vvvvpppp, where vvvv is the VendorID and pppp is the ProductID.
 The DeviceID in more detail

PortID
When calling KeyV with reason code 12 or 13, R3 should hold the PortID. The PortID is a 32-bit number that is unique for each physical (hardware) USB port available on your computer. The number is built from the filing system, the bus, the root HUB and any further HUB port(s). Alternatively, this field can be used as an index to the DeviceID when using multiple identical devices. In such cases the top byte should be set to &FF, whilst the lowest byte contains the index (numbered from 0 onwards). The other bytes (bits 9-23) should be 0.
 The PortID in more detail

Supressing pop-up windows
Whenever a new special key is pressed, a small window will pop-up at the center of the screen asking if you want to assign a function to that key. Although such a pop-up window may be useful in itself, there are situations where pop-up windows are considered unwanted. This may e.g. be the case when running a presentation. Although it is possible to turn off the pop-up window completely, the average user may forget to do so. Whenever a new special key is pressed accidently, the pop-up window would appear in the middle of the presentation.

A new system variable has been defined which may prevent pop-up windows from appearing. Before opening a pop-up window, !HID will inspect the system variable:

PopUp$Inhibit

If this variable is set to any value other than 0 (zero), all pop-up windows will be supressed. If the variable is set to 0 or if it doesn't exist, pop-up windows will appear whenever appropriate. It is advised that all applications use this variable as a standard means to avoid pop-up windows. A few points to note:

  1. Any program that whishes to control this feature should issue the following command when started: 'Set PopUp$Inihibit 1'. When the program is stopped it should issue: 'Set PopUp$Inihibit 0'.
  2. Any program producing pop-up windows, should inspect the system variable PopUp$Inhibit before opening the window. If the variable is set to any value other than 0 it should not open the window.
  3. Programs producing sound may also to supress any sound effects as these may also interfere with a presentation. An example of such a program is !USBinfo which produces a pop-up window and sound a bell whenever a new USB device is detected. Whilst a presentation is running, all such special effects are supressed.

Related subjects

Klik voor homepage © Copyright Paul Reuvers X-Ample Technology bv  usb@xat.nl Last changed: Last changed: Thursday, 12 August 2004 - 16:16 CET.