| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ui/events/ozone/evdev/tablet_event_converter_evdev.h" |
| |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <linux/input.h> |
| #include <unistd.h> |
| |
| #include <memory> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/bind.h" |
| #include "base/files/file_util.h" |
| #include "base/files/scoped_file.h" |
| #include "base/macros.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/posix/eintr_wrapper.h" |
| #include "base/run_loop.h" |
| #include "base/time/time.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/events/event.h" |
| #include "ui/events/ozone/device/device_manager.h" |
| #include "ui/events/ozone/evdev/event_converter_test_util.h" |
| #include "ui/events/ozone/evdev/event_device_test_util.h" |
| #include "ui/events/ozone/evdev/event_factory_evdev.h" |
| #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" |
| #include "ui/events/platform/platform_event_dispatcher.h" |
| #include "ui/events/platform/platform_event_source.h" |
| #include "ui/events/test/scoped_event_test_tick_clock.h" |
| |
| namespace { |
| |
| const char kTestDevicePath[] = "/dev/input/test-device"; |
| |
| const ui::DeviceAbsoluteAxis kWacomIntuos5SPenAbsAxes[] = { |
| {ABS_X, {0, 0, 31496, 4, 0, 200}}, |
| {ABS_Y, {0, 0, 19685, 4, 0, 200}}, |
| {ABS_Z, {0, -900, 899, 0, 0, 0}}, |
| {ABS_RZ, {0, -900, 899, 0, 0, 0}}, |
| {ABS_THROTTLE, {0, -1023, 1023, 0, 0, 0}}, |
| {ABS_WHEEL, {0, 0, 1023, 0, 0, 0}}, |
| {ABS_PRESSURE, {0, 0, 2047, 0, 0, 0}}, |
| {ABS_DISTANCE, {0, 0, 63, 0, 0, 0}}, |
| {ABS_TILT_X, {0, 0, 127, 0, 0, 0}}, |
| {ABS_TILT_Y, {0, 0, 127, 0, 0, 0}}, |
| {ABS_MISC, {0, 0, 0, 0, 0, 0}}, |
| }; |
| |
| const ui::DeviceCapabilities kWacomIntuos5SPen = { |
| /* path */ "/sys/devices/pci0000:00/0000:00:14.0/usb1/" |
| "1-1/1-1:1.0/input/input19/event5", |
| /* name */ "Wacom Intuos5 touch S Pen", |
| /* phys */ "", |
| /* uniq */ "", |
| /* bustype */ "0003", |
| /* vendor */ "056a", |
| /* product */ "0026", |
| /* version */ "0107", |
| /* prop */ "1", |
| /* ev */ "1f", |
| /* key */ "1cdf 1f007f 0 0 0 0", |
| /* rel */ "100", |
| /* abs */ "1000f000167", |
| /* msc */ "1", |
| /* sw */ "0", |
| /* led */ "0", |
| /* ff */ "0", |
| kWacomIntuos5SPenAbsAxes, |
| arraysize(kWacomIntuos5SPenAbsAxes), |
| }; |
| |
| |
| const ui::DeviceAbsoluteAxis EpsonBrightLink1430AbsAxes[] = { |
| {ABS_X, {0, 0, 32767, 0, 0, 200}}, |
| {ABS_Y, {0, 0, 32767, 0, 0, 200}}, |
| {ABS_Z, {0, 0, 32767, 0, 0, 200}}, |
| {ABS_RX,{0, 0, 32767, 0, 0, 200}}, |
| {ABS_PRESSURE, {0, 0, 32767, 0, 0, 0}}, |
| }; |
| |
| const ui::DeviceCapabilities EpsonBrightLink1430 = { |
| /* path */ "/sys/devices/ff580000.usb/usb3/3-1/" |
| "3-1.1/3-1.1.3/3-1.1.3:1.1/0003:04B8:061B.0006/" |
| "input/input12/event6", |
| /* name */ "EPSON EPSON EPSON 1430", |
| /* phys */ "USB-ff580000.USB-1.1.3/input1", |
| /* uniq */ "2.04", |
| /* bustype */ "0003", |
| /* vendor */ "04b8", |
| /* product */ "061b", |
| /* version */ "0200", |
| /* prop */ "0", |
| /* ev */ "1b", |
| /* key */ "c07 30000 0 0 0 0", |
| /* rel */ "0", |
| /* abs */ "100000f", |
| /* msc */ "10", |
| /* sw */ "0", |
| /* led */ "0", |
| /* ff */ "0", |
| EpsonBrightLink1430AbsAxes, |
| arraysize(EpsonBrightLink1430AbsAxes), |
| }; |
| |
| } // namespace |
| |
| namespace ui { |
| |
| class MockTabletEventConverterEvdev : public TabletEventConverterEvdev { |
| public: |
| MockTabletEventConverterEvdev(base::ScopedFD fd, |
| base::FilePath path, |
| CursorDelegateEvdev* cursor, |
| const EventDeviceInfo& devinfo, |
| DeviceEventDispatcherEvdev* dispatcher); |
| ~MockTabletEventConverterEvdev() override {} |
| |
| void ConfigureReadMock(struct input_event* queue, |
| long read_this_many, |
| long queue_index); |
| |
| // Actually dispatch the event reader code. |
| void ReadNow() { |
| OnFileCanReadWithoutBlocking(read_pipe_); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| private: |
| int read_pipe_; |
| int write_pipe_; |
| |
| std::vector<std::unique_ptr<Event>> dispatched_events_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MockTabletEventConverterEvdev); |
| }; |
| |
| class MockTabletCursorEvdev : public CursorDelegateEvdev { |
| public: |
| MockTabletCursorEvdev() { cursor_confined_bounds_ = gfx::Rect(1024, 768); } |
| ~MockTabletCursorEvdev() override {} |
| |
| // CursorDelegateEvdev: |
| void MoveCursorTo(gfx::AcceleratedWidget widget, |
| const gfx::PointF& location) override { |
| NOTREACHED(); |
| } |
| void MoveCursorTo(const gfx::PointF& location) override { |
| cursor_location_ = location; |
| } |
| void MoveCursor(const gfx::Vector2dF& delta) override { NOTREACHED(); } |
| bool IsCursorVisible() override { return 1; } |
| gfx::PointF GetLocation() override { return cursor_location_; } |
| gfx::Rect GetCursorConfinedBounds() override { |
| return cursor_confined_bounds_; |
| } |
| void InitializeOnEvdev() override {} |
| private: |
| gfx::PointF cursor_location_; |
| gfx::Rect cursor_confined_bounds_; |
| DISALLOW_COPY_AND_ASSIGN(MockTabletCursorEvdev); |
| }; |
| |
| MockTabletEventConverterEvdev::MockTabletEventConverterEvdev( |
| base::ScopedFD fd, |
| base::FilePath path, |
| CursorDelegateEvdev* cursor, |
| const EventDeviceInfo& devinfo, |
| DeviceEventDispatcherEvdev* dispatcher) |
| : TabletEventConverterEvdev(std::move(fd), |
| path, |
| 1, |
| cursor, |
| devinfo, |
| dispatcher) { |
| int fds[2]; |
| |
| if (pipe(fds)) |
| PLOG(FATAL) << "failed pipe"; |
| |
| EXPECT_TRUE(base::SetNonBlocking(fds[0]) || base::SetNonBlocking(fds[1])) |
| << "failed to set non-blocking: " << strerror(errno); |
| |
| read_pipe_ = fds[0]; |
| write_pipe_ = fds[1]; |
| } |
| |
| void MockTabletEventConverterEvdev::ConfigureReadMock(struct input_event* queue, |
| long read_this_many, |
| long queue_index) { |
| int nwrite = HANDLE_EINTR(write(write_pipe_, queue + queue_index, |
| sizeof(struct input_event) * read_this_many)); |
| DCHECK(nwrite == |
| static_cast<int>(sizeof(struct input_event) * read_this_many)) |
| << "write() failed, errno: " << errno; |
| } |
| |
| } // namespace ui |
| |
| // Test fixture. |
| class TabletEventConverterEvdevTest : public testing::Test { |
| public: |
| TabletEventConverterEvdevTest() {} |
| |
| // Overridden from testing::Test: |
| void SetUp() override { |
| cursor_.reset(new ui::MockTabletCursorEvdev()); |
| device_manager_ = ui::CreateDeviceManagerForTest(); |
| event_factory_ = ui::CreateEventFactoryEvdevForTest( |
| cursor_.get(), device_manager_.get(), |
| ui::KeyboardLayoutEngineManager::GetKeyboardLayoutEngine(), |
| base::BindRepeating( |
| &TabletEventConverterEvdevTest::DispatchEventForTest, |
| base::Unretained(this))); |
| dispatcher_ = |
| ui::CreateDeviceEventDispatcherEvdevForTest(event_factory_.get()); |
| |
| test_clock_.reset(new ui::test::ScopedEventTestTickClock()); |
| } |
| |
| void TearDown() override { |
| cursor_.reset(); |
| } |
| |
| ui::MockTabletEventConverterEvdev* CreateDevice( |
| const ui::DeviceCapabilities& caps) { |
| // Set up pipe to satisfy message pump (unused). |
| int evdev_io[2]; |
| if (pipe(evdev_io)) |
| PLOG(FATAL) << "failed pipe"; |
| base::ScopedFD events_in(evdev_io[0]); |
| events_out_.reset(evdev_io[1]); |
| |
| ui::EventDeviceInfo devinfo; |
| CapabilitiesToDeviceInfo(caps, &devinfo); |
| return new ui::MockTabletEventConverterEvdev( |
| std::move(events_in), base::FilePath(kTestDevicePath), cursor_.get(), |
| devinfo, dispatcher_.get()); |
| } |
| |
| ui::CursorDelegateEvdev* cursor() { return cursor_.get(); } |
| |
| unsigned size() { return dispatched_events_.size(); } |
| ui::MouseEvent* dispatched_event(unsigned index) { |
| DCHECK_GT(dispatched_events_.size(), index); |
| ui::Event* ev = dispatched_events_[index].get(); |
| DCHECK(ev->IsMouseEvent()); |
| return ev->AsMouseEvent(); |
| } |
| |
| void DispatchEventForTest(ui::Event* event) { |
| std::unique_ptr<ui::Event> cloned_event = ui::Event::Clone(*event); |
| dispatched_events_.push_back(std::move(cloned_event)); |
| } |
| |
| private: |
| std::unique_ptr<ui::MockTabletCursorEvdev> cursor_; |
| std::unique_ptr<ui::DeviceManager> device_manager_; |
| std::unique_ptr<ui::EventFactoryEvdev> event_factory_; |
| std::unique_ptr<ui::DeviceEventDispatcherEvdev> dispatcher_; |
| std::unique_ptr<ui::test::ScopedEventTestTickClock> test_clock_; |
| |
| std::vector<std::unique_ptr<ui::Event>> dispatched_events_; |
| |
| base::ScopedFD events_out_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TabletEventConverterEvdevTest); |
| }; |
| |
| #define EPSILON 20 |
| |
| // Uses real data captured from Wacom Intuos 5 Pen |
| TEST_F(TabletEventConverterEvdevTest, MoveTopLeft) { |
| std::unique_ptr<ui::MockTabletEventConverterEvdev> dev = |
| base::WrapUnique(CreateDevice(kWacomIntuos5SPen)); |
| |
| struct input_event mock_kernel_queue[] = { |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 63}, |
| {{0, 0}, EV_ABS, ABS_X, 477}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 66}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 62}, |
| {{0, 0}, EV_ABS, ABS_MISC, 1050626}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 0}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0}, |
| {{0, 0}, EV_ABS, ABS_MISC, 0}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| }; |
| |
| dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue)); |
| EXPECT_EQ(1u, size()); |
| |
| ui::MouseEvent* event = dispatched_event(0); |
| EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type()); |
| |
| EXPECT_LT(cursor()->GetLocation().x(), EPSILON); |
| EXPECT_LT(cursor()->GetLocation().y(), EPSILON); |
| } |
| |
| TEST_F(TabletEventConverterEvdevTest, MoveTopRight) { |
| std::unique_ptr<ui::MockTabletEventConverterEvdev> dev = |
| base::WrapUnique(CreateDevice(kWacomIntuos5SPen)); |
| |
| struct input_event mock_kernel_queue[] = { |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 63}, |
| {{0, 0}, EV_ABS, ABS_X, 31496}, |
| {{0, 0}, EV_ABS, ABS_Y, 109}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 66}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 61}, |
| {{0, 0}, EV_ABS, ABS_MISC, 1050626}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| {{0, 0}, EV_ABS, ABS_X, 0}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 0}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0}, |
| {{0, 0}, EV_ABS, ABS_MISC, 0}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| }; |
| |
| dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue)); |
| EXPECT_EQ(1u, size()); |
| |
| ui::MouseEvent* event = dispatched_event(0); |
| EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type()); |
| |
| EXPECT_GT(cursor()->GetLocation().x(), |
| cursor()->GetCursorConfinedBounds().width() - EPSILON); |
| EXPECT_LT(cursor()->GetLocation().y(), EPSILON); |
| } |
| |
| TEST_F(TabletEventConverterEvdevTest, MoveBottomLeft) { |
| std::unique_ptr<ui::MockTabletEventConverterEvdev> dev = |
| base::WrapUnique(CreateDevice(kWacomIntuos5SPen)); |
| |
| struct input_event mock_kernel_queue[] = { |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 63}, |
| {{0, 0}, EV_ABS, ABS_Y, 19685}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 64}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 61}, |
| {{0, 0}, EV_ABS, ABS_MISC, 1050626}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| {{0, 0}, EV_ABS, ABS_X, 0}, |
| {{0, 0}, EV_ABS, ABS_Y, 0}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 0}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0}, |
| {{0, 0}, EV_ABS, ABS_MISC, 0}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| }; |
| |
| dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue)); |
| EXPECT_EQ(1u, size()); |
| |
| ui::MouseEvent* event = dispatched_event(0); |
| EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type()); |
| |
| EXPECT_LT(cursor()->GetLocation().x(), EPSILON); |
| EXPECT_GT(cursor()->GetLocation().y(), |
| cursor()->GetCursorConfinedBounds().height() - EPSILON); |
| } |
| |
| TEST_F(TabletEventConverterEvdevTest, MoveBottomRight) { |
| std::unique_ptr<ui::MockTabletEventConverterEvdev> dev = |
| base::WrapUnique(CreateDevice(kWacomIntuos5SPen)); |
| |
| struct input_event mock_kernel_queue[] = { |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 63}, |
| {{0, 0}, EV_ABS, ABS_X, 31496}, |
| {{0, 0}, EV_ABS, ABS_Y, 19685}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 67}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 63}, |
| {{0, 0}, EV_ABS, ABS_MISC, 1050626}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| {{0, 0}, EV_ABS, ABS_X, 0}, |
| {{0, 0}, EV_ABS, ABS_Y, 0}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 0}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0}, |
| {{0, 0}, EV_ABS, ABS_MISC, 0}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| }; |
| |
| dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue)); |
| EXPECT_EQ(1u, size()); |
| |
| ui::MouseEvent* event = dispatched_event(0); |
| EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type()); |
| |
| EXPECT_GT(cursor()->GetLocation().x(), |
| cursor()->GetCursorConfinedBounds().height() - EPSILON); |
| EXPECT_GT(cursor()->GetLocation().y(), |
| cursor()->GetCursorConfinedBounds().height() - EPSILON); |
| } |
| |
| TEST_F(TabletEventConverterEvdevTest, Tap) { |
| std::unique_ptr<ui::MockTabletEventConverterEvdev> dev = |
| base::WrapUnique(CreateDevice(kWacomIntuos5SPen)); |
| |
| struct input_event mock_kernel_queue[] = { |
| {{0, 0}, EV_ABS, ABS_X, 15456}, |
| {{0, 0}, EV_ABS, ABS_Y, 8605}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 49}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 68}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 64}, |
| {{0, 0}, EV_ABS, ABS_MISC, 1050626}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| {{0, 0}, EV_ABS, ABS_X, 15725}, |
| {{0, 0}, EV_ABS, ABS_Y, 8755}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 29}, |
| {{0, 0}, EV_ABS, ABS_PRESSURE, 992}, |
| {{0, 0}, EV_KEY, BTN_TOUCH, 1}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| {{0, 0}, EV_ABS, ABS_X, 15922}, |
| {{0, 0}, EV_ABS, ABS_Y, 8701}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 32}, |
| {{0, 0}, EV_ABS, ABS_PRESSURE, 0}, |
| {{0, 0}, EV_KEY, BTN_TOUCH, 0}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| {{0, 0}, EV_ABS, ABS_X, 0}, |
| {{0, 0}, EV_ABS, ABS_Y, 0}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 0}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0}, |
| {{0, 0}, EV_ABS, ABS_MISC, 0}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| }; |
| |
| dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue)); |
| EXPECT_EQ(3u, size()); |
| |
| ui::MouseEvent* event = dispatched_event(0); |
| EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type()); |
| EXPECT_EQ(ui::EventPointerType::POINTER_TYPE_PEN, |
| event->pointer_details().pointer_type); |
| EXPECT_FLOAT_EQ(5.625f, event->pointer_details().tilt_x); |
| EXPECT_FLOAT_EQ(0.f, event->pointer_details().tilt_y); |
| event = dispatched_event(1); |
| EXPECT_EQ(ui::ET_MOUSE_PRESSED, event->type()); |
| EXPECT_EQ(ui::EventPointerType::POINTER_TYPE_PEN, |
| event->pointer_details().pointer_type); |
| EXPECT_FLOAT_EQ((float)992 / 2047, event->pointer_details().force); |
| EXPECT_EQ(true, event->IsLeftMouseButton()); |
| event = dispatched_event(2); |
| EXPECT_EQ(ui::EventPointerType::POINTER_TYPE_PEN, |
| event->pointer_details().pointer_type); |
| EXPECT_EQ(ui::ET_MOUSE_RELEASED, event->type()); |
| EXPECT_FLOAT_EQ(0.0f, event->pointer_details().force); |
| EXPECT_EQ(true, event->IsLeftMouseButton()); |
| } |
| |
| TEST_F(TabletEventConverterEvdevTest, StylusButtonPress) { |
| std::unique_ptr<ui::MockTabletEventConverterEvdev> dev = |
| base::WrapUnique(CreateDevice(kWacomIntuos5SPen)); |
| |
| struct input_event mock_kernel_queue[] = { |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 63}, |
| {{0, 0}, EV_ABS, ABS_X, 18372}, |
| {{0, 0}, EV_ABS, ABS_Y, 9880}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 61}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 60}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 63}, |
| {{0, 0}, EV_ABS, ABS_MISC, 1050626}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| {{0, 0}, EV_ABS, ABS_X, 18294}, |
| {{0, 0}, EV_ABS, ABS_Y, 9723}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 20}, |
| {{0, 0}, EV_ABS, ABS_PRESSURE, 1015}, |
| {{0, 0}, EV_KEY, BTN_STYLUS2, 1}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| {{0, 0}, EV_ABS, ABS_X, 18516}, |
| {{0, 0}, EV_ABS, ABS_Y, 9723}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 23}, |
| {{0, 0}, EV_KEY, BTN_STYLUS2, 0}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| {{0, 0}, EV_ABS, ABS_X, 0}, |
| {{0, 0}, EV_ABS, ABS_Y, 0}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 0}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0}, |
| {{0, 0}, EV_ABS, ABS_MISC, 0}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| }; |
| |
| dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue)); |
| EXPECT_EQ(3u, size()); |
| |
| ui::MouseEvent* event = dispatched_event(0); |
| EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type()); |
| event = dispatched_event(1); |
| EXPECT_EQ(ui::ET_MOUSE_PRESSED, event->type()); |
| EXPECT_EQ(true, event->IsRightMouseButton()); |
| event = dispatched_event(2); |
| EXPECT_EQ(ui::ET_MOUSE_RELEASED, event->type()); |
| EXPECT_EQ(true, event->IsRightMouseButton()); |
| } |
| |
| // Should only get an event if BTN_TOOL received |
| TEST_F(TabletEventConverterEvdevTest, CheckStylusFiltering) { |
| std::unique_ptr<ui::MockTabletEventConverterEvdev> dev = |
| base::WrapUnique(CreateDevice(kWacomIntuos5SPen)); |
| |
| struct input_event mock_kernel_queue[] = { |
| {{0, 0}, EV_ABS, ABS_X, 0}, |
| {{0, 0}, EV_ABS, ABS_Y, 0}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| }; |
| |
| dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue)); |
| EXPECT_EQ(0u, size()); |
| } |
| |
| // for digitizer pen with only one side button |
| TEST_F(TabletEventConverterEvdevTest, DigitizerPenOneSideButtonPress) { |
| std::unique_ptr<ui::MockTabletEventConverterEvdev> dev = |
| base::WrapUnique(CreateDevice(EpsonBrightLink1430)); |
| |
| struct input_event mock_kernel_queue[] = { |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 63}, |
| {{0, 0}, EV_ABS, ABS_X, 18372}, |
| {{0, 0}, EV_ABS, ABS_Y, 9880}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 61}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 60}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 63}, |
| {{0, 0}, EV_ABS, ABS_MISC, 1050626}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| |
| {{0, 0}, EV_ABS, ABS_X, 18294}, |
| {{0, 0}, EV_ABS, ABS_Y, 9723}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 20}, |
| {{0, 0}, EV_ABS, ABS_PRESSURE, 1015}, |
| {{0, 0}, EV_KEY, BTN_STYLUS, 1}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| |
| {{0, 0}, EV_ABS, ABS_X, 18516}, |
| {{0, 0}, EV_ABS, ABS_Y, 9723}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 23}, |
| {{0, 0}, EV_KEY, BTN_STYLUS, 0}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| |
| {{0, 0}, EV_ABS, ABS_X, 0}, |
| {{0, 0}, EV_ABS, ABS_Y, 0}, |
| {{0, 0}, EV_ABS, ABS_DISTANCE, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_X, 0}, |
| {{0, 0}, EV_ABS, ABS_TILT_Y, 0}, |
| {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0}, |
| {{0, 0}, EV_ABS, ABS_MISC, 0}, |
| {{0, 0}, EV_MSC, MSC_SERIAL, 897618290}, |
| {{0, 0}, EV_SYN, SYN_REPORT, 0}, |
| }; |
| |
| dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue)); |
| EXPECT_EQ(3u, size()); |
| |
| ui::MouseEvent* event = dispatched_event(0); |
| EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type()); |
| |
| event = dispatched_event(1); |
| EXPECT_EQ(ui::ET_MOUSE_PRESSED, event->type()); |
| EXPECT_EQ(true, event->IsRightMouseButton()); |
| |
| event = dispatched_event(2); |
| EXPECT_EQ(ui::ET_MOUSE_RELEASED, event->type()); |
| EXPECT_EQ(true, event->IsRightMouseButton()); |
| |
| } |