/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h"

#include "webrtc/modules/desktop_capture/mac/desktop_configuration.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h"

namespace webrtc {

// The amount of time allowed for displays to reconfigure.
static const int64_t kDisplayConfigurationEventTimeoutMs = 10 * 1000;

DesktopConfigurationMonitor::DesktopConfigurationMonitor()
    : ref_count_(0),
      display_configuration_capture_event_(EventWrapper::Create()) {
  CGError err = CGDisplayRegisterReconfigurationCallback(
      DesktopConfigurationMonitor::DisplaysReconfiguredCallback, this);
  if (err != kCGErrorSuccess) {
    LOG(LS_ERROR) << "CGDisplayRegisterReconfigurationCallback " << err;
    abort();
  }
  display_configuration_capture_event_->Set();

  desktop_configuration_ = MacDesktopConfiguration::GetCurrent(
      MacDesktopConfiguration::TopLeftOrigin);
}

DesktopConfigurationMonitor::~DesktopConfigurationMonitor() {
  CGError err = CGDisplayRemoveReconfigurationCallback(
      DesktopConfigurationMonitor::DisplaysReconfiguredCallback, this);
  if (err != kCGErrorSuccess)
    LOG(LS_ERROR) << "CGDisplayRemoveReconfigurationCallback " << err;
}

void DesktopConfigurationMonitor::Lock() {
  if (!display_configuration_capture_event_->Wait(
              kDisplayConfigurationEventTimeoutMs)) {
    LOG_F(LS_ERROR) << "Event wait timed out.";
    abort();
  }
}

void DesktopConfigurationMonitor::Unlock() {
  display_configuration_capture_event_->Set();
}

// static
void DesktopConfigurationMonitor::DisplaysReconfiguredCallback(
    CGDirectDisplayID display,
    CGDisplayChangeSummaryFlags flags,
    void *user_parameter) {
  DesktopConfigurationMonitor* monitor =
      reinterpret_cast<DesktopConfigurationMonitor*>(user_parameter);
  monitor->DisplaysReconfigured(display, flags);
}

void DesktopConfigurationMonitor::DisplaysReconfigured(
    CGDirectDisplayID display,
    CGDisplayChangeSummaryFlags flags) {
  if (flags & kCGDisplayBeginConfigurationFlag) {
    if (reconfiguring_displays_.empty()) {
      // If this is the first display to start reconfiguring then wait on
      // |display_configuration_capture_event_| to block the capture thread
      // from accessing display memory until the reconfiguration completes.
      if (!display_configuration_capture_event_->Wait(
              kDisplayConfigurationEventTimeoutMs)) {
        LOG_F(LS_ERROR) << "Event wait timed out.";
        abort();
      }
    }
    reconfiguring_displays_.insert(display);
  } else {
    reconfiguring_displays_.erase(display);
    if (reconfiguring_displays_.empty()) {
      desktop_configuration_ = MacDesktopConfiguration::GetCurrent(
          MacDesktopConfiguration::TopLeftOrigin);
      display_configuration_capture_event_->Set();
    }
  }
}

}  // namespace webrtc
