2
* Copyright Ā© 2015 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 3,
6
* as published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
19
#include "src/platforms/evdev/libinput_device.h"
20
#include "src/server/report/null_report_factory.h"
21
#include "src/server/input/default_event_builder.h"
23
#include "mir/input/input_device_registry.h"
24
#include "mir/input/input_sink.h"
25
#include "mir/geometry/point.h"
26
#include "mir/geometry/rectangle.h"
27
#include "mir/test/event_matchers.h"
28
#include "mir/test/doubles/mock_libinput.h"
29
#include "mir/test/gmock_fixes.h"
30
#include "mir_test_framework/udev_environment.h"
32
#include <gmock/gmock.h>
33
#include <gtest/gtest.h>
34
#include <linux/input.h>
38
namespace mi = mir::input;
39
namespace mie = mi::evdev;
40
namespace mt = mir::test;
41
namespace mtf = mir_test_framework;
42
namespace mtd = mt::doubles;
43
namespace geom = mir::geometry;
48
class StubInputDeviceRegistry : public mi::InputDeviceRegistry
51
void add_device(std::shared_ptr<mi::InputDevice> const&) override {}
52
void remove_device(std::shared_ptr<mi::InputDevice> const&) override {}
55
using namespace ::testing;
57
struct MockInputSink : mi::InputSink
61
ON_CALL(*this, bounding_rectangle())
62
.WillByDefault(Return(geom::Rectangle({0,0}, {100,100})));
64
MOCK_METHOD1(handle_input,void(MirEvent &));
65
MOCK_METHOD1(confine_pointer, void(geom::Point&));
66
MOCK_CONST_METHOD0(bounding_rectangle, geom::Rectangle());
69
struct MockEventBuilder : mi::EventBuilder
71
mi::DefaultEventBuilder builder{MirInputDeviceId{3}};
74
ON_CALL(*this, key_event(_,_,_,_,_))
75
.WillByDefault(Invoke([this](Timestamp time, MirKeyboardAction action, xkb_keysym_t key, int scan_code,
76
MirInputEventModifiers modifier)
78
return builder.key_event(time, action, key, scan_code, modifier);
80
ON_CALL(*this, touch_event(_,_))
81
.WillByDefault(Invoke([this](Timestamp time, MirInputEventModifiers modifier)
83
return builder.touch_event(time, modifier);
85
ON_CALL(*this, add_touch(_,_,_,_,_,_,_,_,_,_))
86
.WillByDefault(Invoke([this](MirEvent& event, MirTouchId id, MirTouchAction action,
87
MirTouchTooltype tooltype, float x, float y, float major, float minor,
88
float pressure, float size)
90
return builder.add_touch(event, id, action, tooltype, x, y, major, minor,
93
ON_CALL(*this, pointer_event(_,_,_,_,_,_,_,_,_,_))
94
.WillByDefault(Invoke([this](Timestamp time, MirInputEventModifiers modifier, MirPointerAction action,
95
MirPointerButtons buttons, float x, float y, float hscroll, float vscroll,
96
float relative_x, float relative_y)
98
return builder.pointer_event(time, modifier, action, buttons, x, y, hscroll,
99
vscroll, relative_x, relative_y);
101
ON_CALL(*this, configuration_event(_,_))
102
.WillByDefault(Invoke([this](Timestamp time, MirInputConfigurationAction action)
104
return builder.configuration_event(time, action);
107
using EventBuilder::Timestamp;
108
MOCK_METHOD5(key_event, mir::EventUPtr(Timestamp, MirKeyboardAction, xkb_keysym_t, int, MirInputEventModifiers));
110
MOCK_METHOD2(touch_event, mir::EventUPtr(Timestamp, MirInputEventModifiers));
111
MOCK_METHOD10(add_touch, void(MirEvent&, MirTouchId, MirTouchAction, MirTouchTooltype, float, float, float, float,
114
MOCK_METHOD10(pointer_event, mir::EventUPtr(Timestamp, MirInputEventModifiers, MirPointerAction, MirPointerButtons,
115
float, float, float, float, float, float));
116
MOCK_METHOD2(configuration_event, mir::EventUPtr(Timestamp, MirInputConfigurationAction));
119
struct LibInputDevice : public ::testing::Test
121
mtf::UdevEnvironment env;
122
::testing::NiceMock<mir::test::doubles::MockLibInput> mock_libinput;
123
::testing::NiceMock<MockInputSink> mock_sink;
124
::testing::NiceMock<MockEventBuilder> mock_builder;
126
libinput* fake_input = reinterpret_cast<libinput*>(0xF4C3);
127
libinput_device* fake_device = reinterpret_cast<libinput_device*>(0xF4C4);
128
libinput_event* fake_event_1 = reinterpret_cast<libinput_event*>(0xF4C5);
129
libinput_event* fake_event_2 = reinterpret_cast<libinput_event*>(0xF4C6);
130
libinput_event* fake_event_3 = reinterpret_cast<libinput_event*>(0xF4C7);
131
libinput_event* fake_event_4 = reinterpret_cast<libinput_event*>(0xF4C8);
132
libinput_device* second_fake_device = reinterpret_cast<libinput_device*>(0xF4C9);
134
const uint64_t event_time_1 = 1000;
135
const mi::EventBuilder::Timestamp time_stamp_1{std::chrono::microseconds{event_time_1}};
136
const uint64_t event_time_2 = 2000;
137
const mi::EventBuilder::Timestamp time_stamp_2{std::chrono::microseconds{event_time_2}};
138
const uint64_t event_time_3 = 3000;
139
const mi::EventBuilder::Timestamp time_stamp_3{std::chrono::microseconds{event_time_3}};
140
const uint64_t event_time_4 = 4000;
141
const mi::EventBuilder::Timestamp time_stamp_4{std::chrono::microseconds{event_time_4}};
143
char const* laptop_keyboard_device_path = "/dev/input/event4";
144
char const* path{laptop_keyboard_device_path};
148
setup_device(fake_device, path, "laptop-keyboard", 5252, 3113);
150
ON_CALL(mock_libinput, libinput_path_create_context(_,_))
151
.WillByDefault(Return(fake_input));
154
void setup_device(libinput_device* dev, char const* device_path, char const* umock_name, unsigned int vendor_id, unsigned int product_id)
156
env.add_standard_device(umock_name);
157
mock_libinput.setup_device(fake_input, dev, device_path, umock_name, vendor_id, product_id);
160
void setup_pointer_configuration(libinput_device* dev, double accel_speed, MirPointerButton primary)
162
EXPECT_CALL(mock_libinput, libinput_device_config_accel_get_speed(dev))
163
.WillRepeatedly(Return(accel_speed));
164
EXPECT_CALL(mock_libinput, libinput_device_config_left_handed_get(dev))
165
.WillRepeatedly(Return(primary == mir_pointer_button_secondary));
168
void setup_key_event(libinput_event* event, uint64_t event_time, uint32_t key, libinput_key_state state)
170
auto key_event = reinterpret_cast<libinput_event_keyboard*>(event);
172
EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
173
.WillRepeatedly(Return(LIBINPUT_EVENT_KEYBOARD_KEY));
174
EXPECT_CALL(mock_libinput, libinput_event_get_keyboard_event(event))
175
.WillRepeatedly(Return(key_event));
176
EXPECT_CALL(mock_libinput, libinput_event_keyboard_get_time_usec(key_event))
177
.WillRepeatedly(Return(event_time));
178
EXPECT_CALL(mock_libinput, libinput_event_keyboard_get_key(key_event))
179
.WillRepeatedly(Return(key));
180
EXPECT_CALL(mock_libinput, libinput_event_keyboard_get_key_state(key_event))
181
.WillRepeatedly(Return(state));
184
void setup_pointer_event(libinput_event* event, uint64_t event_time, float relatve_x, float relatve_y)
186
auto pointer_event = reinterpret_cast<libinput_event_pointer*>(event);
188
EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
189
.WillRepeatedly(Return(LIBINPUT_EVENT_POINTER_MOTION));
190
EXPECT_CALL(mock_libinput, libinput_event_get_pointer_event(event))
191
.WillRepeatedly(Return(pointer_event));
192
EXPECT_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
193
.WillRepeatedly(Return(event_time));
194
EXPECT_CALL(mock_libinput, libinput_event_pointer_get_dx(pointer_event))
195
.WillRepeatedly(Return(relatve_x));
196
EXPECT_CALL(mock_libinput, libinput_event_pointer_get_dy(pointer_event))
197
.WillRepeatedly(Return(relatve_y));
200
void setup_button_event(libinput_event* event, uint64_t event_time, int button, libinput_button_state state)
202
auto pointer_event = reinterpret_cast<libinput_event_pointer*>(event);
204
EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
205
.WillRepeatedly(Return(LIBINPUT_EVENT_POINTER_BUTTON));
206
EXPECT_CALL(mock_libinput, libinput_event_get_pointer_event(event))
207
.WillRepeatedly(Return(pointer_event));
208
EXPECT_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
209
.WillRepeatedly(Return(event_time));
210
EXPECT_CALL(mock_libinput, libinput_event_pointer_get_button(pointer_event))
211
.WillRepeatedly(Return(button));
212
EXPECT_CALL(mock_libinput, libinput_event_pointer_get_button_state(pointer_event))
213
.WillRepeatedly(Return(state));
216
void setup_axis_event(libinput_event* event, uint64_t event_time, double horizontal, double vertical)
218
auto pointer_event = reinterpret_cast<libinput_event_pointer*>(event);
220
EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
221
.WillRepeatedly(Return(LIBINPUT_EVENT_POINTER_AXIS));
222
EXPECT_CALL(mock_libinput, libinput_event_get_pointer_event(event))
223
.WillRepeatedly(Return(pointer_event));
224
EXPECT_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
225
.WillRepeatedly(Return(event_time));
226
EXPECT_CALL(mock_libinput, libinput_event_pointer_has_axis(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
227
.WillRepeatedly(Return(horizontal!=0.0));
228
EXPECT_CALL(mock_libinput, libinput_event_pointer_has_axis(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
229
.WillRepeatedly(Return(vertical!=0.0));
230
EXPECT_CALL(mock_libinput, libinput_event_pointer_get_axis_value(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
231
.WillRepeatedly(Return(vertical));
232
EXPECT_CALL(mock_libinput, libinput_event_pointer_get_axis_value(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
233
.WillRepeatedly(Return(horizontal));
236
void setup_touch_event(libinput_event* event, libinput_event_type type, uint64_t event_time, int slot, float x,
237
float y, float major, float minor, float pressure)
239
auto touch_event = reinterpret_cast<libinput_event_touch*>(event);
241
EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
242
.WillRepeatedly(Return(type));
243
EXPECT_CALL(mock_libinput, libinput_event_get_touch_event(event))
244
.WillRepeatedly(Return(touch_event));
245
EXPECT_CALL(mock_libinput, libinput_event_touch_get_slot(touch_event))
246
.WillRepeatedly(Return(slot));
247
EXPECT_CALL(mock_libinput, libinput_event_touch_get_x_transformed(touch_event, _))
248
.WillRepeatedly(Return(x));
249
EXPECT_CALL(mock_libinput, libinput_event_touch_get_y_transformed(touch_event, _))
250
.WillRepeatedly(Return(y));
251
EXPECT_CALL(mock_libinput, libinput_event_touch_get_time_usec(touch_event))
252
.WillRepeatedly(Return(event_time));
253
EXPECT_CALL(mock_libinput, libinput_event_touch_get_major_transformed(touch_event, _, _))
254
.WillRepeatedly(Return(major));
255
EXPECT_CALL(mock_libinput, libinput_event_touch_get_minor_transformed(touch_event, _, _))
256
.WillRepeatedly(Return(minor));
257
EXPECT_CALL(mock_libinput, libinput_event_touch_get_pressure(touch_event))
258
.WillRepeatedly(Return(pressure));
261
void setup_touch_up_event(libinput_event* event, uint64_t event_time, int slot)
263
auto touch_event = reinterpret_cast<libinput_event_touch*>(event);
265
EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
266
.WillRepeatedly(Return(LIBINPUT_EVENT_TOUCH_UP));
267
EXPECT_CALL(mock_libinput, libinput_event_get_touch_event(event))
268
.WillRepeatedly(Return(touch_event));
269
EXPECT_CALL(mock_libinput, libinput_event_touch_get_slot(touch_event))
270
.WillRepeatedly(Return(slot));
271
EXPECT_CALL(mock_libinput, libinput_event_touch_get_x_transformed(touch_event, _))
273
EXPECT_CALL(mock_libinput, libinput_event_touch_get_y_transformed(touch_event, _))
275
EXPECT_CALL(mock_libinput, libinput_event_touch_get_x(touch_event))
277
EXPECT_CALL(mock_libinput, libinput_event_touch_get_y(touch_event))
279
EXPECT_CALL(mock_libinput, libinput_event_touch_get_time_usec(touch_event))
280
.WillRepeatedly(Return(event_time));
281
EXPECT_CALL(mock_libinput, libinput_event_touch_get_major_transformed(touch_event, _, _))
283
EXPECT_CALL(mock_libinput, libinput_event_touch_get_minor_transformed(touch_event, _, _))
285
EXPECT_CALL(mock_libinput, libinput_event_touch_get_pressure(touch_event))
290
void setup_touch_frame(libinput_event* event)
292
EXPECT_CALL(mock_libinput, libinput_event_get_type(event))
293
.WillRepeatedly(Return(LIBINPUT_EVENT_TOUCH_FRAME));
299
TEST_F(LibInputDevice, start_creates_and_unrefs_libinput_device_from_path)
301
EXPECT_CALL(mock_libinput, libinput_path_add_device(fake_input,StrEq(path)))
303
// according to manual libinput_path_add_device creates a temporary device with a ref count 0.
304
// hence it needs a manual ref call
305
EXPECT_CALL(mock_libinput, libinput_device_ref(fake_device))
307
std::shared_ptr<libinput> lib = mie::make_libinput();
308
mie::LibInputDevice dev(mir::report::null_input_report(),
310
std::move(mie::make_libinput_device(lib.get(), path)));
311
dev.start(&mock_sink, &mock_builder);
314
TEST_F(LibInputDevice, open_device_of_group)
316
std::shared_ptr<libinput> lib = mie::make_libinput();
317
char const* second_dev = "/dev/input/event13";
318
char const* second_umock_dev_name = "bluetooth-magic-trackpad";
320
setup_device(second_fake_device, second_dev, second_umock_dev_name, 9663, 1234);
323
EXPECT_CALL(mock_libinput, libinput_path_add_device(fake_input,StrEq(path))).Times(1);
324
// according to manual libinput_path_add_device creates a temporary device with a ref count 0.
325
// hence it needs a manual ref call
326
EXPECT_CALL(mock_libinput, libinput_device_ref(fake_device)).Times(1);
327
EXPECT_CALL(mock_libinput, libinput_path_add_device(fake_input,StrEq(second_dev))).Times(1);
328
EXPECT_CALL(mock_libinput, libinput_device_ref(second_fake_device)).Times(1);
330
mie::LibInputDevice dev(mir::report::null_input_report(),
332
std::move(mie::make_libinput_device(lib.get(), path)));
333
dev.add_device_of_group(second_dev, mie::make_libinput_device(lib.get(), second_dev));
334
dev.start(&mock_sink, &mock_builder);
337
TEST_F(LibInputDevice, input_info_combines_capabilities)
339
std::shared_ptr<libinput> lib = mie::make_libinput();
340
char const* second_dev = "/dev/input/event13";
341
char const* second_umock_dev_name = "bluetooth-magic-trackpad";
343
setup_device(second_fake_device, second_dev, second_umock_dev_name, 9663, 1234);
345
mie::LibInputDevice dev(mir::report::null_input_report(),
347
mie::make_libinput_device(lib.get(), path));
348
dev.add_device_of_group(second_dev, mie::make_libinput_device(lib.get(), second_dev));
349
auto info = dev.get_device_info();
351
EXPECT_THAT(info.capabilities, Eq(mi::DeviceCapability::touchpad|
352
mi::DeviceCapability::keyboard|
353
mi::DeviceCapability::alpha_numeric));
356
TEST_F(LibInputDevice, removal_unrefs_libinput_device)
358
std::shared_ptr<libinput> lib = mie::make_libinput();
360
EXPECT_CALL(mock_libinput, libinput_device_unref(fake_device))
363
mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
367
TEST_F(LibInputDevice, process_event_converts_key_event)
369
std::shared_ptr<libinput> lib = mie::make_libinput();
370
mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
372
setup_key_event(fake_event_1, event_time_1, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
373
setup_key_event(fake_event_2, event_time_2, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
375
EXPECT_CALL(mock_builder, key_event(time_stamp_1, mir_keyboard_action_down, _, KEY_A, mir_input_event_modifier_none));
376
EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_A),mt::KeyDownEvent())));
377
EXPECT_CALL(mock_builder, key_event(time_stamp_2, mir_keyboard_action_up, _, KEY_A, mir_input_event_modifier_none));
378
EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_A),mt::KeyUpEvent())));
380
dev.start(&mock_sink, &mock_builder);
381
dev.process_event(fake_event_1);
382
dev.process_event(fake_event_2);
385
TEST_F(LibInputDevice, process_event_accumulates_key_state)
387
std::shared_ptr<libinput> lib = mie::make_libinput();
388
mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
391
setup_key_event(fake_event_1, event_time_1, KEY_C, LIBINPUT_KEY_STATE_PRESSED);
392
setup_key_event(fake_event_2, event_time_2, KEY_LEFTALT, LIBINPUT_KEY_STATE_PRESSED);
393
setup_key_event(fake_event_3, event_time_3, KEY_C, LIBINPUT_KEY_STATE_RELEASED);
396
EXPECT_CALL(mock_builder, key_event(time_stamp_1, mir_keyboard_action_down, _, KEY_C, mir_input_event_modifier_none));
397
EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_C),mt::KeyDownEvent())));
398
EXPECT_CALL(mock_builder, key_event(time_stamp_2, mir_keyboard_action_down, _, KEY_LEFTALT, mir_input_event_modifier_none));
399
EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_LEFTALT),mt::KeyDownEvent())));
400
EXPECT_CALL(mock_builder, key_event(time_stamp_3, mir_keyboard_action_up, _, KEY_C, mir_input_event_modifier_alt|mir_input_event_modifier_alt_left));
401
EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_C),
402
mt::KeyWithModifiers(
403
MirInputEventModifiers{
404
mir_input_event_modifier_alt|
405
mir_input_event_modifier_alt_left
409
dev.start(&mock_sink, &mock_builder);
410
dev.process_event(fake_event_1);
411
dev.process_event(fake_event_2);
412
dev.process_event(fake_event_3);
415
TEST_F(LibInputDevice, process_event_converts_pointer_event)
417
std::shared_ptr<libinput> lib = mie::make_libinput();
418
mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
422
setup_pointer_event(fake_event_1, event_time_1, x, y);
424
EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithPosition(x,y)));
426
dev.start(&mock_sink, &mock_builder);
427
dev.process_event(fake_event_1);
430
TEST_F(LibInputDevice, process_event_provides_relative_coordinates)
432
std::shared_ptr<libinput> lib = mie::make_libinput();
433
mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
437
setup_pointer_event(fake_event_1, event_time_1, x, y);
439
EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithDiff(x,y)));
441
dev.start(&mock_sink, &mock_builder);
442
dev.process_event(fake_event_1);
445
TEST_F(LibInputDevice, process_event_accumulates_pointer_movement)
447
std::shared_ptr<libinput> lib = mie::make_libinput();
448
mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
450
float x1 = 15, x2 = 23;
451
float y1 = 17, y2 = 21;
453
setup_pointer_event(fake_event_1, event_time_1, x1, y1);
454
setup_pointer_event(fake_event_2, event_time_2, x2, y2);
456
EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithPosition(x1,y1)));
457
EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithPosition(x1+x2,y1+y2)));
459
dev.start(&mock_sink, &mock_builder);
460
dev.process_event(fake_event_1);
461
dev.process_event(fake_event_2);
464
TEST_F(LibInputDevice, process_event_handles_press_and_release)
466
std::shared_ptr<libinput> lib = mie::make_libinput();
467
mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
470
geom::Point const pos{x,y};
472
setup_button_event(fake_event_1, event_time_1, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
473
setup_button_event(fake_event_2, event_time_2, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
474
setup_button_event(fake_event_3, event_time_3, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
475
setup_button_event(fake_event_4, event_time_4, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
478
EXPECT_CALL(mock_sink, handle_input(mt::ButtonDownEventWithButton(pos, mir_pointer_button_primary)));
479
EXPECT_CALL(mock_sink, handle_input(mt::ButtonDownEventWithButton(pos, mir_pointer_button_secondary)));
480
EXPECT_CALL(mock_sink, handle_input(mt::ButtonUpEventWithButton(pos, mir_pointer_button_secondary)));
481
EXPECT_CALL(mock_sink, handle_input(mt::ButtonUpEventWithButton(pos, mir_pointer_button_primary)));
483
dev.start(&mock_sink, &mock_builder);
484
dev.process_event(fake_event_1);
485
dev.process_event(fake_event_2);
486
dev.process_event(fake_event_3);
487
dev.process_event(fake_event_4);
490
TEST_F(LibInputDevice, process_event_handles_scroll)
492
std::shared_ptr<libinput> lib = mie::make_libinput();
493
mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
495
setup_axis_event(fake_event_1, event_time_1, 0.0, 20.0);
496
setup_axis_event(fake_event_2, event_time_2, 5.0, 0.0);
499
// expect two scroll events..
500
EXPECT_CALL(mock_builder, pointer_event(time_stamp_1, mir_input_event_modifier_none, mir_pointer_action_motion, 0, 0.0f, 0.0f, 0.0f, 20.0f, 0.0f, 0.0f));
501
EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_vscroll, 20.0f)));
502
EXPECT_CALL(mock_builder, pointer_event(time_stamp_2, mir_input_event_modifier_none, mir_pointer_action_motion, 0, 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f));
503
EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_hscroll, 5.0f)));
505
dev.start(&mock_sink, &mock_builder);
506
dev.process_event(fake_event_1);
507
dev.process_event(fake_event_2);
510
TEST_F(LibInputDevice, process_event_handles_touch_down_events)
512
std::shared_ptr<libinput> lib = mie::make_libinput();
513
mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
518
float pressure = 0.6f;
522
setup_touch_event(fake_event_1, LIBINPUT_EVENT_TOUCH_DOWN, event_time_1, slot, x, y, major, minor, pressure);
523
setup_touch_frame(fake_event_2);
526
EXPECT_CALL(mock_builder, touch_event(time_stamp_1, mir_input_event_modifier_none));
527
EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{0}, mir_touch_action_down, mir_touch_tooltype_finger, x, y,
528
pressure, major, minor, major));
529
EXPECT_CALL(mock_sink, handle_input(mt::TouchEvent(x,y)));
531
dev.start(&mock_sink, &mock_builder);
532
dev.process_event(fake_event_1);
533
dev.process_event(fake_event_2);
536
TEST_F(LibInputDevice, process_event_handles_touch_move_events)
538
std::shared_ptr<libinput> lib = mie::make_libinput();
539
mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
544
float pressure = 0.6f;
548
setup_touch_event(fake_event_1, LIBINPUT_EVENT_TOUCH_MOTION, event_time_1, slot, x, y, major, minor, pressure);
549
setup_touch_frame(fake_event_2);
552
EXPECT_CALL(mock_builder, touch_event(time_stamp_1, mir_input_event_modifier_none));
553
EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{0}, mir_touch_action_change, mir_touch_tooltype_finger, x, y,
554
pressure, major, minor, major));
555
EXPECT_CALL(mock_sink, handle_input(mt::TouchMovementEvent()));
557
dev.start(&mock_sink, &mock_builder);
558
dev.process_event(fake_event_1);
559
dev.process_event(fake_event_2);
562
TEST_F(LibInputDevice, process_event_handles_touch_up_events_without_querying_properties)
564
std::shared_ptr<libinput> lib = mie::make_libinput();
565
mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
570
float pressure = 0.6f;
574
setup_touch_event(fake_event_1, LIBINPUT_EVENT_TOUCH_DOWN, event_time_1, slot, x, y, major, minor, pressure);
575
setup_touch_frame(fake_event_2);
576
setup_touch_up_event(fake_event_3, event_time_2, slot);
577
setup_touch_frame(fake_event_4);
580
EXPECT_CALL(mock_builder, touch_event(time_stamp_1, mir_input_event_modifier_none));
581
EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{slot}, mir_touch_action_down, mir_touch_tooltype_finger, x, y,
582
pressure, major, minor, major));
583
EXPECT_CALL(mock_sink, handle_input(mt::TouchEvent(x,y)));
585
EXPECT_CALL(mock_builder, touch_event(time_stamp_2, mir_input_event_modifier_none));
586
EXPECT_CALL(mock_builder, add_touch(_, MirTouchId{slot}, mir_touch_action_up, mir_touch_tooltype_finger, x, y,
587
pressure, major, minor, major));
588
EXPECT_CALL(mock_sink, handle_input(mt::TouchUpEvent(x,y)));
590
dev.start(&mock_sink, &mock_builder);
591
dev.process_event(fake_event_1);
592
dev.process_event(fake_event_2);
593
dev.process_event(fake_event_3);
594
dev.process_event(fake_event_4);