From 575183d6dcd8da9b10ee41e47be4b7d4f8631783 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Tue, 16 Jan 2024 12:17:18 -0600 Subject: service: hid: Fully implement touch resource --- src/core/hle/service/hid/hid.cpp | 5 +- src/core/hle/service/hid/hid_debug_server.cpp | 196 +++++++++++++++++++-- src/core/hle/service/hid/hid_debug_server.h | 15 +- src/core/hle/service/hid/hid_server.cpp | 24 ++- src/core/hle/service/hid/hid_system_server.cpp | 64 ++++++- src/core/hle/service/hid/hid_system_server.h | 3 + .../service/set/setting_formats/system_settings.h | 4 +- .../hle/service/set/system_settings_server.cpp | 37 +++- src/core/hle/service/set/system_settings_server.h | 4 + 9 files changed, 318 insertions(+), 34 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 5b28be577..b60fb9139 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -18,9 +18,10 @@ namespace Service::HID { void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); - std::shared_ptr resource_manager = std::make_shared(system); std::shared_ptr firmware_settings = std::make_shared(system); + std::shared_ptr resource_manager = + std::make_shared(system, firmware_settings); // TODO: Remove this hack when am is emulated properly. resource_manager->Initialize(); @@ -31,7 +32,7 @@ void LoopProcess(Core::System& system) { server_manager->RegisterNamedService( "hid", std::make_shared(system, resource_manager, firmware_settings)); server_manager->RegisterNamedService( - "hid:dbg", std::make_shared(system, resource_manager)); + "hid:dbg", std::make_shared(system, resource_manager, firmware_settings)); server_manager->RegisterNamedService( "hid:sys", std::make_shared(system, resource_manager, firmware_settings)); diff --git a/src/core/hle/service/hid/hid_debug_server.cpp b/src/core/hle/service/hid/hid_debug_server.cpp index f2a767d37..610af34dd 100644 --- a/src/core/hle/service/hid/hid_debug_server.cpp +++ b/src/core/hle/service/hid/hid_debug_server.cpp @@ -1,27 +1,37 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +#include + #include "core/hle/service/hid/hid_debug_server.h" #include "core/hle/service/ipc_helpers.h" +#include "hid_core/hid_types.h" #include "hid_core/resource_manager.h" +#include "hid_core/resources/hid_firmware_settings.h" + +#include "hid_core/resources/touch_screen/gesture.h" +#include "hid_core/resources/touch_screen/touch_screen.h" +#include "hid_core/resources/touch_screen/touch_types.h" namespace Service::HID { -IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr resource) - : ServiceFramework{system_, "hid:dbg"}, resource_manager{resource} { +IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr resource, + std::shared_ptr settings) + : ServiceFramework{system_, "hid:dbg"}, resource_manager{resource}, firmware_settings{ + settings} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "DeactivateDebugPad"}, {1, nullptr, "SetDebugPadAutoPilotState"}, {2, nullptr, "UnsetDebugPadAutoPilotState"}, - {10, nullptr, "DeactivateTouchScreen"}, - {11, nullptr, "SetTouchScreenAutoPilotState"}, - {12, nullptr, "UnsetTouchScreenAutoPilotState"}, - {13, nullptr, "GetTouchScreenConfiguration"}, - {14, nullptr, "ProcessTouchScreenAutoTune"}, - {15, nullptr, "ForceStopTouchScreenManagement"}, - {16, nullptr, "ForceRestartTouchScreenManagement"}, - {17, nullptr, "IsTouchScreenManaged"}, + {10, &IHidDebugServer::DeactivateTouchScreen, "DeactivateTouchScreen"}, + {11, &IHidDebugServer::SetTouchScreenAutoPilotState, "SetTouchScreenAutoPilotState"}, + {12, &IHidDebugServer::UnsetTouchScreenAutoPilotState, "UnsetTouchScreenAutoPilotState"}, + {13, &IHidDebugServer::GetTouchScreenConfiguration, "GetTouchScreenConfiguration"}, + {14, &IHidDebugServer::ProcessTouchScreenAutoTune, "ProcessTouchScreenAutoTune"}, + {15, &IHidDebugServer::ForceStopTouchScreenManagement, "ForceStopTouchScreenManagement"}, + {16, &IHidDebugServer::ForceRestartTouchScreenManagement, "ForceRestartTouchScreenManagement"}, + {17, &IHidDebugServer::IsTouchScreenManaged, "IsTouchScreenManaged"}, {20, nullptr, "DeactivateMouse"}, {21, nullptr, "SetMouseAutoPilotState"}, {22, nullptr, "UnsetMouseAutoPilotState"}, @@ -37,7 +47,7 @@ IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptrIsDeviceManaged()) { + result = GetResourceManager()->GetTouchScreen()->Deactivate(); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IHidDebugServer::SetTouchScreenAutoPilotState(HLERequestContext& ctx) { + AutoPilotState auto_pilot{}; + auto_pilot.count = ctx.GetReadBufferNumElements(); + const auto buffer = ctx.ReadBuffer(); + + auto_pilot.count = std::min(auto_pilot.count, static_cast(auto_pilot.state.size())); + memcpy(auto_pilot.state.data(), buffer.data(), auto_pilot.count * sizeof(TouchState)); + + LOG_INFO(Service_HID, "called, auto_pilot_count={}", auto_pilot.count); + + const Result result = + GetResourceManager()->GetTouchScreen()->SetTouchScreenAutoPilotState(auto_pilot); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IHidDebugServer::UnsetTouchScreenAutoPilotState(HLERequestContext& ctx) { + LOG_INFO(Service_HID, "called"); + + const Result result = GetResourceManager()->GetTouchScreen()->UnsetTouchScreenAutoPilotState(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IHidDebugServer::GetTouchScreenConfiguration(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop()}; + + LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + + Core::HID::TouchScreenConfigurationForNx touchscreen_config{}; + const Result result = GetResourceManager()->GetTouchScreen()->GetTouchScreenConfiguration( + touchscreen_config, applet_resource_user_id); + + if (touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Heat2 && + touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Finger) { + touchscreen_config.mode = Core::HID::TouchScreenModeForNx::UseSystemSetting; + } + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(result); + rb.PushRaw(touchscreen_config); +} + +void IHidDebugServer::ProcessTouchScreenAutoTune(HLERequestContext& ctx) { + LOG_INFO(Service_HID, "called"); + + Result result = GetResourceManager()->GetTouchScreen()->ProcessTouchScreenAutoTune(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IHidDebugServer::ForceStopTouchScreenManagement(HLERequestContext& ctx) { + LOG_INFO(Service_HID, "called"); + + if (!firmware_settings->IsDeviceManaged()) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + return; + } + + Result result = ResultSuccess; + bool is_touch_active{}; + bool is_gesture_active{}; + auto touch_screen = GetResourceManager()->GetTouchScreen(); + auto gesture = GetResourceManager()->GetGesture(); + + if (firmware_settings->IsTouchI2cManaged()) { + result = touch_screen->IsActive(is_touch_active); + if (result.IsSuccess()) { + result = gesture->IsActive(is_gesture_active); + } + if (result.IsSuccess() && is_touch_active) { + result = touch_screen->Deactivate(); + } + if (result.IsSuccess() && is_gesture_active) { + result = gesture->Deactivate(); + } + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IHidDebugServer::ForceRestartTouchScreenManagement(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + u32 basic_gesture_id; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw()}; + + LOG_INFO(Service_HID, "called, basic_gesture_id={}, applet_resource_user_id={}", + parameters.basic_gesture_id, parameters.applet_resource_user_id); + + Result result = ResultSuccess; + auto touch_screen = GetResourceManager()->GetTouchScreen(); + auto gesture = GetResourceManager()->GetGesture(); + + if (firmware_settings->IsDeviceManaged() && firmware_settings->IsTouchI2cManaged()) { + result = gesture->Activate(); + if (result.IsSuccess()) { + result = + gesture->Activate(parameters.applet_resource_user_id, parameters.basic_gesture_id); + } + if (result.IsSuccess()) { + result = touch_screen->Activate(); + } + if (result.IsSuccess()) { + result = touch_screen->Activate(parameters.applet_resource_user_id); + } + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IHidDebugServer::IsTouchScreenManaged(HLERequestContext& ctx) { + LOG_INFO(Service_HID, "called"); + + bool is_touch_active{}; + bool is_gesture_active{}; + + Result result = GetResourceManager()->GetTouchScreen()->IsActive(is_touch_active); + if (result.IsSuccess()) { + result = GetResourceManager()->GetGesture()->IsActive(is_gesture_active); + } + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(result); + rb.Push(is_touch_active | is_gesture_active); +} + +void IHidDebugServer::DeactivateGesture(HLERequestContext& ctx) { + LOG_INFO(Service_HID, "called"); + + Result result = ResultSuccess; + + if (!firmware_settings->IsDeviceManaged()) { + result = GetResourceManager()->GetGesture()->Deactivate(); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} std::shared_ptr IHidDebugServer::GetResourceManager() { resource_manager->Initialize(); diff --git a/src/core/hle/service/hid/hid_debug_server.h b/src/core/hle/service/hid/hid_debug_server.h index 406db2211..7d5b082b3 100644 --- a/src/core/hle/service/hid/hid_debug_server.h +++ b/src/core/hle/service/hid/hid_debug_server.h @@ -11,16 +11,29 @@ class System; namespace Service::HID { class ResourceManager; +class HidFirmwareSettings; class IHidDebugServer final : public ServiceFramework { public: - explicit IHidDebugServer(Core::System& system_, std::shared_ptr resource); + explicit IHidDebugServer(Core::System& system_, std::shared_ptr resource, + std::shared_ptr settings); ~IHidDebugServer() override; private: + void DeactivateTouchScreen(HLERequestContext& ctx); + void SetTouchScreenAutoPilotState(HLERequestContext& ctx); + void UnsetTouchScreenAutoPilotState(HLERequestContext& ctx); + void GetTouchScreenConfiguration(HLERequestContext& ctx); + void ProcessTouchScreenAutoTune(HLERequestContext& ctx); + void ForceStopTouchScreenManagement(HLERequestContext& ctx); + void ForceRestartTouchScreenManagement(HLERequestContext& ctx); + void IsTouchScreenManaged(HLERequestContext& ctx); + void DeactivateGesture(HLERequestContext& ctx); + std::shared_ptr GetResourceManager(); std::shared_ptr resource_manager; + std::shared_ptr firmware_settings; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp index 09c47b5e3..9ffe027ff 100644 --- a/src/core/hle/service/hid/hid_server.cpp +++ b/src/core/hle/service/hid/hid_server.cpp @@ -989,8 +989,7 @@ void IHidServer::ActivateGesture(HLERequestContext& ctx) { } if (result.IsSuccess()) { - // TODO: Use gesture id here - result = gesture->Activate(parameters.applet_resource_user_id); + result = gesture->Activate(parameters.applet_resource_user_id, parameters.basic_gesture_id); } IPC::ResponseBuilder rb{ctx, 2}; @@ -2449,14 +2448,22 @@ void IHidServer::GetNpadCommunicationMode(HLERequestContext& ctx) { void IHidServer::SetTouchScreenConfiguration(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - const auto touchscreen_mode{rp.PopRaw()}; + auto touchscreen_config{rp.PopRaw()}; const auto applet_resource_user_id{rp.Pop()}; - LOG_WARNING(Service_HID, "(STUBBED) called, touchscreen_mode={}, applet_resource_user_id={}", - touchscreen_mode.mode, applet_resource_user_id); + LOG_INFO(Service_HID, "called, touchscreen_config={}, applet_resource_user_id={}", + touchscreen_config.mode, applet_resource_user_id); + + if (touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Heat2 && + touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Finger) { + touchscreen_config.mode = Core::HID::TouchScreenModeForNx::UseSystemSetting; + } + + const Result result = GetResourceManager()->GetTouchScreen()->SetTouchScreenConfiguration( + touchscreen_config, applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void IHidServer::IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx) { @@ -2484,11 +2491,12 @@ void IHidServer::SetTouchScreenResolution(HLERequestContext& ctx) { const auto height{rp.Pop()}; const auto applet_resource_user_id{rp.Pop()}; - GetResourceManager()->GetTouchScreen()->SetTouchscreenDimensions(width, height); - LOG_INFO(Service_HID, "called, width={}, height={}, applet_resource_user_id={}", width, height, applet_resource_user_id); + GetResourceManager()->GetTouchScreen()->SetTouchScreenResolution(width, height, + applet_resource_user_id); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp index d1ec42edc..22471e9e2 100644 --- a/src/core/hle/service/hid/hid_system_server.cpp +++ b/src/core/hle/service/hid/hid_system_server.cpp @@ -155,9 +155,9 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr()}; + const auto point1y{rp.Pop()}; + const auto point2x{rp.Pop()}; + const auto point2y{rp.Pop()}; + + LOG_INFO(Service_HID, "called, point1=-({},{}), point2=({},{})", point1x, point1y, point2x, + point2y); + + const Result result = GetResourceManager()->GetTouchScreen()->SetTouchScreenMagnification( + point1x, point1y, point2x, point2y); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IHidSystemServer::GetTouchScreenFirmwareVersion(HLERequestContext& ctx) { + LOG_INFO(Service_HID, "called"); + + Core::HID::FirmwareVersion firmware{}; + const auto result = GetResourceManager()->GetTouchScreenFirmwareVersion(firmware); + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(result); + rb.PushRaw(firmware); +} + +void IHidSystemServer::SetTouchScreenDefaultConfiguration(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + auto touchscreen_config{rp.PopRaw()}; + + LOG_INFO(Service_HID, "called, touchscreen_config={}", touchscreen_config.mode); + + if (touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Heat2 && + touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Finger) { + touchscreen_config.mode = Core::HID::TouchScreenModeForNx::UseSystemSetting; + } + + const Result result = + GetResourceManager()->GetTouchScreen()->SetTouchScreenDefaultConfiguration( + touchscreen_config); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + void IHidSystemServer::GetTouchScreenDefaultConfiguration(HLERequestContext& ctx) { - LOG_WARNING(Service_HID, "(STUBBED) called"); + LOG_INFO(Service_HID, "called"); - Core::HID::TouchScreenConfigurationForNx touchscreen_config{ - .mode = Core::HID::TouchScreenModeForNx::Finger, - }; + Core::HID::TouchScreenConfigurationForNx touchscreen_config{}; + const Result result = + GetResourceManager()->GetTouchScreen()->GetTouchScreenDefaultConfiguration( + touchscreen_config); if (touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Heat2 && touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Finger) { @@ -858,7 +906,7 @@ void IHidSystemServer::GetTouchScreenDefaultConfiguration(HLERequestContext& ctx } IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(ResultSuccess); + rb.Push(result); rb.PushRaw(touchscreen_config); } diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h index 4ab4d3931..738313e08 100644 --- a/src/core/hle/service/hid/hid_system_server.h +++ b/src/core/hle/service/hid/hid_system_server.h @@ -71,6 +71,9 @@ private: void FinalizeUsbFirmwareUpdate(HLERequestContext& ctx); void CheckUsbFirmwareUpdateRequired(HLERequestContext& ctx); void InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx); + void SetTouchScreenMagnification(HLERequestContext& ctx); + void GetTouchScreenFirmwareVersion(HLERequestContext& ctx); + void SetTouchScreenDefaultConfiguration(HLERequestContext& ctx); void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx); void SetForceHandheldStyleVibration(HLERequestContext& ctx); void IsUsingCustomButtonConfig(HLERequestContext& ctx); diff --git a/src/core/hle/service/set/setting_formats/system_settings.h b/src/core/hle/service/set/setting_formats/system_settings.h index ebc373da5..40230182a 100644 --- a/src/core/hle/service/set/setting_formats/system_settings.h +++ b/src/core/hle/service/set/setting_formats/system_settings.h @@ -12,6 +12,7 @@ #include "common/vector_math.h" #include "core/hle/service/set/setting_formats/private_settings.h" #include "core/hle/service/set/settings_types.h" +#include "hid_core/resources/touch_screen/touch_types.h" namespace Service::Set { @@ -257,8 +258,7 @@ struct SystemSettings { std::array analog_stick_user_calibration_left; std::array analog_stick_user_calibration_right; - // nn::settings::system::TouchScreenMode - s32 touch_screen_mode; + TouchScreenMode touch_screen_mode; INSERT_PADDING_BYTES(0x14); // Reserved TvSettings tv_settings; diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index 100cb2db4..c889aec47 100644 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -275,8 +275,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {184, nullptr, "SetPlatformRegion"}, {185, &ISystemSettingsServer::GetHomeMenuSchemeModel, "GetHomeMenuSchemeModel"}, {186, nullptr, "GetMemoryUsageRateFlag"}, - {187, nullptr, "GetTouchScreenMode"}, - {188, nullptr, "SetTouchScreenMode"}, + {187, &ISystemSettingsServer::GetTouchScreenMode, "GetTouchScreenMode"}, + {188, &ISystemSettingsServer::SetTouchScreenMode, "SetTouchScreenMode"}, {189, nullptr, "GetButtonConfigSettingsFull"}, {190, nullptr, "SetButtonConfigSettingsFull"}, {191, nullptr, "GetButtonConfigSettingsEmbedded"}, @@ -1395,6 +1395,28 @@ void ISystemSettingsServer::GetHomeMenuSchemeModel(HLERequestContext& ctx) { rb.Push(0); } +void ISystemSettingsServer::GetTouchScreenMode(HLERequestContext& ctx) { + TouchScreenMode touch_screen_mode{}; + auto res = GetTouchScreenMode(touch_screen_mode); + + LOG_INFO(Service_SET, "called, touch_screen_mode={}", touch_screen_mode); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(res); + rb.PushEnum(touch_screen_mode); +} + +void ISystemSettingsServer::SetTouchScreenMode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto touch_screen_mode = rp.PopEnum(); + auto res = SetTouchScreenMode(touch_screen_mode); + + LOG_INFO(Service_SET, "called, touch_screen_mode={}", touch_screen_mode); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res); +} + void ISystemSettingsServer::GetFieldTestingFlag(HLERequestContext& ctx) { LOG_INFO(Service_SET, "called, field_testing_flag={}", m_system_settings.field_testing_flag); @@ -1670,4 +1692,15 @@ Result ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime( R_SUCCEED(); } +Result ISystemSettingsServer::GetTouchScreenMode(TouchScreenMode& touch_screen_mode) const { + touch_screen_mode = m_system_settings.touch_screen_mode; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetTouchScreenMode(TouchScreenMode touch_screen_mode) { + m_system_settings.touch_screen_mode = touch_screen_mode; + SetSaveNeeded(); + R_SUCCEED(); +} + } // namespace Service::Set diff --git a/src/core/hle/service/set/system_settings_server.h b/src/core/hle/service/set/system_settings_server.h index 1982b9723..9a3b36f0c 100644 --- a/src/core/hle/service/set/system_settings_server.h +++ b/src/core/hle/service/set/system_settings_server.h @@ -74,6 +74,8 @@ public: Service::PSC::Time::SteadyClockTimePoint& out_time_point) const; Result SetUserSystemClockAutomaticCorrectionUpdatedTime( const Service::PSC::Time::SteadyClockTimePoint& time_point); + Result GetTouchScreenMode(TouchScreenMode& touch_screen_mode) const; + Result SetTouchScreenMode(TouchScreenMode touch_screen_mode); private: void SetLanguageCode(HLERequestContext& ctx); @@ -154,6 +156,8 @@ private: void GetChineseTraditionalInputMethod(HLERequestContext& ctx); void GetHomeMenuScheme(HLERequestContext& ctx); void GetHomeMenuSchemeModel(HLERequestContext& ctx); + void GetTouchScreenMode(HLERequestContext& ctx); + void SetTouchScreenMode(HLERequestContext& ctx); void GetFieldTestingFlag(HLERequestContext& ctx); void GetPanelCrcMode(HLERequestContext& ctx); void SetPanelCrcMode(HLERequestContext& ctx); -- cgit v1.2.3