在linux下用ioctl重新映射键盘
实际上,我正在尝试编写一个小程序,以捕获linux下特定USB键盘的全局键盘输入 我正在使用这段代码进行测试:在linux下用ioctl重新映射键盘,c,linux,keyboard-events,ioctl,C,Linux,Keyboard Events,Ioctl,实际上,我正在尝试编写一个小程序,以捕获linux下特定USB键盘的全局键盘输入 我正在使用这段代码进行测试: #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <linux/input.h> #include <string.h> #include <stdio.h> static co
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <string.h>
#include <stdio.h>
static const char *const evval[3] = {
"RELEASED",
"PRESSED ",
"REPEATED"
};
int main(void)
{
const char *dev = "/dev/input/event2";
struct input_event ev;
ssize_t n;
int fd;
char name[256]= "Unknown";
// int codes[2];
// codes[0] = 58; /* M keycap */
// codes[1] = 49; /* assign to N */
fd = open(dev, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "Cannot open %s: %s.\n", dev, strerror(errno));
return EXIT_FAILURE;
}
if(ioctl(fd, EVIOCGNAME(sizeof(name)), name) > 0)
{
printf("The device on %s says its name is '%s'\n", dev, name);
}
/*
int err = ioctl(fd, EVIOCSKEYCODE, codes);
if (err) {
perror("evdev ioctl");
}*/
while (1) {
n = read(fd, &ev, sizeof ev);
if (n == (ssize_t)-1) {
if (errno == EINTR)
continue;
else
break;
} else
if (n != sizeof ev) {
errno = EIO;
break;
}
if (ev.type == EV_KEY && ev.value >= 0 && ev.value <= 2)
printf("%s 0x%04x (%d)\n", evval[ev.value], (int)ev.code, (int)ev.code);
}
fflush(stdout);
fprintf(stderr, "%s.\n", strerror(errno));
return EXIT_FAILURE;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
静态常量字符*常量evval[3]={
“释放”,
“按下”,
“重复”
};
内部主(空)
{
const char*dev=“/dev/input/event2”;
结构输入\事件ev;
(三);
int-fd;
字符名[256]=“未知”;
//int码[2];
//代码[0]=58;/*M键帽*/
//代码[1]=49;/*分配给N*/
fd=打开(仅适用于开发人员);
如果(fd==-1){
fprintf(标准,“无法打开%s:%s.\n”,开发人员,strerror(errno));
返回退出失败;
}
如果(ioctl(fd,eviogname(sizeof(name)),name)>0)
{
printf(“%s上的设备称其名称为“%s”\n”,dev,name);
}
/*
int err=ioctl(fd、EVIOCSKEYCODE、代码);
如果(错误){
perror(“evdev ioctl”);
}*/
而(1){
n=读取(fd和ev,ev大小);
如果(n==(ssize_t)-1){
如果(errno==EINTR)
继续;
其他的
打破
}否则
如果(n!=电动汽车的尺寸){
errno=EIO;
打破
}
如果(ev.type==ev_KEY&&ev.value>=0&&ev.value使用EVIOCGRAB ioctl抓取输入设备,以便通过读取事件来消耗它们。通常(未抓取)在读取事件时不会消耗事件。ioctl采用附加参数,(int)1
进行抓取,(int)0
进行释放
要重新注入任何事件,只需将它们写入uinput
设备。参见示例a。(事件结构是相同的类型,您只需先将struct uinput\u user\u dev
结构写入uinput
设备,即可描述新的输入设备(它提供映射的事件)。)
换句话说,您不需要重新映射:您需要消费和转发。因此,如果我理解,我会从我的真实事件设备抓取,但我会写入虚拟的“uinput”设备?正确吗?@sigzegv:是的。请注意,您只需要使用ioctl一次;然后您就可以正常读取事件。ioctl只是告诉内核您通过读取事件来消耗事件。通常,在未捕获模式下,即使您读取了事件,内核和其他应用程序也会处理事件。