1/* 2 * @APPLE_LICENSE_HEADER_START@ 3 * 4 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include <IOKit/system.h> 25#include <IOKit/IOLib.h> 26#include <IOKit/IODataQueueShared.h> 27#include "IOHIDEventQueue.h" 28 29enum { 30 kHIDQueueStarted = 0x01, 31 kHIDQueueDisabled = 0x02 32}; 33 34#define super IOSharedDataQueue 35OSDefineMetaClassAndStructors( IOHIDEventQueue, super ) 36 37//--------------------------------------------------------------------------- 38// Factory methods. 39 40IOHIDEventQueue * IOHIDEventQueue::withCapacity( UInt32 size ) 41{ 42 IOHIDEventQueue * queue = new IOHIDEventQueue; 43 44 if ( queue && !queue->initWithCapacity(size) ) 45 { 46 queue->release(); 47 queue = 0; 48 } 49 50 queue->_state = 0; 51 queue->_lock = IOLockAlloc(); 52 queue->_numEntries = size / DEFAULT_HID_ENTRY_SIZE; 53 queue->_currentEntrySize = DEFAULT_HID_ENTRY_SIZE; 54 queue->_maxEntrySize = DEFAULT_HID_ENTRY_SIZE; 55 56 return queue; 57} 58 59IOHIDEventQueue * IOHIDEventQueue::withEntries( UInt32 numEntries, 60 UInt32 entrySize ) 61{ 62 IOHIDEventQueue * queue = new IOHIDEventQueue; 63 64 if ( queue && !queue->initWithEntries(numEntries, entrySize) ) 65 { 66 queue->release(); 67 queue = 0; 68 } 69 70 queue->_state = 0; 71 queue->_lock = IOLockAlloc(); 72 queue->_numEntries = numEntries; 73 queue->_currentEntrySize = DEFAULT_HID_ENTRY_SIZE; 74 queue->_maxEntrySize = DEFAULT_HID_ENTRY_SIZE; 75 76 return queue; 77} 78 79void IOHIDEventQueue::free() 80{ 81 if (_lock) 82 { 83 IOLockLock(_lock); 84 IOLock* tempLock = _lock; 85 _lock = NULL; 86 IOLockUnlock(tempLock); 87 IOLockFree(tempLock); 88 } 89 90 if ( _descriptor ) 91 { 92 _descriptor->release(); 93 _descriptor = 0; 94 } 95 96 super::free(); 97} 98 99 100//--------------------------------------------------------------------------- 101// Add data to the queue. 102 103Boolean IOHIDEventQueue::enqueue( void * data, UInt32 dataSize ) 104{ 105 Boolean ret = true; 106 107 if ( _lock ) 108 IOLockLock(_lock); 109 110 // if we are not started, then dont enqueue 111 // for now, return true, since we dont wish to push an error back 112 if ((_state & (kHIDQueueStarted | kHIDQueueDisabled)) == kHIDQueueStarted) 113 ret = super::enqueue(data, dataSize); 114 115 if ( _lock ) 116 IOLockUnlock(_lock); 117 118 return ret; 119} 120 121 122//--------------------------------------------------------------------------- 123// Start the queue. 124 125void IOHIDEventQueue::start() 126{ 127 if ( _lock ) 128 IOLockLock(_lock); 129 130 if ( _state & kHIDQueueStarted ) 131 goto START_END; 132 133 if ( _currentEntrySize != _maxEntrySize ) 134 { 135 mach_port_t port = notifyMsg ? ((mach_msg_header_t *)notifyMsg)->msgh_remote_port : MACH_PORT_NULL; 136 137 // Free the existing queue data 138 if (dataQueue) { 139 IOFreeAligned(dataQueue, round_page_32(getQueueSize() + DATA_QUEUE_MEMORY_HEADER_SIZE)); 140 } 141 142 if (_descriptor) { 143 _descriptor->release(); 144 _descriptor = 0; 145 } 146 147 // init the queue again. This will allocate the appropriate data. 148 if ( !initWithEntries(_numEntries, _maxEntrySize) ) { 149 goto START_END; 150 } 151 152 _currentEntrySize = _maxEntrySize; 153 154 // RY: since we are initing the queue, we should reset the port as well 155 if ( port ) 156 setNotificationPort(port); 157 } 158 else if ( dataQueue ) 159 { 160 dataQueue->head = 0; 161 dataQueue->tail = 0; 162 } 163 164 _state |= kHIDQueueStarted; 165 166START_END: 167 if ( _lock ) 168 IOLockUnlock(_lock); 169 170} 171 172void IOHIDEventQueue::stop() 173{ 174 if ( _lock ) 175 IOLockLock(_lock); 176 177 _state &= ~kHIDQueueStarted; 178 179 if ( _lock ) 180 IOLockUnlock(_lock); 181} 182 183void IOHIDEventQueue::enable() 184{ 185 if ( _lock ) 186 IOLockLock(_lock); 187 188 _state &= ~kHIDQueueDisabled; 189 190 if ( _lock ) 191 IOLockUnlock(_lock); 192} 193 194void IOHIDEventQueue::disable() 195{ 196 if ( _lock ) 197 IOLockLock(_lock); 198 199 _state |= kHIDQueueDisabled; 200 201 if ( _lock ) 202 IOLockUnlock(_lock); 203} 204 205Boolean IOHIDEventQueue::isStarted() 206{ 207 bool ret; 208 209 if ( _lock ) 210 IOLockLock(_lock); 211 212 ret = (_state & kHIDQueueStarted) != 0; 213 214 if ( _lock ) 215 IOLockUnlock(_lock); 216 217 return ret; 218} 219 220void IOHIDEventQueue::setOptions(IOHIDQueueOptionsType flags) 221{ 222 if ( _lock ) 223 IOLockLock(_lock); 224 225 _options = flags; 226 227 if ( _lock ) 228 IOLockUnlock(_lock); 229} 230 231IOHIDQueueOptionsType IOHIDEventQueue::getOptions() 232{ 233 return _options; 234} 235 236//--------------------------------------------------------------------------- 237// Add element to the queue. 238 239void IOHIDEventQueue::addElement( IOHIDElementPrivate * element ) 240{ 241 UInt32 elementSize; 242 243 if ( !element ) 244 return; 245 246 if ( !_elementSet ) 247 { 248 _elementSet = OSSet::withCapacity(4); 249 } 250 251 if ( _elementSet->containsObject( element ) ) 252 return; 253 254 elementSize = element->getElementValueSize() + sizeof(void *); 255 256 if ( _maxEntrySize < elementSize ) 257 _maxEntrySize = elementSize; 258} 259 260//--------------------------------------------------------------------------- 261// Remove element from the queue. 262 263void IOHIDEventQueue::removeElement( IOHIDElementPrivate * element ) 264{ 265 OSCollectionIterator * iterator; 266 IOHIDElementPrivate * temp; 267 UInt32 size = 0; 268 UInt32 maxSize = DEFAULT_HID_ENTRY_SIZE; 269 270 if ( !element || !_elementSet || !_elementSet->containsObject( element )) 271 return; 272 273 _elementSet->removeObject( element ); 274 275 if ( NULL != (iterator = OSCollectionIterator::withCollection(_elementSet)) ) 276 { 277 while ( NULL != (temp = (IOHIDElementPrivate *)iterator->getNextObject()) ) 278 { 279 size = temp->getElementValueSize() + sizeof(void *); 280 281 if ( maxSize < size ) 282 maxSize = size; 283 } 284 285 iterator->release(); 286 } 287 288 _maxEntrySize = maxSize; 289} 290 291//--------------------------------------------------------------------------- 292// get entry size from the queue. 293 294UInt32 IOHIDEventQueue::getEntrySize( ) 295{ 296 return _maxEntrySize; 297} 298 299 300//--------------------------------------------------------------------------- 301// get a mem descriptor. replacing default behavior 302 303IOMemoryDescriptor * IOHIDEventQueue::getMemoryDescriptor() 304{ 305 if (!_descriptor) 306 _descriptor = super::getMemoryDescriptor(); 307 308 return _descriptor; 309} 310 311//--------------------------------------------------------------------------- 312// 313 314OSMetaClassDefineReservedUnused(IOHIDEventQueue, 0); 315OSMetaClassDefineReservedUnused(IOHIDEventQueue, 1); 316OSMetaClassDefineReservedUnused(IOHIDEventQueue, 2); 317OSMetaClassDefineReservedUnused(IOHIDEventQueue, 3); 318OSMetaClassDefineReservedUnused(IOHIDEventQueue, 4); 319OSMetaClassDefineReservedUnused(IOHIDEventQueue, 5); 320OSMetaClassDefineReservedUnused(IOHIDEventQueue, 6); 321OSMetaClassDefineReservedUnused(IOHIDEventQueue, 7); 322OSMetaClassDefineReservedUnused(IOHIDEventQueue, 8); 323OSMetaClassDefineReservedUnused(IOHIDEventQueue, 9); 324OSMetaClassDefineReservedUnused(IOHIDEventQueue, 10); 325OSMetaClassDefineReservedUnused(IOHIDEventQueue, 11); 326OSMetaClassDefineReservedUnused(IOHIDEventQueue, 12); 327OSMetaClassDefineReservedUnused(IOHIDEventQueue, 13); 328OSMetaClassDefineReservedUnused(IOHIDEventQueue, 14); 329OSMetaClassDefineReservedUnused(IOHIDEventQueue, 15); 330