actkbd - A keyboard shortcut daemon



Contents:

    1. Introduction
    2. Platforms
	2.1. Platform-specific information
    3. Setup
	3.1. Compilation
	3.2. Installation
	3.3. Configuration
	3.3.1. Supported command attributes
	3.4. Running
    4. Internals
    5. License
    6. Authors


1. Introduction

actkbd is a simple daemon that binds actions to keyboard events. It recognises 
key combinations and can handle press, repeat and release events. Currently it 
only supports the linux-2.6 evdev interface, but the platform-specific code is 
well-contained, so that support for additional platforms can be added with no or 
minimal changes to the rest of the code.

It uses a plain-text configuration file which contains all the bindings. Its 
file format has some prediction for command attributes, which allow the user to
perform some common actions (e.g. eject the CD-ROM or change the volume) without
having to call external commands. Currently, though, actkbd can only execute
external commands, as the supported attributes only serve configuration purposes.

Please keep in mind that the manual creation of a configuration file can be very
complex, especially if some of the more advanced features are required. Unless
you enjoy mind games, you might wish to stick to the more simple configuration
rules...



2. Platforms

Currently only the following platforms are supported:

* Linux 2.6.x

The following platforms will probably never be supported:

* Windows - no POSIX, no support
* MacOS - contrary to MacOS X, MacOS has no POSIX subsystem
* BeOS - unless someone can resurrect it


2.1. Platform-specific information

* Linux 2.6.x

To run actkbd under Linux 2.6.x you need to have the event interface available. 
In most cases, loading the `evdev' kernel module will be sufficient:

# modprobe evdev

On Linux it is recommended that actkbd is launched using udev rules. This allows
the administrator to use a different configuration for each keyboard, as long as
udev can tell the devices apart. This method is far more reliable and flexible
than using an init script, as it allows for proper support of hotplug events and
removes the probability of the auto-detection code getting confused and causing
problems.

In most Linux systems the device nodes to use are named /dev/input/eventX, where
X is a decimal unsigned number, e.g. /dev/input/event0. If the /proc filesystem
is mounted and accessible, actkbd should be able to detect a usable keyboard
device. You should not need to manually specify one, unless there are multiple
keyboards present.

Update: On newer kernels several special buttons (like the Power switch) may
appear as input devices as well. There is no way for the auto-detection code to
tell them apart and it is quite possible that the actual keyboard will not be
the one actkbd will select. Using udev to start actkbd is the best way to avoid
this problem.



3. Setup

3.1. Compilation

A simple call to `make' is normally all you need to compile actkbd:

$ make

To change the default location of the configuration file, you have to override 
the sysconfdir Makefile variable. You can also override the CFLAGS variable to 
provide optimisation flags e.t.c. The DEBUG variable can be used to enable 
debugging - if you are using gcc, setting DEBUG to "-g" would probably do.


3.2. Installation

First verify with `make -n install' the installation paths. By default, the 
installation prefix is /usr/local and the actkbd daemon binary is installed in 
$(prefix)/sbin. A configuration placeholder is placed in $(sysconfdir), which by 
default is /etc. You can set the prefix, sbindir and sysconfdir variables to 
override these defaults. Then run `make install' as root to perform the actual 
installation:

# make install

Bear in mind that currently the location of the configuration file must be 
explicitly specified (-c) in the actkbd command line options if the default 
($(sysconfdir)/actkbd.conf) location is not valid.


3.3. Configuration

The default configuration file resides in $(sysconfdir)/actkbd.conf. It is a 
plain-text file with each line being an entry. A proper entry has the following 
format:

<keys>:<event type>:<attributes>:<command>

The <keys> field is a series of numeric keycodes, separated by the `+' 
character. `actkbd -n -s' can be used to find out any keycodes you need, as it 
will report all key presses without executing any commands.

The <event type> string field is a comma or whitespace separated list of the
`key' (key press event), `rep' (key repeat event) and `rel' (key release event)
strings. This field indicates which keyboard events this entry corresponds to.
If left empty, it defaults to `key'.

The <attributes> field contains an optional comma or whitespace separated list
of attributes. The listed attributes can modify the execution of the supplied
command or change the state of actkbd in order to perform complex actions. The
attribute actions are executed in the listed order. If no attribute has been
specified actkbd falls back on to calling system().

The <command> field is the executed command that will be passed to system().
Note that in order to have non-blocking behaviour, you have to append the `&' 
character to the command, so that /bin/sh will execute it in the background.
Also keep in mind that the listed command attributes can affect the way the
command is executed, if at all. Currently system() is the only interpretter
for commands, but in the future there may be command attributes that use the
contents of this field differently, e.g. to set a sound mixer.

Lines starting with '#' are considered comments. Invalid lines are silently 
ignored, unless a high enough verbosity level has been specified.

Note that when actkbd searches for an entry to execute, only the first matching
entry is used. Therefore always make sure that the entries in the configuration
file are ordered properly.

A sample actkbd.conf file is included in the actkbd distribution.


3.3.1. Supported command attributes

The supported attributes are:

* `grab': This grabs the keyboard device to block other applications from
	receiving the subsequent events. This allows the user to bind commands
	to keys that are not normally usable because they produce symbols that
	mess with regular keyboard operation (letters, numbers e.t.c.).

* `ungrab': This releases a grabbed device, so that other programs may get the
	key events. Please note that at least some versions of the X keyboard
	driver (and possibly other programs) will interpret a key release event
	as a full key press/release sequence even if the press event was never
	received (why?). Therefore you may prefer to use the `ungrab' attribute
	in release event bindings, rather than keypress ones, to ensure correct
	operation.

WARNING: Using the `grab' attribute without a well thought way to invoke the
	`ungrab' command can easily leave your keyboard unusable for all other
	applications with no way out. You may want to invoke something like the
	following:

	# sleep 120; killall -9 actkbd

	in a different console, while testing you configuration, to be able to
	reclaim your keyboard even if the configuration file is not correct.

* `grabbed': This instructs actkbd to execute the specified command only if the
	keyboard has been grabbed. This can be used to allow a key to act as an
	extra Function key that adds extra functionality to the other keys.

* `ungrabbed': This instructs actkbd to execute the specified command only if
	the keyboard has not been grabbed.

NOTE: If none of the `grabbed'/`ungrabbed' attributes has been used, the command
	is always executed if the key mask matches. If both are specified then
	the command is never executed - obviously the keyboard cannot be grabbed
	and ungrabbed at the same time.

* `noexec': Do not call system() to run an external command. Useful for entries
	that only serve configuration purposes.

* `exec': Use system() to run an external command here and now. Allows specific
	ordering of the attribute actions with regard to the system() call.

NOTE: If none of the `noexec'/`exec' attributes has been specified, or if the
	attribute list is empty, an `exec' call is implied at the end of the
	list. Always use `noexec' for entries with empty/invalid commands.

* `ignrel': When changing the internal state of actkbd, ignore release events
	for the keys that are currently pressed. This allows more complex key
	combinations where the shortcut keys are pressed sequentially, rather
	than simultaneously. When the key combination is completed, the `allrel'
	and `rcvrel' attributes should be used to clear the key mask and to
	resume the proper reception of release events.

* `allrel': Clear the pressed key mask. It is the equivalent of releasing all
	pressed keys, but is not affected by the `ignrel' attribute.

* `rcvrel': Restore proper reception of key release events.

* `key(X)': Send a key X press event to the input layer of the system.

* `rel(X)': Send a key X release event to the input layer of the system.

* `rep(X)': Send a key X repeat event to the input layer of the system.

WARNING: Note that the careless use of the key event injection commands can make
	your life really adventurous - or just difficult. For example injecting
	a `return' key press/release sequence after the `r' key is a way to make
	logging on locally as "root" really, really difficult. Of course you may
	still be able to login using a user without an "r" in their username and
	password and issuing `su', but you'd still need a root password without
	an "r" in it...

WARNING: The `key()', `rel()' and `rep()' attributes, if used without caution,
	may cause event loops that can bring the system to its knees. Also, it
	seems that continuous event loops can cause actkbd to miss some events,
	or even block the event interface, with various dire results. Use with
	extreme caution.

* `set(X)': Manipulate the internal actkbd state, by setting the key X status to
	`pressed'.

* `unset(X)': Manipulate the internal actkbd state, by setting the key X status
	to `released'.

NOTE: `set()' and `unset()' supersede the normal operations associated with the
	received events, if they are in conflict.

NOTE: By using `set()' and `unset()' with key values that are not producable by
	your keyboard, but are still valid, you can create complex configuration
	schemes by using those key values as status variables.

NOTE: An empty value for the `key()', `rel()', `rep()', `set()' and `unset()'
	attributes instructs actkbd to use the key value that triggered the
	current rule.

* `not': Indicates that the current entry will match when any key except for the
	listed ones is received. This attribute can be used along with an empty
	<keys> field to match all events, regardless of the keycode.

* `all': Indicates that the current entry will match when all of the listed keys
	are pressed, without caring about the state of any other keys.

* `any': Indicates that the current entry will match when any of the listed keys
	is pressed. Not very sure what this can be used for, but it seemed nice
	to have :-)

NOTE: The `not', `all' and `any' attributes are checked in this exact order and
	if more than one have been specified, the one with the highest priority
	supersedes all others. If none of these attributes has been specified,
	then actkbd will require an exact match between the listed keys and the
	active key mask in order to execute the entry.

* `ledon(X)': Switches on the keyboard LED X.

* `ledoff(X)': Switches off the keyboard LED X.

NOTE: actkbd does not check which LEDs actually exist on the keyboard, but this
	does not cause any problems as invalid LED values are simply ignored.

NOTE: Setting the LEDs this way is not permanent. Any operation that affects
	a LED (e.g. pressing the Caps Lock key) can affect one or even all
	LEDs, thus nullifying the operations from actkbd.

NOTE: You will have to use some other way to find what LED codes your keyboard
	supports. On Linux the /proc/bus/input/devices file can supply this
	information: the LED= field is a bitwise mask of the present LEDs. For
	example, if it's 7 (binary: 111), all first three LEDs are available.


3.4. Running

Run `actkbd --help' to see the various command line options. actkbd is normally 
able to auto-detect your keyboard device, therefore you do not need to specify 
it. For the most common case - a daemon with the default configuration file in 
$(sysconfdir) - the following command should suffice:

# actkbd -D -q

Note that sending the HUP signal (kill -HUP) to actkbd will cause it to reload 
its configuration file.


4. Internals

The most interesting/messy part of actkbd is the code that keeps track of which 
keys are pressed each moment. It uses a bitmask with one bit for each available 
key. When press/repeat events are received, the corresponding bit is set and it 
becomes unset when a release event is received for that key. To match key events 
with the corresponding actions, each valid configuration file entry has its key 
field transformed to a bitmask. After that, whenever a new event is received, 
the status bitmask is matched against all configuration entry bitmasks and the 
first one to match (if any) is used and the corresponding command is executed.

Please note that the platform specific code is contained in <platform>.c (.e.g. 
linux.c). This file implements a generic interface to keyboard events, hiding 
each system's intricacies from the rest of code. It is also the file that has to 
be written/ported to add support for a new platform.

For any additional details the best documentation is probalby the source code 
itself.


5. License

actkbd is released under the GNU General Public License version 2. The full text 
of the license can be found in the COPYING file that should be included in the 
actkbd distribution.


6. Authors

Original author:
    Theodoros V. Kalamatianos <nyb@users.sourceforge.net>
