Upstream version 7.35.139.0
[platform/framework/web/crosswalk.git] / src / ui / events / x / events_x.cc
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
3 // found in the LICENSE file.
4
5 #include "ui/events/event_constants.h"
6
7 #include <cmath>
8 #include <string.h>
9 #include <X11/extensions/XInput.h>
10 #include <X11/extensions/XInput2.h>
11 #include <X11/Xlib.h>
12 #include <X11/Xutil.h>
13
14 #include "base/logging.h"
15 #include "base/memory/singleton.h"
16 #include "base/message_loop/message_pump_x11.h"
17 #include "ui/events/event_utils.h"
18 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
19 #include "ui/events/x/device_data_manager.h"
20 #include "ui/events/x/device_list_cache_x.h"
21 #include "ui/events/x/touch_factory_x11.h"
22 #include "ui/gfx/display.h"
23 #include "ui/gfx/point.h"
24 #include "ui/gfx/rect.h"
25 #include "ui/gfx/screen.h"
26 #include "ui/gfx/x/x11_atom_cache.h"
27 #include "ui/gfx/x/x11_types.h"
28
29 namespace {
30
31 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+.
32 const int kWheelScrollAmount = 53;
33
34 const int kMinWheelButton = 4;
35 const int kMaxWheelButton = 7;
36
37 // A class to track current modifier state on master device. Only track ctrl,
38 // alt, shift and caps lock keys currently. The tracked state can then be used
39 // by floating device.
40 class XModifierStateWatcher{
41  public:
42   static XModifierStateWatcher* GetInstance() {
43     return Singleton<XModifierStateWatcher>::get();
44   }
45
46   void UpdateStateFromEvent(const base::NativeEvent& native_event) {
47     // Floating device can't access the modifer state from master device.
48     // We need to track the states of modifier keys in a singleton for
49     // floating devices such as touch screen. Issue 106426 is one example
50     // of why we need the modifier states for floating device.
51     state_ = native_event->xkey.state;
52     // master_state is the state before key press. We need to track the
53     // state after key press for floating device. Currently only ctrl,
54     // shift, alt and caps lock keys are tracked.
55     ui::KeyboardCode keyboard_code = ui::KeyboardCodeFromNative(native_event);
56     unsigned int mask = 0;
57
58     switch (keyboard_code) {
59       case ui::VKEY_CONTROL: {
60         mask = ControlMask;
61         break;
62       }
63       case ui::VKEY_SHIFT: {
64         mask = ShiftMask;
65         break;
66       }
67       case ui::VKEY_MENU: {
68         mask = Mod1Mask;
69         break;
70       }
71       case ui::VKEY_CAPITAL: {
72         mask = LockMask;
73         break;
74       }
75       default:
76         break;
77     }
78
79     if (native_event->type == KeyPress)
80       state_ |= mask;
81     else
82       state_ &= ~mask;
83   }
84
85   // Returns the current modifer state in master device. It only contains the
86   // state of ctrl, shift, alt and caps lock keys.
87   unsigned int state() { return state_; }
88
89  private:
90   friend struct DefaultSingletonTraits<XModifierStateWatcher>;
91
92   XModifierStateWatcher() : state_(0) { }
93
94   unsigned int state_;
95
96   DISALLOW_COPY_AND_ASSIGN(XModifierStateWatcher);
97 };
98
99 #if defined(USE_XI2_MT)
100 // Detects if a touch event is a driver-generated 'special event'.
101 // A 'special event' is a touch event with maximum radius and pressure at
102 // location (0, 0).
103 // This needs to be done in a cleaner way: http://crbug.com/169256
104 bool TouchEventIsGeneratedHack(const base::NativeEvent& native_event) {
105   XIDeviceEvent* event =
106       static_cast<XIDeviceEvent*>(native_event->xcookie.data);
107   CHECK(event->evtype == XI_TouchBegin ||
108         event->evtype == XI_TouchUpdate ||
109         event->evtype == XI_TouchEnd);
110
111   // Force is normalized to [0, 1].
112   if (ui::GetTouchForce(native_event) < 1.0f)
113     return false;
114
115   if (ui::EventLocationFromNative(native_event) != gfx::Point())
116     return false;
117
118   // Radius is in pixels, and the valuator is the diameter in pixels.
119   double radius = ui::GetTouchRadiusX(native_event), min, max;
120   unsigned int deviceid =
121       static_cast<XIDeviceEvent*>(native_event->xcookie.data)->sourceid;
122   if (!ui::DeviceDataManager::GetInstance()->GetDataRange(
123       deviceid, ui::DeviceDataManager::DT_TOUCH_MAJOR, &min, &max)) {
124     return false;
125   }
126
127   return radius * 2 == max;
128 }
129 #endif
130
131 int GetEventFlagsFromXState(unsigned int state) {
132   int flags = 0;
133   if (state & ControlMask)
134     flags |= ui::EF_CONTROL_DOWN;
135   if (state & ShiftMask)
136     flags |= ui::EF_SHIFT_DOWN;
137   if (state & Mod1Mask)
138     flags |= ui::EF_ALT_DOWN;
139   if (state & LockMask)
140     flags |= ui::EF_CAPS_LOCK_DOWN;
141   if (state & Mod5Mask)
142     flags |= ui::EF_ALTGR_DOWN;
143   if (state & Button1Mask)
144     flags |= ui::EF_LEFT_MOUSE_BUTTON;
145   if (state & Button2Mask)
146     flags |= ui::EF_MIDDLE_MOUSE_BUTTON;
147   if (state & Button3Mask)
148     flags |= ui::EF_RIGHT_MOUSE_BUTTON;
149   return flags;
150 }
151
152 int GetEventFlagsFromXKeyEvent(XEvent* xevent) {
153   DCHECK(xevent->type == KeyPress || xevent->type == KeyRelease);
154
155 #if defined(OS_CHROMEOS)
156   const int ime_fabricated_flag = 0;
157 #else
158   // XIM fabricates key events for the character compositions by XK_Multi_key.
159   // For example, when a user hits XK_Multi_key, XK_apostrophe, and XK_e in
160   // order to input "é", then XIM generates a key event with keycode=0 and
161   // state=0 for the composition, and the sequence of X11 key events will be
162   // XK_Multi_key, XK_apostrophe, **NoSymbol**, and XK_e.
163   //
164   // We have to send these fabricated key events to XIM so it can correctly
165   // handle the character compositions.
166   const bool fabricated_by_xim =
167       xevent->xkey.keycode == 0 && xevent->xkey.state == 0;
168   const int ime_fabricated_flag =
169       fabricated_by_xim ? ui::EF_IME_FABRICATED_KEY : 0;
170 #endif
171
172   return GetEventFlagsFromXState(xevent->xkey.state) |
173       (IsKeypadKey(XLookupKeysym(&xevent->xkey, 0)) ? ui::EF_NUMPAD_KEY : 0) |
174       ime_fabricated_flag;
175 }
176
177 // Get the event flag for the button in XButtonEvent. During a ButtonPress
178 // event, |state| in XButtonEvent does not include the button that has just been
179 // pressed. Instead |state| contains flags for the buttons (if any) that had
180 // already been pressed before the current button, and |button| stores the most
181 // current pressed button. So, if you press down left mouse button, and while
182 // pressing it down, press down the right mouse button, then for the latter
183 // event, |state| would have Button1Mask set but not Button3Mask, and |button|
184 // would be 3.
185 int GetEventFlagsForButton(int button) {
186   switch (button) {
187     case 1:
188       return ui::EF_LEFT_MOUSE_BUTTON;
189     case 2:
190       return ui::EF_MIDDLE_MOUSE_BUTTON;
191     case 3:
192       return ui::EF_RIGHT_MOUSE_BUTTON;
193     default:
194       return 0;
195   }
196 }
197
198 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) {
199   int buttonflags = 0;
200   for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) {
201     if (XIMaskIsSet(xievent->buttons.mask, i)) {
202       int button = (xievent->sourceid == xievent->deviceid) ?
203                    ui::DeviceDataManager::GetInstance()->GetMappedButton(i) : i;
204       buttonflags |= GetEventFlagsForButton(button);
205     }
206   }
207   return buttonflags;
208 }
209
210 ui::EventType GetTouchEventType(const base::NativeEvent& native_event) {
211   XIDeviceEvent* event =
212       static_cast<XIDeviceEvent*>(native_event->xcookie.data);
213 #if defined(USE_XI2_MT)
214   switch(event->evtype) {
215     case XI_TouchBegin:
216       return TouchEventIsGeneratedHack(native_event) ? ui::ET_UNKNOWN :
217                                                        ui::ET_TOUCH_PRESSED;
218     case XI_TouchUpdate:
219       return TouchEventIsGeneratedHack(native_event) ? ui::ET_UNKNOWN :
220                                                        ui::ET_TOUCH_MOVED;
221     case XI_TouchEnd:
222       return TouchEventIsGeneratedHack(native_event) ? ui::ET_TOUCH_CANCELLED :
223                                                        ui::ET_TOUCH_RELEASED;
224   }
225 #endif  // defined(USE_XI2_MT)
226
227   DCHECK(ui::TouchFactory::GetInstance()->IsTouchDevice(event->sourceid));
228   switch (event->evtype) {
229     case XI_ButtonPress:
230       return ui::ET_TOUCH_PRESSED;
231     case XI_ButtonRelease:
232       return ui::ET_TOUCH_RELEASED;
233     case XI_Motion:
234       // Should not convert any emulated Motion event from touch device to
235       // touch event.
236       if (!(event->flags & XIPointerEmulated) &&
237           GetButtonMaskForX2Event(event))
238         return ui::ET_TOUCH_MOVED;
239       return ui::ET_UNKNOWN;
240     default:
241       NOTREACHED();
242   }
243   return ui::ET_UNKNOWN;
244 }
245
246 double GetTouchParamFromXEvent(XEvent* xev,
247                               ui::DeviceDataManager::DataType val,
248                               double default_value) {
249   ui::DeviceDataManager::GetInstance()->GetEventData(
250       *xev, val, &default_value);
251   return default_value;
252 }
253
254 }  // namespace
255
256 namespace ui {
257
258 void UpdateDeviceList() {
259   XDisplay* display = gfx::GetXDisplay();
260   DeviceListCacheX::GetInstance()->UpdateDeviceList(display);
261   TouchFactory::GetInstance()->UpdateDeviceList(display);
262   DeviceDataManager::GetInstance()->UpdateDeviceList(display);
263 }
264
265 EventType EventTypeFromNative(const base::NativeEvent& native_event) {
266   switch (native_event->type) {
267     case KeyPress:
268       return ET_KEY_PRESSED;
269     case KeyRelease:
270       return ET_KEY_RELEASED;
271     case ButtonPress:
272       if (static_cast<int>(native_event->xbutton.button) >= kMinWheelButton &&
273           static_cast<int>(native_event->xbutton.button) <= kMaxWheelButton)
274         return ET_MOUSEWHEEL;
275       return ET_MOUSE_PRESSED;
276     case ButtonRelease:
277       // Drop wheel events; we should've already scrolled on the press.
278       if (static_cast<int>(native_event->xbutton.button) >= kMinWheelButton &&
279           static_cast<int>(native_event->xbutton.button) <= kMaxWheelButton)
280         return ET_UNKNOWN;
281       return ET_MOUSE_RELEASED;
282     case MotionNotify:
283       if (native_event->xmotion.state &
284           (Button1Mask | Button2Mask | Button3Mask))
285         return ET_MOUSE_DRAGGED;
286       return ET_MOUSE_MOVED;
287     case EnterNotify:
288       // The standard on Windows is to send a MouseMove event when the mouse
289       // first enters a window instead of sending a special mouse enter event.
290       // To be consistent we follow the same style.
291       return ET_MOUSE_MOVED;
292     case LeaveNotify:
293       return ET_MOUSE_EXITED;
294     case GenericEvent: {
295       TouchFactory* factory = TouchFactory::GetInstance();
296       if (!factory->ShouldProcessXI2Event(native_event))
297         return ET_UNKNOWN;
298
299       XIDeviceEvent* xievent =
300           static_cast<XIDeviceEvent*>(native_event->xcookie.data);
301
302       // This check works only for master and floating slave devices. That is
303       // why it is necessary to check for the XI_Touch* events in the following
304       // switch statement to account for attached-slave touchscreens.
305       if (factory->IsTouchDevice(xievent->sourceid))
306         return GetTouchEventType(native_event);
307
308       switch (xievent->evtype) {
309         case XI_TouchBegin:
310           return ui::ET_TOUCH_PRESSED;
311         case XI_TouchUpdate:
312           return ui::ET_TOUCH_MOVED;
313         case XI_TouchEnd:
314           return ui::ET_TOUCH_RELEASED;
315         case XI_ButtonPress: {
316           int button = EventButtonFromNative(native_event);
317           if (button >= kMinWheelButton && button <= kMaxWheelButton)
318             return ET_MOUSEWHEEL;
319           return ET_MOUSE_PRESSED;
320         }
321         case XI_ButtonRelease: {
322           int button = EventButtonFromNative(native_event);
323           // Drop wheel events; we should've already scrolled on the press.
324           if (button >= kMinWheelButton && button <= kMaxWheelButton)
325             return ET_UNKNOWN;
326           return ET_MOUSE_RELEASED;
327         }
328         case XI_Motion: {
329           bool is_cancel;
330           if (GetFlingData(native_event, NULL, NULL, NULL, NULL, &is_cancel)) {
331             return is_cancel ? ET_SCROLL_FLING_CANCEL : ET_SCROLL_FLING_START;
332           } else if (DeviceDataManager::GetInstance()->IsScrollEvent(
333               native_event)) {
334             return IsTouchpadEvent(native_event) ? ET_SCROLL : ET_MOUSEWHEEL;
335           } else if (DeviceDataManager::GetInstance()->IsCMTMetricsEvent(
336               native_event)) {
337             return ET_UMA_DATA;
338           } else if (GetButtonMaskForX2Event(xievent)) {
339             return ET_MOUSE_DRAGGED;
340           } else {
341             return ET_MOUSE_MOVED;
342           }
343         }
344       }
345     }
346     default:
347       break;
348   }
349   return ET_UNKNOWN;
350 }
351
352 int EventFlagsFromNative(const base::NativeEvent& native_event) {
353   switch (native_event->type) {
354     case KeyPress:
355     case KeyRelease: {
356       XModifierStateWatcher::GetInstance()->UpdateStateFromEvent(native_event);
357       return GetEventFlagsFromXKeyEvent(native_event);
358     }
359     case ButtonPress:
360     case ButtonRelease: {
361       int flags = GetEventFlagsFromXState(native_event->xbutton.state);
362       const EventType type = EventTypeFromNative(native_event);
363       if (type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED)
364         flags |= GetEventFlagsForButton(native_event->xbutton.button);
365       return flags;
366     }
367     case EnterNotify:
368     case LeaveNotify:
369       return GetEventFlagsFromXState(native_event->xcrossing.state);
370     case MotionNotify:
371       return GetEventFlagsFromXState(native_event->xmotion.state);
372     case GenericEvent: {
373       XIDeviceEvent* xievent =
374           static_cast<XIDeviceEvent*>(native_event->xcookie.data);
375
376       switch (xievent->evtype) {
377 #if defined(USE_XI2_MT)
378         case XI_TouchBegin:
379         case XI_TouchUpdate:
380         case XI_TouchEnd:
381           return GetButtonMaskForX2Event(xievent) |
382                  GetEventFlagsFromXState(xievent->mods.effective) |
383                  GetEventFlagsFromXState(
384                      XModifierStateWatcher::GetInstance()->state());
385           break;
386 #endif
387         case XI_ButtonPress:
388         case XI_ButtonRelease: {
389           const bool touch =
390               TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid);
391           int flags = GetButtonMaskForX2Event(xievent) |
392               GetEventFlagsFromXState(xievent->mods.effective);
393           if (touch) {
394             flags |= GetEventFlagsFromXState(
395                 XModifierStateWatcher::GetInstance()->state());
396           }
397
398           const EventType type = EventTypeFromNative(native_event);
399           int button = EventButtonFromNative(native_event);
400           if ((type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED) && !touch)
401             flags |= GetEventFlagsForButton(button);
402           return flags;
403         }
404         case XI_Motion:
405            return GetButtonMaskForX2Event(xievent) |
406                   GetEventFlagsFromXState(xievent->mods.effective);
407       }
408     }
409   }
410   return 0;
411 }
412
413 base::TimeDelta EventTimeFromNative(const base::NativeEvent& native_event) {
414   switch(native_event->type) {
415     case KeyPress:
416     case KeyRelease:
417       return base::TimeDelta::FromMilliseconds(native_event->xkey.time);
418     case ButtonPress:
419     case ButtonRelease:
420       return base::TimeDelta::FromMilliseconds(native_event->xbutton.time);
421       break;
422     case MotionNotify:
423       return base::TimeDelta::FromMilliseconds(native_event->xmotion.time);
424       break;
425     case EnterNotify:
426     case LeaveNotify:
427       return base::TimeDelta::FromMilliseconds(native_event->xcrossing.time);
428       break;
429     case GenericEvent: {
430       double start, end;
431       double touch_timestamp;
432       if (GetGestureTimes(native_event, &start, &end)) {
433         // If the driver supports gesture times, use them.
434         return base::TimeDelta::FromMicroseconds(end * 1000000);
435       } else if (DeviceDataManager::GetInstance()->GetEventData(*native_event,
436                  DeviceDataManager::DT_TOUCH_RAW_TIMESTAMP, &touch_timestamp)) {
437         return base::TimeDelta::FromMicroseconds(touch_timestamp * 1000000);
438       } else {
439         XIDeviceEvent* xide =
440             static_cast<XIDeviceEvent*>(native_event->xcookie.data);
441         return base::TimeDelta::FromMilliseconds(xide->time);
442       }
443       break;
444     }
445   }
446   NOTREACHED();
447   return base::TimeDelta();
448 }
449
450 gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) {
451   switch (native_event->type) {
452     case EnterNotify:
453     case LeaveNotify:
454       return gfx::Point(native_event->xcrossing.x, native_event->xcrossing.y);
455     case ButtonPress:
456     case ButtonRelease:
457       return gfx::Point(native_event->xbutton.x, native_event->xbutton.y);
458     case MotionNotify:
459       return gfx::Point(native_event->xmotion.x, native_event->xmotion.y);
460     case GenericEvent: {
461       XIDeviceEvent* xievent =
462           static_cast<XIDeviceEvent*>(native_event->xcookie.data);
463       return gfx::Point(static_cast<int>(xievent->event_x),
464                         static_cast<int>(xievent->event_y));
465     }
466   }
467   return gfx::Point();
468 }
469
470 gfx::Point EventSystemLocationFromNative(
471     const base::NativeEvent& native_event) {
472   switch (native_event->type) {
473     case EnterNotify:
474     case LeaveNotify: {
475       return gfx::Point(native_event->xcrossing.x_root,
476                         native_event->xcrossing.y_root);
477     }
478     case ButtonPress:
479     case ButtonRelease: {
480       return gfx::Point(native_event->xbutton.x_root,
481                         native_event->xbutton.y_root);
482     }
483     case MotionNotify: {
484       return gfx::Point(native_event->xmotion.x_root,
485                         native_event->xmotion.y_root);
486     }
487     case GenericEvent: {
488       XIDeviceEvent* xievent =
489           static_cast<XIDeviceEvent*>(native_event->xcookie.data);
490       return gfx::Point(xievent->root_x, xievent->root_y);
491     }
492   }
493
494   return gfx::Point();
495 }
496
497 int EventButtonFromNative(const base::NativeEvent& native_event) {
498   CHECK_EQ(GenericEvent, native_event->type);
499   XIDeviceEvent* xievent =
500       static_cast<XIDeviceEvent*>(native_event->xcookie.data);
501   int button = xievent->detail;
502
503   return (xievent->sourceid == xievent->deviceid) ?
504          DeviceDataManager::GetInstance()->GetMappedButton(button) : button;
505 }
506
507 KeyboardCode KeyboardCodeFromNative(const base::NativeEvent& native_event) {
508   return KeyboardCodeFromXKeyEvent(native_event);
509 }
510
511 const char* CodeFromNative(const base::NativeEvent& native_event) {
512   return CodeFromXEvent(native_event);
513 }
514
515 int GetChangedMouseButtonFlagsFromNative(
516     const base::NativeEvent& native_event) {
517   switch (native_event->type) {
518     case ButtonPress:
519     case ButtonRelease:
520       return GetEventFlagsFromXState(native_event->xbutton.state);
521     case GenericEvent: {
522       XIDeviceEvent* xievent =
523           static_cast<XIDeviceEvent*>(native_event->xcookie.data);
524       switch (xievent->evtype) {
525         case XI_ButtonPress:
526         case XI_ButtonRelease:
527           return GetEventFlagsForButton(EventButtonFromNative(native_event));
528         default:
529           break;
530       }
531     }
532     default:
533       break;
534   }
535   return 0;
536 }
537
538 gfx::Vector2d GetMouseWheelOffset(const base::NativeEvent& native_event) {
539   float x_offset, y_offset;
540   if (GetScrollOffsets(
541       native_event, &x_offset, &y_offset, NULL, NULL, NULL)) {
542     return gfx::Vector2d(static_cast<int>(x_offset),
543                          static_cast<int>(y_offset));
544   }
545
546   int button = native_event->type == GenericEvent ?
547       EventButtonFromNative(native_event) : native_event->xbutton.button;
548
549   switch (button) {
550     case 4:
551       return gfx::Vector2d(0, kWheelScrollAmount);
552     case 5:
553       return gfx::Vector2d(0, -kWheelScrollAmount);
554     case 6:
555       return gfx::Vector2d(kWheelScrollAmount, 0);
556     case 7:
557       return gfx::Vector2d(-kWheelScrollAmount, 0);
558     default:
559       return gfx::Vector2d();
560   }
561 }
562
563 void ClearTouchIdIfReleased(const base::NativeEvent& xev) {
564   ui::EventType type = ui::EventTypeFromNative(xev);
565   if (type == ui::ET_TOUCH_CANCELLED ||
566       type == ui::ET_TOUCH_RELEASED) {
567     ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
568     ui::DeviceDataManager* manager = ui::DeviceDataManager::GetInstance();
569     double tracking_id;
570     if (manager->GetEventData(
571         *xev, ui::DeviceDataManager::DT_TOUCH_TRACKING_ID, &tracking_id)) {
572       factory->ReleaseSlotForTrackingID(tracking_id);
573     }
574   }
575 }
576
577 int GetTouchId(const base::NativeEvent& xev) {
578   double slot = 0;
579   ui::DeviceDataManager* manager = ui::DeviceDataManager::GetInstance();
580   double tracking_id;
581   if (!manager->GetEventData(
582       *xev, ui::DeviceDataManager::DT_TOUCH_TRACKING_ID, &tracking_id)) {
583     LOG(ERROR) << "Could not get the tracking ID for the event. Using 0.";
584   } else {
585     ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
586     slot = factory->GetSlotForTrackingID(tracking_id);
587   }
588   return slot;
589 }
590
591 float GetTouchRadiusX(const base::NativeEvent& native_event) {
592   return GetTouchParamFromXEvent(native_event,
593       ui::DeviceDataManager::DT_TOUCH_MAJOR, 0.0) / 2.0;
594 }
595
596 float GetTouchRadiusY(const base::NativeEvent& native_event) {
597   return GetTouchParamFromXEvent(native_event,
598       ui::DeviceDataManager::DT_TOUCH_MINOR, 0.0) / 2.0;
599 }
600
601 float GetTouchAngle(const base::NativeEvent& native_event) {
602   return GetTouchParamFromXEvent(native_event,
603       ui::DeviceDataManager::DT_TOUCH_ORIENTATION, 0.0) / 2.0;
604 }
605
606 float GetTouchForce(const base::NativeEvent& native_event) {
607   double force = 0.0;
608   force = GetTouchParamFromXEvent(native_event,
609       ui::DeviceDataManager::DT_TOUCH_PRESSURE, 0.0);
610   unsigned int deviceid =
611       static_cast<XIDeviceEvent*>(native_event->xcookie.data)->sourceid;
612   // Force is normalized to fall into [0, 1]
613   if (!ui::DeviceDataManager::GetInstance()->NormalizeData(
614       deviceid, ui::DeviceDataManager::DT_TOUCH_PRESSURE, &force))
615     force = 0.0;
616   return force;
617 }
618
619 bool GetScrollOffsets(const base::NativeEvent& native_event,
620                       float* x_offset,
621                       float* y_offset,
622                       float* x_offset_ordinal,
623                       float* y_offset_ordinal,
624                       int* finger_count) {
625   if (!DeviceDataManager::GetInstance()->IsScrollEvent(native_event))
626     return false;
627
628   // Temp values to prevent passing NULLs to DeviceDataManager.
629   float x_offset_, y_offset_;
630   float x_offset_ordinal_, y_offset_ordinal_;
631   int finger_count_;
632   if (!x_offset)
633     x_offset = &x_offset_;
634   if (!y_offset)
635     y_offset = &y_offset_;
636   if (!x_offset_ordinal)
637     x_offset_ordinal = &x_offset_ordinal_;
638   if (!y_offset_ordinal)
639     y_offset_ordinal = &y_offset_ordinal_;
640   if (!finger_count)
641     finger_count = &finger_count_;
642
643   DeviceDataManager::GetInstance()->GetScrollOffsets(
644       native_event,
645       x_offset, y_offset,
646       x_offset_ordinal, y_offset_ordinal,
647       finger_count);
648   return true;
649 }
650
651 bool GetFlingData(const base::NativeEvent& native_event,
652                   float* vx,
653                   float* vy,
654                   float* vx_ordinal,
655                   float* vy_ordinal,
656                   bool* is_cancel) {
657   if (!DeviceDataManager::GetInstance()->IsFlingEvent(native_event))
658     return false;
659
660   float vx_, vy_;
661   float vx_ordinal_, vy_ordinal_;
662   bool is_cancel_;
663   if (!vx)
664     vx = &vx_;
665   if (!vy)
666     vy = &vy_;
667   if (!vx_ordinal)
668     vx_ordinal = &vx_ordinal_;
669   if (!vy_ordinal)
670     vy_ordinal = &vy_ordinal_;
671   if (!is_cancel)
672     is_cancel = &is_cancel_;
673
674   DeviceDataManager::GetInstance()->GetFlingData(
675       native_event, vx, vy, vx_ordinal, vy_ordinal, is_cancel);
676   return true;
677 }
678
679 bool GetGestureTimes(const base::NativeEvent& native_event,
680                      double* start_time,
681                      double* end_time) {
682   if (!DeviceDataManager::GetInstance()->HasGestureTimes(native_event))
683     return false;
684
685   double start_time_, end_time_;
686   if (!start_time)
687     start_time = &start_time_;
688   if (!end_time)
689     end_time = &end_time_;
690
691   DeviceDataManager::GetInstance()->GetGestureTimes(
692       native_event, start_time, end_time);
693   return true;
694 }
695
696 void SetNaturalScroll(bool enabled) {
697   DeviceDataManager::GetInstance()->set_natural_scroll_enabled(enabled);
698 }
699
700 bool IsNaturalScrollEnabled() {
701   return DeviceDataManager::GetInstance()->natural_scroll_enabled();
702 }
703
704 bool IsTouchpadEvent(const base::NativeEvent& event) {
705   return DeviceDataManager::GetInstance()->IsTouchpadXInputEvent(event);
706 }
707
708 }  // namespace ui