1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SALOME VTKViewer : build VTK viewer into Salome desktop
24 // File : SVTK_SpaceMouse.cxx
25 // Author : Alexander SLADKOV
34 #include <X11/Xutil.h>
35 #include <X11/Xatom.h>
36 #include <X11/keysym.h>
39 #include "SVTK_SpaceMouse.h"
41 SVTK_SpaceMouse* SVTK_SpaceMouse::myInstance = 0;
44 \return shared instance of object (creates if there is no one)
46 SVTK_SpaceMouse* SVTK_SpaceMouse::getInstance()
49 myInstance = new SVTK_SpaceMouse();
56 SVTK_SpaceMouse::SVTK_SpaceMouse()
69 int SVTK_SpaceMouse::initialize( Display *display, Window window )
71 XMotionEvent = XInternAtom( display, "MotionEvent", 1 );
72 XButtonPressEvent = XInternAtom( display, "ButtonPressEvent", 1 );
73 XButtonReleaseEvent = XInternAtom( display, "ButtonReleaseEvent", 1 );
74 XCommandEvent = XInternAtom( display, "CommandEvent", 1 );
76 spaceMouseOn = (XMotionEvent != 0) &&
77 (XButtonPressEvent != 0) &&
78 (XButtonReleaseEvent != 0) &&
83 spaceMouseOn = setWindow( display, window );
90 static int errorCallback( Display *display, XErrorEvent *Error )
93 if ( Error->error_code != BadWindow ) {
94 XGetErrorText( display,Error->error_code,msg,sizeof( msg ) );
95 fprintf( stderr, "SpaceMouse reported error = %s. Exit ... \n", msg );
103 int SVTK_SpaceMouse::setWindow( Display *display, Window window )
105 XTextProperty winName;
109 unsigned long NItems, BytesReturn;
110 unsigned char *PropReturn;
113 int (*errorHandler)(Display *,XErrorEvent *);
116 errorHandler = XSetErrorHandler( errorCallback );
118 root = RootWindow( display, DefaultScreen(display) );
121 XGetWindowProperty( display, root, XCommandEvent, 0,1, 0,
122 AnyPropertyType, &type, &format, &NItems,
123 &BytesReturn, &PropReturn );
126 if ( PropReturn != NULL ) {
127 win = *(Window *) PropReturn;
133 if ( XGetWMName( display, win, &winName ) == 0 )
136 if ( strcmp( (char *) "Magellan Window", (char *) winName.value) != 0 )
139 xEvent.type = ClientMessage;
140 xEvent.xclient.format = 16;
141 xEvent.xclient.send_event = 0;
142 xEvent.xclient.display = display;
143 xEvent.xclient.window = win;
144 xEvent.xclient.message_type = XCommandEvent;
146 xEvent.xclient.data.s[0] = (short) ((window>>16)&0x0000FFFF);
147 xEvent.xclient.data.s[1] = (short) (window&0x0000FFFF);
148 xEvent.xclient.data.s[2] = 27695;
150 if ( XSendEvent( display, win, 0, 0x0000, &xEvent ) == 0 )
155 XSetErrorHandler( errorHandler );
162 int SVTK_SpaceMouse::close(Display *display)
164 initialize( display, (Window)InputFocus );
173 int SVTK_SpaceMouse::translateEvent( Display* display, XEvent* xEvent, MoveEvent* spaceMouseEvent,
174 double scale, double rScale )
179 if ( xEvent->type == ClientMessage ) {
180 if ( xEvent->xclient.message_type == XMotionEvent ) {
181 spaceMouseEvent->type = SpaceMouseMove;
182 spaceMouseEvent->data[ x ] =
183 xEvent->xclient.data.s[2] * scale;
184 spaceMouseEvent->data[ y ] =
185 xEvent->xclient.data.s[3] * scale;
186 spaceMouseEvent->data[ z ] =
187 xEvent->xclient.data.s[4] * scale;
188 spaceMouseEvent->data[ a ] =
189 xEvent->xclient.data.s[5] * rScale;
190 spaceMouseEvent->data[ b ] =
191 xEvent->xclient.data.s[6] * rScale;
192 spaceMouseEvent->data[ c ] =
193 xEvent->xclient.data.s[7] * rScale;
194 spaceMouseEvent->period = xEvent->xclient.data.s[8];
197 else if ( xEvent->xclient.message_type == XButtonPressEvent ) {
198 spaceMouseEvent->type = SpaceButtonPress;
199 spaceMouseEvent->button = xEvent->xclient.data.s[2];
202 else if ( xEvent->xclient.message_type == XButtonReleaseEvent ) {
203 spaceMouseEvent->type = SpaceButtonRelease;
204 spaceMouseEvent->button = xEvent->xclient.data.s[2];