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);
52 void WaylandPointer::OnMotionNotify(void* data,
53 wl_pointer* input_pointer,
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);
62 device->pointer_position_.SetPoint(sx, sy);
63 if (input->GetGrabWindowHandle() &&
64 input->GetGrabWindowHandle() != input->GetFocusWindowHandle()) {
68 device->dispatcher_->MotionNotify(sx, sy);
71 void WaylandPointer::OnButtonNotify(void* data,
72 wl_pointer* input_pointer,
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);
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;
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;
98 device->dispatcher_->ButtonNotify(input->GetFocusWindowHandle(),
101 device->pointer_position_.x(),
102 device->pointer_position_.y());
105 if (input->GetGrabWindowHandle() && input->GetGrabButton() == button &&
106 state == WL_POINTER_BUTTON_STATE_RELEASED)
107 input->SetGrabWindowHandle(0, 0);
110 void WaylandPointer::OnAxisNotify(void* data,
111 wl_pointer* input_pointer,
115 int x_offset = 0, y_offset = 0;
116 WaylandPointer* device = static_cast<WaylandPointer*>(data);
117 const int delta = ui::MouseWheelEvent::kWheelDelta;
120 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
121 x_offset = value > 0 ? -delta : delta;
123 case WL_POINTER_AXIS_VERTICAL_SCROLL:
124 y_offset = value > 0 ? -delta : delta;
130 device->dispatcher_->AxisNotify(device->pointer_position_.x(),
131 device->pointer_position_.y(),
136 void WaylandPointer::OnPointerEnter(void* data,
137 wl_pointer* input_pointer,
142 WaylandInputDevice* input = WaylandDisplay::GetInstance()->PrimaryInput();
145 input->SetFocusWindowHandle(0);
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);
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());
164 void WaylandPointer::OnPointerLeave(void* data,
165 wl_pointer* input_pointer,
167 wl_surface* surface) {
168 WaylandPointer* device = static_cast<WaylandPointer*>(data);
169 WaylandDisplay::GetInstance()->SetSerial(serial);
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);
178 } // namespace ozonewayland