;  EXAMPLE.ASM written 09/15/86 by Martin Murray
;		last modified 02/22/90 by Martin Murray and Tim Martin
	incdir	"CAPE2.5:includes,CAPE2.5:examples/IntuitionTutor"
	OPTIMON
	OBJFILE "RAM:IntuitionTutor.o"

;***************************************************************************
;*  THIS CODE IS IN NO WAY COPYRIGHT BY INOVATRONICS, INC.  IN FACT, YOU   *
;*  CAN DO ANYTHING WITH IT THAT YOU WANT TO DO.  JUST REMEMBER,           *
;*  INOVATRONICS, INC. WILL BEAR ABSOLUTELY NO RESPONSIBILITY FOR THE USE, *
;*  MISUSE, INABILITY TO USE OR INABLITY TO UNDERSTAND ANY OR ALL PARTS OF *
;*  THIS CODE.  ENJOY IT IN GOOD HEALTH.                                   *
;***************************************************************************

	include	"exec/types.i"
	include	"exec/io.i"
	include	"exec/strings.i"
	include	"libraries/dosextens.i"
	include	"intuition/intuition.i"

	xref	_AbsExecBase

;************   EQUATES
NULL	equ	0

;************   MACROS
xlib	macro
	xref	_LVO\1
	endm

callsys   macro   (routine name to call, A6 must have base pointer of library)
	xlib	\1
	CALLLIB	_LVO\1
	endm

call	macro	(address to call)
	bsr	\1
	endm

push	macro	(long ea to push)
	move.l	\1,-(sp)
	endm

pull	macro	(long ea to fetch without popping)
	move.l	(sp),\1
	endm

pop	macro	(long ea to pop into)
	move.l	(sp)+,\1
	endm


;*********   DATA AREA
	DATA
	include "PWInterface.i"		;include the PowerWindows code

Intuitionname:		cstring 'intuition.library'
DOSname:		cstring 'dos.library'
MenuMsg:		cstring	'You selected a MenuItem or SubItem.',LF
MenuMsgLen		equ	*-MenuMsg
BoolGadgetMsg:		cstring	'You hit the Bool Gadget.',LF
BoolGadgetMsgLen	equ	*-BoolGadgetMsg
StringGadgetMsg:	cstring	'You hit the String Gadget.',LF
StringGadgetMsgLen	equ	*-StringGadgetMsg
PropGadgetMsg:		cstring	'You hit the Prop Gadget.',LF
PropGadgetMsgLen	equ	*-PropGadgetMsg
	cnop	0,2
InitialSP:	dc.l	0
MeMyselfandI:	dc.l	0
ReturnMsg:	dc.l	0
_IntuitionBase:	dc.l	0
_DOSBase:	dc.l	0
StdOut:		dc.l	0
CurrentWindow:	dc.l	0
	ifd NewScreenStructure
CurrentScreen:	dc.l	0
	ifd Palette
_GFXBase:	dc.l	0
Graphicsname:	cstring 'graphics.library'
	cnop	0,2
	endc
	endc

;************   PROGRAM START
	CODE
Main:
;Intitialize by saving the stack pointer and finding our own task.
	move.l	sp,InitialSP		;save the stack pointer
	move.l	_AbsExecBase,a6		;get the system library address
	sub.l	a1,a1
	callsys	FindTask		;please, I must find myself
	move.l	d0,MeMyselfandI		;save the address of the TCB list
	move.l	d0,a0			;  node in case we need it for some
					;  reason
	tst.l	pr_CLI(a0)		;were we run by Workbench?
	bne.s	1$			;no-jump
	lea	pr_MsgPort(a0),a0	;wait for the startup message
	push	a0
	callsys	WaitPort
	pop	a0			;get it
	callsys	GetMsg
	move.l	d0,ReturnMsg		;save the message
1$:
	moveq	#0,d0			;open intuition.library
	lea	Intuitionname,a1
	callsys	OpenLibrary
	move.l	d0,_IntuitionBase	;save her address
	beq	FatalExit		;quit NOW if no Intuition

;open DOS Library
	moveq	#0,d0
	lea	DOSname,a1
	callsys	OpenLibrary
	move.l	d0,_DOSBase
	beq	OpenLibraryError
	move.l	d0,a6			;use DOS library for next call

	callsys	Output			;open the standard output
	move.l	d0,StdOut

;open Graphics Library if anything wants it
	ifd _GFXBase
	move.l	_AbsExecBase,a6
	moveq	#0,d0			;open the Graphics Library
	lea	Graphicsname,a1
	callsys	OpenLibrary
	move.l	d0,_GFXBase		;save the base pointer
	beq	OpenLibraryError	;leave if library not opened
	endc

main:
	move.l	_IntuitionBase,a6	;A6 gets the pointer to Intuition

;open the screen and load the palette, if appropriate
	ifd NewScreenStructure
	lea	NewScreenStructure,a0	;try to open the screen
	callsys	OpenScreen
	move.l	d0,CurrentScreen	;save the Screen structure address
	beq	BigProblem		;woops! if screen didn't open, leave
					;  NOW
	ifd Palette
	move.l	d0,a0			;give the Screen pointer to A0
	lea	sc_ViewPort(a0),a0	;point to the ViewPort structure
					;  INSIDE the Screen structure
	lea	Palette,a1		;point to the Palette and get the
	moveq	#PaletteColorCount,d0	;  color count in D0
	move.l	_GFXBase,a6		;this next call goes through
					;  Graphics
	callsys	LoadRGB4
	move.l	_IntuitionBase,a6	;A6 gets the pointer to Intuition
					;  again
	endc
	endc

;do the opening of the window, et all.
	lea	NewWindowStructure1,a0	;point to the NewWindow structure
	ifd NewScreenStructure
	move.l	CurrentScreen,nw_Screen(a0)	;save the screen pointer
	endc
	callsys	OpenWindow		;open the window (gadgets will come
	move.l	d0,CurrentWindow	;  up too.)
	beq	Exit			;leave if couldn't open window

;attach the menu if present
	ifd MenuList1
	move.l	d0,a0			;window address to A0
	lea	MenuList1,a1		;menustrip pointed to by A1
	callsys	SetMenuStrip
	endc

;draw the IntuiText only if there is some
	ifd IntuiTextList1
	move.l	CurrentWindow,a0	;get the RastPort address
	move.l	wd_RPort(a0),a0
	lea	IntuiTextList1,a1	;print this list of IText structures
	moveq	#0,d0			;let the text position itself
	move.l	d0,d1
	callsys	PrintIText
	endc

;draw the Borders only if there are some of them
	ifd BorderList1
	move.l	CurrentWindow,a0	;get the RastPort address
	move.l	wd_RPort(a0),a0
	lea	BorderList1,a1		;draw this list of Border structures
	moveq	#0,d0			;let the borders position themselves
	move.l	d0,d1
	callsys	DrawBorder
	endc

;draw the Images only if there are some of them
	ifd ImageList1
	move.l	CurrentWindow,a0	;get the RastPort address
	move.l	wd_RPort(a0),a0
	lea	ImageList1,a1		;draw this list of Image structures
	moveq	#0,d0			;let the images position themselves
	move.l	d0,d1
	callsys	DrawImage
	endc

;do the Requester if Required
	ifd RequesterStructure2
	lea	RequesterStructure2,a0	;point to the Requester structure
	move.l	CurrentWindow,a1	;put it in this window
	callsys	Request
	endc

;now wait for the event we should terminate at.
Execloop:
	move.l	_AbsExecBase,a6		;point to the system again
loop:
	move.l	CurrentWindow,a0	;get the IDCMP port address and Wait
	move.l	wd_UserPort(a0),a0	;  on it
	push	a0			;save the port address
	callsys	WaitPort
	pop	a0			;get the message
	callsys	GetMsg
	move.l	d0,a1			;message address to A1
	ifd HandleEvent
	move.w	im_Code(a1),d2		;grab the potential MENUNUM
	move.l	im_IAddress(a1),d3	;grab the potential Gadget address
	endc
	move.l	im_Class(a1),d4		;save the event class in D4
	callsys	ReplyMsg		;reply the message

	ifd HandleEvent
	cmp.l	#GADGETUP,d4		;let the event handler do any
	beq	DoGadgetEvent		;  special code
	cmp.l	#GADGETDOWN,d4
	beq.s	DoGadgetEvent
	ifd MenuList1
	cmp.l	#MENUPICK,d4		;if menu, let that code work
	beq	DoMenuEvent
	endc
	endc

;termination test -- change it to any other IDCMP event, just be sure that
;  your IDCMP flags are set properly
	cmp.l	#CLOSEWINDOW,d4		;should we terminate now?
	bne	loop			;loop if not

quit:
	move.l	_IntuitionBase,a6	;be sure to do next through
					;  Intuition

;detach the menu if present
	ifd MenuList1
	move.l	CurrentWindow,a0	;window address to A0
	callsys	ClearMenuStrip
	endc

	move.l	CurrentWindow,a0	;close the window
	callsys	CloseWindow

;************   PROGRAM EXIT
Exit:
	ifd NewScreenStructure
	move.l	CurrentScreen,a0	;close the screen
	callsys	CloseScreen
	endc
BigProblem:
	move.l	_AbsExecBase,a6
	ifd _GFXBase
	move.l	_GFXBase,a1		;close Graphics if it is real
	callsys	CloseLibrary
	endc
OpenLibraryError:
	move.l	_DOSBase,d0		;close DOS if we got it open
	beq.s	50$
	move.l	d0,a1
	callsys	CloseLibrary
50$:
	move.l	_IntuitionBase,a1	;close Intuition
	callsys	CloseLibrary
FatalExit:
	move.l	ReturnMsg,d0		;reply to any WorkBench message
	beq.s	1$			;jump if none
	move.l	a1,d0			;point with this here register
	callsys	ReplyMsg		;Reply the message
1$:
	moveq	#0,d0			;no error code returned
	move.l	InitialSP,sp		;return to the caller
	rts


;****************************	 SUBROUTINES   *****************************
	ifd HandleEvent

DoGadgetEvent:
	move.l	_IntuitionBase,a6	;be sure to do next through
					;  Intuition
	move.l	d3,d0			;send the gadget address in D0
	jsr	HandleEvent		;it comes back in D0, so just go!
	bra	Execloop		;go back to get ExecBase again

	ifd MenuList1
DoMenuEvent:
	move.l	_IntuitionBase,a6	;be sure to do next through
					;  Intuition
	moveq	#0,d0			;ask Intuition for the MenuItem
					;  address
	move.w	d2,d0			;send the MENUNUM
	lea	MenuList1,a0		;send the menu address
	callsys	ItemAddress
	jsr	HandleEvent		;it comes back in D0, so just go!
	bra	Execloop		;go back to get ExecBase again
	endc

	endc

HandleBooleanGadget:
	move.l	#BoolGadgetMsg,d2	;write a line about each event
	move.l	#BoolGadgetMsgLen,d3
	bra.s	StdWrite

HandleStringGadget:
	move.l	#StringGadgetMsg,d2	;write a line about each event
	move.l	#StringGadgetMsgLen,d3
	bra.s	StdWrite

HandlePropGadget:
	move.l	#PropGadgetMsg,d2	;write a line about each event
	move.l	#PropGadgetMsgLen,d3
	bra.s	StdWrite

HandleMenus:
	move.l	#MenuMsg,d2	;write a line about each event
	move.l	#MenuMsgLen,d3
	bra.s	StdWrite

	nop

******************************************************************************
;Entry values:	D2 = buffer to write
;		D3 = buffer length
StdWrite::
	move.l	StdOut,d1		;get the file output handle
	move.l	_DOSBase,a6
	callsys	Write			;do the write
	rts

	end
