• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef GESTURES_GESTURES_H__
6 #define GESTURES_GESTURES_H__
7 
8 #include <stdint.h>
9 #include <sys/time.h>
10 #include <sys/types.h>
11 
12 #ifdef __cplusplus
13 #include <string>
14 
15 #include <memory>
16 
17 extern "C" {
18 #endif
19 
20 // C API:
21 
22 // external logging interface
23 #define GESTURES_LOG_ERROR 0
24 #define GESTURES_LOG_INFO 1
25 
26 // this function has to be provided by the user of the library.
27 void gestures_log(int verb, const char* format, ...)
28     __attribute__((format(printf, 2, 3)));
29 
30 typedef double stime_t;  // seconds
31 
32 // Represents "unset" when stime_t is used for timeouts or deadlines.
33 #define NO_DEADLINE -1.0
34 
35 enum GestureInterpreterDeviceClass {
36   GESTURES_DEVCLASS_UNKNOWN,
37   GESTURES_DEVCLASS_MOUSE,
38   GESTURES_DEVCLASS_MULTITOUCH_MOUSE,
39   GESTURES_DEVCLASS_TOUCHPAD,
40   GESTURES_DEVCLASS_TOUCHSCREEN,
41   GESTURES_DEVCLASS_POINTING_STICK,
42 };
43 
44 stime_t StimeFromTimeval(const struct timeval*);
45 stime_t StimeFromTimespec(const struct timespec*);
46 
47 // Describes the capabilities of a touchpad or mouse.
48 struct HardwareProperties {
49   // Touch properties
50   // The minimum X coordinate that the device can report.
51   float left = 0;
52   // The minimum Y coordinate that the device can report.
53   float top = 0;
54   // The maximum X coordinate that the device can report.
55   float right;
56   // The maximum Y coordinate that the device can report.
57   float bottom;
58   // The resolutions of the X and Y axes, in units per mm. Set to 0 if the
59   // resolution is unknown.
60   float res_x;
61   float res_y;
62 
63   // Deprecated: these values are now ignored. Previously, they specified the
64   // DPI of the screen to which gestures output by the library should be
65   // scaled.
66   float screen_x_dpi;
67   float screen_y_dpi;
68 
69   // The minimum and maximum orientation values.
70   float orientation_minimum;
71   float orientation_maximum;
72 
73   // The maximum number of finger slots that the device can report in one
74   // HardwareState struct.
75   unsigned short max_finger_cnt;
76   // The maximum number of contacts that the device can detect at once, whether
77   // or not it can report their coordinates.
78   unsigned short max_touch_cnt;
79 
80   // Whether this is a "Track 5, Report 2" touchpad, which can track up to five
81   // fingers but only report the locations of two. (For more details, see
82   // https://crrev.com/37cccb42e652b50f9e788d90e82252f78c78f1ed)
83   unsigned supports_t5r2:1;
84 
85   // Whether this is a "Semi-Multitouch" touchpad, which can detect two separate
86   // fingers but only report their bounding box, not individual locations.
87   unsigned support_semi_mt:1;
88 
89   // Whether the touchpad has a button under its touch surface, allowing the
90   // user to click by pressing (almost) anywhere on the pad, as opposed to
91   // having one or more separate buttons for clicking.
92   unsigned is_button_pad:1;
93 
94   // Mouse properties
95   // Whether the mouse has a scroll wheel.
96   unsigned has_wheel:1;
97   // Whether the mouse's scroll wheel is high-resolution (reported through the
98   // rel_wheel_hi_res field of the HardwareState struct).
99   unsigned wheel_is_hi_res:1;
100 
101   // Whether the touchpad is haptic, meaning that it reports true pressure (not
102   // just touch area) via the pressure axis, and can provide haptic feedback.
103   unsigned is_haptic_pad:1;
104 
105   // Whether the touchpad reports pressure values in any way.
106   bool reports_pressure = true;
107 #ifdef __cplusplus
108   std::string String() const;
109 #endif  // __cplusplus
110 };
111 
112 // Warp: If a finger has the 'warp' flag set for an axis, it means that while
113 // the finger may have moved, it should not cause any motion in that direction.
114 // This may occur is some situations where we thought a finger was in one place,
115 // but then we realized later it was actually in another place.
116 // The *_WARP_X/Y_MOVE version is an indication for suppressing unwanted
117 // cursor movement, while the *_WARP_X/Y_NON_MOVE version is for unwanted
118 // non-cursor movement (e.g. scrolling)
119 #define GESTURES_FINGER_WARP_X_NON_MOVE        (1 << 0)
120 #define GESTURES_FINGER_WARP_Y_NON_MOVE        (1 << 1)
121 // If a finger has notap set, it shouldn't begin a tap gesture.
122 #define GESTURES_FINGER_NO_TAP        (1 << 2)
123 #define GESTURES_FINGER_POSSIBLE_PALM (1 << 3)
124 #define GESTURES_FINGER_PALM          (1 << 4)
125 #define GESTURES_FINGER_WARP_X_MOVE   (1 << 5)
126 #define GESTURES_FINGER_WARP_Y_MOVE   (1 << 6)
127 // If tap to click movement detection should warp:
128 #define GESTURES_FINGER_WARP_X_TAP_MOVE   (1 << 7)
129 #define GESTURES_FINGER_WARP_Y_TAP_MOVE   (1 << 8)
130 // If a finger is a merged finger or one of close fingers
131 #define GESTURES_FINGER_MERGE   (1 << 9)
132 // If a finger is showing a trend of moving (see the TrendClassifyingFilter).
133 #define GESTURES_FINGER_TREND_INC_X (1 << 10)
134 #define GESTURES_FINGER_TREND_DEC_X (1 << 11)
135 #define GESTURES_FINGER_TREND_INC_Y (1 << 12)
136 #define GESTURES_FINGER_TREND_DEC_Y (1 << 13)
137 #define GESTURES_FINGER_TREND_INC_PRESSURE (1 << 14)
138 #define GESTURES_FINGER_TREND_DEC_PRESSURE (1 << 15)
139 #define GESTURES_FINGER_TREND_INC_TOUCH_MAJOR (1 << 16)
140 #define GESTURES_FINGER_TREND_DEC_TOUCH_MAJOR (1 << 17)
141 // If a finger is non-stationary recently (see the StationaryWiggleFilter).
142 // Compared to the trend flags, this one takes the magnitude of movements
143 // into account so it might be more useful in some cases. However, it is also
144 // more prone to abrupt noisy jumps than the trend flags. It also looks at
145 // a shorter period of time than the trend ones so it may provide faster
146 // response and lower latency.
147 #define GESTURES_FINGER_INSTANTANEOUS_MOVING (1 << 18)
148 // We sometimes use the warp flags only because we want to suppress unwanted
149 // movements and not that we really have no good idea of the finger position.
150 // This poses additional difficulty for some classifying logics that relies
151 // much on the finger position. To maximize the use of any available data,
152 // we further mark a finger as GESTURES_FINGER_WARP_TELEPORTATION only if we
153 // indeed have no idea of its position (e.g. due to sensor jumps). For all
154 // other cases (e.g. click wiggle, plams suppression, stationary wiggle), we
155 // skip the flag so that we can have the option to use the not-that-accurate
156 // positions.
157 #define GESTURES_FINGER_WARP_TELEPORTATION (1 << 19)
158 #define GESTURES_FINGER_LARGE_PALM (1 << 20)
159 
160 #define GESTURES_FINGER_WARP_X    (GESTURES_FINGER_WARP_X_NON_MOVE | \
161                                    GESTURES_FINGER_WARP_X_MOVE)
162 #define GESTURES_FINGER_WARP_Y    (GESTURES_FINGER_WARP_Y_NON_MOVE | \
163                                    GESTURES_FINGER_WARP_Y_MOVE)
164 
165 // Describes a single contact on a touch surface. Generally, the fields have the
166 // same meaning as the equivalent ABS_MT_... axis in the Linux evdev protocol.
167 struct FingerState {
168   enum class ToolType {
169     kFinger = 0,
170     kPalm,
171   };
172   // The large and small radii of the ellipse of the finger touching the pad.
173   float touch_major, touch_minor;
174 
175   // The large and small radii of the ellipse of the finger, including parts
176   // that are hovering over the pad but not quite touching. Devices normally
177   // don't report these values, in which case they should be left at 0.
178   float width_major, width_minor;
179   float pressure;
180   float orientation;
181 
182   float position_x;
183   float position_y;
184 
185   // A number that identifies a single physical finger across consecutive
186   // frames. If a finger is the same physical finger across two consecutive
187   // frames, it must have the same tracking ID; if it's a different finger, it
188   // should have a different tracking ID. It should be ≥ 0 (see documentation
189   // comment for HardwareState::fingers).
190   short tracking_id;
191 
192   // A bit field of flags that are used internally by the library. (See the
193   // GESTURES_FINGER_* constants.) Should be set to 0 on incoming FingerStates.
194   unsigned flags;
195 
196   ToolType tool_type = ToolType::kFinger;
197 #ifdef __cplusplus
NonFlagsEqualsFingerState198   bool NonFlagsEquals(const FingerState& that) const {
199     return touch_major == that.touch_major &&
200         touch_minor == that.touch_minor &&
201         width_major == that.width_major &&
202         width_minor == that.width_minor &&
203         pressure == that.pressure &&
204         orientation == that.orientation &&
205         position_x == that.position_x &&
206         position_y == that.position_y &&
207         tracking_id == that.tracking_id;
208   }
209   bool operator==(const FingerState& that) const {
210     return NonFlagsEquals(that) && flags == that.flags;
211   }
212   bool operator!=(const FingerState& that) const { return !(*this == that); }
213   static std::string FlagsString(unsigned flags);
214   std::string String() const;
215 #endif
216 };
217 
218 #define GESTURES_BUTTON_NONE 0
219 #define GESTURES_BUTTON_LEFT 1
220 #define GESTURES_BUTTON_MIDDLE 2
221 #define GESTURES_BUTTON_RIGHT 4
222 #define GESTURES_BUTTON_BACK 8
223 #define GESTURES_BUTTON_FORWARD 16
224 #define GESTURES_BUTTON_SIDE 32
225 #define GESTURES_BUTTON_EXTRA 64
226 
227 // Describes one frame of data from the input device.
228 struct HardwareState {
229 #ifdef __cplusplus
230   FingerState* GetFingerState(short tracking_id);
231   const FingerState* GetFingerState(short tracking_id) const;
232   bool SameFingersAs(const HardwareState& that) const;
233   std::string String() const;
234   void DeepCopy(const HardwareState& that, unsigned short max_finger_cnt);
235 #endif  // __cplusplus
236   // The time at which the event was received by the system.
237   stime_t timestamp;
238   // A bit field indicating which buttons are pressed. (See the
239   // GESTURES_BUTTON_* constants.)
240   int buttons_down;
241   // The number of FingerState structs pointed to by the fingers field.
242   unsigned short finger_cnt;
243   // The number of fingers touching the pad, which may be more than finger_cnt.
244   unsigned short touch_cnt;
245   // A pointer to an array of FingerState structs with finger_cnt entries,
246   // representing the contacts currently being tracked. If finger_cnt is 0, this
247   // pointer will be null.
248   //
249   // The order in which FingerStates appear need not be stable between
250   // HardwareStates — only the tracking ID is used to track individual contacts
251   // over time. Accordingly, when a finger is lifted from the pad (and therefore
252   // its ABS_MT_TRACKING_ID becomes -1), the client should simply stop including
253   // it in this array, rather than including a final FingerState for it.
254   struct FingerState* fingers;
255 
256   // Mouse axes, which have the same meanings as the Linux evdev axes of the
257   // same name.
258   float rel_x;
259   float rel_y;
260   float rel_wheel;
261   float rel_wheel_hi_res;
262   float rel_hwheel;
263 
264   // The timestamp for the frame, as reported by the device's firmware. This may
265   // be different from the timestamp field above, for example if events were
266   // batched when being sent over Bluetooth. Set to 0.0 if no such timestamp is
267   // available. (Named after the MSC_TIMESTAMP axis from evdev.)
268   stime_t msc_timestamp;
269 };
270 
271 #define GESTURES_FLING_START 0  // Scroll end/fling begin
272 #define GESTURES_FLING_TAP_DOWN 1  // Finger touched down/fling end
273 
274 #define GESTURES_ZOOM_START 0  // Pinch zoom begin
275 #define GESTURES_ZOOM_UPDATE 1  // Zoom-in/Zoom-out update
276 #define GESTURES_ZOOM_END 2  // Pinch zoom end
277 
278 // Gesture sub-structs
279 
280 // Note about ordinal_* values: Sometimes, UI will want to use unaccelerated
281 // values for various gestures, so we expose the non-accelerated values in
282 // the ordinal_* fields.
283 
284 typedef struct {
285   // The movement in the X axis. Positive values indicate motion to the right.
286   float dx;
287   // The movement in the Y axis. Positive values indicate downwards motion.
288   float dy;
289   float ordinal_dx, ordinal_dy;
290 } GestureMove;
291 
292 // Represents scroll gestures on a touch device.
293 typedef struct{
294   // The scroll movement in the X axis. Unlike with move gestures, *negative*
295   // values indicate the fingers moving to the right, unless the "Australian
296   // Scrolling" or "Invert Scrolling" properties are set.
297   float dx;
298   // The scroll movement in the Y axis. Unlike with move gestures, *negative*
299   // values indicate the fingers moving downwards, unless the "Australian
300   // Scrolling" or "Invert Scrolling" properties are set.
301   float dy;
302   float ordinal_dx, ordinal_dy;
303   // If set, stop_fling means that this scroll should stop flinging, thus
304   // if an interpreter suppresses it for any reason (e.g., rounds the size
305   // down to 0, thus making it a noop), it will replace it with a Fling
306   // TAP_DOWN gesture
307   unsigned stop_fling:1;
308 } GestureScroll;
309 
310 // Represents mouse wheel movements.
311 typedef struct {
312   // The amount to scroll by, after acceleration and scaling have been applied.
313   float dx, dy;
314   // The amount the wheel actually moved. A change of 120 represents moving the
315   // wheel one whole tick (a.k.a. notch).
316   int tick_120ths_dx, tick_120ths_dy;
317 } GestureMouseWheel;
318 
319 typedef struct {
320   // If a bit is set in both down and up, client should process down first
321   unsigned down;  // bit field, use GESTURES_BUTTON_*
322   unsigned up;  // bit field, use GESTURES_BUTTON_*
323   bool is_tap; // was the gesture generated with tap-to-click?
324 } GestureButtonsChange;
325 
326 typedef struct {
327   // The fling velocity in the X axis, only valid when fling_state is
328   // GESTURES_FLING_START. Unlike with move gestures, *negative* values indicate
329   // the fingers moving to the right, unless the "Australian Scrolling" or
330   // "Invert Scrolling" properties are set.
331   float vx;
332   // The fling velocity in the Y axis, only valid when fling_state is
333   // GESTURES_FLING_START. Unlike with move gestures, *negative* values indicate
334   // the fingers moving downwards, unless the "Australian Scrolling" or "Invert
335   // Scrolling" properties are set.
336   float vy;
337   float ordinal_vx, ordinal_vy;
338   unsigned fling_state:1;  // GESTURES_FLING_START or GESTURES_FLING_TAP_DOWN
339 } GestureFling;
340 
341 typedef struct {
342   // The swipe movement in the X axis. Positive values indicate motion to the
343   // right.
344   float dx;
345   // The swipe movement in the Y axis. Unlike with move gestures, *negative*
346   // values indicate downwards motion, unless the "Australian Scrolling"
347   // property is set.
348   float dy;
349   float ordinal_dx, ordinal_dy;
350 } GestureSwipe;
351 
352 typedef struct {
353   // The swipe movement in the X axis. Positive values indicate motion to the
354   // right.
355   float dx;
356   // The swipe movement in the Y axis. Unlike with move gestures, *negative*
357   // values indicate downwards motion, unless the "Australian Scrolling"
358   // property is set.
359   float dy;
360   float ordinal_dx, ordinal_dy;
361 } GestureFourFingerSwipe;
362 
363 typedef struct {
364   char __dummy;
365   // Remove this when there is a member in this struct. http://crbug.com/341155
366   // Currently no members
367 } GestureFourFingerSwipeLift;
368 
369 typedef struct {
370   char __dummy;
371   // Remove this when there is a member in this struct. http://crbug.com/341155
372   // Currently no members
373 } GestureSwipeLift;
374 
375 typedef struct {
376   // Relative pinch factor starting with 1.0 = no pinch
377   // <1.0 for outwards pinch
378   // >1.0 for inwards pinch
379   float dz;
380   float ordinal_dz;
381   // GESTURES_ZOOM_START, GESTURES_ZOOM_UPDATE, or GESTURES_ZOOM_END
382   unsigned zoom_state;
383 } GesturePinch;
384 
385 // Metrics types that we care about
386 enum GestureMetricsType {
387   kGestureMetricsTypeNoisyGround = 0,
388   kGestureMetricsTypeMouseMovement,
389   kGestureMetricsTypeUnknown,
390 };
391 
392 typedef struct {
393   enum GestureMetricsType type;
394   // Optional values for the metrics. 2 are more than enough for now.
395   float data[2];
396 } GestureMetrics;
397 
398 // Describes the type of gesture that is being reported.
399 enum GestureType {
400 #ifdef GESTURES_INTERNAL
401   kGestureTypeNull = -1,  // internal to Gestures library only
402 #endif  // GESTURES_INTERNAL
403   // No longer used.
404   kGestureTypeContactInitiated = 0,
405   // For touchpads, a movement of a single finger on the pad. For mice, a
406   // movement of the whole mouse.
407   kGestureTypeMove,
408   // A two-finger scroll gesture on a touchpad. (See kGestureTypeMouseWheel for
409   // the mouse equivalent.)
410   kGestureTypeScroll,
411   // A change in the buttons that are currently pressed on the device.
412   kGestureTypeButtonsChange,
413   // The start or end of a fling motion, where scrolling should continue after
414   // the user's fingers have left the touchpad.
415   kGestureTypeFling,
416   // A movement of three fingers on a touchpad.
417   kGestureTypeSwipe,
418   // A movement of two fingers on a touchpad that are primarily moving closer to
419   // or further from each other.
420   kGestureTypePinch,
421   // The end of a movement of three fingers on a touchpad.
422   kGestureTypeSwipeLift,
423   // Used to report metrics to the client.
424   kGestureTypeMetrics,
425   // A movement of four fingers on a touchpad.
426   kGestureTypeFourFingerSwipe,
427   // The end of a movement of four fingers on a touchpad.
428   kGestureTypeFourFingerSwipeLift,
429   // The movement of a scroll wheel on a mouse.
430   kGestureTypeMouseWheel,
431 };
432 
433 #ifdef __cplusplus
434 // Pass these into Gesture() ctor as first arg
435 extern const GestureMove kGestureMove;
436 extern const GestureScroll kGestureScroll;
437 extern const GestureMouseWheel kGestureMouseWheel;
438 extern const GestureButtonsChange kGestureButtonsChange;
439 extern const GestureFling kGestureFling;
440 extern const GestureSwipe kGestureSwipe;
441 extern const GestureFourFingerSwipe kGestureFourFingerSwipe;
442 extern const GesturePinch kGesturePinch;
443 extern const GestureSwipeLift kGestureSwipeLift;
444 extern const GestureFourFingerSwipeLift kGestureFourFingerSwipeLift;
445 extern const GestureMetrics kGestureMetrics;
446 #endif  // __cplusplus
447 
448 struct Gesture {
449 #ifdef __cplusplus
450   // Create Move/Scroll gesture
451 #ifdef GESTURES_INTERNAL
GestureGesture452   Gesture() : start_time(0), end_time(0), type(kGestureTypeNull) {}
453   bool operator==(const Gesture& that) const;
454   bool operator!=(const Gesture& that) const { return !(*this == that); };
455 #endif  // GESTURES_INTERNAL
456   std::string String() const;
GestureGesture457   Gesture(const GestureMove&, stime_t start, stime_t end, float dx, float dy)
458       : start_time(start), end_time(end), type(kGestureTypeMove) {
459     details.move.ordinal_dx = details.move.dx = dx;
460     details.move.ordinal_dy = details.move.dy = dy;
461   }
GestureGesture462   Gesture(const GestureScroll&,
463           stime_t start, stime_t end, float dx, float dy)
464       : start_time(start), end_time(end), type(kGestureTypeScroll) {
465     details.scroll.ordinal_dx = details.scroll.dx = dx;
466     details.scroll.ordinal_dy = details.scroll.dy = dy;
467     details.scroll.stop_fling = 0;
468   }
GestureGesture469   Gesture(const GestureMouseWheel&,
470           stime_t start, stime_t end, float dx, float dy, int tick_120ths_dx,
471           int tick_120ths_dy)
472       : start_time(start), end_time(end), type(kGestureTypeMouseWheel) {
473     details.wheel.dx = dx;
474     details.wheel.dy = dy;
475     details.wheel.tick_120ths_dx = tick_120ths_dx;
476     details.wheel.tick_120ths_dy = tick_120ths_dy;
477   }
GestureGesture478   Gesture(const GestureButtonsChange&,
479           stime_t start, stime_t end, unsigned down, unsigned up, bool is_tap)
480       : start_time(start),
481         end_time(end),
482         type(kGestureTypeButtonsChange) {
483     details.buttons.down = down;
484     details.buttons.up = up;
485     details.buttons.is_tap = is_tap;
486   }
GestureGesture487   Gesture(const GestureFling&,
488           stime_t start, stime_t end, float vx, float vy, unsigned state)
489       : start_time(start), end_time(end), type(kGestureTypeFling) {
490     details.fling.ordinal_vx = details.fling.vx = vx;
491     details.fling.ordinal_vy = details.fling.vy = vy;
492     details.fling.fling_state = state;
493   }
GestureGesture494   Gesture(const GestureSwipe&,
495           stime_t start, stime_t end, float dx, float dy)
496       : start_time(start),
497         end_time(end),
498         type(kGestureTypeSwipe) {
499     details.swipe.ordinal_dx = details.swipe.dx = dx;
500     details.swipe.ordinal_dy = details.swipe.dy = dy;
501   }
GestureGesture502   Gesture(const GestureFourFingerSwipe&,
503           stime_t start, stime_t end, float dx, float dy)
504       : start_time(start),
505         end_time(end),
506         type(kGestureTypeFourFingerSwipe) {
507     details.four_finger_swipe.ordinal_dx = details.four_finger_swipe.dx = dx;
508     details.four_finger_swipe.ordinal_dy = details.four_finger_swipe.dy = dy;
509   }
GestureGesture510   Gesture(const GesturePinch&,
511           stime_t start, stime_t end, float dz, unsigned state)
512       : start_time(start),
513         end_time(end),
514         type(kGestureTypePinch) {
515     details.pinch.ordinal_dz = details.pinch.dz = dz;
516     details.pinch.zoom_state = state;
517   }
GestureGesture518   Gesture(const GestureSwipeLift&, stime_t start, stime_t end)
519       : start_time(start),
520         end_time(end),
521         type(kGestureTypeSwipeLift) {}
GestureGesture522   Gesture(const GestureFourFingerSwipeLift&, stime_t start, stime_t end)
523       : start_time(start),
524         end_time(end),
525         type(kGestureTypeFourFingerSwipeLift) {}
GestureGesture526   Gesture(const GestureMetrics&,
527           stime_t start, stime_t end, GestureMetricsType m_type,
528           float d1, float d2)
529       : start_time(start),
530         end_time(end),
531         type(kGestureTypeMetrics) {
532     details.metrics.type = m_type;
533     details.metrics.data[0] = d1;
534     details.metrics.data[1] = d2;
535   }
536 #endif  // __cplusplus
537 
538   stime_t start_time, end_time;
539   enum GestureType type;
540   union {
541     GestureMove move;
542     GestureScroll scroll;
543     GestureMouseWheel wheel;
544     GestureButtonsChange buttons;
545     GestureFling fling;
546     GestureSwipe swipe;
547     GesturePinch pinch;
548     GestureSwipeLift swipe_lift;
549     GestureMetrics metrics;
550     GestureFourFingerSwipe four_finger_swipe;
551     GestureFourFingerSwipeLift four_finger_swipe_lift;
552   } details;
553 };
554 
555 typedef void (*GestureReadyFunction)(void* client_data,
556                                      const struct Gesture* gesture);
557 
558 // Gestures Timer Provider Interface
559 struct GesturesTimer;
560 typedef struct GesturesTimer GesturesTimer;
561 
562 // If this returns < 0, the timer should be freed. If it returns >= 0.0, it
563 // should be called again after that amount of delay.
564 typedef stime_t (*GesturesTimerCallback)(stime_t now,
565                                          void* callback_data);
566 // Allocate and return a new timer, or nullptr if error.
567 typedef GesturesTimer* (*GesturesTimerCreate)(void* data);
568 // Set a timer:
569 typedef void (*GesturesTimerSet)(void* data,
570                                  GesturesTimer* timer,
571                                  stime_t delay,
572                                  GesturesTimerCallback callback,
573                                  void* callback_data);
574 // Cancel a set timer:
575 typedef void (*GesturesTimerCancel)(void* data, GesturesTimer* timer);
576 // Free the timer. Will not be called from within a timer callback.
577 typedef void (*GesturesTimerFree)(void* data, GesturesTimer* timer);
578 
579 typedef struct {
580   GesturesTimerCreate create_fn;
581   GesturesTimerSet set_fn;
582   GesturesTimerCancel cancel_fn;
583   GesturesTimerFree free_fn;
584 } GesturesTimerProvider;
585 
586 // Gestures Property Provider Interface
587 struct GesturesProp;
588 typedef struct GesturesProp GesturesProp;
589 
590 typedef unsigned char GesturesPropBool;
591 
592 // These functions create a named property of given type.
593 //   data - data used by PropProvider
594 //   loc - location of a variable to be updated by PropProvider
595 //         (Chromium calls its own GesturesPropCreate... functions with loc set
596 //         to null to create read-only properties, but the Gestures library
597 //         itself doesn't, so other clients don't need to support them.)
598 //   init - initial value for the property.
599 //          If the PropProvider has an alternate configuration source, it may
600 //          override this initial value, in which case *loc returns the
601 //          value from the configuration source.
602 typedef GesturesProp* (*GesturesPropCreateInt)(void* data, const char* name,
603                                                int* loc, size_t count,
604                                                const int* init);
605 
606 // Deprecated: the gestures library no longer uses short gesture properties.
607 typedef GesturesProp* (*GesturesPropCreateShort_Deprecated)(
608     void*, const char*, short*, size_t, const short*);
609 
610 typedef GesturesProp* (*GesturesPropCreateBool)(void* data, const char* name,
611                                                 GesturesPropBool* loc,
612                                                 size_t count,
613                                                 const GesturesPropBool* init);
614 
615 typedef GesturesProp* (*GesturesPropCreateString)(void* data, const char* name,
616                                                   const char** loc,
617                                                   const char* const init);
618 
619 typedef GesturesProp* (*GesturesPropCreateReal)(void* data, const char* name,
620                                                 double* loc, size_t count,
621                                                 const double* init);
622 
623 // A function to call just before a property is to be read.
624 // |handler_data| is a local context pointer that can be used by the handler.
625 // Handler should return non-zero if it modifies the property's value.
626 typedef GesturesPropBool (*GesturesPropGetHandler)(void* handler_data);
627 
628 // A function to call just after a property's value is updated.
629 // |handler_data| is a local context pointer that can be used by the handler.
630 typedef void (*GesturesPropSetHandler)(void* handler_data);
631 
632 // Register handlers for the client to call when a GesturesProp is accessed.
633 //
634 // The get handler, if not nullptr, should be called immediately before the
635 // property's value is to be read. This gives the library a chance to update its
636 // value.
637 //
638 // The set handler, if not nullptr, should be called immediately after the
639 // property's value is updated. This can be used to create a property that is
640 // used to trigger an action, or to force an update to multiple properties
641 // atomically.
642 //
643 // Note: the handlers are called from non-signal/interrupt context
644 typedef void (*GesturesPropRegisterHandlers)(void* data, GesturesProp* prop,
645                                              void* handler_data,
646                                              GesturesPropGetHandler getter,
647                                              GesturesPropSetHandler setter);
648 
649 // Free a property.
650 typedef void (*GesturesPropFree)(void* data, GesturesProp* prop);
651 
652 typedef struct GesturesPropProvider {
653   GesturesPropCreateInt create_int_fn;
654   // Deprecated: the library no longer uses short gesture properties, so this
655   // function pointer should be null.
656   GesturesPropCreateShort_Deprecated create_short_fn;
657   GesturesPropCreateBool create_bool_fn;
658   GesturesPropCreateString create_string_fn;
659   GesturesPropCreateReal create_real_fn;
660   GesturesPropRegisterHandlers register_handlers_fn;
661   GesturesPropFree free_fn;
662 } GesturesPropProvider;
663 
664 #ifdef __cplusplus
665 // C++ API:
666 
667 namespace gestures {
668 
669 class Interpreter;
670 class IntProperty;
671 class PropRegistry;
672 class LoggingFilterInterpreter;
673 class Tracer;
674 class GestureInterpreterConsumer;
675 class MetricsProperties;
676 
677 struct GestureInterpreter {
678  public:
679   explicit GestureInterpreter(int version);
680   ~GestureInterpreter();
681   void PushHardwareState(HardwareState* hwstate);
682 
683   void SetHardwareProperties(const HardwareProperties& hwprops);
684 
685   void TimerCallback(stime_t now, stime_t* timeout);
686 
687   void SetCallback(GestureReadyFunction callback, void* client_data);
688   // Deprecated; use SetCallback instead.
689   void set_callback(GestureReadyFunction callback,
690                     void* client_data);
691   void SetTimerProvider(GesturesTimerProvider* tp, void* data);
692   void SetPropProvider(GesturesPropProvider* pp, void* data);
693 
694   // Initialize GestureInterpreter based on device configuration.  This must be
695   // called after GesturesPropProvider is set and before it accepts any inputs.
696   void Initialize(
697       GestureInterpreterDeviceClass type=GESTURES_DEVCLASS_TOUCHPAD);
698 
interpreterGestureInterpreter699   Interpreter* interpreter() const { return interpreter_.get(); }
prop_regGestureInterpreter700   PropRegistry* prop_reg() const { return prop_reg_.get(); }
701 
702   std::string EncodeActivityLog();
703  private:
704   void InitializeTouchpad(void);
705   void InitializeTouchpad2(void);
706   void InitializeMouse(GestureInterpreterDeviceClass cls);
707   void InitializeMultitouchMouse(void);
708 
709   GestureReadyFunction callback_;
710   void* callback_data_;
711 
712   std::unique_ptr<PropRegistry> prop_reg_;
713   std::unique_ptr<Tracer> tracer_;
714   std::unique_ptr<Interpreter> interpreter_;
715   std::unique_ptr<MetricsProperties> mprops_;
716   std::unique_ptr<IntProperty> stack_version_;
717 
718   GesturesTimerProvider* timer_provider_;
719   void* timer_provider_data_;
720   GesturesTimer* interpret_timer_;
721 
722   LoggingFilterInterpreter* loggingFilter_;
723   std::unique_ptr<GestureInterpreterConsumer> consumer_;
724   HardwareProperties hwprops_;
725 
726   // Disallow copy & assign;
727   GestureInterpreter(const GestureInterpreter&);
728   void operator=(const GestureInterpreter&);
729 };
730 
731 }  // namespace gestures
732 
733 typedef gestures::GestureInterpreter GestureInterpreter;
734 #else
735 struct GestureInterpreter;
736 typedef struct GestureInterpreter GestureInterpreter;
737 #endif  // __cplusplus
738 
739 #define GESTURES_VERSION 1
740 GestureInterpreter* NewGestureInterpreterImpl(int);
741 #define NewGestureInterpreter() NewGestureInterpreterImpl(GESTURES_VERSION)
742 
743 void DeleteGestureInterpreter(GestureInterpreter*);
744 
745 void GestureInterpreterSetHardwareProperties(GestureInterpreter*,
746                                              const struct HardwareProperties*);
747 
748 void GestureInterpreterPushHardwareState(GestureInterpreter*,
749                                          struct HardwareState*);
750 
751 void GestureInterpreterSetCallback(GestureInterpreter*,
752                                    GestureReadyFunction,
753                                    void*);
754 
755 // Gestures will hold a reference to passed provider. Pass nullptr to tell
756 // Gestures to stop holding a reference.
757 void GestureInterpreterSetTimerProvider(GestureInterpreter*,
758                                         GesturesTimerProvider*,
759                                         void*);
760 
761 void GestureInterpreterSetPropProvider(GestureInterpreter*,
762                                        GesturesPropProvider*,
763                                        void*);
764 
765 void GestureInterpreterInitialize(GestureInterpreter*,
766                                   enum GestureInterpreterDeviceClass);
767 
768 #ifdef __cplusplus
769 }
770 #endif
771 
772 #endif  // GESTURES_GESTURES_H__
773