Sunshine latest
Self-hosted game stream host for Moonlight.
input.cpp File Reference

Definitions for gamepad, keyboard, and mouse input handling. More...

#include <cstdint>
#include <moonlight-common-c/src/Input.h>
#include <moonlight-common-c/src/Limelight.h>
#include <bitset>
#include <chrono>
#include <cmath>
#include <list>
#include <thread>
#include <unordered_map>
#include <boost/endian/buffers.hpp>
#include "config.h"
#include "globals.h"
#include "input.h"
#include "logging.h"
#include "platform/common.h"
#include "thread_pool.h"
#include "utility.h"
Include dependency graph for input.cpp:

Classes

class  input::deinit_t
 
struct  input::gamepad_t
 
struct  input::input_t
 

Macros

#define DISABLE_LEFT_BUTTON_DELAY   ((thread_pool_util::ThreadPool::task_id_t) 0x01)
 
#define ENABLE_LEFT_BUTTON_DELAY   nullptr
 
#define WHEEL_DELTA   120
 

Typedefs

typedef uint32_t input::key_press_id_t
 

Enumerations

enum class  input::batch_result_e { batched , not_batchable , terminate_batch }
 
enum class  input::button_state_e { NONE , DOWN , UP }
 

Functions

std::shared_ptr< input_tinput::alloc (safe::mail_t mail)
 
template<std::size_t N>
int input::alloc_id (std::bitset< N > &gamepad_mask)
 
int input::apply_shortcut (short keyCode)
 Apply shortcut based on VKEY.
 
batch_result_e input::batch (PNV_ABS_MOUSE_MOVE_PACKET dest, PNV_ABS_MOUSE_MOVE_PACKET src)
 Batch two absolute mouse messages.
 
batch_result_e input::batch (PNV_INPUT_HEADER dest, PNV_INPUT_HEADER src)
 Batch two input messages.
 
batch_result_e input::batch (PNV_MULTI_CONTROLLER_PACKET dest, PNV_MULTI_CONTROLLER_PACKET src)
 Batch two controller state messages.
 
batch_result_e input::batch (PNV_REL_MOUSE_MOVE_PACKET dest, PNV_REL_MOUSE_MOVE_PACKET src)
 Batch two relative mouse messages.
 
batch_result_e input::batch (PNV_SCROLL_PACKET dest, PNV_SCROLL_PACKET src)
 Batch two vertical scroll messages.
 
batch_result_e input::batch (PSS_CONTROLLER_MOTION_PACKET dest, PSS_CONTROLLER_MOTION_PACKET src)
 Batch two controller motion messages.
 
batch_result_e input::batch (PSS_CONTROLLER_TOUCH_PACKET dest, PSS_CONTROLLER_TOUCH_PACKET src)
 Batch two controller touch messages.
 
batch_result_e input::batch (PSS_HSCROLL_PACKET dest, PSS_HSCROLL_PACKET src)
 Batch two horizontal scroll messages.
 
batch_result_e input::batch (PSS_PEN_PACKET dest, PSS_PEN_PACKET src)
 Batch two pen messages.
 
batch_result_e input::batch (PSS_TOUCH_PACKET dest, PSS_TOUCH_PACKET src)
 Batch two touch messages.
 
std::optional< std::pair< float, float > > input::client_to_touchport (std::shared_ptr< input_t > &input, const std::pair< float, float > &val, const std::pair< float, float > &size)
 Converts client coordinates on the specified surface into screen coordinates.
 
uint8_t input::flags_from_kpid (key_press_id_t kpid)
 
void input::free_gamepad (platf::input_t &platf_input, int id)
 
template<std::size_t N>
void input::free_id (std::bitset< N > &gamepad_mask, int id)
 
float input::from_clamped_netfloat (netfloat f, float min, float max)
 Convert a little-endian netfloat to a native endianness float and clamps it.
 
float input::from_netfloat (netfloat f)
 Convert a little-endian netfloat to a native endianness float.
 
std::unique_ptr< platf::deinit_tinput::init ()
 
bool input::is_modifier (uint16_t keyCode)
 
key_press_id_t input::make_kpid (uint16_t vk, uint8_t flags)
 
short input::map_keycode (short keycode)
 
float input::multiply_polar_by_cartesian_scalar (float r, float angle, const std::pair< float, float > &scalar)
 Multiply a polar coordinate pair by a cartesian scaling factor.
 
void input::passthrough (PNV_UNICODE_PACKET packet)
 
void input::passthrough (std::shared_ptr< input_t > &input, PNV_ABS_MOUSE_MOVE_PACKET packet)
 
void input::passthrough (std::shared_ptr< input_t > &input, PNV_KEYBOARD_PACKET packet)
 
void input::passthrough (std::shared_ptr< input_t > &input, PNV_MOUSE_BUTTON_PACKET packet)
 
void input::passthrough (std::shared_ptr< input_t > &input, PNV_MULTI_CONTROLLER_PACKET packet)
 
void input::passthrough (std::shared_ptr< input_t > &input, PNV_REL_MOUSE_MOVE_PACKET packet)
 
void input::passthrough (std::shared_ptr< input_t > &input, PNV_SCROLL_PACKET packet)
 Called to pass a vertical scroll message the platform backend.
 
void input::passthrough (std::shared_ptr< input_t > &input, PSS_CONTROLLER_ARRIVAL_PACKET packet)
 Called to pass a controller arrival message to the platform backend.
 
void input::passthrough (std::shared_ptr< input_t > &input, PSS_CONTROLLER_BATTERY_PACKET packet)
 Called to pass a controller battery message to the platform backend.
 
void input::passthrough (std::shared_ptr< input_t > &input, PSS_CONTROLLER_MOTION_PACKET packet)
 Called to pass a controller motion message to the platform backend.
 
void input::passthrough (std::shared_ptr< input_t > &input, PSS_CONTROLLER_TOUCH_PACKET packet)
 Called to pass a controller touch message to the platform backend.
 
void input::passthrough (std::shared_ptr< input_t > &input, PSS_HSCROLL_PACKET packet)
 Called to pass a horizontal scroll message the platform backend.
 
void input::passthrough (std::shared_ptr< input_t > &input, PSS_PEN_PACKET packet)
 Called to pass a pen message to the platform backend.
 
void input::passthrough (std::shared_ptr< input_t > &input, PSS_TOUCH_PACKET packet)
 Called to pass a touch message to the platform backend.
 
void input::passthrough (std::shared_ptr< input_t > &input, std::vector< std::uint8_t > &&input_data)
 Called on the control stream thread to queue an input message.
 
void input::passthrough_next_message (std::shared_ptr< input_t > input)
 Called on a thread pool thread to process an input message.
 
void input::print (PNV_ABS_MOUSE_MOVE_PACKET packet)
 
void input::print (PNV_KEYBOARD_PACKET packet)
 
void input::print (PNV_MOUSE_BUTTON_PACKET packet)
 
void input::print (PNV_MULTI_CONTROLLER_PACKET packet)
 
void input::print (PNV_REL_MOUSE_MOVE_PACKET packet)
 
void input::print (PNV_SCROLL_PACKET packet)
 
void input::print (PNV_UNICODE_PACKET packet)
 
void input::print (PSS_CONTROLLER_ARRIVAL_PACKET packet)
 Prints a controller arrival packet.
 
void input::print (PSS_CONTROLLER_BATTERY_PACKET packet)
 Prints a controller battery packet.
 
void input::print (PSS_CONTROLLER_MOTION_PACKET packet)
 Prints a controller motion packet.
 
void input::print (PSS_CONTROLLER_TOUCH_PACKET packet)
 Prints a controller touch packet.
 
void input::print (PSS_HSCROLL_PACKET packet)
 
void input::print (PSS_PEN_PACKET packet)
 Prints a pen packet.
 
void input::print (PSS_TOUCH_PACKET packet)
 Prints a touch packet.
 
void input::print (void *payload)
 
bool input::probe_gamepads ()
 
void input::repeat_key (uint16_t key_code, uint8_t flags, uint8_t synthetic_modifiers)
 
void input::reset (std::shared_ptr< input_t > &input)
 
std::pair< float, float > input::scale_client_contact_area (const std::pair< float, float > &val, uint16_t rotation, const std::pair< float, float > &scalar)
 Scale the ellipse axes according to the provided size.
 
void input::send_key_and_modifiers (uint16_t key_code, bool release, uint8_t flags, uint8_t synthetic_modifiers)
 
void input::update_shortcutFlags (int *flags, short keyCode, bool release)
 Update flags for keyboard shortcut combo's.
 
uint16_t input::vk_from_kpid (key_press_id_t kpid)
 

Variables

constexpr auto input::MAX_GAMEPADS = std::min((std::size_t) platf::MAX_GAMEPADS, sizeof(std::int16_t) * 8)
 
constexpr auto input::VKEY_CONTROL = 0x11
 
constexpr auto input::VKEY_LCONTROL = 0xA2
 
constexpr auto input::VKEY_LMENU = 0xA4
 
constexpr auto input::VKEY_LSHIFT = 0xA0
 
constexpr auto input::VKEY_MENU = 0x12
 
constexpr auto input::VKEY_RCONTROL = 0xA3
 
constexpr auto input::VKEY_RMENU = 0xA5
 
constexpr auto input::VKEY_RSHIFT = 0xA1
 
constexpr auto input::VKEY_SHIFT = 0x10
 

Detailed Description

Definitions for gamepad, keyboard, and mouse input handling.

Enumeration Type Documentation

◆ batch_result_e

enum class input::batch_result_e
strong
Enumerator
batched 

This entry was batched with the source entry.

not_batchable 

Not eligible to batch but continue attempts to batch.

terminate_batch 

Stop trying to batch with this entry.

◆ button_state_e

enum class input::button_state_e
strong
Enumerator
NONE 

No button state.

DOWN 

Button is down.

UP 

Button is up.

Function Documentation

◆ apply_shortcut()

int input::apply_shortcut ( short keyCode)
inline

Apply shortcut based on VKEY.

Parameters
keyCodeThe VKEY code
Returns
0 if no shortcut applied, > 0 if shortcut applied.

◆ batch() [1/10]

batch_result_e input::batch ( PNV_ABS_MOUSE_MOVE_PACKET dest,
PNV_ABS_MOUSE_MOVE_PACKET src )

Batch two absolute mouse messages.

Parameters
destThe original packet to batch into.
srcA later packet to attempt to batch.
Returns
The status of the batching operation.

◆ batch() [2/10]

batch_result_e input::batch ( PNV_INPUT_HEADER dest,
PNV_INPUT_HEADER src )

Batch two input messages.

Parameters
destThe original packet to batch into.
srcA later packet to attempt to batch.
Returns
The status of the batching operation.

◆ batch() [3/10]

batch_result_e input::batch ( PNV_MULTI_CONTROLLER_PACKET dest,
PNV_MULTI_CONTROLLER_PACKET src )

Batch two controller state messages.

Parameters
destThe original packet to batch into.
srcA later packet to attempt to batch.
Returns
The status of the batching operation.

◆ batch() [4/10]

batch_result_e input::batch ( PNV_REL_MOUSE_MOVE_PACKET dest,
PNV_REL_MOUSE_MOVE_PACKET src )

Batch two relative mouse messages.

Parameters
destThe original packet to batch into.
srcA later packet to attempt to batch.
Returns
The status of the batching operation.

◆ batch() [5/10]

batch_result_e input::batch ( PNV_SCROLL_PACKET dest,
PNV_SCROLL_PACKET src )

Batch two vertical scroll messages.

Parameters
destThe original packet to batch into.
srcA later packet to attempt to batch.
Returns
The status of the batching operation.

◆ batch() [6/10]

batch_result_e input::batch ( PSS_CONTROLLER_MOTION_PACKET dest,
PSS_CONTROLLER_MOTION_PACKET src )

Batch two controller motion messages.

Parameters
destThe original packet to batch into.
srcA later packet to attempt to batch.
Returns
The status of the batching operation.

◆ batch() [7/10]

batch_result_e input::batch ( PSS_CONTROLLER_TOUCH_PACKET dest,
PSS_CONTROLLER_TOUCH_PACKET src )

Batch two controller touch messages.

Parameters
destThe original packet to batch into.
srcA later packet to attempt to batch.
Returns
The status of the batching operation.

◆ batch() [8/10]

batch_result_e input::batch ( PSS_HSCROLL_PACKET dest,
PSS_HSCROLL_PACKET src )

Batch two horizontal scroll messages.

Parameters
destThe original packet to batch into.
srcA later packet to attempt to batch.
Returns
The status of the batching operation.

◆ batch() [9/10]

batch_result_e input::batch ( PSS_PEN_PACKET dest,
PSS_PEN_PACKET src )

Batch two pen messages.

Parameters
destThe original packet to batch into.
srcA later packet to attempt to batch.
Returns
The status of the batching operation.

◆ batch() [10/10]

batch_result_e input::batch ( PSS_TOUCH_PACKET dest,
PSS_TOUCH_PACKET src )

Batch two touch messages.

Parameters
destThe original packet to batch into.
srcA later packet to attempt to batch.
Returns
The status of the batching operation.

◆ client_to_touchport()

std::optional< std::pair< float, float > > input::client_to_touchport ( std::shared_ptr< input_t > & input,
const std::pair< float, float > & val,
const std::pair< float, float > & size )

Converts client coordinates on the specified surface into screen coordinates.

Parameters
inputThe input context.
valThe cartesian coordinate pair to convert.
sizeThe size of the client's surface containing the value.
Returns
The host-relative coordinate pair if a touchport is available.

◆ from_clamped_netfloat()

float input::from_clamped_netfloat ( netfloat f,
float min,
float max )

Convert a little-endian netfloat to a native endianness float and clamps it.

Parameters
fNetfloat value.
minThe minimium value for clamping.
maxThe maximum value for clamping.
Returns
Clamped native endianess float value.

◆ from_netfloat()

float input::from_netfloat ( netfloat f)

Convert a little-endian netfloat to a native endianness float.

Parameters
fNetfloat value.
Returns
The native endianness float value.

◆ multiply_polar_by_cartesian_scalar()

float input::multiply_polar_by_cartesian_scalar ( float r,
float angle,
const std::pair< float, float > & scalar )

Multiply a polar coordinate pair by a cartesian scaling factor.

Parameters
rThe radial coordinate.
angleThe angular coordinate (radians).
scalarThe scalar cartesian coordinate pair.
Returns
The scaled radial coordinate.

◆ passthrough() [1/10]

void input::passthrough ( std::shared_ptr< input_t > & input,
PNV_MOUSE_BUTTON_PACKET packet )

When Moonlight sends mouse input through absolute coordinates, it's possible that BUTTON_RIGHT is pressed down immediately after releasing BUTTON_LEFT. As a result, Sunshine will left-click on hyperlinks in the browser before right-clicking

This can be solved by delaying BUTTON_LEFT, however, any delay on input is undesirable during gaming As a compromise, Sunshine will only put delays on BUTTON_LEFT when absolute mouse coordinates have been sent.

Try to make sure BUTTON_RIGHT gets called before BUTTON_LEFT is released.

input->mouse_left_button_timeout can only be nullptr when the last mouse coordinates were absolute

◆ passthrough() [2/10]

void input::passthrough ( std::shared_ptr< input_t > & input,
PNV_SCROLL_PACKET packet )

Called to pass a vertical scroll message the platform backend.

Parameters
inputThe input context pointer.
packetThe scroll packet.

◆ passthrough() [3/10]

void input::passthrough ( std::shared_ptr< input_t > & input,
PSS_CONTROLLER_ARRIVAL_PACKET packet )

Called to pass a controller arrival message to the platform backend.

Parameters
inputThe input context pointer.
packetThe controller arrival packet.

◆ passthrough() [4/10]

void input::passthrough ( std::shared_ptr< input_t > & input,
PSS_CONTROLLER_BATTERY_PACKET packet )

Called to pass a controller battery message to the platform backend.

Parameters
inputThe input context pointer.
packetThe controller battery packet.

◆ passthrough() [5/10]

void input::passthrough ( std::shared_ptr< input_t > & input,
PSS_CONTROLLER_MOTION_PACKET packet )

Called to pass a controller motion message to the platform backend.

Parameters
inputThe input context pointer.
packetThe controller motion packet.

◆ passthrough() [6/10]

void input::passthrough ( std::shared_ptr< input_t > & input,
PSS_CONTROLLER_TOUCH_PACKET packet )

Called to pass a controller touch message to the platform backend.

Parameters
inputThe input context pointer.
packetThe controller touch packet.

◆ passthrough() [7/10]

void input::passthrough ( std::shared_ptr< input_t > & input,
PSS_HSCROLL_PACKET packet )

Called to pass a horizontal scroll message the platform backend.

Parameters
inputThe input context pointer.
packetThe scroll packet.

◆ passthrough() [8/10]

void input::passthrough ( std::shared_ptr< input_t > & input,
PSS_PEN_PACKET packet )

Called to pass a pen message to the platform backend.

Parameters
inputThe input context pointer.
packetThe pen packet.

◆ passthrough() [9/10]

void input::passthrough ( std::shared_ptr< input_t > & input,
PSS_TOUCH_PACKET packet )

Called to pass a touch message to the platform backend.

Parameters
inputThe input context pointer.
packetThe touch packet.

◆ passthrough() [10/10]

void input::passthrough ( std::shared_ptr< input_t > & input,
std::vector< std::uint8_t > && input_data )

Called on the control stream thread to queue an input message.

Parameters
inputThe input context pointer.
input_dataThe input message.

◆ passthrough_next_message()

void input::passthrough_next_message ( std::shared_ptr< input_t > input)

Called on a thread pool thread to process an input message.

Parameters
inputThe input context pointer.

◆ print() [1/6]

void input::print ( PSS_CONTROLLER_ARRIVAL_PACKET packet)

Prints a controller arrival packet.

Parameters
packetThe controller arrival packet.

◆ print() [2/6]

void input::print ( PSS_CONTROLLER_BATTERY_PACKET packet)

Prints a controller battery packet.

Parameters
packetThe controller battery packet.

◆ print() [3/6]

void input::print ( PSS_CONTROLLER_MOTION_PACKET packet)

Prints a controller motion packet.

Parameters
packetThe controller motion packet.

◆ print() [4/6]

void input::print ( PSS_CONTROLLER_TOUCH_PACKET packet)

Prints a controller touch packet.

Parameters
packetThe controller touch packet.

◆ print() [5/6]

void input::print ( PSS_PEN_PACKET packet)

Prints a pen packet.

Parameters
packetThe pen packet.

◆ print() [6/6]

void input::print ( PSS_TOUCH_PACKET packet)

Prints a touch packet.

Parameters
packetThe touch packet.

◆ scale_client_contact_area()

std::pair< float, float > input::scale_client_contact_area ( const std::pair< float, float > & val,
uint16_t rotation,
const std::pair< float, float > & scalar )

Scale the ellipse axes according to the provided size.

Parameters
valThe major and minor axis pair.
rotationThe rotation value from the touch/pen event.
scalarThe scalar cartesian coordinate pair.
Returns
The major and minor axis pair.