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

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

Issue 2248933002: Support pen in TouchEventConverterEvdev (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: nit Created 4 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 unified diff | Download patch
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/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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 return ABS_MT_POSITION_Y; 71 return ABS_MT_POSITION_Y;
72 case ABS_PRESSURE: 72 case ABS_PRESSURE:
73 return ABS_MT_PRESSURE; 73 return ABS_MT_PRESSURE;
74 case ABS_DISTANCE: 74 case ABS_DISTANCE:
75 return ABS_MT_DISTANCE; 75 return ABS_MT_DISTANCE;
76 default: 76 default:
77 return -1; 77 return -1;
78 } 78 }
79 } 79 }
80 80
81 ui::EventPointerType GetPointerTypeFromEvent( 81 ui::PointerDetails GetEventPointerDetails(
82 const ui::InProgressTouchEvdev& event) { 82 const ui::InProgressTouchEvdev& event) {
83 return (event.tool_code == BTN_TOOL_PEN) 83 ui::EventPointerType type;
84 ? ui::EventPointerType::POINTER_TYPE_PEN 84 switch (event.tool_code) {
85 : ui::EventPointerType::POINTER_TYPE_TOUCH; 85 case BTN_TOOL_PEN:
86 type = ui::EventPointerType::POINTER_TYPE_PEN;
87 break;
88 default:
89 type = ui::EventPointerType::POINTER_TYPE_TOUCH;
90 }
91 return ui::PointerDetails(type, event.radius_x, event.radius_y,
92 event.pressure,
93 /* tilt_x */ 0.0f,
94 /* tilt_y */ 0.0f);
86 } 95 }
87 96
88 const int kTrackingIdForUnusedSlot = -1; 97 const int kTrackingIdForUnusedSlot = -1;
89 98
90 } // namespace 99 } // namespace
91 100
92 namespace ui { 101 namespace ui {
93 102
94 TouchEventConverterEvdev::TouchEventConverterEvdev( 103 TouchEventConverterEvdev::TouchEventConverterEvdev(
95 int fd, 104 int fd,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 x_num_tuxels_ -= cal.bezel_left + cal.bezel_right; 159 x_num_tuxels_ -= cal.bezel_left + cal.bezel_right;
151 y_min_tuxels_ += cal.bezel_top; 160 y_min_tuxels_ += cal.bezel_top;
152 y_num_tuxels_ -= cal.bezel_top + cal.bezel_bottom; 161 y_num_tuxels_ -= cal.bezel_top + cal.bezel_bottom;
153 162
154 VLOG(1) << "applying touch calibration: " 163 VLOG(1) << "applying touch calibration: "
155 << base::StringPrintf("[%d, %d, %d, %d]", cal.bezel_left, 164 << base::StringPrintf("[%d, %d, %d, %d]", cal.bezel_left,
156 cal.bezel_right, cal.bezel_top, 165 cal.bezel_right, cal.bezel_top,
157 cal.bezel_bottom); 166 cal.bezel_bottom);
158 } 167 }
159 168
169 // TODO(denniskempin): Use EVIOCGKEY to synchronize key state.
170
160 events_.resize(touch_points_); 171 events_.resize(touch_points_);
161 172
162 if (has_mt_) { 173 if (has_mt_) {
163 for (size_t i = 0; i < events_.size(); ++i) { 174 for (size_t i = 0; i < events_.size(); ++i) {
164 events_[i].x = info.GetAbsMtSlotValueWithDefault(ABS_MT_POSITION_X, i, 0); 175 events_[i].x = info.GetAbsMtSlotValueWithDefault(ABS_MT_POSITION_X, i, 0);
165 events_[i].y = info.GetAbsMtSlotValueWithDefault(ABS_MT_POSITION_Y, i, 0); 176 events_[i].y = info.GetAbsMtSlotValueWithDefault(ABS_MT_POSITION_Y, i, 0);
166 events_[i].tracking_id = info.GetAbsMtSlotValueWithDefault( 177 events_[i].tracking_id = info.GetAbsMtSlotValueWithDefault(
167 ABS_MT_TRACKING_ID, i, kTrackingIdForUnusedSlot); 178 ABS_MT_TRACKING_ID, i, kTrackingIdForUnusedSlot);
168 events_[i].touching = (events_[i].tracking_id >= 0); 179 events_[i].touching = (events_[i].tracking_id >= 0);
169 events_[i].slot = i; 180 events_[i].slot = i;
(...skipping 20 matching lines...) Expand all
190 events_[0].touching = false; 201 events_[0].touching = false;
191 events_[0].slot = 0; 202 events_[0].slot = 0;
192 events_[0].radius_x = 0; 203 events_[0].radius_x = 0;
193 events_[0].radius_y = 0; 204 events_[0].radius_y = 0;
194 events_[0].pressure = 0; 205 events_[0].pressure = 0;
195 events_[0].tool_code = 0; 206 events_[0].tool_code = 0;
196 } 207 }
197 } 208 }
198 209
199 void TouchEventConverterEvdev::Reinitialize() { 210 void TouchEventConverterEvdev::Reinitialize() {
211 ReleaseButtons();
212
200 EventDeviceInfo info; 213 EventDeviceInfo info;
201 if (!info.Initialize(fd_, path_)) { 214 if (!info.Initialize(fd_, path_)) {
202 LOG(ERROR) << "Failed to synchronize state for touch device: " 215 LOG(ERROR) << "Failed to synchronize state for touch device: "
203 << path_.value(); 216 << path_.value();
204 Stop(); 217 Stop();
205 return; 218 return;
206 } 219 }
207
208 Initialize(info); 220 Initialize(info);
209 } 221 }
210 222
211 bool TouchEventConverterEvdev::HasTouchscreen() const { 223 bool TouchEventConverterEvdev::HasTouchscreen() const {
212 return true; 224 return true;
213 } 225 }
214 226
215 gfx::Size TouchEventConverterEvdev::GetTouchscreenSize() const { 227 gfx::Size TouchEventConverterEvdev::GetTouchscreenSize() const {
216 return gfx::Size(x_num_tuxels_, y_num_tuxels_); 228 return gfx::Size(x_num_tuxels_, y_num_tuxels_);
217 } 229 }
218 230
219 int TouchEventConverterEvdev::GetTouchPoints() const { 231 int TouchEventConverterEvdev::GetTouchPoints() const {
220 return touch_points_; 232 return touch_points_;
221 } 233 }
222 234
223 void TouchEventConverterEvdev::OnEnabled() { 235 void TouchEventConverterEvdev::OnEnabled() {
224 ReportEvents(EventTimeForNow()); 236 ReportEvents(EventTimeForNow());
225 } 237 }
226 238
227 void TouchEventConverterEvdev::OnDisabled() { 239 void TouchEventConverterEvdev::OnDisabled() {
228 ReleaseTouches(); 240 ReleaseTouches();
241 ReleaseButtons();
229 } 242 }
230 243
231 void TouchEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) { 244 void TouchEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
232 TRACE_EVENT1("evdev", 245 TRACE_EVENT1("evdev",
233 "TouchEventConverterEvdev::OnFileCanReadWithoutBlocking", "fd", 246 "TouchEventConverterEvdev::OnFileCanReadWithoutBlocking", "fd",
234 fd); 247 fd);
235 248
236 input_event inputs[kNumTouchEvdevSlots * 6 + 1]; 249 input_event inputs[kNumTouchEvdevSlots * 6 + 1];
237 ssize_t read_size = read(fd, inputs, sizeof(inputs)); 250 ssize_t read_size = read(fd, inputs, sizeof(inputs));
238 if (read_size < 0) { 251 if (read_size < 0) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 event.value ? NextTrackingId() : kTrackingIdForUnusedSlot; 323 event.value ? NextTrackingId() : kTrackingIdForUnusedSlot;
311 ProcessMultitouchEvent(emulated_event); 324 ProcessMultitouchEvent(emulated_event);
312 } 325 }
313 } 326 }
314 } 327 }
315 328
316 void TouchEventConverterEvdev::ProcessKey(const input_event& input) { 329 void TouchEventConverterEvdev::ProcessKey(const input_event& input) {
317 switch (input.code) { 330 switch (input.code) {
318 case BTN_TOUCH: 331 case BTN_TOUCH:
319 case BTN_LEFT: 332 case BTN_LEFT:
333 events_[current_slot_].btn_left.down = input.value;
334 events_[current_slot_].btn_left.changed = true;
335 break;
336 case BTN_STYLUS:
337 events_[current_slot_].btn_right.down = input.value;
338 events_[current_slot_].btn_right.changed = true;
339 break;
340 case BTN_STYLUS2:
341 events_[current_slot_].btn_middle.down = input.value;
342 events_[current_slot_].btn_middle.changed = true;
320 break; 343 break;
321 case BTN_TOOL_PEN: 344 case BTN_TOOL_PEN:
345 // Do not change tool types while touching to prevent inconsistencies
346 // from switching between Mouse and TouchEvents.
347 if (events_[current_slot_].was_touching)
348 break;
349
322 if (input.value > 0) { 350 if (input.value > 0) {
323 events_[current_slot_].tool_code = input.code; 351 events_[current_slot_].tool_code = input.code;
324 } else { 352 } else {
325 events_[current_slot_].tool_code = 0; 353 events_[current_slot_].tool_code = 0;
326 } 354 }
327 break; 355 break;
328 default: 356 default:
329 NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code; 357 NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code;
330 } 358 }
331 } 359 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 if (touch.touching && !touch.was_touching) 421 if (touch.touching && !touch.was_touching)
394 return ET_UNKNOWN; 422 return ET_UNKNOWN;
395 return ET_TOUCH_CANCELLED; 423 return ET_TOUCH_CANCELLED;
396 } 424 }
397 425
398 if (touch.touching) 426 if (touch.touching)
399 return touch.was_touching ? ET_TOUCH_MOVED : ET_TOUCH_PRESSED; 427 return touch.was_touching ? ET_TOUCH_MOVED : ET_TOUCH_PRESSED;
400 return touch.was_touching ? ET_TOUCH_RELEASED : ET_UNKNOWN; 428 return touch.was_touching ? ET_TOUCH_RELEASED : ET_UNKNOWN;
401 } 429 }
402 430
403 void TouchEventConverterEvdev::ReportEvent(const InProgressTouchEvdev& event, 431 void TouchEventConverterEvdev::ReportTouchEvent(
404 EventType event_type, 432 const InProgressTouchEvdev& event,
405 base::TimeTicks timestamp) { 433 EventType event_type,
406 PointerDetails details(GetPointerTypeFromEvent(event), event.radius_x, 434 base::TimeTicks timestamp) {
407 event.radius_y, event.pressure, 435 dispatcher_->DispatchTouchEvent(TouchEventParams(
408 /* tilt_x */ 0.0f, 436 input_device_.id, event.slot, event_type, gfx::PointF(event.x, event.y),
409 /* tilt_y */ 0.0f); 437 GetEventPointerDetails(event), timestamp));
410 dispatcher_->DispatchTouchEvent( 438 }
411 TouchEventParams(input_device_.id, event.slot, event_type, 439
412 gfx::PointF(event.x, event.y), details, timestamp)); 440 void TouchEventConverterEvdev::ReportStylusEvent(
441 const InProgressTouchEvdev& event,
442 base::TimeTicks timestamp) {
443 if (event.btn_left.changed)
444 ReportButton(BTN_LEFT, event.btn_left.down, event, timestamp);
445 if (event.btn_right.changed)
446 ReportButton(BTN_RIGHT, event.btn_right.down, event, timestamp);
447 if (event.btn_middle.changed)
448 ReportButton(BTN_MIDDLE, event.btn_middle.down, event, timestamp);
449
450 dispatcher_->DispatchMouseMoveEvent(MouseMoveEventParams(
451 input_device_.id, EF_DIRECT_INPUT, gfx::PointF(event.x, event.y),
452 GetEventPointerDetails(event), timestamp));
453 }
454
455 void TouchEventConverterEvdev::ReportButton(unsigned int button,
456 bool down,
457 const InProgressTouchEvdev& event,
458 base::TimeTicks timestamp) {
459 dispatcher_->DispatchMouseButtonEvent(MouseButtonEventParams(
460 input_device_.id, EF_DIRECT_INPUT, gfx::PointF(event.x, event.y), button,
461 down, false /* allow_remap */, GetEventPointerDetails(event), timestamp));
413 } 462 }
414 463
415 void TouchEventConverterEvdev::ReportEvents(base::TimeTicks timestamp) { 464 void TouchEventConverterEvdev::ReportEvents(base::TimeTicks timestamp) {
416 if (dropped_events_) { 465 if (dropped_events_) {
417 Reinitialize(); 466 Reinitialize();
418 dropped_events_ = false; 467 dropped_events_ = false;
419 } 468 }
420 469
421 if (touch_noise_finder_) 470 if (touch_noise_finder_)
422 touch_noise_finder_->HandleTouches(events_, timestamp); 471 touch_noise_finder_->HandleTouches(events_, timestamp);
423 472
424 for (size_t i = 0; i < events_.size(); i++) { 473 for (size_t i = 0; i < events_.size(); i++) {
425 InProgressTouchEvdev* event = &events_[i]; 474 InProgressTouchEvdev* event = &events_[i];
426 if (!event->altered) 475 if (!event->altered)
427 continue; 476 continue;
428 477
429 EventType event_type = GetEventTypeForTouch(*event); 478 if (event->tool_code > 0) {
430 if (event_type == ET_UNKNOWN || event_type == ET_TOUCH_CANCELLED) 479 ReportStylusEvent(*event, timestamp);
431 event->cancelled = true; 480 } else {
481 EventType event_type = GetEventTypeForTouch(*event);
482 if (event_type == ET_UNKNOWN || event_type == ET_TOUCH_CANCELLED)
483 event->cancelled = true;
432 484
433 if (event_type != ET_UNKNOWN) 485 if (event_type != ET_UNKNOWN)
434 ReportEvent(*event, event_type, timestamp); 486 ReportTouchEvent(*event, event_type, timestamp);
487 }
435 488
436 event->was_touching = event->touching; 489 event->was_touching = event->touching;
437 event->altered = false; 490 event->altered = false;
491 event->btn_left.changed = false;
492 event->btn_right.changed = false;
493 event->btn_middle.changed = false;
438 } 494 }
439 } 495 }
440 496
441 void TouchEventConverterEvdev::UpdateTrackingId(int slot, int tracking_id) { 497 void TouchEventConverterEvdev::UpdateTrackingId(int slot, int tracking_id) {
442 InProgressTouchEvdev* event = &events_[slot]; 498 InProgressTouchEvdev* event = &events_[slot];
443 499
444 if (event->tracking_id == tracking_id) 500 if (event->tracking_id == tracking_id)
445 return; 501 return;
446 502
447 event->tracking_id = tracking_id; 503 event->tracking_id = tracking_id;
448 event->touching = (tracking_id >= 0); 504 event->touching = (tracking_id >= 0);
449 event->altered = true; 505 event->altered = true;
450 506
451 if (tracking_id >= 0) 507 if (tracking_id >= 0)
452 event->cancelled = false; 508 event->cancelled = false;
453 } 509 }
454 510
455 void TouchEventConverterEvdev::ReleaseTouches() { 511 void TouchEventConverterEvdev::ReleaseTouches() {
456 for (size_t slot = 0; slot < events_.size(); slot++) 512 for (size_t slot = 0; slot < events_.size(); slot++)
457 UpdateTrackingId(slot, kTrackingIdForUnusedSlot); 513 UpdateTrackingId(slot, kTrackingIdForUnusedSlot);
458 514
459 ReportEvents(EventTimeForNow()); 515 ReportEvents(EventTimeForNow());
460 } 516 }
461 517
518 void TouchEventConverterEvdev::ReleaseButtons() {
519 for (size_t slot = 0; slot < events_.size(); slot++) {
520 InProgressTouchEvdev* event = &events_[slot];
521
522 if (event->btn_left.down) {
523 event->btn_left.down = false;
524 event->btn_left.changed = true;
525 }
526 if (event->btn_right.down) {
527 event->btn_right.down = false;
528 event->btn_right.changed = true;
529 }
530 if (event->btn_middle.down) {
531 event->btn_middle.down = false;
532 event->btn_middle.changed = true;
533 }
534 }
535
536 ReportEvents(EventTimeForNow());
537 }
538
462 float TouchEventConverterEvdev::ScalePressure(int32_t value) { 539 float TouchEventConverterEvdev::ScalePressure(int32_t value) {
463 float pressure = value - pressure_min_; 540 float pressure = value - pressure_min_;
464 if (pressure_max_ - pressure_min_) 541 if (pressure_max_ - pressure_min_)
465 pressure /= pressure_max_ - pressure_min_; 542 pressure /= pressure_max_ - pressure_min_;
466 return pressure; 543 return pressure;
467 } 544 }
468 545
469 int TouchEventConverterEvdev::NextTrackingId() { 546 int TouchEventConverterEvdev::NextTrackingId() {
470 return next_tracking_id_++ & kMaxTrackingId; 547 return next_tracking_id_++ & kMaxTrackingId;
471 } 548 }
472 549
473 } // namespace ui 550 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698