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