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 |