Created
February 25, 2018 13:53
-
-
Save Subv/036b7d4a9885d78fcd6ba5b5cf8b4108 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp | |
index 164c5bb6..3965dee5 100644 | |
--- a/src/core/hle/service/apt/apt.cpp | |
+++ b/src/core/hle/service/apt/apt.cpp | |
@@ -79,8 +79,18 @@ struct AppletSlotData { | |
AppletAttributes attributes; | |
Kernel::SharedPtr<Kernel::Event> notification_event; | |
Kernel::SharedPtr<Kernel::Event> parameter_event; | |
+ | |
+ void Reset() { | |
+ applet_id = AppletId::None; | |
+ registered = false; | |
+ attributes.raw = 0; | |
+ } | |
}; | |
+/// The parameter signal to send to an application when a running library applet calls | |
+/// CloseLibraryApplet. | |
+SignalType library_applet_closing_command = SignalType::None; | |
+ | |
// Holds data about the concurrently running applets in the system. | |
static std::array<AppletSlotData, NumAppletSlot> applet_slots = {}; | |
@@ -737,8 +747,9 @@ void CancelParameter(Service::Interface* self) { | |
rb.Push(RESULT_SUCCESS); // No error | |
rb.Push(cancellation_success); | |
- LOG_DEBUG(Service_APT, "called check_sender=%u, sender_appid=0x%08X, " | |
- "check_receiver=%u, receiver_appid=0x%08X", | |
+ LOG_DEBUG(Service_APT, | |
+ "called check_sender=%u, sender_appid=0x%08X, " | |
+ "check_receiver=%u, receiver_appid=0x%08X", | |
check_sender, sender_appid, check_receiver, receiver_appid); | |
} | |
@@ -954,6 +965,67 @@ void StartLibraryApplet(Service::Interface* self) { | |
} | |
} | |
+void PrepareToCloseLibraryApplet(Service::Interface* self) { | |
+ IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x25, 3, 0); // 0x002500C0 | |
+ bool not_pause = rp.Pop<bool>(); | |
+ bool exiting = rp.Pop<bool>(); | |
+ bool jump_to_home = rp.Pop<bool>(); | |
+ | |
+ LOG_DEBUG(Service_APT, "called not_pause=%u exiting=%u jump_to_home=%u", | |
+ static_cast<u32>(not_pause), static_cast<u32>(exiting), | |
+ static_cast<u32>(jump_to_home)); | |
+ | |
+ if (next_parameter) { | |
+ IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | |
+ rb.Push(ResultCode(ErrCodes::ParameterPresent, ErrorModule::Applet, | |
+ ErrorSummary::InvalidState, ErrorLevel::Status)); | |
+ return; | |
+ } | |
+ | |
+ if (!not_pause) | |
+ library_applet_closing_command = SignalType::WakeupByPause; | |
+ else if (jump_to_home) | |
+ library_applet_closing_command = SignalType::WakeupToJumpHome; | |
+ else if (exiting) | |
+ library_applet_closing_command = SignalType::WakeupByCancel; | |
+ else | |
+ library_applet_closing_command = SignalType::WakeupByExit; | |
+ | |
+ IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | |
+ rb.Push(RESULT_SUCCESS); | |
+} | |
+ | |
+void CloseLibraryApplet(Service::Interface* self) { | |
+ IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x28, 1, 4); // 0x00280044 | |
+ u32 parameter_size = rp.Pop<u32>(); | |
+ Kernel::Handle handle = rp.PopHandle(); | |
+ VAddr parameter_addr = rp.PopStaticBuffer(nullptr); | |
+ | |
+ LOG_DEBUG(Service_APT, "called size=%u handle=%u", parameter_size, static_cast<u32>(handle)); | |
+ | |
+ auto& slot = applet_slots[static_cast<size_t>(AppletSlot::LibraryApplet)]; | |
+ | |
+ MessageParameter param; | |
+ // TODO(Subv): The destination id should be the "current applet slot id", which changes | |
+ // constantly depending on what is going on in the system. Most of the time it is the running | |
+ // application, but it could be something else if a system applet is launched. | |
+ param.destination_id = static_cast<u32>(AppletId::Application); | |
+ param.sender_id = static_cast<u32>(slot.applet_id); | |
+ param.object = Kernel::g_handle_table.GetGeneric(handle); | |
+ param.signal = static_cast<u32>(library_applet_closing_command); | |
+ param.buffer.resize(parameter_size); | |
+ Memory::ReadBlock(parameter_addr, param.buffer.data(), param.buffer.size()); | |
+ SendParameter(param); | |
+ | |
+ if (library_applet_closing_command != SignalType::WakeupByPause) { | |
+ // TODO(Subv): Terminate the running applet title | |
+ slot.Reset(); | |
+ } | |
+ | |
+ IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | |
+ rb.Push(RESULT_SUCCESS); | |
+} | |
+ | |
void CancelLibraryApplet(Service::Interface* self) { | |
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x3B, 1, 0); // 0x003B0040 | |
bool exiting = rp.Pop<bool>(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment