Add IOverlayAppletProxy-specific functions and hid:sys

This commit is contained in:
exelix 2019-02-23 19:27:22 +01:00
parent 0a230bae65
commit 9011f278b6
5 changed files with 290 additions and 0 deletions

View File

@ -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"

View File

@ -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);

View 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);

View File

@ -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
View 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);
}