如何合法地以编程方式捕获 linux、X 下的第二个鼠标或轨迹球?
How to capture legitimately and programmatically a second mouse or a trackball under linux, X?
我正在设计和实现一个实验性 GUI 应用程序。我希望我的用户能够以符合人体工程学的方式同时使用双手与应用程序进行交互。例如,想象一下 GIMP 和左手(另一只手)的第二个鼠标(轨迹球):您可以用左手导航、平移、旋转或缩放图片,而 drawing/editing 点精确的点、线或同时用右手画数字。早在 2000 ~ 2002 年,我用两只鼠标做了一些实验:一只在 PS2 (USB) 接口上,另一只在 RS232 串行接口上。多年后的今天,我正在使用现代软件和现代 (USB) 输入设备重新审视这个古老的想法。
在理想情况下,我的目标是将第二个鼠标(或轨迹球)附加到带有 X 的 GNU/Linux 系统,然后能够:
- (1.) 继续使用主鼠标作为 X 默认主指针。
- (2.) 以编程方式访问/读取第二只鼠标的事件。
- (3.)分别获取第二只鼠标的事件(在一个
可识别的方式)从主鼠标。
- (4.)能够"consume"第二只鼠标的事件,这样每当我的程序启动时,第二只鼠标就不会影响主指针。
- (5.) 最好只在GUI出现时才捕捉第二只鼠标
window我的程序有焦点。
- (6.) 完整的解决方案最好不依赖于其他包或库,例如 gpm。但是,如果需要(任何)udev 规则,这不是问题,因为最终用户无论如何都需要安装我的程序。
- (7.) 解决方案最好不需要任何额外的权限或
例如将用户添加到 "input" 组的权限。
我已经花了 6 个多小时在互联网上搜索提示,但遗憾的是我没有超出一些 "dirty" 部分解决方案,有几个缺点:
- (A.) 将用户添加到 "input" 组。
- (B.) 在下面的示例程序中捕获第二只鼠标的事件。
- (C.)开放点:进一步看如何"consume"第二只鼠标的事件?
- (D.) 应对全局捕获(不只是window有焦点)等问题?
...
#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;
}
简答:The X Input Device Extension
稍微长一点的回答: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
我正在设计和实现一个实验性 GUI 应用程序。我希望我的用户能够以符合人体工程学的方式同时使用双手与应用程序进行交互。例如,想象一下 GIMP 和左手(另一只手)的第二个鼠标(轨迹球):您可以用左手导航、平移、旋转或缩放图片,而 drawing/editing 点精确的点、线或同时用右手画数字。早在 2000 ~ 2002 年,我用两只鼠标做了一些实验:一只在 PS2 (USB) 接口上,另一只在 RS232 串行接口上。多年后的今天,我正在使用现代软件和现代 (USB) 输入设备重新审视这个古老的想法。
在理想情况下,我的目标是将第二个鼠标(或轨迹球)附加到带有 X 的 GNU/Linux 系统,然后能够:
- (1.) 继续使用主鼠标作为 X 默认主指针。
- (2.) 以编程方式访问/读取第二只鼠标的事件。
- (3.)分别获取第二只鼠标的事件(在一个 可识别的方式)从主鼠标。
- (4.)能够"consume"第二只鼠标的事件,这样每当我的程序启动时,第二只鼠标就不会影响主指针。
- (5.) 最好只在GUI出现时才捕捉第二只鼠标 window我的程序有焦点。
- (6.) 完整的解决方案最好不依赖于其他包或库,例如 gpm。但是,如果需要(任何)udev 规则,这不是问题,因为最终用户无论如何都需要安装我的程序。
- (7.) 解决方案最好不需要任何额外的权限或 例如将用户添加到 "input" 组的权限。
我已经花了 6 个多小时在互联网上搜索提示,但遗憾的是我没有超出一些 "dirty" 部分解决方案,有几个缺点:
- (A.) 将用户添加到 "input" 组。
- (B.) 在下面的示例程序中捕获第二只鼠标的事件。
- (C.)开放点:进一步看如何"consume"第二只鼠标的事件?
- (D.) 应对全局捕获(不只是window有焦点)等问题?
...
#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;
}
简答:The X Input Device Extension
稍微长一点的回答: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