summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/audio_out.cpp2
-rw-r--r--src/audio_core/audio_renderer.cpp2
-rw-r--r--src/audio_core/cubeb_sink.cpp2
-rw-r--r--src/audio_core/stream.cpp2
-rw-r--r--src/common/CMakeLists.txt4
-rw-r--r--src/common/assert.cpp7
-rw-r--r--src/common/logging/backend.cpp39
-rw-r--r--src/common/logging/backend.h8
-rw-r--r--src/common/logging/filter.cpp4
-rw-r--r--src/common/logging/filter.h4
-rw-r--r--src/common/logging/log.h34
-rw-r--r--src/common/logging/text_formatter.cpp4
-rw-r--r--src/common/logging/text_formatter.h4
-rw-r--r--src/common/settings.cpp (renamed from src/core/settings.cpp)15
-rw-r--r--src/common/settings.h (renamed from src/core/settings.h)15
-rw-r--r--src/common/settings_input.cpp (renamed from src/input_common/settings.cpp)2
-rw-r--r--src/common/settings_input.h (renamed from src/input_common/settings.h)1
-rw-r--r--src/core/CMakeLists.txt5
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp2
-rw-r--r--src/core/core.cpp11
-rw-r--r--src/core/core.h3
-rw-r--r--src/core/crypto/aes_util.cpp6
-rw-r--r--src/core/crypto/aes_util.h8
-rw-r--r--src/core/crypto/key_manager.cpp2
-rw-r--r--src/core/file_sys/patch_manager.cpp2
-rw-r--r--src/core/file_sys/program_metadata.cpp6
-rw-r--r--src/core/file_sys/program_metadata.h9
-rw-r--r--src/core/frontend/applets/profile_select.cpp2
-rw-r--r--src/core/frontend/applets/software_keyboard.cpp148
-rw-r--r--src/core/frontend/applets/software_keyboard.h118
-rw-r--r--src/core/frontend/emu_window.cpp25
-rw-r--r--src/core/frontend/emu_window.h28
-rw-r--r--src/core/frontend/framebuffer_layout.cpp2
-rw-r--r--src/core/frontend/input_interpreter.cpp15
-rw-r--r--src/core/frontend/input_interpreter.h3
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp8
-rw-r--r--src/core/hle/kernel/hle_ipc.h10
-rw-r--r--src/core/hle/kernel/k_resource_limit.cpp13
-rw-r--r--src/core/hle/kernel/k_resource_limit.h12
-rw-r--r--src/core/hle/kernel/kernel.cpp7
-rw-r--r--src/core/hle/kernel/process.cpp2
-rw-r--r--src/core/hle/kernel/svc.cpp2
-rw-r--r--src/core/hle/service/acc/acc.cpp4
-rw-r--r--src/core/hle/service/acc/profile_manager.cpp2
-rw-r--r--src/core/hle/service/am/am.cpp101
-rw-r--r--src/core/hle/service/am/am.h5
-rw-r--r--src/core/hle/service/am/applets/applets.cpp57
-rw-r--r--src/core/hle/service/am/applets/applets.h30
-rw-r--r--src/core/hle/service/am/applets/controller.cpp5
-rw-r--r--src/core/hle/service/am/applets/controller.h3
-rw-r--r--src/core/hle/service/am/applets/error.cpp5
-rw-r--r--src/core/hle/service/am/applets/error.h3
-rw-r--r--src/core/hle/service/am/applets/general_backend.cpp14
-rw-r--r--src/core/hle/service/am/applets/general_backend.h8
-rw-r--r--src/core/hle/service/am/applets/profile_select.cpp4
-rw-r--r--src/core/hle/service/am/applets/profile_select.h2
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.cpp1153
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.h186
-rw-r--r--src/core/hle/service/am/applets/software_keyboard_types.h295
-rw-r--r--src/core/hle/service/am/applets/web_browser.cpp5
-rw-r--r--src/core/hle/service/am/applets/web_browser.h3
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp2
-rw-r--r--src/core/hle/service/apm/controller.cpp2
-rw-r--r--src/core/hle/service/bcat/backend/boxcat.cpp2
-rw-r--r--src/core/hle/service/bcat/module.cpp2
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp2
-rw-r--r--src/core/hle/service/glue/arp.cpp10
-rw-r--r--src/core/hle/service/glue/ectx.cpp22
-rw-r--r--src/core/hle/service/glue/ectx.h21
-rw-r--r--src/core/hle/service/glue/glue.cpp4
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.h2
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.h2
-rw-r--r--src/core/hle/service/hid/controllers/mouse.h2
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp4
-rw-r--r--src/core/hle/service/hid/controllers/npad.h3
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp2
-rw-r--r--src/core/hle/service/hid/hid.cpp41
-rw-r--r--src/core/hle/service/lbl/lbl.cpp2
-rw-r--r--src/core/hle/service/lm/lm.cpp13
-rw-r--r--src/core/hle/service/nfc/nfc.cpp2
-rw-r--r--src/core/hle/service/nifm/nifm.cpp2
-rw-r--r--src/core/hle/service/ns/ns.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp14
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp12
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp2
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/core/hle/service/set/set.cpp5
-rw-r--r--src/core/hle/service/spl/module.cpp2
-rw-r--r--src/core/hle/service/time/time.cpp8
-rw-r--r--src/core/hle/service/time/time_manager.cpp2
-rw-r--r--src/core/hle/service/time/time_zone_content_manager.cpp2
-rw-r--r--src/core/hle/service/time/time_zone_service.cpp6
-rw-r--r--src/core/hle/service/vi/vi.cpp10
-rw-r--r--src/core/loader/kip.cpp3
-rw-r--r--src/core/loader/nro.cpp2
-rw-r--r--src/core/loader/nso.cpp2
-rw-r--r--src/core/perf_stats.cpp2
-rw-r--r--src/core/reporter.cpp2
-rw-r--r--src/core/telemetry_session.cpp2
-rw-r--r--src/input_common/CMakeLists.txt4
-rwxr-xr-xsrc/input_common/analog_from_button.cpp2
-rw-r--r--src/input_common/gcadapter/gc_adapter.cpp2
-rw-r--r--src/input_common/mouse/mouse_input.cpp2
-rw-r--r--src/input_common/mouse/mouse_poller.cpp2
-rw-r--r--src/input_common/sdl/sdl_impl.cpp38
-rw-r--r--src/input_common/sdl/sdl_impl.h4
-rw-r--r--src/input_common/touch_from_button.cpp2
-rw-r--r--src/input_common/udp/client.cpp2
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h2
-rw-r--r--src/video_core/engines/maxwell_dma.cpp2
-rw-r--r--src/video_core/gpu.cpp12
-rw-r--r--src/video_core/gpu.h3
-rw-r--r--src/video_core/gpu_thread.cpp2
-rw-r--r--src/video_core/macro/macro.cpp2
-rw-r--r--src/video_core/query_cache.h2
-rw-r--r--src/video_core/renderer_base.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.cpp2
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp2
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_master_semaphore.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp25
-rw-r--r--src/video_core/texture_cache/image_view_base.cpp2
-rw-r--r--src/video_core/texture_cache/util.cpp2
-rw-r--r--src/video_core/textures/texture.cpp2
-rw-r--r--src/video_core/video_core.cpp2
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp2
-rw-r--r--src/yuzu/CMakeLists.txt4
-rw-r--r--src/yuzu/applets/error.cpp22
-rw-r--r--src/yuzu/applets/error.h2
-rw-r--r--src/yuzu/applets/software_keyboard.cpp1712
-rw-r--r--src/yuzu/applets/software_keyboard.h283
-rw-r--r--src/yuzu/applets/software_keyboard.ui3503
-rw-r--r--src/yuzu/bootmanager.cpp2
-rw-r--r--src/yuzu/configuration/config.cpp24
-rw-r--r--src/yuzu/configuration/config.h4
-rw-r--r--src/yuzu/configuration/configuration_shared.cpp2
-rw-r--r--src/yuzu/configuration/configuration_shared.h2
-rw-r--r--src/yuzu/configuration/configure_audio.cpp2
-rw-r--r--src/yuzu/configuration/configure_cpu.cpp2
-rw-r--r--src/yuzu/configuration/configure_cpu.h2
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.cpp2
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.h2
-rw-r--r--src/yuzu/configuration/configure_debug.cpp8
-rw-r--r--src/yuzu/configuration/configure_debug.ui7
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp4
-rw-r--r--src/yuzu/configuration/configure_filesystem.cpp2
-rw-r--r--src/yuzu/configuration/configure_general.cpp2
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp2
-rw-r--r--src/yuzu/configuration/configure_graphics.h2
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.cpp2
-rw-r--r--src/yuzu/configuration/configure_hotkeys.cpp2
-rw-r--r--src/yuzu/configuration/configure_input_advanced.cpp2
-rw-r--r--src/yuzu/configuration/configure_input_player.h2
-rw-r--r--src/yuzu/configuration/configure_input_player_widget.h2
-rw-r--r--src/yuzu/configuration/configure_motion_touch.cpp2
-rw-r--r--src/yuzu/configuration/configure_per_game.cpp2
-rw-r--r--src/yuzu/configuration/configure_profile_manager.cpp4
-rw-r--r--src/yuzu/configuration/configure_service.cpp2
-rw-r--r--src/yuzu/configuration/configure_system.cpp4
-rw-r--r--src/yuzu/configuration/configure_touch_from_button.cpp2
-rw-r--r--src/yuzu/configuration/configure_ui.cpp4
-rw-r--r--src/yuzu/configuration/configure_vibration.cpp2
-rw-r--r--src/yuzu/configuration/configure_web.cpp2
-rw-r--r--src/yuzu/debugger/console.cpp8
-rw-r--r--src/yuzu/debugger/controller.cpp2
-rw-r--r--src/yuzu/main.cpp203
-rw-r--r--src/yuzu/main.h35
-rw-r--r--src/yuzu/util/overlay_dialog.cpp249
-rw-r--r--src/yuzu/util/overlay_dialog.h107
-rw-r--r--src/yuzu/util/overlay_dialog.ui404
-rw-r--r--src/yuzu_cmd/CMakeLists.txt1
-rw-r--r--src/yuzu_cmd/config.cpp16
-rw-r--r--src/yuzu_cmd/default_ini.h6
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp11
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.h2
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp12
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp10
-rw-r--r--src/yuzu_cmd/resource.h16
-rw-r--r--src/yuzu_cmd/yuzu.cpp10
186 files changed, 8742 insertions, 828 deletions
diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp
index fe3a898ad..20a756dce 100644
--- a/src/audio_core/audio_out.cpp
+++ b/src/audio_core/audio_out.cpp
@@ -7,7 +7,7 @@
7#include "audio_core/sink_details.h" 7#include "audio_core/sink_details.h"
8#include "common/assert.h" 8#include "common/assert.h"
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "core/settings.h" 10#include "common/settings.h"
11 11
12namespace AudioCore { 12namespace AudioCore {
13 13
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index d2ce8c814..ae2201c36 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -11,8 +11,8 @@
11#include "audio_core/info_updater.h" 11#include "audio_core/info_updater.h"
12#include "audio_core/voice_context.h" 12#include "audio_core/voice_context.h"
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "common/settings.h"
14#include "core/memory.h" 15#include "core/memory.h"
15#include "core/settings.h"
16 16
17namespace { 17namespace {
18[[nodiscard]] static constexpr s16 ClampToS16(s32 value) { 18[[nodiscard]] static constexpr s16 ClampToS16(s32 value) {
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp
index 043447eaa..93c35e785 100644
--- a/src/audio_core/cubeb_sink.cpp
+++ b/src/audio_core/cubeb_sink.cpp
@@ -11,7 +11,7 @@
11#include "common/assert.h" 11#include "common/assert.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "common/ring_buffer.h" 13#include "common/ring_buffer.h"
14#include "core/settings.h" 14#include "common/settings.h"
15 15
16#ifdef _WIN32 16#ifdef _WIN32
17#include <objbase.h> 17#include <objbase.h>
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index b0f6f0c34..ad6c587c2 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -11,8 +11,8 @@
11#include "audio_core/stream.h" 11#include "audio_core/stream.h"
12#include "common/assert.h" 12#include "common/assert.h"
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "common/settings.h"
14#include "core/core_timing.h" 15#include "core/core_timing.h"
15#include "core/settings.h"
16 16
17namespace AudioCore { 17namespace AudioCore {
18 18
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 9f8dafa3b..88644eeb6 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -152,6 +152,10 @@ add_library(common STATIC
152 scm_rev.cpp 152 scm_rev.cpp
153 scm_rev.h 153 scm_rev.h
154 scope_exit.h 154 scope_exit.h
155 settings.cpp
156 settings.h
157 settings_input.cpp
158 settings_input.h
155 spin_lock.cpp 159 spin_lock.cpp
156 spin_lock.h 160 spin_lock.h
157 stream.cpp 161 stream.cpp
diff --git a/src/common/assert.cpp b/src/common/assert.cpp
index d7d91b96b..72f1121aa 100644
--- a/src/common/assert.cpp
+++ b/src/common/assert.cpp
@@ -3,9 +3,12 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/assert.h" 5#include "common/assert.h"
6
7#include "common/common_funcs.h" 6#include "common/common_funcs.h"
8 7
8#include "common/settings.h"
9
9void assert_handle_failure() { 10void assert_handle_failure() {
10 Crash(); 11 if (Settings::values.use_debug_asserts) {
12 Crash();
13 }
11} 14}
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 4575df24d..96efa977d 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -21,11 +21,11 @@
21#include "common/logging/backend.h" 21#include "common/logging/backend.h"
22#include "common/logging/log.h" 22#include "common/logging/log.h"
23#include "common/logging/text_formatter.h" 23#include "common/logging/text_formatter.h"
24#include "common/settings.h"
24#include "common/string_util.h" 25#include "common/string_util.h"
25#include "common/threadsafe_queue.h" 26#include "common/threadsafe_queue.h"
26#include "core/settings.h"
27 27
28namespace Log { 28namespace Common::Log {
29 29
30/** 30/**
31 * Static state as a singleton. 31 * Static state as a singleton.
@@ -37,8 +37,11 @@ public:
37 return backend; 37 return backend;
38 } 38 }
39 39
40 Impl(Impl const&) = delete; 40 Impl(const Impl&) = delete;
41 const Impl& operator=(Impl const&) = delete; 41 Impl& operator=(const Impl&) = delete;
42
43 Impl(Impl&&) = delete;
44 Impl& operator=(Impl&&) = delete;
42 45
43 void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, 46 void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num,
44 const char* function, std::string message) { 47 const char* function, std::string message) {
@@ -53,10 +56,10 @@ public:
53 56
54 void RemoveBackend(std::string_view backend_name) { 57 void RemoveBackend(std::string_view backend_name) {
55 std::lock_guard lock{writing_mutex}; 58 std::lock_guard lock{writing_mutex};
56 const auto it = 59
57 std::remove_if(backends.begin(), backends.end(), 60 std::erase_if(backends, [&backend_name](const auto& backend) {
58 [&backend_name](const auto& i) { return backend_name == i->GetName(); }); 61 return backend_name == backend->GetName();
59 backends.erase(it, backends.end()); 62 });
60 } 63 }
61 64
62 const Filter& GetGlobalFilter() const { 65 const Filter& GetGlobalFilter() const {
@@ -132,7 +135,7 @@ private:
132 std::mutex writing_mutex; 135 std::mutex writing_mutex;
133 std::thread backend_thread; 136 std::thread backend_thread;
134 std::vector<std::unique_ptr<Backend>> backends; 137 std::vector<std::unique_ptr<Backend>> backends;
135 Common::MPSCQueue<Log::Entry> message_queue; 138 MPSCQueue<Entry> message_queue;
136 Filter filter; 139 Filter filter;
137 std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; 140 std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
138}; 141};
@@ -145,17 +148,19 @@ void ColorConsoleBackend::Write(const Entry& entry) {
145 PrintColoredMessage(entry); 148 PrintColoredMessage(entry);
146} 149}
147 150
148FileBackend::FileBackend(const std::string& filename) : bytes_written(0) { 151FileBackend::FileBackend(const std::string& filename) {
149 if (Common::FS::Exists(filename + ".old.txt")) { 152 const auto old_filename = filename + ".old.txt";
150 Common::FS::Delete(filename + ".old.txt"); 153
154 if (FS::Exists(old_filename)) {
155 FS::Delete(old_filename);
151 } 156 }
152 if (Common::FS::Exists(filename)) { 157 if (FS::Exists(filename)) {
153 Common::FS::Rename(filename, filename + ".old.txt"); 158 FS::Rename(filename, old_filename);
154 } 159 }
155 160
156 // _SH_DENYWR allows read only access to the file for other programs. 161 // _SH_DENYWR allows read only access to the file for other programs.
157 // It is #defined to 0 on other platforms 162 // It is #defined to 0 on other platforms
158 file = Common::FS::IOFile(filename, "w", _SH_DENYWR); 163 file = FS::IOFile(filename, "w", _SH_DENYWR);
159} 164}
160 165
161void FileBackend::Write(const Entry& entry) { 166void FileBackend::Write(const Entry& entry) {
@@ -182,7 +187,7 @@ void FileBackend::Write(const Entry& entry) {
182 187
183void DebuggerBackend::Write(const Entry& entry) { 188void DebuggerBackend::Write(const Entry& entry) {
184#ifdef _WIN32 189#ifdef _WIN32
185 ::OutputDebugStringW(Common::UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str()); 190 ::OutputDebugStringW(UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str());
186#endif 191#endif
187} 192}
188 193
@@ -342,4 +347,4 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
342 instance.PushEntry(log_class, log_level, filename, line_num, function, 347 instance.PushEntry(log_class, log_level, filename, line_num, function,
343 fmt::vformat(format, args)); 348 fmt::vformat(format, args));
344} 349}
345} // namespace Log 350} // namespace Common::Log
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h
index da1c2f185..9dd2589c3 100644
--- a/src/common/logging/backend.h
+++ b/src/common/logging/backend.h
@@ -11,7 +11,7 @@
11#include "common/logging/filter.h" 11#include "common/logging/filter.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13 13
14namespace Log { 14namespace Common::Log {
15 15
16class Filter; 16class Filter;
17 17
@@ -94,8 +94,8 @@ public:
94 void Write(const Entry& entry) override; 94 void Write(const Entry& entry) override;
95 95
96private: 96private:
97 Common::FS::IOFile file; 97 FS::IOFile file;
98 std::size_t bytes_written; 98 std::size_t bytes_written = 0;
99}; 99};
100 100
101/** 101/**
@@ -135,4 +135,4 @@ const char* GetLevelName(Level log_level);
135 * never get the message 135 * never get the message
136 */ 136 */
137void SetGlobalFilter(const Filter& filter); 137void SetGlobalFilter(const Filter& filter);
138} // namespace Log \ No newline at end of file 138} // namespace Common::Log \ No newline at end of file
diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp
index 2eccbcd8d..20a2dd106 100644
--- a/src/common/logging/filter.cpp
+++ b/src/common/logging/filter.cpp
@@ -7,7 +7,7 @@
7#include "common/logging/filter.h" 7#include "common/logging/filter.h"
8#include "common/string_util.h" 8#include "common/string_util.h"
9 9
10namespace Log { 10namespace Common::Log {
11namespace { 11namespace {
12template <typename It> 12template <typename It>
13Level GetLevelByName(const It begin, const It end) { 13Level GetLevelByName(const It begin, const It end) {
@@ -103,4 +103,4 @@ bool Filter::IsDebug() const {
103 }); 103 });
104} 104}
105 105
106} // namespace Log 106} // namespace Common::Log
diff --git a/src/common/logging/filter.h b/src/common/logging/filter.h
index 773df6f2c..f5673a9f6 100644
--- a/src/common/logging/filter.h
+++ b/src/common/logging/filter.h
@@ -9,7 +9,7 @@
9#include <string_view> 9#include <string_view>
10#include "common/logging/log.h" 10#include "common/logging/log.h"
11 11
12namespace Log { 12namespace Common::Log {
13 13
14/** 14/**
15 * Implements a log message filter which allows different log classes to have different minimum 15 * Implements a log message filter which allows different log classes to have different minimum
@@ -51,4 +51,4 @@ public:
51private: 51private:
52 std::array<Level, static_cast<std::size_t>(Class::Count)> class_levels; 52 std::array<Level, static_cast<std::size_t>(Class::Count)> class_levels;
53}; 53};
54} // namespace Log 54} // namespace Common::Log
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 3d7b7dab7..1f0f8db52 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -7,7 +7,7 @@
7#include <fmt/format.h> 7#include <fmt/format.h>
8#include "common/common_types.h" 8#include "common/common_types.h"
9 9
10namespace Log { 10namespace Common::Log {
11 11
12// trims up to and including the last of ../, ..\, src/, src\ in a string 12// trims up to and including the last of ../, ..\, src/, src\ in a string
13constexpr const char* TrimSourcePath(std::string_view source) { 13constexpr const char* TrimSourcePath(std::string_view source) {
@@ -148,28 +148,34 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig
148 fmt::make_format_args(args...)); 148 fmt::make_format_args(args...));
149} 149}
150 150
151} // namespace Log 151} // namespace Common::Log
152 152
153#ifdef _DEBUG 153#ifdef _DEBUG
154#define LOG_TRACE(log_class, ...) \ 154#define LOG_TRACE(log_class, ...) \
155 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Trace, \ 155 Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \
156 ::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__) 156 Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
157 __VA_ARGS__)
157#else 158#else
158#define LOG_TRACE(log_class, fmt, ...) (void(0)) 159#define LOG_TRACE(log_class, fmt, ...) (void(0))
159#endif 160#endif
160 161
161#define LOG_DEBUG(log_class, ...) \ 162#define LOG_DEBUG(log_class, ...) \
162 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Debug, \ 163 Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \
163 ::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__) 164 Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
165 __VA_ARGS__)
164#define LOG_INFO(log_class, ...) \ 166#define LOG_INFO(log_class, ...) \
165 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Info, \ 167 Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \
166 ::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__) 168 Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
169 __VA_ARGS__)
167#define LOG_WARNING(log_class, ...) \ 170#define LOG_WARNING(log_class, ...) \
168 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Warning, \ 171 Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \
169 ::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__) 172 Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
173 __VA_ARGS__)
170#define LOG_ERROR(log_class, ...) \ 174#define LOG_ERROR(log_class, ...) \
171 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Error, \ 175 Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \
172 ::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__) 176 Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
177 __VA_ARGS__)
173#define LOG_CRITICAL(log_class, ...) \ 178#define LOG_CRITICAL(log_class, ...) \
174 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Critical, \ 179 Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \
175 ::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__) 180 Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
181 __VA_ARGS__)
diff --git a/src/common/logging/text_formatter.cpp b/src/common/logging/text_formatter.cpp
index 6a0605c63..80ee2cca1 100644
--- a/src/common/logging/text_formatter.cpp
+++ b/src/common/logging/text_formatter.cpp
@@ -16,7 +16,7 @@
16#include "common/logging/text_formatter.h" 16#include "common/logging/text_formatter.h"
17#include "common/string_util.h" 17#include "common/string_util.h"
18 18
19namespace Log { 19namespace Common::Log {
20 20
21std::string FormatLogMessage(const Entry& entry) { 21std::string FormatLogMessage(const Entry& entry) {
22 unsigned int time_seconds = static_cast<unsigned int>(entry.timestamp.count() / 1000000); 22 unsigned int time_seconds = static_cast<unsigned int>(entry.timestamp.count() / 1000000);
@@ -108,4 +108,4 @@ void PrintColoredMessage(const Entry& entry) {
108#undef ESC 108#undef ESC
109#endif 109#endif
110} 110}
111} // namespace Log 111} // namespace Common::Log
diff --git a/src/common/logging/text_formatter.h b/src/common/logging/text_formatter.h
index b6d9e57c8..171e74cfe 100644
--- a/src/common/logging/text_formatter.h
+++ b/src/common/logging/text_formatter.h
@@ -7,7 +7,7 @@
7#include <cstddef> 7#include <cstddef>
8#include <string> 8#include <string>
9 9
10namespace Log { 10namespace Common::Log {
11 11
12struct Entry; 12struct Entry;
13 13
@@ -17,4 +17,4 @@ std::string FormatLogMessage(const Entry& entry);
17void PrintMessage(const Entry& entry); 17void PrintMessage(const Entry& entry);
18/// Prints the same message as `PrintMessage`, but colored according to the severity level. 18/// Prints the same message as `PrintMessage`, but colored according to the severity level.
19void PrintColoredMessage(const Entry& entry); 19void PrintColoredMessage(const Entry& entry);
20} // namespace Log 20} // namespace Common::Log
diff --git a/src/core/settings.cpp b/src/common/settings.cpp
index 2ae5196e0..702b6598d 100644
--- a/src/core/settings.cpp
+++ b/src/common/settings.cpp
@@ -1,4 +1,4 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2021 yuzu Emulator Project
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
@@ -7,10 +7,7 @@
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/file_util.h" 8#include "common/file_util.h"
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "core/core.h" 10#include "common/settings.h"
11#include "core/hle/service/hid/hid.h"
12#include "core/settings.h"
13#include "video_core/renderer_base.h"
14 11
15namespace Settings { 12namespace Settings {
16 13
@@ -32,14 +29,6 @@ std::string GetTimeZoneString() {
32 return timezones[time_zone_index]; 29 return timezones[time_zone_index];
33} 30}
34 31
35void Apply(Core::System& system) {
36 if (system.IsPoweredOn()) {
37 system.Renderer().RefreshBaseSettings();
38 }
39
40 Service::HID::ReloadInputDevices();
41}
42
43void LogSettings() { 32void LogSettings() {
44 const auto log_setting = [](std::string_view name, const auto& value) { 33 const auto log_setting = [](std::string_view name, const auto& value) {
45 LOG_INFO(Config, "{}: {}", name, value); 34 LOG_INFO(Config, "{}: {}", name, value);
diff --git a/src/core/settings.h b/src/common/settings.h
index 6c03a6ea9..d39b4aa45 100644
--- a/src/core/settings.h
+++ b/src/common/settings.h
@@ -1,4 +1,4 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2021 yuzu Emulator Project
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
@@ -11,16 +11,13 @@
11#include <optional> 11#include <optional>
12#include <string> 12#include <string>
13#include <vector> 13#include <vector>
14#include "common/common_types.h"
15#include "input_common/settings.h"
16 14
17namespace Core { 15#include "common/common_types.h"
18class System; 16#include "common/settings_input.h"
19}
20 17
21namespace Settings { 18namespace Settings {
22 19
23enum class RendererBackend { 20enum class RendererBackend : u32 {
24 OpenGL = 0, 21 OpenGL = 0,
25 Vulkan = 1, 22 Vulkan = 1,
26}; 23};
@@ -31,7 +28,7 @@ enum class GPUAccuracy : u32 {
31 Extreme = 2, 28 Extreme = 2,
32}; 29};
33 30
34enum class CPUAccuracy { 31enum class CPUAccuracy : u32 {
35 Accurate = 0, 32 Accurate = 0,
36 Unsafe = 1, 33 Unsafe = 1,
37 DebugMode = 2, 34 DebugMode = 2,
@@ -223,6 +220,7 @@ struct Values {
223 bool quest_flag; 220 bool quest_flag;
224 bool disable_macro_jit; 221 bool disable_macro_jit;
225 bool extended_logging; 222 bool extended_logging;
223 bool use_debug_asserts;
226 bool use_auto_stub; 224 bool use_auto_stub;
227 225
228 // Miscellaneous 226 // Miscellaneous
@@ -255,7 +253,6 @@ float Volume();
255 253
256std::string GetTimeZoneString(); 254std::string GetTimeZoneString();
257 255
258void Apply(Core::System& system);
259void LogSettings(); 256void LogSettings();
260 257
261// Restore the global state of all applicable settings in the Values struct 258// Restore the global state of all applicable settings in the Values struct
diff --git a/src/input_common/settings.cpp b/src/common/settings_input.cpp
index 557e7a9a0..bea2b837b 100644
--- a/src/input_common/settings.cpp
+++ b/src/common/settings_input.cpp
@@ -2,7 +2,7 @@
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 "input_common/settings.h" 5#include "common/settings_input.h"
6 6
7namespace Settings { 7namespace Settings {
8namespace NativeButton { 8namespace NativeButton {
diff --git a/src/input_common/settings.h b/src/common/settings_input.h
index a59f5d461..609600582 100644
--- a/src/input_common/settings.h
+++ b/src/common/settings_input.h
@@ -6,6 +6,7 @@
6 6
7#include <array> 7#include <array>
8#include <string> 8#include <string>
9
9#include "common/common_types.h" 10#include "common/common_types.h"
10 11
11namespace Settings { 12namespace Settings {
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 167ee13f3..04cf3f5b9 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -273,6 +273,7 @@ add_library(core STATIC
273 hle/service/am/applets/profile_select.h 273 hle/service/am/applets/profile_select.h
274 hle/service/am/applets/software_keyboard.cpp 274 hle/service/am/applets/software_keyboard.cpp
275 hle/service/am/applets/software_keyboard.h 275 hle/service/am/applets/software_keyboard.h
276 hle/service/am/applets/software_keyboard_types.h
276 hle/service/am/applets/web_browser.cpp 277 hle/service/am/applets/web_browser.cpp
277 hle/service/am/applets/web_browser.h 278 hle/service/am/applets/web_browser.h
278 hle/service/am/applets/web_types.h 279 hle/service/am/applets/web_types.h
@@ -376,6 +377,8 @@ add_library(core STATIC
376 hle/service/glue/arp.h 377 hle/service/glue/arp.h
377 hle/service/glue/bgtc.cpp 378 hle/service/glue/bgtc.cpp
378 hle/service/glue/bgtc.h 379 hle/service/glue/bgtc.h
380 hle/service/glue/ectx.cpp
381 hle/service/glue/ectx.h
379 hle/service/glue/errors.h 382 hle/service/glue/errors.h
380 hle/service/glue/glue.cpp 383 hle/service/glue/glue.cpp
381 hle/service/glue/glue.h 384 hle/service/glue/glue.h
@@ -621,8 +624,6 @@ add_library(core STATIC
621 perf_stats.h 624 perf_stats.h
622 reporter.cpp 625 reporter.cpp
623 reporter.h 626 reporter.h
624 settings.cpp
625 settings.h
626 telemetry_session.cpp 627 telemetry_session.cpp
627 telemetry_session.h 628 telemetry_session.h
628 tools/freezer.cpp 629 tools/freezer.cpp
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 08d889135..7aeb2a658 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -10,6 +10,7 @@
10#include "common/assert.h" 10#include "common/assert.h"
11#include "common/logging/log.h" 11#include "common/logging/log.h"
12#include "common/page_table.h" 12#include "common/page_table.h"
13#include "common/settings.h"
13#include "core/arm/cpu_interrupt_handler.h" 14#include "core/arm/cpu_interrupt_handler.h"
14#include "core/arm/dynarmic/arm_dynarmic_32.h" 15#include "core/arm/dynarmic/arm_dynarmic_32.h"
15#include "core/arm/dynarmic/arm_dynarmic_cp15.h" 16#include "core/arm/dynarmic/arm_dynarmic_cp15.h"
@@ -18,7 +19,6 @@
18#include "core/core_timing.h" 19#include "core/core_timing.h"
19#include "core/hle/kernel/svc.h" 20#include "core/hle/kernel/svc.h"
20#include "core/memory.h" 21#include "core/memory.h"
21#include "core/settings.h"
22 22
23namespace Core { 23namespace Core {
24 24
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index e12e50658..040529f4d 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -9,6 +9,7 @@
9#include "common/assert.h" 9#include "common/assert.h"
10#include "common/logging/log.h" 10#include "common/logging/log.h"
11#include "common/page_table.h" 11#include "common/page_table.h"
12#include "common/settings.h"
12#include "core/arm/cpu_interrupt_handler.h" 13#include "core/arm/cpu_interrupt_handler.h"
13#include "core/arm/dynarmic/arm_dynarmic_64.h" 14#include "core/arm/dynarmic/arm_dynarmic_64.h"
14#include "core/arm/dynarmic/arm_exclusive_monitor.h" 15#include "core/arm/dynarmic/arm_exclusive_monitor.h"
@@ -19,7 +20,6 @@
19#include "core/hle/kernel/process.h" 20#include "core/hle/kernel/process.h"
20#include "core/hle/kernel/svc.h" 21#include "core/hle/kernel/svc.h"
21#include "core/memory.h" 22#include "core/memory.h"
22#include "core/settings.h"
23 23
24namespace Core { 24namespace Core {
25 25
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 56b47e671..d459d6c34 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -9,6 +9,7 @@
9#include "common/file_util.h" 9#include "common/file_util.h"
10#include "common/logging/log.h" 10#include "common/logging/log.h"
11#include "common/microprofile.h" 11#include "common/microprofile.h"
12#include "common/settings.h"
12#include "common/string_util.h" 13#include "common/string_util.h"
13#include "core/arm/exclusive_monitor.h" 14#include "core/arm/exclusive_monitor.h"
14#include "core/core.h" 15#include "core/core.h"
@@ -36,6 +37,7 @@
36#include "core/hle/service/apm/controller.h" 37#include "core/hle/service/apm/controller.h"
37#include "core/hle/service/filesystem/filesystem.h" 38#include "core/hle/service/filesystem/filesystem.h"
38#include "core/hle/service/glue/manager.h" 39#include "core/hle/service/glue/manager.h"
40#include "core/hle/service/hid/hid.h"
39#include "core/hle/service/service.h" 41#include "core/hle/service/service.h"
40#include "core/hle/service/sm/sm.h" 42#include "core/hle/service/sm/sm.h"
41#include "core/hle/service/time/time_manager.h" 43#include "core/hle/service/time/time_manager.h"
@@ -45,7 +47,6 @@
45#include "core/network/network.h" 47#include "core/network/network.h"
46#include "core/perf_stats.h" 48#include "core/perf_stats.h"
47#include "core/reporter.h" 49#include "core/reporter.h"
48#include "core/settings.h"
49#include "core/telemetry_session.h" 50#include "core/telemetry_session.h"
50#include "core/tools/freezer.h" 51#include "core/tools/freezer.h"
51#include "video_core/renderer_base.h" 52#include "video_core/renderer_base.h"
@@ -774,4 +775,12 @@ void System::ExecuteProgram(std::size_t program_index) {
774 } 775 }
775} 776}
776 777
778void System::ApplySettings() {
779 if (IsPoweredOn()) {
780 Renderer().RefreshBaseSettings();
781 }
782
783 Service::HID::ReloadInputDevices();
784}
785
777} // namespace Core 786} // namespace Core
diff --git a/src/core/core.h b/src/core/core.h
index 3a8e040c1..f1068d23f 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -388,6 +388,9 @@ public:
388 */ 388 */
389 void ExecuteProgram(std::size_t program_index); 389 void ExecuteProgram(std::size_t program_index);
390 390
391 /// Applies any changes to settings to this core instance.
392 void ApplySettings();
393
391private: 394private:
392 System(); 395 System();
393 396
diff --git a/src/core/crypto/aes_util.cpp b/src/core/crypto/aes_util.cpp
index cb7506241..85a666de9 100644
--- a/src/core/crypto/aes_util.cpp
+++ b/src/core/crypto/aes_util.cpp
@@ -119,9 +119,9 @@ void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, std::size_t size, u8*
119} 119}
120 120
121template <typename Key, std::size_t KeySize> 121template <typename Key, std::size_t KeySize>
122void AESCipher<Key, KeySize>::SetIVImpl(const u8* data, std::size_t size) { 122void AESCipher<Key, KeySize>::SetIV(std::span<const u8> data) {
123 ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, data, size) || 123 ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, data.data(), data.size()) ||
124 mbedtls_cipher_set_iv(&ctx->decryption_context, data, size)) == 0, 124 mbedtls_cipher_set_iv(&ctx->decryption_context, data.data(), data.size())) == 0,
125 "Failed to set IV on mbedtls ciphers."); 125 "Failed to set IV on mbedtls ciphers.");
126} 126}
127 127
diff --git a/src/core/crypto/aes_util.h b/src/core/crypto/aes_util.h
index e2a304186..230451b8f 100644
--- a/src/core/crypto/aes_util.h
+++ b/src/core/crypto/aes_util.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <span>
8#include <type_traits> 9#include <type_traits>
9#include "common/common_types.h" 10#include "common/common_types.h"
10#include "core/file_sys/vfs.h" 11#include "core/file_sys/vfs.h"
@@ -33,10 +34,7 @@ public:
33 AESCipher(Key key, Mode mode); 34 AESCipher(Key key, Mode mode);
34 ~AESCipher(); 35 ~AESCipher();
35 36
36 template <typename ContiguousContainer> 37 void SetIV(std::span<const u8> data);
37 void SetIV(const ContiguousContainer& container) {
38 SetIVImpl(std::data(container), std::size(container));
39 }
40 38
41 template <typename Source, typename Dest> 39 template <typename Source, typename Dest>
42 void Transcode(const Source* src, std::size_t size, Dest* dest, Op op) const { 40 void Transcode(const Source* src, std::size_t size, Dest* dest, Op op) const {
@@ -60,8 +58,6 @@ public:
60 std::size_t sector_size, Op op); 58 std::size_t sector_size, Op op);
61 59
62private: 60private:
63 void SetIVImpl(const u8* data, std::size_t size);
64
65 std::unique_ptr<CipherContext> ctx; 61 std::unique_ptr<CipherContext> ctx;
66}; 62};
67} // namespace Core::Crypto 63} // namespace Core::Crypto
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp
index ad116dcc0..070ed439e 100644
--- a/src/core/crypto/key_manager.cpp
+++ b/src/core/crypto/key_manager.cpp
@@ -22,6 +22,7 @@
22#include "common/file_util.h" 22#include "common/file_util.h"
23#include "common/hex_util.h" 23#include "common/hex_util.h"
24#include "common/logging/log.h" 24#include "common/logging/log.h"
25#include "common/settings.h"
25#include "common/string_util.h" 26#include "common/string_util.h"
26#include "core/crypto/aes_util.h" 27#include "core/crypto/aes_util.h"
27#include "core/crypto/key_manager.h" 28#include "core/crypto/key_manager.h"
@@ -32,7 +33,6 @@
32#include "core/file_sys/registered_cache.h" 33#include "core/file_sys/registered_cache.h"
33#include "core/hle/service/filesystem/filesystem.h" 34#include "core/hle/service/filesystem/filesystem.h"
34#include "core/loader/loader.h" 35#include "core/loader/loader.h"
35#include "core/settings.h"
36 36
37namespace Core::Crypto { 37namespace Core::Crypto {
38namespace { 38namespace {
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index 7c3284df8..cc9b4b637 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -10,6 +10,7 @@
10#include "common/file_util.h" 10#include "common/file_util.h"
11#include "common/hex_util.h" 11#include "common/hex_util.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "common/settings.h"
13#include "common/string_util.h" 14#include "common/string_util.h"
14#include "core/core.h" 15#include "core/core.h"
15#include "core/file_sys/common_funcs.h" 16#include "core/file_sys/common_funcs.h"
@@ -25,7 +26,6 @@
25#include "core/loader/loader.h" 26#include "core/loader/loader.h"
26#include "core/loader/nso.h" 27#include "core/loader/nso.h"
27#include "core/memory/cheat_engine.h" 28#include "core/memory/cheat_engine.h"
28#include "core/settings.h"
29 29
30namespace FileSys { 30namespace FileSys {
31namespace { 31namespace {
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp
index 9cf49bf44..83b83a044 100644
--- a/src/core/file_sys/program_metadata.cpp
+++ b/src/core/file_sys/program_metadata.cpp
@@ -58,7 +58,8 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) {
58 result.LoadManual( 58 result.LoadManual(
59 true /*is_64_bit*/, FileSys::ProgramAddressSpaceType::Is39Bit /*address_space*/, 59 true /*is_64_bit*/, FileSys::ProgramAddressSpaceType::Is39Bit /*address_space*/,
60 0x2c /*main_thread_prio*/, 0 /*main_thread_core*/, 0x00100000 /*main_thread_stack_size*/, 60 0x2c /*main_thread_prio*/, 0 /*main_thread_core*/, 0x00100000 /*main_thread_stack_size*/,
61 {}, 0xFFFFFFFFFFFFFFFF /*filesystem_permissions*/, {} /*capabilities*/); 61 0 /*title_id*/, 0xFFFFFFFFFFFFFFFF /*filesystem_permissions*/,
62 0x1FE00000 /*system_resource_size*/, {} /*capabilities*/);
62 63
63 return result; 64 return result;
64} 65}
@@ -66,7 +67,7 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) {
66void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, 67void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space,
67 s32 main_thread_prio, u32 main_thread_core, 68 s32 main_thread_prio, u32 main_thread_core,
68 u32 main_thread_stack_size, u64 title_id, 69 u32 main_thread_stack_size, u64 title_id,
69 u64 filesystem_permissions, 70 u64 filesystem_permissions, u32 system_resource_size,
70 KernelCapabilityDescriptors capabilities) { 71 KernelCapabilityDescriptors capabilities) {
71 npdm_header.has_64_bit_instructions.Assign(is_64_bit); 72 npdm_header.has_64_bit_instructions.Assign(is_64_bit);
72 npdm_header.address_space_type.Assign(address_space); 73 npdm_header.address_space_type.Assign(address_space);
@@ -75,6 +76,7 @@ void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address
75 npdm_header.main_stack_size = main_thread_stack_size; 76 npdm_header.main_stack_size = main_thread_stack_size;
76 aci_header.title_id = title_id; 77 aci_header.title_id = title_id;
77 aci_file_access.permissions = filesystem_permissions; 78 aci_file_access.permissions = filesystem_permissions;
79 npdm_header.system_resource_size = system_resource_size;
78 aci_kernel_capabilities = std ::move(capabilities); 80 aci_kernel_capabilities = std ::move(capabilities);
79} 81}
80 82
diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h
index 455532567..1eee916be 100644
--- a/src/core/file_sys/program_metadata.h
+++ b/src/core/file_sys/program_metadata.h
@@ -44,6 +44,12 @@ public:
44 ProgramMetadata(); 44 ProgramMetadata();
45 ~ProgramMetadata(); 45 ~ProgramMetadata();
46 46
47 ProgramMetadata(const ProgramMetadata&) = default;
48 ProgramMetadata& operator=(const ProgramMetadata&) = default;
49
50 ProgramMetadata(ProgramMetadata&&) = default;
51 ProgramMetadata& operator=(ProgramMetadata&&) = default;
52
47 /// Gets a default ProgramMetadata configuration, should only be used for homebrew formats where 53 /// Gets a default ProgramMetadata configuration, should only be used for homebrew formats where
48 /// we do not have an NPDM file 54 /// we do not have an NPDM file
49 static ProgramMetadata GetDefault(); 55 static ProgramMetadata GetDefault();
@@ -53,7 +59,8 @@ public:
53 /// Load from parameters instead of NPDM file, used for KIP 59 /// Load from parameters instead of NPDM file, used for KIP
54 void LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, s32 main_thread_prio, 60 void LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, s32 main_thread_prio,
55 u32 main_thread_core, u32 main_thread_stack_size, u64 title_id, 61 u32 main_thread_core, u32 main_thread_stack_size, u64 title_id,
56 u64 filesystem_permissions, KernelCapabilityDescriptors capabilities); 62 u64 filesystem_permissions, u32 system_resource_size,
63 KernelCapabilityDescriptors capabilities);
57 64
58 bool Is64BitProgram() const; 65 bool Is64BitProgram() const;
59 ProgramAddressSpaceType GetAddressSpaceType() const; 66 ProgramAddressSpaceType GetAddressSpaceType() const;
diff --git a/src/core/frontend/applets/profile_select.cpp b/src/core/frontend/applets/profile_select.cpp
index 4df3574d2..8d960d1ca 100644
--- a/src/core/frontend/applets/profile_select.cpp
+++ b/src/core/frontend/applets/profile_select.cpp
@@ -2,9 +2,9 @@
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 "common/settings.h"
5#include "core/frontend/applets/profile_select.h" 6#include "core/frontend/applets/profile_select.h"
6#include "core/hle/service/acc/profile_manager.h" 7#include "core/hle/service/acc/profile_manager.h"
7#include "core/settings.h"
8 8
9namespace Core::Frontend { 9namespace Core::Frontend {
10 10
diff --git a/src/core/frontend/applets/software_keyboard.cpp b/src/core/frontend/applets/software_keyboard.cpp
index 856ed33da..12c76c9ee 100644
--- a/src/core/frontend/applets/software_keyboard.cpp
+++ b/src/core/frontend/applets/software_keyboard.cpp
@@ -1,29 +1,149 @@
1// Copyright 2018 yuzu emulator team 1// Copyright 2021 yuzu Emulator Project
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 "common/logging/backend.h" 5#include <thread>
6
7#include "common/logging/log.h"
6#include "common/string_util.h" 8#include "common/string_util.h"
7#include "core/frontend/applets/software_keyboard.h" 9#include "core/frontend/applets/software_keyboard.h"
8 10
9namespace Core::Frontend { 11namespace Core::Frontend {
12
10SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default; 13SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default;
11 14
12void DefaultSoftwareKeyboardApplet::RequestText( 15DefaultSoftwareKeyboardApplet::~DefaultSoftwareKeyboardApplet() = default;
13 std::function<void(std::optional<std::u16string>)> out, 16
14 SoftwareKeyboardParameters parameters) const { 17void DefaultSoftwareKeyboardApplet::InitializeKeyboard(
15 if (parameters.initial_text.empty()) 18 bool is_inline, KeyboardInitializeParameters initialize_parameters,
16 out(u"yuzu"); 19 std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)> submit_normal_callback_,
20 std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
21 submit_inline_callback_) {
22 if (is_inline) {
23 LOG_WARNING(
24 Service_AM,
25 "(STUBBED) called, backend requested to initialize the inline software keyboard.");
26
27 submit_inline_callback = std::move(submit_inline_callback_);
28 } else {
29 LOG_WARNING(
30 Service_AM,
31 "(STUBBED) called, backend requested to initialize the normal software keyboard.");
32
33 submit_normal_callback = std::move(submit_normal_callback_);
34 }
35
36 parameters = std::move(initialize_parameters);
37
38 LOG_INFO(Service_AM,
39 "\nKeyboardInitializeParameters:"
40 "\nok_text={}"
41 "\nheader_text={}"
42 "\nsub_text={}"
43 "\nguide_text={}"
44 "\ninitial_text={}"
45 "\nmax_text_length={}"
46 "\nmin_text_length={}"
47 "\ninitial_cursor_position={}"
48 "\ntype={}"
49 "\npassword_mode={}"
50 "\ntext_draw_type={}"
51 "\nkey_disable_flags={}"
52 "\nuse_blur_background={}"
53 "\nenable_backspace_button={}"
54 "\nenable_return_button={}"
55 "\ndisable_cancel_button={}",
56 Common::UTF16ToUTF8(parameters.ok_text), Common::UTF16ToUTF8(parameters.header_text),
57 Common::UTF16ToUTF8(parameters.sub_text), Common::UTF16ToUTF8(parameters.guide_text),
58 Common::UTF16ToUTF8(parameters.initial_text), parameters.max_text_length,
59 parameters.min_text_length, parameters.initial_cursor_position, parameters.type,
60 parameters.password_mode, parameters.text_draw_type, parameters.key_disable_flags.raw,
61 parameters.use_blur_background, parameters.enable_backspace_button,
62 parameters.enable_return_button, parameters.disable_cancel_button);
63}
64
65void DefaultSoftwareKeyboardApplet::ShowNormalKeyboard() const {
66 LOG_WARNING(Service_AM,
67 "(STUBBED) called, backend requested to show the normal software keyboard.");
68
69 SubmitNormalText(u"yuzu");
70}
71
72void DefaultSoftwareKeyboardApplet::ShowTextCheckDialog(
73 Service::AM::Applets::SwkbdTextCheckResult text_check_result,
74 std::u16string text_check_message) const {
75 LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to show the text check dialog.");
76}
77
78void DefaultSoftwareKeyboardApplet::ShowInlineKeyboard(
79 InlineAppearParameters appear_parameters) const {
80 LOG_WARNING(Service_AM,
81 "(STUBBED) called, backend requested to show the inline software keyboard.");
82
83 LOG_INFO(Service_AM,
84 "\nInlineAppearParameters:"
85 "\nmax_text_length={}"
86 "\nmin_text_length={}"
87 "\nkey_top_scale_x={}"
88 "\nkey_top_scale_y={}"
89 "\nkey_top_translate_x={}"
90 "\nkey_top_translate_y={}"
91 "\ntype={}"
92 "\nkey_disable_flags={}"
93 "\nkey_top_as_floating={}"
94 "\nenable_backspace_button={}"
95 "\nenable_return_button={}"
96 "\ndisable_cancel_button={}",
97 appear_parameters.max_text_length, appear_parameters.min_text_length,
98 appear_parameters.key_top_scale_x, appear_parameters.key_top_scale_y,
99 appear_parameters.key_top_translate_x, appear_parameters.key_top_translate_y,
100 appear_parameters.type, appear_parameters.key_disable_flags.raw,
101 appear_parameters.key_top_as_floating, appear_parameters.enable_backspace_button,
102 appear_parameters.enable_return_button, appear_parameters.disable_cancel_button);
103
104 std::thread([this] { SubmitInlineText(u"yuzu"); }).detach();
105}
17 106
18 out(parameters.initial_text); 107void DefaultSoftwareKeyboardApplet::HideInlineKeyboard() const {
108 LOG_WARNING(Service_AM,
109 "(STUBBED) called, backend requested to hide the inline software keyboard.");
19} 110}
20 111
21void DefaultSoftwareKeyboardApplet::SendTextCheckDialog( 112void DefaultSoftwareKeyboardApplet::InlineTextChanged(InlineTextParameters text_parameters) const {
22 std::u16string error_message, std::function<void()> finished_check) const {
23 LOG_WARNING(Service_AM, 113 LOG_WARNING(Service_AM,
24 "(STUBBED) called - Default fallback software keyboard does not support text " 114 "(STUBBED) called, backend requested to change the inline keyboard text.");
25 "check! (error_message={})", 115
26 Common::UTF16ToUTF8(error_message)); 116 LOG_INFO(Service_AM,
27 finished_check(); 117 "\nInlineTextParameters:"
118 "\ninput_text={}"
119 "\ncursor_position={}",
120 Common::UTF16ToUTF8(text_parameters.input_text), text_parameters.cursor_position);
121
122 submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString,
123 text_parameters.input_text, text_parameters.cursor_position);
124}
125
126void DefaultSoftwareKeyboardApplet::ExitKeyboard() const {
127 LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to exit the software keyboard.");
28} 128}
129
130void DefaultSoftwareKeyboardApplet::SubmitNormalText(std::u16string text) const {
131 submit_normal_callback(Service::AM::Applets::SwkbdResult::Ok, text);
132}
133
134void DefaultSoftwareKeyboardApplet::SubmitInlineText(std::u16string_view text) const {
135 std::this_thread::sleep_for(std::chrono::milliseconds(500));
136
137 for (std::size_t index = 0; index < text.size(); ++index) {
138 submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString,
139 std::u16string(text.data(), text.data() + index + 1),
140 static_cast<s32>(index) + 1);
141
142 std::this_thread::sleep_for(std::chrono::milliseconds(250));
143 }
144
145 submit_inline_callback(Service::AM::Applets::SwkbdReplyType::DecidedEnter, std::u16string(text),
146 static_cast<s32>(text.size()));
147}
148
29} // namespace Core::Frontend 149} // namespace Core::Frontend
diff --git a/src/core/frontend/applets/software_keyboard.h b/src/core/frontend/applets/software_keyboard.h
index f9b202664..506eb35bb 100644
--- a/src/core/frontend/applets/software_keyboard.h
+++ b/src/core/frontend/applets/software_keyboard.h
@@ -1,54 +1,116 @@
1// Copyright 2018 yuzu emulator team 1// Copyright 2021 yuzu Emulator Project
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#pragma once 5#pragma once
6 6
7#include <functional> 7#include <functional>
8#include <optional> 8#include <thread>
9#include <string> 9
10#include "common/bit_field.h"
11#include "common/common_types.h" 10#include "common/common_types.h"
12 11
12#include "core/hle/service/am/applets/software_keyboard_types.h"
13
13namespace Core::Frontend { 14namespace Core::Frontend {
14struct SoftwareKeyboardParameters { 15
15 std::u16string submit_text; 16struct KeyboardInitializeParameters {
17 std::u16string ok_text;
16 std::u16string header_text; 18 std::u16string header_text;
17 std::u16string sub_text; 19 std::u16string sub_text;
18 std::u16string guide_text; 20 std::u16string guide_text;
19 std::u16string initial_text; 21 std::u16string initial_text;
20 std::size_t max_length; 22 u32 max_text_length;
21 bool password; 23 u32 min_text_length;
22 bool cursor_at_beginning; 24 s32 initial_cursor_position;
23 25 Service::AM::Applets::SwkbdType type;
24 union { 26 Service::AM::Applets::SwkbdPasswordMode password_mode;
25 u8 value; 27 Service::AM::Applets::SwkbdTextDrawType text_draw_type;
26 28 Service::AM::Applets::SwkbdKeyDisableFlags key_disable_flags;
27 BitField<1, 1, u8> disable_space; 29 bool use_blur_background;
28 BitField<2, 1, u8> disable_address; 30 bool enable_backspace_button;
29 BitField<3, 1, u8> disable_percent; 31 bool enable_return_button;
30 BitField<4, 1, u8> disable_slash; 32 bool disable_cancel_button;
31 BitField<6, 1, u8> disable_number; 33};
32 BitField<7, 1, u8> disable_download_code; 34
33 }; 35struct InlineAppearParameters {
36 u32 max_text_length;
37 u32 min_text_length;
38 f32 key_top_scale_x;
39 f32 key_top_scale_y;
40 f32 key_top_translate_x;
41 f32 key_top_translate_y;
42 Service::AM::Applets::SwkbdType type;
43 Service::AM::Applets::SwkbdKeyDisableFlags key_disable_flags;
44 bool key_top_as_floating;
45 bool enable_backspace_button;
46 bool enable_return_button;
47 bool disable_cancel_button;
48};
49
50struct InlineTextParameters {
51 std::u16string input_text;
52 s32 cursor_position;
34}; 53};
35 54
36class SoftwareKeyboardApplet { 55class SoftwareKeyboardApplet {
37public: 56public:
38 virtual ~SoftwareKeyboardApplet(); 57 virtual ~SoftwareKeyboardApplet();
39 58
40 virtual void RequestText(std::function<void(std::optional<std::u16string>)> out, 59 virtual void InitializeKeyboard(
41 SoftwareKeyboardParameters parameters) const = 0; 60 bool is_inline, KeyboardInitializeParameters initialize_parameters,
42 virtual void SendTextCheckDialog(std::u16string error_message, 61 std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
43 std::function<void()> finished_check) const = 0; 62 submit_normal_callback_,
63 std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
64 submit_inline_callback_) = 0;
65
66 virtual void ShowNormalKeyboard() const = 0;
67
68 virtual void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
69 std::u16string text_check_message) const = 0;
70
71 virtual void ShowInlineKeyboard(InlineAppearParameters appear_parameters) const = 0;
72
73 virtual void HideInlineKeyboard() const = 0;
74
75 virtual void InlineTextChanged(InlineTextParameters text_parameters) const = 0;
76
77 virtual void ExitKeyboard() const = 0;
44}; 78};
45 79
46class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet { 80class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet {
47public: 81public:
48 void RequestText(std::function<void(std::optional<std::u16string>)> out, 82 ~DefaultSoftwareKeyboardApplet() override;
49 SoftwareKeyboardParameters parameters) const override; 83
50 void SendTextCheckDialog(std::u16string error_message, 84 void InitializeKeyboard(
51 std::function<void()> finished_check) const override; 85 bool is_inline, KeyboardInitializeParameters initialize_parameters,
86 std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
87 submit_normal_callback_,
88 std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
89 submit_inline_callback_) override;
90
91 void ShowNormalKeyboard() const override;
92
93 void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
94 std::u16string text_check_message) const override;
95
96 void ShowInlineKeyboard(InlineAppearParameters appear_parameters) const override;
97
98 void HideInlineKeyboard() const override;
99
100 void InlineTextChanged(InlineTextParameters text_parameters) const override;
101
102 void ExitKeyboard() const override;
103
104private:
105 void SubmitNormalText(std::u16string text) const;
106 void SubmitInlineText(std::u16string_view text) const;
107
108 KeyboardInitializeParameters parameters;
109
110 mutable std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
111 submit_normal_callback;
112 mutable std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
113 submit_inline_callback;
52}; 114};
53 115
54} // namespace Core::Frontend 116} // namespace Core::Frontend
diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp
index ee7a58b1c..cff49899a 100644
--- a/src/core/frontend/emu_window.cpp
+++ b/src/core/frontend/emu_window.cpp
@@ -4,9 +4,9 @@
4 4
5#include <cmath> 5#include <cmath>
6#include <mutex> 6#include <mutex>
7#include "common/settings.h"
7#include "core/frontend/emu_window.h" 8#include "core/frontend/emu_window.h"
8#include "core/frontend/input.h" 9#include "core/frontend/input.h"
9#include "core/settings.h"
10 10
11namespace Core::Frontend { 11namespace Core::Frontend {
12 12
@@ -60,23 +60,23 @@ EmuWindow::~EmuWindow() {
60 * @param framebuffer_y Framebuffer y-coordinate to check 60 * @param framebuffer_y Framebuffer y-coordinate to check
61 * @return True if the coordinates are within the touchpad, otherwise false 61 * @return True if the coordinates are within the touchpad, otherwise false
62 */ 62 */
63static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x, 63static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, u32 framebuffer_x,
64 unsigned framebuffer_y) { 64 u32 framebuffer_y) {
65 return (framebuffer_y >= layout.screen.top && framebuffer_y < layout.screen.bottom && 65 return (framebuffer_y >= layout.screen.top && framebuffer_y < layout.screen.bottom &&
66 framebuffer_x >= layout.screen.left && framebuffer_x < layout.screen.right); 66 framebuffer_x >= layout.screen.left && framebuffer_x < layout.screen.right);
67} 67}
68 68
69std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) const { 69std::pair<u32, u32> EmuWindow::ClipToTouchScreen(u32 new_x, u32 new_y) const {
70 new_x = std::max(new_x, framebuffer_layout.screen.left); 70 new_x = std::max(new_x, framebuffer_layout.screen.left);
71 new_x = std::min(new_x, framebuffer_layout.screen.right - 1); 71 new_x = std::min(new_x, framebuffer_layout.screen.right - 1);
72 72
73 new_y = std::max(new_y, framebuffer_layout.screen.top); 73 new_y = std::max(new_y, framebuffer_layout.screen.top);
74 new_y = std::min(new_y, framebuffer_layout.screen.bottom - 1); 74 new_y = std::min(new_y, framebuffer_layout.screen.bottom - 1);
75 75
76 return std::make_tuple(new_x, new_y); 76 return std::make_pair(new_x, new_y);
77} 77}
78 78
79void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y, std::size_t id) { 79void EmuWindow::TouchPressed(u32 framebuffer_x, u32 framebuffer_y, size_t id) {
80 if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) { 80 if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) {
81 return; 81 return;
82 } 82 }
@@ -95,7 +95,7 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y, std
95 touch_state->status[id] = std::make_tuple(x, y, true); 95 touch_state->status[id] = std::make_tuple(x, y, true);
96} 96}
97 97
98void EmuWindow::TouchReleased(std::size_t id) { 98void EmuWindow::TouchReleased(size_t id) {
99 if (id >= touch_state->status.size()) { 99 if (id >= touch_state->status.size()) {
100 return; 100 return;
101 } 101 }
@@ -103,20 +103,23 @@ void EmuWindow::TouchReleased(std::size_t id) {
103 touch_state->status[id] = std::make_tuple(0.0f, 0.0f, false); 103 touch_state->status[id] = std::make_tuple(0.0f, 0.0f, false);
104} 104}
105 105
106void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y, std::size_t id) { 106void EmuWindow::TouchMoved(u32 framebuffer_x, u32 framebuffer_y, size_t id) {
107 if (id >= touch_state->status.size()) { 107 if (id >= touch_state->status.size()) {
108 return; 108 return;
109 } 109 }
110 if (!std::get<2>(touch_state->status[id])) 110
111 if (!std::get<2>(touch_state->status[id])) {
111 return; 112 return;
113 }
112 114
113 if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) 115 if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) {
114 std::tie(framebuffer_x, framebuffer_y) = ClipToTouchScreen(framebuffer_x, framebuffer_y); 116 std::tie(framebuffer_x, framebuffer_y) = ClipToTouchScreen(framebuffer_x, framebuffer_y);
117 }
115 118
116 TouchPressed(framebuffer_x, framebuffer_y, id); 119 TouchPressed(framebuffer_x, framebuffer_y, id);
117} 120}
118 121
119void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height) { 122void EmuWindow::UpdateCurrentFramebufferLayout(u32 width, u32 height) {
120 NotifyFramebufferLayoutChanged(Layout::DefaultFrameLayout(width, height)); 123 NotifyFramebufferLayoutChanged(Layout::DefaultFrameLayout(width, height));
121} 124}
122 125
diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h
index 2436c6580..076148698 100644
--- a/src/core/frontend/emu_window.h
+++ b/src/core/frontend/emu_window.h
@@ -82,7 +82,7 @@ public:
82 bool fullscreen = false; 82 bool fullscreen = false;
83 int res_width = 0; 83 int res_width = 0;
84 int res_height = 0; 84 int res_height = 0;
85 std::pair<unsigned, unsigned> min_client_area_size; 85 std::pair<u32, u32> min_client_area_size;
86 }; 86 };
87 87
88 /// Data describing host window system information 88 /// Data describing host window system information
@@ -119,13 +119,13 @@ public:
119 * @param framebuffer_y Framebuffer y-coordinate that was pressed 119 * @param framebuffer_y Framebuffer y-coordinate that was pressed
120 * @param id Touch event ID 120 * @param id Touch event ID
121 */ 121 */
122 void TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y, std::size_t id); 122 void TouchPressed(u32 framebuffer_x, u32 framebuffer_y, size_t id);
123 123
124 /** 124 /**
125 * Signal that a touch released event has occurred (e.g. mouse click released) 125 * Signal that a touch released event has occurred (e.g. mouse click released)
126 * @param id Touch event ID 126 * @param id Touch event ID
127 */ 127 */
128 void TouchReleased(std::size_t id); 128 void TouchReleased(size_t id);
129 129
130 /** 130 /**
131 * Signal that a touch movement event has occurred (e.g. mouse was moved over the emu window) 131 * Signal that a touch movement event has occurred (e.g. mouse was moved over the emu window)
@@ -133,7 +133,7 @@ public:
133 * @param framebuffer_y Framebuffer y-coordinate 133 * @param framebuffer_y Framebuffer y-coordinate
134 * @param id Touch event ID 134 * @param id Touch event ID
135 */ 135 */
136 void TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y, std::size_t id); 136 void TouchMoved(u32 framebuffer_x, u32 framebuffer_y, size_t id);
137 137
138 /** 138 /**
139 * Returns currently active configuration. 139 * Returns currently active configuration.
@@ -173,7 +173,7 @@ public:
173 * Convenience method to update the current frame layout 173 * Convenience method to update the current frame layout
174 * Read from the current settings to determine which layout to use. 174 * Read from the current settings to determine which layout to use.
175 */ 175 */
176 void UpdateCurrentFramebufferLayout(unsigned width, unsigned height); 176 void UpdateCurrentFramebufferLayout(u32 width, u32 height);
177 177
178protected: 178protected:
179 explicit EmuWindow(); 179 explicit EmuWindow();
@@ -208,7 +208,7 @@ protected:
208 * Update internal client area size with the given parameter. 208 * Update internal client area size with the given parameter.
209 * @note EmuWindow implementations will usually use this in window resize event handlers. 209 * @note EmuWindow implementations will usually use this in window resize event handlers.
210 */ 210 */
211 void NotifyClientAreaSizeChanged(const std::pair<unsigned, unsigned>& size) { 211 void NotifyClientAreaSizeChanged(std::pair<u32, u32> size) {
212 client_area_width = size.first; 212 client_area_width = size.first;
213 client_area_height = size.second; 213 client_area_height = size.second;
214 } 214 }
@@ -221,14 +221,19 @@ private:
221 * For the request to be honored, EmuWindow implementations will usually reimplement this 221 * For the request to be honored, EmuWindow implementations will usually reimplement this
222 * function. 222 * function.
223 */ 223 */
224 virtual void OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned>) { 224 virtual void OnMinimalClientAreaChangeRequest(std::pair<u32, u32>) {
225 // By default, ignore this request and do nothing. 225 // By default, ignore this request and do nothing.
226 } 226 }
227 227
228 /**
229 * Clip the provided coordinates to be inside the touchscreen area.
230 */
231 std::pair<u32, u32> ClipToTouchScreen(u32 new_x, u32 new_y) const;
232
228 Layout::FramebufferLayout framebuffer_layout; ///< Current framebuffer layout 233 Layout::FramebufferLayout framebuffer_layout; ///< Current framebuffer layout
229 234
230 unsigned client_area_width; ///< Current client width, should be set by window impl. 235 u32 client_area_width; ///< Current client width, should be set by window impl.
231 unsigned client_area_height; ///< Current client height, should be set by window impl. 236 u32 client_area_height; ///< Current client height, should be set by window impl.
232 237
233 WindowConfig config; ///< Internal configuration (changes pending for being applied in 238 WindowConfig config; ///< Internal configuration (changes pending for being applied in
234 /// ProcessConfigurationChanges) 239 /// ProcessConfigurationChanges)
@@ -236,11 +241,6 @@ private:
236 241
237 class TouchState; 242 class TouchState;
238 std::shared_ptr<TouchState> touch_state; 243 std::shared_ptr<TouchState> touch_state;
239
240 /**
241 * Clip the provided coordinates to be inside the touchscreen area.
242 */
243 std::tuple<unsigned, unsigned> ClipToTouchScreen(unsigned new_x, unsigned new_y) const;
244}; 244};
245 245
246} // namespace Core::Frontend 246} // namespace Core::Frontend
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp
index b9a270a55..0832463d6 100644
--- a/src/core/frontend/framebuffer_layout.cpp
+++ b/src/core/frontend/framebuffer_layout.cpp
@@ -5,8 +5,8 @@
5#include <cmath> 5#include <cmath>
6 6
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/settings.h"
8#include "core/frontend/framebuffer_layout.h" 9#include "core/frontend/framebuffer_layout.h"
9#include "core/settings.h"
10 10
11namespace Layout { 11namespace Layout {
12 12
diff --git a/src/core/frontend/input_interpreter.cpp b/src/core/frontend/input_interpreter.cpp
index ec5fe660e..9f6a90e8f 100644
--- a/src/core/frontend/input_interpreter.cpp
+++ b/src/core/frontend/input_interpreter.cpp
@@ -12,7 +12,9 @@ InputInterpreter::InputInterpreter(Core::System& system)
12 : npad{system.ServiceManager() 12 : npad{system.ServiceManager()
13 .GetService<Service::HID::Hid>("hid") 13 .GetService<Service::HID::Hid>("hid")
14 ->GetAppletResource() 14 ->GetAppletResource()
15 ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} {} 15 ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} {
16 ResetButtonStates();
17}
16 18
17InputInterpreter::~InputInterpreter() = default; 19InputInterpreter::~InputInterpreter() = default;
18 20
@@ -25,6 +27,17 @@ void InputInterpreter::PollInput() {
25 button_states[current_index] = button_state; 27 button_states[current_index] = button_state;
26} 28}
27 29
30void InputInterpreter::ResetButtonStates() {
31 previous_index = 0;
32 current_index = 0;
33
34 button_states[0] = 0xFFFFFFFF;
35
36 for (std::size_t i = 1; i < button_states.size(); ++i) {
37 button_states[i] = 0;
38 }
39}
40
28bool InputInterpreter::IsButtonPressed(HIDButton button) const { 41bool InputInterpreter::IsButtonPressed(HIDButton button) const {
29 return (button_states[current_index] & (1U << static_cast<u8>(button))) != 0; 42 return (button_states[current_index] & (1U << static_cast<u8>(button))) != 0;
30} 43}
diff --git a/src/core/frontend/input_interpreter.h b/src/core/frontend/input_interpreter.h
index 73fc47ffb..9495e3daf 100644
--- a/src/core/frontend/input_interpreter.h
+++ b/src/core/frontend/input_interpreter.h
@@ -66,6 +66,9 @@ public:
66 /// Gets a button state from HID and inserts it into the array of button states. 66 /// Gets a button state from HID and inserts it into the array of button states.
67 void PollInput(); 67 void PollInput();
68 68
69 /// Resets all the button states to their defaults.
70 void ResetButtonStates();
71
69 /** 72 /**
70 * Checks whether the button is pressed. 73 * Checks whether the button is pressed.
71 * 74 *
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 161d9f782..2b363b1d9 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -75,10 +75,14 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_
75 if (incoming) { 75 if (incoming) {
76 // Populate the object lists with the data in the IPC request. 76 // Populate the object lists with the data in the IPC request.
77 for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) { 77 for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) {
78 copy_objects.push_back(handle_table.GetGeneric(rp.Pop<Handle>())); 78 const u32 copy_handle{rp.Pop<Handle>()};
79 copy_handles.push_back(copy_handle);
80 copy_objects.push_back(handle_table.GetGeneric(copy_handle));
79 } 81 }
80 for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) { 82 for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) {
81 move_objects.push_back(handle_table.GetGeneric(rp.Pop<Handle>())); 83 const u32 move_handle{rp.Pop<Handle>()};
84 move_handles.push_back(move_handle);
85 move_objects.push_back(handle_table.GetGeneric(move_handle));
82 } 86 }
83 } else { 87 } else {
84 // For responses we just ignore the handles, they're empty and will be populated when 88 // For responses we just ignore the handles, they're empty and will be populated when
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index 9a769781b..6fba42615 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -210,6 +210,14 @@ public:
210 /// Helper function to test whether the output buffer at buffer_index can be written 210 /// Helper function to test whether the output buffer at buffer_index can be written
211 bool CanWriteBuffer(std::size_t buffer_index = 0) const; 211 bool CanWriteBuffer(std::size_t buffer_index = 0) const;
212 212
213 Handle GetCopyHandle(std::size_t index) const {
214 return copy_handles.at(index);
215 }
216
217 Handle GetMoveHandle(std::size_t index) const {
218 return move_handles.at(index);
219 }
220
213 template <typename T> 221 template <typename T>
214 std::shared_ptr<T> GetCopyObject(std::size_t index) { 222 std::shared_ptr<T> GetCopyObject(std::size_t index) {
215 return DynamicObjectCast<T>(copy_objects.at(index)); 223 return DynamicObjectCast<T>(copy_objects.at(index));
@@ -285,6 +293,8 @@ private:
285 std::shared_ptr<Kernel::ServerSession> server_session; 293 std::shared_ptr<Kernel::ServerSession> server_session;
286 std::shared_ptr<KThread> thread; 294 std::shared_ptr<KThread> thread;
287 // TODO(yuriks): Check common usage of this and optimize size accordingly 295 // TODO(yuriks): Check common usage of this and optimize size accordingly
296 boost::container::small_vector<Handle, 8> move_handles;
297 boost::container::small_vector<Handle, 8> copy_handles;
288 boost::container::small_vector<std::shared_ptr<Object>, 8> move_objects; 298 boost::container::small_vector<std::shared_ptr<Object>, 8> move_objects;
289 boost::container::small_vector<std::shared_ptr<Object>, 8> copy_objects; 299 boost::container::small_vector<std::shared_ptr<Object>, 8> copy_objects;
290 boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects; 300 boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp
index d7a4a38e6..d05b34ea3 100644
--- a/src/core/hle/kernel/k_resource_limit.cpp
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -2,21 +2,16 @@
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// This file references various implementation details from Atmosphere, an open-source firmware for
6// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
7
8#include "common/assert.h" 5#include "common/assert.h"
9#include "core/core.h"
10#include "core/core_timing.h" 6#include "core/core_timing.h"
11#include "core/core_timing_util.h"
12#include "core/hle/kernel/k_resource_limit.h" 7#include "core/hle/kernel/k_resource_limit.h"
13#include "core/hle/kernel/svc_results.h" 8#include "core/hle/kernel/svc_results.h"
14 9
15namespace Kernel { 10namespace Kernel {
16constexpr s64 DefaultTimeout = 10000000000; // 10 seconds 11constexpr s64 DefaultTimeout = 10000000000; // 10 seconds
17 12
18KResourceLimit::KResourceLimit(KernelCore& kernel, Core::System& system) 13KResourceLimit::KResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing_)
19 : Object{kernel}, lock{kernel}, cond_var{kernel}, kernel{kernel}, system(system) {} 14 : Object{kernel}, lock{kernel}, cond_var{kernel}, core_timing(core_timing_) {}
20KResourceLimit::~KResourceLimit() = default; 15KResourceLimit::~KResourceLimit() = default;
21 16
22s64 KResourceLimit::GetLimitValue(LimitableResource which) const { 17s64 KResourceLimit::GetLimitValue(LimitableResource which) const {
@@ -83,7 +78,7 @@ ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) {
83} 78}
84 79
85bool KResourceLimit::Reserve(LimitableResource which, s64 value) { 80bool KResourceLimit::Reserve(LimitableResource which, s64 value) {
86 return Reserve(which, value, system.CoreTiming().GetGlobalTimeNs().count() + DefaultTimeout); 81 return Reserve(which, value, core_timing.GetGlobalTimeNs().count() + DefaultTimeout);
87} 82}
88 83
89bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { 84bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
@@ -114,7 +109,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
114 } 109 }
115 110
116 if (current_hints[index] + value <= limit_values[index] && 111 if (current_hints[index] + value <= limit_values[index] &&
117 (timeout < 0 || system.CoreTiming().GetGlobalTimeNs().count() < timeout)) { 112 (timeout < 0 || core_timing.GetGlobalTimeNs().count() < timeout)) {
118 waiter_count++; 113 waiter_count++;
119 cond_var.Wait(&lock, timeout); 114 cond_var.Wait(&lock, timeout);
120 waiter_count--; 115 waiter_count--;
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h
index 58ae456f1..4542317d0 100644
--- a/src/core/hle/kernel/k_resource_limit.h
+++ b/src/core/hle/kernel/k_resource_limit.h
@@ -2,9 +2,6 @@
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// This file references various implementation details from Atmosphere, an open-source firmware for
6// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
7
8#pragma once 5#pragma once
9 6
10#include <array> 7#include <array>
@@ -15,8 +12,8 @@
15 12
16union ResultCode; 13union ResultCode;
17 14
18namespace Core { 15namespace Core::Timing {
19class System; 16class CoreTiming;
20} 17}
21 18
22namespace Kernel { 19namespace Kernel {
@@ -37,7 +34,7 @@ constexpr bool IsValidResourceType(LimitableResource type) {
37 34
38class KResourceLimit final : public Object { 35class KResourceLimit final : public Object {
39public: 36public:
40 explicit KResourceLimit(KernelCore& kernel, Core::System& system); 37 explicit KResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing_);
41 ~KResourceLimit(); 38 ~KResourceLimit();
42 39
43 s64 GetLimitValue(LimitableResource which) const; 40 s64 GetLimitValue(LimitableResource which) const;
@@ -75,7 +72,6 @@ private:
75 mutable KLightLock lock; 72 mutable KLightLock lock;
76 s32 waiter_count{}; 73 s32 waiter_count{};
77 KLightConditionVariable cond_var; 74 KLightConditionVariable cond_var;
78 KernelCore& kernel; 75 const Core::Timing::CoreTiming& core_timing;
79 Core::System& system;
80}; 76};
81} // namespace Kernel 77} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index f7d3f218a..5c4f45ab4 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -72,7 +72,7 @@ struct KernelCore::Impl {
72 KMemoryLayout memory_layout; 72 KMemoryLayout memory_layout;
73 DeriveInitialMemoryLayout(memory_layout); 73 DeriveInitialMemoryLayout(memory_layout);
74 InitializeMemoryLayout(memory_layout); 74 InitializeMemoryLayout(memory_layout);
75 InitializeSystemResourceLimit(kernel, system, memory_layout); 75 InitializeSystemResourceLimit(kernel, system.CoreTiming(), memory_layout);
76 InitializeSlabHeaps(); 76 InitializeSlabHeaps();
77 InitializeSchedulers(); 77 InitializeSchedulers();
78 InitializeSuspendThreads(); 78 InitializeSuspendThreads();
@@ -142,9 +142,10 @@ struct KernelCore::Impl {
142 } 142 }
143 143
144 // Creates the default system resource limit 144 // Creates the default system resource limit
145 void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system, 145 void InitializeSystemResourceLimit(KernelCore& kernel,
146 const Core::Timing::CoreTiming& core_timing,
146 const KMemoryLayout& memory_layout) { 147 const KMemoryLayout& memory_layout) {
147 system_resource_limit = std::make_shared<KResourceLimit>(kernel, system); 148 system_resource_limit = std::make_shared<KResourceLimit>(kernel, core_timing);
148 const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes(); 149 const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes();
149 150
150 // If setting the default system values fails, then something seriously wrong has occurred. 151 // If setting the default system values fails, then something seriously wrong has occurred.
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index dd01f3924..e35deb8e2 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -10,6 +10,7 @@
10#include "common/alignment.h" 10#include "common/alignment.h"
11#include "common/assert.h" 11#include "common/assert.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "common/settings.h"
13#include "core/core.h" 14#include "core/core.h"
14#include "core/device_memory.h" 15#include "core/device_memory.h"
15#include "core/file_sys/program_metadata.h" 16#include "core/file_sys/program_metadata.h"
@@ -26,7 +27,6 @@
26#include "core/hle/kernel/svc_results.h" 27#include "core/hle/kernel/svc_results.h"
27#include "core/hle/lock.h" 28#include "core/hle/lock.h"
28#include "core/memory.h" 29#include "core/memory.h"
29#include "core/settings.h"
30 30
31namespace Kernel { 31namespace Kernel {
32namespace { 32namespace {
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index fcffc746d..bebb86154 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -2156,7 +2156,7 @@ static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle)
2156 LOG_DEBUG(Kernel_SVC, "called"); 2156 LOG_DEBUG(Kernel_SVC, "called");
2157 2157
2158 auto& kernel = system.Kernel(); 2158 auto& kernel = system.Kernel();
2159 auto resource_limit = std::make_shared<KResourceLimit>(kernel, system); 2159 auto resource_limit = std::make_shared<KResourceLimit>(kernel, system.CoreTiming());
2160 2160
2161 auto* const current_process = kernel.CurrentProcess(); 2161 auto* const current_process = kernel.CurrentProcess();
2162 ASSERT(current_process != nullptr); 2162 ASSERT(current_process != nullptr);
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 52535ecc0..5450dcf0f 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -702,16 +702,12 @@ void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestCon
702} 702}
703 703
704void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) { 704void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
705 IPC::RequestParser rp{ctx};
706
707 LOG_DEBUG(Service_ACC, "called"); 705 LOG_DEBUG(Service_ACC, "called");
708 IPC::ResponseBuilder rb{ctx, 2}; 706 IPC::ResponseBuilder rb{ctx, 2};
709 rb.Push(InitializeApplicationInfoBase()); 707 rb.Push(InitializeApplicationInfoBase());
710} 708}
711 709
712void Module::Interface::InitializeApplicationInfoRestricted(Kernel::HLERequestContext& ctx) { 710void Module::Interface::InitializeApplicationInfoRestricted(Kernel::HLERequestContext& ctx) {
713 IPC::RequestParser rp{ctx};
714
715 LOG_WARNING(Service_ACC, "(Partial implementation) called"); 711 LOG_WARNING(Service_ACC, "(Partial implementation) called");
716 712
717 // TODO(ogniK): We require checking if the user actually owns the title and what not. As of 713 // TODO(ogniK): We require checking if the user actually owns the title and what not. As of
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp
index 50b2c58e2..de83d82a4 100644
--- a/src/core/hle/service/acc/profile_manager.cpp
+++ b/src/core/hle/service/acc/profile_manager.cpp
@@ -8,8 +8,8 @@
8#include <fmt/format.h> 8#include <fmt/format.h>
9 9
10#include "common/file_util.h" 10#include "common/file_util.h"
11#include "common/settings.h"
11#include "core/hle/service/acc/profile_manager.h" 12#include "core/hle/service/acc/profile_manager.h"
12#include "core/settings.h"
13 13
14namespace Service::Account { 14namespace Service::Account {
15 15
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 4374487a3..58c7f2930 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -7,6 +7,7 @@
7#include <cinttypes> 7#include <cinttypes>
8#include <cstring> 8#include <cstring>
9#include "audio_core/audio_renderer.h" 9#include "audio_core/audio_renderer.h"
10#include "common/settings.h"
10#include "core/core.h" 11#include "core/core.h"
11#include "core/file_sys/control_metadata.h" 12#include "core/file_sys/control_metadata.h"
12#include "core/file_sys/patch_manager.h" 13#include "core/file_sys/patch_manager.h"
@@ -41,7 +42,6 @@
41#include "core/hle/service/set/set.h" 42#include "core/hle/service/set/set.h"
42#include "core/hle/service/sm/sm.h" 43#include "core/hle/service/sm/sm.h"
43#include "core/hle/service/vi/vi.h" 44#include "core/hle/service/vi/vi.h"
44#include "core/settings.h"
45 45
46namespace Service::AM { 46namespace Service::AM {
47 47
@@ -619,16 +619,20 @@ std::size_t AppletMessageQueue::GetMessageCount() const {
619 return messages.size(); 619 return messages.size();
620} 620}
621 621
622void AppletMessageQueue::RequestExit() {
623 PushMessage(AppletMessage::ExitRequested);
624}
625
626void AppletMessageQueue::FocusStateChanged() {
627 PushMessage(AppletMessage::FocusStateChanged);
628}
629
622void AppletMessageQueue::OperationModeChanged() { 630void AppletMessageQueue::OperationModeChanged() {
623 PushMessage(AppletMessage::OperationModeChanged); 631 PushMessage(AppletMessage::OperationModeChanged);
624 PushMessage(AppletMessage::PerformanceModeChanged); 632 PushMessage(AppletMessage::PerformanceModeChanged);
625 on_operation_mode_changed->GetWritableEvent()->Signal(); 633 on_operation_mode_changed->GetWritableEvent()->Signal();
626} 634}
627 635
628void AppletMessageQueue::RequestExit() {
629 PushMessage(AppletMessage::ExitRequested);
630}
631
632ICommonStateGetter::ICommonStateGetter(Core::System& system_, 636ICommonStateGetter::ICommonStateGetter(Core::System& system_,
633 std::shared_ptr<AppletMessageQueue> msg_queue_) 637 std::shared_ptr<AppletMessageQueue> msg_queue_)
634 : ServiceFramework{system_, "ICommonStateGetter"}, msg_queue{std::move(msg_queue_)} { 638 : ServiceFramework{system_, "ICommonStateGetter"}, msg_queue{std::move(msg_queue_)} {
@@ -683,7 +687,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
683 {501, nullptr, "SuppressDisablingSleepTemporarily"}, 687 {501, nullptr, "SuppressDisablingSleepTemporarily"},
684 {502, nullptr, "IsSleepEnabled"}, 688 {502, nullptr, "IsSleepEnabled"},
685 {503, nullptr, "IsDisablingSleepSuppressed"}, 689 {503, nullptr, "IsDisablingSleepSuppressed"},
686 {900, nullptr, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"}, 690 {900, &ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"},
687 }; 691 };
688 // clang-format on 692 // clang-format on
689 693
@@ -813,6 +817,14 @@ void ICommonStateGetter::SetCpuBoostMode(Kernel::HLERequestContext& ctx) {
813 apm_sys->SetCpuBoostMode(ctx); 817 apm_sys->SetCpuBoostMode(ctx);
814} 818}
815 819
820void ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(
821 Kernel::HLERequestContext& ctx) {
822 LOG_WARNING(Service_AM, "(STUBBED) called");
823
824 IPC::ResponseBuilder rb{ctx, 2};
825 rb.Push(RESULT_SUCCESS);
826}
827
816IStorageImpl::~IStorageImpl() = default; 828IStorageImpl::~IStorageImpl() = default;
817 829
818class StorageDataImpl final : public IStorageImpl { 830class StorageDataImpl final : public IStorageImpl {
@@ -971,7 +983,7 @@ private:
971 983
972 auto storage = applet->GetBroker().PopNormalDataToGame(); 984 auto storage = applet->GetBroker().PopNormalDataToGame();
973 if (storage == nullptr) { 985 if (storage == nullptr) {
974 LOG_ERROR(Service_AM, 986 LOG_DEBUG(Service_AM,
975 "storage is a nullptr. There is no data in the current normal channel"); 987 "storage is a nullptr. There is no data in the current normal channel");
976 IPC::ResponseBuilder rb{ctx, 2}; 988 IPC::ResponseBuilder rb{ctx, 2};
977 rb.Push(ERR_NO_DATA_IN_CHANNEL); 989 rb.Push(ERR_NO_DATA_IN_CHANNEL);
@@ -1002,7 +1014,7 @@ private:
1002 1014
1003 auto storage = applet->GetBroker().PopInteractiveDataToGame(); 1015 auto storage = applet->GetBroker().PopInteractiveDataToGame();
1004 if (storage == nullptr) { 1016 if (storage == nullptr) {
1005 LOG_ERROR(Service_AM, 1017 LOG_DEBUG(Service_AM,
1006 "storage is a nullptr. There is no data in the current interactive channel"); 1018 "storage is a nullptr. There is no data in the current interactive channel");
1007 IPC::ResponseBuilder rb{ctx, 2}; 1019 IPC::ResponseBuilder rb{ctx, 2};
1008 rb.Push(ERR_NO_DATA_IN_CHANNEL); 1020 rb.Push(ERR_NO_DATA_IN_CHANNEL);
@@ -1125,7 +1137,7 @@ ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_)
1125 {2, nullptr, "AreAnyLibraryAppletsLeft"}, 1137 {2, nullptr, "AreAnyLibraryAppletsLeft"},
1126 {10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"}, 1138 {10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"},
1127 {11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"}, 1139 {11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"},
1128 {12, nullptr, "CreateHandleStorage"}, 1140 {12, &ILibraryAppletCreator::CreateHandleStorage, "CreateHandleStorage"},
1129 }; 1141 };
1130 RegisterHandlers(functions); 1142 RegisterHandlers(functions);
1131} 1143}
@@ -1134,14 +1146,15 @@ ILibraryAppletCreator::~ILibraryAppletCreator() = default;
1134 1146
1135void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) { 1147void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) {
1136 IPC::RequestParser rp{ctx}; 1148 IPC::RequestParser rp{ctx};
1149
1137 const auto applet_id = rp.PopRaw<Applets::AppletId>(); 1150 const auto applet_id = rp.PopRaw<Applets::AppletId>();
1138 const auto applet_mode = rp.PopRaw<u32>(); 1151 const auto applet_mode = rp.PopRaw<Applets::LibraryAppletMode>();
1139 1152
1140 LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id, 1153 LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id,
1141 applet_mode); 1154 applet_mode);
1142 1155
1143 const auto& applet_manager{system.GetAppletManager()}; 1156 const auto& applet_manager{system.GetAppletManager()};
1144 const auto applet = applet_manager.GetApplet(applet_id); 1157 const auto applet = applet_manager.GetApplet(applet_id, applet_mode);
1145 1158
1146 if (applet == nullptr) { 1159 if (applet == nullptr) {
1147 LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); 1160 LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
@@ -1159,9 +1172,18 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx)
1159 1172
1160void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) { 1173void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
1161 IPC::RequestParser rp{ctx}; 1174 IPC::RequestParser rp{ctx};
1162 const u64 size{rp.Pop<u64>()}; 1175
1176 const s64 size{rp.Pop<s64>()};
1177
1163 LOG_DEBUG(Service_AM, "called, size={}", size); 1178 LOG_DEBUG(Service_AM, "called, size={}", size);
1164 1179
1180 if (size <= 0) {
1181 LOG_ERROR(Service_AM, "size is less than or equal to 0");
1182 IPC::ResponseBuilder rb{ctx, 2};
1183 rb.Push(RESULT_UNKNOWN);
1184 return;
1185 }
1186
1165 std::vector<u8> buffer(size); 1187 std::vector<u8> buffer(size);
1166 1188
1167 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1189 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -1170,18 +1192,65 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
1170} 1192}
1171 1193
1172void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) { 1194void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) {
1173 LOG_DEBUG(Service_AM, "called"); 1195 IPC::RequestParser rp{ctx};
1196
1197 struct Parameters {
1198 u8 permissions;
1199 s64 size;
1200 };
1201
1202 const auto parameters{rp.PopRaw<Parameters>()};
1203 const auto handle{ctx.GetCopyHandle(0)};
1174 1204
1205 LOG_DEBUG(Service_AM, "called, permissions={}, size={}, handle={:08X}", parameters.permissions,
1206 parameters.size, handle);
1207
1208 if (parameters.size <= 0) {
1209 LOG_ERROR(Service_AM, "size is less than or equal to 0");
1210 IPC::ResponseBuilder rb{ctx, 2};
1211 rb.Push(RESULT_UNKNOWN);
1212 return;
1213 }
1214
1215 auto transfer_mem =
1216 system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
1217
1218 if (transfer_mem == nullptr) {
1219 LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
1220 IPC::ResponseBuilder rb{ctx, 2};
1221 rb.Push(RESULT_UNKNOWN);
1222 return;
1223 }
1224
1225 const u8* const mem_begin = transfer_mem->GetPointer();
1226 const u8* const mem_end = mem_begin + transfer_mem->GetSize();
1227 std::vector<u8> memory{mem_begin, mem_end};
1228
1229 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1230 rb.Push(RESULT_SUCCESS);
1231 rb.PushIpcInterface<IStorage>(system, std::move(memory));
1232}
1233
1234void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx) {
1175 IPC::RequestParser rp{ctx}; 1235 IPC::RequestParser rp{ctx};
1176 1236
1177 rp.SetCurrentOffset(3); 1237 const s64 size{rp.Pop<s64>()};
1178 const auto handle{rp.Pop<Kernel::Handle>()}; 1238 const auto handle{ctx.GetCopyHandle(0)};
1239
1240 LOG_DEBUG(Service_AM, "called, size={}, handle={:08X}", size, handle);
1241
1242 if (size <= 0) {
1243 LOG_ERROR(Service_AM, "size is less than or equal to 0");
1244 IPC::ResponseBuilder rb{ctx, 2};
1245 rb.Push(RESULT_UNKNOWN);
1246 return;
1247 }
1179 1248
1180 auto transfer_mem = 1249 auto transfer_mem =
1181 system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle); 1250 system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
1182 1251
1183 if (transfer_mem == nullptr) { 1252 if (transfer_mem == nullptr) {
1184 LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle); 1253 LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
1185 IPC::ResponseBuilder rb{ctx, 2}; 1254 IPC::ResponseBuilder rb{ctx, 2};
1186 rb.Push(RESULT_UNKNOWN); 1255 rb.Push(RESULT_UNKNOWN);
1187 return; 1256 return;
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index f6a453ab7..5d302e155 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -61,8 +61,9 @@ public:
61 void PushMessage(AppletMessage msg); 61 void PushMessage(AppletMessage msg);
62 AppletMessage PopMessage(); 62 AppletMessage PopMessage();
63 std::size_t GetMessageCount() const; 63 std::size_t GetMessageCount() const;
64 void OperationModeChanged();
65 void RequestExit(); 64 void RequestExit();
65 void FocusStateChanged();
66 void OperationModeChanged();
66 67
67private: 68private:
68 std::queue<AppletMessage> messages; 69 std::queue<AppletMessage> messages;
@@ -195,6 +196,7 @@ private:
195 void EndVrModeEx(Kernel::HLERequestContext& ctx); 196 void EndVrModeEx(Kernel::HLERequestContext& ctx);
196 void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx); 197 void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx);
197 void SetCpuBoostMode(Kernel::HLERequestContext& ctx); 198 void SetCpuBoostMode(Kernel::HLERequestContext& ctx);
199 void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(Kernel::HLERequestContext& ctx);
198 200
199 std::shared_ptr<AppletMessageQueue> msg_queue; 201 std::shared_ptr<AppletMessageQueue> msg_queue;
200 bool vr_mode_state{}; 202 bool vr_mode_state{};
@@ -254,6 +256,7 @@ private:
254 void CreateLibraryApplet(Kernel::HLERequestContext& ctx); 256 void CreateLibraryApplet(Kernel::HLERequestContext& ctx);
255 void CreateStorage(Kernel::HLERequestContext& ctx); 257 void CreateStorage(Kernel::HLERequestContext& ctx);
256 void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx); 258 void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx);
259 void CreateHandleStorage(Kernel::HLERequestContext& ctx);
257}; 260};
258 261
259class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { 262class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index e2f3b7563..a56df6a7e 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -17,6 +17,8 @@
17#include "core/hle/kernel/k_writable_event.h" 17#include "core/hle/kernel/k_writable_event.h"
18#include "core/hle/kernel/server_session.h" 18#include "core/hle/kernel/server_session.h"
19#include "core/hle/service/am/am.h" 19#include "core/hle/service/am/am.h"
20#include "core/hle/service/am/applet_ae.h"
21#include "core/hle/service/am/applet_oe.h"
20#include "core/hle/service/am/applets/applets.h" 22#include "core/hle/service/am/applets/applets.h"
21#include "core/hle/service/am/applets/controller.h" 23#include "core/hle/service/am/applets/controller.h"
22#include "core/hle/service/am/applets/error.h" 24#include "core/hle/service/am/applets/error.h"
@@ -24,17 +26,20 @@
24#include "core/hle/service/am/applets/profile_select.h" 26#include "core/hle/service/am/applets/profile_select.h"
25#include "core/hle/service/am/applets/software_keyboard.h" 27#include "core/hle/service/am/applets/software_keyboard.h"
26#include "core/hle/service/am/applets/web_browser.h" 28#include "core/hle/service/am/applets/web_browser.h"
29#include "core/hle/service/sm/sm.h"
27 30
28namespace Service::AM::Applets { 31namespace Service::AM::Applets {
29 32
30AppletDataBroker::AppletDataBroker(Kernel::KernelCore& kernel) { 33AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_)
34 : system{system_}, applet_mode{applet_mode_} {
31 state_changed_event = 35 state_changed_event =
32 Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:StateChangedEvent"); 36 Kernel::KEvent::Create(system.Kernel(), "ILibraryAppletAccessor:StateChangedEvent");
33 state_changed_event->Initialize(); 37 state_changed_event->Initialize();
34 pop_out_data_event = Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:PopDataOutEvent"); 38 pop_out_data_event =
39 Kernel::KEvent::Create(system.Kernel(), "ILibraryAppletAccessor:PopDataOutEvent");
35 pop_out_data_event->Initialize(); 40 pop_out_data_event->Initialize();
36 pop_interactive_out_data_event = 41 pop_interactive_out_data_event = Kernel::KEvent::Create(
37 Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); 42 system.Kernel(), "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
38 pop_interactive_out_data_event->Initialize(); 43 pop_interactive_out_data_event->Initialize();
39} 44}
40 45
@@ -114,6 +119,27 @@ void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&&
114 119
115void AppletDataBroker::SignalStateChanged() const { 120void AppletDataBroker::SignalStateChanged() const {
116 state_changed_event->GetWritableEvent()->Signal(); 121 state_changed_event->GetWritableEvent()->Signal();
122
123 switch (applet_mode) {
124 case LibraryAppletMode::AllForeground:
125 case LibraryAppletMode::AllForegroundInitiallyHidden: {
126 auto applet_oe = system.ServiceManager().GetService<AppletOE>("appletOE");
127 auto applet_ae = system.ServiceManager().GetService<AppletAE>("appletAE");
128
129 if (applet_oe) {
130 applet_oe->GetMessageQueue()->FocusStateChanged();
131 break;
132 }
133
134 if (applet_ae) {
135 applet_ae->GetMessageQueue()->FocusStateChanged();
136 break;
137 }
138 break;
139 }
140 default:
141 break;
142 }
117} 143}
118 144
119std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetNormalDataEvent() const { 145std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetNormalDataEvent() const {
@@ -128,7 +154,8 @@ std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetStateChangedEvent()
128 return state_changed_event->GetReadableEvent(); 154 return state_changed_event->GetReadableEvent();
129} 155}
130 156
131Applet::Applet(Kernel::KernelCore& kernel_) : broker{kernel_} {} 157Applet::Applet(Core::System& system_, LibraryAppletMode applet_mode_)
158 : broker{system_, applet_mode_}, applet_mode{applet_mode_} {}
132 159
133Applet::~Applet() = default; 160Applet::~Applet() = default;
134 161
@@ -241,31 +268,31 @@ void AppletManager::ClearAll() {
241 frontend = {}; 268 frontend = {};
242} 269}
243 270
244std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id) const { 271std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id, LibraryAppletMode mode) const {
245 switch (id) { 272 switch (id) {
246 case AppletId::Auth: 273 case AppletId::Auth:
247 return std::make_shared<Auth>(system, *frontend.parental_controls); 274 return std::make_shared<Auth>(system, mode, *frontend.parental_controls);
248 case AppletId::Controller: 275 case AppletId::Controller:
249 return std::make_shared<Controller>(system, *frontend.controller); 276 return std::make_shared<Controller>(system, mode, *frontend.controller);
250 case AppletId::Error: 277 case AppletId::Error:
251 return std::make_shared<Error>(system, *frontend.error); 278 return std::make_shared<Error>(system, mode, *frontend.error);
252 case AppletId::ProfileSelect: 279 case AppletId::ProfileSelect:
253 return std::make_shared<ProfileSelect>(system, *frontend.profile_select); 280 return std::make_shared<ProfileSelect>(system, mode, *frontend.profile_select);
254 case AppletId::SoftwareKeyboard: 281 case AppletId::SoftwareKeyboard:
255 return std::make_shared<SoftwareKeyboard>(system, *frontend.software_keyboard); 282 return std::make_shared<SoftwareKeyboard>(system, mode, *frontend.software_keyboard);
256 case AppletId::Web: 283 case AppletId::Web:
257 case AppletId::Shop: 284 case AppletId::Shop:
258 case AppletId::OfflineWeb: 285 case AppletId::OfflineWeb:
259 case AppletId::LoginShare: 286 case AppletId::LoginShare:
260 case AppletId::WebAuth: 287 case AppletId::WebAuth:
261 return std::make_shared<WebBrowser>(system, *frontend.web_browser); 288 return std::make_shared<WebBrowser>(system, mode, *frontend.web_browser);
262 case AppletId::PhotoViewer: 289 case AppletId::PhotoViewer:
263 return std::make_shared<PhotoViewer>(system, *frontend.photo_viewer); 290 return std::make_shared<PhotoViewer>(system, mode, *frontend.photo_viewer);
264 default: 291 default:
265 UNIMPLEMENTED_MSG( 292 UNIMPLEMENTED_MSG(
266 "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.", 293 "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.",
267 static_cast<u8>(id)); 294 static_cast<u8>(id));
268 return std::make_shared<StubApplet>(system, id); 295 return std::make_shared<StubApplet>(system, id, mode);
269 } 296 }
270} 297}
271 298
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index b9a006317..4215d2232 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -62,9 +62,17 @@ enum class AppletId : u32 {
62 MyPage = 0x1A, 62 MyPage = 0x1A,
63}; 63};
64 64
65enum class LibraryAppletMode : u32 {
66 AllForeground = 0,
67 Background = 1,
68 NoUI = 2,
69 BackgroundIndirectDisplay = 3,
70 AllForegroundInitiallyHidden = 4,
71};
72
65class AppletDataBroker final { 73class AppletDataBroker final {
66public: 74public:
67 explicit AppletDataBroker(Kernel::KernelCore& kernel_); 75 explicit AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_);
68 ~AppletDataBroker(); 76 ~AppletDataBroker();
69 77
70 struct RawChannelData { 78 struct RawChannelData {
@@ -94,6 +102,9 @@ public:
94 std::shared_ptr<Kernel::KReadableEvent> GetStateChangedEvent() const; 102 std::shared_ptr<Kernel::KReadableEvent> GetStateChangedEvent() const;
95 103
96private: 104private:
105 Core::System& system;
106 LibraryAppletMode applet_mode;
107
97 // Queues are named from applet's perspective 108 // Queues are named from applet's perspective
98 109
99 // PopNormalDataToApplet and PushNormalDataFromGame 110 // PopNormalDataToApplet and PushNormalDataFromGame
@@ -119,7 +130,7 @@ private:
119 130
120class Applet { 131class Applet {
121public: 132public:
122 explicit Applet(Kernel::KernelCore& kernel_); 133 explicit Applet(Core::System& system_, LibraryAppletMode applet_mode_);
123 virtual ~Applet(); 134 virtual ~Applet();
124 135
125 virtual void Initialize(); 136 virtual void Initialize();
@@ -129,10 +140,6 @@ public:
129 virtual void ExecuteInteractive() = 0; 140 virtual void ExecuteInteractive() = 0;
130 virtual void Execute() = 0; 141 virtual void Execute() = 0;
131 142
132 bool IsInitialized() const {
133 return initialized;
134 }
135
136 AppletDataBroker& GetBroker() { 143 AppletDataBroker& GetBroker() {
137 return broker; 144 return broker;
138 } 145 }
@@ -141,6 +148,14 @@ public:
141 return broker; 148 return broker;
142 } 149 }
143 150
151 LibraryAppletMode GetLibraryAppletMode() const {
152 return applet_mode;
153 }
154
155 bool IsInitialized() const {
156 return initialized;
157 }
158
144protected: 159protected:
145 struct CommonArguments { 160 struct CommonArguments {
146 u32_le arguments_version; 161 u32_le arguments_version;
@@ -154,6 +169,7 @@ protected:
154 169
155 CommonArguments common_args{}; 170 CommonArguments common_args{};
156 AppletDataBroker broker; 171 AppletDataBroker broker;
172 LibraryAppletMode applet_mode;
157 bool initialized = false; 173 bool initialized = false;
158}; 174};
159 175
@@ -200,7 +216,7 @@ public:
200 void SetDefaultAppletsIfMissing(); 216 void SetDefaultAppletsIfMissing();
201 void ClearAll(); 217 void ClearAll();
202 218
203 std::shared_ptr<Applet> GetApplet(AppletId id) const; 219 std::shared_ptr<Applet> GetApplet(AppletId id, LibraryAppletMode mode) const;
204 220
205private: 221private:
206 AppletFrontendSet frontend; 222 AppletFrontendSet frontend;
diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp
index c2bfe698f..218c8d1e4 100644
--- a/src/core/hle/service/am/applets/controller.cpp
+++ b/src/core/hle/service/am/applets/controller.cpp
@@ -45,8 +45,9 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters(
45 }; 45 };
46} 46}
47 47
48Controller::Controller(Core::System& system_, const Core::Frontend::ControllerApplet& frontend_) 48Controller::Controller(Core::System& system_, LibraryAppletMode applet_mode_,
49 : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {} 49 const Core::Frontend::ControllerApplet& frontend_)
50 : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
50 51
51Controller::~Controller() = default; 52Controller::~Controller() = default;
52 53
diff --git a/src/core/hle/service/am/applets/controller.h b/src/core/hle/service/am/applets/controller.h
index d4c9da7b1..2d4dae0bd 100644
--- a/src/core/hle/service/am/applets/controller.h
+++ b/src/core/hle/service/am/applets/controller.h
@@ -106,7 +106,8 @@ static_assert(sizeof(ControllerSupportResultInfo) == 0xC,
106 106
107class Controller final : public Applet { 107class Controller final : public Applet {
108public: 108public:
109 explicit Controller(Core::System& system_, const Core::Frontend::ControllerApplet& frontend_); 109 explicit Controller(Core::System& system_, LibraryAppletMode applet_mode_,
110 const Core::Frontend::ControllerApplet& frontend_);
110 ~Controller() override; 111 ~Controller() override;
111 112
112 void Initialize() override; 113 void Initialize() override;
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp
index 0c8b632e8..23e30aa45 100644
--- a/src/core/hle/service/am/applets/error.cpp
+++ b/src/core/hle/service/am/applets/error.cpp
@@ -86,8 +86,9 @@ ResultCode Decode64BitError(u64 error) {
86 86
87} // Anonymous namespace 87} // Anonymous namespace
88 88
89Error::Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_) 89Error::Error(Core::System& system_, LibraryAppletMode applet_mode_,
90 : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {} 90 const Core::Frontend::ErrorApplet& frontend_)
91 : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
91 92
92Error::~Error() = default; 93Error::~Error() = default;
93 94
diff --git a/src/core/hle/service/am/applets/error.h b/src/core/hle/service/am/applets/error.h
index a105cdb0c..e606d12ce 100644
--- a/src/core/hle/service/am/applets/error.h
+++ b/src/core/hle/service/am/applets/error.h
@@ -25,7 +25,8 @@ enum class ErrorAppletMode : u8 {
25 25
26class Error final : public Applet { 26class Error final : public Applet {
27public: 27public:
28 explicit Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_); 28 explicit Error(Core::System& system_, LibraryAppletMode applet_mode_,
29 const Core::Frontend::ErrorApplet& frontend_);
29 ~Error() override; 30 ~Error() override;
30 31
31 void Initialize() override; 32 void Initialize() override;
diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp
index 4d1df5cbe..b26abad36 100644
--- a/src/core/hle/service/am/applets/general_backend.cpp
+++ b/src/core/hle/service/am/applets/general_backend.cpp
@@ -37,8 +37,9 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix)
37 } 37 }
38} 38}
39 39
40Auth::Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_) 40Auth::Auth(Core::System& system_, LibraryAppletMode applet_mode_,
41 : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {} 41 Core::Frontend::ParentalControlsApplet& frontend_)
42 : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
42 43
43Auth::~Auth() = default; 44Auth::~Auth() = default;
44 45
@@ -152,8 +153,9 @@ void Auth::AuthFinished(bool is_successful) {
152 broker.SignalStateChanged(); 153 broker.SignalStateChanged();
153} 154}
154 155
155PhotoViewer::PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_) 156PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_,
156 : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {} 157 const Core::Frontend::PhotoViewerApplet& frontend_)
158 : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
157 159
158PhotoViewer::~PhotoViewer() = default; 160PhotoViewer::~PhotoViewer() = default;
159 161
@@ -202,8 +204,8 @@ void PhotoViewer::ViewFinished() {
202 broker.SignalStateChanged(); 204 broker.SignalStateChanged();
203} 205}
204 206
205StubApplet::StubApplet(Core::System& system_, AppletId id_) 207StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_)
206 : Applet{system_.Kernel()}, id{id_}, system{system_} {} 208 : Applet{system_, applet_mode_}, id{id_}, system{system_} {}
207 209
208StubApplet::~StubApplet() = default; 210StubApplet::~StubApplet() = default;
209 211
diff --git a/src/core/hle/service/am/applets/general_backend.h b/src/core/hle/service/am/applets/general_backend.h
index ba76ae3d3..7496ded88 100644
--- a/src/core/hle/service/am/applets/general_backend.h
+++ b/src/core/hle/service/am/applets/general_backend.h
@@ -20,7 +20,8 @@ enum class AuthAppletType : u32 {
20 20
21class Auth final : public Applet { 21class Auth final : public Applet {
22public: 22public:
23 explicit Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_); 23 explicit Auth(Core::System& system_, LibraryAppletMode applet_mode_,
24 Core::Frontend::ParentalControlsApplet& frontend_);
24 ~Auth() override; 25 ~Auth() override;
25 26
26 void Initialize() override; 27 void Initialize() override;
@@ -50,7 +51,8 @@ enum class PhotoViewerAppletMode : u8 {
50 51
51class PhotoViewer final : public Applet { 52class PhotoViewer final : public Applet {
52public: 53public:
53 explicit PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_); 54 explicit PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_,
55 const Core::Frontend::PhotoViewerApplet& frontend_);
54 ~PhotoViewer() override; 56 ~PhotoViewer() override;
55 57
56 void Initialize() override; 58 void Initialize() override;
@@ -70,7 +72,7 @@ private:
70 72
71class StubApplet final : public Applet { 73class StubApplet final : public Applet {
72public: 74public:
73 explicit StubApplet(Core::System& system_, AppletId id_); 75 explicit StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_);
74 ~StubApplet() override; 76 ~StubApplet() override;
75 77
76 void Initialize() override; 78 void Initialize() override;
diff --git a/src/core/hle/service/am/applets/profile_select.cpp b/src/core/hle/service/am/applets/profile_select.cpp
index 77fba16c7..c91a9776a 100644
--- a/src/core/hle/service/am/applets/profile_select.cpp
+++ b/src/core/hle/service/am/applets/profile_select.cpp
@@ -15,9 +15,9 @@ namespace Service::AM::Applets {
15 15
16constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1}; 16constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1};
17 17
18ProfileSelect::ProfileSelect(Core::System& system_, 18ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_,
19 const Core::Frontend::ProfileSelectApplet& frontend_) 19 const Core::Frontend::ProfileSelectApplet& frontend_)
20 : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {} 20 : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
21 21
22ProfileSelect::~ProfileSelect() = default; 22ProfileSelect::~ProfileSelect() = default;
23 23
diff --git a/src/core/hle/service/am/applets/profile_select.h b/src/core/hle/service/am/applets/profile_select.h
index 648d33a24..f0dd6c1f3 100644
--- a/src/core/hle/service/am/applets/profile_select.h
+++ b/src/core/hle/service/am/applets/profile_select.h
@@ -33,7 +33,7 @@ static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has inco
33 33
34class ProfileSelect final : public Applet { 34class ProfileSelect final : public Applet {
35public: 35public:
36 explicit ProfileSelect(Core::System& system_, 36 explicit ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_,
37 const Core::Frontend::ProfileSelectApplet& frontend_); 37 const Core::Frontend::ProfileSelectApplet& frontend_);
38 ~ProfileSelect() override; 38 ~ProfileSelect() override;
39 39
diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp
index 79b209c6b..73a06def1 100644
--- a/src/core/hle/service/am/applets/software_keyboard.cpp
+++ b/src/core/hle/service/am/applets/software_keyboard.cpp
@@ -1,93 +1,80 @@
1// Copyright 2018 yuzu emulator team 1// Copyright 2021 yuzu Emulator Project
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>
6#include "common/assert.h"
7#include "common/string_util.h" 5#include "common/string_util.h"
8#include "core/core.h" 6#include "core/core.h"
9#include "core/frontend/applets/software_keyboard.h" 7#include "core/frontend/applets/software_keyboard.h"
10#include "core/hle/result.h"
11#include "core/hle/service/am/am.h" 8#include "core/hle/service/am/am.h"
12#include "core/hle/service/am/applets/software_keyboard.h" 9#include "core/hle/service/am/applets/software_keyboard.h"
13 10
14namespace Service::AM::Applets { 11namespace Service::AM::Applets {
15 12
16namespace { 13namespace {
17enum class Request : u32 { 14
18 Finalize = 0x4, 15// The maximum number of UTF-16 characters that can be input into the swkbd text field.
19 SetUserWordInfo = 0x6, 16constexpr u32 DEFAULT_MAX_TEXT_LENGTH = 500;
20 SetCustomizeDic = 0x7, 17
21 Calc = 0xa, 18constexpr std::size_t REPLY_BASE_SIZE = sizeof(SwkbdState) + sizeof(SwkbdReplyType);
22 SetCustomizedDictionaries = 0xb, 19constexpr std::size_t REPLY_UTF8_SIZE = 0x7D4;
23 UnsetCustomizedDictionaries = 0xc, 20constexpr std::size_t REPLY_UTF16_SIZE = 0x3EC;
24 UnknownD = 0xd, 21
25 UnknownE = 0xe, 22constexpr const char* GetTextCheckResultName(SwkbdTextCheckResult text_check_result) {
26}; 23 switch (text_check_result) {
27constexpr std::size_t SWKBD_INLINE_INIT_SIZE = 0x8; 24 case SwkbdTextCheckResult::Success:
28constexpr std::size_t SWKBD_OUTPUT_BUFFER_SIZE = 0x7D8; 25 return "Success";
29constexpr std::size_t SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE = 0x7D4; 26 case SwkbdTextCheckResult::Failure:
30constexpr std::size_t DEFAULT_MAX_LENGTH = 500; 27 return "Failure";
31constexpr bool INTERACTIVE_STATUS_OK = false; 28 case SwkbdTextCheckResult::Confirm:
29 return "Confirm";
30 case SwkbdTextCheckResult::Silent:
31 return "Silent";
32 default:
33 UNIMPLEMENTED_MSG("Unknown TextCheckResult={}", text_check_result);
34 return "Unknown";
35 }
36}
37
38void SetReplyBase(std::vector<u8>& reply, SwkbdState state, SwkbdReplyType reply_type) {
39 std::memcpy(reply.data(), &state, sizeof(SwkbdState));
40 std::memcpy(reply.data() + sizeof(SwkbdState), &reply_type, sizeof(SwkbdReplyType));
41}
42
32} // Anonymous namespace 43} // Anonymous namespace
33static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters( 44
34 KeyboardConfig config, std::u16string initial_text) { 45SoftwareKeyboard::SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_,
35 Core::Frontend::SoftwareKeyboardParameters params{}; 46 Core::Frontend::SoftwareKeyboardApplet& frontend_)
36 47 : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
37 params.submit_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
38 config.submit_text.data(), config.submit_text.size());
39 params.header_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
40 config.header_text.data(), config.header_text.size());
41 params.sub_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(config.sub_text.data(),
42 config.sub_text.size());
43 params.guide_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(config.guide_text.data(),
44 config.guide_text.size());
45 params.initial_text = std::move(initial_text);
46 params.max_length = config.length_limit == 0 ? DEFAULT_MAX_LENGTH : config.length_limit;
47 params.password = static_cast<bool>(config.is_password);
48 params.cursor_at_beginning = static_cast<bool>(config.initial_cursor_position);
49 params.value = static_cast<u8>(config.keyset_disable_bitmask);
50
51 return params;
52}
53
54SoftwareKeyboard::SoftwareKeyboard(Core::System& system_,
55 const Core::Frontend::SoftwareKeyboardApplet& frontend_)
56 : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
57 48
58SoftwareKeyboard::~SoftwareKeyboard() = default; 49SoftwareKeyboard::~SoftwareKeyboard() = default;
59 50
60void SoftwareKeyboard::Initialize() { 51void SoftwareKeyboard::Initialize() {
61 complete = false;
62 is_inline = false;
63 initial_text.clear();
64 final_data.clear();
65
66 Applet::Initialize(); 52 Applet::Initialize();
67 53
68 const auto keyboard_config_storage = broker.PopNormalDataToApplet(); 54 LOG_INFO(Service_AM, "Initializing Software Keyboard Applet with LibraryAppletMode={}",
69 ASSERT(keyboard_config_storage != nullptr); 55 applet_mode);
70 const auto& keyboard_config = keyboard_config_storage->GetData();
71
72 if (keyboard_config.size() == SWKBD_INLINE_INIT_SIZE) {
73 is_inline = true;
74 return;
75 }
76
77 ASSERT(keyboard_config.size() >= sizeof(KeyboardConfig));
78 std::memcpy(&config, keyboard_config.data(), sizeof(KeyboardConfig));
79 56
80 const auto work_buffer_storage = broker.PopNormalDataToApplet(); 57 LOG_DEBUG(Service_AM,
81 ASSERT_OR_EXECUTE(work_buffer_storage != nullptr, { return; }); 58 "Initializing Applet with common_args: arg_version={}, lib_version={}, "
82 const auto& work_buffer = work_buffer_storage->GetData(); 59 "play_startup_sound={}, size={}, system_tick={}, theme_color={}",
60 common_args.arguments_version, common_args.library_version,
61 common_args.play_startup_sound, common_args.size, common_args.system_tick,
62 common_args.theme_color);
83 63
84 if (config.initial_string_size == 0) 64 swkbd_applet_version = SwkbdAppletVersion{common_args.library_version};
85 return;
86 65
87 std::vector<char16_t> string(config.initial_string_size); 66 switch (applet_mode) {
88 std::memcpy(string.data(), work_buffer.data() + config.initial_string_offset, 67 case LibraryAppletMode::AllForeground:
89 string.size() * 2); 68 InitializeForeground();
90 initial_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()); 69 break;
70 case LibraryAppletMode::Background:
71 case LibraryAppletMode::BackgroundIndirectDisplay:
72 InitializeBackground(applet_mode);
73 break;
74 default:
75 UNREACHABLE_MSG("Invalid LibraryAppletMode={}", applet_mode);
76 break;
77 }
91} 78}
92 79
93bool SoftwareKeyboard::TransactionComplete() const { 80bool SoftwareKeyboard::TransactionComplete() const {
@@ -95,106 +82,996 @@ bool SoftwareKeyboard::TransactionComplete() const {
95} 82}
96 83
97ResultCode SoftwareKeyboard::GetStatus() const { 84ResultCode SoftwareKeyboard::GetStatus() const {
98 return RESULT_SUCCESS; 85 return status;
99} 86}
100 87
101void SoftwareKeyboard::ExecuteInteractive() { 88void SoftwareKeyboard::ExecuteInteractive() {
102 if (complete) 89 if (complete) {
103 return; 90 return;
91 }
104 92
105 const auto storage = broker.PopInteractiveDataToApplet(); 93 if (is_background) {
106 ASSERT(storage != nullptr); 94 ProcessInlineKeyboardRequest();
107 const auto data = storage->GetData();
108 if (!is_inline) {
109 const auto status = static_cast<bool>(data[0]);
110 if (status == INTERACTIVE_STATUS_OK) {
111 complete = true;
112 } else {
113 std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string;
114 std::memcpy(string.data(), data.data() + 4, string.size() * 2);
115 frontend.SendTextCheckDialog(
116 Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()),
117 [this] { broker.SignalStateChanged(); });
118 }
119 } else { 95 } else {
120 Request request{}; 96 ProcessTextCheck();
121 std::memcpy(&request, data.data(), sizeof(Request)); 97 }
98}
99
100void SoftwareKeyboard::Execute() {
101 if (complete) {
102 return;
103 }
104
105 if (is_background) {
106 return;
107 }
108
109 ShowNormalKeyboard();
110}
122 111
123 switch (request) { 112void SoftwareKeyboard::SubmitTextNormal(SwkbdResult result, std::u16string submitted_text) {
124 case Request::Finalize: 113 if (complete) {
125 complete = true; 114 return;
126 broker.SignalStateChanged(); 115 }
116
117 if (swkbd_config_common.use_text_check && result == SwkbdResult::Ok) {
118 SubmitForTextCheck(submitted_text);
119 } else {
120 SubmitNormalOutputAndExit(result, submitted_text);
121 }
122}
123
124void SoftwareKeyboard::SubmitTextInline(SwkbdReplyType reply_type, std::u16string submitted_text,
125 s32 cursor_position) {
126 if (complete) {
127 return;
128 }
129
130 current_text = std::move(submitted_text);
131 current_cursor_position = cursor_position;
132
133 if (inline_use_utf8) {
134 switch (reply_type) {
135 case SwkbdReplyType::ChangedString:
136 reply_type = SwkbdReplyType::ChangedStringUtf8;
127 break; 137 break;
128 case Request::Calc: { 138 case SwkbdReplyType::MovedCursor:
129 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{1})); 139 reply_type = SwkbdReplyType::MovedCursorUtf8;
130 broker.SignalStateChanged(); 140 break;
141 case SwkbdReplyType::DecidedEnter:
142 reply_type = SwkbdReplyType::DecidedEnterUtf8;
143 break;
144 default:
131 break; 145 break;
132 } 146 }
147 }
148
149 if (use_changed_string_v2) {
150 switch (reply_type) {
151 case SwkbdReplyType::ChangedString:
152 reply_type = SwkbdReplyType::ChangedStringV2;
153 break;
154 case SwkbdReplyType::ChangedStringUtf8:
155 reply_type = SwkbdReplyType::ChangedStringUtf8V2;
156 break;
133 default: 157 default:
134 UNIMPLEMENTED_MSG("Request {:X} is not implemented", request);
135 break; 158 break;
136 } 159 }
137 } 160 }
161
162 if (use_moved_cursor_v2) {
163 switch (reply_type) {
164 case SwkbdReplyType::MovedCursor:
165 reply_type = SwkbdReplyType::MovedCursorV2;
166 break;
167 case SwkbdReplyType::MovedCursorUtf8:
168 reply_type = SwkbdReplyType::MovedCursorUtf8V2;
169 break;
170 default:
171 break;
172 }
173 }
174
175 SendReply(reply_type);
138} 176}
139 177
140void SoftwareKeyboard::Execute() { 178void SoftwareKeyboard::InitializeForeground() {
141 if (complete) { 179 LOG_INFO(Service_AM, "Initializing Normal Software Keyboard Applet.");
142 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data))); 180
143 broker.SignalStateChanged(); 181 is_background = false;
182
183 const auto swkbd_config_storage = broker.PopNormalDataToApplet();
184 ASSERT(swkbd_config_storage != nullptr);
185
186 const auto& swkbd_config_data = swkbd_config_storage->GetData();
187 ASSERT(swkbd_config_data.size() >= sizeof(SwkbdConfigCommon));
188
189 std::memcpy(&swkbd_config_common, swkbd_config_data.data(), sizeof(SwkbdConfigCommon));
190
191 switch (swkbd_applet_version) {
192 case SwkbdAppletVersion::Version5:
193 case SwkbdAppletVersion::Version65542:
194 ASSERT(swkbd_config_data.size() == sizeof(SwkbdConfigCommon) + sizeof(SwkbdConfigOld));
195 std::memcpy(&swkbd_config_old, swkbd_config_data.data() + sizeof(SwkbdConfigCommon),
196 sizeof(SwkbdConfigOld));
197 break;
198 case SwkbdAppletVersion::Version196615:
199 case SwkbdAppletVersion::Version262152:
200 case SwkbdAppletVersion::Version327689:
201 ASSERT(swkbd_config_data.size() == sizeof(SwkbdConfigCommon) + sizeof(SwkbdConfigOld2));
202 std::memcpy(&swkbd_config_old2, swkbd_config_data.data() + sizeof(SwkbdConfigCommon),
203 sizeof(SwkbdConfigOld2));
204 break;
205 case SwkbdAppletVersion::Version393227:
206 case SwkbdAppletVersion::Version524301:
207 ASSERT(swkbd_config_data.size() == sizeof(SwkbdConfigCommon) + sizeof(SwkbdConfigNew));
208 std::memcpy(&swkbd_config_new, swkbd_config_data.data() + sizeof(SwkbdConfigCommon),
209 sizeof(SwkbdConfigNew));
210 break;
211 default:
212 UNIMPLEMENTED_MSG("Unknown SwkbdConfig revision={} with size={}", swkbd_applet_version,
213 swkbd_config_data.size());
214 ASSERT(swkbd_config_data.size() >= sizeof(SwkbdConfigCommon) + sizeof(SwkbdConfigNew));
215 std::memcpy(&swkbd_config_new, swkbd_config_data.data() + sizeof(SwkbdConfigCommon),
216 sizeof(SwkbdConfigNew));
217 break;
218 }
219
220 const auto work_buffer_storage = broker.PopNormalDataToApplet();
221 ASSERT(work_buffer_storage != nullptr);
222
223 if (swkbd_config_common.initial_string_length == 0) {
224 InitializeFrontendKeyboard();
144 return; 225 return;
145 } 226 }
146 227
147 const auto parameters = ConvertToFrontendParameters(config, initial_text); 228 const auto& work_buffer = work_buffer_storage->GetData();
148 if (!is_inline) { 229
149 frontend.RequestText( 230 std::vector<char16_t> initial_string(swkbd_config_common.initial_string_length);
150 [this](std::optional<std::u16string> text) { WriteText(std::move(text)); }, parameters); 231
232 std::memcpy(initial_string.data(),
233 work_buffer.data() + swkbd_config_common.initial_string_offset,
234 swkbd_config_common.initial_string_length * sizeof(char16_t));
235
236 initial_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(initial_string.data(),
237 initial_string.size());
238
239 LOG_DEBUG(Service_AM, "\nInitial Text: {}", Common::UTF16ToUTF8(initial_text));
240
241 InitializeFrontendKeyboard();
242}
243
244void SoftwareKeyboard::InitializeBackground(LibraryAppletMode applet_mode) {
245 LOG_INFO(Service_AM, "Initializing Inline Software Keyboard Applet.");
246
247 is_background = true;
248
249 const auto swkbd_inline_initialize_arg_storage = broker.PopNormalDataToApplet();
250 ASSERT(swkbd_inline_initialize_arg_storage != nullptr);
251
252 const auto& swkbd_inline_initialize_arg = swkbd_inline_initialize_arg_storage->GetData();
253 ASSERT(swkbd_inline_initialize_arg.size() == sizeof(SwkbdInitializeArg));
254
255 std::memcpy(&swkbd_initialize_arg, swkbd_inline_initialize_arg.data(),
256 swkbd_inline_initialize_arg.size());
257
258 if (swkbd_initialize_arg.library_applet_mode_flag) {
259 ASSERT(applet_mode == LibraryAppletMode::Background);
260 } else {
261 ASSERT(applet_mode == LibraryAppletMode::BackgroundIndirectDisplay);
262 }
263}
264
265void SoftwareKeyboard::ProcessTextCheck() {
266 const auto text_check_storage = broker.PopInteractiveDataToApplet();
267 ASSERT(text_check_storage != nullptr);
268
269 const auto& text_check_data = text_check_storage->GetData();
270 ASSERT(text_check_data.size() == sizeof(SwkbdTextCheck));
271
272 SwkbdTextCheck swkbd_text_check;
273
274 std::memcpy(&swkbd_text_check, text_check_data.data(), sizeof(SwkbdTextCheck));
275
276 std::u16string text_check_message = Common::UTF16StringFromFixedZeroTerminatedBuffer(
277 swkbd_text_check.text_check_message.data(), swkbd_text_check.text_check_message.size());
278
279 LOG_INFO(Service_AM, "\nTextCheckResult: {}\nTextCheckMessage: {}",
280 GetTextCheckResultName(swkbd_text_check.text_check_result),
281 Common::UTF16ToUTF8(text_check_message));
282
283 switch (swkbd_text_check.text_check_result) {
284 case SwkbdTextCheckResult::Success:
285 SubmitNormalOutputAndExit(SwkbdResult::Ok, current_text);
286 break;
287 case SwkbdTextCheckResult::Failure:
288 ShowTextCheckDialog(SwkbdTextCheckResult::Failure, text_check_message);
289 break;
290 case SwkbdTextCheckResult::Confirm:
291 ShowTextCheckDialog(SwkbdTextCheckResult::Confirm, text_check_message);
292 break;
293 case SwkbdTextCheckResult::Silent:
294 default:
295 break;
151 } 296 }
152} 297}
153 298
154void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) { 299void SoftwareKeyboard::ProcessInlineKeyboardRequest() {
155 std::vector<u8> output_main(SWKBD_OUTPUT_BUFFER_SIZE); 300 const auto request_data_storage = broker.PopInteractiveDataToApplet();
301 ASSERT(request_data_storage != nullptr);
302
303 const auto& request_data = request_data_storage->GetData();
304 ASSERT(request_data.size() >= sizeof(SwkbdRequestCommand));
156 305
157 if (text.has_value()) { 306 SwkbdRequestCommand request_command;
158 std::vector<u8> output_sub(SWKBD_OUTPUT_BUFFER_SIZE);
159 307
160 if (config.utf_8) { 308 std::memcpy(&request_command, request_data.data(), sizeof(SwkbdRequestCommand));
161 const u64 size = text->size() + sizeof(u64);
162 const auto new_text = Common::UTF16ToUTF8(*text);
163 309
164 std::memcpy(output_sub.data(), &size, sizeof(u64)); 310 switch (request_command) {
165 std::memcpy(output_sub.data() + 8, new_text.data(), 311 case SwkbdRequestCommand::Finalize:
166 std::min(new_text.size(), SWKBD_OUTPUT_BUFFER_SIZE - 8)); 312 RequestFinalize(request_data);
313 break;
314 case SwkbdRequestCommand::SetUserWordInfo:
315 RequestSetUserWordInfo(request_data);
316 break;
317 case SwkbdRequestCommand::SetCustomizeDic:
318 RequestSetCustomizeDic(request_data);
319 break;
320 case SwkbdRequestCommand::Calc:
321 RequestCalc(request_data);
322 break;
323 case SwkbdRequestCommand::SetCustomizedDictionaries:
324 RequestSetCustomizedDictionaries(request_data);
325 break;
326 case SwkbdRequestCommand::UnsetCustomizedDictionaries:
327 RequestUnsetCustomizedDictionaries(request_data);
328 break;
329 case SwkbdRequestCommand::SetChangedStringV2Flag:
330 RequestSetChangedStringV2Flag(request_data);
331 break;
332 case SwkbdRequestCommand::SetMovedCursorV2Flag:
333 RequestSetMovedCursorV2Flag(request_data);
334 break;
335 default:
336 UNIMPLEMENTED_MSG("Unknown SwkbdRequestCommand={}", request_command);
337 break;
338 }
339}
167 340
168 output_main[0] = INTERACTIVE_STATUS_OK; 341void SoftwareKeyboard::SubmitNormalOutputAndExit(SwkbdResult result,
169 std::memcpy(output_main.data() + 4, new_text.data(), 342 std::u16string submitted_text) {
170 std::min(new_text.size(), SWKBD_OUTPUT_BUFFER_SIZE - 4)); 343 std::vector<u8> out_data(sizeof(SwkbdResult) + STRING_BUFFER_SIZE);
171 } else {
172 const u64 size = text->size() * 2 + sizeof(u64);
173 std::memcpy(output_sub.data(), &size, sizeof(u64));
174 std::memcpy(output_sub.data() + 8, text->data(),
175 std::min(text->size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 8));
176 344
177 output_main[0] = INTERACTIVE_STATUS_OK; 345 if (swkbd_config_common.use_utf8) {
178 std::memcpy(output_main.data() + 4, text->data(), 346 std::string utf8_submitted_text = Common::UTF16ToUTF8(submitted_text);
179 std::min(text->size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 4));
180 }
181 347
182 complete = !config.text_check; 348 LOG_DEBUG(Service_AM, "\nSwkbdResult: {}\nUTF-8 Submitted Text: {}", result,
183 final_data = output_main; 349 utf8_submitted_text);
184 350
185 if (complete) { 351 std::memcpy(out_data.data(), &result, sizeof(SwkbdResult));
186 broker.PushNormalDataFromApplet( 352 std::memcpy(out_data.data() + sizeof(SwkbdResult), utf8_submitted_text.data(),
187 std::make_shared<IStorage>(system, std::move(output_main))); 353 utf8_submitted_text.size());
188 broker.SignalStateChanged();
189 } else {
190 broker.PushInteractiveDataFromApplet(
191 std::make_shared<IStorage>(system, std::move(output_sub)));
192 }
193 } else { 354 } else {
194 output_main[0] = 1; 355 LOG_DEBUG(Service_AM, "\nSwkbdResult: {}\nUTF-16 Submitted Text: {}", result,
195 complete = true; 356 Common::UTF16ToUTF8(submitted_text));
196 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(output_main))); 357
197 broker.SignalStateChanged(); 358 std::memcpy(out_data.data(), &result, sizeof(SwkbdResult));
359 std::memcpy(out_data.data() + sizeof(SwkbdResult), submitted_text.data(),
360 submitted_text.size() * sizeof(char16_t));
361 }
362
363 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
364
365 ExitKeyboard();
366}
367
368void SoftwareKeyboard::SubmitForTextCheck(std::u16string submitted_text) {
369 current_text = std::move(submitted_text);
370
371 std::vector<u8> out_data(sizeof(u64) + STRING_BUFFER_SIZE);
372
373 if (swkbd_config_common.use_utf8) {
374 std::string utf8_submitted_text = Common::UTF16ToUTF8(current_text);
375 const u64 buffer_size = sizeof(u64) + utf8_submitted_text.size();
376
377 LOG_DEBUG(Service_AM, "\nBuffer Size: {}\nUTF-8 Submitted Text: {}", buffer_size,
378 utf8_submitted_text);
379
380 std::memcpy(out_data.data(), &buffer_size, sizeof(u64));
381 std::memcpy(out_data.data() + sizeof(u64), utf8_submitted_text.data(),
382 utf8_submitted_text.size());
383 } else {
384 const u64 buffer_size = sizeof(u64) + current_text.size() * sizeof(char16_t);
385
386 LOG_DEBUG(Service_AM, "\nBuffer Size: {}\nUTF-16 Submitted Text: {}", buffer_size,
387 Common::UTF16ToUTF8(current_text));
388
389 std::memcpy(out_data.data(), &buffer_size, sizeof(u64));
390 std::memcpy(out_data.data() + sizeof(u64), current_text.data(),
391 current_text.size() * sizeof(char16_t));
392 }
393
394 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
395}
396
397void SoftwareKeyboard::SendReply(SwkbdReplyType reply_type) {
398 switch (reply_type) {
399 case SwkbdReplyType::FinishedInitialize:
400 ReplyFinishedInitialize();
401 break;
402 case SwkbdReplyType::Default:
403 ReplyDefault();
404 break;
405 case SwkbdReplyType::ChangedString:
406 ReplyChangedString();
407 break;
408 case SwkbdReplyType::MovedCursor:
409 ReplyMovedCursor();
410 break;
411 case SwkbdReplyType::MovedTab:
412 ReplyMovedTab();
413 break;
414 case SwkbdReplyType::DecidedEnter:
415 ReplyDecidedEnter();
416 break;
417 case SwkbdReplyType::DecidedCancel:
418 ReplyDecidedCancel();
419 break;
420 case SwkbdReplyType::ChangedStringUtf8:
421 ReplyChangedStringUtf8();
422 break;
423 case SwkbdReplyType::MovedCursorUtf8:
424 ReplyMovedCursorUtf8();
425 break;
426 case SwkbdReplyType::DecidedEnterUtf8:
427 ReplyDecidedEnterUtf8();
428 break;
429 case SwkbdReplyType::UnsetCustomizeDic:
430 ReplyUnsetCustomizeDic();
431 break;
432 case SwkbdReplyType::ReleasedUserWordInfo:
433 ReplyReleasedUserWordInfo();
434 break;
435 case SwkbdReplyType::UnsetCustomizedDictionaries:
436 ReplyUnsetCustomizedDictionaries();
437 break;
438 case SwkbdReplyType::ChangedStringV2:
439 ReplyChangedStringV2();
440 break;
441 case SwkbdReplyType::MovedCursorV2:
442 ReplyMovedCursorV2();
443 break;
444 case SwkbdReplyType::ChangedStringUtf8V2:
445 ReplyChangedStringUtf8V2();
446 break;
447 case SwkbdReplyType::MovedCursorUtf8V2:
448 ReplyMovedCursorUtf8V2();
449 break;
450 default:
451 UNIMPLEMENTED_MSG("Unknown SwkbdReplyType={}", reply_type);
452 ReplyDefault();
453 break;
454 }
455}
456
457void SoftwareKeyboard::ChangeState(SwkbdState state) {
458 swkbd_state = state;
459
460 ReplyDefault();
461}
462
463void SoftwareKeyboard::InitializeFrontendKeyboard() {
464 if (is_background) {
465 const auto& appear_arg = swkbd_calc_arg.appear_arg;
466
467 std::u16string ok_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
468 appear_arg.ok_text.data(), appear_arg.ok_text.size());
469
470 const u32 max_text_length =
471 appear_arg.max_text_length > 0 && appear_arg.max_text_length <= DEFAULT_MAX_TEXT_LENGTH
472 ? appear_arg.max_text_length
473 : DEFAULT_MAX_TEXT_LENGTH;
474
475 const u32 min_text_length =
476 appear_arg.min_text_length <= max_text_length ? appear_arg.min_text_length : 0;
477
478 const s32 initial_cursor_position =
479 current_cursor_position > 0 ? current_cursor_position : 0;
480
481 const auto text_draw_type =
482 max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box;
483
484 Core::Frontend::KeyboardInitializeParameters initialize_parameters{
485 .ok_text{ok_text},
486 .header_text{},
487 .sub_text{},
488 .guide_text{},
489 .initial_text{current_text},
490 .max_text_length{max_text_length},
491 .min_text_length{min_text_length},
492 .initial_cursor_position{initial_cursor_position},
493 .type{appear_arg.type},
494 .password_mode{SwkbdPasswordMode::Disabled},
495 .text_draw_type{text_draw_type},
496 .key_disable_flags{appear_arg.key_disable_flags},
497 .use_blur_background{false},
498 .enable_backspace_button{swkbd_calc_arg.enable_backspace_button},
499 .enable_return_button{appear_arg.enable_return_button},
500 .disable_cancel_button{appear_arg.disable_cancel_button},
501 };
502
503 frontend.InitializeKeyboard(
504 true, std::move(initialize_parameters), {},
505 [this](SwkbdReplyType reply_type, std::u16string submitted_text, s32 cursor_position) {
506 SubmitTextInline(reply_type, submitted_text, cursor_position);
507 });
508 } else {
509 std::u16string ok_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
510 swkbd_config_common.ok_text.data(), swkbd_config_common.ok_text.size());
511
512 std::u16string header_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
513 swkbd_config_common.header_text.data(), swkbd_config_common.header_text.size());
514
515 std::u16string sub_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
516 swkbd_config_common.sub_text.data(), swkbd_config_common.sub_text.size());
517
518 std::u16string guide_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
519 swkbd_config_common.guide_text.data(), swkbd_config_common.guide_text.size());
520
521 const u32 max_text_length =
522 swkbd_config_common.max_text_length > 0 &&
523 swkbd_config_common.max_text_length <= DEFAULT_MAX_TEXT_LENGTH
524 ? swkbd_config_common.max_text_length
525 : DEFAULT_MAX_TEXT_LENGTH;
526
527 const u32 min_text_length = swkbd_config_common.min_text_length <= max_text_length
528 ? swkbd_config_common.min_text_length
529 : 0;
530
531 const s32 initial_cursor_position = [this] {
532 switch (swkbd_config_common.initial_cursor_position) {
533 case SwkbdInitialCursorPosition::Start:
534 default:
535 return 0;
536 case SwkbdInitialCursorPosition::End:
537 return static_cast<s32>(initial_text.size());
538 }
539 }();
540
541 const auto text_draw_type = [this, max_text_length] {
542 switch (swkbd_config_common.text_draw_type) {
543 case SwkbdTextDrawType::Line:
544 default:
545 return max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box;
546 case SwkbdTextDrawType::Box:
547 case SwkbdTextDrawType::DownloadCode:
548 return swkbd_config_common.text_draw_type;
549 }
550 }();
551
552 const auto enable_return_button = text_draw_type == SwkbdTextDrawType::Box
553 ? swkbd_config_common.enable_return_button
554 : false;
555
556 const auto disable_cancel_button = swkbd_applet_version >= SwkbdAppletVersion::Version393227
557 ? swkbd_config_new.disable_cancel_button
558 : false;
559
560 Core::Frontend::KeyboardInitializeParameters initialize_parameters{
561 .ok_text{ok_text},
562 .header_text{header_text},
563 .sub_text{sub_text},
564 .guide_text{guide_text},
565 .initial_text{initial_text},
566 .max_text_length{max_text_length},
567 .min_text_length{min_text_length},
568 .initial_cursor_position{initial_cursor_position},
569 .type{swkbd_config_common.type},
570 .password_mode{swkbd_config_common.password_mode},
571 .text_draw_type{text_draw_type},
572 .key_disable_flags{swkbd_config_common.key_disable_flags},
573 .use_blur_background{swkbd_config_common.use_blur_background},
574 .enable_backspace_button{true},
575 .enable_return_button{enable_return_button},
576 .disable_cancel_button{disable_cancel_button},
577 };
578
579 frontend.InitializeKeyboard(false, std::move(initialize_parameters),
580 [this](SwkbdResult result, std::u16string submitted_text) {
581 SubmitTextNormal(result, submitted_text);
582 },
583 {});
584 }
585}
586
587void SoftwareKeyboard::ShowNormalKeyboard() {
588 frontend.ShowNormalKeyboard();
589}
590
591void SoftwareKeyboard::ShowTextCheckDialog(SwkbdTextCheckResult text_check_result,
592 std::u16string text_check_message) {
593 frontend.ShowTextCheckDialog(text_check_result, text_check_message);
594}
595
596void SoftwareKeyboard::ShowInlineKeyboard() {
597 if (swkbd_state != SwkbdState::InitializedIsHidden) {
598 return;
599 }
600
601 ChangeState(SwkbdState::InitializedIsAppearing);
602
603 const auto& appear_arg = swkbd_calc_arg.appear_arg;
604
605 const u32 max_text_length =
606 appear_arg.max_text_length > 0 && appear_arg.max_text_length <= DEFAULT_MAX_TEXT_LENGTH
607 ? appear_arg.max_text_length
608 : DEFAULT_MAX_TEXT_LENGTH;
609
610 const u32 min_text_length =
611 appear_arg.min_text_length <= max_text_length ? appear_arg.min_text_length : 0;
612
613 Core::Frontend::InlineAppearParameters appear_parameters{
614 .max_text_length{max_text_length},
615 .min_text_length{min_text_length},
616 .key_top_scale_x{swkbd_calc_arg.key_top_scale_x},
617 .key_top_scale_y{swkbd_calc_arg.key_top_scale_y},
618 .key_top_translate_x{swkbd_calc_arg.key_top_translate_x},
619 .key_top_translate_y{swkbd_calc_arg.key_top_translate_y},
620 .type{appear_arg.type},
621 .key_disable_flags{appear_arg.key_disable_flags},
622 .key_top_as_floating{swkbd_calc_arg.key_top_as_floating},
623 .enable_backspace_button{swkbd_calc_arg.enable_backspace_button},
624 .enable_return_button{appear_arg.enable_return_button},
625 .disable_cancel_button{appear_arg.disable_cancel_button},
626 };
627
628 frontend.ShowInlineKeyboard(std::move(appear_parameters));
629
630 ChangeState(SwkbdState::InitializedIsShown);
631}
632
633void SoftwareKeyboard::HideInlineKeyboard() {
634 if (swkbd_state != SwkbdState::InitializedIsShown) {
635 return;
636 }
637
638 ChangeState(SwkbdState::InitializedIsDisappearing);
639
640 frontend.HideInlineKeyboard();
641
642 ChangeState(SwkbdState::InitializedIsHidden);
643}
644
645void SoftwareKeyboard::InlineTextChanged() {
646 Core::Frontend::InlineTextParameters text_parameters{
647 .input_text{current_text},
648 .cursor_position{current_cursor_position},
649 };
650
651 frontend.InlineTextChanged(std::move(text_parameters));
652}
653
654void SoftwareKeyboard::ExitKeyboard() {
655 complete = true;
656 status = RESULT_SUCCESS;
657
658 frontend.ExitKeyboard();
659
660 broker.SignalStateChanged();
661}
662
663// Inline Software Keyboard Requests
664
665void SoftwareKeyboard::RequestFinalize(const std::vector<u8>& request_data) {
666 LOG_DEBUG(Service_AM, "Processing Request: Finalize");
667
668 ChangeState(SwkbdState::NotInitialized);
669
670 ExitKeyboard();
671}
672
673void SoftwareKeyboard::RequestSetUserWordInfo(const std::vector<u8>& request_data) {
674 LOG_WARNING(Service_AM, "SetUserWordInfo is not implemented.");
675}
676
677void SoftwareKeyboard::RequestSetCustomizeDic(const std::vector<u8>& request_data) {
678 LOG_WARNING(Service_AM, "SetCustomizeDic is not implemented.");
679}
680
681void SoftwareKeyboard::RequestCalc(const std::vector<u8>& request_data) {
682 LOG_DEBUG(Service_AM, "Processing Request: Calc");
683
684 ASSERT(request_data.size() == sizeof(SwkbdRequestCommand) + sizeof(SwkbdCalcArg));
685
686 std::memcpy(&swkbd_calc_arg, request_data.data() + sizeof(SwkbdRequestCommand),
687 sizeof(SwkbdCalcArg));
688
689 if (swkbd_calc_arg.flags.set_input_text) {
690 current_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
691 swkbd_calc_arg.input_text.data(), swkbd_calc_arg.input_text.size());
692 }
693
694 if (swkbd_calc_arg.flags.set_cursor_position) {
695 current_cursor_position = swkbd_calc_arg.cursor_position;
696 }
697
698 if (swkbd_calc_arg.flags.set_utf8_mode) {
699 inline_use_utf8 = swkbd_calc_arg.utf8_mode;
700 }
701
702 if (swkbd_state <= SwkbdState::InitializedIsHidden &&
703 swkbd_calc_arg.flags.unset_customize_dic) {
704 ReplyUnsetCustomizeDic();
198 } 705 }
706
707 if (swkbd_state <= SwkbdState::InitializedIsHidden &&
708 swkbd_calc_arg.flags.unset_user_word_info) {
709 ReplyReleasedUserWordInfo();
710 }
711
712 if (swkbd_state == SwkbdState::NotInitialized && swkbd_calc_arg.flags.set_initialize_arg) {
713 InitializeFrontendKeyboard();
714
715 ChangeState(SwkbdState::InitializedIsHidden);
716
717 ReplyFinishedInitialize();
718 }
719
720 if (!swkbd_calc_arg.flags.set_initialize_arg &&
721 (swkbd_calc_arg.flags.set_input_text || swkbd_calc_arg.flags.set_cursor_position)) {
722 InlineTextChanged();
723 }
724
725 if (swkbd_state == SwkbdState::InitializedIsHidden && swkbd_calc_arg.flags.appear) {
726 ShowInlineKeyboard();
727 return;
728 }
729
730 if (swkbd_state == SwkbdState::InitializedIsShown && swkbd_calc_arg.flags.disappear) {
731 HideInlineKeyboard();
732 return;
733 }
734}
735
736void SoftwareKeyboard::RequestSetCustomizedDictionaries(const std::vector<u8>& request_data) {
737 LOG_WARNING(Service_AM, "SetCustomizedDictionaries is not implemented.");
738}
739
740void SoftwareKeyboard::RequestUnsetCustomizedDictionaries(const std::vector<u8>& request_data) {
741 LOG_WARNING(Service_AM, "(STUBBED) Processing Request: UnsetCustomizedDictionaries");
742
743 ReplyUnsetCustomizedDictionaries();
744}
745
746void SoftwareKeyboard::RequestSetChangedStringV2Flag(const std::vector<u8>& request_data) {
747 LOG_DEBUG(Service_AM, "Processing Request: SetChangedStringV2Flag");
748
749 ASSERT(request_data.size() == sizeof(SwkbdRequestCommand) + 1);
750
751 std::memcpy(&use_changed_string_v2, request_data.data() + sizeof(SwkbdRequestCommand), 1);
752}
753
754void SoftwareKeyboard::RequestSetMovedCursorV2Flag(const std::vector<u8>& request_data) {
755 LOG_DEBUG(Service_AM, "Processing Request: SetMovedCursorV2Flag");
756
757 ASSERT(request_data.size() == sizeof(SwkbdRequestCommand) + 1);
758
759 std::memcpy(&use_moved_cursor_v2, request_data.data() + sizeof(SwkbdRequestCommand), 1);
760}
761
762// Inline Software Keyboard Replies
763
764void SoftwareKeyboard::ReplyFinishedInitialize() {
765 LOG_DEBUG(Service_AM, "Sending Reply: FinishedInitialize");
766
767 std::vector<u8> reply(REPLY_BASE_SIZE + 1);
768
769 SetReplyBase(reply, swkbd_state, SwkbdReplyType::FinishedInitialize);
770
771 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
772}
773
774void SoftwareKeyboard::ReplyDefault() {
775 LOG_DEBUG(Service_AM, "Sending Reply: Default");
776
777 std::vector<u8> reply(REPLY_BASE_SIZE);
778
779 SetReplyBase(reply, swkbd_state, SwkbdReplyType::Default);
780
781 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
782}
783
784void SoftwareKeyboard::ReplyChangedString() {
785 LOG_DEBUG(Service_AM, "Sending Reply: ChangedString");
786
787 std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg));
788
789 SetReplyBase(reply, swkbd_state, SwkbdReplyType::ChangedString);
790
791 const SwkbdChangedStringArg changed_string_arg{
792 .text_length{static_cast<u32>(current_text.size())},
793 .dictionary_start_cursor_position{-1},
794 .dictionary_end_cursor_position{-1},
795 .cursor_position{current_cursor_position},
796 };
797
798 std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(),
799 current_text.size() * sizeof(char16_t));
800 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &changed_string_arg,
801 sizeof(SwkbdChangedStringArg));
802
803 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
804}
805
806void SoftwareKeyboard::ReplyMovedCursor() {
807 LOG_DEBUG(Service_AM, "Sending Reply: MovedCursor");
808
809 std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg));
810
811 SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedCursor);
812
813 const SwkbdMovedCursorArg moved_cursor_arg{
814 .text_length{static_cast<u32>(current_text.size())},
815 .cursor_position{current_cursor_position},
816 };
817
818 std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(),
819 current_text.size() * sizeof(char16_t));
820 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_cursor_arg,
821 sizeof(SwkbdMovedCursorArg));
822
823 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
824}
825
826void SoftwareKeyboard::ReplyMovedTab() {
827 LOG_DEBUG(Service_AM, "Sending Reply: MovedTab");
828
829 std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedTabArg));
830
831 SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedTab);
832
833 const SwkbdMovedTabArg moved_tab_arg{
834 .text_length{static_cast<u32>(current_text.size())},
835 .cursor_position{current_cursor_position},
836 };
837
838 std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(),
839 current_text.size() * sizeof(char16_t));
840 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_tab_arg,
841 sizeof(SwkbdMovedTabArg));
842
843 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
844}
845
846void SoftwareKeyboard::ReplyDecidedEnter() {
847 LOG_DEBUG(Service_AM, "Sending Reply: DecidedEnter");
848
849 std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdDecidedEnterArg));
850
851 SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedEnter);
852
853 const SwkbdDecidedEnterArg decided_enter_arg{
854 .text_length{static_cast<u32>(current_text.size())},
855 };
856
857 std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(),
858 current_text.size() * sizeof(char16_t));
859 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &decided_enter_arg,
860 sizeof(SwkbdDecidedEnterArg));
861
862 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
863
864 HideInlineKeyboard();
865}
866
867void SoftwareKeyboard::ReplyDecidedCancel() {
868 LOG_DEBUG(Service_AM, "Sending Reply: DecidedCancel");
869
870 std::vector<u8> reply(REPLY_BASE_SIZE);
871
872 SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedCancel);
873
874 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
875
876 HideInlineKeyboard();
877}
878
879void SoftwareKeyboard::ReplyChangedStringUtf8() {
880 LOG_DEBUG(Service_AM, "Sending Reply: ChangedStringUtf8");
881
882 std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg));
883
884 SetReplyBase(reply, swkbd_state, SwkbdReplyType::ChangedStringUtf8);
885
886 std::string utf8_current_text = Common::UTF16ToUTF8(current_text);
887
888 const SwkbdChangedStringArg changed_string_arg{
889 .text_length{static_cast<u32>(current_text.size())},
890 .dictionary_start_cursor_position{-1},
891 .dictionary_end_cursor_position{-1},
892 .cursor_position{current_cursor_position},
893 };
894
895 std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size());
896 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &changed_string_arg,
897 sizeof(SwkbdChangedStringArg));
898
899 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
199} 900}
901
902void SoftwareKeyboard::ReplyMovedCursorUtf8() {
903 LOG_DEBUG(Service_AM, "Sending Reply: MovedCursorUtf8");
904
905 std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg));
906
907 SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedCursorUtf8);
908
909 std::string utf8_current_text = Common::UTF16ToUTF8(current_text);
910
911 const SwkbdMovedCursorArg moved_cursor_arg{
912 .text_length{static_cast<u32>(current_text.size())},
913 .cursor_position{current_cursor_position},
914 };
915
916 std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size());
917 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &moved_cursor_arg,
918 sizeof(SwkbdMovedCursorArg));
919
920 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
921}
922
923void SoftwareKeyboard::ReplyDecidedEnterUtf8() {
924 LOG_DEBUG(Service_AM, "Sending Reply: DecidedEnterUtf8");
925
926 std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdDecidedEnterArg));
927
928 SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedEnterUtf8);
929
930 std::string utf8_current_text = Common::UTF16ToUTF8(current_text);
931
932 const SwkbdDecidedEnterArg decided_enter_arg{
933 .text_length{static_cast<u32>(current_text.size())},
934 };
935
936 std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size());
937 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &decided_enter_arg,
938 sizeof(SwkbdDecidedEnterArg));
939
940 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
941
942 HideInlineKeyboard();
943}
944
945void SoftwareKeyboard::ReplyUnsetCustomizeDic() {
946 LOG_DEBUG(Service_AM, "Sending Reply: UnsetCustomizeDic");
947
948 std::vector<u8> reply(REPLY_BASE_SIZE);
949
950 SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizeDic);
951
952 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
953}
954
955void SoftwareKeyboard::ReplyReleasedUserWordInfo() {
956 LOG_DEBUG(Service_AM, "Sending Reply: ReleasedUserWordInfo");
957
958 std::vector<u8> reply(REPLY_BASE_SIZE);
959
960 SetReplyBase(reply, swkbd_state, SwkbdReplyType::ReleasedUserWordInfo);
961
962 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
963}
964
965void SoftwareKeyboard::ReplyUnsetCustomizedDictionaries() {
966 LOG_DEBUG(Service_AM, "Sending Reply: UnsetCustomizedDictionaries");
967
968 std::vector<u8> reply(REPLY_BASE_SIZE);
969
970 SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizedDictionaries);
971
972 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
973}
974
975void SoftwareKeyboard::ReplyChangedStringV2() {
976 LOG_DEBUG(Service_AM, "Sending Reply: ChangedStringV2");
977
978 std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg) + 1);
979
980 SetReplyBase(reply, swkbd_state, SwkbdReplyType::ChangedStringV2);
981
982 const SwkbdChangedStringArg changed_string_arg{
983 .text_length{static_cast<u32>(current_text.size())},
984 .dictionary_start_cursor_position{-1},
985 .dictionary_end_cursor_position{-1},
986 .cursor_position{current_cursor_position},
987 };
988
989 constexpr u8 flag = 0;
990
991 std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(),
992 current_text.size() * sizeof(char16_t));
993 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &changed_string_arg,
994 sizeof(SwkbdChangedStringArg));
995 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg),
996 &flag, 1);
997
998 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
999}
1000
1001void SoftwareKeyboard::ReplyMovedCursorV2() {
1002 LOG_DEBUG(Service_AM, "Sending Reply: MovedCursorV2");
1003
1004 std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg) + 1);
1005
1006 SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedCursorV2);
1007
1008 const SwkbdMovedCursorArg moved_cursor_arg{
1009 .text_length{static_cast<u32>(current_text.size())},
1010 .cursor_position{current_cursor_position},
1011 };
1012
1013 constexpr u8 flag = 0;
1014
1015 std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(),
1016 current_text.size() * sizeof(char16_t));
1017 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_cursor_arg,
1018 sizeof(SwkbdMovedCursorArg));
1019 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg),
1020 &flag, 1);
1021
1022 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
1023}
1024
1025void SoftwareKeyboard::ReplyChangedStringUtf8V2() {
1026 LOG_DEBUG(Service_AM, "Sending Reply: ChangedStringUtf8V2");
1027
1028 std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg) + 1);
1029
1030 SetReplyBase(reply, swkbd_state, SwkbdReplyType::ChangedStringUtf8V2);
1031
1032 std::string utf8_current_text = Common::UTF16ToUTF8(current_text);
1033
1034 const SwkbdChangedStringArg changed_string_arg{
1035 .text_length{static_cast<u32>(current_text.size())},
1036 .dictionary_start_cursor_position{-1},
1037 .dictionary_end_cursor_position{-1},
1038 .cursor_position{current_cursor_position},
1039 };
1040
1041 constexpr u8 flag = 0;
1042
1043 std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size());
1044 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &changed_string_arg,
1045 sizeof(SwkbdChangedStringArg));
1046 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg),
1047 &flag, 1);
1048
1049 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
1050}
1051
1052void SoftwareKeyboard::ReplyMovedCursorUtf8V2() {
1053 LOG_DEBUG(Service_AM, "Sending Reply: MovedCursorUtf8V2");
1054
1055 std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg) + 1);
1056
1057 SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedCursorUtf8V2);
1058
1059 std::string utf8_current_text = Common::UTF16ToUTF8(current_text);
1060
1061 const SwkbdMovedCursorArg moved_cursor_arg{
1062 .text_length{static_cast<u32>(current_text.size())},
1063 .cursor_position{current_cursor_position},
1064 };
1065
1066 constexpr u8 flag = 0;
1067
1068 std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size());
1069 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &moved_cursor_arg,
1070 sizeof(SwkbdMovedCursorArg));
1071 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg),
1072 &flag, 1);
1073
1074 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
1075}
1076
200} // namespace Service::AM::Applets 1077} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/software_keyboard.h
index 1d260fef8..7c67b7574 100644
--- a/src/core/hle/service/am/applets/software_keyboard.h
+++ b/src/core/hle/service/am/applets/software_keyboard.h
@@ -1,20 +1,14 @@
1// Copyright 2018 yuzu emulator team 1// Copyright 2021 yuzu Emulator Project
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#pragma once 5#pragma once
6 6
7#include <array>
8#include <string>
9#include <vector>
10
11#include "common/common_funcs.h" 7#include "common/common_funcs.h"
12#include "common/common_types.h" 8#include "common/common_types.h"
13#include "common/swap.h" 9#include "core/hle/result.h"
14#include "core/hle/service/am/am.h"
15#include "core/hle/service/am/applets/applets.h" 10#include "core/hle/service/am/applets/applets.h"
16 11#include "core/hle/service/am/applets/software_keyboard_types.h"
17union ResultCode;
18 12
19namespace Core { 13namespace Core {
20class System; 14class System;
@@ -22,45 +16,10 @@ class System;
22 16
23namespace Service::AM::Applets { 17namespace Service::AM::Applets {
24 18
25enum class KeysetDisable : u32 {
26 Space = 0x02,
27 Address = 0x04,
28 Percent = 0x08,
29 Slashes = 0x10,
30 Numbers = 0x40,
31 DownloadCode = 0x80,
32};
33
34struct KeyboardConfig {
35 INSERT_PADDING_BYTES(4);
36 std::array<char16_t, 9> submit_text;
37 u16_le left_symbol_key;
38 u16_le right_symbol_key;
39 INSERT_PADDING_BYTES(1);
40 KeysetDisable keyset_disable_bitmask;
41 u32_le initial_cursor_position;
42 std::array<char16_t, 65> header_text;
43 std::array<char16_t, 129> sub_text;
44 std::array<char16_t, 257> guide_text;
45 u32_le length_limit;
46 INSERT_PADDING_BYTES(4);
47 u32_le is_password;
48 INSERT_PADDING_BYTES(5);
49 bool utf_8;
50 bool draw_background;
51 u32_le initial_string_offset;
52 u32_le initial_string_size;
53 u32_le user_dictionary_offset;
54 u32_le user_dictionary_size;
55 bool text_check;
56 u64_le text_check_callback;
57};
58static_assert(sizeof(KeyboardConfig) == 0x3E0, "KeyboardConfig has incorrect size.");
59
60class SoftwareKeyboard final : public Applet { 19class SoftwareKeyboard final : public Applet {
61public: 20public:
62 explicit SoftwareKeyboard(Core::System& system_, 21 explicit SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_,
63 const Core::Frontend::SoftwareKeyboardApplet& frontend_); 22 Core::Frontend::SoftwareKeyboardApplet& frontend_);
64 ~SoftwareKeyboard() override; 23 ~SoftwareKeyboard() override;
65 24
66 void Initialize() override; 25 void Initialize() override;
@@ -70,17 +29,138 @@ public:
70 void ExecuteInteractive() override; 29 void ExecuteInteractive() override;
71 void Execute() override; 30 void Execute() override;
72 31
73 void WriteText(std::optional<std::u16string> text); 32 /**
33 * Submits the input text to the application.
34 * If text checking is enabled, the application will verify the input text.
35 * If use_utf8 is enabled, the input text will be converted to UTF-8 prior to being submitted.
36 * This should only be used by the normal software keyboard.
37 *
38 * @param result SwkbdResult enum
39 * @param submitted_text UTF-16 encoded string
40 */
41 void SubmitTextNormal(SwkbdResult result, std::u16string submitted_text);
42
43 /**
44 * Submits the input text to the application.
45 * If utf8_mode is enabled, the input text will be converted to UTF-8 prior to being submitted.
46 * This should only be used by the inline software keyboard.
47 *
48 * @param reply_type SwkbdReplyType enum
49 * @param submitted_text UTF-16 encoded string
50 * @param cursor_position The current position of the text cursor
51 */
52 void SubmitTextInline(SwkbdReplyType reply_type, std::u16string submitted_text,
53 s32 cursor_position);
74 54
75private: 55private:
76 const Core::Frontend::SoftwareKeyboardApplet& frontend; 56 /// Initializes the normal software keyboard.
57 void InitializeForeground();
77 58
78 KeyboardConfig config; 59 /// Initializes the inline software keyboard.
79 std::u16string initial_text; 60 void InitializeBackground(LibraryAppletMode applet_mode);
80 bool complete = false; 61
81 bool is_inline = false; 62 /// Processes the text check sent by the application.
82 std::vector<u8> final_data; 63 void ProcessTextCheck();
64
65 /// Processes the inline software keyboard request command sent by the application.
66 void ProcessInlineKeyboardRequest();
67
68 /// Submits the input text and exits the applet.
69 void SubmitNormalOutputAndExit(SwkbdResult result, std::u16string submitted_text);
70
71 /// Submits the input text for text checking.
72 void SubmitForTextCheck(std::u16string submitted_text);
73
74 /// Sends a reply to the application after processing a request command.
75 void SendReply(SwkbdReplyType reply_type);
76
77 /// Changes the inline keyboard state.
78 void ChangeState(SwkbdState state);
79
80 /**
81 * Signals the frontend to initialize the software keyboard with common parameters.
82 * This initializes either the normal software keyboard or the inline software keyboard
83 * depending on the state of is_background.
84 * Note that this does not cause the keyboard to appear.
85 * Use the respective Show*Keyboard() functions to cause the respective keyboards to appear.
86 */
87 void InitializeFrontendKeyboard();
88
89 /// Signals the frontend to show the normal software keyboard.
90 void ShowNormalKeyboard();
91
92 /// Signals the frontend to show the text check dialog.
93 void ShowTextCheckDialog(SwkbdTextCheckResult text_check_result,
94 std::u16string text_check_message);
95
96 /// Signals the frontend to show the inline software keyboard.
97 void ShowInlineKeyboard();
98
99 /// Signals the frontend to hide the inline software keyboard.
100 void HideInlineKeyboard();
101
102 /// Signals the frontend that the current inline keyboard text has changed.
103 void InlineTextChanged();
104
105 /// Signals both the frontend and application that the software keyboard is exiting.
106 void ExitKeyboard();
107
108 // Inline Software Keyboard Requests
109
110 void RequestFinalize(const std::vector<u8>& request_data);
111 void RequestSetUserWordInfo(const std::vector<u8>& request_data);
112 void RequestSetCustomizeDic(const std::vector<u8>& request_data);
113 void RequestCalc(const std::vector<u8>& request_data);
114 void RequestSetCustomizedDictionaries(const std::vector<u8>& request_data);
115 void RequestUnsetCustomizedDictionaries(const std::vector<u8>& request_data);
116 void RequestSetChangedStringV2Flag(const std::vector<u8>& request_data);
117 void RequestSetMovedCursorV2Flag(const std::vector<u8>& request_data);
118
119 // Inline Software Keyboard Replies
120
121 void ReplyFinishedInitialize();
122 void ReplyDefault();
123 void ReplyChangedString();
124 void ReplyMovedCursor();
125 void ReplyMovedTab();
126 void ReplyDecidedEnter();
127 void ReplyDecidedCancel();
128 void ReplyChangedStringUtf8();
129 void ReplyMovedCursorUtf8();
130 void ReplyDecidedEnterUtf8();
131 void ReplyUnsetCustomizeDic();
132 void ReplyReleasedUserWordInfo();
133 void ReplyUnsetCustomizedDictionaries();
134 void ReplyChangedStringV2();
135 void ReplyMovedCursorV2();
136 void ReplyChangedStringUtf8V2();
137 void ReplyMovedCursorUtf8V2();
138
139 Core::Frontend::SoftwareKeyboardApplet& frontend;
83 Core::System& system; 140 Core::System& system;
141
142 SwkbdAppletVersion swkbd_applet_version;
143
144 SwkbdConfigCommon swkbd_config_common;
145 SwkbdConfigOld swkbd_config_old;
146 SwkbdConfigOld2 swkbd_config_old2;
147 SwkbdConfigNew swkbd_config_new;
148 std::u16string initial_text;
149
150 SwkbdState swkbd_state{SwkbdState::NotInitialized};
151 SwkbdInitializeArg swkbd_initialize_arg;
152 SwkbdCalcArg swkbd_calc_arg;
153 bool use_changed_string_v2{false};
154 bool use_moved_cursor_v2{false};
155 bool inline_use_utf8{false};
156 s32 current_cursor_position{};
157
158 std::u16string current_text;
159
160 bool is_background{false};
161
162 bool complete{false};
163 ResultCode status{RESULT_SUCCESS};
84}; 164};
85 165
86} // namespace Service::AM::Applets 166} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/software_keyboard_types.h b/src/core/hle/service/am/applets/software_keyboard_types.h
new file mode 100644
index 000000000..21aa8e800
--- /dev/null
+++ b/src/core/hle/service/am/applets/software_keyboard_types.h
@@ -0,0 +1,295 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8
9#include "common/bit_field.h"
10#include "common/common_funcs.h"
11#include "common/common_types.h"
12#include "common/swap.h"
13
14namespace Service::AM::Applets {
15
16constexpr std::size_t MAX_OK_TEXT_LENGTH = 8;
17constexpr std::size_t MAX_HEADER_TEXT_LENGTH = 64;
18constexpr std::size_t MAX_SUB_TEXT_LENGTH = 128;
19constexpr std::size_t MAX_GUIDE_TEXT_LENGTH = 256;
20constexpr std::size_t STRING_BUFFER_SIZE = 0x7D4;
21
22enum class SwkbdAppletVersion : u32_le {
23 Version5 = 0x5, // 1.0.0
24 Version65542 = 0x10006, // 2.0.0 - 2.3.0
25 Version196615 = 0x30007, // 3.0.0 - 3.0.2
26 Version262152 = 0x40008, // 4.0.0 - 4.1.0
27 Version327689 = 0x50009, // 5.0.0 - 5.1.0
28 Version393227 = 0x6000B, // 6.0.0 - 7.0.1
29 Version524301 = 0x8000D, // 8.0.0+
30};
31
32enum class SwkbdType : u32 {
33 Normal,
34 NumberPad,
35 Qwerty,
36 Unknown3,
37 Latin,
38 SimplifiedChinese,
39 TraditionalChinese,
40 Korean,
41};
42
43enum class SwkbdInitialCursorPosition : u32 {
44 Start,
45 End,
46};
47
48enum class SwkbdPasswordMode : u32 {
49 Disabled,
50 Enabled,
51};
52
53enum class SwkbdTextDrawType : u32 {
54 Line,
55 Box,
56 DownloadCode,
57};
58
59enum class SwkbdResult : u32 {
60 Ok,
61 Cancel,
62};
63
64enum class SwkbdTextCheckResult : u32 {
65 Success,
66 Failure,
67 Confirm,
68 Silent,
69};
70
71enum class SwkbdState : u32 {
72 NotInitialized = 0x0,
73 InitializedIsHidden = 0x1,
74 InitializedIsAppearing = 0x2,
75 InitializedIsShown = 0x3,
76 InitializedIsDisappearing = 0x4,
77};
78
79enum class SwkbdRequestCommand : u32 {
80 Finalize = 0x4,
81 SetUserWordInfo = 0x6,
82 SetCustomizeDic = 0x7,
83 Calc = 0xA,
84 SetCustomizedDictionaries = 0xB,
85 UnsetCustomizedDictionaries = 0xC,
86 SetChangedStringV2Flag = 0xD,
87 SetMovedCursorV2Flag = 0xE,
88};
89
90enum class SwkbdReplyType : u32 {
91 FinishedInitialize = 0x0,
92 Default = 0x1,
93 ChangedString = 0x2,
94 MovedCursor = 0x3,
95 MovedTab = 0x4,
96 DecidedEnter = 0x5,
97 DecidedCancel = 0x6,
98 ChangedStringUtf8 = 0x7,
99 MovedCursorUtf8 = 0x8,
100 DecidedEnterUtf8 = 0x9,
101 UnsetCustomizeDic = 0xA,
102 ReleasedUserWordInfo = 0xB,
103 UnsetCustomizedDictionaries = 0xC,
104 ChangedStringV2 = 0xD,
105 MovedCursorV2 = 0xE,
106 ChangedStringUtf8V2 = 0xF,
107 MovedCursorUtf8V2 = 0x10,
108};
109
110struct SwkbdKeyDisableFlags {
111 union {
112 u32 raw{};
113
114 BitField<1, 1, u32> space;
115 BitField<2, 1, u32> at;
116 BitField<3, 1, u32> percent;
117 BitField<4, 1, u32> slash;
118 BitField<5, 1, u32> backslash;
119 BitField<6, 1, u32> numbers;
120 BitField<7, 1, u32> download_code;
121 BitField<8, 1, u32> username;
122 };
123};
124static_assert(sizeof(SwkbdKeyDisableFlags) == 0x4, "SwkbdKeyDisableFlags has incorrect size.");
125
126struct SwkbdConfigCommon {
127 SwkbdType type{};
128 std::array<char16_t, MAX_OK_TEXT_LENGTH + 1> ok_text{};
129 char16_t left_optional_symbol_key{};
130 char16_t right_optional_symbol_key{};
131 bool use_prediction{};
132 INSERT_PADDING_BYTES(1);
133 SwkbdKeyDisableFlags key_disable_flags{};
134 SwkbdInitialCursorPosition initial_cursor_position{};
135 std::array<char16_t, MAX_HEADER_TEXT_LENGTH + 1> header_text{};
136 std::array<char16_t, MAX_SUB_TEXT_LENGTH + 1> sub_text{};
137 std::array<char16_t, MAX_GUIDE_TEXT_LENGTH + 1> guide_text{};
138 u32 max_text_length{};
139 u32 min_text_length{};
140 SwkbdPasswordMode password_mode{};
141 SwkbdTextDrawType text_draw_type{};
142 bool enable_return_button{};
143 bool use_utf8{};
144 bool use_blur_background{};
145 INSERT_PADDING_BYTES(1);
146 u32 initial_string_offset{};
147 u32 initial_string_length{};
148 u32 user_dictionary_offset{};
149 u32 user_dictionary_entries{};
150 bool use_text_check{};
151 INSERT_PADDING_BYTES(3);
152};
153static_assert(sizeof(SwkbdConfigCommon) == 0x3D4, "SwkbdConfigCommon has incorrect size.");
154
155#pragma pack(push, 4)
156// SwkbdAppletVersion 0x5, 0x10006
157struct SwkbdConfigOld {
158 INSERT_PADDING_WORDS(1);
159 VAddr text_check_callback{};
160};
161static_assert(sizeof(SwkbdConfigOld) == 0x3E0 - sizeof(SwkbdConfigCommon),
162 "SwkbdConfigOld has incorrect size.");
163
164// SwkbdAppletVersion 0x30007, 0x40008, 0x50009
165struct SwkbdConfigOld2 {
166 INSERT_PADDING_WORDS(1);
167 VAddr text_check_callback{};
168 std::array<u32, 8> text_grouping{};
169};
170static_assert(sizeof(SwkbdConfigOld2) == 0x400 - sizeof(SwkbdConfigCommon),
171 "SwkbdConfigOld2 has incorrect size.");
172
173// SwkbdAppletVersion 0x6000B, 0x8000D
174struct SwkbdConfigNew {
175 std::array<u32, 8> text_grouping{};
176 std::array<u64, 24> customized_dictionary_set_entries{};
177 u8 total_customized_dictionary_set_entries{};
178 bool disable_cancel_button{};
179 INSERT_PADDING_BYTES(18);
180};
181static_assert(sizeof(SwkbdConfigNew) == 0x4C8 - sizeof(SwkbdConfigCommon),
182 "SwkbdConfigNew has incorrect size.");
183#pragma pack(pop)
184
185struct SwkbdTextCheck {
186 SwkbdTextCheckResult text_check_result{};
187 std::array<char16_t, STRING_BUFFER_SIZE / 2> text_check_message{};
188};
189static_assert(sizeof(SwkbdTextCheck) == 0x7D8, "SwkbdTextCheck has incorrect size.");
190
191struct SwkbdCalcArgFlags {
192 union {
193 u64 raw{};
194
195 BitField<0, 1, u64> set_initialize_arg;
196 BitField<1, 1, u64> set_volume;
197 BitField<2, 1, u64> appear;
198 BitField<3, 1, u64> set_input_text;
199 BitField<4, 1, u64> set_cursor_position;
200 BitField<5, 1, u64> set_utf8_mode;
201 BitField<6, 1, u64> unset_customize_dic;
202 BitField<7, 1, u64> disappear;
203 BitField<8, 1, u64> unknown;
204 BitField<9, 1, u64> set_key_top_translate_scale;
205 BitField<10, 1, u64> unset_user_word_info;
206 BitField<11, 1, u64> set_disable_hardware_keyboard;
207 };
208};
209static_assert(sizeof(SwkbdCalcArgFlags) == 0x8, "SwkbdCalcArgFlags has incorrect size.");
210
211struct SwkbdInitializeArg {
212 u32 unknown{};
213 bool library_applet_mode_flag{};
214 bool is_above_hos_500{};
215 INSERT_PADDING_BYTES(2);
216};
217static_assert(sizeof(SwkbdInitializeArg) == 0x8, "SwkbdInitializeArg has incorrect size.");
218
219struct SwkbdAppearArg {
220 SwkbdType type{};
221 std::array<char16_t, MAX_OK_TEXT_LENGTH + 1> ok_text{};
222 char16_t left_optional_symbol_key{};
223 char16_t right_optional_symbol_key{};
224 bool use_prediction{};
225 bool disable_cancel_button{};
226 SwkbdKeyDisableFlags key_disable_flags{};
227 u32 max_text_length{};
228 u32 min_text_length{};
229 bool enable_return_button{};
230 INSERT_PADDING_BYTES(3);
231 u32 flags{};
232 INSERT_PADDING_WORDS(6);
233};
234static_assert(sizeof(SwkbdAppearArg) == 0x48, "SwkbdAppearArg has incorrect size.");
235
236struct SwkbdCalcArg {
237 u32 unknown{};
238 u16 calc_arg_size{};
239 INSERT_PADDING_BYTES(2);
240 SwkbdCalcArgFlags flags{};
241 SwkbdInitializeArg initialize_arg{};
242 f32 volume{};
243 s32 cursor_position{};
244 SwkbdAppearArg appear_arg{};
245 std::array<char16_t, 0x1FA> input_text{};
246 bool utf8_mode{};
247 INSERT_PADDING_BYTES(1);
248 bool enable_backspace_button{};
249 INSERT_PADDING_BYTES(3);
250 bool key_top_as_floating{};
251 bool footer_scalable{};
252 bool alpha_enabled_in_input_mode{};
253 u8 input_mode_fade_type{};
254 bool disable_touch{};
255 bool disable_hardware_keyboard{};
256 INSERT_PADDING_BYTES(8);
257 f32 key_top_scale_x{};
258 f32 key_top_scale_y{};
259 f32 key_top_translate_x{};
260 f32 key_top_translate_y{};
261 f32 key_top_bg_alpha{};
262 f32 footer_bg_alpha{};
263 f32 balloon_scale{};
264 INSERT_PADDING_WORDS(4);
265 u8 se_group{};
266 INSERT_PADDING_BYTES(3);
267};
268static_assert(sizeof(SwkbdCalcArg) == 0x4A0, "SwkbdCalcArg has incorrect size.");
269
270struct SwkbdChangedStringArg {
271 u32 text_length{};
272 s32 dictionary_start_cursor_position{};
273 s32 dictionary_end_cursor_position{};
274 s32 cursor_position{};
275};
276static_assert(sizeof(SwkbdChangedStringArg) == 0x10, "SwkbdChangedStringArg has incorrect size.");
277
278struct SwkbdMovedCursorArg {
279 u32 text_length{};
280 s32 cursor_position{};
281};
282static_assert(sizeof(SwkbdMovedCursorArg) == 0x8, "SwkbdMovedCursorArg has incorrect size.");
283
284struct SwkbdMovedTabArg {
285 u32 text_length{};
286 s32 cursor_position{};
287};
288static_assert(sizeof(SwkbdMovedTabArg) == 0x8, "SwkbdMovedTabArg has incorrect size.");
289
290struct SwkbdDecidedEnterArg {
291 u32 text_length{};
292};
293static_assert(sizeof(SwkbdDecidedEnterArg) == 0x4, "SwkbdDecidedEnterArg has incorrect size.");
294
295} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp
index 2ab420789..2404921fd 100644
--- a/src/core/hle/service/am/applets/web_browser.cpp
+++ b/src/core/hle/service/am/applets/web_browser.cpp
@@ -208,8 +208,9 @@ void ExtractSharedFonts(Core::System& system) {
208 208
209} // namespace 209} // namespace
210 210
211WebBrowser::WebBrowser(Core::System& system_, const Core::Frontend::WebBrowserApplet& frontend_) 211WebBrowser::WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_,
212 : Applet{system_.Kernel()}, frontend(frontend_), system{system_} {} 212 const Core::Frontend::WebBrowserApplet& frontend_)
213 : Applet{system_, applet_mode_}, frontend(frontend_), system{system_} {}
213 214
214WebBrowser::~WebBrowser() = default; 215WebBrowser::~WebBrowser() = default;
215 216
diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/web_browser.h
index 04c274754..21fd910c2 100644
--- a/src/core/hle/service/am/applets/web_browser.h
+++ b/src/core/hle/service/am/applets/web_browser.h
@@ -25,7 +25,8 @@ namespace Service::AM::Applets {
25 25
26class WebBrowser final : public Applet { 26class WebBrowser final : public Applet {
27public: 27public:
28 WebBrowser(Core::System& system_, const Core::Frontend::WebBrowserApplet& frontend_); 28 WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_,
29 const Core::Frontend::WebBrowserApplet& frontend_);
29 30
30 ~WebBrowser() override; 31 ~WebBrowser() override;
31 32
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index 0f51e5871..75867e349 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -7,6 +7,7 @@
7#include <vector> 7#include <vector>
8 8
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "common/settings.h"
10#include "core/core.h" 11#include "core/core.h"
11#include "core/file_sys/common_funcs.h" 12#include "core/file_sys/common_funcs.h"
12#include "core/file_sys/content_archive.h" 13#include "core/file_sys/content_archive.h"
@@ -21,7 +22,6 @@
21#include "core/hle/kernel/process.h" 22#include "core/hle/kernel/process.h"
22#include "core/hle/service/aoc/aoc_u.h" 23#include "core/hle/service/aoc/aoc_u.h"
23#include "core/loader/loader.h" 24#include "core/loader/loader.h"
24#include "core/settings.h"
25 25
26namespace Service::AOC { 26namespace Service::AOC {
27 27
diff --git a/src/core/hle/service/apm/controller.cpp b/src/core/hle/service/apm/controller.cpp
index 03636642b..00c174bb0 100644
--- a/src/core/hle/service/apm/controller.cpp
+++ b/src/core/hle/service/apm/controller.cpp
@@ -7,9 +7,9 @@
7#include <utility> 7#include <utility>
8 8
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "common/settings.h"
10#include "core/core_timing.h" 11#include "core/core_timing.h"
11#include "core/hle/service/apm/controller.h" 12#include "core/hle/service/apm/controller.h"
12#include "core/settings.h"
13 13
14namespace Service::APM { 14namespace Service::APM {
15 15
diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp
index e43f3f47f..78c047bd2 100644
--- a/src/core/hle/service/bcat/backend/boxcat.cpp
+++ b/src/core/hle/service/bcat/backend/boxcat.cpp
@@ -9,6 +9,7 @@
9#include "common/hex_util.h" 9#include "common/hex_util.h"
10#include "common/logging/backend.h" 10#include "common/logging/backend.h"
11#include "common/logging/log.h" 11#include "common/logging/log.h"
12#include "common/settings.h"
12#include "core/core.h" 13#include "core/core.h"
13#include "core/file_sys/vfs.h" 14#include "core/file_sys/vfs.h"
14#include "core/file_sys/vfs_libzip.h" 15#include "core/file_sys/vfs_libzip.h"
@@ -16,7 +17,6 @@
16#include "core/frontend/applets/error.h" 17#include "core/frontend/applets/error.h"
17#include "core/hle/service/am/applets/applets.h" 18#include "core/hle/service/am/applets/applets.h"
18#include "core/hle/service/bcat/backend/boxcat.h" 19#include "core/hle/service/bcat/backend/boxcat.h"
19#include "core/settings.h"
20 20
21namespace Service::BCAT { 21namespace Service::BCAT {
22namespace { 22namespace {
diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp
index b68e2c345..c7dd04a6e 100644
--- a/src/core/hle/service/bcat/module.cpp
+++ b/src/core/hle/service/bcat/module.cpp
@@ -7,6 +7,7 @@
7#include "backend/boxcat.h" 7#include "backend/boxcat.h"
8#include "common/hex_util.h" 8#include "common/hex_util.h"
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "common/settings.h"
10#include "common/string_util.h" 11#include "common/string_util.h"
11#include "core/core.h" 12#include "core/core.h"
12#include "core/file_sys/vfs.h" 13#include "core/file_sys/vfs.h"
@@ -18,7 +19,6 @@
18#include "core/hle/service/bcat/bcat.h" 19#include "core/hle/service/bcat/bcat.h"
19#include "core/hle/service/bcat/module.h" 20#include "core/hle/service/bcat/module.h"
20#include "core/hle/service/filesystem/filesystem.h" 21#include "core/hle/service/filesystem/filesystem.h"
21#include "core/settings.h"
22 22
23namespace Service::BCAT { 23namespace Service::BCAT {
24 24
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index b15c737e1..72ad273b2 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -6,6 +6,7 @@
6 6
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/file_util.h" 8#include "common/file_util.h"
9#include "common/settings.h"
9#include "core/core.h" 10#include "core/core.h"
10#include "core/file_sys/bis_factory.h" 11#include "core/file_sys/bis_factory.h"
11#include "core/file_sys/card_image.h" 12#include "core/file_sys/card_image.h"
@@ -26,7 +27,6 @@
26#include "core/hle/service/filesystem/fsp_pr.h" 27#include "core/hle/service/filesystem/fsp_pr.h"
27#include "core/hle/service/filesystem/fsp_srv.h" 28#include "core/hle/service/filesystem/fsp_srv.h"
28#include "core/loader/loader.h" 29#include "core/loader/loader.h"
29#include "core/settings.h"
30 30
31namespace Service::FileSystem { 31namespace Service::FileSystem {
32 32
diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp
index 322125135..7b1c6677c 100644
--- a/src/core/hle/service/glue/arp.cpp
+++ b/src/core/hle/service/glue/arp.cpp
@@ -157,9 +157,9 @@ class IRegistrar final : public ServiceFramework<IRegistrar> {
157 friend class ARP_W; 157 friend class ARP_W;
158 158
159public: 159public:
160 explicit IRegistrar( 160 using IssuerFn = std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)>;
161 Core::System& system_, 161
162 std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)> issuer) 162 explicit IRegistrar(Core::System& system_, IssuerFn&& issuer)
163 : ServiceFramework{system_, "IRegistrar"}, issue_process_id{std::move(issuer)} { 163 : ServiceFramework{system_, "IRegistrar"}, issue_process_id{std::move(issuer)} {
164 // clang-format off 164 // clang-format off
165 static const FunctionInfo functions[] = { 165 static const FunctionInfo functions[] = {
@@ -238,9 +238,9 @@ private:
238 rb.Push(RESULT_SUCCESS); 238 rb.Push(RESULT_SUCCESS);
239 } 239 }
240 240
241 std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)> issue_process_id; 241 IssuerFn issue_process_id;
242 bool issued = false; 242 bool issued = false;
243 ApplicationLaunchProperty launch; 243 ApplicationLaunchProperty launch{};
244 std::vector<u8> control; 244 std::vector<u8> control;
245}; 245};
246 246
diff --git a/src/core/hle/service/glue/ectx.cpp b/src/core/hle/service/glue/ectx.cpp
new file mode 100644
index 000000000..249c6f003
--- /dev/null
+++ b/src/core/hle/service/glue/ectx.cpp
@@ -0,0 +1,22 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/glue/ectx.h"
6
7namespace Service::Glue {
8
9ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "CreateContextRegistrar"},
13 {1, nullptr, "CommitContext"},
14 };
15 // clang-format on
16
17 RegisterHandlers(functions);
18}
19
20ECTX_AW::~ECTX_AW() = default;
21
22} // namespace Service::Glue
diff --git a/src/core/hle/service/glue/ectx.h b/src/core/hle/service/glue/ectx.h
new file mode 100644
index 000000000..b275e808a
--- /dev/null
+++ b/src/core/hle/service/glue/ectx.h
@@ -0,0 +1,21 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Core {
10class System;
11}
12
13namespace Service::Glue {
14
15class ECTX_AW final : public ServiceFramework<ECTX_AW> {
16public:
17 explicit ECTX_AW(Core::System& system_);
18 ~ECTX_AW() override;
19};
20
21} // namespace Service::Glue
diff --git a/src/core/hle/service/glue/glue.cpp b/src/core/hle/service/glue/glue.cpp
index 4eafbe5fa..a08dc9758 100644
--- a/src/core/hle/service/glue/glue.cpp
+++ b/src/core/hle/service/glue/glue.cpp
@@ -6,6 +6,7 @@
6#include "core/core.h" 6#include "core/core.h"
7#include "core/hle/service/glue/arp.h" 7#include "core/hle/service/glue/arp.h"
8#include "core/hle/service/glue/bgtc.h" 8#include "core/hle/service/glue/bgtc.h"
9#include "core/hle/service/glue/ectx.h"
9#include "core/hle/service/glue/glue.h" 10#include "core/hle/service/glue/glue.h"
10 11
11namespace Service::Glue { 12namespace Service::Glue {
@@ -20,6 +21,9 @@ void InstallInterfaces(Core::System& system) {
20 // BackGround Task Controller 21 // BackGround Task Controller
21 std::make_shared<BGTC_T>(system)->InstallAsService(system.ServiceManager()); 22 std::make_shared<BGTC_T>(system)->InstallAsService(system.ServiceManager());
22 std::make_shared<BGTC_SC>(system)->InstallAsService(system.ServiceManager()); 23 std::make_shared<BGTC_SC>(system)->InstallAsService(system.ServiceManager());
24
25 // Error Context
26 std::make_shared<ECTX_AW>(system)->InstallAsService(system.ServiceManager());
23} 27}
24 28
25} // namespace Service::Glue 29} // namespace Service::Glue
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp
index ad251ed4a..a460f2f79 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ b/src/core/hle/service/hid/controllers/debug_pad.cpp
@@ -4,9 +4,9 @@
4 4
5#include <cstring> 5#include <cstring>
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "common/settings.h"
7#include "core/core_timing.h" 8#include "core/core_timing.h"
8#include "core/hle/service/hid/controllers/debug_pad.h" 9#include "core/hle/service/hid/controllers/debug_pad.h"
9#include "core/settings.h"
10 10
11namespace Service::HID { 11namespace Service::HID {
12 12
diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h
index 555b29d76..0593d7d39 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.h
+++ b/src/core/hle/service/hid/controllers/debug_pad.h
@@ -8,10 +8,10 @@
8#include "common/bit_field.h" 8#include "common/bit_field.h"
9#include "common/common_funcs.h" 9#include "common/common_funcs.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/settings.h"
11#include "common/swap.h" 12#include "common/swap.h"
12#include "core/frontend/input.h" 13#include "core/frontend/input.h"
13#include "core/hle/service/hid/controllers/controller_base.h" 14#include "core/hle/service/hid/controllers/controller_base.h"
14#include "core/settings.h"
15 15
16namespace Service::HID { 16namespace Service::HID {
17class Controller_DebugPad final : public ControllerBase { 17class Controller_DebugPad final : public ControllerBase {
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp
index 93c43a203..155808f6a 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/core/hle/service/hid/controllers/gesture.cpp
@@ -5,10 +5,10 @@
5#include <cstring> 5#include <cstring>
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "common/settings.h"
8#include "core/core_timing.h" 9#include "core/core_timing.h"
9#include "core/frontend/emu_window.h" 10#include "core/frontend/emu_window.h"
10#include "core/hle/service/hid/controllers/gesture.h" 11#include "core/hle/service/hid/controllers/gesture.h"
11#include "core/settings.h"
12 12
13namespace Service::HID { 13namespace Service::HID {
14constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00; 14constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00;
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index c4a59147d..18b76038f 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -4,9 +4,9 @@
4 4
5#include <cstring> 5#include <cstring>
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "common/settings.h"
7#include "core/core_timing.h" 8#include "core/core_timing.h"
8#include "core/hle/service/hid/controllers/keyboard.h" 9#include "core/hle/service/hid/controllers/keyboard.h"
9#include "core/settings.h"
10 10
11namespace Service::HID { 11namespace Service::HID {
12constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; 12constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800;
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h
index b5b281752..e72948591 100644
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ b/src/core/hle/service/hid/controllers/keyboard.h
@@ -8,10 +8,10 @@
8#include "common/bit_field.h" 8#include "common/bit_field.h"
9#include "common/common_funcs.h" 9#include "common/common_funcs.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/settings.h"
11#include "common/swap.h" 12#include "common/swap.h"
12#include "core/frontend/input.h" 13#include "core/frontend/input.h"
13#include "core/hle/service/hid/controllers/controller_base.h" 14#include "core/hle/service/hid/controllers/controller_base.h"
14#include "core/settings.h"
15 15
16namespace Service::HID { 16namespace Service::HID {
17class Controller_Keyboard final : public ControllerBase { 17class Controller_Keyboard final : public ControllerBase {
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h
index 3b432a36e..0ec0c2b94 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/core/hle/service/hid/controllers/mouse.h
@@ -7,10 +7,10 @@
7#include <array> 7#include <array>
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#include "common/settings.h"
10#include "common/swap.h" 11#include "common/swap.h"
11#include "core/frontend/input.h" 12#include "core/frontend/input.h"
12#include "core/hle/service/hid/controllers/controller_base.h" 13#include "core/hle/service/hid/controllers/controller_base.h"
13#include "core/settings.h"
14 14
15namespace Service::HID { 15namespace Service::HID {
16class Controller_Mouse final : public ControllerBase { 16class Controller_Mouse final : public ControllerBase {
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 673db68c7..113a41254 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -9,6 +9,7 @@
9#include "common/bit_field.h" 9#include "common/bit_field.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/logging/log.h" 11#include "common/logging/log.h"
12#include "common/settings.h"
12#include "core/core.h" 13#include "core/core.h"
13#include "core/core_timing.h" 14#include "core/core_timing.h"
14#include "core/frontend/input.h" 15#include "core/frontend/input.h"
@@ -17,7 +18,6 @@
17#include "core/hle/kernel/k_writable_event.h" 18#include "core/hle/kernel/k_writable_event.h"
18#include "core/hle/kernel/kernel.h" 19#include "core/hle/kernel/kernel.h"
19#include "core/hle/service/hid/controllers/npad.h" 20#include "core/hle/service/hid/controllers/npad.h"
20#include "core/settings.h"
21 21
22namespace Service::HID { 22namespace Service::HID {
23constexpr s32 HID_JOYSTICK_MAX = 0x7fff; 23constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
@@ -147,7 +147,7 @@ bool Controller_NPad::IsDeviceHandleValid(const DeviceHandle& device_handle) {
147 device_handle.device_index < DeviceIndex::MaxDeviceIndex; 147 device_handle.device_index < DeviceIndex::MaxDeviceIndex;
148} 148}
149 149
150Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) { 150Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system) {
151 latest_vibration_values.fill({DEFAULT_VIBRATION_VALUE, DEFAULT_VIBRATION_VALUE}); 151 latest_vibration_values.fill({DEFAULT_VIBRATION_VALUE, DEFAULT_VIBRATION_VALUE});
152} 152}
153 153
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 873a0a1e2..c3b07bd41 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -8,10 +8,10 @@
8#include <atomic> 8#include <atomic>
9#include "common/bit_field.h" 9#include "common/bit_field.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/settings.h"
11#include "core/frontend/input.h" 12#include "core/frontend/input.h"
12#include "core/hle/kernel/object.h" 13#include "core/hle/kernel/object.h"
13#include "core/hle/service/hid/controllers/controller_base.h" 14#include "core/hle/service/hid/controllers/controller_base.h"
14#include "core/settings.h"
15 15
16namespace Kernel { 16namespace Kernel {
17class KEvent; 17class KEvent;
@@ -587,6 +587,5 @@ private:
587 std::array<ControllerPad, 10> npad_pad_states{}; 587 std::array<ControllerPad, 10> npad_pad_states{};
588 std::array<TriggerState, 10> npad_trigger_states{}; 588 std::array<TriggerState, 10> npad_trigger_states{};
589 bool is_in_lr_assignment_mode{false}; 589 bool is_in_lr_assignment_mode{false};
590 Core::System& system;
591}; 590};
592} // namespace Service::HID 591} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index be60492a4..b5f8077be 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -6,11 +6,11 @@
6#include <cstring> 6#include <cstring>
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "common/settings.h"
9#include "core/core_timing.h" 10#include "core/core_timing.h"
10#include "core/frontend/emu_window.h" 11#include "core/frontend/emu_window.h"
11#include "core/frontend/input.h" 12#include "core/frontend/input.h"
12#include "core/hle/service/hid/controllers/touchscreen.h" 13#include "core/hle/service/hid/controllers/touchscreen.h"
13#include "core/settings.h"
14 14
15namespace Service::HID { 15namespace Service::HID {
16constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400; 16constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400;
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index a1a779cc0..2aa1942cb 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -5,6 +5,7 @@
5#include <array> 5#include <array>
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "common/settings.h"
8#include "core/core.h" 9#include "core/core.h"
9#include "core/core_timing.h" 10#include "core/core_timing.h"
10#include "core/core_timing_util.h" 11#include "core/core_timing_util.h"
@@ -18,12 +19,12 @@
18#include "core/hle/kernel/k_shared_memory.h" 19#include "core/hle/kernel/k_shared_memory.h"
19#include "core/hle/kernel/k_writable_event.h" 20#include "core/hle/kernel/k_writable_event.h"
20#include "core/hle/kernel/kernel.h" 21#include "core/hle/kernel/kernel.h"
22#include "core/hle/kernel/transfer_memory.h"
21#include "core/hle/service/hid/errors.h" 23#include "core/hle/service/hid/errors.h"
22#include "core/hle/service/hid/hid.h" 24#include "core/hle/service/hid/hid.h"
23#include "core/hle/service/hid/irs.h" 25#include "core/hle/service/hid/irs.h"
24#include "core/hle/service/hid/xcd.h" 26#include "core/hle/service/hid/xcd.h"
25#include "core/hle/service/service.h" 27#include "core/hle/service/service.h"
26#include "core/settings.h"
27 28
28#include "core/hle/service/hid/controllers/controller_base.h" 29#include "core/hle/service/hid/controllers/controller_base.h"
29#include "core/hle/service/hid/controllers/debug_pad.h" 30#include "core/hle/service/hid/controllers/debug_pad.h"
@@ -1484,7 +1485,43 @@ void Hid::StopSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
1484} 1485}
1485 1486
1486void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) { 1487void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
1487 LOG_WARNING(Service_HID, "(STUBBED) called"); 1488 IPC::RequestParser rp{ctx};
1489 const auto applet_resource_user_id{rp.Pop<u64>()};
1490 const auto t_mem_1_size{rp.Pop<u64>()};
1491 const auto t_mem_2_size{rp.Pop<u64>()};
1492 const auto t_mem_1_handle{ctx.GetCopyHandle(0)};
1493 const auto t_mem_2_handle{ctx.GetCopyHandle(1)};
1494
1495 ASSERT_MSG(t_mem_1_size == 0x1000, "t_mem_1_size is not 0x1000 bytes");
1496 ASSERT_MSG(t_mem_2_size == 0x7F000, "t_mem_2_size is not 0x7F000 bytes");
1497
1498 auto t_mem_1 =
1499 system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(t_mem_1_handle);
1500
1501 if (t_mem_1 == nullptr) {
1502 LOG_ERROR(Service_HID, "t_mem_1 is a nullptr for handle=0x{:08X}", t_mem_1_handle);
1503 IPC::ResponseBuilder rb{ctx, 2};
1504 rb.Push(RESULT_UNKNOWN);
1505 return;
1506 }
1507
1508 auto t_mem_2 =
1509 system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(t_mem_2_handle);
1510
1511 if (t_mem_2 == nullptr) {
1512 LOG_ERROR(Service_HID, "t_mem_2 is a nullptr for handle=0x{:08X}", t_mem_2_handle);
1513 IPC::ResponseBuilder rb{ctx, 2};
1514 rb.Push(RESULT_UNKNOWN);
1515 return;
1516 }
1517
1518 ASSERT_MSG(t_mem_1->GetSize() == 0x1000, "t_mem_1 has incorrect size");
1519 ASSERT_MSG(t_mem_2->GetSize() == 0x7F000, "t_mem_2 has incorrect size");
1520
1521 LOG_WARNING(Service_HID,
1522 "(STUBBED) called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, "
1523 "applet_resource_user_id={}",
1524 t_mem_1_handle, t_mem_2_handle, applet_resource_user_id);
1488 1525
1489 IPC::ResponseBuilder rb{ctx, 2}; 1526 IPC::ResponseBuilder rb{ctx, 2};
1490 rb.Push(RESULT_SUCCESS); 1527 rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/lbl/lbl.cpp b/src/core/hle/service/lbl/lbl.cpp
index f4490f3d9..e11a0c45a 100644
--- a/src/core/hle/service/lbl/lbl.cpp
+++ b/src/core/hle/service/lbl/lbl.cpp
@@ -79,7 +79,6 @@ private:
79 } 79 }
80 80
81 void GetCurrentBrightnessSetting(Kernel::HLERequestContext& ctx) { 81 void GetCurrentBrightnessSetting(Kernel::HLERequestContext& ctx) {
82 IPC::RequestParser rp{ctx};
83 auto brightness = current_brightness; 82 auto brightness = current_brightness;
84 if (!std::isfinite(brightness)) { 83 if (!std::isfinite(brightness)) {
85 LOG_ERROR(Service_LBL, "Brightness is infinite!"); 84 LOG_ERROR(Service_LBL, "Brightness is infinite!");
@@ -272,7 +271,6 @@ private:
272 } 271 }
273 272
274 void GetCurrentBrightnessSettingForVrMode(Kernel::HLERequestContext& ctx) { 273 void GetCurrentBrightnessSettingForVrMode(Kernel::HLERequestContext& ctx) {
275 IPC::RequestParser rp{ctx};
276 auto brightness = current_vr_brightness; 274 auto brightness = current_vr_brightness;
277 if (!std::isfinite(brightness)) { 275 if (!std::isfinite(brightness)) {
278 LOG_ERROR(Service_LBL, "Brightness is infinite!"); 276 LOG_ERROR(Service_LBL, "Brightness is infinite!");
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp
index 7d7542fc2..9bcf8870d 100644
--- a/src/core/hle/service/lm/lm.cpp
+++ b/src/core/hle/service/lm/lm.cpp
@@ -46,7 +46,7 @@ struct hash<Service::LM::LogPacketHeaderEntry> {
46 boost::hash_combine(seed, k.severity); 46 boost::hash_combine(seed, k.severity);
47 boost::hash_combine(seed, k.verbosity); 47 boost::hash_combine(seed, k.verbosity);
48 return seed; 48 return seed;
49 }; 49 }
50}; 50};
51} // namespace std 51} // namespace std
52 52
@@ -95,7 +95,7 @@ private:
95 std::memcpy(&header, data.data(), sizeof(LogPacketHeader)); 95 std::memcpy(&header, data.data(), sizeof(LogPacketHeader));
96 offset += sizeof(LogPacketHeader); 96 offset += sizeof(LogPacketHeader);
97 97
98 LogPacketHeaderEntry entry{ 98 const LogPacketHeaderEntry entry{
99 .pid = header.pid, 99 .pid = header.pid,
100 .tid = header.tid, 100 .tid = header.tid,
101 .severity = header.severity, 101 .severity = header.severity,
@@ -105,16 +105,17 @@ private:
105 if (True(header.flags & LogPacketFlags::Head)) { 105 if (True(header.flags & LogPacketFlags::Head)) {
106 std::vector<u8> tmp(data.size() - sizeof(LogPacketHeader)); 106 std::vector<u8> tmp(data.size() - sizeof(LogPacketHeader));
107 std::memcpy(tmp.data(), data.data() + offset, tmp.size()); 107 std::memcpy(tmp.data(), data.data() + offset, tmp.size());
108 entries[entry] = std::move(tmp); 108 entries.insert_or_assign(entry, std::move(tmp));
109 } else { 109 } else {
110 const auto entry_iter = entries.find(entry);
111
110 // Append to existing entry 112 // Append to existing entry
111 if (!entries.contains(entry)) { 113 if (entry_iter == entries.cend()) {
112 LOG_ERROR(Service_LM, "Log entry does not exist!"); 114 LOG_ERROR(Service_LM, "Log entry does not exist!");
113 return; 115 return;
114 } 116 }
115 std::vector<u8> tmp(data.size() - sizeof(LogPacketHeader));
116 117
117 auto& existing_entry = entries[entry]; 118 auto& existing_entry = entry_iter->second;
118 const auto base = existing_entry.size(); 119 const auto base = existing_entry.size();
119 existing_entry.resize(base + (data.size() - sizeof(LogPacketHeader))); 120 existing_entry.resize(base + (data.size() - sizeof(LogPacketHeader)));
120 std::memcpy(existing_entry.data() + base, data.data() + offset, 121 std::memcpy(existing_entry.data() + base, data.data() + offset,
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp
index 6ab35de47..44a5d5789 100644
--- a/src/core/hle/service/nfc/nfc.cpp
+++ b/src/core/hle/service/nfc/nfc.cpp
@@ -5,12 +5,12 @@
5#include <memory> 5#include <memory>
6 6
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "common/settings.h"
8#include "core/hle/ipc_helpers.h" 9#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/hle_ipc.h" 10#include "core/hle/kernel/hle_ipc.h"
10#include "core/hle/service/nfc/nfc.h" 11#include "core/hle/service/nfc/nfc.h"
11#include "core/hle/service/service.h" 12#include "core/hle/service/service.h"
12#include "core/hle/service/sm/sm.h" 13#include "core/hle/service/sm/sm.h"
13#include "core/settings.h"
14 14
15namespace Service::NFC { 15namespace Service::NFC {
16 16
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index afb3342d6..9f110df8e 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -2,6 +2,7 @@
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 "common/settings.h"
5#include "core/core.h" 6#include "core/core.h"
6#include "core/hle/ipc_helpers.h" 7#include "core/hle/ipc_helpers.h"
7#include "core/hle/kernel/k_event.h" 8#include "core/hle/kernel/k_event.h"
@@ -10,7 +11,6 @@
10#include "core/hle/service/nifm/nifm.h" 11#include "core/hle/service/nifm/nifm.h"
11#include "core/hle/service/service.h" 12#include "core/hle/service/service.h"
12#include "core/network/network.h" 13#include "core/network/network.h"
13#include "core/settings.h"
14 14
15namespace Service::NIFM { 15namespace Service::NIFM {
16 16
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index 5fe7a9189..e373609a1 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -3,6 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "common/settings.h"
6#include "core/core.h" 7#include "core/core.h"
7#include "core/file_sys/control_metadata.h" 8#include "core/file_sys/control_metadata.h"
8#include "core/file_sys/patch_manager.h" 9#include "core/file_sys/patch_manager.h"
@@ -14,7 +15,6 @@
14#include "core/hle/service/ns/ns.h" 15#include "core/hle/service/ns/ns.h"
15#include "core/hle/service/ns/pl_u.h" 16#include "core/hle/service/ns/pl_u.h"
16#include "core/hle/service/set/set.h" 17#include "core/hle/service/set/set.h"
17#include "core/settings.h"
18 18
19namespace Service::NS { 19namespace Service::NS {
20 20
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index c8031970b..e2f671d8e 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -31,14 +31,8 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
31 return SetSubmitTimeout(input, output); 31 return SetSubmitTimeout(input, output);
32 case 0x9: 32 case 0x9:
33 return MapBuffer(input, output); 33 return MapBuffer(input, output);
34 case 0xa: { 34 case 0xa:
35 if (command.length == 0x1c) {
36 LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
37 Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}};
38 system.GPU().PushCommandBuffer(cmdlist);
39 }
40 return UnmapBuffer(input, output); 35 return UnmapBuffer(input, output);
41 }
42 default: 36 default:
43 break; 37 break;
44 } 38 }
@@ -70,6 +64,10 @@ NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>&
70} 64}
71 65
72void nvhost_nvdec::OnOpen(DeviceFD fd) {} 66void nvhost_nvdec::OnOpen(DeviceFD fd) {}
73void nvhost_nvdec::OnClose(DeviceFD fd) {} 67
68void nvhost_nvdec::OnClose(DeviceFD fd) {
69 LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
70 system.GPU().ClearCdmaInstance();
71}
74 72
75} // namespace Service::Nvidia::Devices 73} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index 0421fb956..301efe8a1 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -29,13 +29,8 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& i
29 return GetWaitbase(input, output); 29 return GetWaitbase(input, output);
30 case 0x9: 30 case 0x9:
31 return MapBuffer(input, output); 31 return MapBuffer(input, output);
32 case 0xa: { 32 case 0xa:
33 if (command.length == 0x1c) {
34 Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}};
35 system.GPU().PushCommandBuffer(cmdlist);
36 }
37 return UnmapBuffer(input, output); 33 return UnmapBuffer(input, output);
38 }
39 default: 34 default:
40 break; 35 break;
41 } 36 }
@@ -69,6 +64,9 @@ NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& i
69} 64}
70 65
71void nvhost_vic::OnOpen(DeviceFD fd) {} 66void nvhost_vic::OnOpen(DeviceFD fd) {}
72void nvhost_vic::OnClose(DeviceFD fd) {} 67
68void nvhost_vic::OnClose(DeviceFD fd) {
69 system.GPU().ClearCdmaInstance();
70}
73 71
74} // namespace Service::Nvidia::Devices 72} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index ac2906e5b..539b02bc4 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -9,6 +9,7 @@
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "common/microprofile.h" 10#include "common/microprofile.h"
11#include "common/scope_exit.h" 11#include "common/scope_exit.h"
12#include "common/settings.h"
12#include "common/thread.h" 13#include "common/thread.h"
13#include "core/core.h" 14#include "core/core.h"
14#include "core/core_timing.h" 15#include "core/core_timing.h"
@@ -23,7 +24,6 @@
23#include "core/hle/service/vi/display/vi_display.h" 24#include "core/hle/service/vi/display/vi_display.h"
24#include "core/hle/service/vi/layer/vi_layer.h" 25#include "core/hle/service/vi/layer/vi_layer.h"
25#include "core/perf_stats.h" 26#include "core/perf_stats.h"
26#include "core/settings.h"
27#include "video_core/renderer_base.h" 27#include "video_core/renderer_base.h"
28 28
29namespace Service::NVFlinger { 29namespace Service::NVFlinger {
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index aec399076..41a502d8d 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -6,6 +6,7 @@
6#include <fmt/format.h> 6#include <fmt/format.h>
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "common/settings.h"
9#include "common/string_util.h" 10#include "common/string_util.h"
10#include "core/core.h" 11#include "core/core.h"
11#include "core/hle/ipc.h" 12#include "core/hle/ipc.h"
@@ -70,7 +71,6 @@
70#include "core/hle/service/vi/vi.h" 71#include "core/hle/service/vi/vi.h"
71#include "core/hle/service/wlan/wlan.h" 72#include "core/hle/service/wlan/wlan.h"
72#include "core/reporter.h" 73#include "core/reporter.h"
73#include "core/settings.h"
74 74
75namespace Service { 75namespace Service {
76 76
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp
index d953b4303..fbdc4793d 100644
--- a/src/core/hle/service/set/set.cpp
+++ b/src/core/hle/service/set/set.cpp
@@ -6,9 +6,9 @@
6#include <array> 6#include <array>
7#include <chrono> 7#include <chrono>
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "common/settings.h"
9#include "core/hle/ipc_helpers.h" 10#include "core/hle/ipc_helpers.h"
10#include "core/hle/service/set/set.h" 11#include "core/hle/service/set/set.h"
11#include "core/settings.h"
12 12
13namespace Service::Set { 13namespace Service::Set {
14namespace { 14namespace {
@@ -104,9 +104,10 @@ void GetKeyCodeMapImpl(Kernel::HLERequestContext& ctx) {
104 layout = key_code->second; 104 layout = key_code->second;
105 } 105 }
106 106
107 ctx.WriteBuffer(layout);
108
107 IPC::ResponseBuilder rb{ctx, 2}; 109 IPC::ResponseBuilder rb{ctx, 2};
108 rb.Push(RESULT_SUCCESS); 110 rb.Push(RESULT_SUCCESS);
109 ctx.WriteBuffer(layout);
110} 111}
111} // Anonymous namespace 112} // Anonymous namespace
112 113
diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp
index 6903dd534..b1552c3f0 100644
--- a/src/core/hle/service/spl/module.cpp
+++ b/src/core/hle/service/spl/module.cpp
@@ -9,11 +9,11 @@
9#include <functional> 9#include <functional>
10#include <vector> 10#include <vector>
11#include "common/logging/log.h" 11#include "common/logging/log.h"
12#include "common/settings.h"
12#include "core/hle/ipc_helpers.h" 13#include "core/hle/ipc_helpers.h"
13#include "core/hle/service/spl/csrng.h" 14#include "core/hle/service/spl/csrng.h"
14#include "core/hle/service/spl/module.h" 15#include "core/hle/service/spl/module.h"
15#include "core/hle/service/spl/spl.h" 16#include "core/hle/service/spl/spl.h"
16#include "core/settings.h"
17 17
18namespace Service::SPL { 18namespace Service::SPL {
19 19
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index 63e0247de..32f372d71 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -294,16 +294,17 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
294 return; 294 return;
295 } 295 }
296 296
297 ctx.WriteBuffer(clock_snapshot);
298
297 IPC::ResponseBuilder rb{ctx, 2}; 299 IPC::ResponseBuilder rb{ctx, 2};
298 rb.Push(RESULT_SUCCESS); 300 rb.Push(RESULT_SUCCESS);
299 ctx.WriteBuffer(clock_snapshot);
300} 301}
301 302
302void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx) { 303void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx) {
303 IPC::RequestParser rp{ctx}; 304 IPC::RequestParser rp{ctx};
304 const auto type{rp.PopEnum<Clock::TimeType>()}; 305 const auto type{rp.PopEnum<Clock::TimeType>()};
305 306
306 rp.AlignWithPadding(); 307 rp.Skip(1, false);
307 308
308 const Clock::SystemClockContext user_context{rp.PopRaw<Clock::SystemClockContext>()}; 309 const Clock::SystemClockContext user_context{rp.PopRaw<Clock::SystemClockContext>()};
309 const Clock::SystemClockContext network_context{rp.PopRaw<Clock::SystemClockContext>()}; 310 const Clock::SystemClockContext network_context{rp.PopRaw<Clock::SystemClockContext>()};
@@ -319,9 +320,10 @@ void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLEReques
319 return; 320 return;
320 } 321 }
321 322
323 ctx.WriteBuffer(clock_snapshot);
324
322 IPC::ResponseBuilder rb{ctx, 2}; 325 IPC::ResponseBuilder rb{ctx, 2};
323 rb.Push(RESULT_SUCCESS); 326 rb.Push(RESULT_SUCCESS);
324 ctx.WriteBuffer(clock_snapshot);
325} 327}
326 328
327void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser( 329void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser(
diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp
index 51becd074..f89c5aaad 100644
--- a/src/core/hle/service/time/time_manager.cpp
+++ b/src/core/hle/service/time/time_manager.cpp
@@ -5,12 +5,12 @@
5#include <chrono> 5#include <chrono>
6#include <ctime> 6#include <ctime>
7 7
8#include "common/settings.h"
8#include "common/time_zone.h" 9#include "common/time_zone.h"
9#include "core/hle/service/time/ephemeral_network_system_clock_context_writer.h" 10#include "core/hle/service/time/ephemeral_network_system_clock_context_writer.h"
10#include "core/hle/service/time/local_system_clock_context_writer.h" 11#include "core/hle/service/time/local_system_clock_context_writer.h"
11#include "core/hle/service/time/network_system_clock_context_writer.h" 12#include "core/hle/service/time/network_system_clock_context_writer.h"
12#include "core/hle/service/time/time_manager.h" 13#include "core/hle/service/time/time_manager.h"
13#include "core/settings.h"
14 14
15namespace Service::Time { 15namespace Service::Time {
16 16
diff --git a/src/core/hle/service/time/time_zone_content_manager.cpp b/src/core/hle/service/time/time_zone_content_manager.cpp
index 4177d0a41..3c8e71a3c 100644
--- a/src/core/hle/service/time/time_zone_content_manager.cpp
+++ b/src/core/hle/service/time/time_zone_content_manager.cpp
@@ -5,6 +5,7 @@
5#include <sstream> 5#include <sstream>
6 6
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "common/settings.h"
8#include "common/time_zone.h" 9#include "common/time_zone.h"
9#include "core/core.h" 10#include "core/core.h"
10#include "core/file_sys/content_archive.h" 11#include "core/file_sys/content_archive.h"
@@ -15,7 +16,6 @@
15#include "core/hle/service/filesystem/filesystem.h" 16#include "core/hle/service/filesystem/filesystem.h"
16#include "core/hle/service/time/time_manager.h" 17#include "core/hle/service/time/time_manager.h"
17#include "core/hle/service/time/time_zone_content_manager.h" 18#include "core/hle/service/time/time_zone_content_manager.h"
18#include "core/settings.h"
19 19
20namespace Service::Time::TimeZone { 20namespace Service::Time::TimeZone {
21 21
diff --git a/src/core/hle/service/time/time_zone_service.cpp b/src/core/hle/service/time/time_zone_service.cpp
index 3117627cf..19d7a1a0c 100644
--- a/src/core/hle/service/time/time_zone_service.cpp
+++ b/src/core/hle/service/time/time_zone_service.cpp
@@ -140,11 +140,12 @@ void ITimeZoneService::ToPosixTime(Kernel::HLERequestContext& ctx) {
140 return; 140 return;
141 } 141 }
142 142
143 ctx.WriteBuffer(posix_time);
144
143 // TODO(bunnei): Handle multiple times 145 // TODO(bunnei): Handle multiple times
144 IPC::ResponseBuilder rb{ctx, 3}; 146 IPC::ResponseBuilder rb{ctx, 3};
145 rb.Push(RESULT_SUCCESS); 147 rb.Push(RESULT_SUCCESS);
146 rb.PushRaw<u32>(1); // Number of times we're returning 148 rb.PushRaw<u32>(1); // Number of times we're returning
147 ctx.WriteBuffer(posix_time);
148} 149}
149 150
150void ITimeZoneService::ToPosixTimeWithMyRule(Kernel::HLERequestContext& ctx) { 151void ITimeZoneService::ToPosixTimeWithMyRule(Kernel::HLERequestContext& ctx) {
@@ -163,10 +164,11 @@ void ITimeZoneService::ToPosixTimeWithMyRule(Kernel::HLERequestContext& ctx) {
163 return; 164 return;
164 } 165 }
165 166
167 ctx.WriteBuffer(posix_time);
168
166 IPC::ResponseBuilder rb{ctx, 3}; 169 IPC::ResponseBuilder rb{ctx, 3};
167 rb.Push(RESULT_SUCCESS); 170 rb.Push(RESULT_SUCCESS);
168 rb.PushRaw<u32>(1); // Number of times we're returning 171 rb.PushRaw<u32>(1); // Number of times we're returning
169 ctx.WriteBuffer(posix_time);
170} 172}
171 173
172} // namespace Service::Time 174} // namespace Service::Time
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index a1a7ac987..7ae07d072 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -15,6 +15,7 @@
15#include "common/common_funcs.h" 15#include "common/common_funcs.h"
16#include "common/logging/log.h" 16#include "common/logging/log.h"
17#include "common/math_util.h" 17#include "common/math_util.h"
18#include "common/settings.h"
18#include "common/swap.h" 19#include "common/swap.h"
19#include "core/core_timing.h" 20#include "core/core_timing.h"
20#include "core/hle/ipc_helpers.h" 21#include "core/hle/ipc_helpers.h"
@@ -30,7 +31,6 @@
30#include "core/hle/service/vi/vi_m.h" 31#include "core/hle/service/vi/vi_m.h"
31#include "core/hle/service/vi/vi_s.h" 32#include "core/hle/service/vi/vi_s.h"
32#include "core/hle/service/vi/vi_u.h" 33#include "core/hle/service/vi/vi_u.h"
33#include "core/settings.h"
34 34
35namespace Service::VI { 35namespace Service::VI {
36 36
@@ -1129,9 +1129,11 @@ private:
1129 } 1129 }
1130 1130
1131 NativeWindow native_window{*buffer_queue_id}; 1131 NativeWindow native_window{*buffer_queue_id};
1132 const auto buffer_size = ctx.WriteBuffer(native_window.Serialize());
1133
1132 IPC::ResponseBuilder rb{ctx, 4}; 1134 IPC::ResponseBuilder rb{ctx, 4};
1133 rb.Push(RESULT_SUCCESS); 1135 rb.Push(RESULT_SUCCESS);
1134 rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize())); 1136 rb.Push<u64>(buffer_size);
1135 } 1137 }
1136 1138
1137 void CloseLayer(Kernel::HLERequestContext& ctx) { 1139 void CloseLayer(Kernel::HLERequestContext& ctx) {
@@ -1173,10 +1175,12 @@ private:
1173 } 1175 }
1174 1176
1175 NativeWindow native_window{*buffer_queue_id}; 1177 NativeWindow native_window{*buffer_queue_id};
1178 const auto buffer_size = ctx.WriteBuffer(native_window.Serialize());
1179
1176 IPC::ResponseBuilder rb{ctx, 6}; 1180 IPC::ResponseBuilder rb{ctx, 6};
1177 rb.Push(RESULT_SUCCESS); 1181 rb.Push(RESULT_SUCCESS);
1178 rb.Push(*layer_id); 1182 rb.Push(*layer_id);
1179 rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize())); 1183 rb.Push<u64>(buffer_size);
1180 } 1184 }
1181 1185
1182 void DestroyStrayLayer(Kernel::HLERequestContext& ctx) { 1186 void DestroyStrayLayer(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp
index 3f4ba233d..55e6de794 100644
--- a/src/core/loader/kip.cpp
+++ b/src/core/loader/kip.cpp
@@ -68,7 +68,8 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::Process& process,
68 FileSys::ProgramMetadata metadata; 68 FileSys::ProgramMetadata metadata;
69 metadata.LoadManual(kip->Is64Bit(), address_space, kip->GetMainThreadPriority(), 69 metadata.LoadManual(kip->Is64Bit(), address_space, kip->GetMainThreadPriority(),
70 kip->GetMainThreadCpuCore(), kip->GetMainThreadStackSize(), 70 kip->GetMainThreadCpuCore(), kip->GetMainThreadStackSize(),
71 kip->GetTitleID(), 0xFFFFFFFFFFFFFFFF, kip->GetKernelCapabilities()); 71 kip->GetTitleID(), 0xFFFFFFFFFFFFFFFF, 0x1FE00000,
72 kip->GetKernelCapabilities());
72 73
73 const VAddr base_address = process.PageTable().GetCodeRegionStart(); 74 const VAddr base_address = process.PageTable().GetCodeRegionStart();
74 Kernel::CodeSet codeset; 75 Kernel::CodeSet codeset;
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 14618cb40..0115ed0c4 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -9,6 +9,7 @@
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "common/file_util.h" 10#include "common/file_util.h"
11#include "common/logging/log.h" 11#include "common/logging/log.h"
12#include "common/settings.h"
12#include "common/swap.h" 13#include "common/swap.h"
13#include "core/core.h" 14#include "core/core.h"
14#include "core/file_sys/control_metadata.h" 15#include "core/file_sys/control_metadata.h"
@@ -22,7 +23,6 @@
22#include "core/loader/nro.h" 23#include "core/loader/nro.h"
23#include "core/loader/nso.h" 24#include "core/loader/nso.h"
24#include "core/memory.h" 25#include "core/memory.h"
25#include "core/settings.h"
26 26
27namespace Loader { 27namespace Loader {
28 28
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index cbd048695..0c83dd666 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -11,6 +11,7 @@
11#include "common/hex_util.h" 11#include "common/hex_util.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "common/lz4_compression.h" 13#include "common/lz4_compression.h"
14#include "common/settings.h"
14#include "common/swap.h" 15#include "common/swap.h"
15#include "core/core.h" 16#include "core/core.h"
16#include "core/file_sys/patch_manager.h" 17#include "core/file_sys/patch_manager.h"
@@ -20,7 +21,6 @@
20#include "core/hle/kernel/process.h" 21#include "core/hle/kernel/process.h"
21#include "core/loader/nso.h" 22#include "core/loader/nso.h"
22#include "core/memory.h" 23#include "core/memory.h"
23#include "core/settings.h"
24 24
25namespace Loader { 25namespace Loader {
26namespace { 26namespace {
diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp
index b93396a80..c92337079 100644
--- a/src/core/perf_stats.cpp
+++ b/src/core/perf_stats.cpp
@@ -13,8 +13,8 @@
13#include <fmt/format.h> 13#include <fmt/format.h>
14#include "common/file_util.h" 14#include "common/file_util.h"
15#include "common/math_util.h" 15#include "common/math_util.h"
16#include "common/settings.h"
16#include "core/perf_stats.h" 17#include "core/perf_stats.h"
17#include "core/settings.h"
18 18
19using namespace std::chrono_literals; 19using namespace std::chrono_literals;
20using DoubleSecs = std::chrono::duration<double, std::chrono::seconds::period>; 20using DoubleSecs = std::chrono::duration<double, std::chrono::seconds::period>;
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp
index 74fb32814..311d4dda8 100644
--- a/src/core/reporter.cpp
+++ b/src/core/reporter.cpp
@@ -14,6 +14,7 @@
14#include "common/file_util.h" 14#include "common/file_util.h"
15#include "common/hex_util.h" 15#include "common/hex_util.h"
16#include "common/scm_rev.h" 16#include "common/scm_rev.h"
17#include "common/settings.h"
17#include "core/arm/arm_interface.h" 18#include "core/arm/arm_interface.h"
18#include "core/core.h" 19#include "core/core.h"
19#include "core/hle/kernel/hle_ipc.h" 20#include "core/hle/kernel/hle_ipc.h"
@@ -22,7 +23,6 @@
22#include "core/hle/result.h" 23#include "core/hle/result.h"
23#include "core/memory.h" 24#include "core/memory.h"
24#include "core/reporter.h" 25#include "core/reporter.h"
25#include "core/settings.h"
26 26
27namespace { 27namespace {
28 28
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index d11b15f38..6dcff5400 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -12,10 +12,10 @@
12#include "common/file_util.h" 12#include "common/file_util.h"
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14 14
15#include "common/settings.h"
15#include "core/file_sys/control_metadata.h" 16#include "core/file_sys/control_metadata.h"
16#include "core/file_sys/patch_manager.h" 17#include "core/file_sys/patch_manager.h"
17#include "core/loader/loader.h" 18#include "core/loader/loader.h"
18#include "core/settings.h"
19#include "core/telemetry_session.h" 19#include "core/telemetry_session.h"
20 20
21#ifdef ENABLE_WEB_SERVICE 21#ifdef ENABLE_WEB_SERVICE
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index 38ab31898..de53e1fda 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -9,8 +9,6 @@ add_library(input_common STATIC
9 motion_from_button.h 9 motion_from_button.h
10 motion_input.cpp 10 motion_input.cpp
11 motion_input.h 11 motion_input.h
12 settings.cpp
13 settings.h
14 touch_from_button.cpp 12 touch_from_button.cpp
15 touch_from_button.h 13 touch_from_button.h
16 gcadapter/gc_adapter.cpp 14 gcadapter/gc_adapter.cpp
@@ -64,7 +62,7 @@ else()
64 ) 62 )
65endif() 63endif()
66 64
67if(SDL2_FOUND) 65if (ENABLE_SDL2)
68 target_sources(input_common PRIVATE 66 target_sources(input_common PRIVATE
69 sdl/sdl_impl.cpp 67 sdl/sdl_impl.cpp
70 sdl/sdl_impl.h 68 sdl/sdl_impl.h
diff --git a/src/input_common/analog_from_button.cpp b/src/input_common/analog_from_button.cpp
index 770893687..f8ec179d0 100755
--- a/src/input_common/analog_from_button.cpp
+++ b/src/input_common/analog_from_button.cpp
@@ -7,7 +7,7 @@
7#include <cmath> 7#include <cmath>
8#include <thread> 8#include <thread>
9#include "common/math_util.h" 9#include "common/math_util.h"
10#include "core/settings.h" 10#include "common/settings.h"
11#include "input_common/analog_from_button.h" 11#include "input_common/analog_from_button.h"
12 12
13namespace InputCommon { 13namespace InputCommon {
diff --git a/src/input_common/gcadapter/gc_adapter.cpp b/src/input_common/gcadapter/gc_adapter.cpp
index d80195c82..ec3167bea 100644
--- a/src/input_common/gcadapter/gc_adapter.cpp
+++ b/src/input_common/gcadapter/gc_adapter.cpp
@@ -16,8 +16,8 @@
16 16
17#include "common/logging/log.h" 17#include "common/logging/log.h"
18#include "common/param_package.h" 18#include "common/param_package.h"
19#include "common/settings_input.h"
19#include "input_common/gcadapter/gc_adapter.h" 20#include "input_common/gcadapter/gc_adapter.h"
20#include "input_common/settings.h"
21 21
22namespace GCAdapter { 22namespace GCAdapter {
23 23
diff --git a/src/input_common/mouse/mouse_input.cpp b/src/input_common/mouse/mouse_input.cpp
index 329e416c7..fff1c6b45 100644
--- a/src/input_common/mouse/mouse_input.cpp
+++ b/src/input_common/mouse/mouse_input.cpp
@@ -2,7 +2,7 @@
2// Licensed under GPLv2+ 2// Licensed under GPLv2+
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/settings.h" 5#include "common/settings.h"
6#include "input_common/mouse/mouse_input.h" 6#include "input_common/mouse/mouse_input.h"
7 7
8namespace MouseInput { 8namespace MouseInput {
diff --git a/src/input_common/mouse/mouse_poller.cpp b/src/input_common/mouse/mouse_poller.cpp
index 0e1db54fb..d96104a4e 100644
--- a/src/input_common/mouse/mouse_poller.cpp
+++ b/src/input_common/mouse/mouse_poller.cpp
@@ -5,8 +5,8 @@
5#include <mutex> 5#include <mutex>
6#include <utility> 6#include <utility>
7 7
8#include "common/settings.h"
8#include "common/threadsafe_queue.h" 9#include "common/threadsafe_queue.h"
9#include "core/settings.h"
10#include "input_common/mouse/mouse_input.h" 10#include "input_common/mouse/mouse_input.h"
11#include "input_common/mouse/mouse_poller.h" 11#include "input_common/mouse/mouse_poller.h"
12 12
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp
index f67de37e3..f682a6db4 100644
--- a/src/input_common/sdl/sdl_impl.cpp
+++ b/src/input_common/sdl/sdl_impl.cpp
@@ -17,14 +17,24 @@
17#include <unordered_map> 17#include <unordered_map>
18#include <utility> 18#include <utility>
19#include <vector> 19#include <vector>
20
21// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307
22#ifdef __clang__
23#pragma clang diagnostic push
24#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
25#endif
20#include <SDL.h> 26#include <SDL.h>
27#ifdef __clang__
28#pragma clang diagnostic pop
29#endif
30
21#include "common/logging/log.h" 31#include "common/logging/log.h"
22#include "common/param_package.h" 32#include "common/param_package.h"
33#include "common/settings_input.h"
23#include "common/threadsafe_queue.h" 34#include "common/threadsafe_queue.h"
24#include "core/frontend/input.h" 35#include "core/frontend/input.h"
25#include "input_common/motion_input.h" 36#include "input_common/motion_input.h"
26#include "input_common/sdl/sdl_impl.h" 37#include "input_common/sdl/sdl_impl.h"
27#include "input_common/settings.h"
28 38
29namespace InputCommon::SDL { 39namespace InputCommon::SDL {
30 40
@@ -761,7 +771,7 @@ std::vector<Common::ParamPackage> SDLState::GetInputDevices() {
761 for (const auto& joystick : value) { 771 for (const auto& joystick : value) {
762 if (auto* const controller = joystick->GetSDLGameController()) { 772 if (auto* const controller = joystick->GetSDLGameController()) {
763 std::string name = 773 std::string name =
764 fmt::format("{} {}", SDL_GameControllerName(controller), joystick->GetPort()); 774 fmt::format("{} {}", GetControllerName(controller), joystick->GetPort());
765 devices.emplace_back(Common::ParamPackage{ 775 devices.emplace_back(Common::ParamPackage{
766 {"class", "sdl"}, 776 {"class", "sdl"},
767 {"display", std::move(name)}, 777 {"display", std::move(name)},
@@ -782,6 +792,17 @@ std::vector<Common::ParamPackage> SDLState::GetInputDevices() {
782 return devices; 792 return devices;
783} 793}
784 794
795std::string SDLState::GetControllerName(SDL_GameController* controller) const {
796 switch (SDL_GameControllerGetType(controller)) {
797 case SDL_CONTROLLER_TYPE_XBOX360:
798 return "XBox 360 Controller";
799 case SDL_CONTROLLER_TYPE_XBOXONE:
800 return "XBox One Controller";
801 default:
802 return SDL_GameControllerName(controller);
803 }
804}
805
785namespace { 806namespace {
786Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis, 807Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis,
787 float value = 0.1f) { 808 float value = 0.1f) {
@@ -930,16 +951,19 @@ ButtonMapping SDLState::GetButtonMappingForDevice(const Common::ParamPackage& pa
930 return {}; 951 return {};
931 } 952 }
932 953
954 const bool invert =
955 SDL_GameControllerGetType(controller) != SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
956
933 // This list is missing ZL/ZR since those are not considered buttons in SDL GameController. 957 // This list is missing ZL/ZR since those are not considered buttons in SDL GameController.
934 // We will add those afterwards 958 // We will add those afterwards
935 // This list also excludes Screenshot since theres not really a mapping for that 959 // This list also excludes Screenshot since theres not really a mapping for that
936 using ButtonBindings = 960 using ButtonBindings =
937 std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerButton>, 17>; 961 std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerButton>, 17>;
938 static constexpr ButtonBindings switch_to_sdl_button{{ 962 const ButtonBindings switch_to_sdl_button{{
939 {Settings::NativeButton::A, SDL_CONTROLLER_BUTTON_B}, 963 {Settings::NativeButton::A, invert ? SDL_CONTROLLER_BUTTON_B : SDL_CONTROLLER_BUTTON_A},
940 {Settings::NativeButton::B, SDL_CONTROLLER_BUTTON_A}, 964 {Settings::NativeButton::B, invert ? SDL_CONTROLLER_BUTTON_A : SDL_CONTROLLER_BUTTON_B},
941 {Settings::NativeButton::X, SDL_CONTROLLER_BUTTON_Y}, 965 {Settings::NativeButton::X, invert ? SDL_CONTROLLER_BUTTON_Y : SDL_CONTROLLER_BUTTON_X},
942 {Settings::NativeButton::Y, SDL_CONTROLLER_BUTTON_X}, 966 {Settings::NativeButton::Y, invert ? SDL_CONTROLLER_BUTTON_X : SDL_CONTROLLER_BUTTON_Y},
943 {Settings::NativeButton::LStick, SDL_CONTROLLER_BUTTON_LEFTSTICK}, 967 {Settings::NativeButton::LStick, SDL_CONTROLLER_BUTTON_LEFTSTICK},
944 {Settings::NativeButton::RStick, SDL_CONTROLLER_BUTTON_RIGHTSTICK}, 968 {Settings::NativeButton::RStick, SDL_CONTROLLER_BUTTON_RIGHTSTICK},
945 {Settings::NativeButton::L, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, 969 {Settings::NativeButton::L, SDL_CONTROLLER_BUTTON_LEFTSHOULDER},
diff --git a/src/input_common/sdl/sdl_impl.h b/src/input_common/sdl/sdl_impl.h
index 08044b00d..8b7363f56 100644
--- a/src/input_common/sdl/sdl_impl.h
+++ b/src/input_common/sdl/sdl_impl.h
@@ -14,6 +14,7 @@
14#include "input_common/sdl/sdl.h" 14#include "input_common/sdl/sdl.h"
15 15
16union SDL_Event; 16union SDL_Event;
17using SDL_GameController = struct _SDL_GameController;
17using SDL_Joystick = struct _SDL_Joystick; 18using SDL_Joystick = struct _SDL_Joystick;
18using SDL_JoystickID = s32; 19using SDL_JoystickID = s32;
19 20
@@ -64,6 +65,9 @@ private:
64 /// Needs to be called before SDL_QuitSubSystem. 65 /// Needs to be called before SDL_QuitSubSystem.
65 void CloseJoysticks(); 66 void CloseJoysticks();
66 67
68 /// Returns a custom name for specific controllers because the default name is not correct
69 std::string GetControllerName(SDL_GameController* controller) const;
70
67 // Set to true if SDL supports game controller subsystem 71 // Set to true if SDL supports game controller subsystem
68 bool has_gamecontroller = false; 72 bool has_gamecontroller = false;
69 73
diff --git a/src/input_common/touch_from_button.cpp b/src/input_common/touch_from_button.cpp
index ffbe4f2ed..e94ba197b 100644
--- a/src/input_common/touch_from_button.cpp
+++ b/src/input_common/touch_from_button.cpp
@@ -2,8 +2,8 @@
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 "common/settings.h"
5#include "core/frontend/framebuffer_layout.h" 6#include "core/frontend/framebuffer_layout.h"
6#include "core/settings.h"
7#include "input_common/touch_from_button.h" 7#include "input_common/touch_from_button.h"
8 8
9namespace InputCommon { 9namespace InputCommon {
diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp
index e72df924b..8a38a380d 100644
--- a/src/input_common/udp/client.cpp
+++ b/src/input_common/udp/client.cpp
@@ -9,7 +9,7 @@
9#include <thread> 9#include <thread>
10#include <boost/asio.hpp> 10#include <boost/asio.hpp>
11#include "common/logging/log.h" 11#include "common/logging/log.h"
12#include "core/settings.h" 12#include "common/settings.h"
13#include "input_common/udp/client.h" 13#include "input_common/udp/client.h"
14#include "input_common/udp/protocol.h" 14#include "input_common/udp/protocol.h"
15 15
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 4de1e37e5..32dcbd693 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -20,8 +20,8 @@
20#include "common/div_ceil.h" 20#include "common/div_ceil.h"
21#include "common/microprofile.h" 21#include "common/microprofile.h"
22#include "common/scope_exit.h" 22#include "common/scope_exit.h"
23#include "common/settings.h"
23#include "core/memory.h" 24#include "core/memory.h"
24#include "core/settings.h"
25#include "video_core/buffer_cache/buffer_base.h" 25#include "video_core/buffer_cache/buffer_base.h"
26#include "video_core/delayed_destruction_ring.h" 26#include "video_core/delayed_destruction_ring.h"
27#include "video_core/dirty_flags.h" 27#include "video_core/dirty_flags.h"
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index a2f19559f..2ee980bab 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -4,8 +4,8 @@
4 4
5#include "common/assert.h" 5#include "common/assert.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "common/settings.h"
7#include "core/core.h" 8#include "core/core.h"
8#include "core/settings.h"
9#include "video_core/engines/maxwell_3d.h" 9#include "video_core/engines/maxwell_3d.h"
10#include "video_core/engines/maxwell_dma.h" 10#include "video_core/engines/maxwell_dma.h"
11#include "video_core/memory_manager.h" 11#include "video_core/memory_manager.h"
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 009c6f574..a38024242 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -6,13 +6,13 @@
6 6
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/microprofile.h" 8#include "common/microprofile.h"
9#include "common/settings.h"
9#include "core/core.h" 10#include "core/core.h"
10#include "core/core_timing.h" 11#include "core/core_timing.h"
11#include "core/core_timing_util.h" 12#include "core/core_timing_util.h"
12#include "core/frontend/emu_window.h" 13#include "core/frontend/emu_window.h"
13#include "core/hardware_interrupt_manager.h" 14#include "core/hardware_interrupt_manager.h"
14#include "core/memory.h" 15#include "core/memory.h"
15#include "core/settings.h"
16#include "video_core/engines/fermi_2d.h" 16#include "video_core/engines/fermi_2d.h"
17#include "video_core/engines/kepler_compute.h" 17#include "video_core/engines/kepler_compute.h"
18#include "video_core/engines/kepler_memory.h" 18#include "video_core/engines/kepler_memory.h"
@@ -480,11 +480,7 @@ void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) {
480 if (!use_nvdec) { 480 if (!use_nvdec) {
481 return; 481 return;
482 } 482 }
483 // This condition fires when a video stream ends, clear all intermediary data 483
484 if (entries[0].raw == 0xDEADB33F) {
485 cdma_pusher.reset();
486 return;
487 }
488 if (!cdma_pusher) { 484 if (!cdma_pusher) {
489 cdma_pusher = std::make_unique<Tegra::CDmaPusher>(*this); 485 cdma_pusher = std::make_unique<Tegra::CDmaPusher>(*this);
490 } 486 }
@@ -496,6 +492,10 @@ void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) {
496 cdma_pusher->ProcessEntries(std::move(entries)); 492 cdma_pusher->ProcessEntries(std::move(entries));
497} 493}
498 494
495void GPU::ClearCdmaInstance() {
496 cdma_pusher.reset();
497}
498
499void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { 499void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
500 gpu_thread.SwapBuffers(framebuffer); 500 gpu_thread.SwapBuffers(framebuffer);
501} 501}
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index ecab35d3b..8669e9940 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -324,6 +324,9 @@ public:
324 /// Push GPU command buffer entries to be processed 324 /// Push GPU command buffer entries to be processed
325 void PushCommandBuffer(Tegra::ChCommandHeaderList& entries); 325 void PushCommandBuffer(Tegra::ChCommandHeaderList& entries);
326 326
327 /// Frees the CDMAPusher instance to free up resources
328 void ClearCdmaInstance();
329
327 /// Swap buffers (render frame) 330 /// Swap buffers (render frame)
328 void SwapBuffers(const Tegra::FramebufferConfig* framebuffer); 331 void SwapBuffers(const Tegra::FramebufferConfig* framebuffer);
329 332
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 7addfbc7b..cd1fbb9bf 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -5,10 +5,10 @@
5#include "common/assert.h" 5#include "common/assert.h"
6#include "common/microprofile.h" 6#include "common/microprofile.h"
7#include "common/scope_exit.h" 7#include "common/scope_exit.h"
8#include "common/settings.h"
8#include "common/thread.h" 9#include "common/thread.h"
9#include "core/core.h" 10#include "core/core.h"
10#include "core/frontend/emu_window.h" 11#include "core/frontend/emu_window.h"
11#include "core/settings.h"
12#include "video_core/dma_pusher.h" 12#include "video_core/dma_pusher.h"
13#include "video_core/gpu.h" 13#include "video_core/gpu.h"
14#include "video_core/gpu_thread.h" 14#include "video_core/gpu_thread.h"
diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp
index cd21a2112..d7fabe605 100644
--- a/src/video_core/macro/macro.cpp
+++ b/src/video_core/macro/macro.cpp
@@ -6,7 +6,7 @@
6#include <boost/container_hash/hash.hpp> 6#include <boost/container_hash/hash.hpp>
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "core/settings.h" 9#include "common/settings.h"
10#include "video_core/engines/maxwell_3d.h" 10#include "video_core/engines/maxwell_3d.h"
11#include "video_core/macro/macro.h" 11#include "video_core/macro/macro.h"
12#include "video_core/macro/macro_hle.h" 12#include "video_core/macro/macro_hle.h"
diff --git a/src/video_core/query_cache.h b/src/video_core/query_cache.h
index 639d7ce7e..aac851253 100644
--- a/src/video_core/query_cache.h
+++ b/src/video_core/query_cache.h
@@ -16,8 +16,8 @@
16#include <vector> 16#include <vector>
17 17
18#include "common/assert.h" 18#include "common/assert.h"
19#include "common/settings.h"
19#include "core/core.h" 20#include "core/core.h"
20#include "core/settings.h"
21#include "video_core/engines/maxwell_3d.h" 21#include "video_core/engines/maxwell_3d.h"
22#include "video_core/gpu.h" 22#include "video_core/gpu.h"
23#include "video_core/memory_manager.h" 23#include "video_core/memory_manager.h"
diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp
index a93a1732c..c9a360aaf 100644
--- a/src/video_core/renderer_base.cpp
+++ b/src/video_core/renderer_base.cpp
@@ -3,8 +3,8 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "common/settings.h"
6#include "core/frontend/emu_window.h" 7#include "core/frontend/emu_window.h"
7#include "core/settings.h"
8#include "video_core/renderer_base.h" 8#include "video_core/renderer_base.h"
9 9
10namespace VideoCore { 10namespace VideoCore {
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index 5776fccdc..b113f54db 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -16,7 +16,7 @@
16 16
17#include "common/logging/log.h" 17#include "common/logging/log.h"
18#include "common/scope_exit.h" 18#include "common/scope_exit.h"
19#include "core/settings.h" 19#include "common/settings.h"
20#include "video_core/renderer_opengl/gl_device.h" 20#include "video_core/renderer_opengl/gl_device.h"
21#include "video_core/renderer_opengl/gl_resource_manager.h" 21#include "video_core/renderer_opengl/gl_resource_manager.h"
22 22
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 4610fd160..0863904e9 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -17,10 +17,10 @@
17#include "common/math_util.h" 17#include "common/math_util.h"
18#include "common/microprofile.h" 18#include "common/microprofile.h"
19#include "common/scope_exit.h" 19#include "common/scope_exit.h"
20#include "common/settings.h"
20#include "core/core.h" 21#include "core/core.h"
21#include "core/hle/kernel/process.h" 22#include "core/hle/kernel/process.h"
22#include "core/memory.h" 23#include "core/memory.h"
23#include "core/settings.h"
24#include "video_core/engines/kepler_compute.h" 24#include "video_core/engines/kepler_compute.h"
25#include "video_core/engines/maxwell_3d.h" 25#include "video_core/engines/maxwell_3d.h"
26#include "video_core/engines/shader_type.h" 26#include "video_core/engines/shader_type.h"
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
index 955b2abc4..97fb11ac6 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
@@ -12,10 +12,10 @@
12#include "common/file_util.h" 12#include "common/file_util.h"
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "common/scm_rev.h" 14#include "common/scm_rev.h"
15#include "common/settings.h"
15#include "common/zstd_compression.h" 16#include "common/zstd_compression.h"
16#include "core/core.h" 17#include "core/core.h"
17#include "core/hle/kernel/process.h" 18#include "core/hle/kernel/process.h"
18#include "core/settings.h"
19#include "video_core/engines/shader_type.h" 19#include "video_core/engines/shader_type.h"
20#include "video_core/renderer_opengl/gl_shader_cache.h" 20#include "video_core/renderer_opengl/gl_shader_cache.h"
21#include "video_core/renderer_opengl/gl_shader_disk_cache.h" 21#include "video_core/renderer_opengl/gl_shader_disk_cache.h"
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 9d2acd4d9..cc2e499f9 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -13,13 +13,13 @@
13#include "common/assert.h" 13#include "common/assert.h"
14#include "common/logging/log.h" 14#include "common/logging/log.h"
15#include "common/microprofile.h" 15#include "common/microprofile.h"
16#include "common/settings.h"
16#include "common/telemetry.h" 17#include "common/telemetry.h"
17#include "core/core.h" 18#include "core/core.h"
18#include "core/core_timing.h" 19#include "core/core_timing.h"
19#include "core/frontend/emu_window.h" 20#include "core/frontend/emu_window.h"
20#include "core/memory.h" 21#include "core/memory.h"
21#include "core/perf_stats.h" 22#include "core/perf_stats.h"
22#include "core/settings.h"
23#include "core/telemetry_session.h" 23#include "core/telemetry_session.h"
24#include "video_core/host_shaders/opengl_present_frag.h" 24#include "video_core/host_shaders/opengl_present_frag.h"
25#include "video_core/host_shaders/opengl_present_vert.h" 25#include "video_core/host_shaders/opengl_present_vert.h"
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 14e5f36e2..2e0cf4232 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -13,11 +13,11 @@
13#include <fmt/format.h> 13#include <fmt/format.h>
14 14
15#include "common/logging/log.h" 15#include "common/logging/log.h"
16#include "common/settings.h"
16#include "common/telemetry.h" 17#include "common/telemetry.h"
17#include "core/core.h" 18#include "core/core.h"
18#include "core/core_timing.h" 19#include "core/core_timing.h"
19#include "core/frontend/emu_window.h" 20#include "core/frontend/emu_window.h"
20#include "core/settings.h"
21#include "core/telemetry_session.h" 21#include "core/telemetry_session.h"
22#include "video_core/gpu.h" 22#include "video_core/gpu.h"
23#include "video_core/renderer_vulkan/renderer_vulkan.h" 23#include "video_core/renderer_vulkan/renderer_vulkan.h"
diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp
index 56ec5e380..db78ce3d9 100644
--- a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp
+++ b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp
@@ -5,7 +5,7 @@
5#include <atomic> 5#include <atomic>
6#include <chrono> 6#include <chrono>
7 7
8#include "core/settings.h" 8#include "common/settings.h"
9#include "video_core/renderer_vulkan/vk_master_semaphore.h" 9#include "video_core/renderer_vulkan/vk_master_semaphore.h"
10#include "video_core/vulkan_common/vulkan_device.h" 10#include "video_core/vulkan_common/vulkan_device.h"
11#include "video_core/vulkan_common/vulkan_wrapper.h" 11#include "video_core/vulkan_common/vulkan_wrapper.h"
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index df5b7b172..e9a0e7811 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -13,8 +13,8 @@
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "common/microprofile.h" 14#include "common/microprofile.h"
15#include "common/scope_exit.h" 15#include "common/scope_exit.h"
16#include "common/settings.h"
16#include "core/core.h" 17#include "core/core.h"
17#include "core/settings.h"
18#include "video_core/engines/kepler_compute.h" 18#include "video_core/engines/kepler_compute.h"
19#include "video_core/engines/maxwell_3d.h" 19#include "video_core/engines/maxwell_3d.h"
20#include "video_core/renderer_vulkan/blit_image.h" 20#include "video_core/renderer_vulkan/blit_image.h"
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index bc2a53841..017348e05 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -417,7 +417,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
417 }; 417 };
418} 418}
419 419
420[[nodiscard]] constexpr SwizzleSource ConvertGreenRed(SwizzleSource value) { 420[[nodiscard]] SwizzleSource ConvertGreenRed(SwizzleSource value) {
421 switch (value) { 421 switch (value) {
422 case SwizzleSource::G: 422 case SwizzleSource::G:
423 return SwizzleSource::R; 423 return SwizzleSource::R;
@@ -426,6 +426,17 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
426 } 426 }
427} 427}
428 428
429[[nodiscard]] SwizzleSource SwapBlueRed(SwizzleSource value) {
430 switch (value) {
431 case SwizzleSource::R:
432 return SwizzleSource::B;
433 case SwizzleSource::B:
434 return SwizzleSource::R;
435 default:
436 return value;
437 }
438}
439
429void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage image, 440void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage image,
430 VkImageAspectFlags aspect_mask, bool is_initialized, 441 VkImageAspectFlags aspect_mask, bool is_initialized,
431 std::span<const VkBufferImageCopy> copies) { 442 std::span<const VkBufferImageCopy> copies) {
@@ -543,6 +554,15 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
543 }; 554 };
544} 555}
545 556
557[[nodiscard]] bool IsFormatFlipped(PixelFormat format) {
558 switch (format) {
559 case PixelFormat::A1B5G5R5_UNORM:
560 return true;
561 default:
562 return false;
563 }
564}
565
546struct RangedBarrierRange { 566struct RangedBarrierRange {
547 u32 min_mip = std::numeric_limits<u32>::max(); 567 u32 min_mip = std::numeric_limits<u32>::max();
548 u32 max_mip = std::numeric_limits<u32>::min(); 568 u32 max_mip = std::numeric_limits<u32>::min();
@@ -948,6 +968,9 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
948 }; 968 };
949 if (!info.IsRenderTarget()) { 969 if (!info.IsRenderTarget()) {
950 swizzle = info.Swizzle(); 970 swizzle = info.Swizzle();
971 if (IsFormatFlipped(format)) {
972 std::ranges::transform(swizzle, swizzle.begin(), SwapBlueRed);
973 }
951 if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0) { 974 if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0) {
952 std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed); 975 std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed);
953 } 976 }
diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp
index f89a40b4c..e8d632f9e 100644
--- a/src/video_core/texture_cache/image_view_base.cpp
+++ b/src/video_core/texture_cache/image_view_base.cpp
@@ -5,7 +5,7 @@
5#include <algorithm> 5#include <algorithm>
6 6
7#include "common/assert.h" 7#include "common/assert.h"
8#include "core/settings.h" 8#include "common/settings.h"
9#include "video_core/compatible_formats.h" 9#include "video_core/compatible_formats.h"
10#include "video_core/surface.h" 10#include "video_core/surface.h"
11#include "video_core/texture_cache/formatter.h" 11#include "video_core/texture_cache/formatter.h"
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp
index 0ab297413..8c4a5523b 100644
--- a/src/video_core/texture_cache/util.cpp
+++ b/src/video_core/texture_cache/util.cpp
@@ -1139,7 +1139,7 @@ void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase*
1139 dst_info.format = src->info.format; 1139 dst_info.format = src->info.format;
1140 } 1140 }
1141 if (!src && dst && GetFormatType(dst->info.format) != SurfaceType::ColorTexture) { 1141 if (!src && dst && GetFormatType(dst->info.format) != SurfaceType::ColorTexture) {
1142 src_info.format = src->info.format; 1142 src_info.format = dst->info.format;
1143 } 1143 }
1144} 1144}
1145 1145
diff --git a/src/video_core/textures/texture.cpp b/src/video_core/textures/texture.cpp
index ae5621a7d..a552543ed 100644
--- a/src/video_core/textures/texture.cpp
+++ b/src/video_core/textures/texture.cpp
@@ -6,7 +6,7 @@
6#include <array> 6#include <array>
7 7
8#include "common/cityhash.h" 8#include "common/cityhash.h"
9#include "core/settings.h" 9#include "common/settings.h"
10#include "video_core/textures/texture.h" 10#include "video_core/textures/texture.h"
11 11
12using Tegra::Texture::TICEntry; 12using Tegra::Texture::TICEntry;
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp
index e1b38c6ac..3b575db4d 100644
--- a/src/video_core/video_core.cpp
+++ b/src/video_core/video_core.cpp
@@ -5,8 +5,8 @@
5#include <memory> 5#include <memory>
6 6
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "common/settings.h"
8#include "core/core.h" 9#include "core/core.h"
9#include "core/settings.h"
10#include "video_core/renderer_base.h" 10#include "video_core/renderer_base.h"
11#include "video_core/renderer_opengl/renderer_opengl.h" 11#include "video_core/renderer_opengl/renderer_opengl.h"
12#include "video_core/renderer_vulkan/renderer_vulkan.h" 12#include "video_core/renderer_vulkan/renderer_vulkan.h"
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 230b8717b..64206b3d2 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -12,7 +12,7 @@
12#include <vector> 12#include <vector>
13 13
14#include "common/assert.h" 14#include "common/assert.h"
15#include "core/settings.h" 15#include "common/settings.h"
16#include "video_core/vulkan_common/nsight_aftermath_tracker.h" 16#include "video_core/vulkan_common/nsight_aftermath_tracker.h"
17#include "video_core/vulkan_common/vulkan_device.h" 17#include "video_core/vulkan_common/vulkan_device.h"
18#include "video_core/vulkan_common/vulkan_wrapper.h" 18#include "video_core/vulkan_common/vulkan_wrapper.h"
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index b025ced1c..cc0790e07 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -18,6 +18,7 @@ add_executable(yuzu
18 applets/profile_select.h 18 applets/profile_select.h
19 applets/software_keyboard.cpp 19 applets/software_keyboard.cpp
20 applets/software_keyboard.h 20 applets/software_keyboard.h
21 applets/software_keyboard.ui
21 applets/web_browser.cpp 22 applets/web_browser.cpp
22 applets/web_browser.h 23 applets/web_browser.h
23 bootmanager.cpp 24 bootmanager.cpp
@@ -143,6 +144,9 @@ add_executable(yuzu
143 uisettings.h 144 uisettings.h
144 util/limitable_input_dialog.cpp 145 util/limitable_input_dialog.cpp
145 util/limitable_input_dialog.h 146 util/limitable_input_dialog.h
147 util/overlay_dialog.cpp
148 util/overlay_dialog.h
149 util/overlay_dialog.ui
146 util/sequence_dialog/sequence_dialog.cpp 150 util/sequence_dialog/sequence_dialog.cpp
147 util/sequence_dialog/sequence_dialog.h 151 util/sequence_dialog/sequence_dialog.h
148 util/url_request_interceptor.cpp 152 util/url_request_interceptor.cpp
diff --git a/src/yuzu/applets/error.cpp b/src/yuzu/applets/error.cpp
index 8ee03ddb3..085688cd4 100644
--- a/src/yuzu/applets/error.cpp
+++ b/src/yuzu/applets/error.cpp
@@ -19,11 +19,11 @@ QtErrorDisplay::~QtErrorDisplay() = default;
19void QtErrorDisplay::ShowError(ResultCode error, std::function<void()> finished) const { 19void QtErrorDisplay::ShowError(ResultCode error, std::function<void()> finished) const {
20 callback = std::move(finished); 20 callback = std::move(finished);
21 emit MainWindowDisplayError( 21 emit MainWindowDisplayError(
22 tr("An error has occurred.\nPlease try again or contact the developer of the " 22 tr("Error Code: %1-%2 (0x%3)")
23 "software.\n\nError Code: %1-%2 (0x%3)")
24 .arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0')) 23 .arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
25 .arg(error.description, 4, 10, QChar::fromLatin1('0')) 24 .arg(error.description, 4, 10, QChar::fromLatin1('0'))
26 .arg(error.raw, 8, 16, QChar::fromLatin1('0'))); 25 .arg(error.raw, 8, 16, QChar::fromLatin1('0')),
26 tr("An error has occurred.\nPlease try again or contact the developer of the software."));
27} 27}
28 28
29void QtErrorDisplay::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, 29void QtErrorDisplay::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time,
@@ -32,13 +32,14 @@ void QtErrorDisplay::ShowErrorWithTimestamp(ResultCode error, std::chrono::secon
32 32
33 const QDateTime date_time = QDateTime::fromSecsSinceEpoch(time.count()); 33 const QDateTime date_time = QDateTime::fromSecsSinceEpoch(time.count());
34 emit MainWindowDisplayError( 34 emit MainWindowDisplayError(
35 tr("An error occurred on %1 at %2.\nPlease try again or contact the " 35 tr("Error Code: %1-%2 (0x%3)")
36 "developer of the software.\n\nError Code: %3-%4 (0x%5)")
37 .arg(date_time.toString(QStringLiteral("dddd, MMMM d, yyyy")))
38 .arg(date_time.toString(QStringLiteral("h:mm:ss A")))
39 .arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0')) 36 .arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
40 .arg(error.description, 4, 10, QChar::fromLatin1('0')) 37 .arg(error.description, 4, 10, QChar::fromLatin1('0'))
41 .arg(error.raw, 8, 16, QChar::fromLatin1('0'))); 38 .arg(error.raw, 8, 16, QChar::fromLatin1('0')),
39 tr("An error occurred on %1 at %2.\nPlease try again or contact the developer of the "
40 "software.")
41 .arg(date_time.toString(QStringLiteral("dddd, MMMM d, yyyy")))
42 .arg(date_time.toString(QStringLiteral("h:mm:ss A"))));
42} 43}
43 44
44void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_text, 45void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_text,
@@ -46,10 +47,11 @@ void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_te
46 std::function<void()> finished) const { 47 std::function<void()> finished) const {
47 callback = std::move(finished); 48 callback = std::move(finished);
48 emit MainWindowDisplayError( 49 emit MainWindowDisplayError(
49 tr("An error has occurred.\nError Code: %1-%2 (0x%3)\n\n%4\n\n%5") 50 tr("Error Code: %1-%2 (0x%3)")
50 .arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0')) 51 .arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
51 .arg(error.description, 4, 10, QChar::fromLatin1('0')) 52 .arg(error.description, 4, 10, QChar::fromLatin1('0'))
52 .arg(error.raw, 8, 16, QChar::fromLatin1('0')) 53 .arg(error.raw, 8, 16, QChar::fromLatin1('0')),
54 tr("An error has occurred.\n\n%1\n\n%2")
53 .arg(QString::fromStdString(dialog_text)) 55 .arg(QString::fromStdString(dialog_text))
54 .arg(QString::fromStdString(fullscreen_text))); 56 .arg(QString::fromStdString(fullscreen_text)));
55} 57}
diff --git a/src/yuzu/applets/error.h b/src/yuzu/applets/error.h
index b0932d895..8bd895a32 100644
--- a/src/yuzu/applets/error.h
+++ b/src/yuzu/applets/error.h
@@ -24,7 +24,7 @@ public:
24 std::function<void()> finished) const override; 24 std::function<void()> finished) const override;
25 25
26signals: 26signals:
27 void MainWindowDisplayError(QString error) const; 27 void MainWindowDisplayError(QString error_code, QString error_text) const;
28 28
29private: 29private:
30 void MainWindowFinishedError(); 30 void MainWindowFinishedError();
diff --git a/src/yuzu/applets/software_keyboard.cpp b/src/yuzu/applets/software_keyboard.cpp
index ab8cfd8ee..fd3368479 100644
--- a/src/yuzu/applets/software_keyboard.cpp
+++ b/src/yuzu/applets/software_keyboard.cpp
@@ -1,153 +1,1641 @@
1// Copyright 2018 yuzu Emulator Project 1// Copyright 2021 yuzu Emulator Project
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 <algorithm> 5#include <QCursor>
6#include <mutex> 6#include <QKeyEvent>
7#include <QDialogButtonBox> 7#include <QScreen>
8#include <QFont> 8
9#include <QLabel> 9#include "common/logging/log.h"
10#include <QLineEdit> 10#include "common/settings.h"
11#include <QVBoxLayout> 11#include "common/string_util.h"
12#include "core/hle/lock.h" 12#include "core/core.h"
13#include "core/frontend/input_interpreter.h"
14#include "ui_software_keyboard.h"
13#include "yuzu/applets/software_keyboard.h" 15#include "yuzu/applets/software_keyboard.h"
14#include "yuzu/main.h" 16#include "yuzu/main.h"
17#include "yuzu/util/overlay_dialog.h"
18
19namespace {
20
21using namespace Service::AM::Applets;
22
23constexpr float BASE_HEADER_FONT_SIZE = 23.0f;
24constexpr float BASE_SUB_FONT_SIZE = 17.0f;
25constexpr float BASE_EDITOR_FONT_SIZE = 26.0f;
26constexpr float BASE_CHAR_BUTTON_FONT_SIZE = 28.0f;
27constexpr float BASE_LABEL_BUTTON_FONT_SIZE = 18.0f;
28constexpr float BASE_ICON_BUTTON_SIZE = 36.0f;
29[[maybe_unused]] constexpr float BASE_WIDTH = 1280.0f;
30constexpr float BASE_HEIGHT = 720.0f;
31
32} // Anonymous namespace
33
34QtSoftwareKeyboardDialog::QtSoftwareKeyboardDialog(
35 QWidget* parent, Core::System& system_, bool is_inline_,
36 Core::Frontend::KeyboardInitializeParameters initialize_parameters_)
37 : QDialog(parent), ui{std::make_unique<Ui::QtSoftwareKeyboardDialog>()}, system{system_},
38 is_inline{is_inline_}, initialize_parameters{std::move(initialize_parameters_)} {
39 ui->setupUi(this);
40
41 setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowTitleHint |
42 Qt::WindowSystemMenuHint | Qt::CustomizeWindowHint);
43 setWindowModality(Qt::WindowModal);
44 setAttribute(Qt::WA_DeleteOnClose);
45 setAttribute(Qt::WA_TranslucentBackground);
46
47 keyboard_buttons = {{
48 {{
49 {
50 ui->button_1,
51 ui->button_2,
52 ui->button_3,
53 ui->button_4,
54 ui->button_5,
55 ui->button_6,
56 ui->button_7,
57 ui->button_8,
58 ui->button_9,
59 ui->button_0,
60 ui->button_minus,
61 ui->button_backspace,
62 },
63 {
64 ui->button_q,
65 ui->button_w,
66 ui->button_e,
67 ui->button_r,
68 ui->button_t,
69 ui->button_y,
70 ui->button_u,
71 ui->button_i,
72 ui->button_o,
73 ui->button_p,
74 ui->button_slash,
75 ui->button_return,
76 },
77 {
78 ui->button_a,
79 ui->button_s,
80 ui->button_d,
81 ui->button_f,
82 ui->button_g,
83 ui->button_h,
84 ui->button_j,
85 ui->button_k,
86 ui->button_l,
87 ui->button_colon,
88 ui->button_apostrophe,
89 ui->button_return,
90 },
91 {
92 ui->button_z,
93 ui->button_x,
94 ui->button_c,
95 ui->button_v,
96 ui->button_b,
97 ui->button_n,
98 ui->button_m,
99 ui->button_comma,
100 ui->button_dot,
101 ui->button_question,
102 ui->button_exclamation,
103 ui->button_ok,
104 },
105 {
106 ui->button_shift,
107 ui->button_shift,
108 ui->button_space,
109 ui->button_space,
110 ui->button_space,
111 ui->button_space,
112 ui->button_space,
113 ui->button_space,
114 ui->button_space,
115 ui->button_space,
116 ui->button_space,
117 ui->button_ok,
118 },
119 }},
120 {{
121 {
122 ui->button_hash,
123 ui->button_left_bracket,
124 ui->button_right_bracket,
125 ui->button_dollar,
126 ui->button_percent,
127 ui->button_circumflex,
128 ui->button_ampersand,
129 ui->button_asterisk,
130 ui->button_left_parenthesis,
131 ui->button_right_parenthesis,
132 ui->button_underscore,
133 ui->button_backspace_shift,
134 },
135 {
136 ui->button_q_shift,
137 ui->button_w_shift,
138 ui->button_e_shift,
139 ui->button_r_shift,
140 ui->button_t_shift,
141 ui->button_y_shift,
142 ui->button_u_shift,
143 ui->button_i_shift,
144 ui->button_o_shift,
145 ui->button_p_shift,
146 ui->button_at,
147 ui->button_return_shift,
148 },
149 {
150 ui->button_a_shift,
151 ui->button_s_shift,
152 ui->button_d_shift,
153 ui->button_f_shift,
154 ui->button_g_shift,
155 ui->button_h_shift,
156 ui->button_j_shift,
157 ui->button_k_shift,
158 ui->button_l_shift,
159 ui->button_semicolon,
160 ui->button_quotation,
161 ui->button_return_shift,
162 },
163 {
164 ui->button_z_shift,
165 ui->button_x_shift,
166 ui->button_c_shift,
167 ui->button_v_shift,
168 ui->button_b_shift,
169 ui->button_n_shift,
170 ui->button_m_shift,
171 ui->button_less_than,
172 ui->button_greater_than,
173 ui->button_plus,
174 ui->button_equal,
175 ui->button_ok_shift,
176 },
177 {
178 ui->button_shift_shift,
179 ui->button_shift_shift,
180 ui->button_space_shift,
181 ui->button_space_shift,
182 ui->button_space_shift,
183 ui->button_space_shift,
184 ui->button_space_shift,
185 ui->button_space_shift,
186 ui->button_space_shift,
187 ui->button_space_shift,
188 ui->button_space_shift,
189 ui->button_ok_shift,
190 },
191 }},
192 }};
15 193
16QtSoftwareKeyboardValidator::QtSoftwareKeyboardValidator( 194 numberpad_buttons = {{
17 Core::Frontend::SoftwareKeyboardParameters parameters) 195 {
18 : parameters(std::move(parameters)) {} 196 ui->button_1_num,
197 ui->button_2_num,
198 ui->button_3_num,
199 ui->button_backspace_num,
200 },
201 {
202 ui->button_4_num,
203 ui->button_5_num,
204 ui->button_6_num,
205 ui->button_ok_num,
206 },
207 {
208 ui->button_7_num,
209 ui->button_8_num,
210 ui->button_9_num,
211 ui->button_ok_num,
212 },
213 {
214 nullptr,
215 ui->button_0_num,
216 nullptr,
217 ui->button_ok_num,
218 },
219 }};
19 220
20QValidator::State QtSoftwareKeyboardValidator::validate(QString& input, int& pos) const { 221 all_buttons = {
21 if (input.size() > static_cast<s64>(parameters.max_length)) { 222 ui->button_1,
22 return Invalid; 223 ui->button_2,
224 ui->button_3,
225 ui->button_4,
226 ui->button_5,
227 ui->button_6,
228 ui->button_7,
229 ui->button_8,
230 ui->button_9,
231 ui->button_0,
232 ui->button_minus,
233 ui->button_backspace,
234 ui->button_q,
235 ui->button_w,
236 ui->button_e,
237 ui->button_r,
238 ui->button_t,
239 ui->button_y,
240 ui->button_u,
241 ui->button_i,
242 ui->button_o,
243 ui->button_p,
244 ui->button_slash,
245 ui->button_return,
246 ui->button_a,
247 ui->button_s,
248 ui->button_d,
249 ui->button_f,
250 ui->button_g,
251 ui->button_h,
252 ui->button_j,
253 ui->button_k,
254 ui->button_l,
255 ui->button_colon,
256 ui->button_apostrophe,
257 ui->button_z,
258 ui->button_x,
259 ui->button_c,
260 ui->button_v,
261 ui->button_b,
262 ui->button_n,
263 ui->button_m,
264 ui->button_comma,
265 ui->button_dot,
266 ui->button_question,
267 ui->button_exclamation,
268 ui->button_ok,
269 ui->button_shift,
270 ui->button_space,
271 ui->button_hash,
272 ui->button_left_bracket,
273 ui->button_right_bracket,
274 ui->button_dollar,
275 ui->button_percent,
276 ui->button_circumflex,
277 ui->button_ampersand,
278 ui->button_asterisk,
279 ui->button_left_parenthesis,
280 ui->button_right_parenthesis,
281 ui->button_underscore,
282 ui->button_backspace_shift,
283 ui->button_q_shift,
284 ui->button_w_shift,
285 ui->button_e_shift,
286 ui->button_r_shift,
287 ui->button_t_shift,
288 ui->button_y_shift,
289 ui->button_u_shift,
290 ui->button_i_shift,
291 ui->button_o_shift,
292 ui->button_p_shift,
293 ui->button_at,
294 ui->button_return_shift,
295 ui->button_a_shift,
296 ui->button_s_shift,
297 ui->button_d_shift,
298 ui->button_f_shift,
299 ui->button_g_shift,
300 ui->button_h_shift,
301 ui->button_j_shift,
302 ui->button_k_shift,
303 ui->button_l_shift,
304 ui->button_semicolon,
305 ui->button_quotation,
306 ui->button_z_shift,
307 ui->button_x_shift,
308 ui->button_c_shift,
309 ui->button_v_shift,
310 ui->button_b_shift,
311 ui->button_n_shift,
312 ui->button_m_shift,
313 ui->button_less_than,
314 ui->button_greater_than,
315 ui->button_plus,
316 ui->button_equal,
317 ui->button_ok_shift,
318 ui->button_shift_shift,
319 ui->button_space_shift,
320 ui->button_1_num,
321 ui->button_2_num,
322 ui->button_3_num,
323 ui->button_backspace_num,
324 ui->button_4_num,
325 ui->button_5_num,
326 ui->button_6_num,
327 ui->button_ok_num,
328 ui->button_7_num,
329 ui->button_8_num,
330 ui->button_9_num,
331 ui->button_0_num,
332 };
333
334 SetupMouseHover();
335
336 if (!initialize_parameters.ok_text.empty()) {
337 ui->button_ok->setText(QString::fromStdU16String(initialize_parameters.ok_text));
23 } 338 }
24 if (parameters.disable_space && input.contains(QLatin1Char{' '})) { 339
25 return Invalid; 340 ui->label_header->setText(QString::fromStdU16String(initialize_parameters.header_text));
341 ui->label_sub->setText(QString::fromStdU16String(initialize_parameters.sub_text));
342
343 current_text = initialize_parameters.initial_text;
344 cursor_position = initialize_parameters.initial_cursor_position;
345
346 SetTextDrawType();
347
348 for (auto* button : all_buttons) {
349 connect(button, &QPushButton::clicked, this, [this, button](bool) {
350 if (is_inline) {
351 InlineKeyboardButtonClicked(button);
352 } else {
353 NormalKeyboardButtonClicked(button);
354 }
355 });
26 } 356 }
27 if (parameters.disable_address && input.contains(QLatin1Char{'@'})) { 357
28 return Invalid; 358 // TODO (Morph): Remove this when InputInterpreter no longer relies on the HID backend
359 if (system.IsPoweredOn()) {
360 input_interpreter = std::make_unique<InputInterpreter>(system);
29 } 361 }
30 if (parameters.disable_percent && input.contains(QLatin1Char{'%'})) { 362}
31 return Invalid; 363
364QtSoftwareKeyboardDialog::~QtSoftwareKeyboardDialog() {
365 StopInputThread();
366}
367
368void QtSoftwareKeyboardDialog::ShowNormalKeyboard(QPoint pos, QSize size) {
369 if (isVisible()) {
370 return;
32 } 371 }
33 if (parameters.disable_slash && 372
34 (input.contains(QLatin1Char{'/'}) || input.contains(QLatin1Char{'\\'}))) { 373 MoveAndResizeWindow(pos, size);
35 return Invalid; 374
375 SetKeyboardType();
376 SetPasswordMode();
377 SetControllerImage();
378 DisableKeyboardButtons();
379 SetBackspaceOkEnabled();
380
381 open();
382}
383
384void QtSoftwareKeyboardDialog::ShowTextCheckDialog(
385 Service::AM::Applets::SwkbdTextCheckResult text_check_result,
386 std::u16string text_check_message) {
387 switch (text_check_result) {
388 case SwkbdTextCheckResult::Success:
389 case SwkbdTextCheckResult::Silent:
390 default:
391 break;
392 case SwkbdTextCheckResult::Failure: {
393 StopInputThread();
394
395 OverlayDialog dialog(this, system, QString{}, QString::fromStdU16String(text_check_message),
396 QString{}, tr("OK"), Qt::AlignCenter);
397 dialog.exec();
398
399 StartInputThread();
400 break;
36 } 401 }
37 if (parameters.disable_number && 402 case SwkbdTextCheckResult::Confirm: {
38 std::any_of(input.begin(), input.end(), [](QChar c) { return c.isDigit(); })) { 403 StopInputThread();
39 return Invalid; 404
405 OverlayDialog dialog(this, system, QString{}, QString::fromStdU16String(text_check_message),
406 tr("Cancel"), tr("OK"), Qt::AlignCenter);
407 if (dialog.exec() == QDialog::Accepted) {
408 emit SubmitNormalText(SwkbdResult::Ok, current_text);
409 break;
410 }
411
412 StartInputThread();
413 break;
40 } 414 }
415 }
416}
417
418void QtSoftwareKeyboardDialog::ShowInlineKeyboard(
419 Core::Frontend::InlineAppearParameters appear_parameters, QPoint pos, QSize size) {
420 MoveAndResizeWindow(pos, size);
421
422 ui->topOSK->setStyleSheet(QStringLiteral("background: rgba(0, 0, 0, 0);"));
423
424 ui->headerOSK->hide();
425 ui->subOSK->hide();
426 ui->inputOSK->hide();
427 ui->charactersOSK->hide();
428 ui->inputBoxOSK->hide();
429 ui->charactersBoxOSK->hide();
430
431 initialize_parameters.max_text_length = appear_parameters.max_text_length;
432 initialize_parameters.min_text_length = appear_parameters.min_text_length;
433 initialize_parameters.type = appear_parameters.type;
434 initialize_parameters.key_disable_flags = appear_parameters.key_disable_flags;
435 initialize_parameters.enable_backspace_button = appear_parameters.enable_backspace_button;
436 initialize_parameters.enable_return_button = appear_parameters.enable_return_button;
437 initialize_parameters.disable_cancel_button = initialize_parameters.disable_cancel_button;
41 438
42 if (parameters.disable_download_code && std::any_of(input.begin(), input.end(), [](QChar c) { 439 SetKeyboardType();
43 return c == QLatin1Char{'O'} || c == QLatin1Char{'I'}; 440 SetControllerImage();
44 })) { 441 DisableKeyboardButtons();
45 return Invalid; 442 SetBackspaceOkEnabled();
443
444 open();
445}
446
447void QtSoftwareKeyboardDialog::HideInlineKeyboard() {
448 StopInputThread();
449 QDialog::hide();
450}
451
452void QtSoftwareKeyboardDialog::InlineTextChanged(
453 Core::Frontend::InlineTextParameters text_parameters) {
454 current_text = text_parameters.input_text;
455 cursor_position = text_parameters.cursor_position;
456
457 SetBackspaceOkEnabled();
458}
459
460void QtSoftwareKeyboardDialog::ExitKeyboard() {
461 StopInputThread();
462 QDialog::done(QDialog::Accepted);
463}
464
465void QtSoftwareKeyboardDialog::open() {
466 QDialog::open();
467
468 row = 0;
469 column = 0;
470
471 const auto* const curr_button =
472 keyboard_buttons[static_cast<int>(bottom_osk_index)][row][column];
473
474 // This is a workaround for setFocus() randomly not showing focus in the UI
475 QCursor::setPos(curr_button->mapToGlobal(curr_button->rect().center()));
476
477 StartInputThread();
478}
479
480void QtSoftwareKeyboardDialog::reject() {
481 // Pressing the ESC key in a dialog calls QDialog::reject().
482 // We will override this behavior to the "Cancel" action on the software keyboard.
483 if (is_inline) {
484 emit SubmitInlineText(SwkbdReplyType::DecidedCancel, current_text, cursor_position);
485 } else {
486 emit SubmitNormalText(SwkbdResult::Cancel, current_text);
46 } 487 }
488}
489
490void QtSoftwareKeyboardDialog::keyPressEvent(QKeyEvent* event) {
491 if (!is_inline) {
492 QDialog::keyPressEvent(event);
493 return;
494 }
495
496 const auto entered_key = event->key();
47 497
48 return Acceptable; 498 switch (entered_key) {
499 case Qt::Key_Escape:
500 QDialog::keyPressEvent(event);
501 return;
502 case Qt::Key_Backspace:
503 switch (bottom_osk_index) {
504 case BottomOSKIndex::LowerCase:
505 ui->button_backspace->click();
506 break;
507 case BottomOSKIndex::UpperCase:
508 ui->button_backspace_shift->click();
509 break;
510 case BottomOSKIndex::NumberPad:
511 ui->button_backspace_num->click();
512 break;
513 default:
514 break;
515 }
516 return;
517 case Qt::Key_Return:
518 switch (bottom_osk_index) {
519 case BottomOSKIndex::LowerCase:
520 ui->button_ok->click();
521 break;
522 case BottomOSKIndex::UpperCase:
523 ui->button_ok_shift->click();
524 break;
525 case BottomOSKIndex::NumberPad:
526 ui->button_ok_num->click();
527 break;
528 default:
529 break;
530 }
531 return;
532 case Qt::Key_Left:
533 MoveTextCursorDirection(Direction::Left);
534 return;
535 case Qt::Key_Right:
536 MoveTextCursorDirection(Direction::Right);
537 return;
538 default:
539 break;
540 }
541
542 const auto entered_text = event->text();
543
544 if (entered_text.isEmpty()) {
545 return;
546 }
547
548 InlineTextInsertString(entered_text.toStdU16String());
49} 549}
50 550
51QtSoftwareKeyboardDialog::QtSoftwareKeyboardDialog( 551void QtSoftwareKeyboardDialog::MoveAndResizeWindow(QPoint pos, QSize size) {
52 QWidget* parent, Core::Frontend::SoftwareKeyboardParameters parameters_) 552 QDialog::move(pos);
53 : QDialog(parent), parameters(std::move(parameters_)) { 553 QDialog::resize(size);
54 layout = new QVBoxLayout; 554
55 555 // High DPI
56 header_label = new QLabel(QString::fromStdU16String(parameters.header_text)); 556 const float dpi_scale = qApp->screenAt(pos)->logicalDotsPerInch() / 96.0f;
57 header_label->setFont({header_label->font().family(), 11, QFont::Bold}); 557
58 if (header_label->text().isEmpty()) 558 RescaleKeyboardElements(size.width(), size.height(), dpi_scale);
59 header_label->setText(tr("Enter text:")); 559}
60 560
61 sub_label = new QLabel(QString::fromStdU16String(parameters.sub_text)); 561void QtSoftwareKeyboardDialog::RescaleKeyboardElements(float width, float height, float dpi_scale) {
62 sub_label->setFont({sub_label->font().family(), sub_label->font().pointSize(), 562 const auto header_font_size = BASE_HEADER_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
63 sub_label->font().weight(), true}); 563 const auto sub_font_size = BASE_SUB_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
64 sub_label->setHidden(parameters.sub_text.empty()); 564 const auto editor_font_size = BASE_EDITOR_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
65 565 const auto char_button_font_size =
66 guide_label = new QLabel(QString::fromStdU16String(parameters.guide_text)); 566 BASE_CHAR_BUTTON_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
67 guide_label->setHidden(parameters.guide_text.empty()); 567 const auto label_button_font_size =
68 568 BASE_LABEL_BUTTON_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
69 length_label = new QLabel(QStringLiteral("0/%1").arg(parameters.max_length)); 569
70 length_label->setAlignment(Qt::AlignRight); 570 QFont header_font(QStringLiteral("MS Shell Dlg 2"), header_font_size, QFont::Normal);
71 length_label->setFont({length_label->font().family(), 8}); 571 QFont sub_font(QStringLiteral("MS Shell Dlg 2"), sub_font_size, QFont::Normal);
72 572 QFont editor_font(QStringLiteral("MS Shell Dlg 2"), editor_font_size, QFont::Normal);
73 line_edit = new QLineEdit; 573 QFont char_button_font(QStringLiteral("MS Shell Dlg 2"), char_button_font_size, QFont::Normal);
74 line_edit->setValidator(new QtSoftwareKeyboardValidator(parameters)); 574 QFont label_button_font(QStringLiteral("MS Shell Dlg 2"), label_button_font_size,
75 line_edit->setMaxLength(static_cast<int>(parameters.max_length)); 575 QFont::Normal);
76 line_edit->setText(QString::fromStdU16String(parameters.initial_text)); 576
77 line_edit->setCursorPosition( 577 ui->label_header->setFont(header_font);
78 parameters.cursor_at_beginning ? 0 : static_cast<int>(parameters.initial_text.size())); 578 ui->label_sub->setFont(sub_font);
79 line_edit->setEchoMode(parameters.password ? QLineEdit::Password : QLineEdit::Normal); 579 ui->line_edit_osk->setFont(editor_font);
80 580 ui->text_edit_osk->setFont(editor_font);
81 connect(line_edit, &QLineEdit::textChanged, this, [this](const QString& text) { 581 ui->label_characters->setFont(sub_font);
82 length_label->setText(QStringLiteral("%1/%2").arg(text.size()).arg(parameters.max_length)); 582 ui->label_characters_box->setFont(sub_font);
83 }); 583
84 584 ui->label_shift->setFont(label_button_font);
85 buttons = new QDialogButtonBox(QDialogButtonBox::Cancel); 585 ui->label_shift_shift->setFont(label_button_font);
86 if (parameters.submit_text.empty()) { 586 ui->label_cancel->setFont(label_button_font);
87 buttons->addButton(QDialogButtonBox::Ok); 587 ui->label_cancel_shift->setFont(label_button_font);
588 ui->label_cancel_num->setFont(label_button_font);
589 ui->label_enter->setFont(label_button_font);
590 ui->label_enter_shift->setFont(label_button_font);
591 ui->label_enter_num->setFont(label_button_font);
592
593 for (auto* button : all_buttons) {
594 if (button == ui->button_return || button == ui->button_return_shift) {
595 button->setFont(label_button_font);
596 continue;
597 }
598
599 if (button == ui->button_space || button == ui->button_space_shift) {
600 button->setFont(label_button_font);
601 continue;
602 }
603
604 if (button == ui->button_shift || button == ui->button_shift_shift) {
605 button->setFont(label_button_font);
606 button->setIconSize(QSize(BASE_ICON_BUTTON_SIZE, BASE_ICON_BUTTON_SIZE) *
607 (height / BASE_HEIGHT));
608 continue;
609 }
610
611 if (button == ui->button_backspace || button == ui->button_backspace_shift ||
612 button == ui->button_backspace_num) {
613 button->setFont(label_button_font);
614 button->setIconSize(QSize(BASE_ICON_BUTTON_SIZE, BASE_ICON_BUTTON_SIZE) *
615 (height / BASE_HEIGHT));
616 continue;
617 }
618
619 if (button == ui->button_ok || button == ui->button_ok_shift ||
620 button == ui->button_ok_num) {
621 button->setFont(label_button_font);
622 continue;
623 }
624
625 button->setFont(char_button_font);
626 }
627}
628
629void QtSoftwareKeyboardDialog::SetKeyboardType() {
630 switch (initialize_parameters.type) {
631 case SwkbdType::Normal:
632 case SwkbdType::Qwerty:
633 case SwkbdType::Unknown3:
634 case SwkbdType::Latin:
635 case SwkbdType::SimplifiedChinese:
636 case SwkbdType::TraditionalChinese:
637 case SwkbdType::Korean:
638 default: {
639 bottom_osk_index = BottomOSKIndex::LowerCase;
640 ui->bottomOSK->setCurrentIndex(static_cast<int>(bottom_osk_index));
641
642 ui->verticalLayout_2->setStretch(0, 320);
643 ui->verticalLayout_2->setStretch(1, 400);
644
645 ui->gridLineOSK->setRowStretch(5, 94);
646 ui->gridBoxOSK->setRowStretch(2, 81);
647 break;
648 }
649 case SwkbdType::NumberPad: {
650 bottom_osk_index = BottomOSKIndex::NumberPad;
651 ui->bottomOSK->setCurrentIndex(static_cast<int>(bottom_osk_index));
652
653 ui->verticalLayout_2->setStretch(0, 370);
654 ui->verticalLayout_2->setStretch(1, 350);
655
656 ui->gridLineOSK->setRowStretch(5, 144);
657 ui->gridBoxOSK->setRowStretch(2, 131);
658 break;
659 }
660 }
661}
662
663void QtSoftwareKeyboardDialog::SetPasswordMode() {
664 switch (initialize_parameters.password_mode) {
665 case SwkbdPasswordMode::Disabled:
666 default:
667 ui->line_edit_osk->setEchoMode(QLineEdit::Normal);
668 break;
669 case SwkbdPasswordMode::Enabled:
670 ui->line_edit_osk->setEchoMode(QLineEdit::Password);
671 break;
672 }
673}
674
675void QtSoftwareKeyboardDialog::SetTextDrawType() {
676 switch (initialize_parameters.text_draw_type) {
677 case SwkbdTextDrawType::Line:
678 case SwkbdTextDrawType::DownloadCode: {
679 ui->topOSK->setCurrentIndex(0);
680
681 if (initialize_parameters.max_text_length <= 10) {
682 ui->gridLineOSK->setColumnStretch(0, 390);
683 ui->gridLineOSK->setColumnStretch(1, 500);
684 ui->gridLineOSK->setColumnStretch(2, 390);
685 } else {
686 ui->gridLineOSK->setColumnStretch(0, 130);
687 ui->gridLineOSK->setColumnStretch(1, 1020);
688 ui->gridLineOSK->setColumnStretch(2, 130);
689 }
690
691 if (is_inline) {
692 return;
693 }
694
695 connect(ui->line_edit_osk, &QLineEdit::textChanged, [this](const QString& changed_string) {
696 const auto is_valid = ValidateInputText(changed_string);
697
698 const auto text_length = static_cast<u32>(changed_string.length());
699
700 ui->label_characters->setText(QStringLiteral("%1/%2")
701 .arg(text_length)
702 .arg(initialize_parameters.max_text_length));
703
704 ui->button_ok->setEnabled(is_valid);
705 ui->button_ok_shift->setEnabled(is_valid);
706 ui->button_ok_num->setEnabled(is_valid);
707
708 ui->line_edit_osk->setFocus();
709 });
710
711 connect(ui->line_edit_osk, &QLineEdit::cursorPositionChanged,
712 [this](int old_cursor_position, int new_cursor_position) {
713 ui->button_backspace->setEnabled(
714 initialize_parameters.enable_backspace_button && new_cursor_position > 0);
715 ui->button_backspace_shift->setEnabled(
716 initialize_parameters.enable_backspace_button && new_cursor_position > 0);
717 ui->button_backspace_num->setEnabled(
718 initialize_parameters.enable_backspace_button && new_cursor_position > 0);
719
720 ui->line_edit_osk->setFocus();
721 });
722
723 connect(ui->line_edit_osk, &QLineEdit::returnPressed, [this] {
724 switch (bottom_osk_index) {
725 case BottomOSKIndex::LowerCase:
726 ui->button_ok->click();
727 break;
728 case BottomOSKIndex::UpperCase:
729 ui->button_ok_shift->click();
730 break;
731 case BottomOSKIndex::NumberPad:
732 ui->button_ok_num->click();
733 break;
734 default:
735 break;
736 }
737 });
738
739 ui->line_edit_osk->setPlaceholderText(
740 QString::fromStdU16String(initialize_parameters.guide_text));
741 ui->line_edit_osk->setText(QString::fromStdU16String(initialize_parameters.initial_text));
742 ui->line_edit_osk->setMaxLength(initialize_parameters.max_text_length);
743 ui->line_edit_osk->setCursorPosition(initialize_parameters.initial_cursor_position);
744
745 ui->label_characters->setText(QStringLiteral("%1/%2")
746 .arg(initialize_parameters.initial_text.size())
747 .arg(initialize_parameters.max_text_length));
748 break;
749 }
750 case SwkbdTextDrawType::Box:
751 default: {
752 ui->topOSK->setCurrentIndex(1);
753
754 if (is_inline) {
755 return;
756 }
757
758 connect(ui->text_edit_osk, &QTextEdit::textChanged, [this] {
759 if (static_cast<u32>(ui->text_edit_osk->toPlainText().length()) >
760 initialize_parameters.max_text_length) {
761 auto text_cursor = ui->text_edit_osk->textCursor();
762 ui->text_edit_osk->setTextCursor(text_cursor);
763 text_cursor.deletePreviousChar();
764 }
765
766 const auto is_valid = ValidateInputText(ui->text_edit_osk->toPlainText());
767
768 const auto text_length = static_cast<u32>(ui->text_edit_osk->toPlainText().length());
769
770 ui->label_characters_box->setText(QStringLiteral("%1/%2")
771 .arg(text_length)
772 .arg(initialize_parameters.max_text_length));
773
774 ui->button_ok->setEnabled(is_valid);
775 ui->button_ok_shift->setEnabled(is_valid);
776 ui->button_ok_num->setEnabled(is_valid);
777
778 ui->text_edit_osk->setFocus();
779 });
780
781 connect(ui->text_edit_osk, &QTextEdit::cursorPositionChanged, [this] {
782 const auto new_cursor_position = ui->text_edit_osk->textCursor().position();
783
784 ui->button_backspace->setEnabled(initialize_parameters.enable_backspace_button &&
785 new_cursor_position > 0);
786 ui->button_backspace_shift->setEnabled(initialize_parameters.enable_backspace_button &&
787 new_cursor_position > 0);
788 ui->button_backspace_num->setEnabled(initialize_parameters.enable_backspace_button &&
789 new_cursor_position > 0);
790
791 ui->text_edit_osk->setFocus();
792 });
793
794 ui->text_edit_osk->setPlaceholderText(
795 QString::fromStdU16String(initialize_parameters.guide_text));
796 ui->text_edit_osk->setText(QString::fromStdU16String(initialize_parameters.initial_text));
797 ui->text_edit_osk->moveCursor(initialize_parameters.initial_cursor_position == 0
798 ? QTextCursor::Start
799 : QTextCursor::End);
800
801 ui->label_characters_box->setText(QStringLiteral("%1/%2")
802 .arg(initialize_parameters.initial_text.size())
803 .arg(initialize_parameters.max_text_length));
804 break;
805 }
806 }
807}
808
809void QtSoftwareKeyboardDialog::SetControllerImage() {
810 const auto controller_type = Settings::values.players.GetValue()[8].connected
811 ? Settings::values.players.GetValue()[8].controller_type
812 : Settings::values.players.GetValue()[0].controller_type;
813
814 const QString theme = [] {
815 if (QIcon::themeName().contains(QStringLiteral("dark")) ||
816 QIcon::themeName().contains(QStringLiteral("midnight"))) {
817 return QStringLiteral("_dark");
818 } else {
819 return QString{};
820 }
821 }();
822
823 switch (controller_type) {
824 case Settings::ControllerType::ProController:
825 case Settings::ControllerType::GameCube:
826 ui->icon_controller->setStyleSheet(
827 QStringLiteral("image: url(:/overlay/controller_pro%1.png);").arg(theme));
828 ui->icon_controller_shift->setStyleSheet(
829 QStringLiteral("image: url(:/overlay/controller_pro%1.png);").arg(theme));
830 ui->icon_controller_num->setStyleSheet(
831 QStringLiteral("image: url(:/overlay/controller_pro%1.png);").arg(theme));
832 break;
833 case Settings::ControllerType::DualJoyconDetached:
834 ui->icon_controller->setStyleSheet(
835 QStringLiteral("image: url(:/overlay/controller_dual_joycon%1.png);").arg(theme));
836 ui->icon_controller_shift->setStyleSheet(
837 QStringLiteral("image: url(:/overlay/controller_dual_joycon%1.png);").arg(theme));
838 ui->icon_controller_num->setStyleSheet(
839 QStringLiteral("image: url(:/overlay/controller_dual_joycon%1.png);").arg(theme));
840 break;
841 case Settings::ControllerType::LeftJoycon:
842 ui->icon_controller->setStyleSheet(
843 QStringLiteral("image: url(:/overlay/controller_single_joycon_left%1.png);")
844 .arg(theme));
845 ui->icon_controller_shift->setStyleSheet(
846 QStringLiteral("image: url(:/overlay/controller_single_joycon_left%1.png);")
847 .arg(theme));
848 ui->icon_controller_num->setStyleSheet(
849 QStringLiteral("image: url(:/overlay/controller_single_joycon_left%1.png);")
850 .arg(theme));
851 break;
852 case Settings::ControllerType::RightJoycon:
853 ui->icon_controller->setStyleSheet(
854 QStringLiteral("image: url(:/overlay/controller_single_joycon_right%1.png);")
855 .arg(theme));
856 ui->icon_controller_shift->setStyleSheet(
857 QStringLiteral("image: url(:/overlay/controller_single_joycon_right%1.png);")
858 .arg(theme));
859 ui->icon_controller_num->setStyleSheet(
860 QStringLiteral("image: url(:/overlay/controller_single_joycon_right%1.png);")
861 .arg(theme));
862 break;
863 case Settings::ControllerType::Handheld:
864 ui->icon_controller->setStyleSheet(
865 QStringLiteral("image: url(:/overlay/controller_handheld%1.png);").arg(theme));
866 ui->icon_controller_shift->setStyleSheet(
867 QStringLiteral("image: url(:/overlay/controller_handheld%1.png);").arg(theme));
868 ui->icon_controller_num->setStyleSheet(
869 QStringLiteral("image: url(:/overlay/controller_handheld%1.png);").arg(theme));
870 break;
871 default:
872 break;
873 }
874}
875
876void QtSoftwareKeyboardDialog::DisableKeyboardButtons() {
877 switch (bottom_osk_index) {
878 case BottomOSKIndex::LowerCase:
879 case BottomOSKIndex::UpperCase:
880 default: {
881 for (const auto& keys : keyboard_buttons) {
882 for (const auto& rows : keys) {
883 for (auto* button : rows) {
884 if (!button) {
885 continue;
886 }
887
888 button->setEnabled(true);
889 }
890 }
891 }
892
893 const auto& key_disable_flags = initialize_parameters.key_disable_flags;
894
895 ui->button_space->setDisabled(key_disable_flags.space);
896 ui->button_space_shift->setDisabled(key_disable_flags.space);
897
898 ui->button_at->setDisabled(key_disable_flags.at || key_disable_flags.username);
899
900 ui->button_percent->setDisabled(key_disable_flags.percent || key_disable_flags.username);
901
902 ui->button_slash->setDisabled(key_disable_flags.slash);
903
904 ui->button_1->setDisabled(key_disable_flags.numbers);
905 ui->button_2->setDisabled(key_disable_flags.numbers);
906 ui->button_3->setDisabled(key_disable_flags.numbers);
907 ui->button_4->setDisabled(key_disable_flags.numbers);
908 ui->button_5->setDisabled(key_disable_flags.numbers);
909 ui->button_6->setDisabled(key_disable_flags.numbers);
910 ui->button_7->setDisabled(key_disable_flags.numbers);
911 ui->button_8->setDisabled(key_disable_flags.numbers);
912 ui->button_9->setDisabled(key_disable_flags.numbers);
913 ui->button_0->setDisabled(key_disable_flags.numbers);
914
915 ui->button_return->setEnabled(initialize_parameters.enable_return_button);
916 ui->button_return_shift->setEnabled(initialize_parameters.enable_return_button);
917 break;
918 }
919 case BottomOSKIndex::NumberPad: {
920 for (const auto& rows : numberpad_buttons) {
921 for (auto* button : rows) {
922 if (!button) {
923 continue;
924 }
925
926 button->setEnabled(true);
927 }
928 }
929 break;
930 }
931 }
932}
933
934void QtSoftwareKeyboardDialog::SetBackspaceOkEnabled() {
935 if (is_inline) {
936 ui->button_ok->setEnabled(current_text.size() >= initialize_parameters.min_text_length);
937 ui->button_ok_shift->setEnabled(current_text.size() >=
938 initialize_parameters.min_text_length);
939 ui->button_ok_num->setEnabled(current_text.size() >= initialize_parameters.min_text_length);
940
941 ui->button_backspace->setEnabled(initialize_parameters.enable_backspace_button &&
942 cursor_position > 0);
943 ui->button_backspace_shift->setEnabled(initialize_parameters.enable_backspace_button &&
944 cursor_position > 0);
945 ui->button_backspace_num->setEnabled(initialize_parameters.enable_backspace_button &&
946 cursor_position > 0);
88 } else { 947 } else {
89 buttons->addButton(QString::fromStdU16String(parameters.submit_text), 948 const auto text_length = [this] {
90 QDialogButtonBox::AcceptRole); 949 if (ui->topOSK->currentIndex() == 1) {
950 return static_cast<u32>(ui->text_edit_osk->toPlainText().length());
951 } else {
952 return static_cast<u32>(ui->line_edit_osk->text().length());
953 }
954 }();
955
956 const auto normal_cursor_position = [this] {
957 if (ui->topOSK->currentIndex() == 1) {
958 return ui->text_edit_osk->textCursor().position();
959 } else {
960 return ui->line_edit_osk->cursorPosition();
961 }
962 }();
963
964 ui->button_ok->setEnabled(text_length >= initialize_parameters.min_text_length);
965 ui->button_ok_shift->setEnabled(text_length >= initialize_parameters.min_text_length);
966 ui->button_ok_num->setEnabled(text_length >= initialize_parameters.min_text_length);
967
968 ui->button_backspace->setEnabled(initialize_parameters.enable_backspace_button &&
969 normal_cursor_position > 0);
970 ui->button_backspace_shift->setEnabled(initialize_parameters.enable_backspace_button &&
971 normal_cursor_position > 0);
972 ui->button_backspace_num->setEnabled(initialize_parameters.enable_backspace_button &&
973 normal_cursor_position > 0);
91 } 974 }
92 connect(buttons, &QDialogButtonBox::accepted, this, &QtSoftwareKeyboardDialog::accept);
93 connect(buttons, &QDialogButtonBox::rejected, this, &QtSoftwareKeyboardDialog::reject);
94 layout->addWidget(header_label);
95 layout->addWidget(sub_label);
96 layout->addWidget(guide_label);
97 layout->addWidget(length_label);
98 layout->addWidget(line_edit);
99 layout->addWidget(buttons);
100 setLayout(layout);
101 setWindowTitle(tr("Software Keyboard"));
102} 975}
103 976
104QtSoftwareKeyboardDialog::~QtSoftwareKeyboardDialog() = default; 977bool QtSoftwareKeyboardDialog::ValidateInputText(const QString& input_text) {
978 const auto& key_disable_flags = initialize_parameters.key_disable_flags;
979
980 const auto input_text_length = static_cast<u32>(input_text.length());
981
982 if (input_text_length < initialize_parameters.min_text_length ||
983 input_text_length > initialize_parameters.max_text_length) {
984 return false;
985 }
986
987 if (key_disable_flags.space && input_text.contains(QLatin1Char{' '})) {
988 return false;
989 }
990
991 if ((key_disable_flags.at || key_disable_flags.username) &&
992 input_text.contains(QLatin1Char{'@'})) {
993 return false;
994 }
995
996 if ((key_disable_flags.percent || key_disable_flags.username) &&
997 input_text.contains(QLatin1Char{'%'})) {
998 return false;
999 }
1000
1001 if (key_disable_flags.slash && input_text.contains(QLatin1Char{'/'})) {
1002 return false;
1003 }
1004
1005 if ((key_disable_flags.backslash || key_disable_flags.username) &&
1006 input_text.contains(QLatin1Char('\\'))) {
1007 return false;
1008 }
105 1009
106void QtSoftwareKeyboardDialog::accept() { 1010 if (key_disable_flags.numbers &&
107 text = line_edit->text().toStdU16String(); 1011 std::any_of(input_text.begin(), input_text.end(), [](QChar c) { return c.isDigit(); })) {
108 QDialog::accept(); 1012 return false;
1013 }
1014
1015 if (bottom_osk_index == BottomOSKIndex::NumberPad &&
1016 std::any_of(input_text.begin(), input_text.end(), [](QChar c) { return !c.isDigit(); })) {
1017 return false;
1018 }
1019
1020 return true;
109} 1021}
110 1022
111void QtSoftwareKeyboardDialog::reject() { 1023void QtSoftwareKeyboardDialog::ChangeBottomOSKIndex() {
112 text.clear(); 1024 switch (bottom_osk_index) {
113 QDialog::reject(); 1025 case BottomOSKIndex::LowerCase:
1026 bottom_osk_index = BottomOSKIndex::UpperCase;
1027 ui->bottomOSK->setCurrentIndex(static_cast<int>(bottom_osk_index));
1028
1029 ui->button_shift_shift->setStyleSheet(
1030 QStringLiteral("background-image: url(:/overlay/osk_button_shift_lock_off.png);"
1031 "\nbackground-position: left top;"
1032 "\nbackground-repeat: no-repeat;"
1033 "\nbackground-origin: content;"));
1034
1035 ui->button_shift_shift->setIconSize(ui->button_shift->iconSize());
1036 ui->button_backspace_shift->setIconSize(ui->button_backspace->iconSize());
1037 break;
1038 case BottomOSKIndex::UpperCase:
1039 if (caps_lock_enabled) {
1040 caps_lock_enabled = false;
1041
1042 ui->button_shift_shift->setStyleSheet(
1043 QStringLiteral("background-image: url(:/overlay/osk_button_shift_lock_off.png);"
1044 "\nbackground-position: left top;"
1045 "\nbackground-repeat: no-repeat;"
1046 "\nbackground-origin: content;"));
1047
1048 ui->button_shift_shift->setIconSize(ui->button_shift->iconSize());
1049 ui->button_backspace_shift->setIconSize(ui->button_backspace->iconSize());
1050
1051 ui->label_shift_shift->setText(QStringLiteral("Caps Lock"));
1052
1053 bottom_osk_index = BottomOSKIndex::LowerCase;
1054 ui->bottomOSK->setCurrentIndex(static_cast<int>(bottom_osk_index));
1055 } else {
1056 caps_lock_enabled = true;
1057
1058 ui->button_shift_shift->setStyleSheet(
1059 QStringLiteral("background-image: url(:/overlay/osk_button_shift_lock_on.png);"
1060 "\nbackground-position: left top;"
1061 "\nbackground-repeat: no-repeat;"
1062 "\nbackground-origin: content;"));
1063
1064 ui->button_shift_shift->setIconSize(ui->button_shift->iconSize());
1065 ui->button_backspace_shift->setIconSize(ui->button_backspace->iconSize());
1066
1067 ui->label_shift_shift->setText(QStringLiteral("Caps Lock Off"));
1068 }
1069 break;
1070 case BottomOSKIndex::NumberPad:
1071 default:
1072 break;
1073 }
114} 1074}
115 1075
116std::u16string QtSoftwareKeyboardDialog::GetText() const { 1076void QtSoftwareKeyboardDialog::NormalKeyboardButtonClicked(QPushButton* button) {
117 return text; 1077 if (button == ui->button_ampersand) {
1078 if (ui->topOSK->currentIndex() == 1) {
1079 ui->text_edit_osk->insertPlainText(QStringLiteral("&"));
1080 } else {
1081 ui->line_edit_osk->insert(QStringLiteral("&"));
1082 }
1083 return;
1084 }
1085
1086 if (button == ui->button_return || button == ui->button_return_shift) {
1087 if (ui->topOSK->currentIndex() == 1) {
1088 ui->text_edit_osk->insertPlainText(QStringLiteral("\n"));
1089 } else {
1090 ui->line_edit_osk->insert(QStringLiteral("\n"));
1091 }
1092 return;
1093 }
1094
1095 if (button == ui->button_space || button == ui->button_space_shift) {
1096 if (ui->topOSK->currentIndex() == 1) {
1097 ui->text_edit_osk->insertPlainText(QStringLiteral(" "));
1098 } else {
1099 ui->line_edit_osk->insert(QStringLiteral(" "));
1100 }
1101 return;
1102 }
1103
1104 if (button == ui->button_shift || button == ui->button_shift_shift) {
1105 ChangeBottomOSKIndex();
1106 return;
1107 }
1108
1109 if (button == ui->button_backspace || button == ui->button_backspace_shift ||
1110 button == ui->button_backspace_num) {
1111 if (ui->topOSK->currentIndex() == 1) {
1112 auto text_cursor = ui->text_edit_osk->textCursor();
1113 ui->text_edit_osk->setTextCursor(text_cursor);
1114 text_cursor.deletePreviousChar();
1115 } else {
1116 ui->line_edit_osk->backspace();
1117 }
1118 return;
1119 }
1120
1121 if (button == ui->button_ok || button == ui->button_ok_shift || button == ui->button_ok_num) {
1122 if (ui->topOSK->currentIndex() == 1) {
1123 emit SubmitNormalText(SwkbdResult::Ok,
1124 ui->text_edit_osk->toPlainText().toStdU16String());
1125 } else {
1126 emit SubmitNormalText(SwkbdResult::Ok, ui->line_edit_osk->text().toStdU16String());
1127 }
1128 return;
1129 }
1130
1131 if (ui->topOSK->currentIndex() == 1) {
1132 ui->text_edit_osk->insertPlainText(button->text());
1133 } else {
1134 ui->line_edit_osk->insert(button->text());
1135 }
1136
1137 // Revert the keyboard to lowercase if the shift key is active.
1138 if (bottom_osk_index == BottomOSKIndex::UpperCase && !caps_lock_enabled) {
1139 // This is set to true since ChangeBottomOSKIndex will change bottom_osk_index to LowerCase
1140 // if bottom_osk_index is UpperCase and caps_lock_enabled is true.
1141 caps_lock_enabled = true;
1142 ChangeBottomOSKIndex();
1143 }
1144}
1145
1146void QtSoftwareKeyboardDialog::InlineKeyboardButtonClicked(QPushButton* button) {
1147 if (!button->isEnabled()) {
1148 return;
1149 }
1150
1151 if (button == ui->button_ampersand) {
1152 InlineTextInsertString(u"&");
1153 return;
1154 }
1155
1156 if (button == ui->button_return || button == ui->button_return_shift) {
1157 InlineTextInsertString(u"\n");
1158 return;
1159 }
1160
1161 if (button == ui->button_space || button == ui->button_space_shift) {
1162 InlineTextInsertString(u" ");
1163 return;
1164 }
1165
1166 if (button == ui->button_shift || button == ui->button_shift_shift) {
1167 ChangeBottomOSKIndex();
1168 return;
1169 }
1170
1171 if (button == ui->button_backspace || button == ui->button_backspace_shift ||
1172 button == ui->button_backspace_num) {
1173 if (cursor_position <= 0 || current_text.empty()) {
1174 cursor_position = 0;
1175 return;
1176 }
1177
1178 --cursor_position;
1179
1180 current_text.erase(cursor_position, 1);
1181
1182 SetBackspaceOkEnabled();
1183
1184 emit SubmitInlineText(SwkbdReplyType::ChangedString, current_text, cursor_position);
1185 return;
1186 }
1187
1188 if (button == ui->button_ok || button == ui->button_ok_shift || button == ui->button_ok_num) {
1189 emit SubmitInlineText(SwkbdReplyType::DecidedEnter, current_text, cursor_position);
1190 return;
1191 }
1192
1193 InlineTextInsertString(button->text().toStdU16String());
1194
1195 // Revert the keyboard to lowercase if the shift key is active.
1196 if (bottom_osk_index == BottomOSKIndex::UpperCase && !caps_lock_enabled) {
1197 // This is set to true since ChangeBottomOSKIndex will change bottom_osk_index to LowerCase
1198 // if bottom_osk_index is UpperCase and caps_lock_enabled is true.
1199 caps_lock_enabled = true;
1200 ChangeBottomOSKIndex();
1201 }
1202}
1203
1204void QtSoftwareKeyboardDialog::InlineTextInsertString(std::u16string_view string) {
1205 if ((current_text.size() + string.size()) > initialize_parameters.max_text_length) {
1206 return;
1207 }
1208
1209 current_text.insert(cursor_position, string);
1210
1211 cursor_position += static_cast<s32>(string.size());
1212
1213 SetBackspaceOkEnabled();
1214
1215 emit SubmitInlineText(SwkbdReplyType::ChangedString, current_text, cursor_position);
1216}
1217
1218void QtSoftwareKeyboardDialog::SetupMouseHover() {
1219 // setFocus() has a bug where continuously changing focus will cause the focus UI to
1220 // mysteriously disappear. A workaround we have found is using the mouse to hover over
1221 // the buttons to act in place of the button focus. As a result, we will have to set
1222 // a blank cursor when hovering over all the buttons and set a no focus policy so the
1223 // buttons do not stay in focus in addition to the mouse hover.
1224 for (auto* button : all_buttons) {
1225 button->setCursor(QCursor(Qt::BlankCursor));
1226 button->setFocusPolicy(Qt::NoFocus);
1227 }
1228}
1229
1230template <HIDButton... T>
1231void QtSoftwareKeyboardDialog::HandleButtonPressedOnce() {
1232 const auto f = [this](HIDButton button) {
1233 if (input_interpreter->IsButtonPressedOnce(button)) {
1234 TranslateButtonPress(button);
1235 }
1236 };
1237
1238 (f(T), ...);
1239}
1240
1241template <HIDButton... T>
1242void QtSoftwareKeyboardDialog::HandleButtonHold() {
1243 const auto f = [this](HIDButton button) {
1244 if (input_interpreter->IsButtonHeld(button)) {
1245 TranslateButtonPress(button);
1246 }
1247 };
1248
1249 (f(T), ...);
1250}
1251
1252void QtSoftwareKeyboardDialog::TranslateButtonPress(HIDButton button) {
1253 switch (button) {
1254 case HIDButton::A:
1255 switch (bottom_osk_index) {
1256 case BottomOSKIndex::LowerCase:
1257 case BottomOSKIndex::UpperCase:
1258 keyboard_buttons[static_cast<std::size_t>(bottom_osk_index)][row][column]->click();
1259 break;
1260 case BottomOSKIndex::NumberPad:
1261 numberpad_buttons[row][column]->click();
1262 break;
1263 default:
1264 break;
1265 }
1266 break;
1267 case HIDButton::B:
1268 switch (bottom_osk_index) {
1269 case BottomOSKIndex::LowerCase:
1270 ui->button_backspace->click();
1271 break;
1272 case BottomOSKIndex::UpperCase:
1273 ui->button_backspace_shift->click();
1274 break;
1275 case BottomOSKIndex::NumberPad:
1276 ui->button_backspace_num->click();
1277 break;
1278 default:
1279 break;
1280 }
1281 break;
1282 case HIDButton::X:
1283 if (is_inline) {
1284 emit SubmitInlineText(SwkbdReplyType::DecidedCancel, current_text, cursor_position);
1285 } else {
1286 if (ui->topOSK->currentIndex() == 1) {
1287 emit SubmitNormalText(SwkbdResult::Cancel,
1288 ui->text_edit_osk->toPlainText().toStdU16String());
1289 } else {
1290 emit SubmitNormalText(SwkbdResult::Cancel,
1291 ui->line_edit_osk->text().toStdU16String());
1292 }
1293 }
1294 break;
1295 case HIDButton::Y:
1296 switch (bottom_osk_index) {
1297 case BottomOSKIndex::LowerCase:
1298 ui->button_space->click();
1299 break;
1300 case BottomOSKIndex::UpperCase:
1301 ui->button_space_shift->click();
1302 break;
1303 case BottomOSKIndex::NumberPad:
1304 default:
1305 break;
1306 }
1307 break;
1308 case HIDButton::LStick:
1309 case HIDButton::RStick:
1310 switch (bottom_osk_index) {
1311 case BottomOSKIndex::LowerCase:
1312 ui->button_shift->click();
1313 break;
1314 case BottomOSKIndex::UpperCase:
1315 ui->button_shift_shift->click();
1316 break;
1317 case BottomOSKIndex::NumberPad:
1318 default:
1319 break;
1320 }
1321 break;
1322 case HIDButton::L:
1323 MoveTextCursorDirection(Direction::Left);
1324 break;
1325 case HIDButton::R:
1326 MoveTextCursorDirection(Direction::Right);
1327 break;
1328 case HIDButton::Plus:
1329 switch (bottom_osk_index) {
1330 case BottomOSKIndex::LowerCase:
1331 ui->button_ok->click();
1332 break;
1333 case BottomOSKIndex::UpperCase:
1334 ui->button_ok_shift->click();
1335 break;
1336 case BottomOSKIndex::NumberPad:
1337 ui->button_ok_num->click();
1338 break;
1339 default:
1340 break;
1341 }
1342 break;
1343 case HIDButton::DLeft:
1344 case HIDButton::LStickLeft:
1345 case HIDButton::RStickLeft:
1346 MoveButtonDirection(Direction::Left);
1347 break;
1348 case HIDButton::DUp:
1349 case HIDButton::LStickUp:
1350 case HIDButton::RStickUp:
1351 MoveButtonDirection(Direction::Up);
1352 break;
1353 case HIDButton::DRight:
1354 case HIDButton::LStickRight:
1355 case HIDButton::RStickRight:
1356 MoveButtonDirection(Direction::Right);
1357 break;
1358 case HIDButton::DDown:
1359 case HIDButton::LStickDown:
1360 case HIDButton::RStickDown:
1361 MoveButtonDirection(Direction::Down);
1362 break;
1363 default:
1364 break;
1365 }
1366}
1367
1368void QtSoftwareKeyboardDialog::MoveButtonDirection(Direction direction) {
1369 // Changes the row or column index depending on the direction.
1370 auto move_direction = [this, direction](std::size_t max_rows, std::size_t max_columns) {
1371 switch (direction) {
1372 case Direction::Left:
1373 column = (column + max_columns - 1) % max_columns;
1374 break;
1375 case Direction::Up:
1376 row = (row + max_rows - 1) % max_rows;
1377 break;
1378 case Direction::Right:
1379 column = (column + 1) % max_columns;
1380 break;
1381 case Direction::Down:
1382 row = (row + 1) % max_rows;
1383 break;
1384 default:
1385 break;
1386 }
1387 };
1388
1389 switch (bottom_osk_index) {
1390 case BottomOSKIndex::LowerCase:
1391 case BottomOSKIndex::UpperCase: {
1392 const auto index = static_cast<std::size_t>(bottom_osk_index);
1393
1394 const auto* const prev_button = keyboard_buttons[index][row][column];
1395 move_direction(NUM_ROWS_NORMAL, NUM_COLUMNS_NORMAL);
1396 auto* curr_button = keyboard_buttons[index][row][column];
1397
1398 while (!curr_button || !curr_button->isEnabled() || curr_button == prev_button) {
1399 move_direction(NUM_ROWS_NORMAL, NUM_COLUMNS_NORMAL);
1400 curr_button = keyboard_buttons[index][row][column];
1401 }
1402
1403 // This is a workaround for setFocus() randomly not showing focus in the UI
1404 QCursor::setPos(curr_button->mapToGlobal(curr_button->rect().center()));
1405 break;
1406 }
1407 case BottomOSKIndex::NumberPad: {
1408 const auto* const prev_button = numberpad_buttons[row][column];
1409 move_direction(NUM_ROWS_NUMPAD, NUM_COLUMNS_NUMPAD);
1410 auto* curr_button = numberpad_buttons[row][column];
1411
1412 while (!curr_button || !curr_button->isEnabled() || curr_button == prev_button) {
1413 move_direction(NUM_ROWS_NUMPAD, NUM_COLUMNS_NUMPAD);
1414 curr_button = numberpad_buttons[row][column];
1415 }
1416
1417 // This is a workaround for setFocus() randomly not showing focus in the UI
1418 QCursor::setPos(curr_button->mapToGlobal(curr_button->rect().center()));
1419 break;
1420 }
1421 default:
1422 break;
1423 }
1424}
1425
1426void QtSoftwareKeyboardDialog::MoveTextCursorDirection(Direction direction) {
1427 switch (direction) {
1428 case Direction::Left:
1429 if (is_inline) {
1430 if (cursor_position <= 0) {
1431 cursor_position = 0;
1432 } else {
1433 --cursor_position;
1434 emit SubmitInlineText(SwkbdReplyType::MovedCursor, current_text, cursor_position);
1435 }
1436 } else {
1437 if (ui->topOSK->currentIndex() == 1) {
1438 ui->text_edit_osk->moveCursor(QTextCursor::Left);
1439 } else {
1440 ui->line_edit_osk->setCursorPosition(ui->line_edit_osk->cursorPosition() - 1);
1441 }
1442 }
1443 break;
1444 case Direction::Right:
1445 if (is_inline) {
1446 if (cursor_position >= static_cast<s32>(current_text.size())) {
1447 cursor_position = static_cast<s32>(current_text.size());
1448 } else {
1449 ++cursor_position;
1450 emit SubmitInlineText(SwkbdReplyType::MovedCursor, current_text, cursor_position);
1451 }
1452 } else {
1453 if (ui->topOSK->currentIndex() == 1) {
1454 ui->text_edit_osk->moveCursor(QTextCursor::Right);
1455 } else {
1456 ui->line_edit_osk->setCursorPosition(ui->line_edit_osk->cursorPosition() + 1);
1457 }
1458 }
1459 break;
1460 default:
1461 break;
1462 }
1463}
1464
1465void QtSoftwareKeyboardDialog::StartInputThread() {
1466 if (input_thread_running) {
1467 return;
1468 }
1469
1470 input_thread_running = true;
1471
1472 input_thread = std::thread(&QtSoftwareKeyboardDialog::InputThread, this);
1473}
1474
1475void QtSoftwareKeyboardDialog::StopInputThread() {
1476 input_thread_running = false;
1477
1478 if (input_thread.joinable()) {
1479 input_thread.join();
1480 }
1481
1482 if (input_interpreter) {
1483 input_interpreter->ResetButtonStates();
1484 }
1485}
1486
1487void QtSoftwareKeyboardDialog::InputThread() {
1488 while (input_thread_running) {
1489 input_interpreter->PollInput();
1490
1491 HandleButtonPressedOnce<HIDButton::A, HIDButton::B, HIDButton::X, HIDButton::Y,
1492 HIDButton::LStick, HIDButton::RStick, HIDButton::L, HIDButton::R,
1493 HIDButton::Plus, HIDButton::DLeft, HIDButton::DUp,
1494 HIDButton::DRight, HIDButton::DDown, HIDButton::LStickLeft,
1495 HIDButton::LStickUp, HIDButton::LStickRight, HIDButton::LStickDown,
1496 HIDButton::RStickLeft, HIDButton::RStickUp, HIDButton::RStickRight,
1497 HIDButton::RStickDown>();
1498
1499 HandleButtonHold<HIDButton::B, HIDButton::L, HIDButton::R, HIDButton::DLeft, HIDButton::DUp,
1500 HIDButton::DRight, HIDButton::DDown, HIDButton::LStickLeft,
1501 HIDButton::LStickUp, HIDButton::LStickRight, HIDButton::LStickDown,
1502 HIDButton::RStickLeft, HIDButton::RStickUp, HIDButton::RStickRight,
1503 HIDButton::RStickDown>();
1504
1505 std::this_thread::sleep_for(std::chrono::milliseconds(50));
1506 }
118} 1507}
119 1508
120QtSoftwareKeyboard::QtSoftwareKeyboard(GMainWindow& main_window) { 1509QtSoftwareKeyboard::QtSoftwareKeyboard(GMainWindow& main_window) {
121 connect(this, &QtSoftwareKeyboard::MainWindowGetText, &main_window, 1510 connect(this, &QtSoftwareKeyboard::MainWindowInitializeKeyboard, &main_window,
122 &GMainWindow::SoftwareKeyboardGetText, Qt::QueuedConnection); 1511 &GMainWindow::SoftwareKeyboardInitialize, Qt::QueuedConnection);
123 connect(this, &QtSoftwareKeyboard::MainWindowTextCheckDialog, &main_window, 1512 connect(this, &QtSoftwareKeyboard::MainWindowShowNormalKeyboard, &main_window,
124 &GMainWindow::SoftwareKeyboardInvokeCheckDialog, Qt::BlockingQueuedConnection); 1513 &GMainWindow::SoftwareKeyboardShowNormal, Qt::QueuedConnection);
125 connect(&main_window, &GMainWindow::SoftwareKeyboardFinishedText, this, 1514 connect(this, &QtSoftwareKeyboard::MainWindowShowTextCheckDialog, &main_window,
126 &QtSoftwareKeyboard::MainWindowFinishedText, Qt::QueuedConnection); 1515 &GMainWindow::SoftwareKeyboardShowTextCheck, Qt::QueuedConnection);
1516 connect(this, &QtSoftwareKeyboard::MainWindowShowInlineKeyboard, &main_window,
1517 &GMainWindow::SoftwareKeyboardShowInline, Qt::QueuedConnection);
1518 connect(this, &QtSoftwareKeyboard::MainWindowHideInlineKeyboard, &main_window,
1519 &GMainWindow::SoftwareKeyboardHideInline, Qt::QueuedConnection);
1520 connect(this, &QtSoftwareKeyboard::MainWindowInlineTextChanged, &main_window,
1521 &GMainWindow::SoftwareKeyboardInlineTextChanged, Qt::QueuedConnection);
1522 connect(this, &QtSoftwareKeyboard::MainWindowExitKeyboard, &main_window,
1523 &GMainWindow::SoftwareKeyboardExit, Qt::QueuedConnection);
1524 connect(&main_window, &GMainWindow::SoftwareKeyboardSubmitNormalText, this,
1525 &QtSoftwareKeyboard::SubmitNormalText, Qt::QueuedConnection);
1526 connect(&main_window, &GMainWindow::SoftwareKeyboardSubmitInlineText, this,
1527 &QtSoftwareKeyboard::SubmitInlineText, Qt::QueuedConnection);
127} 1528}
128 1529
129QtSoftwareKeyboard::~QtSoftwareKeyboard() = default; 1530QtSoftwareKeyboard::~QtSoftwareKeyboard() = default;
130 1531
131void QtSoftwareKeyboard::RequestText(std::function<void(std::optional<std::u16string>)> out, 1532void QtSoftwareKeyboard::InitializeKeyboard(
132 Core::Frontend::SoftwareKeyboardParameters parameters) const { 1533 bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters,
133 text_output = std::move(out); 1534 std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)> submit_normal_callback_,
134 emit MainWindowGetText(parameters); 1535 std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
1536 submit_inline_callback_) {
1537 if (is_inline) {
1538 submit_inline_callback = std::move(submit_inline_callback_);
1539 } else {
1540 submit_normal_callback = std::move(submit_normal_callback_);
1541 }
1542
1543 LOG_INFO(Service_AM,
1544 "\nKeyboardInitializeParameters:"
1545 "\nok_text={}"
1546 "\nheader_text={}"
1547 "\nsub_text={}"
1548 "\nguide_text={}"
1549 "\ninitial_text={}"
1550 "\nmax_text_length={}"
1551 "\nmin_text_length={}"
1552 "\ninitial_cursor_position={}"
1553 "\ntype={}"
1554 "\npassword_mode={}"
1555 "\ntext_draw_type={}"
1556 "\nkey_disable_flags={}"
1557 "\nuse_blur_background={}"
1558 "\nenable_backspace_button={}"
1559 "\nenable_return_button={}"
1560 "\ndisable_cancel_button={}",
1561 Common::UTF16ToUTF8(initialize_parameters.ok_text),
1562 Common::UTF16ToUTF8(initialize_parameters.header_text),
1563 Common::UTF16ToUTF8(initialize_parameters.sub_text),
1564 Common::UTF16ToUTF8(initialize_parameters.guide_text),
1565 Common::UTF16ToUTF8(initialize_parameters.initial_text),
1566 initialize_parameters.max_text_length, initialize_parameters.min_text_length,
1567 initialize_parameters.initial_cursor_position, initialize_parameters.type,
1568 initialize_parameters.password_mode, initialize_parameters.text_draw_type,
1569 initialize_parameters.key_disable_flags.raw, initialize_parameters.use_blur_background,
1570 initialize_parameters.enable_backspace_button,
1571 initialize_parameters.enable_return_button,
1572 initialize_parameters.disable_cancel_button);
1573
1574 emit MainWindowInitializeKeyboard(is_inline, std::move(initialize_parameters));
1575}
1576
1577void QtSoftwareKeyboard::ShowNormalKeyboard() const {
1578 emit MainWindowShowNormalKeyboard();
1579}
1580
1581void QtSoftwareKeyboard::ShowTextCheckDialog(
1582 Service::AM::Applets::SwkbdTextCheckResult text_check_result,
1583 std::u16string text_check_message) const {
1584 emit MainWindowShowTextCheckDialog(text_check_result, text_check_message);
1585}
1586
1587void QtSoftwareKeyboard::ShowInlineKeyboard(
1588 Core::Frontend::InlineAppearParameters appear_parameters) const {
1589 LOG_INFO(Service_AM,
1590 "\nInlineAppearParameters:"
1591 "\nmax_text_length={}"
1592 "\nmin_text_length={}"
1593 "\nkey_top_scale_x={}"
1594 "\nkey_top_scale_y={}"
1595 "\nkey_top_translate_x={}"
1596 "\nkey_top_translate_y={}"
1597 "\ntype={}"
1598 "\nkey_disable_flags={}"
1599 "\nkey_top_as_floating={}"
1600 "\nenable_backspace_button={}"
1601 "\nenable_return_button={}"
1602 "\ndisable_cancel_button={}",
1603 appear_parameters.max_text_length, appear_parameters.min_text_length,
1604 appear_parameters.key_top_scale_x, appear_parameters.key_top_scale_y,
1605 appear_parameters.key_top_translate_x, appear_parameters.key_top_translate_y,
1606 appear_parameters.type, appear_parameters.key_disable_flags.raw,
1607 appear_parameters.key_top_as_floating, appear_parameters.enable_backspace_button,
1608 appear_parameters.enable_return_button, appear_parameters.disable_cancel_button);
1609
1610 emit MainWindowShowInlineKeyboard(std::move(appear_parameters));
1611}
1612
1613void QtSoftwareKeyboard::HideInlineKeyboard() const {
1614 emit MainWindowHideInlineKeyboard();
1615}
1616
1617void QtSoftwareKeyboard::InlineTextChanged(
1618 Core::Frontend::InlineTextParameters text_parameters) const {
1619 LOG_INFO(Service_AM,
1620 "\nInlineTextParameters:"
1621 "\ninput_text={}"
1622 "\ncursor_position={}",
1623 Common::UTF16ToUTF8(text_parameters.input_text), text_parameters.cursor_position);
1624
1625 emit MainWindowInlineTextChanged(std::move(text_parameters));
135} 1626}
136 1627
137void QtSoftwareKeyboard::SendTextCheckDialog(std::u16string error_message, 1628void QtSoftwareKeyboard::ExitKeyboard() const {
138 std::function<void()> finished_check_) const { 1629 emit MainWindowExitKeyboard();
139 finished_check = std::move(finished_check_);
140 emit MainWindowTextCheckDialog(error_message);
141} 1630}
142 1631
143void QtSoftwareKeyboard::MainWindowFinishedText(std::optional<std::u16string> text) { 1632void QtSoftwareKeyboard::SubmitNormalText(Service::AM::Applets::SwkbdResult result,
144 // Acquire the HLE mutex 1633 std::u16string submitted_text) const {
145 std::lock_guard lock{HLE::g_hle_lock}; 1634 submit_normal_callback(result, submitted_text);
146 text_output(std::move(text));
147} 1635}
148 1636
149void QtSoftwareKeyboard::MainWindowFinishedCheckDialog() { 1637void QtSoftwareKeyboard::SubmitInlineText(Service::AM::Applets::SwkbdReplyType reply_type,
150 // Acquire the HLE mutex 1638 std::u16string submitted_text,
151 std::lock_guard lock{HLE::g_hle_lock}; 1639 s32 cursor_position) const {
152 finished_check(); 1640 submit_inline_callback(reply_type, submitted_text, cursor_position);
153} 1641}
diff --git a/src/yuzu/applets/software_keyboard.h b/src/yuzu/applets/software_keyboard.h
index 9e1094cce..1a03c098c 100644
--- a/src/yuzu/applets/software_keyboard.h
+++ b/src/yuzu/applets/software_keyboard.h
@@ -1,54 +1,228 @@
1// Copyright 2018 yuzu Emulator Project 1// Copyright 2021 yuzu Emulator Project
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#pragma once 5#pragma once
6 6
7#include <array>
8#include <atomic>
9#include <memory>
10#include <thread>
11
7#include <QDialog> 12#include <QDialog>
8#include <QValidator> 13#include <QValidator>
14
9#include "core/frontend/applets/software_keyboard.h" 15#include "core/frontend/applets/software_keyboard.h"
10 16
11class GMainWindow; 17enum class HIDButton : u8;
12class QDialogButtonBox;
13class QLabel;
14class QLineEdit;
15class QVBoxLayout;
16class QtSoftwareKeyboard;
17 18
18class QtSoftwareKeyboardValidator final : public QValidator { 19class InputInterpreter;
19public:
20 explicit QtSoftwareKeyboardValidator(Core::Frontend::SoftwareKeyboardParameters parameters);
21 State validate(QString& input, int& pos) const override;
22 20
23private: 21namespace Core {
24 Core::Frontend::SoftwareKeyboardParameters parameters; 22class System;
25}; 23}
24
25namespace Ui {
26class QtSoftwareKeyboardDialog;
27}
28
29class GMainWindow;
26 30
27class QtSoftwareKeyboardDialog final : public QDialog { 31class QtSoftwareKeyboardDialog final : public QDialog {
28 Q_OBJECT 32 Q_OBJECT
29 33
30public: 34public:
31 QtSoftwareKeyboardDialog(QWidget* parent, 35 QtSoftwareKeyboardDialog(QWidget* parent, Core::System& system_, bool is_inline_,
32 Core::Frontend::SoftwareKeyboardParameters parameters); 36 Core::Frontend::KeyboardInitializeParameters initialize_parameters_);
33 ~QtSoftwareKeyboardDialog() override; 37 ~QtSoftwareKeyboardDialog() override;
34 38
35 void accept() override; 39 void ShowNormalKeyboard(QPoint pos, QSize size);
40
41 void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
42 std::u16string text_check_message);
43
44 void ShowInlineKeyboard(Core::Frontend::InlineAppearParameters appear_parameters, QPoint pos,
45 QSize size);
46
47 void HideInlineKeyboard();
48
49 void InlineTextChanged(Core::Frontend::InlineTextParameters text_parameters);
50
51 void ExitKeyboard();
52
53signals:
54 void SubmitNormalText(Service::AM::Applets::SwkbdResult result,
55 std::u16string submitted_text) const;
56
57 void SubmitInlineText(Service::AM::Applets::SwkbdReplyType reply_type,
58 std::u16string submitted_text, s32 cursor_position) const;
59
60public slots:
61 void open() override;
36 void reject() override; 62 void reject() override;
37 63
38 std::u16string GetText() const; 64protected:
65 /// We override the keyPressEvent for inputting text into the inline software keyboard.
66 void keyPressEvent(QKeyEvent* event) override;
39 67
40private: 68private:
41 std::u16string text; 69 enum class Direction {
70 Left,
71 Up,
72 Right,
73 Down,
74 };
75
76 enum class BottomOSKIndex {
77 LowerCase,
78 UpperCase,
79 NumberPad,
80 };
81
82 /**
83 * Moves and resizes the window to a specified position and size.
84 *
85 * @param pos Top-left window position
86 * @param size Window size
87 */
88 void MoveAndResizeWindow(QPoint pos, QSize size);
89
90 /**
91 * Rescales all keyboard elements to account for High DPI displays.
92 *
93 * @param width Window width
94 * @param height Window height
95 * @param dpi_scale Display scaling factor
96 */
97 void RescaleKeyboardElements(float width, float height, float dpi_scale);
98
99 /// Sets the keyboard type based on initialize_parameters.
100 void SetKeyboardType();
101
102 /// Sets the password mode based on initialize_parameters.
103 void SetPasswordMode();
104
105 /// Sets the text draw type based on initialize_parameters.
106 void SetTextDrawType();
107
108 /// Sets the controller image at the bottom left of the software keyboard.
109 void SetControllerImage();
110
111 /// Disables buttons based on initialize_parameters.
112 void DisableKeyboardButtons();
113
114 /// Changes whether the backspace or/and ok buttons should be enabled or disabled.
115 void SetBackspaceOkEnabled();
116
117 /**
118 * Validates the input text sent in based on the parameters in initialize_parameters.
119 *
120 * @param input_text Input text
121 *
122 * @returns True if the input text is valid, false otherwise.
123 */
124 bool ValidateInputText(const QString& input_text);
125
126 /// Switches between LowerCase and UpperCase (Shift and Caps Lock)
127 void ChangeBottomOSKIndex();
128
129 /// Processes a keyboard button click from the UI as normal keyboard input.
130 void NormalKeyboardButtonClicked(QPushButton* button);
131
132 /// Processes a keyboard button click from the UI as inline keyboard input.
133 void InlineKeyboardButtonClicked(QPushButton* button);
134
135 /**
136 * Inserts a string of arbitrary length into the current_text at the current cursor position.
137 * This is only used for the inline software keyboard.
138 */
139 void InlineTextInsertString(std::u16string_view string);
42 140
43 QDialogButtonBox* buttons; 141 /// Setup the mouse hover workaround for "focusing" buttons. This should only be called once.
44 QLabel* header_label; 142 void SetupMouseHover();
45 QLabel* sub_label;
46 QLabel* guide_label;
47 QLabel* length_label;
48 QLineEdit* line_edit;
49 QVBoxLayout* layout;
50 143
51 Core::Frontend::SoftwareKeyboardParameters parameters; 144 /**
145 * Handles button presses and converts them into keyboard input.
146 *
147 * @tparam HIDButton The list of buttons that can be converted into keyboard input.
148 */
149 template <HIDButton... T>
150 void HandleButtonPressedOnce();
151
152 /**
153 * Handles button holds and converts them into keyboard input.
154 *
155 * @tparam HIDButton The list of buttons that can be converted into keyboard input.
156 */
157 template <HIDButton... T>
158 void HandleButtonHold();
159
160 /**
161 * Translates a button press to focus or click a keyboard button.
162 *
163 * @param button The button press to process.
164 */
165 void TranslateButtonPress(HIDButton button);
166
167 /**
168 * Moves the focus of a button in a certain direction.
169 *
170 * @param direction The direction to move.
171 */
172 void MoveButtonDirection(Direction direction);
173
174 /**
175 * Moves the text cursor in a certain direction.
176 *
177 * @param direction The direction to move.
178 */
179 void MoveTextCursorDirection(Direction direction);
180
181 void StartInputThread();
182 void StopInputThread();
183
184 /// The thread where input is being polled and processed.
185 void InputThread();
186
187 std::unique_ptr<Ui::QtSoftwareKeyboardDialog> ui;
188
189 Core::System& system;
190
191 // True if it is the inline software keyboard.
192 bool is_inline;
193
194 // Common software keyboard initialize parameters.
195 Core::Frontend::KeyboardInitializeParameters initialize_parameters;
196
197 // Used only by the inline software keyboard since the QLineEdit or QTextEdit is hidden.
198 std::u16string current_text;
199 s32 cursor_position{0};
200
201 static constexpr std::size_t NUM_ROWS_NORMAL = 5;
202 static constexpr std::size_t NUM_COLUMNS_NORMAL = 12;
203 static constexpr std::size_t NUM_ROWS_NUMPAD = 4;
204 static constexpr std::size_t NUM_COLUMNS_NUMPAD = 4;
205
206 // Stores the normal keyboard layout.
207 std::array<std::array<std::array<QPushButton*, NUM_COLUMNS_NORMAL>, NUM_ROWS_NORMAL>, 2>
208 keyboard_buttons;
209 // Stores the numberpad keyboard layout.
210 std::array<std::array<QPushButton*, NUM_COLUMNS_NUMPAD>, NUM_ROWS_NUMPAD> numberpad_buttons;
211
212 // Contains a set of all buttons used in keyboard_buttons and numberpad_buttons.
213 std::array<QPushButton*, 110> all_buttons;
214
215 std::size_t row{0};
216 std::size_t column{0};
217
218 BottomOSKIndex bottom_osk_index{BottomOSKIndex::LowerCase};
219 std::atomic<bool> caps_lock_enabled{false};
220
221 std::unique_ptr<InputInterpreter> input_interpreter;
222
223 std::thread input_thread;
224
225 std::atomic<bool> input_thread_running{};
52}; 226};
53 227
54class QtSoftwareKeyboard final : public QObject, public Core::Frontend::SoftwareKeyboardApplet { 228class QtSoftwareKeyboard final : public QObject, public Core::Frontend::SoftwareKeyboardApplet {
@@ -58,19 +232,54 @@ public:
58 explicit QtSoftwareKeyboard(GMainWindow& parent); 232 explicit QtSoftwareKeyboard(GMainWindow& parent);
59 ~QtSoftwareKeyboard() override; 233 ~QtSoftwareKeyboard() override;
60 234
61 void RequestText(std::function<void(std::optional<std::u16string>)> out, 235 void InitializeKeyboard(
62 Core::Frontend::SoftwareKeyboardParameters parameters) const override; 236 bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters,
63 void SendTextCheckDialog(std::u16string error_message, 237 std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
64 std::function<void()> finished_check_) const override; 238 submit_normal_callback_,
239 std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
240 submit_inline_callback_) override;
241
242 void ShowNormalKeyboard() const override;
243
244 void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
245 std::u16string text_check_message) const override;
246
247 void ShowInlineKeyboard(
248 Core::Frontend::InlineAppearParameters appear_parameters) const override;
249
250 void HideInlineKeyboard() const override;
251
252 void InlineTextChanged(Core::Frontend::InlineTextParameters text_parameters) const override;
253
254 void ExitKeyboard() const override;
65 255
66signals: 256signals:
67 void MainWindowGetText(Core::Frontend::SoftwareKeyboardParameters parameters) const; 257 void MainWindowInitializeKeyboard(
68 void MainWindowTextCheckDialog(std::u16string error_message) const; 258 bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters) const;
259
260 void MainWindowShowNormalKeyboard() const;
261
262 void MainWindowShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
263 std::u16string text_check_message) const;
264
265 void MainWindowShowInlineKeyboard(
266 Core::Frontend::InlineAppearParameters appear_parameters) const;
267
268 void MainWindowHideInlineKeyboard() const;
269
270 void MainWindowInlineTextChanged(Core::Frontend::InlineTextParameters text_parameters) const;
271
272 void MainWindowExitKeyboard() const;
69 273
70private: 274private:
71 void MainWindowFinishedText(std::optional<std::u16string> text); 275 void SubmitNormalText(Service::AM::Applets::SwkbdResult result,
72 void MainWindowFinishedCheckDialog(); 276 std::u16string submitted_text) const;
277
278 void SubmitInlineText(Service::AM::Applets::SwkbdReplyType reply_type,
279 std::u16string submitted_text, s32 cursor_position) const;
73 280
74 mutable std::function<void(std::optional<std::u16string>)> text_output; 281 mutable std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
75 mutable std::function<void()> finished_check; 282 submit_normal_callback;
283 mutable std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
284 submit_inline_callback;
76}; 285};
diff --git a/src/yuzu/applets/software_keyboard.ui b/src/yuzu/applets/software_keyboard.ui
new file mode 100644
index 000000000..b0a1fcde9
--- /dev/null
+++ b/src/yuzu/applets/software_keyboard.ui
@@ -0,0 +1,3503 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>QtSoftwareKeyboardDialog</class>
4 <widget class="QDialog" name="QtSoftwareKeyboardDialog">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>1280</width>
10 <height>720</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Software Keyboard</string>
15 </property>
16 <property name="styleSheet">
17 <string notr="true"/>
18 </property>
19 <layout class="QVBoxLayout" name="verticalLayout">
20 <property name="spacing">
21 <number>0</number>
22 </property>
23 <property name="leftMargin">
24 <number>0</number>
25 </property>
26 <property name="topMargin">
27 <number>0</number>
28 </property>
29 <property name="rightMargin">
30 <number>0</number>
31 </property>
32 <property name="bottomMargin">
33 <number>0</number>
34 </property>
35 <item>
36 <widget class="QWidget" name="mainOSK" native="true">
37 <layout class="QVBoxLayout" name="verticalLayout_2" stretch="320,400">
38 <property name="spacing">
39 <number>0</number>
40 </property>
41 <property name="leftMargin">
42 <number>0</number>
43 </property>
44 <property name="topMargin">
45 <number>0</number>
46 </property>
47 <property name="rightMargin">
48 <number>0</number>
49 </property>
50 <property name="bottomMargin">
51 <number>0</number>
52 </property>
53 <item>
54 <widget class="QStackedWidget" name="topOSK">
55 <property name="currentIndex">
56 <number>0</number>
57 </property>
58 <widget class="QWidget" name="lineOSK">
59 <property name="minimumSize">
60 <size>
61 <width>0</width>
62 <height>100</height>
63 </size>
64 </property>
65 <layout class="QVBoxLayout" name="lineOSKVerticalLayout">
66 <property name="spacing">
67 <number>0</number>
68 </property>
69 <property name="leftMargin">
70 <number>0</number>
71 </property>
72 <property name="topMargin">
73 <number>0</number>
74 </property>
75 <property name="rightMargin">
76 <number>0</number>
77 </property>
78 <property name="bottomMargin">
79 <number>0</number>
80 </property>
81 <item>
82 <layout class="QGridLayout" name="gridLineOSK" rowstretch="40,50,23,48,65,94" columnstretch="130,1020,130">
83 <property name="topMargin">
84 <number>0</number>
85 </property>
86 <property name="spacing">
87 <number>0</number>
88 </property>
89 <item row="4" column="2">
90 <spacer name="horizontalSpacer_3">
91 <property name="orientation">
92 <enum>Qt::Horizontal</enum>
93 </property>
94 <property name="sizeHint" stdset="0">
95 <size>
96 <width>40</width>
97 <height>20</height>
98 </size>
99 </property>
100 </spacer>
101 </item>
102 <item row="4" column="0">
103 <spacer name="horizontalSpacer_4">
104 <property name="orientation">
105 <enum>Qt::Horizontal</enum>
106 </property>
107 <property name="sizeHint" stdset="0">
108 <size>
109 <width>40</width>
110 <height>20</height>
111 </size>
112 </property>
113 </spacer>
114 </item>
115 <item row="5" column="1">
116 <widget class="QWidget" name="charactersOSK" native="true">
117 <layout class="QVBoxLayout" name="verticalLayout_5">
118 <property name="spacing">
119 <number>0</number>
120 </property>
121 <property name="leftMargin">
122 <number>0</number>
123 </property>
124 <property name="topMargin">
125 <number>0</number>
126 </property>
127 <property name="rightMargin">
128 <number>0</number>
129 </property>
130 <property name="bottomMargin">
131 <number>0</number>
132 </property>
133 <item alignment="Qt::AlignRight|Qt::AlignTop">
134 <widget class="QLabel" name="label_characters">
135 <property name="font">
136 <font>
137 <pointsize>17</pointsize>
138 </font>
139 </property>
140 <property name="text">
141 <string notr="true">0/32</string>
142 </property>
143 <property name="alignment">
144 <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
145 </property>
146 </widget>
147 </item>
148 </layout>
149 </widget>
150 </item>
151 <item row="3" column="1">
152 <spacer name="verticalSpacer_2">
153 <property name="orientation">
154 <enum>Qt::Vertical</enum>
155 </property>
156 <property name="sizeHint" stdset="0">
157 <size>
158 <width>20</width>
159 <height>40</height>
160 </size>
161 </property>
162 </spacer>
163 </item>
164 <item row="5" column="0">
165 <spacer name="verticalSpacer_3">
166 <property name="orientation">
167 <enum>Qt::Vertical</enum>
168 </property>
169 <property name="sizeHint" stdset="0">
170 <size>
171 <width>20</width>
172 <height>40</height>
173 </size>
174 </property>
175 </spacer>
176 </item>
177 <item row="4" column="1">
178 <widget class="QWidget" name="inputOSK" native="true">
179 <layout class="QVBoxLayout" name="verticalLayout_3">
180 <item>
181 <widget class="QLineEdit" name="line_edit_osk">
182 <property name="font">
183 <font>
184 <pointsize>26</pointsize>
185 <weight>50</weight>
186 <bold>false</bold>
187 </font>
188 </property>
189 <property name="focusPolicy">
190 <enum>Qt::StrongFocus</enum>
191 </property>
192 <property name="text">
193 <string/>
194 </property>
195 <property name="maxLength">
196 <number>32</number>
197 </property>
198 <property name="placeholderText">
199 <string>Enter Text</string>
200 </property>
201 </widget>
202 </item>
203 </layout>
204 </widget>
205 </item>
206 <item row="0" column="1">
207 <spacer name="verticalSpacer_4">
208 <property name="orientation">
209 <enum>Qt::Vertical</enum>
210 </property>
211 <property name="sizeHint" stdset="0">
212 <size>
213 <width>20</width>
214 <height>40</height>
215 </size>
216 </property>
217 </spacer>
218 </item>
219 <item row="1" column="0" colspan="3">
220 <widget class="QWidget" name="headerOSK" native="true">
221 <layout class="QHBoxLayout" name="horizontalLayout_4" stretch="130,1020,130">
222 <property name="spacing">
223 <number>0</number>
224 </property>
225 <property name="leftMargin">
226 <number>0</number>
227 </property>
228 <property name="topMargin">
229 <number>0</number>
230 </property>
231 <property name="rightMargin">
232 <number>0</number>
233 </property>
234 <property name="bottomMargin">
235 <number>0</number>
236 </property>
237 <item>
238 <spacer name="horizontalSpacer_18">
239 <property name="orientation">
240 <enum>Qt::Horizontal</enum>
241 </property>
242 <property name="sizeHint" stdset="0">
243 <size>
244 <width>127</width>
245 <height>20</height>
246 </size>
247 </property>
248 </spacer>
249 </item>
250 <item>
251 <widget class="QLabel" name="label_header">
252 <property name="font">
253 <font>
254 <pointsize>23</pointsize>
255 </font>
256 </property>
257 <property name="text">
258 <string/>
259 </property>
260 </widget>
261 </item>
262 <item>
263 <spacer name="horizontalSpacer_19">
264 <property name="orientation">
265 <enum>Qt::Horizontal</enum>
266 </property>
267 <property name="sizeHint" stdset="0">
268 <size>
269 <width>127</width>
270 <height>20</height>
271 </size>
272 </property>
273 </spacer>
274 </item>
275 </layout>
276 </widget>
277 </item>
278 <item row="2" column="0" colspan="3">
279 <widget class="QWidget" name="subOSK" native="true">
280 <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="130,1020,130">
281 <property name="spacing">
282 <number>0</number>
283 </property>
284 <property name="leftMargin">
285 <number>0</number>
286 </property>
287 <property name="topMargin">
288 <number>0</number>
289 </property>
290 <property name="rightMargin">
291 <number>0</number>
292 </property>
293 <property name="bottomMargin">
294 <number>0</number>
295 </property>
296 <item>
297 <spacer name="horizontalSpacer_16">
298 <property name="orientation">
299 <enum>Qt::Horizontal</enum>
300 </property>
301 <property name="sizeHint" stdset="0">
302 <size>
303 <width>127</width>
304 <height>20</height>
305 </size>
306 </property>
307 </spacer>
308 </item>
309 <item>
310 <widget class="QLabel" name="label_sub">
311 <property name="font">
312 <font>
313 <pointsize>17</pointsize>
314 </font>
315 </property>
316 <property name="text">
317 <string/>
318 </property>
319 </widget>
320 </item>
321 <item>
322 <spacer name="horizontalSpacer_17">
323 <property name="orientation">
324 <enum>Qt::Horizontal</enum>
325 </property>
326 <property name="sizeHint" stdset="0">
327 <size>
328 <width>127</width>
329 <height>20</height>
330 </size>
331 </property>
332 </spacer>
333 </item>
334 </layout>
335 </widget>
336 </item>
337 </layout>
338 </item>
339 </layout>
340 </widget>
341 <widget class="QWidget" name="boxOSK">
342 <layout class="QVBoxLayout" name="boxOSKVerticalLayout">
343 <property name="spacing">
344 <number>0</number>
345 </property>
346 <property name="leftMargin">
347 <number>0</number>
348 </property>
349 <property name="topMargin">
350 <number>0</number>
351 </property>
352 <property name="rightMargin">
353 <number>0</number>
354 </property>
355 <property name="bottomMargin">
356 <number>0</number>
357 </property>
358 <item>
359 <layout class="QGridLayout" name="gridBoxOSK" rowstretch="61,178,81" columnstretch="120,1040,120">
360 <property name="leftMargin">
361 <number>0</number>
362 </property>
363 <property name="topMargin">
364 <number>0</number>
365 </property>
366 <property name="rightMargin">
367 <number>0</number>
368 </property>
369 <property name="bottomMargin">
370 <number>0</number>
371 </property>
372 <property name="spacing">
373 <number>0</number>
374 </property>
375 <item row="0" column="1">
376 <spacer name="verticalSpacer_5">
377 <property name="orientation">
378 <enum>Qt::Vertical</enum>
379 </property>
380 <property name="sizeHint" stdset="0">
381 <size>
382 <width>20</width>
383 <height>40</height>
384 </size>
385 </property>
386 </spacer>
387 </item>
388 <item row="1" column="0">
389 <spacer name="horizontalSpacer_20">
390 <property name="orientation">
391 <enum>Qt::Horizontal</enum>
392 </property>
393 <property name="sizeHint" stdset="0">
394 <size>
395 <width>40</width>
396 <height>20</height>
397 </size>
398 </property>
399 </spacer>
400 </item>
401 <item row="1" column="2">
402 <spacer name="horizontalSpacer_21">
403 <property name="orientation">
404 <enum>Qt::Horizontal</enum>
405 </property>
406 <property name="sizeHint" stdset="0">
407 <size>
408 <width>40</width>
409 <height>20</height>
410 </size>
411 </property>
412 </spacer>
413 </item>
414 <item row="2" column="1" alignment="Qt::AlignRight|Qt::AlignTop">
415 <widget class="QWidget" name="charactersBoxOSK" native="true">
416 <layout class="QVBoxLayout" name="verticalLayout_4">
417 <property name="spacing">
418 <number>0</number>
419 </property>
420 <property name="leftMargin">
421 <number>0</number>
422 </property>
423 <property name="topMargin">
424 <number>0</number>
425 </property>
426 <property name="rightMargin">
427 <number>0</number>
428 </property>
429 <property name="bottomMargin">
430 <number>0</number>
431 </property>
432 <item>
433 <widget class="QLabel" name="label_characters_box">
434 <property name="enabled">
435 <bool>true</bool>
436 </property>
437 <property name="font">
438 <font>
439 <pointsize>17</pointsize>
440 </font>
441 </property>
442 <property name="text">
443 <string notr="true">0/500</string>
444 </property>
445 </widget>
446 </item>
447 </layout>
448 </widget>
449 </item>
450 <item row="1" column="1">
451 <widget class="QWidget" name="inputBoxOSK" native="true">
452 <layout class="QVBoxLayout" name="verticalLayout_6">
453 <property name="spacing">
454 <number>0</number>
455 </property>
456 <property name="leftMargin">
457 <number>14</number>
458 </property>
459 <property name="topMargin">
460 <number>9</number>
461 </property>
462 <property name="rightMargin">
463 <number>14</number>
464 </property>
465 <property name="bottomMargin">
466 <number>9</number>
467 </property>
468 <item>
469 <widget class="QTextEdit" name="text_edit_osk">
470 <property name="font">
471 <font>
472 <pointsize>26</pointsize>
473 </font>
474 </property>
475 <property name="focusPolicy">
476 <enum>Qt::StrongFocus</enum>
477 </property>
478 <property name="html">
479 <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
480&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
481p, li { white-space: pre-wrap; }
482&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:26pt; font-weight:400; font-style:normal;&quot;&gt;
483&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
484 </property>
485 </widget>
486 </item>
487 </layout>
488 </widget>
489 </item>
490 </layout>
491 </item>
492 </layout>
493 </widget>
494 </widget>
495 </item>
496 <item>
497 <widget class="QStackedWidget" name="bottomOSK">
498 <property name="currentIndex">
499 <number>0</number>
500 </property>
501 <widget class="QWidget" name="normalOSK">
502 <layout class="QVBoxLayout" name="normalPageVerticalLayout">
503 <property name="leftMargin">
504 <number>0</number>
505 </property>
506 <property name="topMargin">
507 <number>0</number>
508 </property>
509 <property name="rightMargin">
510 <number>0</number>
511 </property>
512 <property name="bottomMargin">
513 <number>0</number>
514 </property>
515 <item>
516 <layout class="QGridLayout" name="kbOSKnormal" rowstretch="15,63,63,63,63,63,70" columnstretch="54,96,96,96,96,96,96,96,96,96,96,96,116,54">
517 <property name="spacing">
518 <number>0</number>
519 </property>
520 <item row="6" column="1" colspan="12">
521 <widget class="QWidget" name="legendOSK" native="true">
522 <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="70,525,25,12,22,41,25,12,22,41,25,12,47,37,29,12,69,37,29,12,56,8">
523 <property name="spacing">
524 <number>0</number>
525 </property>
526 <property name="leftMargin">
527 <number>2</number>
528 </property>
529 <property name="topMargin">
530 <number>0</number>
531 </property>
532 <property name="rightMargin">
533 <number>0</number>
534 </property>
535 <property name="bottomMargin">
536 <number>0</number>
537 </property>
538 <item>
539 <widget class="QWidget" name="icon_controller" native="true">
540 <property name="styleSheet">
541 <string notr="true"/>
542 </property>
543 </widget>
544 </item>
545 <item>
546 <spacer name="horizontalSpacer_5">
547 <property name="orientation">
548 <enum>Qt::Horizontal</enum>
549 </property>
550 <property name="sizeHint" stdset="0">
551 <size>
552 <width>0</width>
553 <height>20</height>
554 </size>
555 </property>
556 </spacer>
557 </item>
558 <item>
559 <widget class="QWidget" name="button_L" native="true"/>
560 </item>
561 <item>
562 <spacer name="horizontalSpacer_14">
563 <property name="orientation">
564 <enum>Qt::Horizontal</enum>
565 </property>
566 <property name="sizeHint" stdset="0">
567 <size>
568 <width>0</width>
569 <height>20</height>
570 </size>
571 </property>
572 </spacer>
573 </item>
574 <item>
575 <widget class="QWidget" name="arrow_left" native="true"/>
576 </item>
577 <item>
578 <spacer name="horizontalSpacer_13">
579 <property name="orientation">
580 <enum>Qt::Horizontal</enum>
581 </property>
582 <property name="sizeHint" stdset="0">
583 <size>
584 <width>0</width>
585 <height>20</height>
586 </size>
587 </property>
588 </spacer>
589 </item>
590 <item>
591 <widget class="QWidget" name="button_R" native="true"/>
592 </item>
593 <item>
594 <spacer name="horizontalSpacer_12">
595 <property name="orientation">
596 <enum>Qt::Horizontal</enum>
597 </property>
598 <property name="sizeHint" stdset="0">
599 <size>
600 <width>0</width>
601 <height>20</height>
602 </size>
603 </property>
604 </spacer>
605 </item>
606 <item>
607 <widget class="QWidget" name="arrow_right" native="true"/>
608 </item>
609 <item>
610 <spacer name="horizontalSpacer_11">
611 <property name="orientation">
612 <enum>Qt::Horizontal</enum>
613 </property>
614 <property name="sizeHint" stdset="0">
615 <size>
616 <width>0</width>
617 <height>20</height>
618 </size>
619 </property>
620 </spacer>
621 </item>
622 <item>
623 <widget class="QWidget" name="button_press_stick" native="true"/>
624 </item>
625 <item>
626 <spacer name="horizontalSpacer_10">
627 <property name="orientation">
628 <enum>Qt::Horizontal</enum>
629 </property>
630 <property name="sizeHint" stdset="0">
631 <size>
632 <width>0</width>
633 <height>20</height>
634 </size>
635 </property>
636 </spacer>
637 </item>
638 <item>
639 <widget class="QLabel" name="label_shift">
640 <property name="font">
641 <font>
642 <pointsize>18</pointsize>
643 </font>
644 </property>
645 <property name="text">
646 <string notr="true">Shift</string>
647 </property>
648 </widget>
649 </item>
650 <item>
651 <spacer name="horizontalSpacer_15">
652 <property name="orientation">
653 <enum>Qt::Horizontal</enum>
654 </property>
655 <property name="sizeHint" stdset="0">
656 <size>
657 <width>0</width>
658 <height>20</height>
659 </size>
660 </property>
661 </spacer>
662 </item>
663 <item>
664 <widget class="QWidget" name="button_X" native="true"/>
665 </item>
666 <item>
667 <spacer name="horizontalSpacer_9">
668 <property name="orientation">
669 <enum>Qt::Horizontal</enum>
670 </property>
671 <property name="sizeHint" stdset="0">
672 <size>
673 <width>0</width>
674 <height>20</height>
675 </size>
676 </property>
677 </spacer>
678 </item>
679 <item>
680 <widget class="QLabel" name="label_cancel">
681 <property name="font">
682 <font>
683 <pointsize>18</pointsize>
684 </font>
685 </property>
686 <property name="text">
687 <string notr="true">Cancel</string>
688 </property>
689 </widget>
690 </item>
691 <item>
692 <spacer name="horizontalSpacer_8">
693 <property name="orientation">
694 <enum>Qt::Horizontal</enum>
695 </property>
696 <property name="sizeHint" stdset="0">
697 <size>
698 <width>0</width>
699 <height>20</height>
700 </size>
701 </property>
702 </spacer>
703 </item>
704 <item>
705 <widget class="QWidget" name="button_A" native="true"/>
706 </item>
707 <item>
708 <spacer name="horizontalSpacer_7">
709 <property name="orientation">
710 <enum>Qt::Horizontal</enum>
711 </property>
712 <property name="sizeHint" stdset="0">
713 <size>
714 <width>0</width>
715 <height>20</height>
716 </size>
717 </property>
718 </spacer>
719 </item>
720 <item>
721 <widget class="QLabel" name="label_enter">
722 <property name="font">
723 <font>
724 <pointsize>18</pointsize>
725 </font>
726 </property>
727 <property name="text">
728 <string notr="true">Enter</string>
729 </property>
730 </widget>
731 </item>
732 <item>
733 <spacer name="horizontalSpacer_6">
734 <property name="orientation">
735 <enum>Qt::Horizontal</enum>
736 </property>
737 <property name="sizeHint" stdset="0">
738 <size>
739 <width>0</width>
740 <height>20</height>
741 </size>
742 </property>
743 </spacer>
744 </item>
745 </layout>
746 </widget>
747 </item>
748 <item row="1" column="11">
749 <widget class="QPushButton" name="button_minus">
750 <property name="sizePolicy">
751 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
752 <horstretch>1</horstretch>
753 <verstretch>1</verstretch>
754 </sizepolicy>
755 </property>
756 <property name="font">
757 <font>
758 <pointsize>28</pointsize>
759 </font>
760 </property>
761 <property name="text">
762 <string notr="true">-</string>
763 </property>
764 </widget>
765 </item>
766 <item row="3" column="11">
767 <widget class="QPushButton" name="button_apostrophe">
768 <property name="sizePolicy">
769 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
770 <horstretch>1</horstretch>
771 <verstretch>1</verstretch>
772 </sizepolicy>
773 </property>
774 <property name="font">
775 <font>
776 <pointsize>28</pointsize>
777 </font>
778 </property>
779 <property name="text">
780 <string notr="true">'</string>
781 </property>
782 </widget>
783 </item>
784 <item row="2" column="11">
785 <widget class="QPushButton" name="button_slash">
786 <property name="sizePolicy">
787 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
788 <horstretch>1</horstretch>
789 <verstretch>1</verstretch>
790 </sizepolicy>
791 </property>
792 <property name="font">
793 <font>
794 <pointsize>28</pointsize>
795 </font>
796 </property>
797 <property name="text">
798 <string notr="true">/</string>
799 </property>
800 </widget>
801 </item>
802 <item row="4" column="11">
803 <widget class="QPushButton" name="button_exclamation">
804 <property name="sizePolicy">
805 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
806 <horstretch>1</horstretch>
807 <verstretch>1</verstretch>
808 </sizepolicy>
809 </property>
810 <property name="font">
811 <font>
812 <pointsize>28</pointsize>
813 </font>
814 </property>
815 <property name="text">
816 <string notr="true">!</string>
817 </property>
818 </widget>
819 </item>
820 <item row="1" column="7">
821 <widget class="QPushButton" name="button_7">
822 <property name="sizePolicy">
823 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
824 <horstretch>1</horstretch>
825 <verstretch>1</verstretch>
826 </sizepolicy>
827 </property>
828 <property name="font">
829 <font>
830 <pointsize>28</pointsize>
831 </font>
832 </property>
833 <property name="text">
834 <string notr="true">7</string>
835 </property>
836 </widget>
837 </item>
838 <item row="1" column="8">
839 <widget class="QPushButton" name="button_8">
840 <property name="sizePolicy">
841 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
842 <horstretch>1</horstretch>
843 <verstretch>1</verstretch>
844 </sizepolicy>
845 </property>
846 <property name="font">
847 <font>
848 <pointsize>28</pointsize>
849 </font>
850 </property>
851 <property name="text">
852 <string notr="true">8</string>
853 </property>
854 </widget>
855 </item>
856 <item row="1" column="10">
857 <widget class="QPushButton" name="button_0">
858 <property name="sizePolicy">
859 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
860 <horstretch>1</horstretch>
861 <verstretch>1</verstretch>
862 </sizepolicy>
863 </property>
864 <property name="font">
865 <font>
866 <pointsize>28</pointsize>
867 </font>
868 </property>
869 <property name="text">
870 <string notr="true">0</string>
871 </property>
872 </widget>
873 </item>
874 <item row="1" column="9">
875 <widget class="QPushButton" name="button_9">
876 <property name="sizePolicy">
877 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
878 <horstretch>1</horstretch>
879 <verstretch>1</verstretch>
880 </sizepolicy>
881 </property>
882 <property name="font">
883 <font>
884 <pointsize>28</pointsize>
885 </font>
886 </property>
887 <property name="text">
888 <string notr="true">9</string>
889 </property>
890 </widget>
891 </item>
892 <item row="2" column="2">
893 <widget class="QPushButton" name="button_w">
894 <property name="sizePolicy">
895 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
896 <horstretch>1</horstretch>
897 <verstretch>1</verstretch>
898 </sizepolicy>
899 </property>
900 <property name="font">
901 <font>
902 <pointsize>28</pointsize>
903 </font>
904 </property>
905 <property name="text">
906 <string notr="true">w</string>
907 </property>
908 </widget>
909 </item>
910 <item row="2" column="4">
911 <widget class="QPushButton" name="button_r">
912 <property name="sizePolicy">
913 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
914 <horstretch>1</horstretch>
915 <verstretch>1</verstretch>
916 </sizepolicy>
917 </property>
918 <property name="font">
919 <font>
920 <pointsize>28</pointsize>
921 </font>
922 </property>
923 <property name="text">
924 <string notr="true">r</string>
925 </property>
926 </widget>
927 </item>
928 <item row="2" column="3">
929 <widget class="QPushButton" name="button_e">
930 <property name="sizePolicy">
931 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
932 <horstretch>1</horstretch>
933 <verstretch>1</verstretch>
934 </sizepolicy>
935 </property>
936 <property name="font">
937 <font>
938 <pointsize>28</pointsize>
939 </font>
940 </property>
941 <property name="text">
942 <string notr="true">e</string>
943 </property>
944 </widget>
945 </item>
946 <item row="2" column="1">
947 <widget class="QPushButton" name="button_q">
948 <property name="sizePolicy">
949 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
950 <horstretch>1</horstretch>
951 <verstretch>1</verstretch>
952 </sizepolicy>
953 </property>
954 <property name="font">
955 <font>
956 <pointsize>28</pointsize>
957 </font>
958 </property>
959 <property name="text">
960 <string notr="true">q</string>
961 </property>
962 </widget>
963 </item>
964 <item row="2" column="7">
965 <widget class="QPushButton" name="button_u">
966 <property name="sizePolicy">
967 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
968 <horstretch>1</horstretch>
969 <verstretch>1</verstretch>
970 </sizepolicy>
971 </property>
972 <property name="font">
973 <font>
974 <pointsize>28</pointsize>
975 </font>
976 </property>
977 <property name="text">
978 <string notr="true">u</string>
979 </property>
980 </widget>
981 </item>
982 <item row="2" column="6">
983 <widget class="QPushButton" name="button_y">
984 <property name="sizePolicy">
985 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
986 <horstretch>1</horstretch>
987 <verstretch>1</verstretch>
988 </sizepolicy>
989 </property>
990 <property name="font">
991 <font>
992 <pointsize>28</pointsize>
993 </font>
994 </property>
995 <property name="text">
996 <string notr="true">y</string>
997 </property>
998 </widget>
999 </item>
1000 <item row="2" column="5">
1001 <widget class="QPushButton" name="button_t">
1002 <property name="sizePolicy">
1003 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1004 <horstretch>1</horstretch>
1005 <verstretch>1</verstretch>
1006 </sizepolicy>
1007 </property>
1008 <property name="font">
1009 <font>
1010 <pointsize>28</pointsize>
1011 </font>
1012 </property>
1013 <property name="text">
1014 <string notr="true">t</string>
1015 </property>
1016 </widget>
1017 </item>
1018 <item row="2" column="9">
1019 <widget class="QPushButton" name="button_o">
1020 <property name="sizePolicy">
1021 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1022 <horstretch>1</horstretch>
1023 <verstretch>1</verstretch>
1024 </sizepolicy>
1025 </property>
1026 <property name="font">
1027 <font>
1028 <pointsize>28</pointsize>
1029 </font>
1030 </property>
1031 <property name="text">
1032 <string notr="true">o</string>
1033 </property>
1034 </widget>
1035 </item>
1036 <item row="2" column="10">
1037 <widget class="QPushButton" name="button_p">
1038 <property name="sizePolicy">
1039 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1040 <horstretch>1</horstretch>
1041 <verstretch>1</verstretch>
1042 </sizepolicy>
1043 </property>
1044 <property name="font">
1045 <font>
1046 <pointsize>28</pointsize>
1047 </font>
1048 </property>
1049 <property name="text">
1050 <string notr="true">p</string>
1051 </property>
1052 </widget>
1053 </item>
1054 <item row="2" column="8">
1055 <widget class="QPushButton" name="button_i">
1056 <property name="sizePolicy">
1057 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1058 <horstretch>1</horstretch>
1059 <verstretch>1</verstretch>
1060 </sizepolicy>
1061 </property>
1062 <property name="font">
1063 <font>
1064 <pointsize>28</pointsize>
1065 </font>
1066 </property>
1067 <property name="text">
1068 <string notr="true">i</string>
1069 </property>
1070 </widget>
1071 </item>
1072 <item row="3" column="1">
1073 <widget class="QPushButton" name="button_a">
1074 <property name="sizePolicy">
1075 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1076 <horstretch>1</horstretch>
1077 <verstretch>1</verstretch>
1078 </sizepolicy>
1079 </property>
1080 <property name="font">
1081 <font>
1082 <pointsize>28</pointsize>
1083 </font>
1084 </property>
1085 <property name="text">
1086 <string notr="true">a</string>
1087 </property>
1088 </widget>
1089 </item>
1090 <item row="3" column="2">
1091 <widget class="QPushButton" name="button_s">
1092 <property name="sizePolicy">
1093 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1094 <horstretch>1</horstretch>
1095 <verstretch>1</verstretch>
1096 </sizepolicy>
1097 </property>
1098 <property name="font">
1099 <font>
1100 <pointsize>28</pointsize>
1101 </font>
1102 </property>
1103 <property name="text">
1104 <string notr="true">s</string>
1105 </property>
1106 </widget>
1107 </item>
1108 <item row="3" column="3">
1109 <widget class="QPushButton" name="button_d">
1110 <property name="sizePolicy">
1111 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1112 <horstretch>1</horstretch>
1113 <verstretch>1</verstretch>
1114 </sizepolicy>
1115 </property>
1116 <property name="font">
1117 <font>
1118 <pointsize>28</pointsize>
1119 </font>
1120 </property>
1121 <property name="text">
1122 <string notr="true">d</string>
1123 </property>
1124 </widget>
1125 </item>
1126 <item row="3" column="4">
1127 <widget class="QPushButton" name="button_f">
1128 <property name="sizePolicy">
1129 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1130 <horstretch>1</horstretch>
1131 <verstretch>1</verstretch>
1132 </sizepolicy>
1133 </property>
1134 <property name="font">
1135 <font>
1136 <pointsize>28</pointsize>
1137 </font>
1138 </property>
1139 <property name="text">
1140 <string notr="true">f</string>
1141 </property>
1142 </widget>
1143 </item>
1144 <item row="3" column="6">
1145 <widget class="QPushButton" name="button_h">
1146 <property name="sizePolicy">
1147 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1148 <horstretch>1</horstretch>
1149 <verstretch>1</verstretch>
1150 </sizepolicy>
1151 </property>
1152 <property name="font">
1153 <font>
1154 <pointsize>28</pointsize>
1155 </font>
1156 </property>
1157 <property name="text">
1158 <string notr="true">h</string>
1159 </property>
1160 </widget>
1161 </item>
1162 <item row="3" column="7">
1163 <widget class="QPushButton" name="button_j">
1164 <property name="sizePolicy">
1165 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1166 <horstretch>1</horstretch>
1167 <verstretch>1</verstretch>
1168 </sizepolicy>
1169 </property>
1170 <property name="font">
1171 <font>
1172 <pointsize>28</pointsize>
1173 </font>
1174 </property>
1175 <property name="text">
1176 <string notr="true">j</string>
1177 </property>
1178 </widget>
1179 </item>
1180 <item row="3" column="5">
1181 <widget class="QPushButton" name="button_g">
1182 <property name="sizePolicy">
1183 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1184 <horstretch>1</horstretch>
1185 <verstretch>1</verstretch>
1186 </sizepolicy>
1187 </property>
1188 <property name="font">
1189 <font>
1190 <pointsize>28</pointsize>
1191 </font>
1192 </property>
1193 <property name="text">
1194 <string notr="true">g</string>
1195 </property>
1196 </widget>
1197 </item>
1198 <item row="3" column="8">
1199 <widget class="QPushButton" name="button_k">
1200 <property name="sizePolicy">
1201 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1202 <horstretch>1</horstretch>
1203 <verstretch>1</verstretch>
1204 </sizepolicy>
1205 </property>
1206 <property name="font">
1207 <font>
1208 <pointsize>28</pointsize>
1209 </font>
1210 </property>
1211 <property name="text">
1212 <string notr="true">k</string>
1213 </property>
1214 </widget>
1215 </item>
1216 <item row="3" column="9">
1217 <widget class="QPushButton" name="button_l">
1218 <property name="sizePolicy">
1219 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1220 <horstretch>1</horstretch>
1221 <verstretch>1</verstretch>
1222 </sizepolicy>
1223 </property>
1224 <property name="font">
1225 <font>
1226 <pointsize>28</pointsize>
1227 </font>
1228 </property>
1229 <property name="text">
1230 <string notr="true">l</string>
1231 </property>
1232 </widget>
1233 </item>
1234 <item row="3" column="10">
1235 <widget class="QPushButton" name="button_colon">
1236 <property name="sizePolicy">
1237 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1238 <horstretch>1</horstretch>
1239 <verstretch>1</verstretch>
1240 </sizepolicy>
1241 </property>
1242 <property name="font">
1243 <font>
1244 <pointsize>28</pointsize>
1245 </font>
1246 </property>
1247 <property name="text">
1248 <string notr="true">:</string>
1249 </property>
1250 </widget>
1251 </item>
1252 <item row="2" column="12" rowspan="2">
1253 <widget class="QPushButton" name="button_return">
1254 <property name="sizePolicy">
1255 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1256 <horstretch>1</horstretch>
1257 <verstretch>1</verstretch>
1258 </sizepolicy>
1259 </property>
1260 <property name="font">
1261 <font>
1262 <pointsize>18</pointsize>
1263 </font>
1264 </property>
1265 <property name="text">
1266 <string notr="true">Return</string>
1267 </property>
1268 </widget>
1269 </item>
1270 <item row="4" column="12" rowspan="2">
1271 <widget class="QPushButton" name="button_ok">
1272 <property name="sizePolicy">
1273 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1274 <horstretch>1</horstretch>
1275 <verstretch>1</verstretch>
1276 </sizepolicy>
1277 </property>
1278 <property name="font">
1279 <font>
1280 <pointsize>18</pointsize>
1281 </font>
1282 </property>
1283 <property name="text">
1284 <string notr="true">OK</string>
1285 </property>
1286 </widget>
1287 </item>
1288 <item row="4" column="1">
1289 <widget class="QPushButton" name="button_z">
1290 <property name="sizePolicy">
1291 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1292 <horstretch>1</horstretch>
1293 <verstretch>1</verstretch>
1294 </sizepolicy>
1295 </property>
1296 <property name="font">
1297 <font>
1298 <pointsize>28</pointsize>
1299 </font>
1300 </property>
1301 <property name="text">
1302 <string notr="true">z</string>
1303 </property>
1304 </widget>
1305 </item>
1306 <item row="4" column="3">
1307 <widget class="QPushButton" name="button_c">
1308 <property name="sizePolicy">
1309 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1310 <horstretch>1</horstretch>
1311 <verstretch>1</verstretch>
1312 </sizepolicy>
1313 </property>
1314 <property name="font">
1315 <font>
1316 <pointsize>28</pointsize>
1317 </font>
1318 </property>
1319 <property name="text">
1320 <string notr="true">c</string>
1321 </property>
1322 </widget>
1323 </item>
1324 <item row="4" column="2">
1325 <widget class="QPushButton" name="button_x">
1326 <property name="sizePolicy">
1327 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1328 <horstretch>1</horstretch>
1329 <verstretch>1</verstretch>
1330 </sizepolicy>
1331 </property>
1332 <property name="font">
1333 <font>
1334 <pointsize>28</pointsize>
1335 </font>
1336 </property>
1337 <property name="text">
1338 <string notr="true">x</string>
1339 </property>
1340 </widget>
1341 </item>
1342 <item row="4" column="4">
1343 <widget class="QPushButton" name="button_v">
1344 <property name="sizePolicy">
1345 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1346 <horstretch>1</horstretch>
1347 <verstretch>1</verstretch>
1348 </sizepolicy>
1349 </property>
1350 <property name="font">
1351 <font>
1352 <pointsize>28</pointsize>
1353 </font>
1354 </property>
1355 <property name="text">
1356 <string notr="true">v</string>
1357 </property>
1358 </widget>
1359 </item>
1360 <item row="4" column="7">
1361 <widget class="QPushButton" name="button_m">
1362 <property name="sizePolicy">
1363 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1364 <horstretch>1</horstretch>
1365 <verstretch>1</verstretch>
1366 </sizepolicy>
1367 </property>
1368 <property name="font">
1369 <font>
1370 <pointsize>28</pointsize>
1371 </font>
1372 </property>
1373 <property name="text">
1374 <string notr="true">m</string>
1375 </property>
1376 </widget>
1377 </item>
1378 <item row="4" column="8">
1379 <widget class="QPushButton" name="button_comma">
1380 <property name="sizePolicy">
1381 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1382 <horstretch>1</horstretch>
1383 <verstretch>1</verstretch>
1384 </sizepolicy>
1385 </property>
1386 <property name="font">
1387 <font>
1388 <pointsize>28</pointsize>
1389 </font>
1390 </property>
1391 <property name="text">
1392 <string notr="true">,</string>
1393 </property>
1394 </widget>
1395 </item>
1396 <item row="4" column="6">
1397 <widget class="QPushButton" name="button_n">
1398 <property name="sizePolicy">
1399 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1400 <horstretch>1</horstretch>
1401 <verstretch>1</verstretch>
1402 </sizepolicy>
1403 </property>
1404 <property name="font">
1405 <font>
1406 <pointsize>28</pointsize>
1407 </font>
1408 </property>
1409 <property name="text">
1410 <string notr="true">n</string>
1411 </property>
1412 </widget>
1413 </item>
1414 <item row="4" column="5">
1415 <widget class="QPushButton" name="button_b">
1416 <property name="sizePolicy">
1417 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1418 <horstretch>1</horstretch>
1419 <verstretch>1</verstretch>
1420 </sizepolicy>
1421 </property>
1422 <property name="font">
1423 <font>
1424 <pointsize>28</pointsize>
1425 </font>
1426 </property>
1427 <property name="text">
1428 <string notr="true">b</string>
1429 </property>
1430 </widget>
1431 </item>
1432 <item row="5" column="1" colspan="2">
1433 <widget class="QPushButton" name="button_shift">
1434 <property name="sizePolicy">
1435 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1436 <horstretch>1</horstretch>
1437 <verstretch>1</verstretch>
1438 </sizepolicy>
1439 </property>
1440 <property name="font">
1441 <font>
1442 <pointsize>18</pointsize>
1443 </font>
1444 </property>
1445 <property name="text">
1446 <string notr="true"/>
1447 </property>
1448 <property name="checkable">
1449 <bool>true</bool>
1450 </property>
1451 <property name="checked">
1452 <bool>false</bool>
1453 </property>
1454 </widget>
1455 </item>
1456 <item row="4" column="10">
1457 <widget class="QPushButton" name="button_question">
1458 <property name="sizePolicy">
1459 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1460 <horstretch>1</horstretch>
1461 <verstretch>1</verstretch>
1462 </sizepolicy>
1463 </property>
1464 <property name="font">
1465 <font>
1466 <pointsize>28</pointsize>
1467 </font>
1468 </property>
1469 <property name="text">
1470 <string notr="true">?</string>
1471 </property>
1472 </widget>
1473 </item>
1474 <item row="4" column="9">
1475 <widget class="QPushButton" name="button_dot">
1476 <property name="sizePolicy">
1477 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1478 <horstretch>1</horstretch>
1479 <verstretch>1</verstretch>
1480 </sizepolicy>
1481 </property>
1482 <property name="font">
1483 <font>
1484 <pointsize>28</pointsize>
1485 </font>
1486 </property>
1487 <property name="text">
1488 <string notr="true">.</string>
1489 </property>
1490 </widget>
1491 </item>
1492 <item row="1" column="1">
1493 <widget class="QPushButton" name="button_1">
1494 <property name="sizePolicy">
1495 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1496 <horstretch>1</horstretch>
1497 <verstretch>1</verstretch>
1498 </sizepolicy>
1499 </property>
1500 <property name="font">
1501 <font>
1502 <pointsize>28</pointsize>
1503 </font>
1504 </property>
1505 <property name="text">
1506 <string notr="true">1</string>
1507 </property>
1508 </widget>
1509 </item>
1510 <item row="1" column="3">
1511 <widget class="QPushButton" name="button_3">
1512 <property name="sizePolicy">
1513 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1514 <horstretch>1</horstretch>
1515 <verstretch>1</verstretch>
1516 </sizepolicy>
1517 </property>
1518 <property name="font">
1519 <font>
1520 <pointsize>28</pointsize>
1521 </font>
1522 </property>
1523 <property name="text">
1524 <string notr="true">3</string>
1525 </property>
1526 </widget>
1527 </item>
1528 <item row="1" column="4">
1529 <widget class="QPushButton" name="button_4">
1530 <property name="sizePolicy">
1531 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1532 <horstretch>1</horstretch>
1533 <verstretch>1</verstretch>
1534 </sizepolicy>
1535 </property>
1536 <property name="font">
1537 <font>
1538 <pointsize>28</pointsize>
1539 </font>
1540 </property>
1541 <property name="text">
1542 <string notr="true">4</string>
1543 </property>
1544 </widget>
1545 </item>
1546 <item row="1" column="2">
1547 <widget class="QPushButton" name="button_2">
1548 <property name="sizePolicy">
1549 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1550 <horstretch>1</horstretch>
1551 <verstretch>1</verstretch>
1552 </sizepolicy>
1553 </property>
1554 <property name="font">
1555 <font>
1556 <pointsize>28</pointsize>
1557 </font>
1558 </property>
1559 <property name="text">
1560 <string notr="true">2</string>
1561 </property>
1562 </widget>
1563 </item>
1564 <item row="1" column="6">
1565 <widget class="QPushButton" name="button_6">
1566 <property name="sizePolicy">
1567 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1568 <horstretch>1</horstretch>
1569 <verstretch>1</verstretch>
1570 </sizepolicy>
1571 </property>
1572 <property name="font">
1573 <font>
1574 <pointsize>28</pointsize>
1575 </font>
1576 </property>
1577 <property name="text">
1578 <string notr="true">6</string>
1579 </property>
1580 </widget>
1581 </item>
1582 <item row="1" column="5">
1583 <widget class="QPushButton" name="button_5">
1584 <property name="sizePolicy">
1585 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1586 <horstretch>1</horstretch>
1587 <verstretch>1</verstretch>
1588 </sizepolicy>
1589 </property>
1590 <property name="font">
1591 <font>
1592 <pointsize>28</pointsize>
1593 </font>
1594 </property>
1595 <property name="text">
1596 <string notr="true">5</string>
1597 </property>
1598 </widget>
1599 </item>
1600 <item row="5" column="3" colspan="9">
1601 <widget class="QPushButton" name="button_space">
1602 <property name="sizePolicy">
1603 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1604 <horstretch>1</horstretch>
1605 <verstretch>1</verstretch>
1606 </sizepolicy>
1607 </property>
1608 <property name="font">
1609 <font>
1610 <pointsize>18</pointsize>
1611 </font>
1612 </property>
1613 <property name="text">
1614 <string notr="true">Space</string>
1615 </property>
1616 </widget>
1617 </item>
1618 <item row="1" column="12">
1619 <widget class="QPushButton" name="button_backspace">
1620 <property name="sizePolicy">
1621 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1622 <horstretch>1</horstretch>
1623 <verstretch>1</verstretch>
1624 </sizepolicy>
1625 </property>
1626 <property name="font">
1627 <font>
1628 <pointsize>18</pointsize>
1629 </font>
1630 </property>
1631 <property name="text">
1632 <string notr="true"/>
1633 </property>
1634 </widget>
1635 </item>
1636 <item row="1" column="0">
1637 <spacer name="horizontalSpacer">
1638 <property name="orientation">
1639 <enum>Qt::Horizontal</enum>
1640 </property>
1641 <property name="sizeHint" stdset="0">
1642 <size>
1643 <width>40</width>
1644 <height>20</height>
1645 </size>
1646 </property>
1647 </spacer>
1648 </item>
1649 <item row="0" column="1">
1650 <spacer name="verticalSpacer">
1651 <property name="orientation">
1652 <enum>Qt::Vertical</enum>
1653 </property>
1654 <property name="sizeHint" stdset="0">
1655 <size>
1656 <width>20</width>
1657 <height>0</height>
1658 </size>
1659 </property>
1660 </spacer>
1661 </item>
1662 <item row="1" column="13">
1663 <spacer name="horizontalSpacer_2">
1664 <property name="orientation">
1665 <enum>Qt::Horizontal</enum>
1666 </property>
1667 <property name="sizeHint" stdset="0">
1668 <size>
1669 <width>40</width>
1670 <height>20</height>
1671 </size>
1672 </property>
1673 </spacer>
1674 </item>
1675 </layout>
1676 </item>
1677 </layout>
1678 </widget>
1679 <widget class="QWidget" name="shiftOSK">
1680 <layout class="QVBoxLayout" name="shiftPageVerticalLayout">
1681 <property name="leftMargin">
1682 <number>0</number>
1683 </property>
1684 <property name="topMargin">
1685 <number>0</number>
1686 </property>
1687 <property name="rightMargin">
1688 <number>0</number>
1689 </property>
1690 <property name="bottomMargin">
1691 <number>0</number>
1692 </property>
1693 <item>
1694 <layout class="QGridLayout" name="kbOSKshift" rowstretch="15,63,63,63,63,63,70" columnstretch="54,96,96,96,96,96,96,96,96,96,96,96,116,54">
1695 <property name="spacing">
1696 <number>0</number>
1697 </property>
1698 <item row="6" column="1" colspan="12">
1699 <widget class="QWidget" name="legendOSKshift" native="true">
1700 <layout class="QHBoxLayout" name="horizontalLayout_5" stretch="70,464,25,12,22,41,25,12,22,41,25,12,95,37,29,12,69,37,29,12,56,8">
1701 <property name="spacing">
1702 <number>0</number>
1703 </property>
1704 <property name="leftMargin">
1705 <number>2</number>
1706 </property>
1707 <property name="topMargin">
1708 <number>0</number>
1709 </property>
1710 <property name="rightMargin">
1711 <number>0</number>
1712 </property>
1713 <property name="bottomMargin">
1714 <number>0</number>
1715 </property>
1716 <item>
1717 <widget class="QWidget" name="icon_controller_shift" native="true">
1718 <property name="styleSheet">
1719 <string notr="true"/>
1720 </property>
1721 </widget>
1722 </item>
1723 <item>
1724 <spacer name="horizontalSpacer_22">
1725 <property name="orientation">
1726 <enum>Qt::Horizontal</enum>
1727 </property>
1728 <property name="sizeHint" stdset="0">
1729 <size>
1730 <width>0</width>
1731 <height>20</height>
1732 </size>
1733 </property>
1734 </spacer>
1735 </item>
1736 <item>
1737 <widget class="QWidget" name="button_L_shift" native="true"/>
1738 </item>
1739 <item>
1740 <spacer name="horizontalSpacer_23">
1741 <property name="orientation">
1742 <enum>Qt::Horizontal</enum>
1743 </property>
1744 <property name="sizeHint" stdset="0">
1745 <size>
1746 <width>0</width>
1747 <height>20</height>
1748 </size>
1749 </property>
1750 </spacer>
1751 </item>
1752 <item>
1753 <widget class="QWidget" name="arrow_left_shift" native="true"/>
1754 </item>
1755 <item>
1756 <spacer name="horizontalSpacer_24">
1757 <property name="orientation">
1758 <enum>Qt::Horizontal</enum>
1759 </property>
1760 <property name="sizeHint" stdset="0">
1761 <size>
1762 <width>0</width>
1763 <height>20</height>
1764 </size>
1765 </property>
1766 </spacer>
1767 </item>
1768 <item>
1769 <widget class="QWidget" name="button_R_shift" native="true"/>
1770 </item>
1771 <item>
1772 <spacer name="horizontalSpacer_25">
1773 <property name="orientation">
1774 <enum>Qt::Horizontal</enum>
1775 </property>
1776 <property name="sizeHint" stdset="0">
1777 <size>
1778 <width>0</width>
1779 <height>20</height>
1780 </size>
1781 </property>
1782 </spacer>
1783 </item>
1784 <item>
1785 <widget class="QWidget" name="arrow_right_shift" native="true"/>
1786 </item>
1787 <item>
1788 <spacer name="horizontalSpacer_26">
1789 <property name="orientation">
1790 <enum>Qt::Horizontal</enum>
1791 </property>
1792 <property name="sizeHint" stdset="0">
1793 <size>
1794 <width>0</width>
1795 <height>20</height>
1796 </size>
1797 </property>
1798 </spacer>
1799 </item>
1800 <item>
1801 <widget class="QWidget" name="button_press_stick_shift" native="true"/>
1802 </item>
1803 <item>
1804 <spacer name="horizontalSpacer_27">
1805 <property name="orientation">
1806 <enum>Qt::Horizontal</enum>
1807 </property>
1808 <property name="sizeHint" stdset="0">
1809 <size>
1810 <width>0</width>
1811 <height>20</height>
1812 </size>
1813 </property>
1814 </spacer>
1815 </item>
1816 <item>
1817 <widget class="QLabel" name="label_shift_shift">
1818 <property name="font">
1819 <font>
1820 <pointsize>18</pointsize>
1821 </font>
1822 </property>
1823 <property name="text">
1824 <string notr="true">Caps Lock</string>
1825 </property>
1826 </widget>
1827 </item>
1828 <item>
1829 <spacer name="horizontalSpacer_28">
1830 <property name="orientation">
1831 <enum>Qt::Horizontal</enum>
1832 </property>
1833 <property name="sizeHint" stdset="0">
1834 <size>
1835 <width>0</width>
1836 <height>20</height>
1837 </size>
1838 </property>
1839 </spacer>
1840 </item>
1841 <item>
1842 <widget class="QWidget" name="button_X_shift" native="true"/>
1843 </item>
1844 <item>
1845 <spacer name="horizontalSpacer_29">
1846 <property name="orientation">
1847 <enum>Qt::Horizontal</enum>
1848 </property>
1849 <property name="sizeHint" stdset="0">
1850 <size>
1851 <width>0</width>
1852 <height>20</height>
1853 </size>
1854 </property>
1855 </spacer>
1856 </item>
1857 <item>
1858 <widget class="QLabel" name="label_cancel_shift">
1859 <property name="font">
1860 <font>
1861 <pointsize>18</pointsize>
1862 </font>
1863 </property>
1864 <property name="text">
1865 <string notr="true">Cancel</string>
1866 </property>
1867 </widget>
1868 </item>
1869 <item>
1870 <spacer name="horizontalSpacer_30">
1871 <property name="orientation">
1872 <enum>Qt::Horizontal</enum>
1873 </property>
1874 <property name="sizeHint" stdset="0">
1875 <size>
1876 <width>0</width>
1877 <height>20</height>
1878 </size>
1879 </property>
1880 </spacer>
1881 </item>
1882 <item>
1883 <widget class="QWidget" name="button_A_shift" native="true"/>
1884 </item>
1885 <item>
1886 <spacer name="horizontalSpacer_31">
1887 <property name="orientation">
1888 <enum>Qt::Horizontal</enum>
1889 </property>
1890 <property name="sizeHint" stdset="0">
1891 <size>
1892 <width>0</width>
1893 <height>20</height>
1894 </size>
1895 </property>
1896 </spacer>
1897 </item>
1898 <item>
1899 <widget class="QLabel" name="label_enter_shift">
1900 <property name="font">
1901 <font>
1902 <pointsize>18</pointsize>
1903 </font>
1904 </property>
1905 <property name="text">
1906 <string notr="true">Enter</string>
1907 </property>
1908 </widget>
1909 </item>
1910 <item>
1911 <spacer name="horizontalSpacer_32">
1912 <property name="orientation">
1913 <enum>Qt::Horizontal</enum>
1914 </property>
1915 <property name="sizeHint" stdset="0">
1916 <size>
1917 <width>0</width>
1918 <height>20</height>
1919 </size>
1920 </property>
1921 </spacer>
1922 </item>
1923 </layout>
1924 </widget>
1925 </item>
1926 <item row="1" column="11">
1927 <widget class="QPushButton" name="button_underscore">
1928 <property name="sizePolicy">
1929 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1930 <horstretch>1</horstretch>
1931 <verstretch>1</verstretch>
1932 </sizepolicy>
1933 </property>
1934 <property name="font">
1935 <font>
1936 <pointsize>28</pointsize>
1937 </font>
1938 </property>
1939 <property name="text">
1940 <string notr="true">_</string>
1941 </property>
1942 </widget>
1943 </item>
1944 <item row="3" column="11">
1945 <widget class="QPushButton" name="button_quotation">
1946 <property name="sizePolicy">
1947 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1948 <horstretch>1</horstretch>
1949 <verstretch>1</verstretch>
1950 </sizepolicy>
1951 </property>
1952 <property name="font">
1953 <font>
1954 <pointsize>28</pointsize>
1955 </font>
1956 </property>
1957 <property name="text">
1958 <string notr="true">&quot;</string>
1959 </property>
1960 </widget>
1961 </item>
1962 <item row="2" column="11">
1963 <widget class="QPushButton" name="button_at">
1964 <property name="sizePolicy">
1965 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1966 <horstretch>1</horstretch>
1967 <verstretch>1</verstretch>
1968 </sizepolicy>
1969 </property>
1970 <property name="font">
1971 <font>
1972 <pointsize>28</pointsize>
1973 </font>
1974 </property>
1975 <property name="text">
1976 <string notr="true">@</string>
1977 </property>
1978 </widget>
1979 </item>
1980 <item row="4" column="11">
1981 <widget class="QPushButton" name="button_equal">
1982 <property name="sizePolicy">
1983 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1984 <horstretch>1</horstretch>
1985 <verstretch>1</verstretch>
1986 </sizepolicy>
1987 </property>
1988 <property name="font">
1989 <font>
1990 <pointsize>28</pointsize>
1991 </font>
1992 </property>
1993 <property name="text">
1994 <string notr="true">=</string>
1995 </property>
1996 </widget>
1997 </item>
1998 <item row="1" column="7">
1999 <widget class="QPushButton" name="button_ampersand">
2000 <property name="sizePolicy">
2001 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2002 <horstretch>1</horstretch>
2003 <verstretch>1</verstretch>
2004 </sizepolicy>
2005 </property>
2006 <property name="font">
2007 <font>
2008 <pointsize>28</pointsize>
2009 </font>
2010 </property>
2011 <property name="text">
2012 <string notr="true">&amp;&amp;</string>
2013 </property>
2014 </widget>
2015 </item>
2016 <item row="1" column="8">
2017 <widget class="QPushButton" name="button_asterisk">
2018 <property name="sizePolicy">
2019 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2020 <horstretch>1</horstretch>
2021 <verstretch>1</verstretch>
2022 </sizepolicy>
2023 </property>
2024 <property name="font">
2025 <font>
2026 <pointsize>28</pointsize>
2027 </font>
2028 </property>
2029 <property name="text">
2030 <string notr="true">*</string>
2031 </property>
2032 </widget>
2033 </item>
2034 <item row="1" column="10">
2035 <widget class="QPushButton" name="button_right_parenthesis">
2036 <property name="sizePolicy">
2037 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2038 <horstretch>1</horstretch>
2039 <verstretch>1</verstretch>
2040 </sizepolicy>
2041 </property>
2042 <property name="font">
2043 <font>
2044 <pointsize>28</pointsize>
2045 </font>
2046 </property>
2047 <property name="text">
2048 <string notr="true">)</string>
2049 </property>
2050 </widget>
2051 </item>
2052 <item row="1" column="9">
2053 <widget class="QPushButton" name="button_left_parenthesis">
2054 <property name="sizePolicy">
2055 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2056 <horstretch>1</horstretch>
2057 <verstretch>1</verstretch>
2058 </sizepolicy>
2059 </property>
2060 <property name="font">
2061 <font>
2062 <pointsize>28</pointsize>
2063 </font>
2064 </property>
2065 <property name="text">
2066 <string notr="true">(</string>
2067 </property>
2068 </widget>
2069 </item>
2070 <item row="2" column="2">
2071 <widget class="QPushButton" name="button_w_shift">
2072 <property name="sizePolicy">
2073 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2074 <horstretch>1</horstretch>
2075 <verstretch>1</verstretch>
2076 </sizepolicy>
2077 </property>
2078 <property name="font">
2079 <font>
2080 <pointsize>28</pointsize>
2081 </font>
2082 </property>
2083 <property name="text">
2084 <string notr="true">W</string>
2085 </property>
2086 </widget>
2087 </item>
2088 <item row="2" column="4">
2089 <widget class="QPushButton" name="button_r_shift">
2090 <property name="sizePolicy">
2091 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2092 <horstretch>1</horstretch>
2093 <verstretch>1</verstretch>
2094 </sizepolicy>
2095 </property>
2096 <property name="font">
2097 <font>
2098 <pointsize>28</pointsize>
2099 </font>
2100 </property>
2101 <property name="text">
2102 <string notr="true">R</string>
2103 </property>
2104 </widget>
2105 </item>
2106 <item row="2" column="3">
2107 <widget class="QPushButton" name="button_e_shift">
2108 <property name="sizePolicy">
2109 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2110 <horstretch>1</horstretch>
2111 <verstretch>1</verstretch>
2112 </sizepolicy>
2113 </property>
2114 <property name="font">
2115 <font>
2116 <pointsize>28</pointsize>
2117 </font>
2118 </property>
2119 <property name="text">
2120 <string notr="true">E</string>
2121 </property>
2122 </widget>
2123 </item>
2124 <item row="2" column="1">
2125 <widget class="QPushButton" name="button_q_shift">
2126 <property name="sizePolicy">
2127 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2128 <horstretch>1</horstretch>
2129 <verstretch>1</verstretch>
2130 </sizepolicy>
2131 </property>
2132 <property name="font">
2133 <font>
2134 <pointsize>28</pointsize>
2135 </font>
2136 </property>
2137 <property name="text">
2138 <string notr="true">Q</string>
2139 </property>
2140 </widget>
2141 </item>
2142 <item row="2" column="7">
2143 <widget class="QPushButton" name="button_u_shift">
2144 <property name="sizePolicy">
2145 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2146 <horstretch>1</horstretch>
2147 <verstretch>1</verstretch>
2148 </sizepolicy>
2149 </property>
2150 <property name="font">
2151 <font>
2152 <pointsize>28</pointsize>
2153 </font>
2154 </property>
2155 <property name="text">
2156 <string notr="true">U</string>
2157 </property>
2158 </widget>
2159 </item>
2160 <item row="2" column="6">
2161 <widget class="QPushButton" name="button_y_shift">
2162 <property name="sizePolicy">
2163 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2164 <horstretch>1</horstretch>
2165 <verstretch>1</verstretch>
2166 </sizepolicy>
2167 </property>
2168 <property name="font">
2169 <font>
2170 <pointsize>28</pointsize>
2171 </font>
2172 </property>
2173 <property name="text">
2174 <string notr="true">Y</string>
2175 </property>
2176 </widget>
2177 </item>
2178 <item row="2" column="5">
2179 <widget class="QPushButton" name="button_t_shift">
2180 <property name="sizePolicy">
2181 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2182 <horstretch>1</horstretch>
2183 <verstretch>1</verstretch>
2184 </sizepolicy>
2185 </property>
2186 <property name="font">
2187 <font>
2188 <pointsize>28</pointsize>
2189 </font>
2190 </property>
2191 <property name="text">
2192 <string notr="true">T</string>
2193 </property>
2194 </widget>
2195 </item>
2196 <item row="2" column="9">
2197 <widget class="QPushButton" name="button_o_shift">
2198 <property name="sizePolicy">
2199 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2200 <horstretch>1</horstretch>
2201 <verstretch>1</verstretch>
2202 </sizepolicy>
2203 </property>
2204 <property name="font">
2205 <font>
2206 <pointsize>28</pointsize>
2207 </font>
2208 </property>
2209 <property name="text">
2210 <string notr="true">O</string>
2211 </property>
2212 </widget>
2213 </item>
2214 <item row="2" column="10">
2215 <widget class="QPushButton" name="button_p_shift">
2216 <property name="sizePolicy">
2217 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2218 <horstretch>1</horstretch>
2219 <verstretch>1</verstretch>
2220 </sizepolicy>
2221 </property>
2222 <property name="font">
2223 <font>
2224 <pointsize>28</pointsize>
2225 </font>
2226 </property>
2227 <property name="text">
2228 <string notr="true">P</string>
2229 </property>
2230 </widget>
2231 </item>
2232 <item row="2" column="8">
2233 <widget class="QPushButton" name="button_i_shift">
2234 <property name="sizePolicy">
2235 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2236 <horstretch>1</horstretch>
2237 <verstretch>1</verstretch>
2238 </sizepolicy>
2239 </property>
2240 <property name="font">
2241 <font>
2242 <pointsize>28</pointsize>
2243 </font>
2244 </property>
2245 <property name="text">
2246 <string notr="true">I</string>
2247 </property>
2248 </widget>
2249 </item>
2250 <item row="3" column="1">
2251 <widget class="QPushButton" name="button_a_shift">
2252 <property name="sizePolicy">
2253 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2254 <horstretch>1</horstretch>
2255 <verstretch>1</verstretch>
2256 </sizepolicy>
2257 </property>
2258 <property name="font">
2259 <font>
2260 <pointsize>28</pointsize>
2261 </font>
2262 </property>
2263 <property name="text">
2264 <string notr="true">A</string>
2265 </property>
2266 </widget>
2267 </item>
2268 <item row="3" column="2">
2269 <widget class="QPushButton" name="button_s_shift">
2270 <property name="sizePolicy">
2271 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2272 <horstretch>1</horstretch>
2273 <verstretch>1</verstretch>
2274 </sizepolicy>
2275 </property>
2276 <property name="font">
2277 <font>
2278 <pointsize>28</pointsize>
2279 </font>
2280 </property>
2281 <property name="text">
2282 <string notr="true">S</string>
2283 </property>
2284 </widget>
2285 </item>
2286 <item row="3" column="3">
2287 <widget class="QPushButton" name="button_d_shift">
2288 <property name="sizePolicy">
2289 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2290 <horstretch>1</horstretch>
2291 <verstretch>1</verstretch>
2292 </sizepolicy>
2293 </property>
2294 <property name="font">
2295 <font>
2296 <pointsize>28</pointsize>
2297 </font>
2298 </property>
2299 <property name="text">
2300 <string notr="true">D</string>
2301 </property>
2302 </widget>
2303 </item>
2304 <item row="3" column="4">
2305 <widget class="QPushButton" name="button_f_shift">
2306 <property name="sizePolicy">
2307 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2308 <horstretch>1</horstretch>
2309 <verstretch>1</verstretch>
2310 </sizepolicy>
2311 </property>
2312 <property name="font">
2313 <font>
2314 <pointsize>28</pointsize>
2315 </font>
2316 </property>
2317 <property name="text">
2318 <string notr="true">F</string>
2319 </property>
2320 </widget>
2321 </item>
2322 <item row="3" column="6">
2323 <widget class="QPushButton" name="button_h_shift">
2324 <property name="sizePolicy">
2325 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2326 <horstretch>1</horstretch>
2327 <verstretch>1</verstretch>
2328 </sizepolicy>
2329 </property>
2330 <property name="font">
2331 <font>
2332 <pointsize>28</pointsize>
2333 </font>
2334 </property>
2335 <property name="text">
2336 <string notr="true">H</string>
2337 </property>
2338 </widget>
2339 </item>
2340 <item row="3" column="7">
2341 <widget class="QPushButton" name="button_j_shift">
2342 <property name="sizePolicy">
2343 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2344 <horstretch>1</horstretch>
2345 <verstretch>1</verstretch>
2346 </sizepolicy>
2347 </property>
2348 <property name="font">
2349 <font>
2350 <pointsize>28</pointsize>
2351 </font>
2352 </property>
2353 <property name="text">
2354 <string notr="true">J</string>
2355 </property>
2356 </widget>
2357 </item>
2358 <item row="3" column="5">
2359 <widget class="QPushButton" name="button_g_shift">
2360 <property name="sizePolicy">
2361 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2362 <horstretch>1</horstretch>
2363 <verstretch>1</verstretch>
2364 </sizepolicy>
2365 </property>
2366 <property name="font">
2367 <font>
2368 <pointsize>28</pointsize>
2369 </font>
2370 </property>
2371 <property name="text">
2372 <string notr="true">G</string>
2373 </property>
2374 </widget>
2375 </item>
2376 <item row="3" column="8">
2377 <widget class="QPushButton" name="button_k_shift">
2378 <property name="sizePolicy">
2379 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2380 <horstretch>1</horstretch>
2381 <verstretch>1</verstretch>
2382 </sizepolicy>
2383 </property>
2384 <property name="font">
2385 <font>
2386 <pointsize>28</pointsize>
2387 </font>
2388 </property>
2389 <property name="text">
2390 <string notr="true">K</string>
2391 </property>
2392 </widget>
2393 </item>
2394 <item row="3" column="9">
2395 <widget class="QPushButton" name="button_l_shift">
2396 <property name="sizePolicy">
2397 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2398 <horstretch>1</horstretch>
2399 <verstretch>1</verstretch>
2400 </sizepolicy>
2401 </property>
2402 <property name="font">
2403 <font>
2404 <pointsize>28</pointsize>
2405 </font>
2406 </property>
2407 <property name="text">
2408 <string notr="true">L</string>
2409 </property>
2410 </widget>
2411 </item>
2412 <item row="3" column="10">
2413 <widget class="QPushButton" name="button_semicolon">
2414 <property name="sizePolicy">
2415 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2416 <horstretch>1</horstretch>
2417 <verstretch>1</verstretch>
2418 </sizepolicy>
2419 </property>
2420 <property name="font">
2421 <font>
2422 <pointsize>28</pointsize>
2423 </font>
2424 </property>
2425 <property name="text">
2426 <string notr="true">;</string>
2427 </property>
2428 </widget>
2429 </item>
2430 <item row="2" column="12" rowspan="2">
2431 <widget class="QPushButton" name="button_return_shift">
2432 <property name="sizePolicy">
2433 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2434 <horstretch>1</horstretch>
2435 <verstretch>1</verstretch>
2436 </sizepolicy>
2437 </property>
2438 <property name="font">
2439 <font>
2440 <pointsize>18</pointsize>
2441 </font>
2442 </property>
2443 <property name="text">
2444 <string notr="true">Return</string>
2445 </property>
2446 </widget>
2447 </item>
2448 <item row="4" column="12" rowspan="2">
2449 <widget class="QPushButton" name="button_ok_shift">
2450 <property name="sizePolicy">
2451 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2452 <horstretch>1</horstretch>
2453 <verstretch>1</verstretch>
2454 </sizepolicy>
2455 </property>
2456 <property name="font">
2457 <font>
2458 <pointsize>18</pointsize>
2459 </font>
2460 </property>
2461 <property name="text">
2462 <string notr="true">OK</string>
2463 </property>
2464 </widget>
2465 </item>
2466 <item row="4" column="1">
2467 <widget class="QPushButton" name="button_z_shift">
2468 <property name="sizePolicy">
2469 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2470 <horstretch>1</horstretch>
2471 <verstretch>1</verstretch>
2472 </sizepolicy>
2473 </property>
2474 <property name="font">
2475 <font>
2476 <pointsize>28</pointsize>
2477 </font>
2478 </property>
2479 <property name="text">
2480 <string notr="true">Z</string>
2481 </property>
2482 </widget>
2483 </item>
2484 <item row="4" column="3">
2485 <widget class="QPushButton" name="button_c_shift">
2486 <property name="sizePolicy">
2487 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2488 <horstretch>1</horstretch>
2489 <verstretch>1</verstretch>
2490 </sizepolicy>
2491 </property>
2492 <property name="font">
2493 <font>
2494 <pointsize>28</pointsize>
2495 </font>
2496 </property>
2497 <property name="text">
2498 <string notr="true">C</string>
2499 </property>
2500 </widget>
2501 </item>
2502 <item row="4" column="2">
2503 <widget class="QPushButton" name="button_x_shift">
2504 <property name="sizePolicy">
2505 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2506 <horstretch>1</horstretch>
2507 <verstretch>1</verstretch>
2508 </sizepolicy>
2509 </property>
2510 <property name="font">
2511 <font>
2512 <pointsize>28</pointsize>
2513 </font>
2514 </property>
2515 <property name="text">
2516 <string notr="true">X</string>
2517 </property>
2518 </widget>
2519 </item>
2520 <item row="4" column="4">
2521 <widget class="QPushButton" name="button_v_shift">
2522 <property name="sizePolicy">
2523 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2524 <horstretch>1</horstretch>
2525 <verstretch>1</verstretch>
2526 </sizepolicy>
2527 </property>
2528 <property name="font">
2529 <font>
2530 <pointsize>28</pointsize>
2531 </font>
2532 </property>
2533 <property name="text">
2534 <string notr="true">V</string>
2535 </property>
2536 </widget>
2537 </item>
2538 <item row="4" column="7">
2539 <widget class="QPushButton" name="button_m_shift">
2540 <property name="sizePolicy">
2541 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2542 <horstretch>1</horstretch>
2543 <verstretch>1</verstretch>
2544 </sizepolicy>
2545 </property>
2546 <property name="font">
2547 <font>
2548 <pointsize>28</pointsize>
2549 </font>
2550 </property>
2551 <property name="text">
2552 <string notr="true">M</string>
2553 </property>
2554 </widget>
2555 </item>
2556 <item row="4" column="8">
2557 <widget class="QPushButton" name="button_less_than">
2558 <property name="sizePolicy">
2559 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2560 <horstretch>1</horstretch>
2561 <verstretch>1</verstretch>
2562 </sizepolicy>
2563 </property>
2564 <property name="font">
2565 <font>
2566 <pointsize>28</pointsize>
2567 </font>
2568 </property>
2569 <property name="text">
2570 <string notr="true">&lt;</string>
2571 </property>
2572 </widget>
2573 </item>
2574 <item row="4" column="6">
2575 <widget class="QPushButton" name="button_n_shift">
2576 <property name="sizePolicy">
2577 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2578 <horstretch>1</horstretch>
2579 <verstretch>1</verstretch>
2580 </sizepolicy>
2581 </property>
2582 <property name="font">
2583 <font>
2584 <pointsize>28</pointsize>
2585 </font>
2586 </property>
2587 <property name="text">
2588 <string notr="true">N</string>
2589 </property>
2590 </widget>
2591 </item>
2592 <item row="4" column="5">
2593 <widget class="QPushButton" name="button_b_shift">
2594 <property name="sizePolicy">
2595 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2596 <horstretch>1</horstretch>
2597 <verstretch>1</verstretch>
2598 </sizepolicy>
2599 </property>
2600 <property name="font">
2601 <font>
2602 <pointsize>28</pointsize>
2603 </font>
2604 </property>
2605 <property name="text">
2606 <string notr="true">B</string>
2607 </property>
2608 </widget>
2609 </item>
2610 <item row="5" column="1" colspan="2">
2611 <widget class="QPushButton" name="button_shift_shift">
2612 <property name="sizePolicy">
2613 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2614 <horstretch>1</horstretch>
2615 <verstretch>1</verstretch>
2616 </sizepolicy>
2617 </property>
2618 <property name="font">
2619 <font>
2620 <pointsize>18</pointsize>
2621 </font>
2622 </property>
2623 <property name="text">
2624 <string notr="true"/>
2625 </property>
2626 <property name="checkable">
2627 <bool>true</bool>
2628 </property>
2629 <property name="checked">
2630 <bool>false</bool>
2631 </property>
2632 </widget>
2633 </item>
2634 <item row="4" column="10">
2635 <widget class="QPushButton" name="button_plus">
2636 <property name="sizePolicy">
2637 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2638 <horstretch>1</horstretch>
2639 <verstretch>1</verstretch>
2640 </sizepolicy>
2641 </property>
2642 <property name="font">
2643 <font>
2644 <pointsize>28</pointsize>
2645 </font>
2646 </property>
2647 <property name="text">
2648 <string notr="true">+</string>
2649 </property>
2650 </widget>
2651 </item>
2652 <item row="4" column="9">
2653 <widget class="QPushButton" name="button_greater_than">
2654 <property name="sizePolicy">
2655 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2656 <horstretch>1</horstretch>
2657 <verstretch>1</verstretch>
2658 </sizepolicy>
2659 </property>
2660 <property name="font">
2661 <font>
2662 <pointsize>28</pointsize>
2663 </font>
2664 </property>
2665 <property name="text">
2666 <string notr="true">&gt;</string>
2667 </property>
2668 </widget>
2669 </item>
2670 <item row="1" column="1">
2671 <widget class="QPushButton" name="button_hash">
2672 <property name="sizePolicy">
2673 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2674 <horstretch>1</horstretch>
2675 <verstretch>1</verstretch>
2676 </sizepolicy>
2677 </property>
2678 <property name="font">
2679 <font>
2680 <pointsize>28</pointsize>
2681 </font>
2682 </property>
2683 <property name="text">
2684 <string notr="true">#</string>
2685 </property>
2686 </widget>
2687 </item>
2688 <item row="1" column="3">
2689 <widget class="QPushButton" name="button_right_bracket">
2690 <property name="sizePolicy">
2691 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2692 <horstretch>1</horstretch>
2693 <verstretch>1</verstretch>
2694 </sizepolicy>
2695 </property>
2696 <property name="font">
2697 <font>
2698 <pointsize>28</pointsize>
2699 </font>
2700 </property>
2701 <property name="text">
2702 <string notr="true">]</string>
2703 </property>
2704 </widget>
2705 </item>
2706 <item row="1" column="4">
2707 <widget class="QPushButton" name="button_dollar">
2708 <property name="sizePolicy">
2709 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2710 <horstretch>1</horstretch>
2711 <verstretch>1</verstretch>
2712 </sizepolicy>
2713 </property>
2714 <property name="font">
2715 <font>
2716 <pointsize>28</pointsize>
2717 </font>
2718 </property>
2719 <property name="text">
2720 <string notr="true">$</string>
2721 </property>
2722 </widget>
2723 </item>
2724 <item row="1" column="2">
2725 <widget class="QPushButton" name="button_left_bracket">
2726 <property name="sizePolicy">
2727 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2728 <horstretch>1</horstretch>
2729 <verstretch>1</verstretch>
2730 </sizepolicy>
2731 </property>
2732 <property name="font">
2733 <font>
2734 <pointsize>28</pointsize>
2735 </font>
2736 </property>
2737 <property name="text">
2738 <string notr="true">[</string>
2739 </property>
2740 </widget>
2741 </item>
2742 <item row="1" column="6">
2743 <widget class="QPushButton" name="button_circumflex">
2744 <property name="sizePolicy">
2745 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2746 <horstretch>1</horstretch>
2747 <verstretch>1</verstretch>
2748 </sizepolicy>
2749 </property>
2750 <property name="font">
2751 <font>
2752 <pointsize>28</pointsize>
2753 </font>
2754 </property>
2755 <property name="text">
2756 <string notr="true">^</string>
2757 </property>
2758 </widget>
2759 </item>
2760 <item row="1" column="5">
2761 <widget class="QPushButton" name="button_percent">
2762 <property name="sizePolicy">
2763 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2764 <horstretch>1</horstretch>
2765 <verstretch>1</verstretch>
2766 </sizepolicy>
2767 </property>
2768 <property name="font">
2769 <font>
2770 <pointsize>28</pointsize>
2771 </font>
2772 </property>
2773 <property name="text">
2774 <string notr="true">%</string>
2775 </property>
2776 </widget>
2777 </item>
2778 <item row="5" column="3" colspan="9">
2779 <widget class="QPushButton" name="button_space_shift">
2780 <property name="sizePolicy">
2781 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2782 <horstretch>1</horstretch>
2783 <verstretch>1</verstretch>
2784 </sizepolicy>
2785 </property>
2786 <property name="font">
2787 <font>
2788 <pointsize>18</pointsize>
2789 </font>
2790 </property>
2791 <property name="text">
2792 <string notr="true">Space</string>
2793 </property>
2794 </widget>
2795 </item>
2796 <item row="1" column="12">
2797 <widget class="QPushButton" name="button_backspace_shift">
2798 <property name="sizePolicy">
2799 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2800 <horstretch>1</horstretch>
2801 <verstretch>1</verstretch>
2802 </sizepolicy>
2803 </property>
2804 <property name="font">
2805 <font>
2806 <pointsize>18</pointsize>
2807 </font>
2808 </property>
2809 <property name="text">
2810 <string notr="true"/>
2811 </property>
2812 </widget>
2813 </item>
2814 <item row="1" column="0">
2815 <spacer name="horizontalSpacer_33">
2816 <property name="orientation">
2817 <enum>Qt::Horizontal</enum>
2818 </property>
2819 <property name="sizeHint" stdset="0">
2820 <size>
2821 <width>40</width>
2822 <height>20</height>
2823 </size>
2824 </property>
2825 </spacer>
2826 </item>
2827 <item row="0" column="1">
2828 <spacer name="verticalSpacer_6">
2829 <property name="orientation">
2830 <enum>Qt::Vertical</enum>
2831 </property>
2832 <property name="sizeHint" stdset="0">
2833 <size>
2834 <width>20</width>
2835 <height>0</height>
2836 </size>
2837 </property>
2838 </spacer>
2839 </item>
2840 <item row="1" column="13">
2841 <spacer name="horizontalSpacer_34">
2842 <property name="orientation">
2843 <enum>Qt::Horizontal</enum>
2844 </property>
2845 <property name="sizeHint" stdset="0">
2846 <size>
2847 <width>40</width>
2848 <height>20</height>
2849 </size>
2850 </property>
2851 </spacer>
2852 </item>
2853 </layout>
2854 </item>
2855 </layout>
2856 </widget>
2857 <widget class="QWidget" name="numOSK">
2858 <layout class="QVBoxLayout" name="graphicsTabVerticalLayout">
2859 <property name="leftMargin">
2860 <number>0</number>
2861 </property>
2862 <property name="topMargin">
2863 <number>0</number>
2864 </property>
2865 <property name="rightMargin">
2866 <number>0</number>
2867 </property>
2868 <property name="bottomMargin">
2869 <number>0</number>
2870 </property>
2871 <item>
2872 <layout class="QGridLayout" name="kbOSKnum" rowstretch="18,63,63,63,63,10,70" columnstretch="54,307,186,186,186,120,187,54">
2873 <property name="leftMargin">
2874 <number>0</number>
2875 </property>
2876 <property name="rightMargin">
2877 <number>0</number>
2878 </property>
2879 <property name="spacing">
2880 <number>0</number>
2881 </property>
2882 <item row="1" column="5">
2883 <widget class="QPushButton" name="button_backspace_num">
2884 <property name="sizePolicy">
2885 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
2886 <horstretch>1</horstretch>
2887 <verstretch>1</verstretch>
2888 </sizepolicy>
2889 </property>
2890 <property name="font">
2891 <font>
2892 <pointsize>18</pointsize>
2893 </font>
2894 </property>
2895 <property name="text">
2896 <string notr="true"/>
2897 </property>
2898 </widget>
2899 </item>
2900 <item row="1" column="6">
2901 <spacer name="horizontalSpacer_35">
2902 <property name="orientation">
2903 <enum>Qt::Horizontal</enum>
2904 </property>
2905 <property name="sizeHint" stdset="0">
2906 <size>
2907 <width>40</width>
2908 <height>20</height>
2909 </size>
2910 </property>
2911 </spacer>
2912 </item>
2913 <item row="1" column="1">
2914 <spacer name="horizontalSpacer_36">
2915 <property name="orientation">
2916 <enum>Qt::Horizontal</enum>
2917 </property>
2918 <property name="sizeHint" stdset="0">
2919 <size>
2920 <width>40</width>
2921 <height>20</height>
2922 </size>
2923 </property>
2924 </spacer>
2925 </item>
2926 <item row="0" column="2">
2927 <spacer name="verticalSpacer_7">
2928 <property name="orientation">
2929 <enum>Qt::Vertical</enum>
2930 </property>
2931 <property name="sizeHint" stdset="0">
2932 <size>
2933 <width>20</width>
2934 <height>0</height>
2935 </size>
2936 </property>
2937 </spacer>
2938 </item>
2939 <item row="6" column="1" colspan="6">
2940 <widget class="QWidget" name="legendOSKnum" native="true">
2941 <layout class="QHBoxLayout" name="horizontalLayout_6" stretch="25,70,601,25,12,22,41,25,12,22,41,29,12,69,37,29,12,56,30">
2942 <property name="spacing">
2943 <number>0</number>
2944 </property>
2945 <property name="leftMargin">
2946 <number>0</number>
2947 </property>
2948 <property name="topMargin">
2949 <number>0</number>
2950 </property>
2951 <property name="rightMargin">
2952 <number>0</number>
2953 </property>
2954 <property name="bottomMargin">
2955 <number>0</number>
2956 </property>
2957 <item>
2958 <spacer name="horizontalSpacer_48">
2959 <property name="orientation">
2960 <enum>Qt::Horizontal</enum>
2961 </property>
2962 <property name="sizeHint" stdset="0">
2963 <size>
2964 <width>40</width>
2965 <height>20</height>
2966 </size>
2967 </property>
2968 </spacer>
2969 </item>
2970 <item>
2971 <widget class="QWidget" name="icon_controller_num" native="true">
2972 <property name="styleSheet">
2973 <string notr="true"/>
2974 </property>
2975 </widget>
2976 </item>
2977 <item>
2978 <spacer name="horizontalSpacer_38">
2979 <property name="orientation">
2980 <enum>Qt::Horizontal</enum>
2981 </property>
2982 <property name="sizeHint" stdset="0">
2983 <size>
2984 <width>0</width>
2985 <height>20</height>
2986 </size>
2987 </property>
2988 </spacer>
2989 </item>
2990 <item>
2991 <widget class="QWidget" name="button_L_num" native="true"/>
2992 </item>
2993 <item>
2994 <spacer name="horizontalSpacer_39">
2995 <property name="orientation">
2996 <enum>Qt::Horizontal</enum>
2997 </property>
2998 <property name="sizeHint" stdset="0">
2999 <size>
3000 <width>0</width>
3001 <height>20</height>
3002 </size>
3003 </property>
3004 </spacer>
3005 </item>
3006 <item>
3007 <widget class="QWidget" name="arrow_left_num" native="true"/>
3008 </item>
3009 <item>
3010 <spacer name="horizontalSpacer_40">
3011 <property name="orientation">
3012 <enum>Qt::Horizontal</enum>
3013 </property>
3014 <property name="sizeHint" stdset="0">
3015 <size>
3016 <width>0</width>
3017 <height>20</height>
3018 </size>
3019 </property>
3020 </spacer>
3021 </item>
3022 <item>
3023 <widget class="QWidget" name="button_R_num" native="true"/>
3024 </item>
3025 <item>
3026 <spacer name="horizontalSpacer_41">
3027 <property name="orientation">
3028 <enum>Qt::Horizontal</enum>
3029 </property>
3030 <property name="sizeHint" stdset="0">
3031 <size>
3032 <width>0</width>
3033 <height>20</height>
3034 </size>
3035 </property>
3036 </spacer>
3037 </item>
3038 <item>
3039 <widget class="QWidget" name="arrow_right_num" native="true"/>
3040 </item>
3041 <item>
3042 <spacer name="horizontalSpacer_42">
3043 <property name="orientation">
3044 <enum>Qt::Horizontal</enum>
3045 </property>
3046 <property name="sizeHint" stdset="0">
3047 <size>
3048 <width>0</width>
3049 <height>20</height>
3050 </size>
3051 </property>
3052 </spacer>
3053 </item>
3054 <item>
3055 <widget class="QWidget" name="button_X_num" native="true"/>
3056 </item>
3057 <item>
3058 <spacer name="horizontalSpacer_43">
3059 <property name="orientation">
3060 <enum>Qt::Horizontal</enum>
3061 </property>
3062 <property name="sizeHint" stdset="0">
3063 <size>
3064 <width>0</width>
3065 <height>20</height>
3066 </size>
3067 </property>
3068 </spacer>
3069 </item>
3070 <item>
3071 <widget class="QLabel" name="label_cancel_num">
3072 <property name="font">
3073 <font>
3074 <pointsize>18</pointsize>
3075 </font>
3076 </property>
3077 <property name="text">
3078 <string notr="true">Cancel</string>
3079 </property>
3080 </widget>
3081 </item>
3082 <item>
3083 <spacer name="horizontalSpacer_44">
3084 <property name="orientation">
3085 <enum>Qt::Horizontal</enum>
3086 </property>
3087 <property name="sizeHint" stdset="0">
3088 <size>
3089 <width>0</width>
3090 <height>20</height>
3091 </size>
3092 </property>
3093 </spacer>
3094 </item>
3095 <item>
3096 <widget class="QWidget" name="button_A_num" native="true"/>
3097 </item>
3098 <item>
3099 <spacer name="horizontalSpacer_45">
3100 <property name="orientation">
3101 <enum>Qt::Horizontal</enum>
3102 </property>
3103 <property name="sizeHint" stdset="0">
3104 <size>
3105 <width>0</width>
3106 <height>20</height>
3107 </size>
3108 </property>
3109 </spacer>
3110 </item>
3111 <item>
3112 <widget class="QLabel" name="label_enter_num">
3113 <property name="font">
3114 <font>
3115 <pointsize>18</pointsize>
3116 </font>
3117 </property>
3118 <property name="text">
3119 <string notr="true">Enter</string>
3120 </property>
3121 </widget>
3122 </item>
3123 <item>
3124 <spacer name="horizontalSpacer_46">
3125 <property name="orientation">
3126 <enum>Qt::Horizontal</enum>
3127 </property>
3128 <property name="sizeHint" stdset="0">
3129 <size>
3130 <width>0</width>
3131 <height>20</height>
3132 </size>
3133 </property>
3134 </spacer>
3135 </item>
3136 </layout>
3137 </widget>
3138 </item>
3139 <item row="2" column="4">
3140 <widget class="QPushButton" name="button_6_num">
3141 <property name="sizePolicy">
3142 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
3143 <horstretch>1</horstretch>
3144 <verstretch>1</verstretch>
3145 </sizepolicy>
3146 </property>
3147 <property name="font">
3148 <font>
3149 <pointsize>28</pointsize>
3150 </font>
3151 </property>
3152 <property name="text">
3153 <string notr="true">6</string>
3154 </property>
3155 </widget>
3156 </item>
3157 <item row="2" column="2">
3158 <widget class="QPushButton" name="button_4_num">
3159 <property name="sizePolicy">
3160 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
3161 <horstretch>1</horstretch>
3162 <verstretch>1</verstretch>
3163 </sizepolicy>
3164 </property>
3165 <property name="font">
3166 <font>
3167 <pointsize>28</pointsize>
3168 </font>
3169 </property>
3170 <property name="text">
3171 <string notr="true">4</string>
3172 </property>
3173 </widget>
3174 </item>
3175 <item row="3" column="4">
3176 <widget class="QPushButton" name="button_9_num">
3177 <property name="sizePolicy">
3178 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
3179 <horstretch>1</horstretch>
3180 <verstretch>1</verstretch>
3181 </sizepolicy>
3182 </property>
3183 <property name="font">
3184 <font>
3185 <pointsize>28</pointsize>
3186 </font>
3187 </property>
3188 <property name="text">
3189 <string notr="true">9</string>
3190 </property>
3191 </widget>
3192 </item>
3193 <item row="2" column="3">
3194 <widget class="QPushButton" name="button_5_num">
3195 <property name="sizePolicy">
3196 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
3197 <horstretch>1</horstretch>
3198 <verstretch>1</verstretch>
3199 </sizepolicy>
3200 </property>
3201 <property name="font">
3202 <font>
3203 <pointsize>28</pointsize>
3204 </font>
3205 </property>
3206 <property name="text">
3207 <string notr="true">5</string>
3208 </property>
3209 </widget>
3210 </item>
3211 <item row="2" column="5" rowspan="3">
3212 <widget class="QPushButton" name="button_ok_num">
3213 <property name="sizePolicy">
3214 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
3215 <horstretch>1</horstretch>
3216 <verstretch>1</verstretch>
3217 </sizepolicy>
3218 </property>
3219 <property name="font">
3220 <font>
3221 <pointsize>18</pointsize>
3222 </font>
3223 </property>
3224 <property name="text">
3225 <string notr="true">OK</string>
3226 </property>
3227 </widget>
3228 </item>
3229 <item row="3" column="2">
3230 <widget class="QPushButton" name="button_7_num">
3231 <property name="sizePolicy">
3232 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
3233 <horstretch>1</horstretch>
3234 <verstretch>1</verstretch>
3235 </sizepolicy>
3236 </property>
3237 <property name="font">
3238 <font>
3239 <pointsize>28</pointsize>
3240 </font>
3241 </property>
3242 <property name="text">
3243 <string notr="true">7</string>
3244 </property>
3245 </widget>
3246 </item>
3247 <item row="3" column="3">
3248 <widget class="QPushButton" name="button_8_num">
3249 <property name="sizePolicy">
3250 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
3251 <horstretch>1</horstretch>
3252 <verstretch>1</verstretch>
3253 </sizepolicy>
3254 </property>
3255 <property name="font">
3256 <font>
3257 <pointsize>28</pointsize>
3258 </font>
3259 </property>
3260 <property name="text">
3261 <string notr="true">8</string>
3262 </property>
3263 </widget>
3264 </item>
3265 <item row="1" column="3">
3266 <widget class="QPushButton" name="button_2_num">
3267 <property name="sizePolicy">
3268 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
3269 <horstretch>1</horstretch>
3270 <verstretch>1</verstretch>
3271 </sizepolicy>
3272 </property>
3273 <property name="font">
3274 <font>
3275 <pointsize>28</pointsize>
3276 </font>
3277 </property>
3278 <property name="text">
3279 <string notr="true">2</string>
3280 </property>
3281 </widget>
3282 </item>
3283 <item row="1" column="2">
3284 <widget class="QPushButton" name="button_1_num">
3285 <property name="sizePolicy">
3286 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
3287 <horstretch>1</horstretch>
3288 <verstretch>1</verstretch>
3289 </sizepolicy>
3290 </property>
3291 <property name="font">
3292 <font>
3293 <pointsize>28</pointsize>
3294 </font>
3295 </property>
3296 <property name="text">
3297 <string notr="true">1</string>
3298 </property>
3299 </widget>
3300 </item>
3301 <item row="4" column="3">
3302 <widget class="QPushButton" name="button_0_num">
3303 <property name="sizePolicy">
3304 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
3305 <horstretch>1</horstretch>
3306 <verstretch>1</verstretch>
3307 </sizepolicy>
3308 </property>
3309 <property name="font">
3310 <font>
3311 <pointsize>28</pointsize>
3312 </font>
3313 </property>
3314 <property name="text">
3315 <string notr="true">0</string>
3316 </property>
3317 </widget>
3318 </item>
3319 <item row="1" column="4">
3320 <widget class="QPushButton" name="button_3_num">
3321 <property name="sizePolicy">
3322 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
3323 <horstretch>1</horstretch>
3324 <verstretch>1</verstretch>
3325 </sizepolicy>
3326 </property>
3327 <property name="font">
3328 <font>
3329 <pointsize>28</pointsize>
3330 </font>
3331 </property>
3332 <property name="text">
3333 <string notr="true">3</string>
3334 </property>
3335 </widget>
3336 </item>
3337 <item row="1" column="0">
3338 <spacer name="horizontalSpacer_37">
3339 <property name="orientation">
3340 <enum>Qt::Horizontal</enum>
3341 </property>
3342 <property name="sizeHint" stdset="0">
3343 <size>
3344 <width>40</width>
3345 <height>20</height>
3346 </size>
3347 </property>
3348 </spacer>
3349 </item>
3350 <item row="1" column="7">
3351 <spacer name="horizontalSpacer_47">
3352 <property name="orientation">
3353 <enum>Qt::Horizontal</enum>
3354 </property>
3355 <property name="sizeHint" stdset="0">
3356 <size>
3357 <width>40</width>
3358 <height>20</height>
3359 </size>
3360 </property>
3361 </spacer>
3362 </item>
3363 <item row="5" column="3">
3364 <spacer name="verticalSpacer_8">
3365 <property name="orientation">
3366 <enum>Qt::Vertical</enum>
3367 </property>
3368 <property name="sizeHint" stdset="0">
3369 <size>
3370 <width>20</width>
3371 <height>0</height>
3372 </size>
3373 </property>
3374 </spacer>
3375 </item>
3376 </layout>
3377 </item>
3378 </layout>
3379 </widget>
3380 </widget>
3381 </item>
3382 </layout>
3383 </widget>
3384 </item>
3385 </layout>
3386 </widget>
3387 <tabstops>
3388 <tabstop>button_1</tabstop>
3389 <tabstop>button_2</tabstop>
3390 <tabstop>button_3</tabstop>
3391 <tabstop>button_4</tabstop>
3392 <tabstop>button_5</tabstop>
3393 <tabstop>button_6</tabstop>
3394 <tabstop>button_7</tabstop>
3395 <tabstop>button_8</tabstop>
3396 <tabstop>button_9</tabstop>
3397 <tabstop>button_0</tabstop>
3398 <tabstop>button_minus</tabstop>
3399 <tabstop>button_backspace</tabstop>
3400 <tabstop>button_q</tabstop>
3401 <tabstop>button_w</tabstop>
3402 <tabstop>button_e</tabstop>
3403 <tabstop>button_r</tabstop>
3404 <tabstop>button_t</tabstop>
3405 <tabstop>button_y</tabstop>
3406 <tabstop>button_u</tabstop>
3407 <tabstop>button_i</tabstop>
3408 <tabstop>button_o</tabstop>
3409 <tabstop>button_p</tabstop>
3410 <tabstop>button_slash</tabstop>
3411 <tabstop>button_return</tabstop>
3412 <tabstop>button_a</tabstop>
3413 <tabstop>button_s</tabstop>
3414 <tabstop>button_d</tabstop>
3415 <tabstop>button_f</tabstop>
3416 <tabstop>button_g</tabstop>
3417 <tabstop>button_h</tabstop>
3418 <tabstop>button_j</tabstop>
3419 <tabstop>button_k</tabstop>
3420 <tabstop>button_l</tabstop>
3421 <tabstop>button_colon</tabstop>
3422 <tabstop>button_apostrophe</tabstop>
3423 <tabstop>button_z</tabstop>
3424 <tabstop>button_x</tabstop>
3425 <tabstop>button_c</tabstop>
3426 <tabstop>button_v</tabstop>
3427 <tabstop>button_b</tabstop>
3428 <tabstop>button_n</tabstop>
3429 <tabstop>button_m</tabstop>
3430 <tabstop>button_comma</tabstop>
3431 <tabstop>button_dot</tabstop>
3432 <tabstop>button_question</tabstop>
3433 <tabstop>button_exclamation</tabstop>
3434 <tabstop>button_ok</tabstop>
3435 <tabstop>button_shift</tabstop>
3436 <tabstop>button_space</tabstop>
3437 <tabstop>button_hash</tabstop>
3438 <tabstop>button_left_bracket</tabstop>
3439 <tabstop>button_right_bracket</tabstop>
3440 <tabstop>button_dollar</tabstop>
3441 <tabstop>button_percent</tabstop>
3442 <tabstop>button_circumflex</tabstop>
3443 <tabstop>button_ampersand</tabstop>
3444 <tabstop>button_asterisk</tabstop>
3445 <tabstop>button_left_parenthesis</tabstop>
3446 <tabstop>button_right_parenthesis</tabstop>
3447 <tabstop>button_underscore</tabstop>
3448 <tabstop>button_backspace_shift</tabstop>
3449 <tabstop>button_q_shift</tabstop>
3450 <tabstop>button_w_shift</tabstop>
3451 <tabstop>button_e_shift</tabstop>
3452 <tabstop>button_r_shift</tabstop>
3453 <tabstop>button_t_shift</tabstop>
3454 <tabstop>button_y_shift</tabstop>
3455 <tabstop>button_u_shift</tabstop>
3456 <tabstop>button_i_shift</tabstop>
3457 <tabstop>button_o_shift</tabstop>
3458 <tabstop>button_p_shift</tabstop>
3459 <tabstop>button_at</tabstop>
3460 <tabstop>button_return_shift</tabstop>
3461 <tabstop>button_a_shift</tabstop>
3462 <tabstop>button_s_shift</tabstop>
3463 <tabstop>button_d_shift</tabstop>
3464 <tabstop>button_f_shift</tabstop>
3465 <tabstop>button_g_shift</tabstop>
3466 <tabstop>button_h_shift</tabstop>
3467 <tabstop>button_j_shift</tabstop>
3468 <tabstop>button_k_shift</tabstop>
3469 <tabstop>button_l_shift</tabstop>
3470 <tabstop>button_semicolon</tabstop>
3471 <tabstop>button_quotation</tabstop>
3472 <tabstop>button_z_shift</tabstop>
3473 <tabstop>button_x_shift</tabstop>
3474 <tabstop>button_c_shift</tabstop>
3475 <tabstop>button_v_shift</tabstop>
3476 <tabstop>button_b_shift</tabstop>
3477 <tabstop>button_n_shift</tabstop>
3478 <tabstop>button_m_shift</tabstop>
3479 <tabstop>button_less_than</tabstop>
3480 <tabstop>button_greater_than</tabstop>
3481 <tabstop>button_plus</tabstop>
3482 <tabstop>button_equal</tabstop>
3483 <tabstop>button_ok_shift</tabstop>
3484 <tabstop>button_shift_shift</tabstop>
3485 <tabstop>button_space_shift</tabstop>
3486 <tabstop>button_1_num</tabstop>
3487 <tabstop>button_2_num</tabstop>
3488 <tabstop>button_3_num</tabstop>
3489 <tabstop>button_backspace_num</tabstop>
3490 <tabstop>button_4_num</tabstop>
3491 <tabstop>button_5_num</tabstop>
3492 <tabstop>button_6_num</tabstop>
3493 <tabstop>button_ok_num</tabstop>
3494 <tabstop>button_7_num</tabstop>
3495 <tabstop>button_8_num</tabstop>
3496 <tabstop>button_9_num</tabstop>
3497 <tabstop>button_0_num</tabstop>
3498 </tabstops>
3499 <resources>
3500 <include location="../../../dist/icons/overlay/overlay.qrc"/>
3501 </resources>
3502 <connections/>
3503</ui>
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 15c09e0ad..9c7daeac7 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -29,10 +29,10 @@
29#include "common/microprofile.h" 29#include "common/microprofile.h"
30#include "common/scm_rev.h" 30#include "common/scm_rev.h"
31#include "common/scope_exit.h" 31#include "common/scope_exit.h"
32#include "common/settings.h"
32#include "core/core.h" 33#include "core/core.h"
33#include "core/frontend/framebuffer_layout.h" 34#include "core/frontend/framebuffer_layout.h"
34#include "core/hle/kernel/process.h" 35#include "core/hle/kernel/process.h"
35#include "core/settings.h"
36#include "input_common/keyboard.h" 36#include "input_common/keyboard.h"
37#include "input_common/main.h" 37#include "input_common/main.h"
38#include "input_common/mouse/mouse_input.h" 38#include "input_common/mouse/mouse_input.h"
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index ff6a6e961..d1b8c4fc9 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -29,9 +29,10 @@ Config::~Config() {
29} 29}
30 30
31const std::array<int, Settings::NativeButton::NumButtons> Config::default_buttons = { 31const std::array<int, Settings::NativeButton::NumButtons> Config::default_buttons = {
32 Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X, Qt::Key_3, Qt::Key_4, Qt::Key_Q, 32 Qt::Key_C, Qt::Key_X, Qt::Key_V, Qt::Key_Z, Qt::Key_F,
33 Qt::Key_W, Qt::Key_1, Qt::Key_2, Qt::Key_N, Qt::Key_M, Qt::Key_F, Qt::Key_T, 33 Qt::Key_G, Qt::Key_Q, Qt::Key_E, Qt::Key_R, Qt::Key_T,
34 Qt::Key_H, Qt::Key_G, Qt::Key_D, Qt::Key_C, Qt::Key_B, Qt::Key_V, 34 Qt::Key_M, Qt::Key_N, Qt::Key_Left, Qt::Key_Up, Qt::Key_Right,
35 Qt::Key_Down, Qt::Key_Q, Qt::Key_E, 0, 0,
35}; 36};
36 37
37const std::array<int, Settings::NativeMotion::NumMotions> Config::default_motions = { 38const std::array<int, Settings::NativeMotion::NumMotions> Config::default_motions = {
@@ -41,10 +42,10 @@ const std::array<int, Settings::NativeMotion::NumMotions> Config::default_motion
41 42
42const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> Config::default_analogs{{ 43const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> Config::default_analogs{{
43 { 44 {
44 Qt::Key_Up, 45 Qt::Key_W,
45 Qt::Key_Down, 46 Qt::Key_S,
46 Qt::Key_Left, 47 Qt::Key_A,
47 Qt::Key_Right, 48 Qt::Key_D,
48 }, 49 },
49 { 50 {
50 Qt::Key_I, 51 Qt::Key_I,
@@ -55,8 +56,8 @@ const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> Config:
55}}; 56}};
56 57
57const std::array<int, 2> Config::default_stick_mod = { 58const std::array<int, 2> Config::default_stick_mod = {
58 Qt::Key_E, 59 Qt::Key_Shift,
59 Qt::Key_R, 60 0,
60}; 61};
61 62
62const std::array<int, Settings::NativeMouseButton::NumMouseButtons> Config::default_mouse_buttons = 63const std::array<int, Settings::NativeMouseButton::NumMouseButtons> Config::default_mouse_buttons =
@@ -641,6 +642,8 @@ void Config::ReadDebuggingValues() {
641 ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool(); 642 ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool();
642 Settings::values.extended_logging = 643 Settings::values.extended_logging =
643 ReadSetting(QStringLiteral("extended_logging"), false).toBool(); 644 ReadSetting(QStringLiteral("extended_logging"), false).toBool();
645 Settings::values.use_debug_asserts =
646 ReadSetting(QStringLiteral("use_debug_asserts"), false).toBool();
644 Settings::values.use_auto_stub = ReadSetting(QStringLiteral("use_auto_stub"), false).toBool(); 647 Settings::values.use_auto_stub = ReadSetting(QStringLiteral("use_auto_stub"), false).toBool();
645 648
646 qt_config->endGroup(); 649 qt_config->endGroup();
@@ -1245,6 +1248,7 @@ void Config::SaveDebuggingValues() {
1245 WriteSetting(QStringLiteral("dump_exefs"), Settings::values.dump_exefs, false); 1248 WriteSetting(QStringLiteral("dump_exefs"), Settings::values.dump_exefs, false);
1246 WriteSetting(QStringLiteral("dump_nso"), Settings::values.dump_nso, false); 1249 WriteSetting(QStringLiteral("dump_nso"), Settings::values.dump_nso, false);
1247 WriteSetting(QStringLiteral("quest_flag"), Settings::values.quest_flag, false); 1250 WriteSetting(QStringLiteral("quest_flag"), Settings::values.quest_flag, false);
1251 WriteSetting(QStringLiteral("use_debug_asserts"), Settings::values.use_debug_asserts, false);
1248 WriteSetting(QStringLiteral("disable_macro_jit"), Settings::values.disable_macro_jit, false); 1252 WriteSetting(QStringLiteral("disable_macro_jit"), Settings::values.disable_macro_jit, false);
1249 1253
1250 qt_config->endGroup(); 1254 qt_config->endGroup();
@@ -1613,7 +1617,7 @@ void Config::Reload() {
1613 ReadValues(); 1617 ReadValues();
1614 // To apply default value changes 1618 // To apply default value changes
1615 SaveValues(); 1619 SaveValues();
1616 Settings::Apply(Core::System::GetInstance()); 1620 Core::System::GetInstance().ApplySettings();
1617} 1621}
1618 1622
1619void Config::Save() { 1623void Config::Save() {
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index 949c4eb13..5a2c026b3 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -9,7 +9,7 @@
9#include <string> 9#include <string>
10#include <QMetaType> 10#include <QMetaType>
11#include <QVariant> 11#include <QVariant>
12#include "core/settings.h" 12#include "common/settings.h"
13#include "yuzu/uisettings.h" 13#include "yuzu/uisettings.h"
14 14
15class QSettings; 15class QSettings;
@@ -131,6 +131,6 @@ private:
131 bool global; 131 bool global;
132}; 132};
133 133
134// These metatype declarations cannot be in core/settings.h because core is devoid of QT 134// These metatype declarations cannot be in common/settings.h because core is devoid of QT
135Q_DECLARE_METATYPE(Settings::RendererBackend); 135Q_DECLARE_METATYPE(Settings::RendererBackend);
136Q_DECLARE_METATYPE(Settings::GPUAccuracy); 136Q_DECLARE_METATYPE(Settings::GPUAccuracy);
diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp
index 18482795c..89be4a62d 100644
--- a/src/yuzu/configuration/configuration_shared.cpp
+++ b/src/yuzu/configuration/configuration_shared.cpp
@@ -6,7 +6,7 @@
6#include <QComboBox> 6#include <QComboBox>
7#include <QObject> 7#include <QObject>
8#include <QString> 8#include <QString>
9#include "core/settings.h" 9#include "common/settings.h"
10#include "yuzu/configuration/configuration_shared.h" 10#include "yuzu/configuration/configuration_shared.h"
11#include "yuzu/configuration/configure_per_game.h" 11#include "yuzu/configuration/configure_per_game.h"
12 12
diff --git a/src/yuzu/configuration/configuration_shared.h b/src/yuzu/configuration/configuration_shared.h
index 312b9e549..5b344cdbd 100644
--- a/src/yuzu/configuration/configuration_shared.h
+++ b/src/yuzu/configuration/configuration_shared.h
@@ -7,7 +7,7 @@
7#include <QCheckBox> 7#include <QCheckBox>
8#include <QComboBox> 8#include <QComboBox>
9#include <QString> 9#include <QString>
10#include "core/settings.h" 10#include "common/settings.h"
11 11
12namespace ConfigurationShared { 12namespace ConfigurationShared {
13 13
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp
index db9518798..f9507e228 100644
--- a/src/yuzu/configuration/configure_audio.cpp
+++ b/src/yuzu/configuration/configure_audio.cpp
@@ -8,8 +8,8 @@
8 8
9#include "audio_core/sink.h" 9#include "audio_core/sink.h"
10#include "audio_core/sink_details.h" 10#include "audio_core/sink_details.h"
11#include "common/settings.h"
11#include "core/core.h" 12#include "core/core.h"
12#include "core/settings.h"
13#include "ui_configure_audio.h" 13#include "ui_configure_audio.h"
14#include "yuzu/configuration/configuration_shared.h" 14#include "yuzu/configuration/configuration_shared.h"
15#include "yuzu/configuration/configure_audio.h" 15#include "yuzu/configuration/configure_audio.h"
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
index d055cbd60..4f99bc80f 100644
--- a/src/yuzu/configuration/configure_cpu.cpp
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -7,8 +7,8 @@
7 7
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "common/settings.h"
10#include "core/core.h" 11#include "core/core.h"
11#include "core/settings.h"
12#include "ui_configure_cpu.h" 12#include "ui_configure_cpu.h"
13#include "yuzu/configuration/configure_cpu.h" 13#include "yuzu/configuration/configure_cpu.h"
14 14
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h
index 3c5683d81..ef77b2e7e 100644
--- a/src/yuzu/configuration/configure_cpu.h
+++ b/src/yuzu/configuration/configure_cpu.h
@@ -6,7 +6,7 @@
6 6
7#include <memory> 7#include <memory>
8#include <QWidget> 8#include <QWidget>
9#include "core/settings.h" 9#include "common/settings.h"
10 10
11namespace Ui { 11namespace Ui {
12class ConfigureCpu; 12class ConfigureCpu;
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp
index 3385b2cf6..c925c023c 100644
--- a/src/yuzu/configuration/configure_cpu_debug.cpp
+++ b/src/yuzu/configuration/configure_cpu_debug.cpp
@@ -6,8 +6,8 @@
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "common/settings.h"
9#include "core/core.h" 10#include "core/core.h"
10#include "core/settings.h"
11#include "ui_configure_cpu_debug.h" 11#include "ui_configure_cpu_debug.h"
12#include "yuzu/configuration/configure_cpu_debug.h" 12#include "yuzu/configuration/configure_cpu_debug.h"
13 13
diff --git a/src/yuzu/configuration/configure_cpu_debug.h b/src/yuzu/configuration/configure_cpu_debug.h
index c9941ef3b..10de55099 100644
--- a/src/yuzu/configuration/configure_cpu_debug.h
+++ b/src/yuzu/configuration/configure_cpu_debug.h
@@ -6,7 +6,7 @@
6 6
7#include <memory> 7#include <memory>
8#include <QWidget> 8#include <QWidget>
9#include "core/settings.h" 9#include "common/settings.h"
10 10
11namespace Ui { 11namespace Ui {
12class ConfigureCpuDebug; 12class ConfigureCpuDebug;
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index 2a5b3f5e7..6730eb356 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -7,8 +7,8 @@
7#include "common/file_util.h" 7#include "common/file_util.h"
8#include "common/logging/backend.h" 8#include "common/logging/backend.h"
9#include "common/logging/filter.h" 9#include "common/logging/filter.h"
10#include "common/settings.h"
10#include "core/core.h" 11#include "core/core.h"
11#include "core/settings.h"
12#include "ui_configure_debug.h" 12#include "ui_configure_debug.h"
13#include "yuzu/configuration/configure_debug.h" 13#include "yuzu/configuration/configure_debug.h"
14#include "yuzu/debugger/console.h" 14#include "yuzu/debugger/console.h"
@@ -34,6 +34,7 @@ void ConfigureDebug::SetConfiguration() {
34 ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args)); 34 ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args));
35 ui->reporting_services->setChecked(Settings::values.reporting_services); 35 ui->reporting_services->setChecked(Settings::values.reporting_services);
36 ui->quest_flag->setChecked(Settings::values.quest_flag); 36 ui->quest_flag->setChecked(Settings::values.quest_flag);
37 ui->use_debug_asserts->setChecked(Settings::values.use_debug_asserts);
37 ui->use_auto_stub->setChecked(Settings::values.use_auto_stub); 38 ui->use_auto_stub->setChecked(Settings::values.use_auto_stub);
38 ui->enable_graphics_debugging->setEnabled(!Core::System::GetInstance().IsPoweredOn()); 39 ui->enable_graphics_debugging->setEnabled(!Core::System::GetInstance().IsPoweredOn());
39 ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug); 40 ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug);
@@ -48,14 +49,15 @@ void ConfigureDebug::ApplyConfiguration() {
48 Settings::values.program_args = ui->homebrew_args_edit->text().toStdString(); 49 Settings::values.program_args = ui->homebrew_args_edit->text().toStdString();
49 Settings::values.reporting_services = ui->reporting_services->isChecked(); 50 Settings::values.reporting_services = ui->reporting_services->isChecked();
50 Settings::values.quest_flag = ui->quest_flag->isChecked(); 51 Settings::values.quest_flag = ui->quest_flag->isChecked();
52 Settings::values.use_debug_asserts = ui->use_debug_asserts->isChecked();
51 Settings::values.use_auto_stub = ui->use_auto_stub->isChecked(); 53 Settings::values.use_auto_stub = ui->use_auto_stub->isChecked();
52 Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked(); 54 Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked();
53 Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); 55 Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
54 Settings::values.extended_logging = ui->extended_logging->isChecked(); 56 Settings::values.extended_logging = ui->extended_logging->isChecked();
55 Debugger::ToggleConsole(); 57 Debugger::ToggleConsole();
56 Log::Filter filter; 58 Common::Log::Filter filter;
57 filter.ParseFilterString(Settings::values.log_filter); 59 filter.ParseFilterString(Settings::values.log_filter);
58 Log::SetGlobalFilter(filter); 60 Common::Log::SetGlobalFilter(filter);
59} 61}
60 62
61void ConfigureDebug::changeEvent(QEvent* event) { 63void ConfigureDebug::changeEvent(QEvent* event) {
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index ae48b728c..d812858b6 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -186,6 +186,13 @@
186 </widget> 186 </widget>
187 </item> 187 </item>
188 <item> 188 <item>
189 <widget class="QCheckBox" name="use_debug_asserts">
190 <property name="text">
191 <string>Enable Debug Asserts</string>
192 </property>
193 </widget>
194 </item>
195 <item>
189 <widget class="QCheckBox" name="use_auto_stub"> 196 <widget class="QCheckBox" name="use_auto_stub">
190 <property name="text"> 197 <property name="text">
191 <string>Enable Auto-Stub</string> 198 <string>Enable Auto-Stub</string>
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index d6b17a28d..3ad40d2b3 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -5,8 +5,8 @@
5#include <QHash> 5#include <QHash>
6#include <QListWidgetItem> 6#include <QListWidgetItem>
7#include <QSignalBlocker> 7#include <QSignalBlocker>
8#include "common/settings.h"
8#include "core/core.h" 9#include "core/core.h"
9#include "core/settings.h"
10#include "ui_configure.h" 10#include "ui_configure.h"
11#include "yuzu/configuration/config.h" 11#include "yuzu/configuration/config.h"
12#include "yuzu/configuration/configure_dialog.h" 12#include "yuzu/configuration/configure_dialog.h"
@@ -55,7 +55,7 @@ void ConfigureDialog::ApplyConfiguration() {
55 ui->debugTab->ApplyConfiguration(); 55 ui->debugTab->ApplyConfiguration();
56 ui->webTab->ApplyConfiguration(); 56 ui->webTab->ApplyConfiguration();
57 ui->serviceTab->ApplyConfiguration(); 57 ui->serviceTab->ApplyConfiguration();
58 Settings::Apply(Core::System::GetInstance()); 58 Core::System::GetInstance().ApplySettings();
59 Settings::LogSettings(); 59 Settings::LogSettings();
60} 60}
61 61
diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp
index 58f644af4..006eda4b0 100644
--- a/src/yuzu/configuration/configure_filesystem.cpp
+++ b/src/yuzu/configuration/configure_filesystem.cpp
@@ -6,7 +6,7 @@
6#include <QMessageBox> 6#include <QMessageBox>
7#include "common/common_paths.h" 7#include "common/common_paths.h"
8#include "common/file_util.h" 8#include "common/file_util.h"
9#include "core/settings.h" 9#include "common/settings.h"
10#include "ui_configure_filesystem.h" 10#include "ui_configure_filesystem.h"
11#include "yuzu/configuration/configure_filesystem.h" 11#include "yuzu/configuration/configure_filesystem.h"
12#include "yuzu/uisettings.h" 12#include "yuzu/uisettings.h"
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index d4d29d422..2fa88dcec 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -4,8 +4,8 @@
4 4
5#include <QCheckBox> 5#include <QCheckBox>
6#include <QSpinBox> 6#include <QSpinBox>
7#include "common/settings.h"
7#include "core/core.h" 8#include "core/core.h"
8#include "core/settings.h"
9#include "ui_configure_general.h" 9#include "ui_configure_general.h"
10#include "yuzu/configuration/configuration_shared.h" 10#include "yuzu/configuration/configuration_shared.h"
11#include "yuzu/configuration/configure_general.h" 11#include "yuzu/configuration/configure_general.h"
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 8a2008b2a..0a7536617 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -11,8 +11,8 @@
11 11
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "common/settings.h"
14#include "core/core.h" 15#include "core/core.h"
15#include "core/settings.h"
16#include "ui_configure_graphics.h" 16#include "ui_configure_graphics.h"
17#include "video_core/vulkan_common/vulkan_instance.h" 17#include "video_core/vulkan_common/vulkan_instance.h"
18#include "video_core/vulkan_common/vulkan_library.h" 18#include "video_core/vulkan_common/vulkan_library.h"
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h
index 1fefc88eb..c162048a2 100644
--- a/src/yuzu/configuration/configure_graphics.h
+++ b/src/yuzu/configuration/configure_graphics.h
@@ -8,7 +8,7 @@
8#include <vector> 8#include <vector>
9#include <QString> 9#include <QString>
10#include <QWidget> 10#include <QWidget>
11#include "core/settings.h" 11#include "common/settings.h"
12 12
13namespace ConfigurationShared { 13namespace ConfigurationShared {
14enum class CheckState; 14enum class CheckState;
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp
index 383c7bac8..c67609b0e 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.cpp
+++ b/src/yuzu/configuration/configure_graphics_advanced.cpp
@@ -2,8 +2,8 @@
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 "common/settings.h"
5#include "core/core.h" 6#include "core/core.h"
6#include "core/settings.h"
7#include "ui_configure_graphics_advanced.h" 7#include "ui_configure_graphics_advanced.h"
8#include "yuzu/configuration/configuration_shared.h" 8#include "yuzu/configuration/configuration_shared.h"
9#include "yuzu/configuration/configure_graphics_advanced.h" 9#include "yuzu/configuration/configure_graphics_advanced.h"
diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp
index cbee51a5e..ed76fe18e 100644
--- a/src/yuzu/configuration/configure_hotkeys.cpp
+++ b/src/yuzu/configuration/configure_hotkeys.cpp
@@ -5,7 +5,7 @@
5#include <QMenu> 5#include <QMenu>
6#include <QMessageBox> 6#include <QMessageBox>
7#include <QStandardItemModel> 7#include <QStandardItemModel>
8#include "core/settings.h" 8#include "common/settings.h"
9#include "ui_configure_hotkeys.h" 9#include "ui_configure_hotkeys.h"
10#include "yuzu/configuration/config.h" 10#include "yuzu/configuration/config.h"
11#include "yuzu/configuration/configure_hotkeys.h" 11#include "yuzu/configuration/configure_hotkeys.h"
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp
index a1a0eb676..d8d3b83dc 100644
--- a/src/yuzu/configuration/configure_input_advanced.cpp
+++ b/src/yuzu/configuration/configure_input_advanced.cpp
@@ -3,8 +3,8 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <QColorDialog> 5#include <QColorDialog>
6#include "common/settings.h"
6#include "core/core.h" 7#include "core/core.h"
7#include "core/settings.h"
8#include "ui_configure_input_advanced.h" 8#include "ui_configure_input_advanced.h"
9#include "yuzu/configuration/configure_input_advanced.h" 9#include "yuzu/configuration/configure_input_advanced.h"
10 10
diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h
index efe953fbc..c7d101682 100644
--- a/src/yuzu/configuration/configure_input_player.h
+++ b/src/yuzu/configuration/configure_input_player.h
@@ -14,7 +14,7 @@
14#include <QWidget> 14#include <QWidget>
15 15
16#include "common/param_package.h" 16#include "common/param_package.h"
17#include "core/settings.h" 17#include "common/settings.h"
18#include "ui_configure_input.h" 18#include "ui_configure_input.h"
19 19
20class QCheckBox; 20class QCheckBox;
diff --git a/src/yuzu/configuration/configure_input_player_widget.h b/src/yuzu/configuration/configure_input_player_widget.h
index 91c3343f1..51bb84eb6 100644
--- a/src/yuzu/configuration/configure_input_player_widget.h
+++ b/src/yuzu/configuration/configure_input_player_widget.h
@@ -7,8 +7,8 @@
7#include <array> 7#include <array>
8#include <QFrame> 8#include <QFrame>
9#include <QPointer> 9#include <QPointer>
10#include "common/settings.h"
10#include "core/frontend/input.h" 11#include "core/frontend/input.h"
11#include "core/settings.h"
12 12
13class QLabel; 13class QLabel;
14 14
diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp
index 083d1ea43..6a5d625df 100644
--- a/src/yuzu/configuration/configure_motion_touch.cpp
+++ b/src/yuzu/configuration/configure_motion_touch.cpp
@@ -14,7 +14,7 @@
14#include <QVBoxLayout> 14#include <QVBoxLayout>
15 15
16#include "common/logging/log.h" 16#include "common/logging/log.h"
17#include "core/settings.h" 17#include "common/settings.h"
18#include "input_common/main.h" 18#include "input_common/main.h"
19#include "input_common/udp/client.h" 19#include "input_common/udp/client.h"
20#include "input_common/udp/udp.h" 20#include "input_common/udp/udp.h"
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp
index f598513df..bd91ebc42 100644
--- a/src/yuzu/configuration/configure_per_game.cpp
+++ b/src/yuzu/configuration/configure_per_game.cpp
@@ -57,7 +57,7 @@ void ConfigurePerGame::ApplyConfiguration() {
57 ui->graphicsAdvancedTab->ApplyConfiguration(); 57 ui->graphicsAdvancedTab->ApplyConfiguration();
58 ui->audioTab->ApplyConfiguration(); 58 ui->audioTab->ApplyConfiguration();
59 59
60 Settings::Apply(Core::System::GetInstance()); 60 Core::System::GetInstance().ApplySettings();
61 Settings::LogSettings(); 61 Settings::LogSettings();
62 62
63 game_config->Save(); 63 game_config->Save();
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp
index 51647a028..d61b5e29b 100644
--- a/src/yuzu/configuration/configure_profile_manager.cpp
+++ b/src/yuzu/configuration/configure_profile_manager.cpp
@@ -13,10 +13,10 @@
13#include <QVBoxLayout> 13#include <QVBoxLayout>
14#include "common/assert.h" 14#include "common/assert.h"
15#include "common/file_util.h" 15#include "common/file_util.h"
16#include "common/settings.h"
16#include "common/string_util.h" 17#include "common/string_util.h"
17#include "core/core.h" 18#include "core/core.h"
18#include "core/hle/service/acc/profile_manager.h" 19#include "core/hle/service/acc/profile_manager.h"
19#include "core/settings.h"
20#include "ui_configure_profile_manager.h" 20#include "ui_configure_profile_manager.h"
21#include "yuzu/configuration/configure_profile_manager.h" 21#include "yuzu/configuration/configure_profile_manager.h"
22#include "yuzu/util/limitable_input_dialog.h" 22#include "yuzu/util/limitable_input_dialog.h"
@@ -180,7 +180,7 @@ void ConfigureProfileManager::ApplyConfiguration() {
180 return; 180 return;
181 } 181 }
182 182
183 Settings::Apply(Core::System::GetInstance()); 183 Core::System::GetInstance().ApplySettings();
184} 184}
185 185
186void ConfigureProfileManager::SelectUser(const QModelIndex& index) { 186void ConfigureProfileManager::SelectUser(const QModelIndex& index) {
diff --git a/src/yuzu/configuration/configure_service.cpp b/src/yuzu/configuration/configure_service.cpp
index b580cfff2..6d954a67f 100644
--- a/src/yuzu/configuration/configure_service.cpp
+++ b/src/yuzu/configuration/configure_service.cpp
@@ -4,8 +4,8 @@
4 4
5#include <QGraphicsItem> 5#include <QGraphicsItem>
6#include <QtConcurrent/QtConcurrent> 6#include <QtConcurrent/QtConcurrent>
7#include "common/settings.h"
7#include "core/hle/service/bcat/backend/boxcat.h" 8#include "core/hle/service/bcat/backend/boxcat.h"
8#include "core/settings.h"
9#include "ui_configure_service.h" 9#include "ui_configure_service.h"
10#include "yuzu/configuration/configure_service.h" 10#include "yuzu/configuration/configure_service.h"
11 11
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index 6cf2032da..268ed44c3 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -11,9 +11,9 @@
11#include <QMessageBox> 11#include <QMessageBox>
12#include "common/assert.h" 12#include "common/assert.h"
13#include "common/file_util.h" 13#include "common/file_util.h"
14#include "common/settings.h"
14#include "core/core.h" 15#include "core/core.h"
15#include "core/hle/service/time/time.h" 16#include "core/hle/service/time/time.h"
16#include "core/settings.h"
17#include "ui_configure_system.h" 17#include "ui_configure_system.h"
18#include "yuzu/configuration/configuration_shared.h" 18#include "yuzu/configuration/configuration_shared.h"
19#include "yuzu/configuration/configure_system.h" 19#include "yuzu/configuration/configure_system.h"
@@ -199,7 +199,7 @@ void ConfigureSystem::ApplyConfiguration() {
199 } 199 }
200 } 200 }
201 201
202 Settings::Apply(system); 202 system.ApplySettings();
203} 203}
204 204
205void ConfigureSystem::RefreshConsoleID() { 205void ConfigureSystem::RefreshConsoleID() {
diff --git a/src/yuzu/configuration/configure_touch_from_button.cpp b/src/yuzu/configuration/configure_touch_from_button.cpp
index 15557e4b8..40129f228 100644
--- a/src/yuzu/configuration/configure_touch_from_button.cpp
+++ b/src/yuzu/configuration/configure_touch_from_button.cpp
@@ -10,8 +10,8 @@
10#include <QStandardItemModel> 10#include <QStandardItemModel>
11#include <QTimer> 11#include <QTimer>
12#include "common/param_package.h" 12#include "common/param_package.h"
13#include "common/settings.h"
13#include "core/frontend/framebuffer_layout.h" 14#include "core/frontend/framebuffer_layout.h"
14#include "core/settings.h"
15#include "input_common/main.h" 15#include "input_common/main.h"
16#include "ui_configure_touch_from_button.h" 16#include "ui_configure_touch_from_button.h"
17#include "yuzu/configuration/configure_touch_from_button.h" 17#include "yuzu/configuration/configure_touch_from_button.h"
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp
index aed876008..f35c89e04 100644
--- a/src/yuzu/configuration/configure_ui.cpp
+++ b/src/yuzu/configuration/configure_ui.cpp
@@ -9,8 +9,8 @@
9#include <QDirIterator> 9#include <QDirIterator>
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/file_util.h" 11#include "common/file_util.h"
12#include "common/settings.h"
12#include "core/core.h" 13#include "core/core.h"
13#include "core/settings.h"
14#include "ui_configure_ui.h" 14#include "ui_configure_ui.h"
15#include "yuzu/configuration/configure_ui.h" 15#include "yuzu/configuration/configure_ui.h"
16#include "yuzu/uisettings.h" 16#include "yuzu/uisettings.h"
@@ -85,7 +85,7 @@ void ConfigureUi::ApplyConfiguration() {
85 UISettings::values.enable_screenshot_save_as = ui->enable_screenshot_save_as->isChecked(); 85 UISettings::values.enable_screenshot_save_as = ui->enable_screenshot_save_as->isChecked();
86 Common::FS::GetUserPath(Common::FS::UserPath::ScreenshotsDir, 86 Common::FS::GetUserPath(Common::FS::UserPath::ScreenshotsDir,
87 ui->screenshot_path_edit->text().toStdString()); 87 ui->screenshot_path_edit->text().toStdString());
88 Settings::Apply(Core::System::GetInstance()); 88 Core::System::GetInstance().ApplySettings();
89} 89}
90 90
91void ConfigureUi::RequestGameListUpdate() { 91void ConfigureUi::RequestGameListUpdate() {
diff --git a/src/yuzu/configuration/configure_vibration.cpp b/src/yuzu/configuration/configure_vibration.cpp
index 7dcb2c5b9..9d92c4949 100644
--- a/src/yuzu/configuration/configure_vibration.cpp
+++ b/src/yuzu/configuration/configure_vibration.cpp
@@ -8,7 +8,7 @@
8#include <fmt/format.h> 8#include <fmt/format.h>
9 9
10#include "common/param_package.h" 10#include "common/param_package.h"
11#include "core/settings.h" 11#include "common/settings.h"
12#include "ui_configure_vibration.h" 12#include "ui_configure_vibration.h"
13#include "yuzu/configuration/configure_vibration.h" 13#include "yuzu/configuration/configure_vibration.h"
14 14
diff --git a/src/yuzu/configuration/configure_web.cpp b/src/yuzu/configuration/configure_web.cpp
index 8637f5b3c..f3f3b54d6 100644
--- a/src/yuzu/configuration/configure_web.cpp
+++ b/src/yuzu/configuration/configure_web.cpp
@@ -5,7 +5,7 @@
5#include <QIcon> 5#include <QIcon>
6#include <QMessageBox> 6#include <QMessageBox>
7#include <QtConcurrent/QtConcurrentRun> 7#include <QtConcurrent/QtConcurrentRun>
8#include "core/settings.h" 8#include "common/settings.h"
9#include "core/telemetry_session.h" 9#include "core/telemetry_session.h"
10#include "ui_configure_web.h" 10#include "ui_configure_web.h"
11#include "yuzu/configuration/configure_web.h" 11#include "yuzu/configuration/configure_web.h"
diff --git a/src/yuzu/debugger/console.cpp b/src/yuzu/debugger/console.cpp
index 207ff4d58..c11a326ac 100644
--- a/src/yuzu/debugger/console.cpp
+++ b/src/yuzu/debugger/console.cpp
@@ -29,13 +29,13 @@ void ToggleConsole() {
29 freopen_s(&temp, "CONIN$", "r", stdin); 29 freopen_s(&temp, "CONIN$", "r", stdin);
30 freopen_s(&temp, "CONOUT$", "w", stdout); 30 freopen_s(&temp, "CONOUT$", "w", stdout);
31 freopen_s(&temp, "CONOUT$", "w", stderr); 31 freopen_s(&temp, "CONOUT$", "w", stderr);
32 Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>()); 32 Common::Log::AddBackend(std::make_unique<Common::Log::ColorConsoleBackend>());
33 } 33 }
34 } else { 34 } else {
35 if (FreeConsole()) { 35 if (FreeConsole()) {
36 // In order to close the console, we have to also detach the streams on it. 36 // In order to close the console, we have to also detach the streams on it.
37 // Just redirect them to NUL if there is no console window 37 // Just redirect them to NUL if there is no console window
38 Log::RemoveBackend(Log::ColorConsoleBackend::Name()); 38 Common::Log::RemoveBackend(Common::Log::ColorConsoleBackend::Name());
39 freopen_s(&temp, "NUL", "r", stdin); 39 freopen_s(&temp, "NUL", "r", stdin);
40 freopen_s(&temp, "NUL", "w", stdout); 40 freopen_s(&temp, "NUL", "w", stdout);
41 freopen_s(&temp, "NUL", "w", stderr); 41 freopen_s(&temp, "NUL", "w", stderr);
@@ -43,9 +43,9 @@ void ToggleConsole() {
43 } 43 }
44#else 44#else
45 if (UISettings::values.show_console) { 45 if (UISettings::values.show_console) {
46 Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>()); 46 Common::Log::AddBackend(std::make_unique<Common::Log::ColorConsoleBackend>());
47 } else { 47 } else {
48 Log::RemoveBackend(Log::ColorConsoleBackend::Name()); 48 Common::Log::RemoveBackend(Common::Log::ColorConsoleBackend::Name());
49 } 49 }
50#endif 50#endif
51} 51}
diff --git a/src/yuzu/debugger/controller.cpp b/src/yuzu/debugger/controller.cpp
index 2731d948d..7186eac76 100644
--- a/src/yuzu/debugger/controller.cpp
+++ b/src/yuzu/debugger/controller.cpp
@@ -5,7 +5,7 @@
5#include <QAction> 5#include <QAction>
6#include <QLayout> 6#include <QLayout>
7#include <QString> 7#include <QString>
8#include "core/settings.h" 8#include "common/settings.h"
9#include "yuzu/configuration/configure_input_player_widget.h" 9#include "yuzu/configuration/configure_input_player_widget.h"
10#include "yuzu/debugger/controller.h" 10#include "yuzu/debugger/controller.h"
11 11
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 23ea4983d..5f6cdc0c6 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -79,6 +79,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
79#ifdef ARCHITECTURE_x86_64 79#ifdef ARCHITECTURE_x86_64
80#include "common/x64/cpu_detect.h" 80#include "common/x64/cpu_detect.h"
81#endif 81#endif
82#include "common/settings.h"
82#include "common/telemetry.h" 83#include "common/telemetry.h"
83#include "core/core.h" 84#include "core/core.h"
84#include "core/crypto/key_manager.h" 85#include "core/crypto/key_manager.h"
@@ -98,9 +99,9 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
98#include "core/hle/service/sm/sm.h" 99#include "core/hle/service/sm/sm.h"
99#include "core/loader/loader.h" 100#include "core/loader/loader.h"
100#include "core/perf_stats.h" 101#include "core/perf_stats.h"
101#include "core/settings.h"
102#include "core/telemetry_session.h" 102#include "core/telemetry_session.h"
103#include "input_common/main.h" 103#include "input_common/main.h"
104#include "util/overlay_dialog.h"
104#include "video_core/gpu.h" 105#include "video_core/gpu.h"
105#include "video_core/shader_notify.h" 106#include "video_core/shader_notify.h"
106#include "yuzu/about_dialog.h" 107#include "yuzu/about_dialog.h"
@@ -164,19 +165,21 @@ void GMainWindow::ShowTelemetryCallout() {
164 "<br/><br/>Would you like to share your usage data with us?"); 165 "<br/><br/>Would you like to share your usage data with us?");
165 if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) != QMessageBox::Yes) { 166 if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) != QMessageBox::Yes) {
166 Settings::values.enable_telemetry = false; 167 Settings::values.enable_telemetry = false;
167 Settings::Apply(Core::System::GetInstance()); 168 Core::System::GetInstance().ApplySettings();
168 } 169 }
169} 170}
170 171
171const int GMainWindow::max_recent_files_item; 172const int GMainWindow::max_recent_files_item;
172 173
173static void InitializeLogging() { 174static void InitializeLogging() {
175 using namespace Common;
176
174 Log::Filter log_filter; 177 Log::Filter log_filter;
175 log_filter.ParseFilterString(Settings::values.log_filter); 178 log_filter.ParseFilterString(Settings::values.log_filter);
176 Log::SetGlobalFilter(log_filter); 179 Log::SetGlobalFilter(log_filter);
177 180
178 const std::string& log_dir = Common::FS::GetUserPath(Common::FS::UserPath::LogDir); 181 const std::string& log_dir = FS::GetUserPath(FS::UserPath::LogDir);
179 Common::FS::CreateFullPath(log_dir); 182 FS::CreateFullPath(log_dir);
180 Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE)); 183 Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE));
181#ifdef _WIN32 184#ifdef _WIN32
182 Log::AddBackend(std::make_unique<Log::DebuggerBackend>()); 185 Log::AddBackend(std::make_unique<Log::DebuggerBackend>());
@@ -225,6 +228,8 @@ GMainWindow::GMainWindow()
225 SetDiscordEnabled(UISettings::values.enable_discord_presence); 228 SetDiscordEnabled(UISettings::values.enable_discord_presence);
226 discord_rpc->Update(); 229 discord_rpc->Update();
227 230
231 RegisterMetaTypes();
232
228 InitializeWidgets(); 233 InitializeWidgets();
229 InitializeDebugWidgets(); 234 InitializeDebugWidgets();
230 InitializeRecentFileMenuActions(); 235 InitializeRecentFileMenuActions();
@@ -373,6 +378,55 @@ GMainWindow::~GMainWindow() {
373 delete render_window; 378 delete render_window;
374} 379}
375 380
381void GMainWindow::RegisterMetaTypes() {
382 // Register integral and floating point types
383 qRegisterMetaType<u8>("u8");
384 qRegisterMetaType<u16>("u16");
385 qRegisterMetaType<u32>("u32");
386 qRegisterMetaType<u64>("u64");
387 qRegisterMetaType<u128>("u128");
388 qRegisterMetaType<s8>("s8");
389 qRegisterMetaType<s16>("s16");
390 qRegisterMetaType<s32>("s32");
391 qRegisterMetaType<s64>("s64");
392 qRegisterMetaType<f32>("f32");
393 qRegisterMetaType<f64>("f64");
394
395 // Register string types
396 qRegisterMetaType<std::string>("std::string");
397 qRegisterMetaType<std::wstring>("std::wstring");
398 qRegisterMetaType<std::u8string>("std::u8string");
399 qRegisterMetaType<std::u16string>("std::u16string");
400 qRegisterMetaType<std::u32string>("std::u32string");
401 qRegisterMetaType<std::string_view>("std::string_view");
402 qRegisterMetaType<std::wstring_view>("std::wstring_view");
403 qRegisterMetaType<std::u8string_view>("std::u8string_view");
404 qRegisterMetaType<std::u16string_view>("std::u16string_view");
405 qRegisterMetaType<std::u32string_view>("std::u32string_view");
406
407 // Register applet types
408
409 // Controller Applet
410 qRegisterMetaType<Core::Frontend::ControllerParameters>("Core::Frontend::ControllerParameters");
411
412 // Software Keyboard Applet
413 qRegisterMetaType<Core::Frontend::KeyboardInitializeParameters>(
414 "Core::Frontend::KeyboardInitializeParameters");
415 qRegisterMetaType<Core::Frontend::InlineAppearParameters>(
416 "Core::Frontend::InlineAppearParameters");
417 qRegisterMetaType<Core::Frontend::InlineTextParameters>("Core::Frontend::InlineTextParameters");
418 qRegisterMetaType<Service::AM::Applets::SwkbdResult>("Service::AM::Applets::SwkbdResult");
419 qRegisterMetaType<Service::AM::Applets::SwkbdTextCheckResult>(
420 "Service::AM::Applets::SwkbdTextCheckResult");
421 qRegisterMetaType<Service::AM::Applets::SwkbdReplyType>("Service::AM::Applets::SwkbdReplyType");
422
423 // Web Browser Applet
424 qRegisterMetaType<Service::AM::Applets::WebExitReason>("Service::AM::Applets::WebExitReason");
425
426 // Register loader types
427 qRegisterMetaType<Core::System::ResultStatus>("Core::System::ResultStatus");
428}
429
376void GMainWindow::ControllerSelectorReconfigureControllers( 430void GMainWindow::ControllerSelectorReconfigureControllers(
377 const Core::Frontend::ControllerParameters& parameters) { 431 const Core::Frontend::ControllerParameters& parameters) {
378 QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get()); 432 QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get());
@@ -385,7 +439,7 @@ void GMainWindow::ControllerSelectorReconfigureControllers(
385 emit ControllerSelectorReconfigureFinished(); 439 emit ControllerSelectorReconfigureFinished();
386 440
387 // Don't forget to apply settings. 441 // Don't forget to apply settings.
388 Settings::Apply(Core::System::GetInstance()); 442 Core::System::GetInstance().ApplySettings();
389 config->Save(); 443 config->Save();
390 444
391 UpdateStatusButtons(); 445 UpdateStatusButtons();
@@ -412,25 +466,112 @@ void GMainWindow::ProfileSelectorSelectProfile() {
412 emit ProfileSelectorFinishedSelection(uuid); 466 emit ProfileSelectorFinishedSelection(uuid);
413} 467}
414 468
415void GMainWindow::SoftwareKeyboardGetText( 469void GMainWindow::SoftwareKeyboardInitialize(
416 const Core::Frontend::SoftwareKeyboardParameters& parameters) { 470 bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters) {
417 QtSoftwareKeyboardDialog dialog(this, parameters); 471 if (software_keyboard) {
418 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | 472 LOG_ERROR(Frontend, "The software keyboard is already initialized!");
419 Qt::WindowTitleHint | Qt::WindowSystemMenuHint | 473 return;
420 Qt::WindowCloseButtonHint); 474 }
421 dialog.setWindowModality(Qt::WindowModal);
422 475
423 if (dialog.exec() == QDialog::Rejected) { 476 software_keyboard = new QtSoftwareKeyboardDialog(render_window, Core::System::GetInstance(),
424 emit SoftwareKeyboardFinishedText(std::nullopt); 477 is_inline, std::move(initialize_parameters));
478
479 if (is_inline) {
480 connect(
481 software_keyboard, &QtSoftwareKeyboardDialog::SubmitInlineText, this,
482 [this](Service::AM::Applets::SwkbdReplyType reply_type, std::u16string submitted_text,
483 s32 cursor_position) {
484 emit SoftwareKeyboardSubmitInlineText(reply_type, submitted_text, cursor_position);
485 },
486 Qt::QueuedConnection);
487 } else {
488 connect(
489 software_keyboard, &QtSoftwareKeyboardDialog::SubmitNormalText, this,
490 [this](Service::AM::Applets::SwkbdResult result, std::u16string submitted_text) {
491 emit SoftwareKeyboardSubmitNormalText(result, submitted_text);
492 },
493 Qt::QueuedConnection);
494 }
495}
496
497void GMainWindow::SoftwareKeyboardShowNormal() {
498 if (!software_keyboard) {
499 LOG_ERROR(Frontend, "The software keyboard is not initialized!");
500 return;
501 }
502
503 const auto& layout = render_window->GetFramebufferLayout();
504
505 const auto x = layout.screen.left;
506 const auto y = layout.screen.top;
507 const auto w = layout.screen.GetWidth();
508 const auto h = layout.screen.GetHeight();
509
510 software_keyboard->ShowNormalKeyboard(render_window->mapToGlobal(QPoint(x, y)), QSize(w, h));
511}
512
513void GMainWindow::SoftwareKeyboardShowTextCheck(
514 Service::AM::Applets::SwkbdTextCheckResult text_check_result,
515 std::u16string text_check_message) {
516 if (!software_keyboard) {
517 LOG_ERROR(Frontend, "The software keyboard is not initialized!");
518 return;
519 }
520
521 software_keyboard->ShowTextCheckDialog(text_check_result, text_check_message);
522}
523
524void GMainWindow::SoftwareKeyboardShowInline(
525 Core::Frontend::InlineAppearParameters appear_parameters) {
526 if (!software_keyboard) {
527 LOG_ERROR(Frontend, "The software keyboard is not initialized!");
528 return;
529 }
530
531 const auto& layout = render_window->GetFramebufferLayout();
532
533 const auto x =
534 static_cast<int>(layout.screen.left + (0.5f * layout.screen.GetWidth() *
535 ((2.0f * appear_parameters.key_top_translate_x) +
536 (1.0f - appear_parameters.key_top_scale_x))));
537 const auto y =
538 static_cast<int>(layout.screen.top + (layout.screen.GetHeight() *
539 ((2.0f * appear_parameters.key_top_translate_y) +
540 (1.0f - appear_parameters.key_top_scale_y))));
541 const auto w = static_cast<int>(layout.screen.GetWidth() * appear_parameters.key_top_scale_x);
542 const auto h = static_cast<int>(layout.screen.GetHeight() * appear_parameters.key_top_scale_y);
543
544 software_keyboard->ShowInlineKeyboard(std::move(appear_parameters),
545 render_window->mapToGlobal(QPoint(x, y)), QSize(w, h));
546}
547
548void GMainWindow::SoftwareKeyboardHideInline() {
549 if (!software_keyboard) {
550 LOG_ERROR(Frontend, "The software keyboard is not initialized!");
425 return; 551 return;
426 } 552 }
427 553
428 emit SoftwareKeyboardFinishedText(dialog.GetText()); 554 software_keyboard->HideInlineKeyboard();
429} 555}
430 556
431void GMainWindow::SoftwareKeyboardInvokeCheckDialog(std::u16string error_message) { 557void GMainWindow::SoftwareKeyboardInlineTextChanged(
432 QMessageBox::warning(this, tr("Text Check Failed"), QString::fromStdU16String(error_message)); 558 Core::Frontend::InlineTextParameters text_parameters) {
433 emit SoftwareKeyboardFinishedCheckDialog(); 559 if (!software_keyboard) {
560 LOG_ERROR(Frontend, "The software keyboard is not initialized!");
561 return;
562 }
563
564 software_keyboard->InlineTextChanged(std::move(text_parameters));
565}
566
567void GMainWindow::SoftwareKeyboardExit() {
568 if (!software_keyboard) {
569 return;
570 }
571
572 software_keyboard->ExitKeyboard();
573
574 software_keyboard = nullptr;
434} 575}
435 576
436void GMainWindow::WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args, 577void GMainWindow::WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args,
@@ -650,7 +791,7 @@ void GMainWindow::InitializeWidgets() {
650 Settings::values.use_asynchronous_gpu_emulation.SetValue( 791 Settings::values.use_asynchronous_gpu_emulation.SetValue(
651 !Settings::values.use_asynchronous_gpu_emulation.GetValue()); 792 !Settings::values.use_asynchronous_gpu_emulation.GetValue());
652 async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue()); 793 async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
653 Settings::Apply(Core::System::GetInstance()); 794 Core::System::GetInstance().ApplySettings();
654 }); 795 });
655 async_status_button->setText(tr("ASYNC")); 796 async_status_button->setText(tr("ASYNC"));
656 async_status_button->setCheckable(true); 797 async_status_button->setCheckable(true);
@@ -666,7 +807,7 @@ void GMainWindow::InitializeWidgets() {
666 } 807 }
667 Settings::values.use_multi_core.SetValue(!Settings::values.use_multi_core.GetValue()); 808 Settings::values.use_multi_core.SetValue(!Settings::values.use_multi_core.GetValue());
668 multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue()); 809 multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue());
669 Settings::Apply(Core::System::GetInstance()); 810 Core::System::GetInstance().ApplySettings();
670 }); 811 });
671 multicore_status_button->setText(tr("MULTICORE")); 812 multicore_status_button->setText(tr("MULTICORE"));
672 multicore_status_button->setCheckable(true); 813 multicore_status_button->setCheckable(true);
@@ -697,7 +838,7 @@ void GMainWindow::InitializeWidgets() {
697 Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL); 838 Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL);
698 } 839 }
699 840
700 Settings::Apply(Core::System::GetInstance()); 841 Core::System::GetInstance().ApplySettings();
701 }); 842 });
702 statusBar()->insertPermanentWidget(0, renderer_status_button); 843 statusBar()->insertPermanentWidget(0, renderer_status_button);
703 844
@@ -976,6 +1117,10 @@ void GMainWindow::ConnectWidgetEvents() {
976 connect(this, &GMainWindow::EmulationStopping, render_window, 1117 connect(this, &GMainWindow::EmulationStopping, render_window,
977 &GRenderWindow::OnEmulationStopping); 1118 &GRenderWindow::OnEmulationStopping);
978 1119
1120 // Software Keyboard Applet
1121 connect(this, &GMainWindow::EmulationStarting, this, &GMainWindow::SoftwareKeyboardExit);
1122 connect(this, &GMainWindow::EmulationStopping, this, &GMainWindow::SoftwareKeyboardExit);
1123
979 connect(&status_bar_update_timer, &QTimer::timeout, this, &GMainWindow::UpdateStatusBar); 1124 connect(&status_bar_update_timer, &QTimer::timeout, this, &GMainWindow::UpdateStatusBar);
980} 1125}
981 1126
@@ -2185,15 +2330,6 @@ void GMainWindow::OnStartGame() {
2185 2330
2186 emu_thread->SetRunning(true); 2331 emu_thread->SetRunning(true);
2187 2332
2188 qRegisterMetaType<Core::Frontend::ControllerParameters>("Core::Frontend::ControllerParameters");
2189 qRegisterMetaType<Core::Frontend::SoftwareKeyboardParameters>(
2190 "Core::Frontend::SoftwareKeyboardParameters");
2191 qRegisterMetaType<Core::System::ResultStatus>("Core::System::ResultStatus");
2192 qRegisterMetaType<std::string>("std::string");
2193 qRegisterMetaType<std::optional<std::u16string>>("std::optional<std::u16string>");
2194 qRegisterMetaType<std::string_view>("std::string_view");
2195 qRegisterMetaType<Service::AM::Applets::WebExitReason>("Service::AM::Applets::WebExitReason");
2196
2197 connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError); 2333 connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError);
2198 2334
2199 ui.action_Start->setEnabled(false); 2335 ui.action_Start->setEnabled(false);
@@ -2242,8 +2378,11 @@ void GMainWindow::OnExecuteProgram(std::size_t program_index) {
2242 BootGame(last_filename_booted, program_index); 2378 BootGame(last_filename_booted, program_index);
2243} 2379}
2244 2380
2245void GMainWindow::ErrorDisplayDisplayError(QString body) { 2381void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) {
2246 QMessageBox::critical(this, tr("Error Display"), body); 2382 OverlayDialog dialog(render_window, Core::System::GetInstance(), error_code, error_text,
2383 QString{}, tr("OK"), Qt::AlignLeft | Qt::AlignVCenter);
2384 dialog.exec();
2385
2247 emit ErrorDisplayFinished(); 2386 emit ErrorDisplayFinished();
2248} 2387}
2249 2388
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 04d37d4ae..7f1e50a5b 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -37,9 +37,13 @@ enum class GameListRemoveTarget;
37enum class InstalledEntryType; 37enum class InstalledEntryType;
38class GameListPlaceholder; 38class GameListPlaceholder;
39 39
40class QtSoftwareKeyboardDialog;
41
40namespace Core::Frontend { 42namespace Core::Frontend {
41struct ControllerParameters; 43struct ControllerParameters;
42struct SoftwareKeyboardParameters; 44struct InlineAppearParameters;
45struct InlineTextParameters;
46struct KeyboardInitializeParameters;
43} // namespace Core::Frontend 47} // namespace Core::Frontend
44 48
45namespace DiscordRPC { 49namespace DiscordRPC {
@@ -57,8 +61,11 @@ class InputSubsystem;
57} 61}
58 62
59namespace Service::AM::Applets { 63namespace Service::AM::Applets {
64enum class SwkbdResult : u32;
65enum class SwkbdTextCheckResult : u32;
66enum class SwkbdReplyType : u32;
60enum class WebExitReason : u32; 67enum class WebExitReason : u32;
61} 68} // namespace Service::AM::Applets
62 69
63enum class EmulatedDirectoryTarget { 70enum class EmulatedDirectoryTarget {
64 NAND, 71 NAND,
@@ -128,8 +135,10 @@ signals:
128 135
129 void ProfileSelectorFinishedSelection(std::optional<Common::UUID> uuid); 136 void ProfileSelectorFinishedSelection(std::optional<Common::UUID> uuid);
130 137
131 void SoftwareKeyboardFinishedText(std::optional<std::u16string> text); 138 void SoftwareKeyboardSubmitNormalText(Service::AM::Applets::SwkbdResult result,
132 void SoftwareKeyboardFinishedCheckDialog(); 139 std::u16string submitted_text);
140 void SoftwareKeyboardSubmitInlineText(Service::AM::Applets::SwkbdReplyType reply_type,
141 std::u16string submitted_text, s32 cursor_position);
133 142
134 void WebBrowserExtractOfflineRomFS(); 143 void WebBrowserExtractOfflineRomFS();
135 void WebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason, std::string last_url); 144 void WebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason, std::string last_url);
@@ -139,15 +148,24 @@ public slots:
139 void OnExecuteProgram(std::size_t program_index); 148 void OnExecuteProgram(std::size_t program_index);
140 void ControllerSelectorReconfigureControllers( 149 void ControllerSelectorReconfigureControllers(
141 const Core::Frontend::ControllerParameters& parameters); 150 const Core::Frontend::ControllerParameters& parameters);
142 void ErrorDisplayDisplayError(QString body); 151 void SoftwareKeyboardInitialize(
152 bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters);
153 void SoftwareKeyboardShowNormal();
154 void SoftwareKeyboardShowTextCheck(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
155 std::u16string text_check_message);
156 void SoftwareKeyboardShowInline(Core::Frontend::InlineAppearParameters appear_parameters);
157 void SoftwareKeyboardHideInline();
158 void SoftwareKeyboardInlineTextChanged(Core::Frontend::InlineTextParameters text_parameters);
159 void SoftwareKeyboardExit();
160 void ErrorDisplayDisplayError(QString error_code, QString error_text);
143 void ProfileSelectorSelectProfile(); 161 void ProfileSelectorSelectProfile();
144 void SoftwareKeyboardGetText(const Core::Frontend::SoftwareKeyboardParameters& parameters);
145 void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message);
146 void WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args, 162 void WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args,
147 bool is_local); 163 bool is_local);
148 void OnAppFocusStateChanged(Qt::ApplicationState state); 164 void OnAppFocusStateChanged(Qt::ApplicationState state);
149 165
150private: 166private:
167 void RegisterMetaTypes();
168
151 void InitializeWidgets(); 169 void InitializeWidgets();
152 void InitializeDebugWidgets(); 170 void InitializeDebugWidgets();
153 void InitializeRecentFileMenuActions(); 171 void InitializeRecentFileMenuActions();
@@ -334,6 +352,9 @@ private:
334 // Disables the web applet for the rest of the emulated session 352 // Disables the web applet for the rest of the emulated session
335 bool disable_web_applet{}; 353 bool disable_web_applet{};
336 354
355 // Applets
356 QtSoftwareKeyboardDialog* software_keyboard = nullptr;
357
337protected: 358protected:
338 void dropEvent(QDropEvent* event) override; 359 void dropEvent(QDropEvent* event) override;
339 void dragEnterEvent(QDragEnterEvent* event) override; 360 void dragEnterEvent(QDragEnterEvent* event) override;
diff --git a/src/yuzu/util/overlay_dialog.cpp b/src/yuzu/util/overlay_dialog.cpp
new file mode 100644
index 000000000..95b148545
--- /dev/null
+++ b/src/yuzu/util/overlay_dialog.cpp
@@ -0,0 +1,249 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <QKeyEvent>
6#include <QScreen>
7
8#include "core/core.h"
9#include "core/frontend/input_interpreter.h"
10#include "ui_overlay_dialog.h"
11#include "yuzu/util/overlay_dialog.h"
12
13namespace {
14
15constexpr float BASE_TITLE_FONT_SIZE = 14.0f;
16constexpr float BASE_FONT_SIZE = 18.0f;
17constexpr float BASE_WIDTH = 1280.0f;
18constexpr float BASE_HEIGHT = 720.0f;
19
20} // Anonymous namespace
21
22OverlayDialog::OverlayDialog(QWidget* parent, Core::System& system, const QString& title_text,
23 const QString& body_text, const QString& left_button_text,
24 const QString& right_button_text, Qt::Alignment alignment,
25 bool use_rich_text_)
26 : QDialog(parent), ui{std::make_unique<Ui::OverlayDialog>()}, use_rich_text{use_rich_text_} {
27 ui->setupUi(this);
28
29 setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowTitleHint |
30 Qt::WindowSystemMenuHint | Qt::CustomizeWindowHint);
31 setWindowModality(Qt::WindowModal);
32 setAttribute(Qt::WA_TranslucentBackground);
33
34 if (use_rich_text) {
35 InitializeRichTextDialog(title_text, body_text, left_button_text, right_button_text,
36 alignment);
37 } else {
38 InitializeRegularTextDialog(title_text, body_text, left_button_text, right_button_text,
39 alignment);
40 }
41
42 MoveAndResizeWindow();
43
44 // TODO (Morph): Remove this when InputInterpreter no longer relies on the HID backend
45 if (system.IsPoweredOn()) {
46 input_interpreter = std::make_unique<InputInterpreter>(system);
47
48 StartInputThread();
49 }
50}
51
52OverlayDialog::~OverlayDialog() {
53 StopInputThread();
54}
55
56void OverlayDialog::InitializeRegularTextDialog(const QString& title_text, const QString& body_text,
57 const QString& left_button_text,
58 const QString& right_button_text,
59 Qt::Alignment alignment) {
60 ui->stackedDialog->setCurrentIndex(0);
61
62 ui->label_title->setText(title_text);
63 ui->label_dialog->setText(body_text);
64 ui->button_cancel->setText(left_button_text);
65 ui->button_ok_label->setText(right_button_text);
66
67 ui->label_dialog->setAlignment(alignment);
68
69 if (title_text.isEmpty()) {
70 ui->label_title->hide();
71 ui->verticalLayout_2->setStretch(0, 0);
72 ui->verticalLayout_2->setStretch(1, 219);
73 ui->verticalLayout_2->setStretch(2, 82);
74 }
75
76 if (left_button_text.isEmpty()) {
77 ui->button_cancel->hide();
78 ui->button_cancel->setEnabled(false);
79 }
80
81 if (right_button_text.isEmpty()) {
82 ui->button_ok_label->hide();
83 ui->button_ok_label->setEnabled(false);
84 }
85
86 connect(
87 ui->button_cancel, &QPushButton::clicked, this,
88 [this](bool) {
89 StopInputThread();
90 QDialog::reject();
91 },
92 Qt::QueuedConnection);
93 connect(
94 ui->button_ok_label, &QPushButton::clicked, this,
95 [this](bool) {
96 StopInputThread();
97 QDialog::accept();
98 },
99 Qt::QueuedConnection);
100}
101
102void OverlayDialog::InitializeRichTextDialog(const QString& title_text, const QString& body_text,
103 const QString& left_button_text,
104 const QString& right_button_text,
105 Qt::Alignment alignment) {
106 ui->stackedDialog->setCurrentIndex(1);
107
108 ui->label_title_rich->setText(title_text);
109 ui->text_browser_dialog->setText(body_text);
110 ui->button_cancel_rich->setText(left_button_text);
111 ui->button_ok_rich->setText(right_button_text);
112
113 // TODO (Morph/Rei): Replace this with something that works better
114 ui->text_browser_dialog->setAlignment(alignment);
115
116 if (title_text.isEmpty()) {
117 ui->label_title_rich->hide();
118 ui->verticalLayout_3->setStretch(0, 0);
119 ui->verticalLayout_3->setStretch(1, 438);
120 ui->verticalLayout_3->setStretch(2, 82);
121 }
122
123 if (left_button_text.isEmpty()) {
124 ui->button_cancel_rich->hide();
125 ui->button_cancel_rich->setEnabled(false);
126 }
127
128 if (right_button_text.isEmpty()) {
129 ui->button_ok_rich->hide();
130 ui->button_ok_rich->setEnabled(false);
131 }
132
133 connect(
134 ui->button_cancel_rich, &QPushButton::clicked, this,
135 [this](bool) {
136 StopInputThread();
137 QDialog::reject();
138 },
139 Qt::QueuedConnection);
140 connect(
141 ui->button_ok_rich, &QPushButton::clicked, this,
142 [this](bool) {
143 StopInputThread();
144 QDialog::accept();
145 },
146 Qt::QueuedConnection);
147}
148
149void OverlayDialog::MoveAndResizeWindow() {
150 const auto pos = parentWidget()->mapToGlobal(parentWidget()->rect().topLeft());
151 const auto width = static_cast<float>(parentWidget()->width());
152 const auto height = static_cast<float>(parentWidget()->height());
153
154 // High DPI
155 const float dpi_scale = qApp->screenAt(pos)->logicalDotsPerInch() / 96.0f;
156
157 const auto title_text_font_size = BASE_TITLE_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
158 const auto body_text_font_size =
159 BASE_FONT_SIZE * (((width / BASE_WIDTH) + (height / BASE_HEIGHT)) / 2.0f) / dpi_scale;
160 const auto button_text_font_size = BASE_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
161
162 QFont title_text_font(QStringLiteral("MS Shell Dlg 2"), title_text_font_size, QFont::Normal);
163 QFont body_text_font(QStringLiteral("MS Shell Dlg 2"), body_text_font_size, QFont::Normal);
164 QFont button_text_font(QStringLiteral("MS Shell Dlg 2"), button_text_font_size, QFont::Normal);
165
166 if (use_rich_text) {
167 ui->label_title_rich->setFont(title_text_font);
168 ui->text_browser_dialog->setFont(body_text_font);
169 ui->button_cancel_rich->setFont(button_text_font);
170 ui->button_ok_rich->setFont(button_text_font);
171 } else {
172 ui->label_title->setFont(title_text_font);
173 ui->label_dialog->setFont(body_text_font);
174 ui->button_cancel->setFont(button_text_font);
175 ui->button_ok_label->setFont(button_text_font);
176 }
177
178 QDialog::move(pos);
179 QDialog::resize(width, height);
180}
181
182template <HIDButton... T>
183void OverlayDialog::HandleButtonPressedOnce() {
184 const auto f = [this](HIDButton button) {
185 if (input_interpreter->IsButtonPressedOnce(button)) {
186 TranslateButtonPress(button);
187 }
188 };
189
190 (f(T), ...);
191}
192
193void OverlayDialog::TranslateButtonPress(HIDButton button) {
194 QPushButton* left_button = use_rich_text ? ui->button_cancel_rich : ui->button_cancel;
195 QPushButton* right_button = use_rich_text ? ui->button_ok_rich : ui->button_ok_label;
196
197 // TODO (Morph): Handle QTextBrowser text scrolling
198 // TODO (Morph): focusPrevious/NextChild() doesn't work well with the rich text dialog, fix it
199
200 switch (button) {
201 case HIDButton::A:
202 case HIDButton::B:
203 if (left_button->hasFocus()) {
204 left_button->click();
205 } else if (right_button->hasFocus()) {
206 right_button->click();
207 }
208 break;
209 case HIDButton::DLeft:
210 case HIDButton::LStickLeft:
211 focusPreviousChild();
212 break;
213 case HIDButton::DRight:
214 case HIDButton::LStickRight:
215 focusNextChild();
216 break;
217 default:
218 break;
219 }
220}
221
222void OverlayDialog::StartInputThread() {
223 if (input_thread_running) {
224 return;
225 }
226
227 input_thread_running = true;
228
229 input_thread = std::thread(&OverlayDialog::InputThread, this);
230}
231
232void OverlayDialog::StopInputThread() {
233 input_thread_running = false;
234
235 if (input_thread.joinable()) {
236 input_thread.join();
237 }
238}
239
240void OverlayDialog::InputThread() {
241 while (input_thread_running) {
242 input_interpreter->PollInput();
243
244 HandleButtonPressedOnce<HIDButton::A, HIDButton::B, HIDButton::DLeft, HIDButton::DRight,
245 HIDButton::LStickLeft, HIDButton::LStickRight>();
246
247 std::this_thread::sleep_for(std::chrono::milliseconds(50));
248 }
249}
diff --git a/src/yuzu/util/overlay_dialog.h b/src/yuzu/util/overlay_dialog.h
new file mode 100644
index 000000000..e8c388bd0
--- /dev/null
+++ b/src/yuzu/util/overlay_dialog.h
@@ -0,0 +1,107 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <atomic>
9#include <memory>
10#include <thread>
11
12#include <QDialog>
13
14#include "common/common_types.h"
15
16enum class HIDButton : u8;
17
18class InputInterpreter;
19
20namespace Core {
21class System;
22}
23
24namespace Ui {
25class OverlayDialog;
26}
27
28/**
29 * An OverlayDialog is an interactive dialog that accepts controller input (while a game is running)
30 * This dialog attempts to replicate the look and feel of the Nintendo Switch's overlay dialogs and
31 * provide some extra features such as embedding HTML/Rich Text content in a QTextBrowser.
32 * The OverlayDialog provides 2 modes: one to embed regular text into a QLabel and another to embed
33 * HTML/Rich Text content into a QTextBrowser.
34 */
35class OverlayDialog final : public QDialog {
36 Q_OBJECT
37
38public:
39 explicit OverlayDialog(QWidget* parent, Core::System& system, const QString& title_text,
40 const QString& body_text, const QString& left_button_text,
41 const QString& right_button_text,
42 Qt::Alignment alignment = Qt::AlignCenter, bool use_rich_text_ = false);
43 ~OverlayDialog() override;
44
45private:
46 /**
47 * Initializes a text dialog with a QLabel storing text.
48 * Only use this for short text as the dialog buttons would be squashed with longer text.
49 *
50 * @param title_text Title text to be displayed
51 * @param body_text Main text to be displayed
52 * @param left_button_text Left button text. If empty, the button is hidden and disabled
53 * @param right_button_text Right button text. If empty, the button is hidden and disabled
54 * @param alignment Main text alignment
55 */
56 void InitializeRegularTextDialog(const QString& title_text, const QString& body_text,
57 const QString& left_button_text,
58 const QString& right_button_text, Qt::Alignment alignment);
59
60 /**
61 * Initializes a text dialog with a QTextBrowser storing text.
62 * This is ideal for longer text or rich text content. A scrollbar is shown for longer text.
63 *
64 * @param title_text Title text to be displayed
65 * @param body_text Main text to be displayed
66 * @param left_button_text Left button text. If empty, the button is hidden and disabled
67 * @param right_button_text Right button text. If empty, the button is hidden and disabled
68 * @param alignment Main text alignment
69 */
70 void InitializeRichTextDialog(const QString& title_text, const QString& body_text,
71 const QString& left_button_text, const QString& right_button_text,
72 Qt::Alignment alignment);
73
74 /// Moves and resizes the dialog to be fully overlayed on top of the parent window.
75 void MoveAndResizeWindow();
76
77 /**
78 * Handles button presses and converts them into keyboard input.
79 *
80 * @tparam HIDButton The list of buttons that can be converted into keyboard input.
81 */
82 template <HIDButton... T>
83 void HandleButtonPressedOnce();
84
85 /**
86 * Translates a button press to focus or click either the left or right buttons.
87 *
88 * @param button The button press to process.
89 */
90 void TranslateButtonPress(HIDButton button);
91
92 void StartInputThread();
93 void StopInputThread();
94
95 /// The thread where input is being polled and processed.
96 void InputThread();
97
98 std::unique_ptr<Ui::OverlayDialog> ui;
99
100 bool use_rich_text;
101
102 std::unique_ptr<InputInterpreter> input_interpreter;
103
104 std::thread input_thread;
105
106 std::atomic<bool> input_thread_running{};
107};
diff --git a/src/yuzu/util/overlay_dialog.ui b/src/yuzu/util/overlay_dialog.ui
new file mode 100644
index 000000000..278e2f219
--- /dev/null
+++ b/src/yuzu/util/overlay_dialog.ui
@@ -0,0 +1,404 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>OverlayDialog</class>
4 <widget class="QDialog" name="OverlayDialog">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>1280</width>
10 <height>720</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Dialog</string>
15 </property>
16 <property name="styleSheet">
17 <string notr="true"/>
18 </property>
19 <layout class="QVBoxLayout" name="verticalLayout">
20 <property name="spacing">
21 <number>0</number>
22 </property>
23 <property name="leftMargin">
24 <number>0</number>
25 </property>
26 <property name="topMargin">
27 <number>0</number>
28 </property>
29 <property name="rightMargin">
30 <number>0</number>
31 </property>
32 <property name="bottomMargin">
33 <number>0</number>
34 </property>
35 <item>
36 <widget class="QStackedWidget" name="stackedDialog">
37 <property name="currentIndex">
38 <number>0</number>
39 </property>
40 <widget class="QWidget" name="lineDialog">
41 <layout class="QGridLayout" name="lineDialogGridLayout" rowstretch="210,300,210" columnstretch="250,780,250">
42 <property name="leftMargin">
43 <number>0</number>
44 </property>
45 <property name="topMargin">
46 <number>0</number>
47 </property>
48 <property name="rightMargin">
49 <number>0</number>
50 </property>
51 <property name="bottomMargin">
52 <number>0</number>
53 </property>
54 <property name="spacing">
55 <number>0</number>
56 </property>
57 <item row="1" column="1">
58 <widget class="QWidget" name="contentDialog" native="true">
59 <layout class="QVBoxLayout" name="verticalLayout_2" stretch="70,149,82">
60 <property name="spacing">
61 <number>0</number>
62 </property>
63 <property name="leftMargin">
64 <number>0</number>
65 </property>
66 <property name="topMargin">
67 <number>0</number>
68 </property>
69 <property name="rightMargin">
70 <number>0</number>
71 </property>
72 <property name="bottomMargin">
73 <number>0</number>
74 </property>
75 <item>
76 <widget class="QLabel" name="label_title">
77 <property name="font">
78 <font>
79 <pointsize>14</pointsize>
80 </font>
81 </property>
82 <property name="alignment">
83 <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
84 </property>
85 </widget>
86 </item>
87 <item>
88 <widget class="QLabel" name="label_dialog">
89 <property name="font">
90 <font>
91 <pointsize>18</pointsize>
92 </font>
93 </property>
94 <property name="alignment">
95 <set>Qt::AlignCenter</set>
96 </property>
97 <property name="wordWrap">
98 <bool>true</bool>
99 </property>
100 </widget>
101 </item>
102 <item>
103 <widget class="QWidget" name="buttonsDialog" native="true">
104 <layout class="QHBoxLayout" name="horizontalLayout">
105 <property name="spacing">
106 <number>0</number>
107 </property>
108 <property name="leftMargin">
109 <number>0</number>
110 </property>
111 <property name="topMargin">
112 <number>0</number>
113 </property>
114 <property name="rightMargin">
115 <number>0</number>
116 </property>
117 <property name="bottomMargin">
118 <number>0</number>
119 </property>
120 <item>
121 <widget class="QPushButton" name="button_cancel">
122 <property name="sizePolicy">
123 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
124 <horstretch>0</horstretch>
125 <verstretch>0</verstretch>
126 </sizepolicy>
127 </property>
128 <property name="font">
129 <font>
130 <pointsize>18</pointsize>
131 </font>
132 </property>
133 <property name="text">
134 <string>Cancel</string>
135 </property>
136 </widget>
137 </item>
138 <item>
139 <widget class="QPushButton" name="button_ok_label">
140 <property name="sizePolicy">
141 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
142 <horstretch>0</horstretch>
143 <verstretch>0</verstretch>
144 </sizepolicy>
145 </property>
146 <property name="font">
147 <font>
148 <pointsize>18</pointsize>
149 </font>
150 </property>
151 <property name="text">
152 <string>OK</string>
153 </property>
154 </widget>
155 </item>
156 </layout>
157 </widget>
158 </item>
159 </layout>
160 </widget>
161 </item>
162 <item row="0" column="1">
163 <spacer name="verticalSpacer">
164 <property name="orientation">
165 <enum>Qt::Vertical</enum>
166 </property>
167 <property name="sizeHint" stdset="0">
168 <size>
169 <width>20</width>
170 <height>40</height>
171 </size>
172 </property>
173 </spacer>
174 </item>
175 <item row="1" column="0">
176 <spacer name="horizontalSpacer">
177 <property name="orientation">
178 <enum>Qt::Horizontal</enum>
179 </property>
180 <property name="sizeHint" stdset="0">
181 <size>
182 <width>40</width>
183 <height>20</height>
184 </size>
185 </property>
186 </spacer>
187 </item>
188 <item row="2" column="1">
189 <spacer name="verticalSpacer_2">
190 <property name="orientation">
191 <enum>Qt::Vertical</enum>
192 </property>
193 <property name="sizeHint" stdset="0">
194 <size>
195 <width>20</width>
196 <height>40</height>
197 </size>
198 </property>
199 </spacer>
200 </item>
201 <item row="1" column="2">
202 <spacer name="horizontalSpacer_2">
203 <property name="orientation">
204 <enum>Qt::Horizontal</enum>
205 </property>
206 <property name="sizeHint" stdset="0">
207 <size>
208 <width>40</width>
209 <height>20</height>
210 </size>
211 </property>
212 </spacer>
213 </item>
214 </layout>
215 </widget>
216 <widget class="QWidget" name="richDialog">
217 <layout class="QGridLayout" name="richDialogGridLayout" rowstretch="100,520,100" columnstretch="165,950,165">
218 <property name="leftMargin">
219 <number>0</number>
220 </property>
221 <property name="topMargin">
222 <number>0</number>
223 </property>
224 <property name="rightMargin">
225 <number>0</number>
226 </property>
227 <property name="bottomMargin">
228 <number>0</number>
229 </property>
230 <property name="spacing">
231 <number>0</number>
232 </property>
233 <item row="1" column="0">
234 <spacer name="horizontalSpacer_3">
235 <property name="orientation">
236 <enum>Qt::Horizontal</enum>
237 </property>
238 <property name="sizeHint" stdset="0">
239 <size>
240 <width>40</width>
241 <height>20</height>
242 </size>
243 </property>
244 </spacer>
245 </item>
246 <item row="2" column="1">
247 <spacer name="verticalSpacer_4">
248 <property name="orientation">
249 <enum>Qt::Vertical</enum>
250 </property>
251 <property name="sizeHint" stdset="0">
252 <size>
253 <width>20</width>
254 <height>40</height>
255 </size>
256 </property>
257 </spacer>
258 </item>
259 <item row="0" column="1">
260 <spacer name="verticalSpacer_3">
261 <property name="orientation">
262 <enum>Qt::Vertical</enum>
263 </property>
264 <property name="sizeHint" stdset="0">
265 <size>
266 <width>20</width>
267 <height>40</height>
268 </size>
269 </property>
270 </spacer>
271 </item>
272 <item row="1" column="1">
273 <widget class="QWidget" name="contentRichDialog" native="true">
274 <layout class="QVBoxLayout" name="verticalLayout_3" stretch="70,368,82">
275 <property name="spacing">
276 <number>0</number>
277 </property>
278 <property name="leftMargin">
279 <number>0</number>
280 </property>
281 <property name="topMargin">
282 <number>0</number>
283 </property>
284 <property name="rightMargin">
285 <number>0</number>
286 </property>
287 <property name="bottomMargin">
288 <number>0</number>
289 </property>
290 <item>
291 <widget class="QLabel" name="label_title_rich">
292 <property name="font">
293 <font>
294 <pointsize>14</pointsize>
295 </font>
296 </property>
297 <property name="text">
298 <string/>
299 </property>
300 <property name="alignment">
301 <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
302 </property>
303 </widget>
304 </item>
305 <item>
306 <widget class="QTextBrowser" name="text_browser_dialog">
307 <property name="font">
308 <font>
309 <pointsize>18</pointsize>
310 </font>
311 </property>
312 <property name="html">
313 <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
314&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
315p, li { white-space: pre-wrap; }
316&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:18pt; font-weight:400; font-style:normal;&quot;&gt;
317&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
318 </property>
319 </widget>
320 </item>
321 <item>
322 <widget class="QWidget" name="buttonsRichDialog" native="true">
323 <layout class="QHBoxLayout" name="horizontalLayout_2">
324 <property name="spacing">
325 <number>0</number>
326 </property>
327 <property name="leftMargin">
328 <number>0</number>
329 </property>
330 <property name="topMargin">
331 <number>0</number>
332 </property>
333 <property name="rightMargin">
334 <number>0</number>
335 </property>
336 <property name="bottomMargin">
337 <number>0</number>
338 </property>
339 <item>
340 <widget class="QPushButton" name="button_cancel_rich">
341 <property name="sizePolicy">
342 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
343 <horstretch>0</horstretch>
344 <verstretch>0</verstretch>
345 </sizepolicy>
346 </property>
347 <property name="font">
348 <font>
349 <pointsize>18</pointsize>
350 </font>
351 </property>
352 <property name="text">
353 <string>Cancel</string>
354 </property>
355 </widget>
356 </item>
357 <item>
358 <widget class="QPushButton" name="button_ok_rich">
359 <property name="sizePolicy">
360 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
361 <horstretch>0</horstretch>
362 <verstretch>0</verstretch>
363 </sizepolicy>
364 </property>
365 <property name="font">
366 <font>
367 <pointsize>18</pointsize>
368 </font>
369 </property>
370 <property name="text">
371 <string>OK</string>
372 </property>
373 </widget>
374 </item>
375 </layout>
376 </widget>
377 </item>
378 </layout>
379 </widget>
380 </item>
381 <item row="1" column="2">
382 <spacer name="horizontalSpacer_4">
383 <property name="orientation">
384 <enum>Qt::Horizontal</enum>
385 </property>
386 <property name="sizeHint" stdset="0">
387 <size>
388 <width>40</width>
389 <height>20</height>
390 </size>
391 </property>
392 </spacer>
393 </item>
394 </layout>
395 </widget>
396 </widget>
397 </item>
398 </layout>
399 </widget>
400 <resources>
401 <include location="../../../dist/icons/overlay/overlay.qrc"/>
402 </resources>
403 <connections/>
404</ui>
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt
index 8461f8896..4bf25727b 100644
--- a/src/yuzu_cmd/CMakeLists.txt
+++ b/src/yuzu_cmd/CMakeLists.txt
@@ -20,7 +20,6 @@ add_executable(yuzu-cmd
20 emu_window/emu_window_sdl2_gl.h 20 emu_window/emu_window_sdl2_gl.h
21 emu_window/emu_window_sdl2_vk.cpp 21 emu_window/emu_window_sdl2_vk.cpp
22 emu_window/emu_window_sdl2_vk.h 22 emu_window/emu_window_sdl2_vk.h
23 resource.h
24 yuzu.cpp 23 yuzu.cpp
25 yuzu.rc 24 yuzu.rc
26) 25)
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 43877fc98..7e1d5f379 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -4,13 +4,23 @@
4 4
5#include <memory> 5#include <memory>
6#include <sstream> 6#include <sstream>
7
8// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307
9#ifdef __clang__
10#pragma clang diagnostic push
11#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
12#endif
7#include <SDL.h> 13#include <SDL.h>
14#ifdef __clang__
15#pragma clang diagnostic pop
16#endif
17
8#include <inih/cpp/INIReader.h> 18#include <inih/cpp/INIReader.h>
9#include "common/file_util.h" 19#include "common/file_util.h"
10#include "common/logging/log.h" 20#include "common/logging/log.h"
11#include "common/param_package.h" 21#include "common/param_package.h"
22#include "common/settings.h"
12#include "core/hle/service/acc/profile_manager.h" 23#include "core/hle/service/acc/profile_manager.h"
13#include "core/settings.h"
14#include "input_common/main.h" 24#include "input_common/main.h"
15#include "input_common/udp/client.h" 25#include "input_common/udp/client.h"
16#include "yuzu_cmd/config.h" 26#include "yuzu_cmd/config.h"
@@ -428,6 +438,10 @@ void Config::ReadValues() {
428 Settings::values.reporting_services = 438 Settings::values.reporting_services =
429 sdl2_config->GetBoolean("Debugging", "reporting_services", false); 439 sdl2_config->GetBoolean("Debugging", "reporting_services", false);
430 Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false); 440 Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false);
441 Settings::values.use_debug_asserts =
442 sdl2_config->GetBoolean("Debugging", "use_debug_asserts", false);
443 Settings::values.use_auto_stub = sdl2_config->GetBoolean("Debugging", "use_auto_stub", false);
444
431 Settings::values.disable_macro_jit = 445 Settings::values.disable_macro_jit =
432 sdl2_config->GetBoolean("Debugging", "disable_macro_jit", false); 446 sdl2_config->GetBoolean("Debugging", "disable_macro_jit", false);
433 447
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 3ee0e037d..4ce8e08e4 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -325,6 +325,12 @@ dump_nso=false
325# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode 325# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode
326# false: Retail/Normal Mode (default), true: Kiosk Mode 326# false: Retail/Normal Mode (default), true: Kiosk Mode
327quest_flag = 327quest_flag =
328# Determines whether debug asserts should be enabled, which will throw an exception on asserts.
329# false: Disabled (default), true: Enabled
330use_debug_asserts =
331# Determines whether unimplemented HLE service calls should be automatically stubbed.
332# false: Disabled (default), true: Enabled
333use_auto_stub =
328# Enables/Disables the macro JIT compiler 334# Enables/Disables the macro JIT compiler
329disable_macro_jit=false 335disable_macro_jit=false
330 336
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index ce8b7c218..d64f81106 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -2,7 +2,16 @@
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// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307
6#ifdef __clang__
7#pragma clang diagnostic push
8#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
9#endif
5#include <SDL.h> 10#include <SDL.h>
11#ifdef __clang__
12#pragma clang diagnostic pop
13#endif
14
6#include "common/logging/log.h" 15#include "common/logging/log.h"
7#include "common/scm_rev.h" 16#include "common/scm_rev.h"
8#include "core/core.h" 17#include "core/core.h"
@@ -229,6 +238,6 @@ void EmuWindow_SDL2::SetWindowIcon() {
229 SDL_FreeSurface(window_icon); 238 SDL_FreeSurface(window_icon);
230} 239}
231 240
232void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) { 241void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) {
233 SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second); 242 SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second);
234} 243}
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h
index 0e17bbca7..1b9ab5b93 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h
@@ -71,7 +71,7 @@ protected:
71 void Fullscreen(); 71 void Fullscreen();
72 72
73 /// Called when a configuration change affects the minimal size of the window 73 /// Called when a configuration change affects the minimal size of the window
74 void OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) override; 74 void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override;
75 75
76 /// Is the window still open? 76 /// Is the window still open?
77 bool is_open = true; 77 bool is_open = true;
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
index a02485c14..3c49a300b 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
@@ -5,16 +5,26 @@
5#include <algorithm> 5#include <algorithm>
6#include <cstdlib> 6#include <cstdlib>
7#include <string> 7#include <string>
8
8#define SDL_MAIN_HANDLED 9#define SDL_MAIN_HANDLED
10// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307
11#ifdef __clang__
12#pragma clang diagnostic push
13#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
14#endif
9#include <SDL.h> 15#include <SDL.h>
16#ifdef __clang__
17#pragma clang diagnostic pop
18#endif
19
10#include <fmt/format.h> 20#include <fmt/format.h>
11#include <glad/glad.h> 21#include <glad/glad.h>
12#include "common/assert.h" 22#include "common/assert.h"
13#include "common/logging/log.h" 23#include "common/logging/log.h"
14#include "common/scm_rev.h" 24#include "common/scm_rev.h"
25#include "common/settings.h"
15#include "common/string_util.h" 26#include "common/string_util.h"
16#include "core/core.h" 27#include "core/core.h"
17#include "core/settings.h"
18#include "input_common/keyboard.h" 28#include "input_common/keyboard.h"
19#include "input_common/main.h" 29#include "input_common/main.h"
20#include "video_core/renderer_base.h" 30#include "video_core/renderer_base.h"
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
index 6f9b00461..3401ad4b4 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
@@ -11,12 +11,20 @@
11#include "common/assert.h" 11#include "common/assert.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "common/scm_rev.h" 13#include "common/scm_rev.h"
14#include "core/settings.h" 14#include "common/settings.h"
15#include "video_core/renderer_vulkan/renderer_vulkan.h" 15#include "video_core/renderer_vulkan/renderer_vulkan.h"
16#include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h" 16#include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h"
17 17
18// Include these late to avoid polluting everything with Xlib macros 18// Include these late to avoid polluting everything with Xlib macros
19// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307
20#ifdef __clang__
21#pragma clang diagnostic push
22#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
23#endif
19#include <SDL.h> 24#include <SDL.h>
25#ifdef __clang__
26#pragma clang diagnostic pop
27#endif
20#include <SDL_syswm.h> 28#include <SDL_syswm.h>
21 29
22EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem) 30EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem)
diff --git a/src/yuzu_cmd/resource.h b/src/yuzu_cmd/resource.h
deleted file mode 100644
index df8e459e4..000000000
--- a/src/yuzu_cmd/resource.h
+++ /dev/null
@@ -1,16 +0,0 @@
1//{{NO_DEPENDENCIES}}
2// Microsoft Visual C++ generated include file.
3// Used by pcafe.rc
4//
5#define IDI_ICON3 103
6
7// Next default values for new objects
8//
9#ifdef APSTUDIO_INVOKED
10#ifndef APSTUDIO_READONLY_SYMBOLS
11#define _APS_NEXT_RESOURCE_VALUE 105
12#define _APS_NEXT_COMMAND_VALUE 40001
13#define _APS_NEXT_CONTROL_VALUE 1001
14#define _APS_NEXT_SYMED_VALUE 101
15#endif
16#endif
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 982c41785..4871ac3bb 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -20,6 +20,7 @@
20#include "common/nvidia_flags.h" 20#include "common/nvidia_flags.h"
21#include "common/scm_rev.h" 21#include "common/scm_rev.h"
22#include "common/scope_exit.h" 22#include "common/scope_exit.h"
23#include "common/settings.h"
23#include "common/string_util.h" 24#include "common/string_util.h"
24#include "common/telemetry.h" 25#include "common/telemetry.h"
25#include "core/core.h" 26#include "core/core.h"
@@ -29,7 +30,6 @@
29#include "core/hle/kernel/process.h" 30#include "core/hle/kernel/process.h"
30#include "core/hle/service/filesystem/filesystem.h" 31#include "core/hle/service/filesystem/filesystem.h"
31#include "core/loader/loader.h" 32#include "core/loader/loader.h"
32#include "core/settings.h"
33#include "core/telemetry_session.h" 33#include "core/telemetry_session.h"
34#include "input_common/main.h" 34#include "input_common/main.h"
35#include "video_core/renderer_base.h" 35#include "video_core/renderer_base.h"
@@ -74,14 +74,16 @@ static void PrintVersion() {
74} 74}
75 75
76static void InitializeLogging() { 76static void InitializeLogging() {
77 using namespace Common;
78
77 Log::Filter log_filter(Log::Level::Debug); 79 Log::Filter log_filter(Log::Level::Debug);
78 log_filter.ParseFilterString(Settings::values.log_filter); 80 log_filter.ParseFilterString(Settings::values.log_filter);
79 Log::SetGlobalFilter(log_filter); 81 Log::SetGlobalFilter(log_filter);
80 82
81 Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>()); 83 Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>());
82 84
83 const std::string& log_dir = Common::FS::GetUserPath(Common::FS::UserPath::LogDir); 85 const std::string& log_dir = FS::GetUserPath(FS::UserPath::LogDir);
84 Common::FS::CreateFullPath(log_dir); 86 FS::CreateFullPath(log_dir);
85 Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE)); 87 Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE));
86#ifdef _WIN32 88#ifdef _WIN32
87 Log::AddBackend(std::make_unique<Log::DebuggerBackend>()); 89 Log::AddBackend(std::make_unique<Log::DebuggerBackend>());
@@ -164,7 +166,7 @@ int main(int argc, char** argv) {
164 InputCommon::InputSubsystem input_subsystem; 166 InputCommon::InputSubsystem input_subsystem;
165 167
166 // Apply the command line arguments 168 // Apply the command line arguments
167 Settings::Apply(system); 169 system.ApplySettings();
168 170
169 std::unique_ptr<EmuWindow_SDL2> emu_window; 171 std::unique_ptr<EmuWindow_SDL2> emu_window;
170 switch (Settings::values.renderer_backend.GetValue()) { 172 switch (Settings::values.renderer_backend.GetValue()) {