Privacy
An open-source, flexible 3D physical simulation framework
ConnexionHID.cpp
Go to the documentation of this file.
1 
21 #include <math.h>
22 #include <Carbon/Carbon.h>
23 #include <AvailabilityMacros.h>
24 #include <IOKit/hid/IOHIDLib.h>
25 #include "../ConnexionHID.h"
26 
27 namespace mars {
28  namespace plugins {
29  namespace connexion_plugin {
30 
31  IOHIDManagerRef myIOHIDManagerRef = NULL;
32  CFMutableArrayRef myDeviceCFArrayRef = NULL;
33  IOHIDDeviceRef myIOHIDDeviceRef = NULL;
34  CFArrayRef myElementCFArrayRef = NULL;
35  IOHIDElementRef myElementRef[8] = {NULL, NULL, NULL, NULL,
36  NULL, NULL, NULL, NULL};
37  //IOHIDTransactionRef transaction = NULL;
38 
39  static const ControlID gScrolledControlID = { 'Scrl', 0 };
40  static void CFSetApplierFunctionCopyToCFArray(const void *value,
41  void *context) {
42  CFArrayAppendValue((CFMutableArrayRef) context, value);
43  }
44 
45  static Boolean IOHIDDevice_GetLongProperty(IOHIDDeviceRef inIOHIDDeviceRef,
46  CFStringRef inKey,
47  long *outValue) {
48  Boolean result = FALSE;
49 
50  if(inIOHIDDeviceRef) {
51  CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty(inIOHIDDeviceRef, inKey);
52  if(tCFTypeRef) {
53  // if this is a number
54  if(CFNumberGetTypeID() == CFGetTypeID(tCFTypeRef)) {
55  // get it's value
56  result = CFNumberGetValue((CFNumberRef) tCFTypeRef,
57  kCFNumberSInt32Type, outValue);
58  }
59  }
60  }
61  return result;
62  } // IOHIDDevice_GetLongProperty
63 
64  int initConnexionHID(void *windowID) {
65  (void) windowID;
66  // init device manager
67  myIOHIDManagerRef = IOHIDManagerCreate(kCFAllocatorDefault,
68  kIOHIDOptionsTypeNone );
69 
70  if(myIOHIDManagerRef) {
71  // open it
72  IOReturn tIOReturn = IOHIDManagerOpen(myIOHIDManagerRef,
73  kIOHIDOptionsTypeNone);
74  if(kIOReturnSuccess != tIOReturn) {
75  fprintf(stderr, "%s: Couldn't open IOHIDManager.",
76  __PRETTY_FUNCTION__);
77  return 0;
78  }
79  } else {
80  fprintf(stderr, "%s: Couldn't create a IOHIDManager.",
81  __PRETTY_FUNCTION__);
82  return 0;
83  }
84 
85  // set it for IOHIDManager to use to match against
86  IOHIDManagerSetDeviceMatchingMultiple(myIOHIDManagerRef,
87  NULL );
88  // get device list
89  CFSetRef devCFSetRef = IOHIDManagerCopyDevices(myIOHIDManagerRef);
90  if(devCFSetRef) {
91  // create an empty array
92  myDeviceCFArrayRef = CFArrayCreateMutable( kCFAllocatorDefault, 0,
93  &kCFTypeArrayCallBacks );
94  // now copy the set to the array
95  CFSetApplyFunction( devCFSetRef, CFSetApplierFunctionCopyToCFArray,
96  ( void * ) myDeviceCFArrayRef );
97  // and release the set we copied from the IOHID manager
98  CFRelease( devCFSetRef );
99  }
100 
101  // get the space navigator
102  if(!myDeviceCFArrayRef) return 0;
103  CFIndex idx, cnt = CFArrayGetCount( myDeviceCFArrayRef );
104  char product[255] = "";
105  char target_product[255] = "SpaceNavigator";
106  char target_product2[255] = "Space Navigator";
107  //char target_product[255] = "Apple Optical USB Mouse";
108  bool found_device = false;
109  for ( idx = 0; idx < cnt; idx++ ) {
110  myIOHIDDeviceRef = (IOHIDDeviceRef)CFArrayGetValueAtIndex(myDeviceCFArrayRef, idx);
111 
112 
113  CFStringRef string = (CFStringRef)IOHIDDeviceGetProperty(myIOHIDDeviceRef,
114  CFSTR(kIOHIDProductKey));
115  if(string) {
116  verify(CFStringGetCString(string, product, sizeof(product),
117  kCFStringEncodingUTF8));
118  }
119  long result = 0;
120  (void) IOHIDDevice_GetLongProperty(myIOHIDDeviceRef,
121  CFSTR(kIOHIDProductIDKey), &result);
122 
123  if(!strcmp(target_product, product)) {
124  found_device = true;
125  break;
126  }
127  if(!strcmp(target_product2, product)) {
128  found_device = true;
129  break;
130  }
131  }
132  if(!found_device) return 0;
133  myElementCFArrayRef = IOHIDDeviceCopyMatchingElements(myIOHIDDeviceRef,
134  NULL, 0);
135  if(myElementCFArrayRef) {
136  CFIndex eleIndex, eleCount = CFArrayGetCount(myElementCFArrayRef);
137  int e_count = 0;
138  for(eleIndex=0; eleIndex<eleCount; eleIndex++) {
139  IOHIDElementRef tIOHIDElementRef = (IOHIDElementRef)CFArrayGetValueAtIndex(myElementCFArrayRef, eleIndex);
140  if ( !tIOHIDElementRef ) continue;
141  IOHIDElementType tIOHIDElementType = IOHIDElementGetType(tIOHIDElementRef);
142  if(tIOHIDElementType>kIOHIDElementTypeInput_ScanCodes) continue;
143  long usagePage = IOHIDElementGetUsagePage(tIOHIDElementRef);
144  long usage = IOHIDElementGetUsage(tIOHIDElementRef);
145  if ( !usagePage || !usage ) continue;
146  if ( -1 == usage ) continue;
147  myElementRef[e_count++] = tIOHIDElementRef;
148  }
149 
150  }
151  return 1;
152  }
153 
154  void getValue(double *coordinates, struct connexionValues *rawValues) {
155  struct connexionValues result;
156  double values[8];
157  int el;
158  IOHIDValueRef value = NULL;
159 
160  for(el = 0; el < 8; el++) {
161  if(myElementRef[el] != NULL) {
162  if(IOHIDDeviceGetValue(myIOHIDDeviceRef, myElementRef[el],
163  &value) == kIOReturnSuccess) {
164  values[el] = (double)IOHIDValueGetIntegerValue(value);
165  }
166  }
167  }
168  rawValues->tx = values[0];
169  rawValues->ty = values[1];
170  rawValues->tz = values[2];
171  rawValues->rx = values[3];
172  rawValues->ry = values[4];
173  rawValues->rz = values[5];
174  rawValues->button1 = (int)values[6];
175  rawValues->button2 = (int)values[7];
176 
177  coordinates[0] = rawValues->tx * fabs(rawValues->tx * 0.01);
178  coordinates[2] = -rawValues->ty * fabs(rawValues->ty * 0.01);
179  coordinates[1] = -rawValues->tz * fabs(rawValues->tz * 0.01);
180  coordinates[3] = rawValues->rx * fabs(rawValues->rx * 0.01);
181  coordinates[5] = -rawValues->ry * fabs(rawValues->ry * 0.01);
182  coordinates[4] = -rawValues->rz * fabs(rawValues->rz * 0.01);
183  }
184 
185  void closeConnexionHID() {
186  int i;
187 
188  if(myIOHIDManagerRef) {
189  IOHIDManagerClose(myIOHIDManagerRef, 0);
190  }
191  CFRelease(myDeviceCFArrayRef);
192  CFRelease(myElementCFArrayRef);
193  }
194 
195  } // end of namespace connexion_plugin
196  } // end of namespace plugins
197 } // end of namespace mars
static Boolean IOHIDDevice_GetLongProperty(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey, long *outValue)
void getValue(interfaces::sReal *coordiantes, struct connexionValues *rawValues)
static void CFSetApplierFunctionCopyToCFArray(const void *value, void *context)
int initConnexionHID(void *windowID)
Copyright 2012, DFKI GmbH Robotics Innovation Center.
IOHIDElementRef myElementRef[8]
static const ControlID gScrolledControlID
CFMutableArrayRef myDeviceCFArrayRef