1 // Copyright (C) 2007-2020 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, or (at your option) any later version.
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
23 // SALOME VTKViewer : build VTK viewer into Salome desktop
24 // File : SVTK_SpaceMouse.cxx
25 // Author : Alexander SLADKOV
33 #if !defined WIN32 && !defined __APPLE__
35 #include <X11/Xutil.h>
36 #include <X11/Xatom.h>
37 #include <X11/keysym.h>
41 #include "SVTK_SpaceMouse.h"
43 SVTK_SpaceMouseXCB* SVTK_SpaceMouseXCB::myInstance = 0;
48 SVTK_SpaceMouse::SVTK_SpaceMouse()
56 SVTK_SpaceMouseXCB::SVTK_SpaceMouseXCB()
59 #if !defined WIN32 && !defined __APPLE__
65 \return shared instance of object (creates if there is no one)
67 SVTK_SpaceMouseXCB* SVTK_SpaceMouseXCB::getInstance()
70 myInstance = new SVTK_SpaceMouseXCB();
76 #if !defined WIN32 && !defined __APPLE__
77 int SVTK_SpaceMouseXCB::initialize( xcb_connection_t *connection, xcb_window_t window )
80 xcb_intern_atom_cookie_t cookie = xcb_intern_atom (connection, 0, strlen("XCB_MOTION_NOTIFY"), "XCB_MOTION_NOTIFY" );
82 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply ( connection, cookie, NULL );
83 XCBMotionEvent = reply->atom;
84 cookie = xcb_intern_atom (connection, 0, strlen("XCB_BUTTON_PRESS"), "XCB_BUTTON_PRESS" );
85 reply = xcb_intern_atom_reply ( connection, cookie, NULL );
86 XCBButtonPressEvent = reply->atom;
87 cookie = xcb_intern_atom (connection, 0, strlen("XCB_BUTTON_RELEASE"), "XCB_BUTTON_RELEASE" );
88 reply = xcb_intern_atom_reply ( connection, cookie, NULL );
89 XCBButtonReleaseEvent = reply->atom;
93 spaceMouseOn = (XCBMotionEvent != 0) &&
94 (XCBButtonPressEvent != 0) &&
95 (XCBButtonReleaseEvent != 0);
99 spaceMouseOn = setWindow( connection, window );
109 int SVTK_SpaceMouseXCB::setWindow( xcb_connection_t *connection, xcb_window_t window )
111 xcb_client_message_event_t xcbEvent;
112 xcb_window_t root_window = 0; // todo: initial value (if screen is null, see below)
113 xcb_screen_t* screen;
114 xcb_generic_error_t* error;
115 xcb_void_cookie_t cookie;
117 screen = xcb_setup_roots_iterator ( xcb_get_setup ( connection ) ).data;
121 root_window = screen->root;
123 xcb_get_property_cookie_t prop_cookie;
124 xcb_get_property_reply_t* prop_reply;
125 prop_cookie = xcb_get_property (connection, 0, root_window, XCB_ATOM_WM_NAME,
126 XCB_ATOM_STRING, 0, 0);
130 if (( prop_reply = xcb_get_property_reply ( connection, prop_cookie, NULL ) ))
132 int len = xcb_get_property_value_length( prop_reply );
140 if ( strcmp( (char *) "Magellan Window", (char *) xcb_get_property_value( prop_reply ) ) != 0 )
143 win = * ( xcb_window_t * ) xcb_get_property_value( prop_reply );
148 xcbEvent.response_type = XCB_CLIENT_MESSAGE;
149 xcbEvent.format = 16;
150 xcbEvent.sequence = 0;
151 xcbEvent.window = win;
153 xcbEvent.data.data16[0] = (short) ((window>>16)&0x0000FFFF);
154 xcbEvent.data.data16[1] = (short) (window&0x0000FFFF);
155 xcbEvent.data.data16[2] = 27695;
157 cookie = xcb_send_event( connection, 0, win, 0x0000, (const char *)&xcbEvent );
160 if (( error = xcb_request_check( connection, cookie )))
162 if ( error->error_code != BadWindow )
164 fprintf ( stderr, "SpaceMouse reported error = %d. Exit ... \n", error->error_code);
169 xcb_flush(connection);
177 int SVTK_SpaceMouseXCB::close(xcb_connection_t *connection)
179 initialize( connection, (xcb_window_t)InputFocus );
188 int SVTK_SpaceMouseXCB::translateEvent( xcb_connection_t* connection, xcb_client_message_event_t* xcbEvent, MoveEvent* spaceMouseEvent,
189 double scale, double rScale )
194 if ( xcbEvent->response_type == XCB_CLIENT_MESSAGE ) {
195 if ( xcbEvent->type == XCBMotionEvent ) {
196 spaceMouseEvent->type = SpaceMouseMove;
197 spaceMouseEvent->data[ x ] =
198 xcbEvent->data.data16[2] * scale;
199 spaceMouseEvent->data[ y ] =
200 xcbEvent->data.data16[3] * scale;
201 spaceMouseEvent->data[ z ] =
202 xcbEvent->data.data16[4] * scale;
203 spaceMouseEvent->data[ a ] =
204 xcbEvent->data.data16[5] * rScale;
205 spaceMouseEvent->data[ b ] =
206 xcbEvent->data.data16[6] * rScale;
207 spaceMouseEvent->data[ c ] =
208 xcbEvent->data.data16[7] * rScale;
209 spaceMouseEvent->period = xcbEvent->data.data16[8];
212 else if ( xcbEvent->type == XCBButtonPressEvent ) {
213 spaceMouseEvent->type = SpaceButtonPress;
214 spaceMouseEvent->button = xcbEvent->data.data16[2];
217 else if ( xcbEvent->type == XCBButtonReleaseEvent ) {
218 spaceMouseEvent->type = SpaceButtonRelease;
219 spaceMouseEvent->button = xcbEvent->data.data16[2];
223 return (!connection);