svn merge -r38814:38905 https://svn.blender.org/svnroot/bf-blender/trunk/blender .
[blender.git] / intern / ghost / intern / GHOST_NDOFManagerX11.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s):
19  *   Mike Erwin
20  *
21  * ***** END GPL LICENSE BLOCK *****
22  */
23  
24 #include "GHOST_NDOFManagerX11.h"
25 #include "GHOST_SystemX11.h"
26 #include <spnav.h>
27 #include <stdio.h>
28
29
30 GHOST_NDOFManagerX11::GHOST_NDOFManagerX11(GHOST_System& sys)
31         : GHOST_NDOFManager(sys)
32         , m_available(false)
33         {
34         setDeadZone(0.1f); // how to calibrate on Linux? throw away slight motion!
35
36         if (spnav_open() != -1)
37                 {
38                 // determine exactly which device (if any) is plugged in
39
40                 #define MAX_LINE_LENGTH 100
41
42                 // look for USB devices with Logitech's vendor ID
43                 FILE* command_output = popen("lsusb -d 046d:","r");
44                 if (command_output)
45                         {
46                         char line[MAX_LINE_LENGTH] = {0};
47                         while (fgets(line, MAX_LINE_LENGTH, command_output))
48                                 {
49                                 unsigned short vendor_id = 0, product_id = 0;
50                                 if (sscanf(line, "Bus %*d Device %*d: ID %hx:%hx", &vendor_id, &product_id) == 2)
51                                         if (setDevice(vendor_id, product_id))
52                                                 {
53                                                 m_available = true;
54                                                 break; // stop looking once the first 3D mouse is found
55                                                 }
56                                 }
57                         pclose(command_output);
58                         }
59                 }
60         else
61                 {
62                 printf("ndof: spacenavd not found\n");
63                 // This isn't a hard error, just means the user doesn't have a 3D mouse.
64                 }
65         }
66
67 GHOST_NDOFManagerX11::~GHOST_NDOFManagerX11()
68         {
69         if (m_available)
70                 spnav_close();
71         }
72
73 bool GHOST_NDOFManagerX11::available()
74         {
75         return m_available;
76         }
77
78 //bool GHOST_NDOFManagerX11::identifyDevice()
79 //      {
80 //      
81 //      }
82
83 bool GHOST_NDOFManagerX11::processEvents()
84         {
85         GHOST_TUns64 now = m_system.getMilliSeconds();
86
87         bool anyProcessed = false;
88         spnav_event e;
89         while (spnav_poll_event(&e))
90                 {
91                 switch (e.type)
92                         {
93                         case SPNAV_EVENT_MOTION:
94                                 {
95                                 // convert to blender view coords
96                                 short t[3] = {e.motion.x, e.motion.y, -e.motion.z};
97                                 short r[3] = {-e.motion.rx, -e.motion.ry, e.motion.rz};
98
99                                 updateTranslation(t, now);
100                                 updateRotation(r, now);
101                                 break;
102                                 }
103                         case SPNAV_EVENT_BUTTON:
104                                 updateButton(e.button.bnum, e.button.press, now);
105                                 break;
106                         }
107                 anyProcessed = true;
108                 }
109         return anyProcessed;
110         }