在linux中创建uinput设备时,会在文件系统中创建与该设备对应的一个或多个事件文件。 (例如,如果我创建一个输入鼠标,则创建文件/ dev / input / mouseN。)但是,如何确定为给定的输入设备创建了哪些文件? uinput内核模块似乎没有提供任何ioctl来获取该信息。一种可能的方法是在创建uinput设备之后立即轮询文件系统以查看显示的文件,但是这种方法不起作用,因为与其他设备(包括真实输入和uinput)的比赛也在同一时间插入或创建。我是否忽略了某些内容,或者我必须破解内核才能获得此信息?
答案 0 :(得分:6)
如果你查看 sysfs ,你可以找到你的信息。创建完输入设备后,请执行以下操作:
$ ls /sys/class/input/
event0 event1 ... eventN
input0 input2 ... input19 ... inputN
mouse0 mouse1 ... mouseN
mice
$ ls /sys/devices/virtual/input/
input19 mice
请注意,您可以在其他路径中找到虚拟设备。在这种情况下,input19是我的输入设备。哪个是对应的char设备?
$ ls /sys/devices/virtual/input/input19/
event14 name id ...
我的字符设备是/dev/input/event14
。我知道input19
是我的输入设备,因为我是唯一一个创建输入设备的用户。如果您想确定,您必须阅读其sysfs属性 name 并验证它确实是您的设备
$ cat /sys/devices/virtual/input/input19/name
foo-keyboard-201303261446
您可以通过阅读内核消息来检索有关新输入设备的信息:
$ dmesg | tail -n 7
input: foo-keyboard-201303261445 as /devices/virtual/input/input14
input: foo-keyboard-201303261445 as /devices/virtual/input/input15
input: foo-keyboard-201303261445 as /devices/virtual/input/input16
input: foo-keyboard-201303261445 as /devices/virtual/input/input17
input: foo-keyboard-201303261446 as /devices/virtual/input/input18
input: foo-keyboard-201303261446 as /devices/virtual/input/input19
input: foo-keyboard-201303261446 as /devices/virtual/input/input20
从您的程序中,您可以阅读/dev/kmsg
并抓住您的活动。也许您可以打开设备/dev/kmsg
,刷新它,等待select()
,直到您收到输入通知。
另一种方法是使用 libudev 来检索您的输入设备。请查看以下链接:libudev tutorial
更新:感谢您的问题,我改进了github上提供的libuinput库:libuinput by Federico。我实现了使用hte kmsg 设备的解决方案。
更新:2014年,Linux uinput
驱动程序得到了改进(git SHA1 e3480a61fc)。现在可以使用以下uinput
命令直接从ioctl
驱动程序获取sysfs路径:
/**
* UI_GET_SYSNAME - get the sysfs name of the created uinput device
*
* @return the sysfs name of the created virtual input device.
* The complete sysfs path is then /sys/devices/virtual/input/--NAME--
* Usually, it is in the form "inputN"
*/
#define UI_GET_SYSNAME(len) _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 300, len)
因此,如果你有可能使用比3.13更新的Linux内核,你可以使用上面的ioctl
来改进使用uinput的代码。
答案 1 :(得分:1)
这是我到目前为止找到的最好方法,结合这里给出的答案,我会做的事情如下:
How to get name (path) of uinput created device
char sysfs_device_name[16];
ioctl(uinput_fd_after_create, UI_GET_SYSNAME(sizeof(sysfs_device_name)), sysfs_device_name);
printf("/sys/devices/virtual/input/%s\n", sysfs_device_name);
//Now retrieve all files in that folder and grep for event* then
send_input_to_fd = open("the_event[n]", O_WRONLY | O_NDELAY);
现在send_input_to_fd应该是发送事件的正确FD。