Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / ozone / wayland / input / pointer.cc
1 // Copyright 2013 Intel Corporation. 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 "ozone/wayland/input/pointer.h"
6
7 #include <linux/input.h>
8
9 #include "ozone/ui/events/event_factory_ozone_wayland.h"
10 #include "ozone/wayland/input/cursor.h"
11 #include "ozone/wayland/input_device.h"
12 #include "ozone/wayland/window.h"
13 #include "ui/events/event.h"
14
15 namespace ozonewayland {
16
17 WaylandPointer::WaylandPointer()
18   : cursor_(NULL),
19     dispatcher_(NULL),
20     pointer_position_(0, 0),
21     input_pointer_(NULL) {
22 }
23
24 WaylandPointer::~WaylandPointer() {
25   delete cursor_;
26   if (input_pointer_)
27     wl_pointer_destroy(input_pointer_);
28 }
29
30 void WaylandPointer::OnSeatCapabilities(wl_seat *seat, uint32_t caps) {
31   static const struct wl_pointer_listener kInputPointerListener = {
32     WaylandPointer::OnPointerEnter,
33     WaylandPointer::OnPointerLeave,
34     WaylandPointer::OnMotionNotify,
35     WaylandPointer::OnButtonNotify,
36     WaylandPointer::OnAxisNotify,
37   };
38
39   if (!cursor_)
40     cursor_ = new WaylandCursor(WaylandDisplay::GetInstance()->shm());
41
42   dispatcher_ = ui::EventFactoryOzoneWayland::GetInstance()->EventConverter();
43
44   if ((caps & WL_SEAT_CAPABILITY_POINTER) && !cursor_->GetInputPointer()) {
45     input_pointer_ = wl_seat_get_pointer(seat);
46       cursor_->SetInputPointer(input_pointer_);
47     wl_pointer_set_user_data(input_pointer_, this);
48     wl_pointer_add_listener(input_pointer_, &kInputPointerListener, this);
49   }
50 }
51
52 void WaylandPointer::OnMotionNotify(void* data,
53                                     wl_pointer* input_pointer,
54                                     uint32_t time,
55                                     wl_fixed_t sx_w,
56                                     wl_fixed_t sy_w) {
57   WaylandPointer* device = static_cast<WaylandPointer*>(data);
58   WaylandInputDevice* input = WaylandDisplay::GetInstance()->PrimaryInput();
59   float sx = wl_fixed_to_double(sx_w);
60   float sy = wl_fixed_to_double(sy_w);
61
62   device->pointer_position_.SetPoint(sx, sy);
63   if (input->GetGrabWindowHandle() &&
64         input->GetGrabWindowHandle() != input->GetFocusWindowHandle()) {
65       return;
66   }
67
68   device->dispatcher_->MotionNotify(sx, sy);
69 }
70
71 void WaylandPointer::OnButtonNotify(void* data,
72                                     wl_pointer* input_pointer,
73                                     uint32_t serial,
74                                     uint32_t time,
75                                     uint32_t button,
76                                     uint32_t state) {
77   WaylandPointer* device = static_cast<WaylandPointer*>(data);
78   WaylandDisplay::GetInstance()->SetSerial(serial);
79   WaylandInputDevice* input = WaylandDisplay::GetInstance()->PrimaryInput();
80   if (input->GetFocusWindowHandle() && input->GetGrabButton() == 0 &&
81         state == WL_POINTER_BUTTON_STATE_PRESSED)
82     input->SetGrabWindowHandle(input->GetFocusWindowHandle(), button);
83
84   if (input->GetGrabWindowHandle()) {
85     ui::EventType type = ui::ET_MOUSE_PRESSED;
86     if (state == WL_POINTER_BUTTON_STATE_RELEASED)
87       type = ui::ET_MOUSE_RELEASED;
88
89     // TODO(vignatti): simultaneous clicks fail
90     ui::EventFlags flags = ui::EF_NONE;
91     if (button == BTN_LEFT)
92       flags = ui::EF_LEFT_MOUSE_BUTTON;
93     else if (button == BTN_RIGHT)
94       flags = ui::EF_RIGHT_MOUSE_BUTTON;
95     else if (button == BTN_MIDDLE)
96       flags = ui::EF_MIDDLE_MOUSE_BUTTON;
97
98     device->dispatcher_->ButtonNotify(input->GetFocusWindowHandle(),
99                                       type,
100                                       flags,
101                                       device->pointer_position_.x(),
102                                       device->pointer_position_.y());
103   }
104
105   if (input->GetGrabWindowHandle() && input->GetGrabButton() == button &&
106         state == WL_POINTER_BUTTON_STATE_RELEASED)
107     input->SetGrabWindowHandle(0, 0);
108 }
109
110 void WaylandPointer::OnAxisNotify(void* data,
111                                   wl_pointer* input_pointer,
112                                   uint32_t time,
113                                   uint32_t axis,
114                                   int32_t value) {
115   int x_offset = 0, y_offset = 0;
116   WaylandPointer* device = static_cast<WaylandPointer*>(data);
117   const int delta = ui::MouseWheelEvent::kWheelDelta;
118
119   switch (axis) {
120     case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
121       x_offset = value > 0 ? -delta : delta;
122       break;
123     case WL_POINTER_AXIS_VERTICAL_SCROLL:
124       y_offset = value > 0 ? -delta : delta;
125       break;
126     default:
127       break;
128   }
129
130   device->dispatcher_->AxisNotify(device->pointer_position_.x(),
131                                   device->pointer_position_.y(),
132                                   x_offset,
133                                   y_offset);
134 }
135
136 void WaylandPointer::OnPointerEnter(void* data,
137                                     wl_pointer* input_pointer,
138                                     uint32_t serial,
139                                     wl_surface* surface,
140                                     wl_fixed_t sx_w,
141                                     wl_fixed_t sy_w) {
142   WaylandInputDevice* input = WaylandDisplay::GetInstance()->PrimaryInput();
143
144   if (!surface) {
145     input->SetFocusWindowHandle(0);
146     return;
147   }
148
149   WaylandPointer* device = static_cast<WaylandPointer*>(data);
150   WaylandWindow* window =
151       static_cast<WaylandWindow*>(wl_surface_get_user_data(surface));
152   unsigned handle = window->Handle();
153   float sx = wl_fixed_to_double(sx_w);
154   float sy = wl_fixed_to_double(sy_w);
155
156   WaylandDisplay::GetInstance()->SetSerial(serial);
157   device->pointer_position_.SetPoint(sx, sy);
158   input->SetFocusWindowHandle(handle);
159   device->dispatcher_->PointerEnter(handle,
160                                     device->pointer_position_.x(),
161                                     device->pointer_position_.y());
162 }
163
164 void WaylandPointer::OnPointerLeave(void* data,
165                                     wl_pointer* input_pointer,
166                                     uint32_t serial,
167                                     wl_surface* surface) {
168   WaylandPointer* device = static_cast<WaylandPointer*>(data);
169   WaylandDisplay::GetInstance()->SetSerial(serial);
170
171   WaylandInputDevice* input = WaylandDisplay::GetInstance()->PrimaryInput();
172   device->dispatcher_->PointerLeave(input->GetFocusWindowHandle(),
173                                     device->pointer_position_.x(),
174                                     device->pointer_position_.y());
175   input->SetFocusWindowHandle(0);
176 }
177
178 }  // namespace ozonewayland