diff --git a/src/Gui/3Dconnexion/GuiNativeEventCommon.h b/src/Gui/3Dconnexion/GuiNativeEventCommon.h new file mode 100644 index 0000000000..9129161468 --- /dev/null +++ b/src/Gui/3Dconnexion/GuiNativeEventCommon.h @@ -0,0 +1,11 @@ + public: + GuiNativeEvent(GUIApplicationNativeEventAware *app); + ~GuiNativeEvent(); + void initSpaceball(QMainWindow *window); + private: + GuiNativeEvent(); + GuiNativeEvent(const GuiNativeEvent&); + GuiNativeEvent& operator=(const GuiNativeEvent&); + GUIApplicationNativeEventAware *mainApp; + int motionDataArray[6]; + diff --git a/src/Gui/3Dconnexion/GuiNativeEventLinux.cpp b/src/Gui/3Dconnexion/GuiNativeEventLinux.cpp index 0723bf0e7a..9cecc6be91 100644 --- a/src/Gui/3Dconnexion/GuiNativeEventLinux.cpp +++ b/src/Gui/3Dconnexion/GuiNativeEventLinux.cpp @@ -5,7 +5,6 @@ Implementation by Torsten Sadowski 2018 #include "GuiNativeEventLinux.h" #include "GuiApplicationNativeEventAware.h" -#include "SpaceballEvent.h" #include #include #include @@ -46,34 +45,22 @@ void Gui::GuiNativeEvent::pollSpacenav() spnav_event ev; while(spnav_poll_event(&ev)) { - QWidget *currentWidget = mainApp->focusWidget(); - if (!currentWidget) - return; - //if (!setOSIndependentMotionData()) return; - //importSettings(); switch (ev.type) { case SPNAV_EVENT_MOTION: { - Spaceball::MotionEvent *motionEvent = new Spaceball::MotionEvent(); - motionEvent->setTranslations(ev.motion.x, ev.motion.y, ev.motion.z); - motionEvent->setRotations(ev.motion.rx, ev.motion.ry, ev.motion.rz); - mainApp->postEvent(currentWidget, motionEvent); + motionDataArray[0] = -ev.motion.x; + motionDataArray[1] = -ev.motion.z; + motionDataArray[2] = -ev.motion.y; + motionDataArray[3] = -ev.motion.rx; + motionDataArray[4] = -ev.motion.rz; + motionDataArray[5] = -ev.motion.ry; + mainApp->postMotionEvent(&motionDataArray[0]); break; } case SPNAV_EVENT_BUTTON: { - Spaceball::ButtonEvent *buttonEvent = new Spaceball::ButtonEvent(); - buttonEvent->setButtonNumber(ev.button.bnum); - if (ev.button.press) - { - buttonEvent->setButtonStatus(Spaceball::BUTTON_PRESSED); - } - else - { - buttonEvent->setButtonStatus(Spaceball::BUTTON_RELEASED); - } - mainApp->postEvent(currentWidget, buttonEvent); + mainApp->postButtonEvent(ev.button.bnum, ev.button.press); break; } } diff --git a/src/Gui/3Dconnexion/GuiNativeEventLinux.h b/src/Gui/3Dconnexion/GuiNativeEventLinux.h index 5a24673b1e..df4a5abb9f 100644 --- a/src/Gui/3Dconnexion/GuiNativeEventLinux.h +++ b/src/Gui/3Dconnexion/GuiNativeEventLinux.h @@ -12,15 +12,9 @@ namespace Gui class GuiNativeEvent : public QObject { - public: - GuiNativeEvent(GUIApplicationNativeEventAware *app); - ~GuiNativeEvent(); - void initSpaceball(QMainWindow *window); +#include "GuiNativeEventCommon.h" private: - GuiNativeEvent(); - GuiNativeEvent(GuiNativeEvent*); void pollSpacenav(); - GUIApplicationNativeEventAware *mainApp; }; } diff --git a/src/Gui/3Dconnexion/GuiNativeEventLinuxX11.cpp b/src/Gui/3Dconnexion/GuiNativeEventLinuxX11.cpp new file mode 100644 index 0000000000..2a10b63921 --- /dev/null +++ b/src/Gui/3Dconnexion/GuiNativeEventLinuxX11.cpp @@ -0,0 +1,244 @@ + /* +Implementation by Torsten Sadowski 2018 + */ + +#include "GuiNativeEventLinuxX11.h" + +#include "GuiApplicationNativeEventAware.h" +#include "SpaceballEvent.h" +#include +#include +#include + +#include +#include + +#if QT_VERSION >= 0x050000 + #include + #include "GuiRawInputEventFilter.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 +#endif // #if QT_VERSION >= 0x050000 + +Gui::GuiNativeEvent::GuiNativeEvent(Gui::GUIApplicationNativeEventAware *app) +: QObject(app) +{ + mainApp = app; +} + +Gui::GuiNativeEvent::~GuiNativeEvent() +{ + if (spnav_close()) + Base::Console().Log("Couldn't disconnect from spacenav daemon\n"); + else + Base::Console().Log("Disconnected from spacenav daemon\n"); +} + +void Gui::GuiNativeEvent::initSpaceball(QMainWindow *window) +{ + if (spnav_x11_open(QX11Info::display(), window->winId()) == -1) { + Base::Console().Log("Couldn't connect to spacenav daemon\n"); + } else { + Base::Console().Log("Connected to spacenav daemon\n"); + mainApp->setSpaceballPresent(true); + + #if QT_VERSION >= 0x050000 + static auto evFilter( [](void *msg, long *result){ + Q_UNUSED(result); + auto inst(dynamic_cast(QApplication::instance())); + if (inst) { + return inst->nativeEvent->xcbEventFilter(static_cast(msg)); + } else { + return false; + } + } ); + mainApp->installNativeEventFilter(new Gui::RawInputEventFilter(evFilter)); + #endif // #if QT_VERSION >= 0x050000 + } +} + +#if QT_VERSION >= 0x050000 + +bool Gui::GuiNativeEvent::xcbEventFilter(const xcb_client_message_event_t *xcb_ev) +{ + 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() + 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(&xev), &navEvent)) { + return false; + } + } else { + return false; + } + // navEvent is now initialised + + switch (navEvent.type) { + case SPNAV_EVENT_MOTION: + { + motionDataArray[0] = -navEvent.motion.x; + motionDataArray[1] = -navEvent.motion.z; + motionDataArray[2] = -navEvent.motion.y; + motionDataArray[3] = -navEvent.motion.rx; + motionDataArray[4] = -navEvent.motion.rz; + motionDataArray[5] = -navEvent.motion.ry; + + mainApp->postMotionEvent(&motionDataArray[0]); + 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); + } + mainApp->postButtonEvent(navEvent.button.bnum, navEvent.button.press); + return true; + } + default: + Base::Console().Log("Unknown spaceball event\n"); + return true; + } // end switch (navEvent.type) { +} + +#else // if QT_VERSION >= 0x050000 + +bool Gui::GuiNativeEvent::x11EventFilter(XEvent *event) +{ + /* + First we check if we have a motion flush event: + - If there are unprocessed motion events we are in a flooding situation. + In that case we wait with generating a Spaceball event. + - A motion event counter of 0 indicates that FreeCAD is ready to process + the event. A Spaceball event, using the saved motion data, is posted. + */ + static Display* display = QX11Info::display(); + static Atom motion_flush_event = XInternAtom(display, "FCMotionFlushEvent", false); + static int nMotionEvents = 0; + + if (event->type == ClientMessage) + { + Atom message_type = event->xclient.message_type; + + if (message_type == motion_flush_event) + { + nMotionEvents--; + if (nMotionEvents == 0) + { + mainApp->postMotionEvent(&motionDataArray); + } + + return true; + } // XEvent: motion_flush_event + } // XEvent: ClientMessage + + /* + From here on we deal with spacenav events only: + - motion: The event data is saved and a self addressed flush event + is sent through the window system (XEvent). + In the case of an event flooding, the motion data is added up. + - button: A Spaceball event is posted (QInputEvent). + */ + spnav_event navEvent; + if (!spnav_x11_event(event, &navEvent)) + return false; + + if (navEvent.type == SPNAV_EVENT_MOTION) + { + /* + If the motion data of the preceding event has not been processed + through posting an Spaceball event (flooding situation), + the motion data provided by the incoming event is added to the saved data. + */ + int dx, dy, dz, drx, dry, drz; + + if (nMotionEvents == 0) + { + dx = 0; + dy = 0; + dz = 0; + drx = 0; + dry = 0; + drz = 0; + } + else + { + dx = motionDataArray[0]; + dy = motionDataArray[1]; + dz = motionDataArray[2]; + drx = motionDataArray[3]; + dry = motionDataArray[4]; + drz = motionDataArray[5]; + } + + motionDataArray[0] = -navEvent.motion.x; + motionDataArray[1] = -navEvent.motion.z; + motionDataArray[2] = -navEvent.motion.y; + motionDataArray[3] = -navEvent.motion.rx; + motionDataArray[4] = -navEvent.motion.rz; + motionDataArray[5] = -navEvent.motion.ry; + + motionDataArray[0] += dx; + motionDataArray[1] += dy; + motionDataArray[2] += dz; + motionDataArray[3] += drx; + motionDataArray[4] += dry; + motionDataArray[5] += drz; + + /* + Send a self addressed flush event through the window system. This will + trigger a Spaceball event if FreeCAD is ready to do so. + */ + nMotionEvents++; + XClientMessageEvent flushEvent; + + flushEvent.display = display; + flushEvent.window = event->xclient.window; + flushEvent.type = ClientMessage; + flushEvent.format = 8; + flushEvent.message_type = motion_flush_event; + + XSendEvent (display, flushEvent.window, False, 0, (XEvent*)&flushEvent); // siehe spnavd, False, 0 + + return true; + } + + if (navEvent.type == SPNAV_EVENT_BUTTON) + { + this->postButtonEvent(navEvent.button.bnum, navEvent.button.press); + return true; + } + + Base::Console().Log("Unknown spaceball event\n"); + return true; +} +#endif // if/else QT_VERSION >= 0x050000 diff --git a/src/Gui/3Dconnexion/GuiNativeEventLinuxX11.h b/src/Gui/3Dconnexion/GuiNativeEventLinuxX11.h new file mode 100644 index 0000000000..17bd177217 --- /dev/null +++ b/src/Gui/3Dconnexion/GuiNativeEventLinuxX11.h @@ -0,0 +1,32 @@ +#ifndef GUINATIVEEVENT_H +#define GUINATIVEEVENT_H + +#include + +#if QT_VERSION >= 0x050000 + #include + #include + #include +#endif + +class QMainWindow; +class GUIApplicationNativeEventAware; + +namespace Gui +{ + class GUIApplicationNativeEventAware; + + class GuiNativeEvent : public QObject + { +#include "GuiNativeEventCommon.h" + public: + #if QT_VERSION >= 0x050000 + bool xcbEventFilter(const xcb_client_message_event_t *message); + #else + bool x11EventFilter(XEvent *event); + #endif // if/else QT_VERSION >= 0x050000 + }; +} + +#endif //GUINATIVEEVENT_H + diff --git a/src/Gui/3Dconnexion/GuiNativeEventMac.cpp b/src/Gui/3Dconnexion/GuiNativeEventMac.cpp index 7f18b7c797..0ba8528274 100644 --- a/src/Gui/3Dconnexion/GuiNativeEventMac.cpp +++ b/src/Gui/3Dconnexion/GuiNativeEventMac.cpp @@ -46,25 +46,17 @@ uint32_t Gui::GUIApplicationNativeEventAware::lastButtons = 0; //printf("msg->client: %d, tdxClientID: %d\n", msg->client, tdxClientID); if (msg->client == tdxClientID) { - Gui::GUIApplicationNativeEventAware* qapp = static_cast(Gui::GUIApplicationNativeEventAware::instance()); - if (!qapp) return; switch (msg->command) { case kConnexionCmdHandleAxis: { - //printf("TX: %d\n", msg->axis[0]); - //printf("TY: %d\n", msg->axis[1]); - //printf("TZ: %d\n", msg->axis[2]); - //printf("RX: %d\n", msg->axis[3]); - //printf("RY: %d\n", msg->axis[4]); - //printf("RZ: %d\n", msg->axis[5]); - qapp->motionDataArray[0] = msg->axis[0]; - qapp->motionDataArray[1] = msg->axis[1]; - qapp->motionDataArray[2] = msg->axis[2]; - qapp->motionDataArray[3] = msg->axis[3]; - qapp->motionDataArray[4] = msg->axis[4]; - qapp->motionDataArray[5] = msg->axis[5]; - qapp->Move3d(); + motionDataArray[0] = -msg->axis[0]; + motionDataArray[1] = msg->axis[1]; + motionDataArray[2] = msg->axis[2]; + motionDataArray[3] = -msg->axis[3]; + motionDataArray[4] = msg->axis[4]; + motionDataArray[5] = msg->axis[5]; + mainApp->postMotionEvent(&motionDataArray[0]) break; } @@ -78,13 +70,13 @@ uint32_t Gui::GUIApplicationNativeEventAware::lastButtons = 0; for (uint8_t bt = 0; bt < 32; bt++) { if (pressedButtons & 1) - qapp->Button3d(true, bt); + mainApp->postButtonEvent(bt, 1); pressedButtons = pressedButtons>>1; } for (uint8_t bt = 0; bt < 32; bt++) { if (releasedButtons & 1) - qapp->Button3d(false, bt); + mainApp->postButtonEvent(bt, 0); releasedButtons = releasedButtons>>1; } lastButtons = msg->buttons; @@ -160,53 +152,3 @@ void Gui::GuiNativeEvent::initSpaceball(QMainWindow *window) spaceballPresent = true; } -/*! - Called with the processed motion data when a 3D mouse event is received - - The default implementation emits a Move3d signal with the motion data -*/ -void Gui::GUIApplicationNativeEventAware::Move3d() -{ - QWidget *currentWidget = this->focusWidget(); - if (!currentWidget) - return; - //currentWidget = mainWindow; - - if (!setOSIndependentMotionData()) return; - importSettings(); - - Spaceball::MotionEvent *motionEvent = new Spaceball::MotionEvent(); - - motionEvent->setTranslations(motionDataArray[0], motionDataArray[1], motionDataArray[2]); - motionEvent->setRotations(motionDataArray[3], motionDataArray[4], motionDataArray[5]); - - this->postEvent(currentWidget, motionEvent); -} - -/*! - Called when a 3D mouse key is pressed or released - - The default implementation emits a On3dmouseKeyDown signal with the key code. -*/ -void Gui::GUIApplicationNativeEventAware::Button3d(bool buttonDown, int buttonNumber) -{ - QWidget *currentWidget = this->focusWidget(); - if (!currentWidget) - return; - // currentWidget = mainWindow; - - Spaceball::ButtonEvent *buttonEvent = new Spaceball::ButtonEvent(); - buttonEvent->setButtonNumber(buttonNumber); - if (buttonDown) - { - //printf("Button %d pressed\n", buttonNumber); - buttonEvent->setButtonStatus(Spaceball::BUTTON_PRESSED); - } - else - { - //printf("Button %d released\n", buttonNumber); - buttonEvent->setButtonStatus(Spaceball::BUTTON_RELEASED); - } - this->postEvent(currentWidget, buttonEvent); -} - diff --git a/src/Gui/3Dconnexion/GuiNativeEventMac.h b/src/Gui/3Dconnexion/GuiNativeEventMac.h index 2ecb833300..4710e4f36c 100644 --- a/src/Gui/3Dconnexion/GuiNativeEventMac.h +++ b/src/Gui/3Dconnexion/GuiNativeEventMac.h @@ -25,24 +25,13 @@ namespace Gui class GuiNativeEvent : public QObject { - public: - GuiNativeEvent(GUIApplicationNativeEventAware *app); - ~GuiNativeEvent(); - void initSpaceball(QMainWindow *window); + #include "GuiNativeEventCommon.h" private: - GuiNativeEvent(); - GuiNativeEvent(GuiNativeEvent*); - bool spaceballPresent; - GUIApplicationNativeEventAware *mainApp; - static UInt16 tdxClientID; /* ID assigned by the driver */ static uint32_t lastButtons; - static void tdx_drv_handler( io_connect_t connection, natural_t messageType, void *messageArgument ); - void Move3d(); - void Button3d(bool buttonDown, int buttonNumber); }; } diff --git a/src/Gui/3Dconnexion/GuiNativeEventWin32.h b/src/Gui/3Dconnexion/GuiNativeEventWin32.h index 8ca67ea82a..9c5229e7f6 100644 --- a/src/Gui/3Dconnexion/GuiNativeEventWin32.h +++ b/src/Gui/3Dconnexion/GuiNativeEventWin32.h @@ -18,19 +18,7 @@ class GUIApplicationNativeEventAware; namespace Gui { - class GUIApplicationNativeEventAware; - - class GuiNativeEvent : public QObject - { - public: - GuiNativeEvent(GUIApplicationNativeEventAware *app); - ~GuiNativeEvent(); - void initSpaceball(QMainWindow *window); - private: - GuiNativeEvent(); - GuiNativeEvent(GuiNativeEvent*); - GUIApplicationNativeEventAware *mainApp; - +#if QT_VERSION >= 0x050000 class RawInputEventFilter : public QAbstractNativeEventFilter { public: @@ -47,6 +35,19 @@ namespace Gui private: EventFilter eventFilter; }; +#endif // if QT_VERSION >= 0x050000 + class GUIApplicationNativeEventAware; + + class GuiNativeEvent : public QObject + { + public: + GuiNativeEvent(GUIApplicationNativeEventAware *app); + ~GuiNativeEvent(); + void initSpaceball(QMainWindow *window); + private: + GuiNativeEvent(); + GuiNativeEvent(GuiNativeEvent*); + GUIApplicationNativeEventAware *mainApp; public: static bool Is3dmouseAttached(); diff --git a/src/Gui/3Dconnexion/GuiRawInputEventFilter.h b/src/Gui/3Dconnexion/GuiRawInputEventFilter.h new file mode 100644 index 0000000000..8e4255dbe9 --- /dev/null +++ b/src/Gui/3Dconnexion/GuiRawInputEventFilter.h @@ -0,0 +1,24 @@ +#ifndef GUIRAWNATIVEINPUTEVENTFILTER_H +#define GUIRAWNATIVEINPUTEVENTFILTER_H + +namespace Gui +{ + class RawInputEventFilter : public QAbstractNativeEventFilter + { + public: + typedef bool (*EventFilter)(void *message, long *result); + RawInputEventFilter(EventFilter filter) : eventFilter(filter) { + } + virtual ~RawInputEventFilter() { + } + + virtual bool nativeEventFilter(const QByteArray & /*eventType*/, void *message, long *result) { + return eventFilter(message, result); + } + + private: + EventFilter eventFilter; + }; +} //namespace Gui + +#endif //GUIRAWNATIVEINPUTEVENTFILTER_H diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index c65acf3352..8286a47d18 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -106,6 +106,29 @@ else() endif() IF(SPNAV_FOUND) + if(SPNAV_USE_X11) + add_definitions(-DSPNAV_USE_X11) + if (BUILD_QT5 AND UNIX AND NOT APPLE) + find_package(Qt5X11Extras REQUIRED) + include_directories(${Qt5X11Extras_INCLUDE_DIRS}) + list(APPEND FreeCADGui_LIBS ${Qt5X11Extras_LIBRARIES}) + endif() + find_package(X11 QUIET) + if (X11_FOUND) + list(APPEND FreeCADGui_LIBS + ${X11_X11_LIB} + ) + endif(X11_FOUND) + SET(FreeCADGui_SDK_SRCS + 3Dconnexion/GuiNativeEventLinuxX11.cpp + ) + else(SPNAV_USE_X11) + SET(FreeCADGui_SDK_SRCS + 3Dconnexion/GuiNativeEventLinux.cpp + ) + endif(SPNAV_USE_X11) + SOURCE_GROUP("3D connexion SDK" FILES ${FreeCADGui_SDK_SRCS}) + add_definitions(-DSPNAV_FOUND) include_directories( ${SPNAV_INCLUDE_DIR} @@ -196,13 +219,6 @@ SET(FreeCADGui_SDK_SRCS SOURCE_GROUP("3D connexion SDK" FILES ${FreeCADGui_SDK_SRCS}) endif(FREECAD_USE_3DCONNEXION AND APPLE) -if(UNIX AND NOT APPLE) -SET(FreeCADGui_SDK_SRCS - 3Dconnexion/GuiNativeEventLinux.cpp -) -SOURCE_GROUP("3D connexion SDK" FILES ${FreeCADGui_SDK_SRCS}) -endif(UNIX AND NOT APPLE) - set(Gui_MOC_HDRS Action.h ActionFunction.h diff --git a/src/Gui/GuiApplicationNativeEventAware.cpp b/src/Gui/GuiApplicationNativeEventAware.cpp index 7e830b5397..a03ae7793c 100644 --- a/src/Gui/GuiApplicationNativeEventAware.cpp +++ b/src/Gui/GuiApplicationNativeEventAware.cpp @@ -30,32 +30,13 @@ #include "GuiApplicationNativeEventAware.h" #include "SpaceballEvent.h" #include "Application.h" -#if defined(Q_OS_LINUX) - - #if QT_VERSION >= 0x050000 - #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 - #endif // #if QT_VERSION >= 0x050000 - -#endif // if defined(Q_OS_LINUX) - Gui::GUIApplicationNativeEventAware::GUIApplicationNativeEventAware(int &argc, char *argv[]) : QApplication (argc, argv) { +#if defined(_USE_3DCONNEXION_SDK) || defined(SPNAV_FOUND) nativeEvent = new Gui::GuiNativeEvent(this); +#endif } Gui::GUIApplicationNativeEventAware::~GUIApplicationNativeEventAware() @@ -64,7 +45,9 @@ Gui::GUIApplicationNativeEventAware::~GUIApplicationNativeEventAware() void Gui::GUIApplicationNativeEventAware::initSpaceball(QMainWindow *window) { +#if defined(_USE_3DCONNEXION_SDK) || defined(SPNAV_FOUND) nativeEvent->initSpaceball(window); +#endif Spaceball::MotionEvent::MotionEventType = QEvent::registerEventType(); Spaceball::ButtonEvent::ButtonEventType = QEvent::registerEventType(); } @@ -105,6 +88,39 @@ bool Gui::GUIApplicationNativeEventAware::processSpaceballEvent(QObject *object, return true; } +void Gui::GUIApplicationNativeEventAware::postMotionEvent(int *const motionDataArray) +{ + auto currentWidget(focusWidget()); + if (!currentWidget) { + return; + } + importSettings(motionDataArray); + + Spaceball::MotionEvent *motionEvent = new Spaceball::MotionEvent(); + motionEvent->setTranslations(motionDataArray[0], motionDataArray[1], motionDataArray[2]); + motionEvent->setRotations(motionDataArray[3], motionDataArray[4], motionDataArray[5]); + this->postEvent(currentWidget, motionEvent); +} + +void Gui::GUIApplicationNativeEventAware::postButtonEvent(int buttonNumber, int buttonPress) +{ + auto currentWidget(focusWidget()); + if (!currentWidget) { + return; + } + + Spaceball::ButtonEvent *buttonEvent = new Spaceball::ButtonEvent(); + buttonEvent->setButtonNumber(buttonNumber); + if (buttonPress) + { + buttonEvent->setButtonStatus(Spaceball::BUTTON_PRESSED); + } + else + { + buttonEvent->setButtonStatus(Spaceball::BUTTON_RELEASED); + } + this->postEvent(currentWidget, buttonEvent); +} float Gui::GUIApplicationNativeEventAware::convertPrefToSensitivity(int value) { @@ -129,7 +145,7 @@ float Gui::GUIApplicationNativeEventAware::convertPrefToSensitivity(int value) // motionDataArray[5] - Spin mouse - rotate around "Zoom" axis on screen -bool Gui::GUIApplicationNativeEventAware::setOSIndependentMotionData() +/*bool Gui::GUIApplicationNativeEventAware::setOSIndependentMotionData() { #ifdef SPNAV_FOUND int temp; @@ -150,9 +166,9 @@ bool Gui::GUIApplicationNativeEventAware::setOSIndependentMotionData() return false; #endif return true; -} +}*/ -void Gui::GUIApplicationNativeEventAware::importSettings() +void Gui::GUIApplicationNativeEventAware::importSettings(int *const motionDataArray) { ParameterGrp::handle group = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->GetGroup("Spaceball")->GetGroup("Motion"); diff --git a/src/Gui/GuiApplicationNativeEventAware.h b/src/Gui/GuiApplicationNativeEventAware.h index 4dab2bf11c..365ad8e447 100644 --- a/src/Gui/GuiApplicationNativeEventAware.h +++ b/src/Gui/GuiApplicationNativeEventAware.h @@ -29,13 +29,19 @@ class QMainWindow; +#if defined(_USE_3DCONNEXION_SDK) || defined(SPNAV_FOUND) #if defined(Q_OS_LINUX) -#include "3Dconnexion/GuiNativeEventLinux.h" + #if defined(SPNAV_USE_X11) + #include "3Dconnexion/GuiNativeEventLinuxX11.h" + #else + #include "3Dconnexion/GuiNativeEventLinux.h" + #endif #elif defined(Q_OS_WIN) -#include "3Dconnexion/GuiNativeEventWin32.h" + #include "3Dconnexion/GuiNativeEventWin32.h" #elif defined(Q_OS_MACX) -#include "3Dconnexion/GuiNativeEventMac.h" + #include "3Dconnexion/GuiNativeEventMac.h" #endif // Platform switch +#endif // Spacemice namespace Gui { @@ -49,13 +55,16 @@ namespace Gui bool isSpaceballPresent() const {return spaceballPresent;} void setSpaceballPresent(bool present) {spaceballPresent = present;} bool processSpaceballEvent(QObject *object, QEvent *event); + void postMotionEvent(int *const motionDataArray); + void postButtonEvent(int buttonNumber, int buttonPress); private: bool spaceballPresent; - int motionDataArray[6]; - bool setOSIndependentMotionData(); - void importSettings(); + void importSettings(int *const motionDataArray); float convertPrefToSensitivity(int value); + #if defined(_USE_3DCONNEXION_SDK) || defined(SPNAV_FOUND) GuiNativeEvent *nativeEvent; + friend void GuiNativeEvent::initSpaceball(QMainWindow *window); + #endif }; // end class GUIApplicationNativeEventAware } // end namespace Gui