Upstream version 10.39.233.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   } else if (!(caps & WL_SEAT_CAPABILITY_POINTER)
50                 && cursor_->GetInputPointer()) {
51     cursor_->SetInputPointer(NULL);
52   }
53 }
54
55 void WaylandPointer::OnMotionNotify(void* data,
56                                     wl_pointer* input_pointer,
57                                     uint32_t time,
58                                     wl_fixed_t sx_w,
59                                     wl_fixed_t sy_w) {
60   WaylandPointer* device = static_cast<WaylandPointer*>(data);
61   WaylandInputDevice* input = WaylandDisplay::GetInstance()->PrimaryInput();
62   float sx = wl_fixed_to_double(sx_w);
63   float sy = wl_fixed_to_double(sy_w);
64
65   device->pointer_position_.SetPoint(sx, sy);
66   if (input->GetGrabWindowHandle() &&
67         input->GetGrabWindowHandle() != input->GetFocusWindowHandle()) {
68       return;
69   }
70
71   device->dispatcher_->MotionNotify(sx, sy);
72 }
73
74 void WaylandPointer::OnButtonNotify(void* data,
75                                     wl_pointer* input_pointer,
76                                     uint32_t serial,
77                                     uint32_t time,
78                                     uint32_t button,
79                                     uint32_t state) {
80   WaylandPointer* device = static_cast<WaylandPointer*>(data);
81   WaylandDisplay::GetInstance()->SetSerial(serial);
82   WaylandInputDevice* input = WaylandDisplay::GetInstance()->PrimaryInput();
83   if (input->GetFocusWindowHandle() && input->GetGrabButton() == 0 &&
84         state == WL_POINTER_BUTTON_STATE_PRESSED)
85     input->SetGrabWindowHandle(input->GetFocusWindowHandle(), button);
86
87   if (input->GetGrabWindowHandle()) {
88     ui::EventType type = ui::ET_MOUSE_PRESSED;
89     if (state == WL_POINTER_BUTTON_STATE_RELEASED)
90       type = ui::ET_MOUSE_RELEASED;
91
92     // TODO(vignatti): simultaneous clicks fail
93     ui::EventFlags flags = ui::EF_NONE;
94     if (button == BTN_LEFT)
95       flags = ui::EF_LEFT_MOUSE_BUTTON;
96     else if (button == BTN_RIGHT)
97       flags = ui::EF_RIGHT_MOUSE_BUTTON;
98     else if (button == BTN_MIDDLE)
99       flags = ui::EF_MIDDLE_MOUSE_BUTTON;
100
101     device->dispatcher_->ButtonNotify(input->GetFocusWindowHandle(),
102                                       type,
103                                       flags,
104                                       device->pointer_position_.x(),
105                                       device->pointer_position_.y());
106   }
107
108   if (input->GetGrabWindowHandle() && input->GetGrabButton() == button &&
109         state == WL_POINTER_BUTTON_STATE_RELEASED)
110     input->SetGrabWindowHandle(0, 0);
111 }
112
113 void WaylandPointer::OnAxisNotify(void* data,
114                                   wl_pointer* input_pointer,
115                                   uint32_t time,
116                                   uint32_t axis,
117                                   int32_t value) {
118   int x_offset = 0, y_offset = 0;
119   WaylandPointer* device = static_cast<WaylandPointer*>(data);
120   const int delta = ui::MouseWheelEvent::kWheelDelta;
121
122   switch (axis) {
123     case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
124       x_offset = value > 0 ? -delta : delta;
125       break;
126     case WL_POINTER_AXIS_VERTICAL_SCROLL:
127       y_offset = value > 0 ? -delta : delta;
128       break;
129     default:
130       break;
131   }
132
133   device->dispatcher_->AxisNotify(device->pointer_position_.x(),
134                                   device->pointer_position_.y(),
135                                   x_offset,
136                                   y_offset);
137 }
138
139 void WaylandPointer::OnPointerEnter(void* data,
140                                     wl_pointer* input_pointer,
141                                     uint32_t serial,
142                                     wl_surface* surface,
143                                     wl_fixed_t sx_w,
144                                     wl_fixed_t sy_w) {
145   WaylandInputDevice* input = WaylandDisplay::GetInstance()->PrimaryInput();
146
147   if (!surface) {
148     input->SetFocusWindowHandle(0);
149     return;
150   }
151
152   WaylandPointer* device = static_cast<WaylandPointer*>(data);
153   WaylandWindow* window =
154       static_cast<WaylandWindow*>(wl_surface_get_user_data(surface));
155   unsigned handle = window->Handle();
156   float sx = wl_fixed_to_double(sx_w);
157   float sy = wl_fixed_to_double(sy_w);
158
159   WaylandDisplay::GetInstance()->SetSerial(serial);
160   device->pointer_position_.SetPoint(sx, sy);
161   input->SetFocusWindowHandle(handle);
162   device->dispatcher_->PointerEnter(handle,
163                                     device->pointer_position_.x(),
164                                     device->pointer_position_.y());
165 }
166
167 void WaylandPointer::OnPointerLeave(void* data,
168                                     wl_pointer* input_pointer,
169                                     uint32_t serial,
170                                     wl_surface* surface) {
171   WaylandPointer* device = static_cast<WaylandPointer*>(data);
172   WaylandDisplay::GetInstance()->SetSerial(serial);
173
174   WaylandInputDevice* input = WaylandDisplay::GetInstance()->PrimaryInput();
175   device->dispatcher_->PointerLeave(input->GetFocusWindowHandle(),
176                                     device->pointer_position_.x(),
177                                     device->pointer_position_.y());
178   input->SetFocusWindowHandle(0);
179 }
180
181 }  // namespace ozonewayland