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