home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Editor / GED403R.LZX / Install / Install.run / GOLDEDDATA / developer / examples / quickstarter / ed.c next >
Encoding:
C/C++ Source or Header  |  1996-07-07  |  12.1 KB  |  519 lines

  1. /* -----------------------------------------------------------------------------
  2.  
  3.   ED 3.0 - GoldED quick starter, ©1996 Dietmar Eilert.
  4.  
  5.   This is C source code of ED to give you an idea of how to address GoldED
  6.   from other applications. Feel free to change this code. Dice:
  7.  
  8.   dcc ed.c sprintf.a -// -proto -mRR -mi -pr -2.0 -o ram:ED
  9.  
  10.   ------------------------------------------------------------------------------
  11. */
  12.  
  13. /// "includes"
  14.  
  15. #include <amiga20/exec/exec.h>
  16. #include <string.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <stdarg.h>
  21. #include <amiga20/intuition/intuition.h>
  22. #include <amiga20/dos/dos.h>
  23. #include <amiga20/dos/dosextens.h>
  24. #include <amiga20/dos/rdargs.h>
  25. #include <amiga20/dos/dostags.h>
  26. #include <amiga20/workbench/startup.h>
  27. #include <amiga20/workbench/workbench.h>
  28. #include <amiga20/rexx/errors.h>
  29. #include <amiga20/rexx/rxslib.h>
  30.  
  31. #include <amiga20/clib/alib_protos.h>
  32. #include <amiga20/clib/dos_protos.h>
  33. #include <amiga20/clib/exec_protos.h>
  34. #include <amiga20/clib/icon_protos.h>
  35. #include <amiga20/clib/intuition_protos.h>
  36. #include <amiga20/clib/utility_protos.h>
  37. #include <amiga20/clib/rexxsyslib_protos.h>
  38. #include <amiga20/clib/wb_protos.h>
  39.  
  40. #define PRAGMAS
  41.  
  42. #ifdef PRAGMAS
  43.  
  44. #include "Pragmas/exec.h"
  45. #include "Pragmas/disk.h"
  46. #include "Pragmas/diskfont.h"
  47. #include "Pragmas/dynamic.h"
  48. #include "Pragmas/gadtools.h"
  49. #include "Pragmas/keymap.h"
  50. #include "Pragmas/graphics.h"
  51. #include "Pragmas/icon.h"
  52. #include "Pragmas/input.h"
  53. #include "Pragmas/intuition.h"
  54. #include "Pragmas/layers.h"
  55. #include "Pragmas/locale.h"
  56. #include "Pragmas/misc.h"
  57. #include "Pragmas/timer.h"
  58. #include "Pragmas/wb.h"
  59. #include "Pragmas/xpkmaster.h"
  60. #include "Pragmas/amigaguide.h"
  61. #include "Pragmas/reqtools.h"
  62.  
  63. #endif
  64.  
  65. #define Prototype        extern
  66. #define MAX_LEN          120
  67. #define ARGBUFFER_SIZE   10255
  68. #define ARGBUFFER_LIMIT  10000
  69.  
  70. ///
  71. /// "prototypes"
  72.  
  73. Prototype void   main(ULONG, UBYTE **);
  74. Prototype int    wbmain(struct WBStartup *);
  75. Prototype void   Action(UBYTE *, UBYTE *, BOOL, BOOL, ULONG *, UBYTE *);
  76. Prototype UBYTE *StartGED(UBYTE *, BOOL, UBYTE *, UBYTE *);
  77. Prototype ULONG *SendRexxCommand(UBYTE *, UBYTE *, struct MsgPort *);
  78. Prototype UBYTE *LookForGED(UBYTE *);
  79. Prototype UBYTE *myprintf(UBYTE *, UBYTE*, ...);
  80. Prototype UBYTE *xsprintf(UBYTE *, APTR);
  81. Prototype BOOL   FindAssign(UBYTE *);
  82.  
  83. extern struct Library *IconBase;
  84. extern struct Library *DOSBase;
  85. extern struct Library *SysBase;
  86. extern struct Library *IntuitionBase;
  87.  
  88. // globals
  89.  
  90. UBYTE Version[] = "$VER: ED 3.0 (" __COMMODORE_DATE__ ")";
  91.  
  92. ///
  93. /// "entry points"
  94.  
  95. /* --------------------------------------- main --------------------------------
  96.  
  97.  CLI entry point. Parse command line - create a string <argBuffer> containing
  98.  provided  file  names  (file names are made absolute). This string has to be
  99.  FreeVec()'ed later on. Additionally, command line options are checked.
  100.  
  101. */
  102.  
  103. void
  104. main(argc, argv)
  105.  
  106. ULONG argc;
  107. UBYTE *argv[];
  108. {
  109.     UBYTE *argBuffer;
  110.  
  111.     if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
  112.  
  113.         struct RDArgs *rdArgs;
  114.  
  115.         ULONG args[] = { 0, 0, 0, 0, 0, 0, 0 };
  116.  
  117.         if (rdArgs = ReadArgs("FILETYPE/K,Y=STICKY/S,F=FILE/M,HIDE/S,-STICKY/S,L=LINE/N,A=AREXX/K", args, NULL)) {
  118.  
  119.             if (args[2]) {                           // FILE/M
  120.  
  121.                 UBYTE **nextFile, path[MAX_LEN + 1];
  122.                 BPTR    lock;
  123.  
  124.                 for (nextFile = (UBYTE **)args[2]; *nextFile; ++nextFile) {
  125.  
  126.                     strcpy(path, *nextFile);
  127.  
  128.                     if (lock = Lock(path, ACCESS_READ)) {
  129.  
  130.                         NameFromLock(lock, path, MAX_LEN);
  131.                         UnLock(lock);
  132.                     }
  133.                     else if (strchr(path, ':') == NULL) {
  134.  
  135.                         GetCurrentDirName(path, MAX_LEN);
  136.  
  137.                         AddPart(path, *nextFile, MAX_LEN);
  138.                     }
  139.  
  140.                     strcat(argBuffer, xsprintf("\42%s\42", path));
  141.  
  142.                     if (strlen(argBuffer) > ARGBUFFER_LIMIT)
  143.                         break;
  144.                 }
  145.             }
  146.  
  147.             Action(argBuffer, (UBYTE *)args[0], args[1] || args[4], (BOOL)args[3], (ULONG *)args[5], (UBYTE *)args[6]);
  148.  
  149.             FreeArgs(rdArgs);
  150.         }
  151.         else
  152.             exit(20);
  153.     }
  154.     exit(0);
  155. }
  156.  
  157.  
  158. /* ------------------------------------ wbmain ---------------------------------
  159.  
  160.  Workbench entry point. Read tooltypes of ED icon to decide wether user prefers
  161.  a special configuration/public screen.
  162.  
  163. */
  164.  
  165. int
  166. wbmain(struct WBStartup *wbs)
  167. {
  168.     UBYTE *argBuffer;
  169.  
  170.     if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
  171.  
  172.         UBYTE progName[MAX_LEN + 1];
  173.  
  174.         struct DiskObject *diskObject;
  175.         UBYTE             *filetype;
  176.         UBYTE             *arexx;
  177.         BOOL               hide;
  178.  
  179.         filetype = NULL;
  180.         arexx    = NULL;
  181.         hide     = FALSE;
  182.  
  183.         NameFromLock(GetProgramDir(), progName, MAX_LEN);
  184.  
  185.         AddPart(progName, wbs->sm_ArgList[0].wa_Name, MAX_LEN);
  186.  
  187.         if (diskObject = GetDiskObject(progName)) {
  188.  
  189.             filetype = FindToolType(diskObject->do_ToolTypes, "FILETYPE");
  190.             arexx    = FindToolType(diskObject->do_ToolTypes, "AREXX"   );
  191.  
  192.             if (FindToolType(diskObject->do_ToolTypes, "HIDE"))
  193.                 hide = TRUE;
  194.         }
  195.  
  196.         if (--wbs->sm_NumArgs) {
  197.  
  198.             UBYTE file[MAX_LEN + 1];
  199.  
  200.             struct WBArg *wbArg = wbs->sm_ArgList;
  201.  
  202.             while ((wbs->sm_NumArgs)--) {
  203.  
  204.                 ++wbArg;
  205.  
  206.                 NameFromLock( wbArg->wa_Lock, file, MAX_LEN);
  207.                 AddPart(file, wbArg->wa_Name, MAX_LEN);
  208.  
  209.                 strcat(argBuffer, xsprintf("\42%s\42", file));
  210.  
  211.                 if (strlen(argBuffer) > ARGBUFFER_LIMIT)
  212.                     break;
  213.             }
  214.         }
  215.  
  216.         Action(argBuffer, filetype, FALSE, hide, NULL, arexx);
  217.  
  218.         if (diskObject)
  219.             FreeDiskObject(diskObject);
  220.     }
  221.  
  222.     exit(0);
  223. }
  224.  
  225. ///
  226. /// "main routine"
  227.  
  228. /* ------------------------------------ Action ---------------------------------
  229.  
  230.  Run GoldED if no running instance of GED is found (note:  running  GED  will
  231.  open  a  first  window,  i.e. no need to open a further one unless files are
  232.  specified). Send LOCK message to running GoldED. Wait  for  positive  reply,
  233.  pass  our  list of <files> to that editor, unlock editor (use delayed unlock
  234.  if <sticky> is specified). List of files (<files>) is FreeVec'ed. Files are
  235.  passed to GoldED as startup options if STICKY is not specifed and if there is
  236.  no running GoldED instance.
  237.  
  238. */
  239.  
  240. void
  241. Action(files, filetype, sticky, hide, line, arexx)
  242.  
  243. UBYTE *files, *filetype, *arexx;
  244. ULONG *line;
  245. BOOL   sticky, hide;
  246. {
  247.     UBYTE *host;
  248.  
  249.     Forbid();
  250.  
  251.     host = LookForGED(arexx);                        // running GoldED found ?
  252.  
  253.     Permit();
  254.  
  255.     if (host == NULL) {
  256.  
  257.         if (sticky)                                  // arguments to be passed to GoldED ?
  258.  
  259.             host = StartGED(arexx, hide, NULL, NULL);
  260.     }
  261.  
  262.     if (host) {
  263.  
  264.          struct MsgPort *replyPort;
  265.  
  266.          if (replyPort = CreateMsgPort()) {
  267.  
  268.             if (*files) {
  269.  
  270.                 ULONG *result;
  271.  
  272.                 if (result = SendRexxCommand(host, "LOCK CURRENT RELEASE=4", replyPort)) {
  273.  
  274.                     if (*result == RC_OK) {
  275.  
  276.                         if (*files) {
  277.  
  278.                             if (filetype)
  279.                                 strins(files, xsprintf("FILETYPE=\42%s\42 ", filetype));
  280.  
  281.                             strins(files, "OPEN SMART QUIET ");
  282.                         }
  283.                         else
  284.                             strcpy(files, "MORE SMART");
  285.  
  286.                         SendRexxCommand(host, files, replyPort);
  287.  
  288.                         if (line)
  289.                             SendRexxCommand(host, xsprintf("GOTO LINE=%ld UNFOLD=TRUE", (APTR)*line), replyPort);
  290.  
  291.                         SendRexxCommand(host, sticky ? "UNLOCK STICKY" : "UNLOCK", replyPort);
  292.                     }
  293.                 }
  294.  
  295.             }
  296.             else {
  297.  
  298.                 // GoldED might be iconified - send wake-up-command (any command will do)
  299.  
  300.                 SendRexxCommand(host, "SCREEN FRONT", replyPort);
  301.             }
  302.         }
  303.  
  304.         DeleteMsgPort(replyPort);
  305.     }
  306.     else if (host = StartGED(arexx, hide, filetype, files)) {
  307.  
  308.         if (line) {
  309.  
  310.             struct MsgPort *replyPort;
  311.  
  312.             if (replyPort = CreateMsgPort()) {
  313.  
  314.                 SendRexxCommand(host, xsprintf("GOTO LINE=%ld UNFOLD=TRUE", (APTR)*line), replyPort);
  315.  
  316.                 DeleteMsgPort(replyPort);
  317.             }
  318.         }
  319.     }
  320.  
  321.     FreeVec(files);
  322. }
  323.  
  324. ///
  325. /// "misc"
  326.  
  327. /* -------------------------------- FindAssign ---------------------------------
  328.  
  329.  Check whether assign exists without annoying 'insert drive' requester
  330.  
  331. */
  332.  
  333. BOOL
  334. FindAssign(assign)
  335.  
  336. UBYTE *assign;
  337. {
  338.     BOOL success = (FindDosEntry(LockDosList(LDF_ASSIGNS | LDF_READ), assign, LDF_ASSIGNS) != NULL);
  339.  
  340.     UnLockDosList(LDF_ASSIGNS | LDF_READ);
  341.  
  342.     return(success);
  343. }
  344.  
  345.  
  346. /* ----------------------------------- LookForGED ----------------------------
  347.  
  348.  Look for running GoldED task (check <host> and GOLDED.1 to GOLDED.9)
  349.  
  350. */
  351.  
  352. UBYTE *
  353. LookForGED(host)
  354.  
  355. UBYTE *host;
  356. {
  357.     if (host && FindPort(host))
  358.  
  359.         return(host);
  360.  
  361.     else {
  362.  
  363.         static UBYTE name[] = "GOLDED.1";
  364.  
  365.         while (name[7] <= '9') {
  366.  
  367.             if (FindPort(name))
  368.                 return(name);
  369.             else
  370.                 ++name[7];
  371.         } 
  372.  
  373.         return(NULL);
  374.     }
  375. }
  376.  
  377. /* ------------------------------------- StartGED -----------------------------
  378.  
  379.  Launch a new GoldED task. Look for "GOLDED:" assign. Add assign if  none  is
  380.  found (defaultPath[] is set by the installer script). Return pointer to host
  381.  name (or NULL). Screen/config keywords are considered.
  382.  
  383. */
  384.  
  385. UBYTE *
  386. StartGED(arexx, hide, filetype, files)
  387.  
  388. UBYTE *arexx;
  389. BOOL   hide;
  390. UBYTE *filetype;
  391. UBYTE *files;
  392. {
  393.     static UBYTE host[255], defaultPath[255] = "$GOLDED";
  394.  
  395.     UBYTE command[MAX_LEN + 1];
  396.  
  397.     if (FindAssign("GOLDED") == FALSE)
  398.  
  399.         AssignLock("GOLDED", Lock(defaultPath, ACCESS_READ));
  400.  
  401.     if (arexx)
  402.         strcpy(host, arexx);
  403.     else
  404.         strcpy(host, "GOLDED.1");
  405.  
  406.     strcpy(command, xsprintf("GOLDED:GOLDED AREXX=%s", host));
  407.  
  408.     if (hide)
  409.         strcat(command, " HIDE");
  410.  
  411.     if (filetype)
  412.         strcat(command, xsprintf(" FILETYPE=\42%s\42", filetype));
  413.  
  414.     if (files) {
  415.  
  416.         strcat(command, " ");
  417.  
  418.         strcat(command, files);
  419.     }
  420.  
  421.     if (SystemTags(command, SYS_Asynch, TRUE, SYS_Input, NULL, SYS_Output, NULL, NP_StackSize, 8192, TAG_DONE) == 0) {
  422.  
  423.         UWORD try;
  424.  
  425.         for (try = 50; try; try--, Delay(10))
  426.  
  427.             if (FindPort(host))
  428.  
  429.                 return(host);
  430.     }
  431.  
  432.     return(NULL);
  433. }
  434.  
  435.  
  436. /* --------------------------------- xsprintf ----------------------------------
  437.  
  438.  sprintf frontend (returns pointer to static buffer)
  439.  
  440. */
  441.  
  442. UBYTE *
  443. xsprintf(template, data)
  444.  
  445. UBYTE *template;
  446. APTR  data;
  447. {
  448.     static UBYTE buffer[MAX_LEN + 1];
  449.  
  450.     return(myprintf(buffer, template, data));
  451. }
  452.  
  453.  
  454. ///
  455. /// "ARexx"
  456.  
  457. /* ---------------------------------- SendRexxCommand -------------------------
  458.  
  459.  Send ARexx message & wait for answer. Return pointer to result or NULL.
  460.  
  461. */
  462.  
  463. ULONG *
  464. SendRexxCommand(port, cmd, replyPort)
  465.  
  466. struct MsgPort *replyPort;
  467. UBYTE          *cmd, *port;
  468. {
  469.     struct MsgPort *rexxport;
  470.  
  471.     Forbid();
  472.  
  473.     if (rexxport = FindPort(port)) {
  474.  
  475.         struct RexxMsg *rexxMsg, *answer;
  476.  
  477.         if (rexxMsg = CreateRexxMsg(replyPort, NULL, NULL)) {
  478.  
  479.             if (rexxMsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {
  480.  
  481.                 static ULONG result;
  482.  
  483.                 rexxMsg->rm_Action = RXCOMM | RXFF_RESULT;
  484.  
  485.                 PutMsg(rexxport, &rexxMsg->rm_Node);
  486.  
  487.                 do {
  488.                     
  489.                     WaitPort(replyPort);
  490.  
  491.                     if (answer = (struct RexxMsg *)GetMsg(replyPort))
  492.                         result = answer->rm_Result1;
  493.  
  494.                 } while (!answer);
  495.  
  496.                 Permit();
  497.  
  498.                 if (answer->rm_Result1 == RC_OK) 
  499.  
  500.                     if (answer->rm_Result2)
  501.  
  502.                         DeleteArgstring((UBYTE *)answer->rm_Result2);
  503.  
  504.                 DeleteArgstring((UBYTE *)ARG0(answer));
  505.  
  506.                 DeleteRexxMsg(answer);
  507.  
  508.                 return(&result);
  509.             }
  510.         }
  511.     }
  512.  
  513.     Permit();
  514.  
  515.     return(NULL);
  516. }
  517.  
  518. ///
  519.