/dev/input/mouse0 和 /dev/input/mice 之间的区别

dam*_*dam 1 mouse input-devices

我正在使用鼠标 USB 驱动程序,我真的不知道如何区分和使用由/dev/input/mouse0和发送的信息/dev/input/mice

在谷歌上搜索了几次后,我发现了一些关于使用的代码 /dev/input/mice

int fd, bytes;
unsigned char data[4];

const char *pDevice = "/dev/input/mice";

// Open Mouse
fd = open(pDevice, O_RDWR);
if(fd == -1)
{
    printf("ERROR Opening %s\n", pDevice);
    return -1;
}

int left, middle, right;
signed char x, y;

// Read Mouse
bytes = read(fd, data, sizeof(data));

if(bytes > 0)
{
    left = data[0] & 0x1;
    right = data[0] & 0x2;
    middle = data[0] & 0x4;

    x = data[1];
    y = data[2];
    printf("x=%d, y=%d, left=%d, middle=%d, right=%d\n", x, y, left, middle, right);

    if(left)
        return left;
    if(right)
        return right;
    if(middle)
        return middle;
}

return 0;
Run Code Online (Sandbox Code Playgroud)

该程序有效,但没有获得有关滚轮滚动的任何信息

我找到了一个使用的程序 /dev/input/event0

int fd;
struct input_event ev
const char* pFile = "/dev/input/event0";

fd = open(pFile, O_RDONLY);
if(fd == -1)
{
    printf("ERROR Opening %s\n", pFile);
    return -1;
}

read(fd, &ev, sizeof(ev));
std::cout << "type : " << ev.type << "  code : " << ev.code << "  value : " << ev.value << std::endl;

close(fd);

return 0;
Run Code Online (Sandbox Code Playgroud)

但是对角移动有问题,因为这个文件同时只保存了1个坐标,X坐标优先于Y;所以当你想在 Y 轴上移动鼠标时很烦人

但是,我没有找到任何可以使用的代码/dev/input/mouse0,那么此文件中保存了哪些信息?

所以我的问题是: 1. 保存了哪些信息/dev/input/mouse0?2.如何在不打开2个文件的情况下读取所有鼠标信息,并且没有优先级问题(滚动+X/Y轴移动)?

dan*_*zel 7

Linux的输入子系统用户空间的API文档回答您的问题。通常,所有文件/dev/input/都由将设备事件分发到用户空间的事件处理程序提供。

什么是/dev/input/mouse0 和/dev/input/mice?

来自介绍(我突出显示的重要部分)

1.3.1.3. 鼠标开发

mousedev 是一种使使用鼠标输入的旧程序工作的黑客。它从鼠标或数字化仪/平板电脑获取事件,并使用户可以使用 PS/2 样式(la /dev/psaux)鼠标设备。

/dev/input 中的 Mousedev 设备(如上所示)是:

crw-r--r--   1 root     root      13,  32 Mar 28 22:45 mouse0
crw-r--r--   1 root     root      13,  33 Mar 29 00:41 mouse1
crw-r--r--   1 root     root      13,  34 Mar 29 00:41 mouse2
crw-r--r--   1 root     root      13,  35 Apr  1 10:50 mouse3 ... 
...
crw-r--r--   1 root     root      13,  62 Apr  1 10:50 mouse30
crw-r--r--   1 root     root      13,  63 Apr  1 10:50 mice
Run Code Online (Sandbox Code Playgroud)

每个鼠标设备都分配给一个鼠标或数字转换器,最后一个鼠标除外。这个单一字符设备由所有鼠标和数字化仪共享,即使没有连接,该设备也存在。这对于热插拔 USB 鼠标很有用,因此即使没有鼠标,不处理热插拔的旧程序也可以打开设备。[...]

Mousedev 将生成 PS/2、ImPS/2 (Microsoft IntelliMouse) 或 ExplorerPS/2 (IntelliMouse Explorer) 协议,具体取决于读取数据的程序的意愿。您可以将 GPM 和 X 设置为其中任何一个。如果您想使用 USB 鼠标上的滚轮,则需要 ImPS/2,如果您想使用额外的(最多 5 个)按钮,则需要使用 ExplorerPS/2。

...这也可能是您看不到鼠标滚轮事件的原因。由于它是遗留程序的“黑客”,如果你没有必要,你不应该使用它。

如何读取所有鼠标信息 [...]?

使用evdev/dev/input/eventX提供的相应文件(事件处理程序,不要与 xorg-driver evdev 混淆)。这就是你的第二个代码片段显然所做的。

...但是优先级问题呢?

没有优先级问题。根据2.2。事件代码

同步报告:

用于将事件同步和分离成同时发生的输入数据更改数据包。例如,鼠标的运动可以为一个运动设置 REL_X 和 REL_Y 值,然后发出 SYN_REPORT。下一个动作将发出更多 REL_X 和 REL_Y 值并发送另一个 SYN_REPORT。

因为在一个事件之前的所有连续事件SYN_REPORT都可以被认为是同时发生的,所以报告它们的顺序无关紧要。

例如(使用我在 github 上找到的这个程序):

time:1528290186.256449  type:EV_REL     code:REL_X      value:-1
time:1528290186.256449  type:EV_REL     code:REL_Y      value:1
time:1528290186.256449  type:EV_SYN     code:SYN_REPORT value:0
time:1528290186.264460  type:EV_REL     code:REL_Y      value:1
time:1528290186.264460  type:EV_REL     code:REL_WHEEL  value:-1
time:1528290186.264460  type:EV_SYN     code:SYN_REPORT value:0
Run Code Online (Sandbox Code Playgroud)

如您所见,并发事件不仅由SYN_REPORT事件分隔,而且还具有相同的时间戳。

顺便说一下,您还可以使用evtest来查看设备生成的事件。如果您对它的工作方式感兴趣,可以在这里找到它的源代码。