~chasedouglas/grail/work-in-progress

« back to all changes in this revision

Viewing changes to test/x11/tap-touch-accept.cpp

  • Committer: Chase Douglas
  • Date: 2012-03-21 20:32:21 UTC
  • mfrom: (200.4.11 tap-touch-accept-test)
  • Revision ID: chase.douglas@ubuntu.com-20120321203221-jy1wa6plzyqf7tan
Merge fix for tap touch acceptance, memory leaks in tests

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 *
 
3
 * grail - Gesture Recognition And Instantiation Library
 
4
 *
 
5
 * Copyright (C) 2012 Canonical Ltd.
 
6
 *
 
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.
 
11
 *
 
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.
 
16
 *
 
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/>.
 
19
 *
 
20
 ****************************************************************************/
 
21
 
 
22
/**
 
23
 * @internal
 
24
 * @file Tap Touch Accept Test
 
25
 *
 
26
 * This test plays a one touch tap recording, then checks that the tap was
 
27
 * recognized and the touch was not erroneously rejected and replayed to a
 
28
 * subwindow selecting for touch events.
 
29
 *
 
30
 * This is a regression test for lp:960438.
 
31
 */
 
32
 
 
33
#include <map>
 
34
#include <memory>
 
35
#include <stdexcept>
 
36
 
 
37
#include <gtest/gtest.h>
 
38
 
 
39
#include <X11/extensions/XInput2.h>
 
40
 
 
41
#include "device.h"
 
42
#include "recording.h"
 
43
#include "x11/fixture.h"
 
44
#include "utouch/frame_x11.h"
 
45
 
 
46
using namespace utouch::grail::x11::testing;
 
47
 
 
48
class TapTouchAccept : public Test {
 
49
 public:
 
50
  TapTouchAccept() : device_(NULL), saw_tap_(false) {}
 
51
 
 
52
 protected:
 
53
  virtual void SetUp();
 
54
  virtual bool FilterXIEvent(const XGenericEventCookie* xcookie);
 
55
  virtual void ProcessFrameEvents();
 
56
  virtual void ProcessGrailEvents();
 
57
  void Subscribe();
 
58
 
 
59
  UFDevice device_;
 
60
  Window subwin_;
 
61
  bool saw_tap_;
 
62
};
 
63
 
 
64
void TapTouchAccept::SetUp() {
 
65
  ASSERT_NO_FATAL_FAILURE(utouch::grail::x11::testing::Test::SetUp());
 
66
 
 
67
  Window root = DefaultRootWindow(Display());
 
68
 
 
69
  unsigned int width;
 
70
  unsigned int height;
 
71
  {
 
72
    Window root_return;
 
73
    int x;
 
74
    int y;
 
75
    unsigned int border_width;
 
76
    unsigned int depth;
 
77
    ASSERT_NE(0, XGetGeometry(Display(), root, &root_return, &x, &y, &width,
 
78
                              &height, &border_width, &depth));
 
79
  }
 
80
 
 
81
  subwin_ = XCreateSimpleWindow(Display(), root, 0, 0, width, height, 0, 0, 0);
 
82
  ASSERT_NE(subwin_, None);
 
83
 
 
84
  ASSERT_NE(0, XMapWindow(Display(), subwin_));
 
85
 
 
86
  XIEventMask mask;
 
87
  mask.mask_len = XIMaskLen(XI_LASTEVENT);
 
88
  mask.mask = reinterpret_cast<unsigned char*>(calloc(mask.mask_len,
 
89
                                                      sizeof(char)));
 
90
 
 
91
  mask.deviceid = XIAllMasterDevices;
 
92
  XISetMask(mask.mask, XI_TouchBegin);
 
93
  XISetMask(mask.mask, XI_TouchUpdate);
 
94
  XISetMask(mask.mask, XI_TouchEnd);
 
95
 
 
96
  ASSERT_EQ(Success, XISelectEvents(Display(), subwin_, &mask, 1));
 
97
 
 
98
  free(mask.mask);
 
99
}
 
100
 
 
101
bool TapTouchAccept::FilterXIEvent(const XGenericEventCookie* xcookie) {
 
102
  if (xcookie->evtype == XI_TouchBegin) {
 
103
    const XIDeviceEvent* device_event =
 
104
      reinterpret_cast<const XIDeviceEvent*>(xcookie->data);
 
105
 
 
106
    if (device_event->event == subwin_) {
 
107
      ADD_FAILURE() << "saw touch selection event";
 
108
      return true;
 
109
    }
 
110
  }
 
111
 
 
112
  return false;
 
113
}
 
114
 
 
115
void TapTouchAccept::ProcessFrameEvents() {
 
116
  UFEvent event;
 
117
 
 
118
  UFStatus status;
 
119
  while ((status = frame_get_event(frame_handle(), &event)) == UFStatusSuccess) {
 
120
    grail_process_frame_event(grail_handle(), event);
 
121
 
 
122
    if (frame_event_get_type(event) == UFEventTypeDeviceAdded) {
 
123
      UFDevice device;
 
124
      ASSERT_EQ(UFStatusSuccess,
 
125
                frame_event_get_property(event, UFEventPropertyDevice,
 
126
                                         &device));
 
127
 
 
128
      const char* name;
 
129
      ASSERT_EQ(UFStatusSuccess,
 
130
                frame_device_get_property(device, UFDevicePropertyName, &name));
 
131
      if (strcmp(name, "N-Trig MultiTouch (Virtual Test Device)") == 0) {
 
132
        EXPECT_EQ(NULL, device_);
 
133
        device_ = device;
 
134
        Subscribe();
 
135
      }
 
136
    }
 
137
 
 
138
    frame_event_unref(event);
 
139
  }
 
140
 
 
141
  EXPECT_EQ(UFStatusErrorNoEvent, status);
 
142
}
 
143
 
 
144
void TapTouchAccept::ProcessGrailEvents() {
 
145
  UGEvent event;
 
146
 
 
147
  UGStatus status;
 
148
  while ((status = grail_get_event(grail_handle(), &event)) == UGStatusSuccess) {
 
149
    ASSERT_EQ(UGEventTypeSlice, grail_event_get_type(event));
 
150
 
 
151
    UGSlice slice;
 
152
    status = grail_event_get_property(event, UGEventPropertySlice, &slice);
 
153
    ASSERT_EQ(UGStatusSuccess, status);
 
154
 
 
155
    if (!saw_tap_ && grail_slice_get_recognized(slice) & UGGestureTypeTap) {
 
156
      saw_tap_ = true;
 
157
      EXPECT_EQ(UGStatusSuccess,
 
158
                grail_accept_gesture(grail_handle(),
 
159
                                     grail_slice_get_id(slice)));
 
160
    }
 
161
 
 
162
    if (grail_slice_get_state(slice) == UGGestureStateEnd) {
 
163
      UGSubscription subscription = grail_slice_get_subscription(slice);
 
164
      grail_subscription_deactivate(grail_handle(), subscription);
 
165
      grail_subscription_delete(subscription);
 
166
    }
 
167
 
 
168
    grail_event_unref(event);
 
169
  }
 
170
 
 
171
  EXPECT_EQ(UGStatusErrorNoEvent, status);
 
172
}
 
173
 
 
174
void TapTouchAccept::Subscribe() {
 
175
  UGSubscription subscription;
 
176
  UGStatus status = grail_subscription_new(&subscription);
 
177
  ASSERT_EQ(UGStatusSuccess, status);
 
178
 
 
179
  status = grail_subscription_set_property(subscription,
 
180
                                           UGSubscriptionPropertyDevice,
 
181
                                           &device_);
 
182
  ASSERT_EQ(UGStatusSuccess, status);
 
183
 
 
184
  const UFWindowId window_id =
 
185
      frame_x11_create_window_id(DefaultRootWindow(Display()));
 
186
  status = grail_subscription_set_property(subscription,
 
187
                                           UGSubscriptionPropertyWindow,
 
188
                                           &window_id);
 
189
  ASSERT_EQ(UGStatusSuccess, status);
 
190
 
 
191
  const UGGestureTypeMask mask = UGGestureTypeTap;
 
192
  status = grail_subscription_set_property(subscription,
 
193
                                           UGSubscriptionPropertyMask,
 
194
                                           &mask);
 
195
  ASSERT_EQ(UGStatusSuccess, status);
 
196
 
 
197
  const unsigned int touches = 1;
 
198
  status = grail_subscription_set_property(subscription,
 
199
                                           UGSubscriptionPropertyTouchesStart,
 
200
                                           &touches);
 
201
  ASSERT_EQ(UGStatusSuccess, status);
 
202
 
 
203
  status = grail_subscription_set_property(subscription,
 
204
                                           UGSubscriptionPropertyTouchesMinimum,
 
205
                                           &touches);
 
206
  ASSERT_EQ(UGStatusSuccess, status);
 
207
 
 
208
  status = grail_subscription_activate(grail_handle(), subscription);
 
209
  ASSERT_EQ(UGStatusSuccess, status);
 
210
}
 
211
 
 
212
TEST_F(TapTouchAccept, Recording) {
 
213
  utouch::evemu::Device device("recordings/ntrig_dell_xt2/device.prop");
 
214
 
 
215
  /* Pump once to ensure the X server has initialized the device */
 
216
  PumpEvents();
 
217
  ASSERT_NE(nullptr, device_) << "X server failed to initialize touchscreen";
 
218
 
 
219
  utouch::evemu::Recording recording(device,
 
220
                                     "recordings/ntrig_dell_xt2/1_tap.record");
 
221
 
 
222
  recording.Play();
 
223
 
 
224
  PumpEvents();
 
225
 
 
226
  EXPECT_TRUE(saw_tap_);
 
227
}