home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / utility / misc / yak.lha / Yak / src / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-17  |  9.5 KB  |  452 lines

  1. /*
  2.  * Yak version 1.0
  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 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/dostags.h>
  24. #include <libraries/commodities.h>
  25. #include <libraries/reqtools.h>
  26. #include <intuition/intuitionbase.h>
  27. #include <dos/dos.h>
  28. #include <proto/exec.h>
  29. #include <proto/dos.h>
  30. #include <proto/commodities.h>
  31. #include <proto/intuition.h>
  32. #include <proto/reqtools.h>
  33. #include <clib/alib_protos.h>
  34. #include <string.h>
  35.  
  36. #include "yak.h"
  37. #include "beep.h"
  38.  
  39.  
  40. struct Library *CxBase, *IconBase, *GadToolsBase, *LayersBase;
  41. struct ReqToolsBase *ReqToolsBase;
  42. struct IntuitionBase *IntuitionBase;
  43. struct MsgPort *broker_mp;
  44. CxObj *broker;
  45.  
  46. struct NewBroker newbroker = {
  47.     NB_VERSION,
  48.     "Yak",           /* string to identify this broker */
  49.     "Yak 1.0  ⌐ 1992, Martin W. Scott",
  50.     "Multi-purpose commodity",
  51.     NBU_UNIQUE | NBU_NOTIFY,      /* Don't want any new commodities
  52.                                    * starting with this name.  If someone
  53.                                    * tries it, let me know */
  54.     COF_SHOW_HIDE
  55. };
  56.  
  57. ULONG        cxsigflag;
  58. extern ULONG    clicksigflag;
  59. extern struct WBStartup *WBenchMsg;
  60.  
  61.  
  62. /* close what we opened */
  63. void
  64. CloseResources()
  65. {
  66.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  67.     if (CxBase) CloseLibrary(CxBase);
  68.     if (LayersBase) CloseLibrary(LayersBase);
  69.     if (IconBase) CloseLibrary(IconBase);
  70.     if (GadToolsBase) CloseLibrary(GadToolsBase);
  71. }
  72.  
  73. /* open libraries, devices that we need */
  74. BOOL
  75. OpenResources()
  76. {
  77.     if ((IntuitionBase = (void *)OpenLibrary("intuition.library", 37L)) &&
  78.         (CxBase = OpenLibrary("commodities.library", 37L)) &&
  79.         (LayersBase = OpenLibrary("layers.library", 37L)) &&
  80.         (IconBase = OpenLibrary("icon.library", 37L)) &&
  81.         (GadToolsBase = OpenLibrary("gadtools.library", 37L)))
  82.         {
  83.         return TRUE;
  84.     }
  85.     CloseResources();
  86.     return FALSE;
  87. }
  88.  
  89. /* pop up a requester */
  90. void
  91. EasyEasyRequest(char *str)
  92. {
  93.     struct EasyStruct es;
  94.  
  95.     es.es_StructSize = sizeof(struct EasyStruct);
  96.     es.es_Flags = 0L;
  97.     es.es_Title = "Yak: ";
  98.     es.es_TextFormat = str;
  99.     es.es_GadgetFormat = "OK";
  100.     EasyRequestArgs(NULL, &es, NULL, NULL);
  101. }
  102.  
  103. /* display an error appropriately */
  104. void
  105. PostError(char *str)
  106. {
  107.     if (IntuitionBase && WBenchMsg)
  108.         EasyEasyRequest(str);
  109.     else
  110.     {
  111.         PutStr("Yak: ");
  112.         PutStr(str);
  113.     }
  114. }
  115.  
  116. /* modify hk array with new hotkey */    
  117. BOOL
  118. AddHotKey(char *newstr, UWORD n)
  119. {
  120.     CxObj *newfilter;
  121.  
  122.     if (newfilter = HotKey(newstr, broker_mp, hk[n].msgid))
  123.     {
  124.         if (hk[n].filter) DeleteCxObjAll(hk[n].filter);
  125.         hk[n].filter = newfilter;
  126.         strncpy(hk[n].key, newstr, MAXKEYLEN);
  127.         AttachCxObj(broker, hk[n].filter);
  128.         return TRUE;
  129.     }
  130.     return FALSE;
  131. }
  132.  
  133. /* simple extension to ArgXXX routines */
  134. BOOL
  135. ArgBool(char **ttypes, char *tt, BOOL def)
  136. {
  137.     char    *s;
  138.  
  139.     s = ArgString(ttypes, tt, def ? "YES" : "NO");
  140.  
  141.     return    ((strcmp(s, "YES") == 0) ||
  142.         (strcmp(s, "TRUE") == 0) ||
  143.         (strcmp(s, "ON") == 0)) ? TRUE : FALSE;
  144. }
  145.  
  146.  
  147. void
  148. main(int argc, char **argv)    /* Yak: multi-function commodity */
  149. {
  150.     char    **ttypes;
  151.  
  152.     if (OpenResources())
  153.     {
  154.         if (broker_mp = CreateMsgPort())
  155.             {
  156.                 newbroker.nb_Port = broker_mp;
  157.                 cxsigflag = 1L << broker_mp->mp_SigBit;
  158.  
  159.         /* process tool-types */
  160.                 ttypes = ArgArrayInit(argc, argv);
  161.  
  162.                 newbroker.nb_Pri = (BYTE)ArgInt(ttypes, "CX_PRIORITY", 0);
  163.  
  164.         if (broker = CxBroker(&newbroker, NULL))
  165.                 {
  166.             if (InitSettings(ttypes))
  167.             {
  168.                 if (InitHandler())
  169.                 {
  170.                     MyPri(ACTIVE);
  171.                     ActivateCxObj(broker, 1L);
  172.  
  173.                     if (ArgBool(ttypes, "CX_POPUP", FALSE))
  174.                         ShowWindow();
  175.  
  176.                     while (ProcessMsg())
  177.                         ;
  178.                     HideWindow();
  179.                     EndHandler();
  180.                     MyPri(ORIGINAL);
  181.                 }
  182.                 else PostError("Allocation error\n");
  183.             }
  184.             else PostError("HotKey definition error\n");
  185.  
  186.                     DeleteCxObjAll(broker);
  187.                 }
  188.  
  189.                 DeletePort(broker_mp);
  190.         ArgArrayDone();
  191.             }
  192.         else PostError("Allocation error\n");
  193.  
  194.         CloseResources();
  195.     }
  196.     else PostError("Resource error\n");
  197. }
  198.  
  199. /* simulate user clicking close-gadget */
  200. void
  201. DoCloseWindow()
  202. {
  203.     struct InputEvent ev;
  204.     struct Window *window;
  205.     ULONG lock;
  206.  
  207.     lock = LockIBase(0);
  208.     window = IntuitionBase->ActiveWindow;
  209.     UnlockIBase(lock);
  210.  
  211.     if (window && (window->IDCMPFlags & CLOSEWINDOW))
  212.     {
  213.         ev.ie_NextEvent = NULL;
  214.         ev.ie_Class = IECLASS_CLOSEWINDOW;
  215.         ev.ie_SubClass = 0;
  216.         ev.ie_Code = 0;
  217.         ev.ie_Qualifier = 0;
  218.         ev.ie_EventAddress = 0;
  219.         AddIEvents(&ev);
  220.     }
  221. }
  222.  
  223. #define AdjustedLeftEdge(w, width)    (w->LeftEdge + width > w->WScreen->Width ? \
  224.                         w->WScreen->Width - width : w->LeftEdge)
  225. #define AdjustedTopEdge(w, height)    (w->TopEdge + height > w->WScreen->Height ? \
  226.                         w->WScreen->Height - height : w->TopEdge)
  227.  
  228. /* zip/enlarge or whatever the currently active window */
  229. void
  230. HandleWindowKey(LONG what)
  231. {
  232.     struct Window *window;
  233.     ULONG lock;
  234.  
  235.     lock = LockIBase(0);
  236.     if (window = IntuitionBase->ActiveWindow)
  237.     {
  238.         switch (what)
  239.         {
  240.         case HK_ZIPKEY:
  241.             if (window->Flags & WFLG_HASZOOM)
  242.                 ZipWindow(window);
  243.             break;
  244.  
  245.         case HK_SHRINKKEY:
  246.             if (window->Flags & WFLG_SIZEGADGET)
  247.                 ChangeWindowBox(window,
  248.                         window->LeftEdge,
  249.                         window->TopEdge,
  250.                         window->MinWidth,
  251.                         window->MinHeight);
  252.             break;
  253.  
  254.         case HK_ZOOMKEY:
  255.         {    /* sometimes Max vars are -1 == NO LIMIT */
  256.             USHORT width, height;
  257.  
  258.             width = window->MaxWidth;
  259.             if (width == -1) width = window->WScreen->Width-width;
  260.             height = window->MaxHeight;
  261.             if (height == -1) height = window->WScreen->Height-height;
  262.             
  263.             if (window->Flags & WFLG_SIZEGADGET)
  264.                 ChangeWindowBox(window,
  265.                         AdjustedLeftEdge(window, width),
  266.                         AdjustedTopEdge(window, height),
  267.                         width,
  268.                         height);
  269.         }
  270.  
  271.         } /* switch */
  272.     }
  273.     UnlockIBase(lock);
  274. }
  275.  
  276. /* write chars in str to input-stream */
  277. void
  278. WriteEvents(char *str)
  279. {
  280.     struct InputEvent ev;
  281.  
  282.     ev.ie_NextEvent = NULL;
  283.     for (; *str; str++)
  284.     {
  285.         InvertKeyMap((ULONG)*str, &ev, NULL);
  286.         AddIEvents(&ev);
  287.     }
  288. }
  289.  
  290. /* bring a palette up on frontmost screen */
  291. void
  292. DoPalette()
  293. {
  294.     if (ReqToolsBase = (void *)OpenLibrary("reqtools.library", 0L))
  295.     {
  296.         (void) rtPaletteRequest("Palette", NULL,
  297.             RT_Screen, IntuitionBase->FirstScreen, TAG_DONE);
  298.  
  299.         CloseLibrary(ReqToolsBase);
  300.     }
  301. }
  302.  
  303. /* insert date as string into read-stream */
  304. void
  305. InsertDate()
  306. {
  307.     char day[LEN_DATSTRING], date[LEN_DATSTRING], time[LEN_DATSTRING];
  308.     struct DateTime dt;
  309.  
  310.     DateStamp(&dt.dat_Stamp);
  311.     dt.dat_Format = datefmt;
  312.     dt.dat_Flags = 0;
  313.     dt.dat_StrDay = day;
  314.     dt.dat_StrDate = date;
  315.     dt.dat_StrTime = time;
  316.     DateToStr(&dt);
  317.  
  318.     if (insday) WriteEvents(day);
  319.     if (insdate) {
  320.         if (insday) WriteEvents(" ");
  321.         WriteEvents(date);
  322.     }
  323.     if (instime) {
  324.         if (insday | insdate) WriteEvents(" ");
  325.         WriteEvents(time);
  326.     }
  327. }
  328.  
  329. /* monitor cx port, act on messages */
  330. LONG
  331. ProcessMsg(void)
  332. {
  333.     CxMsg *msg;
  334.     ULONG sigrcvd, msgid, msgtype;
  335.     LONG returnvalue = 1L;
  336.  
  337.     sigrcvd = Wait(SIGBREAKF_CTRL_C | cxsigflag | clicksigflag | wndsigflag);
  338.  
  339.     if (sigrcvd & clicksigflag)        /* keyclick please */
  340.     {
  341.     beep(click_volume);
  342.     Delay(1);   /* avoid ugly sound when key repeating */
  343.     }
  344.  
  345.     if (sigrcvd & wndsigflag)        /* settings change */
  346.         if (HandleIDCMP() != HELP_OKAY)
  347.         returnvalue = 0;
  348.  
  349.     while(msg = (CxMsg *)GetMsg(broker_mp))
  350.     {
  351.         msgid = CxMsgID(msg);
  352.         msgtype = CxMsgType(msg);
  353.         ReplyMsg((struct Message *)msg);
  354.  
  355.         switch(msgtype)
  356.         {
  357.             case CXM_IEVENT:
  358.                 switch(msgid)
  359.                 {
  360.             case HK_POPKEY:
  361.             ShowWindow();    /* check error return? */
  362.             break;
  363.  
  364.             case HK_CLOSEKEY:
  365.             DoCloseWindow();
  366.             break;
  367.  
  368.             case HK_ZIPKEY:
  369.             case HK_SHRINKKEY:
  370.             case HK_ZOOMKEY:
  371.             HandleWindowKey(msgid);
  372.                         break;
  373.  
  374.             case HK_WORKBENCH:
  375.             {
  376.                 struct Screen *s = LockPubScreen("Workbench");
  377.                 if (s)
  378.                 {
  379.                 struct Window *w = s->FirstWindow;
  380.                 WBenchToFront();
  381.                 Forbid();
  382.                 for (; w; w = w->NextWindow)
  383.                     if (w->Flags & WFLG_WBENCHWINDOW)
  384.                     {
  385.                         ActivateWindow(w);
  386.                         break;
  387.                     }
  388.                 Permit();
  389.                 UnlockPubScreen(NULL, s);
  390.                 }
  391.             }
  392.             break;
  393.                 
  394.             case HK_POPPALKEY:
  395.             DoPalette();
  396.             break;
  397.  
  398.             case HK_INSDATE:
  399.             InsertDate();
  400.             break;
  401.  
  402.             case HK_POPCLI:
  403.             {
  404.                 BPTR nilfh = Open("NIL:", MODE_NEWFILE);
  405.                 struct Screen *s = LockPubScreen(NULL);
  406.                 if (s)
  407.                 {
  408.                 ScreenToFront(s);
  409.                 UnlockPubScreen(NULL, s);
  410.                 }
  411.                 Execute(PopCommand, NULL, nilfh);
  412.                 if (nilfh)
  413.                 Close(nilfh);
  414.             }
  415.             break;            
  416.                 }
  417.                 break;
  418.  
  419.             case CXM_COMMAND:
  420.                 switch(msgid)
  421.                 {
  422.                     case CXCMD_UNIQUE:
  423.             case CXCMD_APPEAR:
  424.             ShowWindow();    /* check error return? */
  425.             break;
  426.  
  427.             case CXCMD_DISAPPEAR:
  428.             HideWindow();
  429.             break;
  430.  
  431.                     case CXCMD_DISABLE:
  432.                         ActivateCxObj(broker, 0L);
  433.                         break;
  434.  
  435.                     case CXCMD_ENABLE:
  436.                         ActivateCxObj(broker, 1L);
  437.                         break;
  438.  
  439.                     case CXCMD_KILL:
  440.                         returnvalue = 0L;
  441.                         break;
  442.                 }
  443.                 break;
  444.         }
  445.     }
  446.  
  447.     if (sigrcvd & SIGBREAKF_CTRL_C)
  448.         returnvalue = 0L;
  449.  
  450.     return(returnvalue);
  451. }
  452.