#include <IOKit/IOLib.h>
#include <IOKit/assert.h>
#include <IOKit/hidsystem/IOHIDShared.h>
#include <IOKit/hidsystem/IOHIDDescriptorParser.h>
#include "IOHIDParameter.h"
#include "IOHIDPointing.h"
#include "IOHIDKeys.h"
#include "IOHIDElement.h"
#define super IOHITablet
OSDefineMetaClassAndStructors(IOHIDPointing, IOHITablet);
IOHIDPointing * IOHIDPointing::Pointing(
UInt32 buttonCount,
IOFixed pointerResolution,
IOFixed scrollResolution,
bool isDispatcher)
{
IOHIDPointing *nub = new IOHIDPointing;
if ((nub == 0) || !nub->initWithMouseProperties(buttonCount, pointerResolution, scrollResolution, isDispatcher) )
{
if (nub) nub->release();
return 0;
}
return nub;
}
bool IOHIDPointing::initWithMouseProperties(
UInt32 buttonCnt,
IOFixed pointerResolution,
IOFixed scrollResolution,
bool isDispatcher)
{
if (!super::init(0)) return false;
_numButtons = (buttonCnt > 0) ? buttonCnt : 1;
_resolution = pointerResolution;
_scrollResolution = scrollResolution;
_isDispatcher = isDispatcher;
return true;
}
bool IOHIDPointing::start(IOService *provider)
{
_provider = OSDynamicCast(IOHIDEventService, provider);
if (!_provider)
return false;
setupProperties();
return super::start(provider);
}
void IOHIDPointing::stop(IOService *provider)
{
_provider = NULL;
super::stop(provider);
}
void IOHIDPointing::dispatchAbsolutePointerEvent(
AbsoluteTime timeStamp,
IOGPoint * newLoc,
IOGBounds * bounds,
UInt32 buttonState,
bool inRange,
SInt32 tipPressure,
SInt32 tipPressureMin,
SInt32 tipPressureMax,
IOOptionBits options)
{
bool convertToRelative = ((options & kHIDDispatchOptionPointerAbsolutToRelative) != 0);
bool accelerate = ((options & kHIDDispatchOptionPointerNoAcceleration) == 0);
UInt32 pointingMode = getPointingMode();
if ( (((pointingMode & kAccelMouse) != 0) != accelerate) && (((pointingMode & kAbsoluteConvertMouse) != 0) != convertToRelative))
{
if ( accelerate )
pointingMode |= kAccelMouse;
else
pointingMode &= ~kAccelMouse;
if ( convertToRelative )
pointingMode |= kAbsoluteConvertMouse;
else
pointingMode &= ~kAbsoluteConvertMouse;
setPointingMode(pointingMode);
}
super::dispatchAbsolutePointerEvent(newLoc, bounds, buttonState, inRange, tipPressure, tipPressureMin, tipPressureMax, 90, timeStamp);
}
void IOHIDPointing::dispatchRelativePointerEvent(
AbsoluteTime timeStamp,
SInt32 dx,
SInt32 dy,
UInt32 buttonState,
IOOptionBits options)
{
bool accelerate = ((options & kHIDDispatchOptionPointerNoAcceleration) == 0);
UInt32 pointingMode = getPointingMode();
if ( ((pointingMode & kAccelMouse) != 0) != accelerate)
{
if ( accelerate )
pointingMode |= kAccelMouse;
else
pointingMode &= ~kAccelMouse;
setPointingMode(pointingMode);
}
super::dispatchRelativePointerEvent(dx, dy, buttonState, timeStamp);
}
void IOHIDPointing::dispatchScrollWheelEvent(
AbsoluteTime timeStamp,
SInt32 deltaAxis1,
SInt32 deltaAxis2,
UInt32 deltaAxis3,
IOOptionBits options)
{
{
UInt32 oldEventType = getScrollType();
UInt32 newEventType = oldEventType & ~( kScrollTypeMomentumAny | kScrollTypeOptionPhaseAny );
bool setScroll = false;
UInt32 dispatchKey = kHIDDispatchOptionScrollMomentumContinue;
UInt32 eventKey = kScrollTypeMomentumContinue;
bool dispatchVal = options & dispatchKey ? true : false;
bool eventVal = oldEventType & eventKey ? true : false;
if (dispatchVal != eventVal) {
if (dispatchVal) {
newEventType |= eventKey;
}
setScroll = true;
}
dispatchKey = kHIDDispatchOptionScrollMomentumStart;
eventKey = kScrollTypeMomentumStart;
dispatchVal = options & dispatchKey ? true : false;
eventVal = oldEventType & eventKey ? true : false;
if (dispatchVal != eventVal) {
if (dispatchVal) {
newEventType |= eventKey;
}
setScroll = true;
}
dispatchKey = kHIDDispatchOptionScrollMomentumEnd;
eventKey = kScrollTypeMomentumEnd;
dispatchVal = options & dispatchKey ? true : false;
eventVal = oldEventType & eventKey ? true : false;
if (dispatchVal != eventVal) {
if (dispatchVal) {
newEventType |= eventKey;
}
setScroll = true;
}
dispatchKey = (options & kHIDDispatchOptionPhaseAny) << 4;
eventKey = (oldEventType & kScrollTypeOptionPhaseAny);
if (dispatchKey != eventKey) {
newEventType |= dispatchKey;
setScroll = true;
}
if (setScroll) {
setScrollType(newEventType);
}
}
bool accelerate = ((options & kHIDDispatchOptionScrollNoAcceleration) == 0) && ((options & kHIDDispatchOptionPhaseEnded) == 0);
UInt32 pointingMode = getPointingMode();
if (((pointingMode & kAccelScroll) != 0) != accelerate)
{
if ( accelerate )
pointingMode |= kAccelScroll;
else
pointingMode &= ~kAccelScroll;
setPointingMode(pointingMode);
}
super::dispatchScrollWheelEvent(deltaAxis1, deltaAxis2, deltaAxis3, timeStamp);
}
UInt16 IOHIDPointing::generateDeviceID()
{
static UInt16 sNextDeviceID = 0x8000;
return sNextDeviceID++;
}
void IOHIDPointing::dispatchTabletEvent(
NXEventData * tabletEvent,
AbsoluteTime ts)
{
super::dispatchTabletEvent(tabletEvent, ts);
}
void IOHIDPointing::dispatchProximityEvent(
NXEventData * proximityEvent,
AbsoluteTime ts)
{
super::dispatchProximityEvent(proximityEvent, ts);
}
IOItemCount IOHIDPointing::buttonCount()
{
return _numButtons;
}
IOFixed IOHIDPointing::resolution()
{
return _resolution;
}
void IOHIDPointing::setupProperties()
{
OSNumber * number = NULL;
number = _provider ? (OSNumber*)_provider->copyProperty(kIOHIDPointerResolutionKey) : NULL;
if ( OSDynamicCast(OSNumber, number) )
{
IOFixed newResolution = number->unsigned32BitValue();
if ( newResolution != 0 ) {
_resolution = number->unsigned32BitValue();
setProperty(kIOHIDPointerResolutionKey, number);
_isDispatcher = FALSE;
}
}
else if ( _resolution )
{
setProperty(kIOHIDPointerResolutionKey, _resolution, 32);
}
OSSafeReleaseNULL(number);
number = _provider ? (OSNumber*)_provider->copyProperty(kIOHIDScrollResolutionKey) : NULL;
if ( OSDynamicCast(OSNumber, number) )
{
_scrollResolution = number->unsigned32BitValue();
setProperty(kIOHIDScrollResolutionKey, number);
_isDispatcher = FALSE;
}
else if ( _scrollResolution )
{
setProperty(kIOHIDScrollResolutionKey, _scrollResolution, 32);
}
OSSafeReleaseNULL(number);
if ( (_numButtons == 1) &&
(NULL != (number = _provider ? (OSNumber*)_provider->copyProperty(kIOHIDPointerButtonCountKey) : NULL)) &&
OSDynamicCast(OSNumber, number) )
{
_numButtons = number->unsigned32BitValue();
_isDispatcher = FALSE;
}
OSSafeReleaseNULL(number);
if ( _isDispatcher )
setProperty(kIOHIDVirtualHIDevice, kOSBooleanTrue);
if (_provider) {
setProperty(kIOHIDScrollAccelerationTypeKey, _provider->getProperty( kIOHIDScrollAccelerationTypeKey ));
setProperty(kIOHIDPointerAccelerationTypeKey, _provider->getProperty( kIOHIDPointerAccelerationTypeKey ));
setProperty(kIOHIDPointerAccelerationTableKey, _provider->getProperty( kIOHIDPointerAccelerationTableKey ));
setProperty(kIOHIDScrollAccelerationTableKey, _provider->getProperty( kIOHIDScrollAccelerationTableKey ));
setProperty(kIOHIDScrollAccelerationTableXKey, _provider->getProperty( kIOHIDScrollAccelerationTableXKey ));
setProperty(kIOHIDScrollAccelerationTableYKey, _provider->getProperty( kIOHIDScrollAccelerationTableYKey ));
setProperty(kIOHIDScrollAccelerationTableZKey, _provider->getProperty( kIOHIDScrollAccelerationTableZKey ));
setProperty(kIOHIDScrollReportRateKey, _provider->getProperty( kIOHIDScrollReportRateKey ));
setProperty( kIOHIDScrollMouseButtonKey, _provider->getProperty( kIOHIDScrollMouseButtonKey ));
setProperty(kIOHIDScrollResolutionXKey, _provider->getProperty( kIOHIDScrollResolutionXKey ));
setProperty(kIOHIDScrollResolutionYKey, _provider->getProperty( kIOHIDScrollResolutionYKey ));
setProperty(kIOHIDScrollResolutionZKey, _provider->getProperty( kIOHIDScrollResolutionZKey ));
}
}