
前一段时间,需要在一段时间内完成判断它是否为手动操作的功能. 基本思想是在后台监视键盘和鼠标输入事件. 那么我们如何捕获鼠标和键盘事件呢?让我们分享一下我们的实现原理和方法.
打开/ dev / input目录并执行ls命令,我们可以看到类似于以下内容的文件列表.
$ ls -l
total 0
crw-r-----. 1 root root 13, 64 Jan 29 2018 event0
crw-r-----. 1 root root 13, 65 Jan 29 2018 event1
crw-r-----. 1 root root 13, 66 Jan 29 2018 event2
crw-r-----. 1 root root 13, 67 Jan 29 2018 event3
crw-r-----. 1 root root 13, 68 Jan 29 2018 event4
crw-r-----. 1 root root 13, 63 Jan 29 2018 mice
crw-r-----. 1 root root 13, 32 Jan 29 2018 mouse0
crw-r-----. 1 root root 13, 33 Jan 29 2018 mouse1
crw-r-----. 1 root root 13, 34 Jan 29 2018 mouse2
熟悉Linux的朋友必须已经知道这里列出的文件是设备文件. 在Linux环境中,/ dev / input目录中的事件文件(event *)都是通过在驱动程序中调用input_register_device(struct input_dev * dev)生成的. 每个事件将报告指定的事件linux 键盘控制鼠标,例如触摸,鼠标,按钮等. 读取这些事件文件将获得与该事件文件相对应的设备的输入信息.
事件事件的输入数据的结构在linux / input.h文件中定义. 结构定义如下:

struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
时间,指事件发生的时间,其定义如下:
struct timeval
{
__time_t tv_sec; /* Seconds. */
__suseconds_t tv_usec; /* Microseconds. */
};
type,是指事件的类型,常见的事件类型有:
EV_KEY,键事件,键盘键,鼠标左右键等;

EV_REL,相对坐标,主要用于鼠标移动事件;
EV_ABS,绝对坐标,主要用于触摸屏移动事件.
代码事件代码,当事件类型为EV_KEY时,该代码为设备键盘代码,该代码在KEY_开头的input.h文件中定义;
value事件的值. 当事件类型代码为EV_KEY时,键操作值为1,释放操作值为0,事件类型代码为EV_REL. 值是一个正值和一个负值,分别代表不同方向上的值.
/ proc / bus / input / device文件描述了与事件相对应的相关设备信息,例如以下信息:
$cat devices
I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=LNXPWRBN/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
U: Uniq=
H: Handlers=kbd event0
B: EV=3
B: KEY=10000000000000 0
I: Bus=0017 Vendor=0001 Product=0001 Version=0100
N: Name="Macintosh mouse button emulation"
P: Phys=
S: Sysfs=/devices/virtual/input/input1
U: Uniq=
H: Handlers=mouse0 event1
B: EV=7
B: KEY=70000 0 0 0 0
B: REL=3
I: Bus=0011 Vendor=0001 Product=0001 Version=ab41
N: Name="AT Translated Set 2 keyboard"
P: Phys=isa0060/serio0/input0
S: Sysfs=/devices/platform/i8042/serio0/input/input2
U: Uniq=
H: Handlers=kbd event2
B: EV=120013
B: KEY=402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe
B: MSC=10
B: LED=7
I: Bus=0011 Vendor=0002 Product=0005 Version=0000
N: Name="ImPS/2 Generic Wheel Mouse"
P: Phys=isa0060/serio1/input0
S: Sysfs=/devices/platform/i8042/serio1/input/input3
U: Uniq=
H: Handlers=mouse1 event3
B: EV=7
B: KEY=70000 0 0 0 0
B: REL=103
您可以在上方的H: 中看到相应的eventxx.
我们可以通过上一节中列出的文件获得与键盘对应的事件文件. 通常,与键盘对应的事件文件是event2. 通过监视此文件,我们可以捕获键盘事件.
以下代码是我实现的用于监视键盘事件的功能代码. 如果20秒内没有键盘事件,则程序退出:
#include <sys/types.h>
#include <fcntl.h>
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <linux/input.h>
void listen_device(const char *dev, int timeout)
{
int retval;
fd_set readfds;
struct timeval tv;
int fd = open(dev, O_RDONLY);
struct input_event event;
if (fd < 0)
{
perror(dev);
return;
}
while (1)
{
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
tv.tv_sec = timeout;
tv.tv_usec = 0;
if((retval = select(fd+1, &readfds, NULL, NULL, &tv)) == 1)
{
if (read(fd, &event, sizeof(event)) == sizeof(event))
{
if (event.type == EV_KEY)
{
if (event.value == 0 || event.value == 1)
{
printf("key %d %s\n", event.code, event.value ? "Pressed" : "Released");
}
}
else
{
printf("type=%x %d %d\n", event.type, event.code, event.value);
}
}
}
else
{
break;
}
}
close(fd);
}
void listen_keyboard(int timeout)
{
listen_device("/dev/input/event2", timeout);
}
int main(int argc, char **argv)
{
listen_keyboard(20);
printf("keyboard timeout\n");
return 0;
}

我们还可以通过以上几个方面获取鼠标事件文件,以实现鼠标事件的捕获. 但实际上,有一种更方便的捕获鼠标的方法,即位于同一目录中的mouses文件,通过该文件可以获得已解析的鼠标事件.
具体方法如下:
(1)打开“ / dev / input / mice”文件.
(2)读取3个字节. 三个字节的值是``按钮类型''linux 键盘控制鼠标,``X的相对位移''和``Y的相对位移''. 这里首先使用Button,xRel,yRel.
(3)取下Button的低3位(Button和0x07). 0x00 = LeftButtonUp,0x01 = LeftButtonDown,0x02 = RightButtonDown.
以下代码是用于监视我实现的鼠标事件的功能代码:
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-288190-1.html
军舰出海
我在想桃子从韩国回来的时候会不会就是这样坐在飞机上哭的