Replaced appletHomeButtonReaderLockAccessorGetEvent with appletGetHomeButtonReaderLockAccessor. Added appletGetReaderLockAccessorEx, appletGetWriterLockAccessorEx, and appletGetHomeButtonWriterLockAccessor. Added support for AppletLockAccessor.

This commit is contained in:
yellows8 2019-08-05 22:39:27 -04:00
parent 21de119c68
commit 75c79e8d5e
No known key found for this signature in database
GPG Key ID: 0AF90DA3F1E60E43
2 changed files with 227 additions and 8 deletions

View File

@ -186,6 +186,12 @@ struct AppletHookCookie
void* param; ///< Callback parameter. void* param; ///< Callback parameter.
}; };
/// LockAccessor
typedef struct {
Service s; ///< ILockAccessor
Event event; ///< Event from the GetEvent cmd, with autoclear=false.
} AppletLockAccessor;
/// applet IStorage /// applet IStorage
typedef struct { typedef struct {
Service s; Service s;
@ -289,10 +295,27 @@ Result appletReleaseSleepLockTransiently(void);
Result appletPushToGeneralChannel(AppletStorage *s); Result appletPushToGeneralChannel(AppletStorage *s);
/** /**
* @brief Get an event that fires when the home button is pressed, doesn't interfere with home menu. This event does not auto clear. * @brief Gets a \ref AppletLockAccessor for HomeButtonReader.
* @note Doesn't fire for long press. * @note Similar to using \ref appletGetReaderLockAccessorEx with inval=0.
* @param a LockAccessor object.
*/ */
Result appletHomeButtonReaderLockAccessorGetEvent(Event *out_event); Result appletGetHomeButtonReaderLockAccessor(AppletLockAccessor *a);
/**
* @brief Gets a Reader \ref AppletLockAccessor.
* @note Only available with [2.0.0+].
* @param a LockAccessor object.
* @param[in] inval Input value, must be 0-3. 0 = HomeButton.
*/
Result appletGetReaderLockAccessorEx(AppletLockAccessor *a, u32 inval);
/**
* @brief Gets a Writer \ref AppletLockAccessor.
* @note Only available with [7.0.0+]. On older sysvers, this is only available with AppletType_SystemApplet on [2.0.0+].
* @param a LockAccessor object.
* @param[in] inval Input value, must be 0-3. 0 = HomeButton.
*/
Result appletGetWriterLockAccessorEx(AppletLockAccessor *a, u32 inval);
/** /**
* @brief Gets the Dock firmware version. * @brief Gets the Dock firmware version.
@ -792,6 +815,34 @@ Result appletReleaseCallerAppletCaptureSharedBuffer(void);
*/ */
Result appletTakeScreenShotOfOwnLayerEx(bool flag0, bool immediately, AppletCaptureSharedBuffer captureBuf); Result appletTakeScreenShotOfOwnLayerEx(bool flag0, bool immediately, AppletCaptureSharedBuffer captureBuf);
// LockAccessor
/**
* @brief Closes a LockAccessor.
* @param a LockAccessor object.
*/
void appletLockAccessorClose(AppletLockAccessor *a);
/**
* @brief TryLock a LockAccessor.
* @param a LockAccessor object.
* @param[out] flag Whether locking was successful, when false this indicates that this func should be called again.
*/
Result appletLockAccessorTryLock(AppletLockAccessor *a, bool *flag);
/**
* @brief Lock a LockAccessor.
* @note Similar to \ref appletLockAccessorTryLock, except this uses timeout U64_MAX with the eventWait call, and this uses TryLock repeatedly until the output flag value is true.
* @param a LockAccessor object.
*/
Result appletLockAccessorLock(AppletLockAccessor *a);
/**
* @brief Unlock a LockAccessor.
* @param a LockAccessor object.
*/
Result appletLockAccessorUnlock(AppletLockAccessor *a);
// ILibraryAppletCreator // ILibraryAppletCreator
/** /**
@ -1168,6 +1219,16 @@ Result appletQueryApplicationPlayStatisticsByUid(u128 userID, PdmApplicationPlay
*/ */
Result appletGetGpuErrorDetectedSystemEvent(Event *out_event); Result appletGetGpuErrorDetectedSystemEvent(Event *out_event);
// IHomeMenuFunctions
/**
* @brief Gets a \ref AppletLockAccessor for HomeButtonWriter.
* @note Only available with AppletType_SystemApplet.
* @note Similar to using \ref appletGetWriterLockAccessorEx with inval=0.
* @param a LockAccessor object.
*/
Result appletGetHomeButtonWriterLockAccessor(AppletLockAccessor *a);
// ILibraryAppletSelfAccessor // ILibraryAppletSelfAccessor
/** /**

View File

@ -652,6 +652,44 @@ static Result _appletGetSessionIn64(Service* srv, Service* srv_out, u64 cmd_id,
return rc; return rc;
} }
static Result _appletGetSessionIn32(Service* srv, Service* srv_out, u64 cmd_id, u32 inval) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u32 inval;
} *raw;
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = cmd_id;
raw->inval = inval;
Result rc = serviceIpcDispatch(srv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(srv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
serviceCreateSubservice(srv_out, srv, &r, 0);
}
}
return rc;
}
static Result _appletCmdNoIO(Service* session, u64 cmd_id) { static Result _appletCmdNoIO(Service* session, u64 cmd_id) {
IpcCommand c; IpcCommand c;
ipcInitialize(&c); ipcInitialize(&c);
@ -1306,17 +1344,48 @@ Result appletPushToGeneralChannel(AppletStorage *s) {
return _appletCmdInStorage(&g_appletICommonStateGetter, s, 20); return _appletCmdInStorage(&g_appletICommonStateGetter, s, 20);
} }
Result appletHomeButtonReaderLockAccessorGetEvent(Event *out_event) { static Result _appletGetHomeButtonRwLockAccessor(Service* srv, AppletLockAccessor *a, u64 cmd_id) {
Service ILockAccessor = {0}; Result rc = _appletGetSession(srv, &a->s, cmd_id);
Result rc = _appletGetSession(&g_appletICommonStateGetter, &ILockAccessor, 30);
if (R_FAILED(rc)) if (R_FAILED(rc))
return rc; return rc;
rc = _appletGetEvent(&ILockAccessor, out_event, 3, false); rc = _appletGetEvent(&a->s, &a->event, 3, false);
serviceClose(&ILockAccessor); if (R_FAILED(rc)) serviceClose(&a->s);
return rc; return rc;
} }
Result appletGetHomeButtonReaderLockAccessor(AppletLockAccessor *a) {
return _appletGetHomeButtonRwLockAccessor(&g_appletICommonStateGetter, a, 30);
}
static Result _appletGetRwLockAccessor(Service* srv, AppletLockAccessor *a, u64 cmd_id, s32 inval) {
Result rc = _appletGetSessionIn32(srv, &a->s, cmd_id, inval);
if (R_FAILED(rc))
return rc;
rc = _appletGetEvent(&a->s, &a->event, 3, false);
if (R_FAILED(rc)) serviceClose(&a->s);
return rc;
}
Result appletGetReaderLockAccessorEx(AppletLockAccessor *a, u32 inval) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _appletGetRwLockAccessor(&g_appletICommonStateGetter, a, 31, inval);
}
Result appletGetWriterLockAccessorEx(AppletLockAccessor *a, u32 inval) {
if (hosversionBefore(7,0,0)) {
if (__nx_applet_type == AppletType_SystemApplet && hosversionAtLeast(2,0,0))
return _appletGetRwLockAccessor(&g_appletIFunctions, a, 31, inval);
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
}
return _appletGetRwLockAccessor(&g_appletICommonStateGetter, a, 32, inval);
}
Result appletGetCradleFwVersion(u32 *out0, u32 *out1, u32 *out2, u32 *out3) { Result appletGetCradleFwVersion(u32 *out0, u32 *out1, u32 *out2, u32 *out3) {
if (hosversionBefore(2,0,0)) if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
@ -2434,6 +2503,86 @@ Result appletTakeScreenShotOfOwnLayerEx(bool flag0, bool immediately, AppletCapt
return rc; return rc;
} }
// LockAccessor
void appletLockAccessorClose(AppletLockAccessor *a) {
eventClose(&a->event);
serviceClose(&a->s);
}
static Result _appletLockAccessorTryLock(AppletLockAccessor *a, bool get_handle, Handle* handle_out, bool *outflag) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u8 inflag;
} *raw;
raw = serviceIpcPrepareHeader(&a->s, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 1;
raw->inflag = get_handle!=0;
Result rc = serviceIpcDispatch(&a->s);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
u8 outflag;
} *resp;
serviceIpcParse(&a->s, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
if (handle_out) *handle_out = r.Handles[0];
if (outflag) *outflag = resp->outflag!=0;
}
}
return rc;
}
Result appletLockAccessorTryLock(AppletLockAccessor *a, bool *flag) {
Result rc=0;
if (!serviceIsActive(&a->s))
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
rc = eventWait(&a->event, 0);
if (R_SUCCEEDED(rc)) rc = _appletLockAccessorTryLock(a, false, NULL, flag);
return rc;
}
Result appletLockAccessorLock(AppletLockAccessor *a) {
Result rc=0;
bool flag=0;
if (!serviceIsActive(&a->s))
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
do {
rc = eventWait(&a->event, U64_MAX);
if (R_SUCCEEDED(rc)) rc = _appletLockAccessorTryLock(a, false, NULL, &flag);
if (R_FAILED(rc)) break;
} while(!flag);
return rc;
}
Result appletLockAccessorUnlock(AppletLockAccessor *a) {
if (!serviceIsActive(&a->s))
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return _appletCmdNoIO(&a->s, 2);
}
// ILibraryAppletCreator // ILibraryAppletCreator
static Result _appletCreateLibraryApplet(Service* srv_out, AppletId id, LibAppletMode mode) { static Result _appletCreateLibraryApplet(Service* srv_out, AppletId id, LibAppletMode mode) {
@ -3781,6 +3930,15 @@ Result appletGetGpuErrorDetectedSystemEvent(Event *out_event) {
return _appletGetEvent(&g_appletIFunctions, out_event, 130, false); return _appletGetEvent(&g_appletIFunctions, out_event, 130, false);
} }
// IHomeMenuFunctions
Result appletGetHomeButtonWriterLockAccessor(AppletLockAccessor *a) {
if (__nx_applet_type != AppletType_SystemApplet)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return _appletGetHomeButtonRwLockAccessor(&g_appletIFunctions, a, 30);
}
// ILibraryAppletSelfAccessor // ILibraryAppletSelfAccessor
static Result _appletExitProcessAndReturn(void) { static Result _appletExitProcessAndReturn(void) {