summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.ci/scripts/linux/docker.sh12
-rw-r--r--.ci/templates/build-msvc.yml2
-rw-r--r--.gitmodules3
-rw-r--r--CMakeLists.txt109
-rw-r--r--CMakeModules/DownloadExternals.cmake22
-rw-r--r--dist/icons/overlay/arrow_left.pngbin0 -> 1490 bytes
-rw-r--r--dist/icons/overlay/arrow_left_dark.pngbin0 -> 712 bytes
-rw-r--r--dist/icons/overlay/arrow_right.pngbin0 -> 1394 bytes
-rw-r--r--dist/icons/overlay/arrow_right_dark.pngbin0 -> 683 bytes
-rw-r--r--dist/icons/overlay/button_A.pngbin0 -> 3494 bytes
-rw-r--r--dist/icons/overlay/button_A_dark.pngbin0 -> 3167 bytes
-rw-r--r--dist/icons/overlay/button_B.pngbin0 -> 3375 bytes
-rw-r--r--dist/icons/overlay/button_B_dark.pngbin0 -> 2975 bytes
-rw-r--r--dist/icons/overlay/button_L.pngbin0 -> 796 bytes
-rw-r--r--dist/icons/overlay/button_L_dark.pngbin0 -> 745 bytes
-rw-r--r--dist/icons/overlay/button_R.pngbin0 -> 1841 bytes
-rw-r--r--dist/icons/overlay/button_R_dark.pngbin0 -> 1835 bytes
-rw-r--r--dist/icons/overlay/button_X.pngbin0 -> 3968 bytes
-rw-r--r--dist/icons/overlay/button_X_dark.pngbin0 -> 3530 bytes
-rw-r--r--dist/icons/overlay/button_Y.pngbin0 -> 3337 bytes
-rw-r--r--dist/icons/overlay/button_Y_dark.pngbin0 -> 2883 bytes
-rw-r--r--dist/icons/overlay/button_minus.pngbin0 -> 2401 bytes
-rw-r--r--dist/icons/overlay/button_minus_dark.pngbin0 -> 1969 bytes
-rw-r--r--dist/icons/overlay/button_plus.pngbin0 -> 2497 bytes
-rw-r--r--dist/icons/overlay/button_plus_dark.pngbin0 -> 2066 bytes
-rw-r--r--dist/icons/overlay/button_press_stick.pngbin0 -> 5225 bytes
-rw-r--r--dist/icons/overlay/button_press_stick_dark.pngbin0 -> 3636 bytes
-rw-r--r--dist/icons/overlay/controller_dual_joycon.pngbin0 -> 7312 bytes
-rw-r--r--dist/icons/overlay/controller_dual_joycon_dark.pngbin0 -> 5889 bytes
-rw-r--r--dist/icons/overlay/controller_handheld.pngbin0 -> 4645 bytes
-rw-r--r--dist/icons/overlay/controller_handheld_dark.pngbin0 -> 3745 bytes
-rw-r--r--dist/icons/overlay/controller_pro.pngbin0 -> 9493 bytes
-rw-r--r--dist/icons/overlay/controller_pro_dark.pngbin0 -> 7488 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left.pngbin0 -> 7489 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left_a.pngbin0 -> 2609 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left_a_dark.pngbin0 -> 2564 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left_b.pngbin0 -> 2559 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left_b_dark.pngbin0 -> 2383 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left_dark.pngbin0 -> 6768 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left_x.pngbin0 -> 2541 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left_x_dark.pngbin0 -> 2392 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left_y.pngbin0 -> 2641 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left_y_dark.pngbin0 -> 2639 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_right.pngbin0 -> 7497 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_right_dark.pngbin0 -> 6729 bytes
-rw-r--r--dist/icons/overlay/osk_button_B.pngbin0 -> 741 bytes
-rw-r--r--dist/icons/overlay/osk_button_B_dark.pngbin0 -> 767 bytes
-rw-r--r--dist/icons/overlay/osk_button_B_dark_disabled.pngbin0 -> 781 bytes
-rw-r--r--dist/icons/overlay/osk_button_B_disabled.pngbin0 -> 791 bytes
-rw-r--r--dist/icons/overlay/osk_button_Y.pngbin0 -> 726 bytes
-rw-r--r--dist/icons/overlay/osk_button_Y_dark.pngbin0 -> 502 bytes
-rw-r--r--dist/icons/overlay/osk_button_Y_dark_disabled.pngbin0 -> 694 bytes
-rw-r--r--dist/icons/overlay/osk_button_Y_disabled.pngbin0 -> 699 bytes
-rw-r--r--dist/icons/overlay/osk_button_backspace.pngbin0 -> 2919 bytes
-rw-r--r--dist/icons/overlay/osk_button_backspace_dark.pngbin0 -> 2958 bytes
-rw-r--r--dist/icons/overlay/osk_button_plus.pngbin0 -> 626 bytes
-rw-r--r--dist/icons/overlay/osk_button_plus_dark.pngbin0 -> 676 bytes
-rw-r--r--dist/icons/overlay/osk_button_plus_dark_disabled.pngbin0 -> 645 bytes
-rw-r--r--dist/icons/overlay/osk_button_plus_disabled.pngbin0 -> 664 bytes
-rw-r--r--dist/icons/overlay/osk_button_shift.pngbin0 -> 1876 bytes
-rw-r--r--dist/icons/overlay/osk_button_shift_dark.pngbin0 -> 2003 bytes
-rw-r--r--dist/icons/overlay/osk_button_shift_lock_off.pngbin0 -> 281 bytes
-rw-r--r--dist/icons/overlay/osk_button_shift_lock_on.pngbin0 -> 274 bytes
-rw-r--r--dist/icons/overlay/osk_button_shift_on.pngbin0 -> 1573 bytes
-rw-r--r--dist/icons/overlay/osk_button_shift_on_dark.pngbin0 -> 1937 bytes
-rw-r--r--dist/icons/overlay/overlay.qrc64
-rw-r--r--dist/qt_themes/default/style.qss377
-rw-r--r--dist/qt_themes/qdarkstyle/style.qss399
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/style.qss439
-rw-r--r--externals/CMakeLists.txt5
m---------externals/SDL0
-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
257 files changed, 10099 insertions, 903 deletions
diff --git a/.ci/scripts/linux/docker.sh b/.ci/scripts/linux/docker.sh
index 39b1f77d7..1af5ded3d 100755
--- a/.ci/scripts/linux/docker.sh
+++ b/.ci/scripts/linux/docker.sh
@@ -8,7 +8,17 @@ cd /yuzu
8ccache -s 8ccache -s
9 9
10mkdir build || true && cd build 10mkdir build || true && cd build
11cmake .. -DDISPLAY_VERSION=$1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DCMAKE_INSTALL_PREFIX="/usr" 11cmake .. \
12 -DBoost_USE_STATIC_LIBS=ON \
13 -DCMAKE_BUILD_TYPE=Release \
14 -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ \
15 -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc \
16 -DCMAKE_INSTALL_PREFIX="/usr" \
17 -DDISPLAY_VERSION=$1 \
18 -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
19 -DENABLE_QT_TRANSLATION=ON \
20 -DUSE_DISCORD_PRESENCE=ON \
21 -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"}
12 22
13make -j$(nproc) 23make -j$(nproc)
14 24
diff --git a/.ci/templates/build-msvc.yml b/.ci/templates/build-msvc.yml
index 097367018..74e688c12 100644
--- a/.ci/templates/build-msvc.yml
+++ b/.ci/templates/build-msvc.yml
@@ -8,7 +8,7 @@ steps:
8 displayName: 'Install vulkan-sdk' 8 displayName: 'Install vulkan-sdk'
9- script: python -m pip install --upgrade pip conan 9- script: python -m pip install --upgrade pip conan
10 displayName: 'Install conan' 10 displayName: 'Install conan'
11- script: refreshenv && mkdir build && cd build && cmake -G "Visual Studio 16 2019" -A x64 -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} .. && cmake --install . --config Release && cd .. 11- script: refreshenv && mkdir build && cd build && cmake -G "Visual Studio 16 2019" -A x64 -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} .. && cmake --install . --config Release && cd ..
12 displayName: 'Configure CMake' 12 displayName: 'Configure CMake'
13- task: MSBuild@1 13- task: MSBuild@1
14 displayName: 'Build' 14 displayName: 'Build'
diff --git a/.gitmodules b/.gitmodules
index a0a89933d..8e5bc4581 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -40,3 +40,6 @@
40[submodule "ffmpeg"] 40[submodule "ffmpeg"]
41 path = externals/ffmpeg 41 path = externals/ffmpeg
42 url = https://git.ffmpeg.org/ffmpeg.git 42 url = https://git.ffmpeg.org/ffmpeg.git
43[submodule "SDL"]
44 path = externals/SDL
45 url = https://github.com/libsdl-org/SDL.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6ea6c650e..15ecb8a9c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,6 +11,7 @@ project(yuzu)
11# Set bundled sdl2/qt as dependent options. 11# Set bundled sdl2/qt as dependent options.
12# OFF by default, but if ENABLE_SDL2 and MSVC are true then ON 12# OFF by default, but if ENABLE_SDL2 and MSVC are true then ON
13option(ENABLE_SDL2 "Enable the SDL2 frontend" ON) 13option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
14CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON "ENABLE_SDL2;MSVC" OFF)
14 15
15option(ENABLE_QT "Enable the Qt frontend" ON) 16option(ENABLE_QT "Enable the Qt frontend" ON)
16option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF) 17option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
@@ -18,7 +19,9 @@ CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" ON "EN
18 19
19option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON) 20option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
20 21
21CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled yuzu" ON "WIN32" OFF) 22option(YUZU_USE_BUNDLED_BOOST "Download bundled Boost" OFF)
23
24CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" ON "WIN32" OFF)
22 25
23option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF) 26option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF)
24 27
@@ -166,8 +169,6 @@ macro(yuzu_find_packages)
166 # Cmake Pkg Prefix Version Conan Pkg 169 # Cmake Pkg Prefix Version Conan Pkg
167 "Catch2 2.13 catch2/2.13.0" 170 "Catch2 2.13 catch2/2.13.0"
168 "fmt 7.1 fmt/7.1.2" 171 "fmt 7.1 fmt/7.1.2"
169 # can't use until https://github.com/bincrafters/community/issues/1173
170 #"libzip 1.5 libzip/1.5.2@bincrafters/stable"
171 "lz4 1.8 lz4/1.9.2" 172 "lz4 1.8 lz4/1.9.2"
172 "nlohmann_json 3.8 nlohmann_json/3.8.0" 173 "nlohmann_json 3.8 nlohmann_json/3.8.0"
173 "ZLIB 1.2 zlib/1.2.11" 174 "ZLIB 1.2 zlib/1.2.11"
@@ -200,7 +201,9 @@ macro(yuzu_find_packages)
200 unset(FN_FORCE_REQUIRED) 201 unset(FN_FORCE_REQUIRED)
201endmacro() 202endmacro()
202 203
203find_package(Boost 1.73.0 COMPONENTS context headers QUIET) 204if (NOT YUZU_USE_BUNDLED_BOOST)
205 find_package(Boost 1.73.0 COMPONENTS context headers QUIET)
206endif()
204if (Boost_FOUND) 207if (Boost_FOUND)
205 set(Boost_LIBRARIES Boost::boost) 208 set(Boost_LIBRARIES Boost::boost)
206 # Conditionally add Boost::context only if the active version of the Conan or system Boost package provides it 209 # Conditionally add Boost::context only if the active version of the Conan or system Boost package provides it
@@ -211,6 +214,20 @@ if (Boost_FOUND)
211 if (TARGET Boost::context) 214 if (TARGET Boost::context)
212 list(APPEND Boost_LIBRARIES Boost::context) 215 list(APPEND Boost_LIBRARIES Boost::context)
213 endif() 216 endif()
217elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR YUZU_USE_BUNDLED_BOOST)
218 message(STATUS "Boost 1.73.0 or newer not found, falling back to externals")
219 set(YUZU_USE_BUNDLED_BOOST ON CACHE BOOL "Download bundled Boost" FORCE)
220
221 # Use yuzu Boost binaries
222 set(Boost_EXT_NAME "boost_1_75_0")
223 set(Boost_PATH "${CMAKE_BINARY_DIR}/externals/${Boost_EXT_NAME}")
224 download_bundled_external("boost/" ${Boost_EXT_NAME} "")
225 set(Boost_USE_DEBUG_RUNTIME FALSE)
226 set(Boost_USE_STATIC_LIBS ON)
227 find_package(Boost 1.75.0 REQUIRED COMPONENTS context headers PATHS ${Boost_PATH} NO_DEFAULT_PATH)
228 # Manually set the include dirs since the find_package sets it incorrectly
229 set(Boost_INCLUDE_DIRS ${Boost_PATH}/include CACHE PATH "Path to Boost headers" FORCE)
230 include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
214else() 231else()
215 message(STATUS "Boost 1.73.0 or newer not found, falling back to Conan") 232 message(STATUS "Boost 1.73.0 or newer not found, falling back to Conan")
216 list(APPEND CONAN_REQUIRED_LIBS "boost/1.73.0") 233 list(APPEND CONAN_REQUIRED_LIBS "boost/1.73.0")
@@ -251,21 +268,45 @@ if(ENABLE_QT)
251 if (ENABLE_QT_TRANSLATION) 268 if (ENABLE_QT_TRANSLATION)
252 find_package(Qt5 REQUIRED COMPONENTS LinguistTools ${QT_PREFIX_HINT}) 269 find_package(Qt5 REQUIRED COMPONENTS LinguistTools ${QT_PREFIX_HINT})
253 endif() 270 endif()
254 if (NOT Qt5_FOUND)
255 list(APPEND CONAN_REQUIRED_LIBS "qt/5.14.1@bincrafters/stable")
256 endif()
257endif() 271endif()
258# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the yuzu_find_package 272# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the yuzu_find_package
259if(ENABLE_SDL2) 273if (ENABLE_SDL2)
260 if(EXISTS ${CMAKE_BINARY_DIR}/sdl2Config.cmake) 274 if (YUZU_USE_BUNDLED_SDL2)
261 include(${CMAKE_BINARY_DIR}/sdl2Config.cmake) 275 # Detect toolchain and platform
262 list(APPEND CMAKE_MODULE_PATH "${CONAN_SDL2_ROOT_RELEASE}") 276 if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
263 list(APPEND CMAKE_PREFIX_PATH "${CONAN_SDL2_ROOT_RELEASE}") 277 set(SDL2_VER "SDL2-2.0.14")
264 endif() 278 else()
265 find_package(SDL2) 279 message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable YUZU_USE_BUNDLED_SDL2 and provide your own.")
266 if (NOT SDL2_FOUND) 280 endif()
267 # otherwise add this to the list of libraries to install 281
268 list(APPEND CONAN_REQUIRED_LIBS "sdl2/2.0.14@bincrafters/stable") 282 if (DEFINED SDL2_VER)
283 download_bundled_external("sdl2/" ${SDL2_VER} SDL2_PREFIX)
284 endif()
285
286 set(SDL2_FOUND YES)
287 set(SDL2_INCLUDE_DIR "${SDL2_PREFIX}/include" CACHE PATH "Path to SDL2 headers")
288 set(SDL2_LIBRARY "${SDL2_PREFIX}/lib/x64/SDL2.lib" CACHE PATH "Path to SDL2 library")
289 set(SDL2_DLL_DIR "${SDL2_PREFIX}/lib/x64/" CACHE PATH "Path to SDL2.dll")
290
291 add_library(SDL2 INTERFACE)
292 target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARY}")
293 target_include_directories(SDL2 INTERFACE "${SDL2_INCLUDE_DIR}")
294 else()
295 find_package(SDL2 2.0.14 QUIET)
296
297 if (SDL2_FOUND)
298 # Some installations don't set SDL2_LIBRARIES
299 if("${SDL2_LIBRARIES}" STREQUAL "")
300 message(WARNING "SDL2_LIBRARIES wasn't set, manually setting to SDL2::SDL2")
301 set(SDL2_LIBRARIES "SDL2::SDL2")
302 endif()
303
304 include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
305 add_library(SDL2 INTERFACE)
306 target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}")
307 else()
308 message(STATUS "SDL2 2.0.14 or newer not found, falling back to externals.")
309 endif()
269 endif() 310 endif()
270endif() 311endif()
271 312
@@ -287,9 +328,6 @@ if (CONAN_REQUIRED_LIBS)
287 ) 328 )
288 329
289 conan_check(VERSION 1.24.0 REQUIRED) 330 conan_check(VERSION 1.24.0 REQUIRED)
290 # Add the bincrafters remote
291 conan_add_remote(NAME bincrafters
292 URL https://api.bintray.com/conan/bincrafters/public-conan)
293 331
294 # Manually add iconv to fix a dep conflict between qt and sdl2 332 # Manually add iconv to fix a dep conflict between qt and sdl2
295 # We don't need to add it through find_package or anything since the other two can find it just fine 333 # We don't need to add it through find_package or anything since the other two can find it just fine
@@ -340,11 +378,6 @@ if (CONAN_REQUIRED_LIBS)
340 find_package(Qt5 REQUIRED COMPONENTS WebEngineCore WebEngineWidgets) 378 find_package(Qt5 REQUIRED COMPONENTS WebEngineCore WebEngineWidgets)
341 endif() 379 endif()
342 endif() 380 endif()
343 if(ENABLE_SDL2)
344 list(APPEND CMAKE_MODULE_PATH "${CONAN_SDL2_ROOT_RELEASE}")
345 list(APPEND CMAKE_PREFIX_PATH "${CONAN_SDL2_ROOT_RELEASE}")
346 find_package(SDL2 REQUIRED)
347 endif()
348 381
349endif() 382endif()
350 383
@@ -360,23 +393,6 @@ elseif (TARGET Boost::boost)
360 add_library(boost ALIAS Boost::boost) 393 add_library(boost ALIAS Boost::boost)
361endif() 394endif()
362 395
363if (TARGET sdl2::sdl2)
364 # imported from the conan generated sdl2Config.cmake
365 set_target_properties(sdl2::sdl2 PROPERTIES IMPORTED_GLOBAL TRUE)
366 add_library(SDL2 ALIAS sdl2::sdl2)
367elseif(SDL2_FOUND)
368 # found through the system package manager
369 # Some installations don't set SDL2_LIBRARIES
370 if("${SDL2_LIBRARIES}" STREQUAL "")
371 message(WARNING "SDL2_LIBRARIES wasn't set, manually setting to SDL2::SDL2")
372 set(SDL2_LIBRARIES "SDL2::SDL2")
373 endif()
374
375 include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
376 add_library(SDL2 INTERFACE)
377 target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}")
378endif()
379
380# Ensure libusb is properly configured (based on dolphin libusb include) 396# Ensure libusb is properly configured (based on dolphin libusb include)
381if(NOT APPLE) 397if(NOT APPLE)
382 include(FindPkgConfig) 398 include(FindPkgConfig)
@@ -396,7 +412,7 @@ set(FFmpeg_COMPONENTS
396 412
397if (NOT YUZU_USE_BUNDLED_FFMPEG) 413if (NOT YUZU_USE_BUNDLED_FFMPEG)
398 # Use system installed FFmpeg 414 # Use system installed FFmpeg
399 find_package(FFmpeg REQUIRED COMPONENTS ${FFmpeg_COMPONENTS}) 415 find_package(FFmpeg QUIET COMPONENTS ${FFmpeg_COMPONENTS})
400 416
401 if (FFmpeg_FOUND) 417 if (FFmpeg_FOUND)
402 # Overwrite aggregate defines from FFmpeg module to avoid over-linking libraries. 418 # Overwrite aggregate defines from FFmpeg module to avoid over-linking libraries.
@@ -435,6 +451,7 @@ if (YUZU_USE_BUNDLED_FFMPEG)
435 set(FFmpeg_FOUND YES) 451 set(FFmpeg_FOUND YES)
436 endif() 452 endif()
437 453
454 unset(FFmpeg_LIBRARIES CACHE)
438 foreach(COMPONENT ${FFmpeg_COMPONENTS}) 455 foreach(COMPONENT ${FFmpeg_COMPONENTS})
439 set(FFmpeg_${COMPONENT}_PREFIX "${FFmpeg_BUILD_DIR}/lib${COMPONENT}") 456 set(FFmpeg_${COMPONENT}_PREFIX "${FFmpeg_BUILD_DIR}/lib${COMPONENT}")
440 set(FFmpeg_${COMPONENT}_LIB_NAME "lib${COMPONENT}.a") 457 set(FFmpeg_${COMPONENT}_LIB_NAME "lib${COMPONENT}.a")
@@ -447,7 +464,7 @@ if (YUZU_USE_BUNDLED_FFMPEG)
447 endforeach() 464 endforeach()
448 465
449 set(FFmpeg_INCLUDE_DIR 466 set(FFmpeg_INCLUDE_DIR
450 ${FFmpeg_PREFIX} 467 "${FFmpeg_PREFIX};${FFmpeg_BUILD_DIR}"
451 CACHE PATH "Path to FFmpeg headers" FORCE) 468 CACHE PATH "Path to FFmpeg headers" FORCE)
452 469
453 # `configure` parameters builds only exactly what yuzu needs from FFmpeg 470 # `configure` parameters builds only exactly what yuzu needs from FFmpeg
@@ -494,13 +511,11 @@ if (YUZU_USE_BUNDLED_FFMPEG)
494 511
495 # ALL makes this custom target build every time 512 # ALL makes this custom target build every time
496 # but it won't actually build if the DEPENDS parameter is up to date 513 # but it won't actually build if the DEPENDS parameter is up to date
497 add_custom_target(ffmpeg-build ALL DEPENDS ${FFmpeg_LIBRARIES})
498 add_custom_target(ffmpeg-configure ALL DEPENDS ${FFmpeg_MAKEFILE}) 514 add_custom_target(ffmpeg-configure ALL DEPENDS ${FFmpeg_MAKEFILE})
515 add_custom_target(ffmpeg-build ALL DEPENDS ${FFmpeg_LIBRARIES} ffmpeg-configure)
499 516
500 if (FFmpeg_FOUND) 517 if (FFmpeg_FOUND)
501 message(STATUS "Found FFmpeg version ${FFmpeg_VERSION}") 518 message(STATUS "Found FFmpeg version ${FFmpeg_VERSION}")
502
503 add_dependencies(ffmpeg-build ffmpeg-configure)
504 else() 519 else()
505 message(FATAL_ERROR "FFmpeg not found") 520 message(FATAL_ERROR "FFmpeg not found")
506 endif() 521 endif()
diff --git a/CMakeModules/DownloadExternals.cmake b/CMakeModules/DownloadExternals.cmake
index d3f91764d..4c4dec5ff 100644
--- a/CMakeModules/DownloadExternals.cmake
+++ b/CMakeModules/DownloadExternals.cmake
@@ -4,15 +4,29 @@
4# remote_path: path to the file to download, relative to the remote repository root 4# remote_path: path to the file to download, relative to the remote repository root
5# prefix_var: name of a variable which will be set with the path to the extracted contents 5# prefix_var: name of a variable which will be set with the path to the extracted contents
6function(download_bundled_external remote_path lib_name prefix_var) 6function(download_bundled_external remote_path lib_name prefix_var)
7
8set(package_repo "no_platform")
9set(package_extension "no_platform")
10if (WIN32)
11 set(package_repo "ext-windows-bin/raw/master/")
12 set(package_extension ".7z")
13elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
14 set(package_repo "ext-linux-bin/raw/main/")
15 set(package_extension ".tar.xz")
16else()
17 message(FATAL_ERROR "No package available for this platform")
18endif()
19set(package_url "https://github.com/yuzu-emu/${package_repo}")
20
7set(prefix "${CMAKE_BINARY_DIR}/externals/${lib_name}") 21set(prefix "${CMAKE_BINARY_DIR}/externals/${lib_name}")
8if (NOT EXISTS "${prefix}") 22if (NOT EXISTS "${prefix}")
9 message(STATUS "Downloading binaries for ${lib_name}...") 23 message(STATUS "Downloading binaries for ${lib_name}...")
10 file(DOWNLOAD 24 file(DOWNLOAD
11 https://github.com/yuzu-emu/ext-windows-bin/raw/master/${remote_path}${lib_name}.7z 25 ${package_url}${remote_path}${lib_name}${package_extension}
12 "${CMAKE_BINARY_DIR}/externals/${lib_name}.7z" SHOW_PROGRESS) 26 "${CMAKE_BINARY_DIR}/externals/${lib_name}${package_extension}" SHOW_PROGRESS)
13 execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${CMAKE_BINARY_DIR}/externals/${lib_name}.7z" 27 execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${CMAKE_BINARY_DIR}/externals/${lib_name}${package_extension}"
14 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals") 28 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals")
15endif() 29endif()
16message(STATUS "Using bundled binaries at ${prefix}") 30message(STATUS "Using bundled binaries at ${prefix}")
17set(${prefix_var} "${prefix}" PARENT_SCOPE) 31set(${prefix_var} "${prefix}" PARENT_SCOPE)
18endfunction() \ No newline at end of file 32endfunction()
diff --git a/dist/icons/overlay/arrow_left.png b/dist/icons/overlay/arrow_left.png
new file mode 100644
index 000000000..a5d4fecfe
--- /dev/null
+++ b/dist/icons/overlay/arrow_left.png
Binary files differ
diff --git a/dist/icons/overlay/arrow_left_dark.png b/dist/icons/overlay/arrow_left_dark.png
new file mode 100644
index 000000000..f73672a59
--- /dev/null
+++ b/dist/icons/overlay/arrow_left_dark.png
Binary files differ
diff --git a/dist/icons/overlay/arrow_right.png b/dist/icons/overlay/arrow_right.png
new file mode 100644
index 000000000..e47ee94bd
--- /dev/null
+++ b/dist/icons/overlay/arrow_right.png
Binary files differ
diff --git a/dist/icons/overlay/arrow_right_dark.png b/dist/icons/overlay/arrow_right_dark.png
new file mode 100644
index 000000000..91cf83d2c
--- /dev/null
+++ b/dist/icons/overlay/arrow_right_dark.png
Binary files differ
diff --git a/dist/icons/overlay/button_A.png b/dist/icons/overlay/button_A.png
new file mode 100644
index 000000000..fd90f8b42
--- /dev/null
+++ b/dist/icons/overlay/button_A.png
Binary files differ
diff --git a/dist/icons/overlay/button_A_dark.png b/dist/icons/overlay/button_A_dark.png
new file mode 100644
index 000000000..d6b5514fa
--- /dev/null
+++ b/dist/icons/overlay/button_A_dark.png
Binary files differ
diff --git a/dist/icons/overlay/button_B.png b/dist/icons/overlay/button_B.png
new file mode 100644
index 000000000..e8927addc
--- /dev/null
+++ b/dist/icons/overlay/button_B.png
Binary files differ
diff --git a/dist/icons/overlay/button_B_dark.png b/dist/icons/overlay/button_B_dark.png
new file mode 100644
index 000000000..3acbeddcd
--- /dev/null
+++ b/dist/icons/overlay/button_B_dark.png
Binary files differ
diff --git a/dist/icons/overlay/button_L.png b/dist/icons/overlay/button_L.png
new file mode 100644
index 000000000..77838369e
--- /dev/null
+++ b/dist/icons/overlay/button_L.png
Binary files differ
diff --git a/dist/icons/overlay/button_L_dark.png b/dist/icons/overlay/button_L_dark.png
new file mode 100644
index 000000000..c96a5e868
--- /dev/null
+++ b/dist/icons/overlay/button_L_dark.png
Binary files differ
diff --git a/dist/icons/overlay/button_R.png b/dist/icons/overlay/button_R.png
new file mode 100644
index 000000000..4e5553954
--- /dev/null
+++ b/dist/icons/overlay/button_R.png
Binary files differ
diff --git a/dist/icons/overlay/button_R_dark.png b/dist/icons/overlay/button_R_dark.png
new file mode 100644
index 000000000..ed13199c4
--- /dev/null
+++ b/dist/icons/overlay/button_R_dark.png
Binary files differ
diff --git a/dist/icons/overlay/button_X.png b/dist/icons/overlay/button_X.png
new file mode 100644
index 000000000..fe70fb685
--- /dev/null
+++ b/dist/icons/overlay/button_X.png
Binary files differ
diff --git a/dist/icons/overlay/button_X_dark.png b/dist/icons/overlay/button_X_dark.png
new file mode 100644
index 000000000..b2c83d0c1
--- /dev/null
+++ b/dist/icons/overlay/button_X_dark.png
Binary files differ
diff --git a/dist/icons/overlay/button_Y.png b/dist/icons/overlay/button_Y.png
new file mode 100644
index 000000000..ca0de569d
--- /dev/null
+++ b/dist/icons/overlay/button_Y.png
Binary files differ
diff --git a/dist/icons/overlay/button_Y_dark.png b/dist/icons/overlay/button_Y_dark.png
new file mode 100644
index 000000000..0f3e4df25
--- /dev/null
+++ b/dist/icons/overlay/button_Y_dark.png
Binary files differ
diff --git a/dist/icons/overlay/button_minus.png b/dist/icons/overlay/button_minus.png
new file mode 100644
index 000000000..7b315fe79
--- /dev/null
+++ b/dist/icons/overlay/button_minus.png
Binary files differ
diff --git a/dist/icons/overlay/button_minus_dark.png b/dist/icons/overlay/button_minus_dark.png
new file mode 100644
index 000000000..6dfcdc1b5
--- /dev/null
+++ b/dist/icons/overlay/button_minus_dark.png
Binary files differ
diff --git a/dist/icons/overlay/button_plus.png b/dist/icons/overlay/button_plus.png
new file mode 100644
index 000000000..4d8090d7d
--- /dev/null
+++ b/dist/icons/overlay/button_plus.png
Binary files differ
diff --git a/dist/icons/overlay/button_plus_dark.png b/dist/icons/overlay/button_plus_dark.png
new file mode 100644
index 000000000..abe8b9c95
--- /dev/null
+++ b/dist/icons/overlay/button_plus_dark.png
Binary files differ
diff --git a/dist/icons/overlay/button_press_stick.png b/dist/icons/overlay/button_press_stick.png
new file mode 100644
index 000000000..6d0254d50
--- /dev/null
+++ b/dist/icons/overlay/button_press_stick.png
Binary files differ
diff --git a/dist/icons/overlay/button_press_stick_dark.png b/dist/icons/overlay/button_press_stick_dark.png
new file mode 100644
index 000000000..757d0ab29
--- /dev/null
+++ b/dist/icons/overlay/button_press_stick_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_dual_joycon.png b/dist/icons/overlay/controller_dual_joycon.png
new file mode 100644
index 000000000..8e8b5ad41
--- /dev/null
+++ b/dist/icons/overlay/controller_dual_joycon.png
Binary files differ
diff --git a/dist/icons/overlay/controller_dual_joycon_dark.png b/dist/icons/overlay/controller_dual_joycon_dark.png
new file mode 100644
index 000000000..63e03eb4e
--- /dev/null
+++ b/dist/icons/overlay/controller_dual_joycon_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_handheld.png b/dist/icons/overlay/controller_handheld.png
new file mode 100644
index 000000000..deb375011
--- /dev/null
+++ b/dist/icons/overlay/controller_handheld.png
Binary files differ
diff --git a/dist/icons/overlay/controller_handheld_dark.png b/dist/icons/overlay/controller_handheld_dark.png
new file mode 100644
index 000000000..1f5317aa0
--- /dev/null
+++ b/dist/icons/overlay/controller_handheld_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_pro.png b/dist/icons/overlay/controller_pro.png
new file mode 100644
index 000000000..67cf86d5c
--- /dev/null
+++ b/dist/icons/overlay/controller_pro.png
Binary files differ
diff --git a/dist/icons/overlay/controller_pro_dark.png b/dist/icons/overlay/controller_pro_dark.png
new file mode 100644
index 000000000..7be655b96
--- /dev/null
+++ b/dist/icons/overlay/controller_pro_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left.png b/dist/icons/overlay/controller_single_joycon_left.png
new file mode 100644
index 000000000..340ddc71b
--- /dev/null
+++ b/dist/icons/overlay/controller_single_joycon_left.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left_a.png b/dist/icons/overlay/controller_single_joycon_left_a.png
new file mode 100644
index 000000000..e0f5c2ad4
--- /dev/null
+++ b/dist/icons/overlay/controller_single_joycon_left_a.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left_a_dark.png b/dist/icons/overlay/controller_single_joycon_left_a_dark.png
new file mode 100644
index 000000000..53e04781e
--- /dev/null
+++ b/dist/icons/overlay/controller_single_joycon_left_a_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left_b.png b/dist/icons/overlay/controller_single_joycon_left_b.png
new file mode 100644
index 000000000..7429450a3
--- /dev/null
+++ b/dist/icons/overlay/controller_single_joycon_left_b.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left_b_dark.png b/dist/icons/overlay/controller_single_joycon_left_b_dark.png
new file mode 100644
index 000000000..3bd97a8eb
--- /dev/null
+++ b/dist/icons/overlay/controller_single_joycon_left_b_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left_dark.png b/dist/icons/overlay/controller_single_joycon_left_dark.png
new file mode 100644
index 000000000..24ed2c44c
--- /dev/null
+++ b/dist/icons/overlay/controller_single_joycon_left_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left_x.png b/dist/icons/overlay/controller_single_joycon_left_x.png
new file mode 100644
index 000000000..4615172a3
--- /dev/null
+++ b/dist/icons/overlay/controller_single_joycon_left_x.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left_x_dark.png b/dist/icons/overlay/controller_single_joycon_left_x_dark.png
new file mode 100644
index 000000000..119e3091a
--- /dev/null
+++ b/dist/icons/overlay/controller_single_joycon_left_x_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left_y.png b/dist/icons/overlay/controller_single_joycon_left_y.png
new file mode 100644
index 000000000..24421d8b9
--- /dev/null
+++ b/dist/icons/overlay/controller_single_joycon_left_y.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left_y_dark.png b/dist/icons/overlay/controller_single_joycon_left_y_dark.png
new file mode 100644
index 000000000..fdf177c12
--- /dev/null
+++ b/dist/icons/overlay/controller_single_joycon_left_y_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_right.png b/dist/icons/overlay/controller_single_joycon_right.png
new file mode 100644
index 000000000..5b8fc0eff
--- /dev/null
+++ b/dist/icons/overlay/controller_single_joycon_right.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_right_dark.png b/dist/icons/overlay/controller_single_joycon_right_dark.png
new file mode 100644
index 000000000..afa80e6ef
--- /dev/null
+++ b/dist/icons/overlay/controller_single_joycon_right_dark.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_B.png b/dist/icons/overlay/osk_button_B.png
new file mode 100644
index 000000000..f4a041178
--- /dev/null
+++ b/dist/icons/overlay/osk_button_B.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_B_dark.png b/dist/icons/overlay/osk_button_B_dark.png
new file mode 100644
index 000000000..2d2bffcca
--- /dev/null
+++ b/dist/icons/overlay/osk_button_B_dark.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_B_dark_disabled.png b/dist/icons/overlay/osk_button_B_dark_disabled.png
new file mode 100644
index 000000000..93c102b1b
--- /dev/null
+++ b/dist/icons/overlay/osk_button_B_dark_disabled.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_B_disabled.png b/dist/icons/overlay/osk_button_B_disabled.png
new file mode 100644
index 000000000..5900982f6
--- /dev/null
+++ b/dist/icons/overlay/osk_button_B_disabled.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_Y.png b/dist/icons/overlay/osk_button_Y.png
new file mode 100644
index 000000000..b08b4e26b
--- /dev/null
+++ b/dist/icons/overlay/osk_button_Y.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_Y_dark.png b/dist/icons/overlay/osk_button_Y_dark.png
new file mode 100644
index 000000000..1fba9ca93
--- /dev/null
+++ b/dist/icons/overlay/osk_button_Y_dark.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_Y_dark_disabled.png b/dist/icons/overlay/osk_button_Y_dark_disabled.png
new file mode 100644
index 000000000..6ce53f9e4
--- /dev/null
+++ b/dist/icons/overlay/osk_button_Y_dark_disabled.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_Y_disabled.png b/dist/icons/overlay/osk_button_Y_disabled.png
new file mode 100644
index 000000000..25db07f66
--- /dev/null
+++ b/dist/icons/overlay/osk_button_Y_disabled.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_backspace.png b/dist/icons/overlay/osk_button_backspace.png
new file mode 100644
index 000000000..4ad284720
--- /dev/null
+++ b/dist/icons/overlay/osk_button_backspace.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_backspace_dark.png b/dist/icons/overlay/osk_button_backspace_dark.png
new file mode 100644
index 000000000..19ac8847e
--- /dev/null
+++ b/dist/icons/overlay/osk_button_backspace_dark.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_plus.png b/dist/icons/overlay/osk_button_plus.png
new file mode 100644
index 000000000..5baa5201e
--- /dev/null
+++ b/dist/icons/overlay/osk_button_plus.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_plus_dark.png b/dist/icons/overlay/osk_button_plus_dark.png
new file mode 100644
index 000000000..4cadb438b
--- /dev/null
+++ b/dist/icons/overlay/osk_button_plus_dark.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_plus_dark_disabled.png b/dist/icons/overlay/osk_button_plus_dark_disabled.png
new file mode 100644
index 000000000..b8eb8dc3d
--- /dev/null
+++ b/dist/icons/overlay/osk_button_plus_dark_disabled.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_plus_disabled.png b/dist/icons/overlay/osk_button_plus_disabled.png
new file mode 100644
index 000000000..c23e9d95d
--- /dev/null
+++ b/dist/icons/overlay/osk_button_plus_disabled.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_shift.png b/dist/icons/overlay/osk_button_shift.png
new file mode 100644
index 000000000..f03e30697
--- /dev/null
+++ b/dist/icons/overlay/osk_button_shift.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_shift_dark.png b/dist/icons/overlay/osk_button_shift_dark.png
new file mode 100644
index 000000000..c9cc5cd9a
--- /dev/null
+++ b/dist/icons/overlay/osk_button_shift_dark.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_shift_lock_off.png b/dist/icons/overlay/osk_button_shift_lock_off.png
new file mode 100644
index 000000000..585500b3a
--- /dev/null
+++ b/dist/icons/overlay/osk_button_shift_lock_off.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_shift_lock_on.png b/dist/icons/overlay/osk_button_shift_lock_on.png
new file mode 100644
index 000000000..09077ab01
--- /dev/null
+++ b/dist/icons/overlay/osk_button_shift_lock_on.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_shift_on.png b/dist/icons/overlay/osk_button_shift_on.png
new file mode 100644
index 000000000..e7c1187f9
--- /dev/null
+++ b/dist/icons/overlay/osk_button_shift_on.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_shift_on_dark.png b/dist/icons/overlay/osk_button_shift_on_dark.png
new file mode 100644
index 000000000..58e0d9cf4
--- /dev/null
+++ b/dist/icons/overlay/osk_button_shift_on_dark.png
Binary files differ
diff --git a/dist/icons/overlay/overlay.qrc b/dist/icons/overlay/overlay.qrc
new file mode 100644
index 000000000..d5a21ce10
--- /dev/null
+++ b/dist/icons/overlay/overlay.qrc
@@ -0,0 +1,64 @@
1<RCC>
2 <qresource prefix="overlay">
3 <file>arrow_left.png</file>
4 <file>arrow_left_dark.png</file>
5 <file>arrow_right.png</file>
6 <file>arrow_right_dark.png</file>
7 <file>button_minus.png</file>
8 <file>button_minus_dark.png</file>
9 <file>button_plus.png</file>
10 <file>button_plus_dark.png</file>
11 <file>button_A.png</file>
12 <file>button_A_dark.png</file>
13 <file>button_B.png</file>
14 <file>button_B_dark.png</file>
15 <file>button_X.png</file>
16 <file>button_X_dark.png</file>
17 <file>button_Y.png</file>
18 <file>button_Y_dark.png</file>
19 <file>button_L.png</file>
20 <file>button_L_dark.png</file>
21 <file>button_R.png</file>
22 <file>button_R_dark.png</file>
23 <file>button_press_stick.png</file>
24 <file>button_press_stick_dark.png</file>
25 <file>osk_button_B.png</file>
26 <file>osk_button_B_disabled.png</file>
27 <file>osk_button_B_dark.png</file>
28 <file>osk_button_B_dark_disabled.png</file>
29 <file>osk_button_Y.png</file>
30 <file>osk_button_Y_disabled.png</file>
31 <file>osk_button_Y_dark.png</file>
32 <file>osk_button_Y_dark_disabled.png</file>
33 <file>osk_button_backspace.png</file>
34 <file>osk_button_backspace_dark.png</file>
35 <file>osk_button_plus.png</file>
36 <file>osk_button_plus_disabled.png</file>
37 <file>osk_button_plus_dark.png</file>
38 <file>osk_button_plus_dark_disabled.png</file>
39 <file>osk_button_shift.png</file>
40 <file>osk_button_shift_dark.png</file>
41 <file>osk_button_shift_on.png</file>
42 <file>osk_button_shift_on_dark.png</file>
43 <file>osk_button_shift_lock_on.png</file>
44 <file>osk_button_shift_lock_off.png</file>
45 <file>controller_dual_joycon.png</file>
46 <file>controller_dual_joycon_dark.png</file>
47 <file>controller_pro.png</file>
48 <file>controller_pro_dark.png</file>
49 <file>controller_handheld.png</file>
50 <file>controller_handheld_dark.png</file>
51 <file>controller_single_joycon_left.png</file>
52 <file>controller_single_joycon_left_dark.png</file>
53 <file>controller_single_joycon_right.png</file>
54 <file>controller_single_joycon_right_dark.png</file>
55 <file>controller_single_joycon_left_a.png</file>
56 <file>controller_single_joycon_left_a_dark.png</file>
57 <file>controller_single_joycon_left_b.png</file>
58 <file>controller_single_joycon_left_b_dark.png</file>
59 <file>controller_single_joycon_left_x.png</file>
60 <file>controller_single_joycon_left_x_dark.png</file>
61 <file>controller_single_joycon_left_y.png</file>
62 <file>controller_single_joycon_left_y_dark.png</file>
63 </qresource>
64</RCC>
diff --git a/dist/qt_themes/default/style.qss b/dist/qt_themes/default/style.qss
index 836dd25ca..3bc92b69d 100644
--- a/dist/qt_themes/default/style.qss
+++ b/dist/qt_themes/default/style.qss
@@ -281,3 +281,380 @@ QWidget#controllerPlayer7,
281QWidget#controllerPlayer8 { 281QWidget#controllerPlayer8 {
282 background: transparent; 282 background: transparent;
283} 283}
284
285QDialog#QtSoftwareKeyboardDialog,
286QStackedWidget#topOSK {
287 background: rgba(51, 51, 51, .9);
288}
289
290
291QDialog#OverlayDialog,
292QStackedWidget#stackedDialog {
293 background: rgba(51, 51, 51, .7);
294}
295
296QWidget#boxOSK,
297QWidget#lineOSK,
298QWidget#richDialog,
299QWidget#lineDialog {
300 background: transparent;
301}
302
303QStackedWidget#bottomOSK,
304QWidget#contentDialog,
305QWidget#contentRichDialog {
306 background: rgba(240, 240, 240, 1);
307}
308
309QWidget#contentDialog,
310QWidget#contentRichDialog {
311 margin: 5px;
312 border-radius: 6px;
313}
314
315QWidget#buttonsDialog,
316QWidget#buttonsRichDialog {
317 margin: 5px;
318 border-top: 2px solid rgba(44, 44, 44, 1);
319}
320
321QWidget#legendOSKnum {
322 border-top: 1px solid rgba(44, 44, 44, 1);
323}
324
325QStackedWidget#stackedDialog QTextBrowser QScrollBar::vertical {
326 background: #cdcdcd;
327 width: 15px;
328 margin: 15px 3px 15px 3px;
329 border: 1px transparent;
330 border-radius: 4px;
331}
332
333QStackedWidget#stackedDialog QTextBrowser QScrollBar::horizoncal {
334 background: #cdcdcd;
335 height: 15px;
336 margin: 3px 15px 3px 15px;
337 border: 1px transparent;
338 border-radius: 4px;
339}
340
341QStackedWidget#stackedDialog QTextBrowser QScrollBar::handle {
342 background: #fff;
343 border-radius: 4px;
344 min-height: 5px;
345 min-width: 5px;
346}
347
348QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-line,
349QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-line,
350QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-page,
351QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-page {
352 background: none;
353}
354
355QWidget#inputOSK {
356 border-bottom: 3px solid rgba(255, 255, 255, .9);
357}
358
359QWidget#inputOSK QLineEdit {
360 background: transparent;
361 border: none;
362 color: #ccc;
363}
364
365QWidget#inputBoxOSK {
366 border: 2px solid rgba(255, 255, 255, .9);
367}
368
369QWidget#inputBoxOSK QTextEdit {
370 background: transparent;
371 border: none;
372 color: #ccc;
373}
374
375QWidget#richDialog QTextBrowser {
376 background: transparent;
377 border: none;
378 padding: 35px 65px;
379}
380
381
382QWidget#lineOSK QLabel#label_header {
383 color: #f0f0f0;
384}
385
386QWidget#lineOSK QLabel#label_sub,
387QWidget#lineOSK QLabel#label_characters,
388QWidget#boxOSK QLabel#label_characters_box {
389 color: #ccc;
390}
391
392QWidget#contentDialog QLabel#label_title,
393QWidget#contentRichDialog QLabel#label_title_rich {
394 color: #888;
395}
396
397QWidget#contentDialog QLabel#label_dialog {
398 padding: 20px 65px;
399}
400
401QWidget#contentDialog QLabel#label_title,
402QWidget#contentRichDialog QLabel#label_title_rich {
403 padding: 0px 65px;
404}
405
406QDialog#OverlayDialog QPushButton {
407 color: rgba(49, 79, 239, 1);
408 background: transparent;
409 border: none;
410 padding: 0px;
411 min-width: 0px;
412}
413
414QDialog#OverlayDialog QPushButton:focus,
415QDialog#OverlayDialog QPushButton:hover {
416 color: rgba(49, 79, 239, 1);
417 background: rgba(255, 255, 255, 1);
418 border: 5px solid rgba(148, 250, 202, 1);
419 border-radius: 6px;
420 outline: none;
421}
422
423QDialog#OverlayDialog QPushButton:pressed {
424 color: rgba(240, 240, 240, 1);
425 background: rgba(150, 150, 150, 1);
426 border: 5px solid rgba(148, 250, 202, 1);
427 border-radius: 6px;
428 outline: none;
429}
430
431QDialog#QtSoftwareKeyboardDialog QPushButton {
432 background: rgba(232, 232, 232, 1);
433 border: 2px solid rgba(240, 240, 240, 1);
434}
435
436QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift,
437QDialog#QtSoftwareKeyboardDialog QPushButton#button_return,
438QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
439QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift,
440QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift,
441QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
442 background: rgba(218, 218, 218, 1);
443 border: 2px solid rgba(240, 240, 240, 1);
444}
445
446QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
447QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
448QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
449 color: rgba(240, 240, 240, 1);
450 background: rgba(44, 44, 44, 1);
451 border: 2px solid rgba(240, 240, 240, 1);
452}
453
454QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
455QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
456QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
457 color: rgba(240, 240, 240, 1);
458 background: rgba(49, 79, 239, 1);
459 border: 2px solid rgba(240, 240, 240, 1);
460}
461
462QDialog#QtSoftwareKeyboardDialog QPushButton:focus,
463QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:focus,
464QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:focus,
465QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:focus,
466QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:focus,
467QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:focus,
468QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:focus,
469QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:focus,
470QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:focus,
471QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:focus,
472QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:focus,
473QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:focus,
474QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:focus,
475
476QDialog#QtSoftwareKeyboardDialog QPushButton:hover,
477QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:hover,
478QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:hover,
479QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:hover,
480QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:hover,
481QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:hover,
482QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:hover,
483QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:hover,
484QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:hover,
485QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:hover,
486QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:hover,
487QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:hover,
488QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:hover {
489 color: rgba(0, 0, 0, 1);
490 background: rgba(255, 255, 255, 1);
491 border: 5px solid rgba(148, 250, 202, 1);
492 border-radius: 6px;
493 outline: none;
494}
495
496QDialog#QtSoftwareKeyboardDialog QPushButton:pressed,
497QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:pressed,
498QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:pressed,
499QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:pressed,
500QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:pressed,
501QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:pressed,
502QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:pressed,
503QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:pressed,
504QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:pressed,
505QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:pressed,
506QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:pressed,
507QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:pressed,
508QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:pressed {
509 color: rgba(240, 240, 240, 1);
510 background: rgba(150, 150, 150, 1);
511 border: 5px solid rgba(148, 250, 202, 1);
512 border-radius: 6px;
513}
514
515QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
516QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
517QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
518 background-position: right top;
519 background-repeat: no-repeat;
520 background-origin: content;
521 background-image: url(:/overlay/osk_button_B.png);
522 qproperty-icon: url(:/overlay/osk_button_backspace.png);
523 qproperty-iconSize: 36px;
524}
525
526QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
527QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
528 background-position: right top;
529 background-repeat: no-repeat;
530 background-origin: content;
531 background-image: url(:/overlay/osk_button_Y.png);
532}
533
534QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
535QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
536QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
537 background-position: right top;
538 background-repeat: no-repeat;
539 background-origin: content;
540 background-image: url(:/overlay/osk_button_plus.png);
541}
542
543QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
544 background-position: left top;
545 background-repeat: no-repeat;
546 background-origin: content;
547 background-image: url(:/overlay/osk_button_shift_lock_off.png);
548 qproperty-icon: url(:/overlay/osk_button_shift.png);
549 qproperty-iconSize: 36px;
550}
551
552QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
553 background-position: left top;
554 background-repeat: no-repeat;
555 background-origin: content;
556 background-image: url(:/overlay/osk_button_shift_lock_off.png);
557 qproperty-icon: url(:/overlay/osk_button_shift_on.png);
558 qproperty-iconSize: 36px;
559}
560
561QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_bracket,
562QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_bracket,
563QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_parenthesis,
564QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_parenthesis {
565 padding-bottom: 7px;
566}
567
568QDialog#QtSoftwareKeyboardDialog QWidget#titleOSK QLabel {
569 background: transparent;
570 color: #ccc;
571}
572
573QDialog#QtSoftwareKeyboardDialog QWidget#button_L,
574QDialog#QtSoftwareKeyboardDialog QWidget#button_L_shift,
575QDialog#QtSoftwareKeyboardDialog QWidget#button_L_num {
576 image: url(:/overlay/button_L.png);
577}
578
579QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left,
580QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift,
581QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num {
582 image: url(:/overlay/arrow_left.png);
583}
584
585QDialog#QtSoftwareKeyboardDialog QWidget#button_R,
586QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift,
587QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num {
588 image: url(:/overlay/button_R.png);
589}
590
591QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right,
592QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift,
593QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num {
594 image: url(:/overlay/arrow_right.png);
595}
596
597QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick,
598QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift {
599 image: url(:/overlay/button_press_stick.png);
600}
601
602QDialog#QtSoftwareKeyboardDialog QWidget#button_X,
603QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift,
604QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num {
605 image: url(:/overlay/button_X.png);
606}
607
608QDialog#QtSoftwareKeyboardDialog QWidget#button_A,
609QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift,
610QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num {
611 image: url(:/overlay/button_A.png);
612}
613
614QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
615QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
616QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled,
617QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
618QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
619QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled,
620QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:disabled,
621QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
622QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled,
623QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
624 color: rgba(164, 164, 164, 1);
625 background-color: rgba(218, 218, 218, 1);
626}
627
628QDialog#QtSoftwareKeyboardDialog QPushButton#button_at:disabled,
629QDialog#QtSoftwareKeyboardDialog QPushButton#button_slash:disabled,
630QDialog#QtSoftwareKeyboardDialog QPushButton#button_percent:disabled,
631QDialog#QtSoftwareKeyboardDialog QPushButton#button_1:disabled,
632QDialog#QtSoftwareKeyboardDialog QPushButton#button_2:disabled,
633QDialog#QtSoftwareKeyboardDialog QPushButton#button_3:disabled,
634QDialog#QtSoftwareKeyboardDialog QPushButton#button_4:disabled,
635QDialog#QtSoftwareKeyboardDialog QPushButton#button_5:disabled,
636QDialog#QtSoftwareKeyboardDialog QPushButton#button_6:disabled,
637QDialog#QtSoftwareKeyboardDialog QPushButton#button_7:disabled,
638QDialog#QtSoftwareKeyboardDialog QPushButton#button_8:disabled,
639QDialog#QtSoftwareKeyboardDialog QPushButton#button_9:disabled,
640QDialog#QtSoftwareKeyboardDialog QPushButton#button_0:disabled,
641QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled {
642 color: rgba(164, 164, 164, 1);
643}
644
645QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
646QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
647QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled {
648 background-image: url(:/overlay/osk_button_plus_disabled.png);
649}
650
651QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
652QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
653QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
654 background-image: url(:/overlay/osk_button_B_disabled.png);
655}
656
657QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
658QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
659 background-image: url(:/overlay/osk_button_Y_disabled.png);
660}
diff --git a/dist/qt_themes/qdarkstyle/style.qss b/dist/qt_themes/qdarkstyle/style.qss
index 2a1e8ddeb..8ce6d75f7 100644
--- a/dist/qt_themes/qdarkstyle/style.qss
+++ b/dist/qt_themes/qdarkstyle/style.qss
@@ -1560,7 +1560,400 @@ QWidget#controllerPlayer8 {
1560 background: transparent; 1560 background: transparent;
1561} 1561}
1562 1562
1563/* touchscreen mapping widget */ 1563QDialog#QtSoftwareKeyboardDialog,
1564TouchScreenPreview { 1564QStackedWidget#topOSK {
1565 qproperty-dotHighlightColor: #3daee9; 1565 background: rgba(41, 41, 41, .9);
1566}
1567
1568
1569QDialog#OverlayDialog,
1570QStackedWidget#stackedDialog {
1571 background: rgba(41, 41, 41, .7);
1572}
1573
1574QWidget#boxOSK,
1575QWidget#lineOSK,
1576QWidget#richDialog,
1577QWidget#lineDialog {
1578 background: transparent;
1579}
1580
1581QStackedWidget#bottomOSK,
1582QWidget#contentDialog,
1583QWidget#contentRichDialog {
1584 background: rgba(71, 69, 71, 1);
1585}
1586
1587QWidget#contentDialog,
1588QWidget#contentRichDialog {
1589 margin: 5px;
1590 border-radius: 6px;
1591}
1592
1593QWidget#buttonsDialog,
1594QWidget#buttonsRichDialog {
1595 margin: 5px;
1596 border-top: 2px solid rgba(255, 255, 255, .9);
1597}
1598
1599QWidget#legendOSKnum {
1600 border-top: 1px solid rgba(255, 255, 255, 1);
1601}
1602
1603QStackedWidget#stackedDialog QTextBrowser QWidget {
1604 background: transparent;
1605}
1606
1607QStackedWidget#stackedDialog QTextBrowser QScrollBar {
1608 background: #2a2929;
1609}
1610
1611QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-line,
1612QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-line {
1613 border-image: none;
1614}
1615
1616QWidget#inputOSK {
1617 border-bottom: 3px solid rgba(255, 255, 255, .9);
1618}
1619
1620QWidget#inputOSK QLineEdit {
1621 background: transparent;
1622 border: none;
1623 color: #ccc;
1624 padding: 0px;
1625}
1626
1627QWidget#inputBoxOSK {
1628 border: 2px solid rgba(255, 255, 255, .9);
1629}
1630
1631QWidget#inputBoxOSK QTextEdit {
1632 background: transparent;
1633 border: none;
1634 color: #ccc;
1635}
1636
1637QWidget#richDialog QTextBrowser {
1638 background: transparent;
1639 border: none;
1640 color: #fff;
1641 padding: 35px 65px;
1642}
1643
1644QWidget#lineOSK QLabel#label_header {
1645 color: #f0f0f0;
1646}
1647
1648QWidget#lineOSK QLabel#label_sub,
1649QWidget#lineOSK QLabel#label_characters,
1650QWidget#contentDialog QLabel#label_title,
1651QWidget#contentRichDialog QLabel#label_title_rich,
1652QWidget#boxOSK QLabel#label_characters_box {
1653 color: #ccc;
1654}
1655
1656QWidget#buttonsDialog,
1657QWidget#buttonsRichDialog,
1658QWidget#mainOSK,
1659QWidget#headerOSK,
1660QWidget#normalOSK,
1661QWidget#shiftOSK,
1662QWidget#numOSK,
1663QWidget#subOSK,
1664QWidget#inputOSK,
1665QWidget#inputBoxOSK,
1666QWidget#charactersOSK,
1667QWidget#charactersBoxOSK,
1668QWidget#legendOSK,
1669QWidget#legendOSK QWidget,
1670QWidget#legendOSKshift,
1671QWidget#legendOSKshift QWidget,
1672QWidget#legendOSKnum,
1673QWidget#legendOSKnum QWidget {
1674 background: transparent;
1675}
1676
1677QWidget#contentDialog QLabel,
1678QWidget#legendOSK QLabel,
1679QWidget#legendOSKshift QLabel,
1680QWidget#legendOSKnum QLabel {
1681 color: rgba(255, 255, 255, 1);
1682}
1683
1684QWidget#contentDialog QLabel#label_dialog {
1685 padding: 20px 65px;
1686}
1687
1688QWidget#contentDialog QLabel#label_title,
1689QWidget#contentRichDialog QLabel#label_title_rich {
1690 padding: 0px 65px;
1691}
1692
1693QDialog#OverlayDialog QPushButton {
1694 color: rgba(1, 253, 201, 1);
1695 background: transparent;
1696 border: none;
1697 padding: 0px;
1698 min-width: 0px;
1699}
1700
1701QDialog#OverlayDialog QPushButton:focus,
1702QDialog#OverlayDialog QPushButton:hover {
1703 color: rgba(1, 253, 201, 1);
1704 background: rgba(58, 61, 66, 1);
1705 border: 5px solid rgba(56, 189, 225, 1);
1706 border-radius: 6px;
1707 outline: none;
1708}
1709
1710QDialog#OverlayDialog QPushButton:pressed {
1711 color: rgba(240, 240, 240, 1);
1712 background: rgba(150, 150, 150, 1);
1713 border: 5px solid rgba(56, 189, 225, 1);
1714 border-radius: 6px;
1715 outline: none;
1716}
1717
1718QDialog#QtSoftwareKeyboardDialog QPushButton {
1719 color: rgba(255, 255, 255, 1);
1720 background: rgba(80, 79, 80, 1);
1721 border: 2px solid rgba(71, 69, 71, 1);
1722 padding: 0px;
1723 min-width: 0px;
1724}
1725
1726QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift,
1727QDialog#QtSoftwareKeyboardDialog QPushButton#button_return,
1728QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
1729QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift,
1730QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift,
1731QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
1732 background: rgba(95, 94, 95, 1);
1733 border: 2px solid rgba(71, 69, 71, 1);
1734}
1735
1736QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
1737QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
1738QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
1739 color: rgba(240, 240, 240, 1);
1740 background: rgba(255, 255, 255, 1);
1741 border: 2px solid rgba(71, 69, 71, 1);
1742}
1743
1744QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
1745QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
1746QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
1747 color: rgba(0, 0, 0, 1);
1748 background: rgba(1, 253, 201, 1);
1749 border: 2px solid rgba(71, 69, 71, 1);
1750}
1751
1752QDialog#QtSoftwareKeyboardDialog QPushButton:focus,
1753QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:focus,
1754QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:focus,
1755QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:focus,
1756QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:focus,
1757QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:focus,
1758QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:focus,
1759QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:focus,
1760QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:focus,
1761QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:focus,
1762QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:focus,
1763QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:focus,
1764QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:focus,
1765
1766QDialog#QtSoftwareKeyboardDialog QPushButton:hover,
1767QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:hover,
1768QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:hover,
1769QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:hover,
1770QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:hover,
1771QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:hover,
1772QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:hover,
1773QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:hover,
1774QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:hover,
1775QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:hover,
1776QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:hover,
1777QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:hover,
1778QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:hover {
1779 color: rgba(255, 255, 255, 1);
1780 background: rgba(58, 61, 66, 1);
1781 border: 5px solid rgba(56, 189, 225, 1);
1782 border-radius: 6px;
1783 outline: none;
1784}
1785
1786QDialog#QtSoftwareKeyboardDialog QPushButton:pressed,
1787QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:pressed,
1788QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:pressed,
1789QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:pressed,
1790QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:pressed,
1791QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:pressed,
1792QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:pressed,
1793QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:pressed,
1794QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:pressed,
1795QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:pressed,
1796QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:pressed,
1797QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:pressed,
1798QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:pressed {
1799 color: rgba(240, 240, 240, 1);
1800 background: rgba(150, 150, 150, 1);
1801 border: 5px solid rgba(56, 189, 225, 1);
1802 border-radius: 6px;
1803}
1804
1805QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
1806QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
1807QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
1808 background-position: right top;
1809 background-repeat: no-repeat;
1810 background-origin: content;
1811 background-image: url(:/overlay/osk_button_B_dark.png);
1812 qproperty-icon: url(:/overlay/osk_button_backspace_dark.png);
1813 qproperty-iconSize: 36px;
1814}
1815
1816QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
1817QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
1818 background-position: right top;
1819 background-repeat: no-repeat;
1820 background-origin: content;
1821 background-image: url(:/overlay/osk_button_Y_dark.png);
1822}
1823
1824QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
1825QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
1826QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
1827 color: rgba(44, 44, 44, 1);
1828 background-position: right top;
1829 background-repeat: no-repeat;
1830 background-origin: content;
1831 background-image: url(:/overlay/osk_button_plus_dark.png);
1832}
1833
1834QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
1835 background-position: left top;
1836 background-repeat: no-repeat;
1837 background-origin: content;
1838 background-image: url(:/overlay/osk_button_shift_lock_off.png);
1839 qproperty-icon: url(:/overlay/osk_button_shift_dark.png);
1840 qproperty-iconSize: 36px;
1841}
1842
1843QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
1844 background-position: left top;
1845 background-repeat: no-repeat;
1846 background-origin: content;
1847 background-image: url(:/overlay/osk_button_shift_lock_off.png);
1848 qproperty-icon: url(:/overlay/osk_button_shift_on_dark.png);
1849 qproperty-iconSize: 36px;
1850}
1851
1852QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_bracket,
1853QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_bracket,
1854QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_parenthesis,
1855QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_parenthesis {
1856 padding-bottom: 7px;
1857}
1858
1859QDialog#QtSoftwareKeyboardDialog QWidget#titleOSK QLabel {
1860 background: transparent;
1861 color: #ccc;
1862}
1863
1864QDialog#QtSoftwareKeyboardDialog QWidget#button_L,
1865QDialog#QtSoftwareKeyboardDialog QWidget#button_L_shift,
1866QDialog#QtSoftwareKeyboardDialog QWidget#button_L_num {
1867 image: url(:/overlay/button_L_dark.png);
1868}
1869
1870QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left,
1871QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift,
1872QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num {
1873 image: url(:/overlay/arrow_left_dark.png);
1874}
1875
1876QDialog#QtSoftwareKeyboardDialog QWidget#button_R,
1877QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift,
1878QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num {
1879 image: url(:/overlay/button_R_dark.png);
1880}
1881
1882QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right,
1883QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift,
1884QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num {
1885 image: url(:/overlay/arrow_right_dark.png);
1886}
1887
1888QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick,
1889QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift {
1890 image: url(:/overlay/button_press_stick_dark.png);
1891}
1892
1893QDialog#QtSoftwareKeyboardDialog QWidget#button_X,
1894QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift,
1895QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num {
1896 image: url(:/overlay/button_X_dark.png);
1897}
1898
1899QDialog#QtSoftwareKeyboardDialog QWidget#button_A,
1900QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift,
1901QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num {
1902 image: url(:/overlay/button_A_dark.png);
1903}
1904
1905QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
1906QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
1907QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled,
1908QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
1909QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
1910QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled,
1911QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:disabled,
1912QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
1913QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled,
1914QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
1915 color: rgba(144, 144, 144, 1);
1916 background-color: rgba(95, 94, 95, 1);
1917}
1918
1919QDialog#QtSoftwareKeyboardDialog QPushButton#button_at:disabled,
1920QDialog#QtSoftwareKeyboardDialog QPushButton#button_slash:disabled,
1921QDialog#QtSoftwareKeyboardDialog QPushButton#button_percent:disabled,
1922QDialog#QtSoftwareKeyboardDialog QPushButton#button_1:disabled,
1923QDialog#QtSoftwareKeyboardDialog QPushButton#button_2:disabled,
1924QDialog#QtSoftwareKeyboardDialog QPushButton#button_3:disabled,
1925QDialog#QtSoftwareKeyboardDialog QPushButton#button_4:disabled,
1926QDialog#QtSoftwareKeyboardDialog QPushButton#button_5:disabled,
1927QDialog#QtSoftwareKeyboardDialog QPushButton#button_6:disabled,
1928QDialog#QtSoftwareKeyboardDialog QPushButton#button_7:disabled,
1929QDialog#QtSoftwareKeyboardDialog QPushButton#button_8:disabled,
1930QDialog#QtSoftwareKeyboardDialog QPushButton#button_9:disabled,
1931QDialog#QtSoftwareKeyboardDialog QPushButton#button_0:disabled,
1932QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled {
1933 color: rgba(144, 144, 144, 1);
1934}
1935
1936QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
1937QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
1938QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled {
1939 background-image: url(:/overlay/osk_button_plus_dark_disabled.png);
1940}
1941
1942QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
1943QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
1944QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
1945 background-image: url(:/overlay/osk_button_B_dark_disabled.png);
1946}
1947
1948QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
1949QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
1950 background-image: url(:/overlay/osk_button_Y_dark_disabled.png);
1951}
1952
1953QDialog#QtSoftwareKeyboardDialog QFrame,
1954QDialog#QtSoftwareKeyboardDialog QFrame[frameShape="0"],
1955QDialog#OverlayDialog QFrame,
1956QDialog#OverlayDialog QFrame[frameShape="0"] {
1957 border-radius: 0px;
1958 border: none;
1566} 1959}
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/style.qss b/dist/qt_themes/qdarkstyle_midnight_blue/style.qss
index a64037455..64e1ecbcc 100644
--- a/dist/qt_themes/qdarkstyle_midnight_blue/style.qss
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/style.qss
@@ -1,10 +1,10 @@
1/* --------------------------------------------------------------------------- 1/* ---------------------------------------------------------------------------
2 2
3 Created by the qtsass compiler v0.1.1 3 Created by the qtsass compiler v0.1.1
4 4
5 The definitions are in the "qdarkstyle.qss._styles.scss" module 5 The definitions are in the "qdarkstyle.qss._styles.scss" module
6 6
7 WARNING! All changes made in this file will be lost! 7 WARNING! All changes made in this file will be lost!
8 8
9--------------------------------------------------------------------------- */ 9--------------------------------------------------------------------------- */
10/* QDarkStyleSheet ----------------------------------------------------------- 10/* QDarkStyleSheet -----------------------------------------------------------
@@ -15,34 +15,34 @@ It is based on three selecting colors, three greyish (background) colors
15plus three whitish (foreground) colors. Each set of widgets of the same 15plus three whitish (foreground) colors. Each set of widgets of the same
16type have a header like this: 16type have a header like this:
17 17
18 ------------------ 18 ------------------
19 GroupName -------- 19 GroupName --------
20 ------------------ 20 ------------------
21 21
22And each widget is separated with a header like this: 22And each widget is separated with a header like this:
23 23
24 QWidgetName ------ 24 QWidgetName ------
25 25
26This makes more easy to find and change some css field. The basic 26This makes more easy to find and change some css field. The basic
27configuration is described bellow. 27configuration is described bellow.
28 28
29 BACKGROUND ----------- 29 BACKGROUND -----------
30 30
31 Light (unpressed) 31 Light (unpressed)
32 Normal (border, disabled, pressed, checked, toolbars, menus) 32 Normal (border, disabled, pressed, checked, toolbars, menus)
33 Dark (background) 33 Dark (background)
34 34
35 FOREGROUND ----------- 35 FOREGROUND -----------
36 36
37 Light (texts/labels) 37 Light (texts/labels)
38 Normal (not used yet) 38 Normal (not used yet)
39 Dark (disabled texts) 39 Dark (disabled texts)
40 40
41 SELECTION ------------ 41 SELECTION ------------
42 42
43 Light (selection/hover/active) 43 Light (selection/hover/active)
44 Normal (selected) 44 Normal (selected)
45 Dark (selected disabled) 45 Dark (selected disabled)
46 46
47If a stranger configuration is required because of a bugfix or anything 47If a stranger configuration is required because of a bugfix or anything
48else, keep the comment on the line above so nobody changes it, including the 48else, keep the comment on the line above so nobody changes it, including the
@@ -2483,3 +2483,404 @@ QWidget#controllerPlayer7,
2483QWidget#controllerPlayer8 { 2483QWidget#controllerPlayer8 {
2484 background: transparent; 2484 background: transparent;
2485} 2485}
2486
2487QDialog#QtSoftwareKeyboardDialog,
2488QStackedWidget#topOSK {
2489 background: rgba(15, 25, 34, .9);
2490}
2491
2492QDialog#OverlayDialog,
2493QStackedWidget#stackedDialog {
2494 background: rgba(15, 25, 34, .7);
2495}
2496
2497QWidget#boxOSK,
2498QWidget#lineOSK,
2499QWidget#richDialog,
2500QWidget#lineDialog {
2501 background: transparent;
2502}
2503
2504QStackedWidget#bottomOSK,
2505QWidget#contentDialog,
2506QWidget#contentRichDialog {
2507 background: rgba(31, 41, 51, 1);
2508}
2509
2510QWidget#contentDialog,
2511QWidget#contentRichDialog {
2512 margin: 5px;
2513 border-radius: 6px;
2514}
2515
2516QWidget#buttonsDialog,
2517QWidget#buttonsRichDialog {
2518 margin: 5px;
2519 border-top: 2px solid rgba(255, 255, 255, .9);
2520}
2521
2522QWidget#legendOSKnum {
2523 border-top: 1px solid rgba(255, 255, 255, 1);
2524}
2525
2526QStackedWidget#stackedDialog QTextBrowser QWidget {
2527 background: transparent;
2528}
2529
2530QStackedWidget#stackedDialog QTextBrowser QScrollBar {
2531 background: #19232d;
2532 border: none;
2533}
2534
2535QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-line,
2536QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-line {
2537 border-image: none;
2538}
2539
2540QWidget#mainOSK QStackedWidget,
2541QDialog#OverlayDialog QStackedWidget {
2542 border: none;
2543 padding: 0px;
2544}
2545
2546QWidget#inputOSK {
2547 border-bottom: 3px solid rgba(255, 255, 255, .9);
2548}
2549
2550QWidget#inputOSK QLineEdit {
2551 background: transparent;
2552 border: none;
2553 color: #ccc;
2554 padding: 0px;
2555}
2556
2557QWidget#inputBoxOSK {
2558 border: 2px solid rgba(255, 255, 255, .9);
2559}
2560
2561QWidget#inputBoxOSK QTextEdit {
2562 background: transparent;
2563 border: none;
2564 color: #ccc;
2565}
2566
2567QWidget#richDialog QTextBrowser {
2568 background: transparent;
2569 border: none;
2570 color: #fff;
2571 padding: 35px 65px;
2572}
2573
2574QWidget#lineOSK QLabel#label_header {
2575 color: #f0f0f0;
2576}
2577
2578QWidget#lineOSK QLabel#label_sub,
2579QWidget#lineOSK QLabel#label_characters,
2580QWidget#contentDialog QLabel#label_title,
2581QWidget#contentRichDialog QLabel#label_title_rich,
2582QWidget#boxOSK QLabel#label_characters_box {
2583 color: #ccc;
2584}
2585
2586QWidget#buttonsDialog,
2587QWidget#buttonsRichDialog,
2588QWidget#mainOSK,
2589QWidget#headerOSK,
2590QWidget#normalOSK,
2591QWidget#shiftOSK,
2592QWidget#numOSK,
2593QWidget#subOSK,
2594QWidget#inputOSK,
2595QWidget#inputBoxOSK,
2596QWidget#charactersOSK,
2597QWidget#charactersBoxOSK,
2598QWidget#legendOSK,
2599QWidget#legendOSK QWidget,
2600QWidget#legendOSKshift,
2601QWidget#legendOSKshift QWidget,
2602QWidget#legendOSKnum,
2603QWidget#legendOSKnum QWidget {
2604 background: transparent;
2605}
2606
2607QWidget#contentDialog QLabel,
2608QWidget#legendOSK QLabel,
2609QWidget#legendOSKshift QLabel,
2610QWidget#legendOSKnum QLabel {
2611 color: rgba(255, 255, 255, 1);
2612}
2613
2614QWidget#contentDialog QLabel#label_dialog {
2615 padding: 20px 65px;
2616}
2617
2618QWidget#contentDialog QLabel#label_title,
2619QWidget#contentRichDialog QLabel#label_title_rich {
2620 padding: 0px 65px;
2621}
2622
2623QDialog#OverlayDialog QPushButton {
2624 color: rgba(1, 253, 201, 1);
2625 background: transparent;
2626 border: none;
2627 padding: 0px;
2628 min-width: 0px;
2629}
2630
2631QDialog#OverlayDialog QPushButton:focus,
2632QDialog#OverlayDialog QPushButton:hover {
2633 color: rgba(1, 253, 201, 1);
2634 background: rgba(18, 33, 46, 1);
2635 border: 5px solid rgba(56, 189, 225, 1);
2636 border-radius: 6px;
2637 outline: none;
2638}
2639
2640QDialog#OverlayDialog QPushButton:pressed {
2641 color: rgba(240, 240, 240, 1);
2642 background: rgba(110, 122, 130, 1);
2643 border: 5px solid rgba(56, 189, 225, 1);
2644 border-radius: 6px;
2645 outline: none;
2646}
2647
2648QDialog#QtSoftwareKeyboardDialog QLabel {
2649 padding: 0px;
2650}
2651
2652QDialog#QtSoftwareKeyboardDialog QPushButton {
2653 color: rgba(255, 255, 255, 1);
2654 background: rgba(40, 51, 60, 1);
2655 border: 2px solid rgba(31, 41, 51, 1);
2656 border-radius: 0px;
2657 padding: 0px;
2658 min-width: 0px;
2659}
2660
2661QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift,
2662QDialog#QtSoftwareKeyboardDialog QPushButton#button_return,
2663QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
2664QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift,
2665QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift,
2666QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
2667 background: rgba(55, 66, 75, 1);
2668 border: 2px solid rgba(31, 41, 51, 1);
2669}
2670
2671QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
2672QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
2673QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
2674 color: rgba(240, 240, 240, 1);
2675 background: rgba(255, 255, 255, 1);
2676 border: 2px solid rgba(31, 41, 51, 1);
2677}
2678
2679QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
2680QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
2681QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
2682 color: rgba(0, 0, 0, 1);
2683 background: rgba(1, 253, 201, 1);
2684 border: 2px solid rgba(31, 41, 51, 1);
2685}
2686
2687QDialog#QtSoftwareKeyboardDialog QPushButton:focus,
2688QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:focus,
2689QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:focus,
2690QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:focus,
2691QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:focus,
2692QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:focus,
2693QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:focus,
2694QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:focus,
2695QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:focus,
2696QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:focus,
2697QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:focus,
2698QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:focus,
2699QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:focus,
2700
2701QDialog#QtSoftwareKeyboardDialog QPushButton:hover,
2702QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:hover,
2703QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:hover,
2704QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:hover,
2705QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:hover,
2706QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:hover,
2707QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:hover,
2708QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:hover,
2709QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:hover,
2710QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:hover,
2711QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:hover,
2712QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:hover,
2713QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:hover {
2714 color: rgba(255, 255, 255, 1);
2715 background: rgba(18, 33, 46, 1);
2716 border: 5px solid rgba(56, 189, 225, 1);
2717 border-radius: 6px;
2718 outline: none;
2719}
2720
2721QDialog#QtSoftwareKeyboardDialog QPushButton:pressed,
2722QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:pressed,
2723QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:pressed,
2724QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:pressed,
2725QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:pressed,
2726QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:pressed,
2727QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:pressed,
2728QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:pressed,
2729QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:pressed,
2730QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:pressed,
2731QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:pressed,
2732QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:pressed,
2733QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:pressed {
2734 color: rgba(240, 240, 240, 1);
2735 background: rgba(110, 122, 130, 1);
2736 border: 5px solid rgba(56, 189, 225, 1);
2737 border-radius: 6px;
2738}
2739
2740QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
2741QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
2742QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
2743 background-position: right top;
2744 background-repeat: no-repeat;
2745 background-origin: content;
2746 background-image: url(:/overlay/osk_button_B_dark.png);
2747 qproperty-icon: url(:/overlay/osk_button_backspace_dark.png);
2748 qproperty-iconSize: 36px;
2749}
2750
2751QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
2752QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
2753 background-position: right top;
2754 background-repeat: no-repeat;
2755 background-origin: content;
2756 background-image: url(:/overlay/osk_button_Y_dark.png);
2757}
2758
2759QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
2760QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
2761QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
2762 color: rgba(44, 44, 44, 1);
2763 background-position: right top;
2764 background-repeat: no-repeat;
2765 background-origin: content;
2766 background-image: url(:/overlay/osk_button_plus_dark.png);
2767}
2768
2769QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
2770 background-position: left top;
2771 background-repeat: no-repeat;
2772 background-origin: content;
2773 background-image: url(:/overlay/osk_button_shift_lock_off.png);
2774 qproperty-icon: url(:/overlay/osk_button_shift_dark.png);
2775 qproperty-iconSize: 36px;
2776}
2777
2778QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
2779 background-position: left top;
2780 background-repeat: no-repeat;
2781 background-origin: content;
2782 background-image: url(:/overlay/osk_button_shift_lock_off.png);
2783 qproperty-icon: url(:/overlay/osk_button_shift_on_dark.png);
2784 qproperty-iconSize: 36px;
2785}
2786
2787QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_bracket,
2788QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_bracket,
2789QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_parenthesis,
2790QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_parenthesis {
2791 padding-bottom: 7px;
2792}
2793
2794QDialog#QtSoftwareKeyboardDialog QWidget#titleOSK QLabel {
2795 background: transparent;
2796 color: #ccc;
2797}
2798
2799QDialog#QtSoftwareKeyboardDialog QWidget#button_L,
2800QDialog#QtSoftwareKeyboardDialog QWidget#button_L_shift,
2801QDialog#QtSoftwareKeyboardDialog QWidget#button_L_num {
2802 image: url(:/overlay/button_L_dark.png);
2803}
2804
2805QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left,
2806QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift,
2807QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num {
2808 image: url(:/overlay/arrow_left_dark.png);
2809}
2810
2811QDialog#QtSoftwareKeyboardDialog QWidget#button_R,
2812QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift,
2813QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num {
2814 image: url(:/overlay/button_R_dark.png);
2815}
2816
2817QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right,
2818QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift,
2819QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num {
2820 image: url(:/overlay/arrow_right_dark.png);
2821}
2822
2823QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick,
2824QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift {
2825 image: url(:/overlay/button_press_stick_dark.png);
2826}
2827
2828QDialog#QtSoftwareKeyboardDialog QWidget#button_X,
2829QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift,
2830QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num {
2831 image: url(:/overlay/button_X_dark.png);
2832}
2833
2834QDialog#QtSoftwareKeyboardDialog QWidget#button_A,
2835QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift,
2836QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num {
2837 image: url(:/overlay/button_A_dark.png);
2838}
2839
2840QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
2841QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
2842QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled,
2843QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
2844QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
2845QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled,
2846QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:disabled,
2847QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
2848QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled,
2849QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
2850 color: rgba(144, 144, 144, 1);
2851 background-color: rgba(55, 66, 75, 1);
2852}
2853
2854QDialog#QtSoftwareKeyboardDialog QPushButton#button_at:disabled,
2855QDialog#QtSoftwareKeyboardDialog QPushButton#button_slash:disabled,
2856QDialog#QtSoftwareKeyboardDialog QPushButton#button_percent:disabled,
2857QDialog#QtSoftwareKeyboardDialog QPushButton#button_1:disabled,
2858QDialog#QtSoftwareKeyboardDialog QPushButton#button_2:disabled,
2859QDialog#QtSoftwareKeyboardDialog QPushButton#button_3:disabled,
2860QDialog#QtSoftwareKeyboardDialog QPushButton#button_4:disabled,
2861QDialog#QtSoftwareKeyboardDialog QPushButton#button_5:disabled,
2862QDialog#QtSoftwareKeyboardDialog QPushButton#button_6:disabled,
2863QDialog#QtSoftwareKeyboardDialog QPushButton#button_7:disabled,
2864QDialog#QtSoftwareKeyboardDialog QPushButton#button_8:disabled,
2865QDialog#QtSoftwareKeyboardDialog QPushButton#button_9:disabled,
2866QDialog#QtSoftwareKeyboardDialog QPushButton#button_0:disabled,
2867QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled {
2868 color: rgba(144, 144, 144, 1);
2869}
2870
2871QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
2872QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
2873QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled {
2874 background-image: url(:/overlay/osk_button_plus_dark_disabled.png);
2875}
2876
2877QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
2878QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
2879QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
2880 background-image: url(:/overlay/osk_button_B_dark_disabled.png);
2881}
2882
2883QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
2884QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
2885 background-image: url(:/overlay/osk_button_Y_dark_disabled.png);
2886}
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index 891a47c3c..e044d9730 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -45,6 +45,11 @@ target_include_directories(microprofile INTERFACE ./microprofile)
45add_library(unicorn-headers INTERFACE) 45add_library(unicorn-headers INTERFACE)
46target_include_directories(unicorn-headers INTERFACE ./unicorn/include) 46target_include_directories(unicorn-headers INTERFACE ./unicorn/include)
47 47
48# SDL2
49if (NOT SDL2_FOUND AND ENABLE_SDL2)
50 add_subdirectory(SDL EXCLUDE_FROM_ALL)
51endif()
52
48# SoundTouch 53# SoundTouch
49add_subdirectory(soundtouch) 54add_subdirectory(soundtouch)
50 55
diff --git a/externals/SDL b/externals/SDL
new file mode 160000
Subproject 4cd981609b50ed273d80c635c1ca4c1e5518fb2
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()) {