OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/client/plugin/pepper_input_handler.h" | 5 #include "remoting/client/plugin/pepper_input_handler.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "ppapi/c/dev/ppb_keyboard_input_event_dev.h" | 8 #include "ppapi/c/dev/ppb_keyboard_input_event_dev.h" |
| 9 #include "ppapi/cpp/image_data.h" |
9 #include "ppapi/cpp/input_event.h" | 10 #include "ppapi/cpp/input_event.h" |
10 #include "ppapi/cpp/module_impl.h" | 11 #include "ppapi/cpp/module_impl.h" |
| 12 #include "ppapi/cpp/mouse_cursor.h" |
11 #include "ppapi/cpp/point.h" | 13 #include "ppapi/cpp/point.h" |
12 #include "remoting/proto/event.pb.h" | 14 #include "remoting/proto/event.pb.h" |
13 | 15 |
14 namespace remoting { | 16 namespace remoting { |
15 | 17 |
16 PepperInputHandler::PepperInputHandler(protocol::InputStub* input_stub) | 18 PepperInputHandler::PepperInputHandler( |
17 : input_stub_(input_stub), | 19 pp::Instance* instance, |
| 20 protocol::InputStub* input_stub) |
| 21 : pp::MouseLock(instance), |
| 22 instance_(instance), |
| 23 input_stub_(input_stub), |
| 24 callback_factory_(this), |
| 25 has_focus_(false), |
| 26 mouse_lock_state_(MouseLockDisallowed), |
18 wheel_delta_x_(0), | 27 wheel_delta_x_(0), |
19 wheel_delta_y_(0), | 28 wheel_delta_y_(0), |
20 wheel_ticks_x_(0), | 29 wheel_ticks_x_(0), |
21 wheel_ticks_y_(0) { | 30 wheel_ticks_y_(0) { |
22 } | 31 } |
23 | 32 |
24 PepperInputHandler::~PepperInputHandler() { | 33 PepperInputHandler::~PepperInputHandler() { |
25 } | 34 } |
26 | 35 |
27 // Helper function to get the USB key code using the Dev InputEvent interface. | 36 // Helper function to get the USB key code using the Dev InputEvent interface. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 return true; | 100 return true; |
92 } | 101 } |
93 | 102 |
94 case PP_INPUTEVENT_TYPE_MOUSEMOVE: | 103 case PP_INPUTEVENT_TYPE_MOUSEMOVE: |
95 case PP_INPUTEVENT_TYPE_MOUSEENTER: | 104 case PP_INPUTEVENT_TYPE_MOUSEENTER: |
96 case PP_INPUTEVENT_TYPE_MOUSELEAVE: { | 105 case PP_INPUTEVENT_TYPE_MOUSELEAVE: { |
97 pp::MouseInputEvent pp_mouse_event(event); | 106 pp::MouseInputEvent pp_mouse_event(event); |
98 protocol::MouseEvent mouse_event; | 107 protocol::MouseEvent mouse_event; |
99 mouse_event.set_x(pp_mouse_event.GetPosition().x()); | 108 mouse_event.set_x(pp_mouse_event.GetPosition().x()); |
100 mouse_event.set_y(pp_mouse_event.GetPosition().y()); | 109 mouse_event.set_y(pp_mouse_event.GetPosition().y()); |
| 110 |
| 111 // Add relative movement if the mouse is locked. |
| 112 if (mouse_lock_state_ == MouseLockOn) { |
| 113 pp::Point delta = pp_mouse_event.GetMovement(); |
| 114 mouse_event.set_delta_x(delta.x()); |
| 115 mouse_event.set_delta_y(delta.y()); |
| 116 } |
| 117 |
101 input_stub_->InjectMouseEvent(mouse_event); | 118 input_stub_->InjectMouseEvent(mouse_event); |
102 return true; | 119 return true; |
103 } | 120 } |
104 | 121 |
105 case PP_INPUTEVENT_TYPE_WHEEL: { | 122 case PP_INPUTEVENT_TYPE_WHEEL: { |
106 pp::WheelInputEvent pp_wheel_event(event); | 123 pp::WheelInputEvent pp_wheel_event(event); |
107 | 124 |
108 // Don't handle scroll-by-page events, for now. | 125 // Don't handle scroll-by-page events, for now. |
109 if (pp_wheel_event.GetScrollByPage()) | 126 if (pp_wheel_event.GetScrollByPage()) |
110 return false; | 127 return false; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 | 169 |
153 default: { | 170 default: { |
154 LOG(INFO) << "Unhandled input event: " << event.GetType(); | 171 LOG(INFO) << "Unhandled input event: " << event.GetType(); |
155 break; | 172 break; |
156 } | 173 } |
157 } | 174 } |
158 | 175 |
159 return false; | 176 return false; |
160 } | 177 } |
161 | 178 |
| 179 void PepperInputHandler::AllowMouseLock() { |
| 180 DCHECK_EQ(mouse_lock_state_, MouseLockDisallowed); |
| 181 mouse_lock_state_ = MouseLockOff; |
| 182 } |
| 183 |
| 184 void PepperInputHandler::DidChangeFocus(bool has_focus) { |
| 185 has_focus_ = has_focus; |
| 186 if (has_focus_) |
| 187 RequestMouseLock(); |
| 188 } |
| 189 |
| 190 void PepperInputHandler::SetMouseCursor(scoped_ptr<pp::ImageData> image, |
| 191 const pp::Point& hotspot) { |
| 192 cursor_image_ = image.Pass(); |
| 193 cursor_hotspot_ = hotspot; |
| 194 |
| 195 if (mouse_lock_state_ != MouseLockDisallowed && !cursor_image_) { |
| 196 RequestMouseLock(); |
| 197 } else { |
| 198 CancelMouseLock(); |
| 199 } |
| 200 } |
| 201 |
| 202 void PepperInputHandler::MouseLockLost() { |
| 203 DCHECK(mouse_lock_state_ == MouseLockOn || |
| 204 mouse_lock_state_ == MouseLockCancelling); |
| 205 |
| 206 mouse_lock_state_ = MouseLockOff; |
| 207 UpdateMouseCursor(); |
| 208 } |
| 209 |
| 210 void PepperInputHandler::RequestMouseLock() { |
| 211 // Request mouse lock only if the plugin is focused, the host-supplied cursor |
| 212 // is empty and no callback is pending. |
| 213 if (has_focus_ && !cursor_image_ && mouse_lock_state_ == MouseLockOff) { |
| 214 pp::CompletionCallback callback = |
| 215 callback_factory_.NewCallback(&PepperInputHandler::OnMouseLocked); |
| 216 int result = pp::MouseLock::LockMouse(callback); |
| 217 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); |
| 218 |
| 219 // Hide cursor to avoid it becoming a black square (see crbug.com/285809). |
| 220 pp::MouseCursor::SetCursor(instance_, PP_MOUSECURSOR_TYPE_NONE); |
| 221 |
| 222 mouse_lock_state_ = MouseLockRequestPending; |
| 223 } |
| 224 } |
| 225 |
| 226 void PepperInputHandler::CancelMouseLock() { |
| 227 switch (mouse_lock_state_) { |
| 228 case MouseLockDisallowed: |
| 229 case MouseLockOff: |
| 230 UpdateMouseCursor(); |
| 231 break; |
| 232 |
| 233 case MouseLockCancelling: |
| 234 break; |
| 235 |
| 236 case MouseLockRequestPending: |
| 237 // The mouse lock request is pending. Delay UnlockMouse() call until |
| 238 // the callback is called. |
| 239 mouse_lock_state_ = MouseLockCancelling; |
| 240 break; |
| 241 |
| 242 case MouseLockOn: |
| 243 pp::MouseLock::UnlockMouse(); |
| 244 |
| 245 // Note that mouse-lock has been cancelled. We will continue to receive |
| 246 // locked events until MouseLockLost() is called back. |
| 247 mouse_lock_state_ = MouseLockCancelling; |
| 248 break; |
| 249 |
| 250 default: |
| 251 NOTREACHED(); |
| 252 } |
| 253 } |
| 254 |
| 255 void PepperInputHandler::UpdateMouseCursor() { |
| 256 DCHECK(mouse_lock_state_ == MouseLockDisallowed || |
| 257 mouse_lock_state_ == MouseLockOff); |
| 258 |
| 259 if (cursor_image_) { |
| 260 pp::MouseCursor::SetCursor(instance_, PP_MOUSECURSOR_TYPE_CUSTOM, |
| 261 *cursor_image_, |
| 262 cursor_hotspot_); |
| 263 } else { |
| 264 // If there is no cursor shape stored, either because the host never |
| 265 // supplied one, or we were previously in mouse-lock mode, then use |
| 266 // a standard arrow pointer. |
| 267 pp::MouseCursor::SetCursor(instance_, PP_MOUSECURSOR_TYPE_POINTER); |
| 268 } |
| 269 } |
| 270 |
| 271 void PepperInputHandler::OnMouseLocked(int error) { |
| 272 DCHECK(mouse_lock_state_ == MouseLockRequestPending || |
| 273 mouse_lock_state_ == MouseLockCancelling); |
| 274 |
| 275 bool should_cancel = (mouse_lock_state_ == MouseLockCancelling); |
| 276 |
| 277 // See if the operation succeeded. |
| 278 if (error == PP_OK) { |
| 279 mouse_lock_state_ = MouseLockOn; |
| 280 } else { |
| 281 mouse_lock_state_ = MouseLockOff; |
| 282 UpdateMouseCursor(); |
| 283 } |
| 284 |
| 285 // Cancel as needed. |
| 286 if (should_cancel) |
| 287 CancelMouseLock(); |
| 288 } |
| 289 |
162 } // namespace remoting | 290 } // namespace remoting |
OLD | NEW |