// adds all elements to queue, performing any device queue set up required
// queue is started and ready to return events on exit from this function
int  HIDQueueDevice( IOHIDDeviceRef inIOHIDDeviceRef )
{
	IOReturn result = kIOReturnSuccess;
	
	// error checking
	if ( !inIOHIDDeviceRef ) {
		HIDReportError( "Device does not exist, cannot queue device." );
		return kIOReturnBadArgument;
	}
	
	if ( !inIOHIDDeviceRef ) { // must have interface
		HIDReportError( "Device does not have hid device ref, cannot queue device." );
		return kIOReturnError;
	}
	
	IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
	if ( !tIOHIDQueueRef ) {         // if no queue create queue
		result = HIDCreateQueue( inIOHIDDeviceRef );
		if ( kIOReturnSuccess == result ) {
			tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
		}
	}
	
	if ( ( kIOReturnSuccess != result ) || ( !tIOHIDQueueRef ) ) {
		HIDReportErrorNum( "Could not queue device due to problem creating queue.", result );
		
		if ( kIOReturnSuccess != result ) {
			return result;
		} else {
			return kIOReturnError;
		}
	}
	
	// stop queue
	IOHIDQueueStop( tIOHIDQueueRef );
	
	// queue element
	IOHIDElementRef tIOHIDElementRef = HIDGetFirstDeviceElement( inIOHIDDeviceRef, kHIDElementTypeIO );
	while ( tIOHIDElementRef ) {
		if ( !IOHIDQueueContainsElement( tIOHIDQueueRef, tIOHIDElementRef ) ) {
			IOHIDQueueAddElement( tIOHIDQueueRef, tIOHIDElementRef );
		}
		tIOHIDElementRef = HIDGetNextDeviceElement( tIOHIDElementRef, kHIDElementTypeIO );
	}
	
	// restart queue
	IOHIDQueueStart( tIOHIDQueueRef );
	
	return result;
} /* HIDQueueDevice */
// creates a queue for a device, creates and opens device interface if required
static IOReturn HIDCreateQueue( IOHIDDeviceRef inIOHIDDeviceRef )
{
	IOReturn result = kIOReturnSuccess;
	
	if ( inIOHIDDeviceRef ) {
		assert( IOHIDDeviceGetTypeID() == CFGetTypeID( inIOHIDDeviceRef ) );
		
		// do we already have a queue?
		IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
		
		if ( tIOHIDQueueRef ) { // (yes)
			assert( IOHIDQueueGetTypeID() == CFGetTypeID( tIOHIDQueueRef ) );
		} else {
			tIOHIDQueueRef = IOHIDQueueCreate( kCFAllocatorDefault, inIOHIDDeviceRef, kDeviceQueueSize, kIOHIDOptionsTypeNone );
			
			if ( tIOHIDQueueRef ) { // did that work
				HIDReportErrorNum( "Failed to create queue via create", result );
			} else {
				result = kIOReturnSuccess;
			}
		}
	} else {
		HIDReportErrorNum( "HID device ref does not exist for queue creation", result );
	}
	return result;
} /* HIDCreateQueue */
// queues specific element, performing any device queue set up required
// queue is started and ready to return events on exit from this function
int  HIDQueueElement( IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef )
{
	IOReturn result = kIOReturnSuccess;
	
	if ( inIOHIDDeviceRef ) {
		assert( IOHIDDeviceGetTypeID() == CFGetTypeID( inIOHIDDeviceRef ) );
		if ( inIOHIDElementRef ) {
			assert( IOHIDElementGetTypeID() == CFGetTypeID( inIOHIDElementRef ) );
			IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
			if ( !tIOHIDQueueRef ) {         // if no queue create queue
				result = HIDCreateQueue( inIOHIDDeviceRef );
				if ( kIOReturnSuccess == result ) {
					tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
				}
			}
			if ( tIOHIDQueueRef ) {
				
				// stop queue
				IOHIDQueueStop( tIOHIDQueueRef );
				
				// queue element
				if ( !IOHIDQueueContainsElement( tIOHIDQueueRef, inIOHIDElementRef ) ) {
					IOHIDQueueAddElement( tIOHIDQueueRef, inIOHIDElementRef );
				}
				
				// restart queue
				IOHIDQueueStart( tIOHIDQueueRef );
			} else {
				HIDReportError( "No queue for device passed to HIDQueueElement." );
				if ( kIOReturnSuccess == result ) {
					result = kIOReturnError;
				}
			}
		} else {
			HIDReportError( "NULL element passed to HIDQueueElement." );
			result = kIOReturnBadArgument;
		}
	} else {
		HIDReportError( "NULL device passed to HIDQueueElement." );
		result = kIOReturnBadArgument;
	}
	return result;
} /* HIDQueueElement */
Exemplo n.º 4
0
// disposes and releases queue, sets queue to NULL,.
// Note: will have no effect if device or queue do not exist
static IOReturn HIDDisposeReleaseQueue(IOHIDDeviceRef inIOHIDDeviceRef) {
	IOReturn result = kIOReturnSuccess;
	if (inIOHIDDeviceRef) {
		IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
		if (tIOHIDQueueRef) {
			// stop queue
			IOHIDQueueStop(tIOHIDQueueRef);
            
			// release the queue
			CFRelease(tIOHIDQueueRef);
		}
	} else {
		HIDReportError("NULL device passed to HIDDisposeReleaseQueue.");
	}
    
	return (result);
} /* HIDDisposeReleaseQueue */
// ---------------------------------
// removes element for queue, if last element in queue will release queue and closes device interface
int  HIDDequeueElement( IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef )
{
	IOReturn result = kIOReturnSuccess;
	
	if ( inIOHIDDeviceRef ) {
		assert( IOHIDDeviceGetTypeID() == CFGetTypeID( inIOHIDDeviceRef ) );
		if ( inIOHIDElementRef ) {
			assert( IOHIDElementGetTypeID() == CFGetTypeID( inIOHIDElementRef ) );
			IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
			if ( tIOHIDQueueRef ) {
				// stop queue
				IOHIDQueueStop( tIOHIDQueueRef );
				
				// de-queue element
				if ( IOHIDQueueContainsElement( tIOHIDQueueRef, inIOHIDElementRef ) ) {
					IOHIDQueueRemoveElement( tIOHIDQueueRef, inIOHIDElementRef );
				}
				
				// release device queue and close interface if queue empty
				if ( HIDIsDeviceQueueEmpty( inIOHIDDeviceRef ) ) {
					result = HIDDisposeReleaseQueue( inIOHIDDeviceRef );
					
					if ( kIOReturnSuccess != result ) {
						HIDReportErrorNum( "Failed to dispose and release queue.", result );
					}
				} else { // not empty so restart queue
					IOHIDQueueStart( tIOHIDQueueRef );
				}
			} else {
				HIDReportError( "No queue for device passed to HIDDequeueElement." );
				if ( kIOReturnSuccess == result ) {
					result = kIOReturnError;
				}
			}
		} else {
			HIDReportError( "NULL element passed to HIDDequeueElement." );
			result = kIOReturnBadArgument;
		}
	} else {
		HIDReportError( "NULL device passed to HIDDequeueElement." );
		result = kIOReturnBadArgument;
	}
	return result;
} /* HIDDequeueElement */
Exemplo n.º 6
0
// ---------------------------------
// Get the next event in the queue for a device
// elements or entire device should be queued prior to calling this with HIDQueueElement or HIDQueueDevice
// returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise
// Note: kIOReturnUnderrun returned from getNextEvent indicates an empty queue not an error condition
// Note: application should pass in a pointer to a IOHIDEventStruct cast to a void (for CFM compatibility)
unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef) {
	if (inIOHIDDeviceRef) {
		IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
		if (tIOHIDQueueRef) {
			if (pIOHIDValueRef) {
				*pIOHIDValueRef = IOHIDQueueCopyNextValueWithTimeout(tIOHIDQueueRef, 0.0);
				if (*pIOHIDValueRef) {
					return (true);
				}
			}
		} else {
			HIDReportError( "Could not get HID event, hid queue reference does not exist.");
		}
	} else {
        HIDReportError( "Could not get HID event, device does not exist.");
	}
    
	return (false);     // did not get event
} /* HIDGetEvent */
// ---------------------------------
// completely removes all elements from queue and releases queue and closes device interface
// does not release device interfaces, application must call ReleaseHIDDeviceList on exit
int  HIDDequeueDevice( IOHIDDeviceRef inIOHIDDeviceRef )
{
	
	IOReturn result = kIOReturnSuccess;
	
	// error checking
	if ( !inIOHIDDeviceRef ) {
		HIDReportError( "Device does not exist, cannot queue device." );
		return kIOReturnBadArgument;
	}
	
	if ( !inIOHIDDeviceRef ) { // must have interface
		HIDReportError( "Device does not have hid device ref, cannot queue device." );
		return kIOReturnError;
	}
	
	IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
	
	if ( tIOHIDQueueRef ) {
		// iterate through elements and if queued, remove
		IOHIDElementRef tIOHIDElementRef = HIDGetFirstDeviceElement( inIOHIDDeviceRef, kHIDElementTypeIO );
		while ( tIOHIDElementRef ) {
			// de-queue element
			if ( IOHIDQueueContainsElement( tIOHIDQueueRef, tIOHIDElementRef ) ) {
				IOHIDQueueRemoveElement( tIOHIDQueueRef, tIOHIDElementRef );
			}
			tIOHIDElementRef = HIDGetNextDeviceElement( tIOHIDElementRef, kHIDElementTypeIO );
		}
		// ensure queue is disposed and released
		result = HIDDisposeReleaseQueue( inIOHIDDeviceRef );
		
		if ( kIOReturnSuccess != result ) {
			HIDReportErrorNum( "Failed to dispose and release queue.", result );
		}
	} else {
		HIDReportError( "No queue for device passed to HIDDequeueElement." );
		if ( kIOReturnSuccess == result ) {
			result = kIOReturnError;
		}
	}
	return result;
} /* HIDDequeueDevice */
// ---------------------------------
// returns true if queue is empty false otherwise
// error if no device, empty if no queue
static unsigned char HIDIsDeviceQueueEmpty( IOHIDDeviceRef inIOHIDDeviceRef )
{
	if ( inIOHIDDeviceRef ) { // need device and queue
		assert( IOHIDDeviceGetTypeID() == CFGetTypeID( inIOHIDDeviceRef ) );
		IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue( inIOHIDDeviceRef );
		if ( tIOHIDQueueRef ) {
			IOHIDElementRef tIOHIDElementRef = HIDGetFirstDeviceElement( inIOHIDDeviceRef, kHIDElementTypeIO );
			while ( tIOHIDElementRef ) {
				if ( IOHIDQueueContainsElement( tIOHIDQueueRef, tIOHIDElementRef ) ) {
					return false;
				}
				tIOHIDElementRef = HIDGetNextDeviceElement( tIOHIDElementRef, kHIDElementTypeIO );
			}
		} else {
			HIDReportError( "NULL device passed to HIDIsDeviceQueueEmpty." );
		}
	} else {
		HIDReportError( "NULL device passed to HIDIsDeviceQueueEmpty." );
	}
	return true;
} /* HIDIsDeviceQueueEmpty */
Exemplo n.º 9
0
// utility routine to dump device info
void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef) {
	char cstring[256];
	
	printf("Device: %p = { ", inIOHIDDeviceRef);
	
	char        manufacturer[256] = ""; // name of manufacturer
	CFStringRef tCFStringRef      = IOHIDDevice_GetManufacturer(inIOHIDDeviceRef);
	if (tCFStringRef) {
		(void) CFStringGetCString(tCFStringRef, manufacturer, sizeof(manufacturer), kCFStringEncodingUTF8);
	}
	
	char product[256] = "";      // name of product
	tCFStringRef = IOHIDDevice_GetProduct(inIOHIDDeviceRef);
	if (tCFStringRef) {
		(void) CFStringGetCString(tCFStringRef, product, sizeof(product), kCFStringEncodingUTF8);
	}
	
	printf("%s - %s, ", manufacturer, product);
	
	long vendorID = IOHIDDevice_GetVendorID(inIOHIDDeviceRef);
	if (vendorID) {
		if ( HIDGetVendorNameFromVendorID(vendorID, cstring) ) {
			printf(" vendorID: 0x%04lX (\"%s\"), ", vendorID, cstring);
		} else {
			printf(" vendorID: 0x%04lX, ",          vendorID);
		}
	}
	
	long productID = IOHIDDevice_GetProductID(inIOHIDDeviceRef);
	if (productID) {
		if ( HIDGetProductNameFromVendorProductID(vendorID, productID, cstring) ) {
			printf(" productID: 0x%04lX (\"%s\"), ", productID, cstring);
		} else {
			printf(" productID: 0x%04lX, ",          productID);
		}
	}
	
	uint32_t usagePage = IOHIDDevice_GetUsagePage(inIOHIDDeviceRef);
	uint32_t usage     = IOHIDDevice_GetUsage(inIOHIDDeviceRef);
	if (!usagePage || !usage) {
		usagePage = IOHIDDevice_GetPrimaryUsagePage(inIOHIDDeviceRef);
		usage     = IOHIDDevice_GetPrimaryUsage(inIOHIDDeviceRef);
	}
	
	printf("usage: 0x%04lX:0x%04lX, ", (long unsigned int) usagePage, (long unsigned int) usage);
	
	tCFStringRef = HIDCopyUsageName(usagePage, usage);
	if (tCFStringRef) {
		(void) CFStringGetCString(tCFStringRef, cstring, sizeof(cstring), kCFStringEncodingUTF8);
		printf("\"%s\", ", cstring);
		CFRelease(tCFStringRef);
	}

	tCFStringRef = IOHIDDevice_GetTransport(inIOHIDDeviceRef);
	if (tCFStringRef) {
		(void) CFStringGetCString(tCFStringRef, cstring, sizeof(cstring), kCFStringEncodingUTF8);
		printf("Transport: \"%s\", ", cstring);
	}
	
	long vendorIDSource = IOHIDDevice_GetVendorIDSource(inIOHIDDeviceRef);
	if (vendorIDSource) {
		printf("VendorIDSource: %ld, ", vendorIDSource);
	}
	
	long version = IOHIDDevice_GetVersionNumber(inIOHIDDeviceRef);
	if (version) {
		printf("version: %ld, ", version);
	}
	
	tCFStringRef = IOHIDDevice_GetSerialNumber(inIOHIDDeviceRef);
	if (tCFStringRef) {
		(void) CFStringGetCString(tCFStringRef, cstring, sizeof(cstring), kCFStringEncodingUTF8);
		printf("SerialNumber: \"%s\", ", cstring);
	}
	
	long country = IOHIDDevice_GetCountryCode(inIOHIDDeviceRef);
	if (country) {
		printf("CountryCode: %ld, ", country);
	}
	
	long locationID = IOHIDDevice_GetLocationID(inIOHIDDeviceRef);
	if (locationID) {
		printf("locationID: 0x%08lX, ", locationID);
	}
	
#if false
	CFArrayRef pairs = IOHIDDevice_GetUsagePairs(inIOHIDDeviceRef);
	if (pairs) {
		CFIndex idx, cnt = CFArrayGetCount(pairs);
		for (idx = 0; idx < cnt; idx++) {
			const void * pair = CFArrayGetValueAtIndex(pairs, idx);
			CFShow(pair);
		}
	}
#endif // if false

	long maxInputReportSize = IOHIDDevice_GetMaxInputReportSize(inIOHIDDeviceRef);
	if (maxInputReportSize) {
		printf("MaxInputReportSize: %ld, ", maxInputReportSize);
	}
	
	long maxOutputReportSize = IOHIDDevice_GetMaxOutputReportSize(inIOHIDDeviceRef);
	if (maxOutputReportSize) {
		printf("MaxOutputReportSize: %ld, ", maxOutputReportSize);
	}
	
	long maxFeatureReportSize = IOHIDDevice_GetMaxFeatureReportSize(inIOHIDDeviceRef);
	if (maxFeatureReportSize) {
		printf("MaxFeatureReportSize: %ld, ", maxOutputReportSize);
	}
	
	long reportInterval = IOHIDDevice_GetReportInterval(inIOHIDDeviceRef);
	if (reportInterval) {
		printf("ReportInterval: %ld, ", reportInterval);
	}
	
	IOHIDQueueRef queueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
	if (queueRef) {
		printf("queue: %p, ", queueRef);
	}
	
	IOHIDTransactionRef transactionRef = IOHIDDevice_GetTransaction(inIOHIDDeviceRef);
	if (transactionRef) {
		printf("transaction: %p, ", transactionRef);
	}
	
	printf("}\n");
	fflush(stdout);
}   // HIDDumpDeviceInfo