diff --git a/api/current.xml b/api/current.xml index 3a7fd2f921bb2..ae7e7569330a7 100644 --- a/api/current.xml +++ b/api/current.xml @@ -144536,6 +144536,21 @@ + + + + + + + + + + + + + + + + + + @@ -144575,6 +144620,21 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -144860,6 +145020,17 @@ visibility="public" > + + + + + + + + + + + + + + + + + + + + + + 0) { + pointers--; + state[pointers] = pointers; + } + + ev.mTimeSamples[0] = eventTime; return ev; } @@ -218,17 +346,83 @@ public final class MotionEvent implements Parcelable { ev.mDeviceId = deviceId; ev.mEdgeFlags = edgeFlags; ev.mDownTime = downTime; - ev.mEventTime = eventTime; ev.mEventTimeNano = eventTime * 1000000; ev.mAction = action; - ev.mX = ev.mRawX = x; - ev.mY = ev.mRawY = y; - ev.mPressure = pressure; - ev.mSize = size; ev.mMetaState = metaState; ev.mXPrecision = xPrecision; ev.mYPrecision = yPrecision; + ev.mNumPointers = 1; + ev.mNumSamples = 1; + int[] state = ev.mStateSamples; + state[0] = 0; + float[] data = ev.mDataSamples; + data[SAMPLE_X] = ev.mRawX = x; + data[SAMPLE_Y] = ev.mRawY = y; + data[SAMPLE_PRESSURE] = pressure; + data[SAMPLE_SIZE] = size; + ev.mTimeSamples[0] = eventTime; + + return ev; + } + + /** + * Create a new MotionEvent, filling in all of the basic values that + * define the motion. + * + * @param downTime The time (in ms) when the user originally pressed down to start + * a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}. + * @param eventTime The the time (in ms) when this specific event was generated. This + * must be obtained from {@link SystemClock#uptimeMillis()}. + * @param action The kind of action being performed -- one of either + * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or + * {@link #ACTION_CANCEL}. + * @param pointers The number of pointers that are active in this event. + * @param x The X coordinate of this event. + * @param y The Y coordinate of this event. + * @param pressure The current pressure of this event. The pressure generally + * ranges from 0 (no pressure at all) to 1 (normal pressure), however + * values higher than 1 may be generated depending on the calibration of + * the input device. + * @param size A scaled value of the approximate size of the area being pressed when + * touched with the finger. The actual value in pixels corresponding to the finger + * touch is normalized with a device specific range of values + * and scaled to a value between 0 and 1. + * @param metaState The state of any meta / modifier keys that were in effect when + * the event was generated. + * @param xPrecision The precision of the X coordinate being reported. + * @param yPrecision The precision of the Y coordinate being reported. + * @param deviceId The id for the device that this event came from. An id of + * zero indicates that the event didn't come from a physical device; other + * numbers are arbitrary and you shouldn't depend on the values. + * @param edgeFlags A bitfield indicating which edges, if any, where touched by this + * MotionEvent. + */ + static public MotionEvent obtain(long downTime, long eventTime, int action, + int pointers, float x, float y, float pressure, float size, int metaState, + float xPrecision, float yPrecision, int deviceId, int edgeFlags) { + MotionEvent ev = obtain(); + ev.mDeviceId = deviceId; + ev.mEdgeFlags = edgeFlags; + ev.mDownTime = downTime; + ev.mEventTimeNano = eventTime * 1000000; + ev.mAction = action; + ev.mNumPointers = pointers; + ev.mMetaState = metaState; + ev.mXPrecision = xPrecision; + ev.mYPrecision = yPrecision; + + ev.mNumPointers = 1; + ev.mNumSamples = 1; + int[] state = ev.mStateSamples; + state[0] = 0; + float[] data = ev.mDataSamples; + data[SAMPLE_X] = ev.mRawX = x; + data[SAMPLE_Y] = ev.mRawY = y; + data[SAMPLE_PRESSURE] = pressure; + data[SAMPLE_SIZE] = size; + ev.mTimeSamples[0] = eventTime; + return ev; } @@ -255,17 +449,24 @@ public final class MotionEvent implements Parcelable { ev.mDeviceId = 0; ev.mEdgeFlags = 0; ev.mDownTime = downTime; - ev.mEventTime = eventTime; ev.mEventTimeNano = eventTime * 1000000; ev.mAction = action; - ev.mX = ev.mRawX = x; - ev.mY = ev.mRawY = y; - ev.mPressure = 1.0f; - ev.mSize = 1.0f; + ev.mNumPointers = 1; ev.mMetaState = metaState; ev.mXPrecision = 1.0f; ev.mYPrecision = 1.0f; + ev.mNumPointers = 1; + ev.mNumSamples = 1; + int[] state = ev.mStateSamples; + state[0] = 0; + float[] data = ev.mDataSamples; + data[SAMPLE_X] = ev.mRawX = x; + data[SAMPLE_Y] = ev.mRawY = y; + data[SAMPLE_PRESSURE] = 1.0f; + data[SAMPLE_SIZE] = 1.0f; + ev.mTimeSamples[0] = eventTime; + return ev; } @@ -275,43 +476,17 @@ public final class MotionEvent implements Parcelable { * @hide */ public void scale(float scale) { - mX *= scale; - mY *= scale; mRawX *= scale; mRawY *= scale; - mSize *= scale; mXPrecision *= scale; mYPrecision *= scale; - if (mHistory != null) { - float[] history = mHistory; - int length = history.length; - for (int i = 0; i < length; i += 4) { - history[i] *= scale; // X - history[i + 1] *= scale; // Y - // no need to scale pressure ([i+2]) - history[i + 3] *= scale; // Size, TODO: square this? - } - } - } - - /** - * Translate the coordination of the event by given x and y. - * - * @hide - */ - public void translate(float dx, float dy) { - mX += dx; - mY += dy; - mRawX += dx; - mRawY += dx; - if (mHistory != null) { - float[] history = mHistory; - int length = history.length; - for (int i = 0; i < length; i += 4) { - history[i] += dx; // X - history[i + 1] += dy; // Y - // no need to translate pressure (i+2) and size (i+3) - } + float[] history = mDataSamples; + final int length = mNumPointers * mNumSamples * NUM_SAMPLE_DATA; + for (int i = 0; i < length; i += NUM_SAMPLE_DATA) { + history[i + SAMPLE_X] *= scale; + history[i + SAMPLE_Y] *= scale; + // no need to scale pressure + history[i + SAMPLE_SIZE] *= scale; // TODO: square this? } } @@ -323,25 +498,36 @@ public final class MotionEvent implements Parcelable { ev.mDeviceId = o.mDeviceId; ev.mEdgeFlags = o.mEdgeFlags; ev.mDownTime = o.mDownTime; - ev.mEventTime = o.mEventTime; ev.mEventTimeNano = o.mEventTimeNano; ev.mAction = o.mAction; - ev.mX = o.mX; + ev.mNumPointers = o.mNumPointers; ev.mRawX = o.mRawX; - ev.mY = o.mY; ev.mRawY = o.mRawY; - ev.mPressure = o.mPressure; - ev.mSize = o.mSize; ev.mMetaState = o.mMetaState; ev.mXPrecision = o.mXPrecision; ev.mYPrecision = o.mYPrecision; - final int N = o.mNumHistory; - ev.mNumHistory = N; - if (N > 0) { - // could be more efficient about this... - ev.mHistory = (float[])o.mHistory.clone(); - ev.mHistoryTimes = (long[])o.mHistoryTimes.clone(); + + final int NT = ev.mNumSamples = o.mNumSamples; + if (ev.mTimeSamples.length < NT) { + System.arraycopy(o.mTimeSamples, 0, ev.mTimeSamples, 0, NT); + } else { + ev.mTimeSamples = (long[])o.mTimeSamples.clone(); } + + final int NS = (ev.mNumPointers=o.mNumPointers) * NT; + if (ev.mStateSamples.length < NS) { + System.arraycopy(o.mStateSamples, 0, ev.mStateSamples, 0, NS); + } else { + ev.mStateSamples = (int[])o.mStateSamples.clone(); + } + + final int ND = NS * NUM_SAMPLE_DATA; + if (ev.mDataSamples.length < ND) { + System.arraycopy(o.mDataSamples, 0, ev.mDataSamples, 0, ND); + } else { + ev.mDataSamples = (float[])o.mDataSamples.clone(); + } + return ev; } @@ -364,7 +550,7 @@ public final class MotionEvent implements Parcelable { synchronized (gRecyclerLock) { if (gRecyclerUsed < MAX_RECYCLED) { gRecyclerUsed++; - mNumHistory = 0; + mNumSamples = 0; mNext = gRecyclerTop; gRecyclerTop = this; } @@ -392,7 +578,7 @@ public final class MotionEvent implements Parcelable { * Returns the time (in ms) when this specific event was generated. */ public final long getEventTime() { - return mEventTime; + return mTimeSamples[0]; } /** @@ -406,40 +592,88 @@ public final class MotionEvent implements Parcelable { } /** - * Returns the X coordinate of this event. Whole numbers are pixels; the - * value may have a fraction for input devices that are sub-pixel precise. + * The number of pointers of data contained in this event. Always + * >= 1. + */ + public final int getPointerCount() { + return mNumPointers; + } + + /** + * {@link #getX(int)} for the first pointer (pointer 0). */ public final float getX() { - return mX; + return mDataSamples[SAMPLE_X]; } /** - * Returns the Y coordinate of this event. Whole numbers are pixels; the - * value may have a fraction for input devices that are sub-pixel precise. + * {@link #getY(int)} for the first pointer (pointer 0). */ public final float getY() { - return mY; + return mDataSamples[SAMPLE_Y]; } /** - * Returns the current pressure of this event. The pressure generally + * {@link #getPressure(int)} for the first pointer (pointer 0). + */ + public final float getPressure() { + return mDataSamples[SAMPLE_PRESSURE]; + } + + /** + * {@link #getSize(int)} for the first pointer (pointer 0). + */ + public final float getSize() { + return mDataSamples[SAMPLE_SIZE]; + } + + /** + * Returns the X coordinate of this event for the given pointer. + * Whole numbers are pixels; the + * value may have a fraction for input devices that are sub-pixel precise. + * @param pointer The desired pointer to retrieve. Value may be from 0 + * (the first pointer) to {@link #getPointerCount()}-1. + */ + public final float getX(int pointer) { + return mDataSamples[(pointer*NUM_SAMPLE_DATA) + SAMPLE_X]; + } + + /** + * Returns the Y coordinate of this event for the given pointer. + * Whole numbers are pixels; the + * value may have a fraction for input devices that are sub-pixel precise. + * @param pointer The desired pointer to retrieve. Value may be from 0 + * (the first pointer) to {@link #getPointerCount()}-1. + */ + public final float getY(int pointer) { + return mDataSamples[(pointer*NUM_SAMPLE_DATA) + SAMPLE_Y]; + } + + /** + * Returns the current pressure of this event for the given pointer. + * The pressure generally * ranges from 0 (no pressure at all) to 1 (normal pressure), however * values higher than 1 may be generated depending on the calibration of * the input device. + * @param pointer The desired pointer to retrieve. Value may be from 0 + * (the first pointer) to {@link #getPointerCount()}-1. */ - public final float getPressure() { - return mPressure; + public final float getPressure(int pointer) { + return mDataSamples[(pointer*NUM_SAMPLE_DATA) + SAMPLE_PRESSURE]; } /** - * Returns a scaled value of the approximate size, of the area being pressed when - * touched with the finger. The actual value in pixels corresponding to the finger - * touch is normalized with the device specific range of values + * Returns a scaled value of the approximate size for the given pointer, + * representing the area of the screen being pressed. + * The actual value in pixels corresponding to the + * touch is normalized with the device specific range of values * and scaled to a value between 0 and 1. The value of size can be used to * determine fat touch events. + * @param pointer The desired pointer to retrieve. Value may be from 0 + * (the first pointer) to {@link #getPointerCount()}-1. */ - public final float getSize() { - return mSize; + public final float getSize(int pointer) { + return mDataSamples[(pointer*NUM_SAMPLE_DATA) + SAMPLE_SIZE]; } /** @@ -505,7 +739,7 @@ public final class MotionEvent implements Parcelable { * @return Returns the number of historical points in the event. */ public final int getHistorySize() { - return mNumHistory; + return mNumSamples - 1; } /** @@ -519,63 +753,103 @@ public final class MotionEvent implements Parcelable { * @see #getEventTime */ public final long getHistoricalEventTime(int pos) { - return mHistoryTimes[pos]; + return mTimeSamples[pos + 1]; + } + + /** + * {@link #getHistoricalX(int)} for the first pointer (pointer 0). + */ + public final float getHistoricalX(int pos) { + return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_X]; + } + + /** + * {@link #getHistoricalY(int)} for the first pointer (pointer 0). + */ + public final float getHistoricalY(int pos) { + return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_Y]; + } + + /** + * {@link #getHistoricalPressure(int)} for the first pointer (pointer 0). + */ + public final float getHistoricalPressure(int pos) { + return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_PRESSURE]; + } + + /** + * {@link #getHistoricalSize(int)} for the first pointer (pointer 0). + */ + public final float getHistoricalSize(int pos) { + return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_SIZE]; } /** * Returns a historical X coordinate that occurred between this event - * and the previous event. Only applies to ACTION_MOVE events. + * and the previous event for the given pointer. Only applies to ACTION_MOVE events. * + * @param pointer The desired pointer to retrieve. Value may be from 0 + * (the first pointer) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getX */ - public final float getHistoricalX(int pos) { - return mHistory[pos*4]; + public final float getHistoricalX(int pointer, int pos) { + return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + + (pointer * NUM_SAMPLE_DATA) + SAMPLE_X]; } /** * Returns a historical Y coordinate that occurred between this event - * and the previous event. Only applies to ACTION_MOVE events. + * and the previous event for the given pointer. Only applies to ACTION_MOVE events. * + * @param pointer The desired pointer to retrieve. Value may be from 0 + * (the first pointer) to {@link #getPointerCount()}-1. * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * * @see #getHistorySize * @see #getY */ - public final float getHistoricalY(int pos) { - return mHistory[pos*4 + 1]; + public final float getHistoricalY(int pointer, int pos) { + return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + + (pointer * NUM_SAMPLE_DATA) + SAMPLE_Y]; } /** * Returns a historical pressure coordinate that occurred between this event - * and the previous event. Only applies to ACTION_MOVE events. + * and the previous event for the given pointer. Only applies to ACTION_MOVE events. * * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * + * @param pointer The desired pointer to retrieve. Value may be from 0 + * (the first pointer) to {@link #getPointerCount()}-1. * @see #getHistorySize * @see #getPressure */ - public final float getHistoricalPressure(int pos) { - return mHistory[pos*4 + 2]; + public final float getHistoricalPressure(int pointer, int pos) { + return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + + (pointer * NUM_SAMPLE_DATA) + SAMPLE_PRESSURE]; } /** * Returns a historical size coordinate that occurred between this event - * and the previous event. Only applies to ACTION_MOVE events. + * and the previous event for the given pointer. Only applies to ACTION_MOVE events. * * @param pos Which historical value to return; must be less than * {@link #getHistorySize} * + * @param pointer The desired pointer to retrieve. Value may be from 0 + * (the first pointer) to {@link #getPointerCount()}-1. * @see #getHistorySize * @see #getSize */ - public final float getHistoricalSize(int pos) { - return mHistory[pos*4 + 3]; + public final float getHistoricalSize(int pointer, int pos) { + return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + + (pointer * NUM_SAMPLE_DATA) + SAMPLE_SIZE]; } /** @@ -625,16 +899,11 @@ public final class MotionEvent implements Parcelable { * @param deltaY Amount to add to the current Y coordinate of the event. */ public final void offsetLocation(float deltaX, float deltaY) { - mX += deltaX; - mY += deltaY; - final int N = mNumHistory*4; - if (N <= 0) { - return; - } - final float[] pos = mHistory; - for (int i=0; i CREATOR @@ -732,27 +1061,29 @@ public final class MotionEvent implements Parcelable { public void writeToParcel(Parcel out, int flags) { out.writeLong(mDownTime); - out.writeLong(mEventTime); out.writeLong(mEventTimeNano); out.writeInt(mAction); - out.writeFloat(mX); - out.writeFloat(mY); - out.writeFloat(mPressure); - out.writeFloat(mSize); out.writeInt(mMetaState); out.writeFloat(mRawX); out.writeFloat(mRawY); - final int N = mNumHistory; - out.writeInt(N); - if (N > 0) { - final int N4 = N*4; + final int NP = mNumPointers; + out.writeInt(NP); + final int NS = mNumSamples; + out.writeInt(NS); + final int NI = NP*NS; + if (NI > 0) { int i; - float[] history = mHistory; - for (i=0; i 0) { - final int N4 = N*4; - float[] history = mHistory; - if (history == null || history.length < N4) { - mHistory = history = new float[N4 + (4*4)]; + final int NP = in.readInt(); + mNumPointers = NP; + final int NS = in.readInt(); + mNumSamples = NS; + final int NI = NP*NS; + if (NI > 0) { + final int NI4 = NI*4; + int[] state = mStateSamples; + if (state.length < NI) { + mStateSamples = state = new int[NI]; } - for (int i=0; i absX.maxValue + || cur[MotionEvent.SAMPLE_Y] < absY.minValue + || cur[MotionEvent.SAMPLE_Y] > absY.maxValue) { + if (false) Log.v("InputDevice", "Rejecting (" + + cur[MotionEvent.SAMPLE_X] + "," + + cur[MotionEvent.SAMPLE_Y] + "): outside of (" + + absX.minValue + "," + absY.minValue + + ")-(" + absX.maxValue + "," + + absY.maxValue + ")"); + return null; + } + } + mLastAnyDown = anyDown; + if (anyDown) { + action = MotionEvent.ACTION_DOWN; + mDownTime = curTime; + } else { + action = MotionEvent.ACTION_UP; + } + currentMove = null; + } else if (firstDownChanged >= 0) { + if (mDown[firstDownChanged]) { + action = MotionEvent.ACTION_POINTER_DOWN + | (firstDownChanged << MotionEvent.ACTION_POINTER_SHIFT); + } else { + action = MotionEvent.ACTION_POINTER_UP + | (firstDownChanged << MotionEvent.ACTION_POINTER_SHIFT); + } + currentMove = null; + } else { + action = MotionEvent.ACTION_MOVE; + } + + final int dispW = display.getWidth()-1; + final int dispH = display.getHeight()-1; + int w = dispW; + int h = dispH; + if (orientation == Surface.ROTATION_90 + || orientation == Surface.ROTATION_270) { + int tmp = w; + w = h; + h = tmp; + } + + final AbsoluteInfo absX = device.absX; + final AbsoluteInfo absY = device.absY; + final AbsoluteInfo absPressure = device.absPressure; + final AbsoluteInfo absSize = device.absSize; + for (int i=0; i= dispW) { + edgeFlags |= MotionEvent.EDGE_RIGHT; + } + if (scaled[MotionEvent.SAMPLE_Y] <= 0) { + edgeFlags |= MotionEvent.EDGE_TOP; + } else if (scaled[MotionEvent.SAMPLE_Y] >= dispH) { + edgeFlags |= MotionEvent.EDGE_BOTTOM; + } + } + + if (currentMove != null) { + if (false) Log.i("InputDevice", "Adding batch x=" + + scaled[MotionEvent.SAMPLE_X] + + " y=" + scaled[MotionEvent.SAMPLE_Y] + + " to " + currentMove); + currentMove.addBatch(curTime, scaled, metaState); + if (WindowManagerPolicy.WATCH_POINTER) { + Log.i("KeyInputQueue", "Updating: " + currentMove); + } + return null; + } + + MotionEvent me = MotionEvent.obtainNano(mDownTime, curTime, + curTimeNano, action, numPointers, scaled, metaState, + xPrecision, yPrecision, device.id, edgeFlags); + if (action == MotionEvent.ACTION_MOVE) { + currentMove = me; + } + return me; + } + + MotionEvent generateRelMotion(InputDevice device, long curTime, + long curTimeNano, int orientation, int metaState) { + + final float[] scaled = mReportData; + + // For now we only support 1 pointer with relative motions. + scaled[MotionEvent.SAMPLE_X] = mCurData[MotionEvent.SAMPLE_X]; + scaled[MotionEvent.SAMPLE_Y] = mCurData[MotionEvent.SAMPLE_Y]; + scaled[MotionEvent.SAMPLE_PRESSURE] = 1.0f; + scaled[MotionEvent.SAMPLE_SIZE] = 0; int edgeFlags = 0; int action; - if (down != lastDown) { - if (isAbs) { - final AbsoluteInfo absX = device.absX; - final AbsoluteInfo absY = device.absY; - if (down && absX != null && absY != null) { - // We don't let downs start unless we are - // inside of the screen. There are two reasons for - // this: to avoid spurious touches when holding - // the edges of the device near the touchscreen, - // and to avoid reporting events if there are virtual - // keys on the touchscreen outside of the display - // area. - if (scaledX < absX.minValue || scaledX > absX.maxValue - || scaledY < absY.minValue || scaledY > absY.maxValue) { - if (false) Log.v("InputDevice", "Rejecting (" + scaledX + "," - + scaledY + "): outside of (" - + absX.minValue + "," + absY.minValue - + ")-(" + absX.maxValue + "," - + absY.maxValue + ")"); - return null; - } - } - } else { - x = y = 0; - } - lastDown = down; - if (down) { + if (mDown[0] != mLastDown[0]) { + mCurData[MotionEvent.SAMPLE_X] = + mCurData[MotionEvent.SAMPLE_Y] = 0; + mLastDown[0] = mDown[0]; + if (mDown[0]) { action = MotionEvent.ACTION_DOWN; - downTime = curTime; + mDownTime = curTime; } else { action = MotionEvent.ACTION_UP; } @@ -111,100 +275,42 @@ public class InputDevice { action = MotionEvent.ACTION_MOVE; } - if (isAbs) { - final int dispW = display.getWidth()-1; - final int dispH = display.getHeight()-1; - int w = dispW; - int h = dispH; - if (orientation == Surface.ROTATION_90 - || orientation == Surface.ROTATION_270) { - int tmp = w; - w = h; - h = tmp; + scaled[MotionEvent.SAMPLE_X] *= xMoveScale; + scaled[MotionEvent.SAMPLE_Y] *= yMoveScale; + switch (orientation) { + case Surface.ROTATION_90: { + final float temp = scaled[MotionEvent.SAMPLE_X]; + scaled[MotionEvent.SAMPLE_X] = scaled[MotionEvent.SAMPLE_Y]; + scaled[MotionEvent.SAMPLE_Y] = -temp; + break; } - if (device.absX != null) { - scaledX = ((scaledX-device.absX.minValue) - / device.absX.range) * w; + case Surface.ROTATION_180: { + scaled[MotionEvent.SAMPLE_X] = -scaled[MotionEvent.SAMPLE_X]; + scaled[MotionEvent.SAMPLE_Y] = -scaled[MotionEvent.SAMPLE_Y]; + break; } - if (device.absY != null) { - scaledY = ((scaledY-device.absY.minValue) - / device.absY.range) * h; - } - if (device.absPressure != null) { - scaledPressure = - ((pressure-device.absPressure.minValue) - / (float)device.absPressure.range); - } - if (device.absSize != null) { - scaledSize = - ((size-device.absSize.minValue) - / (float)device.absSize.range); - } - switch (orientation) { - case Surface.ROTATION_90: - temp = scaledX; - scaledX = scaledY; - scaledY = w-temp; - break; - case Surface.ROTATION_180: - scaledX = w-scaledX; - scaledY = h-scaledY; - break; - case Surface.ROTATION_270: - temp = scaledX; - scaledX = h-scaledY; - scaledY = temp; - break; - } - - if (action != MotionEvent.ACTION_DOWN) { - if (scaledX <= 0) { - edgeFlags += MotionEvent.EDGE_LEFT; - } else if (scaledX >= dispW) { - edgeFlags += MotionEvent.EDGE_RIGHT; - } - if (scaledY <= 0) { - edgeFlags += MotionEvent.EDGE_TOP; - } else if (scaledY >= dispH) { - edgeFlags += MotionEvent.EDGE_BOTTOM; - } - } - - } else { - scaledX *= xMoveScale; - scaledY *= yMoveScale; - switch (orientation) { - case Surface.ROTATION_90: - temp = scaledX; - scaledX = scaledY; - scaledY = -temp; - break; - case Surface.ROTATION_180: - scaledX = -scaledX; - scaledY = -scaledY; - break; - case Surface.ROTATION_270: - temp = scaledX; - scaledX = -scaledY; - scaledY = temp; - break; + case Surface.ROTATION_270: { + final float temp = scaled[MotionEvent.SAMPLE_X]; + scaled[MotionEvent.SAMPLE_X] = -scaled[MotionEvent.SAMPLE_Y]; + scaled[MotionEvent.SAMPLE_Y] = temp; + break; } } if (currentMove != null) { - if (false) Log.i("InputDevice", "Adding batch x=" + scaledX - + " y=" + scaledY + " to " + currentMove); - currentMove.addBatch(curTime, scaledX, scaledY, - scaledPressure, scaledSize, metaState); + if (false) Log.i("InputDevice", "Adding batch x=" + + scaled[MotionEvent.SAMPLE_X] + + " y=" + scaled[MotionEvent.SAMPLE_Y] + + " to " + currentMove); + currentMove.addBatch(curTime, scaled, metaState); if (WindowManagerPolicy.WATCH_POINTER) { Log.i("KeyInputQueue", "Updating: " + currentMove); } return null; } - MotionEvent me = MotionEvent.obtainNano(downTime, curTime, - curTimeNano, action, scaledX, scaledY, - scaledPressure, scaledSize, metaState, + MotionEvent me = MotionEvent.obtainNano(mDownTime, curTime, + curTimeNano, action, 1, scaled, metaState, xPrecision, yPrecision, device.id, edgeFlags); if (action == MotionEvent.ACTION_MOVE) { currentMove = me; diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java index 77051bd0023c8..17e9625409408 100644 --- a/services/java/com/android/server/KeyInputQueue.java +++ b/services/java/com/android/server/KeyInputQueue.java @@ -446,14 +446,14 @@ public abstract class KeyInputQueue { boolean down; if (ev.value != 0) { down = true; - di.mDownTime = curTime; + di.mKeyDownTime = curTime; } else { down = false; } int keycode = rotateKeyCodeLocked(ev.keycode); addLocked(di, curTimeNano, ev.flags, RawInputEvent.CLASS_KEYBOARD, - newKeyEvent(di, di.mDownTime, curTime, down, + newKeyEvent(di, di.mKeyDownTime, curTime, down, keycode, 0, scancode, ((ev.flags & WindowManagerPolicy.FLAG_WOKE_HERE) != 0) ? KeyEvent.FLAG_WOKE_HERE : 0)); @@ -461,29 +461,47 @@ public abstract class KeyInputQueue { if (ev.scancode == RawInputEvent.BTN_TOUCH && (classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) { di.mAbs.changed = true; - di.mAbs.down = ev.value != 0; - } - if (ev.scancode == RawInputEvent.BTN_MOUSE && + di.mAbs.mDown[0] = ev.value != 0; + } else if (ev.scancode == RawInputEvent.BTN_2 && + (classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) { + di.mAbs.changed = true; + di.mAbs.mDown[1] = ev.value != 0; + } else if (ev.scancode == RawInputEvent.BTN_MOUSE && (classes&RawInputEvent.CLASS_TRACKBALL) != 0) { di.mRel.changed = true; - di.mRel.down = ev.value != 0; + di.mRel.mDown[0] = ev.value != 0; send = true; } } else if (ev.type == RawInputEvent.EV_ABS && (classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) { + // Finger 1 if (ev.scancode == RawInputEvent.ABS_X) { di.mAbs.changed = true; - di.mAbs.x = ev.value; + di.mAbs.mCurData[MotionEvent.SAMPLE_X] = ev.value; } else if (ev.scancode == RawInputEvent.ABS_Y) { di.mAbs.changed = true; - di.mAbs.y = ev.value; + di.mAbs.mCurData[MotionEvent.SAMPLE_Y] = ev.value; } else if (ev.scancode == RawInputEvent.ABS_PRESSURE) { di.mAbs.changed = true; - di.mAbs.pressure = ev.value; + di.mAbs.mCurData[MotionEvent.SAMPLE_PRESSURE] = ev.value; + di.mAbs.mCurData[MotionEvent.NUM_SAMPLE_DATA + + MotionEvent.SAMPLE_PRESSURE] = ev.value; } else if (ev.scancode == RawInputEvent.ABS_TOOL_WIDTH) { di.mAbs.changed = true; - di.mAbs.size = ev.value; + di.mAbs.mCurData[MotionEvent.SAMPLE_SIZE] = ev.value; + di.mAbs.mCurData[MotionEvent.NUM_SAMPLE_DATA + + MotionEvent.SAMPLE_SIZE] = ev.value; + + // Finger 2 + } else if (ev.scancode == RawInputEvent.ABS_HAT0X) { + di.mAbs.changed = true; + di.mAbs.mCurData[MotionEvent.NUM_SAMPLE_DATA + + MotionEvent.SAMPLE_X] = ev.value; + } else if (ev.scancode == RawInputEvent.ABS_HAT0Y) { + di.mAbs.changed = true; + di.mAbs.mCurData[MotionEvent.NUM_SAMPLE_DATA + + MotionEvent.SAMPLE_Y] = ev.value; } } else if (ev.type == RawInputEvent.EV_REL && @@ -491,10 +509,10 @@ public abstract class KeyInputQueue { // Add this relative movement into our totals. if (ev.scancode == RawInputEvent.REL_X) { di.mRel.changed = true; - di.mRel.x += ev.value; + di.mRel.mCurData[MotionEvent.SAMPLE_X] += ev.value; } else if (ev.scancode == RawInputEvent.REL_Y) { di.mRel.changed = true; - di.mRel.y += ev.value; + di.mRel.mCurData[MotionEvent.SAMPLE_Y] += ev.value; } } @@ -516,33 +534,33 @@ public abstract class KeyInputQueue { VirtualKey vk = mPressedVirtualKey; if (vk != null) { doMotion = false; - if (!ms.down) { + if (!ms.mDown[0]) { mPressedVirtualKey = null; - ms.lastDown = ms.down; + ms.mLastDown[0] = ms.mDown[0]; if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Generate key up for: " + vk.scancode); addLocked(di, curTimeNano, ev.flags, RawInputEvent.CLASS_KEYBOARD, - newKeyEvent(di, di.mDownTime, + newKeyEvent(di, di.mKeyDownTime, curTime, false, vk.lastKeycode, 0, vk.scancode, 0)); } - } else if (ms.down && !ms.lastDown) { + } else if (ms.mDown[0] && !ms.mLastDown[0]) { vk = findSoftButton(di); if (vk != null) { doMotion = false; mPressedVirtualKey = vk; vk.lastKeycode = scancodeToKeycode( di.id, vk.scancode); - ms.lastDown = ms.down; - di.mDownTime = curTime; + ms.mLastDown[0] = ms.mDown[0]; + di.mKeyDownTime = curTime; if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Generate key down for: " + vk.scancode + " (keycode=" + vk.lastKeycode + ")"); addLocked(di, curTimeNano, ev.flags, RawInputEvent.CLASS_KEYBOARD, - newKeyEvent(di, di.mDownTime, + newKeyEvent(di, di.mKeyDownTime, curTime, true, vk.lastKeycode, 0, vk.scancode, 0)); @@ -550,11 +568,18 @@ public abstract class KeyInputQueue { } if (doMotion) { - me = ms.generateMotion(di, curTime, - curTimeNano, true, mDisplay, + // XXX Need to be able to generate + // multiple events here, for example + // if two fingers change up/down state + // at the same time. + me = ms.generateAbsMotion(di, curTime, + curTimeNano, mDisplay, mOrientation, mGlobalMetaState); - if (false) Log.v(TAG, "Absolute: x=" + di.mAbs.x - + " y=" + di.mAbs.y + " ev=" + me); + if (false) Log.v(TAG, "Absolute: x=" + + di.mAbs.mCurData[MotionEvent.SAMPLE_X] + + " y=" + + di.mAbs.mCurData[MotionEvent.SAMPLE_Y] + + " ev=" + me); if (me != null) { if (WindowManagerPolicy.WATCH_POINTER) { Log.i(TAG, "Enqueueing: " + me); @@ -569,11 +594,14 @@ public abstract class KeyInputQueue { if (ms.changed) { ms.changed = false; - me = ms.generateMotion(di, curTime, - curTimeNano, false, mDisplay, + me = ms.generateRelMotion(di, curTime, + curTimeNano, mOrientation, mGlobalMetaState); - if (false) Log.v(TAG, "Relative: x=" + di.mRel.x - + " y=" + di.mRel.y + " ev=" + me); + if (false) Log.v(TAG, "Relative: x=" + + di.mRel.mCurData[MotionEvent.SAMPLE_X] + + " y=" + + di.mRel.mCurData[MotionEvent.SAMPLE_Y] + + " ev=" + me); if (me != null) { addLocked(di, curTimeNano, ev.flags, RawInputEvent.CLASS_TRACKBALL, me); @@ -603,21 +631,28 @@ public abstract class KeyInputQueue { return null; } - if (absm.x >= absx.minValue && absm.x <= absx.maxValue - && absm.y >= absy.minValue && absm.y <= absy.maxValue) { - if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Input (" + absm.x - + "," + absm.y + ") inside of display"); + if (absm.mCurData[MotionEvent.SAMPLE_X] >= absx.minValue + && absm.mCurData[MotionEvent.SAMPLE_X] <= absx.maxValue + && absm.mCurData[MotionEvent.SAMPLE_Y] >= absy.minValue + && absm.mCurData[MotionEvent.SAMPLE_Y] <= absy.maxValue) { + if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Input (" + + absm.mCurData[MotionEvent.SAMPLE_X] + + "," + absm.mCurData[MotionEvent.SAMPLE_Y] + + ") inside of display"); return null; } for (int i=0; i