Blender  V2.59
GHOST_NDOFManagerX11.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: GHOST_NDOFManagerX11.cpp 39153 2011-08-07 16:44:10Z merwin $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version. 
00010  *
00011  * This program 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
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * Contributor(s):
00021  *   Mike Erwin
00022  *
00023  * ***** END GPL LICENSE BLOCK *****
00024  */
00025 
00026 #ifdef WITH_INPUT_NDOF
00027 
00028 #include "GHOST_NDOFManagerX11.h"
00029 #include "GHOST_SystemX11.h"
00030 #include <spnav.h>
00031 #include <stdio.h>
00032 
00033 
00034 GHOST_NDOFManagerX11::GHOST_NDOFManagerX11(GHOST_System& sys)
00035     :
00036       GHOST_NDOFManager(sys),
00037       m_available(false)
00038 {
00039         setDeadZone(0.1f); /* how to calibrate on Linux? throw away slight motion! */
00040 
00041         if (spnav_open() != -1) {
00042                 /* determine exactly which device (if any) is plugged in */
00043 
00044 #define MAX_LINE_LENGTH 100
00045 
00046                 /* look for USB devices with Logitech's vendor ID */
00047                 FILE* command_output = popen("lsusb -d 046d:","r");
00048                 if (command_output) {
00049                         char line[MAX_LINE_LENGTH] = {0};
00050                         while (fgets(line, MAX_LINE_LENGTH, command_output)) {
00051                                 unsigned short vendor_id = 0, product_id = 0;
00052                                 if (sscanf(line, "Bus %*d Device %*d: ID %hx:%hx", &vendor_id, &product_id) == 2)
00053                                         if (setDevice(vendor_id, product_id)) {
00054                                                 m_available = true;
00055                                                 break; /* stop looking once the first 3D mouse is found */
00056                                         }
00057                         }
00058                         pclose(command_output);
00059                 }
00060         }
00061         else {
00062                 puts("ndof: spacenavd not found");
00063                 /* This isn't a hard error, just means the user doesn't have a 3D mouse. */
00064         }
00065 }
00066 
00067 GHOST_NDOFManagerX11::~GHOST_NDOFManagerX11()
00068 {
00069         if (m_available)
00070                 spnav_close();
00071 }
00072 
00073 bool GHOST_NDOFManagerX11::available()
00074 {
00075         return m_available;
00076 }
00077 
00078 bool GHOST_NDOFManagerX11::processEvents()
00079 {
00080         GHOST_TUns64 now = m_system.getMilliSeconds();
00081 
00082         bool anyProcessed = false;
00083         spnav_event e;
00084         while (spnav_poll_event(&e)) {
00085                 switch (e.type) {
00086                         case SPNAV_EVENT_MOTION:
00087                         {
00088                                 /* convert to blender view coords */
00089                                 short t[3] = {e.motion.x, e.motion.y, -e.motion.z};
00090                                 short r[3] = {-e.motion.rx, -e.motion.ry, e.motion.rz};
00091 
00092                                 updateTranslation(t, now);
00093                                 updateRotation(r, now);
00094                                 break;
00095                         }
00096                         case SPNAV_EVENT_BUTTON:
00097                                 updateButton(e.button.bnum, e.button.press, now);
00098                                 break;
00099                 }
00100                 anyProcessed = true;
00101         }
00102         return anyProcessed;
00103 }
00104 
00105 #endif /* WITH_INPUT_NDOF */