- add sources.
[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/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"
14
15 namespace ozonewayland {
16
17 WaylandPointer::WaylandPointer()
18   : cursor_(NULL),
19     dispatcher_(NULL),
20     focused_window_handle_(0) {
21 }
22
23 WaylandPointer::~WaylandPointer() {
24   if (cursor_) {
25     delete cursor_;
26     cursor_ = NULL;
27   }
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_ = WaylandDispatcher::GetInstance();
43
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);
53   }
54 }
55
56 void WaylandPointer::OnMotionNotify(void* data,
57                                     wl_pointer* input_pointer,
58                                     uint32_t time,
59                                     wl_fixed_t sx_w,
60                                     wl_fixed_t sy_w) {
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);
64
65   device->pointer_position_.SetPoint(sx, sy);
66   device->dispatcher_->MotionNotify(sx, sy);
67 }
68
69 void WaylandPointer::OnButtonNotify(void* data,
70                                     wl_pointer* input_pointer,
71                                     uint32_t serial,
72                                     uint32_t time,
73                                     uint32_t button,
74                                     uint32_t state) {
75   WaylandPointer* device = static_cast<WaylandPointer*>(data);
76   int currentState;
77   if (state == WL_POINTER_BUTTON_STATE_PRESSED)
78     currentState = 1;
79   else
80     currentState = 0;
81
82   // TODO(vignatti): simultaneous clicks fail
83   int flags = 0;
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;
90
91   device->dispatcher_->ButtonNotify(device->focused_window_handle_,
92                                     currentState,
93                                     flags,
94                                     device->pointer_position_.x(),
95                                     device->pointer_position_.y());
96 }
97
98 void WaylandPointer::OnAxisNotify(void* data,
99                                   wl_pointer* input_pointer,
100                                   uint32_t time,
101                                   uint32_t axis,
102                                   int32_t value) {
103   int x_offset = 0, y_offset = 0;
104   WaylandPointer* device = static_cast<WaylandPointer*>(data);
105   const int delta = ui::MouseWheelEvent::kWheelDelta;
106
107   switch (axis) {
108   case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
109     x_offset = value > 0 ? -delta : delta;
110     break;
111   case WL_POINTER_AXIS_VERTICAL_SCROLL:
112     y_offset = value > 0 ? -delta : delta;
113     break;
114   }
115
116   device->dispatcher_->AxisNotify(device->pointer_position_.x(),
117                                   device->pointer_position_.y(), x_offset,
118                                   y_offset);
119 }
120
121 void WaylandPointer::OnPointerEnter(void* data,
122                                     wl_pointer* input_pointer,
123                                     uint32_t serial,
124                                     wl_surface* surface,
125                                     wl_fixed_t sx_w,
126                                     wl_fixed_t sy_w) {
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;
131   if (surface)
132     window = static_cast<WaylandWindow*>(wl_surface_get_user_data(surface));
133
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());
139 }
140
141 void WaylandPointer::OnPointerLeave(void* data,
142                                     wl_pointer* input_pointer,
143                                     uint32_t serial,
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;
150 }
151
152 }  // namespace ozonewayland