Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * Contributor(s): 00019 * Mike Erwin 00020 * 00021 * ***** END GPL LICENSE BLOCK ***** 00022 */ 00023 00024 #ifdef WITH_INPUT_NDOF 00025 00026 #include "GHOST_NDOFManagerCocoa.h" 00027 #include "GHOST_SystemCocoa.h" 00028 00029 extern "C" { 00030 #include <3DconnexionClient/ConnexionClientAPI.h> 00031 #include <stdio.h> 00032 } 00033 00034 // static functions need to talk to these objects: 00035 static GHOST_SystemCocoa* ghost_system = NULL; 00036 static GHOST_NDOFManager* ndof_manager = NULL; 00037 00038 // 3Dconnexion drivers before 10.x are "old" 00039 // not all buttons will work 00040 static bool has_old_driver = true; 00041 00042 static void NDOF_DeviceAdded(io_connect_t connection) 00043 { 00044 printf("ndof: device added\n"); // change these: printf --> informational reports 00045 00046 #if 0 // device preferences will be useful some day 00047 ConnexionDevicePrefs p; 00048 ConnexionGetCurrentDevicePrefs(kDevID_AnyDevice, &p); 00049 #endif 00050 00051 // determine exactly which device is plugged in 00052 SInt32 result = 0; 00053 ConnexionControl(kConnexionCtlGetDeviceID, 0, &result); 00054 unsigned short vendorID = result >> 16; 00055 unsigned short productID = result & 0xffff; 00056 00057 ndof_manager->setDevice(vendorID, productID); 00058 } 00059 00060 static void NDOF_DeviceRemoved(io_connect_t connection) 00061 { 00062 printf("ndof: device removed\n"); 00063 } 00064 00065 static void NDOF_DeviceEvent(io_connect_t connection, natural_t messageType, void* messageArgument) 00066 { 00067 switch (messageType) 00068 { 00069 case kConnexionMsgDeviceState: 00070 { 00071 ConnexionDeviceState* s = (ConnexionDeviceState*)messageArgument; 00072 00073 GHOST_TUns64 now = ghost_system->getMilliSeconds(); 00074 00075 switch (s->command) 00076 { 00077 case kConnexionCmdHandleAxis: 00078 { 00079 // convert to blender view coordinates 00080 short t[3] = {s->axis[0], -(s->axis[2]), s->axis[1]}; 00081 short r[3] = {-(s->axis[3]), s->axis[5], -(s->axis[4])}; 00082 00083 ndof_manager->updateTranslation(t, now); 00084 ndof_manager->updateRotation(r, now); 00085 00086 ghost_system->notifyExternalEventProcessed(); 00087 break; 00088 } 00089 case kConnexionCmdHandleButtons: 00090 { 00091 int button_bits = has_old_driver ? s->buttons8 : s->buttons; 00092 ndof_manager->updateButtons(button_bits, now); 00093 ghost_system->notifyExternalEventProcessed(); 00094 break; 00095 } 00096 case kConnexionCmdAppSpecific: 00097 printf("ndof: app-specific command, param = %hd, value = %d\n", s->param, s->value); 00098 break; 00099 00100 default: 00101 printf("ndof: mystery device command %d\n", s->command); 00102 } 00103 break; 00104 } 00105 case kConnexionMsgPrefsChanged: 00106 // printf("ndof: prefs changed\n"); // this includes app switches 00107 // TODO: look through updated prefs for things blender cares about 00108 break; 00109 case kConnexionMsgCalibrateDevice: 00110 printf("ndof: calibrate\n"); // but what should blender do? 00111 break; 00112 case kConnexionMsgDoMapping: 00113 // printf("ndof: driver did something\n"); 00114 // sent when the driver itself consumes an NDOF event 00115 // and performs whatever action is set in user prefs 00116 // 3Dx header file says to ignore these 00117 break; 00118 default: 00119 printf("ndof: mystery event %d\n", messageType); 00120 } 00121 } 00122 00123 GHOST_NDOFManagerCocoa::GHOST_NDOFManagerCocoa(GHOST_System& sys) 00124 : GHOST_NDOFManager(sys) 00125 { 00126 if (available()) 00127 { 00128 // give static functions something to talk to: 00129 ghost_system = dynamic_cast<GHOST_SystemCocoa*>(&sys); 00130 ndof_manager = this; 00131 00132 OSErr error = InstallConnexionHandlers(NDOF_DeviceEvent, NDOF_DeviceAdded, NDOF_DeviceRemoved); 00133 if (error) { 00134 printf("ndof: error %d while installing handlers\n", error); 00135 return; 00136 } 00137 00138 // Pascal string *and* a four-letter constant. How old-skool. 00139 m_clientID = RegisterConnexionClient('blnd', (UInt8*) "\007blender", 00140 kConnexionClientModeTakeOver, kConnexionMaskAll); 00141 00142 // printf("ndof: client id = %d\n", m_clientID); 00143 00144 if (oldDRV()) { 00145 has_old_driver = false; 00146 SetConnexionClientButtonMask(m_clientID, kConnexionMaskAllButtons); 00147 } 00148 else { 00149 printf("ndof: old 3Dx driver installed, some buttons may not work\n"); 00150 } 00151 } 00152 else { 00153 printf("ndof: 3Dx driver not found\n"); 00154 // This isn't a hard error, just means the user doesn't have a 3D mouse. 00155 } 00156 } 00157 00158 GHOST_NDOFManagerCocoa::~GHOST_NDOFManagerCocoa() 00159 { 00160 if (available()) 00161 { 00162 UnregisterConnexionClient(m_clientID); 00163 CleanupConnexionHandlers(); 00164 ghost_system = NULL; 00165 ndof_manager = NULL; 00166 } 00167 } 00168 extern "C" { 00169 bool GHOST_NDOFManagerCocoa::available() 00170 { 00171 extern OSErr InstallConnexionHandlers() __attribute__((weak_import)); 00172 // Make the linker happy for the framework check (see link below for more info) 00173 // http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html 00174 return InstallConnexionHandlers != NULL; 00175 // this means that the driver is installed and dynamically linked to blender 00176 } 00177 00178 bool GHOST_NDOFManagerCocoa::oldDRV() 00179 { 00180 extern OSErr SetConnexionClientButtonMask() __attribute__((weak_import)); 00181 // Make the linker happy for the framework check (see link below for more info) 00182 // http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html 00183 return SetConnexionClientButtonMask != NULL; 00184 // this means that the driver has this symbol 00185 } 00186 } 00187 #endif // WITH_INPUT_NDOF