uinput的使用

Uinput是一个虚拟的设备,使得可以在用户控件处理input设备,一般来讲uinput设备文件存在于/dev/input或者/dev/input/uinput目录中。


uinput的使用


一. 创建合适的uinput设备


1.打开uinput设备

so easy, 在linux中,一切都是文件,所以按照通常的做法就是使用系统调用open()来打开uinput设备就可以啦, 不过要注意open()的第二个参数哦, 也就是打开的模式。


2.uinput的配置

打开设备以后我们需要告诉input子系统我们想要使用input event 的哪种type,这些type可以查看/usr/include/linux/input.h,

具有代表性的就是一下三种

#define EV_KEY  :代表按键的按下与释放事件

#define EV_REL :代表相对坐标事件,一般就是鼠标啦

#define EV_ABS : 代表绝对坐标事件,一般是触摸屏


那么如何配置 uinput 呢,那就是使用ioctl()啦, ioctl()是个很棒的系统调用,大家可以深入的研究一下。

我们使用UI_SET_EVBIT作为我们想进行的配置项,并使用以上三个define作为我们想要的事件类型,例如我们可以用如下语句是能按键的按下释放事件

ioctl(fd, UI_SET_EVBIT, EV_KEY)

仅仅这样还不够,我们还需要告诉input子系统,哪些键值可以被送到input子系统:

ioctl(fd, UI_SET_EVBIT, KEY_D)


如果是针对触摸屏进行配置的话,那就是这个样子的:

ioctl(fd, UI_SET_EVBIT, EV_ABS)

ioctl(fd, UI_SET_EVBIT, ABS_X)

ioctl(fd, UI_SET_EVBIT, ABS_Y)


3. 配置struct uinput_user_dev

第二步完成了最基本的配置,接下来我们需要向设备写入一个叫做 struct uinput_user_dev 的结构体,该结构体在/usr/include/linux/uinput.h中定义,如下

#define UINPUT_MAX_NAME_SIZE    80
struct uinput_user_dev {
        char name[UINPUT_MAX_NAME_SIZE];       //用户定义的uinput设备的名字
        struct input_id id;                                                  //用于描述设备的总线类型、厂商ID、产品ID和版本
        __u32 ff_effects_max;
        __s32 absmax[ABS_CNT];                               //定义最大的绝对坐标值,在进行触摸屏的配置时应该使用
        __s32 absmin[ABS_CNT];                               //定义最小的绝对坐标值,在进行触摸屏的配置时应该使用
        __s32 absfuzz[ABS_CNT];
        __s32 absflat[ABS_CNT];
};


我们可以这样填充这个结构体


struct uinput_user_dev iudev;


snprintf(iudev.name, UINPUT_MAX_NAME_SIZE, ''uinput_name");

iudev.id.bustype = BUS_USB;

iudev.id.vendor = 0x1234;

iudev.id.product = 0xfedc;

iudev.id.version = 1;


然后写入到设备中:

write(fd, &iudev, sizeof(iudev));


4. 创建出我们的uinput设备

到目前为止我们完成了对uinput的配置,但是还是不能使用,因为我们并没有申请创建这个设备。创建uinput需要以下语句


ioctl(fd, UI_DEV_CREATE)


OK, 以后我们就可以通过描述符 fd 来对uinput设备进行访问啦。


二. 将事件注入到input子系统中


为了完成这个操作我们需要使用一个结构体: struct input_event, 他有三个成员:

type :事件类型, EV_REL, EV_KEY, EV_ABS

code:键值或者坐标,可以使用 KEY_D 或者 ABS_X...

value:对于按键来讲 1 表示按下 0 表示释放, 如果是鼠标的话,则代表移动的数


例子:

按键:

struct input_event ev;

ev.type = EV_KEY;

ev.code = KEY_D;

ev.value = 1;

ret = write(fd, &ev, sizeof(ev));


触摸屏:

struct input_event ev[2];

ev[0].type = EV_ABS;

ev[0].code = ABS_X;

ev[0].value = 1023;


ev[1].type = EV_ABS;

ev[1].code = ABS_X;

ev[1].value = 102;


ret = write(fd, ev, sizeof(ev));


三. 销毁uinput设备

ret = ioctl(fd, UI_DEV_DESTROY);


PS:

本文中的触摸屏只是使用EV_ABS的其中一个例子而已,不要固话思维。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值