Introduction

The X.org X server has recently had significant improvements to its input subsystem. The most prominent of them is input-hotplugging (short: i-h), but the general design of the system permits an X server to function with correct settings even without a xorg.conf to specify a non-default keymap. Because this new system relies on udev or hal, several people have expressed significant concerns about the need for such external tools. This is a valid question, given that the X server did work for them in the past without using these programs. The first part of this document is an attempt to explain the rationale for the new input system, what problems it solves, and how it functions. The overarching message is that the new input subsystem is built to rely on the host OS rather than reduplicate its functionality, and in doing so it simplifies the operating system by using standardized interfaces to query and interact with the hardware. The second part of the document is a HOWTO which explains how to configure the system to suit your needs.

Rationale

The Long-Term Goals Of X.org

The X.org project inherited a codebase constrained by history from the XFree86 project. The most important constraint was the past need for absolute portability across different varieties of UNIX, none of which provided a Free Software environment that we enjoy today. Thus, X had to do everything itself, from scanning the system bus to driving the hardware. In short, it was an OS sitting on top of an OS.

One of the most significant goals for X.org since its founding has been to bring X in to the modern age by stopping this sort of behavior. Many steps have been taken in line with this vision because today we have a fully open OS from the kernel on up, and the old UNIXes are dead or dying. The old monolithic X codebase was split up to encourage contributions, and with that it was shifted from its own special build system to the fairly standard autotools. Additionally, X left the old /usr/X11R6 directory and entered the FHS world like any normal piece of software. The X server's special loader system (yes, it had its own loader!) was scrapped in favor of the standardized ELF format. Its PCI bus handling code was deleted and now the server utilizes the external libpciaccess to query the OS for the PCI devices. On linux, this just simply looks in /sys, which is a standardized interface.

All of these developments were in line with the goal of making X behave like a good citizen on its host OS rather than a paranoid self-reliant stranger. New moves have begun to actually take advantage of the openness of current systems by moving large portions of the video drivers in to the kernel, as with Kernel Mode Setting (KMS) and the GEM and TTM memory managers.

Basic Input

As one would expect from the previous, the old input drivers (keyboard/kbd, mouse, and friends) had to have somewhat complete knowledge of the hardware in order to actually drive it. They were doing this job so that they didn't have to rely on the host OS to provide the necessary support. However, in doing so, they couldn't take advantage of things that the host OS provided for free, and they also had to duplicate the functionality that was available there.

The evdev driver was the first step in changing this. evdev is a framework for handling I/O generically. It allows the kernel to deal with the details of the specific device, and allows any userspace programs to interface with it. When the X server uses the evdev driver it effectively moves all actual hardware handling in to the kernel where it belongs. The kernel is even able to provide information about things like mouse button or axis function, giving the X server the same flexibility found in its best drivers. This provides a significantly simpler and more maintainable driver on the X side, thereby separating responsibilities clearly and making the X server a good citizen within the OS. Overall, using evdev creates a less complicated system. Because of these benefits, the current default is for the X server to use evdev by default on Linux. In doing so, the keymap changes to that provided by evdev, which has created some minor discomfort for those with custom mappings created through xbindkeys or xmodmap. All that's required in these cases is a simple remapping to the new keycodes. Obviously, this is not the sort of problem we expect to happen again in the foreseeable future, but it's a necessary price to pay once in a decade for the substantial benefits we gain by switching to evdev.

udev, hal, and console-setup

At this point there have been some significant improvements to the system, but a variety of other problems remain. First and foremost is that the xorg.conf is still absolutely necessary to set one's keymap when you're not using the default 'us' map. So Debian has to keep a significant amount of shell script around to ask the user for their keymap and set it accordingly. This information is also duplicated for the console, which has a separate configuration for the keymap. This creates obvious problems if these two ever get out of sync.

Additionally, hotplugging wasn't very well supported. The Linux kernel was able to handle hotplugging transparently by multiplexing all device events through a single device interface. While this worked well enough for many people, it's essentially a hack that made some significant functionality impossible. Because the X server had no idea what the kernel was doing behind its back, it couldn't manage per-device settings at all. Thus, if the devices being hotplugged didn't suit the defaults or weren't already configured in your xorg.conf, you were back to some of the same problems as before.

In order to solve both of these problems there is only one conceptual solution: have the X server ask the host OS what the devices are and how they should be treated specifically. If the device is a mouse, what do the extra buttons do? If the device is a keyboard, what keymap should it use? If the server can get that information, it doesn't have to have that configuration itself any more. This decreases complexity of the whole system because you have a single point where this information comes from, and all apps are able to query it in the same way as the X server.

The way these problems are dealt with on Linux is by using udev. udev listens to the kernel for device creation and deletion. When it detects an event, it sends a corresponding event out via netlink. The X server is able to query udev on startup in order to get a list of all the input devices currently detected. Additionally, the xorg.conf format was extended to allow group configuration, such as having all mice do something. The server can also continue to listen to udev, which sends events whenever a new device is connected, which is why input hotplugging is able to work.

The missing piece is console-setup and keyboard-configuration. keyboard-configuration takes care of the system-wide keymap configuration. keyboard-configuration currently reads xorg.conf on install and if it exists it uses that to set its system-wide keymap. This ensures that previous settings aren't lost in the transition. udev reads those settings on startup to find out what the keymap is, so that udev is able to tell the X server when it receives the query. There is a hack in the X server which makes it read XKB options from udev or hal when a keyboard device is hotplugged (including the devices present on startup if udev or hal is used). This eliminates the need for the xorg.conf to contain the keymap, and you need only set it in one place for the entire system (/etc/default/keyboard) and let the X server just use it like any other application. console-setup also reads the same file, and uses it to set the keymap on the Linux console.

Conclusion

The goals of the input subsystem improvements were to provide significant new functionality while simultaneously decreasing the complexity of both the Xorg codebase and the OS as a whole by utilizing standardized OS services. It has succeeded at both of these goals. There is now a single place to configure a system-wide keymap, rather than divergent settings for the console and for X. Additionally, device hotplugging is fully supported and the X server is able to take complete advantage of it. Finally, the X server can be configured to make specific settings apply to classes of devices (including hotplugged ones) instead of needing one configuration section per device. Both X.org and the X Strike Force believe that these are representative of the substantial improvements that X needs in order to continue to progress beyond a past with substantially less function and freedom. The following section is designed to help you use this system to the best of its capabilities.

HOWTO

Keyboard

On upgrade, keyboard-configuration will be brought in by xserver-xorg dependencies.

keyboard-configuration gathers keyboard layout information from the existing xorg.conf. So you should get something like the following lines in /etc/default/keyboard. If not, you might want to fix this manually.

$ grep -C 3 -i xkb /etc/default/keyboard
# The following variables describe your keyboard and can have the same
# values as the XkbModel, XkbLayout, XkbVariant and XkbOptions options
# in /etc/X11/xorg.conf.
XKBMODEL="pc105"
XKBLAYOUT="fr"
XKBVARIANT="latin9"
XKBOPTIONS="lv3:ralt_switch"

Once keyboard-configuration is ready, udev gathers information from it. It may be required to reboot or trigger udev if the upgrade did not. Then udevadm info --export-db should report the right keyboard layout.

$ /sbin/udevadm info --export-db | grep -i XKB
E: XKBMODEL=pc105
E: XKBLAYOUT=fr
E: XKBVARIANT=latin9
E: XKBOPTIONS=lv3:ralt_switch

Then, the Xserver takes information from udev when an input device is detected. As shown in /var/log/Xorg.0.log:

(II) config/udev: Adding input device Dell Dell USB Keyboard (/dev/input/event9)
(**) Dell Dell USB Keyboard: Applying InputClass "evdev keyboard catchall"
(**) Dell Dell USB Keyboard: always reports core events
(**) Dell Dell USB Keyboard: Device: "/dev/input/event9"
(II) Dell Dell USB Keyboard: Found keys
(II) Dell Dell USB Keyboard: Configuring as keyboard
(II) XINPUT: Adding extended input device "Dell Dell USB Keyboard" (type: KEYBOARD)
(**) Option "xkb_rules" "evdev"
(**) Option "xkb_model" "pc105"
(**) Option "xkb_layout" "fr"
(**) Option "xkb_variant" "latin9"
(**) Option "xkb_options" "lv3:ralt_switch"

To switch to another layout, you can add some overriding rules as a new ?InputClass section in /etc/X11/xorg.conf. For instance, to get German layout in X, but not on the console:

Section "InputClass"
  Identifier "german keyboard"
  MatchIsKeyboard "on"
  Option "XkbLayout" "de"
EndSection

If you have different keyboards with different layout, you might need to add some "match" rules to only change the layout for one of them.

Mouse

Mouse is even easier, there is nothing to do, evdev will be loaded automatically.

TODO talk about xinput

Touchpad

If you have a synaptics touchpad, it may be used as a mouse. But udev also reports the touchpad capability:

$ /sbin/udevadm info --export-db
[...]
P: /devices/platform/i8042/serio1/input/input8/event8
[...]
E: ID_INPUT_MOUSE=1
E: ID_INPUT_TOUCHPAD=1

so if the xserver-xorg-input-synaptics is installed, it will tell hal to load the synaptics driver instead of evdev thanks to the /usr/share/X11/xorg.conf.d/50-synaptics.conf file

TODO: talk about synclient which now does not require the dangerous SHMConfig anymore. For now Fedora has a good explanation of why SHMConfig is not needed.

Disabling auto-configuration of input-devices (HAL and udev)

Setting AutoAddDevices to off in the ServerFlags section of your xorg.conf should do the trick.

Ignoring a device

If you do not want Xorg to use one of your input devices, in the past you would just have not talked about it in xorg.conf. Now, udev notifies the server of all devices, and (almost) all of them are enabled by default. To disable it, you can use something like:

Section "InputClass"
  Identifier "bad device"
  MatchProduct "myname"
  Option "ignore" "on"
EndSection

and use /proc/bus/input/devices to find what "myname" should be.

See Also

See also Peter Hutterer's blog, especially this post and this one.

The xorg.conf manpage has the full documentation of ?InputClass sections and their matching options.

For a document similar to this one see this page from Arch linux.

madduck has a simple write-up on how to extend XKB beyond the default options, layouts, and variants.

Authors

Contributors to this document include Julien Cristau, BriceGoglin, Peter Hutterer, and DavidNusinow.