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

Unified Diff: components/arc/arc_bridge_input_devices.cc

Issue 1408263006: chromeos: Add ArcInputBridge to components/arc (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@arcxx
Patch Set: added owners Created 5 years, 1 month 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: components/arc/arc_bridge_input_devices.cc
diff --git a/components/arc/arc_bridge_input_devices.cc b/components/arc/arc_bridge_input_devices.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bbab636debc06a5eb7594398e5c9ec3e98156273
--- /dev/null
+++ b/components/arc/arc_bridge_input_devices.cc
@@ -0,0 +1,193 @@
+#include "components/arc/arc_bridge_input_devices.h"
Luis Héctor Chávez 2015/11/17 17:51:53 Also missing copyright block.
denniskempin 2015/11/19 19:22:08 Done.
+
+#include "base/logging.h"
+#include "base/time/time.h"
+#include "ui/events/keycodes/dom/keycode_converter.h"
+#include "ui/events/ozone/evdev/keyboard_util_evdev.h"
+
+#include <linux/input.h>
Luis Héctor Chávez 2015/11/17 17:51:53 Convention seems to be to put the system includes
denniskempin 2015/11/19 19:22:08 Done.
+
+namespace arc {
+
+namespace {
+static const int y_offset = 32;
elijahtaylor1 2015/11/16 21:08:26 comment on this, specifically about it being temp
denniskempin 2015/11/19 19:22:08 oops. this line should be part of the HACK CL. I d
+}
+
+// BridgeInputDevice
+
+BridgeInputDevice::BridgeInputDevice(base::ScopedFD fd) : fd_(fd.Pass()) {}
+
+void BridgeInputDevice::SendEvent(base::TimeDelta timestamp,
+ __u16 type,
+ __u16 code,
+ __s32 value) {
+ // Luckily Chrome on POSIX and the receiver both use monotonic time for
+ // input events, so we can just fill in the same timestamp.
+ // todo(denniskempin): Nevertheless there are rare issues with stale events on
+ // the instance side.
+ struct input_event event;
+ event.time.tv_sec = timestamp.InSeconds();
+ base::TimeDelta remainder =
+ timestamp - base::TimeDelta::FromSeconds(event.time.tv_sec);
+ event.time.tv_usec = remainder.InMicroseconds();
+ event.type = type;
+ event.code = code;
+ event.value = value;
+
+ // Write event to file descriptor
+ int num_written = write(fd_.get(), reinterpret_cast<void*>(&event),
Luis Héctor Chávez 2015/11/17 17:51:53 Can you add a thread check to make sure you are no
denniskempin 2015/11/19 19:22:08 I'll have to look into that. I did not know we can
+ sizeof(struct input_event));
+ if (num_written != sizeof(struct input_event)) {
+ LOG(ERROR) << "Can't write to file descriptor";
+ }
+}
+
+void BridgeInputDevice::SendSynReport(base::TimeDelta time) {
+ SendEvent(time, EV_SYN, SYN_REPORT, 0);
+}
+
+// KeyboardBridgeInputDevice
+
+KeyboardBridgeInputDevice::KeyboardBridgeInputDevice(base::ScopedFD fd)
+ : BridgeInputDevice(fd.Pass()) {}
+
+void KeyboardBridgeInputDevice::OnKeyEvent(ui::KeyEvent* event) {
+ int native_code = ui::KeycodeConverter::DomCodeToNativeKeycode(event->code());
+
+ __u16 evdev_code = ui::NativeCodeToEvdevCode(native_code);
Luis Héctor Chávez 2015/11/17 17:51:53 Huh, this does not need a cast?
denniskempin 2015/11/19 19:22:08 I expected the method to return a u16 which is the
+ __u32 evdev_value;
+ if (event->type() == ui::ET_KEY_PRESSED) {
+ if (event->flags() & ui::EF_IS_REPEAT) {
+ evdev_value = kKeyRepeated;
+ } else {
+ evdev_value = kKeyPressed;
+ }
+ } else if (event->type() == ui::ET_KEY_RELEASED) {
+ evdev_value = kKeyReleased;
+ }
+
+ SendEvent(event->time_stamp(), EV_KEY, evdev_code, evdev_value);
+ SendSynReport(event->time_stamp());
+}
+
+// MouseBridgeInputDevice
+
+MouseBridgeInputDevice::MouseBridgeInputDevice(base::ScopedFD fd)
+ : BridgeInputDevice(fd.Pass()) {}
+
+void MouseBridgeInputDevice::OnMouseEvent(ui::MouseEvent* event) {
+ base::TimeDelta time = event->time_stamp();
+ if (event->y() - y_offset < 0) {
+ return;
+ }
+
+ // update location
+ if (event->type() == ui::ET_MOUSE_MOVED) {
+ SendEvent(time, EV_ABS, ABS_X, event->x());
elijahtaylor1 2015/11/16 21:08:26 is there no decoration on the x side that needs to
denniskempin 2015/11/19 19:22:08 See above. We did not see any offset in the X dire
+ SendEvent(time, EV_ABS, ABS_Y, event->y() - y_offset);
+ }
+
+ // update buttons
+ if (event->type() == ui::ET_MOUSE_PRESSED ||
+ event->type() == ui::ET_MOUSE_RELEASED) {
+ bool button_value = event->type() == ui::ET_MOUSE_PRESSED;
+ SendMouseButton(event, ui::EF_LEFT_MOUSE_BUTTON, BTN_LEFT, button_value);
elijahtaylor1 2015/11/16 21:08:26 this is a weird structure. Some of the |event| ch
denniskempin 2015/11/19 19:22:08 I agree. It made sense in the beginning, not anymo
+ SendMouseButton(event, ui::EF_RIGHT_MOUSE_BUTTON, BTN_RIGHT, button_value);
+ SendMouseButton(event, ui::EF_MIDDLE_MOUSE_BUTTON, BTN_MIDDLE,
+ button_value);
+ }
+
+ // update scroll wheel
+ if (event->IsMouseWheelEvent()) {
+ ui::MouseWheelEvent* wheel_event = static_cast<ui::MouseWheelEvent*>(event);
+ SendEvent(time, EV_REL, REL_WHEEL, wheel_event->y_offset());
+ SendEvent(time, EV_REL, REL_HWHEEL, wheel_event->x_offset());
+ }
+
+ SendSynReport(time);
+}
+
+void MouseBridgeInputDevice::SendMouseButton(ui::MouseEvent* event,
+ int flag,
+ int evdev_code,
+ bool button_value) {
+ if (event->changed_button_flags() & flag) {
+ SendEvent(event->time_stamp(), EV_KEY, evdev_code, (__s32)button_value);
+ }
+}
+
+// TouchscreenBridgeInputDevice
+
+TouchscreenBridgeInputDevice::TouchscreenBridgeInputDevice(base::ScopedFD fd)
+ : BridgeInputDevice(fd.Pass()),
+ current_slot_tracking_ids_(kMaxSlots, kEmptySlot),
+ current_slot_(-1) {}
+
+void TouchscreenBridgeInputDevice::OnTouchEvent(ui::TouchEvent* event) {
+ ui::PointerDetails details = event->pointer_details();
+ base::TimeDelta time = event->time_stamp();
+ if (event->y() - y_offset < 0) {
+ return;
+ }
+
+ // find or assing a slot for this tracking id
+ int slot_id = AcquireSlot(event);
+ if (slot_id < 0) {
+ LOG(ERROR) << "Ran out of slot IDs.";
+ return;
+ }
+
+ // we only need to send the slot ID when it has changed.
+ if (slot_id != current_slot_) {
+ current_slot_ = slot_id;
+ SendEvent(time, EV_ABS, ABS_MT_SLOT, current_slot_);
+ }
+
+ // update tracking id
+ if (event->type() == ui::ET_TOUCH_PRESSED) {
+ SendEvent(time, EV_ABS, ABS_MT_TRACKING_ID, event->touch_id());
+ } else if (event->type() == ui::ET_TOUCH_RELEASED) {
+ SendEvent(time, EV_ABS, ABS_MT_TRACKING_ID, -1);
+ }
+
+ // update touch information
+ if (event->type() == ui::ET_TOUCH_MOVED ||
+ event->type() == ui::ET_TOUCH_PRESSED) {
+ SendEvent(time, EV_ABS, ABS_MT_POSITION_X, event->x());
+ SendEvent(time, EV_ABS, ABS_MT_POSITION_Y, event->y() - y_offset);
+ SendEvent(time, EV_ABS, ABS_MT_TOUCH_MAJOR, details.radius_x());
+ SendEvent(time, EV_ABS, ABS_MT_TOUCH_MINOR, details.radius_y());
+ SendEvent(time, EV_ABS, ABS_MT_PRESSURE, 100);
elijahtaylor1 2015/11/16 21:08:26 what is 100?
denniskempin 2015/11/19 19:22:08 a hack. Updated to use force().
+ }
+ SendSynReport(time);
+}
+
+int TouchscreenBridgeInputDevice::AcquireSlot(ui::TouchEvent* event) {
+ int slot_id;
+ if (event->type() == ui::ET_TOUCH_PRESSED) {
+ slot_id = FindSlot(kEmptySlot);
+ } else {
+ slot_id = FindSlot(event->touch_id());
+ }
+ if (slot_id < 0) {
+ return -1;
+ }
+
+ if (event->type() == ui::ET_TOUCH_RELEASED) {
+ current_slot_tracking_ids_[slot_id] = kEmptySlot;
+ } else if (event->type() == ui::ET_TOUCH_PRESSED) {
+ current_slot_tracking_ids_[slot_id] = event->touch_id();
+ }
+ return slot_id;
+}
+
+int TouchscreenBridgeInputDevice::FindSlot(int tracking_id) {
+ for (int i = 0; i < kMaxSlots; ++i) {
+ if (current_slot_tracking_ids_[i] == tracking_id) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+} // namespace arc

Powered by Google App Engine
This is Rietveld 408576698