/* nocapslock. */

/*** define this symbol TRUE to also have the middle
 *** mouse button converted to shift-left button
 ***/
#define MIDDLETOO	1

/*
Copyright (c) 1987, 1988, 1989 Jim Mackraz and I&I Computing.

Executables based on this information may be used in software
for Commodore Amiga computers.  All other rights reserved.
This information is provided "as is"; no warranties are made.
All use is at your own risk, and no liability or responsibility
is assumed.
*/

#include	"cx/cxusr.h"

#ifndef LIBNAME
#define LIBNAME "commodities.library"
#endif

#define D(x)	;

struct Library *CxBase;

LONG nocapsaction();
LONG middlebaction();

#define D2(x)	;
#include <exec/libraries.h>


struct NewBroker mynb = {
	NB_VERSION,
	"nocapslock",				/* broker internal name	*/
	"NoCapsLock",				/* commodity title		*/
	"Renders Caps Lock ineffective",	
								/* description			*/
	NBU_UNIQUE,					/* only me				*/
	0,							/* flags				*/
	5							/* default priority		*/
};

/* An input expression to match any RAWKEY event with the
 * CAPSLOCK qualifier bit set
 */
IX		myix = {
	IX_VERSION,				/* required									*/
	IECLASS_RAWKEY,

	0,						/* Code: won't care							*/
	0,						/* CodeMask: 0 means don't care about Code	*/

	IEQUALIFIER_CAPSLOCK,	/* qualifier I am interested in				*/
	IEQUALIFIER_CAPSLOCK,	/* and it's the only qualifier of interest	*/
	0						/* synonyms irrelevant						*/
};

#if MIDDLETOO
/* An input expression to match any RAWKEY event with the
 * CAPSLOCK qualifier bit set
 */
IX		middleix = {
	IX_VERSION,				/* required									*/
	IECLASS_RAWMOUSE,

	/* debug: am i listening right? */
	IECODE_MBUTTON,			/* Code	*/
	~IECODE_UP_PREFIX,		/* CodeMask	*/

	0,						/* qualifier I am interested in				*/
	0,
	0						/* synonyms irrelevant						*/
};

#endif

main(argc, argv)
int		argc;
char	**argv;
{
	char	**tt;
	int		exitval = 0;

	CxObj	*broker = NULL;
	CxObj	*filter;
	CxObj	*mfilter;

	CxBase = (struct Library *) OpenLibrary( LIBNAME, 2L);
	if (!CxBase) exit (1);

	D2( printf("opened cxlib: %lx ver %d rev: %d ", CxBase,
		CxBase->lib_Version, CxBase->lib_Revision) );
	D2(printf("opencnt: %x, %d\n", CxBase->lib_OpenCnt,CxBase->lib_OpenCnt));

	tt = ArgArrayInit(argc, argv);
	mynb.nb_Pri = ArgInt(tt, "PRIORITY", 0);
	ArgArrayDone();

	broker = CxBroker(&mynb, NULL);

	if (!broker)
	{
		exitval = 1;
		goto ABORT;
	}

#if 1 /* install modifier for capslock */
	filter = CxFilter(NULL);
	if (!filter)
	{
		exitval = 1;
		goto ABORT;
	}

	SetFilterIX(filter, &myix);

	/** DEBUG **/
	D( AttachCxObj(filter, CxDebug( 0xDEADFACE)) );

	AttachCxObj(filter, CxCustom( nocapsaction, 0L));

	if (CxObjError(filter))
	{
		D2( printf("nocapslock: filter error %lx\n", CxObjError(filter) ) );
		DeleteCxObjAll(filter);
		exitval = 2;
		goto ABORT;
	}

	AttachCxObj(broker, filter);
#endif


#if MIDDLETOO	/* install middle button trap */
	/* *** middle button trap	***	*/
	mfilter = CxFilter(NULL);
	if (!mfilter)
	{
		exitval = 1;
		goto ABORT;
	}
	SetFilterIX(mfilter, &middleix);
	D( AttachCxObj(mfilter, CxDebug( 0xDEADFACE)) ); /** DEBUG **/
	AttachCxObj(mfilter, CxCustom( middlebaction, 0L));
	if (CxObjError(mfilter))
	{
		D2( printf("nocapslock: filter error %lx\n", CxObjError(mfilter) ) );
		DeleteCxObjAll(mfilter);
		exitval = 2;
		goto ABORT;
	}
	AttachCxObj(broker, mfilter);
	D2( printf("middle button trap OK\n") );

#endif

	/* all set, activate broker	*/
	ActivateCxObj(broker, 1L);

	/* wait until you die		*/
	Wait((LONG) SIGBREAKF_CTRL_E);


ABORT:
	if (broker) DeleteCxObjAll(broker);
	CloseLibrary(CxBase);

	exit (exitval);
}

#if MIDDLETOO
LONG
middlebaction( cxm, co )
register struct CxMsg	*cxm;
CxObj			*co;
{
	register struct InputEvent *ie;

	/* Manx context set up: I am called by input.device task	*/
	geta4();	

	ie = (struct InputEvent *) CxMsgData(cxm);

#if 1
	/* i KNOW that all messages getting this far are CXM_IEVENT	*/
	/* convert middle button into shift left	*/
	ie->ie_Code = (ie->ie_Code & IECODE_UP_PREFIX) | IECODE_LBUTTON;
	ie->ie_Qualifier |= IEQUALIFIER_LSHIFT;
	D2( kprintf("middlebaction\n") );
#else
	D2( kprintf("leftbaction\n") );
	D2( kprintf("code: %x\n", ie->ie_Code ) );
#endif

}
#endif


LONG
nocapsaction(cxm, co)
register struct CxMsg	*cxm;
CxObj			*co;
{
	register struct InputEvent *ie;

	/* Manx context set up: I am called by input.device task	*/
	geta4();	

	D2( kprintf("nocapsaction\n") );

	/* i KNOW that all messages getting this far are CXM_IEVENT	*/
	ie = (struct InputEvent *) CxMsgData(cxm);

	ie->ie_Qualifier &= ~IEQUALIFIER_CAPSLOCK;
}
