diff options
author | 2024-07-09 19:57:33 +0000 | |
---|---|---|
committer | 2024-07-10 10:36:06 +0000 | |
commit | ba27d1d9484c25a9ab58d13dcc59d35ad73fc7d3 (patch) | |
tree | fe80a0d5ed9c2fa2c460cd7b44cf6c139106d9b1 /libs/input/VirtualInputDevice.cpp | |
parent | 41da946d8c62a36725a23872ab264cfed401520f (diff) |
Native support for rotary encoder high-res scroll
Test: atest RotaryEncoderInputMapperTest
Test: atest VirtualRotaryEncoderTest
Flag: android.companion.virtualdevice.flags.high_resolution_scroll
Bug: 320328752
Change-Id: Iac9092597010582bd3f55e51ee63e9eb9c8d9433
Diffstat (limited to 'libs/input/VirtualInputDevice.cpp')
-rw-r--r-- | libs/input/VirtualInputDevice.cpp | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/libs/input/VirtualInputDevice.cpp b/libs/input/VirtualInputDevice.cpp index 2e3e1a09b8..0579967698 100644 --- a/libs/input/VirtualInputDevice.cpp +++ b/libs/input/VirtualInputDevice.cpp @@ -279,13 +279,17 @@ bool VirtualMouse::writeRelativeEvent(float relativeX, float relativeY, bool VirtualMouse::writeScrollEvent(float xAxisMovement, float yAxisMovement, std::chrono::nanoseconds eventTime) { if (!vd_flags::high_resolution_scroll()) { - return writeInputEvent(EV_REL, REL_HWHEEL, xAxisMovement, eventTime) && - writeInputEvent(EV_REL, REL_WHEEL, yAxisMovement, eventTime) && + return writeInputEvent(EV_REL, REL_HWHEEL, static_cast<int32_t>(xAxisMovement), + eventTime) && + writeInputEvent(EV_REL, REL_WHEEL, static_cast<int32_t>(yAxisMovement), + eventTime) && writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime); } - const int32_t highResScrollX = xAxisMovement * kEvdevMouseHighResScrollUnitsPerDetent; - const int32_t highResScrollY = yAxisMovement * kEvdevMouseHighResScrollUnitsPerDetent; + const auto highResScrollX = + static_cast<int32_t>(xAxisMovement * kEvdevHighResScrollUnitsPerDetent); + const auto highResScrollY = + static_cast<int32_t>(yAxisMovement * kEvdevHighResScrollUnitsPerDetent); bool highResScrollResult = writeInputEvent(EV_REL, REL_HWHEEL_HI_RES, highResScrollX, eventTime) && writeInputEvent(EV_REL, REL_WHEEL_HI_RES, highResScrollY, eventTime); @@ -299,19 +303,19 @@ bool VirtualMouse::writeScrollEvent(float xAxisMovement, float yAxisMovement, // (single mouse wheel click). mAccumulatedHighResScrollX += highResScrollX; mAccumulatedHighResScrollY += highResScrollY; - const int32_t scrollX = mAccumulatedHighResScrollX / kEvdevMouseHighResScrollUnitsPerDetent; - const int32_t scrollY = mAccumulatedHighResScrollY / kEvdevMouseHighResScrollUnitsPerDetent; + const int32_t scrollX = mAccumulatedHighResScrollX / kEvdevHighResScrollUnitsPerDetent; + const int32_t scrollY = mAccumulatedHighResScrollY / kEvdevHighResScrollUnitsPerDetent; if (scrollX != 0) { if (!writeInputEvent(EV_REL, REL_HWHEEL, scrollX, eventTime)) { return false; } - mAccumulatedHighResScrollX %= kEvdevMouseHighResScrollUnitsPerDetent; + mAccumulatedHighResScrollX %= kEvdevHighResScrollUnitsPerDetent; } if (scrollY != 0) { if (!writeInputEvent(EV_REL, REL_WHEEL, scrollY, eventTime)) { return false; } - mAccumulatedHighResScrollY %= kEvdevMouseHighResScrollUnitsPerDetent; + mAccumulatedHighResScrollY %= kEvdevHighResScrollUnitsPerDetent; } return writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime); @@ -550,14 +554,38 @@ bool VirtualStylus::handleStylusUp(uint16_t tool, std::chrono::nanoseconds event } // --- VirtualRotaryEncoder --- -VirtualRotaryEncoder::VirtualRotaryEncoder(unique_fd fd) : VirtualInputDevice(std::move(fd)) {} +VirtualRotaryEncoder::VirtualRotaryEncoder(unique_fd fd) + : VirtualInputDevice(std::move(fd)), mAccumulatedHighResScrollAmount(0) {} VirtualRotaryEncoder::~VirtualRotaryEncoder() {} bool VirtualRotaryEncoder::writeScrollEvent(float scrollAmount, std::chrono::nanoseconds eventTime) { - return writeInputEvent(EV_REL, REL_WHEEL, static_cast<int32_t>(scrollAmount), eventTime) && - writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime); + if (!vd_flags::high_resolution_scroll()) { + return writeInputEvent(EV_REL, REL_WHEEL, static_cast<int32_t>(scrollAmount), eventTime) && + writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime); + } + + const auto highResScrollAmount = + static_cast<int32_t>(scrollAmount * kEvdevHighResScrollUnitsPerDetent); + if (!writeInputEvent(EV_REL, REL_WHEEL_HI_RES, highResScrollAmount, eventTime)) { + return false; + } + + // According to evdev spec, a high-resolution scroll device needs to emit REL_WHEEL / REL_HWHEEL + // events in addition to high-res scroll events. Regular scroll events can approximate high-res + // scroll events, so we send a regular scroll event when the accumulated scroll motion reaches a + // detent (single wheel click). + mAccumulatedHighResScrollAmount += highResScrollAmount; + const int32_t scroll = mAccumulatedHighResScrollAmount / kEvdevHighResScrollUnitsPerDetent; + if (scroll != 0) { + if (!writeInputEvent(EV_REL, REL_WHEEL, scroll, eventTime)) { + return false; + } + mAccumulatedHighResScrollAmount %= kEvdevHighResScrollUnitsPerDetent; + } + + return writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime); } } // namespace android |