From f13b75d87c232ffe761630ea3a896428bd722e30 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Tue, 16 Jul 2019 12:27:46 -0400 Subject: [PATCH] Added appletGetPseudoDeviceId and appletSetApplicationAlbumUserData. Use ipcQueryPointerBufferSize for ISelfController in appletInitialize. Moved appletIsIlluminanceAvailable in applet.h to match cmd order. --- nx/include/switch/services/applet.h | 23 ++++++-- nx/source/services/applet.c | 82 +++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 4 deletions(-) diff --git a/nx/include/switch/services/applet.h b/nx/include/switch/services/applet.h index d5b8fd64..72dd4eac 100644 --- a/nx/include/switch/services/applet.h +++ b/nx/include/switch/services/applet.h @@ -240,6 +240,13 @@ Result appletEndBlockingHomeButton(void); void appletNotifyRunning(u8 *out); +/** + * @brief Gets the PseudoDeviceId. This is derived from the output of a ns command, and from data in the host title control.nacp. + * @note Only available with AppletType_*Application on 2.0.0+. + * @param[out] out Output PseudoDeviceId. + */ +Result appletGetPseudoDeviceId(u128 *out); + /// Set media playback state. /// If state is set to true, screen dimming and auto sleep is disabled. /// For *Application, this uses cmd SetMediaPlaybackStateForApplication, otherwise cmd SetMediaPlaybackState is used. @@ -358,6 +365,13 @@ Result appletCreateManagedDisplayLayer(u64 *out); */ Result appletGetCurrentIlluminance(float *fLux); +/** + * @brief Gets whether Illuminance is available. + * @note Only available with [3.0.0+]. + * @param out Output flag + */ +Result appletIsIlluminanceAvailable(bool *out); + /** * @brief Gets the current Illuminance from the light sensor. Same as \ref appletGetCurrentIlluminance except for the additional param. * @note Only available with [5.0.0+]. @@ -367,11 +381,12 @@ Result appletGetCurrentIlluminance(float *fLux); Result appletGetCurrentIlluminanceEx(bool *bOverLimit, float *fLux); /** - * @brief Gets whether Illuminance is available. - * @note Only available with [3.0.0+]. - * @param out Output flag + * @brief Sets the Application AlbumUserData. + * @note Only available with [8.0.0+]. + * @param[in] buffer Buffer containing arbitrary UserData. + * @param[in] size Buffer size, must be <=0x400. */ -Result appletIsIlluminanceAvailable(bool *out); +Result appletSetApplicationAlbumUserData(const void* buffer, size_t size); /** * @brief Stops forwarding the input to the foreground app, works only in the Overlay applet context. diff --git a/nx/source/services/applet.c b/nx/source/services/applet.c index 9926acaa..7aac920d 100644 --- a/nx/source/services/applet.c +++ b/nx/source/services/applet.c @@ -42,6 +42,8 @@ static Service g_appletIAudioController; static Service g_appletIDisplayController; static Service g_appletIDebugFunctions; +static size_t g_appletISelfController_ptrbufsize; + static Event g_appletMessageEvent; static u64 g_appletResourceUserId = 0; @@ -197,6 +199,9 @@ Result appletInitialize(void) if (R_SUCCEEDED(rc)) rc = _appletGetSession(&g_appletProxySession, &g_appletIDebugFunctions, 1000); + if (R_SUCCEEDED(rc)) + rc = ipcQueryPointerBufferSize(g_appletISelfController.handle, &g_appletISelfController_ptrbufsize); + // ICommonStateGetter::GetEventHandle if (R_SUCCEEDED(rc)) rc = _appletGetEvent(&g_appletICommonStateGetter, &g_appletMessageEvent, 0, false); @@ -1438,6 +1443,46 @@ void appletNotifyRunning(u8 *out) { if (R_FAILED(rc)) fatalSimple(MAKERESULT(Module_Libnx, LibnxError_BadAppletNotifyRunning)); } +Result appletGetPseudoDeviceId(u128 *out) { + IpcCommand c; + ipcInitialize(&c); + + if (!serviceIsActive(&g_appletSrv) || !_appletIsApplication()) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = serviceIpcPrepareHeader(&g_appletIFunctions, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 50; + + Result rc = serviceIpcDispatch(&g_appletIFunctions); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + struct { + u64 magic; + u64 result; + u128 out; + } *resp; + + serviceIpcParse(&g_appletIFunctions, &r, sizeof(*resp)); + resp = r.Raw; + + rc = resp->result; + if (R_SUCCEEDED(rc) && out) *out = resp->out; + } + + return rc; +} + Result appletSetMediaPlaybackState(bool state) { if (!serviceIsActive(&g_appletSrv)) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); @@ -2352,6 +2397,43 @@ Result appletGetCurrentIlluminanceEx(bool *bOverLimit, float *fLux) { return rc; } +Result appletSetApplicationAlbumUserData(const void* buffer, size_t size) { + if (hosversionBefore(8,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + IpcCommand c; + ipcInitialize(&c); + + ipcAddSendSmart(&c, g_appletISelfController_ptrbufsize, buffer, size, 0); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = serviceIpcPrepareHeader(&g_appletISelfController, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 110; + + Result rc = serviceIpcDispatch(&g_appletISelfController); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + struct { + u64 magic; + u64 result; + } *resp; + + serviceIpcParse(&g_appletISelfController, &r, sizeof(*resp)); + resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + // ILibraryAppletSelfAccessor static Result _appletExitProcessAndReturn(void) {