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"
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"
17 TabletEventConverterEvdev::TabletEventConverterEvdev(
21 CursorDelegateEvdev
* cursor
,
22 const EventDeviceInfo
& info
,
23 DeviceEventDispatcherEvdev
* dispatcher
)
24 : EventConverterEvdev(fd
,
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
) {
44 "TabletEventConverterEvdev::OnFileCanReadWithoutBlocking", "fd",
47 input_event inputs
[4];
48 ssize_t read_size
= read(fd
, inputs
, sizeof(inputs
));
50 if (errno
== EINTR
|| errno
== EAGAIN
)
53 PLOG(ERROR
) << "error reading device " << path_
.value();
61 DCHECK_EQ(read_size
% sizeof(*inputs
), 0u);
62 ProcessEvents(inputs
, read_size
/ sizeof(*inputs
));
65 void TabletEventConverterEvdev::ProcessEvents(const input_event
* inputs
,
67 for (int i
= 0; i
< count
; ++i
) {
68 const input_event
& input
= inputs
[i
];
71 ConvertKeyEvent(input
);
74 ConvertAbsEvent(input
);
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
) {
88 else if (input
.value
== 0)
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
);
101 void TabletEventConverterEvdev::ConvertAbsEvent(const input_event
& input
) {
105 switch (input
.code
) {
107 x_abs_location_
= input
.value
;
108 abs_value_dirty_
= true;
111 y_abs_location_
= input
.value
;
112 abs_value_dirty_
= true;
117 void TabletEventConverterEvdev::UpdateCursor() {
118 gfx::Rect confined_bounds
= cursor_
->GetCursorConfinedBounds();
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()) /
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
) {
136 // These are the same as X11 behaviour
137 if (input
.code
== BTN_TOUCH
)
139 else if (input
.code
== BTN_STYLUS2
)
141 else if (input
.code
== BTN_STYLUS
)
146 if (abs_value_dirty_
) {
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
) {
162 // Prevent propagation of invalid data on stylus lift off
164 abs_value_dirty_
= false;
168 if (!abs_value_dirty_
)
173 dispatcher_
->DispatchMouseMoveEvent(
174 MouseMoveEventParams(input_device_
.id
, cursor_
->GetLocation(),
175 TimeDeltaFromInputEvent(input
)));
177 abs_value_dirty_
= false;