XHKEYS - a tool for your special keyboard.

Version 1.0.1
User Manual




Content

Introduction

Preamble

Terms explained

ScanCode vs KeySym
Modifier and shift state.

Support

Installation

From source tarball

From RPM binary

From RPM source

Using xhkeys

Configuration

Activation

Command line arguments

Using xhkconf

Parameters

Modes

Appendix A. Configuration file format

General resources

Code lines

Appendix B. Built-in operations

General purpose operations

CD audio control

Mixer (volume and balance) control.


Introduction

Preamble.

While I was building my new computer,  I purchased  " Turbo Media keyboard " (KB9810R):  this one was really cheap, and a lot of extra keys looked to be useful.  It came with a software for a dumb "operating system", but  given that I use Linux for most of the time,  those keys remained unused ... until recently.

xhkeys is designed to suit any keyboard  that has some extra keys that otherwise make no use with X:   "Menu" key  on a  105 key keyboard,  extra keys on some keyboard models, or laptops.

The application allows to assign a particular action to any key or key combination (key and modifiers ).  An action can be of one of the following types:

The package includes two programs:
xhkeys    - the main application which processes key presses and implements actions
xhkconf - configuration for xhkeys

Terms explained (the way I understand it, which might be not 100% correct).

ScanCode vs  KeySym.

Scan code is a unique code generated  by the keyboard for a particular key.  As opposed to that,  Key Symbol (KeySym for short) is assigned by the X-server(1) ,  depending on the selected layout. KeySyms have  mnemonics starting with XK_,  e.g.  XK_A for capital A,  XK_percent for  %  sign. All KeySyms are listed in  /usr/X11R6/include/X11/keysymdef.h .

While using KeySyms is preferred for portability, this application identifies a key by its scan code,  because:

X reports any scan code as an  8-bit number,  with external keys having  codes in range 128 to 255 (2)
This application however is not limited to range 128-255.

----
(1)  More exactly by KEYBOARD extension, unless disabled.
(2)  In reality all scan codes are below 128, what X reports as  a  key code over 128  is really an e0-sequence, e.g.  '0xc2' corresponds to  '0xe0 0x42'

Modifier and shift state.

A modifier is a key  that can be pressed simultaneously with a function key to affect its interpretation.
At least 6 modifiers are supported by X on PC:  Shift (1), Caps Lock (2),  Ctrl(4), Alt(8),  Win(0x40), ScrollLock(0x80).

Shift state is a bit mask  corresponding  to all pressed modifiers.  With  6 modifiers you have 64 possible shift states, therefore the  amount of possible key combinations (ExtraKey1,  Shift + ExtraKey1 ,  Ctrl+Shift+ExtraKey1, etc.) is 64 times more than a number of extra keys.

Support

The recent version of xhkeys is available from  http://www.geocities.com/wmalms

The author can be contacted by email:  "Michael Glickman" <wmalms@yahoo.com>
 

Installation.

From source tarball:

    tar -xzf xhkeys-1.0.0.tar.gz
    cd xhkeys-1.0.0
    ./configure
    make

To install for common use (binaries and documentation), log in as root and enter
        make install
        make install_doc

This will install the binaries in ${prefix}/bin and the manual in ${prefix}/share/doc/xhkeys-1.0.0

Useful configuration options (with ./configure):
 
--prefix=path installation prefix, default  /usr/local
--disable-cdaudio exclude built-in  CD audio operations
--disable volume exclude built-in volume/balance operations
--disable-syslog exclude syslog support: all messages addressed to syslog will be printed on stout instead

Among most commonly used environment variables are:
CC  name of C compiler 
CFLAGS compilation flags

From RPM binary

For portability, the application was built in RedHat 6.2 (gcc 2.96,  glibc 2.1.3,  rpm 3.0.4) with CFLAGS="-O4 -march=pentiumpro" , and was tested with upgraded  RedHat 7.1 (glibc 2.2.4, rpm 4.0.2).  It is expected  to run with glibc 2.1.3+ and any glibc 2.2. If you have problems, try installing from source.

Log in as root and say

rpm -Uv xhkeys-1.0.0-1.i386.rpm

From RPM source

Log in as root and  set  CC and CFLAGS, if necessary. Enter
rpm --rebuild xhkeys-1.0.0-1.src.rpm
This creates the binary  xhkeys-1.0.0-1.i386.rpm usually in /usr/src/redhat/SRPMS. Change to this directory and follow the instructions for installation from RPM binary .
 

Using xhkeys.

Configuration

xhkeys needs a configuration file.  Its structure is discussed in Appendix A .

 By default xhkeys looks for configuration file in the following  paths:

Global configuration:   /usr/lib/X11/app-defaults/XHkeys
User configuration:      ~/.XHkeys

User settings overwrite the global ones. The location of user configuration file can be changed with --file command line argument.

The package comes with a configuration utility xhkconf ,  that can help you to create and maintain the configuration file. Sorry, I have no time to implement a nice GUI interface (you will do me a favor by building it), but I will always find time to help you in case you have problems.  xhkconf can configure key bindings,  but not other parameters like device names, time-outs, etc. What is really frustrating about 'xhkconf --edit ' is that it uses standard Xrm engine (ended up with XrmPutFileDatabase), which doesn't keep the comments, and completely reshuffles the lines, which makes a resource file hardly readable.

If you want to have a nice looking configuration file, you can still find xhkconf useful. The package includes a sample resource file XHkeys.sample ,  which has to be copied to ~/.XHkeys   [i.e. .XHkeys (the name starts with a dot)  in your home directory].   Since the scan codes for extra keys are keyboard model specific, you will need to change the scan codes and maybe shift state in ~/.XHkeys. Use 'xhkconf -k' to see the scan codes and 'xhkconf -m' to reveal the window information needed for configurations.
 

Activation

To activate xhkeys automatically with X server, you can just insert  'xhkeys'  line somewhere near the start of ~/.xinitrc (don't put it at the end, because in some cases the control might not get to the end of ~/.xinitrc).

As an alternative, some Window Managers provide their own way for application autostart, like ~/GNUstep/Library/WindowMaker/autostart for Window Maker, or Autostart directory for kwm.

FYI:  xhkey fails if X server is inactive, therefore you can't activate it before calling X.
 

Command line arguments

The command line keywords for xhkeys can be used in short or a long format

The  following command line arguments are accepted:

-d
--debug
Debug mode: don't fork and use stout instead of syslog

-f
--file  name
Location of user configuration file, if different from default ~/.XHkeys

-h
--help
Print help and exit

-l level
--log level
The level of logging
    n- don't  log  messages
    e - log only error messages (default)
    a - log all messages:  start, stop/termination and errors
 

Using xhkconf.

A command line argument can either specify a mode (edit, delete, view scan codes) or a parameter for particular modes.
 

Parameters

xhkconf accepts the following parameters:

-f  name
--file  name
Location of user configuration file, if different from default ~/.XHkeys.  Used with  --edit,  --delete, and  --list.

-c  value
--count  value
Number of iterations for --keys, --mouse, --delete and --list

-s  code[.shift]
--scan  code[.shift]
Scan code and optionally shift state separated from the scan code by a dot. The scan code can be specified as a decimal, or hexadecimal number. Shift state 0 is assumed if omitted. Used with  --list, --edit and --delete.

-g
--global
Lookup also global configuration file. Used with --list only.

-a
--all
List all assignments. Used with --list only.
 

N.B.  --count, --scan  and  --all are mutually exclusive.

For details refer to the description of a particular mode
 

Modes


One and only one of the following modes may appear in the command line

-k
--keys

This mode displays key information. After 'xhkconf -k' starts it waits for 5 seconds (the time-out can be changed using  keytimeout parameter  in configuration file).  After you type a key combination, you can see its scan code, shift state and KeySym, if applicable.

If you need to query several key combinations, use --count with a maximum  number of keys. With  0 (zero) as the counter, the number of key combinations is unlimited, so that quit by time-out is the only way to terminate the application.

Examples:
    xhkconf -k -c0               # short keywords
    xhkconf --keys --count=10    # long keywords
 

-m
--mouse

This mode displays information needed for mouse event configuration. Before calling 'xhkconf -m ', you have to start the applications, that will receive mouse events (target applications).

After 'xhkcom -m' starts, it waits 8 seconds for a button click  (the time-out can be changed using  clicktimeout parameter  in configuration file). After you click a window (of the target application), you get

target window id
class hints (application and class names) if applicable
title if applicable,
mouse button number and shift state,
coordinates (x,y) relative to the target window
If you need to perform several queries, use --count with a maximum  number of button clicks , or  0 for unlimited number of clicks.

-l
--list

Display a command assigned to a particular key combination.

You can specify scan code and shift state with --scan argument, or use --all to show all scan codes.

If neither scan code, nor -all  is  specified, 'xhkeys -l' waits keytimeout seconds for key combination, and displays the action associated.  To query several key combinations in same run, use --count with a maximum  number of keys (count 0 - unlimited)

Normally --list processes only user configuration file., however if --global argument is specified,  the key assignment will be displayed from the global configuration in case is not found in the user configuration.

Examples:
 
xhkconf -ls 176.1 -f ~/.XHkeys.1 # Display  binding for scan code 176, shift state 1
# Configuration file is explicitly specified 
xhkconf --list --scan=176.1 --file=~/.XHkeys.1  # Same with long keywords
xhkconf --list --scan=0xb0 # Scan code is specified in hexadecimal format, 
# shift state is  not specified, 0 is assumed
xhkconf -la # List all assignments from user configuration
xhkconf -lag # List all effective assignments (from user,
# or global configuration)

-e
--edit

Edit a command assigned to a particular key in user configuration (global configuration file cannot be accessed).

This is the default mode.

Accepted parameters:  --scan  --count --file.  The interpretation is similar to --list  mode

Examples:
 
xhkconf -es 0xb0.1 # Add/edit  binding for scan code 176, shift state 1
xhkconf --scan=176.1 # Same result with using a long keyword, and decimal scan mode
# edit mode is assumed by default
xhkconf -c0 # Count=0 - edit repeatedly until quit on time-out
xhkconf # No arguments: edit a single (prompted) key combination.

If key and/or mouse event are going to be assigned, you have to activate the application(-s), that will receive the events (target application).

xhkeys will look for a command, assigned to the key combination. If there is an assigned command, you will asked a permission to overwrite it.

To enter a,  you will be asked  to select command type:
 
Internal Function  See Appendix B
Application any external application with command arguments if needed,
(e.g.    mozilla -edit     to start mozilla composer)
Key Event KeyPress and/or KeyRelease events are sent to a designated window
Mouse Event Button Press and/or ButtonRelease events are sent to a designated window

Following prompts depend on the command type.

At last the new command is displayed, and if accepted, the key binding is added or replaced.

The changes are written to the user configuration file,  specified with  --file command line argument, or ~/.XHkeys by default.
 

-d
--delete

Delete user assignment for a  particular key. This will activate the global assignment if any.

Accepts same parameters as --edit.

-h
--help

Print help page and quit. All other command line arguments are ignored.
 

Appendix A.  Configuration file format.

xhkeys uses X11 resource file for configuration, and accesses it using X Resource Manager (Xrm).
Use sample configuration file XHkeys.sample as an example.

The resources are listed below

General resources:

cddevice CD device name to use for built in CD functions (see Appendix B ), default  /dev/cdrom
cdhold yes or no
If yes, the CD device is opened with the first internal command accessing CD, and closes before xhkeys quits
If no (default), the CD device is opened and closed for each individual operations.
Set cdhold=yes, if you use cdrom auto eject  (e.g. dev.cdrom.autoeject=1 in /etc/sysctl.conf)
mixer device Mixer device name for built-in volume and balance control, default /dev/mixer
mixer hold yes or no
Similar to cdhold, but for the mixer device
mixer channel channel used for volume/balance control,  if not specified explicitly  (See Appendix B for details)


keytimeout A period in seconds for xhkconf to wait for a key combination (see Using xhkconf ), default 5
clicktimeout A period in seconds for xhkconf to wait for a mouse button click (see Using xhkconf ), default 5


keylattency A period in microseconds between generated KeyPress and KeyRelease (see Key Event below), default 0
keypause A period in microseconds between consecutively generated key event sequences, default 50000
clicklattency A period in microseconds between generated ButtonPress and ButtonRelease (see Mouse Button Event below), default 0
clickpause A period in microseconds between consecutively generated mouse button event sequences, default 50000


logmode xhkeys log mode, if not specified in the command line: none, errors (default) or all
maxcodes Minimum number of codes: a code line number must not exceed this value (see below).

Code lines

Each key combination assignment  is represented by a string resource, called code line. Its name is codelineNNN, where NUN is a number between  1  and the value of  maxcodes  (inclusive).

A code line has he following structure:

scanCode;shiftState;cmdType;parameters
where:

either scanCode or shiftState is a decimal (e.g. 176) or hexadecimal (e.g. 0xb0) number.

cmdType is one of the  following:

 
I Built-in (internal) command
A Application
Kxx Key event . Two following characters specify
Target window selection:
C - Target window is identified by WM. class hints (application name, and class name), 
T - Target window is identified by its title (caption)
I - Target window is given by the window id
O - Target window is given by its stacking order
Sent key selection:
Y - Sent key is specified by KeySym, 
S - Sent key is specified by scan code

Examples:
KCY  - target window is given by WM. class hints,  key to send is given as KeySym

Mx Mouse button event.
The next character specifies target window selection ( C, T, or I) in the same way as for a key event
Hint: target identification by WM class hints appears to be the safest one,  because window title often includes variables (file name, tip of the day, etc.). A problem with WM class hints is that an application might have several active windows with same WM class hints, where specification by title may become useful. Use window id only for permanent windows (e.g. weaker clip), because window id is allocated dynamically and can't be therefore a reliable identifier.

The parameters depend of command type:

For  a built-in command (I):

commanded  arguments
For  an external application (A):
Shell command to start the application
For a key event (K):
TargetWindow;SentKey;SentShiftState;PressRelease;Count
PressRelease and Count can be omitted with separating semicolons

Target Window (a window receiving the event) format depends on target window selection:
C - AppName-ClassName (hyphen - separated)
T - Window Title
I - Window id (a decimal or hexadecimal number)
O - One of the following characters:
        T - topmost window, B - bottom window,  R - root window

SentKey (key to be sent)  depends on sent key selection
Y - KeySym without XK_ prefix
S - Scan code as a decimal or hexadecimal number

SentShiftState (shift state to send) is a decimal or hexadecimal mask

PressRelease is
1 - send KeyPress event only
2 - send Key Release event only
3 - send KeyPress and Key Release (default)
An interval  between KeyPress and KeyRelease is given as keylattency

Count; how many times the event has to be sent,  default 1
A pause between events is specified as keypause

For a  mouse button event (M):
TargetWindow;SentX,SentY;SentButtonNumber,SentShiftState;PressRelease;Count
PressRelease and Count can be omitted with separating semicolons

Target Window (a window receiving the event) format depends on target window selection:
C - AppName-ClassName (hyphen - separated)
T - Window Title
I - Window id (a decimal or hexadecimal number)

SentX and SentY are coordinates relative to target window

SentButtonNumber (a button number to sent) is an X button number (1- left button, middle, etc.)
SentShiftState (shift state to send) is a decimal or hexadecimal mask

prerelease is
1 - send Button Press event only
2 - send Button Release event only
3 - send Button Press and Button Release (default)
An interval  between ButtonPress and ButtonRelease is given as clicklattency

Count; how many times the event has to be sent,  default 1
A pause between events is specified as clickpause
 

Appendix B.  Built in operations.

Each built-in operation has a operation code, and can accept arguments, e.g.
 
CDPLAY +1T        # Op code CDPLAY, argument +1T
Quit              # Op code QUIT, no arguments


The operation codes are case insensitive
 

General-purpose operations.


QUIT - terminate xhkeys (no arguments)

WNDROTATE - circulate windows
 
WNDROTATE + Circulate windows by raising the lowest window
WNDROTATE - Circulate windows by lowering the highest window

 

CD audio control. 


If you are not interested in controlling CD audio, or want to do it with an external application, you can exclude CD audio control from the code, by using --disable-cdaudio with ./configure  (see Installation )

CDPLAY - play CD

The argument specifies time or track number. When prefixed with + or - it is interpreted as relative to current position,  otherwise it specifies absolute address (track number or time from disc start). D refers to starting track on the disc, * refers to current position.

Examples:
 
CDPLAY Start from current position
CDPLAY * Same
CDPLAY D Play from disc start
CDPLAY -1T Play previous track
CDPLAY +4T Go 4 tracks forward
CDPLAY 4T Play track 4 
CDPLAY+0T Restart  current track
CDPLAY +1M3S2F Go 1 minute 3 sec and 1 frame forward  (frame = 1/75 sec)
CDPLAY -10S Go 10 seconds back

CDPLAYPAUSE - a paused/stopped CD start playing, a playing CD pauses. No arguments

CDPAUSE - pause a playing CD.  No arguments

CDSTOP - stop a playing CD.  No arguments

CDLOADEJECT - load a disk if no medium currently, eject otherwise

CLOAD - attempt load a disk

CDEJECT - attempt to eject a disc

CDSLOT - change current slot on a multi-changer device.
Argument - slot number,  with a sign if relative to current
 
 
CDSLOT +1 Select to next slot
CDSLOT -1 Select previous slot
CDSLOT 0 Select starting slot (slot number 0)

Mixer (volume and balance) control.  


Allows to control volume and balance. If you are not interested in that, or want to do it with an external application, you can exclude mixer support from the code, by using --disable-volume with ./configure  (see Installation )

SNDVOLUME 

Change volume. The argument is coded as volume.device

Volume can be relative to current (+value, -value) or absolute (without a sign).
The maximum volume value is 100.

The optional device number specifies mixer device. If the device is not specified, the device is taken from  mixerdevice
resource in configuration file (see Appendix A ).  If the mixer device isn't found there as well, the application takes the first present device from the following:  Master volume(0), PCM-1 (4), PCM-2 (10)

The full list of mixer devices is given in /usr/include/linux/soundcard.h

The most commonly used mixer devices are

 
0 Master Volume 5 Speaker
1 Bass 6 Line
2 Treble 8 CD
3 Synthesizer 10 PCM-2
4 PCM-1 13 Output Gain
Examples:
 
SNDVOLUME +2 Increase volume by 2 on default devide
SNDVOLUME 0 Mute
SNDVOLUME -1 Reduce volume by 1 on default device
CNDVOLUME +1.8 Increase CD volume (device 8) by 1

 

SNDBALANCE 

Change balance. The argument is coded as balance.device

You need to use prefix = with an absolute negative balance.

Examples:
 
SNDBALANCE +2 Increase balance by 2 on default devide
SNDBALANCE -1.6 Reduce balance by 1 for Line (device 6)
SNDBALANCE =-10 Set balance to -10 on default device  (= is required to avoid confusion)
SNDBALANCE =30.8 Set balance to 30 for CD (device 8)  (= is not necessary, but used fore readability)