jww@sdcsvax.UCSD.EDU (Joel West) (05/21/87)
[ We had so much discussion of launching and sublaunching that, now that this is available, I thought I'd pass it along -- jww] ________________________________________________________________________________ Macintosh Technical Notes #126: Sublaunching: playing the Shell game See also: Segment Loader Written by: Rick Blair May 4, 1987 ________________________________________________________________________________ Note: Macintosh Technical Support takes the view that this is a feature which is best left out for compatibility (and other) reasons, but we want to make sure that when it is absolutely necessary to implement it, it is done in the safest way. Herein is a means to launch an application from your program and have it return to you as though you were a Rshell,S like the Finder. There are unresolved issues, though (and some downright problems), so please read the cautionary notes which follow. ________________________________________________________________________________ Warning The interface to the Launch trap will change in the not-too-distant future. When that happens, programs which launch other applications will break. You should really only consider doing this if you are implementing an integrated development system. The Finder does a lot of hidden cleanups and other tasks of which the user isn't aware. Therefore it is best if you don't try to replace the Finder with a "mini," or try to launch other programs and have them return to your application. In the future the Finder may provide better integration for applications and you would circumvent this if you tried to take over its role. Nevertheless, consider a text editor that wants to allow the user to run, say, ResEdit, and then return to program editing. If it isn't worried about the transition to new environments, then it would want to do this in a way that would fit into the current system well. System file version 4.1 (or higher) includes a mechanism for allowing a call to another application which we term a sublaunch. This is accomplished with a set of simple extensions to the parameter block which is passed to the Launch trap. A Sublaunch from Pascal {It is assumed that the Signals are caught elsewhere; see Technical Note #88 for more information on the Signal mechanism} {the extended parameter block to _Launch} TYPE pLaunchStruct = ^LaunchStruct; LaunchStruct = record pfName: ^Str255; param: INTEGER; LC:PACKED ARRAY[0..1] OF CHAR; {start of extended parameter block} ExtBlockLen: LONGINT; {number of bytes in extension = 6} fFlags: INTEGER; {Finder file info flags (see below)} LaunchFlags: LONGINT; {bit 31=1 for sublaunch, other bits reserved} End; {LaunchStruct} VAR pMyLaunch: pLaunchStruct; myLaunch: LaunchStruct; fName: Str255; PROCEDURE LaunchIt(pLnch: pLaunchStruct);INLINE $205F, $A9F2; { pops pointer into A0 and calls Launch } PROCEDURE DoLaunch; VAR wher: Point; { where to display dialog } reply: SFReply; { reply record } myFileTypes: SFTypeList; { we won't actually use this } NumFileTypes: integer; myPB: CInfoPBRec; DirNameStr: str255; BEGIN wher.h := 20; wher.v := 20; NumFileTypes:= -1; {Display all files} { Let the user choose the file to Launch } SFGetFile (wher, '', Nil, NumFileTypes, MyFileTypes, NIL, reply); IF reply.good THEN begin DirNameStr:= reply.fName; {initialize to file selected} with MyPB do Begin ioCompletion:= NIL; ioNamePtr:= @DirNameStr; ioVRefNum:= reply.vRefNum; ioFDirIndex:= 0; ioDrDirID:=0 End; {with MyPB} { Get the Finder flags } Signal(PBGetCatInfo(@MyPB,FALSE)); { Set the current volume to where the target application is } Signal(SetVol(NIL, reply.vRefNum)); pMyLaunch:= @myLaunch; fName:= reply.fName; With pMyLaunch^ do Begin pfName:= @fName; {pointer to our fileName} param:= 0; {we don't want alternate screen or sound buffers} LC := 'LC'; {here to tell Launch that there is non-junk next} ExtBlockLen := 6; {length of param. block past this long word} {copy flags; set bit 6 of low byte to 1 for RO access:} fFlags := MyPB.ioFlFndrInfo.fdFlags; {from GetCatInfo} LaunchFlags := $80000000; {set hi bit to indicate a sublaunch} End; {With} Launchit(pMyLaunch); {do the actual launch} end; {IF reply.good} End; {DoLaunch} Working directories Putting aside the compatibility issue for the moment, the only problem this creates under the current system is one of Working Directory Control Blocks, or WDCBs. Unless the application you are launching is at the root or on an MFS volume, a new WDCB must be created so that it may be set as the current directory when the program is run. In the example procedure above, the new working directory is opened (allocated) by Standard File and its WDRefNum is returned in reply.vRefNum. If you weren't using Standard File and couldn't assume, for instance, that the application was in the blessed folder or root then you would have to open a new working directory explicitly via OpenWD. The new WDCB should have a WDProcID of 'ERIK' so that the Finder or another shell that saw that the WDCB had been allocated by a RsublauncheeS would know to de-allocate it. The sublaunching process is recursive; you may sublaunch a program which then sublaunches another, and so on, and when each application exits it will return to the one that called it. The problem is that there is a limit to the number of WDCBs that can be created; currently (and probably forever) the limit is 40. You can see how quickly these might be used up if many programs were playing the shell game or neglecting to de-allocate WDCBs they had created. The ideal thing for a truly friendly shell to do would be to make a list of all 'ERIK' WDCBs that were in existence when it first started running. It could do this by indexed calls to GetWDInfo, and the only information it would have to save would be the WDRefNum of each 'ERIK' block. When a program it had launched returned to it, it could once again sequence through all the WDCBs and throw away any that weren't on the original list. WDCBs with WDProcIDs other than 'ERIK' should be left alone. -- Joel West {ucbvax,ihnp4}!sdcsvax!jww (ihnp4!gould9!joel if I ever fix news) jww@sdcsvax.ucsd.edu if you must