// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/host/desktop_resizer_x11.h"

#include <string.h>

#include "base/command_line.h"
#include "base/cxx17_backports.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "remoting/base/logging.h"
#include "remoting/host/linux/x11_util.h"
#include "ui/gfx/x/future.h"
#include "ui/gfx/x/randr.h"
#include "ui/gfx/x/scoped_ignore_errors.h"

// On Linux, we use the xrandr extension to change the desktop resolution. In
// curtain mode, we do exact resize where supported (currently only using a
// patched Xvfb server). Otherwise, we try to pick the best resolution from the
// existing modes.
//
// Xrandr has a number of restrictions that make exact resize more complex:
//
//   1. It's not possible to change the resolution of an existing mode. Instead,
//      the mode must be deleted and recreated.
//   2. It's not possible to delete a mode that's in use.
//   3. Errors are communicated via Xlib's spectacularly unhelpful mechanism
//      of terminating the process unless you install an error handler.
//
// The basic approach is as follows:
//
//   1. Create a new mode with the correct resolution;
//   2. Switch to the new mode;
//   3. Delete the old mode.
//
// Since the new mode must have a different name, and we want the current mode
// name to be consistent, we then additionally:
//
//   4. Recreate the old mode at the new resolution;
//   5. Switch to the old mode;
//   6. Delete the temporary mode.
//
// Name consistency will allow a future CL to disable resize-to-client if the
// user has changed the mode to something other than "Chrome Remote Desktop
// client resolution". It doesn't make the code significantly more complex.

namespace {

constexpr auto kInvalidMode = static_cast<x11::RandR::Mode>(0);

int PixelsToMillimeters(int pixels, int dpi) {
  DCHECK(dpi != 0);

  const double kMillimetersPerInch = 25.4;

  // (pixels / dpi) is the length in inches. Multiplying by
  // kMillimetersPerInch converts to mm. Multiplication is done first to
  // avoid integer division.
  return static_cast<int>(kMillimetersPerInch * pixels / dpi);
}

// TODO(jamiewalch): Use the correct DPI for the mode: http://crbug.com/172405.
const int kDefaultDPI = 96;

}  // namespace

namespace remoting {

ScreenResources::ScreenResources() = default;

ScreenResources::~ScreenResources() = default;

bool ScreenResources::Refresh(x11::RandR* randr, x11::Window window) {
  resources_ = nullptr;
  if (auto response = randr->GetScreenResourcesCurrent({window}).Sync())
    resources_ = std::move(response.reply);
  return resources_ != nullptr;
}

x11::RandR::Mode ScreenResources::GetIdForMode(const std::string& name) {
  CHECK(resources_);
  const char* names = reinterpret_cast<const char*>(resources_->names.data());
  for (const auto& mode_info : resources_->modes) {
    std::string mode_name(names, mode_info.name_len);
    names += mode_info.name_len;
    if (name == mode_name)
      return static_cast<x11::RandR::Mode>(mode_info.id);
  }
  return kInvalidMode;
}

x11::RandR::Output ScreenResources::GetOutput() {
  CHECK(resources_);
  return resources_->outputs[0];
}

x11::RandR::Crtc ScreenResources::GetCrtc() {
  CHECK(resources_);
  return resources_->crtcs[0];
}

x11::RandR::GetScreenResourcesCurrentReply* ScreenResources::get() {
  return resources_.get();
}

DesktopResizerX11::DesktopResizerX11()
    : connection_(x11::Connection::Get()),
      randr_(&connection_->randr()),
      screen_(&connection_->default_screen()),
      root_(screen_->root),
      exact_resize_(base::CommandLine::ForCurrentProcess()->HasSwitch(
          "server-supports-exact-resize")) {
  has_randr_ = randr_->present();
  if (!has_randr_)
    return;
  // Let the server know the client version so it sends us data consistent with
  // xcbproto's definitions.  We don't care about the returned server version,
  // so no need to sync.
  randr_->QueryVersion({x11::RandR::major_version, x11::RandR::minor_version});
  randr_->SelectInput({root_, x11::RandR::NotifyMask::ScreenChange});
}

DesktopResizerX11::~DesktopResizerX11() = default;

ScreenResolution DesktopResizerX11::GetCurrentResolution() {
  // Process pending events so that the connection setup data is updated
  // with the correct display metrics.
  if (has_randr_)
    connection_->DispatchAll();

  ScreenResolution result(
      webrtc::DesktopSize(connection_->default_screen().width_in_pixels,
                          connection_->default_screen().height_in_pixels),
      webrtc::DesktopVector(kDefaultDPI, kDefaultDPI));
  return result;
}

std::list<ScreenResolution> DesktopResizerX11::GetSupportedResolutions(
    const ScreenResolution& preferred) {
  std::list<ScreenResolution> result;
  if (!has_randr_)
    return result;
  if (exact_resize_) {
    // Clamp the specified size to something valid for the X server.
    if (auto response = randr_->GetScreenSizeRange({root_}).Sync()) {
      int width =
          base::clamp(static_cast<uint16_t>(preferred.dimensions().width()),
                      response->min_width, response->max_width);
      int height =
          base::clamp(static_cast<uint16_t>(preferred.dimensions().height()),
                      response->min_height, response->max_height);
      // Additionally impose a minimum size of 640x480, since anything smaller
      // doesn't seem very useful.
      ScreenResolution actual(
          webrtc::DesktopSize(std::max(640, width), std::max(480, height)),
          webrtc::DesktopVector(kDefaultDPI, kDefaultDPI));
      result.push_back(actual);
    }
  } else {
    // Retrieve supported resolutions with RandR
    if (auto response = randr_->GetScreenInfo({root_}).Sync()) {
      for (const auto& size : response->sizes) {
        result.emplace_back(webrtc::DesktopSize(size.width, size.height),
                            webrtc::DesktopVector(kDefaultDPI, kDefaultDPI));
      }
    }
  }
  return result;
}

void DesktopResizerX11::SetResolution(const ScreenResolution& resolution) {
  if (!has_randr_)
    return;

  // Ignore X errors encountered while resizing the display. We might hit an
  // error, for example if xrandr has been used to add a mode with the same
  // name as our temporary mode, or to remove the "client resolution" mode. We
  // don't want to terminate the process if this happens.
  x11::ScopedIgnoreErrors ignore_errors(connection_);

  // Grab the X server while we're changing the display resolution. This ensures
  // that the display configuration doesn't change under our feet.
  ScopedXGrabServer grabber(connection_);

  if (exact_resize_)
    SetResolutionNewMode(resolution);
  else
    SetResolutionExistingMode(resolution);
}

void DesktopResizerX11::RestoreResolution(const ScreenResolution& original) {
  SetResolution(original);
}

void DesktopResizerX11::SetResolutionNewMode(
    const ScreenResolution& resolution) {
  // The name of the mode representing the current client view resolution and
  // the temporary mode used for the reasons described at the top of this file.
  // The former should be localized if it's user-visible; the latter only
  // exists briefly and does not need to localized.
  const char* kModeName = "Chrome Remote Desktop client resolution";
  const char* kTempModeName = "Chrome Remote Desktop temporary mode";

  // Actually do the resize operation, preserving the current mode name. Note
  // that we have to detach the output from any mode in order to resize it
  // (strictly speaking, this is only required when reducing the size, but it
  // seems safe to do it regardless).
  HOST_LOG << "Changing desktop size to " << resolution.dimensions().width()
           << "x" << resolution.dimensions().height();

  // TODO(lambroslambrou): Use the DPI from client size information.
  uint32_t width_mm =
      PixelsToMillimeters(resolution.dimensions().width(), kDefaultDPI);
  uint32_t height_mm =
      PixelsToMillimeters(resolution.dimensions().height(), kDefaultDPI);
  CreateMode(kTempModeName, resolution.dimensions().width(),
             resolution.dimensions().height());
  SwitchToMode(nullptr);
  randr_->SetScreenSize(
      {root_, static_cast<uint16_t>(resolution.dimensions().width()),
       static_cast<uint16_t>(resolution.dimensions().height()), width_mm,
       height_mm});
  SwitchToMode(kTempModeName);
  DeleteMode(kModeName);
  CreateMode(kModeName, resolution.dimensions().width(),
             resolution.dimensions().height());
  SwitchToMode(kModeName);
  DeleteMode(kTempModeName);
}

void DesktopResizerX11::SetResolutionExistingMode(
    const ScreenResolution& resolution) {
  if (auto config = randr_->GetScreenInfo({root_}).Sync()) {
    x11::RandR::Rotation current_rotation = config->rotation;
    const std::vector<x11::RandR::ScreenSize>& sizes = config->sizes;
    for (size_t i = 0; i < sizes.size(); ++i) {
      if (sizes[i].width == resolution.dimensions().width() &&
          sizes[i].height == resolution.dimensions().height()) {
        randr_->SetScreenConfig({
            .window = root_,
            .timestamp = x11::Time::CurrentTime,
            .config_timestamp = config->config_timestamp,
            .sizeID = static_cast<uint16_t>(i),
            .rotation = current_rotation,
            .rate = 0,
        });
        break;
      }
    }
  }
}

void DesktopResizerX11::CreateMode(const char* name, int width, int height) {
  x11::RandR::ModeInfo mode;
  mode.width = width;
  mode.height = height;
  mode.name_len = strlen(name);
  randr_->CreateMode({root_, mode, name});

  if (!resources_.Refresh(randr_, root_))
    return;
  x11::RandR::Mode mode_id = resources_.GetIdForMode(name);
  if (mode_id == kInvalidMode)
    return;
  randr_->AddOutputMode({
      resources_.GetOutput(),
      mode_id,
  });
}

void DesktopResizerX11::DeleteMode(const char* name) {
  x11::RandR::Mode mode_id = resources_.GetIdForMode(name);
  if (mode_id != kInvalidMode) {
    randr_->DeleteOutputMode({resources_.GetOutput(), mode_id});
    randr_->DestroyMode({mode_id});
    resources_.Refresh(randr_, root_);
  }
}

void DesktopResizerX11::SwitchToMode(const char* name) {
  auto mode_id = kInvalidMode;
  std::vector<x11::RandR::Output> outputs;
  if (name) {
    mode_id = resources_.GetIdForMode(name);
    CHECK_NE(mode_id, kInvalidMode);
    outputs = resources_.get()->outputs;
  }
  const auto* resources = resources_.get();
  randr_->SetCrtcConfig({
      .crtc = resources_.GetCrtc(),
      .timestamp = x11::Time::CurrentTime,
      .config_timestamp = resources->config_timestamp,
      .x = 0,
      .y = 0,
      .mode = mode_id,
      .rotation = x11::RandR::Rotation::Rotate_0,
      .outputs = outputs,
  });
}

}  // namespace remoting
