Add initial score-based dock detection
This is early development & untested code specifically targeting the steam deck for now until further finalised
This commit is contained in:
parent
470f4a318f
commit
545815fd6d
8 changed files with 336 additions and 150 deletions
|
@ -48,6 +48,8 @@ namespace HarmonyLinkLib
|
||||||
|
|
||||||
extern "C" HARMONYLINKLIB_API bool get_is_linux();
|
extern "C" HARMONYLINKLIB_API bool get_is_linux();
|
||||||
|
|
||||||
|
extern "C" HARMONYLINKLIB_API bool get_is_docked();
|
||||||
|
|
||||||
extern "C" HARMONYLINKLIB_API FCPUInfo* get_cpu_info();
|
extern "C" HARMONYLINKLIB_API FCPUInfo* get_cpu_info();
|
||||||
|
|
||||||
extern "C" HARMONYLINKLIB_API FDevice* get_device_info();
|
extern "C" HARMONYLINKLIB_API FDevice* get_device_info();
|
||||||
|
|
|
@ -43,6 +43,17 @@ namespace HarmonyLinkLib
|
||||||
return PlatformUtilities->is_linux();
|
return PlatformUtilities->is_linux();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get_is_docked()
|
||||||
|
{
|
||||||
|
if (!PlatformUtilities)
|
||||||
|
{
|
||||||
|
std::wcout << "Failed to get platform utilities!\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PlatformUtilities->is_docked();
|
||||||
|
}
|
||||||
|
|
||||||
FCPUInfo* get_cpu_info()
|
FCPUInfo* get_cpu_info()
|
||||||
{
|
{
|
||||||
if (!PlatformUtilities)
|
if (!PlatformUtilities)
|
||||||
|
|
|
@ -31,43 +31,98 @@ namespace HarmonyLinkLib
|
||||||
{
|
{
|
||||||
static std::shared_ptr<IPlatformUtilities> INSTANCE = nullptr;
|
static std::shared_ptr<IPlatformUtilities> INSTANCE = nullptr;
|
||||||
|
|
||||||
std::shared_ptr<IPlatformUtilities>& IPlatformUtilities::GetInstance()
|
std::shared_ptr<IPlatformUtilities>& IPlatformUtilities::GetInstance()
|
||||||
{
|
{
|
||||||
if (!INSTANCE)
|
if (!INSTANCE)
|
||||||
{
|
{
|
||||||
#if BUILD_WINDOWS
|
#if BUILD_WINDOWS
|
||||||
INSTANCE = std::make_shared<WindowsUtilities>();
|
INSTANCE = std::make_shared<WindowsUtilities>();
|
||||||
#elif BUILD_LINUX
|
#elif BUILD_LINUX
|
||||||
INSTANCE = std::make_shared<LinuxUtilities>();
|
INSTANCE = std::make_shared<LinuxUtilities>();
|
||||||
#elif BUILD_MAC
|
#elif BUILD_MAC
|
||||||
INSTANCE = std::make_shared<MacUtilities>();
|
INSTANCE = std::make_shared<MacUtilities>();
|
||||||
#elif BUILD_UNIX
|
#elif BUILD_UNIX
|
||||||
INSTANCE = std::make_shared<UnixUtilities>();
|
INSTANCE = std::make_shared<UnixUtilities>();
|
||||||
// ... other platform checks
|
// ... other platform checks
|
||||||
#else
|
#else
|
||||||
std::wcout << "Platform is not supported.\n"
|
std::wcout << "Platform is not supported.\n"
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IPlatformUtilities::is_running_under_wine()
|
bool IPlatformUtilities::is_running_under_wine()
|
||||||
{
|
{
|
||||||
return WineUtilities::is_wine_present();
|
return WineUtilities::is_wine_present();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IPlatformUtilities::is_linux()
|
bool IPlatformUtilities::is_linux()
|
||||||
{
|
{
|
||||||
#ifdef BUILD_LINUX
|
#ifdef BUILD_LINUX
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
return is_running_under_wine();
|
return is_running_under_wine();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FDevice> IPlatformUtilities::get_device()
|
bool IPlatformUtilities::is_steam_deck()
|
||||||
{
|
{
|
||||||
|
const std::shared_ptr<FDevice> device = get_device();
|
||||||
|
|
||||||
|
return device && device->device == EDevice::STEAM_DECK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPlatformUtilities::is_docked()
|
||||||
|
{
|
||||||
|
static constexpr uint8_t CHARGING_SCORE = 3;
|
||||||
|
static constexpr uint8_t EXTERNAL_MONITOR_SCORE = 3;
|
||||||
|
static constexpr uint8_t KEYBOARD_DETECTION_SCORE = 2;
|
||||||
|
static constexpr uint8_t CONTROLLER_DETECTION_SCORE = 2;
|
||||||
|
static constexpr uint8_t FINAL_TARGET_DETECTION_SCORE = 6;
|
||||||
|
|
||||||
|
|
||||||
|
const std::shared_ptr<FDevice> device = get_device();
|
||||||
|
|
||||||
|
if (!device)
|
||||||
|
{
|
||||||
|
std::wcout << "Error: failed to get device.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->device != EDevice::STEAM_DECK)
|
||||||
|
{
|
||||||
|
std::wcout << "Error: Dock detection is currently only supported on Steam Decks.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t score = 0;
|
||||||
|
|
||||||
|
if (is_charging())
|
||||||
|
{
|
||||||
|
score += CHARGING_SCORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_is_external_monitor_connected())
|
||||||
|
{
|
||||||
|
score += EXTERNAL_MONITOR_SCORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_mouse_keyboard_detected())
|
||||||
|
{
|
||||||
|
score += KEYBOARD_DETECTION_SCORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_external_controller_detected())
|
||||||
|
{
|
||||||
|
score += CONTROLLER_DETECTION_SCORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return score >= FINAL_TARGET_DETECTION_SCORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<FDevice> IPlatformUtilities::get_device()
|
||||||
|
{
|
||||||
FDevice new_device;
|
FDevice new_device;
|
||||||
|
|
||||||
if (is_linux())
|
if (is_linux())
|
||||||
|
@ -90,14 +145,14 @@ std::shared_ptr<FDevice> IPlatformUtilities::get_device()
|
||||||
new_device.device = EDevice::LAPTOP;
|
new_device.device = EDevice::LAPTOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_steam_deck(new_device)) {
|
if (is_steam_deck_detected(new_device)) {
|
||||||
new_device.device = EDevice::STEAM_DECK;
|
new_device.device = EDevice::STEAM_DECK;
|
||||||
}
|
}
|
||||||
return std::make_shared<FDevice>(new_device);
|
return std::make_shared<FDevice>(new_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to check if the device is a Steam Deck
|
// Helper function to check if the device is a Steam Deck
|
||||||
bool IPlatformUtilities::is_steam_deck(const FDevice& device) {
|
bool IPlatformUtilities::is_steam_deck_detected(const FDevice& device) {
|
||||||
|
|
||||||
// Check if the device is already identified as a Steam Deck
|
// Check if the device is already identified as a Steam Deck
|
||||||
if (device.device == EDevice::STEAM_DECK) {
|
if (device.device == EDevice::STEAM_DECK) {
|
||||||
|
@ -132,5 +187,17 @@ bool IPlatformUtilities::is_steam_deck(const FDevice& device) {
|
||||||
wprintf(L"Device is not a Steam Deck.\n");
|
wprintf(L"Device is not a Steam Deck.\n");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IPlatformUtilities::is_connected_to_ac()
|
||||||
|
{
|
||||||
|
const std::shared_ptr<FBattery> battery = get_battery_status();
|
||||||
|
return battery && battery->is_connected_to_ac;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPlatformUtilities::is_charging()
|
||||||
|
{
|
||||||
|
const std::shared_ptr<FBattery> battery = get_battery_status();
|
||||||
|
return battery && battery->has_battery && battery->is_connected_to_ac;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,13 +35,22 @@ namespace HarmonyLinkLib
|
||||||
// General OS-level functions
|
// General OS-level functions
|
||||||
virtual bool is_running_under_wine();
|
virtual bool is_running_under_wine();
|
||||||
virtual bool is_linux();
|
virtual bool is_linux();
|
||||||
|
virtual bool is_steam_deck();
|
||||||
|
virtual bool is_docked();
|
||||||
|
|
||||||
virtual std::shared_ptr<FDevice> get_device();
|
virtual std::shared_ptr<FDevice> get_device();
|
||||||
virtual std::shared_ptr<FCPUInfo> get_cpu_info() = 0;
|
virtual std::shared_ptr<FCPUInfo> get_cpu_info() = 0;
|
||||||
virtual std::shared_ptr<FBattery> get_battery_status() = 0;
|
virtual std::shared_ptr<FBattery> get_battery_status() = 0;
|
||||||
virtual std::shared_ptr<FOSVerInfo> get_os_version() = 0;
|
virtual std::shared_ptr<FOSVerInfo> get_os_version() = 0;
|
||||||
|
virtual bool get_is_external_monitor_connected() = 0;
|
||||||
|
virtual bool get_mouse_keyboard_detected() = 0;
|
||||||
|
virtual bool get_external_controller_detected() = 0;
|
||||||
|
//virtual bool get_is_ethernet_connected() = 0;
|
||||||
|
//virtual bool get_is_external_input_detected() = 0;
|
||||||
|
|
||||||
bool is_steam_deck(const FDevice& device);
|
bool is_steam_deck_detected(const FDevice& device);
|
||||||
|
bool is_connected_to_ac();
|
||||||
|
bool is_charging();
|
||||||
|
|
||||||
// Add more virtual functions for other OS interactions here
|
// Add more virtual functions for other OS interactions here
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,21 +18,43 @@ namespace HarmonyLinkLib
|
||||||
{
|
{
|
||||||
bool UnixUtilities::is_running_under_wine()
|
bool UnixUtilities::is_running_under_wine()
|
||||||
{
|
{
|
||||||
|
std::wcout << "This feature is not supported on unix systems yet.\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FCPUInfo> UnixUtilities::get_cpu_info()
|
std::shared_ptr<FCPUInfo> UnixUtilities::get_cpu_info()
|
||||||
{
|
{
|
||||||
|
std::wcout << "This feature is not supported on unix systems yet.\n";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FBattery> UnixUtilities::get_battery_status()
|
std::shared_ptr<FBattery> UnixUtilities::get_battery_status()
|
||||||
{
|
{
|
||||||
|
std::wcout << "This feature is not supported on unix systems yet.\n";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FOSVerInfo> UnixUtilities::get_os_version()
|
std::shared_ptr<FOSVerInfo> UnixUtilities::get_os_version()
|
||||||
{
|
{
|
||||||
|
std::wcout << "This feature is not supported on unix systems yet.\n";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UnixUtilities::get_is_external_monitor_connected()
|
||||||
|
{
|
||||||
|
std::wcout << "This feature is not supported on unix-based systems yet.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnixUtilities::get_mouse_keyboard_detected()
|
||||||
|
{
|
||||||
|
std::wcout << "This feature is not supported on unix-based systems yet.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnixUtilities::get_external_controller_detected()
|
||||||
|
{
|
||||||
|
std::wcout << "This feature is not supported on unix-based systems yet.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -17,6 +17,8 @@
|
||||||
#include "Platform/IPlatformUtilities.h"
|
#include "Platform/IPlatformUtilities.h"
|
||||||
namespace HarmonyLinkLib
|
namespace HarmonyLinkLib
|
||||||
{
|
{
|
||||||
|
// This is more of a "catch all" for all unix-based systems
|
||||||
|
// that don't have their own implementations.
|
||||||
class UnixUtilities : public IPlatformUtilities {
|
class UnixUtilities : public IPlatformUtilities {
|
||||||
public:
|
public:
|
||||||
bool is_running_under_wine() override;
|
bool is_running_under_wine() override;
|
||||||
|
@ -25,6 +27,12 @@ namespace HarmonyLinkLib
|
||||||
std::shared_ptr<FBattery> get_battery_status() override;
|
std::shared_ptr<FBattery> get_battery_status() override;
|
||||||
std::shared_ptr<FOSVerInfo> get_os_version() override;
|
std::shared_ptr<FOSVerInfo> get_os_version() override;
|
||||||
|
|
||||||
|
bool get_is_external_monitor_connected() override;
|
||||||
|
|
||||||
|
bool get_mouse_keyboard_detected() override;
|
||||||
|
|
||||||
|
bool get_external_controller_detected() override;
|
||||||
|
|
||||||
// Implementation for other Unix/Linux-specific functions
|
// Implementation for other Unix/Linux-specific functions
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,15 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#include <XInput.h>
|
||||||
|
#pragma comment(lib, "XInput.lib")
|
||||||
|
|
||||||
#include "Platform/WineUtilities.h"
|
#include "Platform/WineUtilities.h"
|
||||||
|
|
||||||
namespace HarmonyLinkLib
|
namespace HarmonyLinkLib
|
||||||
{
|
{
|
||||||
std::shared_ptr<FBattery> WindowsUtilities::get_battery_status()
|
std::shared_ptr<FBattery> WindowsUtilities::get_battery_status()
|
||||||
{
|
{
|
||||||
if (is_linux())
|
if (is_linux())
|
||||||
{
|
{
|
||||||
return WineUtilities::get_battery_status();
|
return WineUtilities::get_battery_status();
|
||||||
|
@ -39,20 +42,20 @@ namespace HarmonyLinkLib
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_shared<FBattery>(result);
|
return std::make_shared<FBattery>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FCPUInfo> WindowsUtilities::get_cpu_info()
|
std::shared_ptr<FCPUInfo> WindowsUtilities::get_cpu_info()
|
||||||
{
|
{
|
||||||
if (is_linux())
|
if (is_linux())
|
||||||
{
|
{
|
||||||
return WineUtilities::get_cpu_info();
|
return WineUtilities::get_cpu_info();
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FOSVerInfo> WindowsUtilities::get_os_version()
|
std::shared_ptr<FOSVerInfo> WindowsUtilities::get_os_version()
|
||||||
{
|
{
|
||||||
if (is_linux())
|
if (is_linux())
|
||||||
{
|
{
|
||||||
return WineUtilities::get_linux_info();
|
return WineUtilities::get_linux_info();
|
||||||
|
@ -91,5 +94,63 @@ std::shared_ptr<FOSVerInfo> WindowsUtilities::get_os_version()
|
||||||
os_version.version = os_version_info.dwBuildNumber; // Build number as the version
|
os_version.version = os_version_info.dwBuildNumber; // Build number as the version
|
||||||
|
|
||||||
return std::make_shared<FOSVerInfo>(os_version);
|
return std::make_shared<FOSVerInfo>(os_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WindowsUtilities::get_is_external_monitor_connected()
|
||||||
|
{
|
||||||
|
// SM_CMONITORS returns the count of all display monitors.
|
||||||
|
const int monitorCount = GetSystemMetrics(SM_CMONITORS);
|
||||||
|
|
||||||
|
// More than one monitor implies an external monitor is connected.
|
||||||
|
return monitorCount > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowsUtilities::get_mouse_keyboard_detected()
|
||||||
|
{
|
||||||
|
UINT n_devices;
|
||||||
|
GetRawInputDeviceList(nullptr, &n_devices, sizeof(RAWINPUTDEVICELIST));
|
||||||
|
|
||||||
|
if (n_devices > 0) {
|
||||||
|
bool mouse_detected = false;
|
||||||
|
bool keyboard_detected = false;
|
||||||
|
|
||||||
|
std::vector<RAWINPUTDEVICELIST> devices(n_devices);
|
||||||
|
GetRawInputDeviceList(devices.data(), &n_devices, sizeof(RAWINPUTDEVICELIST));
|
||||||
|
|
||||||
|
for (const auto& device : devices) {
|
||||||
|
switch (device.dwType)
|
||||||
|
{
|
||||||
|
case RIM_TYPEMOUSE:
|
||||||
|
mouse_detected = true;
|
||||||
|
break;
|
||||||
|
case RIM_TYPEKEYBOARD:
|
||||||
|
keyboard_detected = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mouse_detected && keyboard_detected;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowsUtilities::get_external_controller_detected()
|
||||||
|
{
|
||||||
|
static_assert(XUSER_MAX_COUNT <= UINT8_MAX, "XUSER_MAX_COUNT exceeds uint8_t size");
|
||||||
|
|
||||||
|
uint8_t connectedGamepads = 0;
|
||||||
|
|
||||||
|
for (DWORD i = 0; i < XUSER_MAX_COUNT; ++i) {
|
||||||
|
XINPUT_STATE state;
|
||||||
|
ZeroMemory(&state, sizeof(XINPUT_STATE));
|
||||||
|
|
||||||
|
if (XInputGetState(i, &state) == ERROR_SUCCESS) {
|
||||||
|
connectedGamepads++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return connectedGamepads > 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,5 +26,11 @@ namespace HarmonyLinkLib
|
||||||
std::shared_ptr<FCPUInfo> get_cpu_info() override;
|
std::shared_ptr<FCPUInfo> get_cpu_info() override;
|
||||||
|
|
||||||
std::shared_ptr<FOSVerInfo> get_os_version() override;
|
std::shared_ptr<FOSVerInfo> get_os_version() override;
|
||||||
|
|
||||||
|
bool get_is_external_monitor_connected() override;
|
||||||
|
|
||||||
|
bool get_mouse_keyboard_detected() override;
|
||||||
|
|
||||||
|
bool get_external_controller_detected() override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue