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

Unified Diff: ui/events/ozone/evdev/event_factory_evdev.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
« no previous file with comments | « ui/events/ozone/evdev/event_factory_evdev.h ('k') | ui/events/ozone/evdev/event_modifiers_evdev.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/events/ozone/evdev/event_factory_evdev.cc
diff --git a/ui/events/ozone/evdev/event_factory_evdev.cc b/ui/events/ozone/evdev/event_factory_evdev.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9d79b14b0483ff6eb4ab0c7342b72dd4d323d126
--- /dev/null
+++ b/ui/events/ozone/evdev/event_factory_evdev.cc
@@ -0,0 +1,393 @@
+// 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_factory_evdev.h"
+
+#include "base/bind.h"
+#include "base/task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/threading/worker_pool.h"
+#include "base/time/time.h"
+#include "base/trace_event/trace_event.h"
+#include "ui/events/devices/device_data_manager.h"
+#include "ui/events/devices/input_device.h"
+#include "ui/events/event_utils.h"
+#include "ui/events/ozone/device/device_event.h"
+#include "ui/events/ozone/device/device_manager.h"
+#include "ui/events/ozone/evdev/cursor_delegate_evdev.h"
+#include "ui/events/ozone/evdev/input_controller_evdev.h"
+#include "ui/events/ozone/evdev/input_device_factory_evdev.h"
+#include "ui/events/ozone/evdev/input_device_factory_evdev_proxy.h"
+#include "ui/events/ozone/evdev/input_injector_evdev.h"
+#include "ui/events/ozone/evdev/touch_evdev_types.h"
+
+namespace ui {
+
+namespace {
+
+// Thread safe dispatcher proxy for EventFactoryEvdev.
+//
+// This is used on the device I/O thread for dispatching to UI.
+class ProxyDeviceEventDispatcher : public DeviceEventDispatcherEvdev {
+ public:
+ ProxyDeviceEventDispatcher(
+ scoped_refptr<base::SingleThreadTaskRunner> ui_thread_runner,
+ base::WeakPtr<EventFactoryEvdev> event_factory_evdev)
+ : ui_thread_runner_(ui_thread_runner),
+ event_factory_evdev_(event_factory_evdev) {}
+ ~ProxyDeviceEventDispatcher() override {}
+
+ // DeviceEventDispatcher:
+ void DispatchKeyEvent(const KeyEventParams& params) override {
+ ui_thread_runner_->PostTask(FROM_HERE,
+ base::Bind(&EventFactoryEvdev::DispatchKeyEvent,
+ event_factory_evdev_, params));
+ }
+
+ void DispatchMouseMoveEvent(const MouseMoveEventParams& params) override {
+ ui_thread_runner_->PostTask(
+ FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchMouseMoveEvent,
+ event_factory_evdev_, params));
+ }
+
+ void DispatchMouseButtonEvent(const MouseButtonEventParams& params) override {
+ ui_thread_runner_->PostTask(
+ FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchMouseButtonEvent,
+ event_factory_evdev_, params));
+ }
+
+ void DispatchMouseWheelEvent(const MouseWheelEventParams& params) override {
+ ui_thread_runner_->PostTask(
+ FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchMouseWheelEvent,
+ event_factory_evdev_, params));
+ }
+
+ void DispatchScrollEvent(const ScrollEventParams& params) override {
+ ui_thread_runner_->PostTask(
+ FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchScrollEvent,
+ event_factory_evdev_, params));
+ }
+
+ void DispatchTouchEvent(const TouchEventParams& params) override {
+ ui_thread_runner_->PostTask(
+ FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchTouchEvent,
+ event_factory_evdev_, params));
+ }
+
+ void DispatchKeyboardDevicesUpdated(
+ const std::vector<KeyboardDevice>& devices) override {
+ ui_thread_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&EventFactoryEvdev::DispatchKeyboardDevicesUpdated,
+ event_factory_evdev_, devices));
+ }
+ void DispatchTouchscreenDevicesUpdated(
+ const std::vector<TouchscreenDevice>& devices) override {
+ ui_thread_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&EventFactoryEvdev::DispatchTouchscreenDevicesUpdated,
+ event_factory_evdev_, devices));
+ }
+ void DispatchMouseDevicesUpdated(
+ const std::vector<InputDevice>& devices) override {
+ ui_thread_runner_->PostTask(
+ FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchMouseDevicesUpdated,
+ event_factory_evdev_, devices));
+ }
+ void DispatchTouchpadDevicesUpdated(
+ const std::vector<InputDevice>& devices) override {
+ ui_thread_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&EventFactoryEvdev::DispatchTouchpadDevicesUpdated,
+ event_factory_evdev_, devices));
+ }
+ void DispatchDeviceListsComplete() override {
+ ui_thread_runner_->PostTask(
+ FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchDeviceListsComplete,
+ event_factory_evdev_));
+ }
+
+ private:
+ scoped_refptr<base::SingleThreadTaskRunner> ui_thread_runner_;
+ base::WeakPtr<EventFactoryEvdev> event_factory_evdev_;
+};
+
+} // namespace
+
+EventFactoryEvdev::EventFactoryEvdev(CursorDelegateEvdev* cursor,
+ DeviceManager* device_manager,
+ KeyboardLayoutEngine* keyboard_layout)
+ : device_manager_(device_manager),
+ keyboard_(&modifiers_,
+ keyboard_layout,
+ base::Bind(&EventFactoryEvdev::DispatchUiEvent,
+ base::Unretained(this))),
+ cursor_(cursor),
+ input_controller_(&keyboard_, &button_map_),
+ touch_id_generator_(0),
+ weak_ptr_factory_(this) {
+ DCHECK(device_manager_);
+}
+
+EventFactoryEvdev::~EventFactoryEvdev() {
+}
+
+void EventFactoryEvdev::Init() {
+ DCHECK(!initialized_);
+
+ StartThread();
+
+ initialized_ = true;
+}
+
+scoped_ptr<SystemInputInjector> EventFactoryEvdev::CreateSystemInputInjector() {
+ // Use forwarding dispatcher for the injector rather than dispatching
+ // directly. We cannot assume it is safe to (re-)enter ui::Event dispatch
+ // synchronously from the injection point.
+ scoped_ptr<DeviceEventDispatcherEvdev> proxy_dispatcher(
+ new ProxyDeviceEventDispatcher(base::ThreadTaskRunnerHandle::Get(),
+ weak_ptr_factory_.GetWeakPtr()));
+ return make_scoped_ptr(
+ new InputInjectorEvdev(proxy_dispatcher.Pass(), cursor_));
+}
+
+void EventFactoryEvdev::DispatchKeyEvent(const KeyEventParams& params) {
+ TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchKeyEvent", "device",
+ params.device_id);
+ keyboard_.OnKeyChange(params.code, params.down, params.suppress_auto_repeat,
+ params.timestamp, params.device_id);
+}
+
+void EventFactoryEvdev::DispatchMouseMoveEvent(
+ const MouseMoveEventParams& params) {
+ TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchMouseMoveEvent", "device",
+ params.device_id);
+ MouseEvent event(ui::ET_MOUSE_MOVED, params.location, params.location,
+ params.timestamp, modifiers_.GetModifierFlags(),
+ /* changed_button_flags */ 0);
+ event.set_source_device_id(params.device_id);
+ DispatchUiEvent(&event);
+}
+
+void EventFactoryEvdev::DispatchMouseButtonEvent(
+ const MouseButtonEventParams& params) {
+ TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchMouseButtonEvent", "device",
+ params.device_id);
+
+ // Mouse buttons can be remapped, touchpad taps & clicks cannot.
+ unsigned int button = params.button;
+ if (params.allow_remap)
+ button = button_map_.GetMappedButton(button);
+
+ int modifier = EVDEV_MODIFIER_NONE;
+ switch (button) {
+ case BTN_LEFT:
+ modifier = EVDEV_MODIFIER_LEFT_MOUSE_BUTTON;
+ break;
+ case BTN_RIGHT:
+ modifier = EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON;
+ break;
+ case BTN_MIDDLE:
+ modifier = EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON;
+ break;
+ case BTN_BACK:
+ modifier = EVDEV_MODIFIER_BACK_MOUSE_BUTTON;
+ break;
+ case BTN_FORWARD:
+ modifier = EVDEV_MODIFIER_FORWARD_MOUSE_BUTTON;
+ break;
+ default:
+ return;
+ }
+
+ int flag = modifiers_.GetEventFlagFromModifier(modifier);
+ bool was_down = modifiers_.GetModifierFlags() & flag;
+ modifiers_.UpdateModifier(modifier, params.down);
+ bool down = modifiers_.GetModifierFlags() & flag;
+
+ // Suppress nested clicks. EventModifiersEvdev counts presses, we only
+ // dispatch an event on 0-1 (first press) and 1-0 (last release) transitions.
+ if (down == was_down)
+ return;
+
+ MouseEvent event(params.down ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED,
+ params.location, params.location, params.timestamp,
+ modifiers_.GetModifierFlags() | flag,
+ /* changed_button_flags */ flag);
+ event.set_source_device_id(params.device_id);
+ DispatchUiEvent(&event);
+}
+
+void EventFactoryEvdev::DispatchMouseWheelEvent(
+ const MouseWheelEventParams& params) {
+ TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchMouseWheelEvent", "device",
+ params.device_id);
+ MouseWheelEvent event(params.delta, params.location, params.location,
+ params.timestamp, modifiers_.GetModifierFlags(),
+ 0 /* changed_button_flags */);
+ event.set_source_device_id(params.device_id);
+ DispatchUiEvent(&event);
+}
+
+void EventFactoryEvdev::DispatchScrollEvent(const ScrollEventParams& params) {
+ TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchScrollEvent", "device",
+ params.device_id);
+ ScrollEvent event(params.type, params.location, params.timestamp,
+ modifiers_.GetModifierFlags(), params.delta.x(),
+ params.delta.y(), params.ordinal_delta.x(),
+ params.ordinal_delta.y(), params.finger_count);
+ event.set_source_device_id(params.device_id);
+ DispatchUiEvent(&event);
+}
+
+void EventFactoryEvdev::DispatchTouchEvent(const TouchEventParams& params) {
+ TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchTouchEvent", "device",
+ params.device_id);
+
+ float x = params.location.x();
+ float y = params.location.y();
+ double radius_x = params.radii.x();
+ double radius_y = params.radii.y();
+
+ // Transform the event to align touches to the image based on display mode.
+ DeviceDataManager::GetInstance()->ApplyTouchTransformer(params.device_id, &x,
+ &y);
+ DeviceDataManager::GetInstance()->ApplyTouchRadiusScale(params.device_id,
+ &radius_x);
+ DeviceDataManager::GetInstance()->ApplyTouchRadiusScale(params.device_id,
+ &radius_y);
+
+ // params.slot is guaranteed to be < kNumTouchEvdevSlots.
+ int touch_id = touch_id_generator_.GetGeneratedID(
+ params.device_id * kNumTouchEvdevSlots + params.slot);
+ TouchEvent touch_event(params.type, gfx::PointF(x, y),
+ modifiers_.GetModifierFlags(), touch_id,
+ params.timestamp, radius_x, radius_y,
+ /* angle */ 0.f, params.pressure);
+ touch_event.set_source_device_id(params.device_id);
+ DispatchUiEvent(&touch_event);
+
+ if (params.type == ET_TOUCH_RELEASED || params.type == ET_TOUCH_CANCELLED) {
+ touch_id_generator_.ReleaseGeneratedID(touch_event.touch_id());
+ }
+}
+
+void EventFactoryEvdev::DispatchUiEvent(Event* event) {
+ // DispatchEvent takes PlatformEvent which is void*. This function
+ // wraps it with the real type.
+ DispatchEvent(event);
+}
+
+void EventFactoryEvdev::DispatchKeyboardDevicesUpdated(
+ const std::vector<KeyboardDevice>& devices) {
+ TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchKeyboardDevicesUpdated");
+ DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
+ observer->OnKeyboardDevicesUpdated(devices);
+}
+
+void EventFactoryEvdev::DispatchTouchscreenDevicesUpdated(
+ const std::vector<TouchscreenDevice>& devices) {
+ TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchTouchscreenDevicesUpdated");
+ DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
+ observer->OnTouchscreenDevicesUpdated(devices);
+}
+
+void EventFactoryEvdev::DispatchMouseDevicesUpdated(
+ const std::vector<InputDevice>& devices) {
+ TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchMouseDevicesUpdated");
+
+ // There's no list of mice in DeviceDataManager.
+ input_controller_.set_has_mouse(devices.size() != 0);
+ DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
+ observer->OnMouseDevicesUpdated(devices);
+}
+
+void EventFactoryEvdev::DispatchTouchpadDevicesUpdated(
+ const std::vector<InputDevice>& devices) {
+ TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchTouchpadDevicesUpdated");
+
+ // There's no list of touchpads in DeviceDataManager.
+ input_controller_.set_has_touchpad(devices.size() != 0);
+ DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
+ observer->OnTouchpadDevicesUpdated(devices);
+}
+
+void EventFactoryEvdev::DispatchDeviceListsComplete() {
+ TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchDeviceListsComplete");
+ DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
+ observer->OnDeviceListsComplete();
+}
+
+void EventFactoryEvdev::OnDeviceEvent(const DeviceEvent& event) {
+ if (event.device_type() != DeviceEvent::INPUT)
+ return;
+
+ switch (event.action_type()) {
+ case DeviceEvent::ADD:
+ case DeviceEvent::CHANGE: {
+ TRACE_EVENT1("evdev", "EventFactoryEvdev::OnDeviceAdded", "path",
+ event.path().value());
+ input_device_factory_proxy_->AddInputDevice(NextDeviceId(), event.path());
+ break;
+ }
+ case DeviceEvent::REMOVE: {
+ TRACE_EVENT1("evdev", "EventFactoryEvdev::OnDeviceRemoved", "path",
+ event.path().value());
+ input_device_factory_proxy_->RemoveInputDevice(event.path());
+ break;
+ }
+ }
+}
+
+void EventFactoryEvdev::OnDispatcherListChanged() {
+ if (!initialized_)
+ Init();
+}
+
+void EventFactoryEvdev::WarpCursorTo(gfx::AcceleratedWidget widget,
+ const gfx::PointF& location) {
+ if (!cursor_)
+ return;
+
+ cursor_->MoveCursorTo(widget, location);
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchMouseMoveEvent,
+ weak_ptr_factory_.GetWeakPtr(),
+ MouseMoveEventParams(-1 /* device_id */,
+ cursor_->GetLocation(),
+ EventTimeForNow())));
+}
+
+int EventFactoryEvdev::NextDeviceId() {
+ return ++last_device_id_;
+}
+
+void EventFactoryEvdev::StartThread() {
+ // Set up device factory.
+ scoped_ptr<DeviceEventDispatcherEvdev> proxy_dispatcher(
+ new ProxyDeviceEventDispatcher(base::ThreadTaskRunnerHandle::Get(),
+ weak_ptr_factory_.GetWeakPtr()));
+ thread_.Start(proxy_dispatcher.Pass(), cursor_,
+ base::Bind(&EventFactoryEvdev::OnThreadStarted,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void EventFactoryEvdev::OnThreadStarted(
+ scoped_ptr<InputDeviceFactoryEvdevProxy> input_device_factory) {
+ TRACE_EVENT0("evdev", "EventFactoryEvdev::OnThreadStarted");
+ input_device_factory_proxy_ = input_device_factory.Pass();
+
+ // Hook up device configuration.
+ input_controller_.SetInputDeviceFactory(input_device_factory_proxy_.get());
+
+ // Scan & monitor devices.
+ device_manager_->AddObserver(this);
+ device_manager_->ScanDevices(this);
+
+ // Notify device thread that initial scan is done.
+ input_device_factory_proxy_->OnStartupScanComplete();
+}
+
+} // namespace ui
« no previous file with comments | « ui/events/ozone/evdev/event_factory_evdev.h ('k') | ui/events/ozone/evdev/event_modifiers_evdev.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698