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