IOHIDEventQueue.cpp [plain text]
#include <IOKit/system.h>
#include <IOKit/IOLib.h>
#include <IOKit/IODataQueueShared.h>
#include "IOHIDEventQueue.h"
enum {
kHIDQueueStarted = 0x01,
kHIDQueueDisabled = 0x02
};
#define super IODataQueue
OSDefineMetaClassAndStructors( IOHIDEventQueue, IODataQueue )
IOHIDEventQueue * IOHIDEventQueue::withCapacity( UInt32 size )
{
IOHIDEventQueue * queue = new IOHIDEventQueue;
if ( queue && !queue->initWithCapacity(size) )
{
queue->release();
queue = 0;
}
queue->_state = 0;
queue->_lock = IOLockAlloc();
queue->_numEntries = size / DEFAULT_HID_ENTRY_SIZE;
queue->_currentEntrySize = DEFAULT_HID_ENTRY_SIZE;
queue->_maxEntrySize = DEFAULT_HID_ENTRY_SIZE;
return queue;
}
IOHIDEventQueue * IOHIDEventQueue::withEntries( UInt32 numEntries,
UInt32 entrySize )
{
IOHIDEventQueue * queue = new IOHIDEventQueue;
if ( queue && !queue->initWithEntries(numEntries, entrySize) )
{
queue->release();
queue = 0;
}
queue->_state = 0;
queue->_lock = IOLockAlloc();
queue->_numEntries = numEntries;
queue->_currentEntrySize = DEFAULT_HID_ENTRY_SIZE;
queue->_maxEntrySize = DEFAULT_HID_ENTRY_SIZE;
return queue;
}
void IOHIDEventQueue::free()
{
if (_lock)
{
IOLockLock(_lock);
IOLock* tempLock = _lock;
_lock = NULL;
IOLockUnlock(tempLock);
IOLockFree(tempLock);
}
if ( _descriptor )
{
_descriptor->release();
_descriptor = 0;
}
super::free();
}
Boolean IOHIDEventQueue::enqueue( void * data, UInt32 dataSize )
{
IOReturn ret = true;
if ( _lock )
IOLockLock(_lock);
if ((_state & (kHIDQueueStarted | kHIDQueueDisabled)) == kHIDQueueStarted)
ret = super::enqueue(data, dataSize);
if ( _lock )
IOLockUnlock(_lock);
return ret;
}
void IOHIDEventQueue::start()
{
if ( _lock )
IOLockLock(_lock);
if ( _state & kHIDQueueStarted )
goto START_END;
if ( _currentEntrySize != _maxEntrySize )
{
mach_port_t port = notifyMsg ? ((mach_msg_header_t *)notifyMsg)->msgh_remote_port : MACH_PORT_NULL;
if (dataQueue) {
IOFreeAligned(dataQueue, round_page_32(dataQueue->queueSize + DATA_QUEUE_MEMORY_HEADER_SIZE));
}
if (_descriptor) {
_descriptor->release();
_descriptor = 0;
}
if ( !initWithEntries(_numEntries, _maxEntrySize) ) {
goto START_END;
}
_currentEntrySize = _maxEntrySize;
if ( port )
setNotificationPort(port);
}
else if ( dataQueue )
{
dataQueue->head = 0;
dataQueue->tail = 0;
}
_state |= kHIDQueueStarted;
START_END:
if ( _lock )
IOLockUnlock(_lock);
}
void IOHIDEventQueue::stop()
{
if ( _lock )
IOLockLock(_lock);
_state &= ~kHIDQueueStarted;
if ( _lock )
IOLockUnlock(_lock);
}
void IOHIDEventQueue::enable()
{
if ( _lock )
IOLockLock(_lock);
_state &= ~kHIDQueueDisabled;
if ( _lock )
IOLockUnlock(_lock);
}
void IOHIDEventQueue::disable()
{
if ( _lock )
IOLockLock(_lock);
_state |= kHIDQueueDisabled;
if ( _lock )
IOLockUnlock(_lock);
}
Boolean IOHIDEventQueue::isStarted()
{
bool ret;
if ( _lock )
IOLockLock(_lock);
ret = (_state & kHIDQueueStarted) != 0;
if ( _lock )
IOLockUnlock(_lock);
return ret;
}
void IOHIDEventQueue::setOptions(IOHIDQueueOptionsType flags)
{
if ( _lock )
IOLockLock(_lock);
_options = flags;
if ( _lock )
IOLockUnlock(_lock);
}
IOHIDQueueOptionsType IOHIDEventQueue::getOptions()
{
return _options;
}
void IOHIDEventQueue::addElement( IOHIDElementPrivate * element )
{
UInt32 elementSize;
if ( !element )
return;
if ( !_elementSet )
{
_elementSet = OSSet::withCapacity(4);
}
if ( _elementSet->containsObject( element ) )
return;
elementSize = element->getElementValueSize() + sizeof(void *);
if ( _maxEntrySize < elementSize )
_maxEntrySize = elementSize;
}
void IOHIDEventQueue::removeElement( IOHIDElementPrivate * element )
{
OSCollectionIterator * iterator;
IOHIDElementPrivate * temp;
UInt32 size = 0;
UInt32 maxSize = DEFAULT_HID_ENTRY_SIZE;
if ( !element || !_elementSet || !_elementSet->containsObject( element ))
return;
_elementSet->removeObject( element );
if ( iterator = OSCollectionIterator::withCollection(_elementSet) )
{
while ( temp = (IOHIDElementPrivate *)iterator->getNextObject() )
{
size = temp->getElementValueSize() + sizeof(void *);
if ( maxSize < size )
maxSize = size;
}
iterator->release();
}
_maxEntrySize = maxSize;
}
UInt32 IOHIDEventQueue::getEntrySize( )
{
return _maxEntrySize;
}
IOMemoryDescriptor * IOHIDEventQueue::getMemoryDescriptor()
{
if (!_descriptor)
_descriptor = super::getMemoryDescriptor();
return _descriptor;
}
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 0);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 1);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 2);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 3);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 4);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 5);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 6);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 7);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 8);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 9);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 10);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 11);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 12);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 13);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 14);
OSMetaClassDefineReservedUnused(IOHIDEventQueue, 15);