1 // Copyright 2012 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "include/gestures.h"
6
7 #include <cstring>
8 #include <sys/time.h>
9
10 #include "include/accel_filter_interpreter.h"
11 #include "include/box_filter_interpreter.h"
12 #include "include/click_wiggle_filter_interpreter.h"
13 #include "include/finger_merge_filter_interpreter.h"
14 #include "include/finger_metrics.h"
15 #include "include/fling_stop_filter_interpreter.h"
16 #include "include/haptic_button_generator_filter_interpreter.h"
17 #include "include/iir_filter_interpreter.h"
18 #include "include/immediate_interpreter.h"
19 #include "include/integral_gesture_filter_interpreter.h"
20 #include "include/logging.h"
21 #include "include/logging_filter_interpreter.h"
22 #include "include/lookahead_filter_interpreter.h"
23 #include "include/metrics_filter_interpreter.h"
24 #include "include/mouse_interpreter.h"
25 #include "include/multitouch_mouse_interpreter.h"
26 #include "include/non_linearity_filter_interpreter.h"
27 #include "include/palm_classifying_filter_interpreter.h"
28 #include "include/prop_registry.h"
29 #include "include/scaling_filter_interpreter.h"
30 #include "include/sensor_jump_filter_interpreter.h"
31 #include "include/split_correcting_filter_interpreter.h"
32 #include "include/stationary_wiggle_filter_interpreter.h"
33 #include "include/string_util.h"
34 #include "include/stuck_button_inhibitor_filter_interpreter.h"
35 #include "include/t5r2_correcting_filter_interpreter.h"
36 #include "include/timestamp_filter_interpreter.h"
37 #include "include/trace_marker.h"
38 #include "include/tracer.h"
39 #include "include/trend_classifying_filter_interpreter.h"
40 #include "include/util.h"
41
42 using std::string;
43 using std::min;
44 using gestures::StringPrintf;
45 using gestures::StartsWithASCII;
46
47 // C API:
48
49 static const int kMinSupportedVersion = 1;
50 static const int kMaxSupportedVersion = 1;
51
StimeFromTimeval(const struct timeval * tv)52 stime_t StimeFromTimeval(const struct timeval* tv) {
53 return static_cast<stime_t>(tv->tv_sec) +
54 static_cast<stime_t>(tv->tv_usec) / 1000000.0;
55 }
56
StimeFromTimespec(const struct timespec * ts)57 stime_t StimeFromTimespec(const struct timespec* ts) {
58 return static_cast<stime_t>(ts->tv_sec) +
59 static_cast<stime_t>(ts->tv_nsec) / 1000000000.0;
60 }
61
String() const62 std::string HardwareProperties::String() const {
63 return StringPrintf("%f, // left edge\n"
64 "%f, // top edge\n"
65 "%f, // right edge\n"
66 "%f, // bottom edge\n"
67 "%f, // x pixels/TP width\n"
68 "%f, // y pixels/TP height\n"
69 "%f, // x screen DPI\n"
70 "%f, // y screen DPI\n"
71 "%f, // orientation minimum\n"
72 "%f, // orientation maximum\n"
73 "%u, // max fingers\n"
74 "%u, // max touch\n"
75 "%u, // t5r2\n"
76 "%u, // semi-mt\n"
77 "%u // is button pad\n",
78 left, top, right, bottom,
79 res_x,
80 res_y,
81 screen_x_dpi,
82 screen_y_dpi,
83 orientation_minimum,
84 orientation_maximum,
85 max_finger_cnt,
86 max_touch_cnt,
87 supports_t5r2,
88 support_semi_mt,
89 is_button_pad);
90 }
91
92 namespace {
NameForFingerStateFlag(unsigned flag)93 string NameForFingerStateFlag(unsigned flag) {
94 #define CASERET(name) \
95 case name: return #name
96 switch (flag) {
97 CASERET(GESTURES_FINGER_WARP_X_NON_MOVE);
98 CASERET(GESTURES_FINGER_WARP_Y_NON_MOVE);
99 CASERET(GESTURES_FINGER_NO_TAP);
100 CASERET(GESTURES_FINGER_POSSIBLE_PALM);
101 CASERET(GESTURES_FINGER_PALM);
102 CASERET(GESTURES_FINGER_WARP_X_MOVE);
103 CASERET(GESTURES_FINGER_WARP_Y_MOVE);
104 CASERET(GESTURES_FINGER_WARP_X_TAP_MOVE);
105 CASERET(GESTURES_FINGER_WARP_Y_TAP_MOVE);
106 CASERET(GESTURES_FINGER_MERGE);
107 CASERET(GESTURES_FINGER_TREND_INC_X);
108 CASERET(GESTURES_FINGER_TREND_DEC_X);
109 CASERET(GESTURES_FINGER_TREND_INC_Y);
110 CASERET(GESTURES_FINGER_TREND_DEC_Y);
111 CASERET(GESTURES_FINGER_TREND_INC_PRESSURE);
112 CASERET(GESTURES_FINGER_TREND_DEC_PRESSURE);
113 CASERET(GESTURES_FINGER_TREND_INC_TOUCH_MAJOR);
114 CASERET(GESTURES_FINGER_TREND_DEC_TOUCH_MAJOR);
115 CASERET(GESTURES_FINGER_INSTANTANEOUS_MOVING);
116 CASERET(GESTURES_FINGER_WARP_TELEPORTATION);
117 }
118 #undef CASERET
119 return "";
120 }
121 } // namespace {}
122
FlagsString(unsigned flags)123 string FingerState::FlagsString(unsigned flags) {
124 string ret;
125 const char kPipeSeparator[] = " | ";
126 for (unsigned i = 0; i < 8 * sizeof(flags); i++) {
127 const unsigned flag = 1 << i;
128 const string name = NameForFingerStateFlag(flag);
129 if ((flags & flag) && !name.empty()) {
130 ret += kPipeSeparator;
131 ret += name;
132 flags &= ~flag;
133 }
134 }
135 if (flags) {
136 // prepend remaining number
137 ret = StringPrintf("%u%s", flags, ret.c_str());
138 } else if (StartsWithASCII(ret, kPipeSeparator, false)) {
139 // strip extra pipe
140 ret = string(ret.c_str() + strlen(kPipeSeparator));
141 } else {
142 ret = "0";
143 }
144 return ret;
145 }
146
String() const147 string FingerState::String() const {
148 return StringPrintf("{ %f, %f, %f, %f, %f, %f, %f, %f, %d, %s }",
149 touch_major, touch_minor,
150 width_major, width_minor,
151 pressure,
152 orientation,
153 position_x,
154 position_y,
155 tracking_id,
156 FlagsString(flags).c_str());
157 }
158
GetFingerState(short tracking_id)159 FingerState* HardwareState::GetFingerState(short tracking_id) {
160 return const_cast<FingerState*>(
161 const_cast<const HardwareState*>(this)->GetFingerState(tracking_id));
162 }
163
GetFingerState(short tracking_id) const164 const FingerState* HardwareState::GetFingerState(short tracking_id) const {
165 for (short i = 0; i < finger_cnt; i++) {
166 if (fingers[i].tracking_id == tracking_id)
167 return &fingers[i];
168 }
169 return NULL;
170 }
171
String() const172 string HardwareState::String() const {
173 string ret = StringPrintf("{ %f, %d, %d, %d, {",
174 timestamp,
175 buttons_down,
176 finger_cnt,
177 touch_cnt);
178 for (size_t i = 0; i < finger_cnt; i++) {
179 if (i != 0)
180 ret += ",";
181 ret += " ";
182 ret += fingers[i].String();
183 }
184 if (finger_cnt > 0)
185 ret += " ";
186 ret += "} }";
187 return ret;
188 }
189
SameFingersAs(const HardwareState & that) const190 bool HardwareState::SameFingersAs(const HardwareState& that) const {
191 if (finger_cnt != that.finger_cnt || touch_cnt != that.touch_cnt)
192 return false;
193 // For now, require fingers to be in the same slots
194 for (size_t i = 0; i < finger_cnt; i++)
195 if (fingers[i].tracking_id != that.fingers[i].tracking_id)
196 return false;
197 return true;
198 }
199
DeepCopy(const HardwareState & that,unsigned short max_finger_cnt)200 void HardwareState::DeepCopy(const HardwareState& that,
201 unsigned short max_finger_cnt) {
202 timestamp = that.timestamp;
203 buttons_down = that.buttons_down;
204 touch_cnt = that.touch_cnt;
205 finger_cnt = min(that.finger_cnt, max_finger_cnt);
206 memcpy(fingers, that.fingers, finger_cnt * sizeof(FingerState));
207 rel_x = that.rel_x;
208 rel_y = that.rel_y;
209 rel_wheel = that.rel_wheel;
210 rel_wheel_hi_res = that.rel_wheel_hi_res;
211 rel_hwheel = that.rel_hwheel;
212 msc_timestamp = that.msc_timestamp;
213 }
214
String() const215 string Gesture::String() const {
216 switch (type) {
217 case kGestureTypeNull:
218 return "(Gesture type: null)";
219 case kGestureTypeContactInitiated:
220 return StringPrintf("(Gesture type: contactInitiated "
221 "start: %f stop: %f)", start_time, end_time);
222 case kGestureTypeMove:
223 return StringPrintf("(Gesture type: move start: %f stop: %f "
224 "dx: %f dy: %f ordinal_dx: %f ordinal_dy: %f)",
225 start_time, end_time,
226 details.move.dx, details.move.dy,
227 details.move.ordinal_dx, details.move.ordinal_dy);
228 case kGestureTypeScroll:
229 return StringPrintf("(Gesture type: scroll start: %f stop: %f "
230 "dx: %f dy: %f ordinal_dx: %f ordinal_dy: %f)",
231 start_time, end_time,
232 details.scroll.dx, details.scroll.dy,
233 details.scroll.ordinal_dx, details.scroll.ordinal_dy);
234 case kGestureTypeMouseWheel:
235 return StringPrintf("(Gesture type: wheel start: %f stop %f "
236 "dx: %f dy: %f "
237 "tick_120ths_dx: %d tick_120ths_dy: %d)",
238 start_time, end_time,
239 details.wheel.dx, details.wheel.dy,
240 details.wheel.tick_120ths_dx,
241 details.wheel.tick_120ths_dy);
242 case kGestureTypePinch:
243 return StringPrintf("(Gesture type: pinch start: %f stop: %f "
244 "dz: %f ordinal_dz: %f, state: %d)", start_time,
245 end_time, details.pinch.dz, details.pinch.ordinal_dz,
246 details.pinch.zoom_state);
247 case kGestureTypeButtonsChange:
248 return StringPrintf("(Gesture type: buttons start: %f stop: "
249 "%f down: %d up: %d)", start_time, end_time,
250 details.buttons.down, details.buttons.up);
251 case kGestureTypeFling:
252 return StringPrintf("(Gesture type: fling start: %f stop: "
253 "%f vx: %f vy: %f ordinal_dx: %f ordinal_dy: %f "
254 "state: %s)", start_time, end_time,
255 details.fling.vx, details.fling.vy,
256 details.fling.ordinal_vx, details.fling.ordinal_vy,
257 details.fling.fling_state == GESTURES_FLING_START ?
258 "start" : "tapdown");
259 case kGestureTypeSwipe:
260 return StringPrintf("(Gesture type: swipe start: %f stop: %f "
261 "dx: %f dy: %f ordinal_dx: %f ordinal_dy: %f)",
262 start_time, end_time,
263 details.swipe.dx, details.swipe.dy,
264 details.swipe.ordinal_dx, details.swipe.ordinal_dy);
265 case kGestureTypeSwipeLift:
266 return StringPrintf("(Gesture type: swipeLift start: %f stop: %f)",
267 start_time, end_time);
268 case kGestureTypeFourFingerSwipe:
269 return StringPrintf("(Gesture type: fourFingerSwipe start: %f stop: %f "
270 "dx: %f dy: %f ordinal_dx: %f ordinal_dy: %f)",
271 start_time, end_time,
272 details.four_finger_swipe.dx,
273 details.four_finger_swipe.dy,
274 details.four_finger_swipe.ordinal_dx,
275 details.four_finger_swipe.ordinal_dy);
276 case kGestureTypeFourFingerSwipeLift:
277 return StringPrintf("(Gesture type: fourFingerSwipeLift start: %f "
278 "stop: %f)", start_time, end_time);
279 case kGestureTypeMetrics:
280 return StringPrintf("(Gesture type: metrics start: %f stop: %f "
281 "type: %d d1: %f d2: %f)", start_time, end_time,
282 details.metrics.type,
283 details.metrics.data[0], details.metrics.data[1]);
284 }
285 return "(Gesture type: unknown)";
286 }
287
operator ==(const Gesture & that) const288 bool Gesture::operator==(const Gesture& that) const {
289 if (type != that.type)
290 return false;
291 bool times_equal = gestures::DoubleEq(start_time, that.start_time) &&
292 gestures::DoubleEq(end_time, that.end_time);
293 switch (type) {
294 case kGestureTypeNull: // fall through
295 case kGestureTypeContactInitiated:
296 return true;
297 case kGestureTypeMove:
298 return times_equal &&
299 gestures::FloatEq(details.move.dx, that.details.move.dx) &&
300 gestures::FloatEq(details.move.dy, that.details.move.dy);
301 case kGestureTypeScroll:
302 return times_equal &&
303 gestures::FloatEq(details.scroll.dx, that.details.scroll.dx) &&
304 gestures::FloatEq(details.scroll.dy, that.details.scroll.dy);
305 case kGestureTypeMouseWheel:
306 return times_equal &&
307 gestures::FloatEq(details.wheel.dx, that.details.wheel.dx) &&
308 gestures::FloatEq(details.wheel.dy, that.details.wheel.dy) &&
309 details.wheel.tick_120ths_dx == that.details.wheel.tick_120ths_dx &&
310 details.wheel.tick_120ths_dy == that.details.wheel.tick_120ths_dy;
311 case kGestureTypePinch:
312 return times_equal &&
313 gestures::FloatEq(details.pinch.dz, that.details.pinch.dz);
314 case kGestureTypeButtonsChange:
315 return times_equal &&
316 details.buttons.down == that.details.buttons.down &&
317 details.buttons.up == that.details.buttons.up;
318 case kGestureTypeFling:
319 return times_equal &&
320 gestures::FloatEq(details.fling.vx, that.details.fling.vx) &&
321 gestures::FloatEq(details.fling.vy, that.details.fling.vy);
322 case kGestureTypeSwipe:
323 return times_equal &&
324 gestures::FloatEq(details.swipe.dx, that.details.swipe.dx);
325 case kGestureTypeSwipeLift:
326 return times_equal;
327 case kGestureTypeFourFingerSwipe:
328 return times_equal &&
329 gestures::FloatEq(details.four_finger_swipe.dx,
330 that.details.four_finger_swipe.dx);
331 case kGestureTypeFourFingerSwipeLift:
332 return times_equal;
333 case kGestureTypeMetrics:
334 return times_equal &&
335 details.metrics.type == that.details.metrics.type &&
336 gestures::FloatEq(details.metrics.data[0],
337 that.details.metrics.data[0]) &&
338 gestures::FloatEq(details.metrics.data[1],
339 that.details.metrics.data[1]);
340 }
341 return true;
342 }
343
NewGestureInterpreterImpl(int version)344 GestureInterpreter* NewGestureInterpreterImpl(int version) {
345 if (version < kMinSupportedVersion) {
346 Err("Client too old. It's using version %d"
347 ", but library has min supported version %d",
348 version,
349 kMinSupportedVersion);
350 return NULL;
351 }
352 if (version > kMaxSupportedVersion) {
353 Err("Client too new. It's using version %d"
354 ", but library has max supported version %d",
355 version,
356 kMaxSupportedVersion);
357 return NULL;
358 }
359 return new gestures::GestureInterpreter(version);
360 }
361
DeleteGestureInterpreter(GestureInterpreter * obj)362 void DeleteGestureInterpreter(GestureInterpreter* obj) {
363 delete obj;
364 }
365
GestureInterpreterPushHardwareState(GestureInterpreter * obj,struct HardwareState * hwstate)366 void GestureInterpreterPushHardwareState(GestureInterpreter* obj,
367 struct HardwareState* hwstate) {
368 obj->PushHardwareState(hwstate);
369 }
370
GestureInterpreterSetHardwareProperties(GestureInterpreter * obj,const struct HardwareProperties * hwprops)371 void GestureInterpreterSetHardwareProperties(
372 GestureInterpreter* obj,
373 const struct HardwareProperties* hwprops) {
374 obj->SetHardwareProperties(*hwprops);
375 }
376
GestureInterpreterSetCallback(GestureInterpreter * obj,GestureReadyFunction fn,void * user_data)377 void GestureInterpreterSetCallback(GestureInterpreter* obj,
378 GestureReadyFunction fn,
379 void* user_data) {
380 obj->SetCallback(fn, user_data);
381 }
382
GestureInterpreterSetTimerProvider(GestureInterpreter * obj,GesturesTimerProvider * tp,void * data)383 void GestureInterpreterSetTimerProvider(GestureInterpreter* obj,
384 GesturesTimerProvider* tp,
385 void* data) {
386 obj->SetTimerProvider(tp, data);
387 }
388
GestureInterpreterSetPropProvider(GestureInterpreter * obj,GesturesPropProvider * pp,void * data)389 void GestureInterpreterSetPropProvider(GestureInterpreter* obj,
390 GesturesPropProvider* pp,
391 void* data) {
392 obj->SetPropProvider(pp, data);
393 }
394
GestureInterpreterInitialize(GestureInterpreter * obj,enum GestureInterpreterDeviceClass cls)395 void GestureInterpreterInitialize(GestureInterpreter* obj,
396 enum GestureInterpreterDeviceClass cls) {
397 obj->Initialize(cls);
398 }
399
400 // C++ API:
401 namespace gestures {
402 class GestureInterpreterConsumer : public GestureConsumer {
403 public:
GestureInterpreterConsumer(GestureReadyFunction callback,void * callback_data)404 GestureInterpreterConsumer(GestureReadyFunction callback,
405 void* callback_data)
406 : callback_(callback),
407 callback_data_(callback_data) {}
408
SetCallback(GestureReadyFunction callback,void * callback_data)409 void SetCallback(GestureReadyFunction callback, void* callback_data) {
410 callback_ = callback;
411 callback_data_ = callback_data;
412 }
413
ConsumeGesture(const Gesture & gesture)414 void ConsumeGesture(const Gesture& gesture) {
415 AssertWithReturn(gesture.type != kGestureTypeNull);
416 if (callback_)
417 callback_(callback_data_, &gesture);
418 }
419
420 private:
421 GestureReadyFunction callback_;
422 void* callback_data_;
423 };
424 }
425
GestureInterpreter(int version)426 GestureInterpreter::GestureInterpreter(int version)
427 : callback_(NULL),
428 callback_data_(NULL),
429 timer_provider_(NULL),
430 timer_provider_data_(NULL),
431 interpret_timer_(NULL),
432 loggingFilter_(NULL) {
433 prop_reg_.reset(new PropRegistry);
434 tracer_.reset(new Tracer(prop_reg_.get(), TraceMarker::StaticTraceWrite));
435 TraceMarker::CreateTraceMarker();
436 }
437
~GestureInterpreter()438 GestureInterpreter::~GestureInterpreter() {
439 SetTimerProvider(NULL, NULL);
440 SetPropProvider(NULL, NULL);
441 TraceMarker::DeleteTraceMarker();
442 }
443
444 namespace {
InternalTimerCallback(stime_t now,void * callback_data)445 stime_t InternalTimerCallback(stime_t now, void* callback_data) {
446 Log("TimerCallback called");
447 GestureInterpreter* gi = reinterpret_cast<GestureInterpreter*>(callback_data);
448 stime_t next = NO_DEADLINE;
449 gi->TimerCallback(now, &next);
450 return next;
451 }
452 }
453
PushHardwareState(HardwareState * hwstate)454 void GestureInterpreter::PushHardwareState(HardwareState* hwstate) {
455 if (!interpreter_.get()) {
456 Err("Filters are not composed yet!");
457 return;
458 }
459 stime_t timeout = NO_DEADLINE;
460 interpreter_->SyncInterpret(hwstate, &timeout);
461 if (timer_provider_ && interpret_timer_) {
462 if (timeout == NO_DEADLINE) {
463 timer_provider_->cancel_fn(timer_provider_data_, interpret_timer_);
464 } else {
465 timer_provider_->set_fn(timer_provider_data_,
466 interpret_timer_,
467 timeout,
468 InternalTimerCallback,
469 this);
470 Log("Setting timer for %f s out.", timeout);
471 }
472 } else {
473 ErrOnce("No timer provider has been set, so some features won't work.");
474 }
475 }
476
SetHardwareProperties(const HardwareProperties & hwprops)477 void GestureInterpreter::SetHardwareProperties(
478 const HardwareProperties& hwprops) {
479 if (!interpreter_.get()) {
480 Err("Filters are not composed yet!");
481 return;
482 }
483 hwprops_ = hwprops;
484 if (consumer_)
485 interpreter_->Initialize(&hwprops_, NULL, mprops_.get(), consumer_.get());
486 }
487
TimerCallback(stime_t now,stime_t * timeout)488 void GestureInterpreter::TimerCallback(stime_t now, stime_t* timeout) {
489 if (!interpreter_.get()) {
490 Err("Filters are not composed yet!");
491 return;
492 }
493 interpreter_->HandleTimer(now, timeout);
494 }
495
SetTimerProvider(GesturesTimerProvider * tp,void * data)496 void GestureInterpreter::SetTimerProvider(GesturesTimerProvider* tp,
497 void* data) {
498 if (timer_provider_ == tp && timer_provider_data_ == data)
499 return;
500 if (timer_provider_ && interpret_timer_) {
501 timer_provider_->free_fn(timer_provider_data_, interpret_timer_);
502 interpret_timer_ = NULL;
503 }
504 if (interpret_timer_)
505 Log("How was interpret_timer_ not NULL?!");
506 timer_provider_ = tp;
507 timer_provider_data_ = data;
508 if (timer_provider_)
509 interpret_timer_ = timer_provider_->create_fn(timer_provider_data_);
510 }
511
SetPropProvider(GesturesPropProvider * pp,void * data)512 void GestureInterpreter::SetPropProvider(GesturesPropProvider* pp,
513 void* data) {
514 prop_reg_->SetPropProvider(pp, data);
515 }
516
SetCallback(GestureReadyFunction callback,void * client_data)517 void GestureInterpreter::SetCallback(GestureReadyFunction callback,
518 void* client_data) {
519 callback_ = callback;
520 callback_data_ = client_data;
521
522 if (consumer_)
523 consumer_->SetCallback(callback, client_data);
524 }
525
set_callback(GestureReadyFunction callback,void * client_data)526 void GestureInterpreter::set_callback(GestureReadyFunction callback,
527 void* client_data) {
528 SetCallback(callback, client_data);
529 }
530
InitializeTouchpad(void)531 void GestureInterpreter::InitializeTouchpad(void) {
532 if (prop_reg_.get()) {
533 IntProperty stack_version(prop_reg_.get(), "Touchpad Stack Version", 2);
534 if (stack_version.val_ == 2) {
535 InitializeTouchpad2();
536 return;
537 }
538 }
539
540 Interpreter* temp = new ImmediateInterpreter(prop_reg_.get(), tracer_.get());
541 temp = new FlingStopFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
542 GESTURES_DEVCLASS_TOUCHPAD);
543 temp = new ClickWiggleFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
544 temp = new PalmClassifyingFilterInterpreter(prop_reg_.get(), temp,
545 tracer_.get());
546 temp = new IirFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
547 temp = new LookaheadFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
548 temp = new BoxFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
549 temp = new StationaryWiggleFilterInterpreter(prop_reg_.get(), temp,
550 tracer_.get());
551 temp = new SensorJumpFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
552 temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
553 temp = new SplitCorrectingFilterInterpreter(prop_reg_.get(), temp,
554 tracer_.get());
555 temp = new TrendClassifyingFilterInterpreter(prop_reg_.get(), temp,
556 tracer_.get());
557 temp = new MetricsFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
558 GESTURES_DEVCLASS_TOUCHPAD);
559 temp = new ScalingFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
560 GESTURES_DEVCLASS_TOUCHPAD);
561 temp = new FingerMergeFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
562 temp = new StuckButtonInhibitorFilterInterpreter(temp, tracer_.get());
563 temp = new HapticButtonGeneratorFilterInterpreter(prop_reg_.get(), temp,
564 tracer_.get());
565 temp = new T5R2CorrectingFilterInterpreter(prop_reg_.get(), temp,
566 tracer_.get());
567 temp = new NonLinearityFilterInterpreter(prop_reg_.get(), temp,
568 tracer_.get());
569 temp = new TimestampFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
570 temp = loggingFilter_ = new LoggingFilterInterpreter(prop_reg_.get(), temp,
571 tracer_.get());
572 interpreter_.reset(temp);
573 temp = NULL;
574 }
575
InitializeTouchpad2(void)576 void GestureInterpreter::InitializeTouchpad2(void) {
577 Interpreter* temp = new ImmediateInterpreter(prop_reg_.get(), tracer_.get());
578 temp = new FlingStopFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
579 GESTURES_DEVCLASS_TOUCHPAD);
580 temp = new ClickWiggleFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
581 temp = new PalmClassifyingFilterInterpreter(prop_reg_.get(), temp,
582 tracer_.get());
583 temp = new LookaheadFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
584 temp = new BoxFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
585 temp = new StationaryWiggleFilterInterpreter(prop_reg_.get(), temp,
586 tracer_.get());
587 temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
588 temp = new TrendClassifyingFilterInterpreter(prop_reg_.get(), temp,
589 tracer_.get());
590 temp = new MetricsFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
591 GESTURES_DEVCLASS_TOUCHPAD);
592 temp = new ScalingFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
593 GESTURES_DEVCLASS_TOUCHPAD);
594 temp = new FingerMergeFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
595 temp = new StuckButtonInhibitorFilterInterpreter(temp, tracer_.get());
596 temp = new HapticButtonGeneratorFilterInterpreter(prop_reg_.get(), temp,
597 tracer_.get());
598 temp = new TimestampFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
599 temp = loggingFilter_ = new LoggingFilterInterpreter(prop_reg_.get(), temp,
600 tracer_.get());
601 interpreter_.reset(temp);
602 temp = NULL;
603 }
604
InitializeMouse(GestureInterpreterDeviceClass cls)605 void GestureInterpreter::InitializeMouse(GestureInterpreterDeviceClass cls) {
606 Interpreter* temp = new MouseInterpreter(prop_reg_.get(), tracer_.get());
607 // TODO(clchiou;chromium-os:36321): Use mouse acceleration algorithm for mice
608 temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
609 temp = new ScalingFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
610 cls);
611 temp = new MetricsFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
612 cls);
613 temp = new IntegralGestureFilterInterpreter(temp, tracer_.get());
614 temp = loggingFilter_ = new LoggingFilterInterpreter(prop_reg_.get(), temp,
615 tracer_.get());
616 interpreter_.reset(temp);
617 temp = NULL;
618 }
619
InitializeMultitouchMouse(void)620 void GestureInterpreter::InitializeMultitouchMouse(void) {
621 Interpreter* temp = new MultitouchMouseInterpreter(prop_reg_.get(),
622 tracer_.get());
623 temp = new FlingStopFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
624 GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
625 temp = new ClickWiggleFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
626 temp = new LookaheadFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
627 temp = new BoxFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
628 // TODO(clchiou;chromium-os:36321): Use mouse acceleration algorithm for mice
629 temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
630 temp = new ScalingFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
631 GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
632 temp = new MetricsFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
633 GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
634 temp = new IntegralGestureFilterInterpreter(temp, tracer_.get());
635 temp = new StuckButtonInhibitorFilterInterpreter(temp, tracer_.get());
636 temp = new NonLinearityFilterInterpreter(prop_reg_.get(), temp,
637 tracer_.get());
638 temp = loggingFilter_ = new LoggingFilterInterpreter(prop_reg_.get(), temp,
639 tracer_.get());
640 interpreter_.reset(temp);
641 temp = NULL;
642 }
643
Initialize(GestureInterpreterDeviceClass cls)644 void GestureInterpreter::Initialize(GestureInterpreterDeviceClass cls) {
645 if (cls == GESTURES_DEVCLASS_TOUCHPAD ||
646 cls == GESTURES_DEVCLASS_TOUCHSCREEN)
647 InitializeTouchpad();
648 else if (cls == GESTURES_DEVCLASS_MOUSE ||
649 cls == GESTURES_DEVCLASS_POINTING_STICK)
650 InitializeMouse(cls);
651 else if (cls == GESTURES_DEVCLASS_MULTITOUCH_MOUSE)
652 InitializeMultitouchMouse();
653 else
654 Err("Couldn't recognize device class: %d", cls);
655
656 mprops_.reset(new MetricsProperties(prop_reg_.get()));
657 consumer_.reset(new GestureInterpreterConsumer(callback_,
658 callback_data_));
659 }
660
EncodeActivityLog()661 std::string GestureInterpreter::EncodeActivityLog() {
662 return loggingFilter_->EncodeActivityLog();
663 }
664
665 const GestureMove kGestureMove = { 0, 0, 0, 0 };
666 const GestureScroll kGestureScroll = { 0, 0, 0, 0, 0 };
667 const GestureMouseWheel kGestureMouseWheel = { 0, 0, 0, 0 };
668 const GestureButtonsChange kGestureButtonsChange = { 0, 0, 0 };
669 const GestureFling kGestureFling = { 0, 0, 0, 0, 0 };
670 const GestureSwipe kGestureSwipe = { 0, 0, 0, 0 };
671 const GestureFourFingerSwipe kGestureFourFingerSwipe = { 0, 0, 0, 0 };
672 const GesturePinch kGesturePinch = { 0, 0, 0 };
673 const GestureSwipeLift kGestureSwipeLift = { };
674 const GestureFourFingerSwipeLift kGestureFourFingerSwipeLift = { };
675 const GestureMetrics kGestureMetrics = { kGestureMetricsTypeUnknown, {0, 0} };
676