ca850c787f
Issue #3483
185 lines
7.6 KiB
Plaintext
185 lines
7.6 KiB
Plaintext
This component transforms input events originating from multiple sources.
|
|
|
|
|
|
Configuration
|
|
-------------
|
|
|
|
An input-filter configuration consists of two parts, a declaration of
|
|
input sources ("Input" connections) that the component should request,
|
|
and the definition of a filter chain. Each input source is defined via
|
|
an '<input>' node with the name of the input source as 'name' attribute and
|
|
the session label as 'label' attribute. The latter can be used to route
|
|
several input sources to different components, i.e, input device drivers.
|
|
|
|
The filter chain is defined via one '<output>' node. It contains exactly
|
|
one of the following filters:
|
|
|
|
:<input name="..."/>:
|
|
|
|
Refers to the input source with the matching 'name'.
|
|
|
|
:<remap>:
|
|
|
|
Applies low-level key remapping to the events produced by another filter
|
|
that is embedded as a child node.
|
|
|
|
It may contain any number of '<key>' nodes. Each of those key nodes has
|
|
the key name as 'name' attribute, may feature an optional 'to' attribute
|
|
with the name of the key that should be reported instead of 'name'.
|
|
|
|
A '<remap>' node may contain '<include>' nodes, which include further
|
|
content into the '<remap>' node. The included ROM must have a '<remap>'
|
|
top-level node.
|
|
|
|
:<merge>:
|
|
|
|
Merges the results of any number of filters that appear as child nodes.
|
|
|
|
:<chargen>:
|
|
|
|
Supplements the input-event stream of another filter with artificial
|
|
'CHARACTER' events by applying character mapping rules. The originating
|
|
filter is defined as a child node.
|
|
|
|
:<button-scroll>:
|
|
|
|
Turns relative motion events into wheel events while a special button
|
|
(i.e., the middle mouse button) is pressed. The button and rate of generated
|
|
wheel events can be configured per axis via the sub nodes '<vertical>' and
|
|
'<horizontal>'. The button of each axis can be specified via the 'button'
|
|
attribute. By default, "BTN_MIDDLE" is used. The rate of generated wheel
|
|
events can be defined by the 'speed_percent' attribute. A value of "100"
|
|
uses relative motion vectors directly as wheel motion vectors. In practice,
|
|
this is results in overly fast wheel motion. By lowering the value, the rate
|
|
can be reduced to practical levels. By specifying a negative value, the
|
|
direction of the generated wheel motion can be inverted.
|
|
|
|
The consumed relative motion events are filtered out from the event stream
|
|
such that pointer movements are inhibited while the wheel emulation is
|
|
active. All other events are passed along unmodified.
|
|
|
|
:<accelerate>:
|
|
|
|
Applies acceleration to relative motion values. The 'max' attribute
|
|
defines the maximum value added to the incoming motion values. The
|
|
'sensitivity_percent' attribute scales incoming motion values before
|
|
applying the (potentially non-linear) acceleration function. The 'curve'
|
|
attribute defines the degree of non-linearity of the acceleration. The value
|
|
"0" corresponds to a linear function whereas the maximum value "255" applies
|
|
a curved function. The default value is "127".
|
|
|
|
|
|
Character generator rules
|
|
-------------------------
|
|
|
|
The character-generator ('<chargen>') rules are defined via the following
|
|
sub nodes:
|
|
|
|
:<mod1>/<mod2>/<mod3>/<mod4>:
|
|
|
|
Defines which physical keys are interpreted as modifier keys. Usually,
|
|
'<mod1>' corresponds to shift, '<mod2>' to control, '<mod3>' to altgr
|
|
(on German keyboards), and '<mod4>' to Caps Lock. Each modifier node
|
|
may host any number of '<key>' nodes with their corresponding 'name'
|
|
attribute. For example:
|
|
|
|
! <mod1>
|
|
! <key name="KEY_LEFTSHIFT"/> <key name="KEY_RIGHTSHIFT"/>
|
|
! </mod1>
|
|
! <mod4>
|
|
! <rom name="capslock"/>
|
|
! </mod4>
|
|
|
|
The '<rom>' node incorporates the content of the ROM module of the
|
|
specified name into the modifier state. If the ROM module contains a
|
|
top-level node with the attribute 'enabled' set to "yes", the modifier
|
|
is enabled. This is useful for handling a system-global capslock state.
|
|
|
|
:<map mod1="..." mod2="..." mod3="..." mod4="...">:
|
|
|
|
A '<map>' node contains a list of keys that emit a specified character when
|
|
pressed. Any number of '<map>' nodes can be present. For each map node, the
|
|
attributes 'mod1' to 'mod4' denote the condition, under which it is
|
|
considered. Each 'mod' attribute has three possible values. If the attribute
|
|
is not present, the state of the modifier does not matter. If set to 'yes',
|
|
the modifier must be active. If set to 'no', the modifier must not be active.
|
|
|
|
Each '<map>' may contain any number of '<key>' subnodes. Each '<key>'
|
|
must have the key name as 'name' attribute. The to-be-emitted character
|
|
is defined by the attributes 'ascii', 'char', 'code', or 'b0/b1/b2/b3'.
|
|
|
|
:'ascii': accepts an integer value between 0 and 127
|
|
:'char': accepts a single ASCII character
|
|
:'code': defines the Unicode codepoint as integer value
|
|
:'b0'/'b1'/'b2'/'b3': define the individual bytes of an UTF-8 character
|
|
|
|
:<sequence first="..." second="..." third="..." fourth="..." code="..."/>:
|
|
|
|
A sequence node permits the definition of dead-key/composing
|
|
character sequences. With such sequences the character is not
|
|
generated instantly on key press but only after the sequence is
|
|
completed. If an unfinished sequence can't be completed due to an
|
|
unmatched character, the sequence is aborted and no character is
|
|
generated. input_filter supports sequences of up to four characters.
|
|
|
|
For example, the French AZERTY keyboard layout [1] has a dead key
|
|
for Circumflex Accent "^" right of the P key (which is bracket left
|
|
"[" on US keyboards). When Circumflex is pressed no visible
|
|
character should be generated instantly but the accent must be
|
|
combined with a follow-up character, e.g., Circumflex plus "a"
|
|
generates â.
|
|
|
|
[1] https://docs.microsoft.com/en-us/globalization/keyboards/kbdfr.html
|
|
|
|
Dead keys can be defined in the <key> nodes of any <map> by using
|
|
codepoints not used for direct output, for example, Combining
|
|
Diacritical Marks beginning at U+0300. The French Circumflex example
|
|
can be configured like follows.
|
|
|
|
! <mod1>
|
|
! <key name="KEY_LEFTSHIFT"/> <key name="KEY_RIGHTSHIFT"/>
|
|
! </mod1>
|
|
! <map>
|
|
! <key name="KEY_Q" code="0x0061"/> <!-- a -->
|
|
! <key name="KEY_LEFTBRACE" code="0x0302"/> <!-- dead_circumflex -->
|
|
! </map>
|
|
! <map mod1="true">
|
|
! <key name="KEY_Q" code="0x0041"/> <!-- A -->
|
|
! </map>
|
|
! <sequence first="0x0302" second="0x0061" code="0x00e2"/> <!-- â -->
|
|
! <sequence first="0x0302" second="0x0041" code="0x00c2"/> <!-- Â -->
|
|
|
|
:<repeat delay_ms="500" rate_ms="250">:
|
|
|
|
The '<repeat>' node defines the character-repeat delay and rate that
|
|
triggers the periodic emission of the last produced character while
|
|
the corresponding key is held.
|
|
|
|
:<include rom="...">:
|
|
|
|
The '<include>' node includes further content into the '<chargen>' node
|
|
and thereby allows the easy reuse of common rules. The included ROM must
|
|
have an '<chargen>' top-level node.
|
|
|
|
|
|
Additional features
|
|
-------------------
|
|
|
|
The input filter is able to respond to configuration updates as well as updates
|
|
of included ROM modules. However, a new configuration is applied only if the
|
|
input sources are in their idle state - that is, no key is pressed. This
|
|
ensures the consistency of the generated key events (for each press event there
|
|
must be a corresponding release event), on which clients of the input filter
|
|
may depend. However, this deferred reconfiguration can be overridden by setting
|
|
the 'force' attribute of the '<config>' node to 'yes'. If forced, the new
|
|
configuration is applied immediately.
|
|
|
|
|
|
Examples
|
|
--------
|
|
|
|
An automated test that exercises various corner cases of the input filter
|
|
can be found at _os/run/input_filter.run_. For a practical example of how
|
|
to use the input filter with the terminal, please refer to the
|
|
_gems/run/terminal_echo.run_ script.
|