Example #1
0
CFMutableSetRef
CFSetCreateMutableCopy (CFAllocatorRef allocator, CFIndex capacity,
                        CFSetRef set)
{
  if (CF_IS_OBJC (_kCFSetTypeID, set))
    {
      CFMutableSetRef result;
      const CFIndex count = CFSetGetCount (set);
      void **values =
        (void **) CFAllocatorAllocate (allocator, sizeof (void *) * count, 0);
      CFIndex i;

      CFSetGetValues (set, (const void **) values);
      result = CFSetCreateMutable (allocator, count, &kCFTypeSetCallBacks);

      for (i = 0; i < count; i++)
        GSHashTableAddValue ((GSHashTableRef) result, values[i], values[i]);

      CFAllocatorDeallocate (allocator, (void *) values);
      return result;
    }

  return (CFMutableSetRef) GSHashTableCreateMutableCopy (allocator,
                                                         (GSHashTableRef) set,
                                                         capacity);
}
Example #2
0
CFSetRef CFSetCreateCopy(CFAllocatorRef allocator, CFSetRef set) {
    CFSetRef result;
    const CFSetCallBacks *cb;
    CFIndex numValues = CFSetGetCount(set);
    const void **list, *buffer[256];
    list = (numValues <= 256) ? buffer : CFAllocatorAllocate(allocator, numValues * sizeof(void *), 0);
    if (list != buffer && __CFOASafe) __CFSetLastAllocationEventName(list, "CFSet (temp)");
    CFSetGetValues(set, list);
    cb = CF_IS_OBJC(__kCFSetTypeID, set) ? &kCFTypeSetCallBacks : __CFSetGetCallBacks(set);
    result = CFSetCreate(allocator, list, numValues, cb);
    if (list != buffer) CFAllocatorDeallocate(allocator, list);
    return result;
}
bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor)
{
    if (!initializeManager())
    {
        return false;
    }
    

	CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager);
	CFIndex deviceCount = CFSetGetCount(deviceSet);
    
    // Allocate a block of memory and read the set into it.
    IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount);
    CFSetGetValues(deviceSet, (const void **) devices);
    

    // Iterate over devices.
    for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
    {
        IOHIDDeviceRef hidDev = devices[deviceIndex];
        
        if (!hidDev)
        {
            continue;
        }
        
        HIDDeviceDesc devDesc;
                
        if (getPath(hidDev, &(devDesc.Path)) &&
            initVendorProductVersion(hidDev, &devDesc) &&
            enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId) &&
            initUsage(hidDev, &devDesc))
        {
            initStrings(hidDev, &devDesc);
            initSerialNumber(hidDev, &devDesc);

            // Construct minimal device that the visitor callback can get feature reports from.
            OSX::HIDDevice device(this, hidDev);
            
            enumVisitor->Visit(device, devDesc);
        }
    }
    
    OVR_FREE(devices);
    CFRelease(deviceSet);
    
    return true;
}
Example #4
0
IOHIDDeviceRef FindDevice(IOHIDManagerRef manager, long vendorId, long productId)
{
    IOHIDDeviceRef theDevice = NULL;

    // setup dictionary

    CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(
                                              kCFAllocatorDefault, 
                                              2, 
                                              &kCFTypeDictionaryKeyCallBacks, 
                                              &kCFTypeDictionaryValueCallBacks);

    CFNumberRef cfVendorId = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongType, &vendorId);
    CFStringRef cfVendorSt = CFStringCreateWithCString(kCFAllocatorDefault, kIOHIDVendorIDKey, kCFStringEncodingUTF8);
    CFDictionaryAddValue(dictionary, cfVendorSt, cfVendorId);
    CFRelease(cfVendorId);
    CFRelease(cfVendorSt);

    CFNumberRef cfProductId = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongType, &productId);
    CFStringRef cfProductSt = CFStringCreateWithCString(kCFAllocatorDefault, kIOHIDProductIDKey, kCFStringEncodingUTF8);
    CFDictionaryAddValue(dictionary, cfProductSt, cfProductId);
    CFRelease(cfProductId);
    CFRelease(cfProductSt);

    // look for devices matching criteria

    IOHIDManagerSetDeviceMatching(manager, dictionary);
    CFSetRef foundDevices = IOHIDManagerCopyDevices(manager);
    CFIndex foundCount = foundDevices ? CFSetGetCount(foundDevices) : 0; // what the API does not say is that it could be null
    if(foundCount > 0) 
    {
        CFTypeRef* array = new CFTypeRef[foundCount]; // array of IOHIDDeviceRef
        CFSetGetValues(foundDevices, array);
        // get first matching device
        theDevice = (IOHIDDeviceRef)array[0];
        CFRetain(theDevice);
        delete [] array;
    }

    if(foundDevices)
    {
        CFRelease(foundDevices);
    }
    CFRelease(dictionary);

    return theDevice;
}
Example #5
0
CFMutableSetRef CFSetCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFSetRef set) {
    CFMutableSetRef result;
    const CFSetCallBacks *cb;
    CFIndex idx, numValues = CFSetGetCount(set);
    const void **list, *buffer[256];
    CFAssert3(0 == capacity || numValues <= capacity, __kCFLogAssertion, "%s(): for fixed-mutable sets, capacity (%d) must be greater than or equal to initial number of values (%d)", __PRETTY_FUNCTION__, capacity, numValues);
    list = (numValues <= 256) ? buffer : CFAllocatorAllocate(allocator, numValues * sizeof(void *), 0);
    if (list != buffer && __CFOASafe) __CFSetLastAllocationEventName(list, "CFSet (temp)");
    CFSetGetValues(set, list);
    cb = CF_IS_OBJC(__kCFSetTypeID, set) ? &kCFTypeSetCallBacks : __CFSetGetCallBacks(set);
    result = CFSetCreateMutable(allocator, capacity, cb);
    if (0 == capacity) _CFSetSetCapacity(result, numValues);
    for (idx = 0; idx < numValues; idx++) {
	CFSetAddValue(result, list[idx]);
    }
    if (list != buffer) CFAllocatorDeallocate(allocator, list);
    return result;
}
Example #6
0
void
CFSetApplyFunction (CFSetRef set, CFSetApplierFunction applier, void *context)
{
  // TODO: could be made more efficient by providing a specialized
  // implementation for the CF_IS_OBJC case

  const CFIndex count = CFSetGetCount (set);
  void **values =
    (void **) CFAllocatorAllocate (NULL, sizeof (void *) * count, 0);
  CFIndex i;

  CFSetGetValues (set, (const void **) values);

  for (i = 0; i < count; i++)
    {
      applier (values[i], context);
    }

  CFAllocatorDeallocate (NULL, (void *) values);
}
Example #7
0
static IOHIDDeviceRef* getDevRef(OSX_HID_REF *hid, CFIndex *deviceCount)
{

    CFSetRef        deviceCFSetRef;
    IOHIDDeviceRef  *dev_refs=NULL;

    *deviceCount = 0;

    yEnterCriticalSection(&hid->hidMCS);
    deviceCFSetRef = IOHIDManagerCopyDevices(hid->manager);
    yLeaveCriticalSection(&hid->hidMCS);
    if (deviceCFSetRef!= NULL) {
        // how many devices in the set?
        *deviceCount = CFSetGetCount( deviceCFSetRef );
        dev_refs = yMalloc( sizeof(IOHIDDeviceRef) * (u32)*deviceCount );
        // now extract the device ref's from the set
        CFSetGetValues( deviceCFSetRef, (const void **) dev_refs );
    }
    return dev_refs;
}
Example #8
0
void setAllKeyboards(LedState changes[])
{
    IOHIDManagerRef manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
    if (!manager) {
        fprintf(stderr, "Failed to create IOHID manager.\n");
        return;
    }
    
    CFDictionaryRef keyboard = getKeyboardDictionary();
    if (!keyboard) {
        fprintf(stderr, "Failed to get dictionary usage page for kHIDUsage_GD_Keyboard.\n");
        return;
    }
    
    IOHIDManagerOpen(manager, kIOHIDOptionsTypeNone);
    IOHIDManagerSetDeviceMatching(manager, keyboard);
    
    CFSetRef devices = IOHIDManagerCopyDevices(manager);
    if (devices) {
        CFIndex deviceCount = CFSetGetCount(devices);
        if (deviceCount == 0) {
            fprintf(stderr, "Could not find any keyboard devices.\n");
        }
        else {
            // Loop through all keyboards attempting to get or display led state
            IOHIDDeviceRef *deviceRefs = malloc(sizeof(IOHIDDeviceRef) * deviceCount);
            if (deviceRefs) {
                CFSetGetValues(devices, (const void **) deviceRefs);
                for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
                    if (isKeyboardDevice(deviceRefs[deviceIndex]))
                        setKeyboard(deviceRefs[deviceIndex], keyboard, changes);
                
                free(deviceRefs);
            }
        }
        
        CFRelease(devices);
    }
    
    CFRelease(keyboard);
}
Example #9
0
CFSetRef
CFSetCreateCopy (CFAllocatorRef allocator, CFSetRef set)
{
  if (CF_IS_OBJC (_kCFSetTypeID, set))
    {
      CFSetRef result;
      const CFIndex count = CFSetGetCount (set);
      void **values =
        (void **) CFAllocatorAllocate (allocator, sizeof (void *) * count, 0);

      CFSetGetValues (set, (const void **) values);
      result =
        CFSetCreate (allocator, (const void **) values, count,
                     &kCFTypeSetCallBacks);

      CFAllocatorDeallocate (allocator, (void *) values);
      return result;
    }

  return (CFSetRef) GSHashTableCreateCopy (allocator, (GSHashTableRef) set);
}
Example #10
0
int main(void)
{
	IOHIDManagerRef mgr;
	int i;

	mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
	IOHIDManagerSetDeviceMatching(mgr, NULL);
	IOHIDManagerOpen(mgr, kIOHIDOptionsTypeNone);

	CFSetRef device_set = IOHIDManagerCopyDevices(mgr);
    if (device_set==NULL) {
        return 0;
    }

	CFIndex num_devices = CFSetGetCount(device_set);
	IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef));
	CFSetGetValues(device_set, (const void **) device_array);

	for (i = 0; i < num_devices; i++) {
		IOHIDDeviceRef dev = device_array[i];
		printf("Device: %p\n", dev);
		printf("  %04hx %04hx\n", get_vendor_id(dev), get_product_id(dev));

		wchar_t serial[256], buf[256];
		char cbuf[256];
		get_serial_number(dev, serial, 256);


		printf("  Serial: %ls\n", serial);
		printf("  Loc: %ld\n", get_location_id(dev));
		get_transport(dev, buf, 256);
		printf("  Trans: %ls\n", buf);
		make_path(dev, cbuf, 256);
		printf("  Path: %s\n", cbuf);

	}

	return 0;
}
Example #11
0
CFArrayRef CFLocaleCopyAvailableLocaleIdentifiers(void) {
    int32_t locale, localeCount = uloc_countAvailable();
    CFMutableSetRef working = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeSetCallBacks);
    for (locale = 0; locale < localeCount; ++locale) {
        const char *localeID = uloc_getAvailable(locale);
        CFStringRef string1 = CFStringCreateWithCString(kCFAllocatorSystemDefault, localeID, kCFStringEncodingASCII);
	CFStringRef string2 = CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorSystemDefault, string1);
	CFSetAddValue(working, string1);
	// do not include canonicalized version as IntlFormats cannot cope with that in its popup
        CFRelease(string1);
        CFRelease(string2);
    }
    CFIndex cnt = CFSetGetCount(working);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || (DEPLOYMENT_TARGET_WINDOWS && __GNUC__)
    STACK_BUFFER_DECL(const void *, buffer, cnt);
#else
    const void* buffer[BUFFER_SIZE];
#endif
    CFSetGetValues(working, buffer);
    CFArrayRef result = CFArrayCreate(kCFAllocatorSystemDefault, buffer, cnt, &kCFTypeArrayCallBacks);
    CFRelease(working);
    return result;
}
Example #12
0
bool JoystickImpl::open(unsigned int index)
{
    m_index = index;
    Location deviceLoc = m_locationIDs[index]; // The device we need to load

    // Get all devices
    CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
    if (devices == NULL)
        return false;

    // Get a usable copy of the joysticks devices.
    CFIndex joysticksCount = CFSetGetCount(devices);
    CFTypeRef devicesArray[joysticksCount];
    CFSetGetValues(devices, devicesArray);

    // Get the desired joystick.
    IOHIDDeviceRef self = 0;
    for (CFIndex i(0); i < joysticksCount; ++i)
    {
        IOHIDDeviceRef d = (IOHIDDeviceRef)devicesArray[i];
        if (deviceLoc == HIDInputManager::getLocationID(d))
        {
            self = d;
            break; // We found it so we stop looping.
        }
    }

    if (self == 0)
    {
        // This shouldn't happen!
        CFRelease(devices);
        return false;
    }

    m_identification.name      = getDeviceString(self, CFSTR(kIOHIDProductKey), m_index);
    m_identification.vendorId  = getDeviceUint(self, CFSTR(kIOHIDVendorIDKey), m_index);
    m_identification.productId = getDeviceUint(self, CFSTR(kIOHIDProductIDKey), m_index);

    // Get a list of all elements attached to the device.
    CFArrayRef elements = IOHIDDeviceCopyMatchingElements(self, NULL, kIOHIDOptionsTypeNone);

    if (elements == NULL)
    {
        CFRelease(devices);
        return false;
    }

    // How many elements are there?
    CFIndex elementsCount = CFArrayGetCount(elements);

    if (elementsCount == 0)
    {
        // What is a joystick with no element?
        CFRelease(elements);
        CFRelease(devices);
        return false;
    }

    // Go through all connected elements.
    for (int i = 0; i < elementsCount; ++i)
    {
        IOHIDElementRef element = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, i);
        switch (IOHIDElementGetType(element))
        {
            case kIOHIDElementTypeInput_Misc:
                switch (IOHIDElementGetUsage(element))
                {
                    case kHIDUsage_GD_X:  m_axis[Joystick::X] = element; break;
                    case kHIDUsage_GD_Y:  m_axis[Joystick::Y] = element; break;
                    case kHIDUsage_GD_Z:  m_axis[Joystick::Z] = element; break;
                    case kHIDUsage_GD_Rx: m_axis[Joystick::U] = element; break;
                    case kHIDUsage_GD_Ry: m_axis[Joystick::V] = element; break;
                    case kHIDUsage_GD_Rz: m_axis[Joystick::R] = element; break;
                    // kHIDUsage_GD_Vx, kHIDUsage_GD_Vy, kHIDUsage_GD_Vz are ignored.
                }
                break;

            case kIOHIDElementTypeInput_Button:
                if (m_buttons.size() < Joystick::ButtonCount) // If we have free slot...
                    m_buttons.push_back(element); // ...we add this element to the list
                // Else: too many buttons. We ignore this one.
                break;

            default: // Make compiler happy
                break;
        }
    }

    // Ensure that the buttons will be indexed in the same order as their
    // HID Usage (assigned by manufacturer and/or a driver).
    std::sort(m_buttons.begin(), m_buttons.end(), JoystickButtonSortPredicate);

    // Note: Joy::AxisPovX/Y are not supported (yet).
    // Maybe kIOHIDElementTypeInput_Axis is the corresponding type but I can't test.

    // Retain all these objects for personal use
    for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it)
        CFRetain(*it);
    for (AxisMap::iterator it(m_axis.begin()); it != m_axis.end(); ++it)
        CFRetain(it->second);

    // Note: we didn't retain element in the switch because we might have multiple
    // Axis X (for example) and we want to keep only the last one. So to prevent
    // leaking we retain objects 'only' now.

    CFRelease(devices);
    CFRelease(elements);

    return true;
}
Example #13
0
//int main( int argc, const char * argv[] )
int manipulate_led( int which_led, int led_value )
{
#pragma unused ( argc, argv )
	IOHIDDeviceRef * tIOHIDDeviceRefs = nil;

	// create a IO HID Manager reference
	IOHIDManagerRef tIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone );
	require( tIOHIDManagerRef, Oops );

	// Create a device matching dictionary
	CFDictionaryRef matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( TRUE,
																				  kHIDPage_GenericDesktop,
																				  kHIDUsage_GD_Keyboard );
	require( matchingCFDictRef, Oops );

	// set the HID device matching dictionary
	IOHIDManagerSetDeviceMatching( tIOHIDManagerRef, matchingCFDictRef );

	if ( matchingCFDictRef ) {
		CFRelease( matchingCFDictRef );
	}

	// Now open the IO HID Manager reference
	IOReturn tIOReturn = IOHIDManagerOpen( tIOHIDManagerRef, kIOHIDOptionsTypeNone );
	require_noerr( tIOReturn, Oops );

	// and copy out its devices
	CFSetRef deviceCFSetRef = IOHIDManagerCopyDevices( tIOHIDManagerRef );
	require( deviceCFSetRef, Oops );

	// how many devices in the set?
	CFIndex deviceIndex, deviceCount = CFSetGetCount( deviceCFSetRef );

	// allocate a block of memory to extact the device ref's from the set into
	tIOHIDDeviceRefs = malloc( sizeof( IOHIDDeviceRef ) * deviceCount );
	if (!tIOHIDDeviceRefs) {
		CFRelease(deviceCFSetRef);
		deviceCFSetRef = NULL;
		goto Oops;
	}

	// now extract the device ref's from the set
	CFSetGetValues( deviceCFSetRef, (const void **) tIOHIDDeviceRefs );
	CFRelease(deviceCFSetRef);
	deviceCFSetRef = NULL;

	// before we get into the device loop we'll setup our element matching dictionary
	matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( FALSE, kHIDPage_LEDs, 0 );
	require( matchingCFDictRef, Oops );

	int pass;	// do 256 passes
	//for ( pass = 0; pass < 256; pass++ ) {
		Boolean delayFlag = FALSE;	// if we find an LED element we'll set this to TRUE

		//printf( "pass = %d.\n", pass );
		for ( deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++ ) {

			// if this isn't a keyboard device...
			if ( !IOHIDDeviceConformsTo( tIOHIDDeviceRefs[deviceIndex], kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard ) ) {
				continue;	// ...skip it
			}

			//printf( "	 device = %p.\n", tIOHIDDeviceRefs[deviceIndex] );

			// copy all the elements
			CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements( tIOHIDDeviceRefs[deviceIndex],
																		   matchingCFDictRef,
																		   kIOHIDOptionsTypeNone );
			require( elementCFArrayRef, next_device );

			// for each device on the system these values are divided by the value ranges of all LED elements found
			// for example, if the first four LED element have a range of 0-1 then the four least significant bits of
			// this value will be sent to these first four LED elements, etc.
			int device_value = pass;

			// iterate over all the elements
			CFIndex elementIndex, elementCount = CFArrayGetCount( elementCFArrayRef );
			for ( elementIndex = 0; elementIndex < elementCount; elementIndex++ ) {
				IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( elementCFArrayRef, elementIndex );
				require( tIOHIDElementRef, next_element );

				uint32_t usagePage = IOHIDElementGetUsagePage( tIOHIDElementRef );

				// if this isn't an LED element...
				if ( kHIDPage_LEDs != usagePage ) {
					continue;	// ...skip it
				}

				uint32_t usage = IOHIDElementGetUsage( tIOHIDElementRef );
				IOHIDElementType tIOHIDElementType = IOHIDElementGetType( tIOHIDElementRef );

				//printf( "		 element = %p (page: %d, usage: %d, type: %d ).\n",
				//	   tIOHIDElementRef, usagePage, usage, tIOHIDElementType );

				// get the logical mix/max for this LED element
				CFIndex minCFIndex = IOHIDElementGetLogicalMin( tIOHIDElementRef );
				CFIndex maxCFIndex = IOHIDElementGetLogicalMax( tIOHIDElementRef );

				// calculate the range
				CFIndex modCFIndex = maxCFIndex - minCFIndex + 1;

				// compute the value for this LED element
				//CFIndex tCFIndex = minCFIndex + ( device_value % modCFIndex );
				CFIndex tCFIndex = led_value;
				device_value /= modCFIndex;

				//printf( "			 value = 0x%08lX.\n", tCFIndex );

				uint64_t timestamp = 0; // create the IO HID Value to be sent to this LED element
				IOHIDValueRef tIOHIDValueRef = IOHIDValueCreateWithIntegerValue( kCFAllocatorDefault, tIOHIDElementRef, timestamp, tCFIndex );
				if ( tIOHIDValueRef ) {
					// now set it on the device
					tIOReturn = IOHIDDeviceSetValue( tIOHIDDeviceRefs[deviceIndex], tIOHIDElementRef, tIOHIDValueRef );
					CFRelease( tIOHIDValueRef );
					require_noerr( tIOReturn, next_element );
					delayFlag = TRUE;	// set this TRUE so we'll delay before changing our LED values again
				}
			next_element:	;
				continue;
			}
			CFRelease( elementCFArrayRef );
		next_device: ;
			continue;
		}

		// if we found an LED we'll delay before continuing
		//if ( delayFlag ) {
		//	usleep( 500000 ); // sleep one half second
		//}

		// if the mouse is down…
		//if (GetCurrentButtonState()) {
		//	break;	// abort pass loop
		//}
	//}						  // next pass

	if ( matchingCFDictRef ) {
		CFRelease( matchingCFDictRef );
	}
Oops:	;
	if ( tIOHIDDeviceRefs ) {
		free(tIOHIDDeviceRefs);
	}

	if ( tIOHIDManagerRef ) {
		CFRelease( tIOHIDManagerRef );
	}
	return 0;
} /* main */
int main( int argc, const char * argv[] )
{
	Boolean initialized = FALSE;
	
	if (( argc != 4 ) && ( argc != 5 ))  {
		printf ( "usage: Dream Cheeky Notifier R G B [A]\n\tRGB values should be 0-31.  A is an optional parameter on whether to do the LED activation sequence.  Anything larger than 0 is YES, default is 0 (activate).\n\n");
		exit ( -1 );
	}
	
	char r = (int)strtol ( argv[1], NULL, 10 );
	char g = (int)strtol ( argv[2], NULL, 10 );
	char b = (int)strtol ( argv[3], NULL, 10 );
	if ( argc == 5 ) {
		initialized = TRUE;
	}
	
	if ((r < 0) || (r > 31) || (g < 0) || (g > 31) || (b < 0) || (b > 31)) {
		printf("RGB values must be within 0-31.");
		exit -1;
	}
	
	// create a IO HID Manager reference
	IOHIDManagerRef tIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone );
	// Create a device matching dictionary
	CFDictionaryRef matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( TRUE,
																				  kHIDPage_GenericDesktop,
																				  0x10 );
	// set the HID device matching dictionary
	IOHIDManagerSetDeviceMatching( tIOHIDManagerRef, matchingCFDictRef );
	if ( matchingCFDictRef ) {
		CFRelease( matchingCFDictRef );
	}
	
	// Now open the IO HID Manager reference
	IOReturn tIOReturn = IOHIDManagerOpen( tIOHIDManagerRef, kIOHIDOptionsTypeNone );
	
	// and copy out its devices
	CFSetRef deviceCFSetRef = IOHIDManagerCopyDevices( tIOHIDManagerRef );
	
	// how many devices in the set?
	CFIndex deviceIndex, deviceCount = CFSetGetCount( deviceCFSetRef );
	
	// allocate a block of memory to extact the device ref's from the set into
	IOHIDDeviceRef * tIOHIDDeviceRefs = malloc( sizeof( IOHIDDeviceRef ) * deviceCount );
	
	// now extract the device ref's from the set
	CFSetGetValues( deviceCFSetRef, (const void **) tIOHIDDeviceRefs );
	
	// before we get into the device loop we'll setup our element matching dictionary (Note: we don't do element matching anymore)
	matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( FALSE, 0, 0 );
	
	for ( deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++ ) {
		
		// if this isn't the notifier device...  TODO: let's detect via vendor/product ids instead
		long vendor_id = 0;
		IOHIDDevice_GetLongProperty(tIOHIDDeviceRefs[deviceIndex], CFSTR(kIOHIDVendorIDKey), &vendor_id);
		long product_id = 0;
		IOHIDDevice_GetLongProperty(tIOHIDDeviceRefs[deviceIndex], CFSTR(kIOHIDProductIDKey), &product_id);
		if ((vendor_id != 0x1D34 ) || (product_id != 0x0004 )) {
			printf("	skipping device %p.\n", tIOHIDDeviceRefs[deviceIndex] );
			continue;	// ...skip it
		}
		
		printf( "	 device = %p.\n", tIOHIDDeviceRefs[deviceIndex] );
		
		unsigned char report[8];
		if (initialized == FALSE) {
			report[0] = 0x1F; // turn on LEDs
			report[1] = 0x02;
			report[2] = 0x00;
			report[3] = 0x5F;
			report[4] = 0x00;
			report[5] = 0x00;
			report[6] = 0x1A;
			report[7] = 0x03;
			
            // Note: We don't use the returned value here, so the compiler might throw a warning.
			IOReturn  tIOReturn = IOHIDDeviceSetReport(
													   tIOHIDDeviceRefs[deviceIndex],          // IOHIDDeviceRef for the HID device
													   kIOHIDReportTypeInput,   // IOHIDReportType for the report (input, output, feature)
													   0,           // CFIndex for the report ID
													   report,             // address of report buffer
													   8);      // length of the report
			initialized = TRUE;
		}
		
		report[0] = r; // set brightness on LEDs to r, g, & b
		report[1] = g;
		report[2] = b;
		report[3] = 0x00;
		report[4] = 0x00;
		report[5] = 0x00;
		report[6] = 0x1A;
		report[7] = 0x05;
		
		tIOReturn = IOHIDDeviceSetReport(
										 tIOHIDDeviceRefs[deviceIndex],          // IOHIDDeviceRef for the HID device
										 kIOHIDReportTypeInput,   // IOHIDReportType for the report (input, output, feature)
										 0,           // CFIndex for the report ID
										 report,             // address of report buffer
										 8);      // length of the report
		
	next_device: ;
		continue;
	}
	
	
	if ( tIOHIDManagerRef ) {
		CFRelease( tIOHIDManagerRef );
	}
	
	if ( matchingCFDictRef ) {
		CFRelease( matchingCFDictRef );
	}
Oops:	;
	return -1;
} /* main */
Example #15
0
bool HIDDevice::openDevice()
{
    
    // Have to iterate through devices again to generate paths.
	CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager->HIDManager);
	CFIndex deviceCount = CFSetGetCount(deviceSet);
    
    // Allocate a block of memory and read the set into it.
    IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount);
    CFSetGetValues(deviceSet, (const void **) devices);
    
    
    // Iterate over devices.
    IOHIDDeviceRef device = NULL;

    for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
    {
        IOHIDDeviceRef tmpDevice = devices[deviceIndex];
        
        if (!tmpDevice)
        {
            continue;
        }
        
        String path;
        if (!HIDManager->getPath(tmpDevice, &path))
        {
            continue;
        }
        
        if (path == DevDesc.Path)
        {
            device = tmpDevice;
            break;
        }
    }
    
    
    OVR_FREE(devices);
    
    if (!device)
    {
        CFRelease(deviceSet);
        return false;
    }
    
    // Attempt to open device.
    if (IOHIDDeviceOpen(device, kIOHIDOptionsTypeSeizeDevice)
        != kIOReturnSuccess)
    {
        CFRelease(deviceSet);
        return false;
    }

    // Retain the device before we release the set.
    CFRetain(device);
    CFRelease(deviceSet);
    
    
    Device = device;

    
    if (!initInfo())
    {
        IOHIDDeviceClose(Device, kIOHIDOptionsTypeSeizeDevice);
        CFRelease(Device);
        Device = NULL;
        return false;
    }
    
    
    // Setup the Run Loop and callbacks.
    IOHIDDeviceScheduleWithRunLoop(Device,
                                   HIDManager->getRunLoop(),
                                   kCFRunLoopDefaultMode);
    
    IOHIDDeviceRegisterInputReportCallback(Device,
                                           ReadBuffer,
                                           ReadBufferSize,
                                           staticHIDReportCallback,
                                           this);

    IOHIDDeviceRegisterRemovalCallback(Device,
                                       staticDeviceRemovedCallback,
                                       this);
    
    return true;
}
Example #16
0
File: hid.c Project: billsq/hidapi
struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	struct hid_device_info *root = NULL; /* return object */
	struct hid_device_info *cur_dev = NULL;
	CFIndex num_devices;
	int i;

	/* Set up the HID Manager if it hasn't been done */
	if (hid_init() < 0)
		return NULL;

	/* give the IOHIDManager a chance to update itself */
	process_pending_events();

	/* Get a list of the Devices */
	IOHIDManagerSetDeviceMatching(hid_mgr, NULL);
	CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr);

	/* Convert the list into a C array so we can iterate easily. */
	num_devices = CFSetGetCount(device_set);
	IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef));
	CFSetGetValues(device_set, (const void **) device_array);

	/* Iterate over each device, making an entry for it. */
	for (i = 0; i < num_devices; i++) {
		unsigned short dev_vid;
		unsigned short dev_pid;
		#define BUF_LEN 256
		wchar_t buf[BUF_LEN];

		IOHIDDeviceRef dev = device_array[i];

        if (!dev) {
            continue;
        }
		dev_vid = get_vendor_id(dev);
		dev_pid = get_product_id(dev);

		/* Check the VID/PID against the arguments */
		if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
		    (product_id == 0x0 || product_id == dev_pid)) {
			struct hid_device_info *tmp;
			io_object_t iokit_dev;
			kern_return_t res;
			io_string_t path;

			/* VID/PID match. Create the record. */
			tmp = malloc(sizeof(struct hid_device_info));
			if (cur_dev) {
				cur_dev->next = tmp;
			}
			else {
				root = tmp;
			}
			cur_dev = tmp;

			/* Get the Usage Page and Usage for this device. */
			cur_dev->usage_page = get_int_property(dev, CFSTR(kIOHIDPrimaryUsagePageKey));
			cur_dev->usage = get_int_property(dev, CFSTR(kIOHIDPrimaryUsageKey));

			/* Fill out the record */
			cur_dev->next = NULL;

			/* Fill in the path (IOService plane) */
			iokit_dev = hidapi_IOHIDDeviceGetService(dev);
			res = IORegistryEntryGetPath(iokit_dev, kIOServicePlane, path);
			if (res == KERN_SUCCESS)
				cur_dev->path = strdup(path);
			else
				cur_dev->path = strdup("");

			/* Serial Number */
			get_serial_number(dev, buf, BUF_LEN);
			cur_dev->serial_number = dup_wcs(buf);

			/* Manufacturer and Product strings */
			get_manufacturer_string(dev, buf, BUF_LEN);
			cur_dev->manufacturer_string = dup_wcs(buf);
			get_product_string(dev, buf, BUF_LEN);
			cur_dev->product_string = dup_wcs(buf);

			/* VID/PID */
			cur_dev->vendor_id = dev_vid;
			cur_dev->product_id = dev_pid;

			/* Release Number */
			cur_dev->release_number = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey));

			/* Interface Number (Unsupported on Mac)*/
			cur_dev->interface_number = -1;
		}
	}

	free(device_array);
	CFRelease(device_set);

	return root;
}
Example #17
0
int yUSBGetInterfaces(yInterfaceSt **ifaces,int *nbifaceDetect,char *errmsg)
{
    int             nbifaceAlloc;
    int             deviceIndex;
   
    CFSetRef        deviceCFSetRef;
    CFIndex         deviceCount;
    IOHIDDeviceRef  *dev_refs;
    
    // allocate buffer for detected interfaces
    *nbifaceDetect = 0;
    nbifaceAlloc  = 8;
    *ifaces =yMalloc(nbifaceAlloc * sizeof(yInterfaceSt));
    memset(*ifaces, 0 ,nbifaceAlloc * sizeof(yInterfaceSt));
            
    
    yEnterCriticalSection(&yContext->hidMCS);
    deviceCFSetRef = IOHIDManagerCopyDevices( yContext->hidM );
    yLeaveCriticalSection(&yContext->hidMCS);
    if(deviceCFSetRef== NULL){
        //no device found
        return 0;
    }
    
    // how many devices in the set?
    deviceCount = CFSetGetCount( deviceCFSetRef ); 
    HALLOG("%ld usb interfaces detected\n",deviceCount);
    
    dev_refs = yMalloc( sizeof(IOHIDDeviceRef) * (u32)deviceCount );
    
    // now extract the device ref's from the set
    CFSetGetValues( deviceCFSetRef, (const void **) dev_refs );
    
    for(deviceIndex=0 ; deviceIndex < deviceCount ;deviceIndex++){
        u16 vendorid;
        u16 deviceid;
        IOHIDDeviceRef dev = dev_refs[deviceIndex];
        yInterfaceSt    *iface;
        vendorid = get_int_property(dev,CFSTR(kIOHIDVendorIDKey));
        deviceid = get_int_property(dev,CFSTR(kIOHIDProductIDKey));
        //ensure the buffer of detected interface is big enought
        if(*nbifaceDetect == nbifaceAlloc){
            yInterfaceSt    *tmp;
            tmp = (yInterfaceSt*) yMalloc(nbifaceAlloc*2 * sizeof(yInterfaceSt));
            memset(tmp,0,nbifaceAlloc*2 * sizeof(yInterfaceSt));
            yMemcpy(tmp,*ifaces, nbifaceAlloc * sizeof(yInterfaceSt) );
            yFree(*ifaces);
            *ifaces = tmp;
            nbifaceAlloc    *=2;
        }
        iface = *ifaces + *nbifaceDetect;
        iface->devref   = dev;
        iface->vendorid = vendorid;
        iface->deviceid = deviceid;
        get_txt_property(dev,iface->serial,YOCTO_SERIAL_LEN*2, CFSTR(kIOHIDSerialNumberKey));
        HALLOG("work on interface %d (%x:%x:%s)\n",deviceIndex,vendorid,deviceid,iface->serial);
        (*nbifaceDetect)++;
    }
    CFRelease(deviceCFSetRef);
    yFree(dev_refs);
    return YAPI_SUCCESS;
}
Example #18
0
bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor)
{
    if (!initializeManager())
    {
        return false;
    }
    

	CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager);
    if (!deviceSet)
        return false;
    
	CFIndex deviceCount = CFSetGetCount(deviceSet);
    
    // Allocate a block of memory and read the set into it.
    IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount);
    CFSetGetValues(deviceSet, (const void **) devices);
    

    // Iterate over devices.
    for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
    {
        IOHIDDeviceRef hidDev = devices[deviceIndex];
        
        if (!hidDev)
        {
            continue;
        }
        
        HIDDeviceDesc devDesc;
                
        if (getPath(hidDev, &(devDesc.Path)) &&
            initVendorProductVersion(hidDev, &devDesc) &&
            enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId) &&
            initUsage(hidDev, &devDesc))
        {
            initStrings(hidDev, &devDesc);
            initSerialNumber(hidDev, &devDesc);

            // Look for the device to check if it is already opened.
            Ptr<DeviceCreateDesc> existingDevice = DevManager->FindHIDDevice(devDesc, true);
            // if device exists and it is opened then most likely the CreateHIDFile
            // will fail; therefore, we just set Enumerated to 'true' and continue.
            if (existingDevice && existingDevice->pDevice)
            {
                existingDevice->Enumerated = true;
                continue;
            }

            // open the device temporarily for startup communication
            if (IOHIDDeviceOpen(hidDev, kIOHIDOptionsTypeSeizeDevice) == kIOReturnSuccess)
            {
                // Construct minimal device that the visitor callback can get feature reports from.
                OSX::HIDDevice device(this, hidDev);

                enumVisitor->Visit(device, devDesc);

                IOHIDDeviceClose(hidDev, kIOHIDOptionsTypeSeizeDevice);
            }
        }
    }
    
    OVR_FREE(devices);
    CFRelease(deviceSet);
    
    return true;
}
/**************************************************************************
 *                              find_osx_devices
 */
static int find_osx_devices(void)
{
    IOHIDManagerRef hid_manager;
    int usages[] = { kHIDUsage_GD_Joystick, kHIDUsage_GD_GamePad };
    int i;
    CFDictionaryRef matching_dicts[sizeof(usages) / sizeof(usages[0])];
    CFArrayRef matching;
    CFSetRef devset;

    TRACE("()\n");

    hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, 0L);
    if (IOHIDManagerOpen(hid_manager, 0) != kIOReturnSuccess)
    {
        ERR("Couldn't open IOHIDManager.\n");
        CFRelease(hid_manager);
        return 0;
    }

    for (i = 0; i < sizeof(matching_dicts) / sizeof(matching_dicts[0]); i++)
    {
        matching_dicts[i] = create_osx_device_match(usages[i]);
        if (!matching_dicts[i])
        {
            while (i > 0)
                CFRelease(matching_dicts[--i]);
            goto fail;
        }
    }

    matching = CFArrayCreate(NULL, (const void**)matching_dicts, sizeof(matching_dicts) / sizeof(matching_dicts[0]),
                             &kCFTypeArrayCallBacks);

    for (i = 0; i < sizeof(matching_dicts) / sizeof(matching_dicts[0]); i++)
        CFRelease(matching_dicts[i]);

    IOHIDManagerSetDeviceMatchingMultiple(hid_manager, matching);
    CFRelease(matching);
    devset = IOHIDManagerCopyDevices(hid_manager);
    if (devset)
    {
        CFIndex num_devices, num_main_elements;
        const void** refs;
        CFArrayRef devices;

        num_devices = CFSetGetCount(devset);
        refs = HeapAlloc(GetProcessHeap(), 0, num_devices * sizeof(*refs));
        if (!refs)
        {
            CFRelease(devset);
            goto fail;
        }

        CFSetGetValues(devset, refs);
        devices = CFArrayCreate(NULL, refs, num_devices, &kCFTypeArrayCallBacks);
        HeapFree(GetProcessHeap(), 0, refs);
        CFRelease(devset);
        if (!devices)
            goto fail;

        device_main_elements = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
        if (!device_main_elements)
        {
            CFRelease(devices);
            goto fail;
        }

        num_main_elements = 0;
        for (i = 0; i < num_devices; i++)
        {
            IOHIDDeviceRef hid_device = (IOHIDDeviceRef)CFArrayGetValueAtIndex(devices, i);
            TRACE("hid_device %s\n", debugstr_device(hid_device));
            num_main_elements += find_top_level(hid_device, device_main_elements);
        }

        CFRelease(devices);

        TRACE("found %i device(s), %i collection(s)\n",(int)num_devices,(int)num_main_elements);
        return (int)num_main_elements;
    }

fail:
    IOHIDManagerClose(hid_manager, 0);
    CFRelease(hid_manager);
    return 0;
}
Example #20
0
// ----------------------------------------------------
int main(int			argc,
         const char *	argv[]) {
#pragma unused ( argc, argv )

	IOHIDManagerRef tIOHIDManagerRef = NULL;
	CFSetRef deviceCFSetRef = NULL;
	IOHIDDeviceRef *tIOHIDDeviceRefs = nil;

	do {
		tIOHIDManagerRef = IOHIDManagerCreate(kCFAllocatorDefault,
		                                      kIOHIDOptionsTypeNone);
		if (!tIOHIDManagerRef) {
			break;
		}

		IOHIDManagerSetDeviceMatching(tIOHIDManagerRef,
		                              NULL);

		IOReturn tIOReturn = IOHIDManagerOpen(tIOHIDManagerRef,
		                                      kIOHIDOptionsTypeNone);
		if (noErr != tIOReturn) {
			break;
		}

		deviceCFSetRef = IOHIDManagerCopyDevices(tIOHIDManagerRef);
		if (!deviceCFSetRef) {
			break;
		}

		CFIndex deviceIndex,
		        deviceCount = CFSetGetCount(deviceCFSetRef);

		tIOHIDDeviceRefs = malloc(sizeof(IOHIDDeviceRef) *
		                          deviceCount);
		if (!tIOHIDDeviceRefs) {
			break;
		}

		CFSetGetValues(deviceCFSetRef,
		               (const void **)tIOHIDDeviceRefs);
		CFRelease(deviceCFSetRef);
		deviceCFSetRef = NULL;
		for (deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) {
			if (!tIOHIDDeviceRefs[deviceIndex]) {
				continue;
			}

			HIDDumpDeviceInfo(tIOHIDDeviceRefs[deviceIndex]);
#if true
			// and copy all the elements
			CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements(tIOHIDDeviceRefs[deviceIndex],
			                                                               NULL /* matchingCFDictRef */,
			                                                               kIOHIDOptionsTypeNone);
			if (elementCFArrayRef) {
				// iterate over all the elements
				CFIndex elementIndex,
				        elementCount = CFArrayGetCount(elementCFArrayRef);
				for (elementIndex = 0; elementIndex < elementCount; elementIndex++) {
					IOHIDElementRef tIOHIDElementRef = (IOHIDElementRef)CFArrayGetValueAtIndex(elementCFArrayRef,
					                                                                           elementIndex);
					if (tIOHIDElementRef) {
						HIDDumpElementInfo(tIOHIDElementRef);
					}
				}

				CFRelease(elementCFArrayRef);
			}
#endif
		}
	} while (false);

	if (tIOHIDDeviceRefs) {
		free(tIOHIDDeviceRefs);
	}
	if (deviceCFSetRef) {
		CFRelease(deviceCFSetRef);
		deviceCFSetRef = NULL;
	}
	if (tIOHIDManagerRef) {
		CFRelease(tIOHIDManagerRef);
	}

	return (0);
} // main
Example #21
0
bool JoystickImpl::open(unsigned int index)
{
    m_index = index;
    m_hat = NULL;
    Location deviceLoc = m_locationIDs[index]; // The device we need to load

    // Get all devices
    CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
    if (devices == NULL)
        return false;

    // Get a usable copy of the joysticks devices.
    CFIndex joysticksCount = CFSetGetCount(devices);
    CFTypeRef devicesArray[joysticksCount];
    CFSetGetValues(devices, devicesArray);

    // Get the desired joystick.
    IOHIDDeviceRef self = 0;
    for (CFIndex i(0); self == 0 && i < joysticksCount; ++i)
    {
        IOHIDDeviceRef d = (IOHIDDeviceRef)devicesArray[i];
        if (deviceLoc == HIDInputManager::getLocationID(d))
            self = d;
    }

    if (self == 0)
    {
        CFRelease(devices);
        return false;
    }

    m_identification.name      = getDeviceString(self, CFSTR(kIOHIDProductKey), m_index);
    m_identification.vendorId  = getDeviceUint(self, CFSTR(kIOHIDVendorIDKey), m_index);
    m_identification.productId = getDeviceUint(self, CFSTR(kIOHIDProductIDKey), m_index);

    // Get a list of all elements attached to the device.
    CFArrayRef elements = IOHIDDeviceCopyMatchingElements(self, NULL, kIOHIDOptionsTypeNone);

    if (elements == NULL)
    {
        CFRelease(devices);
        return false;
    }

    // Go through all connected elements.
    CFIndex elementsCount = CFArrayGetCount(elements);
    for (int i = 0; i < elementsCount; ++i)
    {
        IOHIDElementRef element = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, i);
        switch (IOHIDElementGetUsagePage(element))
        {
            case kHIDPage_GenericDesktop:
                switch (IOHIDElementGetUsage(element))
                {
                    case kHIDUsage_GD_X:  m_axis[Joystick::X] = element; break;
                    case kHIDUsage_GD_Y:  m_axis[Joystick::Y] = element; break;
                    case kHIDUsage_GD_Z:  m_axis[Joystick::Z] = element; break;
                    case kHIDUsage_GD_Rx: m_axis[Joystick::U] = element; break;
                    case kHIDUsage_GD_Ry: m_axis[Joystick::V] = element; break;
                    case kHIDUsage_GD_Rz: m_axis[Joystick::R] = element; break;

                    case kHIDUsage_GD_Hatswitch:
                        // From §4.3 MiscellaneousControls of HUT v1.12:
                        //
                        // > Hat Switch:
                        // >   A typical example is four switches that are capable of generating
                        // >   information about four possible directions in which the knob can be
                        // >   tilted. Intermediate positions can also be decoded if the hardware
                        // >   allows two switches to be reported simultaneously.
                        //
                        // We assume this model here as well. Hence, with 4 switches and intermediate
                        // positions we have 8 values (0-7) plus the "null" state (8).
                        {
                            CFIndex min = IOHIDElementGetLogicalMin(element);
                            CFIndex max = IOHIDElementGetLogicalMax(element);

                            if (min != 0 || max != 7)
                            {
                                sf::err() << std::hex
                                          << "Joystick (vendor/product id: 0x" << m_identification.vendorId
                                          << "/0x" << m_identification.productId << std::dec
                                          << ") range is an unexpected one: [" << min << ", " << max << "]"
                                          << std::endl;
                            }
                            else
                            {
                                m_hat = element;
                            }
                        }
                        break;

                    case kHIDUsage_GD_GamePad:
                        // We assume a game pad is an application collection, meaning it doesn't hold
                        // any values per say. They kind of "emit" the joystick's usages.
                        // See §3.4.3 Usage Types (Collection) of HUT v1.12
                        if (IOHIDElementGetCollectionType(element) != kIOHIDElementCollectionTypeApplication)
                        {
                            sf::err() << std::hex << "Gamepage (vendor/product id: 0x" << m_identification.vendorId
                                      << "/0x" << m_identification.productId << ") is not an CA but a 0x"
                                      << IOHIDElementGetCollectionType(element) << std::dec << std::endl;
                        }
                        break;

                    default:
#ifdef SFML_DEBUG
                        sf::err() << "Unexpected usage for element of Page Generic Desktop: 0x" << std::hex << IOHIDElementGetUsage(element) << std::dec << std::endl;
#endif
                        break;
                }
                break;

            case kHIDPage_Button:
                if (m_buttons.size() < Joystick::ButtonCount) // If we have free slot...
                    m_buttons.push_back(element); // ...we add this element to the list
                // Else: too many buttons. We ignore this one.
                break;

            default: /* No other page is expected because of the mask applied by the HID manager. */ break;
        }
    }

    // Ensure that the buttons will be indexed in the same order as their
    // HID Usage (assigned by manufacturer and/or a driver).
    std::sort(m_buttons.begin(), m_buttons.end(), JoystickButtonSortPredicate);

    // Retain all these objects for personal use
    for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it)
        CFRetain(*it);
    for (AxisMap::iterator it(m_axis.begin()); it != m_axis.end(); ++it)
        CFRetain(it->second);
    if (m_hat != NULL)
        CFRetain(m_hat);

    // Note: we didn't retain element in the switch because we might have multiple
    // Axis X (for example) and we want to keep only the last one. To prevent
    // leaking we retain objects 'only' now.

    CFRelease(devices);
    CFRelease(elements);

    return true;
}
Example #22
0
bool JoystickImpl::isConnected(unsigned int index)
{
    bool state = false; // Is the index-th joystick connected?

    // First, let's check if the device was previously detected:
    if (m_locationIDs[index] != 0)
    {
        state = true;
    }
    else
    {
        // Otherwise, let's check if it is now connected
        // i.e., m_locationIDs[index] == 0

        // if there is more connected joystick to the HID manager than
        // opened joystick devices then we find the new one.

        unsigned int openedCount = 0;
        for (unsigned int i(0); i < sf::Joystick::Count; ++i)
        {
            if (m_locationIDs[i] != 0)
                openedCount++;
        }


        unsigned int connectedCount = HIDJoystickManager::getInstance().getJoystickCount();

        if (connectedCount > openedCount)
        {
            // Get all devices
            CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();

            if (devices != NULL)
            {
                CFIndex size = CFSetGetCount(devices);
                if (size > 0)
                {
                    CFTypeRef array[size]; // array of IOHIDDeviceRef
                    CFSetGetValues(devices, array);

                    // If there exists a device d s.t. there is no j s.t.
                    // m_locationIDs[j] == d's location then we have a new device.

                    for (CFIndex didx(0); didx < size; ++didx)
                    {
                        IOHIDDeviceRef d = (IOHIDDeviceRef)array[didx];
                        Location dloc = HIDInputManager::getLocationID(d);

                        bool foundJ = false;
                        for (unsigned int j(0); j < Joystick::Count; ++j)
                        {
                            if (m_locationIDs[j] == dloc)
                            {
                                foundJ = true;
                                break; // no need to loop again
                            }
                        }

                        if (!foundJ) {
                            // This is a new device
                            // We set it up for Open(..)
                            m_locationIDs[index] = dloc;
                            state = true;
                            break; // We stop looking for a new device
                        }
                    }
                }

                CFRelease(devices);
            }
        }
    }

    return state;
}
Example #23
0
struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	struct hid_device_info *root = NULL; // return object
	struct hid_device_info *cur_dev = NULL;
	CFIndex num_devices;
	int i;
	
	setlocale(LC_ALL,"");

	/* Set up the HID Manager if it hasn't been done */
	hid_init();
	
	/* Get a list of the Devices */
	CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr);

	/* Convert the list into a C array so we can iterate easily. */	
	num_devices = CFSetGetCount(device_set);
	IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef));
	CFSetGetValues(device_set, (const void **) device_array);

	/* Iterate over each device, making an entry for it. */	
	for (i = 0; i < num_devices; i++) {
		unsigned short dev_vid;
		unsigned short dev_pid;
		#define BUF_LEN 256
		wchar_t buf[BUF_LEN];
		char cbuf[BUF_LEN];

		IOHIDDeviceRef dev = device_array[i];

        if (!dev) {
            continue;
        }
		dev_vid = get_vendor_id(dev);
		dev_pid = get_product_id(dev);

		/* Check the VID/PID against the arguments */
		if ((vendor_id == 0x0 && product_id == 0x0) ||
		    (vendor_id == dev_vid && product_id == dev_pid)) {
			struct hid_device_info *tmp;
			size_t len;

		    	/* VID/PID match. Create the record. */
			tmp = malloc(sizeof(struct hid_device_info));
			if (cur_dev) {
				cur_dev->next = tmp;
			}
			else {
				root = tmp;
			}
			cur_dev = tmp;

			// Get the Usage Page and Usage for this device.
			cur_dev->usage_page = get_int_property(dev, CFSTR(kIOHIDPrimaryUsagePageKey));
			cur_dev->usage = get_int_property(dev, CFSTR(kIOHIDPrimaryUsageKey));

			/* Fill out the record */
			cur_dev->next = NULL;
			len = make_path(dev, cbuf, sizeof(cbuf));
			cur_dev->path = strdup(cbuf);

			/* Serial Number */
			get_serial_number(dev, buf, BUF_LEN);
			cur_dev->serial_number = dup_wcs(buf);

			/* Manufacturer and Product strings */
			get_manufacturer_string(dev, buf, BUF_LEN);
			cur_dev->manufacturer_string = dup_wcs(buf);
			get_product_string(dev, buf, BUF_LEN);
			cur_dev->product_string = dup_wcs(buf);
			
			/* VID/PID */
			cur_dev->vendor_id = dev_vid;
			cur_dev->product_id = dev_pid;

			/* Release Number */
			cur_dev->release_number = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey));

			/* Interface Number (Unsupported on Mac)*/
			cur_dev->interface_number = -1;
		}
	}
	
	free(device_array);
	CFRelease(device_set);
	
	return root;
}
Example #24
0
hid_device * HID_API_EXPORT hid_open_path(const char *path)
{
  	int i;
	hid_device *dev = NULL;
	CFIndex num_devices;
	
	dev = new_hid_device();

	/* Set up the HID Manager if it hasn't been done */
	hid_init();

	CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr);
	
	num_devices = CFSetGetCount(device_set);
	IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef));
	CFSetGetValues(device_set, (const void **) device_array);	
	for (i = 0; i < num_devices; i++) {
		char cbuf[BUF_LEN];
		size_t len;
		IOHIDDeviceRef os_dev = device_array[i];
		
		len = make_path(os_dev, cbuf, sizeof(cbuf));
		if (!strcmp(cbuf, path)) {
			// Matched Paths. Open this Device.
			IOReturn ret = IOHIDDeviceOpen(os_dev, kIOHIDOptionsTypeNone);
			if (ret == kIOReturnSuccess) {
				char str[32];

				free(device_array);
				CFRelease(device_set);
				dev->device_handle = os_dev;
				
				/* Create the buffers for receiving data */
				dev->max_input_report_len = (CFIndex) get_max_report_length(os_dev);
				dev->input_report_buf = calloc(dev->max_input_report_len, sizeof(uint8_t));
				
				/* Create the Run Loop Mode for this device.
				   printing the reference seems to work. */
				sprintf(str, "HIDAPI_%p", os_dev);
				dev->run_loop_mode = 
					CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII);
				
				/* Attach the device to a Run Loop */
				IOHIDDeviceRegisterInputReportCallback(
					os_dev, dev->input_report_buf, dev->max_input_report_len,
					&hid_report_callback, dev);
				IOHIDManagerRegisterDeviceRemovalCallback(hid_mgr, hid_device_removal_callback, NULL);
				
				/* Start the read thread */
				pthread_create(&dev->thread, NULL, read_thread, dev);

				/* Wait here for the read thread to be initialized. */
				pthread_barrier_wait(&dev->barrier);
				
				return dev;
			}
			else {
				goto return_error;
			}
		}
	}

return_error:
	free(device_array);
	CFRelease(device_set);
	free_hid_device(dev);
	return NULL;
}
Example #25
0
JoystickState JoystickImpl::update()
{
    static const JoystickState disconnectedState; // return this if joystick was disconnected
    JoystickState       state; // otherwise return that
    state.connected = true;

    // Note: free up is done in close() which is called, if required,
    //       by the joystick manager. So we don't release buttons nor axes here.

    // First, let's determine if the joystick is still connected
    Location selfLoc = m_locationIDs[m_index];

    // Get all devices
    CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
    if (devices == NULL)
        return disconnectedState;

    // Get a usable copy of the joysticks devices.
    CFIndex joysticksCount = CFSetGetCount(devices);
    CFTypeRef devicesArray[joysticksCount];
    CFSetGetValues(devices, devicesArray);

    // Search for it
    bool found = false;
    for (CFIndex i(0); i < joysticksCount; ++i)
    {
        IOHIDDeviceRef d = (IOHIDDeviceRef)devicesArray[i];
        if (selfLoc == HIDInputManager::getLocationID(d))
        {
            found = true;
            break; // Stop looping
        }
    }

    // Release unused stuff
    CFRelease(devices);

    // If not found we consider it disconnected
    if (!found)
        return disconnectedState;

    // Update buttons' state
    unsigned int i = 0;
    for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it, ++i)
    {
        IOHIDValueRef value = 0;
        IOHIDDeviceGetValue(IOHIDElementGetDevice(*it), *it, &value);

        // Check for plug out.
        if (!value)
        {
            // No value? Hum... Seems like the joystick is gone
            return disconnectedState;
        }

        // 1 means pressed, others mean released
        state.buttons[i] = IOHIDValueGetIntegerValue(value) == 1;
    }

    // Update axes' state
    for (AxisMap::iterator it = m_axis.begin(); it != m_axis.end(); ++it)
    {
        IOHIDValueRef value = 0;
        IOHIDDeviceGetValue(IOHIDElementGetDevice(it->second), it->second, &value);

        // Check for plug out.
        if (!value)
        {
            // No value? Hum... Seems like the joystick is gone
            return disconnectedState;
        }

        // We want to bind [physicalMin,physicalMax] to [-100=min,100=max].
        //
        // General formula to bind [a,b] to [c,d] with a linear progression:
        //
        // f: [a, b] -> [c, d]
        //        x  |->  (x-a)(d-c)/(b-a)+c
        //
        // This method might not be very accurate (the "0 position" can be
        // slightly shift with some device) but we don't care because most
        // of devices are so sensitive that this is not relevant.
        double  physicalMax   = IOHIDElementGetPhysicalMax(it->second);
        double  physicalMin   = IOHIDElementGetPhysicalMin(it->second);
        double  scaledMin     = -100;
        double  scaledMax     =  100;
        double  physicalValue = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical);
        float   scaledValue   = (((physicalValue - physicalMin) * (scaledMax - scaledMin)) / (physicalMax - physicalMin)) + scaledMin;
        state.axes[it->first] = scaledValue;
    }

    return state;
}