Skip to content

Commit

Permalink
refactor: better split between input library and Moonlight specific code
Browse files Browse the repository at this point in the history
  • Loading branch information
ABeltramo committed Feb 9, 2024
1 parent 4d37d82 commit 65624f4
Show file tree
Hide file tree
Showing 14 changed files with 259 additions and 187 deletions.
35 changes: 0 additions & 35 deletions cmake/FindLIBEVDEV.cmake

This file was deleted.

29 changes: 5 additions & 24 deletions src/core/src/core/input.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
#include <boost/endian/conversion.hpp>
#include <chrono>
#include <cstdint>
#include <immer/array.hpp>
#include <immer/box.hpp>
#include <map>
#include <optional>
#include <thread>
Expand Down Expand Up @@ -130,8 +128,9 @@ class Trackpad : public VirtualDevice {
*
* @param finger_nr
* @param pressure A value between 0 and 1
* @param orientation A value between -90 and 90
*/
void place_finger(int finger_nr, float x, float y, float pressure);
void place_finger(int finger_nr, float x, float y, float pressure, int orientation);

void release_finger(int finger_nr);

Expand Down Expand Up @@ -166,7 +165,7 @@ class TouchScreen : public VirtualDevice {
* @param finger_nr
* @param pressure A value between 0 and 1
*/
void place_finger(int finger_nr, float x, float y, float pressure);
void place_finger(int finger_nr, float x, float y, float pressure, int orientation);

void release_finger(int finger_nr);
};
Expand Down Expand Up @@ -255,19 +254,6 @@ class Keyboard : public VirtualDevice {
void press(short key_code);

void release(short key_code);

/**
* Here we receive a single UTF-8 encoded char at a time,
* the trick is to convert it to UTF-32 then send CTRL+SHIFT+U+<HEXCODE> in order to produce any
* unicode character, see: https://en.wikipedia.org/wiki/Unicode_input
*
* ex:
* - when receiving UTF-8 [0xF0 0x9F 0x92 0xA9] (which is '💩')
* - we'll convert it to UTF-32 [0x1F4A9]
* - then type: CTRL+SHIFT+U+1F4A9
* see the conversion at: https://www.compart.com/en/unicode/U+1F4A9
*/
void paste_utf(const std::basic_string<char32_t> &utf32);
};

/**
Expand Down Expand Up @@ -363,14 +349,9 @@ class Joypad : public VirtualDevice {
void set_on_rumble(const std::function<void(int low_freq, int high_freq)> &callback);

/**
* @see: Trackpad->place_finger
*/
void touchpad_place_finger(int finger_nr, float x, float y, float pressure);

/**
* @see: Trackpad->release_finger
* If the joypad has been created with the TOUCHPAD capability this will return the associated trackpad
*/
void touchpad_release_finger(int finger_nr);
std::optional<Trackpad> get_trackpad() const;

enum MOTION_TYPE : uint8_t {
ACCELERATION = 0x01,
Expand Down
45 changes: 11 additions & 34 deletions src/core/src/platforms/linux/uinput/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,19 @@ file(GLOB PRIVATE_LIST SRCS *.cpp)
add_library(wolf_uinput)
add_library(wolf::uinput ALIAS wolf_uinput)

find_package(LIBEVDEV)
if (NOT (LIBEVDEV_FOUND))
message(FATAL_ERROR "Please install libevdev: CMake will Exit")
endif ()

target_link_libraries(wolf_uinput PUBLIC evdev)
target_include_directories(wolf_uinput PUBLIC ${LIBEVDEV_INCLUDE_DIR})

pkg_check_modules(LIBUDEV REQUIRED libudev)
target_link_libraries(wolf_uinput PUBLIC ${LIBUDEV_LIBRARIES})
target_include_directories(wolf_uinput PUBLIC ${LIBUDEV_INCLUDE_DIR})


message(STATUS "Adding input implementation for LINUX")
target_include_directories(wolf_uinput PRIVATE ../../../)

find_package(ICU 61.0 COMPONENTS uc REQUIRED)
target_link_libraries_system(wolf_uinput PRIVATE ICU::uc)
if (UNIX AND NOT APPLE)
find_package(PkgConfig)
pkg_check_modules(LIBEVDEV REQUIRED IMPORTED_TARGET libevdev)
target_link_libraries(wolf_uinput PUBLIC PkgConfig::LIBEVDEV)

target_include_directories(wolf_uinput PRIVATE ../../../)
target_sources(wolf_uinput
PUBLIC "keyboard.hpp" "uinput.hpp"
PRIVATE ${PRIVATE_LIST})

FetchContent_Declare(
immer
GIT_REPOSITORY https://github.com/arximboldi/immer.git
GIT_TAG e02cbd795e9424a8405a8cb01f659ad61c0cbbc7)
set(immer_BUILD_TESTS OFF)
set(immer_BUILD_EXAMPLES OFF)
set(immer_BUILD_DOCS OFF)
set(immer_BUILD_EXTRAS OFF)

set(FPHSA_NAME_MISMATCHED on) # see: https://github.com/arximboldi/immer/issues/204
FetchContent_MakeAvailable(immer)
target_link_libraries_system(wolf_uinput PUBLIC immer)
unset(FPHSA_NAME_MISMATCHED)
pkg_check_modules(LIBUDEV REQUIRED IMPORTED_TARGET libudev)
target_link_libraries(wolf_uinput PUBLIC PkgConfig::LIBUDEV)
target_sources(wolf_uinput
PUBLIC "keyboard.hpp" "uinput.hpp"
PRIVATE ${PRIVATE_LIST})
endif ()

# We need this directory, and users of our library will need it too
target_include_directories(wolf_uinput PUBLIC .)
Expand Down
12 changes: 2 additions & 10 deletions src/core/src/platforms/linux/uinput/joypad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -768,16 +768,8 @@ void Joypad::set_on_led(const std::function<void(int r, int g, int b)> &callback
this->_state->on_led = callback;
}

void Joypad::touchpad_place_finger(int finger_nr, float x, float y, float pressure) {
if (auto touchpad = this->_state->trackpad) {
touchpad->place_finger(finger_nr, x, y, pressure);
}
}

void Joypad::touchpad_release_finger(int finger_nr) {
if (auto touchpad = this->_state->trackpad) {
touchpad->release_finger(finger_nr);
}
std::optional<Trackpad> Joypad::get_trackpad() const {
return this->_state->trackpad;
}

} // namespace wolf::core::input
29 changes: 0 additions & 29 deletions src/core/src/platforms/linux/uinput/keyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,34 +148,5 @@ void Keyboard::release(short key_code) {
}
}

static void keyboard_ev(libevdev_uinput *keyboard, int linux_code, int event_code = 1) {
libevdev_uinput_write_event(keyboard, EV_KEY, linux_code, event_code);
libevdev_uinput_write_event(keyboard, EV_SYN, SYN_REPORT, 0);
}

void Keyboard::paste_utf(const std::basic_string<char32_t> &utf32) {
/* To HEX string */
auto hex_unicode = to_hex(utf32);
logs::log(logs::debug, "[INPUT] Typing U+{}", hex_unicode);

keyboard_ev(this->_state->kb.get(), KEY_LEFTCTRL, 1);
keyboard_ev(this->_state->kb.get(), KEY_LEFTSHIFT, 1);
keyboard_ev(this->_state->kb.get(), KEY_U, 1);
keyboard_ev(this->_state->kb.get(), KEY_U, 0);

for (auto &ch : hex_unicode) {
auto key_str = "KEY_"s + ch;
auto keycode = libevdev_event_code_from_name(EV_KEY, key_str.c_str());
if (keycode == -1) {
logs::log(logs::warning, "[INPUT] Unable to find keycode for: {}", ch);
} else {
keyboard_ev(this->_state->kb.get(), keycode, 1);
keyboard_ev(this->_state->kb.get(), keycode, 0);
}
}

keyboard_ev(this->_state->kb.get(), KEY_LEFTSHIFT, 0);
keyboard_ev(this->_state->kb.get(), KEY_LEFTCTRL, 0);
}

} // namespace wolf::core::input
8 changes: 5 additions & 3 deletions src/core/src/platforms/linux/uinput/touchscreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,11 @@ TouchScreen::TouchScreen() {
}
}
TouchScreen::~TouchScreen() {}
void TouchScreen::place_finger(int finger_nr, float x, float y, float pressure) {
void TouchScreen::place_finger(int finger_nr, float x, float y, float pressure, int orientation) {
if (auto ts = this->_state->touch_screen.get()) {
int scaled_x = (int)std::lround(TOUCH_MAX_X * x);
int scaled_y = (int)std::lround(TOUCH_MAX_Y * y);
int scaled_orientation = std::clamp(orientation, -90, 90);

if (_state->fingers.find(finger_nr) == _state->fingers.end()) {
// Wow, a wild finger appeared!
Expand All @@ -156,8 +157,9 @@ void TouchScreen::place_finger(int finger_nr, float x, float y, float pressure)
libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_POSITION_X, scaled_x);
libevdev_uinput_write_event(ts, EV_ABS, ABS_Y, scaled_y);
libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_POSITION_Y, scaled_y);
libevdev_uinput_write_event(ts, EV_ABS, ABS_PRESSURE, (int)std::lround(pressure * PRESSURE_MAX));
libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_PRESSURE, (int)std::lround(pressure * PRESSURE_MAX));
libevdev_uinput_write_event(ts, EV_ABS, ABS_PRESSURE, (int) std::lround(pressure * PRESSURE_MAX));
libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_PRESSURE, (int) std::lround(pressure * PRESSURE_MAX));
libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_ORIENTATION, scaled_orientation);

libevdev_uinput_write_event(ts, EV_SYN, SYN_REPORT, 0);
}
Expand Down
8 changes: 5 additions & 3 deletions src/core/src/platforms/linux/uinput/trackpad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ std::optional<libevdev_uinput *> create_trackpad() {
// input_absinfo touch{0, 0, TOUCH_MAX, 4, 0, 0};
// libevdev_enable_event_code(dev, EV_ABS, ABS_MT_TOUCH_MAJOR, &touch);
// libevdev_enable_event_code(dev, EV_ABS, ABS_MT_TOUCH_MINOR, &touch);
// input_absinfo orientation{0, -3, 4, 0, 0, 0};
// libevdev_enable_event_code(dev, EV_ABS, ABS_MT_ORIENTATION, &orientation);
input_absinfo orientation{0, -90, 90, 0, 0, 0};
libevdev_enable_event_code(dev, EV_ABS, ABS_MT_ORIENTATION, &orientation);

// https://docs.kernel.org/input/event-codes.html#trackpads
libevdev_enable_property(dev, INPUT_PROP_POINTER);
Expand All @@ -143,10 +143,11 @@ Trackpad::Trackpad() {

Trackpad::~Trackpad() {}

void Trackpad::place_finger(int finger_nr, float x, float y, float pressure) {
void Trackpad::place_finger(int finger_nr, float x, float y, float pressure, int orientation) {
if (auto touchpad = this->_state->trackpad.get()) {
int scaled_x = (int)std::lround(TOUCH_MAX_X * x);
int scaled_y = (int)std::lround(TOUCH_MAX_Y * y);
int scaled_orientation = std::clamp(orientation, -90, 90);

if (_state->fingers.find(finger_nr) == _state->fingers.end()) {
// Wow, a wild finger appeared!
Expand Down Expand Up @@ -188,6 +189,7 @@ void Trackpad::place_finger(int finger_nr, float x, float y, float pressure) {
libevdev_uinput_write_event(touchpad, EV_ABS, ABS_MT_POSITION_Y, scaled_y);
libevdev_uinput_write_event(touchpad, EV_ABS, ABS_PRESSURE, (int)std::lround(pressure * PRESSURE_MAX));
libevdev_uinput_write_event(touchpad, EV_ABS, ABS_MT_PRESSURE, (int)std::lround(pressure * PRESSURE_MAX));
libevdev_uinput_write_event(touchpad, EV_ABS, ABS_MT_ORIENTATION, scaled_orientation);

libevdev_uinput_write_event(touchpad, EV_SYN, SYN_REPORT, 0);
}
Expand Down
22 changes: 0 additions & 22 deletions src/core/src/platforms/linux/uinput/uinput.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
#include <core/input.hpp>
#include <filesystem>
#include <helpers/logger.hpp>
#include <immer/array.hpp>
#include <immer/atom.hpp>
#include <iomanip>
#include <libevdev/libevdev-uinput.h>
#include <libevdev/libevdev.h>
#include <libudev.h>
Expand Down Expand Up @@ -54,25 +51,6 @@ std::vector<libevdev_event_ptr> fetch_events(const libevdev_ptr &dev, int max_ev
*/
std::vector<libevdev_event_ptr> fetch_events(int uinput_fd, int max_events = 50);

/**
* Takes an UTF-32 encoded string and returns a hex string representation of the bytes (uppercase)
*
* ex: ['💩'] = "1F4A9" // see UTF encoding at https://www.compart.com/en/unicode/U+1F4A9
*
* adapted from: https://stackoverflow.com/a/7639754
*/
static std::string to_hex(const std::basic_string<char32_t> &str) {
std::stringstream ss;
ss << std::hex << std::setfill('0');
for (const auto &ch : str) {
ss << ch;
}

std::string hex_unicode(ss.str());
std::transform(hex_unicode.begin(), hex_unicode.end(), hex_unicode.begin(), ::toupper);
return hex_unicode;
}

static std::pair<unsigned int, unsigned int> get_major_minor(const std::string &devnode) {
struct stat buf {};
if (stat(devnode.c_str(), &buf) == -1) {
Expand Down
10 changes: 8 additions & 2 deletions src/moonlight-server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ FetchContent_Declare(
)
find_package(PkgConfig)
pkg_check_modules(LIBUNWIND QUIET libunwind)
if(LIBUNWIND_FOUND)
if (LIBUNWIND_FOUND)
set(CPPTRACE_UNWIND_WITH_LIBUNWIND ON)
else ()
message(WARNING "Missing libunwind, stacktraces will not be available.")
Expand All @@ -70,7 +70,7 @@ FetchContent_MakeAvailable(cpptrace)
find_package(Threads REQUIRED)
find_package(OpenSSL REQUIRED)

find_package(Boost REQUIRED COMPONENTS log)
find_package(Boost REQUIRED COMPONENTS log locale)
include_directories(${Boost_INCLUDE_DIRS})

target_link_libraries(
Expand All @@ -97,6 +97,12 @@ file(GLOB SRC_LIST SRCS
streaming/*.cpp)

if (UNIX AND NOT APPLE)
message(STATUS "Adding input implementation for LINUX")

find_package(ICU 61.0 COMPONENTS uc REQUIRED) # brought by libboost-locale-dev
target_link_libraries_system(wolf_runner PRIVATE ICU::uc)

list(APPEND SRC_LIST platforms/input_linux.cpp)
pkg_check_modules(LIBDRM IMPORTED_TARGET libdrm)
pkg_check_modules(LIBPCI IMPORTED_TARGET libpci)

Expand Down
Loading

0 comments on commit 65624f4

Please sign in to comment.