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