frameworks/native
Revision | 6084c3ffaba854080c32edfa77aa616a9fc309b4 (tree) |
---|---|
Time | 2018-12-26 13:14:02 |
Author | Jon Doe <tuksgig@gmai...> |
Commiter | Chih-Wei Huang |
inputflinger: treat tablet-style inputs as absolute coordinate mouse pointer
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.
@@ -1214,6 +1214,12 @@ status_t EventHub::openDeviceLocked(const char *devicePath, bool ignoreAlreadyOp | ||
1214 | 1214 | && test_bit(REL_X, device->relBitmask) |
1215 | 1215 | && test_bit(REL_Y, device->relBitmask)) { |
1216 | 1216 | device->classes |= INPUT_DEVICE_CLASS_CURSOR; |
1217 | + // Is this an absolute x-y axis with relative wheel mouse device? | |
1218 | + } else if (test_bit(BTN_MOUSE, device->keyBitmask) | |
1219 | + && test_bit(ABS_X, device->absBitmask) | |
1220 | + && test_bit(ABS_Y, device->absBitmask) | |
1221 | + && test_bit(REL_WHEEL, device->relBitmask)) { | |
1222 | + device->classes |= INPUT_DEVICE_CLASS_CURSOR; | |
1217 | 1223 | } |
1218 | 1224 | |
1219 | 1225 | // See if this is a rotary encoder type device. |
@@ -1238,7 +1244,8 @@ status_t EventHub::openDeviceLocked(const char *devicePath, bool ignoreAlreadyOp | ||
1238 | 1244 | // Is this an old style single-touch driver? |
1239 | 1245 | } else if ((test_bit(BTN_TOUCH, device->keyBitmask) || test_bit(BTN_LEFT, device->keyBitmask)) |
1240 | 1246 | && test_bit(ABS_X, device->absBitmask) |
1241 | - && test_bit(ABS_Y, device->absBitmask)) { | |
1247 | + && test_bit(ABS_Y, device->absBitmask) | |
1248 | + && !test_bit(REL_WHEEL, device->relBitmask)) { | |
1242 | 1249 | device->classes |= INPUT_DEVICE_CLASS_TOUCH; |
1243 | 1250 | // Is this a BT stylus? |
1244 | 1251 | } else if ((test_bit(ABS_PRESSURE, device->absBitmask) || |
@@ -1320,15 +1320,29 @@ void CursorMotionAccumulator::process(const RawEvent* rawEvent) { | ||
1320 | 1320 | switch (rawEvent->code) { |
1321 | 1321 | case REL_X: |
1322 | 1322 | mRelX = rawEvent->value; |
1323 | + mMoved = true; | |
1323 | 1324 | break; |
1324 | 1325 | case REL_Y: |
1325 | 1326 | mRelY = rawEvent->value; |
1327 | + mMoved = true; | |
1328 | + break; | |
1329 | + } | |
1330 | + } else if (rawEvent->type == EV_ABS) { | |
1331 | + switch (rawEvent->code) { | |
1332 | + case ABS_X: | |
1333 | + mAbsX = rawEvent->value; | |
1334 | + mMoved = true; | |
1335 | + break; | |
1336 | + case ABS_Y: | |
1337 | + mAbsY = rawEvent->value; | |
1338 | + mMoved = true; | |
1326 | 1339 | break; |
1327 | 1340 | } |
1328 | 1341 | } |
1329 | 1342 | } |
1330 | 1343 | |
1331 | 1344 | void CursorMotionAccumulator::finishSync() { |
1345 | + mMoved = false; | |
1332 | 1346 | clearRelativeAxes(); |
1333 | 1347 | } |
1334 | 1348 |
@@ -2480,6 +2494,10 @@ void CursorInputMapper::configure(nsecs_t when, | ||
2480 | 2494 | switch (mParameters.mode) { |
2481 | 2495 | case Parameters::MODE_POINTER: |
2482 | 2496 | mSource = AINPUT_SOURCE_MOUSE; |
2497 | + if (mParameters.hasAbsAxis) { | |
2498 | + getAbsoluteAxisInfo(ABS_X, &mRawAbsXInfo); | |
2499 | + getAbsoluteAxisInfo(ABS_Y, &mRawAbsYInfo); | |
2500 | + } | |
2483 | 2501 | mXPrecision = 1.0f; |
2484 | 2502 | mYPrecision = 1.0f; |
2485 | 2503 | mXScale = 1.0f; |
@@ -2506,10 +2524,18 @@ void CursorInputMapper::configure(nsecs_t when, | ||
2506 | 2524 | } |
2507 | 2525 | |
2508 | 2526 | if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) { |
2509 | - if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) { | |
2527 | + if (mParameters.hasAssociatedDisplay) { | |
2510 | 2528 | DisplayViewport v; |
2511 | 2529 | if (config->getDisplayInfo(false /*external*/, &v)) { |
2512 | - mOrientation = v.orientation; | |
2530 | + if (mParameters.orientationAware) { | |
2531 | + mOrientation = v.orientation; | |
2532 | + } | |
2533 | + if (mParameters.hasAbsAxis) { | |
2534 | + mXScale = float(v.logicalRight - v.logicalLeft)/(mRawAbsXInfo.maxValue - mRawAbsXInfo.minValue + 1); | |
2535 | + mYScale = float(v.logicalBottom - v.logicalTop)/(mRawAbsYInfo.maxValue - mRawAbsYInfo.minValue + 1); | |
2536 | + mXPrecision = 1.0f / mXScale; | |
2537 | + mYPrecision = 1.0f / mYScale; | |
2538 | + } | |
2513 | 2539 | } else { |
2514 | 2540 | mOrientation = DISPLAY_ORIENTATION_0; |
2515 | 2541 | } |
@@ -2539,6 +2565,11 @@ void CursorInputMapper::configureParameters() { | ||
2539 | 2565 | if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) { |
2540 | 2566 | mParameters.hasAssociatedDisplay = true; |
2541 | 2567 | } |
2568 | + | |
2569 | + mParameters.hasAbsAxis = false; | |
2570 | + if (mParameters.mode == Parameters::MODE_POINTER) { | |
2571 | + mParameters.hasAbsAxis = getDevice()->hasAbsoluteAxis(ABS_X) && getDevice()->hasAbsoluteAxis(ABS_Y) ? true : false; | |
2572 | + } | |
2542 | 2573 | } |
2543 | 2574 | |
2544 | 2575 | void CursorInputMapper::dumpParameters(String8& dump) { |
@@ -2559,6 +2590,8 @@ void CursorInputMapper::dumpParameters(String8& dump) { | ||
2559 | 2590 | |
2560 | 2591 | dump.appendFormat(INDENT4 "OrientationAware: %s\n", |
2561 | 2592 | toString(mParameters.orientationAware)); |
2593 | + dump.appendFormat(INDENT4 "Absolute Axis: %s\n", | |
2594 | + toString(mParameters.hasAbsAxis)); | |
2562 | 2595 | } |
2563 | 2596 | |
2564 | 2597 | void CursorInputMapper::reset(nsecs_t when) { |
@@ -2586,6 +2619,28 @@ void CursorInputMapper::process(const RawEvent* rawEvent) { | ||
2586 | 2619 | } |
2587 | 2620 | } |
2588 | 2621 | |
2622 | +void CursorInputMapper::rotateAbsolute(float* absX, float* absY) { | |
2623 | + float temp; | |
2624 | + switch (mOrientation) { | |
2625 | + case DISPLAY_ORIENTATION_90: | |
2626 | + temp = *absX; | |
2627 | + *absX = *absY; | |
2628 | + *absY = ((mRawAbsXInfo.maxValue - mRawAbsXInfo.minValue) + 1) - temp; | |
2629 | + break; | |
2630 | + | |
2631 | + case DISPLAY_ORIENTATION_180: | |
2632 | + *absX = ((mRawAbsXInfo.maxValue - mRawAbsXInfo.minValue) + 1) - *absX; | |
2633 | + *absY = ((mRawAbsYInfo.maxValue - mRawAbsYInfo.minValue) + 1) - *absY; | |
2634 | + break; | |
2635 | + | |
2636 | + case DISPLAY_ORIENTATION_270: | |
2637 | + temp = *absX; | |
2638 | + *absX = ((mRawAbsYInfo.maxValue - mRawAbsYInfo.minValue) + 1) - *absY; | |
2639 | + *absY = temp; | |
2640 | + break; | |
2641 | + } | |
2642 | +} | |
2643 | + | |
2589 | 2644 | void CursorInputMapper::sync(nsecs_t when) { |
2590 | 2645 | int32_t lastButtonState = mButtonState; |
2591 | 2646 | int32_t currentButtonState = mCursorButtonAccumulator.getButtonState(); |
@@ -2607,17 +2662,8 @@ void CursorInputMapper::sync(nsecs_t when) { | ||
2607 | 2662 | int32_t buttonsPressed = currentButtonState & ~lastButtonState; |
2608 | 2663 | int32_t buttonsReleased = lastButtonState & ~currentButtonState; |
2609 | 2664 | |
2610 | - float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale; | |
2611 | - float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale; | |
2612 | - bool moved = deltaX != 0 || deltaY != 0; | |
2613 | - | |
2614 | - // Rotate delta according to orientation if needed. | |
2615 | - if (mParameters.orientationAware && mParameters.hasAssociatedDisplay | |
2616 | - && (deltaX != 0.0f || deltaY != 0.0f)) { | |
2617 | - rotateDelta(mOrientation, &deltaX, &deltaY); | |
2618 | - } | |
2665 | + bool moved = false; | |
2619 | 2666 | |
2620 | - // Move the pointer. | |
2621 | 2667 | PointerProperties pointerProperties; |
2622 | 2668 | pointerProperties.clear(); |
2623 | 2669 | pointerProperties.id = 0; |
@@ -2626,6 +2672,47 @@ void CursorInputMapper::sync(nsecs_t when) { | ||
2626 | 2672 | PointerCoords pointerCoords; |
2627 | 2673 | pointerCoords.clear(); |
2628 | 2674 | |
2675 | + if (!mParameters.hasAbsAxis) { | |
2676 | + float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale; | |
2677 | + float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale; | |
2678 | + moved = deltaX != 0 || deltaY != 0; | |
2679 | + | |
2680 | + // Rotate delta according to orientation if needed. | |
2681 | + if (mParameters.orientationAware && mParameters.hasAssociatedDisplay | |
2682 | + && (deltaX != 0.0f || deltaY != 0.0f)) { | |
2683 | + rotateDelta(mOrientation, &deltaX, &deltaY); | |
2684 | + } | |
2685 | + mPointerVelocityControl.move(when, &deltaX, &deltaY); | |
2686 | + if (mPointerController != NULL) { | |
2687 | + if (moved) { | |
2688 | + mPointerController->move(deltaX, deltaY); | |
2689 | + } | |
2690 | + float x, y; | |
2691 | + mPointerController->getPosition(&x, &y); | |
2692 | + pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x); | |
2693 | + pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y); | |
2694 | + pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX); | |
2695 | + pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY); | |
2696 | + } else { | |
2697 | + pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX); | |
2698 | + pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY); | |
2699 | + } | |
2700 | + } else { | |
2701 | + float absX = mCursorMotionAccumulator.getAbsoluteX() - mRawAbsXInfo.minValue; | |
2702 | + float absY = mCursorMotionAccumulator.getAbsoluteY() - mRawAbsYInfo.minValue; | |
2703 | + if (mParameters.orientationAware) { | |
2704 | + rotateAbsolute(&absX, &absY); | |
2705 | + } | |
2706 | + absX = absX * mXScale; | |
2707 | + absY = absY * mYScale; | |
2708 | + moved = mCursorMotionAccumulator.hasMoved(); | |
2709 | + if (moved) { | |
2710 | + mPointerController->setPosition(absX, absY); | |
2711 | + } | |
2712 | + pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, absX); | |
2713 | + pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, absY); | |
2714 | + } | |
2715 | + | |
2629 | 2716 | float vscroll = mCursorScrollAccumulator.getRelativeVWheel(); |
2630 | 2717 | float hscroll = mCursorScrollAccumulator.getRelativeHWheel(); |
2631 | 2718 | bool scrolled = vscroll != 0 || hscroll != 0; |
@@ -2633,35 +2720,20 @@ void CursorInputMapper::sync(nsecs_t when) { | ||
2633 | 2720 | mWheelYVelocityControl.move(when, NULL, &vscroll); |
2634 | 2721 | mWheelXVelocityControl.move(when, &hscroll, NULL); |
2635 | 2722 | |
2636 | - mPointerVelocityControl.move(when, &deltaX, &deltaY); | |
2637 | - | |
2638 | 2723 | int32_t displayId; |
2639 | 2724 | if (mPointerController != NULL) { |
2640 | 2725 | if (moved || scrolled || buttonsChanged) { |
2641 | 2726 | mPointerController->setPresentation( |
2642 | 2727 | PointerControllerInterface::PRESENTATION_POINTER); |
2643 | 2728 | |
2644 | - if (moved) { | |
2645 | - mPointerController->move(deltaX, deltaY); | |
2646 | - } | |
2647 | - | |
2648 | 2729 | if (buttonsChanged) { |
2649 | 2730 | mPointerController->setButtonState(currentButtonState); |
2650 | 2731 | } |
2651 | 2732 | |
2652 | 2733 | mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE); |
2653 | 2734 | } |
2654 | - | |
2655 | - float x, y; | |
2656 | - mPointerController->getPosition(&x, &y); | |
2657 | - pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x); | |
2658 | - pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y); | |
2659 | - pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX); | |
2660 | - pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY); | |
2661 | 2735 | displayId = ADISPLAY_ID_DEFAULT; |
2662 | 2736 | } else { |
2663 | - pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX); | |
2664 | - pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY); | |
2665 | 2737 | displayId = ADISPLAY_ID_NONE; |
2666 | 2738 | } |
2667 | 2739 |
@@ -711,10 +711,16 @@ public: | ||
711 | 711 | |
712 | 712 | inline int32_t getRelativeX() const { return mRelX; } |
713 | 713 | inline int32_t getRelativeY() const { return mRelY; } |
714 | + inline int32_t getAbsoluteX() const { return mAbsX; } | |
715 | + inline int32_t getAbsoluteY() const { return mAbsY; } | |
716 | + inline bool hasMoved() const { return mMoved; } | |
714 | 717 | |
715 | 718 | private: |
716 | 719 | int32_t mRelX; |
717 | 720 | int32_t mRelY; |
721 | + int32_t mAbsX; | |
722 | + int32_t mAbsY; | |
723 | + bool mMoved; | |
718 | 724 | |
719 | 725 | void clearRelativeAxes(); |
720 | 726 | }; |
@@ -1206,6 +1212,7 @@ private: | ||
1206 | 1212 | Mode mode; |
1207 | 1213 | bool hasAssociatedDisplay; |
1208 | 1214 | bool orientationAware; |
1215 | + bool hasAbsAxis; | |
1209 | 1216 | } mParameters; |
1210 | 1217 | |
1211 | 1218 | CursorButtonAccumulator mCursorButtonAccumulator; |
@@ -1213,6 +1220,8 @@ private: | ||
1213 | 1220 | CursorScrollAccumulator mCursorScrollAccumulator; |
1214 | 1221 | |
1215 | 1222 | int32_t mSource; |
1223 | + RawAbsoluteAxisInfo mRawAbsXInfo; | |
1224 | + RawAbsoluteAxisInfo mRawAbsYInfo; | |
1216 | 1225 | float mXScale; |
1217 | 1226 | float mYScale; |
1218 | 1227 | float mXPrecision; |
@@ -1236,7 +1245,7 @@ private: | ||
1236 | 1245 | |
1237 | 1246 | void configureParameters(); |
1238 | 1247 | void dumpParameters(String8& dump); |
1239 | - | |
1248 | + void rotateAbsolute(float* absX, float* absY); | |
1240 | 1249 | void sync(nsecs_t when); |
1241 | 1250 | }; |
1242 | 1251 |