Port SpaceNavigator support on Linux to Qt5
This commit is contained in:
@@ -106,6 +106,12 @@ else()
|
||||
endif()
|
||||
|
||||
IF(SPNAV_FOUND)
|
||||
if (BUILD_QT5 AND UNIX AND NOT APPLE)
|
||||
find_package(Qt5X11Extras REQUIRED)
|
||||
include_directories(${Qt5X11Extras_INCLUDE_DIRS})
|
||||
list(APPEND FreeCADGui_LIBS ${Qt5X11Extras_LIBRARIES})
|
||||
endif()
|
||||
|
||||
add_definitions(-DSPNAV_FOUND)
|
||||
include_directories(
|
||||
${SPNAV_INCLUDE_DIR}
|
||||
|
||||
@@ -23,9 +23,11 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <QGlobalStatic>
|
||||
#ifdef Q_WS_X11
|
||||
#include <QX11Info>
|
||||
#endif
|
||||
#if defined(Q_OS_UNIX) && defined(SPNAV_FOUND)
|
||||
#include <QX11Info>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xproto.h>
|
||||
#endif // if defined(Q_OS_UNIX) && defined(SPNAV_FOUND)
|
||||
#include <QMainWindow>
|
||||
#include <QWidget>
|
||||
#include <FCConfig.h>
|
||||
@@ -34,12 +36,9 @@
|
||||
#include "SpaceballEvent.h"
|
||||
#include "Application.h"
|
||||
|
||||
//linux dependency libspnav-dev
|
||||
#ifdef Q_WS_X11
|
||||
#ifdef SPNAV_FOUND
|
||||
#include <spnav.h>
|
||||
#endif
|
||||
#endif
|
||||
#if defined(Q_OS_UNIX) && defined(SPNAV_FOUND)
|
||||
#include <spnav.h>
|
||||
#endif // if defined(Q_OS_UNIX) && defined(SPNAV_FOUND)
|
||||
|
||||
#ifdef _USE_3DCONNEXION_SDK
|
||||
//windows
|
||||
@@ -56,24 +55,19 @@ Gui::GUIApplicationNativeEventAware::GUIApplicationNativeEventAware(int &argc, c
|
||||
|
||||
Gui::GUIApplicationNativeEventAware::~GUIApplicationNativeEventAware()
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
#ifdef SPNAV_FOUND
|
||||
#if defined(Q_OS_UNIX) && defined(SPNAV_FOUND)
|
||||
if (spnav_close())
|
||||
Base::Console().Log("Couldn't disconnect from spacenav daemon\n");
|
||||
else
|
||||
Base::Console().Log("Disconnected from spacenav daemon\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _USE_3DCONNEXION_SDK
|
||||
#ifdef Q_OS_WIN
|
||||
#elif defined(Q_OS_WIN) && defined(_USE_3DCONNEXION_SDK)
|
||||
if (gMouseInput == this) {
|
||||
gMouseInput = 0;
|
||||
Base::Console().Log("3Dconnexion device detached.\n");
|
||||
}
|
||||
#endif
|
||||
//mac
|
||||
#ifdef Q_OS_MACX
|
||||
|
||||
#elif defined(Q_OS_MACX) && defined(_USE_3DCONNEXION_SDK)
|
||||
// if 3Dconnexion library was loaded at runtime
|
||||
if (InstallConnexionHandlers) {
|
||||
// Close our connection with the 3dx driver
|
||||
@@ -82,28 +76,34 @@ Gui::GUIApplicationNativeEventAware::~GUIApplicationNativeEventAware()
|
||||
CleanupConnexionHandlers();
|
||||
Base::Console().Log("Disconnected from 3Dconnexion driver\n");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif // Platform switch
|
||||
}
|
||||
|
||||
void Gui::GUIApplicationNativeEventAware::initSpaceball(QMainWindow *window)
|
||||
{
|
||||
mainWindow = window;
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
#ifdef SPNAV_FOUND
|
||||
if (spnav_x11_open(QX11Info::display(), window->winId()) == -1)
|
||||
#if defined(Q_OS_UNIX) && defined(SPNAV_FOUND)
|
||||
if (spnav_x11_open(QX11Info::display(), window->winId()) == -1) {
|
||||
Base::Console().Log("Couldn't connect to spacenav daemon\n");
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Base::Console().Log("Connected to spacenav daemon\n");
|
||||
spaceballPresent = true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _USE_3DCONNEXION_SDK
|
||||
#ifdef Q_OS_WIN
|
||||
#if QT_VERSION >= 0x050000
|
||||
static auto evFilter( [](void *msg, long *result){
|
||||
auto inst(dynamic_cast<Gui::GUIApplicationNativeEventAware *>(QApplication::instance()));
|
||||
if (inst) {
|
||||
return inst->xcbEventFilter(msg, result);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} );
|
||||
qApp->installNativeEventFilter(new Gui::RawInputEventFilter(evFilter));
|
||||
#endif // #if QT_VERSION >= 0x050000
|
||||
}
|
||||
|
||||
#elif defined(Q_OS_WIN) && defined(_USE_3DCONNEXION_SDK)
|
||||
spaceballPresent = Is3dmouseAttached();
|
||||
|
||||
if (spaceballPresent) {
|
||||
@@ -123,9 +123,8 @@ void Gui::GUIApplicationNativeEventAware::initSpaceball(QMainWindow *window)
|
||||
} else {
|
||||
Base::Console().Log("3Dconnexion device not attached.\n");
|
||||
}
|
||||
#endif // #ifdef Q_OS_WIN
|
||||
//mac
|
||||
#ifdef Q_OS_MACX
|
||||
|
||||
#elif defined(Q_OS_MACX) && defined(_USE_3DCONNEXION_SDK)
|
||||
OSStatus err;
|
||||
/* make sure the framework is installed */
|
||||
if (InstallConnexionHandlers == NULL)
|
||||
@@ -157,8 +156,7 @@ void Gui::GUIApplicationNativeEventAware::initSpaceball(QMainWindow *window)
|
||||
|
||||
Base::Console().Log("3Dconnexion driver initialized. Client ID: %d\n", tdxClientID);
|
||||
spaceballPresent = true;
|
||||
#endif
|
||||
#endif // _USE_3DCONNEXION_SDK
|
||||
#endif // Platform switch
|
||||
|
||||
Spaceball::MotionEvent::MotionEventType = QEvent::registerEventType();
|
||||
Spaceball::ButtonEvent::ButtonEventType = QEvent::registerEventType();
|
||||
@@ -238,7 +236,7 @@ bool Gui::GUIApplicationNativeEventAware::setOSIndependentMotionData()
|
||||
temp = motionDataArray[4];
|
||||
motionDataArray[4] = -motionDataArray[5];
|
||||
motionDataArray[5] = -temp;
|
||||
#elif _USE_3DCONNEXION_SDK
|
||||
#elif defined(_USE_3DCONNEXION_SDK)
|
||||
motionDataArray[0] = -motionDataArray[0];
|
||||
motionDataArray[3] = -motionDataArray[3];
|
||||
#else
|
||||
@@ -377,8 +375,99 @@ void Gui::GUIApplicationNativeEventAware::importSettings()
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(Q_OS_UNIX)
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
|
||||
bool Gui::GUIApplicationNativeEventAware::xcbEventFilter(void *message, long *result)
|
||||
{
|
||||
#if defined(SPNAV_FOUND)
|
||||
spnav_event navEvent;
|
||||
|
||||
// Qt4 used XEvents in native event filters, but Qt5 changed to XCB. The
|
||||
// SpaceNavigator API only works with XEvent, so we need to construct a
|
||||
// temporary XEvent with just enough information for spnav_x11_event()
|
||||
auto xcb_ev(static_cast<const xcb_client_message_event_t *>(message));
|
||||
if ((xcb_ev->response_type & 0x7F) == XCB_CLIENT_MESSAGE) {
|
||||
XClientMessageEvent xev;
|
||||
|
||||
xev.type = ClientMessage;
|
||||
xev.message_type = xcb_ev->type;
|
||||
memcpy(xev.data.b, xcb_ev->data.data8, sizeof(xev.data.b));
|
||||
xev.serial = 0; // These are just to squash warnings...
|
||||
xev.send_event = 0;
|
||||
xev.display = 0;
|
||||
xev.window = 0;
|
||||
xev.format = 0;
|
||||
|
||||
if (!spnav_x11_event(reinterpret_cast<XEvent *>(&xev), &navEvent)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// navEvent is now initialised
|
||||
|
||||
auto currentWidget(focusWidget());
|
||||
if (!currentWidget) {
|
||||
currentWidget = mainWindow;
|
||||
}
|
||||
|
||||
switch (navEvent.type) {
|
||||
case SPNAV_EVENT_MOTION:
|
||||
{
|
||||
motionDataArray[0] = navEvent.motion.x;
|
||||
motionDataArray[1] = navEvent.motion.y;
|
||||
motionDataArray[2] = navEvent.motion.z;
|
||||
motionDataArray[3] = navEvent.motion.rx;
|
||||
motionDataArray[4] = navEvent.motion.ry;
|
||||
motionDataArray[5] = navEvent.motion.rz;
|
||||
|
||||
setOSIndependentMotionData();
|
||||
|
||||
importSettings();
|
||||
|
||||
auto motionEvent(new Spaceball::MotionEvent());
|
||||
|
||||
motionEvent->setTranslations( motionDataArray[0],
|
||||
motionDataArray[1],
|
||||
motionDataArray[2] );
|
||||
motionEvent->setRotations( motionDataArray[3],
|
||||
motionDataArray[4],
|
||||
motionDataArray[5] );
|
||||
|
||||
postEvent(currentWidget, motionEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
case SPNAV_EVENT_BUTTON:
|
||||
{
|
||||
auto buttonEvent(new Spaceball::ButtonEvent());
|
||||
buttonEvent->setButtonNumber(navEvent.button.bnum);
|
||||
if (navEvent.button.press) {
|
||||
buttonEvent->setButtonStatus(Spaceball::BUTTON_PRESSED);
|
||||
} else {
|
||||
buttonEvent->setButtonStatus(Spaceball::BUTTON_RELEASED);
|
||||
}
|
||||
|
||||
postEvent(currentWidget, buttonEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
Base::Console().Log("Unknown spaceball event\n");
|
||||
return true;
|
||||
} // end switch (navEvent.type) {
|
||||
|
||||
#else
|
||||
Q_UNUSED(message);
|
||||
Q_UNUSED(result);
|
||||
return false;
|
||||
#endif // if/else defined(SPNAV_FOUND)
|
||||
}
|
||||
|
||||
#else // if QT_VERSION >= 0x050000
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
bool Gui::GUIApplicationNativeEventAware::x11EventFilter(XEvent *event)
|
||||
{
|
||||
#ifdef SPNAV_FOUND
|
||||
@@ -512,6 +601,8 @@ bool Gui::GUIApplicationNativeEventAware::x11EventFilter(XEvent *event)
|
||||
return false;
|
||||
#endif // SPNAV_FOUND
|
||||
}
|
||||
#endif // Q_WS_X11
|
||||
#endif // if/else QT_VERSION >= 0x050000
|
||||
|
||||
#endif // Q_OS_UNIX
|
||||
|
||||
#include "moc_GuiApplicationNativeEventAware.cpp"
|
||||
|
||||
@@ -32,21 +32,35 @@
|
||||
|
||||
class QMainWindow;
|
||||
|
||||
#if defined(Q_OS_UNIX)
|
||||
#include <X11/Xlib.h>
|
||||
#undef Bool
|
||||
#undef CursorShape
|
||||
#undef Expose
|
||||
#undef KeyPress
|
||||
#undef KeyRelease
|
||||
#undef FocusIn
|
||||
#undef FocusOut
|
||||
#undef FontChange
|
||||
#undef None
|
||||
#undef Status
|
||||
#undef Unsorted
|
||||
#undef False
|
||||
#undef True
|
||||
#undef Complex
|
||||
#include <functional>
|
||||
|
||||
#ifdef _USE_3DCONNEXION_SDK
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#elif defined(Q_OS_WIN) && defined(_USE_3DCONNEXION_SDK)
|
||||
#include "3Dconnexion/MouseParameters.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
//#define _WIN32_WINNT 0x0501 //target at least windows XP
|
||||
|
||||
#include <Windows.h>
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
#ifdef Q_OS_MACX
|
||||
#elif defined(Q_OS_MACX) && defined(_USE_3DCONNEXION_SDK)
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <ConnexionClientAPI.h>
|
||||
// Note that InstallConnexionHandlers will be replaced with
|
||||
@@ -59,9 +73,7 @@ extern UInt16 RegisterConnexionClient(UInt32 signature, UInt8 *name, UInt16 mode
|
||||
UInt32 mask) __attribute__((weak_import));
|
||||
extern void UnregisterConnexionClient(UInt16 clientID) __attribute__((weak_import));
|
||||
extern void CleanupConnexionHandlers(void) __attribute__((weak_import));
|
||||
#endif // Q_OS_MACX
|
||||
|
||||
#endif // _USE_3DCONNEXION_SDK
|
||||
#endif // Platform switch
|
||||
|
||||
namespace Gui
|
||||
{
|
||||
@@ -82,7 +94,7 @@ namespace Gui
|
||||
private:
|
||||
EventFilter eventFilter;
|
||||
};
|
||||
#endif
|
||||
#endif // if QT_VERSION >= 0x050000
|
||||
|
||||
class GUIApplicationNativeEventAware : public QApplication
|
||||
{
|
||||
@@ -102,10 +114,14 @@ namespace Gui
|
||||
float convertPrefToSensitivity(int value);
|
||||
|
||||
// For X11
|
||||
#ifdef Q_WS_X11
|
||||
#ifdef Q_OS_UNIX
|
||||
public:
|
||||
#if QT_VERSION >= 0x050000
|
||||
bool xcbEventFilter(void *message, long *result);
|
||||
#else
|
||||
bool x11EventFilter(XEvent *event);
|
||||
#endif // Q_WS_X11
|
||||
#endif // if/else QT_VERSION >= 0x050000
|
||||
#endif // Q_OS_UNIX
|
||||
|
||||
#ifdef _USE_3DCONNEXION_SDK
|
||||
// For Windows
|
||||
@@ -168,7 +184,7 @@ namespace Gui
|
||||
|
||||
#endif// Q_OS_MACX
|
||||
#endif // _USE_3DCONNEXION_SDK
|
||||
};
|
||||
}
|
||||
}; // end class GUIApplicationNativeEventAware
|
||||
} // end namespace Gui
|
||||
|
||||
#endif // GUIAPPLICATIONNATIVEEVENTAWARE_H
|
||||
|
||||
Reference in New Issue
Block a user