migrated NDOF code from soc-2010-merwin, SpaceNavigator now works on Mac blender
[blender.git] / intern / ghost / intern / GHOST_NDOFManagerCocoa.mm
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_NDOFManagerCocoa.h"
25 #include "GHOST_SystemCocoa.h"
26
27 extern "C" {
28         #include <3DconnexionClient/ConnexionClientAPI.h>
29         #include <stdio.h>
30         }
31
32 static void SpaceNavAdded(io_connect_t connection)
33         {
34         printf("SpaceNav added\n"); // change these: printf --> informational reports
35         }
36
37 static void SpaceNavRemoved(io_connect_t connection)
38         {
39         printf("SpaceNav removed\n");
40         }
41
42 static void SpaceNavEvent(io_connect_t connection, natural_t messageType, void* messageArgument)
43         {
44         GHOST_SystemCocoa* system = (GHOST_SystemCocoa*) GHOST_ISystem::getSystem();
45         GHOST_NDOFManager* manager = system->getNDOFManager();
46         switch (messageType)
47                 {
48                 case kConnexionMsgDeviceState:
49                         {
50                         ConnexionDeviceState* s = (ConnexionDeviceState*)messageArgument;
51
52                         GHOST_TUns64 now = system->getMilliSeconds();
53
54                         switch (s->command)
55                                 {
56                                 case kConnexionCmdHandleAxis:
57                                         manager->updateTranslation(s->axis, now);
58                                         manager->updateRotation(s->axis + 3, now);
59                                         system->notifyExternalEventProcessed();
60                                         break;
61
62                                 case kConnexionCmdHandleButtons:
63                                         manager->updateButtons(s->buttons, now);
64                                         system->notifyExternalEventProcessed();
65                                         break;
66
67                                 default:
68                                         printf("device state command %d\n", s->command);
69                                 }
70                         break;
71                         }
72                 case kConnexionMsgPrefsChanged:
73                         printf("prefs changed\n"); // this includes app switches
74                         break;
75                 case kConnexionMsgDoAction:
76                         printf("do action\n"); // no idea what this means
77                         // 'calibrate device' in System Prefs sends this
78                         // 3Dx header file says to ignore these
79                         break;
80                 default:
81                         printf("<!> mystery event\n");
82                 }
83         }
84
85 GHOST_NDOFManagerCocoa::GHOST_NDOFManagerCocoa(GHOST_System& sys)
86         : GHOST_NDOFManager(sys)
87         {
88         if (available())
89                 {
90                 OSErr error = InstallConnexionHandlers(SpaceNavEvent, SpaceNavAdded, SpaceNavRemoved);
91                 if (error)
92                         {
93                         printf("<!> error = %d\n", error);
94                         return;
95                         }
96
97                 // Pascal string *and* a four-letter constant. How old-skool.
98                 m_clientID = RegisterConnexionClient('blnd', (UInt8*) "\pblender",
99                         kConnexionClientModeTakeOver, kConnexionMaskAll);
100
101                 printf("client id = %d\n", m_clientID);
102                 }
103         else
104                 {
105                 printf("<!> SpaceNav driver not found\n");
106                 // This isn't a hard error, just means the user doesn't have a SpaceNavigator.
107                 }
108         }
109
110 GHOST_NDOFManagerCocoa::~GHOST_NDOFManagerCocoa()
111         {
112         UnregisterConnexionClient(m_clientID);
113         CleanupConnexionHandlers();
114         }
115
116 bool GHOST_NDOFManagerCocoa::available()
117         {
118 //      extern OSErr InstallConnexionHandlers() __attribute__((weak_import));
119 // ^-- not needed since the entire framework is weak-linked
120         return InstallConnexionHandlers != NULL;
121         }