- add sources.
[platform/framework/web/crosswalk.git] / src / content / renderer / mouse_lock_dispatcher.cc
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
3 // found in the LICENSE file.
4
5 #include "content/renderer/mouse_lock_dispatcher.h"
6
7 #include "base/logging.h"
8 #include "third_party/WebKit/public/web/WebInputEvent.h"
9
10 namespace content {
11
12 MouseLockDispatcher::MouseLockDispatcher() : mouse_locked_(false),
13                                              pending_lock_request_(false),
14                                              pending_unlock_request_(false),
15                                              unlocked_by_target_(false),
16                                              target_(NULL) {
17 }
18
19 MouseLockDispatcher::~MouseLockDispatcher() {
20 }
21
22 bool MouseLockDispatcher::LockMouse(LockTarget* target) {
23   if (MouseLockedOrPendingAction())
24     return false;
25
26   pending_lock_request_ = true;
27   target_ = target;
28
29   SendLockMouseRequest(unlocked_by_target_);
30   unlocked_by_target_ = false;
31   return true;
32 }
33
34 void MouseLockDispatcher::UnlockMouse(LockTarget* target) {
35   if (target && target == target_ && !pending_unlock_request_) {
36     pending_unlock_request_ = true;
37
38     // When a target application voluntarily unlocks the mouse we permit
39     // relocking the mouse silently and with no user gesture requirement.
40     // Check that the lock request is not currently pending and not yet
41     // accepted by the browser process before setting |unlocked_by_target_|.
42     if (!pending_lock_request_)
43       unlocked_by_target_ = true;
44
45     SendUnlockMouseRequest();
46   }
47 }
48
49 void MouseLockDispatcher::OnLockTargetDestroyed(LockTarget* target) {
50   if (target == target_) {
51     UnlockMouse(target);
52     target_ = NULL;
53   }
54 }
55
56 bool MouseLockDispatcher::IsMouseLockedTo(LockTarget* target) {
57   return mouse_locked_ && target_ == target;
58 }
59
60 bool MouseLockDispatcher::WillHandleMouseEvent(
61     const WebKit::WebMouseEvent& event) {
62   if (mouse_locked_ && target_)
63     return target_->HandleMouseLockedInputEvent(event);
64   return false;
65 }
66
67 void MouseLockDispatcher::OnLockMouseACK(bool succeeded) {
68   DCHECK(!mouse_locked_ && pending_lock_request_);
69
70   mouse_locked_ = succeeded;
71   pending_lock_request_ = false;
72   if (pending_unlock_request_ && !succeeded) {
73     // We have sent an unlock request after the lock request. However, since
74     // the lock request has failed, the unlock request will be ignored by the
75     // browser side and there won't be any response to it.
76     pending_unlock_request_ = false;
77   }
78
79   LockTarget* last_target = target_;
80   if (!succeeded)
81     target_ = NULL;
82
83   // Callbacks made after all state modification to prevent reentrant errors
84   // such as OnLockMouseACK() synchronously calling LockMouse().
85
86   if (last_target)
87     last_target->OnLockMouseACK(succeeded);
88 }
89
90 void MouseLockDispatcher::OnMouseLockLost() {
91   DCHECK(mouse_locked_ && !pending_lock_request_);
92
93   mouse_locked_ = false;
94   pending_unlock_request_ = false;
95
96   LockTarget* last_target = target_;
97   target_ = NULL;
98
99   // Callbacks made after all state modification to prevent reentrant errors
100   // such as OnMouseLockLost() synchronously calling LockMouse().
101
102   if (last_target)
103     last_target->OnMouseLockLost();
104 }
105
106 }  // namespace content