了解linux中输入设备信息
cd /dev/input/进入到该目录然后查看输入event
cat /proc/bus/input/devices
从上图看出,我们现在外设不具有按键输入设备,所以我们需要新建一个虚拟按键设备,具体操作如下:
一、创建一个虚拟输入设备
// 第一步:打开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); // 发送同步信号
}
注:发送按下和抬起事件后必须发送同步信号,否则内核系统不会立即响应处理按键事件
三、测试
运行程序后