/*****************************************************************************
* Module to trap ctrl-brk/hardware error and handle them gracefully.	     *
* Note the usage of GraphGen.c module is assumed.			     *
*									     *
* Written by:  Gershon Elber				Ver 1.0, Jan. 1989   *
*****************************************************************************/

#ifdef __MSDOS__
#include <dos.h>
#include <graphics.h>
#else
#include <signal.h>
#endif /* __MSDOS__ */

#include <stdio.h>
#include "program.h"
#include "ctrl-brk.h"

#ifdef __MSDOS__
static void far *OldCtrlBrk; /* Save here old int 1bh to be able to restore. */
#endif /* __MSDOS__ */

static int WasCtrlBrkSetUp = FALSE;  /* TRUE if SetUpCtrlBrk rtn was called. */
int WasCtrlBrk;

#ifdef __MSDOS__

/*****************************************************************************
* Routine TrapCtrlBrk gain control if Control break was typed:		     *
*****************************************************************************/
static void interrupt TrapCtrlBrk(void)
{
    WasCtrlBrk = TRUE;
}

#endif /* __MSDOS__ */

/*****************************************************************************
* Routine TrapCtrlC gain control if Control C was typed (DOS level):	     *
*****************************************************************************/
static int TrapCtrlC(void)
{
    WasCtrlBrk = TRUE;

#ifndef __MSDOS__
    printf("\n*** Break ***\n");
#endif /* __MSDOS__ */

    return -1;						/* Resume execution. */
}

/*****************************************************************************
* Routine SetUpCtrlBrk must be called once by main program:		     *
*****************************************************************************/
void SetUpCtrlBrk(void)
{
    if (WasCtrlBrkSetUp) return;		  /* No need to to it twice! */

#ifdef __MSDOS__
    OldCtrlBrk = getvect(BIOS_CTRL_BRK);
    setvect(BIOS_CTRL_BRK, TrapCtrlBrk);

    ctrlbrk(TrapCtrlC);
#else
    signal(SIGINT, TrapCtrlC);
    signal(SIGQUIT, TrapCtrlC);
#endif /* __MSDOS__ */

    WasCtrlBrkSetUp = TRUE;
}

/*****************************************************************************
* Routine RestoreCtrlBrk must be called before the program quit:	     *
*****************************************************************************/
void RestoreCtrlBrk(void)
{
#ifdef __MSDOS__
    if (WasCtrlBrkSetUp)
	setvect(BIOS_CTRL_BRK, (void interrupt (*)()) OldCtrlBrk);
#endif /* __MSDOS__ */

    WasCtrlBrkSetUp = FALSE;
}

#ifdef __MSDOS__

/*****************************************************************************
* Routine TrapHardWareError gain control if hardware fails - int 24.	     *
*****************************************************************************/
static int TrapHardWareError(int errval, int ax, int bp, int si)
{
    return IGNORE;
}

#endif /* __MSDOS__ */

/*****************************************************************************
* Routine SetUpHardError must be called once by main program:		     *
* harderr set interrupt vector 0x024 to point to TrapHardWareError.	     *
*****************************************************************************/
void SetUpHardErr(void)
{
#ifdef __MSDOS__
    harderr(TrapHardWareError);
#endif /* __MSDOS__ */
}
