无法使用Qt 4.8和Linux从3Dconnexion SpaceNavigator获取事件

时间:2017-10-06 05:43:27

标签: c++ linux qt 3d mouse

我正在Linux下使用Qt 4.8开发3D应用程序。现在我需要支持3D鼠标(3Dconnexion SpaceNavigator)。它附带的SDK是相当古老的学校,使用X11来检索事件。

我正在使用随SDK提供的示例代码,并尝试将其与Qt 4.8合并。看起来设置鼠标正在工作(据我从调试输出中可以看出),但我没有得到任何带有QWidget :: x11Event(XEvent *)的XEvent。

我已经找到了使用libudev或libusb绕过SDK的解决方案,两者目前都不适用于我:/

也许有人已经解决了这个具体问题?我无法想象现在每个人都在使用X11:)

下面是我正在使用的Qt设置代码,调试输出看起来像是在工作:

Display* pDisplay = QX11Info::display();

Atom event_motion  = XInternAtom( pDisplay, "MotionEvent", TRUE );
Atom event_press   = XInternAtom( pDisplay, "ButtonPressEvent", TRUE );
Atom event_release = XInternAtom( pDisplay, "ButtonReleaseEvent", TRUE );
Atom event_command = XInternAtom( pDisplay, "CommandEvent", TRUE );


std::cout << "MotionEvent: " << event_motion << std::endl;
std::cout << "ButtonPressEvent: " << event_press << std::endl;
std::cout << "ButtonReleaseEvent: " << event_release << std::endl;
std::cout << "CommandEvent: " << event_command << std::endl;

Atom ActualType;
int ActualFormat;
unsigned long NItems, BytesReturn;

Window root = RootWindow( pDisplay, DefaultScreen(pDisplay) );
std::cout << "root: " << std::hex << "0x" << root << std::dec << std::endl;
unsigned char* p_property;

Window app_window = (Window) this->window()->winId();

XGetWindowProperty( pDisplay, root, event_command, 0, 1, FALSE, 
    AnyPropertyType, &ActualType, &ActualFormat, &NItems, &BytesReturn, &p_property );

if (0!=p_property)
{
    Window wnd = *(Window*) p_property;
    XFree( p_property );

    std::cout << "magellan window number: " << std::hex << wnd << std::dec << std::endl;

    XTextProperty wnd_name;
    XGetWMName( pDisplay, wnd, &wnd_name );
    std::cout << "magellan window name: " << wnd_name.value << std::endl; 

    XGetWMName( pDisplay, app_window, &wnd_name );
    std::cout << "Found window property: " << wnd_name.value << " (" << std::hex << app_window << std::dec << ")" << std::endl;

    XEvent CommandMessage;
    CommandMessage.type = ClientMessage;
    CommandMessage.xclient.format = 16;
    CommandMessage.xclient.send_event = FALSE;
    CommandMessage.xclient.display = pDisplay;
    CommandMessage.xclient.window = wnd;
    CommandMessage.xclient.message_type = event_command;

    CommandMessage.xclient.data.s[0] = (short) XHigh32( app_window );
    CommandMessage.xclient.data.s[1] = (short) XLow32( app_window );
    CommandMessage.xclient.data.s[2] = 27695;

    if (0!=XSendEvent( pDisplay, wnd, FALSE, 0x0000, &CommandMessage ))
    {
        std::cout << "Sent event to SpaceMouse" << std::endl;
    }

    XSelectInput( pDisplay, app_window, NoEventMask );
}

感谢任何提示:)

1 个答案:

答案 0 :(得分:0)

在对3D鼠标进行修补之后,我得出的结论是,“官方”方式导致了死胡同。驱动程序似乎不再支持Linux。

所以我咬了一口子,我现在正在使用Linux下的/ dev / input / event从3d鼠标收集数据,这至少是与UI无关的。我打开设备并在一个单独的线程中读取数据(设备定期轮询)。

到目前为止效果很好。