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.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 // File : SVTK_SpaceMouse.cxx
25 // Author : Alexander SLADKOV
36 #include <X11/Xutil.h>
37 #include <X11/Xatom.h>
38 #include <X11/keysym.h>
41 #include "SVTK_SpaceMouse.h"
43 SVTK_SpaceMouse* SVTK_SpaceMouse::myInstance = 0;
46 \return shared instance of object (creates if there is no one)
48 SVTK_SpaceMouse* SVTK_SpaceMouse::getInstance()
51 myInstance = new SVTK_SpaceMouse();
58 SVTK_SpaceMouse::SVTK_SpaceMouse()
71 int SVTK_SpaceMouse::initialize( Display *display, Window window )
73 XMotionEvent = XInternAtom( display, "MotionEvent", 1 );
74 XButtonPressEvent = XInternAtom( display, "ButtonPressEvent", 1 );
75 XButtonReleaseEvent = XInternAtom( display, "ButtonReleaseEvent", 1 );
76 XCommandEvent = XInternAtom( display, "CommandEvent", 1 );
78 spaceMouseOn = (XMotionEvent != 0) &&
79 (XButtonPressEvent != 0) &&
80 (XButtonReleaseEvent != 0) &&
85 spaceMouseOn = setWindow( display, window );
92 static int errorCallback( Display *display, XErrorEvent *Error )
95 if ( Error->error_code != BadWindow ) {
96 XGetErrorText( display,Error->error_code,msg,sizeof( msg ) );
97 fprintf( stderr, "SpaceMouse reported error = %s. Exit ... \n", msg );
105 int SVTK_SpaceMouse::setWindow( Display *display, Window window )
107 XTextProperty winName;
111 unsigned long NItems, BytesReturn;
112 unsigned char *PropReturn;
115 int (*errorHandler)(Display *,XErrorEvent *);
118 errorHandler = XSetErrorHandler( errorCallback );
120 root = RootWindow( display, DefaultScreen(display) );
123 XGetWindowProperty( display, root, XCommandEvent, 0,1, 0,
124 AnyPropertyType, &type, &format, &NItems,
125 &BytesReturn, &PropReturn );
128 if ( PropReturn != NULL ) {
129 win = *(Window *) PropReturn;
135 if ( XGetWMName( display, win, &winName ) == 0 )
138 if ( strcmp( (char *) "Magellan Window", (char *) winName.value) != 0 )
141 xEvent.type = ClientMessage;
142 xEvent.xclient.format = 16;
143 xEvent.xclient.send_event = 0;
144 xEvent.xclient.display = display;
145 xEvent.xclient.window = win;
146 xEvent.xclient.message_type = XCommandEvent;
148 xEvent.xclient.data.s[0] = (short) ((window>>16)&0x0000FFFF);
149 xEvent.xclient.data.s[1] = (short) (window&0x0000FFFF);
150 xEvent.xclient.data.s[2] = 27695;
152 if ( XSendEvent( display, win, 0, 0x0000, &xEvent ) == 0 )
157 XSetErrorHandler( errorHandler );
164 int SVTK_SpaceMouse::close(Display *display)
166 initialize( display, (Window)InputFocus );
175 int SVTK_SpaceMouse::translateEvent( Display* display, XEvent* xEvent, MoveEvent* spaceMouseEvent,
176 double scale, double rScale )
181 if ( xEvent->type == ClientMessage ) {
182 if ( xEvent->xclient.message_type == XMotionEvent ) {
183 spaceMouseEvent->type = SpaceMouseMove;
184 spaceMouseEvent->data[ x ] =
185 xEvent->xclient.data.s[2] * scale;
186 spaceMouseEvent->data[ y ] =
187 xEvent->xclient.data.s[3] * scale;
188 spaceMouseEvent->data[ z ] =
189 xEvent->xclient.data.s[4] * scale;
190 spaceMouseEvent->data[ a ] =
191 xEvent->xclient.data.s[5] * rScale;
192 spaceMouseEvent->data[ b ] =
193 xEvent->xclient.data.s[6] * rScale;
194 spaceMouseEvent->data[ c ] =
195 xEvent->xclient.data.s[7] * rScale;
196 spaceMouseEvent->period = xEvent->xclient.data.s[8];
199 else if ( xEvent->xclient.message_type == XButtonPressEvent ) {
200 spaceMouseEvent->type = SpaceButtonPress;
201 spaceMouseEvent->button = xEvent->xclient.data.s[2];
204 else if ( xEvent->xclient.message_type == XButtonReleaseEvent ) {
205 spaceMouseEvent->type = SpaceButtonRelease;
206 spaceMouseEvent->button = xEvent->xclient.data.s[2];