Beispiel #1
0
/* Given an io_object_t from OSX adds a joystick device to our list if appropriate
 */
int
AddDeviceHelper( io_object_t ioHIDDeviceObject )
{
    recDevice *device;

    /* build a device record */
    device = HIDBuildDevice(ioHIDDeviceObject);
    if (!device)
        return 0;

    /* Filter device list to non-keyboard/mouse stuff */
    if ((device->usagePage != kHIDPage_GenericDesktop) ||
            ((device->usage != kHIDUsage_GD_Joystick &&
              device->usage != kHIDUsage_GD_GamePad &&
              device->usage != kHIDUsage_GD_MultiAxisController))) {

        /* release memory for the device */
        HIDDisposeDevice(&device);
        DisposePtr((Ptr) device);
        return 0;
    }

    /* Allocate an instance ID for this device */
    device->instance_id = ++s_joystick_instance_id;

    /* We have to do some storage of the io_service_t for
     * SDL_HapticOpenFromJoystick */
    if (FFIsForceFeedback(ioHIDDeviceObject) == FF_OK) {
        device->ffservice = ioHIDDeviceObject;
    } else {
        device->ffservice = 0;
    }

    device->send_open_event = 1;
    s_bDeviceAdded = SDL_TRUE;

    /* Add device to the end of the list */
    if ( !gpDeviceList )
    {
        gpDeviceList = device;
    }
    else
    {
        recDevice *curdevice;

        curdevice = gpDeviceList;
        while ( curdevice->pNext )
        {
            curdevice = curdevice->pNext;
        }
        curdevice->pNext = device;
    }

    return 1;
}
/* 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 = NULL;
	io_iterator_t hidObjectIterator = NULL;
	CFMutableDictionaryRef hidMatchDictionary = NULL;
	recDevice *device, *lastDevice;
	io_object_t ioHIDDeviceObject = NULL;
	
	SDL_numjoysticks = 0;
	
	if (NULL != 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 != NULL))
	{
		/* 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 (NULL == hidObjectIterator) /* there are no joysticks */
	{
		gpDeviceList = NULL;
		SDL_numjoysticks = 0;
		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 = lastDevice = NULL;
	
	while ((ioHIDDeviceObject = IOIteratorNext (hidObjectIterator)))
	{
		/* build a device record */
		device = HIDBuildDevice (ioHIDDeviceObject);
		if (!device)
			continue;

		/* dump device object, it is no longer needed */
		result = IOObjectRelease (ioHIDDeviceObject);
//		if (KERN_SUCCESS != result)
//			HIDReportErrorNum ("IOObjectRelease error with ioHIDDeviceObject.", result);

		/* Filter device list to non-keyboard/mouse stuff */ 
		if ( (device->usagePage != kHIDPage_GenericDesktop) ||
		     ((device->usage != kHIDUsage_GD_Joystick &&
		      device->usage != kHIDUsage_GD_GamePad)) ) {

			/* release memory for the device */
			HIDDisposeDevice (&device);
			DisposePtr((Ptr)device);
			continue;
		}
		
		/* Add device to the end of the list */
		if (lastDevice)
			lastDevice->pNext = device;
		else
			gpDeviceList = device;
		lastDevice = device;
	}
	result = IOObjectRelease (hidObjectIterator); /* release the iterator */

	/* Count the total number of devices we found */
	device = gpDeviceList;
	while (device)
	{
		SDL_numjoysticks++;
		device = device->pNext;
	}
	
	return SDL_numjoysticks;
}