comparison src/joystick/darwin/SDL_sysjoystick.c @ 1668:4da1ee79c9af SDL-1.3

more tweaking indent options
author Sam Lantinga <slouken@libsdl.org>
date Mon, 29 May 2006 04:04:35 +0000
parents 782fd950bd46
children
comparison
equal deleted inserted replaced
1667:1fddae038bc8 1668:4da1ee79c9af
102 /* Linked list of all available devices */ 102 /* Linked list of all available devices */
103 static recDevice *gpDeviceList = NULL; 103 static recDevice *gpDeviceList = NULL;
104 104
105 105
106 static void 106 static void
107 HIDReportErrorNum (char *strError, long numError) 107 HIDReportErrorNum(char *strError, long numError)
108 { 108 {
109 SDL_SetError (strError); 109 SDL_SetError(strError);
110 } 110 }
111 111
112 static void HIDGetCollectionElements (CFMutableDictionaryRef deviceProperties, 112 static void HIDGetCollectionElements(CFMutableDictionaryRef deviceProperties,
113 recDevice * pDevice); 113 recDevice * pDevice);
114 114
115 /* returns current value for element, polling element 115 /* returns current value for element, polling element
116 * will return 0 on error conditions which should be accounted for by application 116 * will return 0 on error conditions which should be accounted for by application
117 */ 117 */
118 118
119 static SInt32 119 static SInt32
120 HIDGetElementValue (recDevice * pDevice, recElement * pElement) 120 HIDGetElementValue(recDevice * pDevice, recElement * pElement)
121 { 121 {
122 IOReturn result = kIOReturnSuccess; 122 IOReturn result = kIOReturnSuccess;
123 IOHIDEventStruct hidEvent; 123 IOHIDEventStruct hidEvent;
124 hidEvent.value = 0; 124 hidEvent.value = 0;
125 125
126 if (NULL != pDevice && NULL != pElement && NULL != pDevice->interface) { 126 if (NULL != pDevice && NULL != pElement && NULL != pDevice->interface) {
127 result = 127 result =
128 (*(pDevice->interface))->getElementValue (pDevice->interface, 128 (*(pDevice->interface))->getElementValue(pDevice->interface,
129 pElement->cookie, 129 pElement->cookie,
130 &hidEvent); 130 &hidEvent);
131 if (kIOReturnSuccess == result) { 131 if (kIOReturnSuccess == result) {
132 /* record min and max for auto calibration */ 132 /* record min and max for auto calibration */
133 if (hidEvent.value < pElement->minReport) 133 if (hidEvent.value < pElement->minReport)
134 pElement->minReport = hidEvent.value; 134 pElement->minReport = hidEvent.value;
135 if (hidEvent.value > pElement->maxReport) 135 if (hidEvent.value > pElement->maxReport)
140 /* auto user scale */ 140 /* auto user scale */
141 return hidEvent.value; 141 return hidEvent.value;
142 } 142 }
143 143
144 static SInt32 144 static SInt32
145 HIDScaledCalibratedValue (recDevice * pDevice, recElement * pElement, 145 HIDScaledCalibratedValue(recDevice * pDevice, recElement * pElement,
146 long min, long max) 146 long min, long max)
147 { 147 {
148 float deviceScale = max - min; 148 float deviceScale = max - min;
149 float readScale = pElement->maxReport - pElement->minReport; 149 float readScale = pElement->maxReport - pElement->minReport;
150 SInt32 value = HIDGetElementValue (pDevice, pElement); 150 SInt32 value = HIDGetElementValue(pDevice, pElement);
151 if (readScale == 0) 151 if (readScale == 0)
152 return value; /* no scaling at all */ 152 return value; /* no scaling at all */
153 else 153 else
154 return ((value - pElement->minReport) * deviceScale / readScale) + 154 return ((value - pElement->minReport) * deviceScale / readScale) +
155 min; 155 min;
156 } 156 }
157 157
158 158
159 static void 159 static void
160 HIDRemovalCallback (void *target, IOReturn result, void *refcon, void *sender) 160 HIDRemovalCallback(void *target, IOReturn result, void *refcon, void *sender)
161 { 161 {
162 recDevice *device = (recDevice *) refcon; 162 recDevice *device = (recDevice *) refcon;
163 device->removed = 1; 163 device->removed = 1;
164 device->uncentered = 1; 164 device->uncentered = 1;
165 } 165 }
169 /* Create and open an interface to device, required prior to extracting values or building queues. 169 /* Create and open an interface to device, required prior to extracting values or building queues.
170 * Note: appliction now owns the device and must close and release it prior to exiting 170 * Note: appliction now owns the device and must close and release it prior to exiting
171 */ 171 */
172 172
173 static IOReturn 173 static IOReturn
174 HIDCreateOpenDeviceInterface (io_object_t hidDevice, recDevice * pDevice) 174 HIDCreateOpenDeviceInterface(io_object_t hidDevice, recDevice * pDevice)
175 { 175 {
176 IOReturn result = kIOReturnSuccess; 176 IOReturn result = kIOReturnSuccess;
177 HRESULT plugInResult = S_OK; 177 HRESULT plugInResult = S_OK;
178 SInt32 score = 0; 178 SInt32 score = 0;
179 IOCFPlugInInterface **ppPlugInInterface = NULL; 179 IOCFPlugInInterface **ppPlugInInterface = NULL;
180 180
181 if (NULL == pDevice->interface) { 181 if (NULL == pDevice->interface) {
182 result = 182 result =
183 IOCreatePlugInInterfaceForService (hidDevice, 183 IOCreatePlugInInterfaceForService(hidDevice,
184 kIOHIDDeviceUserClientTypeID, 184 kIOHIDDeviceUserClientTypeID,
185 kIOCFPlugInInterfaceID, 185 kIOCFPlugInInterfaceID,
186 &ppPlugInInterface, &score); 186 &ppPlugInInterface, &score);
187 if (kIOReturnSuccess == result) { 187 if (kIOReturnSuccess == result) {
188 /* Call a method of the intermediate plug-in to create the device interface */ 188 /* Call a method of the intermediate plug-in to create the device interface */
189 plugInResult = 189 plugInResult =
190 (*ppPlugInInterface)->QueryInterface (ppPlugInInterface, 190 (*ppPlugInInterface)->QueryInterface(ppPlugInInterface,
191 CFUUIDGetUUIDBytes 191 CFUUIDGetUUIDBytes
192 (kIOHIDDeviceInterfaceID), 192 (kIOHIDDeviceInterfaceID),
193 (void *) &(pDevice-> 193 (void *) &(pDevice->
194 interface)); 194 interface));
195 if (S_OK != plugInResult) 195 if (S_OK != plugInResult)
196 HIDReportErrorNum 196 HIDReportErrorNum
197 ("CouldnŐt query HID class device interface from plugInInterface", 197 ("CouldnŐt query HID class device interface from plugInInterface",
198 plugInResult); 198 plugInResult);
199 (*ppPlugInInterface)->Release (ppPlugInInterface); 199 (*ppPlugInInterface)->Release(ppPlugInInterface);
200 } else 200 } else
201 HIDReportErrorNum 201 HIDReportErrorNum
202 ("Failed to create **plugInInterface via IOCreatePlugInInterfaceForService.", 202 ("Failed to create **plugInInterface via IOCreatePlugInInterfaceForService.",
203 result); 203 result);
204 } 204 }
205 if (NULL != pDevice->interface) { 205 if (NULL != pDevice->interface) {
206 result = (*(pDevice->interface))->open (pDevice->interface, 0); 206 result = (*(pDevice->interface))->open(pDevice->interface, 0);
207 if (kIOReturnSuccess != result) 207 if (kIOReturnSuccess != result)
208 HIDReportErrorNum 208 HIDReportErrorNum
209 ("Failed to open pDevice->interface via open.", result); 209 ("Failed to open pDevice->interface via open.", result);
210 else 210 else
211 (*(pDevice->interface))->setRemovalCallback (pDevice->interface, 211 (*(pDevice->interface))->setRemovalCallback(pDevice->interface,
212 HIDRemovalCallback, 212 HIDRemovalCallback,
213 pDevice, pDevice); 213 pDevice, pDevice);
214 214
215 } 215 }
216 return result; 216 return result;
217 } 217 }
218 218
221 * application will "own" the device if interface is not closed 221 * application will "own" the device if interface is not closed
222 * (device may have to be plug and re-plugged in different location to get it working again without a restart) 222 * (device may have to be plug and re-plugged in different location to get it working again without a restart)
223 */ 223 */
224 224
225 static IOReturn 225 static IOReturn
226 HIDCloseReleaseInterface (recDevice * pDevice) 226 HIDCloseReleaseInterface(recDevice * pDevice)
227 { 227 {
228 IOReturn result = kIOReturnSuccess; 228 IOReturn result = kIOReturnSuccess;
229 229
230 if ((NULL != pDevice) && (NULL != pDevice->interface)) { 230 if ((NULL != pDevice) && (NULL != pDevice->interface)) {
231 /* close the interface */ 231 /* close the interface */
232 result = (*(pDevice->interface))->close (pDevice->interface); 232 result = (*(pDevice->interface))->close(pDevice->interface);
233 if (kIOReturnNotOpen == result) { 233 if (kIOReturnNotOpen == result) {
234 /* do nothing as device was not opened, thus can't be closed */ 234 /* do nothing as device was not opened, thus can't be closed */
235 } else if (kIOReturnSuccess != result) 235 } else if (kIOReturnSuccess != result)
236 HIDReportErrorNum ("Failed to close IOHIDDeviceInterface.", 236 HIDReportErrorNum("Failed to close IOHIDDeviceInterface.",
237 result); 237 result);
238 /* release the interface */ 238 /* release the interface */
239 result = (*(pDevice->interface))->Release (pDevice->interface); 239 result = (*(pDevice->interface))->Release(pDevice->interface);
240 if (kIOReturnSuccess != result) 240 if (kIOReturnSuccess != result)
241 HIDReportErrorNum ("Failed to release IOHIDDeviceInterface.", 241 HIDReportErrorNum("Failed to release IOHIDDeviceInterface.",
242 result); 242 result);
243 pDevice->interface = NULL; 243 pDevice->interface = NULL;
244 } 244 }
245 return result; 245 return result;
246 } 246 }
247 247
248 /* extracts actual specific element information from each element CF dictionary entry */ 248 /* extracts actual specific element information from each element CF dictionary entry */
249 249
250 static void 250 static void
251 HIDGetElementInfo (CFTypeRef refElement, recElement * pElement) 251 HIDGetElementInfo(CFTypeRef refElement, recElement * pElement)
252 { 252 {
253 long number; 253 long number;
254 CFTypeRef refType; 254 CFTypeRef refType;
255 255
256 refType = 256 refType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementCookieKey));
257 CFDictionaryGetValue (refElement, CFSTR (kIOHIDElementCookieKey)); 257 if (refType && CFNumberGetValue(refType, kCFNumberLongType, &number))
258 if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number))
259 pElement->cookie = (IOHIDElementCookie) number; 258 pElement->cookie = (IOHIDElementCookie) number;
260 refType = CFDictionaryGetValue (refElement, CFSTR (kIOHIDElementMinKey)); 259 refType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementMinKey));
261 if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) 260 if (refType && CFNumberGetValue(refType, kCFNumberLongType, &number))
262 pElement->min = number; 261 pElement->min = number;
263 pElement->maxReport = pElement->min; 262 pElement->maxReport = pElement->min;
264 refType = CFDictionaryGetValue (refElement, CFSTR (kIOHIDElementMaxKey)); 263 refType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementMaxKey));
265 if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) 264 if (refType && CFNumberGetValue(refType, kCFNumberLongType, &number))
266 pElement->max = number; 265 pElement->max = number;
267 pElement->minReport = pElement->max; 266 pElement->minReport = pElement->max;
268 /* 267 /*
269 TODO: maybe should handle the following stuff somehow? 268 TODO: maybe should handle the following stuff somehow?
270 269
299 * if element of interest allocate storage, add to list and retrieve element specific info 298 * if element of interest allocate storage, add to list and retrieve element specific info
300 * if collection then pass on to deconstruction collection into additional individual elements 299 * if collection then pass on to deconstruction collection into additional individual elements
301 */ 300 */
302 301
303 static void 302 static void
304 HIDAddElement (CFTypeRef refElement, recDevice * pDevice) 303 HIDAddElement(CFTypeRef refElement, recDevice * pDevice)
305 { 304 {
306 recElement *element = NULL; 305 recElement *element = NULL;
307 recElement **headElement = NULL; 306 recElement **headElement = NULL;
308 long elementType, usagePage, usage; 307 long elementType, usagePage, usage;
309 CFTypeRef refElementType = 308 CFTypeRef refElementType =
310 CFDictionaryGetValue (refElement, CFSTR (kIOHIDElementTypeKey)); 309 CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementTypeKey));
311 CFTypeRef refUsagePage = 310 CFTypeRef refUsagePage =
312 CFDictionaryGetValue (refElement, CFSTR (kIOHIDElementUsagePageKey)); 311 CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementUsagePageKey));
313 CFTypeRef refUsage = 312 CFTypeRef refUsage =
314 CFDictionaryGetValue (refElement, CFSTR (kIOHIDElementUsageKey)); 313 CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementUsageKey));
315 314
316 315
317 if ((refElementType) 316 if ((refElementType)
318 && 317 &&
319 (CFNumberGetValue (refElementType, kCFNumberLongType, &elementType))) 318 (CFNumberGetValue(refElementType, kCFNumberLongType, &elementType))) {
320 {
321 /* look at types of interest */ 319 /* look at types of interest */
322 if ((elementType == kIOHIDElementTypeInput_Misc) 320 if ((elementType == kIOHIDElementTypeInput_Misc)
323 || (elementType == kIOHIDElementTypeInput_Button) 321 || (elementType == kIOHIDElementTypeInput_Button)
324 || (elementType == kIOHIDElementTypeInput_Axis)) { 322 || (elementType == kIOHIDElementTypeInput_Axis)) {
325 if (refUsagePage 323 if (refUsagePage
326 && CFNumberGetValue (refUsagePage, kCFNumberLongType, 324 && CFNumberGetValue(refUsagePage, kCFNumberLongType,
327 &usagePage) && refUsage 325 &usagePage) && refUsage
328 && CFNumberGetValue (refUsage, kCFNumberLongType, &usage)) { 326 && CFNumberGetValue(refUsage, kCFNumberLongType, &usage)) {
329 switch (usagePage) { /* only interested in kHIDPage_GenericDesktop and kHIDPage_Button */ 327 switch (usagePage) { /* only interested in kHIDPage_GenericDesktop and kHIDPage_Button */
330 case kHIDPage_GenericDesktop: 328 case kHIDPage_GenericDesktop:
331 { 329 {
332 switch (usage) { /* look at usage to determine function */ 330 switch (usage) { /* look at usage to determine function */
333 case kHIDUsage_GD_X: 331 case kHIDUsage_GD_X:
338 case kHIDUsage_GD_Rz: 336 case kHIDUsage_GD_Rz:
339 case kHIDUsage_GD_Slider: 337 case kHIDUsage_GD_Slider:
340 case kHIDUsage_GD_Dial: 338 case kHIDUsage_GD_Dial:
341 case kHIDUsage_GD_Wheel: 339 case kHIDUsage_GD_Wheel:
342 element = (recElement *) 340 element = (recElement *)
343 NewPtrClear (sizeof (recElement)); 341 NewPtrClear(sizeof(recElement));
344 if (element) { 342 if (element) {
345 pDevice->axes++; 343 pDevice->axes++;
346 headElement = &(pDevice->firstAxis); 344 headElement = &(pDevice->firstAxis);
347 } 345 }
348 break; 346 break;
349 case kHIDUsage_GD_Hatswitch: 347 case kHIDUsage_GD_Hatswitch:
350 element = (recElement *) 348 element = (recElement *)
351 NewPtrClear (sizeof (recElement)); 349 NewPtrClear(sizeof(recElement));
352 if (element) { 350 if (element) {
353 pDevice->hats++; 351 pDevice->hats++;
354 headElement = &(pDevice->firstHat); 352 headElement = &(pDevice->firstHat);
355 } 353 }
356 break; 354 break;
357 } 355 }
358 } 356 }
359 break; 357 break;
360 case kHIDPage_Button: 358 case kHIDPage_Button:
361 element = (recElement *) 359 element = (recElement *)
362 NewPtrClear (sizeof (recElement)); 360 NewPtrClear(sizeof(recElement));
363 if (element) { 361 if (element) {
364 pDevice->buttons++; 362 pDevice->buttons++;
365 headElement = &(pDevice->firstButton); 363 headElement = &(pDevice->firstButton);
366 } 364 }
367 break; 365 break;
368 default: 366 default:
369 break; 367 break;
370 } 368 }
371 } 369 }
372 } else if (kIOHIDElementTypeCollection == elementType) 370 } else if (kIOHIDElementTypeCollection == elementType)
373 HIDGetCollectionElements ((CFMutableDictionaryRef) refElement, 371 HIDGetCollectionElements((CFMutableDictionaryRef) refElement,
374 pDevice); 372 pDevice);
375 } 373 }
376 374
377 if (element && headElement) { /* add to list */ 375 if (element && headElement) { /* add to list */
378 pDevice->elements++; 376 pDevice->elements++;
379 if (NULL == *headElement) 377 if (NULL == *headElement)
386 elementCurrent = elementPrevious->pNext; 384 elementCurrent = elementPrevious->pNext;
387 } 385 }
388 elementPrevious->pNext = element; 386 elementPrevious->pNext = element;
389 } 387 }
390 element->pNext = NULL; 388 element->pNext = NULL;
391 HIDGetElementInfo (refElement, element); 389 HIDGetElementInfo(refElement, element);
392 } 390 }
393 } 391 }
394 392
395 /* collects information from each array member in device element list (each array memeber = element) */ 393 /* collects information from each array member in device element list (each array memeber = element) */
396 394
397 static void 395 static void
398 HIDGetElementsCFArrayHandler (const void *value, void *parameter) 396 HIDGetElementsCFArrayHandler(const void *value, void *parameter)
399 { 397 {
400 if (CFGetTypeID (value) == CFDictionaryGetTypeID ()) 398 if (CFGetTypeID(value) == CFDictionaryGetTypeID())
401 HIDAddElement ((CFTypeRef) value, (recDevice *) parameter); 399 HIDAddElement((CFTypeRef) value, (recDevice *) parameter);
402 } 400 }
403 401
404 /* handles retrieval of element information from arrays of elements in device IO registry information */ 402 /* handles retrieval of element information from arrays of elements in device IO registry information */
405 403
406 static void 404 static void
407 HIDGetElements (CFTypeRef refElementCurrent, recDevice * pDevice) 405 HIDGetElements(CFTypeRef refElementCurrent, recDevice * pDevice)
408 { 406 {
409 CFTypeID type = CFGetTypeID (refElementCurrent); 407 CFTypeID type = CFGetTypeID(refElementCurrent);
410 if (type == CFArrayGetTypeID ()) { /* if element is an array */ 408 if (type == CFArrayGetTypeID()) { /* if element is an array */
411 CFRange range = { 0, CFArrayGetCount (refElementCurrent) }; 409 CFRange range = { 0, CFArrayGetCount(refElementCurrent) };
412 /* CountElementsCFArrayHandler called for each array member */ 410 /* CountElementsCFArrayHandler called for each array member */
413 CFArrayApplyFunction (refElementCurrent, range, 411 CFArrayApplyFunction(refElementCurrent, range,
414 HIDGetElementsCFArrayHandler, pDevice); 412 HIDGetElementsCFArrayHandler, pDevice);
415 } 413 }
416 } 414 }
417 415
418 /* handles extracting element information from element collection CF types 416 /* handles extracting element information from element collection CF types
419 * used from top level element decoding and hierarchy deconstruction to flatten device element list 417 * used from top level element decoding and hierarchy deconstruction to flatten device element list
420 */ 418 */
421 419
422 static void 420 static void
423 HIDGetCollectionElements (CFMutableDictionaryRef deviceProperties, 421 HIDGetCollectionElements(CFMutableDictionaryRef deviceProperties,
424 recDevice * pDevice) 422 recDevice * pDevice)
425 { 423 {
426 CFTypeRef refElementTop = 424 CFTypeRef refElementTop =
427 CFDictionaryGetValue (deviceProperties, CFSTR (kIOHIDElementKey)); 425 CFDictionaryGetValue(deviceProperties, CFSTR(kIOHIDElementKey));
428 if (refElementTop) 426 if (refElementTop)
429 HIDGetElements (refElementTop, pDevice); 427 HIDGetElements(refElementTop, pDevice);
430 } 428 }
431 429
432 /* use top level element usage page and usage to discern device usage page and usage setting appropriate vlaues in device record */ 430 /* use top level element usage page and usage to discern device usage page and usage setting appropriate vlaues in device record */
433 431
434 static void 432 static void
435 HIDTopLevelElementHandler (const void *value, void *parameter) 433 HIDTopLevelElementHandler(const void *value, void *parameter)
436 { 434 {
437 CFTypeRef refCF = 0; 435 CFTypeRef refCF = 0;
438 if (CFGetTypeID (value) != CFDictionaryGetTypeID ()) 436 if (CFGetTypeID(value) != CFDictionaryGetTypeID())
439 return; 437 return;
440 refCF = CFDictionaryGetValue (value, CFSTR (kIOHIDElementUsagePageKey)); 438 refCF = CFDictionaryGetValue(value, CFSTR(kIOHIDElementUsagePageKey));
441 if (!CFNumberGetValue 439 if (!CFNumberGetValue
442 (refCF, kCFNumberLongType, &((recDevice *) parameter)->usagePage)) 440 (refCF, kCFNumberLongType, &((recDevice *) parameter)->usagePage))
443 SDL_SetError 441 SDL_SetError("CFNumberGetValue error retrieving pDevice->usagePage.");
444 ("CFNumberGetValue error retrieving pDevice->usagePage."); 442 refCF = CFDictionaryGetValue(value, CFSTR(kIOHIDElementUsageKey));
445 refCF = CFDictionaryGetValue (value, CFSTR (kIOHIDElementUsageKey));
446 if (!CFNumberGetValue 443 if (!CFNumberGetValue
447 (refCF, kCFNumberLongType, &((recDevice *) parameter)->usage)) 444 (refCF, kCFNumberLongType, &((recDevice *) parameter)->usage))
448 SDL_SetError ("CFNumberGetValue error retrieving pDevice->usage."); 445 SDL_SetError("CFNumberGetValue error retrieving pDevice->usage.");
449 } 446 }
450 447
451 /* extracts device info from CF dictionary records in IO registry */ 448 /* extracts device info from CF dictionary records in IO registry */
452 449
453 static void 450 static void
454 HIDGetDeviceInfo (io_object_t hidDevice, CFMutableDictionaryRef hidProperties, 451 HIDGetDeviceInfo(io_object_t hidDevice, CFMutableDictionaryRef hidProperties,
455 recDevice * pDevice) 452 recDevice * pDevice)
456 { 453 {
457 CFMutableDictionaryRef usbProperties = 0; 454 CFMutableDictionaryRef usbProperties = 0;
458 io_registry_entry_t parent1, parent2; 455 io_registry_entry_t parent1, parent2;
459 456
460 /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also 457 /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also
461 * get dictionary for usb properties: step up two levels and get CF dictionary for USB properties 458 * get dictionary for usb properties: step up two levels and get CF dictionary for USB properties
462 */ 459 */
463 if ((KERN_SUCCESS == 460 if ((KERN_SUCCESS ==
464 IORegistryEntryGetParentEntry (hidDevice, kIOServicePlane, &parent1)) 461 IORegistryEntryGetParentEntry(hidDevice, kIOServicePlane, &parent1))
465 && (KERN_SUCCESS == 462 && (KERN_SUCCESS ==
466 IORegistryEntryGetParentEntry (parent1, kIOServicePlane, 463 IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2))
467 &parent2))
468 && (KERN_SUCCESS == 464 && (KERN_SUCCESS ==
469 IORegistryEntryCreateCFProperties (parent2, &usbProperties, 465 IORegistryEntryCreateCFProperties(parent2, &usbProperties,
470 kCFAllocatorDefault, 466 kCFAllocatorDefault,
471 kNilOptions))) { 467 kNilOptions))) {
472 if (usbProperties) { 468 if (usbProperties) {
473 CFTypeRef refCF = 0; 469 CFTypeRef refCF = 0;
474 /* get device info 470 /* get device info
475 * try hid dictionary first, if fail then go to usb dictionary 471 * try hid dictionary first, if fail then go to usb dictionary
476 */ 472 */
477 473
478 474
479 /* get product name */ 475 /* get product name */
480 refCF = 476 refCF =
481 CFDictionaryGetValue (hidProperties, 477 CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey));
482 CFSTR (kIOHIDProductKey));
483 if (!refCF) 478 if (!refCF)
484 refCF = 479 refCF =
485 CFDictionaryGetValue (usbProperties, 480 CFDictionaryGetValue(usbProperties,
486 CFSTR ("USB Product Name")); 481 CFSTR("USB Product Name"));
487 if (refCF) { 482 if (refCF) {
488 if (!CFStringGetCString 483 if (!CFStringGetCString
489 (refCF, pDevice->product, 256, 484 (refCF, pDevice->product, 256,
490 CFStringGetSystemEncoding ())) 485 CFStringGetSystemEncoding()))
491 SDL_SetError 486 SDL_SetError
492 ("CFStringGetCString error retrieving pDevice->product."); 487 ("CFStringGetCString error retrieving pDevice->product.");
493 } 488 }
494 489
495 /* get usage page and usage */ 490 /* get usage page and usage */
496 refCF = 491 refCF =
497 CFDictionaryGetValue (hidProperties, 492 CFDictionaryGetValue(hidProperties,
498 CFSTR (kIOHIDPrimaryUsagePageKey)); 493 CFSTR(kIOHIDPrimaryUsagePageKey));
499 if (refCF) { 494 if (refCF) {
500 if (!CFNumberGetValue 495 if (!CFNumberGetValue
501 (refCF, kCFNumberLongType, &pDevice->usagePage)) 496 (refCF, kCFNumberLongType, &pDevice->usagePage))
502 SDL_SetError 497 SDL_SetError
503 ("CFNumberGetValue error retrieving pDevice->usagePage."); 498 ("CFNumberGetValue error retrieving pDevice->usagePage.");
504 refCF = 499 refCF =
505 CFDictionaryGetValue (hidProperties, 500 CFDictionaryGetValue(hidProperties,
506 CFSTR (kIOHIDPrimaryUsageKey)); 501 CFSTR(kIOHIDPrimaryUsageKey));
507 if (refCF) 502 if (refCF)
508 if (!CFNumberGetValue 503 if (!CFNumberGetValue
509 (refCF, kCFNumberLongType, &pDevice->usage)) 504 (refCF, kCFNumberLongType, &pDevice->usage))
510 SDL_SetError 505 SDL_SetError
511 ("CFNumberGetValue error retrieving pDevice->usage."); 506 ("CFNumberGetValue error retrieving pDevice->usage.");
513 508
514 if (NULL == refCF) { /* get top level element HID usage page or usage */ 509 if (NULL == refCF) { /* get top level element HID usage page or usage */
515 /* use top level element instead */ 510 /* use top level element instead */
516 CFTypeRef refCFTopElement = 0; 511 CFTypeRef refCFTopElement = 0;
517 refCFTopElement = 512 refCFTopElement =
518 CFDictionaryGetValue (hidProperties, 513 CFDictionaryGetValue(hidProperties,
519 CFSTR (kIOHIDElementKey)); 514 CFSTR(kIOHIDElementKey));
520 { 515 {
521 /* refCFTopElement points to an array of element dictionaries */ 516 /* refCFTopElement points to an array of element dictionaries */
522 CFRange range = { 0, CFArrayGetCount (refCFTopElement) }; 517 CFRange range = { 0, CFArrayGetCount(refCFTopElement) };
523 CFArrayApplyFunction (refCFTopElement, range, 518 CFArrayApplyFunction(refCFTopElement, range,
524 HIDTopLevelElementHandler, pDevice); 519 HIDTopLevelElementHandler, pDevice);
525 } 520 }
526 } 521 }
527 522
528 CFRelease (usbProperties); 523 CFRelease(usbProperties);
529 } else 524 } else
530 SDL_SetError 525 SDL_SetError
531 ("IORegistryEntryCreateCFProperties failed to create usbProperties."); 526 ("IORegistryEntryCreateCFProperties failed to create usbProperties.");
532 527
533 if (kIOReturnSuccess != IOObjectRelease (parent2)) 528 if (kIOReturnSuccess != IOObjectRelease(parent2))
534 SDL_SetError ("IOObjectRelease error with parent2."); 529 SDL_SetError("IOObjectRelease error with parent2.");
535 if (kIOReturnSuccess != IOObjectRelease (parent1)) 530 if (kIOReturnSuccess != IOObjectRelease(parent1))
536 SDL_SetError ("IOObjectRelease error with parent1."); 531 SDL_SetError("IOObjectRelease error with parent1.");
537 } 532 }
538 } 533 }
539 534
540 535
541 static recDevice * 536 static recDevice *
542 HIDBuildDevice (io_object_t hidDevice) 537 HIDBuildDevice(io_object_t hidDevice)
543 { 538 {
544 recDevice *pDevice = (recDevice *) NewPtrClear (sizeof (recDevice)); 539 recDevice *pDevice = (recDevice *) NewPtrClear(sizeof(recDevice));
545 if (pDevice) { 540 if (pDevice) {
546 /* get dictionary for HID properties */ 541 /* get dictionary for HID properties */
547 CFMutableDictionaryRef hidProperties = 0; 542 CFMutableDictionaryRef hidProperties = 0;
548 kern_return_t result = 543 kern_return_t result =
549 IORegistryEntryCreateCFProperties (hidDevice, &hidProperties, 544 IORegistryEntryCreateCFProperties(hidDevice, &hidProperties,
550 kCFAllocatorDefault, 545 kCFAllocatorDefault,
551 kNilOptions); 546 kNilOptions);
552 if ((result == KERN_SUCCESS) && hidProperties) { 547 if ((result == KERN_SUCCESS) && hidProperties) {
553 /* create device interface */ 548 /* create device interface */
554 result = HIDCreateOpenDeviceInterface (hidDevice, pDevice); 549 result = HIDCreateOpenDeviceInterface(hidDevice, pDevice);
555 if (kIOReturnSuccess == result) { 550 if (kIOReturnSuccess == result) {
556 HIDGetDeviceInfo (hidDevice, hidProperties, pDevice); /* hidDevice used to find parents in registry tree */ 551 HIDGetDeviceInfo(hidDevice, hidProperties, pDevice); /* hidDevice used to find parents in registry tree */
557 HIDGetCollectionElements (hidProperties, pDevice); 552 HIDGetCollectionElements(hidProperties, pDevice);
558 } else { 553 } else {
559 DisposePtr ((Ptr) pDevice); 554 DisposePtr((Ptr) pDevice);
560 pDevice = NULL; 555 pDevice = NULL;
561 } 556 }
562 CFRelease (hidProperties); 557 CFRelease(hidProperties);
563 } else { 558 } else {
564 DisposePtr ((Ptr) pDevice); 559 DisposePtr((Ptr) pDevice);
565 pDevice = NULL; 560 pDevice = NULL;
566 } 561 }
567 } 562 }
568 return pDevice; 563 return pDevice;
569 } 564 }
570 565
571 /* disposes of the element list associated with a device and the memory associated with the list 566 /* disposes of the element list associated with a device and the memory associated with the list
572 */ 567 */
573 568
574 static void 569 static void
575 HIDDisposeElementList (recElement ** elementList) 570 HIDDisposeElementList(recElement ** elementList)
576 { 571 {
577 recElement *pElement = *elementList; 572 recElement *pElement = *elementList;
578 while (pElement) { 573 while (pElement) {
579 recElement *pElementNext = pElement->pNext; 574 recElement *pElementNext = pElement->pNext;
580 DisposePtr ((Ptr) pElement); 575 DisposePtr((Ptr) pElement);
581 pElement = pElementNext; 576 pElement = pElementNext;
582 } 577 }
583 *elementList = NULL; 578 *elementList = NULL;
584 } 579 }
585 580
586 /* disposes of a single device, closing and releaseing interface, freeing memory fro device and elements, setting device pointer to NULL 581 /* disposes of a single device, closing and releaseing interface, freeing memory fro device and elements, setting device pointer to NULL
587 * all your device no longer belong to us... (i.e., you do not 'own' the device anymore) 582 * all your device no longer belong to us... (i.e., you do not 'own' the device anymore)
588 */ 583 */
589 584
590 static recDevice * 585 static recDevice *
591 HIDDisposeDevice (recDevice ** ppDevice) 586 HIDDisposeDevice(recDevice ** ppDevice)
592 { 587 {
593 kern_return_t result = KERN_SUCCESS; 588 kern_return_t result = KERN_SUCCESS;
594 recDevice *pDeviceNext = NULL; 589 recDevice *pDeviceNext = NULL;
595 if (*ppDevice) { 590 if (*ppDevice) {
596 /* save next device prior to disposing of this device */ 591 /* save next device prior to disposing of this device */
597 pDeviceNext = (*ppDevice)->pNext; 592 pDeviceNext = (*ppDevice)->pNext;
598 593
599 /* free element lists */ 594 /* free element lists */
600 HIDDisposeElementList (&(*ppDevice)->firstAxis); 595 HIDDisposeElementList(&(*ppDevice)->firstAxis);
601 HIDDisposeElementList (&(*ppDevice)->firstButton); 596 HIDDisposeElementList(&(*ppDevice)->firstButton);
602 HIDDisposeElementList (&(*ppDevice)->firstHat); 597 HIDDisposeElementList(&(*ppDevice)->firstHat);
603 598
604 result = HIDCloseReleaseInterface (*ppDevice); /* function sanity checks interface value (now application does not own device) */ 599 result = HIDCloseReleaseInterface(*ppDevice); /* function sanity checks interface value (now application does not own device) */
605 if (kIOReturnSuccess != result) 600 if (kIOReturnSuccess != result)
606 HIDReportErrorNum 601 HIDReportErrorNum
607 ("HIDCloseReleaseInterface failed when trying to dipose device.", 602 ("HIDCloseReleaseInterface failed when trying to dipose device.",
608 result); 603 result);
609 DisposePtr ((Ptr) * ppDevice); 604 DisposePtr((Ptr) * ppDevice);
610 *ppDevice = NULL; 605 *ppDevice = NULL;
611 } 606 }
612 return pDeviceNext; 607 return pDeviceNext;
613 } 608 }
614 609
617 * Joystick 0 should be the system default joystick. 612 * Joystick 0 should be the system default joystick.
618 * This function should return the number of available joysticks, or -1 613 * This function should return the number of available joysticks, or -1
619 * on an unrecoverable fatal error. 614 * on an unrecoverable fatal error.
620 */ 615 */
621 int 616 int
622 SDL_SYS_JoystickInit (void) 617 SDL_SYS_JoystickInit(void)
623 { 618 {
624 IOReturn result = kIOReturnSuccess; 619 IOReturn result = kIOReturnSuccess;
625 mach_port_t masterPort = 0; 620 mach_port_t masterPort = 0;
626 io_iterator_t hidObjectIterator = 0; 621 io_iterator_t hidObjectIterator = 0;
627 CFMutableDictionaryRef hidMatchDictionary = NULL; 622 CFMutableDictionaryRef hidMatchDictionary = NULL;
629 io_object_t ioHIDDeviceObject = 0; 624 io_object_t ioHIDDeviceObject = 0;
630 625
631 SDL_numjoysticks = 0; 626 SDL_numjoysticks = 0;
632 627
633 if (gpDeviceList) { 628 if (gpDeviceList) {
634 SDL_SetError ("Joystick: Device list already inited."); 629 SDL_SetError("Joystick: Device list already inited.");
635 return -1; 630 return -1;
636 } 631 }
637 632
638 result = IOMasterPort (bootstrap_port, &masterPort); 633 result = IOMasterPort(bootstrap_port, &masterPort);
639 if (kIOReturnSuccess != result) { 634 if (kIOReturnSuccess != result) {
640 SDL_SetError ("Joystick: IOMasterPort error with bootstrap_port."); 635 SDL_SetError("Joystick: IOMasterPort error with bootstrap_port.");
641 return -1; 636 return -1;
642 } 637 }
643 638
644 /* Set up a matching dictionary to search I/O Registry by class name for all HID class devices. */ 639 /* Set up a matching dictionary to search I/O Registry by class name for all HID class devices. */
645 hidMatchDictionary = IOServiceMatching (kIOHIDDeviceKey); 640 hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
646 if (hidMatchDictionary) { 641 if (hidMatchDictionary) {
647 /* Add key for device type (joystick, in this case) to refine the matching dictionary. */ 642 /* Add key for device type (joystick, in this case) to refine the matching dictionary. */
648 643
649 /* NOTE: we now perform this filtering later 644 /* NOTE: we now perform this filtering later
650 UInt32 usagePage = kHIDPage_GenericDesktop; 645 UInt32 usagePage = kHIDPage_GenericDesktop;
662 return -1; 657 return -1;
663 } 658 }
664 659
665 /*/ Now search I/O Registry for matching devices. */ 660 /*/ Now search I/O Registry for matching devices. */
666 result = 661 result =
667 IOServiceGetMatchingServices (masterPort, hidMatchDictionary, 662 IOServiceGetMatchingServices(masterPort, hidMatchDictionary,
668 &hidObjectIterator); 663 &hidObjectIterator);
669 /* Check for errors */ 664 /* Check for errors */
670 if (kIOReturnSuccess != result) { 665 if (kIOReturnSuccess != result) {
671 SDL_SetError ("Joystick: Couldn't create a HID object iterator."); 666 SDL_SetError("Joystick: Couldn't create a HID object iterator.");
672 return -1; 667 return -1;
673 } 668 }
674 if (!hidObjectIterator) { /* there are no joysticks */ 669 if (!hidObjectIterator) { /* there are no joysticks */
675 gpDeviceList = NULL; 670 gpDeviceList = NULL;
676 SDL_numjoysticks = 0; 671 SDL_numjoysticks = 0;
680 675
681 /* build flat linked list of devices from device iterator */ 676 /* build flat linked list of devices from device iterator */
682 677
683 gpDeviceList = lastDevice = NULL; 678 gpDeviceList = lastDevice = NULL;
684 679
685 while ((ioHIDDeviceObject = IOIteratorNext (hidObjectIterator))) { 680 while ((ioHIDDeviceObject = IOIteratorNext(hidObjectIterator))) {
686 /* build a device record */ 681 /* build a device record */
687 device = HIDBuildDevice (ioHIDDeviceObject); 682 device = HIDBuildDevice(ioHIDDeviceObject);
688 if (!device) 683 if (!device)
689 continue; 684 continue;
690 685
691 /* dump device object, it is no longer needed */ 686 /* dump device object, it is no longer needed */
692 result = IOObjectRelease (ioHIDDeviceObject); 687 result = IOObjectRelease(ioHIDDeviceObject);
693 /* if (KERN_SUCCESS != result) 688 /* if (KERN_SUCCESS != result)
694 HIDReportErrorNum ("IOObjectRelease error with ioHIDDeviceObject.", result); 689 HIDReportErrorNum ("IOObjectRelease error with ioHIDDeviceObject.", result);
695 */ 690 */
696 691
697 /* Filter device list to non-keyboard/mouse stuff */ 692 /* Filter device list to non-keyboard/mouse stuff */
698 if ((device->usagePage != kHIDPage_GenericDesktop) || 693 if ((device->usagePage != kHIDPage_GenericDesktop) ||
699 ((device->usage != kHIDUsage_GD_Joystick && 694 ((device->usage != kHIDUsage_GD_Joystick &&
700 device->usage != kHIDUsage_GD_GamePad))) { 695 device->usage != kHIDUsage_GD_GamePad))) {
701 696
702 /* release memory for the device */ 697 /* release memory for the device */
703 HIDDisposeDevice (&device); 698 HIDDisposeDevice(&device);
704 DisposePtr ((Ptr) device); 699 DisposePtr((Ptr) device);
705 continue; 700 continue;
706 } 701 }
707 702
708 /* Add device to the end of the list */ 703 /* Add device to the end of the list */
709 if (lastDevice) 704 if (lastDevice)
710 lastDevice->pNext = device; 705 lastDevice->pNext = device;
711 else 706 else
712 gpDeviceList = device; 707 gpDeviceList = device;
713 lastDevice = device; 708 lastDevice = device;
714 } 709 }
715 result = IOObjectRelease (hidObjectIterator); /* release the iterator */ 710 result = IOObjectRelease(hidObjectIterator); /* release the iterator */
716 711
717 /* Count the total number of devices we found */ 712 /* Count the total number of devices we found */
718 device = gpDeviceList; 713 device = gpDeviceList;
719 while (device) { 714 while (device) {
720 SDL_numjoysticks++; 715 SDL_numjoysticks++;
724 return SDL_numjoysticks; 719 return SDL_numjoysticks;
725 } 720 }
726 721
727 /* Function to get the device-dependent name of a joystick */ 722 /* Function to get the device-dependent name of a joystick */
728 const char * 723 const char *
729 SDL_SYS_JoystickName (int index) 724 SDL_SYS_JoystickName(int index)
730 { 725 {
731 recDevice *device = gpDeviceList; 726 recDevice *device = gpDeviceList;
732 727
733 for (; index > 0; index--) 728 for (; index > 0; index--)
734 device = device->pNext; 729 device = device->pNext;
740 * The joystick to open is specified by the index field of the joystick. 735 * The joystick to open is specified by the index field of the joystick.
741 * This should fill the nbuttons and naxes fields of the joystick structure. 736 * This should fill the nbuttons and naxes fields of the joystick structure.
742 * It returns 0, or -1 if there is an error. 737 * It returns 0, or -1 if there is an error.
743 */ 738 */
744 int 739 int
745 SDL_SYS_JoystickOpen (SDL_Joystick * joystick) 740 SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
746 { 741 {
747 recDevice *device = gpDeviceList; 742 recDevice *device = gpDeviceList;
748 int index; 743 int index;
749 744
750 for (index = joystick->index; index > 0; index--) 745 for (index = joystick->index; index > 0; index--)
765 * This function shouldn't update the joystick structure directly, 760 * This function shouldn't update the joystick structure directly,
766 * but instead should call SDL_PrivateJoystick*() to deliver events 761 * but instead should call SDL_PrivateJoystick*() to deliver events
767 * and update joystick device state. 762 * and update joystick device state.
768 */ 763 */
769 void 764 void
770 SDL_SYS_JoystickUpdate (SDL_Joystick * joystick) 765 SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
771 { 766 {
772 recDevice *device = joystick->hwdata; 767 recDevice *device = joystick->hwdata;
773 recElement *element; 768 recElement *element;
774 SInt32 value; 769 SInt32 value;
775 int i; 770 int i;
778 if (device->uncentered) { 773 if (device->uncentered) {
779 device->uncentered = 0; 774 device->uncentered = 0;
780 775
781 /* Tell the app that everything is centered/unpressed... */ 776 /* Tell the app that everything is centered/unpressed... */
782 for (i = 0; i < device->axes; i++) 777 for (i = 0; i < device->axes; i++)
783 SDL_PrivateJoystickAxis (joystick, i, 0); 778 SDL_PrivateJoystickAxis(joystick, i, 0);
784 779
785 for (i = 0; i < device->buttons; i++) 780 for (i = 0; i < device->buttons; i++)
786 SDL_PrivateJoystickButton (joystick, i, 0); 781 SDL_PrivateJoystickButton(joystick, i, 0);
787 782
788 for (i = 0; i < device->hats; i++) 783 for (i = 0; i < device->hats; i++)
789 SDL_PrivateJoystickHat (joystick, i, SDL_HAT_CENTERED); 784 SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED);
790 } 785 }
791 786
792 return; 787 return;
793 } 788 }
794 789
795 element = device->firstAxis; 790 element = device->firstAxis;
796 i = 0; 791 i = 0;
797 while (element) { 792 while (element) {
798 value = HIDScaledCalibratedValue (device, element, -32768, 32767); 793 value = HIDScaledCalibratedValue(device, element, -32768, 32767);
799 if (value != joystick->axes[i]) 794 if (value != joystick->axes[i])
800 SDL_PrivateJoystickAxis (joystick, i, value); 795 SDL_PrivateJoystickAxis(joystick, i, value);
801 element = element->pNext; 796 element = element->pNext;
802 ++i; 797 ++i;
803 } 798 }
804 799
805 element = device->firstButton; 800 element = device->firstButton;
806 i = 0; 801 i = 0;
807 while (element) { 802 while (element) {
808 value = HIDGetElementValue (device, element); 803 value = HIDGetElementValue(device, element);
809 if (value > 1) /* handle pressure-sensitive buttons */ 804 if (value > 1) /* handle pressure-sensitive buttons */
810 value = 1; 805 value = 1;
811 if (value != joystick->buttons[i]) 806 if (value != joystick->buttons[i])
812 SDL_PrivateJoystickButton (joystick, i, value); 807 SDL_PrivateJoystickButton(joystick, i, value);
813 element = element->pNext; 808 element = element->pNext;
814 ++i; 809 ++i;
815 } 810 }
816 811
817 element = device->firstHat; 812 element = device->firstHat;
818 i = 0; 813 i = 0;
819 while (element) { 814 while (element) {
820 Uint8 pos = 0; 815 Uint8 pos = 0;
821 816
822 value = HIDGetElementValue (device, element); 817 value = HIDGetElementValue(device, element);
823 if (element->max == 3) /* 4 position hatswitch - scale up value */ 818 if (element->max == 3) /* 4 position hatswitch - scale up value */
824 value *= 2; 819 value *= 2;
825 else if (element->max != 7) /* Neither a 4 nor 8 positions - fall back to default position (centered) */ 820 else if (element->max != 7) /* Neither a 4 nor 8 positions - fall back to default position (centered) */
826 value = -1; 821 value = -1;
827 switch (value) { 822 switch (value) {
856 */ 851 */
857 pos = SDL_HAT_CENTERED; 852 pos = SDL_HAT_CENTERED;
858 break; 853 break;
859 } 854 }
860 if (pos != joystick->hats[i]) 855 if (pos != joystick->hats[i])
861 SDL_PrivateJoystickHat (joystick, i, pos); 856 SDL_PrivateJoystickHat(joystick, i, pos);
862 element = element->pNext; 857 element = element->pNext;
863 ++i; 858 ++i;
864 } 859 }
865 860
866 return; 861 return;
867 } 862 }
868 863
869 /* Function to close a joystick after use */ 864 /* Function to close a joystick after use */
870 void 865 void
871 SDL_SYS_JoystickClose (SDL_Joystick * joystick) 866 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
872 { 867 {
873 /* Should we do anything here? */ 868 /* Should we do anything here? */
874 return; 869 return;
875 } 870 }
876 871
877 /* Function to perform any system-specific joystick related cleanup */ 872 /* Function to perform any system-specific joystick related cleanup */
878 void 873 void
879 SDL_SYS_JoystickQuit (void) 874 SDL_SYS_JoystickQuit(void)
880 { 875 {
881 while (NULL != gpDeviceList) 876 while (NULL != gpDeviceList)
882 gpDeviceList = HIDDisposeDevice (&gpDeviceList); 877 gpDeviceList = HIDDisposeDevice(&gpDeviceList);
883 } 878 }
884 879
885 #endif /* SDL_JOYSTICK_IOKIT */ 880 #endif /* SDL_JOYSTICK_IOKIT */
886 /* vi: set ts=4 sw=4 expandtab: */ 881 /* vi: set ts=4 sw=4 expandtab: */