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