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

Side by Side Diff: ui/events/ozone/evdev/tablet_event_converter_evdev.cc

Issue 847663004: ozone: Handle on-screen stylus support consistently (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 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 unified diff | Download patch
« no previous file with comments | « ui/events/ozone/evdev/tablet_event_converter_evdev.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/events/ozone/evdev/tablet_event_converter_evdev.h" 5 #include "ui/events/ozone/evdev/tablet_event_converter_evdev.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <linux/input.h> 8 #include <linux/input.h>
9 9
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "base/time/time.h"
11 #include "ui/events/event.h" 12 #include "ui/events/event.h"
12 13
13 namespace ui { 14 namespace ui {
14 15
15 TabletEventConverterEvdev::TabletEventConverterEvdev( 16 TabletEventConverterEvdev::TabletEventConverterEvdev(
16 int fd, 17 int fd,
17 base::FilePath path, 18 base::FilePath path,
18 int id, 19 int id,
19 InputDeviceType type, 20 InputDeviceType type,
20 EventModifiersEvdev* modifiers, 21 EventModifiersEvdev* modifiers,
21 CursorDelegateEvdev* cursor, 22 CursorDelegateEvdev* cursor,
22 const EventDeviceInfo& info, 23 const EventDeviceInfo& info,
23 const EventDispatchCallback& callback) 24 const EventDispatchCallback& callback)
24 : EventConverterEvdev(fd, path, id, type), 25 : EventConverterEvdev(fd, path, id, type),
25 cursor_(cursor), 26 cursor_(cursor),
26 modifiers_(modifiers), 27 modifiers_(modifiers),
27 callback_(callback), 28 callback_(callback),
28 stylus_(0), 29 stylus_(0),
29 abs_value_dirty_(false) { 30 abs_value_dirty_(false),
31 on_screen_stylus_(false) {
30 x_abs_min_ = info.GetAbsMinimum(ABS_X); 32 x_abs_min_ = info.GetAbsMinimum(ABS_X);
31 x_abs_range_ = info.GetAbsMaximum(ABS_X) - x_abs_min_ + 1; 33 x_abs_range_ = info.GetAbsMaximum(ABS_X) - x_abs_min_ + 1;
32 y_abs_min_ = info.GetAbsMinimum(ABS_Y); 34 y_abs_min_ = info.GetAbsMinimum(ABS_Y);
33 y_abs_range_ = info.GetAbsMaximum(ABS_Y) - y_abs_min_ + 1; 35 y_abs_range_ = info.GetAbsMaximum(ABS_Y) - y_abs_min_ + 1;
36 pressure_min_ = info.GetAbsMinimum(ABS_PRESSURE);
37 pressure_range_ = info.GetAbsMaximum(ABS_PRESSURE) - pressure_min_ + 1;
38 on_screen_stylus_ = !info.HasProp(INPUT_PROP_POINTER);
34 } 39 }
35 40
36 TabletEventConverterEvdev::~TabletEventConverterEvdev() { 41 TabletEventConverterEvdev::~TabletEventConverterEvdev() {
37 Stop(); 42 Stop();
38 close(fd_); 43 close(fd_);
39 } 44 }
40 45
41 void TabletEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) { 46 void TabletEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
42 input_event inputs[4]; 47 input_event inputs[4];
43 ssize_t read_size = read(fd, inputs, sizeof(inputs)); 48 ssize_t read_size = read(fd, inputs, sizeof(inputs));
(...skipping 18 matching lines...) Expand all
62 for (int i = 0; i < count; ++i) { 67 for (int i = 0; i < count; ++i) {
63 const input_event& input = inputs[i]; 68 const input_event& input = inputs[i];
64 switch (input.type) { 69 switch (input.type) {
65 case EV_KEY: 70 case EV_KEY:
66 ConvertKeyEvent(input); 71 ConvertKeyEvent(input);
67 break; 72 break;
68 case EV_ABS: 73 case EV_ABS:
69 ConvertAbsEvent(input); 74 ConvertAbsEvent(input);
70 break; 75 break;
71 case EV_SYN: 76 case EV_SYN:
72 FlushEvents(); 77 FlushEvents(input);
73 break; 78 break;
74 } 79 }
75 } 80 }
76 } 81 }
77 82
78 void TabletEventConverterEvdev::ConvertKeyEvent(const input_event& input) { 83 void TabletEventConverterEvdev::ConvertKeyEvent(const input_event& input) {
79 // Only handle other events if we have a stylus in proximity 84 // Only handle other events if we have a stylus in proximity
80 if (input.code >= BTN_TOOL_PEN && input.code <= BTN_TOOL_LENS) { 85 if (input.code >= BTN_TOOL_PEN && input.code <= BTN_TOOL_LENS) {
81 if (input.value == 1) 86 if (input.value == 1)
82 stylus_ = input.code; 87 stylus_ = input.code;
83 else if (input.value == 0) 88 else if (input.value == 0)
84 stylus_ = 0; 89 stylus_ = 0;
85 else 90 else
86 LOG(WARNING) << "Unexpected value: " << input.value 91 LOG(WARNING) << "Unexpected value: " << input.value
87 << " for code: " << input.code; 92 << " for code: " << input.code;
88 } 93 }
89 94
90 if (input.code >= BTN_TOUCH && input.code <= BTN_STYLUS2) { 95 if (input.code >= BTN_TOUCH && input.code <= BTN_STYLUS2) {
91 DispatchMouseButton(input); 96 if (input.code == BTN_TOUCH && on_screen_stylus_) {
92 return; 97 DispatchTouch(input);
98 } else {
99 DispatchMouseButton(input);
100 }
93 } 101 }
94 } 102 }
95 103
96 void TabletEventConverterEvdev::ConvertAbsEvent(const input_event& input) { 104 void TabletEventConverterEvdev::ConvertAbsEvent(const input_event& input) {
97 if (!cursor_) 105 if (!cursor_)
98 return; 106 return;
99 107
100 switch (input.code) { 108 switch (input.code) {
101 case ABS_X: 109 case ABS_X:
102 x_abs_location_ = input.value; 110 x_abs_location_ = input.value;
103 abs_value_dirty_ = true; 111 abs_value_dirty_ = true;
104 break; 112 break;
105 case ABS_Y: 113 case ABS_Y:
106 y_abs_location_ = input.value; 114 y_abs_location_ = input.value;
107 abs_value_dirty_ = true; 115 abs_value_dirty_ = true;
108 break; 116 break;
117 case ABS_PRESSURE:
118 pressure_ = input.value;
119 break;
109 } 120 }
110 } 121 }
111 122
112 void TabletEventConverterEvdev::UpdateCursor() { 123 void TabletEventConverterEvdev::UpdateCursor() {
113 gfx::Rect display_bounds = cursor_->GetCursorDisplayBounds(); 124 gfx::Rect display_bounds = cursor_->GetCursorDisplayBounds();
114 125
115 int x = 126 int x =
116 ((x_abs_location_ - x_abs_min_) * display_bounds.width()) / x_abs_range_; 127 ((x_abs_location_ - x_abs_min_) * display_bounds.width()) / x_abs_range_;
117 int y = 128 int y =
118 ((y_abs_location_ - y_abs_min_) * display_bounds.height()) / y_abs_range_; 129 ((y_abs_location_ - y_abs_min_) * display_bounds.height()) / y_abs_range_;
119 130
120 x += display_bounds.x(); 131 x += display_bounds.x();
121 y += display_bounds.y(); 132 y += display_bounds.y();
122 133
123 cursor_->MoveCursorTo(gfx::PointF(x, y)); 134 cursor_->MoveCursorTo(gfx::PointF(x, y));
124 } 135 }
125 136
137 void TabletEventConverterEvdev::DispatchTouch(const input_event& input) {
138 if (abs_value_dirty_) {
139 UpdateCursor();
140 abs_value_dirty_ = false;
141 }
142
143 // Start making motion events touch motion rather than mouse
144 emit_touch_ = input.value;
145
146 base::TimeDelta delta = base::TimeDelta::FromMicroseconds(
147 input.time.tv_sec * 1000000 + input.time.tv_usec);
148 scoped_ptr<TouchEvent> touch_event(new TouchEvent(
149 input.value ? ET_TOUCH_PRESSED : ET_TOUCH_RELEASED,
150 cursor_->GetLocation(),
151 /* flags */ 0,
152 /* touch_id */ 1,
153 /* delta */ delta,
154 /* radius_x */ 1.0,
155 /* radius_y */ 1.0,
156 /* angle */ 0.,
157 /* force */ (float)(pressure_ - pressure_min_) / pressure_range_));
158 touch_event->set_source_device_id(id_);
159 callback_.Run(touch_event.Pass());
160 }
161
126 void TabletEventConverterEvdev::DispatchMouseButton(const input_event& input) { 162 void TabletEventConverterEvdev::DispatchMouseButton(const input_event& input) {
127 if (!cursor_) 163 if (!cursor_)
128 return; 164 return;
129 165
130 unsigned int modifier; 166 unsigned int modifier;
131 // These are the same as X11 behaviour 167 // These are the same as X11 behaviour
132 if (input.code == BTN_TOUCH) 168 if (input.code == BTN_TOUCH)
133 modifier = EVDEV_MODIFIER_LEFT_MOUSE_BUTTON; 169 modifier = EVDEV_MODIFIER_LEFT_MOUSE_BUTTON;
134 else if (input.code == BTN_STYLUS2) 170 else if (input.code == BTN_STYLUS2)
135 modifier = EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON; 171 modifier = EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON;
136 else if (input.code == BTN_STYLUS) 172 else if (input.code == BTN_STYLUS)
137 modifier = EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON; 173 modifier = EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON;
138 else 174 else
139 return; 175 return;
140 176
141 if (abs_value_dirty_) { 177 if (abs_value_dirty_) {
142 UpdateCursor(); 178 UpdateCursor();
143 abs_value_dirty_ = false; 179 abs_value_dirty_ = false;
144 } 180 }
145 181
146 int flag = modifiers_->GetEventFlagFromModifier(modifier); 182 int flag = modifiers_->GetEventFlagFromModifier(modifier);
147 modifiers_->UpdateModifier(modifier, input.value); 183 modifiers_->UpdateModifier(modifier, input.value);
148 callback_.Run(make_scoped_ptr( 184 callback_.Run(make_scoped_ptr(
149 new MouseEvent(input.value ? ET_MOUSE_PRESSED : ET_MOUSE_RELEASED, 185 new MouseEvent(input.value ? ET_MOUSE_PRESSED : ET_MOUSE_RELEASED,
150 cursor_->GetLocation(), cursor_->GetLocation(), 186 cursor_->GetLocation(), cursor_->GetLocation(),
151 modifiers_->GetModifierFlags() | flag, flag))); 187 modifiers_->GetModifierFlags() | flag, flag)));
152 } 188 }
153 189
154 void TabletEventConverterEvdev::FlushEvents() { 190 void TabletEventConverterEvdev::FlushEvents(const input_event& input) {
155 if (!cursor_) 191 if (!cursor_)
156 return; 192 return;
157 193
158 // Prevent propagation of invalid data on stylus lift off 194 // Prevent propagation of invalid data on stylus lift off
159 if (stylus_ == 0) { 195 if (stylus_ == 0) {
160 abs_value_dirty_ = false; 196 abs_value_dirty_ = false;
161 return; 197 return;
162 } 198 }
163 199
164 if (!abs_value_dirty_) 200 if (!abs_value_dirty_)
165 return; 201 return;
166 202
167 UpdateCursor(); 203 UpdateCursor();
168 204
205 if (emit_touch_) {
206 base::TimeDelta delta = base::TimeDelta::FromMicroseconds(
207 input.time.tv_sec * 1000000 + input.time.tv_usec);
208 scoped_ptr<TouchEvent> touch_event(new TouchEvent(
209 ET_TOUCH_MOVED,
210 cursor_->GetLocation(),
211 /* flags */ 0,
212 /* touch_id */ 1,
Rick Byers 2015/01/19 20:44:20 What if there is both real touchscreen and stylus
213 /* delta */ delta,
214 /* radius_x */ 1.0,
215 /* radius_y */ 1.0,
216 /* angle */ 0.,
217 /* force */ (float)(pressure_ - pressure_min_) / pressure_range_));
218 touch_event->set_source_device_id(id_);
219 callback_.Run(touch_event.Pass());
220 } else {
169 callback_.Run(make_scoped_ptr( 221 callback_.Run(make_scoped_ptr(
170 new MouseEvent(ui::ET_MOUSE_MOVED, cursor_->GetLocation(), 222 new MouseEvent(ui::ET_MOUSE_MOVED, cursor_->GetLocation(),
171 cursor_->GetLocation(), modifiers_->GetModifierFlags(), 223 cursor_->GetLocation(), modifiers_->GetModifierFlags(),
172 /* changed_button_flags */ 0))); 224 /* changed_button_flags */ 0)));
173 225 }
174 abs_value_dirty_ = false; 226 abs_value_dirty_ = false;
175 } 227 }
176 228
177 } // namespace ui 229 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/ozone/evdev/tablet_event_converter_evdev.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698