#include <linux/uinput.h>
void emit(int fd, int type, int code, int val)
{
struct input_event ie;
ie.type = type;
ie.code = code;
ie.value = val;
/* timestamp values below are ignored */
ie.time.tv_sec = 0;
ie.time.tv_usec = 0;
write(fd, &ie, sizeof(ie));
}
int main(void)
{
struct uinput_setup usetup;
int i = 50;
int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
/* enable mouse button left and relative events */
ioctl(fd, UI_SET_EVBIT, EV_KEY);
ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
ioctl(fd, UI_SET_EVBIT, EV_REL);
ioctl(fd, UI_SET_RELBIT, REL_X);
ioctl(fd, UI_SET_RELBIT, REL_Y);
memset(&usetup, 0, sizeof(usetup));
usetup.id.bustype = BUS_USB;
usetup.id.vendor = 0x1234; /* sample vendor */
usetup.id.product = 0x5678; /* sample product */
strcpy(usetup.name, "Example device");
ioctl(fd, UI_DEV_SETUP, &usetup);
ioctl(fd, UI_DEV_CREATE);
/*
* On UI_DEV_CREATE the kernel will create the device node for this
* device. We are inserting a pause here so that userspace has time
* to detect, initialize the new device, and can start listening to
* the event, otherwise it will not notice the event we are about
* to send. This pause is only needed in our example code!
*/
sleep(1);
/* Move the mouse diagonally, 5 units per axis */
while (i--) {
emit(fd, EV_REL, REL_X, 5);
emit(fd, EV_REL, REL_Y, 5);
emit(fd, EV_SYN, SYN_REPORT, 0);
usleep(15000);
}
/*
* Give userspace some time to read the events before we destroy the
* device with UI_DEV_DESTOY.
*/
sleep(1);
ioctl(fd, UI_DEV_DESTROY);
close(fd);
return 0;
}
您可以使用uinput (
linux/uinput.h
)。它适用于 X 和 Wayland。上面的文档页面有一个示例,其中包括创建一个充当鼠标的虚拟设备:
如果您不想为uinput编写 C 代码,则可以使用 python 包,甚至一些现有的调试和测试实用程序在相同的evdev级别上工作,即
evemu-describe
,evemu-device
,evemu-play
,evemu-record
, 和evemu-event
来自 evemu 包。您需要成为 root 才能使用它们。这是一个示例,它找到鼠标设备及其生成的事件,然后人为地为其生成事件。首先我们列出 evdev 设备:
这是一个交互式命令,在列出物理设备后要求我们选择一个以获取更多详细信息。我们选择5、鼠标:
另一个 evemu 测试命令将向我们展示移动鼠标时生成的事件:
通常,对于鼠标移动,有事件类型 EV_REL、相对移动轴的事件代码 REL_X 和/或 REL_Y,以及移动的事件值距离(上面的 4、7、1)。这些事件之后是 EV_SYN 类型的同步事件,代码为 SYN_REPORT 以表示事件的结束。
我们可以用另一个测试命令注入我们自己的事件(比如移动 20,10):
该
--sync
选项将 SYN_REPORT 事件添加到末尾(相当于--type EV_SYN --code SYN_REPORT
)。最后,另一个测试命令
evemu-device
允许我们通过给出一个描述来创建一个新的输入设备,例如我们已经看到的鼠标。它使用/dev/uinput
并创建一个新/dev/input/event*
设备,然后我们可以使用它向其发送事件。所以即使你没有鼠标,你也可以动态添加一个,然后随心所欲地控制它。我没有带有绝对位置事件的设备来为您提供示例,但您可以类似地添加类似平板电脑的设备并通过它发送绝对移动事件。
根据meuh 的回答,我编写了这个小
mousemove
bash 脚本,XREL YREL
作为参数运行。作为
root
或通过sudo
:由于鼠标加速概念,实际移动不对应于精确值,除了非常低的值。