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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 #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.
2
3 #include "base/logging.h"
4 #include "base/time/time.h"
5 #include "ui/events/keycodes/dom/keycode_converter.h"
6 #include "ui/events/ozone/evdev/keyboard_util_evdev.h"
7
8 #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.
9
10 namespace arc {
11
12 namespace {
13 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
14 }
15
16 // BridgeInputDevice
17
18 BridgeInputDevice::BridgeInputDevice(base::ScopedFD fd) : fd_(fd.Pass()) {}
19
20 void BridgeInputDevice::SendEvent(base::TimeDelta timestamp,
21 __u16 type,
22 __u16 code,
23 __s32 value) {
24 // Luckily Chrome on POSIX and the receiver both use monotonic time for
25 // input events, so we can just fill in the same timestamp.
26 // todo(denniskempin): Nevertheless there are rare issues with stale events on
27 // the instance side.
28 struct input_event event;
29 event.time.tv_sec = timestamp.InSeconds();
30 base::TimeDelta remainder =
31 timestamp - base::TimeDelta::FromSeconds(event.time.tv_sec);
32 event.time.tv_usec = remainder.InMicroseconds();
33 event.type = type;
34 event.code = code;
35 event.value = value;
36
37 // Write event to file descriptor
38 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
39 sizeof(struct input_event));
40 if (num_written != sizeof(struct input_event)) {
41 LOG(ERROR) << "Can't write to file descriptor";
42 }
43 }
44
45 void BridgeInputDevice::SendSynReport(base::TimeDelta time) {
46 SendEvent(time, EV_SYN, SYN_REPORT, 0);
47 }
48
49 // KeyboardBridgeInputDevice
50
51 KeyboardBridgeInputDevice::KeyboardBridgeInputDevice(base::ScopedFD fd)
52 : BridgeInputDevice(fd.Pass()) {}
53
54 void KeyboardBridgeInputDevice::OnKeyEvent(ui::KeyEvent* event) {
55 int native_code = ui::KeycodeConverter::DomCodeToNativeKeycode(event->code());
56
57 __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
58 __u32 evdev_value;
59 if (event->type() == ui::ET_KEY_PRESSED) {
60 if (event->flags() & ui::EF_IS_REPEAT) {
61 evdev_value = kKeyRepeated;
62 } else {
63 evdev_value = kKeyPressed;
64 }
65 } else if (event->type() == ui::ET_KEY_RELEASED) {
66 evdev_value = kKeyReleased;
67 }
68
69 SendEvent(event->time_stamp(), EV_KEY, evdev_code, evdev_value);
70 SendSynReport(event->time_stamp());
71 }
72
73 // MouseBridgeInputDevice
74
75 MouseBridgeInputDevice::MouseBridgeInputDevice(base::ScopedFD fd)
76 : BridgeInputDevice(fd.Pass()) {}
77
78 void MouseBridgeInputDevice::OnMouseEvent(ui::MouseEvent* event) {
79 base::TimeDelta time = event->time_stamp();
80 if (event->y() - y_offset < 0) {
81 return;
82 }
83
84 // update location
85 if (event->type() == ui::ET_MOUSE_MOVED) {
86 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
87 SendEvent(time, EV_ABS, ABS_Y, event->y() - y_offset);
88 }
89
90 // update buttons
91 if (event->type() == ui::ET_MOUSE_PRESSED ||
92 event->type() == ui::ET_MOUSE_RELEASED) {
93 bool button_value = event->type() == ui::ET_MOUSE_PRESSED;
94 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
95 SendMouseButton(event, ui::EF_RIGHT_MOUSE_BUTTON, BTN_RIGHT, button_value);
96 SendMouseButton(event, ui::EF_MIDDLE_MOUSE_BUTTON, BTN_MIDDLE,
97 button_value);
98 }
99
100 // update scroll wheel
101 if (event->IsMouseWheelEvent()) {
102 ui::MouseWheelEvent* wheel_event = static_cast<ui::MouseWheelEvent*>(event);
103 SendEvent(time, EV_REL, REL_WHEEL, wheel_event->y_offset());
104 SendEvent(time, EV_REL, REL_HWHEEL, wheel_event->x_offset());
105 }
106
107 SendSynReport(time);
108 }
109
110 void MouseBridgeInputDevice::SendMouseButton(ui::MouseEvent* event,
111 int flag,
112 int evdev_code,
113 bool button_value) {
114 if (event->changed_button_flags() & flag) {
115 SendEvent(event->time_stamp(), EV_KEY, evdev_code, (__s32)button_value);
116 }
117 }
118
119 // TouchscreenBridgeInputDevice
120
121 TouchscreenBridgeInputDevice::TouchscreenBridgeInputDevice(base::ScopedFD fd)
122 : BridgeInputDevice(fd.Pass()),
123 current_slot_tracking_ids_(kMaxSlots, kEmptySlot),
124 current_slot_(-1) {}
125
126 void TouchscreenBridgeInputDevice::OnTouchEvent(ui::TouchEvent* event) {
127 ui::PointerDetails details = event->pointer_details();
128 base::TimeDelta time = event->time_stamp();
129 if (event->y() - y_offset < 0) {
130 return;
131 }
132
133 // find or assing a slot for this tracking id
134 int slot_id = AcquireSlot(event);
135 if (slot_id < 0) {
136 LOG(ERROR) << "Ran out of slot IDs.";
137 return;
138 }
139
140 // we only need to send the slot ID when it has changed.
141 if (slot_id != current_slot_) {
142 current_slot_ = slot_id;
143 SendEvent(time, EV_ABS, ABS_MT_SLOT, current_slot_);
144 }
145
146 // update tracking id
147 if (event->type() == ui::ET_TOUCH_PRESSED) {
148 SendEvent(time, EV_ABS, ABS_MT_TRACKING_ID, event->touch_id());
149 } else if (event->type() == ui::ET_TOUCH_RELEASED) {
150 SendEvent(time, EV_ABS, ABS_MT_TRACKING_ID, -1);
151 }
152
153 // update touch information
154 if (event->type() == ui::ET_TOUCH_MOVED ||
155 event->type() == ui::ET_TOUCH_PRESSED) {
156 SendEvent(time, EV_ABS, ABS_MT_POSITION_X, event->x());
157 SendEvent(time, EV_ABS, ABS_MT_POSITION_Y, event->y() - y_offset);
158 SendEvent(time, EV_ABS, ABS_MT_TOUCH_MAJOR, details.radius_x());
159 SendEvent(time, EV_ABS, ABS_MT_TOUCH_MINOR, details.radius_y());
160 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().
161 }
162 SendSynReport(time);
163 }
164
165 int TouchscreenBridgeInputDevice::AcquireSlot(ui::TouchEvent* event) {
166 int slot_id;
167 if (event->type() == ui::ET_TOUCH_PRESSED) {
168 slot_id = FindSlot(kEmptySlot);
169 } else {
170 slot_id = FindSlot(event->touch_id());
171 }
172 if (slot_id < 0) {
173 return -1;
174 }
175
176 if (event->type() == ui::ET_TOUCH_RELEASED) {
177 current_slot_tracking_ids_[slot_id] = kEmptySlot;
178 } else if (event->type() == ui::ET_TOUCH_PRESSED) {
179 current_slot_tracking_ids_[slot_id] = event->touch_id();
180 }
181 return slot_id;
182 }
183
184 int TouchscreenBridgeInputDevice::FindSlot(int tracking_id) {
185 for (int i = 0; i < kMaxSlots; ++i) {
186 if (current_slot_tracking_ids_[i] == tracking_id) {
187 return i;
188 }
189 }
190 return -1;
191 }
192
193 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698