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

Side by Side Diff: ui/base/x/events_x.cc

Issue 10375029: Support both old and new valuator formats for times and flings. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix problem with end time Created 8 years, 7 months 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.h" 5 #include "ui/base/events.h"
6 6
7 #include <X11/Xlib.h> 7 #include <X11/Xlib.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 <string.h> 10 #include <string.h>
(...skipping 11 matching lines...) Expand all
22 22
23 // CMT specific timings 23 // CMT specific timings
24 #define AXIS_LABEL_PROP_ABS_START_TIME "Abs Start Timestamp" 24 #define AXIS_LABEL_PROP_ABS_START_TIME "Abs Start Timestamp"
25 #define AXIS_LABEL_PROP_ABS_END_TIME "Abs End Timestamp" 25 #define AXIS_LABEL_PROP_ABS_END_TIME "Abs End Timestamp"
26 26
27 // Fling properties 27 // Fling properties
28 #define AXIS_LABEL_PROP_ABS_FLING_X "Abs Fling X Velocity" 28 #define AXIS_LABEL_PROP_ABS_FLING_X "Abs Fling X Velocity"
29 #define AXIS_LABEL_PROP_ABS_FLING_Y "Abs Fling Y Velocity" 29 #define AXIS_LABEL_PROP_ABS_FLING_Y "Abs Fling Y Velocity"
30 #define AXIS_LABEL_PROP_ABS_FLING_STATE "Abs Fling State" 30 #define AXIS_LABEL_PROP_ABS_FLING_STATE "Abs Fling State"
31 31
32 // New versions of the valuators, with double values instead of fixed point.
33 #define AXIS_LABEL_PROP_ABS_DBL_START_TIME "Abs Dbl Start Timestamp"
34 #define AXIS_LABEL_PROP_ABS_DBL_END_TIME "Abs Dbl End Timestamp"
35 #define AXIS_LABEL_PROP_ABS_DBL_FLING_VX "Abs Dbl Fling X Velocity"
36 #define AXIS_LABEL_PROP_ABS_DBL_FLING_VY "Abs Dbl Fling Y Velocity"
37
32 namespace { 38 namespace {
33 39
34 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. 40 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+.
35 const int kWheelScrollAmount = 53; 41 const int kWheelScrollAmount = 53;
36 42
37 const int kMinWheelButton = 4; 43 const int kMinWheelButton = 4;
38 const int kMaxWheelButton = 7; 44 const int kMaxWheelButton = 7;
39 45
40 // A class to support the detection of scroll events, using X11 valuators. 46 // A class to support the detection of scroll events, using X11 valuators.
41 class UI_EXPORT CMTEventData { 47 class UI_EXPORT CMTEventData {
(...skipping 20 matching lines...) Expand all
62 touchpads_[dev_list[i].id] = true; 68 touchpads_[dev_list[i].id] = true;
63 } 69 }
64 if (dev_list) 70 if (dev_list)
65 XFreeDeviceList(dev_list); 71 XFreeDeviceList(dev_list);
66 72
67 XIDeviceInfo* info_list = XIQueryDevice(display, XIAllDevices, &count); 73 XIDeviceInfo* info_list = XIQueryDevice(display, XIAllDevices, &count);
68 Atom x_axis = XInternAtom(display, AXIS_LABEL_PROP_REL_HWHEEL, false); 74 Atom x_axis = XInternAtom(display, AXIS_LABEL_PROP_REL_HWHEEL, false);
69 Atom y_axis = XInternAtom(display, AXIS_LABEL_PROP_REL_WHEEL, false); 75 Atom y_axis = XInternAtom(display, AXIS_LABEL_PROP_REL_WHEEL, false);
70 Atom start_time = 76 Atom start_time =
71 XInternAtom(display, AXIS_LABEL_PROP_ABS_START_TIME, false); 77 XInternAtom(display, AXIS_LABEL_PROP_ABS_START_TIME, false);
78 Atom start_time_dbl =
79 XInternAtom(display, AXIS_LABEL_PROP_ABS_DBL_START_TIME, false);
72 Atom end_time = XInternAtom(display, AXIS_LABEL_PROP_ABS_END_TIME, false); 80 Atom end_time = XInternAtom(display, AXIS_LABEL_PROP_ABS_END_TIME, false);
81 Atom end_time_dbl =
82 XInternAtom(display, AXIS_LABEL_PROP_ABS_DBL_END_TIME, false);
73 Atom fling_vx = XInternAtom(display, AXIS_LABEL_PROP_ABS_FLING_X, false); 83 Atom fling_vx = XInternAtom(display, AXIS_LABEL_PROP_ABS_FLING_X, false);
84 Atom fling_vx_dbl =
85 XInternAtom(display, AXIS_LABEL_PROP_ABS_DBL_FLING_VX, false);
74 Atom fling_vy = XInternAtom(display, AXIS_LABEL_PROP_ABS_FLING_Y, false); 86 Atom fling_vy = XInternAtom(display, AXIS_LABEL_PROP_ABS_FLING_Y, false);
87 Atom fling_vy_dbl =
88 XInternAtom(display, AXIS_LABEL_PROP_ABS_DBL_FLING_VY, false);
75 Atom fling_state = 89 Atom fling_state =
76 XInternAtom(display, AXIS_LABEL_PROP_ABS_FLING_STATE, false); 90 XInternAtom(display, AXIS_LABEL_PROP_ABS_FLING_STATE, false);
77 91
78 for (int i = 0; i < count; ++i) { 92 for (int i = 0; i < count; ++i) {
79 XIDeviceInfo* info = info_list + i; 93 XIDeviceInfo* info = info_list + i;
80 94
81 if (info->use != XISlavePointer && info->use != XIFloatingSlave) 95 if (info->use != XISlavePointer && info->use != XIFloatingSlave)
82 continue; 96 continue;
83 97
84 Valuators valuators; 98 Valuators valuators;
85 bool is_cmt = false; 99 bool is_cmt = false;
86 for (int j = 0; j < info->num_classes; ++j) { 100 for (int j = 0; j < info->num_classes; ++j) {
87 if (info->classes[j]->type != XIValuatorClass) 101 if (info->classes[j]->type != XIValuatorClass)
88 continue; 102 continue;
89 103
90 XIValuatorClassInfo* v = 104 XIValuatorClassInfo* v =
91 reinterpret_cast<XIValuatorClassInfo*>(info->classes[j]); 105 reinterpret_cast<XIValuatorClassInfo*>(info->classes[j]);
92 int number = v->number; 106 int number = v->number;
93 if (number > valuators.max) 107 if (number > valuators.max)
94 valuators.max = number; 108 valuators.max = number;
95 if (v->label == x_axis) { 109 if (v->label == x_axis) {
96 valuators.scroll_x = number; 110 valuators.scroll_x = number;
97 is_cmt = true; 111 is_cmt = true;
98 } else if (v->label == y_axis) { 112 } else if (v->label == y_axis) {
99 valuators.scroll_y = number; 113 valuators.scroll_y = number;
100 is_cmt = true; 114 is_cmt = true;
101 } else if (v->label == start_time) { 115 } else if (v->label == start_time) {
102 valuators.start_time = number; 116 valuators.start_time = number;
103 is_cmt = true; 117 is_cmt = true;
118 } else if (v->label == start_time_dbl) {
119 valuators.start_time_dbl = number;
120 is_cmt = true;
104 } else if (v->label == end_time) { 121 } else if (v->label == end_time) {
105 valuators.end_time = number; 122 valuators.end_time = number;
106 is_cmt = true; 123 is_cmt = true;
124 } else if (v->label == end_time_dbl) {
125 valuators.end_time_dbl = number;
126 is_cmt = true;
107 } else if (v->label == fling_vx) { 127 } else if (v->label == fling_vx) {
108 valuators.fling_vx = number; 128 valuators.fling_vx = number;
109 is_cmt = true; 129 is_cmt = true;
130 } else if (v->label == fling_vx_dbl) {
131 valuators.fling_vx_dbl = number;
132 is_cmt = true;
110 } else if (v->label == fling_vy) { 133 } else if (v->label == fling_vy) {
111 valuators.fling_vy = number; 134 valuators.fling_vy = number;
112 is_cmt = true; 135 is_cmt = true;
136 } else if (v->label == fling_vy_dbl) {
137 valuators.fling_vy_dbl = number;
138 is_cmt = true;
113 } else if (v->label == fling_state) { 139 } else if (v->label == fling_state) {
114 valuators.fling_state = number; 140 valuators.fling_state = number;
115 is_cmt = true; 141 is_cmt = true;
116 } 142 }
117 } 143 }
118 if (is_cmt) { 144 if (is_cmt) {
145 // Double valuators override fixed point ones.
146 if (valuators.start_time_dbl >= 0)
147 valuators.start_time = -1;
148 if (valuators.end_time_dbl >= 0)
149 valuators.end_time = -1;
150 if (valuators.fling_vx_dbl >= 0)
151 valuators.fling_vx = -1;
152 if (valuators.fling_vy_dbl >= 0)
153 valuators.fling_vy = -1;
119 device_to_valuators_[info->deviceid] = valuators; 154 device_to_valuators_[info->deviceid] = valuators;
120 cmt_devices_[info->deviceid] = true; 155 cmt_devices_[info->deviceid] = true;
121 } 156 }
122 } 157 }
123 XIFreeDeviceInfo(info_list); 158 XIFreeDeviceInfo(info_list);
124 } 159 }
125 160
126 bool natural_scroll_enabled() const { return natural_scroll_enabled_; } 161 bool natural_scroll_enabled() const { return natural_scroll_enabled_; }
127 void set_natural_scroll_enabled(bool enabled) { 162 void set_natural_scroll_enabled(bool enabled) {
128 natural_scroll_enabled_ = enabled; 163 natural_scroll_enabled_ = enabled;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 *vx = 0; 226 *vx = 0;
192 *vy = 0; 227 *vy = 0;
193 *is_cancel = false; 228 *is_cancel = false;
194 229
195 const int deviceid = xiev->deviceid; 230 const int deviceid = xiev->deviceid;
196 if (!cmt_devices_[deviceid]) 231 if (!cmt_devices_[deviceid])
197 return false; 232 return false;
198 233
199 const float natural_scroll_factor = GetNaturalScrollFactor(deviceid); 234 const float natural_scroll_factor = GetNaturalScrollFactor(deviceid);
200 const Valuators v = device_to_valuators_[deviceid]; 235 const Valuators v = device_to_valuators_[deviceid];
201 if (!XIMaskIsSet(xiev->valuators.mask, v.fling_vx) || 236 if ((!XIMaskIsSet(xiev->valuators.mask, v.fling_vx) &&
202 !XIMaskIsSet(xiev->valuators.mask, v.fling_vy) || 237 !XIMaskIsSet(xiev->valuators.mask, v.fling_vx_dbl)) ||
238 (!XIMaskIsSet(xiev->valuators.mask, v.fling_vy) &&
239 !XIMaskIsSet(xiev->valuators.mask, v.fling_vy_dbl)) ||
203 !XIMaskIsSet(xiev->valuators.mask, v.fling_state)) 240 !XIMaskIsSet(xiev->valuators.mask, v.fling_state))
204 return false; 241 return false;
205 242
206 double* valuators = xiev->valuators.values; 243 double* valuators = xiev->valuators.values;
207 for (int i = 0; i <= v.max; ++i) { 244 for (int i = 0; i <= v.max; ++i) {
208 if (XIMaskIsSet(xiev->valuators.mask, i)) { 245 if (XIMaskIsSet(xiev->valuators.mask, i)) {
209 // Convert values to unsigned ints represending ms before storing them, 246 // Convert values to unsigned ints representing ms before storing them,
210 // as that is how they were encoded before conversion to doubles. 247 // as that is how they were encoded before conversion to doubles.
211 if (v.fling_vx == i) 248 if (v.fling_vx_dbl == i) {
249 *vx = natural_scroll_factor * *valuators;
250 } else if (v.fling_vx == i) {
212 *vx = natural_scroll_factor * 251 *vx = natural_scroll_factor *
213 (static_cast<int>(*valuators)) / 1000.0f; 252 static_cast<double>(static_cast<int>(*valuators)) / 1000.0f;
214 else if (v.fling_vy == i) 253 } else if (v.fling_vy_dbl == i) {
254 *vy = natural_scroll_factor * *valuators;
255 } else if (v.fling_vy == i) {
215 *vy = natural_scroll_factor * 256 *vy = natural_scroll_factor *
216 (static_cast<int>(*valuators)) / 1000.0f; 257 static_cast<double>(static_cast<int>(*valuators)) / 1000.0f;
217 else if (v.fling_state == i) 258 } else if (v.fling_state == i) {
218 *is_cancel = !!static_cast<unsigned int>(*valuators); 259 *is_cancel = !!static_cast<unsigned int>(*valuators);
260 }
219 valuators++; 261 valuators++;
220 } 262 }
221 } 263 }
222 264
223 return true; 265 return true;
224 } 266 }
225 267
226 bool GetGestureTimes(const XEvent& xev, 268 bool GetGestureTimes(const XEvent& xev,
227 double* start_time, 269 double* start_time,
228 double* end_time) { 270 double* end_time) {
229 *start_time = 0; 271 *start_time = 0;
230 *end_time = 0; 272 *end_time = 0;
231 273
232 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev.xcookie.data); 274 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev.xcookie.data);
233 if (!cmt_devices_[xiev->deviceid]) 275 if (!cmt_devices_[xiev->deviceid])
234 return false; 276 return false;
235 277
236 Valuators v = device_to_valuators_[xiev->deviceid]; 278 Valuators v = device_to_valuators_[xiev->deviceid];
237 if (!XIMaskIsSet(xiev->valuators.mask, v.start_time) || 279 if ((!XIMaskIsSet(xiev->valuators.mask, v.start_time) &&
238 !XIMaskIsSet(xiev->valuators.mask, v.end_time)) 280 !XIMaskIsSet(xiev->valuators.mask, v.start_time_dbl)) ||
281 (!XIMaskIsSet(xiev->valuators.mask, v.end_time) &&
282 !XIMaskIsSet(xiev->valuators.mask, v.end_time_dbl)))
239 return false; 283 return false;
240 284
241 double* valuators = xiev->valuators.values; 285 double* valuators = xiev->valuators.values;
242 for (int i = 0; i <= v.max; ++i) { 286 for (int i = 0; i <= v.max; ++i) {
243 if (XIMaskIsSet(xiev->valuators.mask, i)) { 287 if (XIMaskIsSet(xiev->valuators.mask, i)) {
244 // Convert values to unsigned ints represending ms before storing them, 288 if (v.start_time_dbl == i) {
245 // as that is how they were encoded before conversion to doubles. 289 *start_time = *valuators;
246 if (v.start_time == i) 290 } else if (v.start_time == i) {
291 // Convert values to unsigned ints representing ms before storing
292 // them, as that is how they were encoded before conversion
293 // to doubles.
247 *start_time = 294 *start_time =
248 static_cast<double>(static_cast<unsigned int>(*valuators)) / 1000; 295 static_cast<double>(
249 else if (v.end_time == i) 296 static_cast<unsigned int>(*valuators)) / 1000;
297 } else if (v.end_time_dbl == i) {
298 *end_time = *valuators;
299 } else if (v.end_time == i) {
300 // Convert values to unsigned ints representing ms before storing
301 // them, as that is how they were encoded before conversion
302 // to doubles.
250 *end_time = 303 *end_time =
251 static_cast<double>(static_cast<unsigned int>(*valuators)) / 1000; 304 static_cast<double>(
305 static_cast<unsigned int>(*valuators)) / 1000;
306 }
252 valuators++; 307 valuators++;
253 } 308 }
254 } 309 }
255 310
256 return true; 311 return true;
257 } 312 }
258 313
259 private: 314 private:
260 // Requirement for Singleton 315 // Requirement for Singleton
261 friend struct DefaultSingletonTraits<CMTEventData>; 316 friend struct DefaultSingletonTraits<CMTEventData>;
262 317
263 struct Valuators { 318 struct Valuators {
264 int max; 319 int max;
265 int scroll_x; 320 int scroll_x;
266 int scroll_y; 321 int scroll_y;
267 int start_time; 322 int start_time;
268 int end_time; 323 int end_time;
269 int fling_vx; 324 int fling_vx;
270 int fling_vy; 325 int fling_vy;
271 int fling_state; 326 int fling_state;
327 // *_dbl valuators take precedence over the fixed precision versions.
328 int start_time_dbl;
329 int end_time_dbl;
330 int fling_vx_dbl;
331 int fling_vy_dbl;
272 332
273 Valuators() 333 Valuators()
274 : max(-1), 334 : max(-1),
275 scroll_x(-1), 335 scroll_x(-1),
276 scroll_y(-1), 336 scroll_y(-1),
277 start_time(-1), 337 start_time(-1),
278 end_time(-1), 338 end_time(-1),
279 fling_vx(-1), 339 fling_vx(-1),
280 fling_vy(-1), 340 fling_vy(-1),
281 fling_state(-1) { 341 fling_state(-1),
282 342 start_time_dbl(-1),
343 end_time_dbl(-1),
344 fling_vx_dbl(-1),
345 fling_vy_dbl(-1) {
283 } 346 }
284 347
285 }; 348 };
286 349
287 CMTEventData() : natural_scroll_enabled_(true) { 350 CMTEventData() : natural_scroll_enabled_(true) {
288 UpdateDeviceList(ui::GetXDisplay()); 351 UpdateDeviceList(ui::GetXDisplay());
289 } 352 }
290 353
291 ~CMTEventData() {} 354 ~CMTEventData() {}
292 355
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 case ButtonRelease: 718 case ButtonRelease:
656 return base::TimeDelta::FromMilliseconds(native_event->xbutton.time); 719 return base::TimeDelta::FromMilliseconds(native_event->xbutton.time);
657 break; 720 break;
658 case MotionNotify: 721 case MotionNotify:
659 return base::TimeDelta::FromMilliseconds(native_event->xmotion.time); 722 return base::TimeDelta::FromMilliseconds(native_event->xmotion.time);
660 break; 723 break;
661 case GenericEvent: { 724 case GenericEvent: {
662 double start, end; 725 double start, end;
663 if (GetGestureTimes(native_event, &start, &end)) { 726 if (GetGestureTimes(native_event, &start, &end)) {
664 // If the driver supports gesture times, use them. 727 // If the driver supports gesture times, use them.
665 return base::TimeDelta::FromMicroseconds(start * 1000000); 728 return base::TimeDelta::FromMicroseconds(end * 1000000);
666 } else { 729 } else {
667 XIDeviceEvent* xide = 730 XIDeviceEvent* xide =
668 static_cast<XIDeviceEvent*>(native_event->xcookie.data); 731 static_cast<XIDeviceEvent*>(native_event->xcookie.data);
669 return base::TimeDelta::FromMilliseconds(xide->time); 732 return base::TimeDelta::FromMilliseconds(xide->time);
670 } 733 }
671 break; 734 break;
672 } 735 }
673 } 736 }
674 NOTREACHED(); 737 NOTREACHED();
675 return base::TimeDelta(); 738 return base::TimeDelta();
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 noop->xclient.format = 8; 934 noop->xclient.format = 8;
872 DCHECK(!noop->xclient.display); 935 DCHECK(!noop->xclient.display);
873 } 936 }
874 // Make sure we use atom from current xdisplay, which may 937 // Make sure we use atom from current xdisplay, which may
875 // change during the test. 938 // change during the test.
876 noop->xclient.message_type = GetNoopEventAtom(); 939 noop->xclient.message_type = GetNoopEventAtom();
877 return noop; 940 return noop;
878 } 941 }
879 942
880 } // namespace ui 943 } // namespace ui
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698