예제 #1
0
////////////////////////////////////////////////////////////
/// Enumerate all attached joystick/gamepad controllers
////////////////////////////////////////////////////////////
int JoystickSupport::EnumerateDevices(std::vector<JoystickDevice> &devices)
{
	IOReturn ioRes = IOMasterPort(bootstrap_port, &myMasterPort);
	
	if (ioRes != kIOReturnSuccess)
		return 0;

	CFMutableDictionaryRef	hidMatchDictionary	= 0;
	io_iterator_t			hidObjectIterator	= 0;

	hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
	
	ioRes = IOServiceGetMatchingServices( myMasterPort, hidMatchDictionary, &hidObjectIterator );
				
	if ((ioRes != kIOReturnSuccess) || (hidObjectIterator == nil))
	{
		return 0;
	}

	io_object_t 			hidDevice;
	kern_return_t 			result;
	CFMutableDictionaryRef 	properties;
	CFTypeRef 				object;
	long 					usagePage, usage, locationID;

	while ((hidDevice = IOIteratorNext(hidObjectIterator)))
	{
		result = IORegistryEntryCreateCFProperties(hidDevice, &properties, kCFAllocatorDefault, kNilOptions);

		if ((result != KERN_SUCCESS) || (properties == nil))
			continue;
				
		object = CFDictionaryGetValue(properties, CFSTR(kIOHIDPrimaryUsagePageKey));
		if (object)
		{
			if (!CFNumberGetValue((CFNumberRef)object, kCFNumberLongType, &usagePage))
				continue;

			object = CFDictionaryGetValue(properties, CFSTR(kIOHIDPrimaryUsageKey));
	
			if (object)
			{
				if(!CFNumberGetValue((CFNumberRef)object, kCFNumberLongType, &usage))
					continue;
			}
		}
					
		object = CFDictionaryGetValue(properties, CFSTR(kIOHIDLocationIDKey));
		if (!object)
			locationID = 0;		
		else
		{
			if(!CFNumberGetValue((CFNumberRef)object, kCFNumberLongType, &locationID))
				locationID = 0;
		}
	
	    if (usagePage == kHIDPage_GenericDesktop)
		{
			switch(usage)
			{
				case kHIDUsage_GD_Joystick :
				case kHIDUsage_GD_GamePad :
				{
					JoystickDevice	Joystick;
			
					EnumerateElements(properties, &Joystick);

					if (GetDeviceInterface(&hidDevice, Joystick) == kIOReturnSuccess)
					{
						devices.push_back(Joystick);
						std::cout << "Device with " << Joystick.axis.size() << " axes and " << Joystick.buttons.size() << " buttons was found." << std::endl;
					}
				}
				break;
			}
		}
		
		CFRelease(properties);

		ioRes = IOObjectRelease(hidDevice);

		if(ioRes != kIOReturnSuccess)
			std::cout << "Error releasing device" << std::endl;			
	}
			
	IOObjectRelease(hidObjectIterator);
	
	return 1;
}
예제 #2
0
파일: main.cpp 프로젝트: arnelh/Examples
int
main ( int argc, const char * argv[] ) 
{

	//
	// allocate our DMA buffers using vm_allocate
	//
	
	vm_address_t	buffer = nil ;
	::vm_allocate( mach_task_self(), & buffer, kBufferSize, true ) ;
	
	assert( buffer ) ;

	//
	// split up vm_allocated buffer into buffers we will use
	// in our DMA program
	//
	
	UInt8*	buffers[3] = { (UInt8*)buffer, (UInt8*)buffer + 1024, (UInt8*)buffer + 4096 } ;

	//
	// put test data into our DMA program buffers
	//
	
	snprintf( reinterpret_cast<char*>(buffers[0]), 1024, "sample text in a buffer" ) ;
	snprintf( reinterpret_cast<char*>(buffers[1]), 3048, "<this space intentionally left blank>" ) ;
	snprintf( reinterpret_cast<char*>(buffers[2]), 1024, "next sample text is here" ) ;

	//
	// run test
	//
	
	IOReturn	error 			= kIOReturnSuccess ;
	
	cout << i++ << "\n### SETTING UP\n" ;
	
	for( int index=0; index < 3; ++index )
		cout << i << "buffers[" << index << "] " << (char*)(buffers[index]) << endl ;
	
	cout << i++ << "Getting device interface...\n" ;

	IOFireWireLibNubRef				localNode		= 0 ;
	IOCFPlugInInterfaceRef			cfPlugInInterface ;

	error = GetDeviceInterface( & cfPlugInInterface, & localNode ) ;
	cout << i-- << "..." << _success << endl ;
			
	if ( !error )
	{
		cout << i << "Opening...\n" ;
		error = (**localNode).Open( localNode ) ;
	}
	
//	if (!error)
//	{
//		error = (**localNode).AddCallbackDispatcherToRunLoop( localNode, ::CFRunLoopGetCurrent() ) ;
//		if (!error)
//			(**localNode).TurnOnNotification( localNode ) ;
//	}

	if ( !error )
	{
		cout << i++ << "Adding isoch dispatcher to run loop...\n" ;

		error = (**localNode).AddIsochCallbackDispatcherToRunLoop( localNode, CFRunLoopGetCurrent() ) ;
	}
	
	
	IOFireWireLibDCLCommandPoolRef		commandPool 	= 0 ;
	IOFireWireLibRemoteIsochPortRef		remoteIsochPort	= 0 ;
	IOFireWireLibLocalIsochPortRef		localIsochPort	= 0 ;
	IOFireWireLibIsochChannelRef		isochChannel	= 0 ;
	
	if ( !error )
	{
		cout << i++ << "Creating DCL command pool...\n" ;
		error = CreateDCLCommandPool( localNode, & commandPool ) ;
	}
	
	if ( !error )
	{
		cout << i++ << "Creating remote isochronous port...\n" ;
		error = CreateRemoteIsochPort( localNode, & remoteIsochPort ) ;
		cout << i-- << "..." << _success << endl ;
	}
	
	if ( !error )
	{
		cout << i << "Creating local isoch port...\n" ;
		error = CreateLocalIsochPort( localNode, buffers, commandPool, & localIsochPort ) ;
		cout << i-- << "..." << _success << endl ;
	}

	if ( !error )
	{
		cout << i++ << "Creating isoch channel...\n" ;
		error = CreateIsochChannel( localNode, & isochChannel ) ;
		cout << i-- << "..." << _success << endl ;
	}
	
		// remote is listener
	if ( !error )
	{
		cout << i++ << "Adding listener to isoch channel...\n" ;
		error = (**isochChannel).AddListener( isochChannel, (IOFireWireLibIsochPortRef) remoteIsochPort ) ;
		cout << i-- << "..." << _success << endl ;
	}
	
		// local is talker
	if ( !error )
	{
		cout << i++ << "Setting talker on isoch channel...\n" ;
		error = (**isochChannel).SetTalker( isochChannel, (IOFireWireLibIsochPortRef) localIsochPort ) ;
		cout << i-- << "..." << _success << endl ;
	}
	
	if ( !error )
	{
		cout << i++ << "Allocating channel...\n" ;
		error = (**isochChannel).AllocateChannel( isochChannel ) ;
		cout << i-- << "..." << _success << endl ;
	}

	i-- ;	// unindent
	
	// run for approx. 15 seconds
	cout << i++ << "\n### RUNNING\n" ;

	if ( !error )
	{
		if ( !error )
		{
			cout << i++ << "Starting channel...\n" ;
			error = (**isochChannel).Start( isochChannel ) ;
			cout << i-- << "..." << _success << endl ;
		}
		
		cout << i << "\nRunning...\n" ;

		SInt16	runLoopResult ;
		while (  kCFRunLoopRunHandledSource == ( runLoopResult = CFRunLoopRunInMode( kCFRunLoopDefaultMode, 30, false ) ) ) 
		{
		}
		
		error = (**isochChannel).Stop( isochChannel ) ;
		
		cout << i-- << "done!\n" ;
				
		// clean up
		cout << i++ << "\n### CLEAN UP ###\n\n" ;
	
		// release all interfaces
		if ( isochChannel )
		{
			cout << i++ << "releasing isoch channel.\n" ;
	
			if ( error != kIOReturnSuccess )
				cout << i << _file << "error " << error << " stopping channel.\n" ;
			
			error = (**isochChannel).ReleaseChannel( isochChannel ) ;
			if ( error != kIOReturnSuccess )
				cout << i << _file << "error " << error << " from ReleaseChannel().\n" ;
	
			(**isochChannel).Release( isochChannel ) ;
			
			i-- ;
		}
			
		if ( localIsochPort )
		{
			cout << i << "releasing local port.\n" ;

			(**localIsochPort).Release( localIsochPort ) ;
		}
		
		if ( remoteIsochPort )
		{
			cout << i << "releasing remote port.\n" ;
			(**remoteIsochPort).Release( remoteIsochPort ) ;
		}
	}
	
	if ( localNode )
	{
		cout << i << "releasing local node interface.\n" ;
		(**localNode).Close( localNode ) ;
		(**localNode).Release( localNode ) ;
	}
	
	//
	// release the original CFPlugInInterface
	//
	
	if ( cfPlugInInterface )
	{
		cout << i << "releasing CFPlugInInterface.\n" ;
		IODestroyPlugInInterface( cfPlugInInterface ) ;
	}
	
	//
	// deallocate our DMA buffers
	//
	
	if (buffer)
	{
		::vm_deallocate( mach_task_self(), buffer, kBufferSize ) ;
	}
	
	cout << i << "### DONE\n" ;
	return (error == kIOReturnSuccess) ? EXIT_SUCCESS : EXIT_FAILURE ;
}