/* Listing #22 */
#include <proto/commodities.h>

#include <proto/dos.h>

#include <proto/exec.h>

#include <proto/intuition.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

struct NewBroker nb=

{
	NB_VERSION,

	"CLMod",

	"Modyfikator Caps Locka",

	"Modyfikuje CapsLock+Shift",

	NBU_UNIQUE | NBU_NOTIFY,

	COF_SHOW_HIDE

};

long pri=127, param[]={(long)&pri, (long)"alt control m", (long)"yes"};

struct RDArgs *rda=0;

CxObj *broker=0;

struct MsgPort *broker_port=0;

ULONG broker_mask;

struct Window *okno=0;

ULONG okno_mask=0;

void wyjscie(int retkod)

{

	if (okno)

		CloseWindow(okno);

	if (broker)

		DeleteCxObjAll(broker);

	if (broker_port)

	{

		struct Message *msg;

		while (msg=GetMsg(broker_port))

			ReplyMsg(msg);

		DeleteMsgPort(broker_port);

	}

	if (rda)

		FreeArgs(rda);

	exit(retkod);

}

void __interrupt __saveds __stdargs zmiana_caps(CxMsg* msg, CxObj* obj)

{

	struct InputEvent *ie;

	for (ie=CxMsgData(msg); ie; ie=ie->ie_NextEvent)

		if (ie->ie_Class==IECLASS_RAWKEY && (ie->ie_Qualifier & IEQUALIFIER_CAPSLOCK) && (ie->ie_Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))

			ie->ie_Qualifier &= ~(IEQUALIFIER_CAPSLOCK | IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT);

}

void otworz_okno(void)

{

	if (okno)

	{

		WindowToFront(okno);

		ActivateWindow(okno);

	}

	else

	{

		static char buf[128];

		sprintf(buf, "CLMod: Wywoîanie = <%s>", param[1]);

		if (!(okno=OpenWindowTags(0,

				WA_Width, 400,

				WA_Height, 100,

				WA_IDCMP, IDCMP_CLOSEWINDOW,

				WA_Flags, WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_ACTIVATE | WFLG_RMBTRAP,

				WA_Title, buf,

				TAG_DONE)))

			wyjscie(10);

		okno_mask=1 << okno->UserPort->mp_SigBit;

	}

}

void zamknij_okno(void)

{

	if (okno)

		CloseWindow(okno);

	okno=0;

	okno_mask=0;

}

int main(int argc, char* argv[])

{

	CxObj *filter;

	LONG blad;

	char koniec=0;

	if (!(rda=ReadArgs("CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/K", param, 0)))

	{

		PrintFault(IoErr(), argv[0]);

		wyjscie(10);

	}

	if (!(broker_port=CreateMsgPort()))

		wyjscie(10);

	broker_mask=1 << broker_port->mp_SigBit;

	nb.nb_Port=broker_port;

	nb.nb_Pri=*(long*)param[0];

	if (!(broker=CxBroker(&nb, &blad)))

		wyjscie(blad==CBERR_DUP ? 0 : 10);

	AttachCxObj(broker, CxCustom(zmiana_caps, 0));

	AttachCxObj(broker, filter=CxFilter(param[1]));

	AttachCxObj(filter, CxSender(broker_port, 0));

	AttachCxObj(filter, CxTranslate(NULL));

	if (blad=CxObjError(filter))

	{

		if (blad & COERR_BADFILTER)

			Printf("%s: nieprawidîowy filtr '%s'\n", argv[0], param[1]);

		wyjscie(10);

	}

	ActivateCxObj(broker, TRUE);

	if (stricmp((char*)param[2], "yes")==0)

		otworz_okno();

	for (; !koniec;)

	{

		ULONG sig=Wait(broker_mask | okno_mask | SIGBREAKF_CTRL_C);

		if (sig & broker_mask)

		{

			CxMsg *msg;

			while (msg=(CxMsg*)GetMsg(broker_port))

			{

				LONG id=CxMsgID(msg);

				ULONG type=CxMsgType(msg);

				ReplyMsg((struct Message*)msg);

				switch (type)

				{

					case CXM_IEVENT:

						otworz_okno();

						break;

					case CXM_COMMAND:

						switch (id)

						{

							case CXCMD_DISABLE:

							case CXCMD_ENABLE:

								ActivateCxObj(broker, id==CXCMD_ENABLE);

								break;

							case CXCMD_KILL:

								koniec=1;

								break;

							case CXCMD_UNIQUE:

							case CXCMD_APPEAR:

								otworz_okno();

								break;

							case CXCMD_DISAPPEAR:

								zamknij_okno();

						}

				}

			}

		}

		if (sig & okno_mask)

			/* Jedynâ moûliwâ wiadomoôciâ jest IDCMP_CLOSEWINDOW. */

			zamknij_okno();

		if (sig & SIGBREAKF_CTRL_C)

			koniec=1;

	}

	wyjscie(0);


}







