// Copyright 2015 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 "ui/base/x/x11_pointer_grab.h"

#include "base/bind.h"
#include "base/cancelable_callback.h"
#include "base/check.h"
#include "base/no_destructor.h"
#include "base/sys_byteorder.h"
#include "ui/base/x/x11_util.h"
#include "ui/events/devices/x11/device_data_manager_x11.h"
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/xinput.h"
#include "ui/gfx/x/xproto.h"

namespace ui {

namespace {

// The grab window. None if there are no active pointer grabs.
x11::Window g_grab_window = x11::Window::None;

// The "owner events" parameter used to grab the pointer.
bool g_owner_events = false;

base::CancelableOnceCallback<void(x11::Cursor)>& GetGrabCallback() {
  static base::NoDestructor<base::CancelableOnceCallback<void(x11::Cursor)>>
      callback;
  return *callback;
}

x11::GrabStatus GrabPointerImpl(x11::Window window,
                                bool owner_events,
                                x11::Cursor cursor) {
  GetGrabCallback().Cancel();
  auto result = x11::GrabStatus::InvalidTime;
  auto* connection = x11::Connection::Get();
  if (ui::IsXInput2Available()) {
    // Do an xinput pointer grab. If there is an active xinput pointer grab
    // as a result of normal button press, GrabPointer() will fail.
    auto mask = x11::Input::XIEventMask::ButtonPress |
                x11::Input::XIEventMask::ButtonRelease |
                x11::Input::XIEventMask::Motion |
                x11::Input::XIEventMask::TouchBegin |
                x11::Input::XIEventMask::TouchUpdate |
                x11::Input::XIEventMask::TouchEnd;
    static_assert(sizeof(mask) == 4, "");

    for (auto master_pointer :
         ui::DeviceDataManagerX11::GetInstance()->master_pointers()) {
      x11::Input::XIGrabDeviceRequest req{
          .window = window,
          .time = x11::Time::CurrentTime,
          .cursor = cursor,
          .deviceid = master_pointer,
          .mode = x11::GrabMode::Async,
          .paired_device_mode = x11::GrabMode::Async,
          .owner_events = owner_events ? x11::Input::GrabOwner::Owner
                                       : x11::Input::GrabOwner::NoOwner,
          .mask = {base::ByteSwapToLE32(static_cast<uint32_t>(mask))},
      };
      if (auto reply = connection->xinput().XIGrabDevice(req).Sync())
        result = reply->status;

      // Assume that the grab will succeed on either all or none of the master
      // pointers.
      if (result != x11::GrabStatus::Success) {
        // Try core pointer grab.
        break;
      }
    }
  }

  if (result != x11::GrabStatus::Success) {
    auto mask = x11::EventMask::PointerMotion | x11::EventMask::ButtonRelease |
                x11::EventMask::ButtonPress;
    x11::GrabPointerRequest req{
        .owner_events = owner_events,
        .grab_window = window,
        .event_mask = mask,
        .pointer_mode = x11::GrabMode::Async,
        .keyboard_mode = x11::GrabMode::Async,
        .confine_to = x11::Window::None,
        .cursor = cursor,
        .time = x11::Time::CurrentTime,
    };
    if (auto reply = connection->GrabPointer(req).Sync())
      result = reply->status;
  }

  if (result == x11::GrabStatus::Success) {
    g_grab_window = window;
    g_owner_events = owner_events;
  }
  return result;
}

}  // namespace

x11::GrabStatus GrabPointer(x11::Window window,
                            bool owner_events,
                            scoped_refptr<ui::X11Cursor> cursor) {
  if (!cursor)
    return GrabPointerImpl(window, owner_events, x11::Cursor::None);
  if (cursor->loaded())
    return GrabPointerImpl(window, owner_events, cursor->xcursor());

  auto result = GrabPointerImpl(window, owner_events, x11::Cursor::None);
  GetGrabCallback().Reset(base::BindOnce(base::IgnoreResult(GrabPointerImpl),
                                         window, owner_events));
  cursor->OnCursorLoaded(GetGrabCallback().callback());
  return result;
}

void ChangeActivePointerGrabCursor(scoped_refptr<ui::X11Cursor> cursor) {
  DCHECK(g_grab_window != x11::Window::None);
  GrabPointer(g_grab_window, g_owner_events, cursor);
}

void UngrabPointer() {
  GetGrabCallback().Cancel();
  g_grab_window = x11::Window::None;
  auto* connection = x11::Connection::Get();
  if (ui::IsXInput2Available()) {
    for (auto master_pointer :
         ui::DeviceDataManagerX11::GetInstance()->master_pointers()) {
      connection->xinput()
          .XIUngrabDevice({x11::Time::CurrentTime, master_pointer})
          .IgnoreError();
    }
  }
  // Try core pointer ungrab in case the XInput2 pointer ungrab failed.
  connection->UngrabPointer().IgnoreError();
}

}  // namespace ui
