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.
5 #include "ozone/wayland/input/pointer.h"
7 #include <linux/input.h>
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"
15 namespace ozonewayland {
17 WaylandPointer::WaylandPointer()
20 pointer_position_(0, 0),
21 input_pointer_(NULL) {
24 WaylandPointer::~WaylandPointer() {
27 wl_pointer_destroy(input_pointer_);
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,
40 cursor_ = new WaylandCursor(WaylandDisplay::GetInstance()->shm());
42 dispatcher_ = ui::EventFactoryOzoneWayland::GetInstance()->EventConverter();
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);
55 void WaylandPointer::OnMotionNotify(void* data,
56 wl_pointer* input_pointer,
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);
65 device->pointer_position_.SetPoint(sx, sy);
66 if (input->GetGrabWindowHandle() &&
67 input->GetGrabWindowHandle() != input->GetFocusWindowHandle()) {
71 device->dispatcher_->MotionNotify(sx, sy);
74 void WaylandPointer::OnButtonNotify(void* data,
75 wl_pointer* input_pointer,
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);
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;
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;
101 device->dispatcher_->ButtonNotify(input->GetFocusWindowHandle(),
104 device->pointer_position_.x(),
105 device->pointer_position_.y());
108 if (input->GetGrabWindowHandle() && input->GetGrabButton() == button &&
109 state == WL_POINTER_BUTTON_STATE_RELEASED)
110 input->SetGrabWindowHandle(0, 0);
113 void WaylandPointer::OnAxisNotify(void* data,
114 wl_pointer* input_pointer,
118 int x_offset = 0, y_offset = 0;
119 WaylandPointer* device = static_cast<WaylandPointer*>(data);
120 const int delta = ui::MouseWheelEvent::kWheelDelta;
123 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
124 x_offset = value > 0 ? -delta : delta;
126 case WL_POINTER_AXIS_VERTICAL_SCROLL:
127 y_offset = value > 0 ? -delta : delta;
133 device->dispatcher_->AxisNotify(device->pointer_position_.x(),
134 device->pointer_position_.y(),
139 void WaylandPointer::OnPointerEnter(void* data,
140 wl_pointer* input_pointer,
145 WaylandInputDevice* input = WaylandDisplay::GetInstance()->PrimaryInput();
148 input->SetFocusWindowHandle(0);
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);
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());
167 void WaylandPointer::OnPointerLeave(void* data,
168 wl_pointer* input_pointer,
170 wl_surface* surface) {
171 WaylandPointer* device = static_cast<WaylandPointer*>(data);
172 WaylandDisplay::GetInstance()->SetSerial(serial);
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);
181 } // namespace ozonewayland