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