mxk(8)
| MXK(8) | Operator Manual | MXK(8) |
NAME
mxk - configurable input rewriting server
SYNOPSIS
mxk [-a] [-d] [-c] [-h] [-q] [-v] [-z] [-u [unix-socket]] [-p script-file] [-C [log-file]] [-D [log-file]]
OPTIONS
- -a
- Reattach to a running mxk instance
- -c
- Display copyright information and copying conditions
- -d
- Run as daemon, detach into background once the interpreter finishes
- -h
- Help summary
- -q
- Run quietly
- -v
- Increase verbosity. Can be given multiple times
- -z
- Disable interactive interpreter
- -p file
- Load commands into interpreter from file
- -u socket
- Provide a control interface on the specified unix socket. Leave out socket to disable the control interface
- -C file
- Record debug information leading up to a crash to the specified file
- -D file
- Write debug log to the specified file, provided debugging has been enabled during the compile
WARNINGS
- keyboards
- are not all created equal. Inferior ones are unable to report complex chords
- mxk
- is currently poorly tested and badly documented
- mxk
- can be configured to grab your keyboard, rendering your system inoperable until mxk is killed or the system rebooted
- mxk
- operates on input devices which may process confidential information such as passwords
DESCRIPTION
mxk (Marc's eXtended Keyboard) rewrites input events. It receives input events from the linux kernel, rewrites them and sends them back to the kernel via a virtual input device.
mxk uses evdev to receive input events and uinput to queue them back for processing by the kernel. Thus the uinput and evdev modules have to be loaded or compiled into the kernel. It also means that the corresponding device files have to exist (see the FILES section).
Between evdev and uinput, the mxk process can perform a number of transformations. The transformation are specified using a set of commands. The commands can be issued in one of the following ways
- ☞
- Interactively at startup: Unless the -z option has been used, mxk will run its interpreter on the terminal on which it was started.
- ☞
- From a script file: A script file is given with the -p option. Usually mxk script files are installed in the /etc/mxk directory.
- ☞
- By connecting to a running instance: When invoked mxk with the -a option mxk will connect to an already running instance where further commands can be entered, provided the control socket has not been disabled.
Note that in all cases the mxk command interpreter does not display a prompt.
Examples
The below line will start mxk without running an interpreter on the current tty (-z) , will have mxk detach from the current terminal (-d run as a daemon) and interpret a script (-p /etc/mxk/example.mxk) :
~# mxk -dzp /etc/mxk/example.mxk
The next example shows an interactive session. Output is shown in bold while commands are italicised :
~# mxk
console: ready
list-sources
/dev/input/event0: unused: ImExPS/2 Generic Explorer Mouse
/dev/input/event1: unused: PC Speaker
/dev/input/event2: unused: AT Translated Set 2 keyboard
3 entries
halt
console: normal server exit
Command Overview
mxk commands are used to construct a processing graph (a structure of nodes and edges). Data arrives at source nodes, is processed at different intermediate nodes and is sent back to kernel at the target node.
In other words, mxk uses a data flow architecture which, unlike a shell pipeline, can have arbitrary branches. This feature can cause problems if used incorrectly as mxk does not guard against loops. A graph containing a loop can generate a continuous stream of events - this is almost always undesirable.
Also unlike a shell (where the entire pipeline is constructed in one command), mxk uses separate commands to create and configure individual nodes. Once created, the nodes are then connected using another command. These connections between nodes (edges) are anonymous and unidirectional, as in the case in a shell pipeline.
Each node belongs to a node type. Each node type implements a certain function, for example source nodes collect data from evdev, while nodes of the stats type maintain event statistics. If the mxk processing graph is compared to a shell pipeline, a node type can be thought of as a particular utility, while a node is equivalent to a process instance of that utility.
The list-nodes command can be used to view all available node types. Generally commands implemented by a particular node type end in the name of the type. For example, the command start-vector applies to the vector node type.
To construct a graph, nodes (instances of a type) need to be created, configured and then connected to each other. Most nodes are created using a start-* command and then configured using type specific commands.
Nodes are connected to each other using the connect-node command. This command can be thought of as being the equivalent to the pipe token when thinking of a mxk processing graph in terms of a shell pipeline.
Nodes of the same type can be numbered for identification. Generally the first parameter to a command contains the node id. The id is local to a node type. To generate an anonymous node or to refer to all nodes of a particular type, use the id 0.
Note that the manual page is currently incomplete (it only describes some node types) please consult the example scripts in /etc/mxk and the source where there are gaps.
General Commands
help will list all available commands.
echo will display the given parameters.
copying will display the copyright notice.
version will display the version number.
quit will disconnect from a running mxk instance. If the -d option has been given when starting mxk , the server process will detach from the terminal and continue running as a daemon.
halt will stop a running mxk instance. This command should be used to stop mxk rather than quit or control-C , as the latter may leave a running mxk server instance.
Node Management
connect-node will connect the output of the node given as its first parameter to the input of the node given as its second parameter.
Nodes can be specified as a node type name, optionally followed a colon and a node identifier.
The output of one node may be used as input to several nodes, similarly a node may receive input from the output of several nodes.
The below command will connect all input source nodes to array node with identifier 2:
connect-node source array:2
list-nodes displays the node types which are available. Individual nodes of particular type need to be created first before they can be used by the connect-node command. Node instances are created, displayed and manipulated using type specific commands.
Source nodes
The input devices from which mxk can generate input nodes can be displayed using the list-sources command.
Source nodes are created using the file-source, name-source, or caps-source commands. The first parameter to these commands is the node number.
The second parameter to file-source specifies the event device file. A device file should not be opened multiple times. The following example will open the first evdev source and map it to identifier one:
file-source 1 /dev/input/event0
name-source opens an unused input device which has a given name. The second parameter is used as a substring to be matched against the input device name. The match is case sensitive and exact. The following example will open the first device which contains the lowercase string joystick in its name:
name-source 2 joystick
caps-source opens an unused input source which emits a particular set of event types, such as relative motion or key press events. Event types are given as second and further parameters. Event types prefixed with a bang (exclamation mark) indicate capabilities which the device can not have. The following command will open the first device which provides absolute but not relative motion commands:
caps-source 3 key !relative absolute
used-sources lists the input devices which have been opened and their state.
fixup-source source will remap an autorepeat key event to a release and press event, as autorepeat events are discarded by most processing nodes. This is the default state.
repeat-source will disable the translation of autorepeat events and relay them unchanged to downstream processing nodes.
norepeat-source will discard autorepeat key events entirely. This may be needed where a downstream node inserts its own autorepeats.
lock-source activates an opened source for exclusive use. An exclusively used source is inaccessible to other parts of the system. Hence this command should only be issued carefully and only once the processing graph has been set up completely. It is this command which, if used incorrectly, will block input and lock you out of your system.
activate-source activates an opened source in nonexclusive mode. This means that input events reach both mxk and the rest of the system. If used incorrectly this will result in duplicated events.
bypass-source will discard events from an opened source. A newly opened source will always start in bypass mode. Generally a source node should be activated or locked once the rest of the processing graph has been initialised, otherwise no input is collected.
Statistics node
Key press statistics collection nodes are created with the start-stat command. The first parameter to this command is the node id.
The statistics collected sofar can be displayed with the list-stats command.
The following command sequence collects statistics from the first input device:
file-source 0 /dev/input/event0
start-stat 0
connect-node source:0 stat:0
activate-source 0
list-stat 0
Note the use of activate-source rather than lock-source, if the latter is used, events from this device would not reach any other application. Issue further list-stat commands interactively to see the statistics at a later stage.
Target node
A target node is created with the start-target command. This command requires that the uinput device file exists.
A target device is visible in the output of the list-sources command but should not be used as a source. Actually mxk will refuse to use it as a source.
Generally only one instance of the target node needs to be created.
By default, start-target creates a virtual device which is declared to only report keypress, but of all keys.
To change this, specify additional parameters. The first parameter is the node id, subsequent parameters allow users to add relative or absolute motion capabilities to the target, or to select particular keys only.
The example:
start-target 0 key:leftbutton relative:x relative:y
will declare a target which can report relative motion along the x and y-axes in addition to a single keypresses, in other words a one button mouse.
Generic Brailler Node
The generic brailler node can be use to implement chording.
start-genb creates a genb instance. The first parameter is the identifier, the identifier is followed by one to eight key events which should be used to construct the chord. The example :
start-genb 0 s d f
will generate seven key combinations from a chord containing some combination of s d or f. The output keys are virtual keys (virt1 to virt7) which can be remapped using the array node. Up to eight keys can be used to construct a chord, yielding a maximum of 255 virtual key outputs.
Note that output keypress is only generated when a key in the chord is released. The output keyrelease is generated when all input keys are released. When a repeater module is appended to a genb module, it is possible to generate autorepeats by pressing a chord and releasing only one of the input chord keys.
list-genb lists created generic brailler node instances.
An alternative to the genb node is the chord node.
Autorepeat Node
An autorepeat node will transform a key single long keypress into several shorter ones.
start-repeater creates an autorepeat node. Its first parameter is the node id, the second the delay and the third the rate. Delay and rate are given in integer milliseconds.
list-repeater will list existing repeater nodes.
adjust-repeater makes it possible to adjust the repeat rate on the fly. The first parameter specifies the repeater node id, the second the adjustment value, the third and fourth set the keys to increase or decrease the autorepeat rate.
Note that some input devices generate their own autorepeat events for certain keys, these may have to be filtered using the norepeat-source command when a repeater node is used. Also note that the operating system scheduler may not always run mxk when desired, making autorepeats jerky under load. Run mxk at higher priority to reduce this problem.
Array Node
An array node maps a single keypress or release to one or more other events. An array is created using the start-array command, where the first parameter is the node id.
press-array is used to map a keypress to a sequence of events. The first parameter to press-array is the array id, the second parameter the keypress to match. Subsequent parameters are the events to generate on a match.
release-array implements the same function as press-array but matches key releases.
The following example will map the capslock key to the escape key. It will also move the mouse pointer down by ten:
start-array 0
press-array 0 capslock escape/press sync: relative:y/10 sync:
release-array 0 capslock escape/release sync:
ignore-array will configure the node not to forward incoming events which did not match any entry created with the press-array or release-array commands.
bypass-array is the inverse of ignore-array , it configures the node to simply relay events which did not match any entry.
Sorter Node
A sorter node makes it possible to group input events into different groups (bins). Each bin can serve as input to a different set of nodes, making it possible to direct different events through different parts of the processing graph.
A sorter node is started using the start-sorter command. The first parameter is the identifier of the sorter, the next is the currently active bin.
The active bin is used by the node-connect command. The command connects the active bin as output to the input of the node given as its second parameter.
To change the active bin use the bin-sorter command. The first parameter is the identifier of the sorter, the second is the bin number which is to be made active.
To assign a particular key to a bin use the match-sorter command. The first parameter is the identifier of the sorter, the second parameter is the key to be matched, and the last is the bin to which the key is to be assigned.
list-sorters will display the existing sorter nodes.
Timer Node
A timer node will emit a single keypress event once a timer expires. This event can be used by downstream nodes to generate more complex activity.
A timer node can optionally examine its input events for one of three user defined keypress events. These events arm, reset or clear the timer respectively. A reset restarts the timer, while an arm will not affect an already running timer, only start an inactive one.
start-timer will create a timer instance. The first parameter is its identifier, the second its period in milliseconds, the third the keypress event to emit when the timer expires.
trigger-timer sets the input key event which starts the timer. The first parameter is the timer id, the second is the key to match. A running timer is not reset.
reset-timer will start the timer, regardless of it running or not. The parameters are the same as for trigger-timer
clear-timer will disable a running timer. The parameters are the same as for trigger-timer
arm-timer will start a timer identified by its first parameter.
off-timer will stop a running timer identified by its first parameter.
auto-timer will configure a timer to rearm once it expires. The first parameter contains the identifier of the timer to be reconfigured.
single-timer will configure a timer not to arm once it expires. As in the auto-timer case, the first parameter contains the identifier of the timer to be reconfigured.
list-timer will display all timer instances.
Branch Node
A branch node switches its input to one of two destinations, depending on its state. The destinations and its corresponding states are referred to as up and down. The current state of the branch node can be controlled by events on the input stream.
start-branch will create a branch instance. Its first parameter is its identifier.
key-branch associates a particular key with a set of actions. The first parameter is the branch identifier, the second the key while subsequent arguments list the actions. The following actions are defined:
- pass
- The key is forwarded to the current destination
- hipass
- The key event is forwarded, but only if the branch is up
- lopass
- The key event is forwarded only if the branch is down
- toggle
- The key event switches from up to down or vice versa
- up
- The key event switches the branch to the up destination
- down
- The key event switches the branch to the down destination
default-branch functions similarly to key-branch except that the key parameter is omitted, as this command determines what actions are to be taken for all key events which have not been set by a call to key-branch.
up-branch sets the destination to be the up branch directly. The first parameter is the node identifier. When set to up in this way, subsequent connect-node can be used to connect destination nodes to receive input from the up branch.
down-branch functions analogously to the up-branch command, but operates on the down branch instead.
list-branches lists all known branch instances.
Note that a branch will only change when no keys are pressed in order to prevent a key press taking a different path through the processing graph than its corresponding release.
Reduce Node
The reduce node is used to filter out unwanted key events. Optionally the relayed key events can be replaced with another simple key event. For more complex substitutions use the array node.
start-reduce creates a reduce instance. The first parameter is the identifier.
key-reduce loads a set of key events into the reduction map. The first parameter is the identifier, subsequent events list the keys.
relay-reduce configures the node to only relay those key events that have been added using the key-reduce command. This is the default mode of operation.
discard-reduce inverts the function of the reduce node. In other words, it configures the node to discard the key events that have been added using the key reduce command. Instead it relays all the events which have not been listed. Note that this commands needs to be given before the key-reduce command is used. Furthermore, using multiple key-reduce commands while changing from relay-reduce to discard-reduce and vice versa can have unpredictable results.
replace-reduce replaces the key events which do get forwarded with the key event specified as second parameter. The first parameter is the node identifier.
self-reduce undoes the effect of a replace-reduce command, in other words the events are forwarded directly and not replaced.
Bug Node
The bug node can be used to generate different virtual key events from a single key or button by varying the length for which this key is pressed.
A total time period is divided into two or more equal intervals, numbered from one. The number of intervals as well as the overall time period can be set when a node is created. A keypress duration which ends within a given interval generates a virtual key event of the same number. Thus the shortest duration generates a virtual key event one. The virtual events can be remapped using an array node.
start-bug creates a bug instance. The first parameter is the identifier, the second the key to match. The third parameter specifies a total time in milliseconds while the fourth parameter sets the number of intervals.
list-bugs list previously created bug instances.
Single Node
A single node maps one axis of motion to one of two keypresses, one when encountering movement in the negative direction, the other for the positive direction.
start-single starts a single node. The first parameter is the node identifier, the second parameter the type of movement (either relative or absolute), while the third and fourth parameters specify the key to be emitted for negative and positive motion respectively.
list-singles list previously created single nodes.
limit-single sets a threshold below which no key events will be emitted. The first parameter to this command is the identifier, the second the threshold. The default threshold is the minimum, namely one.
sustain-single will configure the single node to continue pressing the key until a motion below the threshold is encountered.
quick-single will emit a key release event immediately after its corresponding press event.
time-single will emit a key release after a timeout. The first parameter to this command is the node identifier, the second parameter specifies the timeout in milliseconds. This command will cause a single node to combine several movements events in the same direction, provided that they occur within an interval less than the timeout.
Chord Node
The chord node matches key combinations.
start-chord will start a chord node instance.
list-chord will list all created chord instances.
new-order-chord will match a sequence of keypresses. The first parameter is the node id, the second parameter sets the key event to emit when the sequence is matched. Parameters three and onwards describe the sequence of keypresses to be matched. Only keypresses which have not been released will be matched. Keypresses have to occur in the order specified.
new-set-chord has the same syntax as new-order-chord but does not require ordering, meaning that the keys specified by parameters three and onward do not have to be pressed in the order that they were given.
old-order-chord functions similarly to new-order-chord but also can match keys which have already been released.
old-set-chord functions similarly to new-set-chord but also can match keys which have already been released.
gap-order-chord functions similarly to new-order-chord but disables repeated matching of a continuously depressed key. This forces the release of a key before a further chord containing the particular key can be matched.
gap-set-chord functions like new-set-chord but with the same restiction as described for gap-order-chord above.
Note that the patterns specified by the old-*-chord commands behave somewhat unusually as they may include older, previously unmatched, keypresses. In future this may change.
Informational commands
list-events will list the event types which mxk can map to symbolic names.
list-codes will list the key or button events that mxk knows about.
ps will list the tasks that the mxk process is currently performing. Each node instance shows up as a task.
COPYRIGHT
Copyright (C) 1999, 2004-2009 Marc Welz. This software is licensed under the terms of the GNU General Public License version 3 or newer as published by the Free Software Foundation. This software comes with no warranty, not even for merchantability or fitness for a particular purpose.
BUGS
Probably lots
FILES
- /dev/input/event?
- source of events. At the time of writing event0 is a character device which has a major number 13 and minor number of 64, subsequent devices increment the minor number
- /dev/input/uinput
- event destination. At the time of writing uinput has a major number of 10 and a minor number of 223. Also note that on some systems uinput exists in /dev/misc
- /var/run/mxk
- control socket
- /etc/mxk
- location of mxk scripts
SEE ALSO
| JULY 2007 | Linux |
