// Put Qt includes before the X11 includes which #define the symbol None
// (see SVTK_SpaceMouse.h) to avoid the compilation error.
#ifndef WIN32
-# include <QX11Info>
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+#include <xcb/xcb.h>
+#endif
+#include <QX11Info>
#endif
#include <QMouseEvent>
::~QVTK_RenderWindowInteractor()
{
#ifndef WIN32
- SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance();
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance();
if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
aSpaceMouse->close( QX11Info::display() );
+#else
+ SVTK_SpaceMouseXCB* aSpaceMouse = SVTK_SpaceMouseXCB::getInstance();
+ if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
+ aSpaceMouse->close( QX11Info::connection() );
+#endif
#endif
}
#ifndef WIN32
// register set space mouse events receiver
- SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance();
-
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance();
if ( aSpaceMouse )
{
if ( !aSpaceMouse->isSpaceMouseOn() )
else
aSpaceMouse->setWindow( QX11Info::display(), winId() );
}
+#else
+ SVTK_SpaceMouseXCB* aSpaceMouse = SVTK_SpaceMouseXCB::getInstance();
+ if ( aSpaceMouse )
+ {
+ if ( !aSpaceMouse->isSpaceMouseOn() )
+ // initialize 3D space mouse driver
+ aSpaceMouse->initialize( QX11Info::connection(), winId() );
+ else
+ aSpaceMouse->setWindow( QX11Info::connection(), winId() );
+ }
+#endif
#endif
}
QWidget::focusOutEvent( event );
#ifndef WIN32
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// unregister set space mouse events receiver
- SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance();
+ SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance();
if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
aSpaceMouse->setWindow( QX11Info::display(), 0 );
+#else
+ SVTK_SpaceMouseXCB* aSpaceMouse = SVTK_SpaceMouseXCB::getInstance();
+ if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
+ aSpaceMouse->setWindow( QX11Info::connection(), 0 );
+#endif
#endif
}
::x11Event( XEvent *xEvent )
{
// handle 3d space mouse events
- if ( SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance() )
+ if ( SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance() )
{
if ( aSpaceMouse->isSpaceMouseOn() && xEvent->type == ClientMessage )
{
}
#endif
+#else
+bool QVTK_RenderWindowInteractor
+::nativeEvent(const QByteArray& eventType, void* message, long* result)
+{
+ if ( eventType == "xcb_generic_event_t" )
+ {
+ xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message);
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ if ( SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance() )
+#else
+ if ( SVTK_SpaceMouseXCB* aSpaceMouse = SVTK_SpaceMouseXCB::getInstance() )
+#endif
+ {
+ if ( aSpaceMouse->isSpaceMouseOn() && ev->response_type == XCB_CLIENT_MESSAGE )
+ {
+ SVTK_SpaceMouse::MoveEvent anEvent;
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ int type = aSpaceMouse->translateEvent( QX11Info::display(), xEvent, &anEvent, 1.0, 1.0 );
+#else
+ int type = aSpaceMouse->translateEvent( QX11Info::connection(), (xcb_client_message_event_t*)ev, &anEvent, 1.0, 1.0 );
+#endif
+ switch ( type )
+ {
+ case SVTK_SpaceMouse::SpaceMouseMove:
+ GetDevice()->InvokeEvent( SVTK::SpaceMouseMoveEvent, anEvent.data );
+ break;
+ case SVTK_SpaceMouse::SpaceButtonPress:
+ GetDevice()->InvokeEvent( SVTK::SpaceMouseButtonEvent, &anEvent.button );
+ break;
+ case SVTK_SpaceMouse::SpaceButtonRelease:
+ break;
+ }
+ return true; // stop handling the event
+ }
+ }
+ }
+
+ return QWidget::nativeEvent( eventType, message, result );
+}
#endif
/*!
Constructor
#include <math.h>
#include <stdio.h>
+#include <QtGlobal>
+
#ifndef WIN32
#include <X11/X.h>
-#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+#include <X11/Xlib.h>
+#else
+#include <xcb/xcb.h>
+#include <xcb/xcb_event.h>
+#endif
#endif
#include "SVTK_SpaceMouse.h"
-SVTK_SpaceMouse* SVTK_SpaceMouse::myInstance = 0;
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+SVTK_SpaceMouseX* SVTK_SpaceMouseX::myInstance = 0;
+#else
+SVTK_SpaceMouseXCB* SVTK_SpaceMouseXCB::myInstance = 0;
+#endif
/*!
- \return shared instance of object (creates if there is no one)
+ Constructor
*/
-SVTK_SpaceMouse* SVTK_SpaceMouse::getInstance()
+SVTK_SpaceMouse::SVTK_SpaceMouse()
{
- if ( !myInstance )
- myInstance = new SVTK_SpaceMouse();
- return myInstance;
+ spaceMouseOn = 0;
}
-
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
/*!
Constructor
*/
-SVTK_SpaceMouse::SVTK_SpaceMouse()
+SVTK_SpaceMouseX::SVTK_SpaceMouseX()
+: SVTK_SpaceMouse()
{
#ifndef WIN32
win = InputFocus;
#endif
- spaceMouseOn = 0;
}
-#ifndef WIN32
-
/*!
- Initialization
+ \return shared instance of object (creates if there is no one)
*/
-int SVTK_SpaceMouse::initialize( Display *display, Window window )
+SVTK_SpaceMouseX* SVTK_SpaceMouseX::getInstance()
{
- XMotionEvent = XInternAtom( display, "MotionEvent", 1 );
- XButtonPressEvent = XInternAtom( display, "ButtonPressEvent", 1 );
- XButtonReleaseEvent = XInternAtom( display, "ButtonReleaseEvent", 1 );
- XCommandEvent = XInternAtom( display, "CommandEvent", 1 );
-
- spaceMouseOn = (XMotionEvent != 0) &&
- (XButtonPressEvent != 0) &&
- (XButtonReleaseEvent != 0) &&
- (XCommandEvent != 0);
- if ( !spaceMouseOn )
- return 0;
-
- spaceMouseOn = setWindow( display, window );
- if ( !spaceMouseOn )
- return 0;
-
- return spaceMouseOn;
+ if ( !myInstance )
+ myInstance = new SVTK_SpaceMouseX();
+ return myInstance;
}
+#ifndef WIN32
+
static int errorCallback( Display *display, XErrorEvent *Error )
{
char msg[ 128 ];
return 0;
}
+/*!
+ Initialization
+*/
+int SVTK_SpaceMouseX::initialize( Display *display, Window window )
+{
+ XMotionEvent = XInternAtom( display, "MotionEvent", 1 );
+ XButtonPressEvent = XInternAtom( display, "ButtonPressEvent", 1 );
+ XButtonReleaseEvent = XInternAtom( display, "ButtonReleaseEvent", 1 );
+ XCommandEvent = XInternAtom( display, "CommandEvent", 1 );
+
+ spaceMouseOn = (XMotionEvent != 0) &&
+ (XButtonPressEvent != 0) &&
+ (XButtonReleaseEvent != 0) &&
+ (XCommandEvent != 0);
+ if ( !spaceMouseOn )
+ return 0;
+
+ spaceMouseOn = setWindow( display, window );
+ if ( !spaceMouseOn )
+ return 0;
+
+ return spaceMouseOn;
+}
+
/*!
Initialize by window
*/
-int SVTK_SpaceMouse::setWindow( Display *display, Window window )
+int SVTK_SpaceMouseX::setWindow( Display *display, Window window )
{
XTextProperty winName;
XEvent xEvent;
unsigned long NItems, BytesReturn;
unsigned char *PropReturn;
Window root;
- int result;
int (*errorHandler)(Display *,XErrorEvent *);
- result = 1;
errorHandler = XSetErrorHandler( errorCallback );
root = RootWindow( display, DefaultScreen(display) );
XFree( PropReturn );
}
else
- return result = 0;
+ return 0;
if ( XGetWMName( display, win, &winName ) == 0 )
- return result = 0;
+ return 0;
if ( strcmp( (char *) "Magellan Window", (char *) winName.value) != 0 )
- return result = 0;
+ return 0;
xEvent.type = ClientMessage;
xEvent.xclient.format = 16;
xEvent.xclient.data.s[2] = 27695;
if ( XSendEvent( display, win, 0, 0x0000, &xEvent ) == 0 )
- return result = 0;
+ return 0;
XFlush( display );
XSetErrorHandler( errorHandler );
- return result;
+ return 1;
}
/*!
Close
*/
-int SVTK_SpaceMouse::close(Display *display)
+int SVTK_SpaceMouseX::close(Display *display)
{
initialize( display, (Window)InputFocus );
spaceMouseOn = 0;
/*!
Custom event handler
*/
-int SVTK_SpaceMouse::translateEvent( Display* display, XEvent* xEvent, MoveEvent* spaceMouseEvent,
+int SVTK_SpaceMouseX::translateEvent( Display* display, XEvent* xEvent, MoveEvent* spaceMouseEvent,
double scale, double rScale )
{
if ( !spaceMouseOn )
}
return (!display);
}
+#endif
+#else
+
+/*!
+ Constructor
+*/
+SVTK_SpaceMouseXCB::SVTK_SpaceMouseXCB()
+: SVTK_SpaceMouse()
+{
+#ifndef WIN32
+ win = InputFocus;
+#endif
+}
+
+/*!
+ \return shared instance of object (creates if there is no one)
+*/
+SVTK_SpaceMouseXCB* SVTK_SpaceMouseXCB::getInstance()
+{
+ if ( !myInstance )
+ myInstance = new SVTK_SpaceMouseXCB();
+ return myInstance;
+}
+/*!
+ Initialization
+*/
+#ifndef WIN32
+int SVTK_SpaceMouseXCB::initialize( xcb_connection_t *connection, xcb_window_t window )
+{
+ // make request
+ xcb_intern_atom_cookie_t cookie = xcb_intern_atom (connection, 0, strlen("XCB_MOTION_NOTIFY"), "XCB_MOTION_NOTIFY" );
+ // get response
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply ( connection, cookie, NULL );
+ XCBMotionEvent = reply->atom;
+ cookie = xcb_intern_atom (connection, 0, strlen("XCB_BUTTON_PRESS"), "XCB_BUTTON_PRESS" );
+ reply = xcb_intern_atom_reply ( connection, cookie, NULL );
+ XCBButtonPressEvent = reply->atom;
+ cookie = xcb_intern_atom (connection, 0, strlen("XCB_BUTTON_RELEASE"), "XCB_BUTTON_RELEASE" );
+ reply = xcb_intern_atom_reply ( connection, cookie, NULL );
+ XCBButtonReleaseEvent = reply->atom;
+
+ free (reply);
+
+ spaceMouseOn = (XCBMotionEvent != 0) &&
+ (XCBButtonPressEvent != 0) &&
+ (XCBButtonReleaseEvent != 0);
+ if ( !spaceMouseOn )
+ return 0;
+
+ spaceMouseOn = setWindow( connection, window );
+ if ( !spaceMouseOn )
+ return 0;
+
+ return spaceMouseOn;
+}
+
+/*!
+ Initialize by window
+*/
+int SVTK_SpaceMouseXCB::setWindow( xcb_connection_t *connection, xcb_window_t window )
+{
+ xcb_client_message_event_t xcbEvent;
+ xcb_window_t root_window;
+ xcb_screen_t* screen;
+ xcb_generic_error_t* error;
+ xcb_void_cookie_t cookie;
+
+ screen = xcb_setup_roots_iterator ( xcb_get_setup ( connection ) ).data;
+
+ /* root window */
+ if ( screen )
+ root_window = screen->root;
+
+ xcb_get_property_cookie_t prop_cookie;
+ xcb_get_property_reply_t* prop_reply;
+ prop_cookie = xcb_get_property (connection, 0, root_window, XCB_ATOM_WM_NAME,
+ XCB_ATOM_STRING, 0, 0);
+
+ win = InputFocus;
+
+ if (( prop_reply = xcb_get_property_reply ( connection, prop_cookie, NULL ) ))
+ {
+ int len = xcb_get_property_value_length( prop_reply );
+ if ( len == 0 )
+ {
+ free(prop_reply);
+ return 0;
+ }
+
+ if ( strcmp( (char *) "Magellan Window", (char *) xcb_get_property_value( prop_reply ) ) != 0 )
+ return 0;
+
+ win = * ( xcb_window_t * ) xcb_get_property_value( prop_reply );
+ }
+
+ free(prop_reply);
+
+ xcbEvent.response_type = XCB_CLIENT_MESSAGE;
+ xcbEvent.format = 16;
+ xcbEvent.sequence = 0;
+ xcbEvent.window = win;
+
+ xcbEvent.data.data16[0] = (short) ((window>>16)&0x0000FFFF);
+ xcbEvent.data.data16[1] = (short) (window&0x0000FFFF);
+ xcbEvent.data.data16[2] = 27695;
+
+ cookie = xcb_send_event( connection, 0, win, 0x0000, (const char *)&xcbEvent );
+
+ if (( error = xcb_request_check( connection, cookie )))
+ {
+ fprintf ( stderr, "SpaceMouse reported error = %s. Exit ... \n", xcb_event_get_label( error->response_type ) );
+ return 0;
+ }
+
+ xcb_flush(connection);
+
+ return 1;
+}
+
+/*!
+ Close
+*/
+int SVTK_SpaceMouseXCB::close(xcb_connection_t *connection)
+{
+ initialize( connection, (xcb_window_t)InputFocus );
+ spaceMouseOn = 0;
+
+ return 1;
+}
+
+/*!
+ Custom event handler
+*/
+int SVTK_SpaceMouseXCB::translateEvent( xcb_connection_t* connection, xcb_client_message_event_t* xcbEvent, MoveEvent* spaceMouseEvent,
+ double scale, double rScale )
+{
+ if ( !spaceMouseOn )
+ return 0;
+
+ if ( xcbEvent->response_type == XCB_CLIENT_MESSAGE ) {
+ if ( xcbEvent->type == XCBMotionEvent ) {
+ spaceMouseEvent->type = SpaceMouseMove;
+ spaceMouseEvent->data[ x ] =
+ xcbEvent->data.data16[2] * scale;
+ spaceMouseEvent->data[ y ] =
+ xcbEvent->data.data16[3] * scale;
+ spaceMouseEvent->data[ z ] =
+ xcbEvent->data.data16[4] * scale;
+ spaceMouseEvent->data[ a ] =
+ xcbEvent->data.data16[5] * rScale;
+ spaceMouseEvent->data[ b ] =
+ xcbEvent->data.data16[6] * rScale;
+ spaceMouseEvent->data[ c ] =
+ xcbEvent->data.data16[7] * rScale;
+ spaceMouseEvent->period = xcbEvent->data.data16[8];
+ return 1;
+ }
+ else if ( xcbEvent->type == XCBButtonPressEvent ) {
+ spaceMouseEvent->type = SpaceButtonPress;
+ spaceMouseEvent->button = xcbEvent->data.data16[2];
+ return 2;
+ }
+ else if ( xcbEvent->type == XCBButtonReleaseEvent ) {
+ spaceMouseEvent->type = SpaceButtonRelease;
+ spaceMouseEvent->button = xcbEvent->data.data16[2];
+ return 3;
+ }
+ }
+ return (!connection);
+}
+#endif
#endif
#ifndef SVTK_SpaceMouse_h
#define SVTK_SpaceMouse_h
+#include <QtGlobal>
+
#ifndef WIN32
extern "C"
{
#include <X11/X.h>
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include <X11/Xlib.h>
+#else
+#include <xcb/xcb.h>
+#endif
}
+
#endif
class SVTK_SpaceMouse
{
public:
- // access to SpaceMouse utility class
- static SVTK_SpaceMouse* getInstance();
-
enum MoveData { x, y, z, a, b, c };
enum EventType { SpaceMouseMove = 1, SpaceButtonPress, SpaceButtonRelease };
bool isSpaceMouseOn() const { return spaceMouseOn != 0; }
+ SVTK_SpaceMouse();
+
+ protected:
+
+ int spaceMouseOn;
+};
+
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+
+class SVTK_SpaceMouseX: public SVTK_SpaceMouse
+{
+
+public:
+ SVTK_SpaceMouseX();
+
+ // access to SpaceMouse utility class
+ static SVTK_SpaceMouseX* getInstance();
+
#ifndef WIN32
int initialize ( Display*, Window );
int setWindow ( Display*, Window );
int translateEvent ( Display*, XEvent*, MoveEvent*, double, double );
int close ( Display* );
-#endif
- private:
- SVTK_SpaceMouse();
- static SVTK_SpaceMouse* myInstance;
-
-#ifndef WIN32
+private:
Atom XMotionEvent;
Atom XButtonPressEvent;
Atom XButtonReleaseEvent;
Atom XCommandEvent;
-
Window win;
#endif
- int spaceMouseOn;
+
+ static SVTK_SpaceMouseX* myInstance;
+
};
+#else
+class SVTK_SpaceMouseXCB: public SVTK_SpaceMouse
+{
+
+public:
+ SVTK_SpaceMouseXCB();
+ // access to SpaceMouse utility class
+ static SVTK_SpaceMouseXCB* getInstance();
+
+#ifndef WIN32
+ int initialize ( xcb_connection_t*, xcb_window_t );
+ int setWindow ( xcb_connection_t*, xcb_window_t );
+ int translateEvent ( xcb_connection_t*, xcb_client_message_event_t*, MoveEvent*, double, double );
+ int close ( xcb_connection_t* );
+
+private:
+ xcb_atom_t XCBMotionEvent;
+ xcb_atom_t XCBButtonPressEvent;
+ xcb_atom_t XCBButtonReleaseEvent;
+ xcb_window_t win;
+#endif
+
+ static SVTK_SpaceMouseXCB* myInstance;
+
+};
+#endif
#endif