mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
Implemented apm.
This commit is contained in:
parent
fa318656b3
commit
1dda414f31
@ -26,6 +26,7 @@ extern "C" {
|
||||
#include <switch/services/sm.h>
|
||||
#include <switch/services/fs.h>
|
||||
#include <switch/services/acc.h>
|
||||
#include <switch/services/apm.h>
|
||||
#include <switch/services/applet.h>
|
||||
#include <switch/services/binder.h>
|
||||
#include <switch/services/bsd.h>
|
||||
|
7
nx/include/switch/services/apm.h
Normal file
7
nx/include/switch/services/apm.h
Normal file
@ -0,0 +1,7 @@
|
||||
/// These are used internally by applet.
|
||||
|
||||
Result apmInitialize(void);
|
||||
void apmExit(void);
|
||||
|
||||
Result apmSetPerformanceConfiguration(u32 PerformanceMode, u32 PerformanceConfiguration);
|
||||
Result apmGetPerformanceConfiguration(u32 PerformanceMode, u32 *PerformanceConfiguration);
|
144
nx/source/services/apm.c
Normal file
144
nx/source/services/apm.c
Normal file
@ -0,0 +1,144 @@
|
||||
#include <string.h>
|
||||
#include <switch.h>
|
||||
|
||||
static Handle g_apmServiceSession = INVALID_HANDLE;
|
||||
static Handle g_apmISession = INVALID_HANDLE;
|
||||
|
||||
static Result _apmGetSession(Handle sessionhandle, Handle* handle_out, u64 cmd_id);
|
||||
|
||||
Result apmInitialize(void) {
|
||||
if (g_apmServiceSession != INVALID_HANDLE) return 0;
|
||||
|
||||
Result rc = 0;
|
||||
|
||||
rc = smGetService(&g_apmServiceSession, "apm:p");
|
||||
if (R_FAILED(rc)) rc = smGetService(&g_apmServiceSession, "apm");
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = _apmGetSession(g_apmServiceSession, &g_apmISession, 0);//OpenSession. Official sw doesn't open this until using commands which need it, when it wasn't already opened.
|
||||
|
||||
if (R_FAILED(rc)) apmExit();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void apmExit(void)
|
||||
{
|
||||
if (g_apmServiceSession == INVALID_HANDLE) return;
|
||||
|
||||
if (g_apmServiceSession != INVALID_HANDLE) {
|
||||
svcCloseHandle(g_apmServiceSession);
|
||||
g_apmServiceSession = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (g_apmISession != INVALID_HANDLE) {
|
||||
svcCloseHandle(g_apmISession);
|
||||
g_apmISession = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
static Result _apmGetSession(Handle sessionhandle, Handle* handle_out, u64 cmd_id) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = cmd_id;
|
||||
|
||||
Result rc = ipcDispatch(sessionhandle);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
*handle_out = r.Handles[0];
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result apmSetPerformanceConfiguration(u32 PerformanceMode, u32 PerformanceConfiguration) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u32 PerformanceMode;
|
||||
u32 PerformanceConfiguration;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 0;
|
||||
raw->PerformanceMode = PerformanceMode;
|
||||
raw->PerformanceConfiguration = PerformanceConfiguration;
|
||||
|
||||
Result rc = ipcDispatch(g_apmISession);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result apmGetPerformanceConfiguration(u32 PerformanceMode, u32 *PerformanceConfiguration) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u32 PerformanceMode;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 1;
|
||||
raw->PerformanceMode = PerformanceMode;
|
||||
|
||||
Result rc = ipcDispatch(g_apmISession);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u32 PerformanceConfiguration;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && PerformanceConfiguration) *PerformanceConfiguration = resp->PerformanceConfiguration;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
__attribute__((weak)) u32 __nx_applet_type = APPLET_TYPE_Default;
|
||||
__attribute__((weak)) bool __nx_applet_auto_notifyrunning = true;
|
||||
__attribute__((weak)) u8 __nx_applet_AppletAttribute[0x80];
|
||||
__attribute__((weak)) u32 __nx_applet_PerformanceConfiguration[2] = {/*0x92220008*//*0x20004*//*0x92220007*/0, 0};
|
||||
|
||||
static Handle g_appletServiceSession = INVALID_HANDLE;
|
||||
static Handle g_appletProxySession = INVALID_HANDLE;
|
||||
@ -57,6 +58,7 @@ Result appletInitialize(void) {
|
||||
Result rc = 0;
|
||||
Handle prochandle = CUR_PROCESS_HANDLE;
|
||||
s32 tmpindex=0;
|
||||
u32 i;
|
||||
u32 msg=0;
|
||||
|
||||
if (__nx_applet_type==APPLET_TYPE_None) return 0;
|
||||
@ -153,6 +155,15 @@ Result appletInitialize(void) {
|
||||
if (R_SUCCEEDED(rc)) rc = _appletSetOperationModeChangedNotification(1);
|
||||
if (R_SUCCEEDED(rc)) rc = _appletSetPerformanceModeChangedNotification(1);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = apmInitialize();
|
||||
|
||||
if (R_SUCCEEDED(rc)) {//Official apps aren't known to use apmSetPerformanceConfiguration with mode=1.
|
||||
for (i=0; i<2; i++) {//This is broken with the regular "apm" service.
|
||||
if (__nx_applet_PerformanceConfiguration[i]) rc = apmSetPerformanceConfiguration(i, __nx_applet_PerformanceConfiguration[i]);
|
||||
if (R_FAILED(rc)) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (R_FAILED(rc)) appletExit();
|
||||
|
||||
return rc;
|
||||
@ -162,6 +173,8 @@ void appletExit(void)
|
||||
{
|
||||
if (g_appletServiceSession == INVALID_HANDLE) return;
|
||||
|
||||
apmExit();
|
||||
|
||||
if (g_appletMessageEventHandle != INVALID_HANDLE) {
|
||||
svcCloseHandle(g_appletMessageEventHandle);
|
||||
g_appletMessageEventHandle = INVALID_HANDLE;
|
||||
|
Loading…
Reference in New Issue
Block a user