home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / utility / misc / dropmenu.lha / DropMenu.c next >
Encoding:
C/C++ Source or Header  |  1992-10-10  |  8.5 KB  |  349 lines

  1. /*****************************************************************************/
  2. /*                          DropMenu - Drop Down Menu Commodity              */
  3. /*                                                                           */
  4. /*                    Public Domain - Written 1992 by Paul Wilkinson         */
  5. /*                         See DropMenu.doc for more information             */
  6. /*                                                                           */
  7. /*                    Contact the author at:                                 */
  8. /*                                  24 Armstrong Ave                         */
  9. /*                                  Mt. Warrigal NSW                         */
  10. /*                                  2528                                     */
  11. /*                                  Australia                                */
  12. /*                                                                           */
  13. /*****************************************************************************/
  14.  
  15. #include "DropMenu.h"           /* Get all the support thingies */
  16.  
  17. main(int argc,char *argv[])
  18. {
  19.     int rc;
  20.  
  21.     if ((rc=Initialise(argc,argv)) == 0) /* Initialise everything */
  22.     {
  23.         Process();              /* If all OK then do main processing */
  24.  
  25.     }
  26.     else
  27.     {
  28.         if (rc > 1)
  29.             EasyRequest(NULL,&TerminalRQ,NULL,errortxt[rc]); /* Complain if did not initialise */
  30.     }
  31.  
  32.     CloseAll();                 /* Clean everything up */
  33.  
  34. }
  35.  
  36. /*
  37.  * Initialise - Initialise everything necessary for DropMenu.
  38.  * Returns 0 if all OK otherwise returns fail code.
  39.  */
  40. long Initialise(int argc,char *argv[])
  41. {
  42.  
  43.     LONG error;
  44.  
  45.     UBYTE *pop;
  46.     int rc=0;
  47.  
  48.     UBYTE **ToolTypes=NULL;
  49.  
  50.     IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37);
  51.  
  52.     if (!IntuitionBase)
  53.             return(1);
  54.  
  55.     CxBase = (struct CxBase *)OpenLibrary("commodities.library",37);
  56.  
  57.     if (!CxBase)
  58.             return(2);
  59.  
  60.     IconBase = (struct IconBase *)OpenLibrary("icon.library",36);
  61.  
  62.     if (!IconBase)
  63.             return(3);
  64.  
  65.     ToolTypes = ArgArrayInit(argc,(UBYTE **)argv);
  66.  
  67.     if (!SetupCx(ToolTypes,&error))
  68.     {
  69.         if (error==CBERR_DUP)   /* Duplicate, not an error, but do not allow */
  70.             return(-1);         /* initialisation to complete */
  71.         else
  72.             return(4);
  73.     }
  74.  
  75.     ArgArrayDone();
  76.  
  77.     stdout=Output();
  78.  
  79.     return(rc);
  80.  
  81. }
  82.  
  83.  
  84.  
  85. void CloseAll()
  86. {
  87.  
  88.     ShutdownCx();
  89.  
  90.  
  91.     if (IntuitionBase)
  92.         CloseLibrary((struct Library *)IntuitionBase);
  93.  
  94.     if (CxBase)
  95.         CloseLibrary((struct Library *)CxBase);
  96.  
  97.     if (IconBase)
  98.         CloseLibrary((struct Library *)IconBase);
  99.  
  100. }
  101.  
  102.  
  103. void Process()
  104. {
  105.     long SignalSet;
  106.  
  107.     int done=FALSE;
  108.  
  109.     while (!done)
  110.  
  111.     {
  112.  
  113.         SignalSet = (1 << CxPort -> mp_SigBit) | SIGBREAKF_CTRL_C ;
  114.  
  115.         SignalSet = Wait(SignalSet);
  116.  
  117.         /* There are messages pending at the
  118.          * Commodities reply port.
  119.          */
  120.  
  121.         if(SignalSet & (1 << CxPort -> mp_SigBit))
  122.         {
  123.             CxMsg *Message;
  124.  
  125.             while(Message = (CxMsg *)GetMsg(CxPort))
  126.                 done = HandleCxMsg(Message);
  127.         }
  128.  
  129.  
  130.         /* ^C tells the program to quit. */
  131.  
  132.         if(SignalSet & SIGBREAKF_CTRL_C)
  133.                 done = TRUE;
  134.     }
  135.  
  136.  
  137. }
  138.  
  139.  
  140. VOID
  141. ShutdownCx()
  142. {
  143.         if(CxPort)
  144.         {
  145.                 struct Message *Message;
  146.  
  147.                         /* Remove the broker. */
  148.  
  149.                 if(Broker)
  150.                         DeleteCxObjAll(Broker);
  151.  
  152.                         /* Remove the MsgPort from the public list. */
  153.  
  154.                 RemPort(CxPort);
  155.  
  156.                         /* Remove all pending messages. */
  157.  
  158.                 while(Message = GetMsg(CxPort))
  159.                         ReplyMsg(Message);
  160.  
  161.                         /* Delete the MsgPort. */
  162.  
  163.                 DeleteMsgPort(CxPort);
  164.  
  165.                 CxPort = NULL;
  166.                 Broker = NULL;
  167.         }
  168. }
  169.  
  170.         /* SetupCx(UBYTE **ToolTypes):
  171.          *
  172.          *      Set up the Commodities interface.
  173.          */
  174.  
  175. BYTE
  176. SetupCx(UBYTE **ToolTypes,LONG *error)
  177. {
  178.                 /* Cancel any previously made assignments. */
  179.  
  180.         ShutdownCx();
  181.  
  182.                 /* Create a reply port. */
  183.  
  184.         if(CxPort = CreateMsgPort())
  185.         {
  186.                         /* Fill in a unique name. */
  187.  
  188.                 CxPort -> mp_Node . ln_Name = NewBroker . nb_Name;
  189.  
  190.                         /* Add the reply port to the public list. */
  191.  
  192.                 AddPort(CxPort);
  193.  
  194.                         /* Set the Commodity priority if possible. */
  195.  
  196.                         NewBroker . nb_Pri  = ArgInt(ToolTypes,"CX_PRIORITY",0);
  197.                         NewBroker . nb_Port = CxPort;
  198.  
  199.                         /* Create the broker. */
  200.  
  201.                 if(Broker = CxBroker(&NewBroker,error))
  202.                 {
  203.  
  204.                         CxObj   *ObjectList;
  205.  
  206.                                 /* Install the plain InputEvent handler. */
  207.  
  208.                         AttachCxObj(Broker,CxFilter("rawmouse"));
  209.  
  210.                         ObjectList = CxCustom(CXEventHandler,NULL);
  211.  
  212.                                 /* Any accumulated errors? */
  213.  
  214.                         if(!CxObjError(ObjectList))
  215.                         {
  216.                                         /* Add the custom object. */
  217.  
  218.                                 AttachCxObj(Broker,ObjectList);
  219.  
  220.                                         /* Any errors? */
  221.  
  222.                                 if(!CxObjError(Broker))
  223.                                 {
  224.                                                 /* Activate the broker. */
  225.  
  226.                                         ActivateCxObj(Broker,TRUE);
  227.  
  228.                                         return(TRUE);
  229.                                 }
  230.                         }
  231.                 }
  232.         }
  233.  
  234.         ShutdownCx();
  235.  
  236.         return(FALSE);
  237. }
  238.  
  239.         /* HandleCxMsg(CxMsg *Message):
  240.          *
  241.          *      Handle incoming Commodities messages.
  242.          */
  243.  
  244. long
  245. HandleCxMsg(CxMsg *Message)
  246. {
  247.         long done = FALSE;
  248.  
  249.         ULONG MessageType = CxMsgID(Message),MessageID = CxMsgType(Message);
  250.  
  251.         ReplyMsg((struct Message *)Message);
  252.  
  253.                 /* Take a look at the message type. */
  254.  
  255.         switch(MessageID)
  256.         {
  257.                         /* It's a hotkey. */
  258.  
  259.         case CXM_IEVENT:
  260.  
  261.             break;
  262.                         /* It's an internal Commodities command. */
  263.  
  264.            case CXM_COMMAND:
  265.                 switch(MessageType)
  266.                 {
  267.                                                         /* Disable the Commodity. */
  268.                     case CXCMD_DISABLE:
  269.                         Active = FALSE;
  270.                         ActivateCxObj(Broker,FALSE);
  271.                     break;
  272.  
  273.                                                         /* Enable the Commodity. */
  274.                    case CXCMD_ENABLE:
  275.                         Active = TRUE;
  276.                         ActivateCxObj(Broker,TRUE);
  277.                    break;
  278.  
  279.                                                         /* Create the control panel. */
  280.  
  281.                    case CXCMD_APPEAR:
  282.  
  283.                    break;
  284.                                                         /* Close the control panel. */
  285.  
  286.                    case CXCMD_DISAPPEAR:
  287.                    break;
  288.                                                         /* Remove this Commodity. */
  289.  
  290.                     case CXCMD_KILL:
  291.                     case CXCMD_UNIQUE:
  292.                         done=TRUE;
  293.                    break;
  294.                 }
  295.  
  296.             break;
  297.         }
  298.  
  299.     return(done);
  300. }
  301.  
  302.         /* CXEventHandlerAction(CxMsg *CxMessage,CxObj *CxObject):
  303.          *
  304.          *      Commodities support routine, handles the Commodities
  305.          *      custom actions (in this case: filter the InputEvents
  306.          *      coming in and swallow rmb ups every now and then).
  307.          */
  308.  
  309. VOID
  310. CXEventHandler(CxMsg *CxMessage,CxObj *CxObject)
  311. {
  312.  
  313.     struct InputEvent *ie;
  314.  
  315.     int_start();
  316.     
  317.     ie = (struct InputEvent *)CxMsgData(CxMessage);
  318.  
  319.     if ((ie->ie_Class & IECLASS_RAWMOUSE)==IECLASS_RAWMOUSE)
  320.     {
  321.     if ((swallowed) && (ie->ie_X != xpos || ie->ie_Y != ypos))
  322.     {
  323.         swallowed=!swallowed;      /*If mouse moved then don't drop menus */
  324.     }
  325.  
  326.     if ((ie->ie_Code & IECODE_RBUTTON)==IECODE_RBUTTON) /* Is it a RMB? */
  327.     {
  328.         if (ie->ie_Code & IECODE_UP_PREFIX) /* RMB Up? */
  329.         {
  330.         if (swallowed)
  331.         {
  332.             ie->ie_Code = ie->ie_Code & ~(IECODE_UP_PREFIX); /* Kill it if swallowing */
  333.         }
  334.         }
  335.         else
  336.         {
  337.         xpos=ie->ie_X;    /* Save mouse position for later comparison */
  338.         ypos=ie->ie_Y;
  339.         swallowed=!swallowed; /* Otherwise toggle swallowing state */
  340.         }
  341.         
  342.     }
  343.     
  344.     }
  345.    
  346.     int_end();
  347.     
  348. }
  349.