1 // Copyright (C) 2007-2008 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.
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
22 // SALOME VTKViewer : build VTK viewer into Salome desktop
23 // File : SVTK_SpaceMouse.cxx
24 // Author : Alexander SLADKOV
35 #include <X11/Xutil.h>
36 #include <X11/Xatom.h>
37 #include <X11/keysym.h>
40 #include "SVTK_SpaceMouse.h"
42 SVTK_SpaceMouse* SVTK_SpaceMouse::myInstance = 0;
45 \return shared instance of object (creates if there is no one)
47 SVTK_SpaceMouse* SVTK_SpaceMouse::getInstance()
50 myInstance = new SVTK_SpaceMouse();
57 SVTK_SpaceMouse::SVTK_SpaceMouse()
70 int SVTK_SpaceMouse::initialize( Display *display, Window window )
72 XMotionEvent = XInternAtom( display, "MotionEvent", 1 );
73 XButtonPressEvent = XInternAtom( display, "ButtonPressEvent", 1 );
74 XButtonReleaseEvent = XInternAtom( display, "ButtonReleaseEvent", 1 );
75 XCommandEvent = XInternAtom( display, "CommandEvent", 1 );
77 spaceMouseOn = (XMotionEvent != 0) &&
78 (XButtonPressEvent != 0) &&
79 (XButtonReleaseEvent != 0) &&
84 spaceMouseOn = setWindow( display, window );
91 static int errorCallback( Display *display, XErrorEvent *Error )
94 if ( Error->error_code != BadWindow ) {
95 XGetErrorText( display,Error->error_code,msg,sizeof( msg ) );
96 fprintf( stderr, "SpaceMouse reported error = %s. Exit ... \n", msg );
104 int SVTK_SpaceMouse::setWindow( Display *display, Window window )
106 XTextProperty winName;
110 unsigned long NItems, BytesReturn;
111 unsigned char *PropReturn;
114 int (*errorHandler)(Display *,XErrorEvent *);
117 errorHandler = XSetErrorHandler( errorCallback );
119 root = RootWindow( display, DefaultScreen(display) );
122 XGetWindowProperty( display, root, XCommandEvent, 0,1, 0,
123 AnyPropertyType, &type, &format, &NItems,
124 &BytesReturn, &PropReturn );
127 if ( PropReturn != NULL ) {
128 win = *(Window *) PropReturn;
134 if ( XGetWMName( display, win, &winName ) == 0 )
137 if ( strcmp( (char *) "Magellan Window", (char *) winName.value) != 0 )
140 xEvent.type = ClientMessage;
141 xEvent.xclient.format = 16;
142 xEvent.xclient.send_event = 0;
143 xEvent.xclient.display = display;
144 xEvent.xclient.window = win;
145 xEvent.xclient.message_type = XCommandEvent;
147 xEvent.xclient.data.s[0] = (short) ((window>>16)&0x0000FFFF);
148 xEvent.xclient.data.s[1] = (short) (window&0x0000FFFF);
149 xEvent.xclient.data.s[2] = 27695;
151 if ( XSendEvent( display, win, 0, 0x0000, &xEvent ) == 0 )
156 XSetErrorHandler( errorHandler );
163 int SVTK_SpaceMouse::close(Display *display)
165 initialize( display, (Window)InputFocus );
174 int SVTK_SpaceMouse::translateEvent( Display* display, XEvent* xEvent, MoveEvent* spaceMouseEvent,
175 double scale, double rScale )
180 if ( xEvent->type == ClientMessage ) {
181 if ( xEvent->xclient.message_type == XMotionEvent ) {
182 spaceMouseEvent->type = SpaceMouseMove;
183 spaceMouseEvent->data[ x ] =
184 xEvent->xclient.data.s[2] * scale;
185 spaceMouseEvent->data[ y ] =
186 xEvent->xclient.data.s[3] * scale;
187 spaceMouseEvent->data[ z ] =
188 xEvent->xclient.data.s[4] * scale;
189 spaceMouseEvent->data[ a ] =
190 xEvent->xclient.data.s[5] * rScale;
191 spaceMouseEvent->data[ b ] =
192 xEvent->xclient.data.s[6] * rScale;
193 spaceMouseEvent->data[ c ] =
194 xEvent->xclient.data.s[7] * rScale;
195 spaceMouseEvent->period = xEvent->xclient.data.s[8];
198 else if ( xEvent->xclient.message_type == XButtonPressEvent ) {
199 spaceMouseEvent->type = SpaceButtonPress;
200 spaceMouseEvent->button = xEvent->xclient.data.s[2];
203 else if ( xEvent->xclient.message_type == XButtonReleaseEvent ) {
204 spaceMouseEvent->type = SpaceButtonRelease;
205 spaceMouseEvent->button = xEvent->xclient.data.s[2];