Commit 7438a6c3 authored by David Reveman's avatar David Reveman Committed by Commit Bot

ui: Add --pen-devices flag.

This adds a --pen-devices flag that works the same way as
--touch-devices and makes it possible to simulate pen
devices on Linux in addition to the current support for
touch devices.

Bug: 
Test: manual
Change-Id: Icc103b029b91b1e9e5d12e89c594069da38577ed
Reviewed-on: https://chromium-review.googlesource.com/667719
Commit-Queue: David Reveman <reveman@chromium.org>
Reviewed-by: default avatarVladislav Kaznacheev <kaznacheev@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Cr-Commit-Position: refs/heads/master@{#502918}
parent 1ac5b774
......@@ -26,6 +26,23 @@
#include "ui/events/event_switches.h"
namespace ui {
namespace {
void AddPointerDevicesFromString(
const std::string& pointer_devices,
EventPointerType type,
std::vector<std::pair<int, EventPointerType>>* devices) {
for (const base::StringPiece& dev : base::SplitStringPiece(
pointer_devices, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
int devid;
if (base::StringToInt(dev, &devid))
devices->push_back({devid, type});
else
DLOG(WARNING) << "Invalid device id: " << dev.as_string();
}
}
} // namespace
TouchFactory::TouchFactory()
: pointer_device_lookup_(),
......@@ -53,23 +70,16 @@ void TouchFactory::SetTouchDeviceListFromCommandLine() {
// Get a list of pointer-devices that should be treated as touch-devices.
// This is primarily used for testing/debugging touch-event processing when a
// touch-device isn't available.
std::string touch_devices =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kTouchDevices);
if (!touch_devices.empty()) {
std::vector<int> device_ids;
for (const base::StringPiece& dev :
base::SplitStringPiece(touch_devices, ",", base::TRIM_WHITESPACE,
base::SPLIT_WANT_ALL)) {
int devid;
if (base::StringToInt(dev, &devid))
device_ids.push_back(devid);
else
DLOG(WARNING) << "Invalid touch-device id: " << dev.as_string();
}
ui::TouchFactory::GetInstance()->SetTouchDeviceList(device_ids);
}
std::vector<std::pair<int, EventPointerType>> devices;
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
AddPointerDevicesFromString(
command_line->GetSwitchValueASCII(switches::kTouchDevices),
EventPointerType::POINTER_TYPE_TOUCH, &devices);
AddPointerDevicesFromString(
command_line->GetSwitchValueASCII(switches::kPenDevices),
EventPointerType::POINTER_TYPE_PEN, &devices);
if (!devices.empty())
ui::TouchFactory::GetInstance()->SetTouchDeviceList(devices);
}
void TouchFactory::UpdateDeviceList(XDisplay* display) {
......@@ -118,7 +128,8 @@ void TouchFactory::UpdateDeviceList(XDisplay* display) {
continue;
touch_device_lookup_[master_id] = true;
touch_device_list_[master_id] = true;
touch_device_list_[master_id] = {true,
EventPointerType::POINTER_TYPE_TOUCH};
if (devinfo.use != XIMasterPointer)
CacheTouchscreenIds(devinfo.deviceid);
......@@ -126,7 +137,8 @@ void TouchFactory::UpdateDeviceList(XDisplay* display) {
if (devinfo.use == XISlavePointer) {
device_master_id_list_[devinfo.deviceid] = master_id;
touch_device_lookup_[devinfo.deviceid] = true;
touch_device_list_[devinfo.deviceid] = false;
touch_device_list_[devinfo.deviceid] = {
false, EventPointerType::POINTER_TYPE_TOUCH};
}
}
pointer_device_lookup_[devinfo.deviceid] =
......@@ -157,7 +169,7 @@ bool TouchFactory::ShouldProcessXI2Event(XEvent* xev) {
// For a 'floating' touchscreen device, X11 sends only one event for
// each touch, with both deviceid and sourceid set to the id of the
// touchscreen device.
bool is_from_master_or_float = touch_device_list_[xiev->deviceid];
bool is_from_master_or_float = touch_device_list_[xiev->deviceid].is_master;
bool is_from_slave_device = !is_from_master_or_float
&& xiev->sourceid == xiev->deviceid;
return !is_touch_disabled &&
......@@ -229,18 +241,21 @@ void TouchFactory::SetupXI2ForXWindow(Window window) {
XFlush(display);
}
void TouchFactory::SetTouchDeviceList(const std::vector<int>& devices) {
void TouchFactory::SetTouchDeviceList(
const std::vector<std::pair<int, EventPointerType>>& devices) {
touch_device_lookup_.reset();
touch_device_list_.clear();
for (int deviceid : devices) {
for (auto& device : devices) {
int deviceid = device.first;
EventPointerType type = device.second;
DCHECK(IsValidDevice(deviceid));
touch_device_lookup_[deviceid] = true;
touch_device_list_[deviceid] = false;
touch_device_list_[deviceid] = {false, type};
if (device_master_id_list_.find(deviceid) != device_master_id_list_.end()) {
// When we set the device through the "--touch-devices" flag to slave
// touch device, we also set its master device to be touch device.
touch_device_lookup_[device_master_id_list_[deviceid]] = true;
touch_device_list_[device_master_id_list_[deviceid]] = false;
touch_device_list_[device_master_id_list_[deviceid]] = {false, type};
}
}
}
......@@ -256,10 +271,15 @@ bool TouchFactory::IsTouchDevice(int deviceid) const {
bool TouchFactory::IsMultiTouchDevice(int deviceid) const {
return (IsValidDevice(deviceid) && touch_device_lookup_[deviceid])
? touch_device_list_.find(deviceid)->second
? touch_device_list_.find(deviceid)->second.is_master
: false;
}
EventPointerType TouchFactory::GetTouchDevicePointerType(int deviceid) const {
DCHECK(IsTouchDevice(deviceid));
return touch_device_list_.find(deviceid)->second.pointer_type;
}
bool TouchFactory::QuerySlotForTrackingID(uint32_t tracking_id, int* slot) {
if (!id_generator_.HasGeneratedIDFor(tracking_id))
return false;
......@@ -297,7 +317,7 @@ void TouchFactory::SetTouchDeviceForTest(
iter != devices.end(); ++iter) {
DCHECK(IsValidDevice(*iter));
touch_device_lookup_[*iter] = true;
touch_device_list_[*iter] = true;
touch_device_list_[*iter] = {true, EventPointerType::POINTER_TYPE_TOUCH};
}
SetTouchscreensEnabled(true);
}
......
......@@ -15,6 +15,7 @@
#include "base/macros.h"
#include "ui/events/devices/x11/events_devices_x11_export.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/sequential_id_generator.h"
#include "ui/gfx/x/x11_types.h"
......@@ -54,7 +55,8 @@ class EVENTS_DEVICES_X11_EXPORT TouchFactory {
// Keeps a list of touch devices so that it is possible to determine if a
// pointer event is a touch-event or a mouse-event. The list is reset each
// time this is called.
void SetTouchDeviceList(const std::vector<int>& devices);
void SetTouchDeviceList(
const std::vector<std::pair<int, EventPointerType>>& devices);
// Is the device ID valid?
bool IsValidDevice(int deviceid) const;
......@@ -66,6 +68,9 @@ class EVENTS_DEVICES_X11_EXPORT TouchFactory {
// below for more explanation.)
bool IsMultiTouchDevice(int deviceid) const;
// Gets the pointer type for touch-device.
EventPointerType GetTouchDevicePointerType(int deviceid) const;
// Tries to find an existing slot ID mapping to tracking ID. Returns true
// if the slot is found and it is saved in |slot|, false if no such slot
// can be found.
......@@ -127,9 +132,13 @@ class EVENTS_DEVICES_X11_EXPORT TouchFactory {
// The list of touch devices. For testing/debugging purposes, a single-pointer
// device (mouse or touch screen without sufficient X/driver support for MT)
// can sometimes be treated as a touch device. The key in the map represents
// the device id, and the value represents if the device is multi-touch
// capable.
std::map<int, bool> touch_device_list_;
// the device id, and the value contains the details for device (e.g. if the
// device is master and multi-touch capable).
struct TouchDeviceDetails {
bool is_master = false;
EventPointerType pointer_type = EventPointerType::POINTER_TYPE_TOUCH;
};
std::map<int, TouchDeviceDetails> touch_device_list_;
// Touch screen <vid, pid>s.
std::set<std::pair<int, int> > touchscreen_ids_;
......
......@@ -22,6 +22,11 @@ const char kCompensateForUnstablePinchZoom[] =
// available with XInput 2 (i.e. X server 1.8 or above). The id's of the
// devices can be retrieved from 'xinput list'.
const char kTouchDevices[] = "touch-devices";
// Tells chrome to interpret events from these devices as pen events. Only
// available with XInput 2 (i.e. X server 1.8 or above). The id's of the
// devices can be retrieved from 'xinput list'.
const char kPenDevices[] = "pen-devices";
#endif
#if defined(USE_X11) || defined(USE_OZONE)
......
......@@ -16,6 +16,7 @@ EVENTS_BASE_EXPORT extern const char kCompensateForUnstablePinchZoom[];
#if defined(OS_LINUX)
EVENTS_BASE_EXPORT extern const char kTouchDevices[];
EVENTS_BASE_EXPORT extern const char kPenDevices[];
#endif
#if defined(USE_X11) || defined(USE_OZONE)
......
......@@ -26,7 +26,7 @@ std::unique_ptr<TouchEvent> CreateTouchEvent(EventType event_type,
std::unique_ptr<TouchEvent> event = base::MakeUnique<TouchEvent>(
event_type, EventLocationFromXEvent(xev), EventTimeFromXEvent(xev),
ui::PointerDetails(
ui::EventPointerType::POINTER_TYPE_TOUCH, GetTouchIdFromXEvent(xev),
GetTouchPointerTypeFromXEvent(xev), GetTouchIdFromXEvent(xev),
GetTouchRadiusXFromXEvent(xev), GetTouchRadiusYFromXEvent(xev),
GetTouchForceFromXEvent(xev)));
......
......@@ -743,6 +743,13 @@ float GetTouchForceFromXEvent(const XEvent& xev) {
return force;
}
EventPointerType GetTouchPointerTypeFromXEvent(const XEvent& xev) {
XIDeviceEvent* event = static_cast<XIDeviceEvent*>(xev.xcookie.data);
DCHECK(ui::TouchFactory::GetInstance()->IsTouchDevice(event->sourceid));
return ui::TouchFactory::GetInstance()->GetTouchDevicePointerType(
event->sourceid);
}
bool GetScrollOffsetsFromXEvent(const XEvent& xev,
float* x_offset,
float* y_offset,
......
......@@ -64,6 +64,10 @@ EVENTS_X_EXPORT float GetTouchAngleFromXEvent(const XEvent& xev);
// Gets the force from a native_event. Normalized to be [0, 1]. Default is 0.0.
EVENTS_X_EXPORT float GetTouchForceFromXEvent(const XEvent& xev);
// Gets the pointer type from a native_event.
EVENTS_X_EXPORT EventPointerType
GetTouchPointerTypeFromXEvent(const XEvent& xev);
// Returns whether this is a scroll event and optionally gets the amount to be
// scrolled. |x_offset|, |y_offset| and |finger_count| can be NULL.
EVENTS_X_EXPORT bool GetScrollOffsetsFromXEvent(const XEvent& xev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment