Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mouse fixes #121

Merged
merged 4 commits into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/linux-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
run: |
git clone https://github.com/games-on-whales/gst-wayland-display
cd gst-wayland-display
git checkout 48382dc
git checkout a31f5a0
cargo install cargo-c
cargo cinstall -p c-bindings --prefix=/usr/local

Expand Down Expand Up @@ -114,7 +114,7 @@ jobs:
run: |
git clone https://github.com/games-on-whales/gst-wayland-display
cd gst-wayland-display
git checkout 48382dc
git checkout a31f5a0
cargo install cargo-c
cargo cinstall -p c-bindings --prefix=/usr/local --destdir=${{runner.workspace}}

Expand Down
2 changes: 1 addition & 1 deletion docker/wolf.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ RUN <<_GST_WAYLAND_DISPLAY

git clone https://github.com/games-on-whales/gst-wayland-display
cd gst-wayland-display
git checkout 48382dc
git checkout a31f5a0
cargo install cargo-c
cargo cinstall -p c-bindings --prefix=/usr/local --libdir=/usr/local/lib/
_GST_WAYLAND_DISPLAY
Expand Down
58 changes: 48 additions & 10 deletions docs/modules/dev/partials/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -399,15 +399,6 @@
"id": {
"type": "string"
},
"joypad_type": {
"type": "string",
"enum": [
"XBOX",
"PS",
"NINTENDO",
"AUTO"
]
},
"opus_gst_pipeline": {
"type": "string"
},
Expand All @@ -427,6 +418,9 @@
}
]
},
"start_audio_server": {
"type": "boolean"
},
"start_virtual_compositor": {
"type": "boolean"
},
Expand All @@ -442,10 +436,10 @@
"h264_gst_pipeline",
"hevc_gst_pipeline",
"id",
"joypad_type",
"opus_gst_pipeline",
"render_node",
"runner",
"start_audio_server",
"start_virtual_compositor",
"support_hdr",
"title"
Expand All @@ -466,6 +460,9 @@
"client_ip": {
"type": "string"
},
"client_settings": {
"$ref": "#/components/schemas/wolf__config__ClientSettings"
},
"video_height": {
"type": "integer"
},
Expand All @@ -481,6 +478,7 @@
"audio_channel_count",
"client_id",
"client_ip",
"client_settings",
"video_height",
"video_refresh_rate",
"video_width"
Expand Down Expand Up @@ -772,6 +770,46 @@
"ports",
"type"
]
},
"wolf__config__ClientSettings": {
"type": "object",
"properties": {
"controllers_override": {
"type": "array",
"items": {
"type": "string",
"enum": [
"XBOX",
"PS",
"NINTENDO",
"AUTO"
]
}
},
"h_scroll_acceleration": {
"type": "number"
},
"mouse_acceleration": {
"type": "number"
},
"run_gid": {
"type": "integer"
},
"run_uid": {
"type": "integer"
},
"v_scroll_acceleration": {
"type": "number"
}
},
"required": [
"controllers_override",
"h_scroll_acceleration",
"mouse_acceleration",
"run_gid",
"run_uid",
"v_scroll_acceleration"
]
}
}
}
Expand Down
27 changes: 23 additions & 4 deletions docs/modules/user/pages/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,17 @@ See more examples in the xref:gstreamer.adoc[] page.
=== Override the default joypad mapping

By default, Wolf will try to match the joypad type that Moonlight sends with the correct mapping.
It is possible to override this behaviour by setting the `joypad_mapping` property in the `apps` entry; example:
It is possible to override this behaviour for each Moonlight paired client, ex:

[source,toml]
....
[[apps]]
title = "Test ball"
joypad_type = "xbox" # Force the joypad to always be xbox
[[paired_clients]]
# client_cert = ...
[paired_clients.settings]
controllers_override = [
"PS", # First controller will be forced to be PS
"XBOX" # Second controller will be forced to be XBOX
]
....

The available joypad types are:
Expand All @@ -211,6 +215,21 @@ The available joypad types are:
* `nintendo`
* `ps`

=== Input mouse overrides

You can increase and decrease the mouse acceleration and scroll speed for each paired client, ex:

[source,toml]
....
[[paired_clients]]
# client_cert = ...
[paired_clients.settings]
# Values above 1.0 will make it faster, between 0.0 and 1.0 will make it slower
mouse_acceleration = 1.0
v_scroll_acceleration = 1.0
h_scroll_acceleration = 1.0
....


[#_app_runner]
==== App Runner
Expand Down
2 changes: 1 addition & 1 deletion src/moonlight-server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ target_link_libraries(wolf_runner PUBLIC tomlplusplus::tomlplusplus)
FetchContent_Declare(
reflect-cpp
GIT_REPOSITORY https://github.com/getml/reflect-cpp
GIT_TAG v0.14.1
GIT_TAG 54c2a84
)
set(REFLECTCPP_BSON OFF)
set(REFLECTCPP_CBOR OFF)
Expand Down
1 change: 0 additions & 1 deletion src/moonlight-server/api/endpoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ void UnixSocketServer::endpoint_AddApp(const HTTPRequest &req, std::shared_ptr<U
.opus_gst_pipeline = app.opus_gst_pipeline,
.start_virtual_compositor = app.start_virtual_compositor,
.runner = runner,
.joypad_type = state::get_controller_type(app.joypad_type),
});
});
auto res = GenericSuccessResponse{.success = true};
Expand Down
68 changes: 48 additions & 20 deletions src/moonlight-server/control/input_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ using namespace moonlight::control;
std::shared_ptr<events::JoypadTypes> create_new_joypad(const events::StreamSession &session,
const immer::atom<enet_clients_map> &connected_clients,
int controller_number,
CONTROLLER_TYPE type,
CONTROLLER_TYPE requested_type,
uint8_t capabilities) {

auto on_rumble_fn = ([clients = &connected_clients,
Expand Down Expand Up @@ -49,11 +49,28 @@ std::shared_ptr<events::JoypadTypes> create_new_joypad(const events::StreamSessi
});

std::shared_ptr<events::JoypadTypes> new_pad;
CONTROLLER_TYPE final_type = session.app->joypad_type == AUTO ? type : session.app->joypad_type;
auto controllers_override = session.client_settings->controllers_override;
auto final_type = controllers_override.size() > controller_number ? controllers_override[controller_number]
: wolf::config::ControllerType::AUTO;
if (final_type == wolf::config::ControllerType::AUTO) {
switch (requested_type) {
case XBOX:
final_type = wolf::config::ControllerType::XBOX;
break;
case PS:
final_type = wolf::config::ControllerType::PS;
break;
case NINTENDO:
final_type = wolf::config::ControllerType::NINTENDO;
break;
default:
final_type = wolf::config::ControllerType::AUTO;
break;
}
}
switch (final_type) {
case UNKNOWN:
case AUTO:
case XBOX: {
case wolf::config::ControllerType::AUTO:
case wolf::config::ControllerType::XBOX: {
logs::log(logs::info, "Creating Xbox joypad for controller {}", controller_number);
auto result =
XboxOneJoypad::create({.name = "Wolf X-Box One (virtual) pad",
Expand All @@ -70,7 +87,7 @@ std::shared_ptr<events::JoypadTypes> create_new_joypad(const events::StreamSessi
}
break;
}
case PS: {
case wolf::config::ControllerType::PS: {
logs::log(logs::info, "Creating PS joypad for controller {}", controller_number);
auto result = PS5Joypad::create(
{.name = "Wolf DualSense (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111});
Expand Down Expand Up @@ -99,7 +116,7 @@ std::shared_ptr<events::JoypadTypes> create_new_joypad(const events::StreamSessi
}
break;
}
case NINTENDO:
case wolf::config::ControllerType::NINTENDO:
logs::log(logs::info, "Creating Nintendo joypad for controller {}", controller_number);
auto result = SwitchJoypad::create({.name = "Wolf Nintendo (virtual) pad",
// https://github.com/torvalds/linux/blob/master/drivers/hid/hid-ids.h#L981
Expand All @@ -116,7 +133,7 @@ std::shared_ptr<events::JoypadTypes> create_new_joypad(const events::StreamSessi
break;
}

if (capabilities & ACCELEROMETER && final_type == PS) {
if (capabilities & ACCELEROMETER && final_type == wolf::config::ControllerType::PS) {
// Request acceleromenter events from the client at 100 Hz
logs::log(logs::info, "Requesting accelerometer events for controller {}", controller_number);
auto accelerometer_pkt = ControlMotionEventPacket{
Expand All @@ -128,7 +145,7 @@ std::shared_ptr<events::JoypadTypes> create_new_joypad(const events::StreamSessi
encrypt_and_send(plaintext, session.aes_key, connected_clients, session.session_id);
}

if (capabilities & GYRO && final_type == PS) {
if (capabilities & GYRO && final_type == wolf::config::ControllerType::PS) {
// Request gyroscope events from the client at 100 Hz
logs::log(logs::info, "Requesting gyroscope events for controller {}", controller_number);
auto gyro_pkt = ControlMotionEventPacket{
Expand All @@ -141,7 +158,10 @@ std::shared_ptr<events::JoypadTypes> create_new_joypad(const events::StreamSessi
}

session.joypads->update([&](events::JoypadList joypads) {
logs::log(logs::debug, "[INPUT] Sending PlugDeviceEvent for joypad {} of type: {}", controller_number, (int)type);
logs::log(logs::debug,
"[INPUT] Sending PlugDeviceEvent for joypad {} of type: {}",
controller_number,
(int)final_type);

events::PlugDeviceEvent unplug_ev{.session_id = session.session_id};
std::visit(
Expand Down Expand Up @@ -216,8 +236,9 @@ static inline float deg2rad(float degree) {

void mouse_move_rel(const MOUSE_MOVE_REL_PACKET &pkt, events::StreamSession &session) {
if (session.mouse->has_value()) {
short delta_x = boost::endian::big_to_native(pkt.delta_x);
short delta_y = boost::endian::big_to_native(pkt.delta_y);
auto pointer_acceleration = session.client_settings->mouse_acceleration;
short delta_x = boost::endian::big_to_native(pkt.delta_x) * pointer_acceleration;
short delta_y = boost::endian::big_to_native(pkt.delta_y) * pointer_acceleration;
std::visit([delta_x, delta_y](auto &mouse) { mouse.move(delta_x, delta_y); }, session.mouse->value());
} else {
logs::log(logs::warning, "Received MOUSE_MOVE_REL_PACKET but no mouse device is present");
Expand All @@ -226,8 +247,9 @@ void mouse_move_rel(const MOUSE_MOVE_REL_PACKET &pkt, events::StreamSession &ses

void mouse_move_abs(const MOUSE_MOVE_ABS_PACKET &pkt, events::StreamSession &session) {
if (session.mouse->has_value()) {
float x = boost::endian::big_to_native(pkt.x);
float y = boost::endian::big_to_native(pkt.y);
auto pointer_acceleration = session.client_settings->mouse_acceleration;
float x = boost::endian::big_to_native(pkt.x) * pointer_acceleration;
float y = boost::endian::big_to_native(pkt.y) * pointer_acceleration;
float width = boost::endian::big_to_native(pkt.width);
float height = boost::endian::big_to_native(pkt.height);
std::visit([x, y, width, height](auto &mouse) { mouse.move_abs(x, y, width, height); }, session.mouse->value());
Expand Down Expand Up @@ -277,19 +299,25 @@ void mouse_button(const MOUSE_BUTTON_PACKET &pkt, events::StreamSession &session

void mouse_scroll(const MOUSE_SCROLL_PACKET &pkt, events::StreamSession &session) {
if (session.mouse->has_value()) {
std::visit([scroll_amount = boost::endian::big_to_native(pkt.scroll_amt1)](
auto &mouse) { mouse.vertical_scroll(scroll_amount); },
session.mouse->value());
std::visit(
[session, scroll_amount = boost::endian::big_to_native(pkt.scroll_amt1)](auto &mouse) {
auto scroll_acceleration = session.client_settings->v_scroll_acceleration;
mouse.vertical_scroll(scroll_amount * scroll_acceleration);
},
session.mouse->value());
} else {
logs::log(logs::warning, "Received MOUSE_SCROLL_PACKET but no mouse device is present");
}
}

void mouse_h_scroll(const MOUSE_HSCROLL_PACKET &pkt, events::StreamSession &session) {
if (session.mouse->has_value()) {
std::visit([scroll_amount = boost::endian::big_to_native(pkt.scroll_amount)](
auto &mouse) { mouse.horizontal_scroll(scroll_amount); },
session.mouse->value());
std::visit(
[session, scroll_amount = boost::endian::big_to_native(pkt.scroll_amount)](auto &mouse) {
auto scroll_acceleration = session.client_settings->h_scroll_acceleration;
mouse.horizontal_scroll(scroll_amount * scroll_acceleration);
},
session.mouse->value());
} else {
logs::log(logs::warning, "Received MOUSE_HSCROLL_PACKET but no mouse device is present");
}
Expand Down
2 changes: 1 addition & 1 deletion src/moonlight-server/events/events.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ struct App {
bool start_virtual_compositor;
bool start_audio_server;
std::shared_ptr<Runner> runner;
moonlight::control::pkts::CONTROLLER_TYPE joypad_type;
};

using MouseTypes = std::variant<input::Mouse, virtual_display::WaylandMouse>;
Expand Down Expand Up @@ -219,6 +218,7 @@ struct StreamSession {
int audio_channel_count;

std::shared_ptr<EventBusType> event_bus;
immer::box<wolf::config::ClientSettings> client_settings;
std::shared_ptr<App> app;
std::string app_state_folder;

Expand Down
Loading
Loading