768 lines
29 KiB
C++
768 lines
29 KiB
C++
// Copyright 2012 The ChromiumOS Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef GESTURES_GESTURES_H__
|
|
#define GESTURES_GESTURES_H__
|
|
|
|
#include <stdint.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
|
|
#ifdef __cplusplus
|
|
#include <string>
|
|
|
|
#include <memory>
|
|
|
|
extern "C" {
|
|
#endif
|
|
|
|
// C API:
|
|
|
|
// external logging interface
|
|
#define GESTURES_LOG_ERROR 0
|
|
#define GESTURES_LOG_INFO 1
|
|
|
|
// this function has to be provided by the user of the library.
|
|
void gestures_log(int verb, const char* format, ...)
|
|
__attribute__((format(printf, 2, 3)));
|
|
|
|
typedef double stime_t; // seconds
|
|
|
|
// Represents "unset" when stime_t is used for timeouts or deadlines.
|
|
#define NO_DEADLINE -1.0
|
|
|
|
enum GestureInterpreterDeviceClass {
|
|
GESTURES_DEVCLASS_UNKNOWN,
|
|
GESTURES_DEVCLASS_MOUSE,
|
|
GESTURES_DEVCLASS_MULTITOUCH_MOUSE,
|
|
GESTURES_DEVCLASS_TOUCHPAD,
|
|
GESTURES_DEVCLASS_TOUCHSCREEN,
|
|
GESTURES_DEVCLASS_POINTING_STICK,
|
|
};
|
|
|
|
stime_t StimeFromTimeval(const struct timeval*);
|
|
stime_t StimeFromTimespec(const struct timespec*);
|
|
|
|
// Describes the capabilities of a touchpad or mouse.
|
|
struct HardwareProperties {
|
|
// Touch properties
|
|
// The minimum X coordinate that the device can report.
|
|
float left;
|
|
// The minimum Y coordinate that the device can report.
|
|
float top;
|
|
// The maximum X coordinate that the device can report.
|
|
float right;
|
|
// The maximum Y coordinate that the device can report.
|
|
float bottom;
|
|
// The resolutions of the X and Y axes, in units per mm. Set to 0 if the
|
|
// resolution is unknown.
|
|
float res_x;
|
|
float res_y;
|
|
|
|
// Deprecated: these values are now ignored. Previously, they specified the
|
|
// DPI of the screen to which gestures output by the library should be
|
|
// scaled.
|
|
float screen_x_dpi;
|
|
float screen_y_dpi;
|
|
|
|
// The minimum and maximum orientation values.
|
|
float orientation_minimum;
|
|
float orientation_maximum;
|
|
|
|
// The maximum number of finger slots that the device can report in one
|
|
// HardwareState struct.
|
|
unsigned short max_finger_cnt;
|
|
// The maximum number of contacts that the device can detect at once, whether
|
|
// or not it can report their coordinates.
|
|
unsigned short max_touch_cnt;
|
|
|
|
// Whether this is a "Track 5, Report 2" touchpad, which can track up to five
|
|
// fingers but only report the locations of two. (For more details, see
|
|
// https://crrev.com/37cccb42e652b50f9e788d90e82252f78c78f1ed)
|
|
unsigned supports_t5r2:1;
|
|
|
|
// Whether this is a "Semi-Multitouch" touchpad, which can detect two separate
|
|
// fingers but only report their bounding box, not individual locations.
|
|
unsigned support_semi_mt:1;
|
|
|
|
// Whether the touchpad has a button under its touch surface, allowing the
|
|
// user to click by pressing (almost) anywhere on the pad, as opposed to
|
|
// having one or more separate buttons for clicking.
|
|
unsigned is_button_pad:1;
|
|
|
|
// Mouse properties
|
|
// Whether the mouse has a scroll wheel.
|
|
unsigned has_wheel:1;
|
|
// Whether the mouse's scroll wheel is high-resolution (reported through the
|
|
// rel_wheel_hi_res field of the HardwareState struct).
|
|
unsigned wheel_is_hi_res:1;
|
|
|
|
// Whether the touchpad is haptic, meaning that it reports true pressure (not
|
|
// just touch area) via the pressure axis, and can provide haptic feedback.
|
|
unsigned is_haptic_pad:1;
|
|
#ifdef __cplusplus
|
|
std::string String() const;
|
|
#endif // __cplusplus
|
|
};
|
|
|
|
// Warp: If a finger has the 'warp' flag set for an axis, it means that while
|
|
// the finger may have moved, it should not cause any motion in that direction.
|
|
// This may occur is some situations where we thought a finger was in one place,
|
|
// but then we realized later it was actually in another place.
|
|
// The *_WARP_X/Y_MOVE version is an indication for suppressing unwanted
|
|
// cursor movement, while the *_WARP_X/Y_NON_MOVE version is for unwanted
|
|
// non-cursor movement (e.g. scrolling)
|
|
#define GESTURES_FINGER_WARP_X_NON_MOVE (1 << 0)
|
|
#define GESTURES_FINGER_WARP_Y_NON_MOVE (1 << 1)
|
|
// If a finger has notap set, it shouldn't begin a tap gesture.
|
|
#define GESTURES_FINGER_NO_TAP (1 << 2)
|
|
#define GESTURES_FINGER_POSSIBLE_PALM (1 << 3)
|
|
#define GESTURES_FINGER_PALM (1 << 4)
|
|
#define GESTURES_FINGER_WARP_X_MOVE (1 << 5)
|
|
#define GESTURES_FINGER_WARP_Y_MOVE (1 << 6)
|
|
// If tap to click movement detection should warp:
|
|
#define GESTURES_FINGER_WARP_X_TAP_MOVE (1 << 7)
|
|
#define GESTURES_FINGER_WARP_Y_TAP_MOVE (1 << 8)
|
|
// If a finger is a merged finger or one of close fingers
|
|
#define GESTURES_FINGER_MERGE (1 << 9)
|
|
// If a finger is showing a trend of moving (see the TrendClassifyingFilter).
|
|
#define GESTURES_FINGER_TREND_INC_X (1 << 10)
|
|
#define GESTURES_FINGER_TREND_DEC_X (1 << 11)
|
|
#define GESTURES_FINGER_TREND_INC_Y (1 << 12)
|
|
#define GESTURES_FINGER_TREND_DEC_Y (1 << 13)
|
|
#define GESTURES_FINGER_TREND_INC_PRESSURE (1 << 14)
|
|
#define GESTURES_FINGER_TREND_DEC_PRESSURE (1 << 15)
|
|
#define GESTURES_FINGER_TREND_INC_TOUCH_MAJOR (1 << 16)
|
|
#define GESTURES_FINGER_TREND_DEC_TOUCH_MAJOR (1 << 17)
|
|
// If a finger is non-stationary recently (see the StationaryWiggleFilter).
|
|
// Compared to the trend flags, this one takes the magnitude of movements
|
|
// into account so it might be more useful in some cases. However, it is also
|
|
// more prone to abrupt noisy jumps than the trend flags. It also looks at
|
|
// a shorter period of time than the trend ones so it may provide faster
|
|
// response and lower latency.
|
|
#define GESTURES_FINGER_INSTANTANEOUS_MOVING (1 << 18)
|
|
// We sometimes use the warp flags only because we want to suppress unwanted
|
|
// movements and not that we really have no good idea of the finger position.
|
|
// This poses additional difficulty for some classifying logics that relies
|
|
// much on the finger position. To maximize the use of any available data,
|
|
// we further mark a finger as GESTURES_FINGER_WARP_TELEPORTATION only if we
|
|
// indeed have no idea of its position (e.g. due to sensor jumps). For all
|
|
// other cases (e.g. click wiggle, plams suppression, stationary wiggle), we
|
|
// skip the flag so that we can have the option to use the not-that-accurate
|
|
// positions.
|
|
#define GESTURES_FINGER_WARP_TELEPORTATION (1 << 19)
|
|
#define GESTURES_FINGER_LARGE_PALM (1 << 20)
|
|
|
|
#define GESTURES_FINGER_WARP_X (GESTURES_FINGER_WARP_X_NON_MOVE | \
|
|
GESTURES_FINGER_WARP_X_MOVE)
|
|
#define GESTURES_FINGER_WARP_Y (GESTURES_FINGER_WARP_Y_NON_MOVE | \
|
|
GESTURES_FINGER_WARP_Y_MOVE)
|
|
|
|
// Describes a single contact on a touch surface. Generally, the fields have the
|
|
// same meaning as the equivalent ABS_MT_... axis in the Linux evdev protocol.
|
|
struct FingerState {
|
|
// The large and small radii of the ellipse of the finger touching the pad.
|
|
float touch_major, touch_minor;
|
|
|
|
// The large and small radii of the ellipse of the finger, including parts
|
|
// that are hovering over the pad but not quite touching. Devices normally
|
|
// don't report these values, in which case they should be left at 0.
|
|
float width_major, width_minor;
|
|
float pressure;
|
|
float orientation;
|
|
|
|
float position_x;
|
|
float position_y;
|
|
|
|
// A number that identifies a single physical finger across consecutive
|
|
// frames. If a finger is the same physical finger across two consecutive
|
|
// frames, it must have the same tracking ID; if it's a different finger, it
|
|
// should have a different tracking ID. It should be ≥ 0 (see documentation
|
|
// comment for HardwareState::fingers).
|
|
short tracking_id;
|
|
|
|
// A bit field of flags that are used internally by the library. (See the
|
|
// GESTURES_FINGER_* constants.) Should be set to 0 on incoming FingerStates.
|
|
unsigned flags;
|
|
#ifdef __cplusplus
|
|
bool NonFlagsEquals(const FingerState& that) const {
|
|
return touch_major == that.touch_major &&
|
|
touch_minor == that.touch_minor &&
|
|
width_major == that.width_major &&
|
|
width_minor == that.width_minor &&
|
|
pressure == that.pressure &&
|
|
orientation == that.orientation &&
|
|
position_x == that.position_x &&
|
|
position_y == that.position_y &&
|
|
tracking_id == that.tracking_id;
|
|
}
|
|
bool operator==(const FingerState& that) const {
|
|
return NonFlagsEquals(that) && flags == that.flags;
|
|
}
|
|
bool operator!=(const FingerState& that) const { return !(*this == that); }
|
|
static std::string FlagsString(unsigned flags);
|
|
std::string String() const;
|
|
#endif
|
|
};
|
|
|
|
#define GESTURES_BUTTON_NONE 0
|
|
#define GESTURES_BUTTON_LEFT 1
|
|
#define GESTURES_BUTTON_MIDDLE 2
|
|
#define GESTURES_BUTTON_RIGHT 4
|
|
#define GESTURES_BUTTON_BACK 8
|
|
#define GESTURES_BUTTON_FORWARD 16
|
|
|
|
// Describes one frame of data from the input device.
|
|
struct HardwareState {
|
|
#ifdef __cplusplus
|
|
FingerState* GetFingerState(short tracking_id);
|
|
const FingerState* GetFingerState(short tracking_id) const;
|
|
bool SameFingersAs(const HardwareState& that) const;
|
|
std::string String() const;
|
|
void DeepCopy(const HardwareState& that, unsigned short max_finger_cnt);
|
|
#endif // __cplusplus
|
|
// The time at which the event was received by the system.
|
|
stime_t timestamp;
|
|
// A bit field indicating which buttons are pressed. (See the
|
|
// GESTURES_BUTTON_* constants.)
|
|
int buttons_down;
|
|
// The number of FingerState structs pointed to by the fingers field.
|
|
unsigned short finger_cnt;
|
|
// The number of fingers touching the pad, which may be more than finger_cnt.
|
|
unsigned short touch_cnt;
|
|
// A pointer to an array of FingerState structs with finger_cnt entries,
|
|
// representing the contacts currently being tracked. The order in which
|
|
// FingerStates appear need not be stable between HardwareStates — only the
|
|
// tracking ID is used to track individual contacts over time. Accordingly,
|
|
// when a finger is lifted from the pad (and therefore its ABS_MT_TRACKING_ID
|
|
// becomes -1), the client should simply stop including it in this array,
|
|
// rather than including a final FingerState for it.
|
|
struct FingerState* fingers;
|
|
|
|
// Mouse axes, which have the same meanings as the Linux evdev axes of the
|
|
// same name.
|
|
float rel_x;
|
|
float rel_y;
|
|
float rel_wheel;
|
|
float rel_wheel_hi_res;
|
|
float rel_hwheel;
|
|
|
|
// The timestamp for the frame, as reported by the device's firmware. This may
|
|
// be different from the timestamp field above, for example if events were
|
|
// batched when being sent over Bluetooth. Set to 0.0 if no such timestamp is
|
|
// available. (Named after the MSC_TIMESTAMP axis from evdev.)
|
|
stime_t msc_timestamp;
|
|
};
|
|
|
|
#define GESTURES_FLING_START 0 // Scroll end/fling begin
|
|
#define GESTURES_FLING_TAP_DOWN 1 // Finger touched down/fling end
|
|
|
|
#define GESTURES_ZOOM_START 0 // Pinch zoom begin
|
|
#define GESTURES_ZOOM_UPDATE 1 // Zoom-in/Zoom-out update
|
|
#define GESTURES_ZOOM_END 2 // Pinch zoom end
|
|
|
|
// Gesture sub-structs
|
|
|
|
// Note about ordinal_* values: Sometimes, UI will want to use unaccelerated
|
|
// values for various gestures, so we expose the non-accelerated values in
|
|
// the ordinal_* fields.
|
|
|
|
typedef struct {
|
|
// The movement in the X axis. Positive values indicate motion to the right.
|
|
float dx;
|
|
// The movement in the Y axis. Positive values indicate downwards motion.
|
|
float dy;
|
|
float ordinal_dx, ordinal_dy;
|
|
} GestureMove;
|
|
|
|
// Represents scroll gestures on a touch device.
|
|
typedef struct{
|
|
// The scroll movement in the X axis. Unlike with move gestures, *negative*
|
|
// values indicate the fingers moving to the right, unless the "Australian
|
|
// Scrolling" or "Invert Scrolling" properties are set.
|
|
float dx;
|
|
// The scroll movement in the Y axis. Unlike with move gestures, *negative*
|
|
// values indicate the fingers moving downwards, unless the "Australian
|
|
// Scrolling" or "Invert Scrolling" properties are set.
|
|
float dy;
|
|
float ordinal_dx, ordinal_dy;
|
|
// If set, stop_fling means that this scroll should stop flinging, thus
|
|
// if an interpreter suppresses it for any reason (e.g., rounds the size
|
|
// down to 0, thus making it a noop), it will replace it with a Fling
|
|
// TAP_DOWN gesture
|
|
unsigned stop_fling:1;
|
|
} GestureScroll;
|
|
|
|
// Represents mouse wheel movements.
|
|
typedef struct {
|
|
// The amount to scroll by, after acceleration and scaling have been applied.
|
|
float dx, dy;
|
|
// The amount the wheel actually moved. A change of 120 represents moving the
|
|
// wheel one whole tick (a.k.a. notch).
|
|
int tick_120ths_dx, tick_120ths_dy;
|
|
} GestureMouseWheel;
|
|
|
|
typedef struct {
|
|
// If a bit is set in both down and up, client should process down first
|
|
unsigned down; // bit field, use GESTURES_BUTTON_*
|
|
unsigned up; // bit field, use GESTURES_BUTTON_*
|
|
bool is_tap; // was the gesture generated with tap-to-click?
|
|
} GestureButtonsChange;
|
|
|
|
typedef struct {
|
|
// The fling velocity in the X axis, only valid when fling_state is
|
|
// GESTURES_FLING_START. Unlike with move gestures, *negative* values indicate
|
|
// the fingers moving to the right, unless the "Australian Scrolling" or
|
|
// "Invert Scrolling" properties are set.
|
|
float vx;
|
|
// The fling velocity in the Y axis, only valid when fling_state is
|
|
// GESTURES_FLING_START. Unlike with move gestures, *negative* values indicate
|
|
// the fingers moving downwards, unless the "Australian Scrolling" or "Invert
|
|
// Scrolling" properties are set.
|
|
float vy;
|
|
float ordinal_vx, ordinal_vy;
|
|
unsigned fling_state:1; // GESTURES_FLING_START or GESTURES_FLING_TAP_DOWN
|
|
} GestureFling;
|
|
|
|
typedef struct {
|
|
// The swipe movement in the X axis. Positive values indicate motion to the
|
|
// right.
|
|
float dx;
|
|
// The swipe movement in the Y axis. Unlike with move gestures, *negative*
|
|
// values indicate downwards motion, unless the "Australian Scrolling"
|
|
// property is set.
|
|
float dy;
|
|
float ordinal_dx, ordinal_dy;
|
|
} GestureSwipe;
|
|
|
|
typedef struct {
|
|
// The swipe movement in the X axis. Positive values indicate motion to the
|
|
// right.
|
|
float dx;
|
|
// The swipe movement in the Y axis. Unlike with move gestures, *negative*
|
|
// values indicate downwards motion, unless the "Australian Scrolling"
|
|
// property is set.
|
|
float dy;
|
|
float ordinal_dx, ordinal_dy;
|
|
} GestureFourFingerSwipe;
|
|
|
|
typedef struct {
|
|
char __dummy;
|
|
// Remove this when there is a member in this struct. http://crbug.com/341155
|
|
// Currently no members
|
|
} GestureFourFingerSwipeLift;
|
|
|
|
typedef struct {
|
|
char __dummy;
|
|
// Remove this when there is a member in this struct. http://crbug.com/341155
|
|
// Currently no members
|
|
} GestureSwipeLift;
|
|
|
|
typedef struct {
|
|
// Relative pinch factor starting with 1.0 = no pinch
|
|
// <1.0 for outwards pinch
|
|
// >1.0 for inwards pinch
|
|
float dz;
|
|
float ordinal_dz;
|
|
// GESTURES_ZOOM_START, GESTURES_ZOOM_UPDATE, or GESTURES_ZOOM_END
|
|
unsigned zoom_state;
|
|
} GesturePinch;
|
|
|
|
// Metrics types that we care about
|
|
enum GestureMetricsType {
|
|
kGestureMetricsTypeNoisyGround = 0,
|
|
kGestureMetricsTypeMouseMovement,
|
|
kGestureMetricsTypeUnknown,
|
|
};
|
|
|
|
typedef struct {
|
|
enum GestureMetricsType type;
|
|
// Optional values for the metrics. 2 are more than enough for now.
|
|
float data[2];
|
|
} GestureMetrics;
|
|
|
|
// Describes the type of gesture that is being reported.
|
|
enum GestureType {
|
|
#ifdef GESTURES_INTERNAL
|
|
kGestureTypeNull = -1, // internal to Gestures library only
|
|
#endif // GESTURES_INTERNAL
|
|
// No longer used.
|
|
kGestureTypeContactInitiated = 0,
|
|
// For touchpads, a movement of a single finger on the pad. For mice, a
|
|
// movement of the whole mouse.
|
|
kGestureTypeMove,
|
|
// A two-finger scroll gesture on a touchpad. (See kGestureTypeMouseWheel for
|
|
// the mouse equivalent.)
|
|
kGestureTypeScroll,
|
|
// A change in the buttons that are currently pressed on the device.
|
|
kGestureTypeButtonsChange,
|
|
// The start or end of a fling motion, where scrolling should continue after
|
|
// the user's fingers have left the touchpad.
|
|
kGestureTypeFling,
|
|
// A movement of three fingers on a touchpad.
|
|
kGestureTypeSwipe,
|
|
// A movement of two fingers on a touchpad that are primarily moving closer to
|
|
// or further from each other.
|
|
kGestureTypePinch,
|
|
// The end of a movement of three fingers on a touchpad.
|
|
kGestureTypeSwipeLift,
|
|
// Used to report metrics to the client.
|
|
kGestureTypeMetrics,
|
|
// A movement of four fingers on a touchpad.
|
|
kGestureTypeFourFingerSwipe,
|
|
// The end of a movement of four fingers on a touchpad.
|
|
kGestureTypeFourFingerSwipeLift,
|
|
// The movement of a scroll wheel on a mouse.
|
|
kGestureTypeMouseWheel,
|
|
};
|
|
|
|
#ifdef __cplusplus
|
|
// Pass these into Gesture() ctor as first arg
|
|
extern const GestureMove kGestureMove;
|
|
extern const GestureScroll kGestureScroll;
|
|
extern const GestureMouseWheel kGestureMouseWheel;
|
|
extern const GestureButtonsChange kGestureButtonsChange;
|
|
extern const GestureFling kGestureFling;
|
|
extern const GestureSwipe kGestureSwipe;
|
|
extern const GestureFourFingerSwipe kGestureFourFingerSwipe;
|
|
extern const GesturePinch kGesturePinch;
|
|
extern const GestureSwipeLift kGestureSwipeLift;
|
|
extern const GestureFourFingerSwipeLift kGestureFourFingerSwipeLift;
|
|
extern const GestureMetrics kGestureMetrics;
|
|
#endif // __cplusplus
|
|
|
|
struct Gesture {
|
|
#ifdef __cplusplus
|
|
// Create Move/Scroll gesture
|
|
#ifdef GESTURES_INTERNAL
|
|
Gesture() : start_time(0), end_time(0), type(kGestureTypeNull) {}
|
|
bool operator==(const Gesture& that) const;
|
|
bool operator!=(const Gesture& that) const { return !(*this == that); };
|
|
#endif // GESTURES_INTERNAL
|
|
std::string String() const;
|
|
Gesture(const GestureMove&, stime_t start, stime_t end, float dx, float dy)
|
|
: start_time(start), end_time(end), type(kGestureTypeMove) {
|
|
details.move.ordinal_dx = details.move.dx = dx;
|
|
details.move.ordinal_dy = details.move.dy = dy;
|
|
}
|
|
Gesture(const GestureScroll&,
|
|
stime_t start, stime_t end, float dx, float dy)
|
|
: start_time(start), end_time(end), type(kGestureTypeScroll) {
|
|
details.scroll.ordinal_dx = details.scroll.dx = dx;
|
|
details.scroll.ordinal_dy = details.scroll.dy = dy;
|
|
details.scroll.stop_fling = 0;
|
|
}
|
|
Gesture(const GestureMouseWheel&,
|
|
stime_t start, stime_t end, float dx, float dy, int tick_120ths_dx,
|
|
int tick_120ths_dy)
|
|
: start_time(start), end_time(end), type(kGestureTypeMouseWheel) {
|
|
details.wheel.dx = dx;
|
|
details.wheel.dy = dy;
|
|
details.wheel.tick_120ths_dx = tick_120ths_dx;
|
|
details.wheel.tick_120ths_dy = tick_120ths_dy;
|
|
}
|
|
Gesture(const GestureButtonsChange&,
|
|
stime_t start, stime_t end, unsigned down, unsigned up, bool is_tap)
|
|
: start_time(start),
|
|
end_time(end),
|
|
type(kGestureTypeButtonsChange) {
|
|
details.buttons.down = down;
|
|
details.buttons.up = up;
|
|
details.buttons.is_tap = is_tap;
|
|
}
|
|
Gesture(const GestureFling&,
|
|
stime_t start, stime_t end, float vx, float vy, unsigned state)
|
|
: start_time(start), end_time(end), type(kGestureTypeFling) {
|
|
details.fling.ordinal_vx = details.fling.vx = vx;
|
|
details.fling.ordinal_vy = details.fling.vy = vy;
|
|
details.fling.fling_state = state;
|
|
}
|
|
Gesture(const GestureSwipe&,
|
|
stime_t start, stime_t end, float dx, float dy)
|
|
: start_time(start),
|
|
end_time(end),
|
|
type(kGestureTypeSwipe) {
|
|
details.swipe.ordinal_dx = details.swipe.dx = dx;
|
|
details.swipe.ordinal_dy = details.swipe.dy = dy;
|
|
}
|
|
Gesture(const GestureFourFingerSwipe&,
|
|
stime_t start, stime_t end, float dx, float dy)
|
|
: start_time(start),
|
|
end_time(end),
|
|
type(kGestureTypeFourFingerSwipe) {
|
|
details.four_finger_swipe.ordinal_dx = details.four_finger_swipe.dx = dx;
|
|
details.four_finger_swipe.ordinal_dy = details.four_finger_swipe.dy = dy;
|
|
}
|
|
Gesture(const GesturePinch&,
|
|
stime_t start, stime_t end, float dz, unsigned state)
|
|
: start_time(start),
|
|
end_time(end),
|
|
type(kGestureTypePinch) {
|
|
details.pinch.ordinal_dz = details.pinch.dz = dz;
|
|
details.pinch.zoom_state = state;
|
|
}
|
|
Gesture(const GestureSwipeLift&, stime_t start, stime_t end)
|
|
: start_time(start),
|
|
end_time(end),
|
|
type(kGestureTypeSwipeLift) {}
|
|
Gesture(const GestureFourFingerSwipeLift&, stime_t start, stime_t end)
|
|
: start_time(start),
|
|
end_time(end),
|
|
type(kGestureTypeFourFingerSwipeLift) {}
|
|
Gesture(const GestureMetrics&,
|
|
stime_t start, stime_t end, GestureMetricsType m_type,
|
|
float d1, float d2)
|
|
: start_time(start),
|
|
end_time(end),
|
|
type(kGestureTypeMetrics) {
|
|
details.metrics.type = m_type;
|
|
details.metrics.data[0] = d1;
|
|
details.metrics.data[1] = d2;
|
|
}
|
|
#endif // __cplusplus
|
|
|
|
stime_t start_time, end_time;
|
|
enum GestureType type;
|
|
union {
|
|
GestureMove move;
|
|
GestureScroll scroll;
|
|
GestureMouseWheel wheel;
|
|
GestureButtonsChange buttons;
|
|
GestureFling fling;
|
|
GestureSwipe swipe;
|
|
GesturePinch pinch;
|
|
GestureSwipeLift swipe_lift;
|
|
GestureMetrics metrics;
|
|
GestureFourFingerSwipe four_finger_swipe;
|
|
GestureFourFingerSwipeLift four_finger_swipe_lift;
|
|
} details;
|
|
};
|
|
|
|
typedef void (*GestureReadyFunction)(void* client_data,
|
|
const struct Gesture* gesture);
|
|
|
|
// Gestures Timer Provider Interface
|
|
struct GesturesTimer;
|
|
typedef struct GesturesTimer GesturesTimer;
|
|
|
|
// If this returns < 0, the timer should be freed. If it returns >= 0.0, it
|
|
// should be called again after that amount of delay.
|
|
typedef stime_t (*GesturesTimerCallback)(stime_t now,
|
|
void* callback_data);
|
|
// Allocate and return a new timer, or NULL if error.
|
|
typedef GesturesTimer* (*GesturesTimerCreate)(void* data);
|
|
// Set a timer:
|
|
typedef void (*GesturesTimerSet)(void* data,
|
|
GesturesTimer* timer,
|
|
stime_t delay,
|
|
GesturesTimerCallback callback,
|
|
void* callback_data);
|
|
// Cancel a set timer:
|
|
typedef void (*GesturesTimerCancel)(void* data, GesturesTimer* timer);
|
|
// Free the timer. Will not be called from within a timer callback.
|
|
typedef void (*GesturesTimerFree)(void* data, GesturesTimer* timer);
|
|
|
|
typedef struct {
|
|
GesturesTimerCreate create_fn;
|
|
GesturesTimerSet set_fn;
|
|
GesturesTimerCancel cancel_fn;
|
|
GesturesTimerFree free_fn;
|
|
} GesturesTimerProvider;
|
|
|
|
// Gestures Property Provider Interface
|
|
struct GesturesProp;
|
|
typedef struct GesturesProp GesturesProp;
|
|
|
|
typedef unsigned char GesturesPropBool;
|
|
|
|
// These functions create a named property of given type.
|
|
// data - data used by PropProvider
|
|
// loc - location of a variable to be updated by PropProvider
|
|
// (Chromium calls its own GesturesPropCreate... functions with loc set
|
|
// to null to create read-only properties, but the Gestures library
|
|
// itself doesn't, so other clients don't need to support them.)
|
|
// init - initial value for the property.
|
|
// If the PropProvider has an alternate configuration source, it may
|
|
// override this initial value, in which case *loc returns the
|
|
// value from the configuration source.
|
|
typedef GesturesProp* (*GesturesPropCreateInt)(void* data, const char* name,
|
|
int* loc, size_t count,
|
|
const int* init);
|
|
|
|
// Deprecated: the gestures library no longer uses short gesture properties.
|
|
typedef GesturesProp* (*GesturesPropCreateShort_Deprecated)(
|
|
void*, const char*, short*, size_t, const short*);
|
|
|
|
typedef GesturesProp* (*GesturesPropCreateBool)(void* data, const char* name,
|
|
GesturesPropBool* loc,
|
|
size_t count,
|
|
const GesturesPropBool* init);
|
|
|
|
typedef GesturesProp* (*GesturesPropCreateString)(void* data, const char* name,
|
|
const char** loc,
|
|
const char* const init);
|
|
|
|
typedef GesturesProp* (*GesturesPropCreateReal)(void* data, const char* name,
|
|
double* loc, size_t count,
|
|
const double* init);
|
|
|
|
// A function to call just before a property is to be read.
|
|
// |handler_data| is a local context pointer that can be used by the handler.
|
|
// Handler should return non-zero if it modifies the property's value.
|
|
typedef GesturesPropBool (*GesturesPropGetHandler)(void* handler_data);
|
|
|
|
// A function to call just after a property's value is updated.
|
|
// |handler_data| is a local context pointer that can be used by the handler.
|
|
typedef void (*GesturesPropSetHandler)(void* handler_data);
|
|
|
|
// Register handlers for the client to call when a GesturesProp is accessed.
|
|
//
|
|
// The get handler, if not NULL, should be called immediately before the
|
|
// property's value is to be read. This gives the library a chance to update its
|
|
// value.
|
|
//
|
|
// The set handler, if not NULL, should be called immediately after the
|
|
// property's value is updated. This can be used to create a property that is
|
|
// used to trigger an action, or to force an update to multiple properties
|
|
// atomically.
|
|
//
|
|
// Note: the handlers are called from non-signal/interrupt context
|
|
typedef void (*GesturesPropRegisterHandlers)(void* data, GesturesProp* prop,
|
|
void* handler_data,
|
|
GesturesPropGetHandler getter,
|
|
GesturesPropSetHandler setter);
|
|
|
|
// Free a property.
|
|
typedef void (*GesturesPropFree)(void* data, GesturesProp* prop);
|
|
|
|
typedef struct GesturesPropProvider {
|
|
GesturesPropCreateInt create_int_fn;
|
|
// Deprecated: the library no longer uses short gesture properties, so this
|
|
// function pointer should be null.
|
|
GesturesPropCreateShort_Deprecated create_short_fn;
|
|
GesturesPropCreateBool create_bool_fn;
|
|
GesturesPropCreateString create_string_fn;
|
|
GesturesPropCreateReal create_real_fn;
|
|
GesturesPropRegisterHandlers register_handlers_fn;
|
|
GesturesPropFree free_fn;
|
|
} GesturesPropProvider;
|
|
|
|
#ifdef __cplusplus
|
|
// C++ API:
|
|
|
|
namespace gestures {
|
|
|
|
class Interpreter;
|
|
class PropRegistry;
|
|
class LoggingFilterInterpreter;
|
|
class Tracer;
|
|
class GestureInterpreterConsumer;
|
|
class MetricsProperties;
|
|
|
|
#if __cplusplus >= 201103L
|
|
|
|
struct GestureInterpreter {
|
|
public:
|
|
explicit GestureInterpreter(int version);
|
|
~GestureInterpreter();
|
|
void PushHardwareState(HardwareState* hwstate);
|
|
|
|
void SetHardwareProperties(const HardwareProperties& hwprops);
|
|
|
|
void TimerCallback(stime_t now, stime_t* timeout);
|
|
|
|
void SetCallback(GestureReadyFunction callback, void* client_data);
|
|
// Deprecated; use SetCallback instead.
|
|
void set_callback(GestureReadyFunction callback,
|
|
void* client_data);
|
|
void SetTimerProvider(GesturesTimerProvider* tp, void* data);
|
|
void SetPropProvider(GesturesPropProvider* pp, void* data);
|
|
|
|
// Initialize GestureInterpreter based on device configuration. This must be
|
|
// called after GesturesPropProvider is set and before it accepts any inputs.
|
|
void Initialize(
|
|
GestureInterpreterDeviceClass type=GESTURES_DEVCLASS_TOUCHPAD);
|
|
|
|
Interpreter* interpreter() const { return interpreter_.get(); }
|
|
PropRegistry* prop_reg() const { return prop_reg_.get(); }
|
|
|
|
std::string EncodeActivityLog();
|
|
private:
|
|
void InitializeTouchpad(void);
|
|
void InitializeTouchpad2(void);
|
|
void InitializeMouse(GestureInterpreterDeviceClass cls);
|
|
void InitializeMultitouchMouse(void);
|
|
|
|
GestureReadyFunction callback_;
|
|
void* callback_data_;
|
|
|
|
std::unique_ptr<PropRegistry> prop_reg_;
|
|
std::unique_ptr<Tracer> tracer_;
|
|
std::unique_ptr<Interpreter> interpreter_;
|
|
std::unique_ptr<MetricsProperties> mprops_;
|
|
|
|
GesturesTimerProvider* timer_provider_;
|
|
void* timer_provider_data_;
|
|
GesturesTimer* interpret_timer_;
|
|
|
|
LoggingFilterInterpreter* loggingFilter_;
|
|
std::unique_ptr<GestureInterpreterConsumer> consumer_;
|
|
HardwareProperties hwprops_;
|
|
|
|
// Disallow copy & assign;
|
|
GestureInterpreter(const GestureInterpreter&);
|
|
void operator=(const GestureInterpreter&);
|
|
};
|
|
|
|
#else // __cplusplus >= 201103L
|
|
|
|
// Must be opaque under C++03 builds, since it has unique_ptr members.
|
|
struct GestureInterpreter;
|
|
|
|
#endif // __cplusplus >= 201103L
|
|
|
|
|
|
} // namespace gestures
|
|
|
|
typedef gestures::GestureInterpreter GestureInterpreter;
|
|
#else
|
|
struct GestureInterpreter;
|
|
typedef struct GestureInterpreter GestureInterpreter;
|
|
#endif // __cplusplus
|
|
|
|
#define GESTURES_VERSION 1
|
|
GestureInterpreter* NewGestureInterpreterImpl(int);
|
|
#define NewGestureInterpreter() NewGestureInterpreterImpl(GESTURES_VERSION)
|
|
|
|
void DeleteGestureInterpreter(GestureInterpreter*);
|
|
|
|
void GestureInterpreterSetHardwareProperties(GestureInterpreter*,
|
|
const struct HardwareProperties*);
|
|
|
|
void GestureInterpreterPushHardwareState(GestureInterpreter*,
|
|
struct HardwareState*);
|
|
|
|
void GestureInterpreterSetCallback(GestureInterpreter*,
|
|
GestureReadyFunction,
|
|
void*);
|
|
|
|
// Gestures will hold a reference to passed provider. Pass NULL to tell
|
|
// Gestures to stop holding a reference.
|
|
void GestureInterpreterSetTimerProvider(GestureInterpreter*,
|
|
GesturesTimerProvider*,
|
|
void*);
|
|
|
|
void GestureInterpreterSetPropProvider(GestureInterpreter*,
|
|
GesturesPropProvider*,
|
|
void*);
|
|
|
|
void GestureInterpreterInitialize(GestureInterpreter*,
|
|
enum GestureInterpreterDeviceClass);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // GESTURES_GESTURES_H__
|