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

#include "termGlobal.h"

	/* Yet another function pointer. */

typedef BYTE (* RESPONSE)(VOID);

	/* Signal response table entry. */

struct SignalResponseInfo
{
	RESPONSE	Routine;
	ULONG		Mask;
};

	/* Signal response table. */

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

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

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

	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	i;

	ResponseMask	= XEM_Signal;
	ResponseCount	= 0;

	AddResponse((RESPONSE)HandleSerialCheck,SIG_CHECK);

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

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

	if(OwnDevUnitBase && !Config -> SerialConfig -> Shared && OwnDevBit != -1)
		AddResponse(HandleOwnDevUnit,1L << OwnDevBit);

	AddResponse(HandleWindow,SIG_WINDOW);

	if(TermRexxPort)
		AddResponse(HandleRexx,SIG_REXX);

	AddResponse(HandleQueueMsg,SIG_QUEUE);

		/* Wait for events. */

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

	if(SignalSet & XEM_Signal)
		HandleExternalEmulation();

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

		if(Running && !MainTerminated)
			SignalSet |= SetSignal(0,ResponseMask) & ResponseMask;
		else
			break;
	}
}
