diff --git a/modules/gui/pymod/export_input.cc b/modules/gui/pymod/export_input.cc index fcda612aa0eebfff8447f3105ad17ca94303ae3e..8906e944b9821b8720b003039cfb3282b572a9e9 100644 --- a/modules/gui/pymod/export_input.cc +++ b/modules/gui/pymod/export_input.cc @@ -32,7 +32,12 @@ object spnav_get_instance() { static object sip_module=import("sip"); static object pyqt4_module=import("PyQt4.QtCore"); - return ost::gui::get_py_qobject<SpnavInput>(SpnavInput::Instance()); + SpnavInput* si = SpnavInput::Instance(); + if(si->isValid()) { + return ost::gui::get_py_qobject<SpnavInput>(si); + } else { + return object(); + } } } diff --git a/modules/gui/pymod/init_spacenav.py b/modules/gui/pymod/init_spacenav.py index 5346b4ca5b8d21d947aa12fa5ef9323faef80fde..d7006e9061be2626162ab9a3dd192e7e3a8f52c7 100644 --- a/modules/gui/pymod/init_spacenav.py +++ b/modules/gui/pymod/init_spacenav.py @@ -1,5 +1,8 @@ +import traceback + from PyQt4 import QtCore +import ost from ost import gfx, gui class SpacenavControl(QtCore.QObject): @@ -18,37 +21,42 @@ class SpacenavControl(QtCore.QObject): if(self.trans): transf.ApplyXAxisTranslation(tx/self.speed) transf.ApplyYAxisTranslation(ty/self.speed) - transf.ApplyZAxisTranslation(-tz/self.speed) if(self.rot): transf.ApplyXAxisRotation(rx/self.speed) transf.ApplyYAxisRotation(ry/self.speed) transf.ApplyZAxisRotation(rz/self.speed) + if(self.trans or self.rot): + transf.ApplyZAxisTranslation(-tz/self.speed) gfx.Scene().SetTransform(transf) gfx.Scene().RequestRedraw() def Toggle(self, button): if button == 0: self.trans = not self.trans - print "Translation Enabled:",self.trans + ost.LogVerbose("SpaceNav: translation %s "%("enabled" if self.trans else "disabled")) elif button == 1: self.rot = not self.rot - print "Rotation Enabled:",self.rot + ost.LogVerbose("SpaceNav: rotation %s"%("enabled" if self.rot else "disabled")) elif button == 12: if self.speed > 20: self.speed *= 0.8 - print "Speed Increased:",self.speed + ost.LogVerbose("SpaceNav: speed increased to "+str(self.speed)) elif button == 13: self.speed /= 0.8 - print "Speed Reduced:",self.speed + ost.LogVerbose("SpaceNav: speed reduced to "+str(self.speed)) else: - print "other:",button + ost.LogDebug("SpaceNav: unmapped button press ["+str(button)+"]") def _InitSpaceNav(app): try: spnav = gui.SpnavInput.GetQThread() - spnav.start() - parent = app.gl_win.qobject - SpacenavControl(spnav,parent) - except AttributeError: - pass + if spnav: + spnav.start() + parent = app.gl_win.qobject + SpacenavControl(spnav,parent) + ost.LogInfo("SpaceNav: device found and connected") + else: + ost.LogInfo("SpaceNav: no device found, or could not connect to device socket") + except: + ost.LogInfo("SpaceNav: caught exception during initialization: %s"%(traceback.format_exc())) diff --git a/modules/gui/src/input/spnav_input.cc b/modules/gui/src/input/spnav_input.cc index 362cfa3d5f0e8df4b747d750f463e89147e1ddbd..10022c6aef7fd6154cbe5246c4d24b10b82906f1 100644 --- a/modules/gui/src/input/spnav_input.cc +++ b/modules/gui/src/input/spnav_input.cc @@ -18,56 +18,86 @@ //------------------------------------------------------------------------------ /* - Author: Stefan Scheuber + Authors: Stefan Scheuber, Ansgar Philippsen */ #include "spnav_input.hh" #include <iostream> -#include <ost/io/io_exception.hh> - #include <stdio.h> #include <stdlib.h> #include <signal.h> +#include <stdexcept> + #include <spnav.h> +#include <sys/un.h> +#include <sys/types.h> +#include <sys/socket.h> -namespace ost { namespace gui { +namespace { -SpnavInput* SpnavInput::spnav_=NULL; + // immitate spnav_open, but without the annoying perror littering + bool check_spnav() { + int s=0; + sockaddr_un addr; -SpnavInput::SpnavInput(QObject* parent): QThread(parent) -{ - qRegisterMetaType<geom::Mat4>("geom::Mat4"); - if(spnav_open()==-1) { - throw(io::IOException("failed to connect to the space navigator daemon\n")); + memset(&addr, 0, sizeof(sockaddr_un)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, "/var/run/spnav.sock", sizeof(addr.sun_path)); + + if((s = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { + return false; + } + if(connect(s, (struct sockaddr*)&addr, sizeof(sockaddr_un)) == -1) { + return false; + } + close(s); + return true; } + } -void SpnavInput::run(){ +namespace ost { namespace gui { + +SpnavInput::SpnavInput(QObject* parent): + QThread(parent), + valid_(false) +{ + qRegisterMetaType<geom::Mat4>("geom::Mat4"); + if(check_spnav() && spnav_open()!=-1) { + valid_=true; + } +} +void SpnavInput::run() +{ + if(!valid_) return; spnav_event sev; while(spnav_wait_event(&sev)) { if(sev.type == SPNAV_EVENT_MOTION) { emit this->deviceTransformed(sev.motion.x,sev.motion.y,sev.motion.z, sev.motion.rx, sev.motion.ry, sev.motion.rz); - } else { /* SPNAV_EVENT_BUTTON */ - printf("got button %s event b(%d)\n", sev.button.press ? "press" : "release", sev.button.bnum); + } else if (sev.type == SPNAV_EVENT_BUTTON) { + //printf("got button %s event b(%d)\n", sev.button.press ? "press" : "release", sev.button.bnum); if(sev.button.press) emit this->deviceButtonPressed(sev.button.bnum); } } } -SpnavInput::~SpnavInput(){ - spnav_close(); +SpnavInput::~SpnavInput() +{ + if(valid_) { + spnav_close(); + this->quit(); + this->terminate(); + } } SpnavInput* SpnavInput::Instance() { - if (!SpnavInput::spnav_) { - SpnavInput::spnav_=new SpnavInput; - } - return SpnavInput::spnav_; + static SpnavInput inst; + return &inst; } }} //ns diff --git a/modules/gui/src/input/spnav_input.hh b/modules/gui/src/input/spnav_input.hh index a77734b34765e4f3e53732021ad8177da23f27af..fe6eec7e651421da882acced300b3aa5e3c52e2b 100644 --- a/modules/gui/src/input/spnav_input.hh +++ b/modules/gui/src/input/spnav_input.hh @@ -41,13 +41,15 @@ public: static SpnavInput* Instance(); + bool isValid() const {return valid_;} + signals: void deviceTransformed(int,int,int,int,int,int); void deviceButtonPressed(int); private: SpnavInput(QObject* parent=NULL); - static SpnavInput* spnav_; + bool valid_; }; }} //ns diff --git a/modules/gui/src/module_config.hh b/modules/gui/src/module_config.hh deleted file mode 100644 index d246cae358cfbc50a0018750317bf2243064996a..0000000000000000000000000000000000000000 --- a/modules/gui/src/module_config.hh +++ /dev/null @@ -1,36 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the OpenStructure project <www.openstructure.org> -// -// Copyright (C) 2008-2011 by the OpenStructure authors -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License as published by the Free -// Software Foundation; either version 3.0 of the License, or (at your option) -// any later version. -// This library is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -// details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this library; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -//------------------------------------------------------------------------------ -#ifndef OST_GUI_MODULE_CONFIG_HH -#define OST_GUI_MODULE_CONFIG_HH - -/* - DO NOT EDIT, automatically generated by CMake -*/ - -#include <ost/base.hh> - -#define OST_SPNAV_ENABLED 0 - -#if defined(OST_MODULE_OST_GUI) -# define DLLEXPORT_OST_GUI DLLEXPORT -#else -# define DLLEXPORT_OST_GUI DLLIMPORT -#endif - -#endif