]> SALOME platform Git repositories - modules/gui.git/blob - src/SVTK/SVTK_SpaceMouse.cxx
Salome HOME
c8a99ee07691fcad1cc2605040ea90406cc83a83
[modules/gui.git] / src / SVTK / SVTK_SpaceMouse.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  SALOME VTKViewer : build VTK viewer into Salome desktop
23 //  File   : SVTK_SpaceMouse.cxx
24 //  Author : Alexander SLADKOV
25 //  Module : SALOME
26 //  $Header$
27 //
28 #include <string.h>
29 #include <math.h>
30 #include <stdio.h>
31
32 #ifndef WIN32
33 #include <X11/X.h>
34 #include <X11/Xlib.h>
35 #include <X11/Xutil.h>
36 #include <X11/Xatom.h>
37 #include <X11/keysym.h>
38 #endif
39
40 #include "SVTK_SpaceMouse.h"
41
42 SVTK_SpaceMouse* SVTK_SpaceMouse::myInstance = 0;
43
44 /*!
45   \return shared instance of object (creates if there is no one)
46 */
47 SVTK_SpaceMouse* SVTK_SpaceMouse::getInstance()
48 {
49   if ( !myInstance )
50     myInstance = new SVTK_SpaceMouse();
51   return myInstance;
52 }
53
54 /*!
55   Constructor
56 */
57 SVTK_SpaceMouse::SVTK_SpaceMouse()
58 {
59 #ifndef WIN32
60   win = InputFocus;
61 #endif
62   spaceMouseOn = 0;
63 }
64
65 #ifndef WIN32
66
67 /*!
68   Initialization
69 */
70 int SVTK_SpaceMouse::initialize( Display *display, Window window )
71 {
72  XMotionEvent        = XInternAtom( display, "MotionEvent",        1 );
73  XButtonPressEvent   = XInternAtom( display, "ButtonPressEvent",   1 );
74  XButtonReleaseEvent = XInternAtom( display, "ButtonReleaseEvent", 1 );
75  XCommandEvent       = XInternAtom( display, "CommandEvent",       1 );
76
77  spaceMouseOn = (XMotionEvent        != 0) && 
78                 (XButtonPressEvent   != 0) && 
79                 (XButtonReleaseEvent != 0) && 
80                 (XCommandEvent       != 0);
81  if ( !spaceMouseOn )
82   return 0;
83
84  spaceMouseOn = setWindow( display, window );
85  if ( !spaceMouseOn )
86   return 0;
87  
88  return spaceMouseOn; 
89 }
90
91 static int errorCallback( Display *display, XErrorEvent *Error )
92 {
93   char msg[ 128 ];
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 );
97   }
98   return 0;
99 }
100
101 /*!
102   Initialize by window
103 */
104 int SVTK_SpaceMouse::setWindow( Display *display, Window window )
105 {
106   XTextProperty winName;
107   XEvent xEvent;
108   Atom type;
109   int format;
110   unsigned long NItems, BytesReturn;
111   unsigned char *PropReturn;
112   Window root;
113   int result;
114   int (*errorHandler)(Display *,XErrorEvent *);
115
116   result = 1;
117   errorHandler = XSetErrorHandler( errorCallback );
118  
119   root = RootWindow( display, DefaultScreen(display) );
120
121   PropReturn = NULL;
122   XGetWindowProperty( display, root, XCommandEvent, 0,1, 0,
123                       AnyPropertyType, &type, &format, &NItems,
124                       &BytesReturn, &PropReturn );
125
126   win = InputFocus;
127   if ( PropReturn != NULL ) {
128     win = *(Window *) PropReturn;
129     XFree( PropReturn );
130   }
131   else
132     return result = 0;
133
134   if ( XGetWMName( display, win, &winName ) == 0 )
135     return result = 0;
136
137   if ( strcmp( (char *) "Magellan Window", (char *) winName.value) != 0 )
138     return result = 0;
139
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;
146   
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;
150
151   if ( XSendEvent( display, win, 0, 0x0000, &xEvent ) == 0 )
152     return result = 0;
153
154   XFlush( display );
155
156   XSetErrorHandler( errorHandler );
157   return result;
158 }
159
160 /*!
161   Close
162 */
163 int SVTK_SpaceMouse::close(Display *display)
164 {
165   initialize( display, (Window)InputFocus );
166   spaceMouseOn = 0;
167   
168   return 1;
169 }
170
171 /*!
172   Custom event handler
173 */
174 int SVTK_SpaceMouse::translateEvent( Display* display, XEvent* xEvent, MoveEvent* spaceMouseEvent,
175                     double scale, double rScale )
176 {
177   if ( !spaceMouseOn )
178     return 0;
179
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];
196       return 1;
197     }
198     else if ( xEvent->xclient.message_type == XButtonPressEvent ) {
199       spaceMouseEvent->type = SpaceButtonPress;
200       spaceMouseEvent->button = xEvent->xclient.data.s[2];
201       return 2;
202     }
203     else if ( xEvent->xclient.message_type == XButtonReleaseEvent ) {
204       spaceMouseEvent->type = SpaceButtonRelease;
205       spaceMouseEvent->button = xEvent->xclient.data.s[2];
206       return 3;
207     }
208   }
209   return (!display);
210 }
211
212 #endif