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 "ui/events/event.h"
12 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
16 TabletEventConverterEvdev::TabletEventConverterEvdev(
21 CursorDelegateEvdev
* cursor
,
22 const EventDeviceInfo
& info
,
23 DeviceEventDispatcherEvdev
* dispatcher
)
24 : EventConverterEvdev(fd
, path
, id
, type
),
26 dispatcher_(dispatcher
),
28 abs_value_dirty_(false) {
29 x_abs_min_
= info
.GetAbsMinimum(ABS_X
);
30 x_abs_range_
= info
.GetAbsMaximum(ABS_X
) - x_abs_min_
+ 1;
31 y_abs_min_
= info
.GetAbsMinimum(ABS_Y
);
32 y_abs_range_
= info
.GetAbsMaximum(ABS_Y
) - y_abs_min_
+ 1;
35 TabletEventConverterEvdev::~TabletEventConverterEvdev() {
40 void TabletEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd
) {
41 input_event inputs
[4];
42 ssize_t read_size
= read(fd
, inputs
, sizeof(inputs
));
44 if (errno
== EINTR
|| errno
== EAGAIN
)
47 PLOG(ERROR
) << "error reading device " << path_
.value();
55 DCHECK_EQ(read_size
% sizeof(*inputs
), 0u);
56 ProcessEvents(inputs
, read_size
/ sizeof(*inputs
));
59 void TabletEventConverterEvdev::ProcessEvents(const input_event
* inputs
,
61 for (int i
= 0; i
< count
; ++i
) {
62 const input_event
& input
= inputs
[i
];
65 ConvertKeyEvent(input
);
68 ConvertAbsEvent(input
);
77 void TabletEventConverterEvdev::ConvertKeyEvent(const input_event
& input
) {
78 // Only handle other events if we have a stylus in proximity
79 if (input
.code
>= BTN_TOOL_PEN
&& input
.code
<= BTN_TOOL_LENS
) {
82 else if (input
.value
== 0)
85 LOG(WARNING
) << "Unexpected value: " << input
.value
86 << " for code: " << input
.code
;
89 if (input
.code
>= BTN_TOUCH
&& input
.code
<= BTN_STYLUS2
) {
90 DispatchMouseButton(input
);
95 void TabletEventConverterEvdev::ConvertAbsEvent(const input_event
& input
) {
101 x_abs_location_
= input
.value
;
102 abs_value_dirty_
= true;
105 y_abs_location_
= input
.value
;
106 abs_value_dirty_
= true;
111 void TabletEventConverterEvdev::UpdateCursor() {
112 gfx::Rect confined_bounds
= cursor_
->GetCursorConfinedBounds();
115 ((x_abs_location_
- x_abs_min_
) * confined_bounds
.width()) / x_abs_range_
;
116 int y
= ((y_abs_location_
- y_abs_min_
) * confined_bounds
.height()) /
119 x
+= confined_bounds
.x();
120 y
+= confined_bounds
.y();
122 cursor_
->MoveCursorTo(gfx::PointF(x
, y
));
125 void TabletEventConverterEvdev::DispatchMouseButton(const input_event
& input
) {
130 // These are the same as X11 behaviour
131 if (input
.code
== BTN_TOUCH
)
133 else if (input
.code
== BTN_STYLUS2
)
135 else if (input
.code
== BTN_STYLUS
)
140 if (abs_value_dirty_
) {
142 abs_value_dirty_
= false;
145 bool down
= input
.value
;
147 dispatcher_
->DispatchMouseButtonEvent(MouseButtonEventParams(
148 id_
, cursor_
->GetLocation(), button
, down
, false /* allow_remap */,
149 TimeDeltaFromInputEvent(input
)));
152 void TabletEventConverterEvdev::FlushEvents(const input_event
& input
) {
156 // Prevent propagation of invalid data on stylus lift off
158 abs_value_dirty_
= false;
162 if (!abs_value_dirty_
)
167 dispatcher_
->DispatchMouseMoveEvent(MouseMoveEventParams(
168 id_
, cursor_
->GetLocation(), TimeDeltaFromInputEvent(input
)));
170 abs_value_dirty_
= false;