IOHIDAcceleration.cpp [plain text]
#include "IOHIDAcceleration.hpp"
#include "CF.h"
#include "IOHIDParameter.h"
#include "IOHIDDebug.h"
#include <sstream>
#include <cmath>
void IOHIDSimpleAccelerator::serialize(CFMutableDictionaryRef dict) const {
CFMutableDictionaryRefWrap serializer (dict);
serializer.SetValueForKey(CFSTR("Class"), CFSTR("IOHIDScrollAccelerator"));
serializer.SetValueForKey(CFSTR("Multiplier"), DOUBLE_TO_FIXED(_multiplier));
}
bool IOHIDSimpleAccelerator::accelerate (double *values, size_t length, uint64_t timestamp __unused) {
if (_multiplier == 1.0) {
return false;
}
for (size_t i = 0; i < length; i++) {
values[i] *= _multiplier;
}
return true;
}
mach_timebase_info_data_t IOHIDScrollAccelerator::_timebase {0,0};
bool IOHIDScrollAccelerator::accelerate (double *values, size_t length __unused, uint64_t timestamp) {
double mult = 1.0;
double &scroll = *values;
double deltaT = ((double)(timestamp - _lastTimeStamp) * _timebase.numer/ ((double)_timebase.denom)) / 1000000;
_lastTimeStamp = timestamp;
int head = _head;
events[head].deltaTime = deltaT;
events[head].scroll = std::abs(scroll);
_head = (++_head) % SCROLL_EVENT_AVARAGE_LENGHT;
if (_head == _tail) {
_tail = (++_tail) % SCROLL_EVENT_AVARAGE_LENGHT;
}
bool direction = scroll > 0 ? true : false;
if (_direction != direction || deltaT > SCROLL_CLEAR_THRESHOLD_MS) {
_tail = head;
_direction = direction;
}
double sumDeltaT = 0;
double sumScroll = 0;
int eventCount = 0;
int i = _head;
do {
i = (i ? i : SCROLL_EVENT_AVARAGE_LENGHT) - 1;
sumScroll += events[i].scroll;
++eventCount;
if (events[i].deltaTime > SCROLL_EVENT_THRESHOLD_MS) {
sumDeltaT +=SCROLL_EVENT_THRESHOLD_MS;
break;
} else {
sumDeltaT += events[i].deltaTime;
}
if (sumDeltaT >= SCROLL_CLEAR_THRESHOLD_MS) {
break;
}
} while (i != _tail);
double avargeDeltaTime;
double avargeScroll;
double velocity;
double rateMultiplier = _rate / FRAME_RATE;
avargeDeltaTime = (sumDeltaT/eventCount) * rateMultiplier;
if (avargeDeltaTime > SCROLL_EVENT_THRESHOLD_MS) {
avargeDeltaTime = SCROLL_EVENT_THRESHOLD_MS;
} else if (avargeDeltaTime < 1) {
avargeDeltaTime = 1;
}
avargeScroll = (double)sumScroll/eventCount;
velocity = (SCROLL_MULTIPLIER_A * avargeDeltaTime * avargeDeltaTime - SCROLL_MULTIPLIER_B * avargeDeltaTime + SCROLL_MULTIPLIER_C) * avargeScroll * rateMultiplier ;
if (velocity < FIXED_TO_DOUBLE(0x1)) {
velocity = FIXED_TO_DOUBLE(0x1);
}
if (_algorithm->getType() == IOHIDAccelerationAlgorithm::Table) {
if (eventCount > 2) {
velocity *= sqrt(eventCount * 16);
velocity /= 4;
}
mult = _algorithm->multiplier(velocity) / std::abs(scroll) ;
} else {
mult = _algorithm->multiplier(velocity) / velocity ;
}
double scrollAccel = scroll * mult * SCROLL_PIXEL_TO_WHEEL_SCALE;
scroll = scrollAccel;
return (mult != 1);
}
void IOHIDScrollAccelerator::serialize(CFMutableDictionaryRef dict) const {
CFMutableDictionaryRefWrap serializer (dict);
serializer.SetValueForKey(CFSTR("Class"), CFSTR("IOHIDScrollAccelerator"));
serializer.SetValueForKey(CFSTR("Resolution"), DOUBLE_TO_FIXED(_resolution));
serializer.SetValueForKey(CFSTR("Rate"), DOUBLE_TO_FIXED(_rate));
CFMutableDictionaryRefWrap accelerator;
if (_algorithm) {
_algorithm->serialize(accelerator);
}
serializer.SetValueForKey(CFSTR("Accelerator"), accelerator);
}
mach_timebase_info_data_t IOHIDPointerAccelerator::_timebase {0,0};
bool IOHIDPointerAccelerator::accelerate (double *values, size_t length __unused, uint64_t timestamp ) {
double mult = 0.0;
double &dx = values[0];
double &dy = values[1];
double rateMultiplier = 1;
if (_rate != 0)
{
double deltaT = ((double)(timestamp - _lastTimeStamp) * _timebase.numer/ ((double)_timebase.denom)) / 1000000;
if (deltaT != 0) {
double period_ms = 1000/_rate;
if (deltaT < period_ms)
deltaT = period_ms;
rateMultiplier = period_ms / deltaT;
}
}
_lastTimeStamp = timestamp;
double velocity = rateMultiplier * floor(sqrt(pow(dx,2) + pow(dy,2)));
mult = _algorithm->multiplier(velocity) / velocity;
dx *= mult;
dy *= mult;
return (mult != 1);
}
void IOHIDPointerAccelerator::serialize(CFMutableDictionaryRef dict) const {
CFMutableDictionaryRefWrap serializer (dict);
serializer.SetValueForKey(CFSTR("Class"), CFSTR("IOHIDPointerAccelerator"));
serializer.SetValueForKey(CFSTR("Resolution"), DOUBLE_TO_FIXED(_resolution));
serializer.SetValueForKey(CFSTR("Rate"), DOUBLE_TO_FIXED(_rate));
CFMutableDictionaryRefWrap accelerator;
if (_algorithm) {
_algorithm->serialize(accelerator);
}
serializer.SetValueForKey(CFSTR("Accelerator"), accelerator);
}