1
/*****************************************************************************
3
* grail - Gesture Recognition And Instantiation Library
5
* Copyright (C) 2012 Canonical Ltd.
7
* This program is free software: you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License as published by the
9
* Free Software Foundation, either version 3 of the License, or (at your
10
* option) any later version.
12
* This program is distributed in the hope that it will be useful, but
13
* WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* General Public License for more details.
17
* You should have received a copy of the GNU General Public License along
18
* with this program. If not, see <http://www.gnu.org/licenses/>.
20
****************************************************************************/
24
* @file Atomic Timout Test
26
* This test plays a two-touch tap and checks that the appropriate events are
27
* generated for a two-touch atomic tap subscription.
29
* Regression test for lp:949855 and lp:957437.
38
#include <gtest/gtest.h>
42
#include "recording.h"
43
#include "x11/fixture.h"
44
#include "utouch/frame_x11.h"
46
using namespace utouch::grail::x11::testing;
48
class AtomicTap : public Test {
50
AtomicTap() : device_(NULL), step_(0) {}
53
static utouch::grail::testing::Events events_;
55
virtual void ProcessFrameEvents();
56
virtual void ProcessGrailEvents();
58
void CheckSlice(UGSlice);
64
void AtomicTap::ProcessFrameEvents() {
68
while ((status = frame_get_event(frame_handle(), &event)) == UFStatusSuccess) {
69
grail_process_frame_event(grail_handle(), event);
71
if (frame_event_get_type(event) == UFEventTypeDeviceAdded) {
73
ASSERT_EQ(UFStatusSuccess,
74
frame_event_get_property(event, UFEventPropertyDevice,
78
ASSERT_EQ(UFStatusSuccess,
79
frame_device_get_property(device, UFDevicePropertyName, &name));
80
if (strcmp(name, "N-Trig MultiTouch (Virtual Test Device)") == 0) {
81
EXPECT_EQ(NULL, device_);
87
frame_event_unref(event);
90
EXPECT_EQ(UFStatusErrorNoEvent, status);
93
void AtomicTap::ProcessGrailEvents() {
97
while ((status = grail_get_event(grail_handle(), &event)) == UGStatusSuccess) {
98
ASSERT_EQ(UGEventTypeSlice, grail_event_get_type(event));
101
status = grail_event_get_property(event, UGEventPropertySlice, &slice);
102
ASSERT_EQ(UGStatusSuccess, status);
106
grail_event_unref(event);
109
EXPECT_EQ(UGStatusErrorNoEvent, status);
112
void AtomicTap::Subscribe() {
113
UGSubscription subscription;
114
UGStatus status = grail_subscription_new(&subscription);
115
ASSERT_EQ(UGStatusSuccess, status);
117
status = grail_subscription_set_property(subscription,
118
UGSubscriptionPropertyDevice,
120
ASSERT_EQ(UGStatusSuccess, status);
122
const UFWindowId window_id =
123
frame_x11_create_window_id(DefaultRootWindow(Display()));
124
status = grail_subscription_set_property(subscription,
125
UGSubscriptionPropertyWindow,
127
ASSERT_EQ(UGStatusSuccess, status);
129
const UGGestureTypeMask mask = UGGestureTypeTap;
130
status = grail_subscription_set_property(subscription,
131
UGSubscriptionPropertyMask,
133
ASSERT_EQ(UGStatusSuccess, status);
135
const int atomic = true;
136
status = grail_subscription_set_property(subscription,
137
UGSubscriptionPropertyAtomicGestures,
140
status = grail_subscription_activate(grail_handle(), subscription);
141
ASSERT_EQ(UGStatusSuccess, status);
144
void AtomicTap::CheckSlice(UGSlice slice) {
145
ASSERT_LT(step_, events_.size()) << "Received too many frame events";
147
/* Ensure we got a device addition event first */
149
EXPECT_NE(nullptr, device_);
151
if (!events_[step_].skip) {
152
EXPECT_EQ(events_[step_].id, grail_slice_get_id(slice)) << "step " << step_;
153
EXPECT_EQ(events_[step_].state, grail_slice_get_state(slice)) << "step "
155
EXPECT_EQ(events_[step_].recognized, grail_slice_get_recognized(slice))
157
EXPECT_EQ(events_[step_].num_touches, grail_slice_get_num_touches(slice))
161
if (grail_slice_get_state(slice) == UGGestureStateEnd) {
162
UGSubscription subscription = grail_slice_get_subscription(slice);
163
grail_subscription_deactivate(grail_handle(), subscription);
164
grail_subscription_delete(subscription);
170
TEST_F(AtomicTap, Recording) {
171
utouch::evemu::Device device("recordings/ntrig_dell_xt2/device.prop");
173
/* Pump once to ensure the X server has initialized the device */
175
ASSERT_NE(nullptr, device_) << "X server failed to initialize touchscreen";
177
utouch::evemu::Recording recording(device,
178
"recordings/ntrig_dell_xt2/2_tap.record");
180
/* We use the c++11 future module so any exceptions thrown by the thread can
181
* be caught later on. If we used the thread module, exceptions would take the
182
* whole thing down. */
183
std::future<void> future = std::async(std::launch::async,
184
&utouch::evemu::Recording::Play,
191
EXPECT_EQ(events_.size(), step_) << "Failed to receive all frame events for "
195
/* Construct the expected events */
198
using namespace utouch::grail::testing;
200
const Events ConstructEvents() {
206
0, /* UGSlicePropertyID */
207
UGGestureStateBegin, /* UGSlicePropertyState */
208
0, /* UGSlicePropertyRecognized */
209
2, /* UGSlicePropertyNumTouches */
210
0, /* UGSlicePropertyOriginalCenterX */
211
0, /* UGSlicePropertyOriginalCenterY */
212
0, /* UGSlicePropertyOriginalRadius */
213
{}, /* UGSlicePropertyTransform */
214
{}, /* UGSlicePropertyCumulativeTransform */
215
0, /* UGSlicePropertyCenterOfRotationX */
216
0, /* UGSlicePropertyCenterOfRotationY */
217
false, /* UGSlicePropertyConstructionFinished */
219
events.push_back(slice);
225
0, /* UGSlicePropertyID */
226
UGGestureStateUpdate, /* UGSlicePropertyState */
227
0, /* UGSlicePropertyRecognized */
228
2, /* UGSlicePropertyNumTouches */
229
0, /* UGSlicePropertyOriginalCenterX */
230
0, /* UGSlicePropertyOriginalCenterY */
231
0, /* UGSlicePropertyOriginalRadius */
232
{}, /* UGSlicePropertyTransform */
233
{}, /* UGSlicePropertyCumulativeTransform */
234
0, /* UGSlicePropertyCenterOfRotationX */
235
0, /* UGSlicePropertyCenterOfRotationY */
236
false, /* UGSlicePropertyConstructionFinished */
238
events.push_back(slice);
244
0, /* UGSlicePropertyID */
245
UGGestureStateUpdate, /* UGSlicePropertyState */
246
UGGestureTypeTap, /* UGSlicePropertyRecognized */
247
2, /* UGSlicePropertyNumTouches */
248
0, /* UGSlicePropertyOriginalCenterX */
249
0, /* UGSlicePropertyOriginalCenterY */
250
0, /* UGSlicePropertyOriginalRadius */
251
{}, /* UGSlicePropertyTransform */
252
{}, /* UGSlicePropertyCumulativeTransform */
253
0, /* UGSlicePropertyCenterOfRotationX */
254
0, /* UGSlicePropertyCenterOfRotationY */
255
false, /* UGSlicePropertyConstructionFinished */
257
events.push_back(slice);
263
0, /* UGSlicePropertyID */
264
UGGestureStateEnd, /* UGSlicePropertyState */
265
UGGestureTypeTap, /* UGSlicePropertyRecognized */
266
2, /* UGSlicePropertyNumTouches */
267
0, /* UGSlicePropertyOriginalCenterX */
268
0, /* UGSlicePropertyOriginalCenterY */
269
0, /* UGSlicePropertyOriginalRadius */
270
{}, /* UGSlicePropertyTransform */
271
{}, /* UGSlicePropertyCumulativeTransform */
272
0, /* UGSlicePropertyCenterOfRotationX */
273
0, /* UGSlicePropertyCenterOfRotationY */
274
true, /* UGSlicePropertyConstructionFinished */
276
events.push_back(slice);
284
/* Now initialize the static test fixture member */
285
utouch::grail::testing::Events AtomicTap::events_(ConstructEvents());