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