diff options
7 files changed, 155 insertions, 7 deletions
diff --git a/ui/events/ozone/evdev/event_device_info.cc b/ui/events/ozone/evdev/event_device_info.cc index e3c9f73..fba26d3 100644 --- a/ui/events/ozone/evdev/event_device_info.cc +++ b/ui/events/ozone/evdev/event_device_info.cc @@ -411,7 +411,7 @@ EventDeviceInfo::ProbeLegacyAbsoluteDevice() const { if (HasKeyEvent(BTN_TOOL_FINGER) && HasKeyEvent(BTN_TOUCH)) return LegacyAbsoluteDeviceType::LADT_TOUCHPAD; - if (HasKeyEvent(BTN_TOUCH)) + if (HasKeyEvent(BTN_TOUCH) || HasKeyEvent(BTN_LEFT)) return LegacyAbsoluteDeviceType::LADT_TOUCHSCREEN; return LegacyAbsoluteDeviceType::LADT_NONE; diff --git a/ui/events/ozone/evdev/event_device_info_unittest.cc b/ui/events/ozone/evdev/event_device_info_unittest.cc index cc7af80..63187a1 100644 --- a/ui/events/ozone/evdev/event_device_info_unittest.cc +++ b/ui/events/ozone/evdev/event_device_info_unittest.cc @@ -136,4 +136,16 @@ TEST_F(EventDeviceInfoTest, HybridKeyboardWithMouse) { EXPECT_FALSE(devinfo.HasTablet()); } +TEST_F(EventDeviceInfoTest, AbsoluteMouseTouchscreen) { + EventDeviceInfo devinfo; + EXPECT_TRUE(CapabilitiesToDeviceInfo(kElo_TouchSystems_2700, &devinfo)); + + // This touchscreen uses BTN_LEFT for touch contact. + EXPECT_FALSE(devinfo.HasKeyboard()); + EXPECT_FALSE(devinfo.HasMouse()); + EXPECT_FALSE(devinfo.HasTouchpad()); + EXPECT_TRUE(devinfo.HasTouchscreen()); + EXPECT_FALSE(devinfo.HasTablet()); +} + } // namespace ui diff --git a/ui/events/ozone/evdev/event_device_test_util.cc b/ui/events/ozone/evdev/event_device_test_util.cc index cb4116c..4d5407c 100644 --- a/ui/events/ozone/evdev/event_device_test_util.cc +++ b/ui/events/ozone/evdev/event_device_test_util.cc @@ -363,6 +363,36 @@ const DeviceCapabilities kLogitechTouchKeyboardK400 = { arraysize(kLogitechTouchKeyboardK400AbsAxes), }; +// Captured from Elo TouchSystems 2700 touchscreen. +const DeviceAbsoluteAxis kElo_TouchSystems_2700AbsAxes[] = { + {ABS_X, {0, 0, 4095, 0, 0, 0}}, + {ABS_Y, {0, 0, 4095, 0, 0, 0}}, + {ABS_MISC, {0, 0, 256, 0, 0, 0}}, +}; +const DeviceCapabilities kElo_TouchSystems_2700 = { + /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/" + "input/input9/event9", + /* name */ "Elo TouchSystems, Inc. Elo TouchSystems 2700 IntelliTouch(r) " + "USB Touchmonitor Interface", + /* phys */ "usb-0000:00:1d.0-1.3/input0", + /* uniq */ "20A01347", + /* bustype */ "0003", + /* vendor */ "04e7", + /* product */ "0020", + /* version */ "0100", + /* prop */ "0", + /* ev */ "1b", + /* key */ "10000 0 0 0 0", + /* rel */ "0", + /* abs */ "10000000003", + /* msc */ "10", + /* sw */ "0", + /* led */ "0", + /* ff */ "0", + kElo_TouchSystems_2700AbsAxes, + arraysize(kElo_TouchSystems_2700AbsAxes), +}; + bool CapabilitiesToDeviceInfo(const DeviceCapabilities& capabilities, EventDeviceInfo* devinfo) { std::vector<unsigned long> ev_bits; diff --git a/ui/events/ozone/evdev/event_device_test_util.h b/ui/events/ozone/evdev/event_device_test_util.h index 46afb6a..b02f74a 100644 --- a/ui/events/ozone/evdev/event_device_test_util.h +++ b/ui/events/ozone/evdev/event_device_test_util.h @@ -68,6 +68,7 @@ extern const DeviceCapabilities kMimoTouch2Touchscreen; extern const DeviceCapabilities kWacomIntuosPtS_Pen; extern const DeviceCapabilities kWacomIntuosPtS_Finger; extern const DeviceCapabilities kLogitechTouchKeyboardK400; +extern const DeviceCapabilities kElo_TouchSystems_2700; } // namspace ui diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.cc b/ui/events/ozone/evdev/touch_event_converter_evdev.cc index 2427f89..a5e9c19 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev.cc +++ b/ui/events/ozone/evdev/touch_event_converter_evdev.cc @@ -137,6 +137,9 @@ void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) { current_slot_ = 0; } + quirk_left_mouse_button_ = + !has_mt_ && !info.HasKeyEvent(BTN_TOUCH) && info.HasKeyEvent(BTN_LEFT); + // Apply --touch-calibration. if (type() == INPUT_DEVICE_INTERNAL) { TouchCalibration cal = {}; @@ -178,6 +181,7 @@ void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) { } } else { // TODO(spang): Add key state to EventDeviceInfo to allow initial contact. + // (and make sure to take into account quirk_left_mouse_button_) events_[0].x = 0; events_[0].y = 0; events_[0].tracking_id = kTrackingIdForUnusedSlot; @@ -259,6 +263,8 @@ void TouchEventConverterEvdev::ProcessMultitouchEvent( } } else if (input.type == EV_KEY) { ProcessKey(input); + } else if (input.type == EV_MSC) { + // Ignored. } else { NOTIMPLEMENTED() << "invalid type: " << input.type; } @@ -272,18 +278,22 @@ void TouchEventConverterEvdev::EmulateMultitouchEvent( emulated_event.code = AbsCodeToMtCode(event.code); if (emulated_event.code >= 0) ProcessMultitouchEvent(emulated_event); - } else if (event.type == EV_KEY && event.code == BTN_TOUCH) { - emulated_event.type = EV_ABS; - emulated_event.code = ABS_MT_TRACKING_ID; - emulated_event.value = - event.value ? NextTrackingId() : kTrackingIdForUnusedSlot; - ProcessMultitouchEvent(emulated_event); + } else if (event.type == EV_KEY) { + if (event.code == BTN_TOUCH || + (quirk_left_mouse_button_ && event.code == BTN_LEFT)) { + emulated_event.type = EV_ABS; + emulated_event.code = ABS_MT_TRACKING_ID; + emulated_event.value = + event.value ? NextTrackingId() : kTrackingIdForUnusedSlot; + ProcessMultitouchEvent(emulated_event); + } } } void TouchEventConverterEvdev::ProcessKey(const input_event& input) { switch (input.code) { case BTN_TOUCH: + case BTN_LEFT: break; default: NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code; diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.h b/ui/events/ozone/evdev/touch_event_converter_evdev.h index 7cd7576..edddea6 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev.h +++ b/ui/events/ozone/evdev/touch_event_converter_evdev.h @@ -83,6 +83,9 @@ class EVENTS_OZONE_EVDEV_EXPORT TouchEventConverterEvdev // Device has multitouch capability. bool has_mt_; + // Use BTN_LEFT instead of BT_TOUCH. + bool quirk_left_mouse_button_ = false; + // Pressure values. int pressure_min_; int pressure_max_; // Used to normalize pressure values. diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc index 77eeef6..96a1f32 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc +++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc @@ -47,6 +47,12 @@ void InitPixelTouchscreen(TouchEventConverterEvdev* device) { device->Initialize(devinfo); } +void InitEloTouchscreen(TouchEventConverterEvdev* device) { + EventDeviceInfo devinfo; + EXPECT_TRUE(CapabilitiesToDeviceInfo(kElo_TouchSystems_2700, &devinfo)); + device->Initialize(devinfo); +} + } // namespace class MockTouchEventConverterEvdev : public TouchEventConverterEvdev { @@ -541,6 +547,92 @@ TEST_F(TouchEventConverterEvdevTest, ShouldReleaseContactsOnStop) { EXPECT_EQ(0, ev2.slot); } +// crbug.com/477695 +TEST_F(TouchEventConverterEvdevTest, ShouldUseLeftButtonIfNoTouchButton) { + ui::MockTouchEventConverterEvdev* dev = device(); + + InitEloTouchscreen(dev); + + // Captured from Elo TouchSystems 2700. + timeval time; + time = {1433965490, 837958}; + struct input_event mock_kernel_queue_press[] = { + {time, EV_ABS, ABS_X, 3654}, + {time, EV_ABS, ABS_Y, 1054}, + {time, EV_ABS, ABS_MISC, 18}, + {time, EV_SYN, SYN_REPORT, 0}, + + {time, EV_MSC, MSC_SCAN, 90001}, + {time, EV_KEY, BTN_LEFT, 1}, + {time, EV_ABS, ABS_Y, 1055}, + {time, EV_ABS, ABS_MISC, 25}, + {time, EV_SYN, SYN_REPORT, 0}, + }; + time = {1433965491, 1953}; + struct input_event mock_kernel_queue_move[] = { + {time, EV_ABS, ABS_X, 3644}, + {time, EV_ABS, ABS_Y, 1059}, + {time, EV_ABS, ABS_MISC, 36}, + {time, EV_SYN, SYN_REPORT, 0}, + }; + time = {1433965491, 225959}; + struct input_event mock_kernel_queue_release[] = { + {time, EV_MSC, MSC_SCAN, 90001}, + {time, EV_KEY, BTN_LEFT, 0}, + {time, EV_ABS, ABS_MISC, 0}, + {time, EV_SYN, SYN_REPORT, 0}, + }; + + // Press. + dev->ConfigureReadMock(mock_kernel_queue_press, + arraysize(mock_kernel_queue_press), 0); + dev->ReadNow(); + EXPECT_EQ(1u, size()); + ui::TouchEventParams event = dispatched_event(0); + EXPECT_EQ(ui::ET_TOUCH_PRESSED, event.type); + EXPECT_EQ(base::TimeDelta::FromMicroseconds(1433965490837958), + event.timestamp); + EXPECT_EQ(3654, event.location.x()); + EXPECT_EQ(1055, event.location.y()); + EXPECT_EQ(0, event.slot); + EXPECT_FLOAT_EQ(0.f, event.radii.x()); + EXPECT_FLOAT_EQ(0.f, event.pressure); + + // Move. + dev->ConfigureReadMock(mock_kernel_queue_move, + arraysize(mock_kernel_queue_move), 0); + dev->ReadNow(); + EXPECT_EQ(2u, size()); + event = dispatched_event(1); + EXPECT_EQ(ui::ET_TOUCH_MOVED, event.type); + EXPECT_EQ(base::TimeDelta::FromMicroseconds(1433965491001953), + event.timestamp); + EXPECT_EQ(3644, event.location.x()); + EXPECT_EQ(1059, event.location.y()); + EXPECT_EQ(0, event.slot); + EXPECT_FLOAT_EQ(0.f, event.radii.x()); + EXPECT_FLOAT_EQ(0.f, event.pressure); + + // Release. + dev->ConfigureReadMock(mock_kernel_queue_release, + arraysize(mock_kernel_queue_release), 0); + dev->ReadNow(); + EXPECT_EQ(3u, size()); + event = dispatched_event(2); + EXPECT_EQ(ui::ET_TOUCH_RELEASED, event.type); + EXPECT_EQ(base::TimeDelta::FromMicroseconds(1433965491225959), + event.timestamp); + EXPECT_EQ(3644, event.location.x()); + EXPECT_EQ(1059, event.location.y()); + EXPECT_EQ(0, event.slot); + EXPECT_FLOAT_EQ(0.f, event.radii.x()); + EXPECT_FLOAT_EQ(0.f, event.pressure); + + // No dispatch on destruction. + DestroyDevice(); + EXPECT_EQ(3u, size()); +} + // crbug.com/407386 TEST_F(TouchEventConverterEvdevTest, DontChangeMultitouchPositionFromLegacyAxes) { |