home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / util / snoopdos-3.0.lha / SnoopDos / Source / hotkey.c < prev    next >
C/C++ Source or Header  |  1994-09-17  |  12KB  |  483 lines

  1. /*
  2.  *        HOTKEY.C                                                vi:ts=4
  3.  *
  4.  *      Copyright (c) Eddy Carroll, September 1994.
  5.  *
  6.  *        Controls the management of the commodities hotkey for SnoopDos,
  7.  *        along with other related stuff (Workbench AppIcon/Tools Menu support).
  8.  */
  9.  
  10. #include "system.h"
  11. #include "snoopdos.h"
  12. #include "snooptext.h"
  13.  
  14. #include "icon.h"
  15.  
  16. extern char CommodityTitle[];    /* From SNOOPDOS.C */
  17.  
  18. struct NewBroker MyBroker = {
  19.     NB_VERSION,
  20.     "SnoopDos",
  21.     CommodityTitle,
  22.     NULL,                        /* Description, filled in at run time */
  23.     NBU_UNIQUE | NBU_NOTIFY,
  24.     COF_SHOW_HIDE,
  25.     0, 0, 0
  26. };
  27.  
  28. struct MsgPort        *BrokerMP;        /* Message port used for msgs from CX    */
  29. CxObj                *Broker;        /* CX handle for the broker we created    */
  30. CxObj                *Filter;        /* Filter to filter CX messages            */
  31. struct MsgPort        *WorkbenchPort;    /* Port for AppIcon/AppMenu messages    */
  32. struct DiskObject    *ProgramIcon;    /* Handle on our program's icon data    */
  33. struct AppMenuItem    *MyAppMenu;        /* Current AppMenuItem, if any            */
  34. struct AppIcon        *MyAppIcon;        /* Current AppMenuItem, if any            */
  35. struct DiskObject    *AppIconObj;    /* Current object for AppMenuItem        */    
  36. struct DiskObject    *DefIconObj;    /* A temporary default icon we use        */    
  37.  
  38. /*
  39.  *        InstallHotKey(char *hotkey)
  40.  *
  41.  *        Initialises commodity support and sets things up so that the
  42.  *        key sequence specified by "hotkey" will send a CTRL-F activation
  43.  *        signal to SnoopDos. We can also get various messages from the
  44.  *        commodities exchange to show/hide the interface etc -- these
  45.  *        will be indicated using CommodityMask.
  46.  *
  47.  *        To see whether a hotkey is currently available or not, simply
  48.  *        check the HotKeyActive flag. (This is used for disabling window
  49.  *        gadgets etc.)
  50.  *
  51.  *        Returns true for success, false for failure.
  52.  */
  53. int InstallHotKey(char *hotkey)
  54. {
  55.     CxObj *newobj;
  56.  
  57.     HotKeyActive = 0;        /* Assume commodity is not currently active */
  58.  
  59.     if (CurSettings.Setup.HideMethod == HIDE_NONE || !CxBase) {
  60.         /*
  61.          *        Don't install a commodity at all if we have no hide
  62.          *        method.
  63.          */
  64.         return (0);
  65.     }
  66.     if (!BrokerMP) {
  67.         BrokerMP = CreateMsgPort();
  68.         if (!BrokerMP)
  69.             return (0);
  70.         CommodityMask      = (1L << BrokerMP->mp_SigBit);
  71.     }
  72.  
  73.     if (Broker && MyBroker.nb_Pri != CommodityPriority) {
  74.         /*
  75.          *        The commodity priority has changed, so 
  76.          *        remove the current broker to force a new
  77.          *        one to be created at the correct priority.
  78.          */
  79.         DeleteCxObjAll(Broker);
  80.         Broker = NULL;
  81.         Filter = NULL;
  82.     }
  83.     if (!Broker) {
  84.         /*
  85.          *        Attempt to create a new broker
  86.          */
  87.         MyBroker.nb_Descr = MSG(MSG_COMMODITY_DESC);
  88.         MyBroker.nb_Port  = BrokerMP;
  89.         MyBroker.nb_Pri   = CommodityPriority;
  90.         Broker = CxBroker(&MyBroker, NULL);
  91.         if (!Broker)
  92.             return (0);
  93.         ActivateCxObj(Broker, 1);
  94.     }
  95.     /*
  96.      *        Okay, now we create a new filter object to handle the
  97.      *        commodity string we were passed
  98.      */
  99.     if (Filter)
  100.         DeleteCxObjAll(Filter);
  101.     
  102.     Filter = CxFilter(hotkey);
  103.     if (!Filter) {
  104.         /*
  105.          *        Couldn't create the filter (probably out of memory --
  106.          *        specifying an illegal hotkey doesn't cause this to
  107.          *        fail, but instead produces an accumulated error later).
  108.          *
  109.          *        We still leave the broker itself installed, since it can
  110.          *        be used to allow the CX to send us Enable/Disable/Show/
  111.          *        Hide/Quit messages.
  112.          */
  113.         return (0);
  114.     }
  115.  
  116.     /*
  117.      *        Now add our various translation bits and pieces to the filter
  118.      */
  119.     newobj = CxSignal(SysBase->ThisTask, SIGBREAKB_CTRL_F);
  120.     if (!newobj)
  121.         goto filter_error;
  122.     AttachCxObj(Filter, newobj);
  123.  
  124.     newobj = CxTranslate(NULL);
  125.     if (!newobj)
  126.         goto filter_error;
  127.     AttachCxObj(Filter, newobj);
  128.  
  129.     if (CxObjError(Filter))
  130.         goto filter_error;
  131.  
  132.     AttachCxObj(Broker, Filter);
  133.     HotKeyActive = 1;    /* Everything went okay so show we're active */
  134.     return (1);
  135.  
  136. filter_error:
  137.     DeleteCxObjAll(Filter);
  138.     Filter = NULL;
  139.     return (NULL);
  140. }
  141.  
  142. /*
  143.  *        HandleHotKey()
  144.  *
  145.  *        Handles any incoming messages on the commodities exchange port.
  146.  *        Should be called whenever a CommodityMask signal is received.
  147.  */
  148. void HandleHotKeyMsgs(void)
  149. {
  150.     CxMsg *msg;
  151.  
  152.     if (!BrokerMP)
  153.         return;
  154.  
  155.     while ((msg = (CxMsg *)GetMsg(BrokerMP)) != NULL) {
  156.         ULONG msgid        = CxMsgID(msg);
  157.         ULONG msgtype    = CxMsgType(msg);
  158.  
  159.         ReplyMsg((void *)msg);
  160.         if (msgtype == CXM_COMMAND) {
  161.             switch (msgid) {
  162.                 
  163.                 case CXCMD_DISABLE:
  164.                     SetMonitorMode(MONITOR_DISABLED);
  165.                     break;
  166.  
  167.                 case CXCMD_ENABLE:
  168.                     if (Disabled)    /* Don't want to enable if Paused */
  169.                         SetMonitorMode(MONITOR_NORMAL);
  170.                     break;
  171.  
  172.                 case CXCMD_KILL:
  173.                     QuitFlag = 1;
  174.                     break;
  175.  
  176.                 case CXCMD_APPEAR:
  177.                 case CXCMD_UNIQUE:
  178.                     ShowSnoopDos();
  179.                     break;
  180.  
  181.                 case CXCMD_DISAPPEAR:
  182.                     HideSnoopDos();
  183.                     break;
  184.             }
  185.         }
  186.     }
  187. }
  188.  
  189. /*
  190.  *        CleanupHotKey()
  191.  *
  192.  *        Frees any resources used by the commodities module
  193.  */
  194. void CleanupHotKey(void)
  195. {
  196.     if (Broker) {
  197.         DeleteCxObjAll(Broker);
  198.         Broker = NULL;
  199.         Filter = NULL;
  200.     }
  201.     if (BrokerMP) {
  202.         struct Message *msg;
  203.         while ((msg = GetMsg(BrokerMP)) != NULL)
  204.             ReplyMsg(msg);
  205.         DeleteMsgPort(BrokerMP);
  206.         BrokerMP      = NULL;
  207.         CommodityMask = 0;
  208.     }
  209.     HotKeyActive = 0;
  210. }
  211.  
  212. /*
  213.  *        GetCommandName()
  214.  *
  215.  *        Returns a pointer to a static string containing the name of
  216.  *        this program. The pointer remains valid until the next call
  217.  *        to this function.
  218.  */
  219. char *GetCommandName(void)
  220. {
  221.     static char name[200];
  222.     struct Process *pr = (struct Process *)SysBase->ThisTask;
  223.     struct CommandLineInterface *cli = BTOC(pr->pr_CLI);
  224.     char *cmdname = (char *)BTOC(cli->cli_CommandName);
  225.  
  226.     if (WBenchMsg)
  227.         return (WBenchMsg->sm_ArgList->wa_Name);
  228.     
  229.     memcpy(name, cmdname+1, *cmdname);
  230.     name[*cmdname] = '\0';
  231.     return (name);
  232. }
  233.  
  234. /*
  235.  *        GetProgramIcon()
  236.  *
  237.  *        Returns a pointer to an icon structure containing a program
  238.  *        icon for SnoopDos, as follows:
  239.  *
  240.  *            If SnoopDos was run from Workbench, we have a lock on it
  241.  *            If SnoopDos was run from CLI, we look in the directory
  242.  *            the program was run from. If we can't find it there, then
  243.  *            we give up and use the default SnoopDos icon image.
  244.  *
  245.  *        Regardless, you should call CleanupIcons() before exiting,
  246.  *        to free up any loose icon images that may have been allocated.
  247.  *
  248.  *        Warning: icon.library must be open when you call this function.
  249.  */
  250. struct DiskObject *GetProgramIcon(void)
  251. {
  252.     if (ProgramIcon)
  253.         return (ProgramIcon);
  254.     
  255.     if (WBenchMsg) {
  256.         /*
  257.          *        Running from Workbench, so try and get the program icon
  258.          *        indicated in the lock
  259.          */
  260.         struct WBArg *wbarg = WBenchMsg->sm_ArgList;
  261.         BPTR lk;
  262.  
  263.         lk          = CurrentDir(wbarg->wa_Lock);
  264.         ProgramIcon = GetDiskObject(wbarg->wa_Name);
  265.         CurrentDir(lk);
  266.     } else {
  267.         /*
  268.          *        Running from CLI so try and get icon associated with executable
  269.          */
  270.         struct Process *pr = (struct Process *)SysBase->ThisTask;
  271.         BPTR lk;
  272.  
  273.         if (pr->pr_HomeDir)    
  274.             lk = CurrentDir(pr->pr_HomeDir);
  275.         ProgramIcon = GetDiskObject(GetCommandName());
  276.         if (pr->pr_HomeDir)
  277.             CurrentDir(lk);
  278.     }
  279.     if (ProgramIcon)
  280.         return (ProgramIcon);
  281.     
  282.     /*
  283.      *        Okay, unfortunately we couldn't locate the program icon, so
  284.      *        instead, let's just fall back to the default icon.
  285.      */
  286.     DefSnoopDosIcon.do_StackSize = MINSTACKSIZE;    /* Fix this up here */
  287.     return (&DefSnoopDosIcon);
  288. }
  289.  
  290. /*
  291.  *        CleanupIcons()
  292.  *
  293.  *        Frees any icon-related resources that were allocated
  294.  */
  295. void CleanupIcons(void)
  296. {
  297.     RemoveProgramFromWorkbench();
  298.     if (ProgramIcon) {
  299.         FreeDiskObject(ProgramIcon);
  300.         ProgramIcon = NULL;
  301.     }
  302.     if (DefIconObj) {
  303.         FreeDiskObject(DefIconObj);
  304.         DefIconObj = NULL;
  305.         AppIconObj = NULL;
  306.     }
  307.     if (WorkbenchPort) {
  308.         struct Message *msg;
  309.  
  310.         while ((msg = GetMsg(WorkbenchPort)) != NULL)
  311.             ReplyMsg(msg);
  312.  
  313.         DeleteMsgPort(WorkbenchPort),
  314.         WorkbenchPort = NULL;
  315.         WorkbenchMask = 0;
  316.     }
  317.     if (WorkbenchBase) {
  318.         CloseLibrary(WorkbenchBase);
  319.         WorkbenchBase = NULL;
  320.     }
  321. }
  322.  
  323. /*
  324.  *        WriteIcon(filename)
  325.  *
  326.  *        Writes a SnoopDos project icon to the associated filename. If an
  327.  *        icon already exists for the filename, then that icon is left alone.
  328.  *
  329.  *        If no icon exists, then we create one using a copy of what we think
  330.  *        is the icon SnoopDos was started from (or the default).
  331.  */
  332. void WriteIcon(char *filename)
  333. {
  334.     struct DiskObject newobj;
  335.     struct DiskObject *dobj;
  336.  
  337.     if (!IconBase)
  338.         return;
  339.     
  340.     dobj = GetDiskObject(filename);
  341.     if (dobj) {
  342.         FreeDiskObject(dobj);
  343.         return;
  344.     }
  345.     dobj = Ge