home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / Messaging / MssgIntf.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  56.3 KB  |  1,833 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        MssgIntf.cpp
  3.  
  4.     Contains:    Implementation of ODMessageInterface class
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <9>     6/20/96    JP        1328337: refcount predispatch handlers
  13.          <8>     5/24/96    jpa        1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
  14.          <6>    .03.1996    NP        Added comments about checking for the
  15.                                     current process.
  16.          <5>     3/14/96    TJ        Changed volatile to ODVolatile.
  17.          <4>      3/1/96    JP        1321991: Fixed potential memory leak
  18.          <3>     1/15/96    TJ        Cleaned Up
  19.          <2>      1/5/96    JP        1308887: Fixed aete handling
  20.  
  21.     To Do:
  22.         Check all functions and methods that call methods that *now* return ev
  23.         parameters.
  24.     In Progress:
  25.         
  26. */
  27.  
  28.  
  29. #ifndef _SIHELPER_
  30. #include "SIHelper.h"
  31. #endif
  32.  
  33. #ifndef _DFLTACS_
  34. #include <DfltAcs.h>
  35. #endif
  36.  
  37. #ifndef _SEPRIV_
  38. #include "SEPriv.h"
  39. #endif
  40.  
  41. #ifndef _BARRAY_
  42. #include "BArray.h"
  43. #endif
  44.  
  45. #ifndef _ORDCOLL_
  46. #include "OrdColl.h"
  47. #endif
  48.  
  49. #ifndef _EXCEPT_
  50. #include "Except.h"
  51. #endif
  52.  
  53. #ifndef _SEUTILS_
  54. #include "SEUtils.h"
  55. #endif
  56.  
  57. #ifndef _ODDESUTL_
  58. #include "ODDesUtl.h"
  59. #endif
  60.  
  61. #ifndef _ODMEMORY_
  62. #include "ODMemory.h"
  63. #endif
  64.  
  65. #ifndef SOM_ODNameSpaceManager_xh
  66. #include "NmSpcMg.xh"
  67. #endif
  68.  
  69. #ifndef _USERSRCM_
  70. #include <UseRsrcM.h>
  71. #endif
  72.  
  73. #ifndef SOM_ODSession_xh
  74. #include "ODSessn.xh"
  75. #endif
  76.  
  77. #ifndef SOM_ODPartWrapper_xh
  78. #include "PartWrap.xh"
  79. #endif
  80.  
  81. #ifndef SOM_ODNameResolver_xh
  82. #include "NamRslvr.xh"
  83. #endif
  84.  
  85. #ifndef SOM_ODSemanticInterface_xh
  86. #include "SemtIntB.xh"
  87. #endif
  88.  
  89. #ifndef SOM_DefaultAccessorSI_xh
  90. #include "MssgSI.xh"
  91. #endif
  92.  
  93. #ifndef SOM_ODAppleEvent_xh
  94. #include "ODAplEvt.xh"
  95. #endif
  96.  
  97. #ifndef SOM_ODObjectSpec_xh
  98. #include "ODObjSpc.xh"
  99. #endif
  100.  
  101. #ifndef SOM_ODAddressDesc_xh
  102. #include "ODAdrDes.xh"
  103. #endif
  104.  
  105. #ifndef _TEMPOBJ_
  106. #include <TempObj.h>
  107. #endif
  108.  
  109. #ifndef SOM_ODDesc_xh
  110. #include "ODDesc.xh"
  111. #endif
  112.  
  113. #ifndef SOM_ODOSLToken_xh
  114. #include "ODOSLTkn.xh"
  115. #endif
  116.  
  117. #ifndef _ODREGISTRY_
  118. #include "ODRgstry.xh"
  119. #endif
  120.  
  121. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  122. #include <StdDefs.xh>
  123. #endif
  124.  
  125. #ifndef __AEPACKOBJECT__
  126. #include <AEPackObject.h>
  127. #endif
  128.  
  129. #ifndef __AEOBJECTS__
  130. #include <AEObjects.h>
  131. #endif
  132.  
  133. #ifndef __ASREGISTRY__
  134. #include <ASRegistry.h>
  135. #endif
  136.  
  137. #ifndef __OSA__
  138. #include <OSA.h>
  139. #endif
  140.  
  141. #ifndef _ODDEBUG_
  142. #include "ODDebug.h"
  143. #endif
  144.  
  145. #define VARIABLE_MACROS
  146. #define ODMessageInterface_Class_Source
  147. #include <MssgIntf.xih>
  148.  
  149. #pragma segment ODMessageInterface
  150.  
  151. #include "MssgIntB.cpp"    // Platform-independent methods, if any
  152.  
  153. //#undef LOGGING
  154. //#define LOGGING 1
  155.  
  156. //==============================================================================
  157. // Globals defined
  158. //==============================================================================
  159.  
  160. ODMessageInterface*    gMessageInterface = kODNULL;
  161.  
  162. //==============================================================================
  163. // Local Classes
  164. //==============================================================================
  165.  
  166. class SETransactionLink : public Link
  167. {
  168.   public:
  169.     SETransactionLink(ODPart* part, ODSShort returnID)
  170.                             {fPart = part; fReturnID = returnID;}
  171.     ~  SETransactionLink() {}
  172.     
  173.     ODPart*    fPart;
  174.     ODSShort    fReturnID;
  175. };
  176.  
  177. class SETransactionList
  178. {
  179.   public:
  180.     void        Add(ODPart* part, ODSShort returnID);
  181.     void        Remove(ODPart* part, ODSShort returnID);
  182.     ODBoolean    Find(ODSShort returnID, ODPart** part);
  183.                     // returns kODFalse if not found.
  184. //    void        DeleteAll();
  185.  
  186.     ~SETransactionList();
  187.   private:
  188.     LinkedList    fList;
  189. };
  190.  
  191. struct PreHandlerInfo
  192. {
  193.   public:
  194.     PreHandlerInfo(ODSemanticInterface* face, ODULong refCon)
  195.                         {fSemanticInterface = face; fRefCon = refCon;}
  196.  
  197.     ODSemanticInterface*    GetSemanticInterface()
  198.                                     {return fSemanticInterface;}
  199.     ODULong                        GetRefCon() {return fRefCon;}
  200.   private:
  201.     ODSemanticInterface*    fSemanticInterface;
  202.     ODULong                        fRefCon;
  203. };
  204.  
  205. //==============================================================================
  206. // Function Prototype
  207. //==============================================================================
  208.  
  209. static ODSShort GetReturnID(AppleEvent* ae);
  210. static ODBoolean SentToSelf(AppleEvent* ae);
  211. static ODPart* GetTokenPart( Environment* ev, ODNameResolver* resolver,
  212.         AEDesc* token );
  213. static pascal OSErr HandleAllSEvents(    AppleEvent* message,
  214.                                         AppleEvent* reply,
  215.                                         long refCon);
  216. static pascal OSErr HandleReplies(    AppleEvent* message,
  217.                                     AppleEvent* reply,
  218.                                     long refCon);
  219. static pascal OSErr HandleGetAETE(    AppleEvent* message,
  220.                                     AppleEvent* reply,
  221.                                     long refCon);
  222. static pascal OSErr HandleAllCoercions(    const AEDesc*    theAEDesc,
  223.                                         DescType        toType,
  224.                                         long            refCon,
  225.                                         AEDesc*            retDesc);
  226. static pascal OSErr HandlePreDispatch(    AppleEvent* message,
  227.                                         AppleEvent* reply,
  228.                                         long refCon);
  229. static void PlaceEmptyListIntoReply(AppleEvent* reply);
  230. static void CreateSubjectObject(Environment* ev, ODFrame* frame, AEDesc* objSpec);
  231.  
  232.  
  233. //==============================================================================
  234. // SETransactionList
  235. //==============================================================================
  236.  
  237. //------------------------------------------------------------------------------
  238. // SETransactionList::Add
  239. //------------------------------------------------------------------------------
  240.  
  241. void SETransactionList::Add(ODPart* part, ODSShort returnID)
  242. {
  243.     SETransactionLink* aLink = new SETransactionLink(part, returnID);
  244.     if (!aLink)
  245.         THROW(kODErrOutOfMemory);
  246.     fList.AddLast(aLink);
  247. }
  248.  
  249. //------------------------------------------------------------------------------
  250. // SETransactionList::Remove
  251. //
  252. //    Do I really need to match both things? How about only the returnID?
  253. //------------------------------------------------------------------------------
  254.  
  255. void SETransactionList::Remove(ODPart* part, ODSShort returnID)
  256. {
  257.     LinkedListIterator iter(&fList);
  258.  
  259.     SETransactionLink* aLink = (SETransactionLink*)iter.First();
  260.     while (aLink != NULL)
  261.     {
  262.         if ((aLink->fPart == part) && (aLink->fReturnID) == returnID)
  263.         {
  264.             fList.Remove(*aLink);
  265.             delete aLink;
  266.             break;
  267.         }
  268.         else
  269.             aLink = (SETransactionLink*)iter.Next();
  270.     }
  271. }
  272.  
  273. //------------------------------------------------------------------------------
  274. // SETransactionList::Find
  275. //------------------------------------------------------------------------------
  276.  
  277. ODBoolean SETransactionList::Find(ODSShort returnID, ODPart** part)
  278. {
  279.     LinkedListIterator iter(&fList);
  280.  
  281.     SETransactionLink* aLink = (SETransactionLink*)iter.First();
  282.     while (aLink != NULL)
  283.     {
  284.         if (aLink->fReturnID == returnID)
  285.         {
  286.             *part = aLink->fPart;
  287.             return kODTrue;
  288.         }
  289.         else
  290.             aLink = (SETransactionLink*)iter.Next();
  291.     }
  292.     return kODFalse;
  293. }
  294.  
  295. //------------------------------------------------------------------------------
  296. // SETransactionList::DeleteAll (Copied from OrderedCollection::DeleteAll)
  297. //------------------------------------------------------------------------------
  298. // This is a no-op now that value isn't being deleted (which it never should
  299. // have been.)  So we just call the destructor instead.
  300. #if 0
  301. void SETransactionList::DeleteAll()
  302. {
  303.     Link* link;    // = fList.RemoveFirst();
  304.     while ((link = fList.RemoveFirst()) != kODNULL)
  305.     {
  306.         ElementType value = ((ValueLink*) link)->GetValue();
  307. //        delete value;        // <eeh> no value was allocated by Add.  This is
  308.                             // an ODPartWrapper* that may have a refcount > 0.
  309.                             // And if I'm right that we should not delete value,
  310.                             // then this whole method can be replaced with a call:
  311.                             // fList.DeleteAllLinks();
  312.         delete link;
  313. //        link = fList.RemoveFirst();
  314.     }
  315. }
  316. #endif
  317.  
  318. //------------------------------------------------------------------------------
  319. // SETransactionList::~SETransactionList
  320. //------------------------------------------------------------------------------
  321.  
  322. SETransactionList::~SETransactionList()
  323. {
  324.     fList.DeleteAllLinks();
  325. }
  326.  
  327. //==============================================================================
  328. // ODMessageInterface
  329. //==============================================================================
  330.  
  331. //------------------------------------------------------------------------------
  332. // ODMessageInterface::InitMessageInterface
  333. //------------------------------------------------------------------------------
  334.  
  335. SOM_Scope void  SOMLINK ODMessageInterfaceInitMessageInterface(ODMessageInterface *somSelf, Environment *ev,
  336.         ODSession* session)
  337. {
  338.     SOM_TRY
  339.  
  340.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  341.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceInitMessageInterface");
  342.  
  343.     /* Moved from somInit. SOM itself sets fields to zero
  344.     _fPreHandlers = kODNULL;
  345.     _fTransactionList = kODNULL;
  346.     _fSession = kODNULL;
  347.     _fNameResolver = kODNULL;
  348.     _fDefaultSI = kODNULL;
  349.     */
  350.     _fNextReturnID = 1;
  351.     somSelf->InitObject(ev);
  352.  
  353.     gMessageInterface = somSelf; // FOR THE PREHANDLER PROC THAT DOESN'T HAVE A
  354.                                  //    REFCON.
  355.  
  356.     _fSession = session;
  357.     _fNameResolver = _fSession->GetNameResolver(ev);
  358.     _fTransactionList = new SETransactionList;
  359.     _fPreHandlers = new OrderedCollection;
  360.  
  361.     DefaultAccessorSI* face = new DefaultAccessorSI();
  362. //    SIHelper* help = new SIHelper();
  363. //    help->InitSIHelper(face);
  364. //    face->InitCPlusSemanticInterface(ev, kODAppShell, help, _fSession);
  365.     face->InitCPlusSemanticInterface(ev, kODAppShell, kODNULL, _fSession);
  366.     _fDefaultSI = face;
  367.  
  368.     
  369.     THROW_IF_ERROR(AEInstallEventHandler(typeWildCard, typeWildCard,
  370.                     NewAEEventHandlerProc(HandleAllSEvents),
  371.                     (long)somSelf, ! kIsSysHandler));
  372.     
  373.     THROW_IF_ERROR(AEInstallEventHandler(kCoreEventClass, kAEAnswer,
  374.                     NewAEEventHandlerProc(HandleReplies),
  375.                     (long)somSelf, ! kIsSysHandler));
  376.     
  377.     THROW_IF_ERROR(AEInstallEventHandler(kASAppleScriptSuite, kGetAETE,
  378.                     NewAEEventHandlerProc(HandleGetAETE),
  379.                     (long)somSelf, ! kIsSysHandler));
  380.     
  381.     THROW_IF_ERROR(AEInstallSpecialHandler(keyPreDispatch,
  382.                     (UniversalProcPtr)NewAEEventHandlerProc(HandlePreDispatch),
  383.                     ! kIsSysHandler));
  384.     
  385.     THROW_IF_ERROR(AEInstallCoercionHandler(typeWildCard, typeWildCard,
  386.                     (AECoercionHandlerUPP)NewAECoerceDescProc(HandleAllCoercions),
  387.                     (long)somSelf, kFromTypeIsDesc, ! kIsSysHandler));
  388.  
  389.     SOM_CATCH_ALL
  390.     SOM_ENDTRY
  391. }
  392.  
  393. //------------------------------------------------------------------------------
  394. // ODMessageInterface::somUninit
  395. //------------------------------------------------------------------------------
  396.  
  397. SOM_Scope void  SOMLINK ODMessageInterfacesomUninit(ODMessageInterface *somSelf)
  398. {
  399.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  400.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfacesomUninit");
  401.  
  402.     Environment*     ev = somGetGlobalEnvironment ();
  403.  
  404.     ODDeleteObject( _fTransactionList );
  405.     
  406.     if (_fPreHandlers)
  407.     {
  408.         _fPreHandlers->DeleteAll();
  409.         ODDeleteObject( _fPreHandlers );
  410.     }
  411.     
  412.     ODReleaseObject(ev, _fDefaultSI);
  413. }
  414. #if 0
  415. //------------------------------------------------------------------------------
  416. // ODMessageInterface::Purge
  417. //------------------------------------------------------------------------------
  418.  
  419. SOM_Scope ODSize  SOMLINK ODMessageInterfacePurge(ODMessageInterface *somSelf, Environment *ev,
  420.         ODSize size)
  421. {
  422. //    ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  423.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfacePurge");
  424.  
  425.     ODSize purged = 0; ODVolatile( purged );
  426.  
  427.     SOM_TRY
  428.         purged = ODMessageInterface_parent_ODObject_Purge(somSelf,ev,size);
  429.     SOM_CATCH_ALL
  430.         WARN("Error %ld trying to purge in ODMessageInterfacePurge",ErrorCode());
  431.         SetErrorCode(kODNoError);        // Eat the exception; Purge should not 
  432.                                         // propagate it because clients function
  433.                                         // fine whether memory was purged or not.
  434.         // dh - Also removed zeroing of purge total if an exception was thrown.
  435.         // The number should be accurate regardless of exceptions because of
  436.         // the initializer of the counter.
  437.     SOM_ENDTRY
  438.     
  439.     return purged;
  440. }
  441. #endif /* 0 */
  442. //------------------------------------------------------------------------------
  443. // ODMessageInterface::CreateEvent
  444. //------------------------------------------------------------------------------
  445.  
  446. SOM_Scope ODSShort  SOMLINK ODMessageInterfaceCreateEvent(ODMessageInterface *somSelf, Environment *ev,
  447.         ODEventClass theAEEventClass,
  448.         ODEventID theAEEventID,
  449.         ODAddressDesc* target,
  450.         ODSLong transactionID,
  451.         ODAppleEvent** result)
  452. {
  453.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  454.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceCreateEvent");
  455.  
  456.     OSErr        error;
  457.     ODSShort    retVal = 0;
  458.  
  459.     SOM_TRY
  460.         // TO BE ABSOLUTELY CORRECT, I SHOULD CHECK THAT THE RETURN ID I'M USING IS
  461.         //    NOT IN THE _fTransactionList. HOWEVER, IS THIS OVERKILL? -- Yes.
  462.         AppleEvent        newEvent;
  463.     
  464.         AEAddressDesc    targetAsAEDesc;
  465.         error = ODDescToAEDesc( target, &targetAsAEDesc );
  466.     
  467.         if ( !error )
  468.         {
  469.             error = AECreateAppleEvent(theAEEventClass, theAEEventID,
  470.                                                 &targetAsAEDesc,
  471.                                                 _fNextReturnID, transactionID,
  472.                                                 &newEvent);
  473.             AEDisposeDesc(&targetAsAEDesc);
  474.         }
  475.     
  476.         if ( !error )
  477.         {    // stick it in the event
  478.             ODAppleEvent* coverEvent = new ODAppleEvent();
  479.             THROW_IF_NULL(coverEvent);
  480.             coverEvent->InitODAppleEvent(ev);
  481.             error = AEDescToODDesc( &newEvent, coverEvent );
  482.             ODDisposeAppleEvent(&newEvent);
  483.             if ( !error )
  484.                 *result = coverEvent;
  485.             else
  486.             {
  487.                 ODDeleteObject(coverEvent);
  488.                 *result = kODNULL;
  489.             }
  490.         }
  491.     
  492.         THROW_IF_ERROR (error);
  493.     
  494.         retVal = _fNextReturnID++;
  495.     SOM_CATCH_ALL
  496.     SOM_ENDTRY
  497.  
  498.     return retVal;
  499. }
  500.  
  501. //------------------------------------------------------------------------------
  502. // ODMessageInterface::Send
  503. //------------------------------------------------------------------------------
  504.  
  505. SOM_Scope void  SOMLINK ODMessageInterfaceSend(ODMessageInterface *somSelf, Environment *ev,
  506.         ODFrame* toFrame,
  507.         ODPart* fromPart,
  508.         ODAppleEvent* theAppleEvent,
  509.         ODAppleEvent* reply,
  510.         ODSendMode sendMode,
  511.         ODSendPriority sendPriority,
  512.         ODULong timeOutInTicks)
  513. {
  514.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  515.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceSend");
  516.  
  517.     // MIGHT CHECK WHETHER WE'RE SENDING IN THE SAME PROCESS. THEN WE CAN
  518.     //    AVOID THE APPLEEVENT MANAGER ALTOGETHER PERHAPS!!!!
  519.     AppleEvent                realEvent = NULL_DESCRIPTOR_DEFINITION;
  520.     AppleEvent                realReply = NULL_DESCRIPTOR_DEFINITION;
  521.     OSErr                    result;
  522.     ODSShort                returnID;
  523.     ODBoolean                isCurrentProcess;
  524.  
  525.     SOM_TRY
  526.         THROW_IF_ERROR( ODDescToAEDesc(theAppleEvent, &realEvent ));
  527. //        THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply ));
  528.  
  529.         // add subject attribute
  530.         if (toFrame)
  531.         {
  532.             AEDesc    subj = NULL_DESCRIPTOR_DEFINITION;
  533.             CreateSubjectObject(ev, toFrame, &subj);
  534.             THROW_IF_ERROR( AEPutAttributeDesc(&realEvent, keySubjectAttr, &subj) );
  535.             AEDisposeDesc(&subj);
  536.         }
  537.     
  538.         TRY
  539.             returnID = GetReturnID(  &realEvent );
  540.         CATCH_ALL
  541.             returnID = _fNextReturnID++;
  542.         ENDTRY
  543.         _fTransactionList->Add(fromPart, returnID);
  544.  
  545.         // $$$$$ CURRENTLY, THIS DOES NOT RETURN THE CORRECT RESULT. THEREFORE,
  546.         //    THE "if" WILL ONLY BE ENTERED IF THE CALLING PART SPECIFIES
  547.         //    kCurrentProcess IN THE ADDRESS DESCRIPTOR AND kAEQueueReply. THERE
  548.         //    ARE NO TEST CASES FOR THIS THAT I KNOW OF, HOWEVER.
  549.         isCurrentProcess = SentToSelf( &realEvent );
  550.     
  551.         if ((sendMode == kAEQueueReply) && isCurrentProcess)
  552.         {
  553.             // WORK AROUND CONDITION THAT REPLY HANDLER IS NOT CALLED IF SENDING
  554.             //    IN THE SAME PROCESS. DO WE HAVE TO DO THIS? PEOPLE SHOULD ALREADY
  555.             //    EXPECT IT. MAYBE WE LET THE USUAL THING HAPPEN FOR A PART SENDING
  556.             //    TO ITSELF AND DO THE MAGIC IF THE SENDER AND RECEIVER PARTS ARE
  557.             //    DIFFERENT!!!!
  558.             result = AESend(&realEvent, &realReply,
  559.                             kAEWaitReply, sendPriority,
  560.                             timeOutInTicks, (AEIdleUPP)kODNULL,
  561.                             (AEFilterUPP)kODNULL);
  562.     
  563.             if (result == noErr)
  564.                     // <eeh> is this right?
  565.                     result = somSelf->DispatchToEventHandler(ev, &realReply,
  566.                             nil, fromPart, kODNULL);
  567.             _fTransactionList->Remove(fromPart, returnID);
  568.         }
  569.         else
  570.         {
  571.             result = AESend(&realEvent, &realReply,
  572.                             sendMode, sendPriority,
  573.                             timeOutInTicks, (AEIdleUPP)kODNULL,
  574.                             (AEFilterUPP)kODNULL);
  575.     
  576.             if ((sendMode & kAEWaitReply != 0)
  577.                         || (sendMode == kAENoReply)
  578.                         || (result != noErr))
  579.                 _fTransactionList->Remove(fromPart, returnID);
  580.         }
  581.     
  582.         //    UPDATE REPLY FOR CALLER
  583.         THROW_IF_ERROR(AEDescToODDesc(&realReply, reply));
  584. #ifdef TO_BE_DELETED
  585.         if (realReply.descriptorType != typeNull
  586.                 && realReply.dataHandle != kODNULL)
  587.         {
  588.             AEDesc    tempDesc;
  589.             OSErr    tempErr;
  590.             tempErr = AEGetParamDesc(&realReply, keyDirectObject, typeWildCard,
  591.                                         &tempDesc);
  592.             if (!tempErr)
  593.                 AEDisposeDesc(&tempDesc);
  594.         }
  595. #endif
  596.         THROW_IF_ERROR (result);
  597.     SOM_CATCH_ALL
  598.     SOM_ENDTRY
  599.  
  600.     ODDisposeAppleEvent(&realReply);
  601.     ODDisposeAppleEvent(&realEvent);
  602. }
  603.  
  604. //------------------------------------------------------------------------------
  605. // ODMessageInterface::ProcessSemanticEvent
  606. //------------------------------------------------------------------------------
  607.  
  608. SOM_Scope ODBoolean  SOMLINK ODMessageInterfaceProcessSemanticEvent(ODMessageInterface *somSelf, Environment *ev,
  609.         ODEventData* theEvent)
  610. {
  611. //    ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  612.     ODMessageInterfaceMethodDebug("ODMessageInterface","ProcessSemanticEvent");
  613.  
  614.     return ! AEProcessAppleEvent((const EventRecord*)theEvent);
  615. }
  616.  
  617. //------------------------------------------------------------------------------
  618. // HandleAllSEvents
  619. //------------------------------------------------------------------------------
  620.  
  621. static pascal OSErr HandleAllSEvents(AppleEvent* message,
  622.                                                         AppleEvent* reply,
  623.                                                         long refCon)
  624. {
  625.     ODMessageInterface* self = (ODMessageInterface*)refCon;
  626.  
  627.     return self->HandleAllSEventsAux(somGetGlobalEnvironment(),
  628.                                         message,
  629.                                         reply);
  630. }
  631.  
  632. //------------------------------------------------------------------------------
  633. // ODMessageInterface::HandleAllSEventsAux
  634. //
  635. //    If there's an object specifier in the direct parameter, we use it to find
  636. //    out to whom to send the event.
  637. //
  638. //    Rework flow of control!!!!
  639. //
  640. //    Since it's a private method, I'm not using SOM exceptions for now.
  641. //------------------------------------------------------------------------------
  642.  
  643. SOM_Scope OSErr  SOMLINK ODMessageInterfaceHandleAllSEventsAux(ODMessageInterface *somSelf, Environment *ev,
  644.         AppleEvent* message,
  645.         AppleEvent* reply)
  646. {
  647.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  648.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceHandleAllSEventsAux");
  649. //DebugStr("\pOK. Here we are.");
  650.  
  651.     OSErr                result;
  652.     AEDesc                theObject;
  653.     OSLToken            tokenAsAEDesc = NULL_DESCRIPTOR_DEFINITION;
  654.     ODBoolean            doResolution = kODFalse;
  655.     ODBoolean            gotSubject = kODFalse;
  656.     ODPart*                destinationPart = kODAppShell;
  657.     ODBoolean            haveValidObject = kODFalse;
  658.  
  659. #if ODDebug
  660.     // just so I can see what event I'm dealing with in the debugger
  661.     ODDescType            debugEventClass;
  662.     ODDescType            debugEventID;
  663.     ODSLong                debugSize;
  664.     ODDescType            debugType;
  665.     
  666.     AEGetAttributePtr(message, keyEventClassAttr,
  667.                                 typeType, &debugType, (Ptr)&debugEventClass,
  668.                                 sizeof(debugEventClass), &debugSize);
  669.     AEGetAttributePtr(message, keyEventIDAttr,
  670.                                 typeType, &debugType, (Ptr)&debugEventID,
  671.                                 sizeof(debugEventID), &debugSize);
  672.     LOG("event %4.4s%4.4s\n", &debugEventClass,  &debugEventID);
  673. #endif
  674.  
  675.         
  676.     // Reset these, because I might be examining them real soon.
  677. //    _fNameResolver->SetLastContainer(ev, typeNull);
  678. //    _fNameResolver->SetLastObject(ev, typeNull);
  679. //    _fNameResolver->ClearLastSwapFrame(ev) ;
  680. //DebugStr("\pStart event handler;ht;g");
  681.     TRY
  682.         _fNameResolver->NeedContextCache(ev, kODTrue);
  683.  
  684.         // SEE IF WE HAVE TO SPECIAL CASE THIS EVENT
  685. //        if (somSelf->HandleSpecialEvents(ev, message, reply, &result))
  686. //            return result;
  687.     
  688.         result = AEGetParamDesc(message, keyDirectObject,
  689.                                 typeWildCard,
  690.                                 &theObject);
  691.         if (!result)
  692.             haveValidObject = kODTrue;
  693.         // IF WE HAVE AN OBJECT SPECIFIER IN THE DIRECT OBJECT, USE IT TO FIND
  694.         //    PART TO DISPATCH TO.
  695.         // BUT CHECK FOR SPECIAL OBJECT SPECIFIER
  696.         if (!result && (theObject.descriptorType == typeObjectSpecifier))
  697.         {
  698.             DescType    gotType;
  699.             DescType    desiredPartSize = sizeof(ODPart*);
  700.             DescType    desiredDescSize = sizeof(DescType);
  701.             DescType    gotSize;
  702.             DescType    keyForm;
  703.             ODPart*    thePart;
  704.             AEDesc        objSpecCopy;
  705.             AEDesc        objSpecAsRecord;
  706.     
  707. //            DebugStr("\pgot it.");
  708.             // IS IT ONE OF OUR SPECIAL OBJECT SPECIFIERS?
  709.             THROW_IF_ERROR(AEDuplicateDesc(&theObject, &objSpecCopy));
  710.             result = AECoerceDesc(&objSpecCopy, typeAERecord, &objSpecAsRecord);
  711.             if (!result)
  712.             {
  713.                 result = AEGetKeyPtr(&objSpecAsRecord, keyAEKeyForm,
  714.                                         typeEnumerated, &gotType, &keyForm,
  715.                                         desiredDescSize, (long*)&gotSize);
  716.                 if (!result && (gotType == typeEnumerated)
  717.                         && (gotSize == desiredDescSize) && (keyForm == cPart))
  718.                 {
  719.                     result = AEGetKeyPtr(&objSpecAsRecord, keyAEKeyData,
  720.                                             typeLongInteger, &gotType, &thePart,
  721.                                             desiredPartSize, (long*)&gotSize);
  722.                     if (!result && (gotType == typeLongInteger)
  723.                             && (gotSize == desiredPartSize))
  724.                         destinationPart = thePart;
  725.                     else
  726.                         doResolution = kODTrue;
  727.                 }
  728.                 else
  729.                     doResolution = kODTrue;
  730.             }
  731.             else
  732.                 doResolution = kODTrue;
  733.     
  734.             AEDisposeDesc(&objSpecCopy);
  735.             AEDisposeDesc(&objSpecAsRecord);
  736.         }
  737.         else
  738.         {
  739.             // NO DIRECT OBJECT, BUT HAVE A SUBJECT ATTRIBUTE, USE IT TO FIND
  740.             //    PART TO DISPATCH TO.
  741.             AEDesc theSubject = NULL_DESCRIPTOR_DEFINITION;
  742.             result = AEGetAttributeDesc(message,
  743.                                         keySubjectAttr, typeWildCard,
  744.                                         &theSubject);
  745.     
  746.             if (!result && (theSubject.descriptorType == typeObjectSpecifier))
  747.             {
  748.                 theObject = theSubject;
  749.                 doResolution = kODTrue;
  750.                 gotSubject = kODTrue;
  751.                 haveValidObject = kODTrue;
  752.             }
  753.             else
  754.                 AEDisposeDesc(&theSubject);
  755.         }
  756.  
  757.         if (doResolution)
  758.         {
  759.             OSErr    error = noErr;
  760.             ODObjectSpec* objWrapper = new ODObjectSpec();
  761.             THROW_IF_NULL(objWrapper);
  762.             objWrapper->InitODObjectSpec(ev);
  763.             ODOSLToken* theToken = new ODOSLToken();
  764.             THROW_IF_NULL(theToken);
  765.             theToken->InitODOSLToken(ev);
  766.  
  767.             TRY
  768.                 THROW_IF_ERROR( AEDescToODDesc(&theObject, objWrapper ) );
  769.  
  770.                 theToken->SetDescType(ev, typeNull);
  771.                 
  772.                 _fNameResolver->Resolve(ev, objWrapper, theToken, kODAppShell);
  773.                 THROW_IF_ERROR(ODDescToAEDesc(theToken, &tokenAsAEDesc));
  774.  
  775.             CATCH_ALL
  776.                 result = ErrorCode();
  777.             ENDTRY
  778.             ODDeleteObject( objWrapper );
  779.             if ( !result )
  780.             {
  781.                 result = somSelf->DispatchEventWithToken(ev, &tokenAsAEDesc,
  782.                         message, reply, gotSubject, kODFalse);
  783.                 // DispatchEventWithToken may have modified the token.  Copy
  784.                 // into the ODDesc that will be passed to DisposeToken.
  785.                 THROW_IF_ERROR( AEDescToODDesc( &tokenAsAEDesc, theToken ));
  786.                 AEDisposeDesc(&tokenAsAEDesc);
  787.             }
  788.             if (theToken)
  789.                 _fNameResolver->DisposeToken(ev, theToken);
  790.         }
  791.         else if ( theObject.descriptorType == typeUserToken )
  792.         {
  793.             result = somSelf->DispatchEventWithToken(ev, &theObject,
  794.                     message, reply, gotSubject, kODTrue );
  795.         }
  796.         else
  797.             // SEND TO THE DESTINATION DIRECTLY
  798.             result = somSelf->DispatchToEventHandler(ev, message, reply,
  799.                                             destinationPart, kODNULL );
  800.     CATCH_ALL
  801.         result = ErrorCode();
  802.         if (haveValidObject)
  803.             AEDisposeDesc(&theObject);
  804.     ENDTRY
  805.  
  806.     if (haveValidObject)
  807.         AEDisposeDesc(&theObject);
  808.  
  809.     _fNameResolver->NeedContextCache(ev, kODFalse);
  810.     _fNameResolver->FlushContextCache(ev);
  811. //DebugStr("\p with event handler;ht");
  812.     return result;
  813. }    // HandleAllSEventsAux
  814.  
  815. //------------------------------------------------------------------------------
  816. // ODMessageInterface::DispatchEventWithToken
  817. //
  818. //    Recursive routine to deal with list tokens whose items might be other
  819. //    lists. But should we stop dispatching if we get an error????
  820. //
  821. //    Need to clean up flow of control here.
  822. //
  823. //    Since it's a private method, I'm not using SOM exceptions for now.
  824. //------------------------------------------------------------------------------
  825.  
  826. SOM_Scope OSErr  SOMLINK ODMessageInterfaceDispatchEventWithToken(ODMessageInterface *somSelf, Environment *ev,
  827.         OSLToken* token,
  828.         AppleEvent* message,
  829.         AppleEvent* reply,
  830.         ODBoolean usingSubjectAttr,
  831.         ODBoolean dpAlreadyToken)
  832. {
  833.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  834.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceDispatchEventWithToken");
  835.  
  836.     OSErr        error = noErr;
  837.     ODBoolean    handledEventRightHere = kODFalse;
  838.     
  839.     // WE USED TO UNPACK ALL LISTS, EVEN THOSE CREATED BY A PART EDITOR. NOW
  840.     //    WE ONLY NEED TO DEAL WITH LISTS IF THE OSL CREATES THEM ITSELF.
  841.     //    UNFORTUNATELY, I'M NOT SURE WHAT THE RIGHT THING TO DO IS. IF WE UNPACK
  842.     //    THE  LIST AND MULTICAST OURSELVES, WE COULD END UP WITH MULTIPLE EVENTS
  843.     //    WHEN ONLY ONE WAS APPROPRIATE. NEED TO CONFER WITH KURT. -NP 5/19/95
  844.     if (token->descriptorType == typeAEList)
  845.     {
  846.         AEDesc        embeddedToken;
  847.         ODSLong        itemCount;
  848.         AEKeyword    returnedKeyWord;
  849.         ODFrame*    prevFrame;
  850.         ODFrame*    thisFrame;
  851.         ODPart*        prevPart;
  852.         ODPart*        thisPart;
  853.  
  854.         #if ODDebug
  855. //            ASSERTM(kODFalse, errAEEventNotHandled, "ODMessageInterfaceDispatchEventWithToken: Handling of lists returned by OSL not yet implemented.");
  856.         #else        
  857. //            DebugStr("\pHandling of lists returned by OSL not yet implemented.");
  858. //            THROW(errAEEventNotHandled);
  859.         #endif
  860.         THROW_IF_ERROR(AECountItems(token, &itemCount));
  861.  
  862.         // I THINK ALL THE TOKENS IN THE LIST SHOULD HAVE BEEN CREATED IN THE
  863.         //    SAME CONTEXT. FOR NOW, I JUST WANT TO VERIFY THIS IS SO AND RAISE
  864.         //    AN ERROR IF NOT. ALSO VERIFYING THAT ALL DESCRIPTORS IN THE LIST
  865.         //    ARE OPENDOC TOKENS.
  866.         if (itemCount == 0)
  867.         {
  868.             PlaceEmptyListIntoReply(reply);
  869.             handledEventRightHere = kODTrue;
  870.         }
  871.         else
  872.         {
  873.             for (ODSLong i = 1; i <= itemCount; i++)
  874.             {
  875.                 THROW_IF_ERROR(AEGetNthDesc(token, i, typeWildCard,
  876.                                             &returnedKeyWord,
  877.                                             &embeddedToken));
  878.     
  879.                 ODOSLToken*    odToken = new ODOSLToken;
  880.                 THROW_IF_NULL(odToken);
  881.                 odToken->InitODOSLToken(ev);
  882.                 THROW_IF_ERROR( AEDescToODDesc(&embeddedToken, odToken ) );
  883.                 AEDisposeDesc(&embeddedToken);
  884.     
  885.                 // SANITY CHECKING
  886.                 if (!_fNameResolver->IsODToken(ev, odToken))
  887.                 {
  888.                     delete odToken;
  889.                     ASSERTM(kODFalse, errAEEventNotHandled, "ODMessageInterfaceDispatchEventWithToken: Found descriptor that was not an OpenDoc token while handling list.");
  890.                 }
  891.     
  892.                 _fNameResolver->GetContextFromToken(ev, odToken, &thisPart,
  893.                                                     &thisFrame);
  894.                 if (i > 1)
  895.                 {
  896.                     // SANITY CHECKING
  897.                     if (thisPart != prevPart || thisFrame != prevFrame)
  898.                         ASSERTM(kODFalse, errAEEventNotHandled, "ODMessageInterfaceDispatchEventWithToken: Not all tokens of list came from same place.");
  899.                 }
  900.                 prevPart = thisPart;
  901.                 prevFrame = thisFrame;
  902.  
  903.                 ODDeleteObject(odToken);
  904.             }
  905.  
  906.             ODDesc*    userODToken = new ODDesc;
  907.             THROW_IF_NULL(userODToken);
  908.             userODToken->InitODDesc(ev);
  909.             AEDescToODDesc(token, userODToken);
  910.             OSLDisposeToken(token);
  911.             
  912.             _fNameResolver->CreateNewODOSLToken(ev, token, userODToken,
  913.                                                 thisPart, thisFrame);
  914.         }
  915.     }
  916.  
  917.     if (!handledEventRightHere)
  918.     {
  919.         ODPart* contextPart = _fNameResolver->GetPartFromToken(ev, token);
  920.         
  921.         if ( !dpAlreadyToken && !usingSubjectAttr )
  922.             THROW_IF_ERROR(AEPutParamDesc(message,
  923.                                             keyDirectObject,
  924.                                             token));
  925.  
  926.         error =  somSelf->DispatchToEventHandler(ev, message, reply,
  927.                 contextPart, token);
  928.     }
  929.  
  930.     return error;
  931. }
  932.  
  933. //------------------------------------------------------------------------------
  934. // PlaceEmptyListIntoReply
  935. //
  936. //    Place an empty AE list into a reply as the direct parameter.
  937. //------------------------------------------------------------------------------
  938.  
  939. static void PlaceEmptyListIntoReply(AppleEvent* reply)
  940. {
  941.     AEDesc            emptyList;
  942.     const Boolean    kCreateListNotRecord = kODFalse;
  943.  
  944.     THROW_IF_ERROR(AECreateList(kODNULL, 0, kCreateListNotRecord, &emptyList));
  945.     THROW_IF_ERROR(AEPutParamDesc(reply, keyDirectObject, &emptyList));
  946.     AEDisposeDesc(&emptyList);
  947. }
  948.  
  949. #if 0
  950. //------------------------------------------------------------------------------
  951. // ODMessageInterface::HandleSpecialEvents
  952. //
  953. //    Special case some events, like recording events, etc.
  954. //    Return kODTrue if handled the event, kODFalse, if not.
  955. //
  956. //    Since it's a private method, I'm not using SOM exceptions for now.
  957. //------------------------------------------------------------------------------
  958.  
  959. SOM_Scope ODBoolean  SOMLINK ODMessageInterfaceHandleSpecialEvents(ODMessageInterface *somSelf, Environment *ev,
  960.         AppleEvent* message,
  961.         AppleEvent* reply,
  962.         OSErr* error)
  963. {
  964.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  965.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceHandleSpecialEvents");
  966.  
  967.     ODUnused(reply);
  968.  
  969.     ODBoolean    result = kODFalse;
  970.     DescType    eventClass;
  971.     DescType    eventID;
  972.     DescType    actualType;
  973.     Size        maxSize = sizeof(DescType);
  974.     Size        actualSize;
  975.  
  976.     *error = noErr;
  977.     *error = AEGetAttributePtr(message, keyEventClassAttr,
  978.                                 typeType, &actualType, (Ptr)&eventClass,
  979.                                 maxSize, &actualSize);
  980.     if (error || actualType != typeType || actualSize != maxSize)
  981.         return result;
  982.     *error = AEGetAttributePtr(message, keyEventIDAttr,
  983.                                 typeType, &actualType, (Ptr)&eventID, maxSize,
  984.                                 &actualSize);
  985.     if (error || actualType != typeType || actualSize != maxSize)
  986.         return result;
  987.  
  988.     switch (eventClass)
  989.     {
  990.         case kCoreEventClass:
  991.             switch (eventID)
  992.             {
  993.                 // SEND THESE TO ALL RUNNING PARTS THAT HAVE A HANDLER FOR THIS
  994.                 case kAENotifyStartRecording:
  995.                     result = kODTrue;
  996.                     break;
  997.                 case kAENotifyStopRecording:
  998.                     result = kODTrue;
  999.                     break;
  1000.             }
  1001.             break;
  1002.         case kOSASuite:
  1003.             switch (eventID)
  1004.             {
  1005.                 // SEND THESE TO ALL RUNNING PARTS THAT HAVE A HANDLER FOR THIS
  1006.                 case kOSARecordedText:
  1007.                     result = kODTrue;
  1008.                     break;
  1009.             }
  1010.             break;
  1011.     }
  1012.     
  1013.     return result;
  1014. }
  1015. #endif /* 0 */
  1016. //------------------------------------------------------------------------------
  1017. // ODMessageInterface::DispatchToEventHandler
  1018. //
  1019. //    Since it's a private method, I'm not using SOM exceptions for now.
  1020. //------------------------------------------------------------------------------
  1021.  
  1022. SOM_Scope OSErr  SOMLINK ODMessageInterfaceDispatchToEventHandler(ODMessageInterface *somSelf, Environment *ev,
  1023.         AppleEvent* message,
  1024.         AppleEvent* reply,
  1025.         ODPart* contextPart,
  1026.         AEDesc* realToken )
  1027. {
  1028.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1029.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceDispatchToEventHandler");
  1030.  
  1031. //    FN_CATCH return (OSErr)ErrorCode();        // Not SOM_CATCH: we don't want to set ev!
  1032.  
  1033.     // * SET THE CURRENT CONTEXT SO THAT COERCIONS ARE HANDLED CORRECTLY
  1034.     ODPart* savedPart = _fNameResolver->GetCurrentContextPart(ev);
  1035.     _fNameResolver->SetCurrentContextPart(ev, contextPart);
  1036.  
  1037.     // <eeh> optimization note: calling GetTokenPart in the recursive case
  1038.     // is stupid since the result will always be the same as before.  It
  1039.     // would be better to pass the ODPart* itself.  But no time now.
  1040.     // On later consideration, I don't think this makes sense.  The recursive
  1041.     // case is fairly rare and I don't think it's worth the extra calls to
  1042.     // pass in default values (or null) from the other places DispatchToEventHandler
  1043.     // is called just to avoid this one.  Plus there's no way to avoid adding
  1044.     // another parameter to this method.
  1045.  
  1046.     ODPart* partFromStdToken = GetTokenPart( ev, _fNameResolver, realToken );
  1047.     ODBoolean tokenFromDefault
  1048.             = realToken? _fNameResolver->TokenIsDefault(ev, realToken):kODFalse;
  1049.     OSErr result = somSelf->DispatchToEventHandlerAux(ev, message, reply,
  1050.             contextPart, tokenFromDefault, partFromStdToken!=kODNULL );
  1051.  
  1052.     // If we got back errAEEventNotHandled, two things could be wrong in
  1053.     // addition to the usual case where the part that should have gotten
  1054.     // the event got it and couldn't handle it.  One possibility is that
  1055.     // the event should have gone to the root part but went to the shell,
  1056.     // which barfed.  This will happen when there's no direct parameter,
  1057.     // and hence no resolution (with swapping) has taken place.  So we
  1058.     // give the root part a chance.  The second possibility is that the
  1059.     // event should have gone to an embedded part (eg.: tell part 1 to
  1060.     // play part 1) but went to the container, which couldn't handle it.
  1061.     // In this case we should swap to the embedded part so it can try.
  1062.     // Note that *both* can happen in the course of handling the same
  1063.     // event, so we can get three levels of recursion.  Actually, if the
  1064.     // embedded part fails to handle the event we'll almost get a fourth,
  1065.     // but the swapPart != contextPart test will stop the process.
  1066.  
  1067.     if ( result == errAEEventNotHandled )
  1068.     {
  1069.         TempODPart swapPart = kODNULL;
  1070.         if ( contextPart == kODAppShell )
  1071.         {
  1072.             ODFrame* frame = GetDefaultRootFrameToSwapTo(ev, _fSession);
  1073.             if ( frame )
  1074.                 swapPart = frame->AcquirePart(ev);
  1075.         }
  1076.         else        // this may fail, ie return null, which means don't recurse
  1077.         {
  1078.             if ( (swapPart = partFromStdToken) != kODNULL )
  1079.                 swapPart->Acquire( ev );
  1080.         }
  1081.         if ( swapPart )
  1082.         {
  1083.             if ( !ODObjectsAreEqual(ev, swapPart, contextPart) )
  1084.                 result = somSelf->DispatchToEventHandler( ev, message, reply,
  1085.                         swapPart, realToken );
  1086. //            ODReleaseObject( ev, swapPart );
  1087.         }
  1088.     }
  1089.  
  1090.     // * CAN RESTORE CONTEXT NOW.
  1091.     _fNameResolver->SetCurrentContextPart(ev, savedPart);
  1092.     
  1093.     return result;
  1094. }    // DispatchToEventHandler
  1095.  
  1096. //------------------------------------------------------------------------------
  1097. // ODMessageInterface::DispatchToEventHandlerAux
  1098. //
  1099. //    Since it's a private method, I'm not using SOM exceptions for now.
  1100. //------------------------------------------------------------------------------
  1101.  
  1102.  
  1103. SOM_Scope OSErr  SOMLINK ODMessageInterfaceDispatchToEventHandlerAux(ODMessageInterface *somSelf, Environment *ev,
  1104.         AppleEvent* message,
  1105.         AppleEvent* reply,
  1106.         ODPart* sendee,
  1107.         ODBoolean tokenFromDefault,
  1108.         ODBoolean isStdPartToken)
  1109. {
  1110.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1111.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceDispatchToEventHandlerAux");
  1112.  
  1113.     OSErr                    result = noErr;
  1114.     ODSemanticInterface*    si = kODNULL;            ODVolatile(si);
  1115.  
  1116.     ODVolatile(sendee);
  1117.     ODAppleEvent* msgWrapper;                        ODVolatile(msgWrapper);
  1118.     ODAppleEvent* replyWrapper;                        ODVolatile(replyWrapper);
  1119.  
  1120.  
  1121.     TRY
  1122.         msgWrapper = new ODAppleEvent();
  1123.         THROW_IF_NULL(msgWrapper);
  1124.         msgWrapper->InitODAppleEvent(ev);
  1125.         THROW_IF_ERROR( AEDescToODDesc( message, msgWrapper ) );
  1126.  
  1127.         replyWrapper = new ODAppleEvent();
  1128.         THROW_IF_NULL(replyWrapper);
  1129.         replyWrapper->InitODAppleEvent(ev);
  1130.         THROW_IF_ERROR( AEDescToODDesc( reply, replyWrapper ) );
  1131.  
  1132.         TRY
  1133.             si = _fNameResolver->AcquireSemtIntf(ev, sendee);
  1134.             if (si && (!tokenFromDefault || isStdPartToken ))
  1135.                 si->CallEventHandler(ev, sendee, msgWrapper, replyWrapper);
  1136.             else
  1137.                 result = errAEEventNotHandled;
  1138.         CATCH_ALL
  1139.             result = ErrorCode();
  1140.         ENDTRY
  1141.         
  1142.         if (result == errAEEventNotHandled)    // shell doesn't have default accessors! NP - Huh? 6/21/95
  1143.         {
  1144.             TRY
  1145.                 _fDefaultSI->CallEventHandler(ev, sendee, msgWrapper,
  1146.                                                 replyWrapper);
  1147.                 result = noErr;
  1148.             CATCH_ALL
  1149.                 result = ErrorCode();
  1150.             ENDTRY
  1151.         }
  1152.     CATCH_ALL
  1153.         result = ErrorCode();
  1154.     ENDTRY
  1155.  
  1156.     ODReleaseObject(ev,si);
  1157.  
  1158.     ODDeleteObject(msgWrapper);
  1159.  
  1160.     // THE AE MANAGER REALLY WANTS US TO USE THE REPLY DESCRIPTOR THAT IT
  1161.     //    ALLOCATED. SO WE MUST BLOCKMOVE OUR DATA BACK IN.
  1162.  
  1163.     if (reply->descriptorType != typeNull && reply->dataHandle != kODNULL)
  1164.     {
  1165.         // This code overwrites whatever in the header tells the AEM that
  1166.         // this is a valid reply.  Execute this code and the AEM will dispose
  1167.         // the reply before returning from AESend -- in the send-to-self
  1168.         // case, that is. <eeh>
  1169.  
  1170.         ODByteArray data = replyWrapper->GetRawData(ev);
  1171.         SetHandleSize(reply->dataHandle, data._length);
  1172.         THROW_IF_ERROR(MemError());
  1173.         ODBlockMove(data._buffer, *(reply->dataHandle), data._length);
  1174.         DisposeByteArrayStruct(data);
  1175.     }
  1176.  
  1177.     ODDeleteObject(replyWrapper);
  1178.  
  1179.     return result;
  1180. }
  1181.  
  1182. //------------------------------------------------------------------------------
  1183. // HandleReplies
  1184. //------------------------------------------------------------------------------
  1185.  
  1186. static pascal OSErr HandleReplies(AppleEvent* message,
  1187.                                                         AppleEvent* reply,
  1188.                                                         long refCon)
  1189. {
  1190.     ODMessageInterface* self = (ODMessageInterface*)refCon;
  1191.     OSErr result = noErr ;
  1192.  
  1193.     TRY
  1194.         result = self->HandleRepliesAux(somGetGlobalEnvironment(),
  1195.                                         message,
  1196.                                         reply);
  1197.     CATCH_ALL
  1198.         result = ErrorCode();
  1199.     ENDTRY
  1200.  
  1201.     return result ;
  1202. }
  1203.  
  1204. //------------------------------------------------------------------------------
  1205. // ODMessageInterface::HandleRepliesAux
  1206. //
  1207. //    Since it's a private method, I'm not using SOM exceptions for now.
  1208. //------------------------------------------------------------------------------
  1209.  
  1210. SOM_Scope OSErr  SOMLINK ODMessageInterfaceHandleRepliesAux(ODMessageInterface *somSelf, Environment *ev,
  1211.         AppleEvent* message,
  1212.         AppleEvent* reply)
  1213. {
  1214.  
  1215.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1216.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceHandleRepliesAux");
  1217.  
  1218.     ODPart*                aPart;
  1219.     ODSShort            returnID;
  1220.  
  1221.     returnID = GetReturnID(message);
  1222.     if (!_fTransactionList->Find(returnID, &aPart))
  1223.         return errAEEventNotHandled;
  1224.     if (aPart == NULL)
  1225.         return errAEEventNotHandled;
  1226.     else
  1227.         return somSelf->DispatchToEventHandler(ev, message, reply, aPart,
  1228.                 kODNULL );
  1229. }
  1230.  
  1231. //------------------------------------------------------------------------------
  1232. // HandleAllCoercions
  1233. //------------------------------------------------------------------------------
  1234.  
  1235. static OSErr pascal HandleAllCoercions(const AEDesc* theAEDesc,
  1236.                                         DescType    toType,
  1237.                                         long        refCon,
  1238.                                         AEDesc*        retDesc)
  1239. {
  1240.     ODMessageInterface* self = (ODMessageInterface*)refCon;
  1241.     return self->HandleAllCoercionsAux(somGetGlobalEnvironment(),
  1242.                                         (AEDesc*)theAEDesc,
  1243.                                         toType, retDesc);
  1244. }
  1245.  
  1246. //------------------------------------------------------------------------------
  1247. // ODMessageInterface::HandleAllCoercionsAux
  1248. //
  1249. //    Since it's a private method, I'm not using SOM exceptions for now.
  1250. //------------------------------------------------------------------------------
  1251.  
  1252. SOM_Scope OSErr  SOMLINK ODMessageInterfaceHandleAllCoercionsAux(ODMessageInterface *somSelf, Environment *ev,
  1253.         AEDesc* theAEDesc,
  1254.         ODDescType toType,
  1255.         AEDesc* retDesc)
  1256. {
  1257.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1258.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceHandleAllCoercionsAux");
  1259.  
  1260.     ODPart*    contextPart = _fNameResolver->GetCurrentContextPart(ev);
  1261.  
  1262.     return somSelf->DispatchToCoercionHandler(ev, theAEDesc, toType,
  1263.                                                 contextPart, retDesc);
  1264. }
  1265. #if 0
  1266. #endif /* 0 */
  1267. //------------------------------------------------------------------------------
  1268. // ODMessageInterface::DispatchToCoercionHandler
  1269. //
  1270. //    Since it's a private method, I'm not using SOM exceptions for now.
  1271. //------------------------------------------------------------------------------
  1272.  
  1273. SOM_Scope OSErr  SOMLINK ODMessageInterfaceDispatchToCoercionHandler(ODMessageInterface *somSelf, Environment *ev,
  1274.         AEDesc* theAEDesc,
  1275.         ODDescType toType,
  1276.         ODPart* sendee,
  1277.         AEDesc* retDesc)
  1278. {
  1279.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1280.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceDispatchToCoercionHandler");
  1281.  
  1282.     OSErr                    result = noErr;
  1283.     ODSemanticInterface*    si = kODNULL;                ODVolatile(si);
  1284.     
  1285.     TRY
  1286.         si = _fNameResolver->AcquireSemtIntf(ev, sendee);
  1287.         if (si)
  1288.         {
  1289.             ODDesc* realInDesc = new ODDesc();
  1290.             THROW_IF_NULL(realInDesc);
  1291.             realInDesc->InitODDesc(ev);
  1292.             THROW_IF_ERROR( AEDescToODDesc(theAEDesc, realInDesc ) );
  1293.             ODDesc* realOutDesc = new ODDesc();
  1294.             THROW_IF_NULL(realOutDesc);
  1295.             realOutDesc->InitODDesc(ev);
  1296.             // APPLE EVENTS DOESN'T PASS US A NULL DESC APPARENTLY. IT'S FULL
  1297.             //    OF GARBAGE.
  1298.             MakeNULLDesc(retDesc);
  1299.             THROW_IF_ERROR( AEDescToODDesc(retDesc, realOutDesc ) );
  1300.  
  1301.             TRY
  1302.                 si->CallCoercionHandler(ev, sendee, realInDesc, toType, realOutDesc);
  1303.                 THROW_IF_ERROR(ODDescToAEDesc(realOutDesc, retDesc));
  1304.             CATCH_ALL
  1305.                 result = ErrorCode();
  1306.             ENDTRY
  1307.  
  1308.             ODDeleteObject(realInDesc);
  1309.             ODDeleteObject(realOutDesc);
  1310.         }
  1311.         else
  1312.             result = errAECoercionFail;
  1313.     CATCH_ALL
  1314.         result = ErrorCode();
  1315.     ENDTRY
  1316.  
  1317.     ODReleaseObject(ev,si);
  1318.     return result;
  1319. }
  1320.  
  1321. //------------------------------------------------------------------------------
  1322. // HandlePreDispatch
  1323. //
  1324. //    Allow all pre-dispatch procs to look at it. Return noErr IF ANY ONE OF THEM
  1325. //    said they handled it.
  1326. //------------------------------------------------------------------------------
  1327.  
  1328. static OSErr pascal HandlePreDispatch(AppleEvent* message,
  1329.                                                         AppleEvent* reply,
  1330.                                                         long refCon)
  1331. {
  1332.     ODUnused(refCon);
  1333.  
  1334.     OSErr            error = errAEEventNotHandled;
  1335.     ODBoolean        someoneHandled = kODFalse;
  1336.     Environment*    ev = somGetGlobalEnvironment();
  1337.  
  1338.     ODMessageInterface*    msgIntf = gMessageInterface;
  1339.  
  1340.     OrderedCollectionIterator    iter(msgIntf->GetPreHandlers(ev));
  1341.     PreHandlerInfo*                element;
  1342.  
  1343.     TRY
  1344.         for (element = (PreHandlerInfo*)iter.First();
  1345.                 iter.IsNotComplete();
  1346.                 element = (PreHandlerInfo*)iter.Next())
  1347.         {
  1348.             ODAppleEvent* coverEvent = new ODAppleEvent();
  1349.             THROW_IF_NULL(coverEvent);
  1350.             coverEvent->InitODAppleEvent(ev);
  1351.             THROW_IF_ERROR( AEDescToODDesc(message, coverEvent ) );
  1352.             ODAppleEvent* coverReply = new ODAppleEvent();
  1353.             THROW_IF_NULL(coverReply);
  1354.             coverReply->InitODAppleEvent(ev);
  1355.             THROW_IF_ERROR( AEDescToODDesc(reply, coverReply ) );
  1356.  
  1357.             TRY
  1358.                 element->GetSemanticInterface()->CallPredispatchProc(ev,
  1359.                                                                     kODNULL,
  1360.                                                                     coverEvent,
  1361.                                                                     coverReply);
  1362.             CATCH_ALL
  1363.                 error = ErrorCode();
  1364.             ENDTRY
  1365.  
  1366.             if (error == noErr)
  1367.                 someoneHandled = kODTrue;
  1368.  
  1369.             ODDeleteObject(coverEvent);
  1370.             ODDeleteObject(coverReply);
  1371.         }
  1372.     CATCH_ALL
  1373.         error = ErrorCode();
  1374.     ENDTRY
  1375.  
  1376.     if (someoneHandled)
  1377.         return noErr;
  1378.     else
  1379.         return error;
  1380. }
  1381.  
  1382. //------------------------------------------------------------------------------
  1383. // ODMessageInterface::GetPreHandlers
  1384. //------------------------------------------------------------------------------
  1385.  
  1386. SOM_Scope OrderedCollection*  SOMLINK ODMessageInterfaceGetPreHandlers(ODMessageInterface *somSelf, Environment *ev)
  1387. {
  1388.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1389.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceGetPreHandlers");
  1390.  
  1391.     return _fPreHandlers;
  1392. }
  1393.  
  1394. //------------------------------------------------------------------------------
  1395. // ODMessageInterface::GetDefaultSI
  1396. //------------------------------------------------------------------------------
  1397.  
  1398. SOM_Scope ODSemanticInterface*  SOMLINK ODMessageInterfaceGetDefaultSI(ODMessageInterface *somSelf, Environment *ev)
  1399. {
  1400.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1401.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceGetDefaultSI");
  1402.  
  1403.     return _fDefaultSI;
  1404. }
  1405.  
  1406. //------------------------------------------------------------------------------
  1407. // ODMessageInterface::PreHandlerAdded
  1408. //------------------------------------------------------------------------------
  1409.  
  1410. SOM_Scope void  SOMLINK ODMessageInterfacePreHandlerAdded(ODMessageInterface *somSelf, Environment *ev,
  1411.         ODSemanticInterface* face,
  1412.         ODSLong refCon)
  1413. {
  1414.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1415.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfacePreHandlerAdded");
  1416.  
  1417.     SOM_TRY
  1418.  
  1419.     PreHandlerInfo* info = new PreHandlerInfo(face, refCon);
  1420.     _fPreHandlers->AddFirst((ElementType)info);
  1421.     face->Acquire(ev);
  1422.  
  1423.     SOM_CATCH_ALL
  1424.     SOM_ENDTRY
  1425. }
  1426.  
  1427. //------------------------------------------------------------------------------
  1428. // ODMessageInterface::PreHandlerRemoved
  1429. //------------------------------------------------------------------------------
  1430.  
  1431. SOM_Scope void  SOMLINK ODMessageInterfacePreHandlerRemoved(ODMessageInterface *somSelf, Environment *ev,
  1432.         ODSemanticInterface* face,
  1433.         ODSLong refCon)
  1434. {
  1435.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1436.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfacePreHandlerRemoved");
  1437.  
  1438.     OrderedCollectionIterator    iter(somSelf->GetPreHandlers(ev));
  1439.     PreHandlerInfo*                element;
  1440.     ElementType                    elementToRemove = kODNULL;
  1441.  
  1442.     for (element = (PreHandlerInfo*)iter.First();
  1443.             iter.IsNotComplete();
  1444.             element = (PreHandlerInfo*)iter.Next())
  1445.     {
  1446.         if (element->GetSemanticInterface() == face
  1447.                 && element->GetRefCon() == refCon)
  1448.             elementToRemove = element;
  1449.     }
  1450.     if (elementToRemove) {
  1451.         _fPreHandlers->Remove(elementToRemove);
  1452.         ODReleaseObject(ev, face);
  1453.     }
  1454. }
  1455.  
  1456. //------------------------------------------------------------------------------
  1457. // ODMessageInterface::CreatePartAddrDesc
  1458. //------------------------------------------------------------------------------
  1459.  
  1460. SOM_Scope void  SOMLINK ODMessageInterfaceCreatePartAddrDesc(ODMessageInterface *somSelf, Environment *ev,
  1461.         ODAddressDesc** theAddressDesc,
  1462.         ODPart* part)
  1463. {
  1464. //    ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1465.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceCreatePartAddrDesc");
  1466.  
  1467.     ODUnused(part);
  1468.  
  1469.     ProcessSerialNumber PSN;
  1470.     OSErr                result;
  1471.     AEDesc        addressDesc; ODVolatile(addressDesc);
  1472.  
  1473.     SOM_TRY
  1474.         PSN.highLongOfPSN = 0;
  1475.         PSN.lowLongOfPSN = kCurrentProcess;
  1476.         result = AECreateDesc( typeProcessSerialNumber, (Ptr)&PSN, sizeof(PSN), 
  1477.                                 &addressDesc );
  1478.         if ( !result )
  1479.         {
  1480.             ODAddressDesc* newODAddress = new ODAddressDesc();
  1481.             THROW_IF_NULL(newODAddress);
  1482.             newODAddress->InitODAddressDesc(ev);
  1483.             result = AEDescToODDesc( &addressDesc, newODAddress);
  1484.             AEDisposeDesc(&addressDesc);
  1485.             if (!result)
  1486.                 *theAddressDesc = newODAddress;
  1487.             else
  1488.                 *theAddressDesc = kODNULL;
  1489.         }
  1490.     
  1491.         THROW_IF_ERROR (result);
  1492.     SOM_CATCH_ALL
  1493.         *theAddressDesc = kODNULL;
  1494.     SOM_ENDTRY
  1495. }
  1496.  
  1497. //------------------------------------------------------------------------------
  1498. // ODMessageInterface::CreatePartObjSpec
  1499. //------------------------------------------------------------------------------
  1500.  
  1501. SOM_Scope void  SOMLINK ODMessageInterfaceCreatePartObjSpec(ODMessageInterface *somSelf, Environment *ev,
  1502.         ODObjectSpec** theObjSpec,
  1503.         ODPart* thePart)
  1504. {
  1505.  
  1506. //    ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1507.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceCreatePartObjSpec");
  1508.  
  1509.     const Boolean        kDisposeInputs = kODTrue;
  1510.     AEDesc                keyData;
  1511.     AEDesc                nullDesc = NULL_DESCRIPTOR_DEFINITION;
  1512.     AEDesc        newObjSpec; ODVolatile(newObjSpec);
  1513.  
  1514.     SOM_TRY
  1515.         THROW_IF_ERROR(AECreateDesc(typeLongInteger, &thePart, sizeof(long),
  1516.                                 &keyData));
  1517.         // USE cPart as the keyform.
  1518.         THROW_IF_ERROR(CreateObjSpecifier(cPart, &nullDesc, cPart, &keyData,
  1519.                                             kDisposeInputs, &newObjSpec));
  1520.         ODObjectSpec* newODObjSpec = new ODObjectSpec();
  1521.         THROW_IF_NULL(newODObjSpec);
  1522.         newODObjSpec->InitODObjectSpec(ev);
  1523.         THROW_IF_ERROR( AEDescToODDesc(&newObjSpec, newODObjSpec ) );
  1524.         AEDisposeDesc(&newObjSpec);
  1525.         *theObjSpec = newODObjSpec;
  1526.     SOM_CATCH_ALL
  1527.         *theObjSpec = kODNULL;
  1528.     SOM_ENDTRY
  1529. }
  1530.  
  1531. //------------------------------------------------------------------------------
  1532. // ODMessageInterface::InstallDefaultHandlers
  1533. //------------------------------------------------------------------------------
  1534.  
  1535. SOM_Scope void  SOMLINK ODMessageInterfaceInstallDefaultHandlers(ODMessageInterface *somSelf, Environment *ev)
  1536. {
  1537.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1538.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceInstallDefaultHandlers");
  1539.  
  1540.     
  1541. }
  1542.  
  1543. #ifdef TO_BE_DELETED
  1544. //------------------------------------------------------------------------------
  1545. // ODMessageInterface: HandleGDUT
  1546. //------------------------------------------------------------------------------
  1547.  
  1548. // <eeh> this reversed the order of enclosed lists.  Shouldn't matter to
  1549. // the current AppleScript, but who knows.
  1550.  
  1551. #define ReturnIfError( funcCall )                                \
  1552.     { OSErr err = (funcCall);                                     \
  1553.     if ( err != noErr ) { return err; } }
  1554.  
  1555. static OSErr AddDPToList( AppleEvent* reply, AEDescList* theList )
  1556. {
  1557.     OSErr err = noErr ;
  1558.     AEDesc item ;
  1559.     ReturnIfError( AEGetKeyDesc( reply, keyDirectObject, typeWildCard, &item ));
  1560.  
  1561.     if ((item.descriptorType == typeAETE) || (item.descriptorType == typeAEUT))
  1562.     {
  1563.         err = AEPutDesc( theList, 0, &item ) ;
  1564.     }
  1565.     else if ( item.descriptorType == typeAEList )
  1566.     {
  1567.         long itemCount ;
  1568.         AECountItems( &item, &itemCount ) ;
  1569.         for( long i = 1; err == noErr && i <= itemCount; ++i )
  1570.         {
  1571.             AEDesc subItem ;
  1572.             DescType ignore ;
  1573.             ReturnIfError( AEGetNthDesc( &item, i, typeWildCard,
  1574.                     &ignore, &subItem ) ) ;
  1575.             err = AddDPToList( &subItem, theList ) ;
  1576.             AEDisposeDesc( &subItem ) ;
  1577.         }
  1578.     }
  1579.     else
  1580.     {
  1581.         WASSERTM( kODFalse, "neither aete nor aeut" ) ;
  1582.     }
  1583.     AEDisposeDesc( &item ) ;
  1584.     return err ;
  1585. }    // AddDPToList()
  1586.  
  1587. SOM_Scope pascal OSErr  SOMLINK ODMessageInterfaceHandleGDUT(ODMessageInterface *somSelf, Environment *ev,
  1588.         AppleEvent* message,
  1589.                                                         AppleEvent* reply,
  1590.                                                         long refCon)
  1591. {
  1592.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1593.     ODMessageInterfaceMethodDebug("ODMessageInterface","HandleGDUT");
  1594.  
  1595.     ODMessageInterface* self = (ODMessageInterface*)refCon;
  1596.     ODMessageInterface* msgInterface = self->_fSession->GetMessageInterface(ev);
  1597.  
  1598.     // Call the shell's GetAETE handler, then iterate through every
  1599.     // part editor getting theirs as well.  Put them all in a list,
  1600.     // making sure the list contains no lists.
  1601.     
  1602.     AEDescList resultList ;
  1603.     ReturnIfError( AECreateList( kODNULL, 0, kODFalse, &resultList ) ) ;
  1604.  
  1605.     ODSemanticInterface* shellSemInt = self->_fSession->GetShellSemtInterface(ev);
  1606.     if ( shellSemInt != kODNULL )
  1607.     {
  1608.         OSErr err = msgInterface->DispatchToEventHandler( message,
  1609.                 reply, kODAppShell ) ;
  1610.         if ( err == noErr )
  1611.             ReturnIfError( AddDPToList( reply, &resultList ) );
  1612.     }
  1613.  
  1614.     
  1615. #ifdef TO_BE_DELETED
  1616.     EditorIterator* ei = self->MakeEditorIterator() ;
  1617.     for( ODSemanticInterface* si = ei->First() ;
  1618.             ie->IsNotComplete() ; si = ei->Next() )
  1619.     {
  1620.         if ( si->HasExtension() && si->IsSemanticEventsExt() )
  1621.         {
  1622.             ReturnIfError( CallGetAETE( si, &oneAETE ) ) ;
  1623.             ReturnIfError( AddDPToList( reply, &resultList ) ) ;
  1624.         }
  1625.     }
  1626. #endif /* TO_BE_DELETED */
  1627.  
  1628.     ReturnIfError( AEPutKeyDesc( reply, keyDirectObject, &resultList ) ) ;
  1629.     AEDisposeDesc( &resultList ) ;
  1630.     return noErr ;
  1631. }    // HandleGDUT()
  1632. #endif /* TO_BE_DELETED */
  1633. //------------------------------------------------------------------------------
  1634. // GetReturnID
  1635. //------------------------------------------------------------------------------
  1636.  
  1637. static ODSShort GetReturnID(AppleEvent* ae)
  1638. {
  1639.     ODSShort    returnID;
  1640.     DescType    actualType;
  1641.     Size        sizeOfBuffer = sizeof(ODSShort);
  1642.     Size        actualSize;
  1643.  
  1644.     THROW_IF_ERROR(AEGetAttributePtr(ae, keyReturnIDAttr,
  1645.                                     typeShortInteger, &actualType,
  1646.                                     (Ptr)&returnID,
  1647.                                     sizeOfBuffer, &actualSize));
  1648.     if ((actualType != typeShortInteger) || (actualSize != sizeOfBuffer))
  1649.         THROW(kODErrOutOfMemory);
  1650.     return returnID;
  1651. }
  1652.  
  1653. //------------------------------------------------------------------------------
  1654. // SentToSelf
  1655. //------------------------------------------------------------------------------
  1656.  
  1657. static ODBoolean SentToSelf(AppleEvent* theAppleEvent)
  1658. {
  1659.     ProcessSerialNumber     PSN;
  1660.     DescType                actualType;
  1661.     Size                    sizeOfBuffer = sizeof(ProcessSerialNumber);
  1662.     Size                    actualSize;
  1663.     Boolean                    isCurrentProcess;
  1664.  
  1665.     THROW_IF_ERROR(AEGetAttributePtr(theAppleEvent,
  1666.                                         keyAddressAttr,
  1667.                                         typeProcessSerialNumber, &actualType,
  1668.                                         (Ptr)&PSN, sizeOfBuffer, &actualSize ));
  1669.     
  1670.     if ((actualType != typeProcessSerialNumber) || (actualSize != sizeOfBuffer))
  1671.         THROW(kODErrOutOfMemory);
  1672.     //$$$$$ THIS IS WRONG. SHOULD BE CALLING SameProcess. AM TOO WORRIED ABOUT
  1673.     //    BREAKING SOMETHING TO FIX IT AT THIS LATE DATE, HOWEVER. -NP 8/30/95
  1674.     isCurrentProcess = ( PSN.lowLongOfPSN == kCurrentProcess );
  1675.     return isCurrentProcess;
  1676. }
  1677.  
  1678. //------------------------------------------------------------------------------
  1679. // GetTokenPart
  1680. // Given a token (of type 'tokn'), determine if the user token it contains
  1681. // is a StandardPartToken and if so return the ODPart* field therefrom.
  1682. // Return NULL in all other cases.
  1683. //------------------------------------------------------------------------------
  1684.  
  1685. static ODPart* GetTokenPart( Environment* ev,
  1686.         ODNameResolver* resolver, AEDesc* realToken )
  1687. {
  1688.     if ( !realToken || (realToken->descriptorType != typeUserToken))
  1689.         return kODNULL;
  1690.  
  1691.     ODPart* result = kODNULL;
  1692.     ODOSLToken* token = new ODOSLToken;
  1693.     THROW_IF_NULL(token);
  1694.     token->InitODOSLToken(ev);
  1695.     if ( AEDescToODDesc( realToken, token ) )
  1696.     {
  1697.         ODDeleteObject(token);
  1698.         return kODNULL;
  1699.     }
  1700.     ODDesc* userToken;
  1701.     userToken = resolver->GetUserToken( ev, token );
  1702.     AEDesc realUserToken;
  1703.     if ( ODDescToAEDesc( userToken, &realUserToken ) )
  1704.         return kODNULL;
  1705.     if ( CanBeStandardPartToken( &realUserToken ) )
  1706.         result = PartFromStandardPartToken( &realUserToken );
  1707.     AEDisposeDesc(&realUserToken);
  1708.     ODDeleteObject(token);
  1709.  
  1710.     return result;
  1711. }
  1712.  
  1713. //------------------------------------------------------------------------------
  1714. // HandleGetAETE
  1715. //------------------------------------------------------------------------------
  1716. pascal OSErr HandleGetAETE(    AppleEvent*    message,
  1717.                             AppleEvent*    reply,
  1718.                             long        refCon)
  1719. {
  1720.     ODMessageInterface *somSelf = (ODMessageInterface*) refCon;
  1721.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1722.  
  1723.     AEDesc            theAETE = NULL_DESCRIPTOR_DEFINITION;
  1724.     AEDesc            scsz = NULL_DESCRIPTOR_DEFINITION;
  1725.     AEDescList        theList = NULL_DESCRIPTOR_DEFINITION;
  1726.     AppleEvent        realEvent = NULL_DESCRIPTOR_DEFINITION;
  1727.     AppleEvent        realReply = NULL_DESCRIPTOR_DEFINITION;
  1728.     Environment*    ev = somGetGlobalEnvironment();
  1729.     DescType        returnedType;
  1730.     ODSize            actualSize;
  1731.     ODSLong            languageCode;
  1732.     ODAddressDesc*    address;
  1733.     ODAppleEvent*    myEvent;
  1734.     ODAppleEvent*    myReply;
  1735.     OSErr            result;
  1736.     ODSession*        session = _fSession;
  1737.     ODError            error = noErr;
  1738.     ODVolatile(error);
  1739.     
  1740.     TRY
  1741.         result = AEGetParamPtr(message, keyDirectObject, typeLongInteger,
  1742.                                &returnedType, (Ptr)&languageCode, sizeof(languageCode),
  1743.                                (Size *)&actualSize);
  1744.         THROW_IF_ERROR( AECreateList(kODNULL, 0, false, &theList) );
  1745.         
  1746.         // get aete list for all part editors
  1747.         session->GetNameSpaceManager(ev)->GetAETEs(ev, languageCode, &theList);
  1748.         
  1749.         // get aete for shell
  1750.         myReply = new ODAppleEvent();
  1751.         THROW_IF_NULL(myReply);
  1752.         myReply->InitODAppleEvent(ev);
  1753.         TRY
  1754.             somSelf->CreatePartAddrDesc(ev, &address, kODNULL);
  1755.             somSelf->CreateEvent(ev, kAEOpenDocSuite, kGetAETE, address, kAnyTransactionID, &myEvent);
  1756.             THROW_IF_ERROR( ODDescToAEDesc(myEvent, &realEvent) );
  1757.             THROW_IF_ERROR( AEPutParamPtr(&realEvent, keyDirectObject, typeLongInteger, (Ptr) &languageCode, sizeof(languageCode)) );
  1758.             THROW_IF_ERROR( AEDescToODDesc(&realEvent, myEvent) );
  1759.             somSelf->Send(ev, kODNULL, kODNULL, myEvent, myReply, kAEWaitReply+kAEDontRecord, kAENormalPriority, kAEDefaultTimeout);
  1760.             THROW_IF_ERROR( ODDescToAEDesc(myReply, &realReply) );
  1761.             THROW_IF_ERROR( AEGetParamDesc(&realReply, keyAEResult, typeAETE, &theAETE) );
  1762.             THROW_IF_ERROR( AEPutDesc(&theList, 0, &theAETE) );
  1763.         CATCH_ALL
  1764. //            error = ErrorCode();    // we're ignoring this, so we're commented out
  1765.             WARN("Couldn't get shell aete");
  1766.         ENDTRY
  1767.         AEDisposeDesc(&realEvent);
  1768.         AEDisposeDesc(&realReply);
  1769.         AEDisposeDesc(&theAETE);
  1770.         ODDeleteObject(myEvent);
  1771.         ODDeleteObject(myReply);
  1772.         
  1773.         // get aete for OpenDoc from messaging library
  1774.         TRY
  1775.             CUsingLibraryResources    ref;
  1776.             // We pervert the language code because we need two aetes in the single
  1777.             // library version, one for the shell and one for OpenDoc.  This way
  1778.             // container apps can override the shell's aete and provide their own.
  1779.             // The shell aete is numbered normally, but OpenDoc's aetes are numbered
  1780.             // according to this scheme (-1 - languageCode) so that they start at -1
  1781.             // and proceed down from there (as opposed to the normal ones which
  1782.             // start at 0 and proceed upward).
  1783.             theAETE.dataHandle = Get1Resource(typeAETE, (short)(-1-languageCode));
  1784.             THROW_IF_NULL(theAETE.dataHandle);
  1785.             theAETE.descriptorType = typeAETE;
  1786.             result = AEPutDesc(&theList, 0, &theAETE);
  1787.             ReleaseResource(theAETE.dataHandle);
  1788.             THROW_IF_ERROR(result);
  1789.         CATCH_ALL
  1790. //            error = ErrorCode();    // we're ignoring this, so we're commented out
  1791.             WARN("Couldn't get OpenDoc aete");
  1792.         ENDTRY
  1793.         
  1794.         TRY
  1795.             scsz.descriptorType = 'scsz';
  1796.             scsz.dataHandle = Get1Resource('scsz', 0);
  1797.             THROW_IF_NULL(scsz.dataHandle);
  1798.             THROW_IF_ERROR( AEPutParamDesc(reply, keyScszResource, &scsz) );
  1799.         CATCH_ALL
  1800. //            error = ErrorCode();    // we're ignoring this, so we're commented out
  1801.             WARN("Couldn't get OpenDoc scsz");
  1802.         ENDTRY
  1803.  
  1804.         THROW_IF_ERROR( AEPutParamDesc(reply, keyDirectObject, &theList) );
  1805.         THROW_IF_ERROR( AEDisposeDesc(&theList) );
  1806.         
  1807.     CATCH_ALL
  1808.         error = ErrorCode();
  1809.     ENDTRY
  1810.  
  1811.     return error;
  1812. }    // HandleGetAETE()
  1813.  
  1814.  
  1815. void CreateSubjectObject(Environment* ev, ODFrame* frame, AEDesc* objSpec)
  1816. {
  1817.     AEDesc                    nullDesc = NULL_DESCRIPTOR_DEFINITION;
  1818.     AEDesc                    id;
  1819.     ODPersistentObjectID    foo;
  1820.     OSErr                    err;    
  1821.     
  1822.     ODStorageUnit* su = frame->GetStorageUnit(ev);
  1823.     WASSERT(su);
  1824.     ODDraft* draft = su->GetDraft(ev);
  1825.     WASSERT(draft);
  1826.     foo = draft->GetPersistentObjectID( ev, frame, kODFrameObject);
  1827.     THROW_IF_ERROR( AECreateDesc(typeInteger, (Ptr) &foo, sizeof(foo), &id) );
  1828.     err = CreateObjSpecifier(cPart, &nullDesc, formUniqueID, &id, kODFalse, objSpec);
  1829.     AEDisposeDesc(&id);
  1830.     THROW_IF_ERROR(err);
  1831. }    // CreateSubjectObject
  1832.  
  1833.