IOHIDTransactionClass.cpp [plain text]
#define CFRUNLOOP_NEW_API 1
#include <AssertMacros.h>
#include <CoreFoundation/CFMachPort.h>
#include "IOHIDTransactionClass.h"
#include "IOHIDLibUserClient.h"
#include "IOHIDTransactionElement.h"
__BEGIN_DECLS
#include <mach/mach_interface.h>
#include <mach/mach.h>
#include <System/libkern/OSCrossEndian.h>
__END_DECLS
#define ownerCheck() do { \
if (!fOwningDevice) \
return kIOReturnNoDevice; \
} while (0)
#define connectCheck() do { \
if ((!fOwningDevice) || \
(!fOwningDevice->fConnection)) \
return kIOReturnNoDevice; \
} while (0)
#define createdCheck() do { \
if (!fIsCreated) \
return kIOReturnError; \
} while (0)
#define openCheck() do { \
if (!fOwningDevice || \
!fOwningDevice->fIsOpen) \
return kIOReturnNotOpen; \
} while (0)
#define seizeCheck() do { \
if ((!fOwningDevice) || \
(!fOwningDevice->isValid())) \
return kIOReturnExclusiveAccess;\
} while (0)
#define mostChecks() do { \
connectCheck(); \
createdCheck(); \
} while (0)
#define allChecks() do { \
mostChecks(); \
openCheck(); \
seizeCheck(); \
} while (0)
IOHIDTransactionClass::IOHIDTransactionClass() : IOHIDIUnknown(NULL)
{
fHIDTransaction.pseudoVTable = (IUnknownVTbl *) &sHIDTransactionInterface;
fHIDTransaction.obj = this;
fDirection = 0;
fIsCreated = false;
fOwningDevice = NULL;
fEventCallback = NULL;
fEventRefcon = NULL;
fElementDictionaryRef = NULL;
}
IOHIDTransactionClass::~IOHIDTransactionClass()
{
if (fIsCreated)
dispose();
if( fOwningDevice )
fOwningDevice->detachTransaction(this);
}
HRESULT IOHIDTransactionClass::queryInterface(REFIID iid, void ** ppv)
{
CFUUIDRef uuid = CFUUIDCreateFromUUIDBytes(NULL, iid);
HRESULT res = S_OK;
if (CFEqual(uuid, kIOHIDDeviceTransactionInterfaceID))
{
*ppv = getInterfaceMap();
addRef();
}
else {
res = fOwningDevice->queryInterface(iid, ppv);
}
if (!*ppv)
res = E_NOINTERFACE;
CFRelease(uuid);
return res;
}
IOReturn IOHIDTransactionClass::getAsyncEventSource(CFTypeRef *source)
{
connectCheck();
return fOwningDevice->getAsyncEventSource(source);
}
void IOHIDTransactionClass::_eventSourceCallback(CFMachPortRef *cfPort __unused, mach_msg_header_t *msg __unused, CFIndex size __unused, void *info)
{
IOHIDTransactionClass *transaction = (IOHIDTransactionClass *)info;
if ( transaction && transaction->fEventCallback)
{
(transaction->fEventCallback)(transaction->fEventRefcon, kIOReturnSuccess, (void *)&transaction->fHIDTransaction);
}
}
IOReturn IOHIDTransactionClass::getAsyncPort(mach_port_t *port)
{
connectCheck();
return fOwningDevice->getAsyncPort(port);
}
IOReturn IOHIDTransactionClass::getDirection(IOHIDTransactionDirectionType * pDirection)
{
if (!pDirection)
return kIOReturnBadArgument;
*pDirection = fDirection;
return kIOReturnSuccess;
}
IOReturn IOHIDTransactionClass::setDirection(IOHIDTransactionDirectionType direction, IOOptionBits options __unused)
{
CFIndex numElements = 0;
IOReturn result = 0;
require_action(fIsCreated && fElementDictionaryRef, exit, result=kIOReturnError);
numElements = CFDictionaryGetCount(fElementDictionaryRef);
if ( numElements ) {
IOHIDTransactionElementRef * elementRefs = NULL;
IOHIDElementRef element = NULL;
CFStringRef * keyRefs = NULL;
elementRefs = (IOHIDTransactionElementRef *)malloc(sizeof(IOHIDTransactionElementRef) * numElements);
keyRefs = (CFStringRef *)malloc(sizeof(CFStringRef) * numElements);
CFDictionaryGetKeysAndValues(fElementDictionaryRef, (const void **)keyRefs, (const void **)elementRefs);
for (int i=0;i<numElements && elementRefs[i] && keyRefs[i]; i++) {
element = IOHIDTransactionElementGetElement(elementRefs[i]);
if (((IOHIDElementGetType(element) == kIOHIDElementTypeOutput) && (direction == kIOHIDTransactionDirectionTypeInput)) ||
((IOHIDElementGetType(element) >= kIOHIDElementTypeInput_Misc) && (IOHIDElementGetType(element) <= kIOHIDElementTypeInput_ScanCodes) && (direction == kIOHIDTransactionDirectionTypeOutput)))
CFDictionaryRemoveValue(fElementDictionaryRef, keyRefs[i]);
}
if (elementRefs)
free(elementRefs);
if (keyRefs)
free(keyRefs);
}
fDirection = direction;
result = kIOReturnSuccess;
exit:
return result;
}
IOReturn IOHIDTransactionClass::create ()
{
IOReturn ret = kIOReturnSuccess;
connectCheck();
if (fIsCreated)
return kIOReturnSuccess;
fElementDictionaryRef = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (!fElementDictionaryRef)
return kIOReturnNoMemory;
fIsCreated = true;
return ret;
}
IOReturn IOHIDTransactionClass::dispose()
{
IOReturn ret = kIOReturnSuccess;
fIsCreated = false;
if (fElementDictionaryRef)
{
CFRelease(fElementDictionaryRef);
fElementDictionaryRef = NULL;
}
return ret;
}
IOReturn IOHIDTransactionClass::addElement (IOHIDElementRef element, IOOptionBits options __unused)
{
IOHIDTransactionElementRef transactionElement;
IOHIDElementType elementType;
IOReturn ret = kIOReturnSuccess;
Boolean added = false;
mostChecks();
if (!element)
return kIOReturnBadArgument;
if (!fIsCreated || hasElement(element, &added) || added)
return kIOReturnError;
elementType = IOHIDElementGetType(element);
if ((elementType != kIOHIDElementTypeOutput) && (elementType != kIOHIDElementTypeFeature))
return kIOReturnBadArgument;
transactionElement = IOHIDTransactionElementCreate(kCFAllocatorDefault, element, 0);
if (!fElementDictionaryRef || !transactionElement)
ret = kIOReturnError;
else
CFDictionarySetValue(fElementDictionaryRef, element, transactionElement);
if (transactionElement) CFRelease(transactionElement);
return ret;
}
IOReturn IOHIDTransactionClass::removeElement (IOHIDElementRef element, IOOptionBits options __unused)
{
Boolean added;
mostChecks();
if (!element)
return kIOReturnBadArgument;
if (!fIsCreated || !fElementDictionaryRef || hasElement(element, &added) || !added)
return kIOReturnError;
CFDictionaryRemoveValue(fElementDictionaryRef, element);
return kIOReturnSuccess;
}
IOReturn IOHIDTransactionClass::hasElement (IOHIDElementRef element, Boolean *pValue, IOOptionBits options __unused)
{
mostChecks();
if (!element || !pValue)
return kIOReturnBadArgument;
if (!fIsCreated || !fElementDictionaryRef)
return kIOReturnError;
*pValue = CFDictionaryContainsKey(fElementDictionaryRef, element);
return kIOReturnSuccess;
}
IOReturn IOHIDTransactionClass::setElementValue(IOHIDElementRef element, IOHIDValueRef event, IOOptionBits options)
{
IOHIDTransactionElementRef transactionElement;
mostChecks();
if (!element || (fDirection == kIOHIDTransactionDirectionTypeInput))
return kIOReturnBadArgument;
if (!fIsCreated || !fElementDictionaryRef)
return kIOReturnError;
transactionElement = (IOHIDTransactionElementRef)CFDictionaryGetValue(fElementDictionaryRef, element);
if (!transactionElement)
return kIOReturnError;
if ( options & kIOHIDTransactionOptionDefaultOutputValue )
IOHIDTransactionElementSetDefaultValue(transactionElement, event);
else
IOHIDTransactionElementSetValue(transactionElement, event);
return kIOReturnSuccess;
}
IOReturn IOHIDTransactionClass::getElementValue(IOHIDElementRef element, IOHIDValueRef * pEvent, IOOptionBits options)
{
IOHIDTransactionElementRef transactionElement;
mostChecks();
if (!element)
return kIOReturnBadArgument;
if (!fIsCreated || !fElementDictionaryRef)
return kIOReturnError;
transactionElement = (IOHIDTransactionElementRef)CFDictionaryGetValue(fElementDictionaryRef, element);
if (!transactionElement)
return kIOReturnError;
*pEvent = ((fDirection == kIOHIDTransactionDirectionTypeOutput) && (options & kIOHIDTransactionOptionDefaultOutputValue)) ?
IOHIDTransactionElementGetDefaultValue(transactionElement) : IOHIDTransactionElementGetValue(transactionElement);
return kIOReturnSuccess;
}
IOReturn IOHIDTransactionClass::commit(uint32_t timeoutMS __unused, IOHIDCallback callback __unused, void * callbackRefcon __unused, IOOptionBits options __unused)
{
IOHIDTransactionElementRef * elementRefs = NULL;
uint64_t * cookies = NULL;
CFIndex numElements = 0;
IOReturn ret = kIOReturnError;
int numValidElements = 0;
IOHIDValueRef event;
uint32_t outputCount = 0;
allChecks();
require_action(fIsCreated && fElementDictionaryRef, exit, ret = kIOReturnError);
numElements = CFDictionaryGetCount(fElementDictionaryRef);
require_action(numElements, exit, ret = kIOReturnError);
cookies = (uint64_t *)malloc(sizeof(uint64_t) * numElements);
elementRefs = (IOHIDTransactionElementRef *)malloc(sizeof(IOHIDTransactionElementRef) * numElements);
CFDictionaryGetKeysAndValues(fElementDictionaryRef, NULL, (const void **)elementRefs);
for (int i=0;i<numElements && elementRefs[i]; i++)
{
if ( fDirection == kIOHIDTransactionDirectionTypeOutput )
{
if ((event = IOHIDTransactionElementGetValue(elementRefs[i])))
{
fOwningDevice->setElementValue(IOHIDTransactionElementGetElement(elementRefs[i]), event, 0, NULL, NULL, kHIDSetElementValuePendEvent);
}
else if ((event = IOHIDTransactionElementGetDefaultValue(elementRefs[i])))
{
fOwningDevice->setElementValue(IOHIDTransactionElementGetElement(elementRefs[i]), event, 0, NULL, NULL, kHIDSetElementValuePendEvent);
}
else
continue;
}
IOHIDTransactionElementSetValue(elementRefs[i], NULL);
cookies[numValidElements] = (uint32_t)IOHIDElementGetCookie(IOHIDTransactionElementGetElement(elementRefs[i]));
ROSETTA_ONLY(
cookies[numValidElements] = OSSwapInt32(cookies[numValidElements]);
);
numValidElements++;
}
switch ( fDirection ) {
case kIOHIDTransactionDirectionTypeOutput:
ret = IOConnectCallScalarMethod(fOwningDevice->fConnection, kIOHIDLibUserClientPostElementValues, cookies, numValidElements, 0, &outputCount);
break;
case kIOHIDTransactionDirectionTypeInput:
ret = IOConnectCallScalarMethod(fOwningDevice->fConnection, kIOHIDLibUserClientUpdateElementValues, cookies, numValidElements, 0, &outputCount);
if (ret == kIOReturnSuccess) {
for (int i=0;i<numElements && elementRefs[i]; i++)
{
fOwningDevice->getElementValue(IOHIDTransactionElementGetElement(elementRefs[i]), &event, 0, NULL, NULL, kHIDGetElementValuePreventPoll);
IOHIDTransactionElementSetValue(elementRefs[i], event);
}
}
break;
default:
break;
}
if (elementRefs)
free(elementRefs);
if ( cookies )
free(cookies);
exit:
return ret;
}
IOReturn IOHIDTransactionClass::clear (IOOptionBits options __unused)
{
IOHIDTransactionElementRef *elementRefs = NULL;
CFIndex numElements = 0;
mostChecks();
if (!fIsCreated || !fElementDictionaryRef)
return kIOReturnError;
numElements = CFDictionaryGetCount(fElementDictionaryRef);
if (!numElements)
return kIOReturnError;
elementRefs = (IOHIDTransactionElementRef *)malloc(sizeof(IOHIDTransactionElementRef) * numElements);
CFDictionaryGetKeysAndValues(fElementDictionaryRef, NULL, (const void **)elementRefs);
for (int i=0;i<numElements && elementRefs[i]; i++)
IOHIDTransactionElementSetValue(elementRefs[i], NULL);
if (elementRefs)
free(elementRefs);
return kIOReturnSuccess;
}
IOHIDDeviceTransactionInterface IOHIDTransactionClass::sHIDTransactionInterface =
{
0,
&IOHIDIUnknown::genericQueryInterface,
&IOHIDIUnknown::genericAddRef,
&IOHIDIUnknown::genericRelease,
&IOHIDTransactionClass::_getAsyncEventSource,
&IOHIDTransactionClass::_setDirection,
&IOHIDTransactionClass::_getDirection,
&IOHIDTransactionClass::_addElement,
&IOHIDTransactionClass::_removeElement,
&IOHIDTransactionClass::_hasElement,
&IOHIDTransactionClass::_setElementValue,
&IOHIDTransactionClass::_getElementValue,
&IOHIDTransactionClass::_commit,
&IOHIDTransactionClass::_clear,
};
IOReturn IOHIDTransactionClass::_getAsyncEventSource(void *self, CFTypeRef *source)
{ return getThis(self)->getAsyncEventSource(source); }
IOReturn IOHIDTransactionClass::_getAsyncPort(void *self, mach_port_t *port)
{ return getThis(self)->getAsyncPort(port); }
IOReturn IOHIDTransactionClass::_setDirection(void *self, IOHIDTransactionDirectionType direction, IOOptionBits options)
{ return getThis(self)->setDirection(direction, options); }
IOReturn IOHIDTransactionClass::_getDirection(void *self, IOHIDTransactionDirectionType * pDirection)
{ return getThis(self)->getDirection(pDirection); }
IOReturn IOHIDTransactionClass::_addElement (void * self, IOHIDElementRef element, IOOptionBits options)
{ return getThis(self)->addElement(element, options); }
IOReturn IOHIDTransactionClass::_removeElement (void * self, IOHIDElementRef element, IOOptionBits options)
{ return getThis(self)->removeElement(element, options); }
IOReturn IOHIDTransactionClass::_hasElement (void * self, IOHIDElementRef element, Boolean *pValue, IOOptionBits options)
{ return getThis(self)->hasElement(element, pValue, options); }
IOReturn IOHIDTransactionClass::_setElementValue(void * self, IOHIDElementRef element, IOHIDValueRef event, IOOptionBits options)
{ return getThis(self)->setElementValue(element, event, options); }
IOReturn IOHIDTransactionClass::_getElementValue(void * self, IOHIDElementRef element, IOHIDValueRef * pEvent, IOOptionBits options)
{ return getThis(self)->getElementValue(element, pEvent, options); }
IOReturn IOHIDTransactionClass::_commit(void * self, uint32_t timeoutMS, IOHIDCallback callback, void * callbackRefcon, IOOptionBits options)
{ return getThis(self)->commit(timeoutMS, callback, callbackRefcon, options);}
IOReturn IOHIDTransactionClass::_clear(void * self, IOOptionBits options)
{ return getThis(self)->clear(options);}
IOHIDOutputTransactionInterface IOHIDOutputTransactionClass::sHIDOutputTransactionInterface =
{
0,
&IOHIDIUnknown::genericQueryInterface,
&IOHIDIUnknown::genericAddRef,
&IOHIDIUnknown::genericRelease,
&IOHIDOutputTransactionClass::_createAsyncEventSource,
&IOHIDOutputTransactionClass::_getAsyncEventSource,
&IOHIDTransactionClass::_getAsyncPort,
&IOHIDOutputTransactionClass::_getAsyncPort,
&IOHIDOutputTransactionClass::_create,
&IOHIDOutputTransactionClass::_dispose,
&IOHIDOutputTransactionClass::_addElement,
&IOHIDOutputTransactionClass::_removeElement,
&IOHIDOutputTransactionClass::_hasElement,
&IOHIDOutputTransactionClass::_setElementDefault,
&IOHIDOutputTransactionClass::_getElementDefault,
&IOHIDOutputTransactionClass::_setElementValue,
&IOHIDOutputTransactionClass::_getElementValue,
&IOHIDOutputTransactionClass::_commit,
&IOHIDOutputTransactionClass::_clear,
};
IOReturn IOHIDOutputTransactionClass::_createAsyncEventSource(void * self, CFRunLoopSourceRef * pSource)
{ return getThis(self)->createAsyncEventSource(pSource); }
CFRunLoopSourceRef IOHIDOutputTransactionClass::_getAsyncEventSource(void *self)
{ CFTypeRef source = NULL; getThis(self)->getAsyncEventSource(&source); return (CFRunLoopSourceRef)source;}
mach_port_t IOHIDOutputTransactionClass::_getAsyncPort(void *self)
{ mach_port_t port = MACH_PORT_NULL; getThis(self)->getAsyncPort(&port); return port; }
IOReturn IOHIDOutputTransactionClass::_create(void * self)
{ return getThis(self)->create(); }
IOReturn IOHIDOutputTransactionClass::_dispose (void * self)
{ return getThis(self)->dispose(); }
IOReturn IOHIDOutputTransactionClass::_addElement (void * self, IOHIDElementCookie cookie)
{ return getThis(self)->addElement(cookie); }
IOReturn IOHIDOutputTransactionClass::_removeElement (void * self, IOHIDElementCookie cookie)
{ return getThis(self)->removeElement(cookie); }
Boolean IOHIDOutputTransactionClass::_hasElement (void * self, IOHIDElementCookie cookie)
{ return getThis(self)->hasElement(cookie); }
IOReturn IOHIDOutputTransactionClass::_setElementDefault(void * self, IOHIDElementCookie cookie, IOHIDEventStruct * pEvent)
{ return getThis(self)->setElementValue(cookie, pEvent, kIOHIDTransactionOptionDefaultOutputValue); }
IOReturn IOHIDOutputTransactionClass::_getElementDefault(void * self, IOHIDElementCookie cookie, IOHIDEventStruct * pEvent)
{ return getThis(self)->getElementValue(cookie, pEvent, kIOHIDTransactionOptionDefaultOutputValue); }
IOReturn IOHIDOutputTransactionClass::_setElementValue(void * self, IOHIDElementCookie cookie, IOHIDEventStruct * pEvent)
{ return getThis(self)->setElementValue(cookie, pEvent); }
IOReturn IOHIDOutputTransactionClass::_getElementValue(void * self, IOHIDElementCookie cookie, IOHIDEventStruct * pEvent)
{ return getThis(self)->getElementValue(cookie, pEvent); }
IOReturn IOHIDOutputTransactionClass::_commit(void * self, uint32_t timeoutMS, IOHIDCallbackFunction callback, void * callbackTarget, void * callbackRefcon)
{ return getThis(self)->commit(timeoutMS, callback, callbackTarget, callbackRefcon);}
IOReturn IOHIDOutputTransactionClass::_clear(void * self)
{ return getThis(self)->clear();}
IOHIDOutputTransactionClass::IOHIDOutputTransactionClass() : IOHIDTransactionClass()
{
fHIDTransaction.pseudoVTable = (IUnknownVTbl *) &sHIDOutputTransactionInterface;
fHIDTransaction.obj = this;
fCallback = NULL;
fTarget = NULL;
fRefcon = NULL;
}
IOHIDOutputTransactionClass::~IOHIDOutputTransactionClass()
{
}
HRESULT IOHIDOutputTransactionClass::queryInterface(REFIID iid, void ** ppv)
{
CFUUIDRef uuid = CFUUIDCreateFromUUIDBytes(NULL, iid);
HRESULT res = S_OK;
if (CFEqual(uuid, kIOHIDOutputTransactionInterfaceID))
{
*ppv = getInterfaceMap();
addRef();
}
else {
res = fOwningDevice->queryInterface(iid, ppv);
}
if (!*ppv)
res = E_NOINTERFACE;
CFRelease(uuid);
return res;
}
IOReturn IOHIDOutputTransactionClass::createAsyncEventSource(CFRunLoopSourceRef * pSource)
{
IOReturn ret = IOHIDTransactionClass::getAsyncEventSource((CFTypeRef *)pSource);
if ( ret == kIOReturnSuccess && pSource && *pSource )
CFRetain(*pSource);
return ret;
}
IOReturn IOHIDOutputTransactionClass::create ()
{
fDirection = kIOHIDTransactionDirectionTypeOutput;
return IOHIDTransactionClass::create();
}
IOReturn IOHIDOutputTransactionClass::addElement (IOHIDElementCookie cookie)
{
IOHIDElementRef element = fOwningDevice->getElement(cookie);
return IOHIDTransactionClass::addElement(element);
}
IOReturn
IOHIDOutputTransactionClass::addElement(IOHIDElementRef element,
IOOptionBits options)
{
return IOHIDTransactionClass::addElement(element, options);
}
IOReturn IOHIDOutputTransactionClass::removeElement (IOHIDElementCookie cookie)
{
IOHIDElementRef element = fOwningDevice->getElement(cookie);
return IOHIDTransactionClass::removeElement(element);
}
IOReturn
IOHIDOutputTransactionClass::removeElement(IOHIDElementRef element,
IOOptionBits options)
{
return IOHIDTransactionClass::removeElement(element, options);
}
Boolean IOHIDOutputTransactionClass::hasElement (IOHIDElementCookie cookie)
{
IOHIDElementRef element = fOwningDevice->getElement(cookie);
Boolean value = FALSE;
return (IOHIDTransactionClass::hasElement(element, &value) == kIOReturnSuccess) ? value : FALSE;
}
IOReturn
IOHIDOutputTransactionClass::hasElement(IOHIDElementRef element,
Boolean * pValue,
IOOptionBits options)
{
return IOHIDTransactionClass::hasElement(element, pValue, options);
}
IOReturn
IOHIDOutputTransactionClass::setElementValue(IOHIDElementCookie cookie,
IOHIDEventStruct * pEvent,
IOOptionBits options)
{
IOHIDValueRef event;
IOHIDElementRef element;
IOReturn ret;
if ( !pEvent )
return kIOReturnBadArgument;
element = fOwningDevice->getElement(cookie);
event = _IOHIDValueCreateWithStruct(kCFAllocatorDefault, element, pEvent);
ret = IOHIDTransactionClass::setElementValue(element, event, options);
CFRelease(event);
return ret;
}
IOReturn
IOHIDOutputTransactionClass::setElementValue(IOHIDElementRef element,
IOHIDValueRef event,
IOOptionBits options)
{
return IOHIDTransactionClass::setElementValue(element, event, options);
}
IOReturn
IOHIDOutputTransactionClass::getElementValue(IOHIDElementCookie cookie,
IOHIDEventStruct * pEvent,
IOOptionBits options)
{
IOHIDValueRef event;
IOReturn ret;
if ( !pEvent )
return kIOReturnBadArgument;
ret = IOHIDTransactionClass::getElementValue(fOwningDevice->getElement(cookie), &event, options);
if ((ret==kIOReturnSuccess) && event)
{
uint32_t length = (uint32_t)_IOHIDElementGetLength(IOHIDValueGetElement(event));;
pEvent->type = IOHIDElementGetType(IOHIDValueGetElement(event));
pEvent->elementCookie = cookie;
*(UInt64 *)&pEvent->timestamp = IOHIDValueGetTimeStamp(event);
if ( length > sizeof(uint32_t) )
{
pEvent->longValueSize = length;
pEvent->longValue = (void *)IOHIDValueGetBytePtr(event);
}
else
{
pEvent->longValueSize = 0;
pEvent->longValue = NULL;
pEvent->value = (int32_t)IOHIDValueGetIntegerValue(event);
}
}
return ret;
}
IOReturn
IOHIDOutputTransactionClass::getElementValue(IOHIDElementRef element,
IOHIDValueRef * pEvent, IOOptionBits options)
{
return IOHIDTransactionClass::getElementValue(element, pEvent, options);
}
IOReturn IOHIDOutputTransactionClass::commit(uint32_t timeoutMS, IOHIDCallbackFunction callback, void * target, void * refcon)
{
fCallback = callback;
fTarget = target;
fRefcon = refcon;
return IOHIDTransactionClass::commit(timeoutMS, IOHIDOutputTransactionClass::_commitCallback, this);
}
IOReturn
IOHIDOutputTransactionClass::commit(uint32_t timeoutMS,
IOHIDCallback callback,
void * callbackRefcon,
IOOptionBits options)
{
return IOHIDTransactionClass::commit(timeoutMS, callback, callbackRefcon, options);
}
void IOHIDOutputTransactionClass::_commitCallback(void * context, IOReturn result __unused, void * sender){
IOHIDOutputTransactionClass *transaction = (IOHIDOutputTransactionClass *)context;
if ( transaction && transaction->fCallback)
{
(transaction->fCallback)(transaction->fTarget, kIOReturnSuccess, transaction->fRefcon, sender);
}
}