/* $Revision Header * Header built automatically - do not edit! *************
 *
 *	(C) Copyright 1991 by Olaf 'Olsen' Barthel & MXM
 *
 *	Name .....: termHotkeys.c
 *	Created ..: Monday 19-Jun-91 18:36
 *	Revision .: 0
 *
 *	Date            Author          Comment
 *	=========       ========        ====================
 *	19-Jun-91       Olsen           Created this file!
 *
 * $Revision Header ********************************************************/

#include "TermGlobal.h"

enum	{	CX_TERMSCREENTOFRONT,CX_BUFFERSCREENTOFRONT,CX_SKIPDIALENTRY };

	/* Asynchronous hotkey task. */

STATIC struct Task *CxTask;

	/* CreateBroker(struct MsgPort *CxPort):
	 *
	 *	Set up a CxObj commodity broker.
	 */

STATIC CxObj *
CreateBroker(struct MsgPort *CxPort)
{
	CxObj *Broker;

		/* Set the commodity priority. */

	NewTermBroker . nb_Pri = Hotkeys . CommodityPriority;

		/* Create the broker. */

	if(Broker = CxBroker(&NewTermBroker,NULL))
	{
			/* Add the hotkeys. */

		AttachCxObj(Broker,HotKey(Hotkeys . termScreenToFront,CxPort,CX_TERMSCREENTOFRONT));
		AttachCxObj(Broker,HotKey(Hotkeys . BufferScreenToFront,CxPort,CX_BUFFERSCREENTOFRONT));
		AttachCxObj(Broker,HotKey(Hotkeys . SkipDialEntry,CxPort,CX_SKIPDIALENTRY));

			/* Did an error show up? */

		if(!CxObjError(Broker))
		{
				/* Broker has been added, now activate it. */

			ActivateCxObj(Broker,Hotkeys . HotkeysEnabled);

			return(Broker);
		}

		DeleteCxObjAll(Broker);
	}

	return(NULL);
}

	/* TermCxServer():
	 *
	 *	Asynchronous hotkey server.
	 */

STATIC VOID __saveds
TermCxServer()
{
	CxObj		*Broker;
	struct MsgPort	*CxPort;
	CxMsg		*Message;

		/* Create a reply port. */

	if(CxPort = CreateMsgPort())
	{
			/* Add the port to the public list. */

		CxPort -> mp_Node . ln_Name = NewTermBroker . nb_Name;

		AddPort(CxPort);

			/* Install the port. */

		NewTermBroker . nb_Port	= CxPort;

			/* Create the broker. */

		if(Broker = CreateBroker(CxPort))
		{
			ULONG	SignalSet;
			BYTE	Terminated = FALSE;

				/* Signal father task that we're done. */

			Signal(ThisProcess,SIGBREAKF_CTRL_C);

				/* Loop and loop... */

			while(!Terminated)
			{
					/* Wait for some signal. */

				SignalSet = Wait(SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | (1 << CxPort -> mp_SigBit));

					/* ^C aborts. */

				if(SignalSet & SIGBREAKF_CTRL_C)
					Terminated = TRUE;

					/* ^D removes the broker and
					 * creates a new one.
					 */

				if(SignalSet & SIGBREAKF_CTRL_D)
				{
					DeleteCxObjAll(Broker);

					Broker = CreateBroker(CxPort);
				}

					/* A commodity message. */

				if(SignalSet & (1 << CxPort -> mp_SigBit))
				{
					ULONG MessageType,MessageID;

						/* Remove all messages. */

					while(Message = (CxMsg *)GetMsg(CxPort))
					{
							/* Extract type and ID. */

						MessageType	= CxMsgID(Message);
						MessageID	= CxMsgType(Message);

						ReplyMsg((struct Message *)Message);

							/* Take a look at the type... */

						switch(MessageID)
						{
								/* A hotkey was pressed. */

							case CXM_IEVENT:	switch(MessageType)
										{
											case CX_TERMSCREENTOFRONT:	BumpWindow(TopWindow);
															break;

											case CX_BUFFERSCREENTOFRONT:	if(BufferProcess)
																Signal(BufferProcess,SIGBREAKF_CTRL_D);

															break;

											case CX_SKIPDIALENTRY:		Signal(ThisProcess,SIGBREAKF_CTRL_F);
															break;
										}

										break;

								/* An internal commodity command. */

							case CXM_COMMAND:	switch(MessageType)
										{
											case CXCMD_DISABLE:	ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = FALSE);
														break;

											case CXCMD_ENABLE:	ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = TRUE);
														break;

											default:		break;
										}

										break;
						}
					}
				}
			}

				/* Remove the broker. */

			DeleteCxObjAll(Broker);
		}

			/* Remove the port from the public list. */

		RemPort(CxPort);

			/* Remove all pendig messages. */

		while(Message = (CxMsg *)GetMsg(CxPort))
			ReplyMsg((struct Message *)Message);

			/* Delete the reply port. */

		DeleteMsgPort(CxPort);
	}

	Forbid();

		/* Clear the task ID. */

	CxTask = NULL;

		/* Signal father process that we're done. */

	Signal(ThisProcess,SIGBREAKF_CTRL_C);
}

	/* ShutdownCx():
	 *
	 *	Remove the hotkey task.
	 */

VOID
ShutdownCx()
{
	if(CxTask)
	{
		Signal(CxTask,SIGBREAKF_CTRL_C);

		Wait(SIGBREAKF_CTRL_C);
	}
}

	/* SetupCx():
	 *
	 *	Create the hotkey task.
	 */

BYTE
SetupCx()
{
		/* If the task is already running, tell it to
		 * update the hotkey settings.
		 */

	if(CxTask)
		Signal(CxTask,SIGBREAKF_CTRL_D);
	else
	{
		CxTask = CreateTask("term Hotkey Task",0,TermCxServer,4000);

		Wait(SIGBREAKF_CTRL_C);

		if(!CxTask)
			return(FALSE);
	}

	return(TRUE);
}
