home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 144.lha / Leach_v1.3 / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-21  |  20.6 KB  |  699 lines

  1. /******************************************************************************
  2.  *
  3.  *  THIS FILE USES 4 COLUMN TAB STOPS. 
  4.  *    
  5.  *
  6.  *    This is the Intuition Message processor for Leach Ver 1.3
  7.  *
  8.  ******************************************************************************/
  9.  
  10. #include    <functions.h>
  11. #include    <exec/ports.h>
  12. #include    <exec/libraries.h>
  13. #include    <graphics/gfx.h>
  14. #include    <graphics/rastport.h>
  15. #include    <graphics/text.h>
  16. #include    <intuition/intuitionbase.h>
  17. #include     <stdio.h>
  18.  
  19. /*----------------------------------------------------------------------------*
  20.  * gad.h is a real mixed bag. It defines (allocates storage for) many gadget
  21.  * related variables. It also declares the char array "statustext".
  22.  *----------------------------------------------------------------------------*/
  23.  
  24. #include    "gad.h"
  25.  
  26.  
  27. /*  Stuff in globals.h is defined globally and initialized in main.c.    */
  28.  
  29. #define GLOBAL extern
  30. #include "globals.h"
  31.  
  32. extern short endpoints[];            /* End point coordinates for ruler    */
  33.  
  34. #define x1 0                        /* endpoints array indexes.            */
  35. #define y1 1                        /* Note LOWER CASE!                    */
  36. #define x2 2
  37. #define y2 3
  38.  
  39. extern struct    Border ruler;        /* Border struct for ruler.            */
  40.  
  41. /************  VARIABLES USED JUST INSIDE THIS FILE  ********************/
  42.  
  43. short    mx, my;            /* Mouse coordinates.    */
  44. short    trac;            /* TRUE if in the middle of MOUSEBUTTONS pair    */
  45. short    update;            /* Flag means status display needs refreshing.    */
  46. short    ruler_color = 3;
  47. short    moving = 0;        /* Nonzero if ruler should be tracking mouse*/
  48. short    sizing = 0;        /* 0 if the ruler is not being sized/moved    */    
  49.                         /* 1 if the first endpoint is being moved.    */
  50.                         /* 2 if the second endpoint is being moved.    */
  51.  
  52.  
  53. /*******************************************************************************
  54.  *                        LOOP MONITORING MENU EVENTS
  55.  *
  56.  * This routine sleeps, waiting for an IntuiMsg for either the Host or for
  57.  * the Leach's status window or for a message being returned by the Host to
  58.  * "MyPort". There are separate processor routines for each of these message
  59.  * types. Note that ALL MESSAGES IN THE HOST IDCMP ARE PROCESSED BEFORE ANY
  60.  * OF THE LEACH MESSAGES ARE PROCESSED. Hopefully this means that there
  61.  * won't be any msgs for Leach in the Host's queue when Leach processes
  62.  * a CLOSEWINDOW event from its queue. Eventually one of the processors will
  63.  * fail to return because it terminated the program. event_processor() will
  64.  * never return to its caller.
  65.  *
  66.  * Also remember that Leach is running at a higher priority than the Host
  67.  * so, Leach will get first crack at the incoming messages even if
  68.  * the Host is processing its msg queue when a msg arrives at the port.
  69.  ******************************************************************************/
  70.  
  71. event_processor()
  72. {
  73.  
  74. ULONG    sigfor, StatMask, HostMask, MyMask;
  75.  
  76. StatMask = 1L << StatWind->UserPort->mp_SigBit;
  77. HostMask = 1L << HostSig;
  78. MyMask     = 1L << MySig;
  79.  
  80. FOREVER
  81. {
  82.     sigfor = Wait(HostMask | StatMask | MyMask);
  83.  
  84.     if (sigfor & MyMask)    /* Replying to IntuiMsgs gets top priority.    */
  85.         myport_event();
  86.     if (sigfor & HostMask)
  87.         host_event();
  88.     if (sigfor & StatMask)
  89.         stat_event();
  90.     if (sigfor & ~(HostMask | StatMask) )
  91.     {
  92.         puts("event_processor(): RECEIVED AN UNEXPECTED SIGNAL BIT.");
  93.         cleanup(202);
  94.     }
  95.  
  96. } /* end of FOREVER */
  97.  
  98. } /*  End of event_processor()  */
  99.  
  100.  
  101. /*****************************************************************************
  102.  * CHECKMSG()
  103.  *
  104.  * This routine looks at the messages in the Host IDCMP's input queue and
  105.  * returns the address of the next message to be processed by host_event().
  106.  * It always starts at the first msg in the queue, walking the linked list
  107.  * until it finds a msg whose mn_ReplyPort is not "MyPort". It sets the
  108.  * mn_ReplyPort to MyPort in messages that have been processed. It has to 
  109.  * work this way cause you never know when a new msg might arrive or what 
  110.  * the Host has been doing to the list since you last looked at it.
  111.  *
  112.  * Returns address of current message or Null if there are no new messages.
  113.  *
  114.  * FYI: This is what an IntuiMessage looks like.
  115.  *
  116.  * struct IntuiMessage
  117.  * {
  118.  *    struct Message ExecMessage 
  119.  *    {
  120.  *        struct Node    mn_Node
  121.  *        {
  122.  *            struct Node *ln_Succ;
  123.  *            struct Node *ln_Pred;
  124.  *            UBYTE        ln_Type;
  125.  *            BYTE        ln_Pri;            NOT ALWAYS INITIALIZED TO ZERO!
  126.  *            char        *ln_Name;
  127.  *        }
  128.  *        struct MsgPort    *mn_ReplyPort;
  129.  *        UWORD            mn_Length;
  130.  *    }
  131.  *    ULONG    Class;
  132.  *    USHORT    Code;
  133.  *    USHORT    Qualifier;
  134.  *    APTR    IAddress;
  135.  *    SHORT    MouseX, MouseY;
  136.  *    ULONG    Seconds, Micros;
  137.  *    struct Window *IDCMPWindow;
  138.  *    struct IntuiMessage *SpecialLisk;        Don't ever mess with this
  139.  * }
  140.  *
  141.  *    struct MsgPort
  142.  *    {
  143.  *        struct    Node    mp_Node;
  144.  *        UBYTE            mp_Flags;
  145.  *        UBYTE            mp_SigBit;
  146.  *        struct    Task    *mp_SigTask;
  147.  *        struct    List     mp_MsgList;
  148.  *    };
  149.  *****************************************************************************/
  150.  
  151. struct IntuiMessage *checkmsg(port)
  152. struct MsgPort    *port;                /* Port to be examined    */
  153. {
  154.  
  155. register struct IntuiMessage *message;
  156.  
  157. short    cnt;                        /* cnt & check_flags are for debugging */
  158. short    check_flags;
  159.  
  160.  
  161. /* These #defines are only used for debugging.    */
  162.  
  163. #define NO_MSG        0x0001
  164. #define NULL_HEAD    0x0004
  165. #define NO_NEW        0x0008
  166.  
  167. cnt = check_flags = 0;
  168. Forbid();                    /*##########  MULTITASKING DISABLED  ##########*/
  169.  
  170.  
  171. /*-------------------------------------------------------------------------*
  172.  * Aim message pointer at the first node in the list. lh_Head should never
  173.  * be NULL, but we'll check anyway. If Head is pointing at the Tail, the
  174.  * msg queue is empty. This could be an error but probably isn't. It
  175.  * happens when disposemsg() Remove()s the only message in the queue. In
  176.  * this case, checkmsg() returned a valid message address so, the while 
  177.  * loop in host_event() takes another look at the message queue, which is 
  178.  * now empty.
  179.  *-------------------------------------------------------------------------*/
  180.  
  181. message = (struct IntuiMessage *) port->mp_MsgList.lh_Head;
  182. if (!message)
  183.     check_flags |= NULL_HEAD;
  184. else if (message == &(port->mp_MsgList.lh_Tail) )
  185. {
  186.     check_flags |= NO_MSG;
  187.     message = NULL;
  188. }
  189. while (message)
  190. {
  191.     ++cnt;
  192.     if (message->ExecMessage.mn_ReplyPort != MyPort)
  193.     {
  194.         /*--------------------------------------------------------------------*
  195.          * Found unprocessed message. I hate altering the IntuiMessage like
  196.          * this but, you can't count on the date stamps uniquely identifying
  197.          * the messages. I had to mark them somehow.
  198.          *--------------------------------------------------------------------*/
  199.         if (!HostIPort)
  200.         {
  201.             HostIPort = message->ExecMessage.mn_ReplyPort;
  202.         }
  203.         else if (message->ExecMessage.mn_ReplyPort != HostIPort)
  204.         {
  205.             /* Aegis Images triggers this error message sometimes.    */
  206.             puts("CHECKMSG(): Found an unexpected mn_ReplyPort.");
  207.         }
  208.         message->ExecMessage.mn_ReplyPort = MyPort;
  209.         break;
  210.     }
  211.     else    /* Leach has already seen this msg. Try next msg in the queue.    */
  212.     {
  213.         message = message->ExecMessage.mn_Node.ln_Succ;
  214.         if (message == &(port->mp_MsgList.lh_Tail) )
  215.         {
  216.             message = NULL;                    /* Reached end of msg list.    */
  217.             check_flags |= NO_NEW;
  218.         }
  219.     }
  220. } /*  end of while (message)  */
  221.  
  222.  
  223. /*------------------------------------------------------------------------*
  224.  * Re-enabling multitasking here feels vaguely dangerous. I am about to
  225.  * pass around a pointer to a msg that I don't own. However, host_event()
  226.  * will make a copy of the message data as soon as checkmsg() returns.
  227.  *------------------------------------------------------------------------*/
  228.  
  229. Permit();                    /*###########  MULTITASKING ENABLED  ###########*/
  230.  
  231. /*****************************************************************************
  232.  *** If any of the "error" conditions occurred, now's the time to speak up.  *
  233.  
  234. if (check_flags)
  235. {
  236.     if (check_flags & NO_MSG)
  237.     {
  238.         puts("No msg in Host's UserPort.");
  239.     }
  240.     if (check_flags & NULL_HEAD)
  241.     {
  242.         puts(" SOME HOW, LH_HEAD IS NULL."); 
  243.     }
  244.     if (check_flags & NO_NEW)
  245.     {
  246.         printf("EOQ #%d.\n", cnt);
  247.     }
  248.     check_flags = 0;
  249. }
  250. else
  251. {
  252.     printf("checkmsg(): Msg #%d new.\n", cnt);
  253. }
  254. printf("checkmsg(): Returning msg addr $%lx.\n", message);
  255. *****************************************************************************
  256. *****************************************************************************/
  257.  
  258. return(message);
  259.  
  260. } /*  End of checkmsg()  */
  261.  
  262.  
  263.  
  264. /*****************************************************************************
  265.  * This routine identifies messages that Leach is not going to pass on
  266.  * to the Host, Remove()'s them, restores mn_ReplyPort to Intuition's Port 
  267.  * address & ReplyMsg()'s to them. It is also responsible for Signal()'ing
  268.  * the Host for msgs that are not consumed by Leach.
  269.  *****************************************************************************/
  270.  
  271. disposemsg(msg)
  272. struct IntuiMessage    *msg;
  273. {
  274.  
  275. register ULONG    class;
  276. register USHORT    code;
  277.  
  278. class = msg->Class;
  279. code  = msg->Code;
  280.  
  281. /*---------------------------------------------------------------------------*
  282.  * If any of 3 criteria for consuming a msg is met the msg is removed from 
  283.  * the queue and replied to. The criteria are:
  284.  *        1) A MOUSEBUTTONS event while the ruler is in "move" mode.
  285.  *        2) A MOUSEMOVE event while the ruler is tracking the mouse.
  286.  *        3) A menu selection has been made from the menu Leach installed
  287.  *           at the end of the Host's first menu.
  288.  *---------------------------------------------------------------------------*/
  289.  
  290. if ( ( (MOVEGAD.Flags & SELECTED) && (class == MOUSEBUTTONS) ) ||
  291.        ( (trac == TRUE) && (class == MOUSEMOVE ) )  ||
  292.        ( (class == MENUPICK) && (code  != MENUNULL) &&
  293.          ( MENUNUM(code) == L_menu_num) && (ITEMNUM(code) == L_menuitem_num) ) )
  294. {
  295.     Forbid();
  296.     Remove( &(msg->ExecMessage.mn_Node) );        /* For Leach only.    */
  297.     Permit();
  298.     msg->ExecMessage.mn_ReplyPort = HostIPort;
  299.     ReplyMsg(msg);
  300. }
  301. else
  302. {
  303.     Signal(HostTask, 1L << HostSig);
  304. }
  305.  
  306. return;
  307.  
  308. }  /*  End of disposemsg()  */
  309.  
  310.  
  311. /*****************************************************************************
  312.  *                    HOST INTUITION EVENT PROCESSOR
  313.  * This routine examins all the messages waiting at the Host's IDCMP. The
  314.  * messages have to be examined in place so that they can be passed on to
  315.  * the Host, if necessary. Messages intended exclusively for Leach are
  316.  * removed from the message queue.
  317.  *****************************************************************************/
  318.  
  319. host_event()
  320. {
  321.  
  322. ULONG    class;         /* Class of IntuiMessage.    */
  323. USHORT    code;         /* Code of IntuiMessage.    */
  324.  
  325. static UBYTE act_flag = 0;    /* Set when Host receives ACTIVEWINDOW msg.    */
  326.  
  327. USHORT    MenuNum, ItemNum, SubNum; /* Menu, MenuItem and Subitem numbers */
  328. short    mmflag;
  329. struct IntuiMessage    *message;
  330.  
  331. /*----------------------------------------------------------------------*
  332.  * Note that checkmsg() is periodically called when there are no msgs in
  333.  * the queue. This happens when disposemsg() removes the only msg in the
  334.  * queue or when the end of the queue is reached. checkmsg() gets called
  335.  * one last time and finds the cupboard is bare. This is not an error.
  336.  *----------------------------------------------------------------------*/
  337.  
  338. while( message =  checkmsg(HostUPort) )
  339. {
  340.     class = message->Class;
  341.     code  = message->Code;
  342.     mx    = message->MouseX;
  343.     my    = message->MouseY;
  344.  
  345.     /* printf("H_event: Class = $%lx. Code = $%x.\n\n", class, code); */
  346.  
  347.     disposemsg(message);        /* ReplyMsg()s to Leach msgs and Signals */
  348.                                 /* the Host for pass through msgs.         */
  349.  
  350.  
  351.     if (class == ACTIVEWINDOW)
  352.         act_flag = 2;            /* Ignore next SELECT UP/DOWN pair.        */
  353.  
  354.     /*---------------------  HOST MENU EVENTS  -------------------------*
  355.      *------------------------------------------------------------------*/
  356.  
  357.     else if (class == MENUPICK && code != MENUNULL) 
  358.     {
  359.         MenuNum = MENUNUM(code);
  360.         ItemNum = ITEMNUM(code);
  361.         SubNum    = SUBNUM(code);
  362.  
  363.         /* If Leach's MenuItem...    */
  364.         if (MenuNum == L_menu_num && ItemNum == L_menuitem_num)
  365.         {
  366.             switch (SubNum)
  367.             {
  368.                 case 0:                            /* Leach screen to front */
  369.                     ScreenToFront(StatScreen);
  370.                     break;
  371.  
  372.                 case 1:                            /* Leach screen to back     */
  373.                     ScreenToBack(StatScreen);
  374.                     break;
  375.             }
  376.         }
  377.         else                                    /* Not Leach Menu         */
  378.         {
  379.             /*----------------------------------------------------------*
  380.              * The only Host menu event that we take special interest in
  381.              * is QUIT. All other Host menu events are treated the same 
  382.              * way. Namely, Leach tries to make itself as inconspicuous
  383.              * as possible.
  384.              *----------------------------------------------------------*/
  385.  
  386.             if ( (MenuNum == H_quit_menu) && (ItemNum == H_quit_item) &&
  387.                                                         (H_found_quit)   )
  388.             {
  389.                 cleanup(204);
  390.             }
  391.             else
  392.             {
  393.                 if (SHOWGAD.Flags & SELECTED)  /* If in show mode... */
  394.                 {
  395.                     hide_ruler();
  396.                 }
  397.                 ScreenToBack(StatScreen);
  398.                 break;
  399.             }
  400.         }
  401.  
  402.     } /* End of if (class == MENUPICK && code != MENUNULL)    */
  403.  
  404.  
  405.     /*-------------------  SELECT BUTTON EVENTS  -----------------------*
  406.      * Select button events while the MOVE gadget is selected are the
  407.      * exclusive property of Leach. They control movement and sizing of
  408.      * the ruler. If the Host window activation flag is set, we want to
  409.      * ignore the next mouse click.
  410.      *------------------------------------------------------------------*/
  411.  
  412.     else if ( (class == MOUSEBUTTONS) && (MOVEGAD.Flags & SELECTED) )
  413.     {
  414.         if (act_flag)
  415.             --act_flag;
  416.         else if (code == SELECTDOWN)
  417.         {
  418.             HostFlagsmods |= REPORTMOUSE;
  419.             HostWind->Flags = HostFlags | HostFlagsmods;
  420.  
  421.             HostIDCMPmods |= MOUSEMOVE;
  422.             ModifyIDCMP(HostWind, HostIDCMPflags | HostIDCMPmods);
  423.  
  424.             trac = TRUE;
  425.  
  426.             /* If the mouse is near the first endpoint, then move it.    */
  427.  
  428.             if ( (mx > endpoints[x1] - 4) && (mx < endpoints[x1] + 4) &&
  429.                  (my > endpoints[y1] - 5) && (my < endpoints[y1] + 5)    )
  430.             {
  431.                 sizing = 1;
  432.                 moving = 0;
  433.                 size_ruler();
  434.             }
  435.  
  436.             /* Or, if the mouse is near the second endpoint, then move it. */
  437.  
  438.             else if ( (mx > endpoints[x2] - 4) && (mx < endpoints[x2] + 4) &&
  439.                       (my > endpoints[y2] - 5) && (my < endpoints[y2] + 5)    )
  440.             {
  441.                 sizing = 2;
  442.                 moving = 0;
  443.                 size_ruler();
  444.             }
  445.             
  446.             /* By default we'll move the entire ruler. The first endpoint */
  447.             /* will jump to the mouse position.                              */
  448.  
  449.             else    
  450.             {
  451.                 sizing = 0;
  452.                 moving = 1;
  453.                 move_ruler();
  454.             }
  455.         } /*  end of if ( (code == SELECTDOWN) && etc )  */
  456.  
  457.         else if (code == SELECTUP)
  458.         {
  459.             /*----------------------------------------------------------*
  460.              * If we're done moving, shut off reports on mouse movement.
  461.              * There may be other mouse movement msgs at the IDCMP but,
  462.              * we'll process/ignore them later.
  463.              *----------------------------------------------------------*/
  464.  
  465.             HostFlagsmods  &= ~REPORTMOUSE;
  466.             HostWind->Flags = HostFlags | HostFlagsmods;
  467.  
  468.             HostIDCMPmods    &= ~MOUSEMOVE;
  469.             ModifyIDCMP(HostWind, HostIDCMPflags | HostIDCMPmods);
  470.             trac = FALSE;
  471.         }
  472.     } /*  end of else if ( (class == MOUSEBUTTONS) && etc)  */
  473.  
  474.  
  475.     /*----------------------  RULER MOVEMENT  -----------------------------*
  476.      * If the ruler is tracking the mouse, all we do is note that the mouse
  477.      * has moved. We don't actually move the ruler until we've processed
  478.      * all the messages in the queue, other wise we couldn't handle the
  479.      * flood of MOUSEMOVE messages that come in.
  480.      *---------------------------------------------------------------------*/
  481.  
  482.     else if ( (class == MOUSEMOVE) && (trac == TRUE) )
  483.     {
  484.         mmflag    = TRUE;
  485.  
  486.     } /*  end of else if (class == MOUSEMOVE && etc)  */
  487.  
  488. } /*  End of while(message =  checkmsg(HostUPort))  */
  489.  
  490.  
  491. /*----------------------------------------------------------------------------*
  492.  * At this point we have processed all of the new msgs that were found in the
  493.  * Host's message queue. If we have encountered any MOUSEMOVE msgs during this
  494.  * pass through the list that were for Leach, we'll now actually move the
  495.  * ruler and change the status display.
  496.  *----------------------------------------------------------------------------*/
  497.  
  498. if (mmflag)        /* If there have been requests for line movement.    */
  499. {
  500.     if (moving)
  501.         move_ruler();
  502.     else if (sizing)
  503.         size_ruler();
  504.  
  505.     mmflag = FALSE;
  506. }
  507. /*---------------------------------------------------------------------------*
  508.  * trac is cleared when a SELECTUP event is detected. This tells disposemsg()
  509.  * to stop scarfing MOUSEMOVE msgs. However, there may still be a move 
  510.  * pending as indicated by moving or sizing. Well, we just finished that
  511.  * move, so now we can finally turn these indicators off.
  512.  *---------------------------------------------------------------------------*/
  513.  
  514. if (!trac)
  515. {
  516.     moving = sizing = 0;
  517. }
  518.     
  519. if (update)
  520. {
  521.     update_status();
  522.     update = 0;
  523. }
  524.  
  525. return;
  526.  
  527. } /*  End of host_event  */
  528.  
  529.  
  530. /******************************************************************************
  531.  *                    LEACH INTUITION EVENT PROCESSOR
  532.  * This routine is a more conventional message processor for the Status 
  533.  * Display Window. We're expecting only Close Window and Gadget events
  534.  * at the moment.
  535.  *
  536.  ******************************************************************************/
  537.  
  538. stat_event()
  539. {
  540.  
  541. ULONG            class;        /* Class of IntuiMessage.                    */
  542. USHORT            code;        /* Code of IntuiMessage & MenuItem number.    */
  543. struct    Gadget    *gad_addr;    /* Address of toggled gadget.                */
  544.  
  545. struct    IntuiMessage    *message;
  546.  
  547. while ( message = (struct IntuiMessage *) GetMsg(StatWind->UserPort) )
  548. {
  549.     class      = message->Class;
  550.     code       = message->Code;
  551.     mx         = message->MouseX;
  552.     my         = message->MouseY;
  553.     gad_addr = (struct Gadget *) message->IAddress;
  554.     
  555.     ReplyMsg(message);
  556.  
  557.     if (class == CLOSEWINDOW)
  558.     {
  559.         cleanup(206);
  560.     }
  561.     else if (class == GADGETUP)
  562.     {
  563.         /*******************  Toggle the SHOW/HIDE" Gadget ?  ***************/
  564.  
  565.         if (gad_addr == &SHOWGAD)            /* If the show/hide gadget    */
  566.         {
  567.             /*  If ruler just got deselected enter hide mode.    */
  568.             if (! (SHOWGAD.Flags & SELECTED) )
  569.             {
  570.                 hide_ruler();
  571.             }
  572.             else
  573.             {
  574.                 /*----------------------------------------------------------*
  575.                  * S/H has just changed to show mode. Change displayed text
  576.                  * Draw ruler. Make sure that M/F gadget is enabled
  577.                  *----------------------------------------------------------*/
  578.  
  579.                 swap_gtext(gad_addr);
  580.                 draw_line(HostRPort, ruler_color, endpoints[x1], endpoints[y1],
  581.                                                   endpoints[x2], endpoints[y2]);
  582.                 OnGadget(&MOVEGAD, StatWind, NULL);
  583.             }
  584.         } /*  end of if (gad_addr == &SHOWGAD)  */
  585.  
  586.  
  587.         /************* Toggled the "MOVE/FREEZE" Gadget ?  *****************/
  588.  
  589.         else if (gad_addr == &MOVEGAD)
  590.         {
  591.             swap_gtext(&MOVEGAD);
  592.  
  593.             if (MOVEGAD.Flags & SELECTED)    /* Entering move mode.    */
  594.             {
  595.                 /* Enable selectbutton reports.    */
  596.                 HostIDCMPmods |= MOUSEBUTTONS;
  597.                 ModifyIDCMP(HostWind, HostIDCMPflags | HostIDCMPmods);
  598.                 set_pointer();
  599.             }
  600.             else    /* Entering freeze mode. Text = "Move" */
  601.             {
  602.                 HostIDCMPmods &= ~(MOUSEBUTTONS | MOUSEMOVE);
  603.                 ModifyIDCMP(HostWind, HostIDCMPflags | HostIDCMPmods);
  604.                 restore_pointer();
  605.             }
  606.         }
  607.         else if (gad_addr == &swind_gad[2])        /* If the left color gadget    */
  608.         {
  609.             if (SHOWGAD.Flags & SELECTED)    /*  If ruler is visible...    */
  610.             {
  611.                 restore_line();
  612.                 --ruler_color;
  613.                 draw_line(HostRPort, ruler_color, endpoints[x1], endpoints[y1],
  614.                                                   endpoints[x2], endpoints[y2]);
  615.             }
  616.         }
  617.         else if (gad_addr == &swind_gad[3])        /* If the rite color gadget    */
  618.         {
  619.             if (SHOWGAD.Flags & SELECTED)    /*  If ruler is visible...    */
  620.             {
  621.                 restore_line();
  622.                 ++ruler_color;
  623.                 draw_line(HostRPort, ruler_color, endpoints[x1], endpoints[y1],
  624.                                                   endpoints[x2], endpoints[y2]);
  625.             }
  626.         }
  627.         else
  628.         {
  629.             puts("Leach received a funny gadget address.");
  630.         }
  631.  
  632.         RefreshGadgets(swind_gad, StatWind, NULL);
  633.  
  634.     } /*  end of else if (class == GADGETUP)  */
  635.  
  636.     else if (class == REFRESHWINDOW) /* Shouldn't get any of these,    */
  637.     {                                 /* but what the Hell.            */
  638.         BeginRefresh(StatWind);
  639.         EndRefresh(StatWind, TRUE);        
  640.         update_status();
  641.         RefreshGadgets(swind_gad, StatWind, NULL);
  642.         update = 0;
  643.     }
  644.     else
  645.     {
  646.         puts("stat_event(): Received unexpected Msg class.");
  647.     }
  648. } /*  end of while (message = etc.)  */
  649.  
  650. return;
  651.  
  652. } /*  End of stat_event()  */
  653.  
  654.  
  655. /**************************************************************************
  656.  * Restore the mn_ReplyPort address in a message returned by the Host and
  657.  * forward to Intuition.
  658.  **************************************************************************/
  659.  
  660. myport_event()
  661. {
  662. struct    IntuiMessage    *msg;
  663.  
  664. while ( msg = (struct IntuiMessage *) GetMsg(MyPort) )
  665. {
  666.     if (HostIPort)
  667.     {
  668.         msg->ExecMessage.mn_ReplyPort = HostIPort;
  669.         ReplyMsg(msg);
  670.     }
  671.     else
  672.         puts("MYPORT_EVENT(): Trouble in River City.");
  673. }
  674. return;
  675.  
  676. } /*  End of myport_event()  */
  677.  
  678.  
  679. /**************************************************************************
  680.  * Exchange gadget IntuiText text pointer with gadget's UserData pointer
  681.  * which, in this case, points to the alternate text string.
  682.  **************************************************************************/
  683.  
  684. swap_gtext(gad_addr)
  685. struct Gadget    *gad_addr;
  686. {
  687.  
  688. UBYTE *itext;    /* Temp storage for alternate text pointer during swap.    */
  689.  
  690. itext                         = gad_addr->UserData;
  691. gad_addr->UserData             = gad_addr->GadgetText->IText;
  692. gad_addr->GadgetText->IText = itext;
  693.  
  694. return;
  695.  
  696. } /*  End of swap_gtext()  */
  697.  
  698. /*********************  END OF EVENT.C FOR LEACH PROGRAM  *********************/
  699.