2
* @file geis_gesture_flick.c
3
* @brief higher-level "flick" gesture recognizer
5
* Copyright 2011 Canonical Ltd.
7
* This library is free software; you can redistribute it and/or modify it under
8
* the terms of the GNU Lesser General Public License as published by the Free
9
* Software Foundation; either version 3 of the License, or (at your option) any
12
* This library is distributed in the hope that it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17
* You should have received a copy of the GNU General Public License
18
* along with this program. If not, see <http://www.gnu.org/licenses/>.
20
#include "geis_gesture_flick.h"
22
#include "geis_class.h"
23
#include "geis_frame.h"
24
#include "geis_logging.h"
25
#include "geis_private.h"
29
struct GeisGestureFlick
32
GeisGestureClass flick_class;
36
static GeisFloat _flick_threshold_squared = 1.0f;
39
static GeisProcessingResult
40
_recognize_flick(GeisEvent event, void *context)
42
GeisProcessingResult result = GEIS_PROCESSING_IGNORED;
43
GeisGestureFlick flick = (GeisGestureFlick)context;
48
switch (geis_event_type(event))
50
case GEIS_EVENT_GESTURE_END:
53
attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_GROUPSET);
56
geis_error("no groupset for gesture event");
60
GeisGroupSet groupset = geis_attr_value_to_pointer(attr);
63
geis_warning("can not convert attr to groupset");
68
for (i = 0; i < geis_groupset_group_count(groupset); ++i)
70
GeisGroup group = geis_groupset_group(groupset, i);
73
geis_warning("can not extract group %zu from groupset", i);
78
for (j = 0; j < geis_group_frame_count(group); ++j)
83
GeisFrame frame = geis_group_frame(group, j);
86
geis_warning("can not extract frame %zu from group", j);
90
GeisSize num_attrs = geis_frame_attr_count(frame);
91
for (i = 0; i < num_attrs; ++i)
93
GeisAttr attr = geis_frame_attr(frame, i);
94
GeisString attr_name = geis_attr_name(attr);
96
if (0 == strcmp(attr_name, GEIS_CLASS_ATTRIBUTE_ID))
98
GeisInteger class_id = geis_attr_value_to_integer(attr);
99
if (class_id != GEIS_GESTURE_PRIMITIVE_DRAG)
104
else if (0 == strcmp(attr_name, GEIS_GESTURE_ATTRIBUTE_VELOCITY_X))
106
dx = geis_attr_value_to_float(attr);
108
else if (0 == strcmp(attr_name, GEIS_GESTURE_ATTRIBUTE_VELOCITY_Y))
110
dy = geis_attr_value_to_float(attr);
114
rv = dx * dx + dy * dy;
115
if (rv > _flick_threshold_squared)
117
geis_frame_set_is_class(frame, flick->flick_class);
134
_add_class_term(GeisBackendToken token,
137
GeisFilterOperation op,
140
GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;
141
GeisGestureFlick flick = (GeisGestureFlick)context;
143
if (0 == strcmp(name, GEIS_CLASS_ATTRIBUTE_NAME))
145
if (op == GEIS_FILTER_OP_EQ)
147
GeisString class_name = (GeisString)value;
148
if (0 == strcmp(class_name, geis_gesture_class_name(flick->flick_class)))
150
geis_filterable_attribute_foreach(flick->geis,
153
GEIS_CLASS_ATTRIBUTE_NAME,
156
flick->enabled = GEIS_TRUE;
160
flick->enabled = GEIS_FALSE;
163
status = GEIS_STATUS_SUCCESS;
165
else if (0 == strcmp(name, GEIS_CLASS_ATTRIBUTE_ID))
167
if (op == GEIS_FILTER_OP_EQ)
169
GeisInteger id = *(GeisInteger*)value;
170
if (id == geis_gesture_class_id(flick->flick_class))
172
geis_filterable_attribute_foreach(flick->geis,
175
GEIS_CLASS_ATTRIBUTE_NAME,
178
flick->enabled = GEIS_TRUE;
182
flick->enabled = GEIS_FALSE;
185
status = GEIS_STATUS_SUCCESS;
187
else if (0 == strcmp(name, GEIS_GESTURE_ATTRIBUTE_TOUCHES))
189
/* GeisInteger touches = *(GeisInteger*)value; */
190
/* must explicitly ask for high-level gestures */
191
/* flick->enabled = GEIS_TRUE; */
192
status = GEIS_STATUS_SUCCESS;
199
geis_gesture_flick_new(Geis geis)
201
GeisSize attr_count = 0;
202
struct GeisFilterableAttribute attrs[3];
203
GeisGestureFlick flick = calloc(1, sizeof(struct GeisGestureFlick));
206
geis_error("can not create flick");
211
flick->flick_class = geis_gesture_class_new(GEIS_GESTURE_FLICK,
212
GEIS_GESTURE_ID_FLICK);
213
geis_gesture_class_ref(flick->flick_class);
214
geis_filterable_attribute_init(&attrs[attr_count++],
215
GEIS_CLASS_ATTRIBUTE_NAME,
216
GEIS_ATTR_TYPE_STRING,
219
geis_filterable_attribute_init(&attrs[attr_count++],
220
GEIS_CLASS_ATTRIBUTE_ID,
221
GEIS_ATTR_TYPE_INTEGER,
224
geis_filterable_attribute_init(&attrs[attr_count++],
225
GEIS_GESTURE_ATTRIBUTE_TOUCHES,
226
GEIS_ATTR_TYPE_INTEGER,
230
geis_register_gesture_class(geis, flick->flick_class, attr_count, attrs);
231
geis_register_processing_callback(geis, 10, _recognize_flick, flick);
239
geis_gesture_flick_delete(GeisGestureFlick flick)
243
geis_gesture_class_unref(flick->flick_class);