Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / ui / events / ozone / evdev / libgestures_glue / gesture_interpreter_libevdev_cros.cc
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.
4
5 #include "ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cros.h"
6
7 #include <gestures/gestures.h>
8 #include <libevdev/libevdev.h>
9
10 #include "base/strings/stringprintf.h"
11 #include "base/timer/timer.h"
12 #include "ui/events/event.h"
13 #include "ui/events/ozone/evdev/cursor_delegate_evdev.h"
14 #include "ui/events/ozone/evdev/event_modifiers_evdev.h"
15 #include "ui/events/ozone/evdev/libgestures_glue/gesture_timer_provider.h"
16 #include "ui/gfx/geometry/point_f.h"
17
18 namespace ui {
19
20 namespace {
21
22 // Convert libevdev device class to libgestures device class.
23 GestureInterpreterDeviceClass GestureDeviceClass(Evdev* evdev) {
24   switch (evdev->info.evdev_class) {
25     case EvdevClassMouse:
26       return GESTURES_DEVCLASS_MOUSE;
27     case EvdevClassMultitouchMouse:
28       return GESTURES_DEVCLASS_MULTITOUCH_MOUSE;
29     case EvdevClassTouchpad:
30       return GESTURES_DEVCLASS_TOUCHPAD;
31     case EvdevClassTouchscreen:
32       return GESTURES_DEVCLASS_TOUCHSCREEN;
33     default:
34       return GESTURES_DEVCLASS_UNKNOWN;
35   }
36 }
37
38 // Convert libevdev state to libgestures hardware properties.
39 HardwareProperties GestureHardwareProperties(Evdev* evdev) {
40   HardwareProperties hwprops;
41   hwprops.left = Event_Get_Left(evdev);
42   hwprops.top = Event_Get_Top(evdev);
43   hwprops.right = Event_Get_Right(evdev);
44   hwprops.bottom = Event_Get_Bottom(evdev);
45   hwprops.res_x = Event_Get_Res_X(evdev);
46   hwprops.res_y = Event_Get_Res_Y(evdev);
47   hwprops.screen_x_dpi = 133;
48   hwprops.screen_y_dpi = 133;
49   hwprops.orientation_minimum = Event_Get_Orientation_Minimum(evdev);
50   hwprops.orientation_maximum = Event_Get_Orientation_Maximum(evdev);
51   hwprops.max_finger_cnt = Event_Get_Slot_Count(evdev);
52   hwprops.max_touch_cnt = Event_Get_Touch_Count_Max(evdev);
53   hwprops.supports_t5r2 = Event_Get_T5R2(evdev);
54   hwprops.support_semi_mt = Event_Get_Semi_MT(evdev);
55   /* buttonpad means a physical button under the touch surface */
56   hwprops.is_button_pad = Event_Get_Button_Pad(evdev);
57   return hwprops;
58 }
59
60 // Callback from libgestures when a gesture is ready.
61 void OnGestureReadyHelper(void* client_data, const Gesture* gesture) {
62   GestureInterpreterLibevdevCros* interpreter =
63       static_cast<GestureInterpreterLibevdevCros*>(client_data);
64   interpreter->OnGestureReady(gesture);
65 }
66
67 // Convert gestures timestamp (stime_t) to ui::Event timestamp.
68 base::TimeDelta StimeToTimedelta(stime_t timestamp) {
69   return base::TimeDelta::FromMicroseconds(timestamp *
70                                            base::Time::kMicrosecondsPerSecond);
71 }
72
73 // Number of fingers for scroll gestures.
74 const int kGestureScrollFingerCount = 2;
75
76 // Number of fingers for swipe gestures.
77 const int kGestureSwipeFingerCount = 3;
78
79 }  // namespace
80
81 GestureInterpreterLibevdevCros::GestureInterpreterLibevdevCros(
82     EventModifiersEvdev* modifiers,
83     CursorDelegateEvdev* cursor,
84     const EventDispatchCallback& callback)
85     : modifiers_(modifiers),
86       cursor_(cursor),
87       dispatch_callback_(callback),
88       interpreter_(NULL) {}
89
90 GestureInterpreterLibevdevCros::~GestureInterpreterLibevdevCros() {
91   if (interpreter_) {
92     DeleteGestureInterpreter(interpreter_);
93     interpreter_ = NULL;
94   }
95 }
96
97 void GestureInterpreterLibevdevCros::OnLibEvdevCrosOpen(
98     Evdev* evdev,
99     EventStateRec* evstate) {
100   CHECK(evdev->info.is_monotonic) << "libevdev must use monotonic timestamps";
101   VLOG(9) << "HACK DO NOT REMOVE OR LINK WILL FAIL" << (void*)gestures_log;
102
103   HardwareProperties hwprops = GestureHardwareProperties(evdev);
104   GestureInterpreterDeviceClass devclass = GestureDeviceClass(evdev);
105
106   // Create & initialize GestureInterpreter.
107   CHECK(!interpreter_);
108   interpreter_ = NewGestureInterpreter();
109   GestureInterpreterInitialize(interpreter_, devclass);
110   GestureInterpreterSetHardwareProperties(interpreter_, &hwprops);
111   GestureInterpreterSetTimerProvider(
112       interpreter_,
113       const_cast<GesturesTimerProvider*>(&kGestureTimerProvider),
114       this);
115   GestureInterpreterSetCallback(interpreter_, OnGestureReadyHelper, this);
116 }
117
118 void GestureInterpreterLibevdevCros::OnLibEvdevCrosEvent(Evdev* evdev,
119                                                          EventStateRec* evstate,
120                                                          const timeval& time) {
121   HardwareState hwstate;
122   memset(&hwstate, 0, sizeof(hwstate));
123   hwstate.timestamp = StimeFromTimeval(&time);
124
125   // Mouse.
126   hwstate.rel_x = evstate->rel_x;
127   hwstate.rel_y = evstate->rel_y;
128   hwstate.rel_wheel = evstate->rel_wheel;
129   hwstate.rel_hwheel = evstate->rel_hwheel;
130
131   // Touch.
132   FingerState fingers[Event_Get_Slot_Count(evdev)];
133   memset(&fingers, 0, sizeof(fingers));
134   int current_finger = 0;
135   for (int i = 0; i < evstate->slot_count; i++) {
136     MtSlotPtr slot = &evstate->slots[i];
137     if (slot->tracking_id == -1)
138       continue;
139     fingers[current_finger].touch_major = slot->touch_major;
140     fingers[current_finger].touch_minor = slot->touch_minor;
141     fingers[current_finger].width_major = slot->width_major;
142     fingers[current_finger].width_minor = slot->width_minor;
143     fingers[current_finger].pressure = slot->pressure;
144     fingers[current_finger].orientation = slot->orientation;
145     fingers[current_finger].position_x = slot->position_x;
146     fingers[current_finger].position_y = slot->position_y;
147     fingers[current_finger].tracking_id = slot->tracking_id;
148     current_finger++;
149   }
150   hwstate.touch_cnt = Event_Get_Touch_Count(evdev);
151   hwstate.finger_cnt = current_finger;
152   hwstate.fingers = fingers;
153
154   // Buttons.
155   if (Event_Get_Button_Left(evdev))
156     hwstate.buttons_down |= GESTURES_BUTTON_LEFT;
157   if (Event_Get_Button_Middle(evdev))
158     hwstate.buttons_down |= GESTURES_BUTTON_MIDDLE;
159   if (Event_Get_Button_Right(evdev))
160     hwstate.buttons_down |= GESTURES_BUTTON_RIGHT;
161
162   GestureInterpreterPushHardwareState(interpreter_, &hwstate);
163 }
164
165 void GestureInterpreterLibevdevCros::OnGestureReady(const Gesture* gesture) {
166   switch (gesture->type) {
167     case kGestureTypeMove:
168       OnGestureMove(gesture, &gesture->details.move);
169       break;
170     case kGestureTypeScroll:
171       OnGestureScroll(gesture, &gesture->details.scroll);
172       break;
173     case kGestureTypeButtonsChange:
174       OnGestureButtonsChange(gesture, &gesture->details.buttons);
175       break;
176     case kGestureTypeContactInitiated:
177       OnGestureContactInitiated(gesture);
178       break;
179     case kGestureTypeFling:
180       OnGestureFling(gesture, &gesture->details.fling);
181       break;
182     case kGestureTypeSwipe:
183       OnGestureSwipe(gesture, &gesture->details.swipe);
184       break;
185     case kGestureTypeSwipeLift:
186       OnGestureSwipeLift(gesture, &gesture->details.swipe_lift);
187       break;
188     case kGestureTypePinch:
189       OnGesturePinch(gesture, &gesture->details.pinch);
190       break;
191     case kGestureTypeMetrics:
192       OnGestureMetrics(gesture, &gesture->details.metrics);
193       break;
194     default:
195       LOG(WARNING) << base::StringPrintf("Unrecognized gesture type (%u)",
196                                          gesture->type);
197       break;
198   }
199 }
200
201 void GestureInterpreterLibevdevCros::OnGestureMove(const Gesture* gesture,
202                                                    const GestureMove* move) {
203   DVLOG(3) << base::StringPrintf("Gesture Move: (%f, %f) [%f, %f]",
204                                  move->dx,
205                                  move->dy,
206                                  move->ordinal_dx,
207                                  move->ordinal_dy);
208   if (!cursor_)
209     return;  // No cursor!
210
211   cursor_->MoveCursor(gfx::Vector2dF(move->dx, move->dy));
212   // TODO(spang): Use move->ordinal_dx, move->ordinal_dy
213   // TODO(spang): Use move->start_time, move->end_time
214   MouseEvent event(ET_MOUSE_MOVED,
215                    cursor_->location(),
216                    cursor_->location(),
217                    modifiers_->GetModifierFlags(),
218                    /* changed_button_flags */ 0);
219   Dispatch(&event);
220 }
221
222 void GestureInterpreterLibevdevCros::OnGestureScroll(
223     const Gesture* gesture,
224     const GestureScroll* scroll) {
225   DVLOG(3) << base::StringPrintf("Gesture Scroll: (%f, %f) [%f, %f]",
226                                  scroll->dx,
227                                  scroll->dy,
228                                  scroll->ordinal_dx,
229                                  scroll->ordinal_dy);
230   if (!cursor_)
231     return;  // No cursor!
232
233   // TODO(spang): Support SetNaturalScroll
234   // TODO(spang): Use scroll->start_time
235   ScrollEvent event(ET_SCROLL,
236                     cursor_->location(),
237                     StimeToTimedelta(gesture->end_time),
238                     modifiers_->GetModifierFlags(),
239                     scroll->dx,
240                     scroll->dy,
241                     scroll->ordinal_dx,
242                     scroll->ordinal_dy,
243                     kGestureScrollFingerCount);
244   Dispatch(&event);
245 }
246
247 void GestureInterpreterLibevdevCros::OnGestureButtonsChange(
248     const Gesture* gesture,
249     const GestureButtonsChange* buttons) {
250   DVLOG(3) << base::StringPrintf("Gesture Button Change: down=0x%02x up=0x%02x",
251                                  buttons->down,
252                                  buttons->up);
253
254   if (!cursor_)
255     return;  // No cursor!
256
257   // TODO(spang): Use buttons->start_time, buttons->end_time
258   if (buttons->down & GESTURES_BUTTON_LEFT)
259     DispatchMouseButton(EVDEV_MODIFIER_LEFT_MOUSE_BUTTON, true);
260   if (buttons->down & GESTURES_BUTTON_MIDDLE)
261     DispatchMouseButton(EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON, true);
262   if (buttons->down & GESTURES_BUTTON_RIGHT)
263     DispatchMouseButton(EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON, true);
264   if (buttons->up & GESTURES_BUTTON_LEFT)
265     DispatchMouseButton(EVDEV_MODIFIER_LEFT_MOUSE_BUTTON, false);
266   if (buttons->up & GESTURES_BUTTON_MIDDLE)
267     DispatchMouseButton(EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON, false);
268   if (buttons->up & GESTURES_BUTTON_RIGHT)
269     DispatchMouseButton(EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON, false);
270 }
271
272 void GestureInterpreterLibevdevCros::OnGestureContactInitiated(
273     const Gesture* gesture) {
274   // TODO(spang): handle contact initiated.
275 }
276
277 void GestureInterpreterLibevdevCros::OnGestureFling(const Gesture* gesture,
278                                                     const GestureFling* fling) {
279   DVLOG(3) << base::StringPrintf(
280                   "Gesture Fling: (%f, %f) [%f, %f] fling_state=%d",
281                   fling->vx,
282                   fling->vy,
283                   fling->ordinal_vx,
284                   fling->ordinal_vy,
285                   fling->fling_state);
286
287   if (!cursor_)
288     return;  // No cursor!
289
290   EventType type =
291       (fling->fling_state == GESTURES_FLING_START ? ET_SCROLL_FLING_START
292                                                   : ET_SCROLL_FLING_CANCEL);
293
294   // Fling is like 2-finger scrolling but with velocity instead of displacement.
295   ScrollEvent event(type,
296                     cursor_->location(),
297                     StimeToTimedelta(gesture->end_time),
298                     modifiers_->GetModifierFlags(),
299                     fling->vx,
300                     fling->vy,
301                     fling->ordinal_vx,
302                     fling->ordinal_vy,
303                     kGestureScrollFingerCount);
304   Dispatch(&event);
305 }
306
307 void GestureInterpreterLibevdevCros::OnGestureSwipe(const Gesture* gesture,
308                                                     const GestureSwipe* swipe) {
309   DVLOG(3) << base::StringPrintf("Gesture Swipe: (%f, %f) [%f, %f]",
310                                  swipe->dx,
311                                  swipe->dy,
312                                  swipe->ordinal_dx,
313                                  swipe->ordinal_dy);
314
315   if (!cursor_)
316     return;  // No cursor!
317
318   // Swipe is 3-finger scrolling.
319   ScrollEvent event(ET_SCROLL,
320                     cursor_->location(),
321                     StimeToTimedelta(gesture->end_time),
322                     modifiers_->GetModifierFlags(),
323                     swipe->dx,
324                     swipe->dy,
325                     swipe->ordinal_dx,
326                     swipe->ordinal_dy,
327                     kGestureSwipeFingerCount);
328   Dispatch(&event);
329 }
330
331 void GestureInterpreterLibevdevCros::OnGestureSwipeLift(
332     const Gesture* gesture,
333     const GestureSwipeLift* swipelift) {
334   DVLOG(3) << base::StringPrintf("Gesture Swipe Lift");
335
336   if (!cursor_)
337     return;  // No cursor!
338
339   // Turn a swipe lift into a fling start.
340   // TODO(spang): Figure out why and put it in this comment.
341
342   ScrollEvent event(ET_SCROLL_FLING_START,
343                     cursor_->location(),
344                     StimeToTimedelta(gesture->end_time),
345                     modifiers_->GetModifierFlags(),
346                     /* x_offset */ 0,
347                     /* y_offset */ 0,
348                     /* x_offset_ordinal */ 0,
349                     /* y_offset_ordinal */ 0,
350                     kGestureScrollFingerCount);
351   Dispatch(&event);
352
353 }
354
355 void GestureInterpreterLibevdevCros::OnGesturePinch(const Gesture* gesture,
356                                                     const GesturePinch* pinch) {
357   DVLOG(3) << base::StringPrintf(
358                   "Gesture Pinch: dz=%f [%f]", pinch->dz, pinch->ordinal_dz);
359
360   if (!cursor_)
361     return;  // No cursor!
362
363   NOTIMPLEMENTED();
364 }
365
366 void GestureInterpreterLibevdevCros::OnGestureMetrics(
367     const Gesture* gesture,
368     const GestureMetrics* metrics) {
369   DVLOG(3) << base::StringPrintf("Gesture Metrics: [%f, %f] type=%d",
370                                  metrics->data[0],
371                                  metrics->data[1],
372                                  metrics->type);
373   NOTIMPLEMENTED();
374 }
375
376 void GestureInterpreterLibevdevCros::Dispatch(Event* event) {
377   dispatch_callback_.Run(event);
378 }
379
380 void GestureInterpreterLibevdevCros::DispatchMouseButton(unsigned int modifier,
381                                                          bool down) {
382   const gfx::PointF& loc = cursor_->location();
383   int flag = modifiers_->GetEventFlagFromModifier(modifier);
384   EventType type = (down ? ET_MOUSE_PRESSED : ET_MOUSE_RELEASED);
385   modifiers_->UpdateModifier(modifier, down);
386   MouseEvent event(type, loc, loc, modifiers_->GetModifierFlags() | flag, flag);
387
388   // This hack is necessary to trigger setting the repeat count.
389   // TODO(spang): Fix it.
390   MouseEvent event2(&event);
391   Dispatch(&event2);
392 }
393
394 }  // namespace ui