/*
 *  Copyright 2010 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/base/x11windowpicker.h"

#include <math.h>
#include <string.h>

#include <algorithm>
#include <string>

#include <X11/Xatom.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xrender.h>
#include <X11/Xutil.h>

#include "webrtc/base/logging.h"

namespace rtc {

// Convenience wrapper for XGetWindowProperty results.
template <class PropertyType>
class XWindowProperty {
 public:
  XWindowProperty(Display* display, Window window, Atom property)
      : data_(NULL) {
    const int kBitsPerByte = 8;
    Atom actual_type;
    int actual_format;
    unsigned long bytes_after;  // NOLINT: type required by XGetWindowProperty
    int status = XGetWindowProperty(display, window, property, 0L, ~0L, False,
                                    AnyPropertyType, &actual_type,
                                    &actual_format, &size_,
                                    &bytes_after, &data_);
    succeeded_ = (status == Success);
    if (!succeeded_) {
      data_ = NULL;  // Ensure nothing is freed.
    } else if (sizeof(PropertyType) * kBitsPerByte != actual_format) {
      LOG(LS_WARNING) << "Returned type size differs from "
          "requested type size.";
      succeeded_ = false;
      // We still need to call XFree in this case, so leave data_ alone.
    }
    if (!succeeded_) {
      size_ = 0;
    }
  }

  ~XWindowProperty() {
    if (data_) {
      XFree(data_);
    }
  }

  bool succeeded() const { return succeeded_; }
  size_t size() const { return size_; }
  const PropertyType* data() const {
    return reinterpret_cast<PropertyType*>(data_);
  }
  PropertyType* data() {
    return reinterpret_cast<PropertyType*>(data_);
  }

 private:
  bool succeeded_;
  unsigned long size_;  // NOLINT: type required by XGetWindowProperty
  unsigned char* data_;

  DISALLOW_COPY_AND_ASSIGN(XWindowProperty);
};

// Stupid X11.  It seems none of the synchronous returns codes from X11 calls
// are meaningful unless an asynchronous error handler is configured.  This
// RAII class registers and unregisters an X11 error handler.
class XErrorSuppressor {
 public:
  explicit XErrorSuppressor(Display* display)
      : display_(display), original_error_handler_(NULL) {
    SuppressX11Errors();
  }
  ~XErrorSuppressor() {
    UnsuppressX11Errors();
  }

 private:
  static int ErrorHandler(Display* display, XErrorEvent* e) {
    char buf[256];
    XGetErrorText(display, e->error_code, buf, sizeof buf);
    LOG(LS_WARNING) << "Received X11 error \"" << buf << "\" for request code "
                    << static_cast<unsigned int>(e->request_code);
    return 0;
  }

  void SuppressX11Errors() {
    XFlush(display_);
    XSync(display_, False);
    original_error_handler_ = XSetErrorHandler(&ErrorHandler);
  }

  void UnsuppressX11Errors() {
    XFlush(display_);
    XSync(display_, False);
    XErrorHandler handler = XSetErrorHandler(original_error_handler_);
    if (handler != &ErrorHandler) {
      LOG(LS_WARNING) << "Unbalanced XSetErrorHandler() calls detected. "
                      << "Final error handler may not be what you expect!";
    }
    original_error_handler_ = NULL;
  }

  Display* display_;
  XErrorHandler original_error_handler_;

  DISALLOW_COPY_AND_ASSIGN(XErrorSuppressor);
};

// Hiding all X11 specifics inside its own class. This to avoid
// conflicts between talk and X11 header declarations.
class XWindowEnumerator {
 public:
  XWindowEnumerator()
      : display_(NULL),
        has_composite_extension_(false),
        has_render_extension_(false) {
  }

  ~XWindowEnumerator() {
    if (display_ != NULL) {
      XCloseDisplay(display_);
    }
  }

  bool Init() {
    if (display_ != NULL) {
      // Already initialized.
      return true;
    }
    display_ = XOpenDisplay(NULL);
    if (display_ == NULL) {
      LOG(LS_ERROR) << "Failed to open display.";
      return false;
    }

    XErrorSuppressor error_suppressor(display_);

    wm_state_ = XInternAtom(display_, "WM_STATE", True);
    net_wm_icon_ = XInternAtom(display_, "_NET_WM_ICON", False);

    int event_base, error_base, major_version, minor_version;
    if (XCompositeQueryExtension(display_, &event_base, &error_base) &&
        XCompositeQueryVersion(display_, &major_version, &minor_version) &&
        // XCompositeNameWindowPixmap() requires version 0.2
        (major_version > 0 || minor_version >= 2)) {
      has_composite_extension_ = true;
    } else {
      LOG(LS_INFO) << "Xcomposite extension not available or too old.";
    }

    if (XRenderQueryExtension(display_, &event_base, &error_base) &&
        XRenderQueryVersion(display_, &major_version, &minor_version) &&
        // XRenderSetPictureTransform() requires version 0.6
        (major_version > 0 || minor_version >= 6)) {
      has_render_extension_ = true;
    } else {
      LOG(LS_INFO) << "Xrender extension not available or too old.";
    }
    return true;
  }

  bool EnumerateWindows(WindowDescriptionList* descriptions) {
    if (!Init()) {
      return false;
    }
    XErrorSuppressor error_suppressor(display_);
    int num_screens = XScreenCount(display_);
    bool result = false;
    for (int i = 0; i < num_screens; ++i) {
      if (EnumerateScreenWindows(descriptions, i)) {
        // We know we succeded on at least one screen.
        result = true;
      }
    }
    return result;
  }

  bool EnumerateDesktops(DesktopDescriptionList* descriptions) {
    if (!Init()) {
      return false;
    }
    XErrorSuppressor error_suppressor(display_);
    Window default_root_window = XDefaultRootWindow(display_);
    int num_screens = XScreenCount(display_);
    for (int i = 0; i < num_screens; ++i) {
      Window root_window = XRootWindow(display_, i);
      DesktopId id(DesktopId(root_window, i));
      // TODO: Figure out an appropriate desktop title.
      DesktopDescription desc(id, "");
      desc.set_primary(root_window == default_root_window);
      descriptions->push_back(desc);
    }
    return num_screens > 0;
  }

  bool IsVisible(const WindowId& id) {
    if (!Init()) {
      return false;
    }
    XErrorSuppressor error_suppressor(display_);
    XWindowAttributes attr;
    if (!XGetWindowAttributes(display_, id.id(), &attr)) {
      LOG(LS_ERROR) << "XGetWindowAttributes() failed";
      return false;
    }
    return attr.map_state == IsViewable;
  }

  bool MoveToFront(const WindowId& id) {
    if (!Init()) {
      return false;
    }
    XErrorSuppressor error_suppressor(display_);
    unsigned int num_children;
    Window* children;
    Window parent;
    Window root;

    // Find root window to pass event to.
    int status = XQueryTree(display_, id.id(), &root, &parent, &children,
                            &num_children);
    if (status == 0) {
      LOG(LS_WARNING) << "Failed to query for child windows.";
      return false;
    }
    if (children != NULL) {
      XFree(children);
    }

    // Move the window to front.
    XRaiseWindow(display_, id.id());

    // Some window managers (e.g., metacity in GNOME) consider it illegal to
    // raise a window without also giving it input focus with
    // _NET_ACTIVE_WINDOW, so XRaiseWindow() on its own isn't enough.
    Atom atom = XInternAtom(display_, "_NET_ACTIVE_WINDOW", True);
    if (atom != None) {
      XEvent xev;
      long event_mask;

      xev.xclient.type = ClientMessage;
      xev.xclient.serial = 0;
      xev.xclient.send_event = True;
      xev.xclient.window = id.id();
      xev.xclient.message_type = atom;

      // The format member is set to 8, 16, or 32 and specifies whether the
      // data should be viewed as a list of bytes, shorts, or longs.
      xev.xclient.format = 32;

      xev.xclient.data.l[0] = 0;
      xev.xclient.data.l[1] = 0;
      xev.xclient.data.l[2] = 0;
      xev.xclient.data.l[3] = 0;
      xev.xclient.data.l[4] = 0;

      event_mask = SubstructureRedirectMask | SubstructureNotifyMask;

      XSendEvent(display_, root, False, event_mask, &xev);
    }
    XFlush(display_);
    return true;
  }

  uint8* GetWindowIcon(const WindowId& id, int* width, int* height) {
    if (!Init()) {
      return NULL;
    }
    XErrorSuppressor error_suppressor(display_);
    Atom ret_type;
    int format;
    unsigned long length, bytes_after, size;
    unsigned char* data = NULL;

    // Find out the size of the icon data.
    if (XGetWindowProperty(
            display_, id.id(), net_wm_icon_, 0, 0, False, XA_CARDINAL,
            &ret_type, &format, &length, &size, &data) == Success &&
        data) {
      XFree(data);
    } else {
      LOG(LS_ERROR) << "Failed to get size of the icon.";
      return NULL;
    }
    // Get the icon data, the format is one uint32 each for width and height,
    // followed by the actual pixel data.
    if (size >= 2 &&
        XGetWindowProperty(
            display_, id.id(), net_wm_icon_, 0, size, False, XA_CARDINAL,
            &ret_type, &format, &length, &bytes_after, &data) == Success &&
        data) {
      uint32* data_ptr = reinterpret_cast<uint32*>(data);
      int w, h;
      w = data_ptr[0];
      h = data_ptr[1];
      if (size < static_cast<unsigned long>(w * h + 2)) {
        XFree(data);
        LOG(LS_ERROR) << "Not a vaild icon.";
        return NULL;
      }
      uint8* rgba =
          ArgbToRgba(&data_ptr[2], 0, 0, w, h, w, h, true);
      XFree(data);
      *width = w;
      *height = h;
      return rgba;
    } else {
      LOG(LS_ERROR) << "Failed to get window icon data.";
      return NULL;
    }
  }

  uint8* GetWindowThumbnail(const WindowId& id, int width, int height) {
    if (!Init()) {
      return NULL;
    }

    if (!has_composite_extension_) {
      // Without the Xcomposite extension we would only get a good thumbnail if
      // the whole window is visible on screen and not covered by any
      // other window. This is not something we want so instead, just
      // bail out.
      LOG(LS_INFO) << "No Xcomposite extension detected.";
      return NULL;
    }
    XErrorSuppressor error_suppressor(display_);

    Window root;
    int x;
    int y;
    unsigned int src_width;
    unsigned int src_height;
    unsigned int border_width;
    unsigned int depth;

    // In addition to needing X11 server-side support for Xcomposite, it
    // actually needs to be turned on for this window in order to get a good
    // thumbnail. If the user has modern hardware/drivers but isn't using a
    // compositing window manager, that won't be the case. Here we
    // automatically turn it on for shareable windows so that we can get
    // thumbnails. We used to avoid it because the transition is visually ugly,
    // but recent window managers don't always redirect windows which led to
    // no thumbnails at all, which is a worse experience.

    // Redirect drawing to an offscreen buffer (ie, turn on compositing).
    // X11 remembers what has requested this and will turn it off for us when
    // we exit.
    XCompositeRedirectWindow(display_, id.id(), CompositeRedirectAutomatic);
    Pixmap src_pixmap = XCompositeNameWindowPixmap(display_, id.id());
    if (!src_pixmap) {
      // Even if the backing pixmap doesn't exist, this still should have
      // succeeded and returned a valid handle (it just wouldn't be a handle to
      // anything). So this is a real error path.
      LOG(LS_ERROR) << "XCompositeNameWindowPixmap() failed";
      return NULL;
    }
    if (!XGetGeometry(display_, src_pixmap, &root, &x, &y,
                      &src_width, &src_height, &border_width,
                      &depth)) {
      // If the window does not actually have a backing pixmap, this is the path
      // that will "fail", so it's a warning rather than an error.
      LOG(LS_WARNING) << "XGetGeometry() failed (probably composite is not in "
                      << "use)";
      XFreePixmap(display_, src_pixmap);
      return NULL;
    }

    // If we get to here, then composite is in use for this window and it has a
    // valid backing pixmap.

    XWindowAttributes attr;
    if (!XGetWindowAttributes(display_, id.id(), &attr)) {
      LOG(LS_ERROR) << "XGetWindowAttributes() failed";
      XFreePixmap(display_, src_pixmap);
      return NULL;
    }

    uint8* data = GetDrawableThumbnail(src_pixmap,
                                       attr.visual,
                                       src_width,
                                       src_height,
                                       width,
                                       height);
    XFreePixmap(display_, src_pixmap);
    return data;
  }

  int GetNumDesktops() {
    if (!Init()) {
      return -1;
    }

    return XScreenCount(display_);
  }

  uint8* GetDesktopThumbnail(const DesktopId& id, int width, int height) {
    if (!Init()) {
      return NULL;
    }
    XErrorSuppressor error_suppressor(display_);

    Window root_window = id.id();
    XWindowAttributes attr;
    if (!XGetWindowAttributes(display_, root_window, &attr)) {
      LOG(LS_ERROR) << "XGetWindowAttributes() failed";
      return NULL;
    }

    return GetDrawableThumbnail(root_window,
                                attr.visual,
                                attr.width,
                                attr.height,
                                width,
                                height);
  }

  bool GetDesktopDimensions(const DesktopId& id, int* width, int* height) {
    if (!Init()) {
      return false;
    }
    XErrorSuppressor error_suppressor(display_);
    XWindowAttributes attr;
    if (!XGetWindowAttributes(display_, id.id(), &attr)) {
      LOG(LS_ERROR) << "XGetWindowAttributes() failed";
      return false;
    }
    *width = attr.width;
    *height = attr.height;
    return true;
  }

 private:
  uint8* GetDrawableThumbnail(Drawable src_drawable,
                              Visual* visual,
                              int src_width,
                              int src_height,
                              int dst_width,
                              int dst_height) {
    if (!has_render_extension_) {
      // Without the Xrender extension we would have to read the full window and
      // scale it down in our process. Xrender is over a decade old so we aren't
      // going to expend effort to support that situation. We still need to
      // check though because probably some virtual VNC displays are in this
      // category.
      LOG(LS_INFO) << "No Xrender extension detected.";
      return NULL;
    }

    XRenderPictFormat* format = XRenderFindVisualFormat(display_,
                                                        visual);
    if (!format) {
      LOG(LS_ERROR) << "XRenderFindVisualFormat() failed";
      return NULL;
    }

    // Create a picture to reference the window pixmap.
    XRenderPictureAttributes pa;
    pa.subwindow_mode = IncludeInferiors;  // Don't clip child widgets
    Picture src = XRenderCreatePicture(display_,
                                       src_drawable,
                                       format,
                                       CPSubwindowMode,
                                       &pa);
    if (!src) {
      LOG(LS_ERROR) << "XRenderCreatePicture() failed";
      return NULL;
    }

    // Create a picture to reference the destination pixmap.
    Pixmap dst_pixmap = XCreatePixmap(display_,
                                      src_drawable,
                                      dst_width,
                                      dst_height,
                                      format->depth);
    if (!dst_pixmap) {
      LOG(LS_ERROR) << "XCreatePixmap() failed";
      XRenderFreePicture(display_, src);
      return NULL;
    }

    Picture dst = XRenderCreatePicture(display_, dst_pixmap, format, 0, NULL);
    if (!dst) {
      LOG(LS_ERROR) << "XRenderCreatePicture() failed";
      XFreePixmap(display_, dst_pixmap);
      XRenderFreePicture(display_, src);
      return NULL;
    }

    // Clear the background.
    XRenderColor transparent = {0};
    XRenderFillRectangle(display_,
                         PictOpSrc,
                         dst,
                         &transparent,
                         0,
                         0,
                         dst_width,
                         dst_height);

    // Calculate how much we need to scale the image.
    double scale_x = static_cast<double>(dst_width) /
        static_cast<double>(src_width);
    double scale_y = static_cast<double>(dst_height) /
        static_cast<double>(src_height);
    double scale = rtc::_min(scale_y, scale_x);

    int scaled_width = round(src_width * scale);
    int scaled_height = round(src_height * scale);

    // Render the thumbnail centered on both axis.
    int centered_x = (dst_width - scaled_width) / 2;
    int centered_y = (dst_height - scaled_height) / 2;

    // Scaling matrix
    XTransform xform = { {
        { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) },
        { XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0) },
        { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(scale) }
        } };
    XRenderSetPictureTransform(display_, src, &xform);

    // Apply filter to smooth out the image.
    XRenderSetPictureFilter(display_, src, FilterBest, NULL, 0);

    // Render the image to the destination picture.
    XRenderComposite(display_,
                     PictOpSrc,
                     src,
                     None,
                     dst,
                     0,
                     0,
                     0,
                     0,
                     centered_x,
                     centered_y,
                     scaled_width,
                     scaled_height);

    // Get the pixel data from the X server. TODO: XGetImage
    // might be slow here, compare with ShmGetImage.
    XImage* image = XGetImage(display_,
                              dst_pixmap,
                              0,
                              0,
                              dst_width,
                              dst_height,
                              AllPlanes, ZPixmap);
    uint8* data = ArgbToRgba(reinterpret_cast<uint32*>(image->data),
                             centered_x,
                             centered_y,
                             scaled_width,
                             scaled_height,
                             dst_width,
                             dst_height,
                             false);
    XDestroyImage(image);
    XRenderFreePicture(display_, dst);
    XFreePixmap(display_, dst_pixmap);
    XRenderFreePicture(display_, src);
    return data;
  }

  uint8* ArgbToRgba(uint32* argb_data, int x, int y, int w, int h,
                    int stride_x, int stride_y, bool has_alpha) {
    uint8* p;
    int len = stride_x * stride_y * 4;
    uint8* data = new uint8[len];
    memset(data, 0, len);
    p = data + 4 * (y * stride_x + x);
    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        uint32 argb;
        uint32 rgba;
        argb = argb_data[stride_x * (y + i) + x + j];
        rgba = (argb << 8) | (argb >> 24);
        *p = rgba >> 24;
        ++p;
        *p = (rgba >> 16) & 0xff;
        ++p;
        *p = (rgba >> 8) & 0xff;
        ++p;
        *p = has_alpha ? rgba & 0xFF : 0xFF;
        ++p;
      }
      p += (stride_x - w) * 4;
    }
    return data;
  }

  bool EnumerateScreenWindows(WindowDescriptionList* descriptions, int screen) {
    Window parent;
    Window *children;
    int status;
    unsigned int num_children;
    Window root_window = XRootWindow(display_, screen);
    status = XQueryTree(display_, root_window, &root_window, &parent, &children,
                        &num_children);
    if (status == 0) {
      LOG(LS_ERROR) << "Failed to query for child windows.";
      return false;
    }
    for (unsigned int i = 0; i < num_children; ++i) {
      // Iterate in reverse order to display windows from front to back.
#ifdef CHROMEOS
      // TODO(jhorwich): Short-term fix for crbug.com/120229: Don't need to
      // filter, just return all windows and let the picker scan through them.
      Window app_window = children[num_children - 1 - i];
#else
      Window app_window = GetApplicationWindow(children[num_children - 1 - i]);
#endif
      if (app_window &&
          !X11WindowPicker::IsDesktopElement(display_, app_window)) {
        std::string title;
        if (GetWindowTitle(app_window, &title)) {
          WindowId id(app_window);
          WindowDescription desc(id, title);
          descriptions->push_back(desc);
        }
      }
    }
    if (children != NULL) {
      XFree(children);
    }
    return true;
  }

  bool GetWindowTitle(Window window, std::string* title) {
    int status;
    bool result = false;
    XTextProperty window_name;
    window_name.value = NULL;
    if (window) {
      status = XGetWMName(display_, window, &window_name);
      if (status && window_name.value && window_name.nitems) {
        int cnt;
        char **list = NULL;
        status = Xutf8TextPropertyToTextList(display_, &window_name, &list,
                                             &cnt);
        if (status >= Success && cnt && *list) {
          if (cnt > 1) {
            LOG(LS_INFO) << "Window has " << cnt
                         << " text properties, only using the first one.";
          }
          *title = *list;
          result = true;
        }
        if (list != NULL) {
          XFreeStringList(list);
        }
      }
      if (window_name.value != NULL) {
        XFree(window_name.value);
      }
    }
    return result;
  }

  Window GetApplicationWindow(Window window) {
    Window root, parent;
    Window app_window = 0;
    Window *children;
    unsigned int num_children;
    Atom type = None;
    int format;
    unsigned long nitems, after;
    unsigned char *data;

    int ret = XGetWindowProperty(display_, window,
                                 wm_state_, 0L, 2,
                                 False, wm_state_, &type, &format,
                                 &nitems, &after, &data);
    if (ret != Success) {
      LOG(LS_ERROR) << "XGetWindowProperty failed with return code " << ret
                    << " for window " << window << ".";
      return 0;
    }
    if (type != None) {
      int64 state = static_cast<int64>(*data);
      XFree(data);
      return state == NormalState ? window : 0;
    }
    XFree(data);
    if (!XQueryTree(display_, window, &root, &parent, &children,
                    &num_children)) {
      LOG(LS_ERROR) << "Failed to query for child windows although window"
                    << "does not have a valid WM_STATE.";
      return 0;
    }
    for (unsigned int i = 0; i < num_children; ++i) {
      app_window = GetApplicationWindow(children[i]);
      if (app_window) {
        break;
      }
    }
    if (children != NULL) {
      XFree(children);
    }
    return app_window;
  }

  Atom wm_state_;
  Atom net_wm_icon_;
  Display* display_;
  bool has_composite_extension_;
  bool has_render_extension_;
};

X11WindowPicker::X11WindowPicker() : enumerator_(new XWindowEnumerator()) {
}

X11WindowPicker::~X11WindowPicker() {
}

bool X11WindowPicker::IsDesktopElement(_XDisplay* display, Window window) {
  if (window == 0) {
    LOG(LS_WARNING) << "Zero is never a valid window.";
    return false;
  }

  // First look for _NET_WM_WINDOW_TYPE. The standard
  // (http://standards.freedesktop.org/wm-spec/latest/ar01s05.html#id2760306)
  // says this hint *should* be present on all windows, and we use the existence
  // of _NET_WM_WINDOW_TYPE_NORMAL in the property to indicate a window is not
  // a desktop element (that is, only "normal" windows should be shareable).
  Atom window_type_atom = XInternAtom(display, "_NET_WM_WINDOW_TYPE", True);
  XWindowProperty<uint32_t> window_type(display, window, window_type_atom);
  if (window_type.succeeded() && window_type.size() > 0) {
    Atom normal_window_type_atom = XInternAtom(
        display, "_NET_WM_WINDOW_TYPE_NORMAL", True);
    uint32_t* end = window_type.data() + window_type.size();
    bool is_normal = (end != std::find(
        window_type.data(), end, normal_window_type_atom));
    return !is_normal;
  }

  // Fall back on using the hint.
  XClassHint class_hint;
  Status s = XGetClassHint(display, window, &class_hint);
  bool result = false;
  if (s == 0) {
    // No hints, assume this is a normal application window.
    return result;
  }
  static const std::string gnome_panel("gnome-panel");
  static const std::string desktop_window("desktop_window");

  if (gnome_panel.compare(class_hint.res_name) == 0 ||
      desktop_window.compare(class_hint.res_name) == 0) {
    result = true;
  }
  XFree(class_hint.res_name);
  XFree(class_hint.res_class);
  return result;
}

bool X11WindowPicker::Init() {
  return enumerator_->Init();
}

bool X11WindowPicker::GetWindowList(WindowDescriptionList* descriptions) {
  return enumerator_->EnumerateWindows(descriptions);
}

bool X11WindowPicker::GetDesktopList(DesktopDescriptionList* descriptions) {
  return enumerator_->EnumerateDesktops(descriptions);
}

bool X11WindowPicker::IsVisible(const WindowId& id) {
  return enumerator_->IsVisible(id);
}

bool X11WindowPicker::MoveToFront(const WindowId& id) {
  return enumerator_->MoveToFront(id);
}


uint8* X11WindowPicker::GetWindowIcon(const WindowId& id, int* width,
                                        int* height) {
  return enumerator_->GetWindowIcon(id, width, height);
}

uint8* X11WindowPicker::GetWindowThumbnail(const WindowId& id, int width,
                                             int height) {
  return enumerator_->GetWindowThumbnail(id, width, height);
}

int X11WindowPicker::GetNumDesktops() {
  return enumerator_->GetNumDesktops();
}

uint8* X11WindowPicker::GetDesktopThumbnail(const DesktopId& id,
                                              int width,
                                              int height) {
  return enumerator_->GetDesktopThumbnail(id, width, height);
}

bool X11WindowPicker::GetDesktopDimensions(const DesktopId& id, int* width,
                                             int* height) {
  return enumerator_->GetDesktopDimensions(id, width, height);
}

}  // namespace rtc
