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, // orientation minimum\n"
69 "%f, // orientation maximum\n"
70 "%u, // max fingers\n"
71 "%u, // max touch\n"
72 "%u, // t5r2\n"
73 "%u, // semi-mt\n"
74 "%u // is button pad\n",
75 left, top, right, bottom,
76 res_x,
77 res_y,
78 orientation_minimum,
79 orientation_maximum,
80 max_finger_cnt,
81 max_touch_cnt,
82 supports_t5r2,
83 support_semi_mt,
84 is_button_pad);
85 }
86
87 namespace {
NameForFingerStateFlag(unsigned flag)88 string NameForFingerStateFlag(unsigned flag) {
89 #define CASERET(name) \
90 case GESTURES_FINGER_##name: return #name
91 switch (flag) {
92 CASERET(WARP_X_NON_MOVE);
93 CASERET(WARP_Y_NON_MOVE);
94 CASERET(NO_TAP);
95 CASERET(POSSIBLE_PALM);
96 CASERET(PALM);
97 CASERET(WARP_X_MOVE);
98 CASERET(WARP_Y_MOVE);
99 CASERET(WARP_X_TAP_MOVE);
100 CASERET(WARP_Y_TAP_MOVE);
101 CASERET(MERGE);
102 CASERET(TREND_INC_X);
103 CASERET(TREND_DEC_X);
104 CASERET(TREND_INC_Y);
105 CASERET(TREND_DEC_Y);
106 CASERET(TREND_INC_PRESSURE);
107 CASERET(TREND_DEC_PRESSURE);
108 CASERET(TREND_INC_TOUCH_MAJOR);
109 CASERET(TREND_DEC_TOUCH_MAJOR);
110 CASERET(INSTANTANEOUS_MOVING);
111 CASERET(WARP_TELEPORTATION);
112 }
113 #undef CASERET
114 return "";
115 }
116 } // namespace {}
117
FlagsString(unsigned flags)118 string FingerState::FlagsString(unsigned flags) {
119 string ret;
120 const char kPipeSeparator[] = " | ";
121 for (unsigned i = 0; i < 8 * sizeof(flags); i++) {
122 const unsigned flag = 1 << i;
123 const string name = NameForFingerStateFlag(flag);
124 if ((flags & flag) && !name.empty()) {
125 ret += kPipeSeparator;
126 ret += name;
127 flags &= ~flag;
128 }
129 }
130 if (flags) {
131 // prepend remaining number
132 ret = StringPrintf("%u%s", flags, ret.c_str());
133 } else if (ret.rfind(kPipeSeparator, 0) == 0) {
134 // strip extra pipe
135 ret = ret.substr(strlen(kPipeSeparator));
136 } else {
137 ret = "no flags";
138 }
139 return ret;
140 }
141
String() const142 string FingerState::String() const {
143 return StringPrintf("{ %d: (%.2f, %.2f), touch %.2fx%.2f, width %.2fx%.2f, "
144 "pressure %.2f, orient %.2f%s }",
145 tracking_id,
146 position_x, position_y,
147 touch_major, touch_minor,
148 width_major, width_minor,
149 pressure,
150 orientation,
151 flags ? (", " + FlagsString(flags)).c_str() : "");
152 }
153
GetFingerState(short tracking_id)154 FingerState* HardwareState::GetFingerState(short tracking_id) {
155 return const_cast<FingerState*>(
156 const_cast<const HardwareState*>(this)->GetFingerState(tracking_id));
157 }
158
GetFingerState(short tracking_id) const159 const FingerState* HardwareState::GetFingerState(short tracking_id) const {
160 for (short i = 0; i < finger_cnt; i++) {
161 if (fingers[i].tracking_id == tracking_id)
162 return &fingers[i];
163 }
164 return nullptr;
165 }
166
String() const167 string HardwareState::String() const {
168 string ret = StringPrintf("{ %f, buttons 0x%x, %d f, %d t, {",
169 timestamp,
170 buttons_down,
171 finger_cnt,
172 touch_cnt);
173 for (size_t i = 0; i < finger_cnt; i++) {
174 if (i != 0)
175 ret += ",";
176 ret += " ";
177 ret += fingers[i].String();
178 }
179 if (finger_cnt > 0)
180 ret += " ";
181 ret += "} }";
182 return ret;
183 }
184
SameFingersAs(const HardwareState & that) const185 bool HardwareState::SameFingersAs(const HardwareState& that) const {
186 if (finger_cnt != that.finger_cnt || touch_cnt != that.touch_cnt)
187 return false;
188 // For now, require fingers to be in the same slots
189 for (size_t i = 0; i < finger_cnt; i++)
190 if (fingers[i].tracking_id != that.fingers[i].tracking_id)
191 return false;
192 return true;
193 }
194
DeepCopy(const HardwareState & that,unsigned short max_finger_cnt)195 void HardwareState::DeepCopy(const HardwareState& that,
196 unsigned short max_finger_cnt) {
197 timestamp = that.timestamp;
198 buttons_down = that.buttons_down;
199 touch_cnt = that.touch_cnt;
200 finger_cnt = min(that.finger_cnt, max_finger_cnt);
201 if(that.fingers != nullptr) {
202 memcpy(fingers, that.fingers, finger_cnt * sizeof(FingerState));
203 } else if (finger_cnt > 0) {
204 Err("HardwareState with no finger data but %d finger count", finger_cnt);
205 }
206 rel_x = that.rel_x;
207 rel_y = that.rel_y;
208 rel_wheel = that.rel_wheel;
209 rel_wheel_hi_res = that.rel_wheel_hi_res;
210 rel_hwheel = that.rel_hwheel;
211 msc_timestamp = that.msc_timestamp;
212 }
213
String() const214 string Gesture::String() const {
215 switch (type) {
216 case kGestureTypeNull:
217 return "(Gesture type: null)";
218 case kGestureTypeContactInitiated:
219 return StringPrintf("(Gesture type: contactInitiated "
220 "start: %f stop: %f)", start_time, end_time);
221 case kGestureTypeMove:
222 return StringPrintf("(Gesture type: move start: %f stop: %f "
223 "dx: %f dy: %f ordinal_dx: %f ordinal_dy: %f)",
224 start_time, end_time,
225 details.move.dx, details.move.dy,
226 details.move.ordinal_dx, details.move.ordinal_dy);
227 case kGestureTypeScroll:
228 return StringPrintf("(Gesture type: scroll start: %f stop: %f "
229 "dx: %f dy: %f ordinal_dx: %f ordinal_dy: %f)",
230 start_time, end_time,
231 details.scroll.dx, details.scroll.dy,
232 details.scroll.ordinal_dx, details.scroll.ordinal_dy);
233 case kGestureTypeMouseWheel:
234 return StringPrintf("(Gesture type: wheel start: %f stop %f "
235 "dx: %f dy: %f "
236 "tick_120ths_dx: %d tick_120ths_dy: %d)",
237 start_time, end_time,
238 details.wheel.dx, details.wheel.dy,
239 details.wheel.tick_120ths_dx,
240 details.wheel.tick_120ths_dy);
241 case kGestureTypePinch:
242 return StringPrintf("(Gesture type: pinch start: %f stop: %f "
243 "dz: %f ordinal_dz: %f, state: %d)", start_time,
244 end_time, details.pinch.dz, details.pinch.ordinal_dz,
245 details.pinch.zoom_state);
246 case kGestureTypeButtonsChange:
247 return StringPrintf("(Gesture type: buttons start: %f stop: "
248 "%f down: %d up: %d is_tap: %s)", start_time, end_time,
249 details.buttons.down, details.buttons.up,
250 details.buttons.is_tap ? "true" : "false");
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 nullptr;
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 nullptr;
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_(nullptr),
428 callback_data_(nullptr),
429 timer_provider_(nullptr),
430 timer_provider_data_(nullptr),
431 interpret_timer_(nullptr),
432 loggingFilter_(nullptr) {
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(nullptr, nullptr);
440 SetPropProvider(nullptr, nullptr);
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_, nullptr, mprops_.get(),
486 consumer_.get());
487 }
488
TimerCallback(stime_t now,stime_t * timeout)489 void GestureInterpreter::TimerCallback(stime_t now, stime_t* timeout) {
490 if (!interpreter_.get()) {
491 Err("Filters are not composed yet!");
492 return;
493 }
494 interpreter_->HandleTimer(now, timeout);
495 }
496
SetTimerProvider(GesturesTimerProvider * tp,void * data)497 void GestureInterpreter::SetTimerProvider(GesturesTimerProvider* tp,
498 void* data) {
499 if (timer_provider_ == tp && timer_provider_data_ == data)
500 return;
501 if (timer_provider_ && interpret_timer_) {
502 timer_provider_->free_fn(timer_provider_data_, interpret_timer_);
503 interpret_timer_ = nullptr;
504 }
505 if (interpret_timer_)
506 Err("How was interpret_timer_ not null?!");
507 timer_provider_ = tp;
508 timer_provider_data_ = data;
509 if (timer_provider_)
510 interpret_timer_ = timer_provider_->create_fn(timer_provider_data_);
511 }
512
SetPropProvider(GesturesPropProvider * pp,void * data)513 void GestureInterpreter::SetPropProvider(GesturesPropProvider* pp,
514 void* data) {
515 prop_reg_->SetPropProvider(pp, data);
516 }
517
SetCallback(GestureReadyFunction callback,void * client_data)518 void GestureInterpreter::SetCallback(GestureReadyFunction callback,
519 void* client_data) {
520 callback_ = callback;
521 callback_data_ = client_data;
522
523 if (consumer_)
524 consumer_->SetCallback(callback, client_data);
525 }
526
set_callback(GestureReadyFunction callback,void * client_data)527 void GestureInterpreter::set_callback(GestureReadyFunction callback,
528 void* client_data) {
529 SetCallback(callback, client_data);
530 }
531
InitializeTouchpad(void)532 void GestureInterpreter::InitializeTouchpad(void) {
533 if (prop_reg_.get()) {
534 stack_version_ = std::make_unique<IntProperty>(prop_reg_.get(),
535 "Touchpad Stack Version", 2);
536 if (stack_version_->val_ == 2) {
537 InitializeTouchpad2();
538 return;
539 }
540 }
541
542 Interpreter* temp = new ImmediateInterpreter(prop_reg_.get(), tracer_.get());
543 temp = new FlingStopFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
544 GESTURES_DEVCLASS_TOUCHPAD);
545 temp = new ClickWiggleFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
546 temp = new PalmClassifyingFilterInterpreter(prop_reg_.get(), temp,
547 tracer_.get());
548 temp = new IirFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
549 temp = new LookaheadFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
550 temp = new BoxFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
551 temp = new StationaryWiggleFilterInterpreter(prop_reg_.get(), temp,
552 tracer_.get());
553 temp = new SensorJumpFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
554 temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
555 temp = new SplitCorrectingFilterInterpreter(prop_reg_.get(), temp,
556 tracer_.get());
557 temp = new TrendClassifyingFilterInterpreter(prop_reg_.get(), temp,
558 tracer_.get());
559 temp = new MetricsFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
560 GESTURES_DEVCLASS_TOUCHPAD);
561 temp = new ScalingFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
562 GESTURES_DEVCLASS_TOUCHPAD);
563 temp = new FingerMergeFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
564 temp = new StuckButtonInhibitorFilterInterpreter(temp, tracer_.get());
565 temp = new HapticButtonGeneratorFilterInterpreter(prop_reg_.get(), temp,
566 tracer_.get());
567 temp = new T5R2CorrectingFilterInterpreter(prop_reg_.get(), temp,
568 tracer_.get());
569 temp = new NonLinearityFilterInterpreter(prop_reg_.get(), temp,
570 tracer_.get());
571 temp = new TimestampFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
572 temp = loggingFilter_ = new LoggingFilterInterpreter(prop_reg_.get(), temp,
573 tracer_.get());
574 interpreter_.reset(temp);
575 temp = nullptr;
576 }
577
InitializeTouchpad2(void)578 void GestureInterpreter::InitializeTouchpad2(void) {
579 Interpreter* temp = new ImmediateInterpreter(prop_reg_.get(), tracer_.get());
580 temp = new FlingStopFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
581 GESTURES_DEVCLASS_TOUCHPAD);
582 temp = new ClickWiggleFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
583 temp = new PalmClassifyingFilterInterpreter(prop_reg_.get(), temp,
584 tracer_.get());
585 temp = new LookaheadFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
586 temp = new BoxFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
587 temp = new StationaryWiggleFilterInterpreter(prop_reg_.get(), temp,
588 tracer_.get());
589 temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
590 temp = new TrendClassifyingFilterInterpreter(prop_reg_.get(), temp,
591 tracer_.get());
592 temp = new MetricsFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
593 GESTURES_DEVCLASS_TOUCHPAD);
594 temp = new ScalingFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
595 GESTURES_DEVCLASS_TOUCHPAD);
596 temp = new FingerMergeFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
597 temp = new StuckButtonInhibitorFilterInterpreter(temp, tracer_.get());
598 temp = new HapticButtonGeneratorFilterInterpreter(prop_reg_.get(), temp,
599 tracer_.get());
600 temp = new TimestampFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
601 temp = loggingFilter_ = new LoggingFilterInterpreter(prop_reg_.get(), temp,
602 tracer_.get());
603 interpreter_.reset(temp);
604 temp = nullptr;
605 }
606
InitializeMouse(GestureInterpreterDeviceClass cls)607 void GestureInterpreter::InitializeMouse(GestureInterpreterDeviceClass cls) {
608 Interpreter* temp = new MouseInterpreter(prop_reg_.get(), tracer_.get());
609 // TODO(clchiou;chromium-os:36321): Use mouse acceleration algorithm for mice
610 temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
611 temp = new ScalingFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
612 cls);
613 temp = new MetricsFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
614 cls);
615 temp = new IntegralGestureFilterInterpreter(temp, tracer_.get());
616 temp = loggingFilter_ = new LoggingFilterInterpreter(prop_reg_.get(), temp,
617 tracer_.get());
618 interpreter_.reset(temp);
619 temp = nullptr;
620 }
621
InitializeMultitouchMouse(void)622 void GestureInterpreter::InitializeMultitouchMouse(void) {
623 Interpreter* temp = new MultitouchMouseInterpreter(prop_reg_.get(),
624 tracer_.get());
625 temp = new FlingStopFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
626 GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
627 temp = new ClickWiggleFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
628 temp = new LookaheadFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
629 temp = new BoxFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
630 // TODO(clchiou;chromium-os:36321): Use mouse acceleration algorithm for mice
631 temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
632 temp = new ScalingFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
633 GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
634 temp = new MetricsFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
635 GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
636 temp = new IntegralGestureFilterInterpreter(temp, tracer_.get());
637 temp = new StuckButtonInhibitorFilterInterpreter(temp, tracer_.get());
638 temp = new NonLinearityFilterInterpreter(prop_reg_.get(), temp,
639 tracer_.get());
640 temp = loggingFilter_ = new LoggingFilterInterpreter(prop_reg_.get(), temp,
641 tracer_.get());
642 interpreter_.reset(temp);
643 temp = nullptr;
644 }
645
Initialize(GestureInterpreterDeviceClass cls)646 void GestureInterpreter::Initialize(GestureInterpreterDeviceClass cls) {
647 if (cls == GESTURES_DEVCLASS_TOUCHPAD ||
648 cls == GESTURES_DEVCLASS_TOUCHSCREEN)
649 InitializeTouchpad();
650 else if (cls == GESTURES_DEVCLASS_MOUSE ||
651 cls == GESTURES_DEVCLASS_POINTING_STICK)
652 InitializeMouse(cls);
653 else if (cls == GESTURES_DEVCLASS_MULTITOUCH_MOUSE)
654 InitializeMultitouchMouse();
655 else
656 Err("Couldn't recognize device class: %d", cls);
657
658 mprops_.reset(new MetricsProperties(prop_reg_.get()));
659 consumer_.reset(new GestureInterpreterConsumer(callback_,
660 callback_data_));
661 }
662
EncodeActivityLog()663 std::string GestureInterpreter::EncodeActivityLog() {
664 return loggingFilter_->EncodeActivityLog();
665 }
666
667 const GestureMove kGestureMove = { 0, 0, 0, 0 };
668 const GestureScroll kGestureScroll = { 0, 0, 0, 0, 0 };
669 const GestureMouseWheel kGestureMouseWheel = { 0, 0, 0, 0 };
670 const GestureButtonsChange kGestureButtonsChange = { 0, 0, 0 };
671 const GestureFling kGestureFling = { 0, 0, 0, 0, 0 };
672 const GestureSwipe kGestureSwipe = { 0, 0, 0, 0 };
673 const GestureFourFingerSwipe kGestureFourFingerSwipe = { 0, 0, 0, 0 };
674 const GesturePinch kGesturePinch = { 0, 0, 0 };
675 const GestureSwipeLift kGestureSwipeLift = { };
676 const GestureFourFingerSwipeLift kGestureFourFingerSwipeLift = { };
677 const GestureMetrics kGestureMetrics = { kGestureMetricsTypeUnknown, {0, 0} };
678