// Copyright 2020 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "screen-capture-utils/uinput.h"

#include <cstdint>
#include <utility>

#include <fcntl.h>
#include <linux/uinput.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <unistd.h>

#include <base/check.h>
#include <base/check_op.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>

namespace screenshot {
namespace {

// TODO(shaochuan): Possibly generate this list from the keymaps.
// clang-format off
constexpr const uint16_t kAllKeys[] = {
  KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9,
  KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K,
  KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V,
  KEY_W, KEY_X, KEY_Y, KEY_Z,
  KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9,
  KEY_F10, KEY_F11, KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17,
  KEY_F18,
  KEY_UP, KEY_DOT, KEY_END, KEY_ESC, KEY_TAB, KEY_DOWN, KEY_HOME, KEY_LEFT,
  KEY_CLEAR, KEY_COMMA, KEY_ENTER, KEY_EQUAL, KEY_GRAVE, KEY_MINUS, KEY_PAUSE,
  KEY_RIGHT, KEY_SLASH, KEY_SPACE, KEY_SYSRQ, KEY_PAGEUP, KEY_LEFTALT,
  KEY_CAPSLOCK, KEY_LEFTCTRL, KEY_LEFTMETA, KEY_LINEFEED, KEY_PAGEDOWN,
  KEY_RIGHTALT, KEY_BACKSLASH, KEY_BACKSPACE, KEY_LEFTBRACE, KEY_LEFTSHIFT,
  KEY_RIGHTCTRL, KEY_RIGHTMETA, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_RIGHTBRACE,
  KEY_RIGHTSHIFT, KEY_SCROLLLOCK, KEY_NUMLOCK,
  KEY_KP0, KEY_KP1, KEY_KP2, KEY_KP3, KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7,
  KEY_KP8, KEY_KP9, KEY_KPASTERISK, KEY_KPCOMMA, KEY_KPDOT, KEY_KPENTER,
  KEY_KPEQUAL, KEY_KPMINUS, KEY_KPPLUS, KEY_KPSLASH,
  0
};
// clang-format on

// Manages a file descriptor representing an uinput device.
class ScopedUinputFD final {
 public:
  ScopedUinputFD() : fd_(open("/dev/uinput", O_WRONLY | O_NONBLOCK)) {
    PCHECK(fd_.is_valid());

    // Ensure protocol version.
    unsigned int ver;
    Ioctl(UI_GET_VERSION, &ver);
    CHECK_GE(ver, 5) << "Unsupported protocol version, should be at least 5";
  }
  ScopedUinputFD(const ScopedUinputFD&) = delete;
  ScopedUinputFD& operator=(const ScopedUinputFD&) = delete;

  ~ScopedUinputFD() {
    if (created_) {
      Ioctl(UI_DEV_DESTROY);
    }
  }

  void CreateDevice() {
    Ioctl(UI_DEV_CREATE);
    created_ = true;
  }

  // Emits an input event with the current device.
  void Emit(uint16_t type, uint16_t code, int32_t value) const {
    input_event ev{
        {},  // time (struct timeval), filled in later
        type,
        code,
        value,
    };
    gettimeofday(&ev.time, nullptr);
    if (write(fd_.get(), &ev, sizeof(ev)) < 0) {
      PLOG(ERROR) << "Failed emitting input event";
    }
  }

  // Wrapped ioctl call to not expose |fd_|.
  template <typename... Args>
  void Ioctl(unsigned long req, Args... args) const {  // NOLINT(runtime/int)
    PCHECK(ioctl(fd_.get(), req, args...) == 0);
  }

 private:
  const base::ScopedFD fd_;
  bool created_{false};
};

// The actual implementation returned by Uinput::Create.
class UinputImpl final : public Uinput {
 public:
  UinputImpl(rfbScreenInfoPtr server, bool rotate);
  ~UinputImpl() override;

 private:
  void SetupKeyboard();
  void SetupPointer(int32_t width, int32_t height);

  void OnKbdAddEvent(rfbBool down, rfbKeySym keySym, rfbClientPtr cl) const;
  void OnPtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl) const;

  ScopedUinputFD keyboard_;
  ScopedUinputFD pointer_;
  const bool rotate_;
  const uint32_t vnc_width_;
};

// The current live instance, or nullptr if no instances exist.
UinputImpl* g_uinput{nullptr};

UinputImpl::UinputImpl(rfbScreenInfoPtr server, bool rotate)
    : rotate_(rotate), vnc_width_(server->width) {
  CHECK(!g_uinput) << "Only one Uinput instance may exist at a time";
  g_uinput = this;

  // Setup devices.
  SetupKeyboard();
  uint32_t width = server->width;
  uint32_t height = server->height;
  if (rotate) {
    std::swap(width, height);
  }
  SetupPointer(width, height);

  // Setup callbacks.
  server->kbdAddEvent = [](rfbBool down, rfbKeySym keySym, rfbClientPtr cl) {
    CHECK(g_uinput) << "uinput not set up";
    g_uinput->OnKbdAddEvent(down, keySym, cl);
  };
  server->ptrAddEvent = [](int buttonMask, int x, int y, rfbClientPtr cl) {
    CHECK(g_uinput) << "uinput not set up";
    g_uinput->OnPtrAddEvent(buttonMask, x, y, cl);
  };
}

UinputImpl::~UinputImpl() {
  g_uinput = nullptr;
}

// Sets up a uinput keyboard device. We simulate a standard 104-key keyboard in
// US layout.
void UinputImpl::SetupKeyboard() {
  // Enable key events.
  keyboard_.Ioctl(UI_SET_EVBIT, EV_KEY);
  for (auto* pkey = kAllKeys; *pkey; pkey++) {
    keyboard_.Ioctl(UI_SET_KEYBIT, *pkey);
  }

  const uinput_setup usetup{
      {BUS_USB /*bustype*/, 0, 0, 0},  // id (struct input_id)
      "kmsvnc keyboard",               // name
  };
  keyboard_.Ioctl(UI_DEV_SETUP, &usetup);

  keyboard_.CreateDevice();
}

// Sets up a uinput pointer device. We simulate a touch device with absolutely
// positioned "tap" events. Only the left mouse button works.
void UinputImpl::SetupPointer(int32_t width, int32_t height) {
  // Enable key events.
  pointer_.Ioctl(UI_SET_EVBIT, EV_KEY);
  pointer_.Ioctl(UI_SET_KEYBIT, BTN_LEFT);

  // Enable absolute events.
  pointer_.Ioctl(UI_SET_EVBIT, EV_ABS);
  pointer_.Ioctl(UI_SET_ABSBIT, ABS_X);
  pointer_.Ioctl(UI_SET_ABSBIT, ABS_Y);

  // Set up X/Y bounds.
  uinput_abs_setup uabs{};
  uabs.code = ABS_X;
  uabs.absinfo.maximum = width - 1;
  pointer_.Ioctl(UI_ABS_SETUP, &uabs);
  uabs.code = ABS_Y;
  uabs.absinfo.maximum = height - 1;
  pointer_.Ioctl(UI_ABS_SETUP, &uabs);

  const uinput_setup usetup{
      {BUS_USB /*bustype*/, 0, 0, 0},  // id (struct input_id)
      "kmsvnc touchscreen",            // name
  };
  pointer_.Ioctl(UI_DEV_SETUP, &usetup);

  pointer_.CreateDevice();
}

void UinputImpl::OnKbdAddEvent(rfbBool down,
                               rfbKeySym keySym,
                               rfbClientPtr cl) const {
  const int scancode = KeySymToScancode(keySym);
  if (!scancode) {
    LOG(WARNING) << "Received unknown keysym 0x" << std::hex << keySym;
    return;
  }

  VLOG(1) << "keysym 0x" << std::hex << keySym
          << " down:" << (down ? "true" : "false");
  keyboard_.Emit(EV_KEY, scancode, down);
  keyboard_.Emit(EV_SYN, SYN_REPORT, 0);
}

void UinputImpl::OnPtrAddEvent(int buttonMask,
                               int x,
                               int y,
                               rfbClientPtr cl) const {
  if (rotate_) {
    x = vnc_width_ - x - 1;
    std::swap(x, y);
  }
  pointer_.Emit(EV_KEY, BTN_LEFT, buttonMask & 1);
  pointer_.Emit(EV_ABS, ABS_X, x);
  pointer_.Emit(EV_ABS, ABS_Y, y);
  pointer_.Emit(EV_SYN, SYN_REPORT, 0);

  rfbDefaultPtrAddEvent(buttonMask, x, y, cl);
}

}  // namespace

// Convert RFB keysyms (identical to X11 keysyms) to input event codes.
// ASCII chars are mapped back to their corresponding keys in US layout.
// Spec: https://tools.ietf.org/html/rfc6143#section-7.5.4
int KeySymToScancode(rfbKeySym key) {
  // We need custom formatting for the keymaps to make them readable.
  // clang-format off
  if ((0x20 <= key && key <= 0x7f) || (0xff00 <= key && key <= 0xff1f)) {
    static const uint16_t map[] = {
      /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0,
      /*0x08*/ KEY_BACKSPACE, KEY_TAB, KEY_LINEFEED, KEY_CLEAR, 0, KEY_ENTER, 0,
               0,
      /*0x10*/ 0, 0, 0, KEY_PAUSE, KEY_SCROLLLOCK, KEY_SYSRQ, 0, 0,
      /*0x18*/ 0, 0, 0, KEY_ESC, 0, 0, 0, 0,
      /*0x20*/ KEY_SPACE, KEY_1, KEY_APOSTROPHE, KEY_3, KEY_4, KEY_5, KEY_7,
               KEY_APOSTROPHE,
      /*0x28*/ KEY_9, KEY_0, KEY_8, KEY_EQUAL, KEY_COMMA, KEY_MINUS, KEY_DOT,
               KEY_SLASH,
      /*0x30*/ KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
      /*0x38*/ KEY_8, KEY_9, KEY_SEMICOLON, KEY_SEMICOLON, KEY_COMMA, KEY_EQUAL,
               KEY_DOT, KEY_SLASH,
      /*0x40*/ KEY_2, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
      /*0x48*/ KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
      /*0x50*/ KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W,
      /*0x58*/ KEY_X, KEY_Y, KEY_Z, KEY_LEFTBRACE, KEY_BACKSLASH,
               KEY_RIGHTBRACE, KEY_6, KEY_MINUS,
      /*0x60*/ KEY_GRAVE, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
      /*0x68*/ KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
      /*0x70*/ KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W,
      /*0x78*/ KEY_X, KEY_Y, KEY_Z, KEY_LEFTBRACE, KEY_BACKSLASH,
               KEY_RIGHTBRACE, KEY_GRAVE, KEY_NUMLOCK,
    };
    return map[key & 0x7f];
  }
  if (0xff50 <= key && key <= 0xff5f) {
    static const uint16_t map[] = {
      /*0x0*/ KEY_HOME, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN, KEY_PAGEUP,
              KEY_PAGEDOWN, KEY_END,
      /*0x8*/ /*XK_Begin*/0, 0, 0, 0, 0, 0, 0, 0,
    };
    return map[key & 0xf];
  }
  if (0xff80 <= key && key <= 0xffbf) {
    static const uint16_t map[] = {
      /*0x80*/ 0, 0, 0, 0, 0, 0, 0, 0,
      /*0x88*/ 0, 0, 0, 0, 0, KEY_KPENTER, 0, 0,
      /*0x90*/ 0, 0, 0, 0, 0, KEY_KP7, KEY_KP4, KEY_KP8,
      /*0x98*/ KEY_KP6, KEY_KP2, KEY_KP9, KEY_KP3, KEY_KP1, 0, KEY_KP0,
               KEY_KPDOT,
      /*0xa0*/ 0, 0, 0, 0, 0, 0, 0, 0,
      /*0xa8*/ 0, 0, KEY_KPASTERISK, KEY_KPPLUS, KEY_KPCOMMA, KEY_KPMINUS,
               KEY_KPDOT, KEY_KPSLASH,
      /*0xb0*/ KEY_KP0, KEY_KP1, KEY_KP2, KEY_KP3, KEY_KP4, KEY_KP5, KEY_KP6,
               KEY_KP7,
      /*0xb8*/ KEY_KP8, KEY_KP9, 0, 0, 0, KEY_KPEQUAL, KEY_F1, KEY_F2,
    };
    return map[key & 0x3f];
  }
  if (0xffc0 <= key && key <= 0xffcf) {
    static const uint16_t map[] = {
      /*0x0*/ KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10,
      /*0x8*/ KEY_F11, KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17,
              KEY_F18,
    };
    return map[key & 0xf];
  }
  if (0xffe0 <= key && key <= 0xffef) {
    static const uint16_t map[] = {
      /*0x0*/ /*XK_F35*/0, KEY_LEFTSHIFT, KEY_RIGHTSHIFT, KEY_LEFTCTRL,
      /*0x4*/ KEY_RIGHTCTRL, KEY_CAPSLOCK, /*XK_Shift_Lock*/0, KEY_LEFTMETA,
      /*0x8*/ KEY_RIGHTMETA, KEY_LEFTALT, KEY_RIGHTALT, /*XK_Super_L*/0,
      /*0xc*/ /*XK_Super_R*/0, /*XK_Hyper_L*/0, /*XK_Hyper_R*/0, 0,
    };
    return map[key & 0xf];
  }
  // clang-format on
  return 0;
}

// static
std::unique_ptr<Uinput> Uinput::Create(rfbScreenInfoPtr server, bool rotate) {
  return std::make_unique<UinputImpl>(server, rotate);
}

}  // namespace screenshot
