zenilib: zenilib/jni/external/sdl/src/joystick/darwin/SDL_sysjoystick.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_sysjoystick.c
Go to the documentation of this file.
1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22
23 #ifdef SDL_JOYSTICK_IOKIT
24
25 /* SDL joystick driver for Darwin / Mac OS X, based on the IOKit HID API */
26 /* Written 2001 by Max Horn */
27
28 #include <unistd.h>
29 #include <ctype.h>
30 #include <sysexits.h>
31 #include <mach/mach.h>
32 #include <mach/mach_error.h>
33 #include <IOKit/IOKitLib.h>
34 #include <IOKit/IOCFPlugIn.h>
35 #ifdef MACOS_10_0_4
36 #include <IOKit/hidsystem/IOHIDUsageTables.h>
37 #else
38 /* The header was moved here in Mac OS X 10.1 */
39 #include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
40 #endif
41 #include <IOKit/hid/IOHIDLib.h>
42 #include <IOKit/hid/IOHIDKeys.h>
43 #include <CoreFoundation/CoreFoundation.h>
44 #include <Carbon/Carbon.h> /* for NewPtrClear, DisposePtr */
45 #include <IOKit/IOMessage.h>
46
47 /* For force feedback testing. */
48 #include <ForceFeedback/ForceFeedback.h>
49 #include <ForceFeedback/ForceFeedbackConstants.h>
50
51 #include "SDL_joystick.h"
52 #include "../SDL_sysjoystick.h"
53 #include "../SDL_joystick_c.h"
54 #include "SDL_sysjoystick_c.h"
55 #include "SDL_events.h"
56 #if !SDL_EVENTS_DISABLED
57 #include "../../events/SDL_events_c.h"
58 #endif
59
60
61 /* Linked list of all available devices */
62 static recDevice *gpDeviceList = NULL;
63 /* OSX reference to the notification object that tells us about device insertion/removal */
64 IONotificationPortRef notificationPort = 0;
65 /* if 1 then a device was added since the last update call */
66 static SDL_bool s_bDeviceAdded = SDL_FALSE;
67 static SDL_bool s_bDeviceRemoved = SDL_FALSE;
68
69 /* static incrementing counter for new joystick devices seen on the system. Devices should start with index 0 */
70 static int s_joystick_instance_id = -1;
71
72 static void
73 HIDReportErrorNum(char *strError, long numError)
74 {
75 SDL_SetError(strError);
76 }
77
78 static void HIDGetCollectionElements(CFMutableDictionaryRef deviceProperties,
79 recDevice * pDevice);
80
81 /* returns current value for element, polling element
82 * will return 0 on error conditions which should be accounted for by application
83 */
84
85 static SInt32
86 HIDGetElementValue(recDevice * pDevice, recElement * pElement)
87 {
88 IOReturn result = kIOReturnSuccess;
89 IOHIDEventStruct hidEvent;
90 hidEvent.value = 0;
91
92 if (NULL != pDevice && NULL != pElement && NULL != pDevice->interface) {
93 result =
94 (*(pDevice->interface))->getElementValue(pDevice->interface,
95 pElement->cookie,
96 &hidEvent);
97 if (kIOReturnSuccess == result) {
98 /* record min and max for auto calibration */
99 if (hidEvent.value < pElement->minReport)
100 pElement->minReport = hidEvent.value;
101 if (hidEvent.value > pElement->maxReport)
102 pElement->maxReport = hidEvent.value;
103 }
104 }
105
106 /* auto user scale */
107 return hidEvent.value;
108 }
109
110 static SInt32
111 HIDScaledCalibratedValue(recDevice * pDevice, recElement * pElement,
112 long min, long max)
113 {
114 float deviceScale = max - min;
115 float readScale = pElement->maxReport - pElement->minReport;
116 SInt32 value = HIDGetElementValue(pDevice, pElement);
117 if (readScale == 0)
118 return value; /* no scaling at all */
119 else
120 return ((value - pElement->minReport) * deviceScale / readScale) +
121 min;
122 }
123
124
125 static void
126 HIDRemovalCallback(void *target, IOReturn result, void *refcon, void *sender)
127 {
128 recDevice *device = (recDevice *) refcon;
129 device->removed = 1;
130 s_bDeviceRemoved = SDL_TRUE;
131 }
132
133
134 /* Called by the io port notifier on removal of this device
135 */
136 void JoystickDeviceWasRemovedCallback( void * refcon, io_service_t service, natural_t messageType, void * messageArgument )
137 {
138 if( messageType == kIOMessageServiceIsTerminated && refcon )
139 {
140 recDevice *device = (recDevice *) refcon;
141 device->removed = 1;
142 s_bDeviceRemoved = SDL_TRUE;
143 }
144 }
145
146
147 /* Create and open an interface to device, required prior to extracting values or building queues.
148 * Note: application now owns the device and must close and release it prior to exiting
149 */
150
151 static IOReturn
152 HIDCreateOpenDeviceInterface(io_object_t hidDevice, recDevice * pDevice)
153 {
154 IOReturn result = kIOReturnSuccess;
155 HRESULT plugInResult = S_OK;
156 SInt32 score = 0;
157 IOCFPlugInInterface **ppPlugInInterface = NULL;
158
159 if (NULL == pDevice->interface) {
160 result =
161 IOCreatePlugInInterfaceForService(hidDevice,
162 kIOHIDDeviceUserClientTypeID,
163 kIOCFPlugInInterfaceID,
164 &ppPlugInInterface, &score);
165 if (kIOReturnSuccess == result) {
166 /* Call a method of the intermediate plug-in to create the device interface */
167 plugInResult =
168 (*ppPlugInInterface)->QueryInterface(ppPlugInInterface,
169 CFUUIDGetUUIDBytes
170 (kIOHIDDeviceInterfaceID),
171 (void *)
172 &(pDevice->interface));
173 if (S_OK != plugInResult)
174 HIDReportErrorNum
175 ("Couldn't query HID class device interface from plugInInterface",
176 plugInResult);
177 (*ppPlugInInterface)->Release(ppPlugInInterface);
178 } else
179 HIDReportErrorNum
180 ("Failed to create **plugInInterface via IOCreatePlugInInterfaceForService.",
181 result);
182 }
183 if (NULL != pDevice->interface) {
184 result = (*(pDevice->interface))->open(pDevice->interface, 0);
185 if (kIOReturnSuccess != result)
186 HIDReportErrorNum
187 ("Failed to open pDevice->interface via open.", result);
188 else
189 {
190 pDevice->portIterator = 0;
191
192 /* It's okay if this fails, we have another detection method below */
193 (*(pDevice->interface))->setRemovalCallback(pDevice->interface,
194 HIDRemovalCallback,
195 pDevice, pDevice);
196
197 /* now connect notification for new devices */
198 pDevice->notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
199
200 CFRunLoopAddSource(CFRunLoopGetCurrent(),
201 IONotificationPortGetRunLoopSource(pDevice->notificationPort),
202 kCFRunLoopDefaultMode);
203
204 /* Register for notifications when a serial port is added to the system */
205 result = IOServiceAddInterestNotification(pDevice->notificationPort,
206 hidDevice,
207 kIOGeneralInterest,
208 JoystickDeviceWasRemovedCallback,
209 pDevice,
210 &pDevice->portIterator);
211 if (kIOReturnSuccess != result) {
212 HIDReportErrorNum
213 ("Failed to register for removal callback.", result);
214 }
215 }
216
217 }
218 return result;
219 }
220
221 /* Closes and releases interface to device, should be done prior to exiting application
222 * Note: will have no affect if device or interface do not exist
223 * application will "own" the device if interface is not closed
224 * (device may have to be plug and re-plugged in different location to get it working again without a restart)
225 */
226
227 static IOReturn
228 HIDCloseReleaseInterface(recDevice * pDevice)
229 {
230 IOReturn result = kIOReturnSuccess;
231
232 if ((NULL != pDevice) && (NULL != pDevice->interface)) {
233 /* close the interface */
234 result = (*(pDevice->interface))->close(pDevice->interface);
235 if (kIOReturnNotOpen == result) {
236 /* do nothing as device was not opened, thus can't be closed */
237 } else if (kIOReturnSuccess != result)
238 HIDReportErrorNum("Failed to close IOHIDDeviceInterface.",
239 result);
240 /* release the interface */
241 result = (*(pDevice->interface))->Release(pDevice->interface);
242 if (kIOReturnSuccess != result)
243 HIDReportErrorNum("Failed to release IOHIDDeviceInterface.",
244 result);
245 pDevice->interface = NULL;
246
247 if ( pDevice->portIterator )
248 {
249 IOObjectRelease( pDevice->portIterator );
250 pDevice->portIterator = 0;
251 }
252 }
253 return result;
254 }
255
256 /* extracts actual specific element information from each element CF dictionary entry */
257
258 static void
259 HIDGetElementInfo(CFTypeRef refElement, recElement * pElement)
260 {
261 long number;
262 CFTypeRef refType;
263
264 refType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementCookieKey));
265 if (refType && CFNumberGetValue(refType, kCFNumberLongType, &number))
266 pElement->cookie = (IOHIDElementCookie) number;
267 refType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementMinKey));
268 if (refType && CFNumberGetValue(refType, kCFNumberLongType, &number))
269 pElement->minReport = pElement->min = number;
270 pElement->maxReport = pElement->min;
271 refType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementMaxKey));
272 if (refType && CFNumberGetValue(refType, kCFNumberLongType, &number))
273 pElement->maxReport = pElement->max = number;
274 /*
275 TODO: maybe should handle the following stuff somehow?
276
277 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementScaledMinKey));
278 if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number))
279 pElement->scaledMin = number;
280 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementScaledMaxKey));
281 if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number))
282 pElement->scaledMax = number;
283 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementSizeKey));
284 if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number))
285 pElement->size = number;
286 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementIsRelativeKey));
287 if (refType)
288 pElement->relative = CFBooleanGetValue (refType);
289 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementIsWrappingKey));
290 if (refType)
291 pElement->wrapping = CFBooleanGetValue (refType);
292 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementIsNonLinearKey));
293 if (refType)
294 pElement->nonLinear = CFBooleanGetValue (refType);
295 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementHasPreferedStateKey));
296 if (refType)
297 pElement->preferredState = CFBooleanGetValue (refType);
298 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementHasNullStateKey));
299 if (refType)
300 pElement->nullState = CFBooleanGetValue (refType);
301 */
302 }
303
304 /* examines CF dictionary value in device element hierarchy to determine if it is element of interest or a collection of more elements
305 * if element of interest allocate storage, add to list and retrieve element specific info
306 * if collection then pass on to deconstruction collection into additional individual elements
307 */
308
309 static void
310 HIDAddElement(CFTypeRef refElement, recDevice * pDevice)
311 {
312 recElement *element = NULL;
313 recElement **headElement = NULL;
314 long elementType, usagePage, usage;
315 CFTypeRef refElementType =
316 CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementTypeKey));
317 CFTypeRef refUsagePage =
318 CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementUsagePageKey));
319 CFTypeRef refUsage =
320 CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementUsageKey));
321
322
323 if ((refElementType)
324 &&
325 (CFNumberGetValue(refElementType, kCFNumberLongType, &elementType))) {
326 /* look at types of interest */
327 if ((elementType == kIOHIDElementTypeInput_Misc)
328 || (elementType == kIOHIDElementTypeInput_Button)
329 || (elementType == kIOHIDElementTypeInput_Axis)) {
330 if (refUsagePage
331 && CFNumberGetValue(refUsagePage, kCFNumberLongType,
332 &usagePage) && refUsage
333 && CFNumberGetValue(refUsage, kCFNumberLongType, &usage)) {
334 switch (usagePage) { /* only interested in kHIDPage_GenericDesktop and kHIDPage_Button */
335 case kHIDPage_GenericDesktop:
336 {
337 switch (usage) { /* look at usage to determine function */
338 case kHIDUsage_GD_X:
339 case kHIDUsage_GD_Y:
340 case kHIDUsage_GD_Z:
341 case kHIDUsage_GD_Rx:
342 case kHIDUsage_GD_Ry:
343 case kHIDUsage_GD_Rz:
344 case kHIDUsage_GD_Slider:
345 case kHIDUsage_GD_Dial:
346 case kHIDUsage_GD_Wheel:
347 element = (recElement *)
348 NewPtrClear(sizeof(recElement));
349 if (element) {
350 pDevice->axes++;
351 headElement = &(pDevice->firstAxis);
352 }
353 break;
354 case kHIDUsage_GD_Hatswitch:
355 element = (recElement *)
356 NewPtrClear(sizeof(recElement));
357 if (element) {
358 pDevice->hats++;
359 headElement = &(pDevice->firstHat);
360 }
361 break;
362 }
363 }
364 break;
365 case kHIDPage_Simulation:
366 switch (usage) {
367 case kHIDUsage_Sim_Rudder:
368 case kHIDUsage_Sim_Throttle:
369 element = (recElement *)
370 NewPtrClear(sizeof(recElement));
371 if (element) {
372 pDevice->axes++;
373 headElement = &(pDevice->firstAxis);
374 }
375 break;
376
377 default:
378 break;
379 }
380 break;
381 case kHIDPage_Button:
382 element = (recElement *)
383 NewPtrClear(sizeof(recElement));
384 if (element) {
385 pDevice->buttons++;
386 headElement = &(pDevice->firstButton);
387 }
388 break;
389 default:
390 break;
391 }
392 }
393 } else if (kIOHIDElementTypeCollection == elementType)
394 HIDGetCollectionElements((CFMutableDictionaryRef) refElement,
395 pDevice);
396 }
397
398 if (element && headElement) { /* add to list */
399 recElement *elementPrevious = NULL;
400 recElement *elementCurrent = *headElement;
401 while (elementCurrent && usage >= elementCurrent->usage) {
402 elementPrevious = elementCurrent;
403 elementCurrent = elementCurrent->pNext;
404 }
405 if (elementPrevious) {
406 elementPrevious->pNext = element;
407 } else {
408 *headElement = element;
409 }
410 element->usagePage = usagePage;
411 element->usage = usage;
412 element->pNext = elementCurrent;
413 HIDGetElementInfo(refElement, element);
414 pDevice->elements++;
415 }
416 }
417
418 /* collects information from each array member in device element list (each array member = element) */
419
420 static void
421 HIDGetElementsCFArrayHandler(const void *value, void *parameter)
422 {
423 if (CFGetTypeID(value) == CFDictionaryGetTypeID())
424 HIDAddElement((CFTypeRef) value, (recDevice *) parameter);
425 }
426
427 /* handles retrieval of element information from arrays of elements in device IO registry information */
428
429 static void
430 HIDGetElements(CFTypeRef refElementCurrent, recDevice * pDevice)
431 {
432 CFTypeID type = CFGetTypeID(refElementCurrent);
433 if (type == CFArrayGetTypeID()) { /* if element is an array */
434 CFRange range = { 0, CFArrayGetCount(refElementCurrent) };
435 /* CountElementsCFArrayHandler called for each array member */
436 CFArrayApplyFunction(refElementCurrent, range,
437 HIDGetElementsCFArrayHandler, pDevice);
438 }
439 }
440
441 /* handles extracting element information from element collection CF types
442 * used from top level element decoding and hierarchy deconstruction to flatten device element list
443 */
444
445 static void
446 HIDGetCollectionElements(CFMutableDictionaryRef deviceProperties,
447 recDevice * pDevice)
448 {
449 CFTypeRef refElementTop =
450 CFDictionaryGetValue(deviceProperties, CFSTR(kIOHIDElementKey));
451 if (refElementTop)
452 HIDGetElements(refElementTop, pDevice);
453 }
454
455 /* use top level element usage page and usage to discern device usage page and usage setting appropriate vlaues in device record */
456
457 static void
458 HIDTopLevelElementHandler(const void *value, void *parameter)
459 {
460 CFTypeRef refCF = 0;
461 if (CFGetTypeID(value) != CFDictionaryGetTypeID())
462 return;
463 refCF = CFDictionaryGetValue(value, CFSTR(kIOHIDElementUsagePageKey));
464 if (!CFNumberGetValue
465 (refCF, kCFNumberLongType, &((recDevice *) parameter)->usagePage))
466 SDL_SetError("CFNumberGetValue error retrieving pDevice->usagePage.");
467 refCF = CFDictionaryGetValue(value, CFSTR(kIOHIDElementUsageKey));
468 if (!CFNumberGetValue
469 (refCF, kCFNumberLongType, &((recDevice *) parameter)->usage))
470 SDL_SetError("CFNumberGetValue error retrieving pDevice->usage.");
471 }
472
473 /* extracts device info from CF dictionary records in IO registry */
474
475 static void
476 HIDGetDeviceInfo(io_object_t hidDevice, CFMutableDictionaryRef hidProperties,
477 recDevice * pDevice)
478 {
479 CFMutableDictionaryRef usbProperties = 0;
480 io_registry_entry_t parent1, parent2;
481
482 /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also
483 * get dictionary for USB properties: step up two levels and get CF dictionary for USB properties
484 */
485 if ((KERN_SUCCESS == IORegistryEntryGetParentEntry(hidDevice, kIOServicePlane, &parent1))
486 && (KERN_SUCCESS == IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2))
487 && (KERN_SUCCESS == IORegistryEntryCreateCFProperties(parent2, &usbProperties, kCFAllocatorDefault, kNilOptions))) {
488 if (usbProperties) {
489 CFTypeRef refCF = 0;
490 /* get device info
491 * try hid dictionary first, if fail then go to usb dictionary
492 */
493
494 /* get product name */
495 refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey));
496 if (!refCF) {
497 refCF = CFDictionaryGetValue(usbProperties, CFSTR("USB Product Name"));
498 }
499 if (refCF) {
500 if (!CFStringGetCString(refCF, pDevice->product, 256, CFStringGetSystemEncoding())) {
501 SDL_SetError("CFStringGetCString error retrieving pDevice->product.");
502 }
503 }
504
505 /* get usage page and usage */
506 refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey));
507 if (refCF) {
508 if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usagePage)) {
509 SDL_SetError("CFNumberGetValue error retrieving pDevice->usagePage.");
510 }
511
512 refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsageKey));
513 if (refCF) {
514 if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usage)) {
515 SDL_SetError("CFNumberGetValue error retrieving pDevice->usage.");
516 }
517 }
518 }
519
520 refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDVendorIDKey));
521 if (refCF) {
522 if (!CFNumberGetValue(refCF, kCFNumberLongType, &pDevice->guid.data[0])) {
523 SDL_SetError("CFNumberGetValue error retrieving pDevice->guid[0]");
524 }
525 }
526
527 refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductIDKey));
528 if (refCF) {
529 if (!CFNumberGetValue(refCF, kCFNumberLongType, &pDevice->guid.data[8])) {
530 SDL_SetError("CFNumberGetValue error retrieving pDevice->guid[8]");
531 }
532 }
533
534 /* Check to make sure we have a vendor and product ID
535 If we don't, use the same algorithm as the Linux code for Bluetooth devices */
536 {
537 Uint32 *guid32 = (Uint32*)pDevice->guid.data;
538 if (!guid32[0] && !guid32[1]) {
539 const Uint16 BUS_BLUETOOTH = 0x05;
540 Uint16 *guid16 = (Uint16 *)guid32;
541 *guid16++ = BUS_BLUETOOTH;
542 *guid16++ = 0;
543 SDL_strlcpy((char*)guid16, pDevice->product, sizeof(pDevice->guid.data) - 4);
544 }
545 }
546
547 /* If we don't have a vendor and product ID this is probably a Bluetooth device */
548
549 if (NULL == refCF) { /* get top level element HID usage page or usage */
550 /* use top level element instead */
551 CFTypeRef refCFTopElement = 0;
552 refCFTopElement = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDElementKey));
553 {
554 /* refCFTopElement points to an array of element dictionaries */
555 CFRange range = { 0, CFArrayGetCount(refCFTopElement) };
556 CFArrayApplyFunction(refCFTopElement, range, HIDTopLevelElementHandler, pDevice);
557 }
558 }
559
560 CFRelease(usbProperties);
561 } else {
562 SDL_SetError("IORegistryEntryCreateCFProperties failed to create usbProperties.");
563 }
564
565 if (kIOReturnSuccess != IOObjectRelease(parent2)) {
566 SDL_SetError("IOObjectRelease error with parent2");
567 }
568 if (kIOReturnSuccess != IOObjectRelease(parent1)) {
569 SDL_SetError("IOObjectRelease error with parent1");
570 }
571 }
572 }
573
574
575 static recDevice *
576 HIDBuildDevice(io_object_t hidDevice)
577 {
578 recDevice *pDevice = (recDevice *) NewPtrClear(sizeof(recDevice));
579 if (pDevice) {
580 /* get dictionary for HID properties */
581 CFMutableDictionaryRef hidProperties = 0;
582 kern_return_t result =
583 IORegistryEntryCreateCFProperties(hidDevice, &hidProperties,
584 kCFAllocatorDefault,
585 kNilOptions);
586 if ((result == KERN_SUCCESS) && hidProperties) {
587 /* create device interface */
588 result = HIDCreateOpenDeviceInterface(hidDevice, pDevice);
589 if (kIOReturnSuccess == result) {
590 HIDGetDeviceInfo(hidDevice, hidProperties, pDevice); /* hidDevice used to find parents in registry tree */
591 HIDGetCollectionElements(hidProperties, pDevice);
592 pDevice->instance_id = ++s_joystick_instance_id;
593 } else {
594 DisposePtr((Ptr) pDevice);
595 pDevice = NULL;
596 }
597 CFRelease(hidProperties);
598 } else {
599 DisposePtr((Ptr) pDevice);
600 pDevice = NULL;
601 }
602 }
603 return pDevice;
604 }
605
606 /* disposes of the element list associated with a device and the memory associated with the list
607 */
608
609 static void
610 HIDDisposeElementList(recElement ** elementList)
611 {
612 recElement *pElement = *elementList;
613 while (pElement) {
614 recElement *pElementNext = pElement->pNext;
615 DisposePtr((Ptr) pElement);
616 pElement = pElementNext;
617 }
618 *elementList = NULL;
619 }
620
621 /* disposes of a single device, closing and releaseing interface, freeing memory fro device and elements, setting device pointer to NULL
622 * all your device no longer belong to us... (i.e., you do not 'own' the device anymore)
623 */
624
625 static recDevice *
626 HIDDisposeDevice(recDevice ** ppDevice)
627 {
628 kern_return_t result = KERN_SUCCESS;
629 recDevice *pDeviceNext = NULL;
630 if (*ppDevice) {
631 /* save next device prior to disposing of this device */
632 pDeviceNext = (*ppDevice)->pNext;
633
634 /* free posible io_service_t */
635 if ((*ppDevice)->ffservice) {
636 IOObjectRelease((*ppDevice)->ffservice);
637 (*ppDevice)->ffservice = 0;
638 }
639
640 /* free element lists */
641 HIDDisposeElementList(&(*ppDevice)->firstAxis);
642 HIDDisposeElementList(&(*ppDevice)->firstButton);
643 HIDDisposeElementList(&(*ppDevice)->firstHat);
644
645 result = HIDCloseReleaseInterface(*ppDevice); /* function sanity checks interface value (now application does not own device) */
646 if (kIOReturnSuccess != result)
647 HIDReportErrorNum
648 ("HIDCloseReleaseInterface failed when trying to dipose device.",
649 result);
650 DisposePtr((Ptr) * ppDevice);
651 *ppDevice = NULL;
652 }
653 return pDeviceNext;
654 }
655
656
657 /* Given an io_object_t from OSX adds a joystick device to our list if appropriate
658 */
659 int
660 AddDeviceHelper( io_object_t ioHIDDeviceObject )
661 {
662 recDevice *device;
663
664 /* build a device record */
665 device = HIDBuildDevice(ioHIDDeviceObject);
666 if (!device)
667 return 0;
668
669 /* Filter device list to non-keyboard/mouse stuff */
670 if ((device->usagePage != kHIDPage_GenericDesktop) ||
671 ((device->usage != kHIDUsage_GD_Joystick &&
672 device->usage != kHIDUsage_GD_GamePad &&
673 device->usage != kHIDUsage_GD_MultiAxisController))) {
674
675 /* release memory for the device */
676 HIDDisposeDevice(&device);
677 DisposePtr((Ptr) device);
678 return 0;
679 }
680
681 /* We have to do some storage of the io_service_t for
682 * SDL_HapticOpenFromJoystick */
683 if (FFIsForceFeedback(ioHIDDeviceObject) == FF_OK) {
684 device->ffservice = ioHIDDeviceObject;
685 } else {
686 device->ffservice = 0;
687 }
688
689 device->send_open_event = 1;
690 s_bDeviceAdded = SDL_TRUE;
691
692 /* Add device to the end of the list */
693 if ( !gpDeviceList )
694 {
695 gpDeviceList = device;
696 }
697 else
698 {
699 recDevice *curdevice;
700
701 curdevice = gpDeviceList;
702 while ( curdevice->pNext )
703 {
704 curdevice = curdevice->pNext;
705 }
706 curdevice->pNext = device;
707 }
708
709 return 1;
710 }
711
712
713 /* Called by our IO port notifier on the master port when a HID device is inserted, we iterate
714 * and check for new joysticks
715 */
716 void JoystickDeviceWasAddedCallback( void *refcon, io_iterator_t iterator )
717 {
718 io_object_t ioHIDDeviceObject = 0;
719
720 while ( ( ioHIDDeviceObject = IOIteratorNext(iterator) ) )
721 {
722 if ( ioHIDDeviceObject )
723 {
724 AddDeviceHelper( ioHIDDeviceObject );
725 }
726 }
727 }
728
729
730 /* Function to scan the system for joysticks.
731 * Joystick 0 should be the system default joystick.
732 * This function should return the number of available joysticks, or -1
733 * on an unrecoverable fatal error.
734 */
735 int
736 SDL_SYS_JoystickInit(void)
737 {
738 IOReturn result = kIOReturnSuccess;
739 mach_port_t masterPort = 0;
740 io_iterator_t hidObjectIterator = 0;
741 CFMutableDictionaryRef hidMatchDictionary = NULL;
742 io_object_t ioHIDDeviceObject = 0;
743 io_iterator_t portIterator = 0;
744
745 if (gpDeviceList) {
746 return SDL_SetError("Joystick: Device list already inited.");
747 }
748
749 result = IOMasterPort(bootstrap_port, &masterPort);
750 if (kIOReturnSuccess != result) {
751 return SDL_SetError("Joystick: IOMasterPort error with bootstrap_port.");
752 }
753
754 /* Set up a matching dictionary to search I/O Registry by class name for all HID class devices. */
755 hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
756 if (hidMatchDictionary) {
757 /* Add key for device type (joystick, in this case) to refine the matching dictionary. */
758
759 /* NOTE: we now perform this filtering later
760 UInt32 usagePage = kHIDPage_GenericDesktop;
761 UInt32 usage = kHIDUsage_GD_Joystick;
762 CFNumberRef refUsage = NULL, refUsagePage = NULL;
763
764 refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usage);
765 CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsageKey), refUsage);
766 refUsagePage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usagePage);
767 CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsagePageKey), refUsagePage);
768 */
769 } else {
770 return SDL_SetError
771 ("Joystick: Failed to get HID CFMutableDictionaryRef via IOServiceMatching.");
772 }
773
774 /* Now search I/O Registry for matching devices. */
775 result =
776 IOServiceGetMatchingServices(masterPort, hidMatchDictionary,
777 &hidObjectIterator);
778 /* Check for errors */
779 if (kIOReturnSuccess != result) {
780 return SDL_SetError("Joystick: Couldn't create a HID object iterator.");
781 }
782 if (!hidObjectIterator) { /* there are no joysticks */
783 gpDeviceList = NULL;
784 return 0;
785 }
786 /* IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref. */
787
788 /* build flat linked list of devices from device iterator */
789
790 gpDeviceList = NULL;
791
792 while ((ioHIDDeviceObject = IOIteratorNext(hidObjectIterator))) {
793 AddDeviceHelper( ioHIDDeviceObject );
794 }
795 result = IOObjectRelease(hidObjectIterator); /* release the iterator */
796
797 /* now connect notification for new devices */
798 notificationPort = IONotificationPortCreate(masterPort);
799 hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
800
801 CFRunLoopAddSource(CFRunLoopGetCurrent(),
802 IONotificationPortGetRunLoopSource(notificationPort),
803 kCFRunLoopDefaultMode);
804
805 /* Register for notifications when a serial port is added to the system */
806 result = IOServiceAddMatchingNotification(notificationPort,
807 kIOFirstMatchNotification,
808 hidMatchDictionary,
809 JoystickDeviceWasAddedCallback,
810 NULL,
811 &portIterator);
812 while (IOIteratorNext(portIterator)) {}; /* Run out the iterator or notifications won't start (you can also use it to iterate the available devices). */
813
814 return SDL_SYS_NumJoysticks();
815 }
816
817 /* Function to return the number of joystick devices plugged in right now */
818 int
819 SDL_SYS_NumJoysticks()
820 {
821 recDevice *device = gpDeviceList;
822 int nJoySticks = 0;
823
824 while ( device )
825 {
826 if ( !device->removed )
827 nJoySticks++;
828 device = device->pNext;
829 }
830
831 return nJoySticks;
832 }
833
834 /* Function to cause any queued joystick insertions to be processed
835 */
836 void
837 SDL_SYS_JoystickDetect()
838 {
839 if ( s_bDeviceAdded || s_bDeviceRemoved )
840 {
841 recDevice *device = gpDeviceList;
842 s_bDeviceAdded = SDL_FALSE;
843 s_bDeviceRemoved = SDL_FALSE;
844 int device_index = 0;
845 /* send notifications */
846 while ( device )
847 {
848 if ( device->send_open_event )
849 {
850 device->send_open_event = 0;
851 #if !SDL_EVENTS_DISABLED
852 SDL_Event event;
853 event.type = SDL_JOYDEVICEADDED;
854
855 if (SDL_GetEventState(event.type) == SDL_ENABLE) {
856 event.jdevice.which = device_index;
857 if ((SDL_EventOK == NULL)
858 || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
859 SDL_PushEvent(&event);
860 }
861 }
862 #endif /* !SDL_EVENTS_DISABLED */
863
864 }
865
866 if ( device->removed )
867 {
868 recDevice *removeDevice = device;
869 if ( gpDeviceList == removeDevice )
870 {
871 device = device->pNext;
872 gpDeviceList = device;
873 }
874 else
875 {
876 device = gpDeviceList;
877 while ( device->pNext != removeDevice )
878 {
879 device = device->pNext;
880 }
881
882 device->pNext = removeDevice->pNext;
883 }
884
885 #if !SDL_EVENTS_DISABLED
886 SDL_Event event;
887 event.type = SDL_JOYDEVICEREMOVED;
888
889 if (SDL_GetEventState(event.type) == SDL_ENABLE) {
890 event.jdevice.which = removeDevice->instance_id;
891 if ((SDL_EventOK == NULL)
892 || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
893 SDL_PushEvent(&event);
894 }
895 }
896
897 DisposePtr((Ptr) removeDevice);
898 #endif /* !SDL_EVENTS_DISABLED */
899
900 }
901 else
902 {
903 device = device->pNext;
904 device_index++;
905 }
906 }
907 }
908 }
909
910 SDL_bool
911 SDL_SYS_JoystickNeedsPolling()
912 {
913 return s_bDeviceAdded || s_bDeviceRemoved;
914 }
915
916 /* Function to get the device-dependent name of a joystick */
917 const char *
918 SDL_SYS_JoystickNameForDeviceIndex(int device_index)
919 {
920 recDevice *device = gpDeviceList;
921
922 for (; device_index > 0; device_index--)
923 device = device->pNext;
924
925 return device->product;
926 }
927
928 /* Function to return the instance id of the joystick at device_index
929 */
930 SDL_JoystickID
931 SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
932 {
933 recDevice *device = gpDeviceList;
934 int index;
935
936 for (index = device_index; index > 0; index--)
937 device = device->pNext;
938
939 return device->instance_id;
940 }
941
942 /* Function to open a joystick for use.
943 * The joystick to open is specified by the index field of the joystick.
944 * This should fill the nbuttons and naxes fields of the joystick structure.
945 * It returns 0, or -1 if there is an error.
946 */
947 int
948 SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
949 {
950 recDevice *device = gpDeviceList;
951 int index;
952
953 for (index = device_index; index > 0; index--)
954 device = device->pNext;
955
956 joystick->instance_id = device->instance_id;
957 joystick->hwdata = device;
958 joystick->name = device->product;
959
960 joystick->naxes = device->axes;
961 joystick->nhats = device->hats;
962 joystick->nballs = 0;
963 joystick->nbuttons = device->buttons;
964 return 0;
965 }
966
967 /* Function to query if the joystick is currently attached
968 * It returns 1 if attached, 0 otherwise.
969 */
970 SDL_bool
971 SDL_SYS_JoystickAttached(SDL_Joystick * joystick)
972 {
973 recDevice *device = gpDeviceList;
974
975 while ( device )
976 {
977 if ( joystick->instance_id == device->instance_id )
978 return SDL_TRUE;
979
980 device = device->pNext;
981 }
982
983 return SDL_FALSE;
984 }
985
986 /* Function to update the state of a joystick - called as a device poll.
987 * This function shouldn't update the joystick structure directly,
988 * but instead should call SDL_PrivateJoystick*() to deliver events
989 * and update joystick device state.
990 */
991 void
992 SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
993 {
994 recDevice *device = joystick->hwdata;
995 recElement *element;
996 SInt32 value, range;
997 int i;
998
999 if ( !device )
1000 return;
1001
1002 if (device->removed) { /* device was unplugged; ignore it. */
1003 recDevice *devicelist = gpDeviceList;
1004 joystick->closed = 1;
1005 joystick->uncentered = 1;
1006
1007 if ( devicelist == device )
1008 {
1009 gpDeviceList = device->pNext;
1010 }
1011 else
1012 {
1013 while ( devicelist->pNext != device )
1014 {
1015 devicelist = devicelist->pNext;
1016 }
1017
1018 devicelist->pNext = device->pNext;
1019 }
1020
1021 DisposePtr((Ptr) device);
1022 joystick->hwdata = NULL;
1023
1024 #if !SDL_EVENTS_DISABLED
1025 SDL_Event event;
1026 event.type = SDL_JOYDEVICEREMOVED;
1027
1028 if (SDL_GetEventState(event.type) == SDL_ENABLE) {
1029 event.jdevice.which = joystick->instance_id;
1030 if ((SDL_EventOK == NULL)
1031 || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
1032 SDL_PushEvent(&event);
1033 }
1034 }
1035 #endif /* !SDL_EVENTS_DISABLED */
1036
1037 return;
1038 }
1039
1040 element = device->firstAxis;
1041 i = 0;
1042 while (element) {
1043 value = HIDScaledCalibratedValue(device, element, -32768, 32767);
1044 if (value != joystick->axes[i])
1045 SDL_PrivateJoystickAxis(joystick, i, value);
1046 element = element->pNext;
1047 ++i;
1048 }
1049
1050 element = device->firstButton;
1051 i = 0;
1052 while (element) {
1053 value = HIDGetElementValue(device, element);
1054 if (value > 1) /* handle pressure-sensitive buttons */
1055 value = 1;
1056 if (value != joystick->buttons[i])
1057 SDL_PrivateJoystickButton(joystick, i, value);
1058 element = element->pNext;
1059 ++i;
1060 }
1061
1062 element = device->firstHat;
1063 i = 0;
1064 while (element) {
1065 Uint8 pos = 0;
1066
1067 range = (element->max - element->min + 1);
1068 value = HIDGetElementValue(device, element) - element->min;
1069 if (range == 4) /* 4 position hatswitch - scale up value */
1070 value *= 2;
1071 else if (range != 8) /* Neither a 4 nor 8 positions - fall back to default position (centered) */
1072 value = -1;
1073 switch (value) {
1074 case 0:
1075 pos = SDL_HAT_UP;
1076 break;
1077 case 1:
1078 pos = SDL_HAT_RIGHTUP;
1079 break;
1080 case 2:
1081 pos = SDL_HAT_RIGHT;
1082 break;
1083 case 3:
1084 pos = SDL_HAT_RIGHTDOWN;
1085 break;
1086 case 4:
1087 pos = SDL_HAT_DOWN;
1088 break;
1089 case 5:
1090 pos = SDL_HAT_LEFTDOWN;
1091 break;
1092 case 6:
1093 pos = SDL_HAT_LEFT;
1094 break;
1095 case 7:
1096 pos = SDL_HAT_LEFTUP;
1097 break;
1098 default:
1099 /* Every other value is mapped to center. We do that because some
1100 * joysticks use 8 and some 15 for this value, and apparently
1101 * there are even more variants out there - so we try to be generous.
1102 */
1103 pos = SDL_HAT_CENTERED;
1104 break;
1105 }
1106 if (pos != joystick->hats[i])
1107 SDL_PrivateJoystickHat(joystick, i, pos);
1108 element = element->pNext;
1109 ++i;
1110 }
1111
1112 return;
1113 }
1114
1115 /* Function to close a joystick after use */
1116 void
1117 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
1118 {
1119 joystick->closed = 1;
1120 }
1121
1122 /* Function to perform any system-specific joystick related cleanup */
1123 void
1124 SDL_SYS_JoystickQuit(void)
1125 {
1126 while (NULL != gpDeviceList)
1127 gpDeviceList = HIDDisposeDevice(&gpDeviceList);
1128
1129 if ( notificationPort )
1130 {
1131 IONotificationPortDestroy( notificationPort );
1132 notificationPort = 0;
1133 }
1134 }
1135
1136
1137 SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
1138 {
1139 recDevice *device = gpDeviceList;
1140 int index;
1141
1142 for (index = device_index; index > 0; index--)
1143 device = device->pNext;
1144
1145 return device->guid;
1146 }
1147
1148 SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick *joystick)
1149 {
1150 return joystick->hwdata->guid;
1151 }
1152
1153 #endif /* SDL_JOYSTICK_IOKIT */
1154
1155 /* vi: set ts=4 sw=4 expandtab: */
SDL_HAT_LEFTDOWN
#define SDL_HAT_LEFTDOWN
Definition: SDL_joystick.h:199
joystick_hwdata::buttons
long buttons
Definition: SDL_sysjoystick_c.h:70
SDL_PushEvent
DECLSPEC int SDLCALL SDL_PushEvent(SDL_Event *event)
Add an event to the event queue.
Definition: SDL_events.c:457
joystick_hwdata::guid
SDL_JoystickGUID guid
Definition: SDL_sysjoystick_c.h:82
SDL_joystick.h
type
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
joystick_hwdata::notificationPort
IONotificationPortRef notificationPort
Definition: SDL_sysjoystick_c.h:62
SDL_PrivateJoystickHat
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Definition: SDL_joystick.c:536
SDL_SYS_NumJoysticks
int SDL_SYS_NumJoysticks()
Definition: SDL_sysjoystick.m:43
NULL
#define NULL
Definition: ftobjs.h:61
joystick_hwdata::portIterator
io_iterator_t portIterator
Definition: SDL_sysjoystick_c.h:63
HRESULT
typedef HRESULT(WINAPI *LPD3DXIMTSIGNALCALLBACK)(CONST D3DXVECTOR2 *uv
recElement::maxReport
long maxReport
Definition: SDL_sysjoystick_c.h:52
recElement::usagePage
long usagePage
Definition: SDL_sysjoystick_c.h:34
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:116
SDL_JOYDEVICEADDED
Definition: SDL_events.h:110
SDL_HAT_RIGHTUP
#define SDL_HAT_RIGHTUP
Definition: SDL_joystick.h:196
SDL_JoystickID
Sint32 SDL_JoystickID
Definition: SDL_joystick.h:72
SDL_TRUE
Definition: SDL_stdinc.h:119
_SDL_Joystick::axes
Sint16 * axes
Definition: SDL_sysjoystick.h:35
SDL_events.h
SDL_PrivateJoystickButton
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
Definition: SDL_joystick.c:610
SDL_ENABLE
#define SDL_ENABLE
Definition: SDL_events.h:688
joystick_hwdata::removed
int removed
Definition: SDL_sysjoystick_c.h:78
SDL_SYS_JoystickQuit
void SDL_SYS_JoystickQuit(void)
Definition: SDL_sysjoystick.m:129
joystick_hwdata::usagePage
long usagePage
Definition: SDL_sysjoystick_c.h:67
SDL_JoystickGUID::data
Uint8 data[16]
Definition: SDL_joystick.h:69
if
if(!yyg->yy_init)
Definition: glslang_lex.cpp:1037
SDL_FALSE
Definition: SDL_stdinc.h:118
_SDL_Joystick::buttons
Uint8 * buttons
Definition: SDL_sysjoystick.h:47
_SDL_Joystick::hats
Uint8 * hats
Definition: SDL_sysjoystick.h:38
SDL_config.h
_SDL_Joystick::hwdata
struct joystick_hwdata * hwdata
Definition: SDL_sysjoystick.h:49
SDL_PrivateJoystickAxis
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:496
_SDL_Joystick::nballs
int nballs
Definition: SDL_sysjoystick.h:40
recElement::pNext
struct recElement * pNext
Definition: SDL_sysjoystick_c.h:54
recElement::cookie
IOHIDElementCookie cookie
Definition: SDL_sysjoystick_c.h:33
joystick_hwdata
Definition: SDL_sysjoystick_c.h:58
SDL_JOYDEVICEREMOVED
Definition: SDL_events.h:111
target
EGLContext EGLenum target
Definition: eglext.h:87
joystick_hwdata::axes
long axes
Definition: SDL_sysjoystick_c.h:69
range
GLenum GLint * range
Definition: glew.h:3391
Uint32
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
SDL_HAT_RIGHT
#define SDL_HAT_RIGHT
Definition: SDL_joystick.h:193
joystick_hwdata::ffservice
io_service_t ffservice
Definition: SDL_sysjoystick_c.h:60
result
GLuint64EXT * result
Definition: glew.h:12708
SDL_HAT_RIGHTDOWN
#define SDL_HAT_RIGHTDOWN
Definition: SDL_joystick.h:197
joystick_hwdata::send_open_event
Uint8 send_open_event
Definition: SDL_sysjoystick_c.h:83
SDL_GetEventState
#define SDL_GetEventState(type)
Definition: SDL_events.h:701
joystick_hwdata::product
char product[256]
Definition: SDL_sysjoystick_c.h:65
SDL_HAT_LEFT
#define SDL_HAT_LEFT
Definition: SDL_joystick.h:195
recElement::min
long min
Definition: SDL_sysjoystick_c.h:35
_SDL_Joystick::uncentered
Uint8 uncentered
Definition: SDL_sysjoystick.h:54
SDL_SYS_JoystickAttached
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:87
SDL_EventOK
SDL_EventFilter SDL_EventOK
Definition: SDL_events.c:40
joystick_hwdata::usage
long usage
Definition: SDL_sysjoystick_c.h:66
SDL_strlcpy
DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen)
Definition: SDL_string.c:448
recElement::max
long max
Definition: SDL_sysjoystick_c.h:36
SDL_SYS_JoystickDetect
void SDL_SYS_JoystickDetect()
Definition: SDL_sysjoystick.m:48
SDL_SetError
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
SDL_SYS_JoystickNameForDeviceIndex
const char * SDL_SYS_JoystickNameForDeviceIndex(int device_index)
Definition: SDL_sysjoystick.m:59
index
GLuint index
Definition: glew.h:1800
joystick_hwdata::elements
long elements
Definition: SDL_sysjoystick_c.h:72
joystick_hwdata::hats
long hats
Definition: SDL_sysjoystick_c.h:71
joystick_hwdata::pNext
struct joystick_hwdata * pNext
Definition: SDL_sysjoystick_c.h:85
SDL_SYS_JoystickUpdate
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:98
SDL_SYS_JoystickGetGUID
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:143
joystick_hwdata::firstAxis
recElement * firstAxis
Definition: SDL_sysjoystick_c.h:74
SDL_SYS_JoystickNeedsPolling
SDL_bool SDL_SYS_JoystickNeedsPolling()
Definition: SDL_sysjoystick.m:52
SDL_SYS_JoystickInit
int SDL_SYS_JoystickInit(void)
Definition: SDL_sysjoystick.m:38
SDL_EventOKParam
void * SDL_EventOKParam
Definition: SDL_events.c:41
_SDL_Joystick::name
char * name
Definition: SDL_sysjoystick.h:32
joystick_hwdata::firstHat
recElement * firstHat
Definition: SDL_sysjoystick_c.h:76
value
EGLSurface EGLint void ** value
Definition: eglext.h:301
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
SDL_HAT_LEFTUP
#define SDL_HAT_LEFTUP
Definition: SDL_joystick.h:198
SDL_JoystickGUID
Definition: SDL_joystick.h:68
_SDL_Joystick
Definition: SDL_sysjoystick.h:29
recElement
Definition: SDL_sysjoystick_c.h:31
SDL_SYS_GetInstanceIdOfDeviceIndex
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
Definition: SDL_sysjoystick.m:65
recElement::usage
long usage
Definition: SDL_sysjoystick_c.h:34
SDL_SYS_JoystickOpen
int SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index)
Definition: SDL_sysjoystick.m:76
Uint16
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:137
SDL_Event
General event structure.
Definition: SDL_events.h:495
_SDL_Joystick::nbuttons
int nbuttons
Definition: SDL_sysjoystick.h:46
min
#define min(x, y)
Definition: os.h:75
joystick_hwdata::firstButton
recElement * firstButton
Definition: SDL_sysjoystick_c.h:75
_SDL_Joystick::closed
Uint8 closed
Definition: SDL_sysjoystick.h:53
i
int i
Definition: pngrutil.c:1377
SDL_HAT_CENTERED
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:191
SDL_SYS_JoystickClose
void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:119
max
#define max(x, y)
Definition: os.h:79
SDL_HAT_UP
#define SDL_HAT_UP
Definition: SDL_joystick.h:192
joystick_hwdata::interface
IOHIDDeviceInterface ** interface
Definition: SDL_sysjoystick_c.h:61
SDL_HAT_DOWN
#define SDL_HAT_DOWN
Definition: SDL_joystick.h:194
_SDL_Joystick::naxes
int naxes
Definition: SDL_sysjoystick.h:34
usage
GLsizeiptr const GLvoid GLenum usage
Definition: glew.h:1667
_SDL_Joystick::instance_id
SDL_JoystickID instance_id
Definition: SDL_sysjoystick.h:31
SDL_SYS_JoystickGetDeviceGUID
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index)
Definition: SDL_sysjoystick.m:133
recElement::minReport
long minReport
Definition: SDL_sysjoystick_c.h:51
SDL_Event::type
Uint32 type
Definition: SDL_events.h:497
joystick_hwdata::instance_id
int instance_id
Definition: SDL_sysjoystick_c.h:81
_SDL_Joystick::nhats
int nhats
Definition: SDL_sysjoystick.h:37
event
cl_event event
Definition: glew.h:3556