返回

Linux evdev 如何从多个游戏手柄中获取去重的输入事件?

Linux

从多个游戏手柄获取去重的输入事件:Linux evdev的解决方案

问题概述

在使用 evdev 从多个控制器获取输入事件时,Linux 系统可能会出现事件重复的现象。当连接多个控制器时,驱动程序无法区分它们并正确处理事件,导致按下其中一个控制器上的按钮会触发两个事件。

原因分析

evdev 设备驱动程序在处理来自多个控制器的输入事件时存在缺陷,导致控制器似乎正在互相镜像。

解决方案

为了解决此问题,需要找到一种方法来区分不同的控制器。通过以下步骤实现:

  1. 获取控制器唯一标识符: 每个控制器都有一个唯一的标识符,可以用来区分它们。
  2. 在输入系统中存储唯一标识符: 将控制器连接到系统时,将它们的唯一标识符存储在输入系统中。
  3. 在读取事件时检查标识符: 在读取输入事件时,检查事件的标识符与存储的标识符是否匹配。只有当标识符匹配时才处理事件。

代码实现

struct input_event e;
int controller_ids[2];
int i;

// 获取控制器唯一标识符
for (i = 0; i < 2; ++i)
{
    if(state.Gamepads[i] <= 0) { continue; }
    controller_ids[i] = get_controller_id(state.Gamepads[i]);
}

// 读取并处理事件
for (i = 0; i < 2; ++i)
{
    if(state.Gamepads[i] <= 0) { continue; }
    read(state.Gamepads[i], &e, sizeof(e));

    // 仅处理与当前控制器标识符匹配的事件
    if (e.type == EV_KEY && e.value == 1 && controller_ids[i] == e.code)
    {
        switch (e.code)
        {
            case BTN_WEST:
            LOG_INFO("BUTTON WEST PRESSED");
            break;
         }
     }
}

在该代码示例中,get_controller_id 函数用于获取控制器的唯一标识符。

结语

通过获取控制器唯一标识符并在读取事件时检查标识符,可以有效地消除 evdev 从多个控制器获取重复输入事件的问题。这将确保只处理来自特定控制器的事件,从而提供准确可靠的输入。

常见问题解答

  1. 为什么在连接多个控制器时会出现输入事件重复的问题?
    答:Linux evdev 驱动程序无法区分不同的控制器并正确处理事件,导致按下其中一个控制器上的按钮会触发两个事件。

  2. 如何解决输入事件重复的问题?
    答:通过获取控制器唯一标识符并在读取事件时检查标识符,可以确保只处理来自特定控制器的事件。

  3. 为什么需要获取控制器唯一标识符?
    答:控制器唯一标识符可以区分不同的控制器,并用于确定事件来自哪个控制器。

  4. 在读取事件时检查标识符有什么作用?
    答:在读取事件时检查标识符可以确保只处理来自特定控制器的事件,从而消除重复事件。

  5. 如何获取控制器的唯一标识符?
    答:可以使用 evdev --list 命令获取控制器的唯一标识符。