Back to index

salome-gui  6.5.0
SVTK_SpaceMouse.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  SALOME VTKViewer : build VTK viewer into Salome desktop
00024 //  File   : SVTK_SpaceMouse.cxx
00025 //  Author : Alexander SLADKOV
00026 
00027 #include <string.h>
00028 #include <math.h>
00029 #include <stdio.h>
00030 
00031 #ifndef WIN32
00032 #include <X11/X.h>
00033 #include <X11/Xlib.h>
00034 #include <X11/Xutil.h>
00035 #include <X11/Xatom.h>
00036 #include <X11/keysym.h>
00037 #endif
00038 
00039 #include "SVTK_SpaceMouse.h"
00040 
00041 SVTK_SpaceMouse* SVTK_SpaceMouse::myInstance = 0;
00042 
00046 SVTK_SpaceMouse* SVTK_SpaceMouse::getInstance()
00047 {
00048   if ( !myInstance )
00049     myInstance = new SVTK_SpaceMouse();
00050   return myInstance;
00051 }
00052 
00056 SVTK_SpaceMouse::SVTK_SpaceMouse()
00057 {
00058 #ifndef WIN32
00059   win = InputFocus;
00060 #endif
00061   spaceMouseOn = 0;
00062 }
00063 
00064 #ifndef WIN32
00065 
00069 int SVTK_SpaceMouse::initialize( Display *display, Window window )
00070 {
00071  XMotionEvent        = XInternAtom( display, "MotionEvent",        1 );
00072  XButtonPressEvent   = XInternAtom( display, "ButtonPressEvent",   1 );
00073  XButtonReleaseEvent = XInternAtom( display, "ButtonReleaseEvent", 1 );
00074  XCommandEvent       = XInternAtom( display, "CommandEvent",       1 );
00075 
00076  spaceMouseOn = (XMotionEvent        != 0) && 
00077                 (XButtonPressEvent   != 0) && 
00078                 (XButtonReleaseEvent != 0) && 
00079                 (XCommandEvent       != 0);
00080  if ( !spaceMouseOn )
00081   return 0;
00082 
00083  spaceMouseOn = setWindow( display, window );
00084  if ( !spaceMouseOn )
00085   return 0;
00086  
00087  return spaceMouseOn; 
00088 }
00089 
00090 static int errorCallback( Display *display, XErrorEvent *Error )
00091 {
00092   char msg[ 128 ];
00093   if ( Error->error_code != BadWindow ) {
00094     XGetErrorText( display,Error->error_code,msg,sizeof( msg ) );
00095     fprintf( stderr, "SpaceMouse reported error = %s. Exit ... \n", msg );
00096   }
00097   return 0;
00098 }
00099 
00103 int SVTK_SpaceMouse::setWindow( Display *display, Window window )
00104 {
00105   XTextProperty winName;
00106   XEvent xEvent;
00107   Atom type;
00108   int format;
00109   unsigned long NItems, BytesReturn;
00110   unsigned char *PropReturn;
00111   Window root;
00112   int result;
00113   int (*errorHandler)(Display *,XErrorEvent *);
00114 
00115   result = 1;
00116   errorHandler = XSetErrorHandler( errorCallback );
00117  
00118   root = RootWindow( display, DefaultScreen(display) );
00119 
00120   PropReturn = NULL;
00121   XGetWindowProperty( display, root, XCommandEvent, 0,1, 0,
00122                       AnyPropertyType, &type, &format, &NItems,
00123                       &BytesReturn, &PropReturn );
00124 
00125   win = InputFocus;
00126   if ( PropReturn != NULL ) {
00127     win = *(Window *) PropReturn;
00128     XFree( PropReturn );
00129   }
00130   else
00131     return result = 0;
00132 
00133   if ( XGetWMName( display, win, &winName ) == 0 )
00134     return result = 0;
00135 
00136   if ( strcmp( (char *) "Magellan Window", (char *) winName.value) != 0 )
00137     return result = 0;
00138 
00139   xEvent.type = ClientMessage;
00140   xEvent.xclient.format = 16;
00141   xEvent.xclient.send_event = 0;
00142   xEvent.xclient.display = display;
00143   xEvent.xclient.window = win;
00144   xEvent.xclient.message_type = XCommandEvent;
00145   
00146   xEvent.xclient.data.s[0] = (short) ((window>>16)&0x0000FFFF);
00147   xEvent.xclient.data.s[1] = (short)  (window&0x0000FFFF);
00148   xEvent.xclient.data.s[2] = 27695;
00149 
00150   if ( XSendEvent( display, win, 0, 0x0000, &xEvent ) == 0 )
00151     return result = 0;
00152 
00153   XFlush( display );
00154 
00155   XSetErrorHandler( errorHandler );
00156   return result;
00157 }
00158 
00162 int SVTK_SpaceMouse::close(Display *display)
00163 {
00164   initialize( display, (Window)InputFocus );
00165   spaceMouseOn = 0;
00166   
00167   return 1;
00168 }
00169 
00173 int SVTK_SpaceMouse::translateEvent( Display* display, XEvent* xEvent, MoveEvent* spaceMouseEvent,
00174                     double scale, double rScale )
00175 {
00176   if ( !spaceMouseOn )
00177     return 0;
00178 
00179   if ( xEvent->type == ClientMessage ) {
00180     if ( xEvent->xclient.message_type == XMotionEvent ) {
00181       spaceMouseEvent->type = SpaceMouseMove;
00182       spaceMouseEvent->data[ x ] =
00183         xEvent->xclient.data.s[2] * scale;
00184       spaceMouseEvent->data[ y ] =
00185         xEvent->xclient.data.s[3] * scale;
00186       spaceMouseEvent->data[ z ] =
00187         xEvent->xclient.data.s[4] * scale;
00188       spaceMouseEvent->data[ a ] =
00189         xEvent->xclient.data.s[5] * rScale;
00190       spaceMouseEvent->data[ b ] =
00191         xEvent->xclient.data.s[6] * rScale;
00192       spaceMouseEvent->data[ c ] =
00193         xEvent->xclient.data.s[7] * rScale;
00194       spaceMouseEvent->period = xEvent->xclient.data.s[8];
00195       return 1;
00196     }
00197     else if ( xEvent->xclient.message_type == XButtonPressEvent ) {
00198       spaceMouseEvent->type = SpaceButtonPress;
00199       spaceMouseEvent->button = xEvent->xclient.data.s[2];
00200       return 2;
00201     }
00202     else if ( xEvent->xclient.message_type == XButtonReleaseEvent ) {
00203       spaceMouseEvent->type = SpaceButtonRelease;
00204       spaceMouseEvent->button = xEvent->xclient.data.s[2];
00205       return 3;
00206     }
00207   }
00208   return (!display);
00209 }
00210 
00211 #endif