blob: 40a6c47d031fc973dcbef4b88736264e8c176223 [file] [log] [blame]
Jeff Brown9f25b7f2012-04-10 14:30:49 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070017#define LOG_TAG "Input"
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070018//#define LOG_NDEBUG 0
19
Jeff Brown91c69ab2011-02-14 17:03:18 -080020#include <math.h>
Jeff Brown19c97d462011-06-01 12:33:19 -070021#include <limits.h>
Jeff Brown91c69ab2011-02-14 17:03:18 -080022
Jeff Brown8a90e6e2012-05-11 12:24:35 -070023#include <androidfw/Input.h>
24
Jeff Brown91c69ab2011-02-14 17:03:18 -080025#ifdef HAVE_ANDROID_OS
26#include <binder/Parcel.h>
27
28#include "SkPoint.h"
29#include "SkMatrix.h"
30#include "SkScalar.h"
31#endif
32
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070033namespace android {
34
Jeff Brown47e6b1b2010-11-29 17:37:49 -080035// --- InputEvent ---
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070036
Jeff Brownc5ed5912010-07-14 18:48:53 -070037void InputEvent::initialize(int32_t deviceId, int32_t source) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070038 mDeviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -070039 mSource = source;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070040}
41
Dianne Hackborn2c6081c2010-07-15 17:44:53 -070042void InputEvent::initialize(const InputEvent& from) {
43 mDeviceId = from.mDeviceId;
44 mSource = from.mSource;
45}
46
Jeff Brown47e6b1b2010-11-29 17:37:49 -080047// --- KeyEvent ---
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070048
Dianne Hackborn3c80a4a2010-06-29 19:20:40 -070049bool KeyEvent::hasDefaultAction(int32_t keyCode) {
50 switch (keyCode) {
Jeff Brownfd0358292010-06-30 16:10:35 -070051 case AKEYCODE_HOME:
52 case AKEYCODE_BACK:
53 case AKEYCODE_CALL:
54 case AKEYCODE_ENDCALL:
55 case AKEYCODE_VOLUME_UP:
56 case AKEYCODE_VOLUME_DOWN:
Jeff Brownb0418da2010-11-01 15:24:01 -070057 case AKEYCODE_VOLUME_MUTE:
Jeff Brownfd0358292010-06-30 16:10:35 -070058 case AKEYCODE_POWER:
59 case AKEYCODE_CAMERA:
60 case AKEYCODE_HEADSETHOOK:
61 case AKEYCODE_MENU:
62 case AKEYCODE_NOTIFICATION:
63 case AKEYCODE_FOCUS:
64 case AKEYCODE_SEARCH:
Jeff Brownb0418da2010-11-01 15:24:01 -070065 case AKEYCODE_MEDIA_PLAY:
66 case AKEYCODE_MEDIA_PAUSE:
Jeff Brownfd0358292010-06-30 16:10:35 -070067 case AKEYCODE_MEDIA_PLAY_PAUSE:
68 case AKEYCODE_MEDIA_STOP:
69 case AKEYCODE_MEDIA_NEXT:
70 case AKEYCODE_MEDIA_PREVIOUS:
71 case AKEYCODE_MEDIA_REWIND:
Jeff Brownb0418da2010-11-01 15:24:01 -070072 case AKEYCODE_MEDIA_RECORD:
Jeff Brownfd0358292010-06-30 16:10:35 -070073 case AKEYCODE_MEDIA_FAST_FORWARD:
74 case AKEYCODE_MUTE:
Dianne Hackborn3c80a4a2010-06-29 19:20:40 -070075 return true;
76 }
77
78 return false;
79}
80
81bool KeyEvent::hasDefaultAction() const {
82 return hasDefaultAction(getKeyCode());
83}
84
85bool KeyEvent::isSystemKey(int32_t keyCode) {
86 switch (keyCode) {
Jeff Brownfd0358292010-06-30 16:10:35 -070087 case AKEYCODE_MENU:
88 case AKEYCODE_SOFT_RIGHT:
89 case AKEYCODE_HOME:
90 case AKEYCODE_BACK:
91 case AKEYCODE_CALL:
92 case AKEYCODE_ENDCALL:
93 case AKEYCODE_VOLUME_UP:
94 case AKEYCODE_VOLUME_DOWN:
Jeff Brownb0418da2010-11-01 15:24:01 -070095 case AKEYCODE_VOLUME_MUTE:
Jeff Brownfd0358292010-06-30 16:10:35 -070096 case AKEYCODE_MUTE:
97 case AKEYCODE_POWER:
98 case AKEYCODE_HEADSETHOOK:
Jeff Brownb0418da2010-11-01 15:24:01 -070099 case AKEYCODE_MEDIA_PLAY:
100 case AKEYCODE_MEDIA_PAUSE:
Jeff Brownfd0358292010-06-30 16:10:35 -0700101 case AKEYCODE_MEDIA_PLAY_PAUSE:
102 case AKEYCODE_MEDIA_STOP:
103 case AKEYCODE_MEDIA_NEXT:
104 case AKEYCODE_MEDIA_PREVIOUS:
105 case AKEYCODE_MEDIA_REWIND:
Jeff Brownb0418da2010-11-01 15:24:01 -0700106 case AKEYCODE_MEDIA_RECORD:
Jeff Brownfd0358292010-06-30 16:10:35 -0700107 case AKEYCODE_MEDIA_FAST_FORWARD:
108 case AKEYCODE_CAMERA:
109 case AKEYCODE_FOCUS:
110 case AKEYCODE_SEARCH:
Dianne Hackborn3c80a4a2010-06-29 19:20:40 -0700111 return true;
112 }
113
114 return false;
115}
116
117bool KeyEvent::isSystemKey() const {
118 return isSystemKey(getKeyCode());
119}
120
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700121void KeyEvent::initialize(
122 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700123 int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700124 int32_t action,
125 int32_t flags,
126 int32_t keyCode,
127 int32_t scanCode,
128 int32_t metaState,
129 int32_t repeatCount,
130 nsecs_t downTime,
131 nsecs_t eventTime) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700132 InputEvent::initialize(deviceId, source);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700133 mAction = action;
134 mFlags = flags;
135 mKeyCode = keyCode;
136 mScanCode = scanCode;
137 mMetaState = metaState;
138 mRepeatCount = repeatCount;
139 mDownTime = downTime;
140 mEventTime = eventTime;
141}
142
Dianne Hackborn2c6081c2010-07-15 17:44:53 -0700143void KeyEvent::initialize(const KeyEvent& from) {
144 InputEvent::initialize(from);
145 mAction = from.mAction;
146 mFlags = from.mFlags;
147 mKeyCode = from.mKeyCode;
148 mScanCode = from.mScanCode;
149 mMetaState = from.mMetaState;
150 mRepeatCount = from.mRepeatCount;
151 mDownTime = from.mDownTime;
152 mEventTime = from.mEventTime;
153}
154
Jeff Brown91c69ab2011-02-14 17:03:18 -0800155
156// --- PointerCoords ---
157
Jeff Brown6f2fba42011-02-19 01:08:02 -0800158float PointerCoords::getAxisValue(int32_t axis) const {
159 if (axis < 0 || axis > 63) {
160 return 0;
161 }
162
163 uint64_t axisBit = 1LL << axis;
164 if (!(bits & axisBit)) {
165 return 0;
166 }
167 uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
168 return values[index];
169}
170
171status_t PointerCoords::setAxisValue(int32_t axis, float value) {
172 if (axis < 0 || axis > 63) {
173 return NAME_NOT_FOUND;
174 }
175
176 uint64_t axisBit = 1LL << axis;
177 uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
178 if (!(bits & axisBit)) {
Jeff Brownbe1aa822011-07-27 16:04:54 -0700179 if (value == 0) {
180 return OK; // axes with value 0 do not need to be stored
181 }
Jeff Brown6f2fba42011-02-19 01:08:02 -0800182 uint32_t count = __builtin_popcountll(bits);
183 if (count >= MAX_AXES) {
184 tooManyAxes(axis);
185 return NO_MEMORY;
186 }
187 bits |= axisBit;
188 for (uint32_t i = count; i > index; i--) {
189 values[i] = values[i - 1];
190 }
191 }
192 values[index] = value;
193 return OK;
194}
195
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400196static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
Jeff Brownbe1aa822011-07-27 16:04:54 -0700197 float value = c.getAxisValue(axis);
198 if (value != 0) {
199 c.setAxisValue(axis, value * scaleFactor);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400200 }
201}
202
203void PointerCoords::scale(float scaleFactor) {
204 // No need to scale pressure or size since they are normalized.
205 // No need to scale orientation since it is meaningless to do so.
206 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
207 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
208 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
209 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
210 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
211 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
212}
213
Jeff Brown771526c2012-04-27 15:13:25 -0700214void PointerCoords::lerp(const PointerCoords& a, const PointerCoords& b, float alpha) {
215 bits = 0;
216 for (uint64_t bitsRemaining = a.bits | b.bits; bitsRemaining; ) {
217 int32_t axis = __builtin_ctz(bitsRemaining);
218 uint64_t axisBit = 1LL << axis;
219 bitsRemaining &= ~axisBit;
220 if (a.bits & axisBit) {
221 if (b.bits & axisBit) {
222 float aval = a.getAxisValue(axis);
223 float bval = b.getAxisValue(axis);
224 setAxisValue(axis, aval + alpha * (bval - aval));
225 } else {
226 setAxisValue(axis, a.getAxisValue(axis));
227 }
228 } else {
229 setAxisValue(axis, b.getAxisValue(axis));
230 }
231 }
232}
233
Jeff Brown91c69ab2011-02-14 17:03:18 -0800234#ifdef HAVE_ANDROID_OS
235status_t PointerCoords::readFromParcel(Parcel* parcel) {
Jeff Brown6f2fba42011-02-19 01:08:02 -0800236 bits = parcel->readInt64();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800237
Jeff Brown6f2fba42011-02-19 01:08:02 -0800238 uint32_t count = __builtin_popcountll(bits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800239 if (count > MAX_AXES) {
240 return BAD_VALUE;
241 }
242
243 for (uint32_t i = 0; i < count; i++) {
244 values[i] = parcel->readInt32();
245 }
246 return OK;
247}
248
249status_t PointerCoords::writeToParcel(Parcel* parcel) const {
Jeff Brown6f2fba42011-02-19 01:08:02 -0800250 parcel->writeInt64(bits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800251
Jeff Brown6f2fba42011-02-19 01:08:02 -0800252 uint32_t count = __builtin_popcountll(bits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800253 for (uint32_t i = 0; i < count; i++) {
254 parcel->writeInt32(values[i]);
255 }
256 return OK;
257}
258#endif
259
260void PointerCoords::tooManyAxes(int axis) {
Steve Block8564c8d2012-01-05 23:22:43 +0000261 ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
Jeff Brown91c69ab2011-02-14 17:03:18 -0800262 "cannot contain more than %d axis values.", axis, int(MAX_AXES));
263}
264
Jeff Brownace13b12011-03-09 17:39:48 -0800265bool PointerCoords::operator==(const PointerCoords& other) const {
266 if (bits != other.bits) {
267 return false;
268 }
269 uint32_t count = __builtin_popcountll(bits);
270 for (uint32_t i = 0; i < count; i++) {
271 if (values[i] != other.values[i]) {
272 return false;
273 }
274 }
275 return true;
276}
277
278void PointerCoords::copyFrom(const PointerCoords& other) {
279 bits = other.bits;
280 uint32_t count = __builtin_popcountll(bits);
281 for (uint32_t i = 0; i < count; i++) {
282 values[i] = other.values[i];
283 }
284}
285
Jeff Brown91c69ab2011-02-14 17:03:18 -0800286
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700287// --- PointerProperties ---
288
289bool PointerProperties::operator==(const PointerProperties& other) const {
290 return id == other.id
291 && toolType == other.toolType;
292}
293
294void PointerProperties::copyFrom(const PointerProperties& other) {
295 id = other.id;
296 toolType = other.toolType;
297}
298
299
Jeff Brown47e6b1b2010-11-29 17:37:49 -0800300// --- MotionEvent ---
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700301
302void MotionEvent::initialize(
303 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700304 int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700305 int32_t action,
Jeff Brown85a31762010-09-01 17:01:00 -0700306 int32_t flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700307 int32_t edgeFlags,
308 int32_t metaState,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700309 int32_t buttonState,
Jeff Brown5c225b12010-06-16 01:53:36 -0700310 float xOffset,
311 float yOffset,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700312 float xPrecision,
313 float yPrecision,
314 nsecs_t downTime,
315 nsecs_t eventTime,
316 size_t pointerCount,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700317 const PointerProperties* pointerProperties,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700318 const PointerCoords* pointerCoords) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700319 InputEvent::initialize(deviceId, source);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700320 mAction = action;
Jeff Brown85a31762010-09-01 17:01:00 -0700321 mFlags = flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700322 mEdgeFlags = edgeFlags;
323 mMetaState = metaState;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700324 mButtonState = buttonState;
Jeff Brown5c225b12010-06-16 01:53:36 -0700325 mXOffset = xOffset;
326 mYOffset = yOffset;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700327 mXPrecision = xPrecision;
328 mYPrecision = yPrecision;
329 mDownTime = downTime;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700330 mPointerProperties.clear();
331 mPointerProperties.appendArray(pointerProperties, pointerCount);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700332 mSampleEventTimes.clear();
333 mSamplePointerCoords.clear();
334 addSample(eventTime, pointerCoords);
335}
336
Jeff Brown91c69ab2011-02-14 17:03:18 -0800337void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
338 InputEvent::initialize(other->mDeviceId, other->mSource);
339 mAction = other->mAction;
340 mFlags = other->mFlags;
341 mEdgeFlags = other->mEdgeFlags;
342 mMetaState = other->mMetaState;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700343 mButtonState = other->mButtonState;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800344 mXOffset = other->mXOffset;
345 mYOffset = other->mYOffset;
346 mXPrecision = other->mXPrecision;
347 mYPrecision = other->mYPrecision;
348 mDownTime = other->mDownTime;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700349 mPointerProperties = other->mPointerProperties;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800350
351 if (keepHistory) {
352 mSampleEventTimes = other->mSampleEventTimes;
353 mSamplePointerCoords = other->mSamplePointerCoords;
354 } else {
355 mSampleEventTimes.clear();
356 mSampleEventTimes.push(other->getEventTime());
357 mSamplePointerCoords.clear();
358 size_t pointerCount = other->getPointerCount();
359 size_t historySize = other->getHistorySize();
360 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
361 + (historySize * pointerCount), pointerCount);
362 }
363}
364
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700365void MotionEvent::addSample(
366 int64_t eventTime,
367 const PointerCoords* pointerCoords) {
368 mSampleEventTimes.push(eventTime);
369 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
370}
371
Jeff Brown91c69ab2011-02-14 17:03:18 -0800372const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
373 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
374}
375
376float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
377 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
378}
379
380float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
381 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
382 switch (axis) {
Jeff Brownebbd5d12011-02-17 13:01:34 -0800383 case AMOTION_EVENT_AXIS_X:
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400384 return value + mXOffset;
Jeff Brownebbd5d12011-02-17 13:01:34 -0800385 case AMOTION_EVENT_AXIS_Y:
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400386 return value + mYOffset;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800387 }
388 return value;
389}
390
391const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
392 size_t pointerIndex, size_t historicalIndex) const {
393 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
394}
395
396float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
397 size_t historicalIndex) const {
398 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
399}
400
401float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
402 size_t historicalIndex) const {
403 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
404 switch (axis) {
Jeff Brownebbd5d12011-02-17 13:01:34 -0800405 case AMOTION_EVENT_AXIS_X:
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400406 return value + mXOffset;
Jeff Brownebbd5d12011-02-17 13:01:34 -0800407 case AMOTION_EVENT_AXIS_Y:
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400408 return value + mYOffset;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800409 }
410 return value;
411}
412
Jeff Brown2ed24622011-03-14 19:39:54 -0700413ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700414 size_t pointerCount = mPointerProperties.size();
Jeff Brown2ed24622011-03-14 19:39:54 -0700415 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700416 if (mPointerProperties.itemAt(i).id == pointerId) {
Jeff Brown2ed24622011-03-14 19:39:54 -0700417 return i;
418 }
419 }
420 return -1;
421}
422
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700423void MotionEvent::offsetLocation(float xOffset, float yOffset) {
Jeff Brown5c225b12010-06-16 01:53:36 -0700424 mXOffset += xOffset;
425 mYOffset += yOffset;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700426}
427
Jeff Brown91c69ab2011-02-14 17:03:18 -0800428void MotionEvent::scale(float scaleFactor) {
429 mXOffset *= scaleFactor;
430 mYOffset *= scaleFactor;
431 mXPrecision *= scaleFactor;
432 mYPrecision *= scaleFactor;
433
434 size_t numSamples = mSamplePointerCoords.size();
435 for (size_t i = 0; i < numSamples; i++) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400436 mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800437 }
438}
439
440#ifdef HAVE_ANDROID_OS
441static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
442 // Construct and transform a vector oriented at the specified clockwise angle from vertical.
443 // Coordinate system: down is increasing Y, right is increasing X.
444 SkPoint vector;
445 vector.fX = SkFloatToScalar(sinf(angleRadians));
446 vector.fY = SkFloatToScalar(-cosf(angleRadians));
447 matrix->mapVectors(& vector, 1);
448
449 // Derive the transformed vector's clockwise angle from vertical.
450 float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
451 if (result < - M_PI_2) {
452 result += M_PI;
453 } else if (result > M_PI_2) {
454 result -= M_PI;
455 }
456 return result;
457}
458
459void MotionEvent::transform(const SkMatrix* matrix) {
460 float oldXOffset = mXOffset;
461 float oldYOffset = mYOffset;
462
463 // The tricky part of this implementation is to preserve the value of
464 // rawX and rawY. So we apply the transformation to the first point
465 // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
466 SkPoint point;
467 float rawX = getRawX(0);
468 float rawY = getRawY(0);
469 matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
470 & point);
471 float newX = SkScalarToFloat(point.fX);
472 float newY = SkScalarToFloat(point.fY);
473 float newXOffset = newX - rawX;
474 float newYOffset = newY - rawY;
475
476 mXOffset = newXOffset;
477 mYOffset = newYOffset;
478
479 // Apply the transformation to all samples.
480 size_t numSamples = mSamplePointerCoords.size();
481 for (size_t i = 0; i < numSamples; i++) {
482 PointerCoords& c = mSamplePointerCoords.editItemAt(i);
Jeff Brownbe1aa822011-07-27 16:04:54 -0700483 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
484 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
485 matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
486 c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
487 c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800488
Jeff Brownbe1aa822011-07-27 16:04:54 -0700489 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
490 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800491 }
492}
493
494status_t MotionEvent::readFromParcel(Parcel* parcel) {
495 size_t pointerCount = parcel->readInt32();
496 size_t sampleCount = parcel->readInt32();
497 if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
498 return BAD_VALUE;
499 }
500
501 mDeviceId = parcel->readInt32();
502 mSource = parcel->readInt32();
503 mAction = parcel->readInt32();
504 mFlags = parcel->readInt32();
505 mEdgeFlags = parcel->readInt32();
506 mMetaState = parcel->readInt32();
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700507 mButtonState = parcel->readInt32();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800508 mXOffset = parcel->readFloat();
509 mYOffset = parcel->readFloat();
510 mXPrecision = parcel->readFloat();
511 mYPrecision = parcel->readFloat();
512 mDownTime = parcel->readInt64();
513
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700514 mPointerProperties.clear();
515 mPointerProperties.setCapacity(pointerCount);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800516 mSampleEventTimes.clear();
517 mSampleEventTimes.setCapacity(sampleCount);
518 mSamplePointerCoords.clear();
519 mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
520
521 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700522 mPointerProperties.push();
523 PointerProperties& properties = mPointerProperties.editTop();
524 properties.id = parcel->readInt32();
525 properties.toolType = parcel->readInt32();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800526 }
527
528 while (sampleCount-- > 0) {
529 mSampleEventTimes.push(parcel->readInt64());
530 for (size_t i = 0; i < pointerCount; i++) {
531 mSamplePointerCoords.push();
532 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800533 if (status) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800534 return status;
535 }
536 }
537 }
538 return OK;
539}
540
541status_t MotionEvent::writeToParcel(Parcel* parcel) const {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700542 size_t pointerCount = mPointerProperties.size();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800543 size_t sampleCount = mSampleEventTimes.size();
544
545 parcel->writeInt32(pointerCount);
546 parcel->writeInt32(sampleCount);
547
548 parcel->writeInt32(mDeviceId);
549 parcel->writeInt32(mSource);
550 parcel->writeInt32(mAction);
551 parcel->writeInt32(mFlags);
552 parcel->writeInt32(mEdgeFlags);
553 parcel->writeInt32(mMetaState);
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700554 parcel->writeInt32(mButtonState);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800555 parcel->writeFloat(mXOffset);
556 parcel->writeFloat(mYOffset);
557 parcel->writeFloat(mXPrecision);
558 parcel->writeFloat(mYPrecision);
559 parcel->writeInt64(mDownTime);
560
561 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700562 const PointerProperties& properties = mPointerProperties.itemAt(i);
563 parcel->writeInt32(properties.id);
564 parcel->writeInt32(properties.toolType);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800565 }
566
567 const PointerCoords* pc = mSamplePointerCoords.array();
568 for (size_t h = 0; h < sampleCount; h++) {
569 parcel->writeInt64(mSampleEventTimes.itemAt(h));
570 for (size_t i = 0; i < pointerCount; i++) {
571 status_t status = (pc++)->writeToParcel(parcel);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800572 if (status) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800573 return status;
574 }
575 }
576 }
577 return OK;
578}
579#endif
580
Jeff Brown56194eb2011-03-02 19:23:13 -0800581bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
582 if (source & AINPUT_SOURCE_CLASS_POINTER) {
583 // Specifically excludes HOVER_MOVE and SCROLL.
584 switch (action & AMOTION_EVENT_ACTION_MASK) {
585 case AMOTION_EVENT_ACTION_DOWN:
586 case AMOTION_EVENT_ACTION_MOVE:
587 case AMOTION_EVENT_ACTION_UP:
588 case AMOTION_EVENT_ACTION_POINTER_DOWN:
589 case AMOTION_EVENT_ACTION_POINTER_UP:
590 case AMOTION_EVENT_ACTION_CANCEL:
591 case AMOTION_EVENT_ACTION_OUTSIDE:
592 return true;
593 }
594 }
595 return false;
596}
597
Jeff Brown91c69ab2011-02-14 17:03:18 -0800598
Jeff Brown2b6c32c2012-03-13 15:00:09 -0700599// --- PooledInputEventFactory ---
600
601PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
602 mMaxPoolSize(maxPoolSize) {
603}
604
605PooledInputEventFactory::~PooledInputEventFactory() {
606 for (size_t i = 0; i < mKeyEventPool.size(); i++) {
607 delete mKeyEventPool.itemAt(i);
608 }
609 for (size_t i = 0; i < mMotionEventPool.size(); i++) {
610 delete mMotionEventPool.itemAt(i);
611 }
612}
613
614KeyEvent* PooledInputEventFactory::createKeyEvent() {
615 if (!mKeyEventPool.isEmpty()) {
616 KeyEvent* event = mKeyEventPool.top();
617 mKeyEventPool.pop();
618 return event;
619 }
620 return new KeyEvent();
621}
622
623MotionEvent* PooledInputEventFactory::createMotionEvent() {
624 if (!mMotionEventPool.isEmpty()) {
625 MotionEvent* event = mMotionEventPool.top();
626 mMotionEventPool.pop();
627 return event;
628 }
629 return new MotionEvent();
630}
631
632void PooledInputEventFactory::recycle(InputEvent* event) {
633 switch (event->getType()) {
634 case AINPUT_EVENT_TYPE_KEY:
635 if (mKeyEventPool.size() < mMaxPoolSize) {
636 mKeyEventPool.push(static_cast<KeyEvent*>(event));
637 return;
638 }
639 break;
640 case AINPUT_EVENT_TYPE_MOTION:
641 if (mMotionEventPool.size() < mMaxPoolSize) {
642 mMotionEventPool.push(static_cast<MotionEvent*>(event));
643 return;
644 }
645 break;
646 }
647 delete event;
648}
649
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700650} // namespace android