Linux – /dev/input – What exactly is this

deviceslinux

I was curious about how hardware interacted with the OS and came across this post: How do keyboard input and text output work?

It seems like a lot of the magic happens in the /dev/input directory. I decided to take a look on my own OS (Ubuntu 16.10) to see what I could find out. All of these files are listed as 0 bytes, and when I do sudo cat mouse0 | hexdump -C I get a ton of hexdata that looks like this:

00000000  b3 82 8a 58 00 00 00 00  53 74 09 00 00 00 00 00  |...X....St......|
00000010  01 00 1c 00 00 00 00 00  b3 82 8a 58 00 00 00 00  |...........X....|
00000020  53 74 09 00 00 00 00 00  00 00 00 00 00 00 00 00  |St..............|
00000030  b6 82 8a 58 00 00 00 00  06 56 0e 00 00 00 00 00  |...X.....V......|
00000040  01 00 10 00 01 00 00 00  b6 82 8a 58 00 00 00 00  |...........X....|
00000050  06 56 0e 00 00 00 00 00  00 00 00 00 00 00 00 00  |.V..............|

So I have a few questions:

  1. What is the purpose of this file? It seems to me that these device files are only used as middle-men to transfer the scancode from the kernel to the X server. Why not just send it directly from the kernel to the X server?

  2. Why there are so many? I have a little over 20 individual event files, but only one keyboard and mouse.

Best Answer

I'll go with the question in reverse order:

  1. Why are there so many?

Those are devices that stand for most inputs present on a machine (there are others, a microphone for example will not be managed in /dev/input). Contrary to the assumption that one keyboard plus one mouse would give 2 devices, even the simplest keyboard and simplest mouse would still give 6 of them.

Why 6? Because Xorg will create a test input keyboard and a test input mouse (both virtual) during its startup. Also, it will aggregate the test keyboard with the actual keyboard into a main virtual device. i.e. it will perform muxing of the input. The same will happen to the test and actual mouse.

Plus a typical computer (desktop or laptop) has other buttons apart from the keyboard: power button, sleep button.

The eventN devices in there are devices for the things that Xorg creates and for what the computer have. The N comes from sequential IDs and is analogous to the IDs in xinput. For example on my machine I have:

[~]# ls -l /dev/input/
total 0
drwxr-xr-x 2 root root     100 Jan 26 16:01 by-id
drwxr-xr-x 2 root root     140 Jan 26 16:01 by-path
crw-rw---- 1 root input 13, 64 Jan 26 16:01 event0
crw-rw---- 1 root input 13, 65 Jan 26 16:01 event1
crw-rw---- 1 root input 13, 74 Jan 26 16:01 event10
crw-rw---- 1 root input 13, 75 Jan 26 16:01 event11
crw-rw---- 1 root input 13, 76 Jan 26 16:01 event12
crw-rw---- 1 root input 13, 77 Jan 26 16:01 event13
crw-rw---- 1 root input 13, 66 Jan 26 16:01 event2
crw-rw---- 1 root input 13, 67 Jan 26 16:01 event3
crw-rw---- 1 root input 13, 68 Jan 26 16:01 event4
crw-rw---- 1 root input 13, 69 Jan 26 16:01 event5
crw-rw---- 1 root input 13, 70 Jan 26 16:01 event6
crw-rw---- 1 root input 13, 71 Jan 26 16:01 event7
crw-rw---- 1 root input 13, 72 Jan 26 16:01 event8
crw-rw---- 1 root input 13, 73 Jan 26 16:01 event9
crw-rw---- 1 root input 13, 63 Jan 26 16:01 mice
crw-rw---- 1 root input 13, 32 Jan 26 16:01 mouse0
crw-rw---- 1 root input 13, 33 Jan 26 16:01 mouse1

And xinput gives me analogous IDs:

[~]$ xinput list
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Logitech USB Optical Mouse                id=10   [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=14   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Power Button                              id=8    [slave  keyboard (3)]
    ↳ Sleep Button                              id=9    [slave  keyboard (3)]
    ↳ USB 2.0 Camera                            id=11   [slave  keyboard (3)]
    ↳ Asus Laptop extra buttons                 id=12   [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=13   [slave  keyboard (3)]

(Look that eventN corresponds to id=N)

Without Xorg

1.1 What is the purpose of this file?

Note that all random inputs (including my USB camera!) are seen by Xorg as part of the virtual keyboard. This allows for muxing and demuxing input. For example, I can move my mouse through my USB mouse or through my trackpad and an application does not need to know the difference.

(The fact that the USB camera is part of the virtual keyboard is because it has a button to turn it on and off. And since a it is a button, it becomes part of the keyboard subsystem. The actual video input is handled in /sys/class/video4linux.)

In other words, for an application there really is only one keyboard and only one mouse. But both Xorg and the kernel needs to know the differences. And this leads to the last part:

1.2 Why not just send it directly from the kernel to the X server?

Because Xorg needs to know the difference.

And there are situations in which it is useful. You can remap keys in Xorg to each slave input device differently. For example, I have a gaming set with pedals, when used in a racing game it outputs a, b and c for each of its pedals. Yet, when programming I remap these keys to Esc, Ctrl and Alt, without remapping the keys on the keyboard itself.

Also, it isn't necessary that a machine runs Xorg. For example, on a headless server I can get the following output:

[~]$ ls -l /dev/input/
total 0
drwxr-xr-x 2 root root      80 Nov  8 02:36 by-path
crw-rw---- 1 root input 13, 64 Nov  8 02:36 event0
crw-rw---- 1 root input 13, 65 Nov  8 02:36 event1
crw-rw---- 1 root input 13, 66 Nov  8 02:36 event2

Where the input devices correspond to serial ports (notably in this case they do) instead of keyboard or mouse.

Related Question