mirror of
https://github.com/XorTroll/uLaunch
synced 2024-11-22 11:53:06 +00:00
Some cleanup, small fixes, ECS working fine now
This commit is contained in:
parent
f086264fb5
commit
aa492d8fe3
36 changed files with 697 additions and 697 deletions
|
@ -1,4 +1,4 @@
|
|||
<img width="200" src="LibraryAppletQMenu/RomFs/LogoLarge.png">
|
||||
<img width="200" src="LibraryAppletDaemon/RomFs/LogoLarge.png">
|
||||
|
||||
> Custom, open-source replacement/reimplementation for Nintendo Switch's HOME menu (qlaunch), extending it with amazing, homebrew-oriented functionality!
|
||||
|
||||
|
|
2
TODO.md
2
TODO.md
|
@ -1,6 +1,6 @@
|
|||
# uLaunch's TODO list
|
||||
|
||||
- Improve QDaemons's IPC with two services, one only for QMenu and the other one for any process to interact with uLaunch:
|
||||
- Improve Daemons's IPC with two services, one only for Daemon and the other one for any process to interact with uLaunch:
|
||||
|
||||
- Easy way to detect whether uLaunch is present
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e5c501e5b66fbeeb57cbc03856582ad470084aca
|
||||
Subproject commit b83ddf8157e7aef37159aaff9e0b40b137339504
|
|
@ -2,57 +2,15 @@
|
|||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
#include <ul_Include.hpp>
|
||||
#include <am/am_Application.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace ecs
|
||||
{
|
||||
NX_CONSTEXPR AppletId DetectAppletIdByProgramId(u64 program_id)
|
||||
{
|
||||
switch(program_id)
|
||||
{
|
||||
case 0x0100000000001001:
|
||||
return AppletId_auth;
|
||||
case 0x0100000000001002:
|
||||
return AppletId_cabinet;
|
||||
case 0x0100000000001003:
|
||||
return AppletId_controller;
|
||||
case 0x0100000000001004:
|
||||
return AppletId_dataErase;
|
||||
case 0x0100000000001005:
|
||||
return AppletId_error;
|
||||
case 0x0100000000001006:
|
||||
return AppletId_netConnect;
|
||||
case 0x0100000000001007:
|
||||
return AppletId_playerSelect;
|
||||
case 0x0100000000001008:
|
||||
return AppletId_swkbd;
|
||||
case 0x0100000000001009:
|
||||
return AppletId_miiEdit;
|
||||
case 0x010000000000100A:
|
||||
return AppletId_web;
|
||||
case 0x010000000000100B:
|
||||
return AppletId_shop;
|
||||
case 0x010000000000100D:
|
||||
return AppletId_photoViewer;
|
||||
case 0x010000000000100E:
|
||||
return AppletId_set;
|
||||
case 0x010000000000100F:
|
||||
return AppletId_offlineWeb;
|
||||
case 0x0100000000001010:
|
||||
return AppletId_loginShare;
|
||||
case 0x0100000000001011:
|
||||
return AppletId_wifiWebAuth;
|
||||
case 0x0100000000001013:
|
||||
return AppletId_myPage;
|
||||
}
|
||||
return (AppletId)0;
|
||||
}
|
||||
|
||||
Result Initialize();
|
||||
void Exit();
|
||||
Result RegisterExternalContent(u64 program_id, std::string exefs_path);
|
||||
Result LaunchApplet(u64 program_id, u32 la_version, void *args, size_t args_size);
|
||||
Result LaunchApplication(u64 program_id, void *args, size_t args_size, AccountUid uid);
|
||||
Result LaunchSystemProcess(u64 program_id, std::string argv_str);
|
||||
|
||||
inline Result RegisterLaunchAsApplet(u64 program_id, u32 la_version, std::string exefs_path, void *args, size_t args_size)
|
||||
|
@ -65,7 +23,7 @@ namespace ecs
|
|||
inline Result RegisterLaunchAsApplication(u64 program_id, std::string exefs_path, void *args, size_t args_size, AccountUid uid)
|
||||
{
|
||||
auto rc = RegisterExternalContent(program_id, exefs_path);
|
||||
if(R_SUCCEEDED(rc)) rc = LaunchApplication(program_id, args, args_size, uid);
|
||||
if(R_SUCCEEDED(rc)) rc = am::ApplicationStart(program_id, false, uid, args, args_size);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,13 +9,14 @@
|
|||
#include <am/am_Application.hpp>
|
||||
#include <am/am_LibraryApplet.hpp>
|
||||
#include <am/am_HomeMenu.hpp>
|
||||
#include <am/am_QCommunications.hpp>
|
||||
#include <am/am_DaemonMenuInteraction.hpp>
|
||||
#include <util/util_Convert.hpp>
|
||||
#include <cfg/cfg_Config.hpp>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
u32 __nx_applet_type = AppletType_SystemApplet;
|
||||
TimeServiceType __nx_time_service_type = TimeServiceType_System;
|
||||
#if UL_DEV
|
||||
size_t __nx_heap_size = 0x3000000; // Dev builds use 48MB (still lower than official qlaunch) for debug console
|
||||
#else
|
||||
|
@ -35,11 +36,12 @@ namespace ams
|
|||
|
||||
AccountUid selected_uid = {};
|
||||
hb::HbTargetParams hblaunch_flag = {};
|
||||
hb::HbTargetParams hbapplaunch_copy = {};
|
||||
hb::HbTargetParams hbapplaunch_flag = {};
|
||||
hb::HbTargetParams hbapplaunch_flag_temp = {};
|
||||
u64 titlelaunch_flag = 0;
|
||||
WebCommonConfig webapplet_flag = {};
|
||||
bool album_flag = false;
|
||||
bool app_opened_hb = false;
|
||||
u8 *usbbuf = nullptr;
|
||||
cfg::Config config = {};
|
||||
Thread ipc_thr;
|
||||
|
@ -49,22 +51,22 @@ Thread usb_thr;
|
|||
bool debug_menu = false;
|
||||
|
||||
ams::os::Mutex latestqlock;
|
||||
am::QMenuMessage latestqmenumsg = am::QMenuMessage::Invalid;
|
||||
am::MenuMessage latestqmenumsg = am::MenuMessage::Invalid;
|
||||
|
||||
am::QDaemonStatus CreateStatus()
|
||||
am::DaemonStatus CreateStatus()
|
||||
{
|
||||
am::QDaemonStatus status = {};
|
||||
am::DaemonStatus status = {};
|
||||
memcpy(&status.selected_user, &selected_uid, sizeof(selected_uid));
|
||||
|
||||
cfg::TitleType tmptype = cfg::TitleType::Invalid;
|
||||
if(am::ApplicationIsActive())
|
||||
{
|
||||
tmptype = cfg::TitleType::Installed;
|
||||
if(os::IsFlogTitle(am::ApplicationGetId())) tmptype = cfg::TitleType::Homebrew;
|
||||
if(app_opened_hb) tmptype = cfg::TitleType::Homebrew;
|
||||
}
|
||||
|
||||
if(tmptype == cfg::TitleType::Installed) status.app_id = am::ApplicationGetId();
|
||||
else if(tmptype == cfg::TitleType::Homebrew) status.params = hbapplaunch_copy;
|
||||
else if(tmptype == cfg::TitleType::Homebrew) memcpy(&status.params, &hbapplaunch_flag_temp, sizeof(hbapplaunch_flag_temp));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -74,20 +76,20 @@ void HandleSleep()
|
|||
appletStartSleepSequence(true);
|
||||
}
|
||||
|
||||
Result LaunchMenu(am::QMenuStartMode stmode, am::QDaemonStatus status)
|
||||
Result LaunchMenu(am::MenuStartMode stmode, am::DaemonStatus status)
|
||||
{
|
||||
if(debug_menu) return 0;
|
||||
return ecs::RegisterLaunchAsApplet(0x010000000000100B, (u32)stmode, "/ulaunch/bin/uMenu/", &status, sizeof(status));
|
||||
return ecs::RegisterLaunchAsApplet(config.menu_program_id, (u32)stmode, "/ulaunch/bin/uMenu/", &status, sizeof(status));
|
||||
}
|
||||
|
||||
void HandleHomeButton()
|
||||
{
|
||||
bool used_to_reopen_menu = false;
|
||||
if(am::LibraryAppletIsActive() && !am::LibraryAppletIsQMenu())
|
||||
if(am::LibraryAppletIsActive() && !am::LibraryAppletIsMenu())
|
||||
{
|
||||
am::LibraryAppletTerminate();
|
||||
auto status = CreateStatus();
|
||||
UL_R_TRY(LaunchMenu(am::QMenuStartMode::Menu, status));
|
||||
UL_R_TRY(LaunchMenu(am::MenuStartMode::Menu, status));
|
||||
return;
|
||||
}
|
||||
if(am::ApplicationIsActive())
|
||||
|
@ -96,14 +98,14 @@ void HandleHomeButton()
|
|||
{
|
||||
am::HomeMenuSetForeground();
|
||||
auto status = CreateStatus();
|
||||
UL_R_TRY(LaunchMenu(am::QMenuStartMode::MenuApplicationSuspended, status));
|
||||
UL_R_TRY(LaunchMenu(am::MenuStartMode::MenuApplicationSuspended, status));
|
||||
used_to_reopen_menu = true;
|
||||
}
|
||||
}
|
||||
if(am::LibraryAppletIsQMenu() && !used_to_reopen_menu)
|
||||
if(am::LibraryAppletIsMenu() && !used_to_reopen_menu)
|
||||
{
|
||||
std::scoped_lock _lock(latestqlock);
|
||||
latestqmenumsg = am::QMenuMessage::HomeRequest;
|
||||
latestqmenumsg = am::MenuMessage::HomeRequest;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,162 +187,165 @@ void HandleAppletMessage()
|
|||
|
||||
void HandleMenuMessage()
|
||||
{
|
||||
if(am::LibraryAppletIsQMenu())
|
||||
if(am::LibraryAppletIsMenu())
|
||||
{
|
||||
am::QDaemonCommandReader reader;
|
||||
am::DaemonCommandReader reader;
|
||||
if(reader)
|
||||
{
|
||||
switch(reader.GetMessage())
|
||||
{
|
||||
case am::QDaemonMessage::SetSelectedUser:
|
||||
case am::DaemonMessage::SetSelectedUser:
|
||||
{
|
||||
selected_uid = reader.Read<AccountUid>();
|
||||
reader.FinishRead();
|
||||
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::LaunchApplication:
|
||||
case am::DaemonMessage::LaunchApplication:
|
||||
{
|
||||
auto app_id = reader.Read<u64>();
|
||||
reader.FinishRead();
|
||||
|
||||
if(am::ApplicationIsActive())
|
||||
{
|
||||
am::QDaemonCommandResultWriter res(RES_VALUE(QDaemon, ApplicationActive));
|
||||
am::DaemonCommandResultWriter res(RES_VALUE(Daemon, ApplicationActive));
|
||||
res.FinishWrite();
|
||||
}
|
||||
else if(!accountUidIsValid(&selected_uid))
|
||||
{
|
||||
am::QDaemonCommandResultWriter res(RES_VALUE(QDaemon, InvalidSelectedUser));
|
||||
am::DaemonCommandResultWriter res(RES_VALUE(Daemon, InvalidSelectedUser));
|
||||
res.FinishWrite();
|
||||
}
|
||||
else if(titlelaunch_flag > 0)
|
||||
{
|
||||
am::QDaemonCommandResultWriter res(RES_VALUE(QDaemon, AlreadyQueued));
|
||||
am::DaemonCommandResultWriter res(RES_VALUE(Daemon, AlreadyQueued));
|
||||
res.FinishWrite();
|
||||
}
|
||||
else
|
||||
{
|
||||
titlelaunch_flag = app_id;
|
||||
am::QDaemonCommandResultWriter res(0);
|
||||
am::DaemonCommandResultWriter res(0);
|
||||
res.FinishWrite();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::ResumeApplication:
|
||||
case am::DaemonMessage::ResumeApplication:
|
||||
{
|
||||
reader.FinishRead();
|
||||
|
||||
if(!am::ApplicationIsActive())
|
||||
{
|
||||
am::QDaemonCommandResultWriter res(RES_VALUE(QDaemon, ApplicationNotActive));
|
||||
am::DaemonCommandResultWriter res(RES_VALUE(Daemon, ApplicationNotActive));
|
||||
res.FinishWrite();
|
||||
}
|
||||
else
|
||||
{
|
||||
am::ApplicationSetForeground();
|
||||
am::QDaemonCommandResultWriter res(0);
|
||||
am::DaemonCommandResultWriter res(0);
|
||||
res.FinishWrite();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::TerminateApplication:
|
||||
case am::DaemonMessage::TerminateApplication:
|
||||
{
|
||||
reader.FinishRead();
|
||||
|
||||
am::ApplicationTerminate();
|
||||
app_opened_hb = false;
|
||||
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::LaunchHomebrewLibApplet:
|
||||
case am::DaemonMessage::LaunchHomebrewLibraryApplet:
|
||||
{
|
||||
hblaunch_flag = reader.Read<hb::HbTargetParams>();
|
||||
reader.FinishRead();
|
||||
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::LaunchHomebrewApplication:
|
||||
case am::DaemonMessage::LaunchHomebrewApplication:
|
||||
{
|
||||
auto app_id = reader.Read<u64>();
|
||||
auto ipt = reader.Read<hb::HbTargetParams>();
|
||||
reader.FinishRead();
|
||||
|
||||
if(am::ApplicationIsActive())
|
||||
{
|
||||
am::QDaemonCommandResultWriter res(RES_VALUE(QDaemon, ApplicationActive));
|
||||
am::DaemonCommandResultWriter res(RES_VALUE(Daemon, ApplicationActive));
|
||||
res.FinishWrite();
|
||||
}
|
||||
else if(!accountUidIsValid(&selected_uid))
|
||||
{
|
||||
am::QDaemonCommandResultWriter res(RES_VALUE(QDaemon, InvalidSelectedUser));
|
||||
am::DaemonCommandResultWriter res(RES_VALUE(Daemon, InvalidSelectedUser));
|
||||
res.FinishWrite();
|
||||
}
|
||||
else if(titlelaunch_flag > 0)
|
||||
{
|
||||
am::QDaemonCommandResultWriter res(RES_VALUE(QDaemon, AlreadyQueued));
|
||||
am::DaemonCommandResultWriter res(RES_VALUE(Daemon, AlreadyQueued));
|
||||
res.FinishWrite();
|
||||
}
|
||||
else
|
||||
{
|
||||
hbapplaunch_copy = ipt;
|
||||
hbapplaunch_flag = hbapplaunch_copy;
|
||||
am::QDaemonCommandResultWriter res(0);
|
||||
memcpy(&hbapplaunch_flag, &ipt, sizeof(ipt));
|
||||
memcpy(&hbapplaunch_flag_temp, &ipt, sizeof(ipt));
|
||||
titlelaunch_flag = app_id;
|
||||
am::DaemonCommandResultWriter res(0);
|
||||
res.FinishWrite();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::OpenWebPage:
|
||||
case am::DaemonMessage::OpenWebPage:
|
||||
{
|
||||
webapplet_flag = reader.Read<WebCommonConfig>();
|
||||
reader.FinishRead();
|
||||
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::GetSelectedUser:
|
||||
case am::DaemonMessage::GetSelectedUser:
|
||||
{
|
||||
reader.FinishRead();
|
||||
|
||||
am::QDaemonCommandResultWriter res(0);
|
||||
am::DaemonCommandResultWriter res(0);
|
||||
res.Write<AccountUid>(selected_uid);
|
||||
res.FinishWrite();
|
||||
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::UserHasPassword:
|
||||
case am::DaemonMessage::UserHasPassword:
|
||||
{
|
||||
auto uid = reader.Read<AccountUid>();
|
||||
reader.FinishRead();
|
||||
|
||||
auto [rc, pass] = db::AccessPassword(uid);
|
||||
|
||||
am::QDaemonCommandResultWriter res(rc);
|
||||
am::DaemonCommandResultWriter res(rc);
|
||||
res.FinishWrite();
|
||||
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::TryLogUser:
|
||||
case am::DaemonMessage::TryLogUser:
|
||||
{
|
||||
auto pass = reader.Read<db::PassBlock>();
|
||||
reader.FinishRead();
|
||||
|
||||
auto rc = db::TryLogUser(pass);
|
||||
|
||||
am::QDaemonCommandResultWriter res(rc);
|
||||
am::DaemonCommandResultWriter res(rc);
|
||||
res.FinishWrite();
|
||||
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::RegisterUserPassword:
|
||||
case am::DaemonMessage::RegisterUserPassword:
|
||||
{
|
||||
auto pass = reader.Read<db::PassBlock>();
|
||||
reader.FinishRead();
|
||||
|
||||
auto rc = db::RegisterUserPassword(pass);
|
||||
|
||||
am::QDaemonCommandResultWriter res(rc);
|
||||
am::DaemonCommandResultWriter res(rc);
|
||||
res.FinishWrite();
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::ChangeUserPassword:
|
||||
case am::DaemonMessage::ChangeUserPassword:
|
||||
{
|
||||
auto pass = reader.Read<db::PassBlock>();
|
||||
auto newpass = reader.Read<db::PassBlock>();
|
||||
|
@ -353,12 +358,12 @@ void HandleMenuMessage()
|
|||
if(R_SUCCEEDED(rc)) rc = db::RegisterUserPassword(newpass);
|
||||
}
|
||||
|
||||
am::QDaemonCommandResultWriter res(rc);
|
||||
am::DaemonCommandResultWriter res(rc);
|
||||
res.FinishWrite();
|
||||
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::RemoveUserPassword:
|
||||
case am::DaemonMessage::RemoveUserPassword:
|
||||
{
|
||||
auto pass = reader.Read<db::PassBlock>();
|
||||
reader.FinishRead();
|
||||
|
@ -369,12 +374,12 @@ void HandleMenuMessage()
|
|||
rc = db::RemoveUserPassword(pass.uid);
|
||||
}
|
||||
|
||||
am::QDaemonCommandResultWriter res(rc);
|
||||
am::DaemonCommandResultWriter res(rc);
|
||||
res.FinishWrite();
|
||||
|
||||
break;
|
||||
}
|
||||
case am::QDaemonMessage::OpenAlbum:
|
||||
case am::DaemonMessage::OpenAlbum:
|
||||
{
|
||||
reader.FinishRead();
|
||||
album_flag = true;
|
||||
|
@ -400,15 +405,15 @@ namespace
|
|||
constexpr size_t MaxServers = 2;
|
||||
constexpr size_t MaxSessions = 2;
|
||||
|
||||
constexpr ams::sm::ServiceName PrivateServiceName = ams::sm::ServiceName::Encode(AM_QDAEMON_SERVICE_NAME);
|
||||
constexpr ams::sm::ServiceName PrivateServiceName = ams::sm::ServiceName::Encode(AM_DAEMON_PRIVATE_SERVICE_NAME);
|
||||
ams::sf::hipc::ServerManager<MaxServers, ServerOptions, MaxSessions> private_service_manager;
|
||||
}
|
||||
|
||||
namespace qdaemon
|
||||
namespace daemn
|
||||
{
|
||||
void IPCManagerThread(void *arg)
|
||||
{
|
||||
private_service_manager.RegisterServer<ipc::IDaemonService>(PrivateServiceName, MaxSessions);
|
||||
UL_R_TRY(private_service_manager.RegisterServer<ipc::IDaemonService>(PrivateServiceName, MaxSessions).GetValue());
|
||||
private_service_manager.LoopProcess();
|
||||
}
|
||||
|
||||
|
@ -435,7 +440,7 @@ namespace qdaemon
|
|||
{
|
||||
if(!am::LibraryAppletIsActive())
|
||||
{
|
||||
am::WebAppletStart(&webapplet_flag);
|
||||
UL_R_TRY(am::WebAppletStart(&webapplet_flag));
|
||||
|
||||
sth_done = true;
|
||||
memset(&webapplet_flag, 0, sizeof(webapplet_flag));
|
||||
|
@ -446,7 +451,7 @@ namespace qdaemon
|
|||
if(!am::LibraryAppletIsActive())
|
||||
{
|
||||
u8 albumflag = 2;
|
||||
am::LibraryAppletStart(AppletId_photoViewer, 0x10000, &albumflag, sizeof(albumflag));
|
||||
UL_R_TRY(am::LibraryAppletStart(AppletId_photoViewer, 0x10000, &albumflag, sizeof(albumflag)));
|
||||
|
||||
sth_done = true;
|
||||
album_flag = false;
|
||||
|
@ -456,18 +461,21 @@ namespace qdaemon
|
|||
{
|
||||
if(!am::LibraryAppletIsActive())
|
||||
{
|
||||
am::ApplicationStart(titlelaunch_flag, false, selected_uid);
|
||||
sth_done = true;
|
||||
titlelaunch_flag = 0;
|
||||
}
|
||||
}
|
||||
if(strlen(hbapplaunch_flag.nro_path))
|
||||
{
|
||||
if(!am::LibraryAppletIsActive())
|
||||
{
|
||||
am::ApplicationStart(OS_FLOG_APP_ID, true, selected_uid, &hbapplaunch_flag, sizeof(hbapplaunch_flag));
|
||||
sth_done = true;
|
||||
hbapplaunch_flag.nro_path[0] = '\0';
|
||||
if(strlen(hbapplaunch_flag.nro_path))
|
||||
{
|
||||
auto params = hb::HbTargetParams::Create(hbapplaunch_flag.nro_path, hbapplaunch_flag.nro_argv, false);
|
||||
UL_R_TRY(ecs::RegisterLaunchAsApplication(titlelaunch_flag, "/ulaunch/bin/uHbTarget/app/", ¶ms, sizeof(params), selected_uid));
|
||||
sth_done = true;
|
||||
app_opened_hb = true;
|
||||
titlelaunch_flag = 0;
|
||||
hbapplaunch_flag.nro_path[0] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
UL_R_TRY(am::ApplicationStart(titlelaunch_flag, false, selected_uid));
|
||||
sth_done = true;
|
||||
titlelaunch_flag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(strlen(hblaunch_flag.nro_path))
|
||||
|
@ -475,36 +483,29 @@ namespace qdaemon
|
|||
if(!am::LibraryAppletIsActive())
|
||||
{
|
||||
auto params = hb::HbTargetParams::Create(hblaunch_flag.nro_path, hblaunch_flag.nro_argv, false);
|
||||
auto rc = ecs::RegisterLaunchAsApplet(0x0100000000001003, 0, "/ulaunch/bin/uHbTarget/applet/", ¶ms, sizeof(params));
|
||||
UL_R_TRY(ecs::RegisterLaunchAsApplet(config.homebrew_applet_program_id, 0, "/ulaunch/bin/uHbTarget/applet/", ¶ms, sizeof(params)));
|
||||
sth_done = true;
|
||||
hblaunch_flag.nro_path[0] = '\0';
|
||||
}
|
||||
}
|
||||
if(!am::LibraryAppletIsActive())
|
||||
{
|
||||
switch(am::LibraryAppletGetId())
|
||||
auto cur_id = am::LibraryAppletGetId();
|
||||
if((cur_id == AppletId_web) || (cur_id == AppletId_photoViewer) || (cur_id == config.homebrew_applet_program_id))
|
||||
{
|
||||
case am::QHbTargetAppletId:
|
||||
case AppletId_web:
|
||||
case AppletId_photoViewer:
|
||||
{
|
||||
auto status = CreateStatus();
|
||||
UL_R_TRY(LaunchMenu(am::QMenuStartMode::Menu, status));
|
||||
sth_done = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
auto status = CreateStatus();
|
||||
UL_R_TRY(LaunchMenu(am::MenuStartMode::Menu, status));
|
||||
sth_done = true;
|
||||
}
|
||||
}
|
||||
if(!sth_done && !debug_menu)
|
||||
{
|
||||
// If nothing was done, but nothing is active... An application or applet might have crashed, terminated, failed to launch...
|
||||
// No matter what is it, we reopen QMenu in launch-error mode.
|
||||
// No matter what is it, we reopen Menu in launch-error mode.
|
||||
if(!am::ApplicationIsActive() && !am::LibraryAppletIsActive())
|
||||
{
|
||||
auto status = CreateStatus();
|
||||
UL_R_TRY(LaunchMenu(am::QMenuStartMode::MenuLaunchFailure, status));
|
||||
UL_R_TRY(LaunchMenu(am::MenuStartMode::MenuLaunchFailure, status));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -547,6 +548,7 @@ namespace qdaemon
|
|||
fs::CreateDirectory(UL_BASE_SD_DIR "/lang");
|
||||
|
||||
config = cfg::EnsureConfig();
|
||||
am::LibraryAppletSetMenuAppletId(am::LibraryAppletGetAppletIdForProgramId(config.menu_program_id));
|
||||
|
||||
if(config.viewer_usb_enabled)
|
||||
{
|
||||
|
@ -624,24 +626,24 @@ namespace qdaemon
|
|||
}
|
||||
}
|
||||
|
||||
// QDaemon handles basic qlaunch functionality and serves as a back-end for uLaunch, communicating with QMenu front-end when neccessary.
|
||||
// Daemon handles basic qlaunch functionality and serves as a back-end for uLaunch, communicating with Menu front-end when neccessary.
|
||||
int main()
|
||||
{
|
||||
qdaemon::Initialize();
|
||||
daemn::Initialize();
|
||||
|
||||
// Cache everything on startup
|
||||
cfg::CacheEverything();
|
||||
|
||||
auto status = CreateStatus();
|
||||
UL_R_TRY(LaunchMenu(am::QMenuStartMode::StartupScreen, status))
|
||||
UL_R_TRY(LaunchMenu(am::MenuStartMode::StartupScreen, status))
|
||||
|
||||
while(true)
|
||||
{
|
||||
qdaemon::LoopUpdate();
|
||||
daemn::LoopUpdate();
|
||||
svcSleepThread(10'000'000);
|
||||
}
|
||||
|
||||
qdaemon::Exit();
|
||||
daemn::Exit();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
#include <am/am_Application.hpp>
|
||||
#include <am/am_LibraryApplet.hpp>
|
||||
#include <am/am_HomeMenu.hpp>
|
||||
#include <am/am_QCommunications.hpp>
|
||||
#include <am/am_DaemonMenuInteraction.hpp>
|
||||
|
||||
namespace ecs
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ namespace ecs
|
|||
ams::sf::hipc::ServerManager<MaxServers, ServerOptions> manager_instance;
|
||||
}
|
||||
|
||||
static void ManagerLoopHandler(void *arg)
|
||||
static void ECSManagerThread(void *arg)
|
||||
{
|
||||
manager_instance.LoopProcess();
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ namespace ecs
|
|||
initialized = R_SUCCEEDED(rc);
|
||||
if(initialized)
|
||||
{
|
||||
R_TRY(threadCreate(&manager_process_thread, &ManagerLoopHandler, nullptr, nullptr, 0x8000, 0x2b, -2));
|
||||
R_TRY(threadCreate(&manager_process_thread, &ECSManagerThread, nullptr, nullptr, 0x8000, 0x2b, -2));
|
||||
R_TRY(threadStart(&manager_process_thread));
|
||||
}
|
||||
return rc;
|
||||
|
@ -87,15 +87,10 @@ namespace ecs
|
|||
Result LaunchApplet(u64 program_id, u32 la_version, void *args, size_t args_size)
|
||||
{
|
||||
Result rc = 0xdead;
|
||||
auto appletid = DetectAppletIdByProgramId(program_id);
|
||||
auto appletid = am::LibraryAppletGetAppletIdForProgramId(program_id);
|
||||
if(appletid != 0) rc = am::LibraryAppletStart(appletid, la_version, args, args_size);
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result LaunchApplication(u64 program_id, void *args, size_t args_size, AccountUid uid)
|
||||
{
|
||||
return am::ApplicationStart(program_id, false, uid, args, args_size);
|
||||
}
|
||||
|
||||
Result LaunchSystemProcess(u64 program_id, std::string argv_str)
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include <ipc/ipc_IDaemonService.hpp>
|
||||
#include <am/am_QCommunications.hpp>
|
||||
#include <am/am_DaemonMenuInteraction.hpp>
|
||||
|
||||
extern ams::os::Mutex latestqlock;
|
||||
extern am::QMenuMessage latestqmenumsg;
|
||||
extern am::DaemonMessage latestqmenumsg;
|
||||
|
||||
namespace ipc
|
||||
{
|
||||
|
@ -10,6 +10,6 @@ namespace ipc
|
|||
{
|
||||
std::scoped_lock _lock(latestqlock);
|
||||
msg.SetValue((u32)latestqmenumsg);
|
||||
latestqmenumsg = am::QMenuMessage::Invalid;
|
||||
latestqmenumsg = am::DaemonMessage::Invalid;
|
||||
}
|
||||
}
|
|
@ -17,11 +17,10 @@ namespace am
|
|||
static_assert(sizeof(ApplicationSelectedUserArgument) == 0x400, "ApplicationSelectedUserArgument must be 0x400!");
|
||||
|
||||
static constexpr u32 SelectedUserMagic = 0xC79497CA;
|
||||
static constexpr u64 QHbTargetSystemApplicationId = OS_FLOG_APP_ID;
|
||||
|
||||
bool ApplicationIsActive();
|
||||
void ApplicationTerminate();
|
||||
Result ApplicationStart(u64 app_id, bool system, AccountUid user_id, void *data = NULL, size_t size = 0);
|
||||
Result ApplicationStart(u64 app_id, bool system, AccountUid user_id, void *data = nullptr, size_t size = 0);
|
||||
bool ApplicationHasForeground();
|
||||
Result ApplicationSetForeground();
|
||||
Result ApplicationSend(void *data, size_t size, AppletLaunchParameterKind kind = AppletLaunchParameterKind_UserChannel);
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
#include <ul_Include.hpp>
|
||||
#include <hb/hb_Target.hpp>
|
||||
|
||||
#define AM_DAEMON_PRIVATE_SERVICE_NAME "qdmnsrv"
|
||||
#define AM_DAEMON_PUBLIC_SERVICE_NAME "ulaunch"
|
||||
|
||||
namespace am
|
||||
{
|
||||
enum class QMenuStartMode
|
||||
enum class MenuStartMode
|
||||
{
|
||||
Invalid,
|
||||
StartupScreen,
|
||||
|
@ -14,20 +17,20 @@ namespace am
|
|||
MenuLaunchFailure
|
||||
};
|
||||
|
||||
enum class QMenuMessage
|
||||
enum class MenuMessage
|
||||
{
|
||||
Invalid,
|
||||
HomeRequest
|
||||
};
|
||||
|
||||
enum class QDaemonMessage
|
||||
enum class DaemonMessage
|
||||
{
|
||||
Invalid,
|
||||
SetSelectedUser,
|
||||
LaunchApplication,
|
||||
ResumeApplication,
|
||||
TerminateApplication,
|
||||
LaunchHomebrewLibApplet,
|
||||
LaunchHomebrewLibraryApplet,
|
||||
LaunchHomebrewApplication,
|
||||
OpenWebPage,
|
||||
GetSelectedUser,
|
||||
|
@ -39,36 +42,29 @@ namespace am
|
|||
OpenAlbum,
|
||||
};
|
||||
|
||||
struct QDaemonStatus
|
||||
struct DaemonStatus
|
||||
{
|
||||
AccountUid selected_user;
|
||||
hb::HbTargetParams params; // Set if homebrew (via flog takeover) is suspended
|
||||
u64 app_id; // Set if any title (other than flog) is suspended
|
||||
};
|
||||
|
||||
#define AM_QDAEMON_SERVICE_NAME "qdmnsrv"
|
||||
ResultWith<MenuStartMode> Menu_ProcessInput();
|
||||
|
||||
Result QDaemon_LaunchQMenu(QMenuStartMode mode, QDaemonStatus status);
|
||||
// Result QDaemon_LaunchQHbTarget(hb::HbTargetParams input);
|
||||
Result Menu_InitializeDaemonService();
|
||||
ResultWith<MenuMessage> Menu_GetLatestMenuMessage();
|
||||
bool MenuIsHomePressed();
|
||||
void Menu_FinalizeDaemonService();
|
||||
|
||||
Result QLibraryAppletReadStorage(void *data, size_t size);
|
||||
Result QApplicationReadStorage(void *data, size_t size);
|
||||
ResultWith<QMenuStartMode> QMenu_ProcessInput();
|
||||
Result Daemon_MenuWriteImpl(void *data, size_t size, bool wait);
|
||||
Result Daemon_MenuReadImpl(void *data, size_t size, bool wait);
|
||||
|
||||
Result QMenu_InitializeDaemonService();
|
||||
ResultWith<QMenuMessage> QMenu_GetLatestQMenuMessage();
|
||||
bool QMenuIsHomePressed();
|
||||
void QMenu_FinalizeDaemonService();
|
||||
Result Menu_DaemonWriteImpl(void *data, size_t size, bool wait);
|
||||
Result Menu_DaemonReadImpl(void *data, size_t size, bool wait);
|
||||
|
||||
Result QDaemon_QMenuWriteImpl(void *data, size_t size, bool wait);
|
||||
Result QDaemon_QMenuReadImpl(void *data, size_t size, bool wait);
|
||||
typedef Result(*DMCommandRWFunction)(void*, size_t, bool);
|
||||
|
||||
Result QMenu_QDaemonWriteImpl(void *data, size_t size, bool wait);
|
||||
Result QMenu_QDaemonReadImpl(void *data, size_t size, bool wait);
|
||||
|
||||
typedef Result(*QCommandRWFunction)(void*, size_t, bool);
|
||||
|
||||
struct QCommandCommonHeader
|
||||
struct DMCommandCommonHeader
|
||||
{
|
||||
u32 magic;
|
||||
u32 val;
|
||||
|
@ -77,18 +73,18 @@ namespace am
|
|||
static constexpr u32 Magic = 0x434D4151;
|
||||
static constexpr size_t BlockSize = 0x4000;
|
||||
|
||||
template<QCommandRWFunction WriteFn>
|
||||
class QCommandWriter
|
||||
template<DMCommandRWFunction WriteFn>
|
||||
class DMCommandWriter
|
||||
{
|
||||
private:
|
||||
QCommandCommonHeader request;
|
||||
DMCommandCommonHeader request;
|
||||
u8 *data_block;
|
||||
size_t data_pos;
|
||||
Result inner_rc;
|
||||
bool write_done;
|
||||
|
||||
public:
|
||||
QCommandWriter(u32 value)
|
||||
DMCommandWriter(u32 value)
|
||||
{
|
||||
write_done = false;
|
||||
request.magic = Magic;
|
||||
|
@ -98,7 +94,7 @@ namespace am
|
|||
inner_rc = WriteFn(&request, sizeof(request), false);
|
||||
}
|
||||
|
||||
~QCommandWriter()
|
||||
~DMCommandWriter()
|
||||
{
|
||||
FinishWrite();
|
||||
}
|
||||
|
@ -131,11 +127,11 @@ namespace am
|
|||
}
|
||||
};
|
||||
|
||||
template<QCommandRWFunction ReadFn>
|
||||
class QCommandReader
|
||||
template<DMCommandRWFunction ReadFn>
|
||||
class DMCommandReader
|
||||
{
|
||||
private:
|
||||
QCommandCommonHeader response;
|
||||
DMCommandCommonHeader response;
|
||||
u8 *data_block;
|
||||
size_t data_pos;
|
||||
Result inner_rc;
|
||||
|
@ -143,17 +139,17 @@ namespace am
|
|||
bool fn_wait;
|
||||
|
||||
public:
|
||||
QCommandReader(bool wait = false)
|
||||
DMCommandReader(bool wait = false)
|
||||
{
|
||||
fn_wait = wait;
|
||||
read_done = false;
|
||||
data_pos = 0;
|
||||
data_block = new u8[BlockSize]();
|
||||
inner_rc = ReadFn(&response, sizeof(QCommandCommonHeader), fn_wait);
|
||||
inner_rc = ReadFn(&response, sizeof(DMCommandCommonHeader), fn_wait);
|
||||
if(R_SUCCEEDED(inner_rc)) inner_rc = ReadFn(data_block, BlockSize, fn_wait);
|
||||
}
|
||||
|
||||
~QCommandReader()
|
||||
~DMCommandReader()
|
||||
{
|
||||
FinishRead();
|
||||
}
|
||||
|
@ -191,27 +187,27 @@ namespace am
|
|||
}
|
||||
};
|
||||
|
||||
class QDaemonCommandReader : public QCommandReader<QDaemon_QMenuReadImpl>
|
||||
class DaemonCommandReader : public DMCommandReader<Daemon_MenuReadImpl>
|
||||
{
|
||||
public:
|
||||
QDaemonMessage GetMessage()
|
||||
DaemonMessage GetMessage()
|
||||
{
|
||||
return (QDaemonMessage)GetValue();
|
||||
return (DaemonMessage)GetValue();
|
||||
}
|
||||
};
|
||||
|
||||
class QDaemonCommandWriter : public QCommandWriter<QDaemon_QMenuWriteImpl>
|
||||
class DaemonCommandWriter : public DMCommandWriter<Daemon_MenuWriteImpl>
|
||||
{
|
||||
public:
|
||||
QDaemonCommandWriter(QMenuMessage msg) : QCommandWriter((u32)msg)
|
||||
DaemonCommandWriter(MenuMessage msg) : DMCommandWriter((u32)msg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class QDaemonCommandResultReader : public QCommandReader<QDaemon_QMenuReadImpl>
|
||||
class DaemonCommandResultReader : public DMCommandReader<Daemon_MenuReadImpl>
|
||||
{
|
||||
public:
|
||||
QDaemonCommandResultReader() : QCommandReader(true)
|
||||
DaemonCommandResultReader() : DMCommandReader(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -221,35 +217,35 @@ namespace am
|
|||
}
|
||||
};
|
||||
|
||||
class QDaemonCommandResultWriter : public QCommandWriter<QDaemon_QMenuWriteImpl>
|
||||
class DaemonCommandResultWriter : public DMCommandWriter<Daemon_MenuWriteImpl>
|
||||
{
|
||||
public:
|
||||
QDaemonCommandResultWriter(Result rc) : QCommandWriter(rc)
|
||||
DaemonCommandResultWriter(Result rc) : DMCommandWriter(rc)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class QMenuCommandReader : public QCommandReader<QMenu_QDaemonReadImpl>
|
||||
class MenuCommandReader : public DMCommandReader<Menu_DaemonReadImpl>
|
||||
{
|
||||
public:
|
||||
QMenuMessage GetMessage()
|
||||
MenuMessage GetMessage()
|
||||
{
|
||||
return (QMenuMessage)GetValue();
|
||||
return (MenuMessage)GetValue();
|
||||
}
|
||||
};
|
||||
|
||||
class QMenuCommandWriter : public QCommandWriter<QMenu_QDaemonWriteImpl>
|
||||
class MenuCommandWriter : public DMCommandWriter<Menu_DaemonWriteImpl>
|
||||
{
|
||||
public:
|
||||
QMenuCommandWriter(QDaemonMessage msg) : QCommandWriter((u32)msg)
|
||||
MenuCommandWriter(DaemonMessage msg) : DMCommandWriter((u32)msg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class QMenuCommandResultReader : public QCommandReader<QMenu_QDaemonReadImpl>
|
||||
class MenuCommandResultReader : public DMCommandReader<Menu_DaemonReadImpl>
|
||||
{
|
||||
public:
|
||||
QMenuCommandResultReader() : QCommandReader(true)
|
||||
MenuCommandResultReader() : DMCommandReader(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -259,10 +255,10 @@ namespace am
|
|||
}
|
||||
};
|
||||
|
||||
class QMenuCommandResultWriter : public QCommandWriter<QMenu_QDaemonWriteImpl>
|
||||
class MenuCommandResultWriter : public DMCommandWriter<Menu_DaemonWriteImpl>
|
||||
{
|
||||
public:
|
||||
QMenuCommandResultWriter(Result rc) : QCommandWriter(rc)
|
||||
MenuCommandResultWriter(Result rc) : DMCommandWriter(rc)
|
||||
{
|
||||
}
|
||||
};
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
#pragma once
|
||||
#include <ul_Include.hpp>
|
||||
#include <map>
|
||||
|
||||
namespace am
|
||||
{
|
||||
|
@ -33,29 +34,32 @@ namespace am
|
|||
}
|
||||
|
||||
bool LibraryAppletIsActive();
|
||||
bool LibraryAppletIsQMenu();
|
||||
void LibraryAppletSetMenuAppletId(AppletId id);
|
||||
bool LibraryAppletIsMenu();
|
||||
void LibraryAppletTerminate();
|
||||
Result LibraryAppletStart(AppletId id, u32 la_version, void *in_data, size_t in_size);
|
||||
Result LibraryAppletSend(void *data, size_t size);
|
||||
Result LibraryAppletRead(void *data, size_t size);
|
||||
Result WebAppletStart(WebCommonConfig *web);
|
||||
Result LibraryAppletQMenuLaunchWith(AppletId id, u32 la_version, std::function<void(AppletHolder*)> on_prepare, std::function<void(AppletHolder*)> on_finish, std::function<bool()> on_wait);
|
||||
Result LibraryAppletDaemonLaunchWith(AppletId id, u32 la_version, std::function<void(AppletHolder*)> on_prepare, std::function<void(AppletHolder*)> on_finish, std::function<bool()> on_wait);
|
||||
|
||||
inline Result LibraryAppletQMenuLaunchWithSimple(AppletId id, u32 la_version, void *in_data, size_t in_size, void *out_data, size_t out_size, std::function<bool()> on_wait)
|
||||
inline Result LibraryAppletDaemonLaunchWithSimple(AppletId id, u32 la_version, void *in_data, size_t in_size, void *out_data, size_t out_size, std::function<bool()> on_wait)
|
||||
{
|
||||
return LibraryAppletQMenuLaunchWith(id, la_version,
|
||||
return LibraryAppletDaemonLaunchWith(id, la_version,
|
||||
[&](AppletHolder *h)
|
||||
{
|
||||
if(in_size > 0) libappletPushInData(h, in_data, in_size);
|
||||
},
|
||||
[&](AppletHolder *h)
|
||||
{
|
||||
if(out_size > 0) libappletPopOutData(h, out_data, out_size, NULL);
|
||||
if(out_size > 0) libappletPopOutData(h, out_data, out_size, nullptr);
|
||||
}, on_wait);
|
||||
}
|
||||
|
||||
u64 LibraryAppletGetProgramIdForAppletId(AppletId id);
|
||||
AppletId LibraryAppletGetAppletIdForProgramId(u64 id);
|
||||
|
||||
AppletId LibraryAppletGetId();
|
||||
|
||||
static constexpr AppletId QMenuAppletId = AppletId_shop;
|
||||
static constexpr AppletId QHbTargetAppletId = AppletId_auth;
|
||||
static constexpr AppletId InvalidAppletId = (AppletId)0;
|
||||
}
|
|
@ -69,14 +69,25 @@ namespace cfg
|
|||
std::string icon_path;
|
||||
};
|
||||
|
||||
// Take over eShop by default
|
||||
static constexpr u64 DefaultMenuProgramId = 0x010000000000100B;
|
||||
|
||||
// Take over parental controls applet by default
|
||||
static constexpr u64 DefaultHomebrewAppletProgramId = 0x0100000000001001;
|
||||
|
||||
struct Config
|
||||
{
|
||||
std::string theme_name;
|
||||
bool system_title_override_enabled;
|
||||
bool viewer_usb_enabled;
|
||||
u64 menu_program_id;
|
||||
u64 homebrew_applet_program_id;
|
||||
u64 homebrew_title_application_id;
|
||||
|
||||
JSON main_lang;
|
||||
JSON default_lang;
|
||||
|
||||
Config() : system_title_override_enabled(false), viewer_usb_enabled(false), menu_program_id(DefaultMenuProgramId), homebrew_applet_program_id(DefaultHomebrewAppletProgramId), homebrew_title_application_id(0) {}
|
||||
};
|
||||
|
||||
static constexpr u32 CurrentThemeFormatVersion = 1;
|
||||
|
@ -86,35 +97,35 @@ namespace cfg
|
|||
#define CFG_CONFIG_JSON UL_BASE_SD_DIR "/config.json"
|
||||
|
||||
TitleList LoadTitleList();
|
||||
std::vector<TitleRecord> QueryAllHomebrew(std::string base = "sdmc:/switch");
|
||||
void CacheEverything(std::string hb_base_path = "sdmc:/switch");
|
||||
std::vector<TitleRecord> QueryAllHomebrew(const std::string &base = "sdmc:/switch");
|
||||
void CacheEverything(const std::string &hb_base_path = "sdmc:/switch");
|
||||
std::string GetRecordIconPath(TitleRecord record);
|
||||
RecordInformation GetRecordInformation(TitleRecord record);
|
||||
|
||||
Theme LoadTheme(std::string base_name);
|
||||
Theme LoadTheme(const std::string &base_name);
|
||||
std::vector<Theme> LoadThemes();
|
||||
std::string GetAssetByTheme(Theme &base, std::string resource_base);
|
||||
std::string GetAssetByTheme(const Theme &base, const std::string &resource_base);
|
||||
|
||||
inline bool ThemeIsDefault(Theme &base)
|
||||
inline bool ThemeIsDefault(const Theme &base)
|
||||
{
|
||||
return base.base_name.empty();
|
||||
}
|
||||
|
||||
std::string GetLanguageJSONPath(std::string lang);
|
||||
std::string GetLanguageString(JSON &lang, JSON &def, std::string name);
|
||||
std::string GetLanguageJSONPath(const std::string &lang);
|
||||
std::string GetLanguageString(const JSON &lang, const JSON &def, const std::string &name);
|
||||
|
||||
Config CreateNewAndLoadConfig();
|
||||
Config LoadConfig();
|
||||
Config EnsureConfig();
|
||||
void SaveConfig(Config &cfg);
|
||||
void SaveConfig(const Config &cfg);
|
||||
|
||||
void SaveRecord(TitleRecord &record);
|
||||
void RemoveRecord(TitleRecord &record);
|
||||
bool MoveRecordTo(TitleList &list, TitleRecord record, std::string folder);
|
||||
TitleFolder &FindFolderByName(TitleList &list, std::string name);
|
||||
void RenameFolder(TitleList &list, std::string old_name, std::string new_name);
|
||||
bool MoveRecordTo(TitleList &list, TitleRecord record, const std::string &folder);
|
||||
TitleFolder &FindFolderByName(TitleList &list, const std::string &name);
|
||||
void RenameFolder(TitleList &list, const std::string &old_name, const std::string &new_name);
|
||||
bool ExistsRecord(TitleList &list, TitleRecord record);
|
||||
|
||||
std::string GetTitleCacheIconPath(u64 app_id);
|
||||
std::string GetNROCacheIconPath(std::string path);
|
||||
std::string GetNROCacheIconPath(const std::string &path);
|
||||
}
|
|
@ -18,7 +18,7 @@ namespace db
|
|||
void Unmount();
|
||||
void Commit();
|
||||
|
||||
ResultWith<PassBlock> PackPassword(AccountUid uid, std::string pass);
|
||||
ResultWith<PassBlock> PackPassword(AccountUid uid, const std::string &pass);
|
||||
ResultWith<PassBlock> AccessPassword(AccountUid user_id);
|
||||
std::string GetUserPasswordFilePath(AccountUid user_id);
|
||||
Result RegisterUserPassword(PassBlock password);
|
||||
|
|
|
@ -4,17 +4,17 @@
|
|||
|
||||
namespace fs
|
||||
{
|
||||
bool ExistsFile(std::string path);
|
||||
bool ExistsDirectory(std::string path);
|
||||
bool ExistsFile(const std::string &path);
|
||||
bool ExistsDirectory(const std::string &path);
|
||||
|
||||
void CreateDirectory(std::string path);
|
||||
void CreateFile(std::string path);
|
||||
void CreateConcatenationFile(std::string path);
|
||||
void CreateDirectory(const std::string &path);
|
||||
void CreateFile(const std::string &path);
|
||||
void CreateConcatenationFile(const std::string &path);
|
||||
|
||||
void DeleteDirectory(std::string path);
|
||||
void DeleteFile(std::string path);
|
||||
void DeleteDirectory(const std::string &path);
|
||||
void DeleteFile(const std::string &path);
|
||||
|
||||
inline bool WriteFile(std::string path, void *data, size_t size, bool overwrite)
|
||||
inline bool WriteFile(const std::string &path, void *data, size_t size, bool overwrite)
|
||||
{
|
||||
FILE *f = fopen(path.c_str(), overwrite ? "wb" : "ab+");
|
||||
if(f)
|
||||
|
@ -26,7 +26,7 @@ namespace fs
|
|||
return false;
|
||||
}
|
||||
|
||||
inline bool ReadFile(std::string path, void *data, size_t size)
|
||||
inline bool ReadFile(const std::string &path, void *data, size_t size)
|
||||
{
|
||||
FILE *f = fopen(path.c_str(), "rb");
|
||||
if(f)
|
||||
|
@ -38,7 +38,7 @@ namespace fs
|
|||
return false;
|
||||
}
|
||||
|
||||
inline size_t GetFileSize(std::string path)
|
||||
inline size_t GetFileSize(const std::string &path)
|
||||
{
|
||||
FILE *f = fopen(path.c_str(), "rb");
|
||||
if(f)
|
||||
|
@ -52,11 +52,11 @@ namespace fs
|
|||
return 0;
|
||||
}
|
||||
|
||||
void MoveFile(std::string p1, std::string p2);
|
||||
void CopyFile(std::string p, std::string np);
|
||||
void MoveFile(const std::string &p1, const std::string &p2);
|
||||
void CopyFile(const std::string &p, const std::string &np);
|
||||
|
||||
void MoveDirectory(std::string d, std::string nd);
|
||||
void CopyDirectory(std::string d, std::string nd);
|
||||
void MoveDirectory(const std::string &d, const std::string &nd);
|
||||
void CopyDirectory(const std::string &d, const std::string &nd);
|
||||
|
||||
#define FS_FOR(dir, name_var, path_var, ...) \
|
||||
DIR *dp = opendir(dir.c_str()); \
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace hb
|
|||
return argv;
|
||||
}
|
||||
|
||||
inline static HbTargetParams Create(std::string nro_path, std::string nro_argv, bool target_once)
|
||||
inline static HbTargetParams Create(const std::string &nro_path, const std::string &nro_argv, bool target_once)
|
||||
{
|
||||
HbTargetParams params = {};
|
||||
params.magic = UL_HB_HBTARGET_MAGIC_U32;
|
||||
|
|
|
@ -89,14 +89,4 @@ inline void Panic(std::string msg)
|
|||
// TODO: non-console panic...?
|
||||
}
|
||||
|
||||
inline void HandleECSMain()
|
||||
{
|
||||
u64 this_app_id = 0;
|
||||
svcGetInfo(&this_app_id, InfoType_ProgramId, CUR_PROCESS_HANDLE, 0);
|
||||
|
||||
ldrShellInitialize();
|
||||
serviceDispatchIn(ldrShellGetServiceSession(), 65001, this_app_id);
|
||||
ldrShellExit();
|
||||
}
|
||||
|
||||
#define UL_R_TRY(expr) { auto _tmp_rc = (expr); if(R_FAILED(_tmp_rc)) { fatalThrow(_tmp_rc); } }
|
||||
#define UL_R_TRY(expr) { auto _tmp_rc = (expr); if(R_FAILED(_tmp_rc)) { fatalThrow(_tmp_rc); } }
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace res
|
|||
RES_DEFINE(InvalidJSONFile, 1)
|
||||
RES_MODULE_END
|
||||
|
||||
RES_MODULE_BEGIN(QDaemon, 3)
|
||||
RES_MODULE_BEGIN(Daemon, 3)
|
||||
RES_DEFINE(ApplicationActive, 1)
|
||||
RES_DEFINE(InvalidSelectedUser, 2)
|
||||
RES_DEFINE(AlreadyQueued, 3)
|
||||
|
|
|
@ -5,7 +5,12 @@
|
|||
namespace util
|
||||
{
|
||||
std::string Format128NintendoStyle(AccountUid value);
|
||||
u64 Get64FromString(std::string val);
|
||||
|
||||
inline u64 Get64FromString(const std::string &val)
|
||||
{
|
||||
return strtoull(val.c_str(), nullptr, 16);
|
||||
}
|
||||
|
||||
std::string FormatApplicationId(u64 app_id);
|
||||
std::string FormatResultDisplay(Result rc);
|
||||
std::string FormatResultHex(Result rc);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
namespace util
|
||||
{
|
||||
ResultWith<JSON> LoadJSONFromFile(std::string path);
|
||||
ResultWith<JSON> LoadJSONFromFile(const std::string &path);
|
||||
std::string GetCurrentTime();
|
||||
u32 GetBatteryLevel();
|
||||
bool IsCharging();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
namespace util
|
||||
{
|
||||
inline bool StringEndsWith(std::string const &value, std::string const &ending)
|
||||
inline bool StringEndsWith(const std::string &value, const std::string &ending)
|
||||
{
|
||||
if(ending.size() > value.size()) return false;
|
||||
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
||||
|
|
91
uLaunch/source/am/am_DaemonMenuInteraction.cpp
Normal file
91
uLaunch/source/am/am_DaemonMenuInteraction.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
#include <am/am_DaemonMenuInteraction.hpp>
|
||||
#include <fs/fs_Stdio.hpp>
|
||||
#include <am/am_LibraryApplet.hpp>
|
||||
|
||||
namespace am
|
||||
{
|
||||
Service daemon_private_srv;
|
||||
|
||||
#define UL_AM_LOOP_TRY_WITH(...) { \
|
||||
Result rc = 0; \
|
||||
do \
|
||||
{ \
|
||||
__VA_ARGS__ \
|
||||
svcSleepThread(10'000'000); \
|
||||
} while(R_FAILED(rc)); \
|
||||
return rc; \
|
||||
}
|
||||
|
||||
#define UL_AM_WAIT_WITH(...) { \
|
||||
if(wait) { UL_AM_LOOP_TRY_WITH(__VA_ARGS__) } \
|
||||
else \
|
||||
{ \
|
||||
Result rc = 0; \
|
||||
__VA_ARGS__ \
|
||||
return rc; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define UL_AM_WAIT(expr) UL_AM_WAIT_WITH(rc = (expr);)
|
||||
|
||||
ResultWith<MenuStartMode> Menu_ProcessInput()
|
||||
{
|
||||
LibAppletArgs in_args;
|
||||
auto rc = Menu_DaemonReadImpl(&in_args, sizeof(LibAppletArgs), false);
|
||||
return MakeResultWith(rc, (MenuStartMode)in_args.LaVersion);
|
||||
}
|
||||
|
||||
Result Menu_InitializeDaemonService()
|
||||
{
|
||||
if(serviceIsActive(&daemon_private_srv)) return 0;
|
||||
return smGetService(&daemon_private_srv, AM_DAEMON_PRIVATE_SERVICE_NAME);
|
||||
}
|
||||
|
||||
ResultWith<MenuMessage> Menu_GetLatestMenuMessage()
|
||||
{
|
||||
u32 outmsg = 0;
|
||||
auto rc = serviceDispatchOut(&daemon_private_srv, 0, outmsg);
|
||||
return MakeResultWith(rc, (MenuMessage)outmsg);
|
||||
}
|
||||
|
||||
bool MenuIsHomePressed()
|
||||
{
|
||||
auto [rc, msg] = Menu_GetLatestMenuMessage();
|
||||
if(R_FAILED(rc)) return false;
|
||||
return (msg == MenuMessage::HomeRequest);
|
||||
}
|
||||
|
||||
void Menu_FinalizeDaemonService()
|
||||
{
|
||||
serviceClose(&daemon_private_srv);
|
||||
}
|
||||
|
||||
Result Daemon_MenuWriteImpl(void *data, size_t size, bool wait)
|
||||
UL_AM_WAIT(LibraryAppletSend(data, size))
|
||||
|
||||
Result Daemon_MenuReadImpl(void *data, size_t size, bool wait)
|
||||
UL_AM_WAIT(LibraryAppletRead(data, size))
|
||||
|
||||
Result Menu_DaemonWriteImpl(void *data, size_t size, bool wait)
|
||||
UL_AM_WAIT_WITH(
|
||||
AppletStorage st;
|
||||
rc = appletCreateStorage(&st, size);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
rc = appletStorageWrite(&st, 0, data, size);
|
||||
if(R_SUCCEEDED(rc)) rc = appletPushOutData(&st);
|
||||
appletStorageClose(&st);
|
||||
}
|
||||
)
|
||||
|
||||
Result Menu_DaemonReadImpl(void *data, size_t size, bool wait)
|
||||
UL_AM_WAIT_WITH(
|
||||
AppletStorage st;
|
||||
rc = appletPopInData(&st);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
rc = appletStorageRead(&st, 0, data, size);
|
||||
appletStorageClose(&st);
|
||||
}
|
||||
)
|
||||
}
|
|
@ -2,8 +2,30 @@
|
|||
|
||||
namespace am
|
||||
{
|
||||
AppletHolder applet_holder;
|
||||
AppletId applet_lastid;
|
||||
static AppletHolder applet_holder;
|
||||
static AppletId applet_menuid = InvalidAppletId;
|
||||
static AppletId applet_lastid = InvalidAppletId;
|
||||
|
||||
static std::map<u64, AppletId> applet_id_table =
|
||||
{
|
||||
{ 0x0100000000001001, AppletId_auth },
|
||||
{ 0x0100000000001002, AppletId_cabinet },
|
||||
{ 0x0100000000001003, AppletId_controller },
|
||||
{ 0x0100000000001004, AppletId_dataErase },
|
||||
{ 0x0100000000001005, AppletId_error },
|
||||
{ 0x0100000000001006, AppletId_netConnect },
|
||||
{ 0x0100000000001007, AppletId_playerSelect },
|
||||
{ 0x0100000000001008, AppletId_swkbd },
|
||||
{ 0x0100000000001009, AppletId_miiEdit },
|
||||
{ 0x010000000000100A, AppletId_web },
|
||||
{ 0x010000000000100B, AppletId_shop },
|
||||
{ 0x010000000000100D, AppletId_photoViewer },
|
||||
{ 0x010000000000100E, AppletId_set },
|
||||
{ 0x010000000000100F, AppletId_offlineWeb },
|
||||
{ 0x0100000000001010, AppletId_loginShare },
|
||||
{ 0x0100000000001011, AppletId_wifiWebAuth },
|
||||
{ 0x0100000000001013, AppletId_myPage }
|
||||
};
|
||||
|
||||
bool LibraryAppletIsActive()
|
||||
{
|
||||
|
@ -12,9 +34,14 @@ namespace am
|
|||
return !appletHolderCheckFinished(&applet_holder);
|
||||
}
|
||||
|
||||
bool LibraryAppletIsQMenu()
|
||||
void LibraryAppletSetMenuAppletId(AppletId id)
|
||||
{
|
||||
return (LibraryAppletIsActive() && (LibraryAppletGetId() == QMenuAppletId));
|
||||
applet_menuid = id;
|
||||
}
|
||||
|
||||
bool LibraryAppletIsMenu()
|
||||
{
|
||||
return (LibraryAppletIsActive() && (applet_menuid != InvalidAppletId) && (LibraryAppletGetId() == applet_menuid));
|
||||
}
|
||||
|
||||
void LibraryAppletTerminate()
|
||||
|
@ -55,7 +82,7 @@ namespace am
|
|||
return LibraryAppletStart(AppletId_web, web->version, &web->arg, sizeof(web->arg));
|
||||
}
|
||||
|
||||
Result LibraryAppletQMenuLaunchWith(AppletId id, u32 la_version, std::function<void(AppletHolder*)> on_prepare, std::function<void(AppletHolder*)> on_finish, std::function<bool()> on_wait)
|
||||
Result LibraryAppletDaemonLaunchWith(AppletId id, u32 la_version, std::function<void(AppletHolder*)> on_prepare, std::function<void(AppletHolder*)> on_finish, std::function<bool()> on_wait)
|
||||
{
|
||||
if(LibraryAppletIsActive()) LibraryAppletTerminate();
|
||||
appletHolderClose(&applet_holder);
|
||||
|
@ -73,17 +100,35 @@ namespace am
|
|||
LibraryAppletTerminate();
|
||||
break;
|
||||
}
|
||||
svcSleepThread(10'000'000);
|
||||
svcSleepThread(10'000'000l);
|
||||
}
|
||||
on_finish(&applet_holder);
|
||||
appletHolderClose(&applet_holder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 LibraryAppletGetProgramIdForAppletId(AppletId id)
|
||||
{
|
||||
for(auto &[program_id, applet_id] : applet_id_table)
|
||||
{
|
||||
if(applet_id == id) return program_id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
AppletId LibraryAppletGetAppletIdForProgramId(u64 id)
|
||||
{
|
||||
for(auto &[program_id, applet_id] : applet_id_table)
|
||||
{
|
||||
if(program_id == id) return applet_id;
|
||||
}
|
||||
return InvalidAppletId;
|
||||
}
|
||||
|
||||
AppletId LibraryAppletGetId()
|
||||
{
|
||||
auto idcopy = applet_lastid;
|
||||
if(!LibraryAppletIsActive()) applet_lastid = (AppletId)0; // Invalid
|
||||
if(!LibraryAppletIsActive()) applet_lastid = InvalidAppletId;
|
||||
return idcopy;
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
#include <am/am_QCommunications.hpp>
|
||||
#include <fs/fs_Stdio.hpp>
|
||||
#include <am/am_LibraryApplet.hpp>
|
||||
|
||||
namespace am
|
||||
{
|
||||
Service daemon_srv;
|
||||
|
||||
#define UL_AM_LOOP_TRY_WITH(...) { \
|
||||
Result rc = 0; \
|
||||
do \
|
||||
{ \
|
||||
__VA_ARGS__ \
|
||||
svcSleepThread(10'000'000); \
|
||||
} while(R_FAILED(rc)); \
|
||||
return rc; \
|
||||
}
|
||||
|
||||
#define UL_AM_WAIT_WITH(...) { \
|
||||
if(wait) { UL_AM_LOOP_TRY_WITH(__VA_ARGS__) } \
|
||||
else \
|
||||
{ \
|
||||
Result rc = 0; \
|
||||
__VA_ARGS__ \
|
||||
return rc; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define UL_AM_WAIT(expr) UL_AM_WAIT_WITH(rc = (expr);)
|
||||
|
||||
Result QDaemon_LaunchQMenu(QMenuStartMode mode, QDaemonStatus status)
|
||||
{
|
||||
return LibraryAppletStart(QMenuAppletId, (u32)mode, &status, sizeof(status));
|
||||
}
|
||||
|
||||
/*
|
||||
Result QDaemon_LaunchQHbTarget(hb::HbTargetParams input)
|
||||
{
|
||||
return LibraryAppletStart(QHbTargetAppletId, (u32)am::Magic, &input, sizeof(input));
|
||||
}
|
||||
*/
|
||||
|
||||
Result QLibraryAppletReadStorage(void *data, size_t size)
|
||||
{
|
||||
return QMenu_QDaemonReadImpl(data, size, false);
|
||||
}
|
||||
|
||||
Result QApplicationReadStorage(void *data, size_t size)
|
||||
{
|
||||
AppletStorage st;
|
||||
auto rc = appletPopLaunchParameter(&st, AppletLaunchParameterKind_UserChannel);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
rc = appletStorageRead(&st, 0, data, size);
|
||||
appletStorageClose(&st);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
ResultWith<QMenuStartMode> QMenu_ProcessInput()
|
||||
{
|
||||
LibAppletArgs in_args;
|
||||
auto rc = QLibraryAppletReadStorage(&in_args, sizeof(LibAppletArgs));
|
||||
return MakeResultWith(rc, (QMenuStartMode)in_args.LaVersion);
|
||||
}
|
||||
|
||||
Result QMenu_InitializeDaemonService()
|
||||
{
|
||||
if(serviceIsActive(&daemon_srv)) return 0;
|
||||
return smGetService(&daemon_srv, AM_QDAEMON_SERVICE_NAME);
|
||||
}
|
||||
|
||||
ResultWith<QMenuMessage> QMenu_GetLatestQMenuMessage()
|
||||
{
|
||||
u32 outmsg = 0;
|
||||
auto rc = serviceDispatchOut(&daemon_srv, 0, outmsg);
|
||||
return MakeResultWith(rc, (QMenuMessage)outmsg);
|
||||
}
|
||||
|
||||
bool QMenuIsHomePressed()
|
||||
{
|
||||
auto [rc, msg] = QMenu_GetLatestQMenuMessage();
|
||||
if(R_FAILED(rc)) return false;
|
||||
return (msg == QMenuMessage::HomeRequest);
|
||||
}
|
||||
|
||||
void QMenu_FinalizeDaemonService()
|
||||
{
|
||||
serviceClose(&daemon_srv);
|
||||
}
|
||||
|
||||
Result QDaemon_QMenuWriteImpl(void *data, size_t size, bool wait)
|
||||
UL_AM_WAIT(LibraryAppletSend(data, size))
|
||||
|
||||
Result QDaemon_QMenuReadImpl(void *data, size_t size, bool wait)
|
||||
UL_AM_WAIT(LibraryAppletRead(data, size))
|
||||
|
||||
Result QMenu_QDaemonWriteImpl(void *data, size_t size, bool wait)
|
||||
UL_AM_WAIT_WITH(
|
||||
AppletStorage st;
|
||||
rc = appletCreateStorage(&st, size);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
rc = appletStorageWrite(&st, 0, data, size);
|
||||
if(R_SUCCEEDED(rc)) rc = appletPushOutData(&st);
|
||||
appletStorageClose(&st);
|
||||
}
|
||||
)
|
||||
|
||||
Result QMenu_QDaemonReadImpl(void *data, size_t size, bool wait)
|
||||
UL_AM_WAIT_WITH(
|
||||
AppletStorage st;
|
||||
rc = appletPopInData(&st);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
rc = appletStorageRead(&st, 0, data, size);
|
||||
appletStorageClose(&st);
|
||||
}
|
||||
)
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
namespace cfg
|
||||
{
|
||||
void CacheHomebrew(std::string nro_path)
|
||||
void CacheHomebrew(const std::string &nro_path)
|
||||
{
|
||||
auto nroimg = GetNROCacheIconPath(nro_path);
|
||||
FILE *f = fopen(nro_path.c_str(), "rb");
|
||||
|
@ -39,7 +39,7 @@ namespace cfg
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<TitleRecord> QueryAllHomebrew(std::string base)
|
||||
std::vector<TitleRecord> QueryAllHomebrew(const std::string &base)
|
||||
{
|
||||
std::vector<TitleRecord> nros;
|
||||
|
||||
|
@ -88,7 +88,7 @@ namespace cfg
|
|||
delete[] recordbuf;
|
||||
}
|
||||
|
||||
static void CacheAllHomebrew(std::string hb_base_path)
|
||||
static void CacheAllHomebrew(const std::string &hb_base_path)
|
||||
{
|
||||
FS_FOR(hb_base_path, name, path,
|
||||
{
|
||||
|
@ -103,7 +103,7 @@ namespace cfg
|
|||
})
|
||||
}
|
||||
|
||||
void CacheEverything(std::string hb_base_path)
|
||||
void CacheEverything(const std::string &hb_base_path)
|
||||
{
|
||||
CacheInstalledTitles();
|
||||
CacheAllHomebrew(hb_base_path);
|
||||
|
@ -188,7 +188,7 @@ namespace cfg
|
|||
return info;
|
||||
}
|
||||
|
||||
Theme LoadTheme(std::string base_name)
|
||||
Theme LoadTheme(const std::string &base_name)
|
||||
{
|
||||
Theme theme = {};
|
||||
theme.base_name = base_name;
|
||||
|
@ -223,7 +223,7 @@ namespace cfg
|
|||
return themes;
|
||||
}
|
||||
|
||||
std::string GetAssetByTheme(Theme &base, std::string resource_base)
|
||||
std::string GetAssetByTheme(const Theme &base, const std::string &resource_base)
|
||||
{
|
||||
auto base_res = base.path + "/" + resource_base;
|
||||
if(fs::ExistsFile(base_res)) return base_res;
|
||||
|
@ -232,12 +232,12 @@ namespace cfg
|
|||
return "";
|
||||
}
|
||||
|
||||
std::string GetLanguageJSONPath(std::string lang)
|
||||
std::string GetLanguageJSONPath(const std::string &lang)
|
||||
{
|
||||
return UL_BASE_SD_DIR "/lang/" + lang + ".json";
|
||||
}
|
||||
|
||||
std::string GetLanguageString(JSON &lang, JSON &def, std::string name)
|
||||
std::string GetLanguageString(const JSON &lang, const JSON &def, const std::string &name)
|
||||
{
|
||||
auto str = lang.value(name, "");
|
||||
if(str.empty()) str = def.value(name, "");
|
||||
|
@ -246,29 +246,36 @@ namespace cfg
|
|||
|
||||
Config CreateNewAndLoadConfig()
|
||||
{
|
||||
Config cfg = {};
|
||||
cfg.system_title_override_enabled = false; // Due to ban risk, have it disabled by default.
|
||||
cfg.viewer_usb_enabled = false; // Do not enable this by default due to conflicts with USB homebrew
|
||||
cfg.theme_name = ""; // Default theme (none)
|
||||
// Default constructor sets everything
|
||||
Config cfg;
|
||||
SaveConfig(cfg);
|
||||
return cfg;
|
||||
}
|
||||
|
||||
Config LoadConfig()
|
||||
{
|
||||
Config cfg = {};
|
||||
// Default constructor sets everything
|
||||
Config cfg;
|
||||
auto [rc, cfgjson] = util::LoadJSONFromFile(CFG_CONFIG_JSON);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
cfg.theme_name = cfgjson.value("theme_name", "");
|
||||
cfg.system_title_override_enabled = cfgjson.value("system_title_override_enabled", false);
|
||||
cfg.viewer_usb_enabled = cfgjson.value("viewer_usb_enabled", false);
|
||||
auto menu_id_str = cfgjson.value("menu_program_id", "");
|
||||
if(!menu_id_str.empty()) cfg.menu_program_id = util::Get64FromString(menu_id_str);
|
||||
auto hb_applet_id_str = cfgjson.value("homebrew_applet_program_id", "");
|
||||
if(!hb_applet_id_str.empty()) cfg.homebrew_applet_program_id = util::Get64FromString(hb_applet_id_str);
|
||||
auto hb_title_id_str = cfgjson.value("homebrew_title_application_id", "");
|
||||
if(!hb_title_id_str.empty()) cfg.homebrew_title_application_id = util::Get64FromString(hb_title_id_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
fs::DeleteFile(CFG_CONFIG_JSON);
|
||||
return CreateNewAndLoadConfig();
|
||||
}
|
||||
// Doing this saves any fields not set previously
|
||||
SaveConfig(cfg);
|
||||
return cfg;
|
||||
}
|
||||
|
||||
|
@ -278,13 +285,15 @@ namespace cfg
|
|||
return LoadConfig();
|
||||
}
|
||||
|
||||
void SaveConfig(Config &cfg)
|
||||
void SaveConfig(const Config &cfg)
|
||||
{
|
||||
fs::DeleteFile(CFG_CONFIG_JSON);
|
||||
JSON j = JSON::object();
|
||||
j["theme_name"] = cfg.theme_name;
|
||||
j["system_title_override_enabled"] = cfg.system_title_override_enabled;
|
||||
j["viewer_usb_enabled"] = cfg.viewer_usb_enabled;
|
||||
j["menu_program_id"] = util::FormatApplicationId(cfg.menu_program_id);
|
||||
j["homebrew_applet_program_id"] = util::FormatApplicationId(cfg.homebrew_applet_program_id);
|
||||
j["homebrew_title_application_id"] = util::FormatApplicationId(cfg.homebrew_title_application_id);
|
||||
std::ofstream ofs(CFG_CONFIG_JSON);
|
||||
ofs << std::setw(4) << j;
|
||||
ofs.close();
|
||||
|
@ -353,7 +362,7 @@ namespace cfg
|
|||
fs::DeleteFile(json);
|
||||
}
|
||||
|
||||
bool MoveTitleToDirectory(TitleList &list, u64 app_id, std::string folder)
|
||||
bool MoveTitleToDirectory(TitleList &list, u64 app_id, const std::string &folder)
|
||||
{
|
||||
bool title_found = false;
|
||||
TitleRecord record_copy = {};
|
||||
|
@ -421,7 +430,7 @@ namespace cfg
|
|||
return title_found;
|
||||
}
|
||||
|
||||
bool MoveRecordTo(TitleList &list, TitleRecord record, std::string folder)
|
||||
bool MoveRecordTo(TitleList &list, TitleRecord record, const std::string &folder)
|
||||
{
|
||||
bool title_found = false;
|
||||
TitleRecord record_copy = {};
|
||||
|
@ -518,7 +527,7 @@ namespace cfg
|
|||
return title_found;
|
||||
}
|
||||
|
||||
TitleFolder &FindFolderByName(TitleList &list, std::string name)
|
||||
TitleFolder &FindFolderByName(TitleList &list, const std::string &name)
|
||||
{
|
||||
if(!name.empty())
|
||||
{
|
||||
|
@ -531,7 +540,7 @@ namespace cfg
|
|||
return list.root;
|
||||
}
|
||||
|
||||
void RenameFolder(TitleList &list, std::string old_name, std::string new_name)
|
||||
void RenameFolder(TitleList &list, const std::string &old_name, const std::string &new_name)
|
||||
{
|
||||
auto &folder = FindFolderByName(list, old_name);
|
||||
if(!folder.name.empty())
|
||||
|
@ -706,7 +715,7 @@ namespace cfg
|
|||
return UL_BASE_SD_DIR "/title/" + strappid + ".jpg";
|
||||
}
|
||||
|
||||
std::string GetNROCacheIconPath(std::string path)
|
||||
std::string GetNROCacheIconPath(const std::string &path)
|
||||
{
|
||||
char pathcopy[FS_MAX_PATH] = {0};
|
||||
strcpy(pathcopy, path.c_str());
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace db
|
|||
fsdevCommitDevice(UL_DB_MOUNT_NAME);
|
||||
}
|
||||
|
||||
ResultWith<PassBlock> PackPassword(AccountUid uid, std::string pass)
|
||||
ResultWith<PassBlock> PackPassword(AccountUid uid, const std::string &pass)
|
||||
{
|
||||
PassBlock pb = {};
|
||||
if((pass.length() > 15) || (pass.empty())) return MakeResultWith(RES_VALUE(Db, InvalidPasswordLength), pb);
|
||||
|
|
|
@ -3,53 +3,53 @@
|
|||
|
||||
namespace fs
|
||||
{
|
||||
static bool ExistsImpl(size_t st_mode, std::string path)
|
||||
static bool ExistsImpl(size_t st_mode, const std::string &path)
|
||||
{
|
||||
struct stat st;
|
||||
return (stat(path.c_str(), &st) == 0) && (st.st_mode & st_mode);
|
||||
}
|
||||
|
||||
bool ExistsFile(std::string path)
|
||||
bool ExistsFile(const std::string &path)
|
||||
{
|
||||
return ExistsImpl(S_IFREG, path);
|
||||
}
|
||||
|
||||
bool ExistsDirectory(std::string path)
|
||||
bool ExistsDirectory(const std::string &path)
|
||||
{
|
||||
return ExistsImpl(S_IFDIR, path);
|
||||
}
|
||||
|
||||
void CreateDirectory(std::string path)
|
||||
void CreateDirectory(const std::string &path)
|
||||
{
|
||||
mkdir(path.c_str(), 777);
|
||||
}
|
||||
|
||||
void CreateFile(std::string path)
|
||||
void CreateFile(const std::string &path)
|
||||
{
|
||||
fsdevCreateFile(path.c_str(), 0, 0);
|
||||
}
|
||||
|
||||
void CreateConcatenationFile(std::string path)
|
||||
void CreateConcatenationFile(const std::string &path)
|
||||
{
|
||||
fsdevCreateFile(path.c_str(), 0, FsCreateOption_BigFile);
|
||||
}
|
||||
|
||||
void DeleteDirectory(std::string path)
|
||||
void DeleteDirectory(const std::string &path)
|
||||
{
|
||||
fsdevDeleteDirectoryRecursively(path.c_str());
|
||||
}
|
||||
|
||||
void DeleteFile(std::string path)
|
||||
void DeleteFile(const std::string &path)
|
||||
{
|
||||
remove(path.c_str());
|
||||
}
|
||||
|
||||
void MoveFile(std::string p1, std::string p2)
|
||||
void MoveFile(const std::string &p1, const std::string &p2)
|
||||
{
|
||||
rename(p1.c_str(), p2.c_str());
|
||||
}
|
||||
|
||||
void CopyFile(std::string p, std::string np)
|
||||
void CopyFile(const std::string &p, const std::string &np)
|
||||
{
|
||||
FILE *inf = fopen(p.c_str(), "rb");
|
||||
if(inf)
|
||||
|
@ -77,7 +77,7 @@ namespace fs
|
|||
}
|
||||
}
|
||||
|
||||
static void HandleDirectoryImpl(bool copy, std::string d, std::string nd)
|
||||
static void HandleDirectoryImpl(bool copy, const std::string &d, const std::string &nd)
|
||||
{
|
||||
DIR *dp = opendir(d.c_str());
|
||||
CreateDirectory(nd);
|
||||
|
@ -102,12 +102,12 @@ namespace fs
|
|||
if(!copy) DeleteDirectory(d);
|
||||
}
|
||||
|
||||
void MoveDirectory(std::string d, std::string nd)
|
||||
void MoveDirectory(const std::string &d, const std::string &nd)
|
||||
{
|
||||
return HandleDirectoryImpl(false, d, nd);
|
||||
}
|
||||
|
||||
void CopyDirectory(std::string d, std::string nd)
|
||||
void CopyDirectory(const std::string &d, const std::string &nd)
|
||||
{
|
||||
return HandleDirectoryImpl(true, d, nd);
|
||||
}
|
||||
|
|
|
@ -31,11 +31,6 @@ namespace util
|
|||
return strm.str();
|
||||
}
|
||||
|
||||
u64 Get64FromString(std::string val)
|
||||
{
|
||||
return strtoull(val.c_str(), NULL, 16);
|
||||
}
|
||||
|
||||
std::string FormatApplicationId(u64 app_id)
|
||||
{
|
||||
std::stringstream strm;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace util
|
||||
{
|
||||
ResultWith<JSON> LoadJSONFromFile(std::string path)
|
||||
ResultWith<JSON> LoadJSONFromFile(const std::string &path)
|
||||
{
|
||||
JSON ret = JSON::object();
|
||||
if(fs::ExistsFile(path))
|
||||
|
|
|
@ -8,16 +8,16 @@
|
|||
|
||||
namespace ui
|
||||
{
|
||||
class QMenuApplication : public pu::ui::Application
|
||||
class MenuApplication : public pu::ui::Application
|
||||
{
|
||||
public:
|
||||
using Application::Application;
|
||||
~QMenuApplication();
|
||||
PU_SMART_CTOR(QMenuApplication)
|
||||
~MenuApplication();
|
||||
PU_SMART_CTOR(MenuApplication)
|
||||
|
||||
void OnLoad() override;
|
||||
|
||||
void SetInformation(am::QMenuStartMode mode, am::QDaemonStatus status);
|
||||
void SetInformation(am::MenuStartMode mode, am::DaemonStatus status);
|
||||
void LoadMenu();
|
||||
void LoadStartupMenu();
|
||||
void LoadThemeMenu();
|
||||
|
@ -81,14 +81,14 @@ namespace ui
|
|||
|
||||
void CommonMenuOnLoop();
|
||||
private:
|
||||
am::QMenuStartMode stmode;
|
||||
am::MenuStartMode stmode;
|
||||
StartupLayout::Ref startupLayout;
|
||||
MenuLayout::Ref menuLayout;
|
||||
ThemeMenuLayout::Ref themeMenuLayout;
|
||||
SettingsMenuLayout::Ref settingsMenuLayout;
|
||||
LanguagesMenuLayout::Ref languagesMenuLayout;
|
||||
pu::ui::extras::Toast::Ref notifToast;
|
||||
am::QDaemonStatus status;
|
||||
am::DaemonStatus status;
|
||||
JSON uijson;
|
||||
JSON bgmjson;
|
||||
bool bgm_loop;
|
||||
|
@ -97,7 +97,7 @@ namespace ui
|
|||
pu::audio::Music bgm;
|
||||
};
|
||||
|
||||
inline void QMenuApplication::CommonMenuOnLoop() // Stuff all menus should handle (currently just connected controllers)
|
||||
inline void MenuApplication::CommonMenuOnLoop() // Stuff all menus should handle (currently just connected controllers)
|
||||
{
|
||||
if(!hidIsControllerConnected(CONTROLLER_HANDHELD) && !hidIsControllerConnected(CONTROLLER_PLAYER_1)) this->menuLayout->HandleControllerAppletOpen();
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
#pragma once
|
||||
#include <ul_Include.hpp>
|
||||
#include <am/am_QCommunications.hpp>
|
||||
#include <am/am_DaemonMenuInteraction.hpp>
|
||||
#include <db/db_Save.hpp>
|
||||
#include <pu/Plutonium>
|
||||
|
||||
|
|
|
@ -8,13 +8,15 @@
|
|||
#include <cfg/cfg_Config.hpp>
|
||||
#include <net/net_Service.hpp>
|
||||
#include <util/util_Misc.hpp>
|
||||
#include <ui/ui_QMenuApplication.hpp>
|
||||
#include <ui/ui_MenuApplication.hpp>
|
||||
#include <os/os_HomeMenu.hpp>
|
||||
#include <util/util_Convert.hpp>
|
||||
#include <am/am_LibraryApplet.hpp>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
u32 __nx_applet_type = AppletType_LibraryApplet; // Explicitly declare we're a library applet (need to do so for non-hbloader homebrew)
|
||||
TimeServiceType __nx_time_service_type = TimeServiceType_System;
|
||||
size_t __nx_heap_size = 0xD000000; // 208MB heap
|
||||
}
|
||||
|
||||
|
@ -22,7 +24,7 @@ extern "C"
|
|||
|
||||
// Some global vars
|
||||
|
||||
ui::QMenuApplication::Ref qapp;
|
||||
ui::MenuApplication::Ref qapp;
|
||||
cfg::TitleList list;
|
||||
std::vector<cfg::TitleRecord> homebrew;
|
||||
cfg::Config config;
|
||||
|
@ -40,7 +42,7 @@ namespace qmenu
|
|||
UL_R_TRY(setsysInitialize())
|
||||
UL_R_TRY(setInitialize())
|
||||
|
||||
UL_R_TRY(am::QMenu_InitializeDaemonService())
|
||||
UL_R_TRY(am::Menu_InitializeDaemonService())
|
||||
|
||||
// Load menu config and theme
|
||||
config = cfg::EnsureConfig();
|
||||
|
@ -49,7 +51,7 @@ namespace qmenu
|
|||
|
||||
void Exit()
|
||||
{
|
||||
am::QMenu_FinalizeDaemonService();
|
||||
am::Menu_FinalizeDaemonService();
|
||||
|
||||
setExit();
|
||||
setsysExit();
|
||||
|
@ -62,17 +64,17 @@ namespace qmenu
|
|||
|
||||
int main()
|
||||
{
|
||||
auto [rc, smode] = am::QMenu_ProcessInput();
|
||||
auto [rc, smode] = am::Menu_ProcessInput();
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
am::QDaemonStatus status = {};
|
||||
am::DaemonStatus status = {};
|
||||
|
||||
// Information block sent as an extra storage to QMenu.
|
||||
am::QLibraryAppletReadStorage(&status, sizeof(status));
|
||||
// Information block sent as an extra storage to Menu.
|
||||
am::Menu_DaemonReadImpl(&status, sizeof(status), false);
|
||||
|
||||
// First read sent storages, then init the renderer (UI, which also inits RomFs), then init everything else
|
||||
|
||||
if(smode != am::QMenuStartMode::Invalid)
|
||||
if(smode != am::MenuStartMode::Invalid)
|
||||
{
|
||||
// Check if our RomFs file exists...
|
||||
if(!fs::ExistsFile(MENU_ROMFS_BIN)) Panic("Unable to find RomFs binary: '" MENU_ROMFS_BIN "'");
|
||||
|
@ -107,12 +109,12 @@ int main()
|
|||
renderoptions.InitRomFs = false; // We have loaded RomFs from an external file, so :P
|
||||
|
||||
auto renderer = pu::ui::render::Renderer::New(SDL_INIT_EVERYTHING, renderoptions, pu::ui::render::RendererHardwareFlags);
|
||||
qapp = ui::QMenuApplication::New(renderer);
|
||||
qapp = ui::MenuApplication::New(renderer);
|
||||
|
||||
qapp->SetInformation(smode, status);
|
||||
qapp->Prepare();
|
||||
|
||||
if(smode == am::QMenuStartMode::MenuApplicationSuspended) qapp->Show();
|
||||
if(smode == am::MenuStartMode::MenuApplicationSuspended) qapp->Show();
|
||||
else qapp->ShowWithFadeIn();
|
||||
|
||||
// Exit RomFs manually, Plutonium won't do it for us since we're initializing it manually
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#include <ui/ui_LanguagesMenuLayout.hpp>
|
||||
#include <os/os_Account.hpp>
|
||||
#include <util/util_Convert.hpp>
|
||||
#include <ui/ui_QMenuApplication.hpp>
|
||||
#include <ui/ui_MenuApplication.hpp>
|
||||
#include <fs/fs_Stdio.hpp>
|
||||
#include <os/os_Misc.hpp>
|
||||
#include <os/os_HomeMenu.hpp>
|
||||
#include <net/net_Service.hpp>
|
||||
#include <am/am_LibraryApplet.hpp>
|
||||
|
||||
extern ui::QMenuApplication::Ref qapp;
|
||||
extern ui::MenuApplication::Ref qapp;
|
||||
extern cfg::Theme theme;
|
||||
extern cfg::Config config;
|
||||
|
||||
|
@ -98,7 +98,7 @@ namespace ui
|
|||
{
|
||||
qapp->CommonMenuOnLoop();
|
||||
|
||||
bool ret = am::QMenuIsHomePressed();
|
||||
bool ret = am::MenuIsHomePressed();
|
||||
if(down & KEY_B)
|
||||
{
|
||||
qapp->FadeOut();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <ui/ui_QMenuApplication.hpp>
|
||||
#include <ui/ui_MenuApplication.hpp>
|
||||
#include <util/util_Misc.hpp>
|
||||
|
||||
extern u8 *app_buf;
|
||||
|
@ -6,12 +6,12 @@ extern cfg::Theme theme;
|
|||
|
||||
namespace ui
|
||||
{
|
||||
QMenuApplication::~QMenuApplication()
|
||||
MenuApplication::~MenuApplication()
|
||||
{
|
||||
pu::audio::Delete(this->bgm);
|
||||
}
|
||||
|
||||
void QMenuApplication::OnLoad()
|
||||
void MenuApplication::OnLoad()
|
||||
{
|
||||
pu::ui::render::SetDefaultFont(cfg::GetAssetByTheme(theme, "ui/Font.ttf"));
|
||||
|
||||
|
@ -43,7 +43,7 @@ namespace ui
|
|||
|
||||
switch(this->stmode)
|
||||
{
|
||||
case am::QMenuStartMode::StartupScreen:
|
||||
case am::MenuStartMode::StartupScreen:
|
||||
this->LoadStartupMenu();
|
||||
break;
|
||||
default:
|
||||
|
@ -53,88 +53,88 @@ namespace ui
|
|||
}
|
||||
}
|
||||
|
||||
void QMenuApplication::SetInformation(am::QMenuStartMode mode, am::QDaemonStatus status)
|
||||
void MenuApplication::SetInformation(am::MenuStartMode mode, am::DaemonStatus status)
|
||||
{
|
||||
this->stmode = mode;
|
||||
this->status = status;
|
||||
}
|
||||
|
||||
void QMenuApplication::LoadMenu()
|
||||
void MenuApplication::LoadMenu()
|
||||
{
|
||||
this->menuLayout->SetUser(this->status.selected_user);
|
||||
this->LoadLayout(this->menuLayout);
|
||||
}
|
||||
|
||||
void QMenuApplication::LoadStartupMenu()
|
||||
void MenuApplication::LoadStartupMenu()
|
||||
{
|
||||
this->StopPlayBGM();
|
||||
this->startupLayout->ReloadMenu();
|
||||
this->LoadLayout(this->startupLayout);
|
||||
}
|
||||
|
||||
void QMenuApplication::LoadThemeMenu()
|
||||
void MenuApplication::LoadThemeMenu()
|
||||
{
|
||||
this->themeMenuLayout->Reload();
|
||||
this->LoadLayout(this->themeMenuLayout);
|
||||
}
|
||||
|
||||
void QMenuApplication::LoadSettingsMenu()
|
||||
void MenuApplication::LoadSettingsMenu()
|
||||
{
|
||||
this->settingsMenuLayout->Reload();
|
||||
this->LoadLayout(this->settingsMenuLayout);
|
||||
}
|
||||
|
||||
void QMenuApplication::LoadSettingsLanguagesMenu()
|
||||
void MenuApplication::LoadSettingsLanguagesMenu()
|
||||
{
|
||||
this->languagesMenuLayout->Reload();
|
||||
this->LoadLayout(this->languagesMenuLayout);
|
||||
}
|
||||
|
||||
bool QMenuApplication::IsSuspended()
|
||||
bool MenuApplication::IsSuspended()
|
||||
{
|
||||
return this->IsTitleSuspended() || this->IsHomebrewSuspended();
|
||||
}
|
||||
|
||||
bool QMenuApplication::IsTitleSuspended()
|
||||
bool MenuApplication::IsTitleSuspended()
|
||||
{
|
||||
return this->status.app_id > 0;
|
||||
}
|
||||
|
||||
bool QMenuApplication::IsHomebrewSuspended()
|
||||
bool MenuApplication::IsHomebrewSuspended()
|
||||
{
|
||||
return strlen(this->status.params.nro_path);
|
||||
}
|
||||
|
||||
bool QMenuApplication::EqualsSuspendedHomebrewPath(std::string path)
|
||||
bool MenuApplication::EqualsSuspendedHomebrewPath(std::string path)
|
||||
{
|
||||
return this->status.params.nro_path == path;
|
||||
}
|
||||
|
||||
u64 QMenuApplication::GetSuspendedApplicationId()
|
||||
u64 MenuApplication::GetSuspendedApplicationId()
|
||||
{
|
||||
return this->status.app_id;
|
||||
}
|
||||
|
||||
void QMenuApplication::NotifyEndSuspended()
|
||||
void MenuApplication::NotifyEndSuspended()
|
||||
{
|
||||
// Blanking the whole status would also blank the selected user...
|
||||
this->status.params = {};
|
||||
this->status.app_id = 0;
|
||||
}
|
||||
|
||||
bool QMenuApplication::LaunchFailed()
|
||||
bool MenuApplication::LaunchFailed()
|
||||
{
|
||||
return (this->stmode == am::QMenuStartMode::MenuLaunchFailure);
|
||||
return (this->stmode == am::MenuStartMode::MenuLaunchFailure);
|
||||
}
|
||||
|
||||
void QMenuApplication::ShowNotification(std::string text, u64 timeout)
|
||||
void MenuApplication::ShowNotification(std::string text, u64 timeout)
|
||||
{
|
||||
this->EndOverlay();
|
||||
this->notifToast->SetText(text);
|
||||
this->StartOverlayWithTimeout(this->notifToast, timeout);
|
||||
}
|
||||
|
||||
void QMenuApplication::StartPlayBGM()
|
||||
void MenuApplication::StartPlayBGM()
|
||||
{
|
||||
if(this->bgm != NULL)
|
||||
{
|
||||
|
@ -144,22 +144,22 @@ namespace ui
|
|||
}
|
||||
}
|
||||
|
||||
void QMenuApplication::StopPlayBGM()
|
||||
void MenuApplication::StopPlayBGM()
|
||||
{
|
||||
if(this->bgm_fade_out_ms > 0) pu::audio::FadeOut(this->bgm_fade_out_ms);
|
||||
else pu::audio::Stop();
|
||||
}
|
||||
|
||||
void QMenuApplication::SetSelectedUser(AccountUid user_id)
|
||||
void MenuApplication::SetSelectedUser(AccountUid user_id)
|
||||
{
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::SetSelectedUser);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::SetSelectedUser);
|
||||
writer.Write<AccountUid>(user_id);
|
||||
writer.FinishWrite();
|
||||
|
||||
memcpy(&this->status.selected_user, &user_id, sizeof(user_id));
|
||||
}
|
||||
|
||||
AccountUid QMenuApplication::GetSelectedUser()
|
||||
AccountUid MenuApplication::GetSelectedUser()
|
||||
{
|
||||
return this->status.selected_user;
|
||||
}
|
|
@ -5,12 +5,12 @@
|
|||
#include <util/util_Misc.hpp>
|
||||
#include <os/os_Misc.hpp>
|
||||
#include <am/am_LibraryApplet.hpp>
|
||||
#include <ui/ui_QMenuApplication.hpp>
|
||||
#include <ui/ui_MenuApplication.hpp>
|
||||
#include <os/os_HomeMenu.hpp>
|
||||
#include <fs/fs_Stdio.hpp>
|
||||
#include <net/net_Service.hpp>
|
||||
|
||||
extern ui::QMenuApplication::Ref qapp;
|
||||
extern ui::MenuApplication::Ref qapp;
|
||||
extern cfg::TitleList list;
|
||||
extern std::vector<cfg::TitleRecord> homebrew;
|
||||
extern cfg::Config config;
|
||||
|
@ -288,205 +288,215 @@ namespace ui
|
|||
}
|
||||
else
|
||||
{
|
||||
if((down & KEY_A) || (down & KEY_X) || (down & KEY_Y))
|
||||
if((index == 0) && this->homebrew_mode)
|
||||
{
|
||||
if((index == 0) && this->homebrew_mode)
|
||||
if(down & KEY_A)
|
||||
{
|
||||
pu::audio::Play(this->sfxTitleLaunch);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::LaunchHomebrewLibraryApplet);
|
||||
hb::HbTargetParams ipt = {};
|
||||
strcpy(ipt.nro_path, MENU_HBMENU_NRO); // Launch normal hbmenu
|
||||
strcpy(ipt.nro_argv, MENU_HBMENU_NRO);
|
||||
writer.Write<hb::HbTargetParams>(ipt);
|
||||
writer.FinishWrite();
|
||||
|
||||
qapp->StopPlayBGM();
|
||||
qapp->CloseWithFadeOut();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 realidx = index;
|
||||
if(this->homebrew_mode) realidx--;
|
||||
if(this->homebrew_mode)
|
||||
{
|
||||
auto hb = homebrew[realidx];
|
||||
if(down & KEY_A)
|
||||
{
|
||||
pu::audio::Play(this->sfxTitleLaunch);
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::LaunchHomebrewLibApplet);
|
||||
hb::HbTargetParams ipt = {};
|
||||
strcpy(ipt.nro_path, MENU_HBMENU_NRO); // Launch normal hbmenu
|
||||
strcpy(ipt.nro_argv, MENU_HBMENU_NRO);
|
||||
writer.Write<hb::HbTargetParams>(ipt);
|
||||
writer.FinishWrite();
|
||||
|
||||
qapp->StopPlayBGM();
|
||||
qapp->CloseWithFadeOut();
|
||||
return;
|
||||
bool hblaunch = true;
|
||||
if(qapp->IsHomebrewSuspended())
|
||||
{
|
||||
if(qapp->EqualsSuspendedHomebrewPath(hb.nro_target.nro_path))
|
||||
{
|
||||
if(this->mode == 1) this->mode = 2;
|
||||
hblaunch = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
hblaunch = false;
|
||||
this->HandleCloseSuspended();
|
||||
hblaunch = !qapp->IsHomebrewSuspended();
|
||||
}
|
||||
}
|
||||
if(hblaunch) this->HandleHomebrewLaunch(hb);
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
if(qapp->IsSuspended())
|
||||
{
|
||||
if(qapp->EqualsSuspendedHomebrewPath(hb.nro_target.nro_path)) this->HandleCloseSuspended();
|
||||
}
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
if(!this->select_on) this->select_on = true;
|
||||
this->itemsMenu->SetItemMultiselected(this->itemsMenu->GetSelectedItem(), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 realidx = index;
|
||||
if(this->homebrew_mode) realidx--;
|
||||
if(this->homebrew_mode)
|
||||
auto &folder = cfg::FindFolderByName(list, this->curfolder);
|
||||
s32 titleidx = realidx;
|
||||
if(this->curfolder.empty())
|
||||
{
|
||||
auto hb = homebrew[realidx];
|
||||
if(down & KEY_A)
|
||||
if(realidx >= list.folders.size())
|
||||
{
|
||||
bool hblaunch = true;
|
||||
if(qapp->IsHomebrewSuspended())
|
||||
titleidx -= list.folders.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto foldr = list.folders[realidx];
|
||||
if(down & KEY_A)
|
||||
{
|
||||
if(qapp->EqualsSuspendedHomebrewPath(hb.nro_target.nro_path))
|
||||
this->MoveFolder(foldr.name, true);
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
auto sopt = qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "menu_rename_folder"), cfg::GetLanguageString(config.main_lang, config.default_lang, "menu_rename_folder_conf"), { cfg::GetLanguageString(config.main_lang, config.default_lang, "yes"), cfg::GetLanguageString(config.main_lang, config.default_lang, "no") }, true);
|
||||
if(sopt == 0)
|
||||
{
|
||||
if(this->mode == 1) this->mode = 2;
|
||||
hblaunch = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
hblaunch = false;
|
||||
this->HandleCloseSuspended();
|
||||
hblaunch = !qapp->IsHomebrewSuspended();
|
||||
SwkbdConfig swkbd;
|
||||
swkbdCreate(&swkbd, 0);
|
||||
swkbdConfigSetGuideText(&swkbd, cfg::GetLanguageString(config.main_lang, config.default_lang, "swkbd_rename_folder_guide").c_str());
|
||||
char dir[500] = {0};
|
||||
auto rc = swkbdShow(&swkbd, dir, 500);
|
||||
swkbdClose(&swkbd);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
cfg::RenameFolder(list, foldr.name, dir);
|
||||
this->MoveFolder(this->curfolder, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
titleidx = -1;
|
||||
}
|
||||
}
|
||||
if(titleidx >= 0)
|
||||
{
|
||||
auto title = folder.titles[titleidx];
|
||||
if(down & KEY_A)
|
||||
{
|
||||
bool titlelaunch = true;
|
||||
|
||||
if(qapp->IsSuspended())
|
||||
{
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Homebrew)
|
||||
{
|
||||
if(qapp->EqualsSuspendedHomebrewPath(title.nro_target.nro_path))
|
||||
{
|
||||
if(this->mode == 1) this->mode = 2;
|
||||
titlelaunch = false;
|
||||
}
|
||||
}
|
||||
else if((cfg::TitleType)title.title_type == cfg::TitleType::Installed)
|
||||
{
|
||||
if(title.app_id == qapp->GetSuspendedApplicationId())
|
||||
{
|
||||
if(this->mode == 1) this->mode = 2;
|
||||
titlelaunch = false;
|
||||
}
|
||||
}
|
||||
if(titlelaunch)
|
||||
{
|
||||
// Homebrew launching code already does this checks later - doing this check only with installed titles
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Installed)
|
||||
{
|
||||
titlelaunch = false;
|
||||
this->HandleCloseSuspended();
|
||||
titlelaunch = !qapp->IsSuspended();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(titlelaunch)
|
||||
{
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Homebrew) this->HandleHomebrewLaunch(title);
|
||||
else
|
||||
{
|
||||
pu::audio::Play(this->sfxTitleLaunch);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::LaunchApplication);
|
||||
writer.Write<u64>(title.app_id);
|
||||
writer.FinishWrite();
|
||||
|
||||
am::MenuCommandResultReader reader;
|
||||
if(reader && R_SUCCEEDED(reader.GetReadResult()))
|
||||
{
|
||||
qapp->StopPlayBGM();
|
||||
qapp->CloseWithFadeOut();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto rc = reader.GetReadResult();
|
||||
qapp->ShowNotification(cfg::GetLanguageString(config.main_lang, config.default_lang, "app_launch_error") + ": " + util::FormatResult(rc));
|
||||
}
|
||||
reader.FinishRead();
|
||||
}
|
||||
}
|
||||
if(hblaunch) this->HandleHomebrewLaunch(hb);
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
if(qapp->IsSuspended())
|
||||
{
|
||||
if(qapp->EqualsSuspendedHomebrewPath(hb.nro_target.nro_path)) this->HandleCloseSuspended();
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Homebrew)
|
||||
{
|
||||
if(qapp->EqualsSuspendedHomebrewPath(title.nro_target.nro_path)) this->HandleCloseSuspended();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(title.app_id == qapp->GetSuspendedApplicationId()) this->HandleCloseSuspended();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
if(!this->select_on) this->select_on = true;
|
||||
this->itemsMenu->SetItemMultiselected(this->itemsMenu->GetSelectedItem(), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto &folder = cfg::FindFolderByName(list, this->curfolder);
|
||||
s32 titleidx = realidx;
|
||||
if(this->curfolder.empty())
|
||||
{
|
||||
if(realidx >= list.folders.size())
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Homebrew)
|
||||
{
|
||||
titleidx -= list.folders.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto foldr = list.folders[realidx];
|
||||
if(down & KEY_A)
|
||||
{
|
||||
this->MoveFolder(foldr.name, true);
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
auto sopt = qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "menu_rename_folder"), cfg::GetLanguageString(config.main_lang, config.default_lang, "menu_rename_folder_conf"), { cfg::GetLanguageString(config.main_lang, config.default_lang, "yes"), cfg::GetLanguageString(config.main_lang, config.default_lang, "no") }, true);
|
||||
if(sopt == 0)
|
||||
{
|
||||
SwkbdConfig swkbd;
|
||||
swkbdCreate(&swkbd, 0);
|
||||
swkbdConfigSetGuideText(&swkbd, cfg::GetLanguageString(config.main_lang, config.default_lang, "swkbd_rename_folder_guide").c_str());
|
||||
char dir[500] = {0};
|
||||
auto rc = swkbdShow(&swkbd, dir, 500);
|
||||
swkbdClose(&swkbd);
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
cfg::RenameFolder(list, foldr.name, dir);
|
||||
this->MoveFolder(this->curfolder, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
titleidx = -1;
|
||||
}
|
||||
}
|
||||
if(titleidx >= 0)
|
||||
{
|
||||
auto title = folder.titles[titleidx];
|
||||
if(down & KEY_A)
|
||||
{
|
||||
bool titlelaunch = true;
|
||||
|
||||
if(qapp->IsSuspended())
|
||||
{
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Homebrew)
|
||||
{
|
||||
if(qapp->EqualsSuspendedHomebrewPath(title.nro_target.nro_path))
|
||||
{
|
||||
if(this->mode == 1) this->mode = 2;
|
||||
titlelaunch = false;
|
||||
}
|
||||
}
|
||||
else if((cfg::TitleType)title.title_type == cfg::TitleType::Installed)
|
||||
{
|
||||
if(title.app_id == qapp->GetSuspendedApplicationId())
|
||||
{
|
||||
if(this->mode == 1) this->mode = 2;
|
||||
titlelaunch = false;
|
||||
}
|
||||
}
|
||||
if(titlelaunch)
|
||||
{
|
||||
// Homebrew launching code already does this checks later - doing this check only with installed titles
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Installed)
|
||||
{
|
||||
titlelaunch = false;
|
||||
this->HandleCloseSuspended();
|
||||
titlelaunch = !qapp->IsSuspended();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(titlelaunch)
|
||||
{
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Homebrew) this->HandleHomebrewLaunch(title);
|
||||
else
|
||||
{
|
||||
pu::audio::Play(this->sfxTitleLaunch);
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::LaunchApplication);
|
||||
writer.Write<u64>(title.app_id);
|
||||
writer.FinishWrite();
|
||||
|
||||
am::QMenuCommandResultReader reader;
|
||||
if(reader && R_SUCCEEDED(reader.GetReadResult()))
|
||||
{
|
||||
qapp->StopPlayBGM();
|
||||
qapp->CloseWithFadeOut();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto rc = reader.GetReadResult();
|
||||
qapp->ShowNotification(cfg::GetLanguageString(config.main_lang, config.default_lang, "app_launch_error") + ": " + util::FormatResult(rc));
|
||||
}
|
||||
reader.FinishRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
if(qapp->IsSuspended())
|
||||
{
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Homebrew)
|
||||
{
|
||||
if(qapp->EqualsSuspendedHomebrewPath(title.nro_target.nro_path)) this->HandleCloseSuspended();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(title.app_id == qapp->GetSuspendedApplicationId()) this->HandleCloseSuspended();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Homebrew)
|
||||
{
|
||||
auto sopt = qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_options"), cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_action"), { cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_move"), cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_remove"), cfg::GetLanguageString(config.main_lang, config.default_lang, "cancel") }, true);
|
||||
if(sopt == 0)
|
||||
{
|
||||
if(!this->select_on) this->select_on = true;
|
||||
this->itemsMenu->SetItemMultiselected(this->itemsMenu->GetSelectedItem(), true);
|
||||
}
|
||||
else if(sopt == 1)
|
||||
{
|
||||
auto sopt2 = qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_remove"), cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_remove_conf"), { cfg::GetLanguageString(config.main_lang, config.default_lang, "yes"), cfg::GetLanguageString(config.main_lang, config.default_lang, "no") }, true);
|
||||
if(sopt2 == 0)
|
||||
{
|
||||
cfg::RemoveRecord(title);
|
||||
folder.titles.erase(folder.titles.begin() + titleidx);
|
||||
qapp->ShowNotification(cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_remove_ok"));
|
||||
this->MoveFolder(this->curfolder, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
auto sopt = qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_options"), cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_action"), { cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_move"), cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_remove"), cfg::GetLanguageString(config.main_lang, config.default_lang, "cancel") }, true);
|
||||
if(sopt == 0)
|
||||
{
|
||||
if(!this->select_on) this->select_on = true;
|
||||
this->itemsMenu->SetItemMultiselected(this->itemsMenu->GetSelectedItem(), true);
|
||||
}
|
||||
else if(sopt == 1)
|
||||
{
|
||||
auto sopt2 = qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_remove"), cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_remove_conf"), { cfg::GetLanguageString(config.main_lang, config.default_lang, "yes"), cfg::GetLanguageString(config.main_lang, config.default_lang, "no") }, true);
|
||||
if(sopt2 == 0)
|
||||
{
|
||||
cfg::RemoveRecord(title);
|
||||
folder.titles.erase(folder.titles.begin() + titleidx);
|
||||
qapp->ShowNotification(cfg::GetLanguageString(config.main_lang, config.default_lang, "entry_remove_ok"));
|
||||
this->MoveFolder(this->curfolder, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!this->select_on) this->select_on = true;
|
||||
this->itemsMenu->SetItemMultiselected(this->itemsMenu->GetSelectedItem(), true);
|
||||
}
|
||||
}
|
||||
else if(down & KEY_UP)
|
||||
{
|
||||
if((cfg::TitleType)title.title_type == cfg::TitleType::Installed)
|
||||
{
|
||||
auto sopt = qapp->CreateShowDialog("Homebrew title take-over", "Would you like to select this title for homebrew launching?\nIf selected, homebrew will be launched as an application over this title.", { "Yes", "Cancel" }, true);
|
||||
if(sopt == 0)
|
||||
{
|
||||
config.homebrew_title_application_id = title.app_id;
|
||||
cfg::SaveConfig(config);
|
||||
qapp->ShowNotification("Done");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -669,7 +679,7 @@ namespace ui
|
|||
}
|
||||
}
|
||||
|
||||
if(am::QMenuIsHomePressed())
|
||||
if(am::MenuIsHomePressed())
|
||||
{
|
||||
if(qapp->IsSuspended())
|
||||
{
|
||||
|
@ -713,10 +723,10 @@ namespace ui
|
|||
if(this->rawalpha == 255)
|
||||
{
|
||||
this->bgSuspendedRaw->SetAlphaFactor(this->rawalpha);
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::ResumeApplication);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::ResumeApplication);
|
||||
writer.FinishWrite();
|
||||
|
||||
am::QMenuCommandResultReader reader;
|
||||
am::MenuCommandResultReader reader;
|
||||
reader.FinishRead();
|
||||
}
|
||||
else
|
||||
|
@ -801,7 +811,7 @@ namespace ui
|
|||
auto sopt = qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "suspended_app"), cfg::GetLanguageString(config.main_lang, config.default_lang, "suspended_close"), { cfg::GetLanguageString(config.main_lang, config.default_lang, "yes"), cfg::GetLanguageString(config.main_lang, config.default_lang, "no") }, true);
|
||||
if(sopt == 0)
|
||||
{
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::TerminateApplication);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::TerminateApplication);
|
||||
writer.FinishWrite();
|
||||
|
||||
this->itemsMenu->UnsetSuspendedItem();
|
||||
|
@ -828,7 +838,7 @@ namespace ui
|
|||
strcpy(ipt.nro_argv, rec.nro_target.nro_argv);
|
||||
if(strlen(rec.nro_target.nro_argv)) sprintf(ipt.nro_argv, "%s %s", rec.nro_target.nro_path, rec.nro_target.nro_argv);
|
||||
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::LaunchHomebrewLibApplet);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::LaunchHomebrewLibraryApplet);
|
||||
writer.Write<hb::HbTargetParams>(ipt);
|
||||
writer.FinishWrite();
|
||||
|
||||
|
@ -838,38 +848,46 @@ namespace ui
|
|||
}
|
||||
else if(launchmode == 2)
|
||||
{
|
||||
bool launch = true;
|
||||
if(qapp->IsSuspended())
|
||||
if(config.homebrew_title_application_id != 0)
|
||||
{
|
||||
launch = false;
|
||||
this->HandleCloseSuspended();
|
||||
if(!qapp->IsSuspended()) launch = true;
|
||||
bool launch = true;
|
||||
if(qapp->IsSuspended())
|
||||
{
|
||||
launch = false;
|
||||
this->HandleCloseSuspended();
|
||||
if(!qapp->IsSuspended()) launch = true;
|
||||
}
|
||||
if(launch)
|
||||
{
|
||||
pu::audio::Play(this->sfxTitleLaunch);
|
||||
hb::HbTargetParams ipt = {};
|
||||
strcpy(ipt.nro_path, rec.nro_target.nro_path);
|
||||
strcpy(ipt.nro_argv, rec.nro_target.nro_argv);
|
||||
if(strlen(rec.nro_target.nro_argv)) sprintf(ipt.nro_argv, "%s %s", rec.nro_target.nro_path, rec.nro_target.nro_argv);
|
||||
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::LaunchHomebrewApplication);
|
||||
writer.Write<u64>(config.homebrew_title_application_id);
|
||||
writer.Write<hb::HbTargetParams>(ipt);
|
||||
writer.FinishWrite();
|
||||
|
||||
am::MenuCommandResultReader reader;
|
||||
if(reader && R_SUCCEEDED(reader.GetReadResult()))
|
||||
{
|
||||
qapp->StopPlayBGM();
|
||||
qapp->CloseWithFadeOut();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto rc = reader.GetReadResult();
|
||||
qapp->ShowNotification(cfg::GetLanguageString(config.main_lang, config.default_lang, "app_launch_error") + ": " + util::FormatResult(rc));
|
||||
}
|
||||
reader.FinishRead();
|
||||
}
|
||||
}
|
||||
if(launch)
|
||||
else
|
||||
{
|
||||
pu::audio::Play(this->sfxTitleLaunch);
|
||||
hb::HbTargetParams ipt = {};
|
||||
strcpy(ipt.nro_path, rec.nro_target.nro_path);
|
||||
strcpy(ipt.nro_argv, rec.nro_target.nro_argv);
|
||||
if(strlen(rec.nro_target.nro_argv)) sprintf(ipt.nro_argv, "%s %s", rec.nro_target.nro_path, rec.nro_target.nro_argv);
|
||||
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::LaunchHomebrewApplication);
|
||||
writer.Write<hb::HbTargetParams>(ipt);
|
||||
writer.FinishWrite();
|
||||
|
||||
am::QMenuCommandResultReader reader;
|
||||
if(reader && R_SUCCEEDED(reader.GetReadResult()))
|
||||
{
|
||||
qapp->StopPlayBGM();
|
||||
qapp->CloseWithFadeOut();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto rc = reader.GetReadResult();
|
||||
qapp->ShowNotification(cfg::GetLanguageString(config.main_lang, config.default_lang, "app_launch_error") + ": " + util::FormatResult(rc));
|
||||
}
|
||||
reader.FinishRead();
|
||||
qapp->CreateShowDialog("Launch", "There is no title specified for homebrew to take over it.\nSelect one by pressing up over it.", { "Ok" }, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -878,11 +896,11 @@ namespace ui
|
|||
{
|
||||
auto uid = qapp->GetSelectedUser();
|
||||
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::UserHasPassword);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::UserHasPassword);
|
||||
writer.Write<AccountUid>(uid);
|
||||
writer.FinishWrite();
|
||||
|
||||
am::QMenuCommandResultReader res;
|
||||
am::MenuCommandResultReader res;
|
||||
res.FinishRead();
|
||||
|
||||
bool has_pass = R_SUCCEEDED(res.GetReadResult());
|
||||
|
@ -929,12 +947,12 @@ namespace ui
|
|||
rc = rc3;
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::ChangeUserPassword);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::ChangeUserPassword);
|
||||
writer.Write<db::PassBlock>(oldpass);
|
||||
writer.Write<db::PassBlock>(newpass);
|
||||
writer.FinishWrite();
|
||||
|
||||
am::QMenuCommandResultReader reader;
|
||||
am::MenuCommandResultReader reader;
|
||||
rc = reader.GetReadResult();
|
||||
}
|
||||
qapp->ShowNotification(R_SUCCEEDED(rc) ? cfg::GetLanguageString(config.main_lang, config.default_lang, "user_pass_change_ok") : cfg::GetLanguageString(config.main_lang, config.default_lang, "user_pass_change_error") + ": " + util::FormatResult(rc));
|
||||
|
@ -946,11 +964,11 @@ namespace ui
|
|||
auto sopt2 = qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "user_pass_remove_full"), cfg::GetLanguageString(config.main_lang, config.default_lang, "user_pass_remove_conf"), { cfg::GetLanguageString(config.main_lang, config.default_lang, "yes"), cfg::GetLanguageString(config.main_lang, config.default_lang, "cancel") }, true);
|
||||
if(sopt2 == 0)
|
||||
{
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::RemoveUserPassword);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::RemoveUserPassword);
|
||||
writer.Write<db::PassBlock>(oldpass);
|
||||
writer.FinishWrite();
|
||||
|
||||
am::QMenuCommandResultReader reader;
|
||||
am::MenuCommandResultReader reader;
|
||||
rc = reader.GetReadResult();
|
||||
|
||||
qapp->ShowNotification(R_SUCCEEDED(rc) ? cfg::GetLanguageString(config.main_lang, config.default_lang, "user_pass_remove_ok") : cfg::GetLanguageString(config.main_lang, config.default_lang, "user_pass_remove_error") + ": " + util::FormatResult(rc));
|
||||
|
@ -979,11 +997,11 @@ namespace ui
|
|||
auto sopt = qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "user_pass_reg"), cfg::GetLanguageString(config.main_lang, config.default_lang, "user_pass_reg_conf"), { cfg::GetLanguageString(config.main_lang, config.default_lang, "yes"), cfg::GetLanguageString(config.main_lang, config.default_lang, "cancel") }, true);
|
||||
if(sopt == 0)
|
||||
{
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::RegisterUserPassword);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::RegisterUserPassword);
|
||||
writer.Write<db::PassBlock>(newpass);
|
||||
writer.FinishWrite();
|
||||
|
||||
am::QMenuCommandResultReader reader;
|
||||
am::MenuCommandResultReader reader;
|
||||
rc = reader.GetReadResult();
|
||||
}
|
||||
}
|
||||
|
@ -998,9 +1016,9 @@ namespace ui
|
|||
*(u32*)in = 7; // Type -> ShowMyProfile
|
||||
memcpy((AccountUid*)(in + 0x8), &uid, sizeof(uid));
|
||||
|
||||
am::LibraryAppletQMenuLaunchWithSimple(AppletId_myPage, 1, in, sizeof(in), NULL, 0, [&]() -> bool
|
||||
am::LibraryAppletDaemonLaunchWithSimple(AppletId_myPage, 1, in, sizeof(in), NULL, 0, [&]() -> bool
|
||||
{
|
||||
return !am::QMenuIsHomePressed();
|
||||
return !am::MenuIsHomePressed();
|
||||
});
|
||||
}
|
||||
else if(sopt == 2)
|
||||
|
@ -1017,7 +1035,7 @@ namespace ui
|
|||
{
|
||||
if(logoff == 2)
|
||||
{
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::TerminateApplication);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::TerminateApplication);
|
||||
writer.FinishWrite();
|
||||
|
||||
this->itemsMenu->UnsetSuspendedItem();
|
||||
|
@ -1046,7 +1064,7 @@ namespace ui
|
|||
webPageCreate(&web, url);
|
||||
webConfigSetWhitelist(&web, ".*");
|
||||
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::OpenWebPage);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::OpenWebPage);
|
||||
writer.Write<WebCommonConfig>(web);
|
||||
writer.FinishWrite();
|
||||
|
||||
|
@ -1086,7 +1104,7 @@ namespace ui
|
|||
arg2.take_over_connection = true;
|
||||
arg2.left_justify = true;
|
||||
|
||||
am::LibraryAppletQMenuLaunchWith(AppletId_controller, 0,
|
||||
am::LibraryAppletDaemonLaunchWith(AppletId_controller, 0,
|
||||
[&](AppletHolder *h)
|
||||
{
|
||||
libappletPushInData(h, &arg1, sizeof(arg1));
|
||||
|
@ -1097,7 +1115,7 @@ namespace ui
|
|||
},
|
||||
[&]() -> bool
|
||||
{
|
||||
return !am::QMenuIsHomePressed();
|
||||
return !am::MenuIsHomePressed();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1117,7 +1135,7 @@ namespace ui
|
|||
|
||||
void MenuLayout::HandleOpenAlbum()
|
||||
{
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::OpenAlbum);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::OpenAlbum);
|
||||
writer.FinishWrite();
|
||||
|
||||
qapp->StopPlayBGM();
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
#include <os/os_Account.hpp>
|
||||
#include <os/os_Misc.hpp>
|
||||
#include <util/util_Convert.hpp>
|
||||
#include <ui/ui_QMenuApplication.hpp>
|
||||
#include <ui/ui_MenuApplication.hpp>
|
||||
#include <fs/fs_Stdio.hpp>
|
||||
#include <net/net_Service.hpp>
|
||||
#include <am/am_LibraryApplet.hpp>
|
||||
|
||||
extern ui::QMenuApplication::Ref qapp;
|
||||
extern ui::MenuApplication::Ref qapp;
|
||||
extern cfg::Theme theme;
|
||||
extern cfg::Config config;
|
||||
|
||||
|
@ -177,9 +177,9 @@ namespace ui
|
|||
*(u32*)in = 1; // 0 = normal, 1 = qlaunch, 2 = starter?
|
||||
u8 out[8] = {0};
|
||||
|
||||
am::LibraryAppletQMenuLaunchWithSimple(AppletId_netConnect, 0, in, sizeof(in), out, sizeof(out), [&]() -> bool
|
||||
am::LibraryAppletDaemonLaunchWithSimple(AppletId_netConnect, 0, in, sizeof(in), out, sizeof(out), [&]() -> bool
|
||||
{
|
||||
return !am::QMenuIsHomePressed();
|
||||
return !am::MenuIsHomePressed();
|
||||
});
|
||||
auto rc = *(u32*)in;
|
||||
|
||||
|
@ -270,7 +270,7 @@ namespace ui
|
|||
{
|
||||
qapp->CommonMenuOnLoop();
|
||||
|
||||
bool ret = am::QMenuIsHomePressed();
|
||||
bool ret = am::MenuIsHomePressed();
|
||||
if(down & KEY_B) ret = true;
|
||||
if(ret)
|
||||
{
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include <ui/ui_StartupLayout.hpp>
|
||||
#include <os/os_Account.hpp>
|
||||
#include <util/util_Convert.hpp>
|
||||
#include <ui/ui_QMenuApplication.hpp>
|
||||
#include <ui/ui_MenuApplication.hpp>
|
||||
#include <fs/fs_Stdio.hpp>
|
||||
|
||||
extern ui::QMenuApplication::Ref qapp;
|
||||
extern ui::MenuApplication::Ref qapp;
|
||||
extern cfg::Theme theme;
|
||||
extern cfg::Config config;
|
||||
|
||||
|
@ -66,11 +66,11 @@ namespace ui
|
|||
rc = rc2;
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::TryLogUser);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::TryLogUser);
|
||||
writer.Write<db::PassBlock>(pass);
|
||||
writer.FinishWrite();
|
||||
|
||||
am::QMenuCommandResultReader reader;
|
||||
am::MenuCommandResultReader reader;
|
||||
rc = reader.GetReadResult();
|
||||
reader.FinishRead();
|
||||
|
||||
|
@ -119,11 +119,11 @@ namespace ui
|
|||
auto [rc, name] = os::GetAccountName(user);
|
||||
if(R_FAILED(rc)) continue;
|
||||
|
||||
am::QMenuCommandWriter writer(am::QDaemonMessage::UserHasPassword);
|
||||
am::MenuCommandWriter writer(am::DaemonMessage::UserHasPassword);
|
||||
writer.Write<AccountUid>(user);
|
||||
writer.FinishWrite();
|
||||
|
||||
am::QMenuCommandResultReader res;
|
||||
am::MenuCommandResultReader res;
|
||||
res.FinishRead();
|
||||
|
||||
bool has_pass = R_SUCCEEDED(res.GetReadResult());
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include <ui/ui_ThemeMenuLayout.hpp>
|
||||
#include <os/os_Account.hpp>
|
||||
#include <util/util_Convert.hpp>
|
||||
#include <ui/ui_QMenuApplication.hpp>
|
||||
#include <ui/ui_MenuApplication.hpp>
|
||||
#include <fs/fs_Stdio.hpp>
|
||||
|
||||
extern ui::QMenuApplication::Ref qapp;
|
||||
extern ui::MenuApplication::Ref qapp;
|
||||
extern cfg::Theme theme;
|
||||
extern cfg::Config config;
|
||||
|
||||
|
@ -105,7 +105,7 @@ namespace ui
|
|||
|
||||
void ThemeMenuLayout::OnInput(u64 down, u64 up, u64 held, pu::ui::Touch pos)
|
||||
{
|
||||
bool ret = am::QMenuIsHomePressed();
|
||||
bool ret = am::MenuIsHomePressed();
|
||||
if(down & KEY_B) ret = true;
|
||||
if(ret)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue