diff --git a/libctru/include/3ds/services/apt.h b/libctru/include/3ds/services/apt.h index 63e15f8..35efb33 100644 --- a/libctru/include/3ds/services/apt.h +++ b/libctru/include/3ds/services/apt.h @@ -37,6 +37,24 @@ enum { APTSIGNAL_ERROR = 11 }; +enum { + APTHOOK_ONSUSPEND = 0, + APTHOOK_ONRESTORE, + APTHOOK_ONSLEEP, + APTHOOK_ONWAKEUP, + APTHOOK_ONEXIT, + + APTHOOK_COUNT, +}; + +typedef void (*aptHookFn)(int hook, void* param); + +typedef struct tag_aptHookCookie +{ + struct tag_aptHookCookie* next; + aptHookFn callback; + void* param; +} aptHookCookie; extern Handle aptEvents[3]; @@ -54,6 +72,9 @@ void aptSignalReadyForSleep(); NS_APPID aptGetMenuAppID(); bool aptMainLoop(); // Use like this in your main(): while (aptMainLoop()) { your code here... } +void aptHook(aptHookCookie* cookie, aptHookFn callback, void* param); +void aptUnhook(aptHookCookie* cookie); + Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle); Result APT_Initialize(Handle* handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2); Result APT_Finalize(Handle* handle, NS_APPID appId); diff --git a/libctru/source/services/apt.c b/libctru/source/services/apt.c index 01754d5..4f33c92 100644 --- a/libctru/source/services/apt.c +++ b/libctru/source/services/apt.c @@ -48,6 +48,15 @@ static Handle __apt_launchapplet_inhandle; static u32 *__apt_launchapplet_parambuf; static u32 __apt_launchapplet_parambufsize; +static aptHookCookie aptFirstHook; + +static void aptCallHook(int hookType) +{ + aptHookCookie* c; + for (c = &aptFirstHook; c && c->callback; c = c->next) + c->callback(hookType, c->param); +} + // The following function can be overriden in order to log APT signals and notifications for debugging purposes __attribute__((weak)) void _aptDebug(int a, int b) { @@ -558,9 +567,12 @@ bool aptMainLoop() case APP_RUNNING: return true; case APP_EXITING: + aptCallHook(APTHOOK_ONEXIT); return false; case APP_SUSPENDING: + aptCallHook(APTHOOK_ONSUSPEND); aptReturnToMenu(); + aptCallHook(APTHOOK_ONRESTORE); break; case APP_APPLETSTARTED: aptAppletStarted(); @@ -569,17 +581,43 @@ bool aptMainLoop() aptAppletClosed(); break; case APP_PREPARE_SLEEPMODE: + aptCallHook(APTHOOK_ONSLEEP); aptSignalReadyForSleep(); // Fall through default: //case APP_NOTINITIALIZED: //case APP_SLEEPMODE: aptWaitStatusEvent(); + aptCallHook(APTHOOK_ONWAKEUP); break; } } } +void aptHook(aptHookCookie* cookie, aptHookFn callback, void* param) +{ + if (!callback) return; + + aptHookCookie* hook = &aptFirstHook; + *cookie = *hook; // Structure copy. + hook->next = cookie; + hook->callback = callback; + hook->param = param; +} + +void aptUnhook(aptHookCookie* cookie) +{ + aptHookCookie* hook; + for (hook = &aptFirstHook; hook; hook = hook->next) + { + if (hook->next == cookie) + { + *hook = *cookie; // Structure copy. + break; + } + } +} + void aptAppStarted() { u8 buf1[4], buf2[4];