/* IPo2C.c */
/* Convert current intuition pointer to C definition file */
/* by Alex Livshits    26-Sep-87 */

#include <exec/types.h>
#include <exec/ports.h>
#include <exec/memory.h>
#include <exec/io.h>
#include <exec/tasks.h>
#include <exec/interrupts.h>
#include <libraries/dos.h>
#include <devices/input.h>
#define INTUITIONPRIVATE
#include <intuition/intuitionbase.h>


#define PORT      0x00000001
#define REQUEST   0x00000002
#define SIGNAL    0x00000004
#define INPUTDEV  0x00000008
#define MEMORY    0x00000010

/* ==== IMPORT ==== */
extern struct IntuitionBase *IntuitionBase;
extern struct InputEvent *InputHandler();
extern int HandlerInterface();
/****/

/* ==== EXPORT ==== */
ULONG EVENT;
APTR  MyTask;
ULONG STOPFLAG=FALSE;
int Suspend=FALSE;
/***/


static struct MsgPort *port;
static struct IOStdReq *req;
static struct Interrupt handler;
static LONG signal;
static int PointerNum = 0;
static char *name;

static ULONG mask;
static BPTR fp;


main(argc,argv)
   int argc;
   char *argv[];
{
   int retc;
   BPTR lock;

   mask = 0;
   fp=0;

   printf("\n\t    ++++  IPo2C  v1.0   ++++");
   printf("\n\t(C)FLam == A.Livshits J-M.Forgeas == 1987");

   if (argc==1)
   {
      printf("\nUsage:\nIPo2C [<FileName> -> valid DOS file]");
      exit(0);
   }

   name = argv[1];
   IntuitionBase = OpenLibrary("intuition.library",0);
   if (!IntuitionBase)
   {
        printf("\nFailed to open intuition.library");
        exit(0);
   }
   port = CreatePort(0,0);
   if (!port)
   {
      printf("\nFailed to open MsgPort");
      cleanup();
      exit(0);
   }
   mask |= PORT;

   req = CreateStdIO(port);
   if (!req)
   {
      printf("\nFailed to create StdIO");
      cleanup();
      exit(0);
   }
   mask |= REQUEST;

   signal = AllocSignal(-1);
   if (signal==-1)
   {
      printf("\nFailed to allocate SignalBit");
      cleanup();
      exit(0);
   }
   mask |= SIGNAL;
   EVENT = 1L<<signal;
   MyTask = (APTR)FindTask(0);

   handler.is_Data = 0;
   handler.is_Code = HandlerInterface;
   handler.is_Node.ln_Pri = 51;

   Suspend=FALSE;
   retc = OpenDevice("input.device",0,req,0);
   if (retc)
   {
      printf("\nFailed to open Input Device");
      cleanup();
      exit(0);
   }

   STOPFLAG = FALSE;

   req->io_Command = IND_ADDHANDLER;
   req->io_Data = &handler;
   DoIO(req);
   mask |= INPUTDEV;

   printf("\n\tALT-F -> Quit");
   printf("\n\tPress ALT-P to write file.\n");
   while(TRUE)
   {
      Wait(EVENT);
      if (STOPFLAG) break;
      lock = Lock(name,ACCESS_WRITE);
      if (lock)
      {
        UnLock(lock);
        fp = Open(name,MODE_OLDFILE);
      }
      else fp = Open(name,MODE_NEWFILE);
      if (!fp)
      {
         printf("\nFailed to open output file %ls",name);
         break;
      }
      Seek(fp,0,OFFSET_END);
      if (!CopyPointer(fp)) break;
      Close(fp);
      fp = 0;
      Suspend=FALSE;
   }
   cleanup();
   exit(0);
}


static
CopyPointer(fp)
    BPTR fp;
{
    UWORD *buf;
    WORD len;
    ULONG ilock;
    BYTE height,width,xoffs,yoffs;
    int retc;

    ilock = LockIBase(0);
    height = IntuitionBase->APtrHeight;
    width = IntuitionBase->APtrWidth;
    xoffs = IntuitionBase->AXOffset;
    yoffs = IntuitionBase->AYOffset;

    len = (height+2)*sizeof(ULONG);
    buf = AllocMem(len,MEMF_PUBLIC+MEMF_CLEAR);
    if (!buf)
    {
        printf("\nOut of memory.");
        return(FALSE);
    }

    CopyMem(IntuitionBase->APointer,buf,len);
    UnlockIBase(ilock);
    retc=SavePointer(fp,buf,width,height,xoffs,yoffs);
    FreeMem(buf,len);
    return(retc);

}

static
SavePointer(fp,buf,w,h,xofs,yofs)
    BPTR fp;
    USHORT *buf;
    BYTE w,h,xofs,yofs;
{
    int i;

    fprintf(fp,"\n/* ============================================= */");
    fprintf(fp,"\n/*              Pointer Data                     */");
    fprintf(fp,"\n/* ============================================= */");

    PointerNum++;
    if (!w) w = 16;
    fprintf(fp,"\n#define POINTER%ld_HEIGHT %ld",PointerNum,h);
    fprintf(fp,"\n#define POINTER%ld_WIDTH  %ld",PointerNum,w);
    fprintf(fp,"\n#define POINTER%ld_HOTX   %ld",PointerNum,xofs);
    fprintf(fp,"\n#define POINTER%ld_HOTY   %ld",PointerNum,yofs);

    fprintf(fp,"\n\nUSHORT pointer%ld_dat[] = {",PointerNum);

    fprintf(fp,"\n\t0x0000,0x0000,");
    buf += 2;

    for (i=0;i<h;i++)
    {
        fprintf(fp,"\n\t0x%lx,0x%lx,",*buf,*(buf+1));
        buf += 2;
    }

    fprintf(fp,"\n\t0x0000,0x0000");

    fprintf(fp,"\n};\n");
    printf("Pointer definition written to %ls.\n",name);
    return(TRUE);
}


static
cleanup()
{
   if (fp) Close(fp);
   if (mask & INPUTDEV) {
         req->io_Command=IND_REMHANDLER;
         req->io_Data=&handler;
         DoIO(req);
         CloseDevice(req);
   }
   if (mask & SIGNAL) FreeSignal(signal);
   if (mask & REQUEST) DeleteStdIO(req);
   if (mask & PORT) DeletePort(port);
   CloseLibrary(IntuitionBase);
}



