Sunshine v2025.118.151840
Self-hosted game stream host for Moonlight.
legacy_input.cpp File Reference

Implementation of input handling, prior to migration to inputtino. More...

#include <fcntl.h>
#include <linux/uinput.h>
#include <poll.h>
#include <libevdev/libevdev-uinput.h>
#include <libevdev/libevdev.h>
#include <boost/locale.hpp>
#include <cmath>
#include <cstring>
#include <filesystem>
#include <thread>
#include "src/config.h"
#include "src/input.h"
#include "src/logging.h"
#include "src/platform/common.h"
#include "src/utility.h"
#include "src/platform/linux/misc.h"
Include dependency graph for legacy_input.cpp:

Classes

struct  platf::client_input_raw_t
 
class  platf::effect_t::data_t
 
class  platf::effect_t
 
struct  platf::input_raw_t
 
struct  platf::keycode_t
 
struct  platf::rumble_ctx_t
 

Macros

#define __CONVERT(wincode, linuxcode, scancode, keysym)
 
#define __CONVERT_UNSAFE(wincode, linuxcode, scancode, keysym)    keycodes[wincode] = keycode_t { linuxcode, scancode };
 
#define REL_HWHEEL_HI_RES   0x0c
 
#define REL_WHEEL_HI_RES   0x0b
 

Typedefs

using platf::evdev_t = util::safe_ptr<libevdev, libevdev_free>
 
using platf::mail_evdev_t = std::tuple<int, uinput_t::pointer, feedback_queue_t, pollfd_t>
 
using platf::uinput_t = util::safe_ptr<libevdev_uinput, libevdev_uinput_destroy>
 

Functions

void platf::abs_mouse (input_t &input, const touch_port_t &touch_port, float x, float y)
 Absolute mouse move.
 
int platf::alloc_gamepad (input_t &input, const gamepad_id_t &id, const gamepad_arrival_t &metadata, feedback_queue_t feedback_queue)
 Create a new virtual gamepad.
 
std::unique_ptr< client_input_tplatf::allocate_client_input_context (input_t &input)
 Allocate a context to store per-client input data.
 
int platf::allocate_slot_index_for_pointer_id (client_input_raw_t *input, uint32_t pointerId)
 Reserves a slot index for a new pointer ID.
 
void platf::broadcastRumble (safe::queue_t< mail_evdev_t > &ctx)
 
void platf::button_mouse (input_t &input, int button, bool release)
 Mouse button press/release.
 
void platf::free_gamepad (input_t &input, int nr)
 
void platf::freeInput (void *)
 
void platf::gamepad_battery (input_t &input, const gamepad_battery_t &battery)
 Send a gamepad battery event to the OS.
 
void platf::gamepad_motion (input_t &input, const gamepad_motion_t &motion)
 Send a gamepad motion event to the OS.
 
void platf::gamepad_touch (input_t &input, const gamepad_touch_t &touch)
 Send a gamepad touch event to the OS.
 
void platf::gamepad_update (input_t &input, int nr, const gamepad_state_t &gamepad_state)
 Updates virtual gamepad with the provided gamepad state.
 
platform_caps::caps_t platf::get_capabilities ()
 Get the supported platform capabilities to advertise to the client.
 
util::point_t platf::get_mouse_loc (input_t &input)
 Get the current mouse position on screen.
 
void platf::hscroll (input_t &input, int high_res_distance)
 Horizontal mouse scroll.
 
input_t platf::input ()
 Initialize the input system and return it.
 
evdev_t platf::keyboard ()
 Initialize a new keyboard and return it.
 
void platf::keyboard_ev (libevdev_uinput *keyboard, int linux_code, int event_code=1)
 
void platf::keyboard_update (input_t &input, uint16_t modcode, bool release, uint8_t flags)
 Keyboard emulation.
 
 platf::KITTY_USING_MOVE_T (pollfd_t, pollfd, read_pollfd, { if(el.fd >=0) { ioctl(el.fd, EVIOCGRAB,(void *) 0);close(el.fd);} })
 
evdev_t platf::mouse_abs ()
 Initialize a new uinput virtual absolute mouse and return it.
 
evdev_t platf::mouse_rel ()
 Initialize a new uinput virtual relative mouse and return it.
 
void platf::move_mouse (input_t &input, int deltaX, int deltaY)
 Relative mouse move.
 
void platf::pen_update (client_input_t *input, const touch_port_t &touch_port, const pen_input_t &pen)
 Send a pen event to the OS.
 
evdev_t platf::penpad ()
 Initialize a new uinput virtual pen pad and return it.
 
void platf::rumbleIterate (std::vector< effect_t > &effects, std::vector< pollfd_t > &polls, std::chrono::milliseconds to)
 
void platf::scroll (input_t &input, int high_res_distance)
 Vertical mouse scroll.
 
int platf::slot_index_by_pointer_id (client_input_raw_t *input, uint32_t pointerId)
 Retrieves the slot index for a given pointer ID.
 
int platf::startRumble (rumble_ctx_t &ctx)
 
void platf::stopRumble (rumble_ctx_t &ctx)
 
std::vector< supported_gamepad_t > & platf::supported_gamepads (input_t *input)
 Gets the supported gamepads for this platform backend.
 
std::string platf::to_hex (const std::basic_string< char32_t > &str)
 
void platf::touch_update (client_input_t *input, const touch_port_t &touch_port, const touch_input_t &touch)
 Send a touch event to the OS.
 
evdev_t platf::touchscreen ()
 Initialize a new uinput virtual touchscreen and return it.
 
void platf::unicode (input_t &input, char *utf8, int size)
 
evdev_t platf::x360 ()
 Initialize a new uinput virtual X360 gamepad and return it.
 

Variables

constexpr auto platf::DISTANCE_MAX = 1024
 
constexpr int64_t platf::INVALID_TRACKING_ID = -1
 
constexpr auto platf::mail_evdev = "platf::evdev"sv
 
constexpr auto platf::NUM_TOUCH_SLOTS = 10
 
constexpr auto platf::PRESSURE_MAX = 4096
 
constexpr auto platf::PRESSURE_MIN = 0.10f
 
constexpr pollfd platf::read_pollfd { -1, 0, 0 }
 
constexpr touch_port_t platf::target_touch_port
 
constexpr auto platf::UNKNOWN = 0
 

Detailed Description

Implementation of input handling, prior to migration to inputtino.

Todo
Remove this file after the next stable release

Macro Definition Documentation

◆ __CONVERT

#define __CONVERT ( wincode,
linuxcode,
scancode,
keysym )
Value:
static_assert(wincode < keycodes.size(), "Keycode doesn't fit into keycode array"); \
static_assert(wincode >= 0, "Are you mad?, keycode needs to be greater than zero"); \
__CONVERT_UNSAFE(wincode, linuxcode, scancode, keysym)

Function Documentation

◆ abs_mouse()

void platf::abs_mouse ( input_t & input,
const touch_port_t & touch_port,
float x,
float y )

Absolute mouse move.

Parameters
inputThe input_t instance to use.
touch_portThe touch_port instance to use.
xAbsolute x position.
yAbsolute y position.

Examples

abs_mouse(input, touch_port, 0, 0);

◆ alloc_gamepad()

int platf::alloc_gamepad ( input_t & input,
const gamepad_id_t & id,
const gamepad_arrival_t & metadata,
feedback_queue_t feedback_queue )

Create a new virtual gamepad.

Parameters
inputThe global input context.
idThe gamepad ID.
metadataController metadata from client (empty if none provided).
feedback_queueThe queue for posting messages back to the client.
Returns
0 on success.

◆ allocate_client_input_context()

std::unique_ptr< client_input_t > platf::allocate_client_input_context ( input_t & input)

Allocate a context to store per-client input data.

Allocates a context to store per-client input data.

Parameters
inputThe global input context.
Returns
A unique pointer to a per-client input data context.

◆ allocate_slot_index_for_pointer_id()

int platf::allocate_slot_index_for_pointer_id ( client_input_raw_t * input,
uint32_t pointerId )

Reserves a slot index for a new pointer ID.

Parameters
inputThe client-specific input context.
pointerIdThe pointer ID sent from the client.
Returns
Slot index or -1 if no unallocated slots remain.

◆ button_mouse()

void platf::button_mouse ( input_t & input,
int button,
bool release )

Mouse button press/release.

Parameters
inputThe input_t instance to use.
buttonWhich mouse button to emulate.
releaseWhether the event was a press (false) or a release (true)

Examples

button_mouse(input, 1, false); // Press left mouse button

◆ gamepad_battery()

void platf::gamepad_battery ( input_t & input,
const gamepad_battery_t & battery )

Send a gamepad battery event to the OS.

Sends a gamepad battery event to the OS.

Parameters
inputThe global input context.
batteryThe battery event.

◆ gamepad_motion()

void platf::gamepad_motion ( input_t & input,
const gamepad_motion_t & motion )

Send a gamepad motion event to the OS.

Sends a gamepad motion event to the OS.

Parameters
inputThe global input context.
motionThe motion event.

◆ gamepad_touch()

void platf::gamepad_touch ( input_t & input,
const gamepad_touch_t & touch )

Send a gamepad touch event to the OS.

Sends a gamepad touch event to the OS.

Parameters
inputThe global input context.
touchThe touch event.

◆ gamepad_update()

void platf::gamepad_update ( input_t & input,
int nr,
const gamepad_state_t & gamepad_state )

Updates virtual gamepad with the provided gamepad state.

Parameters
inputThe input context.
nrThe gamepad index to update.
gamepad_stateThe gamepad button/axis state sent from the client.

◆ get_capabilities()

platform_caps::caps_t platf::get_capabilities ( )

Get the supported platform capabilities to advertise to the client.

Returns the supported platform capabilities to advertise to the client.

Returns
Capability flags.

◆ get_mouse_loc()

util::point_t platf::get_mouse_loc ( input_t & input)

Get the current mouse position on screen.

Parameters
inputThe input_t instance to use.
Returns
Screen coordinates of the mouse.

Examples

auto [x, y] = get_mouse_loc(input);

◆ hscroll()

void platf::hscroll ( input_t & input,
int high_res_distance )

Horizontal mouse scroll.

Parameters
inputThe input_t instance to use.
high_res_distanceHow far to scroll.

Examples

hscroll(input, 1200);

◆ input()

input_t platf::input ( )

Initialize the input system and return it.

Examples

auto my_input = input();

◆ keyboard()

evdev_t platf::keyboard ( )

Initialize a new keyboard and return it.

Examples

auto my_keyboard = keyboard();

◆ keyboard_update()

void platf::keyboard_update ( input_t & input,
uint16_t modcode,
bool release,
uint8_t flags )

Keyboard emulation.

Parameters
inputThe input_t instance to use.
modcodeThe moonlight key code.
releaseWhether the event was a press (false) or a release (true).
flagsSS_KBE_FLAG_* values.

Examples

keyboard(input, 0x5A, false, 0); // Press Z

◆ mouse_abs()

evdev_t platf::mouse_abs ( )

Initialize a new uinput virtual absolute mouse and return it.

Examples

auto my_mouse = mouse_abs();

◆ mouse_rel()

evdev_t platf::mouse_rel ( )

Initialize a new uinput virtual relative mouse and return it.

Examples

auto my_mouse = mouse_rel();

◆ move_mouse()

void platf::move_mouse ( input_t & input,
int deltaX,
int deltaY )

Relative mouse move.

Parameters
inputThe input_t instance to use.
deltaXRelative x position.
deltaYRelative y position.

Examples

move_mouse(input, 10, 10); // Move mouse 10 pixels down and right

◆ pen_update()

void platf::pen_update ( client_input_t * input,
const touch_port_t & touch_port,
const pen_input_t & pen )

Send a pen event to the OS.

Sends a pen event to the OS.

Parameters
inputThe client-specific input context.
touch_portThe current viewport for translating to screen coordinates.
penThe pen event.

◆ penpad()

evdev_t platf::penpad ( )

Initialize a new uinput virtual pen pad and return it.

Examples

auto my_penpad = penpad();

◆ scroll()

void platf::scroll ( input_t & input,
int high_res_distance )

Vertical mouse scroll.

Parameters
inputThe input_t instance to use.
high_res_distanceHow far to scroll.

Examples

scroll(input, 1200);

◆ slot_index_by_pointer_id()

int platf::slot_index_by_pointer_id ( client_input_raw_t * input,
uint32_t pointerId )

Retrieves the slot index for a given pointer ID.

Parameters
inputThe client-specific input context.
pointerIdThe pointer ID sent from the client.
Returns
Slot index or -1 if not found.

◆ supported_gamepads()

std::vector< supported_gamepad_t > & platf::supported_gamepads ( input_t * input)

Gets the supported gamepads for this platform backend.

This may be called prior to platf::input()!

Parameters
inputPointer to the platform's input_t or nullptr.
Returns
Vector of gamepad options and status.

◆ to_hex()

std::string platf::to_hex ( const std::basic_string< char32_t > & str)

Takes an UTF-32 encoded string and returns a hex string representation of the bytes (uppercase)

ex: ['👱'] = "1F471" // see UTF encoding at https://www.compart.com/en/unicode/U+1F471

adapted from: https://stackoverflow.com/a/7639754

◆ touch_update()

void platf::touch_update ( client_input_t * input,
const touch_port_t & touch_port,
const touch_input_t & touch )

Send a touch event to the OS.

Sends a touch event to the OS.

Parameters
inputThe client-specific input context.
touch_portThe current viewport for translating to screen coordinates.
touchThe touch event.

◆ touchscreen()

evdev_t platf::touchscreen ( )

Initialize a new uinput virtual touchscreen and return it.

Examples

auto my_touchscreen = touchscreen();

◆ unicode()

void platf::unicode ( input_t & input,
char * utf8,
int size )

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:

◆ x360()

evdev_t platf::x360 ( )

Initialize a new uinput virtual X360 gamepad and return it.

Examples

auto my_x360 = x360();

Variable Documentation

◆ target_touch_port

constexpr touch_port_t platf::target_touch_port
constexpr
Initial value:
{
0, 0,
19200, 12000
}