#ifndef CPP_EXEC_SIGNALS_H
#define CPP_EXEC_SIGNALS_H

// Klassen für Signals und Signalhandler
//
// Autor: Jochen Becher
//
// Historie:
// Version 1.0 am 30. Juni 94

#ifndef EXEC_TYPES_H
#include <exec/types.h>
#endif

#ifndef DOS_DOS_H
#include <dos/dos.h>
#endif

#ifndef CPP_EXEC_SHARE_H
#include <classes/exec/share.h>
#endif

#ifndef CPP_EXEC_LISTS_H
#include <classes/exec/lists.h>
#endif

#ifndef CPP_EXCEPTIONS_EXCEPTIONS_H
#include <classes/exceptions/exceptions.h>
#endif

class SignalC : private ShareC {
public:
	SignalC(LONG signalNum = -1) throw (SignalX, MemoryX);
	~SignalC();
	SignalC &operator= (const SignalC &);
	LONG number() const { return sigNum; };
private:
	LONG sigNum;
};

class SignalHandlerC : public NodeC {
friend class SignalsC;
public:
	SignalHandlerC(LONG signalNum = -1);
	SignalHandlerC(SignalC &signal);
	SignalHandlerC(const SignalHandlerC &);
	virtual ~SignalHandlerC();
	SignalHandlerC &operator= (const SignalHandlerC &);
	virtual ULONG signals() { return mask; };
	virtual BOOL forMe(ULONG signals)
		{ return (signals & mask) ? TRUE : FALSE; };
	virtual BOOL handle(ULONG signals)
		{ return FALSE; };
protected:
	ULONG mask;
};

class SignalsC : protected ListC {
public:
	SignalsC();
	~SignalsC();
	VOID add(SignalHandlerC &);
	ULONG wait();
	BOOL handle(ULONG signals);
	VOID loop();
private:
	VOID buildMask();
	ULONG mask;
};

class BreakHandlerC : public SignalHandlerC {
public:
	BreakHandlerC(LONG signum) : SignalHandlerC(signum) { };
	BOOL handle(ULONG signals)
		{ return forMe(signals) ? pressed() : FALSE };
protected:
	virtual BOOL pressed() { return TRUE; };
};

class CtrlCHandlerC : public BreakHandlerC {
public:
	CtrlCHandlerC() : BreakHandlerC(SIGBREAKB_CTRL_C) { };
};

class CtrlDHandlerC : public BreakHandlerC {
public:
	CtrlDHandlerC() : BreakHandlerC(SIGBREAKB_CTRL_D) { };
};

class CtrlEHandlerC : public BreakHandlerC {
public:
	CtrlEHandlerC() : BreakHandlerC(SIGBREAKB_CTRL_E) { };
};

class CtrlFHandlerC : public BreakHandlerC {
public:
	CtrlFHandlerC() : BreakHandlerC(SIGBREAKB_CTRL_F) { };
};

#endif
