/*
 *  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 = std::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
