LXDE: All Hail The Halo Of halevt

by Paul Arnote (parnote)

Many users see LXDE as a replacement for their beloved KDE 3.5.x. In fact, with the right knowledge and skills, LXDE can be easily made to look — and function — pretty much as KDE 3.5.x does/did. Of course, the application of that knowledge and those skills is much easier if you have the right tools.

Meet halevt. Halevt is a daemon that helps monitor changes in your computer's hardware. It stands for HAL (Hardware Abstraction Layer) Events manager. Its job is to execute arbitrary commands when a device with certain properties is added to your system, or when device properties change.

These devices can be audio CDs, blank CDs or CD-RWs, DVD movies, USB thumb drives, or any number of other items supported by your computer. Those are just the ones it comes pre-installed knowing how to handle with PCLinuxOS-LXDE. But what if you want to change those default actions? It's easier than you may think, but first you have to understand how halevt works.

Making it work

Halevt knows what to do with different hardware events, thanks to the halevt.xml file. This file tells halevt what to do when certain hardware events occur. You can take a look at the basics of how halevt works, by checking out this post in the PCLinuxOS Forum.

If you've never looked at an XML file, its structure is actually quite simple. It's a text-based file, and is a superset of HTML. So, if you can read (or have a basic understanding of) raw HTML, you are ahead of the game. While we don't have sufficient room here to give you a basic course in HTML, we can give you some basics. When you open a device with <halevt:Device match="xxxx.yyyy.zzzz = true">, you must also close it with </halevt:Device>. It's sort of like when you specify boldface text in HTML, where <b> precedes the text you want boldface, and </b> turns boldface off at the end of the text you want to display in boldface.

Here is the basic halevt.xml file that is installed with PCLinuxOS-LXDE:

<?xml version="1.0" encoding="UTF-8"?>
<halevt:Configuration version="0.1" xmlns:halevt="http://www.environnement.ens.fr/perso/dumas/halevt.html">
<halevt:Device match="hal.volume.disc.has_data = true">
<halevt:Insertion exec="pcmanfm"/>
<halevt:Device match="hal.volume.disc.has_audio = true">
<halevt:Insertion exec="xmms /mnt/cdrom"/>
<halevt:Removal exec="killall xmms"/>
<halevt:Device match="hal.volume.disc.has_video = true">
<halevt:Insertion exec="xine dvd://"/>
<halevt:Removal exec="killall xine"/>
<halevt:Device match="hal.volume.disc.is_videodvd = true">
<halevt:Insertion exec="xine dvd://"/>
<halevt:Removal exec="killall xine"/>
<halevt:Device match="hal.info.udi = /org/freedesktop/Hal/devices/volume_empty_cd_r">
<halevt:Insertion exec="gnomebaker"/>
<halevt:Device match="hal.info.udi = /org/freedesktop/Hal/devices/volume_empty_cd_rw">
<halevt:Insertion exec="gnomebaker"/>
<halevt:Device match="hal.info.udi = /org/freedesktop/Hal/devices/volume_empty_dvd">
<halevt:Insertion exec="gnomebaker"/>
<halevt:Device match="hal.info.category = storage &amp; hal.storage.bus = usb">
  <halevt:Insertion exec="pcmanfm"/>
<halevt:Device match="hal.info.category = camera">
  <halevt:Insertion exec="gtkam"/>
<halevt:Device match="hal.info.udi = /org/freedesktop/Hal/devices/computer_power_supply_ac_adapter_AC">
  <halevt:Property name="hal.ac_adapter.present">
  <halevt:Action value="true" exec="notify-send -t 5000 -i /usr/share/icons/Tango/scalable/status/info.svg 'The AC adapter is connected now ...'"/>
<halevt:Device match="hal.info.udi = /org/freedesktop/Hal/devices/computer_power_supply_ac_adapter_AC">
  <halevt:Property name="hal.ac_adapter.present">
  <halevt:Action value="false" exec="notify-send -t 5000 -i /usr/share/icons/Tango/scalable/status/info.svg 'The AC adapter was removed ...'"/>

While the above halevt.xml file works for many things on my installation of PCLinuxOS-LXDE, there are a few things that didn't work quite right. Yes, my copy of LXDE is fully updated against the PCLinuxOS official repository. So I dug into the halevt.xml file, bound and determined to get those items working properly.

First, look at the eighth line in halevt.xml (count the blank/empty lines when counting the lines). It reads:

<halevt:Device match="hal.volume.disc.has_audio = true">

In the ninth line, it uses xmms to open the audio on the CD. The problem is, xmms does indeed open. But it refuses to play the audio CD. Nothing I do can get xmms to play the audio CD, much less automatically play it when I insert the audio CD.

However, PCLinuxOS-LXDE comes with SMPlayer pre-installed (in the base installation), and it is a very capable media player that can handle not only DVDs, but also audio CDs, video CDs and super video CDs. So, why not change halevt.xml to use SMPlayer? It's actually very easy to do. Simply replace the ninth and tenth lines of halevt.xml with the following:

<halevt:Insertion exec="smplayer cdda://1 -actions play"/>
<halevt:Removal exec="killall smplayer"/>

Now, when you insert an audio CD, SMPlayer automatically opens and playback starts. Easy enough! Actually, I typed smplayer --help in LXTerminal and figured out the command line from the information presented there, coupled with the information SMPlayer gave me in the title bar of its window when I opened the audio CD from the File menu of SMPlayer.

You can do a similar change for DVD videos. Halevt.xml defaults to using xine to playback videos. Again, SMPlayer will do an admirable job playing back your DVD videos. When I insert a DVD, I cannot get xine to start the playback of my disc. So, replace lines 19 and 20 with the following:

<halevt:Insertion exec="smplayer dvd://"/>
<halevt:Removal exec="killall smplayer"/>

Doing this causes SMPlayer to automatically launch and start the playback of your DVD video. Again, easier than you might have thought.

Extending halevt.xml: Make it do more

Besides audio CDs and DVD videos, I also have an odd mix of VCDs (Video Compact Discs) and Super VCDs (Super Video Compact Discs). I also want these discs to automatically launch SMPlayer and start playback.

Before I can do this, I have to find out how halevt sees the media, and by what name. After placing a Super VCD in your optical drive, launch LXTerminal, and enter lshal at the command prompt. There will be a ton of output. Scroll back until you find the section that lists the hardware attributes for your optical drive. Once you've found the right section, it should look something like the following:

udi = '/org/freedesktop/Hal/devices/volume_label_NEW'
  block.device = '/dev/sr0'  (string)  block.is_volume = true  (bool)  block.major = 11  (0xb)  (int)
  block.minor = 0  (0x0)  (int)
  block.storage_device = '/org/freedesktop/Hal/devices/storage_model_DW_28E'  (string)
  info.capabilities = {'volume.disc', 'volume', 'block'} (string list)
  info.category = 'volume'  (string)
  info.interfaces = {'org.freedesktop.Hal.Device.Volume'} (string list)
  info.parent = '/org/freedesktop/Hal/devices/storage_model_DW_28E'  (string)
  info.product = 'NEW'  (string)
  info.udi = '/org/freedesktop/Hal/devices/volume_label_NEW'  (string)
  linux.hotplug_type = 3  (0x3)  (int)
  linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1f.1/host1/target1:0:0/1:0:0:0/block/sr0/fakevolume'  (string)
  org.freedesktop.Hal.Device.Volume.method_argnames = {'mount_point fstype extra_options', 'extra_options', 'extra_options'} (string list)
  org.freedesktop.Hal.Device.Volume.method_execpaths = {'hal-storage-mount', 'hal-storage-unmount', 'hal-storage-eject'} (string list)
  org.freedesktop.Hal.Device.Volume.method_names = {'Mount', 'Unmount', 'Eject'} (string list)
  org.freedesktop.Hal.Device.Volume.method_signatures = {'ssas', 'as', 'as'} (string list)
  volume.block_size = 2048  (0x800)  (int)
  volume.disc.capacity = 735051776  (0x2bd00000)  (uint64)
  volume.disc.has_audio = false  (bool)
  volume.disc.has_data = true  (bool)
  volume.disc.is_appendable = false  (bool)
  volume.disc.is_blank = false  (bool)
  volume.disc.is_blurayvideo = false  (bool)
  volume.disc.is_rewritable = false  (bool)
  volume.disc.is_svcd = true  (bool)
  volume.disc.is_vcd = false  (bool)
  volume.disc.is_videodvd = false  (bool)
  volume.disc.type = 'cd_r'  (string)
  volume.fstype = 'iso9660'  (string)
  volume.fsusage = 'filesystem'  (string)
  volume.fsversion = ''  (string)
  volume.ignore = false  (bool)
  volume.is_disc = true  (bool)
  volume.is_mounted = false  (bool)
  volume.is_mounted_read_only = false  (bool)
  volume.is_partition = false  (bool)
  volume.label = 'NEW'  (string)
  volume.linux.is_device_mapper = false  (bool)
  volume.mount.valid_options = {'ro', 'sync', 'dirsync', 'noatime', 'nodiratime', 'relatime', 'noexec', 'quiet', 'remount', 'exec', 'utf8', 'uid=', 'mode=', 'iocharset='} (string list)
  volume.mount_point = ''  (string)
  volume.num_blocks = 1436264  (0x15ea68)  (uint64)
  volume.size = 735367168  (0x2bd4d000)  (uint64)
  volume.unmount.valid_options = {'lazy'} (string list)
  volume.uuid = ''  (string)

This is only a fraction of the total amount of information supplied. I have changed the color of the text for the section of the output we are interested in. Notice that the seventh red line down says volume.disc.is_svcd = true? This indicates how halevt sees a Super VCD, as svcd.

Armed with that information, I now play the Super VCD in SMPlayer.


On the title bar of SMPlayer, I notice that it says vcd://2. That is important information that I will need to include in the command line that is passed to the exec= parameter of halevt.xml.

Now that I have all the information I need, it's time to add in the ability for halevt to properly recognize a Super VCD. To do this, we need to insert the following lines into the halevt.xml file:

<halevt:Device match="hal.volume.disc.is_svcd = true">
<halevt:Insertion exec="smplayer vcd://2"/>
<halevt:Removal exec="killall smplayer"/>

To keep everything together, I chose to insert the above four lines right after the videodvd line. You can place it wherever you want, except at the end. It must be inserted before the </halvert Configuration> line. Otherwise, it won't be recognized at all.


Similarly, I can repeat the process for Video CDs (shown above playing in SMPlayer). Once again, insert the following four lines after the videodvd line:

<halevt:Device match="hal.volume.disc.is_vcd = true">
<halevt:Insertion exec="smplayer vcd://2"/>
<halevt:Removal exec="killall smplayer"/>

Did you notice that the "exec" command above says vcd://2, even though the SMPlayer title bar says vcd://3? This is because the content of the Video CD starts on the second "track." With this particular VCD, that content is a 17 minute "behind the scenes" special feature with George Lucas. With most every other VCD, our content starts with that second "track." If you don't want to watch the special feature, just fast forward through it to get to the movie content you want to watch.

Once you've finished making the changes to your halevt.xml file, it's a good idea to reboot your computer. Why? Because the halevt.xml file is cached in memory. Restarting your computer flushes out all of the old values, and reloads all the new values in your modified halevt.xml file.

With VCD and SVCD discs, SMPlayer will automatically launch. But so will PCManFM, because your VCD and SVCD discs are also seen as data discs. I've not discovered a way of preventing PCManFM from launching, so it's just easier to simply close out of the extra session of PCManFM.


As you can see, halevt.xml provides a relatively easy way to customize how your copy of LXDE responds to hardware events on your computer. Like we mentioned previously, the configuration options do exist for LXDE, but only if you are willing to get your hands dirty and manually edit some of the configuration files. As you can see, it's not really all that difficult. You just have to "follow the rules."