IOHIDEventOverrideDriver.cpp [plain text]
#include "IOHIDEventOverrideDriver.h"
#include "IOHIDUsageTables.h"
#define super IOHIDEventDriver
OSDefineMetaClassAndStructors( IOHIDEventOverrideDriver, IOHIDEventDriver )
bool IOHIDEventOverrideDriver::handleStart( IOService * provider )
{
OSArray * maps = NULL;
if ( !super::handleStart(provider) )
return false;
maps = OSDynamicCast(OSArray, getProperty("ButtonMaps"));
if ( maps ) {
int index;
for ( index=0; index<maps->getCount(); index++ ) {
OSDictionary * map;
OSNumber * number;
uint32_t button;
uint32_t usagePage;
uint32_t usage;
uint32_t eventType;
map = OSDynamicCast(OSDictionary, maps->getObject(index));
if ( !map )
continue;
number = OSDynamicCast(OSNumber, map->getObject("ButtonNumber"));
if ( !number )
continue;
button = number->unsigned32BitValue();
if ( !button || button>32 )
continue;
number = OSDynamicCast(OSNumber, map->getObject("EventType"));
if ( !number )
continue;
eventType = number->unsigned32BitValue();
number = OSDynamicCast(OSNumber, map->getObject("UsagePage"));
if ( !number )
continue;
usagePage = number->unsigned32BitValue();
number = OSDynamicCast(OSNumber, map->getObject("Usage"));
if ( !number )
continue;
usage = number->unsigned32BitValue();
_buttonMap[button-1].eventType = eventType;
_buttonMap[button-1].usagePage = usagePage;
_buttonMap[button-1].usage = usage;
}
}
return true;
}
void IOHIDEventOverrideDriver::dispatchEvent(IOHIDEvent * event, IOOptionBits options)
{
IOHIDEvent * targetEvent = NULL;
if ( (targetEvent = event->getEvent(kIOHIDEventTypePointer)) ) {
AbsoluteTime timestamp = targetEvent->getTimeStamp();
uint32_t pointerButtonMaskNew = targetEvent->getIntegerValue(kIOHIDEventFieldPointerButtonMask);
uint32_t pointerButtonMaskDelta = _pointerButtonMask ^ pointerButtonMaskNew;
int index;
for ( index=0; index<32; index++ ) {
bool value;
if ( (pointerButtonMaskDelta & (1<<index)) == 0 )
continue;
switch (_buttonMap[index].eventType ) {
case kIOHIDEventTypeKeyboard:
value = pointerButtonMaskNew & (1<<index);
dispatchKeyboardEvent(timestamp, _buttonMap[index].usagePage, _buttonMap[index].usage, value);
break;
default:
break;
}
}
_pointerButtonMask = pointerButtonMaskNew;
} else {
super::dispatchEvent(event, options);
}
}