Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Unified Diff: ui/events/ozone/evdev/event_converter_evdev_impl.cc

Issue 1287103004: Sync ui/events to chromium @ https://codereview.chromium.org/1210203002 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/events/ozone/evdev/event_converter_evdev_impl.cc
diff --git a/ui/events/ozone/evdev/event_converter_evdev_impl.cc b/ui/events/ozone/evdev/event_converter_evdev_impl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0c532d5096856f3023eddd57d1dd20f61c208c1c
--- /dev/null
+++ b/ui/events/ozone/evdev/event_converter_evdev_impl.cc
@@ -0,0 +1,247 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/ozone/evdev/event_converter_evdev_impl.h"
+
+#include <errno.h>
+#include <linux/input.h>
+
+#include "base/trace_event/trace_event.h"
+#include "ui/events/event.h"
+#include "ui/events/event_utils.h"
+#include "ui/events/keycodes/dom/keycode_converter.h"
+#include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
+#include "ui/events/ozone/evdev/keyboard_util_evdev.h"
+
+namespace ui {
+
+namespace {
+
+// Values for EV_KEY.
+const int kKeyReleaseValue = 0;
+const int kKeyRepeatValue = 2;
+
+} // namespace
+
+EventConverterEvdevImpl::EventConverterEvdevImpl(
+ int fd,
+ base::FilePath path,
+ int id,
+ InputDeviceType type,
+ const EventDeviceInfo& devinfo,
+ CursorDelegateEvdev* cursor,
+ DeviceEventDispatcherEvdev* dispatcher)
+ : EventConverterEvdev(fd,
+ path,
+ id,
+ type,
+ devinfo.name(),
+ devinfo.vendor_id(),
+ devinfo.product_id()),
+ has_keyboard_(devinfo.HasKeyboard()),
+ has_touchpad_(devinfo.HasTouchpad()),
+ has_caps_lock_led_(devinfo.HasLedEvent(LED_CAPSL)),
+ cursor_(cursor),
+ dispatcher_(dispatcher) {
+}
+
+EventConverterEvdevImpl::~EventConverterEvdevImpl() {
+ DCHECK(!enabled_);
+ close(fd_);
+}
+
+void EventConverterEvdevImpl::OnFileCanReadWithoutBlocking(int fd) {
+ TRACE_EVENT1("evdev", "EventConverterEvdevImpl::OnFileCanReadWithoutBlocking",
+ "fd", fd);
+
+ input_event inputs[4];
+ ssize_t read_size = read(fd, inputs, sizeof(inputs));
+ if (read_size < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ return;
+ if (errno != ENODEV)
+ PLOG(ERROR) << "error reading device " << path_.value();
+ Stop();
+ return;
+ }
+
+ if (!enabled_)
+ return;
+
+ DCHECK_EQ(read_size % sizeof(*inputs), 0u);
+ ProcessEvents(inputs, read_size / sizeof(*inputs));
+}
+
+bool EventConverterEvdevImpl::HasKeyboard() const {
+ return has_keyboard_;
+}
+
+bool EventConverterEvdevImpl::HasTouchpad() const {
+ return has_touchpad_;
+}
+
+bool EventConverterEvdevImpl::HasCapsLockLed() const {
+ return has_caps_lock_led_;
+}
+
+void EventConverterEvdevImpl::SetKeyFilter(bool enable_filter,
+ std::vector<DomCode> allowed_keys) {
+ if (!enable_filter) {
+ blocked_keys_.reset();
+ return;
+ }
+
+ blocked_keys_.set();
+ for (const DomCode& it : allowed_keys) {
+ int evdev_code =
+ NativeCodeToEvdevCode(KeycodeConverter::DomCodeToNativeKeycode(it));
+ blocked_keys_.reset(evdev_code);
+ }
+
+ // Release any pressed blocked keys.
+ base::TimeDelta timestamp = ui::EventTimeForNow();
+ for (int key = 0; key < KEY_CNT; ++key) {
+ if (blocked_keys_.test(key))
+ OnKeyChange(key, false /* down */, timestamp);
+ }
+}
+
+void EventConverterEvdevImpl::OnDisabled() {
+ ReleaseKeys();
+ ReleaseMouseButtons();
+}
+
+void EventConverterEvdevImpl::ProcessEvents(const input_event* inputs,
+ int count) {
+ for (int i = 0; i < count; ++i) {
+ const input_event& input = inputs[i];
+ switch (input.type) {
+ case EV_KEY:
+ ConvertKeyEvent(input);
+ break;
+ case EV_REL:
+ ConvertMouseMoveEvent(input);
+ break;
+ case EV_SYN:
+ if (input.code == SYN_DROPPED)
+ OnLostSync();
+ else if (input.code == SYN_REPORT)
+ FlushEvents(input);
+ break;
+ }
+ }
+}
+
+void EventConverterEvdevImpl::ConvertKeyEvent(const input_event& input) {
+ // Ignore repeat events.
+ if (input.value == kKeyRepeatValue)
+ return;
+
+ // Mouse processing.
+ if (input.code >= BTN_MOUSE && input.code < BTN_JOYSTICK) {
+ DispatchMouseButton(input);
+ return;
+ }
+
+ // Keyboard processing.
+ OnKeyChange(input.code, input.value != kKeyReleaseValue,
+ TimeDeltaFromInputEvent(input));
+}
+
+void EventConverterEvdevImpl::ConvertMouseMoveEvent(const input_event& input) {
+ if (!cursor_)
+ return;
+ switch (input.code) {
+ case REL_X:
+ x_offset_ = input.value;
+ break;
+ case REL_Y:
+ y_offset_ = input.value;
+ break;
+ }
+}
+
+void EventConverterEvdevImpl::OnKeyChange(unsigned int key,
+ bool down,
+ const base::TimeDelta& timestamp) {
+ if (key > KEY_MAX)
+ return;
+
+ if (down == key_state_.test(key))
+ return;
+
+ // Apply key filter (releases for previously pressed keys are excepted).
+ if (down && blocked_keys_.test(key))
+ return;
+
+ // State transition: !(down) -> (down)
+ key_state_.set(key, down);
+
+ dispatcher_->DispatchKeyEvent(KeyEventParams(input_device_.id, key, down,
+ false /* suppress_auto_repeat */,
+ timestamp));
+}
+
+void EventConverterEvdevImpl::ReleaseKeys() {
+ base::TimeDelta timestamp = ui::EventTimeForNow();
+ for (int key = 0; key < KEY_CNT; ++key)
+ OnKeyChange(key, false /* down */, timestamp);
+}
+
+void EventConverterEvdevImpl::ReleaseMouseButtons() {
+ base::TimeDelta timestamp = ui::EventTimeForNow();
+ for (int code = BTN_MOUSE; code < BTN_JOYSTICK; ++code)
+ OnButtonChange(code, false /* down */, timestamp);
+}
+
+void EventConverterEvdevImpl::OnLostSync() {
+ LOG(WARNING) << "kernel dropped input events";
+
+ // We may have missed key releases. Release everything.
+ // TODO(spang): Use EVIOCGKEY to avoid releasing keys that are still held.
+ ReleaseKeys();
+ ReleaseMouseButtons();
+}
+
+void EventConverterEvdevImpl::DispatchMouseButton(const input_event& input) {
+ if (!cursor_)
+ return;
+
+ OnButtonChange(input.code, input.value, TimeDeltaFromInputEvent(input));
+}
+
+void EventConverterEvdevImpl::OnButtonChange(int code,
+ bool down,
+ const base::TimeDelta& timestamp) {
+ if (code == BTN_SIDE)
+ code = BTN_BACK;
+ else if (code == BTN_EXTRA)
+ code = BTN_FORWARD;
+
+ int button_offset = code - BTN_MOUSE;
+ if (mouse_button_state_.test(button_offset) == down)
+ return;
+
+ mouse_button_state_.set(button_offset, down);
+
+ dispatcher_->DispatchMouseButtonEvent(MouseButtonEventParams(
+ input_device_.id, cursor_->GetLocation(), code, down,
+ /* allow_remap */ true, timestamp));
+}
+
+void EventConverterEvdevImpl::FlushEvents(const input_event& input) {
+ if (!cursor_ || (x_offset_ == 0 && y_offset_ == 0))
+ return;
+
+ cursor_->MoveCursor(gfx::Vector2dF(x_offset_, y_offset_));
+
+ dispatcher_->DispatchMouseMoveEvent(
+ MouseMoveEventParams(input_device_.id, cursor_->GetLocation(),
+ TimeDeltaFromInputEvent(input)));
+
+ x_offset_ = 0;
+ y_offset_ = 0;
+}
+
+} // namespace ui
« no previous file with comments | « ui/events/ozone/evdev/event_converter_evdev_impl.h ('k') | ui/events/ozone/evdev/event_converter_evdev_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698