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: ::: The 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 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 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 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 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 .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