Пример #1
0
static IOReturn HIDCreateOpenDeviceInterface (io_object_t hidDevice, recDevice *pDevice)
{
	IOReturn result = kIOReturnSuccess;
	HRESULT plugInResult = S_OK;
	SInt32 score = 0;
	IOCFPlugInInterface ** ppPlugInInterface = NULL;
	
	if (NULL == pDevice->interface)
	{
		result = IOCreatePlugInInterfaceForService (hidDevice, kIOHIDDeviceUserClientTypeID,
													kIOCFPlugInInterfaceID, &ppPlugInInterface, &score);
		if (kIOReturnSuccess == result)
		{
			// Call a method of the intermediate plug-in to create the device interface
			plugInResult = (*ppPlugInInterface)->QueryInterface (ppPlugInInterface,
								CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID), (void *) &(pDevice->interface));
			if (S_OK != plugInResult)
				HIDReportErrorNum ("CouldnÕt query HID class device interface from plugInInterface", plugInResult);
			(*ppPlugInInterface)->Release (ppPlugInInterface);
		}
		else
			HIDReportErrorNum ("Failed to create **plugInInterface via IOCreatePlugInInterfaceForService.", result);
	}
	if (NULL != pDevice->interface)
	{
		result = (*(pDevice->interface))->open (pDevice->interface, 0);
		if (kIOReturnSuccess != result)
			HIDReportErrorNum ("Failed to open pDevice->interface via open.", result);
		else
			(*(pDevice->interface))->setRemovalCallback (pDevice->interface, HIDRemovalCallback, pDevice, pDevice);

	}
	return result;
}
Пример #2
0
static IOReturn
HIDCloseReleaseInterface(recDevice * pDevice)
{
    IOReturn result = kIOReturnSuccess;

    if ((NULL != pDevice) && (NULL != pDevice->interface)) {
        /* close the interface */
        result = (*(pDevice->interface))->close(pDevice->interface);
        if (kIOReturnNotOpen == result) {
            /* do nothing as device was not opened, thus can't be closed */
        } else if (kIOReturnSuccess != result)
            HIDReportErrorNum("Failed to close IOHIDDeviceInterface.",
                              result);
        /* release the interface */
        result = (*(pDevice->interface))->Release(pDevice->interface);
        if (kIOReturnSuccess != result)
            HIDReportErrorNum("Failed to release IOHIDDeviceInterface.",
                              result);
        pDevice->interface = NULL;
		
		if ( pDevice->portIterator )
		{
			IOObjectRelease( pDevice->portIterator );
			pDevice->portIterator = 0;
		}
    }
    return result;
}
// 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 */
Пример #4
0
static recDevice *
HIDDisposeDevice(recDevice ** ppDevice)
{
    kern_return_t result = KERN_SUCCESS;
    recDevice *pDeviceNext = NULL;
    if (*ppDevice) {
        /* save next device prior to disposing of this device */
        pDeviceNext = (*ppDevice)->pNext;

        /* free posible io_service_t */
        if ((*ppDevice)->ffservice) {
            IOObjectRelease((*ppDevice)->ffservice);
            (*ppDevice)->ffservice = 0;
        }

        /* free element lists */
        HIDDisposeElementList(&(*ppDevice)->firstAxis);
        HIDDisposeElementList(&(*ppDevice)->firstButton);
        HIDDisposeElementList(&(*ppDevice)->firstHat);

        result = HIDCloseReleaseInterface(*ppDevice);   /* function sanity checks interface value (now application does not own device) */
        if (kIOReturnSuccess != result)
            HIDReportErrorNum
                ("HIDCloseReleaseInterface failed when trying to dipose device.",
                 result);
        DisposePtr((Ptr) * ppDevice);
        *ppDevice = NULL;
    }
    return pDeviceNext;
}
Пример #5
0
IOReturn HIDCloseReleaseInterface (recDevice *pDevice)
{
	IOReturn result = kIOReturnSuccess;
	
	if ((NULL != pDevice) && (NULL != pDevice->interface))
	{
		// close the interface
		result = (*(pDevice->interface))->close (pDevice->interface);
		if (kIOReturnNotOpen == result)
		{
			//  do nothing as device was not opened, thus can't be closed
		}
		else if (kIOReturnSuccess != result)
			HIDReportErrorNum ("Failed to close IOHIDDeviceInterface.", result);
		//release the interface
		result = (*(pDevice->interface))->Release (pDevice->interface);
		if (kIOReturnSuccess != result)
			HIDReportErrorNum ("Failed to release IOHIDDeviceInterface.", result);
		pDevice->interface = NULL;
	}	
	return result;
}
// releases all device queues for quit or rebuild (must be called)
// does not release device interfaces, application must call ReleaseHIDDeviceList on exit
IOReturn HIDReleaseAllDeviceQueues( void )
{
	IOReturn result = kIOReturnSuccess;
	IOHIDDeviceRef tIOHIDDeviceRef = HIDGetFirstDevice();
	while ( tIOHIDDeviceRef ) {
		result = HIDDequeueDevice( tIOHIDDeviceRef );
		
		if ( kIOReturnSuccess != result ) {
			HIDReportErrorNum( "Could not dequeue device.", result );
		}
		tIOHIDDeviceRef = HIDGetNextDevice( tIOHIDDeviceRef );
	}
	return result;
} /* HIDReleaseAllDeviceQueues */
// 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 */
// ---------------------------------
// 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 */
// ---------------------------------
// 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 */
Пример #10
0
static IOReturn
HIDCreateOpenDeviceInterface(io_object_t hidDevice, recDevice * pDevice)
{
    IOReturn result = kIOReturnSuccess;
    HRESULT plugInResult = S_OK;
    SInt32 score = 0;
    IOCFPlugInInterface **ppPlugInInterface = NULL;

    if (NULL == pDevice->interface) {
        result =
            IOCreatePlugInInterfaceForService(hidDevice,
                                              kIOHIDDeviceUserClientTypeID,
                                              kIOCFPlugInInterfaceID,
                                              &ppPlugInInterface, &score);
        if (kIOReturnSuccess == result) {
            /* Call a method of the intermediate plug-in to create the device interface */
            plugInResult =
                (*ppPlugInInterface)->QueryInterface(ppPlugInInterface,
                                                     CFUUIDGetUUIDBytes
                                                     (kIOHIDDeviceInterfaceID),
                                                     (void *)
                                                     &(pDevice->interface));
            if (S_OK != plugInResult)
                HIDReportErrorNum
                    ("CouldnÕt query HID class device interface from plugInInterface",
                     plugInResult);
            (*ppPlugInInterface)->Release(ppPlugInInterface);
        } else
            HIDReportErrorNum
                ("Failed to create **plugInInterface via IOCreatePlugInInterfaceForService.",
                 result);
    }
    if (NULL != pDevice->interface) {
        result = (*(pDevice->interface))->open(pDevice->interface, 0);
        if (kIOReturnSuccess != result)
            HIDReportErrorNum
                ("Failed to open pDevice->interface via open.", result);
        else
		{
			pDevice->portIterator = 0;

			// It's okay if this fails, we have another detection method below
            (*(pDevice->interface))->setRemovalCallback(pDevice->interface,
                                                        HIDRemovalCallback,
                                                        pDevice, pDevice);
			
			/* now connect notification for new devices */
			pDevice->notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
			
			CFRunLoopAddSource(CFRunLoopGetCurrent(), 
							   IONotificationPortGetRunLoopSource(pDevice->notificationPort), 
							   kCFRunLoopDefaultMode);
			
			// Register for notifications when a serial port is added to the system
			result = IOServiceAddInterestNotification(pDevice->notificationPort,
													  hidDevice,
													  kIOGeneralInterest,
													  JoystickDeviceWasRemovedCallback,
													  pDevice,           
													  &pDevice->portIterator);
        	if (kIOReturnSuccess != result) {
            	HIDReportErrorNum
                	("Failed to register for removal callback.", result);		
			}	
		}

    }
    return result;
}