From 72238143825361b7d5e3a7d4446d1694d6948af7 Mon Sep 17 00:00:00 2001 From: Larry Davis Date: Mon, 6 Jan 2020 15:45:14 -0800 Subject: [PATCH] Behave like a touchscreen, properly * except dragging to select, which times out after 14ms and screws up your selection --- .../VoodooI2CGoodixEventDriver.cpp | 40 +++++++++++++++++++ .../VoodooI2CGoodixEventDriver.hpp | 14 ++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/VoodooI2CGoodix/VoodooI2CGoodixEventDriver.cpp b/VoodooI2CGoodix/VoodooI2CGoodixEventDriver.cpp index 394348e..d2b362b 100644 --- a/VoodooI2CGoodix/VoodooI2CGoodixEventDriver.cpp +++ b/VoodooI2CGoodix/VoodooI2CGoodixEventDriver.cpp @@ -30,13 +30,32 @@ void VoodooI2CGoodixEventDriver::dispatchDigitizerEvent(int logicalX, int logica // Dispatch the actual event dispatchDigitizerEventWithTiltOrientation(timestamp, 0, kDigitiserTransducerFinger, 0x1, click ? 0x1 : 0x0, x, y); + + last_x = x; + last_y = y; + last_id = 0; +} + +void VoodooI2CGoodixEventDriver::scheduleLift() { + this->timer_source->setTimeoutMS(14); +} + +void VoodooI2CGoodixEventDriver::fingerLift() { + AbsoluteTime timestamp; + clock_get_uptime(×tamp); + + dispatchDigitizerEventWithTiltOrientation(timestamp, last_id, kDigitiserTransducerFinger, 0x1, 0x0, last_x, last_y); } + void VoodooI2CGoodixEventDriver::reportTouches(struct Touch touches[], int numTouches) { if (numTouches == 1) { // Initial mouse down event Touch touch = touches[0]; dispatchDigitizerEvent(touch.x, touch.y, true); + + // Lift a bit later + scheduleLift(); } else { // Move the cursor to the location of the first finger, but don't click @@ -87,6 +106,15 @@ bool VoodooI2CGoodixEventDriver::handleStart(IOService* provider) { return false; } + this->work_loop = getWorkLoop(); + if (!this->work_loop) { + IOLog("%s::Unable to get workloop\n", getName()); + stop(provider); + return false; + } + + work_loop->retain(); + name = getProductName(); publishMultitouchInterface(); @@ -105,6 +133,13 @@ bool VoodooI2CGoodixEventDriver::handleStart(IOService* provider) { multitouch_interface->registerService(); + timer_source = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &VoodooI2CGoodixEventDriver::fingerLift)); + + if (!timer_source || work_loop->addEventSource(timer_source) != kIOReturnSuccess) { + IOLog("%s::Could not add timer source to work loop\n", getName()); + return false; + } + return true; } @@ -121,6 +156,11 @@ void VoodooI2CGoodixEventDriver::handleStop(IOService* provider) { OSSafeReleaseNULL(transducers); } + if (timer_source) { + work_loop->removeEventSource(timer_source); + OSSafeReleaseNULL(timer_source); + } + super::handleStop(provider); } diff --git a/VoodooI2CGoodix/VoodooI2CGoodixEventDriver.hpp b/VoodooI2CGoodix/VoodooI2CGoodixEventDriver.hpp index 89d7d71..92664f9 100644 --- a/VoodooI2CGoodix/VoodooI2CGoodixEventDriver.hpp +++ b/VoodooI2CGoodix/VoodooI2CGoodixEventDriver.hpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -105,14 +106,23 @@ class EXPORT VoodooI2CGoodixEventDriver : public IOHIDEventService { protected: const char* name; bool awake = true; -// IOHIDInterface* hid_interface; VoodooI2CMultitouchInterface* multitouch_interface; OSArray* transducers; private: - OSSet* attached_hid_pointer_devices; + IOWorkLoop *work_loop; + IOTimerEventSource *timer_source; + + UInt32 buttons = 0; + IOFixed last_x = 0; + IOFixed last_y = 0; + SInt32 last_id = 0; + + int click_tick = 0; void dispatchDigitizerEvent(int logicalX, int logicalY, bool click); + void fingerLift(); + void scheduleLift(); };