| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/base/events/event_constants.h" | 5 #include "ui/base/events/event_constants.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 #include <X11/extensions/XInput.h> | 8 #include <X11/extensions/XInput.h> |
| 9 #include <X11/extensions/XInput2.h> | 9 #include <X11/extensions/XInput2.h> |
| 10 #include <X11/Xlib.h> | 10 #include <X11/Xlib.h> |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 | 33 |
| 34 // CMT specific timings | 34 // CMT specific timings |
| 35 #define AXIS_LABEL_PROP_ABS_START_TIME "Abs Start Timestamp" | 35 #define AXIS_LABEL_PROP_ABS_START_TIME "Abs Start Timestamp" |
| 36 #define AXIS_LABEL_PROP_ABS_END_TIME "Abs End Timestamp" | 36 #define AXIS_LABEL_PROP_ABS_END_TIME "Abs End Timestamp" |
| 37 | 37 |
| 38 // Fling properties | 38 // Fling properties |
| 39 #define AXIS_LABEL_PROP_ABS_FLING_X "Abs Fling X Velocity" | 39 #define AXIS_LABEL_PROP_ABS_FLING_X "Abs Fling X Velocity" |
| 40 #define AXIS_LABEL_PROP_ABS_FLING_Y "Abs Fling Y Velocity" | 40 #define AXIS_LABEL_PROP_ABS_FLING_Y "Abs Fling Y Velocity" |
| 41 #define AXIS_LABEL_PROP_ABS_FLING_STATE "Abs Fling State" | 41 #define AXIS_LABEL_PROP_ABS_FLING_STATE "Abs Fling State" |
| 42 | 42 |
| 43 #define AXIS_LABEL_PROP_ABS_FINGER_COUNT "Abs Finger Count" |
| 44 |
| 43 // New versions of the valuators, with double values instead of fixed point. | 45 // New versions of the valuators, with double values instead of fixed point. |
| 44 #define AXIS_LABEL_PROP_ABS_DBL_START_TIME "Abs Dbl Start Timestamp" | 46 #define AXIS_LABEL_PROP_ABS_DBL_START_TIME "Abs Dbl Start Timestamp" |
| 45 #define AXIS_LABEL_PROP_ABS_DBL_END_TIME "Abs Dbl End Timestamp" | 47 #define AXIS_LABEL_PROP_ABS_DBL_END_TIME "Abs Dbl End Timestamp" |
| 46 #define AXIS_LABEL_PROP_ABS_DBL_FLING_VX "Abs Dbl Fling X Velocity" | 48 #define AXIS_LABEL_PROP_ABS_DBL_FLING_VX "Abs Dbl Fling X Velocity" |
| 47 #define AXIS_LABEL_PROP_ABS_DBL_FLING_VY "Abs Dbl Fling Y Velocity" | 49 #define AXIS_LABEL_PROP_ABS_DBL_FLING_VY "Abs Dbl Fling Y Velocity" |
| 48 | 50 |
| 49 namespace { | 51 namespace { |
| 50 | 52 |
| 51 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. | 53 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. |
| 52 const int kWheelScrollAmount = 53; | 54 const int kWheelScrollAmount = 53; |
| 53 | 55 |
| 54 const int kMinWheelButton = 4; | 56 const int kMinWheelButton = 4; |
| 55 const int kMaxWheelButton = 7; | 57 const int kMaxWheelButton = 7; |
| 56 | 58 |
| 57 const char* kCMTCachedAtoms[] = { | 59 const char* kCMTCachedAtoms[] = { |
| 58 AXIS_LABEL_PROP_REL_HWHEEL, | 60 AXIS_LABEL_PROP_REL_HWHEEL, |
| 59 AXIS_LABEL_PROP_REL_WHEEL, | 61 AXIS_LABEL_PROP_REL_WHEEL, |
| 60 AXIS_LABEL_PROP_ABS_START_TIME, | 62 AXIS_LABEL_PROP_ABS_START_TIME, |
| 61 AXIS_LABEL_PROP_ABS_DBL_START_TIME, | 63 AXIS_LABEL_PROP_ABS_DBL_START_TIME, |
| 62 AXIS_LABEL_PROP_ABS_END_TIME, | 64 AXIS_LABEL_PROP_ABS_END_TIME, |
| 63 AXIS_LABEL_PROP_ABS_DBL_END_TIME, | 65 AXIS_LABEL_PROP_ABS_DBL_END_TIME, |
| 64 AXIS_LABEL_PROP_ABS_FLING_X, | 66 AXIS_LABEL_PROP_ABS_FLING_X, |
| 65 AXIS_LABEL_PROP_ABS_FLING_Y, | 67 AXIS_LABEL_PROP_ABS_FLING_Y, |
| 66 AXIS_LABEL_PROP_ABS_DBL_FLING_VX, | 68 AXIS_LABEL_PROP_ABS_DBL_FLING_VX, |
| 67 AXIS_LABEL_PROP_ABS_DBL_FLING_VY, | 69 AXIS_LABEL_PROP_ABS_DBL_FLING_VY, |
| 68 AXIS_LABEL_PROP_ABS_FLING_STATE, | 70 AXIS_LABEL_PROP_ABS_FLING_STATE, |
| 71 AXIS_LABEL_PROP_ABS_FINGER_COUNT, |
| 69 NULL | 72 NULL |
| 70 }; | 73 }; |
| 71 | 74 |
| 72 #if defined(USE_XI2_MT) | 75 #if defined(USE_XI2_MT) |
| 73 // If the calibration values were read, if this is true. | 76 // If the calibration values were read, if this is true. |
| 74 bool calibration_values_read = false; | 77 bool calibration_values_read = false; |
| 75 | 78 |
| 76 // The (positive) calibration values for the four border sides. | 79 // The (positive) calibration values for the four border sides. |
| 77 int left_border_touch_calibration = 0; | 80 int left_border_touch_calibration = 0; |
| 78 int top_border_touch_calibration = 0; | 81 int top_border_touch_calibration = 0; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 Atom start_time = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_START_TIME); | 117 Atom start_time = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_START_TIME); |
| 115 Atom start_time_dbl = | 118 Atom start_time_dbl = |
| 116 atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_DBL_START_TIME); | 119 atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_DBL_START_TIME); |
| 117 Atom end_time = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_END_TIME); | 120 Atom end_time = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_END_TIME); |
| 118 Atom end_time_dbl = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_DBL_END_TIME); | 121 Atom end_time_dbl = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_DBL_END_TIME); |
| 119 Atom fling_vx = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_FLING_X); | 122 Atom fling_vx = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_FLING_X); |
| 120 Atom fling_vx_dbl = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_DBL_FLING_VX); | 123 Atom fling_vx_dbl = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_DBL_FLING_VX); |
| 121 Atom fling_vy = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_FLING_Y); | 124 Atom fling_vy = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_FLING_Y); |
| 122 Atom fling_vy_dbl = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_DBL_FLING_VY); | 125 Atom fling_vy_dbl = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_DBL_FLING_VY); |
| 123 Atom fling_state = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_FLING_STATE); | 126 Atom fling_state = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_FLING_STATE); |
| 127 Atom finger_count = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_FINGER_COUNT); |
| 124 | 128 |
| 125 for (int i = 0; i < count; ++i) { | 129 for (int i = 0; i < count; ++i) { |
| 126 XIDeviceInfo* info = info_list + i; | 130 XIDeviceInfo* info = info_list + i; |
| 127 | 131 |
| 128 if (info->use != XISlavePointer && info->use != XIFloatingSlave) | 132 if (info->use != XISlavePointer && info->use != XIFloatingSlave) |
| 129 continue; | 133 continue; |
| 130 | 134 |
| 131 Valuators valuators; | 135 Valuators valuators; |
| 132 bool is_cmt = false; | 136 bool is_cmt = false; |
| 133 for (int j = 0; j < info->num_classes; ++j) { | 137 for (int j = 0; j < info->num_classes; ++j) { |
| 134 if (info->classes[j]->type == XIScrollClass) { | 138 if (info->classes[j]->type == XIScrollClass) { |
| 135 is_cmt = false; | 139 is_cmt = false; |
| 136 break; | 140 break; |
| 137 } | 141 } |
| 138 if (info->classes[j]->type != XIValuatorClass) | 142 if (info->classes[j]->type != XIValuatorClass) |
| 139 continue; | 143 continue; |
| 140 | 144 |
| 141 XIValuatorClassInfo* v = | 145 XIValuatorClassInfo* v = |
| 142 reinterpret_cast<XIValuatorClassInfo*>(info->classes[j]); | 146 reinterpret_cast<XIValuatorClassInfo*>(info->classes[j]); |
| 143 int number = v->number; | 147 int number = v->number; |
| 144 if (number > valuators.max) | 148 if (number > valuators.max) |
| 145 valuators.max = number; | 149 valuators.max = number; |
| 146 if (v->label == x_axis) { | 150 if (v->label == x_axis) { |
| 147 valuators.scroll_x = number; | 151 valuators.scroll_x = number; |
| 148 is_cmt = true; | 152 is_cmt = true; |
| 149 } else if (v->label == y_axis) { | 153 } else if (v->label == y_axis) { |
| 150 valuators.scroll_y = number; | 154 valuators.scroll_y = number; |
| 151 is_cmt = true; | 155 is_cmt = true; |
| 156 } else if (v->label == finger_count) { |
| 157 valuators.finger_count = number; |
| 158 is_cmt = true; |
| 152 } else if (v->label == start_time) { | 159 } else if (v->label == start_time) { |
| 153 valuators.start_time = number; | 160 valuators.start_time = number; |
| 154 is_cmt = true; | 161 is_cmt = true; |
| 155 } else if (v->label == start_time_dbl) { | 162 } else if (v->label == start_time_dbl) { |
| 156 valuators.start_time_dbl = number; | 163 valuators.start_time_dbl = number; |
| 157 is_cmt = true; | 164 is_cmt = true; |
| 158 } else if (v->label == end_time) { | 165 } else if (v->label == end_time) { |
| 159 valuators.end_time = number; | 166 valuators.end_time = number; |
| 160 is_cmt = true; | 167 is_cmt = true; |
| 161 } else if (v->label == end_time_dbl) { | 168 } else if (v->label == end_time_dbl) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 // Natural scroll is touchpad-only. | 222 // Natural scroll is touchpad-only. |
| 216 if (!touchpads_[sourceid]) | 223 if (!touchpads_[sourceid]) |
| 217 return -1.0f; | 224 return -1.0f; |
| 218 | 225 |
| 219 return natural_scroll_enabled_ ? 1.0f : -1.0f; | 226 return natural_scroll_enabled_ ? 1.0f : -1.0f; |
| 220 } | 227 } |
| 221 | 228 |
| 222 // Returns true if this is a scroll event (a motion event with the necessary | 229 // Returns true if this is a scroll event (a motion event with the necessary |
| 223 // valuators. Also returns the offsets. |x_offset| and |y_offset| can be | 230 // valuators. Also returns the offsets. |x_offset| and |y_offset| can be |
| 224 // NULL. | 231 // NULL. |
| 225 bool GetScrollOffsets(const XEvent& xev, float* x_offset, float* y_offset) { | 232 bool GetScrollOffsets(const XEvent& xev, |
| 233 float* x_offset, |
| 234 float* y_offset, |
| 235 int* finger_count) { |
| 226 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev.xcookie.data); | 236 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev.xcookie.data); |
| 227 | 237 |
| 228 if (x_offset) | 238 if (x_offset) |
| 229 *x_offset = 0; | 239 *x_offset = 0; |
| 230 if (y_offset) | 240 if (y_offset) |
| 231 *y_offset = 0; | 241 *y_offset = 0; |
| 242 if (finger_count) |
| 243 *finger_count = 2; |
| 232 | 244 |
| 233 const int sourceid = xiev->sourceid; | 245 const int sourceid = xiev->sourceid; |
| 234 if (!cmt_devices_[sourceid]) | 246 if (!cmt_devices_[sourceid]) |
| 235 return false; | 247 return false; |
| 236 | 248 |
| 237 const float natural_scroll_factor = GetNaturalScrollFactor(sourceid); | 249 const float natural_scroll_factor = GetNaturalScrollFactor(sourceid); |
| 238 const Valuators v = device_to_valuators_[sourceid]; | 250 const Valuators v = device_to_valuators_[sourceid]; |
| 239 const bool has_x_offset = XIMaskIsSet(xiev->valuators.mask, v.scroll_x); | 251 const bool has_x_offset = XIMaskIsSet(xiev->valuators.mask, v.scroll_x); |
| 240 const bool has_y_offset = XIMaskIsSet(xiev->valuators.mask, v.scroll_y); | 252 const bool has_y_offset = XIMaskIsSet(xiev->valuators.mask, v.scroll_y); |
| 241 const bool is_scroll = has_x_offset || has_y_offset; | 253 const bool is_scroll = has_x_offset || has_y_offset; |
| 242 | 254 |
| 243 if (!is_scroll || (!x_offset && !y_offset)) | 255 if (!is_scroll || (!x_offset && !y_offset)) |
| 244 return is_scroll; | 256 return is_scroll; |
| 245 | 257 |
| 246 double* valuators = xiev->valuators.values; | 258 double* valuators = xiev->valuators.values; |
| 247 for (int i = 0; i <= v.max; ++i) { | 259 for (int i = 0; i <= v.max; ++i) { |
| 248 if (XIMaskIsSet(xiev->valuators.mask, i)) { | 260 if (XIMaskIsSet(xiev->valuators.mask, i)) { |
| 249 if (x_offset && v.scroll_x == i) | 261 if (x_offset && v.scroll_x == i) |
| 250 *x_offset = *valuators * natural_scroll_factor; | 262 *x_offset = *valuators * natural_scroll_factor; |
| 251 else if (y_offset && v.scroll_y == i) | 263 else if (y_offset && v.scroll_y == i) |
| 252 *y_offset = *valuators * natural_scroll_factor; | 264 *y_offset = *valuators * natural_scroll_factor; |
| 265 else if (finger_count && v.finger_count == i) |
| 266 *finger_count = static_cast<int>(*valuators); |
| 253 valuators++; | 267 valuators++; |
| 254 } | 268 } |
| 255 } | 269 } |
| 256 | 270 |
| 257 return true; | 271 return true; |
| 258 } | 272 } |
| 259 | 273 |
| 260 bool GetFlingData(const XEvent& xev, | 274 bool GetFlingData(const XEvent& xev, |
| 261 float* vx, float* vy, | 275 float* vx, float* vy, |
| 262 bool* is_cancel) { | 276 bool* is_cancel) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 } | 365 } |
| 352 | 366 |
| 353 private: | 367 private: |
| 354 // Requirement for Singleton | 368 // Requirement for Singleton |
| 355 friend struct DefaultSingletonTraits<CMTEventData>; | 369 friend struct DefaultSingletonTraits<CMTEventData>; |
| 356 | 370 |
| 357 struct Valuators { | 371 struct Valuators { |
| 358 int max; | 372 int max; |
| 359 int scroll_x; | 373 int scroll_x; |
| 360 int scroll_y; | 374 int scroll_y; |
| 375 int finger_count; |
| 361 int start_time; | 376 int start_time; |
| 362 int end_time; | 377 int end_time; |
| 363 int fling_vx; | 378 int fling_vx; |
| 364 int fling_vy; | 379 int fling_vy; |
| 365 int fling_state; | 380 int fling_state; |
| 366 // *_dbl valuators take precedence over the fixed precision versions. | 381 // *_dbl valuators take precedence over the fixed precision versions. |
| 367 int start_time_dbl; | 382 int start_time_dbl; |
| 368 int end_time_dbl; | 383 int end_time_dbl; |
| 369 int fling_vx_dbl; | 384 int fling_vx_dbl; |
| 370 int fling_vy_dbl; | 385 int fling_vy_dbl; |
| 371 | 386 |
| 372 Valuators() | 387 Valuators() |
| 373 : max(-1), | 388 : max(-1), |
| 374 scroll_x(-1), | 389 scroll_x(-1), |
| 375 scroll_y(-1), | 390 scroll_y(-1), |
| 391 finger_count(-1), |
| 376 start_time(-1), | 392 start_time(-1), |
| 377 end_time(-1), | 393 end_time(-1), |
| 378 fling_vx(-1), | 394 fling_vx(-1), |
| 379 fling_vy(-1), | 395 fling_vy(-1), |
| 380 fling_state(-1), | 396 fling_state(-1), |
| 381 start_time_dbl(-1), | 397 start_time_dbl(-1), |
| 382 end_time_dbl(-1), | 398 end_time_dbl(-1), |
| 383 fling_vx_dbl(-1), | 399 fling_vx_dbl(-1), |
| 384 fling_vy_dbl(-1) { | 400 fling_vy_dbl(-1) { |
| 385 } | 401 } |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 // Drop wheel events; we should've already scrolled on the press. | 758 // Drop wheel events; we should've already scrolled on the press. |
| 743 if (button >= kMinWheelButton && button <= kMaxWheelButton) | 759 if (button >= kMinWheelButton && button <= kMaxWheelButton) |
| 744 return ET_UNKNOWN; | 760 return ET_UNKNOWN; |
| 745 return ET_MOUSE_RELEASED; | 761 return ET_MOUSE_RELEASED; |
| 746 } | 762 } |
| 747 case XI_Motion: { | 763 case XI_Motion: { |
| 748 float vx, vy; | 764 float vx, vy; |
| 749 bool is_cancel; | 765 bool is_cancel; |
| 750 if (GetFlingData(native_event, &vx, &vy, &is_cancel)) { | 766 if (GetFlingData(native_event, &vx, &vy, &is_cancel)) { |
| 751 return is_cancel ? ET_SCROLL_FLING_CANCEL : ET_SCROLL_FLING_START; | 767 return is_cancel ? ET_SCROLL_FLING_CANCEL : ET_SCROLL_FLING_START; |
| 752 } else if (GetScrollOffsets(native_event, NULL, NULL)) { | 768 } else if (GetScrollOffsets(native_event, NULL, NULL, NULL)) { |
| 753 return ET_SCROLL; | 769 return ET_SCROLL; |
| 754 } else if (GetButtonMaskForX2Event(xievent)) { | 770 } else if (GetButtonMaskForX2Event(xievent)) { |
| 755 return ET_MOUSE_DRAGGED; | 771 return ET_MOUSE_DRAGGED; |
| 756 } else { | 772 } else { |
| 757 return ET_MOUSE_MOVED; | 773 return ET_MOUSE_MOVED; |
| 758 } | 774 } |
| 759 } | 775 } |
| 760 } | 776 } |
| 761 } | 777 } |
| 762 default: | 778 default: |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 static_cast<XIDeviceEvent*>(native_event->xcookie.data)->sourceid; | 1075 static_cast<XIDeviceEvent*>(native_event->xcookie.data)->sourceid; |
| 1060 // Force is normalized to fall into [0, 1] | 1076 // Force is normalized to fall into [0, 1] |
| 1061 if (!ui::ValuatorTracker::GetInstance()->NormalizeValuator( | 1077 if (!ui::ValuatorTracker::GetInstance()->NormalizeValuator( |
| 1062 deviceid, ui::ValuatorTracker::VAL_PRESSURE, &force)) | 1078 deviceid, ui::ValuatorTracker::VAL_PRESSURE, &force)) |
| 1063 force = 0.0; | 1079 force = 0.0; |
| 1064 return force; | 1080 return force; |
| 1065 } | 1081 } |
| 1066 | 1082 |
| 1067 bool GetScrollOffsets(const base::NativeEvent& native_event, | 1083 bool GetScrollOffsets(const base::NativeEvent& native_event, |
| 1068 float* x_offset, | 1084 float* x_offset, |
| 1069 float* y_offset) { | 1085 float* y_offset, |
| 1086 int* finger_count) { |
| 1070 return CMTEventData::GetInstance()->GetScrollOffsets( | 1087 return CMTEventData::GetInstance()->GetScrollOffsets( |
| 1071 *native_event, x_offset, y_offset); | 1088 *native_event, x_offset, y_offset, finger_count); |
| 1072 } | 1089 } |
| 1073 | 1090 |
| 1074 bool GetFlingData(const base::NativeEvent& native_event, | 1091 bool GetFlingData(const base::NativeEvent& native_event, |
| 1075 float* vx, | 1092 float* vx, |
| 1076 float* vy, | 1093 float* vy, |
| 1077 bool* is_cancel) { | 1094 bool* is_cancel) { |
| 1078 return CMTEventData::GetInstance()->GetFlingData( | 1095 return CMTEventData::GetInstance()->GetFlingData( |
| 1079 *native_event, vx, vy, is_cancel); | 1096 *native_event, vx, vy, is_cancel); |
| 1080 } | 1097 } |
| 1081 | 1098 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1113 noop->xclient.format = 8; | 1130 noop->xclient.format = 8; |
| 1114 DCHECK(!noop->xclient.display); | 1131 DCHECK(!noop->xclient.display); |
| 1115 } | 1132 } |
| 1116 // Make sure we use atom from current xdisplay, which may | 1133 // Make sure we use atom from current xdisplay, which may |
| 1117 // change during the test. | 1134 // change during the test. |
| 1118 noop->xclient.message_type = GetNoopEventAtom(); | 1135 noop->xclient.message_type = GetNoopEventAtom(); |
| 1119 return noop; | 1136 return noop; |
| 1120 } | 1137 } |
| 1121 | 1138 |
| 1122 } // namespace ui | 1139 } // namespace ui |
| OLD | NEW |