23848c80803ea999c984042384866df0b99f5123
[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 NDOF_DeviceAdded(io_connect_t connection)
33         {
34         printf("ndof device added\n"); // change these: printf --> informational reports
35
36         // determine exactly which device is plugged in
37         ConnexionDevicePrefs p;
38         ConnexionGetCurrentDevicePrefs(kDevID_AnyDevice, &p);
39         printf("device type %d: %s\n", p.deviceID,
40                 p.deviceID == kDevID_SpaceNavigator ? "SpaceNavigator" :
41                 p.deviceID == kDevID_SpaceNavigatorNB ? "SpaceNavigator for Notebooks" :
42                 p.deviceID == kDevID_SpaceExplorer ? "SpaceExplorer" :
43                 "unknown");
44
45         // try a more "standard" way
46         int result = 0;
47         ConnexionControl(kConnexionCtlGetDeviceID, 0, &result);
48         unsigned short vendorID = result >> 16;
49         unsigned short productID = result & 0xffff;
50         printf("vendor %04hx:%04hx product\n", vendorID, productID);
51         }
52
53 static void NDOF_DeviceRemoved(io_connect_t connection)
54         {
55         printf("ndof device removed\n");
56         }
57
58 static void NDOF_DeviceEvent(io_connect_t connection, natural_t messageType, void* messageArgument)
59         {
60         GHOST_SystemCocoa* system = (GHOST_SystemCocoa*) GHOST_ISystem::getSystem();
61         GHOST_NDOFManager* manager = system->getNDOFManager();
62         switch (messageType)
63                 {
64                 case kConnexionMsgDeviceState:
65                         {
66                         ConnexionDeviceState* s = (ConnexionDeviceState*)messageArgument;
67
68                         GHOST_TUns64 now = system->getMilliSeconds();
69
70                         switch (s->command)
71                                 {
72                                 case kConnexionCmdHandleAxis:
73                                         manager->updateTranslation(s->axis, now);
74                                         manager->updateRotation(s->axis + 3, now);
75                                         system->notifyExternalEventProcessed();
76                                         break;
77
78                                 case kConnexionCmdHandleButtons:
79
80                                         // s->buttons field has only 16 bits, not enough for SpacePilotPro
81                                         // look at raw USB report for more button bits
82                                         printf("button bits = [");
83                                         for (int i = 0; i < 8; ++i)
84                                                 printf("%02x", s->report[i]);
85                                         printf("]\n");
86
87                                         manager->updateButtons(s->buttons, now);
88                                         system->notifyExternalEventProcessed();
89                                         break;
90
91                                 case kConnexionCmdAppSpecific:
92                                         printf("app-specific command: param=%hd value=%d\n", s->param, s->value);
93                                         break;
94
95                                 default:
96                                         printf("<!> mystery command %d\n", s->command);
97                                 }
98                         break;
99                         }
100                 case kConnexionMsgPrefsChanged:
101                         printf("prefs changed\n"); // this includes app switches
102                         break;
103                 case kConnexionMsgDoAction:
104                         printf("do action\n"); // no idea what this means
105                         // 'calibrate device' in System Prefs sends this
106                         // 3Dx header file says to ignore these
107                         break;
108                 default:
109                         printf("<!> mystery event\n");
110                 }
111         }
112
113 GHOST_NDOFManagerCocoa::GHOST_NDOFManagerCocoa(GHOST_System& sys)
114         : GHOST_NDOFManager(sys)
115         {
116         if (available())
117                 {
118                 OSErr error = InstallConnexionHandlers(NDOF_DeviceEvent, NDOF_DeviceAdded, NDOF_DeviceRemoved);
119                 if (error)
120                         {
121                         printf("<!> error = %d\n", error);
122                         return;
123                         }
124
125                 // Pascal string *and* a four-letter constant. How old-skool.
126                 m_clientID = RegisterConnexionClient('blnd', (UInt8*) "\pblender",
127                         kConnexionClientModeTakeOver, kConnexionMaskAll);
128
129                 printf("client id = %d\n", m_clientID);
130                 }
131         else
132                 {
133                 printf("<!> SpaceNav driver not found\n");
134                 // This isn't a hard error, just means the user doesn't have a SpaceNavigator.
135                 }
136         }
137
138 GHOST_NDOFManagerCocoa::~GHOST_NDOFManagerCocoa()
139         {
140         UnregisterConnexionClient(m_clientID);
141         CleanupConnexionHandlers();
142         }
143
144 bool GHOST_NDOFManagerCocoa::available()
145         {
146 //      extern OSErr InstallConnexionHandlers() __attribute__((weak_import));
147 // ^-- not needed since the entire framework is weak-linked
148         return InstallConnexionHandlers != NULL;
149         }