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/wayland/dispatcher.h"
10 #include "ozone/wayland/input/cursor.h"
11 #include "ozone/wayland/window.h"
12 #include "ui/base/hit_test.h"
13 #include "ui/events/event.h"
15 namespace ozonewayland {
17 WaylandPointer::WaylandPointer()
20 focused_window_handle_(0) {
23 WaylandPointer::~WaylandPointer() {
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_ = WaylandDispatcher::GetInstance();
44 if ((caps & WL_SEAT_CAPABILITY_POINTER) && !cursor_->GetInputPointer()) {
45 wl_pointer* 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 wl_pointer_destroy(cursor_->GetInputPointer());
52 cursor_->SetInputPointer(NULL);
56 void WaylandPointer::OnMotionNotify(void* data,
57 wl_pointer* input_pointer,
61 WaylandPointer* device = static_cast<WaylandPointer*>(data);
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 device->dispatcher_->MotionNotify(sx, sy);
69 void WaylandPointer::OnButtonNotify(void* data,
70 wl_pointer* input_pointer,
75 WaylandPointer* device = static_cast<WaylandPointer*>(data);
77 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
82 // TODO(vignatti): simultaneous clicks fail
84 if (button == BTN_LEFT)
85 flags = ui::EF_LEFT_MOUSE_BUTTON;
86 else if (button == BTN_RIGHT)
87 flags = ui::EF_RIGHT_MOUSE_BUTTON;
88 else if (button == BTN_MIDDLE)
89 flags = ui::EF_MIDDLE_MOUSE_BUTTON;
91 device->dispatcher_->ButtonNotify(device->focused_window_handle_,
94 device->pointer_position_.x(),
95 device->pointer_position_.y());
98 void WaylandPointer::OnAxisNotify(void* data,
99 wl_pointer* input_pointer,
103 int x_offset = 0, y_offset = 0;
104 WaylandPointer* device = static_cast<WaylandPointer*>(data);
105 const int delta = ui::MouseWheelEvent::kWheelDelta;
108 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
109 x_offset = value > 0 ? -delta : delta;
111 case WL_POINTER_AXIS_VERTICAL_SCROLL:
112 y_offset = value > 0 ? -delta : delta;
116 device->dispatcher_->AxisNotify(device->pointer_position_.x(),
117 device->pointer_position_.y(), x_offset,
121 void WaylandPointer::OnPointerEnter(void* data,
122 wl_pointer* input_pointer,
127 WaylandPointer* device = static_cast<WaylandPointer*>(data);
128 // TODO(vignatti): sx and sy have to be used for setting different resizing
129 // and other cursors.
130 WaylandWindow* window = NULL;
132 window = static_cast<WaylandWindow*>(wl_surface_get_user_data(surface));
134 device->focused_window_handle_ = window ? window->Handle() : 0;
135 device->cursor_->Update(WaylandCursor::CURSOR_LEFT_PTR, serial);
136 device->dispatcher_->PointerEnter(device->focused_window_handle_,
137 device->pointer_position_.x(),
138 device->pointer_position_.y());
141 void WaylandPointer::OnPointerLeave(void* data,
142 wl_pointer* input_pointer,
144 wl_surface* surface) {
145 WaylandPointer* device = static_cast<WaylandPointer*>(data);
146 device->dispatcher_->PointerLeave(device->focused_window_handle_,
147 device->pointer_position_.x(),
148 device->pointer_position_.y());
149 device->focused_window_handle_ = 0;
152 } // namespace ozonewayland