[comp.sys.mac] How to launch an application

pwu@uwmacc.UUCP (Peter Wu) (04/21/87)

Can someone show me how to launch an application from an assembly
program? Thanks.

peter
/*
** ARPA: pwu@trochos.wisc.edu (128.105.2.200)  BITNET: WU at WISVMACC
** UUCP: {seismo|harvard|topaz|caip|ll-xn|                      <-+   
**        allegra|akgua|ucbvax|bellcore|ihnp4}!uwvax!trochos!pwu  |
**                                                                |
**   Uuhosts on this line may have faster delivery time.  --------+
*/

jkm@security.uucp (Jonathan K.Millen) (04/22/87)

In article <1405@uwmacc.UUCP> pwu@uwmacc.UUCP (Peter Wu) writes:
>Can someone show me how to launch an application from an assembly
>program? Thanks.
>
I hope an answer to that is posted, especially if it shows how to tell
the application the name of an application to open.  Inside Mac is very
hard to follow on this.

-Jon Millen
				"We should stand on the shoulders of those
decvax!linus!security!jkm       who have gone before us, not on each
jkm@mitre-bedford.arpa          other's toes."

miker@uwmacc.UUCP (m radovancevich) (04/23/87)

In article <1405@uwmacc.UUCP> pwu@uwmacc.UUCP (Peter Wu) writes:
>Can someone show me how to launch an application from an assembly
>program? Thanks.
>
>peter
>/*
>** ARPA: pwu@trochos.wisc.edu (128.105.2.200)  BITNET: WU at WISVMACC
>** UUCP: {seismo|harvard|topaz|caip|ll-xn|                      <-+   
>**        allegra|akgua|ucbvax|bellcore|ihnp4}!uwvax!trochos!pwu  |
>**                                                                |
>**   Uuhosts on this line may have faster delivery time.  --------+
>*/

There are two ways to do it.

Chain procedure

	_Chain

	(A0): pointer to the applications file name
       4(A0): integer specifying the configureation of the
	      sound & screen buffers.

	This starts up the application without doing anything to the app.
	heap, keeping the calling applications data around in the heap.

	_Launch

	same parameters

	This is the same call made by the finder when starting an application.


	the integer in 4(A0) can have the following meanings.

	4(A0)		meaning
	---------------------------------
	0		use main screen & sound buffs
	<0		use alt sound & main Screen
	>0		use alt sound & alt Screen


	Just a warning,  I think the Mac SE and The Mac II don't have
	alternate buffers so beware.



-- 
Michael P. Radovancevich     Univ. of Wisconsin - Madison C.S. Dept.
Univ. of Wisconsin - Madison Academic Computing Center (MACC) Micro Consultant
UUCP :   ...{allegra,ihnp4,seismo}!uwvax!uwmacc!miker
ARPA :   miker@unix.macc.wisc.edu

pgn@osupyr.UUCP (04/23/87)

I'd love to see Pascal and C codes of how to launch another application from
within an application. Please post them, or else send them to me.

Have Orthogonal Polynomials
Will Travel

Paul Nevai                                pgn@osupyr.uucp (PREFERRED) 
Department of Mathematics                 nevai-p@osu-eddie.uucp
The Ohio State University                 73057,172.Compu$erve
231 West Eighteenth Avenue                TS1171@OHSTVMA.bitnet
Columbus, OH 43210, U.S.A.                1-614-292-5688

earleh@dartvax.UUCP (Earle R. Horton) (04/24/87)

In article <3326@linus.UUCP>, jkm@security.uucp (Jonathan K.Millen) writes:
> In article <1405@uwmacc.UUCP> pwu@uwmacc.UUCP (Peter Wu) writes:
> >Can someone show me how to launch an application from an assembly
> >program? Thanks.
> >
> I hope an answer to that is posted, especially if it shows how to tell
> the application the name of an application to open.  Inside Mac is very
> hard to follow on this.
> 
> -Jon Millen
> 				"We should stand on the shoulders of those
> decvax!linus!security!jkm       who have gone before us, not on each
> jkm@mitre-bedford.arpa          other's toes."

Launch is a lot of fun.  Here is a complete desk accessory example of
how to do it.  With minimal work, this can be incorporated into the code
of an application...  There are some points to be noted here.  The first
is it is more trouble to get the file name of the application than to
do the launch itself!  It is perhaps a good idea to flush all volumes
before calling launch, and it is required to "_SetVol" to the correct
volume before doing so.  The last I can think of is: my "doflush"
routine destroys the contents of A3, meaning it is perhaps NOT a good
choice for a standalone routine to be called from Basic or Pascal.

I heartedly agree with Jon's motto!  I included
the binhex of the desk accessory for non-programmer types.

	include mds:library:Pushpop.txt 	;push and pop macros
	include mds:library:Packages.txt	;Macintosh package macros
	include mds:library:NewLib.D		;assembler equates 

	IOFVersNum	EQU	26
	myparamblk	equ	-80		;stack frame offsets
	otherparamblk	equ	-160
	SFReply		equ	-240
	saveport	equ	-4
	thetype		equ	-6
	itemhandle	equ	-8
	thebox		equ	-16
	filtervars	equ	-16
;
;Earle Horton's Transfer DA
;
OrnEntry
	DC.W		$0400		; ctl-enable only
	DC.W		0		; doesn't need time
	DC.W		$0040		; update events only
	DC.W		0		; no menu
	DC.W	Launch1-OrnEntry	; open routine
	DC.W	Dummy-OrnEntry		; prime - unused
	DC.W	Dummy-OrnEntry 		; control
	DC.W	Dummy-OrnEntry		; status - unused
	DC.W	Dummy-OrnEntry		; close
Dummy:
	rts
;
;	To use in an application, uncomment the next line and cut out
;	all the desk accessory stuff, then assemble and link to your
;	application.  (After you have hacked the code to your taste,
;	of course.)  Suggested calling procedure:
;		extern Launch1();
;		Launch1();
;	Or, from assembler:
;		xref Launch1
;		jsr Launch1
;
;	xdef Launch1
Launch1:
	link	a6,#-240		;get a stack frame
	push.l	SFPoint			;box coordinates
	clr.l	-(sp)			;no prompt string
	pea	fakefilter		;not a real file filter
	push.w	#$01			;one type
	pea	mytypelist 		;push typelist pointer
	clr.l	-(sp)			;no dialog hook procedure
	pea	SFReply(a6)		;reply area pointer	
	_SFGetFile			;call the package routine
	tst.w	SFReply+rGood(a6)	;cancel button?
	beq	endofstuff		;yes, back to main procedure
	bsr	doflush			;flush all disk buffers first
					;in case some application forgot
	lea	myparamblk(a6),a0	;load parameter block
	clr.l	ioVNPtr(a0)		;clear volume name
	move.w	SFReply+rVolume(a6),ioVRefNum(a0)
					;load WDRefNum instead
	clr.w	ioFDirIndex(a0)		;clear directory index field
	clr.w	IOFVersNum(a0)		;clear file version field
	_SetVol				;launch on correct volume!
	clr.w	-(SP)			;zero for normal sound and screen
	lea	SFReply+rName(a6),a0	;load name pointer
	move.l	a0,-(sp)		;push it
	move.l	SP,A0			;put it in a0
	_Launch				;Launch away
endofstuff:   				;second thoughts
	unlk	a6
	rts
fakefilter:	;This is not a file filter.  It is just a procedure to
		;change the title of the SFGetFile box's open button.
		;The button might flash a little bit if a whole bunch
		;of applications are found.  It probably would be better
		;to use some private storage to remember if this routine
		;had been called before.
	link	a6,#filtervars		;get a stack frame
	pea	saveport(a6)		;push a handle
	_GetPort			;get a handle to SFGetFile box port
	push.l	saveport(a6)		;push the port
	push.w	#1			;item #1, the open button
	pea	thetype(a6)		;address of item type
	pea	itemhandle(a6)		;address of item handle (want this)
	pea	thebox(a6)		;address of item's rect
	_GetDItem			;get the item
	push.l	itemhandle(a6)		;push the item handle
	pea	runmsg			;our title of open button
	_SetCTitle			;set it
	unlk	a6			;done for now
	move.w	#0,8(sp)		;display OK
	move.l	(sp)+,(sp)		;move return -> parameter
	rts				;exit	
doflush:	;This piece of code flushes all online volumes in
		;preparation for the launch.  It does NOT write out
		;any data that the open application had been planning
		;to write to any open files.  (How could it?)
	move.l	VCBQHdr+2,a3		;a3 -> VCB entry
scan:
	tst.w	VCBDrvNum(a3)		;volume on line?
	beq.s	nextone			;no, get next
	lea	myparamblk(a6),a0	;a0 -> stack frame parameter block
	move.l	VCBVN(a3),ioVNPtr(a0)	;set volume name
	clr.w	ioVDrvNum(a0)		;clear drive number
	_FlushVol			;flush it
nextone:
	move.l	(a3),a3			;a3 -> next in chain
	move.l	a3,d1			;move to D1 (just testing)
	bne.s	scan			;try again
	rts
;
;
;	Constant data area
;
	.ALIGN 4
	STRING_FORMAT 0
SFPoint: 	DC.W	100,75		;Point for standard file window
MyTypelist:	dc.b	'APPL'		;file types to launch
;
	STRING_FORMAT 3			;Pascal type strings
runmsg		dc.b	'Run'
------------------------------------------------------------------
linker command file to generate the code for the DA
------------------------------------------------------------------
[
/Output mds:transfer_folder:TransferDA
mds:Transfer_folder:TransferDA
$

------------------------------------------------------------------
RMaker command file to make it into a 'DRVR'
------------------------------------------------------------------
*Output file name and the Type and Creator flags
mds:TransferDeskAcc
DFILDMOV

* 
TYPE DRVR = PROC
  Launch,16
mds:Transfer_folder:TransferDA

------------------------------------------------------------------
Just in case, the binhex file.
------------------------------------------------------------------

(This file must be converted with BinHex 4.0)

:$e4bB@jcCQ9b4'9cDd&MB`"%4NP-4%e29J#3#!)4phd!N!3"!*!$!GJ!N!2B!*!
$13F""`%(!3F""`%(!3F#"3%&!38""3%(!3F""`%(!3F"$e4bB@jcCQ9b4'9cDd&
MB`)!N$'FY*1'!*!'!K%(!3S""3%)!3N"#!%)!JS)#!%*!3N"#!%-!3X""J%*!3F
""`%%!33""`%*!3J"$`!+!*!'"qU3!!#3"0N!"J!!rrF!"J!,!a)!#3!#!*!$-`#
3-Y3%!*!%3!#3!a3!%J!5!")!%Nje6PEr%#mk!+T#TdKk!%Sr2!!"5(S!S%+R5'l
r%$mm!!+TkNTZra"R!!!U6VS!B%(Zrl"#U!!5-@lr&J!@3QJ!(%*S!"UJ&8*R3Hl
r'Lm))%qTmNjH6R919[r`5'lrr+Kd,blrr$mm!!&)E[rk5'lrq%KZrr#TM5mZrrK
)HJ!mU9p1AMpm!*!$##kI6R8QH!0B5QX!5'F33HlrX#&V!#`!%N*S!"DJ%bC6)JY
Qj%je!*!$C!",39"36!05G@i$8R9Z!!!"!*!$!GJ!N!2B!*!$13!!rb3"f!#3!a`
!-J!!4&*@8J#3!`S!%!#3#JC-BA9ZBfJfb`:
------------end of transmission------------

wmcb@ecsvax.UUCP (William C. Bauldry) (04/24/87)

Here's a little routine to launch a program selected through the
standard file package. (Done with LightSpeed Pascal - great product!)

program launch;
const
   Launch=$A9F2; { * trap word * }

Var
   TopLeft: Point;
   PromptString : str255;
   FileFilter : ProcPtr;
   NumTypes : integer;
   TypeList : SFTypeList;
   DialogHook : ProcPtr;
   Reply : SFReply;

   myFile : Packed Record
      name: Ptr;
      buffers : integer;
    end;

   myFileHandle : Handle;

   registers = record
      a : array[0..4] of longint;
      d : array[0..7] of longint;
    end;

Procedure CleanUp;
 begin
  { * Clean up current application's mess before the Launch * }
 end;

begin { * Launch * }
   TopLeft.v := 75  { * where to put the dialog box * }
   TopLeft.h := 100;
   PromptString :=''; { * leftover from a previous system * }
   FileFilter := nil;
   NumTypes :=1;      { * we're just interested in applications * }
   TypeList[0] := 'APPL';
   DialogHook := nil;

   SFGetFile( TopLeft, PromptString, fileFilter, NumTypes, Typelist,
                     DialogHook, Reply);

   If (Reply.good:=true) then { * a file was selected to run * }
      begin
         CleanUp;

         myFile.name := @Reply.FName;
         myFileBuffers :=0;  { * 0 : launch with main screen & sound buffs * }
                             { * + :             main        & alternate   * }
                             { * - :             alt         & alt         * }

         registers.a[0] := longint(myFileHandle);

         Generic( Launch, registers );
      end; { * good launch * }

end. { * Launch * }

We havew to use the Generic call since this routine (Launch) expects
A0 to hold a pointer to the name followed by the code for the buffer
e. Launch is register not stack based.
i.e. Launch is a register, not stack, based routine.

Next week the Launch done in Assembler will appear.

-----------------------------------
Bill Bauldry
Dept. of Math Sci
Appalachian State U
Boone, NC 28608		(wmcb@ecsvax.UUCP)
allocations.

waldman@husc4.HARVARD.EDU (benjamin waldman) (05/02/87)

	
	In posting 1405, someone asked how to start an application from
assembly language.  I mailed him an answer directly, but since the same
question has been asked again, I'll post a response.
	Basically, there are two ways to start an application.  You can
use the _Launch trap ($A9F2, I think), or the _Chain trap.  Both start a
new application, but while _Launch clears the application heap, _Chain
does not, enabling one application to pass information to a second.
The Finder uses _Launch.
	Before you use either of these traps, the following must be set up.
(A0) should be a pointer to the name of the new application, a Pascal
string, I presume.  The value in 4(A0) determines which screen and sound
buffers are used.  A 0 means use the main screen and sound buffers, any
positive value means use the alternate sound and main screen buffers, and
any negative value means use the alternate screen and alternate sound buffer.
For the sake of compatibility, only the main screen and sound buffers should
be used, since not all Macs have the alternate buffers  (I think that this is
what got Megaroids into trouble).
	Anyway, I think that this piece of code will serve as a demonstration.
I haven't used it or tested it, but I think it should work.

	String_Format 3   (make sure that strings are Pascal strings)
buffer:	ds.l 2
name:	dc.b "My application"

	lea buffer(A5),A0
	lea name,A1
	move.l A1,(A0)
	clr.l 4(A0)
	_Launch

	I hope this is helpful.
					
					Benjamin Waldman
					waldman@husc4.harvard.edu