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