微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

XISelectEvent 抛出 X 错误:BadValue整数超出操作范围

如何解决XISelectEvent 抛出 X 错误:BadValue整数超出操作范围

我正在尝试从 X11 读取事件,这是我的最小重现:

#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>

int main() {
    if (getenv("disPLAY") == NULL) return 1;

    void *x11 = dlopen("libX11.so.6",RTLD_GLOBAL | RTLD_LAZY);
    if (x11 == NULL) return 1;

    void *xInput2 = dlopen("libXi.so.6",RTLD_GLOBAL | RTLD_LAZY);
    if (xInput2 == NULL) return 1;

    // Check XInput2 functions are present,since libXi may contain XInput or XInput2.
    void *f = dlsym(xInput2,"XISelectEvents");
    if (f == NULL) return 1;

    // Load deFinitions
    dlsym(x11,"XOpendisplay");
    dlsym(x11,"XDefaultRootwindow");
    dlsym(x11,"XQueryExtension");
    dlsym(x11,"XSync");
    dlsym(x11,"XNextEvent");
    dlsym(x11,"XSendEvent");
    dlsym(x11,"XFreeEventData");
    dlsym(x11,"XGetEventData");
    dlsym(xInput2,"XISelectEvents");

    display *display = XOpendisplay(NULL);
    if (display == NULL) return 1;

    int xiOpcode;
    int queryEvent;
    int queryError;
    XQueryExtension(display,"XInputExtension",&xiOpcode,&queryEvent,&queryError);

    Window root = XDefaultRootwindow(display);
    XIEventMask *xiMask = new XIEventMask;
    xiMask->deviceid = XIAllMasterDevices;
    xiMask->mask_len = XIMaskLen(XI_LASTEVENT);
    xiMask->mask = new unsigned char[xiMask->mask_len];

    XISetMask(xiMask->mask,XI_RawKeyPress);
    XISetMask(xiMask->mask,XI_Rawkeyrelease);
    XISelectEvents(display,root,xiMask,1);
    XSync(display,0);

    delete [] xiMask->mask;
}

代码使用g++ test.cpp -lX11 -ldl -lXi

编译

它抛出以下错误

X Error of Failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of Failed request:  132 (XInputExtension)
  Minor opcode of Failed request:  46 ()
  Value in Failed request:  0xb
  Serial number of Failed request:  14
  Current serial number in output stream:  15

我无法理解并对此做出反应,任何帮助将不胜感激。

我试过调试,发现在执行XISelectEvent的时候正好出错。

解决方法

我现在感觉很傻,我忘记了使用 new 关键字在堆中分配的数组里面有垃圾。

我不得不使用

memset(xiMask->mask,xiMask->mask_len);

将数组中的所有值设置为0,然后根据需要开始设置每个元素的值。

更新:

我们可以使用 C++ 鲜为人知的特性,在单个表达式中使用 new T() 将最近分配的数组直接填充为 0。

也是这样:

xiMask->mask = new unsigned char[xiMask->mask_len]();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。