summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-11-11 16:39:25 -0500
committerGravatar Zach Hilman2018-11-18 10:53:47 -0500
commite696ed1f4d20f28f8b26c637498962938df7d96f (patch)
tree79222d795725ba7b19f0aa9326041e236f9a22d8 /src
parentqt/main: Register Qt Software Keyboard frontend with AM (diff)
downloadyuzu-e696ed1f4d20f28f8b26c637498962938df7d96f.tar.gz
yuzu-e696ed1f4d20f28f8b26c637498962938df7d96f.tar.xz
yuzu-e696ed1f4d20f28f8b26c637498962938df7d96f.zip
am: Deglobalize software keyboard applet
Diffstat (limited to '')
-rw-r--r--src/common/string_util.cpp4
-rw-r--r--src/common/string_util.h4
-rw-r--r--src/core/core.cpp17
-rw-r--r--src/core/core.h5
-rw-r--r--src/core/frontend/applets/software_keyboard.cpp13
-rw-r--r--src/core/frontend/applets/software_keyboard.h54
-rw-r--r--src/core/hle/kernel/svc.cpp8
-rw-r--r--src/core/hle/service/am/am.cpp14
-rw-r--r--src/core/hle/service/am/am.h10
-rw-r--r--src/core/hle/service/am/applets/applets.cpp16
-rw-r--r--src/core/hle/service/am/applets/applets.h10
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.cpp12
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.h9
-rw-r--r--src/yuzu/applets/software_keyboard.cpp55
-rw-r--r--src/yuzu/applets/software_keyboard.h33
-rw-r--r--src/yuzu/main.cpp7
-rw-r--r--src/yuzu/main.h9
17 files changed, 180 insertions, 100 deletions
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
214 return std::string(buffer, len); 214 return std::string(buffer, len);
215} 215}
216 216
217std::u16string UTF16StringFromFixedZeroTerminatedBuffer(const char16_t* buffer, 217std::u16string UTF16StringFromFixedZeroTerminatedBuffer(std::u16string_view buffer,
218 std::size_t max_len) { 218 std::size_t max_len) {
219 std::size_t len = 0; 219 std::size_t len = 0;
220 while (len < max_len && buffer[len] != '\0') 220 while (len < max_len && buffer[len] != '\0')
221 ++len; 221 ++len;
222 222
223 return std::u16string(buffer, len); 223 return std::u16string(buffer.begin(), buffer.begin() + len);
224} 224}
225 225
226const char* TrimSourcePath(const char* path, const char* root) { 226const 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
68 68
69/** 69/**
70 * Creates a UTF-16 std::u16string from a fixed-size NUL-terminated char buffer. If the buffer isn't 70 * Creates a UTF-16 std::u16string from a fixed-size NUL-terminated char buffer. If the buffer isn't
71 * NUL-terminated, then the string ends at the greatest multiple of two less then or equal to 71 * null-terminated, then the string ends at the greatest multiple of two less then or equal to
72 * max_len_bytes. 72 * max_len_bytes.
73 */ 73 */
74std::u16string UTF16StringFromFixedZeroTerminatedBuffer(const char16_t* buffer, 74std::u16string UTF16StringFromFixedZeroTerminatedBuffer(std::u16string_view buffer,
75 std::size_t max_len); 75 std::size_t max_len);
76 76
77/** 77/**
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 @@
23#include "core/hle/kernel/process.h" 23#include "core/hle/kernel/process.h"
24#include "core/hle/kernel/scheduler.h" 24#include "core/hle/kernel/scheduler.h"
25#include "core/hle/kernel/thread.h" 25#include "core/hle/kernel/thread.h"
26#include "core/hle/service/am/applets/software_keyboard.h"
26#include "core/hle/service/service.h" 27#include "core/hle/service/service.h"
27#include "core/hle/service/sm/sm.h" 28#include "core/hle/service/sm/sm.h"
28#include "core/loader/loader.h" 29#include "core/loader/loader.h"
29#include "core/perf_stats.h" 30#include "core/perf_stats.h"
30#include "core/settings.h" 31#include "core/settings.h"
31#include "core/telemetry_session.h" 32#include "core/telemetry_session.h"
33#include "frontend/applets/software_keyboard.h"
32#include "video_core/debug_utils/debug_utils.h" 34#include "video_core/debug_utils/debug_utils.h"
33#include "video_core/gpu.h" 35#include "video_core/gpu.h"
34#include "video_core/renderer_base.h" 36#include "video_core/renderer_base.h"
@@ -136,6 +138,10 @@ struct System::Impl {
136 if (virtual_filesystem == nullptr) 138 if (virtual_filesystem == nullptr)
137 virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>(); 139 virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
138 140
141 /// Create default implementations of applets if one is not provided.
142 if (software_keyboard == nullptr)
143 software_keyboard = std::make_unique<Core::Frontend::DefaultSoftwareKeyboardApplet>();
144
139 auto main_process = Kernel::Process::Create(kernel, "main"); 145 auto main_process = Kernel::Process::Create(kernel, "main");
140 kernel.MakeCurrentProcess(main_process.get()); 146 kernel.MakeCurrentProcess(main_process.get());
141 147
@@ -289,6 +295,9 @@ struct System::Impl {
289 std::array<std::unique_ptr<std::thread>, NUM_CPU_CORES - 1> cpu_core_threads; 295 std::array<std::unique_ptr<std::thread>, NUM_CPU_CORES - 1> cpu_core_threads;
290 std::size_t active_core{}; ///< Active core, only used in single thread mode 296 std::size_t active_core{}; ///< Active core, only used in single thread mode
291 297
298 /// Frontend applets
299 std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet> software_keyboard;
300
292 /// Service manager 301 /// Service manager
293 std::shared_ptr<Service::SM::ServiceManager> service_manager; 302 std::shared_ptr<Service::SM::ServiceManager> service_manager;
294 303
@@ -488,6 +497,14 @@ std::shared_ptr<FileSys::VfsFilesystem> System::GetFilesystem() const {
488 return impl->virtual_filesystem; 497 return impl->virtual_filesystem;
489} 498}
490 499
500void System::SetSoftwareKeyboard(std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet> applet) {
501 impl->software_keyboard = std::move(applet);
502}
503
504const Core::Frontend::SoftwareKeyboardApplet& System::GetSoftwareKeyboard() const {
505 return *impl->software_keyboard;
506}
507
491System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) { 508System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) {
492 return impl->Init(emu_window); 509 return impl->Init(emu_window);
493} 510}
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 @@
13 13
14namespace Core::Frontend { 14namespace Core::Frontend {
15class EmuWindow; 15class EmuWindow;
16class SoftwareKeyboardApplet;
16} // namespace Core::Frontend 17} // namespace Core::Frontend
17 18
18namespace FileSys { 19namespace FileSys {
@@ -236,6 +237,10 @@ public:
236 237
237 std::shared_ptr<FileSys::VfsFilesystem> GetFilesystem() const; 238 std::shared_ptr<FileSys::VfsFilesystem> GetFilesystem() const;
238 239
240 void SetSoftwareKeyboard(std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet> applet);
241
242 const Core::Frontend::SoftwareKeyboardApplet& GetSoftwareKeyboard() const;
243
239private: 244private:
240 System(); 245 System();
241 246
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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/backend.h" 5#include "common/logging/backend.h"
6#include "common/string_util.h"
7#include "core/frontend/applets/software_keyboard.h" 6#include "core/frontend/applets/software_keyboard.h"
8 7
9namespace Frontend { 8namespace Core::Frontend {
10bool DefaultSoftwareKeyboardApplet::GetText(Parameters parameters, std::u16string& text) { 9SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default;
10
11bool DefaultSoftwareKeyboardApplet::GetText(SoftwareKeyboardParameters parameters,
12 std::u16string& text) const {
11 if (parameters.initial_text.empty()) 13 if (parameters.initial_text.empty())
12 text = Common::UTF8ToUTF16("yuzu"); 14 text = u"yuzu";
13 else 15 else
14 text = parameters.initial_text; 16 text = parameters.initial_text;
15 17
16 return true; 18 return true;
17} 19}
18} // namespace Frontend 20
21} // 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 @@
8#include "common/bit_field.h" 8#include "common/bit_field.h"
9#include "common/common_types.h" 9#include "common/common_types.h"
10 10
11namespace Frontend { 11namespace Core::Frontend {
12struct SoftwareKeyboardParameters {
13 std::u16string submit_text;
14 std::u16string header_text;
15 std::u16string sub_text;
16 std::u16string guide_text;
17 std::u16string initial_text;
18 std::size_t max_length;
19 bool password;
20 bool cursor_at_beginning;
21
22 union {
23 u8 value;
24
25 BitField<1, 1, u8> disable_space;
26 BitField<2, 1, u8> disable_address;
27 BitField<3, 1, u8> disable_percent;
28 BitField<4, 1, u8> disable_slash;
29 BitField<6, 1, u8> disable_number;
30 BitField<7, 1, u8> disable_download_code;
31 };
32};
33
12class SoftwareKeyboardApplet { 34class SoftwareKeyboardApplet {
13public: 35public:
14 struct Parameters { 36 virtual ~SoftwareKeyboardApplet();
15 std::u16string submit_text;
16 std::u16string header_text;
17 std::u16string sub_text;
18 std::u16string guide_text;
19 std::u16string initial_text;
20 std::size_t max_length;
21 bool password;
22 bool cursor_at_beginning;
23
24 union {
25 u8 value;
26
27 BitField<1, 1, u8> disable_space;
28 BitField<2, 1, u8> disable_address;
29 BitField<3, 1, u8> disable_percent;
30 BitField<4, 1, u8> disable_slash;
31 BitField<6, 1, u8> disable_number;
32 BitField<7, 1, u8> disable_download_code;
33 };
34 };
35 37
36 virtual bool GetText(Parameters parameters, std::u16string& text) = 0; 38 virtual bool GetText(SoftwareKeyboardParameters parameters, std::u16string& text) const = 0;
37 virtual ~SoftwareKeyboardApplet() = default;
38}; 39};
39 40
40class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet { 41class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet {
41 bool GetText(Parameters parameters, std::u16string& text) override; 42public:
43 bool GetText(SoftwareKeyboardParameters parameters, std::u16string& text) const override;
42}; 44};
43 45
44} // namespace Frontend 46} // 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
1207 return ERR_INVALID_ADDRESS; 1207 return ERR_INVALID_ADDRESS;
1208 } 1208 }
1209 1209
1210 if (addr + size <= addr) { 1210 if (!IsValidAddressRange(addr, size)) {
1211 LOG_ERROR(Kernel_SVC, "Address and size cause overflow! (address={:016X}, size={:016X})", 1211 LOG_ERROR(Kernel_SVC, "Address and size cause overflow! (address={:016X}, size={:016X})",
1212 addr, size); 1212 addr, size);
1213 return ERR_INVALID_ADDRESS_STATE; 1213 return ERR_INVALID_ADDRESS_STATE;
1214 } 1214 }
1215 1215
1216 if (permissions > static_cast<u32>(MemoryPermission::ReadWrite) || 1216 const auto perms = static_cast<MemoryPermission>(permissions);
1217 permissions == static_cast<u32>(MemoryPermission::Write)) { 1217 if (perms != MemoryPermission::None && perms != MemoryPermission::Read &&
1218 perms != MemoryPermission::ReadWrite) {
1218 LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})", 1219 LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})",
1219 permissions); 1220 permissions);
1220 return ERR_INVALID_MEMORY_PERMISSIONS; 1221 return ERR_INVALID_MEMORY_PERMISSIONS;
@@ -1222,7 +1223,6 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32
1222 1223
1223 auto& kernel = Core::System::GetInstance().Kernel(); 1224 auto& kernel = Core::System::GetInstance().Kernel();
1224 auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1225 auto& handle_table = Core::CurrentProcess()->GetHandleTable();
1225 const auto perms = static_cast<MemoryPermission>(permissions);
1226 const auto shared_mem_handle = SharedMemory::Create( 1226 const auto shared_mem_handle = SharedMemory::Create(
1227 kernel, handle_table.Get<Process>(CurrentProcess), size, perms, perms, addr); 1227 kernel, handle_table.Get<Process>(CurrentProcess), size, perms, perms, addr);
1228 1228
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<u8> buffer)
501 RegisterHandlers(functions); 501 RegisterHandlers(functions);
502} 502}
503 503
504IStorage::~IStorage() = default;
505
504const std::vector<u8>& IStorage::GetData() const { 506const std::vector<u8>& IStorage::GetData() const {
505 return buffer; 507 return buffer;
506} 508}
@@ -670,6 +672,8 @@ IStorageAccessor::IStorageAccessor(IStorage& storage)
670 RegisterHandlers(functions); 672 RegisterHandlers(functions);
671} 673}
672 674
675IStorageAccessor::~IStorageAccessor() = default;
676
673void IStorageAccessor::GetSize(Kernel::HLERequestContext& ctx) { 677void IStorageAccessor::GetSize(Kernel::HLERequestContext& ctx) {
674 IPC::ResponseBuilder rb{ctx, 4}; 678 IPC::ResponseBuilder rb{ctx, 4};
675 679
@@ -685,7 +689,7 @@ void IStorageAccessor::Write(Kernel::HLERequestContext& ctx) {
685 const u64 offset{rp.Pop<u64>()}; 689 const u64 offset{rp.Pop<u64>()};
686 const std::vector<u8> data{ctx.ReadBuffer()}; 690 const std::vector<u8> data{ctx.ReadBuffer()};
687 691
688 const auto size = std::min<std::size_t>(data.size(), backing.buffer.size() - offset); 692 const auto size = std::min(data.size(), backing.buffer.size() - offset);
689 693
690 std::memcpy(&backing.buffer[offset], data.data(), size); 694 std::memcpy(&backing.buffer[offset], data.data(), size);
691 695
@@ -701,7 +705,7 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) {
701 const u64 offset{rp.Pop<u64>()}; 705 const u64 offset{rp.Pop<u64>()};
702 std::size_t size{ctx.GetWriteBufferSize()}; 706 std::size_t size{ctx.GetWriteBufferSize()};
703 707
704 size = std::min<std::size_t>(size, backing.buffer.size() - offset); 708 size = std::min(size, backing.buffer.size() - offset);
705 709
706 ctx.WriteBuffer(backing.buffer.data() + offset, size); 710 ctx.WriteBuffer(backing.buffer.data() + offset, size);
707 711
@@ -787,9 +791,9 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex
787 return; 791 return;
788 } 792 }
789 793
790 std::vector<u8> memory(shared_mem->size); 794 const auto mem_begin = shared_mem->backing_block->begin() + shared_mem->backing_block_offset;
791 std::memcpy(memory.data(), shared_mem->backing_block->data() + shared_mem->backing_block_offset, 795 const auto mem_end = mem_begin + shared_mem->size;
792 memory.size()); 796 std::vector<u8> memory{mem_begin, mem_end};
793 797
794 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 798 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
795 rb.Push(RESULT_SUCCESS); 799 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:
158class IStorage final : public ServiceFramework<IStorage> { 158class IStorage final : public ServiceFramework<IStorage> {
159public: 159public:
160 explicit IStorage(std::vector<u8> buffer); 160 explicit IStorage(std::vector<u8> buffer);
161 ~IStorage() override;
161 162
162 const std::vector<u8>& GetData() const; 163 const std::vector<u8>& GetData() const;
163 164
164private: 165private:
165 std::vector<u8> buffer;
166
167 void Open(Kernel::HLERequestContext& ctx); 166 void Open(Kernel::HLERequestContext& ctx);
168 167
168 std::vector<u8> buffer;
169
169 friend class IStorageAccessor; 170 friend class IStorageAccessor;
170}; 171};
171 172
172class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { 173class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
173public: 174public:
174 explicit IStorageAccessor(IStorage& backing); 175 explicit IStorageAccessor(IStorage& backing);
176 ~IStorageAccessor() override;
175 177
176private: 178private:
177 IStorage& backing;
178
179 void GetSize(Kernel::HLERequestContext& ctx); 179 void GetSize(Kernel::HLERequestContext& ctx);
180 void Write(Kernel::HLERequestContext& ctx); 180 void Write(Kernel::HLERequestContext& ctx);
181 void Read(Kernel::HLERequestContext& ctx); 181 void Read(Kernel::HLERequestContext& ctx);
182
183 IStorage& backing;
182}; 184};
183 185
184class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { 186class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
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 @@
7 7
8namespace Service::AM::Applets { 8namespace Service::AM::Applets {
9 9
10std::shared_ptr<Frontend::SoftwareKeyboardApplet> software_keyboard = 10Applet::Applet() = default;
11 std::make_shared<Frontend::DefaultSoftwareKeyboardApplet>(); 11
12Applet::~Applet() = default;
12 13
13void Applet::Initialize(std::vector<std::shared_ptr<IStorage>> storage) { 14void Applet::Initialize(std::vector<std::shared_ptr<IStorage>> storage) {
14 storage_stack = std::move(storage); 15 storage_stack = std::move(storage);
15 initialized = true; 16 initialized = true;
16} 17}
17 18
18void RegisterSoftwareKeyboard(std::shared_ptr<Frontend::SoftwareKeyboardApplet> applet) {
19 if (applet == nullptr)
20 return;
21
22 software_keyboard = std::move(applet);
23}
24
25std::shared_ptr<Frontend::SoftwareKeyboardApplet> GetSoftwareKeyboard() {
26 return software_keyboard;
27}
28
29} // namespace Service::AM::Applets 19} // 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 {
20 20
21class Applet { 21class Applet {
22public: 22public:
23 Applet();
24 virtual ~Applet();
25
23 virtual void Initialize(std::vector<std::shared_ptr<IStorage>> storage); 26 virtual void Initialize(std::vector<std::shared_ptr<IStorage>> storage);
24 27
25 virtual IStorage Execute() = 0; 28 virtual IStorage Execute() = 0;
26 29
30 bool IsInitialized() const {
31 return initialized;
32 }
33
27protected: 34protected:
28 struct CommonArguments { 35 struct CommonArguments {
29 u32_le arguments_version; 36 u32_le arguments_version;
@@ -39,8 +46,5 @@ protected:
39 bool initialized = false; 46 bool initialized = false;
40}; 47};
41 48
42void RegisterSoftwareKeyboard(std::shared_ptr<Frontend::SoftwareKeyboardApplet> applet);
43std::shared_ptr<Frontend::SoftwareKeyboardApplet> GetSoftwareKeyboard();
44
45} // namespace Applets 49} // namespace Applets
46} // namespace Service::AM 50} // 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring>
5#include "common/assert.h" 6#include "common/assert.h"
6#include "common/string_util.h" 7#include "common/string_util.h"
8#include "core/core.h"
7#include "core/frontend/applets/software_keyboard.h" 9#include "core/frontend/applets/software_keyboard.h"
8#include "core/hle/service/am/am.h" 10#include "core/hle/service/am/am.h"
9#include "core/hle/service/am/applets/software_keyboard.h" 11#include "core/hle/service/am/applets/software_keyboard.h"
@@ -11,11 +13,13 @@
11namespace Service::AM::Applets { 13namespace Service::AM::Applets {
12 14
13constexpr std::size_t SWKBD_OUTPUT_BUFFER_SIZE = 0x7D8; 15constexpr std::size_t SWKBD_OUTPUT_BUFFER_SIZE = 0x7D8;
16constexpr std::size_t SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE = 0x7D4;
14constexpr std::size_t DEFAULT_MAX_LENGTH = 500; 17constexpr std::size_t DEFAULT_MAX_LENGTH = 500;
18constexpr bool INTERACTIVE_STATUS_OK = false;
15 19
16static Frontend::SoftwareKeyboardApplet::Parameters ConvertToFrontendParameters( 20static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters(
17 KeyboardConfig config, std::u16string initial_text) { 21 KeyboardConfig config, std::u16string initial_text) {
18 Frontend::SoftwareKeyboardApplet::Parameters params{}; 22 Core::Frontend::SoftwareKeyboardParameters params{};
19 23
20 params.submit_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( 24 params.submit_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
21 config.submit_text.data(), config.submit_text.size()); 25 config.submit_text.data(), config.submit_text.size());
@@ -34,6 +38,10 @@ static Frontend::SoftwareKeyboardApplet::Parameters ConvertToFrontendParameters(
34 return params; 38 return params;
35} 39}
36 40
41SoftwareKeyboard::SoftwareKeyboard() = default;
42
43SoftwareKeyboard::~SoftwareKeyboard() = default;
44
37void SoftwareKeyboard::Initialize(std::vector<std::shared_ptr<IStorage>> storage_) { 45void SoftwareKeyboard::Initialize(std::vector<std::shared_ptr<IStorage>> storage_) {
38 Applet::Initialize(std::move(storage_)); 46 Applet::Initialize(std::move(storage_));
39 47
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 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_funcs.h" 7#include "common/common_funcs.h"
8#include "core/hle/service/am/am.h"
8#include "core/hle/service/am/applets/applets.h" 9#include "core/hle/service/am/applets/applets.h"
9 10
10namespace Service::AM::Applets { 11namespace Service::AM::Applets {
@@ -45,13 +46,21 @@ static_assert(sizeof(KeyboardConfig) == 0x3E0, "KeyboardConfig has incorrect siz
45 46
46class SoftwareKeyboard final : public Applet { 47class SoftwareKeyboard final : public Applet {
47public: 48public:
49 SoftwareKeyboard();
50 ~SoftwareKeyboard() override;
51
48 void Initialize(std::vector<std::shared_ptr<IStorage>> storage) override; 52 void Initialize(std::vector<std::shared_ptr<IStorage>> storage) override;
49 53
54 bool TransactionComplete() const override;
55 ResultCode GetStatus() const override;
56 void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) override;
50 IStorage Execute() override; 57 IStorage Execute() override;
51 58
52private: 59private:
53 KeyboardConfig config; 60 KeyboardConfig config;
54 std::u16string initial_text; 61 std::u16string initial_text;
62 bool complete = false;
63 std::vector<u8> final_data;
55}; 64};
56 65
57} // namespace Service::AM::Applets 66} // 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <locale> 5#include <algorithm>
6#include <QDialogButtonBox> 6#include <QDialogButtonBox>
7#include <QFont> 7#include <QFont>
8#include <QLabel> 8#include <QLabel>
9#include <QLineEdit> 9#include <QLineEdit>
10#include <QVBoxLayout> 10#include <QVBoxLayout>
11#include "common/logging/backend.h"
12#include "common/string_util.h"
13#include "yuzu/applets/software_keyboard.h" 11#include "yuzu/applets/software_keyboard.h"
12#include "yuzu/main.h"
14 13
15QtSoftwareKeyboardValidator::QtSoftwareKeyboardValidator( 14QtSoftwareKeyboardValidator::QtSoftwareKeyboardValidator(
16 Frontend::SoftwareKeyboardApplet::Parameters parameters) 15 Core::Frontend::SoftwareKeyboardParameters parameters)
17 : parameters(std::move(parameters)) {} 16 : parameters(std::move(parameters)) {}
18 17
19QValidator::State QtSoftwareKeyboardValidator::validate(QString& input, int&) const { 18QValidator::State QtSoftwareKeyboardValidator::validate(QString& input, int& pos) const {
20 if (input.size() > parameters.max_length) 19 if (input.size() > parameters.max_length)
21 return Invalid; 20 return Invalid;
22 if (parameters.disable_space && input.contains(' ')) 21 if (parameters.disable_space && input.contains(' '))
@@ -28,18 +27,20 @@ QValidator::State QtSoftwareKeyboardValidator::validate(QString& input, int&) co
28 if (parameters.disable_slash && (input.contains('/') || input.contains('\\'))) 27 if (parameters.disable_slash && (input.contains('/') || input.contains('\\')))
29 return Invalid; 28 return Invalid;
30 if (parameters.disable_number && 29 if (parameters.disable_number &&
31 std::any_of(input.begin(), input.end(), [](QChar c) { return c.isDigit(); })) 30 std::any_of(input.begin(), input.end(), [](QChar c) { return c.isDigit(); })) {
32 return Invalid; 31 return Invalid;
32 }
33 33
34 if (parameters.disable_download_code && 34 if (parameters.disable_download_code &&
35 std::any_of(input.begin(), input.end(), [](QChar c) { return c == 'O' || c == 'I'; })) 35 std::any_of(input.begin(), input.end(), [](QChar c) { return c == 'O' || c == 'I'; })) {
36 return Invalid; 36 return Invalid;
37 }
37 38
38 return Acceptable; 39 return Acceptable;
39} 40}
40 41
41QtSoftwareKeyboardDialog::QtSoftwareKeyboardDialog( 42QtSoftwareKeyboardDialog::QtSoftwareKeyboardDialog(
42 QWidget* parent, Frontend::SoftwareKeyboardApplet::Parameters parameters_) 43 QWidget* parent, Core::Frontend::SoftwareKeyboardParameters parameters_)
43 : QDialog(parent), parameters(std::move(parameters_)) { 44 : QDialog(parent), parameters(std::move(parameters_)) {
44 layout = new QVBoxLayout; 45 layout = new QVBoxLayout;
45 46
@@ -79,9 +80,11 @@ QtSoftwareKeyboardDialog::QtSoftwareKeyboardDialog(
79 layout->addWidget(line_edit); 80 layout->addWidget(line_edit);
80 layout->addWidget(buttons); 81 layout->addWidget(buttons);
81 setLayout(layout); 82 setLayout(layout);
82 setWindowTitle("Software Keyboard"); 83 setWindowTitle(tr("Software Keyboard"));
83} 84}
84 85
86QtSoftwareKeyboardDialog::~QtSoftwareKeyboardDialog() = default;
87
85void QtSoftwareKeyboardDialog::Submit() { 88void QtSoftwareKeyboardDialog::Submit() {
86 ok = true; 89 ok = true;
87 text = line_edit->text().toStdU16String(); 90 text = line_edit->text().toStdU16String();
@@ -90,19 +93,33 @@ void QtSoftwareKeyboardDialog::Submit() {
90 93
91void QtSoftwareKeyboardDialog::Reject() { 94void QtSoftwareKeyboardDialog::Reject() {
92 ok = false; 95 ok = false;
93 text = Common::UTF8ToUTF16(""); 96 text.clear();
94 accept(); 97 accept();
95} 98}
96 99
97QtSoftwareKeyboard::QtSoftwareKeyboard(QWidget& parent) : parent(parent) {} 100std::u16string QtSoftwareKeyboardDialog::GetText() {
101 return text;
102}
103
104bool QtSoftwareKeyboardDialog::GetStatus() {
105 return ok;
106}
98 107
99bool QtSoftwareKeyboard::GetText(Parameters parameters, std::u16string& text) { 108QtSoftwareKeyboard::QtSoftwareKeyboard(GMainWindow& parent) : main_window(parent) {}
100 QtSoftwareKeyboardDialog dialog(&parent, parameters); 109
101 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | 110QtSoftwareKeyboard::~QtSoftwareKeyboard() = default;
102 Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); 111
103 dialog.setWindowModality(Qt::WindowModal); 112bool QtSoftwareKeyboard::GetText(Core::Frontend::SoftwareKeyboardParameters parameters,
104 dialog.exec(); 113 std::u16string& text) const {
114 bool success;
115 QMetaObject::invokeMethod(&main_window, "SoftwareKeyboardGetText", Qt::BlockingQueuedConnection,
116 Q_RETURN_ARG(bool, success),
117 Q_ARG(Core::Frontend::SoftwareKeyboardParameters, parameters),
118 Q_ARG(std::u16string&, text));
119 return success;
120}
105 121
106 text = dialog.text; 122void QtSoftwareKeyboard::SendTextCheckDialog(std::u16string error_message) const {
107 return dialog.ok; 123 QMetaObject::invokeMethod(&main_window, "SoftwareKeyboardInvokeCheckDialog",
124 Qt::BlockingQueuedConnection, Q_ARG(std::u16string, error_message));
108} 125}
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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
6
6#include <QDialog> 7#include <QDialog>
7#include <QValidator> 8#include <QValidator>
8#include "common/assert.h" 9#include "common/assert.h"
9#include "core/frontend/applets/software_keyboard.h" 10#include "core/frontend/applets/software_keyboard.h"
10 11
12class GMainWindow;
11class QDialogButtonBox; 13class QDialogButtonBox;
12class QLabel; 14class QLabel;
13class QLineEdit; 15class QLineEdit;
@@ -16,11 +18,11 @@ class QtSoftwareKeyboard;
16 18
17class QtSoftwareKeyboardValidator final : public QValidator { 19class QtSoftwareKeyboardValidator final : public QValidator {
18public: 20public:
19 explicit QtSoftwareKeyboardValidator(Frontend::SoftwareKeyboardApplet::Parameters parameters); 21 explicit QtSoftwareKeyboardValidator(Core::Frontend::SoftwareKeyboardParameters parameters);
20 State validate(QString&, int&) const override; 22 State validate(QString& input, int& pos) const override;
21 23
22private: 24private:
23 Frontend::SoftwareKeyboardApplet::Parameters parameters; 25 Core::Frontend::SoftwareKeyboardParameters parameters;
24}; 26};
25 27
26class QtSoftwareKeyboardDialog final : public QDialog { 28class QtSoftwareKeyboardDialog final : public QDialog {
@@ -28,10 +30,15 @@ class QtSoftwareKeyboardDialog final : public QDialog {
28 30
29public: 31public:
30 QtSoftwareKeyboardDialog(QWidget* parent, 32 QtSoftwareKeyboardDialog(QWidget* parent,
31 Frontend::SoftwareKeyboardApplet::Parameters parameters); 33 Core::Frontend::SoftwareKeyboardParameters parameters);
34 ~QtSoftwareKeyboardDialog() override;
35
32 void Submit(); 36 void Submit();
33 void Reject(); 37 void Reject();
34 38
39 std::u16string GetText();
40 bool GetStatus();
41
35private: 42private:
36 bool ok = false; 43 bool ok = false;
37 std::u16string text; 44 std::u16string text;
@@ -43,20 +50,18 @@ private:
43 QLineEdit* line_edit; 50 QLineEdit* line_edit;
44 QVBoxLayout* layout; 51 QVBoxLayout* layout;
45 52
46 Frontend::SoftwareKeyboardApplet::Parameters parameters; 53 Core::Frontend::SoftwareKeyboardParameters parameters;
47
48 friend class QtSoftwareKeyboard;
49}; 54};
50 55
51class QtSoftwareKeyboard final : public QObject, public Frontend::SoftwareKeyboardApplet { 56class QtSoftwareKeyboard final : public QObject, public Core::Frontend::SoftwareKeyboardApplet {
52public: 57public:
53 explicit QtSoftwareKeyboard(QWidget& parent); 58 explicit QtSoftwareKeyboard(GMainWindow& parent);
54 bool GetText(Parameters parameters, std::u16string& text) override; 59 ~QtSoftwareKeyboard() override;
55 60
56 ~QtSoftwareKeyboard() { 61 bool GetText(Core::Frontend::SoftwareKeyboardParameters parameters,
57 UNREACHABLE(); 62 std::u16string& text) const override;
58 } 63 void SendTextCheckDialog(std::u16string error_message) const override;
59 64
60private: 65private:
61 QWidget& parent; 66 GMainWindow& main_window;
62}; 67};
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) {
561 561
562 system.SetGPUDebugContext(debug_context); 562 system.SetGPUDebugContext(debug_context);
563 563
564 Service::AM::Applets::RegisterSoftwareKeyboard(std::make_shared<QtSoftwareKeyboard>(*this)); 564 system.SetSoftwareKeyboard(std::make_unique<QtSoftwareKeyboard>(*this));
565 565
566 const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())}; 566 const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())};
567 567
@@ -1232,8 +1232,13 @@ void GMainWindow::OnMenuRecentFile() {
1232 1232
1233void GMainWindow::OnStartGame() { 1233void GMainWindow::OnStartGame() {
1234 emu_thread->SetRunning(true); 1234 emu_thread->SetRunning(true);
1235
1236 qRegisterMetaType<Core::Frontend::SoftwareKeyboardParameters>(
1237 "core::Frontend::SoftwareKeyboardParameters");
1235 qRegisterMetaType<Core::System::ResultStatus>("Core::System::ResultStatus"); 1238 qRegisterMetaType<Core::System::ResultStatus>("Core::System::ResultStatus");
1236 qRegisterMetaType<std::string>("std::string"); 1239 qRegisterMetaType<std::string>("std::string");
1240 qRegisterMetaType<std::u16string>("std::u16string");
1241
1237 connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError); 1242 connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError);
1238 1243
1239 ui.action_Start->setEnabled(false); 1244 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;
29class WaitTreeWidget; 29class WaitTreeWidget;
30enum class GameListOpenTarget; 30enum class GameListOpenTarget;
31 31
32namespace Core::Frontend {
33struct SoftwareKeyboardParameters;
34} // namespace Core::Frontend
35
32namespace FileSys { 36namespace FileSys {
33class RegisteredCacheUnion; 37class RegisteredCacheUnion;
34class VfsFilesystem; 38class VfsFilesystem;
@@ -95,6 +99,11 @@ signals:
95 // Signal that tells widgets to update icons to use the current theme 99 // Signal that tells widgets to update icons to use the current theme
96 void UpdateThemedIcons(); 100 void UpdateThemedIcons();
97 101
102public slots:
103 bool SoftwareKeyboardGetText(const Core::Frontend::SoftwareKeyboardParameters& parameters,
104 std::u16string& text);
105 void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message);
106
98private: 107private:
99 void InitializeWidgets(); 108 void InitializeWidgets();
100 void InitializeDebugWidgets(); 109 void InitializeDebugWidgets();