;/*
FailAt 1
LC -M -v -iINCLUDE:CompactH/ ScreenWatch.c
Blink DEFINE __main=__tinymain FROM lib:cback.o ScreenWatch.o LIB lib:lc.lib SC SD ND
Quit
*/

#include <stdio.h>
#include <string.h>
#include <intuition/intuition.h>
#include <exec/tasks.h>
#include <libraries/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>

/*
**  externs for cback.o
*/
LONG _stack         = 4000L;
char *_procname     = "ScreenWatch_v1.0";
LONG _priority      = 0L;
LONG _BackGroundIO  = 0L;

struct IntuitionBase *IntuitionBase = NULL;

#define SLEEP_SIG SIGBREAKF_CTRL_F

struct TextAttr Topaz80 = {"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT};

int req(char *message, char *no_button, char *yes_button,
          struct Window *window)
{
  register struct Window *w;
  register short width;
  register short choice;
  register struct IntuiText *ack;
  register struct IntuiMessage event;
  register struct Message *msg;
  struct IntuiText req_body = {0,1,JAM2,8,4,&Topaz80,NULL,NULL};
  struct IntuiText req_ack = {AUTOFRONTPEN,AUTOBACKPEN,AUTODRAWMODE,
                              AUTOLEFTEDGE,AUTOTOPEDGE,&Topaz80,
                              NULL,AUTONEXTTEXT};
  struct IntuiText req_nak = {AUTOFRONTPEN,AUTOBACKPEN,AUTODRAWMODE,
                              AUTOLEFTEDGE,AUTOTOPEDGE,&Topaz80,
                              NULL,AUTONEXTTEXT};

  req_body.IText = message;
  width = ( IntuiTextLength(&req_body) + 39 );

  req_nak.IText = no_button;

  if (yes_button)
    {
      ack = &req_ack;
      req_ack.IText = yes_button;
    }
  else
    {
      ack = NULL;
    }

  w = BuildSysRequest(window, &req_body, ack, &req_nak,
                      (VANILLAKEY|GADGETUP), width, 47);
  if ((ULONG)w < 2L) return((int)w);  /* an alert was used */

  choice = -1;
  do
    {
      WaitPort(w->UserPort);
      msg = GetMsg(w->UserPort);
      memcpy( (char *)&event, (char *)msg, sizeof(struct IntuiMessage));
      ReplyMsg(msg);

      switch(event.Class)
        {
          case GADGETUP:
            {
              choice = ((struct Gadget *)event.IAddress)->GadgetID;
              break;
            }
          case VANILLAKEY:
            {
              switch(event.Code)
                {
                  case 27:  /* Esc */
                  case 'N': /* "N" key */
                  case 'n': /* "n" key */
                    {
                      choice = 0;
                      break;
                    }
                  case 13:  /* Return */
                  case 'Y': /* "Y" key */
                  case 'y': /* "y" key */
                    {
                      choice = 1;
                      break;
                    }
                }
              break;
            }
        }
    }
  while(choice == -1);

  FreeSysRequest(w);

  return((int)choice);
}

#define msgreq(t,w) req((t),"Okay",NULL,(w))
#define askreq(t,w) req((t),"No!","Yes",(w))


void (* __asm old_CloseScreen)(register __a0 struct Screen *) = NULL;


UBYTE use_cnt = 0;


void __asm __saveds new_CloseScreen(register __a0 struct Screen *s)
{
  UBYTE rep = 0;
  use_cnt++;

  while(s->FirstWindow != NULL)
    {
      rep++;
      if (rep == 1) ScreenToFront(s);
      if (!req("A window is open on this screen!","Ignore It",
                  "I've Closed It",s->FirstWindow)) break;
    }

  old_CloseScreen(s);
  use_cnt--;
}


int CXBRK(void)
{
  return(0);
}


main()
{
  struct Task *t, *me;

/*
**  determine if there is already a copy of this program running
*/
  me = FindTask(NULL);
  me->tc_Node.ln_Name[0] = '@'; /* don't want to find ourselves again */
  t = FindTask(_procname);
  me->tc_Node.ln_Name[0] = *_procname;
  if (t)
    {
      Signal(t,SLEEP_SIG);
      exit(0);
    }

  IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",33L);
  if (!IntuitionBase) exit(0);

  Forbid();
  old_CloseScreen = SetFunction(IntuitionBase,-0x0042,new_CloseScreen);
  Permit();

  SetSignal(0L,SLEEP_SIG);
  Wait(SLEEP_SIG);    /* wait until we get asked to leave */
  while(use_cnt > 0); /* can't pull up the rug while someone's standing on it */

  Forbid();
  SetFunction(IntuitionBase,-0x0042,old_CloseScreen);
  Permit();

  WBenchToFront();
  msgreq("ScreenWatch removed",NULL);

  CloseLibrary((struct Library *)IntuitionBase);
}
