这主要是出于好奇,我试图了解事件处理如何在低级别上工作,所以请不要向我推荐可以为我做这件事的软件。
例如,如果我想用 C/C++ 编写一个对鼠标点击做出反应的程序,我假设我需要使用系统调用将某些函数挂接到内核,或者也许您需要不断检查鼠标的状态,我不知道。
我认为这是可能的,因为在 C/C++ 中几乎一切皆有可能,由于级别如此之低,我最感兴趣的是它是如何工作的,尽管我可能永远不需要自己实现它。
问题是它在linux中是如何工作的,是否有某些系统调用,c库等?
答案1
如果您正在编写一个在 Linux 中使用鼠标的实际程序,那么您很可能正在编写一个 X 应用程序,在这种情况下,您应该向 X 服务器询问鼠标事件。 Qt,GTK, 和库文件是一些流行的 C 库,它们提供了访问鼠标、键盘、图形、计时器以及编写 GUI 程序所需的其他功能的功能。 Ncurses是一个类似的终端应用程序库。
但是,如果您正在探索您的系统,或者由于某种原因无法使用 X,那么以下是它在内核接口上的工作方式。
UNIX 哲学的核心思想是“一切皆文件”。更具体地说,应通过与处理文件相同的系统调用来访问尽可能多的内容。因此鼠标的内核接口是一个设备文件。您open()
可以选择调用poll()
或select()
来查看是否有传入数据,并read()
读取数据。
在 USB 时代之前,特定的设备文件通常是串行端口,例如/dev/ttyS0
,或 PS/2 端口,/dev/psaux
。您可以使用鼠标中内置的任何硬件协议与鼠标进行通信。如今,/dev/input/*
子系统是首选,因为它提供了一种统一的、独立于设备的方式来处理许多不同的输入设备。特别是,/dev/input/mice
将为您提供来自连接到系统的任何鼠标的事件,并将/dev/input/mouseN
为您提供来自特定鼠标的事件。在大多数现代 Linux 发行版中,这些文件是在您插入鼠标时动态创建的。
有关您将读取或写入鼠标设备文件的具体内容的更多信息,您可以从输入/输入.txt在内核文档中。请特别查看第 3.2.2 节 (mousedev) 和 3.2.4 (evdev),以及第 4 节和第 5 节。
答案2
一般来说,来自硬件设备的信息通过以下方式暴露给应用程序:设备文件。对于鼠标,在现代Linux系统上,该设备是/dev/mice
(该设备收集所有连接的鼠标的事件,还有与每个单独的鼠标对应的设备)。
当您移动或单击鼠标时,鼠标会向计算机发送电信号,从而导致计算机产生打断。 Linux 内核中的一段代码称为中断处理程序依次读取事件数据(例如按下了哪个按钮)并触发内核内的一系列通知。
如果有任何应用程序正在读取与该设备对应的设备文件,则该应用程序会被告知输入正在等待。例如,如果应用程序被阻止在read
系统调用,然后系统调用返回。
在典型的系统上,有一个进程读取鼠标事件:X 窗口服务器。该程序管理图形显示和输入外围设备。然后,通过通用 X 事件协议向各个图形应用程序通知鼠标事件,该协议携带其他事件类型,例如按键、窗口焦点更改、窗口可见性更改……