/* Function to scan the system for joysticks. * Joystick 0 should be the system default joystick. * This function should return the number of available joysticks, or -1 * on an unrecoverable fatal error. */ int SDL_SYS_JoystickInit(void) { if (gpDeviceList) { return SDL_SetError("Joystick: Device list already inited."); } if (!CreateHIDManager()) { return SDL_SetError("Joystick: Couldn't initialize HID Manager"); } return SDL_SYS_NumJoysticks(); }
/* * Count the number of joysticks attached to the system */ int SDL_NumJoysticks(void) { return SDL_SYS_NumJoysticks(); }
/* Function to scan the system for joysticks. * Joystick 0 should be the system default joystick. * This function should return the number of available joysticks, or -1 * on an unrecoverable fatal error. */ int SDL_SYS_JoystickInit(void) { IOReturn result = kIOReturnSuccess; mach_port_t masterPort = 0; io_iterator_t hidObjectIterator = 0; CFMutableDictionaryRef hidMatchDictionary = NULL; io_object_t ioHIDDeviceObject = 0; io_iterator_t portIterator = 0; if (gpDeviceList) { SDL_SetError("Joystick: Device list already inited."); return -1; } result = IOMasterPort(bootstrap_port, &masterPort); if (kIOReturnSuccess != result) { SDL_SetError("Joystick: IOMasterPort error with bootstrap_port."); return -1; } /* Set up a matching dictionary to search I/O Registry by class name for all HID class devices. */ hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); if (hidMatchDictionary) { /* Add key for device type (joystick, in this case) to refine the matching dictionary. */ /* NOTE: we now perform this filtering later UInt32 usagePage = kHIDPage_GenericDesktop; UInt32 usage = kHIDUsage_GD_Joystick; CFNumberRef refUsage = NULL, refUsagePage = NULL; refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usage); CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsageKey), refUsage); refUsagePage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usagePage); CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsagePageKey), refUsagePage); */ } else { SDL_SetError ("Joystick: Failed to get HID CFMutableDictionaryRef via IOServiceMatching."); return -1; } /*/ Now search I/O Registry for matching devices. */ result = IOServiceGetMatchingServices(masterPort, hidMatchDictionary, &hidObjectIterator); /* Check for errors */ if (kIOReturnSuccess != result) { SDL_SetError("Joystick: Couldn't create a HID object iterator."); return -1; } if (!hidObjectIterator) { /* there are no joysticks */ gpDeviceList = NULL; return 0; } /* IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref. */ /* build flat linked list of devices from device iterator */ gpDeviceList = NULL; while ((ioHIDDeviceObject = IOIteratorNext(hidObjectIterator))) { AddDeviceHelper( ioHIDDeviceObject ); } result = IOObjectRelease(hidObjectIterator); /* release the iterator */ /* now connect notification for new devices */ notificationPort = IONotificationPortCreate(masterPort); hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notificationPort), kCFRunLoopDefaultMode); // Register for notifications when a serial port is added to the system result = IOServiceAddMatchingNotification(notificationPort, kIOFirstMatchNotification, hidMatchDictionary, JoystickDeviceWasAddedCallback, NULL, &portIterator); while (IOIteratorNext(portIterator)) {}; // Run out the iterator or notifications won't start (you can also use it to iterate the available devices). return SDL_SYS_NumJoysticks(); }