home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / dirs / keymacro_398.lzh / KeyMacro / Null-Handler.c < prev    next >
C/C++ Source or Header  |  1990-11-01  |  5KB  |  199 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1990 by MXM
  4.  *
  5.  *    Name .....: Null-Handler.c
  6.  *    Created ..: Saturday 31-Mar-90 13:47
  7.  *    Revision .: 0
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    15-Apr-90       Olsen           Ported to Aztec 'C' 5.0
  12.  *    07-Jan-90       Olsen           Created this file!
  13.  *
  14.  *    Skeleton    handler    code   by   Phillip   Lindsay   (C)   1986
  15.  *    Commodore-Amiga,  Inc.  You may freely distribute this source and
  16.  *    use  it for Amiga Development, as long as the Copyright notice is
  17.  *    left intact.
  18.  *
  19.  ****************************************************************************
  20.  *
  21.  *    This  is  an  example how a 'real' NIL:  handler could look like.
  22.  *    It  is very loosely based on the 'my-handler' source code written
  23.  *    by Phillip Lindsay.  Since I have no access to the source code of
  24.  *    the  original  Null-Handler  I  rewrote it using Lattice 'C' 5.04
  25.  *    which  resulted  in  a very small executable file (actually about
  26.  *    568 bytes long, about 340 bytes less than the original handler).
  27.  *           Three weeks later I thought "well, why not try to bring it
  28.  *    back to Aztec 'C'?".  And that's what I did.  I can't believe it,
  29.  *    Aztec 'C' 5.0 does a brilliant job on the program:  it's actually
  30.  *    124 bytes smaller than the Lattice version.
  31.  *
  32.  * $Revision Header ********************************************************/
  33.  
  34.     /* Main includes. */
  35.  
  36. #include <libraries/filehandler.h>
  37. #include <libraries/dosextens.h>
  38. #include <exec/execbase.h>
  39. #include <functions.h>
  40.  
  41.     /* Prototypes for this module. */
  42.  
  43. LONG            HandlerEntry(VOID);
  44. VOID            ReturnPacket(struct DosPacket *Packet,ULONG Res1,ULONG Res2,struct Process *HandlerProc);
  45. struct DosPacket *    WaitPacket(struct Process *HandlerProc);
  46.  
  47.     /* Some magic pragmas. */
  48.  
  49. #pragma regcall(ReturnPacket(a0,d0,d1,a1))
  50. #pragma regcall(WaitPacket(a0))
  51.  
  52.     /* Global pointer to ExecBase. */
  53.  
  54. struct ExecBase        *SysBase;
  55.  
  56.     /* HandlerEntry():
  57.      *
  58.      *    The entry point for this handler.
  59.      */
  60.  
  61. LONG
  62. HandlerEntry()
  63. {
  64.     struct Process *HandlerProc;
  65.  
  66.         /* Set the ExecBase pointer. */
  67.  
  68.     SysBase = (struct ExecBase *)(*(LONG *)4);
  69.  
  70.         /* Get a pointer to the process structure of the
  71.          * handler.
  72.          */
  73.  
  74.     HandlerProc = (struct Process *)SysBase -> ThisTask;
  75.  
  76.         /* If not called from CLI (you shouldn't do that)
  77.          * we'll start up as a DOS-handler.
  78.          */
  79.  
  80.     if(!HandlerProc -> pr_CLI)
  81.     {
  82.         struct DosPacket    *NullPacket;
  83.         struct DeviceNode    *NullNode;
  84.  
  85.             /* Wait for startup packet (we aren't a
  86.              * BCPL module).
  87.              */
  88.  
  89.         NullPacket = WaitPacket(HandlerProc);
  90.  
  91.             /* Get pointer to handler device node. */
  92.  
  93.         NullNode = (struct DeviceNode *)BADDR(NullPacket -> dp_Arg3);
  94.  
  95.             /* Install handler task ID -> we're running. */
  96.  
  97.         NullNode -> dn_Task = &HandlerProc -> pr_MsgPort;
  98.  
  99.             /* Return the startup packet to DOS. */
  100.  
  101.         ReturnPacket(NullPacket,DOSTRUE,NullPacket -> dp_Res2,HandlerProc);
  102.  
  103.             /* Run forever - or until somebody lets us die. */
  104.  
  105.         for(;;)
  106.         {
  107.                 /* Wait for a packet. */
  108.  
  109.             NullPacket = WaitPacket(HandlerProc);
  110.  
  111.                 /* Check the type. */
  112.  
  113.             switch(NullPacket -> dp_Type)
  114.             {
  115.                 case ACTION_FINDINPUT:
  116.                 case ACTION_FINDOUTPUT:
  117.                 case ACTION_FINDUPDATE:    
  118.                 case ACTION_END:    ReturnPacket(NullPacket,DOSTRUE,0,HandlerProc);
  119.                             break;
  120.  
  121.                 case ACTION_WRITE:    ReturnPacket(NullPacket,NullPacket -> dp_Arg3,0,HandlerProc);
  122.                             break;
  123.  
  124.                 case ACTION_READ:    ReturnPacket(NullPacket,0,0,HandlerProc);
  125.                             break;
  126.  
  127.                 case ACTION_DIE:    ReturnPacket(NullPacket,DOSTRUE,0,HandlerProc);
  128.                             goto FallOff;
  129.  
  130.                 default:        ReturnPacket(NullPacket,DOSFALSE,ERROR_ACTION_NOT_KNOWN,HandlerProc);
  131.                             break;
  132.             }
  133.         }
  134.  
  135.             /* Okay, we're done, zero the task ID field
  136.              * and fall through.
  137.              */
  138.     
  139. FallOff:    NullNode -> dn_Task = NULL;
  140.     }
  141. }
  142.  
  143.     /* ReturnPacket():
  144.      *
  145.      *    Returns a packet to DOS.
  146.      */
  147.  
  148. VOID
  149. ReturnPacket(struct DosPacket *Packet,ULONG Res1,ULONG Res2,struct Process *HandlerProc)
  150. {
  151.     struct MsgPort *ReplyPort;
  152.  
  153.         /* Remember origin port. */
  154.  
  155.     ReplyPort = Packet -> dp_Port;
  156.  
  157.         /* Fill in the result fields. */
  158.  
  159.     Packet -> dp_Res1 = Res1;
  160.     Packet -> dp_Res2 = Res2;
  161.  
  162.         /* Install our task ID. */
  163.  
  164.     Packet -> dp_Port = &HandlerProc -> pr_MsgPort;
  165.  
  166.         /* Initialize the packet node head. */
  167.  
  168.     Packet -> dp_Link -> mn_Node . ln_Name    = (char *)Packet;
  169.     Packet -> dp_Link -> mn_Node . ln_Succ    = NULL;
  170.     Packet -> dp_Link -> mn_Node . ln_Pred    = NULL;
  171.  
  172.         /* Return the packet to the sender. */
  173.  
  174.     PutMsg(ReplyPort,Packet -> dp_Link);
  175. }
  176.  
  177.     /* WaitPacket():
  178.      *
  179.      *    Wait for a DOS packet.
  180.      */
  181.  
  182. struct DosPacket *
  183. WaitPacket(struct Process *HandlerProc)
  184. {
  185.     struct Message *DOSMsg;
  186.  
  187.         /* Wait at the port... */
  188.  
  189.     WaitPort(&HandlerProc -> pr_MsgPort);
  190.  
  191.         /* Get the packet. */
  192.  
  193.     DOSMsg = (struct Message *)GetMsg(&HandlerProc -> pr_MsgPort);
  194.  
  195.         /* Return a pointer to its head. */
  196.  
  197.     return((struct DosPacket *)DOSMsg -> mn_Node . ln_Name);
  198. }
  199.