mirror of
https://github.com/switchbrew/libnx.git
synced 2025-07-05 10:52:15 +02:00
Add IOverlayAppletProxy-specific functions and hid:sys
This commit is contained in:
parent
0a230bae65
commit
9011f278b6
@ -67,6 +67,7 @@ extern "C" {
|
||||
#include "switch/services/usbds.h"
|
||||
#include "switch/services/usbhs.h"
|
||||
#include "switch/services/hid.h"
|
||||
#include "switch/services/hidsys.h"
|
||||
#include "switch/services/irs.h"
|
||||
#include "switch/services/pl.h"
|
||||
#include "switch/services/vi.h"
|
||||
|
@ -468,3 +468,18 @@ u32 appletGetPerformanceMode(void);
|
||||
AppletFocusState appletGetFocusState(void);
|
||||
|
||||
Result appletSetFocusHandlingMode(AppletFocusHandlingMode mode);
|
||||
|
||||
/**
|
||||
* @brief Stops forwaring the input to the foreground app. Works only in the Overlay applet context
|
||||
*/
|
||||
Result appletBeginToWatchShortHomeButtonMessage(void);
|
||||
|
||||
/**
|
||||
* @brief Forwards input to the foreground app. Works only in the Overlay applet context
|
||||
*/
|
||||
Result appletEndToWatchShortHomeButtonMessage(void);
|
||||
|
||||
/**
|
||||
* @brief Get an event that fires when the home button is pressed, doesn't interfere with home menu
|
||||
*/
|
||||
Result appletHomeButtonReaderLockAccessorGetEvent(Event *out_event);
|
20
nx/include/switch/services/hidsys.h
Normal file
20
nx/include/switch/services/hidsys.h
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @file hidsys.h
|
||||
* @brief hid:sys service IPC wrapper.
|
||||
* @author exelix
|
||||
*/
|
||||
#pragma once
|
||||
#include "../types.h"
|
||||
#include "../kernel/event.h"
|
||||
#include "../services/sm.h"
|
||||
|
||||
Result hidSysInitialize(void);
|
||||
|
||||
void hidSysExit(void);
|
||||
|
||||
Result hidSysEnableAppletToGetInput(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Returns an event that fires when the home button is pressed, this will prevent the home menu from opening when the button is pressed.
|
||||
**/
|
||||
Result hidSysAcquireHomeButtonEventHandle(Event* event_out);
|
@ -83,6 +83,8 @@ static Result _appletSelfExit(void);
|
||||
|
||||
static Result _appletExitProcessAndReturn(void);
|
||||
|
||||
static Event HomeButtonReaderLockAccessorEvent = {0};
|
||||
|
||||
Result appletInitialize(void)
|
||||
{
|
||||
atomicIncrement64(&g_refCnt);
|
||||
@ -314,6 +316,8 @@ void appletExit(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eventClose(&HomeButtonReaderLockAccessorEvent);
|
||||
|
||||
eventClose(&g_appletLibraryAppletLaunchableEvent);
|
||||
|
||||
@ -2315,3 +2319,38 @@ bool appletMainLoop(void) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Result appletBeginToWatchShortHomeButtonMessage(void) {
|
||||
if (__nx_applet_type != AppletType_OverlayApplet)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return _appletCmdNoIO(&g_appletIFunctions, 0);
|
||||
}
|
||||
|
||||
Result appletEndToWatchShortHomeButtonMessage(void) {
|
||||
if (__nx_applet_type != AppletType_OverlayApplet)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return _appletCmdNoIO(&g_appletIFunctions, 1);
|
||||
}
|
||||
|
||||
Result appletHomeButtonReaderLockAccessorGetEvent(Event *out_event)
|
||||
{
|
||||
if (eventActive(&HomeButtonReaderLockAccessorEvent))
|
||||
{
|
||||
*out_event = HomeButtonReaderLockAccessorEvent;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Service ILockAccessor = {0};
|
||||
Result rc = _appletGetSession(&g_appletICommonStateGetter, &ILockAccessor, 30);
|
||||
if (!R_SUCCEEDED(rc))
|
||||
return rc;
|
||||
|
||||
rc = _appletGetEvent(&ILockAccessor, &HomeButtonReaderLockAccessorEvent, 3,true);
|
||||
if (R_SUCCEEDED(rc))
|
||||
*out_event = HomeButtonReaderLockAccessorEvent;
|
||||
|
||||
serviceClose(&ILockAccessor);
|
||||
return rc;
|
||||
}
|
||||
|
215
nx/source/services/hidsys.c
Normal file
215
nx/source/services/hidsys.c
Normal file
@ -0,0 +1,215 @@
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
#include "result.h"
|
||||
#include "arm/atomics.h"
|
||||
#include "kernel/ipc.h"
|
||||
#include "kernel/shmem.h"
|
||||
#include "kernel/rwlock.h"
|
||||
#include "kernel/event.h"
|
||||
#include "services/applet.h"
|
||||
#include "services/hidsys.h"
|
||||
#include "services/sm.h"
|
||||
|
||||
static Service g_hidSysSrv;
|
||||
static u64 g_hidSysRefCnt;
|
||||
|
||||
static Event g_hidSysHomeEvent = {0};
|
||||
static Event g_hidSysCaptureEvent = {0};
|
||||
static Event g_hidSysSleeptEvent = {0};
|
||||
|
||||
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) {
|
||||
eventClose(&g_hidSysHomeEvent);
|
||||
eventClose(&g_hidSysCaptureEvent);
|
||||
eventClose(&g_hidSysSleeptEvent);
|
||||
|
||||
serviceClose(&g_hidSysSrv);
|
||||
}
|
||||
}
|
||||
|
||||
Result hidSysEnableAppletToGetInput(bool enable) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct CmdStruct{
|
||||
u64 magic;
|
||||
u64 cmdid;
|
||||
bool permitInput;
|
||||
u64 appletResourceUserId;
|
||||
} *cmdStruct;
|
||||
|
||||
cmdStruct = (struct CmdStruct*) serviceIpcPrepareHeader(&g_hidSysSrv, &c, sizeof(*cmdStruct));
|
||||
|
||||
cmdStruct->magic = SFCI_MAGIC;
|
||||
cmdStruct->cmdid = 503;
|
||||
cmdStruct->permitInput = enable;
|
||||
cmdStruct->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) {
|
||||
if (eventActive(&g_hidSysHomeEvent))
|
||||
{
|
||||
*event_out = g_hidSysHomeEvent;
|
||||
return 0;
|
||||
}
|
||||
Result rc = _hidSysGetEvent(&g_hidSysHomeEvent, 101, false);
|
||||
if (R_SUCCEEDED(rc))
|
||||
*event_out = g_hidSysHomeEvent;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//These functions don't seem to work in the overlaydisp applet context
|
||||
Result hidSysAcquireCaptureButtonEventHandle(Event* event_out) {
|
||||
if (eventActive(&g_hidSysCaptureEvent))
|
||||
{
|
||||
*event_out = g_hidSysCaptureEvent;
|
||||
return 0;
|
||||
}
|
||||
Result rc = _hidSysGetEvent(&g_hidSysCaptureEvent, 141, false);
|
||||
if (R_SUCCEEDED(rc))
|
||||
*event_out = g_hidSysCaptureEvent;
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result hidSysAcquireSleepButtonEventHandle(Event* event_out) {
|
||||
if (eventActive(&g_hidSysSleeptEvent))
|
||||
{
|
||||
*event_out = g_hidSysSleeptEvent;
|
||||
return 0;
|
||||
}
|
||||
Result rc = _hidSysGetEvent(&g_hidSysSleeptEvent, 121, false);
|
||||
if (R_SUCCEEDED(rc))
|
||||
*event_out = g_hidSysSleeptEvent;
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result hidSysActivateHomeButton(void) {
|
||||
return _hidSysCmdWithResIdAndPid(111);
|
||||
}
|
||||
|
||||
Result hidSysActivateSleepButton(void) {
|
||||
return _hidSysCmdWithResIdAndPid(131);
|
||||
}
|
||||
|
||||
Result hidSysActivateCaptureButton(void) {
|
||||
return _hidSysCmdWithResIdAndPid(151);
|
||||
}
|
Loading…
Reference in New Issue
Block a user