linux系统虚拟鼠标的实现

通过http://blog.csdn.net/jklinux/article/details/72570663博文可以得知:

一个输入设备获取到的数据是以struct input_event为单位的。
而且鼠标的相对坐标事件中的type值为EV_REL时, code的值为REL_X时, value的正值表示右移,负值表示左移, 移动量为value
code的值为REL_Y时, value的正值表示下移,负值表示上移,移动量为value

鼠标的按键事件中的type为EV_KEY时, code的值表示左(BTN_LEFT),中(BTN_MIDDLE), 右键(BTN_RIGHT)
value的值表示相应的键是按下或松手

输入事件的数据处理流程:

硬件设备 --> 设备驱动检测硬件并提交数据  <--> linux内核 <---> 系统调用 <--> 用户程序

而且linux里的输入设备驱动除了检测硬件产生相应的事件数据以外,还可以接收用户提交的事件数据(也就是用户程序里填好数据的input_event).
虚拟的输入设备就可以使用这种接口来实现。

如用键盘的方向代替鼠标的移动, 用’l’键代替鼠标的左键, ‘m’代替中键, ‘r’代替右键, ‘q’键退出
代码:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <linux/input.h>

void handle_rel(int dev_fd); //处理坐标事件
int main(int argc, char *argv[])
{
    int fd, ch; 
    struct input_event evt, evt_syn = {EV_SYN};

    if (argc < 2)
    {
        printf("usage: %s  mouse_device_file \n", argv[0]);
        return 1;
    }

    fd = open(argv[1], O_RDWR);
    if (fd < 0)
    {
        printf("open %s failed\n", argv[1]);
        return 1;
    }

    system("stty raw -echo"); //用于无须确认键,直接接收用户的按键

    while (1)
    {
        ch = getchar();
        if (('q' == ch) || ('Q' == ch)) 
            break;

        memset(&evt, 0, sizeof(evt));
        evt.type = EV_KEY;
        switch (ch)
        {
        case 'l':
            evt.code = BTN_LEFT;
            break;
        case 'r':
            evt.code = BTN_RIGHT;
            break;
        case 'm':
            evt.code = BTN_MIDDLE;
            break;
        case '\033':  //方向键
            evt.type = EV_REL;
            handle_rel(fd);
            break;  
        }
        if ((EV_KEY == evt.type) && evt.code) //按键事件处理
        {
            evt.value = 1; //按下
            write(fd, &evt, sizeof(evt)); //键按下的事件
            write(fd, &evt_syn, sizeof(evt_syn)); //提交事件

            evt.value = 0;
            write(fd, &evt, sizeof(evt)); //键松手的事件
            write(fd, &evt_syn, sizeof(evt_syn)); //提交事件
        }   
    }
    system("stty -raw echo"); //恢复终端属性
    return 0;
}

#define  VAL   10   //移动量的单位大小
void handle_rel(int dev_fd)
{
    int ch;
    struct input_event evt;

    evt.type = EV_REL;

    ch = getchar();
    if ('[' != ch)
        return;

    ch = getchar();
    switch (ch)
    {
    case 'A':  // up
        evt.code = REL_Y;
        evt.value = -VAL;
        break;
    case 'B': // down
        evt.code = REL_Y;
        evt.value = VAL;
        break;
    case 'C':  // right
        evt.code = REL_X;
        evt.value = VAL;
        break;
    case 'D': // left
        evt.code = REL_X;
        evt.value = -VAL;
        break;
    default:
        return;
    }

    write(dev_fd, &evt, sizeof(evt)); //提交相对坐标事件
    memset(&evt, 0, sizeof(evt));
    evt.type = EV_SYN; 
    write(dev_fd, &evt, sizeof(evt)); //提交事件

}

基于上例可以扩展为接收网络传输过来的数据再产生相应的输入事件,即可实现网络输入设备的功能。
另如果系统里没有相应的输入设备, 可以自己写个输入设备驱动用于支持虚拟输入设备功能。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值