I THINK ∴ I'M DANGEROUS

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
ebindkeys [2012/04/05 14:20]
zashi [Advanced Configuration]
ebindkeys [2012/04/05 14:27]
zashi
Line 1: Line 1:
 +====== ebindkeys ======
  
 +Ebindkeys, not to be mistaken with xbindkeys nor [[ebindkeys-zipit]],​ is a linux program for binding key-presses or key-combos.
 +
 +Improvements over ebindkeys for zipit include support for multiple event devices, the option of key-press order relevance, an (IMHO) infinitely better configuration file syntax.
 +
 +Possible downsides include being potentially slower. The core logic is written in an interpreted language.
 +
 +===== Features =====
 +  * Single configuration File
 +  * Multiple event devices supported
 +  * Suitable for embedded devices
 +  * Uses Tcl (based on jim) for configuration and program logic
 +  * Unlike xbindkeys, works regardless of what's in the foreground, be it X11, a virtual console, or a framebuffer.
 +
 +
 +===== Downloads =====
 +
 +==== Source ====
 +Note: To compile ebindkeys you need to have [[http://​jim.tcl.tk|jim]] installed. ​
 +
 +  * {{:​ebindkeys:​ebindkeys-1.0b.tar.bz2|ebindkeys-1.0b.tar.bz2}}
 +
 +==== Binaries ====
 +
 +Here's a binary for i686 linux. It is statically compiled and compressed with upx. 
 +  * {{:​ebindkeys:​ebindkeys-x86-static-upx.gz|}}
 +
 +Here is a statically compiled ARM binary suitable for use on embedded arm devices. There is also an example file for the zipit available (complete with key-mapping).
 +  * {{:​ebindkeys:​ebindkeys-arm-static.gz|}}
 +
 +
 +==== Configuration Samples ====
 +
 +This is a sample configuration file for generic linux systems (i.e. standard ps/2 or usb keyboard).
 +  * {{:​ebindkeys:​ebindkeysrc.gz|}}
 +
 +This is a sample configuration file for zipits. It has all the zipit keypad keys mapped out.
 +  * {{:​ebindkeys:​ebindkeysrc-zipit.gz|}}
 +
 +
 +
 +===== Compilation =====
 +
 +The requirements for compiling ebindkeys are pretty light. You need a c compiler, [[http://​jim.tcl.tk|jim]],​ and make (though you could manually run the commands that make runs).
 +
 +Unpack the source. Compile with make, optionally make dist which strips and tries to compress with upx if upx is available.
 +
 +<​code>​
 +tar -jxf ebindkeys-1.0b.tar.bz2
 +cd ebindkeys-1.0b
 +make
 +make dist #optional
 +</​code>​
 +
 +
 +===== Installation =====
 +Whether you compiled from source or downloaded a binary, installation is the same (and manual). Plunk your binary ('​ebindkeys'​) into somewhere in your path like /bin. Put your ebindkeysrc file in /etc/ and installation is done. Proceed to configuration.
 +
 +===== Configuration =====
 +
 +Ebindkeys looks for the following files in order **/​etc/​ebindkeysrc**,​ **~/​.ebindkeysrc**,​ **./​ebindkeysrc**. The first file it finds it uses it. You will note that if a global config file is found (the /etc one) it will not load the user directory file (~/). This is intentional as ebindkeys binds keys based on physical keypresses and thus responds to actions global to the whole system. It is primarily intended to be used in embedded devices, but can also be used to make extra input devices (like usb keypads) or the power button on your keyboard work no matter what is currently running in the foreground, be it a virtual terminal or X11.
 +
 +==== ebindkeysrc ====
 +
 +The ebindkeysrc is a tcl script, based on [[http://​jim.tcl.tk|jim]]. For full details on jim's implementation of tcl, check jim's homepage. Ebindkeys relevant information will be presented here.
 +
 +You can set values and have them expanded anywhere else in the rc file. Let's look at a small example. String literals don't need to be quoted if they don't contain a space. Brackets quote without substitution,​ double quotes quote with substitution,​ single quotes are not used for quoting.
 +
 +The event command is what lets you define events to respond to input events. The first argument is a event device, you can use either the direct path or the udev created alias under /​dev/​input/​by-path or /​dev/​input/​by-id. The second argument specifies whether or not key-press order matters. The options are ordered and unordered. The third argument is a single button or a list of buttons. Lists should be encapsulated with double quotes. The last argument is a block of commands to run if the previously set criteria match.
 +
 +<code tcl>
 +  set L_CTRL 29
 +  set keyboard /​dev/​input/​event0
 +  ​
 +  event $keyboard ordered $L_CTRL {
 +    exec echo Left Control Key Pressed | wall
 +  }
 +</​code>​
 +
 +
 +The above example, if it isn't obvious enough, will cause "echo Left Control Key Pressed | wall" to be ran every time the left control key is pressed.
 +
 +Here's a more useful example which puts the computer to sleep when the sleep key is pressed and hibernates when left control + sleep is pressed.
 +
 +<code tcl>
 +  set L_CTRL 29
 +  set SLEEP 142
 +  set keyboard /​dev/​input/​event0
 +  ​
 +  event $keyboard ordered $SLEEP {
 +    exec pm-suspend
 +  }
 +  ​
 +  event $keyboard ordered "​$L_CTRL $SLEEP"​ {
 +    exec pm-hibernate
 +  }
 +</​code>​
 +
 +You maybe wondering where the values for the keys come from. These are determined by the kernel. A sample ebindkeysrc file with a standard mapping is provided in the [[ebindkeys#​downloads|downloads]] section. I also have provided a sample ebindkeysrc file for the zipit, though you may have to adjust values / event devices depending on what linux distro you use on your zipit.
 +
 +
 +==== Advanced Configuration ====
 +
 +Because jim is a complete and powerful language you can coax some rather complex behavior out of ebindkeys like command chaining.
 +
 +For example, you can simulate switching between two different bindings for keys.
 +
 +<code tcl>
 +  set L_CTRL 29
 +  set SLEEP 142
 +  set keyboard /​dev/​input/​event0
 +  ​
 +  set alt_set 0
 +  event $keyboard ordered $SLEEP {
 +    #flip alt_set between 0 and 1 when the SLEEP key is pressed
 +    global alt_set
 +    set alt_set [expr ! $alt_set]
 +  }
 +  ​
 +  event $keyboard ordered "​$L_CTRL"​ {
 +    global alt_set
 +    if {$alt_set} {
 +      exec some-command
 +    } else {
 +      exec some-different-command
 +    }
 +  }
 +</​code>​
 +
 +===== Under The Hood =====
 +
 +This version of Ebindkeys (meant to update and replace [[ebindkeys-zipit]]) uses [[http://​jim.tcl.tk|jim tcl]] for configuration and pretty much all of the program logic. The C program basically connects jim and the tcl-code.
 +
 +The core functionality remains the same between the older version and this version--ebindkeys reads input events from the kernel'​s input event interface and reacts according based on the configuration file.
 +
 +===== Security Concerns =====
 +
 +If ebindkeys is launched as root, everything it runs, by default is as root. Since jim is rather complete and powerful programming language, if someone slipped code in to the ebindkeysrc file it could potentially be used to elevate privileges or root a system. The solution to this is easy and up to the user: either run as a non-root user (but don't forget to give appropriate access to /​dev/​input/​event* device) or run as root and keep ebindkeysrc chmod 600. If you run as root you can drop privs depending on what command you run via passing your command through su.
 +
 +
 +===== Known Issues =====
 +
 +==== Endianness Bug ====
 +Possibly the largest issue is that both the program and the Makefile assume little endianness. As is, without modification,​ ebindkeys will not work on big endian systems. Since I don't have any big endian systems I am not too concerned about this, but if someone runs into this problem, let me know and I'll figure away around it. (Probably by rewriting the Makefile and changing the program itself to use binary scan rather than unpack).
 +
 +==== Error Handling ====
 +My error handling is not the best. This is the main issue to be resolved between 1.0b and 1.0. 
 +
 +If you're getting weird errors it's probably error in ebindkeysrc or an issue with reading the input devices. If you are having trouble getting commands to run double check you've got the right device node specified.