/*******************************************************************\
*                                                                   *
*                XSize - XWindows style window sizing               *
*                                                                   *
\*******************************************************************/
/* Auto: make
*/

#define ARGVAL() (*++(*argv) || (--argc && *++argv))
#define WriteStdOut(str) Write(StdOut, str, (LONG)strlen(str))
#define isdigit(c) (c >= '0' && c <= '9')

struct XSizeRsrc *XSizeRsrc = NULL;
struct InputEvent *handler();

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

/* libraries */
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase       *GfxBase = NULL;
struct LayersBase    *LayersBase = NULL;

/* detaching */
ULONG _BackGroundIO = 0;
ULONG _stack = 4096L;
ULONG _priority = 4L;
char *_procname = "XSize";
#ifdef LATTICE
extern BPTR _Backstdout;
#endif LATTICE

LONG hextoint(str)
REGISTER char *str;
{
    REGISTER long val = 0;
    REGISTER char c;
    while (c = *str) {
        val <<= 4;
        val |= (c & 15) + (isdigit(c) ? 0 : 9);
        str++;
    }
    return(val);
}

VOID CloseStuff()
{
    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 (XSizeRsrc) {
        RemResource(XSizeRsrc);
        Kill(XSizeRsrc);
    }
    if (IntuitionBase)      CloseLibrary((struct Library *)IntuitionBase);
    if (GfxBase)            CloseLibrary((struct Library *)GfxBase);
    if (LayersBase)         CloseLibrary((struct Library *)LayersBase);
}

WORD OpenStuff()
{
    inputRequestBlock = NULL;

    /* 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;

    /* 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 = 0;
    handlerStuff.is_Code = (VOID (*)())handler;
    handlerStuff.is_Node.ln_Pri = 53;        /* Ahead of intuition, please */
    handlerStuff.is_Node.ln_Name = "XSize Input Handler";

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

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

    return 1;
}

VOID main(argc, argv)
int argc;
char **argv;
{
    BPTR StdOut = (BPTR)Open("*", MODE_OLDFILE);
    WORD create = 0;
    WORD usage = 0;

#ifdef AZTEC_C
    Enable_Abort = 0;
#endif AZTEC_C

    if (!(XSizeRsrc = (struct XSizeRsrc *)OpenResource(XSIZERSRC))) {
        create = 1;
        XSizeRsrc = Create(XSizeRsrc);
        XSizeRsrc->node.ln_Type = NT_RESOURCE;
        XSizeRsrc->node.ln_Name = XSIZERSRC;
        XSizeRsrc->Task = FindTask(NULL);
        XSizeRsrc->qual = IEQUALIFIER_CONTROL;
        AddResource(XSizeRsrc);
    }

    if (!argc) {    /* WB Startup */
        if (!create) {     /* Second time from WB -- Remove */
            Signal(XSizeRsrc->Task, SIGBREAKF_CTRL_C);
            goto exitpoint;
        } else {
            goto skipargs;
        }
    }

    if (create && StdOut) {
        WriteStdOut("XSize 1.0 (c) 1990 Mikael Karlsson\n");
    }

    for (argc--, argv++; argc > 0; argc--, argv++) {
        if (**argv == '-') { /* Argument coming up */
            switch(*++(*argv)) {
                case 'x': {
                    if (ARGVAL()) {
                        XSizeRsrc->qual = hextoint(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'Q': quit: {
                    Close(StdOut);
                    if (create) {
                        goto close;
                    } else {
                        Signal(XSizeRsrc->Task, SIGBREAKF_CTRL_C);
                        goto exitpoint;
                    }
                }
                case '?': {
                    usage = 1;
                    break;
                }
                default: {
                    if (StdOut) {
                        WriteStdOut("Bad option: -");
                        Write(StdOut, *argv, 1L);
                        WriteStdOut(".\n");
                    }
                    usage = 1;
                    break;
                }
            }
        } else {
            usage = 1;
        }
    }

    if (usage && StdOut) {
        WriteStdOut("Usage:\n");
        WriteStdOut(" XSize -xXX -Q\n");
    }

skipargs:
    if (StdOut) {
        Close(StdOut);
    }

    if (create) {
        if (OpenStuff()) {
            Wait(SIGBREAKF_CTRL_C);
        }
close:
        CloseStuff();  /* Guess what */
    }

exitpoint: ;
}
