home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / util / yak-1.59.lha / Yak-1.59 / Src / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  13.4 KB  |  493 lines

  1. /*
  2.  * Yak version 1.58
  3.  * ----------------
  4.  * [Yak == Yet Another K(?)ommodity
  5.  *
  6.  * There seems to be a profusion of commodities doing this or that.
  7.  * Heres mine, to do what I want it to:
  8.  *
  9.  *      AutoActivate windows (SunMouse)
  10.  *      ClickToFront, ClickToBack, ScreenCycle
  11.  *      Close/Zip/Shrink/Zoom/Turn a window via keyboard.
  12.  *      Bring up a palette on front screen.
  13.  *      Insert date into read-stream.
  14.  *      Produce key-click (like my keyclick program).
  15.  *      Some other things...
  16.  *
  17.  * Martin W. Scott & GaĆ«l Marziou, 8/93.
  18.  */
  19. #include <exec/types.h>
  20. #include <exec/libraries.h>
  21. #include <exec/memory.h>
  22. #include <devices/inputevent.h>
  23. #include <dos/dos.h>
  24. #include <dos/dostags.h>
  25. #include <graphics/displayinfo.h>
  26. #include <libraries/commodities.h>
  27. #include <libraries/reqtools.h>
  28. #include <libraries/locale.h>
  29. #include <intuition/intuitionbase.h>
  30. #include <clib/alib_protos.h>
  31. #include <clib/exec_protos.h>
  32. #include <clib/dos_protos.h>
  33. #include <clib/graphics_protos.h>
  34. #include <clib/commodities_protos.h>
  35. #include <clib/intuition_protos.h>
  36. #include <clib/locale_protos.h>
  37. #include <clib/reqtools_protos.h>
  38.  
  39. #ifdef __SASC
  40. #  include <pragmas/exec_pragmas.h>
  41. #  include <pragmas/dos_pragmas.h>
  42. #  include <pragmas/graphics_pragmas.h>
  43. #  include <pragmas/commodities_pragmas.h>
  44. #  include <pragmas/intuition_pragmas.h>
  45. #  include <pragmas/locale_pragmas.h>
  46. #  include <pragmas/reqtools.h>
  47. #else
  48. #  include <proto/exec.h>
  49. #  include <proto/dos.h>
  50. #  include <proto/graphics.h>
  51. #  include <proto/commodities.h>
  52. #  include <proto/intuition.h>
  53. #  include <proto/locale.h>
  54. #  include <proto/reqtools.h>
  55. extern struct Library *DOSBase;
  56. #endif
  57.  
  58.  
  59. #include <string.h>
  60. #include <stdarg.h>
  61.  
  62. #include "code.h"
  63. #include "yak.h"
  64. #include "hotkey_types.h"
  65. #include "beep.h"
  66. #include "icon.h"
  67. #include "version.h"
  68.  
  69. #define CATCOMP_BLOCK
  70. #define CATCOMP_NUMBERS
  71. #include "locale/yak_locale_strings.h"
  72. #undef CATCOMP_BLOCK
  73.  
  74. #include "WB2CLI.h"     /* we'll be a shell process */
  75. #define DEF_CURRENTDIR  "SYS:"
  76.  
  77.  
  78.  
  79. /* local prototypes for main.c */
  80. static void CloseResources(void);
  81. static BOOL OpenResources(void);
  82. static void FreePatterns(void);
  83. static LONG ProcessMsg(void);
  84. void MAIN(void);
  85.  
  86. LONG (*HandleIDCMP)(void);
  87.  
  88. extern struct WBStartup *WBMsg;
  89. /*
  90.  *  libraries opened by startup code; basepointers needed by function pragmas
  91.  */
  92. extern struct Library *SysBase, *DOSBase;
  93.  
  94. /* global data - library bases and the like */
  95. struct Library  *CxBase, *IconBase,
  96.                 *GadToolsBase, *LayersBase,
  97.                 *WorkbenchBase, *LocaleBase,
  98.                 *GfxBase, *IntuitionBase,
  99.                 *KeymapBase;
  100. struct Locale *locale;
  101. struct Catalog *Catalog;
  102. struct MsgPort *broker_mp;
  103. CxObj *broker;
  104. char *PopKeyStr;
  105. #define POPKEY_EVENT    1L      /* cannot clash with YHK event... */
  106.  
  107. static const char *versionstr=VERSION_STR;
  108.  
  109. struct NewBroker newbroker = {
  110.     NB_VERSION,
  111.     "Yak",                                              /* string to identify this broker */
  112.     VERSION_BROKER,
  113.     "Multi-purpose commodity",
  114.     NBU_UNIQUE | NBU_NOTIFY,    /* Don't want any new commodities
  115.                                  * starting with this name.  If someone
  116.                                  * tries it, let me know */
  117.     COF_SHOW_HIDE
  118. };
  119.  
  120. ULONG           wndsigflag;             /* here for overlay purposes */
  121. ULONG           cxsigflag;
  122. ULONG           invariantsigflag;
  123. BYTE            palette_count;          /* how many palettes are open */
  124.  
  125. /* from handler.c */
  126. extern ULONG    clicksigflag, intuiopsigflag;
  127. extern void (*intui_routine)(APTR);     /* for intui_op's */
  128. extern APTR intui_parameter;
  129.  
  130.  
  131. /* from icon.c */
  132. extern ULONG    appsigflag;
  133.  
  134. /* close what we opened */
  135. static void
  136. CloseResources()
  137. {
  138.         /* NULL pointers are valide so don't waste time to test them */
  139.         CloseLibrary(IntuitionBase);
  140.         CloseLibrary(GfxBase);
  141.         CloseLibrary(CxBase);
  142.         CloseLibrary(LayersBase);
  143.         CloseLibrary(IconBase);
  144.         CloseLibrary(GadToolsBase);
  145.         CloseLibrary(WorkbenchBase);
  146.         CloseLibrary(KeymapBase);
  147.         if (LocaleBase)
  148.         {
  149.                 CloseCatalog (Catalog); 
  150.                 CloseLocale(locale);
  151.                 CloseLibrary(LocaleBase);
  152.         }
  153. }
  154.  
  155. /* open libraries, devices that we need */
  156. static BOOL
  157. OpenResources(void)
  158. {
  159.         if ((IntuitionBase = OpenLibrary("intuition.library", 37L)) &&
  160.             (GfxBase       = OpenLibrary("graphics.library", 37L)) &&
  161.             (CxBase        = OpenLibrary("commodities.library", 37L)) &&
  162.             (LayersBase    = OpenLibrary("layers.library", 37L)) &&
  163.             (IconBase      = OpenLibrary("icon.library", 37L)) &&
  164.             (GadToolsBase  = OpenLibrary("gadtools.library", 37L)) &&
  165.             (WorkbenchBase = OpenLibrary("workbench.library", 37L)) &&
  166.             (KeymapBase    = OpenLibrary("keymap.library", 37L)))
  167.         {
  168.                 return TRUE;
  169.         }
  170.         CloseResources();
  171.         return FALSE;
  172. }
  173.  
  174.  
  175. /* open locale library and catalog */
  176. void
  177. OpenLocaleStuff(char *language)
  178. {
  179.  
  180.         if (LocaleBase =(struct LocaleBase *)OpenLibrary("locale.library", 38L))
  181.         {
  182.                 if (!(locale = OpenLocale(NULL)))
  183.                 {       
  184.                         PostError("No locale set!");
  185.                         CloseLibrary(LocaleBase);
  186.                         LocaleBase = NULL;
  187.                 }
  188.                 Catalog = OpenCatalog(  locale, "yak.catalog", 
  189.                                                           OC_BuiltInLanguage, "english", 
  190.                                                           OC_Language, language,        
  191.                                                           OC_Version, 15L, 
  192.                                                           TAG_DONE );
  193.         }       
  194. }
  195.  
  196.  
  197. /* slighlty modified version of GetString() generated by catcomp */
  198.  
  199. char *getString(ULONG MsgID)
  200. {
  201. LONG   *l;
  202. UWORD  *w;
  203. char *builtIn;
  204.  
  205.    l = (LONG *)CatCompBlock;
  206.  
  207.    while (*l != MsgID )
  208.    {
  209.            w = (UWORD *)((ULONG)l + 4);
  210.            l = (LONG *)((ULONG)l + (ULONG)*w + 6);
  211.    }
  212.    builtIn = (char *)((ULONG)l + 6);
  213.    if (LocaleBase)
  214.            return (GetCatalogStr (Catalog, MsgID, builtIn));
  215.    return(builtIn);
  216. }
  217.  
  218. /* simple requester with args */
  219. void
  220. PostError(char *body, ... )
  221. {
  222.         struct EasyStruct es;
  223.         va_list args;
  224.  
  225.         if (!IntuitionBase)
  226.         {
  227.                 Write(Output(), "Need AmigaDos 2.0+\n", -1);
  228.                 return;
  229.         }
  230.  
  231.         /* setup the argument array */
  232.         va_start( args, body );
  233.  
  234.         /* initialise the structure */
  235.         es.es_StructSize = sizeof(struct EasyStruct);
  236.         es.es_Flags = 0L;
  237.         es.es_Title = getString(Error_Requester_Title);
  238.         es.es_TextFormat = body;
  239.         es.es_GadgetFormat = "OK";
  240.  
  241.         /* display the requester */
  242.         EasyRequestArgs(NULL, &es, NULL, args);
  243.  
  244.         /* free the arguments */
  245.         va_end( args );
  246. }
  247.  
  248. /* parse pattern, report errors */
  249. __regargs BOOL
  250. InitPattern(char *newpatstr, UWORD n)
  251. {
  252.         char *patstr = newpatstr ? newpatstr : patterns[n].patstr;
  253.         char *pat;
  254.         LONG len;
  255.  
  256.         if (pat = AllocVec(len = strlen(patstr)*3+10, MEMF_CLEAR))
  257.         {
  258.                 if (ParsePattern(patstr, pat, len) != -1)
  259.                 {
  260.                         if (newpatstr) strncpy(patterns[n].patstr, newpatstr, PATLEN);
  261.                         if (patterns[n].pat) FreeVec(patterns[n].pat);
  262.                         patterns[n].pat = pat;
  263.                         return TRUE;
  264.                 }
  265.                 
  266.                 PostError("%s:\n\"%s\"", getString(Parsing_Pattern_ERR), patstr);
  267.                 FreeVec(pat);
  268.         }
  269.         else PostError(getString(Allocation_ERR));
  270.         return FALSE;
  271. }
  272.  
  273. static void
  274. FreePatterns()
  275. {
  276.         UWORD i;
  277.  
  278.         for (i = 0; i < NUM_PATTERNS; i++)
  279.                 if (patterns[i].pat) FreeVec(patterns[i].pat);
  280. }
  281.  
  282.  
  283. #ifdef _DCC
  284. void _waitwbmsg(void);
  285. static void
  286. uncalled(void)
  287. {
  288.     _waitwbmsg();
  289. }
  290. #endif
  291.  
  292.  
  293.  
  294. void 
  295. MAIN()             /* Yak: multi-function commodity */
  296. {
  297.     BPTR    newdir = NULL, olddir;
  298.  
  299.     if (OpenResources())
  300.     {
  301.         if (broker_mp = CreateMsgPort())
  302.         {
  303.             newbroker.nb_Port = broker_mp;
  304.             cxsigflag = 1L << broker_mp->mp_SigBit;
  305.  
  306.             /* process tool-types */
  307.             GetOurIcon(WBMsg);
  308.             newbroker.nb_Pri = (BYTE)TTInt("CX_PRIORITY", 0);
  309.  
  310.             if (WBMsg)
  311.             {
  312.                 if (newdir = Lock(DEF_CURRENTDIR, ACCESS_READ))
  313.                     olddir = CurrentDir(newdir);
  314.                 WB2CLI(WBMsg,4000,(struct DosLibrary *)DOSBase); /* get it over with... */
  315.             }
  316.  
  317.             if (broker = CxBroker(&newbroker, NULL))
  318.             {
  319.                 /* HANDLER FIRST, SO IT SEES EVERYTHING!!! */
  320.                 if (InitHandler())
  321.                 {       
  322.                     InitYakHotKeyList();
  323.                     LoadSettings();
  324.                                         
  325.                     /* Open the right locale if tooltype LANGUAGE is used */
  326.                     OpenLocaleStuff(TTString("LANGUAGE",NULL));
  327.  
  328.                     if (PopKeyStr = DupStr(TTString("CX_POPKEY", "Rcommand help")))
  329.                     {
  330.                         CxObj *tmpobj;
  331.                                         
  332.                         if (tmpobj = HotKey(PopKeyStr, broker_mp, POPKEY_EVENT))
  333.                             AttachCxObj(broker, tmpobj);
  334.                         else
  335.                             PostError("%s:\"%s\"", getString(CX_POPKEY_invalid_ERR), 
  336.                                       PopKeyStr);
  337.                     }
  338.                     /* else... if this failed, we lose */
  339.  
  340.                     MyPri(ACTIVE);
  341.                     ActivateCxObj(broker, 1L);
  342.  
  343.                     if (TTBool("CX_POPUP", FALSE))
  344.                         ShowYakInterface();
  345.  
  346.                     if (TTBool("APPICON", FALSE))
  347.                     {
  348.                         if (!MakeOurAppIcon(TTString("ICONNAME", "Yak!")))
  349.                             if (WBMsg)
  350.                                 PostError(getString(Couldn_t_create_AppIcon_ERR));
  351.                     }
  352.                     /* WB makes a copy of icon, so can free it */
  353.                     FreeOurIcon();
  354.  
  355.                     /* these are the signals waited for, + window sig */
  356.                     invariantsigflag = SIGBREAKF_CTRL_C | cxsigflag
  357.                         | clicksigflag | intuiopsigflag
  358.                             | appsigflag;
  359.  
  360.                     while (ProcessMsg())
  361.                         ;
  362.                     HideInterface();
  363.                     RemoveOurAppIcon();
  364.                     DeleteYakHotKeyList();
  365.  
  366.                     FreeStr(PopKeyStr);
  367.                     MyPri(ORIGINAL);
  368.  
  369.                     EndHandler();
  370.                     FreePatterns();
  371.                 }
  372.                 else 
  373.                     PostError(getString(Allocation_ERR));
  374.         
  375.                 DeleteCxObjAll(broker);
  376.             }
  377.  
  378.             if (newdir) 
  379.             {
  380.                 CurrentDir(olddir);
  381.                 UnLock(newdir);
  382.             }
  383.             DeleteMsgPort(broker_mp);
  384.             FreeOurIcon();      /* may already be gone, but so what? */
  385.         }
  386.         else PostError(getString(Allocation_ERR));
  387.  
  388.         CloseResources();
  389.         MWReport("At end of main()", MWR_FULL); /* Generate a memory usage report */
  390.     }
  391.     else PostError(getString(Resource_ERR));
  392. }
  393.  
  394.  
  395.  
  396.  
  397. /* monitor cx port, act on messages */
  398. static LONG
  399. ProcessMsg(void)
  400. {
  401.     CxMsg *msg;
  402.     ULONG sigrcvd, msgid, msgtype;
  403.     LONG returnvalue = 1L;
  404.  
  405.     sigrcvd = Wait(invariantsigflag | wndsigflag);
  406.  
  407.     if (sigrcvd & intuiopsigflag) 
  408.     {       
  409.         /* intuiop requested */
  410.         intui_routine(intui_parameter);
  411.     }
  412.  
  413.  
  414.     if ((sigrcvd & clicksigflag) && click_volume) /* keyclick please */
  415.     {
  416.         beep(click_volume);
  417.         Delay(1);               /* avoid ugly sound when key repeating */
  418.     }
  419.  
  420.     if (sigrcvd & appsigflag)   /* settings change */
  421.     {
  422.         RespondToAppIcon();
  423.         ShowYakInterface();
  424.     }
  425.  
  426.     if (sigrcvd & wndsigflag)   /* settings change */
  427.         if ((*HandleIDCMP)() != ROOT_OKAY)
  428.             returnvalue = 0;
  429.         else 
  430.             if (!wndsigflag)    /* window gone */
  431.                 DummyOverlay(); 
  432.     /* remove code */
  433.  
  434.     while(msg = (CxMsg *)GetMsg(broker_mp))
  435.     {
  436.         msgid = CxMsgID(msg);
  437.         msgtype = CxMsgType(msg);
  438.         ReplyMsg((struct Message *)msg);
  439.  
  440.         switch(msgtype)
  441.         {
  442.           case CXM_IEVENT:
  443.  
  444.             if (msgid == POPKEY_EVENT)
  445.                 ShowYakInterface();
  446.             else
  447.                 /* a generic hotkey... */
  448.                 PerformAction((YakHotKey *)msgid);
  449.             break;
  450.  
  451.           case CXM_COMMAND:
  452.             switch(msgid)
  453.             {
  454.               case CXCMD_UNIQUE:
  455.               case CXCMD_APPEAR:
  456.                 ShowYakInterface(); /* check error return? */
  457.                 break;
  458.  
  459.               case CXCMD_DISAPPEAR:
  460.                 HideInterface();
  461.                 DummyOverlay();
  462.                 break;
  463.  
  464.               case CXCMD_DISABLE:
  465.                 ActivateCxObj(broker, 0L);
  466.                 TurnMouseOn();
  467.                 break;
  468.  
  469.               case CXCMD_ENABLE:
  470.                 ActivateCxObj(broker, 1L);
  471.                 break;
  472.  
  473.               case CXCMD_KILL:
  474.                 returnvalue = 0L;
  475.                 break;
  476.             }
  477.             break;
  478.         }
  479.     }
  480.  
  481.     if (sigrcvd & SIGBREAKF_CTRL_C)
  482.         returnvalue = 0L;
  483.  
  484.     if (!returnvalue && !OkayToExit())
  485.     {
  486.         PostError(getString(Cannot_exit_palette_opened_ERR));
  487.         returnvalue = 1;
  488.     }
  489.     
  490.     return(returnvalue);
  491. }
  492.  
  493.