ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / ui / events / ozone / evdev / event_converter_evdev_impl.cc
blobfeaab9a39bb129a7047c6826bacbb2cd4adfe50a
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"
7 #include <errno.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"
15 namespace ui {
17 namespace {
19 // Values for EV_KEY.
20 const int kKeyReleaseValue = 0;
21 const int kKeyRepeatValue = 2;
23 } // namespace
25 EventConverterEvdevImpl::EventConverterEvdevImpl(
26 int fd,
27 base::FilePath path,
28 int id,
29 InputDeviceType type,
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)),
37 x_offset_(0),
38 y_offset_(0),
39 cursor_(cursor),
40 dispatcher_(dispatcher) {
43 EventConverterEvdevImpl::~EventConverterEvdevImpl() {
44 Stop();
45 close(fd_);
48 void EventConverterEvdevImpl::OnFileCanReadWithoutBlocking(int fd) {
49 input_event inputs[4];
50 ssize_t read_size = read(fd, inputs, sizeof(inputs));
51 if (read_size < 0) {
52 if (errno == EINTR || errno == EAGAIN)
53 return;
54 if (errno != ENODEV)
55 PLOG(ERROR) << "error reading device " << path_.value();
56 Stop();
57 return;
60 // TODO(spang): Re-implement this by releasing buttons & temporarily closing
61 // the device.
62 if (ignore_events_)
63 return;
65 DCHECK_EQ(read_size % sizeof(*inputs), 0u);
66 ProcessEvents(inputs, read_size / sizeof(*inputs));
69 bool EventConverterEvdevImpl::HasKeyboard() const {
70 return has_keyboard_;
73 bool EventConverterEvdevImpl::HasTouchpad() const {
74 return has_touchpad_;
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,
93 int count) {
94 for (int i = 0; i < count; ++i) {
95 const input_event& input = inputs[i];
96 switch (input.type) {
97 case EV_KEY:
98 ConvertKeyEvent(input);
99 break;
100 case EV_REL:
101 ConvertMouseMoveEvent(input);
102 break;
103 case EV_SYN:
104 if (input.code == SYN_DROPPED)
105 LOG(WARNING) << "kernel dropped input events";
106 FlushEvents(input);
107 break;
112 void EventConverterEvdevImpl::ConvertKeyEvent(const input_event& input) {
113 // Ignore repeat events.
114 if (input.value == kKeyRepeatValue)
115 return;
117 // Mouse processing.
118 if (input.code >= BTN_MOUSE && input.code < BTN_JOYSTICK) {
119 DispatchMouseButton(input);
120 return;
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) {
134 if (!cursor_)
135 return;
136 switch (input.code) {
137 case REL_X:
138 x_offset_ = input.value;
139 break;
140 case REL_Y:
141 y_offset_ = input.value;
142 break;
146 void EventConverterEvdevImpl::DispatchMouseButton(const input_event& input) {
147 if (!cursor_)
148 return;
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))
157 return;
159 cursor_->MoveCursor(gfx::Vector2dF(x_offset_, y_offset_));
161 dispatcher_->DispatchMouseMoveEvent(MouseMoveEventParams(
162 id_, cursor_->GetLocation(), TimeDeltaFromInputEvent(input)));
164 x_offset_ = 0;
165 y_offset_ = 0;
168 } // namespace ui