18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file.
48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_capture_client.h"
68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ui/aura/window.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/aura/window_tree_host.h"
108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace views {
128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// static
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)DesktopCaptureClient::CaptureClients*
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)DesktopCaptureClient::capture_clients_ = NULL;
168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DesktopCaptureClient::DesktopCaptureClient(aura::Window* root)
188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : root_(root),
198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      capture_window_(NULL) {
201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!capture_clients_)
211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    capture_clients_ = new CaptureClients;
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  capture_clients_->insert(this);
238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  aura::client::SetCaptureClient(root, this);
248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)DesktopCaptureClient::~DesktopCaptureClient() {
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  aura::client::SetCaptureClient(root_, NULL);
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  capture_clients_->erase(this);
298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DesktopCaptureClient::SetCapture(aura::Window* new_capture_window) {
328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (capture_window_ == new_capture_window)
338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // We should only ever be told to capture a child of |root_|. Otherwise
368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // things are going to be really confused.
378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(!new_capture_window ||
388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)         (new_capture_window->GetRootWindow() == root_));
398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(!capture_window_ || capture_window_->GetRootWindow());
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  aura::Window* old_capture_window = capture_window_;
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // If we're actually starting capture, then cancel any touches/gestures
448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // that aren't already locked to the new window, and transfer any on the
458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // old capture window to the new one.  When capture is released we have no
468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // distinction between the touches/gestures that were in the window all
478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // along (and so shouldn't be canceled) and those that got moved, so
488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // just leave them all where they are.
498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (new_capture_window) {
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ui::GestureRecognizer::Get()->TransferEventsTo(old_capture_window,
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        new_capture_window);
528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  capture_window_ = new_capture_window;
558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::client::CaptureDelegate* delegate = root_->GetHost()->dispatcher();
578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  delegate->UpdateCapture(old_capture_window, new_capture_window);
588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Initiate native capture updating.
608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!capture_window_) {
618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    delegate->ReleaseNativeCapture();
628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else if (!old_capture_window) {
638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    delegate->SetNativeCapture();
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Notify the other roots that we got capture. This is important so that
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // they reset state.
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CaptureClients capture_clients(*capture_clients_);
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    for (CaptureClients::iterator i = capture_clients.begin();
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)         i != capture_clients.end(); ++i) {
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (*i != this) {
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        aura::client::CaptureDelegate* delegate =
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            (*i)->root_->GetHost()->dispatcher();
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        delegate->OnOtherRootGotCapture();
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      }
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }  // else case is capture is remaining in our root, nothing to do.
778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DesktopCaptureClient::ReleaseCapture(aura::Window* window) {
808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (capture_window_ != window)
818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SetCapture(NULL);
838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)aura::Window* DesktopCaptureClient::GetCaptureWindow() {
868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return capture_window_;
878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)aura::Window* DesktopCaptureClient::GetGlobalCaptureWindow() {
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (CaptureClients::iterator i = capture_clients_->begin();
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       i != capture_clients_->end(); ++i) {
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if ((*i)->capture_window_)
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return (*i)->capture_window_;
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return NULL;
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace views
99