]> Chaos Git - corbenik/ctrulib.git/commitdiff
Major APT rewrite, see details:
authorfincs <fincs.alt1@gmail.com>
Fri, 1 Jul 2016 22:57:06 +0000 (00:57 +0200)
committerfincs <fincs.alt1@gmail.com>
Fri, 1 Jul 2016 22:57:06 +0000 (00:57 +0200)
- Internal logic changes in order to follow official behavior
  more closely - the APT state machine has been removed.
- The following functions were removed:
  * aptSetStatus/aptGetStatus along with the APT_AppStatus enum
  * aptGetStatusPower/aptSetStatusPower
  * aptReturnToMenu
  * aptWaitStatusEvent, aptSignalReadyForSleep
- Library applet launching is now fully supported on both official
  environments (ncch/cia) and homebrew environments (3dsx).
  APT_LaunchLibraryApplet has been replaced with aptLaunchLibraryApplet.
- Added aptSetMessageCallback (intended for use with libapplet code)
- Added APT_CancelParameter
- Some other misc changes

libctru/include/3ds/services/apt.h
libctru/source/gfx.c
libctru/source/services/apt.c

index 0f678621b0fa1ab73fcabbf02c048ab3a50e2c85..1dad9de30d721bc5f02bc8e9486718ed33c27620 100644 (file)
@@ -10,6 +10,7 @@
  * Retrieved from http://3dbrew.org/wiki/NS_and_APT_Services#AppIDs
  */
 typedef enum {
+       APPID_NONE = 0,
        APPID_HOMEMENU = 0x101,           ///< Home Menu
        APPID_CAMERA = 0x110,             ///< Camera applet
        APPID_FRIENDS_LIST = 0x112,       ///< Friends List applet
@@ -32,19 +33,6 @@ typedef enum {
        APPID_MEMOLIB = 0x409,            ///< memolib
 } NS_APPID;
 
-/// App status values.
-typedef enum {
-       APP_NOTINITIALIZED,    ///< App not initialized.
-       APP_RUNNING,           ///< App running.
-       APP_SUSPENDED,         ///< App suspended.
-       APP_EXITING,           ///< App exiting.
-       APP_SUSPENDING,        ///< App suspending.
-       APP_SLEEPMODE,         ///< App in sleep mode.
-       APP_PREPARE_SLEEPMODE, ///< App preparing to enter sleep mode.
-       APP_APPLETSTARTED,     ///< Applet started.
-       APP_APPLETCLOSED       ///< Applet closed.
-} APT_AppStatus;
-
 /// APT applet position.
 typedef enum {
        APTPOS_NONE     = -1, ///< No position specified.
@@ -143,8 +131,8 @@ typedef struct tag_aptHookCookie
        void* param;                    ///< Callback parameter.
 } aptHookCookie;
 
-/// APT events.
-extern Handle aptEvents[3];
+/// APT message callback.
+typedef void (*aptMessageCb)(void* user, NS_APPID sender, void* msg, size_t msgsize);
 
 /// Initializes APT.
 Result aptInit(void);
@@ -158,44 +146,6 @@ void aptExit(void);
  */
 Result aptSendCommand(u32* aptcmdbuf);
 
-/**
- * @brief Sets the app's status.
- * @param status Status to set.
- */
-void aptSetStatus(APT_AppStatus status);
-
-/**
- * @brief Gets the app's status.
- * @return The app's status.
- */
-APT_AppStatus aptGetStatus(void);
-
-/**
- * @brief Gets the app's power status.
- * When the status is APT_SUSPEND, this can be used to check what triggered a return-to-menu.
- * @return The app's power status. (0 = normal, 1 = power button pressed)
- */
-u32 aptGetStatusPower(void);
-
-/**
- * @brief Sets the app's power status.
- * @param status Power status to set.
- */
-void aptSetStatusPower(u32 status);
-
-/**
- * @brief Triggers a return to the home menu.
- *
- * This should be called by the user application when aptGetStatus() returns APP_SUSPENDING, not calling this will result in return-to-menu being disabled with the status left at APP_SUSPENDING. This function will not return until the system returns to the application, or when the status was changed to APP_EXITING.
- */
-void aptReturnToMenu(void);
-
-/// Waits for an APT status event.
-void aptWaitStatusEvent(void);
-
-/// Signals that the app is ready to sleep.
-void aptSignalReadyForSleep(void);
-
 /**
  * @brief Gets whether to allow the system to enter sleep mode.
  * @return Whether sleep mode is allowed.
@@ -208,15 +158,9 @@ bool aptIsSleepAllowed(void);
  */
 void aptSetSleepAllowed(bool allowed);
 
-/**
- * @brief Gets the menu's app ID.
- * @return The menu's app ID.
- */
-NS_APPID aptGetMenuAppID(void);
-
 /**
  * @brief Processes the current APT status. Generally used within a main loop.
- * @return Whether the application is closing.
+ * @return Whether the application should continue running.
  */
 bool aptMainLoop(void);
 
@@ -234,6 +178,23 @@ void aptHook(aptHookCookie* cookie, aptHookFn callback, void* param);
  */
 void aptUnhook(aptHookCookie* cookie);
 
+/**
+ * @brief Sets the function to be called when an APT message from another applet is received.
+ * @param callback Callback function.
+ * @param user User-defined data to be passed to the callback.
+ */
+void aptSetMessageCallback(aptMessageCb callback, void* user);
+
+/**
+ * @brief Launches a library applet.
+ * @param appId ID of the applet to launch.
+ * @param buf Input/output buffer that contains launch parameters on entry and result data on exit.
+ * @param bufsize Size of the buffer.
+ * @param handle Handle to pass to the library applet.
+ * @return Whether the application should continue running after the library applet launch.
+ */
+bool aptLaunchLibraryApplet(NS_APPID appId, void* buf, size_t bufsize, Handle handle);
+
 /**
  * @brief Gets an APT lock handle.
  * @param flags Flags to use.
@@ -275,6 +236,17 @@ Result APT_Enable(APT_AppletAttr attr);
  */
 Result APT_GetAppletManInfo(APT_AppletPos inpos, APT_AppletPos* outpos, NS_APPID* req_appid, NS_APPID* menu_appid, NS_APPID* active_appid);
 
+/**
+ * @brief Gets the menu's app ID.
+ * @return The menu's app ID.
+ */
+static inline NS_APPID aptGetMenuAppID(void)
+{
+       NS_APPID menu_appid = APPID_NONE;
+       APT_GetAppletManInfo(APTPOS_NONE, NULL, NULL, &menu_appid, NULL);
+       return menu_appid;
+}
+
 /**
  * @brief Gets an applet's information.
  * @param appID AppID of the applet.
@@ -381,30 +353,32 @@ Result APT_UnlockTransition(u32 transition);
 
 /**
  * @brief Glances at a receieved parameter without removing it from the queue.
- * @param appID ID of the application.
+ * @param appID AppID of the application.
  * @param buffer Buffer to receive to.
  * @param bufferSize Size of the buffer.
+ * @param sender Pointer to output the sender's AppID to.
  * @param command Pointer to output the command ID to.
  * @param actualSize Pointer to output the actual received data size to.
  * @param parameter Pointer to output the parameter handle to.
  */
-Result APT_GlanceParameter(NS_APPID appID, void* buffer, size_t bufferSize, APT_Command* command, size_t* actualSize, Handle* parameter);
+Result APT_GlanceParameter(NS_APPID appID, void* buffer, size_t bufferSize, NS_APPID* sender, APT_Command* command, size_t* actualSize, Handle* parameter);
 
 /**
  * @brief Receives a parameter.
- * @param appID ID of the application.
+ * @param appID AppID of the application.
  * @param buffer Buffer to receive to.
  * @param bufferSize Size of the buffer.
+ * @param sender Pointer to output the sender's AppID to.
  * @param command Pointer to output the command ID to.
  * @param actualSize Pointer to output the actual received data size to.
  * @param parameter Pointer to output the parameter handle to.
  */
-Result APT_ReceiveParameter(NS_APPID appID, void* buffer, size_t bufferSize, APT_Command* command, size_t* actualSize, Handle* parameter);
+Result APT_ReceiveParameter(NS_APPID appID, void* buffer, size_t bufferSize, NS_APPID* sender, APT_Command* command, size_t* actualSize, Handle* parameter);
 
 /**
  * @brief Sends a parameter.
- * @param source ID of the source application.
- * @param dest ID of the destination application.
+ * @param source AppID of the source application.
+ * @param dest AppID of the destination application.
  * @param command Command to send.
  * @param buffer Buffer to send.
  * @param bufferSize Size of the buffer.
@@ -412,6 +386,14 @@ Result APT_ReceiveParameter(NS_APPID appID, void* buffer, size_t bufferSize, APT
  */
 Result APT_SendParameter(NS_APPID source, NS_APPID dest, APT_Command command, const void* buffer, u32 bufferSize, Handle parameter);
 
+/**
+ * @brief Cancels a parameter which matches the specified source and dest AppIDs.
+ * @param source AppID of the source application (use APPID_NONE to disable the check).
+ * @param dest AppID of the destination application (use APPID_NONE to disable the check).
+ * @param success Pointer to output true if a parameter was cancelled, or false otherwise.
+ */
+Result APT_CancelParameter(NS_APPID source, NS_APPID dest, bool* success);
+
 /**
  * @brief Sends capture buffer information.
  * @param captureBuf Capture buffer information to send.
@@ -494,16 +476,6 @@ Result APT_PrepareToStartLibraryApplet(NS_APPID appID);
  */
 Result APT_StartLibraryApplet(NS_APPID appID, const void* param, size_t paramSize, Handle handle);
 
-/**
- * @brief Launches a library applet.
- * Note: This is not usable from the homebrew launcher. This is broken: when the applet does get launched at all, the applet process doesn't actually get terminated when the applet gets closed.
- * @param appID ID of the applet to launch.
- * @param inhandle Handle to pass to the applet.
- * @param parambuf Buffer containing applet parameters.
- * @param parambufsize Size of parambuf.
- */
-Result APT_LaunchLibraryApplet(NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize);
-
 /**
  * @brief Prepares to start a system applet.
  * @param appID AppID of the applet to start.
index 2ce4455d42f150b6f074f20f9f303a310824f2dd..6fa27fb3f5fe87e5930e82d35d7e61cdff25f6bb 100644 (file)
@@ -56,7 +56,7 @@ void gfxSetDoubleBuffering(gfxScreen_t screen, bool doubleBuffering) {
        doubleBuf[screen] = doubleBuffering ? 1 : 0; // make sure they're the integer values '1' and '0'
 }
 
-static u32 __get_bytes_per_pixel(GSPGPU_FramebufferFormats format) {
+u32 __get_bytes_per_pixel(GSPGPU_FramebufferFormats format) {
     switch(format) {
     case GSP_RGBA8_OES:
         return 4;
index 8bc71f15f129a34ce3164645e07ca63c83847de5..da939eb71640611e66f38f9de4d1058d61e33590 100644 (file)
 
 #define APT_HANDLER_STACKSIZE (0x1000)
 
-NS_APPID currentAppId;
-
-Handle aptLockHandle;
-Handle aptEvents[3];
-
-Thread aptEventHandlerThread;
-
-LightLock aptStatusMutex = 1;
-Handle aptStatusEvent;
-APT_AppStatus aptStatus = APP_NOTINITIALIZED;
-APT_AppStatus aptStatusBeforeSleep = APP_NOTINITIALIZED;
-u32 aptStatusPower;
-Handle aptSleepSync;
-static bool aptSleepAllowed = true;
-
-u32 aptParameters[0x1000/4]; //TEMP
-
-static u32 __ns_capinfo[0x20>>2];
-
-static NS_APPID __apt_launchapplet_appID;
-static Handle __apt_launchapplet_inhandle;
-static u32 *__apt_launchapplet_parambuf;
-static u32 __apt_launchapplet_parambufsize;
-
+static int aptRefCount = 0;
+static Handle aptLockHandle;
+static Handle aptEvents[3];
+static LightEvent aptSleepEvent;
+static Thread aptEventHandlerThread;
 static aptHookCookie aptFirstHook;
+static aptMessageCb aptMessageFunc;
+static void* aptMessageFuncData;
+
+enum
+{
+       FLAG_ACTIVE       = BIT(0),
+       FLAG_ALLOWSLEEP   = BIT(1),
+       FLAG_ORDERTOCLOSE = BIT(2),
+       FLAG_SHUTDOWN     = BIT(3),
+       FLAG_POWERBUTTON  = BIT(4),
+       FLAG_WKUPBYCANCEL = BIT(5),
+       FLAG_WANTSTOSLEEP = BIT(6),
+       FLAG_SLEEPING     = BIT(7),
+       FLAG_EXITED       = BIT(31),
+};
+
+static u8 aptHomeButtonState;
+static u32 aptFlags = FLAG_ALLOWSLEEP;
+static u32 aptParameters[0x1000/4];
+
+typedef enum
+{
+       TR_ENABLE     = 0x62,
+       TR_JUMPTOMENU = 0x0E,
+       TR_SYSAPPLET  = 0x05,
+       TR_LIBAPPLET  = 0x04,
+       TR_CANCELLIB  = 0x03,
+       TR_CLOSEAPP   = 0x09,
+       TR_APPJUMP    = 0x12,
+} APT_Transition;
+
+static void aptEventHandler(void *arg);
+static APT_Command aptWaitForWakeUp(APT_Transition transition);
+
+// 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)
+{
+}
 
 static void aptCallHook(APT_HookType hookType)
 {
@@ -50,15 +69,6 @@ static void aptCallHook(APT_HookType hookType)
                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)
-{
-}
-
-void __ctru_speedup_config(void);
-
-static void aptAppStarted(void);
-
 static bool aptIsReinit(void)
 {
        return (envGetSystemRunFlags() & RUNFLAG_APTREINIT) != 0;
@@ -119,396 +129,370 @@ Result aptSendCommand(u32* aptcmdbuf)
        return res;
 }
 
-void aptInitCaptureInfo(u32 *ns_capinfo)
+static void aptInitCaptureInfo(aptCaptureBufInfo* capinfo)
 {
-       u32 tmp=0;
-       u32 main_pixsz, sub_pixsz;
        GSPGPU_CaptureInfo gspcapinfo;
-
-       memset(&gspcapinfo, 0, sizeof(GSPGPU_CaptureInfo));
+       memset(&gspcapinfo, 0, sizeof(gspcapinfo));
 
        // Get display-capture info from GSP.
        GSPGPU_ImportDisplayCaptureInfo(&gspcapinfo);
 
        // Fill in display-capture info for NS.
-       if(gspcapinfo.screencapture[0].framebuf0_vaddr != gspcapinfo.screencapture[0].framebuf1_vaddr)ns_capinfo[1] = 1;
+       capinfo->is3D = gspcapinfo.screencapture[0].framebuf0_vaddr != gspcapinfo.screencapture[0].framebuf1_vaddr;
        
-       ns_capinfo[4] = gspcapinfo.screencapture[0].format & 0x7;
-       ns_capinfo[7] = gspcapinfo.screencapture[1].format & 0x7;
+       capinfo->top.format    = gspcapinfo.screencapture[0].format & 0x7;
+       capinfo->bottom.format = gspcapinfo.screencapture[1].format & 0x7;
 
-       main_pixsz = (ns_capinfo[4] < 2) ? 3 : 2;
-       sub_pixsz  = (ns_capinfo[7] < 2) ? 3 : 2;
+       u32 __get_bytes_per_pixel(u32 format);
+       u32 main_pixsz = __get_bytes_per_pixel(capinfo->top.format);
+       u32 sub_pixsz  = __get_bytes_per_pixel(capinfo->bottom.format);
 
-       ns_capinfo[2] = sub_pixsz * 0x14000;
-       ns_capinfo[3] = ns_capinfo[2];
+       capinfo->bottom.leftOffset  = 0;
+       capinfo->bottom.rightOffset = 0;
+       capinfo->top.leftOffset  = sub_pixsz * 0x14000;
+       capinfo->top.rightOffset = capinfo->top.leftOffset;
 
-       if(ns_capinfo[1])ns_capinfo[3] = main_pixsz * 0x19000 + ns_capinfo[2];
-
-       tmp = main_pixsz * 0x19000 + ns_capinfo[3];
-       ns_capinfo[0] = main_pixsz * 0x7000 + tmp;
-}
-
-void aptWaitStatusEvent(void)
-{
-       svcWaitSynchronization(aptStatusEvent, U64_MAX);
-       svcClearEvent(aptStatusEvent);
-}
-
-void aptAppletUtility_Exit_RetToApp(u32 type)
-{
-       APT_UnlockTransition(0x10);
-       APT_SleepIfShellClosed();
-       APT_UnlockTransition(0x01);
-       APT_SleepIfShellClosed();
-       APT_SleepIfShellClosed();
-       if (type)
-               APT_SleepIfShellClosed();
-}
+       if (capinfo->is3D)
+               capinfo->top.rightOffset += main_pixsz * 0x19000;
 
-NS_APPID aptGetMenuAppID(void)
-{
-       NS_APPID menu_appid = 0;
-       APT_GetAppletManInfo(APTPOS_NONE, NULL, NULL, &menu_appid, NULL);
-       return menu_appid;
+       capinfo->size = main_pixsz * 0x7000 + main_pixsz * 0x19000 + capinfo->top.rightOffset;
 }
 
-void aptReturnToMenu(void)
+Result aptInit(void)
 {
-       NS_APPID menu_appid;
-
-       if(aptIsCrippled())
-       {
-               svcClearEvent(aptStatusEvent);
-               aptSetStatus(APP_EXITING);
-               return;
-       }
-
-       // This is only executed when ret-to-menu was triggered via the home-button, not the power-button.
-       if(aptGetStatusPower() == 0)
-       {
-               bool temp;
-               APT_TryLockTransition(0x01, &temp);
-       }
+       Result ret=0;
 
-       // Set status to SUSPENDED.
-       __apt_launchapplet_appID = 0;
-       svcClearEvent(aptStatusEvent);
-       aptSetStatus(APP_SUSPENDED);
+       if (AtomicPostIncrement(&aptRefCount)) return 0;
 
-       // Prepare for return to menu
-       APT_PrepareToJumpToHomeMenu();
+       // Retrieve APT lock
+       ret = APT_GetLockHandle(0x0, &aptLockHandle);
+       if (R_FAILED(ret)) goto _fail;
+       if (aptIsCrippled()) return 0;
 
-       // Save Vram
-       GSPGPU_SaveVramSysArea();
+       // Initialize APT
+       APT_AppletAttr attr = aptMakeAppletAttr(APTPOS_APP, false, false);
+       ret = APT_Initialize(envGetAptAppId(), attr, &aptEvents[1], &aptEvents[2]);
+       if (R_FAILED(ret)) goto _fail2;
 
-       // Capture screen.
-       memset(__ns_capinfo, 0, 0x20);
+       // Enable APT
+       ret = APT_Enable(attr);
+       if (R_FAILED(ret)) goto _fail3;
 
-       aptInitCaptureInfo(__ns_capinfo);
+       // Create APT close event
+       ret = svcCreateEvent(&aptEvents[0], RESET_STICKY);
+       if (R_FAILED(ret)) goto _fail3;
 
-       menu_appid = aptGetMenuAppID();
+       // Initialize APT sleep event
+       LightEvent_Init(&aptSleepEvent, RESET_ONESHOT);
 
-       // Send capture-screen info to menu.
-       APT_SendParameter(currentAppId, menu_appid, APTCMD_SYSAPPLET_REQUEST, __ns_capinfo, sizeof(__ns_capinfo), 0);
-       APT_SendCaptureBufferInfo((aptCaptureBufInfo*)__ns_capinfo);
+       // Create APT event handler thread
+       aptEventHandlerThread = threadCreate(aptEventHandler, 0x0, APT_HANDLER_STACKSIZE, 0x31, -2, true);
+       if (!aptEventHandlerThread) goto _fail4;
 
-       // Release GSP module.
-       GSPGPU_ReleaseRight();
+       // Special handling for aptReinit (aka hax)
+       APT_Transition transition = TR_ENABLE;
+       if (aptIsReinit())
+       {
+               transition = TR_JUMPTOMENU;
 
-       // Jump to menu!
-       APT_JumpToHomeMenu(NULL, 0, 0);
+               // Clear out any pending parameters
+               bool success = false;
+               do
+                       ret = APT_CancelParameter(APPID_NONE, envGetAptAppId(), &success);
+               while (success);
 
-       // Wait for return to application.
-       APT_NotifyToWait(currentAppId);
+               // APT thinks the application is suspended, so we need to tell it to unsuspend us.
+               APT_PrepareToJumpToApplication(false);
+               APT_JumpToApplication(NULL, 0, 0);
+       }
 
-       // This is only executed when ret-to-menu was triggered via the home-button, not the power-button.
-       if(aptGetStatusPower() == 0)
-               APT_SleepIfShellClosed();
+       // Wait for wakeup
+       aptWaitForWakeUp(transition);
+       return 0;
 
-       aptWaitStatusEvent();
+_fail4:
+       svcCloseHandle(aptEvents[0]);
+_fail3:
+       svcCloseHandle(aptEvents[1]);
+       svcCloseHandle(aptEvents[2]);
+_fail2:
+       svcCloseHandle(aptLockHandle);
+_fail:
+       AtomicDecrement(&aptRefCount);
+       return ret;
 }
 
-void aptAppletStarted(void)
+bool aptIsSleepAllowed(void)
 {
-       // Set status to SUSPENDED.
-       svcClearEvent(aptStatusEvent);
-       aptSetStatus(APP_SUSPENDED);
-
-       APT_SendCaptureBufferInfo((aptCaptureBufInfo*)__ns_capinfo);
-       APT_ReplySleepQuery(currentAppId, APTREPLY_REJECT);
-       APT_StartLibraryApplet(__apt_launchapplet_appID, __apt_launchapplet_parambuf, __apt_launchapplet_parambufsize, __apt_launchapplet_inhandle);
-       APT_SleepIfShellClosed();
-       APT_NotifyToWait(currentAppId);
-       APT_SleepIfShellClosed();
+       return (aptFlags & FLAG_ALLOWSLEEP) != 0;
 }
 
-void aptAppletClosed(void)
+void aptSetSleepAllowed(bool allowed)
 {
-       aptAppletUtility_Exit_RetToApp(1);
-
-       GSPGPU_AcquireRight(0x0);
-       GSPGPU_RestoreVramSysArea();
+       bool cur = aptIsSleepAllowed();
+       if (allowed && !cur)
+       {
+               aptFlags |= FLAG_ALLOWSLEEP;
+               APT_SleepIfShellClosed();
+       }
+       else if (!allowed && cur)
+       {
+               aptFlags &= ~FLAG_ALLOWSLEEP;
+               APT_ReplySleepQuery(envGetAptAppId(), APTREPLY_REJECT);
+       }
+}
 
-       svcClearEvent(aptStatusEvent);
-       aptSetStatus(APP_RUNNING);
-       svcClearEvent(aptStatusEvent);
+static void aptExitProcess(void)
+{
+       APT_CloseApplication(NULL, 0, 0);
+       svcExitProcess();
 }
 
-static void __handle_notification(void) {
-       APT_Signal type;
-       Result ret=0;
+void aptExit(void)
+{
+       if (AtomicDecrement(&aptRefCount)) return;
 
-       // Get notification type.
-       ret = APT_InquireNotification(currentAppId, &type);
-       if(R_FAILED(ret)) return;
-       _aptDebug(1, type);
+       bool closeAptLock = true;
 
-       switch(type)
+       if (!aptIsCrippled())
        {
-       case APTSIGNAL_HOMEBUTTON:
-       case APTSIGNAL_POWERBUTTON:
-               // The main thread should call aptReturnToMenu() when the status gets set to this.
-               if(aptGetStatus() == APP_RUNNING)
-               {
-                       APT_ReplySleepQuery(currentAppId, APTREPLY_REJECT);
-
-                       if(type == APTSIGNAL_HOMEBUTTON)  aptSetStatusPower(0);
-                       if(type == APTSIGNAL_POWERBUTTON) aptSetStatusPower(1);
-                       aptSetStatus(APP_SUSPENDING);
-               }
-               break;
-
-       case APTSIGNAL_SLEEP_QUERY:
-               // Reply to sleep-request.
-               if(aptIsSleepAllowed())
-               {
-                       aptStatusBeforeSleep = aptGetStatus();
-                       aptSetStatus(APP_PREPARE_SLEEPMODE);
-                       svcWaitSynchronization(aptSleepSync, U64_MAX);
-                       svcClearEvent(aptSleepSync);
-                       APT_ReplySleepQuery(currentAppId, APTREPLY_ACCEPT);
-               } else
-                       APT_ReplySleepQuery(currentAppId, APTREPLY_REJECT);
-               break;
-
-       case APTSIGNAL_SLEEP_ENTER:
-               if(aptGetStatus() == APP_PREPARE_SLEEPMODE)
-               {
-                       // Report into sleep-mode.
-                       aptSetStatus(APP_SLEEPMODE);
-                       APT_ReplySleepNotificationComplete(currentAppId);
-               }
-               break;
-
-       // Leaving sleep-mode.
-       case APTSIGNAL_SLEEP_WAKEUP:
-               if(aptGetStatus() == APP_SLEEPMODE)
+               if ((aptFlags & FLAG_EXITED) || !aptIsReinit())
                {
-                       if(aptStatusBeforeSleep == APP_RUNNING)GSPGPU_SetLcdForceBlack(0);
-
-                       // Restore old aptStatus.
-                       aptSetStatus(aptStatusBeforeSleep);
-               }
-               break;
-
-       default:
-               break;
-       }
-}
-
-static bool __handle_incoming_parameter(void) {
-       APT_Command cmd;
-       APT_ReceiveParameter(currentAppId, aptParameters, sizeof(aptParameters), &cmd, NULL, NULL);
-       _aptDebug(2, cmd);
+                       APT_PrepareToCloseApplication(true);
 
-       switch(cmd)
-       {
-       case APTCMD_WAKEUP: // Application just started.
-               aptAppStarted();
-               return true;
-
-       case APTCMD_RESPONSE: // "Launched library applet finished loading"
-               if (aptGetStatus() != APP_SUSPENDED || __apt_launchapplet_appID==0) return true;
-               aptSetStatus(APP_APPLETSTARTED);
-               return true;
-       case APTCMD_WAKEUP_EXIT: // "Launched library applet closed"
-               if (aptGetStatus() != APP_SUSPENDED || __apt_launchapplet_appID==0) return true;
-               if(__apt_launchapplet_parambuf && __apt_launchapplet_parambufsize)memcpy(__apt_launchapplet_parambuf, aptParameters, __apt_launchapplet_parambufsize);
-               aptSetStatus(APP_APPLETCLOSED);
-               return true;
-       case APTCMD_WAKEUP_PAUSE: // Just returned from menu.
-               if (aptGetStatus() != APP_NOTINITIALIZED)
-               {
-                       GSPGPU_AcquireRight(0x0);
-                       GSPGPU_RestoreVramSysArea();
-                       aptAppletUtility_Exit_RetToApp(0);
-                       aptSetStatus(APP_RUNNING);
+                       extern void (*__system_retAddr)(void);
+                       __system_retAddr = aptExitProcess;
+                       closeAptLock = false;
+                       srvInit(); // Keep srv initialized
                } else
-                       aptAppStarted();
-               return true;
+                       APT_Finalize(envGetAptAppId());
 
-       case APTCMD_WAKEUP_CANCEL: // Exiting application.
-               aptSetStatus(APP_EXITING);
-               return false;
-       default:
-               break;
+               svcSignalEvent(aptEvents[0]);
+               threadJoin(aptEventHandlerThread, U64_MAX);
+               int i;
+               for (i = 0; i < 3; i ++)
+                       svcCloseHandle(aptEvents[i]);
        }
 
-       return true;
+       if (closeAptLock)
+               svcCloseHandle(aptLockHandle);
 }
 
 void aptEventHandler(void *arg)
 {
-       bool runThread = true;
-
-       while(runThread)
+       for (;;)
        {
-               s32 syncedID = 0;
-               svcWaitSynchronizationN(&syncedID, aptEvents, 3, 0, U64_MAX);
-               svcClearEvent(aptEvents[syncedID]);
-               switch(syncedID)
+               s32 id = 0;
+               svcWaitSynchronizationN(&id, aptEvents, 2, 0, U64_MAX);
+               svcClearEvent(aptEvents[id]);
+               if (id != 1) break;
+
+               APT_Signal signal;
+               Result res = APT_InquireNotification(envGetAptAppId(), &signal);
+               if (R_FAILED(res)) break;
+               switch (signal)
                {
-                       // Event 0 means we got a signal from NS (home button, power button etc).
-                       case 0x0:
-                               __handle_notification();
+                       case APTSIGNAL_HOMEBUTTON:
+                               if (!aptHomeButtonState) aptHomeButtonState = 1;
+                               break;
+                       case APTSIGNAL_HOMEBUTTON2:
+                               if (!aptHomeButtonState) aptHomeButtonState = 2;
+                               break;
+                       case APTSIGNAL_SLEEP_QUERY:
+                               APT_ReplySleepQuery(envGetAptAppId(), aptIsSleepAllowed() ? APTREPLY_ACCEPT : APTREPLY_REJECT);
+                               break;
+                       case APTSIGNAL_SLEEP_CANCEL:
+                               // Do something maybe?
+                               break;
+                       case APTSIGNAL_SLEEP_ENTER:
+                               aptFlags |= FLAG_WANTSTOSLEEP;
+                               break;
+                       case APTSIGNAL_SLEEP_WAKEUP:
+                               if (aptFlags & FLAG_SLEEPING)
+                                       LightEvent_Signal(&aptSleepEvent);
+                               else
+                                       aptFlags &= ~FLAG_WANTSTOSLEEP;
+                               break;
+                       case APTSIGNAL_SHUTDOWN:
+                               aptFlags |= FLAG_ORDERTOCLOSE | FLAG_SHUTDOWN;
                                break;
-                       // Event 1 means we got an incoming parameter.
-                       case 0x1:
-                               runThread = __handle_incoming_parameter();
+                       case APTSIGNAL_POWERBUTTON:
+                               aptFlags |= FLAG_POWERBUTTON;
                                break;
-                       // Event 2 means we should exit the thread.
-                       case 0x2:
-                               runThread = false;
+                       case APTSIGNAL_POWERBUTTON2:
+                               aptFlags &= ~FLAG_POWERBUTTON;
+                               break;
+                       case APTSIGNAL_TRY_SLEEP:
+                               break;
+                       case APTSIGNAL_ORDERTOCLOSE:
+                               aptFlags |= FLAG_ORDERTOCLOSE;
+                               break;
+                       default:
                                break;
                }
        }
 }
 
-static int aptRefCount = 0;
-
-Result aptInit(void)
+static Result aptReceiveParameter(APT_Command* cmd, size_t* actualSize, Handle* handle)
 {
-       Result ret=0;
-
-       if (AtomicPostIncrement(&aptRefCount)) return 0;
+       NS_APPID sender;
+       size_t temp_actualSize;
+       if (!actualSize) actualSize = &temp_actualSize;
 
-       // Initialize APT stuff, escape load screen.
-       ret = APT_GetLockHandle(0x0, &aptLockHandle);
-       if(R_FAILED(ret)) goto _fail;
+       svcWaitSynchronization(aptEvents[2], U64_MAX);
+       svcClearEvent(aptEvents[2]);
+       Result res = APT_ReceiveParameter(envGetAptAppId(), aptParameters, sizeof(aptParameters), &sender, cmd, actualSize, handle);
+       if (R_SUCCEEDED(res) && *cmd == APTCMD_MESSAGE && aptMessageFunc)
+               aptMessageFunc(aptMessageFuncData, sender, aptParameters, *actualSize);
+       return res;
+}
 
-       currentAppId = envGetAptAppId();
+APT_Command aptWaitForWakeUp(APT_Transition transition)
+{
+       APT_Command cmd;
+       APT_NotifyToWait(envGetAptAppId());
+       if (transition != TR_ENABLE)
+               APT_SleepIfShellClosed();
+       aptFlags &= ~FLAG_ACTIVE;
+       for (;;)
+       {
+               Result res = aptReceiveParameter(&cmd, NULL, NULL);
+               if (R_SUCCEEDED(res)
+                       && (cmd==APTCMD_WAKEUP || cmd==APTCMD_WAKEUP_PAUSE || cmd==APTCMD_WAKEUP_EXIT || cmd==APTCMD_WAKEUP_CANCEL
+                       || cmd==APTCMD_WAKEUP_CANCELALL || cmd==APTCMD_WAKEUP_POWERBUTTON || cmd==APTCMD_WAKEUP_JUMPTOHOME
+                       || cmd==APTCMD_WAKEUP_LAUNCHAPP)) break;
+       }
+       aptFlags |= FLAG_ACTIVE;
 
-       svcCreateEvent(&aptStatusEvent, 0);
-       svcCreateEvent(&aptSleepSync, 0);
-       aptStatus=0;
+       void __ctru_speedup_config();
+       __ctru_speedup_config();
 
-       if(!aptIsCrippled())
+       if (transition != TR_CANCELLIB && cmd != APTCMD_WAKEUP_CANCEL && cmd != APTCMD_WAKEUP)
        {
-               APT_AppletAttr attr = aptMakeAppletAttr(APTPOS_APP, false, false);
-               if(R_FAILED(ret=APT_Initialize(currentAppId, attr, &aptEvents[0], &aptEvents[1])))return ret;
-               if(R_FAILED(ret=APT_Enable(attr))) goto _fail;
+               GSPGPU_AcquireRight(0);
+               GSPGPU_RestoreVramSysArea();
+               aptCallHook(APTHOOK_ONRESTORE);
+       }
 
-               // create APT close event
-               svcCreateEvent(&aptEvents[2], 0);
+       if (cmd == APTCMD_WAKEUP_CANCEL)
+               aptFlags |= FLAG_WKUPBYCANCEL;
 
-               // After a cycle of APT_Finalize+APT_Initialize APT thinks the
-               // application is suspended, so we need to tell it to unsuspend us.
-               if (aptIsReinit())
+       if (cmd != APTCMD_WAKEUP_JUMPTOHOME)
+       {
+               APT_UnlockTransition(0x10);
+               APT_SleepIfShellClosed();
+       } else
+       {
+               bool dummy;
+               APT_TryLockTransition(0x01, &dummy);
+       }
+
+       if (transition == TR_JUMPTOMENU || transition == TR_LIBAPPLET || transition == TR_SYSAPPLET || transition == TR_APPJUMP)
+       {
+               if (cmd != APTCMD_WAKEUP_JUMPTOHOME)
                {
-                       APT_PrepareToJumpToApplication(false);
-                       APT_JumpToApplication(NULL, 0, 0);
+                       aptHomeButtonState = 0;
+                       APT_UnlockTransition(0x01);
+                       APT_SleepIfShellClosed();
                }
+       }
 
-               if(R_FAILED(ret=APT_NotifyToWait(currentAppId)))goto _fail;
-
-               // create APT event handler thread
-               aptEventHandlerThread = threadCreate(aptEventHandler, 0x0, APT_HANDLER_STACKSIZE, 0x31, -2, true);
-
-               // Wait for the state to become APT_RUNNING
-               aptWaitStatusEvent();
-       } else
-               aptAppStarted();
-
-       return 0;
+       return cmd;
+}
 
-_fail:
-       AtomicDecrement(&aptRefCount);
-       return ret;
+static void aptClearParamQueue(void)
+{
+       // Check for parameters?
+       for (;;)
+       {
+               APT_Command cmd;
+               Result res = APT_GlanceParameter(envGetAptAppId(), aptParameters, sizeof(aptParameters), NULL, &cmd, NULL, NULL);
+               if (R_FAILED(res) || cmd==APTCMD_NONE) break;
+               _aptDebug(2, cmd);
+               svcClearEvent(aptEvents[2]);
+               APT_CancelParameter(APPID_NONE, envGetAptAppId(), NULL);
+       }
 }
 
-void aptExit(void)
+static void aptScreenTransfer(NS_APPID appId, bool sysApplet)
 {
-       if (AtomicDecrement(&aptRefCount)) return;
+       aptCallHook(APTHOOK_ONSUSPEND);
+       GSPGPU_SaveVramSysArea();
 
-       if(!aptIsCrippled())aptAppletUtility_Exit_RetToApp(0);
+       aptCaptureBufInfo capinfo;
+       aptInitCaptureInfo(&capinfo);
 
-       // This is only executed when application-termination was triggered via the home-menu power-off screen.
-       if(aptGetStatusPower() == 1)
-               APT_ReplySleepQuery(currentAppId, APTREPLY_REJECT);
+       for (;;)
+       {
+               bool tmp;
+               Result res = APT_IsRegistered(appId, &tmp);
+               if (R_SUCCEEDED(res) && tmp) break;
+               svcSleepThread(10000000);
+       }
 
-       if(!aptIsCrippled())
+       for (;;)
        {
-               bool isReinit = aptIsReinit();
-               if (aptGetStatus() == APP_EXITING || !isReinit)
-               {
-                       APT_PrepareToCloseApplication(true);
-                       APT_CloseApplication(NULL, 0, 0);
-
-                       if (isReinit)
-                       {
-                               extern void (*__system_retAddr)(void);
-                               __system_retAddr = NULL;
-                       }
-               } else if (isReinit)
-                       APT_Finalize(currentAppId);
+               Result res = APT_SendParameter(envGetAptAppId(), appId, sysApplet ? APTCMD_SYSAPPLET_REQUEST : APTCMD_REQUEST, &capinfo, sizeof(capinfo), 0);
+               if (R_SUCCEEDED(res)) break;
+               svcSleepThread(10000000);
        }
 
-       svcSignalEvent(aptEvents[2]);
-       threadJoin(aptEventHandlerThread, U64_MAX);
-       svcCloseHandle(aptEvents[2]);
+       for (;;)
+       {
+               APT_Command cmd;
+               Result res = aptReceiveParameter(&cmd, NULL, NULL);
+               if (R_SUCCEEDED(res) && cmd==APTCMD_RESPONSE)
+                       break;
+       }
+
+       APT_SendCaptureBufferInfo(&capinfo);
+       GSPGPU_ReleaseRight();
+}
 
-       svcCloseHandle(aptSleepSync);
+static void aptProcessJumpToMenu(void)
+{
+       bool sleep = aptIsSleepAllowed();
+       aptSetSleepAllowed(false);
 
-       svcCloseHandle(aptLockHandle);
-       svcCloseHandle(aptStatusEvent);
+       aptClearParamQueue();
+       APT_PrepareToJumpToHomeMenu();
+       aptScreenTransfer(aptGetMenuAppID(), true);
+
+       APT_JumpToHomeMenu(NULL, 0, 0);
+       aptFlags &= ~FLAG_ACTIVE;
+
+       aptWaitForWakeUp(TR_JUMPTOMENU);
+       aptSetSleepAllowed(sleep);
 }
 
 bool aptMainLoop(void)
 {
-       while(1)
+       if (aptIsCrippled()) return true;
+       if (aptFlags & FLAG_EXITED) return false;
+
+       if (aptFlags & FLAG_WANTSTOSLEEP)
        {
-               switch(aptGetStatus())
-               {
-                       case APP_RUNNING:
-                               return true;
-                       case APP_EXITING:
-                               aptCallHook(APTHOOK_ONEXIT);
-                               return false;
-                       case APP_SUSPENDING:
-                               aptCallHook(APTHOOK_ONSUSPEND);
-                               aptReturnToMenu();
-                               if (aptGetStatus() == APP_RUNNING)
-                                       aptCallHook(APTHOOK_ONRESTORE);
-                               break;
-                       case APP_APPLETSTARTED:
-                               aptAppletStarted();
-                               break;
-                       case APP_APPLETCLOSED:
-                               aptAppletClosed();
-                               aptCallHook(APTHOOK_ONRESTORE);
-                               break;
-                       case APP_PREPARE_SLEEPMODE:
-                               aptCallHook(APTHOOK_ONSLEEP);
-                               aptSignalReadyForSleep();
-                               // Fall through
-                       default:
-                       //case APP_NOTINITIALIZED:
-                       //case APP_SLEEPMODE:
-                               aptWaitStatusEvent();
-                               aptCallHook(APTHOOK_ONWAKEUP);
-                               break;
-               }
+               aptFlags = (aptFlags &~ FLAG_WANTSTOSLEEP) | FLAG_SLEEPING;
+               aptCallHook(APTHOOK_ONSLEEP);
+               APT_ReplySleepNotificationComplete(envGetAptAppId());
+               LightEvent_Wait(&aptSleepEvent);
+               aptFlags &= ~FLAG_SLEEPING;
+
+               if (aptFlags & FLAG_ACTIVE)
+                       GSPGPU_SetLcdForceBlack(0);
+               aptCallHook(APTHOOK_ONWAKEUP);
+       }
+       else if ((aptFlags & FLAG_POWERBUTTON) || aptHomeButtonState)
+               aptProcessJumpToMenu();
+
+       if (aptFlags & (FLAG_ORDERTOCLOSE|FLAG_WKUPBYCANCEL))
+       {
+               aptFlags |= FLAG_EXITED;
+               aptCallHook(APTHOOK_ONEXIT);
+               return false;
        }
+
+       return true;
 }
 
 void aptHook(aptHookCookie* cookie, aptHookFn callback, void* param)
@@ -535,74 +519,32 @@ void aptUnhook(aptHookCookie* cookie)
        }
 }
 
-void aptAppStarted(void)
-{
-       aptSetStatus(APP_RUNNING);
-       svcClearEvent(aptStatusEvent);
-
-       if(!aptIsCrippled())
-       {
-               APT_UnlockTransition(0x10);
-               APT_SleepIfShellClosed();
-               APT_SleepIfShellClosed();
-       }
-}
-
-APT_AppStatus aptGetStatus(void)
+void aptSetMessageCallback(aptMessageCb callback, void* user)
 {
-       APT_AppStatus ret;
-       LightLock_Lock(&aptStatusMutex);
-       ret = aptStatus;
-       LightLock_Unlock(&aptStatusMutex);
-       return ret;
+       aptMessageFunc = callback;
+       aptMessageFuncData = user;
 }
 
-void aptSetStatus(APT_AppStatus status)
+bool aptLaunchLibraryApplet(NS_APPID appId, void* buf, size_t bufsize, Handle handle)
 {
-       LightLock_Lock(&aptStatusMutex);
+       bool sleep = aptIsSleepAllowed();
 
-       aptStatus = status;
+       aptSetSleepAllowed(false);
+       aptClearParamQueue();
+       APT_PrepareToStartLibraryApplet(appId);
+       aptSetSleepAllowed(sleep);
 
-       //if(prevstatus != APP_NOTINITIALIZED)
-       //{
-               if(status == APP_RUNNING)
-                       __ctru_speedup_config();
-               if(status == APP_RUNNING || status == APP_EXITING || status == APP_APPLETSTARTED || status == APP_APPLETCLOSED)
-                       svcSignalEvent(aptStatusEvent);
-       //}
-
-       LightLock_Unlock(&aptStatusMutex);
-}
-
-u32 aptGetStatusPower(void)
-{
-       u32 ret;
-       LightLock_Lock(&aptStatusMutex);
-       ret = aptStatusPower;
-       LightLock_Unlock(&aptStatusMutex);
-       return ret;
-}
-
-void aptSetStatusPower(u32 status)
-{
-       LightLock_Lock(&aptStatusMutex);
-       aptStatusPower = status;
-       LightLock_Unlock(&aptStatusMutex);
-}
+       aptScreenTransfer(appId, false);
 
-void aptSignalReadyForSleep(void)
-{
-       svcSignalEvent(aptSleepSync);
-}
+       aptSetSleepAllowed(false);
+       APT_StartLibraryApplet(appId, buf, bufsize, handle);
+       aptFlags &= ~FLAG_ACTIVE;
 
-bool aptIsSleepAllowed(void)
-{
-       return aptSleepAllowed;
-}
+       aptWaitForWakeUp(TR_LIBAPPLET);
+       memcpy(buf, aptParameters, bufsize);
+       aptSetSleepAllowed(sleep);
 
-void aptSetSleepAllowed(bool allowed)
-{
-       aptSleepAllowed = allowed;
+       return aptMainLoop();
 }
 
 Result APT_GetLockHandle(u16 flags, Handle* lockHandle)
@@ -746,7 +688,10 @@ Result APT_InquireNotification(u32 appID, APT_Signal* signalType)
        
        Result ret = aptSendCommand(cmdbuf);
        if (R_SUCCEEDED(ret))
+       {
+               _aptDebug(1, cmdbuf[2]);
                *signalType=cmdbuf[2];
+       }
 
        return ret;
 }
@@ -844,7 +789,7 @@ Result APT_UnlockTransition(u32 transition)
        return APT_AppletUtility(7, &out, sizeof(out), &transition, sizeof(transition));
 }
 
-Result APT_GlanceParameter(NS_APPID appID, void* buffer, size_t bufferSize, APT_Command* command, size_t* actualSize, Handle* parameter)
+Result APT_GlanceParameter(NS_APPID appID, void* buffer, size_t bufferSize, NS_APPID* sender, APT_Command* command, size_t* actualSize, Handle* parameter)
 {
        u32 cmdbuf[16];
        cmdbuf[0]=IPC_MakeHeader(0xE,2,0); // 0xE0080
@@ -864,15 +809,17 @@ Result APT_GlanceParameter(NS_APPID appID, void* buffer, size_t bufferSize, APT_
 
        if (R_SUCCEEDED(ret))
        {
+               if (sender)     *sender    =cmdbuf[2];
                if (command)    *command   =cmdbuf[3];
                if (actualSize) *actualSize=cmdbuf[4];
                if (parameter)  *parameter =cmdbuf[6];
+               else if (cmdbuf[6]) svcCloseHandle(cmdbuf[6]);
        }
 
        return ret;
 }
 
-Result APT_ReceiveParameter(NS_APPID appID, void* buffer, size_t bufferSize, APT_Command* command, size_t* actualSize, Handle* parameter)
+Result APT_ReceiveParameter(NS_APPID appID, void* buffer, size_t bufferSize, NS_APPID* sender, APT_Command* command, size_t* actualSize, Handle* parameter)
 {
        u32 cmdbuf[16];
        cmdbuf[0]=IPC_MakeHeader(0xD,2,0); // 0xD0080
@@ -892,9 +839,12 @@ Result APT_ReceiveParameter(NS_APPID appID, void* buffer, size_t bufferSize, APT
 
        if (R_SUCCEEDED(ret))
        {
+               _aptDebug(2, cmdbuf[3]);
+               if (sender)     *sender    =cmdbuf[2];
                if (command)    *command   =cmdbuf[3];
                if (actualSize) *actualSize=cmdbuf[4];
                if (parameter)  *parameter =cmdbuf[6];
+               else if (cmdbuf[6]) svcCloseHandle(cmdbuf[6]);
        }
 
        return ret;
@@ -919,6 +869,23 @@ Result APT_SendParameter(NS_APPID source, NS_APPID dest, APT_Command command, co
        return aptSendCommand(cmdbuf);
 }
 
+Result APT_CancelParameter(NS_APPID source, NS_APPID dest, bool* success)
+{
+       u32 cmdbuf[16];
+
+       cmdbuf[0] = IPC_MakeHeader(0xF,4,0); // 0xF0100
+       cmdbuf[1] = source != APPID_NONE;
+       cmdbuf[2] = source;
+       cmdbuf[3] = dest != APPID_NONE;
+       cmdbuf[4] = dest;
+
+       Result ret = aptSendCommand(cmdbuf);
+       if (R_SUCCEEDED(ret) && success)
+               *success = cmdbuf[2]&0xFF;
+
+       return ret;
+}
+
 Result APT_SendCaptureBufferInfo(const aptCaptureBufInfo* captureBuf)
 {
        u32 cmdbuf[16];
@@ -1013,6 +980,7 @@ Result APT_CheckNew3DS(bool* out)
        static bool flagInit, flagValue;
        if (!flagInit)
        {
+               *out = false;
                Result ret = APT_CheckNew3DS_System(&flagValue);
                if (R_FAILED(ret)) return ret;
                flagInit = true;
@@ -1071,55 +1039,6 @@ Result APT_StartLibraryApplet(NS_APPID appID, const void* param, size_t paramSiz
        return aptSendCommand(cmdbuf);
 }
 
-Result APT_LaunchLibraryApplet(NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize)
-{
-       Result ret=0;
-
-       APT_ReplySleepQuery(currentAppId, APTREPLY_REJECT);
-
-       ret=APT_PrepareToStartLibraryApplet(appID);
-
-       if(R_FAILED(ret))return ret;
-
-       APT_SleepIfShellClosed();
-
-       while(1)
-       {
-               bool tmp;
-               ret=APT_IsRegistered(appID, &tmp);
-               if(R_FAILED(ret))return ret;
-
-               if(tmp!=0)break;
-       }
-
-       aptCallHook(APTHOOK_ONSUSPEND);
-
-       __apt_launchapplet_appID = appID;
-       __apt_launchapplet_inhandle = inhandle;
-       __apt_launchapplet_parambuf = parambuf;
-       __apt_launchapplet_parambufsize = parambufsize;
-
-       // Set status to SUSPENDED.
-       svcClearEvent(aptStatusEvent);
-       aptSetStatus(APP_SUSPENDED);
-
-       // Save Vram
-       GSPGPU_SaveVramSysArea();
-
-       // Capture screen.
-       memset(__ns_capinfo, 0, 0x20);
-
-       aptInitCaptureInfo(__ns_capinfo);
-
-       // Send capture-screen info to the library applet.
-       APT_SendParameter(currentAppId, appID, APTCMD_REQUEST, __ns_capinfo, sizeof(__ns_capinfo), 0);
-
-       // Release GSP module.
-       GSPGPU_ReleaseRight();
-
-       return 0;
-}
-
 Result APT_PrepareToStartSystemApplet(NS_APPID appID)
 {
        u32 cmdbuf[16];