*******************************************************************
* 	Demonstration zur Funktion "WindowClose"	  *
*-----------------------------------------------------------------*
*				  *
* Dieses Programm schließt alle Fenster auf der Workbench.	  *
* Aufruf von der CLI/Shell: [CloseWindow] ohne Parameter	  *
* 				  *
*   Beschreibung:			  *
*				  *
* Ausgehend vom Ersten geöffneten Fenster auf der Workbench, 	  *
* schickt es jedem eine Nachricht vom Typ IDCMP_CLOSEWINDOW, was  *
* bewirkt, daß, sofern ein Close-Gadget vorhanden ist, das Fenster*
* geschlossen wird und alle zusätzlichen Resourcen vom System und *
* dem zuständigen Task freigegeben werden!		  *
*				  *
*   Benutzter Assembler: 			  *
* MaxonASM in der Version 1.1			  *
*  Tabulator: 16			  *
*				  *
* Die Demo läßt sich aber auch mit allen anderen Assemblern 	  *
* übersetzen!				  *
* Vorraussetzung ist allerdings das Vorhandensein von OS 2.0 und  *
* den dazugehörigen Includes!			  *
*				  *
*******************************************************************

	INCLUDE	intuition/intuition.i
	INCLUDE	intuition/intuitionbase.i
	INCLUDE	intuition/intuition_lib.i
	INCLUDE	exec/devices.i
	INCLUDE	exec/exec_lib.i
	INCLUDE	devices/input.i
	INCLUDE	devices/inputevent.i

*----Benötigte Resourcen öffnen---

Main	move.l	$4.w,a6
	lea	IntName(pc),a1
	moveq	#37,d0	OS 2.0!
	jsr	_LVOOpenLibrary(a6)

	lea	_IntBase(pc),a0
	move.l	d0,(a0)
	beq	.NoInt
	move.l	d0,a6

	lea	InpName(pc),a0
	moveq	#0,d0
	moveq	#IOSTD_SIZE,d1
	bsr	_OpenDevice	;Input.device öffnen

	lea	_IOReq(pc),a0
	move.l	d0,(a0)
	beq.s	.NoDev

*----Workbench-Screen finden---

	suba.l	a0,a0	WBenchScreen
	jsr	_LVOLockPubScreen(a6)
	move.l	d0,d6
	beq.s	.NoPubScreen
	move.l	d0,a3
	move.l	sc_FirstWindow(a3),d5
	beq.s	.freeall

	move.l	d5,a0

.loop	move.l	wd_NextWindow(a0),d5
	bsr	WindowClose
	move.l	d5,a0
	move.l	wd_NextWindow(a0),d5
	beq.s	.closelast	;kein weiteres Fenster
	bra.s	.loop

.closelast
	bsr	WindowClose	;letztes Fenster schließen

*----Alles freigeben-------------------------------------------------

.freeall	suba.l	a0,a0
	move.l	d6,a1
	jsr	_LVOUnlockPubScreen(a6)

.NoPubScreen	move.l	_IOReq,a0
	bsr	_CloseDevice

.NoDev	move.l	_IntBase,a1
	move.l	$4.w,a6
	jsr	_LVOCloseLibrary(a6)

.NoInt	moveq	#0,d0
	rts


*******************************************************************
*                     WindowClose		  *
*				  *
* Funktion: sendet IDCMP_CLOSEWINDOW an ang. Window	  *
* Eingabe : a0=Ptr auf Window		 	  *
* Ausgabe : d0=TRUE/FALSE			  *
*				  *
* Bemerkung: IntBase und _IOReq müssen korrekt initialisiert sein!*
*******************************************************************

WindowClose	movem.l	d1-a6,-(sp)

	move.l	a0,a4	Testen, ob
	move.l	wd_IDCMPFlags(a4),d0   auf das Flag
	and.l	#IDCMP_CLOSEWINDOW,d0  gewartet
	cmp.l	#IDCMP_CLOSEWINDOW,d0  wird
	bne.s	.noclosegg	       NEIN -> ab!

	move.l	a4,a0	   Gewünschtes
	move.l	_IntBase,a6	   Fenster aktivieren
	jsr	_LVOActivateWindow(a6)

	move.l	_IOReq,a0	   IOReq nach a0
	lea	inputEvent(pc),a1  inputEvent nach a1
	move.b	#IECLASS_CLOSEWINDOW,ie_Class(a1) Msg setzen
	bsr	_IDWriteEvent      und Msg senden

.weiter	moveq	#1,d0	TRUE
	bra.s	.weg

.noclosegg	;*--Kein CloseGadget vorhanden, Benutzer aufmerksam machen-

	moveq	#0,d0	FALSE

.weg	movem.l	(sp)+,d1-a6
	rts

*********************************************************************
*	_OpenDevice			    *
*				    *
* Funktion: Device öffnen			    *
* Eingabe : a0=ptr auf Namen (z.B. "audio.device",0)	    *
*           d0=Unit			    *
*           d1=Länge d. IORequest - Blockes		    *
* Ausgabe : d0=ptr auf IOreq oder NULL bei Fehler	    *
*				    *
* Bemerkung : nutzt Funktionen des V36++ OS		    *
*********************************************************************

_OpenDevice	movem.l	d1-a6,-(sp)

	move.l	a0,a4	Namen retten
	move.l	d0,d7	Unit retten
	move.l	d1,d6	Länge retten

	move.l	4.w,a6
	jsr	_LVOCreateMsgPort(a6)
	move.l	d0,a3
	beq.s	.noPort

	move.l	d6,d0
	jsr	_LVOCreateIORequest(a6)
	move.l	d0,a2
	beq.s	.noIoreq

	move.l	a4,a0	Namen nach a0
	move.l	d7,d0	Unit nach d0
	move.l	a2,a1	IORequest nach a1
	moveq	#0,d1	keine Flags
	jsr	_LVOOpenDevice(a6)
	tst	d0	Rückgabe testen
	beq.s	.ok	d0=0, alles Ok

.noDevice	move.l	a2,a0	IOreq nach a0
	jsr	_LVODeleteIORequest(a6)

.noIoreq	move.l	a3,a0	Port nach a0
	jsr	_LVODeleteMsgPort(a6)

.noPort	moveq	#0,d0	Rückwert FALSE setzen
	bra.s	.weg

.ok	move.l	a2,d0	IORequest nach d0

.weg	movem.l	(sp)+,d1-a6
	rts


*********************************************************************
*	_CloseDevice			    *
* 				    *
* Funktion: schließt Device und gibt alle Resourcen frei	    *
* Eingabe : a0=ptr auf IOreq			    *
* Ausgabe : ----------------			    *
*				    *
* Bemerkung: benutzt Funktionen des V36++ OS		    *
*********************************************************************

_CloseDevice	movem.l	d0-a6,-(sp)

	move.l	a0,d0	testen, ob IOreq
	beq.s	.weg	existiert!
	move.l	a0,a5	IOreq nach a5
	move.l	$4.w,a6	ExecBase nach a6

.closedev	move.l	IO_DEVICE(a0),d0 Testen, ob Device
	beq.s	.closemp	 zu öffnen war!
	move.l	a0,a1	 ja!
	jsr	_LVOCloseDevice(a6) Schließen

.closemp	move.l	MN_REPLYPORT(a5),d0 Testen, ob Port
	beq.s	.closeIOreq	    zu öffnen war!
	move.l	d0,a0	    ja!
	jsr	_LVODeleteMsgPort(a6) Schließen

.closeIOreq	move.l	a5,a0	    IOreq schließen
	jsr	_LVODeleteIORequest(a6)

.weg	movem.l	(sp)+,d0-a6	    Register vom Stack
	rts		    und weg


*********************************************************************
*                          _IDWriteEvent                            *
*				    *
* Funktion: InputEvent an das aktuelle Window schicken	    *
* Eingabe : a0=ptr auf IOreq		    	    *
*           a1=ptr auf inputEvent		    *
* Ausgabe : d0=ERROR			    *
* 				    *
*********************************************************************

_IDWriteEvent	movem.l	d1/a0-a2/a6,-(sp)

	move.l	a1,IO_DATA(a0)	        inputEvent eintragen
	move.l	#ie_SIZEOF,IO_LENGTH(a0) größe eintragen

	move.l	a0,a1	IOReq nach a1 für DoIo
	move.l	a0,a2	IOReq retten

	move	#IND_WRITEEVENT,IO_COMMAND(a1)
	move.l	$4.w,a6
	jsr	_LVODoIO(a6)	Prozedur ausführen

	moveq	#0,d0	d0 löschen
	move.b	IO_ERROR(a2),d0	Error Byte holen

	movem.l	(sp)+,d1/a0-a2/a6
	rts

*----Texte und Strukturen--------------------------------------------

Version:	dc.b	"$VER WindowClose V0.01 (10.11.93)",0
	even

IntName	dc.b	"intuition.library",0
	even
InpName	dc.b	"input.device",0
	even
WBenchName	dc.b	"Workbench",0
	even

_IntBase	dc.l	0
_IOReq	dc.l	0

inputEvent	ds.b	ie_SIZEOF
	END