Wednesday, March 18, 2009

Creating fdi policy files for HAL

I have been using Gentoo for about 6 years now, and every now and then the system breaks as a result of a large update. This isn't a terrible thing, and usually I just have to scout the for a couple of minutes to find the solution to the error, if I can't figure it out myself.

The most recent problem people have been seeing lately (since at least 6 months ago) is the merge from configuring input devices in fdi policy files - as a result of the Xorg-team wanting to move to HAL-based configures - instead of an input section inside the xorg.conf file. This is mainly in the xorg-server 1.5 and onward. If you want to read much more about HAL, more info is located here.

I have had lots of problems getting this to work, and every time I was trying to convert, I grew sick of it and just reverted my changes. But now I stuck to it and came through alive on the other side. As usual, the forums could help me.

First we add a section with server flags to our xorg.conf:

Section "ServerFlags"
Option "AutoAddDevices" "on"
Option "AutoEnableDevices" "on"
Option "AllowEmptyInput" "on"

This tells xorg that it is OK that we have removed all input devices in the file. Then we can comment out the devices we have listed (to later remove them for good).

Now we need to convert our input settings to the new fdi config file structure. There are some example files scattered across the web, for example on Ubuntu's wiki. The settings are quite basic for most people, so it makes it easy to write the file.

First off we create our config file in /etc/hal/fdi/policy/ and name it 10-x11-input.fdi. The config in my xorg.conf said:

Section "InputDevice"
Identifier "Keyboard0"
Driver "kbd"
Option "CoreKeyboard"
Option "XkbRules" "xorg"
Option "XkbModel" "pc105"
Option "XkbLayout" "se"

Section "InputDevice"
Identifier "Logitech MX510"
Driver "evdev"
Option "Device" "/dev/input/mice"
Option "Protocol" "ExplorerPS/2"

This translates to very similar settings in our new 10-X11-input.fdi. I should mention that I also took the opportunity to switch my device handling to "evdev" for both my devices, instead of the xorg handled one.

<?xml version="1.0" encoding="utf-8"?>
<deviceinfo version="0.2">
<match key="info.capabilities" contains="input.keyboard">
<merge key="input.x11_options.XkbRules" type="string">evdev</merge>
<merge key="input.x11_options.XkbModel" type="string">evdev</merge>
<merge key="input.x11_options.XkbLayout" type="string">se</merge>
<!--<merge key="input.x11_options.XkbLayout" type="string">altwin:menu</merge>-->
<match key="info.capabilities" contains="input.mouse">
<merge key="input.x11_driver" type="string">evdev</merge>
<!--<merge key="input.x11_options.RelHWHEELOptions" type="string">invert</merge>-->
<merge key="input.x11_options.Emulate3Buttons" type="string">false</merge>

After creating the file, we restart our hal daemon:
root@skare$ /etc/init.d/hald restart

and unplug/plug in our device. If we monitor devices with hal, it will print out a new device.

root@skare$ lshal -m

Start monitoring devicelist:
22:52:00.340: usb_device_46d_c01d_noserial_if0_logicaldev_input removed
22:52:00.344: usb_device_46d_c01d_noserial_if0 removed
22:52:00.345: usb_device_46d_c01d_noserial removed
22:52:09.263: usb_device_46d_c01d_noserial added
22:52:09.263: usb_device_46d_c01d_noserial_if0 added
22:52:09.307: usb_device_46d_c01d_noserial_if0_logicaldev_input added

We can see that I first unpluggen my device, and then plugged it in again. To check what devices we have as mouse and keyboard, we run two other commands:

root@skare$ hal-find-by-capability --capability input.mouse |xargs hal-device
udi = '/org/freedesktop/Hal/devices/usb_device_46d_c01d_noserial_if0_logicaldev_input'
info.subsystem = 'input' (string)
info.product = 'Logitech USB-PS/2 Optical Mouse' (string)
linux.device_file = '/dev/input/event3' (string)
info.category = 'input' (string)
info.udi = '/org/freedesktop/Hal/devices/usb_device_46d_c01d_noserial_if0_logicaldev_input' (string)
input.originating_device = '/org/freedesktop/Hal/devices/usb_device_46d_c01d_noserial_if0' (string)
input.device = '/dev/input/event3' (string)
input.x11_driver = 'evdev' (string)
info.capabilities = { 'input', 'input.mouse' } (string list)
input.product = 'Logitech USB-PS/2 Optical Mouse' (string)
input.x11_options.Emulate3Buttons = 'false' (string)
linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1a.1/usb4/4-2/4-2:1.0/input/input3/event3' (string)
info.parent = '/org/freedesktop/Hal/devices/usb_device_46d_c01d_noserial_if0' (string)
linux.hotplug_type = 2 (0x2) (int)
linux.subsystem = 'input' (string)

root@skare$ hal-find-by-capability --capability input.keys |xargs hal-device
udi = '/org/freedesktop/Hal/devices/platform_i8042_i8042_KBD_port_logicaldev_input'
info.subsystem = 'input' (string)
input.xkb.layout = 'us' (string)
info.product = 'AT Translated Set 2 keyboard' (string)
linux.device_file = '/dev/input/event2' (string)
input.xkb.variant = '' (string)
info.category = 'input' (string)
info.udi = '/org/freedesktop/Hal/devices/platform_i8042_i8042_KBD_port_logicaldev_input' (string)
input.x11_options.XkbRules = 'evdev' (string)
input.originating_device = '/org/freedesktop/Hal/devices/platform_i8042_i8042_KBD_port' (string)
input.x11_options.XkbModel = 'evdev' (string)
input.device = '/dev/input/event2' (string)
input.x11_driver = 'evdev' (string)
input.x11_options.XkbLayout = 'se' (string)
info.capabilities = { 'input', 'input.keyboard', 'input.keypad', 'input.keys', 'button' } (string list)
input.product = 'AT Translated Set 2 keyboard' (string)
linux.sysfs_path = '/sys/devices/platform/i8042/serio0/input/input2/event2' (string)
info.parent = '/org/freedesktop/Hal/devices/platform_i8042_i8042_KBD_port' (string)
info.addons.singleton = { 'hald-addon-input' } (string list)
linux.hotplug_type = 2 (0x2) (int)
input.xkb.rules = 'base' (string)
linux.subsystem = 'input' (string)
input.xkb.model = 'evdev' (string)

Here we can see if our policy file actually did its job, i.e. loaded the right drivers for the devices. It also shows the settings, so we can double check those. The /var/log/Xorg.0.log also displays the changes:

root@skare$ tail -n 20 /var/log/Xorg.0.log
(EE) Logitech USB-PS/2 Optical Mouse: Read error: No such device
(II) config/hal: removing device Logitech USB-PS/2 Optical Mouse
(II) Logitech USB-PS/2 Optical Mouse: Close
(II) UnloadModule: "evdev"
(II) config/hal: Adding input device Logitech USB-PS/2 Optical Mouse
(**) Logitech USB-PS/2 Optical Mouse: always reports core events
(**) Logitech USB-PS/2 Optical Mouse: Device: "/dev/input/event3"
(II) Logitech USB-PS/2 Optical Mouse: Found 8 mouse buttons
(II) Logitech USB-PS/2 Optical Mouse: Found x and y relative axes
(II) Logitech USB-PS/2 Optical Mouse: Found scroll wheel(s)
(II) Logitech USB-PS/2 Optical Mouse: Configuring as mouse
(**) Option "Emulate3Buttons" "false"
(II) Logitech USB-PS/2 Optical Mouse: Forcing middle mouse button emulation off.
(**) Logitech USB-PS/2 Optical Mouse: YAxisMapping: buttons 4 and 5
(**) Logitech USB-PS/2 Optical Mouse: EmulateWheelButton: 4, EmulateWheelInertia: 10, EmulateWheelTimeout: 200
(II) XINPUT: Adding extended input device "Logitech USB-PS/2 Optical Mouse" (type: MOUSE)

One positive thing with this new HAL stuff is that we don't have to restart X when we add a new device, or want to change the settings of the ones we have. Just restart the hald daemon and it re-reads the policy files, and unplug/plug in the device again, and the new settings should be enabled. Good luck!


Anonymous said...

If I compare the traditional xorg.conf settings with the new XML version I wonder whether this change is a wise move. Don't get me wrong: XML is very nice to store and read information using text. But it is meant to be written and read by a machine, not by humans. Bad choice for a config file.

Peter said...

Yes, I agree.. Good XML can be readable, but then there's really bad XML as well. I think this XML is a bit of both, when understanding ordinary xorg.conf it's quite simple to convert, but I wouldn't call it obvious without an already written file =)
I hope they will create better tools to edit it.

Anonymous said...

I've been wondering how to set things like driver options. If the intent is to remove the xorg.conf file, where can I specify nooffscreenpixmaps?

niels said...

I have tried twisting and tweaking it, but I do NOT get my national keyboardlayout, dk,
everything else seems to work fine.
/Niels, Danmarl