libnx/nx/source/services/hidsys.c
Ac_K a3381d3d64 hidsysSetNotificationLedPattern cleanup
Fix a copy/paste issue in hidsysSetNotificationLedPattern
2019-06-01 16:00:28 -04:00

303 lines
6.7 KiB
C

#include <string.h>
#include "types.h"
#include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h"
#include "kernel/event.h"
#include "services/applet.h"
#include "services/hidsys.h"
#include "services/hid.h"
#include "services/sm.h"
#include "runtime/hosversion.h"
static Service g_hidsysSrv;
static u64 g_hidsysRefCnt;
static u64 g_hidsysAppletResourceUserId = 0;
Result hidsysInitialize(void) {
atomicIncrement64(&g_hidsysRefCnt);
if (serviceIsActive(&g_hidsysSrv))
return 0;
Result rc = smGetService(&g_hidsysSrv, "hid:sys");
if (R_FAILED(rc))
return rc;
rc = appletGetAppletResourceUserId(&g_hidsysAppletResourceUserId);
if (R_FAILED(rc))
g_hidsysAppletResourceUserId = 0;
return 0;
}
void hidsysExit(void) {
if (atomicDecrement64(&g_hidsysRefCnt) == 0) {
serviceClose(&g_hidsysSrv);
}
}
Result hidsysEnableAppletToGetInput(bool enable) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmdid;
u8 permitInput;
u64 appletResourceUserId;
} *raw;
raw = serviceIpcPrepareHeader(&g_hidsysSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmdid = 503;
raw->permitInput = enable != 0;
raw->appletResourceUserId = g_hidsysAppletResourceUserId;
Result rc = serviceIpcDispatch(&g_hidsysSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(&g_hidsysSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
}
return rc;
}
static Result _hidsysCmdWithResIdAndPid(u64 cmd_id) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u64 AppletResourceUserId;
} *raw;
ipcSendPid(&c);
raw = serviceIpcPrepareHeader(&g_hidsysSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = cmd_id;
raw->AppletResourceUserId = g_hidsysAppletResourceUserId;
Result rc = serviceIpcDispatch(&g_hidsysSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(&g_hidsysSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
}
return rc;
}
static Result _hidsysGetHandle(Handle* handle_out, u64 cmd_id) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u64 AppletResourceUserId;
} *raw;
ipcSendPid(&c);
raw = serviceIpcPrepareHeader(&g_hidsysSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = cmd_id;
raw->AppletResourceUserId = g_hidsysAppletResourceUserId;
Result rc = serviceIpcDispatch(&g_hidsysSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(&g_hidsysSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
*handle_out = r.Handles[0];
}
}
return rc;
}
static Result _hidsysGetEvent(Event* event_out, u64 cmd_id, bool autoclear) {
Handle tmp_handle=0;
Result rc = 0;
rc = _hidsysGetHandle(&tmp_handle, cmd_id);
if (R_SUCCEEDED(rc)) eventLoadRemote(event_out, tmp_handle, autoclear);
return rc;
}
Result hidsysAcquireHomeButtonEventHandle(Event* event_out) {
return _hidsysGetEvent(event_out, 101, false);
}
//These functions don't seem to work in the overlaydisp applet context
Result hidsysAcquireCaptureButtonEventHandle(Event* event_out) {
return _hidsysGetEvent(event_out, 141, false);
}
Result hidsysAcquireSleepButtonEventHandle(Event* event_out) {
return _hidsysGetEvent(event_out, 121, false);
}
Result hidsysActivateHomeButton(void) {
return _hidsysCmdWithResIdAndPid(111);
}
Result hidsysActivateSleepButton(void) {
return _hidsysCmdWithResIdAndPid(131);
}
Result hidsysActivateCaptureButton(void) {
return _hidsysCmdWithResIdAndPid(151);
}
Result hidsysGetUniquePadsFromNpad(HidControllerID id, u64 *UniquePadIds, size_t count, size_t *total_entries) {
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
Result rc;
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u32 id;
} PACKED *raw;
ipcAddRecvStatic(&c, UniquePadIds, sizeof(u64)*count, 0);
raw = serviceIpcPrepareHeader(&g_hidsysSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 321;
raw->id = hidControllerIDToOfficial(id);
rc = serviceIpcDispatch(&g_hidsysSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
u64 total_entries;
} *resp;
serviceIpcParse(&g_hidsysSrv, &r, sizeof(*resp));
resp = r.Raw;
if (R_SUCCEEDED(rc) && total_entries) *total_entries = resp->total_entries;
}
return rc;
}
Result hidsysGetUniquePadIds(u64 *UniquePadIds, size_t count, size_t *total_entries) {
Result rc;
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
ipcAddRecvStatic(&c, UniquePadIds, sizeof(u64)*count, 0);
raw = serviceIpcPrepareHeader(&g_hidsysSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 703;
rc = serviceIpcDispatch(&g_hidsysSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
u64 total_entries;
} *resp;
serviceIpcParse(&g_hidsysSrv, &r, sizeof(*resp));
resp = r.Raw;
if (R_SUCCEEDED(rc) && total_entries) *total_entries = resp->total_entries;
}
return rc;
}
Result hidsysSetNotificationLedPattern(const HidsysNotificationLedPattern *pattern, u64 UniquePadId) {
if (hosversionBefore(7,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
Result rc;
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
HidsysNotificationLedPattern pattern;
u64 UniquePadId;
} *raw;
raw = serviceIpcPrepareHeader(&g_hidsysSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 830;
memcpy(&raw->pattern, pattern, sizeof(*pattern));
raw->UniquePadId = UniquePadId;
rc = serviceIpcDispatch(&g_hidsysSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(&g_hidsysSrv, &r, sizeof(*resp));
resp = r.Raw;
}
return rc;
}