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

Side by Side Diff: ui/events/devices/x11/device_data_manager_x11.cc

Issue 688253002: Implemented smooth scrolling using xinput2 in X11. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Disabled coalescing for all scroll events Created 5 years 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/devices/x11/device_data_manager_x11.h" 5 #include "ui/events/devices/x11/device_data_manager_x11.h"
6 6
7 #include <X11/extensions/XInput.h> 7 #include <X11/extensions/XInput.h>
8 #include <X11/extensions/XInput2.h> 8 #include <X11/extensions/XInput2.h>
9 #include <X11/Xlib.h> 9 #include <X11/Xlib.h>
10 10
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 return true; 208 return true;
209 } 209 }
210 210
211 bool DeviceDataManagerX11::IsXInput2Available() const { 211 bool DeviceDataManagerX11::IsXInput2Available() const {
212 return xi_opcode_ != -1; 212 return xi_opcode_ != -1;
213 } 213 }
214 214
215 void DeviceDataManagerX11::UpdateDeviceList(Display* display) { 215 void DeviceDataManagerX11::UpdateDeviceList(Display* display) {
216 cmt_devices_.reset(); 216 cmt_devices_.reset();
217 touchpads_.reset(); 217 touchpads_.reset();
218 scrollclass_devices_.reset();
218 master_pointers_.clear(); 219 master_pointers_.clear();
219 for (int i = 0; i < kMaxDeviceNum; ++i) { 220 for (int i = 0; i < kMaxDeviceNum; ++i) {
220 valuator_count_[i] = 0; 221 valuator_count_[i] = 0;
221 valuator_lookup_[i].clear(); 222 valuator_lookup_[i].clear();
222 data_type_lookup_[i].clear(); 223 data_type_lookup_[i].clear();
223 valuator_min_[i].clear(); 224 valuator_min_[i].clear();
224 valuator_max_[i].clear(); 225 valuator_max_[i].clear();
226 scroll_data_[i].horizontal.number = -1;
227 scroll_data_[i].vertical.number = -1;
225 for (int j = 0; j < kMaxSlotNum; j++) 228 for (int j = 0; j < kMaxSlotNum; j++)
226 last_seen_valuator_[i][j].clear(); 229 last_seen_valuator_[i][j].clear();
227 } 230 }
228 231
229 // Find all the touchpad devices. 232 // Find all the touchpad devices.
230 const XDeviceList& dev_list = 233 const XDeviceList& dev_list =
231 ui::DeviceListCacheX11::GetInstance()->GetXDeviceList(display); 234 ui::DeviceListCacheX11::GetInstance()->GetXDeviceList(display);
232 Atom xi_touchpad = XInternAtom(display, XI_TOUCHPAD, false); 235 Atom xi_touchpad = XInternAtom(display, XI_TOUCHPAD, false);
233 for (int i = 0; i < dev_list.count; ++i) 236 for (int i = 0; i < dev_list.count; ++i)
234 if (dev_list[i].type == xi_touchpad) 237 if (dev_list[i].type == xi_touchpad)
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 continue; 273 continue;
271 274
272 valuator_lookup_[deviceid].resize(DT_LAST_ENTRY, -1); 275 valuator_lookup_[deviceid].resize(DT_LAST_ENTRY, -1);
273 data_type_lookup_[deviceid].resize( 276 data_type_lookup_[deviceid].resize(
274 valuator_count_[deviceid], DT_LAST_ENTRY); 277 valuator_count_[deviceid], DT_LAST_ENTRY);
275 valuator_min_[deviceid].resize(DT_LAST_ENTRY, 0); 278 valuator_min_[deviceid].resize(DT_LAST_ENTRY, 0);
276 valuator_max_[deviceid].resize(DT_LAST_ENTRY, 0); 279 valuator_max_[deviceid].resize(DT_LAST_ENTRY, 0);
277 for (int j = 0; j < kMaxSlotNum; j++) 280 for (int j = 0; j < kMaxSlotNum; j++)
278 last_seen_valuator_[deviceid][j].resize(DT_LAST_ENTRY, 0); 281 last_seen_valuator_[deviceid][j].resize(DT_LAST_ENTRY, 0);
279 for (int j = 0; j < info.num_classes; ++j) { 282 for (int j = 0; j < info.num_classes; ++j) {
280 if (info.classes[j]->type != XIValuatorClass) 283 if (info.classes[j]->type == XIValuatorClass) {
281 continue; 284 if (UpdateValuatorClassDevice(
282 285 reinterpret_cast<XIValuatorClassInfo*>(info.classes[j]), atoms,
283 XIValuatorClassInfo* v = 286 deviceid))
284 reinterpret_cast<XIValuatorClassInfo*>(info.classes[j]); 287 possible_cmt = true;
285 for (int data_type = 0; data_type < DT_LAST_ENTRY; ++data_type) { 288 } else if (info.classes[j]->type == XIScrollClass) {
286 if (v->label == atoms[data_type]) { 289 UpdateScrollClassDevice(
287 valuator_lookup_[deviceid][data_type] = v->number; 290 reinterpret_cast<XIScrollClassInfo*>(info.classes[j]), deviceid);
288 data_type_lookup_[deviceid][v->number] = data_type;
289 valuator_min_[deviceid][data_type] = v->min;
290 valuator_max_[deviceid][data_type] = v->max;
291 if (IsCMTDataType(data_type))
292 possible_cmt = true;
293 break;
294 }
295 } 291 }
296 } 292 }
297 293
298 if (possible_cmt && !not_cmt) 294 if (possible_cmt && !not_cmt)
299 cmt_devices_[deviceid] = true; 295 cmt_devices_[deviceid] = true;
300 } 296 }
301 } 297 }
302 298
299 bool DeviceDataManagerX11::UpdateValuatorClassDevice(
300 XIValuatorClassInfo* valuator_class_info,
301 Atom* atoms,
302 int deviceid) {
303 DCHECK(deviceid >= 0 && deviceid < kMaxDeviceNum);
304 for (int data_type = 0; data_type < DT_LAST_ENTRY; ++data_type) {
305 if (valuator_class_info->label == atoms[data_type]) {
306 valuator_lookup_[deviceid][data_type] = valuator_class_info->number;
307 data_type_lookup_[deviceid][valuator_class_info->number] = data_type;
308 valuator_min_[deviceid][data_type] = valuator_class_info->min;
309 valuator_max_[deviceid][data_type] = valuator_class_info->max;
310 if (IsCMTDataType(data_type))
311 return true;
312 }
313 }
314 return false;
315 }
316
317 void DeviceDataManagerX11::UpdateScrollClassDevice(
318 XIScrollClassInfo* scroll_class_info,
319 int deviceid) {
320 DCHECK(deviceid >= 0 && deviceid < kMaxDeviceNum);
321 ScrollInfo& info = scroll_data_[deviceid];
322 switch (scroll_class_info->scroll_type) {
323 case XIScrollTypeVertical:
324 info.vertical.number = scroll_class_info->number;
325 info.vertical.increment = scroll_class_info->increment;
326 info.vertical.position = 0;
327 info.vertical.seen = false;
328 break;
329 case XIScrollTypeHorizontal:
330 info.horizontal.number = scroll_class_info->number;
331 info.horizontal.increment = scroll_class_info->increment;
332 info.horizontal.position = 0;
333 info.horizontal.seen = false;
334 break;
335 }
336 scrollclass_devices_[deviceid] = true;
337 }
338
303 bool DeviceDataManagerX11::GetSlotNumber(const XIDeviceEvent* xiev, int* slot) { 339 bool DeviceDataManagerX11::GetSlotNumber(const XIDeviceEvent* xiev, int* slot) {
304 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); 340 ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
305 if (!factory->IsMultiTouchDevice(xiev->sourceid)) { 341 if (!factory->IsMultiTouchDevice(xiev->sourceid)) {
306 *slot = 0; 342 *slot = 0;
307 return true; 343 return true;
308 } 344 }
309 return factory->QuerySlotForTrackingID(xiev->detail, slot); 345 return factory->QuerySlotForTrackingID(xiev->detail, slot);
310 } 346 }
311 347
312 void DeviceDataManagerX11::GetEventRawData(const XEvent& xev, EventData* data) { 348 void DeviceDataManagerX11::GetEventRawData(const XEvent& xev, EventData* data) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 return false; 451 return false;
416 452
417 XIDeviceEvent* xievent = 453 XIDeviceEvent* xievent =
418 static_cast<XIDeviceEvent*>(native_event->xcookie.data); 454 static_cast<XIDeviceEvent*>(native_event->xcookie.data);
419 CHECK(xievent->sourceid >= 0); 455 CHECK(xievent->sourceid >= 0);
420 if (xievent->sourceid >= kMaxDeviceNum) 456 if (xievent->sourceid >= kMaxDeviceNum)
421 return false; 457 return false;
422 return cmt_devices_[xievent->sourceid]; 458 return cmt_devices_[xievent->sourceid];
423 } 459 }
424 460
461 int DeviceDataManagerX11::GetScrollClassEventDetail(
462 const base::NativeEvent& native_event) const {
463 if (native_event->type != GenericEvent)
464 return SCROLL_TYPE_NO_SCROLL;
465
466 XIDeviceEvent* xievent =
467 static_cast<XIDeviceEvent*>(native_event->xcookie.data);
468 if (xievent->sourceid >= kMaxDeviceNum)
469 return SCROLL_TYPE_NO_SCROLL;
470 if (!scrollclass_devices_[xievent->sourceid])
471 return SCROLL_TYPE_NO_SCROLL;
472 int horizontal_id = scroll_data_[xievent->sourceid].horizontal.number;
473 int vertical_id = scroll_data_[xievent->sourceid].vertical.number;
474 return (XIMaskIsSet(xievent->valuators.mask, horizontal_id)
475 ? SCROLL_TYPE_HORIZONTAL
476 : 0) |
477 (XIMaskIsSet(xievent->valuators.mask, vertical_id)
478 ? SCROLL_TYPE_VERTICAL
479 : 0);
480 }
481
482 int DeviceDataManagerX11::GetScrollClassDeviceDetail(
483 const base::NativeEvent& native_event) const {
484 XEvent& xev = *native_event;
485 if (xev.type != GenericEvent)
486 return SCROLL_TYPE_NO_SCROLL;
487
488 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev.xcookie.data);
489 if (xiev->sourceid >= kMaxDeviceNum || xiev->deviceid >= kMaxDeviceNum)
490 return SCROLL_TYPE_NO_SCROLL;
491 const int sourceid = xiev->sourceid;
492 ScrollInfo device_data = scroll_data_[sourceid];
493 return (device_data.vertical.number >= 0 ? SCROLL_TYPE_VERTICAL : 0) |
494 (device_data.horizontal.number >= 0 ? SCROLL_TYPE_HORIZONTAL : 0);
495 }
496
425 bool DeviceDataManagerX11::IsCMTGestureEvent( 497 bool DeviceDataManagerX11::IsCMTGestureEvent(
426 const base::NativeEvent& native_event) const { 498 const base::NativeEvent& native_event) const {
427 return (IsScrollEvent(native_event) || 499 return (IsScrollEvent(native_event) ||
428 IsFlingEvent(native_event) || 500 IsFlingEvent(native_event) ||
429 IsCMTMetricsEvent(native_event)); 501 IsCMTMetricsEvent(native_event));
430 } 502 }
431 503
432 bool DeviceDataManagerX11::HasEventData( 504 bool DeviceDataManagerX11::HasEventData(
433 const XIDeviceEvent* xiev, const DataType type) const { 505 const XIDeviceEvent* xiev, const DataType type) const {
434 CHECK(xiev->sourceid >= 0); 506 CHECK(xiev->sourceid >= 0);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 if (data.find(DT_CMT_SCROLL_Y) != data.end()) 579 if (data.find(DT_CMT_SCROLL_Y) != data.end())
508 *y_offset = data[DT_CMT_SCROLL_Y]; 580 *y_offset = data[DT_CMT_SCROLL_Y];
509 if (data.find(DT_CMT_ORDINAL_X) != data.end()) 581 if (data.find(DT_CMT_ORDINAL_X) != data.end())
510 *x_offset_ordinal = data[DT_CMT_ORDINAL_X]; 582 *x_offset_ordinal = data[DT_CMT_ORDINAL_X];
511 if (data.find(DT_CMT_ORDINAL_Y) != data.end()) 583 if (data.find(DT_CMT_ORDINAL_Y) != data.end())
512 *y_offset_ordinal = data[DT_CMT_ORDINAL_Y]; 584 *y_offset_ordinal = data[DT_CMT_ORDINAL_Y];
513 if (data.find(DT_CMT_FINGER_COUNT) != data.end()) 585 if (data.find(DT_CMT_FINGER_COUNT) != data.end())
514 *finger_count = static_cast<int>(data[DT_CMT_FINGER_COUNT]); 586 *finger_count = static_cast<int>(data[DT_CMT_FINGER_COUNT]);
515 } 587 }
516 588
589 void DeviceDataManagerX11::GetScrollClassOffsets(
590 const base::NativeEvent& native_event,
591 double* x_offset,
592 double* y_offset) {
593 XEvent& xev = *native_event;
594 if (xev.type != GenericEvent)
595 return;
596
597 *x_offset = 0;
598 *y_offset = 0;
599
600 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev.xcookie.data);
601 if (xiev->sourceid >= kMaxDeviceNum || xiev->deviceid >= kMaxDeviceNum)
602 return;
603 const int sourceid = xiev->sourceid;
604 double* valuators = xiev->valuators.values;
605
606 ScrollInfo& info = scroll_data_[sourceid];
607
608 const int horizontal_number = info.horizontal.number;
609 const int vertical_number = info.vertical.number;
610
611 for (int i = 0; i <= valuator_count_[sourceid]; ++i) {
612 if (!XIMaskIsSet(xiev->valuators.mask, i))
613 continue;
614 if (i == horizontal_number) {
615 double value = *valuators;
616 double delta = 0;
617
618 if (info.horizontal.seen)
619 delta = info.horizontal.position - value;
620
621 info.horizontal.seen = true;
622 info.horizontal.position = value;
623 *x_offset = delta;
624 NormalizeScrollData(sourceid, true, x_offset);
625 } else if (i == vertical_number) {
626 double value = *valuators;
627 double delta = 0;
628 if (info.vertical.seen)
629 delta = info.vertical.position - value;
bokan 2015/12/01 18:29:27 I still see scroll jumping when I have a mouse plu
630
631 info.vertical.seen = true;
632 info.vertical.position = value;
633 *y_offset = delta;
634 NormalizeScrollData(sourceid, false, y_offset);
635 }
636 valuators++;
637 }
638 }
639
640 void DeviceDataManagerX11::InvalidateScrollClasses() {
641 for (int i = 0; i < kMaxDeviceNum; i++) {
642 scroll_data_[i].horizontal.seen = false;
643 scroll_data_[i].vertical.seen = false;
644 }
645 }
646
517 void DeviceDataManagerX11::GetFlingData( 647 void DeviceDataManagerX11::GetFlingData(
518 const base::NativeEvent& native_event, 648 const base::NativeEvent& native_event,
519 float* vx, 649 float* vx,
520 float* vy, 650 float* vy,
521 float* vx_ordinal, 651 float* vx_ordinal,
522 float* vy_ordinal, 652 float* vy_ordinal,
523 bool* is_cancel) { 653 bool* is_cancel) {
524 *vx = 0; 654 *vx = 0;
525 *vy = 0; 655 *vy = 0;
526 *vx_ordinal = 0; 656 *vx_ordinal = 0;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 double max_value; 730 double max_value;
601 double min_value; 731 double min_value;
602 if (GetDataRange(deviceid, type, &min_value, &max_value)) { 732 if (GetDataRange(deviceid, type, &min_value, &max_value)) {
603 *value = (*value - min_value) / (max_value - min_value); 733 *value = (*value - min_value) / (max_value - min_value);
604 DCHECK(*value >= 0.0 && *value <= 1.0); 734 DCHECK(*value >= 0.0 && *value <= 1.0);
605 return true; 735 return true;
606 } 736 }
607 return false; 737 return false;
608 } 738 }
609 739
740 bool DeviceDataManagerX11::NormalizeScrollData(unsigned int deviceid,
741 bool horizontal,
742 double* value) {
743 if (deviceid >= static_cast<unsigned int>(kMaxDeviceNum))
744 return false;
745 if (horizontal && scroll_data_[deviceid].horizontal.number < 0)
746 return false;
747 if (!horizontal && scroll_data_[deviceid].vertical.number < 0)
748 return false;
749 double increment = horizontal ? scroll_data_[deviceid].horizontal.increment
750 : scroll_data_[deviceid].vertical.increment;
751
752 *value /= increment;
753 return true;
754 }
755
610 bool DeviceDataManagerX11::GetDataRange(int deviceid, 756 bool DeviceDataManagerX11::GetDataRange(int deviceid,
611 const DataType type, 757 const DataType type,
612 double* min, 758 double* min,
613 double* max) { 759 double* max) {
614 CHECK(deviceid >= 0); 760 CHECK(deviceid >= 0);
615 if (deviceid >= kMaxDeviceNum) 761 if (deviceid >= kMaxDeviceNum)
616 return false; 762 return false;
617 if (valuator_lookup_[deviceid][type] >= 0) { 763 if (valuator_lookup_[deviceid][type] >= 0) {
618 *min = valuator_min_[deviceid][type]; 764 *min = valuator_min_[deviceid][type];
619 *max = valuator_max_[deviceid][type]; 765 *max = valuator_max_[deviceid][type];
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 } else { 930 } else {
785 keyboards.erase(it); 931 keyboards.erase(it);
786 ++blocked_iter; 932 ++blocked_iter;
787 } 933 }
788 } 934 }
789 // Notify base class of updated list. 935 // Notify base class of updated list.
790 DeviceDataManager::OnKeyboardDevicesUpdated(keyboards); 936 DeviceDataManager::OnKeyboardDevicesUpdated(keyboards);
791 } 937 }
792 938
793 } // namespace ui 939 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698