diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h index f0555ea4..0267a31d 100644 --- a/nx/include/switch/services/hid.h +++ b/nx/include/switch/services/hid.h @@ -8,6 +8,7 @@ #pragma once #include #include "../types.h" +#include "../kernel/event.h" #include "../services/sm.h" // Begin enums and output structs @@ -671,6 +672,11 @@ Result hidSetSupportedNpadIdType(HidControllerID *buf, size_t count); /// Sets which controller types are supported. This is automatically called with all types in \ref hidInitialize. Result hidSetSupportedNpadStyleSet(HidControllerType type); +/// Gets an event with the specified autoclear for the input controller. +/// The user *must* close the event when finished with it / before the app exits. +/// This is signaled when the \ref hidGetControllerType output is updated for the controller. +Result hidAcquireNpadStyleSetUpdateEventHandle(HidControllerID id, Event* event, bool autoclear); + /// Sets the hold-type, see \ref HidJoyHoldType. Result hidSetNpadJoyHoldType(HidJoyHoldType type); diff --git a/nx/source/services/hid.c b/nx/source/services/hid.c index e1770843..f674f5a4 100644 --- a/nx/source/services/hid.c +++ b/nx/source/services/hid.c @@ -5,6 +5,7 @@ #include "kernel/ipc.h" #include "kernel/shmem.h" #include "kernel/rwlock.h" +#include "kernel/event.h" #include "services/applet.h" #include "services/hid.h" #include "services/sm.h" @@ -160,6 +161,12 @@ void hidReset(void) rwlockWriteUnlock(&g_hidLock); } +static u32 _hidControllerIDToOfficial(HidControllerID id) { + if (id < CONTROLLER_HANDHELD) return id; + if (id == CONTROLLER_HANDHELD) return 0x20; + return 0x10;//For CONTROLLER_UNKNOWN and invalid values return this. +} + Service* hidGetSessionService(void) { return &g_hidSrv; } @@ -831,6 +838,56 @@ static Result _hidDeactivateNpad(void) { return _hidCmdWithNoInput(104); } +Result hidAcquireNpadStyleSetUpdateEventHandle(HidControllerID id, Event* event, bool autoclear) { + Result rc; + u64 AppletResourceUserId; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + AppletResourceUserId = 0; + + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 id; + u64 AppletResourceUserId; + u64 event_ptr; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 106; + raw->id = _hidControllerIDToOfficial(id); + raw->AppletResourceUserId = AppletResourceUserId; + raw->event_ptr = 0;//Official sw sets this to a ptr, which the sysmodule doesn't seem to use. + + rc = serviceIpcDispatch(&g_hidSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + eventLoadRemote(event, r.Handles[0], autoclear); + } + } + + return rc; +} + Result hidSetNpadJoyHoldType(HidJoyHoldType type) { return _hidCmdWithInputU64(120, type); }