无法使用带有 Linux 的 Qt 4.8 从 3Dconnexion SpaceNavigator 获取事件
Can't get Events from 3Dconnexion SpaceNavigator using Qt 4.8 with Linux
我正在 Linux 下使用 Qt 4.8 开发 3D 应用程序。现在我需要支持 3d 鼠标 (3Dconnexion SpaceNavigator)。自带的SDK比较老派,使用X11来获取事件。
我正在使用随 SDK 提供的示例代码并尝试将其与 Qt 4.8 合并。看起来设置鼠标正在工作(据我从调试输出中可以看出),但我没有得到任何带有 QWidget::x11Event(XEvent*).
的 XEvents
我已经找到了使用 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 );
}
感谢任何提示:)
在对 3d 鼠标进行更多修改之后,我得出的结论是 "official" 方式是死路一条。 Linux 驱动程序似乎不再正确支持。
所以我咬紧牙关,现在我使用 Linux 下的 /dev/input/event 从 3d 鼠标收集数据,这至少是 UI 独立的。我打开设备并在单独的线程中读取数据(定期轮询设备)。
到目前为止效果很好。
我正在 Linux 下使用 Qt 4.8 开发 3D 应用程序。现在我需要支持 3d 鼠标 (3Dconnexion SpaceNavigator)。自带的SDK比较老派,使用X11来获取事件。
我正在使用随 SDK 提供的示例代码并尝试将其与 Qt 4.8 合并。看起来设置鼠标正在工作(据我从调试输出中可以看出),但我没有得到任何带有 QWidget::x11Event(XEvent*).
的 XEvents我已经找到了使用 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 );
}
感谢任何提示:)
在对 3d 鼠标进行更多修改之后,我得出的结论是 "official" 方式是死路一条。 Linux 驱动程序似乎不再正确支持。
所以我咬紧牙关,现在我使用 Linux 下的 /dev/input/event 从 3d 鼠标收集数据,这至少是 UI 独立的。我打开设备并在单独的线程中读取数据(定期轮询设备)。
到目前为止效果很好。