Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ui / events / ozone / evdev / tablet_event_converter_evdev.cc
blob85eebda931069bf8e9007a53134623e0e5b637b0
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/events/ozone/evdev/tablet_event_converter_evdev.h"
7 #include <errno.h>
8 #include <linux/input.h>
10 #include "base/message_loop/message_loop.h"
11 #include "base/trace_event/trace_event.h"
12 #include "ui/events/event.h"
13 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
15 namespace ui {
17 TabletEventConverterEvdev::TabletEventConverterEvdev(
18 int fd,
19 base::FilePath path,
20 int id,
21 CursorDelegateEvdev* cursor,
22 const EventDeviceInfo& info,
23 DeviceEventDispatcherEvdev* dispatcher)
24 : EventConverterEvdev(fd,
25 path,
26 id,
27 info.device_type(),
28 info.name(),
29 info.vendor_id(),
30 info.product_id()),
31 cursor_(cursor),
32 dispatcher_(dispatcher) {
33 x_abs_min_ = info.GetAbsMinimum(ABS_X);
34 x_abs_range_ = info.GetAbsMaximum(ABS_X) - x_abs_min_ + 1;
35 y_abs_min_ = info.GetAbsMinimum(ABS_Y);
36 y_abs_range_ = info.GetAbsMaximum(ABS_Y) - y_abs_min_ + 1;
39 TabletEventConverterEvdev::~TabletEventConverterEvdev() {
42 void TabletEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
43 TRACE_EVENT1("evdev",
44 "TabletEventConverterEvdev::OnFileCanReadWithoutBlocking", "fd",
45 fd);
47 input_event inputs[4];
48 ssize_t read_size = read(fd, inputs, sizeof(inputs));
49 if (read_size < 0) {
50 if (errno == EINTR || errno == EAGAIN)
51 return;
52 if (errno != ENODEV)
53 PLOG(ERROR) << "error reading device " << path_.value();
54 Stop();
55 return;
58 if (!enabled_)
59 return;
61 DCHECK_EQ(read_size % sizeof(*inputs), 0u);
62 ProcessEvents(inputs, read_size / sizeof(*inputs));
65 void TabletEventConverterEvdev::ProcessEvents(const input_event* inputs,
66 int count) {
67 for (int i = 0; i < count; ++i) {
68 const input_event& input = inputs[i];
69 switch (input.type) {
70 case EV_KEY:
71 ConvertKeyEvent(input);
72 break;
73 case EV_ABS:
74 ConvertAbsEvent(input);
75 break;
76 case EV_SYN:
77 FlushEvents(input);
78 break;
83 void TabletEventConverterEvdev::ConvertKeyEvent(const input_event& input) {
84 // Only handle other events if we have a stylus in proximity
85 if (input.code >= BTN_TOOL_PEN && input.code <= BTN_TOOL_LENS) {
86 if (input.value == 1)
87 stylus_ = input.code;
88 else if (input.value == 0)
89 stylus_ = 0;
90 else
91 LOG(WARNING) << "Unexpected value: " << input.value
92 << " for code: " << input.code;
95 if (input.code >= BTN_TOUCH && input.code <= BTN_STYLUS2) {
96 DispatchMouseButton(input);
97 return;
101 void TabletEventConverterEvdev::ConvertAbsEvent(const input_event& input) {
102 if (!cursor_)
103 return;
105 switch (input.code) {
106 case ABS_X:
107 x_abs_location_ = input.value;
108 abs_value_dirty_ = true;
109 break;
110 case ABS_Y:
111 y_abs_location_ = input.value;
112 abs_value_dirty_ = true;
113 break;
117 void TabletEventConverterEvdev::UpdateCursor() {
118 gfx::Rect confined_bounds = cursor_->GetCursorConfinedBounds();
120 int x =
121 ((x_abs_location_ - x_abs_min_) * confined_bounds.width()) / x_abs_range_;
122 int y = ((y_abs_location_ - y_abs_min_) * confined_bounds.height()) /
123 y_abs_range_;
125 x += confined_bounds.x();
126 y += confined_bounds.y();
128 cursor_->MoveCursorTo(gfx::PointF(x, y));
131 void TabletEventConverterEvdev::DispatchMouseButton(const input_event& input) {
132 if (!cursor_)
133 return;
135 unsigned int button;
136 // These are the same as X11 behaviour
137 if (input.code == BTN_TOUCH)
138 button = BTN_LEFT;
139 else if (input.code == BTN_STYLUS2)
140 button = BTN_RIGHT;
141 else if (input.code == BTN_STYLUS)
142 button = BTN_MIDDLE;
143 else
144 return;
146 if (abs_value_dirty_) {
147 UpdateCursor();
148 abs_value_dirty_ = false;
151 bool down = input.value;
153 dispatcher_->DispatchMouseButtonEvent(MouseButtonEventParams(
154 input_device_.id, cursor_->GetLocation(), button, down,
155 false /* allow_remap */, TimeDeltaFromInputEvent(input)));
158 void TabletEventConverterEvdev::FlushEvents(const input_event& input) {
159 if (!cursor_)
160 return;
162 // Prevent propagation of invalid data on stylus lift off
163 if (stylus_ == 0) {
164 abs_value_dirty_ = false;
165 return;
168 if (!abs_value_dirty_)
169 return;
171 UpdateCursor();
173 dispatcher_->DispatchMouseMoveEvent(
174 MouseMoveEventParams(input_device_.id, cursor_->GetLocation(),
175 TimeDeltaFromInputEvent(input)));
177 abs_value_dirty_ = false;
180 } // namespace ui