Add some functions from IOverlayAppletProxy and hid:sys (#242)

This commit is contained in:
exelix 2019-02-27 16:17:03 +01:00 committed by fincs
parent d2c24bbe10
commit ad5b8c019f
5 changed files with 250 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

@ -252,6 +252,24 @@ Result appletSetScreenShotPermission(s32 val);
Result appletSetScreenShotImageOrientation(s32 val);
/**
* @brief Stops forwarding the input to the foreground app, works only in the Overlay applet context.
* @note You have to call this to receive inputs through the hid service when running as the overlay applet.
*/
Result appletBeginToWatchShortHomeButtonMessage(void);
/**
* @brief Forwards input to the foreground app, works only in the Overlay applet context.
* @note After calling this the overlay applet won't receive any input until \ref appletBeginToWatchShortHomeButtonMessage is called again.
*/
Result appletEndToWatchShortHomeButtonMessage(void);
/**
* @brief Get an event that fires when the home button is pressed, doesn't interfere with home menu. This event does not auto clear.
* @note Doesn't fire for long press.
*/
Result appletHomeButtonReaderLockAccessorGetEvent(Event *out_event);
/**
* @brief Pushes a storage to the general channel. Used for sending requests to qlaunch.
* @note This is not usable under an Application, however it is usable under a LibraryApplet.

View File

@ -0,0 +1,23 @@
/**
* @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. This event does not auto clear.
**/
Result hidsysAcquireHomeButtonEventHandle(Event* event_out);
Result hidsysActivateHomeButton(void);
Result hidsysActivateSleepButton(void);
Result hidsysActivateCaptureButton(void);

View File

@ -1378,8 +1378,35 @@ Result appletQueryApplicationPlayStatistics(AppletApplicationPlayStatistics *sta
return rc;
}
// IOverlayFunctions
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);
}
// ICommonStateGetter
Result appletHomeButtonReaderLockAccessorGetEvent(Event *out_event) {
Service ILockAccessor = {0};
Result rc = _appletGetSession(&g_appletICommonStateGetter, &ILockAccessor, 30);
if (R_FAILED(rc))
return rc;
rc = _appletGetEvent(&ILockAccessor, out_event, 3, false);
serviceClose(&ILockAccessor);
return rc;
}
static Result _appletReceiveMessage(u32 *out) {
IpcCommand c;
ipcInitialize(&c);

181
nx/source/services/hidsys.c Normal file
View File

@ -0,0 +1,181 @@
#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/sm.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);
}