summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/point.h57
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.h6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp4
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.h2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_cp15.h2
-rw-r--r--src/core/arm/dynarmic/arm_exclusive_monitor.h2
-rw-r--r--src/core/hle/kernel/k_class_token.cpp79
-rw-r--r--src/core/hle/kernel/k_client_port.h6
-rw-r--r--src/core/hle/kernel/k_client_session.h4
-rw-r--r--src/core/hle/kernel/k_event.h14
-rw-r--r--src/core/hle/kernel/k_port.h3
-rw-r--r--src/core/hle/kernel/k_process.h8
-rw-r--r--src/core/hle/kernel/k_readable_event.h4
-rw-r--r--src/core/hle/kernel/k_resource_limit.h4
-rw-r--r--src/core/hle/kernel/k_server_port.h12
-rw-r--r--src/core/hle/kernel/k_server_session.h6
-rw-r--r--src/core/hle/kernel/k_session.h10
-rw-r--r--src/core/hle/kernel/k_shared_memory.h4
-rw-r--r--src/core/hle/kernel/k_slab_heap.h199
-rw-r--r--src/core/hle/kernel/k_synchronization_object.h4
-rw-r--r--src/core/hle/kernel/k_thread.cpp10
-rw-r--r--src/core/hle/kernel/k_thread.h10
-rw-r--r--src/core/hle/kernel/k_transfer_memory.h10
-rw-r--r--src/core/hle/kernel/k_writable_event.h2
-rw-r--r--src/core/hle/kernel/kernel.cpp5
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.cpp25
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h36
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp13
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.h7
-rw-r--r--src/core/hle/service/ldn/ldn.cpp141
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h4
-rw-r--r--src/video_core/gpu.cpp12
-rw-r--r--src/video_core/gpu.h2
-rw-r--r--src/yuzu/applets/software_keyboard.cpp25
36 files changed, 549 insertions, 190 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index eafb96b0b..7a4d9e354 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -154,6 +154,7 @@ add_library(common STATIC
154 param_package.cpp 154 param_package.cpp
155 param_package.h 155 param_package.h
156 parent_of_member.h 156 parent_of_member.h
157 point.h
157 quaternion.h 158 quaternion.h
158 ring_buffer.h 159 ring_buffer.h
159 scm_rev.cpp 160 scm_rev.cpp
diff --git a/src/common/point.h b/src/common/point.h
new file mode 100644
index 000000000..c0a52ad8d
--- /dev/null
+++ b/src/common/point.h
@@ -0,0 +1,57 @@
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 <type_traits>
8
9namespace Common {
10
11// Represents a point within a 2D space.
12template <typename T>
13struct Point {
14 static_assert(std::is_arithmetic_v<T>, "T must be an arithmetic type!");
15
16 T x{};
17 T y{};
18
19#define ARITHMETIC_OP(op, compound_op) \
20 friend constexpr Point operator op(const Point& lhs, const Point& rhs) noexcept { \
21 return { \
22 .x = static_cast<T>(lhs.x op rhs.x), \
23 .y = static_cast<T>(lhs.y op rhs.y), \
24 }; \
25 } \
26 friend constexpr Point operator op(const Point& lhs, T value) noexcept { \
27 return { \
28 .x = static_cast<T>(lhs.x op value), \
29 .y = static_cast<T>(lhs.y op value), \
30 }; \
31 } \
32 friend constexpr Point operator op(T value, const Point& rhs) noexcept { \
33 return { \
34 .x = static_cast<T>(value op rhs.x), \
35 .y = static_cast<T>(value op rhs.y), \
36 }; \
37 } \
38 friend constexpr Point& operator compound_op(Point& lhs, const Point& rhs) noexcept { \
39 lhs.x = static_cast<T>(lhs.x op rhs.x); \
40 lhs.y = static_cast<T>(lhs.y op rhs.y); \
41 return lhs; \
42 } \
43 friend constexpr Point& operator compound_op(Point& lhs, T value) noexcept { \
44 lhs.x = static_cast<T>(lhs.x op value); \
45 lhs.y = static_cast<T>(lhs.y op value); \
46 return lhs; \
47 }
48 ARITHMETIC_OP(+, +=)
49 ARITHMETIC_OP(-, -=)
50 ARITHMETIC_OP(*, *=)
51 ARITHMETIC_OP(/, /=)
52#undef ARITHMETIC_OP
53
54 friend constexpr bool operator==(const Point&, const Point&) = default;
55};
56
57} // namespace Common
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 6ff241cd2..cea7f0fb1 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -4,9 +4,9 @@
4 4
5#include <cinttypes> 5#include <cinttypes>
6#include <memory> 6#include <memory>
7#include <dynarmic/A32/a32.h> 7#include <dynarmic/interface/A32/a32.h>
8#include <dynarmic/A32/config.h> 8#include <dynarmic/interface/A32/config.h>
9#include <dynarmic/A32/context.h> 9#include <dynarmic/interface/A32/context.h>
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"
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h
index fa6f4f430..063605b46 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.h
@@ -7,9 +7,9 @@
7#include <memory> 7#include <memory>
8#include <unordered_map> 8#include <unordered_map>
9 9
10#include <dynarmic/A32/a32.h> 10#include <dynarmic/interface/A32/a32.h>
11#include <dynarmic/A64/a64.h> 11#include <dynarmic/interface/A64/a64.h>
12#include <dynarmic/exclusive_monitor.h> 12#include <dynarmic/interface/exclusive_monitor.h>
13#include "common/common_types.h" 13#include "common/common_types.h"
14#include "common/hash.h" 14#include "common/hash.h"
15#include "core/arm/arm_interface.h" 15#include "core/arm/arm_interface.h"
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 98a6cef62..63193dcb1 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -4,8 +4,8 @@
4 4
5#include <cinttypes> 5#include <cinttypes>
6#include <memory> 6#include <memory>
7#include <dynarmic/A64/a64.h> 7#include <dynarmic/interface/A64/a64.h>
8#include <dynarmic/A64/config.h> 8#include <dynarmic/interface/A64/config.h>
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"
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h
index 5214a8147..0c4e46c64 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.h
@@ -7,7 +7,7 @@
7#include <memory> 7#include <memory>
8#include <unordered_map> 8#include <unordered_map>
9 9
10#include <dynarmic/A64/a64.h> 10#include <dynarmic/interface/A64/a64.h>
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "common/hash.h" 12#include "common/hash.h"
13#include "core/arm/arm_interface.h" 13#include "core/arm/arm_interface.h"
diff --git a/src/core/arm/dynarmic/arm_dynarmic_cp15.h b/src/core/arm/dynarmic/arm_dynarmic_cp15.h
index 8597beddf..7c7ede79e 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_cp15.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_cp15.h
@@ -7,7 +7,7 @@
7#include <memory> 7#include <memory>
8#include <optional> 8#include <optional>
9 9
10#include <dynarmic/A32/coprocessor.h> 10#include <dynarmic/interface/A32/coprocessor.h>
11#include "common/common_types.h" 11#include "common/common_types.h"
12 12
13namespace Core { 13namespace Core {
diff --git a/src/core/arm/dynarmic/arm_exclusive_monitor.h b/src/core/arm/dynarmic/arm_exclusive_monitor.h
index f9f056a59..73d41f223 100644
--- a/src/core/arm/dynarmic/arm_exclusive_monitor.h
+++ b/src/core/arm/dynarmic/arm_exclusive_monitor.h
@@ -7,7 +7,7 @@
7#include <memory> 7#include <memory>
8#include <unordered_map> 8#include <unordered_map>
9 9
10#include <dynarmic/exclusive_monitor.h> 10#include <dynarmic/interface/exclusive_monitor.h>
11 11
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "core/arm/dynarmic/arm_dynarmic_32.h" 13#include "core/arm/dynarmic/arm_dynarmic_32.h"
diff --git a/src/core/hle/kernel/k_class_token.cpp b/src/core/hle/kernel/k_class_token.cpp
index beb8a2a05..0be0027be 100644
--- a/src/core/hle/kernel/k_class_token.cpp
+++ b/src/core/hle/kernel/k_class_token.cpp
@@ -84,50 +84,43 @@ static_assert(ClassToken<KTransferMemory> == ((0b10010001 << 8) | ClassToken<KAu
84// Ensure that the token hierarchy reflects the class hierarchy. 84// Ensure that the token hierarchy reflects the class hierarchy.
85 85
86// Base classes. 86// Base classes.
87static_assert(!std::is_final<KSynchronizationObject>::value && 87static_assert(!std::is_final_v<KSynchronizationObject> &&
88 std::is_base_of<KAutoObject, KSynchronizationObject>::value); 88 std::is_base_of_v<KAutoObject, KSynchronizationObject>);
89static_assert(!std::is_final<KReadableEvent>::value && 89static_assert(!std::is_final_v<KReadableEvent> &&
90 std::is_base_of<KSynchronizationObject, KReadableEvent>::value); 90 std::is_base_of_v<KSynchronizationObject, KReadableEvent>);
91 91
92// Final classes 92// Final classes
93// static_assert(std::is_final<KInterruptEvent>::value && 93// static_assert(std::is_final_v<KInterruptEvent> &&
94// std::is_base_of<KReadableEvent, KInterruptEvent>::value); 94// std::is_base_of_v<KReadableEvent, KInterruptEvent>);
95// static_assert(std::is_final<KDebug>::value && 95// static_assert(std::is_final_v<KDebug> &&
96// std::is_base_of<KSynchronizationObject, KDebug>::value); 96// std::is_base_of_v<KSynchronizationObject, KDebug>);
97static_assert(std::is_final<KThread>::value && 97static_assert(std::is_final_v<KThread> && std::is_base_of_v<KSynchronizationObject, KThread>);
98 std::is_base_of<KSynchronizationObject, KThread>::value); 98static_assert(std::is_final_v<KServerPort> &&
99static_assert(std::is_final<KServerPort>::value && 99 std::is_base_of_v<KSynchronizationObject, KServerPort>);
100 std::is_base_of<KSynchronizationObject, KServerPort>::value); 100static_assert(std::is_final_v<KServerSession> &&
101static_assert(std::is_final<KServerSession>::value && 101 std::is_base_of_v<KSynchronizationObject, KServerSession>);
102 std::is_base_of<KSynchronizationObject, KServerSession>::value); 102static_assert(std::is_final_v<KClientPort> &&
103static_assert(std::is_final<KClientPort>::value && 103 std::is_base_of_v<KSynchronizationObject, KClientPort>);
104 std::is_base_of<KSynchronizationObject, KClientPort>::value); 104static_assert(std::is_final_v<KClientSession> && std::is_base_of_v<KAutoObject, KClientSession>);
105static_assert(std::is_final<KClientSession>::value && 105static_assert(std::is_final_v<KProcess> && std::is_base_of_v<KSynchronizationObject, KProcess>);
106 std::is_base_of<KAutoObject, KClientSession>::value); 106static_assert(std::is_final_v<KResourceLimit> && std::is_base_of_v<KAutoObject, KResourceLimit>);
107static_assert(std::is_final<KProcess>::value && 107// static_assert(std::is_final_v<KLightSession> &&
108 std::is_base_of<KSynchronizationObject, KProcess>::value); 108// std::is_base_of_v<KAutoObject, KLightSession>);
109static_assert(std::is_final<KResourceLimit>::value && 109static_assert(std::is_final_v<KPort> && std::is_base_of_v<KAutoObject, KPort>);
110 std::is_base_of<KAutoObject, KResourceLimit>::value); 110static_assert(std::is_final_v<KSession> && std::is_base_of_v<KAutoObject, KSession>);
111// static_assert(std::is_final<KLightSession>::value && 111static_assert(std::is_final_v<KSharedMemory> && std::is_base_of_v<KAutoObject, KSharedMemory>);
112// std::is_base_of<KAutoObject, KLightSession>::value); 112static_assert(std::is_final_v<KEvent> && std::is_base_of_v<KAutoObject, KEvent>);
113static_assert(std::is_final<KPort>::value && std::is_base_of<KAutoObject, KPort>::value); 113static_assert(std::is_final_v<KWritableEvent> && std::is_base_of_v<KAutoObject, KWritableEvent>);
114static_assert(std::is_final<KSession>::value && std::is_base_of<KAutoObject, KSession>::value); 114// static_assert(std::is_final_v<KLightClientSession> &&
115static_assert(std::is_final<KSharedMemory>::value && 115// std::is_base_of_v<KAutoObject, KLightClientSession>);
116 std::is_base_of<KAutoObject, KSharedMemory>::value); 116// static_assert(std::is_final_v<KLightServerSession> &&
117static_assert(std::is_final<KEvent>::value && std::is_base_of<KAutoObject, KEvent>::value); 117// std::is_base_of_v<KAutoObject, KLightServerSession>);
118static_assert(std::is_final<KWritableEvent>::value && 118static_assert(std::is_final_v<KTransferMemory> && std::is_base_of_v<KAutoObject, KTransferMemory>);
119 std::is_base_of<KAutoObject, KWritableEvent>::value); 119// static_assert(std::is_final_v<KDeviceAddressSpace> &&
120// static_assert(std::is_final<KLightClientSession>::value && 120// std::is_base_of_v<KAutoObject, KDeviceAddressSpace>);
121// std::is_base_of<KAutoObject, KLightClientSession>::value); 121// static_assert(std::is_final_v<KSessionRequest> &&
122// static_assert(std::is_final<KLightServerSession>::value && 122// std::is_base_of_v<KAutoObject, KSessionRequest>);
123// std::is_base_of<KAutoObject, KLightServerSession>::value); 123// static_assert(std::is_final_v<KCodeMemory> &&
124static_assert(std::is_final<KTransferMemory>::value && 124// std::is_base_of_v<KAutoObject, KCodeMemory>);
125 std::is_base_of<KAutoObject, KTransferMemory>::value);
126// static_assert(std::is_final<KDeviceAddressSpace>::value &&
127// std::is_base_of<KAutoObject, KDeviceAddressSpace>::value);
128// static_assert(std::is_final<KSessionRequest>::value &&
129// std::is_base_of<KAutoObject, KSessionRequest>::value);
130// static_assert(std::is_final<KCodeMemory>::value &&
131// std::is_base_of<KAutoObject, KCodeMemory>::value);
132 125
133} // namespace Kernel 126} // namespace Kernel
diff --git a/src/core/hle/kernel/k_client_port.h b/src/core/hle/kernel/k_client_port.h
index 8501156e8..f2fff3b01 100644
--- a/src/core/hle/kernel/k_client_port.h
+++ b/src/core/hle/kernel/k_client_port.h
@@ -22,7 +22,7 @@ class KClientPort final : public KSynchronizationObject {
22 22
23public: 23public:
24 explicit KClientPort(KernelCore& kernel_); 24 explicit KClientPort(KernelCore& kernel_);
25 virtual ~KClientPort() override; 25 ~KClientPort() override;
26 26
27 void Initialize(KPort* parent_, s32 max_sessions_, std::string&& name_); 27 void Initialize(KPort* parent_, s32 max_sessions_, std::string&& name_);
28 void OnSessionFinalized(); 28 void OnSessionFinalized();
@@ -49,8 +49,8 @@ public:
49 bool IsServerClosed() const; 49 bool IsServerClosed() const;
50 50
51 // Overridden virtual functions. 51 // Overridden virtual functions.
52 virtual void Destroy() override; 52 void Destroy() override;
53 virtual bool IsSignaled() const override; 53 bool IsSignaled() const override;
54 54
55 ResultCode CreateSession(KClientSession** out); 55 ResultCode CreateSession(KClientSession** out);
56 56
diff --git a/src/core/hle/kernel/k_client_session.h b/src/core/hle/kernel/k_client_session.h
index 720a8c243..b11d5b4e3 100644
--- a/src/core/hle/kernel/k_client_session.h
+++ b/src/core/hle/kernel/k_client_session.h
@@ -34,7 +34,7 @@ class KClientSession final
34 34
35public: 35public:
36 explicit KClientSession(KernelCore& kernel_); 36 explicit KClientSession(KernelCore& kernel_);
37 virtual ~KClientSession(); 37 ~KClientSession() override;
38 38
39 void Initialize(KSession* parent_, std::string&& name_) { 39 void Initialize(KSession* parent_, std::string&& name_) {
40 // Set member variables. 40 // Set member variables.
@@ -42,7 +42,7 @@ public:
42 name = std::move(name_); 42 name = std::move(name_);
43 } 43 }
44 44
45 virtual void Destroy() override; 45 void Destroy() override;
46 static void PostDestroy([[maybe_unused]] uintptr_t arg) {} 46 static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
47 47
48 KSession* GetParent() const { 48 KSession* GetParent() const {
diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h
index 9a59ffb70..3d3ec99e2 100644
--- a/src/core/hle/kernel/k_event.h
+++ b/src/core/hle/kernel/k_event.h
@@ -20,23 +20,21 @@ class KEvent final : public KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObj
20 20
21public: 21public:
22 explicit KEvent(KernelCore& kernel_); 22 explicit KEvent(KernelCore& kernel_);
23 virtual ~KEvent(); 23 ~KEvent() override;
24 24
25 void Initialize(std::string&& name); 25 void Initialize(std::string&& name);
26 26
27 virtual void Finalize() override; 27 void Finalize() override;
28 28
29 virtual bool IsInitialized() const override { 29 bool IsInitialized() const override {
30 return initialized; 30 return initialized;
31 } 31 }
32 32
33 virtual uintptr_t GetPostDestroyArgument() const override { 33 uintptr_t GetPostDestroyArgument() const override {
34 return reinterpret_cast<uintptr_t>(owner); 34 return reinterpret_cast<uintptr_t>(owner);
35 } 35 }
36 36
37 static void PostDestroy(uintptr_t arg); 37 KProcess* GetOwner() const override {
38
39 virtual KProcess* GetOwner() const override {
40 return owner; 38 return owner;
41 } 39 }
42 40
@@ -48,6 +46,8 @@ public:
48 return writable_event; 46 return writable_event;
49 } 47 }
50 48
49 static void PostDestroy(uintptr_t arg);
50
51private: 51private:
52 KReadableEvent readable_event; 52 KReadableEvent readable_event;
53 KWritableEvent writable_event; 53 KWritableEvent writable_event;
diff --git a/src/core/hle/kernel/k_port.h b/src/core/hle/kernel/k_port.h
index 960f1f3a3..4018ea2df 100644
--- a/src/core/hle/kernel/k_port.h
+++ b/src/core/hle/kernel/k_port.h
@@ -22,7 +22,7 @@ class KPort final : public KAutoObjectWithSlabHeapAndContainer<KPort, KAutoObjec
22 22
23public: 23public:
24 explicit KPort(KernelCore& kernel_); 24 explicit KPort(KernelCore& kernel_);
25 virtual ~KPort(); 25 ~KPort() override;
26 26
27 static void PostDestroy([[maybe_unused]] uintptr_t arg) {} 27 static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
28 28
@@ -59,7 +59,6 @@ private:
59 ServerClosed = 3, 59 ServerClosed = 3,
60 }; 60 };
61 61
62private:
63 KServerPort server; 62 KServerPort server;
64 KClientPort client; 63 KClientPort client;
65 State state{State::Invalid}; 64 State state{State::Invalid};
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index 123d71cd3..c0656b9af 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -331,19 +331,19 @@ public:
331 331
332 void LoadModule(CodeSet code_set, VAddr base_addr); 332 void LoadModule(CodeSet code_set, VAddr base_addr);
333 333
334 virtual bool IsInitialized() const override { 334 bool IsInitialized() const override {
335 return is_initialized; 335 return is_initialized;
336 } 336 }
337 337
338 static void PostDestroy([[maybe_unused]] uintptr_t arg) {} 338 static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
339 339
340 virtual void Finalize(); 340 void Finalize() override;
341 341
342 virtual u64 GetId() const override final { 342 u64 GetId() const override {
343 return GetProcessID(); 343 return GetProcessID();
344 } 344 }
345 345
346 virtual bool IsSignaled() const override; 346 bool IsSignaled() const override;
347 347
348 void PinCurrentThread(); 348 void PinCurrentThread();
349 void UnpinCurrentThread(); 349 void UnpinCurrentThread();
diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h
index 33cd1dd3e..b2850ac7b 100644
--- a/src/core/hle/kernel/k_readable_event.h
+++ b/src/core/hle/kernel/k_readable_event.h
@@ -31,8 +31,8 @@ public:
31 return parent; 31 return parent;
32 } 32 }
33 33
34 virtual bool IsSignaled() const override; 34 bool IsSignaled() const override;
35 virtual void Destroy() override; 35 void Destroy() override;
36 36
37 ResultCode Signal(); 37 ResultCode Signal();
38 ResultCode Clear(); 38 ResultCode Clear();
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h
index 0debbbb51..fab6005ff 100644
--- a/src/core/hle/kernel/k_resource_limit.h
+++ b/src/core/hle/kernel/k_resource_limit.h
@@ -37,10 +37,10 @@ class KResourceLimit final
37 37
38public: 38public:
39 explicit KResourceLimit(KernelCore& kernel_); 39 explicit KResourceLimit(KernelCore& kernel_);
40 virtual ~KResourceLimit(); 40 ~KResourceLimit() override;
41 41
42 void Initialize(const Core::Timing::CoreTiming* core_timing_); 42 void Initialize(const Core::Timing::CoreTiming* core_timing_);
43 virtual void Finalize() override; 43 void Finalize() override;
44 44
45 s64 GetLimitValue(LimitableResource which) const; 45 s64 GetLimitValue(LimitableResource which) const;
46 s64 GetCurrentValue(LimitableResource which) const; 46 s64 GetCurrentValue(LimitableResource which) const;
diff --git a/src/core/hle/kernel/k_server_port.h b/src/core/hle/kernel/k_server_port.h
index d1a757ec3..55481d63f 100644
--- a/src/core/hle/kernel/k_server_port.h
+++ b/src/core/hle/kernel/k_server_port.h
@@ -25,12 +25,9 @@ class SessionRequestHandler;
25class KServerPort final : public KSynchronizationObject { 25class KServerPort final : public KSynchronizationObject {
26 KERNEL_AUTOOBJECT_TRAITS(KServerPort, KSynchronizationObject); 26 KERNEL_AUTOOBJECT_TRAITS(KServerPort, KSynchronizationObject);
27 27
28private:
29 using SessionList = boost::intrusive::list<KServerSession>;
30
31public: 28public:
32 explicit KServerPort(KernelCore& kernel_); 29 explicit KServerPort(KernelCore& kernel_);
33 virtual ~KServerPort() override; 30 ~KServerPort() override;
34 31
35 void Initialize(KPort* parent_, std::string&& name_); 32 void Initialize(KPort* parent_, std::string&& name_);
36 33
@@ -63,13 +60,14 @@ public:
63 bool IsLight() const; 60 bool IsLight() const;
64 61
65 // Overridden virtual functions. 62 // Overridden virtual functions.
66 virtual void Destroy() override; 63 void Destroy() override;
67 virtual bool IsSignaled() const override; 64 bool IsSignaled() const override;
68 65
69private: 66private:
67 using SessionList = boost::intrusive::list<KServerSession>;
68
70 void CleanupSessions(); 69 void CleanupSessions();
71 70
72private:
73 SessionList session_list; 71 SessionList session_list;
74 SessionRequestHandlerPtr session_handler; 72 SessionRequestHandlerPtr session_handler;
75 KPort* parent{}; 73 KPort* parent{};
diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h
index dd4de2904..27b757ad2 100644
--- a/src/core/hle/kernel/k_server_session.h
+++ b/src/core/hle/kernel/k_server_session.h
@@ -42,9 +42,9 @@ class KServerSession final : public KSynchronizationObject,
42 42
43public: 43public:
44 explicit KServerSession(KernelCore& kernel_); 44 explicit KServerSession(KernelCore& kernel_);
45 virtual ~KServerSession() override; 45 ~KServerSession() override;
46 46
47 virtual void Destroy() override; 47 void Destroy() override;
48 48
49 void Initialize(KSession* parent_, std::string&& name_); 49 void Initialize(KSession* parent_, std::string&& name_);
50 50
@@ -56,7 +56,7 @@ public:
56 return parent; 56 return parent;
57 } 57 }
58 58
59 virtual bool IsSignaled() const override; 59 bool IsSignaled() const override;
60 60
61 void OnClientClosed(); 61 void OnClientClosed();
62 62
diff --git a/src/core/hle/kernel/k_session.h b/src/core/hle/kernel/k_session.h
index a981fd1f6..4ddd080d2 100644
--- a/src/core/hle/kernel/k_session.h
+++ b/src/core/hle/kernel/k_session.h
@@ -18,17 +18,17 @@ class KSession final : public KAutoObjectWithSlabHeapAndContainer<KSession, KAut
18 18
19public: 19public:
20 explicit KSession(KernelCore& kernel_); 20 explicit KSession(KernelCore& kernel_);
21 virtual ~KSession() override; 21 ~KSession() override;
22 22
23 void Initialize(KClientPort* port_, const std::string& name_); 23 void Initialize(KClientPort* port_, const std::string& name_);
24 24
25 virtual void Finalize() override; 25 void Finalize() override;
26 26
27 virtual bool IsInitialized() const override { 27 bool IsInitialized() const override {
28 return initialized; 28 return initialized;
29 } 29 }
30 30
31 virtual uintptr_t GetPostDestroyArgument() const override { 31 uintptr_t GetPostDestroyArgument() const override {
32 return reinterpret_cast<uintptr_t>(process); 32 return reinterpret_cast<uintptr_t>(process);
33 } 33 }
34 34
@@ -78,7 +78,6 @@ private:
78 ServerClosed = 3, 78 ServerClosed = 3,
79 }; 79 };
80 80
81private:
82 void SetState(State state) { 81 void SetState(State state) {
83 atomic_state = static_cast<u8>(state); 82 atomic_state = static_cast<u8>(state);
84 } 83 }
@@ -87,7 +86,6 @@ private:
87 return static_cast<State>(atomic_state.load(std::memory_order_relaxed)); 86 return static_cast<State>(atomic_state.load(std::memory_order_relaxed));
88 } 87 }
89 88
90private:
91 KServerSession server; 89 KServerSession server;
92 KClientSession client; 90 KClientSession client;
93 std::atomic<std::underlying_type_t<State>> atomic_state{ 91 std::atomic<std::underlying_type_t<State>> atomic_state{
diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h
index 553a56327..e9815f90b 100644
--- a/src/core/hle/kernel/k_shared_memory.h
+++ b/src/core/hle/kernel/k_shared_memory.h
@@ -68,9 +68,9 @@ public:
68 return device_memory->GetPointer(physical_address + offset); 68 return device_memory->GetPointer(physical_address + offset);
69 } 69 }
70 70
71 virtual void Finalize() override; 71 void Finalize() override;
72 72
73 virtual bool IsInitialized() const override { 73 bool IsInitialized() const override {
74 return is_initialized; 74 return is_initialized;
75 } 75 }
76 static void PostDestroy([[maybe_unused]] uintptr_t arg) {} 76 static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
diff --git a/src/core/hle/kernel/k_slab_heap.h b/src/core/hle/kernel/k_slab_heap.h
index 81d472a3e..0ad74b0a0 100644
--- a/src/core/hle/kernel/k_slab_heap.h
+++ b/src/core/hle/kernel/k_slab_heap.h
@@ -4,34 +4,213 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <atomic>
8
9#include "common/assert.h"
10#include "common/common_types.h"
11
7namespace Kernel { 12namespace Kernel {
8 13
9class KernelCore; 14class KernelCore;
10 15
11/// This is a placeholder class to manage slab heaps for kernel objects. For now, we just allocate 16namespace impl {
12/// these with new/delete, but this can be re-implemented later to allocate these in emulated 17
13/// memory. 18class KSlabHeapImpl final : NonCopyable {
19public:
20 struct Node {
21 Node* next{};
22 };
23
24 constexpr KSlabHeapImpl() = default;
25
26 void Initialize(std::size_t size) {
27 ASSERT(head == nullptr);
28 obj_size = size;
29 }
30
31 constexpr std::size_t GetObjectSize() const {
32 return obj_size;
33 }
34
35 Node* GetHead() const {
36 return head;
37 }
38
39 void* Allocate() {
40 Node* ret = head.load();
41
42 do {
43 if (ret == nullptr) {
44 break;
45 }
46 } while (!head.compare_exchange_weak(ret, ret->next));
47
48 return ret;
49 }
50
51 void Free(void* obj) {
52 Node* node = static_cast<Node*>(obj);
53
54 Node* cur_head = head.load();
55 do {
56 node->next = cur_head;
57 } while (!head.compare_exchange_weak(cur_head, node));
58 }
59
60private:
61 std::atomic<Node*> head{};
62 std::size_t obj_size{};
63};
64
65} // namespace impl
66
67class KSlabHeapBase : NonCopyable {
68public:
69 constexpr KSlabHeapBase() = default;
70
71 constexpr bool Contains(uintptr_t addr) const {
72 return start <= addr && addr < end;
73 }
74
75 constexpr std::size_t GetSlabHeapSize() const {
76 return (end - start) / GetObjectSize();
77 }
78
79 constexpr std::size_t GetObjectSize() const {
80 return impl.GetObjectSize();
81 }
82
83 constexpr uintptr_t GetSlabHeapAddress() const {
84 return start;
85 }
86
87 std::size_t GetObjectIndexImpl(const void* obj) const {
88 return (reinterpret_cast<uintptr_t>(obj) - start) / GetObjectSize();
89 }
90
91 std::size_t GetPeakIndex() const {
92 return GetObjectIndexImpl(reinterpret_cast<const void*>(peak));
93 }
94
95 void* AllocateImpl() {
96 return impl.Allocate();
97 }
98
99 void FreeImpl(void* obj) {
100 // Don't allow freeing an object that wasn't allocated from this heap
101 ASSERT(Contains(reinterpret_cast<uintptr_t>(obj)));
102
103 impl.Free(obj);
104 }
105
106 void InitializeImpl(std::size_t obj_size, void* memory, std::size_t memory_size) {
107 // Ensure we don't initialize a slab using null memory
108 ASSERT(memory != nullptr);
109
110 // Initialize the base allocator
111 impl.Initialize(obj_size);
112
113 // Set our tracking variables
114 const std::size_t num_obj = (memory_size / obj_size);
115 start = reinterpret_cast<uintptr_t>(memory);
116 end = start + num_obj * obj_size;
117 peak = start;
118
119 // Free the objects
120 u8* cur = reinterpret_cast<u8*>(end);
121
122 for (std::size_t i{}; i < num_obj; i++) {
123 cur -= obj_size;
124 impl.Free(cur);
125 }
126 }
127
128private:
129 using Impl = impl::KSlabHeapImpl;
130
131 Impl impl;
132 uintptr_t peak{};
133 uintptr_t start{};
134 uintptr_t end{};
135};
14 136
15template <typename T> 137template <typename T>
16class KSlabHeap final : NonCopyable { 138class KSlabHeap final : public KSlabHeapBase {
17public: 139public:
18 KSlabHeap() = default; 140 enum class AllocationType {
141 Host,
142 Guest,
143 };
19 144
20 void Initialize([[maybe_unused]] void* memory, [[maybe_unused]] std::size_t memory_size) { 145 explicit constexpr KSlabHeap(AllocationType allocation_type_ = AllocationType::Host)
21 // Placeholder that should initialize the backing slab heap implementation. 146 : KSlabHeapBase(), allocation_type{allocation_type_} {}
147
148 void Initialize(void* memory, std::size_t memory_size) {
149 if (allocation_type == AllocationType::Guest) {
150 InitializeImpl(sizeof(T), memory, memory_size);
151 }
22 } 152 }
23 153
24 T* Allocate() { 154 T* Allocate() {
25 return new T(); 155 switch (allocation_type) {
156 case AllocationType::Host:
157 // Fallback for cases where we do not yet support allocating guest memory from the slab
158 // heap, such as for kernel memory regions.
159 return new T;
160
161 case AllocationType::Guest:
162 T* obj = static_cast<T*>(AllocateImpl());
163 if (obj != nullptr) {
164 new (obj) T();
165 }
166 return obj;
167 }
168
169 UNREACHABLE_MSG("Invalid AllocationType {}", allocation_type);
170 return nullptr;
26 } 171 }
27 172
28 T* AllocateWithKernel(KernelCore& kernel) { 173 T* AllocateWithKernel(KernelCore& kernel) {
29 return new T(kernel); 174 switch (allocation_type) {
175 case AllocationType::Host:
176 // Fallback for cases where we do not yet support allocating guest memory from the slab
177 // heap, such as for kernel memory regions.
178 return new T(kernel);
179
180 case AllocationType::Guest:
181 T* obj = static_cast<T*>(AllocateImpl());
182 if (obj != nullptr) {
183 new (obj) T(kernel);
184 }
185 return obj;
186 }
187
188 UNREACHABLE_MSG("Invalid AllocationType {}", allocation_type);
189 return nullptr;
30 } 190 }
31 191
32 void Free(T* obj) { 192 void Free(T* obj) {
33 delete obj; 193 switch (allocation_type) {
194 case AllocationType::Host:
195 // Fallback for cases where we do not yet support allocating guest memory from the slab
196 // heap, such as for kernel memory regions.
197 delete obj;
198 return;
199
200 case AllocationType::Guest:
201 FreeImpl(obj);
202 return;
203 }
204
205 UNREACHABLE_MSG("Invalid AllocationType {}", allocation_type);
34 } 206 }
207
208 constexpr std::size_t GetObjectIndex(const T* obj) const {
209 return GetObjectIndexImpl(obj);
210 }
211
212private:
213 const AllocationType allocation_type;
35}; 214};
36 215
37} // namespace Kernel 216} // namespace Kernel
diff --git a/src/core/hle/kernel/k_synchronization_object.h b/src/core/hle/kernel/k_synchronization_object.h
index a41dd1220..3d4ce1fbc 100644
--- a/src/core/hle/kernel/k_synchronization_object.h
+++ b/src/core/hle/kernel/k_synchronization_object.h
@@ -29,7 +29,7 @@ public:
29 KSynchronizationObject** objects, const s32 num_objects, 29 KSynchronizationObject** objects, const s32 num_objects,
30 s64 timeout); 30 s64 timeout);
31 31
32 virtual void Finalize() override; 32 void Finalize() override;
33 33
34 [[nodiscard]] virtual bool IsSignaled() const = 0; 34 [[nodiscard]] virtual bool IsSignaled() const = 0;
35 35
@@ -37,7 +37,7 @@ public:
37 37
38protected: 38protected:
39 explicit KSynchronizationObject(KernelCore& kernel); 39 explicit KSynchronizationObject(KernelCore& kernel);
40 virtual ~KSynchronizationObject(); 40 ~KSynchronizationObject() override;
41 41
42 virtual void OnFinalizeSynchronizationObject() {} 42 virtual void OnFinalizeSynchronizationObject() {}
43 43
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index e3f08f256..3cf43d290 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -168,13 +168,13 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s
168 std::memset(static_cast<void*>(std::addressof(GetStackParameters())), 0, 168 std::memset(static_cast<void*>(std::addressof(GetStackParameters())), 0,
169 sizeof(StackParameters)); 169 sizeof(StackParameters));
170 170
171 // Setup the TLS, if needed.
172 if (type == ThreadType::User) {
173 tls_address = owner->CreateTLSRegion();
174 }
175
176 // Set parent, if relevant. 171 // Set parent, if relevant.
177 if (owner != nullptr) { 172 if (owner != nullptr) {
173 // Setup the TLS, if needed.
174 if (type == ThreadType::User) {
175 tls_address = owner->CreateTLSRegion();
176 }
177
178 parent = owner; 178 parent = owner;
179 parent->Open(); 179 parent->Open();
180 parent->IncrementThreadCount(); 180 parent->IncrementThreadCount();
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index 4abfc2b49..01eebb165 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -358,21 +358,21 @@ public:
358 return termination_requested || GetRawState() == ThreadState::Terminated; 358 return termination_requested || GetRawState() == ThreadState::Terminated;
359 } 359 }
360 360
361 [[nodiscard]] virtual u64 GetId() const override final { 361 [[nodiscard]] u64 GetId() const override {
362 return this->GetThreadID(); 362 return this->GetThreadID();
363 } 363 }
364 364
365 [[nodiscard]] virtual bool IsInitialized() const override { 365 [[nodiscard]] bool IsInitialized() const override {
366 return initialized; 366 return initialized;
367 } 367 }
368 368
369 [[nodiscard]] virtual uintptr_t GetPostDestroyArgument() const override { 369 [[nodiscard]] uintptr_t GetPostDestroyArgument() const override {
370 return reinterpret_cast<uintptr_t>(parent) | (resource_limit_release_hint ? 1 : 0); 370 return reinterpret_cast<uintptr_t>(parent) | (resource_limit_release_hint ? 1 : 0);
371 } 371 }
372 372
373 virtual void Finalize() override; 373 void Finalize() override;
374 374
375 [[nodiscard]] virtual bool IsSignaled() const override; 375 [[nodiscard]] bool IsSignaled() const override;
376 376
377 static void PostDestroy(uintptr_t arg); 377 static void PostDestroy(uintptr_t arg);
378 378
diff --git a/src/core/hle/kernel/k_transfer_memory.h b/src/core/hle/kernel/k_transfer_memory.h
index c2d0f1eaf..31029a5c2 100644
--- a/src/core/hle/kernel/k_transfer_memory.h
+++ b/src/core/hle/kernel/k_transfer_memory.h
@@ -27,23 +27,23 @@ class KTransferMemory final
27 27
28public: 28public:
29 explicit KTransferMemory(KernelCore& kernel_); 29 explicit KTransferMemory(KernelCore& kernel_);
30 virtual ~KTransferMemory() override; 30 ~KTransferMemory() override;
31 31
32 ResultCode Initialize(VAddr address_, std::size_t size_, Svc::MemoryPermission owner_perm_); 32 ResultCode Initialize(VAddr address_, std::size_t size_, Svc::MemoryPermission owner_perm_);
33 33
34 virtual void Finalize() override; 34 void Finalize() override;
35 35
36 virtual bool IsInitialized() const override { 36 bool IsInitialized() const override {
37 return is_initialized; 37 return is_initialized;
38 } 38 }
39 39
40 virtual uintptr_t GetPostDestroyArgument() const override { 40 uintptr_t GetPostDestroyArgument() const override {
41 return reinterpret_cast<uintptr_t>(owner); 41 return reinterpret_cast<uintptr_t>(owner);
42 } 42 }
43 43
44 static void PostDestroy(uintptr_t arg); 44 static void PostDestroy(uintptr_t arg);
45 45
46 KProcess* GetOwner() const { 46 KProcess* GetOwner() const override {
47 return owner; 47 return owner;
48 } 48 }
49 49
diff --git a/src/core/hle/kernel/k_writable_event.h b/src/core/hle/kernel/k_writable_event.h
index 607b0eadb..858d982c4 100644
--- a/src/core/hle/kernel/k_writable_event.h
+++ b/src/core/hle/kernel/k_writable_event.h
@@ -21,7 +21,7 @@ public:
21 explicit KWritableEvent(KernelCore& kernel_); 21 explicit KWritableEvent(KernelCore& kernel_);
22 ~KWritableEvent() override; 22 ~KWritableEvent() override;
23 23
24 virtual void Destroy() override; 24 void Destroy() override;
25 25
26 static void PostDestroy([[maybe_unused]] uintptr_t arg) {} 26 static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
27 27
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 8b55df82e..0ffb78d51 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -258,7 +258,7 @@ struct KernelCore::Impl {
258 KAutoObject::Create(thread.get()); 258 KAutoObject::Create(thread.get());
259 ASSERT(KThread::InitializeDummyThread(thread.get()).IsSuccess()); 259 ASSERT(KThread::InitializeDummyThread(thread.get()).IsSuccess());
260 thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); 260 thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId()));
261 return std::move(thread); 261 return thread;
262 }; 262 };
263 263
264 thread_local auto thread = make_thread(); 264 thread_local auto thread = make_thread();
@@ -620,7 +620,8 @@ struct KernelCore::Impl {
620 620
621 void InitializePageSlab() { 621 void InitializePageSlab() {
622 // Allocate slab heaps 622 // Allocate slab heaps
623 user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>(); 623 user_slab_heap_pages =
624 std::make_unique<KSlabHeap<Page>>(KSlabHeap<Page>::AllocationType::Guest);
624 625
625 // TODO(ameerj): This should be derived, not hardcoded within the kernel 626 // TODO(ameerj): This should be derived, not hardcoded within the kernel
626 constexpr u64 user_slab_heap_size{0x3de000}; 627 constexpr u64 user_slab_heap_size{0x3de000};
diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp
index b05a5da04..b1a81810b 100644
--- a/src/core/hle/service/am/applets/software_keyboard.cpp
+++ b/src/core/hle/service/am/applets/software_keyboard.cpp
@@ -273,8 +273,13 @@ void SoftwareKeyboard::ProcessTextCheck() {
273 273
274 std::memcpy(&swkbd_text_check, text_check_data.data(), sizeof(SwkbdTextCheck)); 274 std::memcpy(&swkbd_text_check, text_check_data.data(), sizeof(SwkbdTextCheck));
275 275
276 std::u16string text_check_message = Common::UTF16StringFromFixedZeroTerminatedBuffer( 276 std::u16string text_check_message =
277 swkbd_text_check.text_check_message.data(), swkbd_text_check.text_check_message.size()); 277 swkbd_text_check.text_check_result == SwkbdTextCheckResult::Failure ||
278 swkbd_text_check.text_check_result == SwkbdTextCheckResult::Confirm
279 ? Common::UTF16StringFromFixedZeroTerminatedBuffer(
280 swkbd_text_check.text_check_message.data(),
281 swkbd_text_check.text_check_message.size())
282 : u"";
278 283
279 LOG_INFO(Service_AM, "\nTextCheckResult: {}\nTextCheckMessage: {}", 284 LOG_INFO(Service_AM, "\nTextCheckResult: {}\nTextCheckMessage: {}",
280 GetTextCheckResultName(swkbd_text_check.text_check_result), 285 GetTextCheckResultName(swkbd_text_check.text_check_result),
@@ -285,10 +290,10 @@ void SoftwareKeyboard::ProcessTextCheck() {
285 SubmitNormalOutputAndExit(SwkbdResult::Ok, current_text); 290 SubmitNormalOutputAndExit(SwkbdResult::Ok, current_text);
286 break; 291 break;
287 case SwkbdTextCheckResult::Failure: 292 case SwkbdTextCheckResult::Failure:
288 ShowTextCheckDialog(SwkbdTextCheckResult::Failure, text_check_message); 293 ShowTextCheckDialog(SwkbdTextCheckResult::Failure, std::move(text_check_message));
289 break; 294 break;
290 case SwkbdTextCheckResult::Confirm: 295 case SwkbdTextCheckResult::Confirm:
291 ShowTextCheckDialog(SwkbdTextCheckResult::Confirm, text_check_message); 296 ShowTextCheckDialog(SwkbdTextCheckResult::Confirm, std::move(text_check_message));
292 break; 297 break;
293 case SwkbdTextCheckResult::Silent: 298 case SwkbdTextCheckResult::Silent:
294 default: 299 default:
@@ -482,7 +487,7 @@ void SoftwareKeyboard::InitializeFrontendKeyboard() {
482 max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box; 487 max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box;
483 488
484 Core::Frontend::KeyboardInitializeParameters initialize_parameters{ 489 Core::Frontend::KeyboardInitializeParameters initialize_parameters{
485 .ok_text{ok_text}, 490 .ok_text{std::move(ok_text)},
486 .header_text{}, 491 .header_text{},
487 .sub_text{}, 492 .sub_text{},
488 .guide_text{}, 493 .guide_text{},
@@ -558,10 +563,10 @@ void SoftwareKeyboard::InitializeFrontendKeyboard() {
558 : false; 563 : false;
559 564
560 Core::Frontend::KeyboardInitializeParameters initialize_parameters{ 565 Core::Frontend::KeyboardInitializeParameters initialize_parameters{
561 .ok_text{ok_text}, 566 .ok_text{std::move(ok_text)},
562 .header_text{header_text}, 567 .header_text{std::move(header_text)},
563 .sub_text{sub_text}, 568 .sub_text{std::move(sub_text)},
564 .guide_text{guide_text}, 569 .guide_text{std::move(guide_text)},
565 .initial_text{initial_text}, 570 .initial_text{initial_text},
566 .max_text_length{max_text_length}, 571 .max_text_length{max_text_length},
567 .min_text_length{min_text_length}, 572 .min_text_length{min_text_length},
@@ -590,7 +595,7 @@ void SoftwareKeyboard::ShowNormalKeyboard() {
590 595
591void SoftwareKeyboard::ShowTextCheckDialog(SwkbdTextCheckResult text_check_result, 596void SoftwareKeyboard::ShowTextCheckDialog(SwkbdTextCheckResult text_check_result,
592 std::u16string text_check_message) { 597 std::u16string text_check_message) {
593 frontend.ShowTextCheckDialog(text_check_result, text_check_message); 598 frontend.ShowTextCheckDialog(text_check_result, std::move(text_check_message));
594} 599}
595 600
596void SoftwareKeyboard::ShowInlineKeyboard() { 601void SoftwareKeyboard::ShowInlineKeyboard() {
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h
index eecfeaad5..7e7ae6625 100644
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ b/src/core/hle/service/hid/controllers/gesture.h
@@ -7,6 +7,7 @@
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/point.h"
10#include "core/frontend/input.h" 11#include "core/frontend/input.h"
11#include "core/hle/service/hid/controllers/controller_base.h" 12#include "core/hle/service/hid/controllers/controller_base.h"
12 13
@@ -63,44 +64,21 @@ private:
63 }; 64 };
64 static_assert(sizeof(Attribute) == 4, "Attribute is an invalid size"); 65 static_assert(sizeof(Attribute) == 4, "Attribute is an invalid size");
65 66
66 template <typename T>
67 struct Point {
68 T x{};
69 T y{};
70
71 friend Point operator+(const Point& lhs, const Point& rhs) {
72 return {
73 .x = lhs.x + rhs.x,
74 .y = lhs.y + rhs.y,
75 };
76 }
77
78 friend Point operator-(const Point& lhs, const Point& rhs) {
79 return {
80 .x = lhs.x - rhs.x,
81 .y = lhs.y - rhs.y,
82 };
83 }
84
85 friend bool operator==(const Point&, const Point&) = default;
86 };
87 static_assert(sizeof(Point<s32_le>) == 8, "Point is an invalid size");
88
89 struct GestureState { 67 struct GestureState {
90 s64_le sampling_number; 68 s64_le sampling_number;
91 s64_le sampling_number2; 69 s64_le sampling_number2;
92 s64_le detection_count; 70 s64_le detection_count;
93 TouchType type; 71 TouchType type;
94 Direction direction; 72 Direction direction;
95 Point<s32_le> pos; 73 Common::Point<s32_le> pos;
96 Point<s32_le> delta; 74 Common::Point<s32_le> delta;
97 f32 vel_x; 75 f32 vel_x;
98 f32 vel_y; 76 f32 vel_y;
99 Attribute attributes; 77 Attribute attributes;
100 f32 scale; 78 f32 scale;
101 f32 rotation_angle; 79 f32 rotation_angle;
102 s32_le point_count; 80 s32_le point_count;
103 std::array<Point<s32_le>, 4> points; 81 std::array<Common::Point<s32_le>, 4> points;
104 }; 82 };
105 static_assert(sizeof(GestureState) == 0x68, "GestureState is an invalid size"); 83 static_assert(sizeof(GestureState) == 0x68, "GestureState is an invalid size");
106 84
@@ -111,14 +89,14 @@ private:
111 static_assert(sizeof(SharedMemory) == 0x708, "SharedMemory is an invalid size"); 89 static_assert(sizeof(SharedMemory) == 0x708, "SharedMemory is an invalid size");
112 90
113 struct Finger { 91 struct Finger {
114 Point<f32> pos{}; 92 Common::Point<f32> pos{};
115 bool pressed{}; 93 bool pressed{};
116 }; 94 };
117 95
118 struct GestureProperties { 96 struct GestureProperties {
119 std::array<Point<s32_le>, MAX_POINTS> points{}; 97 std::array<Common::Point<s32_le>, MAX_POINTS> points{};
120 std::size_t active_points{}; 98 std::size_t active_points{};
121 Point<s32_le> mid_point{}; 99 Common::Point<s32_le> mid_point{};
122 s64_le detection_count{}; 100 s64_le detection_count{};
123 u64_le delta_time{}; 101 u64_le delta_time{};
124 f32 average_distance{}; 102 f32 average_distance{};
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index ac9112c40..6ef17acc5 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -74,8 +74,11 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
74 for (std::size_t id = 0; id < MAX_FINGERS; ++id) { 74 for (std::size_t id = 0; id < MAX_FINGERS; ++id) {
75 auto& touch_entry = cur_entry.states[id]; 75 auto& touch_entry = cur_entry.states[id];
76 if (id < active_fingers_count) { 76 if (id < active_fingers_count) {
77 touch_entry.x = static_cast<u16>(active_fingers[id].x * Layout::ScreenUndocked::Width); 77 const auto& [active_x, active_y] = active_fingers[id].position;
78 touch_entry.y = static_cast<u16>(active_fingers[id].y * Layout::ScreenUndocked::Height); 78 touch_entry.position = {
79 .x = static_cast<u16>(active_x * Layout::ScreenUndocked::Width),
80 .y = static_cast<u16>(active_y * Layout::ScreenUndocked::Height),
81 };
79 touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; 82 touch_entry.diameter_x = Settings::values.touchscreen.diameter_x;
80 touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; 83 touch_entry.diameter_y = Settings::values.touchscreen.diameter_y;
81 touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; 84 touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle;
@@ -86,8 +89,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
86 } else { 89 } else {
87 // Clear touch entry 90 // Clear touch entry
88 touch_entry.attribute.raw = 0; 91 touch_entry.attribute.raw = 0;
89 touch_entry.x = 0; 92 touch_entry.position = {};
90 touch_entry.y = 0;
91 touch_entry.diameter_x = 0; 93 touch_entry.diameter_x = 0;
92 touch_entry.diameter_y = 0; 94 touch_entry.diameter_y = 0;
93 touch_entry.rotation_angle = 0; 95 touch_entry.rotation_angle = 0;
@@ -140,8 +142,7 @@ std::size_t Controller_Touchscreen::UpdateTouchInputEvent(
140 fingers[finger_id].id = static_cast<u32_le>(finger_id); 142 fingers[finger_id].id = static_cast<u32_le>(finger_id);
141 attribute.start_touch.Assign(1); 143 attribute.start_touch.Assign(1);
142 } 144 }
143 fingers[finger_id].x = x; 145 fingers[finger_id].position = {x, y};
144 fingers[finger_id].y = y;
145 fingers[finger_id].attribute = attribute; 146 fingers[finger_id].attribute = attribute;
146 return finger_id; 147 return finger_id;
147 } 148 }
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h
index 2869d0cfd..ef2becefd 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.h
+++ b/src/core/hle/service/hid/controllers/touchscreen.h
@@ -7,6 +7,7 @@
7#include "common/bit_field.h" 7#include "common/bit_field.h"
8#include "common/common_funcs.h" 8#include "common/common_funcs.h"
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "common/point.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"
@@ -55,8 +56,7 @@ private:
55 u64_le delta_time; 56 u64_le delta_time;
56 Attributes attribute; 57 Attributes attribute;
57 u32_le finger; 58 u32_le finger;
58 u32_le x; 59 Common::Point<u32_le> position;
59 u32_le y;
60 u32_le diameter_x; 60 u32_le diameter_x;
61 u32_le diameter_y; 61 u32_le diameter_y;
62 u32_le rotation_angle; 62 u32_le rotation_angle;
@@ -81,8 +81,7 @@ private:
81 81
82 struct Finger { 82 struct Finger {
83 u64_le last_touch{}; 83 u64_le last_touch{};
84 float x{}; 84 Common::Point<float> position;
85 float y{};
86 u32_le id{}; 85 u32_le id{};
87 bool pressed{}; 86 bool pressed{};
88 Attributes attribute; 87 Attributes attribute;
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp
index d160ffe87..c709a8028 100644
--- a/src/core/hle/service/ldn/ldn.cpp
+++ b/src/core/hle/service/ldn/ldn.cpp
@@ -215,10 +215,151 @@ public:
215 } 215 }
216}; 216};
217 217
218class INetworkService final : public ServiceFramework<INetworkService> {
219public:
220 explicit INetworkService(Core::System& system_) : ServiceFramework{system_, "INetworkService"} {
221 // clang-format off
222 static const FunctionInfo functions[] = {
223 {0, nullptr, "Initialize"},
224 {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"},
225 {264, nullptr, "GetNetworkInterfaceLastError"},
226 {272, nullptr, "GetRole"},
227 {280, nullptr, "GetAdvertiseData"},
228 {288, nullptr, "GetGroupInfo"},
229 {296, nullptr, "GetGroupInfo2"},
230 {304, nullptr, "GetGroupOwner"},
231 {312, nullptr, "GetIpConfig"},
232 {320, nullptr, "GetLinkLevel"},
233 {512, nullptr, "Scan"},
234 {768, nullptr, "CreateGroup"},
235 {776, nullptr, "DestroyGroup"},
236 {784, nullptr, "SetAdvertiseData"},
237 {1536, nullptr, "SendToOtherGroup"},
238 {1544, nullptr, "RecvFromOtherGroup"},
239 {1552, nullptr, "AddAcceptableGroupId"},
240 {1560, nullptr, "ClearAcceptableGroupId"},
241 };
242 // clang-format on
243
244 RegisterHandlers(functions);
245 }
246};
247
248class INetworkServiceMonitor final : public ServiceFramework<INetworkServiceMonitor> {
249public:
250 explicit INetworkServiceMonitor(Core::System& system_)
251 : ServiceFramework{system_, "INetworkServiceMonitor"} {
252 // clang-format off
253 static const FunctionInfo functions[] = {
254 {0, &INetworkServiceMonitor::Initialize, "Initialize"},
255 {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"},
256 {264, nullptr, "GetNetworkInterfaceLastError"},
257 {272, nullptr, "GetRole"},
258 {280, nullptr, "GetAdvertiseData"},
259 {281, nullptr, "GetAdvertiseData2"},
260 {288, nullptr, "GetGroupInfo"},
261 {296, nullptr, "GetGroupInfo2"},
262 {304, nullptr, "GetGroupOwner"},
263 {312, nullptr, "GetIpConfig"},
264 {320, nullptr, "GetLinkLevel"},
265 {328, nullptr, "AttachJoinEvent"},
266 {336, nullptr, "GetMembers"},
267 };
268 // clang-format on
269
270 RegisterHandlers(functions);
271 }
272
273 void Initialize(Kernel::HLERequestContext& ctx) {
274 LOG_WARNING(Service_LDN, "(STUBBED) called");
275
276 IPC::ResponseBuilder rb{ctx, 2};
277 rb.Push(ERROR_DISABLED);
278 }
279};
280
281class LP2PAPP final : public ServiceFramework<LP2PAPP> {
282public:
283 explicit LP2PAPP(Core::System& system_) : ServiceFramework{system_, "lp2p:app"} {
284 // clang-format off
285 static const FunctionInfo functions[] = {
286 {0, &LP2PAPP::CreateMonitorService, "CreateNetworkService"},
287 {8, &LP2PAPP::CreateMonitorService, "CreateNetworkServiceMonitor"},
288 };
289 // clang-format on
290
291 RegisterHandlers(functions);
292 }
293
294 void CreateNetworkervice(Kernel::HLERequestContext& ctx) {
295 IPC::RequestParser rp{ctx};
296 const u64 reserved_input = rp.Pop<u64>();
297 const u32 input = rp.Pop<u32>();
298
299 LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={} input={}", reserved_input,
300 input);
301
302 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
303 rb.Push(RESULT_SUCCESS);
304 rb.PushIpcInterface<INetworkService>(system);
305 }
306
307 void CreateMonitorService(Kernel::HLERequestContext& ctx) {
308 IPC::RequestParser rp{ctx};
309 const u64 reserved_input = rp.Pop<u64>();
310
311 LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={}", reserved_input);
312
313 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
314 rb.Push(RESULT_SUCCESS);
315 rb.PushIpcInterface<INetworkServiceMonitor>(system);
316 }
317};
318
319class LP2PSYS final : public ServiceFramework<LP2PSYS> {
320public:
321 explicit LP2PSYS(Core::System& system_) : ServiceFramework{system_, "lp2p:sys"} {
322 // clang-format off
323 static const FunctionInfo functions[] = {
324 {0, &LP2PSYS::CreateMonitorService, "CreateNetworkService"},
325 {8, &LP2PSYS::CreateMonitorService, "CreateNetworkServiceMonitor"},
326 };
327 // clang-format on
328
329 RegisterHandlers(functions);
330 }
331
332 void CreateNetworkervice(Kernel::HLERequestContext& ctx) {
333 IPC::RequestParser rp{ctx};
334 const u64 reserved_input = rp.Pop<u64>();
335 const u32 input = rp.Pop<u32>();
336
337 LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={} input={}", reserved_input,
338 input);
339
340 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
341 rb.Push(RESULT_SUCCESS);
342 rb.PushIpcInterface<INetworkService>(system);
343 }
344
345 void CreateMonitorService(Kernel::HLERequestContext& ctx) {
346 IPC::RequestParser rp{ctx};
347 const u64 reserved_input = rp.Pop<u64>();
348
349 LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={}", reserved_input);
350
351 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
352 rb.Push(RESULT_SUCCESS);
353 rb.PushIpcInterface<INetworkServiceMonitor>(system);
354 }
355};
356
218void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 357void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
219 std::make_shared<LDNM>(system)->InstallAsService(sm); 358 std::make_shared<LDNM>(system)->InstallAsService(sm);
220 std::make_shared<LDNS>(system)->InstallAsService(sm); 359 std::make_shared<LDNS>(system)->InstallAsService(sm);
221 std::make_shared<LDNU>(system)->InstallAsService(sm); 360 std::make_shared<LDNU>(system)->InstallAsService(sm);
361 std::make_shared<LP2PAPP>(system)->InstallAsService(sm);
362 std::make_shared<LP2PSYS>(system)->InstallAsService(sm);
222} 363}
223 364
224} // namespace Service::LDN 365} // namespace Service::LDN
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index de971041f..9e6b87960 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -596,7 +596,7 @@ void BufferCache<P>::PopAsyncFlushes() {
596 runtime.CopyBuffer(download_staging.buffer, slot_buffers[buffer_id], copies); 596 runtime.CopyBuffer(download_staging.buffer, slot_buffers[buffer_id], copies);
597 } 597 }
598 runtime.Finish(); 598 runtime.Finish();
599 for (const auto [copy, buffer_id] : downloads) { 599 for (const auto& [copy, buffer_id] : downloads) {
600 const Buffer& buffer = slot_buffers[buffer_id]; 600 const Buffer& buffer = slot_buffers[buffer_id];
601 const VAddr cpu_addr = buffer.CpuAddr() + copy.src_offset; 601 const VAddr cpu_addr = buffer.CpuAddr() + copy.src_offset;
602 // Undo the modified offset 602 // Undo the modified offset
@@ -606,7 +606,7 @@ void BufferCache<P>::PopAsyncFlushes() {
606 } 606 }
607 } else { 607 } else {
608 const std::span<u8> immediate_buffer = ImmediateBuffer(largest_copy); 608 const std::span<u8> immediate_buffer = ImmediateBuffer(largest_copy);
609 for (const auto [copy, buffer_id] : downloads) { 609 for (const auto& [copy, buffer_id] : downloads) {
610 Buffer& buffer = slot_buffers[buffer_id]; 610 Buffer& buffer = slot_buffers[buffer_id];
611 buffer.ImmediateDownload(copy.src_offset, immediate_buffer.subspan(0, copy.size)); 611 buffer.ImmediateDownload(copy.src_offset, immediate_buffer.subspan(0, copy.size));
612 const VAddr cpu_addr = buffer.CpuAddr() + copy.src_offset; 612 const VAddr cpu_addr = buffer.CpuAddr() + copy.src_offset;
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 37f7b24e1..35cc561be 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -104,7 +104,13 @@ void GPU::WaitFence(u32 syncpoint_id, u32 value) {
104 } 104 }
105 MICROPROFILE_SCOPE(GPU_wait); 105 MICROPROFILE_SCOPE(GPU_wait);
106 std::unique_lock lock{sync_mutex}; 106 std::unique_lock lock{sync_mutex};
107 sync_cv.wait(lock, [=, this] { return syncpoints.at(syncpoint_id).load() >= value; }); 107 sync_cv.wait(lock, [=, this] {
108 if (shutting_down.load(std::memory_order_relaxed)) {
109 // We're shutting down, ensure no threads continue to wait for the next syncpoint
110 return true;
111 }
112 return syncpoints.at(syncpoint_id).load() >= value;
113 });
108} 114}
109 115
110void GPU::IncrementSyncPoint(const u32 syncpoint_id) { 116void GPU::IncrementSyncPoint(const u32 syncpoint_id) {
@@ -523,6 +529,10 @@ void GPU::TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const {
523} 529}
524 530
525void GPU::ShutDown() { 531void GPU::ShutDown() {
532 // Signal that threads should no longer block on syncpoint fences
533 shutting_down.store(true, std::memory_order_relaxed);
534 sync_cv.notify_all();
535
526 gpu_thread.ShutDown(); 536 gpu_thread.ShutDown();
527} 537}
528 538
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 29a867863..a8e98e51b 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -389,6 +389,8 @@ private:
389 std::unique_ptr<Engines::KeplerMemory> kepler_memory; 389 std::unique_ptr<Engines::KeplerMemory> kepler_memory;
390 /// Shader build notifier 390 /// Shader build notifier
391 std::unique_ptr<VideoCore::ShaderNotify> shader_notify; 391 std::unique_ptr<VideoCore::ShaderNotify> shader_notify;
392 /// When true, we are about to shut down emulation session, so terminate outstanding tasks
393 std::atomic_bool shutting_down{};
392 394
393 std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{}; 395 std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{};
394 396
diff --git a/src/yuzu/applets/software_keyboard.cpp b/src/yuzu/applets/software_keyboard.cpp
index a9a095d58..aa453a79f 100644
--- a/src/yuzu/applets/software_keyboard.cpp
+++ b/src/yuzu/applets/software_keyboard.cpp
@@ -1101,12 +1101,11 @@ void QtSoftwareKeyboardDialog::NormalKeyboardButtonClicked(QPushButton* button)
1101 } 1101 }
1102 1102
1103 if (button == ui->button_ok || button == ui->button_ok_shift || button == ui->button_ok_num) { 1103 if (button == ui->button_ok || button == ui->button_ok_shift || button == ui->button_ok_num) {
1104 if (ui->topOSK->currentIndex() == 1) { 1104 auto text = ui->topOSK->currentIndex() == 1
1105 emit SubmitNormalText(SwkbdResult::Ok, 1105 ? ui->text_edit_osk->toPlainText().toStdU16String()
1106 ui->text_edit_osk->toPlainText().toStdU16String()); 1106 : ui->line_edit_osk->text().toStdU16String();
1107 } else { 1107
1108 emit SubmitNormalText(SwkbdResult::Ok, ui->line_edit_osk->text().toStdU16String()); 1108 emit SubmitNormalText(SwkbdResult::Ok, std::move(text));
1109 }
1110 return; 1109 return;
1111 } 1110 }
1112 1111
@@ -1265,13 +1264,11 @@ void QtSoftwareKeyboardDialog::TranslateButtonPress(HIDButton button) {
1265 if (is_inline) { 1264 if (is_inline) {
1266 emit SubmitInlineText(SwkbdReplyType::DecidedCancel, current_text, cursor_position); 1265 emit SubmitInlineText(SwkbdReplyType::DecidedCancel, current_text, cursor_position);
1267 } else { 1266 } else {
1268 if (ui->topOSK->currentIndex() == 1) { 1267 auto text = ui->topOSK->currentIndex() == 1
1269 emit SubmitNormalText(SwkbdResult::Cancel, 1268 ? ui->text_edit_osk->toPlainText().toStdU16String()
1270 ui->text_edit_osk->toPlainText().toStdU16String()); 1269 : ui->line_edit_osk->text().toStdU16String();
1271 } else { 1270
1272 emit SubmitNormalText(SwkbdResult::Cancel, 1271 emit SubmitNormalText(SwkbdResult::Cancel, std::move(text));
1273 ui->line_edit_osk->text().toStdU16String());
1274 }
1275 } 1272 }
1276 break; 1273 break;
1277 case HIDButton::Y: 1274 case HIDButton::Y:
@@ -1563,7 +1560,7 @@ void QtSoftwareKeyboard::ShowNormalKeyboard() const {
1563void QtSoftwareKeyboard::ShowTextCheckDialog( 1560void QtSoftwareKeyboard::ShowTextCheckDialog(
1564 Service::AM::Applets::SwkbdTextCheckResult text_check_result, 1561 Service::AM::Applets::SwkbdTextCheckResult text_check_result,
1565 std::u16string text_check_message) const { 1562 std::u16string text_check_message) const {
1566 emit MainWindowShowTextCheckDialog(text_check_result, text_check_message); 1563 emit MainWindowShowTextCheckDialog(text_check_result, std::move(text_check_message));
1567} 1564}
1568 1565
1569void QtSoftwareKeyboard::ShowInlineKeyboard( 1566void QtSoftwareKeyboard::ShowInlineKeyboard(