我很好奇硬件如何与操作系统交互并看到这篇文章:键盘输入和文本输出如何工作?
似乎很多魔法都发生在 /dev/input 目录中。我决定看看我自己的操作系统(Ubuntu 16.10),看看我能找到什么。所有这些文件都列为 0 字节,当我这样做时,我会sudo cat mouse0 | hexdump -C
得到大量如下所示的十六进制数据:
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..............|
Run Code Online (Sandbox Code Playgroud)
所以我有几个问题:
这个文件的目的是什么?在我看来,这些设备文件只是用作将扫描码从内核传输到 X 服务器的中间人。为什么不直接从内核发送到 X 服务器呢?
为什么有这么多?我有超过 20 个单独的事件文件,但只有一个键盘和鼠标。
gro*_*mal 20
我会以相反的顺序回答这个问题:
- 为什么有这么多?
这些是代表机器上存在的大多数输入的设备(还有其他设备,例如麦克风将不在 中管理/dev/input
)。与一个键盘加一个鼠标会产生 2 个设备的假设相反,即使是最简单的键盘和最简单的鼠标仍然会产生 6 个设备。
为什么是 6?因为 Xorg 在启动时会创建一个测试输入键盘和一个测试输入鼠标(都是虚拟的)。此外,它会将测试键盘与实际键盘聚合到一个主要的虚拟设备中。即它将执行输入的复用。测试和实际鼠标也会发生同样的情况。
此外,典型的计算机(台式机或笔记本电脑)除了键盘之外还有其他按钮:电源按钮、睡眠按钮。
该eventN
在那里的设备都为事情设备是Xorg的创建和什么电脑有。在N
来自顺序ID和类似于在的ID xinput
。例如在我的机器上,我有:
[~]# 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
Run Code Online (Sandbox Code Playgroud)
并xinput
给我类似的 ID:
[~]$ 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)]
Run Code Online (Sandbox Code Playgroud)
(看eventN
对应id=N
)
没有 Xorg
1.1 这个文件的用途是什么?
请注意,所有随机输入(包括我的 USB 摄像头!)都被 Xorg 视为虚拟键盘的一部分。这允许复用和解复用输入。例如,我可以通过 USB 鼠标或触控板移动鼠标,而应用程序不需要知道其中的区别。
(事实上,USB 摄像头是虚拟键盘的一部分,因为它有一个按钮来打开和关闭它。因为它是一个按钮,它成为键盘子系统的一部分。实际的视频输入在/sys/class/video4linux
. )
换句话说,对于一个应用程序来说,实际上只有一个键盘和一个鼠标。但是 Xorg 和内核都需要知道这些差异。这导致了最后一部分:
1.2 为什么不直接从内核发送到X服务器?
因为 Xorg 需要知道区别。
在某些情况下它很有用。您可以以不同的方式将 Xorg 中的键重新映射到每个从属输入设备。例如,我有一个游戏设定与踏板,在赛车游戏中它输出使用时a,b和c它的每个踏板。然而,在编程时,我将这些键重新映射到Esc,Ctrl和Alt,而不重新映射键盘本身上的键。
此外,机器也没有必要运行 Xorg。例如,在无头服务器上,我可以获得以下输出:
[~]$ 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
Run Code Online (Sandbox Code Playgroud)
输入设备对应于串行端口(特别是在这种情况下)而不是键盘或鼠标。
不存在“直接发送”这样的事情。应用程序必须有某种读取数据的方法,在 Unix 中,这与读取常规文件的方式相同,即创建一个与常规文件 IO 系统调用配合使用的设备节点,以允许应用程序打开和读取它们。
除了鼠标和键盘之外,还有其他输入源。您可以通过查看来了解每一项的内容/sys/class/input
。在那里,您将细化具有相同 inputNN 名称的文件,这些文件是指向 sysfs 中描述它们所代表的设备的另一个节点的符号链接。其他常见来源包括声卡(在插入和拔出插头时发出信号)和计算机上的物理电源按钮。