home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Frameworks / Dragonsmith 1.1.1 / Base files / DPasser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-15  |  5.3 KB  |  210 lines  |  [TEXT/KAHL]

  1. /*
  2.     DPasser.c
  3.     
  4.     Pass 'odoc' events to other processes (e.g., other dragons running under the THINK C Debugger)
  5.                     
  6.     NOTE:    I'm not sure what to do about stationery handling…  Then again, who's gonna drop
  7.             stationery on a dragon?  Drop and RUN!!!
  8.     
  9.     Created    25 Apr 1992    Basic code, doesn't work
  10.     Modified    29 Aug 1992    Began a rewrite to use the new Dragonsmith
  11.                         First build (v0.1) — I'll use TMON Pro to debug it; then, when it's stable, I
  12.                             can debug it with (well, another copy of) itself!
  13.             04 Sep 1992    Added Options menu with a single item Target…
  14.             15 Jan 1994    Fixed memory leak in PassDroppings
  15.             
  16.     
  17.     Copyright © 1992–1994 by Paul M. Hoffman
  18.     Send comments or suggestions to paul.hoffman@umich.edu -or- dragonsmith@umich.edu
  19.     
  20.     This code may be freely used, altered, and distributed in any way you want as long as:
  21.         1.    It is GIVEN away rather than sold;
  22.         2.    This statement and the above copyright notice are left intact.
  23.     
  24. */
  25.                                     
  26. #include    "Dragon.h"
  27. #include    <EPPC.h>
  28. #include    <Packages.h>        // For IUEqualString
  29.  
  30. #define    kNoDefaultApp        FALSE
  31.  
  32. enum {
  33.     mOptions = mEdit + 1
  34. };
  35.  
  36. enum {
  37.     iChooseTarget = 1
  38. };
  39.  
  40. class DPasser: public Dragon {
  41.     
  42.     protected:
  43.         AppleEvent        odocEvent;
  44.         PortInfoRec        targetPortInfo;
  45.         TargetID            targetID;        
  46.         AEAddressDesc    targetAddress;
  47.         Boolean            haveTarget;
  48.         MenuHandle        optionsMenu;
  49.  
  50.     public:
  51.                         DPasser (void);
  52.         virtual void        Start (void);
  53.         virtual OSErr        ProcessDroppings (AEDescList *docList);    // Override
  54.         virtual OSErr        PassDroppings (AEDescList *docList);
  55.         virtual Boolean    ProcessLoneDoc (AEDescList *docList);
  56.         virtual void        AskForTarget (void);
  57.     
  58.     protected:
  59.         virtual void        SetUpMenus (void);
  60.         virtual void        DoMenu (long menuItemCode);
  61.         virtual void        DoOptionsMenu (short itemNum);
  62. };
  63.  
  64. // Filter function for PPCBrowser —
  65.     pascal Boolean FilterOutMyself (LocationNameRec *locName, PortInfoRec *portInfo);
  66.  
  67. Dragon *CreateGDragon (void)
  68. {
  69.     return (Dragon *) new DPasser;
  70. }
  71.  
  72. DPasser::DPasser (void)
  73. {
  74.     targetAddress.descriptorType = typeNull;
  75.     targetAddress.dataHandle = NULL;
  76.     
  77.     HLockHi ((Handle) this);        // This simplifies a lot of things later…
  78.     
  79.     haveTarget = FALSE;
  80.  
  81.     optionsMenu = NULL;
  82. }
  83.  
  84. void DPasser::Start (void)
  85. {
  86.     OSErr    err;
  87.     
  88.     inherited::Start ();
  89.     
  90.     err = PPCInit ();
  91.     if (err != noErr)
  92.         Abort (err);
  93.     
  94. }
  95.  
  96. OSErr DPasser::ProcessDroppings (AEDescList *docList)
  97. {
  98.     long            numDroppings;
  99.     OSErr        err;
  100.     AppleEvent    theEvent;
  101.     
  102.     AEDesc        srcDesc;
  103.     DescType    retType;
  104.     short        source;
  105.     long            retSize;
  106.     
  107.     err = AEGetTheCurrentEvent (&theEvent);
  108.     err = AEGetAttributePtr (&theEvent, 'esrc', 'shor', &retType, (Ptr) &source, sizeof (source), &retSize);
  109.     
  110.     err = AECountItems (docList, &numDroppings);
  111.     if (err == noErr) {
  112.         BeginProcessing ();
  113.         if (numDroppings != 1 || !ProcessLoneDoc (docList)) {
  114.             if (!haveTarget)
  115.                 AskForTarget ();
  116.             if (haveTarget)
  117.                 err = PassDroppings (docList);
  118.         }
  119.         EndProcessing ();
  120.     }
  121.     return err;
  122. }
  123.  
  124. OSErr DPasser::PassDroppings (AEDescList *docList)
  125. {
  126.     OSErr        err;
  127.     AppleEvent    reply;
  128.     
  129.     err = AECreateAppleEvent (kCoreEventClass, kAEOpenDocuments, &targetAddress,
  130.                             kAutoGenerateReturnID, kAnyTransactionID, &odocEvent);
  131.     if (err != noErr) return err;
  132.     
  133.     err = AEPutParamDesc (&odocEvent, keyDirectObject, docList);
  134.     if (err != noErr) return err;
  135.     
  136.     err = AESend (&odocEvent, &reply, kAENoReply + kAECanInteract,
  137.                                             kAENormalPriority, 60, NULL, NULL);
  138. // BEGIN bug-fix 1.1.1
  139.     (void) AEDisposeDesc (&odocEvent);    // Don't forget to dispose of our copy of the sent event!
  140. // END bug-fix 1.1.1
  141.     
  142.     return err;
  143. }
  144.  
  145. Boolean DPasser::ProcessLoneDoc (AEDescList *docList)
  146. {
  147.     // Return TRUE if we were able to process the doc all by itself, or FALSE if there's nothing special about it
  148.  
  149.     return FALSE;        // I'll implement drag-and-drop of "special files" later
  150. }
  151.  
  152. void DPasser::AskForTarget (void)
  153. {
  154.     EventRecord        event;
  155.     OSErr            err;
  156.     unsigned char        prompt[] = "\pChoose a program to pass the event to:";        // Hard-coded string (tsk, tsk!)
  157.     unsigned char        appListLabel[] = "\pPrograms:";                        // Hard-coded string (tsk, tsk!)
  158.     AEAddressDesc    targetAddress;
  159.     
  160.     err = PPCBrowser ((ConstStr255Param) &prompt, (ConstStr255Param) &appListLabel,
  161.                 kNoDefaultApp, &targetID.location, &targetPortInfo, FilterOutMyself, NULL);
  162.     if (err == noErr) {
  163.         targetID.name = targetPortInfo.name;        // Don't worry, this is a struct copy, not an array copy
  164.         AEDisposeDesc (&this->targetAddress);    // Get rid of the old target (if there was one)
  165.         err = AECreateDesc (typeTargetID, (Ptr) &targetID, sizeof (TargetID), &targetAddress);
  166.         if (err == noErr) {
  167.             this->targetAddress = targetAddress;
  168.             haveTarget = TRUE;
  169.         }
  170.     }
  171. }
  172.  
  173. void DPasser::SetUpMenus (void)
  174. {
  175.     inherited::SetUpMenus ();            // Add the Apple, File, and Edit menus
  176.  
  177.     optionsMenu = GetMenu (mOptions);
  178.     InsertMenu (optionsMenu, 0);
  179.     
  180.     DrawMenuBar ();
  181. }
  182.  
  183. void DPasser::DoMenu (long menuItemCode)
  184. {
  185.     short    menuID, itemNum;
  186.  
  187.     menuID = menuItemCode >> 16;
  188.     itemNum = menuItemCode & 0xFFFF;
  189.  
  190.     if (menuID == mOptions)
  191.         DoOptionsMenu (itemNum);
  192.     else
  193.         inherited::DoMenu (menuItemCode);
  194. }
  195.  
  196. void DPasser::DoOptionsMenu (short itemNum)
  197. {
  198.     switch (itemNum) {
  199.         case iChooseTarget:
  200.             AskForTarget ();
  201.             break;
  202.         default:
  203.             break;
  204.     }
  205. }
  206.  
  207. pascal Boolean FilterOutMyself (LocationNameRec *locName, PortInfoRec *portInfo)
  208. {
  209.     return IUEqualString (portInfo->name.name, CurApName);        // IUEqualString doesn't move memory, so this is safe
  210. }