OLD | NEW |
---|---|
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/touch_event_converter_evdev.h" | 5 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <linux/input.h> | 9 #include <linux/input.h> |
10 #include <poll.h> | 10 #include <poll.h> |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
53 if (!base::StringToInt(parts[3], &cal->bezel_bottom)) | 53 if (!base::StringToInt(parts[3], &cal->bezel_bottom)) |
54 DLOG(ERROR) << "Incorrect bottom border calibration value passed."; | 54 DLOG(ERROR) << "Incorrect bottom border calibration value passed."; |
55 } | 55 } |
56 } | 56 } |
57 | 57 |
58 } // namespace | 58 } // namespace |
59 | 59 |
60 namespace ui { | 60 namespace ui { |
61 | 61 |
62 TouchEventConverterEvdev::InProgressEvents::InProgressEvents() | 62 TouchEventConverterEvdev::InProgressEvents::InProgressEvents() |
63 : x_(0), | 63 : altered_(false), |
64 x_(0), | |
64 y_(0), | 65 y_(0), |
65 id_(-1), | 66 id_(-1), |
66 finger_(-1), | 67 finger_(-1), |
67 type_(ET_UNKNOWN), | 68 type_(ET_UNKNOWN), |
68 radius_x_(0), | 69 radius_x_(0), |
69 radius_y_(0), | 70 radius_y_(0), |
70 pressure_(0) { | 71 pressure_(0) { |
71 } | 72 } |
72 | 73 |
73 TouchEventConverterEvdev::TouchEventConverterEvdev( | 74 TouchEventConverterEvdev::TouchEventConverterEvdev( |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 y_min_tuxels_ += cal.bezel_top; | 106 y_min_tuxels_ += cal.bezel_top; |
106 y_num_tuxels_ -= cal.bezel_top + cal.bezel_bottom; | 107 y_num_tuxels_ -= cal.bezel_top + cal.bezel_bottom; |
107 | 108 |
108 VLOG(1) << "applying touch calibration: " | 109 VLOG(1) << "applying touch calibration: " |
109 << base::StringPrintf("[%d, %d, %d, %d]", cal.bezel_left, | 110 << base::StringPrintf("[%d, %d, %d, %d]", cal.bezel_left, |
110 cal.bezel_right, cal.bezel_top, | 111 cal.bezel_right, cal.bezel_top, |
111 cal.bezel_bottom); | 112 cal.bezel_bottom); |
112 } | 113 } |
113 | 114 |
114 native_size_ = gfx::Size(x_num_tuxels_, y_num_tuxels_); | 115 native_size_ = gfx::Size(x_num_tuxels_, y_num_tuxels_); |
115 | 116 |
spang
2015/02/02 22:09:42
I think you should create events_ here with size o
achaulk
2015/02/03 16:51:49
Done.
| |
116 for (int i = 0; | 117 for (int i = 0; |
117 i < std::min<int>(info.GetAbsMaximum(ABS_MT_SLOT) + 1, MAX_FINGERS); | 118 i < std::min<int>(info.GetAbsMaximum(ABS_MT_SLOT) + 1, MAX_FINGERS); |
spang
2015/02/02 22:09:42
needs adjustment to iterate the whole vector & ini
| |
118 ++i) { | 119 ++i) { |
119 events_[i].finger_ = info.GetSlotValue(ABS_MT_TRACKING_ID, i); | 120 events_[i].finger_ = info.GetSlotValue(ABS_MT_TRACKING_ID, i); |
120 events_[i].type_ = | 121 events_[i].type_ = |
121 events_[i].finger_ < 0 ? ET_TOUCH_RELEASED : ET_TOUCH_PRESSED; | 122 events_[i].finger_ < 0 ? ET_TOUCH_RELEASED : ET_TOUCH_PRESSED; |
122 events_[i].x_ = info.GetSlotValue(ABS_MT_POSITION_X, i); | 123 events_[i].x_ = info.GetSlotValue(ABS_MT_POSITION_X, i); |
123 events_[i].y_ = info.GetSlotValue(ABS_MT_POSITION_Y, i); | 124 events_[i].y_ = info.GetSlotValue(ABS_MT_POSITION_Y, i); |
124 events_[i].radius_x_ = info.GetSlotValue(ABS_MT_TOUCH_MAJOR, i); | 125 events_[i].radius_x_ = info.GetSlotValue(ABS_MT_TOUCH_MAJOR, i); |
125 events_[i].radius_y_ = info.GetSlotValue(ABS_MT_TOUCH_MINOR, i); | 126 events_[i].radius_y_ = info.GetSlotValue(ABS_MT_TOUCH_MINOR, i); |
126 events_[i].pressure_ = info.GetSlotValue(ABS_MT_PRESSURE, i); | 127 events_[i].pressure_ = info.GetSlotValue(ABS_MT_PRESSURE, i); |
127 } | 128 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 ProcessInputEvent(inputs[i]); | 164 ProcessInputEvent(inputs[i]); |
164 } | 165 } |
165 } | 166 } |
166 | 167 |
167 void TouchEventConverterEvdev::ProcessInputEvent(const input_event& input) { | 168 void TouchEventConverterEvdev::ProcessInputEvent(const input_event& input) { |
168 if (input.type == EV_SYN) { | 169 if (input.type == EV_SYN) { |
169 ProcessSyn(input); | 170 ProcessSyn(input); |
170 } else if(syn_dropped_) { | 171 } else if(syn_dropped_) { |
171 // Do nothing. This branch indicates we have lost sync with the driver. | 172 // Do nothing. This branch indicates we have lost sync with the driver. |
172 } else if (input.type == EV_ABS) { | 173 } else if (input.type == EV_ABS) { |
173 if (current_slot_ >= MAX_FINGERS) { | |
174 LOG(ERROR) << "too many touch events: " << current_slot_; | |
175 return; | |
176 } | |
177 ProcessAbs(input); | 174 ProcessAbs(input); |
178 } else if (input.type == EV_KEY) { | 175 } else if (input.type == EV_KEY) { |
179 switch (input.code) { | 176 switch (input.code) { |
180 case BTN_TOUCH: | 177 case BTN_TOUCH: |
181 break; | 178 break; |
182 default: | 179 default: |
183 NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code; | 180 NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code; |
184 } | 181 } |
185 } else { | 182 } else { |
186 NOTIMPLEMENTED() << "invalid type: " << input.type; | 183 NOTIMPLEMENTED() << "invalid type: " << input.type; |
187 } | 184 } |
188 } | 185 } |
189 | 186 |
190 void TouchEventConverterEvdev::ProcessAbs(const input_event& input) { | 187 void TouchEventConverterEvdev::ProcessAbs(const input_event& input) { |
188 if (events_.size() <= current_slot_) | |
189 events_.resize(current_slot_ + 1); | |
191 switch (input.code) { | 190 switch (input.code) { |
192 case ABS_MT_TOUCH_MAJOR: | 191 case ABS_MT_TOUCH_MAJOR: |
193 altered_slots_.set(current_slot_); | |
194 // TODO(spang): If we have all of major, minor, and orientation, | 192 // TODO(spang): If we have all of major, minor, and orientation, |
195 // we can scale the ellipse correctly. However on the Pixel we get | 193 // we can scale the ellipse correctly. However on the Pixel we get |
196 // neither minor nor orientation, so this is all we can do. | 194 // neither minor nor orientation, so this is all we can do. |
197 events_[current_slot_].radius_x_ = input.value / 2.0f; | 195 events_[current_slot_].radius_x_ = input.value / 2.0f; |
198 break; | 196 break; |
199 case ABS_MT_TOUCH_MINOR: | 197 case ABS_MT_TOUCH_MINOR: |
200 altered_slots_.set(current_slot_); | |
201 events_[current_slot_].radius_y_ = input.value / 2.0f; | 198 events_[current_slot_].radius_y_ = input.value / 2.0f; |
202 break; | 199 break; |
203 case ABS_MT_POSITION_X: | 200 case ABS_MT_POSITION_X: |
204 altered_slots_.set(current_slot_); | |
205 events_[current_slot_].x_ = input.value; | 201 events_[current_slot_].x_ = input.value; |
206 break; | 202 break; |
207 case ABS_MT_POSITION_Y: | 203 case ABS_MT_POSITION_Y: |
208 altered_slots_.set(current_slot_); | |
209 events_[current_slot_].y_ = input.value; | 204 events_[current_slot_].y_ = input.value; |
210 break; | 205 break; |
211 case ABS_MT_TRACKING_ID: | 206 case ABS_MT_TRACKING_ID: |
212 altered_slots_.set(current_slot_); | |
213 if (input.value < 0) { | 207 if (input.value < 0) { |
214 events_[current_slot_].type_ = ET_TOUCH_RELEASED; | 208 events_[current_slot_].type_ = ET_TOUCH_RELEASED; |
215 } else { | 209 } else { |
216 events_[current_slot_].finger_ = input.value; | 210 events_[current_slot_].finger_ = input.value; |
217 events_[current_slot_].type_ = ET_TOUCH_PRESSED; | 211 events_[current_slot_].type_ = ET_TOUCH_PRESSED; |
218 } | 212 } |
219 break; | 213 break; |
220 case ABS_MT_PRESSURE: | 214 case ABS_MT_PRESSURE: |
221 altered_slots_.set(current_slot_); | |
222 events_[current_slot_].pressure_ = input.value - pressure_min_; | 215 events_[current_slot_].pressure_ = input.value - pressure_min_; |
223 events_[current_slot_].pressure_ /= pressure_max_ - pressure_min_; | 216 events_[current_slot_].pressure_ /= pressure_max_ - pressure_min_; |
224 break; | 217 break; |
225 case ABS_MT_SLOT: | 218 case ABS_MT_SLOT: |
226 if (input.value >= MAX_FINGERS) { | 219 if (input.value >= 0 && input.value < MAX_FINGERS) { |
227 LOG(ERROR) << "multi-touch slot " << input.value | 220 current_slot_ = input.value; |
228 << " exceeds MAX_FINGERS"; | 221 } else { |
229 break; | 222 LOG(ERROR) << "invalid touch event index: " << input.value; |
223 return; | |
230 } | 224 } |
231 current_slot_ = input.value; | |
232 altered_slots_.set(current_slot_); | |
233 break; | 225 break; |
234 default: | 226 default: |
235 DVLOG(5) << "unhandled code for EV_ABS: " << input.code; | 227 DVLOG(5) << "unhandled code for EV_ABS: " << input.code; |
228 return; | |
236 } | 229 } |
230 events_[current_slot_].altered_ = true; | |
spang
2015/02/02 22:09:42
ABS_VOLUME or something like that shouldn't genera
achaulk
2015/02/03 16:51:49
The default action returns early now
| |
237 } | 231 } |
238 | 232 |
239 void TouchEventConverterEvdev::ProcessSyn(const input_event& input) { | 233 void TouchEventConverterEvdev::ProcessSyn(const input_event& input) { |
240 switch (input.code) { | 234 switch (input.code) { |
241 case SYN_REPORT: | 235 case SYN_REPORT: |
242 if (syn_dropped_) { | 236 if (syn_dropped_) { |
243 // Have to re-initialize. | 237 // Have to re-initialize. |
244 if (Reinitialize()) { | 238 if (Reinitialize()) { |
245 syn_dropped_ = false; | 239 syn_dropped_ = false; |
246 altered_slots_.reset(); | 240 events_.clear(); |
247 } else { | 241 } else { |
248 LOG(ERROR) << "failed to re-initialize device info"; | 242 LOG(ERROR) << "failed to re-initialize device info"; |
249 } | 243 } |
250 } else { | 244 } else { |
251 ReportEvents(base::TimeDelta::FromMicroseconds( | 245 ReportEvents(base::TimeDelta::FromMicroseconds( |
252 input.time.tv_sec * 1000000 + input.time.tv_usec)); | 246 input.time.tv_sec * 1000000 + input.time.tv_usec)); |
253 } | 247 } |
254 if (is_type_a_) | 248 if (is_type_a_) |
255 current_slot_ = 0; | 249 current_slot_ = 0; |
256 break; | 250 break; |
257 case SYN_MT_REPORT: | 251 case SYN_MT_REPORT: |
258 // For type A devices, we just get a stream of all current contacts, | 252 // For type A devices, we just get a stream of all current contacts, |
259 // in some arbitrary order. | 253 // in some arbitrary order. |
254 if (events_.size() <= current_slot_ + 1) | |
255 events_.resize(current_slot_ + 2); | |
260 events_[current_slot_++].type_ = ET_TOUCH_PRESSED; | 256 events_[current_slot_++].type_ = ET_TOUCH_PRESSED; |
261 is_type_a_ = true; | 257 is_type_a_ = true; |
262 break; | 258 break; |
263 case SYN_DROPPED: | 259 case SYN_DROPPED: |
264 // Some buffer has overrun. We ignore all events up to and | 260 // Some buffer has overrun. We ignore all events up to and |
265 // including the next SYN_REPORT. | 261 // including the next SYN_REPORT. |
266 syn_dropped_ = true; | 262 syn_dropped_ = true; |
267 break; | 263 break; |
268 default: | 264 default: |
269 NOTIMPLEMENTED() << "invalid code for EV_SYN: " << input.code; | 265 NOTIMPLEMENTED() << "invalid code for EV_SYN: " << input.code; |
270 } | 266 } |
271 } | 267 } |
272 | 268 |
273 void TouchEventConverterEvdev::ReportEvent(int touch_id, | 269 void TouchEventConverterEvdev::ReportEvent(int touch_id, |
274 const InProgressEvents& event, | 270 const InProgressEvents& event, |
275 const base::TimeDelta& timestamp) { | 271 const base::TimeDelta& timestamp) { |
276 dispatcher_->DispatchTouchEvent(TouchEventParams( | 272 dispatcher_->DispatchTouchEvent(TouchEventParams( |
277 id_, touch_id, event.type_, gfx::PointF(event.x_, event.y_), | 273 id_, touch_id, event.type_, gfx::PointF(event.x_, event.y_), |
278 gfx::Vector2dF(event.radius_x_, event.radius_y_), event.pressure_, | 274 gfx::Vector2dF(event.radius_x_, event.radius_y_), event.pressure_, |
279 timestamp)); | 275 timestamp)); |
280 } | 276 } |
281 | 277 |
282 void TouchEventConverterEvdev::ReportEvents(base::TimeDelta delta) { | 278 void TouchEventConverterEvdev::ReportEvents(base::TimeDelta delta) { |
283 for (int i = 0; i < MAX_FINGERS; i++) { | 279 for (size_t i = 0; i < events_.size(); i++) { |
284 if (altered_slots_[i]) { | 280 if (events_[i].altered_) { |
285 ReportEvent(i, events_[i], delta); | 281 ReportEvent(i, events_[i], delta); |
286 | 282 |
287 // Subsequent events for this finger will be touch-move until it | 283 // Subsequent events for this finger will be touch-move until it |
288 // is released. | 284 // is released. |
289 events_[i].type_ = ET_TOUCH_MOVED; | 285 events_[i].type_ = ET_TOUCH_MOVED; |
286 events_[i].altered_ = false; | |
290 } | 287 } |
291 } | 288 } |
292 altered_slots_.reset(); | |
293 } | 289 } |
294 | 290 |
295 } // namespace ui | 291 } // namespace ui |
OLD | NEW |