1 // SALOME VTKViewer : build VTK viewer into Salome desktop
3 // Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SVTK_SpaceMouse.cxx
25 // Author : Alexander SLADKOV
35 #include <X11/Xutil.h>
36 #include <X11/Xatom.h>
37 #include <X11/keysym.h>
39 #include "SVTK_SpaceMouse.h"
41 //---------------------------------------------
42 SVTK_SpaceMouse* SVTK_SpaceMouse::myInstance = 0;
44 //---------------------------------------------
45 SVTK_SpaceMouse* SVTK_SpaceMouse::getInstance()
48 myInstance = new SVTK_SpaceMouse();
52 //---------------------------------------------
53 SVTK_SpaceMouse::SVTK_SpaceMouse()
59 //---------------------------------------------
60 int SVTK_SpaceMouse::initialize( Display *display, Window window )
62 XMotionEvent = XInternAtom( display, "MotionEvent", 1 );
63 XButtonPressEvent = XInternAtom( display, "ButtonPressEvent", 1 );
64 XButtonReleaseEvent = XInternAtom( display, "ButtonReleaseEvent", 1 );
65 XCommandEvent = XInternAtom( display, "CommandEvent", 1 );
67 spaceMouseOn = (XMotionEvent != 0) &&
68 (XButtonPressEvent != 0) &&
69 (XButtonReleaseEvent != 0) &&
74 spaceMouseOn = setWindow( display, window );
81 //---------------------------------------------
82 static int errorCallback( Display *display, XErrorEvent *Error )
85 if ( Error->error_code != BadWindow ) {
86 XGetErrorText( display,Error->error_code,msg,sizeof( msg ) );
87 fprintf( stderr, "SpaceMouse reported error = %s. Exit ... \n", msg );
92 //---------------------------------------------
93 int SVTK_SpaceMouse::setWindow( Display *display, Window window )
95 XTextProperty winName;
99 unsigned long NItems, BytesReturn;
100 unsigned char *PropReturn;
103 int (*errorHandler)(Display *,XErrorEvent *);
106 errorHandler = XSetErrorHandler( errorCallback );
108 root = RootWindow( display, DefaultScreen(display) );
111 XGetWindowProperty( display, root, XCommandEvent, 0,1, 0,
112 AnyPropertyType, &type, &format, &NItems,
113 &BytesReturn, &PropReturn );
116 if ( PropReturn != NULL ) {
117 win = *(Window *) PropReturn;
123 if ( XGetWMName( display, win, &winName ) == 0 )
126 if ( strcmp( (char *) "Magellan Window", (char *) winName.value) != 0 )
129 xEvent.type = ClientMessage;
130 xEvent.xclient.format = 16;
131 xEvent.xclient.send_event = 0;
132 xEvent.xclient.display = display;
133 xEvent.xclient.window = win;
134 xEvent.xclient.message_type = XCommandEvent;
136 xEvent.xclient.data.s[0] = (short) ((window>>16)&0x0000FFFF);
137 xEvent.xclient.data.s[1] = (short) (window&0x0000FFFF);
138 xEvent.xclient.data.s[2] = 27695;
140 if ( XSendEvent( display, win, 0, 0x0000, &xEvent ) == 0 )
145 XSetErrorHandler( errorHandler );
149 //---------------------------------------------
150 int SVTK_SpaceMouse::close(Display *display)
152 initialize( display, (Window)InputFocus );
158 //---------------------------------------------
159 int SVTK_SpaceMouse::translateEvent( Display* display, XEvent* xEvent, MoveEvent* spaceMouseEvent,
160 double scale, double rScale )
165 if ( xEvent->type == ClientMessage ) {
166 if ( xEvent->xclient.message_type == XMotionEvent ) {
167 spaceMouseEvent->type = SpaceMouseMove;
168 spaceMouseEvent->data[ x ] =
169 xEvent->xclient.data.s[2] * scale;
170 spaceMouseEvent->data[ y ] =
171 xEvent->xclient.data.s[3] * scale;
172 spaceMouseEvent->data[ z ] =
173 xEvent->xclient.data.s[4] * scale;
174 spaceMouseEvent->data[ a ] =
175 xEvent->xclient.data.s[5] * rScale;
176 spaceMouseEvent->data[ b ] =
177 xEvent->xclient.data.s[6] * rScale;
178 spaceMouseEvent->data[ c ] =
179 xEvent->xclient.data.s[7] * rScale;
180 spaceMouseEvent->period = xEvent->xclient.data.s[8];
183 else if ( xEvent->xclient.message_type == XButtonPressEvent ) {
184 spaceMouseEvent->type = SpaceButtonPress;
185 spaceMouseEvent->button = xEvent->xclient.data.s[2];
188 else if ( xEvent->xclient.message_type == XButtonReleaseEvent ) {
189 spaceMouseEvent->type = SpaceButtonRelease;
190 spaceMouseEvent->button = xEvent->xclient.data.s[2];