From d62b909757e41cad5ad4da800d520aef13a0894a Mon Sep 17 00:00:00 2001 From: yellows8 Date: Fri, 27 Oct 2017 17:10:48 -0400 Subject: [PATCH] Added hid. --- nx/include/switch.h | 1 + nx/include/switch/services/hid.h | 5 ++ nx/source/services/hid.c | 145 +++++++++++++++++++++++++++++++ nx/source/system/init.c | 2 + 4 files changed, 153 insertions(+) create mode 100644 nx/include/switch/services/hid.h create mode 100644 nx/source/services/hid.c diff --git a/nx/include/switch.h b/nx/include/switch.h index ec229fe2..27dff05c 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -26,6 +26,7 @@ extern "C" { #include #include #include +#include #include #include diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h new file mode 100644 index 00000000..e7153900 --- /dev/null +++ b/nx/include/switch/services/hid.h @@ -0,0 +1,5 @@ +Result hidInitialize(void); +void hidExit(void); + +Handle hidGetSessionService(void); +void* hidGetSharedmemAddr(void); diff --git a/nx/source/services/hid.c b/nx/source/services/hid.c new file mode 100644 index 00000000..1fa86ffb --- /dev/null +++ b/nx/source/services/hid.c @@ -0,0 +1,145 @@ +#include +#include + +static Handle g_hidServiceSession = INVALID_HANDLE; +static Handle g_hidIAppletResource = INVALID_HANDLE; +static SharedMemory g_hidSharedmem; + +static Result _hidCreateAppletResource(Handle sessionhandle, Handle* handle_out, u64 AppletResourceUserId); +static Result _hidGetSharedMemoryHandle(Handle sessionhandle, Handle* handle_out); + +Result hidInitialize(void) { + if (g_hidServiceSession != INVALID_HANDLE) return MAKERESULT(MODULE_LIBNX, LIBNX_ALREADYINITIALIZED); + + Result rc = 0; + u64 AppletResourceUserId = 0; + Handle sharedmem_handle=0; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) return rc; + + rc = smGetService(&g_hidServiceSession, "hid"); + if (R_FAILED(rc)) return rc; + + rc = _hidCreateAppletResource(g_hidServiceSession, &g_hidIAppletResource, AppletResourceUserId); + + if (R_SUCCEEDED(rc)) rc = _hidGetSharedMemoryHandle(g_hidIAppletResource, &sharedmem_handle); + + if (R_SUCCEEDED(rc)) { + shmemLoadRemote(&g_hidSharedmem, sharedmem_handle, 0x40000, PERM_R); + + rc = shmemMap(&g_hidSharedmem); + + if (R_FAILED(rc)) svcCloseHandle(sharedmem_handle); + } + + if (R_FAILED(rc)) { + if (g_hidServiceSession != INVALID_HANDLE) svcCloseHandle(g_hidServiceSession); + if (g_hidIAppletResource != INVALID_HANDLE) svcCloseHandle(g_hidIAppletResource); + + g_hidServiceSession = INVALID_HANDLE; + g_hidIAppletResource = INVALID_HANDLE; + } + + return rc; +} + +void hidExit(void) +{ + if (g_hidServiceSession == INVALID_HANDLE) return; + + if (g_hidServiceSession != INVALID_HANDLE) { + svcCloseHandle(g_hidServiceSession); + g_hidServiceSession = INVALID_HANDLE; + } + + if (g_hidIAppletResource != INVALID_HANDLE) { + svcCloseHandle(g_hidIAppletResource); + g_hidIAppletResource = INVALID_HANDLE; + } + + shmemClose(&g_hidSharedmem); +} + +Handle hidGetSessionService(void) { + return g_hidServiceSession; +} + +void* hidGetSharedmemAddr(void) { + return shmemGetAddr(&g_hidSharedmem); +} + +static Result _hidCreateAppletResource(Handle sessionhandle, Handle* handle_out, u64 AppletResourceUserId) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 0; + raw->AppletResourceUserId = AppletResourceUserId; + + 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; +} + +static Result _hidGetSharedMemoryHandle(Handle sessionhandle, Handle* handle_out) { + 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 = 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; +} + diff --git a/nx/source/system/init.c b/nx/source/system/init.c index 08a0aed3..1d7d9094 100644 --- a/nx/source/system/init.c +++ b/nx/source/system/init.c @@ -34,11 +34,13 @@ void __attribute__((weak)) __appInit(void) smInitialize(); fsInitialize(); appletInitialize(); + hidInitialize(); } void __attribute__((weak)) __appExit(void) { // Cleanup default services. + hidExit(); appletExit(); fsExit(); smExit();