示例#1
0
/*
 * Checks to see if the haptic device and joystick and in reality the same.
 */
int
SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
{
    if (IOObjectIsEqualTo((io_object_t) ((size_t)haptic->hwdata->device),
                          joystick->hwdata->ffservice))
        return 1;
    return 0;
}
示例#2
0
/*
 * Opens a SDL_Haptic from a SDL_Joystick.
 */
int
SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
{
    int device_index = 0;
    SDL_hapticlist_item *item;

    for (item = SDL_hapticlist; item; item = item->next) {
        if (IOObjectIsEqualTo((io_object_t) item->dev,
                             joystick->hwdata->ffservice)) {
           haptic->index = device_index;
           break;
        }
        ++device_index;
    }

    return SDL_SYS_HapticOpenFromService(haptic, joystick->hwdata->ffservice);
}
示例#3
0
/*
 * Opens a SDL_Haptic from a SDL_Joystick.
 */
int
SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
{
    int i;
    for (i=0; i<SDL_numhaptics; i++) {
       if (IOObjectIsEqualTo((io_object_t) SDL_hapticlist[i].dev,
                             joystick->hwdata->ffservice)) {
           haptic->index = i;
           break;
       }
    }
    if (i >= SDL_numhaptics) {
       return -1;
    }

    return SDL_SYS_HapticOpenFromService(haptic, joystick->hwdata->ffservice);
}
示例#4
0
int
MacHaptic_MaybeRemoveDevice( io_object_t device )
{
    SDL_hapticlist_item *item;
    SDL_hapticlist_item *prev = NULL;

    if (numhaptics == -1) {
        return -1; /* not initialized. ignore this. */
    }

    for (item = SDL_hapticlist; item != NULL; item = item->next) {
        /* found it, remove it. */
        if (IOObjectIsEqualTo((io_object_t) item->dev, device)) {
            const int retval = item->haptic ? item->haptic->index : -1;

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

            /* Need to decrement the haptic count */
            --numhaptics;
            /* !!! TODO: Send a haptic remove event? */

            IOObjectRelease(item->dev);
            SDL_free(item);
            return retval;
        }
        prev = item;
    }

    return -1;
}
示例#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;
}
// first look up the media object, then create a
// custom matching dictionary that should be persistent
// from boot to boot
int addMatchingInfoForBSDName(BLContextPtr context,
			      mach_port_t masterPort,
			      CFMutableDictionaryRef dict,
			      const char *bsdName,
                  bool shortForm)
{
    io_service_t                media = IO_OBJECT_NULL, checkMedia = IO_OBJECT_NULL;
    CFStringRef                 uuid = NULL;
    CFMutableDictionaryRef      propDict = NULL;
    kern_return_t               kret;
    CFStringRef			lastBSDName = NULL;

    lastBSDName = CFStringCreateWithCString(kCFAllocatorDefault,
					    bsdName,
					    kCFStringEncodingUTF8);

    propDict = IOBSDNameMatching(masterPort, 0, bsdName);
    CFDictionarySetValue(propDict, CFSTR(kIOProviderClassKey), CFSTR(kIOMediaClass));
    
    media = IOServiceGetMatchingService(masterPort,
                                        propDict);
    propDict = NULL;
    
    if(media == IO_OBJECT_NULL) {
        contextprintf(context, kBLLogLevelError, "Could not find object for %s\n", bsdName);
        CFRelease(lastBSDName);
        return 1;
    }
    
    uuid = IORegistryEntryCreateCFProperty(media, CFSTR(kIOMediaUUIDKey),
                                           kCFAllocatorDefault, 0);
    if(uuid == NULL) {
        CFUUIDRef       fsuuid = NULL;
		CFStringRef     fsuuidstr = NULL;        
		io_string_t path;
#if USE_DISKARBITRATION
        DASessionRef    session = NULL;
        DADiskRef       dadisk = NULL;
		
        contextprintf(context, kBLLogLevelVerbose, "IOMedia %s does not have a partition %s\n",
                      bsdName, kIOMediaUUIDKey);
		
        session = DASessionCreate(kCFAllocatorDefault);
        if(session) {
            dadisk = DADiskCreateFromIOMedia(kCFAllocatorDefault, session, 
                                             media);
            if(dadisk) {
                CFDictionaryRef descrip = DADiskCopyDescription(dadisk);
                if(descrip) {
                    fsuuid = CFDictionaryGetValue(descrip, kDADiskDescriptionVolumeUUIDKey);
                    
                    if(fsuuid)
                        CFRetain(fsuuid);
                    CFRelease(descrip);
                }
                
                CFRelease(dadisk);
            }
            
            CFRelease(session);
        }
#endif // USE_DISKARBITRATION
		
        if(fsuuid) {
            char        fsuuidCString[64];
			
            fsuuidstr = CFUUIDCreateString(kCFAllocatorDefault, fsuuid);
            
            CFStringGetCString(fsuuidstr,fsuuidCString,sizeof(fsuuidCString),kCFStringEncodingUTF8);
            
            contextprintf(context, kBLLogLevelVerbose, "DADiskRef %s has Volume UUID %s\n",
                          bsdName, fsuuidCString);
            
            CFRelease(fsuuid);
		} else {
            contextprintf(context, kBLLogLevelVerbose, "IOMedia %s does not have a Volume UUID\n",
                          bsdName);
		}
		
		
		// we have a volume UUID, but our primary matching mechanism will be the device path
		
		kret = IORegistryEntryGetPath(media, kIODeviceTreePlane,path);
		if(kret) {
			contextprintf(context, kBLLogLevelVerbose, "IOMedia %s does not have device tree path\n",
						  bsdName);
			
			propDict = IOServiceMatching(kIOMediaClass);
			CFDictionaryAddValue(propDict,  CFSTR(kIOBSDNameKey), lastBSDName);
			
			// add UUID as hint
			if(fsuuidstr)
				CFDictionaryAddValue(dict, CFSTR("BLVolumeUUID"), fsuuidstr);
			
		} else {
			CFStringRef blpath = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8);
			
			contextprintf(context, kBLLogLevelVerbose, "IOMedia %s has path %s\n",
						  bsdName, path);
			
			propDict = IOServiceMatching(kIOMediaClass);
			CFDictionaryAddValue(propDict, CFSTR(kIOPathMatchKey), blpath);
			CFRelease(blpath);
			
			// add UUID as hint
			if(fsuuidstr)
				CFDictionaryAddValue(dict, CFSTR("BLVolumeUUID"), fsuuidstr);
			
			CFDictionaryAddValue(dict, CFSTR("BLLastBSDName"), lastBSDName);
		}
		
		if(fsuuidstr) {
			CFRelease(fsuuidstr);
		}
		
    } else {
      CFMutableDictionaryRef propMatch;

        contextprintf(context, kBLLogLevelVerbose, "IOMedia %s has UUID %s\n",
                      bsdName, BLGetCStringDescription(uuid));

        propMatch = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                              &kCFTypeDictionaryKeyCallBacks,
                              &kCFTypeDictionaryValueCallBacks);
        CFDictionaryAddValue(propMatch, CFSTR(kIOMediaUUIDKey), uuid);

        propDict = IOServiceMatching(kIOMediaClass);
        CFDictionaryAddValue(propDict,  CFSTR(kIOPropertyMatchKey), propMatch);
        CFRelease(propMatch);

        // add a hint to the top-level dict
        CFDictionaryAddValue(dict, CFSTR("BLLastBSDName"), lastBSDName);

        CFRelease(uuid);
    }

    // verify the dictionary matches
    CFRetain(propDict); // consumed below
    checkMedia = IOServiceGetMatchingService(masterPort,
					     propDict);
    
    if(IO_OBJECT_NULL == checkMedia
       || !IOObjectIsEqualTo(media, checkMedia)) {
      contextprintf(context, kBLLogLevelVerbose, "Inconsistent registry entries for %s\n",
		    bsdName);
      
      if(IO_OBJECT_NULL != checkMedia) IOObjectRelease(checkMedia);
      IOObjectRelease(media);
      CFRelease(lastBSDName);
      CFRelease(propDict);
      
      return 2;
    }
    
    IOObjectRelease(checkMedia);
    IOObjectRelease(media);

    CFDictionaryAddValue(dict, CFSTR("IOMatch"), propDict);        
    CFRelease(lastBSDName);
    CFRelease(propDict);

    if(shortForm) {
        CFDictionaryAddValue(dict, CFSTR("IOEFIShortForm"), kCFBooleanTrue);
    }
    
    return 0;
}