Пример #1
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;
}
Пример #2
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;
}