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 10namespace content { 11 12MouseLockDispatcher::MouseLockDispatcher() : mouse_locked_(false), 13 pending_lock_request_(false), 14 pending_unlock_request_(false), 15 unlocked_by_target_(false), 16 target_(NULL) { 17} 18 19MouseLockDispatcher::~MouseLockDispatcher() { 20} 21 22bool 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 34void 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 49void MouseLockDispatcher::OnLockTargetDestroyed(LockTarget* target) { 50 if (target == target_) { 51 UnlockMouse(target); 52 target_ = NULL; 53 } 54} 55 56bool MouseLockDispatcher::IsMouseLockedTo(LockTarget* target) { 57 return mouse_locked_ && target_ == target; 58} 59 60bool MouseLockDispatcher::WillHandleMouseEvent( 61 const blink::WebMouseEvent& event) { 62 if (mouse_locked_ && target_) 63 return target_->HandleMouseLockedInputEvent(event); 64 return false; 65} 66 67void 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 90void 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 107