© nemo 1999-2020
DeepKeys is a RISC OS module that augments and improves keyboard handling
DeepKeys replaces the standard byte-wide keyboard buffer with a word-wide buffer. It also stores keyboard modifiers and physical key numbers with every keypress. Finally, it delivers this meta-information to Wimp tasks through an extension to the standard Wimp Poll KeyPress message, and (new for 2.09!) outside the desktop via an extension to OS_ReadC.
Without DeepKeys, the keyboard buffer is made of bytes, so only codes 0-255 can be inserted into the buffer. In a convention dating back to the BBC Micro, codes 128-255 are reserved for function keys, cursor keys, tab etc, so character codes in the range 128-255 are preceded by a zero byte. Therefore character zero is also preceded by a zero byte.
Wimp tasks do not read the keyboard buffer – they receive KeyPress events from Wimp_Poll, which hides the zero byte prefix and remaps character codes. KeyPress codes delivered from the Wimp are in the range 0-255 for characters, and 256-511 for the metakeys.
Now With Less!
DeepKeys allows word-sized codes to be inserted into the keyboard buffer. Until RISC OS 4 the Wimp delivered these codes as KeyPress poll messages without modification. Unfortunately, RO4 truncates keypress codes to a single byte, plus the standard metakeys. It is therefore possible to insert code &181 into the keyboard buffer and the task will receive a KeyPress event for code &181, meaning F1 has been pressed.
In RISC OS 3 it was also possible to insert a code such as &123456, which was delivered to the task unmodified. This is not currently possible in RISC OS 4. This regrettable truncation also affects Wimp_ProcessKey in the same way.
The intention was to allow virtual key codes to be defined, which are not restricted to a particular physical keyboard layout. There can be codes with fixed meaning, such as “Scan”, “Calculator” or “Open new spreadsheet”, or dynamically allocated codes for USB devices such as numeric keypads or MIDI controllers.
Command line programs that read the keyboard through OS_ReadC will receive word-sized results, and should try not to truncate the code to a byte before interpreting it. For example, OS_ReadLine correctly excludes such keypresses as they are NOT characters.
Note that because of the Wimp’s use of codes 256-511, it is NOT possible to treat such codes as Unicode. UTF-8 encoding is recommended for Unicode characters. In a system that did not use the WindowManager, or in some future version that delivered function keys etc as codes outside the Unicode range, it would be possible to insert Unicode directly into the keyboard buffer. DeepKeys places no interpretation on the codes it manages.
Modifiers and Physical Keys
KeyPress messages from the Wimp, and codes read direct from the buffer using the extended RemV API, are accompanied by the keyboard modifiers pressed when the key code was generated, and the physical key number of the last non-modifier pressed. Codes inserted with the extended InsV API specify their own modifiers and physical key number.
This can be used to implement sophisticated hot-key functionality in Wimp tasks, as it is now easy to tell the difference between Return, Enter, Ctrl-M, Alt-1-3, Ctrl-Return, Ctrl-Enter and Ctrl-Shift-Return, even though they all produce the same keypress code. In each case the modifiers and physical key number are different.
Note that one should always choose the default action for a keypress code (having exhausted other possibilities) even if the physical key number seems wrong – the keypress code may have been inserted into the keyboard buffer by a program using the ‘old’ interface, rather than by the keyboard driver, and it will have gained the modifiers and physical key number of the physical keyboard. Programs using the extended interface can specify the intended modifiers and physical key number when inserting keypresses into the keyboard buffer.
DeepKeys completely replaces the kernel’s keyboard buffer handling. If VectorExtend is available, DeepKeys will insert itself into various vectors at an appropriate priority when it is loaded. Otherwise, it must be loaded as early as possible – for this reason it has the official name !!DeepKeys and should be installed in <Boot$ToBeLoaded> (!Boot...Choices.Boot.PreDesk).
The KeyPress message block returned from Wimp_Poll for event 8 is augmented:
The presence of DeepKeys can be detected by setting b15 of block+28 before calling Wimp_Poll – it will be clear on a KeyPress event if DeepKeys is present. As of 2.09 the message length is also increased to 32.
The “insert into buffer” vector gains a flag to allow modifier state and low-level key number to be inserted into the keyboard buffer at the same time as the associated buffer code, which can now be a word.
The presence of DeepKeys can be detected by R1b30 being cleared on exit. Note that the DeepKeys implements block mode for the keyboard buffer, which the Kernel does not.
The “examine or remove from buffer” vector is extended to allow the modifiers and low-level key number to be read at the same time as the buffer code.
if b31 clear:
if b31 set:
buffer is filled with bytes when b30 is clear, or keypress/modifier word-pairs when b30 set
The presence of DeepKeys can be detected by R1b30 being cleared on exit.
Block mode (b31 set) without DeepKeys state (b30 clear) is not recommended, as values in the returned block will be truncated to bytes, even if they were words.
RdchV / OS_ReadC API
New for 2.09
A pair of magic values allows the programmer to receive modifier state at the same time as the keypress code when using OS_ReadC or RdchV:
The presence of DeepKeys can be detected by R1b15 being cleared on exit.