Loading core/java/android/view/MotionEvent.java +2 −0 Original line number Diff line number Diff line Loading @@ -2071,6 +2071,8 @@ public final class MotionEvent extends InputEvent implements Parcelable { * MotionEvent. For touch events, clients can use this to determine if the * user's finger was touching the edge of the display. * * This property is only set for {@link #ACTION_DOWN} events. * * @see #EDGE_LEFT * @see #EDGE_TOP * @see #EDGE_RIGHT Loading services/input/EventHub.h +0 −2 Original line number Diff line number Diff line Loading @@ -85,8 +85,6 @@ struct RawAbsoluteAxisInfo { int32_t flat; // center flat position, eg. flat == 8 means center is between -8 and 8 int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise inline int32_t getRange() const { return maxValue - minValue; } inline void clear() { valid = false; minValue = 0; Loading services/input/InputReader.cpp +138 −130 Original line number Diff line number Diff line Loading @@ -88,6 +88,18 @@ static inline const char* toString(bool value) { return value ? "true" : "false"; } static int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation, const int32_t map[][4], size_t mapSize) { if (orientation != DISPLAY_ORIENTATION_0) { for (size_t i = 0; i < mapSize; i++) { if (value == map[i][0]) { return map[i][orientation]; } } } return value; } static const int32_t keyCodeRotationMap[][4] = { // key codes enumerated counter-clockwise with the original (unrotated) key first // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation Loading @@ -96,18 +108,32 @@ static const int32_t keyCodeRotationMap[][4] = { { AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT }, { AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP }, }; static const int keyCodeRotationMapSize = static const size_t keyCodeRotationMapSize = sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]); int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) { if (orientation != DISPLAY_ORIENTATION_0) { for (int i = 0; i < keyCodeRotationMapSize; i++) { if (keyCode == keyCodeRotationMap[i][0]) { return keyCodeRotationMap[i][orientation]; } return rotateValueUsingRotationMap(keyCode, orientation, keyCodeRotationMap, keyCodeRotationMapSize); } } return keyCode; static const int32_t edgeFlagRotationMap[][4] = { // edge flags enumerated counter-clockwise with the original (unrotated) edge flag first // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation { AMOTION_EVENT_EDGE_FLAG_BOTTOM, AMOTION_EVENT_EDGE_FLAG_RIGHT, AMOTION_EVENT_EDGE_FLAG_TOP, AMOTION_EVENT_EDGE_FLAG_LEFT }, { AMOTION_EVENT_EDGE_FLAG_RIGHT, AMOTION_EVENT_EDGE_FLAG_TOP, AMOTION_EVENT_EDGE_FLAG_LEFT, AMOTION_EVENT_EDGE_FLAG_BOTTOM }, { AMOTION_EVENT_EDGE_FLAG_TOP, AMOTION_EVENT_EDGE_FLAG_LEFT, AMOTION_EVENT_EDGE_FLAG_BOTTOM, AMOTION_EVENT_EDGE_FLAG_RIGHT }, { AMOTION_EVENT_EDGE_FLAG_LEFT, AMOTION_EVENT_EDGE_FLAG_BOTTOM, AMOTION_EVENT_EDGE_FLAG_RIGHT, AMOTION_EVENT_EDGE_FLAG_TOP }, }; static const size_t edgeFlagRotationMapSize = sizeof(edgeFlagRotationMap) / sizeof(edgeFlagRotationMap[0]); static int32_t rotateEdgeFlag(int32_t edgeFlag, int32_t orientation) { return rotateValueUsingRotationMap(edgeFlag, orientation, edgeFlagRotationMap, edgeFlagRotationMapSize); } static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) { Loading Loading @@ -1293,7 +1319,8 @@ void CursorInputMapper::sync(nsecs_t when) { return; // no new state changes, so nothing to do } int motionEventAction; int32_t motionEventAction; int32_t motionEventEdgeFlags; PointerCoords pointerCoords; nsecs_t downTime; float vscroll, hscroll; Loading Loading @@ -1364,6 +1391,8 @@ void CursorInputMapper::sync(nsecs_t when) { pointerCoords.clear(); motionEventEdgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE; if (mPointerController != NULL) { mPointerController->move(deltaX, deltaY); if (downChanged) { Loading @@ -1373,6 +1402,22 @@ void CursorInputMapper::sync(nsecs_t when) { mPointerController->getPosition(&x, &y); pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x); pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y); if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) { float minX, minY, maxX, maxY; if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) { if (x <= minX) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT; } else if (x >= maxX) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT; } if (y <= minY) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP; } else if (y >= maxY) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM; } } } } else { pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX); pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY); Loading Loading @@ -1407,7 +1452,7 @@ void CursorInputMapper::sync(nsecs_t when) { int32_t metaState = mContext->getGlobalMetaState(); int32_t pointerId = 0; getDispatcher()->notifyMotion(when, getDeviceId(), mSources, policyFlags, motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE, motionEventAction, 0, metaState, motionEventEdgeFlags, 1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime); mAccumulator.clear(); Loading Loading @@ -1510,8 +1555,6 @@ void TouchInputMapper::dump(String8& dump) { dumpCalibration(dump); dumpSurfaceLocked(dump); dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n"); dump.appendFormat(INDENT4 "XOrigin: %d\n", mLocked.xOrigin); dump.appendFormat(INDENT4 "YOrigin: %d\n", mLocked.yOrigin); dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale); dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale); dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision); Loading Loading @@ -1657,10 +1700,17 @@ void TouchInputMapper::dumpRawAxes(String8& dump) { } bool TouchInputMapper::configureSurfaceLocked() { // Ensure we have valid X and Y axes. if (!mRawAxes.x.valid || !mRawAxes.y.valid) { LOGW(INDENT "Touch device '%s' did not report support for X or Y axis! " "The device will be inoperable.", getDeviceName().string()); return false; } // Update orientation and dimensions if needed. int32_t orientation = DISPLAY_ORIENTATION_0; int32_t width = mRawAxes.x.getRange(); int32_t height = mRawAxes.y.getRange(); int32_t width = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1; int32_t height = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1; if (mParameters.associatedDisplayId >= 0) { bool wantSize = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN; Loading Loading @@ -1688,32 +1738,12 @@ bool TouchInputMapper::configureSurfaceLocked() { mLocked.surfaceHeight = height; // Configure X and Y factors. if (mRawAxes.x.valid && mRawAxes.y.valid) { mLocked.xOrigin = mCalibration.haveXOrigin ? mCalibration.xOrigin : mRawAxes.x.minValue; mLocked.yOrigin = mCalibration.haveYOrigin ? mCalibration.yOrigin : mRawAxes.y.minValue; mLocked.xScale = mCalibration.haveXScale ? mCalibration.xScale : float(width) / mRawAxes.x.getRange(); mLocked.yScale = mCalibration.haveYScale ? mCalibration.yScale : float(height) / mRawAxes.y.getRange(); mLocked.xScale = float(width) / (mRawAxes.x.maxValue - mRawAxes.x.minValue + 1); mLocked.yScale = float(height) / (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1); mLocked.xPrecision = 1.0f / mLocked.xScale; mLocked.yPrecision = 1.0f / mLocked.yScale; configureVirtualKeysLocked(); } else { LOGW(INDENT "Touch device did not report support for X or Y axis!"); mLocked.xOrigin = 0; mLocked.yOrigin = 0; mLocked.xScale = 1.0f; mLocked.yScale = 1.0f; mLocked.xPrecision = 1.0f; mLocked.yPrecision = 1.0f; } // Scale factor for terms that are not oriented in a particular axis. // If the pixels are square then xScale == yScale otherwise we fake it Loading Loading @@ -1847,38 +1877,51 @@ bool TouchInputMapper::configureSurfaceLocked() { } if (orientationChanged || sizeChanged) { // Compute oriented surface dimensions, precision, and scales. float orientedXScale, orientedYScale; // Compute oriented surface dimensions, precision, scales and ranges. // Note that the maximum value reported is an inclusive maximum value so it is one // unit less than the total width or height of surface. switch (mLocked.surfaceOrientation) { case DISPLAY_ORIENTATION_90: case DISPLAY_ORIENTATION_270: mLocked.orientedSurfaceWidth = mLocked.surfaceHeight; mLocked.orientedSurfaceHeight = mLocked.surfaceWidth; mLocked.orientedXPrecision = mLocked.yPrecision; mLocked.orientedYPrecision = mLocked.xPrecision; orientedXScale = mLocked.yScale; orientedYScale = mLocked.xScale; mLocked.orientedRanges.x.min = 0; mLocked.orientedRanges.x.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue) * mLocked.yScale; mLocked.orientedRanges.x.flat = 0; mLocked.orientedRanges.x.fuzz = mLocked.yScale; mLocked.orientedRanges.y.min = 0; mLocked.orientedRanges.y.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue) * mLocked.xScale; mLocked.orientedRanges.y.flat = 0; mLocked.orientedRanges.y.fuzz = mLocked.xScale; break; default: mLocked.orientedSurfaceWidth = mLocked.surfaceWidth; mLocked.orientedSurfaceHeight = mLocked.surfaceHeight; mLocked.orientedXPrecision = mLocked.xPrecision; mLocked.orientedYPrecision = mLocked.yPrecision; orientedXScale = mLocked.xScale; orientedYScale = mLocked.yScale; break; } // Configure position ranges. mLocked.orientedRanges.x.min = 0; mLocked.orientedRanges.x.max = mLocked.orientedSurfaceWidth; mLocked.orientedRanges.x.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue) * mLocked.xScale; mLocked.orientedRanges.x.flat = 0; mLocked.orientedRanges.x.fuzz = orientedXScale; mLocked.orientedRanges.x.fuzz = mLocked.xScale; mLocked.orientedRanges.y.min = 0; mLocked.orientedRanges.y.max = mLocked.orientedSurfaceHeight; mLocked.orientedRanges.y.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue) * mLocked.yScale; mLocked.orientedRanges.y.flat = 0; mLocked.orientedRanges.y.fuzz = orientedYScale; mLocked.orientedRanges.y.fuzz = mLocked.yScale; break; } } return true; Loading @@ -1891,8 +1934,6 @@ void TouchInputMapper::dumpSurfaceLocked(String8& dump) { } void TouchInputMapper::configureVirtualKeysLocked() { assert(mRawAxes.x.valid && mRawAxes.y.valid); Vector<VirtualKeyDefinition> virtualKeyDefinitions; getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions); Loading @@ -1906,8 +1947,8 @@ void TouchInputMapper::configureVirtualKeysLocked() { int32_t touchScreenLeft = mRawAxes.x.minValue; int32_t touchScreenTop = mRawAxes.y.minValue; int32_t touchScreenWidth = mRawAxes.x.getRange(); int32_t touchScreenHeight = mRawAxes.y.getRange(); int32_t touchScreenWidth = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1; int32_t touchScreenHeight = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1; for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) { const VirtualKeyDefinition& virtualKeyDefinition = Loading Loading @@ -1942,7 +1983,6 @@ void TouchInputMapper::configureVirtualKeysLocked() { * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight) * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; } } Loading @@ -1965,12 +2005,6 @@ void TouchInputMapper::parseCalibration() { const PropertyMap& in = getDevice()->getConfiguration(); Calibration& out = mCalibration; // Position out.haveXOrigin = in.tryGetProperty(String8("touch.position.xOrigin"), out.xOrigin); out.haveYOrigin = in.tryGetProperty(String8("touch.position.yOrigin"), out.yOrigin); out.haveXScale = in.tryGetProperty(String8("touch.position.xScale"), out.xScale); out.haveYScale = in.tryGetProperty(String8("touch.position.yScale"), out.yScale); // Touch Size out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT; String8 touchSizeCalibrationString; Loading Loading @@ -2182,20 +2216,6 @@ void TouchInputMapper::resolveCalibration() { void TouchInputMapper::dumpCalibration(String8& dump) { dump.append(INDENT3 "Calibration:\n"); // Position if (mCalibration.haveXOrigin) { dump.appendFormat(INDENT4 "touch.position.xOrigin: %d\n", mCalibration.xOrigin); } if (mCalibration.haveYOrigin) { dump.appendFormat(INDENT4 "touch.position.yOrigin: %d\n", mCalibration.yOrigin); } if (mCalibration.haveXScale) { dump.appendFormat(INDENT4 "touch.position.xScale: %0.3f\n", mCalibration.xScale); } if (mCalibration.haveYScale) { dump.appendFormat(INDENT4 "touch.position.yScale: %0.3f\n", mCalibration.yScale); } // Touch Size switch (mCalibration.touchSizeCalibration) { case Calibration::TOUCH_SIZE_CALIBRATION_NONE: Loading Loading @@ -2623,7 +2643,7 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, int32_t motionEventAction) { int32_t pointerIds[MAX_POINTERS]; PointerCoords pointerCoords[MAX_POINTERS]; int32_t motionEventEdgeFlags = 0; int32_t motionEventEdgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE; float xPrecision, yPrecision; { // acquire lock Loading @@ -2638,10 +2658,6 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, const PointerData& in = touch->pointers[inIndex]; // X and Y float x = float(in.x - mLocked.xOrigin) * mLocked.xScale; float y = float(in.y - mLocked.yOrigin) * mLocked.yScale; // ToolMajor and ToolMinor float toolMajor, toolMinor; switch (mCalibration.toolSizeCalibration) { Loading Loading @@ -2779,33 +2795,34 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, orientation = 0; } // Adjust coords for orientation. // X and Y // Adjust coords for surface orientation. float x, y; switch (mLocked.surfaceOrientation) { case DISPLAY_ORIENTATION_90: { float xTemp = x; x = y; y = mLocked.surfaceWidth - xTemp; case DISPLAY_ORIENTATION_90: x = float(in.y - mRawAxes.y.minValue) * mLocked.yScale; y = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale; orientation -= M_PI_2; if (orientation < - M_PI_2) { orientation += M_PI; } break; } case DISPLAY_ORIENTATION_180: { x = mLocked.surfaceWidth - x; y = mLocked.surfaceHeight - y; case DISPLAY_ORIENTATION_180: x = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale; y = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale; break; } case DISPLAY_ORIENTATION_270: { float xTemp = x; x = mLocked.surfaceHeight - y; y = xTemp; case DISPLAY_ORIENTATION_270: x = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale; y = float(in.x - mRawAxes.x.minValue) * mLocked.xScale; orientation += M_PI_2; if (orientation > M_PI_2) { orientation -= M_PI; } break; } default: x = float(in.x - mRawAxes.x.minValue) * mLocked.xScale; y = float(in.y - mRawAxes.y.minValue) * mLocked.yScale; break; } // Write output coords. Loading @@ -2831,18 +2848,22 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, // Check edge flags by looking only at the first pointer since the flags are // global to the event. if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) { float x = pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X); float y = pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y); uint32_t inIndex = touch->idToIndex[pointerIds[0]]; const PointerData& in = touch->pointers[inIndex]; if (x <= 0) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT; } else if (x >= mLocked.orientedSurfaceWidth) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT; if (in.x <= mRawAxes.x.minValue) { motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_LEFT, mLocked.surfaceOrientation); } else if (in.x >= mRawAxes.x.maxValue) { motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_RIGHT, mLocked.surfaceOrientation); } if (y <= 0) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP; } else if (y >= mLocked.orientedSurfaceHeight) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM; if (in.y <= mRawAxes.y.minValue) { motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_TOP, mLocked.surfaceOrientation); } else if (in.y >= mRawAxes.y.maxValue) { motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_BOTTOM, mLocked.surfaceOrientation); } } Loading @@ -2857,12 +2878,9 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, } bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) { if (mRawAxes.x.valid && mRawAxes.y.valid) { return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue; } return true; } const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked( int32_t x, int32_t y) { Loading Loading @@ -3069,11 +3087,6 @@ void TouchInputMapper::calculatePointerIds() { * points has moved more than a screen height from the last position, * then drop it. */ bool TouchInputMapper::applyBadTouchFilter() { // This hack requires valid axis parameters. if (! mRawAxes.y.valid) { return false; } uint32_t pointerCount = mCurrentTouch.pointerCount; // Nothing to do if there are no points. Loading @@ -3092,7 +3105,7 @@ bool TouchInputMapper::applyBadTouchFilter() { // the long size of the screen to be bad. This was a magic value // determined by looking at the maximum distance it is feasible // to actually move in one sample. int32_t maxDeltaY = mRawAxes.y.getRange() * 7 / 16; int32_t maxDeltaY = (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1) * 7 / 16; // XXX The original code in InputDevice.java included commented out // code for testing the X axis. Note that when we drop a point Loading Loading @@ -3153,11 +3166,6 @@ bool TouchInputMapper::applyBadTouchFilter() { * the coordinate value for one axis has jumped to the other pointer's location. */ bool TouchInputMapper::applyJumpyTouchFilter() { // This hack requires valid axis parameters. if (! mRawAxes.y.valid) { return false; } uint32_t pointerCount = mCurrentTouch.pointerCount; if (mLastTouch.pointerCount != pointerCount) { #if DEBUG_HACKS Loading Loading @@ -3214,7 +3222,7 @@ bool TouchInputMapper::applyJumpyTouchFilter() { } if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) { int jumpyEpsilon = mRawAxes.y.getRange() / JUMPY_EPSILON_DIVISOR; int jumpyEpsilon = (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1) / JUMPY_EPSILON_DIVISOR; // We only replace the single worst jumpy point as characterized by pointer distance // in a single axis. Loading services/input/InputReader.h +0 −12 Original line number Diff line number Diff line Loading @@ -650,16 +650,6 @@ protected: // Immutable calibration parameters in parsed form. struct Calibration { // Position bool haveXOrigin; int32_t xOrigin; bool haveYOrigin; int32_t yOrigin; bool haveXScale; float xScale; bool haveYScale; float yScale; // Touch Size enum TouchSizeCalibration { TOUCH_SIZE_CALIBRATION_DEFAULT, Loading Loading @@ -756,11 +746,9 @@ protected: int32_t surfaceWidth, surfaceHeight; // Translation and scaling factors, orientation-independent. int32_t xOrigin; float xScale; float xPrecision; int32_t yOrigin; float yScale; float yPrecision; Loading services/input/PointerController.cpp +33 −28 Original line number Diff line number Diff line Loading @@ -109,12 +109,12 @@ bool PointerController::getBoundsLocked(float* outMinX, float* outMinY, switch (mLocked.displayOrientation) { case DISPLAY_ORIENTATION_90: case DISPLAY_ORIENTATION_270: *outMaxX = mLocked.displayHeight; *outMaxY = mLocked.displayWidth; *outMaxX = mLocked.displayHeight - 1; *outMaxY = mLocked.displayWidth - 1; break; default: *outMaxX = mLocked.displayWidth; *outMaxY = mLocked.displayHeight; *outMaxX = mLocked.displayWidth - 1; *outMaxY = mLocked.displayHeight - 1; break; } return true; Loading Loading @@ -309,48 +309,53 @@ void PointerController::setDisplayOrientation(int32_t orientation) { AutoMutex _l(mLock); if (mLocked.displayOrientation != orientation) { float absoluteX, absoluteY; // Map from oriented display coordinates to absolute display coordinates. // Apply offsets to convert from the pixel top-left corner position to the pixel center. // This creates an invariant frame of reference that we can easily rotate when // taking into account that the pointer may be located at fractional pixel offsets. float x = mLocked.pointerX + 0.5f; float y = mLocked.pointerY + 0.5f; float temp; // Undo the previous rotation. switch (mLocked.displayOrientation) { case DISPLAY_ORIENTATION_90: absoluteX = mLocked.displayWidth - mLocked.pointerY; absoluteY = mLocked.pointerX; temp = x; x = mLocked.displayWidth - y; y = temp; break; case DISPLAY_ORIENTATION_180: absoluteX = mLocked.displayWidth - mLocked.pointerX; absoluteY = mLocked.displayHeight - mLocked.pointerY; x = mLocked.displayWidth - x; y = mLocked.displayHeight - y; break; case DISPLAY_ORIENTATION_270: absoluteX = mLocked.pointerY; absoluteY = mLocked.displayHeight - mLocked.pointerX; break; default: absoluteX = mLocked.pointerX; absoluteY = mLocked.pointerY; temp = x; x = y; y = mLocked.displayHeight - temp; break; } // Map from absolute display coordinates to oriented display coordinates. // Perform the new rotation. switch (orientation) { case DISPLAY_ORIENTATION_90: mLocked.pointerX = absoluteY; mLocked.pointerY = mLocked.displayWidth - absoluteX; temp = x; x = y; y = mLocked.displayWidth - x; break; case DISPLAY_ORIENTATION_180: mLocked.pointerX = mLocked.displayWidth - absoluteX; mLocked.pointerY = mLocked.displayHeight - absoluteY; x = mLocked.displayWidth - x; y = mLocked.displayHeight - y; break; case DISPLAY_ORIENTATION_270: mLocked.pointerX = mLocked.displayHeight - absoluteY; mLocked.pointerY = absoluteX; break; default: mLocked.pointerX = absoluteX; mLocked.pointerY = absoluteY; temp = x; x = mLocked.displayHeight - y; y = temp; break; } // Apply offsets to convert from the pixel center to the pixel top-left corner position // and save the results. mLocked.pointerX = x - 0.5f; mLocked.pointerY = y - 0.5f; mLocked.displayOrientation = orientation; updateLocked(); Loading Loading
core/java/android/view/MotionEvent.java +2 −0 Original line number Diff line number Diff line Loading @@ -2071,6 +2071,8 @@ public final class MotionEvent extends InputEvent implements Parcelable { * MotionEvent. For touch events, clients can use this to determine if the * user's finger was touching the edge of the display. * * This property is only set for {@link #ACTION_DOWN} events. * * @see #EDGE_LEFT * @see #EDGE_TOP * @see #EDGE_RIGHT Loading
services/input/EventHub.h +0 −2 Original line number Diff line number Diff line Loading @@ -85,8 +85,6 @@ struct RawAbsoluteAxisInfo { int32_t flat; // center flat position, eg. flat == 8 means center is between -8 and 8 int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise inline int32_t getRange() const { return maxValue - minValue; } inline void clear() { valid = false; minValue = 0; Loading
services/input/InputReader.cpp +138 −130 Original line number Diff line number Diff line Loading @@ -88,6 +88,18 @@ static inline const char* toString(bool value) { return value ? "true" : "false"; } static int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation, const int32_t map[][4], size_t mapSize) { if (orientation != DISPLAY_ORIENTATION_0) { for (size_t i = 0; i < mapSize; i++) { if (value == map[i][0]) { return map[i][orientation]; } } } return value; } static const int32_t keyCodeRotationMap[][4] = { // key codes enumerated counter-clockwise with the original (unrotated) key first // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation Loading @@ -96,18 +108,32 @@ static const int32_t keyCodeRotationMap[][4] = { { AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT }, { AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP }, }; static const int keyCodeRotationMapSize = static const size_t keyCodeRotationMapSize = sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]); int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) { if (orientation != DISPLAY_ORIENTATION_0) { for (int i = 0; i < keyCodeRotationMapSize; i++) { if (keyCode == keyCodeRotationMap[i][0]) { return keyCodeRotationMap[i][orientation]; } return rotateValueUsingRotationMap(keyCode, orientation, keyCodeRotationMap, keyCodeRotationMapSize); } } return keyCode; static const int32_t edgeFlagRotationMap[][4] = { // edge flags enumerated counter-clockwise with the original (unrotated) edge flag first // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation { AMOTION_EVENT_EDGE_FLAG_BOTTOM, AMOTION_EVENT_EDGE_FLAG_RIGHT, AMOTION_EVENT_EDGE_FLAG_TOP, AMOTION_EVENT_EDGE_FLAG_LEFT }, { AMOTION_EVENT_EDGE_FLAG_RIGHT, AMOTION_EVENT_EDGE_FLAG_TOP, AMOTION_EVENT_EDGE_FLAG_LEFT, AMOTION_EVENT_EDGE_FLAG_BOTTOM }, { AMOTION_EVENT_EDGE_FLAG_TOP, AMOTION_EVENT_EDGE_FLAG_LEFT, AMOTION_EVENT_EDGE_FLAG_BOTTOM, AMOTION_EVENT_EDGE_FLAG_RIGHT }, { AMOTION_EVENT_EDGE_FLAG_LEFT, AMOTION_EVENT_EDGE_FLAG_BOTTOM, AMOTION_EVENT_EDGE_FLAG_RIGHT, AMOTION_EVENT_EDGE_FLAG_TOP }, }; static const size_t edgeFlagRotationMapSize = sizeof(edgeFlagRotationMap) / sizeof(edgeFlagRotationMap[0]); static int32_t rotateEdgeFlag(int32_t edgeFlag, int32_t orientation) { return rotateValueUsingRotationMap(edgeFlag, orientation, edgeFlagRotationMap, edgeFlagRotationMapSize); } static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) { Loading Loading @@ -1293,7 +1319,8 @@ void CursorInputMapper::sync(nsecs_t when) { return; // no new state changes, so nothing to do } int motionEventAction; int32_t motionEventAction; int32_t motionEventEdgeFlags; PointerCoords pointerCoords; nsecs_t downTime; float vscroll, hscroll; Loading Loading @@ -1364,6 +1391,8 @@ void CursorInputMapper::sync(nsecs_t when) { pointerCoords.clear(); motionEventEdgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE; if (mPointerController != NULL) { mPointerController->move(deltaX, deltaY); if (downChanged) { Loading @@ -1373,6 +1402,22 @@ void CursorInputMapper::sync(nsecs_t when) { mPointerController->getPosition(&x, &y); pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x); pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y); if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) { float minX, minY, maxX, maxY; if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) { if (x <= minX) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT; } else if (x >= maxX) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT; } if (y <= minY) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP; } else if (y >= maxY) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM; } } } } else { pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX); pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY); Loading Loading @@ -1407,7 +1452,7 @@ void CursorInputMapper::sync(nsecs_t when) { int32_t metaState = mContext->getGlobalMetaState(); int32_t pointerId = 0; getDispatcher()->notifyMotion(when, getDeviceId(), mSources, policyFlags, motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE, motionEventAction, 0, metaState, motionEventEdgeFlags, 1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime); mAccumulator.clear(); Loading Loading @@ -1510,8 +1555,6 @@ void TouchInputMapper::dump(String8& dump) { dumpCalibration(dump); dumpSurfaceLocked(dump); dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n"); dump.appendFormat(INDENT4 "XOrigin: %d\n", mLocked.xOrigin); dump.appendFormat(INDENT4 "YOrigin: %d\n", mLocked.yOrigin); dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale); dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale); dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision); Loading Loading @@ -1657,10 +1700,17 @@ void TouchInputMapper::dumpRawAxes(String8& dump) { } bool TouchInputMapper::configureSurfaceLocked() { // Ensure we have valid X and Y axes. if (!mRawAxes.x.valid || !mRawAxes.y.valid) { LOGW(INDENT "Touch device '%s' did not report support for X or Y axis! " "The device will be inoperable.", getDeviceName().string()); return false; } // Update orientation and dimensions if needed. int32_t orientation = DISPLAY_ORIENTATION_0; int32_t width = mRawAxes.x.getRange(); int32_t height = mRawAxes.y.getRange(); int32_t width = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1; int32_t height = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1; if (mParameters.associatedDisplayId >= 0) { bool wantSize = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN; Loading Loading @@ -1688,32 +1738,12 @@ bool TouchInputMapper::configureSurfaceLocked() { mLocked.surfaceHeight = height; // Configure X and Y factors. if (mRawAxes.x.valid && mRawAxes.y.valid) { mLocked.xOrigin = mCalibration.haveXOrigin ? mCalibration.xOrigin : mRawAxes.x.minValue; mLocked.yOrigin = mCalibration.haveYOrigin ? mCalibration.yOrigin : mRawAxes.y.minValue; mLocked.xScale = mCalibration.haveXScale ? mCalibration.xScale : float(width) / mRawAxes.x.getRange(); mLocked.yScale = mCalibration.haveYScale ? mCalibration.yScale : float(height) / mRawAxes.y.getRange(); mLocked.xScale = float(width) / (mRawAxes.x.maxValue - mRawAxes.x.minValue + 1); mLocked.yScale = float(height) / (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1); mLocked.xPrecision = 1.0f / mLocked.xScale; mLocked.yPrecision = 1.0f / mLocked.yScale; configureVirtualKeysLocked(); } else { LOGW(INDENT "Touch device did not report support for X or Y axis!"); mLocked.xOrigin = 0; mLocked.yOrigin = 0; mLocked.xScale = 1.0f; mLocked.yScale = 1.0f; mLocked.xPrecision = 1.0f; mLocked.yPrecision = 1.0f; } // Scale factor for terms that are not oriented in a particular axis. // If the pixels are square then xScale == yScale otherwise we fake it Loading Loading @@ -1847,38 +1877,51 @@ bool TouchInputMapper::configureSurfaceLocked() { } if (orientationChanged || sizeChanged) { // Compute oriented surface dimensions, precision, and scales. float orientedXScale, orientedYScale; // Compute oriented surface dimensions, precision, scales and ranges. // Note that the maximum value reported is an inclusive maximum value so it is one // unit less than the total width or height of surface. switch (mLocked.surfaceOrientation) { case DISPLAY_ORIENTATION_90: case DISPLAY_ORIENTATION_270: mLocked.orientedSurfaceWidth = mLocked.surfaceHeight; mLocked.orientedSurfaceHeight = mLocked.surfaceWidth; mLocked.orientedXPrecision = mLocked.yPrecision; mLocked.orientedYPrecision = mLocked.xPrecision; orientedXScale = mLocked.yScale; orientedYScale = mLocked.xScale; mLocked.orientedRanges.x.min = 0; mLocked.orientedRanges.x.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue) * mLocked.yScale; mLocked.orientedRanges.x.flat = 0; mLocked.orientedRanges.x.fuzz = mLocked.yScale; mLocked.orientedRanges.y.min = 0; mLocked.orientedRanges.y.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue) * mLocked.xScale; mLocked.orientedRanges.y.flat = 0; mLocked.orientedRanges.y.fuzz = mLocked.xScale; break; default: mLocked.orientedSurfaceWidth = mLocked.surfaceWidth; mLocked.orientedSurfaceHeight = mLocked.surfaceHeight; mLocked.orientedXPrecision = mLocked.xPrecision; mLocked.orientedYPrecision = mLocked.yPrecision; orientedXScale = mLocked.xScale; orientedYScale = mLocked.yScale; break; } // Configure position ranges. mLocked.orientedRanges.x.min = 0; mLocked.orientedRanges.x.max = mLocked.orientedSurfaceWidth; mLocked.orientedRanges.x.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue) * mLocked.xScale; mLocked.orientedRanges.x.flat = 0; mLocked.orientedRanges.x.fuzz = orientedXScale; mLocked.orientedRanges.x.fuzz = mLocked.xScale; mLocked.orientedRanges.y.min = 0; mLocked.orientedRanges.y.max = mLocked.orientedSurfaceHeight; mLocked.orientedRanges.y.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue) * mLocked.yScale; mLocked.orientedRanges.y.flat = 0; mLocked.orientedRanges.y.fuzz = orientedYScale; mLocked.orientedRanges.y.fuzz = mLocked.yScale; break; } } return true; Loading @@ -1891,8 +1934,6 @@ void TouchInputMapper::dumpSurfaceLocked(String8& dump) { } void TouchInputMapper::configureVirtualKeysLocked() { assert(mRawAxes.x.valid && mRawAxes.y.valid); Vector<VirtualKeyDefinition> virtualKeyDefinitions; getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions); Loading @@ -1906,8 +1947,8 @@ void TouchInputMapper::configureVirtualKeysLocked() { int32_t touchScreenLeft = mRawAxes.x.minValue; int32_t touchScreenTop = mRawAxes.y.minValue; int32_t touchScreenWidth = mRawAxes.x.getRange(); int32_t touchScreenHeight = mRawAxes.y.getRange(); int32_t touchScreenWidth = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1; int32_t touchScreenHeight = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1; for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) { const VirtualKeyDefinition& virtualKeyDefinition = Loading Loading @@ -1942,7 +1983,6 @@ void TouchInputMapper::configureVirtualKeysLocked() { * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight) * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; } } Loading @@ -1965,12 +2005,6 @@ void TouchInputMapper::parseCalibration() { const PropertyMap& in = getDevice()->getConfiguration(); Calibration& out = mCalibration; // Position out.haveXOrigin = in.tryGetProperty(String8("touch.position.xOrigin"), out.xOrigin); out.haveYOrigin = in.tryGetProperty(String8("touch.position.yOrigin"), out.yOrigin); out.haveXScale = in.tryGetProperty(String8("touch.position.xScale"), out.xScale); out.haveYScale = in.tryGetProperty(String8("touch.position.yScale"), out.yScale); // Touch Size out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT; String8 touchSizeCalibrationString; Loading Loading @@ -2182,20 +2216,6 @@ void TouchInputMapper::resolveCalibration() { void TouchInputMapper::dumpCalibration(String8& dump) { dump.append(INDENT3 "Calibration:\n"); // Position if (mCalibration.haveXOrigin) { dump.appendFormat(INDENT4 "touch.position.xOrigin: %d\n", mCalibration.xOrigin); } if (mCalibration.haveYOrigin) { dump.appendFormat(INDENT4 "touch.position.yOrigin: %d\n", mCalibration.yOrigin); } if (mCalibration.haveXScale) { dump.appendFormat(INDENT4 "touch.position.xScale: %0.3f\n", mCalibration.xScale); } if (mCalibration.haveYScale) { dump.appendFormat(INDENT4 "touch.position.yScale: %0.3f\n", mCalibration.yScale); } // Touch Size switch (mCalibration.touchSizeCalibration) { case Calibration::TOUCH_SIZE_CALIBRATION_NONE: Loading Loading @@ -2623,7 +2643,7 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, int32_t motionEventAction) { int32_t pointerIds[MAX_POINTERS]; PointerCoords pointerCoords[MAX_POINTERS]; int32_t motionEventEdgeFlags = 0; int32_t motionEventEdgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE; float xPrecision, yPrecision; { // acquire lock Loading @@ -2638,10 +2658,6 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, const PointerData& in = touch->pointers[inIndex]; // X and Y float x = float(in.x - mLocked.xOrigin) * mLocked.xScale; float y = float(in.y - mLocked.yOrigin) * mLocked.yScale; // ToolMajor and ToolMinor float toolMajor, toolMinor; switch (mCalibration.toolSizeCalibration) { Loading Loading @@ -2779,33 +2795,34 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, orientation = 0; } // Adjust coords for orientation. // X and Y // Adjust coords for surface orientation. float x, y; switch (mLocked.surfaceOrientation) { case DISPLAY_ORIENTATION_90: { float xTemp = x; x = y; y = mLocked.surfaceWidth - xTemp; case DISPLAY_ORIENTATION_90: x = float(in.y - mRawAxes.y.minValue) * mLocked.yScale; y = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale; orientation -= M_PI_2; if (orientation < - M_PI_2) { orientation += M_PI; } break; } case DISPLAY_ORIENTATION_180: { x = mLocked.surfaceWidth - x; y = mLocked.surfaceHeight - y; case DISPLAY_ORIENTATION_180: x = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale; y = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale; break; } case DISPLAY_ORIENTATION_270: { float xTemp = x; x = mLocked.surfaceHeight - y; y = xTemp; case DISPLAY_ORIENTATION_270: x = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale; y = float(in.x - mRawAxes.x.minValue) * mLocked.xScale; orientation += M_PI_2; if (orientation > M_PI_2) { orientation -= M_PI; } break; } default: x = float(in.x - mRawAxes.x.minValue) * mLocked.xScale; y = float(in.y - mRawAxes.y.minValue) * mLocked.yScale; break; } // Write output coords. Loading @@ -2831,18 +2848,22 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, // Check edge flags by looking only at the first pointer since the flags are // global to the event. if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) { float x = pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X); float y = pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y); uint32_t inIndex = touch->idToIndex[pointerIds[0]]; const PointerData& in = touch->pointers[inIndex]; if (x <= 0) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT; } else if (x >= mLocked.orientedSurfaceWidth) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT; if (in.x <= mRawAxes.x.minValue) { motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_LEFT, mLocked.surfaceOrientation); } else if (in.x >= mRawAxes.x.maxValue) { motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_RIGHT, mLocked.surfaceOrientation); } if (y <= 0) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP; } else if (y >= mLocked.orientedSurfaceHeight) { motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM; if (in.y <= mRawAxes.y.minValue) { motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_TOP, mLocked.surfaceOrientation); } else if (in.y >= mRawAxes.y.maxValue) { motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_BOTTOM, mLocked.surfaceOrientation); } } Loading @@ -2857,12 +2878,9 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, } bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) { if (mRawAxes.x.valid && mRawAxes.y.valid) { return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue; } return true; } const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked( int32_t x, int32_t y) { Loading Loading @@ -3069,11 +3087,6 @@ void TouchInputMapper::calculatePointerIds() { * points has moved more than a screen height from the last position, * then drop it. */ bool TouchInputMapper::applyBadTouchFilter() { // This hack requires valid axis parameters. if (! mRawAxes.y.valid) { return false; } uint32_t pointerCount = mCurrentTouch.pointerCount; // Nothing to do if there are no points. Loading @@ -3092,7 +3105,7 @@ bool TouchInputMapper::applyBadTouchFilter() { // the long size of the screen to be bad. This was a magic value // determined by looking at the maximum distance it is feasible // to actually move in one sample. int32_t maxDeltaY = mRawAxes.y.getRange() * 7 / 16; int32_t maxDeltaY = (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1) * 7 / 16; // XXX The original code in InputDevice.java included commented out // code for testing the X axis. Note that when we drop a point Loading Loading @@ -3153,11 +3166,6 @@ bool TouchInputMapper::applyBadTouchFilter() { * the coordinate value for one axis has jumped to the other pointer's location. */ bool TouchInputMapper::applyJumpyTouchFilter() { // This hack requires valid axis parameters. if (! mRawAxes.y.valid) { return false; } uint32_t pointerCount = mCurrentTouch.pointerCount; if (mLastTouch.pointerCount != pointerCount) { #if DEBUG_HACKS Loading Loading @@ -3214,7 +3222,7 @@ bool TouchInputMapper::applyJumpyTouchFilter() { } if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) { int jumpyEpsilon = mRawAxes.y.getRange() / JUMPY_EPSILON_DIVISOR; int jumpyEpsilon = (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1) / JUMPY_EPSILON_DIVISOR; // We only replace the single worst jumpy point as characterized by pointer distance // in a single axis. Loading
services/input/InputReader.h +0 −12 Original line number Diff line number Diff line Loading @@ -650,16 +650,6 @@ protected: // Immutable calibration parameters in parsed form. struct Calibration { // Position bool haveXOrigin; int32_t xOrigin; bool haveYOrigin; int32_t yOrigin; bool haveXScale; float xScale; bool haveYScale; float yScale; // Touch Size enum TouchSizeCalibration { TOUCH_SIZE_CALIBRATION_DEFAULT, Loading Loading @@ -756,11 +746,9 @@ protected: int32_t surfaceWidth, surfaceHeight; // Translation and scaling factors, orientation-independent. int32_t xOrigin; float xScale; float xPrecision; int32_t yOrigin; float yScale; float yPrecision; Loading
services/input/PointerController.cpp +33 −28 Original line number Diff line number Diff line Loading @@ -109,12 +109,12 @@ bool PointerController::getBoundsLocked(float* outMinX, float* outMinY, switch (mLocked.displayOrientation) { case DISPLAY_ORIENTATION_90: case DISPLAY_ORIENTATION_270: *outMaxX = mLocked.displayHeight; *outMaxY = mLocked.displayWidth; *outMaxX = mLocked.displayHeight - 1; *outMaxY = mLocked.displayWidth - 1; break; default: *outMaxX = mLocked.displayWidth; *outMaxY = mLocked.displayHeight; *outMaxX = mLocked.displayWidth - 1; *outMaxY = mLocked.displayHeight - 1; break; } return true; Loading Loading @@ -309,48 +309,53 @@ void PointerController::setDisplayOrientation(int32_t orientation) { AutoMutex _l(mLock); if (mLocked.displayOrientation != orientation) { float absoluteX, absoluteY; // Map from oriented display coordinates to absolute display coordinates. // Apply offsets to convert from the pixel top-left corner position to the pixel center. // This creates an invariant frame of reference that we can easily rotate when // taking into account that the pointer may be located at fractional pixel offsets. float x = mLocked.pointerX + 0.5f; float y = mLocked.pointerY + 0.5f; float temp; // Undo the previous rotation. switch (mLocked.displayOrientation) { case DISPLAY_ORIENTATION_90: absoluteX = mLocked.displayWidth - mLocked.pointerY; absoluteY = mLocked.pointerX; temp = x; x = mLocked.displayWidth - y; y = temp; break; case DISPLAY_ORIENTATION_180: absoluteX = mLocked.displayWidth - mLocked.pointerX; absoluteY = mLocked.displayHeight - mLocked.pointerY; x = mLocked.displayWidth - x; y = mLocked.displayHeight - y; break; case DISPLAY_ORIENTATION_270: absoluteX = mLocked.pointerY; absoluteY = mLocked.displayHeight - mLocked.pointerX; break; default: absoluteX = mLocked.pointerX; absoluteY = mLocked.pointerY; temp = x; x = y; y = mLocked.displayHeight - temp; break; } // Map from absolute display coordinates to oriented display coordinates. // Perform the new rotation. switch (orientation) { case DISPLAY_ORIENTATION_90: mLocked.pointerX = absoluteY; mLocked.pointerY = mLocked.displayWidth - absoluteX; temp = x; x = y; y = mLocked.displayWidth - x; break; case DISPLAY_ORIENTATION_180: mLocked.pointerX = mLocked.displayWidth - absoluteX; mLocked.pointerY = mLocked.displayHeight - absoluteY; x = mLocked.displayWidth - x; y = mLocked.displayHeight - y; break; case DISPLAY_ORIENTATION_270: mLocked.pointerX = mLocked.displayHeight - absoluteY; mLocked.pointerY = absoluteX; break; default: mLocked.pointerX = absoluteX; mLocked.pointerY = absoluteY; temp = x; x = mLocked.displayHeight - y; y = temp; break; } // Apply offsets to convert from the pixel center to the pixel top-left corner position // and save the results. mLocked.pointerX = x - 0.5f; mLocked.pointerY = y - 0.5f; mLocked.displayOrientation = orientation; updateLocked(); Loading