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

Definitions for input handling on Windows. More...

#include <windows.h>
#include <cmath>
#include <thread>
#include <ViGEm/Client.h>
#include "keylayout.h"
#include "misc.h"
#include "src/config.h"
#include "src/globals.h"
#include "src/logging.h"
#include "src/platform/common.h"
Include dependency graph for input.cpp:

Classes

struct  platf::client_input_raw_t
 
struct  platf::gamepad_context_t
 
struct  platf::gp_touch_context_t
 
struct  platf::input_raw_t
 
class  platf::vigem_t
 

Macros

#define APPLY_CALIBRATION(val, bias, scale)   (int32_t)(((float) (val) + (bias)) / (scale))
 
#define DPS_TO_DS4_GYRO(x)   (int32_t)((x) * (1024 / 64))
 
#define MPS2_TO_DS4_ACCEL(x)   (int32_t)(((x) / EARTH_G) * 8192)
 
#define WINVER   0x0A00
 

Typedefs

using platf::client_t = util::safe_ptr<_VIGEM_CLIENT_T, vigem_free>
 
using platf::target_t = util::safe_ptr<_VIGEM_TARGET_T, vigem_target_free>
 

Functions

void platf::abs_mouse (input_t &input, const touch_port_t &touch_port, float x, float y)
 
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.
 
void platf::button_mouse (input_t &input, int button, bool release)
 
void platf::cancel_all_active_touches (client_input_raw_t *raw)
 Cancels all active touches.
 
void CALLBACK platf::ds4_notify (client_t::pointer client, target_t::pointer target, std::uint8_t largeMotor, std::uint8_t smallMotor, DS4_LIGHTBAR_COLOR, void *userdata)
 
void platf::ds4_update_ts_and_send (vigem_t *vigem, int nr)
 Sends DS4 input with updated timestamps and repeats to keep timestamp updated.
 
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 distance)
 
bool platf::inject_synthetic_pointer_input (input_raw_t *input, HSYNTHETICPOINTERDEVICE device, const POINTER_TYPE_INFO *pointerInfo, UINT32 count)
 Calls InjectSyntheticPointerInput() and switches input desktops if required.
 
input_t platf::input ()
 
void platf::keyboard_update (input_t &input, uint16_t modcode, bool release, uint8_t flags)
 
void platf::move_mouse (input_t &input, int deltaX, int deltaY)
 
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.
 
void platf::perform_touch_compaction (client_input_raw_t *raw)
 Compacts the touch slots into a contiguous block and updates the active count.
 
POINTER_TYPE_INFO * platf::pointer_by_id (client_input_raw_t *raw, uint32_t pointerId, uint8_t eventType)
 Gets a pointer slot by client-relative pointer ID, claiming a new one if necessary.
 
void platf::populate_common_pointer_info (POINTER_INFO &pointerInfo, const touch_port_t &touchPort, uint8_t eventType, float x, float y)
 Populate common POINTER_INFO members shared between pen and touch events.
 
void platf::repeat_pen (client_input_raw_t *raw)
 Repeats the current pen state to avoid the interactions timing out.
 
void platf::repeat_touch (client_input_raw_t *raw)
 Repeats the current touch state to avoid the interactions timing out.
 
void platf::scroll (input_t &input, int distance)
 
void platf::send_input (INPUT &i)
 Calls SendInput() and switches input desktops if required.
 
std::vector< supported_gamepad_t > & platf::supported_gamepads (input_t *input)
 Gets the supported gamepads for this platform backend.
 
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.
 
void platf::unicode (input_t &input, char *utf8, int size)
 
void CALLBACK platf::x360_notify (client_t::pointer client, target_t::pointer target, std::uint8_t largeMotor, std::uint8_t smallMotor, std::uint8_t, void *userdata)
 

Variables

thread_local HDESK platf::_lastKnownInputDesktop = nullptr
 
constexpr DS4_REPORT_EX platf::ds4_report_init_ex
 
constexpr DS4_TOUCH platf::ds4_touch_unused
 
constexpr float platf::EARTH_G = 9.80665f
 
constexpr auto platf::EDGE_TRIGGERED_POINTER_FLAGS = POINTER_FLAG_DOWN | POINTER_FLAG_UP | POINTER_FLAG_CANCELED | POINTER_FLAG_UPDATE
 
constexpr auto platf::ISPI_REPEAT_INTERVAL = 50ms
 
constexpr touch_port_t platf::target_touch_port
 

Detailed Description

Definitions for input handling on Windows.

Function Documentation

◆ 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.

◆ cancel_all_active_touches()

void platf::cancel_all_active_touches ( client_input_raw_t * raw)

Cancels all active touches.

Parameters
rawThe raw client-specific input context.

◆ ds4_update_ts_and_send()

void platf::ds4_update_ts_and_send ( vigem_t * vigem,
int nr )

Sends DS4 input with updated timestamps and repeats to keep timestamp updated.

Some applications require updated timestamps values to register DS4 input.

Parameters
vigemThe global ViGEm context object.
nrThe global gamepad index.

◆ 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);

◆ inject_synthetic_pointer_input()

bool platf::inject_synthetic_pointer_input ( input_raw_t * input,
HSYNTHETICPOINTERDEVICE device,
const POINTER_TYPE_INFO * pointerInfo,
UINT32 count )

Calls InjectSyntheticPointerInput() and switches input desktops if required.

Must only be called if InjectSyntheticPointerInput() is available.

Parameters
inputThe global input context.
deviceThe synthetic pointer device handle.
pointerInfoAn array of POINTER_TYPE_INFO structs.
countThe number of elements in pointerInfo.
Returns
true if input was successfully injected.

◆ 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.

◆ perform_touch_compaction()

void platf::perform_touch_compaction ( client_input_raw_t * raw)

Compacts the touch slots into a contiguous block and updates the active count.

Since this swaps entries around, all slot pointers/references are invalid after compaction.

Parameters
rawThe client-specific input context.

◆ pointer_by_id()

POINTER_TYPE_INFO * platf::pointer_by_id ( client_input_raw_t * raw,
uint32_t pointerId,
uint8_t eventType )

Gets a pointer slot by client-relative pointer ID, claiming a new one if necessary.

Parameters
rawThe raw client-specific input context.
pointerIdThe client's pointer ID.
eventTypeThe LI_TOUCH_EVENT value from the client.
Returns
A pointer to the slot entry.

◆ populate_common_pointer_info()

void platf::populate_common_pointer_info ( POINTER_INFO & pointerInfo,
const touch_port_t & touchPort,
uint8_t eventType,
float x,
float y )

Populate common POINTER_INFO members shared between pen and touch events.

Parameters
pointerInfoThe pointer info to populate.
touchPortThe current viewport for translating to screen coordinates.
eventTypeThe type of touch/pen event.
xThe normalized 0.0-1.0 X coordinate.
yThe normalized 0.0-1.0 Y coordinate.

◆ repeat_pen()

void platf::repeat_pen ( client_input_raw_t * raw)

Repeats the current pen state to avoid the interactions timing out.

Parameters
rawThe raw client-specific input context.

◆ repeat_touch()

void platf::repeat_touch ( client_input_raw_t * raw)

Repeats the current touch state to avoid the interactions timing out.

Parameters
rawThe raw client-specific input context.

◆ send_input()

void platf::send_input ( INPUT & i)

Calls SendInput() and switches input desktops if required.

Parameters
iThe INPUT struct to send.

◆ 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.

◆ 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.

Variable Documentation

◆ ds4_report_init_ex

constexpr DS4_REPORT_EX platf::ds4_report_init_ex
constexpr
Initial value:
= {
{{.bThumbLX = 0x80,
.bThumbLY = 0x80,
.bThumbRX = 0x80,
.bThumbRY = 0x80,
.wButtons = DS4_BUTTON_DPAD_NONE,
.bSpecial = 0,
.bTriggerL = 0,
.bTriggerR = 0,
.wTimestamp = 0,
.bBatteryLvl = 0xFF,
.wGyroX = 0,
.wGyroY = 0,
.wGyroZ = 0,
.wAccelX = 0,
.wAccelY = 0,
.wAccelZ = 0,
._bUnknown1 = {0x00, 0x00, 0x00, 0x00, 0x00},
.bBatteryLvlSpecial = 0x1A,
._bUnknown2 = {0x00, 0x00},
.bTouchPacketsN = 1,
.sCurrentTouch = ds4_touch_unused,
.sPreviousTouch = {ds4_touch_unused, ds4_touch_unused}}}
}

◆ ds4_touch_unused

constexpr DS4_TOUCH platf::ds4_touch_unused
constexpr
Initial value:
= {
.bPacketCounter = 0,
.bIsUpTrackingNum1 = 0x80,
.bTouchData1 = {0x00, 0x00, 0x00},
.bIsUpTrackingNum2 = 0x80,
.bTouchData2 = {0x00, 0x00, 0x00},
}

◆ target_touch_port

constexpr touch_port_t platf::target_touch_port
constexpr
Initial value:
{
0,
0,
65535,
65535
}