LaunchAPPLServer: launch MPW tools by sending AppleEvent to MPW Shell

This commit is contained in:
Wolfgang Thaller 2018-05-06 00:56:48 +02:00
parent 672efae198
commit f9a4fc491d
4 changed files with 129 additions and 5 deletions

View File

@ -9,3 +9,4 @@ public:
};
std::unique_ptr<AppLauncher> CreateAppLauncher();
std::unique_ptr<AppLauncher> CreateToolLauncher();

View File

@ -4,7 +4,8 @@ add_application(LaunchAPPLServer
MacSerialStream.h
MacSerialStream.cc
AppLauncher.h
AppLauncher.cc)
AppLauncher.cc
ToolLauncher.cc)
target_link_libraries(LaunchAPPLServer LaunchAPPLCommon)
set_target_properties(LaunchAPPLServer PROPERTIES

View File

@ -273,6 +273,8 @@ public:
State state = State::command;
RemoteCommand command;
OSType type, creator;
void onReset()
{
SetStatus(AppStatus::ready, 0, 0);
@ -297,8 +299,8 @@ public:
{
if(n < 16)
return 0;
OSType type = *(const OSType*)(p+0);
OSType creator = *(const OSType*)(p+4);
type = *(const OSType*)(p+0);
creator = *(const OSType*)(p+4);
dataSize = *(const uint32_t*)(p+8);
rsrcSize = *(const uint32_t*)(p+12);
@ -430,7 +432,7 @@ int main()
TEInit();
InitDialogs(NULL);
#endif
#if TARGET_CPU_68K && !TARGET_RT_MAC_CFM
short& ROM85 = *(short*) 0x028E;
Boolean is128KROM = (ROM85 > 0);
@ -494,7 +496,7 @@ int main()
LaunchServer server(&rStream);
std::unique_ptr<AppLauncher> appLauncher = CreateAppLauncher();
std::unique_ptr<AppLauncher> appLauncher;
if(gPrefs.inSubLaunch)
{
@ -589,6 +591,11 @@ int main()
ExitToShell();
}
if(server.type == 'MPST')
appLauncher = CreateToolLauncher();
else
appLauncher = CreateAppLauncher();
bool launched = appLauncher->Launch("\pRetro68App");
gPrefs.inSubLaunch = false;
WritePrefs();
@ -603,6 +610,7 @@ int main()
else
{
server.state = LaunchServer::State::command;
gSerialStream->open();
SetStatus(AppStatus::ready, 0, 0);
}
}

View File

@ -0,0 +1,114 @@
#include "AppLauncher.h"
#include <AppleEvents.h>
#include <vector>
#include <string.h>
class ToolLauncher : public AppLauncher
{
bool replyReceived;
AEEventHandlerUPP replyHandler = nullptr;
static pascal OSErr handleReply(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon)
{
ToolLauncher *self = (ToolLauncher*)handlerRefcon;
self->replyReceived = true;
AERemoveEventHandler(kCoreEventClass, kAEAnswer, handleReply, false);
return noErr;
}
Handle buildCommandLine(ConstStr255Param name)
{
CInfoPBRec pb;
memset(&pb, 0, sizeof(pb));
pb.hFileInfo.ioNamePtr = (StringPtr)name;
PBGetCatInfoSync(&pb);
long dirID = pb.hFileInfo.ioFlParID;
std::vector<unsigned long> dirIDs;
while(dirID != 2)
{
dirIDs.push_back(dirID);
pb.dirInfo.ioNamePtr = 0;
pb.dirInfo.ioDrDirID = dirID;
pb.dirInfo.ioFDirIndex = -1;
PBGetCatInfoSync(&pb);
dirID = pb.dirInfo.ioDrParID;
} while(dirID != 2);
dirIDs.push_back(dirID);
Handle text;
PtrToHand("\"", &text, 1);
for(int i = dirIDs.size() - 1; i >= 0; i--)
{
Str32 dirName;
pb.dirInfo.ioNamePtr = dirName;
pb.dirInfo.ioDrDirID = dirIDs[i];
pb.dirInfo.ioFDirIndex = -1;
PBGetCatInfoSync(&pb);
PtrAndHand(dirName+1, text, dirName[0]);
PtrAndHand(":", text, 1);
}
long sz1 = GetHandleSize(text);
PtrAndHand(name+1, text, name[0]);
PtrAndHand("\" > ", text, 4);
long sz2 = GetHandleSize(text);
SetHandleSize(text, sz2 + sz1 + 4);
memcpy((*text) + sz2, *text, sz1);
memcpy((*text) + sz1 + sz2, "out\"", 4);
return text;
}
public:
virtual bool Launch(ConstStr255Param name)
{
if(!replyHandler)
replyHandler = NewAEEventHandlerUPP(&handleReply);
AEInstallEventHandler(kCoreEventClass, kAEAnswer, handleReply, (long)this, false);
AEAddressDesc address;
OSType signature = 'MPS ';
OSErr err = AECreateDesc(typeApplSignature, &signature, 4, &address);
AppleEvent ae;
err = AECreateAppleEvent('misc', 'dosc', &address, kAutoGenerateReturnID, kAnyTransactionID, &ae);
Handle command = buildCommandLine(name);
Str255 commandP;
commandP[0] =GetHandleSize(command);
memcpy(commandP + 1, *command, commandP[0]);
HLock(command);
err = AEPutParamPtr(&ae, keyDirectObject, typeChar, *command, GetHandleSize(command));
DisposeHandle(command);
AppleEvent reply;
err = AESend(&ae, &reply, kAEQueueReply | kAEAlwaysInteract | kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout, nullptr, nullptr);
AEDisposeDesc(&address);
AEDisposeDesc(&ae);
return err == noErr;
}
virtual bool IsRunning(ConstStr255Param name)
{
return !replyReceived;
}
};
std::unique_ptr<AppLauncher> CreateToolLauncher()
{
return std::make_unique<ToolLauncher>();
}