home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 19 / AACD19.BIN / AACD / System / SnoopDos / SnoopDos_Src / SnoopDos_Source / hotkey.c < prev    next >
C/C++ Source or Header  |  2001-02-04  |  18KB  |  504 lines

  1. /*
  2.  *              HOTKEY.C                                                                                                vi:ts=4
  3.  *
  4.  *      Copyright (c) Eddy Carroll, September 1994.
  5.  *      Updated by Thomas Richter, THOR, 5.3.2000
  6.  *
  7.  *              Controls the management of the commodities hotkey for SnoopDos,
  8.  *              along with other related stuff (Workbench AppIcon/Tools Menu support).
  9.  */
  10.  
  11. #include "system.h"
  12. #include "snoopdos.h"
  13. #include "snooptext.h"
  14.  
  15. #include "icon.h"
  16.  
  17. extern char CommodityTitle[];   /* From SNOOPDOS.C */
  18.  
  19. struct NewBroker MyBroker = {
  20.         NB_VERSION,
  21.         "SnoopDos",
  22.         CommodityTitle,
  23.         NULL,                                           /* Description, filled in at run time */
  24.         NBU_UNIQUE | NBU_NOTIFY,
  25.         COF_SHOW_HIDE,
  26.         0, 0, 0
  27. };
  28.  
  29. struct MsgPort          *BrokerMP;              /* Message port used for msgs from CX   */
  30. CxObj                           *Broker;                /* CX handle for the broker we created  */
  31. CxObj                           *Filter;                /* Filter to filter CX messages                 */
  32. struct MsgPort          *WorkbenchPort; /* Port for AppIcon/AppMenu messages    */
  33. struct DiskObject       *ProgramIcon;   /* Handle on our program's icon data    */
  34. struct AppMenuItem      *MyAppMenu;             /* Current AppMenuItem, if any                  */
  35. struct AppIcon          *MyAppIcon;             /* Current AppMenuItem, if any                  */
  36. struct DiskObject       *AppIconObj;    /* Current object for AppMenuItem               */      
  37. struct DiskObject       *DefIconObj;    /* A temporary default icon we use              */      
  38.  
  39. /*
  40.  *              InstallHotKey(char *hotkey)
  41.  *
  42.  *              Initialises commodity support and sets things up so that the
  43.  *              key sequence specified by "hotkey" will send a CTRL-F activation
  44.  *              signal to SnoopDos. We can also get various messages from the
  45.  *              commodities exchange to show/hide the interface etc -- these
  46.  *              will be indicated using CommodityMask.
  47.  *
  48.  *              To see whether a hotkey is currently available or not, simply
  49.  *              check the HotKeyActive flag. (This is used for disabling window
  50.  *              gadgets etc.)
  51.  *
  52.  *              Returns true for success, false for failure.
  53.  */
  54. int InstallHotKey(char *hotkey)
  55. {
  56.         CxObj *newobj;
  57.  
  58.         HotKeyActive = 0;               /* Assume commodity is not currently active */
  59.  
  60.         if (CurSettings.Setup.HideMethod == HIDE_NONE || !CxBase) {
  61.                 /*
  62.                  *              Don't install a commodity at all if we have no hide
  63.                  *              method.
  64.                  */
  65.                 return (0);
  66.         }
  67.         if (!BrokerMP) {
  68.                 BrokerMP = CreateMsgPort();
  69.                 if (!BrokerMP)
  70.                         return (0);
  71.                 CommodityMask     = (1L << BrokerMP->mp_SigBit);
  72.         }
  73.  
  74.         if (Broker && MyBroker.nb_Pri != CommodityPriority) {
  75.                 /*
  76.                  *              The commodity priority has changed, so 
  77.                  *              remove the current broker to force a new
  78.                  *              one to be created at the correct priority.
  79.                  */
  80.                 DeleteCxObjAll(Broker);
  81.                 Broker = NULL;
  82.                 Filter = NULL;
  83.         }
  84.         if (!Broker) {
  85.                 /*
  86.                  *              Attempt to create a new broker
  87.                  */
  88.                 MyBroker.nb_Descr = MSG(MSG_COMMODITY_DESC);
  89.                 MyBroker.nb_Port  = BrokerMP;
  90.                 MyBroker.nb_Pri   = CommodityPriority;
  91.                 Broker = CxBroker(&MyBroker, NULL);
  92.                 if (!Broker)
  93.                         return (0);
  94.                 ActivateCxObj(Broker, 1);
  95.         }
  96.         /*
  97.          *              Okay, now we create a new filter object to handle the
  98.          *              commodity string we were passed
  99.          */
  100.         if (Filter)
  101.                 DeleteCxObjAll(Filter);
  102.         
  103.         Filter = CxFilter(hotkey);
  104.         if (!Filter) {
  105.                 /*
  106.                  *              Couldn't create the filter (probably out of memory --
  107.                  *              specifying an illegal hotkey doesn't cause this to
  108.                  *              fail, but instead produces an accumulated error later).
  109.                  *
  110.                  *              We still leave the broker itself installed, since it can
  111.                  *              be used to allow the CX to send us Enable/Disable/Show/
  112.                  *              Hide/Quit messages.
  113.                  */
  114.                 return (0);
  115.         }
  116.  
  117.         /*
  118.          *              Now add our various translation bits and pieces to the filter
  119.          */
  120.         newobj = CxSignal(SysBase->ThisTask, SIGBREAKB_CTRL_F);
  121.         if (!newobj)
  122.                 goto filter_error;
  123.         AttachCxObj(Filter, newobj);
  124.  
  125.         newobj = CxTranslate(NULL);
  126.         if (!newobj)
  127.                 goto filter_error;
  128.         AttachCxObj(Filter, newobj);
  129.  
  130.         if (CxObjError(Filter))
  131.                 goto filter_error;
  132.  
  133.         AttachCxObj(Broker, Filter);
  134.         HotKeyActive = 1;       /* Everything went okay so show we're active */
  135.         return (1);
  136.  
  137. filter_error:
  138.         DeleteCxObjAll(Filter);
  139.         Filter = NULL;
  140.         return (NULL);
  141. }
  142.  
  143. /*
  144.  *              HandleHotKey()
  145.  *
  146.  *              Handles any incoming messages on the commodities exchange port.
  147.  *              Should be called whenever a CommodityMask signal is received.
  148.  */
  149. void HandleHotKeyMsgs(void)
  150. {
  151.         CxMsg *msg;
  152.  
  153.         if (!BrokerMP)
  154.                 return;
  155.  
  156.         while ((msg = (CxMsg *)GetMsg(BrokerMP)) != NULL) {
  157.                 ULONG msgid             = CxMsgID(msg);
  158.                 ULONG msgtype   = CxMsgType(msg);
  159.  
  160.                 ReplyMsg((void *)msg);
  161.                 if (msgtype == CXM_COMMAND) {
  162.                         switch (msgid) {
  163.                                 
  164.                                 case CXCMD_DISABLE:
  165.                                         SetMonitorMode(MONITOR_DISABLED);
  166.                                         break;
  167.  
  168.                                 case CXCMD_ENABLE:
  169.                                         if (Disabled)   /* Don't want to enable if Paused */
  170.                                                 SetMonitorMode(MONITOR_NORMAL);
  171.                                         break;
  172.  
  173.                                 case CXCMD_KILL:
  174.                                         QuitFlag = 1;
  175.                                         break;
  176.  
  177.                                 case CXCMD_APPEAR:
  178.                                 case CXCMD_UNIQUE:
  179.                                         ShowSnoopDos();
  180.                                         break;
  181.  
  182.                                 case CXCMD_DISAPPEAR:
  183.                                         HideSnoopDos();
  184.                                         break;
  185.                         }
  186.                 }
  187.         }
  188. }
  189.  
  190. /*
  191.  *              CleanupHotKey()
  192.  *
  193.  *              Frees any resources used by the commodities module
  194.  */
  195. void CleanupHotKey(void)
  196. {
  197.         if (Broker) {
  198.                 DeleteCxObjAll(Broker);
  199.                 Broker = NULL;
  200.                 Filter = NULL;
  201.         }
  202.         if (BrokerMP) {
  203.                 struct Message *msg;
  204.                 while ((msg = GetMsg(BrokerMP)) != NULL)
  205.                         ReplyMsg(msg);
  206.                 DeleteMsgPort(BrokerMP);
  207.                 BrokerMP          = NULL;
  208.                 CommodityMask = 0;
  209.         }
  210.         HotKeyActive = 0;
  211. }
  212.  
  213. /*
  214.  *              GetCommandName()
  215.  *
  216.  *              Returns a pointer to a static string containing the name of
  217.  *              this program. The pointer remains valid until the next call
  218.  *              to this function.
  219.  */
  220. char *GetCommandName(void)
  221. {
  222.         static char name[200];
  223.         struct Process *pr = (struct Process *)SysBase->ThisTask;
  224.         struct CommandLineInterface *cli = BTOC(pr->pr_CLI);
  225.         char *cmdname = (char *)BTOC(cli->cli_CommandName);
  226.  
  227.         if (WBenchMsg)
  228.                 return (WBenchMsg->sm_ArgList->wa_Name);
  229.         
  230.         memcpy(name, cmdname+1, *cmdname);
  231.         name[*cmdname] = '\0';
  232.         return (name);
  233. }
  234.  
  235. /*
  236.  *              GetProgramIcon()
  237.  *
  238.  *              Returns a pointer to an icon structure containing a program
  239.  *              icon for SnoopDos, as follows:
  240.  *
  241.  *                      If SnoopDos was run from Workbench, we have a lock on it
  242.  *                      If SnoopDos was run from CLI, we look in the directory
  243.  *                      the program was run from. If we can't find it there, then
  244.  *                      we give up and use the default SnoopDos icon image.
  245.  *
  246.  *              Regardless, you should call CleanupIcons() before exiting,
  247.  *              to free up any loose icon images that may have been allocated.
  248.  *
  249.  *              Warning: icon.library must be open when you call this function.
  250.  */
  251. struct DiskObject *GetProgramIcon(void)
  252. {
  253.         if (ProgramIcon)
  254.                 return (ProgramIcon);
  255.         
  256.         if (WBenchMsg) {
  257.                 /*
  258.                  *              Running from Workbench, so try and get the program icon
  259.                  *              indicated in the lock
  260.                  */
  261.                 struct WBArg *wbarg = WBenchMsg->sm_ArgList;
  262.                 BPTR lk;
  263.  
  264.                 lk          = CurrentDir(wbarg->wa_Lock);
  265.                 ProgramIcon = GetDiskObject(wbarg->wa_Name);
  266.                 CurrentDir(lk);
  267.         } else {
  268.                 /*
  269.                  *              Running from CLI so try and get icon associated with executable
  270.                  */
  271.                 struct Process *pr = (struct Process *)SysBase->ThisTask;
  272.                 BPTR lk;
  273.  
  274.                 if (pr->pr_HomeDir)     
  275.                         lk = CurrentDir(pr->pr_HomeDir);
  276.                 ProgramIcon = GetDiskObject(GetCommandName());
  277.                 if (pr->pr_HomeDir)
  278.                         CurrentDir(lk);
  279.         }
  280.         if (ProgramIcon)
  281.                 return (ProgramIcon);
  282.         
  283.         /*
  284.          *              Okay, unfortunately we couldn't locate the program icon, so
  285.          *              instead, let's just fall back to the default icon.
  286.          */
  287.         DefSnoopDosIcon.do_StackSize = MINSTACKSIZE;    /* Fix this up here */
  288.         return (&DefSnoopDosIcon);
  289. }
  290.  
  291. /*
  292.  *              CleanupIcons()
  293.  *
  294.  *              Frees any icon-related resources that were allocated
  295.  */
  296. void CleanupIcons(void)
  297. {
  298.         RemoveProgramFromWorkbench();
  299.         if (ProgramIcon) {
  300.                 FreeDiskObject(ProgramIcon);
  301.                 ProgramIcon = NULL;
  302.         }
  303.         if (DefIconObj) {
  304.                 FreeDiskObject(DefIconObj);
  305.                 DefIconObj = NULL;
  306.                 AppIconObj = NULL;
  307.         }
  308.         if (WorkbenchPort) {
  309.                 struct Message *msg;
  310.  
  311.                 while ((msg = GetMsg(WorkbenchPort)) != NULL)
  312.                         ReplyMsg(msg);
  313.  
  314.                 DeleteMsgPort(WorkbenchPort),
  315.                 WorkbenchPort = NULL;
  316.                 WorkbenchMask = 0;
  317.         }
  318.         if (WorkbenchBase) {
  319.                 CloseLibrary(WorkbenchBase);
  320.                 WorkbenchBase = NULL;
  321.         }
  322. }
  323.  
  324. /*
  325.  *              WriteIcon(filename)
  326.  *
  327.  *              Writes a SnoopDos project icon to the associated filename. If an
  328.  *              icon already exists for the filename, then that icon is left alone.
  329.  *
  330.  *              If no icon exists, then we create one using a copy of what we think
  331.  *              is the icon SnoopDos was started from (or the default).
  332.  */
  333. void WriteIcon(char *filename)
  334. {
  335.         struct DiskObject newobj;
  336.         struct DiskObject *dobj;
  337.  
  338.         if (!IconBase)
  339.                 return;
  340.         
  341.         dobj = GetDiskObject(filename);
  342.         if (dobj) {
  343.                 FreeDiskObject(dobj);
  344.                 return;
  345.         }
  346.         dobj = GetProgramIcon();
  347.  
  348.         /*
  349.          *              We can create a copy of our tool icon and change
  350.          *              it to a project icon.
  351.          */
  352.         newobj = *dobj;
  353.         newobj.do_CurrentX      = NO_ICON_POSITION;
  354.         newobj.do_CurrentY      = NO_ICON_POSITION;
  355.         newobj.do_ToolTypes     = DefToolTypes;
  356.         newobj.do_Type                  = WBPROJECT;
  357.         if (WBenchMsg)
  358.                 newobj.do_DefaultTool = WBenchMsg->sm_ArgList->wa_Name;
  359.         else
  360.                 newobj.do_DefaultTool = GetCommandName();
  361.         PutDiskObject(filename, &newobj);
  362. }
  363.  
  364. /*
  365.  *              AddProgramToWorkbench(hidetype)
  366.  *
  367.  *              Creates an AppIcon or AppMenuItem which can be used to re-active
  368.  *              SnoopDos, and attaches it to Workbench. Normally used when
  369.  *              SnoopDos goes into a HIDE state.
  370.  *
  371.  *              Hidetype is HIDE_ICON or HIDE_TOOLS, depending on which type of
  372.  *              hide method is required.
  373.  *
  374.  *              Initialises WorkbenchMask accordingly.
  375.  *
  376.  *              Call RemoveProgramFromWorkbench() to remove the item later on.
  377.  *
  378.  *              Returns TRUE for success, FALSE for failure.
  379.  */
  380. int AddProgramToWorkbench(int hidetype)
  381. {
  382.         if (!IconBase)
  383.                 return (FALSE);
  384.  
  385.         if (!WorkbenchBase) {
  386.                 WorkbenchBase = OpenLibrary("workbench.library", 37);
  387.                 if (!WorkbenchBase)
  388.                         return (FALSE);
  389.         }
  390.         if (!WorkbenchPort) {
  391.                 WorkbenchPort = CreateMsgPort();
  392.                 if (!WorkbenchPort)
  393.                         return (FALSE);
  394.                 WorkbenchMask = (1 << WorkbenchPort->mp_SigBit);
  395.         }
  396.         if (hidetype == HIDE_TOOLS && !MyAppMenu) {
  397.                 /*
  398.                  *              Adding an item to the Workbench tools menu
  399.                  */
  400.                 MyAppMenu = AddAppMenuItem(0, 0, MSG(MSG_APPMENU_NAME),
  401.                                                                    WorkbenchPort, NULL);
  402.                 if (!MyAppMenu)
  403.                         return (FALSE);
  404.         }
  405.         if (hidetype == HIDE_ICON && !MyAppIcon) {
  406.                 /*
  407.                  *              Adding an AppIcon to the Workbench. We make a copy
  408.                  *              of the current program icon to use as our appicon.
  409.                  */
  410.                 struct DiskObject *dobj;
  411.  
  412.                 if (!AppIconObj) {
  413.                         /*
  414.                          *              We need a temporary icon to play around with.
  415.                          *              We allocate a new default disk object, copy
  416.                          *              it, and modify our copy to give us an icon
  417.                          *              we can use as an AppIcon. We need to remember
  418.                          *              to free the original icon before we exit.
  419.                          */
  420.  
  421.                          /*             The following is not really required. We operate
  422.                           *             directly on the program icon instead, and release
  423.                           *             this icon.
  424.                           *             THOR, 5.4.2000
  425.                         static struct DiskObject defobj;
  426.                                 
  427.                         DefIconObj = GetDefDiskObject(WBTOOL);
  428.                         if (!DefIconObj)
  429.                                 return (FALSE);
  430.  
  431.                         defobj     = *DefIconObj;
  432.                         AppIconObj = &defobj;
  433.                           *
  434.                           */
  435.  
  436.                         dobj       = GetProgramIcon();
  437.                           /* Note that this call can't fail. In worst case, we
  438.                            * get the default icon.
  439.                            *
  440.                            */
  441.  
  442.                           /*
  443.                            * Removed again. THOR, 5.3.2000
  444.                            *
  445.                         AppIconObj->do_Gadget.Width                     = dobj->do_Gadget.Width;
  446.                         AppIconObj->do_Gadget.Height            = dobj->do_Gadget.Height;
  447.                         AppIconObj->do_Gadget.Flags                     = dobj->do_Gadget.Flags;
  448.                         AppIconObj->do_Gadget.GadgetRender      = dobj->do_Gadget.GadgetRender;
  449.                         AppIconObj->do_Gadget.SelectRender      = dobj->do_Gadget.SelectRender;
  450.                         AppIconObj->do_Type                             = 0;
  451.                            *
  452.                            */
  453.  
  454.                         AppIconObj = dobj;
  455.                 }
  456.                 AppIconObj->do_CurrentX = CurSettings.IconPosLeft != -1 ?
  457.                                                                   CurSettings.IconPosLeft :
  458.                                                                   NO_ICON_POSITION;
  459.                 AppIconObj->do_CurrentY = CurSettings.IconPosTop != -1 ?
  460.                                                                   CurSettings.IconPosTop :
  461.                                                                   NO_ICON_POSITION;
  462.                 MyAppIcon = AddAppIcon(0, 0, APPICON_NAME, WorkbenchPort,
  463.                                                            NULL, AppIconObj, TAG_DONE);
  464.                 if (!MyAppIcon)
  465.                         return (FALSE);
  466.         }
  467.         return (TRUE);
  468. }
  469.  
  470. /*
  471.  *              RemoveProgramFromWorkbench()
  472.  *
  473.  *              Removes any AppIcon or AppMenuItem item that is currently installed
  474.  *              on Workbench. Usually called when the SnoopDos window is about
  475.  *              about to reappear.
  476.  */
  477. void RemoveProgramFromWorkbench(void)
  478. {
  479.         if (MyAppMenu)          RemoveAppMenuItem(MyAppMenu),   MyAppMenu = NULL;
  480.         if (MyAppIcon)          RemoveAppIcon(MyAppIcon),       MyAppIcon = NULL;
  481. }
  482.  
  483. /*
  484.  *              HandleWorkbenchMsgs()
  485.  *
  486.  *              Handles any outstanding messages at the Workbench message port
  487.  */
  488. void HandleWorkbenchMsgs(void)
  489. {
  490.         struct AppMessage *msg;
  491.         int show = 0;
  492.  
  493.         if (!WorkbenchPort)
  494.                 return;
  495.         
  496.         while ((msg = (void *)GetMsg(WorkbenchPort)) != NULL) {
  497.                 show = 1;
  498.                 ReplyMsg(msg);
  499.         }
  500.         if (show)
  501.                 ShowSnoopDos();
  502. }
  503.  
  504.