Added appletGetDesiredLanguage(). In set-serv('set'), added support for all language/region commands, etc.

This commit is contained in:
yellows8 2018-02-26 12:32:55 -05:00
parent 47fa88d838
commit f07d09aeb0
4 changed files with 378 additions and 2 deletions

View File

@ -51,6 +51,8 @@ Result appletGetAppletResourceUserId(u64 *out);
void appletNotifyRunning(u8 *out);
Result appletCreateManagedDisplayLayer(u64 *out);
Result appletGetDesiredLanguage(u64 *LanguageCode);
/**
* @brief Controls whether screenshot-capture is allowed.
* @param val 0 = disable, 1 = enable.

View File

@ -1,4 +1,10 @@
// Copyright 2018 plutoo
/**
* @file set.h
* @brief Settings services IPC wrapper.
* @author plutoo
* @author yellows8
* @copyright libnx Authors
*/
#include "../result.h"
typedef enum {
@ -6,6 +12,54 @@ typedef enum {
ColorSetId_Dark=1
} ColorSetId;
/// IDs for Language.
typedef enum
{
SetLanguage_JA = 0, ///< Japanese
SetLanguage_ENUS = 1, ///< US English
SetLanguage_FR = 2, ///< French
SetLanguage_DE = 3, ///< German
SetLanguage_IT = 4, ///< Italian
SetLanguage_ES = 5, ///< Spanish
SetLanguage_ZHCN = 6, ///< Simplified Chinese
SetLanguage_KO = 7, ///< Korean
SetLanguage_NL = 8, ///< Dutch
SetLanguage_PT = 9, ///< Portugese
SetLanguage_RU = 10, ///< Russian
SetLanguage_ZHTW = 11, ///< Traditional Chinese
SetLanguage_ENGB = 12, ///< GB English
SetLanguage_FRCA = 13, ///< CA French
SetLanguage_ES419 = 14, ///< {?} Spanish
} SetLanguage;
Result setInitialize(void);
void setExit(void);
/// Converts LanguageCode to Language.
Result setMakeLanguage(u64 LanguageCode, s32 *Language);
/// Converts Language to LanguageCode.
Result setMakeLanguageCode(s32 Language, u64 *LanguageCode);
/// Gets the current system LanguageCode.
/// Normally this should be used instead of \ref setGetLanguageCode.
/// LanguageCode is a string, see here: http://switchbrew.org/index.php?title=Settings_services#LanguageCode
Result setGetSystemLanguage(u64 *LanguageCode);
/// Gets the current LanguageCode, \ref setGetSystemLanguage should be used instead normally.
Result setGetLanguageCode(u64 *LanguageCode);
/// Gets available LanguageCodes.
/// On system-version <4.0.0, max_entries is set to the output from \ref setGetAvailableLanguageCodeCount if max_entries is larger than that.
Result setGetAvailableLanguageCodes(s32 *total_entries, u64 *LanguageCodes, size_t max_entries);
/// Gets total available LanguageCodes.
/// Output total is overridden with value 0 if the total is <0.
Result setGetAvailableLanguageCodeCount(s32 *total);
/// Gets the RegionCode.
Result setGetRegionCode(s32 *RegionCode);
Result setsysInitialize(void);
void setsysExit(void);

View File

@ -503,6 +503,45 @@ Result appletGetAppletResourceUserId(u64 *out) {
return 0;
}
Result appletGetDesiredLanguage(u64 *LanguageCode) {
IpcCommand c;
ipcInitialize(&c);
if (!serviceIsActive(&g_appletSrv) || __nx_applet_type!=AppletType_Application)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 21;
Result rc = serviceIpcDispatch(&g_appletIFunctions);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
u64 LanguageCode;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc) && LanguageCode) {
*LanguageCode = resp->LanguageCode;
}
}
return rc;
}
void appletNotifyRunning(u8 *out) {
IpcCommand c;
ipcInitialize(&c);

View File

@ -1,12 +1,42 @@
// Copyright 2018 plutoo
/**
* @file set.h
* @brief Settings services IPC wrapper.
* @author plutoo
* @author yellows8
* @copyright libnx Authors
*/
#include "types.h"
#include "result.h"
#include "ipc.h"
#include "kernel/detect.h"
#include "services/set.h"
#include "services/sm.h"
#include "services/applet.h"
static Service g_setSrv;
static Service g_setsysSrv;
static bool g_setLanguageCodesInitialized;
static u64 g_setLanguageCodes[0x40];
static s32 g_setLanguageCodesTotal;
static Result _setMakeLanguageCode(s32 Language, u64 *LanguageCode);
Result setInitialize(void)
{
if (serviceIsActive(&g_setSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
g_setLanguageCodesInitialized = 0;
return smGetService(&g_setSrv, "set");
}
void setExit(void)
{
serviceClose(&g_setSrv);
}
Result setsysInitialize(void)
{
if (serviceIsActive(&g_setsysSrv))
@ -20,6 +50,257 @@ void setsysExit(void)
serviceClose(&g_setsysSrv);
}
static Result setInitializeLanguageCodesCache(void) {
if (g_setLanguageCodesInitialized) return 0;
Result rc = 0;
rc = setGetAvailableLanguageCodes(&g_setLanguageCodesTotal, g_setLanguageCodes, sizeof(g_setLanguageCodes)/sizeof(u64));
if (R_FAILED(rc)) return rc;
if (g_setLanguageCodesTotal < 0) g_setLanguageCodesTotal = 0;
g_setLanguageCodesInitialized = 1;
return rc;
}
Result setMakeLanguage(u64 LanguageCode, s32 *Language) {
Result rc = setInitializeLanguageCodesCache();
if (R_FAILED(rc)) return rc;
s32 i;
rc = MAKERESULT(Module_Libnx, LibnxError_BadInput);
for (i=0; i<g_setLanguageCodesTotal; i++) {
if (g_setLanguageCodes[i] == LanguageCode) {
*Language = i;
return 0;
}
}
return rc;
}
Result setMakeLanguageCode(s32 Language, u64 *LanguageCode) {
Result rc = setInitializeLanguageCodesCache();
if (R_FAILED(rc)) return rc;
if (Language < 0)
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
if (Language >= g_setLanguageCodesTotal) {
if (!kernelAbove400()) return MAKERESULT(Module_Libnx, LibnxError_BadInput);
return _setMakeLanguageCode(Language, LanguageCode);
}
*LanguageCode = g_setLanguageCodes[Language];
return rc;
}
Result setGetSystemLanguage(u64 *LanguageCode) {
//This is disabled because the returned LanguageCode can differ from the system language, for example ja instead of {English}.
/*Result rc = appletGetDesiredLanguage(LanguageCode);
if (R_SUCCEEDED(rc)) return rc;*/
return setGetLanguageCode(LanguageCode);
}
Result setGetLanguageCode(u64 *LanguageCode) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 0;
Result rc = serviceIpcDispatch(&g_setSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
u64 LanguageCode;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc) && LanguageCode) *LanguageCode = resp->LanguageCode;
}
return rc;
}
Result setGetAvailableLanguageCodes(s32 *total_entries, u64 *LanguageCodes, size_t max_entries) {
IpcCommand c;
ipcInitialize(&c);
Result rc=0;
bool new_cmd = kernelAbove400();
if (!new_cmd) {//On system-version <4.0.0 the sysmodule will close the session if max_entries is too large.
s32 tmptotal = 0;
rc = setGetAvailableLanguageCodeCount(&tmptotal);
if (R_FAILED(rc)) return rc;
if (max_entries > (size_t)tmptotal) max_entries = (size_t)tmptotal;
}
size_t bufsize = max_entries*sizeof(u64);
if (!new_cmd) {
ipcAddRecvStatic(&c, LanguageCodes, bufsize, 0);
}
else {
ipcAddRecvBuffer(&c, LanguageCodes, bufsize, 0);
}
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = new_cmd ? 5 : 1;
rc = serviceIpcDispatch(&g_setSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
s32 total_entries;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc) && total_entries) *total_entries = resp->total_entries;
}
return rc;
}
static Result _setMakeLanguageCode(s32 Language, u64 *LanguageCode) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
s32 Language;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 2;
raw->Language = Language;
Result rc = serviceIpcDispatch(&g_setSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
u64 LanguageCode;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc) && LanguageCode) *LanguageCode = resp->LanguageCode;
}
return rc;
}
Result setGetAvailableLanguageCodeCount(s32 *total) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = kernelAbove400() ? 6 : 3;
Result rc = serviceIpcDispatch(&g_setSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
s32 total;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc) && total) {
*total = resp->total;
if (*total < 0) *total = 0;
}
}
return rc;
}
Result setGetRegionCode(s32 *RegionCode) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 4;
Result rc = serviceIpcDispatch(&g_setSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
s32 RegionCode;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc) && RegionCode) *RegionCode = resp->RegionCode;
}
return rc;
}
Result setsysGetColorSetId(ColorSetId* out)
{
IpcCommand c;