grail.h | grail.h | |||
---|---|---|---|---|
/************************************************************************** *** | /************************************************************************** *** | |||
* | * | |||
* grail - Gesture Recognition And Instantiation Library | * grail - Multitouch Gesture Recognition Library | |||
* | * | |||
* Copyright (C) 2010-2011 Canonical Ltd. | * Copyright (C) 2010-2011 Canonical Ltd. | |||
* | * | |||
* This program is free software: you can redistribute it and/or modify it | * This program is free software: you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License as published by the | * under the terms of the GNU General Public License as published by the | |||
* Free Software Foundation, either version 3 of the License, or (at your | * Free Software Foundation, either version 3 of the License, or (at your | |||
* option) any later version. | * option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, but | * This program is distributed in the hope that it will be useful, but | |||
* WITHOUT ANY WARRANTY; without even the implied warranty of | * WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* General Public License for more details. | * General Public License for more details. | |||
* | * | |||
* You should have received a copy of the GNU General Public License along | * You should have received a copy of the GNU General Public License along | |||
* with this program. If not, see <http://www.gnu.org/licenses/>. | * with this program. If not, see <http://www.gnu.org/licenses/>. | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef GRAIL_H | ||||
#define GRAIL_H | ||||
#include <linux/input.h> | ||||
#include <grail-bits.h> | ||||
#include <grail-types.h> | ||||
#include <utouch/frame.h> | ||||
#ifdef __cplusplus | ||||
extern "C" { | ||||
#endif | ||||
#define GRAIL_VERSION 0x00011000 | ||||
#define DIM_GRAIL_TYPE 64 | ||||
#define DIM_GRAIL_TYPE_BYTES ((DIM_GRAIL_TYPE + 7) >> 3) | ||||
#define DIM_GRAIL_PROP 32 | ||||
#define DIM_GRAIL_PROP_BYTES ((DIM_GRAIL_PROP + 7) >> 3) | ||||
#define GRAIL_STATUS_BEGIN 0 | ||||
#define GRAIL_STATUS_UPDATE 1 | ||||
#define GRAIL_STATUS_END 2 | ||||
#define GRAIL_EXPECT_DRAG_X 0x0001 | ||||
#define GRAIL_EXPECT_DRAG_Y 0x0002 | ||||
#define GRAIL_EXPECT_SCALE 0x0004 | ||||
#define GRAIL_EXPECT_ANGLE 0x0008 | ||||
#define GRAIL_EXPECT_MASK 0x000f | ||||
typedef float grail_prop_t; /* gesture properties */ | ||||
typedef utouch_frame_time_t grail_time_t; /* time in milliseconds */ | ||||
typedef struct grail *grail_handle; /* the grail instance handle | ||||
*/ | ||||
/** | ||||
* struct grail_get_version - get grail library version | ||||
* | ||||
* Report the version of the grail library, which can be different from | ||||
* the value of GRAIL_VERSION in this header file. | ||||
* | ||||
* This function allows for fallback options from major interface | ||||
* extensions within the same ABI version. For the normal cases of ABI | ||||
* agnostic or backwards incompatible changes, this function is not | ||||
* needed. | ||||
*/ | ||||
unsigned int GRAIL_PUBLIC grail_get_version(void); | ||||
/** | ||||
* struct grail_coord - coordinate in bounding box units | ||||
* @x: the horizontal position (bbox units) | ||||
* @y: the vertical position (bbox units) | ||||
*/ | ||||
struct grail_coord { | ||||
float x, y; | ||||
}; | ||||
grail_handle GRAIL_PUBLIC grail_new_raw(utouch_frame_handle fh, | ||||
unsigned int num_frames, | ||||
void *select, | ||||
unsigned int version, | ||||
unsigned int control_size, | ||||
unsigned int frame_size, | ||||
unsigned int slot_size); | ||||
/** | ||||
* grail_new - allocate and initialize a new grail instance | ||||
* @fh: utouch frame handle to use | ||||
* @num_frames: number of frames in cyclic buffer | ||||
* @select: client selection callback | ||||
* | ||||
* Initialize the internal grail structures. | ||||
* | ||||
* Returns zero in case of failure. | ||||
*/ | ||||
#define grail_new(fh, num_frames, select) \ | ||||
grail_new_raw(fh, num_frames, select, \ | ||||
GRAIL_VERSION, \ | ||||
sizeof(struct grail_control), \ | ||||
sizeof(struct grail_frame), \ | ||||
sizeof(struct grail_element)) | ||||
/** | ||||
* grail_delete - destroy and delete grail instance | ||||
* @ge: grail instance in use | ||||
* | ||||
* Deallocates all internal memory structures. | ||||
*/ | ||||
void GRAIL_PUBLIC grail_delete(grail_handle ge); | ||||
/** | ||||
* grail_get_control - get mutable control structure | ||||
* @ge: the grail device in use | ||||
* | ||||
* Return the control struct of the grail instance. | ||||
* | ||||
* The control pointer is ABI agnostic, owned by the grail instance, and | ||||
* has grail scope. | ||||
*/ | ||||
struct grail_control GRAIL_PUBLIC *grail_get_control(grail_handle ge); | ||||
/** | ||||
* grail_pump_frame - insert touch frames into grail | ||||
* @ge: the grail device in use | ||||
* @frame: the touch frame to insert | ||||
* | ||||
* Insert a new touch frame into the grail engine. If the frame induces a | ||||
* new gesture frame, a pointer to the frame is returned. | ||||
* | ||||
* The grail frame pointer is ABI agnostic, owned by the grail instance, an | ||||
d | ||||
* has grail scope. | ||||
*/ | ||||
const struct grail_frame GRAIL_PUBLIC * | ||||
grail_pump_frame(grail_handle ge, const struct utouch_frame *frame); | ||||
/** | ||||
* struct grail_client_id - Gesture client information | ||||
* @client: Client id | ||||
* @root: Root window | ||||
* @event: Window to route events to | ||||
* @child: Window the event occured in | ||||
* | ||||
* This struct is treated opaquely, and only has meaning to the gesture | ||||
* client. Details are subject to change. | ||||
*/ | ||||
struct grail_client_id { | ||||
int client; | ||||
int root, event, child; | ||||
}; | ||||
/** | ||||
* struct grail_client_info - Gesture request information | ||||
* @id: Gesture client id | ||||
* @mask: Gestures the client is listening to | ||||
*/ | ||||
struct grail_client_info { | ||||
struct grail_client_id id; | ||||
grail_mask_t mask[DIM_GRAIL_TYPE_BYTES]; | ||||
}; | ||||
/** | ||||
* struct grail_control - control parameters of grail | ||||
* @glue_ms: minimum time to hold activation (ms) | ||||
* @bar_drag_x: horizontal distance to activate (surface width fraction) | ||||
* @bar_drag_y: vertical distance to activate (surface height fraction) | ||||
* @bar_scale: minimum scaling to activate (fraction) | ||||
* @bar_angle: minimum angle to activate (radians) | ||||
* @drop_x_ms: horizontal expect timeout (ms) | ||||
* @drop_y_ms: vertical expect timeout (ms) | ||||
* @drop_scale_ms: scaling expect timeout (ms) | ||||
* @drop_angle_ms: rotation expect timeout (ms) | ||||
* | ||||
* The parameters are used to tune the behavior of the gesture recognition. | ||||
* | ||||
* The moveness is a number between zero and one denoting the | ||||
* character of the current transform. Zero means pure rotate and | ||||
* scale, one means pure drag. | ||||
* | ||||
* Later versions of this struct may grow in size, but will remain | ||||
* binary compatible with older versions. | ||||
*/ | ||||
struct grail_control { | ||||
float glue_ms; | ||||
float bar_drag_x; | ||||
float bar_drag_y; | ||||
float bar_scale; | ||||
float bar_angle; | ||||
float drop_x_ms; | ||||
float drop_y_ms; | ||||
float drop_scale_ms; | ||||
float drop_angle_ms; | ||||
}; | ||||
/** | ||||
* struct grail_frame - frame of ongoing elementary transformations | ||||
* @prev: pointer to the previous gesture frame | ||||
* @touch: pointer to the touch frame triggering this gesture frame | ||||
* @num_ongoing: number of elements in the ongoing array | ||||
* @ongoing: array of ongoing transformation elements | ||||
* @slots: array of all transformation slots | ||||
* | ||||
* A gesture frame consists of one or several touch frames glued | ||||
* together into a stable transition, combined with information on | ||||
* ongoing elementary gestural transformations. The array of ongoing | ||||
* elements contains all elements with a nonzero expect mask. | ||||
* | ||||
* Later versions of this struct may grow in size, but will remain | ||||
* binary compatible with older versions. | ||||
*/ | ||||
struct grail_frame { | ||||
const struct grail_frame *prev; | ||||
const struct utouch_frame *touch; | ||||
unsigned int num_ongoing; | ||||
struct grail_element **ongoing; | ||||
struct grail_element **slots; | ||||
}; | ||||
/** | ||||
* struct grail_element - elementary gesture transformation | ||||
* @prev: respective element of previous frame | ||||
* @slot: the transformation slot occupied by this element | ||||
* @id: unique identifier of the ongoing transformation | ||||
* @num_touches: number of contacts of this element | ||||
* @touches: array of contacts of this element | ||||
* @start_time: start time of this element | ||||
* @expect_mask: bitmask of expected gestures (grail main types) | ||||
* @active_mask: bitmask of activated gestures (grail main types) | ||||
* @center: gesture center position (surface units) | ||||
* @velocity: current center velocity (surface units per second) | ||||
* @radius: gesture radius from center (surface units) | ||||
* @transform: the transformation matrix of the gesture | ||||
* @rotation_center: current instant center of rotation (surface units) | ||||
* @drag: accumulated transformation displacement (surface units) | ||||
* @scale: accumulated scale (dimensionless) | ||||
* @angle: accumulated rotation angle (radians) | ||||
* | ||||
* The grail element describes the ongoing gestural transformation of | ||||
* a particular set of contacts. The expect mask describes which | ||||
* gestural transformations may become active during the course of | ||||
* events, and the active mask describes which have passed their | ||||
* respective activation threshold. The set of expected gestures can | ||||
* change over time, for instance by exclusion or timeout. | ||||
* | ||||
* Applications handling rotation, either by transformation matrix or | ||||
* angle, should use the drag displacement. For other applications, | ||||
* the center displacement may be used instead, as to not lose | ||||
* movement accuracy. | ||||
* | ||||
* Later versions of this struct may grow in size, but will remain | ||||
* binary compatible with older versions. | ||||
*/ | ||||
struct grail_element { | ||||
const struct grail_element *prev; | ||||
int slot; | ||||
int id; | ||||
int num_touches; | ||||
const struct utouch_contact **touches; | ||||
grail_time_t start_time; | ||||
unsigned int expect_mask; | ||||
unsigned int active_mask; | ||||
struct grail_coord center; | ||||
struct grail_coord velocity; | ||||
float radius2; | ||||
float transform[6]; | ||||
struct grail_coord rotation_center; | ||||
struct grail_coord drag; | ||||
float scale2; | ||||
float angle; | ||||
}; | ||||
/** | ||||
* grail_element_transform - transform coordinates using element | ||||
* @slot: the transformation element to use | ||||
* @q: the grail coordinate to fill | ||||
* @x: the grail coordinate to transform | ||||
* | ||||
* Performs the 3x3 transform *q = T *p, where T is the element | ||||
* transform. | ||||
*/ | ||||
static inline void grail_element_transform(const struct grail_element *slot | ||||
, | ||||
struct grail_coord *q, | ||||
const struct grail_coord *p) | ||||
{ | ||||
const float *T = slot->transform; | ||||
q->x = T[0] * (p->x - slot->center.x) + | ||||
T[1] * (p->y - slot->center.y) + | ||||
T[2] + slot->center.x; | ||||
q->y = T[3] * (p->x - slot->center.x) + | ||||
T[4] * (p->y - slot->center.y) + | ||||
T[5] + slot->center.y; | ||||
} | ||||
/** | ||||
* struct grail_event - Gesture event | ||||
* @type: The gesture type | ||||
* @id: Unique identifier foof the gesture instance | ||||
* @status: Gesture status (begin, update, end) | ||||
* @ntouch: Number of current touches | ||||
* @nprop: Number of properties in the gesture | ||||
* @pos: Focus point of the gesture (bbox coordinates) | ||||
* @touch: Array of individual touch information | ||||
* @client_id: The gesture client to route the gesture to | ||||
* @time: Time of event (milliseconds) | ||||
* @prop: Array of properties of the event | ||||
* | ||||
* Gesture events are passed to the client via the gesture() callback. | ||||
*/ | ||||
struct grail_event { | ||||
int type; | ||||
int id; | ||||
int status; | ||||
int ntouch; | ||||
int nprop; | ||||
struct grail_coord pos; | ||||
struct grail_client_id client_id; | ||||
grail_time_t time; | ||||
grail_prop_t prop[DIM_GRAIL_PROP]; | ||||
}; | ||||
/** | /** | |||
* struct grail - Main grail device | * @file oif/grail.h | |||
* @get_clients: Called at the onset of new gestures to retrieve the list | * Definitions of the main and platform-generic API | |||
* of listening clients. | ||||
* @event: Callback for kernel events passing through grail. | ||||
* @gesture: Main gesture callback. | ||||
* @impl: Grail implementation details. | ||||
* @gin: Gesture instatiation details. | ||||
* @gru: Gesture recognition details. | ||||
* @priv: Generic pointer to user-defined content. | ||||
* | ||||
* The grail device pulls events from the underlying device, detects | ||||
* gestures, and passes them on to the client via the gesture() | ||||
* callback. Events that are not gesture or for other reasons held back are | ||||
* passed on via the event() callback. The user provides information about | ||||
* windows and listening clients via the get_clients callback, which is | ||||
* called during gesture instantiation. | ||||
* | ||||
*/ | */ | |||
struct grail { | ||||
int (*get_clients)(struct grail *ge, | ||||
struct grail_client_info *client, int max_clients | ||||
, | ||||
const struct grail_coord *coords, int num_coords, | ||||
const grail_mask_t *types, int type_bytes); | ||||
void (*event)(struct grail *ge, | ||||
const struct input_event *ev); | ||||
void (*gesture)(struct grail *ge, | ||||
const struct grail_event *ev); | ||||
struct grail_impl *impl; | ||||
struct gesture_inserter *gin; | ||||
struct gesture_recognizer *gru; | ||||
void *priv; | ||||
}; | ||||
/** | #ifndef GRAIL_OIF_GRAIL_H_ | |||
* grail_open - open a grail device | #define GRAIL_OIF_GRAIL_H_ | |||
* @ge: the grail device to open | ||||
* @fd: file descriptor of the kernel device | ||||
* | ||||
* Initialize the internal grail structures and configure it by reading the | ||||
* protocol capabilities through the file descriptor. | ||||
* | ||||
* The callbacks, parameters and priv pointer should be set prior to this | ||||
* call. | ||||
* | ||||
* Returns zero on success, negative error number otherwise. | ||||
*/ | ||||
int GRAIL_PUBLIC grail_open(struct grail *ge, int fd); | ||||
/** | /* Macros that set symbol visibilities in shared libraries properly. | |||
* grail_idle - check state of kernel device | * Adapted from http://gcc.gnu.org/wiki/Visibility | |||
* @ge: the grail device in use | */ | |||
* @fd: file descriptor of the kernel device | ||||
* @ms: number of milliseconds to wait for activity | #if defined _WIN32 || defined __CYGWIN__ | |||
* | #ifdef BUILDING_GRAIL | |||
* Returns true if the device is idle, i.e., there are no fetched | #define GRAIL_PUBLIC __declspec(dllexport) | |||
* events in the pipe and there is nothing to fetch from the device. | #else | |||
*/ | #define GRAIL_PUBLIC __declspec(dllimport) | |||
int GRAIL_PUBLIC grail_idle(struct grail *ge, int fd, int ms); | #endif | |||
#else | ||||
#if defined __GNUC__ | ||||
#define GRAIL_PUBLIC __attribute__ ((visibility("default"))) | ||||
#else | ||||
#pragma message ("Compiler does not support symbol visibility.") | ||||
#define GRAIL_PUBLIC | ||||
#endif | ||||
#endif | ||||
/** | #include <stdint.h> | |||
* grail_pull - pull and process available events from the kernel device | ||||
* @ge: the grail device in use | ||||
* @fd: file descriptor of the kernel device | ||||
* | ||||
* Pull all available events and process them. The grail callbacks are | ||||
* invoked during this call. | ||||
* | ||||
* The underlying file descriptor must have O_NONBLOCK set, or this method | ||||
* will not return until the file is closed. | ||||
* | ||||
* On success, returns the number of events read. Otherwise, | ||||
* a standard negative error number is returned. | ||||
*/ | ||||
int GRAIL_PUBLIC grail_pull(struct grail *ge, int fd); | ||||
/** | #include <oif/frame.h> | |||
* grail_close - close the grail device | ||||
* @ge: the grail device to close | ||||
* @fd: file descriptor of the kernel device | ||||
* | ||||
* Deallocates all memory associated with grail, and clears the grail | ||||
* structure. | ||||
*/ | ||||
void GRAIL_PUBLIC grail_close(struct grail *ge, int fd); | ||||
/** | #ifdef __cplusplus | |||
* grail_set_bbox - set the grail unit bounding box | extern "C" { | |||
* @ge: the grail device in use | #endif | |||
* @min: the minimum (lower-left) corner of the bounding box | ||||
* @max: the maximum (upper-right) corner of the bounding box | ||||
* | ||||
* Sets the box within which the device coordinates should be presented. | ||||
*/ | ||||
void GRAIL_PUBLIC grail_set_bbox(struct grail *ge, | ||||
const struct grail_coord *min, | ||||
const struct grail_coord *max); | ||||
/** | /** | |||
* grail_get_units - get device coordinate ranges | * @defgroup v3 Grail 3.x | |||
* @ge: the grail device in use | * @{ | |||
* @min: minimum x and y coordinates | ||||
* @max: maximum x and y coordinates | ||||
* | ||||
* The grail event attributes pos, touch_major, touch_minor, | ||||
* width_major, and width_minor are all given in device coordinate | ||||
* units, unless specified otherwise using the grail_set_bbox() | ||||
* function. This function reports the device coordinate ranges. | ||||
* | ||||
*/ | */ | |||
void GRAIL_PUBLIC grail_get_units(const struct grail *ge, | ||||
struct grail_coord *min, struct grail_coor | ||||
d *max); | ||||
/** | /** An object for the context of the grail instance */ | |||
* grail_get_contact_frame - get current contact frame | typedef struct UGHandle_* UGHandle; | |||
* @ge: the grail device in use | /** An object for a gesture subscription */ | |||
* | typedef struct UGSubscription_* UGSubscription; | |||
* Return the contact frame current being processed. If called from | /** An object for an event */ | |||
* within a gesture callback, it is guaranteed to return the frame | typedef struct UGEvent_* UGEvent; | |||
* corresponding to the gesture. | /** An object for a gesture state in time */ | |||
* | typedef const struct UGSlice_* UGSlice; | |||
* The returned pointer can be NULL if no input has yet been extracted | ||||
* through the grail instance. | /** The status code denoting the result of a function call */ | |||
* | typedef enum UGStatus { | |||
* The frame pointer is ABI agnostic, owned by the grail instance, and | UGStatusSuccess = 0, /**< The call was successful */ | |||
* has grail scope. | UGStatusErrorGeneric, /**< A platform-dependent error occurred */ | |||
UGStatusErrorResources, /**< An error occurred due to insufficient resour | ||||
ces */ | ||||
UGStatusErrorNoEvent, /**< No events were available to get */ | ||||
UGStatusErrorUnknownProperty, /**< The requested property value was not s | ||||
et */ | ||||
UGStatusErrorInvalidValue, /**< The property value passed in is invalid * | ||||
/ | ||||
UGStatusErrorInvalidDevice, /**< The requested device does not exist */ | ||||
UGStatusErrorInvalidSubscription, /**< The subscription is invalid */ | ||||
UGStatusErrorInvalidGesture, /**< The requested gesture does not exist */ | ||||
UGStatusErrorInvalidIndex, /**< The requested touch index is invalid */ | ||||
UGStatusErrorAtomicity, /**< The subscription has a different value for | ||||
UGSubscriptionPropertyAtomicGestures than ot | ||||
her | ||||
subscriptions active on the window */ | ||||
} UGStatus; | ||||
/** Subscription properties */ | ||||
typedef enum UGSubscriptionProperty { | ||||
/** | ||||
* Device to subscribe to gesture events for | ||||
* | ||||
* Value type: UFDevice | ||||
*/ | ||||
UGSubscriptionPropertyDevice, | ||||
/** | ||||
* Window to subscribe to gesture events for | ||||
* | ||||
* Value type: UFWindowId | ||||
*/ | ||||
UGSubscriptionPropertyWindow, | ||||
/** | ||||
* Gesture types to subscribe for | ||||
* | ||||
* Value type: UGGestureTypeMask | ||||
*/ | ||||
UGSubscriptionPropertyMask, | ||||
/** | ||||
* Number of touches required to begin gesture | ||||
* | ||||
* Value type: unsigned int | ||||
* Default value: 2 touches | ||||
*/ | ||||
UGSubscriptionPropertyTouchesStart, | ||||
/** | ||||
* Minimum number of touches for gesture | ||||
* | ||||
* Value type: unsigned int | ||||
* Default value: 2 touches | ||||
*/ | ||||
UGSubscriptionPropertyTouchesMinimum, | ||||
/** | ||||
* Maximum number of touches for gesture | ||||
* | ||||
* Value type: unsigned int | ||||
* Default value: 2 touches | ||||
*/ | ||||
UGSubscriptionPropertyTouchesMaximum, | ||||
/** | ||||
* Timeout for recognizing a drag gesture | ||||
* | ||||
* Value type: 64-bit unsigned integer | ||||
* Default value: 300 ms | ||||
*/ | ||||
UGSubscriptionPropertyDragTimeout, | ||||
/** | ||||
* Threshold value for recognizing a drag gesture | ||||
* | ||||
* Value type: float | ||||
* Default value: 0.0026 m | ||||
* | ||||
* The value is in units of meters. | ||||
*/ | ||||
UGSubscriptionPropertyDragThreshold, | ||||
/** | ||||
* Timeout for recognizing a pinch gesture | ||||
* | ||||
* Value type: 64-bit unsigned integer | ||||
* Default value: 300 ms | ||||
*/ | ||||
UGSubscriptionPropertyPinchTimeout, | ||||
/** | ||||
* Threshold value for recognizing a pinch gesture | ||||
* | ||||
* Value type: float | ||||
* Default value: 1.1 | ||||
* | ||||
* The value is a proportionality representing how much a group of touche | ||||
s | ||||
* have moved closer or farther apart. For example, a threshold of 1.1 wo | ||||
uld | ||||
* be met if two touches moved from 1000 pixels apart to either 1100 or 9 | ||||
09 | ||||
* pixels apart. | ||||
*/ | ||||
UGSubscriptionPropertyPinchThreshold, | ||||
/** | ||||
* Timeout for recognizing a rotate gesture | ||||
* | ||||
* Value type: 64-bit unsigned integer | ||||
* Default value: 500 ms | ||||
*/ | ||||
UGSubscriptionPropertyRotateTimeout, | ||||
/** | ||||
* Threshold value for recognizing a rotate gesture | ||||
* | ||||
* Value type: float | ||||
* Default value: 0.125663706 (1/50th of a revolution) | ||||
* | ||||
* The value is in units of radians. | ||||
*/ | ||||
UGSubscriptionPropertyRotateThreshold, | ||||
/** | ||||
* Timeout for recognizing a tap gesture | ||||
* | ||||
* Value type: 64-bit unsigned integer | ||||
* Default value: 300 ms | ||||
*/ | ||||
UGSubscriptionPropertyTapTimeout, | ||||
/** | ||||
* Threshold value for recognizing a tap gesture | ||||
* | ||||
* Value type: float | ||||
* Default value: 0.0026 m | ||||
* | ||||
* For a tap to be recognized, the touches must not move more than the | ||||
* threshold value in any direction. | ||||
*/ | ||||
UGSubscriptionPropertyTapThreshold, | ||||
/** | ||||
* Only support one gesture at a time | ||||
* | ||||
* Value type: int with boolean semantics | ||||
* Default value: False | ||||
* | ||||
* The first version of grail supported only one gesture at a time. When | ||||
this | ||||
* property is true, grail will mimic this behavior. This results in the | ||||
* following: | ||||
* | ||||
* - The grail client must not attempt to accept or reject a gesture | ||||
* - If a gesture is active for a maximum of N touches, the addition of | ||||
* another touch will end the gesture. A new gesture is begun if anothe | ||||
r | ||||
* subscription's TouchesStart property equals the new number of touche | ||||
s. | ||||
* - All subscriptions for a window must have the same value for this | ||||
* property. If a client attempts to activate a subscription with a | ||||
* different value for this property than the already activated | ||||
* subscriptions for the window, UGStatusErrorAtomicity will be returne | ||||
d. | ||||
* - Gestures from multiple subscriptions may be active at the same time. | ||||
* | ||||
* There is one key difference between grail v1 behavior and the use of t | ||||
his | ||||
* option. The v1 behavior only supported one gesture per device. The use | ||||
of | ||||
* this option only supports one gesture per device per window. The begin | ||||
ning | ||||
* of a gesture in a window does not inhibit gestures in other windows. I | ||||
t | ||||
* also does not guarantee that there are no active touches outside the | ||||
* window. | ||||
*/ | ||||
UGSubscriptionPropertyAtomicGestures, | ||||
} UGSubscriptionProperty; | ||||
/** Event type */ | ||||
typedef enum UGEventType { | ||||
UGEventTypeSlice = 0, /**< A new gesture slice */ | ||||
} UGEventType; | ||||
/** Event properties */ | ||||
typedef enum UGEventProperty { | ||||
/** | ||||
* Type of event | ||||
* | ||||
* Value type: UGEventType | ||||
*/ | ||||
UGEventPropertyType = 0, | ||||
/** | ||||
* Slice of a gesture | ||||
* | ||||
* Value type: UGSlice | ||||
*/ | ||||
UGEventPropertySlice, | ||||
/** | ||||
* Event time | ||||
* | ||||
* Value type: 64-bit unsigned int | ||||
* | ||||
* This property holds the time the event occurred in display server | ||||
* timespace. The time is provided in milliseconds (ms). | ||||
*/ | ||||
UGEventPropertyTime, | ||||
} UGEventProperty; | ||||
/** Gesture type bit indices */ | ||||
typedef enum UGGestureType { | ||||
UGGestureTypeDrag = 0x1, /**< Drag gesture */ | ||||
UGGestureTypePinch = 0x2, /**< Pinch gesture */ | ||||
UGGestureTypeRotate = 0x4, /**< Rotate gesture */ | ||||
UGGestureTypeTap = 0x8, /**< Tap gesture */ | ||||
UGGestureTypeTouch = 0x10, /**< Touch gesture */ | ||||
} UGGestureType; | ||||
/** Bit-mask of gesture types */ | ||||
typedef uint32_t UGGestureTypeMask; | ||||
/** 2D affine transformation */ | ||||
typedef const float UGTransform[3][3]; | ||||
/** Gesture slice state */ | ||||
typedef enum UGGestureState { | ||||
UGGestureStateBegin = 0, /**< Gesture slice begin */ | ||||
UGGestureStateUpdate, /**< Gesture slice update */ | ||||
UGGestureStateEnd, /**< Gesture slice end */ | ||||
} UGGestureState; | ||||
/** | ||||
* Gesture slice properties | ||||
* | ||||
* The coordinate system for gesture properties is determined by the device | ||||
* type. Direct devices provide screen coordinates. Indirect devices provid | ||||
e | ||||
* device coordinates. | ||||
*/ | ||||
typedef enum UGSliceProperty { | ||||
/** | ||||
* Gesture ID | ||||
* | ||||
* Value type: unsigned int | ||||
*/ | ||||
UGSlicePropertyId = 0, | ||||
/** | ||||
* Gesture set state | ||||
* | ||||
* Value type: UGGestureState | ||||
*/ | ||||
UGSlicePropertyState, | ||||
/** | ||||
* Gesture subscription | ||||
* | ||||
* Value type: UGSubscription | ||||
*/ | ||||
UGSlicePropertySubscription, | ||||
/** | ||||
* Recognized gestures | ||||
* | ||||
* Value type: UGGestureTypeMask | ||||
*/ | ||||
UGSlicePropertyRecognized, | ||||
/** | ||||
* Number of touches | ||||
* | ||||
* Value type: unsigned int | ||||
*/ | ||||
UGSlicePropertyNumTouches, | ||||
/** | ||||
* Touch frame | ||||
* | ||||
* Value type: UFFrame | ||||
*/ | ||||
UGSlicePropertyFrame, | ||||
/** | ||||
* Original gesture center along the X axis | ||||
* | ||||
* Value type: float | ||||
* | ||||
* This value represents the original geometric center of the touches. | ||||
*/ | ||||
UGSlicePropertyOriginalCenterX, | ||||
/** | ||||
* Original gesture center along the Y axis | ||||
* | ||||
* Value type: float | ||||
* | ||||
* This value represents the original geometric center of the touches. | ||||
*/ | ||||
UGSlicePropertyOriginalCenterY, | ||||
/** | ||||
* Original radius of touches | ||||
* | ||||
* Value type: float | ||||
* | ||||
* This value represents the average of the square of the euclidean dista | ||||
nce | ||||
* from the geometric center of the original touches to each touch. | ||||
*/ | ||||
UGSlicePropertyOriginalRadius, | ||||
/** | ||||
* Best-fit 2D affine transformation of previous to current touch locatio | ||||
ns | ||||
* | ||||
* Value type: pointer to UGTransform | ||||
* | ||||
* The transformation is relative to the previous geometric center of the | ||||
* touches. | ||||
*/ | ||||
UGSlicePropertyTransform, | ||||
/** | ||||
* Best-fit 2D affine transformation of original to current touch locatio | ||||
ns | ||||
* | ||||
* Value type: pointer to UGTransform | ||||
* | ||||
* The transformation is relative to the original geometric center of the | ||||
* touches. | ||||
*/ | ||||
UGSlicePropertyCumulativeTransform, | ||||
/** | ||||
* Best-fit instant center of rotation along the X axis | ||||
* | ||||
* Value type: float | ||||
*/ | ||||
UGSlicePropertyCenterOfRotationX, | ||||
/** | ||||
* Best-fit instant center of rotation along the Y axis | ||||
* | ||||
* Value type: float | ||||
*/ | ||||
UGSlicePropertyCenterOfRotationY, | ||||
/** | ||||
* Whether the construction of all gestures containing the same touches i | ||||
s | ||||
* finished | ||||
* | ||||
* Value type: int with boolean semantics | ||||
* | ||||
* Grail events are serial. This property allows the client to determine | ||||
if | ||||
* all the possible gestures from the set of touches in this gesture have | ||||
been | ||||
* sent. When this value is true, the client will have received all the | ||||
* information needed to make a gesture accept and reject decision based | ||||
on | ||||
* potentially overlapping gestures. An example is when both one and two | ||||
touch | ||||
* gestures are subscribed on the same window with the same gesture types | ||||
and | ||||
* thresholds. When this property is true for one touch gesture events, t | ||||
he | ||||
* client can be sure there are no other touches unless a two touch gestu | ||||
re | ||||
* event has already been sent. | ||||
*/ | ||||
UGSlicePropertyConstructionFinished, | ||||
} UGSliceProperty; | ||||
/** | ||||
* Create a new grail context | ||||
* | ||||
* @param [out] handle The new grail context object | ||||
* @return UGStatusSuccess or UGStatusErrorResources | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGStatus grail_new(UGHandle *handle); | ||||
/** | ||||
* Delete a grail context | ||||
* | ||||
* @param [in] handle The grail context object | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
void grail_delete(UGHandle handle); | ||||
/** | ||||
* Get the event file descriptor for the frame context | ||||
* | ||||
* @param [in] handle The grail context object | ||||
* @return A file descriptor for the context | ||||
* | ||||
* When events are available for processing, the file descriptor will be | ||||
* readable. Perform an 8-byte read from the file descriptor to clear the s | ||||
tate. | ||||
* Refer to the EVENTFD(2) man page for more details. | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
int grail_get_fd(UGHandle handle); | ||||
/** | ||||
* Create a new subscription object | ||||
* | ||||
* @param [out] subscription The new subscription object | ||||
* @return UGStatusSuccess or UGStatusErrorResources | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGStatus grail_subscription_new(UGSubscription* subscription); | ||||
/** | ||||
* Delete a subscription object | ||||
* | ||||
* @param [in] subscription The subscription object | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
void grail_subscription_delete(UGSubscription subscription); | ||||
/** | ||||
* Set a subscription property | ||||
* | ||||
* @param [in] subscription The subscription object | ||||
* @param [in] property The subscription property | ||||
* @param [in] value The new value of the property | ||||
* @return UGStatusSuccess or UGStatusInvalidProperty | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGStatus grail_subscription_set_property(UGSubscription subscription, | ||||
UGSubscriptionProperty property, | ||||
const void* value); | ||||
/** | ||||
* Get a subscription property | ||||
* | ||||
* @param [in] subscription The subscription object | ||||
* @param [in] property The subscription property | ||||
* @param [out] value The value of the property | ||||
* @return UGStatusSuccess or UGStatusInvalidProperty | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGStatus grail_subscription_get_property(UGSubscription subscription, | ||||
UGSubscriptionProperty property, | ||||
void* value); | ||||
/** | ||||
* Activate a subscription | ||||
* | ||||
* @param [in] handle The context object | ||||
* @param [in] subscription The subscription object | ||||
* @return UGStatusSuccess or UGStatusErrorInvalidDevice | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGStatus grail_subscription_activate(UGHandle handle, UGSubscription subscr | ||||
iption); | ||||
/** | ||||
* Deactivate a subscription | ||||
* | ||||
* @param [in] handle The context object | ||||
* @param [in] subscription The subscription object | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
void grail_subscription_deactivate(UGHandle handle, | ||||
UGSubscription subscription); | ||||
/** | ||||
* Process a frame event | ||||
* | ||||
* @param [in] handle The context object | ||||
* @param [in] event The frame event | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
void grail_process_frame_event(UGHandle handle, const UFEvent event); | ||||
/** | ||||
* Get an event from the grail context | ||||
* | ||||
* @param [in] handle The context object | ||||
* @param [out] event The retrieved event | ||||
* @return UGStatusSuccess or UGStatusErrorNoEvent | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGStatus grail_get_event(UGHandle handle, UGEvent *event); | ||||
/** | ||||
* Update the grail state for the given server time | ||||
* | ||||
* @param [in] handle The context object | ||||
* @param [in] time The current server time | ||||
* | ||||
* The recognizer uses timeouts for deciding whether to accept or reject | ||||
* touches. Calling this function will perform any pending decisions based | ||||
on | ||||
* the current server time. | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
void grail_update_time(UGHandle handle, uint64_t time); | ||||
/** | ||||
* Get the next timeout at which to update the grail state | ||||
* | ||||
* @param [in] handle The context object | ||||
* @return The next server time at which the grail state should be updated | ||||
* | ||||
* To update the grail state, call grail_update_time(). | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
uint64_t grail_next_timeout(UGHandle handle); | ||||
/** | ||||
* Increment the reference count of an event | ||||
* | ||||
* @param [in] event The event object | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
void grail_event_ref(UGEvent event); | ||||
/** | ||||
* Decrement the reference count of an event | ||||
* | ||||
* @param [in] event The event object | ||||
* | ||||
* When the reference count reaches zero, the event is freed. | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
void grail_event_unref(UGEvent event); | ||||
/** | ||||
* Get the value of a property of an event | ||||
* | ||||
* @param [in] event The event object | ||||
* @param [in] property The property to retrieve a value for | ||||
* @param [out] value The value retrieved | ||||
* @return UGStatusSuccess or UGStatusErrorUnknownProperty | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGStatus grail_event_get_property(const UGEvent event, UGEventProperty prop | ||||
erty, | ||||
void *value); | ||||
/** | ||||
* Get the touch ID of a touch in a slice | ||||
* | ||||
* @param [in] slice The gesture slcie object | ||||
* @param [in] index The index of the touch in the slice | ||||
* @param [out] touch_id The touch ID of the touch | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGStatus grail_slice_get_touch_id(const UGSlice slice, unsigned int index, | ||||
UFTouchId *touch_id); | ||||
/** | ||||
* Get the value of a property of a gesture slice | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @param [in] property The property to retrieve a value for | ||||
* @param [out] value The value retrieved | ||||
* @return UGStatusSuccess or UGStatusErrorUnknownProperty | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGStatus grail_slice_get_property(const UGSlice slice, UGSliceProperty prop | ||||
erty, | ||||
void *value); | ||||
/** | ||||
* Accept gesture associated with gesture slice | ||||
* | ||||
* @param [in] handle The context object | ||||
* @param [in] id The ID of the gesture to accept | ||||
* @return UGStatusSuccess or UGStatusErrorInvalidGesture | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGStatus grail_accept_gesture(UGHandle handle, unsigned int id); | ||||
/** | ||||
* Reject gesture associated with gesture slice | ||||
* | ||||
* @param [in] handle The context object | ||||
* @param [in] id The ID of the gesture to reject | ||||
* @return UGStatusSuccess or UGStatusErrorInvalidGesture | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGStatus grail_reject_gesture(UGHandle handle, unsigned int id); | ||||
/** | ||||
* @defgroup v3-helpers Helper Functions | ||||
* These helper functions may be used in place of the generic property gett | ||||
ers. | ||||
* They are limited to properties that are guaranteed to exist in all insta | ||||
nces | ||||
* of the objects. | ||||
* @{ | ||||
*/ | ||||
/** | ||||
* Get the type of an event | ||||
* | ||||
* @param [in] event The event object | ||||
* @return The type of the event | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGEventType grail_event_get_type(const UGEvent event); | ||||
/** | ||||
* Get the time of an event | ||||
* | ||||
* @param [in] event The event object | ||||
* @return The time of the event | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
uint64_t grail_event_get_time(const UGEvent event); | ||||
/** | ||||
* Get the ID of a gesture from a slice | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return The ID of the gesture | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
unsigned int grail_slice_get_id(const UGSlice slice); | ||||
/** | ||||
* Get the state of a gesture in a slice | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return The state of the gesture in the slice | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGGestureState grail_slice_get_state(const UGSlice slice); | ||||
/** | ||||
* Get the subscription for the gesture from the slice | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return The subscription | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGSubscription grail_slice_get_subscription(const UGSlice slice); | ||||
/** | ||||
* Get the gestures recognized through the slice | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return The recognized gestures | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
UGGestureTypeMask grail_slice_get_recognized(const UGSlice slice); | ||||
/** | ||||
* Get the current number of touches in the slice | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return The number of touches | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
unsigned int grail_slice_get_num_touches(const UGSlice slice); | ||||
/** | ||||
* Get the original centroid position of the gesture along the X axis | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return The position | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
float grail_slice_get_original_center_x(const UGSlice slice); | ||||
/** | ||||
* Get the original centroid position of the gesture along the Y axis | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return The position | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
float grail_slice_get_original_center_y(const UGSlice slice); | ||||
/** | ||||
* Get the original radius of the gesture | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return The position | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
float grail_slice_get_original_radius(const UGSlice slice); | ||||
/** | ||||
* Get the instantaneous center of rotation of the gesture along the X axis | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return The position | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
float grail_slice_get_center_of_rotation_x(const UGSlice slice); | ||||
/** | ||||
* Get the instantaneous center of rotation of the gesture along the Y axis | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return The position | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
float grail_slice_get_center_of_rotation_y(const UGSlice slice); | ||||
/** | ||||
* Get the best-fit instantaneous 2D affine transformation for the gesture | ||||
slice | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return the transformation | ||||
* | ||||
* The returned transformation is owned by the gesture slice. | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
const UGTransform *grail_slice_get_transform(const UGSlice slice); | ||||
/** | ||||
* Get the best-fit cumulative 2D affine transformation for the gesture sli | ||||
ce | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return the transformation | ||||
* | ||||
* The returned transformation is owned by the gesture slice. | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
const UGTransform *grail_slice_get_cumulative_transform(const UGSlice slice | ||||
); | ||||
/** | ||||
* Get the frame frame for the slice | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return the frame | ||||
*/ | ||||
GRAIL_PUBLIC | ||||
const UFFrame grail_slice_get_frame(const UGSlice slice); | ||||
/** | ||||
* Get whether construction has finished for all touches in the gesture | ||||
* | ||||
* @param [in] slice The gesture slice object | ||||
* @return whether construction has finished | ||||
*/ | */ | |||
const struct utouch_frame GRAIL_PUBLIC * | GRAIL_PUBLIC | |||
grail_get_contact_frame(const struct grail *ge); | int grail_slice_get_construction_finished(const UGSlice slice); | |||
#ifndef GRAIL_NO_LEGACY_API | /** @} */ | |||
struct grail_contact { | /** @} */ | |||
int id; | ||||
int tool_type; | ||||
struct grail_coord pos; | ||||
float touch_major; | ||||
float touch_minor; | ||||
float width_major; | ||||
float width_minor; | ||||
float angle; | ||||
float pressure; | ||||
}; | ||||
void GRAIL_PUBLIC grail_filter_abs_events(struct grail *ge, int usage); | ||||
int GRAIL_PUBLIC grail_get_contacts(const struct grail *ge, | ||||
struct grail_contact *touch, int max_tou | ||||
ch); | ||||
#endif | ||||
void GRAIL_PUBLIC grail_set_coordinate_transform_callback(struct grail *ge, | ||||
utouch_coordinate_ | ||||
transform_cb callback, | ||||
void *user_data); | ||||
#ifdef __cplusplus | #ifdef __cplusplus | |||
} | } | |||
#endif | #endif | |||
#endif | #endif // GRAIL_OIF_GRAIL_H_ | |||
End of changes. 16 change blocks. | ||||
446 lines changed or deleted | 767 lines changed or added | |||