diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index a1360dd26..959f278aa 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -214,13 +214,13 @@ std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, std::size_t return std::string(buffer, len); } -std::u16string UTF16StringFromFixedZeroTerminatedBuffer(const char16_t* buffer, +std::u16string UTF16StringFromFixedZeroTerminatedBuffer(std::u16string_view buffer, std::size_t max_len) { std::size_t len = 0; while (len < max_len && buffer[len] != '\0') ++len; - return std::u16string(buffer, len); + return std::u16string(buffer.begin(), buffer.begin() + len); } const char* TrimSourcePath(const char* path, const char* root) { diff --git a/src/common/string_util.h b/src/common/string_util.h index 95b7badaf..583fd05e6 100644 --- a/src/common/string_util.h +++ b/src/common/string_util.h @@ -68,10 +68,10 @@ std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, std::size_t /** * Creates a UTF-16 std::u16string from a fixed-size NUL-terminated char buffer. If the buffer isn't - * NUL-terminated, then the string ends at the greatest multiple of two less then or equal to + * null-terminated, then the string ends at the greatest multiple of two less then or equal to * max_len_bytes. */ -std::u16string UTF16StringFromFixedZeroTerminatedBuffer(const char16_t* buffer, +std::u16string UTF16StringFromFixedZeroTerminatedBuffer(std::u16string_view buffer, std::size_t max_len); /** diff --git a/src/core/core.cpp b/src/core/core.cpp index 6d5b5a2d0..6c72fdf4a 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -23,12 +23,14 @@ #include "core/hle/kernel/process.h" #include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" +#include "core/hle/service/am/applets/software_keyboard.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" #include "core/loader/loader.h" #include "core/perf_stats.h" #include "core/settings.h" #include "core/telemetry_session.h" +#include "frontend/applets/software_keyboard.h" #include "video_core/debug_utils/debug_utils.h" #include "video_core/gpu.h" #include "video_core/renderer_base.h" @@ -136,6 +138,10 @@ struct System::Impl { if (virtual_filesystem == nullptr) virtual_filesystem = std::make_shared(); + /// Create default implementations of applets if one is not provided. + if (software_keyboard == nullptr) + software_keyboard = std::make_unique(); + auto main_process = Kernel::Process::Create(kernel, "main"); kernel.MakeCurrentProcess(main_process.get()); @@ -289,6 +295,9 @@ struct System::Impl { std::array, NUM_CPU_CORES - 1> cpu_core_threads; std::size_t active_core{}; ///< Active core, only used in single thread mode + /// Frontend applets + std::unique_ptr software_keyboard; + /// Service manager std::shared_ptr service_manager; @@ -488,6 +497,14 @@ std::shared_ptr System::GetFilesystem() const { return impl->virtual_filesystem; } +void System::SetSoftwareKeyboard(std::unique_ptr applet) { + impl->software_keyboard = std::move(applet); +} + +const Core::Frontend::SoftwareKeyboardApplet& System::GetSoftwareKeyboard() const { + return *impl->software_keyboard; +} + System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) { return impl->Init(emu_window); } diff --git a/src/core/core.h b/src/core/core.h index cfacceb81..be71bd437 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -13,6 +13,7 @@ namespace Core::Frontend { class EmuWindow; +class SoftwareKeyboardApplet; } // namespace Core::Frontend namespace FileSys { @@ -236,6 +237,10 @@ public: std::shared_ptr GetFilesystem() const; + void SetSoftwareKeyboard(std::unique_ptr applet); + + const Core::Frontend::SoftwareKeyboardApplet& GetSoftwareKeyboard() const; + private: System(); diff --git a/src/core/frontend/applets/software_keyboard.cpp b/src/core/frontend/applets/software_keyboard.cpp index c1bacefef..41d81c293 100644 --- a/src/core/frontend/applets/software_keyboard.cpp +++ b/src/core/frontend/applets/software_keyboard.cpp @@ -3,16 +3,19 @@ // Refer to the license.txt file included. #include "common/logging/backend.h" -#include "common/string_util.h" #include "core/frontend/applets/software_keyboard.h" -namespace Frontend { -bool DefaultSoftwareKeyboardApplet::GetText(Parameters parameters, std::u16string& text) { +namespace Core::Frontend { +SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default; + +bool DefaultSoftwareKeyboardApplet::GetText(SoftwareKeyboardParameters parameters, + std::u16string& text) const { if (parameters.initial_text.empty()) - text = Common::UTF8ToUTF16("yuzu"); + text = u"yuzu"; else text = parameters.initial_text; return true; } -} // namespace Frontend + +} // namespace Core::Frontend diff --git a/src/core/frontend/applets/software_keyboard.h b/src/core/frontend/applets/software_keyboard.h index d368385d2..2ea9db889 100644 --- a/src/core/frontend/applets/software_keyboard.h +++ b/src/core/frontend/applets/software_keyboard.h @@ -8,37 +8,39 @@ #include "common/bit_field.h" #include "common/common_types.h" -namespace Frontend { +namespace Core::Frontend { +struct SoftwareKeyboardParameters { + std::u16string submit_text; + std::u16string header_text; + std::u16string sub_text; + std::u16string guide_text; + std::u16string initial_text; + std::size_t max_length; + bool password; + bool cursor_at_beginning; + + union { + u8 value; + + BitField<1, 1, u8> disable_space; + BitField<2, 1, u8> disable_address; + BitField<3, 1, u8> disable_percent; + BitField<4, 1, u8> disable_slash; + BitField<6, 1, u8> disable_number; + BitField<7, 1, u8> disable_download_code; + }; +}; + class SoftwareKeyboardApplet { public: - struct Parameters { - std::u16string submit_text; - std::u16string header_text; - std::u16string sub_text; - std::u16string guide_text; - std::u16string initial_text; - std::size_t max_length; - bool password; - bool cursor_at_beginning; + virtual ~SoftwareKeyboardApplet(); - union { - u8 value; - - BitField<1, 1, u8> disable_space; - BitField<2, 1, u8> disable_address; - BitField<3, 1, u8> disable_percent; - BitField<4, 1, u8> disable_slash; - BitField<6, 1, u8> disable_number; - BitField<7, 1, u8> disable_download_code; - }; - }; - - virtual bool GetText(Parameters parameters, std::u16string& text) = 0; - virtual ~SoftwareKeyboardApplet() = default; + virtual bool GetText(SoftwareKeyboardParameters parameters, std::u16string& text) const = 0; }; class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet { - bool GetText(Parameters parameters, std::u16string& text) override; +public: + bool GetText(SoftwareKeyboardParameters parameters, std::u16string& text) const override; }; -} // namespace Frontend +} // namespace Core::Frontend diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 20af65ee7..f84b00a00 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1207,14 +1207,15 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 return ERR_INVALID_ADDRESS; } - if (addr + size <= addr) { + if (!IsValidAddressRange(addr, size)) { LOG_ERROR(Kernel_SVC, "Address and size cause overflow! (address={:016X}, size={:016X})", addr, size); return ERR_INVALID_ADDRESS_STATE; } - if (permissions > static_cast(MemoryPermission::ReadWrite) || - permissions == static_cast(MemoryPermission::Write)) { + const auto perms = static_cast(permissions); + if (perms != MemoryPermission::None && perms != MemoryPermission::Read && + perms != MemoryPermission::ReadWrite) { LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})", permissions); return ERR_INVALID_MEMORY_PERMISSIONS; @@ -1222,7 +1223,6 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 auto& kernel = Core::System::GetInstance().Kernel(); auto& handle_table = Core::CurrentProcess()->GetHandleTable(); - const auto perms = static_cast(permissions); const auto shared_mem_handle = SharedMemory::Create( kernel, handle_table.Get(CurrentProcess), size, perms, perms, addr); diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 53580d673..fc464270e 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -501,6 +501,8 @@ IStorage::IStorage(std::vector buffer) RegisterHandlers(functions); } +IStorage::~IStorage() = default; + const std::vector& IStorage::GetData() const { return buffer; } @@ -670,6 +672,8 @@ IStorageAccessor::IStorageAccessor(IStorage& storage) RegisterHandlers(functions); } +IStorageAccessor::~IStorageAccessor() = default; + void IStorageAccessor::GetSize(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; @@ -685,7 +689,7 @@ void IStorageAccessor::Write(Kernel::HLERequestContext& ctx) { const u64 offset{rp.Pop()}; const std::vector data{ctx.ReadBuffer()}; - const auto size = std::min(data.size(), backing.buffer.size() - offset); + const auto size = std::min(data.size(), backing.buffer.size() - offset); std::memcpy(&backing.buffer[offset], data.data(), size); @@ -701,7 +705,7 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) { const u64 offset{rp.Pop()}; std::size_t size{ctx.GetWriteBufferSize()}; - size = std::min(size, backing.buffer.size() - offset); + size = std::min(size, backing.buffer.size() - offset); ctx.WriteBuffer(backing.buffer.data() + offset, size); @@ -787,9 +791,9 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex return; } - std::vector memory(shared_mem->size); - std::memcpy(memory.data(), shared_mem->backing_block->data() + shared_mem->backing_block_offset, - memory.size()); + const auto mem_begin = shared_mem->backing_block->begin() + shared_mem->backing_block_offset; + const auto mem_end = mem_begin + shared_mem->size; + std::vector memory{mem_begin, mem_end}; IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 640901e4a..44c1bcde5 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -158,27 +158,29 @@ private: class IStorage final : public ServiceFramework { public: explicit IStorage(std::vector buffer); + ~IStorage() override; const std::vector& GetData() const; private: - std::vector buffer; - void Open(Kernel::HLERequestContext& ctx); + std::vector buffer; + friend class IStorageAccessor; }; class IStorageAccessor final : public ServiceFramework { public: explicit IStorageAccessor(IStorage& backing); + ~IStorageAccessor() override; private: - IStorage& backing; - void GetSize(Kernel::HLERequestContext& ctx); void Write(Kernel::HLERequestContext& ctx); void Read(Kernel::HLERequestContext& ctx); + + IStorage& backing; }; class ILibraryAppletCreator final : public ServiceFramework { diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index 8cc4b0f1a..03b9d83e7 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp @@ -7,23 +7,13 @@ namespace Service::AM::Applets { -std::shared_ptr software_keyboard = - std::make_shared(); +Applet::Applet() = default; + +Applet::~Applet() = default; void Applet::Initialize(std::vector> storage) { storage_stack = std::move(storage); initialized = true; } -void RegisterSoftwareKeyboard(std::shared_ptr applet) { - if (applet == nullptr) - return; - - software_keyboard = std::move(applet); -} - -std::shared_ptr GetSoftwareKeyboard() { - return software_keyboard; -} - } // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 1f91392b4..47db22fb4 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h @@ -20,10 +20,17 @@ namespace Applets { class Applet { public: + Applet(); + virtual ~Applet(); + virtual void Initialize(std::vector> storage); virtual IStorage Execute() = 0; + bool IsInitialized() const { + return initialized; + } + protected: struct CommonArguments { u32_le arguments_version; @@ -39,8 +46,5 @@ protected: bool initialized = false; }; -void RegisterSoftwareKeyboard(std::shared_ptr applet); -std::shared_ptr GetSoftwareKeyboard(); - } // namespace Applets } // namespace Service::AM diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index ad1797ef1..556dea3e4 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp @@ -2,8 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include "common/assert.h" #include "common/string_util.h" +#include "core/core.h" #include "core/frontend/applets/software_keyboard.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/software_keyboard.h" @@ -11,11 +13,13 @@ namespace Service::AM::Applets { constexpr std::size_t SWKBD_OUTPUT_BUFFER_SIZE = 0x7D8; +constexpr std::size_t SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE = 0x7D4; constexpr std::size_t DEFAULT_MAX_LENGTH = 500; +constexpr bool INTERACTIVE_STATUS_OK = false; -static Frontend::SoftwareKeyboardApplet::Parameters ConvertToFrontendParameters( +static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters( KeyboardConfig config, std::u16string initial_text) { - Frontend::SoftwareKeyboardApplet::Parameters params{}; + Core::Frontend::SoftwareKeyboardParameters params{}; params.submit_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( config.submit_text.data(), config.submit_text.size()); @@ -34,6 +38,10 @@ static Frontend::SoftwareKeyboardApplet::Parameters ConvertToFrontendParameters( return params; } +SoftwareKeyboard::SoftwareKeyboard() = default; + +SoftwareKeyboard::~SoftwareKeyboard() = default; + void SoftwareKeyboard::Initialize(std::vector> storage_) { Applet::Initialize(std::move(storage_)); diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/software_keyboard.h index 9a37ba45f..9d77f5802 100644 --- a/src/core/hle/service/am/applets/software_keyboard.h +++ b/src/core/hle/service/am/applets/software_keyboard.h @@ -5,6 +5,7 @@ #pragma once #include "common/common_funcs.h" +#include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/applets.h" namespace Service::AM::Applets { @@ -45,13 +46,21 @@ static_assert(sizeof(KeyboardConfig) == 0x3E0, "KeyboardConfig has incorrect siz class SoftwareKeyboard final : public Applet { public: + SoftwareKeyboard(); + ~SoftwareKeyboard() override; + void Initialize(std::vector> storage) override; + bool TransactionComplete() const override; + ResultCode GetStatus() const override; + void ReceiveInteractiveData(std::shared_ptr storage) override; IStorage Execute() override; private: KeyboardConfig config; std::u16string initial_text; + bool complete = false; + std::vector final_data; }; } // namespace Service::AM::Applets diff --git a/src/yuzu/applets/software_keyboard.cpp b/src/yuzu/applets/software_keyboard.cpp index bd8bd0dd0..fad150ec1 100644 --- a/src/yuzu/applets/software_keyboard.cpp +++ b/src/yuzu/applets/software_keyboard.cpp @@ -2,21 +2,20 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include +#include #include #include #include #include #include -#include "common/logging/backend.h" -#include "common/string_util.h" #include "yuzu/applets/software_keyboard.h" +#include "yuzu/main.h" QtSoftwareKeyboardValidator::QtSoftwareKeyboardValidator( - Frontend::SoftwareKeyboardApplet::Parameters parameters) + Core::Frontend::SoftwareKeyboardParameters parameters) : parameters(std::move(parameters)) {} -QValidator::State QtSoftwareKeyboardValidator::validate(QString& input, int&) const { +QValidator::State QtSoftwareKeyboardValidator::validate(QString& input, int& pos) const { if (input.size() > parameters.max_length) return Invalid; if (parameters.disable_space && input.contains(' ')) @@ -28,18 +27,20 @@ QValidator::State QtSoftwareKeyboardValidator::validate(QString& input, int&) co if (parameters.disable_slash && (input.contains('/') || input.contains('\\'))) return Invalid; if (parameters.disable_number && - std::any_of(input.begin(), input.end(), [](QChar c) { return c.isDigit(); })) + std::any_of(input.begin(), input.end(), [](QChar c) { return c.isDigit(); })) { return Invalid; + } if (parameters.disable_download_code && - std::any_of(input.begin(), input.end(), [](QChar c) { return c == 'O' || c == 'I'; })) + std::any_of(input.begin(), input.end(), [](QChar c) { return c == 'O' || c == 'I'; })) { return Invalid; + } return Acceptable; } QtSoftwareKeyboardDialog::QtSoftwareKeyboardDialog( - QWidget* parent, Frontend::SoftwareKeyboardApplet::Parameters parameters_) + QWidget* parent, Core::Frontend::SoftwareKeyboardParameters parameters_) : QDialog(parent), parameters(std::move(parameters_)) { layout = new QVBoxLayout; @@ -79,9 +80,11 @@ QtSoftwareKeyboardDialog::QtSoftwareKeyboardDialog( layout->addWidget(line_edit); layout->addWidget(buttons); setLayout(layout); - setWindowTitle("Software Keyboard"); + setWindowTitle(tr("Software Keyboard")); } +QtSoftwareKeyboardDialog::~QtSoftwareKeyboardDialog() = default; + void QtSoftwareKeyboardDialog::Submit() { ok = true; text = line_edit->text().toStdU16String(); @@ -90,19 +93,33 @@ void QtSoftwareKeyboardDialog::Submit() { void QtSoftwareKeyboardDialog::Reject() { ok = false; - text = Common::UTF8ToUTF16(""); + text.clear(); accept(); } -QtSoftwareKeyboard::QtSoftwareKeyboard(QWidget& parent) : parent(parent) {} - -bool QtSoftwareKeyboard::GetText(Parameters parameters, std::u16string& text) { - QtSoftwareKeyboardDialog dialog(&parent, parameters); - dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | - Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); - dialog.setWindowModality(Qt::WindowModal); - dialog.exec(); - - text = dialog.text; - return dialog.ok; +std::u16string QtSoftwareKeyboardDialog::GetText() { + return text; +} + +bool QtSoftwareKeyboardDialog::GetStatus() { + return ok; +} + +QtSoftwareKeyboard::QtSoftwareKeyboard(GMainWindow& parent) : main_window(parent) {} + +QtSoftwareKeyboard::~QtSoftwareKeyboard() = default; + +bool QtSoftwareKeyboard::GetText(Core::Frontend::SoftwareKeyboardParameters parameters, + std::u16string& text) const { + bool success; + QMetaObject::invokeMethod(&main_window, "SoftwareKeyboardGetText", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(bool, success), + Q_ARG(Core::Frontend::SoftwareKeyboardParameters, parameters), + Q_ARG(std::u16string&, text)); + return success; +} + +void QtSoftwareKeyboard::SendTextCheckDialog(std::u16string error_message) const { + QMetaObject::invokeMethod(&main_window, "SoftwareKeyboardInvokeCheckDialog", + Qt::BlockingQueuedConnection, Q_ARG(std::u16string, error_message)); } diff --git a/src/yuzu/applets/software_keyboard.h b/src/yuzu/applets/software_keyboard.h index 2a18419db..1069c10ec 100644 --- a/src/yuzu/applets/software_keyboard.h +++ b/src/yuzu/applets/software_keyboard.h @@ -3,11 +3,13 @@ // Refer to the license.txt file included. #pragma once + #include #include #include "common/assert.h" #include "core/frontend/applets/software_keyboard.h" +class GMainWindow; class QDialogButtonBox; class QLabel; class QLineEdit; @@ -16,11 +18,11 @@ class QtSoftwareKeyboard; class QtSoftwareKeyboardValidator final : public QValidator { public: - explicit QtSoftwareKeyboardValidator(Frontend::SoftwareKeyboardApplet::Parameters parameters); - State validate(QString&, int&) const override; + explicit QtSoftwareKeyboardValidator(Core::Frontend::SoftwareKeyboardParameters parameters); + State validate(QString& input, int& pos) const override; private: - Frontend::SoftwareKeyboardApplet::Parameters parameters; + Core::Frontend::SoftwareKeyboardParameters parameters; }; class QtSoftwareKeyboardDialog final : public QDialog { @@ -28,10 +30,15 @@ class QtSoftwareKeyboardDialog final : public QDialog { public: QtSoftwareKeyboardDialog(QWidget* parent, - Frontend::SoftwareKeyboardApplet::Parameters parameters); + Core::Frontend::SoftwareKeyboardParameters parameters); + ~QtSoftwareKeyboardDialog() override; + void Submit(); void Reject(); + std::u16string GetText(); + bool GetStatus(); + private: bool ok = false; std::u16string text; @@ -43,20 +50,18 @@ private: QLineEdit* line_edit; QVBoxLayout* layout; - Frontend::SoftwareKeyboardApplet::Parameters parameters; - - friend class QtSoftwareKeyboard; + Core::Frontend::SoftwareKeyboardParameters parameters; }; -class QtSoftwareKeyboard final : public QObject, public Frontend::SoftwareKeyboardApplet { +class QtSoftwareKeyboard final : public QObject, public Core::Frontend::SoftwareKeyboardApplet { public: - explicit QtSoftwareKeyboard(QWidget& parent); - bool GetText(Parameters parameters, std::u16string& text) override; + explicit QtSoftwareKeyboard(GMainWindow& parent); + ~QtSoftwareKeyboard() override; - ~QtSoftwareKeyboard() { - UNREACHABLE(); - } + bool GetText(Core::Frontend::SoftwareKeyboardParameters parameters, + std::u16string& text) const override; + void SendTextCheckDialog(std::u16string error_message) const override; private: - QWidget& parent; + GMainWindow& main_window; }; diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 7b2a01169..9b2c09f32 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -561,7 +561,7 @@ bool GMainWindow::LoadROM(const QString& filename) { system.SetGPUDebugContext(debug_context); - Service::AM::Applets::RegisterSoftwareKeyboard(std::make_shared(*this)); + system.SetSoftwareKeyboard(std::make_unique(*this)); const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())}; @@ -1232,8 +1232,13 @@ void GMainWindow::OnMenuRecentFile() { void GMainWindow::OnStartGame() { emu_thread->SetRunning(true); + + qRegisterMetaType( + "core::Frontend::SoftwareKeyboardParameters"); qRegisterMetaType("Core::System::ResultStatus"); qRegisterMetaType("std::string"); + qRegisterMetaType("std::u16string"); + connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError); ui.action_Start->setEnabled(false); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 929250e8c..38074e3f0 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -29,6 +29,10 @@ class ProfilerWidget; class WaitTreeWidget; enum class GameListOpenTarget; +namespace Core::Frontend { +struct SoftwareKeyboardParameters; +} // namespace Core::Frontend + namespace FileSys { class RegisteredCacheUnion; class VfsFilesystem; @@ -95,6 +99,11 @@ signals: // Signal that tells widgets to update icons to use the current theme void UpdateThemedIcons(); +public slots: + bool SoftwareKeyboardGetText(const Core::Frontend::SoftwareKeyboardParameters& parameters, + std::u16string& text); + void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message); + private: void InitializeWidgets(); void InitializeDebugWidgets();