*****
*
*	$VER : AutoClick 1.00, Pierre-Louis MANGEARD, Feb. 1993
*
*****

	OPT	l-,c+,d+,line	-,w+,o1+,o2+,o3+,o4+,o5+,o6+,o7+,o10+,o11+,o12+

	INCLUDE	CxPak_Include

	SECTION		NTRYHUNK,CODE

	clr.l	d4
	lea	_DataBase,a4

	suba.l	a1,a1
	EXEC		FindTask	find us
	movea.l	d0,a2
	move.l	d0,cxp_Task(a4)		addresse de la task
	move.b	LN_PRI(a2),Old_Pri(a4)	priorite
	lea	pr_MsgPort(a2),a0	port du process
	move.l	a0,cxp_Port(a4)

	tst.l	pr_CLI(a2)
	bne.s	end_startup

fromWorkbench

;	movea.l	cxp_Port(a4),a0		deja en a0
	CALL		WaitPort	wait for a message
	movea.l	cxp_Port(a4),a0
	CALL		GetMsg		then get it
	move.l	d0,RetMsg_	save it for later reply

end_startup

	bsr.s	_main			call our program

	tst.l	RetMsg_
	beq.s	exitToDOS		if I was a CLI

	EXEC		Forbid
	movea.l	RetMsg_,a1
	CALL		ReplyMsg

exitToDOS

	rts

_main

*****
*	debut effectif du programme.
*****

	lea	cxname(a4),a1
	CALL		OldOpenLibrary
	move.l	d0,_CxBase(a4)
	beq	cxp55

	lea	intname(a4),a1
	CALL		OldOpenLibrary
	move.l	d0,_IntuitionBase(a4)
	beq	cxp55

	lea	layername(a4),a1
	CALL		OldOpenLibrary
	move.l	d0,_LayerBase(a4)
	beq	cxp55

	lea	iconname(a4),a1
	CALL		OldOpenLibrary
	move.l	d0,_IconBase(a4)
	beq	cxp55

	lea	dosname(a4),a1
	CALL		OldOpenLibrary
	move.l	d0,_DOSBase(a4)
	beq	cxp55


	tst.l	RetMsg_
	beq.s	cxp05

* si on vient du workbench, recuperer ToolTypeArray :

	movea.l	RetMsg_,a2
	movea.l	sm_ArgList(a2),a2	ArgList sauvegarde provisoire en a2
	beq.s	cxp05
	move.l	wa_Lock(a2),d1
	DOS		CurrentDir

	movea.l	wa_Name(a2),a0		name en a0
	ICON		GetDiskObject
	move.l	d0,cxp_DiskObj(a4)
	beq.s	cxp05
	movea.l	d0,a2
	movea.l	do_ToolTypes(a2),a2


* recupere PRIORITY en tooltype :

	movea.l	a2,a0
	lea	cxp_ToolType(a4),a1
	CALL		FindToolType
	tst.l	d0
	beq.s	cxp05

	movea.l	d0,a0
	clr.w	d2

* conversion ascii -> entier du tooltype CX_PRIORITY :

	cmpi.b	#'-',(a0)
	bne.s	cxp06

	moveq	#1,d2
	addq.l	#BYTE,a0

cxp06	moveq	#0,d0

cxp07	moveq	#0,d1
	move.b	(a0)+,d1
	beq.s	cxp09
	subi.b	#'0',d1
	add.l	d0,d0
	add.l	d0,d1
	lsl.l	#2,d0
	add.l	d1,d0
	bra.s	cxp07

cxp09	tst.w	d2
	beq.s	cxp08

	neg.b	d0

cxp08	move.b	d0,cxp_Pri(a4)

	movea.l	cxp_DiskObj(a4),a0
	CALL		FreeDiskObject


* definition du signal :

cxp05	clr.l	d0
	movea.l	cxp_Port(a4),a1
	move.b	MP_SIGBIT(a1),d0
	moveq	#1,SigFlg_
	lsl.l	d0,SigFlg_
	ori.l	#SIGBREAKF_CTRL_C,SigFlg_

* installation du broker :

	lea	cxp_NewBroker(a4),a0
	moveq	#0,d0
	CX		CxBroker
	move.l	d0,Broker_
	beq	cxp55				si autoclick deja la

* installation des filters et senders (_CxBase deja en a6) :

	lea	cxp_HotKey(a4),a0		rawkey
	lea	IX(a4),a1
	bsr.s	Set_CxNet
	beq	cxp55

	lea	cxp_HotKey(a4),a0		right button
	lea	IX1(a4),a1
	bsr.s	Set_CxNet
	beq	cxp55

	lea	cxp_HotKey(a4),a0		mid button
	lea	IX2(a4),a1
	bsr.s	Set_CxNet
	beq	cxp55

	lea	cxp_DiskIn(a4),a0		disk in
	suba.l	a1,a1
	bsr.s	Set_CxNet
	beq	cxp55

	lea	cxp_DiskRem(a4),a0		disk rem
	suba.l	a1,a1
	bsr.s	Set_CxNet
	beq	cxp55

	bra.s	cxp20


Set_CxNet:

* success = Set_CxNet(ie string, IX)
*  d0 (CCR)		a0	a1
* (_CxBase deja en a6)

	movea.l	a1,a2

	moveq	#CX_FILTER,d0			mid button
;						ie string deja en a0
	suba.l	a1,a1
	CALL		CreateCxObj
	move.l	d0,d2
	beq.s	scxn20
	movea.l	Broker_,a0
	movea.l	d0,a1
	CALL		AttachCxObj

	cmpa.w	#NULL,a2
	beq.s	scxn10

	movea.l	d2,a0
	movea.l	a2,a1				IX en a1
	CALL		SetFilterIX

scxn10	movea.l	cxp_Port(a4),a0
	moveq	#CX_SEND,d0
	movea.l	#CX_MAGIC,a1
	CALL		CreateCxObj
	tst.l	d0
	beq.s	scxn20
	movea.l	d2,a0
	movea.l	d0,a1
	CALL		AttachCxObj

	moveq	#TRUE,d0			operation reussie

scxn20	rts


* la tache a la priorite 21 pour prendre la main sur l'input.device :

cxp20	movea.l	cxp_Task(a4),a1
	moveq	#CXP_PRIORITY,d0
	EXEC	SetTaskPri

* activation du broker :

	moveq	#TRUE,d0
	bsr	SwitchBroker


* recuperation du message :

cxp1	move.l	SigFlg_,d0
	EXEC	Wait

	cmpi.l	#SIGBREAKF_CTRL_C,d0
	bne.s	cxp3

	moveq	#CXCMD_KILL,MsgId_

cxp3	movea.l	cxp_Port(a4),a0
	CALL	GetMsg
	tst.l	d0
	beq	cxp40
	movea.l	d0,a2

* type et id du message :

	movea.l	a2,a0
	CX		CxMsgType
	move.w	d0,MsgType_

	movea.l	a2,a0
	CALL		CxMsgID
	move.w	d0,MsgId_

	movea.l	a2,a1
	EXEC	ReplyMsg

* action selon le type :

	cmpi.w	#CXM_COMMAND,MsgType_
	beq.s	cxp40


* ACTIVATION DE LA FENETRE :

* IntuitionBase en a3
* screen en a2

	moveq	#0,d0
	INT		LockIBase
	move.l	d0,-(sp)

	movea.l	_IntuitionBase(a4),a0
	movea.l	a0,a3
	movea.l	ib_FirstScreen(a0),a2
cxp5	move.w	ib_MouseY(a0),d0		coord Y de la souris
	cmp.w	sc_TopEdge(a2),d0		- haut de l'ecran
	bge.s	cxp10
	movea.l	sc_NextScreen(a2),a2
	cmpa.w	#0,a2
	bne.s	cxp5

cxp10	movea.l	(sp)+,a0
	CALL		UnlockIBase

	movea.l	a2,a0
	adda.w	#sc_LayerInfo,a0
	move.l	a0,-(sp)
	LAYER		LockLayerInfo

	movea.l	(sp),a0
	move.w	sc_MouseX(a2),d0
	move.w	sc_MouseY(a2),d1
	CALL		WhichLayer
	move.l	d0,d2				sauvegarde provisoire

	movea.l	(sp)+,a0
	CALL		UnlockLayerInfo

	tst.l	d2
	beq	cxp1				si pas de layer, rien

	movea.l	d2,a0
	movea.l	lr_Window(a0),a0		window du layer
	cmpa.l	ib_ActiveWindow(a3),a0		est-ce la fenetre deja active ?
	beq	cxp1				si oui rien
	INT		ActivateWindow

	bra	cxp1


* on a recu un msg COMMAND :

cxp40	cmpi.w	#CXCMD_KILL,MsgId_		kill autoclick
	beq.s	cxp60

	cmpi.w	#CXCMD_UNIQUE,MsgId_		toggle autoclick
	beq.s	cxp60

	cmpi.w	#CXCMD_DISABLE,MsgId_		dormant autoclick
	bne.s	cxp43

	moveq	#FALSE,d0
	bsr.s	SwitchBroker

	bra	cxp1

cxp43	cmpi.w	#CXCMD_ENABLE,MsgId_		wake up autoclick
	bne	cxp1

	moveq	#TRUE,d0
	bsr.s	SwitchBroker

	bra	cxp1


cxp55	moveq	#RETURN_ERROR,d2

	bra.s	cxp62


* Exit :

cxp60	moveq	#RETURN_OK,d2

cxp62	tst.l	Broker_
	beq.s	cxp70

cxp65	movea.l	Broker_,a0
	CX		DeleteCxObjAll

cxp70	movea.l	_DOSBase(a4),a1
	EXEC	CloseLibrary

cxp94	movea.l	_IconBase(a4),a1
	CALL	CloseLibrary

cxp93	movea.l	_LayerBase(a4),a1
	CALL	CloseLibrary

cxp92	movea.l	_IntuitionBase(a4),a1
	CALL	CloseLibrary

cxp91	movea.l	_CxBase(a4),a1
	CALL	CloseLibrary

* restore la priorite du shell d'origine le cas echeant :

cxp90	clr.l	d0
	movea.l	cxp_Task(a4),a1
	move.b	Old_Pri(a4),d0
	CALL	SetTaskPri

	move.l	d2,d0

	rts


*****
*	subroutines.
*****

SwitchBroker:

* void SwitchBroker(BOOL)
*		     d0 = TRUE or FALSE

	movea.l	Broker_,a0
	CX		ActivateCxObj

	rts


*****
*	version.
*****

	dc.b	'$VER: AutoClick 1.00 (02.93)'

	cnop	0,2


*****
*	variables et constantes du programme.
*****

	SECTION		Data,DATA

_DataBase:

	DAT	_CxBase
		dc.l	0
	DAT	_IntuitionBase
		dc.l	0
	DAT	_LayerBase
		dc.l	0
	DAT	_IconBase
		dc.l	0
	DAT	_DOSBase
		dc.l	0
	DAT	cxp_Task
		dc.l	0
	DAT	cxp_DiskObj
		dc.l	0


    LAB	cxp_NewBroker:
		dc.b	NB_VERSION,0
		dc.l	_DataBase+cxp_BkName
		dc.l	_DataBase+cxp_BkTitle
		dc.l	_DataBase+cxp_BkDescr
		dc.w	NBU_UNIQUE+NBU_NOTIFY
		dc.w	0
	DAT	cxp_Pri
		dc.b	0
		dc.b	0
	DAT	cxp_Port
		dc.l	0
		dc.w	0


    LAB	IX
		dc.b	IX_VERSION
		dc.b	IECLASS_RAWKEY
		dc.w	0
		dc.w	IECODE_UP_PREFIX
		dc.w	0
		dc.w	0
		dc.w	0

    LAB	IX1
		dc.b	IX_VERSION
		dc.b	IECLASS_RAWMOUSE
		dc.w	0
		dc.w	IECODE_UP_PREFIX
		dc.w	IEQUALIFIER_RBUTTON
		dc.w	IEQUALIFIER_RBUTTON
		dc.w	0

    LAB	IX2
		dc.b	IX_VERSION
		dc.b	IECLASS_RAWMOUSE
		dc.w	0
		dc.w	IECODE_UP_PREFIX
		dc.w	IEQUALIFIER_MIDBUTTON
		dc.w	IEQUALIFIER_MIDBUTTON
		dc.w	0

	DAT	Old_Pri
		dc.b	0

	CHAR	cxname
		CXNAME
	CHAR	intname
		INTNAME
	CHAR	iconname
		ICONNAME
	CHAR	dosname
		DOSNAME
	CHAR	layername
		dc.b	'layers.library',0
	CHAR	cxp_BkName
		dc.b	'AutoClick',0
	CHAR	cxp_BkTitle
		dc.b	'Window Activator',0
	CHAR	cxp_BkDescr
		dc.b	'only after an input event',0
	CHAR	cxp_HotKey
	CHAR	cxp_DiskIn
		dc.b	'diskinserted',0
	CHAR	cxp_DiskRem
		dc.b	'diskremoved',0
	CHAR	cxp_ToolType
		dc.b	'CX_PRIORITY',0

	END

