/*
 *  Copyright (c) 2013 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 "modules/desktop_capture/linux/screen_capturer_x11.h"

#include <X11/Xlib.h>
#include <X11/extensions/Xdamage.h>
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/damagewire.h>
#include <dlfcn.h>
#include <stdint.h>
#include <string.h>

#include <memory>
#include <utility>

#include "modules/desktop_capture/desktop_capture_options.h"
#include "modules/desktop_capture/desktop_capturer.h"
#include "modules/desktop_capture/desktop_frame.h"
#include "modules/desktop_capture/desktop_geometry.h"
#include "modules/desktop_capture/linux/x_server_pixel_buffer.h"
#include "modules/desktop_capture/screen_capture_frame_queue.h"
#include "modules/desktop_capture/screen_capturer_helper.h"
#include "modules/desktop_capture/shared_desktop_frame.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/sanitizer.h"
#include "rtc_base/time_utils.h"
#include "rtc_base/trace_event.h"

namespace webrtc {

ScreenCapturerX11::ScreenCapturerX11() {
  helper_.SetLogGridSize(4);
}

ScreenCapturerX11::~ScreenCapturerX11() {
  options_.x_display()->RemoveEventHandler(ConfigureNotify, this);
  if (use_damage_) {
    options_.x_display()->RemoveEventHandler(damage_event_base_ + XDamageNotify,
                                             this);
  }
  if (use_randr_) {
    options_.x_display()->RemoveEventHandler(
        randr_event_base_ + RRScreenChangeNotify, this);
  }
  DeinitXlib();
}

bool ScreenCapturerX11::Init(const DesktopCaptureOptions& options) {
  TRACE_EVENT0("webrtc", "ScreenCapturerX11::Init");
  options_ = options;

  atom_cache_ = std::make_unique<XAtomCache>(display());

  root_window_ = RootWindow(display(), DefaultScreen(display()));
  if (root_window_ == BadValue) {
    RTC_LOG(LS_ERROR) << "Unable to get the root window";
    DeinitXlib();
    return false;
  }

  gc_ = XCreateGC(display(), root_window_, 0, NULL);
  if (gc_ == NULL) {
    RTC_LOG(LS_ERROR) << "Unable to get graphics context";
    DeinitXlib();
    return false;
  }

  options_.x_display()->AddEventHandler(ConfigureNotify, this);

  // Check for XFixes extension. This is required for cursor shape
  // notifications, and for our use of XDamage.
  if (XFixesQueryExtension(display(), &xfixes_event_base_,
                           &xfixes_error_base_)) {
    has_xfixes_ = true;
  } else {
    RTC_LOG(LS_INFO) << "X server does not support XFixes.";
  }

  // Register for changes to the dimensions of the root window.
  XSelectInput(display(), root_window_, StructureNotifyMask);

  if (!x_server_pixel_buffer_.Init(atom_cache_.get(),
                                   DefaultRootWindow(display()))) {
    RTC_LOG(LS_ERROR) << "Failed to initialize pixel buffer.";
    return false;
  }

  if (options_.use_update_notifications()) {
    InitXDamage();
  }

  InitXrandr();

  // Default source set here so that selected_monitor_rect_ is sized correctly.
  SelectSource(kFullDesktopScreenId);

  return true;
}

void ScreenCapturerX11::InitXDamage() {
  // Our use of XDamage requires XFixes.
  if (!has_xfixes_) {
    return;
  }

  // Check for XDamage extension.
  if (!XDamageQueryExtension(display(), &damage_event_base_,
                             &damage_error_base_)) {
    RTC_LOG(LS_INFO) << "X server does not support XDamage.";
    return;
  }

  // TODO(lambroslambrou): Disable DAMAGE in situations where it is known
  // to fail, such as when Desktop Effects are enabled, with graphics
  // drivers (nVidia, ATI) that fail to report DAMAGE notifications
  // properly.

  // Request notifications every time the screen becomes damaged.
  damage_handle_ =
      XDamageCreate(display(), root_window_, XDamageReportNonEmpty);
  if (!damage_handle_) {
    RTC_LOG(LS_ERROR) << "Unable to initialize XDamage.";
    return;
  }

  // Create an XFixes server-side region to collate damage into.
  damage_region_ = XFixesCreateRegion(display(), 0, 0);
  if (!damage_region_) {
    XDamageDestroy(display(), damage_handle_);
    RTC_LOG(LS_ERROR) << "Unable to create XFixes region.";
    return;
  }

  options_.x_display()->AddEventHandler(damage_event_base_ + XDamageNotify,
                                        this);

  use_damage_ = true;
  RTC_LOG(LS_INFO) << "Using XDamage extension.";
}

RTC_NO_SANITIZE("cfi-icall")
void ScreenCapturerX11::InitXrandr() {
  int major_version = 0;
  int minor_version = 0;
  int error_base_ignored = 0;
  if (XRRQueryExtension(display(), &randr_event_base_, &error_base_ignored) &&
      XRRQueryVersion(display(), &major_version, &minor_version)) {
    if (major_version > 1 || (major_version == 1 && minor_version >= 5)) {
      // Dynamically link XRRGetMonitors and XRRFreeMonitors as a workaround
      // to avoid a dependency issue with Debian 8.
      get_monitors_ = reinterpret_cast<get_monitors_func>(
          dlsym(RTLD_DEFAULT, "XRRGetMonitors"));
      free_monitors_ = reinterpret_cast<free_monitors_func>(
          dlsym(RTLD_DEFAULT, "XRRFreeMonitors"));
      if (get_monitors_ && free_monitors_) {
        use_randr_ = true;
        RTC_LOG(LS_INFO) << "Using XRandR extension v" << major_version << '.'
                         << minor_version << '.';
        monitors_ =
            get_monitors_(display(), root_window_, true, &num_monitors_);

        // Register for screen change notifications
        XRRSelectInput(display(), root_window_, RRScreenChangeNotifyMask);
        options_.x_display()->AddEventHandler(
            randr_event_base_ + RRScreenChangeNotify, this);
      } else {
        RTC_LOG(LS_ERROR) << "Unable to link XRandR monitor functions.";
      }
    } else {
      RTC_LOG(LS_ERROR) << "XRandR entension is older than v1.5.";
    }
  } else {
    RTC_LOG(LS_ERROR) << "X server does not support XRandR.";
  }
}

RTC_NO_SANITIZE("cfi-icall")
void ScreenCapturerX11::UpdateMonitors() {
  if (monitors_) {
    free_monitors_(monitors_);
    monitors_ = nullptr;
  }

  monitors_ = get_monitors_(display(), root_window_, true, &num_monitors_);

  if (selected_monitor_name_) {
    if (selected_monitor_name_ == static_cast<Atom>(kFullDesktopScreenId)) {
      selected_monitor_rect_ =
          DesktopRect::MakeSize(x_server_pixel_buffer_.window_size());
      return;
    }

    for (int i = 0; i < num_monitors_; ++i) {
      XRRMonitorInfo& m = monitors_[i];
      if (selected_monitor_name_ == m.name) {
        RTC_LOG(LS_INFO) << "XRandR monitor " << m.name << " rect updated.";
        selected_monitor_rect_ =
            DesktopRect::MakeXYWH(m.x, m.y, m.width, m.height);
        const auto& pixel_buffer_rect = x_server_pixel_buffer_.window_rect();
        if (!pixel_buffer_rect.ContainsRect(selected_monitor_rect_)) {
          // This is never expected to happen, but crop the rectangle anyway
          // just in case the server returns inconsistent information.
          // CaptureScreen() expects `selected_monitor_rect_` to lie within
          // the pixel-buffer's rectangle.
          RTC_LOG(LS_WARNING)
              << "Cropping selected monitor rect to fit the pixel-buffer.";
          selected_monitor_rect_.IntersectWith(pixel_buffer_rect);
        }
        return;
      }
    }

    // The selected monitor is not connected anymore
    RTC_LOG(LS_INFO) << "XRandR selected monitor " << selected_monitor_name_
                     << " lost.";
    selected_monitor_rect_ = DesktopRect::MakeWH(0, 0);
  }
}

void ScreenCapturerX11::Start(Callback* callback) {
  RTC_DCHECK(!callback_);
  RTC_DCHECK(callback);

  callback_ = callback;
}

void ScreenCapturerX11::CaptureFrame() {
  TRACE_EVENT0("webrtc", "ScreenCapturerX11::CaptureFrame");
  int64_t capture_start_time_nanos = rtc::TimeNanos();

  queue_.MoveToNextFrame();
  if (queue_.current_frame() && queue_.current_frame()->IsShared()) {
    RTC_DLOG(LS_WARNING) << "Overwriting frame that is still shared.";
  }

  // Process XEvents for XDamage and cursor shape tracking.
  options_.x_display()->ProcessPendingXEvents();

  // ProcessPendingXEvents() may call ScreenConfigurationChanged() which
  // reinitializes `x_server_pixel_buffer_`. Check if the pixel buffer is still
  // in a good shape.
  if (!x_server_pixel_buffer_.is_initialized()) {
    // We failed to initialize pixel buffer.
    RTC_LOG(LS_ERROR) << "Pixel buffer is not initialized.";
    callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
    return;
  }

  // Allocate the current frame buffer only if it is not already allocated.
  // Note that we can't reallocate other buffers at this point, since the caller
  // may still be reading from them.
  if (!queue_.current_frame()) {
    std::unique_ptr<DesktopFrame> frame(
        new BasicDesktopFrame(selected_monitor_rect_.size()));

    // We set the top-left of the frame so the mouse cursor will be composited
    // properly, and our frame buffer will not be overrun while blitting.
    frame->set_top_left(selected_monitor_rect_.top_left());
    queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(frame)));
  }

  std::unique_ptr<DesktopFrame> result = CaptureScreen();
  if (!result) {
    RTC_LOG(LS_WARNING) << "Temporarily failed to capture screen.";
    callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
    return;
  }

  last_invalid_region_ = result->updated_region();
  result->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) /
                              rtc::kNumNanosecsPerMillisec);
  callback_->OnCaptureResult(Result::SUCCESS, std::move(result));
}

bool ScreenCapturerX11::GetSourceList(SourceList* sources) {
  RTC_DCHECK(sources->size() == 0);
  if (!use_randr_) {
    sources->push_back({});
    return true;
  }

  // Ensure that `monitors_` is updated with changes that may have happened
  // between calls to GetSourceList().
  options_.x_display()->ProcessPendingXEvents();

  for (int i = 0; i < num_monitors_; ++i) {
    XRRMonitorInfo& m = monitors_[i];
    char* monitor_title = XGetAtomName(display(), m.name);

    // Note name is an X11 Atom used to id the monitor.
    sources->push_back({static_cast<SourceId>(m.name), monitor_title});
    XFree(monitor_title);
  }

  return true;
}

bool ScreenCapturerX11::SelectSource(SourceId id) {
  // Prevent the reuse of any frame buffers allocated for a previously selected
  // source. This is required to stop crashes, or old data from appearing in
  // a captured frame, when the new source is sized differently then the source
  // that was selected at the time a reused frame buffer was created.
  queue_.Reset();

  if (!use_randr_ || id == kFullDesktopScreenId) {
    selected_monitor_name_ = kFullDesktopScreenId;
    selected_monitor_rect_ =
        DesktopRect::MakeSize(x_server_pixel_buffer_.window_size());
    return true;
  }

  for (int i = 0; i < num_monitors_; ++i) {
    if (id == static_cast<SourceId>(monitors_[i].name)) {
      RTC_LOG(LS_INFO) << "XRandR selected source: " << id;
      XRRMonitorInfo& m = monitors_[i];
      selected_monitor_name_ = m.name;
      selected_monitor_rect_ =
          DesktopRect::MakeXYWH(m.x, m.y, m.width, m.height);
      return true;
    }
  }
  return false;
}

bool ScreenCapturerX11::HandleXEvent(const XEvent& event) {
  if (use_damage_ && (event.type == damage_event_base_ + XDamageNotify)) {
    const XDamageNotifyEvent* damage_event =
        reinterpret_cast<const XDamageNotifyEvent*>(&event);
    if (damage_event->damage != damage_handle_)
      return false;
    RTC_DCHECK(damage_event->level == XDamageReportNonEmpty);
    return true;
  } else if (use_randr_ &&
             event.type == randr_event_base_ + RRScreenChangeNotify) {
    XRRUpdateConfiguration(const_cast<XEvent*>(&event));
    UpdateMonitors();
    RTC_LOG(LS_INFO) << "XRandR screen change event received.";
    return true;
  } else if (event.type == ConfigureNotify) {
    ScreenConfigurationChanged();
    return true;
  }
  return false;
}

std::unique_ptr<DesktopFrame> ScreenCapturerX11::CaptureScreen() {
  std::unique_ptr<SharedDesktopFrame> frame = queue_.current_frame()->Share();
  RTC_DCHECK(selected_monitor_rect_.size().equals(frame->size()));
  RTC_DCHECK(selected_monitor_rect_.top_left().equals(frame->top_left()));

  // Pass the screen size to the helper, so it can clip the invalid region if it
  // expands that region to a grid.
  helper_.set_size_most_recent(x_server_pixel_buffer_.window_size());

  // In the DAMAGE case, ensure the frame is up-to-date with the previous frame
  // if any.  If there isn't a previous frame, that means a screen-resolution
  // change occurred, and `invalid_rects` will be updated to include the whole
  // screen.
  if (use_damage_ && queue_.previous_frame())
    SynchronizeFrame();

  DesktopRegion* updated_region = frame->mutable_updated_region();

  x_server_pixel_buffer_.Synchronize();
  if (use_damage_ && queue_.previous_frame()) {
    // Atomically fetch and clear the damage region.
    XDamageSubtract(display(), damage_handle_, None, damage_region_);
    int rects_num = 0;
    XRectangle bounds;
    XRectangle* rects = XFixesFetchRegionAndBounds(display(), damage_region_,
                                                   &rects_num, &bounds);
    for (int i = 0; i < rects_num; ++i) {
      auto damage_rect = DesktopRect::MakeXYWH(rects[i].x, rects[i].y,
                                               rects[i].width, rects[i].height);

      // Damage regions are in the same coordinate-system as
      // ```selected_monitor_rect_```, but may fall outside of it.
      damage_rect.IntersectWith(selected_monitor_rect_);
      if (!damage_rect.is_empty()) {
        // Convert to DesktopFrame coordinates where the top-left is
        // always (0, 0), before adding to the frame's update_region.
        damage_rect.Translate(-frame->top_left());
        updated_region->AddRect(damage_rect);
      }
    }
    XFree(rects);
    helper_.InvalidateRegion(*updated_region);

    // Capture the damaged portions of the desktop.
    helper_.TakeInvalidRegion(updated_region);

    for (DesktopRegion::Iterator it(*updated_region); !it.IsAtEnd();
         it.Advance()) {
      auto rect = it.rect();
      rect.Translate(frame->top_left());
      if (!x_server_pixel_buffer_.CaptureRect(rect, frame.get()))
        return nullptr;
    }
  } else {
    // Doing full-screen polling, or this is the first capture after a
    // screen-resolution change.  In either case, need a full-screen capture.
    if (!x_server_pixel_buffer_.CaptureRect(selected_monitor_rect_,
                                            frame.get())) {
      return nullptr;
    }
    updated_region->SetRect(DesktopRect::MakeSize(frame->size()));
  }

  return std::move(frame);
}

void ScreenCapturerX11::ScreenConfigurationChanged() {
  TRACE_EVENT0("webrtc", "ScreenCapturerX11::ScreenConfigurationChanged");
  // Make sure the frame buffers will be reallocated.
  queue_.Reset();

  helper_.ClearInvalidRegion();
  if (!x_server_pixel_buffer_.Init(atom_cache_.get(),
                                   DefaultRootWindow(display()))) {
    RTC_LOG(LS_ERROR) << "Failed to initialize pixel buffer after screen "
                         "configuration change.";
  }

  if (use_randr_) {
    // Adding/removing RANDR monitors can generate a ConfigureNotify event
    // without generating any RRScreenChangeNotify event. So it is important to
    // update the monitors here even if the screen resolution hasn't changed.
    UpdateMonitors();
  } else {
    selected_monitor_rect_ =
        DesktopRect::MakeSize(x_server_pixel_buffer_.window_size());
  }
}

void ScreenCapturerX11::SynchronizeFrame() {
  // Synchronize the current buffer with the previous one since we do not
  // capture the entire desktop. Note that encoder may be reading from the
  // previous buffer at this time so thread access complaints are false
  // positives.

  // TODO(hclam): We can reduce the amount of copying here by subtracting
  // `capturer_helper_`s region from `last_invalid_region_`.
  // http://crbug.com/92354
  RTC_DCHECK(queue_.previous_frame());

  DesktopFrame* current = queue_.current_frame();
  DesktopFrame* last = queue_.previous_frame();
  RTC_DCHECK(current != last);
  for (DesktopRegion::Iterator it(last_invalid_region_); !it.IsAtEnd();
       it.Advance()) {
    const DesktopRect& r = it.rect();
    current->CopyPixelsFrom(*last, r.top_left(), r);
  }
}

RTC_NO_SANITIZE("cfi-icall")
void ScreenCapturerX11::DeinitXlib() {
  if (monitors_) {
    free_monitors_(monitors_);
    monitors_ = nullptr;
  }

  if (gc_) {
    XFreeGC(display(), gc_);
    gc_ = nullptr;
  }

  x_server_pixel_buffer_.Release();

  if (display()) {
    if (damage_handle_) {
      XDamageDestroy(display(), damage_handle_);
      damage_handle_ = 0;
    }

    if (damage_region_) {
      XFixesDestroyRegion(display(), damage_region_);
      damage_region_ = 0;
    }
  }
}

// static
std::unique_ptr<DesktopCapturer> ScreenCapturerX11::CreateRawScreenCapturer(
    const DesktopCaptureOptions& options) {
  if (!options.x_display())
    return nullptr;

  std::unique_ptr<ScreenCapturerX11> capturer(new ScreenCapturerX11());
  if (!capturer.get()->Init(options)) {
    return nullptr;
  }

  return std::move(capturer);
}

}  // namespace webrtc
