Пример #1
0
static HRESULT get_ff(IOHIDDeviceRef device, FFDeviceObjectReference *ret)
{
    io_service_t service;
    CFMutableDictionaryRef matching;
    CFTypeRef type;

    matching = IOServiceMatching(kIOHIDDeviceKey);
    if(!matching) {
        WARN("IOServiceMatching failed, force feedback disabled\n");
        return DIERR_DEVICENOTREG;
    }

    type = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDLocationIDKey));
    if(!matching) {
        CFRelease(matching);
        WARN("IOHIDDeviceGetProperty failed, force feedback disabled\n");
        return DIERR_DEVICENOTREG;
    }

    CFDictionaryAddValue(matching, CFSTR(kIOHIDLocationIDKey), type);

    service = IOServiceGetMatchingService(kIOMasterPortDefault, matching);

    if(!ret)
        return FFIsForceFeedback(service) == FF_OK ? S_OK : S_FALSE;

    return osx_to_win32_hresult(FFCreateDevice(service, ret));
}
Пример #2
0
static void
JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef ioHIDDeviceObject)
{
    recDevice *device;

    if (res != kIOReturnSuccess) {
        return;
    }

    if (JoystickAlreadyKnown(ioHIDDeviceObject)) {
        return;  /* IOKit sent us a duplicate. */
    }

    device = (recDevice *) SDL_calloc(1, sizeof(recDevice));

    if (!device) {
        SDL_OutOfMemory();
        return;
    }

    if (!GetDeviceInfo(ioHIDDeviceObject, device)) {
        SDL_free(device);
        return;   /* not a device we care about, probably. */
    }

    /* Get notified when this device is disconnected. */
    IOHIDDeviceRegisterRemovalCallback(ioHIDDeviceObject, JoystickDeviceWasRemovedCallback, device);
    IOHIDDeviceScheduleWithRunLoop(ioHIDDeviceObject, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE);

    /* 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 (IOHIDDeviceGetService != NULL) {  /* weak reference: available in 10.6 and later. */
        const io_service_t ioservice = IOHIDDeviceGetService(ioHIDDeviceObject);
        if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) {
            device->ffservice = ioservice;
#if SDL_HAPTIC_IOKIT
            MacHaptic_MaybeAddDevice(ioservice);
#endif
        }
    }

    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;
    }
}
Пример #3
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;
}
Пример #4
0
void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) {

	if (p_res != kIOReturnSuccess || have_device(p_device)) {
		return;
	}

	joypad new_joypad;
	if (is_joypad(p_device)) {
		configure_joypad(p_device, &new_joypad);
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
		if (IOHIDDeviceGetService != NULL) {
#endif
			const io_service_t ioservice = IOHIDDeviceGetService(p_device);
			if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK) && new_joypad.config_force_feedback(ioservice)) {
				new_joypad.ffservice = ioservice;
			}
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
		}
#endif
		device_list.push_back(new_joypad);
	}
	IOHIDDeviceRegisterRemovalCallback(p_device, joypad_removed_callback, (void *)(intptr_t)new_joypad.id);
	IOHIDDeviceScheduleWithRunLoop(p_device, CFRunLoopGetCurrent(), GODOT_JOY_LOOP_RUN_MODE);
}
Пример #5
0
int
MacHaptic_MaybeAddDevice( io_object_t device )
{
    IOReturn result;
    CFMutableDictionaryRef hidProperties;
    CFTypeRef refCF;
    SDL_hapticlist_item *item;

    if (numhaptics == -1) {
        return -1; /* not initialized. We'll pick these up on enumeration if we init later. */
    }

    /* Check for force feedback. */
    if (FFIsForceFeedback(device) != FF_OK) {
        return -1;
    }

    /* Make sure we don't already have it */
    for (item = SDL_hapticlist; item ; item = item->next)
    {
        if (IOObjectIsEqualTo((io_object_t) item->dev, device)) {
            /* Already added */
            return -1;
        }
    }

    item = (SDL_hapticlist_item *)SDL_calloc(1, sizeof(SDL_hapticlist_item));
    if (item == NULL) {
        return SDL_SetError("Could not allocate haptic storage");
    }

    /* retain it as we are going to keep it around a while */
    IOObjectRetain(device);

    /* Set basic device data. */
    HIDGetDeviceProduct(device, item->name);
    item->dev = device;

    /* Set usage pages. */
    hidProperties = 0;
    refCF = 0;
    result = IORegistryEntryCreateCFProperties(device,
                                               &hidProperties,
                                               kCFAllocatorDefault,
                                               kNilOptions);
    if ((result == KERN_SUCCESS) && hidProperties) {
        refCF = CFDictionaryGetValue(hidProperties,
                                     CFSTR(kIOHIDPrimaryUsagePageKey));
        if (refCF) {
            if (!CFNumberGetValue(refCF, kCFNumberLongType, &item->usagePage)) {
                SDL_SetError("Haptic: Receiving device's usage page.");
            }
            refCF = CFDictionaryGetValue(hidProperties,
                                         CFSTR(kIOHIDPrimaryUsageKey));
            if (refCF) {
                if (!CFNumberGetValue(refCF, kCFNumberLongType, &item->usage)) {
                    SDL_SetError("Haptic: Receiving device's usage.");
                }
            }
        }
        CFRelease(hidProperties);
    }

    if (SDL_hapticlist_tail == NULL) {
        SDL_hapticlist = SDL_hapticlist_tail = item;
    } else {
        SDL_hapticlist_tail->next = item;
        SDL_hapticlist_tail = item;
    }

    /* Device has been added. */
    ++numhaptics;

    return numhaptics;
}
Пример #6
0
/*
 * Initializes the haptic subsystem.
 */
int
SDL_SYS_HapticInit(void)
{
    int numhaptics;
    IOReturn result;
    io_iterator_t iter;
    CFDictionaryRef match;
    io_service_t device;
    CFMutableDictionaryRef hidProperties;
    CFTypeRef refCF;

    /* Clear all the memory. */
    SDL_memset(SDL_hapticlist, 0, sizeof(SDL_hapticlist));

    /* Get HID devices. */
    match = IOServiceMatching(kIOHIDDeviceKey);
    if (match == NULL) {
        return SDL_SetError("Haptic: Failed to get IOServiceMatching.");
    }

    /* Now search I/O Registry for matching devices. */
    result = IOServiceGetMatchingServices(kIOMasterPortDefault, match, &iter);
    if (result != kIOReturnSuccess) {
        return SDL_SetError("Haptic: Couldn't create a HID object iterator.");
    }
    /* IOServiceGetMatchingServices consumes dictionary. */

    if (!IOIteratorIsValid(iter)) {     /* No iterator. */
        return 0;
    }

    numhaptics = 0;
    while ((device = IOIteratorNext(iter)) != IO_OBJECT_NULL) {

        /* Check for force feedback. */
        if (FFIsForceFeedback(device) == FF_OK) {

            /* Set basic device data. */
            HIDGetDeviceProduct(device, SDL_hapticlist[numhaptics].name);
            SDL_hapticlist[numhaptics].dev = device;
            SDL_hapticlist[numhaptics].haptic = NULL;

            /* Set usage pages. */
            hidProperties = 0;
            refCF = 0;
            result = IORegistryEntryCreateCFProperties(device,
                                                       &hidProperties,
                                                       kCFAllocatorDefault,
                                                       kNilOptions);
            if ((result == KERN_SUCCESS) && hidProperties) {
                refCF =
                    CFDictionaryGetValue(hidProperties,
                                         CFSTR(kIOHIDPrimaryUsagePageKey));
                if (refCF) {
                    if (!CFNumberGetValue(refCF, kCFNumberLongType,
                                          &SDL_hapticlist[numhaptics].
                                          usagePage))
                        SDL_SetError
                            ("Haptic: Recieving device's usage page.");
                    refCF =
                        CFDictionaryGetValue(hidProperties,
                                             CFSTR(kIOHIDPrimaryUsageKey));
                    if (refCF) {
                        if (!CFNumberGetValue(refCF, kCFNumberLongType,
                                              &SDL_hapticlist[numhaptics].
                                              usage))
                            SDL_SetError("Haptic: Recieving device's usage.");
                    }
                }
                CFRelease(hidProperties);
            }

            /* Device has been added. */
            numhaptics++;
        } else {                /* Free the unused device. */
            IOObjectRelease(device);
        }

        /* Reached haptic limit. */
        if (numhaptics >= MAX_HAPTICS)
            break;
    }
    IOObjectRelease(iter);

    return numhaptics;
}
/* 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;
    recDevice *device, *lastDevice;
    io_object_t ioHIDDeviceObject = 0;

    SDL_numjoysticks = 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;
        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;

        /* 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);
            continue;
        }

        /* 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;
        }

        /* 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;
}
Пример #8
0
static void
JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef ioHIDDeviceObject)
{
    recDevice *device;
    int device_index = 0;

    if (res != kIOReturnSuccess) {
        return;
    }

    if (JoystickAlreadyKnown(ioHIDDeviceObject)) {
        return;  /* IOKit sent us a duplicate. */
    }

    device = (recDevice *) SDL_calloc(1, sizeof(recDevice));

    if (!device) {
        SDL_OutOfMemory();
        return;
    }

    if (!GetDeviceInfo(ioHIDDeviceObject, device)) {
        SDL_free(device);
        return;   /* not a device we care about, probably. */
    }

    /* Get notified when this device is disconnected. */
    IOHIDDeviceRegisterRemovalCallback(ioHIDDeviceObject, JoystickDeviceWasRemovedCallback, device);
    IOHIDDeviceScheduleWithRunLoop(ioHIDDeviceObject, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE);

    /* 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 MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    if (IOHIDDeviceGetService != NULL) {  /* weak reference: available in 10.6 and later. */
#endif

        const io_service_t ioservice = IOHIDDeviceGetService(ioHIDDeviceObject);
#if SDL_HAPTIC_IOKIT
        if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) {
            device->ffservice = ioservice;
            MacHaptic_MaybeAddDevice(ioservice);
        }
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    }
#endif

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

        curdevice = gpDeviceList;
        while ( curdevice->pNext ) {
            ++device_index;
            curdevice = curdevice->pNext;
        }
        curdevice->pNext = device;
        ++device_index;  /* bump by one since we counted by pNext. */
    }

/* !!! FIXME: why isn't there an SDL_PrivateJoyDeviceAdded()? */
#if !SDL_EVENTS_DISABLED
    {
        SDL_Event event;
        event.type = SDL_JOYDEVICEADDED;

        if (SDL_GetEventState(event.type) == SDL_ENABLE) {
            event.jdevice.which = device_index;
            if ((SDL_EventOK == NULL)
                || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
                SDL_PushEvent(&event);
            }
        }
    }
#endif /* !SDL_EVENTS_DISABLED */
}
Пример #9
0
static void
JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef ioHIDDeviceObject)
{
    recDevice *device;
    int device_index = 0;
    io_service_t ioservice;

    if (res != kIOReturnSuccess) {
        return;
    }

    if (JoystickAlreadyKnown(ioHIDDeviceObject)) {
        return;  /* IOKit sent us a duplicate. */
    }

    device = (recDevice *) SDL_calloc(1, sizeof(recDevice));

    if (!device) {
        SDL_OutOfMemory();
        return;
    }

    if (!GetDeviceInfo(ioHIDDeviceObject, device)) {
        SDL_free(device);
        return;   /* not a device we care about, probably. */
    }

    if (SDL_IsGameControllerNameAndGUID(device->product, device->guid) &&
        SDL_ShouldIgnoreGameController(device->product, device->guid)) {
        SDL_free(device);
        return;
    }

    /* Get notified when this device is disconnected. */
    IOHIDDeviceRegisterRemovalCallback(ioHIDDeviceObject, JoystickDeviceWasRemovedCallback, device);
    IOHIDDeviceScheduleWithRunLoop(ioHIDDeviceObject, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE);

    /* 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 */
    ioservice = IOHIDDeviceGetService(ioHIDDeviceObject);
#if SDL_HAPTIC_IOKIT
    if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) {
        device->ffservice = ioservice;
        MacHaptic_MaybeAddDevice(ioservice);
    }
#endif

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

        curdevice = gpDeviceList;
        while ( curdevice->pNext ) {
            ++device_index;
            curdevice = curdevice->pNext;
        }
        curdevice->pNext = device;
        ++device_index;  /* bump by one since we counted by pNext. */
    }

    SDL_PrivateJoystickAdded(device_index);
}