home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga Shareware Floppies / ma15.dms / ma15.adf / Yak / Source / main.c < prev    next >
C/C++ Source or Header  |  1993-05-17  |  9KB  |  389 lines

  1. /*
  2.  * Yak version 1.5
  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, 9/92.
  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 <proto/exec.h>
  31. #include <proto/dos.h>
  32. #include <proto/graphics.h>
  33. #include <proto/commodities.h>
  34. #include <proto/intuition.h>
  35. #include <proto/reqtools.h>
  36. #include <proto/locale.h>
  37. #include <string.h>
  38. #include <stdarg.h>
  39.  
  40. #include "yak.h"
  41. #include "hotkey_types.h"
  42. #include "beep.h"
  43. #include "icon.h"
  44. #include "version.h"
  45.  
  46. #include "WB2CLI.h"    /* we'll be a shell process */
  47. #define DEF_CURRENTDIR    "SYS:"
  48.  
  49. /* local prototypes for main.c */
  50. static void CloseResources(void);
  51. static BOOL OpenResources(void);
  52. static void FreePatterns(void);
  53. static LONG ProcessMsg(void);
  54. void __main(void);
  55.  
  56. #ifdef __SASC_60    /* save some bytes */
  57. void _MemCleanup(void){}
  58. #else
  59. void MemCleanup(void){}
  60. #endif
  61.  
  62. /* global data - library bases and the like */
  63. extern struct WBStartup *_WBenchMsg;
  64. struct Library    *CxBase, *IconBase,
  65.         *GadToolsBase, *LayersBase,
  66.         *WorkbenchBase, *LocaleBase;
  67. struct IntuitionBase *IntuitionBase;
  68. struct GfxBase *GfxBase;
  69. struct Locale *locale;
  70. struct MsgPort *broker_mp;
  71. CxObj *broker;
  72. char *PopKeyStr;
  73. #define POPKEY_EVENT    1L    /* cannot clash with YHK event... */
  74.  
  75. char *versionstr="\0$VER: "VERSION_NAME;
  76.  
  77. struct NewBroker newbroker = {
  78.     NB_VERSION,
  79.     "Yak",           /* string to identify this broker */
  80.     VERSION_STR,
  81.     "Multi-purpose commodity",
  82.     NBU_UNIQUE | NBU_NOTIFY,      /* Don't want any new commodities
  83.                                    * starting with this name.  If someone
  84.                                    * tries it, let me know */
  85.     COF_SHOW_HIDE
  86. };
  87.  
  88. ULONG        wndsigflag;        /* here for overlay purposes */
  89. ULONG        cxsigflag;
  90. ULONG        invariantsigflag;
  91. BYTE        palette_count;        /* how many palettes are open */
  92.  
  93. /* from handler.c */
  94. extern ULONG    clicksigflag, intuiopsigflag;
  95. extern void (*intui_routine)(APTR);    /* for intui_op's */
  96. extern APTR intui_parameter;
  97.  
  98. /* from icon.c */
  99. extern ULONG    appsigflag;
  100.  
  101. /* close what we opened */
  102. static void
  103. CloseResources()
  104. {
  105.     if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  106.     if (GfxBase) CloseLibrary((struct Library *)GfxBase);
  107.     if (CxBase) CloseLibrary(CxBase);
  108.     if (LayersBase) CloseLibrary(LayersBase);
  109.     if (IconBase) CloseLibrary(IconBase);
  110.     if (GadToolsBase) CloseLibrary(GadToolsBase);
  111.     if (WorkbenchBase) CloseLibrary(WorkbenchBase);
  112.     if (LocaleBase)
  113.     {
  114.         CloseLocale(locale);
  115.         CloseLibrary(LocaleBase);
  116.     }
  117. }
  118.  
  119. /* open libraries, devices that we need */
  120. static BOOL
  121. OpenResources()
  122. {
  123.     if ((IntuitionBase = (void *)OpenLibrary("intuition.library", 37L)) &&
  124.         (GfxBase = (void *)OpenLibrary("graphics.library", 37L)) &&
  125.         (CxBase = OpenLibrary("commodities.library", 37L)) &&
  126.         (LayersBase = OpenLibrary("layers.library", 37L)) &&
  127.         (IconBase = OpenLibrary("icon.library", 37L)) &&
  128.         (GadToolsBase = OpenLibrary("gadtools.library", 37L)) &&
  129.         (WorkbenchBase = OpenLibrary("workbench.library", 37L)))
  130.         {
  131.         if (LocaleBase = OpenLibrary("locale.library", 38L))
  132.             if (!(locale = OpenLocale(NULL)))
  133.             {
  134.                 PostError("No locale set!");
  135.                 CloseLibrary(LocaleBase);
  136.                 LocaleBase = NULL;
  137.             }
  138.  
  139.         return TRUE;
  140.     }
  141.     CloseResources();
  142.     return FALSE;
  143. }
  144.  
  145. /* simple requester with args */
  146. void
  147. PostError(char *body, ... )
  148. {
  149.     struct EasyStruct es;
  150.     va_list args;
  151.  
  152.     if (!IntuitionBase)
  153.     {
  154.         Write(Output(), "Need AmigaDos 2.0+\n", -1);
  155.         return;
  156.     }
  157.  
  158.     /* setup the argument array */
  159.     va_start( args, body );
  160.  
  161.     /* initialise the structure */
  162.     es.es_StructSize = sizeof(struct EasyStruct);
  163.     es.es_Flags = 0L;
  164.     es.es_Title = "Yak Message";
  165.     es.es_TextFormat = body;
  166.     es.es_GadgetFormat = "OK";
  167.  
  168.     /* display the requester */
  169.     EasyRequestArgs(NULL, &es, NULL, args);
  170.  
  171.     /* free the arguments */
  172.     va_end( args );
  173. }
  174.  
  175. /* parse pattern, report errors */
  176. BOOL __regargs
  177. InitPattern(char *newpatstr, UWORD n)
  178. {
  179.     char *patstr = newpatstr ? newpatstr : patterns[n].patstr;
  180.     char *pat;
  181.     LONG len;
  182.  
  183.     if (pat = AllocVec(len = strlen(patstr)*3+10, MEMF_CLEAR))
  184.     {
  185.         if (ParsePattern(patstr, pat, len) != -1)
  186.         {
  187.             if (newpatstr) strncpy(patterns[n].patstr, newpatstr, PATLEN);
  188.             if (patterns[n].pat) FreeVec(patterns[n].pat);
  189.             patterns[n].pat = pat;
  190.             return TRUE;
  191.         }
  192.         PostError("Error parsing pattern:\n\"%s\"", patstr);
  193.         FreeVec(pat);
  194.     }
  195.     else PostError("Allocation error");
  196.     return FALSE;
  197. }
  198.  
  199. static void
  200. FreePatterns()
  201. {
  202.     UWORD i;
  203.  
  204.     for (i = 0; i < NUM_PATTERNS; i++)
  205.         if (patterns[i].pat) FreeVec(patterns[i].pat);
  206. }
  207.  
  208. void
  209. __main()        /* Yak: multi-function commodity */
  210. {
  211.     BPTR    newdir = NULL, olddir;
  212.  
  213.     if (OpenResources())
  214.     {
  215.         if (broker_mp = CreateMsgPort())
  216.             {
  217.                 newbroker.nb_Port = broker_mp;
  218.                 cxsigflag = 1L << broker_mp->mp_SigBit;
  219.  
  220.         /* process tool-types */
  221.         GetOurIcon(_WBenchMsg);
  222.                 newbroker.nb_Pri = (BYTE)TTInt("CX_PRIORITY", 0);
  223.  
  224.         if (_WBenchMsg)
  225.         {
  226.             if (newdir = Lock(DEF_CURRENTDIR, ACCESS_READ))
  227.                 olddir = CurrentDir(newdir);
  228.             WB2CLI(_WBenchMsg,4000,DOSBase);        /* get it over with... */
  229.         }
  230.  
  231.         if (broker = CxBroker(&newbroker, NULL))
  232.                 {
  233.             /* HANDLER FIRST, SO IT SEES EVERYTHING!!! */
  234.             if (InitHandler())
  235.             {
  236.                 InitYakHotKeyList();
  237.                 LoadSettings();
  238.  
  239.                 if (PopKeyStr = DupStr(TTString("CX_POPKEY", "Rcommand help")))
  240.                 {
  241.                     CxObj *tmpobj;
  242.  
  243.                     if (tmpobj = HotKey(PopKeyStr, broker_mp, POPKEY_EVENT))
  244.                         AttachCxObj(broker, tmpobj);
  245.                     else
  246.                         PostError("CX_POPKEY definition invalid:\"%s\"", PopKeyStr);
  247.                 }
  248.                 /* else... if this failed, we lose */
  249.  
  250.                 MyPri(ACTIVE);
  251.                 ActivateCxObj(broker, 1L);
  252.  
  253.                 if (TTBool("CX_POPUP", FALSE))
  254.                     ShowWindow();
  255.  
  256.                 if (TTBool("APPICON", FALSE))
  257.                 {
  258.                     if (!MakeOurAppIcon(TTString("ICONNAME", "Yak!")))
  259.                         if (_WBenchMsg)
  260.                             PostError("Couldn't create AppIcon");
  261.                 }
  262.                 /* WB makes a copy of icon, so can free it */
  263.                 FreeOurIcon();
  264.  
  265.                 /* these are the signals waited for, + window sig */
  266.                 invariantsigflag = SIGBREAKF_CTRL_C | cxsigflag
  267.                            | clicksigflag | intuiopsigflag
  268.                            | appsigflag;
  269.  
  270.                 while (ProcessMsg())
  271.                     ;
  272.                 HideWindow();
  273.                 RemoveOurAppIcon();
  274.                 DeleteYakHotKeyList();
  275.                 FreeStr(PopKeyStr);
  276.                 MyPri(ORIGINAL);
  277.  
  278.                 EndHandler();
  279.                 FreePatterns();
  280.             }
  281.             else PostError("Allocation error");
  282.  
  283.                     DeleteCxObjAll(broker);
  284.                 }
  285.  
  286.         if (newdir) {
  287.             CurrentDir(olddir);
  288.             UnLock(newdir);
  289.         }
  290.  
  291.                 DeleteMsgPort(broker_mp);
  292.         FreeOurIcon();    /* may already be gone, but so what? */
  293.             }
  294.         else PostError("Allocation error");
  295.  
  296.         CloseResources();
  297.     }
  298.     else PostError("Resource error");
  299. }
  300.  
  301. /* monitor cx port, act on messages */
  302. static LONG
  303. ProcessMsg(void)
  304. {
  305.     CxMsg *msg;
  306.     ULONG sigrcvd, msgid, msgtype;
  307.     LONG returnvalue = 1L;
  308.  
  309.     sigrcvd = Wait(invariantsigflag | wndsigflag);
  310.  
  311.     if (sigrcvd & intuiopsigflag)        /* intuiop requested */
  312.     intui_routine(intui_parameter);
  313.  
  314.     if ((sigrcvd & clicksigflag) && click_volume)    /* keyclick please */
  315.     {
  316.     beep(click_volume);
  317.         Delay(1);   /* avoid ugly sound when key repeating */
  318.     }
  319.  
  320.     if (sigrcvd & appsigflag)        /* settings change */
  321.     {
  322.     RespondToAppIcon();
  323.     ShowWindow();
  324.     }
  325.  
  326.     if (sigrcvd & wndsigflag)        /* settings change */
  327.         if (HandleIDCMP() != HELP_OKAY)
  328.         returnvalue = 0;
  329.     else if (!wndsigflag)        /* window gone */
  330.         DummyOverlay();        /* remove code */
  331.  
  332.     while(msg = (CxMsg *)GetMsg(broker_mp))
  333.     {
  334.         msgid = CxMsgID(msg);
  335.         msgtype = CxMsgType(msg);
  336.         ReplyMsg((struct Message *)msg);
  337.  
  338.         switch(msgtype)
  339.         {
  340.             case CXM_IEVENT:
  341.  
  342.         if (msgid == POPKEY_EVENT)
  343.             ShowWindow();
  344.         else
  345.             /* a generic hotkey... */
  346.             PerformAction((YakHotKey *)msgid);
  347.         break;
  348.  
  349.             case CXM_COMMAND:
  350.                 switch(msgid)
  351.                 {
  352.                     case CXCMD_UNIQUE:
  353.             case CXCMD_APPEAR:
  354.             ShowWindow();    /* check error return? */
  355.             break;
  356.  
  357.             case CXCMD_DISAPPEAR:
  358.             HideWindow();
  359.             DummyOverlay();
  360.             break;
  361.  
  362.                     case CXCMD_DISABLE:
  363.                         ActivateCxObj(broker, 0L);
  364.                         break;
  365.  
  366.                     case CXCMD_ENABLE:
  367.                         ActivateCxObj(broker, 1L);
  368.                         break;
  369.  
  370.                     case CXCMD_KILL:
  371.                         returnvalue = 0L;
  372.                         break;
  373.                 }
  374.                 break;
  375.         }
  376.     }
  377.  
  378.     if (sigrcvd & SIGBREAKF_CTRL_C)
  379.         returnvalue = 0L;
  380.  
  381.     if (!returnvalue && !OkayToExit())
  382.     {
  383.     PostError("Cannot exit yet:\npalette(s) remain open");
  384.     returnvalue = 1;
  385.     }
  386.     
  387.     return(returnvalue);
  388. }
  389.