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