feat(input): implement multiseat support and virtual device naming (#4954)

This commit is contained in:
Willian Barreto
2026-05-05 19:12:16 -03:00
committed by GitHub
parent 3cb827790c
commit dd30d0555f
6 changed files with 97 additions and 12 deletions
+20 -4
View File
@@ -13,12 +13,28 @@
#include "src/config.h"
#include "src/logging.h"
#include "src/platform/common.h"
#include "src/platform/linux/input/inputtino_seat.h"
#include "src/utility.h"
using namespace std::literals;
namespace platf {
inline std::string inputtino_name_for_seat(std::string_view base_name) {
auto seat_id = inputtino_seat::get_target_seat();
if (seat_id.empty() || seat_id == "seat0") {
return std::string(base_name);
}
std::string name;
name.reserve(base_name.size() + seat_id.size() + 3);
name.append(base_name);
name.append(" (");
name.append(seat_id);
name.push_back(')');
return name;
}
using joypads_t = std::variant<inputtino::XboxOneJoypad, inputtino::SwitchJoypad, inputtino::PS5Joypad>;
struct joypad_state {
@@ -30,13 +46,13 @@ namespace platf {
struct input_raw_t {
input_raw_t():
mouse(inputtino::Mouse::create({
.name = "Mouse passthrough",
.name = inputtino_name_for_seat("Mouse passthrough"sv),
.vendor_id = 0xBEEF,
.product_id = 0xDEAD,
.version = 0x111,
})),
keyboard(inputtino::Keyboard::create({
.name = "Keyboard passthrough",
.name = inputtino_name_for_seat("Keyboard passthrough"sv),
.vendor_id = 0xBEEF,
.product_id = 0xDEAD,
.version = 0x111,
@@ -66,13 +82,13 @@ namespace platf {
struct client_input_raw_t: public client_input_t {
client_input_raw_t(input_t &input):
touch(inputtino::TouchScreen::create({
.name = "Touch passthrough",
.name = inputtino_name_for_seat("Touch passthrough"sv),
.vendor_id = 0xBEEF,
.product_id = 0xDEAD,
.version = 0x111,
})),
pen(inputtino::PenTablet::create({
.name = "Pen passthrough",
.name = inputtino_name_for_seat("Pen passthrough"sv),
.vendor_id = 0xBEEF,
.product_id = 0xDEAD,
.version = 0x111,
@@ -10,6 +10,7 @@
// local includes
#include "inputtino_common.h"
#include "inputtino_gamepad.h"
#include "inputtino_seat.h"
#include "src/config.h"
#include "src/logging.h"
#include "src/platform/common.h"
@@ -27,7 +28,7 @@ namespace platf::gamepad {
};
auto create_xbox_one() {
return inputtino::XboxOneJoypad::create({.name = "Sunshine X-Box One (virtual) pad",
return inputtino::XboxOneJoypad::create({.name = inputtino_name_for_seat("Sunshine X-Box One (virtual) pad"sv),
// https://github.com/torvalds/linux/blob/master/drivers/input/joystick/xpad.c#L147
.vendor_id = 0x045E,
.product_id = 0x02EA,
@@ -35,7 +36,7 @@ namespace platf::gamepad {
}
auto create_switch() {
return inputtino::SwitchJoypad::create({.name = "Sunshine Nintendo (virtual) pad",
return inputtino::SwitchJoypad::create({.name = inputtino_name_for_seat("Sunshine Nintendo (virtual) pad"sv),
// https://github.com/torvalds/linux/blob/master/drivers/hid/hid-ids.h#L981
.vendor_id = 0x057e,
.product_id = 0x2009,
@@ -50,7 +51,7 @@ namespace platf::gamepad {
device_mac = std::format("02:00:00:00:00:{:02x}", globalIndex);
}
return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111, .device_phys = device_mac, .device_uniq = device_mac});
return inputtino::PS5Joypad::create({.name = inputtino_name_for_seat("Sunshine PS5 (virtual) pad"sv), .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111, .device_phys = device_mac, .device_uniq = device_mac});
}
int alloc(input_raw_t *raw, const gamepad_id_t &id, const gamepad_arrival_t &metadata, feedback_queue_t feedback_queue) {
@@ -0,0 +1,23 @@
/**
* @file src/platform/linux/input/inputtino_seat.cpp
* @brief Implementation for multi-seat naming (udev-only).
*/
// standard includes
#include <cstdlib>
// local includes
#include "inputtino_seat.h"
namespace platf::inputtino_seat {
std::string get_target_seat() {
if (const char *seat = std::getenv("XDG_SEAT")) {
if (seat[0] != '\0') {
return seat;
}
}
return {};
}
} // namespace platf::inputtino_seat
+17
View File
@@ -0,0 +1,17 @@
/**
* @file src/platform/linux/input/inputtino_seat.h
* @brief Helpers for multi-seat naming (udev-only).
*/
#pragma once
#include <string>
namespace platf::inputtino_seat {
/**
* Determine the target seat for the current Sunshine instance.
* Returns empty string if no seat could be determined.
*/
std::string get_target_seat();
} // namespace platf::inputtino_seat