// 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.h"
#include "remoting/host/linux/x11_util.h"

#include <string.h>
#include <X11/extensions/Xrandr.h>
#include <X11/Xlib.h>

#include "base/command_line.h"
#include "remoting/base/logging.h"

// On Linux, we use the xrandr extension to change the desktop resolution. For
// now, we only support resize-to-client for Xvfb-based servers that can match
// the client resolution exactly. To support best-resolution matching, it would
// be necessary to implement |GetSupportedResolutions|, but it's not considered
// a priority now.
//
// Xrandr has a number of restrictions that make this code 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 {

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 {

// Wrapper class for the XRRScreenResources struct.
class ScreenResources {
 public:
  ScreenResources() : resources_(NULL) {
  }

  ~ScreenResources() {
    Release();
  }

  bool Refresh(Display* display, Window window) {
    Release();
    resources_ = XRRGetScreenResources(display, window);
    return resources_ != NULL;
  }

  void Release() {
    if (resources_) {
      XRRFreeScreenResources(resources_);
      resources_ = NULL;
    }
  }

  RRMode GetIdForMode(const char* name) {
    CHECK(resources_);
    for (int i = 0; i < resources_->nmode; ++i) {
      const XRRModeInfo& mode = resources_->modes[i];
      if (strcmp(mode.name, name) == 0) {
        return mode.id;
      }
    }
    return 0;
  }

  // For now, assume we're only ever interested in the first output.
  RROutput GetOutput() {
    CHECK(resources_);
    return resources_->outputs[0];
  }

  // For now, assume we're only ever interested in the first crtc.
  RRCrtc GetCrtc() {
    CHECK(resources_);
    return resources_->crtcs[0];
  }

  XRROutputInfo* GetOutputInfo(Display* display, RROutput output_id) {
    CHECK(resources_);
    return XRRGetOutputInfo(display, resources_, output_id);
  }

  XRRScreenResources* get() { return resources_; }

 private:
  XRRScreenResources* resources_;
};


class DesktopResizerLinux : public DesktopResizer {
 public:
  DesktopResizerLinux();
  virtual ~DesktopResizerLinux();

  // DesktopResizer interface
  virtual ScreenResolution GetCurrentResolution() OVERRIDE;
  virtual std::list<ScreenResolution> GetSupportedResolutions(
      const ScreenResolution& preferred) OVERRIDE;
  virtual void SetResolution(const ScreenResolution& resolution) OVERRIDE;
  virtual void RestoreResolution(const ScreenResolution& original) OVERRIDE;

 private:
  // Create a mode, and attach it to the primary output. If the mode already
  // exists, it is left unchanged.
  void CreateMode(const char* name, int width, int height);

  // Remove the specified mode from the primary output, and delete it. If the
  // mode is in use, it is not deleted.
  void DeleteMode(const char* name);

  // Switch the primary output to the specified mode. If name is NULL, the
  // primary output is disabled instead, which is required before changing
  // its resolution.
  void SwitchToMode(const char* name);

  Display* display_;
  int screen_;
  Window root_;
  ScreenResources resources_;
  bool exact_resize_;

  DISALLOW_COPY_AND_ASSIGN(DesktopResizerLinux);
};

DesktopResizerLinux::DesktopResizerLinux()
    : display_(XOpenDisplay(NULL)),
      screen_(DefaultScreen(display_)),
      root_(RootWindow(display_, screen_)),
      exact_resize_(CommandLine::ForCurrentProcess()->
                    HasSwitch("server-supports-exact-resize")) {
  XRRSelectInput (display_, root_, RRScreenChangeNotifyMask);
}

DesktopResizerLinux::~DesktopResizerLinux() {
  XCloseDisplay(display_);
}

ScreenResolution DesktopResizerLinux::GetCurrentResolution() {
  if (!exact_resize_) {
    // TODO(jamiewalch): Remove this early return if we decide to support
    // non-Xvfb servers.
    return ScreenResolution();
  }

  // TODO(lambroslambrou): Xrandr requires that we process RRScreenChangeNotify
  // events, otherwise DisplayWidth and DisplayHeight do not return the current
  // values. Normally, this would be done via a central X event loop, but we
  // don't have one, hence this horrible hack.
  //
  // Note that the WatchFileDescriptor approach taken in XServerClipboard
  // doesn't work here because resize events have already been read from the
  // X server socket by the time the resize function returns, hence the
  // file descriptor is never seen as readable.
  while (XEventsQueued(display_, QueuedAlready)) {
    XEvent event;
    XNextEvent(display_, &event);
    XRRUpdateConfiguration(&event);
  }

  ScreenResolution result(
      webrtc::DesktopSize(
          DisplayWidth(display_, DefaultScreen(display_)),
          DisplayHeight(display_, DefaultScreen(display_))),
      webrtc::DesktopVector(kDefaultDPI, kDefaultDPI));
  return result;
}

std::list<ScreenResolution> DesktopResizerLinux::GetSupportedResolutions(
    const ScreenResolution& preferred) {
  std::list<ScreenResolution> result;
  if (exact_resize_) {
    // Clamp the specified size to something valid for the X server.
    int min_width = 0, min_height = 0, max_width = 0, max_height = 0;
    XRRGetScreenSizeRange(display_, root_,
                          &min_width, &min_height,
                          &max_width, &max_height);
    int width = std::min(std::max(preferred.dimensions().width(), min_width),
                         max_width);
    int height = std::min(std::max(preferred.dimensions().height(), min_height),
                          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 {
    // TODO(jamiewalch): Return the list of supported resolutions if we can't
    // support exact-size matching.
  }
  return result;
}

void DesktopResizerLinux::SetResolution(const ScreenResolution& resolution) {
  if (!exact_resize_) {
    // TODO(jamiewalch): Remove this early return if we decide to support
    // non-Xvfb servers.
    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.
  ScopedXErrorHandler handler(ScopedXErrorHandler::Ignore());

  // 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(display_);

  // 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.
  int width_mm = PixelsToMillimeters(resolution.dimensions().width(),
                                     kDefaultDPI);
  int height_mm = PixelsToMillimeters(resolution.dimensions().height(),
                                      kDefaultDPI);
  CreateMode(kTempModeName, resolution.dimensions().width(),
             resolution.dimensions().height());
  SwitchToMode(NULL);
  XRRSetScreenSize(display_, root_, resolution.dimensions().width(),
                   resolution.dimensions().height(), width_mm, height_mm);
  SwitchToMode(kTempModeName);
  DeleteMode(kModeName);
  CreateMode(kModeName, resolution.dimensions().width(),
             resolution.dimensions().height());
  SwitchToMode(kModeName);
  DeleteMode(kTempModeName);
}

void DesktopResizerLinux::RestoreResolution(const ScreenResolution& original) {
  // Since the desktop is only visible via a remote connection, the original
  // resolution of the desktop will never been seen and there's no point
  // restoring it; if we did, we'd just risk messing up the user's window
  // layout.
}

void DesktopResizerLinux::CreateMode(const char* name, int width, int height) {
  XRRModeInfo mode;
  memset(&mode, 0, sizeof(mode));
  mode.width = width;
  mode.height = height;
  mode.name = const_cast<char*>(name);
  mode.nameLength = strlen(name);
  XRRCreateMode(display_, root_, &mode);

  if (!resources_.Refresh(display_, root_)) {
    return;
  }
  RRMode mode_id = resources_.GetIdForMode(name);
  if (!mode_id) {
    return;
  }
  XRRAddOutputMode(display_, resources_.GetOutput(), mode_id);
}

void DesktopResizerLinux::DeleteMode(const char* name) {
  RRMode mode_id = resources_.GetIdForMode(name);
  if (mode_id) {
    XRRDeleteOutputMode(display_, resources_.GetOutput(), mode_id);
    XRRDestroyMode(display_, mode_id);
    resources_.Refresh(display_, root_);
  }
}

void DesktopResizerLinux::SwitchToMode(const char* name) {
  RRMode mode_id = None;
  RROutput* outputs = NULL;
  int number_of_outputs = 0;
  if (name) {
    mode_id = resources_.GetIdForMode(name);
    CHECK(mode_id);
    outputs = resources_.get()->outputs;
    number_of_outputs = resources_.get()->noutput;
  }
  XRRSetCrtcConfig(display_, resources_.get(), resources_.GetCrtc(),
                   CurrentTime, 0, 0, mode_id, 1, outputs, number_of_outputs);
}

scoped_ptr<DesktopResizer> DesktopResizer::Create() {
  return scoped_ptr<DesktopResizer>(new DesktopResizerLinux);
}

}  // namespace remoting
