// Copyright 2014 The Chromium Embedded Framework Authors.
// Portions copyright 2014 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 "libcef/browser/native/window_x11.h"
#include "libcef/browser/thread_util.h"

#include "ui/base/x/x11_util.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/events/x/x11_event_translation.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
#include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"

#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/XInput2.h>

namespace {

const char kAtom[] = "ATOM";
const char kWMDeleteWindow[] = "WM_DELETE_WINDOW";
const char kWMProtocols[] = "WM_PROTOCOLS";
const char kNetWMName[] = "_NET_WM_NAME";
const char kNetWMPid[] = "_NET_WM_PID";
const char kNetWMPing[] = "_NET_WM_PING";
const char kNetWMState[] = "_NET_WM_STATE";
const char kXdndProxy[] = "XdndProxy";
const char kUTF8String[] = "UTF8_STRING";

::Window FindChild(::Display* display, ::Window window) {
  ::Window root;
  ::Window parent;
  ::Window* children;
  ::Window child_window = x11::None;
  unsigned int nchildren;
  if (XQueryTree(display, window, &root, &parent, &children, &nchildren) &&
      nchildren == 1) {
    child_window = children[0];
    XFree(children);
  }
  return child_window;
}

::Window FindToplevelParent(::Display* display, ::Window window) {
  ::Window top_level_window = window;
  ::Window root = x11::None;
  ::Window parent = x11::None;
  ::Window* children = nullptr;
  unsigned int nchildren = 0;
  // Enumerate all parents of "window" to find the highest level window
  // that either:
  //   - has a parent that does not contain the _NET_WM_PID property
  //   - has a parent that is the root window.
  while (XQueryTree(display, window, &root, &parent, &children, &nchildren)) {
    if (children) {
      XFree(children);
    }

    top_level_window = window;
    if (!ui::PropertyExists(parent, kNetWMPid) || parent == root) {
      break;
    }
    window = parent;
  }
  return top_level_window;
}

}  // namespace

CEF_EXPORT XDisplay* cef_get_xdisplay() {
  if (!CEF_CURRENTLY_ON(CEF_UIT))
    return nullptr;
  return gfx::GetXDisplay();
}

CefWindowX11::CefWindowX11(CefRefPtr<CefBrowserHostImpl> browser,
                           ::Window parent_xwindow,
                           const gfx::Rect& bounds,
                           const std::string& title)
    : browser_(browser),
      xdisplay_(gfx::GetXDisplay()),
      parent_xwindow_(parent_xwindow),
      xwindow_(0),
      window_mapped_(false),
      bounds_(bounds),
      focus_pending_(false),
      weak_ptr_factory_(this) {
  if (parent_xwindow_ == x11::None)
    parent_xwindow_ = DefaultRootWindow(xdisplay_);

  XSetWindowAttributes swa;
  memset(&swa, 0, sizeof(swa));
  swa.background_pixmap = x11::None;
  swa.override_redirect = false;
  xwindow_ = XCreateWindow(xdisplay_, parent_xwindow_, bounds.x(), bounds.y(),
                           bounds.width(), bounds.height(),
                           0,               // border width
                           CopyFromParent,  // depth
                           InputOutput,
                           CopyFromParent,  // visual
                           CWBackPixmap | CWOverrideRedirect, &swa);
  CHECK(xwindow_);

  DCHECK(ui::X11EventSource::HasInstance());
  ui::X11EventSource::GetInstance()->AddXEventDispatcher(this);

  long event_mask = FocusChangeMask | StructureNotifyMask | PropertyChangeMask;
  XSelectInput(xdisplay_, xwindow_, event_mask);
  XFlush(xdisplay_);

  // TODO(erg): We currently only request window deletion events. We also
  // should listen for activation events and anything else that GTK+ listens
  // for, and do something useful.
  ::Atom protocols[2];
  protocols[0] = gfx::GetAtom(kWMDeleteWindow);
  protocols[1] = gfx::GetAtom(kNetWMPing);
  XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);

  // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
  // the desktop environment.
  XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL);

  // Likewise, the X server needs to know this window's pid so it knows which
  // program to kill if the window hangs.
  // XChangeProperty() expects "pid" to be long.
  static_assert(sizeof(long) >= sizeof(pid_t),
                "pid_t should not be larger than long");
  long pid = getpid();
  XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom(kNetWMPid), XA_CARDINAL, 32,
                  PropModeReplace, reinterpret_cast<unsigned char*>(&pid), 1);

  // Set the initial window name, if provided.
  if (!title.empty()) {
    XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom(kNetWMName),
                    gfx::GetAtom(kUTF8String), 8, PropModeReplace,
                    reinterpret_cast<const unsigned char*>(title.c_str()),
                    title.size());
  }
}

CefWindowX11::~CefWindowX11() {
  DCHECK(!xwindow_);
  DCHECK(ui::X11EventSource::HasInstance());
  ui::X11EventSource::GetInstance()->RemoveXEventDispatcher(this);
}

void CefWindowX11::Close() {
  XEvent ev = {0};
  ev.xclient.type = ClientMessage;
  ev.xclient.window = xwindow_;
  ev.xclient.message_type = gfx::GetAtom(kWMProtocols);
  ev.xclient.format = 32;
  ev.xclient.data.l[0] = gfx::GetAtom(kWMDeleteWindow);
  ev.xclient.data.l[1] = x11::CurrentTime;
  XSendEvent(xdisplay_, xwindow_, false, NoEventMask, &ev);

  auto host = GetHost();
  if (host)
    host->Close();
}

void CefWindowX11::Show() {
  if (xwindow_ == x11::None)
    return;

  if (!window_mapped_) {
    // Before we map the window, set size hints. Otherwise, some window managers
    // will ignore toplevel XMoveWindow commands.
    XSizeHints size_hints;
    size_hints.flags = PPosition | PWinGravity;
    size_hints.x = bounds_.x();
    size_hints.y = bounds_.y();
    // Set StaticGravity so that the window position is not affected by the
    // frame width when running with window manager.
    size_hints.win_gravity = StaticGravity;
    XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);

    XMapWindow(xdisplay_, xwindow_);

    // TODO(thomasanderson): Find out why this flush is necessary.
    XFlush(xdisplay_);
    window_mapped_ = true;

    // Setup the drag and drop proxy on the top level window of the application
    // to be the child of this window.
    ::Window child = FindChild(xdisplay_, xwindow_);
    ::Window toplevel_window = FindToplevelParent(xdisplay_, xwindow_);
    DCHECK(toplevel_window);
    if (child && toplevel_window) {
      // Configure the drag&drop proxy property for the top-most window so
      // that all drag&drop-related messages will be sent to the child
      // DesktopWindowTreeHostX11. The proxy property is referenced by
      // DesktopDragDropClientAuraX11::FindWindowFor.
      ::Window proxy_target = gfx::kNullAcceleratedWidget;
      ui::GetXIDProperty(toplevel_window, kXdndProxy, &proxy_target);

      if (proxy_target != child) {
        // Set the proxy target for the top-most window.
        XChangeProperty(xdisplay_, toplevel_window, gfx::GetAtom(kXdndProxy),
                        XA_WINDOW, 32, PropModeReplace,
                        reinterpret_cast<unsigned char*>(&child), 1);
        // Do the same for the proxy target per the spec.
        XChangeProperty(xdisplay_, child, gfx::GetAtom(kXdndProxy), XA_WINDOW,
                        32, PropModeReplace,
                        reinterpret_cast<unsigned char*>(&child), 1);
      }
    }
  }
}

void CefWindowX11::Hide() {
  if (xwindow_ == x11::None)
    return;

  if (window_mapped_) {
    XWithdrawWindow(xdisplay_, xwindow_, 0);
    window_mapped_ = false;
  }
}

void CefWindowX11::Focus() {
  if (xwindow_ == x11::None || !window_mapped_)
    return;

  if (browser_.get()) {
    ::Window child = FindChild(xdisplay_, xwindow_);
    if (child && ui::IsWindowVisible(child)) {
      // Give focus to the child DesktopWindowTreeHostX11.
      XSetInputFocus(xdisplay_, child, RevertToParent, x11::CurrentTime);
    }
  } else {
    XSetInputFocus(xdisplay_, xwindow_, RevertToParent, x11::CurrentTime);
  }
}

void CefWindowX11::SetBounds(const gfx::Rect& bounds) {
  if (xwindow_ == x11::None)
    return;

  bool origin_changed = bounds_.origin() != bounds.origin();
  bool size_changed = bounds_.size() != bounds.size();
  XWindowChanges changes = {0};
  unsigned value_mask = 0;

  if (size_changed) {
    changes.width = bounds.width();
    changes.height = bounds.height();
    value_mask = CWHeight | CWWidth;
  }

  if (origin_changed) {
    changes.x = bounds.x();
    changes.y = bounds.y();
    value_mask |= CWX | CWY;
  }

  if (value_mask)
    XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes);
}

gfx::Rect CefWindowX11::GetBoundsInScreen() {
  int x, y;
  Window child;
  if (XTranslateCoordinates(xdisplay_, xwindow_, DefaultRootWindow(xdisplay_),
                            0, 0, &x, &y, &child)) {
    return gfx::Rect(gfx::Point(x, y), bounds_.size());
  }
  return gfx::Rect();
}

views::DesktopWindowTreeHostX11* CefWindowX11::GetHost() {
  if (browser_.get()) {
    ::Window child = FindChild(xdisplay_, xwindow_);
    if (child) {
      return static_cast<views::DesktopWindowTreeHostX11*>(
          views::DesktopWindowTreeHostLinux::GetHostForWidget(child));
    }
  }
  return nullptr;
}

bool CefWindowX11::CanDispatchEvent(const ui::PlatformEvent& event) {
  DCHECK_NE(xwindow_, x11::None);
  return !!current_xevent_;
}

uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
  DCHECK_NE(xwindow_, x11::None);
  DCHECK(event);
  DCHECK(current_xevent_);

  ProcessXEvent(current_xevent_);
  return ui::POST_DISPATCH_STOP_PROPAGATION;
}

// Called by X11EventSourceLibevent to determine whether this XEventDispatcher
// implementation is able to process the next translated event sent by it.
void CefWindowX11::CheckCanDispatchNextPlatformEvent(XEvent* xev) {
  current_xevent_ = IsTargetedBy(*xev) ? xev : nullptr;
}

void CefWindowX11::PlatformEventDispatchFinished() {
  current_xevent_ = nullptr;
}

ui::PlatformEventDispatcher* CefWindowX11::GetPlatformEventDispatcher() {
  return this;
}

bool CefWindowX11::DispatchXEvent(XEvent* xev) {
  if (!IsTargetedBy(*xev))
    return false;
  ProcessXEvent(xev);
  return true;
}

void CefWindowX11::ContinueFocus() {
  if (!focus_pending_)
    return;
  if (browser_.get())
    browser_->SetFocus(true);
  focus_pending_ = false;
}

bool CefWindowX11::TopLevelAlwaysOnTop() const {
  ::Window toplevel_window = FindToplevelParent(xdisplay_, xwindow_);

  Atom state_atom = gfx::GetAtom("_NET_WM_STATE");
  Atom state_keep_above = gfx::GetAtom("_NET_WM_STATE_KEEP_ABOVE");
  Atom* states;

  Atom actual_type;
  int actual_format;
  unsigned long num_items;
  unsigned long bytes_after;

  XGetWindowProperty(xdisplay_, toplevel_window, state_atom, 0, 1024,
                     x11::False, XA_ATOM, &actual_type, &actual_format,
                     &num_items, &bytes_after,
                     reinterpret_cast<unsigned char**>(&states));

  bool always_on_top = false;

  for (unsigned long i = 0; i < num_items; ++i) {
    if (states[i] == state_keep_above) {
      always_on_top = true;
      break;
    }
  }

  XFree(states);

  return always_on_top;
}

bool CefWindowX11::IsTargetedBy(const XEvent& xev) const {
  ::Window target_window =
      (xev.type == GenericEvent)
          ? static_cast<XIDeviceEvent*>(xev.xcookie.data)->event
          : xev.xany.window;
  return target_window == xwindow_;
}

void CefWindowX11::ProcessXEvent(XEvent* xev) {
  switch (xev->type) {
    case ConfigureNotify: {
      DCHECK_EQ(xwindow_, xev->xconfigure.event);
      DCHECK_EQ(xwindow_, xev->xconfigure.window);
      // It's possible that the X window may be resized by some other means
      // than from within Aura (e.g. the X window manager can change the
      // size). Make sure the root window size is maintained properly.
      gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
                       xev->xconfigure.width, xev->xconfigure.height);
      bounds_ = bounds;

      if (browser_.get()) {
        ::Window child = FindChild(xdisplay_, xwindow_);
        if (child) {
          // Resize the child DesktopWindowTreeHostX11 to match this window.
          XWindowChanges changes = {0};
          changes.width = bounds.width();
          changes.height = bounds.height();
          XConfigureWindow(xdisplay_, child, CWHeight | CWWidth, &changes);

          browser_->NotifyMoveOrResizeStarted();
        }
      }
      break;
    }
    case ClientMessage: {
      Atom message_type = xev->xclient.message_type;
      if (message_type == gfx::GetAtom(kWMProtocols)) {
        Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]);
        if (protocol == gfx::GetAtom(kWMDeleteWindow)) {
          // We have received a close message from the window manager.
          if (!browser_ || browser_->TryCloseBrowser()) {
            // Allow the close.
            XDestroyWindow(xdisplay_, xwindow_);

            xwindow_ = x11::None;

            if (browser_.get()) {
              // Force the browser to be destroyed and release the reference
              // added in PlatformCreateWindow().
              browser_->WindowDestroyed();
            }

            delete this;
          }
        } else if (protocol == gfx::GetAtom(kNetWMPing)) {
          XEvent reply_event = *xev;
          reply_event.xclient.window = parent_xwindow_;

          XSendEvent(xdisplay_, reply_event.xclient.window, false,
                     SubstructureRedirectMask | SubstructureNotifyMask,
                     &reply_event);
          XFlush(xdisplay_);
        }
      }
      break;
    }
    case x11::FocusIn:
      // This message is received first followed by a "_NET_ACTIVE_WINDOW"
      // message sent to the root window. When X11DesktopHandler handles the
      // "_NET_ACTIVE_WINDOW" message it will erroneously mark the WebView
      // (hosted in a DesktopWindowTreeHostX11) as unfocused. Use a delayed
      // task here to restore the WebView's focus state.
      if (!focus_pending_) {
        focus_pending_ = true;
        CEF_POST_DELAYED_TASK(CEF_UIT,
                              base::Bind(&CefWindowX11::ContinueFocus,
                                         weak_ptr_factory_.GetWeakPtr()),
                              100);
      }
      break;
    case x11::FocusOut:
      // Cancel the pending focus change if some other window has gained focus
      // while waiting for the async task to run. Otherwise we can get stuck in
      // a focus change loop.
      if (focus_pending_)
        focus_pending_ = false;
      break;
    case PropertyNotify: {
      ::Atom changed_atom = xev->xproperty.atom;
      if (changed_atom == gfx::GetAtom(kNetWMState)) {
        // State change event like minimize/maximize.
        if (browser_.get()) {
          ::Window child = FindChild(xdisplay_, xwindow_);
          if (child) {
            // Forward the state change to the child DesktopWindowTreeHostX11
            // window so that resource usage will be reduced while the window is
            // minimized.
            std::vector<::Atom> atom_list;
            if (ui::GetAtomArrayProperty(xwindow_, kNetWMState, &atom_list) &&
                !atom_list.empty()) {
              ui::SetAtomArrayProperty(child, kNetWMState, "ATOM", atom_list);
            } else {
              // Set an empty list of property values to pass the check in
              // DesktopWindowTreeHostX11::OnWMStateUpdated().
              XChangeProperty(xdisplay_, child,
                              gfx::GetAtom(kNetWMState),  // name
                              gfx::GetAtom(kAtom),        // type
                              32,  // size in bits of items in 'value'
                              PropModeReplace, NULL,
                              0);  // num items
            }
          }
        }
      }
      break;
    }
  }
}
