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
3 // found in the LICENSE file.
5 #include "ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cros.h"
7 #include <gestures/gestures.h>
8 #include <libevdev/libevdev.h>
9 #include <linux/input.h>
11 #include "base/strings/stringprintf.h"
12 #include "base/timer/timer.h"
13 #include "ui/events/event.h"
14 #include "ui/events/keycodes/dom4/keycode_converter.h"
15 #include "ui/events/ozone/evdev/cursor_delegate_evdev.h"
16 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
17 #include "ui/events/ozone/evdev/event_device_info.h"
18 #include "ui/events/ozone/evdev/event_device_util.h"
19 #include "ui/events/ozone/evdev/keyboard_util_evdev.h"
20 #include "ui/events/ozone/evdev/libgestures_glue/gesture_property_provider.h"
21 #include "ui/events/ozone/evdev/libgestures_glue/gesture_timer_provider.h"
22 #include "ui/gfx/geometry/point_f.h"
28 // Convert libevdev device class to libgestures device class.
29 GestureInterpreterDeviceClass
GestureDeviceClass(Evdev
* evdev
) {
30 switch (evdev
->info
.evdev_class
) {
32 return GESTURES_DEVCLASS_MOUSE
;
33 case EvdevClassMultitouchMouse
:
34 return GESTURES_DEVCLASS_MULTITOUCH_MOUSE
;
35 case EvdevClassTouchpad
:
36 return GESTURES_DEVCLASS_TOUCHPAD
;
37 case EvdevClassTouchscreen
:
38 return GESTURES_DEVCLASS_TOUCHSCREEN
;
40 return GESTURES_DEVCLASS_UNKNOWN
;
44 // Convert libevdev state to libgestures hardware properties.
45 HardwareProperties
GestureHardwareProperties(
47 const GestureDeviceProperties
* props
) {
48 HardwareProperties hwprops
;
49 hwprops
.left
= props
->area_left
;
50 hwprops
.top
= props
->area_top
;
51 hwprops
.right
= props
->area_right
;
52 hwprops
.bottom
= props
->area_bottom
;
53 hwprops
.res_x
= props
->res_x
;
54 hwprops
.res_y
= props
->res_y
;
55 hwprops
.screen_x_dpi
= 133;
56 hwprops
.screen_y_dpi
= 133;
57 hwprops
.orientation_minimum
= props
->orientation_minimum
;
58 hwprops
.orientation_maximum
= props
->orientation_maximum
;
59 hwprops
.max_finger_cnt
= Event_Get_Slot_Count(evdev
);
60 hwprops
.max_touch_cnt
= Event_Get_Touch_Count_Max(evdev
);
61 hwprops
.supports_t5r2
= Event_Get_T5R2(evdev
);
62 hwprops
.support_semi_mt
= Event_Get_Semi_MT(evdev
);
63 /* buttonpad means a physical button under the touch surface */
64 hwprops
.is_button_pad
= Event_Get_Button_Pad(evdev
);
68 // Callback from libgestures when a gesture is ready.
69 void OnGestureReadyHelper(void* client_data
, const Gesture
* gesture
) {
70 GestureInterpreterLibevdevCros
* interpreter
=
71 static_cast<GestureInterpreterLibevdevCros
*>(client_data
);
72 interpreter
->OnGestureReady(gesture
);
75 // Convert gestures timestamp (stime_t) to ui::Event timestamp.
76 base::TimeDelta
StimeToTimedelta(stime_t timestamp
) {
77 return base::TimeDelta::FromMicroseconds(timestamp
*
78 base::Time::kMicrosecondsPerSecond
);
81 // Number of fingers for scroll gestures.
82 const int kGestureScrollFingerCount
= 2;
84 // Number of fingers for swipe gestures.
85 const int kGestureSwipeFingerCount
= 3;
89 GestureInterpreterLibevdevCros::GestureInterpreterLibevdevCros(
91 CursorDelegateEvdev
* cursor
,
92 GesturePropertyProvider
* property_provider
,
93 DeviceEventDispatcherEvdev
* dispatcher
)
97 property_provider_(property_provider
),
98 dispatcher_(dispatcher
),
101 device_properties_(new GestureDeviceProperties
) {
102 memset(&prev_key_state_
, 0, sizeof(prev_key_state_
));
105 GestureInterpreterLibevdevCros::~GestureInterpreterLibevdevCros() {
106 // Note that this destructor got called after the evdev device node has been
107 // closed. Therefore, all clean-up codes here shouldn't depend on the device
108 // information (except for the pointer address itself).
110 // Clean-up if the gesture interpreter has been successfully created.
113 GestureInterpreterSetCallback(interpreter_
, NULL
, NULL
);
114 GestureInterpreterSetPropProvider(interpreter_
, NULL
, NULL
);
115 GestureInterpreterSetTimerProvider(interpreter_
, NULL
, NULL
);
116 DeleteGestureInterpreter(interpreter_
);
120 // Unregister device from the gesture property provider.
121 GesturesPropFunctionsWrapper::UnregisterDevice(this);
124 void GestureInterpreterLibevdevCros::OnLibEvdevCrosOpen(
126 EventStateRec
* evstate
) {
127 DCHECK(evdev
->info
.is_monotonic
) << "libevdev must use monotonic timestamps";
128 VLOG(9) << "HACK DO NOT REMOVE OR LINK WILL FAIL" << (void*)gestures_log
;
130 // Set device pointer and initialize properties.
132 GesturesPropFunctionsWrapper::InitializeDeviceProperties(
133 this, device_properties_
.get());
134 HardwareProperties hwprops
=
135 GestureHardwareProperties(evdev
, device_properties_
.get());
136 GestureInterpreterDeviceClass devclass
= GestureDeviceClass(evdev
);
137 is_mouse_
= property_provider_
->IsDeviceIdOfType(id_
, DT_MOUSE
);
139 // Create & initialize GestureInterpreter.
140 DCHECK(!interpreter_
);
141 interpreter_
= NewGestureInterpreter();
142 GestureInterpreterSetPropProvider(
144 const_cast<GesturesPropProvider
*>(&kGesturePropProvider
),
146 GestureInterpreterInitialize(interpreter_
, devclass
);
147 GestureInterpreterSetHardwareProperties(interpreter_
, &hwprops
);
148 GestureInterpreterSetTimerProvider(
150 const_cast<GesturesTimerProvider
*>(&kGestureTimerProvider
),
152 GestureInterpreterSetCallback(interpreter_
, OnGestureReadyHelper
, this);
155 void GestureInterpreterLibevdevCros::OnLibEvdevCrosEvent(Evdev
* evdev
,
156 EventStateRec
* evstate
,
157 const timeval
& time
) {
158 // If the device has keys no it, dispatch any presses/release.
159 DispatchChangedKeys(evdev
, time
);
161 HardwareState hwstate
;
162 memset(&hwstate
, 0, sizeof(hwstate
));
163 hwstate
.timestamp
= StimeFromTimeval(&time
);
166 hwstate
.rel_x
= evstate
->rel_x
;
167 hwstate
.rel_y
= evstate
->rel_y
;
168 hwstate
.rel_wheel
= evstate
->rel_wheel
;
169 hwstate
.rel_hwheel
= evstate
->rel_hwheel
;
172 FingerState fingers
[Event_Get_Slot_Count(evdev
)];
173 memset(&fingers
, 0, sizeof(fingers
));
174 int current_finger
= 0;
175 for (int i
= 0; i
< evstate
->slot_count
; i
++) {
176 MtSlotPtr slot
= &evstate
->slots
[i
];
177 if (slot
->tracking_id
== -1)
179 fingers
[current_finger
].touch_major
= slot
->touch_major
;
180 fingers
[current_finger
].touch_minor
= slot
->touch_minor
;
181 fingers
[current_finger
].width_major
= slot
->width_major
;
182 fingers
[current_finger
].width_minor
= slot
->width_minor
;
183 fingers
[current_finger
].pressure
= slot
->pressure
;
184 fingers
[current_finger
].orientation
= slot
->orientation
;
185 fingers
[current_finger
].position_x
= slot
->position_x
;
186 fingers
[current_finger
].position_y
= slot
->position_y
;
187 fingers
[current_finger
].tracking_id
= slot
->tracking_id
;
190 hwstate
.touch_cnt
= Event_Get_Touch_Count(evdev
);
191 hwstate
.finger_cnt
= current_finger
;
192 hwstate
.fingers
= fingers
;
195 if (Event_Get_Button_Left(evdev
))
196 hwstate
.buttons_down
|= GESTURES_BUTTON_LEFT
;
197 if (Event_Get_Button_Middle(evdev
))
198 hwstate
.buttons_down
|= GESTURES_BUTTON_MIDDLE
;
199 if (Event_Get_Button_Right(evdev
))
200 hwstate
.buttons_down
|= GESTURES_BUTTON_RIGHT
;
202 GestureInterpreterPushHardwareState(interpreter_
, &hwstate
);
205 void GestureInterpreterLibevdevCros::SetAllowedKeys(
206 scoped_ptr
<std::set
<DomCode
>> allowed_keys
) {
208 allowed_keys_
.reset();
212 allowed_keys_
.reset(new std::set
<int>());
213 for (const auto& it
: *allowed_keys
) {
215 NativeCodeToEvdevCode(KeycodeConverter::DomCodeToNativeKeycode(it
));
216 allowed_keys_
->insert(evdev_code
);
220 void GestureInterpreterLibevdevCros::AllowAllKeys() {
221 allowed_keys_
.reset();
224 void GestureInterpreterLibevdevCros::OnGestureReady(const Gesture
* gesture
) {
225 switch (gesture
->type
) {
226 case kGestureTypeMove
:
227 OnGestureMove(gesture
, &gesture
->details
.move
);
229 case kGestureTypeScroll
:
230 OnGestureScroll(gesture
, &gesture
->details
.scroll
);
232 case kGestureTypeButtonsChange
:
233 OnGestureButtonsChange(gesture
, &gesture
->details
.buttons
);
235 case kGestureTypeContactInitiated
:
236 OnGestureContactInitiated(gesture
);
238 case kGestureTypeFling
:
239 OnGestureFling(gesture
, &gesture
->details
.fling
);
241 case kGestureTypeSwipe
:
242 OnGestureSwipe(gesture
, &gesture
->details
.swipe
);
244 case kGestureTypeSwipeLift
:
245 OnGestureSwipeLift(gesture
, &gesture
->details
.swipe_lift
);
247 case kGestureTypePinch
:
248 OnGesturePinch(gesture
, &gesture
->details
.pinch
);
250 case kGestureTypeMetrics
:
251 OnGestureMetrics(gesture
, &gesture
->details
.metrics
);
254 LOG(WARNING
) << base::StringPrintf("Unrecognized gesture type (%u)",
260 void GestureInterpreterLibevdevCros::OnGestureMove(const Gesture
* gesture
,
261 const GestureMove
* move
) {
262 DVLOG(3) << base::StringPrintf("Gesture Move: (%f, %f) [%f, %f]",
268 return; // No cursor!
270 cursor_
->MoveCursor(gfx::Vector2dF(move
->dx
, move
->dy
));
271 // TODO(spang): Use move->ordinal_dx, move->ordinal_dy
272 // TODO(spang): Use move->start_time, move->end_time
273 dispatcher_
->DispatchMouseMoveEvent(
274 MouseMoveEventParams(id_
, cursor_
->GetLocation()));
277 void GestureInterpreterLibevdevCros::OnGestureScroll(
278 const Gesture
* gesture
,
279 const GestureScroll
* scroll
) {
280 DVLOG(3) << base::StringPrintf("Gesture Scroll: (%f, %f) [%f, %f]",
286 return; // No cursor!
288 // TODO(spang): Use scroll->start_time
290 dispatcher_
->DispatchMouseWheelEvent(MouseWheelEventParams(
291 id_
, cursor_
->GetLocation(), gfx::Vector2d(scroll
->dx
, scroll
->dy
)));
293 dispatcher_
->DispatchScrollEvent(ScrollEventParams(
294 id_
, ET_SCROLL
, cursor_
->GetLocation(),
295 gfx::Vector2dF(scroll
->dx
, scroll
->dy
),
296 gfx::Vector2dF(scroll
->ordinal_dx
, scroll
->ordinal_dy
),
297 kGestureScrollFingerCount
, StimeToTimedelta(gesture
->end_time
)));
301 void GestureInterpreterLibevdevCros::OnGestureButtonsChange(
302 const Gesture
* gesture
,
303 const GestureButtonsChange
* buttons
) {
304 DVLOG(3) << base::StringPrintf("Gesture Button Change: down=0x%02x up=0x%02x",
309 return; // No cursor!
311 // TODO(spang): Use buttons->start_time, buttons->end_time
312 if (buttons
->down
& GESTURES_BUTTON_LEFT
)
313 DispatchMouseButton(BTN_LEFT
, true);
314 if (buttons
->down
& GESTURES_BUTTON_MIDDLE
)
315 DispatchMouseButton(BTN_MIDDLE
, true);
316 if (buttons
->down
& GESTURES_BUTTON_RIGHT
)
317 DispatchMouseButton(BTN_RIGHT
, true);
318 if (buttons
->up
& GESTURES_BUTTON_LEFT
)
319 DispatchMouseButton(BTN_LEFT
, false);
320 if (buttons
->up
& GESTURES_BUTTON_MIDDLE
)
321 DispatchMouseButton(BTN_MIDDLE
, false);
322 if (buttons
->up
& GESTURES_BUTTON_RIGHT
)
323 DispatchMouseButton(BTN_RIGHT
, false);
326 void GestureInterpreterLibevdevCros::OnGestureContactInitiated(
327 const Gesture
* gesture
) {
328 // TODO(spang): handle contact initiated.
331 void GestureInterpreterLibevdevCros::OnGestureFling(const Gesture
* gesture
,
332 const GestureFling
* fling
) {
333 DVLOG(3) << base::StringPrintf(
334 "Gesture Fling: (%f, %f) [%f, %f] fling_state=%d",
342 return; // No cursor!
345 (fling
->fling_state
== GESTURES_FLING_START
? ET_SCROLL_FLING_START
346 : ET_SCROLL_FLING_CANCEL
);
348 // Fling is like 2-finger scrolling but with velocity instead of displacement.
349 dispatcher_
->DispatchScrollEvent(ScrollEventParams(
350 id_
, type
, cursor_
->GetLocation(), gfx::Vector2dF(fling
->vx
, fling
->vy
),
351 gfx::Vector2dF(fling
->ordinal_vx
, fling
->ordinal_vy
),
352 kGestureScrollFingerCount
, StimeToTimedelta(gesture
->end_time
)));
355 void GestureInterpreterLibevdevCros::OnGestureSwipe(const Gesture
* gesture
,
356 const GestureSwipe
* swipe
) {
357 DVLOG(3) << base::StringPrintf("Gesture Swipe: (%f, %f) [%f, %f]",
364 return; // No cursor!
366 // Swipe is 3-finger scrolling.
367 dispatcher_
->DispatchScrollEvent(ScrollEventParams(
368 id_
, ET_SCROLL
, cursor_
->GetLocation(),
369 gfx::Vector2dF(swipe
->dx
, swipe
->dy
),
370 gfx::Vector2dF(swipe
->ordinal_dx
, swipe
->ordinal_dy
),
371 kGestureSwipeFingerCount
, StimeToTimedelta(gesture
->end_time
)));
374 void GestureInterpreterLibevdevCros::OnGestureSwipeLift(
375 const Gesture
* gesture
,
376 const GestureSwipeLift
* swipelift
) {
377 DVLOG(3) << base::StringPrintf("Gesture Swipe Lift");
380 return; // No cursor!
382 // Turn a swipe lift into a fling start.
383 // TODO(spang): Figure out why and put it in this comment.
385 dispatcher_
->DispatchScrollEvent(ScrollEventParams(
386 id_
, ET_SCROLL_FLING_START
, cursor_
->GetLocation(),
387 gfx::Vector2dF() /* delta */, gfx::Vector2dF() /* ordinal_delta */,
388 kGestureScrollFingerCount
, StimeToTimedelta(gesture
->end_time
)));
391 void GestureInterpreterLibevdevCros::OnGesturePinch(const Gesture
* gesture
,
392 const GesturePinch
* pinch
) {
393 DVLOG(3) << base::StringPrintf(
394 "Gesture Pinch: dz=%f [%f]", pinch
->dz
, pinch
->ordinal_dz
);
397 return; // No cursor!
402 void GestureInterpreterLibevdevCros::OnGestureMetrics(
403 const Gesture
* gesture
,
404 const GestureMetrics
* metrics
) {
405 DVLOG(3) << base::StringPrintf("Gesture Metrics: [%f, %f] type=%d",
412 void GestureInterpreterLibevdevCros::DispatchMouseButton(unsigned int button
,
414 bool allow_remap
= is_mouse_
;
415 dispatcher_
->DispatchMouseButtonEvent(MouseButtonEventParams(
416 id_
, cursor_
->GetLocation(), button
, down
, allow_remap
));
419 void GestureInterpreterLibevdevCros::DispatchChangedKeys(Evdev
* evdev
,
420 const timeval
& time
) {
421 unsigned long key_state_diff
[EVDEV_BITS_TO_LONGS(KEY_CNT
)];
423 // Find changed keys.
424 for (unsigned long i
= 0; i
< arraysize(key_state_diff
); ++i
)
425 key_state_diff
[i
] = evdev
->key_state_bitmask
[i
] ^ prev_key_state_
[i
];
427 // Dispatch events for changed keys.
428 for (unsigned long key
= 0; key
< KEY_CNT
; ++key
) {
429 if (EvdevBitIsSet(key_state_diff
, key
)) {
430 bool value
= EvdevBitIsSet(evdev
->key_state_bitmask
, key
);
432 // Mouse buttons are handled by DispatchMouseButton.
433 if (key
>= BTN_MOUSE
&& key
< BTN_JOYSTICK
)
436 // Ignore digi buttons (e.g. BTN_TOOL_FINGER).
437 if (key
>= BTN_DIGI
&& key
< BTN_WHEEL
)
440 if (allowed_keys_
&& !allowed_keys_
->count(key
))
443 // Dispatch key press or release to keyboard.
444 dispatcher_
->DispatchKeyEvent(KeyEventParams(id_
, key
, value
));
448 // Update internal key state.
449 for (unsigned long i
= 0; i
< EVDEV_BITS_TO_LONGS(KEY_CNT
); ++i
)
450 prev_key_state_
[i
] = evdev
->key_state_bitmask
[i
];