private static MotionEvent transformEventOld(MotionEvent paramMotionEvent, Matrix paramMatrix) { long l1 = paramMotionEvent.getDownTime(); long l2 = paramMotionEvent.getEventTime(); int i = paramMotionEvent.getAction(); int j = paramMotionEvent.getPointerCount(); int[] arrayOfInt = getPointerIds(paramMotionEvent); MotionEvent.PointerCoords[] arrayOfPointerCoords = getPointerCoords(paramMotionEvent); int k = paramMotionEvent.getMetaState(); float f1 = paramMotionEvent.getXPrecision(); float f2 = paramMotionEvent.getYPrecision(); int l = paramMotionEvent.getDeviceId(); int i1 = paramMotionEvent.getEdgeFlags(); int i2 = paramMotionEvent.getSource(); int i3 = paramMotionEvent.getFlags(); float[] arrayOfFloat = new float[2 * arrayOfPointerCoords.length]; for (int i4 = 0; i4 < j; ++i4) { arrayOfFloat[(i4 * 2)] = arrayOfPointerCoords[i4].x; arrayOfFloat[(1 + i4 * 2)] = arrayOfPointerCoords[i4].y; } paramMatrix.mapPoints(arrayOfFloat); for (int i5 = 0; i5 < j; ++i5) { arrayOfPointerCoords[i5].x = arrayOfFloat[(i5 * 2)]; arrayOfPointerCoords[i5].y = arrayOfFloat[(1 + i5 * 2)]; arrayOfPointerCoords[i5].orientation = transformAngle(paramMatrix, arrayOfPointerCoords[i5].orientation); } return MotionEvent.obtain( l1, l2, i, j, arrayOfInt, arrayOfPointerCoords, k, f1, f2, l, i1, i2, i3); }
/** * Clone given motion event and set specified action. This method is useful, when we want to * cancel event propagation in child views by sending event with {@link MotionEvent#ACTION_CANCEL} * action. * * @param event event to clone * @param action new action * @return cloned motion event */ private MotionEvent cloneMotionEventWithAction(MotionEvent event, int action) { return MotionEvent.obtain( event.getDownTime(), event.getEventTime(), action, event.getX(), event.getY(), event.getMetaState()); }
/** * Convert a motion event to a format suitable for sending over the wire * * @param evt motion event; x and y must already have been converted from screen coordinates to * remote frame buffer coordinates. * @param downEvent True if "mouse button" (touch or trackball button) is down when this happens * @param useRightButton If true, event is interpreted as happening with right mouse button * @return true if event was actually sent */ public boolean processPointerEvent(MotionEvent evt, boolean downEvent, boolean useRightButton) { return processPointerEvent( (int) evt.getX(), (int) evt.getY(), evt.getAction(), evt.getMetaState(), downEvent, useRightButton, false, false, -1); }
private void sendUpEvent() { final MotionEvent last = mLastMoveEvent; MotionEvent e = MotionEvent.obtain( last.getDownTime(), last.getEventTime(), MotionEvent.ACTION_UP, last.getX(), last.getY(), last.getMetaState()); dispatchTouchEvent(e); }
private void sendDownEvent() { if (DEBUG) { PtrCLog.d(LOG_TAG, "send down event"); } final MotionEvent last = mLastMoveEvent; MotionEvent e = MotionEvent.obtain( last.getDownTime(), last.getEventTime(), MotionEvent.ACTION_DOWN, last.getX(), last.getY(), last.getMetaState()); dispatchTouchEventSupper(e); }
private void sendCancelEvent() { if (DEBUG) { PtrCLog.d(LOG_TAG, "send cancel event"); } MotionEvent last = mDownEvent; last = mLastMoveEvent; MotionEvent e = MotionEvent.obtain( last.getDownTime(), last.getEventTime() + ViewConfiguration.getLongPressTimeout(), MotionEvent.ACTION_CANCEL, last.getX(), last.getY(), last.getMetaState()); dispatchTouchEventSupper(e); }
@Override public boolean onTouchEvent(@NonNull MotionEvent event) { if (mRecyclerWantsTouchEvent) { int scrollDiff = mCurrentScroll - mDownScroll; MotionEvent recyclerEvent = MotionEvent.obtain( event.getDownTime(), event.getEventTime(), event.getAction(), event.getX(), event.getY() - scrollDiff, event.getMetaState()); mRecycler.onTouchEvent(recyclerEvent); return false; } return super.onTouchEvent(event); }
/** * Overloaded processPointerEvent method which supports mouse scroll button. * * @param evt motion event; x and y must already have been converted from screen coordinates to * remote frame buffer coordinates. * @param downEvent True if "mouse button" (touch or trackball button) is down when this happens * @param useRightButton If true, event is interpreted as happening with right mouse button * @param useMiddleButton If true, event is interpreted as click happening with middle mouse * button * @param useScrollButton If true, event is interpreted as click happening with mouse scroll * button * @param direction Indicates the direction of the scroll event: 0 for up, 1 for down, 2 for left, * 3 for right. * @return true if event was actually sent */ public boolean processPointerEvent( MotionEvent evt, boolean downEvent, boolean useRightButton, boolean useMiddleButton, boolean useScrollButton, int direction) { return processPointerEvent( (int) evt.getX(), (int) evt.getY(), evt.getActionMasked(), evt.getMetaState(), downEvent, useRightButton, useMiddleButton, useScrollButton, direction); }
private void sendCancelEvent() { LogUtils.d("sendCancelEvent"); if (!mHasSendCancelEvent) { setRefreshTime(); mHasSendCancelEvent = true; mHasSendDownEvent = false; MotionEvent last = mLastMoveEvent; MotionEvent e = MotionEvent.obtain( last.getDownTime(), last.getEventTime() + ViewConfiguration.getLongPressTimeout(), MotionEvent.ACTION_CANCEL, last.getX(), last.getY(), last.getMetaState()); dispatchTouchEventSupper(e); } }
private void sendDownEvent() { if (!mHasSendDownEvent) { LogUtils.d("sendDownEvent"); mHasSendCancelEvent = false; mHasSendDownEvent = true; isIntercepted = false; final MotionEvent last = mLastMoveEvent; if (last == null) return; MotionEvent e = MotionEvent.obtain( last.getDownTime(), last.getEventTime(), MotionEvent.ACTION_DOWN, last.getX(), last.getY(), last.getMetaState()); dispatchTouchEventSupper(e); } }
private void initMotionEvent(MotionEvent m) { mAction = m.getAction(); mTime = (System.currentTimeMillis() - SystemClock.elapsedRealtime()) + m.getEventTime(); mMetaState = m.getMetaState(); switch (mAction & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_POINTER_DOWN: case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_HOVER_ENTER: case MotionEvent.ACTION_HOVER_MOVE: case MotionEvent.ACTION_HOVER_EXIT: { mCount = m.getPointerCount(); mPoints = new Point[mCount]; mPointIndicies = new int[mCount]; mOrientations = new float[mCount]; mPressures = new float[mCount]; mPointRadii = new Point[mCount]; mPointerIndex = (mAction & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; for (int i = 0; i < mCount; i++) { addMotionPoint(i, i, m); } break; } default: { mCount = 0; mPointerIndex = -1; mPoints = new Point[mCount]; mPointIndicies = new int[mCount]; mOrientations = new float[mCount]; mPressures = new float[mCount]; mPointRadii = new Point[mCount]; } } }
private void sendCancelEvent() { if (DEBUG) { PtrCLog.d(LOG_TAG, "send cancel event"); } // The ScrollChecker will update position and lead to send cancel event when mLastMoveEvent is // null. // fix #104, #80, #92 if (mLastMoveEvent == null) { return; } MotionEvent last = mLastMoveEvent; MotionEvent e = MotionEvent.obtain( last.getDownTime(), last.getEventTime() + ViewConfiguration.getLongPressTimeout(), MotionEvent.ACTION_CANCEL, last.getX(), last.getY(), last.getMetaState()); dispatchTouchEventSupper(e); }
private MotionEvent transformEvent(MotionEvent e, int headerPosition) { if (headerPosition == MATCHED_STICKIED_HEADER) { return e; } long downTime = e.getDownTime(); long eventTime = e.getEventTime(); int action = e.getAction(); int pointerCount = e.getPointerCount(); int[] pointerIds = getPointerIds(e); MotionEvent.PointerCoords[] pointerCoords = getPointerCoords(e); int metaState = e.getMetaState(); float xPrecision = e.getXPrecision(); float yPrecision = e.getYPrecision(); int deviceId = e.getDeviceId(); int edgeFlags = e.getEdgeFlags(); int source = e.getSource(); int flags = e.getFlags(); View headerHolder = getChildAt(headerPosition); for (int i = 0; i < pointerCount; i++) { pointerCoords[i].y -= headerHolder.getTop(); } MotionEvent n = MotionEvent.obtain( downTime, eventTime, action, pointerCount, pointerIds, pointerCoords, metaState, xPrecision, yPrecision, deviceId, edgeFlags, source, flags); return n; }
@Override public boolean dispatchTouchEvent(MotionEvent ev) { int action = ev.getAction() & MotionEvent.ACTION_MASK; if (action == MotionEvent.ACTION_DOWN) { mDownY = ev.getY(); mHeaderOwnsTouch = mHeader != null && mDownY <= mHeader.getHeight() + mHeaderOffset; } boolean handled; if (mHeaderOwnsTouch) { if (mHeader != null && Math.abs(mDownY - ev.getY()) <= mTouchSlop) { handled = mHeader.dispatchTouchEvent(ev); } else { if (mHeader != null) { MotionEvent cancelEvent = MotionEvent.obtain(ev); cancelEvent.setAction(MotionEvent.ACTION_CANCEL); mHeader.dispatchTouchEvent(cancelEvent); cancelEvent.recycle(); } MotionEvent downEvent = MotionEvent.obtain( ev.getDownTime(), ev.getEventTime(), ev.getAction(), ev.getX(), mDownY, ev.getMetaState()); downEvent.setAction(MotionEvent.ACTION_DOWN); handled = mList.dispatchTouchEvent(downEvent); downEvent.recycle(); mHeaderOwnsTouch = false; } } else { handled = mList.dispatchTouchEvent(ev); } return handled; }
/** * Overrides default trackball behavior: * * <ul> * <li>Up/down: Increases/decreases text navigation granularity * <li>Left/right: Moves to previous/next unit of text * </ul> * * <br> * Moving the trackball far to the left or right results in moving by multiple units. * * <p>If one of the following conditions is met, default behavior is preserved: * * <ul> * <li>No input connection available * <li>Input view is hidden * <li>Not currently editing text * <li>Cannot move in the specified direction * </ul> */ @SuppressWarnings("unused") @Override public boolean onTrackballEvent(MotionEvent event) { if (!ENABLE_TRACKBALL) return false; AccessibleInputConnection aic = getCurrentInputConnection(); if (aic == null || !isInputViewShown()) { return super.onTrackballEvent(event); } float x = event.getX(); float absX = Math.abs(event.getX()); float y = event.getY(); float absY = Math.abs(event.getY()); if (absY > 2 * absX && absY >= 0.75) { // Up and down switch granularities, but this is less common so it's // less sensitive. if (y < 0) { adjustGranularity(1); } else { adjustGranularity(-1); } } else { // If they moved the trackball really far, move by more than one but // only announce for the last move. int count = Math.max(1, (int) Math.floor(absX + 0.25)); boolean isNext = (x > 0); boolean isShiftPressed = (event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0; moveUnit(mGranularity, count, isNext, isShiftPressed); } return true; }
/** * Strips the last pointer from a {@link MotionEvent} and returns the modified event. Does not * modify the original event. * * @param ev The MotionEvent to modify. * @return The modified MotionEvent. */ private MotionEvent stripLastPointer(MotionEvent ev) { ev.getPointerCount(); int removePointer = ev.getPointerCount() - 1; int removePointerId = ev.getPointerId(removePointer); long downTime = ev.getDownTime(); long eventTime = ev.getEventTime(); int action = ev.getAction(); int pointers = ev.getPointerCount() - 1; int[] pointerIds = new int[pointers]; int metaState = ev.getMetaState(); float xPrecision = ev.getXPrecision(); float yPrecision = ev.getYPrecision(); int deviceId = ev.getDeviceId(); int edgeFlags = ev.getEdgeFlags(); switch (ev.getActionMasked()) { case MotionEvent.ACTION_POINTER_DOWN: case MotionEvent.ACTION_POINTER_UP: action -= 0x100; if (pointers == 1) { action -= 0x5; } break; } MotionEvent event = null; if (mCompatibilityMode) { float x = ev.getX(); float y = ev.getY(); float pressure = ev.getPressure(); float size = ev.getSize(); event = MotionEvent.obtain( downTime, eventTime, action, pointers, x, y, pressure, size, metaState, xPrecision, yPrecision, deviceId, edgeFlags); } // XXX commented out to get this to compile ! /* else { PointerCoords[] pointerCoords = new PointerCoords[pointers]; int source = ev.getSource(); int flags = ev.getFlags(); for (int i = 0; i < pointers; i++) { pointerIds[i] = ev.getPointerId(i); pointerCoords[i] = new PointerCoords(); ev.getPointerCoords(i, pointerCoords[i]); } event = MotionEvent.obtain(downTime, eventTime, action, pointers, pointerIds, pointerCoords, metaState, xPrecision, yPrecision, deviceId, edgeFlags, source, flags); } */ return event; }
private void logMotionEvent(MotionEvent event, boolean gen) { String s = gen ? "GenericMotionEvent from " : "TouchEvent from "; s += printDevice(event.getDeviceId()) + " source " + printSource(event.getSource()); int pointerCount = event.getPointerCount(); String action; switch (event.getActionMasked()) { case MotionEvent.ACTION_CANCEL: action = "cancel"; break; case MotionEvent.ACTION_DOWN: action = "down"; break; case MotionEvent.ACTION_HOVER_ENTER: action = "hover_enter"; break; case MotionEvent.ACTION_HOVER_EXIT: action = "hover_exit"; break; case MotionEvent.ACTION_HOVER_MOVE: action = "hover_move"; break; case MotionEvent.ACTION_MOVE: action = "move"; break; case MotionEvent.ACTION_OUTSIDE: action = "outside"; break; case MotionEvent.ACTION_POINTER_DOWN: action = "pointer_down"; break; case MotionEvent.ACTION_POINTER_UP: action = "pointer_up"; break; case MotionEvent.ACTION_UP: action = "up"; break; case MotionEvent.ACTION_SCROLL: action = "scroll"; break; default: action = "" + event.getAction(); break; } s += ", action " + action + " pointer count " + pointerCount + " buttons " + event.getButtonState() + " RawX " + event.getRawX() + " RawY " + event.getRawY() + " MetaState " + event.getMetaState() + " Flags " + event.getFlags() + "\n"; for (int p = 0; p < pointerCount; p++) { int ptrId = event.getPointerId(p); s += "Pointer id " + ptrId + " X " + event.getX(p) + " Y " + event.getY(p) + " pressure " + event.getPressure(p) + " size " + event.getSize(p) + " orientation " + event.getOrientation(p) + // (float)Math.toDegrees(event.getOrientation(p)) + " TouchMajor " + event.getTouchMajor(p) + " TouchMinor " + event.getTouchMinor(p) + " ToolMajor " + event.getToolMajor(p) + " ToolMinor " + event.getToolMinor(p) + "\n"; for (int i = 0; i < 255; i++) { if (event.getAxisValue(i, p) != 0.0) { s += "Axis " + i + " " + event.axisToString(i) + ": " + event.getAxisValue(i, p); InputDevice device = InputDevice.getDevice(event.getDeviceId()); if (device != null) { InputDevice.MotionRange range = device.getMotionRange(i); if (range != null) s += " range " + range.getMin() + " to " + range.getMax(); } s += "\n"; } } } pushText(s); }
/** * This function checks to see if we need to handle any sudden jumps in the pointer location that * could be due to a multi-touch being treated as a move by the firmware or hardware. Once a * sudden jump is detected, all subsequent move events are discarded until an UP is received. * * <p>When a sudden jump is detected, an UP event is simulated at the last position and when the * sudden moves subside, a DOWN event is simulated for the second key. * * @param me the motion event * @return true if the event was consumed, so that it doesn't continue to be handled by {@link * LatinKeyboardView}. */ private boolean handleSuddenJumping(MotionEvent me) { if (!mNeedsSuddenJumpingHack) return false; final int action = me.getAction(); final int x = (int) me.getX(); final int y = (int) me.getY(); boolean result = false; // Real multi-touch event? Stop looking for sudden jumps if (me.getPointerCount() > 1) { mDisableDisambiguation = true; } if (mDisableDisambiguation) { // If UP, reset the multi-touch flag if (action == MotionEvent.ACTION_UP) mDisableDisambiguation = false; return false; } switch (action) { case MotionEvent.ACTION_DOWN: // Reset the "session" mDroppingEvents = false; mDisableDisambiguation = false; break; case MotionEvent.ACTION_MOVE: // Is this a big jump? final int distanceSquare = (mLastX - x) * (mLastX - x) + (mLastY - y) * (mLastY - y); // Check the distance. if (distanceSquare > mJumpThresholdSquare) { // If we're not yet dropping events, start dropping and send an UP event if (!mDroppingEvents) { mDroppingEvents = true; // Send an up event MotionEvent translated = MotionEvent.obtain( me.getEventTime(), me.getEventTime(), MotionEvent.ACTION_UP, mLastX, mLastY, me.getMetaState()); mView.processMotionEvent(translated); translated.recycle(); } result = true; } else if (mDroppingEvents) { // If moves are small and we're already dropping events, continue dropping result = true; } break; case MotionEvent.ACTION_UP: if (mDroppingEvents) { // Send a down event first, as we dropped a bunch of sudden jumps and assume that // the user is releasing the touch on the second key. MotionEvent translated = MotionEvent.obtain( me.getEventTime(), me.getEventTime(), MotionEvent.ACTION_DOWN, x, y, me.getMetaState()); mView.processMotionEvent(translated); translated.recycle(); mDroppingEvents = false; // Let the up event get processed as well, result = false } break; } // Track the previous coordinate mLastX = x; mLastY = y; return result; }
@Override public boolean onTouch(View view, MotionEvent event) { if (layerView == null) { return false; } switch (event.getAction()) { case MotionEvent.ACTION_MOVE: if (moveZoomedView(event)) { dragged = true; } break; case MotionEvent.ACTION_UP: if (dragged) { dragged = false; } else { if (isClickInZoomedView(event.getY())) { GeckoAppShell.notifyObservers("Gesture:ClickInZoomedView", ""); layerView.dispatchTouchEvent(actionDownEvent); actionDownEvent.recycle(); PointF convertedPosition = getUnzoomedPositionFromPointInZoomedView(event.getX(), event.getY()); // the LayerView expects the coordinates relative to the window, not the surface, so // we need // to adjust that here. convertedPosition.y += layerView.getSurfaceTranslation(); MotionEvent e = MotionEvent.obtain( event.getDownTime(), event.getEventTime(), MotionEvent.ACTION_UP, convertedPosition.x, convertedPosition.y, event.getMetaState()); layerView.dispatchTouchEvent(e); e.recycle(); } } break; case MotionEvent.ACTION_DOWN: dragged = false; originRawX = event.getRawX(); originRawY = event.getRawY(); PointF convertedPosition = getUnzoomedPositionFromPointInZoomedView(event.getX(), event.getY()); // the LayerView expects the coordinates relative to the window, not the surface, so we // need // to adjust that here. convertedPosition.y += layerView.getSurfaceTranslation(); actionDownEvent = MotionEvent.obtain( event.getDownTime(), event.getEventTime(), MotionEvent.ACTION_DOWN, convertedPosition.x, convertedPosition.y, event.getMetaState()); break; } return true; }