这是我的第一个问题,但我真的迷路了,我需要你的帮助.我写了一个程序在C,打印出鼠标按钮的数量.我决定使用XI. h为此事.该程序的行为奇怪.
这里展示的代码是一个更大程序的代码,这就是为什么包含了这么多库的原因。只是不要看它。
使用的源:XListInputDevicesXInternAtom
程序代码(mouse.c)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/XInput.h>
#include <X11/extensions/XI.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h> /* socket() connect() bind() listen() accept() socketpair() */
#include <sys/types.h>
#include <unistd.h>
#include <string.h> /* strcpy() */
#include <stdio.h> /* perror() */
#include <errno.h> /* error numbers */
#include <stdlib.h>
int main ( void )
{
XDeviceInfo mouse_info;
XDeviceInfoPtr ptr_mouse_info;
XDevice *mouse;
XID mouse_id;
XButtonInfoPtr ptr_mouse_buttons;
XKeyInfoPtr ptr_mouse_keys;
XValuatorInfoPtr ptr_mouse_axes;
char * mouse_name;
int num_devices, num_props, i;
Display *display = XOpenDisplay(NULL);
if (display == NULL)
{
perror("XOpenDisplay error");
exit(-1);
}
ptr_mouse_info = XListInputDevices(display, &num_devices);
for (i = 0; i < num_devices; i++)
{
if (XInternAtom(display, XI_MOUSE, 1) == ptr_mouse_info[i].type)
{
mouse_id=ptr_mouse_info[i].id;
mouse_name=ptr_mouse_info[i].name;
mouse = XOpenDevice(display, mouse_id);
ptr_mouse_buttons = (XButtonInfoPtr)&ptr_mouse_info[i].inputclassinfo[ButtonClass];
ptr_mouse_keys = (XKeyInfoPtr) &ptr_mouse_info[i].inputclassinfo[KeyClass];
printf("Mouse name: %s\n", mouse_name);
printf("Number of buttons: %d\n", ptr_mouse_buttons->num_buttons);
printf("Number of keys: %d\n", ptr_mouse_keys->num_keys);
}
}
printf("Mouse name: %s\n", mouse_name);
printf("Number of buttons: %d\n", ptr_mouse_buttons->num_buttons);
printf("Number of keys: %d\n", ptr_mouse_keys->num_keys);
XFreeDeviceList(ptr_mouse_info);
exit(0);
}
字符串
编译
cc mouse_test.c -lX11 -lXfixes -lXi -o mouse_test
型
我希望得到鼠标上的按钮数量(7个),但我总是得到:
Mouse name: Logitech Mechanical keyboard Logitech Mechanical keyboard Keyboard
Number of buttons: 4
Number of keys: 2
Mouse name: ROCCAT ROCCAT Kone Pro Keyboard
Number of buttons: 4
Number of keys: 2
Mouse name: ROCCAT ROCCAT Kone Pro
Number of buttons: 4
Number of keys: 2
Mouse name: ROCCAT ROCCAT Kone Pro
Number of buttons: 4
Number of keys: 2
型
我想,这可能与Linux驱动程序有关,但我不确定
1条答案
按热度按时间xxls0lw81#
我知道你可能期待一个实际的答案,但在我们谈论经验方面之前,我们需要讨论一些先验方面,一些哲学和概念问题。
我们把你的鼠标作为物理现实的一部分,这是一件事。软件不是现实本身,而是一个代表现实的模型。作为一个模型,总是有局限性,不完美等等。
所以,适当的问题是:你想知道你的实际物理设备的按钮的数量,或者Xorg识别的按钮的数量?如果你想获得实际物理设备的按钮的数量,你需要抓住它并计数它。
Xorg库将为您提供有关这些库所看到的信息。与某些专有操作系统不同,Xorg以及Unix(&类)系统上的大多数东西通常依赖于更通用的驱动程序。因此,一些Xorg驱动程序将被调整以支持大量设备,使用大量操作系统驱动程序-因为它也可以在多个操作系统上工作。(PS:我不是Xorg或Xorg驱动程序的Maven,所以如果有人可以在这里提供更准确的细节,欢迎这样做,并删除此说明后)
是的,我们的堆栈在这里还有另一层,操作系统,Xorg驱动程序可能在很大程度上依赖于操作系统驱动程序(在您的情况下,Linux内核驱动程序,因为我假设您运行的是Linux)。因此,这些驱动程序可能实现您设备的所有功能,也可能不实现,它们可能会也可能不会为Xorg提供有关您实际设备的准确信息。
所以,正如你所看到的,我们的堆栈中有一个整体的复杂性,可能会帮助你获得不准确的信息。
此外,我们还有X11协议,这是80年代中期的遗留协议,Xorg对它的实现,我们正在运行的库和扩展以及限制因素,以帮助您获得有关设备的准确信息。我们需要考虑到,我们正在处理一个非常旧的堆栈,太复杂了,开发时考虑到非常旧的桌面,已经进行了调整,设计和重新设计,使现代台式机的现代硬件符合旧的想法。
但足够的背景,让我们去解决方案。
就像我说的,Xorg是一个混乱的框架。我们有
XInput
API,它很旧,我们有一个更准确和最新的东西,那就是XInput2
。你的代码使用XInput
(1),所以这可能是一个限制因素。事实上,我自己的鼠标有很多按钮,列出的方式和你的完全一样。(我的触摸板也是)。我做了一个你的原始代码的改编版本,因为我试图在XWayland上运行(我不再使用X本机),但最后我配置了Xorg,让另一个用户在X上测试它。你的代码有其他问题无关的问题,我会解释在最后,但在这里我使用:
字符串
我的输出,剥离非鼠标条目:
型
正如你所看到的,这可能是一个很大的巧合,我们的两个鼠标都有相同数量的按钮和键,或者
XInput
(1)不再提供准确的信息。为了测试这是否是代码的问题,我运行了xinput list --long
,获得了以下内容:型
所以,如果
xinput list
可以正确地检索信息,我研究了一下,发现这是一个XInput
1的问题。所以我用XInput2
尝试,代码如下:型
通过这段代码,我得到了一个更准确的(我认为)结果:
型
所以,我认为我假设你的问题的答案是:如果你真的需要这些信息来自你的X11实现,使用XInput 2。虽然,我建议使用你的操作系统中的一些东西,如果不是这样的话,这在很大程度上取决于你的需求和建模用户是什么。
无关评论
在Wayland上,我得到了一个Segmentation Fault,因为你使用了很多未初始化的指针。永远不要在C中这样做,总是初始化你的指针,否则它们将以内存垃圾为值,而内存垃圾值指针指向未定义的位置。