]> Chaos Git - corbenik/ctrulib.git/commitdiff
APT : preliminary support for exiting app
authorsmea <smealum@gmail.com>
Sat, 1 Feb 2014 12:27:52 +0000 (13:27 +0100)
committersmea <smealum@gmail.com>
Sat, 1 Feb 2014 12:27:52 +0000 (13:27 +0100)
arm11u/source/main.c
libctru/include/ctr/APT.h
libctru/include/ctr/svc.h
libctru/source/APT.c
libctru/source/svc.s
sdmc/source/main.c

index b28cac4742734251865c1612e88c077d265d76c4..3f49a562c6750a01a33367db90facd6cd125d257 100644 (file)
@@ -118,7 +118,7 @@ int main()
 
        aptSetupEventHandler();
 
-       while(1)
+       while(!aptGetStatus())
        {
                u32 PAD=((u32*)0x10000000)[7];
                renderEffect();
@@ -129,6 +129,7 @@ int main()
                svc_sleepThread(1000000000);
        }
 
+       aptExit();
        svc_exitProcess();
        return 0;
 }
index 32feef69760e76a8647e1569ab0840849b8b1913..60e7d750ef7688e05c8bf0ae210302e357c903e9 100644 (file)
@@ -11,9 +11,12 @@ typedef enum{
 extern Handle aptEvents[3];
 
 void aptInit();
+void aptExit();
 void aptOpenSession();
 void aptCloseSession();
 void aptSetupEventHandler();
+u32 aptGetStatus();
+void aptSetStatus(u32 status);
 
 Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle);
 Result APT_Initialize(Handle* handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2);
@@ -23,7 +26,10 @@ Result APT_JumpToHomeMenu(Handle* handle, u32 a, u32 b, u32 c);
 Result APT_InquireNotification(Handle* handle, u32 appID, u8* signalType);
 Result APT_NotifyToWait(Handle* handle, NS_APPID appID);
 Result APT_AppletUtility(Handle* handle, u32* out, u32 a, u32 size1, u8* buf1, u32 size2, u8* buf2);
-Result APT_GlanceParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize);
-Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize);
+Result APT_GlanceParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize, u8* signalType);
+Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize, u8* signalType);
+Result APT_ReplySleepQuery(Handle* handle, NS_APPID appID, u32 a);
+Result APT_PrepareToCloseApplication(Handle* handle, u8 a);
+Result APT_CloseApplication(Handle* handle, u32 a, u32 b, u32 c);
 
 #endif
index dbf3a1e3fb93e4135a43919594375e7c962b733e..e1566169e89a397b80f889b0326a9ca9a889046c 100644 (file)
@@ -7,6 +7,7 @@
        Result svc_createThread(Handle* thread, ThreadFunc entrypoint, u32 arg, u32* stacktop, s32 threadpriority, s32 processorid);
        void svc_exitThread();
        void svc_sleepThread(s64 ns);
+       Result svc_createMutex(Handle* mutex, bool initialLocked);
        Result svc_releaseMutex(Handle handle);
        Result svc_controlMemory(u32* outaddr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions); //(outaddr is usually the same as the input addr0)
        Result svc_createEvent(Handle* event, u8 resettype);
index 57c24e1d8e8973f1e3810ecbe1babf09914b78b6..78e097ea9b27d4a675aab5e4e3befafac3a8960c 100644 (file)
@@ -16,6 +16,9 @@ Handle aptEvents[3];
 Handle aptEventHandlerThread;
 u64 aptEventHandlerStack[APT_HANDLER_STACKSIZE/8]; //u64 so that it's 8-byte aligned
 
+Handle aptStatusMutex;
+u32 aptStatus;
+
 u32 aptParameters[0x1000/4]; //TEMP
 
 void aptEventHandler(u32 arg)
@@ -55,11 +58,27 @@ void aptEventHandler(u32 arg)
                                break;
                        case 0x1: //event 1 means app just started or we're returning to app
                                {
+                                       u8 signalType;
                                        aptOpenSession();
-                                       APT_ReceiveParameter(NULL, APPID_APPLICATION, 0x1000, aptParameters, NULL);
+                                       APT_ReceiveParameter(NULL, APPID_APPLICATION, 0x1000, aptParameters, NULL, &signalType);
                                        aptCloseSession();
        
-                                       // if(!draw)GSPGPU_AcquireRight(NULL, 0x0);
+                                       switch(signalType)
+                                       {
+                                               case 0x1: //application just started
+                                                       break;
+                                               case 0xB: //just returned from menu
+                                                       GSPGPU_AcquireRight(NULL, 0x0);
+                                                       break;
+                                               case 0xC: //exiting application
+                                                       aptOpenSession();
+                                                       APT_ReplySleepQuery(NULL, APPID_APPLICATION, 0x0);
+                                                       aptCloseSession();
+
+                                                       runThread=false;
+                                                       aptSetStatus(1); //app exit signal
+                                                       break;
+                                       }
                                }
                                break;
                        case 0x2: //event 2 means we should exit the thread
@@ -90,10 +109,21 @@ void aptInit()
        aptCloseSession();
 }
 
+void aptExit()
+{
+       aptOpenSession();
+       APT_PrepareToCloseApplication(NULL, 0x1);
+       aptCloseSession();
+       
+       aptOpenSession();
+       APT_CloseApplication(NULL, 0x0, 0x0, 0x0);
+       aptCloseSession();
+}
+
 void aptSetupEventHandler()
 {
        u8 buf1[4], buf2[4];
-       
+
        buf1[0]=0x02; buf1[1]=0x00; buf1[2]=0x00; buf1[3]=0x04;
        aptOpenSession();
        APT_AppletUtility(NULL, NULL, 0x7, 0x4, buf1, 0x1, buf2);
@@ -116,10 +146,30 @@ void aptSetupEventHandler()
        APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
        aptCloseSession();
 
+       svc_createMutex(&aptStatusMutex, true);
+       aptStatus=0;
+       svc_releaseMutex(aptStatusMutex);
+
        //create thread for stuff handling APT events
        svc_createThread(&aptEventHandlerThread, aptEventHandler, 0x0, (u32*)(&aptEventHandlerStack[APT_HANDLER_STACKSIZE/8]), 0x31, 0xfffffffe);
 }
 
+u32 aptGetStatus()
+{
+       u32 ret;
+       svc_waitSynchronization1(aptStatusMutex, U64_MAX);
+       ret=aptStatus;
+       svc_releaseMutex(aptStatusMutex);
+       return ret;
+}
+
+void aptSetStatus(u32 status)
+{
+       svc_waitSynchronization1(aptStatusMutex, U64_MAX);
+       aptStatus=status;
+       svc_releaseMutex(aptStatusMutex);
+}
+
 void aptOpenSession()
 {
        svc_waitSynchronization1(aptLockHandle, U64_MAX);
@@ -255,7 +305,7 @@ Result APT_AppletUtility(Handle* handle, u32* out, u32 a, u32 size1, u8* buf1, u
        return cmdbuf[1];
 }
 
-Result APT_GlanceParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize)
+Result APT_GlanceParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize, u8* signalType)
 {
        if(!handle)handle=&aptuHandle;
        u32* cmdbuf=getThreadCommandBuffer();
@@ -269,12 +319,13 @@ Result APT_GlanceParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32*
        Result ret=0;
        if((ret=svc_sendSyncRequest(*handle)))return ret;
 
+       if(signalType)*signalType=cmdbuf[3];
        if(actualSize)*actualSize=cmdbuf[4];
 
        return cmdbuf[1];
 }
 
-Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize)
+Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize, u8* signalType)
 {
        if(!handle)handle=&aptuHandle;
        u32* cmdbuf=getThreadCommandBuffer();
@@ -288,7 +339,55 @@ Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32*
        Result ret=0;
        if((ret=svc_sendSyncRequest(*handle)))return ret;
 
+       if(signalType)*signalType=cmdbuf[3];
        if(actualSize)*actualSize=cmdbuf[4];
 
        return cmdbuf[1];
 }
+
+Result APT_ReplySleepQuery(Handle* handle, NS_APPID appID, u32 a)
+{
+       if(!handle)handle=&aptuHandle;
+
+       u32* cmdbuf=getThreadCommandBuffer();
+       cmdbuf[0]=0x3E0080; //request header code
+       cmdbuf[1]=appID;
+       cmdbuf[2]=a;
+       
+       Result ret=0;
+       if((ret=svc_sendSyncRequest(*handle)))return ret;
+
+       return cmdbuf[1];
+}
+
+Result APT_PrepareToCloseApplication(Handle* handle, u8 a)
+{
+       if(!handle)handle=&aptuHandle;
+
+       u32* cmdbuf=getThreadCommandBuffer();
+       cmdbuf[0]=0x220040; //request header code
+       cmdbuf[1]=a;
+       
+       Result ret=0;
+       if((ret=svc_sendSyncRequest(*handle)))return ret;
+
+       return cmdbuf[1];
+}
+
+Result APT_CloseApplication(Handle* handle, u32 a, u32 b, u32 c)
+{
+       if(!handle)handle=&aptuHandle;
+
+       u32* cmdbuf=getThreadCommandBuffer();
+       cmdbuf[0]=0x270044; //request header code
+       cmdbuf[1]=a;
+       cmdbuf[2]=0x0;
+       cmdbuf[3]=b;
+       cmdbuf[4]=(a<<14)|2;
+       cmdbuf[5]=c;
+       
+       Result ret=0;
+       if((ret=svc_sendSyncRequest(*handle)))return ret;
+
+       return cmdbuf[1];
+}
index f5e5ffc117856f689ce66da8ab8e5deee4c41c5f..15a667e9e756041b57eba84c60d9c374345e8c72 100644 (file)
@@ -52,6 +52,15 @@ svc_sleepThread:
        svc 0x0A
        bx lr
 
+.global svc_createMutex
+.type svc_createMutex, %function
+svc_createMutex:
+       str r0, [sp, #-4]!
+       svc 0x13
+       ldr r3, [sp], #4
+       str r1, [r3]
+       bx lr
+
 .global svc_releaseMutex
 .type svc_releaseMutex, %function
 svc_releaseMutex:
index 74c6bb895c4540fb120d3bfece9fd403884b4bdf..9039842c45e9e0204c6b4b2566c298d2662a23da 100644 (file)
@@ -131,7 +131,7 @@ int main()
 
        aptSetupEventHandler();
        
-       while(1)
+       while(!aptGetStatus())
        {
                u32 PAD=((u32*)0x10000000)[7];
                renderEffect();
@@ -142,6 +142,7 @@ int main()
                svc_sleepThread(1000000000);
        }
 
+       aptExit();
        svc_exitProcess();
        return 0;
 }