参考https://www.cnblogs.com/yangwindsor/articles/3454955.html
linux/input.h 这个文件定义了event事件的结构体,API和标准按键的编码等;
struct input_event {
struct timeval time; //按键时间
__u16 type; //事件类型
__u16 code; //要模拟成什么按键
__s32 value;//是按下还是释放
};
type,指事件类型,常见的事件类型有:
EV_KEY, 按键事件,如键盘的按键(按下哪个键),鼠标的左键右键(是非击下)等;
EV_REL, 相对坐标,主要是指鼠标的移动事件(相对位移);
EV_ABS, 绝对坐标,主要指触摸屏的移动事件
code:事件的代码.
如果事件的类型代码是EV_KEY,该代码code为设备键盘代码.0~127为键盘上的按键代码
linux处理按键流程
- 系统启动后,驱动会生成按键设备/dev/input/event0
- 打开该设备得到一个文件描述符,监听该文件描述符的可读状态,例如使用select函数,或者阻塞读(直接用read)取该文件描述符
- 当按键触发后,内核会将该文件描述符置可读状态那么接着使用read函数去读该文件描述符,或者直接返回给read函数
- 根据读取到的数据,将该数据转换为struct input_event,然后根据键值来判断具体是那个按键按下或者弹起,一般使用弹起状态来判断按键触发了;
通过read堵塞读取数据;
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <linux/input.h>
#define SERIALPORT_NAME ("/dev/input/event0")
static int keys_fd = -1;
#define KEY_1 2
#define KEY_2 3
#define KEY_3 4
#define KEY_4 5
u8 initKey(void)
{
struct input_event t;
keys_fd = open(SERIALPORT_NAME, O_RDONLY);
if (keys_fd <= 0)
{
qDebug("open /dev/input/event2 device error!\n");
return 0;
}
while(1)
{
if (read(keys_fd, &t, sizeof(t)) == sizeof(t))
{
qDebug("key %d %s\n", t.code, (t.value) ? "Pressed" : "Released");
switch (t.code)
{
case KEY_1:
XKEY = (t.value) ? 0 : 1;
break;
case KEY_2:
XKEY1 = (t.value) ? 0 : 1;
break;
case KEY_3:
XKEY2 = (t.value) ? 0 : 1;
continue;
case KEY_4:
XKEY3 = (t.value) ? 0 : 1;
continue;
default:
continue;
}
}
}
close(keys_fd);
return 0;
}