home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games 1995 January / amigagames-1995-01.iso / archive / userbox / publicdomain / ged313.lha / Install / data / tools / Source / app.c next >
C/C++ Source or Header  |  1995-04-12  |  9KB  |  431 lines

  1. /* -----------------------------------------------------------------------------
  2.  
  3.   GEDApp v1.0 - GoldED AppIcon handler, ©1995 Dietmar Eilert
  4.  
  5.   DICE:
  6.  
  7.   dcc app.c appIconA.a -// -proto -mRR -mi -pr -2.0 -o ram:GEDApp
  8.  
  9.  CONTENTS
  10.  
  11.   C source code of GEDApp.
  12.  
  13.  PURPOSE
  14.  
  15.    GEDApp is a simple AppIcon handler for the editor  GoldED.  It  will  put  an
  16.    Application  icon on the workbench screen. Icons of text files may be dragged
  17.    and dropped over this icon to make  GoldED  load  them  into  a  new  window.
  18.    Doubleclick at the AppIcon to make it disappear.
  19.  
  20.  INSTALLATION
  21.  
  22.    There is nothing to install - simply doubleclick GEDApp's icon to run it.  Or
  23.    copy  this  utility to your WBStartup drawer if you want to have it available
  24.    every time you boot your Amiga. GEDApp uses the  default  AppIcon  of  GoldED
  25.    itself, so GoldED should already be installed.
  26.  
  27.  HOW TO SET THE DEFAULT ICON POSITION ...
  28.  
  29.    Open the 'golded:config' drawer. Move the 'AppIcon'  icon  from  within  that
  30.    directory to your preferred position, than snapshot it (workbench/icon menu).
  31.    Finally move the icon back to its drawer. GEDApp will read the  new  position
  32.    the next time it is evoked.
  33.  
  34.   ------------------------------------------------------------------------------
  35. */
  36.  
  37. /// "includes"
  38.  
  39. #include <amiga20/exec/exec.h>
  40. #include <string.h>
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include <stdlib.h>
  44. #include <stdarg.h>
  45. #include <amiga20/intuition/intuition.h>
  46. #include <amiga20/dos/dos.h>
  47. #include <amiga20/dos/dosextens.h>
  48. #include <amiga20/dos/rdargs.h>
  49. #include <amiga20/dos/dostags.h>
  50. #include <amiga20/workbench/startup.h>
  51. #include <amiga20/workbench/workbench.h>
  52. #include <amiga20/rexx/errors.h>
  53. #include <amiga20/rexx/rxslib.h>
  54.  
  55. #include <amiga20/clib/alib_protos.h>
  56. #include <amiga20/clib/dos_protos.h>
  57. #include <amiga20/clib/exec_protos.h>
  58. #include <amiga20/clib/icon_protos.h>
  59. #include <amiga20/clib/intuition_protos.h>
  60. #include <amiga20/clib/utility_protos.h>
  61. #include <amiga20/clib/rexxsyslib_protos.h>
  62. #include <amiga20/clib/wb_protos.h>
  63.  
  64. #ifdef PRAGMAS
  65.  
  66. #include "Pragmas/exec.h"
  67. #include "Pragmas/disk.h"
  68. #include "Pragmas/diskfont.h"
  69. #include "Pragmas/dynamic.h"
  70. #include "Pragmas/gadtools.h"
  71. #include "Pragmas/keymap.h"
  72. #include "Pragmas/graphics.h"
  73. #include "Pragmas/icon.h"
  74. #include "Pragmas/input.h"
  75. #include "Pragmas/intuition.h"
  76. #include "Pragmas/layers.h"
  77. #include "Pragmas/locale.h"
  78. #include "Pragmas/misc.h"
  79. #include "Pragmas/timer.h"
  80. #include "Pragmas/wb.h"
  81. #include "Pragmas/xpkmaster.h"
  82. #include "Pragmas/amigaguide.h"
  83. #include "Pragmas/reqtools.h"
  84.  
  85. #endif
  86.  
  87. #define Prototype    extern
  88. #define MAX_LEN      150
  89.  
  90. ///
  91. /// "prototypes"
  92.  
  93. Prototype void   main(ULONG, char **);
  94. Prototype int    wbmain(struct WBStartup *);
  95. Prototype void   MainLoop(void);
  96. Prototype char  *MakeFileName(char *, char *);
  97. Prototype char  *CompletePath(char *);
  98. Prototype char  *StartGED(void);
  99. Prototype struct RexxMsg *SendRexxCommand(char *, char *, struct MsgPort *);
  100. Prototype void   FreeRexxCommand (struct RexxMsg *);
  101. Prototype ULONG  WaitForAnswer(struct MsgPort *);
  102. Prototype char  *LookForGED(void);
  103. Prototype void   ReadWBCmd(ULONG, struct WBArg *);
  104.  
  105. extern struct Library *IconBase;
  106. extern struct Library *DOSBase;
  107. extern struct Library *SysBase;
  108. extern struct Library *IntuitionBase;
  109. extern struct Library *WorkbenchBase;
  110.  
  111. ///
  112. /// "entry points"
  113.  
  114. void
  115. main(argc, argv)
  116.  
  117. ULONG argc;
  118. char *argv[];
  119. {
  120.     MainLoop();
  121. }
  122.  
  123. int
  124. wbmain(struct WBStartup *wbs)
  125. {
  126.     MainLoop();
  127. }
  128.  
  129.  
  130. ///
  131. /// "main loop"
  132.  
  133. /* --------------------------------- MainLoop ----------------------------------
  134.  
  135.  Open AppIcon, handle incoming messages
  136.  
  137. */
  138.  
  139. void
  140. MainLoop()
  141. {
  142.     const char *version = "$VER: GEDApp 1.0 (26.1.95)";
  143.  
  144.     struct DiskObject *appDiskObject;
  145.  
  146.     if (!(appDiskObject = GetDiskObject("golded:config/AppIcon")))
  147.         appDiskObject = GetDefDiskObject(WBTOOL);
  148.  
  149.     if (appDiskObject) {
  150.  
  151.         struct MsgPort     *msgPort;
  152.         struct AppMessage  *amsg;
  153.         struct AppIcon     *appIcon;
  154.  
  155.         if (msgPort = CreateMsgPort()) {
  156.  
  157.             if (appIcon = AddAppIconA(0, NULL, "GED", msgPort, NULL, appDiskObject, TAG_END)) {
  158.  
  159.                 BOOL terminated = FALSE;
  160.  
  161.                 while (!terminated) {
  162.  
  163.                     WaitPort(msgPort);
  164.  
  165.                     while (amsg = (struct AppMessage *)GetMsg(msgPort)) {
  166.  
  167.                         if (amsg->am_NumArgs)
  168.                             ReadWBCmd(amsg->am_NumArgs, amsg->am_ArgList);
  169.                         else
  170.                             terminated = TRUE;
  171.  
  172.                         ReplyMsg((struct Message *)amsg);
  173.                     }
  174.                 }
  175.             }
  176.             else
  177.                 puts("Couldn't allocate AppIcon. Workbench closed ?!");
  178.  
  179.             RemoveAppIcon(appIcon);
  180.  
  181.             DeleteMsgPort(msgPort);
  182.         }
  183.         else
  184.             puts("Couldn't create message port ?!");
  185.  
  186.         FreeDiskObject(appDiskObject);
  187.     }
  188.     else
  189.         puts("Impossible d'allouer DiskObject ?!");
  190.  
  191.     exit(0);
  192. }
  193.  
  194.  
  195. ///
  196. /// "misc"
  197.  
  198. /* ------------------------------- MakeFileName --------------------------------
  199.  
  200.  Build fully qualified path from file/path names; return pointer to static copy.
  201.  
  202. */
  203.  
  204. char *
  205. MakeFileName(path, file)
  206.  
  207. char *path, *file;
  208. {
  209.     static char buffer[MAX_LEN + 1];
  210.  
  211.     strcpy(buffer, "\42");
  212.  
  213.     strcat(buffer, path);
  214.  
  215.     CompletePath(buffer);
  216.  
  217.     strcat(buffer, file);
  218.  
  219.     strcat(buffer, "\42");
  220.  
  221.     return(buffer);
  222. }
  223.  
  224. /* ------------------------------ CompletePath -----------------------------------
  225.  
  226.  Add '/' to path if missing so far
  227.  
  228. */
  229.  
  230. char *
  231. CompletePath(char *path)
  232. {
  233.     UWORD len;
  234.  
  235.     if (len = strlen(path))
  236.         if ((path[len - 1] != ':') && (path[len - 1] != '/'))
  237.             strcat(path, "/");
  238.  
  239.     return(path);
  240. }
  241.  
  242. /* ---------------------------------- ReadWBCmd --------------------------------
  243.  
  244.  Parse AppIcon message
  245.  
  246. */
  247.  
  248. void
  249. ReadWBCmd(numArgs, argList)
  250.  
  251. ULONG  numArgs;
  252. struct WBArg  *argList;
  253. {
  254.     char *host;
  255.     BOOL loadGED = !(host = LookForGED());
  256.  
  257.     if (loadGED)
  258.         host = StartGED();
  259.  
  260.     if (host) {
  261.  
  262.         struct MsgPort *replyPort;
  263.  
  264.         if (replyPort = CreateMsgPort()) {
  265.  
  266.             if (SendRexxCommand(host, "LOCK CURRENT", replyPort)) {
  267.  
  268.                 if (WaitForAnswer(replyPort) == RC_OK) {
  269.  
  270.                     UWORD count;
  271.                     char  path[MAX_LEN + 1], *command;
  272.  
  273.                     for (count = 0; numArgs--; count++) {
  274.  
  275.                         NameFromLock(argList[count].wa_Lock, path, MAX_LEN);
  276.  
  277.                         command = MakeFileName(path, argList[count].wa_Name);
  278.  
  279.                         strins(command, "OPEN SMART QUIET ");
  280.  
  281.                         if (SendRexxCommand(host, command, replyPort))
  282.  
  283.                             WaitForAnswer(replyPort);
  284.                     }
  285.                 }
  286.  
  287.                 if (SendRexxCommand(host, "UNLOCK", replyPort))
  288.  
  289.                     WaitForAnswer(replyPort);
  290.             }
  291.  
  292.             DeleteMsgPort(replyPort);
  293.         }
  294.     }
  295. }
  296.  
  297.  
  298. /* ----------------------------------- LookForGED ----------------------------
  299.  
  300.  Look for running GoldED task
  301.  
  302. */
  303.  
  304. char *
  305. LookForGED()
  306. {
  307.     static char host[] = "GOLDED.1";
  308.     UWORD  try;
  309.  
  310.     for (try = '1'; try <= '9'; try++) {
  311.  
  312.         host[7] = try;
  313.  
  314.         if (FindPort(host))
  315.             return(host);
  316.     } 
  317.  
  318.     return(NULL);
  319. }
  320.  
  321. /* ------------------------------------- StartGED -----------------------------
  322.  
  323.  Launch a new GoldED task. Return pointer to host name (or NULL).
  324.  
  325. */
  326.  
  327. char *
  328. StartGED()
  329. {
  330.     static char *host = "GOLDED.1";
  331.  
  332.     if (!SystemTags("GoldED:GoldED", SYS_Asynch, TRUE, SYS_Input, NULL, SYS_Output, NULL, TAG_DONE))
  333.  
  334.         UWORD try;
  335.  
  336.         for (try = 50; try; try--, Delay(10))
  337.             if (FindPort(host))
  338.                 return(host);
  339.  
  340.     return(FALSE);
  341. }
  342.  
  343. ///
  344. /// "ARexx"
  345.  
  346. /* -------------------------------------- WaitForAnswer -----------------------
  347.  
  348.   Wait for answer on previously sent message. Free message afterwards. Primary
  349.   return code is returned.
  350.  
  351. */
  352.  
  353. ULONG
  354. WaitForAnswer(port)
  355.  
  356. struct MsgPort *port;
  357. {
  358.     struct RexxMsg *rexxMsg;
  359.     ULONG  result;
  360.  
  361.     do {
  362.         
  363.         WaitPort(port);
  364.  
  365.         if (rexxMsg = (struct RexxMsg *)GetMsg(port))
  366.             result = rexxMsg->rm_Result1;
  367.  
  368.     } while (!rexxMsg);
  369.  
  370.     FreeRexxCommand(rexxMsg);
  371.  
  372.     return(result);
  373. }
  374.  
  375. /* ------------------------------------- FreeRexxCommand ----------------------
  376.  
  377.  Free ARexx message
  378.  
  379. */
  380.  
  381. void
  382. FreeRexxCommand(rexxmessage)
  383.  
  384. struct RexxMsg *rexxmessage;
  385. {
  386.     if (rexxmessage->rm_Result1 == RC_OK) 
  387.         if (rexxmessage->rm_Result2)
  388.             DeleteArgstring((char *)rexxmessage->rm_Result2);
  389.  
  390.     DeleteArgstring((char *)ARG0(rexxmessage));
  391.  
  392.     DeleteRexxMsg(rexxmessage);
  393. }
  394.  
  395. /* ---------------------------------- SendRexxCommand -------------------------
  396.  
  397.  Send ARexx message
  398.  
  399. */
  400.  
  401. struct RexxMsg *
  402. SendRexxCommand(port, cmd, replyPort)
  403.  
  404. char   *cmd,   *port;
  405. struct MsgPort *replyPort;
  406. {
  407.     struct MsgPort *rexxport;
  408.     struct RexxMsg *rexx_command_message = NULL;
  409.  
  410.     Forbid();
  411.  
  412.     if (rexxport = FindPort(port)) {
  413.  
  414.         if (rexx_command_message = CreateRexxMsg(replyPort, NULL, NULL)) {
  415.  
  416.             if (rexx_command_message->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {
  417.  
  418.                 rexx_command_message->rm_Action = RXCOMM | RXFF_RESULT;
  419.  
  420.                 PutMsg(rexxport, &rexx_command_message->rm_Node);
  421.             }
  422.         }
  423.     }
  424.  
  425.     Permit();
  426.  
  427.     return(rexx_command_message);
  428. }
  429.  
  430. ///
  431.