/* Auto: make
*/

IMPORT LONGBITS startsignal, insertsignal, cancelsignal, donesignal;
IMPORT LONGBITS movesignal, clicksignal, timersignal, initsignal, cwsignal;
IMPORT ULONG startsignum, insertsignum, cancelsignum, donesignum;
IMPORT ULONG movesignum, clicksignum, timersignum, initsignum, cwsignum;

/* program */
IMPORT struct SnapRsrc *SnapRsrc;
IMPORT struct Task *MyTask;

/* Snap state machine */
IMPORT WORD action;
IMPORT WORD state;

/* clipboard */
IMPORT struct IOClipReq *ClipReq;
IMPORT struct MsgPort *ClipPort;

/* timer device */
IMPORT struct MsgPort *TimerPort;
IMPORT struct timerequest MyTR;

/* input device */
IMPORT struct MsgPort *inputDevPort;
IMPORT struct Interrupt handlerStuff;
IMPORT struct IOStdReq *inputRequestBlock;

IMPORT UBYTE *CharData;

/* console */
IMPORT struct MsgPort *ConPort;
IMPORT struct IOStdReq *ConIOR;
IMPORT struct KeyMap keymap;

/* windows */
IMPORT struct MsgPort *Sharedport;
IMPORT SHORT Sharedrefs;
IMPORT struct MinList CachedWindows;

/* libraries */
IMPORT struct IntuitionBase *IntuitionBase;
IMPORT struct GfxBase       *GfxBase;
IMPORT struct LayersBase    *LayersBase;
IMPORT struct ArpBase       *ArpBase;

/* graphics */
IMPORT struct RastPort TempRp;
IMPORT struct BitMap TempBM;
IMPORT UBYTE *TempRaster;

IMPORT struct Image DiskImage;
UWORD ImData[24] = {
    /* BitPlane 0 */
    0xFFFF,
    0xF00F,
    0xF7EF,
    0xF42F,
    0xF7EF,
    0xF00F,
    0xF3CF,
    0xF2CF,
    0xF2CF,
    0xFFFF,
    0xFFFF,
    0xFFFF,
    0xFFFF,
    0xFFFF,
    0xFFFF,
    0xFFFF,
    0xFFFF,
    0xFFFF,
    0xFFFF,
    0xFFFF,
    0xFFFF,
    0xFFFF,
    0xFFFF,
    0xFFFF
};

VOID CloseStuff()
{
    SafeRestore();
    {
        struct CacheWindow *cw;
        while (cw = (struct CacheWindow *)
          RemHead((struct List *)&CachedWindows)) {
            FreeMem(cw, (LONG)sizeof(struct CacheWindow));
        }
    }
    if (DiskImage.ImageData) FreeMem(DiskImage.ImageData, 32L);
    if (TempRaster)         FreeRaster(TempRaster, 16L, 16L);
    if (CharData)           FreeMem(CharData, 256L*32);
    if (inputRequestBlock) {
        if (inputRequestBlock->io_Device) {
            inputRequestBlock->io_Command = IND_REMHANDLER;  /* Remove handler */
            inputRequestBlock->io_Data    = (APTR)&handlerStuff;
            DoIO(inputRequestBlock);
            CloseDevice(inputRequestBlock);
        }
        DeleteExtIO(inputRequestBlock);
    }
    if (inputDevPort)       DeletePort(inputDevPort);
    if (TimerPort) {
        DeletePort(TimerPort);
        CloseDevice((struct IOStdReq *)&MyTR);
    }
    if (ConIOR) {
        CloseDevice(ConIOR);
        DeleteExtIO(ConIOR);
    }
    if (ConPort)            DeletePort(ConPort);
    if (ClipReq) {
        if (ClipReq->io_Device) {
            CloseDevice(ClipReq);
        }
        DeleteExtIO(ClipReq);
    }
    if (ClipPort)           DeletePort(ClipPort);
    if (startsignum != -1)  FreeSignal(startsignum);
    if (donesignum != -1)   FreeSignal(donesignum);
    if (cancelsignum != -1) FreeSignal(cancelsignum);
    if (movesignum != -1)   FreeSignal(movesignum);
    if (insertsignum != -1) FreeSignal(insertsignum);
    if (clicksignum != -1)  FreeSignal(clicksignum);
    if (timersignum != -1)  FreeSignal(timersignum);
    if (initsignum != -1)   FreeSignal(initsignum);
    if (cwsignum != -1)     FreeSignal(cwsignum);
    if (SnapRsrc) {
        RemResource(SnapRsrc);
        Kill(SnapRsrc);
    }
    if (ArpBase)            CloseLibrary((struct Library *)ArpBase);
    if (IntuitionBase)      CloseLibrary((struct Library *)IntuitionBase);
    if (GfxBase)            CloseLibrary((struct Library *)GfxBase);
    if (LayersBase)         CloseLibrary((struct Library *)LayersBase);
}

WORD OpenStuff()
{
    action = noaction;
    state  = waiting;
    inputRequestBlock = NULL;

    Sharedrefs = 0;
    Sharedport = NULL;
    NewList((struct NewList *)&CachedWindows);

    /* Set up everything we need. */

    /* libraries */

    if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L)))
        return 0;
    if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0L)))
        return 0;
    if (!(LayersBase = (struct LayersBase *)OpenLibrary("layers.library", 0L)))
        return 0;
    ArpBase = (struct ArpBase *)OpenLibrary(ArpName, ArpVersion);

    /* signals */

    if ((startsignum = AllocSignal(-1L)) == -1L)
        return 0;
    if ((insertsignum = AllocSignal(-1L)) == -1L)
        return 0;
    if ((cancelsignum = AllocSignal(-1L)) == -1L)
        return 0;
    if ((donesignum = AllocSignal(-1L)) == -1L)
        return 0;
    if ((movesignum = AllocSignal(-1L)) == -1L)
        return 0;
    if ((clicksignum = AllocSignal(-1L)) == -1L)
        return 0;
    if ((timersignum = AllocSignal(-1L)) == -1L)
        return 0;
    if ((initsignum = AllocSignal(-1L)) == -1L)
        return 0;
    if ((cwsignum = AllocSignal(-1L)) == -1L)
        return 0;
    MyTask = FindTask(NULL);                  /* Find myself to Signal me.  */
    startsignal  = 1L << startsignum;         /* No good to use bit numbers */
    insertsignal = 1L << insertsignum;
    cancelsignal = 1L << cancelsignum;
    donesignal   = 1L << donesignum;
    movesignal   = 1L << movesignum;
    clicksignal  = 1L << clicksignum;
    timersignal  = 1L << timersignum;
    initsignal   = 1L << initsignum;
    cwsignal     = 1L << cwsignum;

    /* clipboard device */

    if (!(ClipPort = CreatePort(0L, 0L)))
        return 0;
    if (!(ClipReq = (struct IOClipReq *)CreateExtIO(ClipPort, (LONG)sizeof(*ClipReq))))
        return 0;
    if (OpenDevice("clipboard.device", 0L, ClipReq, 0L))
        return 0;
    ClipReq->io_ClipID = 0L;

    /* console device */

    if (!(ConPort = CreatePort(0L, 0L)))
        return 0;
    if (!(ConIOR = (struct IOStdReq *)CreateExtIO(ConPort, (LONG)sizeof(struct IOStdReq))))
        return 0;
    if (OpenDevice("console.device", -1L, ConIOR, 0L))
        return 0;

    /* timer device */
    if (!(TimerPort = CreatePort(NULL, 0L)))
        return 0;
    if (OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IOStdReq *)&MyTR, 0L))
        return 0;
    MyTR.tr_node.io_Message.mn_ReplyPort = TimerPort;
    MyTR.tr_node.io_Command = TR_ADDREQUEST;

    /* input devive */

    if (!(inputDevPort = CreatePort(0L, 0L)))
        return 0;
    if (!(inputRequestBlock = (struct IOStdReq *)CreateExtIO(inputDevPort, (LONG)sizeof(struct IOStdReq))))
        return 0;
    if (OpenDevice("input.device", 0L, inputRequestBlock, 0L))
        return 0;

    /* input handler */

    handlerStuff.is_Data = (APTR)0x534E4150; /* Set up for installation of */
    handlerStuff.is_Code = myhandler;        /* myhandler.                 */
    handlerStuff.is_Node.ln_Pri = SnapRsrc->Priority;
                                             /* Ahead of intuition, please */
    handlerStuff.is_Node.ln_Name = "Snap Input Handler";

    inputRequestBlock->io_Command = IND_ADDHANDLER;
    inputRequestBlock->io_Data    = (APTR)&handlerStuff;

    DoIO(inputRequestBlock);  /* Add me. */


    /* Aligned font bitmap to use when matching */

    if (!(CharData = AllocRaster(16L, 256L*16))) {
        return 0;
    }

    /* temporary raster */

    if (!(TempRaster = AllocRaster(16L, 16L)))
        return 0;
    InitRastPort(&TempRp);                   /* Init RastPort used for */
    InitBitMap(&TempBM, 1L, 16L, 16L);       /* Locating position of   */
    TempBM.Planes[0] = TempRaster;           /* first character.       */
    TempRp.BitMap = &TempBM;

    if (!(DiskImage.ImageData = AllocMem(48L, MEMF_CHIP))) {
        return 0;
    }
    CopyMem((char *)&ImData[0], (char *)DiskImage.ImageData, 48L);
    return 1;
}
