OSDN Git Service

inputflinger: treat tablet-style inputs as absolute coordinate mouse pointer android-x86-8.1-r1
authorJon Doe <tuksgig@gmail.com>
Sun, 23 Dec 2018 14:50:00 +0000 (22:50 +0800)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Wed, 26 Dec 2018 04:16:58 +0000 (12:16 +0800)
Qemu and VirtualBox use tablet-style inputs. However, it's difficult to
work with the current "invisible finger" or "drag pointer" interface
provided to the virtual absolute coordinate pointing devices.
Instead, this patch classifies them as a regular mouse pointer
(INPUT_DEVICE_CLASS_CURSOR), which is more intuitive to work with.

services/inputflinger/EventHub.cpp
services/inputflinger/InputReader.cpp
services/inputflinger/InputReader.h

index a3ace87..bf2adaf 100644 (file)
@@ -1252,6 +1252,12 @@ status_t EventHub::openDeviceLocked(const char *devicePath, bool ignoreAlreadyOp
             && test_bit(REL_X, device->relBitmask)
             && test_bit(REL_Y, device->relBitmask)) {
         device->classes |= INPUT_DEVICE_CLASS_CURSOR;
+    // Is this an absolute x-y axis with relative wheel mouse device?
+    } else if (test_bit(BTN_MOUSE, device->keyBitmask)
+               && test_bit(ABS_X, device->absBitmask)
+               && test_bit(ABS_Y, device->absBitmask)
+               && test_bit(REL_WHEEL, device->relBitmask)) {
+        device->classes |= INPUT_DEVICE_CLASS_CURSOR;
     }
 
     // See if this is a rotary encoder type device.
@@ -1276,7 +1282,8 @@ status_t EventHub::openDeviceLocked(const char *devicePath, bool ignoreAlreadyOp
     // Is this an old style single-touch driver?
     } else if ((test_bit(BTN_TOUCH, device->keyBitmask) || test_bit(BTN_LEFT, device->keyBitmask))
             && test_bit(ABS_X, device->absBitmask)
-            && test_bit(ABS_Y, device->absBitmask)) {
+            && test_bit(ABS_Y, device->absBitmask)
+            && !test_bit(REL_WHEEL, device->relBitmask)) {
         device->classes |= INPUT_DEVICE_CLASS_TOUCH;
     // Is this a BT stylus?
     } else if ((test_bit(ABS_PRESSURE, device->absBitmask) ||
index 4f0b1a7..e1d76a4 100644 (file)
@@ -1433,15 +1433,29 @@ void CursorMotionAccumulator::process(const RawEvent* rawEvent) {
         switch (rawEvent->code) {
         case REL_X:
             mRelX = rawEvent->value;
+            mMoved = true;
             break;
         case REL_Y:
             mRelY = rawEvent->value;
+            mMoved = true;
+            break;
+        }
+    } else if (rawEvent->type == EV_ABS) {
+        switch (rawEvent->code) {
+        case ABS_X:
+            mAbsX = rawEvent->value;
+            mMoved = true;
+            break;
+        case ABS_Y:
+            mAbsY = rawEvent->value;
+            mMoved = true;
             break;
         }
     }
 }
 
 void CursorMotionAccumulator::finishSync() {
+    mMoved = false;
     clearRelativeAxes();
 }
 
@@ -2641,6 +2655,10 @@ void CursorInputMapper::configure(nsecs_t when,
             // fall through.
         case Parameters::MODE_POINTER:
             mSource = AINPUT_SOURCE_MOUSE;
+            if (mParameters.hasAbsAxis) {
+                getAbsoluteAxisInfo(ABS_X, &mRawAbsXInfo);
+                getAbsoluteAxisInfo(ABS_Y, &mRawAbsYInfo);
+            }
             mXPrecision = 1.0f;
             mYPrecision = 1.0f;
             mXScale = 1.0f;
@@ -2692,10 +2710,18 @@ void CursorInputMapper::configure(nsecs_t when,
     }
 
     if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
-        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
+        if (mParameters.hasAssociatedDisplay) {
             DisplayViewport v;
             if (config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, NULL, &v)) {
-                mOrientation = v.orientation;
+                if (mParameters.orientationAware) {
+                    mOrientation = v.orientation;
+                }
+                if (mParameters.hasAbsAxis) {
+                    mXScale = float(v.logicalRight - v.logicalLeft)/(mRawAbsXInfo.maxValue - mRawAbsXInfo.minValue + 1);
+                    mYScale = float(v.logicalBottom - v.logicalTop)/(mRawAbsYInfo.maxValue - mRawAbsYInfo.minValue + 1);
+                    mXPrecision = 1.0f / mXScale;
+                    mYPrecision = 1.0f / mYScale;
+                }
             } else {
                 mOrientation = DISPLAY_ORIENTATION_0;
             }
@@ -2725,6 +2751,11 @@ void CursorInputMapper::configureParameters() {
     if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
         mParameters.hasAssociatedDisplay = true;
     }
+
+    mParameters.hasAbsAxis = false;
+    if (mParameters.mode == Parameters::MODE_POINTER) {
+        mParameters.hasAbsAxis = getDevice()->hasAbsoluteAxis(ABS_X) && getDevice()->hasAbsoluteAxis(ABS_Y) ? true : false;
+    }
 }
 
 void CursorInputMapper::dumpParameters(String8& dump) {
@@ -2748,6 +2779,8 @@ void CursorInputMapper::dumpParameters(String8& dump) {
 
     dump.appendFormat(INDENT4 "OrientationAware: %s\n",
             toString(mParameters.orientationAware));
+    dump.appendFormat(INDENT4 "Absolute Axis: %s\n",
+            toString(mParameters.hasAbsAxis));
 }
 
 void CursorInputMapper::reset(nsecs_t when) {
@@ -2775,6 +2808,28 @@ void CursorInputMapper::process(const RawEvent* rawEvent) {
     }
 }
 
+void CursorInputMapper::rotateAbsolute(float* absX, float* absY) {
+    float temp;
+    switch (mOrientation) {
+    case DISPLAY_ORIENTATION_90:
+        temp = *absX;
+        *absX = *absY;
+        *absY = ((mRawAbsXInfo.maxValue - mRawAbsXInfo.minValue) + 1) - temp;
+        break;
+
+    case DISPLAY_ORIENTATION_180:
+        *absX = ((mRawAbsXInfo.maxValue - mRawAbsXInfo.minValue) + 1) - *absX;
+        *absY = ((mRawAbsYInfo.maxValue - mRawAbsYInfo.minValue) + 1) - *absY;
+        break;
+
+    case DISPLAY_ORIENTATION_270:
+        temp = *absX;
+        *absX = ((mRawAbsYInfo.maxValue - mRawAbsYInfo.minValue) + 1) - *absY;
+        *absY = temp;
+        break;
+    }
+}
+
 void CursorInputMapper::sync(nsecs_t when) {
     int32_t lastButtonState = mButtonState;
     int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
@@ -2796,17 +2851,7 @@ void CursorInputMapper::sync(nsecs_t when) {
     int32_t buttonsPressed = currentButtonState & ~lastButtonState;
     int32_t buttonsReleased = lastButtonState & ~currentButtonState;
 
-    float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
-    float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
-    bool moved = deltaX != 0 || deltaY != 0;
-
-    // Rotate delta according to orientation if needed.
-    if (mParameters.orientationAware && mParameters.hasAssociatedDisplay
-            && (deltaX != 0.0f || deltaY != 0.0f)) {
-        rotateDelta(mOrientation, &deltaX, &deltaY);
-    }
-
-    // Move the pointer.
+    bool moved = false;
     PointerProperties pointerProperties;
     pointerProperties.clear();
     pointerProperties.id = 0;
@@ -2815,6 +2860,47 @@ void CursorInputMapper::sync(nsecs_t when) {
     PointerCoords pointerCoords;
     pointerCoords.clear();
 
+    if (!mParameters.hasAbsAxis) {
+        float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
+        float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
+        moved = deltaX != 0 || deltaY != 0;
+
+        // Rotate delta according to orientation if needed.
+        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay
+                && (deltaX != 0.0f || deltaY != 0.0f)) {
+            rotateDelta(mOrientation, &deltaX, &deltaY);
+        }
+        mPointerVelocityControl.move(when, &deltaX, &deltaY);
+        if (mPointerController != NULL) {
+            if (moved) {
+                mPointerController->move(deltaX, deltaY);
+            }
+            float x, y;
+            mPointerController->getPosition(&x, &y);
+            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
+            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
+        } else {
+            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
+            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
+        }
+    } else {
+        float absX = mCursorMotionAccumulator.getAbsoluteX() - mRawAbsXInfo.minValue;
+        float absY = mCursorMotionAccumulator.getAbsoluteY() - mRawAbsYInfo.minValue;
+        if (mParameters.orientationAware) {
+            rotateAbsolute(&absX, &absY);
+        }
+        absX = absX * mXScale;
+        absY = absY * mYScale;
+        moved = mCursorMotionAccumulator.hasMoved();
+        if (moved) {
+            mPointerController->setPosition(absX, absY);
+        }
+        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, absX);
+        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, absY);
+    }
+
     float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
     float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
     bool scrolled = vscroll != 0 || hscroll != 0;
@@ -2822,35 +2908,20 @@ void CursorInputMapper::sync(nsecs_t when) {
     mWheelYVelocityControl.move(when, NULL, &vscroll);
     mWheelXVelocityControl.move(when, &hscroll, NULL);
 
-    mPointerVelocityControl.move(when, &deltaX, &deltaY);
-
     int32_t displayId;
     if (mSource == AINPUT_SOURCE_MOUSE) {
         if (moved || scrolled || buttonsChanged) {
             mPointerController->setPresentation(
                     PointerControllerInterface::PRESENTATION_POINTER);
 
-            if (moved) {
-                mPointerController->move(deltaX, deltaY);
-            }
-
             if (buttonsChanged) {
                 mPointerController->setButtonState(currentButtonState);
             }
 
             mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
         }
-
-        float x, y;
-        mPointerController->getPosition(&x, &y);
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
         displayId = ADISPLAY_ID_DEFAULT;
     } else {
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
         displayId = ADISPLAY_ID_NONE;
     }
 
index e00b9b0..a679130 100644 (file)
@@ -678,10 +678,16 @@ public:
 
     inline int32_t getRelativeX() const { return mRelX; }
     inline int32_t getRelativeY() const { return mRelY; }
+    inline int32_t getAbsoluteX() const { return mAbsX; }
+    inline int32_t getAbsoluteY() const { return mAbsY; }
+    inline bool hasMoved() const { return mMoved; }
 
 private:
     int32_t mRelX;
     int32_t mRelY;
+    int32_t mAbsX;
+    int32_t mAbsY;
+    bool mMoved;
 
     void clearRelativeAxes();
 };
@@ -1175,6 +1181,7 @@ private:
         Mode mode;
         bool hasAssociatedDisplay;
         bool orientationAware;
+        bool hasAbsAxis;
     } mParameters;
 
     CursorButtonAccumulator mCursorButtonAccumulator;
@@ -1182,6 +1189,8 @@ private:
     CursorScrollAccumulator mCursorScrollAccumulator;
 
     int32_t mSource;
+    RawAbsoluteAxisInfo mRawAbsXInfo;
+    RawAbsoluteAxisInfo mRawAbsYInfo;
     float mXScale;
     float mYScale;
     float mXPrecision;
@@ -1205,7 +1214,7 @@ private:
 
     void configureParameters();
     void dumpParameters(String8& dump);
-
+    void rotateAbsolute(float* absX, float* absY);
     void sync(nsecs_t when);
 };