Linux上层映射键盘键值发送至系统

了解linux中输入设备信息

cd /dev/input/进入到该目录然后查看输入event

 cat /proc/bus/input/devices

Linux上层映射键盘键值发送至系统_第1张图片

从上图看出,我们现在外设不具有按键输入设备,所以我们需要新建一个虚拟按键设备,具体操作如下:

一、创建一个虚拟输入设备

    // 第一步:打开uinput输入设备
    int key_fd = open (DEVNAME, O_RDWR);
    if (key_fd < 0)
    {
        qDebug() << "input dev open fail";
        return -1;
    }
    // 第二步:配置io
    // 设置设备所支持的动作,#defineEV_KEY 0x01  按下键
    if(ioctl(key_fd ,UI_SET_EVBIT,EV_KEY)<0)
    {
        qDebug()<<"don't set EV_KEY";
        return -1;
    }
    //设置设备所支持的动作,#defineEV_KEY 0x02  释放
    if(ioctl(key_fd ,UI_SET_EVBIT,EV_REP)<0)
    {
        qDebug()<<"don't set EV_REP";
        return -1;
    }
    // 设置兼职0-256的一个值
    for(int i = 0; i < 256; i++)
    {
        ioctl(key_fd , UI_SET_KEYBIT, i);
    }
    // 第三步:创建设备并写入至input子系统
    struct  uinput_user_dev  uinput;
    memset(&uinput,0,sizeof(uinput));
    // 设置版本
    uinput.id.version = 4;
    // 设置类型-这里使用usb
    /*#define BUS_PCI			0x01
      #define BUS_ISAPNP		0x02
      #define BUS_USB			0x03
      #define BUS_HIL			0x04
      #define BUS_BLUETOOTH		0x05
      #define BUS_VIRTUAL		0x06
    */
    uinput.id.bustype = BUS_USB;
    // 设置名称
    strncpy(uinput.name,"virtual device keyboard",UINPUT_MAX_NAME_SIZE);
    int ret = write( key_fd , &uinput, sizeof(uinput) );
    if(ret<0)
    {
        return -1;
    }
    int err = ioctl(key_fd, UI_DEV_CREATE);
    if(err < 0)
    {
        // 创建设备失败
        qDebug()<<"creat device fail";
        return -1;
    }

二、向系统发送键值

int reportkey(int fd, uint16_t type, uint16_t keycode, int32_t value)
{
    struct input_event event;

    event.type = type;
    event.code = keycode;
    event.value = value;

    gettimeofday(&event.time, 0);

    if (write(fd, &event, sizeof(struct input_event)) < 0)
    {
        printf("report key error!\n");
        return -1;
    }
    else
    {
        printf("report key ok!\n");
    }
    return 0;
}

void sendKeyEvent(int fd, uint8_t ui8_keyValue)
{
    uint16_t keycode;
    switch (ui8_keyValue)
    {
    case 1:
        keycode = KEY_Z;
        break;
    case 2:
        keycode = KEY_X;
        break;
    case 3:
        keycode = KEY_C;
        break;
    case 4:
        keycode = KEY_V;
        break;
    case 5:
        keycode = KEY_A;
        break;
    case 6:
        keycode = KEY_S;
        break;
    case 7:
        keycode = KEY_D;
        break;
    case 8:
        keycode = KEY_F;
        break;
    case 9:
        keycode = KEY_G;
        break;
    case 10:
        keycode = KEY_1;
        break;
    case 11:
        keycode = KEY_2;
        break;
    case 12:
        keycode = KEY_3;
        break;
    case 13:
        keycode = KEY_4;
        break;
    case 14:
        keycode = KEY_5;
        break;
    case 15:
        keycode = KEY_6;
        break;
    case 16:
        keycode = KEY_7;
        break;
    default:
        keycode = KEY_ESC;
        break;
    }
    reportkey(fd, EV_KEY, keycode, KEYDOWN);  // 发送按下事件
    reportkey(fd, EV_SYN, SYN_REPORT, KEYUP); // 发送同步信号
    reportkey(fd, EV_KEY, keycode, KEYUP);    // 发送抬起事件
    reportkey(fd, EV_SYN, SYN_REPORT, KEYUP); // 发送同步信号

}

注:发送按下和抬起事件后必须发送同步信号,否则内核系统不会立即响应处理按键事件

三、测试

运行程序后

Linux上层映射键盘键值发送至系统_第2张图片

你可能感兴趣的:(Linux)