linux 虚拟输入设备(uinput)模拟鼠标和键盘的使用方法

转自 http://blog.csdn.net/outblue/archive/2010/02/04/5288760.aspx

Dashboard January 2007 Issue
Mehul Patel
Using uinput driver in Linux-
2.6.x to send user input

Dashboard January 2007 Issue
Using uinput driver in Linux-2.6.x to send user
input
Introduction:
The Linux 2.6.x provides a “uinput” driver, which helps users to inject data to the Linux kernel.
This is very useful while writing applications to interface customized input devices like wireless
joystick, keyboard etc.
The driver uses /dev/uinput device to send data to kernel space which in turn send data to Xwindows
OR active shell. This feature can be used to perform automated shell scripts which
involve graphical user inputs.
Uinput is configured as a loadable module in most of the Linux kernels. You can load uinput
driver by giving the following commands.
$ modprobe uinput
$ lsmod
The “lsmod” command lists all the drivers loaded in the Linux system. You should see “uinput”
driver in the list.
The next step is to develop a sample application. This application will send the user key
sequence to kernel which is in turn sent to X-Windows or shell.
Opening an input device:
// Open the input device
uinp_fd = open("/dev/uinput", O_WRONLY | O_NDELAY);
if (uinp_fd == NULL)
{
printf("Unable to open /dev/uinput/n");
return -1;
}
After opening device you have to configure the uinput device parameters (mouse, keyboard,
etc) using the ioctl() function such as:
ioctl (out_fd, UI_SET_EVBIT, EV_KEY);
ioctl (out_fd, UI_SET_EVBIT, EV_REP);
The EV_KEY and EV_REP inform the uinput driver as the event is a keyboard event and the
key value contains the key repetition property.
Dashboard January 2007 Issue
Sending events to kernel:
All the events coming from the user program will be carried to the kernel space through the
structure "struct input_event" defined in kernels "/usr/include/linux/input.h".
A keyboard can be generated using following piece of code:
event.type = EV_KEY;
event.code = KEY_ENTER;
event.value = 1;
write (uinp_fd, &event, sizeof(event));
The above example will send ENTER key to kernel. This key event in-turn will be sent to user
space application. All the key definitions are defined in “/usr/include/linux/input.h” file.
You can use the following sample code to test Linux uinput interface.
// uinput.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* Globals */
static int uinp_fd = -1;
struct uinput_user_dev uinp; // uInput device structure
struct input_event event; // Input device structure
/* Setup the uinput device */
int setup_uinput_device()
{
// Temporary variable
int i=0;
// Open the input device
uinp_fd = open("/dev/uinput", O_WRONLY | O_NDELAY);
if (uinp_fd == NULL)
{
Dashboard January 2007 Issue
printf("Unable to open /dev/uinput/n");
return -1;
}
memset(&uinp,0,sizeof(uinp)); // Intialize the uInput device to NULL
strncpy(uinp.name, "PolyVision Touch Screen", UINPUT_MAX_NAME_SIZE);
uinp.id.version = 4;
uinp.id.bustype = BUS_USB;
// Setup the uinput device
ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY);
ioctl(uinp_fd, UI_SET_EVBIT, EV_REL);
ioctl(uinp_fd, UI_SET_RELBIT, REL_X);
ioctl(uinp_fd, UI_SET_RELBIT, REL_Y);
for (i=0; i < 256; i++) {
ioctl(uinp_fd, UI_SET_KEYBIT, i);
}
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MOUSE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_TOUCH);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MOUSE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_LEFT);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MIDDLE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_RIGHT);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_FORWARD);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_BACK);
/* Create input device into input sub-system */
write(uinp_fd, &uinp, sizeof(uinp));
if (ioctl(uinp_fd, UI_DEV_CREATE))
{
printf("Unable to create UINPUT device.");
return -1;
}
return 1;
}
void send_click_events( )
{
// Move pointer to (0,0) location
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_REL;
event.code = REL_X;
Dashboard January 2007 Issue
event.value = 100;
write(uinp_fd, &event, sizeof(event));
event.type = EV_REL;
event.code = REL_Y;
event.value = 100;
write(uinp_fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
// Report BUTTON CLICK - PRESS event
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = BTN_LEFT;
event.value = 1;
write(uinp_fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
// Report BUTTON CLICK - RELEASE event
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = BTN_LEFT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
}
void send_a_button()
{
// Report BUTTON CLICK - PRESS event
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = KEY_A;
Dashboard January 2007 Issue
event.value = 1;
write(uinp_fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
// Report BUTTON CLICK - RELEASE event
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = KEY_A;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
}
/* This function will open the uInput device. Please make
sure that you have inserted the uinput.ko into kernel. */
int main()
{
// Return an error if device not found.
if (setup_uinput_device() < 0)
{
printf("Unable to find uinput device/n");
return -1;
}
send_a_button(); // Send a "A" key
send_click_events(); // Send mouse event
/* Destroy the input device */
ioctl(uinp_fd, UI_DEV_DESTROY);
/* Close the UINPUT device */
close(uinp_fd);
}

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/outblue/archive/2010/02/04/5288760.aspx

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Linux中实现读写HID模拟鼠标可以通过以下步骤来完成: 1. 首先,需要使用hidraw设备来读写HID设备。HID设备Linux中通常以hidraw设备的形式出现。可以通过以下命令查看系统中的hidraw设备: ```shell ls /dev/hidraw* ``` 2. 打开hidraw设备以进行读写操作。可以使用C语言编写一个程序来打开hidraw设备,并使用read和write函数来读写数据。以下是一个简单的示例程序: ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <linux/hidraw.h> int main() { int fd; char buf[8]; fd = open("/dev/hidraw0", O_RDWR); if (fd < 0) { perror("Unable to open hidraw device"); exit(1); } // 读取数据 if (read(fd, buf, sizeof(buf)) < 0) { perror("Unable to read from hidraw device"); exit(1); } // 写入数据 if (write(fd, buf, sizeof(buf)) < 0) { perror("Unable to write to hidraw device"); exit(1); } close(fd); return 0; } ``` 3. 解析HID报文。HID报文通常是由一系列的字节组成的。根据HID规范,可以解析报文中的每个字节来获取鼠标的相关信息,例如鼠标的坐标、按键状态等。 4. 模拟鼠标操作。根据解析得到的鼠标信息,可以使用X11或者uinput模拟鼠标操作。X11是Linux下的图形系统,可以使用XTest库来模拟鼠标操作。uinputLinux内核提供的一个虚拟输入设备接口,可以使用uinput库来模拟鼠标操作。 以下是一个使用XTest库来模拟鼠标操作的示例程序: ```c #include <stdio.h> #include <X11/Xlib.h> #include <X11/extensions/XTest.h> int main() { Display *display; Window root; XEvent event; display = XOpenDisplay(NULL); if (display == NULL) { fprintf(stderr, "Unable to open display\n"); return 1; } root = DefaultRootWindow(display); // 模拟鼠标移动 XTestFakeMotionEvent(display, -1, 100, 100, CurrentTime); // 模拟鼠标点击 XTestFakeButtonEvent(display, 1, True, CurrentTime); XTestFakeButtonEvent(display, 1, False, CurrentTime); XFlush(display); XCloseDisplay(display); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值