Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / remoting / client / plugin / pepper_mouse_locker.cc
blob8b0338a8eb73d595bb049ec250c9b0ab91853691
1 // Copyright 2014 The Chromium Authors. 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 "remoting/client/plugin/pepper_mouse_locker.h"
7 #include "base/logging.h"
8 #include "remoting/client/plugin/empty_cursor_filter.h"
9 #include "remoting/proto/control.pb.h"
11 namespace remoting {
13 PepperMouseLocker::PepperMouseLocker(
14 pp::Instance* instance,
15 const base::Callback<void(bool)>& enable_mouse_deltas,
16 protocol::CursorShapeStub* cursor_stub)
17 : pp::MouseLock(instance),
18 enable_mouse_deltas_(enable_mouse_deltas),
19 cursor_stub_(cursor_stub),
20 cursor_shape_(new protocol::CursorShapeInfo),
21 callback_factory_(this),
22 has_focus_(false),
23 mouse_lock_state_(MouseLockOff) {
24 *cursor_shape_ = EmptyCursorShape();
27 PepperMouseLocker::~PepperMouseLocker() {}
29 void PepperMouseLocker::DidChangeFocus(bool has_focus) {
30 has_focus_ = has_focus;
31 if (has_focus_)
32 RequestMouseLock();
35 void PepperMouseLocker::SetCursorShape(
36 const protocol::CursorShapeInfo& cursor_shape) {
37 *cursor_shape_ = cursor_shape;
38 if (IsCursorShapeEmpty(*cursor_shape_)) {
39 RequestMouseLock();
40 } else {
41 CancelMouseLock();
45 void PepperMouseLocker::MouseLockLost() {
46 DCHECK(mouse_lock_state_ == MouseLockOn ||
47 mouse_lock_state_ == MouseLockCancelling);
49 OnMouseLockOff();
52 void PepperMouseLocker::OnMouseLocked(int error) {
53 DCHECK(mouse_lock_state_ == MouseLockRequestPending ||
54 mouse_lock_state_ == MouseLockCancelling);
56 bool should_cancel = (mouse_lock_state_ == MouseLockCancelling);
58 // See if the operation succeeded.
59 if (error == PP_OK) {
60 mouse_lock_state_ = MouseLockOn;
61 } else {
62 OnMouseLockOff();
65 // Cancel as needed.
66 if (should_cancel)
67 CancelMouseLock();
70 void PepperMouseLocker::OnMouseLockOff() {
71 mouse_lock_state_ = MouseLockOff;
72 cursor_stub_->SetCursorShape(*cursor_shape_);
75 void PepperMouseLocker::RequestMouseLock() {
76 // Request mouse lock only if the plugin is focused, the host-supplied cursor
77 // is empty and no callback is pending.
78 if (!has_focus_)
79 return;
80 if (!IsCursorShapeEmpty(*cursor_shape_))
81 return;
82 if (mouse_lock_state_ != MouseLockOff)
83 return;
85 pp::CompletionCallback callback =
86 callback_factory_.NewCallback(&PepperMouseLocker::OnMouseLocked);
87 int result = pp::MouseLock::LockMouse(callback);
88 if (result != PP_OK_COMPLETIONPENDING) {
89 LOG(ERROR) << "Unexpected MouseLock result:" << result;
90 return;
92 mouse_lock_state_ = MouseLockRequestPending;
94 // Hide cursor to avoid it becoming a black square (see crbug.com/285809).
95 cursor_stub_->SetCursorShape(EmptyCursorShape());
98 void PepperMouseLocker::CancelMouseLock() {
99 switch (mouse_lock_state_) {
100 case MouseLockOff:
101 OnMouseLockOff();
102 break;
104 case MouseLockCancelling:
105 break;
107 case MouseLockRequestPending:
108 // The mouse lock request is pending. Delay UnlockMouse() call until
109 // the callback is called.
110 mouse_lock_state_ = MouseLockCancelling;
111 break;
113 case MouseLockOn:
114 pp::MouseLock::UnlockMouse();
116 // Note that mouse-lock has been cancelled. We will continue to receive
117 // locked events until MouseLockLost() is called back.
118 mouse_lock_state_ = MouseLockCancelling;
119 break;
121 default:
122 NOTREACHED();
126 } // namespace remoting