| 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 | 161 |
| 162 VLOG(1) << "applying touch calibration: " | 162 VLOG(1) << "applying touch calibration: " |
| 163 << base::StringPrintf("[%d, %d, %d, %d]", cal.bezel_left, | 163 << base::StringPrintf("[%d, %d, %d, %d]", cal.bezel_left, |
| 164 cal.bezel_right, cal.bezel_top, | 164 cal.bezel_right, cal.bezel_top, |
| 165 cal.bezel_bottom); | 165 cal.bezel_bottom); |
| 166 } | 166 } |
| 167 | 167 |
| 168 // TODO(denniskempin): Use EVIOCGKEY to synchronize key state. | 168 // TODO(denniskempin): Use EVIOCGKEY to synchronize key state. |
| 169 | 169 |
| 170 events_.resize(touch_points_); | 170 events_.resize(touch_points_); |
| 171 | 171 bool cancelled_state = false; |
| 172 if (has_mt_) { | 172 if (has_mt_) { |
| 173 for (size_t i = 0; i < events_.size(); ++i) { | 173 for (size_t i = 0; i < events_.size(); ++i) { |
| 174 events_[i].x = info.GetAbsMtSlotValueWithDefault(ABS_MT_POSITION_X, i, 0); | 174 events_[i].x = info.GetAbsMtSlotValueWithDefault(ABS_MT_POSITION_X, i, 0); |
| 175 events_[i].y = info.GetAbsMtSlotValueWithDefault(ABS_MT_POSITION_Y, i, 0); | 175 events_[i].y = info.GetAbsMtSlotValueWithDefault(ABS_MT_POSITION_Y, i, 0); |
| 176 events_[i].tracking_id = info.GetAbsMtSlotValueWithDefault( | 176 events_[i].tracking_id = info.GetAbsMtSlotValueWithDefault( |
| 177 ABS_MT_TRACKING_ID, i, kTrackingIdForUnusedSlot); | 177 ABS_MT_TRACKING_ID, i, kTrackingIdForUnusedSlot); |
| 178 events_[i].touching = (events_[i].tracking_id >= 0); | 178 events_[i].touching = (events_[i].tracking_id >= 0); |
| 179 events_[i].slot = i; | 179 events_[i].slot = i; |
| 180 | 180 |
| 181 // Dirty the slot so we'll update the consumer at the first opportunity. | 181 // Dirty the slot so we'll update the consumer at the first opportunity. |
| 182 events_[i].altered = true; | 182 events_[i].altered = true; |
| 183 | 183 |
| 184 // Optional bits. | 184 // Optional bits. |
| 185 int touch_major = | 185 int touch_major = |
| 186 info.GetAbsMtSlotValueWithDefault(ABS_MT_TOUCH_MAJOR, i, 0); | 186 info.GetAbsMtSlotValueWithDefault(ABS_MT_TOUCH_MAJOR, i, 0); |
| 187 events_[i].radius_x = touch_major / 2.0f; | 187 events_[i].radius_x = touch_major / 2.0f; |
| 188 events_[i].radius_y = | 188 events_[i].radius_y = |
| 189 info.GetAbsMtSlotValueWithDefault(ABS_MT_TOUCH_MINOR, i, 0) / 2.0f; | 189 info.GetAbsMtSlotValueWithDefault(ABS_MT_TOUCH_MINOR, i, 0) / 2.0f; |
| 190 events_[i].pressure = ScalePressure( | 190 events_[i].pressure = ScalePressure( |
| 191 info.GetAbsMtSlotValueWithDefault(ABS_MT_PRESSURE, i, 0)); | 191 info.GetAbsMtSlotValueWithDefault(ABS_MT_PRESSURE, i, 0)); |
| 192 events_[i].cancelled = (major_max_ > 0 && touch_major == major_max_); | 192 events_[i].cancelled = major_max_ > 0 && touch_major == major_max_; |
| 193 if (events_[i].cancelled) |
| 194 cancelled_state = true; |
| 193 } | 195 } |
| 194 } else { | 196 } else { |
| 195 // TODO(spang): Add key state to EventDeviceInfo to allow initial contact. | 197 // TODO(spang): Add key state to EventDeviceInfo to allow initial contact. |
| 196 // (and make sure to take into account quirk_left_mouse_button_) | 198 // (and make sure to take into account quirk_left_mouse_button_) |
| 197 events_[0].x = 0; | 199 events_[0].x = 0; |
| 198 events_[0].y = 0; | 200 events_[0].y = 0; |
| 199 events_[0].tracking_id = kTrackingIdForUnusedSlot; | 201 events_[0].tracking_id = kTrackingIdForUnusedSlot; |
| 200 events_[0].touching = false; | 202 events_[0].touching = false; |
| 201 events_[0].slot = 0; | 203 events_[0].slot = 0; |
| 202 events_[0].radius_x = 0; | 204 events_[0].radius_x = 0; |
| 203 events_[0].radius_y = 0; | 205 events_[0].radius_y = 0; |
| 204 events_[0].pressure = 0; | 206 events_[0].pressure = 0; |
| 205 events_[0].tool_code = 0; | 207 events_[0].tool_code = 0; |
| 206 events_[0].cancelled = false; | 208 events_[0].cancelled = false; |
| 207 } | 209 } |
| 210 if (cancelled_state) |
| 211 CancelAllTouches(); |
| 208 } | 212 } |
| 209 | 213 |
| 210 void TouchEventConverterEvdev::Reinitialize() { | 214 void TouchEventConverterEvdev::Reinitialize() { |
| 211 ReleaseButtons(); | 215 ReleaseButtons(); |
| 212 | 216 |
| 213 EventDeviceInfo info; | 217 EventDeviceInfo info; |
| 214 if (!info.Initialize(fd_, path_)) { | 218 if (!info.Initialize(fd_, path_)) { |
| 215 LOG(ERROR) << "Failed to synchronize state for touch device: " | 219 LOG(ERROR) << "Failed to synchronize state for touch device: " |
| 216 << path_.value(); | 220 << path_.value(); |
| 217 Stop(); | 221 Stop(); |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 EventType event_type, | 443 EventType event_type, |
| 440 base::TimeTicks timestamp) { | 444 base::TimeTicks timestamp) { |
| 441 ui::PointerDetails details(event.reported_tool_type, event.radius_x, | 445 ui::PointerDetails details(event.reported_tool_type, event.radius_x, |
| 442 event.radius_y, event.pressure, | 446 event.radius_y, event.pressure, |
| 443 /* tilt_x */ 0.0f, /* tilt_y */ 0.0f); | 447 /* tilt_x */ 0.0f, /* tilt_y */ 0.0f); |
| 444 dispatcher_->DispatchTouchEvent( | 448 dispatcher_->DispatchTouchEvent( |
| 445 TouchEventParams(input_device_.id, event.slot, event_type, | 449 TouchEventParams(input_device_.id, event.slot, event_type, |
| 446 gfx::PointF(event.x, event.y), details, timestamp)); | 450 gfx::PointF(event.x, event.y), details, timestamp)); |
| 447 } | 451 } |
| 448 | 452 |
| 453 void TouchEventConverterEvdev::CancelAllTouches() { |
| 454 // TODO(denniskempin): Remove once upper layers properly handle single |
| 455 // cancelled touches. |
| 456 for (size_t i = 0; i < events_.size(); i++) { |
| 457 InProgressTouchEvdev* event = &events_[i]; |
| 458 if (event->was_touching || event->touching) { |
| 459 event->cancelled = true; |
| 460 event->altered = true; |
| 461 } |
| 462 } |
| 463 } |
| 464 |
| 449 void TouchEventConverterEvdev::ReportEvents(base::TimeTicks timestamp) { | 465 void TouchEventConverterEvdev::ReportEvents(base::TimeTicks timestamp) { |
| 450 if (dropped_events_) { | 466 if (dropped_events_) { |
| 451 Reinitialize(); | 467 Reinitialize(); |
| 452 dropped_events_ = false; | 468 dropped_events_ = false; |
| 453 } | 469 } |
| 454 | 470 |
| 455 if (touch_noise_finder_) | 471 if (touch_noise_finder_) |
| 456 touch_noise_finder_->HandleTouches(events_, timestamp); | 472 touch_noise_finder_->HandleTouches(events_, timestamp); |
| 457 | 473 |
| 458 for (size_t i = 0; i < events_.size(); i++) { | 474 for (size_t i = 0; i < events_.size(); i++) { |
| 459 InProgressTouchEvdev* event = &events_[i]; | 475 InProgressTouchEvdev* event = &events_[i]; |
| 476 if (event->altered && (event->cancelled || |
| 477 (touch_noise_finder_ && |
| 478 touch_noise_finder_->SlotHasNoise(event->slot)))) { |
| 479 CancelAllTouches(); |
| 480 break; |
| 481 } |
| 482 } |
| 483 |
| 484 for (size_t i = 0; i < events_.size(); i++) { |
| 485 InProgressTouchEvdev* event = &events_[i]; |
| 460 if (!event->altered) | 486 if (!event->altered) |
| 461 continue; | 487 continue; |
| 462 | 488 |
| 463 if (enable_palm_suppression_callback_) | 489 if (enable_palm_suppression_callback_) |
| 464 enable_palm_suppression_callback_.Run(event->tool_code > 0); | 490 enable_palm_suppression_callback_.Run(event->tool_code > 0); |
| 465 | 491 |
| 466 if (touch_noise_finder_ && touch_noise_finder_->SlotHasNoise(event->slot)) | |
| 467 event->cancelled = true; | |
| 468 | |
| 469 EventType event_type = GetEventTypeForTouch(*event); | 492 EventType event_type = GetEventTypeForTouch(*event); |
| 470 // The tool type is fixed with the touch pressed event and does not change. | 493 // The tool type is fixed with the touch pressed event and does not change. |
| 471 if (event_type == ET_TOUCH_PRESSED) | 494 if (event_type == ET_TOUCH_PRESSED) |
| 472 event->reported_tool_type = GetEventPointerType(event->tool_code); | 495 event->reported_tool_type = GetEventPointerType(event->tool_code); |
| 473 if (event_type != ET_UNKNOWN) | 496 if (event_type != ET_UNKNOWN) |
| 474 ReportTouchEvent(*event, event_type, timestamp); | 497 ReportTouchEvent(*event, event_type, timestamp); |
| 475 | 498 |
| 476 event->was_cancelled = event->cancelled; | 499 event->was_cancelled = event->cancelled; |
| 477 event->was_touching = event->touching; | 500 event->was_touching = event->touching; |
| 478 event->altered = false; | 501 event->altered = false; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 if (pressure_max_ - pressure_min_) | 556 if (pressure_max_ - pressure_min_) |
| 534 pressure /= pressure_max_ - pressure_min_; | 557 pressure /= pressure_max_ - pressure_min_; |
| 535 return pressure; | 558 return pressure; |
| 536 } | 559 } |
| 537 | 560 |
| 538 int TouchEventConverterEvdev::NextTrackingId() { | 561 int TouchEventConverterEvdev::NextTrackingId() { |
| 539 return next_tracking_id_++ & kMaxTrackingId; | 562 return next_tracking_id_++ & kMaxTrackingId; |
| 540 } | 563 } |
| 541 | 564 |
| 542 } // namespace ui | 565 } // namespace ui |
| OLD | NEW |