diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/service/am/am.cpp | 92 | ||||
| -rw-r--r-- | src/core/hle/service/am/am.h | 3 | ||||
| -rw-r--r-- | src/core/hle/service/caps/caps_manager.cpp | 16 | ||||
| -rw-r--r-- | src/core/hle/service/caps/caps_manager.h | 9 | ||||
| -rw-r--r-- | src/core/hle/service/caps/caps_ss.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/service/caps/caps_su.cpp | 42 | ||||
| -rw-r--r-- | src/core/hle/service/caps/caps_su.h | 9 | 
7 files changed, 162 insertions, 19 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index ff067c8d9..cc643ea09 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -23,6 +23,7 @@  #include "core/hle/service/am/applets/applet_cabinet.h"  #include "core/hle/service/am/applets/applet_mii_edit_types.h"  #include "core/hle/service/am/applets/applet_profile_select.h" +#include "core/hle/service/am/applets/applet_software_keyboard_types.h"  #include "core/hle/service/am/applets/applet_web_browser.h"  #include "core/hle/service/am/applets/applets.h"  #include "core/hle/service/am/idle.h" @@ -31,6 +32,7 @@  #include "core/hle/service/apm/apm_controller.h"  #include "core/hle/service/apm/apm_interface.h"  #include "core/hle/service/bcat/backend/backend.h" +#include "core/hle/service/caps/caps_su.h"  #include "core/hle/service/caps/caps_types.h"  #include "core/hle/service/filesystem/filesystem.h"  #include "core/hle/service/ipc_helpers.h" @@ -702,9 +704,17 @@ void ISelfController::SetAlbumImageTakenNotificationEnabled(HLERequestContext& c  void ISelfController::SaveCurrentScreenshot(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx}; -    const auto album_report_option = rp.PopEnum<Capture::AlbumReportOption>(); +    const auto report_option = rp.PopEnum<Capture::AlbumReportOption>(); -    LOG_WARNING(Service_AM, "(STUBBED) called. album_report_option={}", album_report_option); +    LOG_INFO(Service_AM, "called, report_option={}", report_option); + +    const auto screenshot_service = +        system.ServiceManager().GetService<Service::Capture::IScreenShotApplicationService>( +            "caps:su"); + +    if (screenshot_service) { +        screenshot_service->CaptureAndSaveScreenshot(report_option); +    }      IPC::ResponseBuilder rb{ctx, 2};      rb.Push(ResultSuccess); @@ -1562,7 +1572,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)          {16, nullptr, "GetMainAppletStorageId"},          {17, nullptr, "GetCallerAppletIdentityInfoStack"},          {18, nullptr, "GetNextReturnDestinationAppletIdentityInfo"}, -        {19, nullptr, "GetDesirableKeyboardLayout"}, +        {19, &ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout, "GetDesirableKeyboardLayout"},          {20, nullptr, "PopExtraStorage"},          {25, nullptr, "GetPopExtraStorageEvent"},          {30, nullptr, "UnpopInData"}, @@ -1581,7 +1591,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)          {120, nullptr, "GetLaunchStorageInfoForDebug"},          {130, nullptr, "GetGpuErrorDetectedSystemEvent"},          {140, nullptr, "SetApplicationMemoryReservation"}, -        {150, nullptr, "ShouldSetGpuTimeSliceManually"}, +        {150, &ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually, "ShouldSetGpuTimeSliceManually"},      };      // clang-format on      RegisterHandlers(functions); @@ -1596,6 +1606,9 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)      case Applets::AppletId::PhotoViewer:          PushInShowAlbum();          break; +    case Applets::AppletId::SoftwareKeyboard: +        PushInShowSoftwareKeyboard(); +        break;      default:          break;      } @@ -1672,6 +1685,14 @@ void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext&      rb.PushRaw(applet_info);  } +void ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(HLERequestContext& ctx) { +    LOG_WARNING(Service_AM, "(STUBBED) called"); + +    IPC::ResponseBuilder rb{ctx, 3}; +    rb.Push(ResultSuccess); +    rb.Push<u32>(0); +} +  void ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers(HLERequestContext& ctx) {      const Service::Account::ProfileManager manager{};      bool is_empty{true}; @@ -1691,6 +1712,14 @@ void ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers(HLERequestContext&      rb.Push(user_count);  } +void ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually(HLERequestContext& ctx) { +    LOG_WARNING(Service_AM, "(STUBBED) called"); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +    rb.Push<u8>(0); +} +  void ILibraryAppletSelfAccessor::PushInShowAlbum() {      const Applets::CommonArguments arguments{          .arguments_version = Applets::CommonArgumentVersion::Version3, @@ -1759,6 +1788,61 @@ void ILibraryAppletSelfAccessor::PushInShowMiiEditData() {      queue_data.emplace_back(std::move(argument_data));  } +void ILibraryAppletSelfAccessor::PushInShowSoftwareKeyboard() { +    const Applets::CommonArguments arguments{ +        .arguments_version = Applets::CommonArgumentVersion::Version3, +        .size = Applets::CommonArgumentSize::Version3, +        .library_version = static_cast<u32>(Applets::SwkbdAppletVersion::Version524301), +        .theme_color = Applets::ThemeColor::BasicBlack, +        .play_startup_sound = true, +        .system_tick = system.CoreTiming().GetClockTicks(), +    }; + +    std::vector<char16_t> initial_string(0); + +    const Applets::SwkbdConfigCommon swkbd_config{ +        .type = Applets::SwkbdType::Qwerty, +        .ok_text{}, +        .left_optional_symbol_key{}, +        .right_optional_symbol_key{}, +        .use_prediction = false, +        .key_disable_flags{}, +        .initial_cursor_position = Applets::SwkbdInitialCursorPosition::Start, +        .header_text{}, +        .sub_text{}, +        .guide_text{}, +        .max_text_length = 500, +        .min_text_length = 0, +        .password_mode = Applets::SwkbdPasswordMode::Disabled, +        .text_draw_type = Applets::SwkbdTextDrawType::Box, +        .enable_return_button = true, +        .use_utf8 = false, +        .use_blur_background = true, +        .initial_string_offset{}, +        .initial_string_length = static_cast<u32>(initial_string.size()), +        .user_dictionary_offset{}, +        .user_dictionary_entries{}, +        .use_text_check = false, +    }; + +    Applets::SwkbdConfigNew swkbd_config_new{}; + +    std::vector<u8> argument_data(sizeof(arguments)); +    std::vector<u8> swkbd_data(sizeof(swkbd_config) + sizeof(swkbd_config_new)); +    std::vector<u8> work_buffer(swkbd_config.initial_string_length * sizeof(char16_t)); + +    std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); +    std::memcpy(swkbd_data.data(), &swkbd_config, sizeof(swkbd_config)); +    std::memcpy(swkbd_data.data() + sizeof(swkbd_config), &swkbd_config_new, +                sizeof(Applets::SwkbdConfigNew)); +    std::memcpy(work_buffer.data(), initial_string.data(), +                swkbd_config.initial_string_length * sizeof(char16_t)); + +    queue_data.emplace_back(std::move(argument_data)); +    queue_data.emplace_back(std::move(swkbd_data)); +    queue_data.emplace_back(std::move(work_buffer)); +} +  IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_)      : ServiceFramework{system_, "IAppletCommonFunctions"} {      // clang-format off diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 64b3f3fe2..8f8cb8a9e 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -347,11 +347,14 @@ private:      void GetLibraryAppletInfo(HLERequestContext& ctx);      void ExitProcessAndReturn(HLERequestContext& ctx);      void GetCallerAppletIdentityInfo(HLERequestContext& ctx); +    void GetDesirableKeyboardLayout(HLERequestContext& ctx);      void GetMainAppletAvailableUsers(HLERequestContext& ctx); +    void ShouldSetGpuTimeSliceManually(HLERequestContext& ctx);      void PushInShowAlbum();      void PushInShowCabinetData();      void PushInShowMiiEditData(); +    void PushInShowSoftwareKeyboard();      std::deque<std::vector<u8>> queue_data;  }; diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp index 7d733eb54..96b225d5f 100644 --- a/src/core/hle/service/caps/caps_manager.cpp +++ b/src/core/hle/service/caps/caps_manager.cpp @@ -228,12 +228,14 @@ Result AlbumManager::LoadAlbumScreenShotThumbnail(  Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry,                                      const ScreenShotAttribute& attribute, -                                    std::span<const u8> image_data, u64 aruid) { -    return SaveScreenShot(out_entry, attribute, {}, image_data, aruid); +                                    AlbumReportOption report_option, std::span<const u8> image_data, +                                    u64 aruid) { +    return SaveScreenShot(out_entry, attribute, report_option, {}, image_data, aruid);  }  Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry,                                      const ScreenShotAttribute& attribute, +                                    AlbumReportOption report_option,                                      const ApplicationData& app_data, std::span<const u8> image_data,                                      u64 aruid) {      const u64 title_id = system.GetApplicationProcessProgramID(); @@ -407,10 +409,14 @@ Result AlbumManager::LoadImage(std::span<u8> out_image, const std::filesystem::p      return ResultSuccess;  } -static void PNGToMemory(void* context, void* png, int len) { +void AlbumManager::FlipVerticallyOnWrite(bool flip) { +    stbi_flip_vertically_on_write(flip); +} + +static void PNGToMemory(void* context, void* data, int len) {      std::vector<u8>* png_image = static_cast<std::vector<u8>*>(context); -    png_image->reserve(len); -    std::memcpy(png_image->data(), png, len); +    unsigned char* png = static_cast<unsigned char*>(data); +    png_image->insert(png_image->end(), png, png + len);  }  Result AlbumManager::SaveImage(ApplicationAlbumEntry& out_entry, std::span<const u8> image, diff --git a/src/core/hle/service/caps/caps_manager.h b/src/core/hle/service/caps/caps_manager.h index 44d85117f..e20c70c7b 100644 --- a/src/core/hle/service/caps/caps_manager.h +++ b/src/core/hle/service/caps/caps_manager.h @@ -59,14 +59,17 @@ public:                                          const ScreenShotDecodeOption& decoder_options) const;      Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute, -                          std::span<const u8> image_data, u64 aruid); -    Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute, -                          const ApplicationData& app_data, std::span<const u8> image_data, +                          AlbumReportOption report_option, std::span<const u8> image_data,                            u64 aruid); +    Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute, +                          AlbumReportOption report_option, const ApplicationData& app_data, +                          std::span<const u8> image_data, u64 aruid);      Result SaveEditedScreenShot(ApplicationAlbumEntry& out_entry,                                  const ScreenShotAttribute& attribute, const AlbumFileId& file_id,                                  std::span<const u8> image_data); +    void FlipVerticallyOnWrite(bool flip); +  private:      static constexpr std::size_t NandAlbumFileLimit = 1000;      static constexpr std::size_t SdAlbumFileLimit = 10000; diff --git a/src/core/hle/service/caps/caps_ss.cpp b/src/core/hle/service/caps/caps_ss.cpp index 1ba2b7972..eab023568 100644 --- a/src/core/hle/service/caps/caps_ss.cpp +++ b/src/core/hle/service/caps/caps_ss.cpp @@ -34,7 +34,7 @@ void IScreenShotService::SaveScreenShotEx0(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      struct Parameters {          ScreenShotAttribute attribute{}; -        u32 report_option{}; +        AlbumReportOption report_option{};          INSERT_PADDING_BYTES(0x4);          u64 applet_resource_user_id{};      }; @@ -49,13 +49,16 @@ void IScreenShotService::SaveScreenShotEx0(HLERequestContext& ctx) {               parameters.applet_resource_user_id);      ApplicationAlbumEntry entry{}; -    const auto result = manager->SaveScreenShot(entry, parameters.attribute, image_data_buffer, -                                                parameters.applet_resource_user_id); +    manager->FlipVerticallyOnWrite(false); +    const auto result = +        manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, +                                image_data_buffer, parameters.applet_resource_user_id);      IPC::ResponseBuilder rb{ctx, 10};      rb.Push(result);      rb.PushRaw(entry);  } +  void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      struct Parameters { @@ -83,6 +86,7 @@ void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) {               image_data_buffer.size(), thumbnail_image_data_buffer.size());      ApplicationAlbumEntry entry{}; +    manager->FlipVerticallyOnWrite(false);      const auto result = manager->SaveEditedScreenShot(entry, parameters.attribute,                                                        parameters.file_id, image_data_buffer); diff --git a/src/core/hle/service/caps/caps_su.cpp b/src/core/hle/service/caps/caps_su.cpp index e85625ee4..296b07b00 100644 --- a/src/core/hle/service/caps/caps_su.cpp +++ b/src/core/hle/service/caps/caps_su.cpp @@ -2,10 +2,12 @@  // SPDX-License-Identifier: GPL-2.0-or-later  #include "common/logging/log.h" +#include "core/core.h"  #include "core/hle/service/caps/caps_manager.h"  #include "core/hle/service/caps/caps_su.h"  #include "core/hle/service/caps/caps_types.h"  #include "core/hle/service/ipc_helpers.h" +#include "video_core/renderer_base.h"  namespace Service::Capture { @@ -58,8 +60,10 @@ void IScreenShotApplicationService::SaveScreenShotEx0(HLERequestContext& ctx) {               parameters.applet_resource_user_id);      ApplicationAlbumEntry entry{}; -    const auto result = manager->SaveScreenShot(entry, parameters.attribute, image_data_buffer, -                                                parameters.applet_resource_user_id); +    manager->FlipVerticallyOnWrite(false); +    const auto result = +        manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, +                                image_data_buffer, parameters.applet_resource_user_id);      IPC::ResponseBuilder rb{ctx, 10};      rb.Push(result); @@ -88,13 +92,43 @@ void IScreenShotApplicationService::SaveScreenShotEx1(HLERequestContext& ctx) {      ApplicationAlbumEntry entry{};      ApplicationData app_data{};      std::memcpy(&app_data, app_data_buffer.data(), sizeof(ApplicationData)); +    manager->FlipVerticallyOnWrite(false);      const auto result = -        manager->SaveScreenShot(entry, parameters.attribute, app_data, image_data_buffer, -                                parameters.applet_resource_user_id); +        manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, app_data, +                                image_data_buffer, parameters.applet_resource_user_id);      IPC::ResponseBuilder rb{ctx, 10};      rb.Push(result);      rb.PushRaw(entry);  } +void IScreenShotApplicationService::CaptureAndSaveScreenshot(AlbumReportOption report_option) { +    auto& renderer = system.Renderer(); +    Layout::FramebufferLayout layout = +        Layout::DefaultFrameLayout(screenshot_width, screenshot_height); + +    const Capture::ScreenShotAttribute attribute{ +        .unknown_0{}, +        .orientation = Capture::AlbumImageOrientation::None, +        .unknown_1{}, +        .unknown_2{}, +    }; + +    renderer.RequestScreenshot( +        image_data.data(), +        [attribute, report_option, this](bool invert_y) { +            // Convert from BGRA to RGBA +            for (std::size_t i = 0; i < image_data.size(); i += bytes_per_pixel) { +                const u8 temp = image_data[i]; +                image_data[i] = image_data[i + 2]; +                image_data[i + 2] = temp; +            } + +            Capture::ApplicationAlbumEntry entry{}; +            manager->FlipVerticallyOnWrite(invert_y); +            manager->SaveScreenShot(entry, attribute, report_option, image_data, {}); +        }, +        layout); +} +  } // namespace Service::Capture diff --git a/src/core/hle/service/caps/caps_su.h b/src/core/hle/service/caps/caps_su.h index 89e71f506..21912e95f 100644 --- a/src/core/hle/service/caps/caps_su.h +++ b/src/core/hle/service/caps/caps_su.h @@ -10,6 +10,7 @@ class System;  }  namespace Service::Capture { +enum class AlbumReportOption : s32;  class AlbumManager;  class IScreenShotApplicationService final : public ServiceFramework<IScreenShotApplicationService> { @@ -18,11 +19,19 @@ public:                                             std::shared_ptr<AlbumManager> album_manager);      ~IScreenShotApplicationService() override; +    void CaptureAndSaveScreenshot(AlbumReportOption report_option); +  private: +    static constexpr std::size_t screenshot_width = 1280; +    static constexpr std::size_t screenshot_height = 720; +    static constexpr std::size_t bytes_per_pixel = 4; +      void SetShimLibraryVersion(HLERequestContext& ctx);      void SaveScreenShotEx0(HLERequestContext& ctx);      void SaveScreenShotEx1(HLERequestContext& ctx); +    std::array<u8, screenshot_width * screenshot_height * bytes_per_pixel> image_data; +      std::shared_ptr<AlbumManager> manager;  };  | 
