diff options
Diffstat (limited to 'src/core/hle/applets')
-rw-r--r-- | src/core/hle/applets/applet.cpp | 40 | ||||
-rw-r--r-- | src/core/hle/applets/applet.h | 53 | ||||
-rw-r--r-- | src/core/hle/applets/swkbd.cpp | 73 | ||||
-rw-r--r-- | src/core/hle/applets/swkbd.h | 67 |
4 files changed, 233 insertions, 0 deletions
diff --git a/src/core/hle/applets/applet.cpp b/src/core/hle/applets/applet.cpp new file mode 100644 index 000000000..1f447e5fc --- /dev/null +++ b/src/core/hle/applets/applet.cpp @@ -0,0 +1,40 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/assert.h" +#include "common/logging/log.h" + +#include "core/hle/applets/applet.h" +#include "core/hle/applets/swkbd.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace HLE { +namespace Applets { + +static std::unordered_map<Service::APT::AppletId, std::shared_ptr<Applet>> applets; + +ResultCode Applet::Create(Service::APT::AppletId id) { + switch (id) { + case Service::APT::AppletId::SoftwareKeyboard1: + case Service::APT::AppletId::SoftwareKeyboard2: + applets[id] = std::make_shared<SoftwareKeyboard>(id); + break; + default: + // TODO(Subv): Find the right error code + return ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotSupported, ErrorLevel::Permanent); + } + + return RESULT_SUCCESS; +} + +std::shared_ptr<Applet> Applet::Get(Service::APT::AppletId id) { + auto itr = applets.find(id); + if (itr != applets.end()) + return itr->second; + return nullptr; +} + +} +} // namespace diff --git a/src/core/hle/applets/applet.h b/src/core/hle/applets/applet.h new file mode 100644 index 000000000..221348d9c --- /dev/null +++ b/src/core/hle/applets/applet.h @@ -0,0 +1,53 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/common_types.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/shared_memory.h" +#include "core/hle/service/apt/apt.h" + +namespace HLE { +namespace Applets { + +class Applet { +public: + virtual ~Applet() {}; + Applet(Service::APT::AppletId id) : id(id) {}; + + /** + * Creates an instance of the Applet subclass identified by the parameter + * and stores it in a global map. + * @param id Id of the applet to create + * @returns ResultCode Whether the operation was successful or not + */ + static ResultCode Create(Service::APT::AppletId id); + + /** + * Retrieves the Applet instance identified by the specified id + * @param id Id of the Applet to retrieve + * @returns Requested Applet or nullptr if not found + */ + static std::shared_ptr<Applet> Get(Service::APT::AppletId id); + + /** + * Handles a parameter from the application + * @param parameter Parameter data to handle + * @returns ResultCode Whether the operation was successful or not + */ + virtual ResultCode ReceiveParameter(Service::APT::MessageParameter const& parameter) = 0; + + /** + * Handles the Applet start event, triggered from the application + * @param parameter Parameter data to handle + * @returns ResultCode Whether the operation was successful or not + */ + virtual ResultCode Start(Service::APT::AppletStartupParameter const& parameter) = 0; + + Service::APT::AppletId id; ///< Id of this Applet +}; + +} +} // namespace diff --git a/src/core/hle/applets/swkbd.cpp b/src/core/hle/applets/swkbd.cpp new file mode 100644 index 000000000..224aeb096 --- /dev/null +++ b/src/core/hle/applets/swkbd.cpp @@ -0,0 +1,73 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/assert.h" +#include "common/logging/log.h" + +#include "core/hle/applets/swkbd.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace HLE { +namespace Applets { + +SoftwareKeyboard::SoftwareKeyboard(Service::APT::AppletId id) : Applet(id) { + // Create the SharedMemory that will hold the framebuffer data + // TODO(Subv): What size should we use here? + using Kernel::MemoryPermission; + framebuffer_memory = Kernel::SharedMemory::Create(0x1000, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, "SoftwareKeyboard Memory"); +} + +ResultCode SoftwareKeyboard::ReceiveParameter(Service::APT::MessageParameter const& parameter) { + if (parameter.signal != static_cast<u32>(Service::APT::SignalType::LibAppJustStarted)) { + LOG_ERROR(Service_APT, "unsupported signal %u", parameter.signal); + UNIMPLEMENTED(); + // TODO(Subv): Find the right error code + return ResultCode(-1); + } + + Service::APT::MessageParameter result; + // The buffer passed in parameter contains the data returned by GSPGPU::ImportDisplayCaptureInfo + result.signal = static_cast<u32>(Service::APT::SignalType::LibAppFinished); + result.data = nullptr; + result.buffer_size = 0; + result.destination_id = static_cast<u32>(Service::APT::AppletId::Application); + result.sender_id = static_cast<u32>(id); + result.object = framebuffer_memory; + + Service::APT::SendParameter(result); + return RESULT_SUCCESS; +} + +ResultCode SoftwareKeyboard::Start(Service::APT::AppletStartupParameter const& parameter) { + memcpy(&config, parameter.data, parameter.buffer_size); + text_memory = boost::static_pointer_cast<Kernel::SharedMemory, Kernel::Object>(parameter.object); + + // TODO(Subv): Verify if this is the correct behavior + memset(text_memory->GetPointer(), 0, text_memory->size); + + // TODO(Subv): Remove this hardcoded text + const wchar_t str[] = L"Subv"; + memcpy(text_memory->GetPointer(), str, 4 * sizeof(wchar_t)); + + // TODO(Subv): Ask for input and write it to the shared memory + // TODO(Subv): Find out what are the possible values for the return code, + // some games seem to check for a hardcoded 2 + config.return_code = 2; + config.text_length = 5; + config.text_offset = 0; + + Service::APT::MessageParameter message; + message.buffer_size = sizeof(SoftwareKeyboardConfig); + message.data = reinterpret_cast<u8*>(&config); + message.signal = static_cast<u32>(Service::APT::SignalType::LibAppClosed); + message.destination_id = static_cast<u32>(Service::APT::AppletId::Application); + message.sender_id = static_cast<u32>(id); + Service::APT::SendParameter(message); + + return RESULT_SUCCESS; +} + +} +} // namespace diff --git a/src/core/hle/applets/swkbd.h b/src/core/hle/applets/swkbd.h new file mode 100644 index 000000000..d7199690c --- /dev/null +++ b/src/core/hle/applets/swkbd.h @@ -0,0 +1,67 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/common_types.h" +#include "core/hle/applets/applet.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/shared_memory.h" +#include "core/hle/service/apt/apt.h" + +namespace HLE { +namespace Applets { + +struct SoftwareKeyboardConfig { + INSERT_PADDING_WORDS(0x8); + + u16 max_text_length; ///< Maximum length of the input text + + INSERT_PADDING_BYTES(0x6E); + + char16_t display_text[65]; ///< Text to display when asking the user for input + + INSERT_PADDING_BYTES(0xE); + + u32 default_text_offset; ///< Offset of the default text in the output SharedMemory + + INSERT_PADDING_WORDS(0x3); + + u32 shared_memory_size; ///< Size of the SharedMemory + + INSERT_PADDING_WORDS(0x1); + + u32 return_code; ///< Return code of the SoftwareKeyboard, usually 2, other values are unknown + + INSERT_PADDING_WORDS(0x2); + + u32 text_offset; ///< Offset in the SharedMemory where the output text starts + u16 text_length; ///< Length in characters of the output text + + INSERT_PADDING_BYTES(0x2B6); +}; + +static_assert(sizeof(SoftwareKeyboardConfig) == 0x400, "Software Keyboard Config size is wrong"); + +class SoftwareKeyboard : public Applet { +public: + SoftwareKeyboard(Service::APT::AppletId id); + ~SoftwareKeyboard() {} + + ResultCode ReceiveParameter(Service::APT::MessageParameter const& parameter) override; + ResultCode Start(Service::APT::AppletStartupParameter const& parameter) override; + + /// TODO(Subv): Find out what this is actually used for. + // It is believed that the application stores the current screen image here. + Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory; + + /// SharedMemory where the output text will be stored + Kernel::SharedPtr<Kernel::SharedMemory> text_memory; + + /// Configuration of this instance of the SoftwareKeyboard, as received from the application + SoftwareKeyboardConfig config; +}; + +} +} // namespace |