LaunchAPPLServer: choose the right method for launching the app by system

This commit is contained in:
Wolfgang Thaller 2018-04-27 01:36:33 +02:00
parent d91c257d89
commit 797ab906f5
2 changed files with 140 additions and 69 deletions

View File

@ -5,4 +5,7 @@ add_application(LaunchAPPLServer
MacSerialStream.cc)
target_link_libraries(LaunchAPPLServer LaunchAPPLCommon)
set_target_properties(LaunchAPPLServer PROPERTIES LINK_FLAGS "-Wl,-gc-sections")
set_target_properties(LaunchAPPLServer PROPERTIES
CXX_STANDARD 17
LINK_FLAGS "-Wl,-gc-sections"
)

View File

@ -33,6 +33,7 @@
#include <Processes.h>
#include <string.h>
#include <stdio.h>
#include <memory>
#include <UnreliableStream.h>
@ -340,6 +341,113 @@ void SetBaud(long baud)
gSerialStream->setBaud(baud);
}
class AppLauncher
{
public:
virtual bool Launch(ConstStr255Param name) = 0;
virtual bool IsRunning(ConstStr255Param name) = 0;
};
class AppLauncherSingle : public AppLauncher
{
public:
virtual bool Launch(ConstStr255Param name)
{
gSerialStream->close();
LaunchParamBlockRec lpb;
memset(&lpb, 0, sizeof(lpb));
lpb.reserved1 = (unsigned long) name;
lpb.reserved2 = 0;
lpb.launchBlockID = extendedBlock;
lpb.launchEPBLength = 6;
lpb.launchFileFlags = 0;
lpb.launchControlFlags = 0xC000;
LaunchApplication(&lpb);
return false;
}
virtual bool IsRunning(ConstStr255Param name)
{
return false;
}
};
class AppLauncher7 : public AppLauncher
{
ProcessSerialNumber psn;
public:
virtual bool Launch(ConstStr255Param name)
{
LaunchParamBlockRec lpb;
memset(&lpb, 0, sizeof(lpb));
FSSpec spec;
FSMakeFSSpec(0,0,name,&spec);
lpb.launchBlockID = extendedBlock;
lpb.launchEPBLength = extendedBlockLen;
lpb.launchFileFlags = 0;
lpb.launchControlFlags = launchContinue;
lpb.launchAppSpec = &spec;
OSErr err = LaunchApplication(&lpb);
psn = lpb.launchProcessSN;
return err >= 0;
}
virtual bool IsRunning(ConstStr255Param name)
{
ProcessInfoRec info;
memset(&info, 0, sizeof(info));
info.processInfoLength = sizeof(info);
OSErr err = GetProcessInformation(&psn,&info);
return err == noErr;
}
};
class AppLauncherMultiFinder : public AppLauncher
{
public:
virtual bool Launch(ConstStr255Param name)
{
LaunchParamBlockRec lpb;
memset(&lpb, 0, sizeof(lpb));
lpb.reserved1 = (unsigned long) name;
lpb.reserved2 = 0;
lpb.launchBlockID = extendedBlock;
lpb.launchEPBLength = 6;
lpb.launchFileFlags = 0;
lpb.launchControlFlags = 0xC000;
OSErr err = LaunchApplication(&lpb);
return err >= 0;
}
virtual bool IsRunning(ConstStr255Param name)
{
uint8_t *fcbs = *(uint8_t**)0x34E; // FCBSPtr;
uint16_t bufSize = * (uint16_t*) fcbs;
uint8_t *end = fcbs + bufSize;
for(uint8_t *fcb = fcbs + 2; fcb < end; fcb += 94)
{
if(*(uint32_t*) fcb == 0)
continue;
if(*(OSType*) (fcb + 0x32) != 'APPL')
continue;
if(EqualString(fcb + 0x3E, "\pRetro68App", true, true))
return true;
}
return false;
}
};
int main()
{
#if !TARGET_API_MAC_CARBON
@ -372,6 +480,24 @@ int main()
LaunchServer server(&rStream);
std::unique_ptr<AppLauncher> appLauncher;
#if TARGET_API_MAC_CARBON || TARGET_RT_MAC_CFM
appLauncher = std::make_unique<AppLauncher7>();
#else
SysEnvRec environ;
SysEnvirons(curSysEnvVers, &environ);
if(environ.systemVersion >= 0x0700)
appLauncher = std::make_unique<AppLauncher7>();
else
{
uint32_t& Twitcher2 = *(uint32_t*) 0xB7C;
if(Twitcher2 == 0 || Twitcher2 == 0xFFFFFFFF)
appLauncher = std::make_unique<AppLauncherSingle>();
else
appLauncher = std::make_unique<AppLauncherMultiFinder>();
}
#endif
for(;;)
{
@ -432,80 +558,22 @@ int main()
if(server.state == LaunchServer::State::launch)
{
//
if(appLauncher->Launch("\pRetro68App"))
{
LaunchParamBlockRec lpb;
memset(&lpb, 0, sizeof(lpb));
server.state = LaunchServer::State::wait;
nullEventCounter = 0;
#if 1
lpb.reserved1 = (unsigned long) "\pRetro68App";
lpb.reserved2 = 0;
lpb.launchBlockID = extendedBlock;
lpb.launchEPBLength = 6;
lpb.launchFileFlags = 0;
lpb.launchControlFlags = 0xC000;
// stream.close();
#else
FSSpec spec;
FSMakeFSSpec(0,0,"\pRetro68App",&spec);
lpb.launchBlockID = extendedBlock;
lpb.launchEPBLength = extendedBlockLen;
lpb.launchFileFlags = 0;
lpb.launchControlFlags = launchContinue;
lpb.launchAppSpec = &spec;
#endif
OSErr err = LaunchApplication(&lpb);
if(err < 0)
{
server.state = LaunchServer::State::size;
SetStatus(AppStatus::ready, 0, 0);
}
else
{
psn = lpb.launchProcessSN;
server.state = LaunchServer::State::wait;
nullEventCounter = 0;
SetStatus(AppStatus::running, 0, 0);
}
SetStatus(AppStatus::running, 0, 0);
}
else
{
server.state = LaunchServer::State::size;
SetStatus(AppStatus::ready, 0, 0);
}
}
else if(server.state == LaunchServer::State::wait && nullEventCounter > 3)
{
bool running = false;
#if 0
ProcessInfoRec info;
memset(&info, 0, sizeof(info));
info.processInfoLength = sizeof(info);
OSErr err = GetProcessInformation(&psn,&info);
running = (err == noErr);
#else
{
uint8_t *fcbs = *(uint8_t**)0x34E; // FCBSPtr;
uint16_t bufSize = * (uint16_t*) fcbs;
uint8_t *end = fcbs + bufSize;
for(uint8_t *fcb = fcbs + 2; fcb < end; fcb += 94)
{
if(*(uint32_t*) fcb == 0)
continue;
if(*(OSType*) (fcb + 0x32) != 'APPL')
continue;
if(EqualString(fcb + 0x3E, "\pRetro68App", true, true))
{
running = true;
break;
}
}
}
#endif
if(!running)
if(!appLauncher->IsRunning("\pRetro68App"))
{
server.state = LaunchServer::State::respond;
uint32_t zero = 0;