summaryrefslogtreecommitdiff
path: root/libs/input/VirtualInputDevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/input/VirtualInputDevice.cpp')
-rw-r--r--libs/input/VirtualInputDevice.cpp48
1 files changed, 44 insertions, 4 deletions
diff --git a/libs/input/VirtualInputDevice.cpp b/libs/input/VirtualInputDevice.cpp
index b73ee65504..2e3e1a09b8 100644
--- a/libs/input/VirtualInputDevice.cpp
+++ b/libs/input/VirtualInputDevice.cpp
@@ -18,6 +18,7 @@
#include <android/input.h>
#include <android/keycodes.h>
+#include <android_companion_virtualdevice_flags.h>
#include <fcntl.h>
#include <input/Input.h>
#include <input/VirtualInputDevice.h>
@@ -40,6 +41,8 @@ static bool isDebug() {
namespace android {
+namespace vd_flags = android::companion::virtualdevice::flags;
+
VirtualInputDevice::VirtualInputDevice(unique_fd fd) : mFd(std::move(fd)) {}
VirtualInputDevice::~VirtualInputDevice() {
@@ -253,7 +256,10 @@ const std::map<int, int> VirtualMouse::BUTTON_CODE_MAPPING = {
// clang-format on
};
-VirtualMouse::VirtualMouse(unique_fd fd) : VirtualInputDevice(std::move(fd)) {}
+VirtualMouse::VirtualMouse(unique_fd fd)
+ : VirtualInputDevice(std::move(fd)),
+ mAccumulatedHighResScrollX(0),
+ mAccumulatedHighResScrollY(0) {}
VirtualMouse::~VirtualMouse() {}
@@ -272,9 +278,43 @@ bool VirtualMouse::writeRelativeEvent(float relativeX, float relativeY,
bool VirtualMouse::writeScrollEvent(float xAxisMovement, float yAxisMovement,
std::chrono::nanoseconds eventTime) {
- return writeInputEvent(EV_REL, REL_HWHEEL, xAxisMovement, eventTime) &&
- writeInputEvent(EV_REL, REL_WHEEL, yAxisMovement, eventTime) &&
- writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
+ if (!vd_flags::high_resolution_scroll()) {
+ return writeInputEvent(EV_REL, REL_HWHEEL, xAxisMovement, eventTime) &&
+ writeInputEvent(EV_REL, REL_WHEEL, yAxisMovement, eventTime) &&
+ writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
+ }
+
+ const int32_t highResScrollX = xAxisMovement * kEvdevMouseHighResScrollUnitsPerDetent;
+ const int32_t highResScrollY = yAxisMovement * kEvdevMouseHighResScrollUnitsPerDetent;
+ bool highResScrollResult =
+ writeInputEvent(EV_REL, REL_HWHEEL_HI_RES, highResScrollX, eventTime) &&
+ writeInputEvent(EV_REL, REL_WHEEL_HI_RES, highResScrollY, eventTime);
+ if (!highResScrollResult) {
+ return false;
+ }
+
+ // According to evdev spec, a high-resolution mouse 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 mouse wheel click).
+ mAccumulatedHighResScrollX += highResScrollX;
+ mAccumulatedHighResScrollY += highResScrollY;
+ const int32_t scrollX = mAccumulatedHighResScrollX / kEvdevMouseHighResScrollUnitsPerDetent;
+ const int32_t scrollY = mAccumulatedHighResScrollY / kEvdevMouseHighResScrollUnitsPerDetent;
+ if (scrollX != 0) {
+ if (!writeInputEvent(EV_REL, REL_HWHEEL, scrollX, eventTime)) {
+ return false;
+ }
+ mAccumulatedHighResScrollX %= kEvdevMouseHighResScrollUnitsPerDetent;
+ }
+ if (scrollY != 0) {
+ if (!writeInputEvent(EV_REL, REL_WHEEL, scrollY, eventTime)) {
+ return false;
+ }
+ mAccumulatedHighResScrollY %= kEvdevMouseHighResScrollUnitsPerDetent;
+ }
+
+ return writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
}
// --- VirtualTouchscreen ---