博客
关于我
linux下如何模拟按键输入和模拟鼠标【转】
阅读量:473 次
发布时间:2019-03-06

本文共 4790 字,大约阅读时间需要 15 分钟。

Linux 输入事件处理与模拟技术

在 Linux 系统中,输入事件的处理和模拟是非常重要的功能,尤其是在开发自定义输入设备或需要控制鼠标和键盘输入的应用时。以下将详细介绍如何利用 Linux 输入事件模拟技术来实现按键和鼠标的输入效果。


按键输入事件模拟

1. 按键事件类型

在 Linux 输入系统中,按键事件的类型由 event.type 字段决定,常见类型包括:

  • EV_KEY:键盘按键事件。
  • EV_REL:相对坐标事件(通常用于轨迹球)。
  • EV_ABS:绝对坐标事件(用于直接指定坐标)。

按键事件的代码由 event.code 字段定义,键盘按键代码范围为 0~127,鼠标按键代码范围为 0x110~0x116。例如:

  • BTN_LEFT 对应鼠标左键,代码为 0x110。
  • BTN_RIGHT 对应鼠标右键,代码为 0x111。

2. 按键事件值

按键事件的值由 event.value 字段决定,具体含义如下:

  • EV_KEY:按键按下时值为 1,松开时值为 0。
  • EV_REL:正值表示移动方向,负值表示反方向。
  • EV_ABS:正值和负值分别表示两个不同的方向。

3. 按键输入模拟方法

要模拟按键输入,可以通过向 /dev/input/eventX 文件中写入 input_event 结构体来实现。以下是一个模拟按键输入的示例函数:

#include 
#include
#include
void simulate_key(int fd, int code) {
struct input_event event;
event.type = EV_KEY;
event.code = code;
event.value = 1; // 按键按下
gettimeofday(&event.time, NULL);
if (write(fd, &event, sizeof(event)) < 0) {
printf("模拟按键失败\n");
return;
}
// 发送 SYN_REPORT 事件
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(fd, &event, sizeof(event));
}

鼠标输入事件模拟

1. 鼠标事件类型

鼠标事件的类型包括:

  • EV_REL:相对坐标事件(X 和 Y 轴方向)。
  • EV_ABS:绝对坐标事件(用于直接指定坐标)。
  • EV_WHEEL:滚动事件(用于鼠标滚轮)。

2. 鼠标输入模拟方法

要模拟鼠标输入,可以通过向 /dev/input/eventX 文件中写入 input_event 结构体来实现。以下是一个模拟鼠标输入的示例函数:

void simulate_mouse(int fd) {
struct input_event event;
event.type = EV_REL;
event.code = REL_X;
event.value = 10; // X 轴方向移动
gettimeofday(&event.time, NULL);
write(fd, &event, sizeof(event));
event.type = EV_REL;
event.code = REL_Y;
event.value = 10; // Y 轴方向移动
write(fd, &event, sizeof(event));
// 发送 SYN_REPORT 事件
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(fd, &event, sizeof(event));
}

事件类型定义

在 Linux 输入系统中,事件类型的定义如下:

#define EV_SYN            0x00  // 同步事件
#define EV_KEY 0x01 // 按键事件
#define EV_REL 0x02 // 相对坐标事件
#define EV_ABS 0x03 // 绝对坐标事件
#define EV_MSC 0x04 // 其他事件
#define EV_SW 0x05 // 切换事件
#define EV_LED 0x11 // LED 状态事件
#define EV_SND 0x12 // 声音事件
#define EV_REP 0x14 // 重复事件
#define EV_FF 0x15 // 快捷功能事件
#define EV_PWR 0x16 // 电源管理事件
#define EV_FF_STATUS 0x17 // 快捷功能状态事件
#define EV_MAX 0x1f // 最大事件类型编号
#define EV_CNT (EV_MAX + 1) // 事件类型总数

实际应用示例

1. 模拟按键输入

以下是一个模拟常用按键的示例:

#include 
#include
#include
int main() {
int fd_kbd;
fd_kbd = open("/dev/input/event1", O_RDWR);
if (fd_kbd <= 0) {
printf("无法打开键盘设备\n");
return -1;
}
for (int i = 0; i < 10; i++) {
simulate_key(fd_kbd, KEY_A + i);
sleep(1);
}
close(fd_kbd);
return 0;
}

2. 模拟鼠标输入

以下是一个模拟鼠标滚轮滚动的示例:

void simulate_mouse滚轮(int fd) {
struct input_event event;
event.type = EV_REL;
event.code = REL_WHEEL;
event.value = 100; // 滚动100个单位
gettimeofday(&event.time, NULL);
write(fd, &event, sizeof(event));
}

鼠标和键盘事件读取示例

以下是一个读取鼠标和键盘事件的示例程序:

#include 
#include
#include
#include
#include
static void show_event(struct input_event *event) {
printf("事件类型: %d 代码: %d 值: %d\n", event->type, event->code, event->value);
return;
}
int main(int argc, char *argv) {
struct input_event event;
const char *file_name = argc == 2 ? argv[1] : "/dev/input/event2";
int fd = open(file_name, O_RDWR);
if (fd > 0) {
while (1) {
int ret = read(fd, &event, sizeof(event));
if (ret == sizeof(event)) {
show_event(&event);
} else {
break;
}
}
close(fd);
}
return 0;
}

模拟特殊按键(如 Ctrl + Space)

以下是一个模拟 Ctrl + Space 键的示例:

void simulate_ctrl_space(int fd) {
struct input_event event;
// 发送 Ctrl 按键按下事件
event.type = EV_KEY;
event.code = KEY_LEFTCTRL;
event.value = 1;
gettimeofday(&event.time, NULL);
write(fd, &event, sizeof(event));
// 发送 空格键按下事件
event.type = EV_KEY;
event.code = KEY_SPACE;
event.value = 1;
gettimeofday(&event.time, NULL);
write(fd, &event, sizeof(event));
// 发送 空格键松开事件
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = KEY_SPACE;
event.value = 0;
write(fd, &event, sizeof(event));
// 发送 Ctrl 松开事件
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = KEY_LEFTCTRL;
event.value = 0;
write(fd, &event, sizeof(event));
}

总结

通过以上方法,我们可以轻松地在 Linux 系统中模拟按键和鼠标的输入事件。无论是需要控制键盘输入,还是模拟鼠标的运动和滚动,都是可以通过向输入设备文件中写入 input_event 结构体来实现的。这种方法灵活且高效,是 Linux 输入事件处理的基础技术。

转载地址:http://eeobz.baihongyu.com/

你可能感兴趣的文章
PyQ5学习笔记——使用内部槽函数关闭窗口
查看>>
PyQ5学习笔记——使用自定义槽函数关闭窗口
查看>>
PyQt MimeData 文件名
查看>>
PyQt QML Material Design 按钮背景不会改变
查看>>
PyQt QString转成python stirng
查看>>
PyQt QToolButton在焦点时不更新图标
查看>>
PyQt 正确使用 emit() 和 pyqtSignal()
查看>>
PyQT-将文件复制到剪贴板
查看>>
PYQT.如何在QTableView中插入小部件
查看>>
PyQt4 代码在 PyQt5 (QHeaderView) 上不起作用
查看>>
PyQt4 到 PyQt5 ->mainFrame() 已弃用,需要修复才能加载网页
查看>>
PyQt4, class:mouseButtons用法
查看>>
PyQt4参考文档
查看>>
PyTorch Lightning:通过分布式训练扩展深度学习工作流
查看>>
PyQt5 - QThread:在线程仍在运行时被销毁
查看>>
PyQt5 - 如何从工作线程发出信号以通过 GUI 线程调用事件
查看>>
PyQt5 Designer 不工作:此应用程序无法启动,因为无法初始化 Qt 平台插件
查看>>
PyQt5 QLCNumber 没有更新
查看>>
PyQt5 TabWidget选项卡BarClicked TypeError:本机Qt信号不可调用
查看>>
PyQt5 从 PyQt4 转换信号代码
查看>>