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