blob: 3b9c70e2dcea0cd846ea5e0cfd9a9c1f2ff11cca [file] [log] [blame]
Jeff Brownfd0358292010-06-30 16:10:35 -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
17#ifndef _UI_INPUT_DEVICE_H
18#define _UI_INPUT_DEVICE_H
19
20#include <ui/EventHub.h>
21#include <ui/Input.h>
22#include <utils/KeyedVector.h>
23#include <utils/threads.h>
24#include <utils/Timers.h>
25#include <utils/RefBase.h>
26#include <utils/String8.h>
27#include <utils/BitSet.h>
28
29#include <stddef.h>
30#include <unistd.h>
31
32/* Maximum pointer id value supported.
33 * (This is limited by our use of BitSet32 to track pointer assignments.) */
34#define MAX_POINTER_ID 31
35
36/* Maximum number of historical samples to average. */
37#define AVERAGING_HISTORY_SIZE 5
38
39
40namespace android {
41
42extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
43extern int32_t rotateKeyCode(int32_t keyCode, int32_t orientation);
44
Jeff Brownc5ed5912010-07-14 18:48:53 -070045
Jeff Brownfd0358292010-06-30 16:10:35 -070046/*
47 * An input device structure tracks the state of a single input device.
48 *
49 * This structure is only used by ReaderThread and is not intended to be shared with
50 * DispatcherThread (because that would require locking). This works out fine because
51 * DispatcherThread is only interested in cooked event data anyways and does not need
52 * any of the low-level data from InputDevice.
53 */
54struct InputDevice {
55 struct AbsoluteAxisInfo {
56 bool valid; // set to true if axis parameters are known, false otherwise
57
58 int32_t minValue; // minimum value
59 int32_t maxValue; // maximum value
60 int32_t range; // range of values, equal to maxValue - minValue
61 int32_t flat; // center flat position, eg. flat == 8 means center is between -8 and 8
62 int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
63 };
64
65 struct VirtualKey {
66 int32_t keyCode;
67 int32_t scanCode;
68 uint32_t flags;
69
70 // computed hit box, specified in touch screen coords based on known display size
71 int32_t hitLeft;
72 int32_t hitTop;
73 int32_t hitRight;
74 int32_t hitBottom;
75
76 inline bool isHit(int32_t x, int32_t y) const {
77 return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
78 }
79 };
80
81 struct KeyboardState {
82 struct Current {
83 int32_t metaState;
84 nsecs_t downTime; // time of most recent key down
85 } current;
86
87 void reset();
88 };
89
90 struct TrackballState {
91 struct Accumulator {
92 enum {
93 FIELD_BTN_MOUSE = 1,
94 FIELD_REL_X = 2,
95 FIELD_REL_Y = 4
96 };
97
98 uint32_t fields;
99
100 bool btnMouse;
101 int32_t relX;
102 int32_t relY;
103
104 inline void clear() {
105 fields = 0;
106 }
107
108 inline bool isDirty() {
109 return fields != 0;
110 }
111 } accumulator;
112
113 struct Current {
114 bool down;
115 nsecs_t downTime;
116 } current;
117
118 struct Precalculated {
119 float xScale;
120 float yScale;
121 float xPrecision;
122 float yPrecision;
123 } precalculated;
124
125 void reset();
126 };
127
128 struct SingleTouchScreenState {
129 struct Accumulator {
130 enum {
131 FIELD_BTN_TOUCH = 1,
132 FIELD_ABS_X = 2,
133 FIELD_ABS_Y = 4,
134 FIELD_ABS_PRESSURE = 8,
135 FIELD_ABS_TOOL_WIDTH = 16
136 };
137
138 uint32_t fields;
139
140 bool btnTouch;
141 int32_t absX;
142 int32_t absY;
143 int32_t absPressure;
144 int32_t absToolWidth;
145
146 inline void clear() {
147 fields = 0;
148 }
149
150 inline bool isDirty() {
151 return fields != 0;
152 }
153 } accumulator;
154
155 struct Current {
156 bool down;
157 int32_t x;
158 int32_t y;
159 int32_t pressure;
160 int32_t size;
161 } current;
162
163 void reset();
164 };
165
166 struct MultiTouchScreenState {
167 struct Accumulator {
168 enum {
169 FIELD_ABS_MT_POSITION_X = 1,
170 FIELD_ABS_MT_POSITION_Y = 2,
171 FIELD_ABS_MT_TOUCH_MAJOR = 4,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700172 FIELD_ABS_MT_TOUCH_MINOR = 8,
173 FIELD_ABS_MT_WIDTH_MAJOR = 16,
174 FIELD_ABS_MT_WIDTH_MINOR = 32,
175 FIELD_ABS_MT_ORIENTATION = 64,
176 FIELD_ABS_MT_TRACKING_ID = 128
Jeff Brownfd0358292010-06-30 16:10:35 -0700177 };
178
179 uint32_t pointerCount;
180 struct Pointer {
181 uint32_t fields;
182
183 int32_t absMTPositionX;
184 int32_t absMTPositionY;
185 int32_t absMTTouchMajor;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700186 int32_t absMTTouchMinor;
Jeff Brownfd0358292010-06-30 16:10:35 -0700187 int32_t absMTWidthMajor;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700188 int32_t absMTWidthMinor;
189 int32_t absMTOrientation;
Jeff Brownfd0358292010-06-30 16:10:35 -0700190 int32_t absMTTrackingId;
191
192 inline void clear() {
193 fields = 0;
194 }
195 } pointers[MAX_POINTERS + 1]; // + 1 to remove the need for extra range checks
196
197 inline void clear() {
198 pointerCount = 0;
199 pointers[0].clear();
200 }
201
202 inline bool isDirty() {
203 return pointerCount != 0;
204 }
205 } accumulator;
206
207 void reset();
208 };
209
210 struct PointerData {
211 uint32_t id;
212 int32_t x;
213 int32_t y;
214 int32_t pressure;
215 int32_t size;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700216 int32_t touchMajor;
217 int32_t touchMinor;
218 int32_t toolMajor;
219 int32_t toolMinor;
220 int32_t orientation;
Jeff Brownfd0358292010-06-30 16:10:35 -0700221 };
222
223 struct TouchData {
224 uint32_t pointerCount;
225 PointerData pointers[MAX_POINTERS];
226 BitSet32 idBits;
227 uint32_t idToIndex[MAX_POINTER_ID + 1];
228
229 void copyFrom(const TouchData& other);
230
231 inline void clear() {
232 pointerCount = 0;
233 idBits.clear();
234 }
235 };
236
237 // common state used for both single-touch and multi-touch screens after the initial
238 // touch decoding has been performed
239 struct TouchScreenState {
240 Vector<VirtualKey> virtualKeys;
241
242 struct Parameters {
243 bool useBadTouchFilter;
244 bool useJumpyTouchFilter;
245 bool useAveragingTouchFilter;
246
247 AbsoluteAxisInfo xAxis;
248 AbsoluteAxisInfo yAxis;
249 AbsoluteAxisInfo pressureAxis;
250 AbsoluteAxisInfo sizeAxis;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700251 AbsoluteAxisInfo orientationAxis;
Jeff Brownfd0358292010-06-30 16:10:35 -0700252 } parameters;
253
254 // The touch data of the current sample being processed.
255 TouchData currentTouch;
256
257 // The touch data of the previous sample that was processed. This is updated
258 // incrementally while the current sample is being processed.
259 TouchData lastTouch;
260
261 // The time the primary pointer last went down.
262 nsecs_t downTime;
263
264 struct CurrentVirtualKeyState {
265 enum Status {
266 STATUS_UP,
267 STATUS_DOWN,
268 STATUS_CANCELED
269 };
270
271 Status status;
272 nsecs_t downTime;
273 int32_t keyCode;
274 int32_t scanCode;
275 } currentVirtualKey;
276
277 struct AveragingTouchFilterState {
278 // Individual history tracks are stored by pointer id
279 uint32_t historyStart[MAX_POINTERS];
280 uint32_t historyEnd[MAX_POINTERS];
281 struct {
282 struct {
283 int32_t x;
284 int32_t y;
285 int32_t pressure;
286 } pointers[MAX_POINTERS];
287 } historyData[AVERAGING_HISTORY_SIZE];
288 } averagingTouchFilter;
289
290 struct JumpTouchFilterState {
291 int32_t jumpyPointsDropped;
292 } jumpyTouchFilter;
293
294 struct Precalculated {
295 int32_t xOrigin;
296 float xScale;
297
298 int32_t yOrigin;
299 float yScale;
300
301 int32_t pressureOrigin;
302 float pressureScale;
303
304 int32_t sizeOrigin;
305 float sizeScale;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700306
307 float orientationScale;
Jeff Brownfd0358292010-06-30 16:10:35 -0700308 } precalculated;
309
310 void reset();
311
312 bool applyBadTouchFilter();
313 bool applyJumpyTouchFilter();
314 void applyAveragingTouchFilter();
315 void calculatePointerIds();
316
317 bool isPointInsideDisplay(int32_t x, int32_t y) const;
318 const InputDevice::VirtualKey* findVirtualKeyHit() const;
319 };
320
321 InputDevice(int32_t id, uint32_t classes, String8 name);
322
323 int32_t id;
324 uint32_t classes;
325 String8 name;
326 bool ignored;
327
328 KeyboardState keyboard;
329 TrackballState trackball;
330 TouchScreenState touchScreen;
331 union {
332 SingleTouchScreenState singleTouchScreen;
333 MultiTouchScreenState multiTouchScreen;
334 };
335
336 void reset();
337
338 inline bool isKeyboard() const { return classes & INPUT_DEVICE_CLASS_KEYBOARD; }
339 inline bool isAlphaKey() const { return classes & INPUT_DEVICE_CLASS_ALPHAKEY; }
340 inline bool isTrackball() const { return classes & INPUT_DEVICE_CLASS_TRACKBALL; }
341 inline bool isDPad() const { return classes & INPUT_DEVICE_CLASS_DPAD; }
342 inline bool isSingleTouchScreen() const { return (classes
343 & (INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT))
344 == INPUT_DEVICE_CLASS_TOUCHSCREEN; }
345 inline bool isMultiTouchScreen() const { return classes
346 & INPUT_DEVICE_CLASS_TOUCHSCREEN_MT; }
347 inline bool isTouchScreen() const { return classes
348 & (INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT); }
349};
350
351} // namespace android
352
353#endif // _UI_INPUT_DEVICE_H