/*
**	termResponse.c
**
**	Signal event handling routines
**
**	Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
**		All Rights Reserved
*/

#include "termGlobal.h"

	/* Yet another function pointer. */

typedef BYTE (* RESPONSE)(VOID);

	/* Signal response table entry. */

struct SignalResponseInfo
{
	RESPONSE	Routine;
	ULONG		Mask;
	BYTE		Loop;
};

	/* Signal response table. */

STATIC struct SignalResponseInfo	ResponseTable[9];
STATIC WORD				ResponseCount;
STATIC ULONG				ResponseMask;

	/* AddResponse(RESPONSE Routine,ULONG Mask,BYTE Loop):
	 *
	 *	Register a signal response routine.
	 */

STATIC VOID __regargs
AddResponse(RESPONSE Routine,ULONG Mask,BYTE Loop)
{
	ResponseTable[ResponseCount] . Routine	= Routine;
	ResponseTable[ResponseCount] . Mask	= Mask;
	ResponseTable[ResponseCount] . Loop	= Loop;

	ResponseMask |= Mask;

	ResponseCount++;
}

	/* HandleResponse():
	 *
	 *	Register routines and corresponding signals,
	 *	wait for events and process them.
	 */

VOID
HandleResponse()
{
	register ULONG	SignalSet;
	register BYTE	Running;
	register WORD	SingleShot,i;

	ResponseMask	= NULL;
	ResponseCount	= 0;

	if(WriteRequest)
		AddResponse((RESPONSE)HandleSerialCheck,SIG_CHECK,FALSE);

	if(WorkbenchPort)
		AddResponse((RESPONSE)HandleWorkbenchWindow,SIG_WORKBENCH,FALSE);

	if(XEM_Signal)
		AddResponse((RESPONSE)HandleExternalEmulation,XEM_Signal,FALSE);

	AddResponse((RESPONSE)HandleClipboard,SIG_CLIP,FALSE);

	SingleShot = ResponseCount;

	if(ReadPort && Status != STATUS_HOLDING)
		AddResponse(HandleSerial,SIG_SERIAL,TRUE);

	AddResponse(HandleWindow,SIG_WINDOW,TRUE);

#ifdef USE_AREXX

	if(TermRexxPort)
		AddResponse(HandleRexx,SIG_REXX,TRUE);

#endif	/* USE_AREXX */

	if(PacketWindow)
		AddResponse(HandlePacket,SIG_PACKET,TRUE);

	if(ReviewPort)
		AddResponse(HandleReview,SIG_REVIEW,TRUE);

		/* Wait for events. */

	if(HostReadBuffer)
	{
		if(ReadPort && Status != STATUS_HOLDING)
			SignalSet = CheckSignal(ResponseMask) | SIG_SERIAL;
		else
			SignalSet = CheckSignal(ResponseMask);
	}
	else
		SignalSet = Wait(ResponseMask);

		/* Handle single-shot events. */

	for(i = 0 ; i < SingleShot ; i++)
	{
		if(SignalSet & ResponseTable[i] . Mask)
			(*ResponseTable[i] . Routine)();
	}

		/* Handle loop-fed events. */

	do
	{
		Running = FALSE;

		for(i = SingleShot ; !MainTerminated && i < ResponseCount ; i++)
		{
			if(SignalSet & ResponseTable[i] . Mask)
			{
				if((*ResponseTable[i] . Routine)())
					Running = TRUE;
				else
					SignalSet &= ~ResponseTable[i] . Mask;
			}
		}
	}
	while(Running && !MainTerminated);
}
