Home Page

Tips page

University Page

Programming

Debian & Linux

Some works

About me

Del.icio.us Bookmarks

BOINC Combined Statistics

Site Statistics

Contact me sending an e-mail (antispam defense activated)

debian

hacker emblem

blogger

GeoURL

View Sandro Tosi's profile on LinkedIn

This is my Google PageRank

Use Microsoft Internet Keyboard special keys to control XMMS

Use Microsoft Internet Keyboard special keys to control XMMS

 Sandro Tosi, 07 September 2006


My keyboard, the Microsoft Internet Keyboard (don't shame on me, it was the cheaper, black keyboard...), has many special keys, that on Windows would allow to control Internet Explorer and some other aspects of the pc; but I don't have Windows, so I'd like to use those keys to control XMMS music players and maybe something else.

1. Special Keys

Using showkey you can find the code sent by every button on the keyboard. We are interested in the special one, so let's look at their code (I have an italian keyboard, so I'll translate the legend: maybe they won't be exactly the one on english version):

Special Key Press Release
Back 0x00 0x81 0x9e 0x80 0x81 0x9e
Forward 0x00 0x81 0x9f 0x80 0x81 0x9f
Stop 0x00 0x81 0x80 0x80 0x81 0x80
Mail 0x00 0x81 0x9b 0x80 0x81 0x9b
Find 0x00 0x81 0xd9 0x80 0x81 0xd9
Favorites 0x00 0x81 0x9c 0x80 0x81 0x9c
Web/Home 0x00 0x81 0x96 0x80 0x81 0x96
Resources 0x00 0x81 0x9d 0x80 0x81 0x9d
Calc 0x00 0x81 0x8c 0x80 0x81 0x8c
Stand-by 0x00 0x81 0x8e 0x80 0x81 0x8e

where "Press" means the code when the key is pressed, and "Release" the code when the key is released.

A similar output is available with xev; we report even that one since will be useful for the tools we'll use after:

Special Key Press Release
Back KeyPress event, serial 28, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060407269, (227,-300), root:(778,140),
    state 0x10, keycode 234 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False
KeyRelease event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060407498, (227,-300), root:(778,140),
    state 0x10, keycode 234 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
Forward KeyPress event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060409184, (227,-300), root:(778,140),
    state 0x10, keycode 233 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False
KeyRelease event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060409369, (227,-300), root:(778,140),
    state 0x10, keycode 233 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
Stop KeyPress event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060412702, (227,-300), root:(778,140),
    state 0x10, keycode 232 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False
KeyRelease event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060412913, (227,-300), root:(778,140),
    state 0x10, keycode 232 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
Mail KeyPress event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060413568, (227,-300), root:(778,140),
    state 0x10, keycode 236 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False
KeyRelease event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060413802, (227,-300), root:(778,140),
    state 0x10, keycode 236 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
Find KeyPress event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060414365, (227,-300), root:(778,140),
    state 0x10, keycode 229 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False
KeyRelease event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060414634, (227,-300), root:(778,140),
    state 0x10, keycode 229 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
Favorites KeyPress event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060415287, (227,-300), root:(778,140),
    state 0x10, keycode 230 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False
KeyRelease event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060415592, (227,-300), root:(778,140),
    state 0x10, keycode 230 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
Web/Home KeyPress event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060416029, (227,-300), root:(778,140),
    state 0x10, keycode 178 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False
KeyRelease event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060416278, (227,-300), root:(778,140),
    state 0x10, keycode 178 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
Resources KeyPress event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060417224, (227,-300), root:(778,140),
    state 0x10, keycode 235 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False
KeyRelease event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060417445, (227,-300), root:(778,140),
    state 0x10, keycode 235 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
Calc KeyPress event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060418254, (227,-300), root:(778,140),
    state 0x10, keycode 161 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False
KeyRelease event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060418419, (227,-300), root:(778,140),
    state 0x10, keycode 161 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
Stand-by KeyPress event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060419035, (227,-300), root:(778,140),
    state 0x10, keycode 223 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False
KeyRelease event, serial 31, synthetic NO, window 0x2c00001,
    root 0x44, subw 0x0, time 2060419258, (227,-300), root:(778,140),
    state 0x10, keycode 223 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes:

2. Control special keys

There are a couple of tool to handle keyboard special keys

2.1 hotkeys

It's a really simple and customizable daemon to intercept hotkeys and associate to them a command/action.

Due to it's easy XML-enable configuration, I'll use this command XMMS. As a note, the Debian package already contains configurations for many multimedia keyboards, including Microsoft Internet I got.

2.2 lineak

It's another hotkeys daemon; if you're already using it, or what to try something different, you can try it and send me the configuration you've done :)

2.3 xbindkeys

With its companion xbindkeys-config it allows very easily to associate a command to a keys sequence. Sadly, it seems not to support special keys of my keyboard. This is its homepage.

3. How to control XMMS

There are some interesting options for XMMS, that let's you control it via CLI:

  -r, --rew                     Skip backwards in playlist
  -p, --play                    Start playing current playlist
  -u, --pause                   Pause current song
  -s, --stop                    Stop current song
  -t, --play-pause              Pause if playing, play otherwise
  -f, --fwd                     Skip forward in playlist

so, for example, calling xmms -f, we can play the next song in the playlist.

Some useful option is missing, for example volume management and the ability to go back/forward for the current song. There are some external tools that can be used to control XMMS far better (and many more not listed here):

  • xmms-shell
  • pyxmms
  • pyxmms-remote
  • xmmsctrl
  • a Perl interface to control XMMS (it's a sort of shell) is available here

I've chosen to use xmmsctrl, a simple CLI tool with a huge control commands for XMMS (I maintain even the Debian package for it).

4. Control XMMS with hotkeys

Install xmmsctrl: you can install the Debian package, or take the source from author's site and compile/install by yourself.

Debian package for hotkeys provides a configuration file, /usr/share/hotkeys/msnet.def, for Microsoft Internet Keyboard. I've used that file to forge a config file to control XMMS.

To create that file, take the keycode from xev output when pressing a key; then you can create a file or copy an existing one in the directory $HOME/.hotkeys (that dir is local to the user who will execute hotkeys) calling the new file with a not-existing keyboard config (I chose msxmms.def). This is the file I use:

<?xml version="1.0"?>

<!-- Author: Sandro Tosi, matrixhasu@gmail.com, on 2006-09-07 -->

<definition>

  <config model="Microsoft Internet Keyboard">

    <userdef keycode="234" command="xmmsctrl time -5">Back 5 secs</userdef>
    <userdef keycode="233" command="xmmsctrl time +5">Forward 5 secs</userdef>
    <userdef keycode="232" command="xmmsctrl stop">Stop</userdef>
    <userdef keycode="236" command="xmms -t">Play/Pause</userdef>

  </config>

  <contributor>
    <name>Sandro Tosi</name>
    <email>matrixhasu@gmail.com</email>
  </contributor>

</definition>

Let's examine the line <userdef keycode="234" command="xmmsctrl time -5">Back 5 secs</userdef>, so that you'll be able to customize it more:

  • userdef is the XML element to specify a custom key configuration
  • keycode="234" is the code read from xev output for key press
  • command="xmmsctrl time -5" is the command we'd like to execute when the key is pressed
  • Back 5 secs is the text written in a box displayed when you press the key (in my box, at the bottom left of the screen; you can disable it with -o option)

Once you have the file ready to be used, you can execute this command:

$ hotkeys -t msxmms -Z

that sent the command in background, so you are ready to test the keys!

Since you have to execute the program before using special keys, I suggest to execute it at user login, placing previous command for example in $HOME/.bashrc.

Any comment is welcome!