/* Procedures to manage DOS async I/O & find window  87:4:24 */
/* .. adapted from Finkel, Lindsay, and Scheppner --  CBM */


#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <devices/conunit.h>



/* Globals initialized by findWindow() */
struct Window  *conWindow;
struct ConUnit *conUnit;



struct Window * findWindow(file) LONG file;
 /* inits conWindow and conUnit (global vars)
		and returns window pointer */
{
   struct InfoData *id;
   struct FileHandle *handle;
   struct MsgPort  *conid;
   LONG myarg, res1;

   /* Alloc to insure longword alignment */
   id = (struct InfoData *)AllocMem(sizeof(struct InfoData),
                                       MEMF_PUBLIC|MEMF_CLEAR);
   if(! id) return(NULL);
   handle = (struct FileHandle *)(file<<2);
   if (!handle->fh_Port /*Interactive*/) return(NULL);

   conid = (struct MsgPort *)handle->fh_Type /* ProcessID (!) */;
   myarg = ((ULONG)id) >> 2;
   res1 = (LONG)sendpkt(conid,ACTION_DISK_INFO,&myarg,1); /* degeneralized */
   conWindow = (struct Window *)id->id_VolumeNode;
   conUnit = (struct ConUnit *) /* USE in WB 1.2 ONLY...(but OK to read it!)*/
                 ((struct IOStdReq *)id->id_InUse)->io_Unit;
   FreeMem(id,sizeof(struct InfoData));
   return(res1 ? conWindow : NULL);
}


/* sendpkt code - A. Finkel, P. Lindsay, C. Scheppner  CBM */


sendpkt(pid,action,args,nargs) /* Lattticeified (default LONG) */
struct MsgPort *pid;  /* process indentifier ... (handler's message port ) */
LONG action,          /* packet type ... (what you want handler to do )   */
     *args,           /* a pointer to an argument list */
     nargs;           /* number of arguments in list  */
{
   struct MsgPort        *replyport;
   struct StandardPacket *packet;
 
   LONG  *pargs, res1;

   replyport = (struct MsgPort *) CreatePort(NULL,0);
   if(!replyport) return(NULL);

   packet = (struct StandardPacket *) 
      AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
   if(!packet) 
      {
      DeletePort(replyport);
      return(NULL);
      }

   packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
   packet->sp_Pkt.dp_Link         = &(packet->sp_Msg);
   packet->sp_Pkt.dp_Port         = replyport;
   packet->sp_Pkt.dp_Type         = action;

   /* copy the args into the packet */
   pargs = &(packet->sp_Pkt.dp_Arg1);       /* address of first argument */
   while (nargs--) /* compacter than original */
      *pargs++ = *args++;
 
   PutMsg(pid,packet); /* send packet */

   WaitPort(replyport);
   GetMsg(replyport); 

   res1 = packet->sp_Pkt.dp_Res1;

   FreeMem(packet,(long)sizeof(struct StandardPacket));
   DeletePort(replyport); 

   return(res1);
}


