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/event_converter_evdev_impl.h"
8 #include <linux/input.h>
10 #include "ui/events/event.h"
11 #include "ui/events/keycodes/dom4/keycode_converter.h"
12 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
13 #include "ui/events/ozone/evdev/keyboard_util_evdev.h"
20 const int kKeyReleaseValue
= 0;
21 const int kKeyRepeatValue
= 2;
25 EventConverterEvdevImpl::EventConverterEvdevImpl(
30 const EventDeviceInfo
& devinfo
,
31 CursorDelegateEvdev
* cursor
,
32 DeviceEventDispatcherEvdev
* dispatcher
)
33 : EventConverterEvdev(fd
, path
, id
, type
),
34 has_keyboard_(devinfo
.HasKeyboard()),
35 has_touchpad_(devinfo
.HasTouchpad()),
36 has_caps_lock_led_(devinfo
.HasLedEvent(LED_CAPSL
)),
40 dispatcher_(dispatcher
) {
43 EventConverterEvdevImpl::~EventConverterEvdevImpl() {
48 void EventConverterEvdevImpl::OnFileCanReadWithoutBlocking(int fd
) {
49 input_event inputs
[4];
50 ssize_t read_size
= read(fd
, inputs
, sizeof(inputs
));
52 if (errno
== EINTR
|| errno
== EAGAIN
)
55 PLOG(ERROR
) << "error reading device " << path_
.value();
60 // TODO(spang): Re-implement this by releasing buttons & temporarily closing
65 DCHECK_EQ(read_size
% sizeof(*inputs
), 0u);
66 ProcessEvents(inputs
, read_size
/ sizeof(*inputs
));
69 bool EventConverterEvdevImpl::HasKeyboard() const {
73 bool EventConverterEvdevImpl::HasTouchpad() const {
77 bool EventConverterEvdevImpl::HasCapsLockLed() const {
78 return has_caps_lock_led_
;
81 void EventConverterEvdevImpl::SetAllowedKeys(
82 scoped_ptr
<std::set
<DomCode
>> allowed_keys
) {
83 DCHECK(HasKeyboard());
84 allowed_keys_
= allowed_keys
.Pass();
87 void EventConverterEvdevImpl::AllowAllKeys() {
88 DCHECK(HasKeyboard());
89 allowed_keys_
.reset();
92 void EventConverterEvdevImpl::ProcessEvents(const input_event
* inputs
,
94 for (int i
= 0; i
< count
; ++i
) {
95 const input_event
& input
= inputs
[i
];
98 ConvertKeyEvent(input
);
101 ConvertMouseMoveEvent(input
);
104 if (input
.code
== SYN_DROPPED
)
105 LOG(WARNING
) << "kernel dropped input events";
112 void EventConverterEvdevImpl::ConvertKeyEvent(const input_event
& input
) {
113 // Ignore repeat events.
114 if (input
.value
== kKeyRepeatValue
)
118 if (input
.code
>= BTN_MOUSE
&& input
.code
< BTN_JOYSTICK
) {
119 DispatchMouseButton(input
);
123 // Keyboard processing.
124 DomCode key_code
= KeycodeConverter::NativeKeycodeToDomCode(
125 EvdevCodeToNativeCode(input
.code
));
126 if (!allowed_keys_
|| allowed_keys_
->count(key_code
)) {
127 dispatcher_
->DispatchKeyEvent(
128 KeyEventParams(id_
, input
.code
, input
.value
!= kKeyReleaseValue
,
129 TimeDeltaFromInputEvent(input
)));
133 void EventConverterEvdevImpl::ConvertMouseMoveEvent(const input_event
& input
) {
136 switch (input
.code
) {
138 x_offset_
= input
.value
;
141 y_offset_
= input
.value
;
146 void EventConverterEvdevImpl::DispatchMouseButton(const input_event
& input
) {
150 dispatcher_
->DispatchMouseButtonEvent(MouseButtonEventParams(
151 id_
, cursor_
->GetLocation(), input
.code
, input
.value
,
152 /* allow_remap */ true, TimeDeltaFromInputEvent(input
)));
155 void EventConverterEvdevImpl::FlushEvents(const input_event
& input
) {
156 if (!cursor_
|| (x_offset_
== 0 && y_offset_
== 0))
159 cursor_
->MoveCursor(gfx::Vector2dF(x_offset_
, y_offset_
));
161 dispatcher_
->DispatchMouseMoveEvent(MouseMoveEventParams(
162 id_
, cursor_
->GetLocation(), TimeDeltaFromInputEvent(input
)));