From c28c27fc075f6de707388e27de9a9be56237d6a2 Mon Sep 17 00:00:00 2001
From: nift4 <nift4@protonmail.com>
Date: Sat, 13 Aug 2022 11:17:17 +0200
Subject: [PATCH] refactor input once again

touch=false && useRelativeInput=false needs frameworks/native patch!!
---
 src/AndroidDesktop.cpp | 13 ++++++------
 src/InputDevice.cpp    | 46 ++++++++++++++++++++++++++++++++----------
 2 files changed, 42 insertions(+), 17 deletions(-)

diff --git a/src/AndroidDesktop.cpp b/src/AndroidDesktop.cpp
index 7d04b85..0ab708c 100644
--- a/src/AndroidDesktop.cpp
+++ b/src/AndroidDesktop.cpp
@@ -21,7 +21,6 @@ using namespace vncflinger;
 using namespace android;
 
 AndroidDesktop::AndroidDesktop() {
-    mInputDevice = new InputDevice();
     mDisplayRect = Rect(0, 0);
 
     mEventFd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
@@ -32,12 +31,12 @@ AndroidDesktop::AndroidDesktop() {
 }
 
 AndroidDesktop::~AndroidDesktop() {
-    mInputDevice->stop();
     close(mEventFd);
 }
 
 void AndroidDesktop::start(rfb::VNCServer* vs) {
     mServer = vs;
+    mInputDevice = new InputDevice();
 
     mPixels = new AndroidPixelBuffer();
     mPixels->setDimensionsChangedListener(this);
@@ -62,6 +61,7 @@ void AndroidDesktop::stop() {
 
     mVirtualDisplay.clear();
     mPixels.clear();
+    mInputDevice->stop();
 }
 
 void AndroidDesktop::processFrames() {
@@ -147,9 +147,10 @@ void AndroidDesktop::pointerEvent(const rfb::Point& pos, int buttonMask) {
         // outside viewport
         return;
     }
-    uint32_t spaceX = abs(((float)(mDisplayRect.getWidth() - mPixels->width())) / 2);
-    uint32_t x = pos.x - spaceX;
-    uint32_t y = pos.y * ((float)(mDisplayRect.getHeight()) / (float)mPixels->height());
+    uint32_t mx = (mPixels->width() - mDisplayRect.getWidth()) / 2;
+    uint32_t my = (mPixels->height() - mDisplayRect.getHeight()) / 2;
+    uint32_t x = (((pos.x - mx) * mDisplayMode.width) / ((float)(mDisplayRect.getWidth())));
+    uint32_t y = (((pos.y - my) * mDisplayMode.height) / ((float)(mDisplayRect.getHeight())));
 
     ALOGV("pointer xlate x1=%d y1=%d x2=%d y2=%d", pos.x, pos.y, x, y);
 
@@ -206,7 +207,7 @@ void AndroidDesktop::onBufferDimensionsChanged(uint32_t width, uint32_t height)
 
     mDisplayRect = mVirtualDisplay->getDisplayRect();
 
-    mInputDevice->reconfigure(mDisplayRect.getWidth(), mDisplayRect.getHeight());
+    mInputDevice->reconfigure(mDisplayMode.width, mDisplayMode.height);
 
     mServer->setPixelBuffer(mPixels.get(), computeScreenLayout());
     mServer->setScreenLayout(computeScreenLayout());
diff --git a/src/InputDevice.cpp b/src/InputDevice.cpp
index 3bf38b3..87dc834 100644
--- a/src/InputDevice.cpp
+++ b/src/InputDevice.cpp
@@ -32,7 +32,12 @@
 
 using namespace android;
 
-static bool touch = false;
+static bool touch = false; // true = touchscreen, false = mouse
+static bool useRelativeInput = false; // false = touchscreen, true = mouse
+// Relative Input tracking is unreliable BECAUSE Android adds fling to relative mouse input
+// I solved this by patching absolute mouse support into frameworks/native, but if you really want to use this
+// Do mind that viewer cursor and server cursor need to be same pos at the beginning
+// Or it will cause confusion
 
 static const struct UInputOptions {
     int cmd;
@@ -57,6 +62,9 @@ static const struct UInputOptions mOptions[] = {
     {UI_SET_RELBIT, REL_X},
     {UI_SET_RELBIT, REL_Y},
     {UI_SET_RELBIT, REL_WHEEL},
+    {UI_SET_EVBIT, EV_ABS},
+    {UI_SET_ABSBIT, ABS_X},
+    {UI_SET_ABSBIT, ABS_Y},
     {UI_SET_EVBIT, EV_SYN},
 };
 
@@ -115,7 +123,7 @@ status_t InputDevice::start(uint32_t width, uint32_t height) {
 
     mUserDev.id = id;
 
-    if (touch) {
+    if (!useRelativeInput) {
         mUserDev.absmin[ABS_X] = 0;
         mUserDev.absmax[ABS_X] = width;
         mUserDev.absmin[ABS_Y] = 0;
@@ -196,7 +204,7 @@ status_t InputDevice::movePointer(int32_t x, int32_t y) {
 
 status_t InputDevice::setPointer(int32_t x, int32_t y) {
     ALOGV("setPointer: x=%d y=%d", x, y);
-    if (!touch) {
+    if (useRelativeInput) {
         if (inject(EV_REL, REL_X, x - mLastX) != OK) {
             return BAD_VALUE;
         }
@@ -275,22 +283,28 @@ void InputDevice::pointerEvent(int buttonMask, int x, int y) {
 
     ALOGV("pointerEvent: buttonMask=%x x=%d y=%d", buttonMask, x, y);
 
-    int32_t diffX = x - mLastX;
-    int32_t diffY = y - mLastY;
+    int32_t diffX = (x - mLastX);
+    int32_t diffY = (y - mLastY);
     mLastX = x;
     mLastY = y;
     if (!touch) {
-        inject(EV_REL, REL_X, diffX);
-        inject(EV_REL, REL_Y, diffY);
+        if (!useRelativeInput) {
+            inject(EV_ABS, ABS_X, x);
+            inject(EV_ABS, ABS_Y, y);
+        } else {
+            inject(EV_REL, REL_X, diffX);
+            inject(EV_REL, REL_Y, diffY);
+        }
         inject(EV_SYN, SYN_REPORT, 0);
     }
 
     if ((buttonMask & 1) && !mLeftClicked) {  // left btn clicked
         mLeftClicked = true;
-
-        if (touch) {
+        if (!useRelativeInput) {
             inject(EV_ABS, ABS_X, x);
             inject(EV_ABS, ABS_Y, y);
+        }
+        if (touch) {
             inject(EV_KEY, BTN_TOUCH, 1);
         } else {
             inject(EV_KEY, BTN_LEFT, 1);
@@ -298,15 +312,17 @@ void InputDevice::pointerEvent(int buttonMask, int x, int y) {
         inject(EV_SYN, SYN_REPORT, 0);
     } else if (!(buttonMask & 1) && mLeftClicked) {  // left btn released
         mLeftClicked = false;
-        if (touch) {
+        if (!useRelativeInput) {
             inject(EV_ABS, ABS_X, x);
             inject(EV_ABS, ABS_Y, y);
+        }
+        if (touch) {
             inject(EV_KEY, BTN_TOUCH, 0);
         } else {
             inject(EV_KEY, BTN_LEFT, 0);
         }
         inject(EV_SYN, SYN_REPORT, 0);
-    } else if (mLeftClicked && touch) {
+    } else if (mLeftClicked && !useRelativeInput) { // dragclick
         inject(EV_ABS, ABS_X, x);
         inject(EV_ABS, ABS_Y, y);
         inject(EV_SYN, SYN_REPORT, 0);
@@ -330,6 +346,10 @@ void InputDevice::pointerEvent(int buttonMask, int x, int y) {
             inject(EV_KEY, BTN_RIGHT, 0);
         }
         inject(EV_SYN, SYN_REPORT, 0);
+    } else if (mRightClicked && !useRelativeInput) { // dragclick
+        inject(EV_ABS, ABS_X, x);
+        inject(EV_ABS, ABS_Y, y);
+        inject(EV_SYN, SYN_REPORT, 0);
     }
 
     if ((buttonMask & 2) && !mMiddleClicked) {  // mid btn clicked
@@ -349,6 +369,10 @@ void InputDevice::pointerEvent(int buttonMask, int x, int y) {
             inject(EV_KEY, BTN_MIDDLE, 0);
         }
         inject(EV_SYN, SYN_REPORT, 0);
+    } else if (mMiddleClicked && !useRelativeInput) { // dragclick
+        inject(EV_ABS, ABS_X, x);
+        inject(EV_ABS, ABS_Y, y);
+        inject(EV_SYN, SYN_REPORT, 0);
     }
 
     if (buttonMask & 8) {
-- 
GitLab