Chromium Code Reviews| Index: ui/display/chromeos/x11/touchscreen_device_manager_x11.cc |
| diff --git a/ui/display/chromeos/x11/touchscreen_device_manager_x11.cc b/ui/display/chromeos/x11/touchscreen_device_manager_x11.cc |
| index 6c8137b1cb47e7893fbd3d33c8181ed6dba931f7..5265e36ec2fdc4432633a2bb81adbdc7309a9a0e 100644 |
| --- a/ui/display/chromeos/x11/touchscreen_device_manager_x11.cc |
| +++ b/ui/display/chromeos/x11/touchscreen_device_manager_x11.cc |
| @@ -9,9 +9,86 @@ |
| #include <cmath> |
| #include <set> |
| - |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "base/command_line.h" |
| +#include "base/files/file_enumerator.h" |
| +#include "base/logging.h" |
| +#include "base/process/launch.h" |
| +#include "base/strings/string_util.h" |
| +#include "base/sys_info.h" |
| #include "ui/gfx/x/x11_types.h" |
| +namespace { |
| + |
| +// We consider the touchscreen is internal if it is an I2c device. |
|
Daniel Erat
2014/07/16 20:31:24
nit: s/touchscreen is internal/touchscreen to be i
Yufeng Shen (Slow to review)
2014/07/16 20:42:24
Done.
|
| +// With the device id, we can query X to get the device's dev input |
| +// node eventXXX. Then we search all the dev input nodes registered |
| +// by I2C devices to see if we can find eventXXX. |
| +bool IsTouchscreenInternal(Display* dpy, int device_id) { |
|
Daniel Erat
2014/07/16 20:31:23
nit: s/Display/XDisplay/ to match x11_types.h
Yufeng Shen (Slow to review)
2014/07/16 20:42:23
Done.
|
| + using base::FileEnumerator; |
| + using base::FilePath; |
| + |
| + if (!base::SysInfo::IsRunningOnChromeOS()) |
| + return false; |
| + |
| + // Input device has a property "Device Node" pointing to its dev input node, |
| + // e.g. Device Node (250): "/dev/input/event8" |
| + Atom device_node = XInternAtom(dpy, "Device Node", False); |
| + if (device_node == None) |
| + return false; |
| + |
| + Atom act_type; |
|
Daniel Erat
2014/07/16 20:31:24
avoid abbreviations: rename this to |actual_type|
Yufeng Shen (Slow to review)
2014/07/16 20:42:24
Done.
|
| + int act_format; |
| + unsigned long nitems, bytes_after; |
| + unsigned char* data; |
| + XDevice* dev = XOpenDevice(dpy, device_id); |
| + if (!dev) |
| + return false; |
| + |
| + if (XGetDeviceProperty(dpy, dev, device_node, 0, 1000, False, |
| + AnyPropertyType, &act_type, &act_format, |
| + &nitems, &bytes_after, &data) != Success) |
| + return false; |
|
Daniel Erat
2014/07/16 20:31:23
do you need to call XCloseDevice() before returnin
Yufeng Shen (Slow to review)
2014/07/16 20:42:24
Done.
|
| + base::FilePath dev_node_path(reinterpret_cast<char*>(data)); |
| + XFree(data); |
| + XCloseDevice(dpy, dev); |
| + |
| + std::string event_node = dev_node_path.BaseName().value(); |
| + if (event_node.empty() || |
| + !StartsWithASCII(event_node, "event", false)) { |
| + return false; |
| + } |
| + |
| + // Extract id "XXX" from "eventXXX" |
| + std::string event_node_id = event_node.substr(5); |
| + |
| + // I2C input device registers its dev input node at |
| + // /sys/bus/i2c/devices/*/input/inputXXX/eventXXX |
| + FileEnumerator i2c_enum(FilePath(FILE_PATH_LITERAL("/sys/bus/i2c/devices/")), |
| + false, |
| + base::FileEnumerator::DIRECTORIES); |
| + for (FilePath i2c_name = i2c_enum.Next(); |
| + !i2c_name.empty(); |
| + i2c_name = i2c_enum.Next()) { |
| + FileEnumerator input_enum(i2c_name.Append(FILE_PATH_LITERAL("input")), |
| + false, |
| + base::FileEnumerator::DIRECTORIES, |
| + FILE_PATH_LITERAL("input*")); |
| + for (base::FilePath input = input_enum.Next(); |
| + !input.empty(); |
| + input = input_enum.Next()) { |
| + if (input.BaseName().value().substr(5) == event_node_id) |
| + return true; |
| + } |
| + } |
| + |
| + return false; |
| +} |
| + |
| +} |
|
Daniel Erat
2014/07/16 20:31:24
nit: } // namespace
Yufeng Shen (Slow to review)
2014/07/16 20:42:24
Done.
|
| + |
| namespace ui { |
| TouchscreenDeviceManagerX11::TouchscreenDeviceManagerX11() |
| @@ -70,8 +147,10 @@ std::vector<TouchscreenDevice> TouchscreenDeviceManagerX11::GetDevices() { |
| // Touchscreens should have absolute X and Y axes, and be direct touch |
| // devices. |
| if (width > 0.0 && height > 0.0 && is_direct_touch) { |
| + bool is_internal = IsTouchscreenInternal(display_, info[i].deviceid); |
| devices.push_back(TouchscreenDevice(info[i].deviceid, |
| - gfx::Size(width, height))); |
| + gfx::Size(width, height), |
| + is_internal)); |
| } |
| } |