1

我正在设计和实现一个实验性的 GUI 应用程序。我希望让我的用户以符合人体工程学的方式同时使用双手与应用程序交互。例如,想象一下 GIMP 和您的左(另一只)手上的第二个鼠标(轨迹球):您可以用左手导航、平移、旋转或缩放图片,同时绘制/编辑点精确的点、线或图形同时用右手。早在 2000 ~ 2002 年,我用两只老鼠做了一些实验:一只在 PS2 (USB) 接口上,另一只在 RS232 串行接口上​​。多年后的今天,我正在用现代软件和现代(USB)输入设备重新审视这个古老的想法。

在理想情况下,我的目标是将第二个鼠标(或轨迹球)连接到带有 X 的 GNU/Linux 系统,然后能够:

  • (1.) 继续使用主鼠标作为 X 默认主指针。
  • (2.) 以编程方式从第二只鼠标访问/读取事件。
  • (3.) 与主鼠标分开(以可辨别的方式)从第二只鼠标获取事件。
  • (4.) 能够“消费”第二只鼠标的事件,这样每当我的程序启动时,第二只鼠标都不会影响主指针。
  • (5.) 优选地,仅当我的程序的 GUI 窗口具有焦点时才捕获第二个鼠标。
  • (6.) 优选地,完整的解决方案不应依赖于其他包或库,例如 gpm。但是,如果需要(任何)udev 规则,这不是问题,因为最终用户无论如何都需要安装我的程序。
  • (7.) 解决方案最好不需要任何额外的特权或权限,例如将用户添加到“输入”组。

我花了 6 个多小时在互联网上搜索提示,但遗憾的是,我并没有超出一些“肮脏”的部分解决方案,但有几个缺点:

  • (A.) 将用户添加到“输入”组。
  • (B.) 从第二只鼠标捕获事件,如下面的示例程序所示。
  • (C.) 开放点:进一步了解如何“消费”第二只鼠标的事件?
  • (D.) 处理全局捕获(不仅仅是有焦点的窗口)和其他问题?

...

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>

int main(int argc, char **argv)
{
  int ret=1; /* Program's return value; 0=success. */
  int fd; /* File descriptor (handler) */
  struct input_event ev;

  if (argc != 2) {
    printf("Usage:\n rdinpdev <device>\n"
      "Print events from an input device.\n"
    );
  }
  else {
    fd = open(argv[1], O_RDONLY);
    printf("open returned %d\n",fd);
    if(fd >= 0) {
      ret=0;
      while(1) {
        read(fd, &ev, sizeof(struct input_event));
        printf("value %d, type %d, code %d\n",ev.value,ev.type,ev.code);
      }
    }
  }
  return ret;
}
4

1 回答 1

1

简短回答:X 输入设备扩展

稍微长一点的答案:X 有一个核心输入设备的概念,通常是键盘和鼠标,以及可以使用上述扩展名查询的附加输入设备。如果您要求,这些替代输入可以生成事件。

下面是列出所有输入设备的一小段代码:

#include <stdio.h>

#include <X11/Xlib.h>
#include <X11/extensions/XInput.h>

int main (int argc, char *argv[])
{

  Display *d = XOpenDisplay (0);

  if (!d)
  {
    printf ("Failed to open display.\n");
    return 1;
  }

  int i, num;
  XDeviceInfo *dev;

  dev = XListInputDevices (d, &num);
  printf ("Found %d input devices:\n", num);

  for (i = 0; i < num; i++)
  {
    printf ("  name: %s; classes: %d; use: %d\n", dev[i].name, dev[i].num_classes, dev[i].use);
  }

  XCloseDisplay (d);
  return 0;
}

生成文件:

second-input: second-input.o
       $(CC) -o $@ $< -lX11 -lXi

.o:.c
       $(CC) -g -o $@ $<

我有一个连接到我的系统的 Wacom 绘图板,但这段代码列出了更多,有些是我没想到的:

Found 10 input devices:
  name: Virtual core pointer; classes: 2; use: 0
  name: Virtual core keyboard; classes: 1; use: 1
  name: Virtual core XTEST pointer; classes: 2; use: 4
  name: Virtual core XTEST keyboard; classes: 1; use: 3
  name: Power Button; classes: 1; use: 3
  name: Power Button; classes: 1; use: 3
  name: USB Mouse              ; classes: 2; use: 4
  name: Wacom Volito Pen; classes: 0; use: 2
  name: UVC Camera (046d:081d); classes: 1; use: 3
  name: AT Translated Set 2 keyboard; classes: 1; use: 3
于 2018-04-13T18:16:00.283 回答